1 s/next_tick/next_tint/ because next_tick shadows a global on sparc64.
2 Fix the bus-barrier helper routines, which had the tag & handle
swapped (!!). Move the helpers from rtwreg.h to rtwvar.h, and
change RTW_BARRIER() into an inline subroutine called rtw_barrier().
tap only RSSI when there is a Philips RF front-end. Tap both Barker
lock quality and RSSI when there is any other RF front-end.
Provide radiotap listeners a more complete picture of channel
activity:
in promiscuous mode, tap frames who do not pass the CRC32 check.
Flag packets that were received with a short preamble. Ask
the NIC to pass us 802.11 Control frames. Pass frames to
radiotap listeners before stripping the FCS. Re-order operations
in rtw_intr_rx() in order to accomplish all of this, taking
care not to pass a broken packet to net80211!
Do not provide a flags field when tapping xmitted frames.
Assert sane Rx packet lengths. Really should check and drop instead
of KASSERTing. I will revisit this, soon.
Update copyright.
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.
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.
I had duplicated them. Improve the macros' names. Simplify their
implementation.
A brief description of each macro is below.
BIT(n): Return a bitmask with bit m set, where the least
significant bit is bit 0.
BITS(m, n): Return a bitmask with bits m through n, inclusive,
set. It does not matter whether m>n or m<=n.
The least significant bit is bit 0.
A "bitfield" is a span of consecutive bits defined by a
bitmask, where 1s select the bits in the bitfield. SHIFTIN,
SHIFTOUT, and SHIFTOUT_MASK help read and write bitfields
from device registers.
SHIFTIN(v, mask): Left-shift bits `v' into the bitfield
defined by `mask', and return them. No
side-effects.
SHIFTOUT(v, mask): Extract and return the bitfield selected
by `mask' from `v', right-shifting the
bits so that the rightmost selected bit
is at bit 0. No side-effects.
SHIFTOUT_MASK(mask): Right-shift the bits in `mask' so that
the rightmost non-zero bit is at bit
0. This is useful for finding the
greatest unsigned value that a bitfield
can hold. No side-effects. Note that
SHIFTOUT_MASK(m) = SHIFTOUT(m, m).
Examples:
/*
* Register definitions taken from the RFMD RF3000 manual.
*/
#define RF3000_GAINCTL 0x11 /* TX variable gain control */
#define RF3000_GAINCTL_TXVGC_MASK BITS(7, 2)
#define RF3000_GAINCTL_SCRAMBLER BIT(1)
/*
* Shift the transmit power into the transmit-power field of the
* gain-control register and write it to the baseband processor.
*/
atw_rf3000_write(sc, RF3000_GAINCTL,
SHIFTIN(txpower, RF3000_GAINCTL_TXVGC_MASK));
/*
* Register definitions taken from the ADMtek ADM8211 manual.
*
*/
#define ATW_RXSTAT_OWN BIT(31) /* 1: NIC may fill descriptor */
/* ... */
#define ATW_RXSTAT_DA1 BIT(17) /* DA bit 1, admin'd address */
#define ATW_RXSTAT_DA0 BIT(16) /* DA bit 0, group address */
#define ATW_RXSTAT_RXDR_MASK BITS(15,12) /* RX data rate */
#define ATW_RXSTAT_FL_MASK BITS(11,0) /* RX frame length, last
* descriptor only
*/
/* Extract the frame length from the Rx descriptor's
* status field.
*/
len = SHIFTOUT(rxstat, ATW_RXSTAT_FL_MASK);
1 Added new sysctl controls for debugging.
2 Improve detection & support for hardware WEP.
3 Revamp handling of transmit descriptor rings.
4 Reliably IFF_OACTIVE when transmit descriptors are available, to
stop the transmit section of the driver from freezing up.
5 Fix beacon transmission in adhoc and hostap modes. XXX There is
a wart in hostap mode, where beacons are transmitted at 1/2 the
correct rate. Load beacon descriptors when the RTW_INTR_BINT
interrupt arrives; schedule RTW_INTR_BINT 1ms ahead of the target
beacon time.
6 Recover more gracefully from tx/rx errors: avoid
transmitter/receiver/chip resets. Try to re-synchronize software
state with hardware state---e.g., load next descriptor pointer
from hardware.
7 Activate the transmit watchdog timer for beacons as well as other
packets.
8 Introduce rtw_idle() that waits for transmit DMA to finish; call
it before resetting the transmitter.
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.
Use clue from rtk(4) and re(4) to fix the rtw(4) packet
filter. Previously, I was using the wrong CRC32 function
to hash multicast addresses; to compensate, I set the
multicast filter to all 1s. Now that I hash the addresses
correctly, I do not any longer set the filter to all 1s.
In rtw_ioctl, avoid gratuitous re-initialization when the
interface flags change. If a !IFF_UP -> IFF_UP transition,
call rtw_init(); otherwise, only reload the packet filter.
In sys/dev/ic/rtwreg.h:
Put useful combinations of Receiver Control Register flags
in RTW_RCR_PKTFILT_MASK, RTW_RCR_MONITOR, and
RTW_RCR_PKTFILT_DEFAULT. (XXX RTW_RCR_MONITOR should be
called RTW_RCR_PKTFILT_MONITOR.)
better than txctl. Change from rtw_txctl/rtw_rxctl to
rtw_txsoft/rtw_rxsoft. Change the descriptor blocks' names to
match: rtw_txctl_blk becomes rtw_txsoft_blk. Change the member-name
prefixes for both software and hardware descriptors.
bit in the SROM. It seems as if it is set to 1 when the PHY is
*analog*, not *digital*. Fix my sources.
In rtw_intr_rx, use units of 500kb/s instead of 100kb/s for rate,
to be consistent with net80211's expectations. Polish up some
debugging ugly messages. Dump raw 802.11 packets if IFF_DEBUG|IFF_LINK2
and RTW_DEBUG is defined.
Polish power-state (on/sleep/off) handling. Especially improve
support for RFMD (totally untested) and Maxim. For Philips, take
the Digital PHY property into account.
Call the net80211 watchdog function from rtw_watchdog, so that we
scan again if auth/assoc fails.
Be a little more cautious about writing register[RTW_TPPOLL], since
other drivers are.... Don't frob the high/low-priority queues
right now, since I don't use them.
Add rtw_join_bss which programs the card with the BSSID and other
properties of a BSS. Use it on state transitions. Factor out
rtw_set_nettype.
Make rtw_recv_beacon call ieee80211_recv_mgmt instead of dropping
beacons on the floor! TBD IBSS merges.
Change some rtw_debug=2 printfs to rtw_debug=3 (RTW_DPRINTF3)
printfs so the console doesn't get spammed so badly at rtw_debug=2.
Change some debugging printfs to RTW_DPRINTFs. E.g., print the
"RF programming method" only if debugging is enabled.
descriptor rings, move packets from the transmit queues to the
transmit rings, handle transmission-completed interrupts. My
Linksys WPC11 ver. 4 with Maxim RF, generates interrupts like it
is successfully transmitting packets. Clearly there are bugs: my
G4 Powerbook locks up hard. I will debug tomorrow.