2005-02-04 05:10:35 +03:00
|
|
|
/* $NetBSD: rtwvar.h,v 1.20 2005/02/04 02:10:37 perry Exp $ */
|
2004-09-26 06:29:15 +04:00
|
|
|
/*-
|
|
|
|
* Copyright (c) 2004, 2005 David Young. All rights reserved.
|
|
|
|
*
|
|
|
|
* Driver for the Realtek RTL8180 802.11 MAC/BBP by David Young.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
* 3. The name of David Young may not be used to endorse or promote
|
|
|
|
* products derived from this software without specific prior
|
|
|
|
* written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY David Young ``AS IS'' AND ANY
|
|
|
|
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
|
|
|
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
|
|
|
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL David
|
|
|
|
* Young BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
|
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
|
|
|
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
|
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
|
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
|
|
|
* OF SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _DEV_IC_RTWVAR_H_
|
|
|
|
#define _DEV_IC_RTWVAR_H_
|
|
|
|
|
|
|
|
#include <sys/queue.h>
|
|
|
|
#include <sys/callout.h>
|
|
|
|
|
|
|
|
#ifdef RTW_DEBUG
|
2004-12-25 10:45:53 +03:00
|
|
|
#define RTW_DEBUG_TUNE 0x000001
|
|
|
|
#define RTW_DEBUG_PKTFILT 0x000002
|
|
|
|
#define RTW_DEBUG_XMIT 0x000004
|
|
|
|
#define RTW_DEBUG_XMIT_DESC 0x000008
|
|
|
|
#define RTW_DEBUG_NODE 0x000010
|
|
|
|
#define RTW_DEBUG_PWR 0x000020
|
|
|
|
#define RTW_DEBUG_ATTACH 0x000040
|
|
|
|
#define RTW_DEBUG_REGDUMP 0x000080
|
|
|
|
#define RTW_DEBUG_ACCESS 0x000100
|
|
|
|
#define RTW_DEBUG_RESET 0x000200
|
|
|
|
#define RTW_DEBUG_INIT 0x000400
|
|
|
|
#define RTW_DEBUG_IOSTATE 0x000800
|
|
|
|
#define RTW_DEBUG_RECV 0x001000
|
|
|
|
#define RTW_DEBUG_RECV_DESC 0x002000
|
|
|
|
#define RTW_DEBUG_IO_KICK 0x004000
|
|
|
|
#define RTW_DEBUG_INTR 0x008000
|
|
|
|
#define RTW_DEBUG_PHY 0x010000
|
|
|
|
#define RTW_DEBUG_PHYIO 0x020000
|
|
|
|
#define RTW_DEBUG_PHYBITIO 0x040000
|
|
|
|
#define RTW_DEBUG_TIMEOUT 0x080000
|
|
|
|
#define RTW_DEBUG_BUGS 0x100000
|
Move the register access mode into struct rtw_regs. Change
rtw_set_access, rtw_set_access1 to match.
Add a subroutine for setting WEP keys. WEP isn't quite finished,
because I have to add the WEP header to Tx packets. Implement the
SIOCS80211NWKEY ioctl for setting WEP keys.
Program the LEDs based on operating state and packet activity.
* On a Revision F RTL8180, blink LED1 at 1Hz to indicate
scan/authenticate/associate states. In the run state, turn LED1
on. In every state, blink LED1 at 5Hz to indicate non-beacon
tx/rx activity. I would like to use two LEDs, but in all my
Rev. F instances, LED0 is not wired to an LED; instead, the
first LED is wired to indicate that the card's power is on.
* On a Revision D RTL8180, program the LEDs so that LED0 indicates
Tx, and LED1 indicates Rx. The Rx LED will blink annoyingly if
there are beacons in the air, but at least the Tx LED is useful.
* Store the hardware revision in the softc to support my futile
attempt at programming LEDs for both Rev. D and Rev. F parts;
I never did get Rev. D LEDs to work right.
* Add a debug flag RTW_DEBUG_LED for the LED transitions.
Add RTW_TPPOLL_ALL, RTW_TPPOLL_SALL to start and stop, respectively,
all of the transmit rings.
In ad hoc mode, allocate a beacon and load it into the beacon ring.
Start the ring. In one trial, the card re-transmitted the beacon
ring's contents several times before stopping. More programming
and testing for ad hoc mode is necessary. I'm not setting the
beacon flag in the transmit descriptor.
Revamp the transmit section to make better use of all the transmit
rings: beacon queue, high-, low-, and medium-priority rings. Put
beacon frames on the beacon ring. All other management frames,
and data frames, go on the medium-priority ring. Power-save data
frames go on the high-priority ring. (Note that powersaving is
not implemented!) This is a work in progress.
Send all 802.11 Management frames at 1Mbps.
After we put a packet on a transmit ring, tickle the right bit in
the TPPOLL to tell RTL8180. Stop all rings on error and in rtw_stop.
Use the RF chip type, not the RTL8180 revision, to choose between
host- and MAC-controlled RF serial I/O. Now the Netgear MA521
works.
Remove bogus definition of bit RTW_TPPOLL_FSWINT.
2005-01-16 14:50:43 +03:00
|
|
|
#define RTW_DEBUG_BEACON 0x200000
|
|
|
|
#define RTW_DEBUG_LED 0x400000
|
|
|
|
#define RTW_DEBUG_MAX 0x7fffff
|
2004-12-25 09:58:37 +03:00
|
|
|
|
2004-09-26 06:29:15 +04:00
|
|
|
extern int rtw_debug;
|
2004-12-25 09:58:37 +03:00
|
|
|
#define RTW_DPRINTF(__flags, __x) \
|
|
|
|
if ((rtw_debug & (__flags)) != 0) printf __x
|
|
|
|
#define DPRINTF(__sc, __flags, __x) \
|
|
|
|
if (((__sc)->sc_ic.ic_if.if_flags & IFF_DEBUG) != 0) \
|
|
|
|
RTW_DPRINTF(__flags, __x)
|
2005-01-03 06:25:06 +03:00
|
|
|
#define RTW_PRINT_REGS(__regs, __dvname, __where) \
|
|
|
|
rtw_print_regs((__regs), (__dvname), (__where))
|
2004-09-26 06:29:15 +04:00
|
|
|
#else /* RTW_DEBUG */
|
2004-12-27 01:37:57 +03:00
|
|
|
#define RTW_DPRINTF(__flags, __x)
|
|
|
|
#define DPRINTF(__sc, __flags, __x)
|
2005-01-03 06:25:06 +03:00
|
|
|
#define RTW_PRINT_REGS(__regs, __dvname, __where)
|
2004-09-26 06:29:15 +04:00
|
|
|
#endif /* RTW_DEBUG */
|
|
|
|
|
|
|
|
enum rtw_locale {
|
|
|
|
RTW_LOCALE_USA = 0,
|
|
|
|
RTW_LOCALE_EUROPE,
|
|
|
|
RTW_LOCALE_JAPAN,
|
|
|
|
RTW_LOCALE_UNKNOWN
|
|
|
|
};
|
|
|
|
|
|
|
|
enum rtw_rfchipid {
|
|
|
|
RTW_RFCHIPID_RESERVED = 0,
|
|
|
|
RTW_RFCHIPID_INTERSIL = 1,
|
|
|
|
RTW_RFCHIPID_RFMD = 2,
|
|
|
|
RTW_RFCHIPID_PHILIPS = 3,
|
|
|
|
RTW_RFCHIPID_MAXIM = 4,
|
|
|
|
RTW_RFCHIPID_GCT = 5
|
|
|
|
};
|
|
|
|
|
|
|
|
/* sc_flags */
|
|
|
|
#define RTW_F_ENABLED 0x00000001 /* chip is enabled */
|
|
|
|
#define RTW_F_DIGPHY 0x00000002 /* digital PHY */
|
|
|
|
#define RTW_F_DFLANTB 0x00000004 /* B antenna is default */
|
|
|
|
#define RTW_F_ANTDIV 0x00000010 /* h/w antenna diversity */
|
|
|
|
#define RTW_F_9356SROM 0x00000020 /* 93c56 SROM */
|
Miscellaneous changes. Details below. Important changes flagged
with []. Using the driver with my Linksys WPC11 ver. 4, it seems
to be receiving packets for a change. The WPC11 ver. 4 has a Maxim
RF section. My no-name rtw with Philips RF section still does not
receive any packets.
Keep access-level (analog params > config[0123] registers > none)
in sc_access. Add rtw_set_access for changing the access level.
Make rtw_continuous_tx_enable and other subroutines use rtw_set_access
instead of rtw_config0123_enable and rtw_anaparm_enable.
Factor part of the chip-reset code into rtw_chip_reset1.
Change the 'struct foo (*bar)[N]'-style arguments to
'struct foo *bar'-style arguments.
Consolidate software/hardware Tx/Rx ring setup in rtw_hwring_setup,
rtw_swring_setup.
Add a new constant, SA2400_OPMODE_DEFAULTS, for the bits that we
*always* set in the SA2400 OPMODE register.
Factor some code out into rtw_sa2400_calibrate. (Inspired by the
Linux driver.)
[] When the receiver goes into underrun/overflow state, call a new
subroutine, rtw_kick() that stops the Rx/Tx processes, resets
the chip, reinitializes the Tx/Rx rings, and restarts Rx/Tx
processes. (Inspired by the Linux driver.)
[] In rtw_intr_rx, check for too-short packets before calling
ieee80211_find_rxnode. I believe this will prevent a repeat of
the MCHK exception I saw once on macppc.
[] Use seconds-elapased as well as microseconds-elapsed to set the
next "due date" for the timeout interrupt. This keeps the driver
from programming the timeout to expire too early.
[] In rtw_intr, read RTW_ISR at most 10 times, then get out. If
the interface is not enabled (RTW_F_ENABLED), then get out.
[] In rtw_stop, get out if the interface is not enabled (RTW_F_ENABLED).
Block IPL_NET interrupts. Don't read/write any registers if
the interface is invalid (RTW_F_INVALID).
[] Call rtw_stop in rtw_detach.
2004-12-12 09:37:59 +03:00
|
|
|
#define RTW_F_SLEEP 0x00000040 /* chip is asleep */
|
|
|
|
#define RTW_F_INVALID 0x00000080 /* chip is absent */
|
2004-09-26 06:29:15 +04:00
|
|
|
/* all PHY flags */
|
|
|
|
#define RTW_F_ALLPHY (RTW_F_DIGPHY|RTW_F_DFLANTB|RTW_F_ANTDIV)
|
|
|
|
|
Move the register access mode into struct rtw_regs. Change
rtw_set_access, rtw_set_access1 to match.
Add a subroutine for setting WEP keys. WEP isn't quite finished,
because I have to add the WEP header to Tx packets. Implement the
SIOCS80211NWKEY ioctl for setting WEP keys.
Program the LEDs based on operating state and packet activity.
* On a Revision F RTL8180, blink LED1 at 1Hz to indicate
scan/authenticate/associate states. In the run state, turn LED1
on. In every state, blink LED1 at 5Hz to indicate non-beacon
tx/rx activity. I would like to use two LEDs, but in all my
Rev. F instances, LED0 is not wired to an LED; instead, the
first LED is wired to indicate that the card's power is on.
* On a Revision D RTL8180, program the LEDs so that LED0 indicates
Tx, and LED1 indicates Rx. The Rx LED will blink annoyingly if
there are beacons in the air, but at least the Tx LED is useful.
* Store the hardware revision in the softc to support my futile
attempt at programming LEDs for both Rev. D and Rev. F parts;
I never did get Rev. D LEDs to work right.
* Add a debug flag RTW_DEBUG_LED for the LED transitions.
Add RTW_TPPOLL_ALL, RTW_TPPOLL_SALL to start and stop, respectively,
all of the transmit rings.
In ad hoc mode, allocate a beacon and load it into the beacon ring.
Start the ring. In one trial, the card re-transmitted the beacon
ring's contents several times before stopping. More programming
and testing for ad hoc mode is necessary. I'm not setting the
beacon flag in the transmit descriptor.
Revamp the transmit section to make better use of all the transmit
rings: beacon queue, high-, low-, and medium-priority rings. Put
beacon frames on the beacon ring. All other management frames,
and data frames, go on the medium-priority ring. Power-save data
frames go on the high-priority ring. (Note that powersaving is
not implemented!) This is a work in progress.
Send all 802.11 Management frames at 1Mbps.
After we put a packet on a transmit ring, tickle the right bit in
the TPPOLL to tell RTL8180. Stop all rings on error and in rtw_stop.
Use the RF chip type, not the RTL8180 revision, to choose between
host- and MAC-controlled RF serial I/O. Now the Netgear MA521
works.
Remove bogus definition of bit RTW_TPPOLL_FSWINT.
2005-01-16 14:50:43 +03:00
|
|
|
enum rtw_access {RTW_ACCESS_NONE = 0,
|
|
|
|
RTW_ACCESS_CONFIG = 1,
|
|
|
|
RTW_ACCESS_ANAPARM = 2};
|
|
|
|
|
2004-09-26 06:29:15 +04:00
|
|
|
struct rtw_regs {
|
|
|
|
bus_space_tag_t r_bt;
|
|
|
|
bus_space_handle_t r_bh;
|
Move the register access mode into struct rtw_regs. Change
rtw_set_access, rtw_set_access1 to match.
Add a subroutine for setting WEP keys. WEP isn't quite finished,
because I have to add the WEP header to Tx packets. Implement the
SIOCS80211NWKEY ioctl for setting WEP keys.
Program the LEDs based on operating state and packet activity.
* On a Revision F RTL8180, blink LED1 at 1Hz to indicate
scan/authenticate/associate states. In the run state, turn LED1
on. In every state, blink LED1 at 5Hz to indicate non-beacon
tx/rx activity. I would like to use two LEDs, but in all my
Rev. F instances, LED0 is not wired to an LED; instead, the
first LED is wired to indicate that the card's power is on.
* On a Revision D RTL8180, program the LEDs so that LED0 indicates
Tx, and LED1 indicates Rx. The Rx LED will blink annoyingly if
there are beacons in the air, but at least the Tx LED is useful.
* Store the hardware revision in the softc to support my futile
attempt at programming LEDs for both Rev. D and Rev. F parts;
I never did get Rev. D LEDs to work right.
* Add a debug flag RTW_DEBUG_LED for the LED transitions.
Add RTW_TPPOLL_ALL, RTW_TPPOLL_SALL to start and stop, respectively,
all of the transmit rings.
In ad hoc mode, allocate a beacon and load it into the beacon ring.
Start the ring. In one trial, the card re-transmitted the beacon
ring's contents several times before stopping. More programming
and testing for ad hoc mode is necessary. I'm not setting the
beacon flag in the transmit descriptor.
Revamp the transmit section to make better use of all the transmit
rings: beacon queue, high-, low-, and medium-priority rings. Put
beacon frames on the beacon ring. All other management frames,
and data frames, go on the medium-priority ring. Power-save data
frames go on the high-priority ring. (Note that powersaving is
not implemented!) This is a work in progress.
Send all 802.11 Management frames at 1Mbps.
After we put a packet on a transmit ring, tickle the right bit in
the TPPOLL to tell RTL8180. Stop all rings on error and in rtw_stop.
Use the RF chip type, not the RTL8180 revision, to choose between
host- and MAC-controlled RF serial I/O. Now the Netgear MA521
works.
Remove bogus definition of bit RTW_TPPOLL_FSWINT.
2005-01-16 14:50:43 +03:00
|
|
|
enum rtw_access r_access;
|
2004-09-26 06:29:15 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
#define RTW_SR_GET(sr, ofs) \
|
|
|
|
(((sr)->sr_content[(ofs)/2] >> (((ofs) % 2 == 0) ? 0 : 8)) & 0xff)
|
|
|
|
|
|
|
|
#define RTW_SR_GET16(sr, ofs) \
|
|
|
|
(RTW_SR_GET((sr), (ofs)) | (RTW_SR_GET((sr), (ofs) + 1) << 8))
|
|
|
|
|
|
|
|
struct rtw_srom {
|
2005-01-02 07:23:03 +03:00
|
|
|
uint16_t *sr_content;
|
|
|
|
uint16_t sr_size;
|
2004-09-26 06:29:15 +04:00
|
|
|
};
|
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
struct rtw_rxsoft {
|
|
|
|
struct mbuf *rs_mbuf;
|
|
|
|
bus_dmamap_t rs_dmamap;
|
2004-09-26 06:29:15 +04:00
|
|
|
};
|
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
struct rtw_txsoft {
|
|
|
|
SIMPLEQ_ENTRY(rtw_txsoft) ts_q;
|
|
|
|
struct mbuf *ts_mbuf;
|
|
|
|
bus_dmamap_t ts_dmamap;
|
|
|
|
struct ieee80211_node *ts_ni; /* destination node */
|
|
|
|
u_int ts_first; /* 1st hw descriptor */
|
|
|
|
u_int ts_last; /* last hw descriptor */
|
|
|
|
struct ieee80211_duration ts_d0;
|
|
|
|
struct ieee80211_duration ts_dn;
|
2004-09-26 06:29:15 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
#define RTW_NTXPRI 4 /* number of Tx priorities */
|
|
|
|
#define RTW_TXPRILO 0
|
|
|
|
#define RTW_TXPRIMD 1
|
|
|
|
#define RTW_TXPRIHI 2
|
|
|
|
#define RTW_TXPRIBCN 3 /* beacon priority */
|
|
|
|
|
2004-12-25 09:58:37 +03:00
|
|
|
#define RTW_MAXPKTSEGS 64 /* Max 64 segments per Tx packet */
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
#define CASSERT(cond, complaint) complaint[(cond) ? 0 : -1] = complaint[(cond) ? 0 : -1]
|
|
|
|
|
2004-12-25 09:58:37 +03:00
|
|
|
/* Note well: the descriptor rings must begin on RTW_DESC_ALIGNMENT
|
|
|
|
* boundaries. I allocate them consecutively from one buffer, so
|
|
|
|
* just round up.
|
2004-09-26 06:29:15 +04:00
|
|
|
*/
|
2004-12-25 09:58:37 +03:00
|
|
|
#define RTW_TXQLENLO 64 /* low-priority queue length */
|
|
|
|
#define RTW_TXQLENMD 64 /* medium-priority */
|
|
|
|
#define RTW_TXQLENHI 64 /* high-priority */
|
|
|
|
#define RTW_TXQLENBCN 1 /* beacon */
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2004-12-25 09:58:37 +03:00
|
|
|
#define RTW_NTXDESCLO RTW_TXQLENLO
|
|
|
|
#define RTW_NTXDESCMD RTW_TXQLENMD
|
|
|
|
#define RTW_NTXDESCHI RTW_TXQLENHI
|
|
|
|
#define RTW_NTXDESCBCN RTW_TXQLENBCN
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
#define RTW_NTXDESCTOTAL (RTW_NTXDESCLO + RTW_NTXDESCMD + \
|
|
|
|
RTW_NTXDESCHI + RTW_NTXDESCBCN)
|
|
|
|
|
2004-12-25 09:58:37 +03:00
|
|
|
#define RTW_RXQLEN 64
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2004-12-29 03:21:37 +03:00
|
|
|
struct rtw_rxdesc_blk {
|
2004-12-29 04:06:52 +03:00
|
|
|
struct rtw_rxdesc *rdb_desc;
|
|
|
|
u_int rdb_next;
|
|
|
|
u_int rdb_ndesc;
|
|
|
|
bus_dma_tag_t rdb_dmat;
|
|
|
|
bus_dmamap_t rdb_dmamap;
|
2004-12-29 03:21:37 +03:00
|
|
|
};
|
|
|
|
|
2004-09-26 06:29:15 +04:00
|
|
|
struct rtw_txdesc_blk {
|
2004-12-29 04:06:52 +03:00
|
|
|
u_int tdb_ndesc;
|
|
|
|
u_int tdb_next;
|
|
|
|
u_int tdb_nfree;
|
|
|
|
bus_dma_tag_t tdb_dmat;
|
|
|
|
bus_dmamap_t tdb_dmamap;
|
|
|
|
bus_addr_t tdb_physbase;
|
|
|
|
bus_addr_t tdb_ofs;
|
|
|
|
struct rtw_txdesc *tdb_desc;
|
2004-09-26 06:29:15 +04:00
|
|
|
};
|
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
#define RTW_NEXT_IDX(__htc, __idx) (((__idx) + 1) % (__htc)->tdb_ndesc)
|
2004-12-19 11:19:25 +03:00
|
|
|
|
|
|
|
#define RTW_NEXT_DESC(__htc, __idx) \
|
2004-12-29 04:06:52 +03:00
|
|
|
((__htc)->tdb_physbase + \
|
2004-12-19 11:19:25 +03:00
|
|
|
sizeof(struct rtw_txdesc) * RTW_NEXT_IDX((__htc), (__idx)))
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
SIMPLEQ_HEAD(rtw_txq, rtw_txsoft);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
struct rtw_txsoft_blk {
|
2004-09-26 06:29:15 +04:00
|
|
|
/* dirty/free s/w descriptors */
|
2004-12-29 04:06:52 +03:00
|
|
|
struct rtw_txq tsb_dirtyq;
|
|
|
|
struct rtw_txq tsb_freeq;
|
|
|
|
u_int tsb_ndesc;
|
|
|
|
int tsb_tx_timer;
|
|
|
|
struct rtw_txsoft *tsb_desc;
|
Move the register access mode into struct rtw_regs. Change
rtw_set_access, rtw_set_access1 to match.
Add a subroutine for setting WEP keys. WEP isn't quite finished,
because I have to add the WEP header to Tx packets. Implement the
SIOCS80211NWKEY ioctl for setting WEP keys.
Program the LEDs based on operating state and packet activity.
* On a Revision F RTL8180, blink LED1 at 1Hz to indicate
scan/authenticate/associate states. In the run state, turn LED1
on. In every state, blink LED1 at 5Hz to indicate non-beacon
tx/rx activity. I would like to use two LEDs, but in all my
Rev. F instances, LED0 is not wired to an LED; instead, the
first LED is wired to indicate that the card's power is on.
* On a Revision D RTL8180, program the LEDs so that LED0 indicates
Tx, and LED1 indicates Rx. The Rx LED will blink annoyingly if
there are beacons in the air, but at least the Tx LED is useful.
* Store the hardware revision in the softc to support my futile
attempt at programming LEDs for both Rev. D and Rev. F parts;
I never did get Rev. D LEDs to work right.
* Add a debug flag RTW_DEBUG_LED for the LED transitions.
Add RTW_TPPOLL_ALL, RTW_TPPOLL_SALL to start and stop, respectively,
all of the transmit rings.
In ad hoc mode, allocate a beacon and load it into the beacon ring.
Start the ring. In one trial, the card re-transmitted the beacon
ring's contents several times before stopping. More programming
and testing for ad hoc mode is necessary. I'm not setting the
beacon flag in the transmit descriptor.
Revamp the transmit section to make better use of all the transmit
rings: beacon queue, high-, low-, and medium-priority rings. Put
beacon frames on the beacon ring. All other management frames,
and data frames, go on the medium-priority ring. Power-save data
frames go on the high-priority ring. (Note that powersaving is
not implemented!) This is a work in progress.
Send all 802.11 Management frames at 1Mbps.
After we put a packet on a transmit ring, tickle the right bit in
the TPPOLL to tell RTL8180. Stop all rings on error and in rtw_stop.
Use the RF chip type, not the RTL8180 revision, to choose between
host- and MAC-controlled RF serial I/O. Now the Netgear MA521
works.
Remove bogus definition of bit RTW_TPPOLL_FSWINT.
2005-01-16 14:50:43 +03:00
|
|
|
uint8_t tsb_poll;
|
2004-09-26 06:29:15 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
struct rtw_descs {
|
|
|
|
struct rtw_txdesc hd_txlo[RTW_NTXDESCLO];
|
|
|
|
struct rtw_txdesc hd_txmd[RTW_NTXDESCMD];
|
|
|
|
struct rtw_txdesc hd_txhi[RTW_NTXDESCMD];
|
2004-12-25 09:58:37 +03:00
|
|
|
struct rtw_rxdesc hd_rx[RTW_RXQLEN];
|
2004-09-26 06:29:15 +04:00
|
|
|
struct rtw_txdesc hd_bcn[RTW_NTXDESCBCN];
|
|
|
|
};
|
|
|
|
#define RTW_DESC_OFFSET(ring, i) offsetof(struct rtw_descs, ring[i])
|
|
|
|
#define RTW_RING_OFFSET(ring) RTW_DESC_OFFSET(ring, 0)
|
|
|
|
#define RTW_RING_BASE(sc, ring) ((sc)->sc_desc_physaddr + \
|
|
|
|
RTW_RING_OFFSET(ring))
|
|
|
|
|
|
|
|
/* Radio capture format for RTL8180. */
|
|
|
|
|
2004-12-29 01:30:07 +03:00
|
|
|
#define RTW_RX_RADIOTAP_PRESENT \
|
|
|
|
((1 << IEEE80211_RADIOTAP_TSFT) | \
|
|
|
|
(1 << IEEE80211_RADIOTAP_FLAGS) | \
|
|
|
|
(1 << IEEE80211_RADIOTAP_RATE) | \
|
|
|
|
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
|
|
|
|
(1 << IEEE80211_RADIOTAP_LOCK_QUALITY) | \
|
|
|
|
(1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) | \
|
|
|
|
0)
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
struct rtw_rx_radiotap_header {
|
|
|
|
struct ieee80211_radiotap_header rr_ihdr;
|
2004-12-29 01:30:07 +03:00
|
|
|
uint64_t rr_tsft;
|
2005-01-02 07:23:03 +03:00
|
|
|
uint8_t rr_flags;
|
|
|
|
uint8_t rr_rate;
|
|
|
|
uint16_t rr_chan_freq;
|
|
|
|
uint16_t rr_chan_flags;
|
2004-12-29 01:30:07 +03:00
|
|
|
uint16_t rr_barker_lock;
|
2005-01-02 07:23:03 +03:00
|
|
|
uint8_t rr_antsignal;
|
2004-09-26 06:29:15 +04:00
|
|
|
} __attribute__((__packed__));
|
|
|
|
|
2004-12-29 01:30:07 +03:00
|
|
|
#define RTW_TX_RADIOTAP_PRESENT \
|
|
|
|
((1 << IEEE80211_RADIOTAP_FLAGS) | \
|
|
|
|
(1 << IEEE80211_RADIOTAP_RATE) | \
|
|
|
|
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
|
|
|
|
0)
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
struct rtw_tx_radiotap_header {
|
|
|
|
struct ieee80211_radiotap_header rt_ihdr;
|
2005-01-02 07:23:03 +03:00
|
|
|
uint8_t rt_flags;
|
|
|
|
uint8_t rt_rate;
|
|
|
|
uint16_t rt_chan_freq;
|
|
|
|
uint16_t rt_chan_flags;
|
2004-09-26 06:29:15 +04:00
|
|
|
} __attribute__((__packed__));
|
|
|
|
|
|
|
|
enum rtw_attach_state {FINISHED, FINISH_DESCMAP_LOAD, FINISH_DESCMAP_CREATE,
|
|
|
|
FINISH_DESC_MAP, FINISH_DESC_ALLOC, FINISH_RXMAPS_CREATE,
|
|
|
|
FINISH_TXMAPS_CREATE, FINISH_RESET, FINISH_READ_SROM, FINISH_PARSE_SROM,
|
|
|
|
FINISH_RF_ATTACH, FINISH_ID_STA, FINISH_TXDESCBLK_SETUP,
|
|
|
|
FINISH_TXCTLBLK_SETUP, DETACHED};
|
|
|
|
|
|
|
|
struct rtw_hooks {
|
|
|
|
void *rh_shutdown; /* shutdown hook */
|
|
|
|
void *rh_power; /* power management hook */
|
|
|
|
};
|
|
|
|
|
|
|
|
struct rtw_mtbl {
|
|
|
|
int (*mt_newstate)(struct ieee80211com *,
|
|
|
|
enum ieee80211_state, int);
|
|
|
|
void (*mt_recv_mgmt)(struct ieee80211com *,
|
|
|
|
struct mbuf *, struct ieee80211_node *,
|
2005-01-02 07:23:03 +03:00
|
|
|
int, int, uint32_t);
|
2004-09-26 06:29:15 +04:00
|
|
|
struct ieee80211_node *(*mt_node_alloc)(struct ieee80211com *);
|
|
|
|
void (*mt_node_free)(struct ieee80211com *,
|
|
|
|
struct ieee80211_node *);
|
|
|
|
};
|
|
|
|
|
|
|
|
enum rtw_pwrstate { RTW_OFF = 0, RTW_SLEEP, RTW_ON };
|
|
|
|
|
|
|
|
typedef void (*rtw_continuous_tx_cb_t)(void *arg, int);
|
|
|
|
|
|
|
|
struct rtw_phy {
|
|
|
|
struct rtw_rf *p_rf;
|
|
|
|
struct rtw_regs *p_regs;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct rtw_bbpset {
|
|
|
|
u_int bb_antatten;
|
|
|
|
u_int bb_chestlim;
|
|
|
|
u_int bb_chsqlim;
|
|
|
|
u_int bb_ifagcdet;
|
|
|
|
u_int bb_ifagcini;
|
|
|
|
u_int bb_ifagclimit;
|
|
|
|
u_int bb_lnadet;
|
|
|
|
u_int bb_sys1;
|
|
|
|
u_int bb_sys2;
|
|
|
|
u_int bb_sys3;
|
|
|
|
u_int bb_trl;
|
|
|
|
u_int bb_txagc;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct rtw_rf {
|
|
|
|
void (*rf_destroy)(struct rtw_rf *);
|
|
|
|
/* args: frequency, txpower, power state */
|
2005-01-02 07:23:03 +03:00
|
|
|
int (*rf_init)(struct rtw_rf *, u_int, uint8_t,
|
2004-09-26 06:29:15 +04:00
|
|
|
enum rtw_pwrstate);
|
|
|
|
/* arg: power state */
|
|
|
|
int (*rf_pwrstate)(struct rtw_rf *, enum rtw_pwrstate);
|
|
|
|
/* arg: frequency */
|
|
|
|
int (*rf_tune)(struct rtw_rf *, u_int);
|
|
|
|
/* arg: txpower */
|
2005-01-02 07:23:03 +03:00
|
|
|
int (*rf_txpower)(struct rtw_rf *, uint8_t);
|
2004-09-26 06:29:15 +04:00
|
|
|
rtw_continuous_tx_cb_t rf_continuous_tx_cb;
|
|
|
|
void *rf_continuous_tx_arg;
|
|
|
|
struct rtw_bbpset rf_bbpset;
|
|
|
|
};
|
|
|
|
|
|
|
|
static __inline void
|
|
|
|
rtw_rf_destroy(struct rtw_rf *rf)
|
|
|
|
{
|
|
|
|
(*rf->rf_destroy)(rf);
|
|
|
|
}
|
|
|
|
|
|
|
|
static __inline int
|
2005-01-02 07:23:03 +03:00
|
|
|
rtw_rf_init(struct rtw_rf *rf, u_int freq, uint8_t opaque_txpower,
|
2004-09-26 06:29:15 +04:00
|
|
|
enum rtw_pwrstate power)
|
|
|
|
{
|
|
|
|
return (*rf->rf_init)(rf, freq, opaque_txpower, power);
|
|
|
|
}
|
|
|
|
|
|
|
|
static __inline int
|
|
|
|
rtw_rf_pwrstate(struct rtw_rf *rf, enum rtw_pwrstate power)
|
|
|
|
{
|
|
|
|
return (*rf->rf_pwrstate)(rf, power);
|
|
|
|
}
|
|
|
|
|
|
|
|
static __inline int
|
|
|
|
rtw_rf_tune(struct rtw_rf *rf, u_int freq)
|
|
|
|
{
|
|
|
|
return (*rf->rf_tune)(rf, freq);
|
|
|
|
}
|
|
|
|
|
|
|
|
static __inline int
|
2005-01-02 07:23:03 +03:00
|
|
|
rtw_rf_txpower(struct rtw_rf *rf, uint8_t opaque_txpower)
|
2004-09-26 06:29:15 +04:00
|
|
|
{
|
|
|
|
return (*rf->rf_txpower)(rf, opaque_txpower);
|
|
|
|
}
|
|
|
|
|
|
|
|
typedef int (*rtw_rf_write_t)(struct rtw_regs *, enum rtw_rfchipid, u_int,
|
2005-01-02 07:23:03 +03:00
|
|
|
uint32_t);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
struct rtw_rfbus {
|
|
|
|
struct rtw_regs *b_regs;
|
|
|
|
rtw_rf_write_t b_write;
|
|
|
|
};
|
|
|
|
|
|
|
|
static __inline int
|
|
|
|
rtw_rfbus_write(struct rtw_rfbus *bus, enum rtw_rfchipid rfchipid, u_int addr,
|
2005-01-02 07:23:03 +03:00
|
|
|
uint32_t val)
|
2004-09-26 06:29:15 +04:00
|
|
|
{
|
|
|
|
return (*bus->b_write)(bus->b_regs, rfchipid, addr, val);
|
|
|
|
}
|
|
|
|
|
|
|
|
struct rtw_max2820 {
|
|
|
|
struct rtw_rf mx_rf;
|
|
|
|
struct rtw_rfbus mx_bus;
|
|
|
|
int mx_is_a; /* 1: MAX2820A/MAX2821A */
|
|
|
|
};
|
|
|
|
|
|
|
|
struct rtw_sa2400 {
|
|
|
|
struct rtw_rf sa_rf;
|
|
|
|
struct rtw_rfbus sa_bus;
|
|
|
|
int sa_digphy; /* 1: digital PHY */
|
|
|
|
};
|
|
|
|
|
2004-12-21 02:05:41 +03:00
|
|
|
typedef void (*rtw_pwrstate_t)(struct rtw_regs *, enum rtw_pwrstate, int, int);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
Move the register access mode into struct rtw_regs. Change
rtw_set_access, rtw_set_access1 to match.
Add a subroutine for setting WEP keys. WEP isn't quite finished,
because I have to add the WEP header to Tx packets. Implement the
SIOCS80211NWKEY ioctl for setting WEP keys.
Program the LEDs based on operating state and packet activity.
* On a Revision F RTL8180, blink LED1 at 1Hz to indicate
scan/authenticate/associate states. In the run state, turn LED1
on. In every state, blink LED1 at 5Hz to indicate non-beacon
tx/rx activity. I would like to use two LEDs, but in all my
Rev. F instances, LED0 is not wired to an LED; instead, the
first LED is wired to indicate that the card's power is on.
* On a Revision D RTL8180, program the LEDs so that LED0 indicates
Tx, and LED1 indicates Rx. The Rx LED will blink annoyingly if
there are beacons in the air, but at least the Tx LED is useful.
* Store the hardware revision in the softc to support my futile
attempt at programming LEDs for both Rev. D and Rev. F parts;
I never did get Rev. D LEDs to work right.
* Add a debug flag RTW_DEBUG_LED for the LED transitions.
Add RTW_TPPOLL_ALL, RTW_TPPOLL_SALL to start and stop, respectively,
all of the transmit rings.
In ad hoc mode, allocate a beacon and load it into the beacon ring.
Start the ring. In one trial, the card re-transmitted the beacon
ring's contents several times before stopping. More programming
and testing for ad hoc mode is necessary. I'm not setting the
beacon flag in the transmit descriptor.
Revamp the transmit section to make better use of all the transmit
rings: beacon queue, high-, low-, and medium-priority rings. Put
beacon frames on the beacon ring. All other management frames,
and data frames, go on the medium-priority ring. Power-save data
frames go on the high-priority ring. (Note that powersaving is
not implemented!) This is a work in progress.
Send all 802.11 Management frames at 1Mbps.
After we put a packet on a transmit ring, tickle the right bit in
the TPPOLL to tell RTL8180. Stop all rings on error and in rtw_stop.
Use the RF chip type, not the RTL8180 revision, to choose between
host- and MAC-controlled RF serial I/O. Now the Netgear MA521
works.
Remove bogus definition of bit RTW_TPPOLL_FSWINT.
2005-01-16 14:50:43 +03:00
|
|
|
union rtw_keys {
|
|
|
|
uint8_t rk_keys[4][16];
|
|
|
|
uint32_t rk_words[16];
|
|
|
|
};
|
|
|
|
|
|
|
|
#define RTW_LED_SLOW_TICKS MAX(1, hz/2)
|
|
|
|
#define RTW_LED_FAST_TICKS MAX(1, hz/10)
|
|
|
|
|
|
|
|
struct rtw_led_state {
|
|
|
|
#define RTW_LED0 0x1
|
|
|
|
#define RTW_LED1 0x2
|
|
|
|
uint8_t ls_slowblink:2;
|
|
|
|
uint8_t ls_actblink:2;
|
|
|
|
uint8_t ls_default:2;
|
|
|
|
uint8_t ls_state;
|
|
|
|
uint8_t ls_event;
|
|
|
|
#define RTW_LED_S_RX 0x1
|
|
|
|
#define RTW_LED_S_TX 0x2
|
|
|
|
#define RTW_LED_S_SLOW 0x4
|
|
|
|
struct callout ls_slow_ch;
|
|
|
|
struct callout ls_fast_ch;
|
|
|
|
};
|
Miscellaneous changes. Details below. Important changes flagged
with []. Using the driver with my Linksys WPC11 ver. 4, it seems
to be receiving packets for a change. The WPC11 ver. 4 has a Maxim
RF section. My no-name rtw with Philips RF section still does not
receive any packets.
Keep access-level (analog params > config[0123] registers > none)
in sc_access. Add rtw_set_access for changing the access level.
Make rtw_continuous_tx_enable and other subroutines use rtw_set_access
instead of rtw_config0123_enable and rtw_anaparm_enable.
Factor part of the chip-reset code into rtw_chip_reset1.
Change the 'struct foo (*bar)[N]'-style arguments to
'struct foo *bar'-style arguments.
Consolidate software/hardware Tx/Rx ring setup in rtw_hwring_setup,
rtw_swring_setup.
Add a new constant, SA2400_OPMODE_DEFAULTS, for the bits that we
*always* set in the SA2400 OPMODE register.
Factor some code out into rtw_sa2400_calibrate. (Inspired by the
Linux driver.)
[] When the receiver goes into underrun/overflow state, call a new
subroutine, rtw_kick() that stops the Rx/Tx processes, resets
the chip, reinitializes the Tx/Rx rings, and restarts Rx/Tx
processes. (Inspired by the Linux driver.)
[] In rtw_intr_rx, check for too-short packets before calling
ieee80211_find_rxnode. I believe this will prevent a repeat of
the MCHK exception I saw once on macppc.
[] Use seconds-elapased as well as microseconds-elapsed to set the
next "due date" for the timeout interrupt. This keeps the driver
from programming the timeout to expire too early.
[] In rtw_intr, read RTW_ISR at most 10 times, then get out. If
the interface is not enabled (RTW_F_ENABLED), then get out.
[] In rtw_stop, get out if the interface is not enabled (RTW_F_ENABLED).
Block IPL_NET interrupts. Don't read/write any registers if
the interface is invalid (RTW_F_INVALID).
[] Call rtw_stop in rtw_detach.
2004-12-12 09:37:59 +03:00
|
|
|
|
2004-09-26 06:29:15 +04:00
|
|
|
struct rtw_softc {
|
|
|
|
struct device sc_dev;
|
|
|
|
struct ieee80211com sc_ic;
|
|
|
|
struct rtw_regs sc_regs;
|
|
|
|
bus_dma_tag_t sc_dmat;
|
2005-01-02 07:23:03 +03:00
|
|
|
uint32_t sc_flags;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
enum rtw_attach_state sc_attach_state;
|
|
|
|
enum rtw_rfchipid sc_rfchipid;
|
|
|
|
enum rtw_locale sc_locale;
|
2005-01-02 07:23:03 +03:00
|
|
|
uint8_t sc_phydelay;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
/* s/w Tx/Rx descriptors */
|
2004-12-29 04:06:52 +03:00
|
|
|
struct rtw_txsoft_blk sc_txsoft_blk[RTW_NTXPRI];
|
2004-09-26 06:29:15 +04:00
|
|
|
struct rtw_txdesc_blk sc_txdesc_blk[RTW_NTXPRI];
|
2004-12-29 03:21:37 +03:00
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
struct rtw_rxsoft sc_rxsoft[RTW_RXQLEN];
|
2004-12-29 03:21:37 +03:00
|
|
|
struct rtw_rxdesc_blk sc_rxdesc_blk;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
struct rtw_descs *sc_descs;
|
|
|
|
|
|
|
|
bus_dma_segment_t sc_desc_segs;
|
|
|
|
int sc_desc_nsegs;
|
|
|
|
bus_dmamap_t sc_desc_dmamap;
|
|
|
|
#define sc_desc_physaddr sc_desc_dmamap->dm_segs[0].ds_addr
|
|
|
|
|
|
|
|
struct rtw_srom sc_srom;
|
|
|
|
|
|
|
|
enum rtw_pwrstate sc_pwrstate;
|
|
|
|
|
|
|
|
rtw_pwrstate_t sc_pwrstate_cb;
|
|
|
|
|
|
|
|
struct rtw_rf *sc_rf;
|
|
|
|
|
2005-01-02 07:23:03 +03:00
|
|
|
uint16_t sc_inten;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
/* interrupt acknowledge hook */
|
2005-02-04 05:10:35 +03:00
|
|
|
void (*sc_intr_ack)(struct rtw_regs *);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
int (*sc_enable)(struct rtw_softc *);
|
|
|
|
void (*sc_disable)(struct rtw_softc *);
|
|
|
|
void (*sc_power)(struct rtw_softc *, int);
|
|
|
|
struct rtw_mtbl sc_mtbl;
|
|
|
|
struct rtw_hooks sc_hooks;
|
|
|
|
|
|
|
|
caddr_t sc_radiobpf;
|
|
|
|
|
|
|
|
struct callout sc_scan_ch;
|
|
|
|
u_int sc_cur_chan;
|
|
|
|
|
2005-01-02 07:23:03 +03:00
|
|
|
uint32_t sc_tsfth; /* most significant TSFT bits */
|
|
|
|
uint32_t sc_rcr; /* RTW_RCR */
|
|
|
|
uint8_t sc_csthr; /* carrier-sense threshold */
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
int sc_do_tick; /* indicate 1s ticks */
|
|
|
|
struct timeval sc_tick0; /* first tick */
|
|
|
|
|
At last, I have rtw w/ Philips RF receiving packets.
I added some sysctls to aid debugging:
* hw.rtw.debug -- enable debugging
* hw.rtw.flush_rfio -- Linux voodoo: possibly makes the MAC
"flush" bits down the serial bus to the RF
* hw.rtw.host_rfio: force the host to bang bits to the RF, instead
of the MAC banging bits
* hw.rtw.rfio_delay: after telling the MAC to bang bits to the
RF front-end, delay rfio_delay microseconds.
* hw.rtw.rfprog_fallback: there is this notion of the "RF
programming method." I believe the choice influences the
polarity/timing of the serial bus used to program the RF
front-end. I know the correct choice for Intersil/RFMD/Philips
front-ends, only. For all other front-ends, I "fallback" to
rfprog_fallback.
Make rtw_txdac_enable take an rtw_softc argument. I will probably
revert this change.
Add some Linux voodoo to rtw_continuous_tx_enable. I will probably
revert this change.
Important: add rtw_set_rfprog, which sets the correct RF programming
method. This change and the following change are probably responsible
for making the Philips RF work.
Important: RTW_CONFIG1 is an 8-bit register, treat it that way!
Important: RTW_BRSR is 16-bit, RTW_CRCOUNT, RTW_PHYDELAY, and
RTW_MSR are 8-bit: treat them that way!
Vastly simplify rtw_resume_ticks.
Note to self: set the LED state to match the power state.
Hedge against the possibility that RTW_MSR is protected as
RTW_CONFIG[0123] are, meanwhile reworking that section of rtw_init
a little.
Add sc_anaparm, which isn't used, yet....
2004-12-13 03:48:02 +03:00
|
|
|
uint8_t sc_rev; /* PCI/Cardbus revision */
|
|
|
|
|
|
|
|
uint32_t sc_anaparm; /* register RTW_ANAPARM */
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
union {
|
|
|
|
struct rtw_rx_radiotap_header tap;
|
2005-01-02 07:23:03 +03:00
|
|
|
uint8_t pad[64];
|
2004-09-26 06:29:15 +04:00
|
|
|
} sc_rxtapu;
|
|
|
|
union {
|
|
|
|
struct rtw_tx_radiotap_header tap;
|
2005-01-02 07:23:03 +03:00
|
|
|
uint8_t pad[64];
|
2004-09-26 06:29:15 +04:00
|
|
|
} sc_txtapu;
|
Move the register access mode into struct rtw_regs. Change
rtw_set_access, rtw_set_access1 to match.
Add a subroutine for setting WEP keys. WEP isn't quite finished,
because I have to add the WEP header to Tx packets. Implement the
SIOCS80211NWKEY ioctl for setting WEP keys.
Program the LEDs based on operating state and packet activity.
* On a Revision F RTL8180, blink LED1 at 1Hz to indicate
scan/authenticate/associate states. In the run state, turn LED1
on. In every state, blink LED1 at 5Hz to indicate non-beacon
tx/rx activity. I would like to use two LEDs, but in all my
Rev. F instances, LED0 is not wired to an LED; instead, the
first LED is wired to indicate that the card's power is on.
* On a Revision D RTL8180, program the LEDs so that LED0 indicates
Tx, and LED1 indicates Rx. The Rx LED will blink annoyingly if
there are beacons in the air, but at least the Tx LED is useful.
* Store the hardware revision in the softc to support my futile
attempt at programming LEDs for both Rev. D and Rev. F parts;
I never did get Rev. D LEDs to work right.
* Add a debug flag RTW_DEBUG_LED for the LED transitions.
Add RTW_TPPOLL_ALL, RTW_TPPOLL_SALL to start and stop, respectively,
all of the transmit rings.
In ad hoc mode, allocate a beacon and load it into the beacon ring.
Start the ring. In one trial, the card re-transmitted the beacon
ring's contents several times before stopping. More programming
and testing for ad hoc mode is necessary. I'm not setting the
beacon flag in the transmit descriptor.
Revamp the transmit section to make better use of all the transmit
rings: beacon queue, high-, low-, and medium-priority rings. Put
beacon frames on the beacon ring. All other management frames,
and data frames, go on the medium-priority ring. Power-save data
frames go on the high-priority ring. (Note that powersaving is
not implemented!) This is a work in progress.
Send all 802.11 Management frames at 1Mbps.
After we put a packet on a transmit ring, tickle the right bit in
the TPPOLL to tell RTL8180. Stop all rings on error and in rtw_stop.
Use the RF chip type, not the RTL8180 revision, to choose between
host- and MAC-controlled RF serial I/O. Now the Netgear MA521
works.
Remove bogus definition of bit RTW_TPPOLL_FSWINT.
2005-01-16 14:50:43 +03:00
|
|
|
union rtw_keys sc_keys;
|
|
|
|
int sc_txkey;
|
|
|
|
struct ifqueue sc_beaconq;
|
|
|
|
struct rtw_led_state sc_led_state;
|
|
|
|
int sc_hwverid;
|
2004-09-26 06:29:15 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
#define sc_if sc_ic.ic_if
|
|
|
|
#define sc_rxtap sc_rxtapu.tap
|
|
|
|
#define sc_txtap sc_txtapu.tap
|
|
|
|
|
At last, I have rtw w/ Philips RF receiving packets.
I added some sysctls to aid debugging:
* hw.rtw.debug -- enable debugging
* hw.rtw.flush_rfio -- Linux voodoo: possibly makes the MAC
"flush" bits down the serial bus to the RF
* hw.rtw.host_rfio: force the host to bang bits to the RF, instead
of the MAC banging bits
* hw.rtw.rfio_delay: after telling the MAC to bang bits to the
RF front-end, delay rfio_delay microseconds.
* hw.rtw.rfprog_fallback: there is this notion of the "RF
programming method." I believe the choice influences the
polarity/timing of the serial bus used to program the RF
front-end. I know the correct choice for Intersil/RFMD/Philips
front-ends, only. For all other front-ends, I "fallback" to
rfprog_fallback.
Make rtw_txdac_enable take an rtw_softc argument. I will probably
revert this change.
Add some Linux voodoo to rtw_continuous_tx_enable. I will probably
revert this change.
Important: add rtw_set_rfprog, which sets the correct RF programming
method. This change and the following change are probably responsible
for making the Philips RF work.
Important: RTW_CONFIG1 is an 8-bit register, treat it that way!
Important: RTW_BRSR is 16-bit, RTW_CRCOUNT, RTW_PHYDELAY, and
RTW_MSR are 8-bit: treat them that way!
Vastly simplify rtw_resume_ticks.
Note to self: set the LED state to match the power state.
Hedge against the possibility that RTW_MSR is protected as
RTW_CONFIG[0123] are, meanwhile reworking that section of rtw_init
a little.
Add sc_anaparm, which isn't used, yet....
2004-12-13 03:48:02 +03:00
|
|
|
extern int rtw_host_rfio;
|
|
|
|
|
|
|
|
void rtw_txdac_enable(struct rtw_softc *, int);
|
2004-09-26 06:29:15 +04:00
|
|
|
void rtw_anaparm_enable(struct rtw_regs *, int);
|
|
|
|
void rtw_config0123_enable(struct rtw_regs *, int);
|
Miscellaneous changes. Details below. Important changes flagged
with []. Using the driver with my Linksys WPC11 ver. 4, it seems
to be receiving packets for a change. The WPC11 ver. 4 has a Maxim
RF section. My no-name rtw with Philips RF section still does not
receive any packets.
Keep access-level (analog params > config[0123] registers > none)
in sc_access. Add rtw_set_access for changing the access level.
Make rtw_continuous_tx_enable and other subroutines use rtw_set_access
instead of rtw_config0123_enable and rtw_anaparm_enable.
Factor part of the chip-reset code into rtw_chip_reset1.
Change the 'struct foo (*bar)[N]'-style arguments to
'struct foo *bar'-style arguments.
Consolidate software/hardware Tx/Rx ring setup in rtw_hwring_setup,
rtw_swring_setup.
Add a new constant, SA2400_OPMODE_DEFAULTS, for the bits that we
*always* set in the SA2400 OPMODE register.
Factor some code out into rtw_sa2400_calibrate. (Inspired by the
Linux driver.)
[] When the receiver goes into underrun/overflow state, call a new
subroutine, rtw_kick() that stops the Rx/Tx processes, resets
the chip, reinitializes the Tx/Rx rings, and restarts Rx/Tx
processes. (Inspired by the Linux driver.)
[] In rtw_intr_rx, check for too-short packets before calling
ieee80211_find_rxnode. I believe this will prevent a repeat of
the MCHK exception I saw once on macppc.
[] Use seconds-elapased as well as microseconds-elapsed to set the
next "due date" for the timeout interrupt. This keeps the driver
from programming the timeout to expire too early.
[] In rtw_intr, read RTW_ISR at most 10 times, then get out. If
the interface is not enabled (RTW_F_ENABLED), then get out.
[] In rtw_stop, get out if the interface is not enabled (RTW_F_ENABLED).
Block IPL_NET interrupts. Don't read/write any registers if
the interface is invalid (RTW_F_INVALID).
[] Call rtw_stop in rtw_detach.
2004-12-12 09:37:59 +03:00
|
|
|
void rtw_continuous_tx_enable(struct rtw_softc *, int);
|
Move the register access mode into struct rtw_regs. Change
rtw_set_access, rtw_set_access1 to match.
Add a subroutine for setting WEP keys. WEP isn't quite finished,
because I have to add the WEP header to Tx packets. Implement the
SIOCS80211NWKEY ioctl for setting WEP keys.
Program the LEDs based on operating state and packet activity.
* On a Revision F RTL8180, blink LED1 at 1Hz to indicate
scan/authenticate/associate states. In the run state, turn LED1
on. In every state, blink LED1 at 5Hz to indicate non-beacon
tx/rx activity. I would like to use two LEDs, but in all my
Rev. F instances, LED0 is not wired to an LED; instead, the
first LED is wired to indicate that the card's power is on.
* On a Revision D RTL8180, program the LEDs so that LED0 indicates
Tx, and LED1 indicates Rx. The Rx LED will blink annoyingly if
there are beacons in the air, but at least the Tx LED is useful.
* Store the hardware revision in the softc to support my futile
attempt at programming LEDs for both Rev. D and Rev. F parts;
I never did get Rev. D LEDs to work right.
* Add a debug flag RTW_DEBUG_LED for the LED transitions.
Add RTW_TPPOLL_ALL, RTW_TPPOLL_SALL to start and stop, respectively,
all of the transmit rings.
In ad hoc mode, allocate a beacon and load it into the beacon ring.
Start the ring. In one trial, the card re-transmitted the beacon
ring's contents several times before stopping. More programming
and testing for ad hoc mode is necessary. I'm not setting the
beacon flag in the transmit descriptor.
Revamp the transmit section to make better use of all the transmit
rings: beacon queue, high-, low-, and medium-priority rings. Put
beacon frames on the beacon ring. All other management frames,
and data frames, go on the medium-priority ring. Power-save data
frames go on the high-priority ring. (Note that powersaving is
not implemented!) This is a work in progress.
Send all 802.11 Management frames at 1Mbps.
After we put a packet on a transmit ring, tickle the right bit in
the TPPOLL to tell RTL8180. Stop all rings on error and in rtw_stop.
Use the RF chip type, not the RTL8180 revision, to choose between
host- and MAC-controlled RF serial I/O. Now the Netgear MA521
works.
Remove bogus definition of bit RTW_TPPOLL_FSWINT.
2005-01-16 14:50:43 +03:00
|
|
|
void rtw_set_access(struct rtw_regs *, enum rtw_access);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
void rtw_attach(struct rtw_softc *);
|
|
|
|
int rtw_detach(struct rtw_softc *);
|
|
|
|
int rtw_intr(void *);
|
|
|
|
|
|
|
|
void rtw_disable(struct rtw_softc *);
|
|
|
|
int rtw_enable(struct rtw_softc *);
|
|
|
|
|
|
|
|
int rtw_activate(struct device *, enum devact);
|
|
|
|
void rtw_power(int, void *);
|
|
|
|
void rtw_shutdown(void *);
|
|
|
|
|
|
|
|
const char *rtw_pwrstate_string(enum rtw_pwrstate);
|
|
|
|
|
|
|
|
#endif /* _DEV_IC_RTWVAR_H_ */
|