aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/rndis_wlan.c
diff options
context:
space:
mode:
authorJussi Kivilinna <jussi.kivilinna@mbnet.fi>2009-08-11 15:57:16 -0400
committerJohn W. Linville <linville@tuxdriver.com>2009-08-14 09:14:04 -0400
commit7834ddbcc7a097443761b0722e8c9fb8511b95b1 (patch)
treef764502e46a6a5db52dcec7b961238161848e9b6 /drivers/net/wireless/rndis_wlan.c
parentd4de9532fd0b50d486259ace17650a58bbb751c2 (diff)
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 828dc1825bb..d42692dfbc6 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,
1764 1764
1765 if (!wrqu->essid.flags || length == 0) 1765 if (!wrqu->essid.flags || length == 0)
1766 return disassociate(usbdev, 1); 1766 return disassociate(usbdev, 1);
1767 else 1767 else {
1768 /* Pause and purge rx queue, so we don't pass packets before
1769 * 'media connect'-indication.
1770 */
1771 usbnet_pause_rx(usbdev);
1772 usbnet_purge_paused_rxq(usbdev);
1773
1768 return set_essid(usbdev, &ssid); 1774 return set_essid(usbdev, &ssid);
1775 }
1769} 1776}
1770 1777
1771 1778
@@ -2328,6 +2335,8 @@ get_bssid:
2328 memcpy(evt.ap_addr.sa_data, bssid, ETH_ALEN); 2335 memcpy(evt.ap_addr.sa_data, bssid, ETH_ALEN);
2329 wireless_send_event(usbdev->net, SIOCGIWAP, &evt, NULL); 2336 wireless_send_event(usbdev->net, SIOCGIWAP, &evt, NULL);
2330 } 2337 }
2338
2339 usbnet_resume_rx(usbdev);
2331 } 2340 }
2332 2341
2333 if (test_and_clear_bit(WORK_LINK_DOWN, &priv->work_pending)) { 2342 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)
2541 2550
2542 switch (msg->status) { 2551 switch (msg->status) {
2543 case RNDIS_STATUS_MEDIA_CONNECT: 2552 case RNDIS_STATUS_MEDIA_CONNECT:
2553 usbnet_pause_rx(usbdev);
2554
2544 devinfo(usbdev, "media connect"); 2555 devinfo(usbdev, "media connect");
2545 2556
2546 /* queue work to avoid recursive calls into rndis_command */ 2557 /* queue work to avoid recursive calls into rndis_command */