aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2013-07-01 16:21:17 -0400
committerDavid S. Miller <davem@davemloft.net>2013-07-01 16:21:17 -0400
commite62bc9e55f75ecb41dac3e68cd4b61f9d9501f72 (patch)
tree0437bf3c50de5e1b1ef2b9d73cd802223158232a /drivers/net
parentfb825a550a1af75323cee9d62d6fb818384c8c95 (diff)
parent57ed5cd695d7373b8ae0ae9f10fe945e774d58f0 (diff)
Merge branch 'for-davem' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next
John W. Linville says: ==================== Yet one more pull request for wireless updates intended for 3.11... For the mac80211 bits, Johannes says: "Here we have a few memory leak fixes related to BSS struct handling mostly from Ben, including a fix for a more theoretical problem (associating while a BSS struct times out) from myself, a compilation warning fix from Arend, mesh fixes from Thomas, tracking the beacon bitrate (Alex), a bandwidth change event fix (Ilan) and some initial work for 5/10 MHz channels from Simon." Regarding the iwlwifi bits, Johannes says: "Emmanuel removed some unneeded/unsupported module parameters and adds a Bluetooth 1x1 lookup-table for some upcoming products. From Alex I have an older patch to add low-power receive support, this depended on a mac80211 commit that only just came in with the merge from wireless-next I did. Ilan made beacon timings better, and Eytan added some debug statements for thermal throttling. I have a few cleanups, a fix for a long-standing but rare warning, and, arguably the most important patch here, the firmware API version bump for the 7260/3160 devices." Also included is a Bluetooth pull -- Gustavo says: "Here goes a set of patches to 3.11. The biggest work here is from Andre Guedes on the move of the Discovery to use the new request framework. Other than that Johan provided a bunch of fixes to the L2CAP code. The rest are just small fixes and clean ups." On top of all that, there are a variety of updates and fixes to brcmfmac, rt2x00, wil6210, ath9k, ath10k, and a few others here and there. This also includes a pull of the wireless tree, in order to prevent some merge conflicts. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.c53
-rw-r--r--drivers/net/wireless/ath/ath10k/pci.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_eeprom.c7
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_hw.c62
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.h4
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h63
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9462_2p1_initvals.h1774
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/hif_usb.c8
-rw-r--r--drivers/net/wireless/ath/ath9k/htc.h16
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_debug.c97
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_init.c13
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c46
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c1
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c57
-rw-r--r--drivers/net/wireless/ath/ath9k/reg.h13
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c16
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.c12
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.h4
-rw-r--r--drivers/net/wireless/b43/Kconfig6
-rw-r--r--drivers/net/wireless/b43/main.c12
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c165
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c29
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c260
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h5
-rw-r--r--drivers/net/wireless/cw1200/cw1200.h2
-rw-r--r--drivers/net/wireless/cw1200/cw1200_spi.c32
-rw-r--r--drivers/net/wireless/cw1200/hwio.c18
-rw-r--r--drivers/net/wireless/cw1200/hwio.h31
-rw-r--r--drivers/net/wireless/cw1200/main.c4
-rw-r--r--drivers/net/wireless/cw1200/queue.c2
-rw-r--r--drivers/net/wireless/cw1200/sta.c23
-rw-r--r--drivers/net/wireless/cw1200/txrx.c9
-rw-r--r--drivers/net/wireless/cw1200/wsm.c33
-rw-r--r--drivers/net/wireless/cw1200/wsm.h45
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.c1
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_rx.c2
-rw-r--r--drivers/net/wireless/iwlwifi/Kconfig10
-rw-r--r--drivers/net/wireless/iwlwifi/Makefile1
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/Makefile1
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/agn.h37
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/dev.h13
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/lib.c6
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/mac80211.c2
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/main.c15
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/rs.c43
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/rx.c40
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/testmode.c471
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/tx.c12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-7000.c12
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-config.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.c16
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-modparams.h6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-test.c852
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-test.h161
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-testmode.h309
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/bt-coex.c21
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/d3.c6
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs.c27
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-power.h5
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c56
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h8
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/power.c22
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.c30
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tt.c22
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/rx.c71
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c17
-rw-r--r--drivers/net/wireless/rt2x00/rt2800.h12
-rw-r--r--drivers/net/wireless/rt2x00/rt2800lib.c53
-rw-r--r--drivers/net/wireless/rt2x00/rt2800pci.c11
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c8
-rw-r--r--drivers/net/wireless/rt2x00/rt61pci.c3
-rw-r--r--drivers/net/wireless/rt2x00/rt73usb.c3
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/sw.c6
77 files changed, 2817 insertions, 2513 deletions
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index 3446c989d6a6..da5c333d0d4b 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -54,7 +54,6 @@ static int ath10k_send_key(struct ath10k_vif *arvif,
54 key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX; 54 key->flags |= IEEE80211_KEY_FLAG_SW_MGMT_TX;
55 break; 55 break;
56 case WLAN_CIPHER_SUITE_TKIP: 56 case WLAN_CIPHER_SUITE_TKIP:
57 key->flags |= IEEE80211_KEY_FLAG_GENERATE_MMIC;
58 arg.key_cipher = WMI_CIPHER_TKIP; 57 arg.key_cipher = WMI_CIPHER_TKIP;
59 arg.key_txmic_len = 8; 58 arg.key_txmic_len = 8;
60 arg.key_rxmic_len = 8; 59 arg.key_rxmic_len = 8;
@@ -237,6 +236,8 @@ chan_to_phymode(const struct cfg80211_chan_def *chandef)
237 case NL80211_CHAN_WIDTH_40: 236 case NL80211_CHAN_WIDTH_40:
238 phymode = MODE_11NG_HT40; 237 phymode = MODE_11NG_HT40;
239 break; 238 break;
239 case NL80211_CHAN_WIDTH_5:
240 case NL80211_CHAN_WIDTH_10:
240 case NL80211_CHAN_WIDTH_80: 241 case NL80211_CHAN_WIDTH_80:
241 case NL80211_CHAN_WIDTH_80P80: 242 case NL80211_CHAN_WIDTH_80P80:
242 case NL80211_CHAN_WIDTH_160: 243 case NL80211_CHAN_WIDTH_160:
@@ -258,6 +259,8 @@ chan_to_phymode(const struct cfg80211_chan_def *chandef)
258 case NL80211_CHAN_WIDTH_80: 259 case NL80211_CHAN_WIDTH_80:
259 phymode = MODE_11AC_VHT80; 260 phymode = MODE_11AC_VHT80;
260 break; 261 break;
262 case NL80211_CHAN_WIDTH_5:
263 case NL80211_CHAN_WIDTH_10:
261 case NL80211_CHAN_WIDTH_80P80: 264 case NL80211_CHAN_WIDTH_80P80:
262 case NL80211_CHAN_WIDTH_160: 265 case NL80211_CHAN_WIDTH_160:
263 phymode = MODE_UNKNOWN; 266 phymode = MODE_UNKNOWN;
@@ -2721,30 +2724,30 @@ static const struct ieee80211_channel ath10k_2ghz_channels[] = {
2721}; 2724};
2722 2725
2723static const struct ieee80211_channel ath10k_5ghz_channels[] = { 2726static const struct ieee80211_channel ath10k_5ghz_channels[] = {
2724 CHAN5G(36, 5180, 14), 2727 CHAN5G(36, 5180, 0),
2725 CHAN5G(40, 5200, 15), 2728 CHAN5G(40, 5200, 0),
2726 CHAN5G(44, 5220, 16), 2729 CHAN5G(44, 5220, 0),
2727 CHAN5G(48, 5240, 17), 2730 CHAN5G(48, 5240, 0),
2728 CHAN5G(52, 5260, 18), 2731 CHAN5G(52, 5260, 0),
2729 CHAN5G(56, 5280, 19), 2732 CHAN5G(56, 5280, 0),
2730 CHAN5G(60, 5300, 20), 2733 CHAN5G(60, 5300, 0),
2731 CHAN5G(64, 5320, 21), 2734 CHAN5G(64, 5320, 0),
2732 CHAN5G(100, 5500, 22), 2735 CHAN5G(100, 5500, 0),
2733 CHAN5G(104, 5520, 23), 2736 CHAN5G(104, 5520, 0),
2734 CHAN5G(108, 5540, 24), 2737 CHAN5G(108, 5540, 0),
2735 CHAN5G(112, 5560, 25), 2738 CHAN5G(112, 5560, 0),
2736 CHAN5G(116, 5580, 26), 2739 CHAN5G(116, 5580, 0),
2737 CHAN5G(120, 5600, 27), 2740 CHAN5G(120, 5600, 0),
2738 CHAN5G(124, 5620, 28), 2741 CHAN5G(124, 5620, 0),
2739 CHAN5G(128, 5640, 29), 2742 CHAN5G(128, 5640, 0),
2740 CHAN5G(132, 5660, 30), 2743 CHAN5G(132, 5660, 0),
2741 CHAN5G(136, 5680, 31), 2744 CHAN5G(136, 5680, 0),
2742 CHAN5G(140, 5700, 32), 2745 CHAN5G(140, 5700, 0),
2743 CHAN5G(149, 5745, 33), 2746 CHAN5G(149, 5745, 0),
2744 CHAN5G(153, 5765, 34), 2747 CHAN5G(153, 5765, 0),
2745 CHAN5G(157, 5785, 35), 2748 CHAN5G(157, 5785, 0),
2746 CHAN5G(161, 5805, 36), 2749 CHAN5G(161, 5805, 0),
2747 CHAN5G(165, 5825, 37), 2750 CHAN5G(165, 5825, 0),
2748}; 2751};
2749 2752
2750static struct ieee80211_rate ath10k_rates[] = { 2753static struct ieee80211_rate ath10k_rates[] = {
diff --git a/drivers/net/wireless/ath/ath10k/pci.c b/drivers/net/wireless/ath/ath10k/pci.c
index c8e905669701..33af4672c909 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -1883,9 +1883,10 @@ static int ath10k_pci_start_intr_msix(struct ath10k *ar, int num)
1883 ath10k_warn("request_irq(%d) failed %d\n", 1883 ath10k_warn("request_irq(%d) failed %d\n",
1884 ar_pci->pdev->irq + i, ret); 1884 ar_pci->pdev->irq + i, ret);
1885 1885
1886 for (; i >= MSI_ASSIGN_CE_INITIAL; i--) 1886 for (i--; i >= MSI_ASSIGN_CE_INITIAL; i--)
1887 free_irq(ar_pci->pdev->irq, ar); 1887 free_irq(ar_pci->pdev->irq + i, ar);
1888 1888
1889 free_irq(ar_pci->pdev->irq + MSI_ASSIGN_FW, ar);
1889 pci_disable_msi(ar_pci->pdev); 1890 pci_disable_msi(ar_pci->pdev);
1890 return ret; 1891 return ret;
1891 } 1892 }
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
index 1e86977d3322..d105e43d22e1 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_eeprom.c
@@ -3606,7 +3606,7 @@ static void ar9003_hw_ant_ctrl_apply(struct ath_hw *ah, bool is2ghz)
3606 * 7:4 R/W SWITCH_TABLE_COM_SPDT_WLAN_IDLE 3606 * 7:4 R/W SWITCH_TABLE_COM_SPDT_WLAN_IDLE
3607 * SWITCH_TABLE_COM_SPDT_WLAN_IDLE 3607 * SWITCH_TABLE_COM_SPDT_WLAN_IDLE
3608 */ 3608 */
3609 if (AR_SREV_9462_20(ah) || AR_SREV_9565(ah)) { 3609 if (AR_SREV_9462_20_OR_LATER(ah) || AR_SREV_9565(ah)) {
3610 value = ar9003_switch_com_spdt_get(ah, is2ghz); 3610 value = ar9003_switch_com_spdt_get(ah, is2ghz);
3611 REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL, 3611 REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL,
3612 AR_SWITCH_TABLE_COM_SPDT_ALL, value); 3612 AR_SWITCH_TABLE_COM_SPDT_ALL, value);
@@ -4059,8 +4059,9 @@ static void ar9003_hw_thermo_cal_apply(struct ath_hw *ah)
4059{ 4059{
4060 u32 data, ko, kg; 4060 u32 data, ko, kg;
4061 4061
4062 if (!AR_SREV_9462_20(ah)) 4062 if (!AR_SREV_9462_20_OR_LATER(ah))
4063 return; 4063 return;
4064
4064 ar9300_otp_read_word(ah, 1, &data); 4065 ar9300_otp_read_word(ah, 1, &data);
4065 ko = data & 0xff; 4066 ko = data & 0xff;
4066 kg = (data >> 8) & 0xff; 4067 kg = (data >> 8) & 0xff;
@@ -4752,7 +4753,7 @@ tempslope:
4752 AR_PHY_TPC_19_ALPHA_THERM, temp_slope); 4753 AR_PHY_TPC_19_ALPHA_THERM, temp_slope);
4753 } 4754 }
4754 4755
4755 if (AR_SREV_9462_20(ah)) 4756 if (AR_SREV_9462_20_OR_LATER(ah))
4756 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1, 4757 REG_RMW_FIELD(ah, AR_PHY_TPC_19_B1,
4757 AR_PHY_TPC_19_B1_ALPHA_THERM, temp_slope); 4758 AR_PHY_TPC_19_B1_ALPHA_THERM, temp_slope);
4758 4759
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
index 671aaa7e7337..d402cb32283f 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -24,6 +24,7 @@
24#include "ar955x_1p0_initvals.h" 24#include "ar955x_1p0_initvals.h"
25#include "ar9580_1p0_initvals.h" 25#include "ar9580_1p0_initvals.h"
26#include "ar9462_2p0_initvals.h" 26#include "ar9462_2p0_initvals.h"
27#include "ar9462_2p1_initvals.h"
27#include "ar9565_1p0_initvals.h" 28#include "ar9565_1p0_initvals.h"
28 29
29/* General hardware code for the AR9003 hadware family */ 30/* General hardware code for the AR9003 hadware family */
@@ -197,6 +198,31 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
197 198
198 INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, 199 INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
199 ar9485_1_1_pcie_phy_clkreq_disable_L1); 200 ar9485_1_1_pcie_phy_clkreq_disable_L1);
201 } else if (AR_SREV_9462_21(ah)) {
202 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
203 ar9462_2p1_mac_core);
204 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_POST],
205 ar9462_2p1_mac_postamble);
206 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_CORE],
207 ar9462_2p1_baseband_core);
208 INIT_INI_ARRAY(&ah->iniBB[ATH_INI_POST],
209 ar9462_2p1_baseband_postamble);
210 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_CORE],
211 ar9462_2p1_radio_core);
212 INIT_INI_ARRAY(&ah->iniRadio[ATH_INI_POST],
213 ar9462_2p1_radio_postamble);
214 INIT_INI_ARRAY(&ah->ini_radio_post_sys2ant,
215 ar9462_2p1_radio_postamble_sys2ant);
216 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_PRE],
217 ar9462_2p1_soc_preamble);
218 INIT_INI_ARRAY(&ah->iniSOC[ATH_INI_POST],
219 ar9462_2p1_soc_postamble);
220 INIT_INI_ARRAY(&ah->iniModesRxGain,
221 ar9462_2p1_common_rx_gain);
222 INIT_INI_ARRAY(&ah->iniModesFastClock,
223 ar9462_2p1_modes_fast_clock);
224 INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
225 ar9462_2p1_baseband_core_txfir_coeff_japan_2484);
200 } else if (AR_SREV_9462_20(ah)) { 226 } else if (AR_SREV_9462_20(ah)) {
201 227
202 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], ar9462_2p0_mac_core); 228 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], ar9462_2p0_mac_core);
@@ -407,6 +433,9 @@ static void ar9003_tx_gain_table_mode0(struct ath_hw *ah)
407 else if (AR_SREV_9580(ah)) 433 else if (AR_SREV_9580(ah))
408 INIT_INI_ARRAY(&ah->iniModesTxGain, 434 INIT_INI_ARRAY(&ah->iniModesTxGain,
409 ar9580_1p0_lowest_ob_db_tx_gain_table); 435 ar9580_1p0_lowest_ob_db_tx_gain_table);
436 else if (AR_SREV_9462_21(ah))
437 INIT_INI_ARRAY(&ah->iniModesTxGain,
438 ar9462_2p1_modes_low_ob_db_tx_gain);
410 else if (AR_SREV_9462_20(ah)) 439 else if (AR_SREV_9462_20(ah))
411 INIT_INI_ARRAY(&ah->iniModesTxGain, 440 INIT_INI_ARRAY(&ah->iniModesTxGain,
412 ar9462_modes_low_ob_db_tx_gain_table_2p0); 441 ar9462_modes_low_ob_db_tx_gain_table_2p0);
@@ -438,6 +467,9 @@ static void ar9003_tx_gain_table_mode1(struct ath_hw *ah)
438 else if (AR_SREV_9550(ah)) 467 else if (AR_SREV_9550(ah))
439 INIT_INI_ARRAY(&ah->iniModesTxGain, 468 INIT_INI_ARRAY(&ah->iniModesTxGain,
440 ar955x_1p0_modes_no_xpa_tx_gain_table); 469 ar955x_1p0_modes_no_xpa_tx_gain_table);
470 else if (AR_SREV_9462_21(ah))
471 INIT_INI_ARRAY(&ah->iniModesTxGain,
472 ar9462_2p1_modes_high_ob_db_tx_gain);
441 else if (AR_SREV_9462_20(ah)) 473 else if (AR_SREV_9462_20(ah))
442 INIT_INI_ARRAY(&ah->iniModesTxGain, 474 INIT_INI_ARRAY(&ah->iniModesTxGain,
443 ar9462_modes_high_ob_db_tx_gain_table_2p0); 475 ar9462_modes_high_ob_db_tx_gain_table_2p0);
@@ -507,6 +539,12 @@ static void ar9003_tx_gain_table_mode4(struct ath_hw *ah)
507 else if (AR_SREV_9580(ah)) 539 else if (AR_SREV_9580(ah))
508 INIT_INI_ARRAY(&ah->iniModesTxGain, 540 INIT_INI_ARRAY(&ah->iniModesTxGain,
509 ar9580_1p0_mixed_ob_db_tx_gain_table); 541 ar9580_1p0_mixed_ob_db_tx_gain_table);
542 else if (AR_SREV_9462_21(ah))
543 INIT_INI_ARRAY(&ah->iniModesTxGain,
544 ar9462_2p1_modes_mix_ob_db_tx_gain);
545 else if (AR_SREV_9462_20(ah))
546 INIT_INI_ARRAY(&ah->iniModesTxGain,
547 ar9462_modes_mix_ob_db_tx_gain_table_2p0);
510 else 548 else
511 INIT_INI_ARRAY(&ah->iniModesTxGain, 549 INIT_INI_ARRAY(&ah->iniModesTxGain,
512 ar9300Modes_mixed_ob_db_tx_gain_table_2p2); 550 ar9300Modes_mixed_ob_db_tx_gain_table_2p2);
@@ -584,6 +622,9 @@ static void ar9003_rx_gain_table_mode0(struct ath_hw *ah)
584 } else if (AR_SREV_9580(ah)) 622 } else if (AR_SREV_9580(ah))
585 INIT_INI_ARRAY(&ah->iniModesRxGain, 623 INIT_INI_ARRAY(&ah->iniModesRxGain,
586 ar9580_1p0_rx_gain_table); 624 ar9580_1p0_rx_gain_table);
625 else if (AR_SREV_9462_21(ah))
626 INIT_INI_ARRAY(&ah->iniModesRxGain,
627 ar9462_2p1_common_rx_gain);
587 else if (AR_SREV_9462_20(ah)) 628 else if (AR_SREV_9462_20(ah))
588 INIT_INI_ARRAY(&ah->iniModesRxGain, 629 INIT_INI_ARRAY(&ah->iniModesRxGain,
589 ar9462_common_rx_gain_table_2p0); 630 ar9462_common_rx_gain_table_2p0);
@@ -606,6 +647,9 @@ static void ar9003_rx_gain_table_mode1(struct ath_hw *ah)
606 else if (AR_SREV_9485_11(ah)) 647 else if (AR_SREV_9485_11(ah))
607 INIT_INI_ARRAY(&ah->iniModesRxGain, 648 INIT_INI_ARRAY(&ah->iniModesRxGain,
608 ar9485Common_wo_xlna_rx_gain_1_1); 649 ar9485Common_wo_xlna_rx_gain_1_1);
650 else if (AR_SREV_9462_21(ah))
651 INIT_INI_ARRAY(&ah->iniModesRxGain,
652 ar9462_2p1_common_wo_xlna_rx_gain);
609 else if (AR_SREV_9462_20(ah)) 653 else if (AR_SREV_9462_20(ah))
610 INIT_INI_ARRAY(&ah->iniModesRxGain, 654 INIT_INI_ARRAY(&ah->iniModesRxGain,
611 ar9462_common_wo_xlna_rx_gain_table_2p0); 655 ar9462_common_wo_xlna_rx_gain_table_2p0);
@@ -627,7 +671,16 @@ static void ar9003_rx_gain_table_mode1(struct ath_hw *ah)
627 671
628static void ar9003_rx_gain_table_mode2(struct ath_hw *ah) 672static void ar9003_rx_gain_table_mode2(struct ath_hw *ah)
629{ 673{
630 if (AR_SREV_9462_20(ah)) { 674 if (AR_SREV_9462_21(ah)) {
675 INIT_INI_ARRAY(&ah->iniModesRxGain,
676 ar9462_2p1_common_mixed_rx_gain);
677 INIT_INI_ARRAY(&ah->ini_modes_rxgain_bb_core,
678 ar9462_2p1_baseband_core_mix_rxgain);
679 INIT_INI_ARRAY(&ah->ini_modes_rxgain_bb_postamble,
680 ar9462_2p1_baseband_postamble_mix_rxgain);
681 INIT_INI_ARRAY(&ah->ini_modes_rxgain_5g_xlna,
682 ar9462_2p1_baseband_postamble_5g_xlna);
683 } else if (AR_SREV_9462_20(ah)) {
631 INIT_INI_ARRAY(&ah->iniModesRxGain, 684 INIT_INI_ARRAY(&ah->iniModesRxGain,
632 ar9462_common_mixed_rx_gain_table_2p0); 685 ar9462_common_mixed_rx_gain_table_2p0);
633 INIT_INI_ARRAY(&ah->ini_modes_rxgain_bb_core, 686 INIT_INI_ARRAY(&ah->ini_modes_rxgain_bb_core,
@@ -641,7 +694,12 @@ static void ar9003_rx_gain_table_mode2(struct ath_hw *ah)
641 694
642static void ar9003_rx_gain_table_mode3(struct ath_hw *ah) 695static void ar9003_rx_gain_table_mode3(struct ath_hw *ah)
643{ 696{
644 if (AR_SREV_9462_20(ah)) { 697 if (AR_SREV_9462_21(ah)) {
698 INIT_INI_ARRAY(&ah->iniModesRxGain,
699 ar9462_2p1_common_5g_xlna_only_rx_gain);
700 INIT_INI_ARRAY(&ah->ini_modes_rxgain_5g_xlna,
701 ar9462_2p1_baseband_postamble_5g_xlna);
702 } else if (AR_SREV_9462_20(ah)) {
645 INIT_INI_ARRAY(&ah->iniModesRxGain, 703 INIT_INI_ARRAY(&ah->iniModesRxGain,
646 ar9462_2p0_5g_xlna_only_rxgain); 704 ar9462_2p0_5g_xlna_only_rxgain);
647 INIT_INI_ARRAY(&ah->ini_modes_rxgain_5g_xlna, 705 INIT_INI_ARRAY(&ah->ini_modes_rxgain_5g_xlna,
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.c b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
index df84d20e1092..1f694ab3cc78 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.c
@@ -743,7 +743,7 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
743 ar9003_hw_prog_ini(ah, &ah->iniMac[i], modesIndex); 743 ar9003_hw_prog_ini(ah, &ah->iniMac[i], modesIndex);
744 ar9003_hw_prog_ini(ah, &ah->iniBB[i], modesIndex); 744 ar9003_hw_prog_ini(ah, &ah->iniBB[i], modesIndex);
745 ar9003_hw_prog_ini(ah, &ah->iniRadio[i], modesIndex); 745 ar9003_hw_prog_ini(ah, &ah->iniRadio[i], modesIndex);
746 if (i == ATH_INI_POST && AR_SREV_9462_20(ah)) 746 if (i == ATH_INI_POST && AR_SREV_9462_20_OR_LATER(ah))
747 ar9003_hw_prog_ini(ah, 747 ar9003_hw_prog_ini(ah,
748 &ah->ini_radio_post_sys2ant, 748 &ah->ini_radio_post_sys2ant,
749 modesIndex); 749 modesIndex);
@@ -754,7 +754,7 @@ static int ar9003_hw_process_ini(struct ath_hw *ah,
754 */ 754 */
755 REG_WRITE_ARRAY(&ah->iniModesRxGain, 1, regWrites); 755 REG_WRITE_ARRAY(&ah->iniModesRxGain, 1, regWrites);
756 756
757 if (AR_SREV_9462_20(ah)) { 757 if (AR_SREV_9462_20_OR_LATER(ah)) {
758 /* 758 /*
759 * CUS217 mix LNA mode. 759 * CUS217 mix LNA mode.
760 */ 760 */
@@ -1512,7 +1512,7 @@ static int ar9003_hw_fast_chan_change(struct ath_hw *ah,
1512 ar9003_hw_prog_ini(ah, &ah->iniBB[ATH_INI_POST], modesIndex); 1512 ar9003_hw_prog_ini(ah, &ah->iniBB[ATH_INI_POST], modesIndex);
1513 ar9003_hw_prog_ini(ah, &ah->iniRadio[ATH_INI_POST], modesIndex); 1513 ar9003_hw_prog_ini(ah, &ah->iniRadio[ATH_INI_POST], modesIndex);
1514 1514
1515 if (AR_SREV_9462_20(ah)) 1515 if (AR_SREV_9462_20_OR_LATER(ah))
1516 ar9003_hw_prog_ini(ah, &ah->ini_radio_post_sys2ant, 1516 ar9003_hw_prog_ini(ah, &ah->ini_radio_post_sys2ant,
1517 modesIndex); 1517 modesIndex);
1518 1518
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
index 5013c731f9f6..d4d39f305a0b 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
@@ -954,7 +954,7 @@
954#define AR_PHY_TPC_5_B1 (AR_SM1_BASE + 0x208) 954#define AR_PHY_TPC_5_B1 (AR_SM1_BASE + 0x208)
955#define AR_PHY_TPC_6_B1 (AR_SM1_BASE + 0x20c) 955#define AR_PHY_TPC_6_B1 (AR_SM1_BASE + 0x20c)
956#define AR_PHY_TPC_11_B1 (AR_SM1_BASE + 0x220) 956#define AR_PHY_TPC_11_B1 (AR_SM1_BASE + 0x220)
957#define AR_PHY_PDADC_TAB_1 (AR_SM1_BASE + (AR_SREV_AR9462(ah) ? \ 957#define AR_PHY_PDADC_TAB_1 (AR_SM1_BASE + (AR_SREV_9462_20_OR_LATER(ah) ? \
958 0x280 : 0x240)) 958 0x280 : 0x240))
959#define AR_PHY_TPC_19_B1 (AR_SM1_BASE + 0x240) 959#define AR_PHY_TPC_19_B1 (AR_SM1_BASE + 0x240)
960#define AR_PHY_TPC_19_B1_ALPHA_THERM 0xff 960#define AR_PHY_TPC_19_B1_ALPHA_THERM 0xff
@@ -1048,7 +1048,7 @@
1048#define AR_GLB_GPIO_CONTROL (AR_GLB_BASE) 1048#define AR_GLB_GPIO_CONTROL (AR_GLB_BASE)
1049#define AR_PHY_GLB_CONTROL (AR_GLB_BASE + 0x44) 1049#define AR_PHY_GLB_CONTROL (AR_GLB_BASE + 0x44)
1050#define AR_GLB_SCRATCH(_ah) (AR_GLB_BASE + \ 1050#define AR_GLB_SCRATCH(_ah) (AR_GLB_BASE + \
1051 (AR_SREV_9462_20(_ah) ? 0x4c : 0x50)) 1051 (AR_SREV_9462_20_OR_LATER(_ah) ? 0x4c : 0x50))
1052#define AR_GLB_STATUS (AR_GLB_BASE + 0x48) 1052#define AR_GLB_STATUS (AR_GLB_BASE + 0x48)
1053 1053
1054/* 1054/*
diff --git a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h
index 1d6b705ba110..092b9d412e7f 100644
--- a/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9462_2p0_initvals.h
@@ -879,6 +879,69 @@ static const u32 ar9462_2p0_radio_postamble[][5] = {
879 {0x0001650c, 0x48000000, 0x40000000, 0x40000000, 0x40000000}, 879 {0x0001650c, 0x48000000, 0x40000000, 0x40000000, 0x40000000},
880}; 880};
881 881
882static const u32 ar9462_modes_mix_ob_db_tx_gain_table_2p0[][5] = {
883 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
884 {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
885 {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
886 {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
887 {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
888 {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
889 {0x0000a410, 0x0000d0da, 0x0000d0da, 0x0000d0de, 0x0000d0de},
890 {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
891 {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
892 {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002},
893 {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004},
894 {0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200},
895 {0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202},
896 {0x0000a514, 0x18022622, 0x18022622, 0x12000400, 0x12000400},
897 {0x0000a518, 0x1b022822, 0x1b022822, 0x16000402, 0x16000402},
898 {0x0000a51c, 0x20022842, 0x20022842, 0x19000404, 0x19000404},
899 {0x0000a520, 0x22022c41, 0x22022c41, 0x1c000603, 0x1c000603},
900 {0x0000a524, 0x28023042, 0x28023042, 0x21000a02, 0x21000a02},
901 {0x0000a528, 0x2c023044, 0x2c023044, 0x25000a04, 0x25000a04},
902 {0x0000a52c, 0x2f023644, 0x2f023644, 0x28000a20, 0x28000a20},
903 {0x0000a530, 0x34025643, 0x34025643, 0x2c000e20, 0x2c000e20},
904 {0x0000a534, 0x38025a44, 0x38025a44, 0x30000e22, 0x30000e22},
905 {0x0000a538, 0x3b025e45, 0x3b025e45, 0x34000e24, 0x34000e24},
906 {0x0000a53c, 0x41025e4a, 0x41025e4a, 0x38001640, 0x38001640},
907 {0x0000a540, 0x48025e6c, 0x48025e6c, 0x3c001660, 0x3c001660},
908 {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3f001861, 0x3f001861},
909 {0x0000a548, 0x55025eb3, 0x55025eb3, 0x43001a81, 0x43001a81},
910 {0x0000a54c, 0x58025ef3, 0x58025ef3, 0x47001a83, 0x47001a83},
911 {0x0000a550, 0x5d025ef6, 0x5d025ef6, 0x4a001c84, 0x4a001c84},
912 {0x0000a554, 0x62025f56, 0x62025f56, 0x4e001ce3, 0x4e001ce3},
913 {0x0000a558, 0x66027f56, 0x66027f56, 0x52001ce5, 0x52001ce5},
914 {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x56001ce9, 0x56001ce9},
915 {0x0000a560, 0x70049f56, 0x70049f56, 0x5a001ceb, 0x5a001ceb},
916 {0x0000a564, 0x751ffff6, 0x751ffff6, 0x5c001eec, 0x5c001eec},
917 {0x0000a568, 0x751ffff6, 0x751ffff6, 0x5e001ef0, 0x5e001ef0},
918 {0x0000a56c, 0x751ffff6, 0x751ffff6, 0x60001ef4, 0x60001ef4},
919 {0x0000a570, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6},
920 {0x0000a574, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6},
921 {0x0000a578, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6},
922 {0x0000a57c, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6},
923 {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
924 {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
925 {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
926 {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
927 {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000},
928 {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000},
929 {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501},
930 {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501},
931 {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03},
932 {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04},
933 {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04},
934 {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
935 {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
936 {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
937 {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
938 {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
939 {0x0000b2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
940 {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
941 {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
942 {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
943};
944
882static const u32 ar9462_modes_high_ob_db_tx_gain_table_2p0[][5] = { 945static const u32 ar9462_modes_high_ob_db_tx_gain_table_2p0[][5] = {
883 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */ 946 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
884 {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002}, 947 {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
diff --git a/drivers/net/wireless/ath/ath9k/ar9462_2p1_initvals.h b/drivers/net/wireless/ath/ath9k/ar9462_2p1_initvals.h
new file mode 100644
index 000000000000..4dbc294df7e3
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9462_2p1_initvals.h
@@ -0,0 +1,1774 @@
1/*
2 * Copyright (c) 2010-2011 Atheros Communications Inc.
3 * Copyright (c) 2011-2012 Qualcomm Atheros Inc.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18#ifndef INITVALS_9462_2P1_H
19#define INITVALS_9462_2P1_H
20
21/* AR9462 2.1 */
22
23static const u32 ar9462_2p1_mac_core[][2] = {
24 /* Addr allmodes */
25 {0x00000008, 0x00000000},
26 {0x00000030, 0x000e0085},
27 {0x00000034, 0x00000005},
28 {0x00000040, 0x00000000},
29 {0x00000044, 0x00000000},
30 {0x00000048, 0x00000008},
31 {0x0000004c, 0x00000010},
32 {0x00000050, 0x00000000},
33 {0x00001040, 0x002ffc0f},
34 {0x00001044, 0x002ffc0f},
35 {0x00001048, 0x002ffc0f},
36 {0x0000104c, 0x002ffc0f},
37 {0x00001050, 0x002ffc0f},
38 {0x00001054, 0x002ffc0f},
39 {0x00001058, 0x002ffc0f},
40 {0x0000105c, 0x002ffc0f},
41 {0x00001060, 0x002ffc0f},
42 {0x00001064, 0x002ffc0f},
43 {0x000010f0, 0x00000100},
44 {0x00001270, 0x00000000},
45 {0x000012b0, 0x00000000},
46 {0x000012f0, 0x00000000},
47 {0x0000143c, 0x00000000},
48 {0x0000147c, 0x00000000},
49 {0x00001810, 0x0f000003},
50 {0x00008000, 0x00000000},
51 {0x00008004, 0x00000000},
52 {0x00008008, 0x00000000},
53 {0x0000800c, 0x00000000},
54 {0x00008018, 0x00000000},
55 {0x00008020, 0x00000000},
56 {0x00008038, 0x00000000},
57 {0x0000803c, 0x00080000},
58 {0x00008040, 0x00000000},
59 {0x00008044, 0x00000000},
60 {0x00008048, 0x00000000},
61 {0x0000804c, 0xffffffff},
62 {0x00008054, 0x00000000},
63 {0x00008058, 0x00000000},
64 {0x0000805c, 0x000fc78f},
65 {0x00008060, 0x0000000f},
66 {0x00008064, 0x00000000},
67 {0x00008070, 0x00000310},
68 {0x00008074, 0x00000020},
69 {0x00008078, 0x00000000},
70 {0x0000809c, 0x0000000f},
71 {0x000080a0, 0x00000000},
72 {0x000080a4, 0x02ff0000},
73 {0x000080a8, 0x0e070605},
74 {0x000080ac, 0x0000000d},
75 {0x000080b0, 0x00000000},
76 {0x000080b4, 0x00000000},
77 {0x000080b8, 0x00000000},
78 {0x000080bc, 0x00000000},
79 {0x000080c0, 0x2a800000},
80 {0x000080c4, 0x06900168},
81 {0x000080c8, 0x13881c20},
82 {0x000080cc, 0x01f40000},
83 {0x000080d0, 0x00252500},
84 {0x000080d4, 0x00b00005},
85 {0x000080d8, 0x00400002},
86 {0x000080dc, 0x00000000},
87 {0x000080e0, 0xffffffff},
88 {0x000080e4, 0x0000ffff},
89 {0x000080e8, 0x3f3f3f3f},
90 {0x000080ec, 0x00000000},
91 {0x000080f0, 0x00000000},
92 {0x000080f4, 0x00000000},
93 {0x000080fc, 0x00020000},
94 {0x00008100, 0x00000000},
95 {0x00008108, 0x00000052},
96 {0x0000810c, 0x00000000},
97 {0x00008110, 0x00000000},
98 {0x00008114, 0x000007ff},
99 {0x00008118, 0x000000aa},
100 {0x0000811c, 0x00003210},
101 {0x00008124, 0x00000000},
102 {0x00008128, 0x00000000},
103 {0x0000812c, 0x00000000},
104 {0x00008130, 0x00000000},
105 {0x00008134, 0x00000000},
106 {0x00008138, 0x00000000},
107 {0x0000813c, 0x0000ffff},
108 {0x00008144, 0xffffffff},
109 {0x00008168, 0x00000000},
110 {0x0000816c, 0x00000000},
111 {0x00008170, 0x18486e00},
112 {0x00008174, 0x33332210},
113 {0x00008178, 0x00000000},
114 {0x0000817c, 0x00020000},
115 {0x000081c4, 0x33332210},
116 {0x000081c8, 0x00000000},
117 {0x000081cc, 0x00000000},
118 {0x000081d4, 0x00000000},
119 {0x000081ec, 0x00000000},
120 {0x000081f0, 0x00000000},
121 {0x000081f4, 0x00000000},
122 {0x000081f8, 0x00000000},
123 {0x000081fc, 0x00000000},
124 {0x00008240, 0x00100000},
125 {0x00008244, 0x0010f400},
126 {0x00008248, 0x00000800},
127 {0x0000824c, 0x0001e800},
128 {0x00008250, 0x00000000},
129 {0x00008254, 0x00000000},
130 {0x00008258, 0x00000000},
131 {0x0000825c, 0x40000000},
132 {0x00008260, 0x00080922},
133 {0x00008264, 0x99c00010},
134 {0x00008268, 0xffffffff},
135 {0x0000826c, 0x0000ffff},
136 {0x00008270, 0x00000000},
137 {0x00008274, 0x40000000},
138 {0x00008278, 0x003e4180},
139 {0x0000827c, 0x00000004},
140 {0x00008284, 0x0000002c},
141 {0x00008288, 0x0000002c},
142 {0x0000828c, 0x000000ff},
143 {0x00008294, 0x00000000},
144 {0x00008298, 0x00000000},
145 {0x0000829c, 0x00000000},
146 {0x00008300, 0x00000140},
147 {0x00008314, 0x00000000},
148 {0x0000831c, 0x0000010d},
149 {0x00008328, 0x00000000},
150 {0x0000832c, 0x0000001f},
151 {0x00008330, 0x00000302},
152 {0x00008334, 0x00000700},
153 {0x00008338, 0xffff0000},
154 {0x0000833c, 0x02400000},
155 {0x00008340, 0x000107ff},
156 {0x00008344, 0xaa48107b},
157 {0x00008348, 0x008f0000},
158 {0x0000835c, 0x00000000},
159 {0x00008360, 0xffffffff},
160 {0x00008364, 0xffffffff},
161 {0x00008368, 0x00000000},
162 {0x00008370, 0x00000000},
163 {0x00008374, 0x000000ff},
164 {0x00008378, 0x00000000},
165 {0x0000837c, 0x00000000},
166 {0x00008380, 0xffffffff},
167 {0x00008384, 0xffffffff},
168 {0x00008390, 0xffffffff},
169 {0x00008394, 0xffffffff},
170 {0x00008398, 0x00000000},
171 {0x0000839c, 0x00000000},
172 {0x000083a4, 0x0000fa14},
173 {0x000083a8, 0x000f0c00},
174 {0x000083ac, 0x33332210},
175 {0x000083b0, 0x33332210},
176 {0x000083b4, 0x33332210},
177 {0x000083b8, 0x33332210},
178 {0x000083bc, 0x00000000},
179 {0x000083c0, 0x00000000},
180 {0x000083c4, 0x00000000},
181 {0x000083c8, 0x00000000},
182 {0x000083cc, 0x00000200},
183 {0x000083d0, 0x000301ff},
184};
185
186static const u32 ar9462_2p1_mac_postamble[][5] = {
187 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
188 {0x00001030, 0x00000230, 0x00000460, 0x000002c0, 0x00000160},
189 {0x00001070, 0x00000168, 0x000002d0, 0x00000318, 0x0000018c},
190 {0x000010b0, 0x00000e60, 0x00001cc0, 0x00007c70, 0x00003e38},
191 {0x00008014, 0x03e803e8, 0x07d007d0, 0x10801600, 0x08400b00},
192 {0x0000801c, 0x128d8027, 0x128d804f, 0x12e00057, 0x12e0002b},
193 {0x00008120, 0x08f04800, 0x08f04800, 0x08f04810, 0x08f04810},
194 {0x000081d0, 0x00003210, 0x00003210, 0x0000320a, 0x0000320a},
195 {0x00008318, 0x00003e80, 0x00007d00, 0x00006880, 0x00003440},
196};
197
198static const u32 ar9462_2p1_baseband_core[][2] = {
199 /* Addr allmodes */
200 {0x00009800, 0xafe68e30},
201 {0x00009804, 0xfd14e000},
202 {0x00009808, 0x9c0a9f6b},
203 {0x0000980c, 0x04900000},
204 {0x00009814, 0x9280c00a},
205 {0x00009818, 0x00000000},
206 {0x0000981c, 0x00020028},
207 {0x00009834, 0x6400a290},
208 {0x00009838, 0x0108ecff},
209 {0x0000983c, 0x0d000600},
210 {0x00009880, 0x201fff00},
211 {0x00009884, 0x00001042},
212 {0x000098a4, 0x00200400},
213 {0x000098b0, 0x32440bbe},
214 {0x000098d0, 0x004b6a8e},
215 {0x000098d4, 0x00000820},
216 {0x000098dc, 0x00000000},
217 {0x000098e4, 0x01ffffff},
218 {0x000098e8, 0x01ffffff},
219 {0x000098ec, 0x01ffffff},
220 {0x000098f0, 0x00000000},
221 {0x000098f4, 0x00000000},
222 {0x00009bf0, 0x80000000},
223 {0x00009c04, 0xff55ff55},
224 {0x00009c08, 0x0320ff55},
225 {0x00009c0c, 0x00000000},
226 {0x00009c10, 0x00000000},
227 {0x00009c14, 0x00046384},
228 {0x00009c18, 0x05b6b440},
229 {0x00009c1c, 0x00b6b440},
230 {0x00009d00, 0xc080a333},
231 {0x00009d04, 0x40206c10},
232 {0x00009d08, 0x009c4060},
233 {0x00009d0c, 0x9883800a},
234 {0x00009d10, 0x01834061},
235 {0x00009d14, 0x00c0040b},
236 {0x00009d18, 0x00000000},
237 {0x00009e08, 0x0038230c},
238 {0x00009e24, 0x990bb515},
239 {0x00009e28, 0x0c6f0000},
240 {0x00009e30, 0x06336f77},
241 {0x00009e34, 0x6af6532f},
242 {0x00009e38, 0x0cc80c00},
243 {0x00009e40, 0x15262820},
244 {0x00009e4c, 0x00001004},
245 {0x00009e50, 0x00ff03f1},
246 {0x00009e54, 0xe4c555c2},
247 {0x00009e58, 0xfd857722},
248 {0x00009e5c, 0xe9198724},
249 {0x00009fc0, 0x803e4788},
250 {0x00009fc4, 0x0001efb5},
251 {0x00009fcc, 0x40000014},
252 {0x00009fd0, 0x0a193b93},
253 {0x0000a20c, 0x00000000},
254 {0x0000a220, 0x00000000},
255 {0x0000a224, 0x00000000},
256 {0x0000a228, 0x10002310},
257 {0x0000a23c, 0x00000000},
258 {0x0000a244, 0x0c000000},
259 {0x0000a2a0, 0x00000001},
260 {0x0000a2c0, 0x00000001},
261 {0x0000a2c8, 0x00000000},
262 {0x0000a2cc, 0x18c43433},
263 {0x0000a2d4, 0x00000000},
264 {0x0000a2ec, 0x00000000},
265 {0x0000a2f0, 0x00000000},
266 {0x0000a2f4, 0x00000000},
267 {0x0000a2f8, 0x00000000},
268 {0x0000a344, 0x00000000},
269 {0x0000a34c, 0x00000000},
270 {0x0000a350, 0x0000a000},
271 {0x0000a364, 0x00000000},
272 {0x0000a370, 0x00000000},
273 {0x0000a390, 0x00000001},
274 {0x0000a394, 0x00000444},
275 {0x0000a398, 0x001f0e0f},
276 {0x0000a39c, 0x0075393f},
277 {0x0000a3a0, 0xb79f6427},
278 {0x0000a3c0, 0x20202020},
279 {0x0000a3c4, 0x22222220},
280 {0x0000a3c8, 0x20200020},
281 {0x0000a3cc, 0x20202020},
282 {0x0000a3d0, 0x20202020},
283 {0x0000a3d4, 0x20202020},
284 {0x0000a3d8, 0x20202020},
285 {0x0000a3dc, 0x20202020},
286 {0x0000a3e0, 0x20202020},
287 {0x0000a3e4, 0x20202020},
288 {0x0000a3e8, 0x20202020},
289 {0x0000a3ec, 0x20202020},
290 {0x0000a3f0, 0x00000000},
291 {0x0000a3f4, 0x00000006},
292 {0x0000a3f8, 0x0c9bd380},
293 {0x0000a3fc, 0x000f0f01},
294 {0x0000a400, 0x8fa91f01},
295 {0x0000a404, 0x00000000},
296 {0x0000a408, 0x0e79e5c6},
297 {0x0000a40c, 0x00820820},
298 {0x0000a414, 0x1ce739ce},
299 {0x0000a418, 0x2d001dce},
300 {0x0000a434, 0x00000000},
301 {0x0000a438, 0x00001801},
302 {0x0000a43c, 0x00100000},
303 {0x0000a444, 0x00000000},
304 {0x0000a448, 0x05000080},
305 {0x0000a44c, 0x00000001},
306 {0x0000a450, 0x00010000},
307 {0x0000a454, 0x07000000},
308 {0x0000a644, 0xbfad9d74},
309 {0x0000a648, 0x0048060a},
310 {0x0000a64c, 0x00002037},
311 {0x0000a670, 0x03020100},
312 {0x0000a674, 0x09080504},
313 {0x0000a678, 0x0d0c0b0a},
314 {0x0000a67c, 0x13121110},
315 {0x0000a680, 0x31301514},
316 {0x0000a684, 0x35343332},
317 {0x0000a688, 0x00000036},
318 {0x0000a690, 0x00000838},
319 {0x0000a6b0, 0x0000000a},
320 {0x0000a6b4, 0x00512c01},
321 {0x0000a7c0, 0x00000000},
322 {0x0000a7c4, 0xfffffffc},
323 {0x0000a7c8, 0x00000000},
324 {0x0000a7cc, 0x00000000},
325 {0x0000a7d0, 0x00000000},
326 {0x0000a7d4, 0x00000004},
327 {0x0000a7dc, 0x00000000},
328 {0x0000a7f0, 0x80000000},
329 {0x0000a8d0, 0x004b6a8e},
330 {0x0000a8d4, 0x00000820},
331 {0x0000a8dc, 0x00000000},
332 {0x0000a8f0, 0x00000000},
333 {0x0000a8f4, 0x00000000},
334 {0x0000abf0, 0x80000000},
335 {0x0000b2d0, 0x00000080},
336 {0x0000b2d4, 0x00000000},
337 {0x0000b2ec, 0x00000000},
338 {0x0000b2f0, 0x00000000},
339 {0x0000b2f4, 0x00000000},
340 {0x0000b2f8, 0x00000000},
341 {0x0000b408, 0x0e79e5c0},
342 {0x0000b40c, 0x00820820},
343 {0x0000b420, 0x00000000},
344 {0x0000b6b0, 0x0000000a},
345 {0x0000b6b4, 0x00000001},
346};
347
348static const u32 ar9462_2p1_baseband_postamble[][5] = {
349 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
350 {0x00009810, 0xd00a8005, 0xd00a8005, 0xd00a8011, 0xd00a800d},
351 {0x00009820, 0x206a022e, 0x206a022e, 0x206a012e, 0x206a01ae},
352 {0x00009824, 0x63c640de, 0x5ac640d0, 0x5ac640d0, 0x63c640da},
353 {0x00009828, 0x0796be89, 0x0696b081, 0x0696b881, 0x09143e81},
354 {0x0000982c, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4, 0x05eea6d4},
355 {0x00009830, 0x0000059c, 0x0000059c, 0x0000119c, 0x0000119c},
356 {0x00009c00, 0x000000c4, 0x000000c4, 0x000000c4, 0x000000c4},
357 {0x00009e00, 0x0372111a, 0x0372111a, 0x037216a0, 0x037216a2},
358 {0x00009e04, 0x001c2020, 0x001c2020, 0x001c2020, 0x001c2020},
359 {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000e2, 0x6c4000d8},
360 {0x00009e10, 0x92c88d2e, 0x7ec88d2e, 0x7ec84d2e, 0x7ec86d2e},
361 {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3236605e, 0x32365a5e},
362 {0x00009e18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
363 {0x00009e1c, 0x0001cf9c, 0x0001cf9c, 0x00021f9c, 0x00021f9c},
364 {0x00009e20, 0x000003b5, 0x000003b5, 0x000003ce, 0x000003ce},
365 {0x00009e2c, 0x0000001c, 0x0000001c, 0x00000021, 0x00000021},
366 {0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c282},
367 {0x00009e44, 0x62321e27, 0x62321e27, 0xfe291e27, 0xfe291e27},
368 {0x00009e48, 0x5030201a, 0x5030201a, 0x50302012, 0x50302012},
369 {0x00009fc8, 0x0003f000, 0x0003f000, 0x0001a000, 0x0001a000},
370 {0x0000a204, 0x01318fc0, 0x01318fc4, 0x01318fc4, 0x01318fc0},
371 {0x0000a208, 0x00000104, 0x00000104, 0x00000004, 0x00000004},
372 {0x0000a22c, 0x01026a2f, 0x01026a27, 0x01026a2f, 0x01026a2f},
373 {0x0000a230, 0x0000400a, 0x00004014, 0x00004016, 0x0000400b},
374 {0x0000a234, 0x00000fff, 0x10000fff, 0x10000fff, 0x00000fff},
375 {0x0000a238, 0xffb81018, 0xffb81018, 0xffb81018, 0xffb81018},
376 {0x0000a250, 0x00000000, 0x00000000, 0x00000210, 0x00000108},
377 {0x0000a254, 0x000007d0, 0x00000fa0, 0x00001130, 0x00000898},
378 {0x0000a258, 0x02020002, 0x02020002, 0x02020002, 0x02020002},
379 {0x0000a25c, 0x01000e0e, 0x01000e0e, 0x01000e0e, 0x01000e0e},
380 {0x0000a260, 0x0a021501, 0x0a021501, 0x3a021501, 0x3a021501},
381 {0x0000a264, 0x00000e0e, 0x00000e0e, 0x00000e0e, 0x00000e0e},
382 {0x0000a280, 0x00000007, 0x00000007, 0x0000000b, 0x0000000b},
383 {0x0000a284, 0x00000000, 0x00000000, 0x00000150, 0x00000150},
384 {0x0000a288, 0x00000110, 0x00000110, 0x00000110, 0x00000110},
385 {0x0000a28c, 0x00022222, 0x00022222, 0x00022222, 0x00022222},
386 {0x0000a2c4, 0x00158d18, 0x00158d18, 0x00158d18, 0x00158d18},
387 {0x0000a2d0, 0x00041981, 0x00041981, 0x00041981, 0x00041982},
388 {0x0000a2d8, 0x7999a83b, 0x7999a83b, 0x7999a83b, 0x7999a83b},
389 {0x0000a358, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
390 {0x0000a3a4, 0x00000050, 0x00000050, 0x00000000, 0x00000000},
391 {0x0000a3a8, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa, 0xaaaaaaaa},
392 {0x0000a3ac, 0xaaaaaa00, 0xaa30aa30, 0xaaaaaa00, 0xaaaaaa00},
393 {0x0000a41c, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce},
394 {0x0000a420, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce},
395 {0x0000a424, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce},
396 {0x0000a428, 0x000001ce, 0x000001ce, 0x000001ce, 0x000001ce},
397 {0x0000a42c, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce},
398 {0x0000a430, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce, 0x1ce739ce},
399 {0x0000a830, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
400 {0x0000ae04, 0x001c0000, 0x001c0000, 0x001c0000, 0x00100000},
401 {0x0000ae18, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
402 {0x0000ae1c, 0x0000019c, 0x0000019c, 0x0000019c, 0x0000019c},
403 {0x0000ae20, 0x000001b5, 0x000001b5, 0x000001ce, 0x000001ce},
404 {0x0000b284, 0x00000000, 0x00000000, 0x00000550, 0x00000550},
405};
406
407static const u32 ar9462_2p1_radio_core[][2] = {
408 /* Addr allmodes */
409 {0x00016000, 0x36db6db6},
410 {0x00016004, 0x6db6db40},
411 {0x00016008, 0x73f00000},
412 {0x0001600c, 0x00000000},
413 {0x00016010, 0x6d820001},
414 {0x00016040, 0x7f80fff8},
415 {0x0001604c, 0x2699e04f},
416 {0x00016050, 0x6db6db6c},
417 {0x00016058, 0x6c200000},
418 {0x00016080, 0x000c0000},
419 {0x00016084, 0x9a68048c},
420 {0x00016088, 0x54214514},
421 {0x0001608c, 0x1203040b},
422 {0x00016090, 0x24926490},
423 {0x00016098, 0xd2888888},
424 {0x000160a0, 0x0a108ffe},
425 {0x000160a4, 0x812fc491},
426 {0x000160a8, 0x423c8000},
427 {0x000160b4, 0x92000000},
428 {0x000160b8, 0x0285dddc},
429 {0x000160bc, 0x02908888},
430 {0x000160c0, 0x00adb6d0},
431 {0x000160c4, 0x6db6db60},
432 {0x000160c8, 0x6db6db6c},
433 {0x000160cc, 0x0de6c1b0},
434 {0x00016100, 0x3fffbe04},
435 {0x00016104, 0xfff80000},
436 {0x00016108, 0x00200400},
437 {0x00016110, 0x00000000},
438 {0x00016144, 0x02084080},
439 {0x00016148, 0x000080c0},
440 {0x00016280, 0x050a0001},
441 {0x00016284, 0x3d841418},
442 {0x00016288, 0x00000000},
443 {0x0001628c, 0xe3000000},
444 {0x00016290, 0xa1005080},
445 {0x00016294, 0x00000020},
446 {0x00016298, 0x54a82900},
447 {0x00016340, 0x121e4276},
448 {0x00016344, 0x00300000},
449 {0x00016400, 0x36db6db6},
450 {0x00016404, 0x6db6db40},
451 {0x00016408, 0x73f00000},
452 {0x0001640c, 0x00000000},
453 {0x00016410, 0x6c800001},
454 {0x00016440, 0x7f80fff8},
455 {0x0001644c, 0x4699e04f},
456 {0x00016450, 0x6db6db6c},
457 {0x00016500, 0x3fffbe04},
458 {0x00016504, 0xfff80000},
459 {0x00016508, 0x00200400},
460 {0x00016510, 0x00000000},
461 {0x00016544, 0x02084080},
462 {0x00016548, 0x000080c0},
463};
464
465static const u32 ar9462_2p1_radio_postamble[][5] = {
466 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
467 {0x0001609c, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524, 0x0b8ee524},
468 {0x000160b0, 0x01d67f70, 0x01d67f70, 0x01d67f70, 0x01d67f70},
469 {0x0001610c, 0x48000000, 0x40000000, 0x40000000, 0x40000000},
470 {0x0001650c, 0x48000000, 0x40000000, 0x40000000, 0x40000000},
471};
472
473static const u32 ar9462_2p1_soc_preamble[][2] = {
474 /* Addr allmodes */
475 {0x000040a4, 0x00a0c1c9},
476 {0x00007020, 0x00000000},
477 {0x00007034, 0x00000002},
478 {0x00007038, 0x000004c2},
479};
480
481static const u32 ar9462_2p1_soc_postamble[][5] = {
482 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
483 {0x00007010, 0x00000033, 0x00000033, 0x00000033, 0x00000033},
484};
485
486static const u32 ar9462_2p1_radio_postamble_sys2ant[][5] = {
487 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
488 {0x000160ac, 0xa4646c08, 0xa4646c08, 0x24645808, 0x24645808},
489 {0x00016140, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
490 {0x00016540, 0x10804008, 0x10804008, 0x50804008, 0x50804008},
491};
492
493static const u32 ar9462_2p1_common_rx_gain[][2] = {
494 /* Addr allmodes */
495 {0x0000a000, 0x00010000},
496 {0x0000a004, 0x00030002},
497 {0x0000a008, 0x00050004},
498 {0x0000a00c, 0x00810080},
499 {0x0000a010, 0x00830082},
500 {0x0000a014, 0x01810180},
501 {0x0000a018, 0x01830182},
502 {0x0000a01c, 0x01850184},
503 {0x0000a020, 0x01890188},
504 {0x0000a024, 0x018b018a},
505 {0x0000a028, 0x018d018c},
506 {0x0000a02c, 0x01910190},
507 {0x0000a030, 0x01930192},
508 {0x0000a034, 0x01950194},
509 {0x0000a038, 0x038a0196},
510 {0x0000a03c, 0x038c038b},
511 {0x0000a040, 0x0390038d},
512 {0x0000a044, 0x03920391},
513 {0x0000a048, 0x03940393},
514 {0x0000a04c, 0x03960395},
515 {0x0000a050, 0x00000000},
516 {0x0000a054, 0x00000000},
517 {0x0000a058, 0x00000000},
518 {0x0000a05c, 0x00000000},
519 {0x0000a060, 0x00000000},
520 {0x0000a064, 0x00000000},
521 {0x0000a068, 0x00000000},
522 {0x0000a06c, 0x00000000},
523 {0x0000a070, 0x00000000},
524 {0x0000a074, 0x00000000},
525 {0x0000a078, 0x00000000},
526 {0x0000a07c, 0x00000000},
527 {0x0000a080, 0x22222229},
528 {0x0000a084, 0x1d1d1d1d},
529 {0x0000a088, 0x1d1d1d1d},
530 {0x0000a08c, 0x1d1d1d1d},
531 {0x0000a090, 0x171d1d1d},
532 {0x0000a094, 0x11111717},
533 {0x0000a098, 0x00030311},
534 {0x0000a09c, 0x00000000},
535 {0x0000a0a0, 0x00000000},
536 {0x0000a0a4, 0x00000000},
537 {0x0000a0a8, 0x00000000},
538 {0x0000a0ac, 0x00000000},
539 {0x0000a0b0, 0x00000000},
540 {0x0000a0b4, 0x00000000},
541 {0x0000a0b8, 0x00000000},
542 {0x0000a0bc, 0x00000000},
543 {0x0000a0c0, 0x001f0000},
544 {0x0000a0c4, 0x01000101},
545 {0x0000a0c8, 0x011e011f},
546 {0x0000a0cc, 0x011c011d},
547 {0x0000a0d0, 0x02030204},
548 {0x0000a0d4, 0x02010202},
549 {0x0000a0d8, 0x021f0200},
550 {0x0000a0dc, 0x0302021e},
551 {0x0000a0e0, 0x03000301},
552 {0x0000a0e4, 0x031e031f},
553 {0x0000a0e8, 0x0402031d},
554 {0x0000a0ec, 0x04000401},
555 {0x0000a0f0, 0x041e041f},
556 {0x0000a0f4, 0x0502041d},
557 {0x0000a0f8, 0x05000501},
558 {0x0000a0fc, 0x051e051f},
559 {0x0000a100, 0x06010602},
560 {0x0000a104, 0x061f0600},
561 {0x0000a108, 0x061d061e},
562 {0x0000a10c, 0x07020703},
563 {0x0000a110, 0x07000701},
564 {0x0000a114, 0x00000000},
565 {0x0000a118, 0x00000000},
566 {0x0000a11c, 0x00000000},
567 {0x0000a120, 0x00000000},
568 {0x0000a124, 0x00000000},
569 {0x0000a128, 0x00000000},
570 {0x0000a12c, 0x00000000},
571 {0x0000a130, 0x00000000},
572 {0x0000a134, 0x00000000},
573 {0x0000a138, 0x00000000},
574 {0x0000a13c, 0x00000000},
575 {0x0000a140, 0x001f0000},
576 {0x0000a144, 0x01000101},
577 {0x0000a148, 0x011e011f},
578 {0x0000a14c, 0x011c011d},
579 {0x0000a150, 0x02030204},
580 {0x0000a154, 0x02010202},
581 {0x0000a158, 0x021f0200},
582 {0x0000a15c, 0x0302021e},
583 {0x0000a160, 0x03000301},
584 {0x0000a164, 0x031e031f},
585 {0x0000a168, 0x0402031d},
586 {0x0000a16c, 0x04000401},
587 {0x0000a170, 0x041e041f},
588 {0x0000a174, 0x0502041d},
589 {0x0000a178, 0x05000501},
590 {0x0000a17c, 0x051e051f},
591 {0x0000a180, 0x06010602},
592 {0x0000a184, 0x061f0600},
593 {0x0000a188, 0x061d061e},
594 {0x0000a18c, 0x07020703},
595 {0x0000a190, 0x07000701},
596 {0x0000a194, 0x00000000},
597 {0x0000a198, 0x00000000},
598 {0x0000a19c, 0x00000000},
599 {0x0000a1a0, 0x00000000},
600 {0x0000a1a4, 0x00000000},
601 {0x0000a1a8, 0x00000000},
602 {0x0000a1ac, 0x00000000},
603 {0x0000a1b0, 0x00000000},
604 {0x0000a1b4, 0x00000000},
605 {0x0000a1b8, 0x00000000},
606 {0x0000a1bc, 0x00000000},
607 {0x0000a1c0, 0x00000000},
608 {0x0000a1c4, 0x00000000},
609 {0x0000a1c8, 0x00000000},
610 {0x0000a1cc, 0x00000000},
611 {0x0000a1d0, 0x00000000},
612 {0x0000a1d4, 0x00000000},
613 {0x0000a1d8, 0x00000000},
614 {0x0000a1dc, 0x00000000},
615 {0x0000a1e0, 0x00000000},
616 {0x0000a1e4, 0x00000000},
617 {0x0000a1e8, 0x00000000},
618 {0x0000a1ec, 0x00000000},
619 {0x0000a1f0, 0x00000396},
620 {0x0000a1f4, 0x00000396},
621 {0x0000a1f8, 0x00000396},
622 {0x0000a1fc, 0x00000196},
623 {0x0000b000, 0x00010000},
624 {0x0000b004, 0x00030002},
625 {0x0000b008, 0x00050004},
626 {0x0000b00c, 0x00810080},
627 {0x0000b010, 0x00830082},
628 {0x0000b014, 0x01810180},
629 {0x0000b018, 0x01830182},
630 {0x0000b01c, 0x01850184},
631 {0x0000b020, 0x02810280},
632 {0x0000b024, 0x02830282},
633 {0x0000b028, 0x02850284},
634 {0x0000b02c, 0x02890288},
635 {0x0000b030, 0x028b028a},
636 {0x0000b034, 0x0388028c},
637 {0x0000b038, 0x038a0389},
638 {0x0000b03c, 0x038c038b},
639 {0x0000b040, 0x0390038d},
640 {0x0000b044, 0x03920391},
641 {0x0000b048, 0x03940393},
642 {0x0000b04c, 0x03960395},
643 {0x0000b050, 0x00000000},
644 {0x0000b054, 0x00000000},
645 {0x0000b058, 0x00000000},
646 {0x0000b05c, 0x00000000},
647 {0x0000b060, 0x00000000},
648 {0x0000b064, 0x00000000},
649 {0x0000b068, 0x00000000},
650 {0x0000b06c, 0x00000000},
651 {0x0000b070, 0x00000000},
652 {0x0000b074, 0x00000000},
653 {0x0000b078, 0x00000000},
654 {0x0000b07c, 0x00000000},
655 {0x0000b080, 0x2a2d2f32},
656 {0x0000b084, 0x21232328},
657 {0x0000b088, 0x19191c1e},
658 {0x0000b08c, 0x12141417},
659 {0x0000b090, 0x07070e0e},
660 {0x0000b094, 0x03030305},
661 {0x0000b098, 0x00000003},
662 {0x0000b09c, 0x00000000},
663 {0x0000b0a0, 0x00000000},
664 {0x0000b0a4, 0x00000000},
665 {0x0000b0a8, 0x00000000},
666 {0x0000b0ac, 0x00000000},
667 {0x0000b0b0, 0x00000000},
668 {0x0000b0b4, 0x00000000},
669 {0x0000b0b8, 0x00000000},
670 {0x0000b0bc, 0x00000000},
671 {0x0000b0c0, 0x003f0020},
672 {0x0000b0c4, 0x00400041},
673 {0x0000b0c8, 0x0140005f},
674 {0x0000b0cc, 0x0160015f},
675 {0x0000b0d0, 0x017e017f},
676 {0x0000b0d4, 0x02410242},
677 {0x0000b0d8, 0x025f0240},
678 {0x0000b0dc, 0x027f0260},
679 {0x0000b0e0, 0x0341027e},
680 {0x0000b0e4, 0x035f0340},
681 {0x0000b0e8, 0x037f0360},
682 {0x0000b0ec, 0x04400441},
683 {0x0000b0f0, 0x0460045f},
684 {0x0000b0f4, 0x0541047f},
685 {0x0000b0f8, 0x055f0540},
686 {0x0000b0fc, 0x057f0560},
687 {0x0000b100, 0x06400641},
688 {0x0000b104, 0x0660065f},
689 {0x0000b108, 0x067e067f},
690 {0x0000b10c, 0x07410742},
691 {0x0000b110, 0x075f0740},
692 {0x0000b114, 0x077f0760},
693 {0x0000b118, 0x07800781},
694 {0x0000b11c, 0x07a0079f},
695 {0x0000b120, 0x07c107bf},
696 {0x0000b124, 0x000007c0},
697 {0x0000b128, 0x00000000},
698 {0x0000b12c, 0x00000000},
699 {0x0000b130, 0x00000000},
700 {0x0000b134, 0x00000000},
701 {0x0000b138, 0x00000000},
702 {0x0000b13c, 0x00000000},
703 {0x0000b140, 0x003f0020},
704 {0x0000b144, 0x00400041},
705 {0x0000b148, 0x0140005f},
706 {0x0000b14c, 0x0160015f},
707 {0x0000b150, 0x017e017f},
708 {0x0000b154, 0x02410242},
709 {0x0000b158, 0x025f0240},
710 {0x0000b15c, 0x027f0260},
711 {0x0000b160, 0x0341027e},
712 {0x0000b164, 0x035f0340},
713 {0x0000b168, 0x037f0360},
714 {0x0000b16c, 0x04400441},
715 {0x0000b170, 0x0460045f},
716 {0x0000b174, 0x0541047f},
717 {0x0000b178, 0x055f0540},
718 {0x0000b17c, 0x057f0560},
719 {0x0000b180, 0x06400641},
720 {0x0000b184, 0x0660065f},
721 {0x0000b188, 0x067e067f},
722 {0x0000b18c, 0x07410742},
723 {0x0000b190, 0x075f0740},
724 {0x0000b194, 0x077f0760},
725 {0x0000b198, 0x07800781},
726 {0x0000b19c, 0x07a0079f},
727 {0x0000b1a0, 0x07c107bf},
728 {0x0000b1a4, 0x000007c0},
729 {0x0000b1a8, 0x00000000},
730 {0x0000b1ac, 0x00000000},
731 {0x0000b1b0, 0x00000000},
732 {0x0000b1b4, 0x00000000},
733 {0x0000b1b8, 0x00000000},
734 {0x0000b1bc, 0x00000000},
735 {0x0000b1c0, 0x00000000},
736 {0x0000b1c4, 0x00000000},
737 {0x0000b1c8, 0x00000000},
738 {0x0000b1cc, 0x00000000},
739 {0x0000b1d0, 0x00000000},
740 {0x0000b1d4, 0x00000000},
741 {0x0000b1d8, 0x00000000},
742 {0x0000b1dc, 0x00000000},
743 {0x0000b1e0, 0x00000000},
744 {0x0000b1e4, 0x00000000},
745 {0x0000b1e8, 0x00000000},
746 {0x0000b1ec, 0x00000000},
747 {0x0000b1f0, 0x00000396},
748 {0x0000b1f4, 0x00000396},
749 {0x0000b1f8, 0x00000396},
750 {0x0000b1fc, 0x00000196},
751};
752
753static const u32 ar9462_2p1_common_mixed_rx_gain[][2] = {
754 /* Addr allmodes */
755 {0x0000a000, 0x00010000},
756 {0x0000a004, 0x00030002},
757 {0x0000a008, 0x00050004},
758 {0x0000a00c, 0x00810080},
759 {0x0000a010, 0x00830082},
760 {0x0000a014, 0x01810180},
761 {0x0000a018, 0x01830182},
762 {0x0000a01c, 0x01850184},
763 {0x0000a020, 0x01890188},
764 {0x0000a024, 0x018b018a},
765 {0x0000a028, 0x018d018c},
766 {0x0000a02c, 0x03820190},
767 {0x0000a030, 0x03840383},
768 {0x0000a034, 0x03880385},
769 {0x0000a038, 0x038a0389},
770 {0x0000a03c, 0x038c038b},
771 {0x0000a040, 0x0390038d},
772 {0x0000a044, 0x03920391},
773 {0x0000a048, 0x03940393},
774 {0x0000a04c, 0x03960395},
775 {0x0000a050, 0x00000000},
776 {0x0000a054, 0x00000000},
777 {0x0000a058, 0x00000000},
778 {0x0000a05c, 0x00000000},
779 {0x0000a060, 0x00000000},
780 {0x0000a064, 0x00000000},
781 {0x0000a068, 0x00000000},
782 {0x0000a06c, 0x00000000},
783 {0x0000a070, 0x00000000},
784 {0x0000a074, 0x00000000},
785 {0x0000a078, 0x00000000},
786 {0x0000a07c, 0x00000000},
787 {0x0000a080, 0x29292929},
788 {0x0000a084, 0x29292929},
789 {0x0000a088, 0x29292929},
790 {0x0000a08c, 0x29292929},
791 {0x0000a090, 0x22292929},
792 {0x0000a094, 0x1d1d2222},
793 {0x0000a098, 0x0c111117},
794 {0x0000a09c, 0x00030303},
795 {0x0000a0a0, 0x00000000},
796 {0x0000a0a4, 0x00000000},
797 {0x0000a0a8, 0x00000000},
798 {0x0000a0ac, 0x00000000},
799 {0x0000a0b0, 0x00000000},
800 {0x0000a0b4, 0x00000000},
801 {0x0000a0b8, 0x00000000},
802 {0x0000a0bc, 0x00000000},
803 {0x0000a0c0, 0x001f0000},
804 {0x0000a0c4, 0x01000101},
805 {0x0000a0c8, 0x011e011f},
806 {0x0000a0cc, 0x011c011d},
807 {0x0000a0d0, 0x02030204},
808 {0x0000a0d4, 0x02010202},
809 {0x0000a0d8, 0x021f0200},
810 {0x0000a0dc, 0x0302021e},
811 {0x0000a0e0, 0x03000301},
812 {0x0000a0e4, 0x031e031f},
813 {0x0000a0e8, 0x0402031d},
814 {0x0000a0ec, 0x04000401},
815 {0x0000a0f0, 0x041e041f},
816 {0x0000a0f4, 0x0502041d},
817 {0x0000a0f8, 0x05000501},
818 {0x0000a0fc, 0x051e051f},
819 {0x0000a100, 0x06010602},
820 {0x0000a104, 0x061f0600},
821 {0x0000a108, 0x061d061e},
822 {0x0000a10c, 0x07020703},
823 {0x0000a110, 0x07000701},
824 {0x0000a114, 0x00000000},
825 {0x0000a118, 0x00000000},
826 {0x0000a11c, 0x00000000},
827 {0x0000a120, 0x00000000},
828 {0x0000a124, 0x00000000},
829 {0x0000a128, 0x00000000},
830 {0x0000a12c, 0x00000000},
831 {0x0000a130, 0x00000000},
832 {0x0000a134, 0x00000000},
833 {0x0000a138, 0x00000000},
834 {0x0000a13c, 0x00000000},
835 {0x0000a140, 0x001f0000},
836 {0x0000a144, 0x01000101},
837 {0x0000a148, 0x011e011f},
838 {0x0000a14c, 0x011c011d},
839 {0x0000a150, 0x02030204},
840 {0x0000a154, 0x02010202},
841 {0x0000a158, 0x021f0200},
842 {0x0000a15c, 0x0302021e},
843 {0x0000a160, 0x03000301},
844 {0x0000a164, 0x031e031f},
845 {0x0000a168, 0x0402031d},
846 {0x0000a16c, 0x04000401},
847 {0x0000a170, 0x041e041f},
848 {0x0000a174, 0x0502041d},
849 {0x0000a178, 0x05000501},
850 {0x0000a17c, 0x051e051f},
851 {0x0000a180, 0x06010602},
852 {0x0000a184, 0x061f0600},
853 {0x0000a188, 0x061d061e},
854 {0x0000a18c, 0x07020703},
855 {0x0000a190, 0x07000701},
856 {0x0000a194, 0x00000000},
857 {0x0000a198, 0x00000000},
858 {0x0000a19c, 0x00000000},
859 {0x0000a1a0, 0x00000000},
860 {0x0000a1a4, 0x00000000},
861 {0x0000a1a8, 0x00000000},
862 {0x0000a1ac, 0x00000000},
863 {0x0000a1b0, 0x00000000},
864 {0x0000a1b4, 0x00000000},
865 {0x0000a1b8, 0x00000000},
866 {0x0000a1bc, 0x00000000},
867 {0x0000a1c0, 0x00000000},
868 {0x0000a1c4, 0x00000000},
869 {0x0000a1c8, 0x00000000},
870 {0x0000a1cc, 0x00000000},
871 {0x0000a1d0, 0x00000000},
872 {0x0000a1d4, 0x00000000},
873 {0x0000a1d8, 0x00000000},
874 {0x0000a1dc, 0x00000000},
875 {0x0000a1e0, 0x00000000},
876 {0x0000a1e4, 0x00000000},
877 {0x0000a1e8, 0x00000000},
878 {0x0000a1ec, 0x00000000},
879 {0x0000a1f0, 0x00000396},
880 {0x0000a1f4, 0x00000396},
881 {0x0000a1f8, 0x00000396},
882 {0x0000a1fc, 0x00000196},
883 {0x0000b000, 0x00010000},
884 {0x0000b004, 0x00030002},
885 {0x0000b008, 0x00050004},
886 {0x0000b00c, 0x00810080},
887 {0x0000b010, 0x00830082},
888 {0x0000b014, 0x01810180},
889 {0x0000b018, 0x01830182},
890 {0x0000b01c, 0x01850184},
891 {0x0000b020, 0x02810280},
892 {0x0000b024, 0x02830282},
893 {0x0000b028, 0x02850284},
894 {0x0000b02c, 0x02890288},
895 {0x0000b030, 0x028b028a},
896 {0x0000b034, 0x0388028c},
897 {0x0000b038, 0x038a0389},
898 {0x0000b03c, 0x038c038b},
899 {0x0000b040, 0x0390038d},
900 {0x0000b044, 0x03920391},
901 {0x0000b048, 0x03940393},
902 {0x0000b04c, 0x03960395},
903 {0x0000b050, 0x00000000},
904 {0x0000b054, 0x00000000},
905 {0x0000b058, 0x00000000},
906 {0x0000b05c, 0x00000000},
907 {0x0000b060, 0x00000000},
908 {0x0000b064, 0x00000000},
909 {0x0000b068, 0x00000000},
910 {0x0000b06c, 0x00000000},
911 {0x0000b070, 0x00000000},
912 {0x0000b074, 0x00000000},
913 {0x0000b078, 0x00000000},
914 {0x0000b07c, 0x00000000},
915 {0x0000b080, 0x2a2d2f32},
916 {0x0000b084, 0x21232328},
917 {0x0000b088, 0x19191c1e},
918 {0x0000b08c, 0x12141417},
919 {0x0000b090, 0x07070e0e},
920 {0x0000b094, 0x03030305},
921 {0x0000b098, 0x00000003},
922 {0x0000b09c, 0x00000000},
923 {0x0000b0a0, 0x00000000},
924 {0x0000b0a4, 0x00000000},
925 {0x0000b0a8, 0x00000000},
926 {0x0000b0ac, 0x00000000},
927 {0x0000b0b0, 0x00000000},
928 {0x0000b0b4, 0x00000000},
929 {0x0000b0b8, 0x00000000},
930 {0x0000b0bc, 0x00000000},
931 {0x0000b0c0, 0x003f0020},
932 {0x0000b0c4, 0x00400041},
933 {0x0000b0c8, 0x0140005f},
934 {0x0000b0cc, 0x0160015f},
935 {0x0000b0d0, 0x017e017f},
936 {0x0000b0d4, 0x02410242},
937 {0x0000b0d8, 0x025f0240},
938 {0x0000b0dc, 0x027f0260},
939 {0x0000b0e0, 0x0341027e},
940 {0x0000b0e4, 0x035f0340},
941 {0x0000b0e8, 0x037f0360},
942 {0x0000b0ec, 0x04400441},
943 {0x0000b0f0, 0x0460045f},
944 {0x0000b0f4, 0x0541047f},
945 {0x0000b0f8, 0x055f0540},
946 {0x0000b0fc, 0x057f0560},
947 {0x0000b100, 0x06400641},
948 {0x0000b104, 0x0660065f},
949 {0x0000b108, 0x067e067f},
950 {0x0000b10c, 0x07410742},
951 {0x0000b110, 0x075f0740},
952 {0x0000b114, 0x077f0760},
953 {0x0000b118, 0x07800781},
954 {0x0000b11c, 0x07a0079f},
955 {0x0000b120, 0x07c107bf},
956 {0x0000b124, 0x000007c0},
957 {0x0000b128, 0x00000000},
958 {0x0000b12c, 0x00000000},
959 {0x0000b130, 0x00000000},
960 {0x0000b134, 0x00000000},
961 {0x0000b138, 0x00000000},
962 {0x0000b13c, 0x00000000},
963 {0x0000b140, 0x003f0020},
964 {0x0000b144, 0x00400041},
965 {0x0000b148, 0x0140005f},
966 {0x0000b14c, 0x0160015f},
967 {0x0000b150, 0x017e017f},
968 {0x0000b154, 0x02410242},
969 {0x0000b158, 0x025f0240},
970 {0x0000b15c, 0x027f0260},
971 {0x0000b160, 0x0341027e},
972 {0x0000b164, 0x035f0340},
973 {0x0000b168, 0x037f0360},
974 {0x0000b16c, 0x04400441},
975 {0x0000b170, 0x0460045f},
976 {0x0000b174, 0x0541047f},
977 {0x0000b178, 0x055f0540},
978 {0x0000b17c, 0x057f0560},
979 {0x0000b180, 0x06400641},
980 {0x0000b184, 0x0660065f},
981 {0x0000b188, 0x067e067f},
982 {0x0000b18c, 0x07410742},
983 {0x0000b190, 0x075f0740},
984 {0x0000b194, 0x077f0760},
985 {0x0000b198, 0x07800781},
986 {0x0000b19c, 0x07a0079f},
987 {0x0000b1a0, 0x07c107bf},
988 {0x0000b1a4, 0x000007c0},
989 {0x0000b1a8, 0x00000000},
990 {0x0000b1ac, 0x00000000},
991 {0x0000b1b0, 0x00000000},
992 {0x0000b1b4, 0x00000000},
993 {0x0000b1b8, 0x00000000},
994 {0x0000b1bc, 0x00000000},
995 {0x0000b1c0, 0x00000000},
996 {0x0000b1c4, 0x00000000},
997 {0x0000b1c8, 0x00000000},
998 {0x0000b1cc, 0x00000000},
999 {0x0000b1d0, 0x00000000},
1000 {0x0000b1d4, 0x00000000},
1001 {0x0000b1d8, 0x00000000},
1002 {0x0000b1dc, 0x00000000},
1003 {0x0000b1e0, 0x00000000},
1004 {0x0000b1e4, 0x00000000},
1005 {0x0000b1e8, 0x00000000},
1006 {0x0000b1ec, 0x00000000},
1007 {0x0000b1f0, 0x00000396},
1008 {0x0000b1f4, 0x00000396},
1009 {0x0000b1f8, 0x00000396},
1010 {0x0000b1fc, 0x00000196},
1011};
1012
1013static const u32 ar9462_2p1_baseband_core_mix_rxgain[][2] = {
1014 /* Addr allmodes */
1015 {0x00009fd0, 0x0a2d6b93},
1016};
1017
1018static const u32 ar9462_2p1_baseband_postamble_mix_rxgain[][5] = {
1019 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1020 {0x00009820, 0x206a022e, 0x206a022e, 0x206a01ae, 0x206a01ae},
1021 {0x00009824, 0x63c640de, 0x5ac640d0, 0x63c640da, 0x63c640da},
1022 {0x00009828, 0x0796be89, 0x0696b081, 0x0916be81, 0x0916be81},
1023 {0x00009e0c, 0x6c4000e2, 0x6d4000e2, 0x6d4000d8, 0x6c4000d8},
1024 {0x00009e10, 0x92c88d2e, 0x7ec88d2e, 0x7ec86d2e, 0x7ec86d2e},
1025 {0x00009e14, 0x37b95d5e, 0x37b9605e, 0x3236605e, 0x32395c5e},
1026};
1027
1028static const u32 ar9462_2p1_baseband_postamble_5g_xlna[][5] = {
1029 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1030 {0x00009e3c, 0xcf946220, 0xcf946220, 0xcfd5c782, 0xcfd5c282},
1031};
1032
1033static const u32 ar9462_2p1_common_wo_xlna_rx_gain[][2] = {
1034 /* Addr allmodes */
1035 {0x0000a000, 0x00010000},
1036 {0x0000a004, 0x00030002},
1037 {0x0000a008, 0x00050004},
1038 {0x0000a00c, 0x00810080},
1039 {0x0000a010, 0x00830082},
1040 {0x0000a014, 0x01810180},
1041 {0x0000a018, 0x01830182},
1042 {0x0000a01c, 0x01850184},
1043 {0x0000a020, 0x01890188},
1044 {0x0000a024, 0x018b018a},
1045 {0x0000a028, 0x018d018c},
1046 {0x0000a02c, 0x03820190},
1047 {0x0000a030, 0x03840383},
1048 {0x0000a034, 0x03880385},
1049 {0x0000a038, 0x038a0389},
1050 {0x0000a03c, 0x038c038b},
1051 {0x0000a040, 0x0390038d},
1052 {0x0000a044, 0x03920391},
1053 {0x0000a048, 0x03940393},
1054 {0x0000a04c, 0x03960395},
1055 {0x0000a050, 0x00000000},
1056 {0x0000a054, 0x00000000},
1057 {0x0000a058, 0x00000000},
1058 {0x0000a05c, 0x00000000},
1059 {0x0000a060, 0x00000000},
1060 {0x0000a064, 0x00000000},
1061 {0x0000a068, 0x00000000},
1062 {0x0000a06c, 0x00000000},
1063 {0x0000a070, 0x00000000},
1064 {0x0000a074, 0x00000000},
1065 {0x0000a078, 0x00000000},
1066 {0x0000a07c, 0x00000000},
1067 {0x0000a080, 0x29292929},
1068 {0x0000a084, 0x29292929},
1069 {0x0000a088, 0x29292929},
1070 {0x0000a08c, 0x29292929},
1071 {0x0000a090, 0x22292929},
1072 {0x0000a094, 0x1d1d2222},
1073 {0x0000a098, 0x0c111117},
1074 {0x0000a09c, 0x00030303},
1075 {0x0000a0a0, 0x00000000},
1076 {0x0000a0a4, 0x00000000},
1077 {0x0000a0a8, 0x00000000},
1078 {0x0000a0ac, 0x00000000},
1079 {0x0000a0b0, 0x00000000},
1080 {0x0000a0b4, 0x00000000},
1081 {0x0000a0b8, 0x00000000},
1082 {0x0000a0bc, 0x00000000},
1083 {0x0000a0c0, 0x001f0000},
1084 {0x0000a0c4, 0x01000101},
1085 {0x0000a0c8, 0x011e011f},
1086 {0x0000a0cc, 0x011c011d},
1087 {0x0000a0d0, 0x02030204},
1088 {0x0000a0d4, 0x02010202},
1089 {0x0000a0d8, 0x021f0200},
1090 {0x0000a0dc, 0x0302021e},
1091 {0x0000a0e0, 0x03000301},
1092 {0x0000a0e4, 0x031e031f},
1093 {0x0000a0e8, 0x0402031d},
1094 {0x0000a0ec, 0x04000401},
1095 {0x0000a0f0, 0x041e041f},
1096 {0x0000a0f4, 0x0502041d},
1097 {0x0000a0f8, 0x05000501},
1098 {0x0000a0fc, 0x051e051f},
1099 {0x0000a100, 0x06010602},
1100 {0x0000a104, 0x061f0600},
1101 {0x0000a108, 0x061d061e},
1102 {0x0000a10c, 0x07020703},
1103 {0x0000a110, 0x07000701},
1104 {0x0000a114, 0x00000000},
1105 {0x0000a118, 0x00000000},
1106 {0x0000a11c, 0x00000000},
1107 {0x0000a120, 0x00000000},
1108 {0x0000a124, 0x00000000},
1109 {0x0000a128, 0x00000000},
1110 {0x0000a12c, 0x00000000},
1111 {0x0000a130, 0x00000000},
1112 {0x0000a134, 0x00000000},
1113 {0x0000a138, 0x00000000},
1114 {0x0000a13c, 0x00000000},
1115 {0x0000a140, 0x001f0000},
1116 {0x0000a144, 0x01000101},
1117 {0x0000a148, 0x011e011f},
1118 {0x0000a14c, 0x011c011d},
1119 {0x0000a150, 0x02030204},
1120 {0x0000a154, 0x02010202},
1121 {0x0000a158, 0x021f0200},
1122 {0x0000a15c, 0x0302021e},
1123 {0x0000a160, 0x03000301},
1124 {0x0000a164, 0x031e031f},
1125 {0x0000a168, 0x0402031d},
1126 {0x0000a16c, 0x04000401},
1127 {0x0000a170, 0x041e041f},
1128 {0x0000a174, 0x0502041d},
1129 {0x0000a178, 0x05000501},
1130 {0x0000a17c, 0x051e051f},
1131 {0x0000a180, 0x06010602},
1132 {0x0000a184, 0x061f0600},
1133 {0x0000a188, 0x061d061e},
1134 {0x0000a18c, 0x07020703},
1135 {0x0000a190, 0x07000701},
1136 {0x0000a194, 0x00000000},
1137 {0x0000a198, 0x00000000},
1138 {0x0000a19c, 0x00000000},
1139 {0x0000a1a0, 0x00000000},
1140 {0x0000a1a4, 0x00000000},
1141 {0x0000a1a8, 0x00000000},
1142 {0x0000a1ac, 0x00000000},
1143 {0x0000a1b0, 0x00000000},
1144 {0x0000a1b4, 0x00000000},
1145 {0x0000a1b8, 0x00000000},
1146 {0x0000a1bc, 0x00000000},
1147 {0x0000a1c0, 0x00000000},
1148 {0x0000a1c4, 0x00000000},
1149 {0x0000a1c8, 0x00000000},
1150 {0x0000a1cc, 0x00000000},
1151 {0x0000a1d0, 0x00000000},
1152 {0x0000a1d4, 0x00000000},
1153 {0x0000a1d8, 0x00000000},
1154 {0x0000a1dc, 0x00000000},
1155 {0x0000a1e0, 0x00000000},
1156 {0x0000a1e4, 0x00000000},
1157 {0x0000a1e8, 0x00000000},
1158 {0x0000a1ec, 0x00000000},
1159 {0x0000a1f0, 0x00000396},
1160 {0x0000a1f4, 0x00000396},
1161 {0x0000a1f8, 0x00000396},
1162 {0x0000a1fc, 0x00000196},
1163 {0x0000b000, 0x00010000},
1164 {0x0000b004, 0x00030002},
1165 {0x0000b008, 0x00050004},
1166 {0x0000b00c, 0x00810080},
1167 {0x0000b010, 0x00830082},
1168 {0x0000b014, 0x01810180},
1169 {0x0000b018, 0x01830182},
1170 {0x0000b01c, 0x01850184},
1171 {0x0000b020, 0x02810280},
1172 {0x0000b024, 0x02830282},
1173 {0x0000b028, 0x02850284},
1174 {0x0000b02c, 0x02890288},
1175 {0x0000b030, 0x028b028a},
1176 {0x0000b034, 0x0388028c},
1177 {0x0000b038, 0x038a0389},
1178 {0x0000b03c, 0x038c038b},
1179 {0x0000b040, 0x0390038d},
1180 {0x0000b044, 0x03920391},
1181 {0x0000b048, 0x03940393},
1182 {0x0000b04c, 0x03960395},
1183 {0x0000b050, 0x00000000},
1184 {0x0000b054, 0x00000000},
1185 {0x0000b058, 0x00000000},
1186 {0x0000b05c, 0x00000000},
1187 {0x0000b060, 0x00000000},
1188 {0x0000b064, 0x00000000},
1189 {0x0000b068, 0x00000000},
1190 {0x0000b06c, 0x00000000},
1191 {0x0000b070, 0x00000000},
1192 {0x0000b074, 0x00000000},
1193 {0x0000b078, 0x00000000},
1194 {0x0000b07c, 0x00000000},
1195 {0x0000b080, 0x32323232},
1196 {0x0000b084, 0x2f2f3232},
1197 {0x0000b088, 0x23282a2d},
1198 {0x0000b08c, 0x1c1e2123},
1199 {0x0000b090, 0x14171919},
1200 {0x0000b094, 0x0e0e1214},
1201 {0x0000b098, 0x03050707},
1202 {0x0000b09c, 0x00030303},
1203 {0x0000b0a0, 0x00000000},
1204 {0x0000b0a4, 0x00000000},
1205 {0x0000b0a8, 0x00000000},
1206 {0x0000b0ac, 0x00000000},
1207 {0x0000b0b0, 0x00000000},
1208 {0x0000b0b4, 0x00000000},
1209 {0x0000b0b8, 0x00000000},
1210 {0x0000b0bc, 0x00000000},
1211 {0x0000b0c0, 0x003f0020},
1212 {0x0000b0c4, 0x00400041},
1213 {0x0000b0c8, 0x0140005f},
1214 {0x0000b0cc, 0x0160015f},
1215 {0x0000b0d0, 0x017e017f},
1216 {0x0000b0d4, 0x02410242},
1217 {0x0000b0d8, 0x025f0240},
1218 {0x0000b0dc, 0x027f0260},
1219 {0x0000b0e0, 0x0341027e},
1220 {0x0000b0e4, 0x035f0340},
1221 {0x0000b0e8, 0x037f0360},
1222 {0x0000b0ec, 0x04400441},
1223 {0x0000b0f0, 0x0460045f},
1224 {0x0000b0f4, 0x0541047f},
1225 {0x0000b0f8, 0x055f0540},
1226 {0x0000b0fc, 0x057f0560},
1227 {0x0000b100, 0x06400641},
1228 {0x0000b104, 0x0660065f},
1229 {0x0000b108, 0x067e067f},
1230 {0x0000b10c, 0x07410742},
1231 {0x0000b110, 0x075f0740},
1232 {0x0000b114, 0x077f0760},
1233 {0x0000b118, 0x07800781},
1234 {0x0000b11c, 0x07a0079f},
1235 {0x0000b120, 0x07c107bf},
1236 {0x0000b124, 0x000007c0},
1237 {0x0000b128, 0x00000000},
1238 {0x0000b12c, 0x00000000},
1239 {0x0000b130, 0x00000000},
1240 {0x0000b134, 0x00000000},
1241 {0x0000b138, 0x00000000},
1242 {0x0000b13c, 0x00000000},
1243 {0x0000b140, 0x003f0020},
1244 {0x0000b144, 0x00400041},
1245 {0x0000b148, 0x0140005f},
1246 {0x0000b14c, 0x0160015f},
1247 {0x0000b150, 0x017e017f},
1248 {0x0000b154, 0x02410242},
1249 {0x0000b158, 0x025f0240},
1250 {0x0000b15c, 0x027f0260},
1251 {0x0000b160, 0x0341027e},
1252 {0x0000b164, 0x035f0340},
1253 {0x0000b168, 0x037f0360},
1254 {0x0000b16c, 0x04400441},
1255 {0x0000b170, 0x0460045f},
1256 {0x0000b174, 0x0541047f},
1257 {0x0000b178, 0x055f0540},
1258 {0x0000b17c, 0x057f0560},
1259 {0x0000b180, 0x06400641},
1260 {0x0000b184, 0x0660065f},
1261 {0x0000b188, 0x067e067f},
1262 {0x0000b18c, 0x07410742},
1263 {0x0000b190, 0x075f0740},
1264 {0x0000b194, 0x077f0760},
1265 {0x0000b198, 0x07800781},
1266 {0x0000b19c, 0x07a0079f},
1267 {0x0000b1a0, 0x07c107bf},
1268 {0x0000b1a4, 0x000007c0},
1269 {0x0000b1a8, 0x00000000},
1270 {0x0000b1ac, 0x00000000},
1271 {0x0000b1b0, 0x00000000},
1272 {0x0000b1b4, 0x00000000},
1273 {0x0000b1b8, 0x00000000},
1274 {0x0000b1bc, 0x00000000},
1275 {0x0000b1c0, 0x00000000},
1276 {0x0000b1c4, 0x00000000},
1277 {0x0000b1c8, 0x00000000},
1278 {0x0000b1cc, 0x00000000},
1279 {0x0000b1d0, 0x00000000},
1280 {0x0000b1d4, 0x00000000},
1281 {0x0000b1d8, 0x00000000},
1282 {0x0000b1dc, 0x00000000},
1283 {0x0000b1e0, 0x00000000},
1284 {0x0000b1e4, 0x00000000},
1285 {0x0000b1e8, 0x00000000},
1286 {0x0000b1ec, 0x00000000},
1287 {0x0000b1f0, 0x00000396},
1288 {0x0000b1f4, 0x00000396},
1289 {0x0000b1f8, 0x00000396},
1290 {0x0000b1fc, 0x00000196},
1291};
1292
1293static const u32 ar9462_2p1_common_5g_xlna_only_rx_gain[][2] = {
1294 /* Addr allmodes */
1295 {0x0000a000, 0x00010000},
1296 {0x0000a004, 0x00030002},
1297 {0x0000a008, 0x00050004},
1298 {0x0000a00c, 0x00810080},
1299 {0x0000a010, 0x00830082},
1300 {0x0000a014, 0x01810180},
1301 {0x0000a018, 0x01830182},
1302 {0x0000a01c, 0x01850184},
1303 {0x0000a020, 0x01890188},
1304 {0x0000a024, 0x018b018a},
1305 {0x0000a028, 0x018d018c},
1306 {0x0000a02c, 0x03820190},
1307 {0x0000a030, 0x03840383},
1308 {0x0000a034, 0x03880385},
1309 {0x0000a038, 0x038a0389},
1310 {0x0000a03c, 0x038c038b},
1311 {0x0000a040, 0x0390038d},
1312 {0x0000a044, 0x03920391},
1313 {0x0000a048, 0x03940393},
1314 {0x0000a04c, 0x03960395},
1315 {0x0000a050, 0x00000000},
1316 {0x0000a054, 0x00000000},
1317 {0x0000a058, 0x00000000},
1318 {0x0000a05c, 0x00000000},
1319 {0x0000a060, 0x00000000},
1320 {0x0000a064, 0x00000000},
1321 {0x0000a068, 0x00000000},
1322 {0x0000a06c, 0x00000000},
1323 {0x0000a070, 0x00000000},
1324 {0x0000a074, 0x00000000},
1325 {0x0000a078, 0x00000000},
1326 {0x0000a07c, 0x00000000},
1327 {0x0000a080, 0x29292929},
1328 {0x0000a084, 0x29292929},
1329 {0x0000a088, 0x29292929},
1330 {0x0000a08c, 0x29292929},
1331 {0x0000a090, 0x22292929},
1332 {0x0000a094, 0x1d1d2222},
1333 {0x0000a098, 0x0c111117},
1334 {0x0000a09c, 0x00030303},
1335 {0x0000a0a0, 0x00000000},
1336 {0x0000a0a4, 0x00000000},
1337 {0x0000a0a8, 0x00000000},
1338 {0x0000a0ac, 0x00000000},
1339 {0x0000a0b0, 0x00000000},
1340 {0x0000a0b4, 0x00000000},
1341 {0x0000a0b8, 0x00000000},
1342 {0x0000a0bc, 0x00000000},
1343 {0x0000a0c0, 0x001f0000},
1344 {0x0000a0c4, 0x01000101},
1345 {0x0000a0c8, 0x011e011f},
1346 {0x0000a0cc, 0x011c011d},
1347 {0x0000a0d0, 0x02030204},
1348 {0x0000a0d4, 0x02010202},
1349 {0x0000a0d8, 0x021f0200},
1350 {0x0000a0dc, 0x0302021e},
1351 {0x0000a0e0, 0x03000301},
1352 {0x0000a0e4, 0x031e031f},
1353 {0x0000a0e8, 0x0402031d},
1354 {0x0000a0ec, 0x04000401},
1355 {0x0000a0f0, 0x041e041f},
1356 {0x0000a0f4, 0x0502041d},
1357 {0x0000a0f8, 0x05000501},
1358 {0x0000a0fc, 0x051e051f},
1359 {0x0000a100, 0x06010602},
1360 {0x0000a104, 0x061f0600},
1361 {0x0000a108, 0x061d061e},
1362 {0x0000a10c, 0x07020703},
1363 {0x0000a110, 0x07000701},
1364 {0x0000a114, 0x00000000},
1365 {0x0000a118, 0x00000000},
1366 {0x0000a11c, 0x00000000},
1367 {0x0000a120, 0x00000000},
1368 {0x0000a124, 0x00000000},
1369 {0x0000a128, 0x00000000},
1370 {0x0000a12c, 0x00000000},
1371 {0x0000a130, 0x00000000},
1372 {0x0000a134, 0x00000000},
1373 {0x0000a138, 0x00000000},
1374 {0x0000a13c, 0x00000000},
1375 {0x0000a140, 0x001f0000},
1376 {0x0000a144, 0x01000101},
1377 {0x0000a148, 0x011e011f},
1378 {0x0000a14c, 0x011c011d},
1379 {0x0000a150, 0x02030204},
1380 {0x0000a154, 0x02010202},
1381 {0x0000a158, 0x021f0200},
1382 {0x0000a15c, 0x0302021e},
1383 {0x0000a160, 0x03000301},
1384 {0x0000a164, 0x031e031f},
1385 {0x0000a168, 0x0402031d},
1386 {0x0000a16c, 0x04000401},
1387 {0x0000a170, 0x041e041f},
1388 {0x0000a174, 0x0502041d},
1389 {0x0000a178, 0x05000501},
1390 {0x0000a17c, 0x051e051f},
1391 {0x0000a180, 0x06010602},
1392 {0x0000a184, 0x061f0600},
1393 {0x0000a188, 0x061d061e},
1394 {0x0000a18c, 0x07020703},
1395 {0x0000a190, 0x07000701},
1396 {0x0000a194, 0x00000000},
1397 {0x0000a198, 0x00000000},
1398 {0x0000a19c, 0x00000000},
1399 {0x0000a1a0, 0x00000000},
1400 {0x0000a1a4, 0x00000000},
1401 {0x0000a1a8, 0x00000000},
1402 {0x0000a1ac, 0x00000000},
1403 {0x0000a1b0, 0x00000000},
1404 {0x0000a1b4, 0x00000000},
1405 {0x0000a1b8, 0x00000000},
1406 {0x0000a1bc, 0x00000000},
1407 {0x0000a1c0, 0x00000000},
1408 {0x0000a1c4, 0x00000000},
1409 {0x0000a1c8, 0x00000000},
1410 {0x0000a1cc, 0x00000000},
1411 {0x0000a1d0, 0x00000000},
1412 {0x0000a1d4, 0x00000000},
1413 {0x0000a1d8, 0x00000000},
1414 {0x0000a1dc, 0x00000000},
1415 {0x0000a1e0, 0x00000000},
1416 {0x0000a1e4, 0x00000000},
1417 {0x0000a1e8, 0x00000000},
1418 {0x0000a1ec, 0x00000000},
1419 {0x0000a1f0, 0x00000396},
1420 {0x0000a1f4, 0x00000396},
1421 {0x0000a1f8, 0x00000396},
1422 {0x0000a1fc, 0x00000196},
1423 {0x0000b000, 0x00010000},
1424 {0x0000b004, 0x00030002},
1425 {0x0000b008, 0x00050004},
1426 {0x0000b00c, 0x00810080},
1427 {0x0000b010, 0x00830082},
1428 {0x0000b014, 0x01810180},
1429 {0x0000b018, 0x01830182},
1430 {0x0000b01c, 0x01850184},
1431 {0x0000b020, 0x02810280},
1432 {0x0000b024, 0x02830282},
1433 {0x0000b028, 0x02850284},
1434 {0x0000b02c, 0x02890288},
1435 {0x0000b030, 0x028b028a},
1436 {0x0000b034, 0x0388028c},
1437 {0x0000b038, 0x038a0389},
1438 {0x0000b03c, 0x038c038b},
1439 {0x0000b040, 0x0390038d},
1440 {0x0000b044, 0x03920391},
1441 {0x0000b048, 0x03940393},
1442 {0x0000b04c, 0x03960395},
1443 {0x0000b050, 0x00000000},
1444 {0x0000b054, 0x00000000},
1445 {0x0000b058, 0x00000000},
1446 {0x0000b05c, 0x00000000},
1447 {0x0000b060, 0x00000000},
1448 {0x0000b064, 0x00000000},
1449 {0x0000b068, 0x00000000},
1450 {0x0000b06c, 0x00000000},
1451 {0x0000b070, 0x00000000},
1452 {0x0000b074, 0x00000000},
1453 {0x0000b078, 0x00000000},
1454 {0x0000b07c, 0x00000000},
1455 {0x0000b080, 0x2a2d2f32},
1456 {0x0000b084, 0x21232328},
1457 {0x0000b088, 0x19191c1e},
1458 {0x0000b08c, 0x12141417},
1459 {0x0000b090, 0x07070e0e},
1460 {0x0000b094, 0x03030305},
1461 {0x0000b098, 0x00000003},
1462 {0x0000b09c, 0x00000000},
1463 {0x0000b0a0, 0x00000000},
1464 {0x0000b0a4, 0x00000000},
1465 {0x0000b0a8, 0x00000000},
1466 {0x0000b0ac, 0x00000000},
1467 {0x0000b0b0, 0x00000000},
1468 {0x0000b0b4, 0x00000000},
1469 {0x0000b0b8, 0x00000000},
1470 {0x0000b0bc, 0x00000000},
1471 {0x0000b0c0, 0x003f0020},
1472 {0x0000b0c4, 0x00400041},
1473 {0x0000b0c8, 0x0140005f},
1474 {0x0000b0cc, 0x0160015f},
1475 {0x0000b0d0, 0x017e017f},
1476 {0x0000b0d4, 0x02410242},
1477 {0x0000b0d8, 0x025f0240},
1478 {0x0000b0dc, 0x027f0260},
1479 {0x0000b0e0, 0x0341027e},
1480 {0x0000b0e4, 0x035f0340},
1481 {0x0000b0e8, 0x037f0360},
1482 {0x0000b0ec, 0x04400441},
1483 {0x0000b0f0, 0x0460045f},
1484 {0x0000b0f4, 0x0541047f},
1485 {0x0000b0f8, 0x055f0540},
1486 {0x0000b0fc, 0x057f0560},
1487 {0x0000b100, 0x06400641},
1488 {0x0000b104, 0x0660065f},
1489 {0x0000b108, 0x067e067f},
1490 {0x0000b10c, 0x07410742},
1491 {0x0000b110, 0x075f0740},
1492 {0x0000b114, 0x077f0760},
1493 {0x0000b118, 0x07800781},
1494 {0x0000b11c, 0x07a0079f},
1495 {0x0000b120, 0x07c107bf},
1496 {0x0000b124, 0x000007c0},
1497 {0x0000b128, 0x00000000},
1498 {0x0000b12c, 0x00000000},
1499 {0x0000b130, 0x00000000},
1500 {0x0000b134, 0x00000000},
1501 {0x0000b138, 0x00000000},
1502 {0x0000b13c, 0x00000000},
1503 {0x0000b140, 0x003f0020},
1504 {0x0000b144, 0x00400041},
1505 {0x0000b148, 0x0140005f},
1506 {0x0000b14c, 0x0160015f},
1507 {0x0000b150, 0x017e017f},
1508 {0x0000b154, 0x02410242},
1509 {0x0000b158, 0x025f0240},
1510 {0x0000b15c, 0x027f0260},
1511 {0x0000b160, 0x0341027e},
1512 {0x0000b164, 0x035f0340},
1513 {0x0000b168, 0x037f0360},
1514 {0x0000b16c, 0x04400441},
1515 {0x0000b170, 0x0460045f},
1516 {0x0000b174, 0x0541047f},
1517 {0x0000b178, 0x055f0540},
1518 {0x0000b17c, 0x057f0560},
1519 {0x0000b180, 0x06400641},
1520 {0x0000b184, 0x0660065f},
1521 {0x0000b188, 0x067e067f},
1522 {0x0000b18c, 0x07410742},
1523 {0x0000b190, 0x075f0740},
1524 {0x0000b194, 0x077f0760},
1525 {0x0000b198, 0x07800781},
1526 {0x0000b19c, 0x07a0079f},
1527 {0x0000b1a0, 0x07c107bf},
1528 {0x0000b1a4, 0x000007c0},
1529 {0x0000b1a8, 0x00000000},
1530 {0x0000b1ac, 0x00000000},
1531 {0x0000b1b0, 0x00000000},
1532 {0x0000b1b4, 0x00000000},
1533 {0x0000b1b8, 0x00000000},
1534 {0x0000b1bc, 0x00000000},
1535 {0x0000b1c0, 0x00000000},
1536 {0x0000b1c4, 0x00000000},
1537 {0x0000b1c8, 0x00000000},
1538 {0x0000b1cc, 0x00000000},
1539 {0x0000b1d0, 0x00000000},
1540 {0x0000b1d4, 0x00000000},
1541 {0x0000b1d8, 0x00000000},
1542 {0x0000b1dc, 0x00000000},
1543 {0x0000b1e0, 0x00000000},
1544 {0x0000b1e4, 0x00000000},
1545 {0x0000b1e8, 0x00000000},
1546 {0x0000b1ec, 0x00000000},
1547 {0x0000b1f0, 0x00000396},
1548 {0x0000b1f4, 0x00000396},
1549 {0x0000b1f8, 0x00000396},
1550 {0x0000b1fc, 0x00000196},
1551};
1552
1553static const u32 ar9462_2p1_modes_low_ob_db_tx_gain[][5] = {
1554 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1555 {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
1556 {0x0000a2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
1557 {0x0000a2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
1558 {0x0000a2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
1559 {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
1560 {0x0000a410, 0x000050d9, 0x000050d9, 0x000050d9, 0x000050d9},
1561 {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1562 {0x0000a500, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1563 {0x0000a504, 0x06000003, 0x06000003, 0x04000002, 0x04000002},
1564 {0x0000a508, 0x0a000020, 0x0a000020, 0x08000004, 0x08000004},
1565 {0x0000a50c, 0x10000023, 0x10000023, 0x0b000200, 0x0b000200},
1566 {0x0000a510, 0x16000220, 0x16000220, 0x0f000202, 0x0f000202},
1567 {0x0000a514, 0x1c000223, 0x1c000223, 0x12000400, 0x12000400},
1568 {0x0000a518, 0x21020220, 0x21020220, 0x16000402, 0x16000402},
1569 {0x0000a51c, 0x27020223, 0x27020223, 0x19000404, 0x19000404},
1570 {0x0000a520, 0x2b022220, 0x2b022220, 0x1c000603, 0x1c000603},
1571 {0x0000a524, 0x2f022222, 0x2f022222, 0x21000a02, 0x21000a02},
1572 {0x0000a528, 0x34022225, 0x34022225, 0x25000a04, 0x25000a04},
1573 {0x0000a52c, 0x3a02222a, 0x3a02222a, 0x28000a20, 0x28000a20},
1574 {0x0000a530, 0x3e02222c, 0x3e02222c, 0x2c000e20, 0x2c000e20},
1575 {0x0000a534, 0x4202242a, 0x4202242a, 0x30000e22, 0x30000e22},
1576 {0x0000a538, 0x4702244a, 0x4702244a, 0x34000e24, 0x34000e24},
1577 {0x0000a53c, 0x4b02244c, 0x4b02244c, 0x38001640, 0x38001640},
1578 {0x0000a540, 0x4e02246c, 0x4e02246c, 0x3c001660, 0x3c001660},
1579 {0x0000a544, 0x5302266c, 0x5302266c, 0x3f001861, 0x3f001861},
1580 {0x0000a548, 0x5702286c, 0x5702286c, 0x43001a81, 0x43001a81},
1581 {0x0000a54c, 0x5c04286b, 0x5c04286b, 0x47001a83, 0x47001a83},
1582 {0x0000a550, 0x61042a6c, 0x61042a6c, 0x4a001c84, 0x4a001c84},
1583 {0x0000a554, 0x66062a6c, 0x66062a6c, 0x4e001ce3, 0x4e001ce3},
1584 {0x0000a558, 0x6b062e6c, 0x6b062e6c, 0x52001ce5, 0x52001ce5},
1585 {0x0000a55c, 0x7006308c, 0x7006308c, 0x56001ce9, 0x56001ce9},
1586 {0x0000a560, 0x730a308a, 0x730a308a, 0x5a001ceb, 0x5a001ceb},
1587 {0x0000a564, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
1588 {0x0000a568, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
1589 {0x0000a56c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
1590 {0x0000a570, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
1591 {0x0000a574, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
1592 {0x0000a578, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
1593 {0x0000a57c, 0x770a308c, 0x770a308c, 0x5d001eec, 0x5d001eec},
1594 {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1595 {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1596 {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1597 {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1598 {0x0000a610, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1599 {0x0000a614, 0x01404000, 0x01404000, 0x01404000, 0x01404000},
1600 {0x0000a618, 0x01404501, 0x01404501, 0x01404501, 0x01404501},
1601 {0x0000a61c, 0x02008802, 0x02008802, 0x02008501, 0x02008501},
1602 {0x0000a620, 0x0300cc03, 0x0300cc03, 0x0280ca03, 0x0280ca03},
1603 {0x0000a624, 0x0300cc03, 0x0300cc03, 0x03010c04, 0x03010c04},
1604 {0x0000a628, 0x0300cc03, 0x0300cc03, 0x04014c04, 0x04014c04},
1605 {0x0000a62c, 0x03810c03, 0x03810c03, 0x04015005, 0x04015005},
1606 {0x0000a630, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
1607 {0x0000a634, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
1608 {0x0000a638, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
1609 {0x0000a63c, 0x03810e04, 0x03810e04, 0x04015005, 0x04015005},
1610 {0x0000b2dc, 0x0380c7fc, 0x0380c7fc, 0x03aaa352, 0x03aaa352},
1611 {0x0000b2e0, 0x0000f800, 0x0000f800, 0x03ccc584, 0x03ccc584},
1612 {0x0000b2e4, 0x03ff0000, 0x03ff0000, 0x03f0f800, 0x03f0f800},
1613 {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
1614 {0x00016044, 0x012482d4, 0x012482d4, 0x012482d4, 0x012482d4},
1615 {0x00016048, 0x64992060, 0x64992060, 0x64992060, 0x64992060},
1616 {0x00016054, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000},
1617 {0x00016444, 0x012482d4, 0x012482d4, 0x012482d4, 0x012482d4},
1618 {0x00016448, 0x64992000, 0x64992000, 0x64992000, 0x64992000},
1619 {0x00016454, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000},
1620};
1621
1622static const u32 ar9462_2p1_modes_high_ob_db_tx_gain[][5] = {
1623 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1624 {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
1625 {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
1626 {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
1627 {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
1628 {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
1629 {0x0000a410, 0x000050da, 0x000050da, 0x000050de, 0x000050de},
1630 {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1631 {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
1632 {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002},
1633 {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004},
1634 {0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200},
1635 {0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202},
1636 {0x0000a514, 0x18022622, 0x18022622, 0x11000400, 0x11000400},
1637 {0x0000a518, 0x1b022822, 0x1b022822, 0x15000402, 0x15000402},
1638 {0x0000a51c, 0x20022842, 0x20022842, 0x19000404, 0x19000404},
1639 {0x0000a520, 0x22022c41, 0x22022c41, 0x1b000603, 0x1b000603},
1640 {0x0000a524, 0x28023042, 0x28023042, 0x1f000a02, 0x1f000a02},
1641 {0x0000a528, 0x2c023044, 0x2c023044, 0x23000a04, 0x23000a04},
1642 {0x0000a52c, 0x2f023644, 0x2f023644, 0x26000a20, 0x26000a20},
1643 {0x0000a530, 0x34025643, 0x34025643, 0x2a000e20, 0x2a000e20},
1644 {0x0000a534, 0x38025a44, 0x38025a44, 0x2e000e22, 0x2e000e22},
1645 {0x0000a538, 0x3b025e45, 0x3b025e45, 0x31000e24, 0x31000e24},
1646 {0x0000a53c, 0x41025e4a, 0x41025e4a, 0x34001640, 0x34001640},
1647 {0x0000a540, 0x48025e6c, 0x48025e6c, 0x38001660, 0x38001660},
1648 {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3b001861, 0x3b001861},
1649 {0x0000a548, 0x55025eb3, 0x55025eb3, 0x3e001a81, 0x3e001a81},
1650 {0x0000a54c, 0x58025ef3, 0x58025ef3, 0x42001a83, 0x42001a83},
1651 {0x0000a550, 0x5d025ef6, 0x5d025ef6, 0x44001a84, 0x44001a84},
1652 {0x0000a554, 0x62025f56, 0x62025f56, 0x48001ce3, 0x48001ce3},
1653 {0x0000a558, 0x66027f56, 0x66027f56, 0x4c001ce5, 0x4c001ce5},
1654 {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x50001ce9, 0x50001ce9},
1655 {0x0000a560, 0x70049f56, 0x70049f56, 0x54001ceb, 0x54001ceb},
1656 {0x0000a564, 0x751ffff6, 0x751ffff6, 0x56001eec, 0x56001eec},
1657 {0x0000a568, 0x751ffff6, 0x751ffff6, 0x58001ef0, 0x58001ef0},
1658 {0x0000a56c, 0x751ffff6, 0x751ffff6, 0x5a001ef4, 0x5a001ef4},
1659 {0x0000a570, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6},
1660 {0x0000a574, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6},
1661 {0x0000a578, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6},
1662 {0x0000a57c, 0x751ffff6, 0x751ffff6, 0x5c001ff6, 0x5c001ff6},
1663 {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1664 {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1665 {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1666 {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1667 {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000},
1668 {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000},
1669 {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501},
1670 {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501},
1671 {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03},
1672 {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04},
1673 {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04},
1674 {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1675 {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1676 {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1677 {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1678 {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1679 {0x0000b2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
1680 {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
1681 {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
1682 {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
1683 {0x00016044, 0x056d82e4, 0x056d82e4, 0x056d82e4, 0x056d82e4},
1684 {0x00016048, 0x8db49060, 0x8db49060, 0x8db49060, 0x8db49060},
1685 {0x00016054, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000},
1686 {0x00016444, 0x056d82e4, 0x056d82e4, 0x056d82e4, 0x056d82e4},
1687 {0x00016448, 0x8db49000, 0x8db49000, 0x8db49000, 0x8db49000},
1688 {0x00016454, 0x6db60000, 0x6db60000, 0x6db60000, 0x6db60000},
1689};
1690
1691static const u32 ar9462_2p1_modes_mix_ob_db_tx_gain[][5] = {
1692 /* Addr 5G_HT20 5G_HT40 2G_HT40 2G_HT20 */
1693 {0x000098bc, 0x00000002, 0x00000002, 0x00000002, 0x00000002},
1694 {0x0000a2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
1695 {0x0000a2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
1696 {0x0000a2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
1697 {0x0000a2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
1698 {0x0000a410, 0x0000d0da, 0x0000d0da, 0x0000d0de, 0x0000d0de},
1699 {0x0000a458, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1700 {0x0000a500, 0x00002220, 0x00002220, 0x00000000, 0x00000000},
1701 {0x0000a504, 0x06002223, 0x06002223, 0x04000002, 0x04000002},
1702 {0x0000a508, 0x0a022220, 0x0a022220, 0x08000004, 0x08000004},
1703 {0x0000a50c, 0x0f022223, 0x0f022223, 0x0b000200, 0x0b000200},
1704 {0x0000a510, 0x14022620, 0x14022620, 0x0f000202, 0x0f000202},
1705 {0x0000a514, 0x18022622, 0x18022622, 0x12000400, 0x12000400},
1706 {0x0000a518, 0x1b022822, 0x1b022822, 0x16000402, 0x16000402},
1707 {0x0000a51c, 0x20022842, 0x20022842, 0x19000404, 0x19000404},
1708 {0x0000a520, 0x22022c41, 0x22022c41, 0x1c000603, 0x1c000603},
1709 {0x0000a524, 0x28023042, 0x28023042, 0x21000a02, 0x21000a02},
1710 {0x0000a528, 0x2c023044, 0x2c023044, 0x25000a04, 0x25000a04},
1711 {0x0000a52c, 0x2f023644, 0x2f023644, 0x28000a20, 0x28000a20},
1712 {0x0000a530, 0x34025643, 0x34025643, 0x2c000e20, 0x2c000e20},
1713 {0x0000a534, 0x38025a44, 0x38025a44, 0x30000e22, 0x30000e22},
1714 {0x0000a538, 0x3b025e45, 0x3b025e45, 0x34000e24, 0x34000e24},
1715 {0x0000a53c, 0x41025e4a, 0x41025e4a, 0x38001640, 0x38001640},
1716 {0x0000a540, 0x48025e6c, 0x48025e6c, 0x3c001660, 0x3c001660},
1717 {0x0000a544, 0x4e025e8e, 0x4e025e8e, 0x3f001861, 0x3f001861},
1718 {0x0000a548, 0x55025eb3, 0x55025eb3, 0x43001a81, 0x43001a81},
1719 {0x0000a54c, 0x58025ef3, 0x58025ef3, 0x47001a83, 0x47001a83},
1720 {0x0000a550, 0x5d025ef6, 0x5d025ef6, 0x4a001c84, 0x4a001c84},
1721 {0x0000a554, 0x62025f56, 0x62025f56, 0x4e001ce3, 0x4e001ce3},
1722 {0x0000a558, 0x66027f56, 0x66027f56, 0x52001ce5, 0x52001ce5},
1723 {0x0000a55c, 0x6a029f56, 0x6a029f56, 0x56001ce9, 0x56001ce9},
1724 {0x0000a560, 0x70049f56, 0x70049f56, 0x5a001ceb, 0x5a001ceb},
1725 {0x0000a564, 0x751ffff6, 0x751ffff6, 0x5c001eec, 0x5c001eec},
1726 {0x0000a568, 0x751ffff6, 0x751ffff6, 0x5e001ef0, 0x5e001ef0},
1727 {0x0000a56c, 0x751ffff6, 0x751ffff6, 0x60001ef4, 0x60001ef4},
1728 {0x0000a570, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6},
1729 {0x0000a574, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6},
1730 {0x0000a578, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6},
1731 {0x0000a57c, 0x751ffff6, 0x751ffff6, 0x62001ff6, 0x62001ff6},
1732 {0x0000a600, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1733 {0x0000a604, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1734 {0x0000a608, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1735 {0x0000a60c, 0x00000000, 0x00000000, 0x00000000, 0x00000000},
1736 {0x0000a610, 0x00804000, 0x00804000, 0x00000000, 0x00000000},
1737 {0x0000a614, 0x00804201, 0x00804201, 0x01404000, 0x01404000},
1738 {0x0000a618, 0x0280c802, 0x0280c802, 0x01404501, 0x01404501},
1739 {0x0000a61c, 0x0280ca03, 0x0280ca03, 0x02008501, 0x02008501},
1740 {0x0000a620, 0x04c15104, 0x04c15104, 0x0280ca03, 0x0280ca03},
1741 {0x0000a624, 0x04c15305, 0x04c15305, 0x03010c04, 0x03010c04},
1742 {0x0000a628, 0x04c15305, 0x04c15305, 0x04014c04, 0x04014c04},
1743 {0x0000a62c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1744 {0x0000a630, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1745 {0x0000a634, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1746 {0x0000a638, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1747 {0x0000a63c, 0x04c15305, 0x04c15305, 0x04015005, 0x04015005},
1748 {0x0000b2dc, 0x01feee00, 0x01feee00, 0x03aaa352, 0x03aaa352},
1749 {0x0000b2e0, 0x0000f000, 0x0000f000, 0x03ccc584, 0x03ccc584},
1750 {0x0000b2e4, 0x01ff0000, 0x01ff0000, 0x03f0f800, 0x03f0f800},
1751 {0x0000b2e8, 0x00000000, 0x00000000, 0x03ff0000, 0x03ff0000},
1752};
1753
1754static const u32 ar9462_2p1_modes_fast_clock[][3] = {
1755 /* Addr 5G_HT20 5G_HT40 */
1756 {0x00001030, 0x00000268, 0x000004d0},
1757 {0x00001070, 0x0000018c, 0x00000318},
1758 {0x000010b0, 0x00000fd0, 0x00001fa0},
1759 {0x00008014, 0x044c044c, 0x08980898},
1760 {0x0000801c, 0x148ec02b, 0x148ec057},
1761 {0x00008318, 0x000044c0, 0x00008980},
1762 {0x00009e00, 0x0372131c, 0x0372131c},
1763 {0x0000a230, 0x0000400b, 0x00004016},
1764 {0x0000a254, 0x00000898, 0x00001130},
1765};
1766
1767static const u32 ar9462_2p1_baseband_core_txfir_coeff_japan_2484[][2] = {
1768 /* Addr allmodes */
1769 {0x0000a398, 0x00000000},
1770 {0x0000a39c, 0x6f7f0301},
1771 {0x0000a3a0, 0xca9228ee},
1772};
1773
1774#endif /* INITVALS_9462_2P1_H */
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 04b2d3ea728f..c1224b5a257b 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -634,6 +634,7 @@ void ath_ant_comb_update(struct ath_softc *sc);
634#define ATH9K_PCI_CUS198 0x0001 634#define ATH9K_PCI_CUS198 0x0001
635#define ATH9K_PCI_CUS230 0x0002 635#define ATH9K_PCI_CUS230 0x0002
636#define ATH9K_PCI_CUS217 0x0004 636#define ATH9K_PCI_CUS217 0x0004
637#define ATH9K_PCI_WOW 0x0008
637 638
638/* 639/*
639 * Default cache line size, in bytes. 640 * Default cache line size, in bytes.
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index f5dda84176c3..9e582e14da74 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -234,10 +234,15 @@ static inline void ath9k_skb_queue_complete(struct hif_device_usb *hif_dev,
234 struct sk_buff *skb; 234 struct sk_buff *skb;
235 235
236 while ((skb = __skb_dequeue(queue)) != NULL) { 236 while ((skb = __skb_dequeue(queue)) != NULL) {
237#ifdef CONFIG_ATH9K_HTC_DEBUGFS
238 int ln = skb->len;
239#endif
237 ath9k_htc_txcompletion_cb(hif_dev->htc_handle, 240 ath9k_htc_txcompletion_cb(hif_dev->htc_handle,
238 skb, txok); 241 skb, txok);
239 if (txok) 242 if (txok) {
240 TX_STAT_INC(skb_success); 243 TX_STAT_INC(skb_success);
244 TX_STAT_ADD(skb_success_bytes, ln);
245 }
241 else 246 else
242 TX_STAT_INC(skb_failed); 247 TX_STAT_INC(skb_failed);
243 } 248 }
@@ -620,6 +625,7 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev,
620 625
621err: 626err:
622 for (i = 0; i < pool_index; i++) { 627 for (i = 0; i < pool_index; i++) {
628 RX_STAT_ADD(skb_completed_bytes, skb_pool[i]->len);
623 ath9k_htc_rx_msg(hif_dev->htc_handle, skb_pool[i], 629 ath9k_htc_rx_msg(hif_dev->htc_handle, skb_pool[i],
624 skb_pool[i]->len, USB_WLAN_RX_PIPE); 630 skb_pool[i]->len, USB_WLAN_RX_PIPE);
625 RX_STAT_INC(skb_completed); 631 RX_STAT_INC(skb_completed);
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index 69581031f2cd..055d7c25e090 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -324,7 +324,9 @@ static inline struct ath9k_htc_tx_ctl *HTC_SKB_CB(struct sk_buff *skb)
324#ifdef CONFIG_ATH9K_HTC_DEBUGFS 324#ifdef CONFIG_ATH9K_HTC_DEBUGFS
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 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.rx_stats.c++)
329#define RX_STAT_ADD(c, a) (hif_dev->htc_handle->drv_priv->debug.rx_stats.c += a)
328#define CAB_STAT_INC priv->debug.tx_stats.cab_queued++ 330#define CAB_STAT_INC priv->debug.tx_stats.cab_queued++
329 331
330#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]++)
@@ -337,6 +339,7 @@ struct ath_tx_stats {
337 u32 buf_completed; 339 u32 buf_completed;
338 u32 skb_queued; 340 u32 skb_queued;
339 u32 skb_success; 341 u32 skb_success;
342 u32 skb_success_bytes;
340 u32 skb_failed; 343 u32 skb_failed;
341 u32 cab_queued; 344 u32 cab_queued;
342 u32 queue_stats[IEEE80211_NUM_ACS]; 345 u32 queue_stats[IEEE80211_NUM_ACS];
@@ -345,6 +348,7 @@ struct ath_tx_stats {
345struct ath_rx_stats { 348struct ath_rx_stats {
346 u32 skb_allocated; 349 u32 skb_allocated;
347 u32 skb_completed; 350 u32 skb_completed;
351 u32 skb_completed_bytes;
348 u32 skb_dropped; 352 u32 skb_dropped;
349 u32 err_crc; 353 u32 err_crc;
350 u32 err_decrypt_crc; 354 u32 err_decrypt_crc;
@@ -362,10 +366,20 @@ struct ath9k_debug {
362 struct ath_rx_stats rx_stats; 366 struct ath_rx_stats rx_stats;
363}; 367};
364 368
369void ath9k_htc_get_et_strings(struct ieee80211_hw *hw,
370 struct ieee80211_vif *vif,
371 u32 sset, u8 *data);
372int ath9k_htc_get_et_sset_count(struct ieee80211_hw *hw,
373 struct ieee80211_vif *vif, int sset);
374void ath9k_htc_get_et_stats(struct ieee80211_hw *hw,
375 struct ieee80211_vif *vif,
376 struct ethtool_stats *stats, u64 *data);
365#else 377#else
366 378
367#define TX_STAT_INC(c) do { } while (0) 379#define TX_STAT_INC(c) do { } while (0)
380#define TX_STAT_ADD(c, a) do { } while (0)
368#define RX_STAT_INC(c) do { } while (0) 381#define RX_STAT_INC(c) do { } while (0)
382#define RX_STAT_ADD(c, a) do { } while (0)
369#define CAB_STAT_INC do { } while (0) 383#define CAB_STAT_INC do { } while (0)
370 384
371#define TX_QSTAT_INC(c) do { } while (0) 385#define TX_QSTAT_INC(c) do { } while (0)
@@ -583,6 +597,8 @@ bool ath9k_htc_setpower(struct ath9k_htc_priv *priv,
583void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv); 597void ath9k_start_rfkill_poll(struct ath9k_htc_priv *priv);
584void ath9k_htc_rfkill_poll_state(struct ieee80211_hw *hw); 598void ath9k_htc_rfkill_poll_state(struct ieee80211_hw *hw);
585 599
600struct base_eep_header *ath9k_htc_get_eeprom_base(struct ath9k_htc_priv *priv);
601
586#ifdef CONFIG_MAC80211_LEDS 602#ifdef CONFIG_MAC80211_LEDS
587void ath9k_init_leds(struct ath9k_htc_priv *priv); 603void ath9k_init_leds(struct ath9k_htc_priv *priv);
588void ath9k_deinit_leds(struct ath9k_htc_priv *priv); 604void ath9k_deinit_leds(struct ath9k_htc_priv *priv);
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
index d08ef24e9696..c1b45e2f8481 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_debug.c
@@ -496,21 +496,7 @@ static ssize_t read_file_base_eeprom(struct file *file, char __user *user_buf,
496 ssize_t retval = 0; 496 ssize_t retval = 0;
497 char *buf; 497 char *buf;
498 498
499 /* 499 pBase = ath9k_htc_get_eeprom_base(priv);
500 * This can be done since all the 3 EEPROM families have the
501 * same base header upto a certain point, and we are interested in
502 * the data only upto that point.
503 */
504
505 if (AR_SREV_9271(priv->ah))
506 pBase = (struct base_eep_header *)
507 &priv->ah->eeprom.map4k.baseEepHeader;
508 else if (priv->ah->hw_version.usbdev == AR9280_USB)
509 pBase = (struct base_eep_header *)
510 &priv->ah->eeprom.def.baseEepHeader;
511 else if (priv->ah->hw_version.usbdev == AR9287_USB)
512 pBase = (struct base_eep_header *)
513 &priv->ah->eeprom.map9287.baseEepHeader;
514 500
515 if (pBase == NULL) { 501 if (pBase == NULL) {
516 ath_err(common, "Unknown EEPROM type\n"); 502 ath_err(common, "Unknown EEPROM type\n");
@@ -916,6 +902,87 @@ static const struct file_operations fops_modal_eeprom = {
916 .llseek = default_llseek, 902 .llseek = default_llseek,
917}; 903};
918 904
905
906/* Ethtool support for get-stats */
907#define AMKSTR(nm) #nm "_BE", #nm "_BK", #nm "_VI", #nm "_VO"
908static const char ath9k_htc_gstrings_stats[][ETH_GSTRING_LEN] = {
909 "tx_pkts_nic",
910 "tx_bytes_nic",
911 "rx_pkts_nic",
912 "rx_bytes_nic",
913
914 AMKSTR(d_tx_pkts),
915
916 "d_rx_crc_err",
917 "d_rx_decrypt_crc_err",
918 "d_rx_phy_err",
919 "d_rx_mic_err",
920 "d_rx_pre_delim_crc_err",
921 "d_rx_post_delim_crc_err",
922 "d_rx_decrypt_busy_err",
923
924 "d_rx_phyerr_radar",
925 "d_rx_phyerr_ofdm_timing",
926 "d_rx_phyerr_cck_timing",
927
928};
929#define ATH9K_HTC_SSTATS_LEN ARRAY_SIZE(ath9k_htc_gstrings_stats)
930
931void ath9k_htc_get_et_strings(struct ieee80211_hw *hw,
932 struct ieee80211_vif *vif,
933 u32 sset, u8 *data)
934{
935 if (sset == ETH_SS_STATS)
936 memcpy(data, *ath9k_htc_gstrings_stats,
937 sizeof(ath9k_htc_gstrings_stats));
938}
939
940int ath9k_htc_get_et_sset_count(struct ieee80211_hw *hw,
941 struct ieee80211_vif *vif, int sset)
942{
943 if (sset == ETH_SS_STATS)
944 return ATH9K_HTC_SSTATS_LEN;
945 return 0;
946}
947
948#define STXBASE priv->debug.tx_stats
949#define SRXBASE priv->debug.rx_stats
950#define ASTXQ(a) \
951 data[i++] = STXBASE.a[IEEE80211_AC_BE]; \
952 data[i++] = STXBASE.a[IEEE80211_AC_BK]; \
953 data[i++] = STXBASE.a[IEEE80211_AC_VI]; \
954 data[i++] = STXBASE.a[IEEE80211_AC_VO]
955
956void ath9k_htc_get_et_stats(struct ieee80211_hw *hw,
957 struct ieee80211_vif *vif,
958 struct ethtool_stats *stats, u64 *data)
959{
960 struct ath9k_htc_priv *priv = hw->priv;
961 int i = 0;
962
963 data[i++] = STXBASE.skb_success;
964 data[i++] = STXBASE.skb_success_bytes;
965 data[i++] = SRXBASE.skb_completed;
966 data[i++] = SRXBASE.skb_completed_bytes;
967
968 ASTXQ(queue_stats);
969
970 data[i++] = SRXBASE.err_crc;
971 data[i++] = SRXBASE.err_decrypt_crc;
972 data[i++] = SRXBASE.err_phy;
973 data[i++] = SRXBASE.err_mic;
974 data[i++] = SRXBASE.err_pre_delim;
975 data[i++] = SRXBASE.err_post_delim;
976 data[i++] = SRXBASE.err_decrypt_busy;
977
978 data[i++] = SRXBASE.err_phy_stats[ATH9K_PHYERR_RADAR];
979 data[i++] = SRXBASE.err_phy_stats[ATH9K_PHYERR_OFDM_TIMING];
980 data[i++] = SRXBASE.err_phy_stats[ATH9K_PHYERR_CCK_TIMING];
981
982 WARN_ON(i != ATH9K_HTC_SSTATS_LEN);
983}
984
985
919int ath9k_htc_init_debug(struct ath_hw *ah) 986int ath9k_htc_init_debug(struct ath_hw *ah)
920{ 987{
921 struct ath_common *common = ath9k_hw_common(ah); 988 struct ath_common *common = ath9k_hw_common(ah);
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index bb0ba9e3e083..71a183ffc77f 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -701,8 +701,10 @@ static const struct ieee80211_iface_limit if_limits[] = {
701 { .max = 2, .types = BIT(NL80211_IFTYPE_STATION) | 701 { .max = 2, .types = BIT(NL80211_IFTYPE_STATION) |
702 BIT(NL80211_IFTYPE_P2P_CLIENT) }, 702 BIT(NL80211_IFTYPE_P2P_CLIENT) },
703 { .max = 2, .types = BIT(NL80211_IFTYPE_AP) | 703 { .max = 2, .types = BIT(NL80211_IFTYPE_AP) |
704 BIT(NL80211_IFTYPE_P2P_GO) | 704#ifdef CONFIG_MAC80211_MESH
705 BIT(NL80211_IFTYPE_MESH_POINT) }, 705 BIT(NL80211_IFTYPE_MESH_POINT) |
706#endif
707 BIT(NL80211_IFTYPE_P2P_GO) },
706}; 708};
707 709
708static const struct ieee80211_iface_combination if_comb = { 710static const struct ieee80211_iface_combination if_comb = {
@@ -716,6 +718,7 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
716 struct ieee80211_hw *hw) 718 struct ieee80211_hw *hw)
717{ 719{
718 struct ath_common *common = ath9k_hw_common(priv->ah); 720 struct ath_common *common = ath9k_hw_common(priv->ah);
721 struct base_eep_header *pBase;
719 722
720 hw->flags = IEEE80211_HW_SIGNAL_DBM | 723 hw->flags = IEEE80211_HW_SIGNAL_DBM |
721 IEEE80211_HW_AMPDU_AGGREGATION | 724 IEEE80211_HW_AMPDU_AGGREGATION |
@@ -771,6 +774,12 @@ static void ath9k_set_hw_capab(struct ath9k_htc_priv *priv,
771 &priv->sbands[IEEE80211_BAND_5GHZ].ht_cap); 774 &priv->sbands[IEEE80211_BAND_5GHZ].ht_cap);
772 } 775 }
773 776
777 pBase = ath9k_htc_get_eeprom_base(priv);
778 if (pBase) {
779 hw->wiphy->available_antennas_rx = pBase->rxMask;
780 hw->wiphy->available_antennas_tx = pBase->txMask;
781 }
782
774 SET_IEEE80211_PERM_ADDR(hw, common->macaddr); 783 SET_IEEE80211_PERM_ADDR(hw, common->macaddr);
775} 784}
776 785
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index eaa94feb4333..5c1bec18c9e3 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -1183,7 +1183,7 @@ static int ath9k_htc_config(struct ieee80211_hw *hw, u32 changed)
1183 mutex_lock(&priv->htc_pm_lock); 1183 mutex_lock(&priv->htc_pm_lock);
1184 1184
1185 priv->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE); 1185 priv->ps_idle = !!(conf->flags & IEEE80211_CONF_IDLE);
1186 if (priv->ps_idle) 1186 if (!priv->ps_idle)
1187 chip_reset = true; 1187 chip_reset = true;
1188 1188
1189 mutex_unlock(&priv->htc_pm_lock); 1189 mutex_unlock(&priv->htc_pm_lock);
@@ -1774,6 +1774,43 @@ static int ath9k_htc_get_stats(struct ieee80211_hw *hw,
1774 return 0; 1774 return 0;
1775} 1775}
1776 1776
1777struct base_eep_header *ath9k_htc_get_eeprom_base(struct ath9k_htc_priv *priv)
1778{
1779 struct base_eep_header *pBase = NULL;
1780 /*
1781 * This can be done since all the 3 EEPROM families have the
1782 * same base header upto a certain point, and we are interested in
1783 * the data only upto that point.
1784 */
1785
1786 if (AR_SREV_9271(priv->ah))
1787 pBase = (struct base_eep_header *)
1788 &priv->ah->eeprom.map4k.baseEepHeader;
1789 else if (priv->ah->hw_version.usbdev == AR9280_USB)
1790 pBase = (struct base_eep_header *)
1791 &priv->ah->eeprom.def.baseEepHeader;
1792 else if (priv->ah->hw_version.usbdev == AR9287_USB)
1793 pBase = (struct base_eep_header *)
1794 &priv->ah->eeprom.map9287.baseEepHeader;
1795 return pBase;
1796}
1797
1798
1799static int ath9k_htc_get_antenna(struct ieee80211_hw *hw, u32 *tx_ant,
1800 u32 *rx_ant)
1801{
1802 struct ath9k_htc_priv *priv = hw->priv;
1803 struct base_eep_header *pBase = ath9k_htc_get_eeprom_base(priv);
1804 if (pBase) {
1805 *tx_ant = pBase->txMask;
1806 *rx_ant = pBase->rxMask;
1807 } else {
1808 *tx_ant = 0;
1809 *rx_ant = 0;
1810 }
1811 return 0;
1812}
1813
1777struct ieee80211_ops ath9k_htc_ops = { 1814struct ieee80211_ops ath9k_htc_ops = {
1778 .tx = ath9k_htc_tx, 1815 .tx = ath9k_htc_tx,
1779 .start = ath9k_htc_start, 1816 .start = ath9k_htc_start,
@@ -1799,4 +1836,11 @@ struct ieee80211_ops ath9k_htc_ops = {
1799 .set_coverage_class = ath9k_htc_set_coverage_class, 1836 .set_coverage_class = ath9k_htc_set_coverage_class,
1800 .set_bitrate_mask = ath9k_htc_set_bitrate_mask, 1837 .set_bitrate_mask = ath9k_htc_set_bitrate_mask,
1801 .get_stats = ath9k_htc_get_stats, 1838 .get_stats = ath9k_htc_get_stats,
1839 .get_antenna = ath9k_htc_get_antenna,
1840
1841#ifdef CONFIG_ATH9K_HTC_DEBUGFS
1842 .get_et_sset_count = ath9k_htc_get_et_sset_count,
1843 .get_et_stats = ath9k_htc_get_et_stats,
1844 .get_et_strings = ath9k_htc_get_et_strings,
1845#endif
1802}; 1846};
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 5324c3346af8..4ca0cb060106 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -2599,7 +2599,7 @@ int ath9k_hw_fill_cap_info(struct ath_hw *ah)
2599 if (!(ah->ent_mode & AR_ENT_OTP_49GHZ_DISABLE)) 2599 if (!(ah->ent_mode & AR_ENT_OTP_49GHZ_DISABLE))
2600 pCap->hw_caps |= ATH9K_HW_CAP_MCI; 2600 pCap->hw_caps |= ATH9K_HW_CAP_MCI;
2601 2601
2602 if (AR_SREV_9462_20(ah)) 2602 if (AR_SREV_9462_20_OR_LATER(ah))
2603 pCap->hw_caps |= ATH9K_HW_CAP_RTT; 2603 pCap->hw_caps |= ATH9K_HW_CAP_RTT;
2604 } 2604 }
2605 2605
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 1e555d899469..16f8b201642b 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -837,6 +837,7 @@ void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
837 837
838#ifdef CONFIG_PM_SLEEP 838#ifdef CONFIG_PM_SLEEP
839 if ((ah->caps.hw_caps & ATH9K_HW_WOW_DEVICE_CAPABLE) && 839 if ((ah->caps.hw_caps & ATH9K_HW_WOW_DEVICE_CAPABLE) &&
840 (sc->driver_data & ATH9K_PCI_WOW) &&
840 device_can_wakeup(sc->dev)) 841 device_can_wakeup(sc->dev))
841 hw->wiphy->wowlan = &ath9k_wowlan_support; 842 hw->wiphy->wowlan = &ath9k_wowlan_support;
842 843
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index b096bb2c28c8..c585c9b35973 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -79,6 +79,63 @@ static DEFINE_PCI_DEVICE_TABLE(ath_pci_id_table) = {
79 0x6661), 79 0x6661),
80 .driver_data = ATH9K_PCI_CUS217 }, 80 .driver_data = ATH9K_PCI_CUS217 },
81 81
82 /* AR9462 with WoW support */
83 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
84 0x0034,
85 PCI_VENDOR_ID_ATHEROS,
86 0x3117),
87 .driver_data = ATH9K_PCI_WOW },
88 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
89 0x0034,
90 PCI_VENDOR_ID_LENOVO,
91 0x3214),
92 .driver_data = ATH9K_PCI_WOW },
93 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
94 0x0034,
95 PCI_VENDOR_ID_ATTANSIC,
96 0x0091),
97 .driver_data = ATH9K_PCI_WOW },
98 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
99 0x0034,
100 PCI_VENDOR_ID_AZWAVE,
101 0x2110),
102 .driver_data = ATH9K_PCI_WOW },
103 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
104 0x0034,
105 PCI_VENDOR_ID_ASUSTEK,
106 0x850E),
107 .driver_data = ATH9K_PCI_WOW },
108 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
109 0x0034,
110 0x11AD, /* LITEON */
111 0x6631),
112 .driver_data = ATH9K_PCI_WOW },
113 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
114 0x0034,
115 0x11AD, /* LITEON */
116 0x6641),
117 .driver_data = ATH9K_PCI_WOW },
118 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
119 0x0034,
120 PCI_VENDOR_ID_HP,
121 0x1864),
122 .driver_data = ATH9K_PCI_WOW },
123 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
124 0x0034,
125 0x14CD, /* USI */
126 0x0063),
127 .driver_data = ATH9K_PCI_WOW },
128 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
129 0x0034,
130 0x14CD, /* USI */
131 0x0064),
132 .driver_data = ATH9K_PCI_WOW },
133 { PCI_DEVICE_SUB(PCI_VENDOR_ID_ATHEROS,
134 0x0034,
135 0x10CF, /* Fujitsu */
136 0x1783),
137 .driver_data = ATH9K_PCI_WOW },
138
82 { PCI_VDEVICE(ATHEROS, 0x0034) }, /* PCI-E AR9462 */ 139 { PCI_VDEVICE(ATHEROS, 0x0034) }, /* PCI-E AR9462 */
83 { PCI_VDEVICE(ATHEROS, 0x0037) }, /* PCI-E AR1111/AR9485 */ 140 { PCI_VDEVICE(ATHEROS, 0x0037) }, /* PCI-E AR1111/AR9485 */
84 { PCI_VDEVICE(ATHEROS, 0x0036) }, /* PCI-E AR9565 */ 141 { PCI_VDEVICE(ATHEROS, 0x0036) }, /* PCI-E AR9565 */
diff --git a/drivers/net/wireless/ath/ath9k/reg.h b/drivers/net/wireless/ath/ath9k/reg.h
index f7c90cc58d56..5af97442ac37 100644
--- a/drivers/net/wireless/ath/ath9k/reg.h
+++ b/drivers/net/wireless/ath/ath9k/reg.h
@@ -806,6 +806,7 @@
806#define AR_SREV_REVISION_9580_10 4 /* AR9580 1.0 */ 806#define AR_SREV_REVISION_9580_10 4 /* AR9580 1.0 */
807#define AR_SREV_VERSION_9462 0x280 807#define AR_SREV_VERSION_9462 0x280
808#define AR_SREV_REVISION_9462_20 2 808#define AR_SREV_REVISION_9462_20 2
809#define AR_SREV_REVISION_9462_21 3
809#define AR_SREV_VERSION_9565 0x2C0 810#define AR_SREV_VERSION_9565 0x2C0
810#define AR_SREV_REVISION_9565_10 0 811#define AR_SREV_REVISION_9565_10 0
811#define AR_SREV_VERSION_9550 0x400 812#define AR_SREV_VERSION_9550 0x400
@@ -911,10 +912,18 @@
911 912
912#define AR_SREV_9462(_ah) \ 913#define AR_SREV_9462(_ah) \
913 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462)) 914 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462))
914
915#define AR_SREV_9462_20(_ah) \ 915#define AR_SREV_9462_20(_ah) \
916 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \ 916 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \
917 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9462_20)) 917 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9462_20))
918#define AR_SREV_9462_21(_ah) \
919 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \
920 ((_ah)->hw_version.macRev == AR_SREV_REVISION_9462_21))
921#define AR_SREV_9462_20_OR_LATER(_ah) \
922 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \
923 ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9462_20))
924#define AR_SREV_9462_21_OR_LATER(_ah) \
925 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9462) && \
926 ((_ah)->hw_version.macRev >= AR_SREV_REVISION_9462_21))
918 927
919#define AR_SREV_9565(_ah) \ 928#define AR_SREV_9565(_ah) \
920 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565)) 929 (((_ah)->hw_version.macVersion == AR_SREV_VERSION_9565))
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 7e19d9b5214e..c59ae43b9b35 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -1673,6 +1673,8 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
1673 txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) 1673 txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH)
1674 return; 1674 return;
1675 1675
1676 rcu_read_lock();
1677
1676 ac = list_first_entry(&txq->axq_acq, struct ath_atx_ac, list); 1678 ac = list_first_entry(&txq->axq_acq, struct ath_atx_ac, list);
1677 last_ac = list_entry(txq->axq_acq.prev, struct ath_atx_ac, list); 1679 last_ac = list_entry(txq->axq_acq.prev, struct ath_atx_ac, list);
1678 1680
@@ -1711,8 +1713,10 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq)
1711 1713
1712 if (ac == last_ac || 1714 if (ac == last_ac ||
1713 txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH) 1715 txq->axq_ampdu_depth >= ATH_AGGR_MIN_QDEPTH)
1714 return; 1716 break;
1715 } 1717 }
1718
1719 rcu_read_unlock();
1716} 1720}
1717 1721
1718/***********/ 1722/***********/
@@ -1778,9 +1782,13 @@ static void ath_tx_txqaddbuf(struct ath_softc *sc, struct ath_txq *txq,
1778 } 1782 }
1779 1783
1780 if (!internal) { 1784 if (!internal) {
1781 txq->axq_depth++; 1785 while (bf) {
1782 if (bf_is_ampdu_not_probing(bf)) 1786 txq->axq_depth++;
1783 txq->axq_ampdu_depth++; 1787 if (bf_is_ampdu_not_probing(bf))
1788 txq->axq_ampdu_depth++;
1789
1790 bf = bf->bf_lastbf->bf_next;
1791 }
1784 } 1792 }
1785} 1793}
1786 1794
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index e1c492b9dfef..d240b24e1ccf 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -621,7 +621,8 @@ static struct vring *wil_find_tx_vring(struct wil6210_priv *wil,
621 return NULL; 621 return NULL;
622} 622}
623 623
624static int wil_tx_desc_map(struct vring_tx_desc *d, dma_addr_t pa, u32 len) 624static int wil_tx_desc_map(struct vring_tx_desc *d, dma_addr_t pa, u32 len,
625 int vring_index)
625{ 626{
626 wil_desc_addr_set(&d->dma.addr, pa); 627 wil_desc_addr_set(&d->dma.addr, pa);
627 d->dma.ip_length = 0; 628 d->dma.ip_length = 0;
@@ -630,7 +631,7 @@ static int wil_tx_desc_map(struct vring_tx_desc *d, dma_addr_t pa, u32 len)
630 d->dma.error = 0; 631 d->dma.error = 0;
631 d->dma.status = 0; /* BIT(0) should be 0 for HW_OWNED */ 632 d->dma.status = 0; /* BIT(0) should be 0 for HW_OWNED */
632 d->dma.length = cpu_to_le16((u16)len); 633 d->dma.length = cpu_to_le16((u16)len);
633 d->dma.d0 = 0; 634 d->dma.d0 = (vring_index << DMA_CFG_DESC_TX_0_QID_POS);
634 d->mac.d[0] = 0; 635 d->mac.d[0] = 0;
635 d->mac.d[1] = 0; 636 d->mac.d[1] = 0;
636 d->mac.d[2] = 0; 637 d->mac.d[2] = 0;
@@ -684,7 +685,7 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
684 if (unlikely(dma_mapping_error(dev, pa))) 685 if (unlikely(dma_mapping_error(dev, pa)))
685 return -EINVAL; 686 return -EINVAL;
686 /* 1-st segment */ 687 /* 1-st segment */
687 wil_tx_desc_map(d, pa, skb_headlen(skb)); 688 wil_tx_desc_map(d, pa, skb_headlen(skb), vring_index);
688 d->mac.d[2] |= ((nr_frags + 1) << 689 d->mac.d[2] |= ((nr_frags + 1) <<
689 MAC_CFG_DESC_TX_2_NUM_OF_DESCRIPTORS_POS); 690 MAC_CFG_DESC_TX_2_NUM_OF_DESCRIPTORS_POS);
690 if (nr_frags) 691 if (nr_frags)
@@ -701,15 +702,14 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
701 DMA_TO_DEVICE); 702 DMA_TO_DEVICE);
702 if (unlikely(dma_mapping_error(dev, pa))) 703 if (unlikely(dma_mapping_error(dev, pa)))
703 goto dma_error; 704 goto dma_error;
704 wil_tx_desc_map(d, pa, len); 705 wil_tx_desc_map(d, pa, len, vring_index);
705 vring->ctx[i] = NULL; 706 vring->ctx[i] = NULL;
706 *_d = *d; 707 *_d = *d;
707 } 708 }
708 /* for the last seg only */ 709 /* for the last seg only */
709 d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_EOP_POS); 710 d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_EOP_POS);
710 d->dma.d0 |= BIT(9); /* BUG: undocumented bit */ 711 d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_MARK_WB_POS);
711 d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_DMA_IT_POS); 712 d->dma.d0 |= BIT(DMA_CFG_DESC_TX_0_CMD_DMA_IT_POS);
712 d->dma.d0 |= (vring_index << DMA_CFG_DESC_TX_0_QID_POS);
713 *_d = *d; 713 *_d = *d;
714 714
715 wil_hex_dump_txrx("Tx ", DUMP_PREFIX_NONE, 32, 4, 715 wil_hex_dump_txrx("Tx ", DUMP_PREFIX_NONE, 32, 4,
diff --git a/drivers/net/wireless/ath/wil6210/txrx.h b/drivers/net/wireless/ath/wil6210/txrx.h
index 23c0781cdb93..859aea68a1fa 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.h
+++ b/drivers/net/wireless/ath/wil6210/txrx.h
@@ -201,6 +201,10 @@ struct vring_tx_mac {
201#define DMA_CFG_DESC_TX_0_CMD_EOP_LEN 1 201#define DMA_CFG_DESC_TX_0_CMD_EOP_LEN 1
202#define DMA_CFG_DESC_TX_0_CMD_EOP_MSK 0x100 202#define DMA_CFG_DESC_TX_0_CMD_EOP_MSK 0x100
203 203
204#define DMA_CFG_DESC_TX_0_CMD_MARK_WB_POS 9
205#define DMA_CFG_DESC_TX_0_CMD_MARK_WB_LEN 1
206#define DMA_CFG_DESC_TX_0_CMD_MARK_WB_MSK 0x200
207
204#define DMA_CFG_DESC_TX_0_CMD_DMA_IT_POS 10 208#define DMA_CFG_DESC_TX_0_CMD_DMA_IT_POS 10
205#define DMA_CFG_DESC_TX_0_CMD_DMA_IT_LEN 1 209#define DMA_CFG_DESC_TX_0_CMD_DMA_IT_LEN 1
206#define DMA_CFG_DESC_TX_0_CMD_DMA_IT_MSK 0x400 210#define DMA_CFG_DESC_TX_0_CMD_DMA_IT_MSK 0x400
diff --git a/drivers/net/wireless/b43/Kconfig b/drivers/net/wireless/b43/Kconfig
index 3f21e0ba39ba..51ff0b198d0a 100644
--- a/drivers/net/wireless/b43/Kconfig
+++ b/drivers/net/wireless/b43/Kconfig
@@ -31,12 +31,6 @@ config B43_BCMA
31 depends on B43 && (BCMA = y || BCMA = B43) 31 depends on B43 && (BCMA = y || BCMA = B43)
32 default y 32 default y
33 33
34config B43_BCMA_EXTRA
35 bool "Hardware support that overlaps with the brcmsmac driver"
36 depends on B43_BCMA
37 default n if BRCMSMAC
38 default y
39
40config B43_SSB 34config B43_SSB
41 bool 35 bool
42 depends on B43 && (SSB = y || SSB = B43) 36 depends on B43 && (SSB = y || SSB = B43)
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index a95b77ab360e..0e933bb71543 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -113,13 +113,15 @@ static int b43_modparam_pio = 0;
113module_param_named(pio, b43_modparam_pio, int, 0644); 113module_param_named(pio, b43_modparam_pio, int, 0644);
114MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO"); 114MODULE_PARM_DESC(pio, "Use PIO accesses by default: 0=DMA, 1=PIO");
115 115
116static int modparam_allhwsupport = !IS_ENABLED(CONFIG_BRCMSMAC);
117module_param_named(allhwsupport, modparam_allhwsupport, int, 0444);
118MODULE_PARM_DESC(allhwsupport, "Enable support for all hardware (even it if overlaps with the brcmsmac driver)");
119
116#ifdef CONFIG_B43_BCMA 120#ifdef CONFIG_B43_BCMA
117static const struct bcma_device_id b43_bcma_tbl[] = { 121static const struct bcma_device_id b43_bcma_tbl[] = {
118 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x11, BCMA_ANY_CLASS), 122 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x11, BCMA_ANY_CLASS),
119#ifdef CONFIG_B43_BCMA_EXTRA
120 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x17, BCMA_ANY_CLASS), 123 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x17, BCMA_ANY_CLASS),
121 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x18, BCMA_ANY_CLASS), 124 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x18, BCMA_ANY_CLASS),
122#endif
123 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x1D, BCMA_ANY_CLASS), 125 BCMA_CORE(BCMA_MANUF_BCM, BCMA_CORE_80211, 0x1D, BCMA_ANY_CLASS),
124 BCMA_CORETABLE_END 126 BCMA_CORETABLE_END
125}; 127};
@@ -5396,6 +5398,12 @@ static int b43_bcma_probe(struct bcma_device *core)
5396 struct b43_wl *wl; 5398 struct b43_wl *wl;
5397 int err; 5399 int err;
5398 5400
5401 if (!modparam_allhwsupport &&
5402 (core->id.rev == 0x17 || core->id.rev == 0x18)) {
5403 pr_err("Support for cores revisions 0x17 and 0x18 disabled by module param allhwsupport=0. Try b43.allhwsupport=1\n");
5404 return -ENOTSUPP;
5405 }
5406
5399 dev = b43_bus_dev_bcma_init(core); 5407 dev = b43_bus_dev_bcma_init(core);
5400 if (!dev) 5408 if (!dev)
5401 return -ENODEV; 5409 return -ENODEV;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index 3f8e69c29146..e3f3c48f86d4 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -162,7 +162,7 @@ int brcmf_sdio_intr_unregister(struct brcmf_sdio_dev *sdiodev)
162 return 0; 162 return 0;
163} 163}
164 164
165int 165static int
166brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address) 166brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address)
167{ 167{
168 int err = 0, i; 168 int err = 0, i;
@@ -193,12 +193,33 @@ brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev, u32 address)
193 return err; 193 return err;
194} 194}
195 195
196static int
197brcmf_sdio_addrprep(struct brcmf_sdio_dev *sdiodev, uint width, u32 *addr)
198{
199 uint bar0 = *addr & ~SBSDIO_SB_OFT_ADDR_MASK;
200 int err = 0;
201
202 if (bar0 != sdiodev->sbwad) {
203 err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0);
204 if (err)
205 return err;
206
207 sdiodev->sbwad = bar0;
208 }
209
210 *addr &= SBSDIO_SB_OFT_ADDR_MASK;
211
212 if (width == 4)
213 *addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
214
215 return 0;
216}
217
196int 218int
197brcmf_sdio_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr, 219brcmf_sdio_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
198 void *data, bool write) 220 void *data, bool write)
199{ 221{
200 u8 func_num, reg_size; 222 u8 func_num, reg_size;
201 u32 bar;
202 s32 retry = 0; 223 s32 retry = 0;
203 int ret; 224 int ret;
204 225
@@ -218,18 +239,7 @@ brcmf_sdio_regrw_helper(struct brcmf_sdio_dev *sdiodev, u32 addr,
218 func_num = SDIO_FUNC_1; 239 func_num = SDIO_FUNC_1;
219 reg_size = 4; 240 reg_size = 4;
220 241
221 /* Set the window for SB core register */ 242 brcmf_sdio_addrprep(sdiodev, reg_size, &addr);
222 bar = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
223 if (bar != sdiodev->sbwad) {
224 ret = brcmf_sdcard_set_sbaddr_window(sdiodev, bar);
225 if (ret != 0) {
226 memset(data, 0xFF, reg_size);
227 return ret;
228 }
229 sdiodev->sbwad = bar;
230 }
231 addr &= SBSDIO_SB_OFT_ADDR_MASK;
232 addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
233 } 243 }
234 244
235 do { 245 do {
@@ -321,10 +331,11 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
321 bool write, u32 addr, struct sk_buff_head *pktlist) 331 bool write, u32 addr, struct sk_buff_head *pktlist)
322{ 332{
323 unsigned int req_sz, func_blk_sz, sg_cnt, sg_data_sz, pkt_offset; 333 unsigned int req_sz, func_blk_sz, sg_cnt, sg_data_sz, pkt_offset;
324 unsigned int max_blks, max_req_sz; 334 unsigned int max_blks, max_req_sz, orig_offset, dst_offset;
325 unsigned short max_seg_sz, seg_sz; 335 unsigned short max_seg_sz, seg_sz;
326 unsigned char *pkt_data; 336 unsigned char *pkt_data, *orig_data, *dst_data;
327 struct sk_buff *pkt_next = NULL; 337 struct sk_buff *pkt_next = NULL, *local_pkt_next;
338 struct sk_buff_head local_list, *target_list;
328 struct mmc_request mmc_req; 339 struct mmc_request mmc_req;
329 struct mmc_command mmc_cmd; 340 struct mmc_command mmc_cmd;
330 struct mmc_data mmc_dat; 341 struct mmc_data mmc_dat;
@@ -361,6 +372,32 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
361 req_sz); 372 req_sz);
362 } 373 }
363 374
375 target_list = pktlist;
376 /* for host with broken sg support, prepare a page aligned list */
377 __skb_queue_head_init(&local_list);
378 if (sdiodev->pdata && sdiodev->pdata->broken_sg_support && !write) {
379 req_sz = 0;
380 skb_queue_walk(pktlist, pkt_next)
381 req_sz += pkt_next->len;
382 req_sz = ALIGN(req_sz, sdiodev->func[fn]->cur_blksize);
383 while (req_sz > PAGE_SIZE) {
384 pkt_next = brcmu_pkt_buf_get_skb(PAGE_SIZE);
385 if (pkt_next == NULL) {
386 ret = -ENOMEM;
387 goto exit;
388 }
389 __skb_queue_tail(&local_list, pkt_next);
390 req_sz -= PAGE_SIZE;
391 }
392 pkt_next = brcmu_pkt_buf_get_skb(req_sz);
393 if (pkt_next == NULL) {
394 ret = -ENOMEM;
395 goto exit;
396 }
397 __skb_queue_tail(&local_list, pkt_next);
398 target_list = &local_list;
399 }
400
364 host = sdiodev->func[fn]->card->host; 401 host = sdiodev->func[fn]->card->host;
365 func_blk_sz = sdiodev->func[fn]->cur_blksize; 402 func_blk_sz = sdiodev->func[fn]->cur_blksize;
366 /* Blocks per command is limited by host count, host transfer 403 /* Blocks per command is limited by host count, host transfer
@@ -370,13 +407,15 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
370 max_req_sz = min_t(unsigned int, host->max_req_size, 407 max_req_sz = min_t(unsigned int, host->max_req_size,
371 max_blks * func_blk_sz); 408 max_blks * func_blk_sz);
372 max_seg_sz = min_t(unsigned short, host->max_segs, SG_MAX_SINGLE_ALLOC); 409 max_seg_sz = min_t(unsigned short, host->max_segs, SG_MAX_SINGLE_ALLOC);
373 max_seg_sz = min_t(unsigned short, max_seg_sz, pktlist->qlen); 410 max_seg_sz = min_t(unsigned short, max_seg_sz, target_list->qlen);
374 seg_sz = pktlist->qlen; 411 seg_sz = target_list->qlen;
375 pkt_offset = 0; 412 pkt_offset = 0;
376 pkt_next = pktlist->next; 413 pkt_next = target_list->next;
377 414
378 if (sg_alloc_table(&st, max_seg_sz, GFP_KERNEL)) 415 if (sg_alloc_table(&st, max_seg_sz, GFP_KERNEL)) {
379 return -ENOMEM; 416 ret = -ENOMEM;
417 goto exit;
418 }
380 419
381 while (seg_sz) { 420 while (seg_sz) {
382 req_sz = 0; 421 req_sz = 0;
@@ -386,7 +425,7 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
386 memset(&mmc_dat, 0, sizeof(struct mmc_data)); 425 memset(&mmc_dat, 0, sizeof(struct mmc_data));
387 sgl = st.sgl; 426 sgl = st.sgl;
388 /* prep sg table */ 427 /* prep sg table */
389 while (pkt_next != (struct sk_buff *)pktlist) { 428 while (pkt_next != (struct sk_buff *)target_list) {
390 pkt_data = pkt_next->data + pkt_offset; 429 pkt_data = pkt_next->data + pkt_offset;
391 sg_data_sz = pkt_next->len - pkt_offset; 430 sg_data_sz = pkt_next->len - pkt_offset;
392 if (sg_data_sz > host->max_seg_size) 431 if (sg_data_sz > host->max_seg_size)
@@ -413,8 +452,8 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
413 if (req_sz % func_blk_sz != 0) { 452 if (req_sz % func_blk_sz != 0) {
414 brcmf_err("sg request length %u is not %u aligned\n", 453 brcmf_err("sg request length %u is not %u aligned\n",
415 req_sz, func_blk_sz); 454 req_sz, func_blk_sz);
416 sg_free_table(&st); 455 ret = -ENOTBLK;
417 return -ENOTBLK; 456 goto exit;
418 } 457 }
419 mmc_dat.sg = st.sgl; 458 mmc_dat.sg = st.sgl;
420 mmc_dat.sg_len = sg_cnt; 459 mmc_dat.sg_len = sg_cnt;
@@ -447,35 +486,36 @@ static int brcmf_sdio_buffrw(struct brcmf_sdio_dev *sdiodev, uint fn,
447 } 486 }
448 } 487 }
449 488
450 sg_free_table(&st); 489 if (sdiodev->pdata && sdiodev->pdata->broken_sg_support && !write) {
451 490 local_pkt_next = local_list.next;
452 return ret; 491 orig_offset = 0;
453} 492 skb_queue_walk(pktlist, pkt_next) {
454 493 dst_offset = 0;
455static int brcmf_sdcard_recv_prepare(struct brcmf_sdio_dev *sdiodev, uint fn, 494 do {
456 uint flags, uint width, u32 *addr) 495 req_sz = local_pkt_next->len - orig_offset;
457{ 496 req_sz = min_t(uint, pkt_next->len - dst_offset,
458 uint bar0 = *addr & ~SBSDIO_SB_OFT_ADDR_MASK; 497 req_sz);
459 int err = 0; 498 orig_data = local_pkt_next->data + orig_offset;
460 499 dst_data = pkt_next->data + dst_offset;
461 /* Async not implemented yet */ 500 memcpy(dst_data, orig_data, req_sz);
462 if (flags & SDIO_REQ_ASYNC) 501 orig_offset += req_sz;
463 return -ENOTSUPP; 502 dst_offset += req_sz;
464 503 if (orig_offset == local_pkt_next->len) {
465 if (bar0 != sdiodev->sbwad) { 504 orig_offset = 0;
466 err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0); 505 local_pkt_next = local_pkt_next->next;
467 if (err) 506 }
468 return err; 507 if (dst_offset == pkt_next->len)
469 508 break;
470 sdiodev->sbwad = bar0; 509 } while (!skb_queue_empty(&local_list));
510 }
471 } 511 }
472 512
473 *addr &= SBSDIO_SB_OFT_ADDR_MASK; 513exit:
474 514 sg_free_table(&st);
475 if (width == 4) 515 while ((pkt_next = __skb_dequeue(&local_list)) != NULL)
476 *addr |= SBSDIO_SB_ACCESS_2_4B_FLAG; 516 brcmu_pkt_buf_free_skb(pkt_next);
477 517
478 return 0; 518 return ret;
479} 519}
480 520
481int 521int
@@ -512,7 +552,7 @@ brcmf_sdcard_recv_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
512 fn, addr, pkt->len); 552 fn, addr, pkt->len);
513 553
514 width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; 554 width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
515 err = brcmf_sdcard_recv_prepare(sdiodev, fn, flags, width, &addr); 555 err = brcmf_sdio_addrprep(sdiodev, width, &addr);
516 if (err) 556 if (err)
517 goto done; 557 goto done;
518 558
@@ -536,7 +576,7 @@ int brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
536 fn, addr, pktq->qlen); 576 fn, addr, pktq->qlen);
537 577
538 width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; 578 width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
539 err = brcmf_sdcard_recv_prepare(sdiodev, fn, flags, width, &addr); 579 err = brcmf_sdio_addrprep(sdiodev, width, &addr);
540 if (err) 580 if (err)
541 goto done; 581 goto done;
542 582
@@ -574,37 +614,20 @@ brcmf_sdcard_send_pkt(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
574 uint flags, struct sk_buff *pkt) 614 uint flags, struct sk_buff *pkt)
575{ 615{
576 uint width; 616 uint width;
577 uint bar0 = addr & ~SBSDIO_SB_OFT_ADDR_MASK;
578 int err = 0; 617 int err = 0;
579 struct sk_buff_head pkt_list; 618 struct sk_buff_head pkt_list;
580 619
581 brcmf_dbg(SDIO, "fun = %d, addr = 0x%x, size = %d\n", 620 brcmf_dbg(SDIO, "fun = %d, addr = 0x%x, size = %d\n",
582 fn, addr, pkt->len); 621 fn, addr, pkt->len);
583 622
584 /* Async not implemented yet */
585 if (flags & SDIO_REQ_ASYNC)
586 return -ENOTSUPP;
587
588 if (bar0 != sdiodev->sbwad) {
589 err = brcmf_sdcard_set_sbaddr_window(sdiodev, bar0);
590 if (err)
591 goto done;
592
593 sdiodev->sbwad = bar0;
594 }
595
596 addr &= SBSDIO_SB_OFT_ADDR_MASK;
597
598 width = (flags & SDIO_REQ_4BYTE) ? 4 : 2; 623 width = (flags & SDIO_REQ_4BYTE) ? 4 : 2;
599 if (width == 4) 624 brcmf_sdio_addrprep(sdiodev, width, &addr);
600 addr |= SBSDIO_SB_ACCESS_2_4B_FLAG;
601 625
602 skb_queue_head_init(&pkt_list); 626 skb_queue_head_init(&pkt_list);
603 skb_queue_tail(&pkt_list, pkt); 627 skb_queue_tail(&pkt_list, pkt);
604 err = brcmf_sdio_buffrw(sdiodev, fn, true, addr, &pkt_list); 628 err = brcmf_sdio_buffrw(sdiodev, fn, true, addr, &pkt_list);
605 skb_dequeue_tail(&pkt_list); 629 skb_dequeue_tail(&pkt_list);
606 630
607done:
608 return err; 631 return err;
609} 632}
610 633
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
index 8c402e7b97eb..8e8975562ec3 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/dhd_linux.c
@@ -281,8 +281,6 @@ void brcmf_txflowblock(struct device *dev, bool state)
281 281
282void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list) 282void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list)
283{ 283{
284 unsigned char *eth;
285 uint len;
286 struct sk_buff *skb, *pnext; 284 struct sk_buff *skb, *pnext;
287 struct brcmf_if *ifp; 285 struct brcmf_if *ifp;
288 struct brcmf_bus *bus_if = dev_get_drvdata(dev); 286 struct brcmf_bus *bus_if = dev_get_drvdata(dev);
@@ -306,33 +304,12 @@ void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list)
306 continue; 304 continue;
307 } 305 }
308 306
309 /* Get the protocol, maintain skb around eth_type_trans()
310 * The main reason for this hack is for the limitation of
311 * Linux 2.4 where 'eth_type_trans' uses the
312 * 'net->hard_header_len'
313 * to perform skb_pull inside vs ETH_HLEN. Since to avoid
314 * coping of the packet coming from the network stack to add
315 * BDC, Hardware header etc, during network interface
316 * registration
317 * we set the 'net->hard_header_len' to ETH_HLEN + extra space
318 * required
319 * for BDC, Hardware header etc. and not just the ETH_HLEN
320 */
321 eth = skb->data;
322 len = skb->len;
323
324 skb->dev = ifp->ndev; 307 skb->dev = ifp->ndev;
325 skb->protocol = eth_type_trans(skb, skb->dev); 308 skb->protocol = eth_type_trans(skb, skb->dev);
326 309
327 if (skb->pkt_type == PACKET_MULTICAST) 310 if (skb->pkt_type == PACKET_MULTICAST)
328 ifp->stats.multicast++; 311 ifp->stats.multicast++;
329 312
330 skb->data = eth;
331 skb->len = len;
332
333 /* Strip header, count, deliver upward */
334 skb_pull(skb, ETH_HLEN);
335
336 /* Process special event packets */ 313 /* Process special event packets */
337 brcmf_fweh_process_skb(drvr, skb); 314 brcmf_fweh_process_skb(drvr, skb);
338 315
@@ -348,10 +325,8 @@ void brcmf_rx_frames(struct device *dev, struct sk_buff_head *skb_list)
348 netif_rx(skb); 325 netif_rx(skb);
349 else 326 else
350 /* If the receive is not processed inside an ISR, 327 /* If the receive is not processed inside an ISR,
351 * the softirqd must be woken explicitly to service 328 * the softirqd must be woken explicitly to service the
352 * the NET_RX_SOFTIRQ. In 2.6 kernels, this is handled 329 * NET_RX_SOFTIRQ. This is handled by netif_rx_ni().
353 * by netif_rx_ni(), but in earlier kernels, we need
354 * to do it manually.
355 */ 330 */
356 netif_rx_ni(skb); 331 netif_rx_ni(skb);
357 } 332 }
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
index 13e75c4b1a6b..f0d9f7f6c83d 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/fwsignal.c
@@ -796,9 +796,8 @@ static int brcmf_fws_hdrpush(struct brcmf_fws_info *fws, struct sk_buff *skb)
796 u8 fillers; 796 u8 fillers;
797 __le32 pkttag = cpu_to_le32(brcmf_skbcb(skb)->htod); 797 __le32 pkttag = cpu_to_le32(brcmf_skbcb(skb)->htod);
798 798
799 brcmf_dbg(TRACE, "enter: ea=%pM, ifidx=%u (%u), pkttag=0x%08X, hslot=%d\n", 799 brcmf_dbg(TRACE, "enter: %s, idx=%d pkttag=0x%08X, hslot=%d\n",
800 entry->ea, entry->interface_id, 800 entry->name, brcmf_skb_if_flags_get_field(skb, INDEX),
801 brcmf_skb_if_flags_get_field(skb, INDEX),
802 le32_to_cpu(pkttag), (le32_to_cpu(pkttag) >> 8) & 0xffff); 801 le32_to_cpu(pkttag), (le32_to_cpu(pkttag) >> 8) & 0xffff);
803 if (entry->send_tim_signal) 802 if (entry->send_tim_signal)
804 data_offset += 2 + BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN; 803 data_offset += 2 + BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN;
@@ -822,8 +821,8 @@ static int brcmf_fws_hdrpush(struct brcmf_fws_info *fws, struct sk_buff *skb)
822 wlh[1] = BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN; 821 wlh[1] = BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN;
823 wlh[2] = entry->mac_handle; 822 wlh[2] = entry->mac_handle;
824 wlh[3] = entry->traffic_pending_bmp; 823 wlh[3] = entry->traffic_pending_bmp;
825 brcmf_dbg(TRACE, "adding TIM info: %02X:%02X:%02X:%02X\n", 824 brcmf_dbg(TRACE, "adding TIM info: handle %d bmp 0x%X\n",
826 wlh[0], wlh[1], wlh[2], wlh[3]); 825 entry->mac_handle, entry->traffic_pending_bmp);
827 wlh += BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN + 2; 826 wlh += BRCMF_FWS_TYPE_PENDING_TRAFFIC_BMP_LEN + 2;
828 entry->traffic_lastreported_bmp = entry->traffic_pending_bmp; 827 entry->traffic_lastreported_bmp = entry->traffic_pending_bmp;
829 } 828 }
@@ -906,10 +905,26 @@ static int brcmf_fws_rssi_indicate(struct brcmf_fws_info *fws, s8 rssi)
906 return 0; 905 return 0;
907} 906}
908 907
908/* using macro so sparse checking does not complain
909 * about locking imbalance.
910 */
911#define brcmf_fws_lock(drvr, flags) \
912do { \
913 flags = 0; \
914 spin_lock_irqsave(&((drvr)->fws_spinlock), (flags)); \
915} while (0)
916
917/* using macro so sparse checking does not complain
918 * about locking imbalance.
919 */
920#define brcmf_fws_unlock(drvr, flags) \
921 spin_unlock_irqrestore(&((drvr)->fws_spinlock), (flags))
922
909static 923static
910int brcmf_fws_macdesc_indicate(struct brcmf_fws_info *fws, u8 type, u8 *data) 924int brcmf_fws_macdesc_indicate(struct brcmf_fws_info *fws, u8 type, u8 *data)
911{ 925{
912 struct brcmf_fws_mac_descriptor *entry, *existing; 926 struct brcmf_fws_mac_descriptor *entry, *existing;
927 ulong flags;
913 u8 mac_handle; 928 u8 mac_handle;
914 u8 ifidx; 929 u8 ifidx;
915 u8 *addr; 930 u8 *addr;
@@ -923,8 +938,10 @@ int brcmf_fws_macdesc_indicate(struct brcmf_fws_info *fws, u8 type, u8 *data)
923 if (entry->occupied) { 938 if (entry->occupied) {
924 brcmf_dbg(TRACE, "deleting %s mac %pM\n", 939 brcmf_dbg(TRACE, "deleting %s mac %pM\n",
925 entry->name, addr); 940 entry->name, addr);
941 brcmf_fws_lock(fws->drvr, flags);
926 brcmf_fws_macdesc_cleanup(fws, entry, -1); 942 brcmf_fws_macdesc_cleanup(fws, entry, -1);
927 brcmf_fws_macdesc_deinit(entry); 943 brcmf_fws_macdesc_deinit(entry);
944 brcmf_fws_unlock(fws->drvr, flags);
928 } else 945 } else
929 fws->stats.mac_update_failed++; 946 fws->stats.mac_update_failed++;
930 return 0; 947 return 0;
@@ -933,11 +950,13 @@ int brcmf_fws_macdesc_indicate(struct brcmf_fws_info *fws, u8 type, u8 *data)
933 existing = brcmf_fws_macdesc_lookup(fws, addr); 950 existing = brcmf_fws_macdesc_lookup(fws, addr);
934 if (IS_ERR(existing)) { 951 if (IS_ERR(existing)) {
935 if (!entry->occupied) { 952 if (!entry->occupied) {
953 brcmf_fws_lock(fws->drvr, flags);
936 entry->mac_handle = mac_handle; 954 entry->mac_handle = mac_handle;
937 brcmf_fws_macdesc_init(entry, addr, ifidx); 955 brcmf_fws_macdesc_init(entry, addr, ifidx);
938 brcmf_fws_macdesc_set_name(fws, entry); 956 brcmf_fws_macdesc_set_name(fws, entry);
939 brcmu_pktq_init(&entry->psq, BRCMF_FWS_PSQ_PREC_COUNT, 957 brcmu_pktq_init(&entry->psq, BRCMF_FWS_PSQ_PREC_COUNT,
940 BRCMF_FWS_PSQ_LEN); 958 BRCMF_FWS_PSQ_LEN);
959 brcmf_fws_unlock(fws->drvr, flags);
941 brcmf_dbg(TRACE, "add %s mac %pM\n", entry->name, addr); 960 brcmf_dbg(TRACE, "add %s mac %pM\n", entry->name, addr);
942 } else { 961 } else {
943 fws->stats.mac_update_failed++; 962 fws->stats.mac_update_failed++;
@@ -945,11 +964,13 @@ int brcmf_fws_macdesc_indicate(struct brcmf_fws_info *fws, u8 type, u8 *data)
945 } else { 964 } else {
946 if (entry != existing) { 965 if (entry != existing) {
947 brcmf_dbg(TRACE, "copy mac %s\n", existing->name); 966 brcmf_dbg(TRACE, "copy mac %s\n", existing->name);
967 brcmf_fws_lock(fws->drvr, flags);
948 memcpy(entry, existing, 968 memcpy(entry, existing,
949 offsetof(struct brcmf_fws_mac_descriptor, psq)); 969 offsetof(struct brcmf_fws_mac_descriptor, psq));
950 entry->mac_handle = mac_handle; 970 entry->mac_handle = mac_handle;
951 brcmf_fws_macdesc_deinit(existing); 971 brcmf_fws_macdesc_deinit(existing);
952 brcmf_fws_macdesc_set_name(fws, entry); 972 brcmf_fws_macdesc_set_name(fws, entry);
973 brcmf_fws_unlock(fws->drvr, flags);
953 brcmf_dbg(TRACE, "relocate %s mac %pM\n", entry->name, 974 brcmf_dbg(TRACE, "relocate %s mac %pM\n", entry->name,
954 addr); 975 addr);
955 } else { 976 } else {
@@ -965,7 +986,9 @@ static int brcmf_fws_macdesc_state_indicate(struct brcmf_fws_info *fws,
965 u8 type, u8 *data) 986 u8 type, u8 *data)
966{ 987{
967 struct brcmf_fws_mac_descriptor *entry; 988 struct brcmf_fws_mac_descriptor *entry;
989 ulong flags;
968 u8 mac_handle; 990 u8 mac_handle;
991 int ret;
969 992
970 mac_handle = data[0]; 993 mac_handle = data[0];
971 entry = &fws->desc.nodes[mac_handle & 0x1F]; 994 entry = &fws->desc.nodes[mac_handle & 0x1F];
@@ -973,26 +996,30 @@ static int brcmf_fws_macdesc_state_indicate(struct brcmf_fws_info *fws,
973 fws->stats.mac_ps_update_failed++; 996 fws->stats.mac_ps_update_failed++;
974 return -ESRCH; 997 return -ESRCH;
975 } 998 }
999 brcmf_fws_lock(fws->drvr, flags);
976 /* a state update should wipe old credits */ 1000 /* a state update should wipe old credits */
977 entry->requested_credit = 0; 1001 entry->requested_credit = 0;
978 entry->requested_packet = 0; 1002 entry->requested_packet = 0;
979 if (type == BRCMF_FWS_TYPE_MAC_OPEN) { 1003 if (type == BRCMF_FWS_TYPE_MAC_OPEN) {
980 entry->state = BRCMF_FWS_STATE_OPEN; 1004 entry->state = BRCMF_FWS_STATE_OPEN;
981 return BRCMF_FWS_RET_OK_SCHEDULE; 1005 ret = BRCMF_FWS_RET_OK_SCHEDULE;
982 } else { 1006 } else {
983 entry->state = BRCMF_FWS_STATE_CLOSE; 1007 entry->state = BRCMF_FWS_STATE_CLOSE;
984 brcmf_fws_tim_update(fws, entry, BRCMF_FWS_FIFO_AC_BK, false); 1008 brcmf_fws_tim_update(fws, entry, BRCMF_FWS_FIFO_AC_BK, false);
985 brcmf_fws_tim_update(fws, entry, BRCMF_FWS_FIFO_AC_BE, false); 1009 brcmf_fws_tim_update(fws, entry, BRCMF_FWS_FIFO_AC_BE, false);
986 brcmf_fws_tim_update(fws, entry, BRCMF_FWS_FIFO_AC_VI, false); 1010 brcmf_fws_tim_update(fws, entry, BRCMF_FWS_FIFO_AC_VI, false);
987 brcmf_fws_tim_update(fws, entry, BRCMF_FWS_FIFO_AC_VO, true); 1011 brcmf_fws_tim_update(fws, entry, BRCMF_FWS_FIFO_AC_VO, true);
1012 ret = BRCMF_FWS_RET_OK_NOSCHEDULE;
988 } 1013 }
989 return BRCMF_FWS_RET_OK_NOSCHEDULE; 1014 brcmf_fws_unlock(fws->drvr, flags);
1015 return ret;
990} 1016}
991 1017
992static int brcmf_fws_interface_state_indicate(struct brcmf_fws_info *fws, 1018static int brcmf_fws_interface_state_indicate(struct brcmf_fws_info *fws,
993 u8 type, u8 *data) 1019 u8 type, u8 *data)
994{ 1020{
995 struct brcmf_fws_mac_descriptor *entry; 1021 struct brcmf_fws_mac_descriptor *entry;
1022 ulong flags;
996 u8 ifidx; 1023 u8 ifidx;
997 int ret; 1024 int ret;
998 1025
@@ -1011,17 +1038,24 @@ static int brcmf_fws_interface_state_indicate(struct brcmf_fws_info *fws,
1011 1038
1012 brcmf_dbg(TRACE, "%s (%d): %s\n", brcmf_fws_get_tlv_name(type), type, 1039 brcmf_dbg(TRACE, "%s (%d): %s\n", brcmf_fws_get_tlv_name(type), type,
1013 entry->name); 1040 entry->name);
1041 brcmf_fws_lock(fws->drvr, flags);
1014 switch (type) { 1042 switch (type) {
1015 case BRCMF_FWS_TYPE_INTERFACE_OPEN: 1043 case BRCMF_FWS_TYPE_INTERFACE_OPEN:
1016 entry->state = BRCMF_FWS_STATE_OPEN; 1044 entry->state = BRCMF_FWS_STATE_OPEN;
1017 return BRCMF_FWS_RET_OK_SCHEDULE; 1045 ret = BRCMF_FWS_RET_OK_SCHEDULE;
1046 break;
1018 case BRCMF_FWS_TYPE_INTERFACE_CLOSE: 1047 case BRCMF_FWS_TYPE_INTERFACE_CLOSE:
1019 entry->state = BRCMF_FWS_STATE_CLOSE; 1048 entry->state = BRCMF_FWS_STATE_CLOSE;
1020 return BRCMF_FWS_RET_OK_NOSCHEDULE; 1049 ret = BRCMF_FWS_RET_OK_NOSCHEDULE;
1050 break;
1021 default: 1051 default:
1022 ret = -EINVAL; 1052 ret = -EINVAL;
1023 break; 1053 brcmf_fws_unlock(fws->drvr, flags);
1054 goto fail;
1024 } 1055 }
1056 brcmf_fws_unlock(fws->drvr, flags);
1057 return ret;
1058
1025fail: 1059fail:
1026 fws->stats.if_update_failed++; 1060 fws->stats.if_update_failed++;
1027 return ret; 1061 return ret;
@@ -1031,6 +1065,7 @@ static int brcmf_fws_request_indicate(struct brcmf_fws_info *fws, u8 type,
1031 u8 *data) 1065 u8 *data)
1032{ 1066{
1033 struct brcmf_fws_mac_descriptor *entry; 1067 struct brcmf_fws_mac_descriptor *entry;
1068 ulong flags;
1034 1069
1035 entry = &fws->desc.nodes[data[1] & 0x1F]; 1070 entry = &fws->desc.nodes[data[1] & 0x1F];
1036 if (!entry->occupied) { 1071 if (!entry->occupied) {
@@ -1044,12 +1079,14 @@ static int brcmf_fws_request_indicate(struct brcmf_fws_info *fws, u8 type,
1044 brcmf_dbg(TRACE, "%s (%d): %s cnt %d bmp %d\n", 1079 brcmf_dbg(TRACE, "%s (%d): %s cnt %d bmp %d\n",
1045 brcmf_fws_get_tlv_name(type), type, entry->name, 1080 brcmf_fws_get_tlv_name(type), type, entry->name,
1046 data[0], data[2]); 1081 data[0], data[2]);
1082 brcmf_fws_lock(fws->drvr, flags);
1047 if (type == BRCMF_FWS_TYPE_MAC_REQUEST_CREDIT) 1083 if (type == BRCMF_FWS_TYPE_MAC_REQUEST_CREDIT)
1048 entry->requested_credit = data[0]; 1084 entry->requested_credit = data[0];
1049 else 1085 else
1050 entry->requested_packet = data[0]; 1086 entry->requested_packet = data[0];
1051 1087
1052 entry->ac_bitmap = data[2]; 1088 entry->ac_bitmap = data[2];
1089 brcmf_fws_unlock(fws->drvr, flags);
1053 return BRCMF_FWS_RET_OK_SCHEDULE; 1090 return BRCMF_FWS_RET_OK_SCHEDULE;
1054} 1091}
1055 1092
@@ -1346,6 +1383,7 @@ brcmf_fws_txs_process(struct brcmf_fws_info *fws, u8 flags, u32 hslot,
1346static int brcmf_fws_fifocreditback_indicate(struct brcmf_fws_info *fws, 1383static int brcmf_fws_fifocreditback_indicate(struct brcmf_fws_info *fws,
1347 u8 *data) 1384 u8 *data)
1348{ 1385{
1386 ulong flags;
1349 int i; 1387 int i;
1350 1388
1351 if (fws->fcmode != BRCMF_FWS_FCMODE_EXPLICIT_CREDIT) { 1389 if (fws->fcmode != BRCMF_FWS_FCMODE_EXPLICIT_CREDIT) {
@@ -1354,16 +1392,19 @@ static int brcmf_fws_fifocreditback_indicate(struct brcmf_fws_info *fws,
1354 } 1392 }
1355 1393
1356 brcmf_dbg(DATA, "enter: data %pM\n", data); 1394 brcmf_dbg(DATA, "enter: data %pM\n", data);
1395 brcmf_fws_lock(fws->drvr, flags);
1357 for (i = 0; i < BRCMF_FWS_FIFO_COUNT; i++) 1396 for (i = 0; i < BRCMF_FWS_FIFO_COUNT; i++)
1358 brcmf_fws_return_credits(fws, i, data[i]); 1397 brcmf_fws_return_credits(fws, i, data[i]);
1359 1398
1360 brcmf_dbg(DATA, "map: credit %x delay %x\n", fws->fifo_credit_map, 1399 brcmf_dbg(DATA, "map: credit %x delay %x\n", fws->fifo_credit_map,
1361 fws->fifo_delay_map); 1400 fws->fifo_delay_map);
1401 brcmf_fws_unlock(fws->drvr, flags);
1362 return BRCMF_FWS_RET_OK_SCHEDULE; 1402 return BRCMF_FWS_RET_OK_SCHEDULE;
1363} 1403}
1364 1404
1365static int brcmf_fws_txstatus_indicate(struct brcmf_fws_info *fws, u8 *data) 1405static int brcmf_fws_txstatus_indicate(struct brcmf_fws_info *fws, u8 *data)
1366{ 1406{
1407 ulong lflags;
1367 __le32 status_le; 1408 __le32 status_le;
1368 u32 status; 1409 u32 status;
1369 u32 hslot; 1410 u32 hslot;
@@ -1377,7 +1418,10 @@ static int brcmf_fws_txstatus_indicate(struct brcmf_fws_info *fws, u8 *data)
1377 hslot = brcmf_txstatus_get_field(status, HSLOT); 1418 hslot = brcmf_txstatus_get_field(status, HSLOT);
1378 genbit = brcmf_txstatus_get_field(status, GENERATION); 1419 genbit = brcmf_txstatus_get_field(status, GENERATION);
1379 1420
1380 return brcmf_fws_txs_process(fws, flags, hslot, genbit); 1421 brcmf_fws_lock(fws->drvr, lflags);
1422 brcmf_fws_txs_process(fws, flags, hslot, genbit);
1423 brcmf_fws_unlock(fws->drvr, lflags);
1424 return BRCMF_FWS_RET_OK_NOSCHEDULE;
1381} 1425}
1382 1426
1383static int brcmf_fws_dbg_seqnum_check(struct brcmf_fws_info *fws, u8 *data) 1427static int brcmf_fws_dbg_seqnum_check(struct brcmf_fws_info *fws, u8 *data)
@@ -1390,21 +1434,6 @@ static int brcmf_fws_dbg_seqnum_check(struct brcmf_fws_info *fws, u8 *data)
1390 return 0; 1434 return 0;
1391} 1435}
1392 1436
1393/* using macro so sparse checking does not complain
1394 * about locking imbalance.
1395 */
1396#define brcmf_fws_lock(drvr, flags) \
1397do { \
1398 flags = 0; \
1399 spin_lock_irqsave(&((drvr)->fws_spinlock), (flags)); \
1400} while (0)
1401
1402/* using macro so sparse checking does not complain
1403 * about locking imbalance.
1404 */
1405#define brcmf_fws_unlock(drvr, flags) \
1406 spin_unlock_irqrestore(&((drvr)->fws_spinlock), (flags))
1407
1408static int brcmf_fws_notify_credit_map(struct brcmf_if *ifp, 1437static int brcmf_fws_notify_credit_map(struct brcmf_if *ifp,
1409 const struct brcmf_event_msg *e, 1438 const struct brcmf_event_msg *e,
1410 void *data) 1439 void *data)
@@ -1455,7 +1484,6 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
1455 struct sk_buff *skb) 1484 struct sk_buff *skb)
1456{ 1485{
1457 struct brcmf_fws_info *fws = drvr->fws; 1486 struct brcmf_fws_info *fws = drvr->fws;
1458 ulong flags;
1459 u8 *signal_data; 1487 u8 *signal_data;
1460 s16 data_len; 1488 s16 data_len;
1461 u8 type; 1489 u8 type;
@@ -1475,9 +1503,6 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
1475 return 0; 1503 return 0;
1476 } 1504 }
1477 1505
1478 /* lock during tlv parsing */
1479 brcmf_fws_lock(drvr, flags);
1480
1481 fws->stats.header_pulls++; 1506 fws->stats.header_pulls++;
1482 data_len = signal_len; 1507 data_len = signal_len;
1483 signal_data = skb->data; 1508 signal_data = skb->data;
@@ -1571,25 +1596,17 @@ int brcmf_fws_hdrpull(struct brcmf_pub *drvr, int ifidx, s16 signal_len,
1571 if (skb->len == 0) 1596 if (skb->len == 0)
1572 fws->stats.header_only_pkt++; 1597 fws->stats.header_only_pkt++;
1573 1598
1574 brcmf_fws_unlock(drvr, flags);
1575 return 0; 1599 return 0;
1576} 1600}
1577 1601
1578static int brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo, 1602static void brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo,
1579 struct sk_buff *p) 1603 struct sk_buff *p)
1580{ 1604{
1581 struct brcmf_skbuff_cb *skcb = brcmf_skbcb(p); 1605 struct brcmf_skbuff_cb *skcb = brcmf_skbcb(p);
1582 struct brcmf_fws_mac_descriptor *entry = skcb->mac; 1606 struct brcmf_fws_mac_descriptor *entry = skcb->mac;
1583 int rc = 0;
1584 bool first_time;
1585 int hslot = BRCMF_FWS_HANGER_MAXITEMS;
1586 u8 free_ctr;
1587 u8 flags; 1607 u8 flags;
1588 1608
1589 first_time = skcb->state != BRCMF_FWS_SKBSTATE_SUPPRESSED;
1590
1591 brcmf_skb_if_flags_set_field(p, TRANSMIT, 1); 1609 brcmf_skb_if_flags_set_field(p, TRANSMIT, 1);
1592 brcmf_skb_htod_tag_set_field(p, FIFO, fifo);
1593 brcmf_skb_htod_tag_set_field(p, GENERATION, entry->generation); 1610 brcmf_skb_htod_tag_set_field(p, GENERATION, entry->generation);
1594 flags = BRCMF_FWS_HTOD_FLAG_PKTFROMHOST; 1611 flags = BRCMF_FWS_HTOD_FLAG_PKTFROMHOST;
1595 if (brcmf_skb_if_flags_get_field(p, REQUESTED)) { 1612 if (brcmf_skb_if_flags_get_field(p, REQUESTED)) {
@@ -1600,80 +1617,36 @@ static int brcmf_fws_precommit_skb(struct brcmf_fws_info *fws, int fifo,
1600 flags |= BRCMF_FWS_HTOD_FLAG_PKT_REQUESTED; 1617 flags |= BRCMF_FWS_HTOD_FLAG_PKT_REQUESTED;
1601 } 1618 }
1602 brcmf_skb_htod_tag_set_field(p, FLAGS, flags); 1619 brcmf_skb_htod_tag_set_field(p, FLAGS, flags);
1603 if (first_time) { 1620 brcmf_fws_hdrpush(fws, p);
1604 /* obtaining free slot may fail, but that will be caught
1605 * by the hanger push. This assures the packet has a BDC
1606 * header upon return.
1607 */
1608 hslot = brcmf_fws_hanger_get_free_slot(&fws->hanger);
1609 free_ctr = entry->seq[fifo];
1610 brcmf_skb_htod_tag_set_field(p, HSLOT, hslot);
1611 brcmf_skb_htod_tag_set_field(p, FREERUN, free_ctr);
1612 rc = brcmf_fws_hanger_pushpkt(&fws->hanger, p, hslot);
1613 if (rc)
1614 brcmf_err("hanger push failed: rc=%d\n", rc);
1615 }
1616
1617 if (rc == 0)
1618 brcmf_fws_hdrpush(fws, p);
1619
1620 return rc;
1621} 1621}
1622 1622
1623static void 1623static void brcmf_fws_rollback_toq(struct brcmf_fws_info *fws,
1624brcmf_fws_rollback_toq(struct brcmf_fws_info *fws, 1624 struct sk_buff *skb, int fifo)
1625 struct sk_buff *skb, int fifo)
1626{ 1625{
1627 /*
1628 put the packet back to the head of queue
1629
1630 - suppressed packet goes back to suppress sub-queue
1631 - pull out the header, if new or delayed packet
1632
1633 Note: hslot is used only when header removal is done.
1634 */
1635 struct brcmf_fws_mac_descriptor *entry; 1626 struct brcmf_fws_mac_descriptor *entry;
1636 enum brcmf_fws_skb_state state;
1637 struct sk_buff *pktout; 1627 struct sk_buff *pktout;
1628 int qidx, hslot;
1638 int rc = 0; 1629 int rc = 0;
1639 int hslot;
1640 1630
1641 state = brcmf_skbcb(skb)->state;
1642 entry = brcmf_skbcb(skb)->mac; 1631 entry = brcmf_skbcb(skb)->mac;
1643 hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT); 1632 if (entry->occupied) {
1644 1633 qidx = 2 * fifo;
1645 if (entry != NULL) { 1634 if (brcmf_skbcb(skb)->state == BRCMF_FWS_SKBSTATE_SUPPRESSED)
1646 if (state == BRCMF_FWS_SKBSTATE_SUPPRESSED) { 1635 qidx++;
1647 /* wl-header is saved for suppressed packets */ 1636
1648 pktout = brcmu_pktq_penq_head(&entry->psq, 2 * fifo + 1, 1637 pktout = brcmu_pktq_penq_head(&entry->psq, qidx, skb);
1649 skb); 1638 if (pktout == NULL) {
1650 if (pktout == NULL) { 1639 brcmf_err("%s queue %d full\n", entry->name, qidx);
1651 brcmf_err("suppress queue full\n"); 1640 rc = -ENOSPC;
1652 rc = -ENOSPC;
1653 }
1654 } else {
1655 /* delay-q packets are going to delay-q */
1656 pktout = brcmu_pktq_penq_head(&entry->psq,
1657 2 * fifo, skb);
1658 if (pktout == NULL) {
1659 brcmf_err("delay queue full\n");
1660 rc = -ENOSPC;
1661 }
1662
1663 /* free the hanger slot */
1664 brcmf_fws_hanger_poppkt(&fws->hanger, hslot, &pktout,
1665 true);
1666
1667 /* decrement sequence count */
1668 entry->seq[fifo]--;
1669 } 1641 }
1670 } else { 1642 } else {
1671 brcmf_err("no mac entry linked\n"); 1643 brcmf_err("%s entry removed\n", entry->name);
1672 rc = -ENOENT; 1644 rc = -ENOENT;
1673 } 1645 }
1674 1646
1675 if (rc) { 1647 if (rc) {
1676 fws->stats.rollback_failed++; 1648 fws->stats.rollback_failed++;
1649 hslot = brcmf_skb_htod_tag_get_field(skb, HSLOT);
1677 brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED, 1650 brcmf_fws_txs_process(fws, BRCMF_FWS_TXSTATUS_HOST_TOSSED,
1678 hslot, 0); 1651 hslot, 0);
1679 } else { 1652 } else {
@@ -1707,37 +1680,6 @@ static int brcmf_fws_borrow_credit(struct brcmf_fws_info *fws)
1707 return -ENAVAIL; 1680 return -ENAVAIL;
1708} 1681}
1709 1682
1710static int brcmf_fws_consume_credit(struct brcmf_fws_info *fws, int fifo,
1711 struct sk_buff *skb)
1712{
1713 struct brcmf_fws_mac_descriptor *entry = brcmf_skbcb(skb)->mac;
1714 int *credit = &fws->fifo_credit[fifo];
1715
1716 if (fifo != BRCMF_FWS_FIFO_AC_BE)
1717 fws->borrow_defer_timestamp = jiffies +
1718 BRCMF_FWS_BORROW_DEFER_PERIOD;
1719
1720 if (!(*credit)) {
1721 /* Try to borrow a credit from other queue */
1722 if (fifo != BRCMF_FWS_FIFO_AC_BE ||
1723 (brcmf_fws_borrow_credit(fws) != 0)) {
1724 brcmf_dbg(DATA, "ac=%d, credits depleted\n", fifo);
1725 return -ENAVAIL;
1726 }
1727 } else {
1728 (*credit)--;
1729 if (!(*credit))
1730 fws->fifo_credit_map &= ~(1 << fifo);
1731 }
1732
1733 brcmf_fws_macdesc_use_req_credit(entry, skb);
1734
1735 brcmf_dbg(DATA, "ac=%d, credits=%02d:%02d:%02d:%02d\n", fifo,
1736 fws->fifo_credit[0], fws->fifo_credit[1],
1737 fws->fifo_credit[2], fws->fifo_credit[3]);
1738 return 0;
1739}
1740
1741static int brcmf_fws_commit_skb(struct brcmf_fws_info *fws, int fifo, 1683static int brcmf_fws_commit_skb(struct brcmf_fws_info *fws, int fifo,
1742 struct sk_buff *skb) 1684 struct sk_buff *skb)
1743{ 1685{
@@ -1751,15 +1693,10 @@ static int brcmf_fws_commit_skb(struct brcmf_fws_info *fws, int fifo,
1751 if (IS_ERR(entry)) 1693 if (IS_ERR(entry))
1752 return PTR_ERR(entry); 1694 return PTR_ERR(entry);
1753 1695
1754 rc = brcmf_fws_precommit_skb(fws, fifo, skb); 1696 brcmf_fws_precommit_skb(fws, fifo, skb);
1755 if (rc < 0) {
1756 fws->stats.generic_error++;
1757 goto rollback;
1758 }
1759
1760 brcmf_dbg(DATA, "%s flags %X htod %X\n", entry->name, skcb->if_flags,
1761 skcb->htod);
1762 rc = brcmf_bus_txdata(bus, skb); 1697 rc = brcmf_bus_txdata(bus, skb);
1698 brcmf_dbg(DATA, "%s flags %X htod %X bus_tx %d\n", entry->name,
1699 skcb->if_flags, skcb->htod, rc);
1763 if (rc < 0) { 1700 if (rc < 0) {
1764 brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb); 1701 brcmf_proto_hdrpull(fws->drvr, false, &ifidx, skb);
1765 goto rollback; 1702 goto rollback;
@@ -1768,7 +1705,6 @@ static int brcmf_fws_commit_skb(struct brcmf_fws_info *fws, int fifo,
1768 entry->transit_count++; 1705 entry->transit_count++;
1769 if (entry->suppressed) 1706 if (entry->suppressed)
1770 entry->suppr_transit_count++; 1707 entry->suppr_transit_count++;
1771 entry->seq[fifo]++;
1772 fws->stats.pkt2bus++; 1708 fws->stats.pkt2bus++;
1773 fws->stats.send_pkts[fifo]++; 1709 fws->stats.send_pkts[fifo]++;
1774 if (brcmf_skb_if_flags_get_field(skb, REQUESTED)) 1710 if (brcmf_skb_if_flags_get_field(skb, REQUESTED))
@@ -1781,6 +1717,24 @@ rollback:
1781 return rc; 1717 return rc;
1782} 1718}
1783 1719
1720static int brcmf_fws_assign_htod(struct brcmf_fws_info *fws, struct sk_buff *p,
1721 int fifo)
1722{
1723 struct brcmf_skbuff_cb *skcb = brcmf_skbcb(p);
1724 int rc, hslot;
1725
1726 hslot = brcmf_fws_hanger_get_free_slot(&fws->hanger);
1727 brcmf_skb_htod_tag_set_field(p, HSLOT, hslot);
1728 brcmf_skb_htod_tag_set_field(p, FREERUN, skcb->mac->seq[fifo]);
1729 brcmf_skb_htod_tag_set_field(p, FIFO, fifo);
1730 rc = brcmf_fws_hanger_pushpkt(&fws->hanger, p, hslot);
1731 if (!rc)
1732 skcb->mac->seq[fifo]++;
1733 else
1734 fws->stats.generic_error++;
1735 return rc;
1736}
1737
1784int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb) 1738int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb)
1785{ 1739{
1786 struct brcmf_pub *drvr = ifp->drvr; 1740 struct brcmf_pub *drvr = ifp->drvr;
@@ -1809,33 +1763,25 @@ int brcmf_fws_process_skb(struct brcmf_if *ifp, struct sk_buff *skb)
1809 1763
1810 /* set control buffer information */ 1764 /* set control buffer information */
1811 skcb->if_flags = 0; 1765 skcb->if_flags = 0;
1812 skcb->mac = brcmf_fws_macdesc_find(fws, ifp, eh->h_dest);
1813 skcb->state = BRCMF_FWS_SKBSTATE_NEW; 1766 skcb->state = BRCMF_FWS_SKBSTATE_NEW;
1814 brcmf_skb_if_flags_set_field(skb, INDEX, ifp->ifidx); 1767 brcmf_skb_if_flags_set_field(skb, INDEX, ifp->ifidx);
1815 if (!multicast) 1768 if (!multicast)
1816 fifo = brcmf_fws_prio2fifo[skb->priority]; 1769 fifo = brcmf_fws_prio2fifo[skb->priority];
1817 1770
1771 brcmf_fws_lock(drvr, flags);
1772 if (fifo != BRCMF_FWS_FIFO_AC_BE && fifo < BRCMF_FWS_FIFO_BCMC)
1773 fws->borrow_defer_timestamp = jiffies +
1774 BRCMF_FWS_BORROW_DEFER_PERIOD;
1775
1776 skcb->mac = brcmf_fws_macdesc_find(fws, ifp, eh->h_dest);
1818 brcmf_dbg(DATA, "%s mac %pM multi %d fifo %d\n", skcb->mac->name, 1777 brcmf_dbg(DATA, "%s mac %pM multi %d fifo %d\n", skcb->mac->name,
1819 eh->h_dest, multicast, fifo); 1778 eh->h_dest, multicast, fifo);
1820 1779 if (!brcmf_fws_assign_htod(fws, skb, fifo)) {
1821 brcmf_fws_lock(drvr, flags);
1822 /* multicast credit support is conditional, setting
1823 * flag to false to assure credit is consumed below.
1824 */
1825 if (fws->bcmc_credit_check)
1826 multicast = false;
1827
1828 if (skcb->mac->suppressed ||
1829 fws->bus_flow_blocked ||
1830 brcmf_fws_macdesc_closed(fws, skcb->mac, fifo) ||
1831 brcmu_pktq_mlen(&skcb->mac->psq, 3 << (fifo * 2)) ||
1832 (!multicast &&
1833 brcmf_fws_consume_credit(fws, fifo, skb) < 0)) {
1834 /* enqueue the packet in delayQ */
1835 drvr->fws->fifo_delay_map |= 1 << fifo;
1836 brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_DELAYED, fifo, skb); 1780 brcmf_fws_enq(fws, BRCMF_FWS_SKBSTATE_DELAYED, fifo, skb);
1781 brcmf_fws_schedule_deq(fws);
1837 } else { 1782 } else {
1838 brcmf_fws_commit_skb(fws, fifo, skb); 1783 brcmf_err("drop skb: no hanger slot\n");
1784 brcmu_pkt_buf_free_skb(skb);
1839 } 1785 }
1840 brcmf_fws_unlock(drvr, flags); 1786 brcmf_fws_unlock(drvr, flags);
1841 return 0; 1787 return 0;
@@ -1895,7 +1841,7 @@ static void brcmf_fws_dequeue_worker(struct work_struct *worker)
1895 fws = container_of(worker, struct brcmf_fws_info, fws_dequeue_work); 1841 fws = container_of(worker, struct brcmf_fws_info, fws_dequeue_work);
1896 1842
1897 brcmf_fws_lock(fws->drvr, flags); 1843 brcmf_fws_lock(fws->drvr, flags);
1898 for (fifo = NL80211_NUM_ACS; fifo >= 0 && !fws->bus_flow_blocked; 1844 for (fifo = BRCMF_FWS_FIFO_BCMC; fifo >= 0 && !fws->bus_flow_blocked;
1899 fifo--) { 1845 fifo--) {
1900 while ((fws->fifo_credit[fifo]) || ((!fws->bcmc_credit_check) && 1846 while ((fws->fifo_credit[fifo]) || ((!fws->bcmc_credit_check) &&
1901 (fifo == BRCMF_FWS_FIFO_BCMC))) { 1847 (fifo == BRCMF_FWS_FIFO_BCMC))) {
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
index 793df66fe0bf..09786a539950 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio_host.h
@@ -229,8 +229,6 @@ brcmf_sdcard_recv_chain(struct brcmf_sdio_dev *sdiodev, u32 addr, uint fn,
229#define SDIO_REQ_4BYTE 0x1 229#define SDIO_REQ_4BYTE 0x1
230/* Fixed address (FIFO) (vs. incrementing address) */ 230/* Fixed address (FIFO) (vs. incrementing address) */
231#define SDIO_REQ_FIXED 0x2 231#define SDIO_REQ_FIXED 0x2
232/* Async request (vs. sync request) */
233#define SDIO_REQ_ASYNC 0x4
234 232
235/* Read/write to memory block (F1, no FIFO) via CMD53 (sync only). 233/* Read/write to memory block (F1, no FIFO) via CMD53 (sync only).
236 * rw: read or write (0/1) 234 * rw: read or write (0/1)
@@ -251,9 +249,6 @@ extern int brcmf_sdcard_abort(struct brcmf_sdio_dev *sdiodev, uint fn);
251extern int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev); 249extern int brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev);
252extern int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev); 250extern int brcmf_sdio_remove(struct brcmf_sdio_dev *sdiodev);
253 251
254extern int brcmf_sdcard_set_sbaddr_window(struct brcmf_sdio_dev *sdiodev,
255 u32 address);
256
257/* attach, return handler on success, NULL if failed. 252/* attach, return handler on success, NULL if failed.
258 * The handler shall be provided by all subsequent calls. No local cache 253 * The handler shall be provided by all subsequent calls. No local cache
259 * cfghdl points to the starting address of pci device mapped memory 254 * cfghdl points to the starting address of pci device mapped memory
diff --git a/drivers/net/wireless/cw1200/cw1200.h b/drivers/net/wireless/cw1200/cw1200.h
index 243e96353d13..1ad7d3602520 100644
--- a/drivers/net/wireless/cw1200/cw1200.h
+++ b/drivers/net/wireless/cw1200/cw1200.h
@@ -267,7 +267,7 @@ struct cw1200_common {
267 struct delayed_work bss_loss_work; 267 struct delayed_work bss_loss_work;
268 spinlock_t bss_loss_lock; /* Protect BSS loss state */ 268 spinlock_t bss_loss_lock; /* Protect BSS loss state */
269 int bss_loss_state; 269 int bss_loss_state;
270 int bss_loss_confirm_id; 270 u32 bss_loss_confirm_id;
271 int delayed_link_loss; 271 int delayed_link_loss;
272 struct work_struct bss_params_work; 272 struct work_struct bss_params_work;
273 273
diff --git a/drivers/net/wireless/cw1200/cw1200_spi.c b/drivers/net/wireless/cw1200/cw1200_spi.c
index 953bd1904d3d..d06376014bcd 100644
--- a/drivers/net/wireless/cw1200/cw1200_spi.c
+++ b/drivers/net/wireless/cw1200/cw1200_spi.c
@@ -61,7 +61,7 @@ static int cw1200_spi_memcpy_fromio(struct hwbus_priv *self,
61 void *dst, int count) 61 void *dst, int count)
62{ 62{
63 int ret, i; 63 int ret, i;
64 uint16_t regaddr; 64 u16 regaddr;
65 struct spi_message m; 65 struct spi_message m;
66 66
67 struct spi_transfer t_addr = { 67 struct spi_transfer t_addr = {
@@ -76,15 +76,18 @@ static int cw1200_spi_memcpy_fromio(struct hwbus_priv *self,
76 regaddr = (SDIO_TO_SPI_ADDR(addr))<<12; 76 regaddr = (SDIO_TO_SPI_ADDR(addr))<<12;
77 regaddr |= SET_READ; 77 regaddr |= SET_READ;
78 regaddr |= (count>>1); 78 regaddr |= (count>>1);
79 regaddr = cpu_to_le16(regaddr);
80 79
81#ifdef SPI_DEBUG 80#ifdef SPI_DEBUG
82 pr_info("READ : %04d from 0x%02x (%04x)\n", count, addr, 81 pr_info("READ : %04d from 0x%02x (%04x)\n", count, addr, regaddr);
83 le16_to_cpu(regaddr));
84#endif 82#endif
85 83
84 /* Header is LE16 */
85 regaddr = cpu_to_le16(regaddr);
86
87 /* We have to byteswap if the SPI bus is limited to 8b operation
88 or we are running on a Big Endian system
89 */
86#if defined(__LITTLE_ENDIAN) 90#if defined(__LITTLE_ENDIAN)
87 /* We have to byteswap if the SPI bus is limited to 8b operation */
88 if (self->func->bits_per_word == 8) 91 if (self->func->bits_per_word == 8)
89#endif 92#endif
90 regaddr = swab16(regaddr); 93 regaddr = swab16(regaddr);
@@ -104,8 +107,10 @@ static int cw1200_spi_memcpy_fromio(struct hwbus_priv *self,
104 printk("\n"); 107 printk("\n");
105#endif 108#endif
106 109
110 /* We have to byteswap if the SPI bus is limited to 8b operation
111 or we are running on a Big Endian system
112 */
107#if defined(__LITTLE_ENDIAN) 113#if defined(__LITTLE_ENDIAN)
108 /* We have to byteswap if the SPI bus is limited to 8b operation */
109 if (self->func->bits_per_word == 8) 114 if (self->func->bits_per_word == 8)
110#endif 115#endif
111 { 116 {
@@ -122,7 +127,7 @@ static int cw1200_spi_memcpy_toio(struct hwbus_priv *self,
122 const void *src, int count) 127 const void *src, int count)
123{ 128{
124 int rval, i; 129 int rval, i;
125 uint16_t regaddr; 130 u16 regaddr;
126 struct spi_transfer t_addr = { 131 struct spi_transfer t_addr = {
127 .tx_buf = &regaddr, 132 .tx_buf = &regaddr,
128 .len = sizeof(regaddr), 133 .len = sizeof(regaddr),
@@ -136,20 +141,23 @@ static int cw1200_spi_memcpy_toio(struct hwbus_priv *self,
136 regaddr = (SDIO_TO_SPI_ADDR(addr))<<12; 141 regaddr = (SDIO_TO_SPI_ADDR(addr))<<12;
137 regaddr &= SET_WRITE; 142 regaddr &= SET_WRITE;
138 regaddr |= (count>>1); 143 regaddr |= (count>>1);
139 regaddr = cpu_to_le16(regaddr);
140 144
141#ifdef SPI_DEBUG 145#ifdef SPI_DEBUG
142 pr_info("WRITE: %04d to 0x%02x (%04x)\n", count, addr, 146 pr_info("WRITE: %04d to 0x%02x (%04x)\n", count, addr, regaddr);
143 le16_to_cpu(regaddr));
144#endif 147#endif
145 148
149 /* Header is LE16 */
150 regaddr = cpu_to_le16(regaddr);
151
152 /* We have to byteswap if the SPI bus is limited to 8b operation
153 or we are running on a Big Endian system
154 */
146#if defined(__LITTLE_ENDIAN) 155#if defined(__LITTLE_ENDIAN)
147 /* We have to byteswap if the SPI bus is limited to 8b operation */
148 if (self->func->bits_per_word == 8) 156 if (self->func->bits_per_word == 8)
149#endif 157#endif
150 { 158 {
151 uint16_t *buf = (uint16_t *)src; 159 uint16_t *buf = (uint16_t *)src;
152 regaddr = swab16(regaddr); 160 regaddr = swab16(regaddr);
153 for (i = 0; i < ((count + 1) >> 1); i++) 161 for (i = 0; i < ((count + 1) >> 1); i++)
154 buf[i] = swab16(buf[i]); 162 buf[i] = swab16(buf[i]);
155 } 163 }
diff --git a/drivers/net/wireless/cw1200/hwio.c b/drivers/net/wireless/cw1200/hwio.c
index dad3fb331818..ff230b7aeedd 100644
--- a/drivers/net/wireless/cw1200/hwio.c
+++ b/drivers/net/wireless/cw1200/hwio.c
@@ -69,31 +69,33 @@ static int __cw1200_reg_write(struct cw1200_common *priv, u16 addr,
69static inline int __cw1200_reg_read_32(struct cw1200_common *priv, 69static inline int __cw1200_reg_read_32(struct cw1200_common *priv,
70 u16 addr, u32 *val) 70 u16 addr, u32 *val)
71{ 71{
72 int i = __cw1200_reg_read(priv, addr, val, sizeof(*val), 0); 72 __le32 tmp;
73 *val = le32_to_cpu(*val); 73 int i = __cw1200_reg_read(priv, addr, &tmp, sizeof(tmp), 0);
74 *val = le32_to_cpu(tmp);
74 return i; 75 return i;
75} 76}
76 77
77static inline int __cw1200_reg_write_32(struct cw1200_common *priv, 78static inline int __cw1200_reg_write_32(struct cw1200_common *priv,
78 u16 addr, u32 val) 79 u16 addr, u32 val)
79{ 80{
80 val = cpu_to_le32(val); 81 __le32 tmp = cpu_to_le32(val);
81 return __cw1200_reg_write(priv, addr, &val, sizeof(val), 0); 82 return __cw1200_reg_write(priv, addr, &tmp, sizeof(tmp), 0);
82} 83}
83 84
84static inline int __cw1200_reg_read_16(struct cw1200_common *priv, 85static inline int __cw1200_reg_read_16(struct cw1200_common *priv,
85 u16 addr, u16 *val) 86 u16 addr, u16 *val)
86{ 87{
87 int i = __cw1200_reg_read(priv, addr, val, sizeof(*val), 0); 88 __le16 tmp;
88 *val = le16_to_cpu(*val); 89 int i = __cw1200_reg_read(priv, addr, &tmp, sizeof(tmp), 0);
90 *val = le16_to_cpu(tmp);
89 return i; 91 return i;
90} 92}
91 93
92static inline int __cw1200_reg_write_16(struct cw1200_common *priv, 94static inline int __cw1200_reg_write_16(struct cw1200_common *priv,
93 u16 addr, u16 val) 95 u16 addr, u16 val)
94{ 96{
95 val = cpu_to_le16(val); 97 __le16 tmp = cpu_to_le16(val);
96 return __cw1200_reg_write(priv, addr, &val, sizeof(val), 0); 98 return __cw1200_reg_write(priv, addr, &tmp, sizeof(tmp), 0);
97} 99}
98 100
99int cw1200_reg_read(struct cw1200_common *priv, u16 addr, void *buf, 101int cw1200_reg_read(struct cw1200_common *priv, u16 addr, void *buf,
diff --git a/drivers/net/wireless/cw1200/hwio.h b/drivers/net/wireless/cw1200/hwio.h
index 563329cfead6..ddf52669dc5b 100644
--- a/drivers/net/wireless/cw1200/hwio.h
+++ b/drivers/net/wireless/cw1200/hwio.h
@@ -169,35 +169,34 @@ int cw1200_reg_write(struct cw1200_common *priv, u16 addr,
169static inline int cw1200_reg_read_16(struct cw1200_common *priv, 169static inline int cw1200_reg_read_16(struct cw1200_common *priv,
170 u16 addr, u16 *val) 170 u16 addr, u16 *val)
171{ 171{
172 u32 tmp; 172 __le32 tmp;
173 int i; 173 int i;
174 i = cw1200_reg_read(priv, addr, &tmp, sizeof(tmp)); 174 i = cw1200_reg_read(priv, addr, &tmp, sizeof(tmp));
175 tmp = le32_to_cpu(tmp); 175 *val = le32_to_cpu(tmp) & 0xfffff;
176 *val = tmp & 0xffff;
177 return i; 176 return i;
178} 177}
179 178
180static inline int cw1200_reg_write_16(struct cw1200_common *priv, 179static inline int cw1200_reg_write_16(struct cw1200_common *priv,
181 u16 addr, u16 val) 180 u16 addr, u16 val)
182{ 181{
183 u32 tmp = val; 182 __le32 tmp = cpu_to_le32((u32)val);
184 tmp = cpu_to_le32(tmp);
185 return cw1200_reg_write(priv, addr, &tmp, sizeof(tmp)); 183 return cw1200_reg_write(priv, addr, &tmp, sizeof(tmp));
186} 184}
187 185
188static inline int cw1200_reg_read_32(struct cw1200_common *priv, 186static inline int cw1200_reg_read_32(struct cw1200_common *priv,
189 u16 addr, u32 *val) 187 u16 addr, u32 *val)
190{ 188{
191 int i = cw1200_reg_read(priv, addr, val, sizeof(*val)); 189 __le32 tmp;
192 *val = le32_to_cpu(*val); 190 int i = cw1200_reg_read(priv, addr, &tmp, sizeof(tmp));
191 *val = le32_to_cpu(tmp);
193 return i; 192 return i;
194} 193}
195 194
196static inline int cw1200_reg_write_32(struct cw1200_common *priv, 195static inline int cw1200_reg_write_32(struct cw1200_common *priv,
197 u16 addr, u32 val) 196 u16 addr, u32 val)
198{ 197{
199 val = cpu_to_le32(val); 198 __le32 tmp = cpu_to_le32(val);
200 return cw1200_reg_write(priv, addr, &val, sizeof(val)); 199 return cw1200_reg_write(priv, addr, &tmp, sizeof(val));
201} 200}
202 201
203int cw1200_indirect_read(struct cw1200_common *priv, u32 addr, void *buf, 202int cw1200_indirect_read(struct cw1200_common *priv, u32 addr, void *buf,
@@ -224,22 +223,24 @@ static inline int cw1200_ahb_read(struct cw1200_common *priv, u32 addr,
224static inline int cw1200_apb_read_32(struct cw1200_common *priv, 223static inline int cw1200_apb_read_32(struct cw1200_common *priv,
225 u32 addr, u32 *val) 224 u32 addr, u32 *val)
226{ 225{
227 int i = cw1200_apb_read(priv, addr, val, sizeof(*val)); 226 __le32 tmp;
228 *val = le32_to_cpu(*val); 227 int i = cw1200_apb_read(priv, addr, &tmp, sizeof(tmp));
228 *val = le32_to_cpu(tmp);
229 return i; 229 return i;
230} 230}
231 231
232static inline int cw1200_apb_write_32(struct cw1200_common *priv, 232static inline int cw1200_apb_write_32(struct cw1200_common *priv,
233 u32 addr, u32 val) 233 u32 addr, u32 val)
234{ 234{
235 val = cpu_to_le32(val); 235 __le32 tmp = cpu_to_le32(val);
236 return cw1200_apb_write(priv, addr, &val, sizeof(val)); 236 return cw1200_apb_write(priv, addr, &tmp, sizeof(val));
237} 237}
238static inline int cw1200_ahb_read_32(struct cw1200_common *priv, 238static inline int cw1200_ahb_read_32(struct cw1200_common *priv,
239 u32 addr, u32 *val) 239 u32 addr, u32 *val)
240{ 240{
241 int i = cw1200_ahb_read(priv, addr, val, sizeof(*val)); 241 __le32 tmp;
242 *val = le32_to_cpu(*val); 242 int i = cw1200_ahb_read(priv, addr, &tmp, sizeof(tmp));
243 *val = le32_to_cpu(tmp);
243 return i; 244 return i;
244} 245}
245 246
diff --git a/drivers/net/wireless/cw1200/main.c b/drivers/net/wireless/cw1200/main.c
index da885036ca5f..3724e739cbf4 100644
--- a/drivers/net/wireless/cw1200/main.c
+++ b/drivers/net/wireless/cw1200/main.c
@@ -238,8 +238,8 @@ static const struct ieee80211_ops cw1200_ops = {
238 /*.cancel_remain_on_channel = cw1200_cancel_remain_on_channel, */ 238 /*.cancel_remain_on_channel = cw1200_cancel_remain_on_channel, */
239}; 239};
240 240
241int cw1200_ba_rx_tids = -1; 241static int cw1200_ba_rx_tids = -1;
242int cw1200_ba_tx_tids = -1; 242static int cw1200_ba_tx_tids = -1;
243module_param(cw1200_ba_rx_tids, int, 0644); 243module_param(cw1200_ba_rx_tids, int, 0644);
244module_param(cw1200_ba_tx_tids, int, 0644); 244module_param(cw1200_ba_tx_tids, int, 0644);
245MODULE_PARM_DESC(cw1200_ba_rx_tids, "Block ACK RX TIDs"); 245MODULE_PARM_DESC(cw1200_ba_rx_tids, "Block ACK RX TIDs");
diff --git a/drivers/net/wireless/cw1200/queue.c b/drivers/net/wireless/cw1200/queue.c
index 8510454d5db1..9c3925f58d79 100644
--- a/drivers/net/wireless/cw1200/queue.c
+++ b/drivers/net/wireless/cw1200/queue.c
@@ -355,7 +355,7 @@ int cw1200_queue_get(struct cw1200_queue *queue,
355 *tx = (struct wsm_tx *)item->skb->data; 355 *tx = (struct wsm_tx *)item->skb->data;
356 *tx_info = IEEE80211_SKB_CB(item->skb); 356 *tx_info = IEEE80211_SKB_CB(item->skb);
357 *txpriv = &item->txpriv; 357 *txpriv = &item->txpriv;
358 (*tx)->packet_id = __cpu_to_le32(item->packet_id); 358 (*tx)->packet_id = item->packet_id;
359 list_move_tail(&item->head, &queue->pending); 359 list_move_tail(&item->head, &queue->pending);
360 ++queue->num_pending; 360 ++queue->num_pending;
361 --queue->link_map_cache[item->txpriv.link_id]; 361 --queue->link_map_cache[item->txpriv.link_id];
diff --git a/drivers/net/wireless/cw1200/sta.c b/drivers/net/wireless/cw1200/sta.c
index 4cd0352b508d..7365674366f4 100644
--- a/drivers/net/wireless/cw1200/sta.c
+++ b/drivers/net/wireless/cw1200/sta.c
@@ -621,7 +621,7 @@ int cw1200_conf_tx(struct ieee80211_hw *dev, struct ieee80211_vif *vif,
621 mutex_lock(&priv->conf_mutex); 621 mutex_lock(&priv->conf_mutex);
622 622
623 if (queue < dev->queues) { 623 if (queue < dev->queues) {
624 old_uapsd_flags = priv->uapsd_info.uapsd_flags; 624 old_uapsd_flags = le16_to_cpu(priv->uapsd_info.uapsd_flags);
625 625
626 WSM_TX_QUEUE_SET(&priv->tx_queue_params, queue, 0, 0, 0); 626 WSM_TX_QUEUE_SET(&priv->tx_queue_params, queue, 0, 0, 0);
627 ret = wsm_set_tx_queue_params(priv, 627 ret = wsm_set_tx_queue_params(priv,
@@ -645,7 +645,7 @@ int cw1200_conf_tx(struct ieee80211_hw *dev, struct ieee80211_vif *vif,
645 ret = cw1200_set_uapsd_param(priv, &priv->edca); 645 ret = cw1200_set_uapsd_param(priv, &priv->edca);
646 if (!ret && priv->setbssparams_done && 646 if (!ret && priv->setbssparams_done &&
647 (priv->join_status == CW1200_JOIN_STATUS_STA) && 647 (priv->join_status == CW1200_JOIN_STATUS_STA) &&
648 (old_uapsd_flags != priv->uapsd_info.uapsd_flags)) 648 (old_uapsd_flags != le16_to_cpu(priv->uapsd_info.uapsd_flags)))
649 ret = cw1200_set_pm(priv, &priv->powersave_mode); 649 ret = cw1200_set_pm(priv, &priv->powersave_mode);
650 } 650 }
651 } else { 651 } else {
@@ -1089,18 +1089,18 @@ static int cw1200_parse_sdd_file(struct cw1200_common *priv)
1089 ret = -1; 1089 ret = -1;
1090 break; 1090 break;
1091 } 1091 }
1092 v = le16_to_cpu(*((u16 *)(p + 2))); 1092 v = le16_to_cpu(*((__le16 *)(p + 2)));
1093 if (!v) /* non-zero means this is enabled */ 1093 if (!v) /* non-zero means this is enabled */
1094 break; 1094 break;
1095 1095
1096 v = le16_to_cpu(*((u16 *)(p + 4))); 1096 v = le16_to_cpu(*((__le16 *)(p + 4)));
1097 priv->conf_listen_interval = (v >> 7) & 0x1F; 1097 priv->conf_listen_interval = (v >> 7) & 0x1F;
1098 pr_debug("PTA found; Listen Interval %d\n", 1098 pr_debug("PTA found; Listen Interval %d\n",
1099 priv->conf_listen_interval); 1099 priv->conf_listen_interval);
1100 break; 1100 break;
1101 } 1101 }
1102 case SDD_REFERENCE_FREQUENCY_ELT_ID: { 1102 case SDD_REFERENCE_FREQUENCY_ELT_ID: {
1103 u16 clk = le16_to_cpu(*((u16 *)(p + 2))); 1103 u16 clk = le16_to_cpu(*((__le16 *)(p + 2)));
1104 if (clk != priv->hw_refclk) 1104 if (clk != priv->hw_refclk)
1105 pr_warn("SDD file doesn't match configured refclk (%d vs %d)\n", 1105 pr_warn("SDD file doesn't match configured refclk (%d vs %d)\n",
1106 clk, priv->hw_refclk); 1106 clk, priv->hw_refclk);
@@ -1785,9 +1785,9 @@ static int cw1200_set_btcoexinfo(struct cw1200_common *priv)
1785 } else { 1785 } else {
1786 pr_debug("[STA] STA has non ERP rates\n"); 1786 pr_debug("[STA] STA has non ERP rates\n");
1787 /* B only mode */ 1787 /* B only mode */
1788 arg.internalTxRate = (__ffs(priv->association_mode.basic_rate_set)); 1788 arg.internalTxRate = (__ffs(le32_to_cpu(priv->association_mode.basic_rate_set)));
1789 } 1789 }
1790 arg.nonErpInternalTxRate = (__ffs(priv->association_mode.basic_rate_set)); 1790 arg.nonErpInternalTxRate = (__ffs(le32_to_cpu(priv->association_mode.basic_rate_set)));
1791 } else { 1791 } else {
1792 /* P2P mode */ 1792 /* P2P mode */
1793 arg.internalTxRate = (__ffs(priv->bss_params.operational_rate_set & ~0xF)); 1793 arg.internalTxRate = (__ffs(priv->bss_params.operational_rate_set & ~0xF));
@@ -1908,7 +1908,7 @@ void cw1200_bss_info_changed(struct ieee80211_hw *dev,
1908 1908
1909 if (info->assoc || info->ibss_joined) { 1909 if (info->assoc || info->ibss_joined) {
1910 struct ieee80211_sta *sta = NULL; 1910 struct ieee80211_sta *sta = NULL;
1911 u32 val = 0; 1911 __le32 htprot = 0;
1912 1912
1913 if (info->dtim_period) 1913 if (info->dtim_period)
1914 priv->join_dtim_period = info->dtim_period; 1914 priv->join_dtim_period = info->dtim_period;
@@ -1935,19 +1935,18 @@ void cw1200_bss_info_changed(struct ieee80211_hw *dev,
1935 /* Non Greenfield stations present */ 1935 /* Non Greenfield stations present */
1936 if (priv->ht_info.operation_mode & 1936 if (priv->ht_info.operation_mode &
1937 IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT) 1937 IEEE80211_HT_OP_MODE_NON_GF_STA_PRSNT)
1938 val |= WSM_NON_GREENFIELD_STA_PRESENT; 1938 htprot |= cpu_to_le32(WSM_NON_GREENFIELD_STA_PRESENT);
1939 1939
1940 /* Set HT protection method */ 1940 /* Set HT protection method */
1941 val |= (priv->ht_info.operation_mode & IEEE80211_HT_OP_MODE_PROTECTION) << 2; 1941 htprot |= cpu_to_le32((priv->ht_info.operation_mode & IEEE80211_HT_OP_MODE_PROTECTION) << 2);
1942 1942
1943 /* TODO: 1943 /* TODO:
1944 * STBC_param.dual_cts 1944 * STBC_param.dual_cts
1945 * STBC_param.LSIG_TXOP_FILL 1945 * STBC_param.LSIG_TXOP_FILL
1946 */ 1946 */
1947 1947
1948 val = cpu_to_le32(val);
1949 wsm_write_mib(priv, WSM_MIB_ID_SET_HT_PROTECTION, 1948 wsm_write_mib(priv, WSM_MIB_ID_SET_HT_PROTECTION,
1950 &val, sizeof(val)); 1949 &htprot, sizeof(htprot));
1951 1950
1952 priv->association_mode.greenfield = 1951 priv->association_mode.greenfield =
1953 cw1200_ht_greenfield(&priv->ht_info); 1952 cw1200_ht_greenfield(&priv->ht_info);
diff --git a/drivers/net/wireless/cw1200/txrx.c b/drivers/net/wireless/cw1200/txrx.c
index 44ca10cb0d39..5862c373d714 100644
--- a/drivers/net/wireless/cw1200/txrx.c
+++ b/drivers/net/wireless/cw1200/txrx.c
@@ -599,15 +599,15 @@ cw1200_tx_h_bt(struct cw1200_common *priv,
599 } else if (ieee80211_is_data(t->hdr->frame_control)) { 599 } else if (ieee80211_is_data(t->hdr->frame_control)) {
600 /* Skip LLC SNAP header (+6) */ 600 /* Skip LLC SNAP header (+6) */
601 u8 *payload = &t->skb->data[t->hdrlen]; 601 u8 *payload = &t->skb->data[t->hdrlen];
602 u16 *ethertype = (u16 *)&payload[6]; 602 __be16 *ethertype = (__be16 *)&payload[6];
603 if (*ethertype == __be16_to_cpu(ETH_P_PAE)) 603 if (be16_to_cpu(*ethertype) == ETH_P_PAE)
604 priority = WSM_EPTA_PRIORITY_EAPOL; 604 priority = WSM_EPTA_PRIORITY_EAPOL;
605 } else if (ieee80211_is_assoc_req(t->hdr->frame_control) || 605 } else if (ieee80211_is_assoc_req(t->hdr->frame_control) ||
606 ieee80211_is_reassoc_req(t->hdr->frame_control)) { 606 ieee80211_is_reassoc_req(t->hdr->frame_control)) {
607 struct ieee80211_mgmt *mgt_frame = 607 struct ieee80211_mgmt *mgt_frame =
608 (struct ieee80211_mgmt *)t->hdr; 608 (struct ieee80211_mgmt *)t->hdr;
609 609
610 if (mgt_frame->u.assoc_req.listen_interval < 610 if (le16_to_cpu(mgt_frame->u.assoc_req.listen_interval) <
611 priv->listen_interval) { 611 priv->listen_interval) {
612 pr_debug("Modified Listen Interval to %d from %d\n", 612 pr_debug("Modified Listen Interval to %d from %d\n",
613 priv->listen_interval, 613 priv->listen_interval,
@@ -615,8 +615,7 @@ cw1200_tx_h_bt(struct cw1200_common *priv,
615 /* Replace listen interval derieved from 615 /* Replace listen interval derieved from
616 * the one read from SDD 616 * the one read from SDD
617 */ 617 */
618 mgt_frame->u.assoc_req.listen_interval = 618 mgt_frame->u.assoc_req.listen_interval = cpu_to_le16(priv->listen_interval);
619 priv->listen_interval;
620 } 619 }
621 } 620 }
622 621
diff --git a/drivers/net/wireless/cw1200/wsm.c b/drivers/net/wireless/cw1200/wsm.c
index d95094fdcc50..cbb74d7a9be5 100644
--- a/drivers/net/wireless/cw1200/wsm.c
+++ b/drivers/net/wireless/cw1200/wsm.c
@@ -42,19 +42,19 @@
42 (buf)->data += size; \ 42 (buf)->data += size; \
43 } while (0) 43 } while (0)
44 44
45#define __WSM_GET(buf, type, cvt) \ 45#define __WSM_GET(buf, type, type2, cvt) \
46 ({ \ 46 ({ \
47 type val; \ 47 type val; \
48 if ((buf)->data + sizeof(type) > (buf)->end) \ 48 if ((buf)->data + sizeof(type) > (buf)->end) \
49 goto underflow; \ 49 goto underflow; \
50 val = cvt(*(type *)(buf)->data); \ 50 val = cvt(*(type2 *)(buf)->data); \
51 (buf)->data += sizeof(type); \ 51 (buf)->data += sizeof(type); \
52 val; \ 52 val; \
53 }) 53 })
54 54
55#define WSM_GET8(buf) __WSM_GET(buf, u8, (u8)) 55#define WSM_GET8(buf) __WSM_GET(buf, u8, u8, (u8))
56#define WSM_GET16(buf) __WSM_GET(buf, u16, __le16_to_cpu) 56#define WSM_GET16(buf) __WSM_GET(buf, u16, __le16, __le16_to_cpu)
57#define WSM_GET32(buf) __WSM_GET(buf, u32, __le32_to_cpu) 57#define WSM_GET32(buf) __WSM_GET(buf, u32, __le32, __le32_to_cpu)
58 58
59#define WSM_PUT(buf, ptr, size) \ 59#define WSM_PUT(buf, ptr, size) \
60 do { \ 60 do { \
@@ -65,18 +65,18 @@
65 (buf)->data += size; \ 65 (buf)->data += size; \
66 } while (0) 66 } while (0)
67 67
68#define __WSM_PUT(buf, val, type, cvt) \ 68#define __WSM_PUT(buf, val, type, type2, cvt) \
69 do { \ 69 do { \
70 if ((buf)->data + sizeof(type) > (buf)->end) \ 70 if ((buf)->data + sizeof(type) > (buf)->end) \
71 if (wsm_buf_reserve((buf), sizeof(type))) \ 71 if (wsm_buf_reserve((buf), sizeof(type))) \
72 goto nomem; \ 72 goto nomem; \
73 *(type *)(buf)->data = cvt(val); \ 73 *(type2 *)(buf)->data = cvt(val); \
74 (buf)->data += sizeof(type); \ 74 (buf)->data += sizeof(type); \
75 } while (0) 75 } while (0)
76 76
77#define WSM_PUT8(buf, val) __WSM_PUT(buf, val, u8, (u8)) 77#define WSM_PUT8(buf, val) __WSM_PUT(buf, val, u8, u8, (u8))
78#define WSM_PUT16(buf, val) __WSM_PUT(buf, val, u16, __cpu_to_le16) 78#define WSM_PUT16(buf, val) __WSM_PUT(buf, val, u16, __le16, __cpu_to_le16)
79#define WSM_PUT32(buf, val) __WSM_PUT(buf, val, u32, __cpu_to_le32) 79#define WSM_PUT32(buf, val) __WSM_PUT(buf, val, u32, __le32, __cpu_to_le32)
80 80
81static void wsm_buf_reset(struct wsm_buf *buf); 81static void wsm_buf_reset(struct wsm_buf *buf);
82static int wsm_buf_reserve(struct wsm_buf *buf, size_t extra_size); 82static int wsm_buf_reserve(struct wsm_buf *buf, size_t extra_size);
@@ -931,8 +931,8 @@ static int wsm_event_indication(struct cw1200_common *priv, struct wsm_buf *buf)
931 if (!event) 931 if (!event)
932 return -ENOMEM; 932 return -ENOMEM;
933 933
934 event->evt.id = __le32_to_cpu(WSM_GET32(buf)); 934 event->evt.id = WSM_GET32(buf);
935 event->evt.data = __le32_to_cpu(WSM_GET32(buf)); 935 event->evt.data = WSM_GET32(buf);
936 936
937 pr_debug("[WSM] Event: %d(%d)\n", 937 pr_debug("[WSM] Event: %d(%d)\n",
938 event->evt.id, event->evt.data); 938 event->evt.id, event->evt.data);
@@ -1311,7 +1311,7 @@ int wsm_handle_rx(struct cw1200_common *priv, u16 id,
1311 1311
1312 wsm_buf.begin = (u8 *)&wsm[0]; 1312 wsm_buf.begin = (u8 *)&wsm[0];
1313 wsm_buf.data = (u8 *)&wsm[1]; 1313 wsm_buf.data = (u8 *)&wsm[1];
1314 wsm_buf.end = &wsm_buf.begin[__le32_to_cpu(wsm->len)]; 1314 wsm_buf.end = &wsm_buf.begin[__le16_to_cpu(wsm->len)];
1315 1315
1316 pr_debug("[WSM] <<< 0x%.4X (%td)\n", id, 1316 pr_debug("[WSM] <<< 0x%.4X (%td)\n", id,
1317 wsm_buf.end - wsm_buf.begin); 1317 wsm_buf.end - wsm_buf.begin);
@@ -1550,7 +1550,7 @@ static bool wsm_handle_tx_data(struct cw1200_common *priv,
1550 */ 1550 */
1551 pr_debug("[WSM] Convert probe request to scan.\n"); 1551 pr_debug("[WSM] Convert probe request to scan.\n");
1552 wsm_lock_tx_async(priv); 1552 wsm_lock_tx_async(priv);
1553 priv->pending_frame_id = __le32_to_cpu(wsm->packet_id); 1553 priv->pending_frame_id = wsm->packet_id;
1554 if (queue_delayed_work(priv->workqueue, 1554 if (queue_delayed_work(priv->workqueue,
1555 &priv->scan.probe_work, 0) <= 0) 1555 &priv->scan.probe_work, 0) <= 0)
1556 wsm_unlock_tx(priv); 1556 wsm_unlock_tx(priv);
@@ -1558,15 +1558,14 @@ static bool wsm_handle_tx_data(struct cw1200_common *priv,
1558 break; 1558 break;
1559 case do_drop: 1559 case do_drop:
1560 pr_debug("[WSM] Drop frame (0x%.4X).\n", fctl); 1560 pr_debug("[WSM] Drop frame (0x%.4X).\n", fctl);
1561 BUG_ON(cw1200_queue_remove(queue, 1561 BUG_ON(cw1200_queue_remove(queue, wsm->packet_id));
1562 __le32_to_cpu(wsm->packet_id)));
1563 handled = true; 1562 handled = true;
1564 break; 1563 break;
1565 case do_wep: 1564 case do_wep:
1566 pr_debug("[WSM] Issue set_default_wep_key.\n"); 1565 pr_debug("[WSM] Issue set_default_wep_key.\n");
1567 wsm_lock_tx_async(priv); 1566 wsm_lock_tx_async(priv);
1568 priv->wep_default_key_id = tx_info->control.hw_key->keyidx; 1567 priv->wep_default_key_id = tx_info->control.hw_key->keyidx;
1569 priv->pending_frame_id = __le32_to_cpu(wsm->packet_id); 1568 priv->pending_frame_id = wsm->packet_id;
1570 if (queue_work(priv->workqueue, &priv->wep_key_work) <= 0) 1569 if (queue_work(priv->workqueue, &priv->wep_key_work) <= 0)
1571 wsm_unlock_tx(priv); 1570 wsm_unlock_tx(priv);
1572 handled = true; 1571 handled = true;
diff --git a/drivers/net/wireless/cw1200/wsm.h b/drivers/net/wireless/cw1200/wsm.h
index 2816171f7a1d..7afc613c3706 100644
--- a/drivers/net/wireless/cw1200/wsm.h
+++ b/drivers/net/wireless/cw1200/wsm.h
@@ -806,7 +806,7 @@ struct wsm_tx {
806 struct wsm_hdr hdr; 806 struct wsm_hdr hdr;
807 807
808 /* Packet identifier that meant to be used in completion. */ 808 /* Packet identifier that meant to be used in completion. */
809 __le32 packet_id; 809 u32 packet_id; /* Note this is actually a cookie */
810 810
811 /* WSM_TRANSMIT_RATE_... */ 811 /* WSM_TRANSMIT_RATE_... */
812 u8 max_tx_rate; 812 u8 max_tx_rate;
@@ -825,18 +825,18 @@ struct wsm_tx {
825 u8 flags; 825 u8 flags;
826 826
827 /* Should be 0. */ 827 /* Should be 0. */
828 __le32 reserved; 828 u32 reserved;
829 829
830 /* The elapsed time in TUs, after the initial transmission */ 830 /* The elapsed time in TUs, after the initial transmission */
831 /* of an MSDU, after which further attempts to transmit */ 831 /* of an MSDU, after which further attempts to transmit */
832 /* the MSDU shall be terminated. Overrides the global */ 832 /* the MSDU shall be terminated. Overrides the global */
833 /* dot11MaxTransmitMsduLifeTime setting [optional] */ 833 /* dot11MaxTransmitMsduLifeTime setting [optional] */
834 /* Device will set the default value if this is 0. */ 834 /* Device will set the default value if this is 0. */
835 __le32 expire_time; 835 u32 expire_time;
836 836
837 /* WSM_HT_TX_... */ 837 /* WSM_HT_TX_... */
838 __le32 ht_tx_parameters; 838 __le32 ht_tx_parameters;
839}; 839} __packed;
840 840
841/* = sizeof(generic hi hdr) + sizeof(wsm hdr) + sizeof(alignment) */ 841/* = sizeof(generic hi hdr) + sizeof(wsm hdr) + sizeof(alignment) */
842#define WSM_TX_EXTRA_HEADROOM (28) 842#define WSM_TX_EXTRA_HEADROOM (28)
@@ -846,10 +846,10 @@ struct wsm_tx {
846 846
847struct wsm_rx { 847struct wsm_rx {
848 /* WSM_STATUS_... */ 848 /* WSM_STATUS_... */
849 __le32 status; 849 u32 status;
850 850
851 /* Specifies the channel of the received packet. */ 851 /* Specifies the channel of the received packet. */
852 __le16 channel_number; 852 u16 channel_number;
853 853
854 /* WSM_TRANSMIT_RATE_... */ 854 /* WSM_TRANSMIT_RATE_... */
855 u8 rx_rate; 855 u8 rx_rate;
@@ -859,11 +859,8 @@ struct wsm_rx {
859 u8 rcpi_rssi; 859 u8 rcpi_rssi;
860 860
861 /* WSM_RX_STATUS_... */ 861 /* WSM_RX_STATUS_... */
862 __le32 flags; 862 u32 flags;
863 863};
864 /* Payload */
865 u8 data[0];
866} __packed;
867 864
868/* = sizeof(generic hi hdr) + sizeof(wsm hdr) */ 865/* = sizeof(generic hi hdr) + sizeof(wsm hdr) */
869#define WSM_RX_EXTRA_HEADROOM (16) 866#define WSM_RX_EXTRA_HEADROOM (16)
@@ -1119,22 +1116,22 @@ int wsm_set_tx_queue_params(struct cw1200_common *priv,
1119#define WSM_EDCA_PARAMS_RESP_ID 0x0413 1116#define WSM_EDCA_PARAMS_RESP_ID 0x0413
1120struct wsm_edca_queue_params { 1117struct wsm_edca_queue_params {
1121 /* CWmin (in slots) for the access class. */ 1118 /* CWmin (in slots) for the access class. */
1122 __le16 cwmin; 1119 u16 cwmin;
1123 1120
1124 /* CWmax (in slots) for the access class. */ 1121 /* CWmax (in slots) for the access class. */
1125 __le16 cwmax; 1122 u16 cwmax;
1126 1123
1127 /* AIFS (in slots) for the access class. */ 1124 /* AIFS (in slots) for the access class. */
1128 __le16 aifns; 1125 u16 aifns;
1129 1126
1130 /* TX OP Limit (in microseconds) for the access class. */ 1127 /* TX OP Limit (in microseconds) for the access class. */
1131 __le16 txop_limit; 1128 u16 txop_limit;
1132 1129
1133 /* dot11MaxReceiveLifetime to be used for the specified */ 1130 /* dot11MaxReceiveLifetime to be used for the specified */
1134 /* the access class. Overrides the global */ 1131 /* the access class. Overrides the global */
1135 /* dot11MaxReceiveLifetime value */ 1132 /* dot11MaxReceiveLifetime value */
1136 __le32 max_rx_lifetime; 1133 u32 max_rx_lifetime;
1137} __packed; 1134};
1138 1135
1139struct wsm_edca_params { 1136struct wsm_edca_params {
1140 /* NOTE: index is a linux queue id. */ 1137 /* NOTE: index is a linux queue id. */
@@ -1147,12 +1144,12 @@ struct wsm_edca_params {
1147 __uapsd) \ 1144 __uapsd) \
1148 do { \ 1145 do { \
1149 struct wsm_edca_queue_params *p = &(__edca)->params[__queue]; \ 1146 struct wsm_edca_queue_params *p = &(__edca)->params[__queue]; \
1150 p->cwmin = (__cw_min); \ 1147 p->cwmin = __cw_min; \
1151 p->cwmax = (__cw_max); \ 1148 p->cwmax = __cw_max; \
1152 p->aifns = (__aifs); \ 1149 p->aifns = __aifs; \
1153 p->txop_limit = ((__txop) * TXOP_UNIT); \ 1150 p->txop_limit = ((__txop) * TXOP_UNIT); \
1154 p->max_rx_lifetime = (__lifetime); \ 1151 p->max_rx_lifetime = __lifetime; \
1155 (__edca)->uapsd_enable[__queue] = (__uapsd); \ 1152 (__edca)->uapsd_enable[__queue] = (__uapsd); \
1156 } while (0) 1153 } while (0)
1157 1154
1158int wsm_set_edca_params(struct cw1200_common *priv, 1155int wsm_set_edca_params(struct cw1200_common *priv,
@@ -1475,7 +1472,7 @@ static inline int wsm_set_template_frame(struct cw1200_common *priv,
1475 u8 *p = skb_push(arg->skb, 4); 1472 u8 *p = skb_push(arg->skb, 4);
1476 p[0] = arg->frame_type; 1473 p[0] = arg->frame_type;
1477 p[1] = arg->rate; 1474 p[1] = arg->rate;
1478 ((u16 *)p)[1] = __cpu_to_le16(arg->skb->len - 4); 1475 ((__le16 *)p)[1] = __cpu_to_le16(arg->skb->len - 4);
1479 ret = wsm_write_mib(priv, WSM_MIB_ID_TEMPLATE_FRAME, p, arg->skb->len); 1476 ret = wsm_write_mib(priv, WSM_MIB_ID_TEMPLATE_FRAME, p, arg->skb->len);
1480 skb_pull(arg->skb, 4); 1477 skb_pull(arg->skb, 4);
1481 return ret; 1478 return ret;
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index d96257b79a84..312fa0e42e6f 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -3548,6 +3548,7 @@ static int ipw_load(struct ipw_priv *priv)
3548 ipw_rx_queue_reset(priv, priv->rxq); 3548 ipw_rx_queue_reset(priv, priv->rxq);
3549 if (!priv->rxq) { 3549 if (!priv->rxq) {
3550 IPW_ERROR("Unable to initialize Rx queue\n"); 3550 IPW_ERROR("Unable to initialize Rx queue\n");
3551 rc = -ENOMEM;
3551 goto error; 3552 goto error;
3552 } 3553 }
3553 3554
diff --git a/drivers/net/wireless/ipw2x00/libipw_rx.c b/drivers/net/wireless/ipw2x00/libipw_rx.c
index 95a1ca1e895c..9ffe65931b29 100644
--- a/drivers/net/wireless/ipw2x00/libipw_rx.c
+++ b/drivers/net/wireless/ipw2x00/libipw_rx.c
@@ -1195,7 +1195,7 @@ static int libipw_parse_info_param(struct libipw_info_element
1195#ifdef CONFIG_LIBIPW_DEBUG 1195#ifdef CONFIG_LIBIPW_DEBUG
1196 p += snprintf(p, sizeof(rates_str) - 1196 p += snprintf(p, sizeof(rates_str) -
1197 (p - rates_str), "%02X ", 1197 (p - rates_str), "%02X ",
1198 network->rates[i]); 1198 network->rates_ex[i]);
1199#endif 1199#endif
1200 if (libipw_is_ofdm_rate 1200 if (libipw_is_ofdm_rate
1201 (info_element->data[i])) { 1201 (info_element->data[i])) {
diff --git a/drivers/net/wireless/iwlwifi/Kconfig b/drivers/net/wireless/iwlwifi/Kconfig
index 56c2040a955b..cbaa5c2c410f 100644
--- a/drivers/net/wireless/iwlwifi/Kconfig
+++ b/drivers/net/wireless/iwlwifi/Kconfig
@@ -128,16 +128,6 @@ config IWLWIFI_DEVICE_TRACING
128 occur. 128 occur.
129endmenu 129endmenu
130 130
131config IWLWIFI_DEVICE_TESTMODE
132 def_bool y
133 depends on IWLWIFI
134 depends on NL80211_TESTMODE
135 help
136 This option enables the testmode support for iwlwifi device through
137 NL80211_TESTMODE. This provide the capabilities of enable user space
138 validation applications to interacts with the device through the
139 generic netlink message via NL80211_TESTMODE channel.
140
141config IWLWIFI_P2P 131config IWLWIFI_P2P
142 def_bool y 132 def_bool y
143 bool "iwlwifi experimental P2P support" 133 bool "iwlwifi experimental P2P support"
diff --git a/drivers/net/wireless/iwlwifi/Makefile b/drivers/net/wireless/iwlwifi/Makefile
index f55a758b87f6..1fa64429bcc2 100644
--- a/drivers/net/wireless/iwlwifi/Makefile
+++ b/drivers/net/wireless/iwlwifi/Makefile
@@ -13,7 +13,6 @@ iwlwifi-$(CONFIG_IWLMVM) += iwl-7000.o
13iwlwifi-objs += $(iwlwifi-m) 13iwlwifi-objs += $(iwlwifi-m)
14 14
15iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o 15iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TRACING) += iwl-devtrace.o
16iwlwifi-$(CONFIG_IWLWIFI_DEVICE_TESTMODE) += iwl-test.o
17 16
18ccflags-y += -D__CHECK_ENDIAN__ -I$(src) 17ccflags-y += -D__CHECK_ENDIAN__ -I$(src)
19 18
diff --git a/drivers/net/wireless/iwlwifi/dvm/Makefile b/drivers/net/wireless/iwlwifi/dvm/Makefile
index 5ff76b204141..dce7ab2e0c4b 100644
--- a/drivers/net/wireless/iwlwifi/dvm/Makefile
+++ b/drivers/net/wireless/iwlwifi/dvm/Makefile
@@ -8,6 +8,5 @@ iwldvm-objs += scan.o led.o
8iwldvm-objs += rxon.o devices.o 8iwldvm-objs += rxon.o devices.o
9 9
10iwldvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o 10iwldvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o
11iwldvm-$(CONFIG_IWLWIFI_DEVICE_TESTMODE) += testmode.o
12 11
13ccflags-y += -D__CHECK_ENDIAN__ -I$(src)/../ 12ccflags-y += -D__CHECK_ENDIAN__ -I$(src)/../
diff --git a/drivers/net/wireless/iwlwifi/dvm/agn.h b/drivers/net/wireless/iwlwifi/dvm/agn.h
index de2c9514bef6..18355110deff 100644
--- a/drivers/net/wireless/iwlwifi/dvm/agn.h
+++ b/drivers/net/wireless/iwlwifi/dvm/agn.h
@@ -405,43 +405,6 @@ static inline __le32 iwl_hw_set_rate_n_flags(u8 rate, u32 flags)
405 405
406extern int iwl_alive_start(struct iwl_priv *priv); 406extern int iwl_alive_start(struct iwl_priv *priv);
407 407
408/* testmode support */
409#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
410
411extern int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data,
412 int len);
413extern int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw,
414 struct sk_buff *skb,
415 struct netlink_callback *cb,
416 void *data, int len);
417extern void iwl_testmode_init(struct iwl_priv *priv);
418extern void iwl_testmode_free(struct iwl_priv *priv);
419
420#else
421
422static inline
423int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
424{
425 return -ENOSYS;
426}
427
428static inline
429int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb,
430 struct netlink_callback *cb,
431 void *data, int len)
432{
433 return -ENOSYS;
434}
435
436static inline void iwl_testmode_init(struct iwl_priv *priv)
437{
438}
439
440static inline void iwl_testmode_free(struct iwl_priv *priv)
441{
442}
443#endif
444
445#ifdef CONFIG_IWLWIFI_DEBUG 408#ifdef CONFIG_IWLWIFI_DEBUG
446void iwl_print_rx_config_cmd(struct iwl_priv *priv, 409void iwl_print_rx_config_cmd(struct iwl_priv *priv,
447 enum iwl_rxon_context_id ctxid); 410 enum iwl_rxon_context_id ctxid);
diff --git a/drivers/net/wireless/iwlwifi/dvm/dev.h b/drivers/net/wireless/iwlwifi/dvm/dev.h
index 5cd87f949266..60a4e0d15715 100644
--- a/drivers/net/wireless/iwlwifi/dvm/dev.h
+++ b/drivers/net/wireless/iwlwifi/dvm/dev.h
@@ -52,8 +52,6 @@
52#include "rs.h" 52#include "rs.h"
53#include "tt.h" 53#include "tt.h"
54 54
55#include "iwl-test.h"
56
57/* CT-KILL constants */ 55/* CT-KILL constants */
58#define CT_KILL_THRESHOLD_LEGACY 110 /* in Celsius */ 56#define CT_KILL_THRESHOLD_LEGACY 110 /* in Celsius */
59#define CT_KILL_THRESHOLD 114 /* in Celsius */ 57#define CT_KILL_THRESHOLD 114 /* in Celsius */
@@ -691,10 +689,6 @@ struct iwl_priv {
691 struct iwl_spectrum_notification measure_report; 689 struct iwl_spectrum_notification measure_report;
692 u8 measurement_status; 690 u8 measurement_status;
693 691
694#define IWL_OWNERSHIP_DRIVER 0
695#define IWL_OWNERSHIP_TM 1
696 u8 ucode_owner;
697
698 /* ucode beacon time */ 692 /* ucode beacon time */
699 u32 ucode_beacon_time; 693 u32 ucode_beacon_time;
700 int missed_beacon_threshold; 694 int missed_beacon_threshold;
@@ -889,7 +883,7 @@ struct iwl_priv {
889#endif /* CONFIG_IWLWIFI_DEBUGFS */ 883#endif /* CONFIG_IWLWIFI_DEBUGFS */
890 884
891 struct iwl_nvm_data *nvm_data; 885 struct iwl_nvm_data *nvm_data;
892 /* eeprom blob for debugfs/testmode */ 886 /* eeprom blob for debugfs */
893 u8 *eeprom_blob; 887 u8 *eeprom_blob;
894 size_t eeprom_blob_size; 888 size_t eeprom_blob_size;
895 889
@@ -905,11 +899,6 @@ struct iwl_priv {
905 unsigned long blink_on, blink_off; 899 unsigned long blink_on, blink_off;
906 bool led_registered; 900 bool led_registered;
907 901
908#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
909 struct iwl_test tst;
910 u32 tm_fixed_rate;
911#endif
912
913 /* WoWLAN GTK rekey data */ 902 /* WoWLAN GTK rekey data */
914 u8 kck[NL80211_KCK_LEN], kek[NL80211_KEK_LEN]; 903 u8 kck[NL80211_KCK_LEN], kek[NL80211_KEK_LEN];
915 __le64 replay_ctr; 904 __le64 replay_ctr;
diff --git a/drivers/net/wireless/iwlwifi/dvm/lib.c b/drivers/net/wireless/iwlwifi/dvm/lib.c
index 9879550a0fea..3d5bdc4217a8 100644
--- a/drivers/net/wireless/iwlwifi/dvm/lib.c
+++ b/drivers/net/wireless/iwlwifi/dvm/lib.c
@@ -1288,12 +1288,6 @@ int iwl_dvm_send_cmd(struct iwl_priv *priv, struct iwl_host_cmd *cmd)
1288 if (!(cmd->flags & CMD_ASYNC)) 1288 if (!(cmd->flags & CMD_ASYNC))
1289 lockdep_assert_held(&priv->mutex); 1289 lockdep_assert_held(&priv->mutex);
1290 1290
1291 if (priv->ucode_owner == IWL_OWNERSHIP_TM &&
1292 !(cmd->flags & CMD_ON_DEMAND)) {
1293 IWL_DEBUG_HC(priv, "tm own the uCode, no regular hcmd send\n");
1294 return -EIO;
1295 }
1296
1297 return iwl_trans_send_cmd(priv->trans, cmd); 1291 return iwl_trans_send_cmd(priv->trans, cmd);
1298} 1292}
1299 1293
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
index eef64bb854f7..822f1a00efbb 100644
--- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
@@ -1766,8 +1766,6 @@ struct ieee80211_ops iwlagn_hw_ops = {
1766 .remain_on_channel = iwlagn_mac_remain_on_channel, 1766 .remain_on_channel = iwlagn_mac_remain_on_channel,
1767 .cancel_remain_on_channel = iwlagn_mac_cancel_remain_on_channel, 1767 .cancel_remain_on_channel = iwlagn_mac_cancel_remain_on_channel,
1768 .rssi_callback = iwlagn_mac_rssi_callback, 1768 .rssi_callback = iwlagn_mac_rssi_callback,
1769 CFG80211_TESTMODE_CMD(iwlagn_mac_testmode_cmd)
1770 CFG80211_TESTMODE_DUMP(iwlagn_mac_testmode_dump)
1771 .set_tim = iwlagn_mac_set_tim, 1769 .set_tim = iwlagn_mac_set_tim,
1772}; 1770};
1773 1771
diff --git a/drivers/net/wireless/iwlwifi/dvm/main.c b/drivers/net/wireless/iwlwifi/dvm/main.c
index 7aa9c8dc33ef..3952ddf2ddb2 100644
--- a/drivers/net/wireless/iwlwifi/dvm/main.c
+++ b/drivers/net/wireless/iwlwifi/dvm/main.c
@@ -1105,8 +1105,6 @@ static int iwl_init_drv(struct iwl_priv *priv)
1105 priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF; 1105 priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF;
1106 priv->agg_tids_count = 0; 1106 priv->agg_tids_count = 0;
1107 1107
1108 priv->ucode_owner = IWL_OWNERSHIP_DRIVER;
1109
1110 priv->rx_statistics_jiffies = jiffies; 1108 priv->rx_statistics_jiffies = jiffies;
1111 1109
1112 /* Choose which receivers/antennas to use */ 1110 /* Choose which receivers/antennas to use */
@@ -1172,12 +1170,6 @@ static void iwl_option_config(struct iwl_priv *priv)
1172 IWL_INFO(priv, "CONFIG_IWLWIFI_DEVICE_TRACING disabled\n"); 1170 IWL_INFO(priv, "CONFIG_IWLWIFI_DEVICE_TRACING disabled\n");
1173#endif 1171#endif
1174 1172
1175#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
1176 IWL_INFO(priv, "CONFIG_IWLWIFI_DEVICE_TESTMODE enabled\n");
1177#else
1178 IWL_INFO(priv, "CONFIG_IWLWIFI_DEVICE_TESTMODE disabled\n");
1179#endif
1180
1181#ifdef CONFIG_IWLWIFI_P2P 1173#ifdef CONFIG_IWLWIFI_P2P
1182 IWL_INFO(priv, "CONFIG_IWLWIFI_P2P enabled\n"); 1174 IWL_INFO(priv, "CONFIG_IWLWIFI_P2P enabled\n");
1183#else 1175#else
@@ -1355,8 +1347,8 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
1355 IWL_BT_ANTENNA_COUPLING_THRESHOLD) ? 1347 IWL_BT_ANTENNA_COUPLING_THRESHOLD) ?
1356 true : false; 1348 true : false;
1357 1349
1358 /* enable/disable bt channel inhibition */ 1350 /* bt channel inhibition enabled*/
1359 priv->bt_ch_announce = iwlwifi_mod_params.bt_ch_announce; 1351 priv->bt_ch_announce = true;
1360 IWL_DEBUG_INFO(priv, "BT channel inhibition is %s\n", 1352 IWL_DEBUG_INFO(priv, "BT channel inhibition is %s\n",
1361 (priv->bt_ch_announce) ? "On" : "Off"); 1353 (priv->bt_ch_announce) ? "On" : "Off");
1362 1354
@@ -1451,7 +1443,6 @@ static struct iwl_op_mode *iwl_op_mode_dvm_start(struct iwl_trans *trans,
1451 ********************/ 1443 ********************/
1452 iwl_setup_deferred_work(priv); 1444 iwl_setup_deferred_work(priv);
1453 iwl_setup_rx_handlers(priv); 1445 iwl_setup_rx_handlers(priv);
1454 iwl_testmode_init(priv);
1455 1446
1456 iwl_power_initialize(priv); 1447 iwl_power_initialize(priv);
1457 iwl_tt_initialize(priv); 1448 iwl_tt_initialize(priv);
@@ -1488,7 +1479,6 @@ out_mac80211_unregister:
1488 iwlagn_mac_unregister(priv); 1479 iwlagn_mac_unregister(priv);
1489out_destroy_workqueue: 1480out_destroy_workqueue:
1490 iwl_tt_exit(priv); 1481 iwl_tt_exit(priv);
1491 iwl_testmode_free(priv);
1492 iwl_cancel_deferred_work(priv); 1482 iwl_cancel_deferred_work(priv);
1493 destroy_workqueue(priv->workqueue); 1483 destroy_workqueue(priv->workqueue);
1494 priv->workqueue = NULL; 1484 priv->workqueue = NULL;
@@ -1510,7 +1500,6 @@ static void iwl_op_mode_dvm_stop(struct iwl_op_mode *op_mode)
1510 1500
1511 IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n"); 1501 IWL_DEBUG_INFO(priv, "*** UNLOAD DRIVER ***\n");
1512 1502
1513 iwl_testmode_free(priv);
1514 iwlagn_mac_unregister(priv); 1503 iwlagn_mac_unregister(priv);
1515 1504
1516 iwl_tt_exit(priv); 1505 iwl_tt_exit(priv);
diff --git a/drivers/net/wireless/iwlwifi/dvm/rs.c b/drivers/net/wireless/iwlwifi/dvm/rs.c
index 8fe76dc4f373..1b693944123b 100644
--- a/drivers/net/wireless/iwlwifi/dvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/dvm/rs.c
@@ -351,12 +351,6 @@ static void rs_program_fix_rate(struct iwl_priv *priv,
351 lq_sta->active_mimo2_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ 351 lq_sta->active_mimo2_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
352 lq_sta->active_mimo3_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */ 352 lq_sta->active_mimo3_rate = 0x1FD0; /* 6 - 60 MBits, no 9, no CCK */
353 353
354#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
355 /* testmode has higher priority to overwirte the fixed rate */
356 if (priv->tm_fixed_rate)
357 lq_sta->dbg_fixed_rate = priv->tm_fixed_rate;
358#endif
359
360 IWL_DEBUG_RATE(priv, "sta_id %d rate 0x%X\n", 354 IWL_DEBUG_RATE(priv, "sta_id %d rate 0x%X\n",
361 lq_sta->lq.sta_id, lq_sta->dbg_fixed_rate); 355 lq_sta->lq.sta_id, lq_sta->dbg_fixed_rate);
362 356
@@ -419,23 +413,18 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv,
419 413
420 load = rs_tl_get_load(lq_data, tid); 414 load = rs_tl_get_load(lq_data, tid);
421 415
422 if ((iwlwifi_mod_params.auto_agg) || (load > IWL_AGG_LOAD_THRESHOLD)) { 416 IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n",
423 IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n", 417 sta->addr, tid);
424 sta->addr, tid); 418 ret = ieee80211_start_tx_ba_session(sta, tid, 5000);
425 ret = ieee80211_start_tx_ba_session(sta, tid, 5000); 419 if (ret == -EAGAIN) {
426 if (ret == -EAGAIN) { 420 /*
427 /* 421 * driver and mac80211 is out of sync
428 * driver and mac80211 is out of sync 422 * this might be cause by reloading firmware
429 * this might be cause by reloading firmware 423 * stop the tx ba session here
430 * stop the tx ba session here 424 */
431 */ 425 IWL_ERR(priv, "Fail start Tx agg on tid: %d\n",
432 IWL_ERR(priv, "Fail start Tx agg on tid: %d\n", 426 tid);
433 tid); 427 ieee80211_stop_tx_ba_session(sta, tid);
434 ieee80211_stop_tx_ba_session(sta, tid);
435 }
436 } else {
437 IWL_DEBUG_HT(priv, "Aggregation not enabled for tid %d "
438 "because load = %u\n", tid, load);
439 } 428 }
440 return ret; 429 return ret;
441} 430}
@@ -1083,11 +1072,6 @@ done:
1083 if (sta && sta->supp_rates[sband->band]) 1072 if (sta && sta->supp_rates[sband->band])
1084 rs_rate_scale_perform(priv, skb, sta, lq_sta); 1073 rs_rate_scale_perform(priv, skb, sta, lq_sta);
1085 1074
1086#if defined(CONFIG_MAC80211_DEBUGFS) && defined(CONFIG_IWLWIFI_DEVICE_TESTMODE)
1087 if ((priv->tm_fixed_rate) &&
1088 (priv->tm_fixed_rate != lq_sta->dbg_fixed_rate))
1089 rs_program_fix_rate(priv, lq_sta);
1090#endif
1091 if (priv->lib->bt_params && priv->lib->bt_params->advanced_bt_coexist) 1075 if (priv->lib->bt_params && priv->lib->bt_params->advanced_bt_coexist)
1092 rs_bt_update_lq(priv, ctx, lq_sta); 1076 rs_bt_update_lq(priv, ctx, lq_sta);
1093} 1077}
@@ -2913,9 +2897,6 @@ void iwl_rs_rate_init(struct iwl_priv *priv, struct ieee80211_sta *sta, u8 sta_i
2913 if (sband->band == IEEE80211_BAND_5GHZ) 2897 if (sband->band == IEEE80211_BAND_5GHZ)
2914 lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE; 2898 lq_sta->last_txrate_idx += IWL_FIRST_OFDM_RATE;
2915 lq_sta->is_agg = 0; 2899 lq_sta->is_agg = 0;
2916#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
2917 priv->tm_fixed_rate = 0;
2918#endif
2919#ifdef CONFIG_MAC80211_DEBUGFS 2900#ifdef CONFIG_MAC80211_DEBUGFS
2920 lq_sta->dbg_fixed_rate = 0; 2901 lq_sta->dbg_fixed_rate = 0;
2921#endif 2902#endif
diff --git a/drivers/net/wireless/iwlwifi/dvm/rx.c b/drivers/net/wireless/iwlwifi/dvm/rx.c
index 2f3fd160ab44..d71776dd1e6a 100644
--- a/drivers/net/wireless/iwlwifi/dvm/rx.c
+++ b/drivers/net/wireless/iwlwifi/dvm/rx.c
@@ -335,8 +335,7 @@ static void iwlagn_recover_from_statistics(struct iwl_priv *priv,
335 if (msecs < 99) 335 if (msecs < 99)
336 return; 336 return;
337 337
338 if (iwlwifi_mod_params.plcp_check && 338 if (!iwlagn_good_plcp_health(priv, cur_ofdm, cur_ofdm_ht, msecs))
339 !iwlagn_good_plcp_health(priv, cur_ofdm, cur_ofdm_ht, msecs))
340 iwl_force_rf_reset(priv, false); 339 iwl_force_rf_reset(priv, false);
341} 340}
342 341
@@ -1120,32 +1119,17 @@ int iwl_rx_dispatch(struct iwl_op_mode *op_mode, struct iwl_rx_cmd_buffer *rxb,
1120 */ 1119 */
1121 iwl_notification_wait_notify(&priv->notif_wait, pkt); 1120 iwl_notification_wait_notify(&priv->notif_wait, pkt);
1122 1121
1123#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE 1122 /* Based on type of command response or notification,
1124 /* 1123 * handle those that need handling via function in
1125 * RX data may be forwarded to userspace in one 1124 * rx_handlers table. See iwl_setup_rx_handlers() */
1126 * of two cases: the user owns the fw through testmode or when 1125 if (priv->rx_handlers[pkt->hdr.cmd]) {
1127 * the user requested to monitor the rx w/o affecting the regular flow. 1126 priv->rx_handlers_stats[pkt->hdr.cmd]++;
1128 * In these cases the iwl_test object will handle forwarding the rx 1127 err = priv->rx_handlers[pkt->hdr.cmd] (priv, rxb, cmd);
1129 * data to user space. 1128 } else {
1130 * Note that if the ownership flag != IWL_OWNERSHIP_TM the flow 1129 /* No handling needed */
1131 * continues. 1130 IWL_DEBUG_RX(priv, "No handler needed for %s, 0x%02x\n",
1132 */ 1131 iwl_dvm_get_cmd_string(pkt->hdr.cmd),
1133 iwl_test_rx(&priv->tst, rxb); 1132 pkt->hdr.cmd);
1134#endif
1135
1136 if (priv->ucode_owner != IWL_OWNERSHIP_TM) {
1137 /* Based on type of command response or notification,
1138 * handle those that need handling via function in
1139 * rx_handlers table. See iwl_setup_rx_handlers() */
1140 if (priv->rx_handlers[pkt->hdr.cmd]) {
1141 priv->rx_handlers_stats[pkt->hdr.cmd]++;
1142 err = priv->rx_handlers[pkt->hdr.cmd] (priv, rxb, cmd);
1143 } else {
1144 /* No handling needed */
1145 IWL_DEBUG_RX(priv, "No handler needed for %s, 0x%02x\n",
1146 iwl_dvm_get_cmd_string(pkt->hdr.cmd),
1147 pkt->hdr.cmd);
1148 }
1149 } 1133 }
1150 return err; 1134 return err;
1151} 1135}
diff --git a/drivers/net/wireless/iwlwifi/dvm/testmode.c b/drivers/net/wireless/iwlwifi/dvm/testmode.c
deleted file mode 100644
index b89b9d9b9969..000000000000
--- a/drivers/net/wireless/iwlwifi/dvm/testmode.c
+++ /dev/null
@@ -1,471 +0,0 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2010 - 2013 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called COPYING.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2010 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63
64#include <linux/init.h>
65#include <linux/kernel.h>
66#include <linux/module.h>
67#include <linux/dma-mapping.h>
68#include <net/net_namespace.h>
69#include <linux/netdevice.h>
70#include <net/cfg80211.h>
71#include <net/mac80211.h>
72#include <net/netlink.h>
73
74#include "iwl-debug.h"
75#include "iwl-trans.h"
76#include "dev.h"
77#include "agn.h"
78#include "iwl-test.h"
79#include "iwl-testmode.h"
80
81static int iwl_testmode_send_cmd(struct iwl_op_mode *op_mode,
82 struct iwl_host_cmd *cmd)
83{
84 struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
85 return iwl_dvm_send_cmd(priv, cmd);
86}
87
88static bool iwl_testmode_valid_hw_addr(u32 addr)
89{
90 if (iwlagn_hw_valid_rtc_data_addr(addr))
91 return true;
92
93 if (IWLAGN_RTC_INST_LOWER_BOUND <= addr &&
94 addr < IWLAGN_RTC_INST_UPPER_BOUND)
95 return true;
96
97 return false;
98}
99
100static u32 iwl_testmode_get_fw_ver(struct iwl_op_mode *op_mode)
101{
102 struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
103 return priv->fw->ucode_ver;
104}
105
106static struct sk_buff*
107iwl_testmode_alloc_reply(struct iwl_op_mode *op_mode, int len)
108{
109 struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
110 return cfg80211_testmode_alloc_reply_skb(priv->hw->wiphy, len);
111}
112
113static int iwl_testmode_reply(struct iwl_op_mode *op_mode, struct sk_buff *skb)
114{
115 return cfg80211_testmode_reply(skb);
116}
117
118static struct sk_buff *iwl_testmode_alloc_event(struct iwl_op_mode *op_mode,
119 int len)
120{
121 struct iwl_priv *priv = IWL_OP_MODE_GET_DVM(op_mode);
122 return cfg80211_testmode_alloc_event_skb(priv->hw->wiphy, len,
123 GFP_ATOMIC);
124}
125
126static void iwl_testmode_event(struct iwl_op_mode *op_mode, struct sk_buff *skb)
127{
128 return cfg80211_testmode_event(skb, GFP_ATOMIC);
129}
130
131static struct iwl_test_ops tst_ops = {
132 .send_cmd = iwl_testmode_send_cmd,
133 .valid_hw_addr = iwl_testmode_valid_hw_addr,
134 .get_fw_ver = iwl_testmode_get_fw_ver,
135 .alloc_reply = iwl_testmode_alloc_reply,
136 .reply = iwl_testmode_reply,
137 .alloc_event = iwl_testmode_alloc_event,
138 .event = iwl_testmode_event,
139};
140
141void iwl_testmode_init(struct iwl_priv *priv)
142{
143 iwl_test_init(&priv->tst, priv->trans, &tst_ops);
144}
145
146void iwl_testmode_free(struct iwl_priv *priv)
147{
148 iwl_test_free(&priv->tst);
149}
150
151static int iwl_testmode_cfg_init_calib(struct iwl_priv *priv)
152{
153 struct iwl_notification_wait calib_wait;
154 static const u8 calib_complete[] = {
155 CALIBRATION_COMPLETE_NOTIFICATION
156 };
157 int ret;
158
159 iwl_init_notification_wait(&priv->notif_wait, &calib_wait,
160 calib_complete, ARRAY_SIZE(calib_complete),
161 NULL, NULL);
162 ret = iwl_init_alive_start(priv);
163 if (ret) {
164 IWL_ERR(priv, "Fail init calibration: %d\n", ret);
165 goto cfg_init_calib_error;
166 }
167
168 ret = iwl_wait_notification(&priv->notif_wait, &calib_wait, 2 * HZ);
169 if (ret)
170 IWL_ERR(priv, "Error detecting"
171 " CALIBRATION_COMPLETE_NOTIFICATION: %d\n", ret);
172 return ret;
173
174cfg_init_calib_error:
175 iwl_remove_notification(&priv->notif_wait, &calib_wait);
176 return ret;
177}
178
179/*
180 * This function handles the user application commands for driver.
181 *
182 * It retrieves command ID carried with IWL_TM_ATTR_COMMAND and calls to the
183 * handlers respectively.
184 *
185 * If it's an unknown commdn ID, -ENOSYS is replied; otherwise, the returned
186 * value of the actual command execution is replied to the user application.
187 *
188 * If there's any message responding to the user space, IWL_TM_ATTR_SYNC_RSP
189 * is used for carry the message while IWL_TM_ATTR_COMMAND must set to
190 * IWL_TM_CMD_DEV2APP_SYNC_RSP.
191 *
192 * @hw: ieee80211_hw object that represents the device
193 * @tb: gnl message fields from the user space
194 */
195static int iwl_testmode_driver(struct ieee80211_hw *hw, struct nlattr **tb)
196{
197 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
198 struct iwl_trans *trans = priv->trans;
199 struct sk_buff *skb;
200 unsigned char *rsp_data_ptr = NULL;
201 int status = 0, rsp_data_len = 0;
202 u32 inst_size = 0, data_size = 0;
203 const struct fw_img *img;
204
205 switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
206 case IWL_TM_CMD_APP2DEV_GET_DEVICENAME:
207 rsp_data_ptr = (unsigned char *)priv->cfg->name;
208 rsp_data_len = strlen(priv->cfg->name);
209 skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy,
210 rsp_data_len + 20);
211 if (!skb) {
212 IWL_ERR(priv, "Memory allocation fail\n");
213 return -ENOMEM;
214 }
215 if (nla_put_u32(skb, IWL_TM_ATTR_COMMAND,
216 IWL_TM_CMD_DEV2APP_SYNC_RSP) ||
217 nla_put(skb, IWL_TM_ATTR_SYNC_RSP,
218 rsp_data_len, rsp_data_ptr))
219 goto nla_put_failure;
220 status = cfg80211_testmode_reply(skb);
221 if (status < 0)
222 IWL_ERR(priv, "Error sending msg : %d\n", status);
223 break;
224
225 case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW:
226 status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_INIT);
227 if (status)
228 IWL_ERR(priv, "Error loading init ucode: %d\n", status);
229 break;
230
231 case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB:
232 iwl_testmode_cfg_init_calib(priv);
233 priv->ucode_loaded = false;
234 iwl_trans_stop_device(trans);
235 break;
236
237 case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW:
238 status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_REGULAR);
239 if (status) {
240 IWL_ERR(priv,
241 "Error loading runtime ucode: %d\n", status);
242 break;
243 }
244 status = iwl_alive_start(priv);
245 if (status)
246 IWL_ERR(priv,
247 "Error starting the device: %d\n", status);
248 break;
249
250 case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW:
251 iwl_scan_cancel_timeout(priv, 200);
252 priv->ucode_loaded = false;
253 iwl_trans_stop_device(trans);
254 status = iwl_load_ucode_wait_alive(priv, IWL_UCODE_WOWLAN);
255 if (status) {
256 IWL_ERR(priv,
257 "Error loading WOWLAN ucode: %d\n", status);
258 break;
259 }
260 status = iwl_alive_start(priv);
261 if (status)
262 IWL_ERR(priv,
263 "Error starting the device: %d\n", status);
264 break;
265
266 case IWL_TM_CMD_APP2DEV_GET_EEPROM:
267 if (priv->eeprom_blob) {
268 skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy,
269 priv->eeprom_blob_size + 20);
270 if (!skb) {
271 IWL_ERR(priv, "Memory allocation fail\n");
272 return -ENOMEM;
273 }
274 if (nla_put_u32(skb, IWL_TM_ATTR_COMMAND,
275 IWL_TM_CMD_DEV2APP_EEPROM_RSP) ||
276 nla_put(skb, IWL_TM_ATTR_EEPROM,
277 priv->eeprom_blob_size,
278 priv->eeprom_blob))
279 goto nla_put_failure;
280 status = cfg80211_testmode_reply(skb);
281 if (status < 0)
282 IWL_ERR(priv, "Error sending msg : %d\n",
283 status);
284 } else
285 return -ENODATA;
286 break;
287
288 case IWL_TM_CMD_APP2DEV_FIXRATE_REQ:
289 if (!tb[IWL_TM_ATTR_FIXRATE]) {
290 IWL_ERR(priv, "Missing fixrate setting\n");
291 return -ENOMSG;
292 }
293 priv->tm_fixed_rate = nla_get_u32(tb[IWL_TM_ATTR_FIXRATE]);
294 break;
295
296 case IWL_TM_CMD_APP2DEV_GET_FW_INFO:
297 skb = cfg80211_testmode_alloc_reply_skb(hw->wiphy, 20 + 8);
298 if (!skb) {
299 IWL_ERR(priv, "Memory allocation fail\n");
300 return -ENOMEM;
301 }
302 if (!priv->ucode_loaded) {
303 IWL_ERR(priv, "No uCode has not been loaded\n");
304 return -EINVAL;
305 } else {
306 img = &priv->fw->img[priv->cur_ucode];
307 inst_size = img->sec[IWL_UCODE_SECTION_INST].len;
308 data_size = img->sec[IWL_UCODE_SECTION_DATA].len;
309 }
310 if (nla_put_u32(skb, IWL_TM_ATTR_FW_TYPE, priv->cur_ucode) ||
311 nla_put_u32(skb, IWL_TM_ATTR_FW_INST_SIZE, inst_size) ||
312 nla_put_u32(skb, IWL_TM_ATTR_FW_DATA_SIZE, data_size))
313 goto nla_put_failure;
314 status = cfg80211_testmode_reply(skb);
315 if (status < 0)
316 IWL_ERR(priv, "Error sending msg : %d\n", status);
317 break;
318
319 default:
320 IWL_ERR(priv, "Unknown testmode driver command ID\n");
321 return -ENOSYS;
322 }
323 return status;
324
325nla_put_failure:
326 kfree_skb(skb);
327 return -EMSGSIZE;
328}
329
330/*
331 * This function handles the user application switch ucode ownership.
332 *
333 * It retrieves the mandatory fields IWL_TM_ATTR_UCODE_OWNER and
334 * decide who the current owner of the uCode
335 *
336 * If the current owner is OWNERSHIP_TM, then the only host command
337 * can deliver to uCode is from testmode, all the other host commands
338 * will dropped.
339 *
340 * default driver is the owner of uCode in normal operational mode
341 *
342 * @hw: ieee80211_hw object that represents the device
343 * @tb: gnl message fields from the user space
344 */
345static int iwl_testmode_ownership(struct ieee80211_hw *hw, struct nlattr **tb)
346{
347 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
348 u8 owner;
349
350 if (!tb[IWL_TM_ATTR_UCODE_OWNER]) {
351 IWL_ERR(priv, "Missing ucode owner\n");
352 return -ENOMSG;
353 }
354
355 owner = nla_get_u8(tb[IWL_TM_ATTR_UCODE_OWNER]);
356 if (owner == IWL_OWNERSHIP_DRIVER) {
357 priv->ucode_owner = owner;
358 iwl_test_enable_notifications(&priv->tst, false);
359 } else if (owner == IWL_OWNERSHIP_TM) {
360 priv->ucode_owner = owner;
361 iwl_test_enable_notifications(&priv->tst, true);
362 } else {
363 IWL_ERR(priv, "Invalid owner\n");
364 return -EINVAL;
365 }
366 return 0;
367}
368
369/* The testmode gnl message handler that takes the gnl message from the
370 * user space and parses it per the policy iwl_testmode_gnl_msg_policy, then
371 * invoke the corresponding handlers.
372 *
373 * This function is invoked when there is user space application sending
374 * gnl message through the testmode tunnel NL80211_CMD_TESTMODE regulated
375 * by nl80211.
376 *
377 * It retrieves the mandatory field, IWL_TM_ATTR_COMMAND, before
378 * dispatching it to the corresponding handler.
379 *
380 * If IWL_TM_ATTR_COMMAND is missing, -ENOMSG is replied to user application;
381 * -ENOSYS is replied to the user application if the command is unknown;
382 * Otherwise, the command is dispatched to the respective handler.
383 *
384 * @hw: ieee80211_hw object that represents the device
385 * @data: pointer to user space message
386 * @len: length in byte of @data
387 */
388int iwlagn_mac_testmode_cmd(struct ieee80211_hw *hw, void *data, int len)
389{
390 struct nlattr *tb[IWL_TM_ATTR_MAX];
391 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
392 int result;
393
394 result = iwl_test_parse(&priv->tst, tb, data, len);
395 if (result)
396 return result;
397
398 /* in case multiple accesses to the device happens */
399 mutex_lock(&priv->mutex);
400 switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
401 case IWL_TM_CMD_APP2DEV_UCODE:
402 case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32:
403 case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32:
404 case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8:
405 case IWL_TM_CMD_APP2DEV_BEGIN_TRACE:
406 case IWL_TM_CMD_APP2DEV_END_TRACE:
407 case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ:
408 case IWL_TM_CMD_APP2DEV_NOTIFICATIONS:
409 case IWL_TM_CMD_APP2DEV_GET_FW_VERSION:
410 case IWL_TM_CMD_APP2DEV_GET_DEVICE_ID:
411 case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE:
412 result = iwl_test_handle_cmd(&priv->tst, tb);
413 break;
414
415 case IWL_TM_CMD_APP2DEV_GET_DEVICENAME:
416 case IWL_TM_CMD_APP2DEV_LOAD_INIT_FW:
417 case IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB:
418 case IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW:
419 case IWL_TM_CMD_APP2DEV_GET_EEPROM:
420 case IWL_TM_CMD_APP2DEV_FIXRATE_REQ:
421 case IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW:
422 case IWL_TM_CMD_APP2DEV_GET_FW_INFO:
423 IWL_DEBUG_INFO(priv, "testmode cmd to driver\n");
424 result = iwl_testmode_driver(hw, tb);
425 break;
426
427 case IWL_TM_CMD_APP2DEV_OWNERSHIP:
428 IWL_DEBUG_INFO(priv, "testmode change uCode ownership\n");
429 result = iwl_testmode_ownership(hw, tb);
430 break;
431
432 default:
433 IWL_ERR(priv, "Unknown testmode command\n");
434 result = -ENOSYS;
435 break;
436 }
437 mutex_unlock(&priv->mutex);
438
439 if (result)
440 IWL_ERR(priv, "Test cmd failed result=%d\n", result);
441 return result;
442}
443
444int iwlagn_mac_testmode_dump(struct ieee80211_hw *hw, struct sk_buff *skb,
445 struct netlink_callback *cb,
446 void *data, int len)
447{
448 struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw);
449 int result;
450 u32 cmd;
451
452 if (cb->args[3]) {
453 /* offset by 1 since commands start at 0 */
454 cmd = cb->args[3] - 1;
455 } else {
456 struct nlattr *tb[IWL_TM_ATTR_MAX];
457
458 result = iwl_test_parse(&priv->tst, tb, data, len);
459 if (result)
460 return result;
461
462 cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]);
463 cb->args[3] = cmd + 1;
464 }
465
466 /* in case multiple accesses to the device happens */
467 mutex_lock(&priv->mutex);
468 result = iwl_test_dump(&priv->tst, cmd, skb, cb);
469 mutex_unlock(&priv->mutex);
470 return result;
471}
diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c
index 353a053b4eb1..5ee983faa679 100644
--- a/drivers/net/wireless/iwlwifi/dvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/dvm/tx.c
@@ -162,18 +162,6 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv,
162 if (ieee80211_is_data(fc)) { 162 if (ieee80211_is_data(fc)) {
163 tx_cmd->initial_rate_index = 0; 163 tx_cmd->initial_rate_index = 0;
164 tx_cmd->tx_flags |= TX_CMD_FLG_STA_RATE_MSK; 164 tx_cmd->tx_flags |= TX_CMD_FLG_STA_RATE_MSK;
165#ifdef CONFIG_IWLWIFI_DEVICE_TESTMODE
166 if (priv->tm_fixed_rate) {
167 /*
168 * rate overwrite by testmode
169 * we not only send lq command to change rate
170 * we also re-enforce per data pkt base.
171 */
172 tx_cmd->tx_flags &= ~TX_CMD_FLG_STA_RATE_MSK;
173 memcpy(&tx_cmd->rate_n_flags, &priv->tm_fixed_rate,
174 sizeof(tx_cmd->rate_n_flags));
175 }
176#endif
177 return; 165 return;
178 } else if (ieee80211_is_back_req(fc)) 166 } else if (ieee80211_is_back_req(fc))
179 tx_cmd->tx_flags |= TX_CMD_FLG_STA_RATE_MSK; 167 tx_cmd->tx_flags |= TX_CMD_FLG_STA_RATE_MSK;
diff --git a/drivers/net/wireless/iwlwifi/iwl-7000.c b/drivers/net/wireless/iwlwifi/iwl-7000.c
index d4f3b4864ab1..22b7fa5b971a 100644
--- a/drivers/net/wireless/iwlwifi/iwl-7000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-7000.c
@@ -67,16 +67,16 @@
67#include "iwl-agn-hw.h" 67#include "iwl-agn-hw.h"
68 68
69/* Highest firmware API version supported */ 69/* Highest firmware API version supported */
70#define IWL7260_UCODE_API_MAX 6 70#define IWL7260_UCODE_API_MAX 7
71#define IWL3160_UCODE_API_MAX 6 71#define IWL3160_UCODE_API_MAX 7
72 72
73/* Oldest version we won't warn about */ 73/* Oldest version we won't warn about */
74#define IWL7260_UCODE_API_OK 6 74#define IWL7260_UCODE_API_OK 7
75#define IWL3160_UCODE_API_OK 6 75#define IWL3160_UCODE_API_OK 7
76 76
77/* Lowest firmware API version supported */ 77/* Lowest firmware API version supported */
78#define IWL7260_UCODE_API_MIN 6 78#define IWL7260_UCODE_API_MIN 7
79#define IWL3160_UCODE_API_MIN 6 79#define IWL3160_UCODE_API_MIN 7
80 80
81/* NVM versions */ 81/* NVM versions */
82#define IWL7260_NVM_VERSION 0x0a1d 82#define IWL7260_NVM_VERSION 0x0a1d
diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h
index 0189b9050f22..83b9ff6ff3ad 100644
--- a/drivers/net/wireless/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/iwlwifi/iwl-config.h
@@ -222,6 +222,7 @@ struct iwl_cfg {
222 const u32 max_inst_size; 222 const u32 max_inst_size;
223 u8 valid_tx_ant; 223 u8 valid_tx_ant;
224 u8 valid_rx_ant; 224 u8 valid_rx_ant;
225 bool bt_shared_single_ant;
225 u16 nvm_ver; 226 u16 nvm_ver;
226 u16 nvm_calib_ver; 227 u16 nvm_calib_ver;
227 /* params not likely to change within a device family */ 228 /* params not likely to change within a device family */
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c
index 2f690e578b5c..d0162d426f88 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.c
@@ -1111,11 +1111,8 @@ void iwl_drv_stop(struct iwl_drv *drv)
1111/* shared module parameters */ 1111/* shared module parameters */
1112struct iwl_mod_params iwlwifi_mod_params = { 1112struct iwl_mod_params iwlwifi_mod_params = {
1113 .restart_fw = true, 1113 .restart_fw = true,
1114 .plcp_check = true,
1115 .bt_coex_active = true, 1114 .bt_coex_active = true,
1116 .power_level = IWL_POWER_INDEX_1, 1115 .power_level = IWL_POWER_INDEX_1,
1117 .bt_ch_announce = true,
1118 .auto_agg = true,
1119 .wd_disable = true, 1116 .wd_disable = true,
1120 /* the rest are 0 by default */ 1117 /* the rest are 0 by default */
1121}; 1118};
@@ -1223,14 +1220,6 @@ module_param_named(antenna_coupling, iwlwifi_mod_params.ant_coupling,
1223MODULE_PARM_DESC(antenna_coupling, 1220MODULE_PARM_DESC(antenna_coupling,
1224 "specify antenna coupling in dB (defualt: 0 dB)"); 1221 "specify antenna coupling in dB (defualt: 0 dB)");
1225 1222
1226module_param_named(bt_ch_inhibition, iwlwifi_mod_params.bt_ch_announce,
1227 bool, S_IRUGO);
1228MODULE_PARM_DESC(bt_ch_inhibition,
1229 "Enable BT channel inhibition (default: enable)");
1230
1231module_param_named(plcp_check, iwlwifi_mod_params.plcp_check, bool, S_IRUGO);
1232MODULE_PARM_DESC(plcp_check, "Check plcp health (default: 1 [enabled])");
1233
1234module_param_named(wd_disable, iwlwifi_mod_params.wd_disable, int, S_IRUGO); 1223module_param_named(wd_disable, iwlwifi_mod_params.wd_disable, int, S_IRUGO);
1235MODULE_PARM_DESC(wd_disable, 1224MODULE_PARM_DESC(wd_disable,
1236 "Disable stuck queue watchdog timer 0=system default, " 1225 "Disable stuck queue watchdog timer 0=system default, "
@@ -1272,8 +1261,3 @@ module_param_named(power_level, iwlwifi_mod_params.power_level,
1272 int, S_IRUGO); 1261 int, S_IRUGO);
1273MODULE_PARM_DESC(power_level, 1262MODULE_PARM_DESC(power_level,
1274 "default power save level (range from 1 - 5, default: 1)"); 1263 "default power save level (range from 1 - 5, default: 1)");
1275
1276module_param_named(auto_agg, iwlwifi_mod_params.auto_agg,
1277 bool, S_IRUGO);
1278MODULE_PARM_DESC(auto_agg,
1279 "enable agg w/o check traffic load (default: enable)");
diff --git a/drivers/net/wireless/iwlwifi/iwl-modparams.h b/drivers/net/wireless/iwlwifi/iwl-modparams.h
index d4ad505b0a4b..a1f580c0c6c6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-modparams.h
+++ b/drivers/net/wireless/iwlwifi/iwl-modparams.h
@@ -93,7 +93,6 @@ enum iwl_power_level {
93 * use IWL_DISABLE_HT_* constants 93 * use IWL_DISABLE_HT_* constants
94 * @amsdu_size_8K: enable 8K amsdu size, default = 0 94 * @amsdu_size_8K: enable 8K amsdu size, default = 0
95 * @restart_fw: restart firmware, default = 1 95 * @restart_fw: restart firmware, default = 1
96 * @plcp_check: enable plcp health check, default = true
97 * @wd_disable: enable stuck queue check, default = 0 96 * @wd_disable: enable stuck queue check, default = 0
98 * @bt_coex_active: enable bt coex, default = true 97 * @bt_coex_active: enable bt coex, default = true
99 * @led_mode: system default, default = 0 98 * @led_mode: system default, default = 0
@@ -101,15 +100,12 @@ enum iwl_power_level {
101 * @power_level: power level, default = 1 100 * @power_level: power level, default = 1
102 * @debug_level: levels are IWL_DL_* 101 * @debug_level: levels are IWL_DL_*
103 * @ant_coupling: antenna coupling in dB, default = 0 102 * @ant_coupling: antenna coupling in dB, default = 0
104 * @bt_ch_announce: BT channel inhibition, default = enable
105 * @auto_agg: enable agg. without check, default = true
106 */ 103 */
107struct iwl_mod_params { 104struct iwl_mod_params {
108 int sw_crypto; 105 int sw_crypto;
109 unsigned int disable_11n; 106 unsigned int disable_11n;
110 int amsdu_size_8K; 107 int amsdu_size_8K;
111 bool restart_fw; 108 bool restart_fw;
112 bool plcp_check;
113 int wd_disable; 109 int wd_disable;
114 bool bt_coex_active; 110 bool bt_coex_active;
115 int led_mode; 111 int led_mode;
@@ -119,8 +115,6 @@ struct iwl_mod_params {
119 u32 debug_level; 115 u32 debug_level;
120#endif 116#endif
121 int ant_coupling; 117 int ant_coupling;
122 bool bt_ch_announce;
123 bool auto_agg;
124 char *nvm_file; 118 char *nvm_file;
125}; 119};
126 120
diff --git a/drivers/net/wireless/iwlwifi/iwl-test.c b/drivers/net/wireless/iwlwifi/iwl-test.c
deleted file mode 100644
index 5cfd55b86ed3..000000000000
--- a/drivers/net/wireless/iwlwifi/iwl-test.c
+++ /dev/null
@@ -1,852 +0,0 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2010 - 2013 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called COPYING.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2010 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63
64#include <linux/export.h>
65#include <net/netlink.h>
66
67#include "iwl-drv.h"
68#include "iwl-io.h"
69#include "iwl-fh.h"
70#include "iwl-prph.h"
71#include "iwl-trans.h"
72#include "iwl-test.h"
73#include "iwl-csr.h"
74#include "iwl-testmode.h"
75
76/*
77 * Periphery registers absolute lower bound. This is used in order to
78 * differentiate registery access through HBUS_TARG_PRPH_* and
79 * HBUS_TARG_MEM_* accesses.
80 */
81#define IWL_ABS_PRPH_START (0xA00000)
82
83/*
84 * The TLVs used in the gnl message policy between the kernel module and
85 * user space application. iwl_testmode_gnl_msg_policy is to be carried
86 * through the NL80211_CMD_TESTMODE channel regulated by nl80211.
87 * See iwl-testmode.h
88 */
89static
90struct nla_policy iwl_testmode_gnl_msg_policy[IWL_TM_ATTR_MAX] = {
91 [IWL_TM_ATTR_COMMAND] = { .type = NLA_U32, },
92
93 [IWL_TM_ATTR_UCODE_CMD_ID] = { .type = NLA_U8, },
94 [IWL_TM_ATTR_UCODE_CMD_DATA] = { .type = NLA_UNSPEC, },
95
96 [IWL_TM_ATTR_REG_OFFSET] = { .type = NLA_U32, },
97 [IWL_TM_ATTR_REG_VALUE8] = { .type = NLA_U8, },
98 [IWL_TM_ATTR_REG_VALUE32] = { .type = NLA_U32, },
99
100 [IWL_TM_ATTR_SYNC_RSP] = { .type = NLA_UNSPEC, },
101 [IWL_TM_ATTR_UCODE_RX_PKT] = { .type = NLA_UNSPEC, },
102
103 [IWL_TM_ATTR_EEPROM] = { .type = NLA_UNSPEC, },
104
105 [IWL_TM_ATTR_TRACE_ADDR] = { .type = NLA_UNSPEC, },
106 [IWL_TM_ATTR_TRACE_DUMP] = { .type = NLA_UNSPEC, },
107 [IWL_TM_ATTR_TRACE_SIZE] = { .type = NLA_U32, },
108
109 [IWL_TM_ATTR_FIXRATE] = { .type = NLA_U32, },
110
111 [IWL_TM_ATTR_UCODE_OWNER] = { .type = NLA_U8, },
112
113 [IWL_TM_ATTR_MEM_ADDR] = { .type = NLA_U32, },
114 [IWL_TM_ATTR_BUFFER_SIZE] = { .type = NLA_U32, },
115 [IWL_TM_ATTR_BUFFER_DUMP] = { .type = NLA_UNSPEC, },
116
117 [IWL_TM_ATTR_FW_VERSION] = { .type = NLA_U32, },
118 [IWL_TM_ATTR_DEVICE_ID] = { .type = NLA_U32, },
119 [IWL_TM_ATTR_FW_TYPE] = { .type = NLA_U32, },
120 [IWL_TM_ATTR_FW_INST_SIZE] = { .type = NLA_U32, },
121 [IWL_TM_ATTR_FW_DATA_SIZE] = { .type = NLA_U32, },
122
123 [IWL_TM_ATTR_ENABLE_NOTIFICATION] = {.type = NLA_FLAG, },
124};
125
126static inline void iwl_test_trace_clear(struct iwl_test *tst)
127{
128 memset(&tst->trace, 0, sizeof(struct iwl_test_trace));
129}
130
131static void iwl_test_trace_stop(struct iwl_test *tst)
132{
133 if (!tst->trace.enabled)
134 return;
135
136 if (tst->trace.cpu_addr && tst->trace.dma_addr)
137 dma_free_coherent(tst->trans->dev,
138 tst->trace.tsize,
139 tst->trace.cpu_addr,
140 tst->trace.dma_addr);
141
142 iwl_test_trace_clear(tst);
143}
144
145static inline void iwl_test_mem_clear(struct iwl_test *tst)
146{
147 memset(&tst->mem, 0, sizeof(struct iwl_test_mem));
148}
149
150static inline void iwl_test_mem_stop(struct iwl_test *tst)
151{
152 if (!tst->mem.in_read)
153 return;
154
155 iwl_test_mem_clear(tst);
156}
157
158/*
159 * Initializes the test object
160 * During the lifetime of the test object it is assumed that the transport is
161 * started. The test object should be stopped before the transport is stopped.
162 */
163void iwl_test_init(struct iwl_test *tst, struct iwl_trans *trans,
164 struct iwl_test_ops *ops)
165{
166 tst->trans = trans;
167 tst->ops = ops;
168
169 iwl_test_trace_clear(tst);
170 iwl_test_mem_clear(tst);
171}
172EXPORT_SYMBOL_GPL(iwl_test_init);
173
174/*
175 * Stop the test object
176 */
177void iwl_test_free(struct iwl_test *tst)
178{
179 iwl_test_mem_stop(tst);
180 iwl_test_trace_stop(tst);
181}
182EXPORT_SYMBOL_GPL(iwl_test_free);
183
184static inline int iwl_test_send_cmd(struct iwl_test *tst,
185 struct iwl_host_cmd *cmd)
186{
187 return tst->ops->send_cmd(tst->trans->op_mode, cmd);
188}
189
190static inline bool iwl_test_valid_hw_addr(struct iwl_test *tst, u32 addr)
191{
192 return tst->ops->valid_hw_addr(addr);
193}
194
195static inline u32 iwl_test_fw_ver(struct iwl_test *tst)
196{
197 return tst->ops->get_fw_ver(tst->trans->op_mode);
198}
199
200static inline struct sk_buff*
201iwl_test_alloc_reply(struct iwl_test *tst, int len)
202{
203 return tst->ops->alloc_reply(tst->trans->op_mode, len);
204}
205
206static inline int iwl_test_reply(struct iwl_test *tst, struct sk_buff *skb)
207{
208 return tst->ops->reply(tst->trans->op_mode, skb);
209}
210
211static inline struct sk_buff*
212iwl_test_alloc_event(struct iwl_test *tst, int len)
213{
214 return tst->ops->alloc_event(tst->trans->op_mode, len);
215}
216
217static inline void
218iwl_test_event(struct iwl_test *tst, struct sk_buff *skb)
219{
220 return tst->ops->event(tst->trans->op_mode, skb);
221}
222
223/*
224 * This function handles the user application commands to the fw. The fw
225 * commands are sent in a synchronuous manner. In case that the user requested
226 * to get commands response, it is send to the user.
227 */
228static int iwl_test_fw_cmd(struct iwl_test *tst, struct nlattr **tb)
229{
230 struct iwl_host_cmd cmd;
231 struct iwl_rx_packet *pkt;
232 struct sk_buff *skb;
233 void *reply_buf;
234 u32 reply_len;
235 int ret;
236 bool cmd_want_skb;
237
238 memset(&cmd, 0, sizeof(struct iwl_host_cmd));
239
240 if (!tb[IWL_TM_ATTR_UCODE_CMD_ID] ||
241 !tb[IWL_TM_ATTR_UCODE_CMD_DATA]) {
242 IWL_ERR(tst->trans, "Missing fw command mandatory fields\n");
243 return -ENOMSG;
244 }
245
246 cmd.flags = CMD_ON_DEMAND | CMD_SYNC;
247 cmd_want_skb = nla_get_flag(tb[IWL_TM_ATTR_UCODE_CMD_SKB]);
248 if (cmd_want_skb)
249 cmd.flags |= CMD_WANT_SKB;
250
251 cmd.id = nla_get_u8(tb[IWL_TM_ATTR_UCODE_CMD_ID]);
252 cmd.data[0] = nla_data(tb[IWL_TM_ATTR_UCODE_CMD_DATA]);
253 cmd.len[0] = nla_len(tb[IWL_TM_ATTR_UCODE_CMD_DATA]);
254 cmd.dataflags[0] = IWL_HCMD_DFL_NOCOPY;
255 IWL_DEBUG_INFO(tst->trans, "test fw cmd=0x%x, flags 0x%x, len %d\n",
256 cmd.id, cmd.flags, cmd.len[0]);
257
258 ret = iwl_test_send_cmd(tst, &cmd);
259 if (ret) {
260 IWL_ERR(tst->trans, "Failed to send hcmd\n");
261 return ret;
262 }
263 if (!cmd_want_skb)
264 return ret;
265
266 /* Handling return of SKB to the user */
267 pkt = cmd.resp_pkt;
268 if (!pkt) {
269 IWL_ERR(tst->trans, "HCMD received a null response packet\n");
270 return ret;
271 }
272
273 reply_len = le32_to_cpu(pkt->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
274 skb = iwl_test_alloc_reply(tst, reply_len + 20);
275 reply_buf = kmemdup(&pkt->hdr, reply_len, GFP_KERNEL);
276 if (!skb || !reply_buf) {
277 kfree_skb(skb);
278 kfree(reply_buf);
279 return -ENOMEM;
280 }
281
282 /* The reply is in a page, that we cannot send to user space. */
283 iwl_free_resp(&cmd);
284
285 if (nla_put_u32(skb, IWL_TM_ATTR_COMMAND,
286 IWL_TM_CMD_DEV2APP_UCODE_RX_PKT) ||
287 nla_put(skb, IWL_TM_ATTR_UCODE_RX_PKT, reply_len, reply_buf))
288 goto nla_put_failure;
289 return iwl_test_reply(tst, skb);
290
291nla_put_failure:
292 IWL_DEBUG_INFO(tst->trans, "Failed creating NL attributes\n");
293 kfree(reply_buf);
294 kfree_skb(skb);
295 return -ENOMSG;
296}
297
298/*
299 * Handles the user application commands for register access.
300 */
301static int iwl_test_reg(struct iwl_test *tst, struct nlattr **tb)
302{
303 u32 ofs, val32, cmd;
304 u8 val8;
305 struct sk_buff *skb;
306 int status = 0;
307 struct iwl_trans *trans = tst->trans;
308
309 if (!tb[IWL_TM_ATTR_REG_OFFSET]) {
310 IWL_ERR(trans, "Missing reg offset\n");
311 return -ENOMSG;
312 }
313
314 ofs = nla_get_u32(tb[IWL_TM_ATTR_REG_OFFSET]);
315 IWL_DEBUG_INFO(trans, "test reg access cmd offset=0x%x\n", ofs);
316
317 cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]);
318
319 /*
320 * Allow access only to FH/CSR/HBUS in direct mode.
321 * Since we don't have the upper bounds for the CSR and HBUS segments,
322 * we will use only the upper bound of FH for sanity check.
323 */
324 if (ofs >= FH_MEM_UPPER_BOUND) {
325 IWL_ERR(trans, "offset out of segment (0x0 - 0x%x)\n",
326 FH_MEM_UPPER_BOUND);
327 return -EINVAL;
328 }
329
330 switch (cmd) {
331 case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32:
332 val32 = iwl_read_direct32(tst->trans, ofs);
333 IWL_DEBUG_INFO(trans, "32 value to read 0x%x\n", val32);
334
335 skb = iwl_test_alloc_reply(tst, 20);
336 if (!skb) {
337 IWL_ERR(trans, "Memory allocation fail\n");
338 return -ENOMEM;
339 }
340 if (nla_put_u32(skb, IWL_TM_ATTR_REG_VALUE32, val32))
341 goto nla_put_failure;
342 status = iwl_test_reply(tst, skb);
343 if (status < 0)
344 IWL_ERR(trans, "Error sending msg : %d\n", status);
345 break;
346
347 case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32:
348 if (!tb[IWL_TM_ATTR_REG_VALUE32]) {
349 IWL_ERR(trans, "Missing value to write\n");
350 return -ENOMSG;
351 } else {
352 val32 = nla_get_u32(tb[IWL_TM_ATTR_REG_VALUE32]);
353 IWL_DEBUG_INFO(trans, "32b write val=0x%x\n", val32);
354 iwl_write_direct32(tst->trans, ofs, val32);
355 }
356 break;
357
358 case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8:
359 if (!tb[IWL_TM_ATTR_REG_VALUE8]) {
360 IWL_ERR(trans, "Missing value to write\n");
361 return -ENOMSG;
362 } else {
363 val8 = nla_get_u8(tb[IWL_TM_ATTR_REG_VALUE8]);
364 IWL_DEBUG_INFO(trans, "8b write val=0x%x\n", val8);
365 iwl_write8(tst->trans, ofs, val8);
366 }
367 break;
368
369 default:
370 IWL_ERR(trans, "Unknown test register cmd ID\n");
371 return -ENOMSG;
372 }
373
374 return status;
375
376nla_put_failure:
377 kfree_skb(skb);
378 return -EMSGSIZE;
379}
380
381/*
382 * Handles the request to start FW tracing. Allocates of the trace buffer
383 * and sends a reply to user space with the address of the allocated buffer.
384 */
385static int iwl_test_trace_begin(struct iwl_test *tst, struct nlattr **tb)
386{
387 struct sk_buff *skb;
388 int status = 0;
389
390 if (tst->trace.enabled)
391 return -EBUSY;
392
393 if (!tb[IWL_TM_ATTR_TRACE_SIZE])
394 tst->trace.size = TRACE_BUFF_SIZE_DEF;
395 else
396 tst->trace.size =
397 nla_get_u32(tb[IWL_TM_ATTR_TRACE_SIZE]);
398
399 if (!tst->trace.size)
400 return -EINVAL;
401
402 if (tst->trace.size < TRACE_BUFF_SIZE_MIN ||
403 tst->trace.size > TRACE_BUFF_SIZE_MAX)
404 return -EINVAL;
405
406 tst->trace.tsize = tst->trace.size + TRACE_BUFF_PADD;
407 tst->trace.cpu_addr = dma_alloc_coherent(tst->trans->dev,
408 tst->trace.tsize,
409 &tst->trace.dma_addr,
410 GFP_KERNEL);
411 if (!tst->trace.cpu_addr)
412 return -ENOMEM;
413
414 tst->trace.enabled = true;
415 tst->trace.trace_addr = (u8 *)PTR_ALIGN(tst->trace.cpu_addr, 0x100);
416
417 memset(tst->trace.trace_addr, 0x03B, tst->trace.size);
418
419 skb = iwl_test_alloc_reply(tst, sizeof(tst->trace.dma_addr) + 20);
420 if (!skb) {
421 IWL_ERR(tst->trans, "Memory allocation fail\n");
422 iwl_test_trace_stop(tst);
423 return -ENOMEM;
424 }
425
426 if (nla_put(skb, IWL_TM_ATTR_TRACE_ADDR,
427 sizeof(tst->trace.dma_addr),
428 (u64 *)&tst->trace.dma_addr))
429 goto nla_put_failure;
430
431 status = iwl_test_reply(tst, skb);
432 if (status < 0)
433 IWL_ERR(tst->trans, "Error sending msg : %d\n", status);
434
435 tst->trace.nchunks = DIV_ROUND_UP(tst->trace.size,
436 DUMP_CHUNK_SIZE);
437
438 return status;
439
440nla_put_failure:
441 kfree_skb(skb);
442 if (nla_get_u32(tb[IWL_TM_ATTR_COMMAND]) ==
443 IWL_TM_CMD_APP2DEV_BEGIN_TRACE)
444 iwl_test_trace_stop(tst);
445 return -EMSGSIZE;
446}
447
448/*
449 * Handles indirect read from the periphery or the SRAM. The read is performed
450 * to a temporary buffer. The user space application should later issue a dump
451 */
452static int iwl_test_indirect_read(struct iwl_test *tst, u32 addr, u32 size)
453{
454 struct iwl_trans *trans = tst->trans;
455 unsigned long flags;
456 int i;
457
458 if (size & 0x3)
459 return -EINVAL;
460
461 tst->mem.size = size;
462 tst->mem.addr = kmalloc(tst->mem.size, GFP_KERNEL);
463 if (tst->mem.addr == NULL)
464 return -ENOMEM;
465
466 /* Hard-coded periphery absolute address */
467 if (IWL_ABS_PRPH_START <= addr &&
468 addr < IWL_ABS_PRPH_START + PRPH_END) {
469 if (!iwl_trans_grab_nic_access(trans, false, &flags)) {
470 return -EIO;
471 }
472 iwl_write32(trans, HBUS_TARG_PRPH_RADDR,
473 addr | (3 << 24));
474 for (i = 0; i < size; i += 4)
475 *(u32 *)(tst->mem.addr + i) =
476 iwl_read32(trans, HBUS_TARG_PRPH_RDAT);
477 iwl_trans_release_nic_access(trans, &flags);
478 } else { /* target memory (SRAM) */
479 iwl_trans_read_mem(trans, addr, tst->mem.addr,
480 tst->mem.size / 4);
481 }
482
483 tst->mem.nchunks =
484 DIV_ROUND_UP(tst->mem.size, DUMP_CHUNK_SIZE);
485 tst->mem.in_read = true;
486 return 0;
487
488}
489
490/*
491 * Handles indirect write to the periphery or SRAM. The is performed to a
492 * temporary buffer.
493 */
494static int iwl_test_indirect_write(struct iwl_test *tst, u32 addr,
495 u32 size, unsigned char *buf)
496{
497 struct iwl_trans *trans = tst->trans;
498 u32 val, i;
499 unsigned long flags;
500
501 if (IWL_ABS_PRPH_START <= addr &&
502 addr < IWL_ABS_PRPH_START + PRPH_END) {
503 /* Periphery writes can be 1-3 bytes long, or DWORDs */
504 if (size < 4) {
505 memcpy(&val, buf, size);
506 if (!iwl_trans_grab_nic_access(trans, false, &flags))
507 return -EIO;
508 iwl_write32(trans, HBUS_TARG_PRPH_WADDR,
509 (addr & 0x0000FFFF) |
510 ((size - 1) << 24));
511 iwl_write32(trans, HBUS_TARG_PRPH_WDAT, val);
512 iwl_trans_release_nic_access(trans, &flags);
513 } else {
514 if (size % 4)
515 return -EINVAL;
516 for (i = 0; i < size; i += 4)
517 iwl_write_prph(trans, addr+i,
518 *(u32 *)(buf+i));
519 }
520 } else if (iwl_test_valid_hw_addr(tst, addr)) {
521 iwl_trans_write_mem(trans, addr, buf, size / 4);
522 } else {
523 return -EINVAL;
524 }
525 return 0;
526}
527
528/*
529 * Handles the user application commands for indirect read/write
530 * to/from the periphery or the SRAM.
531 */
532static int iwl_test_indirect_mem(struct iwl_test *tst, struct nlattr **tb)
533{
534 u32 addr, size, cmd;
535 unsigned char *buf;
536
537 /* Both read and write should be blocked, for atomicity */
538 if (tst->mem.in_read)
539 return -EBUSY;
540
541 cmd = nla_get_u32(tb[IWL_TM_ATTR_COMMAND]);
542 if (!tb[IWL_TM_ATTR_MEM_ADDR]) {
543 IWL_ERR(tst->trans, "Error finding memory offset address\n");
544 return -ENOMSG;
545 }
546 addr = nla_get_u32(tb[IWL_TM_ATTR_MEM_ADDR]);
547 if (!tb[IWL_TM_ATTR_BUFFER_SIZE]) {
548 IWL_ERR(tst->trans, "Error finding size for memory reading\n");
549 return -ENOMSG;
550 }
551 size = nla_get_u32(tb[IWL_TM_ATTR_BUFFER_SIZE]);
552
553 if (cmd == IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ) {
554 return iwl_test_indirect_read(tst, addr, size);
555 } else {
556 if (!tb[IWL_TM_ATTR_BUFFER_DUMP])
557 return -EINVAL;
558 buf = (unsigned char *)nla_data(tb[IWL_TM_ATTR_BUFFER_DUMP]);
559 return iwl_test_indirect_write(tst, addr, size, buf);
560 }
561}
562
563/*
564 * Enable notifications to user space
565 */
566static int iwl_test_notifications(struct iwl_test *tst,
567 struct nlattr **tb)
568{
569 tst->notify = nla_get_flag(tb[IWL_TM_ATTR_ENABLE_NOTIFICATION]);
570 return 0;
571}
572
573/*
574 * Handles the request to get the device id
575 */
576static int iwl_test_get_dev_id(struct iwl_test *tst, struct nlattr **tb)
577{
578 u32 devid = tst->trans->hw_id;
579 struct sk_buff *skb;
580 int status;
581
582 IWL_DEBUG_INFO(tst->trans, "hw version: 0x%x\n", devid);
583
584 skb = iwl_test_alloc_reply(tst, 20);
585 if (!skb) {
586 IWL_ERR(tst->trans, "Memory allocation fail\n");
587 return -ENOMEM;
588 }
589
590 if (nla_put_u32(skb, IWL_TM_ATTR_DEVICE_ID, devid))
591 goto nla_put_failure;
592 status = iwl_test_reply(tst, skb);
593 if (status < 0)
594 IWL_ERR(tst->trans, "Error sending msg : %d\n", status);
595
596 return 0;
597
598nla_put_failure:
599 kfree_skb(skb);
600 return -EMSGSIZE;
601}
602
603/*
604 * Handles the request to get the FW version
605 */
606static int iwl_test_get_fw_ver(struct iwl_test *tst, struct nlattr **tb)
607{
608 struct sk_buff *skb;
609 int status;
610 u32 ver = iwl_test_fw_ver(tst);
611
612 IWL_DEBUG_INFO(tst->trans, "uCode version raw: 0x%x\n", ver);
613
614 skb = iwl_test_alloc_reply(tst, 20);
615 if (!skb) {
616 IWL_ERR(tst->trans, "Memory allocation fail\n");
617 return -ENOMEM;
618 }
619
620 if (nla_put_u32(skb, IWL_TM_ATTR_FW_VERSION, ver))
621 goto nla_put_failure;
622
623 status = iwl_test_reply(tst, skb);
624 if (status < 0)
625 IWL_ERR(tst->trans, "Error sending msg : %d\n", status);
626
627 return 0;
628
629nla_put_failure:
630 kfree_skb(skb);
631 return -EMSGSIZE;
632}
633
634/*
635 * Parse the netlink message and validate that the IWL_TM_ATTR_CMD exists
636 */
637int iwl_test_parse(struct iwl_test *tst, struct nlattr **tb,
638 void *data, int len)
639{
640 int result;
641
642 result = nla_parse(tb, IWL_TM_ATTR_MAX - 1, data, len,
643 iwl_testmode_gnl_msg_policy);
644 if (result) {
645 IWL_ERR(tst->trans, "Fail parse gnl msg: %d\n", result);
646 return result;
647 }
648
649 /* IWL_TM_ATTR_COMMAND is absolutely mandatory */
650 if (!tb[IWL_TM_ATTR_COMMAND]) {
651 IWL_ERR(tst->trans, "Missing testmode command type\n");
652 return -ENOMSG;
653 }
654 return 0;
655}
656IWL_EXPORT_SYMBOL(iwl_test_parse);
657
658/*
659 * Handle test commands.
660 * Returns 1 for unknown commands (not handled by the test object); negative
661 * value in case of error.
662 */
663int iwl_test_handle_cmd(struct iwl_test *tst, struct nlattr **tb)
664{
665 int result;
666
667 switch (nla_get_u32(tb[IWL_TM_ATTR_COMMAND])) {
668 case IWL_TM_CMD_APP2DEV_UCODE:
669 IWL_DEBUG_INFO(tst->trans, "test cmd to uCode\n");
670 result = iwl_test_fw_cmd(tst, tb);
671 break;
672
673 case IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32:
674 case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32:
675 case IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8:
676 IWL_DEBUG_INFO(tst->trans, "test cmd to register\n");
677 result = iwl_test_reg(tst, tb);
678 break;
679
680 case IWL_TM_CMD_APP2DEV_BEGIN_TRACE:
681 IWL_DEBUG_INFO(tst->trans, "test uCode trace cmd to driver\n");
682 result = iwl_test_trace_begin(tst, tb);
683 break;
684
685 case IWL_TM_CMD_APP2DEV_END_TRACE:
686 iwl_test_trace_stop(tst);
687 result = 0;
688 break;
689
690 case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ:
691 case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE:
692 IWL_DEBUG_INFO(tst->trans, "test indirect memory cmd\n");
693 result = iwl_test_indirect_mem(tst, tb);
694 break;
695
696 case IWL_TM_CMD_APP2DEV_NOTIFICATIONS:
697 IWL_DEBUG_INFO(tst->trans, "test notifications cmd\n");
698 result = iwl_test_notifications(tst, tb);
699 break;
700
701 case IWL_TM_CMD_APP2DEV_GET_FW_VERSION:
702 IWL_DEBUG_INFO(tst->trans, "test get FW ver cmd\n");
703 result = iwl_test_get_fw_ver(tst, tb);
704 break;
705
706 case IWL_TM_CMD_APP2DEV_GET_DEVICE_ID:
707 IWL_DEBUG_INFO(tst->trans, "test Get device ID cmd\n");
708 result = iwl_test_get_dev_id(tst, tb);
709 break;
710
711 default:
712 IWL_DEBUG_INFO(tst->trans, "Unknown test command\n");
713 result = 1;
714 break;
715 }
716 return result;
717}
718IWL_EXPORT_SYMBOL(iwl_test_handle_cmd);
719
720static int iwl_test_trace_dump(struct iwl_test *tst, struct sk_buff *skb,
721 struct netlink_callback *cb)
722{
723 int idx, length;
724
725 if (!tst->trace.enabled || !tst->trace.trace_addr)
726 return -EFAULT;
727
728 idx = cb->args[4];
729 if (idx >= tst->trace.nchunks)
730 return -ENOENT;
731
732 length = DUMP_CHUNK_SIZE;
733 if (((idx + 1) == tst->trace.nchunks) &&
734 (tst->trace.size % DUMP_CHUNK_SIZE))
735 length = tst->trace.size %
736 DUMP_CHUNK_SIZE;
737
738 if (nla_put(skb, IWL_TM_ATTR_TRACE_DUMP, length,
739 tst->trace.trace_addr + (DUMP_CHUNK_SIZE * idx)))
740 goto nla_put_failure;
741
742 cb->args[4] = ++idx;
743 return 0;
744
745 nla_put_failure:
746 return -ENOBUFS;
747}
748
749static int iwl_test_buffer_dump(struct iwl_test *tst, struct sk_buff *skb,
750 struct netlink_callback *cb)
751{
752 int idx, length;
753
754 if (!tst->mem.in_read)
755 return -EFAULT;
756
757 idx = cb->args[4];
758 if (idx >= tst->mem.nchunks) {
759 iwl_test_mem_stop(tst);
760 return -ENOENT;
761 }
762
763 length = DUMP_CHUNK_SIZE;
764 if (((idx + 1) == tst->mem.nchunks) &&
765 (tst->mem.size % DUMP_CHUNK_SIZE))
766 length = tst->mem.size % DUMP_CHUNK_SIZE;
767
768 if (nla_put(skb, IWL_TM_ATTR_BUFFER_DUMP, length,
769 tst->mem.addr + (DUMP_CHUNK_SIZE * idx)))
770 goto nla_put_failure;
771
772 cb->args[4] = ++idx;
773 return 0;
774
775 nla_put_failure:
776 return -ENOBUFS;
777}
778
779/*
780 * Handle dump commands.
781 * Returns 1 for unknown commands (not handled by the test object); negative
782 * value in case of error.
783 */
784int iwl_test_dump(struct iwl_test *tst, u32 cmd, struct sk_buff *skb,
785 struct netlink_callback *cb)
786{
787 int result;
788
789 switch (cmd) {
790 case IWL_TM_CMD_APP2DEV_READ_TRACE:
791 IWL_DEBUG_INFO(tst->trans, "uCode trace cmd\n");
792 result = iwl_test_trace_dump(tst, skb, cb);
793 break;
794
795 case IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP:
796 IWL_DEBUG_INFO(tst->trans, "testmode sram dump cmd\n");
797 result = iwl_test_buffer_dump(tst, skb, cb);
798 break;
799
800 default:
801 result = 1;
802 break;
803 }
804 return result;
805}
806IWL_EXPORT_SYMBOL(iwl_test_dump);
807
808/*
809 * Multicast a spontaneous messages from the device to the user space.
810 */
811static void iwl_test_send_rx(struct iwl_test *tst,
812 struct iwl_rx_cmd_buffer *rxb)
813{
814 struct sk_buff *skb;
815 struct iwl_rx_packet *data;
816 int length;
817
818 data = rxb_addr(rxb);
819 length = le32_to_cpu(data->len_n_flags) & FH_RSCSR_FRAME_SIZE_MSK;
820
821 /* the length doesn't include len_n_flags field, so add it manually */
822 length += sizeof(__le32);
823
824 skb = iwl_test_alloc_event(tst, length + 20);
825 if (skb == NULL) {
826 IWL_ERR(tst->trans, "Out of memory for message to user\n");
827 return;
828 }
829
830 if (nla_put_u32(skb, IWL_TM_ATTR_COMMAND,
831 IWL_TM_CMD_DEV2APP_UCODE_RX_PKT) ||
832 nla_put(skb, IWL_TM_ATTR_UCODE_RX_PKT, length, data))
833 goto nla_put_failure;
834
835 iwl_test_event(tst, skb);
836 return;
837
838nla_put_failure:
839 kfree_skb(skb);
840 IWL_ERR(tst->trans, "Ouch, overran buffer, check allocation!\n");
841}
842
843/*
844 * Called whenever a Rx frames is recevied from the device. If notifications to
845 * the user space are requested, sends the frames to the user.
846 */
847void iwl_test_rx(struct iwl_test *tst, struct iwl_rx_cmd_buffer *rxb)
848{
849 if (tst->notify)
850 iwl_test_send_rx(tst, rxb);
851}
852IWL_EXPORT_SYMBOL(iwl_test_rx);
diff --git a/drivers/net/wireless/iwlwifi/iwl-test.h b/drivers/net/wireless/iwlwifi/iwl-test.h
deleted file mode 100644
index 8fbd21704840..000000000000
--- a/drivers/net/wireless/iwlwifi/iwl-test.h
+++ /dev/null
@@ -1,161 +0,0 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2010 - 2013 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called COPYING.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2010 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63
64#ifndef __IWL_TEST_H__
65#define __IWL_TEST_H__
66
67#include <linux/types.h>
68#include "iwl-trans.h"
69
70struct iwl_test_trace {
71 u32 size;
72 u32 tsize;
73 u32 nchunks;
74 u8 *cpu_addr;
75 u8 *trace_addr;
76 dma_addr_t dma_addr;
77 bool enabled;
78};
79
80struct iwl_test_mem {
81 u32 size;
82 u32 nchunks;
83 u8 *addr;
84 bool in_read;
85};
86
87/*
88 * struct iwl_test_ops: callback to the op mode
89 *
90 * The structure defines the callbacks that the op_mode should handle,
91 * inorder to handle logic that is out of the scope of iwl_test. The
92 * op_mode must set all the callbacks.
93
94 * @send_cmd: handler that is used by the test object to request the
95 * op_mode to send a command to the fw.
96 *
97 * @valid_hw_addr: handler that is used by the test object to request the
98 * op_mode to check if the given address is a valid address.
99 *
100 * @get_fw_ver: handler used to get the FW version.
101 *
102 * @alloc_reply: handler used by the test object to request the op_mode
103 * to allocate an skb for sending a reply to the user, and initialize
104 * the skb. It is assumed that the test object only fills the required
105 * attributes.
106 *
107 * @reply: handler used by the test object to request the op_mode to reply
108 * to a request. The skb is an skb previously allocated by the the
109 * alloc_reply callback.
110 I
111 * @alloc_event: handler used by the test object to request the op_mode
112 * to allocate an skb for sending an event, and initialize
113 * the skb. It is assumed that the test object only fills the required
114 * attributes.
115 *
116 * @reply: handler used by the test object to request the op_mode to send
117 * an event. The skb is an skb previously allocated by the the
118 * alloc_event callback.
119 */
120struct iwl_test_ops {
121 int (*send_cmd)(struct iwl_op_mode *op_modes,
122 struct iwl_host_cmd *cmd);
123 bool (*valid_hw_addr)(u32 addr);
124 u32 (*get_fw_ver)(struct iwl_op_mode *op_mode);
125
126 struct sk_buff *(*alloc_reply)(struct iwl_op_mode *op_mode, int len);
127 int (*reply)(struct iwl_op_mode *op_mode, struct sk_buff *skb);
128 struct sk_buff* (*alloc_event)(struct iwl_op_mode *op_mode, int len);
129 void (*event)(struct iwl_op_mode *op_mode, struct sk_buff *skb);
130};
131
132struct iwl_test {
133 struct iwl_trans *trans;
134 struct iwl_test_ops *ops;
135 struct iwl_test_trace trace;
136 struct iwl_test_mem mem;
137 bool notify;
138};
139
140void iwl_test_init(struct iwl_test *tst, struct iwl_trans *trans,
141 struct iwl_test_ops *ops);
142
143void iwl_test_free(struct iwl_test *tst);
144
145int iwl_test_parse(struct iwl_test *tst, struct nlattr **tb,
146 void *data, int len);
147
148int iwl_test_handle_cmd(struct iwl_test *tst, struct nlattr **tb);
149
150int iwl_test_dump(struct iwl_test *tst, u32 cmd, struct sk_buff *skb,
151 struct netlink_callback *cb);
152
153void iwl_test_rx(struct iwl_test *tst, struct iwl_rx_cmd_buffer *rxb);
154
155static inline void iwl_test_enable_notifications(struct iwl_test *tst,
156 bool enable)
157{
158 tst->notify = enable;
159}
160
161#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-testmode.h b/drivers/net/wireless/iwlwifi/iwl-testmode.h
deleted file mode 100644
index 98f48a9afc98..000000000000
--- a/drivers/net/wireless/iwlwifi/iwl-testmode.h
+++ /dev/null
@@ -1,309 +0,0 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2010 - 2013 Intel Corporation. All rights reserved.
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called COPYING.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2010 - 2013 Intel Corporation. All rights reserved.
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63#ifndef __IWL_TESTMODE_H__
64#define __IWL_TESTMODE_H__
65
66#include <linux/types.h>
67
68
69/*
70 * Commands from user space to kernel space(IWL_TM_CMD_ID_APP2DEV_XX) and
71 * from and kernel space to user space(IWL_TM_CMD_ID_DEV2APP_XX).
72 * The command ID is carried with IWL_TM_ATTR_COMMAND.
73 *
74 * @IWL_TM_CMD_APP2DEV_UCODE:
75 * commands from user application to the uCode,
76 * the actual uCode host command ID is carried with
77 * IWL_TM_ATTR_UCODE_CMD_ID
78 *
79 * @IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32:
80 * @IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32:
81 * @IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8:
82 * commands from user applicaiton to access register
83 *
84 * @IWL_TM_CMD_APP2DEV_GET_DEVICENAME: retrieve device name
85 * @IWL_TM_CMD_APP2DEV_LOAD_INIT_FW: load initial uCode image
86 * @IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB: perform calibration
87 * @IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW: load runtime uCode image
88 * @IWL_TM_CMD_APP2DEV_GET_EEPROM: request EEPROM data
89 * @IWL_TM_CMD_APP2DEV_FIXRATE_REQ: set fix MCS
90 * commands fom user space for pure driver level operations
91 *
92 * @IWL_TM_CMD_APP2DEV_BEGIN_TRACE:
93 * @IWL_TM_CMD_APP2DEV_END_TRACE:
94 * @IWL_TM_CMD_APP2DEV_READ_TRACE:
95 * commands fom user space for uCode trace operations
96 *
97 * @IWL_TM_CMD_DEV2APP_SYNC_RSP:
98 * commands from kernel space to carry the synchronous response
99 * to user application
100 * @IWL_TM_CMD_DEV2APP_UCODE_RX_PKT:
101 * commands from kernel space to multicast the spontaneous messages
102 * to user application, or reply of host commands
103 * @IWL_TM_CMD_DEV2APP_EEPROM_RSP:
104 * commands from kernel space to carry the eeprom response
105 * to user application
106 *
107 * @IWL_TM_CMD_APP2DEV_OWNERSHIP:
108 * commands from user application to own change the ownership of the uCode
109 * if application has the ownership, the only host command from
110 * testmode will deliver to uCode. Default owner is driver
111 *
112 * @IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW: load Wake On Wireless LAN uCode image
113 * @IWL_TM_CMD_APP2DEV_GET_FW_VERSION: retrieve uCode version
114 * @IWL_TM_CMD_APP2DEV_GET_DEVICE_ID: retrieve ID information in device
115 * @IWL_TM_CMD_APP2DEV_GET_FW_INFO:
116 * retrieve information of existing loaded uCode image
117 *
118 * @IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ:
119 * @IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP:
120 * @IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE:
121 * Commands to read/write data from periphery or SRAM memory ranges.
122 * Fore reading, a READ command is sent from the userspace and the data
123 * is returned when the user calls a DUMP command.
124 * For writing, only a WRITE command is used.
125 * @IWL_TM_CMD_APP2DEV_NOTIFICATIONS:
126 * Command to enable/disable notifications (currently RX packets) from the
127 * driver to userspace.
128 */
129enum iwl_tm_cmd_t {
130 IWL_TM_CMD_APP2DEV_UCODE = 1,
131 IWL_TM_CMD_APP2DEV_DIRECT_REG_READ32 = 2,
132 IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE32 = 3,
133 IWL_TM_CMD_APP2DEV_DIRECT_REG_WRITE8 = 4,
134 IWL_TM_CMD_APP2DEV_GET_DEVICENAME = 5,
135 IWL_TM_CMD_APP2DEV_LOAD_INIT_FW = 6,
136 IWL_TM_CMD_APP2DEV_CFG_INIT_CALIB = 7,
137 IWL_TM_CMD_APP2DEV_LOAD_RUNTIME_FW = 8,
138 IWL_TM_CMD_APP2DEV_GET_EEPROM = 9,
139 IWL_TM_CMD_APP2DEV_FIXRATE_REQ = 10,
140 IWL_TM_CMD_APP2DEV_BEGIN_TRACE = 11,
141 IWL_TM_CMD_APP2DEV_END_TRACE = 12,
142 IWL_TM_CMD_APP2DEV_READ_TRACE = 13,
143 IWL_TM_CMD_DEV2APP_SYNC_RSP = 14,
144 IWL_TM_CMD_DEV2APP_UCODE_RX_PKT = 15,
145 IWL_TM_CMD_DEV2APP_EEPROM_RSP = 16,
146 IWL_TM_CMD_APP2DEV_OWNERSHIP = 17,
147 RESERVED_18 = 18,
148 RESERVED_19 = 19,
149 RESERVED_20 = 20,
150 RESERVED_21 = 21,
151 IWL_TM_CMD_APP2DEV_LOAD_WOWLAN_FW = 22,
152 IWL_TM_CMD_APP2DEV_GET_FW_VERSION = 23,
153 IWL_TM_CMD_APP2DEV_GET_DEVICE_ID = 24,
154 IWL_TM_CMD_APP2DEV_GET_FW_INFO = 25,
155 IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ = 26,
156 IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP = 27,
157 IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE = 28,
158 IWL_TM_CMD_APP2DEV_NOTIFICATIONS = 29,
159 IWL_TM_CMD_MAX = 30,
160};
161
162/*
163 * Atrribute filed in testmode command
164 * See enum iwl_tm_cmd_t.
165 *
166 * @IWL_TM_ATTR_NOT_APPLICABLE:
167 * The attribute is not applicable or invalid
168 * @IWL_TM_ATTR_COMMAND:
169 * From user space to kernel space:
170 * the command either destines to ucode, driver, or register;
171 * From kernel space to user space:
172 * the command either carries synchronous response,
173 * or the spontaneous message multicast from the device;
174 *
175 * @IWL_TM_ATTR_UCODE_CMD_ID:
176 * @IWL_TM_ATTR_UCODE_CMD_DATA:
177 * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_UCODE,
178 * The mandatory fields are :
179 * IWL_TM_ATTR_UCODE_CMD_ID for recognizable command ID;
180 * IWL_TM_ATTR_UCODE_CMD_DATA for the actual command payload
181 * to the ucode
182 *
183 * @IWL_TM_ATTR_REG_OFFSET:
184 * @IWL_TM_ATTR_REG_VALUE8:
185 * @IWL_TM_ATTR_REG_VALUE32:
186 * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_REG_XXX,
187 * The mandatory fields are:
188 * IWL_TM_ATTR_REG_OFFSET for the offset of the target register;
189 * IWL_TM_ATTR_REG_VALUE8 or IWL_TM_ATTR_REG_VALUE32 for value
190 *
191 * @IWL_TM_ATTR_SYNC_RSP:
192 * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_DEV2APP_SYNC_RSP,
193 * The mandatory fields are:
194 * IWL_TM_ATTR_SYNC_RSP for the data content responding to the user
195 * application command
196 *
197 * @IWL_TM_ATTR_UCODE_RX_PKT:
198 * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_DEV2APP_UCODE_RX_PKT,
199 * The mandatory fields are:
200 * IWL_TM_ATTR_UCODE_RX_PKT for the data content multicast to the user
201 * application
202 *
203 * @IWL_TM_ATTR_EEPROM:
204 * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_DEV2APP_EEPROM,
205 * The mandatory fields are:
206 * IWL_TM_ATTR_EEPROM for the data content responging to the user
207 * application
208 *
209 * @IWL_TM_ATTR_TRACE_ADDR:
210 * @IWL_TM_ATTR_TRACE_SIZE:
211 * @IWL_TM_ATTR_TRACE_DUMP:
212 * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_XXX_TRACE,
213 * The mandatory fields are:
214 * IWL_TM_ATTR_MEM_TRACE_ADDR for the trace address
215 * IWL_TM_ATTR_MEM_TRACE_SIZE for the trace buffer size
216 * IWL_TM_ATTR_MEM_TRACE_DUMP for the trace dump
217 *
218 * @IWL_TM_ATTR_FIXRATE:
219 * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_FIXRATE_REQ,
220 * The mandatory fields are:
221 * IWL_TM_ATTR_FIXRATE for the fixed rate
222 *
223 * @IWL_TM_ATTR_UCODE_OWNER:
224 * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_OWNERSHIP,
225 * The mandatory fields are:
226 * IWL_TM_ATTR_UCODE_OWNER for the new owner
227 *
228 * @IWL_TM_ATTR_MEM_ADDR:
229 * @IWL_TM_ATTR_BUFFER_SIZE:
230 * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_READ
231 * or IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE.
232 * The mandatory fields are:
233 * IWL_TM_ATTR_MEM_ADDR for the address in SRAM/periphery to read/write
234 * IWL_TM_ATTR_BUFFER_SIZE for the buffer size of data to read/write.
235 *
236 * @IWL_TM_ATTR_BUFFER_DUMP:
237 * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_DUMP,
238 * IWL_TM_ATTR_BUFFER_DUMP is used for the data that was read.
239 * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_INDIRECT_BUFFER_WRITE,
240 * this attribute contains the data to write.
241 *
242 * @IWL_TM_ATTR_FW_VERSION:
243 * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_GET_FW_VERSION,
244 * IWL_TM_ATTR_FW_VERSION for the uCode version
245 *
246 * @IWL_TM_ATTR_DEVICE_ID:
247 * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_GET_DEVICE_ID,
248 * IWL_TM_ATTR_DEVICE_ID for the device ID information
249 *
250 * @IWL_TM_ATTR_FW_TYPE:
251 * @IWL_TM_ATTR_FW_INST_SIZE:
252 * @IWL_TM_ATTR_FW_DATA_SIZE:
253 * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_GET_FW_INFO,
254 * The mandatory fields are:
255 * IWL_TM_ATTR_FW_TYPE for the uCode type (INIT/RUNTIME/...)
256 * IWL_TM_ATTR_FW_INST_SIZE for the size of instruction section
257 * IWL_TM_ATTR_FW_DATA_SIZE for the size of data section
258 *
259 * @IWL_TM_ATTR_UCODE_CMD_SKB:
260 * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_UCODE this flag
261 * indicates that the user wants to receive the response of the command
262 * in a reply SKB. If it's not present, the response is not returned.
263 * @IWL_TM_ATTR_ENABLE_NOTIFICATIONS:
264 * When IWL_TM_ATTR_COMMAND is IWL_TM_CMD_APP2DEV_NOTIFICATIONS, this
265 * flag enables (if present) or disables (if not) the forwarding
266 * to userspace.
267 */
268enum iwl_tm_attr_t {
269 IWL_TM_ATTR_NOT_APPLICABLE = 0,
270 IWL_TM_ATTR_COMMAND = 1,
271 IWL_TM_ATTR_UCODE_CMD_ID = 2,
272 IWL_TM_ATTR_UCODE_CMD_DATA = 3,
273 IWL_TM_ATTR_REG_OFFSET = 4,
274 IWL_TM_ATTR_REG_VALUE8 = 5,
275 IWL_TM_ATTR_REG_VALUE32 = 6,
276 IWL_TM_ATTR_SYNC_RSP = 7,
277 IWL_TM_ATTR_UCODE_RX_PKT = 8,
278 IWL_TM_ATTR_EEPROM = 9,
279 IWL_TM_ATTR_TRACE_ADDR = 10,
280 IWL_TM_ATTR_TRACE_SIZE = 11,
281 IWL_TM_ATTR_TRACE_DUMP = 12,
282 IWL_TM_ATTR_FIXRATE = 13,
283 IWL_TM_ATTR_UCODE_OWNER = 14,
284 IWL_TM_ATTR_MEM_ADDR = 15,
285 IWL_TM_ATTR_BUFFER_SIZE = 16,
286 IWL_TM_ATTR_BUFFER_DUMP = 17,
287 IWL_TM_ATTR_FW_VERSION = 18,
288 IWL_TM_ATTR_DEVICE_ID = 19,
289 IWL_TM_ATTR_FW_TYPE = 20,
290 IWL_TM_ATTR_FW_INST_SIZE = 21,
291 IWL_TM_ATTR_FW_DATA_SIZE = 22,
292 IWL_TM_ATTR_UCODE_CMD_SKB = 23,
293 IWL_TM_ATTR_ENABLE_NOTIFICATION = 24,
294 IWL_TM_ATTR_MAX = 25,
295};
296
297/* uCode trace buffer */
298#define TRACE_BUFF_SIZE_MAX 0x200000
299#define TRACE_BUFF_SIZE_MIN 0x20000
300#define TRACE_BUFF_SIZE_DEF TRACE_BUFF_SIZE_MIN
301#define TRACE_BUFF_PADD 0x2000
302
303/* Maximum data size of each dump it packet */
304#define DUMP_CHUNK_SIZE (PAGE_SIZE - 1024)
305
306/* Address offset of data segment in SRAM */
307#define SRAM_DATA_SEG_OFFSET 0x800000
308
309#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index be4b2ac3dbbf..8d91422c5982 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -183,14 +183,12 @@ struct iwl_rx_packet {
183 * @CMD_ASYNC: Return right away and don't want for the response 183 * @CMD_ASYNC: Return right away and don't want for the response
184 * @CMD_WANT_SKB: valid only with CMD_SYNC. The caller needs the buffer of the 184 * @CMD_WANT_SKB: valid only with CMD_SYNC. The caller needs the buffer of the
185 * response. The caller needs to call iwl_free_resp when done. 185 * response. The caller needs to call iwl_free_resp when done.
186 * @CMD_ON_DEMAND: This command is sent by the test mode pipe.
187 */ 186 */
188enum CMD_MODE { 187enum CMD_MODE {
189 CMD_SYNC = 0, 188 CMD_SYNC = 0,
190 CMD_ASYNC = BIT(0), 189 CMD_ASYNC = BIT(0),
191 CMD_WANT_SKB = BIT(1), 190 CMD_WANT_SKB = BIT(1),
192 CMD_SEND_IN_RFKILL = BIT(2), 191 CMD_SEND_IN_RFKILL = BIT(2),
193 CMD_ON_DEMAND = BIT(3),
194}; 192};
195 193
196#define DEF_CMD_PAYLOAD_SIZE 320 194#define DEF_CMD_PAYLOAD_SIZE 320
diff --git a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
index 9a4d94a1f90d..dbd622a3929c 100644
--- a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
+++ b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
@@ -202,6 +202,22 @@ static const __le32 iwl_concurrent_lookup[BT_COEX_LUT_SIZE] = {
202 cpu_to_le32(0x00000000), 202 cpu_to_le32(0x00000000),
203}; 203};
204 204
205/* single shared antenna */
206static const __le32 iwl_single_shared_ant_lookup[BT_COEX_LUT_SIZE] = {
207 cpu_to_le32(0x40000000),
208 cpu_to_le32(0x00000000),
209 cpu_to_le32(0x44000000),
210 cpu_to_le32(0x00000000),
211 cpu_to_le32(0x40000000),
212 cpu_to_le32(0x00000000),
213 cpu_to_le32(0x44000000),
214 cpu_to_le32(0x00000000),
215 cpu_to_le32(0xC0004000),
216 cpu_to_le32(0xF0005000),
217 cpu_to_le32(0xC0004000),
218 cpu_to_le32(0xF0005000),
219};
220
205int iwl_send_bt_init_conf(struct iwl_mvm *mvm) 221int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
206{ 222{
207 struct iwl_bt_coex_cmd cmd = { 223 struct iwl_bt_coex_cmd cmd = {
@@ -225,7 +241,10 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
225 BT_VALID_REDUCED_TX_POWER | 241 BT_VALID_REDUCED_TX_POWER |
226 BT_VALID_LUT); 242 BT_VALID_LUT);
227 243
228 if (is_loose_coex()) 244 if (mvm->cfg->bt_shared_single_ant)
245 memcpy(&cmd.decision_lut, iwl_single_shared_ant_lookup,
246 sizeof(iwl_single_shared_ant_lookup));
247 else if (is_loose_coex())
229 memcpy(&cmd.decision_lut, iwl_loose_lookup, 248 memcpy(&cmd.decision_lut, iwl_loose_lookup,
230 sizeof(iwl_tight_lookup)); 249 sizeof(iwl_tight_lookup));
231 else 250 else
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c
index 8c49db02c9c1..7e5e5c2f9f87 100644
--- a/drivers/net/wireless/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/iwlwifi/mvm/d3.c
@@ -1026,6 +1026,12 @@ static int __iwl_mvm_suspend(struct ieee80211_hw *hw,
1026 if (ret) 1026 if (ret)
1027 goto out; 1027 goto out;
1028 1028
1029#ifdef CONFIG_IWLWIFI_DEBUGFS
1030 if (mvm->d3_wake_sysassert)
1031 d3_cfg_cmd_data.wakeup_flags |=
1032 cpu_to_le32(IWL_WAKEUP_D3_CONFIG_FW_ERROR);
1033#endif
1034
1029 /* must be last -- this switches firmware state */ 1035 /* must be last -- this switches firmware state */
1030 ret = iwl_mvm_send_cmd(mvm, &d3_cfg_cmd); 1036 ret = iwl_mvm_send_cmd(mvm, &d3_cfg_cmd);
1031 if (ret) 1037 if (ret)
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
index b7643c16201f..e56ed2a84888 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
@@ -344,6 +344,13 @@ static void iwl_dbgfs_update_pm(struct iwl_mvm *mvm,
344 case MVM_DEBUGFS_PM_DISABLE_POWER_OFF: 344 case MVM_DEBUGFS_PM_DISABLE_POWER_OFF:
345 IWL_DEBUG_POWER(mvm, "disable_power_off=%d\n", val); 345 IWL_DEBUG_POWER(mvm, "disable_power_off=%d\n", val);
346 dbgfs_pm->disable_power_off = val; 346 dbgfs_pm->disable_power_off = val;
347 case MVM_DEBUGFS_PM_LPRX_ENA:
348 IWL_DEBUG_POWER(mvm, "lprx %s\n", val ? "enabled" : "disabled");
349 dbgfs_pm->lprx_ena = val;
350 break;
351 case MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD:
352 IWL_DEBUG_POWER(mvm, "lprx_rssi_threshold=%d\n", val);
353 dbgfs_pm->lprx_rssi_threshold = val;
347 break; 354 break;
348 } 355 }
349} 356}
@@ -387,6 +394,17 @@ static ssize_t iwl_dbgfs_pm_params_write(struct file *file,
387 if (sscanf(buf + 18, "%d", &val) != 1) 394 if (sscanf(buf + 18, "%d", &val) != 1)
388 return -EINVAL; 395 return -EINVAL;
389 param = MVM_DEBUGFS_PM_DISABLE_POWER_OFF; 396 param = MVM_DEBUGFS_PM_DISABLE_POWER_OFF;
397 } else if (!strncmp("lprx=", buf, 5)) {
398 if (sscanf(buf + 5, "%d", &val) != 1)
399 return -EINVAL;
400 param = MVM_DEBUGFS_PM_LPRX_ENA;
401 } else if (!strncmp("lprx_rssi_threshold=", buf, 20)) {
402 if (sscanf(buf + 20, "%d", &val) != 1)
403 return -EINVAL;
404 if (val > POWER_LPRX_RSSI_THRESHOLD_MAX || val <
405 POWER_LPRX_RSSI_THRESHOLD_MIN)
406 return -EINVAL;
407 param = MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD;
390 } else { 408 } else {
391 return -EINVAL; 409 return -EINVAL;
392 } 410 }
@@ -421,7 +439,7 @@ static ssize_t iwl_dbgfs_pm_params_read(struct file *file,
421 le32_to_cpu(cmd.skip_dtim_periods)); 439 le32_to_cpu(cmd.skip_dtim_periods));
422 pos += scnprintf(buf+pos, bufsz-pos, "power_scheme = %d\n", 440 pos += scnprintf(buf+pos, bufsz-pos, "power_scheme = %d\n",
423 iwlmvm_mod_params.power_scheme); 441 iwlmvm_mod_params.power_scheme);
424 pos += scnprintf(buf+pos, bufsz-pos, "flags = %d\n", 442 pos += scnprintf(buf+pos, bufsz-pos, "flags = 0x%x\n",
425 le16_to_cpu(cmd.flags)); 443 le16_to_cpu(cmd.flags));
426 pos += scnprintf(buf+pos, bufsz-pos, "keep_alive = %d\n", 444 pos += scnprintf(buf+pos, bufsz-pos, "keep_alive = %d\n",
427 cmd.keep_alive_seconds); 445 cmd.keep_alive_seconds);
@@ -435,6 +453,10 @@ static ssize_t iwl_dbgfs_pm_params_read(struct file *file,
435 le32_to_cpu(cmd.rx_data_timeout)); 453 le32_to_cpu(cmd.rx_data_timeout));
436 pos += scnprintf(buf+pos, bufsz-pos, "tx_data_timeout = %d\n", 454 pos += scnprintf(buf+pos, bufsz-pos, "tx_data_timeout = %d\n",
437 le32_to_cpu(cmd.tx_data_timeout)); 455 le32_to_cpu(cmd.tx_data_timeout));
456 if (cmd.flags & cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK))
457 pos += scnprintf(buf+pos, bufsz-pos,
458 "lprx_rssi_threshold = %d\n",
459 le32_to_cpu(cmd.lprx_rssi_threshold));
438 } 460 }
439 461
440 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 462 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
@@ -939,6 +961,9 @@ int iwl_mvm_dbgfs_register(struct iwl_mvm *mvm, struct dentry *dbgfs_dir)
939#ifdef CONFIG_PM_SLEEP 961#ifdef CONFIG_PM_SLEEP
940 MVM_DEBUGFS_ADD_FILE(d3_sram, mvm->debugfs_dir, S_IRUSR | S_IWUSR); 962 MVM_DEBUGFS_ADD_FILE(d3_sram, mvm->debugfs_dir, S_IRUSR | S_IWUSR);
941 MVM_DEBUGFS_ADD_FILE(d3_test, mvm->debugfs_dir, S_IRUSR); 963 MVM_DEBUGFS_ADD_FILE(d3_test, mvm->debugfs_dir, S_IRUSR);
964 if (!debugfs_create_bool("d3_wake_sysassert", S_IRUSR | S_IWUSR,
965 mvm->debugfs_dir, &mvm->d3_wake_sysassert))
966 goto err;
942#endif 967#endif
943 968
944 /* 969 /*
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
index d8e19290b0f3..a6da359a80c3 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-power.h
@@ -66,6 +66,11 @@
66 66
67/* Power Management Commands, Responses, Notifications */ 67/* Power Management Commands, Responses, Notifications */
68 68
69/* Radio LP RX Energy Threshold measured in dBm */
70#define POWER_LPRX_RSSI_THRESHOLD 75
71#define POWER_LPRX_RSSI_THRESHOLD_MAX 94
72#define POWER_LPRX_RSSI_THRESHOLD_MIN 30
73
69/** 74/**
70 * enum iwl_scan_flags - masks for power table command flags 75 * enum iwl_scan_flags - masks for power table command flags
71 * @POWER_FLAGS_POWER_SAVE_ENA_MSK: '1' Allow to save power by turning off 76 * @POWER_FLAGS_POWER_SAVE_ENA_MSK: '1' Allow to save power by turning off
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
index 273b0cc197ab..94aae9c8562c 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
@@ -865,6 +865,30 @@ int iwl_mvm_mac_ctxt_beacon_changed(struct iwl_mvm *mvm,
865 return ret; 865 return ret;
866} 866}
867 867
868struct iwl_mvm_mac_ap_iterator_data {
869 struct iwl_mvm *mvm;
870 struct ieee80211_vif *vif;
871 u32 beacon_device_ts;
872 u16 beacon_int;
873};
874
875/* Find the beacon_device_ts and beacon_int for a managed interface */
876static void iwl_mvm_mac_ap_iterator(void *_data, u8 *mac,
877 struct ieee80211_vif *vif)
878{
879 struct iwl_mvm_mac_ap_iterator_data *data = _data;
880
881 if (vif->type != NL80211_IFTYPE_STATION || !vif->bss_conf.assoc)
882 return;
883
884 /* Station client has higher priority over P2P client*/
885 if (vif->p2p && data->beacon_device_ts)
886 return;
887
888 data->beacon_device_ts = vif->bss_conf.sync_device_ts;
889 data->beacon_int = vif->bss_conf.beacon_int;
890}
891
868/* 892/*
869 * Fill the specific data for mac context of type AP of P2P GO 893 * Fill the specific data for mac context of type AP of P2P GO
870 */ 894 */
@@ -874,6 +898,11 @@ static void iwl_mvm_mac_ctxt_cmd_fill_ap(struct iwl_mvm *mvm,
874 bool add) 898 bool add)
875{ 899{
876 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 900 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
901 struct iwl_mvm_mac_ap_iterator_data data = {
902 .mvm = mvm,
903 .vif = vif,
904 .beacon_device_ts = 0
905 };
877 906
878 ctxt_ap->bi = cpu_to_le32(vif->bss_conf.beacon_int); 907 ctxt_ap->bi = cpu_to_le32(vif->bss_conf.beacon_int);
879 ctxt_ap->bi_reciprocal = 908 ctxt_ap->bi_reciprocal =
@@ -887,16 +916,33 @@ static void iwl_mvm_mac_ctxt_cmd_fill_ap(struct iwl_mvm *mvm,
887 ctxt_ap->mcast_qid = cpu_to_le32(vif->cab_queue); 916 ctxt_ap->mcast_qid = cpu_to_le32(vif->cab_queue);
888 917
889 /* 918 /*
890 * Only read the system time when the MAC is being added, when we 919 * Only set the beacon time when the MAC is being added, when we
891 * just modify the MAC then we should keep the time -- the firmware 920 * just modify the MAC then we should keep the time -- the firmware
892 * can otherwise have a "jumping" TBTT. 921 * can otherwise have a "jumping" TBTT.
893 */ 922 */
894 if (add) 923 if (add) {
895 mvmvif->ap_beacon_time = 924 /*
896 iwl_read_prph(mvm->trans, DEVICE_SYSTEM_TIME_REG); 925 * If there is a station/P2P client interface which is
926 * associated, set the AP's TBTT far enough from the station's
927 * TBTT. Otherwise, set it to the current system time
928 */
929 ieee80211_iterate_active_interfaces_atomic(
930 mvm->hw, IEEE80211_IFACE_ITER_RESUME_ALL,
931 iwl_mvm_mac_ap_iterator, &data);
932
933 if (data.beacon_device_ts) {
934 u32 rand = (prandom_u32() % (80 - 20)) + 20;
935 mvmvif->ap_beacon_time = data.beacon_device_ts +
936 ieee80211_tu_to_usec(data.beacon_int * rand /
937 100);
938 } else {
939 mvmvif->ap_beacon_time =
940 iwl_read_prph(mvm->trans,
941 DEVICE_SYSTEM_TIME_REG);
942 }
943 }
897 944
898 ctxt_ap->beacon_time = cpu_to_le32(mvmvif->ap_beacon_time); 945 ctxt_ap->beacon_time = cpu_to_le32(mvmvif->ap_beacon_time);
899
900 ctxt_ap->beacon_tsf = 0; /* unused */ 946 ctxt_ap->beacon_tsf = 0; /* unused */
901 947
902 /* TODO: Assume that the beacon id == mac context id */ 948 /* TODO: Assume that the beacon id == mac context id */
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index c7409f159a36..d40d7db185d6 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -73,7 +73,6 @@
73#include "iwl-trans.h" 73#include "iwl-trans.h"
74#include "iwl-notif-wait.h" 74#include "iwl-notif-wait.h"
75#include "iwl-eeprom-parse.h" 75#include "iwl-eeprom-parse.h"
76#include "iwl-test.h"
77#include "iwl-trans.h" 76#include "iwl-trans.h"
78#include "sta.h" 77#include "sta.h"
79#include "fw-api.h" 78#include "fw-api.h"
@@ -159,6 +158,8 @@ enum iwl_dbgfs_pm_mask {
159 MVM_DEBUGFS_PM_RX_DATA_TIMEOUT = BIT(3), 158 MVM_DEBUGFS_PM_RX_DATA_TIMEOUT = BIT(3),
160 MVM_DEBUGFS_PM_TX_DATA_TIMEOUT = BIT(4), 159 MVM_DEBUGFS_PM_TX_DATA_TIMEOUT = BIT(4),
161 MVM_DEBUGFS_PM_DISABLE_POWER_OFF = BIT(5), 160 MVM_DEBUGFS_PM_DISABLE_POWER_OFF = BIT(5),
161 MVM_DEBUGFS_PM_LPRX_ENA = BIT(6),
162 MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD = BIT(7),
162}; 163};
163 164
164struct iwl_dbgfs_pm { 165struct iwl_dbgfs_pm {
@@ -168,6 +169,8 @@ struct iwl_dbgfs_pm {
168 bool skip_over_dtim; 169 bool skip_over_dtim;
169 u8 skip_dtim_periods; 170 u8 skip_dtim_periods;
170 bool disable_power_off; 171 bool disable_power_off;
172 bool lprx_ena;
173 u32 lprx_rssi_threshold;
171 int mask; 174 int mask;
172}; 175};
173 176
@@ -353,12 +356,14 @@ struct iwl_tt_params {
353 * @dynamic_smps: Is thermal throttling enabled dynamic_smps? 356 * @dynamic_smps: Is thermal throttling enabled dynamic_smps?
354 * @tx_backoff: The current thremal throttling tx backoff in uSec. 357 * @tx_backoff: The current thremal throttling tx backoff in uSec.
355 * @params: Parameters to configure the thermal throttling algorithm. 358 * @params: Parameters to configure the thermal throttling algorithm.
359 * @throttle: Is thermal throttling is active?
356 */ 360 */
357struct iwl_mvm_tt_mgmt { 361struct iwl_mvm_tt_mgmt {
358 struct delayed_work ct_kill_exit; 362 struct delayed_work ct_kill_exit;
359 bool dynamic_smps; 363 bool dynamic_smps;
360 u32 tx_backoff; 364 u32 tx_backoff;
361 const struct iwl_tt_params *params; 365 const struct iwl_tt_params *params;
366 bool throttle;
362}; 367};
363 368
364struct iwl_mvm { 369struct iwl_mvm {
@@ -461,6 +466,7 @@ struct iwl_mvm {
461 struct wiphy_wowlan_support wowlan; 466 struct wiphy_wowlan_support wowlan;
462 int gtk_ivlen, gtk_icvlen, ptk_ivlen, ptk_icvlen; 467 int gtk_ivlen, gtk_icvlen, ptk_ivlen, ptk_icvlen;
463#ifdef CONFIG_IWLWIFI_DEBUGFS 468#ifdef CONFIG_IWLWIFI_DEBUGFS
469 u32 d3_wake_sysassert; /* must be u32 for debugfs_create_bool */
464 bool d3_test_active; 470 bool d3_test_active;
465 bool store_d3_resume_sram; 471 bool store_d3_resume_sram;
466 void *d3_resume_sram; 472 void *d3_resume_sram;
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c
index 3760a33ca3a4..e7ca965a89b8 100644
--- a/drivers/net/wireless/iwlwifi/mvm/power.c
+++ b/drivers/net/wireless/iwlwifi/mvm/power.c
@@ -137,11 +137,12 @@ static void iwl_mvm_power_log(struct iwl_mvm *mvm,
137 le32_to_cpu(cmd->rx_data_timeout)); 137 le32_to_cpu(cmd->rx_data_timeout));
138 IWL_DEBUG_POWER(mvm, "Tx timeout = %u usec\n", 138 IWL_DEBUG_POWER(mvm, "Tx timeout = %u usec\n",
139 le32_to_cpu(cmd->tx_data_timeout)); 139 le32_to_cpu(cmd->tx_data_timeout));
140 IWL_DEBUG_POWER(mvm, "LP RX RSSI threshold = %u\n",
141 cmd->lprx_rssi_threshold);
142 if (cmd->flags & cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK)) 140 if (cmd->flags & cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK))
143 IWL_DEBUG_POWER(mvm, "DTIM periods to skip = %u\n", 141 IWL_DEBUG_POWER(mvm, "DTIM periods to skip = %u\n",
144 le32_to_cpu(cmd->skip_dtim_periods)); 142 le32_to_cpu(cmd->skip_dtim_periods));
143 if (cmd->flags & cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK))
144 IWL_DEBUG_POWER(mvm, "LP RX RSSI threshold = %u\n",
145 le32_to_cpu(cmd->lprx_rssi_threshold));
145 } 146 }
146} 147}
147 148
@@ -181,6 +182,14 @@ void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
181 182
182 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK); 183 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK);
183 184
185 if (vif->bss_conf.beacon_rate &&
186 (vif->bss_conf.beacon_rate->bitrate == 10 ||
187 vif->bss_conf.beacon_rate->bitrate == 60)) {
188 cmd->flags |= cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK);
189 cmd->lprx_rssi_threshold =
190 cpu_to_le32(POWER_LPRX_RSSI_THRESHOLD);
191 }
192
184 dtimper = hw->conf.ps_dtim_period ?: 1; 193 dtimper = hw->conf.ps_dtim_period ?: 1;
185 194
186 /* Check if radar detection is required on current channel */ 195 /* Check if radar detection is required on current channel */
@@ -236,6 +245,15 @@ void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
236 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS) 245 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_SKIP_DTIM_PERIODS)
237 cmd->skip_dtim_periods = 246 cmd->skip_dtim_periods =
238 cpu_to_le32(mvmvif->dbgfs_pm.skip_dtim_periods); 247 cpu_to_le32(mvmvif->dbgfs_pm.skip_dtim_periods);
248 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_LPRX_ENA) {
249 if (mvmvif->dbgfs_pm.lprx_ena)
250 cmd->flags |= cpu_to_le16(POWER_FLAGS_LPRX_ENA_MSK);
251 else
252 cmd->flags &= cpu_to_le16(~POWER_FLAGS_LPRX_ENA_MSK);
253 }
254 if (mvmvif->dbgfs_pm.mask & MVM_DEBUGFS_PM_LPRX_RSSI_THRESHOLD)
255 cmd->lprx_rssi_threshold =
256 cpu_to_le32(mvmvif->dbgfs_pm.lprx_rssi_threshold);
239#endif /* CONFIG_IWLWIFI_DEBUGFS */ 257#endif /* CONFIG_IWLWIFI_DEBUGFS */
240} 258}
241 259
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c
index 31587a318f8b..b328a988c130 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.c
@@ -412,24 +412,18 @@ static int rs_tl_turn_on_agg_for_tid(struct iwl_mvm *mvm,
412 return ret; 412 return ret;
413 } 413 }
414 414
415 if ((iwlwifi_mod_params.auto_agg) || (load > IWL_AGG_LOAD_THRESHOLD)) { 415 IWL_DEBUG_HT(mvm, "Starting Tx agg: STA: %pM tid: %d\n",
416 IWL_DEBUG_HT(mvm, "Starting Tx agg: STA: %pM tid: %d\n", 416 sta->addr, tid);
417 sta->addr, tid); 417 ret = ieee80211_start_tx_ba_session(sta, tid, 5000);
418 ret = ieee80211_start_tx_ba_session(sta, tid, 5000); 418 if (ret == -EAGAIN) {
419 if (ret == -EAGAIN) { 419 /*
420 /* 420 * driver and mac80211 is out of sync
421 * driver and mac80211 is out of sync 421 * this might be cause by reloading firmware
422 * this might be cause by reloading firmware 422 * stop the tx ba session here
423 * stop the tx ba session here 423 */
424 */ 424 IWL_ERR(mvm, "Fail start Tx agg on tid: %d\n",
425 IWL_ERR(mvm, "Fail start Tx agg on tid: %d\n", 425 tid);
426 tid); 426 ieee80211_stop_tx_ba_session(sta, tid);
427 ieee80211_stop_tx_ba_session(sta, tid);
428 }
429 } else {
430 IWL_DEBUG_HT(mvm,
431 "Aggregation not enabled for tid %d because load = %u\n",
432 tid, load);
433 } 427 }
434 return ret; 428 return ret;
435} 429}
diff --git a/drivers/net/wireless/iwlwifi/mvm/tt.c b/drivers/net/wireless/iwlwifi/mvm/tt.c
index a7e3b8ddf22b..d6ae7f16ac11 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tt.c
@@ -427,6 +427,7 @@ void iwl_mvm_tt_handler(struct iwl_mvm *mvm)
427 const struct iwl_tt_params *params = mvm->thermal_throttle.params; 427 const struct iwl_tt_params *params = mvm->thermal_throttle.params;
428 struct iwl_mvm_tt_mgmt *tt = &mvm->thermal_throttle; 428 struct iwl_mvm_tt_mgmt *tt = &mvm->thermal_throttle;
429 s32 temperature = mvm->temperature; 429 s32 temperature = mvm->temperature;
430 bool throttle_enable = false;
430 int i; 431 int i;
431 u32 tx_backoff; 432 u32 tx_backoff;
432 433
@@ -445,6 +446,7 @@ void iwl_mvm_tt_handler(struct iwl_mvm *mvm)
445 ieee80211_iterate_active_interfaces_atomic( 446 ieee80211_iterate_active_interfaces_atomic(
446 mvm->hw, IEEE80211_IFACE_ITER_NORMAL, 447 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
447 iwl_mvm_tt_smps_iterator, mvm); 448 iwl_mvm_tt_smps_iterator, mvm);
449 throttle_enable = true;
448 } else if (tt->dynamic_smps && 450 } else if (tt->dynamic_smps &&
449 temperature <= params->dynamic_smps_exit) { 451 temperature <= params->dynamic_smps_exit) {
450 IWL_DEBUG_TEMP(mvm, "Disable dynamic SMPS\n"); 452 IWL_DEBUG_TEMP(mvm, "Disable dynamic SMPS\n");
@@ -456,10 +458,12 @@ void iwl_mvm_tt_handler(struct iwl_mvm *mvm)
456 } 458 }
457 459
458 if (params->support_tx_protection) { 460 if (params->support_tx_protection) {
459 if (temperature >= params->tx_protection_entry) 461 if (temperature >= params->tx_protection_entry) {
460 iwl_mvm_tt_tx_protection(mvm, true); 462 iwl_mvm_tt_tx_protection(mvm, true);
461 else if (temperature <= params->tx_protection_exit) 463 throttle_enable = true;
464 } else if (temperature <= params->tx_protection_exit) {
462 iwl_mvm_tt_tx_protection(mvm, false); 465 iwl_mvm_tt_tx_protection(mvm, false);
466 }
463 } 467 }
464 468
465 if (params->support_tx_backoff) { 469 if (params->support_tx_backoff) {
@@ -469,9 +473,22 @@ void iwl_mvm_tt_handler(struct iwl_mvm *mvm)
469 break; 473 break;
470 tx_backoff = params->tx_backoff[i].backoff; 474 tx_backoff = params->tx_backoff[i].backoff;
471 } 475 }
476 if (tx_backoff != 0)
477 throttle_enable = true;
472 if (tt->tx_backoff != tx_backoff) 478 if (tt->tx_backoff != tx_backoff)
473 iwl_mvm_tt_tx_backoff(mvm, tx_backoff); 479 iwl_mvm_tt_tx_backoff(mvm, tx_backoff);
474 } 480 }
481
482 if (!tt->throttle && throttle_enable) {
483 IWL_WARN(mvm,
484 "Due to high temperature thermal throttling initiated\n");
485 tt->throttle = true;
486 } else if (tt->throttle && !tt->dynamic_smps && tt->tx_backoff == 0 &&
487 temperature <= params->tx_protection_exit) {
488 IWL_WARN(mvm,
489 "Temperature is back to normal thermal throttling stopped\n");
490 tt->throttle = false;
491 }
475} 492}
476 493
477static const struct iwl_tt_params iwl7000_tt_params = { 494static const struct iwl_tt_params iwl7000_tt_params = {
@@ -502,6 +519,7 @@ void iwl_mvm_tt_initialize(struct iwl_mvm *mvm)
502 519
503 IWL_DEBUG_TEMP(mvm, "Initialize Thermal Throttling\n"); 520 IWL_DEBUG_TEMP(mvm, "Initialize Thermal Throttling\n");
504 tt->params = &iwl7000_tt_params; 521 tt->params = &iwl7000_tt_params;
522 tt->throttle = false;
505 INIT_DELAYED_WORK(&tt->ct_kill_exit, check_exit_ctkill); 523 INIT_DELAYED_WORK(&tt->ct_kill_exit, check_exit_ctkill);
506} 524}
507 525
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c
index 3688dc5ba1ac..fd848cd1583e 100644
--- a/drivers/net/wireless/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/rx.c
@@ -110,9 +110,10 @@
110/* 110/*
111 * iwl_rxq_space - Return number of free slots available in queue. 111 * iwl_rxq_space - Return number of free slots available in queue.
112 */ 112 */
113static int iwl_rxq_space(const struct iwl_rxq *q) 113static int iwl_rxq_space(const struct iwl_rxq *rxq)
114{ 114{
115 int s = q->read - q->write; 115 int s = rxq->read - rxq->write;
116
116 if (s <= 0) 117 if (s <= 0)
117 s += RX_QUEUE_SIZE; 118 s += RX_QUEUE_SIZE;
118 /* keep some buffer to not confuse full and empty queue */ 119 /* keep some buffer to not confuse full and empty queue */
@@ -143,21 +144,22 @@ int iwl_pcie_rx_stop(struct iwl_trans *trans)
143/* 144/*
144 * iwl_pcie_rxq_inc_wr_ptr - Update the write pointer for the RX queue 145 * iwl_pcie_rxq_inc_wr_ptr - Update the write pointer for the RX queue
145 */ 146 */
146static void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans *trans, struct iwl_rxq *q) 147static void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans *trans,
148 struct iwl_rxq *rxq)
147{ 149{
148 unsigned long flags; 150 unsigned long flags;
149 u32 reg; 151 u32 reg;
150 152
151 spin_lock_irqsave(&q->lock, flags); 153 spin_lock_irqsave(&rxq->lock, flags);
152 154
153 if (q->need_update == 0) 155 if (rxq->need_update == 0)
154 goto exit_unlock; 156 goto exit_unlock;
155 157
156 if (trans->cfg->base_params->shadow_reg_enable) { 158 if (trans->cfg->base_params->shadow_reg_enable) {
157 /* shadow register enabled */ 159 /* shadow register enabled */
158 /* Device expects a multiple of 8 */ 160 /* Device expects a multiple of 8 */
159 q->write_actual = (q->write & ~0x7); 161 rxq->write_actual = (rxq->write & ~0x7);
160 iwl_write32(trans, FH_RSCSR_CHNL0_WPTR, q->write_actual); 162 iwl_write32(trans, FH_RSCSR_CHNL0_WPTR, rxq->write_actual);
161 } else { 163 } else {
162 struct iwl_trans_pcie *trans_pcie = 164 struct iwl_trans_pcie *trans_pcie =
163 IWL_TRANS_GET_PCIE_TRANS(trans); 165 IWL_TRANS_GET_PCIE_TRANS(trans);
@@ -175,22 +177,22 @@ static void iwl_pcie_rxq_inc_wr_ptr(struct iwl_trans *trans, struct iwl_rxq *q)
175 goto exit_unlock; 177 goto exit_unlock;
176 } 178 }
177 179
178 q->write_actual = (q->write & ~0x7); 180 rxq->write_actual = (rxq->write & ~0x7);
179 iwl_write_direct32(trans, FH_RSCSR_CHNL0_WPTR, 181 iwl_write_direct32(trans, FH_RSCSR_CHNL0_WPTR,
180 q->write_actual); 182 rxq->write_actual);
181 183
182 /* Else device is assumed to be awake */ 184 /* Else device is assumed to be awake */
183 } else { 185 } else {
184 /* Device expects a multiple of 8 */ 186 /* Device expects a multiple of 8 */
185 q->write_actual = (q->write & ~0x7); 187 rxq->write_actual = (rxq->write & ~0x7);
186 iwl_write_direct32(trans, FH_RSCSR_CHNL0_WPTR, 188 iwl_write_direct32(trans, FH_RSCSR_CHNL0_WPTR,
187 q->write_actual); 189 rxq->write_actual);
188 } 190 }
189 } 191 }
190 q->need_update = 0; 192 rxq->need_update = 0;
191 193
192 exit_unlock: 194 exit_unlock:
193 spin_unlock_irqrestore(&q->lock, flags); 195 spin_unlock_irqrestore(&rxq->lock, flags);
194} 196}
195 197
196/* 198/*
@@ -355,19 +357,16 @@ static void iwl_pcie_rxq_free_rbs(struct iwl_trans *trans)
355 struct iwl_rxq *rxq = &trans_pcie->rxq; 357 struct iwl_rxq *rxq = &trans_pcie->rxq;
356 int i; 358 int i;
357 359
358 /* Fill the rx_used queue with _all_ of the Rx buffers */ 360 lockdep_assert_held(&rxq->lock);
361
359 for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) { 362 for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++) {
360 /* In the reset function, these buffers may have been allocated 363 if (!rxq->pool[i].page)
361 * to an SKB, so we need to unmap and free potential storage */ 364 continue;
362 if (rxq->pool[i].page != NULL) { 365 dma_unmap_page(trans->dev, rxq->pool[i].page_dma,
363 dma_unmap_page(trans->dev, rxq->pool[i].page_dma, 366 PAGE_SIZE << trans_pcie->rx_page_order,
364 PAGE_SIZE << trans_pcie->rx_page_order, 367 DMA_FROM_DEVICE);
365 DMA_FROM_DEVICE); 368 __free_pages(rxq->pool[i].page, trans_pcie->rx_page_order);
366 __free_pages(rxq->pool[i].page, 369 rxq->pool[i].page = NULL;
367 trans_pcie->rx_page_order);
368 rxq->pool[i].page = NULL;
369 }
370 list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
371 } 370 }
372} 371}
373 372
@@ -491,6 +490,20 @@ static void iwl_pcie_rx_hw_init(struct iwl_trans *trans, struct iwl_rxq *rxq)
491 iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF); 490 iwl_write8(trans, CSR_INT_COALESCING, IWL_HOST_INT_TIMEOUT_DEF);
492} 491}
493 492
493static void iwl_pcie_rx_init_rxb_lists(struct iwl_rxq *rxq)
494{
495 int i;
496
497 lockdep_assert_held(&rxq->lock);
498
499 INIT_LIST_HEAD(&rxq->rx_free);
500 INIT_LIST_HEAD(&rxq->rx_used);
501 rxq->free_count = 0;
502
503 for (i = 0; i < RX_FREE_BUFFERS + RX_QUEUE_SIZE; i++)
504 list_add(&rxq->pool[i].list, &rxq->rx_used);
505}
506
494int iwl_pcie_rx_init(struct iwl_trans *trans) 507int iwl_pcie_rx_init(struct iwl_trans *trans)
495{ 508{
496 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 509 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
@@ -505,13 +518,12 @@ int iwl_pcie_rx_init(struct iwl_trans *trans)
505 } 518 }
506 519
507 spin_lock_irqsave(&rxq->lock, flags); 520 spin_lock_irqsave(&rxq->lock, flags);
508 INIT_LIST_HEAD(&rxq->rx_free);
509 INIT_LIST_HEAD(&rxq->rx_used);
510 521
511 INIT_WORK(&trans_pcie->rx_replenish, 522 INIT_WORK(&trans_pcie->rx_replenish, iwl_pcie_rx_replenish_work);
512 iwl_pcie_rx_replenish_work);
513 523
524 /* free all first - we might be reconfigured for a different size */
514 iwl_pcie_rxq_free_rbs(trans); 525 iwl_pcie_rxq_free_rbs(trans);
526 iwl_pcie_rx_init_rxb_lists(rxq);
515 527
516 for (i = 0; i < RX_QUEUE_SIZE; i++) 528 for (i = 0; i < RX_QUEUE_SIZE; i++)
517 rxq->queue[i] = NULL; 529 rxq->queue[i] = NULL;
@@ -520,7 +532,6 @@ int iwl_pcie_rx_init(struct iwl_trans *trans)
520 * not restocked the Rx queue with fresh buffers */ 532 * not restocked the Rx queue with fresh buffers */
521 rxq->read = rxq->write = 0; 533 rxq->read = rxq->write = 0;
522 rxq->write_actual = 0; 534 rxq->write_actual = 0;
523 rxq->free_count = 0;
524 memset(rxq->rb_stts, 0, sizeof(*rxq->rb_stts)); 535 memset(rxq->rb_stts, 0, sizeof(*rxq->rb_stts));
525 spin_unlock_irqrestore(&rxq->lock, flags); 536 spin_unlock_irqrestore(&rxq->lock, flags);
526 537
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index 197dbe0a868c..826c15602c46 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -838,8 +838,9 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, bool silent,
838 unsigned long *flags) 838 unsigned long *flags)
839{ 839{
840 int ret; 840 int ret;
841 struct iwl_trans_pcie *pcie_trans = IWL_TRANS_GET_PCIE_TRANS(trans); 841 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
842 spin_lock_irqsave(&pcie_trans->reg_lock, *flags); 842
843 spin_lock_irqsave(&trans_pcie->reg_lock, *flags);
843 844
844 /* this bit wakes up the NIC */ 845 /* this bit wakes up the NIC */
845 __iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL, 846 __iwl_trans_pcie_set_bit(trans, CSR_GP_CNTRL,
@@ -875,7 +876,7 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, bool silent,
875 WARN_ONCE(1, 876 WARN_ONCE(1,
876 "Timeout waiting for hardware access (CSR_GP_CNTRL 0x%08x)\n", 877 "Timeout waiting for hardware access (CSR_GP_CNTRL 0x%08x)\n",
877 val); 878 val);
878 spin_unlock_irqrestore(&pcie_trans->reg_lock, *flags); 879 spin_unlock_irqrestore(&trans_pcie->reg_lock, *flags);
879 return false; 880 return false;
880 } 881 }
881 } 882 }
@@ -884,22 +885,22 @@ static bool iwl_trans_pcie_grab_nic_access(struct iwl_trans *trans, bool silent,
884 * Fool sparse by faking we release the lock - sparse will 885 * Fool sparse by faking we release the lock - sparse will
885 * track nic_access anyway. 886 * track nic_access anyway.
886 */ 887 */
887 __release(&pcie_trans->reg_lock); 888 __release(&trans_pcie->reg_lock);
888 return true; 889 return true;
889} 890}
890 891
891static void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans, 892static void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans,
892 unsigned long *flags) 893 unsigned long *flags)
893{ 894{
894 struct iwl_trans_pcie *pcie_trans = IWL_TRANS_GET_PCIE_TRANS(trans); 895 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
895 896
896 lockdep_assert_held(&pcie_trans->reg_lock); 897 lockdep_assert_held(&trans_pcie->reg_lock);
897 898
898 /* 899 /*
899 * Fool sparse by faking we acquiring the lock - sparse will 900 * Fool sparse by faking we acquiring the lock - sparse will
900 * track nic_access anyway. 901 * track nic_access anyway.
901 */ 902 */
902 __acquire(&pcie_trans->reg_lock); 903 __acquire(&trans_pcie->reg_lock);
903 904
904 __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL, 905 __iwl_trans_pcie_clear_bit(trans, CSR_GP_CNTRL,
905 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ); 906 CSR_GP_CNTRL_REG_FLAG_MAC_ACCESS_REQ);
@@ -910,7 +911,7 @@ static void iwl_trans_pcie_release_nic_access(struct iwl_trans *trans,
910 * scheduled on different CPUs (after we drop reg_lock). 911 * scheduled on different CPUs (after we drop reg_lock).
911 */ 912 */
912 mmiowb(); 913 mmiowb();
913 spin_unlock_irqrestore(&pcie_trans->reg_lock, *flags); 914 spin_unlock_irqrestore(&trans_pcie->reg_lock, *flags);
914} 915}
915 916
916static int iwl_trans_pcie_read_mem(struct iwl_trans *trans, u32 addr, 917static int iwl_trans_pcie_read_mem(struct iwl_trans *trans, u32 addr,
diff --git a/drivers/net/wireless/rt2x00/rt2800.h b/drivers/net/wireless/rt2x00/rt2800.h
index a7630d5ec892..d78c495a86a0 100644
--- a/drivers/net/wireless/rt2x00/rt2800.h
+++ b/drivers/net/wireless/rt2x00/rt2800.h
@@ -100,7 +100,7 @@
100#define CSR_REG_BASE 0x1000 100#define CSR_REG_BASE 0x1000
101#define CSR_REG_SIZE 0x0800 101#define CSR_REG_SIZE 0x0800
102#define EEPROM_BASE 0x0000 102#define EEPROM_BASE 0x0000
103#define EEPROM_SIZE 0x0110 103#define EEPROM_SIZE 0x0200
104#define BBP_BASE 0x0000 104#define BBP_BASE 0x0000
105#define BBP_SIZE 0x00ff 105#define BBP_SIZE 0x00ff
106#define RF_BASE 0x0004 106#define RF_BASE 0x0004
@@ -2625,11 +2625,13 @@ struct mac_iveiv_entry {
2625/* 2625/*
2626 * DMA descriptor defines. 2626 * DMA descriptor defines.
2627 */ 2627 */
2628#define TXWI_DESC_SIZE (4 * sizeof(__le32))
2629#define RXWI_DESC_SIZE (4 * sizeof(__le32))
2630 2628
2631#define TXWI_DESC_SIZE_5592 (5 * sizeof(__le32)) 2629#define TXWI_DESC_SIZE_4WORDS (4 * sizeof(__le32))
2632#define RXWI_DESC_SIZE_5592 (6 * sizeof(__le32)) 2630#define TXWI_DESC_SIZE_5WORDS (5 * sizeof(__le32))
2631
2632#define RXWI_DESC_SIZE_4WORDS (4 * sizeof(__le32))
2633#define RXWI_DESC_SIZE_6WORDS (6 * sizeof(__le32))
2634
2633/* 2635/*
2634 * TX WI structure 2636 * TX WI structure
2635 */ 2637 */
diff --git a/drivers/net/wireless/rt2x00/rt2800lib.c b/drivers/net/wireless/rt2x00/rt2800lib.c
index 3aa30ddcbfea..1f80ea5e29dd 100644
--- a/drivers/net/wireless/rt2x00/rt2800lib.c
+++ b/drivers/net/wireless/rt2x00/rt2800lib.c
@@ -2392,7 +2392,7 @@ static void rt2800_config_channel_rf55xx(struct rt2x00_dev *rt2x00dev,
2392 rt2800_rfcsr_write(rt2x00dev, 49, rfcsr); 2392 rt2800_rfcsr_write(rt2x00dev, 49, rfcsr);
2393 2393
2394 rt2800_rfcsr_read(rt2x00dev, 50, &rfcsr); 2394 rt2800_rfcsr_read(rt2x00dev, 50, &rfcsr);
2395 if (info->default_power1 > power_bound) 2395 if (info->default_power2 > power_bound)
2396 rt2x00_set_field8(&rfcsr, RFCSR50_TX, power_bound); 2396 rt2x00_set_field8(&rfcsr, RFCSR50_TX, power_bound);
2397 else 2397 else
2398 rt2x00_set_field8(&rfcsr, RFCSR50_TX, info->default_power2); 2398 rt2x00_set_field8(&rfcsr, RFCSR50_TX, info->default_power2);
@@ -2678,30 +2678,53 @@ static void rt2800_config_channel(struct rt2x00_dev *rt2x00dev,
2678 2678
2679 tx_pin = 0; 2679 tx_pin = 0;
2680 2680
2681 /* Turn on unused PA or LNA when not using 1T or 1R */ 2681 switch (rt2x00dev->default_ant.tx_chain_num) {
2682 if (rt2x00dev->default_ant.tx_chain_num == 2) { 2682 case 3:
2683 /* Turn on tertiary PAs */
2684 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A2_EN,
2685 rf->channel > 14);
2686 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G2_EN,
2687 rf->channel <= 14);
2688 /* fall-through */
2689 case 2:
2690 /* Turn on secondary PAs */
2683 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A1_EN, 2691 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A1_EN,
2684 rf->channel > 14); 2692 rf->channel > 14);
2685 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G1_EN, 2693 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G1_EN,
2686 rf->channel <= 14); 2694 rf->channel <= 14);
2695 /* fall-through */
2696 case 1:
2697 /* Turn on primary PAs */
2698 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A0_EN,
2699 rf->channel > 14);
2700 if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags))
2701 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G0_EN, 1);
2702 else
2703 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G0_EN,
2704 rf->channel <= 14);
2705 break;
2687 } 2706 }
2688 2707
2689 /* Turn on unused PA or LNA when not using 1T or 1R */ 2708 switch (rt2x00dev->default_ant.rx_chain_num) {
2690 if (rt2x00dev->default_ant.rx_chain_num == 2) { 2709 case 3:
2710 /* Turn on tertiary LNAs */
2711 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A2_EN, 1);
2712 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G2_EN, 1);
2713 /* fall-through */
2714 case 2:
2715 /* Turn on secondary LNAs */
2691 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A1_EN, 1); 2716 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A1_EN, 1);
2692 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G1_EN, 1); 2717 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G1_EN, 1);
2718 /* fall-through */
2719 case 1:
2720 /* Turn on primary LNAs */
2721 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A0_EN, 1);
2722 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G0_EN, 1);
2723 break;
2693 } 2724 }
2694 2725
2695 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_A0_EN, 1);
2696 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_LNA_PE_G0_EN, 1);
2697 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_RFTR_EN, 1); 2726 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_RFTR_EN, 1);
2698 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_TRSW_EN, 1); 2727 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_TRSW_EN, 1);
2699 if (test_bit(CAPABILITY_BT_COEXIST, &rt2x00dev->cap_flags))
2700 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G0_EN, 1);
2701 else
2702 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_G0_EN,
2703 rf->channel <= 14);
2704 rt2x00_set_field32(&tx_pin, TX_PIN_CFG_PA_PE_A0_EN, rf->channel > 14);
2705 2728
2706 rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin); 2729 rt2800_register_write(rt2x00dev, TX_PIN_CFG, tx_pin);
2707 2730
@@ -6254,8 +6277,8 @@ static int rt2800_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
6254 default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2); 6277 default_power2 = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A2);
6255 6278
6256 for (i = 14; i < spec->num_channels; i++) { 6279 for (i = 14; i < spec->num_channels; i++) {
6257 info[i].default_power1 = default_power1[i]; 6280 info[i].default_power1 = default_power1[i - 14];
6258 info[i].default_power2 = default_power2[i]; 6281 info[i].default_power2 = default_power2[i - 14];
6259 } 6282 }
6260 } 6283 }
6261 6284
diff --git a/drivers/net/wireless/rt2x00/rt2800pci.c b/drivers/net/wireless/rt2x00/rt2800pci.c
index 7c7478219bbc..00055627eb8d 100644
--- a/drivers/net/wireless/rt2x00/rt2800pci.c
+++ b/drivers/net/wireless/rt2x00/rt2800pci.c
@@ -637,6 +637,7 @@ static void rt2800pci_write_tx_desc(struct queue_entry *entry,
637 struct queue_entry_priv_mmio *entry_priv = entry->priv_data; 637 struct queue_entry_priv_mmio *entry_priv = entry->priv_data;
638 __le32 *txd = entry_priv->desc; 638 __le32 *txd = entry_priv->desc;
639 u32 word; 639 u32 word;
640 const unsigned int txwi_size = entry->queue->winfo_size;
640 641
641 /* 642 /*
642 * The buffers pointed by SD_PTR0/SD_LEN0 and SD_PTR1/SD_LEN1 643 * The buffers pointed by SD_PTR0/SD_LEN0 and SD_PTR1/SD_LEN1
@@ -659,14 +660,14 @@ static void rt2800pci_write_tx_desc(struct queue_entry *entry,
659 !test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags)); 660 !test_bit(ENTRY_TXD_MORE_FRAG, &txdesc->flags));
660 rt2x00_set_field32(&word, TXD_W1_BURST, 661 rt2x00_set_field32(&word, TXD_W1_BURST,
661 test_bit(ENTRY_TXD_BURST, &txdesc->flags)); 662 test_bit(ENTRY_TXD_BURST, &txdesc->flags));
662 rt2x00_set_field32(&word, TXD_W1_SD_LEN0, TXWI_DESC_SIZE); 663 rt2x00_set_field32(&word, TXD_W1_SD_LEN0, txwi_size);
663 rt2x00_set_field32(&word, TXD_W1_LAST_SEC0, 0); 664 rt2x00_set_field32(&word, TXD_W1_LAST_SEC0, 0);
664 rt2x00_set_field32(&word, TXD_W1_DMA_DONE, 0); 665 rt2x00_set_field32(&word, TXD_W1_DMA_DONE, 0);
665 rt2x00_desc_write(txd, 1, word); 666 rt2x00_desc_write(txd, 1, word);
666 667
667 word = 0; 668 word = 0;
668 rt2x00_set_field32(&word, TXD_W2_SD_PTR1, 669 rt2x00_set_field32(&word, TXD_W2_SD_PTR1,
669 skbdesc->skb_dma + TXWI_DESC_SIZE); 670 skbdesc->skb_dma + txwi_size);
670 rt2x00_desc_write(txd, 2, word); 671 rt2x00_desc_write(txd, 2, word);
671 672
672 word = 0; 673 word = 0;
@@ -1193,7 +1194,7 @@ static void rt2800pci_queue_init(struct data_queue *queue)
1193 queue->limit = 128; 1194 queue->limit = 128;
1194 queue->data_size = AGGREGATION_SIZE; 1195 queue->data_size = AGGREGATION_SIZE;
1195 queue->desc_size = RXD_DESC_SIZE; 1196 queue->desc_size = RXD_DESC_SIZE;
1196 queue->winfo_size = RXWI_DESC_SIZE; 1197 queue->winfo_size = RXWI_DESC_SIZE_4WORDS;
1197 queue->priv_size = sizeof(struct queue_entry_priv_mmio); 1198 queue->priv_size = sizeof(struct queue_entry_priv_mmio);
1198 break; 1199 break;
1199 1200
@@ -1204,7 +1205,7 @@ static void rt2800pci_queue_init(struct data_queue *queue)
1204 queue->limit = 64; 1205 queue->limit = 64;
1205 queue->data_size = AGGREGATION_SIZE; 1206 queue->data_size = AGGREGATION_SIZE;
1206 queue->desc_size = TXD_DESC_SIZE; 1207 queue->desc_size = TXD_DESC_SIZE;
1207 queue->winfo_size = TXWI_DESC_SIZE; 1208 queue->winfo_size = TXWI_DESC_SIZE_4WORDS;
1208 queue->priv_size = sizeof(struct queue_entry_priv_mmio); 1209 queue->priv_size = sizeof(struct queue_entry_priv_mmio);
1209 break; 1210 break;
1210 1211
@@ -1212,7 +1213,7 @@ static void rt2800pci_queue_init(struct data_queue *queue)
1212 queue->limit = 8; 1213 queue->limit = 8;
1213 queue->data_size = 0; /* No DMA required for beacons */ 1214 queue->data_size = 0; /* No DMA required for beacons */
1214 queue->desc_size = TXD_DESC_SIZE; 1215 queue->desc_size = TXD_DESC_SIZE;
1215 queue->winfo_size = TXWI_DESC_SIZE; 1216 queue->winfo_size = TXWI_DESC_SIZE_4WORDS;
1216 queue->priv_size = sizeof(struct queue_entry_priv_mmio); 1217 queue->priv_size = sizeof(struct queue_entry_priv_mmio);
1217 break; 1218 break;
1218 1219
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 7edd903dd749..840833b26bfa 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -855,11 +855,11 @@ static void rt2800usb_queue_init(struct data_queue *queue)
855 unsigned short txwi_size, rxwi_size; 855 unsigned short txwi_size, rxwi_size;
856 856
857 if (rt2x00_rt(rt2x00dev, RT5592)) { 857 if (rt2x00_rt(rt2x00dev, RT5592)) {
858 txwi_size = TXWI_DESC_SIZE_5592; 858 txwi_size = TXWI_DESC_SIZE_5WORDS;
859 rxwi_size = RXWI_DESC_SIZE_5592; 859 rxwi_size = RXWI_DESC_SIZE_6WORDS;
860 } else { 860 } else {
861 txwi_size = TXWI_DESC_SIZE; 861 txwi_size = TXWI_DESC_SIZE_4WORDS;
862 rxwi_size = RXWI_DESC_SIZE; 862 rxwi_size = RXWI_DESC_SIZE_4WORDS;
863 } 863 }
864 864
865 switch (queue->qid) { 865 switch (queue->qid) {
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c
index 53754bc66d05..54d3ddfc9888 100644
--- a/drivers/net/wireless/rt2x00/rt61pci.c
+++ b/drivers/net/wireless/rt2x00/rt61pci.c
@@ -2825,7 +2825,8 @@ static int rt61pci_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
2825 tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); 2825 tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START);
2826 for (i = 14; i < spec->num_channels; i++) { 2826 for (i = 14; i < spec->num_channels; i++) {
2827 info[i].max_power = MAX_TXPOWER; 2827 info[i].max_power = MAX_TXPOWER;
2828 info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]); 2828 info[i].default_power1 =
2829 TXPOWER_FROM_DEV(tx_power[i - 14]);
2829 } 2830 }
2830 } 2831 }
2831 2832
diff --git a/drivers/net/wireless/rt2x00/rt73usb.c b/drivers/net/wireless/rt2x00/rt73usb.c
index 1616ed484ceb..1d3880e09a13 100644
--- a/drivers/net/wireless/rt2x00/rt73usb.c
+++ b/drivers/net/wireless/rt2x00/rt73usb.c
@@ -2167,7 +2167,8 @@ static int rt73usb_probe_hw_mode(struct rt2x00_dev *rt2x00dev)
2167 tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START); 2167 tx_power = rt2x00_eeprom_addr(rt2x00dev, EEPROM_TXPOWER_A_START);
2168 for (i = 14; i < spec->num_channels; i++) { 2168 for (i = 14; i < spec->num_channels; i++) {
2169 info[i].max_power = MAX_TXPOWER; 2169 info[i].max_power = MAX_TXPOWER;
2170 info[i].default_power1 = TXPOWER_FROM_DEV(tx_power[i]); 2170 info[i].default_power1 =
2171 TXPOWER_FROM_DEV(tx_power[i - 14]);
2171 } 2172 }
2172 } 2173 }
2173 2174
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c b/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c
index e4c4cdc3eb67..d9ee2efffe5f 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/sw.c
@@ -251,7 +251,7 @@ static struct rtl_hal_cfg rtl8723ae_hal_cfg = {
251 .bar_id = 2, 251 .bar_id = 2,
252 .write_readback = true, 252 .write_readback = true,
253 .name = "rtl8723ae_pci", 253 .name = "rtl8723ae_pci",
254 .fw_name = "rtlwifi/rtl8723aefw.bin", 254 .fw_name = "rtlwifi/rtl8723fw.bin",
255 .ops = &rtl8723ae_hal_ops, 255 .ops = &rtl8723ae_hal_ops,
256 .mod_params = &rtl8723ae_mod_params, 256 .mod_params = &rtl8723ae_mod_params,
257 .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL, 257 .maps[SYS_ISO_CTRL] = REG_SYS_ISO_CTRL,
@@ -353,8 +353,8 @@ MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");
353MODULE_AUTHOR("Larry Finger <Larry.Finger@lwfinger.net>"); 353MODULE_AUTHOR("Larry Finger <Larry.Finger@lwfinger.net>");
354MODULE_LICENSE("GPL"); 354MODULE_LICENSE("GPL");
355MODULE_DESCRIPTION("Realtek 8723E 802.11n PCI wireless"); 355MODULE_DESCRIPTION("Realtek 8723E 802.11n PCI wireless");
356MODULE_FIRMWARE("rtlwifi/rtl8723aefw.bin"); 356MODULE_FIRMWARE("rtlwifi/rtl8723fw.bin");
357MODULE_FIRMWARE("rtlwifi/rtl8723aefw_B.bin"); 357MODULE_FIRMWARE("rtlwifi/rtl8723fw_B.bin");
358 358
359module_param_named(swenc, rtl8723ae_mod_params.sw_crypto, bool, 0444); 359module_param_named(swenc, rtl8723ae_mod_params.sw_crypto, bool, 0444);
360module_param_named(debug, rtl8723ae_mod_params.debug, int, 0444); 360module_param_named(debug, rtl8723ae_mod_params.debug, int, 0444);