NetBSD/sys/dev/ic/rtwvar.h

513 lines
14 KiB
C
Raw Normal View History

I have made a small change that suppresses "recovery" from (spurious?) tx timeouts on the beacon queue. The driver's recovery process badly disrupts the MAC's receiver. This needs a closer look, later. Every other fix is by Charles M. Hannum. Charles writes: "With these, the device is quite stable under load, does not experience xmit timeouts, no longer mysteriously freezes, and does not spew a lot of garbage. It does, however, continue to get some "tx fifo underflow"s. global, SYSCTL_SETUP(): a) Removed unused sysctl variables. rtw_io_enable(): b) Change rtw_io_enable to take a softc, and make it call rtw_txring_fixup(). c) Enable the PCI multiple read/write bit. d) Always reset rdb_next to 0 when starting the receive engine. rtw_intr_rx(): e) When processing receive packets, store the next pointer in rdb_next and read it back on the next round, to fix a race condition vs. rtw_tune() during AP discovery and association. f) Remove the special "skip to 0th descriptor" code, because it is no longer needed. rtw_collect_txring(): g) In the "force" case, stop when we catch up to the hardware xmit pointer. rtw_intr_beacon(): h) Resetting tdb_next here looked fishy to me, in light of changes in rtw_collect_txring(). XXX However, this is the one part I haven't tested. rtw_txring_fixup(): i) Add function and line arguments, so we can print out information about the caller. j) In addition to reading the hardware pointer, skip over any additional packets with OWN set -- we may have queued more. rtw_rxring_fixup(): k) Remove this, because it's completely wrong. rtw_intr_ioerror(): l) Don't handle receive overruns here; handle them in the normal receive path. Also changed RTW_INTR_RX and RTW_INTR_IOERROR accordingly. m) Do not fiddle with CR; the transmit engine is still running just fine. n) Do not fiddle with IMR; it was unnecessary. o) Don't touch the receive engine at all; not necessary now that we're leaving CR alone. p) Remove the rtw_do_chip_reset case; it was dangerous and not actually used. rtw_intr(): q) Don't mask off ISR bits when we pass down the ISR value; it's not necessary, and sometimes the other bits useful in debugging output. rtw_seg_too_short(): r) Don't spew here; the caller will do it if necessary. (Stops spewage in an expected case.) rtw_rxdesc_blk: s) Minor change to make the elements have the same order as txdesc_blk. general: t) Added a bunch of debugging output, #ifdef RTW_DIAG, that was useful while investigating the ring management problems. Also moved rtw_txring_fixup() into RTW_DIAG, as I believe the transmit pointer is always kept in sync now, and the function has potential race conditions.
2007-01-06 11:27:53 +03:00
/* $NetBSD: rtwvar.h,v 1.30 2007/01/06 08:27:53 dyoung Exp $ */
/*-
* 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
#define RTW_DEBUG_TUNE 0x0000001
#define RTW_DEBUG_PKTFILT 0x0000002
#define RTW_DEBUG_XMIT 0x0000004
#define RTW_DEBUG_XMIT_DESC 0x0000008
#define RTW_DEBUG_NODE 0x0000010
#define RTW_DEBUG_PWR 0x0000020
#define RTW_DEBUG_ATTACH 0x0000040
#define RTW_DEBUG_REGDUMP 0x0000080
#define RTW_DEBUG_ACCESS 0x0000100
#define RTW_DEBUG_RESET 0x0000200
#define RTW_DEBUG_INIT 0x0000400
#define RTW_DEBUG_IOSTATE 0x0000800
#define RTW_DEBUG_RECV 0x0001000
#define RTW_DEBUG_RECV_DESC 0x0002000
#define RTW_DEBUG_IO_KICK 0x0004000
#define RTW_DEBUG_INTR 0x0008000
#define RTW_DEBUG_PHY 0x0010000
#define RTW_DEBUG_PHYIO 0x0020000
#define RTW_DEBUG_PHYBITIO 0x0040000
#define RTW_DEBUG_TIMEOUT 0x0080000
#define RTW_DEBUG_BUGS 0x0100000
#define RTW_DEBUG_BEACON 0x0200000
#define RTW_DEBUG_LED 0x0400000
#define RTW_DEBUG_KEY 0x0800000
#define RTW_DEBUG_XMIT_RSRC 0x1000000
#define RTW_DEBUG_OACTIVE 0x2000000
#define RTW_DEBUG_MAX 0x3ffffff
extern int rtw_debug;
#define RTW_DPRINTF(__flags, __x) \
if ((rtw_debug & (__flags)) != 0) printf __x
#define DPRINTF(__sc, __flags, __x) \
if (((__sc)->sc_if.if_flags & IFF_DEBUG) != 0) \
RTW_DPRINTF(__flags, __x)
#define RTW_PRINT_REGS(__regs, __dvname, __where) \
rtw_print_regs((__regs), (__dvname), (__where))
#else /* RTW_DEBUG */
2004-12-27 01:37:57 +03:00
#define RTW_DPRINTF(__flags, __x)
#define DPRINTF(__sc, __flags, __x)
#define RTW_PRINT_REGS(__regs, __dvname, __where)
#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
2005-02-27 03:26:58 +03:00
};
/* 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 */
#define RTW_F_DK_VALID 0x00000100 /* keys in DK0-DK3 are valid */
#define RTW_C_RXWEP_40 0x00000200 /* h/w decrypts 40-bit WEP */
#define RTW_C_RXWEP_104 0x00000400 /* h/w decrypts 104-bit WEP */
/* 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};
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;
};
#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 {
uint16_t *sr_content;
uint16_t sr_size;
};
struct rtw_rxsoft {
struct mbuf *rs_mbuf;
bus_dmamap_t rs_dmamap;
};
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;
};
#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 */
#define RTW_MAXPKTSEGS 64 /* Max 64 segments per Tx packet */
#define CASSERT(cond, complaint) complaint[(cond) ? 0 : -1] = complaint[(cond) ? 0 : -1]
/* Note well: the descriptor rings must begin on RTW_DESC_ALIGNMENT
* boundaries. I allocate them consecutively from one buffer, so
* just round up.
*/
#define RTW_TXQLENLO 64 /* low-priority queue length */
#define RTW_TXQLENMD 64 /* medium-priority */
#define RTW_TXQLENHI 64 /* high-priority */
#define RTW_TXQLENBCN 8 /* beacon */
#define RTW_NTXDESCLO RTW_TXQLENLO
#define RTW_NTXDESCMD RTW_TXQLENMD
#define RTW_NTXDESCHI RTW_TXQLENHI
#define RTW_NTXDESCBCN RTW_TXQLENBCN
#define RTW_NTXDESCTOTAL (RTW_NTXDESCLO + RTW_NTXDESCMD + \
RTW_NTXDESCHI + RTW_NTXDESCBCN)
#define RTW_RXQLEN 64
struct rtw_rxdesc_blk {
u_int rdb_ndesc;
I have made a small change that suppresses "recovery" from (spurious?) tx timeouts on the beacon queue. The driver's recovery process badly disrupts the MAC's receiver. This needs a closer look, later. Every other fix is by Charles M. Hannum. Charles writes: "With these, the device is quite stable under load, does not experience xmit timeouts, no longer mysteriously freezes, and does not spew a lot of garbage. It does, however, continue to get some "tx fifo underflow"s. global, SYSCTL_SETUP(): a) Removed unused sysctl variables. rtw_io_enable(): b) Change rtw_io_enable to take a softc, and make it call rtw_txring_fixup(). c) Enable the PCI multiple read/write bit. d) Always reset rdb_next to 0 when starting the receive engine. rtw_intr_rx(): e) When processing receive packets, store the next pointer in rdb_next and read it back on the next round, to fix a race condition vs. rtw_tune() during AP discovery and association. f) Remove the special "skip to 0th descriptor" code, because it is no longer needed. rtw_collect_txring(): g) In the "force" case, stop when we catch up to the hardware xmit pointer. rtw_intr_beacon(): h) Resetting tdb_next here looked fishy to me, in light of changes in rtw_collect_txring(). XXX However, this is the one part I haven't tested. rtw_txring_fixup(): i) Add function and line arguments, so we can print out information about the caller. j) In addition to reading the hardware pointer, skip over any additional packets with OWN set -- we may have queued more. rtw_rxring_fixup(): k) Remove this, because it's completely wrong. rtw_intr_ioerror(): l) Don't handle receive overruns here; handle them in the normal receive path. Also changed RTW_INTR_RX and RTW_INTR_IOERROR accordingly. m) Do not fiddle with CR; the transmit engine is still running just fine. n) Do not fiddle with IMR; it was unnecessary. o) Don't touch the receive engine at all; not necessary now that we're leaving CR alone. p) Remove the rtw_do_chip_reset case; it was dangerous and not actually used. rtw_intr(): q) Don't mask off ISR bits when we pass down the ISR value; it's not necessary, and sometimes the other bits useful in debugging output. rtw_seg_too_short(): r) Don't spew here; the caller will do it if necessary. (Stops spewage in an expected case.) rtw_rxdesc_blk: s) Minor change to make the elements have the same order as txdesc_blk. general: t) Added a bunch of debugging output, #ifdef RTW_DIAG, that was useful while investigating the ring management problems. Also moved rtw_txring_fixup() into RTW_DIAG, as I believe the transmit pointer is always kept in sync now, and the function has potential race conditions.
2007-01-06 11:27:53 +03:00
u_int rdb_next;
bus_dma_tag_t rdb_dmat;
bus_dmamap_t rdb_dmamap;
I have made a small change that suppresses "recovery" from (spurious?) tx timeouts on the beacon queue. The driver's recovery process badly disrupts the MAC's receiver. This needs a closer look, later. Every other fix is by Charles M. Hannum. Charles writes: "With these, the device is quite stable under load, does not experience xmit timeouts, no longer mysteriously freezes, and does not spew a lot of garbage. It does, however, continue to get some "tx fifo underflow"s. global, SYSCTL_SETUP(): a) Removed unused sysctl variables. rtw_io_enable(): b) Change rtw_io_enable to take a softc, and make it call rtw_txring_fixup(). c) Enable the PCI multiple read/write bit. d) Always reset rdb_next to 0 when starting the receive engine. rtw_intr_rx(): e) When processing receive packets, store the next pointer in rdb_next and read it back on the next round, to fix a race condition vs. rtw_tune() during AP discovery and association. f) Remove the special "skip to 0th descriptor" code, because it is no longer needed. rtw_collect_txring(): g) In the "force" case, stop when we catch up to the hardware xmit pointer. rtw_intr_beacon(): h) Resetting tdb_next here looked fishy to me, in light of changes in rtw_collect_txring(). XXX However, this is the one part I haven't tested. rtw_txring_fixup(): i) Add function and line arguments, so we can print out information about the caller. j) In addition to reading the hardware pointer, skip over any additional packets with OWN set -- we may have queued more. rtw_rxring_fixup(): k) Remove this, because it's completely wrong. rtw_intr_ioerror(): l) Don't handle receive overruns here; handle them in the normal receive path. Also changed RTW_INTR_RX and RTW_INTR_IOERROR accordingly. m) Do not fiddle with CR; the transmit engine is still running just fine. n) Do not fiddle with IMR; it was unnecessary. o) Don't touch the receive engine at all; not necessary now that we're leaving CR alone. p) Remove the rtw_do_chip_reset case; it was dangerous and not actually used. rtw_intr(): q) Don't mask off ISR bits when we pass down the ISR value; it's not necessary, and sometimes the other bits useful in debugging output. rtw_seg_too_short(): r) Don't spew here; the caller will do it if necessary. (Stops spewage in an expected case.) rtw_rxdesc_blk: s) Minor change to make the elements have the same order as txdesc_blk. general: t) Added a bunch of debugging output, #ifdef RTW_DIAG, that was useful while investigating the ring management problems. Also moved rtw_txring_fixup() into RTW_DIAG, as I believe the transmit pointer is always kept in sync now, and the function has potential race conditions.
2007-01-06 11:27:53 +03:00
struct rtw_rxdesc *rdb_desc;
};
struct rtw_txdesc_blk {
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;
bus_size_t tdb_basereg;
uint32_t tdb_base;
struct rtw_txdesc *tdb_desc;
};
#define RTW_NEXT_IDX(__htc, __idx) (((__idx) + 1) % (__htc)->tdb_ndesc)
#define RTW_NEXT_DESC(__htc, __idx) \
((__htc)->tdb_physbase + \
sizeof(struct rtw_txdesc) * RTW_NEXT_IDX((__htc), (__idx)))
SIMPLEQ_HEAD(rtw_txq, rtw_txsoft);
struct rtw_txsoft_blk {
/* dirty/free s/w descriptors */
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;
};
struct rtw_descs {
struct rtw_txdesc hd_txlo[RTW_NTXDESCLO];
struct rtw_txdesc hd_txmd[RTW_NTXDESCMD];
struct rtw_txdesc hd_txhi[RTW_NTXDESCMD];
struct rtw_rxdesc hd_rx[RTW_RXQLEN];
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. */
#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)
struct rtw_rx_radiotap_header {
struct ieee80211_radiotap_header rr_ihdr;
uint64_t rr_tsft;
uint8_t rr_flags;
uint8_t rr_rate;
uint16_t rr_chan_freq;
uint16_t rr_chan_flags;
uint16_t rr_barker_lock;
uint8_t rr_antsignal;
} __attribute__((__packed__));
#define RTW_TX_RADIOTAP_PRESENT \
((1 << IEEE80211_RADIOTAP_FLAGS) | \
(1 << IEEE80211_RADIOTAP_RATE) | \
(1 << IEEE80211_RADIOTAP_CHANNEL) | \
0)
struct rtw_tx_radiotap_header {
struct ieee80211_radiotap_header rt_ihdr;
uint8_t rt_flags;
uint8_t rt_rate;
uint16_t rt_chan_freq;
uint16_t rt_chan_flags;
} __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 *,
int, int, uint32_t);
struct ieee80211_node *(*mt_node_alloc)(struct ieee80211_node_table*);
void (*mt_node_free)(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 */
int (*rf_init)(struct rtw_rf *, u_int, uint8_t,
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 */
int (*rf_txpower)(struct rtw_rf *, uint8_t);
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
rtw_rf_init(struct rtw_rf *rf, u_int freq, uint8_t opaque_txpower,
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
rtw_rf_txpower(struct rtw_rf *rf, uint8_t opaque_txpower)
{
return (*rf->rf_txpower)(rf, opaque_txpower);
}
typedef int (*rtw_rf_write_t)(struct rtw_regs *, enum rtw_rfchipid, u_int,
uint32_t);
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,
uint32_t val)
{
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_grf5101 {
struct rtw_rf gr_rf;
struct rtw_rfbus gr_bus;
};
struct rtw_sa2400 {
struct rtw_rf sa_rf;
struct rtw_rfbus sa_bus;
int sa_digphy; /* 1: digital PHY */
};
typedef void (*rtw_pwrstate_t)(struct rtw_regs *, enum rtw_pwrstate, int, 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
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
struct rtw_softc {
struct device sc_dev;
struct ethercom sc_ec;
struct ieee80211com sc_ic;
struct rtw_regs sc_regs;
bus_dma_tag_t sc_dmat;
uint32_t sc_flags;
enum rtw_attach_state sc_attach_state;
enum rtw_rfchipid sc_rfchipid;
enum rtw_locale sc_locale;
uint8_t sc_phydelay;
/* s/w Tx/Rx descriptors */
struct rtw_txsoft_blk sc_txsoft_blk[RTW_NTXPRI];
struct rtw_txdesc_blk sc_txdesc_blk[RTW_NTXPRI];
struct rtw_rxsoft sc_rxsoft[RTW_RXQLEN];
struct rtw_rxdesc_blk sc_rxdesc_blk;
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;
uint16_t sc_inten;
/* interrupt acknowledge hook */
2005-02-04 05:10:35 +03:00
void (*sc_intr_ack)(struct rtw_regs *);
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;
uint32_t sc_tsfth; /* most significant TSFT bits */
uint32_t sc_rcr; /* RTW_RCR */
uint8_t sc_csthr; /* carrier-sense threshold */
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 */
union {
struct rtw_rx_radiotap_header tap;
uint8_t pad[64];
} sc_rxtapu;
union {
struct rtw_tx_radiotap_header tap;
uint8_t pad[64];
} 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;
struct ifqueue sc_beaconq;
struct rtw_led_state sc_led_state;
int sc_hwverid;
};
#define sc_if sc_ec.ec_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
void rtw_txdac_enable(struct rtw_softc *, int);
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);
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_ */