Following Charles Hannum's wi(4) optimizations, there could be a
Transmit command outstanding after wi_tx_intr or wi_start returns.
The driver would blithely issue a second command [*] before the
first command was finished, taking the first command's WI_EV_CMD
indication to mean the second command had finished. The driver
would be dreadfully confused when the second command's results did
not meet its expectations (e.g., a RID mismatch error would occur).
The packet transmit section of the code would never read the
WI_EV_CMD it expected, so transmissions would cease.
This patch counts the outstanding transmit commands (there can be
only one) and, if a transmit command is outstanding at the top of
wi_cmd(), wi_cmd waits for the command to complete. If there was
a transmit command outstanding when wi_cmd begins, it calls
wi_cmd_intr() on its way out.
I have tested this on an Orinoco card. Previously, the card would
stop transmitting or the kernel would panic as desynchronization
occurred. Now it works beautifully.
[*] A second command could be issued by wi_ioctl or else by
wi_intr->wi_info_intr->wi_newstate->wi_read_xrid->wi_read_rid.
* If the device returns a length too short to even contain the RID number,
flag it as not supported and return EOPNOTSUPP, rather than returning a
length of -2 and trying to use the value anyway.
* Check the returned lengths to see if we actually got anything.
* If we get no rate list, fail the attach, so we don't just blow up later.
Allow the frontend to pass in a MAC address.
start and the number we've started that have not been alloced yet. Currently
sc_txstarted is constained to 0 or 1 because of the way we start the next
packet, but this will change.
* Update sc_txpending[] when a packet is written, even before we issue the TX
command, since it may be active when we issue the TX command for the
following packet.
* Do not lower the rate in ni_txrate or id_rateidx, because these are used to
keep track of sc_txpending[], and could cause us to get "stuck" at the lower
rate.
bug report from Simon Burge: the firmware seems to lock up.
If rate-adaptation is disabled on a Lucent card, then do all the
rate-adaptation work *except* for writing the new transmit rate,
since I suspect that is what locks-up the firmware.
APs to run at "full speed" where before they ran at just 1 or 2Mb/s.
The AP will adapt the data rate for each client based on packet
losses and the received signal strength.
I have also enabled rate adaptation for STA mode and for IBSS mode,
but the hardware gives us less control over the data rate in those
modes.
denote a signed dBm Rx power, so rename them to _DBM_ and change
the signedness. Add new _DB_ flags for unsigned Rx power measured
from an arbitrary reference.
Try to synchronize net80211/ieee80211_radiotap.h with my tcpdump
sources (which public tcpdump has not seen, yet) and with FreeBSD.
1 Add channel mask, transmit rate-mask arguments to wi_scan_ap.
2 Adopt the macros WI_LOCK/WI_UNLOCK for synchronization. FreeBSD
uses a different synchronization mechanism.
3 In wi_cmd, adopt constants WI_DELAY/WI_TIMEOUT for timing.
4 Pull debug messages from into wi_read_nicid from FreeBSD.
5 Bug fix: if IFF_ALLMULTI, don't filter any multicasts.
6 Count and report TX exceptions, but don't generate any additional
interrupts.
FreeBSD.)
Fix a bug in wi_stop where ejecting from the Powerbook crashes the
system. Essentially, the patch makes sure we write *no* registers
when we are no longer attached.
Also, for consistency w/ FreeBSD, use sc_portnum throughout wi,
instead of hard-coding WI_PORT0 .
which is safer than the loop there used to be here.
wi_mwrite_bap: if wi_write_bap fails, don't keep on going: this
way you avoid writing garbage to the radio. First time you see
an odd-length mbuf, copy the remainder of the chain to sc_txbuf
and from there to the MAC. This way, you do not read an mbuf past
the end of its data (occasionally you will cross a page doing
that!) and you avoid expensive, excess seeks in the radio's own
buffer chain.
wi_rx_intr: clamp the frame length told to us by the driver to the
most bytes we can fit in our mbuf cluster.
I am still getting e-mails from my testers telling me how much
better this makes things.
LINK_STAT notification for every change of BSSID, so the firmware's
BSSID and the driver's BSSID will get out of sync. This has two
bad affects. First, because the 802.11 framework filters received
packets based on BSSID, many packets can be dropped before the
driver adopts the firmware's BSSID. Second, ifconfig's tells a
misleading BSSID to the operator.
This problem is most apparent in networks where every station does
not hear every other. I reproduce these conditions in an office by
removing/replacing the antennas on my 802.11 cards.
As a solution, in IBSS mode, the driver will ask the firmware for
the BSSID every five seconds. Also, whenever the driver receives
a frame carrying a different BSSID than the driver's BSSID, then
the driver asks the firmware for the BSSID before handing the frame
to ieee80211_input.
WI_RID_DBM_ADJUST: In preparation for capturing Prism packets
containing received signal strength indications (RSSI), read the
constant for conversion from RSSI to dBm (decibels relative to
a milliwatt).
WI_RID_FRAG_THRESH: Get/set the packet fragmentation threshold
on Lucent/Prism.
correctly. To avoid massive extra code in each driver, now if_iee80211subr.c
also handles non-standard old lucent adhoc-demo mode.
This also fixes PR 14227.
- Eliminate wi_hostap.c since most of the code are duplicated with
net/if_ieee80211subr.c
- Station for Infrastructure network and IBSS also use service functions
as much as possible to be consistent with other wireless drivers.
Now WEP works for station/ibss/hostap.
by me:
* Speed up reading/writing buffers from the hardware by avoiding
slow forward seeks. In preparation to use the optimization, do
not read overlapping bytes. This is currently disabled, but can
be enabled with OPTIMIZE_RW_DATA.
* Hand 802.11 and Prism-specific frames to BPF. User can watch these
frames by specifying an alternate DLT to e.g. tcpdump(8).
* Add support for SIOC[SG]80211BSSID and SIOC[SG]80211CHANNEL.
* Issue join requests and track join/create state through link-status
notifications.
* Split wi_rxeof into separate routines for receiving Ethernet II,
802.11 data, and 802.11 management frames.
* Bug fix: Account for aligning m_data to a word boundary in the Rx
buffer size check.
* Bug fix: Check for LLC/SNAP even if the firmware tells us the frame
is Ethernet II, as the firmware sometimes gets this wrong.
* Process as many events as possible when we get an interrupt, using
a simple heuristic to avoid reprocessing an event (which can have
bad side-effects). Clamp the time spent in the interrupt handler
to 4ms.
* Redo the timeout loops to be consistent and less prone to error.
* Add delays to timeout loops which were missing them, so that a
fast CPU won't win the race.
* Borrow some timeout loop values from the linux-wlan-ng driver,
which seems to reflect a high level of clue (due to direct support
from Intersil).
* Get rid of silly wi_read_data(..., len + 2) idiom; simply round up
in wi_read_data() and wi_write_data(). Also, protect against a
length of 0.
* Name some frequently-used constants. Correct spelling. Other style nits.
* Bug fix: On Prism, set Create IBSS register to 0 *always*. The meaning
of Create IBSS == 1 is join an IBSS or *ESS*, and we do not want to
join an ESS, because that would put us in an inconsistent state. 0
is the right value for Prism.
* Bug fix: Clean up state at the top of wi_init(), in the event that
we don't reach the bottom.
* Simplify wi_start() by always providing an RFC1042-encoded 802.11
frame to the firmware.
* Larval powersave support for HostAP mode, enabled by WI_HOSTAP_POWERSAVE.
* Bug fix: Call wi_stop() from wi_shutdown().
* Bug fix: sync media options with HostAP mode in wi_sync_media().
* In wi_media_status(), inquire firmware for current media state if
media == auto. From FreeBSD.
* Clean up the way buffer lengths are computed by using pointer
arithmetic rather than magic constants.
* Swap the order of comparisons in addr_cmp() for speed.
* Bug fix: Send ReAssoc Response instead of Assoc Response to a
ReAssoc Request.
* Bug fix: Copy SSID using the correct size.
* Give more meaningful names to offsets in a wi_frame.
* Bug fix: Assign the right values to the named constants for
Rx frame encoding.
* Get rid of useless SNAP constants.
WEP for APs is not yet implemented, but without WEP, this works well
enough for my laptop to associate with an AP running this code.
Adapted from OpenBSD.
in this info based on firmware type and version. Replace "wi_has_wep"
with a flag.
* For cards which support IBSS, add "ibss" has a media option.
* For cards which support CREATE_IBSS, add "ibss-master" as a media
option.
* Use the "ibss" and "ibss-master" media options to determine if
we should go into IBSS mode and/or create the IBSS.
* Internally convert between the generic WI_PORTTYPE_IBSS and the
value the firmware wants to use for IBSS.
* When setting the IBSS name, if a desired-SSID is set, and we're
an ibss-master, write the desired-SSID into the own-SSID slot.
This ensures that "ifconfig wi0 nwid FOO" will do the expected
thing.
* Only set the roaming mode if the card supports roaming.
From OpenBSD.
;
Implement wi_scan into wi.c.
forces if_wi to initiate one round of access point scan.
This code was written by jrb@cs.pdx.edu, modified and bug-fixed by ichiro@netbsd.org