ipw2100: race between isr_indicate_associated and rx path

Helmut Schaa <[email protected]> Wed, 21 Jan 2009 17:34:48 +0100
Newsgroups gmane.linux.drivers.ipw2100.devel
Message-ID <[email protected]>
Hi.

I tracked down a wireless issue with ipw2100 and WPA-EAP but I'm not yet sure
on how to fix that.

Here's the scenario:

wpa_supplicant associates with a WPA-EAP access point AP1. After some time it
roams to another AP2 which succeeds. Again after some time it tries to roam
back to AP1.

As wpa_supplicant was already associated with AP1 it has the PMK cached and
attaches the PMKID in the association request. The 802.11 standard
specifies that the AP has to start the 4-way handshake if it accepts the PMKID
or to start a full 802.1x authentication if it does not accept the PMKID
(that's different to the case where no PMK was cached and the client starts 
the 802.1x authentication).

However, the AP sends the next frame shortly after the association response
which leads to the following problem with ipw2100:

1) The firmware receives the assoc response and moves internally to associated
state, followed by an interrupt which informs the driver about that change.
2) The driver does _not_ update its internal state to ASSOCIATED in the
interrupt handler. Instead it queues a work to be executed later.
3) The firmware receives the identity request from the AP and accepts the
frame as it is in associated state. Followed by an interrupt to the driver.
4) The driver gets the rx interrupt but drops the frame due to not being in
associated state.
5) The queued work is executed and state changes to associated but the AP will
not resend the EAP frame as the firmware already acked it.

Afterwards wpa_supplicant times out because it did not receive anything from
the AP.

I've tested a quick hack and just allowed frames to pass through even when in
associating state instead of associated state. That allows the supplicant to
catch the EAP frame but of course this mixes the event order up: The frame
arrives before the driver announces its associated state. The hack works fine
but I do not think it is the right way to go.

I thought about the following solution:
If the driver gets notified by the firmware about the association it enters an
intermediate state (something like firmware_already_associated) and buffers
all received frames until the delayed work is executed. The delayed work
notifies user space about the association and releases all buffered frames.

Hence we would not lose frames between the association and the delayed work
but still maintain the right order of first entering associated state and
afterwards receiving frames.

Thanks,
Helmut

------------------------------------------------------------------------------
This SF.net email is sponsored by:
SourcForge Community
SourceForge wants to tell your story.
http://p.sf.net/sfu/sf-spreadtheword