2013-10-18 01:24:24 +04:00
|
|
|
/* $NetBSD: rtw.c,v 1.120 2013/10/17 21:24:24 christos Exp $ */
|
2004-09-26 06:29:15 +04:00
|
|
|
/*-
|
2007-11-17 02:35:19 +03:00
|
|
|
* Copyright (c) 2004, 2005, 2006, 2007 David Young. All rights
|
|
|
|
* reserved.
|
2004-09-26 06:29:15 +04:00
|
|
|
*
|
|
|
|
* Programmed for NetBSD 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.
|
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
/*
|
|
|
|
* Device driver for the Realtek RTL8180 802.11 MAC/BBP.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <sys/cdefs.h>
|
2013-10-18 01:24:24 +04:00
|
|
|
__KERNEL_RCSID(0, "$NetBSD: rtw.c,v 1.120 2013/10/17 21:24:24 christos Exp $");
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
|
|
|
|
#include <sys/param.h>
|
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
|
|
|
#include <sys/sysctl.h>
|
2005-02-27 03:26:58 +03:00
|
|
|
#include <sys/systm.h>
|
2004-09-26 06:29:15 +04:00
|
|
|
#include <sys/callout.h>
|
2005-02-27 03:26:58 +03:00
|
|
|
#include <sys/mbuf.h>
|
2004-09-26 06:29:15 +04:00
|
|
|
#include <sys/malloc.h>
|
|
|
|
#include <sys/kernel.h>
|
|
|
|
#include <sys/time.h>
|
|
|
|
#include <sys/types.h>
|
2008-03-03 15:30:57 +03:00
|
|
|
#include <sys/device.h>
|
2010-11-15 08:56:29 +03:00
|
|
|
#include <sys/sockio.h>
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
#include <machine/endian.h>
|
2007-10-19 15:59:34 +04:00
|
|
|
#include <sys/bus.h>
|
|
|
|
#include <sys/intr.h> /* splnet */
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
#include <net/if.h>
|
|
|
|
#include <net/if_media.h>
|
|
|
|
#include <net/if_ether.h>
|
|
|
|
|
2005-06-22 10:14:51 +04:00
|
|
|
#include <net80211/ieee80211_netbsd.h>
|
2004-09-26 06:29:15 +04:00
|
|
|
#include <net80211/ieee80211_var.h>
|
|
|
|
#include <net80211/ieee80211_radiotap.h>
|
|
|
|
|
|
|
|
#include <net/bpf.h>
|
|
|
|
|
|
|
|
#include <dev/ic/rtwreg.h>
|
|
|
|
#include <dev/ic/rtwvar.h>
|
|
|
|
#include <dev/ic/rtwphyio.h>
|
|
|
|
#include <dev/ic/rtwphy.h>
|
|
|
|
|
|
|
|
#include <dev/ic/smc93cx6var.h>
|
|
|
|
|
2005-11-23 07:12:33 +03:00
|
|
|
static int rtw_rfprog_fallback = 0;
|
|
|
|
static int rtw_host_rfio = 0;
|
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
|
|
|
|
2004-09-26 06:29:15 +04:00
|
|
|
#ifdef RTW_DEBUG
|
2004-12-25 09:58:37 +03:00
|
|
|
int rtw_debug = 0;
|
2005-11-23 07:12:33 +03:00
|
|
|
static int rtw_rxbufs_limit = RTW_RXQLEN;
|
2004-09-26 06:29:15 +04:00
|
|
|
#endif /* RTW_DEBUG */
|
|
|
|
|
2004-12-25 09:58:37 +03:00
|
|
|
#define NEXT_ATTACH_STATE(sc, state) do { \
|
|
|
|
DPRINTF(sc, RTW_DEBUG_ATTACH, \
|
|
|
|
("%s: attach state %s\n", __func__, #state)); \
|
|
|
|
sc->sc_attach_state = state; \
|
2004-09-26 06:29:15 +04:00
|
|
|
} while (0)
|
|
|
|
|
2004-12-27 09:12:28 +03:00
|
|
|
int rtw_dwelltime = 200; /* milliseconds */
|
Here is a grotty hack that lets the RTL8180L handle WEP in the
receive direction, while software handles WEP in the transmit
direction. When net80211 calls rtw's rtw_key_set with a WEP key,
I point the key's wk_cipher at our "fake" cipher, rtw_cipher_wep,
which is alike to ieee80211_cipher_wep except it provides a different
crypto-decapsulation routine, rtw_wep_decap. rtw_wep_decap copies
the key passed to it by net80211, clears the key's SWCRYPT flag,
and then calls wep_decap. Now wep_decap will decapsulate, but it
will *not* re-decrypt.
XXX I need to check whether the hardware supports 40-bit WEP,
XXX 104-bit WEP, or both, and act accordingly.
2005-06-28 11:19:33 +04:00
|
|
|
static struct ieee80211_cipher rtw_cipher_wep;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
Use device_t and its accessors throughout. Use aprint_*_dev().
Improve PMF-ability.
Add a 'flags' argument to suspend/resume handlers and
callers such as pmf_system_suspend().
Define a flag, PMF_F_SELF, which indicates to PMF that a
device is suspending/resuming itself. Add helper routines,
pmf_device_suspend_self(dev) and pmf_device_resume_self(dev),
that call pmf_device_suspend(dev, PMF_F_SELF) and
pmf_device_resume(dev, PMF_F_SELF), respectively. Use
PMF_F_SELF to suspend/resume self in ath(4), audio(4),
rtw(4), and sip(4).
In ath(4) and in rtw(4), replace the icky sc_enable/sc_disable
callbacks, provided by the bus front-end, with
self-suspension/resumption. Also, clean up the bus
front-ends. Make sure that the interrupt handler is
disestablished during suspension. Get rid of driver-private
flags (e.g., RTW_F_ENABLED, ath_softc->sc_invalid); use
device_is_active()/device_has_power() calls, instead.
In the network-class suspend handler, call if_stop(, 0)
instead of if_stop(, 1), because the latter is superfluous
(bus- and driver-suspension hooks will 'disable' the NIC),
and it may cause recursion.
In the network-class resume handler, prevent infinite
recursion through if_init() by getting out early if we are
self-suspending (PMF_F_SELF).
rtw(4) improvements:
Destroy rtw(4) callouts when we detach it. Make rtw at
pci detachable. Print some more information with the "rx
frame too long" warning.
Remove activate() methods:
Get rid of rtw_activate() and ath_activate(). The device
activate() methods are not good for much these days.
Make ath at cardbus resume with crypto functions intact:
Introduce a boolean device property, "pmf-powerdown". If
pmf-powerdown is present and false, it indicates that a
bus back-end should not remove power from a device.
Honor this property in cardbus_child_suspend().
Set this property to 'false' in ath_attach(), since removing
power from an ath at cardbus seems to lobotomize the WPA
crypto engine. XXX Should the pmf-powerdown property
propagate toward the root of the device tree?
Miscellaneous ath(4) changes:
Warn if ath(4) tries to write crypto keys to suspended
hardware.
Reduce differences between FreeBSD and NetBSD in ath(4)
multicast filter setup.
Make ath_printrxbuf() print an rx descriptor's status &
key index, to help debug crypto errors.
Shorten a staircase in ath_ioctl(). Don't check for
ieee80211_ioctl() return code ERESTART, it never happens.
2008-03-12 21:02:21 +03:00
|
|
|
static void rtw_disable_interrupts(struct rtw_regs *);
|
|
|
|
static void rtw_enable_interrupts(struct rtw_softc *);
|
|
|
|
|
|
|
|
static int rtw_init(struct ifnet *);
|
|
|
|
|
2004-12-19 11:19:25 +03:00
|
|
|
static void rtw_start(struct ifnet *);
|
2005-11-23 07:12:33 +03:00
|
|
|
static void rtw_reset_oactive(struct rtw_softc *);
|
|
|
|
static struct mbuf *rtw_beacon_alloc(struct rtw_softc *,
|
|
|
|
struct ieee80211_node *);
|
|
|
|
static u_int rtw_txring_next(struct rtw_regs *, struct rtw_txdesc_blk *);
|
2004-12-19 11:19:25 +03:00
|
|
|
|
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
|
|
|
static void rtw_io_enable(struct rtw_softc *, uint8_t, int);
|
2005-06-27 09:49:13 +04:00
|
|
|
static int rtw_key_delete(struct ieee80211com *, const struct ieee80211_key *);
|
|
|
|
static int rtw_key_set(struct ieee80211com *, const struct ieee80211_key *,
|
|
|
|
const u_int8_t[IEEE80211_ADDR_LEN]);
|
|
|
|
static void rtw_key_update_end(struct ieee80211com *);
|
|
|
|
static void rtw_key_update_begin(struct ieee80211com *);
|
2005-09-06 05:59:26 +04:00
|
|
|
static int rtw_wep_decap(struct ieee80211_key *, struct mbuf *, int);
|
2005-06-27 09:49:13 +04:00
|
|
|
static void rtw_wep_setkeys(struct rtw_softc *, struct ieee80211_key *, int);
|
|
|
|
|
2005-03-02 08:20:43 +03:00
|
|
|
static void rtw_led_attach(struct rtw_led_state *, void *);
|
Use device_t and its accessors throughout. Use aprint_*_dev().
Improve PMF-ability.
Add a 'flags' argument to suspend/resume handlers and
callers such as pmf_system_suspend().
Define a flag, PMF_F_SELF, which indicates to PMF that a
device is suspending/resuming itself. Add helper routines,
pmf_device_suspend_self(dev) and pmf_device_resume_self(dev),
that call pmf_device_suspend(dev, PMF_F_SELF) and
pmf_device_resume(dev, PMF_F_SELF), respectively. Use
PMF_F_SELF to suspend/resume self in ath(4), audio(4),
rtw(4), and sip(4).
In ath(4) and in rtw(4), replace the icky sc_enable/sc_disable
callbacks, provided by the bus front-end, with
self-suspension/resumption. Also, clean up the bus
front-ends. Make sure that the interrupt handler is
disestablished during suspension. Get rid of driver-private
flags (e.g., RTW_F_ENABLED, ath_softc->sc_invalid); use
device_is_active()/device_has_power() calls, instead.
In the network-class suspend handler, call if_stop(, 0)
instead of if_stop(, 1), because the latter is superfluous
(bus- and driver-suspension hooks will 'disable' the NIC),
and it may cause recursion.
In the network-class resume handler, prevent infinite
recursion through if_init() by getting out early if we are
self-suspending (PMF_F_SELF).
rtw(4) improvements:
Destroy rtw(4) callouts when we detach it. Make rtw at
pci detachable. Print some more information with the "rx
frame too long" warning.
Remove activate() methods:
Get rid of rtw_activate() and ath_activate(). The device
activate() methods are not good for much these days.
Make ath at cardbus resume with crypto functions intact:
Introduce a boolean device property, "pmf-powerdown". If
pmf-powerdown is present and false, it indicates that a
bus back-end should not remove power from a device.
Honor this property in cardbus_child_suspend().
Set this property to 'false' in ath_attach(), since removing
power from an ath at cardbus seems to lobotomize the WPA
crypto engine. XXX Should the pmf-powerdown property
propagate toward the root of the device tree?
Miscellaneous ath(4) changes:
Warn if ath(4) tries to write crypto keys to suspended
hardware.
Reduce differences between FreeBSD and NetBSD in ath(4)
multicast filter setup.
Make ath_printrxbuf() print an rx descriptor's status &
key index, to help debug crypto errors.
Shorten a staircase in ath_ioctl(). Don't check for
ieee80211_ioctl() return code ERESTART, it never happens.
2008-03-12 21:02:21 +03:00
|
|
|
static void rtw_led_detach(struct rtw_led_state *);
|
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
|
|
|
static void rtw_led_init(struct rtw_regs *);
|
|
|
|
static void rtw_led_slowblink(void *);
|
|
|
|
static void rtw_led_fastblink(void *);
|
|
|
|
static void rtw_led_set(struct rtw_led_state *, struct rtw_regs *, int);
|
|
|
|
|
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
|
|
|
static int rtw_sysctl_verify_rfio(SYSCTLFN_PROTO);
|
|
|
|
static int rtw_sysctl_verify_rfprog(SYSCTLFN_PROTO);
|
|
|
|
#ifdef RTW_DEBUG
|
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
|
|
|
static void rtw_dump_rings(struct rtw_softc *sc);
|
2004-12-25 09:58:37 +03:00
|
|
|
static void rtw_print_txdesc(struct rtw_softc *, const char *,
|
2004-12-29 04:06:52 +03:00
|
|
|
struct rtw_txsoft *, struct rtw_txdesc_blk *, int);
|
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
|
|
|
static int rtw_sysctl_verify_debug(SYSCTLFN_PROTO);
|
If defined(RTW_DEBUG), provide a sysctl (hw.rtw.rxbufs_limit) for
limiting the number of rx buffers an rtw may allocate. Use this
sysctl to test the code that copes with buffer exhaustion.
Allocate at most RTW_RXQLEN rx buffers, stopping at the sysctl
limit. Record in sc_nrxdesc how many were allocated, and put the
end-of-ring indication on sc_rxdesc[sc_nrxdesc - 1]. In rtw_init,
if no rx buffers could be allocated, log a complaint, clear
IFF_RUNNING, and exit with an error.
Many changes to accomodate a short rx ring, mainly of the "add a
rx-ring length argument" variety. XXX I really should consolidate
all of the rx ring variables in one struct and pass that to the
rx-ring subroutines.
Bug fix: after calling MCLGET, use the (m->m_flags & M_EXT) idiom
to check for success, instead of m != NULL.
Bug fix: at the top of rtw_start, if IFF_RUNNING is not set, or
IFF_OACTIVE is, get out.
2004-12-29 01:21:15 +03:00
|
|
|
static int rtw_sysctl_verify_rxbufs_limit(SYSCTLFN_PROTO);
|
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
|
|
|
#endif /* RTW_DEBUG */
|
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
|
|
|
#ifdef RTW_DIAG
|
|
|
|
static void rtw_txring_fixup(struct rtw_softc *sc, const char *fn, int ln);
|
|
|
|
#endif /* RTW_DIAG */
|
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
|
|
|
|
|
|
|
/*
|
|
|
|
* Setup sysctl(3) MIB, hw.rtw.*
|
|
|
|
*
|
2008-11-12 15:35:50 +03:00
|
|
|
* TBD condition CTLFLAG_PERMANENT on being a module or not
|
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
|
|
|
*/
|
|
|
|
SYSCTL_SETUP(sysctl_rtw, "sysctl rtw(4) subtree setup")
|
|
|
|
{
|
|
|
|
int rc;
|
2005-06-20 06:49:18 +04:00
|
|
|
const struct sysctlnode *cnode, *rnode;
|
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
|
|
|
|
|
|
|
if ((rc = sysctl_createv(clog, 0, NULL, &rnode,
|
|
|
|
CTLFLAG_PERMANENT, CTLTYPE_NODE, "hw", NULL,
|
|
|
|
NULL, 0, NULL, 0, CTL_HW, CTL_EOL)) != 0)
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
if ((rc = sysctl_createv(clog, 0, &rnode, &rnode,
|
|
|
|
CTLFLAG_PERMANENT, CTLTYPE_NODE, "rtw",
|
|
|
|
"Realtek RTL818x 802.11 controls",
|
|
|
|
NULL, 0, NULL, 0, CTL_CREATE, CTL_EOL)) != 0)
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
#ifdef RTW_DEBUG
|
|
|
|
/* control debugging printfs */
|
|
|
|
if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
|
|
|
|
CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
|
|
|
|
"debug", SYSCTL_DESCR("Enable RTL818x debugging output"),
|
|
|
|
rtw_sysctl_verify_debug, 0, &rtw_debug, 0,
|
|
|
|
CTL_CREATE, CTL_EOL)) != 0)
|
|
|
|
goto err;
|
If defined(RTW_DEBUG), provide a sysctl (hw.rtw.rxbufs_limit) for
limiting the number of rx buffers an rtw may allocate. Use this
sysctl to test the code that copes with buffer exhaustion.
Allocate at most RTW_RXQLEN rx buffers, stopping at the sysctl
limit. Record in sc_nrxdesc how many were allocated, and put the
end-of-ring indication on sc_rxdesc[sc_nrxdesc - 1]. In rtw_init,
if no rx buffers could be allocated, log a complaint, clear
IFF_RUNNING, and exit with an error.
Many changes to accomodate a short rx ring, mainly of the "add a
rx-ring length argument" variety. XXX I really should consolidate
all of the rx ring variables in one struct and pass that to the
rx-ring subroutines.
Bug fix: after calling MCLGET, use the (m->m_flags & M_EXT) idiom
to check for success, instead of m != NULL.
Bug fix: at the top of rtw_start, if IFF_RUNNING is not set, or
IFF_OACTIVE is, get out.
2004-12-29 01:21:15 +03:00
|
|
|
|
|
|
|
/* Limit rx buffers, for simulating resource exhaustion. */
|
|
|
|
if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
|
|
|
|
CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
|
|
|
|
"rxbufs_limit",
|
|
|
|
SYSCTL_DESCR("Set rx buffers limit"),
|
|
|
|
rtw_sysctl_verify_rxbufs_limit, 0, &rtw_rxbufs_limit, 0,
|
|
|
|
CTL_CREATE, CTL_EOL)) != 0)
|
|
|
|
goto err;
|
|
|
|
|
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
|
|
|
#endif /* RTW_DEBUG */
|
|
|
|
/* set fallback RF programming method */
|
|
|
|
if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
|
|
|
|
CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
|
|
|
|
"rfprog_fallback",
|
|
|
|
SYSCTL_DESCR("Set fallback RF programming method"),
|
|
|
|
rtw_sysctl_verify_rfprog, 0, &rtw_rfprog_fallback, 0,
|
|
|
|
CTL_CREATE, CTL_EOL)) != 0)
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
/* force host to control RF I/O bus */
|
|
|
|
if ((rc = sysctl_createv(clog, 0, &rnode, &cnode,
|
|
|
|
CTLFLAG_PERMANENT|CTLFLAG_READWRITE, CTLTYPE_INT,
|
|
|
|
"host_rfio", SYSCTL_DESCR("Enable host control of RF I/O"),
|
|
|
|
rtw_sysctl_verify_rfio, 0, &rtw_host_rfio, 0,
|
|
|
|
CTL_CREATE, CTL_EOL)) != 0)
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
return;
|
|
|
|
err:
|
|
|
|
printf("%s: sysctl_createv failed (rc = %d)\n", __func__, rc);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
rtw_sysctl_verify(SYSCTLFN_ARGS, int lower, int upper)
|
|
|
|
{
|
|
|
|
int error, t;
|
|
|
|
struct sysctlnode node;
|
|
|
|
|
|
|
|
node = *rnode;
|
|
|
|
t = *(int*)rnode->sysctl_data;
|
|
|
|
node.sysctl_data = &t;
|
|
|
|
error = sysctl_lookup(SYSCTLFN_CALL(&node));
|
|
|
|
if (error || newp == NULL)
|
|
|
|
return (error);
|
|
|
|
|
|
|
|
if (t < lower || t > upper)
|
|
|
|
return (EINVAL);
|
|
|
|
|
|
|
|
*(int*)rnode->sysctl_data = t;
|
|
|
|
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
rtw_sysctl_verify_rfprog(SYSCTLFN_ARGS)
|
|
|
|
{
|
2005-06-10 06:35:34 +04:00
|
|
|
return rtw_sysctl_verify(SYSCTLFN_CALL(__UNCONST(rnode)), 0,
|
Per discussion on tech-kern and tech-userlevel, move the bit-twiddling
macros, __BIT, __BITS, SHIFTIN, SHIFTOUT, and __arraycount() from
lib/libkern/libkern.h to sys/cdefs.h. Add a __-prefix to SHIFTIN
and SHIFTOUT, and add a manual page for the bit-twiddling macros,
bits(3).
Make the __BIT and __BITS macros "widthless," as best I can, by
changing their type to uintmax_t from uint32_t. XXX The manual
page lags this change by a bit.
Define __PRIxBIT and __PRIxBITS printf(3) format strings.
2006-08-31 23:24:37 +04:00
|
|
|
__SHIFTOUT(RTW_CONFIG4_RFTYPE_MASK, RTW_CONFIG4_RFTYPE_MASK));
|
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
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
rtw_sysctl_verify_rfio(SYSCTLFN_ARGS)
|
|
|
|
{
|
2005-06-10 06:35:34 +04:00
|
|
|
return rtw_sysctl_verify(SYSCTLFN_CALL(__UNCONST(rnode)), 0, 1);
|
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
|
|
|
}
|
|
|
|
|
2004-09-26 06:29:15 +04:00
|
|
|
#ifdef RTW_DEBUG
|
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
|
|
|
static int
|
|
|
|
rtw_sysctl_verify_debug(SYSCTLFN_ARGS)
|
|
|
|
{
|
2005-06-10 06:35:34 +04:00
|
|
|
return rtw_sysctl_verify(SYSCTLFN_CALL(__UNCONST(rnode)),
|
|
|
|
0, RTW_DEBUG_MAX);
|
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
|
|
|
}
|
|
|
|
|
If defined(RTW_DEBUG), provide a sysctl (hw.rtw.rxbufs_limit) for
limiting the number of rx buffers an rtw may allocate. Use this
sysctl to test the code that copes with buffer exhaustion.
Allocate at most RTW_RXQLEN rx buffers, stopping at the sysctl
limit. Record in sc_nrxdesc how many were allocated, and put the
end-of-ring indication on sc_rxdesc[sc_nrxdesc - 1]. In rtw_init,
if no rx buffers could be allocated, log a complaint, clear
IFF_RUNNING, and exit with an error.
Many changes to accomodate a short rx ring, mainly of the "add a
rx-ring length argument" variety. XXX I really should consolidate
all of the rx ring variables in one struct and pass that to the
rx-ring subroutines.
Bug fix: after calling MCLGET, use the (m->m_flags & M_EXT) idiom
to check for success, instead of m != NULL.
Bug fix: at the top of rtw_start, if IFF_RUNNING is not set, or
IFF_OACTIVE is, get out.
2004-12-29 01:21:15 +03:00
|
|
|
static int
|
|
|
|
rtw_sysctl_verify_rxbufs_limit(SYSCTLFN_ARGS)
|
|
|
|
{
|
2005-06-10 06:35:34 +04:00
|
|
|
return rtw_sysctl_verify(SYSCTLFN_CALL(__UNCONST(rnode)),
|
|
|
|
0, RTW_RXQLEN);
|
If defined(RTW_DEBUG), provide a sysctl (hw.rtw.rxbufs_limit) for
limiting the number of rx buffers an rtw may allocate. Use this
sysctl to test the code that copes with buffer exhaustion.
Allocate at most RTW_RXQLEN rx buffers, stopping at the sysctl
limit. Record in sc_nrxdesc how many were allocated, and put the
end-of-ring indication on sc_rxdesc[sc_nrxdesc - 1]. In rtw_init,
if no rx buffers could be allocated, log a complaint, clear
IFF_RUNNING, and exit with an error.
Many changes to accomodate a short rx ring, mainly of the "add a
rx-ring length argument" variety. XXX I really should consolidate
all of the rx ring variables in one struct and pass that to the
rx-ring subroutines.
Bug fix: after calling MCLGET, use the (m->m_flags & M_EXT) idiom
to check for success, instead of m != NULL.
Bug fix: at the top of rtw_start, if IFF_RUNNING is not set, or
IFF_OACTIVE is, get out.
2004-12-29 01:21:15 +03:00
|
|
|
}
|
|
|
|
|
2004-09-26 06:29:15 +04:00
|
|
|
static void
|
|
|
|
rtw_print_regs(struct rtw_regs *regs, const char *dvname, const char *where)
|
|
|
|
{
|
2004-12-25 09:58:37 +03:00
|
|
|
#define PRINTREG32(sc, reg) \
|
|
|
|
RTW_DPRINTF(RTW_DEBUG_REGDUMP, \
|
|
|
|
("%s: reg[ " #reg " / %03x ] = %08x\n", \
|
2004-09-26 06:29:15 +04:00
|
|
|
dvname, reg, RTW_READ(regs, reg)))
|
|
|
|
|
2004-12-25 09:58:37 +03:00
|
|
|
#define PRINTREG16(sc, reg) \
|
|
|
|
RTW_DPRINTF(RTW_DEBUG_REGDUMP, \
|
|
|
|
("%s: reg[ " #reg " / %03x ] = %04x\n", \
|
2004-09-26 06:29:15 +04:00
|
|
|
dvname, reg, RTW_READ16(regs, reg)))
|
|
|
|
|
2004-12-25 09:58:37 +03:00
|
|
|
#define PRINTREG8(sc, reg) \
|
|
|
|
RTW_DPRINTF(RTW_DEBUG_REGDUMP, \
|
|
|
|
("%s: reg[ " #reg " / %03x ] = %02x\n", \
|
2004-09-26 06:29:15 +04:00
|
|
|
dvname, reg, RTW_READ8(regs, reg)))
|
|
|
|
|
2004-12-25 09:58:37 +03:00
|
|
|
RTW_DPRINTF(RTW_DEBUG_REGDUMP, ("%s: %s\n", dvname, where));
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
PRINTREG32(regs, RTW_IDR0);
|
|
|
|
PRINTREG32(regs, RTW_IDR1);
|
|
|
|
PRINTREG32(regs, RTW_MAR0);
|
|
|
|
PRINTREG32(regs, RTW_MAR1);
|
|
|
|
PRINTREG32(regs, RTW_TSFTRL);
|
|
|
|
PRINTREG32(regs, RTW_TSFTRH);
|
|
|
|
PRINTREG32(regs, RTW_TLPDA);
|
|
|
|
PRINTREG32(regs, RTW_TNPDA);
|
|
|
|
PRINTREG32(regs, RTW_THPDA);
|
|
|
|
PRINTREG32(regs, RTW_TCR);
|
|
|
|
PRINTREG32(regs, RTW_RCR);
|
|
|
|
PRINTREG32(regs, RTW_TINT);
|
|
|
|
PRINTREG32(regs, RTW_TBDA);
|
|
|
|
PRINTREG32(regs, RTW_ANAPARM);
|
|
|
|
PRINTREG32(regs, RTW_BB);
|
|
|
|
PRINTREG32(regs, RTW_PHYCFG);
|
|
|
|
PRINTREG32(regs, RTW_WAKEUP0L);
|
|
|
|
PRINTREG32(regs, RTW_WAKEUP0H);
|
|
|
|
PRINTREG32(regs, RTW_WAKEUP1L);
|
|
|
|
PRINTREG32(regs, RTW_WAKEUP1H);
|
|
|
|
PRINTREG32(regs, RTW_WAKEUP2LL);
|
|
|
|
PRINTREG32(regs, RTW_WAKEUP2LH);
|
|
|
|
PRINTREG32(regs, RTW_WAKEUP2HL);
|
|
|
|
PRINTREG32(regs, RTW_WAKEUP2HH);
|
|
|
|
PRINTREG32(regs, RTW_WAKEUP3LL);
|
|
|
|
PRINTREG32(regs, RTW_WAKEUP3LH);
|
|
|
|
PRINTREG32(regs, RTW_WAKEUP3HL);
|
|
|
|
PRINTREG32(regs, RTW_WAKEUP3HH);
|
|
|
|
PRINTREG32(regs, RTW_WAKEUP4LL);
|
|
|
|
PRINTREG32(regs, RTW_WAKEUP4LH);
|
|
|
|
PRINTREG32(regs, RTW_WAKEUP4HL);
|
|
|
|
PRINTREG32(regs, RTW_WAKEUP4HH);
|
|
|
|
PRINTREG32(regs, RTW_DK0);
|
|
|
|
PRINTREG32(regs, RTW_DK1);
|
|
|
|
PRINTREG32(regs, RTW_DK2);
|
|
|
|
PRINTREG32(regs, RTW_DK3);
|
|
|
|
PRINTREG32(regs, RTW_RETRYCTR);
|
|
|
|
PRINTREG32(regs, RTW_RDSAR);
|
|
|
|
PRINTREG32(regs, RTW_FER);
|
|
|
|
PRINTREG32(regs, RTW_FEMR);
|
|
|
|
PRINTREG32(regs, RTW_FPSR);
|
|
|
|
PRINTREG32(regs, RTW_FFER);
|
|
|
|
|
|
|
|
/* 16-bit registers */
|
|
|
|
PRINTREG16(regs, RTW_BRSR);
|
|
|
|
PRINTREG16(regs, RTW_IMR);
|
|
|
|
PRINTREG16(regs, RTW_ISR);
|
|
|
|
PRINTREG16(regs, RTW_BCNITV);
|
|
|
|
PRINTREG16(regs, RTW_ATIMWND);
|
|
|
|
PRINTREG16(regs, RTW_BINTRITV);
|
|
|
|
PRINTREG16(regs, RTW_ATIMTRITV);
|
|
|
|
PRINTREG16(regs, RTW_CRC16ERR);
|
|
|
|
PRINTREG16(regs, RTW_CRC0);
|
|
|
|
PRINTREG16(regs, RTW_CRC1);
|
|
|
|
PRINTREG16(regs, RTW_CRC2);
|
|
|
|
PRINTREG16(regs, RTW_CRC3);
|
|
|
|
PRINTREG16(regs, RTW_CRC4);
|
|
|
|
PRINTREG16(regs, RTW_CWR);
|
|
|
|
|
|
|
|
/* 8-bit registers */
|
|
|
|
PRINTREG8(regs, RTW_CR);
|
|
|
|
PRINTREG8(regs, RTW_9346CR);
|
|
|
|
PRINTREG8(regs, RTW_CONFIG0);
|
|
|
|
PRINTREG8(regs, RTW_CONFIG1);
|
|
|
|
PRINTREG8(regs, RTW_CONFIG2);
|
|
|
|
PRINTREG8(regs, RTW_MSR);
|
|
|
|
PRINTREG8(regs, RTW_CONFIG3);
|
|
|
|
PRINTREG8(regs, RTW_CONFIG4);
|
|
|
|
PRINTREG8(regs, RTW_TESTR);
|
|
|
|
PRINTREG8(regs, RTW_PSR);
|
|
|
|
PRINTREG8(regs, RTW_SCR);
|
|
|
|
PRINTREG8(regs, RTW_PHYDELAY);
|
|
|
|
PRINTREG8(regs, RTW_CRCOUNT);
|
|
|
|
PRINTREG8(regs, RTW_PHYADDR);
|
|
|
|
PRINTREG8(regs, RTW_PHYDATAW);
|
|
|
|
PRINTREG8(regs, RTW_PHYDATAR);
|
|
|
|
PRINTREG8(regs, RTW_CONFIG5);
|
|
|
|
PRINTREG8(regs, RTW_TPPOLL);
|
|
|
|
|
|
|
|
PRINTREG16(regs, RTW_BSSID16);
|
|
|
|
PRINTREG32(regs, RTW_BSSID32);
|
|
|
|
#undef PRINTREG32
|
|
|
|
#undef PRINTREG16
|
|
|
|
#undef PRINTREG8
|
|
|
|
}
|
|
|
|
#endif /* RTW_DEBUG */
|
|
|
|
|
|
|
|
void
|
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
|
|
|
rtw_continuous_tx_enable(struct rtw_softc *sc, int enable)
|
2004-09-26 06:29:15 +04:00
|
|
|
{
|
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_regs *regs = &sc->sc_regs;
|
|
|
|
|
2005-01-02 07:23:03 +03:00
|
|
|
uint32_t tcr;
|
2004-09-26 06:29:15 +04:00
|
|
|
tcr = RTW_READ(regs, RTW_TCR);
|
|
|
|
tcr &= ~RTW_TCR_LBK_MASK;
|
|
|
|
if (enable)
|
|
|
|
tcr |= RTW_TCR_LBK_CONT;
|
|
|
|
else
|
|
|
|
tcr |= RTW_TCR_LBK_NORMAL;
|
|
|
|
RTW_WRITE(regs, RTW_TCR, tcr);
|
|
|
|
RTW_SYNC(regs, RTW_TCR, RTW_TCR);
|
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
|
|
|
rtw_set_access(regs, RTW_ACCESS_ANAPARM);
|
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
|
|
|
rtw_txdac_enable(sc, !enable);
|
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
|
|
|
rtw_set_access(regs, RTW_ACCESS_ANAPARM);/* XXX Voodoo from Linux. */
|
|
|
|
rtw_set_access(regs, RTW_ACCESS_NONE);
|
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-12-27 01:59:41 +03:00
|
|
|
#ifdef RTW_DEBUG
|
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
|
|
|
static const char *
|
|
|
|
rtw_access_string(enum rtw_access access)
|
|
|
|
{
|
|
|
|
switch (access) {
|
|
|
|
case RTW_ACCESS_NONE:
|
|
|
|
return "none";
|
|
|
|
case RTW_ACCESS_CONFIG:
|
|
|
|
return "config";
|
|
|
|
case RTW_ACCESS_ANAPARM:
|
|
|
|
return "anaparm";
|
|
|
|
default:
|
|
|
|
return "unknown";
|
|
|
|
}
|
|
|
|
}
|
2004-12-27 01:59:41 +03:00
|
|
|
#endif /* RTW_DEBUG */
|
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
|
|
|
|
|
|
|
static void
|
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
|
|
|
rtw_set_access1(struct rtw_regs *regs, enum rtw_access naccess)
|
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
|
|
|
{
|
2006-09-03 09:10:24 +04:00
|
|
|
KASSERT(/* naccess >= RTW_ACCESS_NONE && */
|
|
|
|
naccess <= RTW_ACCESS_ANAPARM);
|
|
|
|
KASSERT(/* regs->r_access >= RTW_ACCESS_NONE && */
|
|
|
|
regs->r_access <= RTW_ACCESS_ANAPARM);
|
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
|
|
|
|
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
|
|
|
if (naccess == regs->r_access)
|
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
|
|
|
return;
|
|
|
|
|
|
|
|
switch (naccess) {
|
|
|
|
case RTW_ACCESS_NONE:
|
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
|
|
|
switch (regs->r_access) {
|
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
|
|
|
case RTW_ACCESS_ANAPARM:
|
|
|
|
rtw_anaparm_enable(regs, 0);
|
|
|
|
/*FALLTHROUGH*/
|
|
|
|
case RTW_ACCESS_CONFIG:
|
|
|
|
rtw_config0123_enable(regs, 0);
|
|
|
|
/*FALLTHROUGH*/
|
|
|
|
case RTW_ACCESS_NONE:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case RTW_ACCESS_CONFIG:
|
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
|
|
|
switch (regs->r_access) {
|
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
|
|
|
case RTW_ACCESS_NONE:
|
|
|
|
rtw_config0123_enable(regs, 1);
|
|
|
|
/*FALLTHROUGH*/
|
|
|
|
case RTW_ACCESS_CONFIG:
|
|
|
|
break;
|
|
|
|
case RTW_ACCESS_ANAPARM:
|
|
|
|
rtw_anaparm_enable(regs, 0);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case RTW_ACCESS_ANAPARM:
|
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
|
|
|
switch (regs->r_access) {
|
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
|
|
|
case RTW_ACCESS_NONE:
|
|
|
|
rtw_config0123_enable(regs, 1);
|
|
|
|
/*FALLTHROUGH*/
|
|
|
|
case RTW_ACCESS_CONFIG:
|
|
|
|
rtw_anaparm_enable(regs, 1);
|
|
|
|
/*FALLTHROUGH*/
|
|
|
|
case RTW_ACCESS_ANAPARM:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
break;
|
2004-09-26 06:29:15 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
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
|
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
|
|
|
rtw_set_access(struct rtw_regs *regs, enum rtw_access access)
|
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
|
|
|
{
|
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
|
|
|
rtw_set_access1(regs, access);
|
2004-12-25 09:58:37 +03:00
|
|
|
RTW_DPRINTF(RTW_DEBUG_ACCESS,
|
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
|
|
|
("%s: access %s -> %s\n", __func__,
|
|
|
|
rtw_access_string(regs->r_access),
|
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
|
|
|
rtw_access_string(access)));
|
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
|
|
|
regs->r_access = access;
|
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
|
|
|
/*
|
|
|
|
* Enable registers, switch register banks.
|
|
|
|
*/
|
|
|
|
void
|
|
|
|
rtw_config0123_enable(struct rtw_regs *regs, int enable)
|
|
|
|
{
|
2005-01-02 07:23:03 +03:00
|
|
|
uint8_t ecr;
|
2004-09-26 06:29:15 +04:00
|
|
|
ecr = RTW_READ8(regs, RTW_9346CR);
|
|
|
|
ecr &= ~(RTW_9346CR_EEM_MASK | RTW_9346CR_EECS | RTW_9346CR_EESK);
|
|
|
|
if (enable)
|
|
|
|
ecr |= RTW_9346CR_EEM_CONFIG;
|
2004-12-20 04:13:45 +03:00
|
|
|
else {
|
|
|
|
RTW_WBW(regs, RTW_9346CR, MAX(RTW_CONFIG0, RTW_CONFIG3));
|
2004-09-26 06:29:15 +04:00
|
|
|
ecr |= RTW_9346CR_EEM_NORMAL;
|
2004-12-20 04:13:45 +03:00
|
|
|
}
|
2004-09-26 06:29:15 +04:00
|
|
|
RTW_WRITE8(regs, RTW_9346CR, ecr);
|
|
|
|
RTW_SYNC(regs, RTW_9346CR, RTW_9346CR);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* requires rtw_config0123_enable(, 1) */
|
|
|
|
void
|
|
|
|
rtw_anaparm_enable(struct rtw_regs *regs, int enable)
|
|
|
|
{
|
2005-01-02 07:23:03 +03:00
|
|
|
uint8_t cfg3;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
cfg3 = RTW_READ8(regs, RTW_CONFIG3);
|
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
|
|
|
cfg3 |= RTW_CONFIG3_CLKRUNEN;
|
|
|
|
if (enable)
|
|
|
|
cfg3 |= RTW_CONFIG3_PARMEN;
|
|
|
|
else
|
2004-09-26 06:29:15 +04:00
|
|
|
cfg3 &= ~RTW_CONFIG3_PARMEN;
|
|
|
|
RTW_WRITE8(regs, RTW_CONFIG3, cfg3);
|
|
|
|
RTW_SYNC(regs, RTW_CONFIG3, RTW_CONFIG3);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* requires rtw_anaparm_enable(, 1) */
|
|
|
|
void
|
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
|
|
|
rtw_txdac_enable(struct rtw_softc *sc, int enable)
|
2004-09-26 06:29:15 +04:00
|
|
|
{
|
2005-01-02 07:23:03 +03:00
|
|
|
uint32_t anaparm;
|
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
|
|
|
struct rtw_regs *regs = &sc->sc_regs;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
anaparm = RTW_READ(regs, RTW_ANAPARM);
|
|
|
|
if (enable)
|
|
|
|
anaparm &= ~RTW_ANAPARM_TXDACOFF;
|
|
|
|
else
|
|
|
|
anaparm |= RTW_ANAPARM_TXDACOFF;
|
|
|
|
RTW_WRITE(regs, RTW_ANAPARM, anaparm);
|
|
|
|
RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM);
|
|
|
|
}
|
|
|
|
|
2005-12-24 23:27:29 +03:00
|
|
|
static inline int
|
2007-12-21 21:22:43 +03:00
|
|
|
rtw_chip_reset1(struct rtw_regs *regs, device_t dev)
|
2004-09-26 06:29:15 +04:00
|
|
|
{
|
2005-01-02 07:23:03 +03:00
|
|
|
uint8_t cr;
|
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
|
|
|
int i;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
RTW_WRITE8(regs, RTW_CR, RTW_CR_RST);
|
|
|
|
|
|
|
|
RTW_WBR(regs, RTW_CR, RTW_CR);
|
|
|
|
|
2004-12-25 09:58:37 +03:00
|
|
|
for (i = 0; i < 1000; i++) {
|
2004-09-26 06:29:15 +04:00
|
|
|
if ((cr = RTW_READ8(regs, RTW_CR) & RTW_CR_RST) == 0) {
|
2004-12-25 09:58:37 +03:00
|
|
|
RTW_DPRINTF(RTW_DEBUG_RESET,
|
2007-12-21 21:22:43 +03:00
|
|
|
("%s: reset in %dus\n", device_xname(dev), i));
|
2004-09-26 06:29:15 +04:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
RTW_RBR(regs, RTW_CR, RTW_CR);
|
2004-12-25 09:58:37 +03:00
|
|
|
DELAY(10); /* 10us */
|
2004-09-26 06:29:15 +04:00
|
|
|
}
|
|
|
|
|
2007-12-21 21:22:43 +03:00
|
|
|
aprint_error_dev(dev, "reset failed\n");
|
2004-09-26 06:29:15 +04:00
|
|
|
return ETIMEDOUT;
|
|
|
|
}
|
|
|
|
|
2005-12-24 23:27:29 +03:00
|
|
|
static inline int
|
2007-12-21 21:22:43 +03:00
|
|
|
rtw_chip_reset(struct rtw_regs *regs, device_t dev)
|
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
|
|
|
{
|
|
|
|
uint32_t tcr;
|
|
|
|
|
|
|
|
/* from Linux driver */
|
|
|
|
tcr = RTW_TCR_CWMIN | RTW_TCR_MXDMA_2048 |
|
Per discussion on tech-kern and tech-userlevel, move the bit-twiddling
macros, __BIT, __BITS, SHIFTIN, SHIFTOUT, and __arraycount() from
lib/libkern/libkern.h to sys/cdefs.h. Add a __-prefix to SHIFTIN
and SHIFTOUT, and add a manual page for the bit-twiddling macros,
bits(3).
Make the __BIT and __BITS macros "widthless," as best I can, by
changing their type to uintmax_t from uint32_t. XXX The manual
page lags this change by a bit.
Define __PRIxBIT and __PRIxBITS printf(3) format strings.
2006-08-31 23:24:37 +04:00
|
|
|
__SHIFTIN(7, RTW_TCR_SRL_MASK) | __SHIFTIN(7, RTW_TCR_LRL_MASK);
|
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
|
|
|
|
|
|
|
RTW_WRITE(regs, RTW_TCR, tcr);
|
|
|
|
|
|
|
|
RTW_WBW(regs, RTW_CR, RTW_TCR);
|
|
|
|
|
2007-12-21 21:22:43 +03:00
|
|
|
return rtw_chip_reset1(regs, dev);
|
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
|
|
|
}
|
|
|
|
|
Here is a grotty hack that lets the RTL8180L handle WEP in the
receive direction, while software handles WEP in the transmit
direction. When net80211 calls rtw's rtw_key_set with a WEP key,
I point the key's wk_cipher at our "fake" cipher, rtw_cipher_wep,
which is alike to ieee80211_cipher_wep except it provides a different
crypto-decapsulation routine, rtw_wep_decap. rtw_wep_decap copies
the key passed to it by net80211, clears the key's SWCRYPT flag,
and then calls wep_decap. Now wep_decap will decapsulate, but it
will *not* re-decrypt.
XXX I need to check whether the hardware supports 40-bit WEP,
XXX 104-bit WEP, or both, and act accordingly.
2005-06-28 11:19:33 +04:00
|
|
|
static int
|
2005-11-23 07:12:33 +03:00
|
|
|
rtw_wep_decap(struct ieee80211_key *k, struct mbuf *m, int hdrlen)
|
Here is a grotty hack that lets the RTL8180L handle WEP in the
receive direction, while software handles WEP in the transmit
direction. When net80211 calls rtw's rtw_key_set with a WEP key,
I point the key's wk_cipher at our "fake" cipher, rtw_cipher_wep,
which is alike to ieee80211_cipher_wep except it provides a different
crypto-decapsulation routine, rtw_wep_decap. rtw_wep_decap copies
the key passed to it by net80211, clears the key's SWCRYPT flag,
and then calls wep_decap. Now wep_decap will decapsulate, but it
will *not* re-decrypt.
XXX I need to check whether the hardware supports 40-bit WEP,
XXX 104-bit WEP, or both, and act accordingly.
2005-06-28 11:19:33 +04:00
|
|
|
{
|
|
|
|
struct ieee80211_key keycopy;
|
|
|
|
|
|
|
|
RTW_DPRINTF(RTW_DEBUG_KEY, ("%s:\n", __func__));
|
|
|
|
|
|
|
|
keycopy = *k;
|
|
|
|
keycopy.wk_flags &= ~IEEE80211_KEY_SWCRYPT;
|
|
|
|
|
2005-11-23 07:12:33 +03:00
|
|
|
return (*ieee80211_cipher_wep.ic_decap)(&keycopy, m, hdrlen);
|
Here is a grotty hack that lets the RTL8180L handle WEP in the
receive direction, while software handles WEP in the transmit
direction. When net80211 calls rtw's rtw_key_set with a WEP key,
I point the key's wk_cipher at our "fake" cipher, rtw_cipher_wep,
which is alike to ieee80211_cipher_wep except it provides a different
crypto-decapsulation routine, rtw_wep_decap. rtw_wep_decap copies
the key passed to it by net80211, clears the key's SWCRYPT flag,
and then calls wep_decap. Now wep_decap will decapsulate, but it
will *not* re-decrypt.
XXX I need to check whether the hardware supports 40-bit WEP,
XXX 104-bit WEP, or both, and act accordingly.
2005-06-28 11:19:33 +04:00
|
|
|
}
|
|
|
|
|
2005-06-27 09:49:13 +04:00
|
|
|
static int
|
|
|
|
rtw_key_delete(struct ieee80211com *ic, const struct ieee80211_key *k)
|
|
|
|
{
|
|
|
|
struct rtw_softc *sc = ic->ic_ifp->if_softc;
|
|
|
|
|
2008-03-15 02:04:42 +03:00
|
|
|
DPRINTF(sc, RTW_DEBUG_KEY, ("%s: delete key %u\n", __func__,
|
|
|
|
k->wk_keyix));
|
2005-06-27 09:49:13 +04:00
|
|
|
|
2008-03-15 02:04:42 +03:00
|
|
|
KASSERT(k->wk_keyix < IEEE80211_WEP_NKID);
|
|
|
|
|
|
|
|
if (k->wk_keylen != 0 &&
|
|
|
|
k->wk_cipher->ic_cipher == IEEE80211_CIPHER_WEP)
|
2005-06-27 09:49:13 +04:00
|
|
|
sc->sc_flags &= ~RTW_F_DK_VALID;
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
rtw_key_set(struct ieee80211com *ic, const struct ieee80211_key *k,
|
2006-11-16 04:32:37 +03:00
|
|
|
const u_int8_t mac[IEEE80211_ADDR_LEN])
|
2005-06-27 09:49:13 +04:00
|
|
|
{
|
|
|
|
struct rtw_softc *sc = ic->ic_ifp->if_softc;
|
|
|
|
|
|
|
|
DPRINTF(sc, RTW_DEBUG_KEY, ("%s: set key %u\n", __func__, k->wk_keyix));
|
|
|
|
|
2008-03-15 02:04:42 +03:00
|
|
|
KASSERT(k->wk_keyix < IEEE80211_WEP_NKID);
|
2005-06-27 09:49:13 +04:00
|
|
|
|
|
|
|
sc->sc_flags &= ~RTW_F_DK_VALID;
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2006-11-16 04:32:37 +03:00
|
|
|
rtw_key_update_begin(struct ieee80211com *ic)
|
2005-06-27 09:49:13 +04:00
|
|
|
{
|
2005-09-07 09:25:41 +04:00
|
|
|
#ifdef RTW_DEBUG
|
2005-06-27 09:49:13 +04:00
|
|
|
struct ifnet *ifp = ic->ic_ifp;
|
|
|
|
struct rtw_softc *sc = ifp->if_softc;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
DPRINTF(sc, RTW_DEBUG_KEY, ("%s:\n", __func__));
|
|
|
|
}
|
|
|
|
|
2008-03-15 02:59:01 +03:00
|
|
|
static void
|
|
|
|
rtw_tx_kick(struct rtw_regs *regs, uint8_t ringsel)
|
|
|
|
{
|
|
|
|
uint8_t tppoll;
|
|
|
|
|
|
|
|
tppoll = RTW_READ8(regs, RTW_TPPOLL);
|
|
|
|
tppoll &= ~RTW_TPPOLL_SALL;
|
|
|
|
tppoll |= ringsel & RTW_TPPOLL_ALL;
|
|
|
|
RTW_WRITE8(regs, RTW_TPPOLL, tppoll);
|
|
|
|
RTW_SYNC(regs, RTW_TPPOLL, RTW_TPPOLL);
|
|
|
|
}
|
|
|
|
|
2005-06-27 09:49:13 +04:00
|
|
|
static void
|
|
|
|
rtw_key_update_end(struct ieee80211com *ic)
|
|
|
|
{
|
|
|
|
struct ifnet *ifp = ic->ic_ifp;
|
|
|
|
struct rtw_softc *sc = ifp->if_softc;
|
|
|
|
|
|
|
|
DPRINTF(sc, RTW_DEBUG_KEY, ("%s:\n", __func__));
|
|
|
|
|
2005-11-23 07:12:33 +03:00
|
|
|
if ((sc->sc_flags & RTW_F_DK_VALID) != 0 ||
|
Use device_t and its accessors throughout. Use aprint_*_dev().
Improve PMF-ability.
Add a 'flags' argument to suspend/resume handlers and
callers such as pmf_system_suspend().
Define a flag, PMF_F_SELF, which indicates to PMF that a
device is suspending/resuming itself. Add helper routines,
pmf_device_suspend_self(dev) and pmf_device_resume_self(dev),
that call pmf_device_suspend(dev, PMF_F_SELF) and
pmf_device_resume(dev, PMF_F_SELF), respectively. Use
PMF_F_SELF to suspend/resume self in ath(4), audio(4),
rtw(4), and sip(4).
In ath(4) and in rtw(4), replace the icky sc_enable/sc_disable
callbacks, provided by the bus front-end, with
self-suspension/resumption. Also, clean up the bus
front-ends. Make sure that the interrupt handler is
disestablished during suspension. Get rid of driver-private
flags (e.g., RTW_F_ENABLED, ath_softc->sc_invalid); use
device_is_active()/device_has_power() calls, instead.
In the network-class suspend handler, call if_stop(, 0)
instead of if_stop(, 1), because the latter is superfluous
(bus- and driver-suspension hooks will 'disable' the NIC),
and it may cause recursion.
In the network-class resume handler, prevent infinite
recursion through if_init() by getting out early if we are
self-suspending (PMF_F_SELF).
rtw(4) improvements:
Destroy rtw(4) callouts when we detach it. Make rtw at
pci detachable. Print some more information with the "rx
frame too long" warning.
Remove activate() methods:
Get rid of rtw_activate() and ath_activate(). The device
activate() methods are not good for much these days.
Make ath at cardbus resume with crypto functions intact:
Introduce a boolean device property, "pmf-powerdown". If
pmf-powerdown is present and false, it indicates that a
bus back-end should not remove power from a device.
Honor this property in cardbus_child_suspend().
Set this property to 'false' in ath_attach(), since removing
power from an ath at cardbus seems to lobotomize the WPA
crypto engine. XXX Should the pmf-powerdown property
propagate toward the root of the device tree?
Miscellaneous ath(4) changes:
Warn if ath(4) tries to write crypto keys to suspended
hardware.
Reduce differences between FreeBSD and NetBSD in ath(4)
multicast filter setup.
Make ath_printrxbuf() print an rx descriptor's status &
key index, to help debug crypto errors.
Shorten a staircase in ath_ioctl(). Don't check for
ieee80211_ioctl() return code ERESTART, it never happens.
2008-03-12 21:02:21 +03:00
|
|
|
!device_is_active(sc->sc_dev))
|
2005-06-27 09:49:13 +04:00
|
|
|
return;
|
|
|
|
|
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
|
|
|
rtw_io_enable(sc, RTW_CR_RE | RTW_CR_TE, 0);
|
2005-06-27 09:49:13 +04:00
|
|
|
rtw_wep_setkeys(sc, ic->ic_nw_keys, ic->ic_def_txkey);
|
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
|
|
|
rtw_io_enable(sc, RTW_CR_RE | RTW_CR_TE,
|
2005-06-27 09:49:13 +04:00
|
|
|
(ifp->if_flags & IFF_RUNNING) != 0);
|
|
|
|
}
|
|
|
|
|
2008-03-15 03:21:12 +03:00
|
|
|
static bool
|
2005-11-23 07:12:33 +03:00
|
|
|
rtw_key_hwsupp(uint32_t flags, const struct ieee80211_key *k)
|
|
|
|
{
|
|
|
|
if (k->wk_cipher->ic_cipher != IEEE80211_CIPHER_WEP)
|
2008-03-15 03:21:12 +03:00
|
|
|
return false;
|
2005-11-23 07:12:33 +03:00
|
|
|
|
|
|
|
return ((flags & RTW_C_RXWEP_40) != 0 && k->wk_keylen == 5) ||
|
|
|
|
((flags & RTW_C_RXWEP_104) != 0 && k->wk_keylen == 13);
|
|
|
|
}
|
|
|
|
|
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
|
|
|
static void
|
2005-06-22 10:14:51 +04:00
|
|
|
rtw_wep_setkeys(struct rtw_softc *sc, struct ieee80211_key *wk, int txkey)
|
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
|
|
|
{
|
2005-11-23 07:12:33 +03:00
|
|
|
uint8_t psr, scr;
|
2008-03-15 03:21:12 +03:00
|
|
|
int i, keylen = 0;
|
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
|
|
|
struct rtw_regs *regs;
|
|
|
|
union rtw_keys *rk;
|
|
|
|
|
|
|
|
regs = &sc->sc_regs;
|
|
|
|
rk = &sc->sc_keys;
|
|
|
|
|
2011-07-04 20:06:17 +04:00
|
|
|
(void)memset(rk, 0, sizeof(*rk));
|
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
|
|
|
|
2005-11-23 07:12:33 +03:00
|
|
|
/* Temporarily use software crypto for all keys. */
|
|
|
|
for (i = 0; i < IEEE80211_WEP_NKID; i++) {
|
|
|
|
if (wk[i].wk_cipher == &rtw_cipher_wep)
|
|
|
|
wk[i].wk_cipher = &ieee80211_cipher_wep;
|
|
|
|
}
|
|
|
|
|
Here is a grotty hack that lets the RTL8180L handle WEP in the
receive direction, while software handles WEP in the transmit
direction. When net80211 calls rtw's rtw_key_set with a WEP key,
I point the key's wk_cipher at our "fake" cipher, rtw_cipher_wep,
which is alike to ieee80211_cipher_wep except it provides a different
crypto-decapsulation routine, rtw_wep_decap. rtw_wep_decap copies
the key passed to it by net80211, clears the key's SWCRYPT flag,
and then calls wep_decap. Now wep_decap will decapsulate, but it
will *not* re-decrypt.
XXX I need to check whether the hardware supports 40-bit WEP,
XXX 104-bit WEP, or both, and act accordingly.
2005-06-28 11:19:33 +04:00
|
|
|
rtw_set_access(regs, RTW_ACCESS_CONFIG);
|
|
|
|
|
|
|
|
psr = RTW_READ8(regs, RTW_PSR);
|
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
|
|
|
scr = RTW_READ8(regs, RTW_SCR);
|
|
|
|
scr &= ~(RTW_SCR_KM_MASK | RTW_SCR_TXSECON | RTW_SCR_RXSECON);
|
|
|
|
|
|
|
|
if ((sc->sc_ic.ic_flags & IEEE80211_F_PRIVACY) == 0)
|
|
|
|
goto out;
|
|
|
|
|
2008-03-15 03:21:12 +03:00
|
|
|
for (i = 0; i < IEEE80211_WEP_NKID; i++) {
|
2006-02-19 11:10:06 +03:00
|
|
|
if (!rtw_key_hwsupp(sc->sc_flags, &wk[i]))
|
|
|
|
continue;
|
|
|
|
if (i == txkey) {
|
|
|
|
keylen = wk[i].wk_keylen;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
keylen = MAX(keylen, wk[i].wk_keylen);
|
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
|
|
|
}
|
|
|
|
|
2006-02-19 11:10:06 +03:00
|
|
|
if (keylen == 5)
|
|
|
|
scr |= RTW_SCR_KM_WEP40 | RTW_SCR_RXSECON;
|
|
|
|
else if (keylen == 13)
|
|
|
|
scr |= RTW_SCR_KM_WEP104 | RTW_SCR_RXSECON;
|
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
|
|
|
|
2005-06-27 09:49:13 +04:00
|
|
|
for (i = 0; i < IEEE80211_WEP_NKID; i++) {
|
2006-02-19 11:10:06 +03:00
|
|
|
if (wk[i].wk_keylen != keylen ||
|
2005-11-23 07:12:33 +03:00
|
|
|
wk[i].wk_cipher->ic_cipher != IEEE80211_CIPHER_WEP)
|
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
|
|
|
continue;
|
2005-11-23 07:12:33 +03:00
|
|
|
/* h/w will decrypt, s/w still strips headers */
|
|
|
|
wk[i].wk_cipher = &rtw_cipher_wep;
|
2005-06-27 09:49:13 +04:00
|
|
|
(void)memcpy(rk->rk_keys[i], wk[i].wk_key, wk[i].wk_keylen);
|
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
|
|
|
}
|
|
|
|
|
|
|
|
out:
|
Here is a grotty hack that lets the RTL8180L handle WEP in the
receive direction, while software handles WEP in the transmit
direction. When net80211 calls rtw's rtw_key_set with a WEP key,
I point the key's wk_cipher at our "fake" cipher, rtw_cipher_wep,
which is alike to ieee80211_cipher_wep except it provides a different
crypto-decapsulation routine, rtw_wep_decap. rtw_wep_decap copies
the key passed to it by net80211, clears the key's SWCRYPT flag,
and then calls wep_decap. Now wep_decap will decapsulate, but it
will *not* re-decrypt.
XXX I need to check whether the hardware supports 40-bit WEP,
XXX 104-bit WEP, or both, and act accordingly.
2005-06-28 11:19:33 +04:00
|
|
|
RTW_WRITE8(regs, RTW_PSR, psr & ~RTW_PSR_PSEN);
|
|
|
|
|
2007-05-29 22:38:20 +04:00
|
|
|
bus_space_write_region_stream_4(regs->r_bt, regs->r_bh,
|
2007-05-29 22:33:38 +04:00
|
|
|
RTW_DK0, rk->rk_words, __arraycount(rk->rk_words));
|
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
|
|
|
|
Here is a grotty hack that lets the RTL8180L handle WEP in the
receive direction, while software handles WEP in the transmit
direction. When net80211 calls rtw's rtw_key_set with a WEP key,
I point the key's wk_cipher at our "fake" cipher, rtw_cipher_wep,
which is alike to ieee80211_cipher_wep except it provides a different
crypto-decapsulation routine, rtw_wep_decap. rtw_wep_decap copies
the key passed to it by net80211, clears the key's SWCRYPT flag,
and then calls wep_decap. Now wep_decap will decapsulate, but it
will *not* re-decrypt.
XXX I need to check whether the hardware supports 40-bit WEP,
XXX 104-bit WEP, or both, and act accordingly.
2005-06-28 11:19:33 +04:00
|
|
|
bus_space_barrier(regs->r_bt, regs->r_bh, RTW_DK0, sizeof(rk->rk_words),
|
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
|
|
|
BUS_SPACE_BARRIER_SYNC);
|
|
|
|
|
2008-03-15 03:21:12 +03:00
|
|
|
RTW_DPRINTF(RTW_DEBUG_KEY,
|
|
|
|
("%s.%d: scr %02" PRIx8 ", keylen %d\n", __func__, __LINE__, scr,
|
|
|
|
keylen));
|
|
|
|
|
2005-11-23 07:12:33 +03:00
|
|
|
RTW_WBW(regs, RTW_DK0, RTW_PSR);
|
Here is a grotty hack that lets the RTL8180L handle WEP in the
receive direction, while software handles WEP in the transmit
direction. When net80211 calls rtw's rtw_key_set with a WEP key,
I point the key's wk_cipher at our "fake" cipher, rtw_cipher_wep,
which is alike to ieee80211_cipher_wep except it provides a different
crypto-decapsulation routine, rtw_wep_decap. rtw_wep_decap copies
the key passed to it by net80211, clears the key's SWCRYPT flag,
and then calls wep_decap. Now wep_decap will decapsulate, but it
will *not* re-decrypt.
XXX I need to check whether the hardware supports 40-bit WEP,
XXX 104-bit WEP, or both, and act accordingly.
2005-06-28 11:19:33 +04:00
|
|
|
RTW_WRITE8(regs, RTW_PSR, psr);
|
2005-11-23 07:12:33 +03:00
|
|
|
RTW_WBW(regs, RTW_PSR, RTW_SCR);
|
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
|
|
|
RTW_WRITE8(regs, RTW_SCR, scr);
|
|
|
|
RTW_SYNC(regs, RTW_SCR, RTW_SCR);
|
|
|
|
rtw_set_access(regs, RTW_ACCESS_NONE);
|
2005-06-27 09:49:13 +04:00
|
|
|
sc->sc_flags |= RTW_F_DK_VALID;
|
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
|
|
|
}
|
|
|
|
|
2005-12-24 23:27:29 +03:00
|
|
|
static inline int
|
2007-12-21 21:22:43 +03:00
|
|
|
rtw_recall_eeprom(struct rtw_regs *regs, device_t dev)
|
2004-09-26 06:29:15 +04:00
|
|
|
{
|
|
|
|
int i;
|
2005-01-02 07:23:03 +03:00
|
|
|
uint8_t ecr;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
ecr = RTW_READ8(regs, RTW_9346CR);
|
|
|
|
ecr = (ecr & ~RTW_9346CR_EEM_MASK) | RTW_9346CR_EEM_AUTOLOAD;
|
|
|
|
RTW_WRITE8(regs, RTW_9346CR, ecr);
|
|
|
|
|
|
|
|
RTW_WBR(regs, RTW_9346CR, RTW_9346CR);
|
|
|
|
|
2005-09-07 09:25:41 +04:00
|
|
|
/* wait 25ms for completion */
|
|
|
|
for (i = 0; i < 250; i++) {
|
2004-09-26 06:29:15 +04:00
|
|
|
ecr = RTW_READ8(regs, RTW_9346CR);
|
|
|
|
if ((ecr & RTW_9346CR_EEM_MASK) == RTW_9346CR_EEM_NORMAL) {
|
2004-12-25 09:58:37 +03:00
|
|
|
RTW_DPRINTF(RTW_DEBUG_RESET,
|
2007-12-21 21:22:43 +03:00
|
|
|
("%s: recall EEPROM in %dus\n", device_xname(dev),
|
|
|
|
i * 100));
|
2004-09-26 06:29:15 +04:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
RTW_RBR(regs, RTW_9346CR, RTW_9346CR);
|
|
|
|
DELAY(100);
|
|
|
|
}
|
2007-12-21 21:22:43 +03:00
|
|
|
aprint_error_dev(dev, "recall EEPROM failed\n");
|
2004-09-26 06:29:15 +04:00
|
|
|
return ETIMEDOUT;
|
|
|
|
}
|
|
|
|
|
2005-12-24 23:27:29 +03:00
|
|
|
static inline int
|
2004-09-26 06:29:15 +04:00
|
|
|
rtw_reset(struct rtw_softc *sc)
|
|
|
|
{
|
|
|
|
int rc;
|
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 config1;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2005-06-27 09:49:13 +04:00
|
|
|
sc->sc_flags &= ~RTW_F_DK_VALID;
|
|
|
|
|
2007-12-21 21:22:43 +03:00
|
|
|
if ((rc = rtw_chip_reset(&sc->sc_regs, sc->sc_dev)) != 0)
|
2004-09-26 06:29:15 +04:00
|
|
|
return rc;
|
|
|
|
|
2007-12-21 21:22:43 +03:00
|
|
|
rc = rtw_recall_eeprom(&sc->sc_regs, sc->sc_dev);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
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
|
|
|
config1 = RTW_READ8(&sc->sc_regs, RTW_CONFIG1);
|
|
|
|
RTW_WRITE8(&sc->sc_regs, RTW_CONFIG1, config1 & ~RTW_CONFIG1_PMEN);
|
2004-09-26 06:29:15 +04:00
|
|
|
/* TBD turn off maximum power saving? */
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-12-24 23:27:29 +03:00
|
|
|
static inline int
|
2004-12-29 04:06:52 +03:00
|
|
|
rtw_txdesc_dmamaps_create(bus_dma_tag_t dmat, struct rtw_txsoft *descs,
|
2004-09-26 06:29:15 +04:00
|
|
|
u_int ndescs)
|
|
|
|
{
|
|
|
|
int i, rc = 0;
|
|
|
|
for (i = 0; i < ndescs; i++) {
|
|
|
|
rc = bus_dmamap_create(dmat, MCLBYTES, RTW_MAXPKTSEGS, MCLBYTES,
|
2004-12-29 04:06:52 +03:00
|
|
|
0, 0, &descs[i].ts_dmamap);
|
2004-09-26 06:29:15 +04:00
|
|
|
if (rc != 0)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2005-12-24 23:27:29 +03:00
|
|
|
static inline int
|
2004-12-29 04:06:52 +03:00
|
|
|
rtw_rxdesc_dmamaps_create(bus_dma_tag_t dmat, struct rtw_rxsoft *descs,
|
2004-09-26 06:29:15 +04:00
|
|
|
u_int ndescs)
|
|
|
|
{
|
|
|
|
int i, rc = 0;
|
|
|
|
for (i = 0; i < ndescs; i++) {
|
|
|
|
rc = bus_dmamap_create(dmat, MCLBYTES, 1, MCLBYTES, 0, 0,
|
2004-12-29 04:06:52 +03:00
|
|
|
&descs[i].rs_dmamap);
|
2004-09-26 06:29:15 +04:00
|
|
|
if (rc != 0)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2005-12-24 23:27:29 +03:00
|
|
|
static inline void
|
2004-12-29 04:06:52 +03:00
|
|
|
rtw_rxdesc_dmamaps_destroy(bus_dma_tag_t dmat, struct rtw_rxsoft *descs,
|
2004-09-26 06:29:15 +04:00
|
|
|
u_int ndescs)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < ndescs; i++) {
|
2004-12-29 04:06:52 +03:00
|
|
|
if (descs[i].rs_dmamap != NULL)
|
|
|
|
bus_dmamap_destroy(dmat, descs[i].rs_dmamap);
|
2004-09-26 06:29:15 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-12-24 23:27:29 +03:00
|
|
|
static inline void
|
2004-12-29 04:06:52 +03:00
|
|
|
rtw_txdesc_dmamaps_destroy(bus_dma_tag_t dmat, struct rtw_txsoft *descs,
|
2004-09-26 06:29:15 +04:00
|
|
|
u_int ndescs)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < ndescs; i++) {
|
2004-12-29 04:06:52 +03:00
|
|
|
if (descs[i].ts_dmamap != NULL)
|
|
|
|
bus_dmamap_destroy(dmat, descs[i].ts_dmamap);
|
2004-09-26 06:29:15 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-12-24 23:27:29 +03:00
|
|
|
static inline void
|
2004-09-26 06:29:15 +04:00
|
|
|
rtw_srom_free(struct rtw_srom *sr)
|
|
|
|
{
|
|
|
|
sr->sr_size = 0;
|
|
|
|
if (sr->sr_content == NULL)
|
|
|
|
return;
|
|
|
|
free(sr->sr_content, M_DEVBUF);
|
|
|
|
sr->sr_content = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2006-11-16 04:32:37 +03:00
|
|
|
rtw_srom_defaults(struct rtw_srom *sr, uint32_t *flags,
|
2006-10-12 05:30:41 +04:00
|
|
|
uint8_t *cs_threshold, enum rtw_rfchipid *rfchipid, uint32_t *rcr)
|
2004-09-26 06:29:15 +04:00
|
|
|
{
|
|
|
|
*flags |= (RTW_F_DIGPHY|RTW_F_ANTDIV);
|
|
|
|
*cs_threshold = RTW_SR_ENERGYDETTHR_DEFAULT;
|
|
|
|
*rcr |= RTW_RCR_ENCS1;
|
|
|
|
*rfchipid = RTW_RFCHIPID_PHILIPS;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2005-01-02 07:23:03 +03:00
|
|
|
rtw_srom_parse(struct rtw_srom *sr, uint32_t *flags, uint8_t *cs_threshold,
|
|
|
|
enum rtw_rfchipid *rfchipid, uint32_t *rcr, enum rtw_locale *locale,
|
2007-12-21 21:22:43 +03:00
|
|
|
device_t dev)
|
2004-09-26 06:29:15 +04:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
const char *rfname, *paname;
|
|
|
|
char scratch[sizeof("unknown 0xXX")];
|
2005-06-10 06:35:34 +04:00
|
|
|
uint16_t srom_version;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
*flags &= ~(RTW_F_DIGPHY|RTW_F_DFLANTB|RTW_F_ANTDIV);
|
|
|
|
*rcr &= ~(RTW_RCR_ENCS1 | RTW_RCR_ENCS2);
|
|
|
|
|
2005-06-10 06:35:34 +04:00
|
|
|
srom_version = RTW_SR_GET16(sr, RTW_SR_VERSION);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2005-06-10 06:35:34 +04:00
|
|
|
if (srom_version <= 0x0101) {
|
2007-12-21 21:22:43 +03:00
|
|
|
aprint_error_dev(dev,
|
|
|
|
"SROM version %d.%d is not understood, "
|
|
|
|
"limping along with defaults\n",
|
|
|
|
srom_version >> 8, srom_version & 0xff);
|
2004-12-20 03:28:02 +03:00
|
|
|
rtw_srom_defaults(sr, flags, cs_threshold, rfchipid, rcr);
|
2004-09-26 06:29:15 +04:00
|
|
|
return 0;
|
2007-12-21 21:22:43 +03:00
|
|
|
} else {
|
2010-01-31 21:12:51 +03:00
|
|
|
aprint_verbose_dev(dev, "SROM version %d.%d\n",
|
2007-12-21 21:22:43 +03:00
|
|
|
srom_version >> 8, srom_version & 0xff);
|
2004-09-26 06:29:15 +04:00
|
|
|
}
|
|
|
|
|
2013-10-18 01:24:24 +04:00
|
|
|
uint8_t mac[IEEE80211_ADDR_LEN];
|
2004-09-26 06:29:15 +04:00
|
|
|
for (i = 0; i < IEEE80211_ADDR_LEN; i++)
|
|
|
|
mac[i] = RTW_SR_GET(sr, RTW_SR_MAC + i);
|
2013-10-18 01:24:24 +04:00
|
|
|
__USE(mac);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2004-12-25 09:58:37 +03:00
|
|
|
RTW_DPRINTF(RTW_DEBUG_ATTACH,
|
2007-12-21 21:22:43 +03:00
|
|
|
("%s: EEPROM MAC %s\n", device_xname(dev), ether_sprintf(mac)));
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
*cs_threshold = RTW_SR_GET(sr, RTW_SR_ENERGYDETTHR);
|
|
|
|
|
|
|
|
if ((RTW_SR_GET(sr, RTW_SR_CONFIG2) & RTW_CONFIG2_ANT) != 0)
|
|
|
|
*flags |= RTW_F_ANTDIV;
|
|
|
|
|
2004-12-21 02:05:41 +03:00
|
|
|
/* Note well: the sense of the RTW_SR_RFPARM_DIGPHY bit seems
|
|
|
|
* to be reversed.
|
|
|
|
*/
|
|
|
|
if ((RTW_SR_GET(sr, RTW_SR_RFPARM) & RTW_SR_RFPARM_DIGPHY) == 0)
|
2004-09-26 06:29:15 +04:00
|
|
|
*flags |= RTW_F_DIGPHY;
|
|
|
|
if ((RTW_SR_GET(sr, RTW_SR_RFPARM) & RTW_SR_RFPARM_DFLANTB) != 0)
|
|
|
|
*flags |= RTW_F_DFLANTB;
|
|
|
|
|
Per discussion on tech-kern and tech-userlevel, move the bit-twiddling
macros, __BIT, __BITS, SHIFTIN, SHIFTOUT, and __arraycount() from
lib/libkern/libkern.h to sys/cdefs.h. Add a __-prefix to SHIFTIN
and SHIFTOUT, and add a manual page for the bit-twiddling macros,
bits(3).
Make the __BIT and __BITS macros "widthless," as best I can, by
changing their type to uintmax_t from uint32_t. XXX The manual
page lags this change by a bit.
Define __PRIxBIT and __PRIxBITS printf(3) format strings.
2006-08-31 23:24:37 +04:00
|
|
|
*rcr |= __SHIFTIN(__SHIFTOUT(RTW_SR_GET(sr, RTW_SR_RFPARM),
|
2004-09-26 06:29:15 +04:00
|
|
|
RTW_SR_RFPARM_CS_MASK), RTW_RCR_ENCS1);
|
|
|
|
|
2005-11-23 07:12:33 +03:00
|
|
|
if ((RTW_SR_GET(sr, RTW_SR_CONFIG0) & RTW_CONFIG0_WEP104) != 0)
|
|
|
|
*flags |= RTW_C_RXWEP_104;
|
|
|
|
|
|
|
|
*flags |= RTW_C_RXWEP_40; /* XXX */
|
|
|
|
|
2004-09-26 06:29:15 +04:00
|
|
|
*rfchipid = RTW_SR_GET(sr, RTW_SR_RFCHIPID);
|
|
|
|
switch (*rfchipid) {
|
|
|
|
case RTW_RFCHIPID_GCT: /* this combo seen in the wild */
|
|
|
|
rfname = "GCT GRF5101";
|
|
|
|
paname = "Winspring WS9901";
|
|
|
|
break;
|
|
|
|
case RTW_RFCHIPID_MAXIM:
|
|
|
|
rfname = "Maxim MAX2820"; /* guess */
|
|
|
|
paname = "Maxim MAX2422"; /* guess */
|
|
|
|
break;
|
|
|
|
case RTW_RFCHIPID_INTERSIL:
|
|
|
|
rfname = "Intersil HFA3873"; /* guess */
|
|
|
|
paname = "Intersil <unknown>";
|
|
|
|
break;
|
|
|
|
case RTW_RFCHIPID_PHILIPS: /* this combo seen in the wild */
|
|
|
|
rfname = "Philips SA2400A";
|
|
|
|
paname = "Philips SA2411";
|
|
|
|
break;
|
|
|
|
case RTW_RFCHIPID_RFMD:
|
|
|
|
/* this is the same front-end as an atw(4)! */
|
|
|
|
rfname = "RFMD RF2948B, " /* mentioned in Realtek docs */
|
|
|
|
"LNA: RFMD RF2494, " /* mentioned in Realtek docs */
|
|
|
|
"SYN: Silicon Labs Si4126"; /* inferred from
|
|
|
|
* reference driver
|
|
|
|
*/
|
|
|
|
paname = "RFMD RF2189"; /* mentioned in Realtek docs */
|
|
|
|
break;
|
|
|
|
case RTW_RFCHIPID_RESERVED:
|
|
|
|
rfname = paname = "reserved";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
snprintf(scratch, sizeof(scratch), "unknown 0x%02x", *rfchipid);
|
|
|
|
rfname = paname = scratch;
|
|
|
|
}
|
2007-12-21 21:22:43 +03:00
|
|
|
aprint_normal_dev(dev, "RF: %s, PA: %s\n", rfname, paname);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
switch (RTW_SR_GET(sr, RTW_SR_CONFIG0) & RTW_CONFIG0_GL_MASK) {
|
|
|
|
case RTW_CONFIG0_GL_USA:
|
2005-09-07 09:25:41 +04:00
|
|
|
case _RTW_CONFIG0_GL_USA:
|
2004-09-26 06:29:15 +04:00
|
|
|
*locale = RTW_LOCALE_USA;
|
|
|
|
break;
|
|
|
|
case RTW_CONFIG0_GL_EUROPE:
|
|
|
|
*locale = RTW_LOCALE_EUROPE;
|
|
|
|
break;
|
|
|
|
case RTW_CONFIG0_GL_JAPAN:
|
|
|
|
*locale = RTW_LOCALE_JAPAN;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
*locale = RTW_LOCALE_UNKNOWN;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Returns -1 on failure. */
|
|
|
|
static int
|
2005-01-02 07:23:03 +03:00
|
|
|
rtw_srom_read(struct rtw_regs *regs, uint32_t flags, struct rtw_srom *sr,
|
2007-12-21 21:22:43 +03:00
|
|
|
device_t dev)
|
2004-09-26 06:29:15 +04:00
|
|
|
{
|
|
|
|
int rc;
|
|
|
|
struct seeprom_descriptor sd;
|
2005-01-02 07:23:03 +03:00
|
|
|
uint8_t ecr;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
(void)memset(&sd, 0, sizeof(sd));
|
|
|
|
|
|
|
|
ecr = RTW_READ8(regs, RTW_9346CR);
|
|
|
|
|
|
|
|
if ((flags & RTW_F_9356SROM) != 0) {
|
2007-12-21 21:22:43 +03:00
|
|
|
RTW_DPRINTF(RTW_DEBUG_ATTACH, ("%s: 93c56 SROM\n",
|
|
|
|
device_xname(dev)));
|
2004-09-26 06:29:15 +04:00
|
|
|
sr->sr_size = 256;
|
|
|
|
sd.sd_chip = C56_66;
|
|
|
|
} else {
|
2007-12-21 21:22:43 +03:00
|
|
|
RTW_DPRINTF(RTW_DEBUG_ATTACH, ("%s: 93c46 SROM\n",
|
|
|
|
device_xname(dev)));
|
2004-09-26 06:29:15 +04:00
|
|
|
sr->sr_size = 128;
|
|
|
|
sd.sd_chip = C46;
|
|
|
|
}
|
|
|
|
|
|
|
|
ecr &= ~(RTW_9346CR_EEDI | RTW_9346CR_EEDO | RTW_9346CR_EESK |
|
2005-01-04 04:04:52 +03:00
|
|
|
RTW_9346CR_EEM_MASK | RTW_9346CR_EECS);
|
2004-09-26 06:29:15 +04:00
|
|
|
ecr |= RTW_9346CR_EEM_PROGRAM;
|
|
|
|
|
|
|
|
RTW_WRITE8(regs, RTW_9346CR, ecr);
|
|
|
|
|
|
|
|
sr->sr_content = malloc(sr->sr_size, M_DEVBUF, M_NOWAIT);
|
|
|
|
|
|
|
|
if (sr->sr_content == NULL) {
|
2007-12-21 21:22:43 +03:00
|
|
|
aprint_error_dev(dev, "unable to allocate SROM buffer\n");
|
2004-09-26 06:29:15 +04:00
|
|
|
return ENOMEM;
|
|
|
|
}
|
|
|
|
|
|
|
|
(void)memset(sr->sr_content, 0, sr->sr_size);
|
|
|
|
|
|
|
|
/* RTL8180 has a single 8-bit register for controlling the
|
|
|
|
* 93cx6 SROM. There is no "ready" bit. The RTL8180
|
|
|
|
* input/output sense is the reverse of read_seeprom's.
|
|
|
|
*/
|
|
|
|
sd.sd_tag = regs->r_bt;
|
|
|
|
sd.sd_bsh = regs->r_bh;
|
|
|
|
sd.sd_regsize = 1;
|
|
|
|
sd.sd_control_offset = RTW_9346CR;
|
|
|
|
sd.sd_status_offset = RTW_9346CR;
|
|
|
|
sd.sd_dataout_offset = RTW_9346CR;
|
|
|
|
sd.sd_CK = RTW_9346CR_EESK;
|
|
|
|
sd.sd_CS = RTW_9346CR_EECS;
|
|
|
|
sd.sd_DI = RTW_9346CR_EEDO;
|
|
|
|
sd.sd_DO = RTW_9346CR_EEDI;
|
2005-02-27 03:26:58 +03:00
|
|
|
/* make read_seeprom enter EEPROM read/write mode */
|
2004-09-26 06:29:15 +04:00
|
|
|
sd.sd_MS = ecr;
|
|
|
|
sd.sd_RDY = 0;
|
|
|
|
|
2004-12-20 04:13:45 +03:00
|
|
|
/* TBD bus barriers */
|
2004-09-26 06:29:15 +04:00
|
|
|
if (!read_seeprom(&sd, sr->sr_content, 0, sr->sr_size/2)) {
|
2007-12-21 21:22:43 +03:00
|
|
|
aprint_error_dev(dev, "could not read SROM\n");
|
2004-09-26 06:29:15 +04:00
|
|
|
free(sr->sr_content, M_DEVBUF);
|
|
|
|
sr->sr_content = NULL;
|
|
|
|
return -1; /* XXX */
|
|
|
|
}
|
|
|
|
|
2005-02-27 03:26:58 +03:00
|
|
|
/* end EEPROM read/write mode */
|
2004-09-26 06:29:15 +04:00
|
|
|
RTW_WRITE8(regs, RTW_9346CR,
|
|
|
|
(ecr & ~RTW_9346CR_EEM_MASK) | RTW_9346CR_EEM_NORMAL);
|
|
|
|
RTW_WBRW(regs, RTW_9346CR, RTW_9346CR);
|
|
|
|
|
2007-12-21 21:22:43 +03:00
|
|
|
if ((rc = rtw_recall_eeprom(regs, dev)) != 0)
|
2004-09-26 06:29:15 +04:00
|
|
|
return rc;
|
|
|
|
|
|
|
|
#ifdef RTW_DEBUG
|
|
|
|
{
|
|
|
|
int i;
|
2004-12-25 09:58:37 +03:00
|
|
|
RTW_DPRINTF(RTW_DEBUG_ATTACH,
|
2007-12-21 21:22:43 +03:00
|
|
|
("\n%s: serial ROM:\n\t", device_xname(dev)));
|
2004-09-26 06:29:15 +04:00
|
|
|
for (i = 0; i < sr->sr_size/2; i++) {
|
|
|
|
if (((i % 8) == 0) && (i != 0))
|
2004-12-25 09:58:37 +03:00
|
|
|
RTW_DPRINTF(RTW_DEBUG_ATTACH, ("\n\t"));
|
|
|
|
RTW_DPRINTF(RTW_DEBUG_ATTACH,
|
|
|
|
(" %04x", sr->sr_content[i]));
|
2004-09-26 06:29:15 +04:00
|
|
|
}
|
2004-12-25 09:58:37 +03:00
|
|
|
RTW_DPRINTF(RTW_DEBUG_ATTACH, ("\n"));
|
2004-09-26 06:29:15 +04:00
|
|
|
}
|
|
|
|
#endif /* RTW_DEBUG */
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
static void
|
|
|
|
rtw_set_rfprog(struct rtw_regs *regs, enum rtw_rfchipid rfchipid,
|
2007-12-21 21:22:43 +03:00
|
|
|
device_t dev)
|
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
|
|
|
{
|
2005-01-02 07:23:03 +03:00
|
|
|
uint8_t cfg4;
|
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
|
|
|
const char *method;
|
|
|
|
|
|
|
|
cfg4 = RTW_READ8(regs, RTW_CONFIG4) & ~RTW_CONFIG4_RFTYPE_MASK;
|
|
|
|
|
|
|
|
switch (rfchipid) {
|
|
|
|
default:
|
Per discussion on tech-kern and tech-userlevel, move the bit-twiddling
macros, __BIT, __BITS, SHIFTIN, SHIFTOUT, and __arraycount() from
lib/libkern/libkern.h to sys/cdefs.h. Add a __-prefix to SHIFTIN
and SHIFTOUT, and add a manual page for the bit-twiddling macros,
bits(3).
Make the __BIT and __BITS macros "widthless," as best I can, by
changing their type to uintmax_t from uint32_t. XXX The manual
page lags this change by a bit.
Define __PRIxBIT and __PRIxBITS printf(3) format strings.
2006-08-31 23:24:37 +04:00
|
|
|
cfg4 |= __SHIFTIN(rtw_rfprog_fallback, RTW_CONFIG4_RFTYPE_MASK);
|
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
|
|
|
method = "fallback";
|
|
|
|
break;
|
|
|
|
case RTW_RFCHIPID_INTERSIL:
|
|
|
|
cfg4 |= RTW_CONFIG4_RFTYPE_INTERSIL;
|
|
|
|
method = "Intersil";
|
|
|
|
break;
|
|
|
|
case RTW_RFCHIPID_PHILIPS:
|
|
|
|
cfg4 |= RTW_CONFIG4_RFTYPE_PHILIPS;
|
|
|
|
method = "Philips";
|
|
|
|
break;
|
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
|
|
|
case RTW_RFCHIPID_GCT: /* XXX a guess */
|
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
|
|
|
case RTW_RFCHIPID_RFMD:
|
|
|
|
cfg4 |= RTW_CONFIG4_RFTYPE_RFMD;
|
|
|
|
method = "RFMD";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
RTW_WRITE8(regs, RTW_CONFIG4, cfg4);
|
|
|
|
|
2004-12-20 04:13:45 +03:00
|
|
|
RTW_WBR(regs, RTW_CONFIG4, RTW_CONFIG4);
|
|
|
|
|
2013-10-18 01:24:24 +04:00
|
|
|
#ifdef RTW_DEBUG
|
2004-12-25 09:58:37 +03:00
|
|
|
RTW_DPRINTF(RTW_DEBUG_INIT,
|
2007-12-21 21:22:43 +03:00
|
|
|
("%s: %s RF programming method, %#02x\n", device_xname(dev), method,
|
2004-12-21 02:05:41 +03:00
|
|
|
RTW_READ8(regs, RTW_CONFIG4)));
|
2013-10-18 01:24:24 +04:00
|
|
|
#else
|
|
|
|
__USE(method);
|
|
|
|
#endif
|
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
|
|
|
}
|
|
|
|
|
2005-12-24 23:27:29 +03:00
|
|
|
static inline void
|
2004-09-26 06:29:15 +04:00
|
|
|
rtw_init_channels(enum rtw_locale locale,
|
2007-12-21 21:22:43 +03:00
|
|
|
struct ieee80211_channel (*chans)[IEEE80211_CHAN_MAX+1], device_t dev)
|
2004-09-26 06:29:15 +04:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
const char *name = NULL;
|
|
|
|
#define ADD_CHANNEL(_chans, _chan) do { \
|
|
|
|
(*_chans)[_chan].ic_flags = IEEE80211_CHAN_B; \
|
|
|
|
(*_chans)[_chan].ic_freq = \
|
|
|
|
ieee80211_ieee2mhz(_chan, (*_chans)[_chan].ic_flags);\
|
|
|
|
} while (0)
|
|
|
|
|
|
|
|
switch (locale) {
|
|
|
|
case RTW_LOCALE_USA: /* 1-11 */
|
|
|
|
name = "USA";
|
|
|
|
for (i = 1; i <= 11; i++)
|
|
|
|
ADD_CHANNEL(chans, i);
|
|
|
|
break;
|
|
|
|
case RTW_LOCALE_JAPAN: /* 1-14 */
|
|
|
|
name = "Japan";
|
|
|
|
ADD_CHANNEL(chans, 14);
|
|
|
|
for (i = 1; i <= 14; i++)
|
|
|
|
ADD_CHANNEL(chans, i);
|
|
|
|
break;
|
|
|
|
case RTW_LOCALE_EUROPE: /* 1-13 */
|
|
|
|
name = "Europe";
|
|
|
|
for (i = 1; i <= 13; i++)
|
|
|
|
ADD_CHANNEL(chans, i);
|
|
|
|
break;
|
|
|
|
default: /* 10-11 allowed by most countries */
|
|
|
|
name = "<unknown>";
|
|
|
|
for (i = 10; i <= 11; i++)
|
|
|
|
ADD_CHANNEL(chans, i);
|
|
|
|
break;
|
|
|
|
}
|
2007-12-21 21:22:43 +03:00
|
|
|
aprint_normal_dev(dev, "Geographic Location %s\n", name);
|
2004-09-26 06:29:15 +04:00
|
|
|
#undef ADD_CHANNEL
|
|
|
|
}
|
|
|
|
|
2005-11-23 07:12:33 +03:00
|
|
|
|
2005-12-24 23:27:29 +03:00
|
|
|
static inline void
|
2005-11-23 07:12:33 +03:00
|
|
|
rtw_identify_country(struct rtw_regs *regs, enum rtw_locale *locale)
|
2004-09-26 06:29:15 +04:00
|
|
|
{
|
2005-01-02 07:23:03 +03:00
|
|
|
uint8_t cfg0 = RTW_READ8(regs, RTW_CONFIG0);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
switch (cfg0 & RTW_CONFIG0_GL_MASK) {
|
|
|
|
case RTW_CONFIG0_GL_USA:
|
2005-09-07 09:25:41 +04:00
|
|
|
case _RTW_CONFIG0_GL_USA:
|
2004-09-26 06:29:15 +04:00
|
|
|
*locale = RTW_LOCALE_USA;
|
|
|
|
break;
|
|
|
|
case RTW_CONFIG0_GL_JAPAN:
|
|
|
|
*locale = RTW_LOCALE_JAPAN;
|
|
|
|
break;
|
|
|
|
case RTW_CONFIG0_GL_EUROPE:
|
|
|
|
*locale = RTW_LOCALE_EUROPE;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
*locale = RTW_LOCALE_UNKNOWN;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-12-24 23:27:29 +03:00
|
|
|
static inline int
|
2005-01-02 07:23:03 +03:00
|
|
|
rtw_identify_sta(struct rtw_regs *regs, uint8_t (*addr)[IEEE80211_ADDR_LEN],
|
2007-12-21 21:22:43 +03:00
|
|
|
device_t dev)
|
2004-09-26 06:29:15 +04:00
|
|
|
{
|
2005-01-02 07:23:03 +03:00
|
|
|
static const uint8_t empty_macaddr[IEEE80211_ADDR_LEN] = {
|
2004-09-26 06:29:15 +04:00
|
|
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
|
|
|
};
|
2005-01-02 07:23:03 +03:00
|
|
|
uint32_t idr0 = RTW_READ(regs, RTW_IDR0),
|
2004-09-26 06:29:15 +04:00
|
|
|
idr1 = RTW_READ(regs, RTW_IDR1);
|
|
|
|
|
Per discussion on tech-kern and tech-userlevel, move the bit-twiddling
macros, __BIT, __BITS, SHIFTIN, SHIFTOUT, and __arraycount() from
lib/libkern/libkern.h to sys/cdefs.h. Add a __-prefix to SHIFTIN
and SHIFTOUT, and add a manual page for the bit-twiddling macros,
bits(3).
Make the __BIT and __BITS macros "widthless," as best I can, by
changing their type to uintmax_t from uint32_t. XXX The manual
page lags this change by a bit.
Define __PRIxBIT and __PRIxBITS printf(3) format strings.
2006-08-31 23:24:37 +04:00
|
|
|
(*addr)[0] = __SHIFTOUT(idr0, __BITS(0, 7));
|
|
|
|
(*addr)[1] = __SHIFTOUT(idr0, __BITS(8, 15));
|
|
|
|
(*addr)[2] = __SHIFTOUT(idr0, __BITS(16, 23));
|
|
|
|
(*addr)[3] = __SHIFTOUT(idr0, __BITS(24 ,31));
|
2004-09-26 06:29:15 +04:00
|
|
|
|
Per discussion on tech-kern and tech-userlevel, move the bit-twiddling
macros, __BIT, __BITS, SHIFTIN, SHIFTOUT, and __arraycount() from
lib/libkern/libkern.h to sys/cdefs.h. Add a __-prefix to SHIFTIN
and SHIFTOUT, and add a manual page for the bit-twiddling macros,
bits(3).
Make the __BIT and __BITS macros "widthless," as best I can, by
changing their type to uintmax_t from uint32_t. XXX The manual
page lags this change by a bit.
Define __PRIxBIT and __PRIxBITS printf(3) format strings.
2006-08-31 23:24:37 +04:00
|
|
|
(*addr)[4] = __SHIFTOUT(idr1, __BITS(0, 7));
|
|
|
|
(*addr)[5] = __SHIFTOUT(idr1, __BITS(8, 15));
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
if (IEEE80211_ADDR_EQ(addr, empty_macaddr)) {
|
2007-12-21 21:22:43 +03:00
|
|
|
aprint_error_dev(dev,
|
|
|
|
"could not get mac address, attach failed\n");
|
2004-09-26 06:29:15 +04:00
|
|
|
return ENXIO;
|
|
|
|
}
|
|
|
|
|
2007-12-21 21:22:43 +03:00
|
|
|
aprint_normal_dev(dev, "802.11 address %s\n", ether_sprintf(*addr));
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-01-02 07:23:03 +03:00
|
|
|
static uint8_t
|
2004-09-26 06:29:15 +04:00
|
|
|
rtw_chan2txpower(struct rtw_srom *sr, struct ieee80211com *ic,
|
|
|
|
struct ieee80211_channel *chan)
|
|
|
|
{
|
|
|
|
u_int idx = RTW_SR_TXPOWER1 + ieee80211_chan2ieee(ic, chan) - 1;
|
2007-12-20 21:47:23 +03:00
|
|
|
KASSERT(idx >= RTW_SR_TXPOWER1 && idx <= RTW_SR_TXPOWER14);
|
2004-09-26 06:29:15 +04:00
|
|
|
return RTW_SR_GET(sr, idx);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2004-12-29 04:06:52 +03:00
|
|
|
rtw_txdesc_blk_init_all(struct rtw_txdesc_blk *tdb)
|
2004-09-26 06:29:15 +04:00
|
|
|
{
|
|
|
|
int pri;
|
2005-11-23 07:12:33 +03:00
|
|
|
/* nfree: the number of free descriptors in each ring.
|
|
|
|
* The beacon ring is a special case: I do not let the
|
|
|
|
* driver use all of the descriptors on the beacon ring.
|
|
|
|
* The reasons are two-fold:
|
|
|
|
*
|
|
|
|
* (1) A BEACON descriptor's OWN bit is (apparently) not
|
|
|
|
* updated, so the driver cannot easily know if the descriptor
|
|
|
|
* belongs to it, or if it is racing the NIC. If the NIC
|
|
|
|
* does not OWN every descriptor, then the driver can safely
|
|
|
|
* update the descriptors when RTW_TBDA points at tdb_next.
|
|
|
|
*
|
|
|
|
* (2) I hope that the NIC will process more than one BEACON
|
|
|
|
* descriptor in a single beacon interval, since that will
|
|
|
|
* enable multiple-BSS support. Since the NIC does not
|
|
|
|
* clear the OWN bit, there is no natural place for it to
|
|
|
|
* stop processing BEACON desciptors. Maybe it will *not*
|
|
|
|
* stop processing them! I do not want to chance the NIC
|
|
|
|
* looping around and around a saturated beacon ring, so
|
|
|
|
* I will leave one descriptor unOWNed at all times.
|
|
|
|
*/
|
|
|
|
u_int nfree[RTW_NTXPRI] =
|
|
|
|
{RTW_NTXDESCLO, RTW_NTXDESCMD, RTW_NTXDESCHI,
|
|
|
|
RTW_NTXDESCBCN - 1};
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
for (pri = 0; pri < RTW_NTXPRI; pri++) {
|
2005-11-23 07:12:33 +03:00
|
|
|
tdb[pri].tdb_nfree = nfree[pri];
|
2004-12-29 04:06:52 +03:00
|
|
|
tdb[pri].tdb_next = 0;
|
2004-09-26 06:29:15 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2004-12-29 04:06:52 +03:00
|
|
|
rtw_txsoft_blk_init(struct rtw_txsoft_blk *tsb)
|
2004-09-26 06:29:15 +04:00
|
|
|
{
|
|
|
|
int i;
|
2004-12-29 04:06:52 +03:00
|
|
|
struct rtw_txsoft *ts;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
SIMPLEQ_INIT(&tsb->tsb_dirtyq);
|
|
|
|
SIMPLEQ_INIT(&tsb->tsb_freeq);
|
|
|
|
for (i = 0; i < tsb->tsb_ndesc; i++) {
|
|
|
|
ts = &tsb->tsb_desc[i];
|
|
|
|
ts->ts_mbuf = NULL;
|
|
|
|
SIMPLEQ_INSERT_TAIL(&tsb->tsb_freeq, ts, ts_q);
|
2004-09-26 06:29:15 +04:00
|
|
|
}
|
2005-11-23 07:12:33 +03:00
|
|
|
tsb->tsb_tx_timer = 0;
|
2004-09-26 06:29:15 +04:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2004-12-29 04:06:52 +03:00
|
|
|
rtw_txsoft_blk_init_all(struct rtw_txsoft_blk *tsb)
|
2004-09-26 06:29:15 +04:00
|
|
|
{
|
|
|
|
int pri;
|
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
|
|
|
for (pri = 0; pri < RTW_NTXPRI; pri++)
|
2004-12-29 04:06:52 +03:00
|
|
|
rtw_txsoft_blk_init(&tsb[pri]);
|
2004-09-26 06:29:15 +04:00
|
|
|
}
|
|
|
|
|
2005-12-24 23:27:29 +03:00
|
|
|
static inline void
|
2004-12-29 04:06:52 +03:00
|
|
|
rtw_rxdescs_sync(struct rtw_rxdesc_blk *rdb, int desc0, int nsync, int ops)
|
2004-09-26 06:29:15 +04:00
|
|
|
{
|
2004-12-29 04:06:52 +03:00
|
|
|
KASSERT(nsync <= rdb->rdb_ndesc);
|
2004-09-26 06:29:15 +04:00
|
|
|
/* sync to end of ring */
|
2004-12-29 04:06:52 +03:00
|
|
|
if (desc0 + nsync > rdb->rdb_ndesc) {
|
|
|
|
bus_dmamap_sync(rdb->rdb_dmat, rdb->rdb_dmamap,
|
2004-09-26 06:29:15 +04:00
|
|
|
offsetof(struct rtw_descs, hd_rx[desc0]),
|
2004-12-29 04:06:52 +03:00
|
|
|
sizeof(struct rtw_rxdesc) * (rdb->rdb_ndesc - desc0), ops);
|
|
|
|
nsync -= (rdb->rdb_ndesc - desc0);
|
2004-09-26 06:29:15 +04:00
|
|
|
desc0 = 0;
|
|
|
|
}
|
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
KASSERT(desc0 < rdb->rdb_ndesc);
|
|
|
|
KASSERT(nsync <= rdb->rdb_ndesc);
|
|
|
|
KASSERT(desc0 + nsync <= rdb->rdb_ndesc);
|
2004-12-25 09:58:37 +03:00
|
|
|
|
2004-09-26 06:29:15 +04:00
|
|
|
/* sync what remains */
|
2004-12-29 04:06:52 +03:00
|
|
|
bus_dmamap_sync(rdb->rdb_dmat, rdb->rdb_dmamap,
|
2004-09-26 06:29:15 +04:00
|
|
|
offsetof(struct rtw_descs, hd_rx[desc0]),
|
|
|
|
sizeof(struct rtw_rxdesc) * nsync, ops);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2004-12-29 04:06:52 +03:00
|
|
|
rtw_txdescs_sync(struct rtw_txdesc_blk *tdb, u_int desc0, u_int nsync, int ops)
|
2004-09-26 06:29:15 +04:00
|
|
|
{
|
|
|
|
/* sync to end of ring */
|
2004-12-29 04:06:52 +03:00
|
|
|
if (desc0 + nsync > tdb->tdb_ndesc) {
|
|
|
|
bus_dmamap_sync(tdb->tdb_dmat, tdb->tdb_dmamap,
|
|
|
|
tdb->tdb_ofs + sizeof(struct rtw_txdesc) * desc0,
|
|
|
|
sizeof(struct rtw_txdesc) * (tdb->tdb_ndesc - desc0),
|
2004-09-26 06:29:15 +04:00
|
|
|
ops);
|
2004-12-29 04:06:52 +03:00
|
|
|
nsync -= (tdb->tdb_ndesc - desc0);
|
2004-09-26 06:29:15 +04:00
|
|
|
desc0 = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* sync what remains */
|
2004-12-29 04:06:52 +03:00
|
|
|
bus_dmamap_sync(tdb->tdb_dmat, tdb->tdb_dmamap,
|
|
|
|
tdb->tdb_ofs + sizeof(struct rtw_txdesc) * desc0,
|
2004-09-26 06:29:15 +04:00
|
|
|
sizeof(struct rtw_txdesc) * nsync, ops);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2004-12-29 04:06:52 +03:00
|
|
|
rtw_txdescs_sync_all(struct rtw_txdesc_blk *tdb)
|
2004-09-26 06:29:15 +04:00
|
|
|
{
|
|
|
|
int pri;
|
|
|
|
for (pri = 0; pri < RTW_NTXPRI; pri++) {
|
2004-12-29 04:06:52 +03:00
|
|
|
rtw_txdescs_sync(&tdb[pri], 0, tdb[pri].tdb_ndesc,
|
2004-09-26 06:29:15 +04:00
|
|
|
BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2004-12-29 04:06:52 +03:00
|
|
|
rtw_rxbufs_release(bus_dma_tag_t dmat, struct rtw_rxsoft *desc)
|
2004-09-26 06:29:15 +04:00
|
|
|
{
|
|
|
|
int i;
|
2004-12-29 04:06:52 +03:00
|
|
|
struct rtw_rxsoft *rs;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2004-12-25 09:58:37 +03:00
|
|
|
for (i = 0; i < RTW_RXQLEN; i++) {
|
2004-12-29 04:06:52 +03:00
|
|
|
rs = &desc[i];
|
|
|
|
if (rs->rs_mbuf == NULL)
|
If defined(RTW_DEBUG), provide a sysctl (hw.rtw.rxbufs_limit) for
limiting the number of rx buffers an rtw may allocate. Use this
sysctl to test the code that copes with buffer exhaustion.
Allocate at most RTW_RXQLEN rx buffers, stopping at the sysctl
limit. Record in sc_nrxdesc how many were allocated, and put the
end-of-ring indication on sc_rxdesc[sc_nrxdesc - 1]. In rtw_init,
if no rx buffers could be allocated, log a complaint, clear
IFF_RUNNING, and exit with an error.
Many changes to accomodate a short rx ring, mainly of the "add a
rx-ring length argument" variety. XXX I really should consolidate
all of the rx ring variables in one struct and pass that to the
rx-ring subroutines.
Bug fix: after calling MCLGET, use the (m->m_flags & M_EXT) idiom
to check for success, instead of m != NULL.
Bug fix: at the top of rtw_start, if IFF_RUNNING is not set, or
IFF_OACTIVE is, get out.
2004-12-29 01:21:15 +03:00
|
|
|
continue;
|
2004-12-29 04:06:52 +03:00
|
|
|
bus_dmamap_sync(dmat, rs->rs_dmamap, 0,
|
|
|
|
rs->rs_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
|
|
|
|
bus_dmamap_unload(dmat, rs->rs_dmamap);
|
|
|
|
m_freem(rs->rs_mbuf);
|
|
|
|
rs->rs_mbuf = NULL;
|
2004-09-26 06:29:15 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2005-12-24 23:27:29 +03:00
|
|
|
static inline int
|
2004-12-29 04:06:52 +03:00
|
|
|
rtw_rxsoft_alloc(bus_dma_tag_t dmat, struct rtw_rxsoft *rs)
|
2004-09-26 06:29:15 +04:00
|
|
|
{
|
|
|
|
int rc;
|
|
|
|
struct mbuf *m;
|
|
|
|
|
2005-02-27 03:26:58 +03:00
|
|
|
MGETHDR(m, M_DONTWAIT, MT_DATA);
|
2004-09-26 06:29:15 +04:00
|
|
|
if (m == NULL)
|
2004-12-23 09:03:09 +03:00
|
|
|
return ENOBUFS;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2005-02-27 03:26:58 +03:00
|
|
|
MCLGET(m, M_DONTWAIT);
|
If defined(RTW_DEBUG), provide a sysctl (hw.rtw.rxbufs_limit) for
limiting the number of rx buffers an rtw may allocate. Use this
sysctl to test the code that copes with buffer exhaustion.
Allocate at most RTW_RXQLEN rx buffers, stopping at the sysctl
limit. Record in sc_nrxdesc how many were allocated, and put the
end-of-ring indication on sc_rxdesc[sc_nrxdesc - 1]. In rtw_init,
if no rx buffers could be allocated, log a complaint, clear
IFF_RUNNING, and exit with an error.
Many changes to accomodate a short rx ring, mainly of the "add a
rx-ring length argument" variety. XXX I really should consolidate
all of the rx ring variables in one struct and pass that to the
rx-ring subroutines.
Bug fix: after calling MCLGET, use the (m->m_flags & M_EXT) idiom
to check for success, instead of m != NULL.
Bug fix: at the top of rtw_start, if IFF_RUNNING is not set, or
IFF_OACTIVE is, get out.
2004-12-29 01:21:15 +03:00
|
|
|
if ((m->m_flags & M_EXT) == 0) {
|
|
|
|
m_freem(m);
|
2004-12-23 09:03:09 +03:00
|
|
|
return ENOBUFS;
|
If defined(RTW_DEBUG), provide a sysctl (hw.rtw.rxbufs_limit) for
limiting the number of rx buffers an rtw may allocate. Use this
sysctl to test the code that copes with buffer exhaustion.
Allocate at most RTW_RXQLEN rx buffers, stopping at the sysctl
limit. Record in sc_nrxdesc how many were allocated, and put the
end-of-ring indication on sc_rxdesc[sc_nrxdesc - 1]. In rtw_init,
if no rx buffers could be allocated, log a complaint, clear
IFF_RUNNING, and exit with an error.
Many changes to accomodate a short rx ring, mainly of the "add a
rx-ring length argument" variety. XXX I really should consolidate
all of the rx ring variables in one struct and pass that to the
rx-ring subroutines.
Bug fix: after calling MCLGET, use the (m->m_flags & M_EXT) idiom
to check for success, instead of m != NULL.
Bug fix: at the top of rtw_start, if IFF_RUNNING is not set, or
IFF_OACTIVE is, get out.
2004-12-29 01:21:15 +03:00
|
|
|
}
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
m->m_pkthdr.len = m->m_len = m->m_ext.ext_size;
|
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
if (rs->rs_mbuf != NULL)
|
|
|
|
bus_dmamap_unload(dmat, rs->rs_dmamap);
|
2004-12-23 09:03:09 +03:00
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
rs->rs_mbuf = NULL;
|
2004-12-23 09:03:09 +03:00
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
rc = bus_dmamap_load_mbuf(dmat, rs->rs_dmamap, m, BUS_DMA_NOWAIT);
|
2004-12-23 09:03:09 +03:00
|
|
|
if (rc != 0) {
|
|
|
|
m_freem(m);
|
|
|
|
return -1;
|
|
|
|
}
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
rs->rs_mbuf = m;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2004-12-29 04:06:52 +03:00
|
|
|
rtw_rxsoft_init_all(bus_dma_tag_t dmat, struct rtw_rxsoft *desc,
|
2007-12-21 21:22:43 +03:00
|
|
|
int *ndesc, device_t dev)
|
2004-09-26 06:29:15 +04:00
|
|
|
{
|
If defined(RTW_DEBUG), provide a sysctl (hw.rtw.rxbufs_limit) for
limiting the number of rx buffers an rtw may allocate. Use this
sysctl to test the code that copes with buffer exhaustion.
Allocate at most RTW_RXQLEN rx buffers, stopping at the sysctl
limit. Record in sc_nrxdesc how many were allocated, and put the
end-of-ring indication on sc_rxdesc[sc_nrxdesc - 1]. In rtw_init,
if no rx buffers could be allocated, log a complaint, clear
IFF_RUNNING, and exit with an error.
Many changes to accomodate a short rx ring, mainly of the "add a
rx-ring length argument" variety. XXX I really should consolidate
all of the rx ring variables in one struct and pass that to the
rx-ring subroutines.
Bug fix: after calling MCLGET, use the (m->m_flags & M_EXT) idiom
to check for success, instead of m != NULL.
Bug fix: at the top of rtw_start, if IFF_RUNNING is not set, or
IFF_OACTIVE is, get out.
2004-12-29 01:21:15 +03:00
|
|
|
int i, rc = 0;
|
2004-12-29 04:06:52 +03:00
|
|
|
struct rtw_rxsoft *rs;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2004-12-25 09:58:37 +03:00
|
|
|
for (i = 0; i < RTW_RXQLEN; i++) {
|
2004-12-29 04:06:52 +03:00
|
|
|
rs = &desc[i];
|
If defined(RTW_DEBUG), provide a sysctl (hw.rtw.rxbufs_limit) for
limiting the number of rx buffers an rtw may allocate. Use this
sysctl to test the code that copes with buffer exhaustion.
Allocate at most RTW_RXQLEN rx buffers, stopping at the sysctl
limit. Record in sc_nrxdesc how many were allocated, and put the
end-of-ring indication on sc_rxdesc[sc_nrxdesc - 1]. In rtw_init,
if no rx buffers could be allocated, log a complaint, clear
IFF_RUNNING, and exit with an error.
Many changes to accomodate a short rx ring, mainly of the "add a
rx-ring length argument" variety. XXX I really should consolidate
all of the rx ring variables in one struct and pass that to the
rx-ring subroutines.
Bug fix: after calling MCLGET, use the (m->m_flags & M_EXT) idiom
to check for success, instead of m != NULL.
Bug fix: at the top of rtw_start, if IFF_RUNNING is not set, or
IFF_OACTIVE is, get out.
2004-12-29 01:21:15 +03:00
|
|
|
/* we're in rtw_init, so there should be no mbufs allocated */
|
2004-12-29 04:06:52 +03:00
|
|
|
KASSERT(rs->rs_mbuf == NULL);
|
If defined(RTW_DEBUG), provide a sysctl (hw.rtw.rxbufs_limit) for
limiting the number of rx buffers an rtw may allocate. Use this
sysctl to test the code that copes with buffer exhaustion.
Allocate at most RTW_RXQLEN rx buffers, stopping at the sysctl
limit. Record in sc_nrxdesc how many were allocated, and put the
end-of-ring indication on sc_rxdesc[sc_nrxdesc - 1]. In rtw_init,
if no rx buffers could be allocated, log a complaint, clear
IFF_RUNNING, and exit with an error.
Many changes to accomodate a short rx ring, mainly of the "add a
rx-ring length argument" variety. XXX I really should consolidate
all of the rx ring variables in one struct and pass that to the
rx-ring subroutines.
Bug fix: after calling MCLGET, use the (m->m_flags & M_EXT) idiom
to check for success, instead of m != NULL.
Bug fix: at the top of rtw_start, if IFF_RUNNING is not set, or
IFF_OACTIVE is, get out.
2004-12-29 01:21:15 +03:00
|
|
|
#ifdef RTW_DEBUG
|
|
|
|
if (i == rtw_rxbufs_limit) {
|
2007-12-21 21:22:43 +03:00
|
|
|
aprint_error_dev(dev, "TEST hit %d-buffer limit\n", i);
|
If defined(RTW_DEBUG), provide a sysctl (hw.rtw.rxbufs_limit) for
limiting the number of rx buffers an rtw may allocate. Use this
sysctl to test the code that copes with buffer exhaustion.
Allocate at most RTW_RXQLEN rx buffers, stopping at the sysctl
limit. Record in sc_nrxdesc how many were allocated, and put the
end-of-ring indication on sc_rxdesc[sc_nrxdesc - 1]. In rtw_init,
if no rx buffers could be allocated, log a complaint, clear
IFF_RUNNING, and exit with an error.
Many changes to accomodate a short rx ring, mainly of the "add a
rx-ring length argument" variety. XXX I really should consolidate
all of the rx ring variables in one struct and pass that to the
rx-ring subroutines.
Bug fix: after calling MCLGET, use the (m->m_flags & M_EXT) idiom
to check for success, instead of m != NULL.
Bug fix: at the top of rtw_start, if IFF_RUNNING is not set, or
IFF_OACTIVE is, get out.
2004-12-29 01:21:15 +03:00
|
|
|
rc = ENOBUFS;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
#endif /* RTW_DEBUG */
|
2004-12-29 04:06:52 +03:00
|
|
|
if ((rc = rtw_rxsoft_alloc(dmat, rs)) != 0) {
|
2007-12-21 21:22:43 +03:00
|
|
|
aprint_error_dev(dev,
|
|
|
|
"rtw_rxsoft_alloc failed, %d buffers, rc %d\n",
|
|
|
|
i, rc);
|
If defined(RTW_DEBUG), provide a sysctl (hw.rtw.rxbufs_limit) for
limiting the number of rx buffers an rtw may allocate. Use this
sysctl to test the code that copes with buffer exhaustion.
Allocate at most RTW_RXQLEN rx buffers, stopping at the sysctl
limit. Record in sc_nrxdesc how many were allocated, and put the
end-of-ring indication on sc_rxdesc[sc_nrxdesc - 1]. In rtw_init,
if no rx buffers could be allocated, log a complaint, clear
IFF_RUNNING, and exit with an error.
Many changes to accomodate a short rx ring, mainly of the "add a
rx-ring length argument" variety. XXX I really should consolidate
all of the rx ring variables in one struct and pass that to the
rx-ring subroutines.
Bug fix: after calling MCLGET, use the (m->m_flags & M_EXT) idiom
to check for success, instead of m != NULL.
Bug fix: at the top of rtw_start, if IFF_RUNNING is not set, or
IFF_OACTIVE is, get out.
2004-12-29 01:21:15 +03:00
|
|
|
break;
|
2004-09-26 06:29:15 +04:00
|
|
|
}
|
|
|
|
}
|
If defined(RTW_DEBUG), provide a sysctl (hw.rtw.rxbufs_limit) for
limiting the number of rx buffers an rtw may allocate. Use this
sysctl to test the code that copes with buffer exhaustion.
Allocate at most RTW_RXQLEN rx buffers, stopping at the sysctl
limit. Record in sc_nrxdesc how many were allocated, and put the
end-of-ring indication on sc_rxdesc[sc_nrxdesc - 1]. In rtw_init,
if no rx buffers could be allocated, log a complaint, clear
IFF_RUNNING, and exit with an error.
Many changes to accomodate a short rx ring, mainly of the "add a
rx-ring length argument" variety. XXX I really should consolidate
all of the rx ring variables in one struct and pass that to the
rx-ring subroutines.
Bug fix: after calling MCLGET, use the (m->m_flags & M_EXT) idiom
to check for success, instead of m != NULL.
Bug fix: at the top of rtw_start, if IFF_RUNNING is not set, or
IFF_OACTIVE is, get out.
2004-12-29 01:21:15 +03:00
|
|
|
*ndesc = i;
|
|
|
|
return rc;
|
2004-09-26 06:29:15 +04:00
|
|
|
}
|
|
|
|
|
2005-12-24 23:27:29 +03:00
|
|
|
static inline void
|
2004-12-29 04:06:52 +03:00
|
|
|
rtw_rxdesc_init(struct rtw_rxdesc_blk *rdb, struct rtw_rxsoft *rs,
|
2006-11-16 04:32:37 +03:00
|
|
|
int idx, int kick)
|
2004-09-26 06:29:15 +04:00
|
|
|
{
|
2004-12-29 04:06:52 +03:00
|
|
|
int is_last = (idx == rdb->rdb_ndesc - 1);
|
2004-12-25 09:58:37 +03:00
|
|
|
uint32_t ctl, octl, obuf;
|
2004-12-29 04:06:52 +03:00
|
|
|
struct rtw_rxdesc *rd = &rdb->rdb_desc[idx];
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2007-11-16 01:55:50 +03:00
|
|
|
/* sync the mbuf before the descriptor */
|
|
|
|
bus_dmamap_sync(rdb->rdb_dmat, rs->rs_dmamap, 0,
|
|
|
|
rs->rs_dmamap->dm_mapsize, BUS_DMASYNC_PREREAD);
|
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
obuf = rd->rd_buf;
|
|
|
|
rd->rd_buf = htole32(rs->rs_dmamap->dm_segs[0].ds_addr);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
Per discussion on tech-kern and tech-userlevel, move the bit-twiddling
macros, __BIT, __BITS, SHIFTIN, SHIFTOUT, and __arraycount() from
lib/libkern/libkern.h to sys/cdefs.h. Add a __-prefix to SHIFTIN
and SHIFTOUT, and add a manual page for the bit-twiddling macros,
bits(3).
Make the __BIT and __BITS macros "widthless," as best I can, by
changing their type to uintmax_t from uint32_t. XXX The manual
page lags this change by a bit.
Define __PRIxBIT and __PRIxBITS printf(3) format strings.
2006-08-31 23:24:37 +04:00
|
|
|
ctl = __SHIFTIN(rs->rs_mbuf->m_len, RTW_RXCTL_LENGTH_MASK) |
|
2004-09-26 06:29:15 +04:00
|
|
|
RTW_RXCTL_OWN | RTW_RXCTL_FS | RTW_RXCTL_LS;
|
|
|
|
|
|
|
|
if (is_last)
|
|
|
|
ctl |= RTW_RXCTL_EOR;
|
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
octl = rd->rd_ctl;
|
|
|
|
rd->rd_ctl = htole32(ctl);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2013-10-18 01:24:24 +04:00
|
|
|
#ifdef RTW_DEBUG
|
2004-12-27 01:59:41 +03:00
|
|
|
RTW_DPRINTF(
|
|
|
|
kick ? (RTW_DEBUG_RECV_DESC | RTW_DEBUG_IO_KICK)
|
|
|
|
: RTW_DEBUG_RECV_DESC,
|
2004-12-29 04:06:52 +03:00
|
|
|
("%s: rd %p buf %08x -> %08x ctl %08x -> %08x\n", __func__, rd,
|
|
|
|
le32toh(obuf), le32toh(rd->rd_buf), le32toh(octl),
|
|
|
|
le32toh(rd->rd_ctl)));
|
2013-10-18 01:24:24 +04:00
|
|
|
#else
|
|
|
|
__USE(octl);
|
|
|
|
__USE(obuf);
|
|
|
|
#endif
|
2004-12-25 09:58:37 +03:00
|
|
|
|
2004-09-26 06:29:15 +04:00
|
|
|
/* sync the descriptor */
|
2004-12-29 04:06:52 +03:00
|
|
|
bus_dmamap_sync(rdb->rdb_dmat, rdb->rdb_dmamap,
|
2004-12-29 03:21:37 +03:00
|
|
|
RTW_DESC_OFFSET(hd_rx, idx), sizeof(struct rtw_rxdesc),
|
2004-09-26 06:29:15 +04:00
|
|
|
BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2004-12-29 04:06:52 +03:00
|
|
|
rtw_rxdesc_init_all(struct rtw_rxdesc_blk *rdb, struct rtw_rxsoft *ctl, int kick)
|
2004-09-26 06:29:15 +04:00
|
|
|
{
|
|
|
|
int i;
|
2004-12-29 04:06:52 +03:00
|
|
|
struct rtw_rxsoft *rs;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
for (i = 0; i < rdb->rdb_ndesc; i++) {
|
|
|
|
rs = &ctl[i];
|
|
|
|
rtw_rxdesc_init(rdb, rs, i, kick);
|
2004-09-26 06:29:15 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
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
|
|
|
rtw_io_enable(struct rtw_softc *sc, uint8_t flags, int enable)
|
2004-09-26 06:29:15 +04:00
|
|
|
{
|
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_regs *regs = &sc->sc_regs;
|
2005-01-02 07:23:03 +03:00
|
|
|
uint8_t cr;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2004-12-25 09:58:37 +03:00
|
|
|
RTW_DPRINTF(RTW_DEBUG_IOSTATE, ("%s: %s 0x%02x\n", __func__,
|
2004-09-26 06:29:15 +04:00
|
|
|
enable ? "enable" : "disable", flags));
|
|
|
|
|
|
|
|
cr = RTW_READ8(regs, RTW_CR);
|
|
|
|
|
|
|
|
/* XXX reference source does not enable MULRW */
|
|
|
|
/* enable PCI Read/Write Multiple */
|
|
|
|
cr |= RTW_CR_MULRW;
|
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
|
|
|
|
|
|
|
/* The receive engine will always start at RDSAR. */
|
|
|
|
if (enable && (flags & ~cr & RTW_CR_RE)) {
|
|
|
|
struct rtw_rxdesc_blk *rdb;
|
|
|
|
rdb = &sc->sc_rxdesc_blk;
|
|
|
|
rdb->rdb_next = 0;
|
|
|
|
}
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
RTW_RBW(regs, RTW_CR, RTW_CR); /* XXX paranoia? */
|
|
|
|
if (enable)
|
|
|
|
cr |= flags;
|
|
|
|
else
|
|
|
|
cr &= ~flags;
|
|
|
|
RTW_WRITE8(regs, RTW_CR, cr);
|
|
|
|
RTW_SYNC(regs, RTW_CR, RTW_CR);
|
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
|
|
|
|
|
|
|
#ifdef RTW_DIAG
|
|
|
|
if (cr & RTW_CR_TE)
|
|
|
|
rtw_txring_fixup(sc, __func__, __LINE__);
|
|
|
|
#endif
|
2008-03-15 02:59:01 +03:00
|
|
|
if (cr & RTW_CR_TE) {
|
|
|
|
rtw_tx_kick(&sc->sc_regs,
|
|
|
|
RTW_TPPOLL_HPQ | RTW_TPPOLL_NPQ | RTW_TPPOLL_LPQ);
|
|
|
|
}
|
2004-09-26 06:29:15 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2006-11-16 04:32:37 +03:00
|
|
|
rtw_intr_rx(struct rtw_softc *sc, uint16_t isr)
|
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
|
|
|
#define IS_BEACON(__fc0) \
|
|
|
|
((__fc0 & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==\
|
|
|
|
(IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_BEACON))
|
|
|
|
|
2004-12-27 23:04:45 +03:00
|
|
|
static const int ratetbl[4] = {2, 4, 11, 22}; /* convert rates:
|
|
|
|
* hardware -> net80211
|
|
|
|
*/
|
2004-12-25 09:58:37 +03:00
|
|
|
u_int next, nproc = 0;
|
2004-12-29 01:30:07 +03:00
|
|
|
int hwrate, len, rate, rssi, sq;
|
2005-01-02 07:23:03 +03:00
|
|
|
uint32_t hrssi, hstat, htsfth, htsftl;
|
2004-12-29 04:06:52 +03:00
|
|
|
struct rtw_rxdesc *rd;
|
|
|
|
struct rtw_rxsoft *rs;
|
|
|
|
struct rtw_rxdesc_blk *rdb;
|
2004-09-26 06:29:15 +04:00
|
|
|
struct mbuf *m;
|
2005-06-22 10:14:51 +04:00
|
|
|
struct ifnet *ifp = &sc->sc_if;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
struct ieee80211_node *ni;
|
2005-06-22 10:14:51 +04:00
|
|
|
struct ieee80211_frame_min *wh;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
rdb = &sc->sc_rxdesc_blk;
|
2004-12-25 09:58:37 +03:00
|
|
|
|
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
|
|
|
for (next = rdb->rdb_next; ; next = rdb->rdb_next) {
|
|
|
|
KASSERT(next < rdb->rdb_ndesc);
|
2007-11-17 02:35:19 +03:00
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
rtw_rxdescs_sync(rdb, next, 1,
|
If defined(RTW_DEBUG), provide a sysctl (hw.rtw.rxbufs_limit) for
limiting the number of rx buffers an rtw may allocate. Use this
sysctl to test the code that copes with buffer exhaustion.
Allocate at most RTW_RXQLEN rx buffers, stopping at the sysctl
limit. Record in sc_nrxdesc how many were allocated, and put the
end-of-ring indication on sc_rxdesc[sc_nrxdesc - 1]. In rtw_init,
if no rx buffers could be allocated, log a complaint, clear
IFF_RUNNING, and exit with an error.
Many changes to accomodate a short rx ring, mainly of the "add a
rx-ring length argument" variety. XXX I really should consolidate
all of the rx ring variables in one struct and pass that to the
rx-ring subroutines.
Bug fix: after calling MCLGET, use the (m->m_flags & M_EXT) idiom
to check for success, instead of m != NULL.
Bug fix: at the top of rtw_start, if IFF_RUNNING is not set, or
IFF_OACTIVE is, get out.
2004-12-29 01:21:15 +03:00
|
|
|
BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
|
2004-12-29 04:06:52 +03:00
|
|
|
rd = &rdb->rdb_desc[next];
|
|
|
|
rs = &sc->sc_rxsoft[next];
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
hstat = le32toh(rd->rd_stat);
|
|
|
|
hrssi = le32toh(rd->rd_rssi);
|
|
|
|
htsfth = le32toh(rd->rd_tsfth);
|
|
|
|
htsftl = le32toh(rd->rd_tsftl);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2004-12-25 09:58:37 +03:00
|
|
|
RTW_DPRINTF(RTW_DEBUG_RECV_DESC,
|
|
|
|
("%s: rxdesc[%d] hstat %08x hrssi %08x htsft %08x%08x\n",
|
|
|
|
__func__, next, hstat, hrssi, htsfth, htsftl));
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2004-12-25 09:58:37 +03:00
|
|
|
++nproc;
|
|
|
|
|
|
|
|
/* still belongs to NIC */
|
|
|
|
if ((hstat & RTW_RXSTAT_OWN) != 0) {
|
2007-01-06 09:07:55 +03:00
|
|
|
rtw_rxdescs_sync(rdb, next, 1, BUS_DMASYNC_PREREAD);
|
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
|
|
|
break;
|
2004-12-25 09:58:37 +03:00
|
|
|
}
|
2004-09-26 06:29:15 +04:00
|
|
|
|
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
|
|
|
/* ieee80211_input() might reset the receive engine
|
|
|
|
* (e.g. by indirectly calling rtw_tune()), so save
|
|
|
|
* the next pointer here and retrieve it again on
|
|
|
|
* the next round.
|
|
|
|
*/
|
|
|
|
rdb->rdb_next = (next + 1) % rdb->rdb_ndesc;
|
|
|
|
|
2005-03-02 08:20:43 +03:00
|
|
|
#ifdef RTW_DEBUG
|
|
|
|
#define PRINTSTAT(flag) do { \
|
|
|
|
if ((hstat & flag) != 0) { \
|
|
|
|
printf("%s" #flag, delim); \
|
|
|
|
delim = ","; \
|
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
if ((rtw_debug & RTW_DEBUG_RECV_DESC) != 0) {
|
|
|
|
const char *delim = "<";
|
2007-12-21 21:22:43 +03:00
|
|
|
printf("%s: ", device_xname(sc->sc_dev));
|
2005-03-02 08:20:43 +03:00
|
|
|
if ((hstat & RTW_RXSTAT_DEBUG) != 0) {
|
|
|
|
printf("status %08x", hstat);
|
|
|
|
PRINTSTAT(RTW_RXSTAT_SPLCP);
|
|
|
|
PRINTSTAT(RTW_RXSTAT_MAR);
|
|
|
|
PRINTSTAT(RTW_RXSTAT_PAR);
|
|
|
|
PRINTSTAT(RTW_RXSTAT_BAR);
|
|
|
|
PRINTSTAT(RTW_RXSTAT_PWRMGT);
|
|
|
|
PRINTSTAT(RTW_RXSTAT_CRC32);
|
|
|
|
PRINTSTAT(RTW_RXSTAT_ICV);
|
|
|
|
printf(">, ");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif /* RTW_DEBUG */
|
|
|
|
|
2004-09-26 06:29:15 +04:00
|
|
|
if ((hstat & RTW_RXSTAT_IOERROR) != 0) {
|
2007-12-21 21:22:43 +03:00
|
|
|
aprint_error_dev(sc->sc_dev,
|
|
|
|
"DMA error/FIFO overflow %08" PRIx32 ", "
|
|
|
|
"rx descriptor %d\n", hstat, next);
|
2005-06-22 10:14:51 +04:00
|
|
|
ifp->if_ierrors++;
|
2004-09-26 06:29:15 +04:00
|
|
|
goto next;
|
|
|
|
}
|
|
|
|
|
Per discussion on tech-kern and tech-userlevel, move the bit-twiddling
macros, __BIT, __BITS, SHIFTIN, SHIFTOUT, and __arraycount() from
lib/libkern/libkern.h to sys/cdefs.h. Add a __-prefix to SHIFTIN
and SHIFTOUT, and add a manual page for the bit-twiddling macros,
bits(3).
Make the __BIT and __BITS macros "widthless," as best I can, by
changing their type to uintmax_t from uint32_t. XXX The manual
page lags this change by a bit.
Define __PRIxBIT and __PRIxBITS printf(3) format strings.
2006-08-31 23:24:37 +04:00
|
|
|
len = __SHIFTOUT(hstat, RTW_RXSTAT_LENGTH_MASK);
|
2004-12-25 10:24:17 +03:00
|
|
|
if (len < IEEE80211_MIN_LEN) {
|
|
|
|
sc->sc_ic.ic_stats.is_rx_tooshort++;
|
|
|
|
goto next;
|
|
|
|
}
|
2007-12-21 21:22:43 +03:00
|
|
|
if (len > rs->rs_mbuf->m_len) {
|
Use device_t and its accessors throughout. Use aprint_*_dev().
Improve PMF-ability.
Add a 'flags' argument to suspend/resume handlers and
callers such as pmf_system_suspend().
Define a flag, PMF_F_SELF, which indicates to PMF that a
device is suspending/resuming itself. Add helper routines,
pmf_device_suspend_self(dev) and pmf_device_resume_self(dev),
that call pmf_device_suspend(dev, PMF_F_SELF) and
pmf_device_resume(dev, PMF_F_SELF), respectively. Use
PMF_F_SELF to suspend/resume self in ath(4), audio(4),
rtw(4), and sip(4).
In ath(4) and in rtw(4), replace the icky sc_enable/sc_disable
callbacks, provided by the bus front-end, with
self-suspension/resumption. Also, clean up the bus
front-ends. Make sure that the interrupt handler is
disestablished during suspension. Get rid of driver-private
flags (e.g., RTW_F_ENABLED, ath_softc->sc_invalid); use
device_is_active()/device_has_power() calls, instead.
In the network-class suspend handler, call if_stop(, 0)
instead of if_stop(, 1), because the latter is superfluous
(bus- and driver-suspension hooks will 'disable' the NIC),
and it may cause recursion.
In the network-class resume handler, prevent infinite
recursion through if_init() by getting out early if we are
self-suspending (PMF_F_SELF).
rtw(4) improvements:
Destroy rtw(4) callouts when we detach it. Make rtw at
pci detachable. Print some more information with the "rx
frame too long" warning.
Remove activate() methods:
Get rid of rtw_activate() and ath_activate(). The device
activate() methods are not good for much these days.
Make ath at cardbus resume with crypto functions intact:
Introduce a boolean device property, "pmf-powerdown". If
pmf-powerdown is present and false, it indicates that a
bus back-end should not remove power from a device.
Honor this property in cardbus_child_suspend().
Set this property to 'false' in ath_attach(), since removing
power from an ath at cardbus seems to lobotomize the WPA
crypto engine. XXX Should the pmf-powerdown property
propagate toward the root of the device tree?
Miscellaneous ath(4) changes:
Warn if ath(4) tries to write crypto keys to suspended
hardware.
Reduce differences between FreeBSD and NetBSD in ath(4)
multicast filter setup.
Make ath_printrxbuf() print an rx descriptor's status &
key index, to help debug crypto errors.
Shorten a staircase in ath_ioctl(). Don't check for
ieee80211_ioctl() return code ERESTART, it never happens.
2008-03-12 21:02:21 +03:00
|
|
|
aprint_error_dev(sc->sc_dev,
|
|
|
|
"rx frame too long, %d > %d, %08" PRIx32
|
|
|
|
", desc %d\n",
|
|
|
|
len, rs->rs_mbuf->m_len, hstat, next);
|
2007-12-21 21:22:43 +03:00
|
|
|
ifp->if_ierrors++;
|
|
|
|
goto next;
|
|
|
|
}
|
2005-01-31 05:51:17 +03:00
|
|
|
|
Per discussion on tech-kern and tech-userlevel, move the bit-twiddling
macros, __BIT, __BITS, SHIFTIN, SHIFTOUT, and __arraycount() from
lib/libkern/libkern.h to sys/cdefs.h. Add a __-prefix to SHIFTIN
and SHIFTOUT, and add a manual page for the bit-twiddling macros,
bits(3).
Make the __BIT and __BITS macros "widthless," as best I can, by
changing their type to uintmax_t from uint32_t. XXX The manual
page lags this change by a bit.
Define __PRIxBIT and __PRIxBITS printf(3) format strings.
2006-08-31 23:24:37 +04:00
|
|
|
hwrate = __SHIFTOUT(hstat, RTW_RXSTAT_RATE_MASK);
|
2007-05-29 22:33:38 +04:00
|
|
|
if (hwrate >= __arraycount(ratetbl)) {
|
2007-12-21 21:22:43 +03:00
|
|
|
aprint_error_dev(sc->sc_dev,
|
|
|
|
"unknown rate #%" __PRIuBITS "\n",
|
Per discussion on tech-kern and tech-userlevel, move the bit-twiddling
macros, __BIT, __BITS, SHIFTIN, SHIFTOUT, and __arraycount() from
lib/libkern/libkern.h to sys/cdefs.h. Add a __-prefix to SHIFTIN
and SHIFTOUT, and add a manual page for the bit-twiddling macros,
bits(3).
Make the __BIT and __BITS macros "widthless," as best I can, by
changing their type to uintmax_t from uint32_t. XXX The manual
page lags this change by a bit.
Define __PRIxBIT and __PRIxBITS printf(3) format strings.
2006-08-31 23:24:37 +04:00
|
|
|
__SHIFTOUT(hstat, RTW_RXSTAT_RATE_MASK));
|
2005-06-22 10:14:51 +04:00
|
|
|
ifp->if_ierrors++;
|
2004-12-25 10:24:17 +03:00
|
|
|
goto next;
|
2004-09-26 06:29:15 +04:00
|
|
|
}
|
2004-12-27 23:04:45 +03:00
|
|
|
rate = ratetbl[hwrate];
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
#ifdef RTW_DEBUG
|
2005-03-02 08:20:43 +03:00
|
|
|
RTW_DPRINTF(RTW_DEBUG_RECV_DESC,
|
|
|
|
("rate %d.%d Mb/s, time %08x%08x\n", (rate * 5) / 10,
|
|
|
|
(rate * 5) % 10, htsfth, htsftl));
|
2004-09-26 06:29:15 +04:00
|
|
|
#endif /* RTW_DEBUG */
|
|
|
|
|
|
|
|
/* if bad flags, skip descriptor */
|
|
|
|
if ((hstat & RTW_RXSTAT_ONESEG) != RTW_RXSTAT_ONESEG) {
|
2007-12-21 21:22:43 +03:00
|
|
|
aprint_error_dev(sc->sc_dev, "too many rx segments, "
|
|
|
|
"next=%d, %08" PRIx32 "\n", next, hstat);
|
2004-09-26 06:29:15 +04:00
|
|
|
goto next;
|
|
|
|
}
|
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
bus_dmamap_sync(sc->sc_dmat, rs->rs_dmamap, 0,
|
|
|
|
rs->rs_dmamap->dm_mapsize, BUS_DMASYNC_POSTREAD);
|
2004-12-23 09:03:09 +03:00
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
m = rs->rs_mbuf;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
/* if temporarily out of memory, re-use mbuf */
|
2004-12-29 04:06:52 +03:00
|
|
|
switch (rtw_rxsoft_alloc(sc->sc_dmat, rs)) {
|
2004-12-23 09:03:09 +03:00
|
|
|
case 0:
|
|
|
|
break;
|
|
|
|
case ENOBUFS:
|
2007-12-21 21:22:43 +03:00
|
|
|
aprint_error_dev(sc->sc_dev,
|
|
|
|
"rtw_rxsoft_alloc(, %d) failed, dropping packet\n",
|
|
|
|
next);
|
2004-09-26 06:29:15 +04:00
|
|
|
goto next;
|
2004-12-23 09:03:09 +03:00
|
|
|
default:
|
|
|
|
/* XXX shorten rx ring, instead? */
|
2007-12-21 21:22:43 +03:00
|
|
|
aprint_error_dev(sc->sc_dev,
|
|
|
|
"could not load DMA map\n");
|
2004-09-26 06:29:15 +04:00
|
|
|
}
|
|
|
|
|
2007-11-17 02:35:19 +03:00
|
|
|
sq = __SHIFTOUT(hrssi, RTW_RXRSSI_SQ);
|
|
|
|
|
2004-09-26 06:29:15 +04:00
|
|
|
if (sc->sc_rfchipid == RTW_RFCHIPID_PHILIPS)
|
2007-11-17 02:35:19 +03:00
|
|
|
rssi = UINT8_MAX - sq;
|
2004-09-26 06:29:15 +04:00
|
|
|
else {
|
Per discussion on tech-kern and tech-userlevel, move the bit-twiddling
macros, __BIT, __BITS, SHIFTIN, SHIFTOUT, and __arraycount() from
lib/libkern/libkern.h to sys/cdefs.h. Add a __-prefix to SHIFTIN
and SHIFTOUT, and add a manual page for the bit-twiddling macros,
bits(3).
Make the __BIT and __BITS macros "widthless," as best I can, by
changing their type to uintmax_t from uint32_t. XXX The manual
page lags this change by a bit.
Define __PRIxBIT and __PRIxBITS printf(3) format strings.
2006-08-31 23:24:37 +04:00
|
|
|
rssi = __SHIFTOUT(hrssi, RTW_RXRSSI_IMR_RSSI);
|
2004-09-26 06:29:15 +04:00
|
|
|
/* TBD find out each front-end's LNA gain in the
|
|
|
|
* front-end's units
|
|
|
|
*/
|
|
|
|
if ((hrssi & RTW_RXRSSI_IMR_LNA) == 0)
|
|
|
|
rssi |= 0x80;
|
|
|
|
}
|
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
/* Note well: now we cannot recycle the rs_mbuf unless
|
2004-12-29 01:30:07 +03:00
|
|
|
* we restore its original length.
|
|
|
|
*/
|
2005-06-22 10:14:51 +04:00
|
|
|
m->m_pkthdr.rcvif = ifp;
|
2004-12-25 10:24:17 +03:00
|
|
|
m->m_pkthdr.len = m->m_len = len;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2005-06-22 10:14:51 +04:00
|
|
|
wh = mtod(m, struct ieee80211_frame_min *);
|
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
|
|
|
|
|
|
|
if (!IS_BEACON(wh->i_fc[0]))
|
|
|
|
sc->sc_led_state.ls_event |= RTW_LED_S_RX;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
sc->sc_tsfth = htsfth;
|
|
|
|
|
2004-12-21 02:05:41 +03:00
|
|
|
#ifdef RTW_DEBUG
|
2005-06-22 10:14:51 +04:00
|
|
|
if ((ifp->if_flags & (IFF_DEBUG|IFF_LINK2)) ==
|
2004-12-21 02:05:41 +03:00
|
|
|
(IFF_DEBUG|IFF_LINK2)) {
|
|
|
|
ieee80211_dump_pkt(mtod(m, uint8_t *), m->m_pkthdr.len,
|
|
|
|
rate, rssi);
|
|
|
|
}
|
|
|
|
#endif /* RTW_DEBUG */
|
2004-12-29 01:30:07 +03:00
|
|
|
|
|
|
|
if (sc->sc_radiobpf != NULL) {
|
|
|
|
struct rtw_rx_radiotap_header *rr = &sc->sc_rxtap;
|
|
|
|
|
|
|
|
rr->rr_tsft =
|
|
|
|
htole64(((uint64_t)htsfth << 32) | htsftl);
|
|
|
|
|
2007-11-17 02:35:19 +03:00
|
|
|
rr->rr_flags = IEEE80211_RADIOTAP_F_FCS;
|
|
|
|
|
2004-12-29 01:30:07 +03:00
|
|
|
if ((hstat & RTW_RXSTAT_SPLCP) != 0)
|
2007-11-17 02:35:19 +03:00
|
|
|
rr->rr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
|
|
|
|
if ((hstat & RTW_RXSTAT_CRC32) != 0)
|
|
|
|
rr->rr_flags |= IEEE80211_RADIOTAP_F_BADFCS;
|
2004-12-29 01:30:07 +03:00
|
|
|
|
|
|
|
rr->rr_rate = rate;
|
|
|
|
|
2007-11-17 02:35:19 +03:00
|
|
|
if (sc->sc_rfchipid == RTW_RFCHIPID_PHILIPS)
|
|
|
|
rr->rr_u.u_philips.p_antsignal = rssi;
|
|
|
|
else {
|
|
|
|
rr->rr_u.u_other.o_antsignal = rssi;
|
|
|
|
rr->rr_u.u_other.o_barker_lock =
|
|
|
|
htole16(UINT8_MAX - sq);
|
|
|
|
}
|
|
|
|
|
2010-04-05 11:19:28 +04:00
|
|
|
bpf_mtap2(sc->sc_radiobpf,
|
2010-01-20 01:06:18 +03:00
|
|
|
rr, sizeof(sc->sc_rxtapu), m);
|
2004-12-29 01:30:07 +03:00
|
|
|
}
|
|
|
|
|
2007-11-17 02:35:19 +03:00
|
|
|
if ((hstat & RTW_RXSTAT_RES) != 0) {
|
|
|
|
m_freem(m);
|
|
|
|
goto next;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* CRC is included with the packet; trim it off. */
|
|
|
|
m_adj(m, -IEEE80211_CRC_LEN);
|
|
|
|
|
|
|
|
/* TBD use _MAR, _BAR, _PAR flags as hints to _find_rxnode? */
|
|
|
|
ni = ieee80211_find_rxnode(&sc->sc_ic, wh);
|
2005-06-22 10:14:51 +04:00
|
|
|
ieee80211_input(&sc->sc_ic, m, ni, rssi, htsftl);
|
|
|
|
ieee80211_free_node(ni);
|
2004-09-26 06:29:15 +04:00
|
|
|
next:
|
2004-12-29 04:06:52 +03:00
|
|
|
rtw_rxdesc_init(rdb, rs, next, 0);
|
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
|
|
|
#undef IS_BEACON
|
2004-09-26 06:29:15 +04:00
|
|
|
}
|
|
|
|
|
2004-12-19 11:19:25 +03:00
|
|
|
static void
|
2006-11-16 04:32:37 +03:00
|
|
|
rtw_txsoft_release(bus_dma_tag_t dmat, struct ieee80211com *ic,
|
2004-12-29 04:06:52 +03:00
|
|
|
struct rtw_txsoft *ts)
|
2004-12-19 11:19:25 +03:00
|
|
|
{
|
|
|
|
struct mbuf *m;
|
|
|
|
struct ieee80211_node *ni;
|
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
m = ts->ts_mbuf;
|
|
|
|
ni = ts->ts_ni;
|
2004-12-25 09:58:37 +03:00
|
|
|
KASSERT(m != NULL);
|
|
|
|
KASSERT(ni != NULL);
|
2004-12-29 04:06:52 +03:00
|
|
|
ts->ts_mbuf = NULL;
|
|
|
|
ts->ts_ni = NULL;
|
2004-12-19 11:19:25 +03:00
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
bus_dmamap_sync(dmat, ts->ts_dmamap, 0, ts->ts_dmamap->dm_mapsize,
|
2004-12-19 11:19:25 +03:00
|
|
|
BUS_DMASYNC_POSTWRITE);
|
2004-12-29 04:06:52 +03:00
|
|
|
bus_dmamap_unload(dmat, ts->ts_dmamap);
|
2004-12-19 11:19:25 +03:00
|
|
|
m_freem(m);
|
2005-06-22 10:14:51 +04:00
|
|
|
ieee80211_free_node(ni);
|
2004-12-19 11:19:25 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2004-12-29 04:06:52 +03:00
|
|
|
rtw_txsofts_release(bus_dma_tag_t dmat, struct ieee80211com *ic,
|
|
|
|
struct rtw_txsoft_blk *tsb)
|
2004-12-19 11:19:25 +03:00
|
|
|
{
|
2004-12-29 04:06:52 +03:00
|
|
|
struct rtw_txsoft *ts;
|
2004-12-19 11:19:25 +03:00
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
while ((ts = SIMPLEQ_FIRST(&tsb->tsb_dirtyq)) != NULL) {
|
|
|
|
rtw_txsoft_release(dmat, ic, ts);
|
|
|
|
SIMPLEQ_REMOVE_HEAD(&tsb->tsb_dirtyq, ts_q);
|
|
|
|
SIMPLEQ_INSERT_TAIL(&tsb->tsb_freeq, ts, ts_q);
|
2004-12-19 11:19:25 +03:00
|
|
|
}
|
2005-11-23 07:12:33 +03:00
|
|
|
tsb->tsb_tx_timer = 0;
|
2004-12-19 11:19:25 +03:00
|
|
|
}
|
|
|
|
|
2005-12-24 23:27:29 +03:00
|
|
|
static inline void
|
2004-12-29 04:06:52 +03:00
|
|
|
rtw_collect_txpkt(struct rtw_softc *sc, struct rtw_txdesc_blk *tdb,
|
|
|
|
struct rtw_txsoft *ts, int ndesc)
|
2004-12-19 11:19:25 +03:00
|
|
|
{
|
2004-12-23 08:44:39 +03:00
|
|
|
uint32_t hstat;
|
2004-12-19 11:19:25 +03:00
|
|
|
int data_retry, rts_retry;
|
2004-12-29 04:06:52 +03:00
|
|
|
struct rtw_txdesc *tdn;
|
2004-12-19 11:19:25 +03:00
|
|
|
const char *condstring;
|
2005-06-22 10:14:51 +04:00
|
|
|
struct ifnet *ifp = &sc->sc_if;
|
2004-12-19 11:19:25 +03:00
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
rtw_txsoft_release(sc->sc_dmat, &sc->sc_ic, ts);
|
2004-12-19 11:19:25 +03:00
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
tdb->tdb_nfree += ndesc;
|
2004-12-19 11:19:25 +03:00
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
tdn = &tdb->tdb_desc[ts->ts_last];
|
2004-12-19 11:19:25 +03:00
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
hstat = le32toh(tdn->td_stat);
|
Per discussion on tech-kern and tech-userlevel, move the bit-twiddling
macros, __BIT, __BITS, SHIFTIN, SHIFTOUT, and __arraycount() from
lib/libkern/libkern.h to sys/cdefs.h. Add a __-prefix to SHIFTIN
and SHIFTOUT, and add a manual page for the bit-twiddling macros,
bits(3).
Make the __BIT and __BITS macros "widthless," as best I can, by
changing their type to uintmax_t from uint32_t. XXX The manual
page lags this change by a bit.
Define __PRIxBIT and __PRIxBITS printf(3) format strings.
2006-08-31 23:24:37 +04:00
|
|
|
rts_retry = __SHIFTOUT(hstat, RTW_TXSTAT_RTSRETRY_MASK);
|
|
|
|
data_retry = __SHIFTOUT(hstat, RTW_TXSTAT_DRC_MASK);
|
2004-12-19 11:19:25 +03:00
|
|
|
|
2005-06-22 10:14:51 +04:00
|
|
|
ifp->if_collisions += rts_retry + data_retry;
|
2004-12-19 11:19:25 +03:00
|
|
|
|
2004-12-23 08:44:39 +03:00
|
|
|
if ((hstat & RTW_TXSTAT_TOK) != 0)
|
2004-12-19 11:19:25 +03:00
|
|
|
condstring = "ok";
|
|
|
|
else {
|
2005-06-22 10:14:51 +04:00
|
|
|
ifp->if_oerrors++;
|
2004-12-19 11:19:25 +03:00
|
|
|
condstring = "error";
|
|
|
|
}
|
|
|
|
|
2013-10-18 01:24:24 +04:00
|
|
|
#ifdef RTW_DEBUG
|
2004-12-25 09:58:37 +03:00
|
|
|
DPRINTF(sc, RTW_DEBUG_XMIT_DESC,
|
2004-12-29 04:06:52 +03:00
|
|
|
("%s: ts %p txdesc[%d, %d] %s tries rts %u data %u\n",
|
2007-12-21 21:22:43 +03:00
|
|
|
device_xname(sc->sc_dev), ts, ts->ts_first, ts->ts_last,
|
2004-12-19 11:19:25 +03:00
|
|
|
condstring, rts_retry, data_retry));
|
2013-10-18 01:24:24 +04:00
|
|
|
#else
|
|
|
|
__USE(condstring);
|
|
|
|
#endif
|
2004-12-19 11:19:25 +03:00
|
|
|
}
|
|
|
|
|
2005-11-23 07:12:33 +03:00
|
|
|
static void
|
|
|
|
rtw_reset_oactive(struct rtw_softc *sc)
|
|
|
|
{
|
|
|
|
short oflags;
|
|
|
|
int pri;
|
|
|
|
struct rtw_txsoft_blk *tsb;
|
|
|
|
struct rtw_txdesc_blk *tdb;
|
|
|
|
oflags = sc->sc_if.if_flags;
|
|
|
|
for (pri = 0; pri < RTW_NTXPRI; pri++) {
|
|
|
|
tsb = &sc->sc_txsoft_blk[pri];
|
|
|
|
tdb = &sc->sc_txdesc_blk[pri];
|
|
|
|
if (!SIMPLEQ_EMPTY(&tsb->tsb_freeq) && tdb->tdb_nfree > 0)
|
|
|
|
sc->sc_if.if_flags &= ~IFF_OACTIVE;
|
|
|
|
}
|
|
|
|
if (oflags != sc->sc_if.if_flags) {
|
|
|
|
DPRINTF(sc, RTW_DEBUG_OACTIVE,
|
|
|
|
("%s: reset OACTIVE\n", __func__));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-12-19 11:19:25 +03:00
|
|
|
/* Collect transmitted packets. */
|
2009-04-02 04:57:20 +04:00
|
|
|
static bool
|
2004-12-29 04:06:52 +03:00
|
|
|
rtw_collect_txring(struct rtw_softc *sc, struct rtw_txsoft_blk *tsb,
|
2005-11-23 07:12:33 +03:00
|
|
|
struct rtw_txdesc_blk *tdb, int force)
|
2004-12-19 11:19:25 +03:00
|
|
|
{
|
2009-04-02 04:57:20 +04:00
|
|
|
bool collected = false;
|
2004-12-19 11:19:25 +03:00
|
|
|
int ndesc;
|
2004-12-29 04:06:52 +03:00
|
|
|
struct rtw_txsoft *ts;
|
2004-12-19 11:19:25 +03:00
|
|
|
|
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
|
|
|
#ifdef RTW_DEBUG
|
|
|
|
rtw_dump_rings(sc);
|
|
|
|
#endif
|
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
while ((ts = SIMPLEQ_FIRST(&tsb->tsb_dirtyq)) != NULL) {
|
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
|
|
|
/* If we're clearing a failed transmission, only clear
|
|
|
|
up to the last packet the hardware has processed. */
|
|
|
|
if (ts->ts_first == rtw_txring_next(&sc->sc_regs, tdb))
|
|
|
|
break;
|
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
ndesc = 1 + ts->ts_last - ts->ts_first;
|
|
|
|
if (ts->ts_last < ts->ts_first)
|
|
|
|
ndesc += tdb->tdb_ndesc;
|
2004-12-19 11:19:25 +03:00
|
|
|
|
2004-12-20 03:16:21 +03:00
|
|
|
KASSERT(ndesc > 0);
|
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
rtw_txdescs_sync(tdb, ts->ts_first, ndesc,
|
2004-12-19 11:19:25 +03:00
|
|
|
BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
|
|
|
|
|
2005-11-23 07:12:33 +03:00
|
|
|
if (force) {
|
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
|
|
|
int next;
|
|
|
|
#ifdef RTW_DIAG
|
|
|
|
printf("%s: clearing packet, stats", __func__);
|
|
|
|
#endif
|
|
|
|
for (next = ts->ts_first; ;
|
|
|
|
next = RTW_NEXT_IDX(tdb, next)) {
|
|
|
|
#ifdef RTW_DIAG
|
|
|
|
printf(" %" PRIx32 "/%" PRIx32 "/%" PRIx32 "/%" PRIu32 "/%" PRIx32, le32toh(tdb->tdb_desc[next].td_stat), le32toh(tdb->tdb_desc[next].td_ctl1), le32toh(tdb->tdb_desc[next].td_buf), le32toh(tdb->tdb_desc[next].td_len), le32toh(tdb->tdb_desc[next].td_next));
|
|
|
|
#endif
|
|
|
|
tdb->tdb_desc[next].td_stat &=
|
2005-11-23 07:12:33 +03:00
|
|
|
~htole32(RTW_TXSTAT_OWN);
|
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
|
|
|
if (next == ts->ts_last)
|
2005-11-23 07:12:33 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
rtw_txdescs_sync(tdb, ts->ts_first, ndesc,
|
|
|
|
BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
|
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
|
|
|
#ifdef RTW_DIAG
|
|
|
|
next = RTW_NEXT_IDX(tdb, next);
|
|
|
|
printf(" -> end %u stat %" PRIx32 ", was %u\n", next,
|
|
|
|
le32toh(tdb->tdb_desc[next].td_stat),
|
|
|
|
rtw_txring_next(&sc->sc_regs, tdb));
|
|
|
|
#endif
|
2005-11-23 07:12:33 +03:00
|
|
|
} else if ((tdb->tdb_desc[ts->ts_last].td_stat &
|
2007-01-06 09:07:55 +03:00
|
|
|
htole32(RTW_TXSTAT_OWN)) != 0) {
|
|
|
|
rtw_txdescs_sync(tdb, ts->ts_last, 1,
|
|
|
|
BUS_DMASYNC_PREREAD);
|
2004-12-19 11:19:25 +03:00
|
|
|
break;
|
2007-01-06 09:07:55 +03:00
|
|
|
}
|
2004-12-19 11:19:25 +03:00
|
|
|
|
2009-04-02 04:57:20 +04:00
|
|
|
collected = true;
|
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
rtw_collect_txpkt(sc, tdb, ts, ndesc);
|
|
|
|
SIMPLEQ_REMOVE_HEAD(&tsb->tsb_dirtyq, ts_q);
|
|
|
|
SIMPLEQ_INSERT_TAIL(&tsb->tsb_freeq, ts, ts_q);
|
2004-12-19 11:19:25 +03:00
|
|
|
}
|
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
|
|
|
|
2006-05-26 16:52:45 +04:00
|
|
|
/* no more pending transmissions, cancel watchdog */
|
2004-12-29 04:06:52 +03:00
|
|
|
if (ts == NULL)
|
|
|
|
tsb->tsb_tx_timer = 0;
|
2005-11-23 07:12:33 +03:00
|
|
|
rtw_reset_oactive(sc);
|
2009-04-02 04:57:20 +04:00
|
|
|
|
|
|
|
return collected;
|
2004-12-19 11:19:25 +03:00
|
|
|
}
|
|
|
|
|
2004-09-26 06:29:15 +04:00
|
|
|
static void
|
2005-01-02 07:23:03 +03:00
|
|
|
rtw_intr_tx(struct rtw_softc *sc, uint16_t isr)
|
2004-09-26 06:29:15 +04:00
|
|
|
{
|
2004-12-19 11:19:25 +03:00
|
|
|
int pri;
|
2004-12-29 04:06:52 +03:00
|
|
|
struct rtw_txsoft_blk *tsb;
|
|
|
|
struct rtw_txdesc_blk *tdb;
|
2005-06-22 10:14:51 +04:00
|
|
|
struct ifnet *ifp = &sc->sc_if;
|
2004-12-19 11:19:25 +03:00
|
|
|
|
|
|
|
for (pri = 0; pri < RTW_NTXPRI; pri++) {
|
2004-12-29 04:06:52 +03:00
|
|
|
tsb = &sc->sc_txsoft_blk[pri];
|
|
|
|
tdb = &sc->sc_txdesc_blk[pri];
|
2005-11-23 07:12:33 +03:00
|
|
|
rtw_collect_txring(sc, tsb, tdb, 0);
|
2004-12-19 11:19:25 +03:00
|
|
|
}
|
|
|
|
|
2005-11-23 07:12:33 +03:00
|
|
|
if ((isr & RTW_INTR_TX) != 0)
|
|
|
|
rtw_start(ifp);
|
|
|
|
|
2004-09-26 06:29:15 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2005-01-02 07:23:03 +03:00
|
|
|
rtw_intr_beacon(struct rtw_softc *sc, uint16_t isr)
|
2004-09-26 06:29:15 +04:00
|
|
|
{
|
2005-11-23 07:12:33 +03:00
|
|
|
u_int next;
|
|
|
|
uint32_t tsfth, tsftl;
|
|
|
|
struct ieee80211com *ic;
|
|
|
|
struct rtw_txdesc_blk *tdb = &sc->sc_txdesc_blk[RTW_TXPRIBCN];
|
|
|
|
struct rtw_txsoft_blk *tsb = &sc->sc_txsoft_blk[RTW_TXPRIBCN];
|
|
|
|
struct mbuf *m;
|
|
|
|
|
|
|
|
tsfth = RTW_READ(&sc->sc_regs, RTW_TSFTRH);
|
|
|
|
tsftl = RTW_READ(&sc->sc_regs, RTW_TSFTRL);
|
|
|
|
|
|
|
|
if ((isr & (RTW_INTR_TBDOK|RTW_INTR_TBDER)) != 0) {
|
|
|
|
next = rtw_txring_next(&sc->sc_regs, tdb);
|
2013-10-18 01:24:24 +04:00
|
|
|
#ifdef RTW_DEBUG
|
2005-11-23 07:12:33 +03:00
|
|
|
RTW_DPRINTF(RTW_DEBUG_BEACON,
|
|
|
|
("%s: beacon ring %sprocessed, isr = %#04" PRIx16
|
|
|
|
", next %u expected %u, %" PRIu64 "\n", __func__,
|
|
|
|
(next == tdb->tdb_next) ? "" : "un", isr, next,
|
|
|
|
tdb->tdb_next, (uint64_t)tsfth << 32 | tsftl));
|
2013-10-18 01:24:24 +04:00
|
|
|
#else
|
|
|
|
__USE(next);
|
|
|
|
__USE(tsfth);
|
|
|
|
__USE(tsftl);
|
|
|
|
#endif
|
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
|
|
|
if ((RTW_READ8(&sc->sc_regs, RTW_TPPOLL) & RTW_TPPOLL_BQ) == 0)
|
2005-11-23 07:12:33 +03:00
|
|
|
rtw_collect_txring(sc, tsb, tdb, 1);
|
|
|
|
}
|
|
|
|
/* Start beacon transmission. */
|
|
|
|
|
|
|
|
if ((isr & RTW_INTR_BCNINT) != 0 &&
|
|
|
|
sc->sc_ic.ic_state == IEEE80211_S_RUN &&
|
|
|
|
SIMPLEQ_EMPTY(&tsb->tsb_dirtyq)) {
|
|
|
|
RTW_DPRINTF(RTW_DEBUG_BEACON,
|
|
|
|
("%s: beacon prep. time, isr = %#04" PRIx16
|
|
|
|
", %16" PRIu64 "\n", __func__, isr,
|
|
|
|
(uint64_t)tsfth << 32 | tsftl));
|
|
|
|
ic = &sc->sc_ic;
|
|
|
|
m = rtw_beacon_alloc(sc, ic->ic_bss);
|
|
|
|
|
|
|
|
if (m == NULL) {
|
2007-12-21 21:22:43 +03:00
|
|
|
aprint_error_dev(sc->sc_dev,
|
|
|
|
"could not allocate beacon\n");
|
2005-11-23 07:12:33 +03:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
m->m_pkthdr.rcvif = (void *)ieee80211_ref_node(ic->ic_bss);
|
|
|
|
IF_ENQUEUE(&sc->sc_beaconq, m);
|
|
|
|
rtw_start(&sc->sc_if);
|
|
|
|
}
|
2004-09-26 06:29:15 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2006-11-16 04:32:37 +03:00
|
|
|
rtw_intr_atim(struct rtw_softc *sc)
|
2004-09-26 06:29:15 +04:00
|
|
|
{
|
|
|
|
/* TBD */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2004-12-25 09:58:37 +03:00
|
|
|
#ifdef RTW_DEBUG
|
|
|
|
static void
|
|
|
|
rtw_dump_rings(struct rtw_softc *sc)
|
|
|
|
{
|
2004-12-29 04:06:52 +03:00
|
|
|
struct rtw_txdesc_blk *tdb;
|
|
|
|
struct rtw_rxdesc *rd;
|
|
|
|
struct rtw_rxdesc_blk *rdb;
|
2004-12-25 09:58:37 +03:00
|
|
|
int desc, pri;
|
|
|
|
|
|
|
|
if ((rtw_debug & RTW_DEBUG_IO_KICK) == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
for (pri = 0; pri < RTW_NTXPRI; pri++) {
|
2004-12-29 04:06:52 +03:00
|
|
|
tdb = &sc->sc_txdesc_blk[pri];
|
2004-12-25 09:58:37 +03:00
|
|
|
printf("%s: txpri %d ndesc %d nfree %d\n", __func__, pri,
|
2004-12-29 04:06:52 +03:00
|
|
|
tdb->tdb_ndesc, tdb->tdb_nfree);
|
|
|
|
for (desc = 0; desc < tdb->tdb_ndesc; desc++)
|
|
|
|
rtw_print_txdesc(sc, ".", NULL, tdb, desc);
|
2004-12-25 09:58:37 +03:00
|
|
|
}
|
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
rdb = &sc->sc_rxdesc_blk;
|
2004-12-29 03:21:37 +03:00
|
|
|
|
2004-12-25 09:58:37 +03:00
|
|
|
for (desc = 0; desc < RTW_RXQLEN; desc++) {
|
2004-12-29 04:06:52 +03:00
|
|
|
rd = &rdb->rdb_desc[desc];
|
If defined(RTW_DEBUG), provide a sysctl (hw.rtw.rxbufs_limit) for
limiting the number of rx buffers an rtw may allocate. Use this
sysctl to test the code that copes with buffer exhaustion.
Allocate at most RTW_RXQLEN rx buffers, stopping at the sysctl
limit. Record in sc_nrxdesc how many were allocated, and put the
end-of-ring indication on sc_rxdesc[sc_nrxdesc - 1]. In rtw_init,
if no rx buffers could be allocated, log a complaint, clear
IFF_RUNNING, and exit with an error.
Many changes to accomodate a short rx ring, mainly of the "add a
rx-ring length argument" variety. XXX I really should consolidate
all of the rx ring variables in one struct and pass that to the
rx-ring subroutines.
Bug fix: after calling MCLGET, use the (m->m_flags & M_EXT) idiom
to check for success, instead of m != NULL.
Bug fix: at the top of rtw_start, if IFF_RUNNING is not set, or
IFF_OACTIVE is, get out.
2004-12-29 01:21:15 +03:00
|
|
|
printf("%s: %sctl %08x rsvd0/rssi %08x buf/tsftl %08x "
|
2004-12-25 09:58:37 +03:00
|
|
|
"rsvd1/tsfth %08x\n", __func__,
|
2004-12-29 04:06:52 +03:00
|
|
|
(desc >= rdb->rdb_ndesc) ? "UNUSED " : "",
|
|
|
|
le32toh(rd->rd_ctl), le32toh(rd->rd_rssi),
|
|
|
|
le32toh(rd->rd_buf), le32toh(rd->rd_tsfth));
|
2004-12-25 09:58:37 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif /* RTW_DEBUG */
|
|
|
|
|
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
|
|
|
static void
|
|
|
|
rtw_hwring_setup(struct rtw_softc *sc)
|
|
|
|
{
|
2005-11-23 07:12:33 +03:00
|
|
|
int pri;
|
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_regs *regs = &sc->sc_regs;
|
2005-11-23 07:12:33 +03:00
|
|
|
struct rtw_txdesc_blk *tdb;
|
|
|
|
|
|
|
|
sc->sc_txdesc_blk[RTW_TXPRILO].tdb_basereg = RTW_TLPDA;
|
|
|
|
sc->sc_txdesc_blk[RTW_TXPRILO].tdb_base = RTW_RING_BASE(sc, hd_txlo);
|
|
|
|
sc->sc_txdesc_blk[RTW_TXPRIMD].tdb_basereg = RTW_TNPDA;
|
|
|
|
sc->sc_txdesc_blk[RTW_TXPRIMD].tdb_base = RTW_RING_BASE(sc, hd_txmd);
|
|
|
|
sc->sc_txdesc_blk[RTW_TXPRIHI].tdb_basereg = RTW_THPDA;
|
|
|
|
sc->sc_txdesc_blk[RTW_TXPRIHI].tdb_base = RTW_RING_BASE(sc, hd_txhi);
|
|
|
|
sc->sc_txdesc_blk[RTW_TXPRIBCN].tdb_basereg = RTW_TBDA;
|
|
|
|
sc->sc_txdesc_blk[RTW_TXPRIBCN].tdb_base = RTW_RING_BASE(sc, hd_bcn);
|
|
|
|
|
|
|
|
for (pri = 0; pri < RTW_NTXPRI; pri++) {
|
|
|
|
tdb = &sc->sc_txdesc_blk[pri];
|
|
|
|
RTW_WRITE(regs, tdb->tdb_basereg, tdb->tdb_base);
|
|
|
|
RTW_DPRINTF(RTW_DEBUG_XMIT_DESC,
|
|
|
|
("%s: reg[tdb->tdb_basereg] <- %" PRIxPTR "\n", __func__,
|
|
|
|
(uintptr_t)tdb->tdb_base));
|
|
|
|
}
|
|
|
|
|
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
|
|
|
RTW_WRITE(regs, RTW_RDSAR, RTW_RING_BASE(sc, hd_rx));
|
2005-11-23 07:12:33 +03:00
|
|
|
|
2004-12-25 09:58:37 +03:00
|
|
|
RTW_DPRINTF(RTW_DEBUG_RECV_DESC,
|
|
|
|
("%s: reg[RDSAR] <- %" PRIxPTR "\n", __func__,
|
|
|
|
(uintptr_t)RTW_RING_BASE(sc, hd_rx)));
|
2005-11-23 07:12:33 +03:00
|
|
|
|
|
|
|
RTW_SYNC(regs, RTW_TLPDA, RTW_RDSAR);
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
If defined(RTW_DEBUG), provide a sysctl (hw.rtw.rxbufs_limit) for
limiting the number of rx buffers an rtw may allocate. Use this
sysctl to test the code that copes with buffer exhaustion.
Allocate at most RTW_RXQLEN rx buffers, stopping at the sysctl
limit. Record in sc_nrxdesc how many were allocated, and put the
end-of-ring indication on sc_rxdesc[sc_nrxdesc - 1]. In rtw_init,
if no rx buffers could be allocated, log a complaint, clear
IFF_RUNNING, and exit with an error.
Many changes to accomodate a short rx ring, mainly of the "add a
rx-ring length argument" variety. XXX I really should consolidate
all of the rx ring variables in one struct and pass that to the
rx-ring subroutines.
Bug fix: after calling MCLGET, use the (m->m_flags & M_EXT) idiom
to check for success, instead of m != NULL.
Bug fix: at the top of rtw_start, if IFF_RUNNING is not set, or
IFF_OACTIVE is, get out.
2004-12-29 01:21:15 +03:00
|
|
|
static 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
|
|
|
rtw_swring_setup(struct rtw_softc *sc)
|
|
|
|
{
|
If defined(RTW_DEBUG), provide a sysctl (hw.rtw.rxbufs_limit) for
limiting the number of rx buffers an rtw may allocate. Use this
sysctl to test the code that copes with buffer exhaustion.
Allocate at most RTW_RXQLEN rx buffers, stopping at the sysctl
limit. Record in sc_nrxdesc how many were allocated, and put the
end-of-ring indication on sc_rxdesc[sc_nrxdesc - 1]. In rtw_init,
if no rx buffers could be allocated, log a complaint, clear
IFF_RUNNING, and exit with an error.
Many changes to accomodate a short rx ring, mainly of the "add a
rx-ring length argument" variety. XXX I really should consolidate
all of the rx ring variables in one struct and pass that to the
rx-ring subroutines.
Bug fix: after calling MCLGET, use the (m->m_flags & M_EXT) idiom
to check for success, instead of m != NULL.
Bug fix: at the top of rtw_start, if IFF_RUNNING is not set, or
IFF_OACTIVE is, get out.
2004-12-29 01:21:15 +03:00
|
|
|
int rc;
|
2004-12-29 04:06:52 +03:00
|
|
|
struct rtw_rxdesc_blk *rdb;
|
2004-12-29 03:21:37 +03:00
|
|
|
|
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
|
|
|
rtw_txdesc_blk_init_all(&sc->sc_txdesc_blk[0]);
|
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
rtw_txsoft_blk_init_all(&sc->sc_txsoft_blk[0]);
|
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-12-29 04:06:52 +03:00
|
|
|
rdb = &sc->sc_rxdesc_blk;
|
|
|
|
if ((rc = rtw_rxsoft_init_all(sc->sc_dmat, sc->sc_rxsoft, &rdb->rdb_ndesc,
|
2007-12-21 21:22:43 +03:00
|
|
|
sc->sc_dev)) != 0 && rdb->rdb_ndesc == 0) {
|
|
|
|
aprint_error_dev(sc->sc_dev, "could not allocate rx buffers\n");
|
If defined(RTW_DEBUG), provide a sysctl (hw.rtw.rxbufs_limit) for
limiting the number of rx buffers an rtw may allocate. Use this
sysctl to test the code that copes with buffer exhaustion.
Allocate at most RTW_RXQLEN rx buffers, stopping at the sysctl
limit. Record in sc_nrxdesc how many were allocated, and put the
end-of-ring indication on sc_rxdesc[sc_nrxdesc - 1]. In rtw_init,
if no rx buffers could be allocated, log a complaint, clear
IFF_RUNNING, and exit with an error.
Many changes to accomodate a short rx ring, mainly of the "add a
rx-ring length argument" variety. XXX I really should consolidate
all of the rx ring variables in one struct and pass that to the
rx-ring subroutines.
Bug fix: after calling MCLGET, use the (m->m_flags & M_EXT) idiom
to check for success, instead of m != NULL.
Bug fix: at the top of rtw_start, if IFF_RUNNING is not set, or
IFF_OACTIVE is, get out.
2004-12-29 01:21:15 +03:00
|
|
|
return rc;
|
|
|
|
}
|
2005-02-27 03:26:58 +03:00
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
rdb = &sc->sc_rxdesc_blk;
|
|
|
|
rtw_rxdescs_sync(rdb, 0, rdb->rdb_ndesc,
|
If defined(RTW_DEBUG), provide a sysctl (hw.rtw.rxbufs_limit) for
limiting the number of rx buffers an rtw may allocate. Use this
sysctl to test the code that copes with buffer exhaustion.
Allocate at most RTW_RXQLEN rx buffers, stopping at the sysctl
limit. Record in sc_nrxdesc how many were allocated, and put the
end-of-ring indication on sc_rxdesc[sc_nrxdesc - 1]. In rtw_init,
if no rx buffers could be allocated, log a complaint, clear
IFF_RUNNING, and exit with an error.
Many changes to accomodate a short rx ring, mainly of the "add a
rx-ring length argument" variety. XXX I really should consolidate
all of the rx ring variables in one struct and pass that to the
rx-ring subroutines.
Bug fix: after calling MCLGET, use the (m->m_flags & M_EXT) idiom
to check for success, instead of m != NULL.
Bug fix: at the top of rtw_start, if IFF_RUNNING is not set, or
IFF_OACTIVE is, get out.
2004-12-29 01:21:15 +03:00
|
|
|
BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
|
2004-12-29 04:06:52 +03:00
|
|
|
rtw_rxdesc_init_all(rdb, sc->sc_rxsoft, 1);
|
2005-11-23 07:12:33 +03:00
|
|
|
rdb->rdb_next = 0;
|
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-12-29 03:21:37 +03:00
|
|
|
rtw_txdescs_sync_all(&sc->sc_txdesc_blk[0]);
|
If defined(RTW_DEBUG), provide a sysctl (hw.rtw.rxbufs_limit) for
limiting the number of rx buffers an rtw may allocate. Use this
sysctl to test the code that copes with buffer exhaustion.
Allocate at most RTW_RXQLEN rx buffers, stopping at the sysctl
limit. Record in sc_nrxdesc how many were allocated, and put the
end-of-ring indication on sc_rxdesc[sc_nrxdesc - 1]. In rtw_init,
if no rx buffers could be allocated, log a complaint, clear
IFF_RUNNING, and exit with an error.
Many changes to accomodate a short rx ring, mainly of the "add a
rx-ring length argument" variety. XXX I really should consolidate
all of the rx ring variables in one struct and pass that to the
rx-ring subroutines.
Bug fix: after calling MCLGET, use the (m->m_flags & M_EXT) idiom
to check for success, instead of m != NULL.
Bug fix: at the top of rtw_start, if IFF_RUNNING is not set, or
IFF_OACTIVE is, get out.
2004-12-29 01:21:15 +03:00
|
|
|
return 0;
|
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
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2005-11-23 07:12:33 +03:00
|
|
|
rtw_txdesc_blk_init(struct rtw_txdesc_blk *tdb)
|
2004-12-25 09:58:37 +03:00
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
(void)memset(tdb->tdb_desc, 0,
|
|
|
|
sizeof(tdb->tdb_desc[0]) * tdb->tdb_ndesc);
|
|
|
|
for (i = 0; i < tdb->tdb_ndesc; i++)
|
|
|
|
tdb->tdb_desc[i].td_next = htole32(RTW_NEXT_DESC(tdb, i));
|
2005-11-23 07:12:33 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static u_int
|
|
|
|
rtw_txring_next(struct rtw_regs *regs, struct rtw_txdesc_blk *tdb)
|
|
|
|
{
|
|
|
|
return (le32toh(RTW_READ(regs, tdb->tdb_basereg)) - tdb->tdb_base) /
|
|
|
|
sizeof(struct rtw_txdesc);
|
2004-12-25 09:58:37 +03:00
|
|
|
}
|
|
|
|
|
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
|
|
|
#ifdef RTW_DIAG
|
2004-12-25 09:58:37 +03:00
|
|
|
static void
|
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
|
|
|
rtw_txring_fixup(struct rtw_softc *sc, const char *fn, int ln)
|
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-12-19 11:19:25 +03:00
|
|
|
int pri;
|
2005-11-23 07:12:33 +03:00
|
|
|
u_int next;
|
2004-12-29 04:06:52 +03:00
|
|
|
struct rtw_txdesc_blk *tdb;
|
2005-11-23 07:12:33 +03:00
|
|
|
struct rtw_regs *regs = &sc->sc_regs;
|
2004-12-25 09:58:37 +03:00
|
|
|
|
|
|
|
for (pri = 0; pri < RTW_NTXPRI; pri++) {
|
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
|
|
|
int i;
|
2004-12-29 04:06:52 +03:00
|
|
|
tdb = &sc->sc_txdesc_blk[pri];
|
2005-11-23 07:12:33 +03:00
|
|
|
next = rtw_txring_next(regs, tdb);
|
|
|
|
if (tdb->tdb_next == next)
|
|
|
|
continue;
|
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
|
|
|
for (i = 0; next != tdb->tdb_next;
|
|
|
|
next = RTW_NEXT_IDX(tdb, next), i++) {
|
|
|
|
if ((tdb->tdb_desc[next].td_stat & htole32(RTW_TXSTAT_OWN)) == 0)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
printf("%s:%d: tx-ring %d expected next %u, read %u+%d -> %s\n", fn,
|
|
|
|
ln, pri, tdb->tdb_next, next, i, tdb->tdb_next == next ? "okay" : "BAD");
|
|
|
|
if (tdb->tdb_next == next)
|
|
|
|
continue;
|
2006-02-05 02:22:27 +03:00
|
|
|
tdb->tdb_next = MIN(next, tdb->tdb_ndesc - 1);
|
2004-12-25 09:58:37 +03:00
|
|
|
}
|
|
|
|
}
|
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
|
|
|
#endif
|
2005-11-23 07:12:33 +03:00
|
|
|
|
|
|
|
static void
|
|
|
|
rtw_txdescs_reset(struct rtw_softc *sc)
|
|
|
|
{
|
|
|
|
int pri;
|
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_txsoft_blk *tsb;
|
|
|
|
struct rtw_txdesc_blk *tdb;
|
2005-11-23 07:12:33 +03:00
|
|
|
|
|
|
|
for (pri = 0; pri < RTW_NTXPRI; pri++) {
|
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
|
|
|
tsb = &sc->sc_txsoft_blk[pri];
|
|
|
|
tdb = &sc->sc_txdesc_blk[pri];
|
|
|
|
rtw_collect_txring(sc, tsb, tdb, 1);
|
|
|
|
#ifdef RTW_DIAG
|
|
|
|
if (!SIMPLEQ_EMPTY(&tsb->tsb_dirtyq))
|
|
|
|
printf("%s: packets left in ring %d\n", __func__, pri);
|
|
|
|
#endif
|
2005-11-23 07:12:33 +03:00
|
|
|
}
|
2004-12-25 09:58:37 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
rtw_intr_ioerror(struct rtw_softc *sc, uint16_t isr)
|
|
|
|
{
|
2007-12-21 21:22:43 +03:00
|
|
|
aprint_error_dev(sc->sc_dev, "tx fifo underflow\n");
|
2004-12-19 11:19:25 +03:00
|
|
|
|
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
|
|
|
RTW_DPRINTF(RTW_DEBUG_BUGS, ("%s: cleaning up xmit, isr %" PRIx16
|
2007-12-21 21:22:43 +03:00
|
|
|
"\n", device_xname(sc->sc_dev), isr));
|
2004-12-23 08:54:54 +03:00
|
|
|
|
2004-12-27 01:59:41 +03:00
|
|
|
#ifdef RTW_DEBUG
|
2004-12-25 09:58:37 +03:00
|
|
|
rtw_dump_rings(sc);
|
2004-12-27 01:59:41 +03:00
|
|
|
#endif /* RTW_DEBUG */
|
2004-12-23 08:54:54 +03:00
|
|
|
|
2005-11-23 07:12:33 +03:00
|
|
|
/* Collect tx'd packets. XXX let's hope this stops the transmit
|
|
|
|
* timeouts.
|
|
|
|
*/
|
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
|
|
|
rtw_txdescs_reset(sc);
|
2004-12-25 09:58:37 +03:00
|
|
|
|
2004-12-27 01:59:41 +03:00
|
|
|
#ifdef RTW_DEBUG
|
2004-12-25 09:58:37 +03:00
|
|
|
rtw_dump_rings(sc);
|
2004-12-27 01:59:41 +03:00
|
|
|
#endif /* RTW_DEBUG */
|
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
|
|
|
}
|
|
|
|
|
2005-12-24 23:27:29 +03:00
|
|
|
static inline void
|
2004-09-26 06:29:15 +04:00
|
|
|
rtw_suspend_ticks(struct rtw_softc *sc)
|
|
|
|
{
|
2004-12-25 09:58:37 +03:00
|
|
|
RTW_DPRINTF(RTW_DEBUG_TIMEOUT,
|
2007-12-21 21:22:43 +03:00
|
|
|
("%s: suspending ticks\n", device_xname(sc->sc_dev)));
|
2004-09-26 06:29:15 +04:00
|
|
|
sc->sc_do_tick = 0;
|
|
|
|
}
|
|
|
|
|
2005-12-24 23:27:29 +03:00
|
|
|
static inline void
|
2004-09-26 06:29:15 +04:00
|
|
|
rtw_resume_ticks(struct rtw_softc *sc)
|
|
|
|
{
|
2010-03-16 02:21:08 +03:00
|
|
|
uint32_t tsftrl0, tsftrl1, next_tint;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
tsftrl0 = RTW_READ(&sc->sc_regs, RTW_TSFTRL);
|
|
|
|
|
|
|
|
tsftrl1 = RTW_READ(&sc->sc_regs, RTW_TSFTRL);
|
2010-03-16 02:21:08 +03:00
|
|
|
next_tint = tsftrl1 + 1000000;
|
|
|
|
RTW_WRITE(&sc->sc_regs, RTW_TINT, next_tint);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
sc->sc_do_tick = 1;
|
|
|
|
|
2013-10-18 01:24:24 +04:00
|
|
|
#ifdef RTW_DEBUG
|
2004-12-25 09:58:37 +03:00
|
|
|
RTW_DPRINTF(RTW_DEBUG_TIMEOUT,
|
|
|
|
("%s: resume ticks delta %#08x now %#08x next %#08x\n",
|
2010-03-16 02:21:08 +03:00
|
|
|
device_xname(sc->sc_dev), tsftrl1 - tsftrl0, tsftrl1, next_tint));
|
2013-10-18 01:24:24 +04:00
|
|
|
#else
|
|
|
|
__USE(tsftrl0);
|
|
|
|
#endif
|
2004-09-26 06:29:15 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
rtw_intr_timeout(struct rtw_softc *sc)
|
|
|
|
{
|
2007-12-21 21:22:43 +03:00
|
|
|
RTW_DPRINTF(RTW_DEBUG_TIMEOUT, ("%s: timeout\n", device_xname(sc->sc_dev)));
|
2004-09-26 06:29:15 +04:00
|
|
|
if (sc->sc_do_tick)
|
|
|
|
rtw_resume_ticks(sc);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
rtw_intr(void *arg)
|
|
|
|
{
|
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
|
|
|
int i;
|
2004-09-26 06:29:15 +04:00
|
|
|
struct rtw_softc *sc = arg;
|
|
|
|
struct rtw_regs *regs = &sc->sc_regs;
|
2005-01-02 07:23:03 +03:00
|
|
|
uint16_t isr;
|
2005-06-22 10:14:51 +04:00
|
|
|
struct ifnet *ifp = &sc->sc_if;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
/*
|
|
|
|
* If the interface isn't running, the interrupt couldn't
|
|
|
|
* possibly have come from us.
|
|
|
|
*/
|
Use device_t and its accessors throughout. Use aprint_*_dev().
Improve PMF-ability.
Add a 'flags' argument to suspend/resume handlers and
callers such as pmf_system_suspend().
Define a flag, PMF_F_SELF, which indicates to PMF that a
device is suspending/resuming itself. Add helper routines,
pmf_device_suspend_self(dev) and pmf_device_resume_self(dev),
that call pmf_device_suspend(dev, PMF_F_SELF) and
pmf_device_resume(dev, PMF_F_SELF), respectively. Use
PMF_F_SELF to suspend/resume self in ath(4), audio(4),
rtw(4), and sip(4).
In ath(4) and in rtw(4), replace the icky sc_enable/sc_disable
callbacks, provided by the bus front-end, with
self-suspension/resumption. Also, clean up the bus
front-ends. Make sure that the interrupt handler is
disestablished during suspension. Get rid of driver-private
flags (e.g., RTW_F_ENABLED, ath_softc->sc_invalid); use
device_is_active()/device_has_power() calls, instead.
In the network-class suspend handler, call if_stop(, 0)
instead of if_stop(, 1), because the latter is superfluous
(bus- and driver-suspension hooks will 'disable' the NIC),
and it may cause recursion.
In the network-class resume handler, prevent infinite
recursion through if_init() by getting out early if we are
self-suspending (PMF_F_SELF).
rtw(4) improvements:
Destroy rtw(4) callouts when we detach it. Make rtw at
pci detachable. Print some more information with the "rx
frame too long" warning.
Remove activate() methods:
Get rid of rtw_activate() and ath_activate(). The device
activate() methods are not good for much these days.
Make ath at cardbus resume with crypto functions intact:
Introduce a boolean device property, "pmf-powerdown". If
pmf-powerdown is present and false, it indicates that a
bus back-end should not remove power from a device.
Honor this property in cardbus_child_suspend().
Set this property to 'false' in ath_attach(), since removing
power from an ath at cardbus seems to lobotomize the WPA
crypto engine. XXX Should the pmf-powerdown property
propagate toward the root of the device tree?
Miscellaneous ath(4) changes:
Warn if ath(4) tries to write crypto keys to suspended
hardware.
Reduce differences between FreeBSD and NetBSD in ath(4)
multicast filter setup.
Make ath_printrxbuf() print an rx descriptor's status &
key index, to help debug crypto errors.
Shorten a staircase in ath_ioctl(). Don't check for
ieee80211_ioctl() return code ERESTART, it never happens.
2008-03-12 21:02:21 +03:00
|
|
|
if ((ifp->if_flags & IFF_RUNNING) == 0 ||
|
In pmf(9), improve the implementation of device self-suspension
and make suspension by self, by drvctl(8), and by ACPI system sleep
play nice together. Start solidifying some temporary API changes.
1. Extract a new header file, <sys/device_if.h>, from <sys/device.h> and
#include it from <sys/pmf.h> instead of <sys/device.h> to break the
circular dependency between <sys/device.h> and <sys/pmf.h>.
2. Introduce pmf_qual_t, an aggregate of qualifications on a PMF
suspend/resume call. Start to replace instances of PMF_FN_PROTO,
PMF_FN_ARGS, et cetera, with a pmf_qual_t.
3. Introduce the notion of a "suspensor," an entity that holds a
device in suspension. More than one suspensor may hold a device
at once. A device stays suspended as long as at least one
suspensor holds it. A device resumes when the last suspensor
releases it.
Currently, the kernel defines three suspensors,
3a the system-suspensor: for system suspension, initiated
by 'sysctl -w machdep.sleep_state=3', by lid closure, by
power-button press, et cetera,
3b the drvctl-suspensor: for device suspension by /dev/drvctl
ioctl, e.g., drvctl -S sip0.
3c the system self-suspensor: for device drivers that suspend
themselves and their children. Several drivers for network
interfaces put the network device to sleep while it is not
administratively up, that is, after the kernel calls if_stop(,
1). The self-suspensor should not be used directly. See
the description of suspensor delegates, below.
A suspensor can have one or more "delegates". A suspensor can
release devices that its delegates hold suspended. Right now,
only the system self-suspensor has delegates. For each device
that a self-suspending driver attaches, it creates the device's
self-suspensor, a delegate of the system self-suspensor.
Suspensors stop a system-wide suspend/resume cycle from waking
devices that the operator put to sleep with drvctl before the cycle.
They also help self-suspension to work more simply, safely, and in
accord with expectations.
4. Add the notion of device activation level, devact_level_t,
and a routine for checking the current activation level,
device_activation(). Current activation levels are DEVACT_LEVEL_BUS,
DEVACT_LEVEL_DRIVER, and DEVACT_LEVEL_CLASS, which respectively
indicate that the device's bus is active, that the bus and device are
active, and that the bus, device, and the functions of the device's
class (network, audio) are active.
Suspend/resume calls can be qualified with a devact_level_t.
The power-management framework treats a devact_level_t that
qualifies a device suspension as the device's current activation
level; it only runs hooks to reduce the activation level from
the presumed current level to the fully suspended state. The
framework treats a devact_level_t qualifying device resumption
as the target activation level; it only runs hooks to raise the
activation level to the target.
5. Use pmf_qual_t, devact_level_t, and self-suspensors in several
drivers.
6. Temporarily add an unused power-management workqueue that I will
remove or replace, soon.
2009-09-16 20:34:49 +04:00
|
|
|
!device_activation(sc->sc_dev, DEVACT_LEVEL_DRIVER)) {
|
2007-12-21 21:22:43 +03:00
|
|
|
RTW_DPRINTF(RTW_DEBUG_INTR, ("%s: stray interrupt\n",
|
|
|
|
device_xname(sc->sc_dev)));
|
2004-09-26 06:29:15 +04:00
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
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
|
|
|
for (i = 0; i < 10; i++) {
|
2004-09-26 06:29:15 +04:00
|
|
|
isr = RTW_READ16(regs, RTW_ISR);
|
|
|
|
|
|
|
|
RTW_WRITE16(regs, RTW_ISR, isr);
|
2004-12-20 04:13:45 +03:00
|
|
|
RTW_WBR(regs, RTW_ISR, RTW_ISR);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
if (sc->sc_intr_ack != NULL)
|
|
|
|
(*sc->sc_intr_ack)(regs);
|
|
|
|
|
|
|
|
if (isr == 0)
|
|
|
|
break;
|
|
|
|
|
|
|
|
#ifdef RTW_DEBUG
|
|
|
|
#define PRINTINTR(flag) do { \
|
|
|
|
if ((isr & flag) != 0) { \
|
|
|
|
printf("%s" #flag, delim); \
|
|
|
|
delim = ","; \
|
|
|
|
} \
|
|
|
|
} while (0)
|
|
|
|
|
2004-12-25 09:58:37 +03:00
|
|
|
if ((rtw_debug & RTW_DEBUG_INTR) != 0 && isr != 0) {
|
2004-09-26 06:29:15 +04:00
|
|
|
const char *delim = "<";
|
|
|
|
|
2007-12-21 21:22:43 +03:00
|
|
|
printf("%s: reg[ISR] = %x", device_xname(sc->sc_dev),
|
|
|
|
isr);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
PRINTINTR(RTW_INTR_TXFOVW);
|
|
|
|
PRINTINTR(RTW_INTR_TIMEOUT);
|
|
|
|
PRINTINTR(RTW_INTR_BCNINT);
|
|
|
|
PRINTINTR(RTW_INTR_ATIMINT);
|
|
|
|
PRINTINTR(RTW_INTR_TBDER);
|
|
|
|
PRINTINTR(RTW_INTR_TBDOK);
|
|
|
|
PRINTINTR(RTW_INTR_THPDER);
|
|
|
|
PRINTINTR(RTW_INTR_THPDOK);
|
|
|
|
PRINTINTR(RTW_INTR_TNPDER);
|
|
|
|
PRINTINTR(RTW_INTR_TNPDOK);
|
|
|
|
PRINTINTR(RTW_INTR_RXFOVW);
|
|
|
|
PRINTINTR(RTW_INTR_RDU);
|
|
|
|
PRINTINTR(RTW_INTR_TLPDER);
|
|
|
|
PRINTINTR(RTW_INTR_TLPDOK);
|
|
|
|
PRINTINTR(RTW_INTR_RER);
|
|
|
|
PRINTINTR(RTW_INTR_ROK);
|
|
|
|
|
|
|
|
printf(">\n");
|
|
|
|
}
|
|
|
|
#undef PRINTINTR
|
|
|
|
#endif /* RTW_DEBUG */
|
|
|
|
|
|
|
|
if ((isr & RTW_INTR_RX) != 0)
|
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
|
|
|
rtw_intr_rx(sc, isr);
|
2004-09-26 06:29:15 +04:00
|
|
|
if ((isr & RTW_INTR_TX) != 0)
|
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
|
|
|
rtw_intr_tx(sc, isr);
|
2004-09-26 06:29:15 +04:00
|
|
|
if ((isr & RTW_INTR_BEACON) != 0)
|
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
|
|
|
rtw_intr_beacon(sc, isr);
|
2004-09-26 06:29:15 +04:00
|
|
|
if ((isr & RTW_INTR_ATIMINT) != 0)
|
|
|
|
rtw_intr_atim(sc);
|
|
|
|
if ((isr & RTW_INTR_IOERROR) != 0)
|
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
|
|
|
rtw_intr_ioerror(sc, isr);
|
2004-09-26 06:29:15 +04:00
|
|
|
if ((isr & RTW_INTR_TIMEOUT) != 0)
|
|
|
|
rtw_intr_timeout(sc);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2004-12-25 09:58:37 +03:00
|
|
|
/* Must be called at splnet. */
|
2004-09-26 06:29:15 +04:00
|
|
|
static void
|
|
|
|
rtw_stop(struct ifnet *ifp, int disable)
|
|
|
|
{
|
2004-12-25 09:58:37 +03:00
|
|
|
int pri;
|
2004-09-26 06:29:15 +04:00
|
|
|
struct rtw_softc *sc = (struct rtw_softc *)ifp->if_softc;
|
|
|
|
struct ieee80211com *ic = &sc->sc_ic;
|
|
|
|
struct rtw_regs *regs = &sc->sc_regs;
|
|
|
|
|
|
|
|
rtw_suspend_ticks(sc);
|
|
|
|
|
|
|
|
ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
|
|
|
|
|
Use device_t and its accessors throughout. Use aprint_*_dev().
Improve PMF-ability.
Add a 'flags' argument to suspend/resume handlers and
callers such as pmf_system_suspend().
Define a flag, PMF_F_SELF, which indicates to PMF that a
device is suspending/resuming itself. Add helper routines,
pmf_device_suspend_self(dev) and pmf_device_resume_self(dev),
that call pmf_device_suspend(dev, PMF_F_SELF) and
pmf_device_resume(dev, PMF_F_SELF), respectively. Use
PMF_F_SELF to suspend/resume self in ath(4), audio(4),
rtw(4), and sip(4).
In ath(4) and in rtw(4), replace the icky sc_enable/sc_disable
callbacks, provided by the bus front-end, with
self-suspension/resumption. Also, clean up the bus
front-ends. Make sure that the interrupt handler is
disestablished during suspension. Get rid of driver-private
flags (e.g., RTW_F_ENABLED, ath_softc->sc_invalid); use
device_is_active()/device_has_power() calls, instead.
In the network-class suspend handler, call if_stop(, 0)
instead of if_stop(, 1), because the latter is superfluous
(bus- and driver-suspension hooks will 'disable' the NIC),
and it may cause recursion.
In the network-class resume handler, prevent infinite
recursion through if_init() by getting out early if we are
self-suspending (PMF_F_SELF).
rtw(4) improvements:
Destroy rtw(4) callouts when we detach it. Make rtw at
pci detachable. Print some more information with the "rx
frame too long" warning.
Remove activate() methods:
Get rid of rtw_activate() and ath_activate(). The device
activate() methods are not good for much these days.
Make ath at cardbus resume with crypto functions intact:
Introduce a boolean device property, "pmf-powerdown". If
pmf-powerdown is present and false, it indicates that a
bus back-end should not remove power from a device.
Honor this property in cardbus_child_suspend().
Set this property to 'false' in ath_attach(), since removing
power from an ath at cardbus seems to lobotomize the WPA
crypto engine. XXX Should the pmf-powerdown property
propagate toward the root of the device tree?
Miscellaneous ath(4) changes:
Warn if ath(4) tries to write crypto keys to suspended
hardware.
Reduce differences between FreeBSD and NetBSD in ath(4)
multicast filter setup.
Make ath_printrxbuf() print an rx descriptor's status &
key index, to help debug crypto errors.
Shorten a staircase in ath_ioctl(). Don't check for
ieee80211_ioctl() return code ERESTART, it never happens.
2008-03-12 21:02:21 +03:00
|
|
|
if (device_has_power(sc->sc_dev)) {
|
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
|
|
|
/* Disable interrupts. */
|
|
|
|
RTW_WRITE16(regs, RTW_IMR, 0);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2004-12-20 04:13:45 +03:00
|
|
|
RTW_WBW(regs, RTW_TPPOLL, RTW_IMR);
|
|
|
|
|
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
|
|
|
/* Stop the transmit and receive processes. First stop DMA,
|
|
|
|
* then disable receiver and transmitter.
|
|
|
|
*/
|
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
|
|
|
RTW_WRITE8(regs, RTW_TPPOLL, RTW_TPPOLL_SALL);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2004-12-20 04:13:45 +03:00
|
|
|
RTW_SYNC(regs, RTW_TPPOLL, RTW_IMR);
|
|
|
|
|
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
|
|
|
rtw_io_enable(sc, RTW_CR_RE | RTW_CR_TE, 0);
|
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
|
|
|
|
2004-12-19 11:19:25 +03:00
|
|
|
for (pri = 0; pri < RTW_NTXPRI; pri++) {
|
2004-12-29 04:06:52 +03:00
|
|
|
rtw_txsofts_release(sc->sc_dmat, &sc->sc_ic,
|
|
|
|
&sc->sc_txsoft_blk[pri]);
|
2004-12-19 11:19:25 +03:00
|
|
|
}
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
rtw_rxbufs_release(sc->sc_dmat, &sc->sc_rxsoft[0]);
|
If defined(RTW_DEBUG), provide a sysctl (hw.rtw.rxbufs_limit) for
limiting the number of rx buffers an rtw may allocate. Use this
sysctl to test the code that copes with buffer exhaustion.
Allocate at most RTW_RXQLEN rx buffers, stopping at the sysctl
limit. Record in sc_nrxdesc how many were allocated, and put the
end-of-ring indication on sc_rxdesc[sc_nrxdesc - 1]. In rtw_init,
if no rx buffers could be allocated, log a complaint, clear
IFF_RUNNING, and exit with an error.
Many changes to accomodate a short rx ring, mainly of the "add a
rx-ring length argument" variety. XXX I really should consolidate
all of the rx ring variables in one struct and pass that to the
rx-ring subroutines.
Bug fix: after calling MCLGET, use the (m->m_flags & M_EXT) idiom
to check for success, instead of m != NULL.
Bug fix: at the top of rtw_start, if IFF_RUNNING is not set, or
IFF_OACTIVE is, get out.
2004-12-29 01:21:15 +03:00
|
|
|
|
2004-09-26 06:29:15 +04:00
|
|
|
/* Mark the interface as not running. Cancel the watchdog timer. */
|
2004-12-25 09:58:37 +03:00
|
|
|
ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE);
|
2004-09-26 06:29:15 +04:00
|
|
|
ifp->if_timer = 0;
|
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
|
|
|
|
Use device_t and its accessors throughout. Use aprint_*_dev().
Improve PMF-ability.
Add a 'flags' argument to suspend/resume handlers and
callers such as pmf_system_suspend().
Define a flag, PMF_F_SELF, which indicates to PMF that a
device is suspending/resuming itself. Add helper routines,
pmf_device_suspend_self(dev) and pmf_device_resume_self(dev),
that call pmf_device_suspend(dev, PMF_F_SELF) and
pmf_device_resume(dev, PMF_F_SELF), respectively. Use
PMF_F_SELF to suspend/resume self in ath(4), audio(4),
rtw(4), and sip(4).
In ath(4) and in rtw(4), replace the icky sc_enable/sc_disable
callbacks, provided by the bus front-end, with
self-suspension/resumption. Also, clean up the bus
front-ends. Make sure that the interrupt handler is
disestablished during suspension. Get rid of driver-private
flags (e.g., RTW_F_ENABLED, ath_softc->sc_invalid); use
device_is_active()/device_has_power() calls, instead.
In the network-class suspend handler, call if_stop(, 0)
instead of if_stop(, 1), because the latter is superfluous
(bus- and driver-suspension hooks will 'disable' the NIC),
and it may cause recursion.
In the network-class resume handler, prevent infinite
recursion through if_init() by getting out early if we are
self-suspending (PMF_F_SELF).
rtw(4) improvements:
Destroy rtw(4) callouts when we detach it. Make rtw at
pci detachable. Print some more information with the "rx
frame too long" warning.
Remove activate() methods:
Get rid of rtw_activate() and ath_activate(). The device
activate() methods are not good for much these days.
Make ath at cardbus resume with crypto functions intact:
Introduce a boolean device property, "pmf-powerdown". If
pmf-powerdown is present and false, it indicates that a
bus back-end should not remove power from a device.
Honor this property in cardbus_child_suspend().
Set this property to 'false' in ath_attach(), since removing
power from an ath at cardbus seems to lobotomize the WPA
crypto engine. XXX Should the pmf-powerdown property
propagate toward the root of the device tree?
Miscellaneous ath(4) changes:
Warn if ath(4) tries to write crypto keys to suspended
hardware.
Reduce differences between FreeBSD and NetBSD in ath(4)
multicast filter setup.
Make ath_printrxbuf() print an rx descriptor's status &
key index, to help debug crypto errors.
Shorten a staircase in ath_ioctl(). Don't check for
ieee80211_ioctl() return code ERESTART, it never happens.
2008-03-12 21:02:21 +03:00
|
|
|
if (disable)
|
In pmf(9), improve the implementation of device self-suspension
and make suspension by self, by drvctl(8), and by ACPI system sleep
play nice together. Start solidifying some temporary API changes.
1. Extract a new header file, <sys/device_if.h>, from <sys/device.h> and
#include it from <sys/pmf.h> instead of <sys/device.h> to break the
circular dependency between <sys/device.h> and <sys/pmf.h>.
2. Introduce pmf_qual_t, an aggregate of qualifications on a PMF
suspend/resume call. Start to replace instances of PMF_FN_PROTO,
PMF_FN_ARGS, et cetera, with a pmf_qual_t.
3. Introduce the notion of a "suspensor," an entity that holds a
device in suspension. More than one suspensor may hold a device
at once. A device stays suspended as long as at least one
suspensor holds it. A device resumes when the last suspensor
releases it.
Currently, the kernel defines three suspensors,
3a the system-suspensor: for system suspension, initiated
by 'sysctl -w machdep.sleep_state=3', by lid closure, by
power-button press, et cetera,
3b the drvctl-suspensor: for device suspension by /dev/drvctl
ioctl, e.g., drvctl -S sip0.
3c the system self-suspensor: for device drivers that suspend
themselves and their children. Several drivers for network
interfaces put the network device to sleep while it is not
administratively up, that is, after the kernel calls if_stop(,
1). The self-suspensor should not be used directly. See
the description of suspensor delegates, below.
A suspensor can have one or more "delegates". A suspensor can
release devices that its delegates hold suspended. Right now,
only the system self-suspensor has delegates. For each device
that a self-suspending driver attaches, it creates the device's
self-suspensor, a delegate of the system self-suspensor.
Suspensors stop a system-wide suspend/resume cycle from waking
devices that the operator put to sleep with drvctl before the cycle.
They also help self-suspension to work more simply, safely, and in
accord with expectations.
4. Add the notion of device activation level, devact_level_t,
and a routine for checking the current activation level,
device_activation(). Current activation levels are DEVACT_LEVEL_BUS,
DEVACT_LEVEL_DRIVER, and DEVACT_LEVEL_CLASS, which respectively
indicate that the device's bus is active, that the bus and device are
active, and that the bus, device, and the functions of the device's
class (network, audio) are active.
Suspend/resume calls can be qualified with a devact_level_t.
The power-management framework treats a devact_level_t that
qualifies a device suspension as the device's current activation
level; it only runs hooks to reduce the activation level from
the presumed current level to the fully suspended state. The
framework treats a devact_level_t qualifying device resumption
as the target activation level; it only runs hooks to raise the
activation level to the target.
5. Use pmf_qual_t, devact_level_t, and self-suspensors in several
drivers.
6. Temporarily add an unused power-management workqueue that I will
remove or replace, soon.
2009-09-16 20:34:49 +04:00
|
|
|
pmf_device_suspend(sc->sc_dev, &sc->sc_qual);
|
Use device_t and its accessors throughout. Use aprint_*_dev().
Improve PMF-ability.
Add a 'flags' argument to suspend/resume handlers and
callers such as pmf_system_suspend().
Define a flag, PMF_F_SELF, which indicates to PMF that a
device is suspending/resuming itself. Add helper routines,
pmf_device_suspend_self(dev) and pmf_device_resume_self(dev),
that call pmf_device_suspend(dev, PMF_F_SELF) and
pmf_device_resume(dev, PMF_F_SELF), respectively. Use
PMF_F_SELF to suspend/resume self in ath(4), audio(4),
rtw(4), and sip(4).
In ath(4) and in rtw(4), replace the icky sc_enable/sc_disable
callbacks, provided by the bus front-end, with
self-suspension/resumption. Also, clean up the bus
front-ends. Make sure that the interrupt handler is
disestablished during suspension. Get rid of driver-private
flags (e.g., RTW_F_ENABLED, ath_softc->sc_invalid); use
device_is_active()/device_has_power() calls, instead.
In the network-class suspend handler, call if_stop(, 0)
instead of if_stop(, 1), because the latter is superfluous
(bus- and driver-suspension hooks will 'disable' the NIC),
and it may cause recursion.
In the network-class resume handler, prevent infinite
recursion through if_init() by getting out early if we are
self-suspending (PMF_F_SELF).
rtw(4) improvements:
Destroy rtw(4) callouts when we detach it. Make rtw at
pci detachable. Print some more information with the "rx
frame too long" warning.
Remove activate() methods:
Get rid of rtw_activate() and ath_activate(). The device
activate() methods are not good for much these days.
Make ath at cardbus resume with crypto functions intact:
Introduce a boolean device property, "pmf-powerdown". If
pmf-powerdown is present and false, it indicates that a
bus back-end should not remove power from a device.
Honor this property in cardbus_child_suspend().
Set this property to 'false' in ath_attach(), since removing
power from an ath at cardbus seems to lobotomize the WPA
crypto engine. XXX Should the pmf-powerdown property
propagate toward the root of the device tree?
Miscellaneous ath(4) changes:
Warn if ath(4) tries to write crypto keys to suspended
hardware.
Reduce differences between FreeBSD and NetBSD in ath(4)
multicast filter setup.
Make ath_printrxbuf() print an rx descriptor's status &
key index, to help debug crypto errors.
Shorten a staircase in ath_ioctl(). Don't check for
ieee80211_ioctl() return code ERESTART, it never happens.
2008-03-12 21:02:21 +03:00
|
|
|
|
2004-09-26 06:29:15 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *
|
|
|
|
rtw_pwrstate_string(enum rtw_pwrstate power)
|
|
|
|
{
|
|
|
|
switch (power) {
|
|
|
|
case RTW_ON:
|
|
|
|
return "on";
|
|
|
|
case RTW_SLEEP:
|
|
|
|
return "sleep";
|
|
|
|
case RTW_OFF:
|
|
|
|
return "off";
|
|
|
|
default:
|
|
|
|
return "unknown";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-12-21 02:05:41 +03:00
|
|
|
/* XXX For Maxim, I am using the RFMD settings gleaned from the
|
|
|
|
* reference driver, plus a magic Maxim "ON" value that comes from
|
|
|
|
* the Realtek document "Windows PG for Rtl8180."
|
2004-09-26 06:29:15 +04:00
|
|
|
*/
|
|
|
|
static void
|
|
|
|
rtw_maxim_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power,
|
2006-11-16 04:32:37 +03:00
|
|
|
int before_rf, int digphy)
|
2004-09-26 06:29:15 +04:00
|
|
|
{
|
2005-01-02 07:23:03 +03:00
|
|
|
uint32_t anaparm;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2004-12-21 02:05:41 +03:00
|
|
|
anaparm = RTW_READ(regs, RTW_ANAPARM);
|
|
|
|
anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF);
|
|
|
|
|
|
|
|
switch (power) {
|
|
|
|
case RTW_OFF:
|
|
|
|
if (before_rf)
|
|
|
|
return;
|
|
|
|
anaparm |= RTW_ANAPARM_RFPOW_MAXIM_OFF;
|
|
|
|
anaparm |= RTW_ANAPARM_TXDACOFF;
|
|
|
|
break;
|
|
|
|
case RTW_SLEEP:
|
|
|
|
if (!before_rf)
|
|
|
|
return;
|
|
|
|
anaparm |= RTW_ANAPARM_RFPOW_MAXIM_SLEEP;
|
|
|
|
anaparm |= RTW_ANAPARM_TXDACOFF;
|
|
|
|
break;
|
|
|
|
case RTW_ON:
|
|
|
|
if (!before_rf)
|
|
|
|
return;
|
|
|
|
anaparm |= RTW_ANAPARM_RFPOW_MAXIM_ON;
|
|
|
|
break;
|
|
|
|
}
|
2004-12-25 09:58:37 +03:00
|
|
|
RTW_DPRINTF(RTW_DEBUG_PWR,
|
|
|
|
("%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n",
|
2004-12-21 02:05:41 +03:00
|
|
|
__func__, rtw_pwrstate_string(power),
|
|
|
|
(before_rf) ? "before" : "after", anaparm));
|
|
|
|
|
|
|
|
RTW_WRITE(regs, RTW_ANAPARM, anaparm);
|
|
|
|
RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* XXX I am using the RFMD settings gleaned from the reference
|
2005-02-27 03:26:58 +03:00
|
|
|
* driver. They agree
|
2004-12-21 02:05:41 +03:00
|
|
|
*/
|
|
|
|
static void
|
|
|
|
rtw_rfmd_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power,
|
2006-11-16 04:32:37 +03:00
|
|
|
int before_rf, int digphy)
|
2004-12-21 02:05:41 +03:00
|
|
|
{
|
2005-01-02 07:23:03 +03:00
|
|
|
uint32_t anaparm;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
anaparm = RTW_READ(regs, RTW_ANAPARM);
|
2004-12-21 02:05:41 +03:00
|
|
|
anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
switch (power) {
|
|
|
|
case RTW_OFF:
|
|
|
|
if (before_rf)
|
|
|
|
return;
|
2004-12-21 02:05:41 +03:00
|
|
|
anaparm |= RTW_ANAPARM_RFPOW_RFMD_OFF;
|
2004-09-26 06:29:15 +04:00
|
|
|
anaparm |= RTW_ANAPARM_TXDACOFF;
|
|
|
|
break;
|
|
|
|
case RTW_SLEEP:
|
|
|
|
if (!before_rf)
|
|
|
|
return;
|
2004-12-21 02:05:41 +03:00
|
|
|
anaparm |= RTW_ANAPARM_RFPOW_RFMD_SLEEP;
|
2004-09-26 06:29:15 +04:00
|
|
|
anaparm |= RTW_ANAPARM_TXDACOFF;
|
|
|
|
break;
|
|
|
|
case RTW_ON:
|
|
|
|
if (!before_rf)
|
|
|
|
return;
|
2004-12-21 02:05:41 +03:00
|
|
|
anaparm |= RTW_ANAPARM_RFPOW_RFMD_ON;
|
2004-09-26 06:29:15 +04:00
|
|
|
break;
|
|
|
|
}
|
2004-12-25 09:58:37 +03:00
|
|
|
RTW_DPRINTF(RTW_DEBUG_PWR,
|
|
|
|
("%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n",
|
2004-12-21 02:05:41 +03:00
|
|
|
__func__, rtw_pwrstate_string(power),
|
|
|
|
(before_rf) ? "before" : "after", anaparm));
|
|
|
|
|
2004-09-26 06:29:15 +04:00
|
|
|
RTW_WRITE(regs, RTW_ANAPARM, anaparm);
|
|
|
|
RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
rtw_philips_pwrstate(struct rtw_regs *regs, enum rtw_pwrstate power,
|
2004-12-21 02:05:41 +03:00
|
|
|
int before_rf, int digphy)
|
2004-09-26 06:29:15 +04:00
|
|
|
{
|
2005-01-02 07:23:03 +03:00
|
|
|
uint32_t anaparm;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
anaparm = RTW_READ(regs, RTW_ANAPARM);
|
2004-12-21 02:05:41 +03:00
|
|
|
anaparm &= ~(RTW_ANAPARM_RFPOW_MASK | RTW_ANAPARM_TXDACOFF);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
switch (power) {
|
|
|
|
case RTW_OFF:
|
|
|
|
if (before_rf)
|
|
|
|
return;
|
2004-12-21 02:05:41 +03:00
|
|
|
anaparm |= RTW_ANAPARM_RFPOW_PHILIPS_OFF;
|
2004-09-26 06:29:15 +04:00
|
|
|
anaparm |= RTW_ANAPARM_TXDACOFF;
|
|
|
|
break;
|
|
|
|
case RTW_SLEEP:
|
|
|
|
if (!before_rf)
|
|
|
|
return;
|
2004-12-21 02:05:41 +03:00
|
|
|
anaparm |= RTW_ANAPARM_RFPOW_PHILIPS_SLEEP;
|
2004-09-26 06:29:15 +04:00
|
|
|
anaparm |= RTW_ANAPARM_TXDACOFF;
|
|
|
|
break;
|
|
|
|
case RTW_ON:
|
|
|
|
if (!before_rf)
|
|
|
|
return;
|
2004-12-21 02:05:41 +03:00
|
|
|
if (digphy) {
|
|
|
|
anaparm |= RTW_ANAPARM_RFPOW_DIG_PHILIPS_ON;
|
|
|
|
/* XXX guess */
|
|
|
|
anaparm |= RTW_ANAPARM_TXDACOFF;
|
|
|
|
} else
|
|
|
|
anaparm |= RTW_ANAPARM_RFPOW_ANA_PHILIPS_ON;
|
2004-09-26 06:29:15 +04:00
|
|
|
break;
|
|
|
|
}
|
2004-12-25 09:58:37 +03:00
|
|
|
RTW_DPRINTF(RTW_DEBUG_PWR,
|
|
|
|
("%s: power state %s, %s RF, reg[ANAPARM] <- %08x\n",
|
2004-12-21 02:05:41 +03:00
|
|
|
__func__, rtw_pwrstate_string(power),
|
|
|
|
(before_rf) ? "before" : "after", anaparm));
|
|
|
|
|
2004-09-26 06:29:15 +04:00
|
|
|
RTW_WRITE(regs, RTW_ANAPARM, anaparm);
|
|
|
|
RTW_SYNC(regs, RTW_ANAPARM, RTW_ANAPARM);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2004-12-21 02:05:41 +03:00
|
|
|
rtw_pwrstate0(struct rtw_softc *sc, enum rtw_pwrstate power, int before_rf,
|
|
|
|
int digphy)
|
2004-09-26 06:29:15 +04:00
|
|
|
{
|
|
|
|
struct rtw_regs *regs = &sc->sc_regs;
|
|
|
|
|
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
|
|
|
rtw_set_access(regs, RTW_ACCESS_ANAPARM);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2004-12-21 02:05:41 +03:00
|
|
|
(*sc->sc_pwrstate_cb)(regs, power, before_rf, digphy);
|
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
|
|
|
rtw_set_access(regs, RTW_ACCESS_NONE);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
rtw_pwrstate(struct rtw_softc *sc, enum rtw_pwrstate power)
|
|
|
|
{
|
|
|
|
int rc;
|
|
|
|
|
2004-12-25 09:58:37 +03:00
|
|
|
RTW_DPRINTF(RTW_DEBUG_PWR,
|
|
|
|
("%s: %s->%s\n", __func__,
|
2004-09-26 06:29:15 +04:00
|
|
|
rtw_pwrstate_string(sc->sc_pwrstate), rtw_pwrstate_string(power)));
|
|
|
|
|
|
|
|
if (sc->sc_pwrstate == power)
|
|
|
|
return 0;
|
|
|
|
|
2004-12-21 02:05:41 +03:00
|
|
|
rtw_pwrstate0(sc, power, 1, sc->sc_flags & RTW_F_DIGPHY);
|
2004-09-26 06:29:15 +04:00
|
|
|
rc = rtw_rf_pwrstate(sc->sc_rf, power);
|
2004-12-21 02:05:41 +03:00
|
|
|
rtw_pwrstate0(sc, power, 0, sc->sc_flags & RTW_F_DIGPHY);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
switch (power) {
|
|
|
|
case RTW_ON:
|
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
|
|
|
/* TBD set LEDs */
|
2004-09-26 06:29:15 +04:00
|
|
|
break;
|
|
|
|
case RTW_SLEEP:
|
|
|
|
/* TBD */
|
|
|
|
break;
|
|
|
|
case RTW_OFF:
|
|
|
|
/* TBD */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (rc == 0)
|
|
|
|
sc->sc_pwrstate = power;
|
|
|
|
else
|
|
|
|
sc->sc_pwrstate = RTW_OFF;
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
rtw_tune(struct rtw_softc *sc)
|
|
|
|
{
|
|
|
|
struct ieee80211com *ic = &sc->sc_ic;
|
2006-03-28 02:03:36 +04:00
|
|
|
struct rtw_tx_radiotap_header *rt = &sc->sc_txtap;
|
|
|
|
struct rtw_rx_radiotap_header *rr = &sc->sc_rxtap;
|
2004-09-26 06:29:15 +04:00
|
|
|
u_int chan;
|
|
|
|
int rc;
|
|
|
|
int antdiv = sc->sc_flags & RTW_F_ANTDIV,
|
|
|
|
dflantb = sc->sc_flags & RTW_F_DFLANTB;
|
|
|
|
|
2005-11-18 19:53:56 +03:00
|
|
|
chan = ieee80211_chan2ieee(ic, ic->ic_curchan);
|
2007-12-20 21:47:23 +03:00
|
|
|
KASSERT(chan != IEEE80211_CHAN_ANY);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2006-03-28 02:03:36 +04:00
|
|
|
rt->rt_chan_freq = htole16(ic->ic_curchan->ic_freq);
|
|
|
|
rt->rt_chan_flags = htole16(ic->ic_curchan->ic_flags);
|
|
|
|
|
|
|
|
rr->rr_chan_freq = htole16(ic->ic_curchan->ic_freq);
|
|
|
|
rr->rr_chan_flags = htole16(ic->ic_curchan->ic_flags);
|
|
|
|
|
2004-09-26 06:29:15 +04:00
|
|
|
if (chan == sc->sc_cur_chan) {
|
2004-12-25 09:58:37 +03:00
|
|
|
RTW_DPRINTF(RTW_DEBUG_TUNE,
|
2005-02-27 03:26:58 +03:00
|
|
|
("%s: already tuned chan #%d\n", __func__, chan));
|
2004-09-26 06:29:15 +04:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
rtw_suspend_ticks(sc);
|
|
|
|
|
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
|
|
|
rtw_io_enable(sc, RTW_CR_RE | RTW_CR_TE, 0);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
/* TBD wait for Tx to complete */
|
|
|
|
|
Use device_t and its accessors throughout. Use aprint_*_dev().
Improve PMF-ability.
Add a 'flags' argument to suspend/resume handlers and
callers such as pmf_system_suspend().
Define a flag, PMF_F_SELF, which indicates to PMF that a
device is suspending/resuming itself. Add helper routines,
pmf_device_suspend_self(dev) and pmf_device_resume_self(dev),
that call pmf_device_suspend(dev, PMF_F_SELF) and
pmf_device_resume(dev, PMF_F_SELF), respectively. Use
PMF_F_SELF to suspend/resume self in ath(4), audio(4),
rtw(4), and sip(4).
In ath(4) and in rtw(4), replace the icky sc_enable/sc_disable
callbacks, provided by the bus front-end, with
self-suspension/resumption. Also, clean up the bus
front-ends. Make sure that the interrupt handler is
disestablished during suspension. Get rid of driver-private
flags (e.g., RTW_F_ENABLED, ath_softc->sc_invalid); use
device_is_active()/device_has_power() calls, instead.
In the network-class suspend handler, call if_stop(, 0)
instead of if_stop(, 1), because the latter is superfluous
(bus- and driver-suspension hooks will 'disable' the NIC),
and it may cause recursion.
In the network-class resume handler, prevent infinite
recursion through if_init() by getting out early if we are
self-suspending (PMF_F_SELF).
rtw(4) improvements:
Destroy rtw(4) callouts when we detach it. Make rtw at
pci detachable. Print some more information with the "rx
frame too long" warning.
Remove activate() methods:
Get rid of rtw_activate() and ath_activate(). The device
activate() methods are not good for much these days.
Make ath at cardbus resume with crypto functions intact:
Introduce a boolean device property, "pmf-powerdown". If
pmf-powerdown is present and false, it indicates that a
bus back-end should not remove power from a device.
Honor this property in cardbus_child_suspend().
Set this property to 'false' in ath_attach(), since removing
power from an ath at cardbus seems to lobotomize the WPA
crypto engine. XXX Should the pmf-powerdown property
propagate toward the root of the device tree?
Miscellaneous ath(4) changes:
Warn if ath(4) tries to write crypto keys to suspended
hardware.
Reduce differences between FreeBSD and NetBSD in ath(4)
multicast filter setup.
Make ath_printrxbuf() print an rx descriptor's status &
key index, to help debug crypto errors.
Shorten a staircase in ath_ioctl(). Don't check for
ieee80211_ioctl() return code ERESTART, it never happens.
2008-03-12 21:02:21 +03:00
|
|
|
KASSERT(device_has_power(sc->sc_dev));
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
if ((rc = rtw_phy_init(&sc->sc_regs, sc->sc_rf,
|
2005-11-18 19:53:56 +03:00
|
|
|
rtw_chan2txpower(&sc->sc_srom, ic, ic->ic_curchan), sc->sc_csthr,
|
|
|
|
ic->ic_curchan->ic_freq, antdiv, dflantb, RTW_ON)) != 0) {
|
2004-09-26 06:29:15 +04:00
|
|
|
/* XXX condition on powersaving */
|
2007-12-21 21:22:43 +03:00
|
|
|
aprint_error_dev(sc->sc_dev, "phy init failed\n");
|
2004-09-26 06:29:15 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
sc->sc_cur_chan = chan;
|
|
|
|
|
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
|
|
|
rtw_io_enable(sc, RTW_CR_RE | RTW_CR_TE, 1);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
rtw_resume_ticks(sc);
|
|
|
|
|
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
Use device_t and its accessors throughout. Use aprint_*_dev().
Improve PMF-ability.
Add a 'flags' argument to suspend/resume handlers and
callers such as pmf_system_suspend().
Define a flag, PMF_F_SELF, which indicates to PMF that a
device is suspending/resuming itself. Add helper routines,
pmf_device_suspend_self(dev) and pmf_device_resume_self(dev),
that call pmf_device_suspend(dev, PMF_F_SELF) and
pmf_device_resume(dev, PMF_F_SELF), respectively. Use
PMF_F_SELF to suspend/resume self in ath(4), audio(4),
rtw(4), and sip(4).
In ath(4) and in rtw(4), replace the icky sc_enable/sc_disable
callbacks, provided by the bus front-end, with
self-suspension/resumption. Also, clean up the bus
front-ends. Make sure that the interrupt handler is
disestablished during suspension. Get rid of driver-private
flags (e.g., RTW_F_ENABLED, ath_softc->sc_invalid); use
device_is_active()/device_has_power() calls, instead.
In the network-class suspend handler, call if_stop(, 0)
instead of if_stop(, 1), because the latter is superfluous
(bus- and driver-suspension hooks will 'disable' the NIC),
and it may cause recursion.
In the network-class resume handler, prevent infinite
recursion through if_init() by getting out early if we are
self-suspending (PMF_F_SELF).
rtw(4) improvements:
Destroy rtw(4) callouts when we detach it. Make rtw at
pci detachable. Print some more information with the "rx
frame too long" warning.
Remove activate() methods:
Get rid of rtw_activate() and ath_activate(). The device
activate() methods are not good for much these days.
Make ath at cardbus resume with crypto functions intact:
Introduce a boolean device property, "pmf-powerdown". If
pmf-powerdown is present and false, it indicates that a
bus back-end should not remove power from a device.
Honor this property in cardbus_child_suspend().
Set this property to 'false' in ath_attach(), since removing
power from an ath at cardbus seems to lobotomize the WPA
crypto engine. XXX Should the pmf-powerdown property
propagate toward the root of the device tree?
Miscellaneous ath(4) changes:
Warn if ath(4) tries to write crypto keys to suspended
hardware.
Reduce differences between FreeBSD and NetBSD in ath(4)
multicast filter setup.
Make ath_printrxbuf() print an rx descriptor's status &
key index, to help debug crypto errors.
Shorten a staircase in ath_ioctl(). Don't check for
ieee80211_ioctl() return code ERESTART, it never happens.
2008-03-12 21:02:21 +03:00
|
|
|
bool
|
2010-02-25 01:37:54 +03:00
|
|
|
rtw_suspend(device_t self, const pmf_qual_t *qual)
|
2004-09-26 06:29:15 +04:00
|
|
|
{
|
|
|
|
int rc;
|
Use device_t and its accessors throughout. Use aprint_*_dev().
Improve PMF-ability.
Add a 'flags' argument to suspend/resume handlers and
callers such as pmf_system_suspend().
Define a flag, PMF_F_SELF, which indicates to PMF that a
device is suspending/resuming itself. Add helper routines,
pmf_device_suspend_self(dev) and pmf_device_resume_self(dev),
that call pmf_device_suspend(dev, PMF_F_SELF) and
pmf_device_resume(dev, PMF_F_SELF), respectively. Use
PMF_F_SELF to suspend/resume self in ath(4), audio(4),
rtw(4), and sip(4).
In ath(4) and in rtw(4), replace the icky sc_enable/sc_disable
callbacks, provided by the bus front-end, with
self-suspension/resumption. Also, clean up the bus
front-ends. Make sure that the interrupt handler is
disestablished during suspension. Get rid of driver-private
flags (e.g., RTW_F_ENABLED, ath_softc->sc_invalid); use
device_is_active()/device_has_power() calls, instead.
In the network-class suspend handler, call if_stop(, 0)
instead of if_stop(, 1), because the latter is superfluous
(bus- and driver-suspension hooks will 'disable' the NIC),
and it may cause recursion.
In the network-class resume handler, prevent infinite
recursion through if_init() by getting out early if we are
self-suspending (PMF_F_SELF).
rtw(4) improvements:
Destroy rtw(4) callouts when we detach it. Make rtw at
pci detachable. Print some more information with the "rx
frame too long" warning.
Remove activate() methods:
Get rid of rtw_activate() and ath_activate(). The device
activate() methods are not good for much these days.
Make ath at cardbus resume with crypto functions intact:
Introduce a boolean device property, "pmf-powerdown". If
pmf-powerdown is present and false, it indicates that a
bus back-end should not remove power from a device.
Honor this property in cardbus_child_suspend().
Set this property to 'false' in ath_attach(), since removing
power from an ath at cardbus seems to lobotomize the WPA
crypto engine. XXX Should the pmf-powerdown property
propagate toward the root of the device tree?
Miscellaneous ath(4) changes:
Warn if ath(4) tries to write crypto keys to suspended
hardware.
Reduce differences between FreeBSD and NetBSD in ath(4)
multicast filter setup.
Make ath_printrxbuf() print an rx descriptor's status &
key index, to help debug crypto errors.
Shorten a staircase in ath_ioctl(). Don't check for
ieee80211_ioctl() return code ERESTART, it never happens.
2008-03-12 21:02:21 +03:00
|
|
|
struct rtw_softc *sc = device_private(self);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
Use device_t and its accessors throughout. Use aprint_*_dev().
Improve PMF-ability.
Add a 'flags' argument to suspend/resume handlers and
callers such as pmf_system_suspend().
Define a flag, PMF_F_SELF, which indicates to PMF that a
device is suspending/resuming itself. Add helper routines,
pmf_device_suspend_self(dev) and pmf_device_resume_self(dev),
that call pmf_device_suspend(dev, PMF_F_SELF) and
pmf_device_resume(dev, PMF_F_SELF), respectively. Use
PMF_F_SELF to suspend/resume self in ath(4), audio(4),
rtw(4), and sip(4).
In ath(4) and in rtw(4), replace the icky sc_enable/sc_disable
callbacks, provided by the bus front-end, with
self-suspension/resumption. Also, clean up the bus
front-ends. Make sure that the interrupt handler is
disestablished during suspension. Get rid of driver-private
flags (e.g., RTW_F_ENABLED, ath_softc->sc_invalid); use
device_is_active()/device_has_power() calls, instead.
In the network-class suspend handler, call if_stop(, 0)
instead of if_stop(, 1), because the latter is superfluous
(bus- and driver-suspension hooks will 'disable' the NIC),
and it may cause recursion.
In the network-class resume handler, prevent infinite
recursion through if_init() by getting out early if we are
self-suspending (PMF_F_SELF).
rtw(4) improvements:
Destroy rtw(4) callouts when we detach it. Make rtw at
pci detachable. Print some more information with the "rx
frame too long" warning.
Remove activate() methods:
Get rid of rtw_activate() and ath_activate(). The device
activate() methods are not good for much these days.
Make ath at cardbus resume with crypto functions intact:
Introduce a boolean device property, "pmf-powerdown". If
pmf-powerdown is present and false, it indicates that a
bus back-end should not remove power from a device.
Honor this property in cardbus_child_suspend().
Set this property to 'false' in ath_attach(), since removing
power from an ath at cardbus seems to lobotomize the WPA
crypto engine. XXX Should the pmf-powerdown property
propagate toward the root of the device tree?
Miscellaneous ath(4) changes:
Warn if ath(4) tries to write crypto keys to suspended
hardware.
Reduce differences between FreeBSD and NetBSD in ath(4)
multicast filter setup.
Make ath_printrxbuf() print an rx descriptor's status &
key index, to help debug crypto errors.
Shorten a staircase in ath_ioctl(). Don't check for
ieee80211_ioctl() return code ERESTART, it never happens.
2008-03-12 21:02:21 +03:00
|
|
|
sc->sc_flags &= ~RTW_F_DK_VALID;
|
|
|
|
|
|
|
|
if (!device_has_power(self))
|
|
|
|
return false;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
/* turn off PHY */
|
Use device_t and its accessors throughout. Use aprint_*_dev().
Improve PMF-ability.
Add a 'flags' argument to suspend/resume handlers and
callers such as pmf_system_suspend().
Define a flag, PMF_F_SELF, which indicates to PMF that a
device is suspending/resuming itself. Add helper routines,
pmf_device_suspend_self(dev) and pmf_device_resume_self(dev),
that call pmf_device_suspend(dev, PMF_F_SELF) and
pmf_device_resume(dev, PMF_F_SELF), respectively. Use
PMF_F_SELF to suspend/resume self in ath(4), audio(4),
rtw(4), and sip(4).
In ath(4) and in rtw(4), replace the icky sc_enable/sc_disable
callbacks, provided by the bus front-end, with
self-suspension/resumption. Also, clean up the bus
front-ends. Make sure that the interrupt handler is
disestablished during suspension. Get rid of driver-private
flags (e.g., RTW_F_ENABLED, ath_softc->sc_invalid); use
device_is_active()/device_has_power() calls, instead.
In the network-class suspend handler, call if_stop(, 0)
instead of if_stop(, 1), because the latter is superfluous
(bus- and driver-suspension hooks will 'disable' the NIC),
and it may cause recursion.
In the network-class resume handler, prevent infinite
recursion through if_init() by getting out early if we are
self-suspending (PMF_F_SELF).
rtw(4) improvements:
Destroy rtw(4) callouts when we detach it. Make rtw at
pci detachable. Print some more information with the "rx
frame too long" warning.
Remove activate() methods:
Get rid of rtw_activate() and ath_activate(). The device
activate() methods are not good for much these days.
Make ath at cardbus resume with crypto functions intact:
Introduce a boolean device property, "pmf-powerdown". If
pmf-powerdown is present and false, it indicates that a
bus back-end should not remove power from a device.
Honor this property in cardbus_child_suspend().
Set this property to 'false' in ath_attach(), since removing
power from an ath at cardbus seems to lobotomize the WPA
crypto engine. XXX Should the pmf-powerdown property
propagate toward the root of the device tree?
Miscellaneous ath(4) changes:
Warn if ath(4) tries to write crypto keys to suspended
hardware.
Reduce differences between FreeBSD and NetBSD in ath(4)
multicast filter setup.
Make ath_printrxbuf() print an rx descriptor's status &
key index, to help debug crypto errors.
Shorten a staircase in ath_ioctl(). Don't check for
ieee80211_ioctl() return code ERESTART, it never happens.
2008-03-12 21:02:21 +03:00
|
|
|
if ((rc = rtw_pwrstate(sc, RTW_OFF)) != 0) {
|
|
|
|
aprint_error_dev(self, "failed to turn off PHY (%d)\n", rc);
|
|
|
|
return false;
|
2004-12-29 22:41:04 +03:00
|
|
|
}
|
2004-09-26 06:29:15 +04:00
|
|
|
|
Use device_t and its accessors throughout. Use aprint_*_dev().
Improve PMF-ability.
Add a 'flags' argument to suspend/resume handlers and
callers such as pmf_system_suspend().
Define a flag, PMF_F_SELF, which indicates to PMF that a
device is suspending/resuming itself. Add helper routines,
pmf_device_suspend_self(dev) and pmf_device_resume_self(dev),
that call pmf_device_suspend(dev, PMF_F_SELF) and
pmf_device_resume(dev, PMF_F_SELF), respectively. Use
PMF_F_SELF to suspend/resume self in ath(4), audio(4),
rtw(4), and sip(4).
In ath(4) and in rtw(4), replace the icky sc_enable/sc_disable
callbacks, provided by the bus front-end, with
self-suspension/resumption. Also, clean up the bus
front-ends. Make sure that the interrupt handler is
disestablished during suspension. Get rid of driver-private
flags (e.g., RTW_F_ENABLED, ath_softc->sc_invalid); use
device_is_active()/device_has_power() calls, instead.
In the network-class suspend handler, call if_stop(, 0)
instead of if_stop(, 1), because the latter is superfluous
(bus- and driver-suspension hooks will 'disable' the NIC),
and it may cause recursion.
In the network-class resume handler, prevent infinite
recursion through if_init() by getting out early if we are
self-suspending (PMF_F_SELF).
rtw(4) improvements:
Destroy rtw(4) callouts when we detach it. Make rtw at
pci detachable. Print some more information with the "rx
frame too long" warning.
Remove activate() methods:
Get rid of rtw_activate() and ath_activate(). The device
activate() methods are not good for much these days.
Make ath at cardbus resume with crypto functions intact:
Introduce a boolean device property, "pmf-powerdown". If
pmf-powerdown is present and false, it indicates that a
bus back-end should not remove power from a device.
Honor this property in cardbus_child_suspend().
Set this property to 'false' in ath_attach(), since removing
power from an ath at cardbus seems to lobotomize the WPA
crypto engine. XXX Should the pmf-powerdown property
propagate toward the root of the device tree?
Miscellaneous ath(4) changes:
Warn if ath(4) tries to write crypto keys to suspended
hardware.
Reduce differences between FreeBSD and NetBSD in ath(4)
multicast filter setup.
Make ath_printrxbuf() print an rx descriptor's status &
key index, to help debug crypto errors.
Shorten a staircase in ath_ioctl(). Don't check for
ieee80211_ioctl() return code ERESTART, it never happens.
2008-03-12 21:02:21 +03:00
|
|
|
rtw_disable_interrupts(&sc->sc_regs);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
Use device_t and its accessors throughout. Use aprint_*_dev().
Improve PMF-ability.
Add a 'flags' argument to suspend/resume handlers and
callers such as pmf_system_suspend().
Define a flag, PMF_F_SELF, which indicates to PMF that a
device is suspending/resuming itself. Add helper routines,
pmf_device_suspend_self(dev) and pmf_device_resume_self(dev),
that call pmf_device_suspend(dev, PMF_F_SELF) and
pmf_device_resume(dev, PMF_F_SELF), respectively. Use
PMF_F_SELF to suspend/resume self in ath(4), audio(4),
rtw(4), and sip(4).
In ath(4) and in rtw(4), replace the icky sc_enable/sc_disable
callbacks, provided by the bus front-end, with
self-suspension/resumption. Also, clean up the bus
front-ends. Make sure that the interrupt handler is
disestablished during suspension. Get rid of driver-private
flags (e.g., RTW_F_ENABLED, ath_softc->sc_invalid); use
device_is_active()/device_has_power() calls, instead.
In the network-class suspend handler, call if_stop(, 0)
instead of if_stop(, 1), because the latter is superfluous
(bus- and driver-suspension hooks will 'disable' the NIC),
and it may cause recursion.
In the network-class resume handler, prevent infinite
recursion through if_init() by getting out early if we are
self-suspending (PMF_F_SELF).
rtw(4) improvements:
Destroy rtw(4) callouts when we detach it. Make rtw at
pci detachable. Print some more information with the "rx
frame too long" warning.
Remove activate() methods:
Get rid of rtw_activate() and ath_activate(). The device
activate() methods are not good for much these days.
Make ath at cardbus resume with crypto functions intact:
Introduce a boolean device property, "pmf-powerdown". If
pmf-powerdown is present and false, it indicates that a
bus back-end should not remove power from a device.
Honor this property in cardbus_child_suspend().
Set this property to 'false' in ath_attach(), since removing
power from an ath at cardbus seems to lobotomize the WPA
crypto engine. XXX Should the pmf-powerdown property
propagate toward the root of the device tree?
Miscellaneous ath(4) changes:
Warn if ath(4) tries to write crypto keys to suspended
hardware.
Reduce differences between FreeBSD and NetBSD in ath(4)
multicast filter setup.
Make ath_printrxbuf() print an rx descriptor's status &
key index, to help debug crypto errors.
Shorten a staircase in ath_ioctl(). Don't check for
ieee80211_ioctl() return code ERESTART, it never happens.
2008-03-12 21:02:21 +03:00
|
|
|
return true;
|
2004-09-26 06:29:15 +04:00
|
|
|
}
|
|
|
|
|
Use device_t and its accessors throughout. Use aprint_*_dev().
Improve PMF-ability.
Add a 'flags' argument to suspend/resume handlers and
callers such as pmf_system_suspend().
Define a flag, PMF_F_SELF, which indicates to PMF that a
device is suspending/resuming itself. Add helper routines,
pmf_device_suspend_self(dev) and pmf_device_resume_self(dev),
that call pmf_device_suspend(dev, PMF_F_SELF) and
pmf_device_resume(dev, PMF_F_SELF), respectively. Use
PMF_F_SELF to suspend/resume self in ath(4), audio(4),
rtw(4), and sip(4).
In ath(4) and in rtw(4), replace the icky sc_enable/sc_disable
callbacks, provided by the bus front-end, with
self-suspension/resumption. Also, clean up the bus
front-ends. Make sure that the interrupt handler is
disestablished during suspension. Get rid of driver-private
flags (e.g., RTW_F_ENABLED, ath_softc->sc_invalid); use
device_is_active()/device_has_power() calls, instead.
In the network-class suspend handler, call if_stop(, 0)
instead of if_stop(, 1), because the latter is superfluous
(bus- and driver-suspension hooks will 'disable' the NIC),
and it may cause recursion.
In the network-class resume handler, prevent infinite
recursion through if_init() by getting out early if we are
self-suspending (PMF_F_SELF).
rtw(4) improvements:
Destroy rtw(4) callouts when we detach it. Make rtw at
pci detachable. Print some more information with the "rx
frame too long" warning.
Remove activate() methods:
Get rid of rtw_activate() and ath_activate(). The device
activate() methods are not good for much these days.
Make ath at cardbus resume with crypto functions intact:
Introduce a boolean device property, "pmf-powerdown". If
pmf-powerdown is present and false, it indicates that a
bus back-end should not remove power from a device.
Honor this property in cardbus_child_suspend().
Set this property to 'false' in ath_attach(), since removing
power from an ath at cardbus seems to lobotomize the WPA
crypto engine. XXX Should the pmf-powerdown property
propagate toward the root of the device tree?
Miscellaneous ath(4) changes:
Warn if ath(4) tries to write crypto keys to suspended
hardware.
Reduce differences between FreeBSD and NetBSD in ath(4)
multicast filter setup.
Make ath_printrxbuf() print an rx descriptor's status &
key index, to help debug crypto errors.
Shorten a staircase in ath_ioctl(). Don't check for
ieee80211_ioctl() return code ERESTART, it never happens.
2008-03-12 21:02:21 +03:00
|
|
|
bool
|
2010-02-25 01:37:54 +03:00
|
|
|
rtw_resume(device_t self, const pmf_qual_t *qual)
|
2004-09-26 06:29:15 +04:00
|
|
|
{
|
Use device_t and its accessors throughout. Use aprint_*_dev().
Improve PMF-ability.
Add a 'flags' argument to suspend/resume handlers and
callers such as pmf_system_suspend().
Define a flag, PMF_F_SELF, which indicates to PMF that a
device is suspending/resuming itself. Add helper routines,
pmf_device_suspend_self(dev) and pmf_device_resume_self(dev),
that call pmf_device_suspend(dev, PMF_F_SELF) and
pmf_device_resume(dev, PMF_F_SELF), respectively. Use
PMF_F_SELF to suspend/resume self in ath(4), audio(4),
rtw(4), and sip(4).
In ath(4) and in rtw(4), replace the icky sc_enable/sc_disable
callbacks, provided by the bus front-end, with
self-suspension/resumption. Also, clean up the bus
front-ends. Make sure that the interrupt handler is
disestablished during suspension. Get rid of driver-private
flags (e.g., RTW_F_ENABLED, ath_softc->sc_invalid); use
device_is_active()/device_has_power() calls, instead.
In the network-class suspend handler, call if_stop(, 0)
instead of if_stop(, 1), because the latter is superfluous
(bus- and driver-suspension hooks will 'disable' the NIC),
and it may cause recursion.
In the network-class resume handler, prevent infinite
recursion through if_init() by getting out early if we are
self-suspending (PMF_F_SELF).
rtw(4) improvements:
Destroy rtw(4) callouts when we detach it. Make rtw at
pci detachable. Print some more information with the "rx
frame too long" warning.
Remove activate() methods:
Get rid of rtw_activate() and ath_activate(). The device
activate() methods are not good for much these days.
Make ath at cardbus resume with crypto functions intact:
Introduce a boolean device property, "pmf-powerdown". If
pmf-powerdown is present and false, it indicates that a
bus back-end should not remove power from a device.
Honor this property in cardbus_child_suspend().
Set this property to 'false' in ath_attach(), since removing
power from an ath at cardbus seems to lobotomize the WPA
crypto engine. XXX Should the pmf-powerdown property
propagate toward the root of the device tree?
Miscellaneous ath(4) changes:
Warn if ath(4) tries to write crypto keys to suspended
hardware.
Reduce differences between FreeBSD and NetBSD in ath(4)
multicast filter setup.
Make ath_printrxbuf() print an rx descriptor's status &
key index, to help debug crypto errors.
Shorten a staircase in ath_ioctl(). Don't check for
ieee80211_ioctl() return code ERESTART, it never happens.
2008-03-12 21:02:21 +03:00
|
|
|
struct rtw_softc *sc = device_private(self);
|
|
|
|
|
|
|
|
/* Power may have been removed, resetting WEP keys.
|
|
|
|
*/
|
|
|
|
sc->sc_flags &= ~RTW_F_DK_VALID;
|
|
|
|
rtw_enable_interrupts(sc);
|
|
|
|
|
|
|
|
return true;
|
2004-09-26 06:29:15 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
rtw_transmit_config(struct rtw_regs *regs)
|
|
|
|
{
|
2005-01-02 07:23:03 +03:00
|
|
|
uint32_t tcr;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
tcr = RTW_READ(regs, RTW_TCR);
|
|
|
|
|
2004-12-21 02:05:41 +03:00
|
|
|
tcr |= RTW_TCR_CWMIN;
|
|
|
|
tcr &= ~RTW_TCR_MXDMA_MASK;
|
|
|
|
tcr |= RTW_TCR_MXDMA_256;
|
2004-09-26 06:29:15 +04:00
|
|
|
tcr |= RTW_TCR_SAT; /* send ACK as fast as possible */
|
|
|
|
tcr &= ~RTW_TCR_LBK_MASK;
|
|
|
|
tcr |= RTW_TCR_LBK_NORMAL; /* normal operating mode */
|
|
|
|
|
|
|
|
/* set short/long retry limits */
|
|
|
|
tcr &= ~(RTW_TCR_SRL_MASK|RTW_TCR_LRL_MASK);
|
Per discussion on tech-kern and tech-userlevel, move the bit-twiddling
macros, __BIT, __BITS, SHIFTIN, SHIFTOUT, and __arraycount() from
lib/libkern/libkern.h to sys/cdefs.h. Add a __-prefix to SHIFTIN
and SHIFTOUT, and add a manual page for the bit-twiddling macros,
bits(3).
Make the __BIT and __BITS macros "widthless," as best I can, by
changing their type to uintmax_t from uint32_t. XXX The manual
page lags this change by a bit.
Define __PRIxBIT and __PRIxBITS printf(3) format strings.
2006-08-31 23:24:37 +04:00
|
|
|
tcr |= __SHIFTIN(4, RTW_TCR_SRL_MASK) | __SHIFTIN(4, RTW_TCR_LRL_MASK);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2004-12-23 08:50:24 +03:00
|
|
|
tcr &= ~RTW_TCR_CRC; /* NIC appends CRC32 */
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
RTW_WRITE(regs, RTW_TCR, tcr);
|
2004-12-20 04:13:45 +03:00
|
|
|
RTW_SYNC(regs, RTW_TCR, RTW_TCR);
|
2004-09-26 06:29:15 +04:00
|
|
|
}
|
|
|
|
|
Use device_t and its accessors throughout. Use aprint_*_dev().
Improve PMF-ability.
Add a 'flags' argument to suspend/resume handlers and
callers such as pmf_system_suspend().
Define a flag, PMF_F_SELF, which indicates to PMF that a
device is suspending/resuming itself. Add helper routines,
pmf_device_suspend_self(dev) and pmf_device_resume_self(dev),
that call pmf_device_suspend(dev, PMF_F_SELF) and
pmf_device_resume(dev, PMF_F_SELF), respectively. Use
PMF_F_SELF to suspend/resume self in ath(4), audio(4),
rtw(4), and sip(4).
In ath(4) and in rtw(4), replace the icky sc_enable/sc_disable
callbacks, provided by the bus front-end, with
self-suspension/resumption. Also, clean up the bus
front-ends. Make sure that the interrupt handler is
disestablished during suspension. Get rid of driver-private
flags (e.g., RTW_F_ENABLED, ath_softc->sc_invalid); use
device_is_active()/device_has_power() calls, instead.
In the network-class suspend handler, call if_stop(, 0)
instead of if_stop(, 1), because the latter is superfluous
(bus- and driver-suspension hooks will 'disable' the NIC),
and it may cause recursion.
In the network-class resume handler, prevent infinite
recursion through if_init() by getting out early if we are
self-suspending (PMF_F_SELF).
rtw(4) improvements:
Destroy rtw(4) callouts when we detach it. Make rtw at
pci detachable. Print some more information with the "rx
frame too long" warning.
Remove activate() methods:
Get rid of rtw_activate() and ath_activate(). The device
activate() methods are not good for much these days.
Make ath at cardbus resume with crypto functions intact:
Introduce a boolean device property, "pmf-powerdown". If
pmf-powerdown is present and false, it indicates that a
bus back-end should not remove power from a device.
Honor this property in cardbus_child_suspend().
Set this property to 'false' in ath_attach(), since removing
power from an ath at cardbus seems to lobotomize the WPA
crypto engine. XXX Should the pmf-powerdown property
propagate toward the root of the device tree?
Miscellaneous ath(4) changes:
Warn if ath(4) tries to write crypto keys to suspended
hardware.
Reduce differences between FreeBSD and NetBSD in ath(4)
multicast filter setup.
Make ath_printrxbuf() print an rx descriptor's status &
key index, to help debug crypto errors.
Shorten a staircase in ath_ioctl(). Don't check for
ieee80211_ioctl() return code ERESTART, it never happens.
2008-03-12 21:02:21 +03:00
|
|
|
static void
|
|
|
|
rtw_disable_interrupts(struct rtw_regs *regs)
|
|
|
|
{
|
|
|
|
RTW_WRITE16(regs, RTW_IMR, 0);
|
|
|
|
RTW_WBW(regs, RTW_IMR, RTW_ISR);
|
|
|
|
RTW_WRITE16(regs, RTW_ISR, 0xffff);
|
|
|
|
RTW_SYNC(regs, RTW_IMR, RTW_ISR);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2004-09-26 06:29:15 +04:00
|
|
|
rtw_enable_interrupts(struct rtw_softc *sc)
|
|
|
|
{
|
|
|
|
struct rtw_regs *regs = &sc->sc_regs;
|
|
|
|
|
|
|
|
sc->sc_inten = RTW_INTR_RX|RTW_INTR_TX|RTW_INTR_BEACON|RTW_INTR_ATIMINT;
|
|
|
|
sc->sc_inten |= RTW_INTR_IOERROR|RTW_INTR_TIMEOUT;
|
|
|
|
|
|
|
|
RTW_WRITE16(regs, RTW_IMR, sc->sc_inten);
|
2004-12-20 04:13:45 +03:00
|
|
|
RTW_WBW(regs, RTW_IMR, RTW_ISR);
|
2004-09-26 06:29:15 +04:00
|
|
|
RTW_WRITE16(regs, RTW_ISR, 0xffff);
|
2004-12-20 04:13:45 +03:00
|
|
|
RTW_SYNC(regs, RTW_IMR, RTW_ISR);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
/* XXX necessary? */
|
|
|
|
if (sc->sc_intr_ack != NULL)
|
|
|
|
(*sc->sc_intr_ack)(regs);
|
|
|
|
}
|
|
|
|
|
2004-12-21 02:05:41 +03:00
|
|
|
static void
|
|
|
|
rtw_set_nettype(struct rtw_softc *sc, enum ieee80211_opmode opmode)
|
|
|
|
{
|
|
|
|
uint8_t msr;
|
|
|
|
|
|
|
|
/* I'm guessing that MSR is protected as CONFIG[0123] are. */
|
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
|
|
|
rtw_set_access(&sc->sc_regs, RTW_ACCESS_CONFIG);
|
2004-12-21 02:05:41 +03:00
|
|
|
|
|
|
|
msr = RTW_READ8(&sc->sc_regs, RTW_MSR) & ~RTW_MSR_NETYPE_MASK;
|
|
|
|
|
|
|
|
switch (opmode) {
|
|
|
|
case IEEE80211_M_AHDEMO:
|
|
|
|
case IEEE80211_M_IBSS:
|
|
|
|
msr |= RTW_MSR_NETYPE_ADHOC_OK;
|
|
|
|
break;
|
|
|
|
case IEEE80211_M_HOSTAP:
|
|
|
|
msr |= RTW_MSR_NETYPE_AP_OK;
|
|
|
|
break;
|
|
|
|
case IEEE80211_M_MONITOR:
|
|
|
|
/* XXX */
|
|
|
|
msr |= RTW_MSR_NETYPE_NOLINK;
|
|
|
|
break;
|
|
|
|
case IEEE80211_M_STA:
|
|
|
|
msr |= RTW_MSR_NETYPE_INFRA_OK;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
RTW_WRITE8(&sc->sc_regs, RTW_MSR, msr);
|
|
|
|
|
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
|
|
|
rtw_set_access(&sc->sc_regs, RTW_ACCESS_NONE);
|
2004-12-21 02:05:41 +03:00
|
|
|
}
|
|
|
|
|
2004-09-26 06:29:15 +04:00
|
|
|
#define rtw_calchash(addr) \
|
2005-01-03 06:07:12 +03:00
|
|
|
(ether_crc32_be((addr), IEEE80211_ADDR_LEN) >> 26)
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
static void
|
|
|
|
rtw_pktfilt_load(struct rtw_softc *sc)
|
|
|
|
{
|
|
|
|
struct rtw_regs *regs = &sc->sc_regs;
|
|
|
|
struct ieee80211com *ic = &sc->sc_ic;
|
2005-06-22 10:14:51 +04:00
|
|
|
struct ethercom *ec = &sc->sc_ec;
|
|
|
|
struct ifnet *ifp = &sc->sc_if;
|
2004-09-26 06:29:15 +04:00
|
|
|
int hash;
|
2005-01-02 07:23:03 +03:00
|
|
|
uint32_t hashes[2] = { 0, 0 };
|
2004-09-26 06:29:15 +04:00
|
|
|
struct ether_multi *enm;
|
|
|
|
struct ether_multistep step;
|
|
|
|
|
|
|
|
/* XXX might be necessary to stop Rx/Tx engines while setting filters */
|
|
|
|
|
2005-01-03 06:07:12 +03:00
|
|
|
sc->sc_rcr &= ~RTW_RCR_PKTFILTER_MASK;
|
|
|
|
sc->sc_rcr &= ~(RTW_RCR_MXDMA_MASK | RTW_RCR_RXFTH_MASK);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2005-01-03 06:07:12 +03:00
|
|
|
sc->sc_rcr |= RTW_RCR_PKTFILTER_DEFAULT;
|
|
|
|
/* MAC auto-reset PHY (huh?) */
|
2004-12-21 02:05:41 +03:00
|
|
|
sc->sc_rcr |= RTW_RCR_ENMARP;
|
2005-01-03 06:07:12 +03:00
|
|
|
/* DMA whole Rx packets, only. Set Tx DMA burst size to 1024 bytes. */
|
|
|
|
sc->sc_rcr |= RTW_RCR_MXDMA_1024 | RTW_RCR_RXFTH_WHOLE;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2005-01-03 06:07:12 +03:00
|
|
|
switch (ic->ic_opmode) {
|
|
|
|
case IEEE80211_M_MONITOR:
|
|
|
|
sc->sc_rcr |= RTW_RCR_MONITOR;
|
|
|
|
break;
|
|
|
|
case IEEE80211_M_AHDEMO:
|
|
|
|
case IEEE80211_M_IBSS:
|
|
|
|
/* receive broadcasts in our BSS */
|
|
|
|
sc->sc_rcr |= RTW_RCR_ADD3;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
ifp->if_flags &= ~IFF_ALLMULTI;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Program the 64-bit multicast hash filter.
|
|
|
|
*/
|
|
|
|
ETHER_FIRST_MULTI(step, ec, enm);
|
|
|
|
while (enm != NULL) {
|
|
|
|
/* XXX */
|
|
|
|
if (memcmp(enm->enm_addrlo, enm->enm_addrhi,
|
2007-05-29 22:32:07 +04:00
|
|
|
ETHER_ADDR_LEN) != 0) {
|
|
|
|
ifp->if_flags |= IFF_ALLMULTI;
|
|
|
|
break;
|
|
|
|
}
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
hash = rtw_calchash(enm->enm_addrlo);
|
2005-01-03 06:07:12 +03:00
|
|
|
hashes[hash >> 5] |= (1 << (hash & 0x1f));
|
2004-09-26 06:29:15 +04:00
|
|
|
ETHER_NEXT_MULTI(step, enm);
|
|
|
|
}
|
|
|
|
|
2007-05-29 22:32:07 +04:00
|
|
|
/* XXX accept all broadcast if scanning */
|
|
|
|
if ((ifp->if_flags & IFF_BROADCAST) != 0)
|
|
|
|
sc->sc_rcr |= RTW_RCR_AB; /* accept all broadcast */
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2007-05-29 22:32:07 +04:00
|
|
|
if (ifp->if_flags & IFF_PROMISC) {
|
|
|
|
sc->sc_rcr |= RTW_RCR_AB; /* accept all broadcast */
|
2007-11-17 02:35:19 +03:00
|
|
|
sc->sc_rcr |= RTW_RCR_ACRC32; /* accept frames failing CRC */
|
|
|
|
sc->sc_rcr |= RTW_RCR_AICV; /* accept frames failing ICV */
|
2007-05-29 22:32:07 +04:00
|
|
|
ifp->if_flags |= IFF_ALLMULTI;
|
2005-01-03 06:07:12 +03:00
|
|
|
}
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2007-05-29 22:32:07 +04:00
|
|
|
if (ifp->if_flags & IFF_ALLMULTI)
|
|
|
|
hashes[0] = hashes[1] = 0xffffffff;
|
|
|
|
|
|
|
|
if ((hashes[0] | hashes[1]) != 0)
|
|
|
|
sc->sc_rcr |= RTW_RCR_AM; /* accept multicast */
|
|
|
|
|
2004-09-26 06:29:15 +04:00
|
|
|
RTW_WRITE(regs, RTW_MAR0, hashes[0]);
|
|
|
|
RTW_WRITE(regs, RTW_MAR1, hashes[1]);
|
|
|
|
RTW_WRITE(regs, RTW_RCR, sc->sc_rcr);
|
|
|
|
RTW_SYNC(regs, RTW_MAR0, RTW_RCR); /* RTW_MAR0 < RTW_MAR1 < RTW_RCR */
|
|
|
|
|
2004-12-25 09:58:37 +03:00
|
|
|
DPRINTF(sc, RTW_DEBUG_PKTFILT,
|
|
|
|
("%s: RTW_MAR0 %08x RTW_MAR1 %08x RTW_RCR %08x\n",
|
2007-12-21 21:22:43 +03:00
|
|
|
device_xname(sc->sc_dev), RTW_READ(regs, RTW_MAR0),
|
2004-09-26 06:29:15 +04:00
|
|
|
RTW_READ(regs, RTW_MAR1), RTW_READ(regs, RTW_RCR)));
|
|
|
|
}
|
|
|
|
|
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
|
|
|
static struct mbuf *
|
|
|
|
rtw_beacon_alloc(struct rtw_softc *sc, struct ieee80211_node *ni)
|
|
|
|
{
|
|
|
|
struct ieee80211com *ic = &sc->sc_ic;
|
|
|
|
struct mbuf *m;
|
2005-06-22 10:14:51 +04:00
|
|
|
struct ieee80211_beacon_offsets boff;
|
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
|
|
|
|
2005-11-23 07:12:33 +03:00
|
|
|
if ((m = ieee80211_beacon_alloc(ic, ni, &boff)) != NULL) {
|
|
|
|
RTW_DPRINTF(RTW_DEBUG_BEACON,
|
|
|
|
("%s: m %p len %u\n", __func__, m, m->m_len));
|
|
|
|
}
|
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
|
|
|
return m;
|
|
|
|
}
|
|
|
|
|
2004-12-25 09:58:37 +03:00
|
|
|
/* Must be called at splnet. */
|
2004-09-26 06:29:15 +04:00
|
|
|
static int
|
|
|
|
rtw_init(struct ifnet *ifp)
|
|
|
|
{
|
|
|
|
struct rtw_softc *sc = (struct rtw_softc *)ifp->if_softc;
|
|
|
|
struct ieee80211com *ic = &sc->sc_ic;
|
|
|
|
struct rtw_regs *regs = &sc->sc_regs;
|
Use device_t and its accessors throughout. Use aprint_*_dev().
Improve PMF-ability.
Add a 'flags' argument to suspend/resume handlers and
callers such as pmf_system_suspend().
Define a flag, PMF_F_SELF, which indicates to PMF that a
device is suspending/resuming itself. Add helper routines,
pmf_device_suspend_self(dev) and pmf_device_resume_self(dev),
that call pmf_device_suspend(dev, PMF_F_SELF) and
pmf_device_resume(dev, PMF_F_SELF), respectively. Use
PMF_F_SELF to suspend/resume self in ath(4), audio(4),
rtw(4), and sip(4).
In ath(4) and in rtw(4), replace the icky sc_enable/sc_disable
callbacks, provided by the bus front-end, with
self-suspension/resumption. Also, clean up the bus
front-ends. Make sure that the interrupt handler is
disestablished during suspension. Get rid of driver-private
flags (e.g., RTW_F_ENABLED, ath_softc->sc_invalid); use
device_is_active()/device_has_power() calls, instead.
In the network-class suspend handler, call if_stop(, 0)
instead of if_stop(, 1), because the latter is superfluous
(bus- and driver-suspension hooks will 'disable' the NIC),
and it may cause recursion.
In the network-class resume handler, prevent infinite
recursion through if_init() by getting out early if we are
self-suspending (PMF_F_SELF).
rtw(4) improvements:
Destroy rtw(4) callouts when we detach it. Make rtw at
pci detachable. Print some more information with the "rx
frame too long" warning.
Remove activate() methods:
Get rid of rtw_activate() and ath_activate(). The device
activate() methods are not good for much these days.
Make ath at cardbus resume with crypto functions intact:
Introduce a boolean device property, "pmf-powerdown". If
pmf-powerdown is present and false, it indicates that a
bus back-end should not remove power from a device.
Honor this property in cardbus_child_suspend().
Set this property to 'false' in ath_attach(), since removing
power from an ath at cardbus seems to lobotomize the WPA
crypto engine. XXX Should the pmf-powerdown property
propagate toward the root of the device tree?
Miscellaneous ath(4) changes:
Warn if ath(4) tries to write crypto keys to suspended
hardware.
Reduce differences between FreeBSD and NetBSD in ath(4)
multicast filter setup.
Make ath_printrxbuf() print an rx descriptor's status &
key index, to help debug crypto errors.
Shorten a staircase in ath_ioctl(). Don't check for
ieee80211_ioctl() return code ERESTART, it never happens.
2008-03-12 21:02:21 +03:00
|
|
|
int rc;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
Use device_t and its accessors throughout. Use aprint_*_dev().
Improve PMF-ability.
Add a 'flags' argument to suspend/resume handlers and
callers such as pmf_system_suspend().
Define a flag, PMF_F_SELF, which indicates to PMF that a
device is suspending/resuming itself. Add helper routines,
pmf_device_suspend_self(dev) and pmf_device_resume_self(dev),
that call pmf_device_suspend(dev, PMF_F_SELF) and
pmf_device_resume(dev, PMF_F_SELF), respectively. Use
PMF_F_SELF to suspend/resume self in ath(4), audio(4),
rtw(4), and sip(4).
In ath(4) and in rtw(4), replace the icky sc_enable/sc_disable
callbacks, provided by the bus front-end, with
self-suspension/resumption. Also, clean up the bus
front-ends. Make sure that the interrupt handler is
disestablished during suspension. Get rid of driver-private
flags (e.g., RTW_F_ENABLED, ath_softc->sc_invalid); use
device_is_active()/device_has_power() calls, instead.
In the network-class suspend handler, call if_stop(, 0)
instead of if_stop(, 1), because the latter is superfluous
(bus- and driver-suspension hooks will 'disable' the NIC),
and it may cause recursion.
In the network-class resume handler, prevent infinite
recursion through if_init() by getting out early if we are
self-suspending (PMF_F_SELF).
rtw(4) improvements:
Destroy rtw(4) callouts when we detach it. Make rtw at
pci detachable. Print some more information with the "rx
frame too long" warning.
Remove activate() methods:
Get rid of rtw_activate() and ath_activate(). The device
activate() methods are not good for much these days.
Make ath at cardbus resume with crypto functions intact:
Introduce a boolean device property, "pmf-powerdown". If
pmf-powerdown is present and false, it indicates that a
bus back-end should not remove power from a device.
Honor this property in cardbus_child_suspend().
Set this property to 'false' in ath_attach(), since removing
power from an ath at cardbus seems to lobotomize the WPA
crypto engine. XXX Should the pmf-powerdown property
propagate toward the root of the device tree?
Miscellaneous ath(4) changes:
Warn if ath(4) tries to write crypto keys to suspended
hardware.
Reduce differences between FreeBSD and NetBSD in ath(4)
multicast filter setup.
Make ath_printrxbuf() print an rx descriptor's status &
key index, to help debug crypto errors.
Shorten a staircase in ath_ioctl(). Don't check for
ieee80211_ioctl() return code ERESTART, it never happens.
2008-03-12 21:02:21 +03:00
|
|
|
if (device_is_active(sc->sc_dev)) {
|
|
|
|
/* Cancel pending I/O and reset. */
|
|
|
|
rtw_stop(ifp, 0);
|
In pmf(9), improve the implementation of device self-suspension
and make suspension by self, by drvctl(8), and by ACPI system sleep
play nice together. Start solidifying some temporary API changes.
1. Extract a new header file, <sys/device_if.h>, from <sys/device.h> and
#include it from <sys/pmf.h> instead of <sys/device.h> to break the
circular dependency between <sys/device.h> and <sys/pmf.h>.
2. Introduce pmf_qual_t, an aggregate of qualifications on a PMF
suspend/resume call. Start to replace instances of PMF_FN_PROTO,
PMF_FN_ARGS, et cetera, with a pmf_qual_t.
3. Introduce the notion of a "suspensor," an entity that holds a
device in suspension. More than one suspensor may hold a device
at once. A device stays suspended as long as at least one
suspensor holds it. A device resumes when the last suspensor
releases it.
Currently, the kernel defines three suspensors,
3a the system-suspensor: for system suspension, initiated
by 'sysctl -w machdep.sleep_state=3', by lid closure, by
power-button press, et cetera,
3b the drvctl-suspensor: for device suspension by /dev/drvctl
ioctl, e.g., drvctl -S sip0.
3c the system self-suspensor: for device drivers that suspend
themselves and their children. Several drivers for network
interfaces put the network device to sleep while it is not
administratively up, that is, after the kernel calls if_stop(,
1). The self-suspensor should not be used directly. See
the description of suspensor delegates, below.
A suspensor can have one or more "delegates". A suspensor can
release devices that its delegates hold suspended. Right now,
only the system self-suspensor has delegates. For each device
that a self-suspending driver attaches, it creates the device's
self-suspensor, a delegate of the system self-suspensor.
Suspensors stop a system-wide suspend/resume cycle from waking
devices that the operator put to sleep with drvctl before the cycle.
They also help self-suspension to work more simply, safely, and in
accord with expectations.
4. Add the notion of device activation level, devact_level_t,
and a routine for checking the current activation level,
device_activation(). Current activation levels are DEVACT_LEVEL_BUS,
DEVACT_LEVEL_DRIVER, and DEVACT_LEVEL_CLASS, which respectively
indicate that the device's bus is active, that the bus and device are
active, and that the bus, device, and the functions of the device's
class (network, audio) are active.
Suspend/resume calls can be qualified with a devact_level_t.
The power-management framework treats a devact_level_t that
qualifies a device suspension as the device's current activation
level; it only runs hooks to reduce the activation level from
the presumed current level to the fully suspended state. The
framework treats a devact_level_t qualifying device resumption
as the target activation level; it only runs hooks to raise the
activation level to the target.
5. Use pmf_qual_t, devact_level_t, and self-suspensors in several
drivers.
6. Temporarily add an unused power-management workqueue that I will
remove or replace, soon.
2009-09-16 20:34:49 +04:00
|
|
|
} else if (!pmf_device_resume(sc->sc_dev, &sc->sc_qual) ||
|
|
|
|
!device_is_active(sc->sc_dev))
|
|
|
|
return 0;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2004-12-25 09:58:37 +03:00
|
|
|
DPRINTF(sc, RTW_DEBUG_TUNE, ("%s: channel %d freq %d flags 0x%04x\n",
|
2005-11-18 19:53:56 +03:00
|
|
|
__func__, ieee80211_chan2ieee(ic, ic->ic_curchan),
|
|
|
|
ic->ic_curchan->ic_freq, ic->ic_curchan->ic_flags));
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
if ((rc = rtw_pwrstate(sc, RTW_OFF)) != 0)
|
|
|
|
goto out;
|
|
|
|
|
If defined(RTW_DEBUG), provide a sysctl (hw.rtw.rxbufs_limit) for
limiting the number of rx buffers an rtw may allocate. Use this
sysctl to test the code that copes with buffer exhaustion.
Allocate at most RTW_RXQLEN rx buffers, stopping at the sysctl
limit. Record in sc_nrxdesc how many were allocated, and put the
end-of-ring indication on sc_rxdesc[sc_nrxdesc - 1]. In rtw_init,
if no rx buffers could be allocated, log a complaint, clear
IFF_RUNNING, and exit with an error.
Many changes to accomodate a short rx ring, mainly of the "add a
rx-ring length argument" variety. XXX I really should consolidate
all of the rx ring variables in one struct and pass that to the
rx-ring subroutines.
Bug fix: after calling MCLGET, use the (m->m_flags & M_EXT) idiom
to check for success, instead of m != NULL.
Bug fix: at the top of rtw_start, if IFF_RUNNING is not set, or
IFF_OACTIVE is, get out.
2004-12-29 01:21:15 +03:00
|
|
|
if ((rc = rtw_swring_setup(sc)) != 0)
|
|
|
|
goto out;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
rtw_transmit_config(regs);
|
|
|
|
|
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
|
|
|
rtw_set_access(regs, RTW_ACCESS_CONFIG);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
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
|
|
|
RTW_WRITE8(regs, RTW_MSR, 0x0); /* no link */
|
2004-12-20 04:13:45 +03:00
|
|
|
RTW_WBW(regs, RTW_MSR, RTW_BRSR);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2004-12-27 12:40:18 +03:00
|
|
|
/* long PLCP header, 1Mb/2Mb basic rate */
|
|
|
|
RTW_WRITE16(regs, RTW_BRSR, RTW_BRSR_MBR8180_2MBPS);
|
2004-12-20 04:13:45 +03:00
|
|
|
RTW_SYNC(regs, RTW_BRSR, RTW_BRSR);
|
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
|
|
|
rtw_set_access(regs, RTW_ACCESS_ANAPARM);
|
|
|
|
rtw_set_access(regs, RTW_ACCESS_NONE);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
/* XXX from reference sources */
|
|
|
|
RTW_WRITE(regs, RTW_FEMR, 0xffff);
|
2004-12-20 04:13:45 +03:00
|
|
|
RTW_SYNC(regs, RTW_FEMR, RTW_FEMR);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2007-12-21 21:22:43 +03:00
|
|
|
rtw_set_rfprog(regs, sc->sc_rfchipid, sc->sc_dev);
|
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
|
|
|
|
|
|
|
RTW_WRITE8(regs, RTW_PHYDELAY, sc->sc_phydelay);
|
2004-09-26 06:29:15 +04:00
|
|
|
/* from Linux driver */
|
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
|
|
|
RTW_WRITE8(regs, RTW_CRCOUNT, RTW_CRCOUNT_MAGIC);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2004-12-20 04:13:45 +03:00
|
|
|
RTW_SYNC(regs, RTW_PHYDELAY, RTW_CRCOUNT);
|
|
|
|
|
2004-09-26 06:29:15 +04:00
|
|
|
rtw_enable_interrupts(sc);
|
|
|
|
|
|
|
|
rtw_pktfilt_load(sc);
|
|
|
|
|
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
|
|
|
rtw_hwring_setup(sc);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2005-06-22 10:14:51 +04:00
|
|
|
rtw_wep_setkeys(sc, ic->ic_nw_keys, ic->ic_def_txkey);
|
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
|
|
|
|
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
|
|
|
rtw_io_enable(sc, RTW_CR_RE | RTW_CR_TE, 1);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
ifp->if_flags |= IFF_RUNNING;
|
|
|
|
ic->ic_state = IEEE80211_S_INIT;
|
|
|
|
|
|
|
|
RTW_WRITE16(regs, RTW_BSSID16, 0x0);
|
|
|
|
RTW_WRITE(regs, RTW_BSSID32, 0x0);
|
|
|
|
|
|
|
|
rtw_resume_ticks(sc);
|
|
|
|
|
2004-12-21 02:05:41 +03:00
|
|
|
rtw_set_nettype(sc, IEEE80211_M_MONITOR);
|
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
|
|
|
|
|
|
|
if (ic->ic_opmode == IEEE80211_M_MONITOR)
|
|
|
|
return ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
|
|
|
|
else
|
|
|
|
return ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
|
|
|
|
|
2004-09-26 06:29:15 +04:00
|
|
|
out:
|
2007-12-21 21:22:43 +03:00
|
|
|
aprint_error_dev(sc->sc_dev, "interface not running\n");
|
2004-09-26 06:29:15 +04:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
2005-12-24 23:27:29 +03:00
|
|
|
static inline void
|
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
|
|
|
rtw_led_init(struct rtw_regs *regs)
|
|
|
|
{
|
|
|
|
uint8_t cfg0, cfg1;
|
|
|
|
|
|
|
|
rtw_set_access(regs, RTW_ACCESS_CONFIG);
|
|
|
|
|
|
|
|
cfg0 = RTW_READ8(regs, RTW_CONFIG0);
|
|
|
|
cfg0 |= RTW_CONFIG0_LEDGPOEN;
|
|
|
|
RTW_WRITE8(regs, RTW_CONFIG0, cfg0);
|
|
|
|
|
|
|
|
cfg1 = RTW_READ8(regs, RTW_CONFIG1);
|
|
|
|
RTW_DPRINTF(RTW_DEBUG_LED,
|
|
|
|
("%s: read %" PRIx8 " from reg[CONFIG1]\n", __func__, cfg1));
|
|
|
|
|
|
|
|
cfg1 &= ~RTW_CONFIG1_LEDS_MASK;
|
|
|
|
cfg1 |= RTW_CONFIG1_LEDS_TX_RX;
|
|
|
|
RTW_WRITE8(regs, RTW_CONFIG1, cfg1);
|
|
|
|
|
|
|
|
rtw_set_access(regs, RTW_ACCESS_NONE);
|
|
|
|
}
|
|
|
|
|
2005-02-27 03:26:58 +03: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
|
|
|
* IEEE80211_S_INIT: LED1 off
|
|
|
|
*
|
|
|
|
* IEEE80211_S_AUTH,
|
|
|
|
* IEEE80211_S_ASSOC,
|
|
|
|
* IEEE80211_S_SCAN: LED1 blinks @ 1 Hz, blinks at 5Hz for tx/rx
|
|
|
|
*
|
|
|
|
* IEEE80211_S_RUN: LED1 on, blinks @ 5Hz for tx/rx
|
|
|
|
*/
|
|
|
|
static void
|
|
|
|
rtw_led_newstate(struct rtw_softc *sc, enum ieee80211_state nstate)
|
|
|
|
{
|
|
|
|
struct rtw_led_state *ls;
|
|
|
|
|
|
|
|
ls = &sc->sc_led_state;
|
|
|
|
|
|
|
|
switch (nstate) {
|
|
|
|
case IEEE80211_S_INIT:
|
|
|
|
rtw_led_init(&sc->sc_regs);
|
Use device_t and its accessors throughout. Use aprint_*_dev().
Improve PMF-ability.
Add a 'flags' argument to suspend/resume handlers and
callers such as pmf_system_suspend().
Define a flag, PMF_F_SELF, which indicates to PMF that a
device is suspending/resuming itself. Add helper routines,
pmf_device_suspend_self(dev) and pmf_device_resume_self(dev),
that call pmf_device_suspend(dev, PMF_F_SELF) and
pmf_device_resume(dev, PMF_F_SELF), respectively. Use
PMF_F_SELF to suspend/resume self in ath(4), audio(4),
rtw(4), and sip(4).
In ath(4) and in rtw(4), replace the icky sc_enable/sc_disable
callbacks, provided by the bus front-end, with
self-suspension/resumption. Also, clean up the bus
front-ends. Make sure that the interrupt handler is
disestablished during suspension. Get rid of driver-private
flags (e.g., RTW_F_ENABLED, ath_softc->sc_invalid); use
device_is_active()/device_has_power() calls, instead.
In the network-class suspend handler, call if_stop(, 0)
instead of if_stop(, 1), because the latter is superfluous
(bus- and driver-suspension hooks will 'disable' the NIC),
and it may cause recursion.
In the network-class resume handler, prevent infinite
recursion through if_init() by getting out early if we are
self-suspending (PMF_F_SELF).
rtw(4) improvements:
Destroy rtw(4) callouts when we detach it. Make rtw at
pci detachable. Print some more information with the "rx
frame too long" warning.
Remove activate() methods:
Get rid of rtw_activate() and ath_activate(). The device
activate() methods are not good for much these days.
Make ath at cardbus resume with crypto functions intact:
Introduce a boolean device property, "pmf-powerdown". If
pmf-powerdown is present and false, it indicates that a
bus back-end should not remove power from a device.
Honor this property in cardbus_child_suspend().
Set this property to 'false' in ath_attach(), since removing
power from an ath at cardbus seems to lobotomize the WPA
crypto engine. XXX Should the pmf-powerdown property
propagate toward the root of the device tree?
Miscellaneous ath(4) changes:
Warn if ath(4) tries to write crypto keys to suspended
hardware.
Reduce differences between FreeBSD and NetBSD in ath(4)
multicast filter setup.
Make ath_printrxbuf() print an rx descriptor's status &
key index, to help debug crypto errors.
Shorten a staircase in ath_ioctl(). Don't check for
ieee80211_ioctl() return code ERESTART, it never happens.
2008-03-12 21:02:21 +03:00
|
|
|
aprint_debug_dev(sc->sc_dev, "stopping blink\n");
|
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
|
|
|
callout_stop(&ls->ls_slow_ch);
|
|
|
|
callout_stop(&ls->ls_fast_ch);
|
|
|
|
ls->ls_slowblink = 0;
|
|
|
|
ls->ls_actblink = 0;
|
|
|
|
ls->ls_default = 0;
|
|
|
|
break;
|
|
|
|
case IEEE80211_S_SCAN:
|
Use device_t and its accessors throughout. Use aprint_*_dev().
Improve PMF-ability.
Add a 'flags' argument to suspend/resume handlers and
callers such as pmf_system_suspend().
Define a flag, PMF_F_SELF, which indicates to PMF that a
device is suspending/resuming itself. Add helper routines,
pmf_device_suspend_self(dev) and pmf_device_resume_self(dev),
that call pmf_device_suspend(dev, PMF_F_SELF) and
pmf_device_resume(dev, PMF_F_SELF), respectively. Use
PMF_F_SELF to suspend/resume self in ath(4), audio(4),
rtw(4), and sip(4).
In ath(4) and in rtw(4), replace the icky sc_enable/sc_disable
callbacks, provided by the bus front-end, with
self-suspension/resumption. Also, clean up the bus
front-ends. Make sure that the interrupt handler is
disestablished during suspension. Get rid of driver-private
flags (e.g., RTW_F_ENABLED, ath_softc->sc_invalid); use
device_is_active()/device_has_power() calls, instead.
In the network-class suspend handler, call if_stop(, 0)
instead of if_stop(, 1), because the latter is superfluous
(bus- and driver-suspension hooks will 'disable' the NIC),
and it may cause recursion.
In the network-class resume handler, prevent infinite
recursion through if_init() by getting out early if we are
self-suspending (PMF_F_SELF).
rtw(4) improvements:
Destroy rtw(4) callouts when we detach it. Make rtw at
pci detachable. Print some more information with the "rx
frame too long" warning.
Remove activate() methods:
Get rid of rtw_activate() and ath_activate(). The device
activate() methods are not good for much these days.
Make ath at cardbus resume with crypto functions intact:
Introduce a boolean device property, "pmf-powerdown". If
pmf-powerdown is present and false, it indicates that a
bus back-end should not remove power from a device.
Honor this property in cardbus_child_suspend().
Set this property to 'false' in ath_attach(), since removing
power from an ath at cardbus seems to lobotomize the WPA
crypto engine. XXX Should the pmf-powerdown property
propagate toward the root of the device tree?
Miscellaneous ath(4) changes:
Warn if ath(4) tries to write crypto keys to suspended
hardware.
Reduce differences between FreeBSD and NetBSD in ath(4)
multicast filter setup.
Make ath_printrxbuf() print an rx descriptor's status &
key index, to help debug crypto errors.
Shorten a staircase in ath_ioctl(). Don't check for
ieee80211_ioctl() return code ERESTART, it never happens.
2008-03-12 21:02:21 +03:00
|
|
|
aprint_debug_dev(sc->sc_dev, "scheduling blink\n");
|
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
|
|
|
callout_schedule(&ls->ls_slow_ch, RTW_LED_SLOW_TICKS);
|
|
|
|
callout_schedule(&ls->ls_fast_ch, RTW_LED_FAST_TICKS);
|
|
|
|
/*FALLTHROUGH*/
|
|
|
|
case IEEE80211_S_AUTH:
|
|
|
|
case IEEE80211_S_ASSOC:
|
|
|
|
ls->ls_default = RTW_LED1;
|
|
|
|
ls->ls_actblink = RTW_LED1;
|
|
|
|
ls->ls_slowblink = RTW_LED1;
|
|
|
|
break;
|
|
|
|
case IEEE80211_S_RUN:
|
|
|
|
ls->ls_slowblink = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
rtw_led_set(ls, &sc->sc_regs, sc->sc_hwverid);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
rtw_led_set(struct rtw_led_state *ls, struct rtw_regs *regs, int hwverid)
|
|
|
|
{
|
|
|
|
uint8_t led_condition;
|
|
|
|
bus_size_t ofs;
|
|
|
|
uint8_t mask, newval, val;
|
|
|
|
|
|
|
|
led_condition = ls->ls_default;
|
|
|
|
|
|
|
|
if (ls->ls_state & RTW_LED_S_SLOW)
|
|
|
|
led_condition ^= ls->ls_slowblink;
|
|
|
|
if (ls->ls_state & (RTW_LED_S_RX|RTW_LED_S_TX))
|
|
|
|
led_condition ^= ls->ls_actblink;
|
|
|
|
|
|
|
|
RTW_DPRINTF(RTW_DEBUG_LED,
|
|
|
|
("%s: LED condition %" PRIx8 "\n", __func__, led_condition));
|
|
|
|
|
|
|
|
switch (hwverid) {
|
|
|
|
default:
|
|
|
|
case 'F':
|
|
|
|
ofs = RTW_PSR;
|
|
|
|
newval = mask = RTW_PSR_LEDGPO0 | RTW_PSR_LEDGPO1;
|
|
|
|
if (led_condition & RTW_LED0)
|
|
|
|
newval &= ~RTW_PSR_LEDGPO0;
|
|
|
|
if (led_condition & RTW_LED1)
|
|
|
|
newval &= ~RTW_PSR_LEDGPO1;
|
|
|
|
break;
|
|
|
|
case 'D':
|
|
|
|
ofs = RTW_9346CR;
|
|
|
|
mask = RTW_9346CR_EEM_MASK | RTW_9346CR_EEDI | RTW_9346CR_EECS;
|
|
|
|
newval = RTW_9346CR_EEM_PROGRAM;
|
|
|
|
if (led_condition & RTW_LED0)
|
|
|
|
newval |= RTW_9346CR_EEDI;
|
|
|
|
if (led_condition & RTW_LED1)
|
|
|
|
newval |= RTW_9346CR_EECS;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
val = RTW_READ8(regs, ofs);
|
|
|
|
RTW_DPRINTF(RTW_DEBUG_LED,
|
2005-03-02 08:20:43 +03:00
|
|
|
("%s: read %" PRIx8 " from reg[%#02" PRIxPTR "]\n", __func__, val,
|
|
|
|
(uintptr_t)ofs));
|
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
|
|
|
val &= ~mask;
|
|
|
|
val |= newval;
|
|
|
|
RTW_WRITE8(regs, ofs, val);
|
|
|
|
RTW_DPRINTF(RTW_DEBUG_LED,
|
2005-03-02 08:20:43 +03:00
|
|
|
("%s: wrote %" PRIx8 " to reg[%#02" PRIxPTR "]\n", __func__, val,
|
|
|
|
(uintptr_t)ofs));
|
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
|
|
|
RTW_SYNC(regs, ofs, ofs);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
rtw_led_fastblink(void *arg)
|
|
|
|
{
|
|
|
|
int ostate, s;
|
|
|
|
struct rtw_softc *sc = (struct rtw_softc *)arg;
|
|
|
|
struct rtw_led_state *ls = &sc->sc_led_state;
|
|
|
|
|
|
|
|
s = splnet();
|
|
|
|
ostate = ls->ls_state;
|
|
|
|
ls->ls_state ^= ls->ls_event;
|
|
|
|
|
|
|
|
if ((ls->ls_event & RTW_LED_S_TX) == 0)
|
|
|
|
ls->ls_state &= ~RTW_LED_S_TX;
|
|
|
|
|
|
|
|
if ((ls->ls_event & RTW_LED_S_RX) == 0)
|
|
|
|
ls->ls_state &= ~RTW_LED_S_RX;
|
|
|
|
|
|
|
|
ls->ls_event = 0;
|
|
|
|
|
|
|
|
if (ostate != ls->ls_state)
|
|
|
|
rtw_led_set(ls, &sc->sc_regs, sc->sc_hwverid);
|
|
|
|
splx(s);
|
|
|
|
|
Use device_t and its accessors throughout. Use aprint_*_dev().
Improve PMF-ability.
Add a 'flags' argument to suspend/resume handlers and
callers such as pmf_system_suspend().
Define a flag, PMF_F_SELF, which indicates to PMF that a
device is suspending/resuming itself. Add helper routines,
pmf_device_suspend_self(dev) and pmf_device_resume_self(dev),
that call pmf_device_suspend(dev, PMF_F_SELF) and
pmf_device_resume(dev, PMF_F_SELF), respectively. Use
PMF_F_SELF to suspend/resume self in ath(4), audio(4),
rtw(4), and sip(4).
In ath(4) and in rtw(4), replace the icky sc_enable/sc_disable
callbacks, provided by the bus front-end, with
self-suspension/resumption. Also, clean up the bus
front-ends. Make sure that the interrupt handler is
disestablished during suspension. Get rid of driver-private
flags (e.g., RTW_F_ENABLED, ath_softc->sc_invalid); use
device_is_active()/device_has_power() calls, instead.
In the network-class suspend handler, call if_stop(, 0)
instead of if_stop(, 1), because the latter is superfluous
(bus- and driver-suspension hooks will 'disable' the NIC),
and it may cause recursion.
In the network-class resume handler, prevent infinite
recursion through if_init() by getting out early if we are
self-suspending (PMF_F_SELF).
rtw(4) improvements:
Destroy rtw(4) callouts when we detach it. Make rtw at
pci detachable. Print some more information with the "rx
frame too long" warning.
Remove activate() methods:
Get rid of rtw_activate() and ath_activate(). The device
activate() methods are not good for much these days.
Make ath at cardbus resume with crypto functions intact:
Introduce a boolean device property, "pmf-powerdown". If
pmf-powerdown is present and false, it indicates that a
bus back-end should not remove power from a device.
Honor this property in cardbus_child_suspend().
Set this property to 'false' in ath_attach(), since removing
power from an ath at cardbus seems to lobotomize the WPA
crypto engine. XXX Should the pmf-powerdown property
propagate toward the root of the device tree?
Miscellaneous ath(4) changes:
Warn if ath(4) tries to write crypto keys to suspended
hardware.
Reduce differences between FreeBSD and NetBSD in ath(4)
multicast filter setup.
Make ath_printrxbuf() print an rx descriptor's status &
key index, to help debug crypto errors.
Shorten a staircase in ath_ioctl(). Don't check for
ieee80211_ioctl() return code ERESTART, it never happens.
2008-03-12 21:02:21 +03:00
|
|
|
aprint_debug_dev(sc->sc_dev, "scheduling fast blink\n");
|
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
|
|
|
callout_schedule(&ls->ls_fast_ch, RTW_LED_FAST_TICKS);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
rtw_led_slowblink(void *arg)
|
|
|
|
{
|
|
|
|
int s;
|
|
|
|
struct rtw_softc *sc = (struct rtw_softc *)arg;
|
|
|
|
struct rtw_led_state *ls = &sc->sc_led_state;
|
|
|
|
|
|
|
|
s = splnet();
|
|
|
|
ls->ls_state ^= RTW_LED_S_SLOW;
|
|
|
|
rtw_led_set(ls, &sc->sc_regs, sc->sc_hwverid);
|
|
|
|
splx(s);
|
Use device_t and its accessors throughout. Use aprint_*_dev().
Improve PMF-ability.
Add a 'flags' argument to suspend/resume handlers and
callers such as pmf_system_suspend().
Define a flag, PMF_F_SELF, which indicates to PMF that a
device is suspending/resuming itself. Add helper routines,
pmf_device_suspend_self(dev) and pmf_device_resume_self(dev),
that call pmf_device_suspend(dev, PMF_F_SELF) and
pmf_device_resume(dev, PMF_F_SELF), respectively. Use
PMF_F_SELF to suspend/resume self in ath(4), audio(4),
rtw(4), and sip(4).
In ath(4) and in rtw(4), replace the icky sc_enable/sc_disable
callbacks, provided by the bus front-end, with
self-suspension/resumption. Also, clean up the bus
front-ends. Make sure that the interrupt handler is
disestablished during suspension. Get rid of driver-private
flags (e.g., RTW_F_ENABLED, ath_softc->sc_invalid); use
device_is_active()/device_has_power() calls, instead.
In the network-class suspend handler, call if_stop(, 0)
instead of if_stop(, 1), because the latter is superfluous
(bus- and driver-suspension hooks will 'disable' the NIC),
and it may cause recursion.
In the network-class resume handler, prevent infinite
recursion through if_init() by getting out early if we are
self-suspending (PMF_F_SELF).
rtw(4) improvements:
Destroy rtw(4) callouts when we detach it. Make rtw at
pci detachable. Print some more information with the "rx
frame too long" warning.
Remove activate() methods:
Get rid of rtw_activate() and ath_activate(). The device
activate() methods are not good for much these days.
Make ath at cardbus resume with crypto functions intact:
Introduce a boolean device property, "pmf-powerdown". If
pmf-powerdown is present and false, it indicates that a
bus back-end should not remove power from a device.
Honor this property in cardbus_child_suspend().
Set this property to 'false' in ath_attach(), since removing
power from an ath at cardbus seems to lobotomize the WPA
crypto engine. XXX Should the pmf-powerdown property
propagate toward the root of the device tree?
Miscellaneous ath(4) changes:
Warn if ath(4) tries to write crypto keys to suspended
hardware.
Reduce differences between FreeBSD and NetBSD in ath(4)
multicast filter setup.
Make ath_printrxbuf() print an rx descriptor's status &
key index, to help debug crypto errors.
Shorten a staircase in ath_ioctl(). Don't check for
ieee80211_ioctl() return code ERESTART, it never happens.
2008-03-12 21:02:21 +03:00
|
|
|
aprint_debug_dev(sc->sc_dev, "scheduling slow blink\n");
|
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
|
|
|
callout_schedule(&ls->ls_slow_ch, RTW_LED_SLOW_TICKS);
|
|
|
|
}
|
|
|
|
|
Use device_t and its accessors throughout. Use aprint_*_dev().
Improve PMF-ability.
Add a 'flags' argument to suspend/resume handlers and
callers such as pmf_system_suspend().
Define a flag, PMF_F_SELF, which indicates to PMF that a
device is suspending/resuming itself. Add helper routines,
pmf_device_suspend_self(dev) and pmf_device_resume_self(dev),
that call pmf_device_suspend(dev, PMF_F_SELF) and
pmf_device_resume(dev, PMF_F_SELF), respectively. Use
PMF_F_SELF to suspend/resume self in ath(4), audio(4),
rtw(4), and sip(4).
In ath(4) and in rtw(4), replace the icky sc_enable/sc_disable
callbacks, provided by the bus front-end, with
self-suspension/resumption. Also, clean up the bus
front-ends. Make sure that the interrupt handler is
disestablished during suspension. Get rid of driver-private
flags (e.g., RTW_F_ENABLED, ath_softc->sc_invalid); use
device_is_active()/device_has_power() calls, instead.
In the network-class suspend handler, call if_stop(, 0)
instead of if_stop(, 1), because the latter is superfluous
(bus- and driver-suspension hooks will 'disable' the NIC),
and it may cause recursion.
In the network-class resume handler, prevent infinite
recursion through if_init() by getting out early if we are
self-suspending (PMF_F_SELF).
rtw(4) improvements:
Destroy rtw(4) callouts when we detach it. Make rtw at
pci detachable. Print some more information with the "rx
frame too long" warning.
Remove activate() methods:
Get rid of rtw_activate() and ath_activate(). The device
activate() methods are not good for much these days.
Make ath at cardbus resume with crypto functions intact:
Introduce a boolean device property, "pmf-powerdown". If
pmf-powerdown is present and false, it indicates that a
bus back-end should not remove power from a device.
Honor this property in cardbus_child_suspend().
Set this property to 'false' in ath_attach(), since removing
power from an ath at cardbus seems to lobotomize the WPA
crypto engine. XXX Should the pmf-powerdown property
propagate toward the root of the device tree?
Miscellaneous ath(4) changes:
Warn if ath(4) tries to write crypto keys to suspended
hardware.
Reduce differences between FreeBSD and NetBSD in ath(4)
multicast filter setup.
Make ath_printrxbuf() print an rx descriptor's status &
key index, to help debug crypto errors.
Shorten a staircase in ath_ioctl(). Don't check for
ieee80211_ioctl() return code ERESTART, it never happens.
2008-03-12 21:02:21 +03:00
|
|
|
static void
|
|
|
|
rtw_led_detach(struct rtw_led_state *ls)
|
|
|
|
{
|
|
|
|
callout_destroy(&ls->ls_fast_ch);
|
|
|
|
callout_destroy(&ls->ls_slow_ch);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2005-03-02 08:20:43 +03:00
|
|
|
rtw_led_attach(struct rtw_led_state *ls, void *arg)
|
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
|
|
|
{
|
2007-07-10 00:51:58 +04:00
|
|
|
callout_init(&ls->ls_fast_ch, 0);
|
|
|
|
callout_init(&ls->ls_slow_ch, 0);
|
2005-03-02 08:20:43 +03:00
|
|
|
callout_setfunc(&ls->ls_fast_ch, rtw_led_fastblink, arg);
|
|
|
|
callout_setfunc(&ls->ls_slow_ch, rtw_led_slowblink, arg);
|
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
|
|
|
}
|
|
|
|
|
2004-09-26 06:29:15 +04:00
|
|
|
static int
|
2007-03-04 08:59:00 +03:00
|
|
|
rtw_ioctl(struct ifnet *ifp, u_long cmd, void *data)
|
2004-09-26 06:29:15 +04:00
|
|
|
{
|
2004-12-25 09:58:37 +03:00
|
|
|
int rc = 0, s;
|
2004-09-26 06:29:15 +04:00
|
|
|
struct rtw_softc *sc = ifp->if_softc;
|
|
|
|
|
2004-12-25 09:58:37 +03:00
|
|
|
s = splnet();
|
2007-05-29 22:32:07 +04:00
|
|
|
if (cmd == SIOCSIFFLAGS) {
|
*** Summary ***
When a link-layer address changes (e.g., ifconfig ex0 link
02:de:ad:be:ef:02 active), send a gratuitous ARP and/or a Neighbor
Advertisement to update the network-/link-layer address bindings
on our LAN peers.
Refuse a change of ethernet address to the address 00:00:00:00:00:00
or to any multicast/broadcast address. (Thanks matt@.)
Reorder ifnet ioctl operations so that driver ioctls may inherit
the functions of their "class"---ether_ioctl(), fddi_ioctl(), et
cetera---and the class ioctls may inherit from the generic ioctl,
ifioctl_common(), but both driver- and class-ioctls may override
the generic behavior. Make network drivers share more code.
Distinguish a "factory" link-layer address from others for the
purposes of both protecting that address from deletion and computing
EUI64.
Return consistent, appropriate error codes from network drivers.
Improve readability. KNF.
*** Details ***
In if_attach(), always initialize the interface ioctl routine,
ifnet->if_ioctl, if the driver has not already initialized it.
Delete if_ioctl == NULL tests everywhere else, because it cannot
happen.
In the ioctl routines of network interfaces, inherit common ioctl
behaviors by calling either ifioctl_common() or whichever ioctl
routine is appropriate for the class of interface---e.g., ether_ioctl()
for ethernets.
Stop (ab)using SIOCSIFADDR and start to use SIOCINITIFADDR. In
the user->kernel interface, SIOCSIFADDR's argument was an ifreq,
but on the protocol->ifnet interface, SIOCSIFADDR's argument was
an ifaddr. That was confusing, and it would work against me as I
make it possible for a network interface to overload most ioctls.
On the protocol->ifnet interface, replace SIOCSIFADDR with
SIOCINITIFADDR. In ifioctl(), return EPERM if userland tries to
invoke SIOCINITIFADDR.
In ifioctl(), give the interface the first shot at handling most
interface ioctls, and give the protocol the second shot, instead
of the other way around. Finally, let compatibility code (COMPAT_OSOCK)
take a shot.
Pull device initialization out of switch statements under
SIOCINITIFADDR. For example, pull ..._init() out of any switch
statement that looks like this:
switch (...->sa_family) {
case ...:
..._init();
...
break;
...
default:
..._init();
...
break;
}
Rewrite many if-else clauses that handle all permutations of IFF_UP
and IFF_RUNNING to use a switch statement,
switch (x & (IFF_UP|IFF_RUNNING)) {
case 0:
...
break;
case IFF_RUNNING:
...
break;
case IFF_UP:
...
break;
case IFF_UP|IFF_RUNNING:
...
break;
}
unifdef lots of code containing #ifdef FreeBSD, #ifdef NetBSD, and
#ifdef SIOCSIFMTU, especially in fwip(4) and in ndis(4).
In ipw(4), remove an if_set_sadl() call that is out of place.
In nfe(4), reuse the jumbo MTU logic in ether_ioctl().
Let ethernets register a callback for setting h/w state such as
promiscuous mode and the multicast filter in accord with a change
in the if_flags: ether_set_ifflags_cb() registers a callback that
returns ENETRESET if the caller should reset the ethernet by calling
if_init(), 0 on success, != 0 on failure. Pull common code from
ex(4), gem(4), nfe(4), sip(4), tlp(4), vge(4) into ether_ioctl(),
and register if_flags callbacks for those drivers.
Return ENOTTY instead of EINVAL for inappropriate ioctls. In
zyd(4), use ENXIO instead of ENOTTY to indicate that the device is
not any longer attached.
Add to if_set_sadl() a boolean 'factory' argument that indicates
whether a link-layer address was assigned by the factory or some
other source. In a comment, recommend using the factory address
for generating an EUI64, and update in6_get_hw_ifid() to prefer a
factory address to any other link-layer address.
Add a routing message, RTM_LLINFO_UPD, that tells protocols to
update the binding of network-layer addresses to link-layer addresses.
Implement this message in IPv4 and IPv6 by sending a gratuitous
ARP or a neighbor advertisement, respectively. Generate RTM_LLINFO_UPD
messages on a change of an interface's link-layer address.
In ether_ioctl(), do not let SIOCALIFADDR set a link-layer address
that is broadcast/multicast or equal to 00:00:00:00:00:00.
Make ether_ioctl() call ifioctl_common() to handle ioctls that it
does not understand.
In gif(4), initialize if_softc and use it, instead of assuming that
the gif_softc and ifp overlap.
Let ifioctl_common() handle SIOCGIFADDR.
Sprinkle rtcache_invariants(), which checks on DIAGNOSTIC kernels
that certain invariants on a struct route are satisfied.
In agr(4), rewrite agr_ioctl_filter() to be a bit more explicit
about the ioctls that we do not allow on an agr(4) member interface.
bzero -> memset. Delete unnecessary casts to void *. Use
sockaddr_in_init() and sockaddr_in6_init(). Compare pointers with
NULL instead of "testing truth". Replace some instances of (type
*)0 with NULL. Change some K&R prototypes to ANSI C, and join
lines.
2008-11-07 03:20:01 +03:00
|
|
|
if ((rc = ifioctl_common(ifp, cmd, data)) != 0)
|
|
|
|
;
|
In pmf(9), improve the implementation of device self-suspension
and make suspension by self, by drvctl(8), and by ACPI system sleep
play nice together. Start solidifying some temporary API changes.
1. Extract a new header file, <sys/device_if.h>, from <sys/device.h> and
#include it from <sys/pmf.h> instead of <sys/device.h> to break the
circular dependency between <sys/device.h> and <sys/pmf.h>.
2. Introduce pmf_qual_t, an aggregate of qualifications on a PMF
suspend/resume call. Start to replace instances of PMF_FN_PROTO,
PMF_FN_ARGS, et cetera, with a pmf_qual_t.
3. Introduce the notion of a "suspensor," an entity that holds a
device in suspension. More than one suspensor may hold a device
at once. A device stays suspended as long as at least one
suspensor holds it. A device resumes when the last suspensor
releases it.
Currently, the kernel defines three suspensors,
3a the system-suspensor: for system suspension, initiated
by 'sysctl -w machdep.sleep_state=3', by lid closure, by
power-button press, et cetera,
3b the drvctl-suspensor: for device suspension by /dev/drvctl
ioctl, e.g., drvctl -S sip0.
3c the system self-suspensor: for device drivers that suspend
themselves and their children. Several drivers for network
interfaces put the network device to sleep while it is not
administratively up, that is, after the kernel calls if_stop(,
1). The self-suspensor should not be used directly. See
the description of suspensor delegates, below.
A suspensor can have one or more "delegates". A suspensor can
release devices that its delegates hold suspended. Right now,
only the system self-suspensor has delegates. For each device
that a self-suspending driver attaches, it creates the device's
self-suspensor, a delegate of the system self-suspensor.
Suspensors stop a system-wide suspend/resume cycle from waking
devices that the operator put to sleep with drvctl before the cycle.
They also help self-suspension to work more simply, safely, and in
accord with expectations.
4. Add the notion of device activation level, devact_level_t,
and a routine for checking the current activation level,
device_activation(). Current activation levels are DEVACT_LEVEL_BUS,
DEVACT_LEVEL_DRIVER, and DEVACT_LEVEL_CLASS, which respectively
indicate that the device's bus is active, that the bus and device are
active, and that the bus, device, and the functions of the device's
class (network, audio) are active.
Suspend/resume calls can be qualified with a devact_level_t.
The power-management framework treats a devact_level_t that
qualifies a device suspension as the device's current activation
level; it only runs hooks to reduce the activation level from
the presumed current level to the fully suspended state. The
framework treats a devact_level_t qualifying device resumption
as the target activation level; it only runs hooks to raise the
activation level to the target.
5. Use pmf_qual_t, devact_level_t, and self-suspensors in several
drivers.
6. Temporarily add an unused power-management workqueue that I will
remove or replace, soon.
2009-09-16 20:34:49 +04:00
|
|
|
else switch (ifp->if_flags & (IFF_UP|IFF_RUNNING)) {
|
|
|
|
case IFF_UP:
|
|
|
|
rc = rtw_init(ifp);
|
|
|
|
RTW_PRINT_REGS(&sc->sc_regs, ifp->if_xname, __func__);
|
|
|
|
break;
|
|
|
|
case IFF_UP|IFF_RUNNING:
|
|
|
|
if (device_activation(sc->sc_dev, DEVACT_LEVEL_DRIVER))
|
2004-09-26 06:29:15 +04:00
|
|
|
rtw_pktfilt_load(sc);
|
2005-01-03 06:25:06 +03:00
|
|
|
RTW_PRINT_REGS(&sc->sc_regs, ifp->if_xname, __func__);
|
In pmf(9), improve the implementation of device self-suspension
and make suspension by self, by drvctl(8), and by ACPI system sleep
play nice together. Start solidifying some temporary API changes.
1. Extract a new header file, <sys/device_if.h>, from <sys/device.h> and
#include it from <sys/pmf.h> instead of <sys/device.h> to break the
circular dependency between <sys/device.h> and <sys/pmf.h>.
2. Introduce pmf_qual_t, an aggregate of qualifications on a PMF
suspend/resume call. Start to replace instances of PMF_FN_PROTO,
PMF_FN_ARGS, et cetera, with a pmf_qual_t.
3. Introduce the notion of a "suspensor," an entity that holds a
device in suspension. More than one suspensor may hold a device
at once. A device stays suspended as long as at least one
suspensor holds it. A device resumes when the last suspensor
releases it.
Currently, the kernel defines three suspensors,
3a the system-suspensor: for system suspension, initiated
by 'sysctl -w machdep.sleep_state=3', by lid closure, by
power-button press, et cetera,
3b the drvctl-suspensor: for device suspension by /dev/drvctl
ioctl, e.g., drvctl -S sip0.
3c the system self-suspensor: for device drivers that suspend
themselves and their children. Several drivers for network
interfaces put the network device to sleep while it is not
administratively up, that is, after the kernel calls if_stop(,
1). The self-suspensor should not be used directly. See
the description of suspensor delegates, below.
A suspensor can have one or more "delegates". A suspensor can
release devices that its delegates hold suspended. Right now,
only the system self-suspensor has delegates. For each device
that a self-suspending driver attaches, it creates the device's
self-suspensor, a delegate of the system self-suspensor.
Suspensors stop a system-wide suspend/resume cycle from waking
devices that the operator put to sleep with drvctl before the cycle.
They also help self-suspension to work more simply, safely, and in
accord with expectations.
4. Add the notion of device activation level, devact_level_t,
and a routine for checking the current activation level,
device_activation(). Current activation levels are DEVACT_LEVEL_BUS,
DEVACT_LEVEL_DRIVER, and DEVACT_LEVEL_CLASS, which respectively
indicate that the device's bus is active, that the bus and device are
active, and that the bus, device, and the functions of the device's
class (network, audio) are active.
Suspend/resume calls can be qualified with a devact_level_t.
The power-management framework treats a devact_level_t that
qualifies a device suspension as the device's current activation
level; it only runs hooks to reduce the activation level from
the presumed current level to the fully suspended state. The
framework treats a devact_level_t qualifying device resumption
as the target activation level; it only runs hooks to raise the
activation level to the target.
5. Use pmf_qual_t, devact_level_t, and self-suspensors in several
drivers.
6. Temporarily add an unused power-management workqueue that I will
remove or replace, soon.
2009-09-16 20:34:49 +04:00
|
|
|
break;
|
|
|
|
case IFF_RUNNING:
|
2005-01-03 06:25:06 +03:00
|
|
|
RTW_PRINT_REGS(&sc->sc_regs, ifp->if_xname, __func__);
|
2004-09-26 06:29:15 +04:00
|
|
|
rtw_stop(ifp, 1);
|
In pmf(9), improve the implementation of device self-suspension
and make suspension by self, by drvctl(8), and by ACPI system sleep
play nice together. Start solidifying some temporary API changes.
1. Extract a new header file, <sys/device_if.h>, from <sys/device.h> and
#include it from <sys/pmf.h> instead of <sys/device.h> to break the
circular dependency between <sys/device.h> and <sys/pmf.h>.
2. Introduce pmf_qual_t, an aggregate of qualifications on a PMF
suspend/resume call. Start to replace instances of PMF_FN_PROTO,
PMF_FN_ARGS, et cetera, with a pmf_qual_t.
3. Introduce the notion of a "suspensor," an entity that holds a
device in suspension. More than one suspensor may hold a device
at once. A device stays suspended as long as at least one
suspensor holds it. A device resumes when the last suspensor
releases it.
Currently, the kernel defines three suspensors,
3a the system-suspensor: for system suspension, initiated
by 'sysctl -w machdep.sleep_state=3', by lid closure, by
power-button press, et cetera,
3b the drvctl-suspensor: for device suspension by /dev/drvctl
ioctl, e.g., drvctl -S sip0.
3c the system self-suspensor: for device drivers that suspend
themselves and their children. Several drivers for network
interfaces put the network device to sleep while it is not
administratively up, that is, after the kernel calls if_stop(,
1). The self-suspensor should not be used directly. See
the description of suspensor delegates, below.
A suspensor can have one or more "delegates". A suspensor can
release devices that its delegates hold suspended. Right now,
only the system self-suspensor has delegates. For each device
that a self-suspending driver attaches, it creates the device's
self-suspensor, a delegate of the system self-suspensor.
Suspensors stop a system-wide suspend/resume cycle from waking
devices that the operator put to sleep with drvctl before the cycle.
They also help self-suspension to work more simply, safely, and in
accord with expectations.
4. Add the notion of device activation level, devact_level_t,
and a routine for checking the current activation level,
device_activation(). Current activation levels are DEVACT_LEVEL_BUS,
DEVACT_LEVEL_DRIVER, and DEVACT_LEVEL_CLASS, which respectively
indicate that the device's bus is active, that the bus and device are
active, and that the bus, device, and the functions of the device's
class (network, audio) are active.
Suspend/resume calls can be qualified with a devact_level_t.
The power-management framework treats a devact_level_t that
qualifies a device suspension as the device's current activation
level; it only runs hooks to reduce the activation level from
the presumed current level to the fully suspended state. The
framework treats a devact_level_t qualifying device resumption
as the target activation level; it only runs hooks to raise the
activation level to the target.
5. Use pmf_qual_t, devact_level_t, and self-suspensors in several
drivers.
6. Temporarily add an unused power-management workqueue that I will
remove or replace, soon.
2009-09-16 20:34:49 +04:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
2004-09-26 06:29:15 +04:00
|
|
|
}
|
2007-05-29 22:32:07 +04:00
|
|
|
} else if ((rc = ieee80211_ioctl(&sc->sc_ic, cmd, data)) != ENETRESET)
|
|
|
|
; /* nothing to do */
|
|
|
|
else if (cmd == SIOCADDMULTI || cmd == SIOCDELMULTI) {
|
|
|
|
/* reload packet filter if running */
|
2005-01-03 06:25:06 +03:00
|
|
|
if (ifp->if_flags & IFF_RUNNING)
|
|
|
|
rtw_pktfilt_load(sc);
|
|
|
|
rc = 0;
|
Use device_t and its accessors throughout. Use aprint_*_dev().
Improve PMF-ability.
Add a 'flags' argument to suspend/resume handlers and
callers such as pmf_system_suspend().
Define a flag, PMF_F_SELF, which indicates to PMF that a
device is suspending/resuming itself. Add helper routines,
pmf_device_suspend_self(dev) and pmf_device_resume_self(dev),
that call pmf_device_suspend(dev, PMF_F_SELF) and
pmf_device_resume(dev, PMF_F_SELF), respectively. Use
PMF_F_SELF to suspend/resume self in ath(4), audio(4),
rtw(4), and sip(4).
In ath(4) and in rtw(4), replace the icky sc_enable/sc_disable
callbacks, provided by the bus front-end, with
self-suspension/resumption. Also, clean up the bus
front-ends. Make sure that the interrupt handler is
disestablished during suspension. Get rid of driver-private
flags (e.g., RTW_F_ENABLED, ath_softc->sc_invalid); use
device_is_active()/device_has_power() calls, instead.
In the network-class suspend handler, call if_stop(, 0)
instead of if_stop(, 1), because the latter is superfluous
(bus- and driver-suspension hooks will 'disable' the NIC),
and it may cause recursion.
In the network-class resume handler, prevent infinite
recursion through if_init() by getting out early if we are
self-suspending (PMF_F_SELF).
rtw(4) improvements:
Destroy rtw(4) callouts when we detach it. Make rtw at
pci detachable. Print some more information with the "rx
frame too long" warning.
Remove activate() methods:
Get rid of rtw_activate() and ath_activate(). The device
activate() methods are not good for much these days.
Make ath at cardbus resume with crypto functions intact:
Introduce a boolean device property, "pmf-powerdown". If
pmf-powerdown is present and false, it indicates that a
bus back-end should not remove power from a device.
Honor this property in cardbus_child_suspend().
Set this property to 'false' in ath_attach(), since removing
power from an ath at cardbus seems to lobotomize the WPA
crypto engine. XXX Should the pmf-powerdown property
propagate toward the root of the device tree?
Miscellaneous ath(4) changes:
Warn if ath(4) tries to write crypto keys to suspended
hardware.
Reduce differences between FreeBSD and NetBSD in ath(4)
multicast filter setup.
Make ath_printrxbuf() print an rx descriptor's status &
key index, to help debug crypto errors.
Shorten a staircase in ath_ioctl(). Don't check for
ieee80211_ioctl() return code ERESTART, it never happens.
2008-03-12 21:02:21 +03:00
|
|
|
} else if ((ifp->if_flags & IFF_UP) != 0)
|
2007-05-29 22:32:07 +04:00
|
|
|
rc = rtw_init(ifp);
|
|
|
|
else
|
|
|
|
rc = 0;
|
2004-12-25 09:58:37 +03:00
|
|
|
splx(s);
|
2004-09-26 06:29:15 +04:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
/* Select a transmit ring with at least one h/w and s/w descriptor free.
|
|
|
|
* Return 0 on success, -1 on failure.
|
|
|
|
*/
|
2005-12-24 23:27:29 +03:00
|
|
|
static inline 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
|
|
|
rtw_txring_choose(struct rtw_softc *sc, struct rtw_txsoft_blk **tsbp,
|
|
|
|
struct rtw_txdesc_blk **tdbp, int pri)
|
|
|
|
{
|
|
|
|
struct rtw_txsoft_blk *tsb;
|
|
|
|
struct rtw_txdesc_blk *tdb;
|
|
|
|
|
|
|
|
KASSERT(pri >= 0 && pri < RTW_NTXPRI);
|
|
|
|
|
|
|
|
tsb = &sc->sc_txsoft_blk[pri];
|
|
|
|
tdb = &sc->sc_txdesc_blk[pri];
|
|
|
|
|
|
|
|
if (SIMPLEQ_EMPTY(&tsb->tsb_freeq) || tdb->tdb_nfree == 0) {
|
2005-11-23 07:12:33 +03:00
|
|
|
if (tsb->tsb_tx_timer == 0)
|
|
|
|
tsb->tsb_tx_timer = 5;
|
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
|
|
|
*tsbp = NULL;
|
|
|
|
*tdbp = NULL;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
*tsbp = tsb;
|
|
|
|
*tdbp = tdb;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-12-24 23:27:29 +03:00
|
|
|
static inline struct mbuf *
|
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
|
|
|
rtw_80211_dequeue(struct rtw_softc *sc, struct ifqueue *ifq, int pri,
|
|
|
|
struct rtw_txsoft_blk **tsbp, struct rtw_txdesc_blk **tdbp,
|
|
|
|
struct ieee80211_node **nip, short *if_flagsp)
|
|
|
|
{
|
|
|
|
struct mbuf *m;
|
|
|
|
|
|
|
|
if (IF_IS_EMPTY(ifq))
|
|
|
|
return NULL;
|
|
|
|
if (rtw_txring_choose(sc, tsbp, tdbp, pri) == -1) {
|
2005-11-23 07:12:33 +03:00
|
|
|
DPRINTF(sc, RTW_DEBUG_XMIT_RSRC, ("%s: no ring %d descriptor\n",
|
|
|
|
__func__, pri));
|
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
|
|
|
*if_flagsp |= IFF_OACTIVE;
|
2005-11-23 07:12:33 +03:00
|
|
|
sc->sc_if.if_timer = 1;
|
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
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
IF_DEQUEUE(ifq, m);
|
|
|
|
*nip = (struct ieee80211_node *)m->m_pkthdr.rcvif;
|
|
|
|
m->m_pkthdr.rcvif = NULL;
|
2005-06-22 10:14:51 +04:00
|
|
|
KASSERT(*nip != NULL);
|
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
|
|
|
return m;
|
|
|
|
}
|
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
/* Point *mp at the next 802.11 frame to transmit. Point *tsbp
|
2004-09-26 06:29:15 +04:00
|
|
|
* at the driver's selection of transmit control block for the packet.
|
|
|
|
*/
|
2005-12-24 23:27:29 +03:00
|
|
|
static inline int
|
2004-12-29 04:06:52 +03:00
|
|
|
rtw_dequeue(struct ifnet *ifp, struct rtw_txsoft_blk **tsbp,
|
|
|
|
struct rtw_txdesc_blk **tdbp, struct mbuf **mp,
|
2004-09-26 06:29:15 +04:00
|
|
|
struct ieee80211_node **nip)
|
|
|
|
{
|
2005-06-22 10:14:51 +04:00
|
|
|
int pri;
|
|
|
|
struct ether_header *eh;
|
2004-09-26 06:29:15 +04:00
|
|
|
struct mbuf *m0;
|
|
|
|
struct rtw_softc *sc;
|
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
|
|
|
short *if_flagsp;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2007-01-29 10:08:09 +03:00
|
|
|
*mp = NULL;
|
|
|
|
|
2004-09-26 06:29:15 +04:00
|
|
|
sc = (struct rtw_softc *)ifp->if_softc;
|
|
|
|
|
2004-12-25 09:58:37 +03:00
|
|
|
DPRINTF(sc, RTW_DEBUG_XMIT,
|
2007-12-21 21:22:43 +03:00
|
|
|
("%s: enter %s\n", device_xname(sc->sc_dev), __func__));
|
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
|
|
|
if_flagsp = &ifp->if_flags;
|
2004-12-19 11:19:25 +03: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
|
|
|
if (sc->sc_ic.ic_state == IEEE80211_S_RUN &&
|
|
|
|
(*mp = rtw_80211_dequeue(sc, &sc->sc_beaconq, RTW_TXPRIBCN, tsbp,
|
|
|
|
tdbp, nip, if_flagsp)) != NULL) {
|
|
|
|
DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: dequeue beacon frame\n",
|
|
|
|
__func__));
|
2004-12-19 11:19:25 +03:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
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
|
|
|
if ((*mp = rtw_80211_dequeue(sc, &sc->sc_ic.ic_mgtq, RTW_TXPRIMD, tsbp,
|
|
|
|
tdbp, nip, if_flagsp)) != NULL) {
|
|
|
|
DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: dequeue mgt frame\n",
|
|
|
|
__func__));
|
|
|
|
return 0;
|
|
|
|
}
|
2004-12-19 11:19:25 +03: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
|
|
|
if (sc->sc_ic.ic_state != IEEE80211_S_RUN) {
|
2004-12-25 09:58:37 +03:00
|
|
|
DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: not running\n", __func__));
|
2004-09-26 06:29:15 +04:00
|
|
|
return 0;
|
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
|
|
|
}
|
|
|
|
|
2005-06-22 10:14:51 +04:00
|
|
|
IFQ_POLL(&ifp->if_snd, m0);
|
|
|
|
if (m0 == NULL) {
|
|
|
|
DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: no frame ready\n",
|
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
|
|
|
__func__));
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2005-06-22 10:14:51 +04:00
|
|
|
pri = ((m0->m_flags & M_PWR_SAV) != 0) ? RTW_TXPRIHI : RTW_TXPRIMD;
|
|
|
|
|
|
|
|
if (rtw_txring_choose(sc, tsbp, tdbp, pri) == -1) {
|
2005-11-23 07:12:33 +03:00
|
|
|
DPRINTF(sc, RTW_DEBUG_XMIT_RSRC, ("%s: no ring %d descriptor\n",
|
|
|
|
__func__, pri));
|
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
|
|
|
*if_flagsp |= IFF_OACTIVE;
|
2005-11-23 07:12:33 +03:00
|
|
|
sc->sc_if.if_timer = 1;
|
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
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
IFQ_DEQUEUE(&ifp->if_snd, m0);
|
|
|
|
if (m0 == NULL) {
|
2005-06-22 10:14:51 +04:00
|
|
|
DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: no frame ready\n",
|
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
|
|
|
__func__));
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: dequeue data frame\n", __func__));
|
|
|
|
ifp->if_opackets++;
|
2010-04-05 11:19:28 +04:00
|
|
|
bpf_mtap(ifp, m0);
|
2005-06-22 10:14:51 +04:00
|
|
|
eh = mtod(m0, struct ether_header *);
|
|
|
|
*nip = ieee80211_find_txnode(&sc->sc_ic, eh->ether_dhost);
|
|
|
|
if (*nip == NULL) {
|
|
|
|
/* NB: ieee80211_find_txnode does stat+msg */
|
|
|
|
m_freem(m0);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
if ((m0 = ieee80211_encap(&sc->sc_ic, m0, *nip)) == NULL) {
|
|
|
|
DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: encap error\n", __func__));
|
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
|
|
|
ifp->if_oerrors++;
|
|
|
|
return -1;
|
2004-09-26 06:29:15 +04:00
|
|
|
}
|
2004-12-25 09:58:37 +03:00
|
|
|
DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: leave\n", __func__));
|
2004-09-26 06:29:15 +04:00
|
|
|
*mp = m0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2004-12-25 09:58:37 +03:00
|
|
|
static int
|
|
|
|
rtw_seg_too_short(bus_dmamap_t dmamap)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < dmamap->dm_nsegs; i++) {
|
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
|
|
|
if (dmamap->dm_segs[i].ds_len < 4)
|
2004-12-25 09:58:37 +03:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2004-12-19 11:19:25 +03:00
|
|
|
/* TBD factor with atw_start */
|
|
|
|
static struct mbuf *
|
|
|
|
rtw_dmamap_load_txbuf(bus_dma_tag_t dmat, bus_dmamap_t dmam, struct mbuf *chain,
|
2007-12-21 21:22:43 +03:00
|
|
|
u_int ndescfree, device_t dev)
|
2004-12-19 11:19:25 +03:00
|
|
|
{
|
|
|
|
int first, rc;
|
|
|
|
struct mbuf *m, *m0;
|
|
|
|
|
|
|
|
m0 = chain;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Load the DMA map. Copy and try (once) again if the packet
|
|
|
|
* didn't fit in the alloted number of segments.
|
|
|
|
*/
|
|
|
|
for (first = 1;
|
|
|
|
((rc = bus_dmamap_load_mbuf(dmat, dmam, m0,
|
|
|
|
BUS_DMA_WRITE|BUS_DMA_NOWAIT)) != 0 ||
|
2004-12-25 09:58:37 +03:00
|
|
|
dmam->dm_nsegs > ndescfree || rtw_seg_too_short(dmam)) && first;
|
2004-12-19 11:19:25 +03:00
|
|
|
first = 0) {
|
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
|
|
|
if (rc == 0) {
|
|
|
|
#ifdef RTW_DIAGxxx
|
|
|
|
if (rtw_seg_too_short(dmam)) {
|
|
|
|
printf("%s: short segment, mbuf lengths:", __func__);
|
|
|
|
for (m = m0; m; m = m->m_next)
|
|
|
|
printf(" %d", m->m_len);
|
|
|
|
printf("\n");
|
|
|
|
}
|
|
|
|
#endif
|
2004-12-19 11:19:25 +03:00
|
|
|
bus_dmamap_unload(dmat, dmam);
|
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
|
|
|
}
|
2004-12-19 11:19:25 +03:00
|
|
|
MGETHDR(m, M_DONTWAIT, MT_DATA);
|
|
|
|
if (m == NULL) {
|
2007-12-21 21:22:43 +03:00
|
|
|
aprint_error_dev(dev, "unable to allocate Tx mbuf\n");
|
2004-12-19 11:19:25 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (m0->m_pkthdr.len > MHLEN) {
|
|
|
|
MCLGET(m, M_DONTWAIT);
|
|
|
|
if ((m->m_flags & M_EXT) == 0) {
|
2007-12-21 21:22:43 +03:00
|
|
|
aprint_error_dev(dev,
|
|
|
|
"cannot allocate Tx cluster\n");
|
2004-12-19 11:19:25 +03:00
|
|
|
m_freem(m);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2007-03-04 08:59:00 +03:00
|
|
|
m_copydata(m0, 0, m0->m_pkthdr.len, mtod(m, void *));
|
2004-12-19 11:19:25 +03:00
|
|
|
m->m_pkthdr.len = m->m_len = m0->m_pkthdr.len;
|
|
|
|
m_freem(m0);
|
|
|
|
m0 = m;
|
|
|
|
m = NULL;
|
|
|
|
}
|
|
|
|
if (rc != 0) {
|
2007-12-21 21:22:43 +03:00
|
|
|
aprint_error_dev(dev, "cannot load Tx buffer, rc = %d\n", rc);
|
2004-12-19 11:19:25 +03:00
|
|
|
m_freem(m0);
|
|
|
|
return NULL;
|
2004-12-25 09:58:37 +03:00
|
|
|
} else if (rtw_seg_too_short(dmam)) {
|
2007-12-21 21:22:43 +03:00
|
|
|
aprint_error_dev(dev,
|
|
|
|
"cannot load Tx buffer, segment too short\n");
|
2004-12-25 09:58:37 +03:00
|
|
|
bus_dmamap_unload(dmat, dmam);
|
|
|
|
m_freem(m0);
|
|
|
|
return NULL;
|
2004-12-19 11:19:25 +03:00
|
|
|
} else if (dmam->dm_nsegs > ndescfree) {
|
2007-12-21 21:22:43 +03:00
|
|
|
aprint_error_dev(dev, "too many tx segments\n");
|
2004-12-19 11:19:25 +03:00
|
|
|
bus_dmamap_unload(dmat, dmam);
|
|
|
|
m_freem(m0);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return m0;
|
|
|
|
}
|
|
|
|
|
2004-12-25 09:58:37 +03:00
|
|
|
#ifdef RTW_DEBUG
|
2004-12-23 08:57:18 +03:00
|
|
|
static void
|
|
|
|
rtw_print_txdesc(struct rtw_softc *sc, const char *action,
|
2004-12-29 04:06:52 +03:00
|
|
|
struct rtw_txsoft *ts, struct rtw_txdesc_blk *tdb, int desc)
|
2004-12-23 08:57:18 +03:00
|
|
|
{
|
2004-12-29 04:06:52 +03:00
|
|
|
struct rtw_txdesc *td = &tdb->tdb_desc[desc];
|
2005-11-23 07:12:33 +03:00
|
|
|
DPRINTF(sc, RTW_DEBUG_XMIT_DESC, ("%s: %p %s txdesc[%d] next %#08x "
|
|
|
|
"buf %#08x ctl0 %#08x ctl1 %#08x len %#08x\n",
|
2007-12-21 21:22:43 +03:00
|
|
|
device_xname(sc->sc_dev), ts, action, desc,
|
2005-11-23 07:12:33 +03:00
|
|
|
le32toh(td->td_buf), le32toh(td->td_next),
|
|
|
|
le32toh(td->td_ctl0), le32toh(td->td_ctl1),
|
2004-12-29 04:06:52 +03:00
|
|
|
le32toh(td->td_len)));
|
2004-12-23 08:57:18 +03:00
|
|
|
}
|
2004-12-25 09:58:37 +03:00
|
|
|
#endif /* RTW_DEBUG */
|
2004-12-23 08:57:18 +03:00
|
|
|
|
2004-09-26 06:29:15 +04:00
|
|
|
static void
|
|
|
|
rtw_start(struct ifnet *ifp)
|
|
|
|
{
|
2004-12-19 11:19:25 +03:00
|
|
|
int desc, i, lastdesc, npkt, rate;
|
2004-12-23 08:52:27 +03:00
|
|
|
uint32_t proto_ctl0, ctl0, ctl1;
|
2004-12-19 11:19:25 +03:00
|
|
|
bus_dmamap_t dmamap;
|
|
|
|
struct ieee80211com *ic;
|
|
|
|
struct ieee80211_duration *d0;
|
2005-06-27 09:49:13 +04:00
|
|
|
struct ieee80211_frame_min *wh;
|
2006-05-14 09:42:43 +04:00
|
|
|
struct ieee80211_node *ni = NULL; /* XXX: GCC */
|
2004-12-19 11:19:25 +03:00
|
|
|
struct mbuf *m0;
|
|
|
|
struct rtw_softc *sc;
|
2006-05-14 09:42:43 +04:00
|
|
|
struct rtw_txsoft_blk *tsb = NULL; /* XXX: GCC */
|
|
|
|
struct rtw_txdesc_blk *tdb = NULL; /* XXX: GCC */
|
2004-12-29 04:06:52 +03:00
|
|
|
struct rtw_txsoft *ts;
|
|
|
|
struct rtw_txdesc *td;
|
2005-06-27 09:49:13 +04:00
|
|
|
struct ieee80211_key *k;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
sc = (struct rtw_softc *)ifp->if_softc;
|
2004-12-19 11:19:25 +03:00
|
|
|
ic = &sc->sc_ic;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2004-12-25 09:58:37 +03:00
|
|
|
DPRINTF(sc, RTW_DEBUG_XMIT,
|
2007-12-21 21:22:43 +03:00
|
|
|
("%s: enter %s\n", device_xname(sc->sc_dev), __func__));
|
2004-12-19 11:19:25 +03:00
|
|
|
|
If defined(RTW_DEBUG), provide a sysctl (hw.rtw.rxbufs_limit) for
limiting the number of rx buffers an rtw may allocate. Use this
sysctl to test the code that copes with buffer exhaustion.
Allocate at most RTW_RXQLEN rx buffers, stopping at the sysctl
limit. Record in sc_nrxdesc how many were allocated, and put the
end-of-ring indication on sc_rxdesc[sc_nrxdesc - 1]. In rtw_init,
if no rx buffers could be allocated, log a complaint, clear
IFF_RUNNING, and exit with an error.
Many changes to accomodate a short rx ring, mainly of the "add a
rx-ring length argument" variety. XXX I really should consolidate
all of the rx ring variables in one struct and pass that to the
rx-ring subroutines.
Bug fix: after calling MCLGET, use the (m->m_flags & M_EXT) idiom
to check for success, instead of m != NULL.
Bug fix: at the top of rtw_start, if IFF_RUNNING is not set, or
IFF_OACTIVE is, get out.
2004-12-29 01:21:15 +03:00
|
|
|
if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING)
|
|
|
|
goto out;
|
|
|
|
|
2004-12-19 11:19:25 +03:00
|
|
|
/* XXX do real rate control */
|
2004-12-23 08:52:27 +03:00
|
|
|
proto_ctl0 = RTW_TXCTL0_RTSRATE_1MBPS;
|
2004-12-19 11:19:25 +03:00
|
|
|
|
|
|
|
if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0)
|
2004-12-23 08:52:27 +03:00
|
|
|
proto_ctl0 |= RTW_TXCTL0_SPLCP;
|
2004-12-19 11:19:25 +03:00
|
|
|
|
|
|
|
for (;;) {
|
2004-12-29 04:06:52 +03:00
|
|
|
if (rtw_dequeue(ifp, &tsb, &tdb, &m0, &ni) == -1)
|
2004-09-26 06:29:15 +04:00
|
|
|
continue;
|
|
|
|
if (m0 == NULL)
|
|
|
|
break;
|
2005-06-27 09:49:13 +04:00
|
|
|
|
|
|
|
wh = mtod(m0, struct ieee80211_frame_min *);
|
|
|
|
|
|
|
|
if ((wh->i_fc[1] & IEEE80211_FC1_WEP) != 0 &&
|
|
|
|
(k = ieee80211_crypto_encap(ic, ni, m0)) == NULL) {
|
2005-07-07 03:44:15 +04:00
|
|
|
m_freem(m0);
|
2005-06-27 09:49:13 +04:00
|
|
|
break;
|
|
|
|
} else
|
|
|
|
k = NULL;
|
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
ts = SIMPLEQ_FIRST(&tsb->tsb_freeq);
|
2004-12-19 11:19:25 +03:00
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
dmamap = ts->ts_dmamap;
|
2004-12-19 11:19:25 +03:00
|
|
|
|
|
|
|
m0 = rtw_dmamap_load_txbuf(sc->sc_dmat, dmamap, m0,
|
2007-12-21 21:22:43 +03:00
|
|
|
tdb->tdb_nfree, sc->sc_dev);
|
2004-12-19 11:19:25 +03:00
|
|
|
|
|
|
|
if (m0 == NULL || dmamap->dm_nsegs == 0) {
|
2004-12-25 09:58:37 +03:00
|
|
|
DPRINTF(sc, RTW_DEBUG_XMIT,
|
|
|
|
("%s: fail dmamap load\n", __func__));
|
2004-12-19 11:19:25 +03:00
|
|
|
goto post_dequeue_err;
|
|
|
|
}
|
|
|
|
|
2005-06-27 09:49:13 +04:00
|
|
|
/* Note well: rtw_dmamap_load_txbuf may have created
|
|
|
|
* a new chain, so we must find the header once
|
|
|
|
* more.
|
|
|
|
*/
|
|
|
|
wh = mtod(m0, struct ieee80211_frame_min *);
|
2005-03-02 08:20:43 +03:00
|
|
|
|
|
|
|
/* XXX do real rate control */
|
|
|
|
if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
|
|
|
|
IEEE80211_FC0_TYPE_MGT)
|
|
|
|
rate = 2;
|
|
|
|
else
|
2006-03-28 04:48:10 +04:00
|
|
|
rate = MAX(2, ieee80211_get_rate(ni));
|
2005-03-02 08:20:43 +03:00
|
|
|
|
2004-12-23 08:57:18 +03:00
|
|
|
#ifdef RTW_DEBUG
|
2005-06-22 10:14:51 +04:00
|
|
|
if ((ifp->if_flags & (IFF_DEBUG|IFF_LINK2)) ==
|
2004-12-23 08:57:18 +03:00
|
|
|
(IFF_DEBUG|IFF_LINK2)) {
|
|
|
|
ieee80211_dump_pkt(mtod(m0, uint8_t *),
|
|
|
|
(dmamap->dm_nsegs == 1) ? m0->m_pkthdr.len
|
|
|
|
: sizeof(wh),
|
|
|
|
rate, 0);
|
|
|
|
}
|
|
|
|
#endif /* RTW_DEBUG */
|
2004-12-23 08:52:27 +03:00
|
|
|
ctl0 = proto_ctl0 |
|
Per discussion on tech-kern and tech-userlevel, move the bit-twiddling
macros, __BIT, __BITS, SHIFTIN, SHIFTOUT, and __arraycount() from
lib/libkern/libkern.h to sys/cdefs.h. Add a __-prefix to SHIFTIN
and SHIFTOUT, and add a manual page for the bit-twiddling macros,
bits(3).
Make the __BIT and __BITS macros "widthless," as best I can, by
changing their type to uintmax_t from uint32_t. XXX The manual
page lags this change by a bit.
Define __PRIxBIT and __PRIxBITS printf(3) format strings.
2006-08-31 23:24:37 +04:00
|
|
|
__SHIFTIN(m0->m_pkthdr.len, RTW_TXCTL0_TPKTSIZE_MASK);
|
2004-12-19 11:19:25 +03:00
|
|
|
|
2005-03-02 08:20:43 +03:00
|
|
|
switch (rate) {
|
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
|
|
|
default:
|
|
|
|
case 2:
|
|
|
|
ctl0 |= RTW_TXCTL0_RATE_1MBPS;
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
ctl0 |= RTW_TXCTL0_RATE_2MBPS;
|
|
|
|
break;
|
|
|
|
case 11:
|
|
|
|
ctl0 |= RTW_TXCTL0_RATE_5MBPS;
|
|
|
|
break;
|
|
|
|
case 22:
|
|
|
|
ctl0 |= RTW_TXCTL0_RATE_11MBPS;
|
|
|
|
break;
|
|
|
|
}
|
2005-03-02 08:20:43 +03:00
|
|
|
/* XXX >= ? Compare after fragmentation? */
|
|
|
|
if (m0->m_pkthdr.len > ic->ic_rtsthreshold)
|
|
|
|
ctl0 |= RTW_TXCTL0_RTSEN;
|
|
|
|
|
2006-02-19 11:10:06 +03:00
|
|
|
/* XXX Sometimes writes a bogus keyid; h/w doesn't
|
|
|
|
* seem to care, since we don't activate h/w Tx
|
|
|
|
* encryption.
|
|
|
|
*/
|
2009-04-02 04:57:20 +04:00
|
|
|
if (k != NULL &&
|
|
|
|
k->wk_cipher->ic_cipher == IEEE80211_CIPHER_WEP) {
|
Per discussion on tech-kern and tech-userlevel, move the bit-twiddling
macros, __BIT, __BITS, SHIFTIN, SHIFTOUT, and __arraycount() from
lib/libkern/libkern.h to sys/cdefs.h. Add a __-prefix to SHIFTIN
and SHIFTOUT, and add a manual page for the bit-twiddling macros,
bits(3).
Make the __BIT and __BITS macros "widthless," as best I can, by
changing their type to uintmax_t from uint32_t. XXX The manual
page lags this change by a bit.
Define __PRIxBIT and __PRIxBITS printf(3) format strings.
2006-08-31 23:24:37 +04:00
|
|
|
ctl0 |= __SHIFTIN(k->wk_keyix, RTW_TXCTL0_KEYID_MASK) &
|
2005-06-27 09:49:13 +04:00
|
|
|
RTW_TXCTL0_KEYID_MASK;
|
|
|
|
}
|
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
|
|
|
|
2005-03-02 08:20:43 +03:00
|
|
|
if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
|
|
|
|
IEEE80211_FC0_TYPE_MGT) {
|
|
|
|
ctl0 &= ~(RTW_TXCTL0_SPLCP | RTW_TXCTL0_RTSEN);
|
|
|
|
if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) ==
|
|
|
|
IEEE80211_FC0_SUBTYPE_BEACON)
|
|
|
|
ctl0 |= RTW_TXCTL0_BEACON;
|
|
|
|
}
|
|
|
|
|
2005-12-30 00:08:26 +03:00
|
|
|
if (ieee80211_compute_duration(wh, k, m0->m_pkthdr.len,
|
2004-12-19 11:19:25 +03:00
|
|
|
ic->ic_flags, ic->ic_fragthreshold,
|
2004-12-29 04:06:52 +03:00
|
|
|
rate, &ts->ts_d0, &ts->ts_dn, &npkt,
|
2005-06-22 10:14:51 +04:00
|
|
|
(ifp->if_flags & (IFF_DEBUG|IFF_LINK2)) ==
|
2004-12-23 09:08:52 +03:00
|
|
|
(IFF_DEBUG|IFF_LINK2)) == -1) {
|
2004-12-25 09:58:37 +03:00
|
|
|
DPRINTF(sc, RTW_DEBUG_XMIT,
|
|
|
|
("%s: fail compute duration\n", __func__));
|
2004-12-19 11:19:25 +03:00
|
|
|
goto post_load_err;
|
|
|
|
}
|
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
d0 = &ts->ts_d0;
|
2004-12-19 11:19:25 +03:00
|
|
|
|
2004-12-23 09:12:43 +03:00
|
|
|
*(uint16_t*)wh->i_dur = htole16(d0->d_data_dur);
|
|
|
|
|
Per discussion on tech-kern and tech-userlevel, move the bit-twiddling
macros, __BIT, __BITS, SHIFTIN, SHIFTOUT, and __arraycount() from
lib/libkern/libkern.h to sys/cdefs.h. Add a __-prefix to SHIFTIN
and SHIFTOUT, and add a manual page for the bit-twiddling macros,
bits(3).
Make the __BIT and __BITS macros "widthless," as best I can, by
changing their type to uintmax_t from uint32_t. XXX The manual
page lags this change by a bit.
Define __PRIxBIT and __PRIxBITS printf(3) format strings.
2006-08-31 23:24:37 +04:00
|
|
|
ctl1 = __SHIFTIN(d0->d_plcp_len, RTW_TXCTL1_LENGTH_MASK) |
|
|
|
|
__SHIFTIN(d0->d_rts_dur, RTW_TXCTL1_RTSDUR_MASK);
|
2004-12-19 11:19:25 +03:00
|
|
|
|
2004-12-27 04:51:49 +03:00
|
|
|
if (d0->d_residue)
|
2004-12-23 08:52:27 +03:00
|
|
|
ctl1 |= RTW_TXCTL1_LENGEXT;
|
2004-12-19 11:19:25 +03:00
|
|
|
|
|
|
|
/* TBD fragmentation */
|
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
ts->ts_first = tdb->tdb_next;
|
2004-12-19 11:19:25 +03:00
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
rtw_txdescs_sync(tdb, ts->ts_first, dmamap->dm_nsegs,
|
2004-12-19 11:19:25 +03:00
|
|
|
BUS_DMASYNC_PREWRITE);
|
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
KASSERT(ts->ts_first < tdb->tdb_ndesc);
|
2004-12-25 09:58:37 +03:00
|
|
|
|
2010-04-05 11:19:28 +04:00
|
|
|
bpf_mtap3(ic->ic_rawbpf, m0);
|
2004-12-29 01:30:07 +03:00
|
|
|
|
|
|
|
if (sc->sc_radiobpf != NULL) {
|
|
|
|
struct rtw_tx_radiotap_header *rt = &sc->sc_txtap;
|
|
|
|
|
|
|
|
rt->rt_rate = rate;
|
|
|
|
|
2010-04-05 11:19:28 +04:00
|
|
|
bpf_mtap2(sc->sc_radiobpf, rt, sizeof(sc->sc_txtapu),
|
|
|
|
m0);
|
2004-12-29 01:30:07 +03:00
|
|
|
}
|
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
for (i = 0, lastdesc = desc = ts->ts_first;
|
2004-12-19 11:19:25 +03:00
|
|
|
i < dmamap->dm_nsegs;
|
2004-12-29 04:06:52 +03:00
|
|
|
i++, desc = RTW_NEXT_IDX(tdb, desc)) {
|
2004-12-19 11:19:25 +03:00
|
|
|
if (dmamap->dm_segs[i].ds_len > RTW_TXLEN_LENGTH_MASK) {
|
2004-12-25 09:58:37 +03:00
|
|
|
DPRINTF(sc, RTW_DEBUG_XMIT_DESC,
|
|
|
|
("%s: seg too long\n", __func__));
|
2004-12-19 11:19:25 +03:00
|
|
|
goto post_load_err;
|
|
|
|
}
|
2004-12-29 04:06:52 +03:00
|
|
|
td = &tdb->tdb_desc[desc];
|
|
|
|
td->td_ctl0 = htole32(ctl0);
|
|
|
|
td->td_ctl1 = htole32(ctl1);
|
|
|
|
td->td_buf = htole32(dmamap->dm_segs[i].ds_addr);
|
|
|
|
td->td_len = htole32(dmamap->dm_segs[i].ds_len);
|
2007-11-16 01:55:50 +03:00
|
|
|
td->td_next = htole32(RTW_NEXT_DESC(tdb, desc));
|
|
|
|
if (i != 0)
|
|
|
|
td->td_ctl0 |= htole32(RTW_TXCTL0_OWN);
|
2004-12-19 11:19:25 +03:00
|
|
|
lastdesc = desc;
|
2004-12-23 08:57:18 +03:00
|
|
|
#ifdef RTW_DEBUG
|
2004-12-29 04:06:52 +03:00
|
|
|
rtw_print_txdesc(sc, "load", ts, tdb, desc);
|
2004-12-23 08:57:18 +03:00
|
|
|
#endif /* RTW_DEBUG */
|
2004-12-19 11:19:25 +03:00
|
|
|
}
|
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
KASSERT(desc < tdb->tdb_ndesc);
|
2004-12-25 09:58:37 +03:00
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
ts->ts_ni = ni;
|
2005-06-22 10:14:51 +04:00
|
|
|
KASSERT(ni != NULL);
|
2004-12-29 04:06:52 +03:00
|
|
|
ts->ts_mbuf = m0;
|
|
|
|
ts->ts_last = lastdesc;
|
|
|
|
tdb->tdb_desc[ts->ts_last].td_ctl0 |= htole32(RTW_TXCTL0_LS);
|
|
|
|
tdb->tdb_desc[ts->ts_first].td_ctl0 |=
|
2004-12-23 08:57:18 +03:00
|
|
|
htole32(RTW_TXCTL0_FS);
|
|
|
|
|
|
|
|
#ifdef RTW_DEBUG
|
2004-12-29 04:06:52 +03:00
|
|
|
rtw_print_txdesc(sc, "FS on", ts, tdb, ts->ts_first);
|
|
|
|
rtw_print_txdesc(sc, "LS on", ts, tdb, ts->ts_last);
|
2004-12-23 08:57:18 +03:00
|
|
|
#endif /* RTW_DEBUG */
|
2004-12-19 11:19:25 +03:00
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
tdb->tdb_nfree -= dmamap->dm_nsegs;
|
|
|
|
tdb->tdb_next = desc;
|
2004-12-19 11:19:25 +03:00
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
rtw_txdescs_sync(tdb, ts->ts_first, dmamap->dm_nsegs,
|
2004-12-19 11:19:25 +03:00
|
|
|
BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
|
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
tdb->tdb_desc[ts->ts_first].td_ctl0 |=
|
2004-12-19 11:19:25 +03:00
|
|
|
htole32(RTW_TXCTL0_OWN);
|
|
|
|
|
2004-12-23 08:57:18 +03:00
|
|
|
#ifdef RTW_DEBUG
|
2004-12-29 04:06:52 +03:00
|
|
|
rtw_print_txdesc(sc, "OWN on", ts, tdb, ts->ts_first);
|
2004-12-23 08:57:18 +03:00
|
|
|
#endif /* RTW_DEBUG */
|
2004-12-19 11:19:25 +03:00
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
rtw_txdescs_sync(tdb, ts->ts_first, 1,
|
2004-12-19 11:19:25 +03:00
|
|
|
BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
|
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
SIMPLEQ_REMOVE_HEAD(&tsb->tsb_freeq, ts_q);
|
|
|
|
SIMPLEQ_INSERT_TAIL(&tsb->tsb_dirtyq, ts, ts_q);
|
2004-12-19 11:19:25 +03:00
|
|
|
|
2005-11-23 07:12:33 +03:00
|
|
|
if (tsb != &sc->sc_txsoft_blk[RTW_TXPRIBCN])
|
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
|
|
|
sc->sc_led_state.ls_event |= RTW_LED_S_TX;
|
2005-11-23 07:12:33 +03:00
|
|
|
tsb->tsb_tx_timer = 5;
|
|
|
|
ifp->if_timer = 1;
|
2008-03-15 02:59:01 +03:00
|
|
|
rtw_tx_kick(&sc->sc_regs, tsb->tsb_poll);
|
2004-09-26 06:29:15 +04:00
|
|
|
}
|
If defined(RTW_DEBUG), provide a sysctl (hw.rtw.rxbufs_limit) for
limiting the number of rx buffers an rtw may allocate. Use this
sysctl to test the code that copes with buffer exhaustion.
Allocate at most RTW_RXQLEN rx buffers, stopping at the sysctl
limit. Record in sc_nrxdesc how many were allocated, and put the
end-of-ring indication on sc_rxdesc[sc_nrxdesc - 1]. In rtw_init,
if no rx buffers could be allocated, log a complaint, clear
IFF_RUNNING, and exit with an error.
Many changes to accomodate a short rx ring, mainly of the "add a
rx-ring length argument" variety. XXX I really should consolidate
all of the rx ring variables in one struct and pass that to the
rx-ring subroutines.
Bug fix: after calling MCLGET, use the (m->m_flags & M_EXT) idiom
to check for success, instead of m != NULL.
Bug fix: at the top of rtw_start, if IFF_RUNNING is not set, or
IFF_OACTIVE is, get out.
2004-12-29 01:21:15 +03:00
|
|
|
out:
|
2004-12-25 09:58:37 +03:00
|
|
|
DPRINTF(sc, RTW_DEBUG_XMIT, ("%s: leave\n", __func__));
|
2004-12-19 11:19:25 +03:00
|
|
|
return;
|
|
|
|
post_load_err:
|
|
|
|
bus_dmamap_unload(sc->sc_dmat, dmamap);
|
|
|
|
m_freem(m0);
|
|
|
|
post_dequeue_err:
|
2005-06-22 10:14:51 +04:00
|
|
|
ieee80211_free_node(ni);
|
2004-09-26 06:29:15 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2005-11-23 07:12:33 +03:00
|
|
|
static void
|
|
|
|
rtw_idle(struct rtw_regs *regs)
|
|
|
|
{
|
|
|
|
int active;
|
2008-03-12 18:47:49 +03:00
|
|
|
uint8_t tppoll;
|
2005-11-23 07:12:33 +03:00
|
|
|
|
|
|
|
/* request stop DMA; wait for packets to stop transmitting. */
|
|
|
|
|
|
|
|
RTW_WRITE8(regs, RTW_TPPOLL, RTW_TPPOLL_SALL);
|
|
|
|
RTW_WBR(regs, RTW_TPPOLL, RTW_TPPOLL);
|
|
|
|
|
|
|
|
for (active = 0; active < 300 &&
|
2008-03-12 18:47:49 +03:00
|
|
|
(tppoll = RTW_READ8(regs, RTW_TPPOLL) & RTW_TPPOLL_ACTIVE) != 0;
|
|
|
|
active++)
|
2005-11-23 07:12:33 +03:00
|
|
|
DELAY(10);
|
2008-03-12 18:47:49 +03:00
|
|
|
printf("%s: transmit DMA idle in %dus, tppoll %02" PRIx8 "\n", __func__,
|
|
|
|
active * 10, tppoll);
|
2005-11-23 07:12:33 +03:00
|
|
|
}
|
|
|
|
|
2004-09-26 06:29:15 +04:00
|
|
|
static void
|
|
|
|
rtw_watchdog(struct ifnet *ifp)
|
|
|
|
{
|
2005-11-23 07:12:33 +03:00
|
|
|
int pri, tx_timeouts = 0;
|
2004-12-19 11:19:25 +03:00
|
|
|
struct rtw_softc *sc;
|
2004-12-29 04:06:52 +03:00
|
|
|
struct rtw_txsoft_blk *tsb;
|
2004-12-19 11:19:25 +03:00
|
|
|
|
|
|
|
sc = ifp->if_softc;
|
|
|
|
|
|
|
|
ifp->if_timer = 0;
|
|
|
|
|
Use device_t and its accessors throughout. Use aprint_*_dev().
Improve PMF-ability.
Add a 'flags' argument to suspend/resume handlers and
callers such as pmf_system_suspend().
Define a flag, PMF_F_SELF, which indicates to PMF that a
device is suspending/resuming itself. Add helper routines,
pmf_device_suspend_self(dev) and pmf_device_resume_self(dev),
that call pmf_device_suspend(dev, PMF_F_SELF) and
pmf_device_resume(dev, PMF_F_SELF), respectively. Use
PMF_F_SELF to suspend/resume self in ath(4), audio(4),
rtw(4), and sip(4).
In ath(4) and in rtw(4), replace the icky sc_enable/sc_disable
callbacks, provided by the bus front-end, with
self-suspension/resumption. Also, clean up the bus
front-ends. Make sure that the interrupt handler is
disestablished during suspension. Get rid of driver-private
flags (e.g., RTW_F_ENABLED, ath_softc->sc_invalid); use
device_is_active()/device_has_power() calls, instead.
In the network-class suspend handler, call if_stop(, 0)
instead of if_stop(, 1), because the latter is superfluous
(bus- and driver-suspension hooks will 'disable' the NIC),
and it may cause recursion.
In the network-class resume handler, prevent infinite
recursion through if_init() by getting out early if we are
self-suspending (PMF_F_SELF).
rtw(4) improvements:
Destroy rtw(4) callouts when we detach it. Make rtw at
pci detachable. Print some more information with the "rx
frame too long" warning.
Remove activate() methods:
Get rid of rtw_activate() and ath_activate(). The device
activate() methods are not good for much these days.
Make ath at cardbus resume with crypto functions intact:
Introduce a boolean device property, "pmf-powerdown". If
pmf-powerdown is present and false, it indicates that a
bus back-end should not remove power from a device.
Honor this property in cardbus_child_suspend().
Set this property to 'false' in ath_attach(), since removing
power from an ath at cardbus seems to lobotomize the WPA
crypto engine. XXX Should the pmf-powerdown property
propagate toward the root of the device tree?
Miscellaneous ath(4) changes:
Warn if ath(4) tries to write crypto keys to suspended
hardware.
Reduce differences between FreeBSD and NetBSD in ath(4)
multicast filter setup.
Make ath_printrxbuf() print an rx descriptor's status &
key index, to help debug crypto errors.
Shorten a staircase in ath_ioctl(). Don't check for
ieee80211_ioctl() return code ERESTART, it never happens.
2008-03-12 21:02:21 +03:00
|
|
|
if (!device_is_active(sc->sc_dev))
|
2004-12-19 11:19:25 +03:00
|
|
|
return;
|
|
|
|
|
|
|
|
for (pri = 0; pri < RTW_NTXPRI; pri++) {
|
2004-12-29 04:06:52 +03:00
|
|
|
tsb = &sc->sc_txsoft_blk[pri];
|
2004-12-19 11:19:25 +03:00
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
if (tsb->tsb_tx_timer == 0)
|
2004-12-19 11:19:25 +03:00
|
|
|
continue;
|
2005-11-23 07:12:33 +03:00
|
|
|
else if (--tsb->tsb_tx_timer == 0) {
|
2004-12-29 04:06:52 +03:00
|
|
|
if (SIMPLEQ_EMPTY(&tsb->tsb_dirtyq))
|
2004-12-19 11:19:25 +03:00
|
|
|
continue;
|
2009-04-02 04:57:20 +04:00
|
|
|
else if (rtw_collect_txring(sc, tsb,
|
|
|
|
&sc->sc_txdesc_blk[pri], 0))
|
|
|
|
continue;
|
2004-12-19 11:19:25 +03:00
|
|
|
printf("%s: transmit timeout, priority %d\n",
|
|
|
|
ifp->if_xname, pri);
|
|
|
|
ifp->if_oerrors++;
|
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
|
|
|
if (pri != RTW_TXPRIBCN)
|
|
|
|
tx_timeouts++;
|
2004-12-19 11:19:25 +03:00
|
|
|
} else
|
|
|
|
ifp->if_timer = 1;
|
|
|
|
}
|
2005-11-23 07:12:33 +03:00
|
|
|
|
|
|
|
if (tx_timeouts > 0) {
|
|
|
|
/* Stop Tx DMA, disable xmtr, flush Tx rings, enable xmtr,
|
|
|
|
* reset s/w tx-ring pointers, and start transmission.
|
|
|
|
*
|
|
|
|
* TBD Stop/restart just the broken rings?
|
|
|
|
*/
|
|
|
|
rtw_idle(&sc->sc_regs);
|
2009-04-02 04:57:20 +04:00
|
|
|
rtw_io_enable(sc, RTW_CR_RE | RTW_CR_TE, 0);
|
2005-11-23 07:12:33 +03:00
|
|
|
rtw_txdescs_reset(sc);
|
2009-04-02 04:57:20 +04:00
|
|
|
rtw_io_enable(sc, RTW_CR_RE | RTW_CR_TE, 1);
|
2005-11-23 07:12:33 +03:00
|
|
|
rtw_start(ifp);
|
|
|
|
}
|
2005-06-22 10:14:51 +04:00
|
|
|
ieee80211_watchdog(&sc->sc_ic);
|
2004-09-26 06:29:15 +04:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
rtw_next_scan(void *arg)
|
|
|
|
{
|
|
|
|
struct ieee80211com *ic = arg;
|
|
|
|
int s;
|
|
|
|
|
|
|
|
/* don't call rtw_start w/o network interrupts blocked */
|
|
|
|
s = splnet();
|
|
|
|
if (ic->ic_state == IEEE80211_S_SCAN)
|
|
|
|
ieee80211_next_scan(ic);
|
|
|
|
splx(s);
|
|
|
|
}
|
|
|
|
|
2004-12-21 02:05:41 +03:00
|
|
|
static void
|
2005-03-02 08:20:43 +03:00
|
|
|
rtw_join_bss(struct rtw_softc *sc, uint8_t *bssid, uint16_t intval0)
|
2004-12-21 02:05:41 +03:00
|
|
|
{
|
2005-11-23 07:12:33 +03:00
|
|
|
uint16_t bcnitv, bintritv, intval;
|
2004-12-21 02:05:41 +03:00
|
|
|
int i;
|
|
|
|
struct rtw_regs *regs = &sc->sc_regs;
|
|
|
|
|
|
|
|
for (i = 0; i < IEEE80211_ADDR_LEN; i++)
|
|
|
|
RTW_WRITE8(regs, RTW_BSSID + i, bssid[i]);
|
|
|
|
|
|
|
|
RTW_SYNC(regs, RTW_BSSID16, RTW_BSSID32);
|
|
|
|
|
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
|
|
|
rtw_set_access(regs, RTW_ACCESS_CONFIG);
|
2004-12-21 02:05:41 +03:00
|
|
|
|
Per discussion on tech-kern and tech-userlevel, move the bit-twiddling
macros, __BIT, __BITS, SHIFTIN, SHIFTOUT, and __arraycount() from
lib/libkern/libkern.h to sys/cdefs.h. Add a __-prefix to SHIFTIN
and SHIFTOUT, and add a manual page for the bit-twiddling macros,
bits(3).
Make the __BIT and __BITS macros "widthless," as best I can, by
changing their type to uintmax_t from uint32_t. XXX The manual
page lags this change by a bit.
Define __PRIxBIT and __PRIxBITS printf(3) format strings.
2006-08-31 23:24:37 +04:00
|
|
|
intval = MIN(intval0, __SHIFTOUT_MASK(RTW_BCNITV_BCNITV_MASK));
|
2004-12-21 02:05:41 +03:00
|
|
|
|
|
|
|
bcnitv = RTW_READ16(regs, RTW_BCNITV) & ~RTW_BCNITV_BCNITV_MASK;
|
Per discussion on tech-kern and tech-userlevel, move the bit-twiddling
macros, __BIT, __BITS, SHIFTIN, SHIFTOUT, and __arraycount() from
lib/libkern/libkern.h to sys/cdefs.h. Add a __-prefix to SHIFTIN
and SHIFTOUT, and add a manual page for the bit-twiddling macros,
bits(3).
Make the __BIT and __BITS macros "widthless," as best I can, by
changing their type to uintmax_t from uint32_t. XXX The manual
page lags this change by a bit.
Define __PRIxBIT and __PRIxBITS printf(3) format strings.
2006-08-31 23:24:37 +04:00
|
|
|
bcnitv |= __SHIFTIN(intval, RTW_BCNITV_BCNITV_MASK);
|
2004-12-21 02:05:41 +03:00
|
|
|
RTW_WRITE16(regs, RTW_BCNITV, bcnitv);
|
2005-11-23 07:12:33 +03:00
|
|
|
/* interrupt host 1ms before the TBTT */
|
|
|
|
bintritv = RTW_READ16(regs, RTW_BINTRITV) & ~RTW_BINTRITV_BINTRITV;
|
Per discussion on tech-kern and tech-userlevel, move the bit-twiddling
macros, __BIT, __BITS, SHIFTIN, SHIFTOUT, and __arraycount() from
lib/libkern/libkern.h to sys/cdefs.h. Add a __-prefix to SHIFTIN
and SHIFTOUT, and add a manual page for the bit-twiddling macros,
bits(3).
Make the __BIT and __BITS macros "widthless," as best I can, by
changing their type to uintmax_t from uint32_t. XXX The manual
page lags this change by a bit.
Define __PRIxBIT and __PRIxBITS printf(3) format strings.
2006-08-31 23:24:37 +04:00
|
|
|
bintritv |= __SHIFTIN(1000, RTW_BINTRITV_BINTRITV);
|
2005-11-23 07:12:33 +03:00
|
|
|
RTW_WRITE16(regs, RTW_BINTRITV, bintritv);
|
2004-12-21 02:05:41 +03:00
|
|
|
/* magic from Linux */
|
Per discussion on tech-kern and tech-userlevel, move the bit-twiddling
macros, __BIT, __BITS, SHIFTIN, SHIFTOUT, and __arraycount() from
lib/libkern/libkern.h to sys/cdefs.h. Add a __-prefix to SHIFTIN
and SHIFTOUT, and add a manual page for the bit-twiddling macros,
bits(3).
Make the __BIT and __BITS macros "widthless," as best I can, by
changing their type to uintmax_t from uint32_t. XXX The manual
page lags this change by a bit.
Define __PRIxBIT and __PRIxBITS printf(3) format strings.
2006-08-31 23:24:37 +04:00
|
|
|
RTW_WRITE16(regs, RTW_ATIMWND, __SHIFTIN(1, RTW_ATIMWND_ATIMWND));
|
|
|
|
RTW_WRITE16(regs, RTW_ATIMTRITV, __SHIFTIN(2, RTW_ATIMTRITV_ATIMTRITV));
|
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
|
|
|
rtw_set_access(regs, RTW_ACCESS_NONE);
|
2004-12-21 02:05:41 +03:00
|
|
|
|
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
|
|
|
rtw_io_enable(sc, RTW_CR_RE | RTW_CR_TE, 1);
|
2004-12-21 02:05:41 +03:00
|
|
|
}
|
|
|
|
|
2004-09-26 06:29:15 +04:00
|
|
|
/* Synchronize the hardware state with the software state. */
|
|
|
|
static int
|
|
|
|
rtw_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
|
|
|
|
{
|
2005-06-22 10:14:51 +04:00
|
|
|
struct ifnet *ifp = ic->ic_ifp;
|
|
|
|
struct rtw_softc *sc = (struct rtw_softc *)ifp->if_softc;
|
2004-09-26 06:29:15 +04:00
|
|
|
enum ieee80211_state ostate;
|
|
|
|
int error;
|
|
|
|
|
|
|
|
ostate = ic->ic_state;
|
|
|
|
|
Use device_t and its accessors throughout. Use aprint_*_dev().
Improve PMF-ability.
Add a 'flags' argument to suspend/resume handlers and
callers such as pmf_system_suspend().
Define a flag, PMF_F_SELF, which indicates to PMF that a
device is suspending/resuming itself. Add helper routines,
pmf_device_suspend_self(dev) and pmf_device_resume_self(dev),
that call pmf_device_suspend(dev, PMF_F_SELF) and
pmf_device_resume(dev, PMF_F_SELF), respectively. Use
PMF_F_SELF to suspend/resume self in ath(4), audio(4),
rtw(4), and sip(4).
In ath(4) and in rtw(4), replace the icky sc_enable/sc_disable
callbacks, provided by the bus front-end, with
self-suspension/resumption. Also, clean up the bus
front-ends. Make sure that the interrupt handler is
disestablished during suspension. Get rid of driver-private
flags (e.g., RTW_F_ENABLED, ath_softc->sc_invalid); use
device_is_active()/device_has_power() calls, instead.
In the network-class suspend handler, call if_stop(, 0)
instead of if_stop(, 1), because the latter is superfluous
(bus- and driver-suspension hooks will 'disable' the NIC),
and it may cause recursion.
In the network-class resume handler, prevent infinite
recursion through if_init() by getting out early if we are
self-suspending (PMF_F_SELF).
rtw(4) improvements:
Destroy rtw(4) callouts when we detach it. Make rtw at
pci detachable. Print some more information with the "rx
frame too long" warning.
Remove activate() methods:
Get rid of rtw_activate() and ath_activate(). The device
activate() methods are not good for much these days.
Make ath at cardbus resume with crypto functions intact:
Introduce a boolean device property, "pmf-powerdown". If
pmf-powerdown is present and false, it indicates that a
bus back-end should not remove power from a device.
Honor this property in cardbus_child_suspend().
Set this property to 'false' in ath_attach(), since removing
power from an ath at cardbus seems to lobotomize the WPA
crypto engine. XXX Should the pmf-powerdown property
propagate toward the root of the device tree?
Miscellaneous ath(4) changes:
Warn if ath(4) tries to write crypto keys to suspended
hardware.
Reduce differences between FreeBSD and NetBSD in ath(4)
multicast filter setup.
Make ath_printrxbuf() print an rx descriptor's status &
key index, to help debug crypto errors.
Shorten a staircase in ath_ioctl(). Don't check for
ieee80211_ioctl() return code ERESTART, it never happens.
2008-03-12 21:02:21 +03:00
|
|
|
aprint_debug_dev(sc->sc_dev, "%s: l.%d\n", __func__, __LINE__);
|
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
|
|
|
rtw_led_newstate(sc, nstate);
|
|
|
|
|
Use device_t and its accessors throughout. Use aprint_*_dev().
Improve PMF-ability.
Add a 'flags' argument to suspend/resume handlers and
callers such as pmf_system_suspend().
Define a flag, PMF_F_SELF, which indicates to PMF that a
device is suspending/resuming itself. Add helper routines,
pmf_device_suspend_self(dev) and pmf_device_resume_self(dev),
that call pmf_device_suspend(dev, PMF_F_SELF) and
pmf_device_resume(dev, PMF_F_SELF), respectively. Use
PMF_F_SELF to suspend/resume self in ath(4), audio(4),
rtw(4), and sip(4).
In ath(4) and in rtw(4), replace the icky sc_enable/sc_disable
callbacks, provided by the bus front-end, with
self-suspension/resumption. Also, clean up the bus
front-ends. Make sure that the interrupt handler is
disestablished during suspension. Get rid of driver-private
flags (e.g., RTW_F_ENABLED, ath_softc->sc_invalid); use
device_is_active()/device_has_power() calls, instead.
In the network-class suspend handler, call if_stop(, 0)
instead of if_stop(, 1), because the latter is superfluous
(bus- and driver-suspension hooks will 'disable' the NIC),
and it may cause recursion.
In the network-class resume handler, prevent infinite
recursion through if_init() by getting out early if we are
self-suspending (PMF_F_SELF).
rtw(4) improvements:
Destroy rtw(4) callouts when we detach it. Make rtw at
pci detachable. Print some more information with the "rx
frame too long" warning.
Remove activate() methods:
Get rid of rtw_activate() and ath_activate(). The device
activate() methods are not good for much these days.
Make ath at cardbus resume with crypto functions intact:
Introduce a boolean device property, "pmf-powerdown". If
pmf-powerdown is present and false, it indicates that a
bus back-end should not remove power from a device.
Honor this property in cardbus_child_suspend().
Set this property to 'false' in ath_attach(), since removing
power from an ath at cardbus seems to lobotomize the WPA
crypto engine. XXX Should the pmf-powerdown property
propagate toward the root of the device tree?
Miscellaneous ath(4) changes:
Warn if ath(4) tries to write crypto keys to suspended
hardware.
Reduce differences between FreeBSD and NetBSD in ath(4)
multicast filter setup.
Make ath_printrxbuf() print an rx descriptor's status &
key index, to help debug crypto errors.
Shorten a staircase in ath_ioctl(). Don't check for
ieee80211_ioctl() return code ERESTART, it never happens.
2008-03-12 21:02:21 +03:00
|
|
|
aprint_debug_dev(sc->sc_dev, "%s: l.%d\n", __func__, __LINE__);
|
2004-09-26 06:29:15 +04:00
|
|
|
if (nstate == IEEE80211_S_INIT) {
|
|
|
|
callout_stop(&sc->sc_scan_ch);
|
|
|
|
sc->sc_cur_chan = IEEE80211_CHAN_ANY;
|
|
|
|
return (*sc->sc_mtbl.mt_newstate)(ic, nstate, arg);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ostate == IEEE80211_S_INIT && nstate != IEEE80211_S_INIT)
|
|
|
|
rtw_pwrstate(sc, RTW_ON);
|
|
|
|
|
|
|
|
if ((error = rtw_tune(sc)) != 0)
|
|
|
|
return error;
|
|
|
|
|
|
|
|
switch (nstate) {
|
|
|
|
case IEEE80211_S_INIT:
|
|
|
|
panic("%s: unexpected state IEEE80211_S_INIT\n", __func__);
|
|
|
|
break;
|
|
|
|
case IEEE80211_S_SCAN:
|
2004-12-25 09:58:37 +03:00
|
|
|
if (ostate != IEEE80211_S_SCAN) {
|
|
|
|
(void)memset(ic->ic_bss->ni_bssid, 0,
|
|
|
|
IEEE80211_ADDR_LEN);
|
2005-03-02 08:20:43 +03:00
|
|
|
rtw_set_nettype(sc, IEEE80211_M_MONITOR);
|
2004-12-25 09:58:37 +03:00
|
|
|
}
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
callout_reset(&sc->sc_scan_ch, rtw_dwelltime * hz / 1000,
|
|
|
|
rtw_next_scan, ic);
|
|
|
|
|
|
|
|
break;
|
|
|
|
case IEEE80211_S_RUN:
|
2005-01-03 06:07:12 +03:00
|
|
|
switch (ic->ic_opmode) {
|
|
|
|
case IEEE80211_M_HOSTAP:
|
|
|
|
case IEEE80211_M_IBSS:
|
2005-03-02 08:20:43 +03:00
|
|
|
rtw_set_nettype(sc, IEEE80211_M_MONITOR);
|
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
|
|
|
/*FALLTHROUGH*/
|
|
|
|
case IEEE80211_M_AHDEMO:
|
2005-03-02 08:20:43 +03:00
|
|
|
case IEEE80211_M_STA:
|
|
|
|
rtw_join_bss(sc, ic->ic_bss->ni_bssid,
|
2005-01-03 06:07:12 +03:00
|
|
|
ic->ic_bss->ni_intval);
|
2004-09-26 06:29:15 +04:00
|
|
|
break;
|
2005-01-03 06:07:12 +03:00
|
|
|
case IEEE80211_M_MONITOR:
|
2004-09-26 06:29:15 +04:00
|
|
|
break;
|
2005-01-03 06:07:12 +03:00
|
|
|
}
|
2005-03-02 08:20:43 +03:00
|
|
|
rtw_set_nettype(sc, ic->ic_opmode);
|
2005-01-03 06:07:12 +03:00
|
|
|
break;
|
2005-03-02 08:20:43 +03:00
|
|
|
case IEEE80211_S_ASSOC:
|
2005-01-03 06:07:12 +03:00
|
|
|
case IEEE80211_S_AUTH:
|
2004-09-26 06:29:15 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (nstate != IEEE80211_S_SCAN)
|
|
|
|
callout_stop(&sc->sc_scan_ch);
|
|
|
|
|
|
|
|
return (*sc->sc_mtbl.mt_newstate)(ic, nstate, arg);
|
|
|
|
}
|
|
|
|
|
2005-01-04 04:00:30 +03:00
|
|
|
/* Extend a 32-bit TSF timestamp to a 64-bit timestamp. */
|
|
|
|
static uint64_t
|
|
|
|
rtw_tsf_extend(struct rtw_regs *regs, uint32_t rstamp)
|
|
|
|
{
|
|
|
|
uint32_t tsftl, tsfth;
|
|
|
|
|
|
|
|
tsfth = RTW_READ(regs, RTW_TSFTRH);
|
|
|
|
tsftl = RTW_READ(regs, RTW_TSFTRL);
|
|
|
|
if (tsftl < rstamp) /* Compensate for rollover. */
|
|
|
|
tsfth--;
|
|
|
|
return ((uint64_t)tsfth << 32) | rstamp;
|
|
|
|
}
|
|
|
|
|
2004-09-26 06:29:15 +04:00
|
|
|
static void
|
|
|
|
rtw_recv_mgmt(struct ieee80211com *ic, struct mbuf *m,
|
2005-01-02 07:23:03 +03:00
|
|
|
struct ieee80211_node *ni, int subtype, int rssi, uint32_t rstamp)
|
2004-09-26 06:29:15 +04:00
|
|
|
{
|
2005-06-22 10:14:51 +04:00
|
|
|
struct ifnet *ifp = ic->ic_ifp;
|
|
|
|
struct rtw_softc *sc = (struct rtw_softc *)ifp->if_softc;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2005-01-04 04:00:30 +03:00
|
|
|
(*sc->sc_mtbl.mt_recv_mgmt)(ic, m, ni, subtype, rssi, rstamp);
|
|
|
|
|
2004-09-26 06:29:15 +04:00
|
|
|
switch (subtype) {
|
|
|
|
case IEEE80211_FC0_SUBTYPE_PROBE_RESP:
|
|
|
|
case IEEE80211_FC0_SUBTYPE_BEACON:
|
2005-12-30 01:23:52 +03:00
|
|
|
if (ic->ic_opmode == IEEE80211_M_IBSS &&
|
Use device_t and its accessors throughout. Use aprint_*_dev().
Improve PMF-ability.
Add a 'flags' argument to suspend/resume handlers and
callers such as pmf_system_suspend().
Define a flag, PMF_F_SELF, which indicates to PMF that a
device is suspending/resuming itself. Add helper routines,
pmf_device_suspend_self(dev) and pmf_device_resume_self(dev),
that call pmf_device_suspend(dev, PMF_F_SELF) and
pmf_device_resume(dev, PMF_F_SELF), respectively. Use
PMF_F_SELF to suspend/resume self in ath(4), audio(4),
rtw(4), and sip(4).
In ath(4) and in rtw(4), replace the icky sc_enable/sc_disable
callbacks, provided by the bus front-end, with
self-suspension/resumption. Also, clean up the bus
front-ends. Make sure that the interrupt handler is
disestablished during suspension. Get rid of driver-private
flags (e.g., RTW_F_ENABLED, ath_softc->sc_invalid); use
device_is_active()/device_has_power() calls, instead.
In the network-class suspend handler, call if_stop(, 0)
instead of if_stop(, 1), because the latter is superfluous
(bus- and driver-suspension hooks will 'disable' the NIC),
and it may cause recursion.
In the network-class resume handler, prevent infinite
recursion through if_init() by getting out early if we are
self-suspending (PMF_F_SELF).
rtw(4) improvements:
Destroy rtw(4) callouts when we detach it. Make rtw at
pci detachable. Print some more information with the "rx
frame too long" warning.
Remove activate() methods:
Get rid of rtw_activate() and ath_activate(). The device
activate() methods are not good for much these days.
Make ath at cardbus resume with crypto functions intact:
Introduce a boolean device property, "pmf-powerdown". If
pmf-powerdown is present and false, it indicates that a
bus back-end should not remove power from a device.
Honor this property in cardbus_child_suspend().
Set this property to 'false' in ath_attach(), since removing
power from an ath at cardbus seems to lobotomize the WPA
crypto engine. XXX Should the pmf-powerdown property
propagate toward the root of the device tree?
Miscellaneous ath(4) changes:
Warn if ath(4) tries to write crypto keys to suspended
hardware.
Reduce differences between FreeBSD and NetBSD in ath(4)
multicast filter setup.
Make ath_printrxbuf() print an rx descriptor's status &
key index, to help debug crypto errors.
Shorten a staircase in ath_ioctl(). Don't check for
ieee80211_ioctl() return code ERESTART, it never happens.
2008-03-12 21:02:21 +03:00
|
|
|
ic->ic_state == IEEE80211_S_RUN &&
|
|
|
|
device_is_active(sc->sc_dev)) {
|
2005-12-30 01:23:52 +03:00
|
|
|
uint64_t tsf = rtw_tsf_extend(&sc->sc_regs, rstamp);
|
|
|
|
if (le64toh(ni->ni_tstamp.tsf) >= tsf)
|
|
|
|
(void)ieee80211_ibss_merge(ni);
|
|
|
|
}
|
2004-09-26 06:29:15 +04:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct ieee80211_node *
|
2005-06-22 10:14:51 +04:00
|
|
|
rtw_node_alloc(struct ieee80211_node_table *nt)
|
2004-09-26 06:29:15 +04:00
|
|
|
{
|
2005-06-22 10:14:51 +04:00
|
|
|
struct ifnet *ifp = nt->nt_ic->ic_ifp;
|
|
|
|
struct rtw_softc *sc = (struct rtw_softc *)ifp->if_softc;
|
|
|
|
struct ieee80211_node *ni = (*sc->sc_mtbl.mt_node_alloc)(nt);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2004-12-25 09:58:37 +03:00
|
|
|
DPRINTF(sc, RTW_DEBUG_NODE,
|
2007-12-21 21:22:43 +03:00
|
|
|
("%s: alloc node %p\n", device_xname(sc->sc_dev), ni));
|
2004-09-26 06:29:15 +04:00
|
|
|
return ni;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2005-06-22 10:14:51 +04:00
|
|
|
rtw_node_free(struct ieee80211_node *ni)
|
2004-09-26 06:29:15 +04:00
|
|
|
{
|
2005-06-22 10:14:51 +04:00
|
|
|
struct ieee80211com *ic = ni->ni_ic;
|
|
|
|
struct ifnet *ifp = ic->ic_ifp;
|
|
|
|
struct rtw_softc *sc = (struct rtw_softc *)ifp->if_softc;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2004-12-25 09:58:37 +03:00
|
|
|
DPRINTF(sc, RTW_DEBUG_NODE,
|
2007-12-21 21:22:43 +03:00
|
|
|
("%s: freeing node %p %s\n", device_xname(sc->sc_dev), ni,
|
2004-09-26 06:29:15 +04:00
|
|
|
ether_sprintf(ni->ni_bssid)));
|
2005-06-22 10:14:51 +04:00
|
|
|
(*sc->sc_mtbl.mt_node_free)(ni);
|
2004-09-26 06:29:15 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
rtw_media_change(struct ifnet *ifp)
|
|
|
|
{
|
|
|
|
int error;
|
|
|
|
|
|
|
|
error = ieee80211_media_change(ifp);
|
|
|
|
if (error == ENETRESET) {
|
|
|
|
if ((ifp->if_flags & (IFF_RUNNING|IFF_UP)) ==
|
|
|
|
(IFF_RUNNING|IFF_UP))
|
|
|
|
rtw_init(ifp); /* XXX lose error */
|
|
|
|
error = 0;
|
|
|
|
}
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
rtw_media_status(struct ifnet *ifp, struct ifmediareq *imr)
|
|
|
|
{
|
|
|
|
struct rtw_softc *sc = ifp->if_softc;
|
|
|
|
|
Use device_t and its accessors throughout. Use aprint_*_dev().
Improve PMF-ability.
Add a 'flags' argument to suspend/resume handlers and
callers such as pmf_system_suspend().
Define a flag, PMF_F_SELF, which indicates to PMF that a
device is suspending/resuming itself. Add helper routines,
pmf_device_suspend_self(dev) and pmf_device_resume_self(dev),
that call pmf_device_suspend(dev, PMF_F_SELF) and
pmf_device_resume(dev, PMF_F_SELF), respectively. Use
PMF_F_SELF to suspend/resume self in ath(4), audio(4),
rtw(4), and sip(4).
In ath(4) and in rtw(4), replace the icky sc_enable/sc_disable
callbacks, provided by the bus front-end, with
self-suspension/resumption. Also, clean up the bus
front-ends. Make sure that the interrupt handler is
disestablished during suspension. Get rid of driver-private
flags (e.g., RTW_F_ENABLED, ath_softc->sc_invalid); use
device_is_active()/device_has_power() calls, instead.
In the network-class suspend handler, call if_stop(, 0)
instead of if_stop(, 1), because the latter is superfluous
(bus- and driver-suspension hooks will 'disable' the NIC),
and it may cause recursion.
In the network-class resume handler, prevent infinite
recursion through if_init() by getting out early if we are
self-suspending (PMF_F_SELF).
rtw(4) improvements:
Destroy rtw(4) callouts when we detach it. Make rtw at
pci detachable. Print some more information with the "rx
frame too long" warning.
Remove activate() methods:
Get rid of rtw_activate() and ath_activate(). The device
activate() methods are not good for much these days.
Make ath at cardbus resume with crypto functions intact:
Introduce a boolean device property, "pmf-powerdown". If
pmf-powerdown is present and false, it indicates that a
bus back-end should not remove power from a device.
Honor this property in cardbus_child_suspend().
Set this property to 'false' in ath_attach(), since removing
power from an ath at cardbus seems to lobotomize the WPA
crypto engine. XXX Should the pmf-powerdown property
propagate toward the root of the device tree?
Miscellaneous ath(4) changes:
Warn if ath(4) tries to write crypto keys to suspended
hardware.
Reduce differences between FreeBSD and NetBSD in ath(4)
multicast filter setup.
Make ath_printrxbuf() print an rx descriptor's status &
key index, to help debug crypto errors.
Shorten a staircase in ath_ioctl(). Don't check for
ieee80211_ioctl() return code ERESTART, it never happens.
2008-03-12 21:02:21 +03:00
|
|
|
if (!device_is_active(sc->sc_dev)) {
|
2004-09-26 06:29:15 +04:00
|
|
|
imr->ifm_active = IFM_IEEE80211 | IFM_NONE;
|
|
|
|
imr->ifm_status = 0;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
ieee80211_media_status(ifp, imr);
|
|
|
|
}
|
|
|
|
|
2005-12-24 23:27:29 +03:00
|
|
|
static inline void
|
2004-12-20 03:28:02 +03:00
|
|
|
rtw_setifprops(struct ifnet *ifp, const char *dvname, void *softc)
|
2004-09-26 06:29:15 +04:00
|
|
|
{
|
2007-12-21 21:22:43 +03:00
|
|
|
(void)strlcpy(ifp->if_xname, dvname, IFNAMSIZ);
|
2004-09-26 06:29:15 +04:00
|
|
|
ifp->if_softc = softc;
|
|
|
|
ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST |
|
|
|
|
IFF_NOTRAILERS;
|
|
|
|
ifp->if_ioctl = rtw_ioctl;
|
|
|
|
ifp->if_start = rtw_start;
|
|
|
|
ifp->if_watchdog = rtw_watchdog;
|
|
|
|
ifp->if_init = rtw_init;
|
|
|
|
ifp->if_stop = rtw_stop;
|
|
|
|
}
|
|
|
|
|
2005-12-24 23:27:29 +03:00
|
|
|
static inline void
|
2004-09-26 06:29:15 +04:00
|
|
|
rtw_set80211props(struct ieee80211com *ic)
|
|
|
|
{
|
|
|
|
int nrate;
|
|
|
|
ic->ic_phytype = IEEE80211_T_DS;
|
|
|
|
ic->ic_opmode = IEEE80211_M_STA;
|
|
|
|
ic->ic_caps = IEEE80211_C_PMGT | IEEE80211_C_IBSS |
|
2009-04-02 04:57:20 +04:00
|
|
|
IEEE80211_C_HOSTAP | IEEE80211_C_MONITOR | IEEE80211_C_WEP;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
nrate = 0;
|
2004-12-23 08:47:42 +03:00
|
|
|
ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[nrate++] =
|
|
|
|
IEEE80211_RATE_BASIC | 2;
|
|
|
|
ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[nrate++] =
|
|
|
|
IEEE80211_RATE_BASIC | 4;
|
2004-09-26 06:29:15 +04:00
|
|
|
ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[nrate++] = 11;
|
|
|
|
ic->ic_sup_rates[IEEE80211_MODE_11B].rs_rates[nrate++] = 22;
|
|
|
|
ic->ic_sup_rates[IEEE80211_MODE_11B].rs_nrates = nrate;
|
|
|
|
}
|
|
|
|
|
2005-12-24 23:27:29 +03:00
|
|
|
static inline void
|
2004-09-26 06:29:15 +04:00
|
|
|
rtw_set80211methods(struct rtw_mtbl *mtbl, struct ieee80211com *ic)
|
|
|
|
{
|
|
|
|
mtbl->mt_newstate = ic->ic_newstate;
|
|
|
|
ic->ic_newstate = rtw_newstate;
|
|
|
|
|
|
|
|
mtbl->mt_recv_mgmt = ic->ic_recv_mgmt;
|
|
|
|
ic->ic_recv_mgmt = rtw_recv_mgmt;
|
|
|
|
|
|
|
|
mtbl->mt_node_free = ic->ic_node_free;
|
|
|
|
ic->ic_node_free = rtw_node_free;
|
|
|
|
|
|
|
|
mtbl->mt_node_alloc = ic->ic_node_alloc;
|
|
|
|
ic->ic_node_alloc = rtw_node_alloc;
|
2005-06-27 09:49:13 +04:00
|
|
|
|
|
|
|
ic->ic_crypto.cs_key_delete = rtw_key_delete;
|
|
|
|
ic->ic_crypto.cs_key_set = rtw_key_set;
|
|
|
|
ic->ic_crypto.cs_key_update_begin = rtw_key_update_begin;
|
|
|
|
ic->ic_crypto.cs_key_update_end = rtw_key_update_end;
|
2004-09-26 06:29:15 +04:00
|
|
|
}
|
|
|
|
|
2005-12-24 23:27:29 +03:00
|
|
|
static inline void
|
2004-09-26 06:29:15 +04:00
|
|
|
rtw_init_radiotap(struct rtw_softc *sc)
|
|
|
|
{
|
2007-11-17 02:35:19 +03:00
|
|
|
uint32_t present;
|
|
|
|
|
2004-09-26 06:29:15 +04:00
|
|
|
memset(&sc->sc_rxtapu, 0, sizeof(sc->sc_rxtapu));
|
2004-12-29 01:30:07 +03:00
|
|
|
sc->sc_rxtap.rr_ihdr.it_len = htole16(sizeof(sc->sc_rxtapu));
|
2007-11-17 02:35:19 +03:00
|
|
|
|
|
|
|
if (sc->sc_rfchipid == RTW_RFCHIPID_PHILIPS)
|
|
|
|
present = htole32(RTW_PHILIPS_RX_RADIOTAP_PRESENT);
|
|
|
|
else
|
|
|
|
present = htole32(RTW_RX_RADIOTAP_PRESENT);
|
|
|
|
sc->sc_rxtap.rr_ihdr.it_present = present;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
memset(&sc->sc_txtapu, 0, sizeof(sc->sc_txtapu));
|
2004-12-29 01:30:07 +03:00
|
|
|
sc->sc_txtap.rt_ihdr.it_len = htole16(sizeof(sc->sc_txtapu));
|
|
|
|
sc->sc_txtap.rt_ihdr.it_present = htole32(RTW_TX_RADIOTAP_PRESENT);
|
2004-09-26 06:29:15 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2004-12-29 04:06:52 +03:00
|
|
|
rtw_txsoft_blk_setup(struct rtw_txsoft_blk *tsb, u_int qlen)
|
2004-09-26 06:29:15 +04:00
|
|
|
{
|
2004-12-29 04:06:52 +03:00
|
|
|
SIMPLEQ_INIT(&tsb->tsb_dirtyq);
|
|
|
|
SIMPLEQ_INIT(&tsb->tsb_freeq);
|
|
|
|
tsb->tsb_ndesc = qlen;
|
|
|
|
tsb->tsb_desc = malloc(qlen * sizeof(*tsb->tsb_desc), M_DEVBUF,
|
2004-09-26 06:29:15 +04:00
|
|
|
M_NOWAIT);
|
2004-12-29 04:06:52 +03:00
|
|
|
if (tsb->tsb_desc == NULL)
|
2004-09-26 06:29:15 +04:00
|
|
|
return ENOMEM;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2004-12-29 04:06:52 +03:00
|
|
|
rtw_txsoft_blk_cleanup_all(struct rtw_softc *sc)
|
2004-09-26 06:29:15 +04:00
|
|
|
{
|
|
|
|
int pri;
|
2004-12-29 04:06:52 +03:00
|
|
|
struct rtw_txsoft_blk *tsb;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2004-12-25 09:58:37 +03:00
|
|
|
for (pri = 0; pri < RTW_NTXPRI; pri++) {
|
2004-12-29 04:06:52 +03:00
|
|
|
tsb = &sc->sc_txsoft_blk[pri];
|
|
|
|
free(tsb->tsb_desc, M_DEVBUF);
|
|
|
|
tsb->tsb_desc = NULL;
|
2004-09-26 06:29:15 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2004-12-29 04:06:52 +03:00
|
|
|
rtw_txsoft_blk_setup_all(struct rtw_softc *sc)
|
2004-09-26 06:29:15 +04:00
|
|
|
{
|
|
|
|
int pri, rc = 0;
|
|
|
|
int qlen[RTW_NTXPRI] =
|
|
|
|
{RTW_TXQLENLO, RTW_TXQLENMD, RTW_TXQLENHI, RTW_TXQLENBCN};
|
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
|
|
|
struct rtw_txsoft_blk *tsbs;
|
|
|
|
|
|
|
|
tsbs = sc->sc_txsoft_blk;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2004-12-25 09:58:37 +03:00
|
|
|
for (pri = 0; pri < RTW_NTXPRI; pri++) {
|
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
|
|
|
rc = rtw_txsoft_blk_setup(&tsbs[pri], qlen[pri]);
|
2004-09-26 06:29:15 +04:00
|
|
|
if (rc != 0)
|
|
|
|
break;
|
|
|
|
}
|
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
|
|
|
tsbs[RTW_TXPRILO].tsb_poll = RTW_TPPOLL_LPQ | RTW_TPPOLL_SLPQ;
|
|
|
|
tsbs[RTW_TXPRIMD].tsb_poll = RTW_TPPOLL_NPQ | RTW_TPPOLL_SNPQ;
|
|
|
|
tsbs[RTW_TXPRIHI].tsb_poll = RTW_TPPOLL_HPQ | RTW_TPPOLL_SHPQ;
|
|
|
|
tsbs[RTW_TXPRIBCN].tsb_poll = RTW_TPPOLL_BQ | RTW_TPPOLL_SBQ;
|
2004-09-26 06:29:15 +04:00
|
|
|
return rc;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2004-12-29 04:06:52 +03:00
|
|
|
rtw_txdesc_blk_setup(struct rtw_txdesc_blk *tdb, struct rtw_txdesc *desc,
|
2004-09-26 06:29:15 +04:00
|
|
|
u_int ndesc, bus_addr_t ofs, bus_addr_t physbase)
|
|
|
|
{
|
2004-12-29 04:06:52 +03:00
|
|
|
tdb->tdb_ndesc = ndesc;
|
|
|
|
tdb->tdb_desc = desc;
|
|
|
|
tdb->tdb_physbase = physbase;
|
|
|
|
tdb->tdb_ofs = ofs;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
(void)memset(tdb->tdb_desc, 0,
|
|
|
|
sizeof(tdb->tdb_desc[0]) * tdb->tdb_ndesc);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2005-11-23 07:12:33 +03:00
|
|
|
rtw_txdesc_blk_init(tdb);
|
|
|
|
tdb->tdb_next = 0;
|
2004-09-26 06:29:15 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
rtw_txdesc_blk_setup_all(struct rtw_softc *sc)
|
|
|
|
{
|
|
|
|
rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRILO],
|
|
|
|
&sc->sc_descs->hd_txlo[0], RTW_NTXDESCLO,
|
|
|
|
RTW_RING_OFFSET(hd_txlo), RTW_RING_BASE(sc, hd_txlo));
|
|
|
|
|
|
|
|
rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRIMD],
|
|
|
|
&sc->sc_descs->hd_txmd[0], RTW_NTXDESCMD,
|
|
|
|
RTW_RING_OFFSET(hd_txmd), RTW_RING_BASE(sc, hd_txmd));
|
|
|
|
|
|
|
|
rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRIHI],
|
|
|
|
&sc->sc_descs->hd_txhi[0], RTW_NTXDESCHI,
|
|
|
|
RTW_RING_OFFSET(hd_txhi), RTW_RING_BASE(sc, hd_txhi));
|
|
|
|
|
|
|
|
rtw_txdesc_blk_setup(&sc->sc_txdesc_blk[RTW_TXPRIBCN],
|
|
|
|
&sc->sc_descs->hd_bcn[0], RTW_NTXDESCBCN,
|
|
|
|
RTW_RING_OFFSET(hd_bcn), RTW_RING_BASE(sc, hd_bcn));
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct rtw_rf *
|
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
|
|
|
rtw_rf_attach(struct rtw_softc *sc, enum rtw_rfchipid rfchipid, int digphy)
|
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
|
|
|
rtw_rf_write_t rf_write;
|
2004-09-26 06:29:15 +04:00
|
|
|
struct rtw_rf *rf;
|
|
|
|
|
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
|
|
|
switch (rfchipid) {
|
|
|
|
default:
|
|
|
|
rf_write = rtw_rf_hostwrite;
|
|
|
|
break;
|
|
|
|
case RTW_RFCHIPID_INTERSIL:
|
|
|
|
case RTW_RFCHIPID_PHILIPS:
|
|
|
|
case RTW_RFCHIPID_GCT: /* XXX a guess */
|
|
|
|
case RTW_RFCHIPID_RFMD:
|
|
|
|
rf_write = (rtw_host_rfio) ? rtw_rf_hostwrite : rtw_rf_macwrite;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2004-09-26 06:29:15 +04:00
|
|
|
switch (rfchipid) {
|
2005-12-30 01:27:17 +03:00
|
|
|
case RTW_RFCHIPID_GCT:
|
|
|
|
rf = rtw_grf5101_create(&sc->sc_regs, rf_write, 0);
|
|
|
|
sc->sc_pwrstate_cb = rtw_maxim_pwrstate;
|
|
|
|
break;
|
2004-09-26 06:29:15 +04:00
|
|
|
case RTW_RFCHIPID_MAXIM:
|
|
|
|
rf = rtw_max2820_create(&sc->sc_regs, rf_write, 0);
|
|
|
|
sc->sc_pwrstate_cb = rtw_maxim_pwrstate;
|
|
|
|
break;
|
|
|
|
case RTW_RFCHIPID_PHILIPS:
|
|
|
|
rf = rtw_sa2400_create(&sc->sc_regs, rf_write, digphy);
|
|
|
|
sc->sc_pwrstate_cb = rtw_philips_pwrstate;
|
|
|
|
break;
|
2004-12-21 02:05:41 +03:00
|
|
|
case RTW_RFCHIPID_RFMD:
|
|
|
|
/* XXX RFMD has no RF constructor */
|
|
|
|
sc->sc_pwrstate_cb = rtw_rfmd_pwrstate;
|
|
|
|
/*FALLTHROUGH*/
|
2004-09-26 06:29:15 +04:00
|
|
|
default:
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
rf->rf_continuous_tx_cb =
|
|
|
|
(rtw_continuous_tx_cb_t)rtw_continuous_tx_enable;
|
|
|
|
rf->rf_continuous_tx_arg = (void *)sc;
|
|
|
|
return rf;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Revision C and later use a different PHY delay setting than
|
|
|
|
* revisions A and B.
|
|
|
|
*/
|
2005-01-02 07:23:03 +03:00
|
|
|
static uint8_t
|
2005-06-10 06:35:34 +04:00
|
|
|
rtw_check_phydelay(struct rtw_regs *regs, uint32_t old_rcr)
|
2004-09-26 06:29:15 +04:00
|
|
|
{
|
|
|
|
#define REVAB (RTW_RCR_MXDMA_UNLIMITED | RTW_RCR_AICV)
|
|
|
|
#define REVC (REVAB | RTW_RCR_RXFTH_WHOLE)
|
|
|
|
|
Per discussion on tech-kern and tech-userlevel, move the bit-twiddling
macros, __BIT, __BITS, SHIFTIN, SHIFTOUT, and __arraycount() from
lib/libkern/libkern.h to sys/cdefs.h. Add a __-prefix to SHIFTIN
and SHIFTOUT, and add a manual page for the bit-twiddling macros,
bits(3).
Make the __BIT and __BITS macros "widthless," as best I can, by
changing their type to uintmax_t from uint32_t. XXX The manual
page lags this change by a bit.
Define __PRIxBIT and __PRIxBITS printf(3) format strings.
2006-08-31 23:24:37 +04:00
|
|
|
uint8_t phydelay = __SHIFTIN(0x6, RTW_PHYDELAY_PHYDELAY);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
RTW_WRITE(regs, RTW_RCR, REVAB);
|
2004-12-20 04:13:45 +03:00
|
|
|
RTW_WBW(regs, RTW_RCR, RTW_RCR);
|
2004-09-26 06:29:15 +04:00
|
|
|
RTW_WRITE(regs, RTW_RCR, REVC);
|
|
|
|
|
|
|
|
RTW_WBR(regs, RTW_RCR, RTW_RCR);
|
|
|
|
if ((RTW_READ(regs, RTW_RCR) & REVC) == REVC)
|
|
|
|
phydelay |= RTW_PHYDELAY_REVC_MAGIC;
|
|
|
|
|
2005-06-10 06:35:34 +04:00
|
|
|
RTW_WRITE(regs, RTW_RCR, old_rcr); /* restore RCR */
|
2004-12-20 04:13:45 +03:00
|
|
|
RTW_SYNC(regs, RTW_RCR, RTW_RCR);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
return phydelay;
|
|
|
|
#undef REVC
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
rtw_attach(struct rtw_softc *sc)
|
|
|
|
{
|
2005-06-22 10:14:51 +04:00
|
|
|
struct ifnet *ifp = &sc->sc_if;
|
2005-07-11 10:01:42 +04:00
|
|
|
struct ieee80211com *ic = &sc->sc_ic;
|
2004-12-29 04:06:52 +03:00
|
|
|
struct rtw_txsoft_blk *tsb;
|
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
|
|
|
int pri, rc;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
In pmf(9), improve the implementation of device self-suspension
and make suspension by self, by drvctl(8), and by ACPI system sleep
play nice together. Start solidifying some temporary API changes.
1. Extract a new header file, <sys/device_if.h>, from <sys/device.h> and
#include it from <sys/pmf.h> instead of <sys/device.h> to break the
circular dependency between <sys/device.h> and <sys/pmf.h>.
2. Introduce pmf_qual_t, an aggregate of qualifications on a PMF
suspend/resume call. Start to replace instances of PMF_FN_PROTO,
PMF_FN_ARGS, et cetera, with a pmf_qual_t.
3. Introduce the notion of a "suspensor," an entity that holds a
device in suspension. More than one suspensor may hold a device
at once. A device stays suspended as long as at least one
suspensor holds it. A device resumes when the last suspensor
releases it.
Currently, the kernel defines three suspensors,
3a the system-suspensor: for system suspension, initiated
by 'sysctl -w machdep.sleep_state=3', by lid closure, by
power-button press, et cetera,
3b the drvctl-suspensor: for device suspension by /dev/drvctl
ioctl, e.g., drvctl -S sip0.
3c the system self-suspensor: for device drivers that suspend
themselves and their children. Several drivers for network
interfaces put the network device to sleep while it is not
administratively up, that is, after the kernel calls if_stop(,
1). The self-suspensor should not be used directly. See
the description of suspensor delegates, below.
A suspensor can have one or more "delegates". A suspensor can
release devices that its delegates hold suspended. Right now,
only the system self-suspensor has delegates. For each device
that a self-suspending driver attaches, it creates the device's
self-suspensor, a delegate of the system self-suspensor.
Suspensors stop a system-wide suspend/resume cycle from waking
devices that the operator put to sleep with drvctl before the cycle.
They also help self-suspension to work more simply, safely, and in
accord with expectations.
4. Add the notion of device activation level, devact_level_t,
and a routine for checking the current activation level,
device_activation(). Current activation levels are DEVACT_LEVEL_BUS,
DEVACT_LEVEL_DRIVER, and DEVACT_LEVEL_CLASS, which respectively
indicate that the device's bus is active, that the bus and device are
active, and that the bus, device, and the functions of the device's
class (network, audio) are active.
Suspend/resume calls can be qualified with a devact_level_t.
The power-management framework treats a devact_level_t that
qualifies a device suspension as the device's current activation
level; it only runs hooks to reduce the activation level from
the presumed current level to the fully suspended state. The
framework treats a devact_level_t qualifying device resumption
as the target activation level; it only runs hooks to raise the
activation level to the target.
5. Use pmf_qual_t, devact_level_t, and self-suspensors in several
drivers.
6. Temporarily add an unused power-management workqueue that I will
remove or replace, soon.
2009-09-16 20:34:49 +04:00
|
|
|
pmf_self_suspensor_init(sc->sc_dev, &sc->sc_suspensor, &sc->sc_qual);
|
|
|
|
|
2005-11-23 07:12:33 +03:00
|
|
|
rtw_cipher_wep = ieee80211_cipher_wep;
|
|
|
|
rtw_cipher_wep.ic_decap = rtw_wep_decap;
|
|
|
|
|
2004-09-26 06:29:15 +04:00
|
|
|
NEXT_ATTACH_STATE(sc, DETACHED);
|
|
|
|
|
|
|
|
switch (RTW_READ(&sc->sc_regs, RTW_TCR) & RTW_TCR_HWVERID_MASK) {
|
|
|
|
case RTW_TCR_HWVERID_F:
|
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
|
|
|
sc->sc_hwverid = 'F';
|
2004-09-26 06:29:15 +04:00
|
|
|
break;
|
|
|
|
case RTW_TCR_HWVERID_D:
|
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
|
|
|
sc->sc_hwverid = 'D';
|
2004-09-26 06:29:15 +04:00
|
|
|
break;
|
|
|
|
default:
|
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
|
|
|
sc->sc_hwverid = '?';
|
2004-09-26 06:29:15 +04:00
|
|
|
break;
|
|
|
|
}
|
2007-12-21 21:22:43 +03:00
|
|
|
aprint_verbose_dev(sc->sc_dev, "hardware version %c\n",
|
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
|
|
|
sc->sc_hwverid);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
rc = bus_dmamem_alloc(sc->sc_dmat, sizeof(struct rtw_descs),
|
|
|
|
RTW_DESC_ALIGNMENT, 0, &sc->sc_desc_segs, 1, &sc->sc_desc_nsegs,
|
|
|
|
0);
|
|
|
|
|
|
|
|
if (rc != 0) {
|
2007-12-21 21:22:43 +03:00
|
|
|
aprint_error_dev(sc->sc_dev,
|
|
|
|
"could not allocate hw descriptors, error %d\n", rc);
|
2004-09-26 06:29:15 +04:00
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
|
|
|
NEXT_ATTACH_STATE(sc, FINISH_DESC_ALLOC);
|
|
|
|
|
|
|
|
rc = bus_dmamem_map(sc->sc_dmat, &sc->sc_desc_segs,
|
|
|
|
sc->sc_desc_nsegs, sizeof(struct rtw_descs),
|
2007-03-04 08:59:00 +03:00
|
|
|
(void **)&sc->sc_descs, BUS_DMA_COHERENT);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
if (rc != 0) {
|
2007-12-21 21:22:43 +03:00
|
|
|
aprint_error_dev(sc->sc_dev,
|
|
|
|
"could not map hw descriptors, error %d\n", rc);
|
2004-09-26 06:29:15 +04:00
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
NEXT_ATTACH_STATE(sc, FINISH_DESC_MAP);
|
|
|
|
|
|
|
|
rc = bus_dmamap_create(sc->sc_dmat, sizeof(struct rtw_descs), 1,
|
|
|
|
sizeof(struct rtw_descs), 0, 0, &sc->sc_desc_dmamap);
|
|
|
|
|
|
|
|
if (rc != 0) {
|
2007-12-21 21:22:43 +03:00
|
|
|
aprint_error_dev(sc->sc_dev,
|
|
|
|
"could not create DMA map for hw descriptors, error %d\n",
|
|
|
|
rc);
|
2004-09-26 06:29:15 +04:00
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
NEXT_ATTACH_STATE(sc, FINISH_DESCMAP_CREATE);
|
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
sc->sc_rxdesc_blk.rdb_dmat = sc->sc_dmat;
|
|
|
|
sc->sc_rxdesc_blk.rdb_dmamap = sc->sc_desc_dmamap;
|
2004-12-29 03:21:37 +03:00
|
|
|
|
|
|
|
for (pri = 0; pri < RTW_NTXPRI; pri++) {
|
2004-12-29 04:06:52 +03:00
|
|
|
sc->sc_txdesc_blk[pri].tdb_dmat = sc->sc_dmat;
|
|
|
|
sc->sc_txdesc_blk[pri].tdb_dmamap = sc->sc_desc_dmamap;
|
2004-12-29 03:21:37 +03:00
|
|
|
}
|
|
|
|
|
2004-09-26 06:29:15 +04:00
|
|
|
rc = bus_dmamap_load(sc->sc_dmat, sc->sc_desc_dmamap, sc->sc_descs,
|
|
|
|
sizeof(struct rtw_descs), NULL, 0);
|
|
|
|
|
|
|
|
if (rc != 0) {
|
2007-12-21 21:22:43 +03:00
|
|
|
aprint_error_dev(sc->sc_dev,
|
|
|
|
"could not load DMA map for hw descriptors, error %d\n",
|
|
|
|
rc);
|
2004-09-26 06:29:15 +04:00
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
NEXT_ATTACH_STATE(sc, FINISH_DESCMAP_LOAD);
|
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
if (rtw_txsoft_blk_setup_all(sc) != 0)
|
2004-09-26 06:29:15 +04:00
|
|
|
goto err;
|
|
|
|
NEXT_ATTACH_STATE(sc, FINISH_TXCTLBLK_SETUP);
|
|
|
|
|
|
|
|
rtw_txdesc_blk_setup_all(sc);
|
|
|
|
|
|
|
|
NEXT_ATTACH_STATE(sc, FINISH_TXDESCBLK_SETUP);
|
|
|
|
|
2004-12-29 04:06:52 +03:00
|
|
|
sc->sc_rxdesc_blk.rdb_desc = &sc->sc_descs->hd_rx[0];
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
for (pri = 0; pri < RTW_NTXPRI; pri++) {
|
2004-12-29 04:06:52 +03:00
|
|
|
tsb = &sc->sc_txsoft_blk[pri];
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
if ((rc = rtw_txdesc_dmamaps_create(sc->sc_dmat,
|
2004-12-29 04:06:52 +03:00
|
|
|
&tsb->tsb_desc[0], tsb->tsb_ndesc)) != 0) {
|
2007-12-21 21:22:43 +03:00
|
|
|
aprint_error_dev(sc->sc_dev,
|
|
|
|
"could not load DMA map for hw tx descriptors, "
|
|
|
|
"error %d\n", rc);
|
2004-09-26 06:29:15 +04:00
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
NEXT_ATTACH_STATE(sc, FINISH_TXMAPS_CREATE);
|
2004-12-29 04:06:52 +03:00
|
|
|
if ((rc = rtw_rxdesc_dmamaps_create(sc->sc_dmat, &sc->sc_rxsoft[0],
|
2004-09-26 06:29:15 +04:00
|
|
|
RTW_RXQLEN)) != 0) {
|
2007-12-21 21:22:43 +03:00
|
|
|
aprint_error_dev(sc->sc_dev,
|
|
|
|
"could not load DMA map for hw rx descriptors, error %d\n",
|
|
|
|
rc);
|
2004-09-26 06:29:15 +04:00
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
NEXT_ATTACH_STATE(sc, FINISH_RXMAPS_CREATE);
|
|
|
|
|
|
|
|
/* Reset the chip to a known state. */
|
|
|
|
if (rtw_reset(sc) != 0)
|
|
|
|
goto err;
|
|
|
|
NEXT_ATTACH_STATE(sc, FINISH_RESET);
|
|
|
|
|
|
|
|
sc->sc_rcr = RTW_READ(&sc->sc_regs, RTW_RCR);
|
|
|
|
|
|
|
|
if ((sc->sc_rcr & RTW_RCR_9356SEL) != 0)
|
|
|
|
sc->sc_flags |= RTW_F_9356SROM;
|
|
|
|
|
|
|
|
if (rtw_srom_read(&sc->sc_regs, sc->sc_flags, &sc->sc_srom,
|
2007-12-21 21:22:43 +03:00
|
|
|
sc->sc_dev) != 0)
|
2004-09-26 06:29:15 +04:00
|
|
|
goto err;
|
|
|
|
|
|
|
|
NEXT_ATTACH_STATE(sc, FINISH_READ_SROM);
|
|
|
|
|
|
|
|
if (rtw_srom_parse(&sc->sc_srom, &sc->sc_flags, &sc->sc_csthr,
|
|
|
|
&sc->sc_rfchipid, &sc->sc_rcr, &sc->sc_locale,
|
2007-12-21 21:22:43 +03:00
|
|
|
sc->sc_dev) != 0) {
|
|
|
|
aprint_error_dev(sc->sc_dev,
|
|
|
|
"attach failed, malformed serial ROM\n");
|
2004-09-26 06:29:15 +04:00
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
2007-12-21 21:22:43 +03:00
|
|
|
aprint_verbose_dev(sc->sc_dev, "%s PHY\n",
|
2004-12-21 02:05:41 +03:00
|
|
|
((sc->sc_flags & RTW_F_DIGPHY) != 0) ? "digital" : "analog");
|
|
|
|
|
2007-12-21 21:22:43 +03:00
|
|
|
aprint_verbose_dev(sc->sc_dev, "carrier-sense threshold %u\n",
|
|
|
|
sc->sc_csthr);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
NEXT_ATTACH_STATE(sc, FINISH_PARSE_SROM);
|
|
|
|
|
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
|
|
|
sc->sc_rf = rtw_rf_attach(sc, sc->sc_rfchipid,
|
2004-09-26 06:29:15 +04:00
|
|
|
sc->sc_flags & RTW_F_DIGPHY);
|
|
|
|
|
|
|
|
if (sc->sc_rf == NULL) {
|
2007-12-21 21:22:43 +03:00
|
|
|
aprint_verbose_dev(sc->sc_dev,
|
|
|
|
"attach failed, could not attach RF\n");
|
2004-09-26 06:29:15 +04:00
|
|
|
goto err;
|
|
|
|
}
|
|
|
|
|
|
|
|
NEXT_ATTACH_STATE(sc, FINISH_RF_ATTACH);
|
|
|
|
|
|
|
|
sc->sc_phydelay = rtw_check_phydelay(&sc->sc_regs, sc->sc_rcr);
|
|
|
|
|
2004-12-25 09:58:37 +03:00
|
|
|
RTW_DPRINTF(RTW_DEBUG_ATTACH,
|
2007-12-21 21:22:43 +03:00
|
|
|
("%s: PHY delay %d\n", device_xname(sc->sc_dev), sc->sc_phydelay));
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
if (sc->sc_locale == RTW_LOCALE_UNKNOWN)
|
2005-11-23 07:12:33 +03:00
|
|
|
rtw_identify_country(&sc->sc_regs, &sc->sc_locale);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2007-12-21 21:22:43 +03:00
|
|
|
rtw_init_channels(sc->sc_locale, &sc->sc_ic.ic_channels, sc->sc_dev);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
if (rtw_identify_sta(&sc->sc_regs, &sc->sc_ic.ic_myaddr,
|
2007-12-21 21:22:43 +03:00
|
|
|
sc->sc_dev) != 0)
|
2004-09-26 06:29:15 +04:00
|
|
|
goto err;
|
|
|
|
NEXT_ATTACH_STATE(sc, FINISH_ID_STA);
|
|
|
|
|
2007-12-21 21:22:43 +03:00
|
|
|
rtw_setifprops(ifp, device_xname(sc->sc_dev), (void*)sc);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2005-09-22 20:15:20 +04:00
|
|
|
IFQ_SET_READY(&ifp->if_snd);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2005-06-22 10:14:51 +04:00
|
|
|
sc->sc_ic.ic_ifp = ifp;
|
2004-09-26 06:29:15 +04:00
|
|
|
rtw_set80211props(&sc->sc_ic);
|
|
|
|
|
2005-03-02 08:20:43 +03:00
|
|
|
rtw_led_attach(&sc->sc_led_state, (void *)sc);
|
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
|
|
|
|
2004-09-26 06:29:15 +04:00
|
|
|
/*
|
|
|
|
* Call MI attach routines.
|
|
|
|
*/
|
2005-06-22 10:14:51 +04:00
|
|
|
if_attach(ifp);
|
|
|
|
ieee80211_ifattach(&sc->sc_ic);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
|
|
|
rtw_set80211methods(&sc->sc_mtbl, &sc->sc_ic);
|
|
|
|
|
|
|
|
/* possibly we should fill in our own sc_send_prresp, since
|
|
|
|
* the RTL8180 is probably sending probe responses in ad hoc
|
|
|
|
* mode.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* complete initialization */
|
2005-06-22 10:14:51 +04:00
|
|
|
ieee80211_media_init(&sc->sc_ic, rtw_media_change, rtw_media_status);
|
2007-07-10 00:51:58 +04:00
|
|
|
callout_init(&sc->sc_scan_ch, 0);
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2004-12-29 01:30:07 +03:00
|
|
|
rtw_init_radiotap(sc);
|
|
|
|
|
2010-04-05 11:19:28 +04:00
|
|
|
bpf_attach2(ifp, DLT_IEEE802_11_RADIO,
|
2004-09-26 06:29:15 +04:00
|
|
|
sizeof(struct ieee80211_frame) + 64, &sc->sc_radiobpf);
|
|
|
|
|
|
|
|
NEXT_ATTACH_STATE(sc, FINISHED);
|
|
|
|
|
2005-07-07 03:58:14 +04:00
|
|
|
ieee80211_announce(ic);
|
2004-09-26 06:29:15 +04:00
|
|
|
return;
|
|
|
|
err:
|
|
|
|
rtw_detach(sc);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
rtw_detach(struct rtw_softc *sc)
|
|
|
|
{
|
2005-06-22 10:14:51 +04:00
|
|
|
struct ifnet *ifp = &sc->sc_if;
|
2007-12-16 03:04:07 +03:00
|
|
|
int pri, s;
|
2004-09-26 06:29:15 +04:00
|
|
|
|
2007-12-16 03:04:07 +03:00
|
|
|
s = splnet();
|
2004-12-29 22:41:04 +03:00
|
|
|
|
2004-09-26 06:29:15 +04:00
|
|
|
switch (sc->sc_attach_state) {
|
|
|
|
case FINISHED:
|
2005-06-22 10:14:51 +04:00
|
|
|
rtw_stop(ifp, 1);
|
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
|
|
|
|
2007-12-21 21:22:43 +03:00
|
|
|
pmf_device_deregister(sc->sc_dev);
|
2004-09-26 06:29:15 +04:00
|
|
|
callout_stop(&sc->sc_scan_ch);
|
2005-06-22 10:14:51 +04:00
|
|
|
ieee80211_ifdetach(&sc->sc_ic);
|
|
|
|
if_detach(ifp);
|
Use device_t and its accessors throughout. Use aprint_*_dev().
Improve PMF-ability.
Add a 'flags' argument to suspend/resume handlers and
callers such as pmf_system_suspend().
Define a flag, PMF_F_SELF, which indicates to PMF that a
device is suspending/resuming itself. Add helper routines,
pmf_device_suspend_self(dev) and pmf_device_resume_self(dev),
that call pmf_device_suspend(dev, PMF_F_SELF) and
pmf_device_resume(dev, PMF_F_SELF), respectively. Use
PMF_F_SELF to suspend/resume self in ath(4), audio(4),
rtw(4), and sip(4).
In ath(4) and in rtw(4), replace the icky sc_enable/sc_disable
callbacks, provided by the bus front-end, with
self-suspension/resumption. Also, clean up the bus
front-ends. Make sure that the interrupt handler is
disestablished during suspension. Get rid of driver-private
flags (e.g., RTW_F_ENABLED, ath_softc->sc_invalid); use
device_is_active()/device_has_power() calls, instead.
In the network-class suspend handler, call if_stop(, 0)
instead of if_stop(, 1), because the latter is superfluous
(bus- and driver-suspension hooks will 'disable' the NIC),
and it may cause recursion.
In the network-class resume handler, prevent infinite
recursion through if_init() by getting out early if we are
self-suspending (PMF_F_SELF).
rtw(4) improvements:
Destroy rtw(4) callouts when we detach it. Make rtw at
pci detachable. Print some more information with the "rx
frame too long" warning.
Remove activate() methods:
Get rid of rtw_activate() and ath_activate(). The device
activate() methods are not good for much these days.
Make ath at cardbus resume with crypto functions intact:
Introduce a boolean device property, "pmf-powerdown". If
pmf-powerdown is present and false, it indicates that a
bus back-end should not remove power from a device.
Honor this property in cardbus_child_suspend().
Set this property to 'false' in ath_attach(), since removing
power from an ath at cardbus seems to lobotomize the WPA
crypto engine. XXX Should the pmf-powerdown property
propagate toward the root of the device tree?
Miscellaneous ath(4) changes:
Warn if ath(4) tries to write crypto keys to suspended
hardware.
Reduce differences between FreeBSD and NetBSD in ath(4)
multicast filter setup.
Make ath_printrxbuf() print an rx descriptor's status &
key index, to help debug crypto errors.
Shorten a staircase in ath_ioctl(). Don't check for
ieee80211_ioctl() return code ERESTART, it never happens.
2008-03-12 21:02:21 +03:00
|
|
|
rtw_led_detach(&sc->sc_led_state);
|
2007-12-17 00:39:33 +03:00
|
|
|
/*FALLTHROUGH*/
|
2004-09-26 06:29:15 +04:00
|
|
|
case FINISH_ID_STA:
|
|
|
|
case FINISH_RF_ATTACH:
|
|
|
|
rtw_rf_destroy(sc->sc_rf);
|
|
|
|
sc->sc_rf = NULL;
|
|
|
|
/*FALLTHROUGH*/
|
|
|
|
case FINISH_PARSE_SROM:
|
|
|
|
case FINISH_READ_SROM:
|
|
|
|
rtw_srom_free(&sc->sc_srom);
|
|
|
|
/*FALLTHROUGH*/
|
|
|
|
case FINISH_RESET:
|
|
|
|
case FINISH_RXMAPS_CREATE:
|
2004-12-29 04:06:52 +03:00
|
|
|
rtw_rxdesc_dmamaps_destroy(sc->sc_dmat, &sc->sc_rxsoft[0],
|
2004-09-26 06:29:15 +04:00
|
|
|
RTW_RXQLEN);
|
|
|
|
/*FALLTHROUGH*/
|
|
|
|
case FINISH_TXMAPS_CREATE:
|
|
|
|
for (pri = 0; pri < RTW_NTXPRI; pri++) {
|
|
|
|
rtw_txdesc_dmamaps_destroy(sc->sc_dmat,
|
2004-12-29 04:06:52 +03:00
|
|
|
sc->sc_txsoft_blk[pri].tsb_desc,
|
|
|
|
sc->sc_txsoft_blk[pri].tsb_ndesc);
|
2004-09-26 06:29:15 +04:00
|
|
|
}
|
|
|
|
/*FALLTHROUGH*/
|
|
|
|
case FINISH_TXDESCBLK_SETUP:
|
|
|
|
case FINISH_TXCTLBLK_SETUP:
|
2004-12-29 04:06:52 +03:00
|
|
|
rtw_txsoft_blk_cleanup_all(sc);
|
2004-09-26 06:29:15 +04:00
|
|
|
/*FALLTHROUGH*/
|
|
|
|
case FINISH_DESCMAP_LOAD:
|
|
|
|
bus_dmamap_unload(sc->sc_dmat, sc->sc_desc_dmamap);
|
|
|
|
/*FALLTHROUGH*/
|
|
|
|
case FINISH_DESCMAP_CREATE:
|
|
|
|
bus_dmamap_destroy(sc->sc_dmat, sc->sc_desc_dmamap);
|
|
|
|
/*FALLTHROUGH*/
|
|
|
|
case FINISH_DESC_MAP:
|
2007-03-04 08:59:00 +03:00
|
|
|
bus_dmamem_unmap(sc->sc_dmat, (void *)sc->sc_descs,
|
2004-09-26 06:29:15 +04:00
|
|
|
sizeof(struct rtw_descs));
|
|
|
|
/*FALLTHROUGH*/
|
|
|
|
case FINISH_DESC_ALLOC:
|
|
|
|
bus_dmamem_free(sc->sc_dmat, &sc->sc_desc_segs,
|
|
|
|
sc->sc_desc_nsegs);
|
|
|
|
/*FALLTHROUGH*/
|
|
|
|
case DETACHED:
|
|
|
|
NEXT_ATTACH_STATE(sc, DETACHED);
|
|
|
|
break;
|
|
|
|
}
|
2007-12-16 03:04:07 +03:00
|
|
|
splx(s);
|
2004-09-26 06:29:15 +04:00
|
|
|
return 0;
|
|
|
|
}
|