aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2012-10-10 11:59:54 -0400
committerDavid S. Miller <davem@davemloft.net>2012-10-10 11:59:54 -0400
commit85457685e0e314f6902caaef976b3fd8ef4f51b4 (patch)
treea5610b82fdf0a9f2b315cab37656ab97abf93a38 /drivers/net
parent2474542f64432398f503373f53bdf620491bcfa8 (diff)
parentc3e7724b6bc2f25e46c38dbe68f09d71fafeafb8 (diff)
Merge tag 'master-2012-10-08' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless
John W. Linville says: ==================== Here is a batch of fixes intended for 3.7... Amitkumar Karwar provides a couple of mwifiex fixes to correctly report some reason codes for certain connection failures. He also provides a fix to cleanup after a scanning failure. Bing Zhao rounds that out with another mwifiex scanning fix. Daniel Golle gives us a fix for a copy/paste error in rt2x00. Felix Fietkau brings a couple of ath9k fixes related to suspend/resume, and a couple of fixes to prevent memory leaks in ath9k and mac80211. Ronald Wahl sends a carl9170 fix for a sleep in softirq context. Thomas Pedersen reorders some code to prevent drv_get_tsf from being called while holding a spinlock, now that it can sleep. Finally, Wei Yongjun prevents a NULL pointer dereference in the ath5k driver. Please let me know if there are problems! ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c15
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c7
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c53
-rw-r--r--drivers/net/wireless/ath/carl9170/carl9170.h1
-rw-r--r--drivers/net/wireless/ath/carl9170/main.c29
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c27
-rw-r--r--drivers/net/wireless/mwifiex/join.c6
-rw-r--r--drivers/net/wireless/mwifiex/main.h2
-rw-r--r--drivers/net/wireless/mwifiex/scan.c38
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmdresp.c4
-rw-r--r--drivers/net/wireless/mwifiex/sta_event.c31
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c4
16 files changed, 136 insertions, 92 deletions
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 9fd6d9a9942e..9f31cfa56cc0 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -1804,7 +1804,7 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
1804{ 1804{
1805 int ret; 1805 int ret;
1806 struct ath5k_hw *ah = hw->priv; 1806 struct ath5k_hw *ah = hw->priv;
1807 struct ath5k_vif *avf = (void *)vif->drv_priv; 1807 struct ath5k_vif *avf;
1808 struct sk_buff *skb; 1808 struct sk_buff *skb;
1809 1809
1810 if (WARN_ON(!vif)) { 1810 if (WARN_ON(!vif)) {
@@ -1819,6 +1819,7 @@ ath5k_beacon_update(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
1819 goto out; 1819 goto out;
1820 } 1820 }
1821 1821
1822 avf = (void *)vif->drv_priv;
1822 ath5k_txbuf_free_skb(ah, avf->bbuf); 1823 ath5k_txbuf_free_skb(ah, avf->bbuf);
1823 avf->bbuf->skb = skb; 1824 avf->bbuf->skb = skb;
1824 ret = ath5k_beacon_setup(ah, avf->bbuf); 1825 ret = ath5k_beacon_setup(ah, avf->bbuf);
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index 76f07d8c272d..1b48414dca95 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -120,7 +120,7 @@ static void ath9k_tx_cabq(struct ieee80211_hw *hw, struct sk_buff *skb)
120 120
121 if (ath_tx_start(hw, skb, &txctl) != 0) { 121 if (ath_tx_start(hw, skb, &txctl) != 0) {
122 ath_dbg(common, XMIT, "CABQ TX failed\n"); 122 ath_dbg(common, XMIT, "CABQ TX failed\n");
123 dev_kfree_skb_any(skb); 123 ieee80211_free_txskb(hw, skb);
124 } 124 }
125} 125}
126 126
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index f9a6ec5cf470..8e1559aba495 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1450,9 +1450,14 @@ static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type)
1450 REG_WRITE(ah, AR_RTC_FORCE_WAKE, 1450 REG_WRITE(ah, AR_RTC_FORCE_WAKE,
1451 AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT); 1451 AR_RTC_FORCE_WAKE_EN | AR_RTC_FORCE_WAKE_ON_INT);
1452 1452
1453 if (!ah->reset_power_on)
1454 type = ATH9K_RESET_POWER_ON;
1455
1453 switch (type) { 1456 switch (type) {
1454 case ATH9K_RESET_POWER_ON: 1457 case ATH9K_RESET_POWER_ON:
1455 ret = ath9k_hw_set_reset_power_on(ah); 1458 ret = ath9k_hw_set_reset_power_on(ah);
1459 if (!ret)
1460 ah->reset_power_on = true;
1456 break; 1461 break;
1457 case ATH9K_RESET_WARM: 1462 case ATH9K_RESET_WARM:
1458 case ATH9K_RESET_COLD: 1463 case ATH9K_RESET_COLD:
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 566a4ce4f156..dbc1b7a4cbfd 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -741,6 +741,7 @@ struct ath_hw {
741 u32 rfkill_polarity; 741 u32 rfkill_polarity;
742 u32 ah_flags; 742 u32 ah_flags;
743 743
744 bool reset_power_on;
744 bool htc_reset_init; 745 bool htc_reset_init;
745 746
746 enum nl80211_iftype opmode; 747 enum nl80211_iftype opmode;
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 31ab82e3ba85..dd45edfa6bae 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -639,8 +639,7 @@ static int ath9k_start(struct ieee80211_hw *hw)
639 ath_err(common, 639 ath_err(common,
640 "Unable to reset hardware; reset status %d (freq %u MHz)\n", 640 "Unable to reset hardware; reset status %d (freq %u MHz)\n",
641 r, curchan->center_freq); 641 r, curchan->center_freq);
642 spin_unlock_bh(&sc->sc_pcu_lock); 642 ah->reset_power_on = false;
643 goto mutex_unlock;
644 } 643 }
645 644
646 /* Setup our intr mask. */ 645 /* Setup our intr mask. */
@@ -665,11 +664,8 @@ static int ath9k_start(struct ieee80211_hw *hw)
665 clear_bit(SC_OP_INVALID, &sc->sc_flags); 664 clear_bit(SC_OP_INVALID, &sc->sc_flags);
666 sc->sc_ah->is_monitoring = false; 665 sc->sc_ah->is_monitoring = false;
667 666
668 if (!ath_complete_reset(sc, false)) { 667 if (!ath_complete_reset(sc, false))
669 r = -EIO; 668 ah->reset_power_on = false;
670 spin_unlock_bh(&sc->sc_pcu_lock);
671 goto mutex_unlock;
672 }
673 669
674 if (ah->led_pin >= 0) { 670 if (ah->led_pin >= 0) {
675 ath9k_hw_cfg_output(ah, ah->led_pin, 671 ath9k_hw_cfg_output(ah, ah->led_pin,
@@ -688,12 +684,11 @@ static int ath9k_start(struct ieee80211_hw *hw)
688 if (ah->caps.pcie_lcr_extsync_en && common->bus_ops->extn_synch_en) 684 if (ah->caps.pcie_lcr_extsync_en && common->bus_ops->extn_synch_en)
689 common->bus_ops->extn_synch_en(common); 685 common->bus_ops->extn_synch_en(common);
690 686
691mutex_unlock:
692 mutex_unlock(&sc->mutex); 687 mutex_unlock(&sc->mutex);
693 688
694 ath9k_ps_restore(sc); 689 ath9k_ps_restore(sc);
695 690
696 return r; 691 return 0;
697} 692}
698 693
699static void ath9k_tx(struct ieee80211_hw *hw, 694static void ath9k_tx(struct ieee80211_hw *hw,
@@ -770,7 +765,7 @@ static void ath9k_tx(struct ieee80211_hw *hw,
770 765
771 return; 766 return;
772exit: 767exit:
773 dev_kfree_skb_any(skb); 768 ieee80211_free_txskb(hw, skb);
774} 769}
775 770
776static void ath9k_stop(struct ieee80211_hw *hw) 771static void ath9k_stop(struct ieee80211_hw *hw)
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index 0e630a99b68b..f088f4bf9a26 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -324,6 +324,10 @@ static int ath_pci_suspend(struct device *device)
324static int ath_pci_resume(struct device *device) 324static int ath_pci_resume(struct device *device)
325{ 325{
326 struct pci_dev *pdev = to_pci_dev(device); 326 struct pci_dev *pdev = to_pci_dev(device);
327 struct ieee80211_hw *hw = pci_get_drvdata(pdev);
328 struct ath_softc *sc = hw->priv;
329 struct ath_hw *ah = sc->sc_ah;
330 struct ath_common *common = ath9k_hw_common(ah);
327 u32 val; 331 u32 val;
328 332
329 /* 333 /*
@@ -335,6 +339,9 @@ static int ath_pci_resume(struct device *device)
335 if ((val & 0x0000ff00) != 0) 339 if ((val & 0x0000ff00) != 0)
336 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); 340 pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
337 341
342 ath_pci_aspm_init(common);
343 ah->reset_power_on = false;
344
338 return 0; 345 return 0;
339} 346}
340 347
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 36618e3a5e60..378bd70256b2 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -66,8 +66,7 @@ static void ath_tx_update_baw(struct ath_softc *sc, struct ath_atx_tid *tid,
66static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, 66static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
67 struct ath_txq *txq, 67 struct ath_txq *txq,
68 struct ath_atx_tid *tid, 68 struct ath_atx_tid *tid,
69 struct sk_buff *skb, 69 struct sk_buff *skb);
70 bool dequeue);
71 70
72enum { 71enum {
73 MCS_HT20, 72 MCS_HT20,
@@ -176,7 +175,15 @@ static void ath_tx_flush_tid(struct ath_softc *sc, struct ath_atx_tid *tid)
176 fi = get_frame_info(skb); 175 fi = get_frame_info(skb);
177 bf = fi->bf; 176 bf = fi->bf;
178 177
179 if (bf && fi->retries) { 178 if (!bf) {
179 bf = ath_tx_setup_buffer(sc, txq, tid, skb);
180 if (!bf) {
181 ieee80211_free_txskb(sc->hw, skb);
182 continue;
183 }
184 }
185
186 if (fi->retries) {
180 list_add_tail(&bf->list, &bf_head); 187 list_add_tail(&bf->list, &bf_head);
181 ath_tx_update_baw(sc, tid, bf->bf_state.seqno); 188 ath_tx_update_baw(sc, tid, bf->bf_state.seqno);
182 ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0); 189 ath_tx_complete_buf(sc, bf, txq, &bf_head, &ts, 0);
@@ -785,10 +792,13 @@ static enum ATH_AGGR_STATUS ath_tx_form_aggr(struct ath_softc *sc,
785 fi = get_frame_info(skb); 792 fi = get_frame_info(skb);
786 bf = fi->bf; 793 bf = fi->bf;
787 if (!fi->bf) 794 if (!fi->bf)
788 bf = ath_tx_setup_buffer(sc, txq, tid, skb, true); 795 bf = ath_tx_setup_buffer(sc, txq, tid, skb);
789 796
790 if (!bf) 797 if (!bf) {
798 __skb_unlink(skb, &tid->buf_q);
799 ieee80211_free_txskb(sc->hw, skb);
791 continue; 800 continue;
801 }
792 802
793 bf->bf_state.bf_type = BUF_AMPDU | BUF_AGGR; 803 bf->bf_state.bf_type = BUF_AMPDU | BUF_AGGR;
794 seqno = bf->bf_state.seqno; 804 seqno = bf->bf_state.seqno;
@@ -1731,9 +1741,11 @@ static void ath_tx_send_ampdu(struct ath_softc *sc, struct ath_atx_tid *tid,
1731 return; 1741 return;
1732 } 1742 }
1733 1743
1734 bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb, false); 1744 bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb);
1735 if (!bf) 1745 if (!bf) {
1746 ieee80211_free_txskb(sc->hw, skb);
1736 return; 1747 return;
1748 }
1737 1749
1738 bf->bf_state.bf_type = BUF_AMPDU; 1750 bf->bf_state.bf_type = BUF_AMPDU;
1739 INIT_LIST_HEAD(&bf_head); 1751 INIT_LIST_HEAD(&bf_head);
@@ -1757,11 +1769,6 @@ static void ath_tx_send_normal(struct ath_softc *sc, struct ath_txq *txq,
1757 struct ath_buf *bf; 1769 struct ath_buf *bf;
1758 1770
1759 bf = fi->bf; 1771 bf = fi->bf;
1760 if (!bf)
1761 bf = ath_tx_setup_buffer(sc, txq, tid, skb, false);
1762
1763 if (!bf)
1764 return;
1765 1772
1766 INIT_LIST_HEAD(&bf_head); 1773 INIT_LIST_HEAD(&bf_head);
1767 list_add_tail(&bf->list, &bf_head); 1774 list_add_tail(&bf->list, &bf_head);
@@ -1839,8 +1846,7 @@ u8 ath_txchainmask_reduction(struct ath_softc *sc, u8 chainmask, u32 rate)
1839static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc, 1846static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
1840 struct ath_txq *txq, 1847 struct ath_txq *txq,
1841 struct ath_atx_tid *tid, 1848 struct ath_atx_tid *tid,
1842 struct sk_buff *skb, 1849 struct sk_buff *skb)
1843 bool dequeue)
1844{ 1850{
1845 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 1851 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1846 struct ath_frame_info *fi = get_frame_info(skb); 1852 struct ath_frame_info *fi = get_frame_info(skb);
@@ -1852,7 +1858,7 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
1852 bf = ath_tx_get_buffer(sc); 1858 bf = ath_tx_get_buffer(sc);
1853 if (!bf) { 1859 if (!bf) {
1854 ath_dbg(common, XMIT, "TX buffers are full\n"); 1860 ath_dbg(common, XMIT, "TX buffers are full\n");
1855 goto error; 1861 return NULL;
1856 } 1862 }
1857 1863
1858 ATH_TXBUF_RESET(bf); 1864 ATH_TXBUF_RESET(bf);
@@ -1881,18 +1887,12 @@ static struct ath_buf *ath_tx_setup_buffer(struct ath_softc *sc,
1881 ath_err(ath9k_hw_common(sc->sc_ah), 1887 ath_err(ath9k_hw_common(sc->sc_ah),
1882 "dma_mapping_error() on TX\n"); 1888 "dma_mapping_error() on TX\n");
1883 ath_tx_return_buffer(sc, bf); 1889 ath_tx_return_buffer(sc, bf);
1884 goto error; 1890 return NULL;
1885 } 1891 }
1886 1892
1887 fi->bf = bf; 1893 fi->bf = bf;
1888 1894
1889 return bf; 1895 return bf;
1890
1891error:
1892 if (dequeue)
1893 __skb_unlink(skb, &tid->buf_q);
1894 dev_kfree_skb_any(skb);
1895 return NULL;
1896} 1896}
1897 1897
1898/* FIXME: tx power */ 1898/* FIXME: tx power */
@@ -1921,9 +1921,14 @@ static void ath_tx_start_dma(struct ath_softc *sc, struct sk_buff *skb,
1921 */ 1921 */
1922 ath_tx_send_ampdu(sc, tid, skb, txctl); 1922 ath_tx_send_ampdu(sc, tid, skb, txctl);
1923 } else { 1923 } else {
1924 bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb, false); 1924 bf = ath_tx_setup_buffer(sc, txctl->txq, tid, skb);
1925 if (!bf) 1925 if (!bf) {
1926 if (txctl->paprd)
1927 dev_kfree_skb_any(skb);
1928 else
1929 ieee80211_free_txskb(sc->hw, skb);
1926 return; 1930 return;
1931 }
1927 1932
1928 bf->bf_state.bfs_paprd = txctl->paprd; 1933 bf->bf_state.bfs_paprd = txctl->paprd;
1929 1934
diff --git a/drivers/net/wireless/ath/carl9170/carl9170.h b/drivers/net/wireless/ath/carl9170/carl9170.h
index 2aa4a59c72c8..2df17f1e49ef 100644
--- a/drivers/net/wireless/ath/carl9170/carl9170.h
+++ b/drivers/net/wireless/ath/carl9170/carl9170.h
@@ -303,6 +303,7 @@ struct ar9170 {
303 unsigned long queue_stop_timeout[__AR9170_NUM_TXQ]; 303 unsigned long queue_stop_timeout[__AR9170_NUM_TXQ];
304 unsigned long max_queue_stop_timeout[__AR9170_NUM_TXQ]; 304 unsigned long max_queue_stop_timeout[__AR9170_NUM_TXQ];
305 bool needs_full_reset; 305 bool needs_full_reset;
306 bool force_usb_reset;
306 atomic_t pending_restarts; 307 atomic_t pending_restarts;
307 308
308 /* interface mode settings */ 309 /* interface mode settings */
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c
index 67997b39aba7..25a1e2f4f738 100644
--- a/drivers/net/wireless/ath/carl9170/main.c
+++ b/drivers/net/wireless/ath/carl9170/main.c
@@ -465,27 +465,26 @@ static void carl9170_restart_work(struct work_struct *work)
465{ 465{
466 struct ar9170 *ar = container_of(work, struct ar9170, 466 struct ar9170 *ar = container_of(work, struct ar9170,
467 restart_work); 467 restart_work);
468 int err; 468 int err = -EIO;
469 469
470 ar->usedkeys = 0; 470 ar->usedkeys = 0;
471 ar->filter_state = 0; 471 ar->filter_state = 0;
472 carl9170_cancel_worker(ar); 472 carl9170_cancel_worker(ar);
473 473
474 mutex_lock(&ar->mutex); 474 mutex_lock(&ar->mutex);
475 err = carl9170_usb_restart(ar); 475 if (!ar->force_usb_reset) {
476 if (net_ratelimit()) { 476 err = carl9170_usb_restart(ar);
477 if (err) { 477 if (net_ratelimit()) {
478 dev_err(&ar->udev->dev, "Failed to restart device " 478 if (err)
479 " (%d).\n", err); 479 dev_err(&ar->udev->dev, "Failed to restart device (%d).\n", err);
480 } else { 480 else
481 dev_info(&ar->udev->dev, "device restarted " 481 dev_info(&ar->udev->dev, "device restarted successfully.\n");
482 "successfully.\n");
483 } 482 }
484 } 483 }
485
486 carl9170_zap_queues(ar); 484 carl9170_zap_queues(ar);
487 mutex_unlock(&ar->mutex); 485 mutex_unlock(&ar->mutex);
488 if (!err) { 486
487 if (!err && !ar->force_usb_reset) {
489 ar->restart_counter++; 488 ar->restart_counter++;
490 atomic_set(&ar->pending_restarts, 0); 489 atomic_set(&ar->pending_restarts, 0);
491 490
@@ -526,10 +525,10 @@ void carl9170_restart(struct ar9170 *ar, const enum carl9170_restart_reasons r)
526 if (!ar->registered) 525 if (!ar->registered)
527 return; 526 return;
528 527
529 if (IS_ACCEPTING_CMD(ar) && !ar->needs_full_reset) 528 if (!IS_ACCEPTING_CMD(ar) || ar->needs_full_reset)
530 ieee80211_queue_work(ar->hw, &ar->restart_work); 529 ar->force_usb_reset = true;
531 else 530
532 carl9170_usb_reset(ar); 531 ieee80211_queue_work(ar->hw, &ar->restart_work);
533 532
534 /* 533 /*
535 * At this point, the device instance might have vanished/disabled. 534 * At this point, the device instance might have vanished/disabled.
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 2691620393ea..0679458a1bac 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -1596,8 +1596,9 @@ done:
1596 } 1596 }
1597 } 1597 }
1598 1598
1599 if (mwifiex_bss_start(priv, bss, &req_ssid)) 1599 ret = mwifiex_bss_start(priv, bss, &req_ssid);
1600 return -EFAULT; 1600 if (ret)
1601 return ret;
1601 1602
1602 if (mode == NL80211_IFTYPE_ADHOC) { 1603 if (mode == NL80211_IFTYPE_ADHOC) {
1603 /* Inform the BSS information to kernel, otherwise 1604 /* Inform the BSS information to kernel, otherwise
@@ -1652,9 +1653,19 @@ done:
1652 "info: association to bssid %pM failed\n", 1653 "info: association to bssid %pM failed\n",
1653 priv->cfg_bssid); 1654 priv->cfg_bssid);
1654 memset(priv->cfg_bssid, 0, ETH_ALEN); 1655 memset(priv->cfg_bssid, 0, ETH_ALEN);
1656
1657 if (ret > 0)
1658 cfg80211_connect_result(priv->netdev, priv->cfg_bssid,
1659 NULL, 0, NULL, 0, ret,
1660 GFP_KERNEL);
1661 else
1662 cfg80211_connect_result(priv->netdev, priv->cfg_bssid,
1663 NULL, 0, NULL, 0,
1664 WLAN_STATUS_UNSPECIFIED_FAILURE,
1665 GFP_KERNEL);
1655 } 1666 }
1656 1667
1657 return ret; 1668 return 0;
1658} 1669}
1659 1670
1660/* 1671/*
@@ -1802,7 +1813,7 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy,
1802{ 1813{
1803 struct net_device *dev = request->wdev->netdev; 1814 struct net_device *dev = request->wdev->netdev;
1804 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev); 1815 struct mwifiex_private *priv = mwifiex_netdev_get_priv(dev);
1805 int i, offset; 1816 int i, offset, ret;
1806 struct ieee80211_channel *chan; 1817 struct ieee80211_channel *chan;
1807 struct ieee_types_header *ie; 1818 struct ieee_types_header *ie;
1808 1819
@@ -1855,8 +1866,12 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy,
1855 1866
1856 priv->user_scan_cfg->chan_list[i].scan_time = 0; 1867 priv->user_scan_cfg->chan_list[i].scan_time = 0;
1857 } 1868 }
1858 if (mwifiex_scan_networks(priv, priv->user_scan_cfg)) 1869
1859 return -EFAULT; 1870 ret = mwifiex_scan_networks(priv, priv->user_scan_cfg);
1871 if (ret) {
1872 dev_err(priv->adapter->dev, "scan failed: %d\n", ret);
1873 return ret;
1874 }
1860 1875
1861 if (request->ie && request->ie_len) { 1876 if (request->ie && request->ie_len) {
1862 for (i = 0; i < MWIFIEX_MAX_VSIE_NUM; i++) { 1877 for (i = 0; i < MWIFIEX_MAX_VSIE_NUM; i++) {
diff --git a/drivers/net/wireless/mwifiex/join.c b/drivers/net/wireless/mwifiex/join.c
index 82e63cee1e97..7b0858af8f5d 100644
--- a/drivers/net/wireless/mwifiex/join.c
+++ b/drivers/net/wireless/mwifiex/join.c
@@ -1180,16 +1180,18 @@ int mwifiex_ret_802_11_ad_hoc(struct mwifiex_private *priv,
1180 struct mwifiex_adapter *adapter = priv->adapter; 1180 struct mwifiex_adapter *adapter = priv->adapter;
1181 struct host_cmd_ds_802_11_ad_hoc_result *adhoc_result; 1181 struct host_cmd_ds_802_11_ad_hoc_result *adhoc_result;
1182 struct mwifiex_bssdescriptor *bss_desc; 1182 struct mwifiex_bssdescriptor *bss_desc;
1183 u16 reason_code;
1183 1184
1184 adhoc_result = &resp->params.adhoc_result; 1185 adhoc_result = &resp->params.adhoc_result;
1185 1186
1186 bss_desc = priv->attempted_bss_desc; 1187 bss_desc = priv->attempted_bss_desc;
1187 1188
1188 /* Join result code 0 --> SUCCESS */ 1189 /* Join result code 0 --> SUCCESS */
1189 if (le16_to_cpu(resp->result)) { 1190 reason_code = le16_to_cpu(resp->result);
1191 if (reason_code) {
1190 dev_err(priv->adapter->dev, "ADHOC_RESP: failed\n"); 1192 dev_err(priv->adapter->dev, "ADHOC_RESP: failed\n");
1191 if (priv->media_connected) 1193 if (priv->media_connected)
1192 mwifiex_reset_connect_state(priv); 1194 mwifiex_reset_connect_state(priv, reason_code);
1193 1195
1194 memset(&priv->curr_bss_params.bss_descriptor, 1196 memset(&priv->curr_bss_params.bss_descriptor,
1195 0x00, sizeof(struct mwifiex_bssdescriptor)); 1197 0x00, sizeof(struct mwifiex_bssdescriptor));
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index bfb3fa69805c..c2d0ab146af5 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -847,7 +847,7 @@ int mwifiex_cmd_802_11_associate(struct mwifiex_private *priv,
847 struct mwifiex_bssdescriptor *bss_desc); 847 struct mwifiex_bssdescriptor *bss_desc);
848int mwifiex_ret_802_11_associate(struct mwifiex_private *priv, 848int mwifiex_ret_802_11_associate(struct mwifiex_private *priv,
849 struct host_cmd_ds_command *resp); 849 struct host_cmd_ds_command *resp);
850void mwifiex_reset_connect_state(struct mwifiex_private *priv); 850void mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason);
851u8 mwifiex_band_to_radio_type(u8 band); 851u8 mwifiex_band_to_radio_type(u8 band);
852int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac); 852int mwifiex_deauthenticate(struct mwifiex_private *priv, u8 *mac);
853int mwifiex_adhoc_start(struct mwifiex_private *priv, 853int mwifiex_adhoc_start(struct mwifiex_private *priv,
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index e36a75988f87..00b658d3b6ec 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -1296,7 +1296,7 @@ mwifiex_radio_type_to_band(u8 radio_type)
1296int mwifiex_scan_networks(struct mwifiex_private *priv, 1296int mwifiex_scan_networks(struct mwifiex_private *priv,
1297 const struct mwifiex_user_scan_cfg *user_scan_in) 1297 const struct mwifiex_user_scan_cfg *user_scan_in)
1298{ 1298{
1299 int ret = 0; 1299 int ret;
1300 struct mwifiex_adapter *adapter = priv->adapter; 1300 struct mwifiex_adapter *adapter = priv->adapter;
1301 struct cmd_ctrl_node *cmd_node; 1301 struct cmd_ctrl_node *cmd_node;
1302 union mwifiex_scan_cmd_config_tlv *scan_cfg_out; 1302 union mwifiex_scan_cmd_config_tlv *scan_cfg_out;
@@ -1309,25 +1309,26 @@ int mwifiex_scan_networks(struct mwifiex_private *priv,
1309 unsigned long flags; 1309 unsigned long flags;
1310 1310
1311 if (adapter->scan_processing) { 1311 if (adapter->scan_processing) {
1312 dev_dbg(adapter->dev, "cmd: Scan already in process...\n"); 1312 dev_err(adapter->dev, "cmd: Scan already in process...\n");
1313 return ret; 1313 return -EBUSY;
1314 } 1314 }
1315 1315
1316 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
1317 adapter->scan_processing = true;
1318 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
1319
1320 if (priv->scan_block) { 1316 if (priv->scan_block) {
1321 dev_dbg(adapter->dev, 1317 dev_err(adapter->dev,
1322 "cmd: Scan is blocked during association...\n"); 1318 "cmd: Scan is blocked during association...\n");
1323 return ret; 1319 return -EBUSY;
1324 } 1320 }
1325 1321
1322 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
1323 adapter->scan_processing = true;
1324 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
1325
1326 scan_cfg_out = kzalloc(sizeof(union mwifiex_scan_cmd_config_tlv), 1326 scan_cfg_out = kzalloc(sizeof(union mwifiex_scan_cmd_config_tlv),
1327 GFP_KERNEL); 1327 GFP_KERNEL);
1328 if (!scan_cfg_out) { 1328 if (!scan_cfg_out) {
1329 dev_err(adapter->dev, "failed to alloc scan_cfg_out\n"); 1329 dev_err(adapter->dev, "failed to alloc scan_cfg_out\n");
1330 return -ENOMEM; 1330 ret = -ENOMEM;
1331 goto done;
1331 } 1332 }
1332 1333
1333 buf_size = sizeof(struct mwifiex_chan_scan_param_set) * 1334 buf_size = sizeof(struct mwifiex_chan_scan_param_set) *
@@ -1336,7 +1337,8 @@ int mwifiex_scan_networks(struct mwifiex_private *priv,
1336 if (!scan_chan_list) { 1337 if (!scan_chan_list) {
1337 dev_err(adapter->dev, "failed to alloc scan_chan_list\n"); 1338 dev_err(adapter->dev, "failed to alloc scan_chan_list\n");
1338 kfree(scan_cfg_out); 1339 kfree(scan_cfg_out);
1339 return -ENOMEM; 1340 ret = -ENOMEM;
1341 goto done;
1340 } 1342 }
1341 1343
1342 mwifiex_config_scan(priv, user_scan_in, &scan_cfg_out->config, 1344 mwifiex_config_scan(priv, user_scan_in, &scan_cfg_out->config,
@@ -1364,14 +1366,16 @@ int mwifiex_scan_networks(struct mwifiex_private *priv,
1364 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, 1366 spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
1365 flags); 1367 flags);
1366 } 1368 }
1367 } else {
1368 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
1369 adapter->scan_processing = true;
1370 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
1371 } 1369 }
1372 1370
1373 kfree(scan_cfg_out); 1371 kfree(scan_cfg_out);
1374 kfree(scan_chan_list); 1372 kfree(scan_chan_list);
1373done:
1374 if (ret) {
1375 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
1376 adapter->scan_processing = false;
1377 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
1378 }
1375 return ret; 1379 return ret;
1376} 1380}
1377 1381
@@ -1430,8 +1434,8 @@ int mwifiex_check_network_compatibility(struct mwifiex_private *priv,
1430 ret = mwifiex_is_network_compatible(priv, bss_desc, 1434 ret = mwifiex_is_network_compatible(priv, bss_desc,
1431 priv->bss_mode); 1435 priv->bss_mode);
1432 if (ret) 1436 if (ret)
1433 dev_err(priv->adapter->dev, "cannot find ssid " 1437 dev_err(priv->adapter->dev,
1434 "%s\n", bss_desc->ssid.ssid); 1438 "Incompatible network settings\n");
1435 break; 1439 break;
1436 default: 1440 default:
1437 ret = 0; 1441 ret = 0;
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index e380171c4c5d..09e6a267f566 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -545,7 +545,7 @@ static int mwifiex_ret_802_11_deauthenticate(struct mwifiex_private *priv,
545 if (!memcmp(resp->params.deauth.mac_addr, 545 if (!memcmp(resp->params.deauth.mac_addr,
546 &priv->curr_bss_params.bss_descriptor.mac_address, 546 &priv->curr_bss_params.bss_descriptor.mac_address,
547 sizeof(resp->params.deauth.mac_addr))) 547 sizeof(resp->params.deauth.mac_addr)))
548 mwifiex_reset_connect_state(priv); 548 mwifiex_reset_connect_state(priv, WLAN_REASON_DEAUTH_LEAVING);
549 549
550 return 0; 550 return 0;
551} 551}
@@ -558,7 +558,7 @@ static int mwifiex_ret_802_11_deauthenticate(struct mwifiex_private *priv,
558static int mwifiex_ret_802_11_ad_hoc_stop(struct mwifiex_private *priv, 558static int mwifiex_ret_802_11_ad_hoc_stop(struct mwifiex_private *priv,
559 struct host_cmd_ds_command *resp) 559 struct host_cmd_ds_command *resp)
560{ 560{
561 mwifiex_reset_connect_state(priv); 561 mwifiex_reset_connect_state(priv, WLAN_REASON_DEAUTH_LEAVING);
562 return 0; 562 return 0;
563} 563}
564 564
diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c
index aafde30e714a..8132119e1a21 100644
--- a/drivers/net/wireless/mwifiex/sta_event.c
+++ b/drivers/net/wireless/mwifiex/sta_event.c
@@ -41,7 +41,7 @@
41 * - Sends a disconnect event to upper layers/applications. 41 * - Sends a disconnect event to upper layers/applications.
42 */ 42 */
43void 43void
44mwifiex_reset_connect_state(struct mwifiex_private *priv) 44mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason_code)
45{ 45{
46 struct mwifiex_adapter *adapter = priv->adapter; 46 struct mwifiex_adapter *adapter = priv->adapter;
47 47
@@ -117,10 +117,10 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv)
117 priv->media_connected = false; 117 priv->media_connected = false;
118 dev_dbg(adapter->dev, 118 dev_dbg(adapter->dev,
119 "info: successfully disconnected from %pM: reason code %d\n", 119 "info: successfully disconnected from %pM: reason code %d\n",
120 priv->cfg_bssid, WLAN_REASON_DEAUTH_LEAVING); 120 priv->cfg_bssid, reason_code);
121 if (priv->bss_mode == NL80211_IFTYPE_STATION) { 121 if (priv->bss_mode == NL80211_IFTYPE_STATION) {
122 cfg80211_disconnected(priv->netdev, WLAN_REASON_DEAUTH_LEAVING, 122 cfg80211_disconnected(priv->netdev, reason_code, NULL, 0,
123 NULL, 0, GFP_KERNEL); 123 GFP_KERNEL);
124 } 124 }
125 memset(priv->cfg_bssid, 0, ETH_ALEN); 125 memset(priv->cfg_bssid, 0, ETH_ALEN);
126 126
@@ -186,7 +186,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
186 struct mwifiex_adapter *adapter = priv->adapter; 186 struct mwifiex_adapter *adapter = priv->adapter;
187 int ret = 0; 187 int ret = 0;
188 u32 eventcause = adapter->event_cause; 188 u32 eventcause = adapter->event_cause;
189 u16 ctrl; 189 u16 ctrl, reason_code;
190 190
191 switch (eventcause) { 191 switch (eventcause) {
192 case EVENT_DUMMY_HOST_WAKEUP_SIGNAL: 192 case EVENT_DUMMY_HOST_WAKEUP_SIGNAL:
@@ -204,22 +204,31 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
204 case EVENT_DEAUTHENTICATED: 204 case EVENT_DEAUTHENTICATED:
205 dev_dbg(adapter->dev, "event: Deauthenticated\n"); 205 dev_dbg(adapter->dev, "event: Deauthenticated\n");
206 adapter->dbg.num_event_deauth++; 206 adapter->dbg.num_event_deauth++;
207 if (priv->media_connected) 207 if (priv->media_connected) {
208 mwifiex_reset_connect_state(priv); 208 reason_code =
209 le16_to_cpu(*(__le16 *)adapter->event_body);
210 mwifiex_reset_connect_state(priv, reason_code);
211 }
209 break; 212 break;
210 213
211 case EVENT_DISASSOCIATED: 214 case EVENT_DISASSOCIATED:
212 dev_dbg(adapter->dev, "event: Disassociated\n"); 215 dev_dbg(adapter->dev, "event: Disassociated\n");
213 adapter->dbg.num_event_disassoc++; 216 adapter->dbg.num_event_disassoc++;
214 if (priv->media_connected) 217 if (priv->media_connected) {
215 mwifiex_reset_connect_state(priv); 218 reason_code =
219 le16_to_cpu(*(__le16 *)adapter->event_body);
220 mwifiex_reset_connect_state(priv, reason_code);
221 }
216 break; 222 break;
217 223
218 case EVENT_LINK_LOST: 224 case EVENT_LINK_LOST:
219 dev_dbg(adapter->dev, "event: Link lost\n"); 225 dev_dbg(adapter->dev, "event: Link lost\n");
220 adapter->dbg.num_event_link_lost++; 226 adapter->dbg.num_event_link_lost++;
221 if (priv->media_connected) 227 if (priv->media_connected) {
222 mwifiex_reset_connect_state(priv); 228 reason_code =
229 le16_to_cpu(*(__le16 *)adapter->event_body);
230 mwifiex_reset_connect_state(priv, reason_code);
231 }
223 break; 232 break;
224 233
225 case EVENT_PS_SLEEP: 234 case EVENT_PS_SLEEP:
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 540c94f8505a..01dc8891070c 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -2252,9 +2252,9 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
2252 */ 2252 */
2253 if (rt2x00_rt(rt2x00dev, RT3352)) { 2253 if (rt2x00_rt(rt2x00dev, RT3352)) {
2254 rt2800_bbp_write(rt2x00dev, 27, 0x0); 2254 rt2800_bbp_write(rt2x00dev, 27, 0x0);
2255 rt2800_bbp_write(rt2x00dev, 62, 0x26 + rt2x00dev->lna_gain); 2255 rt2800_bbp_write(rt2x00dev, 66, 0x26 + rt2x00dev->lna_gain);
2256 rt2800_bbp_write(rt2x00dev, 27, 0x20); 2256 rt2800_bbp_write(rt2x00dev, 27, 0x20);
2257 rt2800_bbp_write(rt2x00dev, 62, 0x26 + rt2x00dev->lna_gain); 2257 rt2800_bbp_write(rt2x00dev, 66, 0x26 + rt2x00dev->lna_gain);
2258 } else { 2258 } else {
2259 rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain); 2259 rt2800_bbp_write(rt2x00dev, 62, 0x37 - rt2x00dev->lna_gain);
2260 rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain); 2260 rt2800_bbp_write(rt2x00dev, 63, 0x37 - rt2x00dev->lna_gain);