summaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rndis_wlan.c
diff options
context:
space:
mode:
authorJussi Kivilinna <jussi.kivilinna@mbnet.fi>2009-08-11 22:57:16 +0300
committerJohn W. Linville <linville@tuxdriver.com>2009-08-14 09:14:04 -0400
commit7834ddbcc7a097443761b0722e8c9fb8511b95b1 (patch)
treef764502e46a6a5db52dcec7b961238161848e9b6 /drivers/net/wireless/rndis_wlan.c
parentd4de9532fd0b50d486259ace17650a58bbb751c2 (diff)
downloadlinux-stable-7834ddbcc7a097443761b0722e8c9fb8511b95b1.tar.gz
linux-stable-7834ddbcc7a097443761b0722e8c9fb8511b95b1.tar.bz2
linux-stable-7834ddbcc7a097443761b0722e8c9fb8511b95b1.zip
usbnet: add rx queue pausing
Add rx queue pausing to usbnet. This is needed by rndis_wlan so that it can control rx queue and prevent received packets from being send forward before rndis_wlan receives and handles 'media connect'-indication. Without this establishing WPA connections is hard and fail often. [v2] - removed unneeded use of skb_clone Cc: David Brownell <dbrownell@users.sourceforge.net> Signed-off-by: Jussi Kivilinna <jussi.kivilinna@mbnet.fi> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rndis_wlan.c')
-rw-r--r--drivers/net/wireless/rndis_wlan.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index 828dc1825bba..d42692dfbc67 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -1764,8 +1764,15 @@ static int rndis_iw_set_essid(struct net_device *dev,
if (!wrqu->essid.flags || length == 0)
return disassociate(usbdev, 1);
- else
+ else {
+ /* Pause and purge rx queue, so we don't pass packets before
+ * 'media connect'-indication.
+ */
+ usbnet_pause_rx(usbdev);
+ usbnet_purge_paused_rxq(usbdev);
+
return set_essid(usbdev, &ssid);
+ }
}
@@ -2328,6 +2335,8 @@ get_bssid:
memcpy(evt.ap_addr.sa_data, bssid, ETH_ALEN);
wireless_send_event(usbdev->net, SIOCGIWAP, &evt, NULL);
}
+
+ usbnet_resume_rx(usbdev);
}
if (test_and_clear_bit(WORK_LINK_DOWN, &priv->work_pending)) {
@@ -2541,6 +2550,8 @@ static void rndis_wlan_indication(struct usbnet *usbdev, void *ind, int buflen)
switch (msg->status) {
case RNDIS_STATUS_MEDIA_CONNECT:
+ usbnet_pause_rx(usbdev);
+
devinfo(usbdev, "media connect");
/* queue work to avoid recursive calls into rndis_command */