diff options
-rw-r--r-- | drivers/net/wireless/rndis_wlan.c | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index f181b00f2534..612c2c75a997 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c | |||
@@ -470,6 +470,7 @@ struct rndis_wlan_private { | |||
470 | int radio_on; | 470 | int radio_on; |
471 | int infra_mode; | 471 | int infra_mode; |
472 | struct ndis_80211_ssid essid; | 472 | struct ndis_80211_ssid essid; |
473 | __le32 current_command_oid; | ||
473 | 474 | ||
474 | /* encryption stuff */ | 475 | /* encryption stuff */ |
475 | int encr_tx_key_index; | 476 | int encr_tx_key_index; |
@@ -665,7 +666,9 @@ static int rndis_query_oid(struct usbnet *dev, __le32 oid, void *data, int *len) | |||
665 | u.get->msg_len = cpu_to_le32(sizeof *u.get); | 666 | u.get->msg_len = cpu_to_le32(sizeof *u.get); |
666 | u.get->oid = oid; | 667 | u.get->oid = oid; |
667 | 668 | ||
669 | priv->current_command_oid = oid; | ||
668 | ret = rndis_command(dev, u.header, buflen); | 670 | ret = rndis_command(dev, u.header, buflen); |
671 | priv->current_command_oid = 0; | ||
669 | if (ret < 0) | 672 | if (ret < 0) |
670 | devdbg(dev, "rndis_query_oid(%s): rndis_command() failed, %d " | 673 | devdbg(dev, "rndis_query_oid(%s): rndis_command() failed, %d " |
671 | "(%08x)", oid_to_string(oid), ret, | 674 | "(%08x)", oid_to_string(oid), ret, |
@@ -725,7 +728,9 @@ static int rndis_set_oid(struct usbnet *dev, __le32 oid, void *data, int len) | |||
725 | u.set->handle = cpu_to_le32(0); | 728 | u.set->handle = cpu_to_le32(0); |
726 | memcpy(u.buf + sizeof(*u.set), data, len); | 729 | memcpy(u.buf + sizeof(*u.set), data, len); |
727 | 730 | ||
731 | priv->current_command_oid = oid; | ||
728 | ret = rndis_command(dev, u.header, buflen); | 732 | ret = rndis_command(dev, u.header, buflen); |
733 | priv->current_command_oid = 0; | ||
729 | if (ret < 0) | 734 | if (ret < 0) |
730 | devdbg(dev, "rndis_set_oid(%s): rndis_command() failed, %d " | 735 | devdbg(dev, "rndis_set_oid(%s): rndis_command() failed, %d " |
731 | "(%08x)", oid_to_string(oid), ret, | 736 | "(%08x)", oid_to_string(oid), ret, |
@@ -760,6 +765,7 @@ static int rndis_reset(struct usbnet *usbdev) | |||
760 | memset(reset, 0, sizeof(*reset)); | 765 | memset(reset, 0, sizeof(*reset)); |
761 | reset->msg_type = RNDIS_MSG_RESET; | 766 | reset->msg_type = RNDIS_MSG_RESET; |
762 | reset->msg_len = cpu_to_le32(sizeof(*reset)); | 767 | reset->msg_len = cpu_to_le32(sizeof(*reset)); |
768 | priv->current_command_oid = 0; | ||
763 | ret = rndis_command(usbdev, (void *)reset, CONTROL_BUFFER_SIZE); | 769 | ret = rndis_command(usbdev, (void *)reset, CONTROL_BUFFER_SIZE); |
764 | 770 | ||
765 | mutex_unlock(&priv->command_lock); | 771 | mutex_unlock(&priv->command_lock); |
@@ -2558,6 +2564,17 @@ static void rndis_wlan_indication(struct usbnet *usbdev, void *ind, int buflen) | |||
2558 | 2564 | ||
2559 | switch (msg->status) { | 2565 | switch (msg->status) { |
2560 | case RNDIS_STATUS_MEDIA_CONNECT: | 2566 | case RNDIS_STATUS_MEDIA_CONNECT: |
2567 | if (priv->current_command_oid == OID_802_11_ADD_KEY) { | ||
2568 | /* OID_802_11_ADD_KEY causes sometimes extra | ||
2569 | * "media connect" indications which confuses driver | ||
2570 | * and userspace to think that device is | ||
2571 | * roaming/reassociating when it isn't. | ||
2572 | */ | ||
2573 | devdbg(usbdev, "ignored OID_802_11_ADD_KEY triggered " | ||
2574 | "'media connect'"); | ||
2575 | return; | ||
2576 | } | ||
2577 | |||
2561 | usbnet_pause_rx(usbdev); | 2578 | usbnet_pause_rx(usbdev); |
2562 | 2579 | ||
2563 | devinfo(usbdev, "media connect"); | 2580 | devinfo(usbdev, "media connect"); |