aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/ath/ar5523/ar5523.c3
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.c3
-rw-r--r--drivers/net/wireless/ath/ath5k/phy.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/Makefile3
-rw-r--r--drivers/net/wireless/ath/ath9k/ahb.c4
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9330_1p2_initvals.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9340_initvals.h8
-rw-r--r--drivers/net/wireless/ath/ath9k/ar953x_initvals.h6
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h3
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/common-debug.c253
-rw-r--r--drivers/net/wireless/ath/ath9k/common-debug.h72
-rw-r--r--drivers/net/wireless/ath/ath9k/common.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c214
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.h44
-rw-r--r--drivers/net/wireless/ath/ath9k/debug_sta.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/dfs.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/dfs_debug.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/htc.h17
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_debug.c555
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_txrx.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c8
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c7
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c13
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c14
-rw-r--r--drivers/net/wireless/ath/carl9170/main.c4
-rw-r--r--drivers/net/wireless/b43/Kconfig38
-rw-r--r--drivers/net/wireless/b43/bus.h10
-rw-r--r--drivers/net/wireless/b43/main.c27
-rw-r--r--drivers/net/wireless/b43/phy_common.c6
-rw-r--r--drivers/net/wireless/b43/phy_n.c32
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/chip.c5
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd.h2
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h1
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c18
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c32
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h24
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c80
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/nvram.c220
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/usb.c1
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c202
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c3
-rw-r--r--drivers/net/wireless/brcm80211/brcmutil/d11.c93
-rw-r--r--drivers/net/wireless/brcm80211/include/brcmu_d11.h14
-rw-r--r--drivers/net/wireless/brcm80211/include/brcmu_wifi.h1
-rw-r--r--drivers/net/wireless/cw1200/sta.c3
-rw-r--r--drivers/net/wireless/cw1200/sta.h3
-rw-r--r--drivers/net/wireless/iwlegacy/3945.c2
-rw-r--r--drivers/net/wireless/iwlegacy/4965-mac.c2
-rw-r--r--drivers/net/wireless/iwlegacy/common.c3
-rw-r--r--drivers/net/wireless/iwlegacy/common.h3
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig12
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/Makefile3
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/dev.h2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/led.h12
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/mac80211.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-7000.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-8000.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-hw.h4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-config.h6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h (renamed from drivers/net/wireless/iwlwifi/mvm/fw-error-dump.h)26
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-nvm-parse.c46
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h19
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/Makefile3
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/coex.c6
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h8
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw.c2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c12
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c100
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h19
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/nvm.c30
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c36
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c9
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.c173
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/scan.c55
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/utils.c21
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/internal.h24
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/rx.c2
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c74
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/tx.c129
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c5
-rw-r--r--drivers/net/wireless/mwifiex/11n.c42
-rw-r--r--drivers/net/wireless/mwifiex/11n.h1
-rw-r--r--drivers/net/wireless/mwifiex/cmdevt.c3
-rw-r--r--drivers/net/wireless/mwifiex/fw.h20
-rw-r--r--drivers/net/wireless/mwifiex/main.c2
-rw-r--r--drivers/net/wireless/mwifiex/main.h2
-rw-r--r--drivers/net/wireless/mwifiex/pcie.c227
-rw-r--r--drivers/net/wireless/mwifiex/pcie.h27
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmd.c7
-rw-r--r--drivers/net/wireless/mwifiex/sta_event.c40
-rw-r--r--drivers/net/wireless/mwifiex/tdls.c53
-rw-r--r--drivers/net/wireless/orinoco/orinoco_usb.c2
-rw-r--r--drivers/net/wireless/p54/main.c3
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_mac80211.c1
-rw-r--r--drivers/net/wireless/rsi/rsi_91x_mgmt.c4
-rw-r--r--drivers/net/wireless/rsi/rsi_mgmt.h1
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00.h3
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00mac.c25
-rw-r--r--drivers/net/wireless/rtl818x/rtl8180/dev.c17
-rw-r--r--drivers/net/wireless/rtl818x/rtl8187/dev.c11
-rw-r--r--drivers/net/wireless/rtlwifi/core.c3
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/sw.c5
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/trx.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/hw.c4
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/trx.c6
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/sw.c5
-rw-r--r--drivers/net/wireless/rtlwifi/wifi.h4
-rw-r--r--drivers/net/wireless/ti/wl1251/event.c5
-rw-r--r--drivers/net/wireless/ti/wl1251/main.c68
-rw-r--r--drivers/net/wireless/ti/wlcore/main.c3
-rw-r--r--drivers/net/wireless/ti/wlcore/sdio.c28
-rw-r--r--drivers/net/wireless/ti/wlcore/spi.c23
121 files changed, 1893 insertions, 1704 deletions
diff --git a/drivers/net/wireless/ath/ar5523/ar5523.c b/drivers/net/wireless/ath/ar5523/ar5523.c
index 507d9a9ee69a..f92050617ae6 100644
--- a/drivers/net/wireless/ath/ar5523/ar5523.c
+++ b/drivers/net/wireless/ath/ar5523/ar5523.c
@@ -1090,7 +1090,8 @@ static int ar5523_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
1090 return ret; 1090 return ret;
1091} 1091}
1092 1092
1093static void ar5523_flush(struct ieee80211_hw *hw, u32 queues, bool drop) 1093static void ar5523_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1094 u32 queues, bool drop)
1094{ 1095{
1095 struct ar5523 *ar = hw->priv; 1096 struct ar5523 *ar = hw->priv;
1096 1097
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index e2c01dc5900c..7026f021ccbb 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -3651,7 +3651,8 @@ static int ath10k_set_frag_threshold(struct ieee80211_hw *hw, u32 value)
3651 return ret; 3651 return ret;
3652} 3652}
3653 3653
3654static void ath10k_flush(struct ieee80211_hw *hw, u32 queues, bool drop) 3654static void ath10k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
3655 u32 queues, bool drop)
3655{ 3656{
3656 struct ath10k *ar = hw->priv; 3657 struct ath10k *ar = hw->priv;
3657 bool skip; 3658 bool skip;
diff --git a/drivers/net/wireless/ath/ath5k/phy.c b/drivers/net/wireless/ath/ath5k/phy.c
index 1a2973b7acf2..0fce1c76638e 100644
--- a/drivers/net/wireless/ath/ath5k/phy.c
+++ b/drivers/net/wireless/ath/ath5k/phy.c
@@ -3709,8 +3709,8 @@ ath5k_hw_txpower(struct ath5k_hw *ah, struct ieee80211_channel *channel,
3709 AR5K_REG_MS(AR5K_TUNE_MAX_TXPOWER, AR5K_TPC_CHIRP), 3709 AR5K_REG_MS(AR5K_TUNE_MAX_TXPOWER, AR5K_TPC_CHIRP),
3710 AR5K_TPC); 3710 AR5K_TPC);
3711 } else { 3711 } else {
3712 ath5k_hw_reg_write(ah, AR5K_PHY_TXPOWER_RATE_MAX | 3712 ath5k_hw_reg_write(ah, AR5K_TUNE_MAX_TXPOWER,
3713 AR5K_TUNE_MAX_TXPOWER, AR5K_PHY_TXPOWER_RATE_MAX); 3713 AR5K_PHY_TXPOWER_RATE_MAX);
3714 } 3714 }
3715 3715
3716 return 0; 3716 return 0;
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
index 8e1c7b0fe76c..8fcd586d1c39 100644
--- a/drivers/net/wireless/ath/ath9k/Makefile
+++ b/drivers/net/wireless/ath/ath9k/Makefile
@@ -53,7 +53,8 @@ obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o
53obj-$(CONFIG_ATH9K_COMMON) += ath9k_common.o 53obj-$(CONFIG_ATH9K_COMMON) += ath9k_common.o
54ath9k_common-y:= common.o \ 54ath9k_common-y:= common.o \
55 common-init.o \ 55 common-init.o \
56 common-beacon.o 56 common-beacon.o \
57 common-debug.o
57 58
58ath9k_htc-y += htc_hst.o \ 59ath9k_htc-y += htc_hst.o \
59 hif_usb.o \ 60 hif_usb.o \
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c
index a0398fe3eb28..be3eb2a8d602 100644
--- a/drivers/net/wireless/ath/ath9k/ahb.c
+++ b/drivers/net/wireless/ath/ath9k/ahb.c
@@ -86,7 +86,6 @@ static int ath_ahb_probe(struct platform_device *pdev)
86 int irq; 86 int irq;
87 int ret = 0; 87 int ret = 0;
88 struct ath_hw *ah; 88 struct ath_hw *ah;
89 struct ath_common *common;
90 char hw_name[64]; 89 char hw_name[64];
91 90
92 if (!dev_get_platdata(&pdev->dev)) { 91 if (!dev_get_platdata(&pdev->dev)) {
@@ -146,9 +145,6 @@ static int ath_ahb_probe(struct platform_device *pdev)
146 wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n", 145 wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n",
147 hw_name, (unsigned long)mem, irq); 146 hw_name, (unsigned long)mem, irq);
148 147
149 common = ath9k_hw_common(sc->sc_ah);
150 /* Will be cleared in ath9k_start() */
151 set_bit(ATH_OP_INVALID, &common->op_flags);
152 return 0; 148 return 0;
153 149
154 err_irq: 150 err_irq:
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index 6d47783f2e5b..ba502a2d199b 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -155,6 +155,9 @@ static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel,
155 ATH9K_ANI_RSSI_THR_LOW, 155 ATH9K_ANI_RSSI_THR_LOW,
156 ATH9K_ANI_RSSI_THR_HIGH); 156 ATH9K_ANI_RSSI_THR_HIGH);
157 157
158 if (AR_SREV_9100(ah) && immunityLevel < ATH9K_ANI_OFDM_DEF_LEVEL)
159 immunityLevel = ATH9K_ANI_OFDM_DEF_LEVEL;
160
158 if (!scan) 161 if (!scan)
159 aniState->ofdmNoiseImmunityLevel = immunityLevel; 162 aniState->ofdmNoiseImmunityLevel = immunityLevel;
160 163
@@ -235,6 +238,9 @@ static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel,
235 BEACON_RSSI(ah), ATH9K_ANI_RSSI_THR_LOW, 238 BEACON_RSSI(ah), ATH9K_ANI_RSSI_THR_LOW,
236 ATH9K_ANI_RSSI_THR_HIGH); 239 ATH9K_ANI_RSSI_THR_HIGH);
237 240
241 if (AR_SREV_9100(ah) && immunityLevel < ATH9K_ANI_CCK_DEF_LEVEL)
242 immunityLevel = ATH9K_ANI_CCK_DEF_LEVEL;
243
238 if (ah->opmode == NL80211_IFTYPE_STATION && 244 if (ah->opmode == NL80211_IFTYPE_STATION &&
239 BEACON_RSSI(ah) <= ATH9K_ANI_RSSI_THR_LOW && 245 BEACON_RSSI(ah) <= ATH9K_ANI_RSSI_THR_LOW &&
240 immunityLevel > ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI) 246 immunityLevel > ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI)
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
index 0a6163e9248c..c38399bc9aa9 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_2p2_initvals.h
@@ -410,7 +410,7 @@ static const u32 ar9300_2p2_baseband_core[][2] = {
410 {0x00009e30, 0x06336f77}, 410 {0x00009e30, 0x06336f77},
411 {0x00009e34, 0x6af6532f}, 411 {0x00009e34, 0x6af6532f},
412 {0x00009e38, 0x0cc80c00}, 412 {0x00009e38, 0x0cc80c00},
413 {0x00009e40, 0x0d261820}, 413 {0x00009e40, 0x0d261800},
414 {0x00009e4c, 0x00001004}, 414 {0x00009e4c, 0x00001004},
415 {0x00009e50, 0x00ff03f1}, 415 {0x00009e50, 0x00ff03f1},
416 {0x00009e54, 0x00000000}, 416 {0x00009e54, 0x00000000},
diff --git a/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h b/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h
index f76139bbb74f..2c42ff05efa3 100644
--- a/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9330_1p1_initvals.h
@@ -592,7 +592,7 @@ static const u32 ar9331_1p1_baseband_core[][2] = {
592 {0x00009e30, 0x06336f77}, 592 {0x00009e30, 0x06336f77},
593 {0x00009e34, 0x6af6532f}, 593 {0x00009e34, 0x6af6532f},
594 {0x00009e38, 0x0cc80c00}, 594 {0x00009e38, 0x0cc80c00},
595 {0x00009e40, 0x0d261820}, 595 {0x00009e40, 0x0d261800},
596 {0x00009e4c, 0x00001004}, 596 {0x00009e4c, 0x00001004},
597 {0x00009e50, 0x00ff03f1}, 597 {0x00009e50, 0x00ff03f1},
598 {0x00009fc0, 0x803e4788}, 598 {0x00009fc0, 0x803e4788},
diff --git a/drivers/net/wireless/ath/ath9k/ar9330_1p2_initvals.h b/drivers/net/wireless/ath/ath9k/ar9330_1p2_initvals.h
index 0ac8be96097f..2154efcd3900 100644
--- a/drivers/net/wireless/ath/ath9k/ar9330_1p2_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9330_1p2_initvals.h
@@ -231,7 +231,7 @@ static const u32 ar9331_1p2_baseband_core[][2] = {
231 {0x00009e30, 0x06336f77}, 231 {0x00009e30, 0x06336f77},
232 {0x00009e34, 0x6af6532f}, 232 {0x00009e34, 0x6af6532f},
233 {0x00009e38, 0x0cc80c00}, 233 {0x00009e38, 0x0cc80c00},
234 {0x00009e40, 0x0d261820}, 234 {0x00009e40, 0x0d261800},
235 {0x00009e4c, 0x00001004}, 235 {0x00009e4c, 0x00001004},
236 {0x00009e50, 0x00ff03f1}, 236 {0x00009e50, 0x00ff03f1},
237 {0x00009fc0, 0x803e4788}, 237 {0x00009fc0, 0x803e4788},
diff --git a/drivers/net/wireless/ath/ath9k/ar9340_initvals.h b/drivers/net/wireless/ath/ath9k/ar9340_initvals.h
index a01f0edb6518..b995ffe88b33 100644
--- a/drivers/net/wireless/ath/ath9k/ar9340_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9340_initvals.h
@@ -318,7 +318,7 @@ static const u32 ar9340_1p0_baseband_core[][2] = {
318 {0x00009e30, 0x06336f77}, 318 {0x00009e30, 0x06336f77},
319 {0x00009e34, 0x6af6532f}, 319 {0x00009e34, 0x6af6532f},
320 {0x00009e38, 0x0cc80c00}, 320 {0x00009e38, 0x0cc80c00},
321 {0x00009e40, 0x0d261820}, 321 {0x00009e40, 0x0d261800},
322 {0x00009e4c, 0x00001004}, 322 {0x00009e4c, 0x00001004},
323 {0x00009e50, 0x00ff03f1}, 323 {0x00009e50, 0x00ff03f1},
324 {0x00009e54, 0x00000000}, 324 {0x00009e54, 0x00000000},
@@ -348,9 +348,9 @@ static const u32 ar9340_1p0_baseband_core[][2] = {
348 {0x0000a370, 0x00000000}, 348 {0x0000a370, 0x00000000},
349 {0x0000a390, 0x00000001}, 349 {0x0000a390, 0x00000001},
350 {0x0000a394, 0x00000444}, 350 {0x0000a394, 0x00000444},
351 {0x0000a398, 0x00000000}, 351 {0x0000a398, 0x001f0e0f},
352 {0x0000a39c, 0x210d0401}, 352 {0x0000a39c, 0x0075393f},
353 {0x0000a3a0, 0xab9a7144}, 353 {0x0000a3a0, 0xb79f6427},
354 {0x0000a3a4, 0x00000000}, 354 {0x0000a3a4, 0x00000000},
355 {0x0000a3a8, 0xaaaaaaaa}, 355 {0x0000a3a8, 0xaaaaaaaa},
356 {0x0000a3ac, 0x3c466478}, 356 {0x0000a3ac, 0x3c466478},
diff --git a/drivers/net/wireless/ath/ath9k/ar953x_initvals.h b/drivers/net/wireless/ath/ath9k/ar953x_initvals.h
index 3c9113d9b1bc..8e5c3b9786e3 100644
--- a/drivers/net/wireless/ath/ath9k/ar953x_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar953x_initvals.h
@@ -257,9 +257,9 @@ static const u32 qca953x_1p0_baseband_core[][2] = {
257 {0x0000a370, 0x00000000}, 257 {0x0000a370, 0x00000000},
258 {0x0000a390, 0x00000001}, 258 {0x0000a390, 0x00000001},
259 {0x0000a394, 0x00000444}, 259 {0x0000a394, 0x00000444},
260 {0x0000a398, 0x1f020503}, 260 {0x0000a398, 0x001f0e0f},
261 {0x0000a39c, 0x29180c03}, 261 {0x0000a39c, 0x0075393f},
262 {0x0000a3a0, 0x9a8b6844}, 262 {0x0000a3a0, 0xb79f6427},
263 {0x0000a3a4, 0x000000ff}, 263 {0x0000a3a4, 0x000000ff},
264 {0x0000a3a8, 0x6a6a6a6a}, 264 {0x0000a3a8, 0x6a6a6a6a},
265 {0x0000a3ac, 0x6a6a6a6a}, 265 {0x0000a3ac, 0x6a6a6a6a},
diff --git a/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h
index e6aec2c0207f..a5ca65240af3 100644
--- a/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9580_1p0_initvals.h
@@ -90,7 +90,7 @@ static const u32 ar9580_1p0_baseband_core[][2] = {
90 {0x00009e30, 0x06336f77}, 90 {0x00009e30, 0x06336f77},
91 {0x00009e34, 0x6af6532f}, 91 {0x00009e34, 0x6af6532f},
92 {0x00009e38, 0x0cc80c00}, 92 {0x00009e38, 0x0cc80c00},
93 {0x00009e40, 0x0d261820}, 93 {0x00009e40, 0x0d261800},
94 {0x00009e4c, 0x00001004}, 94 {0x00009e4c, 0x00001004},
95 {0x00009e50, 0x00ff03f1}, 95 {0x00009e50, 0x00ff03f1},
96 {0x00009e54, 0x00000000}, 96 {0x00009e54, 0x00000000},
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 05935f638525..20dd344bf645 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -23,8 +23,8 @@
23#include <linux/leds.h> 23#include <linux/leds.h>
24#include <linux/completion.h> 24#include <linux/completion.h>
25 25
26#include "debug.h"
27#include "common.h" 26#include "common.h"
27#include "debug.h"
28#include "mci.h" 28#include "mci.h"
29#include "dfs.h" 29#include "dfs.h"
30#include "spectral.h" 30#include "spectral.h"
@@ -254,7 +254,6 @@ struct ath_atx_tid {
254 254
255 s8 bar_index; 255 s8 bar_index;
256 bool sched; 256 bool sched;
257 bool paused;
258 bool active; 257 bool active;
259}; 258};
260 259
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index bd9e634879e6..e387f0b2954a 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -537,8 +537,6 @@ static void ath9k_cache_beacon_config(struct ath_softc *sc,
537 cur_conf->dtim_period = bss_conf->dtim_period; 537 cur_conf->dtim_period = bss_conf->dtim_period;
538 cur_conf->dtim_count = 1; 538 cur_conf->dtim_count = 1;
539 cur_conf->ibss_creator = bss_conf->ibss_creator; 539 cur_conf->ibss_creator = bss_conf->ibss_creator;
540 cur_conf->bmiss_timeout =
541 ATH_DEFAULT_BMISS_LIMIT * cur_conf->beacon_interval;
542 540
543 /* 541 /*
544 * It looks like mac80211 may end up using beacon interval of zero in 542 * It looks like mac80211 may end up using beacon interval of zero in
@@ -549,6 +547,9 @@ static void ath9k_cache_beacon_config(struct ath_softc *sc,
549 if (cur_conf->beacon_interval == 0) 547 if (cur_conf->beacon_interval == 0)
550 cur_conf->beacon_interval = 100; 548 cur_conf->beacon_interval = 100;
551 549
550 cur_conf->bmiss_timeout =
551 ATH_DEFAULT_BMISS_LIMIT * cur_conf->beacon_interval;
552
552 /* 553 /*
553 * We don't parse dtim period from mac80211 during the driver 554 * We don't parse dtim period from mac80211 during the driver
554 * initialization as it breaks association with hidden-ssid 555 * initialization as it breaks association with hidden-ssid
diff --git a/drivers/net/wireless/ath/ath9k/common-debug.c b/drivers/net/wireless/ath/ath9k/common-debug.c
new file mode 100644
index 000000000000..3b289f933405
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/common-debug.c
@@ -0,0 +1,253 @@
1/*
2 * Copyright (c) 2008-2011 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "common.h"
18
19static ssize_t read_file_modal_eeprom(struct file *file, char __user *user_buf,
20 size_t count, loff_t *ppos)
21{
22 struct ath_hw *ah = file->private_data;
23 u32 len = 0, size = 6000;
24 char *buf;
25 size_t retval;
26
27 buf = kzalloc(size, GFP_KERNEL);
28 if (buf == NULL)
29 return -ENOMEM;
30
31 len = ah->eep_ops->dump_eeprom(ah, false, buf, len, size);
32
33 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
34 kfree(buf);
35
36 return retval;
37}
38
39static const struct file_operations fops_modal_eeprom = {
40 .read = read_file_modal_eeprom,
41 .open = simple_open,
42 .owner = THIS_MODULE,
43 .llseek = default_llseek,
44};
45
46
47void ath9k_cmn_debug_modal_eeprom(struct dentry *debugfs_phy,
48 struct ath_hw *ah)
49{
50 debugfs_create_file("modal_eeprom", S_IRUSR, debugfs_phy, ah,
51 &fops_modal_eeprom);
52}
53EXPORT_SYMBOL(ath9k_cmn_debug_modal_eeprom);
54
55static ssize_t read_file_base_eeprom(struct file *file, char __user *user_buf,
56 size_t count, loff_t *ppos)
57{
58 struct ath_hw *ah = file->private_data;
59 u32 len = 0, size = 1500;
60 ssize_t retval = 0;
61 char *buf;
62
63 buf = kzalloc(size, GFP_KERNEL);
64 if (!buf)
65 return -ENOMEM;
66
67 len = ah->eep_ops->dump_eeprom(ah, true, buf, len, size);
68
69 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
70 kfree(buf);
71
72 return retval;
73}
74
75static const struct file_operations fops_base_eeprom = {
76 .read = read_file_base_eeprom,
77 .open = simple_open,
78 .owner = THIS_MODULE,
79 .llseek = default_llseek,
80};
81
82void ath9k_cmn_debug_base_eeprom(struct dentry *debugfs_phy,
83 struct ath_hw *ah)
84{
85 debugfs_create_file("base_eeprom", S_IRUSR, debugfs_phy, ah,
86 &fops_base_eeprom);
87}
88EXPORT_SYMBOL(ath9k_cmn_debug_base_eeprom);
89
90void ath9k_cmn_debug_stat_rx(struct ath_rx_stats *rxstats,
91 struct ath_rx_status *rs)
92{
93#define RX_PHY_ERR_INC(c) rxstats->phy_err_stats[c]++
94#define RX_CMN_STAT_INC(c) (rxstats->c++)
95
96 RX_CMN_STAT_INC(rx_pkts_all);
97 rxstats->rx_bytes_all += rs->rs_datalen;
98
99 if (rs->rs_status & ATH9K_RXERR_CRC)
100 RX_CMN_STAT_INC(crc_err);
101 if (rs->rs_status & ATH9K_RXERR_DECRYPT)
102 RX_CMN_STAT_INC(decrypt_crc_err);
103 if (rs->rs_status & ATH9K_RXERR_MIC)
104 RX_CMN_STAT_INC(mic_err);
105 if (rs->rs_status & ATH9K_RX_DELIM_CRC_PRE)
106 RX_CMN_STAT_INC(pre_delim_crc_err);
107 if (rs->rs_status & ATH9K_RX_DELIM_CRC_POST)
108 RX_CMN_STAT_INC(post_delim_crc_err);
109 if (rs->rs_status & ATH9K_RX_DECRYPT_BUSY)
110 RX_CMN_STAT_INC(decrypt_busy_err);
111
112 if (rs->rs_status & ATH9K_RXERR_PHY) {
113 RX_CMN_STAT_INC(phy_err);
114 if (rs->rs_phyerr < ATH9K_PHYERR_MAX)
115 RX_PHY_ERR_INC(rs->rs_phyerr);
116 }
117
118#undef RX_CMN_STAT_INC
119#undef RX_PHY_ERR_INC
120}
121EXPORT_SYMBOL(ath9k_cmn_debug_stat_rx);
122
123static ssize_t read_file_recv(struct file *file, char __user *user_buf,
124 size_t count, loff_t *ppos)
125{
126#define RXS_ERR(s, e) \
127 do { \
128 len += scnprintf(buf + len, size - len, \
129 "%18s : %10u\n", s, \
130 rxstats->e); \
131 } while (0)
132
133 struct ath_rx_stats *rxstats = file->private_data;
134 char *buf;
135 unsigned int len = 0, size = 1600;
136 ssize_t retval = 0;
137
138 buf = kzalloc(size, GFP_KERNEL);
139 if (buf == NULL)
140 return -ENOMEM;
141
142 RXS_ERR("PKTS-ALL", rx_pkts_all);
143 RXS_ERR("BYTES-ALL", rx_bytes_all);
144 RXS_ERR("BEACONS", rx_beacons);
145 RXS_ERR("FRAGS", rx_frags);
146 RXS_ERR("SPECTRAL", rx_spectral);
147
148 RXS_ERR("CRC ERR", crc_err);
149 RXS_ERR("DECRYPT CRC ERR", decrypt_crc_err);
150 RXS_ERR("PHY ERR", phy_err);
151 RXS_ERR("MIC ERR", mic_err);
152 RXS_ERR("PRE-DELIM CRC ERR", pre_delim_crc_err);
153 RXS_ERR("POST-DELIM CRC ERR", post_delim_crc_err);
154 RXS_ERR("DECRYPT BUSY ERR", decrypt_busy_err);
155 RXS_ERR("LENGTH-ERR", rx_len_err);
156 RXS_ERR("OOM-ERR", rx_oom_err);
157 RXS_ERR("RATE-ERR", rx_rate_err);
158 RXS_ERR("TOO-MANY-FRAGS", rx_too_many_frags_err);
159
160 if (len > size)
161 len = size;
162
163 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
164 kfree(buf);
165
166 return retval;
167
168#undef RXS_ERR
169}
170
171static const struct file_operations fops_recv = {
172 .read = read_file_recv,
173 .open = simple_open,
174 .owner = THIS_MODULE,
175 .llseek = default_llseek,
176};
177
178void ath9k_cmn_debug_recv(struct dentry *debugfs_phy,
179 struct ath_rx_stats *rxstats)
180{
181 debugfs_create_file("recv", S_IRUSR, debugfs_phy, rxstats,
182 &fops_recv);
183}
184EXPORT_SYMBOL(ath9k_cmn_debug_recv);
185
186static ssize_t read_file_phy_err(struct file *file, char __user *user_buf,
187 size_t count, loff_t *ppos)
188{
189#define PHY_ERR(s, p) \
190 len += scnprintf(buf + len, size - len, "%22s : %10u\n", s, \
191 rxstats->phy_err_stats[p]);
192
193 struct ath_rx_stats *rxstats = file->private_data;
194 char *buf;
195 unsigned int len = 0, size = 1600;
196 ssize_t retval = 0;
197
198 buf = kzalloc(size, GFP_KERNEL);
199 if (buf == NULL)
200 return -ENOMEM;
201
202 PHY_ERR("UNDERRUN ERR", ATH9K_PHYERR_UNDERRUN);
203 PHY_ERR("TIMING ERR", ATH9K_PHYERR_TIMING);
204 PHY_ERR("PARITY ERR", ATH9K_PHYERR_PARITY);
205 PHY_ERR("RATE ERR", ATH9K_PHYERR_RATE);
206 PHY_ERR("LENGTH ERR", ATH9K_PHYERR_LENGTH);
207 PHY_ERR("RADAR ERR", ATH9K_PHYERR_RADAR);
208 PHY_ERR("SERVICE ERR", ATH9K_PHYERR_SERVICE);
209 PHY_ERR("TOR ERR", ATH9K_PHYERR_TOR);
210 PHY_ERR("OFDM-TIMING ERR", ATH9K_PHYERR_OFDM_TIMING);
211 PHY_ERR("OFDM-SIGNAL-PARITY ERR", ATH9K_PHYERR_OFDM_SIGNAL_PARITY);
212 PHY_ERR("OFDM-RATE ERR", ATH9K_PHYERR_OFDM_RATE_ILLEGAL);
213 PHY_ERR("OFDM-LENGTH ERR", ATH9K_PHYERR_OFDM_LENGTH_ILLEGAL);
214 PHY_ERR("OFDM-POWER-DROP ERR", ATH9K_PHYERR_OFDM_POWER_DROP);
215 PHY_ERR("OFDM-SERVICE ERR", ATH9K_PHYERR_OFDM_SERVICE);
216 PHY_ERR("OFDM-RESTART ERR", ATH9K_PHYERR_OFDM_RESTART);
217 PHY_ERR("FALSE-RADAR-EXT ERR", ATH9K_PHYERR_FALSE_RADAR_EXT);
218 PHY_ERR("CCK-TIMING ERR", ATH9K_PHYERR_CCK_TIMING);
219 PHY_ERR("CCK-HEADER-CRC ERR", ATH9K_PHYERR_CCK_HEADER_CRC);
220 PHY_ERR("CCK-RATE ERR", ATH9K_PHYERR_CCK_RATE_ILLEGAL);
221 PHY_ERR("CCK-SERVICE ERR", ATH9K_PHYERR_CCK_SERVICE);
222 PHY_ERR("CCK-RESTART ERR", ATH9K_PHYERR_CCK_RESTART);
223 PHY_ERR("CCK-LENGTH ERR", ATH9K_PHYERR_CCK_LENGTH_ILLEGAL);
224 PHY_ERR("CCK-POWER-DROP ERR", ATH9K_PHYERR_CCK_POWER_DROP);
225 PHY_ERR("HT-CRC ERR", ATH9K_PHYERR_HT_CRC_ERROR);
226 PHY_ERR("HT-LENGTH ERR", ATH9K_PHYERR_HT_LENGTH_ILLEGAL);
227 PHY_ERR("HT-RATE ERR", ATH9K_PHYERR_HT_RATE_ILLEGAL);
228
229 if (len > size)
230 len = size;
231
232 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
233 kfree(buf);
234
235 return retval;
236
237#undef PHY_ERR
238}
239
240static const struct file_operations fops_phy_err = {
241 .read = read_file_phy_err,
242 .open = simple_open,
243 .owner = THIS_MODULE,
244 .llseek = default_llseek,
245};
246
247void ath9k_cmn_debug_phy_err(struct dentry *debugfs_phy,
248 struct ath_rx_stats *rxstats)
249{
250 debugfs_create_file("phy_err", S_IRUSR, debugfs_phy, rxstats,
251 &fops_phy_err);
252}
253EXPORT_SYMBOL(ath9k_cmn_debug_phy_err);
diff --git a/drivers/net/wireless/ath/ath9k/common-debug.h b/drivers/net/wireless/ath/ath9k/common-debug.h
new file mode 100644
index 000000000000..7c9788490f7f
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/common-debug.h
@@ -0,0 +1,72 @@
1/*
2 * Copyright (c) 2008-2011 Atheros Communications Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17
18
19/**
20 * struct ath_rx_stats - RX Statistics
21 * @rx_pkts_all: No. of total frames received, including ones that
22 may have had errors.
23 * @rx_bytes_all: No. of total bytes received, including ones that
24 may have had errors.
25 * @crc_err: No. of frames with incorrect CRC value
26 * @decrypt_crc_err: No. of frames whose CRC check failed after
27 decryption process completed
28 * @phy_err: No. of frames whose reception failed because the PHY
29 encountered an error
30 * @mic_err: No. of frames with incorrect TKIP MIC verification failure
31 * @pre_delim_crc_err: Pre-Frame delimiter CRC error detections
32 * @post_delim_crc_err: Post-Frame delimiter CRC error detections
33 * @decrypt_busy_err: Decryption interruptions counter
34 * @phy_err_stats: Individual PHY error statistics
35 * @rx_len_err: No. of frames discarded due to bad length.
36 * @rx_oom_err: No. of frames dropped due to OOM issues.
37 * @rx_rate_err: No. of frames dropped due to rate errors.
38 * @rx_too_many_frags_err: Frames dropped due to too-many-frags received.
39 * @rx_beacons: No. of beacons received.
40 * @rx_frags: No. of rx-fragements received.
41 * @rx_spectral: No of spectral packets received.
42 */
43struct ath_rx_stats {
44 u32 rx_pkts_all;
45 u32 rx_bytes_all;
46 u32 crc_err;
47 u32 decrypt_crc_err;
48 u32 phy_err;
49 u32 mic_err;
50 u32 pre_delim_crc_err;
51 u32 post_delim_crc_err;
52 u32 decrypt_busy_err;
53 u32 phy_err_stats[ATH9K_PHYERR_MAX];
54 u32 rx_len_err;
55 u32 rx_oom_err;
56 u32 rx_rate_err;
57 u32 rx_too_many_frags_err;
58 u32 rx_beacons;
59 u32 rx_frags;
60 u32 rx_spectral;
61};
62
63void ath9k_cmn_debug_modal_eeprom(struct dentry *debugfs_phy,
64 struct ath_hw *ah);
65void ath9k_cmn_debug_base_eeprom(struct dentry *debugfs_phy,
66 struct ath_hw *ah);
67void ath9k_cmn_debug_stat_rx(struct ath_rx_stats *rxstats,
68 struct ath_rx_status *rs);
69void ath9k_cmn_debug_recv(struct dentry *debugfs_phy,
70 struct ath_rx_stats *rxstats);
71void ath9k_cmn_debug_phy_err(struct dentry *debugfs_phy,
72 struct ath_rx_stats *rxstats);
diff --git a/drivers/net/wireless/ath/ath9k/common.h b/drivers/net/wireless/ath/ath9k/common.h
index ca38116838f0..ffc454b18637 100644
--- a/drivers/net/wireless/ath/ath9k/common.h
+++ b/drivers/net/wireless/ath/ath9k/common.h
@@ -23,6 +23,7 @@
23 23
24#include "common-init.h" 24#include "common-init.h"
25#include "common-beacon.h" 25#include "common-beacon.h"
26#include "common-debug.h"
26 27
27/* Common header for Atheros 802.11n base driver cores */ 28/* Common header for Atheros 802.11n base driver cores */
28 29
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index 780ff1bee6f6..6cc42be48d4e 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -948,151 +948,11 @@ static const struct file_operations fops_reset = {
948 .llseek = default_llseek, 948 .llseek = default_llseek,
949}; 949};
950 950
951static ssize_t read_file_recv(struct file *file, char __user *user_buf,
952 size_t count, loff_t *ppos)
953{
954#define RXS_ERR(s, e) \
955 do { \
956 len += scnprintf(buf + len, size - len, \
957 "%18s : %10u\n", s, \
958 sc->debug.stats.rxstats.e);\
959 } while (0)
960
961 struct ath_softc *sc = file->private_data;
962 char *buf;
963 unsigned int len = 0, size = 1600;
964 ssize_t retval = 0;
965
966 buf = kzalloc(size, GFP_KERNEL);
967 if (buf == NULL)
968 return -ENOMEM;
969
970 RXS_ERR("PKTS-ALL", rx_pkts_all);
971 RXS_ERR("BYTES-ALL", rx_bytes_all);
972 RXS_ERR("BEACONS", rx_beacons);
973 RXS_ERR("FRAGS", rx_frags);
974 RXS_ERR("SPECTRAL", rx_spectral);
975
976 RXS_ERR("CRC ERR", crc_err);
977 RXS_ERR("DECRYPT CRC ERR", decrypt_crc_err);
978 RXS_ERR("PHY ERR", phy_err);
979 RXS_ERR("MIC ERR", mic_err);
980 RXS_ERR("PRE-DELIM CRC ERR", pre_delim_crc_err);
981 RXS_ERR("POST-DELIM CRC ERR", post_delim_crc_err);
982 RXS_ERR("DECRYPT BUSY ERR", decrypt_busy_err);
983 RXS_ERR("LENGTH-ERR", rx_len_err);
984 RXS_ERR("OOM-ERR", rx_oom_err);
985 RXS_ERR("RATE-ERR", rx_rate_err);
986 RXS_ERR("TOO-MANY-FRAGS", rx_too_many_frags_err);
987
988 if (len > size)
989 len = size;
990
991 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
992 kfree(buf);
993
994 return retval;
995
996#undef RXS_ERR
997}
998
999void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs) 951void ath_debug_stat_rx(struct ath_softc *sc, struct ath_rx_status *rs)
1000{ 952{
1001#define RX_PHY_ERR_INC(c) sc->debug.stats.rxstats.phy_err_stats[c]++ 953 ath9k_cmn_debug_stat_rx(&sc->debug.stats.rxstats, rs);
1002
1003 RX_STAT_INC(rx_pkts_all);
1004 sc->debug.stats.rxstats.rx_bytes_all += rs->rs_datalen;
1005
1006 if (rs->rs_status & ATH9K_RXERR_CRC)
1007 RX_STAT_INC(crc_err);
1008 if (rs->rs_status & ATH9K_RXERR_DECRYPT)
1009 RX_STAT_INC(decrypt_crc_err);
1010 if (rs->rs_status & ATH9K_RXERR_MIC)
1011 RX_STAT_INC(mic_err);
1012 if (rs->rs_status & ATH9K_RX_DELIM_CRC_PRE)
1013 RX_STAT_INC(pre_delim_crc_err);
1014 if (rs->rs_status & ATH9K_RX_DELIM_CRC_POST)
1015 RX_STAT_INC(post_delim_crc_err);
1016 if (rs->rs_status & ATH9K_RX_DECRYPT_BUSY)
1017 RX_STAT_INC(decrypt_busy_err);
1018
1019 if (rs->rs_status & ATH9K_RXERR_PHY) {
1020 RX_STAT_INC(phy_err);
1021 if (rs->rs_phyerr < ATH9K_PHYERR_MAX)
1022 RX_PHY_ERR_INC(rs->rs_phyerr);
1023 }
1024
1025#undef RX_PHY_ERR_INC
1026} 954}
1027 955
1028static const struct file_operations fops_recv = {
1029 .read = read_file_recv,
1030 .open = simple_open,
1031 .owner = THIS_MODULE,
1032 .llseek = default_llseek,
1033};
1034
1035static ssize_t read_file_phy_err(struct file *file, char __user *user_buf,
1036 size_t count, loff_t *ppos)
1037{
1038#define PHY_ERR(s, p) \
1039 len += scnprintf(buf + len, size - len, "%22s : %10u\n", s, \
1040 sc->debug.stats.rxstats.phy_err_stats[p]);
1041
1042 struct ath_softc *sc = file->private_data;
1043 char *buf;
1044 unsigned int len = 0, size = 1600;
1045 ssize_t retval = 0;
1046
1047 buf = kzalloc(size, GFP_KERNEL);
1048 if (buf == NULL)
1049 return -ENOMEM;
1050
1051 PHY_ERR("UNDERRUN ERR", ATH9K_PHYERR_UNDERRUN);
1052 PHY_ERR("TIMING ERR", ATH9K_PHYERR_TIMING);
1053 PHY_ERR("PARITY ERR", ATH9K_PHYERR_PARITY);
1054 PHY_ERR("RATE ERR", ATH9K_PHYERR_RATE);
1055 PHY_ERR("LENGTH ERR", ATH9K_PHYERR_LENGTH);
1056 PHY_ERR("RADAR ERR", ATH9K_PHYERR_RADAR);
1057 PHY_ERR("SERVICE ERR", ATH9K_PHYERR_SERVICE);
1058 PHY_ERR("TOR ERR", ATH9K_PHYERR_TOR);
1059 PHY_ERR("OFDM-TIMING ERR", ATH9K_PHYERR_OFDM_TIMING);
1060 PHY_ERR("OFDM-SIGNAL-PARITY ERR", ATH9K_PHYERR_OFDM_SIGNAL_PARITY);
1061 PHY_ERR("OFDM-RATE ERR", ATH9K_PHYERR_OFDM_RATE_ILLEGAL);
1062 PHY_ERR("OFDM-LENGTH ERR", ATH9K_PHYERR_OFDM_LENGTH_ILLEGAL);
1063 PHY_ERR("OFDM-POWER-DROP ERR", ATH9K_PHYERR_OFDM_POWER_DROP);
1064 PHY_ERR("OFDM-SERVICE ERR", ATH9K_PHYERR_OFDM_SERVICE);
1065 PHY_ERR("OFDM-RESTART ERR", ATH9K_PHYERR_OFDM_RESTART);
1066 PHY_ERR("FALSE-RADAR-EXT ERR", ATH9K_PHYERR_FALSE_RADAR_EXT);
1067 PHY_ERR("CCK-TIMING ERR", ATH9K_PHYERR_CCK_TIMING);
1068 PHY_ERR("CCK-HEADER-CRC ERR", ATH9K_PHYERR_CCK_HEADER_CRC);
1069 PHY_ERR("CCK-RATE ERR", ATH9K_PHYERR_CCK_RATE_ILLEGAL);
1070 PHY_ERR("CCK-SERVICE ERR", ATH9K_PHYERR_CCK_SERVICE);
1071 PHY_ERR("CCK-RESTART ERR", ATH9K_PHYERR_CCK_RESTART);
1072 PHY_ERR("CCK-LENGTH ERR", ATH9K_PHYERR_CCK_LENGTH_ILLEGAL);
1073 PHY_ERR("CCK-POWER-DROP ERR", ATH9K_PHYERR_CCK_POWER_DROP);
1074 PHY_ERR("HT-CRC ERR", ATH9K_PHYERR_HT_CRC_ERROR);
1075 PHY_ERR("HT-LENGTH ERR", ATH9K_PHYERR_HT_LENGTH_ILLEGAL);
1076 PHY_ERR("HT-RATE ERR", ATH9K_PHYERR_HT_RATE_ILLEGAL);
1077
1078 if (len > size)
1079 len = size;
1080
1081 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
1082 kfree(buf);
1083
1084 return retval;
1085
1086#undef PHY_ERR
1087}
1088
1089static const struct file_operations fops_phy_err = {
1090 .read = read_file_phy_err,
1091 .open = simple_open,
1092 .owner = THIS_MODULE,
1093 .llseek = default_llseek,
1094};
1095
1096static ssize_t read_file_regidx(struct file *file, char __user *user_buf, 956static ssize_t read_file_regidx(struct file *file, char __user *user_buf,
1097 size_t count, loff_t *ppos) 957 size_t count, loff_t *ppos)
1098{ 958{
@@ -1268,62 +1128,6 @@ static const struct file_operations fops_dump_nfcal = {
1268 .llseek = default_llseek, 1128 .llseek = default_llseek,
1269}; 1129};
1270 1130
1271static ssize_t read_file_base_eeprom(struct file *file, char __user *user_buf,
1272 size_t count, loff_t *ppos)
1273{
1274 struct ath_softc *sc = file->private_data;
1275 struct ath_hw *ah = sc->sc_ah;
1276 u32 len = 0, size = 1500;
1277 ssize_t retval = 0;
1278 char *buf;
1279
1280 buf = kzalloc(size, GFP_KERNEL);
1281 if (!buf)
1282 return -ENOMEM;
1283
1284 len = ah->eep_ops->dump_eeprom(ah, true, buf, len, size);
1285
1286 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
1287 kfree(buf);
1288
1289 return retval;
1290}
1291
1292static const struct file_operations fops_base_eeprom = {
1293 .read = read_file_base_eeprom,
1294 .open = simple_open,
1295 .owner = THIS_MODULE,
1296 .llseek = default_llseek,
1297};
1298
1299static ssize_t read_file_modal_eeprom(struct file *file, char __user *user_buf,
1300 size_t count, loff_t *ppos)
1301{
1302 struct ath_softc *sc = file->private_data;
1303 struct ath_hw *ah = sc->sc_ah;
1304 u32 len = 0, size = 6000;
1305 char *buf;
1306 size_t retval;
1307
1308 buf = kzalloc(size, GFP_KERNEL);
1309 if (buf == NULL)
1310 return -ENOMEM;
1311
1312 len = ah->eep_ops->dump_eeprom(ah, false, buf, len, size);
1313
1314 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
1315 kfree(buf);
1316
1317 return retval;
1318}
1319
1320static const struct file_operations fops_modal_eeprom = {
1321 .read = read_file_modal_eeprom,
1322 .open = simple_open,
1323 .owner = THIS_MODULE,
1324 .llseek = default_llseek,
1325};
1326
1327#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT 1131#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
1328static ssize_t read_file_btcoex(struct file *file, char __user *user_buf, 1132static ssize_t read_file_btcoex(struct file *file, char __user *user_buf,
1329 size_t count, loff_t *ppos) 1133 size_t count, loff_t *ppos)
@@ -1524,10 +1328,10 @@ int ath9k_init_debug(struct ath_hw *ah)
1524 &fops_misc); 1328 &fops_misc);
1525 debugfs_create_file("reset", S_IRUSR, sc->debug.debugfs_phy, sc, 1329 debugfs_create_file("reset", S_IRUSR, sc->debug.debugfs_phy, sc,
1526 &fops_reset); 1330 &fops_reset);
1527 debugfs_create_file("recv", S_IRUSR, sc->debug.debugfs_phy, sc, 1331
1528 &fops_recv); 1332 ath9k_cmn_debug_recv(sc->debug.debugfs_phy, &sc->debug.stats.rxstats);
1529 debugfs_create_file("phy_err", S_IRUSR, sc->debug.debugfs_phy, sc, 1333 ath9k_cmn_debug_phy_err(sc->debug.debugfs_phy, &sc->debug.stats.rxstats);
1530 &fops_phy_err); 1334
1531 debugfs_create_u8("rx_chainmask", S_IRUSR, sc->debug.debugfs_phy, 1335 debugfs_create_u8("rx_chainmask", S_IRUSR, sc->debug.debugfs_phy,
1532 &ah->rxchainmask); 1336 &ah->rxchainmask);
1533 debugfs_create_u8("tx_chainmask", S_IRUSR, sc->debug.debugfs_phy, 1337 debugfs_create_u8("tx_chainmask", S_IRUSR, sc->debug.debugfs_phy,
@@ -1547,10 +1351,10 @@ int ath9k_init_debug(struct ath_hw *ah)
1547 &fops_regdump); 1351 &fops_regdump);
1548 debugfs_create_file("dump_nfcal", S_IRUSR, sc->debug.debugfs_phy, sc, 1352 debugfs_create_file("dump_nfcal", S_IRUSR, sc->debug.debugfs_phy, sc,
1549 &fops_dump_nfcal); 1353 &fops_dump_nfcal);
1550 debugfs_create_file("base_eeprom", S_IRUSR, sc->debug.debugfs_phy, sc, 1354
1551 &fops_base_eeprom); 1355 ath9k_cmn_debug_base_eeprom(sc->debug.debugfs_phy, sc->sc_ah);
1552 debugfs_create_file("modal_eeprom", S_IRUSR, sc->debug.debugfs_phy, sc, 1356 ath9k_cmn_debug_modal_eeprom(sc->debug.debugfs_phy, sc->sc_ah);
1553 &fops_modal_eeprom); 1357
1554 debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR, 1358 debugfs_create_u32("gpio_mask", S_IRUSR | S_IWUSR,
1555 sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask); 1359 sc->debug.debugfs_phy, &sc->sc_ah->gpio_mask);
1556 debugfs_create_u32("gpio_val", S_IRUSR | S_IWUSR, 1360 debugfs_create_u32("gpio_val", S_IRUSR | S_IWUSR,
diff --git a/drivers/net/wireless/ath/ath9k/debug.h b/drivers/net/wireless/ath/ath9k/debug.h
index 559a68c2709c..53ae15bd0c9d 100644
--- a/drivers/net/wireless/ath/ath9k/debug.h
+++ b/drivers/net/wireless/ath/ath9k/debug.h
@@ -221,50 +221,6 @@ struct ath_rx_rate_stats {
221 } cck_stats[4]; 221 } cck_stats[4];
222}; 222};
223 223
224/**
225 * struct ath_rx_stats - RX Statistics
226 * @rx_pkts_all: No. of total frames received, including ones that
227 may have had errors.
228 * @rx_bytes_all: No. of total bytes received, including ones that
229 may have had errors.
230 * @crc_err: No. of frames with incorrect CRC value
231 * @decrypt_crc_err: No. of frames whose CRC check failed after
232 decryption process completed
233 * @phy_err: No. of frames whose reception failed because the PHY
234 encountered an error
235 * @mic_err: No. of frames with incorrect TKIP MIC verification failure
236 * @pre_delim_crc_err: Pre-Frame delimiter CRC error detections
237 * @post_delim_crc_err: Post-Frame delimiter CRC error detections
238 * @decrypt_busy_err: Decryption interruptions counter
239 * @phy_err_stats: Individual PHY error statistics
240 * @rx_len_err: No. of frames discarded due to bad length.
241 * @rx_oom_err: No. of frames dropped due to OOM issues.
242 * @rx_rate_err: No. of frames dropped due to rate errors.
243 * @rx_too_many_frags_err: Frames dropped due to too-many-frags received.
244 * @rx_beacons: No. of beacons received.
245 * @rx_frags: No. of rx-fragements received.
246 * @rx_spectral: No of spectral packets received.
247 */
248struct ath_rx_stats {
249 u32 rx_pkts_all;
250 u32 rx_bytes_all;
251 u32 crc_err;
252 u32 decrypt_crc_err;
253 u32 phy_err;
254 u32 mic_err;
255 u32 pre_delim_crc_err;
256 u32 post_delim_crc_err;
257 u32 decrypt_busy_err;
258 u32 phy_err_stats[ATH9K_PHYERR_MAX];
259 u32 rx_len_err;
260 u32 rx_oom_err;
261 u32 rx_rate_err;
262 u32 rx_too_many_frags_err;
263 u32 rx_beacons;
264 u32 rx_frags;
265 u32 rx_spectral;
266};
267
268#define ANT_MAIN 0 224#define ANT_MAIN 0
269#define ANT_ALT 1 225#define ANT_ALT 1
270 226
diff --git a/drivers/net/wireless/ath/ath9k/debug_sta.c b/drivers/net/wireless/ath/ath9k/debug_sta.c
index d76e6e0120d2..ffca918ff16a 100644
--- a/drivers/net/wireless/ath/ath9k/debug_sta.c
+++ b/drivers/net/wireless/ath/ath9k/debug_sta.c
@@ -72,7 +72,7 @@ static ssize_t read_file_node_aggr(struct file *file, char __user *user_buf,
72 ath_txq_lock(sc, txq); 72 ath_txq_lock(sc, txq);
73 if (tid->active) { 73 if (tid->active) {
74 len += scnprintf(buf + len, size - len, 74 len += scnprintf(buf + len, size - len,
75 "%3d%11d%10d%10d%10d%10d%9d%6d%8d\n", 75 "%3d%11d%10d%10d%10d%10d%9d%6d\n",
76 tid->tidno, 76 tid->tidno,
77 tid->seq_start, 77 tid->seq_start,
78 tid->seq_next, 78 tid->seq_next,
@@ -80,8 +80,7 @@ static ssize_t read_file_node_aggr(struct file *file, char __user *user_buf,
80 tid->baw_head, 80 tid->baw_head,
81 tid->baw_tail, 81 tid->baw_tail,
82 tid->bar_index, 82 tid->bar_index,
83 tid->sched, 83 tid->sched);
84 tid->paused);
85 } 84 }
86 ath_txq_unlock(sc, txq); 85 ath_txq_unlock(sc, txq);
87 } 86 }
diff --git a/drivers/net/wireless/ath/ath9k/dfs.c b/drivers/net/wireless/ath/ath9k/dfs.c
index 857bb28b3894..5049bec5c676 100644
--- a/drivers/net/wireless/ath/ath9k/dfs.c
+++ b/drivers/net/wireless/ath/ath9k/dfs.c
@@ -178,12 +178,12 @@ void ath9k_dfs_process_phyerr(struct ath_softc *sc, void *data,
178 pe.ts = mactime; 178 pe.ts = mactime;
179 if (ath9k_postprocess_radar_event(sc, &ard, &pe)) { 179 if (ath9k_postprocess_radar_event(sc, &ard, &pe)) {
180 struct dfs_pattern_detector *pd = sc->dfs_detector; 180 struct dfs_pattern_detector *pd = sc->dfs_detector;
181 static u64 last_ts;
182 ath_dbg(common, DFS, 181 ath_dbg(common, DFS,
183 "ath9k_dfs_process_phyerr: channel=%d, ts=%llu, " 182 "ath9k_dfs_process_phyerr: channel=%d, ts=%llu, "
184 "width=%d, rssi=%d, delta_ts=%llu\n", 183 "width=%d, rssi=%d, delta_ts=%llu\n",
185 pe.freq, pe.ts, pe.width, pe.rssi, pe.ts-last_ts); 184 pe.freq, pe.ts, pe.width, pe.rssi,
186 last_ts = pe.ts; 185 pe.ts - sc->debug.stats.dfs_stats.last_ts);
186 sc->debug.stats.dfs_stats.last_ts = pe.ts;
187 DFS_STAT_INC(sc, pulses_processed); 187 DFS_STAT_INC(sc, pulses_processed);
188 if (pd != NULL && pd->add_pulse(pd, &pe)) { 188 if (pd != NULL && pd->add_pulse(pd, &pe)) {
189 DFS_STAT_INC(sc, radar_detected); 189 DFS_STAT_INC(sc, radar_detected);
diff --git a/drivers/net/wireless/ath/ath9k/dfs_debug.h b/drivers/net/wireless/ath/ath9k/dfs_debug.h
index 7936c9126a20..d9486867a5e0 100644
--- a/drivers/net/wireless/ath/ath9k/dfs_debug.h
+++ b/drivers/net/wireless/ath/ath9k/dfs_debug.h
@@ -51,6 +51,7 @@ struct ath_dfs_stats {
51 /* pattern detection stats */ 51 /* pattern detection stats */
52 u32 pulses_processed; 52 u32 pulses_processed;
53 u32 radar_detected; 53 u32 radar_detected;
54 u64 last_ts;
54}; 55};
55 56
56#if defined(CONFIG_ATH9K_DFS_DEBUGFS) 57#if defined(CONFIG_ATH9K_DFS_DEBUGFS)
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index dab1f0cab993..04d2f4f90e49 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -325,14 +325,14 @@ static inline struct ath9k_htc_tx_ctl *HTC_SKB_CB(struct sk_buff *skb)
325 325
326#define TX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c++) 326#define TX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c++)
327#define TX_STAT_ADD(c, a) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c += a) 327#define TX_STAT_ADD(c, a) (hif_dev->htc_handle->drv_priv->debug.tx_stats.c += a)
328#define RX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.rx_stats.c++) 328#define RX_STAT_INC(c) (hif_dev->htc_handle->drv_priv->debug.skbrx_stats.c++)
329#define RX_STAT_ADD(c, a) (hif_dev->htc_handle->drv_priv->debug.rx_stats.c += a) 329#define RX_STAT_ADD(c, a) (hif_dev->htc_handle->drv_priv->debug.skbrx_stats.c += a)
330#define CAB_STAT_INC priv->debug.tx_stats.cab_queued++ 330#define CAB_STAT_INC priv->debug.tx_stats.cab_queued++
331 331
332#define TX_QSTAT_INC(q) (priv->debug.tx_stats.queue_stats[q]++) 332#define TX_QSTAT_INC(q) (priv->debug.tx_stats.queue_stats[q]++)
333 333
334void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv, 334void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv,
335 struct ath_htc_rx_status *rxs); 335 struct ath_rx_status *rs);
336 336
337struct ath_tx_stats { 337struct ath_tx_stats {
338 u32 buf_queued; 338 u32 buf_queued;
@@ -345,25 +345,18 @@ struct ath_tx_stats {
345 u32 queue_stats[IEEE80211_NUM_ACS]; 345 u32 queue_stats[IEEE80211_NUM_ACS];
346}; 346};
347 347
348struct ath_rx_stats { 348struct ath_skbrx_stats {
349 u32 skb_allocated; 349 u32 skb_allocated;
350 u32 skb_completed; 350 u32 skb_completed;
351 u32 skb_completed_bytes; 351 u32 skb_completed_bytes;
352 u32 skb_dropped; 352 u32 skb_dropped;
353 u32 err_crc;
354 u32 err_decrypt_crc;
355 u32 err_mic;
356 u32 err_pre_delim;
357 u32 err_post_delim;
358 u32 err_decrypt_busy;
359 u32 err_phy;
360 u32 err_phy_stats[ATH9K_PHYERR_MAX];
361}; 353};
362 354
363struct ath9k_debug { 355struct ath9k_debug {
364 struct dentry *debugfs_phy; 356 struct dentry *debugfs_phy;
365 struct ath_tx_stats tx_stats; 357 struct ath_tx_stats tx_stats;
366 struct ath_rx_stats rx_stats; 358 struct ath_rx_stats rx_stats;
359 struct ath_skbrx_stats skbrx_stats;
367}; 360};
368 361
369void ath9k_htc_get_et_strings(struct ieee80211_hw *hw, 362void ath9k_htc_get_et_strings(struct ieee80211_hw *hw,
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
index fb071ee4fcfb..8b529e4b8ac4 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
@@ -243,39 +243,14 @@ static const struct file_operations fops_xmit = {
243}; 243};
244 244
245void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv, 245void ath9k_htc_err_stat_rx(struct ath9k_htc_priv *priv,
246 struct ath_htc_rx_status *rxs) 246 struct ath_rx_status *rs)
247{ 247{
248#define RX_PHY_ERR_INC(c) priv->debug.rx_stats.err_phy_stats[c]++ 248 ath9k_cmn_debug_stat_rx(&priv->debug.rx_stats, rs);
249
250 if (rxs->rs_status & ATH9K_RXERR_CRC)
251 priv->debug.rx_stats.err_crc++;
252 if (rxs->rs_status & ATH9K_RXERR_DECRYPT)
253 priv->debug.rx_stats.err_decrypt_crc++;
254 if (rxs->rs_status & ATH9K_RXERR_MIC)
255 priv->debug.rx_stats.err_mic++;
256 if (rxs->rs_status & ATH9K_RX_DELIM_CRC_PRE)
257 priv->debug.rx_stats.err_pre_delim++;
258 if (rxs->rs_status & ATH9K_RX_DELIM_CRC_POST)
259 priv->debug.rx_stats.err_post_delim++;
260 if (rxs->rs_status & ATH9K_RX_DECRYPT_BUSY)
261 priv->debug.rx_stats.err_decrypt_busy++;
262
263 if (rxs->rs_status & ATH9K_RXERR_PHY) {
264 priv->debug.rx_stats.err_phy++;
265 if (rxs->rs_phyerr < ATH9K_PHYERR_MAX)
266 RX_PHY_ERR_INC(rxs->rs_phyerr);
267 }
268
269#undef RX_PHY_ERR_INC
270} 249}
271 250
272static ssize_t read_file_recv(struct file *file, char __user *user_buf, 251static ssize_t read_file_skb_rx(struct file *file, char __user *user_buf,
273 size_t count, loff_t *ppos) 252 size_t count, loff_t *ppos)
274{ 253{
275#define PHY_ERR(s, p) \
276 len += scnprintf(buf + len, size - len, "%20s : %10u\n", s, \
277 priv->debug.rx_stats.err_phy_stats[p]);
278
279 struct ath9k_htc_priv *priv = file->private_data; 254 struct ath9k_htc_priv *priv = file->private_data;
280 char *buf; 255 char *buf;
281 unsigned int len = 0, size = 1500; 256 unsigned int len = 0, size = 1500;
@@ -287,63 +262,13 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
287 262
288 len += scnprintf(buf + len, size - len, 263 len += scnprintf(buf + len, size - len,
289 "%20s : %10u\n", "SKBs allocated", 264 "%20s : %10u\n", "SKBs allocated",
290 priv->debug.rx_stats.skb_allocated); 265 priv->debug.skbrx_stats.skb_allocated);
291 len += scnprintf(buf + len, size - len, 266 len += scnprintf(buf + len, size - len,
292 "%20s : %10u\n", "SKBs completed", 267 "%20s : %10u\n", "SKBs completed",
293 priv->debug.rx_stats.skb_completed); 268 priv->debug.skbrx_stats.skb_completed);
294 len += scnprintf(buf + len, size - len, 269 len += scnprintf(buf + len, size - len,
295 "%20s : %10u\n", "SKBs Dropped", 270 "%20s : %10u\n", "SKBs Dropped",
296 priv->debug.rx_stats.skb_dropped); 271 priv->debug.skbrx_stats.skb_dropped);
297
298 len += scnprintf(buf + len, size - len,
299 "%20s : %10u\n", "CRC ERR",
300 priv->debug.rx_stats.err_crc);
301 len += scnprintf(buf + len, size - len,
302 "%20s : %10u\n", "DECRYPT CRC ERR",
303 priv->debug.rx_stats.err_decrypt_crc);
304 len += scnprintf(buf + len, size - len,
305 "%20s : %10u\n", "MIC ERR",
306 priv->debug.rx_stats.err_mic);
307 len += scnprintf(buf + len, size - len,
308 "%20s : %10u\n", "PRE-DELIM CRC ERR",
309 priv->debug.rx_stats.err_pre_delim);
310 len += scnprintf(buf + len, size - len,
311 "%20s : %10u\n", "POST-DELIM CRC ERR",
312 priv->debug.rx_stats.err_post_delim);
313 len += scnprintf(buf + len, size - len,
314 "%20s : %10u\n", "DECRYPT BUSY ERR",
315 priv->debug.rx_stats.err_decrypt_busy);
316 len += scnprintf(buf + len, size - len,
317 "%20s : %10u\n", "TOTAL PHY ERR",
318 priv->debug.rx_stats.err_phy);
319
320
321 PHY_ERR("UNDERRUN", ATH9K_PHYERR_UNDERRUN);
322 PHY_ERR("TIMING", ATH9K_PHYERR_TIMING);
323 PHY_ERR("PARITY", ATH9K_PHYERR_PARITY);
324 PHY_ERR("RATE", ATH9K_PHYERR_RATE);
325 PHY_ERR("LENGTH", ATH9K_PHYERR_LENGTH);
326 PHY_ERR("RADAR", ATH9K_PHYERR_RADAR);
327 PHY_ERR("SERVICE", ATH9K_PHYERR_SERVICE);
328 PHY_ERR("TOR", ATH9K_PHYERR_TOR);
329 PHY_ERR("OFDM-TIMING", ATH9K_PHYERR_OFDM_TIMING);
330 PHY_ERR("OFDM-SIGNAL-PARITY", ATH9K_PHYERR_OFDM_SIGNAL_PARITY);
331 PHY_ERR("OFDM-RATE", ATH9K_PHYERR_OFDM_RATE_ILLEGAL);
332 PHY_ERR("OFDM-LENGTH", ATH9K_PHYERR_OFDM_LENGTH_ILLEGAL);
333 PHY_ERR("OFDM-POWER-DROP", ATH9K_PHYERR_OFDM_POWER_DROP);
334 PHY_ERR("OFDM-SERVICE", ATH9K_PHYERR_OFDM_SERVICE);
335 PHY_ERR("OFDM-RESTART", ATH9K_PHYERR_OFDM_RESTART);
336 PHY_ERR("FALSE-RADAR-EXT", ATH9K_PHYERR_FALSE_RADAR_EXT);
337 PHY_ERR("CCK-TIMING", ATH9K_PHYERR_CCK_TIMING);
338 PHY_ERR("CCK-HEADER-CRC", ATH9K_PHYERR_CCK_HEADER_CRC);
339 PHY_ERR("CCK-RATE", ATH9K_PHYERR_CCK_RATE_ILLEGAL);
340 PHY_ERR("CCK-SERVICE", ATH9K_PHYERR_CCK_SERVICE);
341 PHY_ERR("CCK-RESTART", ATH9K_PHYERR_CCK_RESTART);
342 PHY_ERR("CCK-LENGTH", ATH9K_PHYERR_CCK_LENGTH_ILLEGAL);
343 PHY_ERR("CCK-POWER-DROP", ATH9K_PHYERR_CCK_POWER_DROP);
344 PHY_ERR("HT-CRC", ATH9K_PHYERR_HT_CRC_ERROR);
345 PHY_ERR("HT-LENGTH", ATH9K_PHYERR_HT_LENGTH_ILLEGAL);
346 PHY_ERR("HT-RATE", ATH9K_PHYERR_HT_RATE_ILLEGAL);
347 272
348 if (len > size) 273 if (len > size)
349 len = size; 274 len = size;
@@ -352,12 +277,10 @@ static ssize_t read_file_recv(struct file *file, char __user *user_buf,
352 kfree(buf); 277 kfree(buf);
353 278
354 return retval; 279 return retval;
355
356#undef PHY_ERR
357} 280}
358 281
359static const struct file_operations fops_recv = { 282static const struct file_operations fops_skb_rx = {
360 .read = read_file_recv, 283 .read = read_file_skb_rx,
361 .open = simple_open, 284 .open = simple_open,
362 .owner = THIS_MODULE, 285 .owner = THIS_MODULE,
363 .llseek = default_llseek, 286 .llseek = default_llseek,
@@ -486,423 +409,6 @@ static const struct file_operations fops_debug = {
486 .llseek = default_llseek, 409 .llseek = default_llseek,
487}; 410};
488 411
489static ssize_t read_file_base_eeprom(struct file *file, char __user *user_buf,
490 size_t count, loff_t *ppos)
491{
492 struct ath9k_htc_priv *priv = file->private_data;
493 struct ath_common *common = ath9k_hw_common(priv->ah);
494 struct base_eep_header *pBase = NULL;
495 unsigned int len = 0, size = 1500;
496 ssize_t retval = 0;
497 char *buf;
498
499 pBase = ath9k_htc_get_eeprom_base(priv);
500
501 if (pBase == NULL) {
502 ath_err(common, "Unknown EEPROM type\n");
503 return 0;
504 }
505
506 buf = kzalloc(size, GFP_KERNEL);
507 if (buf == NULL)
508 return -ENOMEM;
509
510 len += scnprintf(buf + len, size - len,
511 "%20s : %10d\n", "Major Version",
512 pBase->version >> 12);
513 len += scnprintf(buf + len, size - len,
514 "%20s : %10d\n", "Minor Version",
515 pBase->version & 0xFFF);
516 len += scnprintf(buf + len, size - len,
517 "%20s : %10d\n", "Checksum",
518 pBase->checksum);
519 len += scnprintf(buf + len, size - len,
520 "%20s : %10d\n", "Length",
521 pBase->length);
522 len += scnprintf(buf + len, size - len,
523 "%20s : %10d\n", "RegDomain1",
524 pBase->regDmn[0]);
525 len += scnprintf(buf + len, size - len,
526 "%20s : %10d\n", "RegDomain2",
527 pBase->regDmn[1]);
528 len += scnprintf(buf + len, size - len,
529 "%20s : %10d\n",
530 "TX Mask", pBase->txMask);
531 len += scnprintf(buf + len, size - len,
532 "%20s : %10d\n",
533 "RX Mask", pBase->rxMask);
534 len += scnprintf(buf + len, size - len,
535 "%20s : %10d\n",
536 "Allow 5GHz",
537 !!(pBase->opCapFlags & AR5416_OPFLAGS_11A));
538 len += scnprintf(buf + len, size - len,
539 "%20s : %10d\n",
540 "Allow 2GHz",
541 !!(pBase->opCapFlags & AR5416_OPFLAGS_11G));
542 len += scnprintf(buf + len, size - len,
543 "%20s : %10d\n",
544 "Disable 2GHz HT20",
545 !!(pBase->opCapFlags & AR5416_OPFLAGS_N_2G_HT20));
546 len += scnprintf(buf + len, size - len,
547 "%20s : %10d\n",
548 "Disable 2GHz HT40",
549 !!(pBase->opCapFlags & AR5416_OPFLAGS_N_2G_HT40));
550 len += scnprintf(buf + len, size - len,
551 "%20s : %10d\n",
552 "Disable 5Ghz HT20",
553 !!(pBase->opCapFlags & AR5416_OPFLAGS_N_5G_HT20));
554 len += scnprintf(buf + len, size - len,
555 "%20s : %10d\n",
556 "Disable 5Ghz HT40",
557 !!(pBase->opCapFlags & AR5416_OPFLAGS_N_5G_HT40));
558 len += scnprintf(buf + len, size - len,
559 "%20s : %10d\n",
560 "Big Endian",
561 !!(pBase->eepMisc & 0x01));
562 len += scnprintf(buf + len, size - len,
563 "%20s : %10d\n",
564 "Cal Bin Major Ver",
565 (pBase->binBuildNumber >> 24) & 0xFF);
566 len += scnprintf(buf + len, size - len,
567 "%20s : %10d\n",
568 "Cal Bin Minor Ver",
569 (pBase->binBuildNumber >> 16) & 0xFF);
570 len += scnprintf(buf + len, size - len,
571 "%20s : %10d\n",
572 "Cal Bin Build",
573 (pBase->binBuildNumber >> 8) & 0xFF);
574
575 /*
576 * UB91 specific data.
577 */
578 if (AR_SREV_9271(priv->ah)) {
579 struct base_eep_header_4k *pBase4k =
580 &priv->ah->eeprom.map4k.baseEepHeader;
581
582 len += scnprintf(buf + len, size - len,
583 "%20s : %10d\n",
584 "TX Gain type",
585 pBase4k->txGainType);
586 }
587
588 /*
589 * UB95 specific data.
590 */
591 if (priv->ah->hw_version.usbdev == AR9287_USB) {
592 struct base_eep_ar9287_header *pBase9287 =
593 &priv->ah->eeprom.map9287.baseEepHeader;
594
595 len += scnprintf(buf + len, size - len,
596 "%20s : %10ddB\n",
597 "Power Table Offset",
598 pBase9287->pwrTableOffset);
599
600 len += scnprintf(buf + len, size - len,
601 "%20s : %10d\n",
602 "OpenLoop Power Ctrl",
603 pBase9287->openLoopPwrCntl);
604 }
605
606 len += scnprintf(buf + len, size - len, "%20s : %pM\n", "MacAddress",
607 pBase->macAddr);
608 if (len > size)
609 len = size;
610
611 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
612 kfree(buf);
613
614 return retval;
615}
616
617static const struct file_operations fops_base_eeprom = {
618 .read = read_file_base_eeprom,
619 .open = simple_open,
620 .owner = THIS_MODULE,
621 .llseek = default_llseek,
622};
623
624static ssize_t read_4k_modal_eeprom(struct file *file,
625 char __user *user_buf,
626 size_t count, loff_t *ppos)
627{
628#define PR_EEP(_s, _val) \
629 do { \
630 len += scnprintf(buf + len, size - len, "%20s : %10d\n",\
631 _s, (_val)); \
632 } while (0)
633
634 struct ath9k_htc_priv *priv = file->private_data;
635 struct modal_eep_4k_header *pModal = &priv->ah->eeprom.map4k.modalHeader;
636 unsigned int len = 0, size = 2048;
637 ssize_t retval = 0;
638 char *buf;
639
640 buf = kzalloc(size, GFP_KERNEL);
641 if (buf == NULL)
642 return -ENOMEM;
643
644 PR_EEP("Chain0 Ant. Control", pModal->antCtrlChain[0]);
645 PR_EEP("Ant. Common Control", pModal->antCtrlCommon);
646 PR_EEP("Chain0 Ant. Gain", pModal->antennaGainCh[0]);
647 PR_EEP("Switch Settle", pModal->switchSettling);
648 PR_EEP("Chain0 TxRxAtten", pModal->txRxAttenCh[0]);
649 PR_EEP("Chain0 RxTxMargin", pModal->rxTxMarginCh[0]);
650 PR_EEP("ADC Desired size", pModal->adcDesiredSize);
651 PR_EEP("PGA Desired size", pModal->pgaDesiredSize);
652 PR_EEP("Chain0 xlna Gain", pModal->xlnaGainCh[0]);
653 PR_EEP("txEndToXpaOff", pModal->txEndToXpaOff);
654 PR_EEP("txEndToRxOn", pModal->txEndToRxOn);
655 PR_EEP("txFrameToXpaOn", pModal->txFrameToXpaOn);
656 PR_EEP("CCA Threshold)", pModal->thresh62);
657 PR_EEP("Chain0 NF Threshold", pModal->noiseFloorThreshCh[0]);
658 PR_EEP("xpdGain", pModal->xpdGain);
659 PR_EEP("External PD", pModal->xpd);
660 PR_EEP("Chain0 I Coefficient", pModal->iqCalICh[0]);
661 PR_EEP("Chain0 Q Coefficient", pModal->iqCalQCh[0]);
662 PR_EEP("pdGainOverlap", pModal->pdGainOverlap);
663 PR_EEP("O/D Bias Version", pModal->version);
664 PR_EEP("CCK OutputBias", pModal->ob_0);
665 PR_EEP("BPSK OutputBias", pModal->ob_1);
666 PR_EEP("QPSK OutputBias", pModal->ob_2);
667 PR_EEP("16QAM OutputBias", pModal->ob_3);
668 PR_EEP("64QAM OutputBias", pModal->ob_4);
669 PR_EEP("CCK Driver1_Bias", pModal->db1_0);
670 PR_EEP("BPSK Driver1_Bias", pModal->db1_1);
671 PR_EEP("QPSK Driver1_Bias", pModal->db1_2);
672 PR_EEP("16QAM Driver1_Bias", pModal->db1_3);
673 PR_EEP("64QAM Driver1_Bias", pModal->db1_4);
674 PR_EEP("CCK Driver2_Bias", pModal->db2_0);
675 PR_EEP("BPSK Driver2_Bias", pModal->db2_1);
676 PR_EEP("QPSK Driver2_Bias", pModal->db2_2);
677 PR_EEP("16QAM Driver2_Bias", pModal->db2_3);
678 PR_EEP("64QAM Driver2_Bias", pModal->db2_4);
679 PR_EEP("xPA Bias Level", pModal->xpaBiasLvl);
680 PR_EEP("txFrameToDataStart", pModal->txFrameToDataStart);
681 PR_EEP("txFrameToPaOn", pModal->txFrameToPaOn);
682 PR_EEP("HT40 Power Inc.", pModal->ht40PowerIncForPdadc);
683 PR_EEP("Chain0 bswAtten", pModal->bswAtten[0]);
684 PR_EEP("Chain0 bswMargin", pModal->bswMargin[0]);
685 PR_EEP("HT40 Switch Settle", pModal->swSettleHt40);
686 PR_EEP("Chain0 xatten2Db", pModal->xatten2Db[0]);
687 PR_EEP("Chain0 xatten2Margin", pModal->xatten2Margin[0]);
688 PR_EEP("Ant. Diversity ctl1", pModal->antdiv_ctl1);
689 PR_EEP("Ant. Diversity ctl2", pModal->antdiv_ctl2);
690 PR_EEP("TX Diversity", pModal->tx_diversity);
691
692 if (len > size)
693 len = size;
694
695 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
696 kfree(buf);
697
698 return retval;
699
700#undef PR_EEP
701}
702
703static ssize_t read_def_modal_eeprom(struct file *file,
704 char __user *user_buf,
705 size_t count, loff_t *ppos)
706{
707#define PR_EEP(_s, _val) \
708 do { \
709 if (pBase->opCapFlags & AR5416_OPFLAGS_11G) { \
710 pModal = &priv->ah->eeprom.def.modalHeader[1]; \
711 len += scnprintf(buf + len, size - len, "%20s : %8d%7s", \
712 _s, (_val), "|"); \
713 } \
714 if (pBase->opCapFlags & AR5416_OPFLAGS_11A) { \
715 pModal = &priv->ah->eeprom.def.modalHeader[0]; \
716 len += scnprintf(buf + len, size - len, "%9d\n",\
717 (_val)); \
718 } \
719 } while (0)
720
721 struct ath9k_htc_priv *priv = file->private_data;
722 struct base_eep_header *pBase = &priv->ah->eeprom.def.baseEepHeader;
723 struct modal_eep_header *pModal = NULL;
724 unsigned int len = 0, size = 3500;
725 ssize_t retval = 0;
726 char *buf;
727
728 buf = kzalloc(size, GFP_KERNEL);
729 if (buf == NULL)
730 return -ENOMEM;
731
732 len += scnprintf(buf + len, size - len,
733 "%31s %15s\n", "2G", "5G");
734 len += scnprintf(buf + len, size - len,
735 "%32s %16s\n", "====", "====\n");
736
737 PR_EEP("Chain0 Ant. Control", pModal->antCtrlChain[0]);
738 PR_EEP("Chain1 Ant. Control", pModal->antCtrlChain[1]);
739 PR_EEP("Chain2 Ant. Control", pModal->antCtrlChain[2]);
740 PR_EEP("Ant. Common Control", pModal->antCtrlCommon);
741 PR_EEP("Chain0 Ant. Gain", pModal->antennaGainCh[0]);
742 PR_EEP("Chain1 Ant. Gain", pModal->antennaGainCh[1]);
743 PR_EEP("Chain2 Ant. Gain", pModal->antennaGainCh[2]);
744 PR_EEP("Switch Settle", pModal->switchSettling);
745 PR_EEP("Chain0 TxRxAtten", pModal->txRxAttenCh[0]);
746 PR_EEP("Chain1 TxRxAtten", pModal->txRxAttenCh[1]);
747 PR_EEP("Chain2 TxRxAtten", pModal->txRxAttenCh[2]);
748 PR_EEP("Chain0 RxTxMargin", pModal->rxTxMarginCh[0]);
749 PR_EEP("Chain1 RxTxMargin", pModal->rxTxMarginCh[1]);
750 PR_EEP("Chain2 RxTxMargin", pModal->rxTxMarginCh[2]);
751 PR_EEP("ADC Desired size", pModal->adcDesiredSize);
752 PR_EEP("PGA Desired size", pModal->pgaDesiredSize);
753 PR_EEP("Chain0 xlna Gain", pModal->xlnaGainCh[0]);
754 PR_EEP("Chain1 xlna Gain", pModal->xlnaGainCh[1]);
755 PR_EEP("Chain2 xlna Gain", pModal->xlnaGainCh[2]);
756 PR_EEP("txEndToXpaOff", pModal->txEndToXpaOff);
757 PR_EEP("txEndToRxOn", pModal->txEndToRxOn);
758 PR_EEP("txFrameToXpaOn", pModal->txFrameToXpaOn);
759 PR_EEP("CCA Threshold)", pModal->thresh62);
760 PR_EEP("Chain0 NF Threshold", pModal->noiseFloorThreshCh[0]);
761 PR_EEP("Chain1 NF Threshold", pModal->noiseFloorThreshCh[1]);
762 PR_EEP("Chain2 NF Threshold", pModal->noiseFloorThreshCh[2]);
763 PR_EEP("xpdGain", pModal->xpdGain);
764 PR_EEP("External PD", pModal->xpd);
765 PR_EEP("Chain0 I Coefficient", pModal->iqCalICh[0]);
766 PR_EEP("Chain1 I Coefficient", pModal->iqCalICh[1]);
767 PR_EEP("Chain2 I Coefficient", pModal->iqCalICh[2]);
768 PR_EEP("Chain0 Q Coefficient", pModal->iqCalQCh[0]);
769 PR_EEP("Chain1 Q Coefficient", pModal->iqCalQCh[1]);
770 PR_EEP("Chain2 Q Coefficient", pModal->iqCalQCh[2]);
771 PR_EEP("pdGainOverlap", pModal->pdGainOverlap);
772 PR_EEP("Chain0 OutputBias", pModal->ob);
773 PR_EEP("Chain0 DriverBias", pModal->db);
774 PR_EEP("xPA Bias Level", pModal->xpaBiasLvl);
775 PR_EEP("2chain pwr decrease", pModal->pwrDecreaseFor2Chain);
776 PR_EEP("3chain pwr decrease", pModal->pwrDecreaseFor3Chain);
777 PR_EEP("txFrameToDataStart", pModal->txFrameToDataStart);
778 PR_EEP("txFrameToPaOn", pModal->txFrameToPaOn);
779 PR_EEP("HT40 Power Inc.", pModal->ht40PowerIncForPdadc);
780 PR_EEP("Chain0 bswAtten", pModal->bswAtten[0]);
781 PR_EEP("Chain1 bswAtten", pModal->bswAtten[1]);
782 PR_EEP("Chain2 bswAtten", pModal->bswAtten[2]);
783 PR_EEP("Chain0 bswMargin", pModal->bswMargin[0]);
784 PR_EEP("Chain1 bswMargin", pModal->bswMargin[1]);
785 PR_EEP("Chain2 bswMargin", pModal->bswMargin[2]);
786 PR_EEP("HT40 Switch Settle", pModal->swSettleHt40);
787 PR_EEP("Chain0 xatten2Db", pModal->xatten2Db[0]);
788 PR_EEP("Chain1 xatten2Db", pModal->xatten2Db[1]);
789 PR_EEP("Chain2 xatten2Db", pModal->xatten2Db[2]);
790 PR_EEP("Chain0 xatten2Margin", pModal->xatten2Margin[0]);
791 PR_EEP("Chain1 xatten2Margin", pModal->xatten2Margin[1]);
792 PR_EEP("Chain2 xatten2Margin", pModal->xatten2Margin[2]);
793 PR_EEP("Chain1 OutputBias", pModal->ob_ch1);
794 PR_EEP("Chain1 DriverBias", pModal->db_ch1);
795 PR_EEP("LNA Control", pModal->lna_ctl);
796 PR_EEP("XPA Bias Freq0", pModal->xpaBiasLvlFreq[0]);
797 PR_EEP("XPA Bias Freq1", pModal->xpaBiasLvlFreq[1]);
798 PR_EEP("XPA Bias Freq2", pModal->xpaBiasLvlFreq[2]);
799
800 if (len > size)
801 len = size;
802
803 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
804 kfree(buf);
805
806 return retval;
807
808#undef PR_EEP
809}
810
811static ssize_t read_9287_modal_eeprom(struct file *file,
812 char __user *user_buf,
813 size_t count, loff_t *ppos)
814{
815#define PR_EEP(_s, _val) \
816 do { \
817 len += scnprintf(buf + len, size - len, "%20s : %10d\n",\
818 _s, (_val)); \
819 } while (0)
820
821 struct ath9k_htc_priv *priv = file->private_data;
822 struct modal_eep_ar9287_header *pModal = &priv->ah->eeprom.map9287.modalHeader;
823 unsigned int len = 0, size = 3000;
824 ssize_t retval = 0;
825 char *buf;
826
827 buf = kzalloc(size, GFP_KERNEL);
828 if (buf == NULL)
829 return -ENOMEM;
830
831 PR_EEP("Chain0 Ant. Control", pModal->antCtrlChain[0]);
832 PR_EEP("Chain1 Ant. Control", pModal->antCtrlChain[1]);
833 PR_EEP("Ant. Common Control", pModal->antCtrlCommon);
834 PR_EEP("Chain0 Ant. Gain", pModal->antennaGainCh[0]);
835 PR_EEP("Chain1 Ant. Gain", pModal->antennaGainCh[1]);
836 PR_EEP("Switch Settle", pModal->switchSettling);
837 PR_EEP("Chain0 TxRxAtten", pModal->txRxAttenCh[0]);
838 PR_EEP("Chain1 TxRxAtten", pModal->txRxAttenCh[1]);
839 PR_EEP("Chain0 RxTxMargin", pModal->rxTxMarginCh[0]);
840 PR_EEP("Chain1 RxTxMargin", pModal->rxTxMarginCh[1]);
841 PR_EEP("ADC Desired size", pModal->adcDesiredSize);
842 PR_EEP("txEndToXpaOff", pModal->txEndToXpaOff);
843 PR_EEP("txEndToRxOn", pModal->txEndToRxOn);
844 PR_EEP("txFrameToXpaOn", pModal->txFrameToXpaOn);
845 PR_EEP("CCA Threshold)", pModal->thresh62);
846 PR_EEP("Chain0 NF Threshold", pModal->noiseFloorThreshCh[0]);
847 PR_EEP("Chain1 NF Threshold", pModal->noiseFloorThreshCh[1]);
848 PR_EEP("xpdGain", pModal->xpdGain);
849 PR_EEP("External PD", pModal->xpd);
850 PR_EEP("Chain0 I Coefficient", pModal->iqCalICh[0]);
851 PR_EEP("Chain1 I Coefficient", pModal->iqCalICh[1]);
852 PR_EEP("Chain0 Q Coefficient", pModal->iqCalQCh[0]);
853 PR_EEP("Chain1 Q Coefficient", pModal->iqCalQCh[1]);
854 PR_EEP("pdGainOverlap", pModal->pdGainOverlap);
855 PR_EEP("xPA Bias Level", pModal->xpaBiasLvl);
856 PR_EEP("txFrameToDataStart", pModal->txFrameToDataStart);
857 PR_EEP("txFrameToPaOn", pModal->txFrameToPaOn);
858 PR_EEP("HT40 Power Inc.", pModal->ht40PowerIncForPdadc);
859 PR_EEP("Chain0 bswAtten", pModal->bswAtten[0]);
860 PR_EEP("Chain1 bswAtten", pModal->bswAtten[1]);
861 PR_EEP("Chain0 bswMargin", pModal->bswMargin[0]);
862 PR_EEP("Chain1 bswMargin", pModal->bswMargin[1]);
863 PR_EEP("HT40 Switch Settle", pModal->swSettleHt40);
864 PR_EEP("AR92x7 Version", pModal->version);
865 PR_EEP("DriverBias1", pModal->db1);
866 PR_EEP("DriverBias2", pModal->db1);
867 PR_EEP("CCK OutputBias", pModal->ob_cck);
868 PR_EEP("PSK OutputBias", pModal->ob_psk);
869 PR_EEP("QAM OutputBias", pModal->ob_qam);
870 PR_EEP("PAL_OFF OutputBias", pModal->ob_pal_off);
871
872 if (len > size)
873 len = size;
874
875 retval = simple_read_from_buffer(user_buf, count, ppos, buf, len);
876 kfree(buf);
877
878 return retval;
879
880#undef PR_EEP
881}
882
883static ssize_t read_file_modal_eeprom(struct file *file, char __user *user_buf,
884 size_t count, loff_t *ppos)
885{
886 struct ath9k_htc_priv *priv = file->private_data;
887
888 if (AR_SREV_9271(priv->ah))
889 return read_4k_modal_eeprom(file, user_buf, count, ppos);
890 else if (priv->ah->hw_version.usbdev == AR9280_USB)
891 return read_def_modal_eeprom(file, user_buf, count, ppos);
892 else if (priv->ah->hw_version.usbdev == AR9287_USB)
893 return read_9287_modal_eeprom(file, user_buf, count, ppos);
894
895 return 0;
896}
897
898static const struct file_operations fops_modal_eeprom = {
899 .read = read_file_modal_eeprom,
900 .open = simple_open,
901 .owner = THIS_MODULE,
902 .llseek = default_llseek,
903};
904
905
906/* Ethtool support for get-stats */ 412/* Ethtool support for get-stats */
907#define AMKSTR(nm) #nm "_BE", #nm "_BK", #nm "_VI", #nm "_VO" 413#define AMKSTR(nm) #nm "_BE", #nm "_BK", #nm "_VI", #nm "_VO"
908static const char ath9k_htc_gstrings_stats[][ETH_GSTRING_LEN] = { 414static const char ath9k_htc_gstrings_stats[][ETH_GSTRING_LEN] = {
@@ -947,6 +453,8 @@ int ath9k_htc_get_et_sset_count(struct ieee80211_hw *hw,
947 453
948#define STXBASE priv->debug.tx_stats 454#define STXBASE priv->debug.tx_stats
949#define SRXBASE priv->debug.rx_stats 455#define SRXBASE priv->debug.rx_stats
456#define SKBTXBASE priv->debug.tx_stats
457#define SKBRXBASE priv->debug.skbrx_stats
950#define ASTXQ(a) \ 458#define ASTXQ(a) \
951 data[i++] = STXBASE.a[IEEE80211_AC_BE]; \ 459 data[i++] = STXBASE.a[IEEE80211_AC_BE]; \
952 data[i++] = STXBASE.a[IEEE80211_AC_BK]; \ 460 data[i++] = STXBASE.a[IEEE80211_AC_BK]; \
@@ -960,24 +468,24 @@ void ath9k_htc_get_et_stats(struct ieee80211_hw *hw,
960 struct ath9k_htc_priv *priv = hw->priv; 468 struct ath9k_htc_priv *priv = hw->priv;
961 int i = 0; 469 int i = 0;
962 470
963 data[i++] = STXBASE.skb_success; 471 data[i++] = SKBTXBASE.skb_success;
964 data[i++] = STXBASE.skb_success_bytes; 472 data[i++] = SKBTXBASE.skb_success_bytes;
965 data[i++] = SRXBASE.skb_completed; 473 data[i++] = SKBRXBASE.skb_completed;
966 data[i++] = SRXBASE.skb_completed_bytes; 474 data[i++] = SKBRXBASE.skb_completed_bytes;
967 475
968 ASTXQ(queue_stats); 476 ASTXQ(queue_stats);
969 477
970 data[i++] = SRXBASE.err_crc; 478 data[i++] = SRXBASE.crc_err;
971 data[i++] = SRXBASE.err_decrypt_crc; 479 data[i++] = SRXBASE.decrypt_crc_err;
972 data[i++] = SRXBASE.err_phy; 480 data[i++] = SRXBASE.phy_err;
973 data[i++] = SRXBASE.err_mic; 481 data[i++] = SRXBASE.mic_err;
974 data[i++] = SRXBASE.err_pre_delim; 482 data[i++] = SRXBASE.pre_delim_crc_err;
975 data[i++] = SRXBASE.err_post_delim; 483 data[i++] = SRXBASE.post_delim_crc_err;
976 data[i++] = SRXBASE.err_decrypt_busy; 484 data[i++] = SRXBASE.decrypt_busy_err;
977 485
978 data[i++] = SRXBASE.err_phy_stats[ATH9K_PHYERR_RADAR]; 486 data[i++] = SRXBASE.phy_err_stats[ATH9K_PHYERR_RADAR];
979 data[i++] = SRXBASE.err_phy_stats[ATH9K_PHYERR_OFDM_TIMING]; 487 data[i++] = SRXBASE.phy_err_stats[ATH9K_PHYERR_OFDM_TIMING];
980 data[i++] = SRXBASE.err_phy_stats[ATH9K_PHYERR_CCK_TIMING]; 488 data[i++] = SRXBASE.phy_err_stats[ATH9K_PHYERR_CCK_TIMING];
981 489
982 WARN_ON(i != ATH9K_HTC_SSTATS_LEN); 490 WARN_ON(i != ATH9K_HTC_SSTATS_LEN);
983} 491}
@@ -1001,18 +509,21 @@ int ath9k_htc_init_debug(struct ath_hw *ah)
1001 priv, &fops_tgt_rx_stats); 509 priv, &fops_tgt_rx_stats);
1002 debugfs_create_file("xmit", S_IRUSR, priv->debug.debugfs_phy, 510 debugfs_create_file("xmit", S_IRUSR, priv->debug.debugfs_phy,
1003 priv, &fops_xmit); 511 priv, &fops_xmit);
1004 debugfs_create_file("recv", S_IRUSR, priv->debug.debugfs_phy, 512 debugfs_create_file("skb_rx", S_IRUSR, priv->debug.debugfs_phy,
1005 priv, &fops_recv); 513 priv, &fops_skb_rx);
514
515 ath9k_cmn_debug_recv(priv->debug.debugfs_phy, &priv->debug.rx_stats);
516 ath9k_cmn_debug_phy_err(priv->debug.debugfs_phy, &priv->debug.rx_stats);
517
1006 debugfs_create_file("slot", S_IRUSR, priv->debug.debugfs_phy, 518 debugfs_create_file("slot", S_IRUSR, priv->debug.debugfs_phy,
1007 priv, &fops_slot); 519 priv, &fops_slot);
1008 debugfs_create_file("queue", S_IRUSR, priv->debug.debugfs_phy, 520 debugfs_create_file("queue", S_IRUSR, priv->debug.debugfs_phy,
1009 priv, &fops_queue); 521 priv, &fops_queue);
1010 debugfs_create_file("debug", S_IRUSR | S_IWUSR, priv->debug.debugfs_phy, 522 debugfs_create_file("debug", S_IRUSR | S_IWUSR, priv->debug.debugfs_phy,
1011 priv, &fops_debug); 523 priv, &fops_debug);
1012 debugfs_create_file("base_eeprom", S_IRUSR, priv->debug.debugfs_phy, 524
1013 priv, &fops_base_eeprom); 525 ath9k_cmn_debug_base_eeprom(priv->debug.debugfs_phy, priv->ah);
1014 debugfs_create_file("modal_eeprom", S_IRUSR, priv->debug.debugfs_phy, 526 ath9k_cmn_debug_modal_eeprom(priv->debug.debugfs_phy, priv->ah);
1015 priv, &fops_modal_eeprom);
1016 527
1017 return 0; 528 return 0;
1018} 529}
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
index 289f3d8924b5..bb86eb2ffc95 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c
@@ -996,8 +996,6 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv,
996 goto rx_next; 996 goto rx_next;
997 } 997 }
998 998
999 ath9k_htc_err_stat_rx(priv, rxstatus);
1000
1001 /* Get the RX status information */ 999 /* Get the RX status information */
1002 1000
1003 memset(rx_status, 0, sizeof(struct ieee80211_rx_status)); 1001 memset(rx_status, 0, sizeof(struct ieee80211_rx_status));
@@ -1005,6 +1003,7 @@ static bool ath9k_rx_prepare(struct ath9k_htc_priv *priv,
1005 /* Copy everything from ath_htc_rx_status (HTC_RX_FRAME_HEADER). 1003 /* Copy everything from ath_htc_rx_status (HTC_RX_FRAME_HEADER).
1006 * After this, we can drop this part of skb. */ 1004 * After this, we can drop this part of skb. */
1007 rx_status_htc_to_ath(&rx_stats, rxstatus); 1005 rx_status_htc_to_ath(&rx_stats, rxstatus);
1006 ath9k_htc_err_stat_rx(priv, &rx_stats);
1008 rx_status->mactime = be64_to_cpu(rxstatus->rs_tstamp); 1007 rx_status->mactime = be64_to_cpu(rxstatus->rs_tstamp);
1009 skb_pull(skb, HTC_RX_FRAME_HEADER_SIZE); 1008 skb_pull(skb, HTC_RX_FRAME_HEADER_SIZE);
1010 1009
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index c8a9dfab1fee..2a8ed8375ec0 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -26,7 +26,6 @@
26#include "ar9003_mac.h" 26#include "ar9003_mac.h"
27#include "ar9003_mci.h" 27#include "ar9003_mci.h"
28#include "ar9003_phy.h" 28#include "ar9003_phy.h"
29#include "debug.h"
30#include "ath9k.h" 29#include "ath9k.h"
31 30
32static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type); 31static bool ath9k_hw_set_reset_reg(struct ath_hw *ah, u32 type);
@@ -246,6 +245,8 @@ static void ath9k_hw_read_revisions(struct ath_hw *ah)
246 return; 245 return;
247 case AR9300_DEVID_AR953X: 246 case AR9300_DEVID_AR953X:
248 ah->hw_version.macVersion = AR_SREV_VERSION_9531; 247 ah->hw_version.macVersion = AR_SREV_VERSION_9531;
248 if (ah->get_mac_revision)
249 ah->hw_version.macRev = ah->get_mac_revision();
249 return; 250 return;
250 } 251 }
251 252
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 21e174cfc909..1af77081181e 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -508,7 +508,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
508 sc->tx99_power = MAX_RATE_POWER + 1; 508 sc->tx99_power = MAX_RATE_POWER + 1;
509 init_waitqueue_head(&sc->tx_wait); 509 init_waitqueue_head(&sc->tx_wait);
510 510
511 if (!pdata) { 511 if (!pdata || pdata->use_eeprom) {
512 ah->ah_flags |= AH_USE_EEPROM; 512 ah->ah_flags |= AH_USE_EEPROM;
513 sc->sc_ah->led_pin = -1; 513 sc->sc_ah->led_pin = -1;
514 } else { 514 } else {
@@ -714,7 +714,8 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
714 if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || ath9k_modparam_nohwcrypt) 714 if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || ath9k_modparam_nohwcrypt)
715 hw->flags |= IEEE80211_HW_MFP_CAPABLE; 715 hw->flags |= IEEE80211_HW_MFP_CAPABLE;
716 716
717 hw->wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR; 717 hw->wiphy->features |= (NL80211_FEATURE_ACTIVE_MONITOR |
718 NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE);
718 719
719 if (!config_enabled(CONFIG_ATH9K_TX99)) { 720 if (!config_enabled(CONFIG_ATH9K_TX99)) {
720 hw->wiphy->interface_modes = 721 hw->wiphy->interface_modes =
@@ -786,6 +787,9 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc,
786 common = ath9k_hw_common(ah); 787 common = ath9k_hw_common(ah);
787 ath9k_set_hw_capab(sc, hw); 788 ath9k_set_hw_capab(sc, hw);
788 789
790 /* Will be cleared in ath9k_start() */
791 set_bit(ATH_OP_INVALID, &common->op_flags);
792
789 /* Initialize regulatory */ 793 /* Initialize regulatory */
790 error = ath_regd_init(&common->regulatory, sc->hw->wiphy, 794 error = ath_regd_init(&common->regulatory, sc->hw->wiphy,
791 ath9k_reg_notifier); 795 ath9k_reg_notifier);
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 22c9e5471f9c..8d7b9b66fefa 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -1989,7 +1989,8 @@ static bool ath9k_has_tx_pending(struct ath_softc *sc)
1989 return !!npend; 1989 return !!npend;
1990} 1990}
1991 1991
1992static void ath9k_flush(struct ieee80211_hw *hw, u32 queues, bool drop) 1992static void ath9k_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1993 u32 queues, bool drop)
1993{ 1994{
1994 struct ath_softc *sc = hw->priv; 1995 struct ath_softc *sc = hw->priv;
1995 struct ath_hw *ah = sc->sc_ah; 1996 struct ath_hw *ah = sc->sc_ah;
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index 25304adece57..c1e82f779544 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -686,7 +686,7 @@ static bool ath_pci_eeprom_read(struct ath_common *common, u32 off, u16 *data)
686 struct ath_softc *sc = (struct ath_softc *) common->priv; 686 struct ath_softc *sc = (struct ath_softc *) common->priv;
687 struct ath9k_platform_data *pdata = sc->dev->platform_data; 687 struct ath9k_platform_data *pdata = sc->dev->platform_data;
688 688
689 if (pdata) { 689 if (pdata && !pdata->use_eeprom) {
690 if (off >= (ARRAY_SIZE(pdata->eeprom_data))) { 690 if (off >= (ARRAY_SIZE(pdata->eeprom_data))) {
691 ath_err(common, 691 ath_err(common,
692 "%s: eeprom read failed, offset %08x is out of range\n", 692 "%s: eeprom read failed, offset %08x is out of range\n",
@@ -784,7 +784,6 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
784{ 784{
785 struct ath_softc *sc; 785 struct ath_softc *sc;
786 struct ieee80211_hw *hw; 786 struct ieee80211_hw *hw;
787 struct ath_common *common;
788 u8 csz; 787 u8 csz;
789 u32 val; 788 u32 val;
790 int ret = 0; 789 int ret = 0;
@@ -877,10 +876,6 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
877 wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n", 876 wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n",
878 hw_name, (unsigned long)sc->mem, pdev->irq); 877 hw_name, (unsigned long)sc->mem, pdev->irq);
879 878
880 /* Will be cleared in ath9k_start() */
881 common = ath9k_hw_common(sc->sc_ah);
882 set_bit(ATH_OP_INVALID, &common->op_flags);
883
884 return 0; 879 return 0;
885 880
886err_init: 881err_init:
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index a01efd3e741e..43ae199601f7 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -538,8 +538,8 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
538 sc->ps_flags &= ~PS_BEACON_SYNC; 538 sc->ps_flags &= ~PS_BEACON_SYNC;
539 ath_dbg(common, PS, 539 ath_dbg(common, PS,
540 "Reconfigure beacon timers based on synchronized timestamp\n"); 540 "Reconfigure beacon timers based on synchronized timestamp\n");
541 ath9k_set_beacon(sc); 541 if (!(WARN_ON_ONCE(sc->cur_beacon_conf.beacon_interval == 0)))
542 542 ath9k_set_beacon(sc);
543 if (sc->p2p_ps_vif) 543 if (sc->p2p_ps_vif)
544 ath9k_update_p2p_ps(sc, sc->p2p_ps_vif->vif); 544 ath9k_update_p2p_ps(sc, sc->p2p_ps_vif->vif);
545 } 545 }
@@ -978,6 +978,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
978 u64 tsf = 0; 978 u64 tsf = 0;
979 unsigned long flags; 979 unsigned long flags;
980 dma_addr_t new_buf_addr; 980 dma_addr_t new_buf_addr;
981 unsigned int budget = 512;
981 982
982 if (edma) 983 if (edma)
983 dma_type = DMA_BIDIRECTIONAL; 984 dma_type = DMA_BIDIRECTIONAL;
@@ -1116,15 +1117,17 @@ requeue_drop_frag:
1116 } 1117 }
1117requeue: 1118requeue:
1118 list_add_tail(&bf->list, &sc->rx.rxbuf); 1119 list_add_tail(&bf->list, &sc->rx.rxbuf);
1119 if (flush)
1120 continue;
1121 1120
1122 if (edma) { 1121 if (edma) {
1123 ath_rx_edma_buf_link(sc, qtype); 1122 ath_rx_edma_buf_link(sc, qtype);
1124 } else { 1123 } else {
1125 ath_rx_buf_relink(sc, bf); 1124 ath_rx_buf_relink(sc, bf);
1126 ath9k_hw_rxena(ah); 1125 if (!flush)
1126 ath9k_hw_rxena(ah);
1127 } 1127 }
1128
1129 if (!budget--)
1130 break;
1128 } while (1); 1131 } while (1);
1129 1132
1130 if (!(ah->imask & ATH9K_INT_RXEOL)) { 1133 if (!(ah->imask & ATH9K_INT_RXEOL)) {
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 87cbec47fb48..66acb2cbd9df 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -107,9 +107,6 @@ static void ath_tx_queue_tid(struct ath_txq *txq, struct ath_atx_tid *tid)
107{ 107{
108 struct ath_atx_ac *ac = tid->ac; 108 struct ath_atx_ac *ac = tid->ac;
109 109
110 if (tid->paused)
111 return;
112
113 if (tid->sched) 110 if (tid->sched)
114 return; 111 return;
115 112
@@ -1407,7 +1404,6 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta,
1407 ath_tx_tid_change_state(sc, txtid); 1404 ath_tx_tid_change_state(sc, txtid);
1408 1405
1409 txtid->active = true; 1406 txtid->active = true;
1410 txtid->paused = true;
1411 *ssn = txtid->seq_start = txtid->seq_next; 1407 *ssn = txtid->seq_start = txtid->seq_next;
1412 txtid->bar_index = -1; 1408 txtid->bar_index = -1;
1413 1409
@@ -1427,7 +1423,6 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid)
1427 1423
1428 ath_txq_lock(sc, txq); 1424 ath_txq_lock(sc, txq);
1429 txtid->active = false; 1425 txtid->active = false;
1430 txtid->paused = false;
1431 ath_tx_flush_tid(sc, txtid); 1426 ath_tx_flush_tid(sc, txtid);
1432 ath_tx_tid_change_state(sc, txtid); 1427 ath_tx_tid_change_state(sc, txtid);
1433 ath_txq_unlock_complete(sc, txq); 1428 ath_txq_unlock_complete(sc, txq);
@@ -1487,7 +1482,7 @@ void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an)
1487 ath_txq_lock(sc, txq); 1482 ath_txq_lock(sc, txq);
1488 ac->clear_ps_filter = true; 1483 ac->clear_ps_filter = true;
1489 1484
1490 if (!tid->paused && ath_tid_has_buffered(tid)) { 1485 if (ath_tid_has_buffered(tid)) {
1491 ath_tx_queue_tid(txq, tid); 1486 ath_tx_queue_tid(txq, tid);
1492 ath_txq_schedule(sc, txq); 1487 ath_txq_schedule(sc, txq);
1493 } 1488 }
@@ -1510,7 +1505,6 @@ void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta,
1510 ath_txq_lock(sc, txq); 1505 ath_txq_lock(sc, txq);
1511 1506
1512 tid->baw_size = IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor; 1507 tid->baw_size = IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor;
1513 tid->paused = false;
1514 1508
1515 if (ath_tid_has_buffered(tid)) { 1509 if (ath_tid_has_buffered(tid)) {
1516 ath_tx_queue_tid(txq, tid); 1510 ath_tx_queue_tid(txq, tid);
@@ -1544,8 +1538,6 @@ void ath9k_release_buffered_frames(struct ieee80211_hw *hw,
1544 continue; 1538 continue;
1545 1539
1546 tid = ATH_AN_2_TID(an, i); 1540 tid = ATH_AN_2_TID(an, i);
1547 if (tid->paused)
1548 continue;
1549 1541
1550 ath_txq_lock(sc, tid->ac->txq); 1542 ath_txq_lock(sc, tid->ac->txq);
1551 while (nframes > 0) { 1543 while (nframes > 0) {
@@ -1844,9 +1836,6 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
1844 list_del(&tid->list); 1836 list_del(&tid->list);
1845 tid->sched = false; 1837 tid->sched = false;
1846 1838
1847 if (tid->paused)
1848 continue;
1849
1850 if (ath_tx_sched_aggr(sc, txq, tid, &stop)) 1839 if (ath_tx_sched_aggr(sc, txq, tid, &stop))
1851 sent = true; 1840 sent = true;
1852 1841
@@ -2698,7 +2687,6 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an)
2698 tid->baw_size = WME_MAX_BA; 2687 tid->baw_size = WME_MAX_BA;
2699 tid->baw_head = tid->baw_tail = 0; 2688 tid->baw_head = tid->baw_tail = 0;
2700 tid->sched = false; 2689 tid->sched = false;
2701 tid->paused = false;
2702 tid->active = false; 2690 tid->active = false;
2703 __skb_queue_head_init(&tid->buf_q); 2691 __skb_queue_head_init(&tid->buf_q);
2704 __skb_queue_head_init(&tid->retry_q); 2692 __skb_queue_head_init(&tid->retry_q);
diff --git a/drivers/net/wireless/ath/carl9170/main.c b/drivers/net/wireless/ath/carl9170/main.c
index 4c8cdb097b65..f8ded84b7be8 100644
--- a/drivers/net/wireless/ath/carl9170/main.c
+++ b/drivers/net/wireless/ath/carl9170/main.c
@@ -1707,7 +1707,9 @@ found:
1707 return 0; 1707 return 0;
1708} 1708}
1709 1709
1710static void carl9170_op_flush(struct ieee80211_hw *hw, u32 queues, bool drop) 1710static void carl9170_op_flush(struct ieee80211_hw *hw,
1711 struct ieee80211_vif *vif,
1712 u32 queues, bool drop)
1711{ 1713{
1712 struct ar9170 *ar = hw->priv; 1714 struct ar9170 *ar = hw->priv;
1713 unsigned int vid; 1715 unsigned int vid;
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig
index 088d544ec63f..1c7d27bf4bf0 100644
--- a/drivers/net/wireless/b43/Kconfig
+++ b/drivers/net/wireless/b43/Kconfig
@@ -1,7 +1,8 @@
1config B43 1config B43
2 tristate "Broadcom 43xx wireless support (mac80211 stack)" 2 tristate "Broadcom 43xx wireless support (mac80211 stack)"
3 depends on SSB_POSSIBLE && MAC80211 && HAS_DMA 3 depends on (BCMA_POSSIBLE || SSB_POSSIBLE) && MAC80211 && HAS_DMA
4 select SSB 4 select BCMA if B43_BCMA
5 select SSB if B43_SSB
5 select FW_LOADER 6 select FW_LOADER
6 ---help--- 7 ---help---
7 b43 is a driver for the Broadcom 43xx series wireless devices. 8 b43 is a driver for the Broadcom 43xx series wireless devices.
@@ -27,14 +28,33 @@ config B43
27 If unsure, say M. 28 If unsure, say M.
28 29
29config B43_BCMA 30config B43_BCMA
30 bool "Support for BCMA bus" 31 bool
31 depends on B43 && (BCMA = y || BCMA = B43)
32 default y
33 32
34config B43_SSB 33config B43_SSB
35 bool 34 bool
36 depends on B43 && (SSB = y || SSB = B43) 35
37 default y 36choice
37 prompt "Supported bus types"
38 depends on B43
39 default B43_BCMA_AND_SSB
40
41config B43_BUSES_BCMA_AND_SSB
42 bool "BCMA and SSB"
43 depends on BCMA_POSSIBLE && SSB_POSSIBLE
44 select B43_BCMA
45 select B43_SSB
46
47config B43_BUSES_BCMA
48 bool "BCMA only"
49 depends on BCMA_POSSIBLE
50 select B43_BCMA
51
52config B43_BUSES_SSB
53 bool "SSB only"
54 depends on SSB_POSSIBLE
55 select B43_SSB
56
57endchoice
38 58
39# Auto-select SSB PCI-HOST support, if possible 59# Auto-select SSB PCI-HOST support, if possible
40config B43_PCI_AUTOSELECT 60config B43_PCI_AUTOSELECT
@@ -98,7 +118,7 @@ config B43_BCMA_PIO
98 118
99config B43_PIO 119config B43_PIO
100 bool 120 bool
101 depends on B43 121 depends on B43 && B43_SSB
102 select SSB_BLOCKIO 122 select SSB_BLOCKIO
103 default y 123 default y
104 124
@@ -116,7 +136,7 @@ config B43_PHY_N
116 136
117config B43_PHY_LP 137config B43_PHY_LP
118 bool "Support for low-power (LP-PHY) devices" 138 bool "Support for low-power (LP-PHY) devices"
119 depends on B43 139 depends on B43 && B43_SSB
120 default y 140 default y
121 ---help--- 141 ---help---
122 Support for the LP-PHY. 142 Support for the LP-PHY.
diff --git a/drivers/net/wireless/b43/bus.h b/drivers/net/wireless/b43/bus.h
index 184c95659279..f3205c6988bc 100644
--- a/drivers/net/wireless/b43/bus.h
+++ b/drivers/net/wireless/b43/bus.h
@@ -5,7 +5,9 @@ enum b43_bus_type {
5#ifdef CONFIG_B43_BCMA 5#ifdef CONFIG_B43_BCMA
6 B43_BUS_BCMA, 6 B43_BUS_BCMA,
7#endif 7#endif
8#ifdef CONFIG_B43_SSB
8 B43_BUS_SSB, 9 B43_BUS_SSB,
10#endif
9}; 11};
10 12
11struct b43_bus_dev { 13struct b43_bus_dev {
@@ -52,13 +54,21 @@ struct b43_bus_dev {
52 54
53static inline bool b43_bus_host_is_pcmcia(struct b43_bus_dev *dev) 55static inline bool b43_bus_host_is_pcmcia(struct b43_bus_dev *dev)
54{ 56{
57#ifdef CONFIG_B43_SSB
55 return (dev->bus_type == B43_BUS_SSB && 58 return (dev->bus_type == B43_BUS_SSB &&
56 dev->sdev->bus->bustype == SSB_BUSTYPE_PCMCIA); 59 dev->sdev->bus->bustype == SSB_BUSTYPE_PCMCIA);
60#else
61 return false;
62#endif
57} 63}
58static inline bool b43_bus_host_is_sdio(struct b43_bus_dev *dev) 64static inline bool b43_bus_host_is_sdio(struct b43_bus_dev *dev)
59{ 65{
66#ifdef CONFIG_B43_SSB
60 return (dev->bus_type == B43_BUS_SSB && 67 return (dev->bus_type == B43_BUS_SSB &&
61 dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO); 68 dev->sdev->bus->bustype == SSB_BUSTYPE_SDIO);
69#else
70 return false;
71#endif
62} 72}
63 73
64struct b43_bus_dev *b43_bus_dev_bcma_init(struct bcma_device *core); 74struct b43_bus_dev *b43_bus_dev_bcma_init(struct bcma_device *core);
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 07024c69d0b5..558abe7718e4 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -1195,14 +1195,20 @@ static void b43_bcma_wireless_core_reset(struct b43_wldev *dev, bool gmode)
1195 B43_BCMA_CLKCTLST_PHY_PLL_REQ; 1195 B43_BCMA_CLKCTLST_PHY_PLL_REQ;
1196 u32 status = B43_BCMA_CLKCTLST_80211_PLL_ST | 1196 u32 status = B43_BCMA_CLKCTLST_80211_PLL_ST |
1197 B43_BCMA_CLKCTLST_PHY_PLL_ST; 1197 B43_BCMA_CLKCTLST_PHY_PLL_ST;
1198 u32 flags;
1199
1200 flags = B43_BCMA_IOCTL_PHY_CLKEN;
1201 if (gmode)
1202 flags |= B43_BCMA_IOCTL_GMODE;
1203 b43_device_enable(dev, flags);
1198 1204
1199 b43_device_enable(dev, B43_BCMA_IOCTL_PHY_CLKEN);
1200 bcma_core_set_clockmode(dev->dev->bdev, BCMA_CLKMODE_FAST); 1205 bcma_core_set_clockmode(dev->dev->bdev, BCMA_CLKMODE_FAST);
1201 b43_bcma_phy_reset(dev); 1206 b43_bcma_phy_reset(dev);
1202 bcma_core_pll_ctl(dev->dev->bdev, req, status, true); 1207 bcma_core_pll_ctl(dev->dev->bdev, req, status, true);
1203} 1208}
1204#endif 1209#endif
1205 1210
1211#ifdef CONFIG_B43_SSB
1206static void b43_ssb_wireless_core_reset(struct b43_wldev *dev, bool gmode) 1212static void b43_ssb_wireless_core_reset(struct b43_wldev *dev, bool gmode)
1207{ 1213{
1208 struct ssb_device *sdev = dev->dev->sdev; 1214 struct ssb_device *sdev = dev->dev->sdev;
@@ -1230,6 +1236,7 @@ static void b43_ssb_wireless_core_reset(struct b43_wldev *dev, bool gmode)
1230 ssb_read32(sdev, SSB_TMSLOW); /* flush */ 1236 ssb_read32(sdev, SSB_TMSLOW); /* flush */
1231 msleep(1); 1237 msleep(1);
1232} 1238}
1239#endif
1233 1240
1234void b43_wireless_core_reset(struct b43_wldev *dev, bool gmode) 1241void b43_wireless_core_reset(struct b43_wldev *dev, bool gmode)
1235{ 1242{
@@ -2730,6 +2737,8 @@ out:
2730/* Initialize the GPIOs 2737/* Initialize the GPIOs
2731 * http://bcm-specs.sipsolutions.net/GPIO 2738 * http://bcm-specs.sipsolutions.net/GPIO
2732 */ 2739 */
2740
2741#ifdef CONFIG_B43_SSB
2733static struct ssb_device *b43_ssb_gpio_dev(struct b43_wldev *dev) 2742static struct ssb_device *b43_ssb_gpio_dev(struct b43_wldev *dev)
2734{ 2743{
2735 struct ssb_bus *bus = dev->dev->sdev->bus; 2744 struct ssb_bus *bus = dev->dev->sdev->bus;
@@ -2740,10 +2749,13 @@ static struct ssb_device *b43_ssb_gpio_dev(struct b43_wldev *dev)
2740 return bus->chipco.dev; 2749 return bus->chipco.dev;
2741#endif 2750#endif
2742} 2751}
2752#endif
2743 2753
2744static int b43_gpio_init(struct b43_wldev *dev) 2754static int b43_gpio_init(struct b43_wldev *dev)
2745{ 2755{
2756#ifdef CONFIG_B43_SSB
2746 struct ssb_device *gpiodev; 2757 struct ssb_device *gpiodev;
2758#endif
2747 u32 mask, set; 2759 u32 mask, set;
2748 2760
2749 b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_GPOUTSMSK, 0); 2761 b43_maskset32(dev, B43_MMIO_MACCTL, ~B43_MACCTL_GPOUTSMSK, 0);
@@ -2802,7 +2814,9 @@ static int b43_gpio_init(struct b43_wldev *dev)
2802/* Turn off all GPIO stuff. Call this on module unload, for example. */ 2814/* Turn off all GPIO stuff. Call this on module unload, for example. */
2803static void b43_gpio_cleanup(struct b43_wldev *dev) 2815static void b43_gpio_cleanup(struct b43_wldev *dev)
2804{ 2816{
2817#ifdef CONFIG_B43_SSB
2805 struct ssb_device *gpiodev; 2818 struct ssb_device *gpiodev;
2819#endif
2806 2820
2807 switch (dev->dev->bus_type) { 2821 switch (dev->dev->bus_type) {
2808#ifdef CONFIG_B43_BCMA 2822#ifdef CONFIG_B43_BCMA
@@ -3687,7 +3701,9 @@ static void b43_op_set_tsf(struct ieee80211_hw *hw,
3687 3701
3688static void b43_put_phy_into_reset(struct b43_wldev *dev) 3702static void b43_put_phy_into_reset(struct b43_wldev *dev)
3689{ 3703{
3704#ifdef CONFIG_B43_SSB
3690 u32 tmp; 3705 u32 tmp;
3706#endif
3691 3707
3692 switch (dev->dev->bus_type) { 3708 switch (dev->dev->bus_type) {
3693#ifdef CONFIG_B43_BCMA 3709#ifdef CONFIG_B43_BCMA
@@ -4577,8 +4593,12 @@ static void b43_imcfglo_timeouts_workaround(struct b43_wldev *dev)
4577 struct ssb_bus *bus; 4593 struct ssb_bus *bus;
4578 u32 tmp; 4594 u32 tmp;
4579 4595
4596#ifdef CONFIG_B43_SSB
4580 if (dev->dev->bus_type != B43_BUS_SSB) 4597 if (dev->dev->bus_type != B43_BUS_SSB)
4581 return; 4598 return;
4599#else
4600 return;
4601#endif
4582 4602
4583 bus = dev->dev->sdev->bus; 4603 bus = dev->dev->sdev->bus;
4584 4604
@@ -4733,7 +4753,7 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
4733 } 4753 }
4734 if (sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW) 4754 if (sprom->boardflags_lo & B43_BFL_XTAL_NOSLOW)
4735 hf |= B43_HF_DSCRQ; /* Disable slowclock requests from ucode. */ 4755 hf |= B43_HF_DSCRQ; /* Disable slowclock requests from ucode. */
4736#ifdef CONFIG_SSB_DRIVER_PCICORE 4756#if defined(CONFIG_B43_SSB) && defined(CONFIG_SSB_DRIVER_PCICORE)
4737 if (dev->dev->bus_type == B43_BUS_SSB && 4757 if (dev->dev->bus_type == B43_BUS_SSB &&
4738 dev->dev->sdev->bus->bustype == SSB_BUSTYPE_PCI && 4758 dev->dev->sdev->bus->bustype == SSB_BUSTYPE_PCI &&
4739 dev->dev->sdev->bus->pcicore.dev->id.revision <= 10) 4759 dev->dev->sdev->bus->pcicore.dev->id.revision <= 10)
@@ -5173,7 +5193,6 @@ static int b43_wireless_core_attach(struct b43_wldev *dev)
5173 } 5193 }
5174 5194
5175 dev->phy.gmode = have_2ghz_phy; 5195 dev->phy.gmode = have_2ghz_phy;
5176 dev->phy.radio_on = true;
5177 b43_wireless_core_reset(dev, dev->phy.gmode); 5196 b43_wireless_core_reset(dev, dev->phy.gmode);
5178 5197
5179 err = b43_phy_versioning(dev); 5198 err = b43_phy_versioning(dev);
@@ -5306,6 +5325,7 @@ static int b43_one_core_attach(struct b43_bus_dev *dev, struct b43_wl *wl)
5306 (pdev->subsystem_vendor == PCI_VENDOR_ID_##_subvendor) && \ 5325 (pdev->subsystem_vendor == PCI_VENDOR_ID_##_subvendor) && \
5307 (pdev->subsystem_device == _subdevice) ) 5326 (pdev->subsystem_device == _subdevice) )
5308 5327
5328#ifdef CONFIG_B43_SSB
5309static void b43_sprom_fixup(struct ssb_bus *bus) 5329static void b43_sprom_fixup(struct ssb_bus *bus)
5310{ 5330{
5311 struct pci_dev *pdev; 5331 struct pci_dev *pdev;
@@ -5337,6 +5357,7 @@ static void b43_wireless_exit(struct b43_bus_dev *dev, struct b43_wl *wl)
5337 ssb_set_devtypedata(dev->sdev, NULL); 5357 ssb_set_devtypedata(dev->sdev, NULL);
5338 ieee80211_free_hw(hw); 5358 ieee80211_free_hw(hw);
5339} 5359}
5360#endif
5340 5361
5341static struct b43_wl *b43_wireless_init(struct b43_bus_dev *dev) 5362static struct b43_wl *b43_wireless_init(struct b43_bus_dev *dev)
5342{ 5363{
diff --git a/drivers/net/wireless/b43/phy_common.c b/drivers/net/wireless/b43/phy_common.c
index dbaa51890198..3e45989f418d 100644
--- a/drivers/net/wireless/b43/phy_common.c
+++ b/drivers/net/wireless/b43/phy_common.c
@@ -96,7 +96,7 @@ int b43_phy_init(struct b43_wldev *dev)
96 96
97 phy->channel = ops->get_default_chan(dev); 97 phy->channel = ops->get_default_chan(dev);
98 98
99 ops->software_rfkill(dev, false); 99 b43_software_rfkill(dev, false);
100 err = ops->init(dev); 100 err = ops->init(dev);
101 if (err) { 101 if (err) {
102 b43err(dev->wl, "PHY init failed\n"); 102 b43err(dev->wl, "PHY init failed\n");
@@ -116,7 +116,7 @@ err_phy_exit:
116 if (ops->exit) 116 if (ops->exit)
117 ops->exit(dev); 117 ops->exit(dev);
118err_block_rf: 118err_block_rf:
119 ops->software_rfkill(dev, true); 119 b43_software_rfkill(dev, true);
120 120
121 return err; 121 return err;
122} 122}
@@ -125,7 +125,7 @@ void b43_phy_exit(struct b43_wldev *dev)
125{ 125{
126 const struct b43_phy_operations *ops = dev->phy.ops; 126 const struct b43_phy_operations *ops = dev->phy.ops;
127 127
128 ops->software_rfkill(dev, true); 128 b43_software_rfkill(dev, true);
129 if (ops->exit) 129 if (ops->exit)
130 ops->exit(dev); 130 ops->exit(dev);
131} 131}
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index 482b31210d28..41dab89a2942 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -807,9 +807,16 @@ static void b43_radio_2056_setup(struct b43_wldev *dev,
807 u16 bias, cbias; 807 u16 bias, cbias;
808 u16 pag_boost, padg_boost, pgag_boost, mixg_boost; 808 u16 pag_boost, padg_boost, pgag_boost, mixg_boost;
809 u16 paa_boost, pada_boost, pgaa_boost, mixa_boost; 809 u16 paa_boost, pada_boost, pgaa_boost, mixa_boost;
810 bool is_pkg_fab_smic;
810 811
811 B43_WARN_ON(dev->phy.rev < 3); 812 B43_WARN_ON(dev->phy.rev < 3);
812 813
814 is_pkg_fab_smic =
815 ((dev->dev->chip_id == BCMA_CHIP_ID_BCM43224 ||
816 dev->dev->chip_id == BCMA_CHIP_ID_BCM43225 ||
817 dev->dev->chip_id == BCMA_CHIP_ID_BCM43421) &&
818 dev->dev->chip_pkg == BCMA_PKG_ID_BCM43224_FAB_SMIC);
819
813 b43_chantab_radio_2056_upload(dev, e); 820 b43_chantab_radio_2056_upload(dev, e);
814 b2056_upload_syn_pll_cp2(dev, band == IEEE80211_BAND_5GHZ); 821 b2056_upload_syn_pll_cp2(dev, band == IEEE80211_BAND_5GHZ);
815 822
@@ -817,7 +824,8 @@ static void b43_radio_2056_setup(struct b43_wldev *dev,
817 b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) { 824 b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
818 b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER1, 0x1F); 825 b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER1, 0x1F);
819 b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER2, 0x1F); 826 b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER2, 0x1F);
820 if (dev->dev->chip_id == 0x4716) { 827 if (dev->dev->chip_id == BCMA_CHIP_ID_BCM4716 ||
828 dev->dev->chip_id == BCMA_CHIP_ID_BCM47162) {
821 b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER4, 0x14); 829 b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER4, 0x14);
822 b43_radio_write(dev, B2056_SYN_PLL_CP2, 0); 830 b43_radio_write(dev, B2056_SYN_PLL_CP2, 0);
823 } else { 831 } else {
@@ -825,6 +833,13 @@ static void b43_radio_2056_setup(struct b43_wldev *dev,
825 b43_radio_write(dev, B2056_SYN_PLL_CP2, 0x14); 833 b43_radio_write(dev, B2056_SYN_PLL_CP2, 0x14);
826 } 834 }
827 } 835 }
836 if (sprom->boardflags2_hi & B43_BFH2_GPLL_WAR2 &&
837 b43_current_band(dev->wl) == IEEE80211_BAND_2GHZ) {
838 b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER1, 0x1f);
839 b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER2, 0x1f);
840 b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER4, 0x0b);
841 b43_radio_write(dev, B2056_SYN_PLL_CP2, 0x20);
842 }
828 if (sprom->boardflags2_lo & B43_BFL2_APLL_WAR && 843 if (sprom->boardflags2_lo & B43_BFL2_APLL_WAR &&
829 b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) { 844 b43_current_band(dev->wl) == IEEE80211_BAND_5GHZ) {
830 b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER1, 0x1F); 845 b43_radio_write(dev, B2056_SYN_PLL_LOOPFILTER1, 0x1F);
@@ -840,7 +855,8 @@ static void b43_radio_2056_setup(struct b43_wldev *dev,
840 b43_radio_write(dev, 855 b43_radio_write(dev,
841 offset | B2056_TX_PADG_IDAC, 0xcc); 856 offset | B2056_TX_PADG_IDAC, 0xcc);
842 857
843 if (dev->dev->chip_id == 0x4716) { 858 if (dev->dev->chip_id == BCMA_CHIP_ID_BCM4716 ||
859 dev->dev->chip_id == BCMA_CHIP_ID_BCM47162) {
844 bias = 0x40; 860 bias = 0x40;
845 cbias = 0x45; 861 cbias = 0x45;
846 pag_boost = 0x5; 862 pag_boost = 0x5;
@@ -849,6 +865,10 @@ static void b43_radio_2056_setup(struct b43_wldev *dev,
849 } else { 865 } else {
850 bias = 0x25; 866 bias = 0x25;
851 cbias = 0x20; 867 cbias = 0x20;
868 if (is_pkg_fab_smic) {
869 bias = 0x2a;
870 cbias = 0x38;
871 }
852 pag_boost = 0x4; 872 pag_boost = 0x4;
853 pgag_boost = 0x03; 873 pgag_boost = 0x03;
854 mixg_boost = 0x65; 874 mixg_boost = 0x65;
@@ -917,6 +937,8 @@ static void b43_radio_2056_setup(struct b43_wldev *dev,
917 mixa_boost = 0xF; 937 mixa_boost = 0xF;
918 } 938 }
919 939
940 cbias = is_pkg_fab_smic ? 0x35 : 0x30;
941
920 for (i = 0; i < 2; i++) { 942 for (i = 0; i < 2; i++) {
921 offset = i ? B2056_TX1 : B2056_TX0; 943 offset = i ? B2056_TX1 : B2056_TX0;
922 944
@@ -935,11 +957,11 @@ static void b43_radio_2056_setup(struct b43_wldev *dev,
935 b43_radio_write(dev, 957 b43_radio_write(dev,
936 offset | B2056_TX_PADA_CASCBIAS, 0x03); 958 offset | B2056_TX_PADA_CASCBIAS, 0x03);
937 b43_radio_write(dev, 959 b43_radio_write(dev,
938 offset | B2056_TX_INTPAA_IAUX_STAT, 0x50); 960 offset | B2056_TX_INTPAA_IAUX_STAT, 0x30);
939 b43_radio_write(dev, 961 b43_radio_write(dev,
940 offset | B2056_TX_INTPAA_IMAIN_STAT, 0x50); 962 offset | B2056_TX_INTPAA_IMAIN_STAT, 0x30);
941 b43_radio_write(dev, 963 b43_radio_write(dev,
942 offset | B2056_TX_INTPAA_CASCBIAS, 0x30); 964 offset | B2056_TX_INTPAA_CASCBIAS, cbias);
943 } 965 }
944 } 966 }
945 967
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/chip.c b/drivers/net/wireless/brcm80211/brcmfmac/chip.c
index df130ef53d1c..c7c9f15c0fe0 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c
@@ -303,10 +303,10 @@ static void brcmf_chip_ai_coredisable(struct brcmf_core_priv *core,
303 303
304 ci = core->chip; 304 ci = core->chip;
305 305
306 /* if core is already in reset, just return */ 306 /* if core is already in reset, skip reset */
307 regdata = ci->ops->read32(ci->ctx, core->wrapbase + BCMA_RESET_CTL); 307 regdata = ci->ops->read32(ci->ctx, core->wrapbase + BCMA_RESET_CTL);
308 if ((regdata & BCMA_RESET_CTL_RESET) != 0) 308 if ((regdata & BCMA_RESET_CTL_RESET) != 0)
309 return; 309 goto in_reset_configure;
310 310
311 /* configure reset */ 311 /* configure reset */
312 ci->ops->write32(ci->ctx, core->wrapbase + BCMA_IOCTL, 312 ci->ops->write32(ci->ctx, core->wrapbase + BCMA_IOCTL,
@@ -322,6 +322,7 @@ static void brcmf_chip_ai_coredisable(struct brcmf_core_priv *core,
322 SPINWAIT(ci->ops->read32(ci->ctx, core->wrapbase + BCMA_RESET_CTL) != 322 SPINWAIT(ci->ops->read32(ci->ctx, core->wrapbase + BCMA_RESET_CTL) !=
323 BCMA_RESET_CTL_RESET, 300); 323 BCMA_RESET_CTL_RESET, 300);
324 324
325in_reset_configure:
325 /* in-reset configure */ 326 /* in-reset configure */
326 ci->ops->write32(ci->ctx, core->wrapbase + BCMA_IOCTL, 327 ci->ops->write32(ci->ctx, core->wrapbase + BCMA_IOCTL,
327 reset | BCMA_IOCTL_FGC | BCMA_IOCTL_CLK); 328 reset | BCMA_IOCTL_FGC | BCMA_IOCTL_CLK);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
index 939d6b132922..16f9ab2568a8 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd.h
@@ -186,7 +186,7 @@ void brcmf_del_if(struct brcmf_pub *drvr, s32 bssidx);
186void brcmf_txflowblock_if(struct brcmf_if *ifp, 186void brcmf_txflowblock_if(struct brcmf_if *ifp,
187 enum brcmf_netif_stop_reason reason, bool state); 187 enum brcmf_netif_stop_reason reason, bool state);
188u32 brcmf_get_chip_info(struct brcmf_if *ifp); 188u32 brcmf_get_chip_info(struct brcmf_if *ifp);
189void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp, 189void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp, u8 ifidx,
190 bool success); 190 bool success);
191 191
192/* Sets dongle media info (drv_version, mac address). */ 192/* Sets dongle media info (drv_version, mac address). */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
index c4535616064e..c5dcd82e884b 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_bus.h
@@ -99,6 +99,7 @@ struct brcmf_bus {
99 unsigned long tx_realloc; 99 unsigned long tx_realloc;
100 u32 chip; 100 u32 chip;
101 u32 chiprev; 101 u32 chiprev;
102 bool always_use_fws_queue;
102 103
103 struct brcmf_bus_ops *ops; 104 struct brcmf_bus_ops *ops;
104}; 105};
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
index 6a8983a1fb9c..ed3e32ce8c23 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_common.c
@@ -32,6 +32,9 @@
32#define BRCMF_DEFAULT_SCAN_UNASSOC_TIME 40 32#define BRCMF_DEFAULT_SCAN_UNASSOC_TIME 40
33#define BRCMF_DEFAULT_PACKET_FILTER "100 0 0 0 0x01 0x00" 33#define BRCMF_DEFAULT_PACKET_FILTER "100 0 0 0 0x01 0x00"
34 34
35/* boost value for RSSI_DELTA in preferred join selection */
36#define BRCMF_JOIN_PREF_RSSI_BOOST 8
37
35 38
36bool brcmf_c_prec_enq(struct device *dev, struct pktq *q, 39bool brcmf_c_prec_enq(struct device *dev, struct pktq *q,
37 struct sk_buff *pkt, int prec) 40 struct sk_buff *pkt, int prec)
@@ -246,6 +249,7 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
246{ 249{
247 s8 eventmask[BRCMF_EVENTING_MASK_LEN]; 250 s8 eventmask[BRCMF_EVENTING_MASK_LEN];
248 u8 buf[BRCMF_DCMD_SMLEN]; 251 u8 buf[BRCMF_DCMD_SMLEN];
252 struct brcmf_join_pref_params join_pref_params[2];
249 char *ptr; 253 char *ptr;
250 s32 err; 254 s32 err;
251 255
@@ -298,6 +302,20 @@ int brcmf_c_preinit_dcmds(struct brcmf_if *ifp)
298 goto done; 302 goto done;
299 } 303 }
300 304
305 /* Setup join_pref to select target by RSSI(with boost on 5GHz) */
306 join_pref_params[0].type = BRCMF_JOIN_PREF_RSSI_DELTA;
307 join_pref_params[0].len = 2;
308 join_pref_params[0].rssi_gain = BRCMF_JOIN_PREF_RSSI_BOOST;
309 join_pref_params[0].band = WLC_BAND_5G;
310 join_pref_params[1].type = BRCMF_JOIN_PREF_RSSI;
311 join_pref_params[1].len = 2;
312 join_pref_params[1].rssi_gain = 0;
313 join_pref_params[1].band = 0;
314 err = brcmf_fil_iovar_data_set(ifp, "join_pref", join_pref_params,
315 sizeof(join_pref_params));
316 if (err)
317 brcmf_err("Set join_pref error (%d)\n", err);
318
301 /* Setup event_msgs, enable E_IF */ 319 /* Setup event_msgs, enable E_IF */
302 err = brcmf_fil_iovar_data_get(ifp, "event_msgs", eventmask, 320 err = brcmf_fil_iovar_data_get(ifp, "event_msgs", eventmask,
303 BRCMF_EVENTING_MASK_LEN); 321 BRCMF_EVENTING_MASK_LEN);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index 7d28cd385092..4cacc3d85212 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -190,7 +190,7 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
190 int ret; 190 int ret;
191 struct brcmf_if *ifp = netdev_priv(ndev); 191 struct brcmf_if *ifp = netdev_priv(ndev);
192 struct brcmf_pub *drvr = ifp->drvr; 192 struct brcmf_pub *drvr = ifp->drvr;
193 struct ethhdr *eh; 193 struct ethhdr *eh = (struct ethhdr *)(skb->data);
194 194
195 brcmf_dbg(DATA, "Enter, idx=%d\n", ifp->bssidx); 195 brcmf_dbg(DATA, "Enter, idx=%d\n", ifp->bssidx);
196 196
@@ -236,6 +236,9 @@ static netdev_tx_t brcmf_netdev_start_xmit(struct sk_buff *skb,
236 goto done; 236 goto done;
237 } 237 }
238 238
239 if (eh->h_proto == htons(ETH_P_PAE))
240 atomic_inc(&ifp->pend_8021x_cnt);
241
239 ret = brcmf_fws_process_skb(ifp, skb); 242 ret = brcmf_fws_process_skb(ifp, skb);
240 243
241done: 244done:
@@ -538,31 +541,26 @@ void brcmf_rx_frame(struct device *dev, struct sk_buff *skb)
538 brcmf_netif_rx(ifp, skb); 541 brcmf_netif_rx(ifp, skb);
539} 542}
540 543
541void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp, 544void brcmf_txfinalize(struct brcmf_pub *drvr, struct sk_buff *txp, u8 ifidx,
542 bool success) 545 bool success)
543{ 546{
544 struct brcmf_if *ifp; 547 struct brcmf_if *ifp;
545 struct ethhdr *eh; 548 struct ethhdr *eh;
546 u8 ifidx;
547 u16 type; 549 u16 type;
548 int res;
549
550 res = brcmf_proto_hdrpull(drvr, false, &ifidx, txp);
551 550
552 ifp = drvr->iflist[ifidx]; 551 ifp = drvr->iflist[ifidx];
553 if (!ifp) 552 if (!ifp)
554 goto done; 553 goto done;
555 554
556 if (res == 0) { 555 eh = (struct ethhdr *)(txp->data);
557 eh = (struct ethhdr *)(txp->data); 556 type = ntohs(eh->h_proto);
558 type = ntohs(eh->h_proto);
559 557
560 if (type == ETH_P_PAE) { 558 if (type == ETH_P_PAE) {
561 atomic_dec(&ifp->pend_8021x_cnt); 559 atomic_dec(&ifp->pend_8021x_cnt);
562 if (waitqueue_active(&ifp->pend_8021x_wait)) 560 if (waitqueue_active(&ifp->pend_8021x_wait))
563 wake_up(&ifp->pend_8021x_wait); 561 wake_up(&ifp->pend_8021x_wait);
564 }
565 } 562 }
563
566 if (!success) 564 if (!success)
567 ifp->stats.tx_errors++; 565 ifp->stats.tx_errors++;
568done: 566done:
@@ -573,13 +571,17 @@ void brcmf_txcomplete(struct device *dev, struct sk_buff *txp, bool success)
573{ 571{
574 struct brcmf_bus *bus_if = dev_get_drvdata(dev); 572 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
575 struct brcmf_pub *drvr = bus_if->drvr; 573 struct brcmf_pub *drvr = bus_if->drvr;
574 u8 ifidx;
576 575
577 /* await txstatus signal for firmware if active */ 576 /* await txstatus signal for firmware if active */
578 if (brcmf_fws_fc_active(drvr->fws)) { 577 if (brcmf_fws_fc_active(drvr->fws)) {
579 if (!success) 578 if (!success)
580 brcmf_fws_bustxfail(drvr->fws, txp); 579 brcmf_fws_bustxfail(drvr->fws, txp);
581 } else { 580 } else {
582 brcmf_txfinalize(drvr, txp, success); 581 if (brcmf_proto_hdrpull(drvr, false, &ifidx, txp))
582 brcmu_pkt_buf_free_skb(txp);
583 else
584 brcmf_txfinalize(drvr, txp, ifidx, success);
583 } 585 }
584} 586}
585 587
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h b/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
index 614e4888504f..2bc68a2137fc 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwil_types.h
@@ -53,6 +53,14 @@
53#define BRCMF_OBSS_COEX_OFF 0 53#define BRCMF_OBSS_COEX_OFF 0
54#define BRCMF_OBSS_COEX_ON 1 54#define BRCMF_OBSS_COEX_ON 1
55 55
56/* join preference types for join_pref iovar */
57enum brcmf_join_pref_types {
58 BRCMF_JOIN_PREF_RSSI = 1,
59 BRCMF_JOIN_PREF_WPA,
60 BRCMF_JOIN_PREF_BAND,
61 BRCMF_JOIN_PREF_RSSI_DELTA,
62};
63
56enum brcmf_fil_p2p_if_types { 64enum brcmf_fil_p2p_if_types {
57 BRCMF_FIL_P2P_IF_CLIENT, 65 BRCMF_FIL_P2P_IF_CLIENT,
58 BRCMF_FIL_P2P_IF_GO, 66 BRCMF_FIL_P2P_IF_GO,
@@ -282,6 +290,22 @@ struct brcmf_assoc_params_le {
282 __le16 chanspec_list[1]; 290 __le16 chanspec_list[1];
283}; 291};
284 292
293/**
294 * struct join_pref params - parameters for preferred join selection.
295 *
296 * @type: preference type (see enum brcmf_join_pref_types).
297 * @len: length of bytes following (currently always 2).
298 * @rssi_gain: signal gain for selection (only when @type is RSSI_DELTA).
299 * @band: band to which selection preference applies.
300 * This is used if @type is BAND or RSSI_DELTA.
301 */
302struct brcmf_join_pref_params {
303 u8 type;
304 u8 len;
305 u8 rssi_gain;
306 u8 band;
307};
308
285/* used for join with or without a specific bssid and channel list */ 309/* used for join with or without a specific bssid and channel list */
286struct brcmf_join_params { 310struct brcmf_join_params {
287 struct brcmf_ssid_le ssid_le; 311 struct brcmf_ssid_le ssid_le;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
index c3e7d76dbf35..699908de314a 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
@@ -476,6 +476,7 @@ struct brcmf_fws_info {
476 bool bus_flow_blocked; 476 bool bus_flow_blocked;
477 bool creditmap_received; 477 bool creditmap_received;
478 u8 mode; 478 u8 mode;
479 bool avoid_queueing;
479}; 480};
480 481
481/* 482/*
@@ -1369,13 +1370,12 @@ done:
1369} 1370}
1370 1371
1371static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo, 1372static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo,
1372 struct sk_buff *skb, u32 genbit, 1373 struct sk_buff *skb, u8 ifidx,
1373 u16 seq) 1374 u32 genbit, u16 seq)
1374{ 1375{
1375 struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac; 1376 struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac;
1376 u32 hslot; 1377 u32 hslot;
1377 int ret; 1378 int ret;
1378 u8 ifidx;
1379 1379
1380 hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT); 1380 hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
1381 1381
@@ -1389,29 +1389,21 @@ static int brcmf_fws_txstatus_suppressed(struct brcmf_fws_info *fws, int fifo,
1389 1389
1390 entry->generation = genbit; 1390 entry->generation = genbit;
1391 1391
1392 ret = brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb); 1392 brcmf_skb_htod_tag_set_field(skb, GENERATION, genbit);
1393 if (ret == 0) { 1393 brcmf_skbcb(skb)->htod_seq = seq;
1394 brcmf_skb_htod_tag_set_field(skb, GENERATION, genbit); 1394 if (brcmf_skb_htod_seq_get_field(skb, FROMFW)) {
1395 brcmf_skbcb(skb)->htod_seq = seq; 1395 brcmf_skb_htod_seq_set_field(skb, FROMDRV, 1);
1396 if (brcmf_skb_htod_seq_get_field(skb, FROMFW)) { 1396 brcmf_skb_htod_seq_set_field(skb, FROMFW, 0);
1397 brcmf_skb_htod_seq_set_field(skb, FROMDRV, 1); 1397 } else {
1398 brcmf_skb_htod_seq_set_field(skb, FROMFW, 0); 1398 brcmf_skb_htod_seq_set_field(skb, FROMDRV, 0);
1399 } else {
1400 brcmf_skb_htod_seq_set_field(skb, FROMDRV, 0);
1401 }
1402 ret = brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_SUPPRESSED, fifo,
1403 skb);
1404 } 1399 }
1400 ret = brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_SUPPRESSED, fifo, skb);
1405 1401
1406 if (ret != 0) { 1402 if (ret != 0) {
1407 /* suppress q is full or hdrpull failed, drop this packet */ 1403 /* suppress q is full drop this packet */
1408 brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &skb, 1404 brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &skb, true);
1409 true);
1410 } else { 1405 } else {
1411 /* 1406 /* Mark suppressed to avoid a double free during wlfc cleanup */
1412 * Mark suppressed to avoid a double free during
1413 * wlfc cleanup
1414 */
1415 brcmf_fws_hanger_mark_suppressed(&fws->hanger, hslot); 1407 brcmf_fws_hanger_mark_suppressed(&fws->hanger, hslot);
1416 } 1408 }
1417 1409
@@ -1428,6 +1420,7 @@ brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot,
1428 struct sk_buff *skb; 1420 struct sk_buff *skb;
1429 struct brcmf_skbuff_cb *skcb; 1421 struct brcmf_skbuff_cb *skcb;
1430 struct brcmf_fws_mac_descriptor *entry = NULL; 1422 struct brcmf_fws_mac_descriptor *entry = NULL;
1423 u8 ifidx;
1431 1424
1432 brcmf_dbg(DATA, "flags %d\n", flags); 1425 brcmf_dbg(DATA, "flags %d\n", flags);
1433 1426
@@ -1476,12 +1469,15 @@ brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot,
1476 } 1469 }
1477 brcmf_fws_macdesc_return_req_credit(skb); 1470 brcmf_fws_macdesc_return_req_credit(skb);
1478 1471
1472 if (brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb)) {
1473 brcmu_pkt_buf_free_skb(skb);
1474 return -EINVAL;
1475 }
1479 if (!remove_from_hanger) 1476 if (!remove_from_hanger)
1480 ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, genbit, 1477 ret = brcmf_fws_txstatus_suppressed(fws, fifo, skb, ifidx,
1481 seq); 1478 genbit, seq);
1482
1483 if (remove_from_hanger || ret) 1479 if (remove_from_hanger || ret)
1484 brcmf_txfinalize(fws->drvr, skb, true); 1480 brcmf_txfinalize(fws->drvr, skb, ifidx, true);
1485 1481
1486 return 0; 1482 return 0;
1487} 1483}
@@ -1868,7 +1864,7 @@ int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb)
1868 struct ethhdr *eh = (struct ethhdr *)(skb->data); 1864 struct ethhdr *eh = (struct ethhdr *)(skb->data);
1869 int fifo = BRCMF_FWS_FIFO_BCMC; 1865 int fifo = BRCMF_FWS_FIFO_BCMC;
1870 bool multicast = is_multicast_ether_addr(eh->h_dest); 1866 bool multicast = is_multicast_ether_addr(eh->h_dest);
1871 bool pae = eh->h_proto == htons(ETH_P_PAE); 1867 int rc = 0;
1872 1868
1873 brcmf_dbg(DATA, "tx proto=0x%X\n", ntohs(eh->h_proto)); 1869 brcmf_dbg(DATA, "tx proto=0x%X\n", ntohs(eh->h_proto));
1874 /* determine the priority */ 1870 /* determine the priority */
@@ -1876,8 +1872,13 @@ int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb)
1876 skb->priority = cfg80211_classify8021d(skb, NULL); 1872 skb->priority = cfg80211_classify8021d(skb, NULL);
1877 1873
1878 drvr->tx_multicast += !!multicast; 1874 drvr->tx_multicast += !!multicast;
1879 if (pae) 1875
1880 atomic_inc(&ifp->pend_8021x_cnt); 1876 if (fws->avoid_queueing) {
1877 rc = brcmf_proto_txdata(drvr, ifp->ifidx, 0, skb);
1878 if (rc < 0)
1879 brcmf_txfinalize(drvr, skb, ifp->ifidx, false);
1880 return rc;
1881 }
1881 1882
1882 /* set control buffer information */ 1883 /* set control buffer information */
1883 skcb->if_flags = 0; 1884 skcb->if_flags = 0;
@@ -1899,15 +1900,12 @@ int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb)
1899 brcmf_fws_schedule_deq(fws); 1900 brcmf_fws_schedule_deq(fws);
1900 } else { 1901 } else {
1901 brcmf_err("drop skb: no hanger slot\n"); 1902 brcmf_err("drop skb: no hanger slot\n");
1902 if (pae) { 1903 brcmf_txfinalize(drvr, skb, ifp->ifidx, false);
1903 atomic_dec(&ifp->pend_8021x_cnt); 1904 rc = -ENOMEM;
1904 if (waitqueue_active(&ifp->pend_8021x_wait))
1905 wake_up(&ifp->pend_8021x_wait);
1906 }
1907 brcmu_pkt_buf_free_skb(skb);
1908 } 1905 }
1909 brcmf_fws_unlock(fws); 1906 brcmf_fws_unlock(fws);
1910 return 0; 1907
1908 return rc;
1911} 1909}
1912 1910
1913void brcmf_fws_reset_interface(struct brcmf_if *ifp) 1911void brcmf_fws_reset_interface(struct brcmf_if *ifp)
@@ -1982,7 +1980,8 @@ static void brcmf_fws_dequeue_worker(struct work_struct *worker)
1982 ret = brcmf_proto_txdata(drvr, ifidx, 0, skb); 1980 ret = brcmf_proto_txdata(drvr, ifidx, 0, skb);
1983 brcmf_fws_lock(fws); 1981 brcmf_fws_lock(fws);
1984 if (ret < 0) 1982 if (ret < 0)
1985 brcmf_txfinalize(drvr, skb, false); 1983 brcmf_txfinalize(drvr, skb, ifidx,
1984 false);
1986 if (fws->bus_flow_blocked) 1985 if (fws->bus_flow_blocked)
1987 break; 1986 break;
1988 } 1987 }
@@ -2039,6 +2038,13 @@ int brcmf_fws_init(struct brcmf_pub *drvr)
2039 fws->drvr = drvr; 2038 fws->drvr = drvr;
2040 fws->fcmode = fcmode; 2039 fws->fcmode = fcmode;
2041 2040
2041 if ((drvr->bus_if->always_use_fws_queue == false) &&
2042 (fcmode == BRCMF_FWS_FCMODE_NONE)) {
2043 fws->avoid_queueing = true;
2044 brcmf_dbg(INFO, "FWS queueing will be avoided\n");
2045 return 0;
2046 }
2047
2042 fws->fws_wq = create_singlethread_workqueue("brcmf_fws_wq"); 2048 fws->fws_wq = create_singlethread_workqueue("brcmf_fws_wq");
2043 if (fws->fws_wq == NULL) { 2049 if (fws->fws_wq == NULL) {
2044 brcmf_err("workqueue creation failed\n"); 2050 brcmf_err("workqueue creation failed\n");
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/nvram.c b/drivers/net/wireless/brcm80211/brcmfmac/nvram.c
index d5ef86db631b..5c450d11dbc9 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/nvram.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/nvram.c
@@ -18,72 +18,205 @@
18#include <linux/slab.h> 18#include <linux/slab.h>
19#include <linux/firmware.h> 19#include <linux/firmware.h>
20 20
21#include "dhd_dbg.h"
21#include "nvram.h" 22#include "nvram.h"
22 23
23/* brcmf_nvram_strip :Takes a buffer of "<var>=<value>\n" lines read from a file 24enum nvram_parser_state {
25 IDLE,
26 KEY,
27 VALUE,
28 COMMENT,
29 END
30};
31
32/**
33 * struct nvram_parser - internal info for parser.
34 *
35 * @state: current parser state.
36 * @fwnv: input buffer being parsed.
37 * @nvram: output buffer with parse result.
38 * @nvram_len: lenght of parse result.
39 * @line: current line.
40 * @column: current column in line.
41 * @pos: byte offset in input buffer.
42 * @entry: start position of key,value entry.
43 */
44struct nvram_parser {
45 enum nvram_parser_state state;
46 const struct firmware *fwnv;
47 u8 *nvram;
48 u32 nvram_len;
49 u32 line;
50 u32 column;
51 u32 pos;
52 u32 entry;
53};
54
55static bool is_nvram_char(char c)
56{
57 /* comment marker excluded */
58 if (c == '#')
59 return false;
60
61 /* key and value may have any other readable character */
62 return (c > 0x20 && c < 0x7f);
63}
64
65static bool is_whitespace(char c)
66{
67 return (c == ' ' || c == '\r' || c == '\n' || c == '\t');
68}
69
70static enum nvram_parser_state brcmf_nvram_handle_idle(struct nvram_parser *nvp)
71{
72 char c;
73
74 c = nvp->fwnv->data[nvp->pos];
75 if (c == '\n')
76 return COMMENT;
77 if (is_whitespace(c))
78 goto proceed;
79 if (c == '#')
80 return COMMENT;
81 if (is_nvram_char(c)) {
82 nvp->entry = nvp->pos;
83 return KEY;
84 }
85 brcmf_dbg(INFO, "warning: ln=%d:col=%d: ignoring invalid character\n",
86 nvp->line, nvp->column);
87proceed:
88 nvp->column++;
89 nvp->pos++;
90 return IDLE;
91}
92
93static enum nvram_parser_state brcmf_nvram_handle_key(struct nvram_parser *nvp)
94{
95 enum nvram_parser_state st = nvp->state;
96 char c;
97
98 c = nvp->fwnv->data[nvp->pos];
99 if (c == '=') {
100 st = VALUE;
101 } else if (!is_nvram_char(c)) {
102 brcmf_dbg(INFO, "warning: ln=%d:col=%d: '=' expected, skip invalid key entry\n",
103 nvp->line, nvp->column);
104 return COMMENT;
105 }
106
107 nvp->column++;
108 nvp->pos++;
109 return st;
110}
111
112static enum nvram_parser_state
113brcmf_nvram_handle_value(struct nvram_parser *nvp)
114{
115 char c;
116 char *skv;
117 char *ekv;
118 u32 cplen;
119
120 c = nvp->fwnv->data[nvp->pos];
121 if (!is_nvram_char(c)) {
122 /* key,value pair complete */
123 ekv = (u8 *)&nvp->fwnv->data[nvp->pos];
124 skv = (u8 *)&nvp->fwnv->data[nvp->entry];
125 cplen = ekv - skv;
126 /* copy to output buffer */
127 memcpy(&nvp->nvram[nvp->nvram_len], skv, cplen);
128 nvp->nvram_len += cplen;
129 nvp->nvram[nvp->nvram_len] = '\0';
130 nvp->nvram_len++;
131 return IDLE;
132 }
133 nvp->pos++;
134 nvp->column++;
135 return VALUE;
136}
137
138static enum nvram_parser_state
139brcmf_nvram_handle_comment(struct nvram_parser *nvp)
140{
141 char *eol, *sol;
142
143 sol = (char *)&nvp->fwnv->data[nvp->pos];
144 eol = strchr(sol, '\n');
145 if (eol == NULL)
146 return END;
147
148 /* eat all moving to next line */
149 nvp->line++;
150 nvp->column = 1;
151 nvp->pos += (eol - sol) + 1;
152 return IDLE;
153}
154
155static enum nvram_parser_state brcmf_nvram_handle_end(struct nvram_parser *nvp)
156{
157 /* final state */
158 return END;
159}
160
161static enum nvram_parser_state
162(*nv_parser_states[])(struct nvram_parser *nvp) = {
163 brcmf_nvram_handle_idle,
164 brcmf_nvram_handle_key,
165 brcmf_nvram_handle_value,
166 brcmf_nvram_handle_comment,
167 brcmf_nvram_handle_end
168};
169
170static int brcmf_init_nvram_parser(struct nvram_parser *nvp,
171 const struct firmware *nv)
172{
173 memset(nvp, 0, sizeof(*nvp));
174 nvp->fwnv = nv;
175 /* Alloc for extra 0 byte + roundup by 4 + length field */
176 nvp->nvram = kzalloc(nv->size + 1 + 3 + sizeof(u32), GFP_KERNEL);
177 if (!nvp->nvram)
178 return -ENOMEM;
179
180 nvp->line = 1;
181 nvp->column = 1;
182 return 0;
183}
184
185/* brcmf_nvram_strip :Takes a buffer of "<var>=<value>\n" lines read from a fil
24 * and ending in a NUL. Removes carriage returns, empty lines, comment lines, 186 * and ending in a NUL. Removes carriage returns, empty lines, comment lines,
25 * and converts newlines to NULs. Shortens buffer as needed and pads with NULs. 187 * and converts newlines to NULs. Shortens buffer as needed and pads with NULs.
26 * End of buffer is completed with token identifying length of buffer. 188 * End of buffer is completed with token identifying length of buffer.
27 */ 189 */
28void *brcmf_nvram_strip(const struct firmware *nv, u32 *new_length) 190void *brcmf_nvram_strip(const struct firmware *nv, u32 *new_length)
29{ 191{
30 u8 *nvram; 192 struct nvram_parser nvp;
31 u32 i; 193 u32 pad;
32 u32 len;
33 u32 column;
34 u8 val;
35 bool comment;
36 u32 token; 194 u32 token;
37 __le32 token_le; 195 __le32 token_le;
38 196
39 /* Alloc for extra 0 byte + roundup by 4 + length field */ 197 if (brcmf_init_nvram_parser(&nvp, nv) < 0)
40 nvram = kmalloc(nv->size + 1 + 3 + sizeof(token_le), GFP_KERNEL);
41 if (!nvram)
42 return NULL; 198 return NULL;
43 199
44 len = 0; 200 while (nvp.pos < nv->size) {
45 column = 0; 201 nvp.state = nv_parser_states[nvp.state](&nvp);
46 comment = false; 202 if (nvp.state == END)
47 for (i = 0; i < nv->size; i++) {
48 val = nv->data[i];
49 if (val == 0)
50 break; 203 break;
51 if (val == '\r')
52 continue;
53 if (comment && (val != '\n'))
54 continue;
55 comment = false;
56 if (val == '#') {
57 comment = true;
58 continue;
59 }
60 if (val == '\n') {
61 if (column == 0)
62 continue;
63 nvram[len] = 0;
64 len++;
65 column = 0;
66 continue;
67 }
68 nvram[len] = val;
69 len++;
70 column++;
71 } 204 }
72 column = len; 205 pad = nvp.nvram_len;
73 *new_length = roundup(len + 1, 4); 206 *new_length = roundup(nvp.nvram_len + 1, 4);
74 while (column != *new_length) { 207 while (pad != *new_length) {
75 nvram[column] = 0; 208 nvp.nvram[pad] = 0;
76 column++; 209 pad++;
77 } 210 }
78 211
79 token = *new_length / 4; 212 token = *new_length / 4;
80 token = (~token << 16) | (token & 0x0000FFFF); 213 token = (~token << 16) | (token & 0x0000FFFF);
81 token_le = cpu_to_le32(token); 214 token_le = cpu_to_le32(token);
82 215
83 memcpy(&nvram[*new_length], &token_le, sizeof(token_le)); 216 memcpy(&nvp.nvram[*new_length], &token_le, sizeof(token_le));
84 *new_length += sizeof(token_le); 217 *new_length += sizeof(token_le);
85 218
86 return nvram; 219 return nvp.nvram;
87} 220}
88 221
89void brcmf_nvram_free(void *nvram) 222void brcmf_nvram_free(void *nvram)
@@ -91,4 +224,3 @@ void brcmf_nvram_free(void *nvram)
91 kfree(nvram); 224 kfree(nvram);
92} 225}
93 226
94
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/usb.c b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
index 24f65cd53859..3ce0e7cfd027 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/usb.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/usb.c
@@ -1254,6 +1254,7 @@ static int brcmf_usb_probe_cb(struct brcmf_usbdev_info *devinfo)
1254 bus->chip = bus_pub->devid; 1254 bus->chip = bus_pub->devid;
1255 bus->chiprev = bus_pub->chiprev; 1255 bus->chiprev = bus_pub->chiprev;
1256 bus->proto_type = BRCMF_PROTO_BCDC; 1256 bus->proto_type = BRCMF_PROTO_BCDC;
1257 bus->always_use_fws_queue = true;
1257 1258
1258 /* Attach to the common driver interface */ 1259 /* Attach to the common driver interface */
1259 ret = brcmf_attach(dev); 1260 ret = brcmf_attach(dev);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
index afb3d15e38ff..70bc2542061a 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
@@ -221,9 +221,9 @@ static const struct ieee80211_regdomain brcmf_regdom = {
221 */ 221 */
222 REG_RULE(2484-10, 2484+10, 20, 6, 20, 0), 222 REG_RULE(2484-10, 2484+10, 20, 6, 20, 0),
223 /* IEEE 802.11a, channel 36..64 */ 223 /* IEEE 802.11a, channel 36..64 */
224 REG_RULE(5150-10, 5350+10, 40, 6, 20, 0), 224 REG_RULE(5150-10, 5350+10, 80, 6, 20, 0),
225 /* IEEE 802.11a, channel 100..165 */ 225 /* IEEE 802.11a, channel 100..165 */
226 REG_RULE(5470-10, 5850+10, 40, 6, 20, 0), } 226 REG_RULE(5470-10, 5850+10, 80, 6, 20, 0), }
227}; 227};
228 228
229static const u32 __wl_cipher_suites[] = { 229static const u32 __wl_cipher_suites[] = {
@@ -341,6 +341,60 @@ static u8 brcmf_mw_to_qdbm(u16 mw)
341 return qdbm; 341 return qdbm;
342} 342}
343 343
344u16 chandef_to_chanspec(struct brcmu_d11inf *d11inf,
345 struct cfg80211_chan_def *ch)
346{
347 struct brcmu_chan ch_inf;
348 s32 primary_offset;
349
350 brcmf_dbg(TRACE, "chandef: control %d center %d width %d\n",
351 ch->chan->center_freq, ch->center_freq1, ch->width);
352 ch_inf.chnum = ieee80211_frequency_to_channel(ch->center_freq1);
353 primary_offset = ch->center_freq1 - ch->chan->center_freq;
354 switch (ch->width) {
355 case NL80211_CHAN_WIDTH_20:
356 ch_inf.bw = BRCMU_CHAN_BW_20;
357 WARN_ON(primary_offset != 0);
358 break;
359 case NL80211_CHAN_WIDTH_40:
360 ch_inf.bw = BRCMU_CHAN_BW_40;
361 if (primary_offset < 0)
362 ch_inf.sb = BRCMU_CHAN_SB_U;
363 else
364 ch_inf.sb = BRCMU_CHAN_SB_L;
365 break;
366 case NL80211_CHAN_WIDTH_80:
367 ch_inf.bw = BRCMU_CHAN_BW_80;
368 if (primary_offset < 0) {
369 if (primary_offset < -CH_10MHZ_APART)
370 ch_inf.sb = BRCMU_CHAN_SB_UU;
371 else
372 ch_inf.sb = BRCMU_CHAN_SB_UL;
373 } else {
374 if (primary_offset > CH_10MHZ_APART)
375 ch_inf.sb = BRCMU_CHAN_SB_LL;
376 else
377 ch_inf.sb = BRCMU_CHAN_SB_LU;
378 }
379 break;
380 default:
381 WARN_ON_ONCE(1);
382 }
383 switch (ch->chan->band) {
384 case IEEE80211_BAND_2GHZ:
385 ch_inf.band = BRCMU_CHAN_BAND_2G;
386 break;
387 case IEEE80211_BAND_5GHZ:
388 ch_inf.band = BRCMU_CHAN_BAND_5G;
389 break;
390 default:
391 WARN_ON_ONCE(1);
392 }
393 d11inf->encchspec(&ch_inf);
394
395 return ch_inf.chspec;
396}
397
344u16 channel_to_chanspec(struct brcmu_d11inf *d11inf, 398u16 channel_to_chanspec(struct brcmu_d11inf *d11inf,
345 struct ieee80211_channel *ch) 399 struct ieee80211_channel *ch)
346{ 400{
@@ -1236,8 +1290,8 @@ brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1236 params->chandef.chan->center_freq); 1290 params->chandef.chan->center_freq);
1237 if (params->channel_fixed) { 1291 if (params->channel_fixed) {
1238 /* adding chanspec */ 1292 /* adding chanspec */
1239 chanspec = channel_to_chanspec(&cfg->d11inf, 1293 chanspec = chandef_to_chanspec(&cfg->d11inf,
1240 params->chandef.chan); 1294 &params->chandef);
1241 join_params.params_le.chanspec_list[0] = 1295 join_params.params_le.chanspec_list[0] =
1242 cpu_to_le16(chanspec); 1296 cpu_to_le16(chanspec);
1243 join_params.params_le.chanspec_num = cpu_to_le32(1); 1297 join_params.params_le.chanspec_num = cpu_to_le32(1);
@@ -3734,23 +3788,6 @@ brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif *vif,
3734} 3788}
3735 3789
3736static s32 3790static s32
3737brcmf_cfg80211_set_channel(struct brcmf_cfg80211_info *cfg,
3738 struct brcmf_if *ifp,
3739 struct ieee80211_channel *channel)
3740{
3741 u16 chanspec;
3742 s32 err;
3743
3744 brcmf_dbg(TRACE, "band=%d, center_freq=%d\n", channel->band,
3745 channel->center_freq);
3746
3747 chanspec = channel_to_chanspec(&cfg->d11inf, channel);
3748 err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
3749
3750 return err;
3751}
3752
3753static s32
3754brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev, 3791brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3755 struct cfg80211_ap_settings *settings) 3792 struct cfg80211_ap_settings *settings)
3756{ 3793{
@@ -3765,11 +3802,12 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3765 struct brcmf_join_params join_params; 3802 struct brcmf_join_params join_params;
3766 enum nl80211_iftype dev_role; 3803 enum nl80211_iftype dev_role;
3767 struct brcmf_fil_bss_enable_le bss_enable; 3804 struct brcmf_fil_bss_enable_le bss_enable;
3805 u16 chanspec;
3768 3806
3769 brcmf_dbg(TRACE, "channel_type=%d, beacon_interval=%d, dtim_period=%d,\n", 3807 brcmf_dbg(TRACE, "ctrlchn=%d, center=%d, bw=%d, beacon_interval=%d, dtim_period=%d,\n",
3770 cfg80211_get_chandef_type(&settings->chandef), 3808 settings->chandef.chan->hw_value,
3771 settings->beacon_interval, 3809 settings->chandef.center_freq1, settings->chandef.width,
3772 settings->dtim_period); 3810 settings->beacon_interval, settings->dtim_period);
3773 brcmf_dbg(TRACE, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n", 3811 brcmf_dbg(TRACE, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
3774 settings->ssid, settings->ssid_len, settings->auth_type, 3812 settings->ssid, settings->ssid_len, settings->auth_type,
3775 settings->inactivity_timeout); 3813 settings->inactivity_timeout);
@@ -3826,9 +3864,10 @@ brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3826 3864
3827 brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon); 3865 brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon);
3828 3866
3829 err = brcmf_cfg80211_set_channel(cfg, ifp, settings->chandef.chan); 3867 chanspec = chandef_to_chanspec(&cfg->d11inf, &settings->chandef);
3868 err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
3830 if (err < 0) { 3869 if (err < 0) {
3831 brcmf_err("Set Channel failed, %d\n", err); 3870 brcmf_err("Set Channel failed: chspec=%d, %d\n", chanspec, err);
3832 goto exit; 3871 goto exit;
3833 } 3872 }
3834 3873
@@ -4364,6 +4403,8 @@ static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
4364 WIPHY_FLAG_OFFCHAN_TX | 4403 WIPHY_FLAG_OFFCHAN_TX |
4365 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | 4404 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
4366 WIPHY_FLAG_SUPPORTS_TDLS; 4405 WIPHY_FLAG_SUPPORTS_TDLS;
4406 if (!brcmf_roamoff)
4407 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
4367 wiphy->mgmt_stypes = brcmf_txrx_stypes; 4408 wiphy->mgmt_stypes = brcmf_txrx_stypes;
4368 wiphy->max_remain_on_channel_duration = 5000; 4409 wiphy->max_remain_on_channel_duration = 5000;
4369 brcmf_wiphy_pno_params(wiphy); 4410 brcmf_wiphy_pno_params(wiphy);
@@ -4685,7 +4726,6 @@ brcmf_notify_connect_status(struct brcmf_if *ifp,
4685 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile; 4726 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4686 struct ieee80211_channel *chan; 4727 struct ieee80211_channel *chan;
4687 s32 err = 0; 4728 s32 err = 0;
4688 u16 reason;
4689 4729
4690 if (brcmf_is_apmode(ifp->vif)) { 4730 if (brcmf_is_apmode(ifp->vif)) {
4691 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data); 4731 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
@@ -4706,16 +4746,6 @@ brcmf_notify_connect_status(struct brcmf_if *ifp,
4706 brcmf_dbg(CONN, "Linkdown\n"); 4746 brcmf_dbg(CONN, "Linkdown\n");
4707 if (!brcmf_is_ibssmode(ifp->vif)) { 4747 if (!brcmf_is_ibssmode(ifp->vif)) {
4708 brcmf_bss_connect_done(cfg, ndev, e, false); 4748 brcmf_bss_connect_done(cfg, ndev, e, false);
4709 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED,
4710 &ifp->vif->sme_state)) {
4711 reason = 0;
4712 if (((e->event_code == BRCMF_E_DEAUTH_IND) ||
4713 (e->event_code == BRCMF_E_DISASSOC_IND)) &&
4714 (e->reason != WLAN_REASON_UNSPECIFIED))
4715 reason = e->reason;
4716 cfg80211_disconnected(ndev, reason, NULL, 0,
4717 GFP_KERNEL);
4718 }
4719 } 4749 }
4720 brcmf_link_down(ifp->vif); 4750 brcmf_link_down(ifp->vif);
4721 brcmf_init_prof(ndev_to_prof(ndev)); 4751 brcmf_init_prof(ndev_to_prof(ndev));
@@ -4948,7 +4978,7 @@ static int brcmf_enable_bw40_2g(struct brcmf_if *ifp)
4948 if (!err) { 4978 if (!err) {
4949 /* only set 2G bandwidth using bw_cap command */ 4979 /* only set 2G bandwidth using bw_cap command */
4950 band_bwcap.band = cpu_to_le32(WLC_BAND_2G); 4980 band_bwcap.band = cpu_to_le32(WLC_BAND_2G);
4951 band_bwcap.bw_cap = cpu_to_le32(WLC_BW_40MHZ_BIT); 4981 band_bwcap.bw_cap = cpu_to_le32(WLC_BW_CAP_40MHZ);
4952 err = brcmf_fil_iovar_data_set(ifp, "bw_cap", &band_bwcap, 4982 err = brcmf_fil_iovar_data_set(ifp, "bw_cap", &band_bwcap,
4953 sizeof(band_bwcap)); 4983 sizeof(band_bwcap));
4954 } else { 4984 } else {
@@ -5215,6 +5245,9 @@ static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg,
5215 if (!(bw_cap[band] & WLC_BW_40MHZ_BIT) && 5245 if (!(bw_cap[band] & WLC_BW_40MHZ_BIT) &&
5216 ch.bw == BRCMU_CHAN_BW_40) 5246 ch.bw == BRCMU_CHAN_BW_40)
5217 continue; 5247 continue;
5248 if (!(bw_cap[band] & WLC_BW_80MHZ_BIT) &&
5249 ch.bw == BRCMU_CHAN_BW_80)
5250 continue;
5218 update = false; 5251 update = false;
5219 for (j = 0; (j < *n_cnt && (*n_cnt < array_size)); j++) { 5252 for (j = 0; (j < *n_cnt && (*n_cnt < array_size)); j++) {
5220 if (band_chan_arr[j].hw_value == ch.chnum) { 5253 if (band_chan_arr[j].hw_value == ch.chnum) {
@@ -5231,10 +5264,13 @@ static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg,
5231 ieee80211_channel_to_frequency(ch.chnum, band); 5264 ieee80211_channel_to_frequency(ch.chnum, band);
5232 band_chan_arr[index].hw_value = ch.chnum; 5265 band_chan_arr[index].hw_value = ch.chnum;
5233 5266
5234 if (ch.bw == BRCMU_CHAN_BW_40) { 5267 /* assuming the chanspecs order is HT20,
5235 /* assuming the order is HT20, HT40 Upper, 5268 * HT40 upper, HT40 lower, and VHT80.
5236 * HT40 lower from chanspecs 5269 */
5237 */ 5270 if (ch.bw == BRCMU_CHAN_BW_80) {
5271 band_chan_arr[index].flags &=
5272 ~IEEE80211_CHAN_NO_80MHZ;
5273 } else if (ch.bw == BRCMU_CHAN_BW_40) {
5238 ht40_flag = band_chan_arr[index].flags & 5274 ht40_flag = band_chan_arr[index].flags &
5239 IEEE80211_CHAN_NO_HT40; 5275 IEEE80211_CHAN_NO_HT40;
5240 if (ch.sb == BRCMU_CHAN_SB_U) { 5276 if (ch.sb == BRCMU_CHAN_SB_U) {
@@ -5255,8 +5291,13 @@ static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg,
5255 IEEE80211_CHAN_NO_HT40MINUS; 5291 IEEE80211_CHAN_NO_HT40MINUS;
5256 } 5292 }
5257 } else { 5293 } else {
5294 /* disable other bandwidths for now as mentioned
5295 * order assure they are enabled for subsequent
5296 * chanspecs.
5297 */
5258 band_chan_arr[index].flags = 5298 band_chan_arr[index].flags =
5259 IEEE80211_CHAN_NO_HT40; 5299 IEEE80211_CHAN_NO_HT40 |
5300 IEEE80211_CHAN_NO_80MHZ;
5260 ch.bw = BRCMU_CHAN_BW_20; 5301 ch.bw = BRCMU_CHAN_BW_20;
5261 cfg->d11inf.encchspec(&ch); 5302 cfg->d11inf.encchspec(&ch);
5262 channel = ch.chspec; 5303 channel = ch.chspec;
@@ -5323,13 +5364,63 @@ static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[])
5323 } 5364 }
5324} 5365}
5325 5366
5367static void brcmf_update_ht_cap(struct ieee80211_supported_band *band,
5368 u32 bw_cap[2], u32 nchain)
5369{
5370 band->ht_cap.ht_supported = true;
5371 if (bw_cap[band->band] & WLC_BW_40MHZ_BIT) {
5372 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
5373 band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5374 }
5375 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
5376 band->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
5377 band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
5378 band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
5379 memset(band->ht_cap.mcs.rx_mask, 0xff, nchain);
5380 band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
5381}
5382
5383static __le16 brcmf_get_mcs_map(u32 nchain, enum ieee80211_vht_mcs_support supp)
5384{
5385 u16 mcs_map;
5386 int i;
5387
5388 for (i = 0, mcs_map = 0xFFFF; i < nchain; i++)
5389 mcs_map = (mcs_map << 2) | supp;
5390
5391 return cpu_to_le16(mcs_map);
5392}
5393
5394static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
5395 u32 bw_cap[2], u32 nchain)
5396{
5397 __le16 mcs_map;
5398
5399 /* not allowed in 2.4G band */
5400 if (band->band == IEEE80211_BAND_2GHZ)
5401 return;
5402
5403 band->vht_cap.vht_supported = true;
5404 /* 80MHz is mandatory */
5405 band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
5406 if (bw_cap[band->band] & WLC_BW_160MHZ_BIT) {
5407 band->vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
5408 band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
5409 }
5410 /* all support 256-QAM */
5411 mcs_map = brcmf_get_mcs_map(nchain, IEEE80211_VHT_MCS_SUPPORT_0_9);
5412 band->vht_cap.vht_mcs.rx_mcs_map = mcs_map;
5413 band->vht_cap.vht_mcs.tx_mcs_map = mcs_map;
5414}
5415
5326static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg) 5416static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg)
5327{ 5417{
5328 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg)); 5418 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5329 struct wiphy *wiphy; 5419 struct wiphy *wiphy;
5330 s32 phy_list; 5420 s32 phy_list;
5331 u32 band_list[3]; 5421 u32 band_list[3];
5332 u32 nmode; 5422 u32 nmode = 0;
5423 u32 vhtmode = 0;
5333 u32 bw_cap[2] = { 0, 0 }; 5424 u32 bw_cap[2] = { 0, 0 };
5334 u32 rxchain; 5425 u32 rxchain;
5335 u32 nchain; 5426 u32 nchain;
@@ -5360,14 +5451,16 @@ static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg)
5360 brcmf_dbg(INFO, "BRCMF_C_GET_BANDLIST reported: 0x%08x 0x%08x 0x%08x phy\n", 5451 brcmf_dbg(INFO, "BRCMF_C_GET_BANDLIST reported: 0x%08x 0x%08x 0x%08x phy\n",
5361 band_list[0], band_list[1], band_list[2]); 5452 band_list[0], band_list[1], band_list[2]);
5362 5453
5454 (void)brcmf_fil_iovar_int_get(ifp, "vhtmode", &vhtmode);
5363 err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode); 5455 err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode);
5364 if (err) { 5456 if (err) {
5365 brcmf_err("nmode error (%d)\n", err); 5457 brcmf_err("nmode error (%d)\n", err);
5366 } else { 5458 } else {
5367 brcmf_get_bwcap(ifp, bw_cap); 5459 brcmf_get_bwcap(ifp, bw_cap);
5368 } 5460 }
5369 brcmf_dbg(INFO, "nmode=%d, bw_cap=(%d, %d)\n", nmode, 5461 brcmf_dbg(INFO, "nmode=%d, vhtmode=%d, bw_cap=(%d, %d)\n",
5370 bw_cap[IEEE80211_BAND_2GHZ], bw_cap[IEEE80211_BAND_5GHZ]); 5462 nmode, vhtmode, bw_cap[IEEE80211_BAND_2GHZ],
5463 bw_cap[IEEE80211_BAND_5GHZ]);
5371 5464
5372 err = brcmf_fil_iovar_int_get(ifp, "rxchain", &rxchain); 5465 err = brcmf_fil_iovar_int_get(ifp, "rxchain", &rxchain);
5373 if (err) { 5466 if (err) {
@@ -5398,17 +5491,10 @@ static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg)
5398 else 5491 else
5399 continue; 5492 continue;
5400 5493
5401 if (bw_cap[band->band] & WLC_BW_40MHZ_BIT) { 5494 if (nmode)
5402 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40; 5495 brcmf_update_ht_cap(band, bw_cap, nchain);
5403 band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40; 5496 if (vhtmode)
5404 } 5497 brcmf_update_vht_cap(band, bw_cap, nchain);
5405 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
5406 band->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
5407 band->ht_cap.ht_supported = true;
5408 band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
5409 band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
5410 memset(band->ht_cap.mcs.rx_mask, 0xff, nchain);
5411 band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
5412 bands[band->band] = band; 5498 bands[band->band] = band;
5413 } 5499 }
5414 5500
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
index 8c5fa4e58139..43c71bfaa474 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/mac80211_if.c
@@ -897,7 +897,8 @@ static bool brcms_tx_flush_completed(struct brcms_info *wl)
897 return result; 897 return result;
898} 898}
899 899
900static void brcms_ops_flush(struct ieee80211_hw *hw, u32 queues, bool drop) 900static void brcms_ops_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
901 u32 queues, bool drop)
901{ 902{
902 struct brcms_info *wl = hw->priv; 903 struct brcms_info *wl = hw->priv;
903 int ret; 904 int ret;
diff --git a/drivers/net/wireless/brcm80211/brcmutil/d11.c b/drivers/net/wireless/brcm80211/brcmutil/d11.c
index 30e54e2c6c9b..6cbc33d0fc19 100644
--- a/drivers/net/wireless/brcm80211/brcmutil/d11.c
+++ b/drivers/net/wireless/brcm80211/brcmutil/d11.c
@@ -21,43 +21,81 @@
21#include <brcmu_wifi.h> 21#include <brcmu_wifi.h>
22#include <brcmu_d11.h> 22#include <brcmu_d11.h>
23 23
24static void brcmu_d11n_encchspec(struct brcmu_chan *ch) 24static u16 d11n_sb(enum brcmu_chan_sb sb)
25{ 25{
26 ch->chspec = ch->chnum & BRCMU_CHSPEC_CH_MASK; 26 switch (sb) {
27 case BRCMU_CHAN_SB_NONE:
28 return BRCMU_CHSPEC_D11N_SB_N;
29 case BRCMU_CHAN_SB_L:
30 return BRCMU_CHSPEC_D11N_SB_L;
31 case BRCMU_CHAN_SB_U:
32 return BRCMU_CHSPEC_D11N_SB_U;
33 default:
34 WARN_ON(1);
35 }
36 return 0;
37}
27 38
28 switch (ch->bw) { 39static u16 d11n_bw(enum brcmu_chan_bw bw)
40{
41 switch (bw) {
29 case BRCMU_CHAN_BW_20: 42 case BRCMU_CHAN_BW_20:
30 ch->chspec |= BRCMU_CHSPEC_D11N_BW_20 | BRCMU_CHSPEC_D11N_SB_N; 43 return BRCMU_CHSPEC_D11N_BW_20;
31 break;
32 case BRCMU_CHAN_BW_40: 44 case BRCMU_CHAN_BW_40:
45 return BRCMU_CHSPEC_D11N_BW_40;
33 default: 46 default:
34 WARN_ON_ONCE(1); 47 WARN_ON(1);
35 break;
36 } 48 }
49 return 0;
50}
37 51
52static void brcmu_d11n_encchspec(struct brcmu_chan *ch)
53{
54 if (ch->bw == BRCMU_CHAN_BW_20)
55 ch->sb = BRCMU_CHAN_SB_NONE;
56
57 brcmu_maskset16(&ch->chspec, BRCMU_CHSPEC_CH_MASK,
58 BRCMU_CHSPEC_CH_SHIFT, ch->chnum);
59 brcmu_maskset16(&ch->chspec, BRCMU_CHSPEC_D11N_SB_MASK,
60 0, d11n_sb(ch->sb));
61 brcmu_maskset16(&ch->chspec, BRCMU_CHSPEC_D11N_BW_MASK,
62 0, d11n_bw(ch->bw));
63
64 ch->chspec &= ~BRCMU_CHSPEC_D11N_BND_MASK;
38 if (ch->chnum <= CH_MAX_2G_CHANNEL) 65 if (ch->chnum <= CH_MAX_2G_CHANNEL)
39 ch->chspec |= BRCMU_CHSPEC_D11N_BND_2G; 66 ch->chspec |= BRCMU_CHSPEC_D11N_BND_2G;
40 else 67 else
41 ch->chspec |= BRCMU_CHSPEC_D11N_BND_5G; 68 ch->chspec |= BRCMU_CHSPEC_D11N_BND_5G;
42} 69}
43 70
44static void brcmu_d11ac_encchspec(struct brcmu_chan *ch) 71static u16 d11ac_bw(enum brcmu_chan_bw bw)
45{ 72{
46 ch->chspec = ch->chnum & BRCMU_CHSPEC_CH_MASK; 73 switch (bw) {
47
48 switch (ch->bw) {
49 case BRCMU_CHAN_BW_20: 74 case BRCMU_CHAN_BW_20:
50 ch->chspec |= BRCMU_CHSPEC_D11AC_BW_20; 75 return BRCMU_CHSPEC_D11AC_BW_20;
51 break;
52 case BRCMU_CHAN_BW_40: 76 case BRCMU_CHAN_BW_40:
77 return BRCMU_CHSPEC_D11AC_BW_40;
53 case BRCMU_CHAN_BW_80: 78 case BRCMU_CHAN_BW_80:
54 case BRCMU_CHAN_BW_80P80: 79 return BRCMU_CHSPEC_D11AC_BW_80;
55 case BRCMU_CHAN_BW_160:
56 default: 80 default:
57 WARN_ON_ONCE(1); 81 WARN_ON(1);
58 break;
59 } 82 }
83 return 0;
84}
60 85
86static void brcmu_d11ac_encchspec(struct brcmu_chan *ch)
87{
88 if (ch->bw == BRCMU_CHAN_BW_20 || ch->sb == BRCMU_CHAN_SB_NONE)
89 ch->sb = BRCMU_CHAN_SB_L;
90
91 brcmu_maskset16(&ch->chspec, BRCMU_CHSPEC_CH_MASK,
92 BRCMU_CHSPEC_CH_SHIFT, ch->chnum);
93 brcmu_maskset16(&ch->chspec, BRCMU_CHSPEC_D11AC_SB_MASK,
94 BRCMU_CHSPEC_D11AC_SB_SHIFT, ch->sb);
95 brcmu_maskset16(&ch->chspec, BRCMU_CHSPEC_D11AC_BW_MASK,
96 0, d11ac_bw(ch->bw));
97
98 ch->chspec &= ~BRCMU_CHSPEC_D11AC_BND_MASK;
61 if (ch->chnum <= CH_MAX_2G_CHANNEL) 99 if (ch->chnum <= CH_MAX_2G_CHANNEL)
62 ch->chspec |= BRCMU_CHSPEC_D11AC_BND_2G; 100 ch->chspec |= BRCMU_CHSPEC_D11AC_BND_2G;
63 else 101 else
@@ -73,6 +111,7 @@ static void brcmu_d11n_decchspec(struct brcmu_chan *ch)
73 switch (ch->chspec & BRCMU_CHSPEC_D11N_BW_MASK) { 111 switch (ch->chspec & BRCMU_CHSPEC_D11N_BW_MASK) {
74 case BRCMU_CHSPEC_D11N_BW_20: 112 case BRCMU_CHSPEC_D11N_BW_20:
75 ch->bw = BRCMU_CHAN_BW_20; 113 ch->bw = BRCMU_CHAN_BW_20;
114 ch->sb = BRCMU_CHAN_SB_NONE;
76 break; 115 break;
77 case BRCMU_CHSPEC_D11N_BW_40: 116 case BRCMU_CHSPEC_D11N_BW_40:
78 ch->bw = BRCMU_CHAN_BW_40; 117 ch->bw = BRCMU_CHAN_BW_40;
@@ -112,6 +151,7 @@ static void brcmu_d11ac_decchspec(struct brcmu_chan *ch)
112 switch (ch->chspec & BRCMU_CHSPEC_D11AC_BW_MASK) { 151 switch (ch->chspec & BRCMU_CHSPEC_D11AC_BW_MASK) {
113 case BRCMU_CHSPEC_D11AC_BW_20: 152 case BRCMU_CHSPEC_D11AC_BW_20:
114 ch->bw = BRCMU_CHAN_BW_20; 153 ch->bw = BRCMU_CHAN_BW_20;
154 ch->sb = BRCMU_CHAN_SB_NONE;
115 break; 155 break;
116 case BRCMU_CHSPEC_D11AC_BW_40: 156 case BRCMU_CHSPEC_D11AC_BW_40:
117 ch->bw = BRCMU_CHAN_BW_40; 157 ch->bw = BRCMU_CHAN_BW_40;
@@ -128,6 +168,25 @@ static void brcmu_d11ac_decchspec(struct brcmu_chan *ch)
128 break; 168 break;
129 case BRCMU_CHSPEC_D11AC_BW_80: 169 case BRCMU_CHSPEC_D11AC_BW_80:
130 ch->bw = BRCMU_CHAN_BW_80; 170 ch->bw = BRCMU_CHAN_BW_80;
171 ch->sb = brcmu_maskget16(ch->chspec, BRCMU_CHSPEC_D11AC_SB_MASK,
172 BRCMU_CHSPEC_D11AC_SB_SHIFT);
173 switch (ch->sb) {
174 case BRCMU_CHAN_SB_LL:
175 ch->chnum -= CH_30MHZ_APART;
176 break;
177 case BRCMU_CHAN_SB_LU:
178 ch->chnum -= CH_10MHZ_APART;
179 break;
180 case BRCMU_CHAN_SB_UL:
181 ch->chnum += CH_10MHZ_APART;
182 break;
183 case BRCMU_CHAN_SB_UU:
184 ch->chnum += CH_30MHZ_APART;
185 break;
186 default:
187 WARN_ON_ONCE(1);
188 break;
189 }
131 break; 190 break;
132 case BRCMU_CHSPEC_D11AC_BW_8080: 191 case BRCMU_CHSPEC_D11AC_BW_8080:
133 case BRCMU_CHSPEC_D11AC_BW_160: 192 case BRCMU_CHSPEC_D11AC_BW_160:
diff --git a/drivers/net/wireless/brcm80211/include/brcmu_d11.h b/drivers/net/wireless/brcm80211/include/brcmu_d11.h
index 8660a2cba098..f9745ea8b3e0 100644
--- a/drivers/net/wireless/brcm80211/include/brcmu_d11.h
+++ b/drivers/net/wireless/brcm80211/include/brcmu_d11.h
@@ -108,13 +108,7 @@ enum brcmu_chan_bw {
108}; 108};
109 109
110enum brcmu_chan_sb { 110enum brcmu_chan_sb {
111 BRCMU_CHAN_SB_NONE = 0, 111 BRCMU_CHAN_SB_NONE = -1,
112 BRCMU_CHAN_SB_L,
113 BRCMU_CHAN_SB_U,
114 BRCMU_CHAN_SB_LL,
115 BRCMU_CHAN_SB_LU,
116 BRCMU_CHAN_SB_UL,
117 BRCMU_CHAN_SB_UU,
118 BRCMU_CHAN_SB_LLL, 112 BRCMU_CHAN_SB_LLL,
119 BRCMU_CHAN_SB_LLU, 113 BRCMU_CHAN_SB_LLU,
120 BRCMU_CHAN_SB_LUL, 114 BRCMU_CHAN_SB_LUL,
@@ -123,6 +117,12 @@ enum brcmu_chan_sb {
123 BRCMU_CHAN_SB_ULU, 117 BRCMU_CHAN_SB_ULU,
124 BRCMU_CHAN_SB_UUL, 118 BRCMU_CHAN_SB_UUL,
125 BRCMU_CHAN_SB_UUU, 119 BRCMU_CHAN_SB_UUU,
120 BRCMU_CHAN_SB_L = BRCMU_CHAN_SB_LLL,
121 BRCMU_CHAN_SB_U = BRCMU_CHAN_SB_LLU,
122 BRCMU_CHAN_SB_LL = BRCMU_CHAN_SB_LLL,
123 BRCMU_CHAN_SB_LU = BRCMU_CHAN_SB_LLU,
124 BRCMU_CHAN_SB_UL = BRCMU_CHAN_SB_LUL,
125 BRCMU_CHAN_SB_UU = BRCMU_CHAN_SB_LUU,
126}; 126};
127 127
128struct brcmu_chan { 128struct brcmu_chan {
diff --git a/drivers/net/wireless/brcm80211/include/brcmu_wifi.h b/drivers/net/wireless/brcm80211/include/brcmu_wifi.h
index 74419d4bd123..76b5d3a86294 100644
--- a/drivers/net/wireless/brcm80211/include/brcmu_wifi.h
+++ b/drivers/net/wireless/brcm80211/include/brcmu_wifi.h
@@ -29,6 +29,7 @@
29#define CH_UPPER_SB 0x01 29#define CH_UPPER_SB 0x01
30#define CH_LOWER_SB 0x02 30#define CH_LOWER_SB 0x02
31#define CH_EWA_VALID 0x04 31#define CH_EWA_VALID 0x04
32#define CH_30MHZ_APART 6
32#define CH_20MHZ_APART 4 33#define CH_20MHZ_APART 4
33#define CH_10MHZ_APART 2 34#define CH_10MHZ_APART 2
34#define CH_5MHZ_APART 1 /* 2G band channels are 5 Mhz apart */ 35#define CH_5MHZ_APART 1 /* 2G band channels are 5 Mhz apart */
diff --git a/drivers/net/wireless/cw1200/sta.c b/drivers/net/wireless/cw1200/sta.c
index 103f7bce8932..cd0cad7f7759 100644
--- a/drivers/net/wireless/cw1200/sta.c
+++ b/drivers/net/wireless/cw1200/sta.c
@@ -936,7 +936,8 @@ static int __cw1200_flush(struct cw1200_common *priv, bool drop)
936 return ret; 936 return ret;
937} 937}
938 938
939void cw1200_flush(struct ieee80211_hw *hw, u32 queues, bool drop) 939void cw1200_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
940 u32 queues, bool drop)
940{ 941{
941 struct cw1200_common *priv = hw->priv; 942 struct cw1200_common *priv = hw->priv;
942 943
diff --git a/drivers/net/wireless/cw1200/sta.h b/drivers/net/wireless/cw1200/sta.h
index 35babb62cc6a..b7e386b7662b 100644
--- a/drivers/net/wireless/cw1200/sta.h
+++ b/drivers/net/wireless/cw1200/sta.h
@@ -40,7 +40,8 @@ int cw1200_set_key(struct ieee80211_hw *dev, enum set_key_cmd cmd,
40 40
41int cw1200_set_rts_threshold(struct ieee80211_hw *hw, u32 value); 41int cw1200_set_rts_threshold(struct ieee80211_hw *hw, u32 value);
42 42
43void cw1200_flush(struct ieee80211_hw *hw, u32 queues, bool drop); 43void cw1200_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
44 u32 queues, bool drop);
44 45
45u64 cw1200_prepare_multicast(struct ieee80211_hw *hw, 46u64 cw1200_prepare_multicast(struct ieee80211_hw *hw,
46 struct netdev_hw_addr_list *mc_list); 47 struct netdev_hw_addr_list *mc_list);
diff --git a/drivers/net/wireless/iwlegacy/3945.c b/drivers/net/wireless/iwlegacy/3945.c
index d37a6fd90d40..b598e2803500 100644
--- a/drivers/net/wireless/iwlegacy/3945.c
+++ b/drivers/net/wireless/iwlegacy/3945.c
@@ -573,7 +573,7 @@ il3945_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb)
573 rx_status.flag |= RX_FLAG_SHORTPRE; 573 rx_status.flag |= RX_FLAG_SHORTPRE;
574 574
575 if ((unlikely(rx_stats->phy_count > 20))) { 575 if ((unlikely(rx_stats->phy_count > 20))) {
576 D_DROP("dsp size out of range [0,20]: %d/n", 576 D_DROP("dsp size out of range [0,20]: %d\n",
577 rx_stats->phy_count); 577 rx_stats->phy_count);
578 return; 578 return;
579 } 579 }
diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c
index 888ad5c74639..c159c05db6ef 100644
--- a/drivers/net/wireless/iwlegacy/4965-mac.c
+++ b/drivers/net/wireless/iwlegacy/4965-mac.c
@@ -670,7 +670,7 @@ il4965_hdl_rx(struct il_priv *il, struct il_rx_buf *rxb)
670 } 670 }
671 671
672 if ((unlikely(phy_res->cfg_phy_cnt > 20))) { 672 if ((unlikely(phy_res->cfg_phy_cnt > 20))) {
673 D_DROP("dsp size out of range [0,20]: %d/n", 673 D_DROP("dsp size out of range [0,20]: %d\n",
674 phy_res->cfg_phy_cnt); 674 phy_res->cfg_phy_cnt);
675 return; 675 return;
676 } 676 }
diff --git a/drivers/net/wireless/iwlegacy/common.c b/drivers/net/wireless/iwlegacy/common.c
index 4f42174d9994..ecc674627e6e 100644
--- a/drivers/net/wireless/iwlegacy/common.c
+++ b/drivers/net/wireless/iwlegacy/common.c
@@ -4755,7 +4755,8 @@ out:
4755} 4755}
4756EXPORT_SYMBOL(il_mac_change_interface); 4756EXPORT_SYMBOL(il_mac_change_interface);
4757 4757
4758void il_mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop) 4758void il_mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
4759 u32 queues, bool drop)
4759{ 4760{
4760 struct il_priv *il = hw->priv; 4761 struct il_priv *il = hw->priv;
4761 unsigned long timeout = jiffies + msecs_to_jiffies(500); 4762 unsigned long timeout = jiffies + msecs_to_jiffies(500);
diff --git a/drivers/net/wireless/iwlegacy/common.h b/drivers/net/wireless/iwlegacy/common.h
index dfb13c70efe8..ea5c0f863c4e 100644
--- a/drivers/net/wireless/iwlegacy/common.h
+++ b/drivers/net/wireless/iwlegacy/common.h
@@ -1723,7 +1723,8 @@ void il_mac_remove_interface(struct ieee80211_hw *hw,
1723 struct ieee80211_vif *vif); 1723 struct ieee80211_vif *vif);
1724int il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 1724int il_mac_change_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1725 enum nl80211_iftype newtype, bool newp2p); 1725 enum nl80211_iftype newtype, bool newp2p);
1726void il_mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop); 1726void il_mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1727 u32 queues, bool drop);
1727int il_alloc_txq_mem(struct il_priv *il); 1728int il_alloc_txq_mem(struct il_priv *il);
1728void il_free_txq_mem(struct il_priv *il); 1729void il_free_txq_mem(struct il_priv *il);
1729 1730
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index 74b3b4de7bb7..b82d30c0f0c9 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -2,10 +2,6 @@ config IWLWIFI
2 tristate "Intel Wireless WiFi Next Gen AGN - Wireless-N/Advanced-N/Ultimate-N (iwlwifi) " 2 tristate "Intel Wireless WiFi Next Gen AGN - Wireless-N/Advanced-N/Ultimate-N (iwlwifi) "
3 depends on PCI && MAC80211 && HAS_IOMEM 3 depends on PCI && MAC80211 && HAS_IOMEM
4 select FW_LOADER 4 select FW_LOADER
5 select NEW_LEDS
6 select LEDS_CLASS
7 select LEDS_TRIGGERS
8 select MAC80211_LEDS
9 ---help--- 5 ---help---
10 Select to build the driver supporting the: 6 Select to build the driver supporting the:
11 7
@@ -43,6 +39,14 @@ config IWLWIFI
43 say M here and read <file:Documentation/kbuild/modules.txt>. The 39 say M here and read <file:Documentation/kbuild/modules.txt>. The
44 module will be called iwlwifi. 40 module will be called iwlwifi.
45 41
42config IWLWIFI_LEDS
43 bool
44 depends on IWLWIFI
45 depends on LEDS_CLASS
46 select LEDS_TRIGGERS
47 select MAC80211_LEDS
48 default y
49
46config IWLDVM 50config IWLDVM
47 tristate "Intel Wireless WiFi DVM Firmware support" 51 tristate "Intel Wireless WiFi DVM Firmware support"
48 depends on IWLWIFI 52 depends on IWLWIFI
diff --git a/drivers/net/wireless/iwlwifi/dvm/Makefile b/drivers/net/wireless/iwlwifi/dvm/Makefile
index dce7ab2e0c4b..4d19685f31c3 100644
--- a/drivers/net/wireless/iwlwifi/dvm/Makefile
+++ b/drivers/net/wireless/iwlwifi/dvm/Makefile
@@ -4,9 +4,10 @@ iwldvm-objs += main.o rs.o mac80211.o ucode.o tx.o
4iwldvm-objs += lib.o calib.o tt.o sta.o rx.o 4iwldvm-objs += lib.o calib.o tt.o sta.o rx.o
5 5
6iwldvm-objs += power.o 6iwldvm-objs += power.o
7iwldvm-objs += scan.o led.o 7iwldvm-objs += scan.o
8iwldvm-objs += rxon.o devices.o 8iwldvm-objs += rxon.o devices.o
9 9
10iwldvm-$(CONFIG_IWLWIFI_LEDS) += led.o
10iwldvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o 11iwldvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o
11 12
12ccflags-y += -D__CHECK_ENDIAN__ -I$(src)/../ 13ccflags-y += -D__CHECK_ENDIAN__ -I$(src)/../
diff --git a/drivers/net/wireless/iwlwifi/dvm/dev.h b/drivers/net/wireless/iwlwifi/dvm/dev.h
index 3441f70d0ff9..a6f22c32a279 100644
--- a/drivers/net/wireless/iwlwifi/dvm/dev.h
+++ b/drivers/net/wireless/iwlwifi/dvm/dev.h
@@ -888,9 +888,11 @@ struct iwl_priv {
888 888
889 struct iwl_event_log event_log; 889 struct iwl_event_log event_log;
890 890
891#ifdef CONFIG_IWLWIFI_LEDS
891 struct led_classdev led; 892 struct led_classdev led;
892 unsigned long blink_on, blink_off; 893 unsigned long blink_on, blink_off;
893 bool led_registered; 894 bool led_registered;
895#endif
894 896
895 /* WoWLAN GTK rekey data */ 897 /* WoWLAN GTK rekey data */
896 u8 kck[NL80211_KCK_LEN], kek[NL80211_KEK_LEN]; 898 u8 kck[NL80211_KCK_LEN], kek[NL80211_KEK_LEN];
diff --git a/drivers/net/wireless/iwlwifi/dvm/led.h b/drivers/net/wireless/iwlwifi/dvm/led.h
index 6a0817d9c4fa..1c6b2252d0f2 100644
--- a/drivers/net/wireless/iwlwifi/dvm/led.h
+++ b/drivers/net/wireless/iwlwifi/dvm/led.h
@@ -36,8 +36,20 @@ struct iwl_priv;
36#define IWL_LED_ACTIVITY (0<<1) 36#define IWL_LED_ACTIVITY (0<<1)
37#define IWL_LED_LINK (1<<1) 37#define IWL_LED_LINK (1<<1)
38 38
39#ifdef CONFIG_IWLWIFI_LEDS
39void iwlagn_led_enable(struct iwl_priv *priv); 40void iwlagn_led_enable(struct iwl_priv *priv);
40void iwl_leds_init(struct iwl_priv *priv); 41void iwl_leds_init(struct iwl_priv *priv);
41void iwl_leds_exit(struct iwl_priv *priv); 42void iwl_leds_exit(struct iwl_priv *priv);
43#else
44static inline void iwlagn_led_enable(struct iwl_priv *priv)
45{
46}
47static inline void iwl_leds_init(struct iwl_priv *priv)
48{
49}
50static inline void iwl_leds_exit(struct iwl_priv *priv)
51{
52}
53#endif
42 54
43#endif /* __iwl_leds_h__ */ 55#endif /* __iwl_leds_h__ */
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
index d3abc15125d6..29af7b51e370 100644
--- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
@@ -1091,7 +1091,8 @@ static void iwlagn_configure_filter(struct ieee80211_hw *hw,
1091 FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL; 1091 FIF_BCN_PRBRESP_PROMISC | FIF_CONTROL;
1092} 1092}
1093 1093
1094static void iwlagn_mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop) 1094static void iwlagn_mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1095 u32 queues, bool drop)
1095{ 1096{
1096 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); 1097 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
1097 1098
diff --git a/drivers/net/wireless/iwlwifi/iwl-7000.c b/drivers/net/wireless/iwlwifi/iwl-7000.c
index f73de239cdc1..48730064da73 100644
--- a/drivers/net/wireless/iwlwifi/iwl-7000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-7000.c
@@ -98,7 +98,7 @@
98#define NVM_HW_SECTION_NUM_FAMILY_7000 0 98#define NVM_HW_SECTION_NUM_FAMILY_7000 0
99 99
100static const struct iwl_base_params iwl7000_base_params = { 100static const struct iwl_base_params iwl7000_base_params = {
101 .eeprom_size = OTP_LOW_IMAGE_SIZE, 101 .eeprom_size = OTP_LOW_IMAGE_SIZE_FAMILY_7000,
102 .num_of_queues = IWLAGN_NUM_QUEUES, 102 .num_of_queues = IWLAGN_NUM_QUEUES,
103 .pll_cfg_val = 0, 103 .pll_cfg_val = 0,
104 .shadow_ram_support = true, 104 .shadow_ram_support = true,
diff --git a/drivers/net/wireless/iwlwifi/iwl-8000.c b/drivers/net/wireless/iwlwifi/iwl-8000.c
index f5bd82b88592..b26b68ce8205 100644
--- a/drivers/net/wireless/iwlwifi/iwl-8000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-8000.c
@@ -85,7 +85,7 @@
85#define NVM_HW_SECTION_NUM_FAMILY_8000 10 85#define NVM_HW_SECTION_NUM_FAMILY_8000 10
86 86
87static const struct iwl_base_params iwl8000_base_params = { 87static const struct iwl_base_params iwl8000_base_params = {
88 .eeprom_size = OTP_LOW_IMAGE_SIZE, 88 .eeprom_size = OTP_LOW_IMAGE_SIZE_FAMILY_8000,
89 .num_of_queues = IWLAGN_NUM_QUEUES, 89 .num_of_queues = IWLAGN_NUM_QUEUES,
90 .pll_cfg_val = 0, 90 .pll_cfg_val = 0,
91 .shadow_ram_support = true, 91 .shadow_ram_support = true,
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h
index 7f37fb86837b..04a483d38659 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn-hw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-agn-hw.h
@@ -102,9 +102,7 @@
102 102
103/* EEPROM */ 103/* EEPROM */
104#define IWLAGN_EEPROM_IMG_SIZE 2048 104#define IWLAGN_EEPROM_IMG_SIZE 2048
105/* OTP */ 105
106/* lower blocks contain EEPROM image and calibration data */
107#define OTP_LOW_IMAGE_SIZE (2 * 512 * sizeof(u16)) /* 2 KB */
108/* high blocks contain PAPD data */ 106/* high blocks contain PAPD data */
109#define OTP_HIGH_IMAGE_SIZE_6x00 (6 * 512 * sizeof(u16)) /* 6 KB */ 107#define OTP_HIGH_IMAGE_SIZE_6x00 (6 * 512 * sizeof(u16)) /* 6 KB */
110#define OTP_HIGH_IMAGE_SIZE_1000 (0x200 * sizeof(u16)) /* 1024 bytes */ 108#define OTP_HIGH_IMAGE_SIZE_1000 (0x200 * sizeof(u16)) /* 1024 bytes */
diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h
index 7ce82d9c7222..97f23d6e480b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/iwlwifi/iwl-config.h
@@ -193,6 +193,11 @@ struct iwl_ht_params {
193#define EEPROM_6000_REG_BAND_24_HT40_CHANNELS 0x80 193#define EEPROM_6000_REG_BAND_24_HT40_CHANNELS 0x80
194#define EEPROM_REGULATORY_BAND_NO_HT40 0 194#define EEPROM_REGULATORY_BAND_NO_HT40 0
195 195
196/* lower blocks contain EEPROM image and calibration data */
197#define OTP_LOW_IMAGE_SIZE (2 * 512 * sizeof(u16)) /* 2 KB */
198#define OTP_LOW_IMAGE_SIZE_FAMILY_7000 (4 * 512 * sizeof(u16)) /* 4 KB */
199#define OTP_LOW_IMAGE_SIZE_FAMILY_8000 (32 * 512 * sizeof(u16)) /* 32 KB */
200
196struct iwl_eeprom_params { 201struct iwl_eeprom_params {
197 const u8 regulatory_bands[7]; 202 const u8 regulatory_bands[7];
198 bool enhanced_txpower; 203 bool enhanced_txpower;
@@ -269,6 +274,7 @@ struct iwl_cfg {
269 u8 nvm_hw_section_num; 274 u8 nvm_hw_section_num;
270 bool lp_xtal_workaround; 275 bool lp_xtal_workaround;
271 const struct iwl_pwr_tx_backoff *pwr_tx_backoffs; 276 const struct iwl_pwr_tx_backoff *pwr_tx_backoffs;
277 bool no_power_up_nic_in_init;
272}; 278};
273 279
274/* 280/*
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-error-dump.h b/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
index f381908be7e5..2953ffceda38 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-error-dump.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw-error-dump.h
@@ -72,11 +72,14 @@
72 * @IWL_FW_ERROR_DUMP_SRAM: 72 * @IWL_FW_ERROR_DUMP_SRAM:
73 * @IWL_FW_ERROR_DUMP_REG: 73 * @IWL_FW_ERROR_DUMP_REG:
74 * @IWL_FW_ERROR_DUMP_RXF: 74 * @IWL_FW_ERROR_DUMP_RXF:
75 * @IWL_FW_ERROR_DUMP_TXCMD: last TX command data, structured as
76 * &struct iwl_fw_error_dump_txcmd packets
75 */ 77 */
76enum iwl_fw_error_dump_type { 78enum iwl_fw_error_dump_type {
77 IWL_FW_ERROR_DUMP_SRAM = 0, 79 IWL_FW_ERROR_DUMP_SRAM = 0,
78 IWL_FW_ERROR_DUMP_REG = 1, 80 IWL_FW_ERROR_DUMP_REG = 1,
79 IWL_FW_ERROR_DUMP_RXF = 2, 81 IWL_FW_ERROR_DUMP_RXF = 2,
82 IWL_FW_ERROR_DUMP_TXCMD = 3,
80 83
81 IWL_FW_ERROR_DUMP_MAX, 84 IWL_FW_ERROR_DUMP_MAX,
82}; 85};
@@ -105,4 +108,27 @@ struct iwl_fw_error_dump_file {
105 u8 data[0]; 108 u8 data[0];
106} __packed; 109} __packed;
107 110
111/**
112 * struct iwl_fw_error_dump_txcmd - TX command data
113 * @cmdlen: original length of command
114 * @caplen: captured length of command (may be less)
115 * @data: captured command data, @caplen bytes
116 */
117struct iwl_fw_error_dump_txcmd {
118 __le32 cmdlen;
119 __le32 caplen;
120 u8 data[];
121} __packed;
122
123/**
124 * iwl_mvm_fw_error_next_data - advance fw error dump data pointer
125 * @data: previous data block
126 * Returns: next data block
127 */
128static inline struct iwl_fw_error_dump_data *
129iwl_mvm_fw_error_next_data(struct iwl_fw_error_dump_data *data)
130{
131 return (void *)(data->data + le32_to_cpu(data->len));
132}
133
108#endif /* __fw_error_dump_h__ */ 134#endif /* __fw_error_dump_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h
index f5927d0cf9b6..6fea27c0dd8e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw.h
@@ -116,9 +116,11 @@ enum iwl_ucode_tlv_flag {
116/** 116/**
117 * enum iwl_ucode_tlv_api - ucode api 117 * enum iwl_ucode_tlv_api - ucode api
118 * @IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID: wowlan config includes tid field. 118 * @IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID: wowlan config includes tid field.
119 * @IWL_UCODE_TLV_API_CSA_FLOW: ucode can do unbind-bind flow for CSA.
119 */ 120 */
120enum iwl_ucode_tlv_api { 121enum iwl_ucode_tlv_api {
121 IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID = BIT(0), 122 IWL_UCODE_TLV_API_WOWLAN_CONFIG_TID = BIT(0),
123 IWL_UCODE_TLV_API_CSA_FLOW = BIT(4),
122}; 124};
123 125
124/** 126/**
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
index 4049c0d626ba..49963e4a887e 100644
--- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
@@ -62,6 +62,7 @@
62#include <linux/types.h> 62#include <linux/types.h>
63#include <linux/slab.h> 63#include <linux/slab.h>
64#include <linux/export.h> 64#include <linux/export.h>
65#include <linux/etherdevice.h>
65#include "iwl-drv.h" 66#include "iwl-drv.h"
66#include "iwl-modparams.h" 67#include "iwl-modparams.h"
67#include "iwl-nvm-parse.h" 68#include "iwl-nvm-parse.h"
@@ -450,13 +451,7 @@ static void iwl_set_hw_address(const struct iwl_cfg *cfg,
450 struct iwl_nvm_data *data, 451 struct iwl_nvm_data *data,
451 const __le16 *nvm_sec) 452 const __le16 *nvm_sec)
452{ 453{
453 u8 hw_addr[ETH_ALEN]; 454 const u8 *hw_addr = (const u8 *)(nvm_sec + HW_ADDR);
454
455 if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
456 memcpy(hw_addr, nvm_sec + HW_ADDR, ETH_ALEN);
457 else
458 memcpy(hw_addr, nvm_sec + MAC_ADDRESS_OVERRIDE_FAMILY_8000,
459 ETH_ALEN);
460 455
461 /* The byte order is little endian 16 bit, meaning 214365 */ 456 /* The byte order is little endian 16 bit, meaning 214365 */
462 data->hw_addr[0] = hw_addr[1]; 457 data->hw_addr[0] = hw_addr[1];
@@ -467,6 +462,41 @@ static void iwl_set_hw_address(const struct iwl_cfg *cfg,
467 data->hw_addr[5] = hw_addr[4]; 462 data->hw_addr[5] = hw_addr[4];
468} 463}
469 464
465static void iwl_set_hw_address_family_8000(const struct iwl_cfg *cfg,
466 struct iwl_nvm_data *data,
467 const __le16 *mac_override,
468 const __le16 *nvm_hw)
469{
470 const u8 *hw_addr;
471
472 if (mac_override) {
473 hw_addr = (const u8 *)(mac_override +
474 MAC_ADDRESS_OVERRIDE_FAMILY_8000);
475
476 /* The byte order is little endian 16 bit, meaning 214365 */
477 data->hw_addr[0] = hw_addr[1];
478 data->hw_addr[1] = hw_addr[0];
479 data->hw_addr[2] = hw_addr[3];
480 data->hw_addr[3] = hw_addr[2];
481 data->hw_addr[4] = hw_addr[5];
482 data->hw_addr[5] = hw_addr[4];
483
484 if (is_valid_ether_addr(hw_addr))
485 return;
486 }
487
488 /* take the MAC address from the OTP */
489 hw_addr = (const u8 *)(nvm_hw + HW_ADDR0_FAMILY_8000);
490 data->hw_addr[0] = hw_addr[3];
491 data->hw_addr[1] = hw_addr[2];
492 data->hw_addr[2] = hw_addr[1];
493 data->hw_addr[3] = hw_addr[0];
494
495 hw_addr = (const u8 *)(nvm_hw + HW_ADDR1_FAMILY_8000);
496 data->hw_addr[4] = hw_addr[1];
497 data->hw_addr[5] = hw_addr[0];
498}
499
470struct iwl_nvm_data * 500struct iwl_nvm_data *
471iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg, 501iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
472 const __le16 *nvm_hw, const __le16 *nvm_sw, 502 const __le16 *nvm_hw, const __le16 *nvm_sw,
@@ -526,7 +556,7 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
526 rx_chains); 556 rx_chains);
527 } else { 557 } else {
528 /* MAC address in family 8000 */ 558 /* MAC address in family 8000 */
529 iwl_set_hw_address(cfg, data, mac_override); 559 iwl_set_hw_address_family_8000(cfg, data, mac_override, nvm_hw);
530 560
531 iwl_init_sbands(dev, cfg, data, regulatory, 561 iwl_init_sbands(dev, cfg, data, regulatory,
532 sku & NVM_SKU_CAP_11AC_ENABLE, tx_chains, 562 sku & NVM_SKU_CAP_11AC_ENABLE, tx_chains,
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index 22fd94ec8048..84ad48de6e29 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -463,6 +463,11 @@ struct iwl_trans;
463 * @unref: release a reference previously taken with @ref. Note that 463 * @unref: release a reference previously taken with @ref. Note that
464 * initially the reference count is 1, making an initial @unref 464 * initially the reference count is 1, making an initial @unref
465 * necessary to allow low power states. 465 * necessary to allow low power states.
466 * @dump_data: fill a data dump with debug data, maybe containing last
467 * TX'ed commands and similar. When called with a NULL buffer and
468 * zero buffer length, provide only the (estimated) required buffer
469 * length. Return the used buffer length.
470 * Note that the transport must fill in the proper file headers.
466 */ 471 */
467struct iwl_trans_ops { 472struct iwl_trans_ops {
468 473
@@ -511,6 +516,10 @@ struct iwl_trans_ops {
511 u32 value); 516 u32 value);
512 void (*ref)(struct iwl_trans *trans); 517 void (*ref)(struct iwl_trans *trans);
513 void (*unref)(struct iwl_trans *trans); 518 void (*unref)(struct iwl_trans *trans);
519
520#ifdef CONFIG_IWLWIFI_DEBUGFS
521 u32 (*dump_data)(struct iwl_trans *trans, void *buf, u32 buflen);
522#endif
514}; 523};
515 524
516/** 525/**
@@ -664,6 +673,16 @@ static inline void iwl_trans_unref(struct iwl_trans *trans)
664 trans->ops->unref(trans); 673 trans->ops->unref(trans);
665} 674}
666 675
676#ifdef CONFIG_IWLWIFI_DEBUGFS
677static inline u32 iwl_trans_dump_data(struct iwl_trans *trans,
678 void *buf, u32 buflen)
679{
680 if (!trans->ops->dump_data)
681 return 0;
682 return trans->ops->dump_data(trans, buf, buflen);
683}
684#endif
685
667static inline int iwl_trans_send_cmd(struct iwl_trans *trans, 686static inline int iwl_trans_send_cmd(struct iwl_trans *trans,
668 struct iwl_host_cmd *cmd) 687 struct iwl_host_cmd *cmd)
669{ 688{
diff --git a/drivers/net/wireless/iwlwifi/mvm/Makefile b/drivers/net/wireless/iwlwifi/mvm/Makefile
index ccdd3b7c4cce..c30d7f64ec1e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/Makefile
+++ b/drivers/net/wireless/iwlwifi/mvm/Makefile
@@ -3,8 +3,9 @@ iwlmvm-y += fw.o mac80211.o nvm.o ops.o phy-ctxt.o mac-ctxt.o
3iwlmvm-y += utils.o rx.o tx.o binding.o quota.o sta.o sf.o 3iwlmvm-y += utils.o rx.o tx.o binding.o quota.o sta.o sf.o
4iwlmvm-y += scan.o time-event.o rs.o 4iwlmvm-y += scan.o time-event.o rs.o
5iwlmvm-y += power.o coex.o 5iwlmvm-y += power.o coex.o
6iwlmvm-y += led.o tt.o offloading.o 6iwlmvm-y += tt.o offloading.o
7iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o debugfs-vif.o 7iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o debugfs-vif.o
8iwlmvm-$(CONFIG_IWLWIFI_LEDS) += led.o
8iwlmvm-$(CONFIG_PM_SLEEP) += d3.o 9iwlmvm-$(CONFIG_PM_SLEEP) += d3.o
9 10
10ccflags-y += -D__CHECK_ENDIAN__ -I$(src)/../ 11ccflags-y += -D__CHECK_ENDIAN__ -I$(src)/../
diff --git a/drivers/net/wireless/iwlwifi/mvm/coex.c b/drivers/net/wireless/iwlwifi/mvm/coex.c
index 8f4b03dbaf3f..4284672d0397 100644
--- a/drivers/net/wireless/iwlwifi/mvm/coex.c
+++ b/drivers/net/wireless/iwlwifi/mvm/coex.c
@@ -611,14 +611,14 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
611 bt_cmd->flags |= cpu_to_le32(BT_COEX_SYNC2SCO); 611 bt_cmd->flags |= cpu_to_le32(BT_COEX_SYNC2SCO);
612 612
613 if (IWL_MVM_BT_COEX_CORUNNING) { 613 if (IWL_MVM_BT_COEX_CORUNNING) {
614 bt_cmd->valid_bit_msk = cpu_to_le32(BT_VALID_CORUN_LUT_20 | 614 bt_cmd->valid_bit_msk |= cpu_to_le32(BT_VALID_CORUN_LUT_20 |
615 BT_VALID_CORUN_LUT_40); 615 BT_VALID_CORUN_LUT_40);
616 bt_cmd->flags |= cpu_to_le32(BT_COEX_CORUNNING); 616 bt_cmd->flags |= cpu_to_le32(BT_COEX_CORUNNING);
617 } 617 }
618 618
619 if (IWL_MVM_BT_COEX_MPLUT) { 619 if (IWL_MVM_BT_COEX_MPLUT) {
620 bt_cmd->flags |= cpu_to_le32(BT_COEX_MPLUT); 620 bt_cmd->flags |= cpu_to_le32(BT_COEX_MPLUT);
621 bt_cmd->valid_bit_msk = cpu_to_le32(BT_VALID_MULTI_PRIO_LUT); 621 bt_cmd->valid_bit_msk |= cpu_to_le32(BT_VALID_MULTI_PRIO_LUT);
622 } 622 }
623 623
624 if (mvm->cfg->bt_shared_single_ant) 624 if (mvm->cfg->bt_shared_single_ant)
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
index f462c9baa2b5..bef487bb880e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
@@ -67,7 +67,7 @@
67#include "iwl-io.h" 67#include "iwl-io.h"
68#include "iwl-prph.h" 68#include "iwl-prph.h"
69#include "debugfs.h" 69#include "debugfs.h"
70#include "fw-error-dump.h" 70#include "iwl-fw-error-dump.h"
71 71
72static ssize_t iwl_dbgfs_tx_flush_write(struct iwl_mvm *mvm, char *buf, 72static ssize_t iwl_dbgfs_tx_flush_write(struct iwl_mvm *mvm, char *buf,
73 size_t count, loff_t *ppos) 73 size_t count, loff_t *ppos)
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
index 6174c027ff59..6959fda3fe09 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-scan.h
@@ -187,9 +187,9 @@ enum iwl_scan_type {
187 * this number of packets were received (typically 1) 187 * this number of packets were received (typically 1)
188 * @passive2active: is auto switching from passive to active during scan allowed 188 * @passive2active: is auto switching from passive to active during scan allowed
189 * @rxchain_sel_flags: RXON_RX_CHAIN_* 189 * @rxchain_sel_flags: RXON_RX_CHAIN_*
190 * @max_out_time: in usecs, max out of serving channel time 190 * @max_out_time: in TUs, max out of serving channel time
191 * @suspend_time: how long to pause scan when returning to service channel: 191 * @suspend_time: how long to pause scan when returning to service channel:
192 * bits 0-19: beacon interal in usecs (suspend before executing) 192 * bits 0-19: beacon interal in TUs (suspend before executing)
193 * bits 20-23: reserved 193 * bits 20-23: reserved
194 * bits 24-31: number of beacons (suspend between channels) 194 * bits 24-31: number of beacons (suspend between channels)
195 * @rxon_flags: RXON_FLG_* 195 * @rxon_flags: RXON_FLG_*
@@ -387,8 +387,8 @@ enum scan_framework_client {
387 * @quiet_plcp_th: quiet channel num of packets threshold 387 * @quiet_plcp_th: quiet channel num of packets threshold
388 * @good_CRC_th: passive to active promotion threshold 388 * @good_CRC_th: passive to active promotion threshold
389 * @rx_chain: RXON rx chain. 389 * @rx_chain: RXON rx chain.
390 * @max_out_time: max uSec to be out of assoceated channel 390 * @max_out_time: max TUs to be out of assoceated channel
391 * @suspend_time: pause scan this long when returning to service channel 391 * @suspend_time: pause scan this TUs when returning to service channel
392 * @flags: RXON flags 392 * @flags: RXON flags
393 * @filter_flags: RXONfilter 393 * @filter_flags: RXONfilter
394 * @tx_cmd: tx command for active scan; for 2GHz and for 5GHz. 394 * @tx_cmd: tx command for active scan; for 2GHz and for 5GHz.
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c
index 3d99cf564ba6..34ae3f32b300 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/iwlwifi/mvm/fw.c
@@ -295,7 +295,7 @@ int iwl_run_init_mvm_ucode(struct iwl_mvm *mvm, bool read_nvm)
295 /* Read the NVM only at driver load time, no need to do this twice */ 295 /* Read the NVM only at driver load time, no need to do this twice */
296 if (read_nvm) { 296 if (read_nvm) {
297 /* Read nvm */ 297 /* Read nvm */
298 ret = iwl_nvm_init(mvm); 298 ret = iwl_nvm_init(mvm, true);
299 if (ret) { 299 if (ret) {
300 IWL_ERR(mvm, "Failed to read NVM: %d\n", ret); 300 IWL_ERR(mvm, "Failed to read NVM: %d\n", ret);
301 goto error; 301 goto error;
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
index 7110ec2605d6..56cf58e95698 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
@@ -1237,11 +1237,23 @@ int iwl_mvm_rx_beacon_notif(struct iwl_mvm *mvm,
1237 u32 rate __maybe_unused = 1237 u32 rate __maybe_unused =
1238 le32_to_cpu(beacon->beacon_notify_hdr.initial_rate); 1238 le32_to_cpu(beacon->beacon_notify_hdr.initial_rate);
1239 1239
1240 lockdep_assert_held(&mvm->mutex);
1241
1240 IWL_DEBUG_RX(mvm, "beacon status %#x retries:%d tsf:0x%16llX rate:%d\n", 1242 IWL_DEBUG_RX(mvm, "beacon status %#x retries:%d tsf:0x%16llX rate:%d\n",
1241 status & TX_STATUS_MSK, 1243 status & TX_STATUS_MSK,
1242 beacon->beacon_notify_hdr.failure_frame, 1244 beacon->beacon_notify_hdr.failure_frame,
1243 le64_to_cpu(beacon->tsf), 1245 le64_to_cpu(beacon->tsf),
1244 rate); 1246 rate);
1247
1248 if (unlikely(mvm->csa_vif && mvm->csa_vif->csa_active)) {
1249 if (!ieee80211_csa_is_complete(mvm->csa_vif)) {
1250 iwl_mvm_mac_ctxt_beacon_changed(mvm, mvm->csa_vif);
1251 } else {
1252 ieee80211_csa_finish(mvm->csa_vif);
1253 mvm->csa_vif = NULL;
1254 }
1255 }
1256
1245 return 0; 1257 return 0;
1246} 1258}
1247 1259
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index 97c3deae6552..f20cbd06a49f 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -320,6 +320,9 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
320 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_GO_UAPSD) 320 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_GO_UAPSD)
321 hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD; 321 hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
322 322
323 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_CSA_FLOW)
324 hw->wiphy->flags |= WIPHY_FLAG_HAS_CHANNEL_SWITCH;
325
323 hw->wiphy->iface_combinations = iwl_mvm_iface_combinations; 326 hw->wiphy->iface_combinations = iwl_mvm_iface_combinations;
324 hw->wiphy->n_iface_combinations = 327 hw->wiphy->n_iface_combinations =
325 ARRAY_SIZE(iwl_mvm_iface_combinations); 328 ARRAY_SIZE(iwl_mvm_iface_combinations);
@@ -539,13 +542,22 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
539 return -EACCES; 542 return -EACCES;
540 543
541 /* return from D0i3 before starting a new Tx aggregation */ 544 /* return from D0i3 before starting a new Tx aggregation */
542 if (action == IEEE80211_AMPDU_TX_START) { 545 switch (action) {
546 case IEEE80211_AMPDU_TX_START:
547 case IEEE80211_AMPDU_TX_STOP_CONT:
548 case IEEE80211_AMPDU_TX_STOP_FLUSH:
549 case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT:
550 case IEEE80211_AMPDU_TX_OPERATIONAL:
543 iwl_mvm_ref(mvm, IWL_MVM_REF_TX_AGG); 551 iwl_mvm_ref(mvm, IWL_MVM_REF_TX_AGG);
544 tx_agg_ref = true; 552 tx_agg_ref = true;
545 553
546 /* 554 /*
547 * wait synchronously until D0i3 exit to get the correct 555 * for tx start, wait synchronously until D0i3 exit to
548 * sequence number for the tid 556 * get the correct sequence number for the tid.
557 * additionally, some other ampdu actions use direct
558 * target access, which is not handled automatically
559 * by the trans layer (unlike commands), so wait for
560 * d0i3 exit in these cases as well.
549 */ 561 */
550 if (!wait_event_timeout(mvm->d0i3_exit_waitq, 562 if (!wait_event_timeout(mvm->d0i3_exit_waitq,
551 !test_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status), HZ)) { 563 !test_bit(IWL_MVM_STATUS_IN_D0I3, &mvm->status), HZ)) {
@@ -553,6 +565,9 @@ static int iwl_mvm_mac_ampdu_action(struct ieee80211_hw *hw,
553 iwl_mvm_unref(mvm, IWL_MVM_REF_TX_AGG); 565 iwl_mvm_unref(mvm, IWL_MVM_REF_TX_AGG);
554 return -EIO; 566 return -EIO;
555 } 567 }
568 break;
569 default:
570 break;
556 } 571 }
557 572
558 mutex_lock(&mvm->mutex); 573 mutex_lock(&mvm->mutex);
@@ -1005,7 +1020,7 @@ static void iwl_mvm_mc_iface_iterator(void *_data, u8 *mac,
1005 memcpy(cmd->bssid, vif->bss_conf.bssid, ETH_ALEN); 1020 memcpy(cmd->bssid, vif->bss_conf.bssid, ETH_ALEN);
1006 len = roundup(sizeof(*cmd) + cmd->count * ETH_ALEN, 4); 1021 len = roundup(sizeof(*cmd) + cmd->count * ETH_ALEN, 4);
1007 1022
1008 ret = iwl_mvm_send_cmd_pdu(mvm, MCAST_FILTER_CMD, CMD_SYNC, len, cmd); 1023 ret = iwl_mvm_send_cmd_pdu(mvm, MCAST_FILTER_CMD, CMD_ASYNC, len, cmd);
1009 if (ret) 1024 if (ret)
1010 IWL_ERR(mvm, "mcast filter cmd error. ret=%d\n", ret); 1025 IWL_ERR(mvm, "mcast filter cmd error. ret=%d\n", ret);
1011} 1026}
@@ -1021,7 +1036,7 @@ static void iwl_mvm_recalc_multicast(struct iwl_mvm *mvm)
1021 if (WARN_ON_ONCE(!mvm->mcast_filter_cmd)) 1036 if (WARN_ON_ONCE(!mvm->mcast_filter_cmd))
1022 return; 1037 return;
1023 1038
1024 ieee80211_iterate_active_interfaces( 1039 ieee80211_iterate_active_interfaces_atomic(
1025 mvm->hw, IEEE80211_IFACE_ITER_NORMAL, 1040 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
1026 iwl_mvm_mc_iface_iterator, &iter_data); 1041 iwl_mvm_mc_iface_iterator, &iter_data);
1027} 1042}
@@ -1814,6 +1829,11 @@ static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw,
1814 1829
1815 mutex_lock(&mvm->mutex); 1830 mutex_lock(&mvm->mutex);
1816 1831
1832 if (!iwl_mvm_is_idle(mvm)) {
1833 ret = -EBUSY;
1834 goto out;
1835 }
1836
1817 switch (mvm->scan_status) { 1837 switch (mvm->scan_status) {
1818 case IWL_MVM_SCAN_OS: 1838 case IWL_MVM_SCAN_OS:
1819 IWL_DEBUG_SCAN(mvm, "Stopping previous scan for sched_scan\n"); 1839 IWL_DEBUG_SCAN(mvm, "Stopping previous scan for sched_scan\n");
@@ -2186,6 +2206,11 @@ static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
2186 2206
2187 switch (vif->type) { 2207 switch (vif->type) {
2188 case NL80211_IFTYPE_AP: 2208 case NL80211_IFTYPE_AP:
2209 /* Unless it's a CSA flow we have nothing to do here */
2210 if (vif->csa_active) {
2211 mvmvif->ap_ibss_active = true;
2212 break;
2213 }
2189 case NL80211_IFTYPE_ADHOC: 2214 case NL80211_IFTYPE_ADHOC:
2190 /* 2215 /*
2191 * The AP binding flow is handled as part of the start_ap flow 2216 * The AP binding flow is handled as part of the start_ap flow
@@ -2222,6 +2247,12 @@ static int iwl_mvm_assign_vif_chanctx(struct ieee80211_hw *hw,
2222 goto out_remove_binding; 2247 goto out_remove_binding;
2223 } 2248 }
2224 2249
2250 /* Handle binding during CSA */
2251 if (vif->type == NL80211_IFTYPE_AP) {
2252 iwl_mvm_update_quotas(mvm, vif);
2253 iwl_mvm_mac_ctxt_changed(mvm, vif);
2254 }
2255
2225 goto out_unlock; 2256 goto out_unlock;
2226 2257
2227 out_remove_binding: 2258 out_remove_binding:
@@ -2246,13 +2277,20 @@ static void iwl_mvm_unassign_vif_chanctx(struct ieee80211_hw *hw,
2246 iwl_mvm_remove_time_event(mvm, mvmvif, &mvmvif->time_event_data); 2277 iwl_mvm_remove_time_event(mvm, mvmvif, &mvmvif->time_event_data);
2247 2278
2248 switch (vif->type) { 2279 switch (vif->type) {
2249 case NL80211_IFTYPE_AP:
2250 case NL80211_IFTYPE_ADHOC: 2280 case NL80211_IFTYPE_ADHOC:
2251 goto out_unlock; 2281 goto out_unlock;
2252 case NL80211_IFTYPE_MONITOR: 2282 case NL80211_IFTYPE_MONITOR:
2253 mvmvif->monitor_active = false; 2283 mvmvif->monitor_active = false;
2254 iwl_mvm_update_quotas(mvm, NULL); 2284 iwl_mvm_update_quotas(mvm, NULL);
2255 break; 2285 break;
2286 case NL80211_IFTYPE_AP:
2287 /* This part is triggered only during CSA */
2288 if (!vif->csa_active || !mvmvif->ap_ibss_active)
2289 goto out_unlock;
2290
2291 mvmvif->ap_ibss_active = false;
2292 iwl_mvm_update_quotas(mvm, NULL);
2293 /*TODO: bt_coex notification here? */
2256 default: 2294 default:
2257 break; 2295 break;
2258 } 2296 }
@@ -2348,6 +2386,53 @@ static int iwl_mvm_mac_testmode_cmd(struct ieee80211_hw *hw,
2348} 2386}
2349#endif 2387#endif
2350 2388
2389static void iwl_mvm_channel_switch_beacon(struct ieee80211_hw *hw,
2390 struct ieee80211_vif *vif,
2391 struct cfg80211_chan_def *chandef)
2392{
2393 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
2394
2395 mutex_lock(&mvm->mutex);
2396 if (WARN(mvm->csa_vif && mvm->csa_vif->csa_active,
2397 "Another CSA is already in progress"))
2398 goto out_unlock;
2399
2400 IWL_DEBUG_MAC80211(mvm, "CSA started to freq %d\n",
2401 chandef->center_freq1);
2402 mvm->csa_vif = vif;
2403
2404out_unlock:
2405 mutex_unlock(&mvm->mutex);
2406}
2407
2408static void iwl_mvm_mac_flush(struct ieee80211_hw *hw,
2409 struct ieee80211_vif *vif, u32 queues, bool drop)
2410{
2411 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
2412 struct iwl_mvm_vif *mvmvif;
2413 struct iwl_mvm_sta *mvmsta;
2414
2415 if (!vif || vif->type != NL80211_IFTYPE_STATION)
2416 return;
2417
2418 mutex_lock(&mvm->mutex);
2419 mvmvif = iwl_mvm_vif_from_mac80211(vif);
2420 mvmsta = iwl_mvm_sta_from_staid_protected(mvm, mvmvif->ap_sta_id);
2421
2422 if (WARN_ON_ONCE(!mvmsta))
2423 goto done;
2424
2425 if (drop) {
2426 if (iwl_mvm_flush_tx_path(mvm, mvmsta->tfd_queue_msk, true))
2427 IWL_ERR(mvm, "flush request fail\n");
2428 } else {
2429 iwl_trans_wait_tx_queue_empty(mvm->trans,
2430 mvmsta->tfd_queue_msk);
2431 }
2432done:
2433 mutex_unlock(&mvm->mutex);
2434}
2435
2351const struct ieee80211_ops iwl_mvm_hw_ops = { 2436const struct ieee80211_ops iwl_mvm_hw_ops = {
2352 .tx = iwl_mvm_mac_tx, 2437 .tx = iwl_mvm_mac_tx,
2353 .ampdu_action = iwl_mvm_mac_ampdu_action, 2438 .ampdu_action = iwl_mvm_mac_ampdu_action,
@@ -2371,6 +2456,7 @@ const struct ieee80211_ops iwl_mvm_hw_ops = {
2371 .sta_rc_update = iwl_mvm_sta_rc_update, 2456 .sta_rc_update = iwl_mvm_sta_rc_update,
2372 .conf_tx = iwl_mvm_mac_conf_tx, 2457 .conf_tx = iwl_mvm_mac_conf_tx,
2373 .mgd_prepare_tx = iwl_mvm_mac_mgd_prepare_tx, 2458 .mgd_prepare_tx = iwl_mvm_mac_mgd_prepare_tx,
2459 .flush = iwl_mvm_mac_flush,
2374 .sched_scan_start = iwl_mvm_mac_sched_scan_start, 2460 .sched_scan_start = iwl_mvm_mac_sched_scan_start,
2375 .sched_scan_stop = iwl_mvm_mac_sched_scan_stop, 2461 .sched_scan_stop = iwl_mvm_mac_sched_scan_stop,
2376 .set_key = iwl_mvm_mac_set_key, 2462 .set_key = iwl_mvm_mac_set_key,
@@ -2390,6 +2476,8 @@ const struct ieee80211_ops iwl_mvm_hw_ops = {
2390 2476
2391 .set_tim = iwl_mvm_set_tim, 2477 .set_tim = iwl_mvm_set_tim,
2392 2478
2479 .channel_switch_beacon = iwl_mvm_channel_switch_beacon,
2480
2393 CFG80211_TESTMODE_CMD(iwl_mvm_mac_testmode_cmd) 2481 CFG80211_TESTMODE_CMD(iwl_mvm_mac_testmode_cmd)
2394 2482
2395#ifdef CONFIG_PM_SLEEP 2483#ifdef CONFIG_PM_SLEEP
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index 17c42da5f9f2..8747d03311f3 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -589,7 +589,9 @@ struct iwl_mvm {
589 u32 *fw_error_rxf; 589 u32 *fw_error_rxf;
590 u32 fw_error_rxf_len; 590 u32 fw_error_rxf_len;
591 591
592#ifdef CONFIG_IWLWIFI_LEDS
592 struct led_classdev led; 593 struct led_classdev led;
594#endif
593 595
594 struct ieee80211_vif *p2p_device_vif; 596 struct ieee80211_vif *p2p_device_vif;
595 597
@@ -642,6 +644,8 @@ struct iwl_mvm {
642 644
643 /* Indicate if device power save is allowed */ 645 /* Indicate if device power save is allowed */
644 bool ps_disabled; 646 bool ps_disabled;
647
648 struct ieee80211_vif *csa_vif;
645}; 649};
646 650
647/* Extract MVM priv from op_mode and _hw */ 651/* Extract MVM priv from op_mode and _hw */
@@ -757,7 +761,7 @@ int iwl_mvm_rx_statistics(struct iwl_mvm *mvm,
757 struct iwl_device_cmd *cmd); 761 struct iwl_device_cmd *cmd);
758 762
759/* NVM */ 763/* NVM */
760int iwl_nvm_init(struct iwl_mvm *mvm); 764int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic);
761int iwl_mvm_load_nvm_to_nic(struct iwl_mvm *mvm); 765int iwl_mvm_load_nvm_to_nic(struct iwl_mvm *mvm);
762 766
763int iwl_mvm_up(struct iwl_mvm *mvm); 767int iwl_mvm_up(struct iwl_mvm *mvm);
@@ -896,8 +900,18 @@ int iwl_mvm_power_uapsd_misbehaving_ap_notif(struct iwl_mvm *mvm,
896 struct iwl_rx_cmd_buffer *rxb, 900 struct iwl_rx_cmd_buffer *rxb,
897 struct iwl_device_cmd *cmd); 901 struct iwl_device_cmd *cmd);
898 902
903#ifdef CONFIG_IWLWIFI_LEDS
899int iwl_mvm_leds_init(struct iwl_mvm *mvm); 904int iwl_mvm_leds_init(struct iwl_mvm *mvm);
900void iwl_mvm_leds_exit(struct iwl_mvm *mvm); 905void iwl_mvm_leds_exit(struct iwl_mvm *mvm);
906#else
907static inline int iwl_mvm_leds_init(struct iwl_mvm *mvm)
908{
909 return 0;
910}
911static inline void iwl_mvm_leds_exit(struct iwl_mvm *mvm)
912{
913}
914#endif
901 915
902/* D3 (WoWLAN, NetDetect) */ 916/* D3 (WoWLAN, NetDetect) */
903int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan); 917int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan);
@@ -1015,6 +1029,9 @@ static inline bool iwl_mvm_vif_low_latency(struct iwl_mvm_vif *mvmvif)
1015 return mvmvif->low_latency; 1029 return mvmvif->low_latency;
1016} 1030}
1017 1031
1032/* Assoc status */
1033bool iwl_mvm_is_idle(struct iwl_mvm *mvm);
1034
1018/* Thermal management and CT-kill */ 1035/* Thermal management and CT-kill */
1019void iwl_mvm_tt_tx_backoff(struct iwl_mvm *mvm, u32 backoff); 1036void iwl_mvm_tt_tx_backoff(struct iwl_mvm *mvm, u32 backoff);
1020void iwl_mvm_tt_handler(struct iwl_mvm *mvm); 1037void iwl_mvm_tt_handler(struct iwl_mvm *mvm);
diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c
index cf2d09f53782..6b88c29ebe6b 100644
--- a/drivers/net/wireless/iwlwifi/mvm/nvm.c
+++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c
@@ -238,13 +238,20 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm)
238 return NULL; 238 return NULL;
239 } 239 }
240 } else { 240 } else {
241 /* SW and REGULATORY sections are mandatory */
241 if (!mvm->nvm_sections[NVM_SECTION_TYPE_SW].data || 242 if (!mvm->nvm_sections[NVM_SECTION_TYPE_SW].data ||
242 !mvm->nvm_sections[NVM_SECTION_TYPE_MAC_OVERRIDE].data ||
243 !mvm->nvm_sections[NVM_SECTION_TYPE_REGULATORY].data) { 243 !mvm->nvm_sections[NVM_SECTION_TYPE_REGULATORY].data) {
244 IWL_ERR(mvm, 244 IWL_ERR(mvm,
245 "Can't parse empty family 8000 NVM sections\n"); 245 "Can't parse empty family 8000 NVM sections\n");
246 return NULL; 246 return NULL;
247 } 247 }
248 /* MAC_OVERRIDE or at least HW section must exist */
249 if (!mvm->nvm_sections[mvm->cfg->nvm_hw_section_num].data &&
250 !mvm->nvm_sections[NVM_SECTION_TYPE_MAC_OVERRIDE].data) {
251 IWL_ERR(mvm,
252 "Can't parse mac_address, empty sections\n");
253 return NULL;
254 }
248 } 255 }
249 256
250 if (WARN_ON(!mvm->cfg)) 257 if (WARN_ON(!mvm->cfg))
@@ -427,7 +434,7 @@ int iwl_mvm_load_nvm_to_nic(struct iwl_mvm *mvm)
427 return ret; 434 return ret;
428} 435}
429 436
430int iwl_nvm_init(struct iwl_mvm *mvm) 437int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic)
431{ 438{
432 int ret, i, section; 439 int ret, i, section;
433 u8 *nvm_buffer, *temp; 440 u8 *nvm_buffer, *temp;
@@ -437,13 +444,8 @@ int iwl_nvm_init(struct iwl_mvm *mvm)
437 if (WARN_ON_ONCE(mvm->cfg->nvm_hw_section_num >= NVM_MAX_NUM_SECTIONS)) 444 if (WARN_ON_ONCE(mvm->cfg->nvm_hw_section_num >= NVM_MAX_NUM_SECTIONS))
438 return -EINVAL; 445 return -EINVAL;
439 446
440 /* load external NVM if configured */ 447 /* load NVM values from nic */
441 if (iwlwifi_mod_params.nvm_file) { 448 if (read_nvm_from_nic) {
442 /* move to External NVM flow */
443 ret = iwl_mvm_read_external_nvm(mvm);
444 if (ret)
445 return ret;
446 } else {
447 /* list of NVM sections we are allowed/need to read */ 449 /* list of NVM sections we are allowed/need to read */
448 if (mvm->trans->cfg->device_family != IWL_DEVICE_FAMILY_8000) { 450 if (mvm->trans->cfg->device_family != IWL_DEVICE_FAMILY_8000) {
449 nvm_to_read[0] = mvm->cfg->nvm_hw_section_num; 451 nvm_to_read[0] = mvm->cfg->nvm_hw_section_num;
@@ -463,7 +465,6 @@ int iwl_nvm_init(struct iwl_mvm *mvm)
463 /* Read From FW NVM */ 465 /* Read From FW NVM */
464 IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from NVM\n"); 466 IWL_DEBUG_EEPROM(mvm->trans->dev, "Read from NVM\n");
465 467
466 /* TODO: find correct NVM max size for a section */
467 nvm_buffer = kmalloc(mvm->cfg->base_params->eeprom_size, 468 nvm_buffer = kmalloc(mvm->cfg->base_params->eeprom_size,
468 GFP_KERNEL); 469 GFP_KERNEL);
469 if (!nvm_buffer) 470 if (!nvm_buffer)
@@ -511,6 +512,15 @@ int iwl_nvm_init(struct iwl_mvm *mvm)
511 return ret; 512 return ret;
512 } 513 }
513 514
515 /* load external NVM if configured */
516 if (iwlwifi_mod_params.nvm_file) {
517 /* move to External NVM flow */
518 ret = iwl_mvm_read_external_nvm(mvm);
519 if (ret)
520 return ret;
521 }
522
523 /* parse the relevant nvm sections */
514 mvm->nvm_data = iwl_parse_nvm_sections(mvm); 524 mvm->nvm_data = iwl_parse_nvm_sections(mvm);
515 if (!mvm->nvm_data) 525 if (!mvm->nvm_data)
516 return -ENODATA; 526 return -ENODATA;
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index 7a5a8bac5fd0..f8530b329d17 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -79,8 +79,8 @@
79#include "iwl-prph.h" 79#include "iwl-prph.h"
80#include "rs.h" 80#include "rs.h"
81#include "fw-api-scan.h" 81#include "fw-api-scan.h"
82#include "fw-error-dump.h"
83#include "time-event.h" 82#include "time-event.h"
83#include "iwl-fw-error-dump.h"
84 84
85/* 85/*
86 * module name, copyright, version, etc. 86 * module name, copyright, version, etc.
@@ -220,7 +220,7 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
220 RX_HANDLER(BA_NOTIF, iwl_mvm_rx_ba_notif, false), 220 RX_HANDLER(BA_NOTIF, iwl_mvm_rx_ba_notif, false),
221 221
222 RX_HANDLER(BT_PROFILE_NOTIFICATION, iwl_mvm_rx_bt_coex_notif, true), 222 RX_HANDLER(BT_PROFILE_NOTIFICATION, iwl_mvm_rx_bt_coex_notif, true),
223 RX_HANDLER(BEACON_NOTIFICATION, iwl_mvm_rx_beacon_notif, false), 223 RX_HANDLER(BEACON_NOTIFICATION, iwl_mvm_rx_beacon_notif, true),
224 RX_HANDLER(STATISTICS_NOTIFICATION, iwl_mvm_rx_statistics, true), 224 RX_HANDLER(STATISTICS_NOTIFICATION, iwl_mvm_rx_statistics, true),
225 RX_HANDLER(ANTENNA_COUPLING_NOTIFICATION, 225 RX_HANDLER(ANTENNA_COUPLING_NOTIFICATION,
226 iwl_mvm_rx_ant_coupling_notif, true), 226 iwl_mvm_rx_ant_coupling_notif, true),
@@ -467,12 +467,18 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
467 min_backoff = calc_min_backoff(trans, cfg); 467 min_backoff = calc_min_backoff(trans, cfg);
468 iwl_mvm_tt_initialize(mvm, min_backoff); 468 iwl_mvm_tt_initialize(mvm, min_backoff);
469 469
470 if (WARN(cfg->no_power_up_nic_in_init && !iwlwifi_mod_params.nvm_file,
471 "not allowing power-up and not having nvm_file\n"))
472 goto out_free;
473
470 /* 474 /*
471 * If the NVM exists in an external file, 475 * Even if nvm exists in the nvm_file driver should read agin the nvm
472 * there is no need to unnecessarily power up the NIC at driver load 476 * from the nic because there might be entries that exist in the OTP
477 * and not in the file.
478 * for nics with no_power_up_nic_in_init: rely completley on nvm_file
473 */ 479 */
474 if (iwlwifi_mod_params.nvm_file) { 480 if (cfg->no_power_up_nic_in_init && iwlwifi_mod_params.nvm_file) {
475 err = iwl_nvm_init(mvm); 481 err = iwl_nvm_init(mvm, false);
476 if (err) 482 if (err)
477 goto out_free; 483 goto out_free;
478 } else { 484 } else {
@@ -519,7 +525,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
519 out_free: 525 out_free:
520 iwl_phy_db_free(mvm->phy_db); 526 iwl_phy_db_free(mvm->phy_db);
521 kfree(mvm->scan_cmd); 527 kfree(mvm->scan_cmd);
522 if (!iwlwifi_mod_params.nvm_file) 528 if (!cfg->no_power_up_nic_in_init || !iwlwifi_mod_params.nvm_file)
523 iwl_trans_op_mode_leave(trans); 529 iwl_trans_op_mode_leave(trans);
524 ieee80211_free_hw(mvm->hw); 530 ieee80211_free_hw(mvm->hw);
525 return NULL; 531 return NULL;
@@ -816,6 +822,7 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
816 struct iwl_fw_error_dump_file *dump_file; 822 struct iwl_fw_error_dump_file *dump_file;
817 struct iwl_fw_error_dump_data *dump_data; 823 struct iwl_fw_error_dump_data *dump_data;
818 u32 file_len; 824 u32 file_len;
825 u32 trans_len;
819 826
820 lockdep_assert_held(&mvm->mutex); 827 lockdep_assert_held(&mvm->mutex);
821 828
@@ -827,6 +834,10 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
827 sizeof(*dump_file) + 834 sizeof(*dump_file) +
828 sizeof(*dump_data) * 2; 835 sizeof(*dump_data) * 2;
829 836
837 trans_len = iwl_trans_dump_data(mvm->trans, NULL, 0);
838 if (trans_len)
839 file_len += trans_len;
840
830 dump_file = vmalloc(file_len); 841 dump_file = vmalloc(file_len);
831 if (!dump_file) 842 if (!dump_file)
832 return; 843 return;
@@ -840,7 +851,7 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
840 dump_data->len = cpu_to_le32(mvm->fw_error_rxf_len); 851 dump_data->len = cpu_to_le32(mvm->fw_error_rxf_len);
841 memcpy(dump_data->data, mvm->fw_error_rxf, mvm->fw_error_rxf_len); 852 memcpy(dump_data->data, mvm->fw_error_rxf, mvm->fw_error_rxf_len);
842 853
843 dump_data = (void *)((u8 *)dump_data->data + mvm->fw_error_rxf_len); 854 dump_data = iwl_mvm_fw_error_next_data(dump_data);
844 dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_SRAM); 855 dump_data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_SRAM);
845 dump_data->len = cpu_to_le32(mvm->fw_error_sram_len); 856 dump_data->len = cpu_to_le32(mvm->fw_error_sram_len);
846 857
@@ -858,6 +869,15 @@ void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
858 kfree(mvm->fw_error_sram); 869 kfree(mvm->fw_error_sram);
859 mvm->fw_error_sram = NULL; 870 mvm->fw_error_sram = NULL;
860 mvm->fw_error_sram_len = 0; 871 mvm->fw_error_sram_len = 0;
872
873 if (trans_len) {
874 void *buf = iwl_mvm_fw_error_next_data(dump_data);
875 u32 real_trans_len = iwl_trans_dump_data(mvm->trans, buf,
876 trans_len);
877 dump_data = (void *)((u8 *)buf + real_trans_len);
878 dump_file->file_len =
879 cpu_to_le32(file_len - trans_len + real_trans_len);
880 }
861} 881}
862#endif 882#endif
863 883
diff --git a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
index 237efe0ac1c4..eafc517a5f9e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/phy-ctxt.c
@@ -202,18 +202,15 @@ int iwl_mvm_phy_ctxt_add(struct iwl_mvm *mvm, struct iwl_mvm_phy_ctxt *ctxt,
202 struct cfg80211_chan_def *chandef, 202 struct cfg80211_chan_def *chandef,
203 u8 chains_static, u8 chains_dynamic) 203 u8 chains_static, u8 chains_dynamic)
204{ 204{
205 int ret;
206
207 WARN_ON(!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) && 205 WARN_ON(!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) &&
208 ctxt->ref); 206 ctxt->ref);
209 lockdep_assert_held(&mvm->mutex); 207 lockdep_assert_held(&mvm->mutex);
210 208
211 ctxt->channel = chandef->chan; 209 ctxt->channel = chandef->chan;
212 ret = iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef,
213 chains_static, chains_dynamic,
214 FW_CTXT_ACTION_ADD, 0);
215 210
216 return ret; 211 return iwl_mvm_phy_ctxt_apply(mvm, ctxt, chandef,
212 chains_static, chains_dynamic,
213 FW_CTXT_ACTION_ADD, 0);
217} 214}
218 215
219/* 216/*
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c
index d44b2b33b5cc..10ad1dca5f17 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.c
@@ -211,7 +211,7 @@ static const struct rs_tx_column rs_tx_columns[] = {
211 .next_columns = { 211 .next_columns = {
212 RS_COLUMN_LEGACY_ANT_B, 212 RS_COLUMN_LEGACY_ANT_B,
213 RS_COLUMN_SISO_ANT_A, 213 RS_COLUMN_SISO_ANT_A,
214 RS_COLUMN_SISO_ANT_B, 214 RS_COLUMN_MIMO2,
215 RS_COLUMN_INVALID, 215 RS_COLUMN_INVALID,
216 RS_COLUMN_INVALID, 216 RS_COLUMN_INVALID,
217 RS_COLUMN_INVALID, 217 RS_COLUMN_INVALID,
@@ -223,8 +223,8 @@ static const struct rs_tx_column rs_tx_columns[] = {
223 .ant = ANT_B, 223 .ant = ANT_B,
224 .next_columns = { 224 .next_columns = {
225 RS_COLUMN_LEGACY_ANT_A, 225 RS_COLUMN_LEGACY_ANT_A,
226 RS_COLUMN_SISO_ANT_A,
227 RS_COLUMN_SISO_ANT_B, 226 RS_COLUMN_SISO_ANT_B,
227 RS_COLUMN_MIMO2,
228 RS_COLUMN_INVALID, 228 RS_COLUMN_INVALID,
229 RS_COLUMN_INVALID, 229 RS_COLUMN_INVALID,
230 RS_COLUMN_INVALID, 230 RS_COLUMN_INVALID,
@@ -238,10 +238,10 @@ static const struct rs_tx_column rs_tx_columns[] = {
238 RS_COLUMN_SISO_ANT_B, 238 RS_COLUMN_SISO_ANT_B,
239 RS_COLUMN_MIMO2, 239 RS_COLUMN_MIMO2,
240 RS_COLUMN_SISO_ANT_A_SGI, 240 RS_COLUMN_SISO_ANT_A_SGI,
241 RS_COLUMN_SISO_ANT_B_SGI,
242 RS_COLUMN_LEGACY_ANT_A, 241 RS_COLUMN_LEGACY_ANT_A,
243 RS_COLUMN_LEGACY_ANT_B, 242 RS_COLUMN_LEGACY_ANT_B,
244 RS_COLUMN_INVALID, 243 RS_COLUMN_INVALID,
244 RS_COLUMN_INVALID,
245 }, 245 },
246 .checks = { 246 .checks = {
247 rs_siso_allow, 247 rs_siso_allow,
@@ -254,10 +254,10 @@ static const struct rs_tx_column rs_tx_columns[] = {
254 RS_COLUMN_SISO_ANT_A, 254 RS_COLUMN_SISO_ANT_A,
255 RS_COLUMN_MIMO2, 255 RS_COLUMN_MIMO2,
256 RS_COLUMN_SISO_ANT_B_SGI, 256 RS_COLUMN_SISO_ANT_B_SGI,
257 RS_COLUMN_SISO_ANT_A_SGI,
258 RS_COLUMN_LEGACY_ANT_A, 257 RS_COLUMN_LEGACY_ANT_A,
259 RS_COLUMN_LEGACY_ANT_B, 258 RS_COLUMN_LEGACY_ANT_B,
260 RS_COLUMN_INVALID, 259 RS_COLUMN_INVALID,
260 RS_COLUMN_INVALID,
261 }, 261 },
262 .checks = { 262 .checks = {
263 rs_siso_allow, 263 rs_siso_allow,
@@ -271,10 +271,10 @@ static const struct rs_tx_column rs_tx_columns[] = {
271 RS_COLUMN_SISO_ANT_B_SGI, 271 RS_COLUMN_SISO_ANT_B_SGI,
272 RS_COLUMN_MIMO2_SGI, 272 RS_COLUMN_MIMO2_SGI,
273 RS_COLUMN_SISO_ANT_A, 273 RS_COLUMN_SISO_ANT_A,
274 RS_COLUMN_SISO_ANT_B,
275 RS_COLUMN_MIMO2,
276 RS_COLUMN_LEGACY_ANT_A, 274 RS_COLUMN_LEGACY_ANT_A,
277 RS_COLUMN_LEGACY_ANT_B, 275 RS_COLUMN_LEGACY_ANT_B,
276 RS_COLUMN_INVALID,
277 RS_COLUMN_INVALID,
278 }, 278 },
279 .checks = { 279 .checks = {
280 rs_siso_allow, 280 rs_siso_allow,
@@ -289,10 +289,10 @@ static const struct rs_tx_column rs_tx_columns[] = {
289 RS_COLUMN_SISO_ANT_A_SGI, 289 RS_COLUMN_SISO_ANT_A_SGI,
290 RS_COLUMN_MIMO2_SGI, 290 RS_COLUMN_MIMO2_SGI,
291 RS_COLUMN_SISO_ANT_B, 291 RS_COLUMN_SISO_ANT_B,
292 RS_COLUMN_SISO_ANT_A,
293 RS_COLUMN_MIMO2,
294 RS_COLUMN_LEGACY_ANT_A, 292 RS_COLUMN_LEGACY_ANT_A,
295 RS_COLUMN_LEGACY_ANT_B, 293 RS_COLUMN_LEGACY_ANT_B,
294 RS_COLUMN_INVALID,
295 RS_COLUMN_INVALID,
296 }, 296 },
297 .checks = { 297 .checks = {
298 rs_siso_allow, 298 rs_siso_allow,
@@ -304,12 +304,12 @@ static const struct rs_tx_column rs_tx_columns[] = {
304 .ant = ANT_AB, 304 .ant = ANT_AB,
305 .next_columns = { 305 .next_columns = {
306 RS_COLUMN_SISO_ANT_A, 306 RS_COLUMN_SISO_ANT_A,
307 RS_COLUMN_SISO_ANT_B,
308 RS_COLUMN_SISO_ANT_A_SGI,
309 RS_COLUMN_SISO_ANT_B_SGI,
310 RS_COLUMN_MIMO2_SGI, 307 RS_COLUMN_MIMO2_SGI,
311 RS_COLUMN_LEGACY_ANT_A, 308 RS_COLUMN_LEGACY_ANT_A,
312 RS_COLUMN_LEGACY_ANT_B, 309 RS_COLUMN_LEGACY_ANT_B,
310 RS_COLUMN_INVALID,
311 RS_COLUMN_INVALID,
312 RS_COLUMN_INVALID,
313 }, 313 },
314 .checks = { 314 .checks = {
315 rs_mimo_allow, 315 rs_mimo_allow,
@@ -321,12 +321,12 @@ static const struct rs_tx_column rs_tx_columns[] = {
321 .sgi = true, 321 .sgi = true,
322 .next_columns = { 322 .next_columns = {
323 RS_COLUMN_SISO_ANT_A_SGI, 323 RS_COLUMN_SISO_ANT_A_SGI,
324 RS_COLUMN_SISO_ANT_B_SGI,
325 RS_COLUMN_SISO_ANT_A,
326 RS_COLUMN_SISO_ANT_B,
327 RS_COLUMN_MIMO2, 324 RS_COLUMN_MIMO2,
328 RS_COLUMN_LEGACY_ANT_A, 325 RS_COLUMN_LEGACY_ANT_A,
329 RS_COLUMN_LEGACY_ANT_B, 326 RS_COLUMN_LEGACY_ANT_B,
327 RS_COLUMN_INVALID,
328 RS_COLUMN_INVALID,
329 RS_COLUMN_INVALID,
330 }, 330 },
331 .checks = { 331 .checks = {
332 rs_mimo_allow, 332 rs_mimo_allow,
@@ -1031,7 +1031,7 @@ static void rs_tx_status(void *mvm_r, struct ieee80211_supported_band *sband,
1031 return; 1031 return;
1032 } 1032 }
1033 1033
1034#ifdef CPTCFG_MAC80211_DEBUGFS 1034#ifdef CONFIG_MAC80211_DEBUGFS
1035 /* Disable last tx check if we are debugging with fixed rate */ 1035 /* Disable last tx check if we are debugging with fixed rate */
1036 if (lq_sta->dbg_fixed_rate) { 1036 if (lq_sta->dbg_fixed_rate) {
1037 IWL_DEBUG_RATE(mvm, "Fixed rate. avoid rate scaling\n"); 1037 IWL_DEBUG_RATE(mvm, "Fixed rate. avoid rate scaling\n");
@@ -1335,105 +1335,50 @@ static void rs_set_expected_tpt_table(struct iwl_lq_sta *lq_sta,
1335 tbl->expected_tpt = rs_get_expected_tpt_table(lq_sta, column, rate->bw); 1335 tbl->expected_tpt = rs_get_expected_tpt_table(lq_sta, column, rate->bw);
1336} 1336}
1337 1337
1338/*
1339 * Find starting rate for new "search" high-throughput mode of modulation.
1340 * Goal is to find lowest expected rate (under perfect conditions) that is
1341 * above the current measured throughput of "active" mode, to give new mode
1342 * a fair chance to prove itself without too many challenges.
1343 *
1344 * This gets called when transitioning to more aggressive modulation
1345 * (i.e. legacy to SISO or MIMO, or SISO to MIMO), as well as less aggressive
1346 * (i.e. MIMO to SISO). When moving to MIMO, bit rate will typically need
1347 * to decrease to match "active" throughput. When moving from MIMO to SISO,
1348 * bit rate will typically need to increase, but not if performance was bad.
1349 */
1350static s32 rs_get_best_rate(struct iwl_mvm *mvm, 1338static s32 rs_get_best_rate(struct iwl_mvm *mvm,
1351 struct iwl_lq_sta *lq_sta, 1339 struct iwl_lq_sta *lq_sta,
1352 struct iwl_scale_tbl_info *tbl, /* "search" */ 1340 struct iwl_scale_tbl_info *tbl, /* "search" */
1353 u16 rate_mask, s8 index) 1341 unsigned long rate_mask, s8 index)
1354{ 1342{
1355 /* "active" values */
1356 struct iwl_scale_tbl_info *active_tbl = 1343 struct iwl_scale_tbl_info *active_tbl =
1357 &(lq_sta->lq_info[lq_sta->active_tbl]); 1344 &(lq_sta->lq_info[lq_sta->active_tbl]);
1358 s32 active_sr = active_tbl->win[index].success_ratio; 1345 s32 success_ratio = active_tbl->win[index].success_ratio;
1359 s32 active_tpt = active_tbl->expected_tpt[index]; 1346 u16 expected_current_tpt = active_tbl->expected_tpt[index];
1360 /* expected "search" throughput */
1361 const u16 *tpt_tbl = tbl->expected_tpt; 1347 const u16 *tpt_tbl = tbl->expected_tpt;
1362
1363 s32 new_rate, high, low, start_hi;
1364 u16 high_low; 1348 u16 high_low;
1365 s8 rate = index; 1349 u32 target_tpt;
1366 1350 int rate_idx;
1367 new_rate = high = low = start_hi = IWL_RATE_INVALID;
1368
1369 while (1) {
1370 high_low = rs_get_adjacent_rate(mvm, rate, rate_mask,
1371 tbl->rate.type);
1372
1373 low = high_low & 0xff;
1374 high = (high_low >> 8) & 0xff;
1375 1351
1376 /* 1352 if (success_ratio > RS_SR_NO_DECREASE) {
1377 * Lower the "search" bit rate, to give new "search" mode 1353 target_tpt = 100 * expected_current_tpt;
1378 * approximately the same throughput as "active" if: 1354 IWL_DEBUG_RATE(mvm,
1379 * 1355 "SR %d high. Find rate exceeding EXPECTED_CURRENT %d\n",
1380 * 1) "Active" mode has been working modestly well (but not 1356 success_ratio, target_tpt);
1381 * great), and expected "search" throughput (under perfect 1357 } else {
1382 * conditions) at candidate rate is above the actual 1358 target_tpt = lq_sta->last_tpt;
1383 * measured "active" throughput (but less than expected 1359 IWL_DEBUG_RATE(mvm,
1384 * "active" throughput under perfect conditions). 1360 "SR %d not thag good. Find rate exceeding ACTUAL_TPT %d\n",
1385 * OR 1361 success_ratio, target_tpt);
1386 * 2) "Active" mode has been working perfectly or very well 1362 }
1387 * and expected "search" throughput (under perfect
1388 * conditions) at candidate rate is above expected
1389 * "active" throughput (under perfect conditions).
1390 */
1391 if ((((100 * tpt_tbl[rate]) > lq_sta->last_tpt) &&
1392 ((active_sr > RS_SR_FORCE_DECREASE) &&
1393 (active_sr <= IWL_RATE_HIGH_TH) &&
1394 (tpt_tbl[rate] <= active_tpt))) ||
1395 ((active_sr >= IWL_RATE_SCALE_SWITCH) &&
1396 (tpt_tbl[rate] > active_tpt))) {
1397 /* (2nd or later pass)
1398 * If we've already tried to raise the rate, and are
1399 * now trying to lower it, use the higher rate. */
1400 if (start_hi != IWL_RATE_INVALID) {
1401 new_rate = start_hi;
1402 break;
1403 }
1404
1405 new_rate = rate;
1406
1407 /* Loop again with lower rate */
1408 if (low != IWL_RATE_INVALID)
1409 rate = low;
1410 1363
1411 /* Lower rate not available, use the original */ 1364 rate_idx = find_first_bit(&rate_mask, BITS_PER_LONG);
1412 else
1413 break;
1414 1365
1415 /* Else try to raise the "search" rate to match "active" */ 1366 while (rate_idx != IWL_RATE_INVALID) {
1416 } else { 1367 if (target_tpt < (100 * tpt_tbl[rate_idx]))
1417 /* (2nd or later pass) 1368 break;
1418 * If we've already tried to lower the rate, and are
1419 * now trying to raise it, use the lower rate. */
1420 if (new_rate != IWL_RATE_INVALID)
1421 break;
1422 1369
1423 /* Loop again with higher rate */ 1370 high_low = rs_get_adjacent_rate(mvm, rate_idx, rate_mask,
1424 else if (high != IWL_RATE_INVALID) { 1371 tbl->rate.type);
1425 start_hi = high;
1426 rate = high;
1427 1372
1428 /* Higher rate not available, use the original */ 1373 rate_idx = (high_low >> 8) & 0xff;
1429 } else {
1430 new_rate = rate;
1431 break;
1432 }
1433 }
1434 } 1374 }
1435 1375
1436 return new_rate; 1376 IWL_DEBUG_RATE(mvm, "Best rate found %d target_tp %d expected_new %d\n",
1377 rate_idx, target_tpt,
1378 rate_idx != IWL_RATE_INVALID ?
1379 100 * tpt_tbl[rate_idx] : IWL_INVALID_VALUE);
1380
1381 return rate_idx;
1437} 1382}
1438 1383
1439static u32 rs_bw_from_sta_bw(struct ieee80211_sta *sta) 1384static u32 rs_bw_from_sta_bw(struct ieee80211_sta *sta)
@@ -1608,7 +1553,7 @@ static enum rs_column rs_get_next_column(struct iwl_mvm *mvm,
1608 1553
1609 tpt = lq_sta->last_tpt / 100; 1554 tpt = lq_sta->last_tpt / 100;
1610 expected_tpt_tbl = rs_get_expected_tpt_table(lq_sta, next_col, 1555 expected_tpt_tbl = rs_get_expected_tpt_table(lq_sta, next_col,
1611 tbl->rate.bw); 1556 rs_bw_from_sta_bw(sta));
1612 if (WARN_ON_ONCE(!expected_tpt_tbl)) 1557 if (WARN_ON_ONCE(!expected_tpt_tbl))
1613 continue; 1558 continue;
1614 1559
@@ -1649,7 +1594,7 @@ static int rs_switch_to_column(struct iwl_mvm *mvm,
1649 const struct rs_tx_column *curr_column = &rs_tx_columns[tbl->column]; 1594 const struct rs_tx_column *curr_column = &rs_tx_columns[tbl->column];
1650 u32 sz = (sizeof(struct iwl_scale_tbl_info) - 1595 u32 sz = (sizeof(struct iwl_scale_tbl_info) -
1651 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT)); 1596 (sizeof(struct iwl_rate_scale_data) * IWL_RATE_COUNT));
1652 u16 rate_mask = 0; 1597 unsigned long rate_mask = 0;
1653 u32 rate_idx = 0; 1598 u32 rate_idx = 0;
1654 1599
1655 memcpy(search_tbl, tbl, sz); 1600 memcpy(search_tbl, tbl, sz);
@@ -1691,7 +1636,7 @@ static int rs_switch_to_column(struct iwl_mvm *mvm,
1691 !(BIT(rate_idx) & rate_mask)) { 1636 !(BIT(rate_idx) & rate_mask)) {
1692 IWL_DEBUG_RATE(mvm, 1637 IWL_DEBUG_RATE(mvm,
1693 "can not switch with index %d" 1638 "can not switch with index %d"
1694 " rate mask %x\n", 1639 " rate mask %lx\n",
1695 rate_idx, rate_mask); 1640 rate_idx, rate_mask);
1696 1641
1697 goto err; 1642 goto err;
@@ -1805,16 +1750,21 @@ static void rs_get_adjacent_txp(struct iwl_mvm *mvm, int index,
1805 *stronger = TPC_INVALID; 1750 *stronger = TPC_INVALID;
1806} 1751}
1807 1752
1808static bool rs_tpc_allowed(struct iwl_mvm *mvm, struct rs_rate *rate, 1753static bool rs_tpc_allowed(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
1809 enum ieee80211_band band) 1754 struct rs_rate *rate, enum ieee80211_band band)
1810{ 1755{
1811 int index = rate->index; 1756 int index = rate->index;
1757 bool cam = (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM);
1758 bool sta_ps_disabled = (vif->type == NL80211_IFTYPE_STATION &&
1759 !vif->bss_conf.ps);
1812 1760
1761 IWL_DEBUG_RATE(mvm, "cam: %d sta_ps_disabled %d\n",
1762 cam, sta_ps_disabled);
1813 /* 1763 /*
1814 * allow tpc only if power management is enabled, or bt coex 1764 * allow tpc only if power management is enabled, or bt coex
1815 * activity grade allows it and we are on 2.4Ghz. 1765 * activity grade allows it and we are on 2.4Ghz.
1816 */ 1766 */
1817 if (iwlmvm_mod_params.power_scheme == IWL_POWER_SCHEME_CAM && 1767 if ((cam || sta_ps_disabled) &&
1818 !iwl_mvm_bt_coex_is_tpc_allowed(mvm, band)) 1768 !iwl_mvm_bt_coex_is_tpc_allowed(mvm, band))
1819 return false; 1769 return false;
1820 1770
@@ -1931,7 +1881,7 @@ static bool rs_tpc_perform(struct iwl_mvm *mvm,
1931 band = chanctx_conf->def.chan->band; 1881 band = chanctx_conf->def.chan->band;
1932 rcu_read_unlock(); 1882 rcu_read_unlock();
1933 1883
1934 if (!rs_tpc_allowed(mvm, rate, band)) { 1884 if (!rs_tpc_allowed(mvm, vif, rate, band)) {
1935 IWL_DEBUG_RATE(mvm, 1885 IWL_DEBUG_RATE(mvm,
1936 "tpc is not allowed. remove txp restrictions"); 1886 "tpc is not allowed. remove txp restrictions");
1937 lq_sta->lq.reduced_tpc = TPC_NO_REDUCTION; 1887 lq_sta->lq.reduced_tpc = TPC_NO_REDUCTION;
@@ -2235,7 +2185,8 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
2235 break; 2185 break;
2236 case RS_ACTION_STAY: 2186 case RS_ACTION_STAY:
2237 /* No change */ 2187 /* No change */
2238 update_lq = rs_tpc_perform(mvm, sta, lq_sta, tbl); 2188 if (lq_sta->rs_state == RS_STATE_STAY_IN_COLUMN)
2189 update_lq = rs_tpc_perform(mvm, sta, lq_sta, tbl);
2239 break; 2190 break;
2240 default: 2191 default:
2241 break; 2192 break;
@@ -2489,10 +2440,6 @@ static void rs_vht_set_enabled_rates(struct ieee80211_sta *sta,
2489 if (i == IWL_RATE_9M_INDEX) 2440 if (i == IWL_RATE_9M_INDEX)
2490 continue; 2441 continue;
2491 2442
2492 /* Disable MCS9 as a workaround */
2493 if (i == IWL_RATE_MCS_9_INDEX)
2494 continue;
2495
2496 /* VHT MCS9 isn't valid for 20Mhz for NSS=1,2 */ 2443 /* VHT MCS9 isn't valid for 20Mhz for NSS=1,2 */
2497 if (i == IWL_RATE_MCS_9_INDEX && 2444 if (i == IWL_RATE_MCS_9_INDEX &&
2498 sta->bandwidth == IEEE80211_STA_RX_BW_20) 2445 sta->bandwidth == IEEE80211_STA_RX_BW_20)
@@ -2511,10 +2458,6 @@ static void rs_vht_set_enabled_rates(struct ieee80211_sta *sta,
2511 if (i == IWL_RATE_9M_INDEX) 2458 if (i == IWL_RATE_9M_INDEX)
2512 continue; 2459 continue;
2513 2460
2514 /* Disable MCS9 as a workaround */
2515 if (i == IWL_RATE_MCS_9_INDEX)
2516 continue;
2517
2518 /* VHT MCS9 isn't valid for 20Mhz for NSS=1,2 */ 2461 /* VHT MCS9 isn't valid for 20Mhz for NSS=1,2 */
2519 if (i == IWL_RATE_MCS_9_INDEX && 2462 if (i == IWL_RATE_MCS_9_INDEX &&
2520 sta->bandwidth == IEEE80211_STA_RX_BW_20) 2463 sta->bandwidth == IEEE80211_STA_RX_BW_20)
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c
index 63e7b16edb55..36ae01a18dee 100644
--- a/drivers/net/wireless/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
@@ -277,51 +277,22 @@ static void iwl_mvm_scan_calc_params(struct iwl_mvm *mvm,
277 IEEE80211_IFACE_ITER_NORMAL, 277 IEEE80211_IFACE_ITER_NORMAL,
278 iwl_mvm_scan_condition_iterator, 278 iwl_mvm_scan_condition_iterator,
279 &global_bound); 279 &global_bound);
280 /*
281 * Under low latency traffic passive scan is fragmented meaning
282 * that dwell on a particular channel will be fragmented. Each fragment
283 * dwell time is 20ms and fragments period is 105ms. Skipping to next
284 * channel will be delayed by the same period - 105ms. So suspend_time
285 * parameter describing both fragments and channels skipping periods is
286 * set to 105ms. This value is chosen so that overall passive scan
287 * duration will not be too long. Max_out_time in this case is set to
288 * 70ms, so for active scanning operating channel will be left for 70ms
289 * while for passive still for 20ms (fragment dwell).
290 */
291 if (global_bound) {
292 if (!iwl_mvm_low_latency(mvm)) {
293 params->suspend_time = ieee80211_tu_to_usec(100);
294 params->max_out_time = ieee80211_tu_to_usec(600);
295 } else {
296 params->suspend_time = ieee80211_tu_to_usec(105);
297 /* P2P doesn't support fragmented passive scan, so
298 * configure max_out_time to be at least longest dwell
299 * time for passive scan.
300 */
301 if (vif->type == NL80211_IFTYPE_STATION && !vif->p2p) {
302 params->max_out_time = ieee80211_tu_to_usec(70);
303 params->passive_fragmented = true;
304 } else {
305 u32 passive_dwell;
306 280
307 /* 281 if (!global_bound)
308 * Use band G so that passive channel dwell time 282 goto not_bound;
309 * will be assigned with maximum value. 283
310 */ 284 params->suspend_time = 100;
311 band = IEEE80211_BAND_2GHZ; 285 params->max_out_time = 600;
312 passive_dwell = iwl_mvm_get_passive_dwell(band); 286
313 params->max_out_time = 287 if (iwl_mvm_low_latency(mvm)) {
314 ieee80211_tu_to_usec(passive_dwell); 288 params->suspend_time = 250;
315 } 289 params->max_out_time = 250;
316 }
317 } 290 }
318 291
292not_bound:
293
319 for (band = IEEE80211_BAND_2GHZ; band < IEEE80211_NUM_BANDS; band++) { 294 for (band = IEEE80211_BAND_2GHZ; band < IEEE80211_NUM_BANDS; band++) {
320 if (params->passive_fragmented) 295 params->dwell[band].passive = iwl_mvm_get_passive_dwell(band);
321 params->dwell[band].passive = 20;
322 else
323 params->dwell[band].passive =
324 iwl_mvm_get_passive_dwell(band);
325 params->dwell[band].active = iwl_mvm_get_active_dwell(band, 296 params->dwell[band].active = iwl_mvm_get_active_dwell(band,
326 n_ssids); 297 n_ssids);
327 } 298 }
@@ -770,7 +741,7 @@ int iwl_mvm_config_sched_scan(struct iwl_mvm *mvm,
770 int band_2ghz = mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels; 741 int band_2ghz = mvm->nvm_data->bands[IEEE80211_BAND_2GHZ].n_channels;
771 int band_5ghz = mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels; 742 int band_5ghz = mvm->nvm_data->bands[IEEE80211_BAND_5GHZ].n_channels;
772 int head = 0; 743 int head = 0;
773 int tail = band_2ghz + band_5ghz; 744 int tail = band_2ghz + band_5ghz - 1;
774 u32 ssid_bitmap; 745 u32 ssid_bitmap;
775 int cmd_len; 746 int cmd_len;
776 int ret; 747 int ret;
diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c
index c5f4532cafa9..2f82d0dc7ad8 100644
--- a/drivers/net/wireless/iwlwifi/mvm/utils.c
+++ b/drivers/net/wireless/iwlwifi/mvm/utils.c
@@ -519,6 +519,7 @@ void iwl_mvm_dump_nic_error_log(struct iwl_mvm *mvm)
519 iwl_mvm_dump_umac_error_log(mvm); 519 iwl_mvm_dump_umac_error_log(mvm);
520} 520}
521 521
522#ifdef CONFIG_IWLWIFI_DEBUGFS
522void iwl_mvm_fw_error_sram_dump(struct iwl_mvm *mvm) 523void iwl_mvm_fw_error_sram_dump(struct iwl_mvm *mvm)
523{ 524{
524 const struct fw_img *img; 525 const struct fw_img *img;
@@ -581,6 +582,7 @@ void iwl_mvm_fw_error_rxf_dump(struct iwl_mvm *mvm)
581 } 582 }
582 iwl_trans_release_nic_access(mvm->trans, &flags); 583 iwl_trans_release_nic_access(mvm->trans, &flags);
583} 584}
585#endif
584 586
585/** 587/**
586 * iwl_mvm_send_lq_cmd() - Send link quality command 588 * iwl_mvm_send_lq_cmd() - Send link quality command
@@ -688,3 +690,22 @@ bool iwl_mvm_low_latency(struct iwl_mvm *mvm)
688 690
689 return result; 691 return result;
690} 692}
693
694static void iwl_mvm_idle_iter(void *_data, u8 *mac, struct ieee80211_vif *vif)
695{
696 bool *idle = _data;
697
698 if (!vif->bss_conf.idle)
699 *idle = false;
700}
701
702bool iwl_mvm_is_idle(struct iwl_mvm *mvm)
703{
704 bool idle = true;
705
706 ieee80211_iterate_active_interfaces_atomic(
707 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
708 iwl_mvm_idle_iter, &idle);
709
710 return idle;
711}
diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h
index 1b95d856dfd5..6c22b23a2845 100644
--- a/drivers/net/wireless/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/iwlwifi/pcie/internal.h
@@ -117,21 +117,19 @@ struct iwl_dma_ptr {
117/** 117/**
118 * iwl_queue_inc_wrap - increment queue index, wrap back to beginning 118 * iwl_queue_inc_wrap - increment queue index, wrap back to beginning
119 * @index -- current index 119 * @index -- current index
120 * @n_bd -- total number of entries in queue (must be power of 2)
121 */ 120 */
122static inline int iwl_queue_inc_wrap(int index, int n_bd) 121static inline int iwl_queue_inc_wrap(int index)
123{ 122{
124 return ++index & (n_bd - 1); 123 return ++index & (TFD_QUEUE_SIZE_MAX - 1);
125} 124}
126 125
127/** 126/**
128 * iwl_queue_dec_wrap - decrement queue index, wrap back to end 127 * iwl_queue_dec_wrap - decrement queue index, wrap back to end
129 * @index -- current index 128 * @index -- current index
130 * @n_bd -- total number of entries in queue (must be power of 2)
131 */ 129 */
132static inline int iwl_queue_dec_wrap(int index, int n_bd) 130static inline int iwl_queue_dec_wrap(int index)
133{ 131{
134 return --index & (n_bd - 1); 132 return --index & (TFD_QUEUE_SIZE_MAX - 1);
135} 133}
136 134
137struct iwl_cmd_meta { 135struct iwl_cmd_meta {
@@ -145,13 +143,13 @@ struct iwl_cmd_meta {
145 * 143 *
146 * Contains common data for Rx and Tx queues. 144 * Contains common data for Rx and Tx queues.
147 * 145 *
148 * Note the difference between n_bd and n_window: the hardware 146 * Note the difference between TFD_QUEUE_SIZE_MAX and n_window: the hardware
149 * always assumes 256 descriptors, so n_bd is always 256 (unless 147 * always assumes 256 descriptors, so TFD_QUEUE_SIZE_MAX is always 256 (unless
150 * there might be HW changes in the future). For the normal TX 148 * there might be HW changes in the future). For the normal TX
151 * queues, n_window, which is the size of the software queue data 149 * queues, n_window, which is the size of the software queue data
152 * is also 256; however, for the command queue, n_window is only 150 * is also 256; however, for the command queue, n_window is only
153 * 32 since we don't need so many commands pending. Since the HW 151 * 32 since we don't need so many commands pending. Since the HW
154 * still uses 256 BDs for DMA though, n_bd stays 256. As a result, 152 * still uses 256 BDs for DMA though, TFD_QUEUE_SIZE_MAX stays 256. As a result,
155 * the software buffers (in the variables @meta, @txb in struct 153 * the software buffers (in the variables @meta, @txb in struct
156 * iwl_txq) only have 32 entries, while the HW buffers (@tfds in 154 * iwl_txq) only have 32 entries, while the HW buffers (@tfds in
157 * the same struct) have 256. 155 * the same struct) have 256.
@@ -162,7 +160,6 @@ struct iwl_cmd_meta {
162 * data is a window overlayed over the HW queue. 160 * data is a window overlayed over the HW queue.
163 */ 161 */
164struct iwl_queue { 162struct iwl_queue {
165 int n_bd; /* number of BDs in this queue */
166 int write_ptr; /* 1-st empty entry (index) host_w*/ 163 int write_ptr; /* 1-st empty entry (index) host_w*/
167 int read_ptr; /* last used entry (index) host_r*/ 164 int read_ptr; /* last used entry (index) host_r*/
168 /* use for monitoring and recovering the stuck queue */ 165 /* use for monitoring and recovering the stuck queue */
@@ -373,6 +370,13 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
373 struct sk_buff_head *skbs); 370 struct sk_buff_head *skbs);
374void iwl_trans_pcie_tx_reset(struct iwl_trans *trans); 371void iwl_trans_pcie_tx_reset(struct iwl_trans *trans);
375 372
373static inline u16 iwl_pcie_tfd_tb_get_len(struct iwl_tfd *tfd, u8 idx)
374{
375 struct iwl_tfd_tb *tb = &tfd->tbs[idx];
376
377 return le16_to_cpu(tb->hi_n_len) >> 4;
378}
379
376/***************************************************** 380/*****************************************************
377* Error handling 381* Error handling
378******************************************************/ 382******************************************************/
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c
index 4a26a082a1ba..a2698e5e062c 100644
--- a/drivers/net/wireless/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/rx.c
@@ -850,7 +850,7 @@ static u32 iwl_pcie_int_cause_ict(struct iwl_trans *trans)
850 trans_pcie->ict_index, read); 850 trans_pcie->ict_index, read);
851 trans_pcie->ict_tbl[trans_pcie->ict_index] = 0; 851 trans_pcie->ict_tbl[trans_pcie->ict_index] = 0;
852 trans_pcie->ict_index = 852 trans_pcie->ict_index =
853 iwl_queue_inc_wrap(trans_pcie->ict_index, ICT_COUNT); 853 ((trans_pcie->ict_index + 1) & (ICT_COUNT - 1));
854 854
855 read = le32_to_cpu(trans_pcie->ict_tbl[trans_pcie->ict_index]); 855 read = le32_to_cpu(trans_pcie->ict_tbl[trans_pcie->ict_index]);
856 trace_iwlwifi_dev_ict_read(trans->dev, trans_pcie->ict_index, 856 trace_iwlwifi_dev_ict_read(trans->dev, trans_pcie->ict_index,
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index f98ef1e62eb9..a1af903f6c9b 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -73,6 +73,7 @@
73#include "iwl-csr.h" 73#include "iwl-csr.h"
74#include "iwl-prph.h" 74#include "iwl-prph.h"
75#include "iwl-agn-hw.h" 75#include "iwl-agn-hw.h"
76#include "iwl-fw-error-dump.h"
76#include "internal.h" 77#include "internal.h"
77 78
78static u32 iwl_trans_pcie_read_shr(struct iwl_trans *trans, u32 reg) 79static u32 iwl_trans_pcie_read_shr(struct iwl_trans *trans, u32 reg)
@@ -1337,8 +1338,8 @@ static int iwl_trans_pcie_wait_txq_empty(struct iwl_trans *trans, u32 txq_bm)
1337 IWL_ERR(trans, 1338 IWL_ERR(trans,
1338 "Q %d is %sactive and mapped to fifo %d ra_tid 0x%04x [%d,%d]\n", 1339 "Q %d is %sactive and mapped to fifo %d ra_tid 0x%04x [%d,%d]\n",
1339 cnt, active ? "" : "in", fifo, tbl_dw, 1340 cnt, active ? "" : "in", fifo, tbl_dw,
1340 iwl_read_prph(trans, 1341 iwl_read_prph(trans, SCD_QUEUE_RDPTR(cnt)) &
1341 SCD_QUEUE_RDPTR(cnt)) & (txq->q.n_bd - 1), 1342 (TFD_QUEUE_SIZE_MAX - 1),
1342 iwl_read_prph(trans, SCD_QUEUE_WRPTR(cnt))); 1343 iwl_read_prph(trans, SCD_QUEUE_WRPTR(cnt)));
1343 } 1344 }
1344 1345
@@ -1669,6 +1670,61 @@ err:
1669 IWL_ERR(trans, "failed to create the trans debugfs entry\n"); 1670 IWL_ERR(trans, "failed to create the trans debugfs entry\n");
1670 return -ENOMEM; 1671 return -ENOMEM;
1671} 1672}
1673
1674static u32 iwl_trans_pcie_get_cmdlen(struct iwl_tfd *tfd)
1675{
1676 u32 cmdlen = 0;
1677 int i;
1678
1679 for (i = 0; i < IWL_NUM_OF_TBS; i++)
1680 cmdlen += iwl_pcie_tfd_tb_get_len(tfd, i);
1681
1682 return cmdlen;
1683}
1684
1685static u32 iwl_trans_pcie_dump_data(struct iwl_trans *trans,
1686 void *buf, u32 buflen)
1687{
1688 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1689 struct iwl_fw_error_dump_data *data;
1690 struct iwl_txq *cmdq = &trans_pcie->txq[trans_pcie->cmd_queue];
1691 struct iwl_fw_error_dump_txcmd *txcmd;
1692 u32 len;
1693 int i, ptr;
1694
1695 if (!buf)
1696 return sizeof(*data) +
1697 cmdq->q.n_window * (sizeof(*txcmd) +
1698 TFD_MAX_PAYLOAD_SIZE);
1699
1700 len = 0;
1701 data = buf;
1702 data->type = cpu_to_le32(IWL_FW_ERROR_DUMP_TXCMD);
1703 txcmd = (void *)data->data;
1704 spin_lock_bh(&cmdq->lock);
1705 ptr = cmdq->q.write_ptr;
1706 for (i = 0; i < cmdq->q.n_window; i++) {
1707 u8 idx = get_cmd_index(&cmdq->q, ptr);
1708 u32 caplen, cmdlen;
1709
1710 cmdlen = iwl_trans_pcie_get_cmdlen(&cmdq->tfds[ptr]);
1711 caplen = min_t(u32, TFD_MAX_PAYLOAD_SIZE, cmdlen);
1712
1713 if (cmdlen) {
1714 len += sizeof(*txcmd) + caplen;
1715 txcmd->cmdlen = cpu_to_le32(cmdlen);
1716 txcmd->caplen = cpu_to_le32(caplen);
1717 memcpy(txcmd->data, cmdq->entries[idx].cmd, caplen);
1718 txcmd = (void *)((u8 *)txcmd->data + caplen);
1719 }
1720
1721 ptr = iwl_queue_dec_wrap(ptr);
1722 }
1723 spin_unlock_bh(&cmdq->lock);
1724
1725 data->len = cpu_to_le32(len);
1726 return sizeof(*data) + len;
1727}
1672#else 1728#else
1673static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans, 1729static int iwl_trans_pcie_dbgfs_register(struct iwl_trans *trans,
1674 struct dentry *dir) 1730 struct dentry *dir)
@@ -1711,6 +1767,10 @@ static const struct iwl_trans_ops trans_ops_pcie = {
1711 .grab_nic_access = iwl_trans_pcie_grab_nic_access, 1767 .grab_nic_access = iwl_trans_pcie_grab_nic_access,
1712 .release_nic_access = iwl_trans_pcie_release_nic_access, 1768 .release_nic_access = iwl_trans_pcie_release_nic_access,
1713 .set_bits_mask = iwl_trans_pcie_set_bits_mask, 1769 .set_bits_mask = iwl_trans_pcie_set_bits_mask,
1770
1771#ifdef CONFIG_IWLWIFI_DEBUGFS
1772 .dump_data = iwl_trans_pcie_dump_data,
1773#endif
1714}; 1774};
1715 1775
1716struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev, 1776struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
@@ -1788,6 +1848,10 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
1788 * PCI Tx retries from interfering with C3 CPU state */ 1848 * PCI Tx retries from interfering with C3 CPU state */
1789 pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); 1849 pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00);
1790 1850
1851 trans->dev = &pdev->dev;
1852 trans_pcie->pci_dev = pdev;
1853 iwl_disable_interrupts(trans);
1854
1791 err = pci_enable_msi(pdev); 1855 err = pci_enable_msi(pdev);
1792 if (err) { 1856 if (err) {
1793 dev_err(&pdev->dev, "pci_enable_msi failed(0X%x)\n", err); 1857 dev_err(&pdev->dev, "pci_enable_msi failed(0X%x)\n", err);
@@ -1799,8 +1863,6 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
1799 } 1863 }
1800 } 1864 }
1801 1865
1802 trans->dev = &pdev->dev;
1803 trans_pcie->pci_dev = pdev;
1804 trans->hw_rev = iwl_read32(trans, CSR_HW_REV); 1866 trans->hw_rev = iwl_read32(trans, CSR_HW_REV);
1805 trans->hw_id = (pdev->device << 16) + pdev->subsystem_device; 1867 trans->hw_id = (pdev->device << 16) + pdev->subsystem_device;
1806 snprintf(trans->hw_id_str, sizeof(trans->hw_id_str), 1868 snprintf(trans->hw_id_str, sizeof(trans->hw_id_str),
@@ -1826,8 +1888,6 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
1826 goto out_pci_disable_msi; 1888 goto out_pci_disable_msi;
1827 } 1889 }
1828 1890
1829 trans_pcie->inta_mask = CSR_INI_SET_MASK;
1830
1831 if (iwl_pcie_alloc_ict(trans)) 1891 if (iwl_pcie_alloc_ict(trans))
1832 goto out_free_cmd_pool; 1892 goto out_free_cmd_pool;
1833 1893
@@ -1839,6 +1899,8 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
1839 goto out_free_ict; 1899 goto out_free_ict;
1840 } 1900 }
1841 1901
1902 trans_pcie->inta_mask = CSR_INI_SET_MASK;
1903
1842 return trans; 1904 return trans;
1843 1905
1844out_free_ict: 1906out_free_ict:
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c
index dde6031f4257..77a512a5a755 100644
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -70,20 +70,20 @@ static int iwl_queue_space(const struct iwl_queue *q)
70 70
71 /* 71 /*
72 * To avoid ambiguity between empty and completely full queues, there 72 * To avoid ambiguity between empty and completely full queues, there
73 * should always be less than q->n_bd elements in the queue. 73 * should always be less than TFD_QUEUE_SIZE_MAX elements in the queue.
74 * If q->n_window is smaller than q->n_bd, there is no need to reserve 74 * If q->n_window is smaller than TFD_QUEUE_SIZE_MAX, there is no need
75 * any queue entries for this purpose. 75 * to reserve any queue entries for this purpose.
76 */ 76 */
77 if (q->n_window < q->n_bd) 77 if (q->n_window < TFD_QUEUE_SIZE_MAX)
78 max = q->n_window; 78 max = q->n_window;
79 else 79 else
80 max = q->n_bd - 1; 80 max = TFD_QUEUE_SIZE_MAX - 1;
81 81
82 /* 82 /*
83 * q->n_bd is a power of 2, so the following is equivalent to modulo by 83 * TFD_QUEUE_SIZE_MAX is a power of 2, so the following is equivalent to
84 * q->n_bd and is well defined for negative dividends. 84 * modulo by TFD_QUEUE_SIZE_MAX and is well defined.
85 */ 85 */
86 used = (q->write_ptr - q->read_ptr) & (q->n_bd - 1); 86 used = (q->write_ptr - q->read_ptr) & (TFD_QUEUE_SIZE_MAX - 1);
87 87
88 if (WARN_ON(used > max)) 88 if (WARN_ON(used > max))
89 return 0; 89 return 0;
@@ -94,17 +94,11 @@ static int iwl_queue_space(const struct iwl_queue *q)
94/* 94/*
95 * iwl_queue_init - Initialize queue's high/low-water and read/write indexes 95 * iwl_queue_init - Initialize queue's high/low-water and read/write indexes
96 */ 96 */
97static int iwl_queue_init(struct iwl_queue *q, int count, int slots_num, u32 id) 97static int iwl_queue_init(struct iwl_queue *q, int slots_num, u32 id)
98{ 98{
99 q->n_bd = count;
100 q->n_window = slots_num; 99 q->n_window = slots_num;
101 q->id = id; 100 q->id = id;
102 101
103 /* count must be power-of-two size, otherwise iwl_queue_inc_wrap
104 * and iwl_queue_dec_wrap are broken. */
105 if (WARN_ON(!is_power_of_2(count)))
106 return -EINVAL;
107
108 /* slots_num must be power-of-two size, otherwise 102 /* slots_num must be power-of-two size, otherwise
109 * get_cmd_index is broken. */ 103 * get_cmd_index is broken. */
110 if (WARN_ON(!is_power_of_2(slots_num))) 104 if (WARN_ON(!is_power_of_2(slots_num)))
@@ -197,13 +191,13 @@ static void iwl_pcie_txq_stuck_timer(unsigned long data)
197 IWL_ERR(trans, 191 IWL_ERR(trans,
198 "Q %d is %sactive and mapped to fifo %d ra_tid 0x%04x [%d,%d]\n", 192 "Q %d is %sactive and mapped to fifo %d ra_tid 0x%04x [%d,%d]\n",
199 i, active ? "" : "in", fifo, tbl_dw, 193 i, active ? "" : "in", fifo, tbl_dw,
200 iwl_read_prph(trans, 194 iwl_read_prph(trans, SCD_QUEUE_RDPTR(i)) &
201 SCD_QUEUE_RDPTR(i)) & (txq->q.n_bd - 1), 195 (TFD_QUEUE_SIZE_MAX - 1),
202 iwl_read_prph(trans, SCD_QUEUE_WRPTR(i))); 196 iwl_read_prph(trans, SCD_QUEUE_WRPTR(i)));
203 } 197 }
204 198
205 for (i = q->read_ptr; i != q->write_ptr; 199 for (i = q->read_ptr; i != q->write_ptr;
206 i = iwl_queue_inc_wrap(i, q->n_bd)) 200 i = iwl_queue_inc_wrap(i))
207 IWL_ERR(trans, "scratch %d = 0x%08x\n", i, 201 IWL_ERR(trans, "scratch %d = 0x%08x\n", i,
208 le32_to_cpu(txq->scratchbufs[i].scratch)); 202 le32_to_cpu(txq->scratchbufs[i].scratch));
209 203
@@ -359,13 +353,6 @@ static inline dma_addr_t iwl_pcie_tfd_tb_get_addr(struct iwl_tfd *tfd, u8 idx)
359 return addr; 353 return addr;
360} 354}
361 355
362static inline u16 iwl_pcie_tfd_tb_get_len(struct iwl_tfd *tfd, u8 idx)
363{
364 struct iwl_tfd_tb *tb = &tfd->tbs[idx];
365
366 return le16_to_cpu(tb->hi_n_len) >> 4;
367}
368
369static inline void iwl_pcie_tfd_set_tb(struct iwl_tfd *tfd, u8 idx, 356static inline void iwl_pcie_tfd_set_tb(struct iwl_tfd *tfd, u8 idx,
370 dma_addr_t addr, u16 len) 357 dma_addr_t addr, u16 len)
371{ 358{
@@ -425,13 +412,17 @@ static void iwl_pcie_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq)
425{ 412{
426 struct iwl_tfd *tfd_tmp = txq->tfds; 413 struct iwl_tfd *tfd_tmp = txq->tfds;
427 414
428 /* rd_ptr is bounded by n_bd and idx is bounded by n_window */ 415 /* rd_ptr is bounded by TFD_QUEUE_SIZE_MAX and
416 * idx is bounded by n_window
417 */
429 int rd_ptr = txq->q.read_ptr; 418 int rd_ptr = txq->q.read_ptr;
430 int idx = get_cmd_index(&txq->q, rd_ptr); 419 int idx = get_cmd_index(&txq->q, rd_ptr);
431 420
432 lockdep_assert_held(&txq->lock); 421 lockdep_assert_held(&txq->lock);
433 422
434 /* We have only q->n_window txq->entries, but we use q->n_bd tfds */ 423 /* We have only q->n_window txq->entries, but we use
424 * TFD_QUEUE_SIZE_MAX tfds
425 */
435 iwl_pcie_tfd_unmap(trans, &txq->entries[idx].meta, &tfd_tmp[rd_ptr]); 426 iwl_pcie_tfd_unmap(trans, &txq->entries[idx].meta, &tfd_tmp[rd_ptr]);
436 427
437 /* free SKB */ 428 /* free SKB */
@@ -452,7 +443,7 @@ static void iwl_pcie_txq_free_tfd(struct iwl_trans *trans, struct iwl_txq *txq)
452} 443}
453 444
454static int iwl_pcie_txq_build_tfd(struct iwl_trans *trans, struct iwl_txq *txq, 445static int iwl_pcie_txq_build_tfd(struct iwl_trans *trans, struct iwl_txq *txq,
455 dma_addr_t addr, u16 len, u8 reset) 446 dma_addr_t addr, u16 len, bool reset)
456{ 447{
457 struct iwl_queue *q; 448 struct iwl_queue *q;
458 struct iwl_tfd *tfd, *tfd_tmp; 449 struct iwl_tfd *tfd, *tfd_tmp;
@@ -565,8 +556,7 @@ static int iwl_pcie_txq_init(struct iwl_trans *trans, struct iwl_txq *txq,
565 BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1)); 556 BUILD_BUG_ON(TFD_QUEUE_SIZE_MAX & (TFD_QUEUE_SIZE_MAX - 1));
566 557
567 /* Initialize queue's high/low-water marks, and head/tail indexes */ 558 /* Initialize queue's high/low-water marks, and head/tail indexes */
568 ret = iwl_queue_init(&txq->q, TFD_QUEUE_SIZE_MAX, slots_num, 559 ret = iwl_queue_init(&txq->q, slots_num, txq_id);
569 txq_id);
570 if (ret) 560 if (ret)
571 return ret; 561 return ret;
572 562
@@ -591,15 +581,12 @@ static void iwl_pcie_txq_unmap(struct iwl_trans *trans, int txq_id)
591 struct iwl_txq *txq = &trans_pcie->txq[txq_id]; 581 struct iwl_txq *txq = &trans_pcie->txq[txq_id];
592 struct iwl_queue *q = &txq->q; 582 struct iwl_queue *q = &txq->q;
593 583
594 if (!q->n_bd)
595 return;
596
597 spin_lock_bh(&txq->lock); 584 spin_lock_bh(&txq->lock);
598 while (q->write_ptr != q->read_ptr) { 585 while (q->write_ptr != q->read_ptr) {
599 IWL_DEBUG_TX_REPLY(trans, "Q %d Free %d\n", 586 IWL_DEBUG_TX_REPLY(trans, "Q %d Free %d\n",
600 txq_id, q->read_ptr); 587 txq_id, q->read_ptr);
601 iwl_pcie_txq_free_tfd(trans, txq); 588 iwl_pcie_txq_free_tfd(trans, txq);
602 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd); 589 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr);
603 } 590 }
604 txq->active = false; 591 txq->active = false;
605 spin_unlock_bh(&txq->lock); 592 spin_unlock_bh(&txq->lock);
@@ -636,10 +623,12 @@ static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id)
636 } 623 }
637 624
638 /* De-alloc circular buffer of TFDs */ 625 /* De-alloc circular buffer of TFDs */
639 if (txq->q.n_bd) { 626 if (txq->tfds) {
640 dma_free_coherent(dev, sizeof(struct iwl_tfd) * 627 dma_free_coherent(dev,
641 txq->q.n_bd, txq->tfds, txq->q.dma_addr); 628 sizeof(struct iwl_tfd) * TFD_QUEUE_SIZE_MAX,
629 txq->tfds, txq->q.dma_addr);
642 txq->q.dma_addr = 0; 630 txq->q.dma_addr = 0;
631 txq->tfds = NULL;
643 632
644 dma_free_coherent(dev, 633 dma_free_coherent(dev,
645 sizeof(*txq->scratchbufs) * txq->q.n_window, 634 sizeof(*txq->scratchbufs) * txq->q.n_window,
@@ -948,8 +937,7 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
948{ 937{
949 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 938 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
950 struct iwl_txq *txq = &trans_pcie->txq[txq_id]; 939 struct iwl_txq *txq = &trans_pcie->txq[txq_id];
951 /* n_bd is usually 256 => n_bd - 1 = 0xff */ 940 int tfd_num = ssn & (TFD_QUEUE_SIZE_MAX - 1);
952 int tfd_num = ssn & (txq->q.n_bd - 1);
953 struct iwl_queue *q = &txq->q; 941 struct iwl_queue *q = &txq->q;
954 int last_to_free; 942 int last_to_free;
955 943
@@ -973,12 +961,12 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
973 961
974 /*Since we free until index _not_ inclusive, the one before index is 962 /*Since we free until index _not_ inclusive, the one before index is
975 * the last we will free. This one must be used */ 963 * the last we will free. This one must be used */
976 last_to_free = iwl_queue_dec_wrap(tfd_num, q->n_bd); 964 last_to_free = iwl_queue_dec_wrap(tfd_num);
977 965
978 if (!iwl_queue_used(q, last_to_free)) { 966 if (!iwl_queue_used(q, last_to_free)) {
979 IWL_ERR(trans, 967 IWL_ERR(trans,
980 "%s: Read index for DMA queue txq id (%d), last_to_free %d is out of range [0-%d] %d %d.\n", 968 "%s: Read index for DMA queue txq id (%d), last_to_free %d is out of range [0-%d] %d %d.\n",
981 __func__, txq_id, last_to_free, q->n_bd, 969 __func__, txq_id, last_to_free, TFD_QUEUE_SIZE_MAX,
982 q->write_ptr, q->read_ptr); 970 q->write_ptr, q->read_ptr);
983 goto out; 971 goto out;
984 } 972 }
@@ -988,7 +976,7 @@ void iwl_trans_pcie_reclaim(struct iwl_trans *trans, int txq_id, int ssn,
988 976
989 for (; 977 for (;
990 q->read_ptr != tfd_num; 978 q->read_ptr != tfd_num;
991 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { 979 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr)) {
992 980
993 if (WARN_ON_ONCE(txq->entries[txq->q.read_ptr].skb == NULL)) 981 if (WARN_ON_ONCE(txq->entries[txq->q.read_ptr].skb == NULL))
994 continue; 982 continue;
@@ -1027,16 +1015,16 @@ static void iwl_pcie_cmdq_reclaim(struct iwl_trans *trans, int txq_id, int idx)
1027 1015
1028 lockdep_assert_held(&txq->lock); 1016 lockdep_assert_held(&txq->lock);
1029 1017
1030 if ((idx >= q->n_bd) || (!iwl_queue_used(q, idx))) { 1018 if ((idx >= TFD_QUEUE_SIZE_MAX) || (!iwl_queue_used(q, idx))) {
1031 IWL_ERR(trans, 1019 IWL_ERR(trans,
1032 "%s: Read index for DMA queue txq id (%d), index %d is out of range [0-%d] %d %d.\n", 1020 "%s: Read index for DMA queue txq id (%d), index %d is out of range [0-%d] %d %d.\n",
1033 __func__, txq_id, idx, q->n_bd, 1021 __func__, txq_id, idx, TFD_QUEUE_SIZE_MAX,
1034 q->write_ptr, q->read_ptr); 1022 q->write_ptr, q->read_ptr);
1035 return; 1023 return;
1036 } 1024 }
1037 1025
1038 for (idx = iwl_queue_inc_wrap(idx, q->n_bd); q->read_ptr != idx; 1026 for (idx = iwl_queue_inc_wrap(idx); q->read_ptr != idx;
1039 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd)) { 1027 q->read_ptr = iwl_queue_inc_wrap(q->read_ptr)) {
1040 1028
1041 if (nfreed++ > 0) { 1029 if (nfreed++ > 0) {
1042 IWL_ERR(trans, "HCMD skipped: index (%d) %d %d\n", 1030 IWL_ERR(trans, "HCMD skipped: index (%d) %d %d\n",
@@ -1327,28 +1315,39 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
1327 cmd_pos = offsetof(struct iwl_device_cmd, payload); 1315 cmd_pos = offsetof(struct iwl_device_cmd, payload);
1328 copy_size = sizeof(out_cmd->hdr); 1316 copy_size = sizeof(out_cmd->hdr);
1329 for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) { 1317 for (i = 0; i < IWL_MAX_CMD_TBS_PER_TFD; i++) {
1330 int copy = 0; 1318 int copy;
1331 1319
1332 if (!cmd->len[i]) 1320 if (!cmd->len[i])
1333 continue; 1321 continue;
1334 1322
1335 /* need at least IWL_HCMD_SCRATCHBUF_SIZE copied */
1336 if (copy_size < IWL_HCMD_SCRATCHBUF_SIZE) {
1337 copy = IWL_HCMD_SCRATCHBUF_SIZE - copy_size;
1338
1339 if (copy > cmd->len[i])
1340 copy = cmd->len[i];
1341 }
1342
1343 /* copy everything if not nocopy/dup */ 1323 /* copy everything if not nocopy/dup */
1344 if (!(cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY | 1324 if (!(cmd->dataflags[i] & (IWL_HCMD_DFL_NOCOPY |
1345 IWL_HCMD_DFL_DUP))) 1325 IWL_HCMD_DFL_DUP))) {
1346 copy = cmd->len[i]; 1326 copy = cmd->len[i];
1347 1327
1348 if (copy) {
1349 memcpy((u8 *)out_cmd + cmd_pos, cmd->data[i], copy); 1328 memcpy((u8 *)out_cmd + cmd_pos, cmd->data[i], copy);
1350 cmd_pos += copy; 1329 cmd_pos += copy;
1351 copy_size += copy; 1330 copy_size += copy;
1331 continue;
1332 }
1333
1334 /*
1335 * Otherwise we need at least IWL_HCMD_SCRATCHBUF_SIZE copied
1336 * in total (for the scratchbuf handling), but copy up to what
1337 * we can fit into the payload for debug dump purposes.
1338 */
1339 copy = min_t(int, TFD_MAX_PAYLOAD_SIZE - cmd_pos, cmd->len[i]);
1340
1341 memcpy((u8 *)out_cmd + cmd_pos, cmd->data[i], copy);
1342 cmd_pos += copy;
1343
1344 /* However, treat copy_size the proper way, we need it below */
1345 if (copy_size < IWL_HCMD_SCRATCHBUF_SIZE) {
1346 copy = IWL_HCMD_SCRATCHBUF_SIZE - copy_size;
1347
1348 if (copy > cmd->len[i])
1349 copy = cmd->len[i];
1350 copy_size += copy;
1352 } 1351 }
1353 } 1352 }
1354 1353
@@ -1363,7 +1362,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
1363 memcpy(&txq->scratchbufs[q->write_ptr], &out_cmd->hdr, scratch_size); 1362 memcpy(&txq->scratchbufs[q->write_ptr], &out_cmd->hdr, scratch_size);
1364 iwl_pcie_txq_build_tfd(trans, txq, 1363 iwl_pcie_txq_build_tfd(trans, txq,
1365 iwl_pcie_get_scratchbuf_dma(txq, q->write_ptr), 1364 iwl_pcie_get_scratchbuf_dma(txq, q->write_ptr),
1366 scratch_size, 1); 1365 scratch_size, true);
1367 1366
1368 /* map first command fragment, if any remains */ 1367 /* map first command fragment, if any remains */
1369 if (copy_size > scratch_size) { 1368 if (copy_size > scratch_size) {
@@ -1379,7 +1378,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
1379 } 1378 }
1380 1379
1381 iwl_pcie_txq_build_tfd(trans, txq, phys_addr, 1380 iwl_pcie_txq_build_tfd(trans, txq, phys_addr,
1382 copy_size - scratch_size, 0); 1381 copy_size - scratch_size, false);
1383 } 1382 }
1384 1383
1385 /* map the remaining (adjusted) nocopy/dup fragments */ 1384 /* map the remaining (adjusted) nocopy/dup fragments */
@@ -1402,7 +1401,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
1402 goto out; 1401 goto out;
1403 } 1402 }
1404 1403
1405 iwl_pcie_txq_build_tfd(trans, txq, phys_addr, cmdlen[i], 0); 1404 iwl_pcie_txq_build_tfd(trans, txq, phys_addr, cmdlen[i], false);
1406 } 1405 }
1407 1406
1408 out_meta->flags = cmd->flags; 1407 out_meta->flags = cmd->flags;
@@ -1445,7 +1444,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
1445 } 1444 }
1446 1445
1447 /* Increment and update queue's write index */ 1446 /* Increment and update queue's write index */
1448 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); 1447 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr);
1449 iwl_pcie_txq_inc_wr_ptr(trans, txq); 1448 iwl_pcie_txq_inc_wr_ptr(trans, txq);
1450 1449
1451 spin_unlock_irqrestore(&trans_pcie->reg_lock, flags); 1450 spin_unlock_irqrestore(&trans_pcie->reg_lock, flags);
@@ -1740,7 +1739,7 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
1740 memcpy(&txq->scratchbufs[q->write_ptr], &dev_cmd->hdr, 1739 memcpy(&txq->scratchbufs[q->write_ptr], &dev_cmd->hdr,
1741 IWL_HCMD_SCRATCHBUF_SIZE); 1740 IWL_HCMD_SCRATCHBUF_SIZE);
1742 iwl_pcie_txq_build_tfd(trans, txq, tb0_phys, 1741 iwl_pcie_txq_build_tfd(trans, txq, tb0_phys,
1743 IWL_HCMD_SCRATCHBUF_SIZE, 1); 1742 IWL_HCMD_SCRATCHBUF_SIZE, true);
1744 1743
1745 /* there must be data left over for TB1 or this code must be changed */ 1744 /* there must be data left over for TB1 or this code must be changed */
1746 BUILD_BUG_ON(sizeof(struct iwl_tx_cmd) < IWL_HCMD_SCRATCHBUF_SIZE); 1745 BUILD_BUG_ON(sizeof(struct iwl_tx_cmd) < IWL_HCMD_SCRATCHBUF_SIZE);
@@ -1750,7 +1749,7 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
1750 tb1_phys = dma_map_single(trans->dev, tb1_addr, tb1_len, DMA_TO_DEVICE); 1749 tb1_phys = dma_map_single(trans->dev, tb1_addr, tb1_len, DMA_TO_DEVICE);
1751 if (unlikely(dma_mapping_error(trans->dev, tb1_phys))) 1750 if (unlikely(dma_mapping_error(trans->dev, tb1_phys)))
1752 goto out_err; 1751 goto out_err;
1753 iwl_pcie_txq_build_tfd(trans, txq, tb1_phys, tb1_len, 0); 1752 iwl_pcie_txq_build_tfd(trans, txq, tb1_phys, tb1_len, false);
1754 1753
1755 /* 1754 /*
1756 * Set up TFD's third entry to point directly to remainder 1755 * Set up TFD's third entry to point directly to remainder
@@ -1766,7 +1765,7 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
1766 &txq->tfds[q->write_ptr]); 1765 &txq->tfds[q->write_ptr]);
1767 goto out_err; 1766 goto out_err;
1768 } 1767 }
1769 iwl_pcie_txq_build_tfd(trans, txq, tb2_phys, tb2_len, 0); 1768 iwl_pcie_txq_build_tfd(trans, txq, tb2_phys, tb2_len, false);
1770 } 1769 }
1771 1770
1772 /* Set up entry for this TFD in Tx byte-count array */ 1771 /* Set up entry for this TFD in Tx byte-count array */
@@ -1788,7 +1787,7 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb,
1788 mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout); 1787 mod_timer(&txq->stuck_timer, jiffies + trans_pcie->wd_timeout);
1789 1788
1790 /* Tell device the write index *just past* this latest filled TFD */ 1789 /* Tell device the write index *just past* this latest filled TFD */
1791 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr, q->n_bd); 1790 q->write_ptr = iwl_queue_inc_wrap(q->write_ptr);
1792 if (!wait_write_ptr) 1791 if (!wait_write_ptr)
1793 iwl_pcie_txq_inc_wr_ptr(trans, txq); 1792 iwl_pcie_txq_inc_wr_ptr(trans, txq);
1794 1793
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 9d7a52f5a410..a312c653d116 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -1676,7 +1676,9 @@ static int mac80211_hwsim_ampdu_action(struct ieee80211_hw *hw,
1676 return 0; 1676 return 0;
1677} 1677}
1678 1678
1679static void mac80211_hwsim_flush(struct ieee80211_hw *hw, u32 queues, bool drop) 1679static void mac80211_hwsim_flush(struct ieee80211_hw *hw,
1680 struct ieee80211_vif *vif,
1681 u32 queues, bool drop)
1680{ 1682{
1681 /* Not implemented, queues only on kernel side */ 1683 /* Not implemented, queues only on kernel side */
1682} 1684}
@@ -2056,6 +2058,7 @@ static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2,
2056 WIPHY_FLAG_AP_UAPSD | 2058 WIPHY_FLAG_AP_UAPSD |
2057 WIPHY_FLAG_HAS_CHANNEL_SWITCH; 2059 WIPHY_FLAG_HAS_CHANNEL_SWITCH;
2058 hw->wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR; 2060 hw->wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR;
2061 hw->wiphy->features |= NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE;
2059 2062
2060 /* ask mac80211 to reserve space for magic */ 2063 /* ask mac80211 to reserve space for magic */
2061 hw->vif_data_size = sizeof(struct hwsim_vif_priv); 2064 hw->vif_data_size = sizeof(struct hwsim_vif_priv);
diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c
index 2bd07d681c5e..e1c2f67ae85e 100644
--- a/drivers/net/wireless/mwifiex/11n.c
+++ b/drivers/net/wireless/mwifiex/11n.c
@@ -749,3 +749,45 @@ void mwifiex_set_ba_params(struct mwifiex_private *priv)
749 749
750 return; 750 return;
751} 751}
752
753u8 mwifiex_get_sec_chan_offset(int chan)
754{
755 u8 sec_offset;
756
757 switch (chan) {
758 case 36:
759 case 44:
760 case 52:
761 case 60:
762 case 100:
763 case 108:
764 case 116:
765 case 124:
766 case 132:
767 case 140:
768 case 149:
769 case 157:
770 sec_offset = IEEE80211_HT_PARAM_CHA_SEC_ABOVE;
771 break;
772 case 40:
773 case 48:
774 case 56:
775 case 64:
776 case 104:
777 case 112:
778 case 120:
779 case 128:
780 case 136:
781 case 144:
782 case 153:
783 case 161:
784 sec_offset = IEEE80211_HT_PARAM_CHA_SEC_BELOW;
785 break;
786 case 165:
787 default:
788 sec_offset = IEEE80211_HT_PARAM_CHA_SEC_NONE;
789 break;
790 }
791
792 return sec_offset;
793}
diff --git a/drivers/net/wireless/mwifiex/11n.h b/drivers/net/wireless/mwifiex/11n.h
index 40b007a00f4b..43889d9e3b35 100644
--- a/drivers/net/wireless/mwifiex/11n.h
+++ b/drivers/net/wireless/mwifiex/11n.h
@@ -63,6 +63,7 @@ int mwifiex_cmd_amsdu_aggr_ctrl(struct host_cmd_ds_command *cmd,
63 int cmd_action, 63 int cmd_action,
64 struct mwifiex_ds_11n_amsdu_aggr_ctrl *aa_ctrl); 64 struct mwifiex_ds_11n_amsdu_aggr_ctrl *aa_ctrl);
65void mwifiex_del_tx_ba_stream_tbl_by_ra(struct mwifiex_private *priv, u8 *ra); 65void mwifiex_del_tx_ba_stream_tbl_by_ra(struct mwifiex_private *priv, u8 *ra);
66u8 mwifiex_get_sec_chan_offset(int chan);
66 67
67static inline u8 68static inline u8
68mwifiex_is_station_ampdu_allowed(struct mwifiex_private *priv, 69mwifiex_is_station_ampdu_allowed(struct mwifiex_private *priv,
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index 421322f5e5fb..8dee6c86f4f1 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -960,9 +960,6 @@ mwifiex_cmd_timeout_func(unsigned long function_context)
960 if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING) 960 if (adapter->hw_status == MWIFIEX_HW_STATUS_INITIALIZING)
961 mwifiex_init_fw_complete(adapter); 961 mwifiex_init_fw_complete(adapter);
962 962
963 if (adapter->if_ops.fw_dump)
964 adapter->if_ops.fw_dump(adapter);
965
966 if (adapter->if_ops.card_reset) 963 if (adapter->if_ops.card_reset)
967 adapter->if_ops.card_reset(adapter); 964 adapter->if_ops.card_reset(adapter);
968} 965}
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index b485dc1ae5eb..ee59508307cc 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -169,6 +169,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
169#define TLV_TYPE_GWK_CIPHER (PROPRIETARY_TLV_BASE_ID + 146) 169#define TLV_TYPE_GWK_CIPHER (PROPRIETARY_TLV_BASE_ID + 146)
170#define TLV_TYPE_COALESCE_RULE (PROPRIETARY_TLV_BASE_ID + 154) 170#define TLV_TYPE_COALESCE_RULE (PROPRIETARY_TLV_BASE_ID + 154)
171#define TLV_TYPE_KEY_PARAM_V2 (PROPRIETARY_TLV_BASE_ID + 156) 171#define TLV_TYPE_KEY_PARAM_V2 (PROPRIETARY_TLV_BASE_ID + 156)
172#define TLV_TYPE_TDLS_IDLE_TIMEOUT (PROPRIETARY_TLV_BASE_ID + 194)
172#define TLV_TYPE_FW_API_REV (PROPRIETARY_TLV_BASE_ID + 199) 173#define TLV_TYPE_FW_API_REV (PROPRIETARY_TLV_BASE_ID + 199)
173 174
174#define MWIFIEX_TX_DATA_BUF_SIZE_2K 2048 175#define MWIFIEX_TX_DATA_BUF_SIZE_2K 2048
@@ -229,6 +230,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
229#define ISENABLED_40MHZ_INTOLERANT(Dot11nDevCap) (Dot11nDevCap & BIT(8)) 230#define ISENABLED_40MHZ_INTOLERANT(Dot11nDevCap) (Dot11nDevCap & BIT(8))
230#define ISSUPP_RXLDPC(Dot11nDevCap) (Dot11nDevCap & BIT(22)) 231#define ISSUPP_RXLDPC(Dot11nDevCap) (Dot11nDevCap & BIT(22))
231#define ISSUPP_BEAMFORMING(Dot11nDevCap) (Dot11nDevCap & BIT(30)) 232#define ISSUPP_BEAMFORMING(Dot11nDevCap) (Dot11nDevCap & BIT(30))
233#define ISALLOWED_CHANWIDTH40(ht_param) (ht_param & BIT(2))
232 234
233/* httxcfg bitmap 235/* httxcfg bitmap
234 * 0 reserved 236 * 0 reserved
@@ -487,6 +489,7 @@ enum P2P_MODES {
487#define EVENT_UAP_MIC_COUNTERMEASURES 0x0000004c 489#define EVENT_UAP_MIC_COUNTERMEASURES 0x0000004c
488#define EVENT_HOSTWAKE_STAIE 0x0000004d 490#define EVENT_HOSTWAKE_STAIE 0x0000004d
489#define EVENT_CHANNEL_SWITCH_ANN 0x00000050 491#define EVENT_CHANNEL_SWITCH_ANN 0x00000050
492#define EVENT_TDLS_GENERIC_EVENT 0x00000052
490#define EVENT_EXT_SCAN_REPORT 0x00000058 493#define EVENT_EXT_SCAN_REPORT 0x00000058
491#define EVENT_REMAIN_ON_CHAN_EXPIRED 0x0000005f 494#define EVENT_REMAIN_ON_CHAN_EXPIRED 0x0000005f
492 495
@@ -519,6 +522,7 @@ enum P2P_MODES {
519#define ACT_TDLS_DELETE 0x00 522#define ACT_TDLS_DELETE 0x00
520#define ACT_TDLS_CREATE 0x01 523#define ACT_TDLS_CREATE 0x01
521#define ACT_TDLS_CONFIG 0x02 524#define ACT_TDLS_CONFIG 0x02
525#define TDLS_EVENT_LINK_TEAR_DOWN 3
522 526
523#define MWIFIEX_FW_V15 15 527#define MWIFIEX_FW_V15 15
524 528
@@ -708,6 +712,13 @@ struct mwifiex_ie_types_vendor_param_set {
708 u8 ie[MWIFIEX_MAX_VSIE_LEN]; 712 u8 ie[MWIFIEX_MAX_VSIE_LEN];
709}; 713};
710 714
715#define MWIFIEX_TDLS_IDLE_TIMEOUT 60
716
717struct mwifiex_ie_types_tdls_idle_timeout {
718 struct mwifiex_ie_types_header header;
719 __le16 value;
720} __packed;
721
711struct mwifiex_ie_types_rsn_param_set { 722struct mwifiex_ie_types_rsn_param_set {
712 struct mwifiex_ie_types_header header; 723 struct mwifiex_ie_types_header header;
713 u8 rsn_ie[1]; 724 u8 rsn_ie[1];
@@ -1745,6 +1756,15 @@ struct host_cmd_ds_802_11_subsc_evt {
1745 __le16 events; 1756 __le16 events;
1746} __packed; 1757} __packed;
1747 1758
1759struct mwifiex_tdls_generic_event {
1760 __le16 type;
1761 u8 peer_mac[ETH_ALEN];
1762 union {
1763 __le16 reason_code;
1764 __le16 reserved;
1765 } u;
1766} __packed;
1767
1748struct mwifiex_ie { 1768struct mwifiex_ie {
1749 __le16 ie_index; 1769 __le16 ie_index;
1750 __le16 mgmt_subtype_mask; 1770 __le16 mgmt_subtype_mask;
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index 6bc645a120fa..cbabc12fbda3 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -881,8 +881,6 @@ mwifiex_add_card(void *card, struct semaphore *sem,
881 goto err_kmalloc; 881 goto err_kmalloc;
882 882
883 INIT_WORK(&adapter->main_work, mwifiex_main_work_queue); 883 INIT_WORK(&adapter->main_work, mwifiex_main_work_queue);
884 if (adapter->if_ops.iface_work)
885 INIT_WORK(&adapter->iface_work, adapter->if_ops.iface_work);
886 884
887 /* Register the device. Fill up the private data structure with relevant 885 /* Register the device. Fill up the private data structure with relevant
888 information from the card. */ 886 information from the card. */
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index d70457b26e26..34181192a666 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -674,7 +674,6 @@ struct mwifiex_if_ops {
674 void (*card_reset) (struct mwifiex_adapter *); 674 void (*card_reset) (struct mwifiex_adapter *);
675 void (*fw_dump)(struct mwifiex_adapter *); 675 void (*fw_dump)(struct mwifiex_adapter *);
676 int (*clean_pcie_ring) (struct mwifiex_adapter *adapter); 676 int (*clean_pcie_ring) (struct mwifiex_adapter *adapter);
677 void (*iface_work)(struct work_struct *work);
678}; 677};
679 678
680struct mwifiex_adapter { 679struct mwifiex_adapter {
@@ -810,7 +809,6 @@ struct mwifiex_adapter {
810 bool ext_scan; 809 bool ext_scan;
811 u8 fw_api_ver; 810 u8 fw_api_ver;
812 u8 fw_key_api_major_ver, fw_key_api_minor_ver; 811 u8 fw_key_api_major_ver, fw_key_api_minor_ver;
813 struct work_struct iface_work;
814}; 812};
815 813
816int mwifiex_init_lock_list(struct mwifiex_adapter *adapter); 814int mwifiex_init_lock_list(struct mwifiex_adapter *adapter);
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c
index 51989b31137a..c2cfeec466d8 100644
--- a/drivers/net/wireless/mwifiex/pcie.c
+++ b/drivers/net/wireless/mwifiex/pcie.c
@@ -37,9 +37,6 @@ static struct mwifiex_if_ops pcie_ops;
37 37
38static struct semaphore add_remove_card_sem; 38static struct semaphore add_remove_card_sem;
39 39
40/* enum mwifiex_pcie_work_flags bitmap */
41static unsigned long pcie_work_flags;
42
43static int 40static int
44mwifiex_map_pci_memory(struct mwifiex_adapter *adapter, struct sk_buff *skb, 41mwifiex_map_pci_memory(struct mwifiex_adapter *adapter, struct sk_buff *skb,
45 size_t size, int flags) 42 size_t size, int flags)
@@ -224,8 +221,6 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev)
224 if (!adapter || !adapter->priv_num) 221 if (!adapter || !adapter->priv_num)
225 return; 222 return;
226 223
227 cancel_work_sync(&adapter->iface_work);
228
229 if (user_rmmod) { 224 if (user_rmmod) {
230#ifdef CONFIG_PM_SLEEP 225#ifdef CONFIG_PM_SLEEP
231 if (adapter->is_suspended) 226 if (adapter->is_suspended)
@@ -312,17 +307,6 @@ static int mwifiex_read_reg(struct mwifiex_adapter *adapter, int reg, u32 *data)
312 return 0; 307 return 0;
313} 308}
314 309
315/* This function reads u8 data from PCIE card register. */
316static int mwifiex_read_reg_byte(struct mwifiex_adapter *adapter,
317 int reg, u8 *data)
318{
319 struct pcie_service_card *card = adapter->card;
320
321 *data = ioread8(card->pci_mmap1 + reg);
322
323 return 0;
324}
325
326/* 310/*
327 * This function adds delay loop to ensure FW is awake before proceeding. 311 * This function adds delay loop to ensure FW is awake before proceeding.
328 */ 312 */
@@ -2188,215 +2172,6 @@ static int mwifiex_pcie_host_to_card(struct mwifiex_adapter *adapter, u8 type,
2188 return 0; 2172 return 0;
2189} 2173}
2190 2174
2191/* This function read/write firmware */
2192static enum rdwr_status
2193mwifiex_pcie_rdwr_firmware(struct mwifiex_adapter *adapter, u8 doneflag)
2194{
2195 int ret, tries;
2196 u8 ctrl_data;
2197
2198 ret = mwifiex_write_reg(adapter, DEBUG_DUMP_CTRL_REG, DEBUG_HOST_READY);
2199 if (ret) {
2200 dev_err(adapter->dev, "PCIE write err\n");
2201 return RDWR_STATUS_FAILURE;
2202 }
2203
2204 for (tries = 0; tries < MAX_POLL_TRIES; tries++) {
2205 mwifiex_read_reg_byte(adapter, DEBUG_DUMP_CTRL_REG, &ctrl_data);
2206 if (ctrl_data == DEBUG_FW_DONE)
2207 return RDWR_STATUS_SUCCESS;
2208 if (doneflag && ctrl_data == doneflag)
2209 return RDWR_STATUS_DONE;
2210 if (ctrl_data != DEBUG_HOST_READY) {
2211 dev_info(adapter->dev,
2212 "The ctrl reg was changed, re-try again!\n");
2213 mwifiex_write_reg(adapter, DEBUG_DUMP_CTRL_REG,
2214 DEBUG_HOST_READY);
2215 if (ret) {
2216 dev_err(adapter->dev, "PCIE write err\n");
2217 return RDWR_STATUS_FAILURE;
2218 }
2219 }
2220 usleep_range(100, 200);
2221 }
2222
2223 dev_err(adapter->dev, "Fail to pull ctrl_data\n");
2224 return RDWR_STATUS_FAILURE;
2225}
2226
2227/* This function dump firmware memory to file */
2228static void mwifiex_pcie_fw_dump_work(struct work_struct *work)
2229{
2230 struct mwifiex_adapter *adapter =
2231 container_of(work, struct mwifiex_adapter, iface_work);
2232 unsigned int reg, reg_start, reg_end;
2233 u8 *dbg_ptr;
2234 struct timeval t;
2235 u8 dump_num = 0, idx, i, read_reg, doneflag = 0;
2236 enum rdwr_status stat;
2237 u32 memory_size;
2238 u8 filename[MAX_FULL_NAME_LEN];
2239 mm_segment_t fs;
2240 loff_t pos;
2241 u8 *end_ptr;
2242 u8 *name_prefix = "/var/log/fw_dump_";
2243 struct memory_type_mapping mem_type_mapping_tbl[] = {
2244 {"ITCM", NULL, NULL, 0xF0},
2245 {"DTCM", NULL, NULL, 0xF1},
2246 {"SQRAM", NULL, NULL, 0xF2},
2247 {"IRAM", NULL, NULL, 0xF3},
2248 };
2249
2250 if (!adapter) {
2251 dev_err(adapter->dev, "Could not dump firmwware info\n");
2252 return;
2253 }
2254
2255 do_gettimeofday(&t);
2256 dev_info(adapter->dev, "== mwifiex firmware dump start: %u.%06u ==\n",
2257 (u32)t.tv_sec, (u32)t.tv_usec);
2258
2259 /* Read the number of the memories which will dump */
2260 stat = mwifiex_pcie_rdwr_firmware(adapter, doneflag);
2261 if (stat == RDWR_STATUS_FAILURE)
2262 goto done;
2263
2264 reg = DEBUG_DUMP_START_REG;
2265 mwifiex_read_reg_byte(adapter, reg, &dump_num);
2266
2267 /* Read the length of every memory which will dump */
2268 for (idx = 0; idx < dump_num; idx++) {
2269 struct memory_type_mapping *entry = &mem_type_mapping_tbl[idx];
2270
2271 stat = mwifiex_pcie_rdwr_firmware(adapter, doneflag);
2272 if (stat == RDWR_STATUS_FAILURE)
2273 goto done;
2274
2275 memory_size = 0;
2276 reg = DEBUG_DUMP_START_REG;
2277 for (i = 0; i < 4; i++) {
2278 mwifiex_read_reg_byte(adapter, reg, &read_reg);
2279 memory_size |= (read_reg << (i * 8));
2280 reg++;
2281 }
2282
2283 if (memory_size == 0) {
2284 dev_info(adapter->dev, "Firmware dump Finished!\n");
2285 break;
2286 }
2287
2288 dev_info(adapter->dev,
2289 "%s_SIZE=0x%x\n", entry->mem_name, memory_size);
2290 entry->mem_ptr = vmalloc(memory_size + 1);
2291 if (!entry->mem_ptr) {
2292 dev_err(adapter->dev,
2293 "Vmalloc %s failed\n", entry->mem_name);
2294 goto done;
2295 }
2296 dbg_ptr = entry->mem_ptr;
2297 end_ptr = dbg_ptr + memory_size;
2298
2299 doneflag = entry->done_flag;
2300 do_gettimeofday(&t);
2301 dev_info(adapter->dev, "Start %s output %u.%06u, please wait...\n",
2302 entry->mem_name, (u32)t.tv_sec, (u32)t.tv_usec);
2303
2304 do {
2305 stat = mwifiex_pcie_rdwr_firmware(adapter, doneflag);
2306 if (RDWR_STATUS_FAILURE == stat)
2307 goto done;
2308
2309 reg_start = DEBUG_DUMP_START_REG;
2310 reg_end = DEBUG_DUMP_END_REG;
2311 for (reg = reg_start; reg <= reg_end; reg++) {
2312 mwifiex_read_reg_byte(adapter, reg, dbg_ptr);
2313 if (dbg_ptr < end_ptr)
2314 dbg_ptr++;
2315 else
2316 dev_err(adapter->dev,
2317 "Allocated buf not enough\n");
2318 }
2319
2320 if (stat != RDWR_STATUS_DONE)
2321 continue;
2322
2323 dev_info(adapter->dev, "%s done: size=0x%lx\n",
2324 entry->mem_name, dbg_ptr - entry->mem_ptr);
2325 memset(filename, 0, sizeof(filename));
2326 memcpy(filename, name_prefix, strlen(name_prefix));
2327 strcat(filename, entry->mem_name);
2328 do_gettimeofday(&t);
2329 entry->file_mem = filp_open(filename, O_CREAT | O_RDWR,
2330 0644);
2331 if (IS_ERR(entry->file_mem)) {
2332 dev_info(adapter->dev,
2333 "Create %s file failed at %s, opening another dir /tmp\n",
2334 entry->mem_name, filename);
2335 memset(filename, 0, sizeof(filename));
2336 sprintf(filename, "%s%s", "/tmp/fw_dump_",
2337 entry->mem_name);
2338 entry->file_mem =
2339 filp_open(filename,
2340 O_CREAT | O_RDWR, 0644);
2341 }
2342 if (!IS_ERR(entry->file_mem)) {
2343 dev_info(adapter->dev,
2344 "Start to save the output : %u.%06u, please wait...\n",
2345 (u32)t.tv_sec, (u32)t.tv_usec);
2346 fs = get_fs();
2347 set_fs(KERNEL_DS);
2348 pos = 0;
2349 vfs_write(entry->file_mem,
2350 (char __user *)entry->mem_ptr,
2351 memory_size, &pos);
2352 filp_close(entry->file_mem, NULL);
2353 set_fs(fs);
2354 dev_info(adapter->dev,
2355 "The output %s have been saved to file successfully!\n",
2356 entry->mem_name);
2357 } else {
2358 dev_err(adapter->dev,
2359 "Failed to create file %s\n", filename);
2360 }
2361 vfree(entry->mem_ptr);
2362 entry->mem_ptr = NULL;
2363 break;
2364 } while (true);
2365 }
2366 do_gettimeofday(&t);
2367 dev_info(adapter->dev, "== mwifiex firmware dump end: %u.%06u ==\n",
2368 (u32)t.tv_sec, (u32)t.tv_usec);
2369
2370done:
2371 for (idx = 0; idx < ARRAY_SIZE(mem_type_mapping_tbl); idx++) {
2372 struct memory_type_mapping *entry = &mem_type_mapping_tbl[idx];
2373
2374 if (entry->mem_ptr) {
2375 vfree(entry->mem_ptr);
2376 entry->mem_ptr = NULL;
2377 }
2378 }
2379
2380 return;
2381}
2382
2383static void mwifiex_pcie_work(struct work_struct *work)
2384{
2385 if (test_and_clear_bit(MWIFIEX_PCIE_WORK_FW_DUMP, &pcie_work_flags))
2386 mwifiex_pcie_fw_dump_work(work);
2387}
2388
2389/* This function dumps FW information */
2390static void mwifiex_pcie_fw_dump(struct mwifiex_adapter *adapter)
2391{
2392 if (test_bit(MWIFIEX_PCIE_WORK_FW_DUMP, &pcie_work_flags))
2393 return;
2394
2395 set_bit(MWIFIEX_PCIE_WORK_FW_DUMP, &pcie_work_flags);
2396
2397 schedule_work(&adapter->iface_work);
2398}
2399
2400/* 2175/*
2401 * This function initializes the PCI-E host memory space, WCB rings, etc. 2176 * This function initializes the PCI-E host memory space, WCB rings, etc.
2402 * 2177 *
@@ -2618,8 +2393,6 @@ static struct mwifiex_if_ops pcie_ops = {
2618 .cleanup_mpa_buf = NULL, 2393 .cleanup_mpa_buf = NULL,
2619 .init_fw_port = mwifiex_pcie_init_fw_port, 2394 .init_fw_port = mwifiex_pcie_init_fw_port,
2620 .clean_pcie_ring = mwifiex_clean_pcie_ring_buf, 2395 .clean_pcie_ring = mwifiex_clean_pcie_ring_buf,
2621 .fw_dump = mwifiex_pcie_fw_dump,
2622 .iface_work = mwifiex_pcie_work,
2623}; 2396};
2624 2397
2625/* 2398/*
diff --git a/drivers/net/wireless/mwifiex/pcie.h b/drivers/net/wireless/mwifiex/pcie.h
index 3abba32e9448..e8ec561f8a64 100644
--- a/drivers/net/wireless/mwifiex/pcie.h
+++ b/drivers/net/wireless/mwifiex/pcie.h
@@ -100,28 +100,6 @@
100#define MWIFIEX_DEF_SLEEP_COOKIE 0xBEEFBEEF 100#define MWIFIEX_DEF_SLEEP_COOKIE 0xBEEFBEEF
101#define MWIFIEX_MAX_DELAY_COUNT 5 101#define MWIFIEX_MAX_DELAY_COUNT 5
102 102
103#define DEBUG_DUMP_CTRL_REG 0xCF4
104#define DEBUG_DUMP_START_REG 0xCF8
105#define DEBUG_DUMP_END_REG 0xCFF
106#define DEBUG_HOST_READY 0xEE
107#define DEBUG_FW_DONE 0xFF
108
109#define MAX_NAME_LEN 8
110#define MAX_FULL_NAME_LEN 32
111
112struct memory_type_mapping {
113 u8 mem_name[MAX_NAME_LEN];
114 u8 *mem_ptr;
115 struct file *file_mem;
116 u8 done_flag;
117};
118
119enum rdwr_status {
120 RDWR_STATUS_SUCCESS = 0,
121 RDWR_STATUS_FAILURE = 1,
122 RDWR_STATUS_DONE = 2
123};
124
125struct mwifiex_pcie_card_reg { 103struct mwifiex_pcie_card_reg {
126 u16 cmd_addr_lo; 104 u16 cmd_addr_lo;
127 u16 cmd_addr_hi; 105 u16 cmd_addr_hi;
@@ -344,9 +322,4 @@ mwifiex_pcie_txbd_not_full(struct pcie_service_card *card)
344 322
345 return 0; 323 return 0;
346} 324}
347
348enum mwifiex_pcie_work_flags {
349 MWIFIEX_PCIE_WORK_FW_DUMP,
350};
351
352#endif /* _MWIFIEX_PCIE_H */ 325#endif /* _MWIFIEX_PCIE_H */
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c
index e3cac1495cc7..88202ce0c139 100644
--- a/drivers/net/wireless/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/mwifiex/sta_cmd.c
@@ -1546,6 +1546,7 @@ mwifiex_cmd_tdls_oper(struct mwifiex_private *priv,
1546 struct mwifiex_ie_types_extcap *extcap; 1546 struct mwifiex_ie_types_extcap *extcap;
1547 struct mwifiex_ie_types_vhtcap *vht_capab; 1547 struct mwifiex_ie_types_vhtcap *vht_capab;
1548 struct mwifiex_ie_types_aid *aid; 1548 struct mwifiex_ie_types_aid *aid;
1549 struct mwifiex_ie_types_tdls_idle_timeout *timeout;
1549 u8 *pos, qos_info; 1550 u8 *pos, qos_info;
1550 u16 config_len = 0; 1551 u16 config_len = 0;
1551 struct station_parameters *params = priv->sta_params; 1552 struct station_parameters *params = priv->sta_params;
@@ -1643,6 +1644,12 @@ mwifiex_cmd_tdls_oper(struct mwifiex_private *priv,
1643 config_len += sizeof(struct mwifiex_ie_types_aid); 1644 config_len += sizeof(struct mwifiex_ie_types_aid);
1644 } 1645 }
1645 1646
1647 timeout = (void *)(pos + config_len);
1648 timeout->header.type = cpu_to_le16(TLV_TYPE_TDLS_IDLE_TIMEOUT);
1649 timeout->header.len = cpu_to_le16(sizeof(timeout->value));
1650 timeout->value = cpu_to_le16(MWIFIEX_TDLS_IDLE_TIMEOUT);
1651 config_len += sizeof(struct mwifiex_ie_types_tdls_idle_timeout);
1652
1646 break; 1653 break;
1647 default: 1654 default:
1648 dev_err(priv->adapter->dev, "Unknown TDLS operation\n"); 1655 dev_err(priv->adapter->dev, "Unknown TDLS operation\n");
diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c
index 368450cc56c7..5aea719219a3 100644
--- a/drivers/net/wireless/mwifiex/sta_event.c
+++ b/drivers/net/wireless/mwifiex/sta_event.c
@@ -134,6 +134,42 @@ mwifiex_reset_connect_state(struct mwifiex_private *priv, u16 reason_code)
134 netif_carrier_off(priv->netdev); 134 netif_carrier_off(priv->netdev);
135} 135}
136 136
137static int mwifiex_parse_tdls_event(struct mwifiex_private *priv,
138 struct sk_buff *event_skb)
139{
140 struct mwifiex_adapter *adapter = priv->adapter;
141 struct mwifiex_sta_node *sta_ptr;
142 struct mwifiex_tdls_generic_event *tdls_evt =
143 (void *)event_skb->data + sizeof(adapter->event_cause);
144
145 /* reserved 2 bytes are not mandatory in tdls event */
146 if (event_skb->len < (sizeof(struct mwifiex_tdls_generic_event) -
147 sizeof(u16) - sizeof(adapter->event_cause))) {
148 dev_err(adapter->dev, "Invalid event length!\n");
149 return -1;
150 }
151
152 sta_ptr = mwifiex_get_sta_entry(priv, tdls_evt->peer_mac);
153 if (!sta_ptr) {
154 dev_err(adapter->dev, "cannot get sta entry!\n");
155 return -1;
156 }
157
158 switch (le16_to_cpu(tdls_evt->type)) {
159 case TDLS_EVENT_LINK_TEAR_DOWN:
160 cfg80211_tdls_oper_request(priv->netdev,
161 tdls_evt->peer_mac,
162 NL80211_TDLS_TEARDOWN,
163 le16_to_cpu(tdls_evt->u.reason_code),
164 GFP_KERNEL);
165 break;
166 default:
167 break;
168 }
169
170 return 0;
171}
172
137/* 173/*
138 * This function handles events generated by firmware. 174 * This function handles events generated by firmware.
139 * 175 *
@@ -459,6 +495,10 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
459 false); 495 false);
460 break; 496 break;
461 497
498 case EVENT_TDLS_GENERIC_EVENT:
499 ret = mwifiex_parse_tdls_event(priv, adapter->event_skb);
500 break;
501
462 default: 502 default:
463 dev_dbg(adapter->dev, "event: unknown event id: %#x\n", 503 dev_dbg(adapter->dev, "event: unknown event id: %#x\n",
464 eventcause); 504 eventcause);
diff --git a/drivers/net/wireless/mwifiex/tdls.c b/drivers/net/wireless/mwifiex/tdls.c
index 97662a1ba58c..6bef47c2a70d 100644
--- a/drivers/net/wireless/mwifiex/tdls.c
+++ b/drivers/net/wireless/mwifiex/tdls.c
@@ -185,6 +185,48 @@ static int mwifiex_tdls_add_vht_capab(struct mwifiex_private *priv,
185 return 0; 185 return 0;
186} 186}
187 187
188static int
189mwifiex_tdls_add_ht_oper(struct mwifiex_private *priv, u8 *mac,
190 u8 vht_enabled, struct sk_buff *skb)
191{
192 struct ieee80211_ht_operation *ht_oper;
193 struct mwifiex_sta_node *sta_ptr;
194 struct mwifiex_bssdescriptor *bss_desc =
195 &priv->curr_bss_params.bss_descriptor;
196 u8 *pos;
197
198 sta_ptr = mwifiex_get_sta_entry(priv, mac);
199 if (unlikely(!sta_ptr)) {
200 dev_warn(priv->adapter->dev,
201 "TDLS peer station not found in list\n");
202 return -1;
203 }
204
205 pos = (void *)skb_put(skb, sizeof(struct ieee80211_ht_operation) + 2);
206 *pos++ = WLAN_EID_HT_OPERATION;
207 *pos++ = sizeof(struct ieee80211_ht_operation);
208 ht_oper = (void *)pos;
209
210 ht_oper->primary_chan = bss_desc->channel;
211
212 /* follow AP's channel bandwidth */
213 if (ISSUPP_CHANWIDTH40(priv->adapter->hw_dot_11n_dev_cap) &&
214 bss_desc->bcn_ht_cap &&
215 ISALLOWED_CHANWIDTH40(bss_desc->bcn_ht_oper->ht_param))
216 ht_oper->ht_param = bss_desc->bcn_ht_oper->ht_param;
217
218 if (vht_enabled) {
219 ht_oper->ht_param =
220 mwifiex_get_sec_chan_offset(bss_desc->channel);
221 ht_oper->ht_param |= BIT(2);
222 }
223
224 memcpy(&sta_ptr->tdls_cap.ht_oper, ht_oper,
225 sizeof(struct ieee80211_ht_operation));
226
227 return 0;
228}
229
188static int mwifiex_tdls_add_vht_oper(struct mwifiex_private *priv, 230static int mwifiex_tdls_add_vht_oper(struct mwifiex_private *priv,
189 u8 *mac, struct sk_buff *skb) 231 u8 *mac, struct sk_buff *skb)
190{ 232{
@@ -428,6 +470,17 @@ static int mwifiex_prep_tdls_encap_data(struct mwifiex_private *priv,
428 dev_kfree_skb_any(skb); 470 dev_kfree_skb_any(skb);
429 return ret; 471 return ret;
430 } 472 }
473 ret = mwifiex_tdls_add_ht_oper(priv, peer, 1, skb);
474 if (ret) {
475 dev_kfree_skb_any(skb);
476 return ret;
477 }
478 } else {
479 ret = mwifiex_tdls_add_ht_oper(priv, peer, 0, skb);
480 if (ret) {
481 dev_kfree_skb_any(skb);
482 return ret;
483 }
431 } 484 }
432 break; 485 break;
433 486
diff --git a/drivers/net/wireless/orinoco/orinoco_usb.c b/drivers/net/wireless/orinoco/orinoco_usb.c
index f9805c9353d2..1cbb7835806f 100644
--- a/drivers/net/wireless/orinoco/orinoco_usb.c
+++ b/drivers/net/wireless/orinoco/orinoco_usb.c
@@ -1687,7 +1687,7 @@ static int ezusb_probe(struct usb_interface *interface,
1687 firmware.code = fw_entry->data; 1687 firmware.code = fw_entry->data;
1688 } 1688 }
1689 if (firmware.size && firmware.code) { 1689 if (firmware.size && firmware.code) {
1690 if (ezusb_firmware_download(upriv, &firmware)) 1690 if (ezusb_firmware_download(upriv, &firmware) < 0)
1691 goto error; 1691 goto error;
1692 } else { 1692 } else {
1693 err("No firmware to download"); 1693 err("No firmware to download");
diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c
index eede90b63f84..7be3a4839640 100644
--- a/drivers/net/wireless/p54/main.c
+++ b/drivers/net/wireless/p54/main.c
@@ -669,7 +669,8 @@ static unsigned int p54_flush_count(struct p54_common *priv)
669 return total; 669 return total;
670} 670}
671 671
672static void p54_flush(struct ieee80211_hw *dev, u32 queues, bool drop) 672static void p54_flush(struct ieee80211_hw *dev, struct ieee80211_vif *vif,
673 u32 queues, bool drop)
673{ 674{
674 struct p54_common *priv = dev->priv; 675 struct p54_common *priv = dev->priv;
675 unsigned int total, i; 676 unsigned int total, i;
diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
index 84164747ace0..54aaeb09debf 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
@@ -656,6 +656,7 @@ static int rsi_mac80211_ampdu_action(struct ieee80211_hw *hw,
656 case IEEE80211_AMPDU_TX_START: 656 case IEEE80211_AMPDU_TX_START:
657 common->vif_info[ii].seq_start = seq_no; 657 common->vif_info[ii].seq_start = seq_no;
658 ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid); 658 ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
659 status = 0;
659 break; 660 break;
660 661
661 case IEEE80211_AMPDU_TX_STOP_CONT: 662 case IEEE80211_AMPDU_TX_STOP_CONT:
diff --git a/drivers/net/wireless/rsi/rsi_91x_mgmt.c b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
index 1b28cda6ca88..2eefbf159bc0 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mgmt.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mgmt.c
@@ -1083,7 +1083,7 @@ void rsi_inform_bss_status(struct rsi_common *common,
1083{ 1083{
1084 if (status) { 1084 if (status) {
1085 rsi_hal_send_sta_notify_frame(common, 1085 rsi_hal_send_sta_notify_frame(common,
1086 NL80211_IFTYPE_STATION, 1086 RSI_IFTYPE_STATION,
1087 STA_CONNECTED, 1087 STA_CONNECTED,
1088 bssid, 1088 bssid,
1089 qos_enable, 1089 qos_enable,
@@ -1092,7 +1092,7 @@ void rsi_inform_bss_status(struct rsi_common *common,
1092 rsi_send_auto_rate_request(common); 1092 rsi_send_auto_rate_request(common);
1093 } else { 1093 } else {
1094 rsi_hal_send_sta_notify_frame(common, 1094 rsi_hal_send_sta_notify_frame(common,
1095 NL80211_IFTYPE_STATION, 1095 RSI_IFTYPE_STATION,
1096 STA_DISCONNECTED, 1096 STA_DISCONNECTED,
1097 bssid, 1097 bssid,
1098 qos_enable, 1098 qos_enable,
diff --git a/drivers/net/wireless/rsi/rsi_mgmt.h b/drivers/net/wireless/rsi/rsi_mgmt.h
index ac67c4ad63c2..225215a3b8bb 100644
--- a/drivers/net/wireless/rsi/rsi_mgmt.h
+++ b/drivers/net/wireless/rsi/rsi_mgmt.h
@@ -73,6 +73,7 @@
73#define RX_BA_INDICATION 1 73#define RX_BA_INDICATION 1
74#define RSI_TBL_SZ 40 74#define RSI_TBL_SZ 40
75#define MAX_RETRIES 8 75#define MAX_RETRIES 8
76#define RSI_IFTYPE_STATION 0
76 77
77#define STD_RATE_MCS7 0x07 78#define STD_RATE_MCS7 0x07
78#define STD_RATE_MCS6 0x06 79#define STD_RATE_MCS6 0x06
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index e3b885d8f7db..010b76505243 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -1448,7 +1448,8 @@ int rt2x00mac_conf_tx(struct ieee80211_hw *hw,
1448 struct ieee80211_vif *vif, u16 queue, 1448 struct ieee80211_vif *vif, u16 queue,
1449 const struct ieee80211_tx_queue_params *params); 1449 const struct ieee80211_tx_queue_params *params);
1450void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw); 1450void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw);
1451void rt2x00mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop); 1451void rt2x00mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1452 u32 queues, bool drop);
1452int rt2x00mac_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant); 1453int rt2x00mac_set_antenna(struct ieee80211_hw *hw, u32 tx_ant, u32 rx_ant);
1453int rt2x00mac_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant); 1454int rt2x00mac_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant, u32 *rx_ant);
1454void rt2x00mac_get_ringparam(struct ieee80211_hw *hw, 1455void rt2x00mac_get_ringparam(struct ieee80211_hw *hw,
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index ddeb5a709aa3..212ac4842c16 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -621,20 +621,18 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
621 bss_conf->bssid); 621 bss_conf->bssid);
622 622
623 /* 623 /*
624 * Update the beacon. This is only required on USB devices. PCI
625 * devices fetch beacons periodically.
626 */
627 if (changes & BSS_CHANGED_BEACON && rt2x00_is_usb(rt2x00dev))
628 rt2x00queue_update_beacon(rt2x00dev, vif);
629
630 /*
631 * Start/stop beaconing. 624 * Start/stop beaconing.
632 */ 625 */
633 if (changes & BSS_CHANGED_BEACON_ENABLED) { 626 if (changes & BSS_CHANGED_BEACON_ENABLED) {
634 if (!bss_conf->enable_beacon && intf->enable_beacon) { 627 if (!bss_conf->enable_beacon && intf->enable_beacon) {
635 rt2x00queue_clear_beacon(rt2x00dev, vif);
636 rt2x00dev->intf_beaconing--; 628 rt2x00dev->intf_beaconing--;
637 intf->enable_beacon = false; 629 intf->enable_beacon = false;
630 /*
631 * Clear beacon in the H/W for this vif. This is needed
632 * to disable beaconing on this particular interface
633 * and keep it running on other interfaces.
634 */
635 rt2x00queue_clear_beacon(rt2x00dev, vif);
638 636
639 if (rt2x00dev->intf_beaconing == 0) { 637 if (rt2x00dev->intf_beaconing == 0) {
640 /* 638 /*
@@ -645,11 +643,15 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw,
645 rt2x00queue_stop_queue(rt2x00dev->bcn); 643 rt2x00queue_stop_queue(rt2x00dev->bcn);
646 mutex_unlock(&intf->beacon_skb_mutex); 644 mutex_unlock(&intf->beacon_skb_mutex);
647 } 645 }
648
649
650 } else if (bss_conf->enable_beacon && !intf->enable_beacon) { 646 } else if (bss_conf->enable_beacon && !intf->enable_beacon) {
651 rt2x00dev->intf_beaconing++; 647 rt2x00dev->intf_beaconing++;
652 intf->enable_beacon = true; 648 intf->enable_beacon = true;
649 /*
650 * Upload beacon to the H/W. This is only required on
651 * USB devices. PCI devices fetch beacons periodically.
652 */
653 if (rt2x00_is_usb(rt2x00dev))
654 rt2x00queue_update_beacon(rt2x00dev, vif);
653 655
654 if (rt2x00dev->intf_beaconing == 1) { 656 if (rt2x00dev->intf_beaconing == 1) {
655 /* 657 /*
@@ -747,7 +749,8 @@ void rt2x00mac_rfkill_poll(struct ieee80211_hw *hw)
747} 749}
748EXPORT_SYMBOL_GPL(rt2x00mac_rfkill_poll); 750EXPORT_SYMBOL_GPL(rt2x00mac_rfkill_poll);
749 751
750void rt2x00mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop) 752void rt2x00mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
753 u32 queues, bool drop)
751{ 754{
752 struct rt2x00_dev *rt2x00dev = hw->priv; 755 struct rt2x00_dev *rt2x00dev = hw->priv;
753 struct data_queue *queue; 756 struct data_queue *queue;
diff --git a/drivers/net/wireless/rtl818x/rtl8180/dev.c b/drivers/net/wireless/rtl818x/rtl8180/dev.c
index 50d69b13f984..2c1c02bafa10 100644
--- a/drivers/net/wireless/rtl818x/rtl8180/dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8180/dev.c
@@ -284,6 +284,8 @@ static void rtl8180_handle_rx(struct ieee80211_hw *dev)
284 rx_status.band = dev->conf.chandef.chan->band; 284 rx_status.band = dev->conf.chandef.chan->band;
285 rx_status.mactime = tsft; 285 rx_status.mactime = tsft;
286 rx_status.flag |= RX_FLAG_MACTIME_START; 286 rx_status.flag |= RX_FLAG_MACTIME_START;
287 if (flags & RTL818X_RX_DESC_FLAG_SPLCP)
288 rx_status.flag |= RX_FLAG_SHORTPRE;
287 if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR) 289 if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR)
288 rx_status.flag |= RX_FLAG_FAILED_FCS_CRC; 290 rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
289 291
@@ -461,18 +463,23 @@ static void rtl8180_tx(struct ieee80211_hw *dev,
461 RTL818X_TX_DESC_FLAG_NO_ENC; 463 RTL818X_TX_DESC_FLAG_NO_ENC;
462 464
463 rc_flags = info->control.rates[0].flags; 465 rc_flags = info->control.rates[0].flags;
466
467 /* HW will perform RTS-CTS when only RTS flags is set.
468 * HW will perform CTS-to-self when both RTS and CTS flags are set.
469 * RTS rate and RTS duration will be used also for CTS-to-self.
470 */
464 if (rc_flags & IEEE80211_TX_RC_USE_RTS_CTS) { 471 if (rc_flags & IEEE80211_TX_RC_USE_RTS_CTS) {
465 tx_flags |= RTL818X_TX_DESC_FLAG_RTS; 472 tx_flags |= RTL818X_TX_DESC_FLAG_RTS;
466 tx_flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19; 473 tx_flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19;
474 rts_duration = ieee80211_rts_duration(dev, priv->vif,
475 skb->len, info);
467 } else if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { 476 } else if (rc_flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
468 tx_flags |= RTL818X_TX_DESC_FLAG_CTS; 477 tx_flags |= RTL818X_TX_DESC_FLAG_RTS | RTL818X_TX_DESC_FLAG_CTS;
469 tx_flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19; 478 tx_flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19;
479 rts_duration = ieee80211_ctstoself_duration(dev, priv->vif,
480 skb->len, info);
470 } 481 }
471 482
472 if (rc_flags & IEEE80211_TX_RC_USE_RTS_CTS)
473 rts_duration = ieee80211_rts_duration(dev, priv->vif, skb->len,
474 info);
475
476 if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8180) { 483 if (priv->chip_family == RTL818X_CHIP_FAMILY_RTL8180) {
477 unsigned int remainder; 484 unsigned int remainder;
478 485
diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c
index 0ca17cda48fa..629ad8cfa17b 100644
--- a/drivers/net/wireless/rtl818x/rtl8187/dev.c
+++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c
@@ -253,14 +253,21 @@ static void rtl8187_tx(struct ieee80211_hw *dev,
253 flags |= ieee80211_get_tx_rate(dev, info)->hw_value << 24; 253 flags |= ieee80211_get_tx_rate(dev, info)->hw_value << 24;
254 if (ieee80211_has_morefrags(tx_hdr->frame_control)) 254 if (ieee80211_has_morefrags(tx_hdr->frame_control))
255 flags |= RTL818X_TX_DESC_FLAG_MOREFRAG; 255 flags |= RTL818X_TX_DESC_FLAG_MOREFRAG;
256
257 /* HW will perform RTS-CTS when only RTS flags is set.
258 * HW will perform CTS-to-self when both RTS and CTS flags are set.
259 * RTS rate and RTS duration will be used also for CTS-to-self.
260 */
256 if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) { 261 if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_RTS_CTS) {
257 flags |= RTL818X_TX_DESC_FLAG_RTS; 262 flags |= RTL818X_TX_DESC_FLAG_RTS;
258 flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19; 263 flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19;
259 rts_dur = ieee80211_rts_duration(dev, priv->vif, 264 rts_dur = ieee80211_rts_duration(dev, priv->vif,
260 skb->len, info); 265 skb->len, info);
261 } else if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) { 266 } else if (info->control.rates[0].flags & IEEE80211_TX_RC_USE_CTS_PROTECT) {
262 flags |= RTL818X_TX_DESC_FLAG_CTS; 267 flags |= RTL818X_TX_DESC_FLAG_RTS | RTL818X_TX_DESC_FLAG_CTS;
263 flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19; 268 flags |= ieee80211_get_rts_cts_rate(dev, info)->hw_value << 19;
269 rts_dur = ieee80211_ctstoself_duration(dev, priv->vif,
270 skb->len, info);
264 } 271 }
265 272
266 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { 273 if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) {
@@ -381,6 +388,8 @@ static void rtl8187_rx_cb(struct urb *urb)
381 rx_status.freq = dev->conf.chandef.chan->center_freq; 388 rx_status.freq = dev->conf.chandef.chan->center_freq;
382 rx_status.band = dev->conf.chandef.chan->band; 389 rx_status.band = dev->conf.chandef.chan->band;
383 rx_status.flag |= RX_FLAG_MACTIME_START; 390 rx_status.flag |= RX_FLAG_MACTIME_START;
391 if (flags & RTL818X_RX_DESC_FLAG_SPLCP)
392 rx_status.flag |= RX_FLAG_SHORTPRE;
384 if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR) 393 if (flags & RTL818X_RX_DESC_FLAG_CRC32_ERR)
385 rx_status.flag |= RX_FLAG_FAILED_FCS_CRC; 394 rx_status.flag |= RX_FLAG_FAILED_FCS_CRC;
386 memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status)); 395 memcpy(IEEE80211_SKB_RXCB(skb), &rx_status, sizeof(rx_status));
diff --git a/drivers/net/wireless/rtlwifi/core.c b/drivers/net/wireless/rtlwifi/core.c
index 4ec424f26672..b1ed6d0796f6 100644
--- a/drivers/net/wireless/rtlwifi/core.c
+++ b/drivers/net/wireless/rtlwifi/core.c
@@ -1387,7 +1387,8 @@ static void rtl_op_rfkill_poll(struct ieee80211_hw *hw)
1387 * before switch channel or power save, or tx buffer packet 1387 * before switch channel or power save, or tx buffer packet
1388 * maybe send after offchannel or rf sleep, this may cause 1388 * maybe send after offchannel or rf sleep, this may cause
1389 * dis-association by AP */ 1389 * dis-association by AP */
1390static void rtl_op_flush(struct ieee80211_hw *hw, u32 queues, bool drop) 1390static void rtl_op_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1391 u32 queues, bool drop)
1391{ 1392{
1392 struct rtl_priv *rtlpriv = rtl_priv(hw); 1393 struct rtl_priv *rtlpriv = rtl_priv(hw);
1393 1394
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/sw.c b/drivers/net/wireless/rtlwifi/rtl8188ee/sw.c
index 1b4101bf9974..79792d477b43 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/sw.c
@@ -93,7 +93,7 @@ int rtl88e_init_sw_vars(struct ieee80211_hw *hw)
93 u8 tid; 93 u8 tid;
94 94
95 rtl8188ee_bt_reg_init(hw); 95 rtl8188ee_bt_reg_init(hw);
96 rtlpci->msi_support = true; 96 rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support;
97 97
98 rtlpriv->dm.dm_initialgain_enable = 1; 98 rtlpriv->dm.dm_initialgain_enable = 1;
99 rtlpriv->dm.dm_flag = 0; 99 rtlpriv->dm.dm_flag = 0;
@@ -267,6 +267,7 @@ static struct rtl_mod_params rtl88ee_mod_params = {
267 .inactiveps = true, 267 .inactiveps = true,
268 .swctrl_lps = false, 268 .swctrl_lps = false,
269 .fwctrl_lps = true, 269 .fwctrl_lps = true,
270 .msi_support = false,
270 .debug = DBG_EMERG, 271 .debug = DBG_EMERG,
271}; 272};
272 273
@@ -383,10 +384,12 @@ module_param_named(debug, rtl88ee_mod_params.debug, int, 0444);
383module_param_named(ips, rtl88ee_mod_params.inactiveps, bool, 0444); 384module_param_named(ips, rtl88ee_mod_params.inactiveps, bool, 0444);
384module_param_named(swlps, rtl88ee_mod_params.swctrl_lps, bool, 0444); 385module_param_named(swlps, rtl88ee_mod_params.swctrl_lps, bool, 0444);
385module_param_named(fwlps, rtl88ee_mod_params.fwctrl_lps, bool, 0444); 386module_param_named(fwlps, rtl88ee_mod_params.fwctrl_lps, bool, 0444);
387module_param_named(msi, rtl88ee_mod_params.msi_support, bool, 0444);
386MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n"); 388MODULE_PARM_DESC(swenc, "Set to 1 for software crypto (default 0)\n");
387MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n"); 389MODULE_PARM_DESC(ips, "Set to 0 to not use link power save (default 1)\n");
388MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n"); 390MODULE_PARM_DESC(swlps, "Set to 1 to use SW control power save (default 0)\n");
389MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n"); 391MODULE_PARM_DESC(fwlps, "Set to 1 to use FW control power save (default 1)\n");
392MODULE_PARM_DESC(msi, "Set to 1 to use MSI interrupts mode (default 0)\n");
390MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)"); 393MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
391 394
392static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume); 395static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume);
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c b/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c
index 06ef47cd6203..5b4c225396f2 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c
@@ -293,7 +293,7 @@ static void _rtl88ee_translate_rx_signal_stuff(struct ieee80211_hw *hw,
293 u8 *psaddr; 293 u8 *psaddr;
294 __le16 fc; 294 __le16 fc;
295 u16 type, ufc; 295 u16 type, ufc;
296 bool match_bssid, packet_toself, packet_beacon, addr; 296 bool match_bssid, packet_toself, packet_beacon = false, addr;
297 297
298 tmp_buf = skb->data + pstatus->rx_drvinfo_size + pstatus->rx_bufshift; 298 tmp_buf = skb->data + pstatus->rx_drvinfo_size + pstatus->rx_bufshift;
299 299
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
index 68b5c7e92cfb..a903c2671b4d 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
@@ -511,7 +511,7 @@ static int _rtl92cu_init_power_on(struct ieee80211_hw *hw)
511 pr_info("MAC auto ON okay!\n"); 511 pr_info("MAC auto ON okay!\n");
512 break; 512 break;
513 } 513 }
514 if (pollingCount++ > 100) { 514 if (pollingCount++ > 1000) {
515 RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, 515 RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
516 "Failed to polling REG_APS_FSMCO[APFM_ONMAC] done!\n"); 516 "Failed to polling REG_APS_FSMCO[APFM_ONMAC] done!\n");
517 return -ENODEV; 517 return -ENODEV;
@@ -1001,7 +1001,7 @@ int rtl92cu_hw_init(struct ieee80211_hw *hw)
1001 err = _rtl92cu_init_mac(hw); 1001 err = _rtl92cu_init_mac(hw);
1002 if (err) { 1002 if (err) {
1003 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "init mac failed!\n"); 1003 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "init mac failed!\n");
1004 return err; 1004 goto exit;
1005 } 1005 }
1006 err = rtl92c_download_fw(hw); 1006 err = rtl92c_download_fw(hw);
1007 if (err) { 1007 if (err) {
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
index 36b48be8329c..2b3c78baa9f8 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c
@@ -49,6 +49,12 @@ static u8 _rtl92se_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 skb_queue)
49 if (ieee80211_is_nullfunc(fc)) 49 if (ieee80211_is_nullfunc(fc))
50 return QSLT_HIGH; 50 return QSLT_HIGH;
51 51
52 /* Kernel commit 1bf4bbb4024dcdab changed EAPOL packets to use
53 * queue V0 at priority 7; however, the RTL8192SE appears to have
54 * that queue at priority 6
55 */
56 if (skb->priority == 7)
57 return QSLT_VO;
52 return skb->priority; 58 return skb->priority;
53} 59}
54 60
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/sw.c b/drivers/net/wireless/rtlwifi/rtl8723be/sw.c
index b4577ebc4bb0..ff12bf41644b 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/sw.c
@@ -92,7 +92,7 @@ int rtl8723be_init_sw_vars(struct ieee80211_hw *hw)
92 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 92 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
93 93
94 rtl8723be_bt_reg_init(hw); 94 rtl8723be_bt_reg_init(hw);
95 rtlpci->msi_support = true; 95 rtlpci->msi_support = rtlpriv->cfg->mod_params->msi_support;
96 rtlpriv->btcoexist.btc_ops = rtl_btc_get_ops_pointer(); 96 rtlpriv->btcoexist.btc_ops = rtl_btc_get_ops_pointer();
97 97
98 rtlpriv->dm.dm_initialgain_enable = 1; 98 rtlpriv->dm.dm_initialgain_enable = 1;
@@ -253,6 +253,7 @@ static struct rtl_mod_params rtl8723be_mod_params = {
253 .inactiveps = true, 253 .inactiveps = true,
254 .swctrl_lps = false, 254 .swctrl_lps = false,
255 .fwctrl_lps = true, 255 .fwctrl_lps = true,
256 .msi_support = false,
256 .debug = DBG_EMERG, 257 .debug = DBG_EMERG,
257}; 258};
258 259
@@ -365,9 +366,11 @@ module_param_named(debug, rtl8723be_mod_params.debug, int, 0444);
365module_param_named(ips, rtl8723be_mod_params.inactiveps, bool, 0444); 366module_param_named(ips, rtl8723be_mod_params.inactiveps, bool, 0444);
366module_param_named(swlps, rtl8723be_mod_params.swctrl_lps, bool, 0444); 367module_param_named(swlps, rtl8723be_mod_params.swctrl_lps, bool, 0444);
367module_param_named(fwlps, rtl8723be_mod_params.fwctrl_lps, bool, 0444); 368module_param_named(fwlps, rtl8723be_mod_params.fwctrl_lps, bool, 0444);
369module_param_named(msi, rtl8723be_mod_params.msi_support, bool, 0444);
368MODULE_PARM_DESC(swenc, "using hardware crypto (default 0 [hardware])\n"); 370MODULE_PARM_DESC(swenc, "using hardware crypto (default 0 [hardware])\n");
369MODULE_PARM_DESC(ips, "using no link power save (default 1 is open)\n"); 371MODULE_PARM_DESC(ips, "using no link power save (default 1 is open)\n");
370MODULE_PARM_DESC(fwlps, "using linked fw control power save (default 1 is open)\n"); 372MODULE_PARM_DESC(fwlps, "using linked fw control power save (default 1 is open)\n");
373MODULE_PARM_DESC(msi, "Set to 1 to use MSI interrupts mode (default 0)\n");
371MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)"); 374MODULE_PARM_DESC(debug, "Set debug level (0-5) (default 0)");
372 375
373static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume); 376static SIMPLE_DEV_PM_OPS(rtlwifi_pm_ops, rtl_pci_suspend, rtl_pci_resume);
diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h
index 6965afdf572a..eef93d1ccc56 100644
--- a/drivers/net/wireless/rtlwifi/wifi.h
+++ b/drivers/net/wireless/rtlwifi/wifi.h
@@ -2030,6 +2030,10 @@ struct rtl_mod_params {
2030 2030
2031 /* default: 1 = using linked fw power save */ 2031 /* default: 1 = using linked fw power save */
2032 bool fwctrl_lps; 2032 bool fwctrl_lps;
2033
2034 /* default: 0 = not using MSI interrupts mode */
2035 /* submodules should set their own defalut value */
2036 bool msi_support;
2033}; 2037};
2034 2038
2035struct rtl_hal_usbint_cfg { 2039struct rtl_hal_usbint_cfg {
diff --git a/drivers/net/wireless/ti/wl1251/event.c b/drivers/net/wireless/ti/wl1251/event.c
index db0105313745..c98630394a1a 100644
--- a/drivers/net/wireless/ti/wl1251/event.c
+++ b/drivers/net/wireless/ti/wl1251/event.c
@@ -124,11 +124,12 @@ static int wl1251_event_process(struct wl1251 *wl, struct event_mailbox *mbox)
124 return ret; 124 return ret;
125 } 125 }
126 126
127 if (wl->vif && vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID) { 127 if (vector & SYNCHRONIZATION_TIMEOUT_EVENT_ID) {
128 wl1251_debug(DEBUG_EVENT, "SYNCHRONIZATION_TIMEOUT_EVENT"); 128 wl1251_debug(DEBUG_EVENT, "SYNCHRONIZATION_TIMEOUT_EVENT");
129 129
130 /* indicate to the stack, that beacons have been lost */ 130 /* indicate to the stack, that beacons have been lost */
131 ieee80211_beacon_loss(wl->vif); 131 if (wl->vif && wl->vif->type == NL80211_IFTYPE_STATION)
132 ieee80211_beacon_loss(wl->vif);
132 } 133 }
133 134
134 if (vector & REGAINED_BSS_EVENT_ID) { 135 if (vector & REGAINED_BSS_EVENT_ID) {
diff --git a/drivers/net/wireless/ti/wl1251/main.c b/drivers/net/wireless/ti/wl1251/main.c
index 757e25784a8a..4e782f18ae34 100644
--- a/drivers/net/wireless/ti/wl1251/main.c
+++ b/drivers/net/wireless/ti/wl1251/main.c
@@ -550,6 +550,34 @@ static void wl1251_op_remove_interface(struct ieee80211_hw *hw,
550 mutex_unlock(&wl->mutex); 550 mutex_unlock(&wl->mutex);
551} 551}
552 552
553static int wl1251_build_null_data(struct wl1251 *wl)
554{
555 struct sk_buff *skb = NULL;
556 int size;
557 void *ptr;
558 int ret = -ENOMEM;
559
560 if (wl->bss_type == BSS_TYPE_IBSS) {
561 size = sizeof(struct wl12xx_null_data_template);
562 ptr = NULL;
563 } else {
564 skb = ieee80211_nullfunc_get(wl->hw, wl->vif);
565 if (!skb)
566 goto out;
567 size = skb->len;
568 ptr = skb->data;
569 }
570
571 ret = wl1251_cmd_template_set(wl, CMD_NULL_DATA, ptr, size);
572
573out:
574 dev_kfree_skb(skb);
575 if (ret)
576 wl1251_warning("cmd buld null data failed: %d", ret);
577
578 return ret;
579}
580
553static int wl1251_build_qos_null_data(struct wl1251 *wl) 581static int wl1251_build_qos_null_data(struct wl1251 *wl)
554{ 582{
555 struct ieee80211_qos_hdr template; 583 struct ieee80211_qos_hdr template;
@@ -687,16 +715,6 @@ static int wl1251_op_config(struct ieee80211_hw *hw, u32 changed)
687 wl->power_level = conf->power_level; 715 wl->power_level = conf->power_level;
688 } 716 }
689 717
690 /*
691 * Tell stack that connection is lost because hw encryption isn't
692 * supported in monitor mode.
693 * This requires temporary enabling of the hw connection monitor flag
694 */
695 if ((changed & IEEE80211_CONF_CHANGE_MONITOR) && wl->vif) {
696 wl->hw->flags |= IEEE80211_HW_CONNECTION_MONITOR;
697 ieee80211_connection_loss(wl->vif);
698 }
699
700out_sleep: 718out_sleep:
701 wl1251_ps_elp_sleep(wl); 719 wl1251_ps_elp_sleep(wl);
702 720
@@ -1103,24 +1121,19 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
1103 wl->rssi_thold = bss_conf->cqm_rssi_thold; 1121 wl->rssi_thold = bss_conf->cqm_rssi_thold;
1104 } 1122 }
1105 1123
1106 if (changed & BSS_CHANGED_BSSID) { 1124 if ((changed & BSS_CHANGED_BSSID) &&
1125 memcmp(wl->bssid, bss_conf->bssid, ETH_ALEN)) {
1107 memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN); 1126 memcpy(wl->bssid, bss_conf->bssid, ETH_ALEN);
1108 1127
1109 skb = ieee80211_nullfunc_get(wl->hw, wl->vif); 1128 if (!is_zero_ether_addr(wl->bssid)) {
1110 if (!skb) 1129 ret = wl1251_build_null_data(wl);
1111 goto out_sleep; 1130 if (ret < 0)
1112 1131 goto out_sleep;
1113 ret = wl1251_cmd_template_set(wl, CMD_NULL_DATA,
1114 skb->data, skb->len);
1115 dev_kfree_skb(skb);
1116 if (ret < 0)
1117 goto out_sleep;
1118 1132
1119 ret = wl1251_build_qos_null_data(wl); 1133 ret = wl1251_build_qos_null_data(wl);
1120 if (ret < 0) 1134 if (ret < 0)
1121 goto out; 1135 goto out_sleep;
1122 1136
1123 if (wl->bss_type != BSS_TYPE_IBSS) {
1124 ret = wl1251_join(wl, wl->bss_type, wl->channel, 1137 ret = wl1251_join(wl, wl->bss_type, wl->channel,
1125 wl->beacon_int, wl->dtim_period); 1138 wl->beacon_int, wl->dtim_period);
1126 if (ret < 0) 1139 if (ret < 0)
@@ -1129,9 +1142,6 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
1129 } 1142 }
1130 1143
1131 if (changed & BSS_CHANGED_ASSOC) { 1144 if (changed & BSS_CHANGED_ASSOC) {
1132 /* Disable temporary enabled hw connection monitor flag */
1133 wl->hw->flags &= ~IEEE80211_HW_CONNECTION_MONITOR;
1134
1135 if (bss_conf->assoc) { 1145 if (bss_conf->assoc) {
1136 wl->beacon_int = bss_conf->beacon_int; 1146 wl->beacon_int = bss_conf->beacon_int;
1137 1147
@@ -1216,8 +1226,8 @@ static void wl1251_op_bss_info_changed(struct ieee80211_hw *hw,
1216 if (ret < 0) 1226 if (ret < 0)
1217 goto out_sleep; 1227 goto out_sleep;
1218 1228
1219 ret = wl1251_join(wl, wl->bss_type, wl->beacon_int, 1229 ret = wl1251_join(wl, wl->bss_type, wl->channel,
1220 wl->channel, wl->dtim_period); 1230 wl->beacon_int, wl->dtim_period);
1221 1231
1222 if (ret < 0) 1232 if (ret < 0)
1223 goto out_sleep; 1233 goto out_sleep;
diff --git a/drivers/net/wireless/ti/wlcore/main.c b/drivers/net/wireless/ti/wlcore/main.c
index ed88d3913483..077eb5b9cd74 100644
--- a/drivers/net/wireless/ti/wlcore/main.c
+++ b/drivers/net/wireless/ti/wlcore/main.c
@@ -5184,7 +5184,8 @@ out:
5184 mutex_unlock(&wl->mutex); 5184 mutex_unlock(&wl->mutex);
5185} 5185}
5186 5186
5187static void wlcore_op_flush(struct ieee80211_hw *hw, u32 queues, bool drop) 5187static void wlcore_op_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
5188 u32 queues, bool drop)
5188{ 5189{
5189 struct wl1271 *wl = hw->priv; 5190 struct wl1271 *wl = hw->priv;
5190 5191
diff --git a/drivers/net/wireless/ti/wlcore/sdio.c b/drivers/net/wireless/ti/wlcore/sdio.c
index 29ef2492951f..d3dd7bfdf3f1 100644
--- a/drivers/net/wireless/ti/wlcore/sdio.c
+++ b/drivers/net/wireless/ti/wlcore/sdio.c
@@ -217,7 +217,7 @@ static struct wl1271_if_operations sdio_ops = {
217static int wl1271_probe(struct sdio_func *func, 217static int wl1271_probe(struct sdio_func *func,
218 const struct sdio_device_id *id) 218 const struct sdio_device_id *id)
219{ 219{
220 struct wlcore_platdev_data *pdev_data; 220 struct wlcore_platdev_data pdev_data;
221 struct wl12xx_sdio_glue *glue; 221 struct wl12xx_sdio_glue *glue;
222 struct resource res[1]; 222 struct resource res[1];
223 mmc_pm_flag_t mmcflags; 223 mmc_pm_flag_t mmcflags;
@@ -228,16 +228,13 @@ static int wl1271_probe(struct sdio_func *func,
228 if (func->num != 0x02) 228 if (func->num != 0x02)
229 return -ENODEV; 229 return -ENODEV;
230 230
231 pdev_data = kzalloc(sizeof(*pdev_data), GFP_KERNEL); 231 memset(&pdev_data, 0x00, sizeof(pdev_data));
232 if (!pdev_data) 232 pdev_data.if_ops = &sdio_ops;
233 goto out;
234
235 pdev_data->if_ops = &sdio_ops;
236 233
237 glue = kzalloc(sizeof(*glue), GFP_KERNEL); 234 glue = kzalloc(sizeof(*glue), GFP_KERNEL);
238 if (!glue) { 235 if (!glue) {
239 dev_err(&func->dev, "can't allocate glue\n"); 236 dev_err(&func->dev, "can't allocate glue\n");
240 goto out_free_pdev_data; 237 goto out;
241 } 238 }
242 239
243 glue->dev = &func->dev; 240 glue->dev = &func->dev;
@@ -248,9 +245,9 @@ static int wl1271_probe(struct sdio_func *func,
248 /* Use block mode for transferring over one block size of data */ 245 /* Use block mode for transferring over one block size of data */
249 func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE; 246 func->card->quirks |= MMC_QUIRK_BLKSZ_FOR_BYTE_MODE;
250 247
251 pdev_data->pdata = wl12xx_get_platform_data(); 248 pdev_data.pdata = wl12xx_get_platform_data();
252 if (IS_ERR(pdev_data->pdata)) { 249 if (IS_ERR(pdev_data.pdata)) {
253 ret = PTR_ERR(pdev_data->pdata); 250 ret = PTR_ERR(pdev_data.pdata);
254 dev_err(glue->dev, "missing wlan platform data: %d\n", ret); 251 dev_err(glue->dev, "missing wlan platform data: %d\n", ret);
255 goto out_free_glue; 252 goto out_free_glue;
256 } 253 }
@@ -260,7 +257,7 @@ static int wl1271_probe(struct sdio_func *func,
260 dev_dbg(glue->dev, "sdio PM caps = 0x%x\n", mmcflags); 257 dev_dbg(glue->dev, "sdio PM caps = 0x%x\n", mmcflags);
261 258
262 if (mmcflags & MMC_PM_KEEP_POWER) 259 if (mmcflags & MMC_PM_KEEP_POWER)
263 pdev_data->pdata->pwr_in_suspend = true; 260 pdev_data.pdata->pwr_in_suspend = true;
264 261
265 sdio_set_drvdata(func, glue); 262 sdio_set_drvdata(func, glue);
266 263
@@ -289,7 +286,7 @@ static int wl1271_probe(struct sdio_func *func,
289 286
290 memset(res, 0x00, sizeof(res)); 287 memset(res, 0x00, sizeof(res));
291 288
292 res[0].start = pdev_data->pdata->irq; 289 res[0].start = pdev_data.pdata->irq;
293 res[0].flags = IORESOURCE_IRQ; 290 res[0].flags = IORESOURCE_IRQ;
294 res[0].name = "irq"; 291 res[0].name = "irq";
295 292
@@ -299,8 +296,8 @@ static int wl1271_probe(struct sdio_func *func,
299 goto out_dev_put; 296 goto out_dev_put;
300 } 297 }
301 298
302 ret = platform_device_add_data(glue->core, pdev_data, 299 ret = platform_device_add_data(glue->core, &pdev_data,
303 sizeof(*pdev_data)); 300 sizeof(pdev_data));
304 if (ret) { 301 if (ret) {
305 dev_err(glue->dev, "can't add platform data\n"); 302 dev_err(glue->dev, "can't add platform data\n");
306 goto out_dev_put; 303 goto out_dev_put;
@@ -319,9 +316,6 @@ out_dev_put:
319out_free_glue: 316out_free_glue:
320 kfree(glue); 317 kfree(glue);
321 318
322out_free_pdev_data:
323 kfree(pdev_data);
324
325out: 319out:
326 return ret; 320 return ret;
327} 321}
diff --git a/drivers/net/wireless/ti/wlcore/spi.c b/drivers/net/wireless/ti/wlcore/spi.c
index dbe826dd7c23..5f3a389dd74c 100644
--- a/drivers/net/wireless/ti/wlcore/spi.c
+++ b/drivers/net/wireless/ti/wlcore/spi.c
@@ -327,27 +327,25 @@ static struct wl1271_if_operations spi_ops = {
327static int wl1271_probe(struct spi_device *spi) 327static int wl1271_probe(struct spi_device *spi)
328{ 328{
329 struct wl12xx_spi_glue *glue; 329 struct wl12xx_spi_glue *glue;
330 struct wlcore_platdev_data *pdev_data; 330 struct wlcore_platdev_data pdev_data;
331 struct resource res[1]; 331 struct resource res[1];
332 int ret = -ENOMEM; 332 int ret = -ENOMEM;
333 333
334 pdev_data = kzalloc(sizeof(*pdev_data), GFP_KERNEL); 334 memset(&pdev_data, 0x00, sizeof(pdev_data));
335 if (!pdev_data)
336 goto out;
337 335
338 pdev_data->pdata = dev_get_platdata(&spi->dev); 336 pdev_data.pdata = dev_get_platdata(&spi->dev);
339 if (!pdev_data->pdata) { 337 if (!pdev_data.pdata) {
340 dev_err(&spi->dev, "no platform data\n"); 338 dev_err(&spi->dev, "no platform data\n");
341 ret = -ENODEV; 339 ret = -ENODEV;
342 goto out_free_pdev_data; 340 goto out;
343 } 341 }
344 342
345 pdev_data->if_ops = &spi_ops; 343 pdev_data.if_ops = &spi_ops;
346 344
347 glue = kzalloc(sizeof(*glue), GFP_KERNEL); 345 glue = kzalloc(sizeof(*glue), GFP_KERNEL);
348 if (!glue) { 346 if (!glue) {
349 dev_err(&spi->dev, "can't allocate glue\n"); 347 dev_err(&spi->dev, "can't allocate glue\n");
350 goto out_free_pdev_data; 348 goto out;
351 } 349 }
352 350
353 glue->dev = &spi->dev; 351 glue->dev = &spi->dev;
@@ -385,8 +383,8 @@ static int wl1271_probe(struct spi_device *spi)
385 goto out_dev_put; 383 goto out_dev_put;
386 } 384 }
387 385
388 ret = platform_device_add_data(glue->core, pdev_data, 386 ret = platform_device_add_data(glue->core, &pdev_data,
389 sizeof(*pdev_data)); 387 sizeof(pdev_data));
390 if (ret) { 388 if (ret) {
391 dev_err(glue->dev, "can't add platform data\n"); 389 dev_err(glue->dev, "can't add platform data\n");
392 goto out_dev_put; 390 goto out_dev_put;
@@ -406,9 +404,6 @@ out_dev_put:
406out_free_glue: 404out_free_glue:
407 kfree(glue); 405 kfree(glue);
408 406
409out_free_pdev_data:
410 kfree(pdev_data);
411
412out: 407out:
413 return ret; 408 return ret;
414} 409}