diff options
author | Jussi Kivilinna <jussi.kivilinna@mbnet.fi> | 2009-08-11 15:57:16 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-08-14 09:14:04 -0400 |
commit | 7834ddbcc7a097443761b0722e8c9fb8511b95b1 (patch) | |
tree | f764502e46a6a5db52dcec7b961238161848e9b6 /drivers/net/wireless/rndis_wlan.c | |
parent | d4de9532fd0b50d486259ace17650a58bbb751c2 (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.c | 13 |
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, | |||
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 */ |