diff options
author | Bing Zhao <bzhao@marvell.com> | 2013-01-29 17:38:02 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2013-01-30 14:13:09 -0500 |
commit | 8a7d7cbf7b5ff9912ef50b3e94c9ad9f37b1c75f (patch) | |
tree | 8b557716ce3090acd8b152d92d56bdb026ea5151 /drivers/net/wireless/mwifiex/scan.c | |
parent | 0a06ad8e3a1cb5311b7dbafde45410aa1bce9d40 (diff) |
mwifiex: fix incomplete scan in case of IE parsing error
A scan request is split into multiple scan commands queued in
scan_pending_q. Each scan command will be sent to firmware and
its response is handlded one after another.
If any error is detected while parsing IE in command response
buffer the remaining data will be ignored and error is returned.
We should check if there is any more scan commands pending in
the queue before returning error. This ensures that we will call
cfg80211_scan_done if this is the last scan command, or send
next scan command in scan_pending_q to firmware.
Cc: "3.6+" <stable@vger.kernel.org>
Signed-off-by: Bing Zhao <bzhao@marvell.com>
Signed-off-by: Amitkumar Karwar <akarwar@marvell.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/mwifiex/scan.c')
-rw-r--r-- | drivers/net/wireless/mwifiex/scan.c | 9 |
1 files changed, 5 insertions, 4 deletions
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c index 9189a32b7844..973a9d90e9ea 100644 --- a/drivers/net/wireless/mwifiex/scan.c +++ b/drivers/net/wireless/mwifiex/scan.c | |||
@@ -1563,7 +1563,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, | |||
1563 | dev_err(adapter->dev, "SCAN_RESP: too many AP returned (%d)\n", | 1563 | dev_err(adapter->dev, "SCAN_RESP: too many AP returned (%d)\n", |
1564 | scan_rsp->number_of_sets); | 1564 | scan_rsp->number_of_sets); |
1565 | ret = -1; | 1565 | ret = -1; |
1566 | goto done; | 1566 | goto check_next_scan; |
1567 | } | 1567 | } |
1568 | 1568 | ||
1569 | bytes_left = le16_to_cpu(scan_rsp->bss_descript_size); | 1569 | bytes_left = le16_to_cpu(scan_rsp->bss_descript_size); |
@@ -1634,7 +1634,8 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, | |||
1634 | if (!beacon_size || beacon_size > bytes_left) { | 1634 | if (!beacon_size || beacon_size > bytes_left) { |
1635 | bss_info += bytes_left; | 1635 | bss_info += bytes_left; |
1636 | bytes_left = 0; | 1636 | bytes_left = 0; |
1637 | return -1; | 1637 | ret = -1; |
1638 | goto check_next_scan; | ||
1638 | } | 1639 | } |
1639 | 1640 | ||
1640 | /* Initialize the current working beacon pointer for this BSS | 1641 | /* Initialize the current working beacon pointer for this BSS |
@@ -1690,7 +1691,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, | |||
1690 | dev_err(priv->adapter->dev, | 1691 | dev_err(priv->adapter->dev, |
1691 | "%s: bytes left < IE length\n", | 1692 | "%s: bytes left < IE length\n", |
1692 | __func__); | 1693 | __func__); |
1693 | goto done; | 1694 | goto check_next_scan; |
1694 | } | 1695 | } |
1695 | if (element_id == WLAN_EID_DS_PARAMS) { | 1696 | if (element_id == WLAN_EID_DS_PARAMS) { |
1696 | channel = *(current_ptr + sizeof(struct ieee_types_header)); | 1697 | channel = *(current_ptr + sizeof(struct ieee_types_header)); |
@@ -1753,6 +1754,7 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, | |||
1753 | } | 1754 | } |
1754 | } | 1755 | } |
1755 | 1756 | ||
1757 | check_next_scan: | ||
1756 | spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); | 1758 | spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); |
1757 | if (list_empty(&adapter->scan_pending_q)) { | 1759 | if (list_empty(&adapter->scan_pending_q)) { |
1758 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); | 1760 | spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags); |
@@ -1813,7 +1815,6 @@ int mwifiex_ret_802_11_scan(struct mwifiex_private *priv, | |||
1813 | } | 1815 | } |
1814 | } | 1816 | } |
1815 | 1817 | ||
1816 | done: | ||
1817 | return ret; | 1818 | return ret; |
1818 | } | 1819 | } |
1819 | 1820 | ||