aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/ath/ar5523/ar5523.c9
-rw-r--r--drivers/net/wireless/ath/ar5523/ar5523.h1
-rw-r--r--drivers/net/wireless/ath/ath.h3
-rw-r--r--drivers/net/wireless/ath/ath5k/ath5k.h1
-rw-r--r--drivers/net/wireless/ath/ath5k/base.c31
-rw-r--r--drivers/net/wireless/ath/ath5k/reset.c24
-rw-r--r--drivers/net/wireless/ath/ath9k/Makefile3
-rw-r--r--drivers/net/wireless/ath/ath9k/ani.c20
-rw-r--r--drivers/net/wireless/ath/ath9k/ar5008_phy.c5
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_calib.c77
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_aic.c599
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_aic.h61
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_hw.c84
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mci.c20
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_phy.h25
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_rtt.c6
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h2
-rw-r--r--drivers/net/wireless/ath/ath9k/btcoex.h12
-rw-r--r--drivers/net/wireless/ath/ath9k/calib.c19
-rw-r--r--drivers/net/wireless/ath/ath9k/dfs.c44
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom.c7
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_4k.c36
-rw-r--r--drivers/net/wireless/ath/ath9k/eeprom_def.c34
-rw-r--r--drivers/net/wireless/ath/ath9k/htc.h5
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_init.c142
-rw-r--r--drivers/net/wireless/ath/ath9k/hw-ops.h8
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c37
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h31
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c23
-rw-r--r--drivers/net/wireless/ath/ath9k/reg_aic.h168
-rw-r--r--drivers/net/wireless/ath/ath9k/wmi.c3
-rw-r--r--drivers/net/wireless/ath/ath9k/wmi.h16
-rw-r--r--drivers/net/wireless/ath/dfs_pattern_detector.c2
-rw-r--r--drivers/net/wireless/ath/wil6210/cfg80211.c34
-rw-r--r--drivers/net/wireless/ath/wil6210/debugfs.c19
-rw-r--r--drivers/net/wireless/ath/wil6210/main.c36
-rw-r--r--drivers/net/wireless/ath/wil6210/netdev.c4
-rw-r--r--drivers/net/wireless/ath/wil6210/pcie_bus.c2
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.c302
-rw-r--r--drivers/net/wireless/ath/wil6210/wil6210.h8
-rw-r--r--drivers/net/wireless/ath/wil6210/wmi.c16
-rw-r--r--drivers/net/wireless/ath/wil6210/wmi.h23
-rw-r--r--drivers/net/wireless/b43/main.c2
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c8
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/chip.c310
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/chip.h12
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c5
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/msgbuf.h8
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/pcie.c24
-rw-r--r--drivers/net/wireless/brcm80211/brcmfmac/sdio.c199
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/main.c2
-rw-r--r--drivers/net/wireless/brcm80211/include/brcm_hw_ids.h2
-rw-r--r--drivers/net/wireless/brcm80211/include/chipcommon.h9
-rw-r--r--drivers/net/wireless/cw1200/cw1200_spi.c11
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/mac80211.c17
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/rs.c7
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/tx.c6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-7000.c8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-8000.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-debug.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.c22
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h1
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw-file.h8
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-modparams.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-nvm-parse.c411
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-nvm-parse.h19
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-prph.h27
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h15
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/coex.c220
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/coex_legacy.c61
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/d3.c19
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs.c26
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h47
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api.h107
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw.c10
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c180
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h63
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/nvm.c290
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c11
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/power.c6
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/quota.c3
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.c96
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sf.c67
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.c5
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/time-event.c22
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/utils.c2
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/drv.c27
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/internal.h4
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c157
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/tx.c63
-rw-r--r--drivers/net/wireless/libertas_tf/if_usb.c2
-rw-r--r--drivers/net/wireless/mwifiex/11n.c18
-rw-r--r--drivers/net/wireless/mwifiex/11n.h32
-rw-r--r--drivers/net/wireless/mwifiex/11n_aggr.c16
-rw-r--r--drivers/net/wireless/mwifiex/11n_rxreorder.c7
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c167
-rw-r--r--drivers/net/wireless/mwifiex/decl.h10
-rw-r--r--drivers/net/wireless/mwifiex/fw.h11
-rw-r--r--drivers/net/wireless/mwifiex/init.c26
-rw-r--r--drivers/net/wireless/mwifiex/main.c76
-rw-r--r--drivers/net/wireless/mwifiex/main.h30
-rw-r--r--drivers/net/wireless/mwifiex/pcie.c31
-rw-r--r--drivers/net/wireless/mwifiex/sdio.c226
-rw-r--r--drivers/net/wireless/mwifiex/sdio.h14
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmd.c61
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmdresp.c21
-rw-r--r--drivers/net/wireless/mwifiex/sta_event.c4
-rw-r--r--drivers/net/wireless/mwifiex/txrx.c128
-rw-r--r--drivers/net/wireless/mwifiex/usb.c6
-rw-r--r--drivers/net/wireless/mwifiex/util.c4
-rw-r--r--drivers/net/wireless/mwifiex/wmm.c48
-rw-r--r--drivers/net/wireless/mwifiex/wmm.h2
-rw-r--r--drivers/net/wireless/rt2x00/rt2800usb.c13
-rw-r--r--drivers/net/wireless/rt2x00/rt2x00usb.h4
-rw-r--r--drivers/net/wireless/rtlwifi/base.h1
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8188ee/hw.c5
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/hw.c7
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/mac.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192cu/sw.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/hw.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192ee/hw.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192se/hw.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/hw.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723be/hw.c2
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8821ae/hw.c4
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8821ae/trx.c16
-rw-r--r--drivers/net/wireless/rtlwifi/stats.c24
-rw-r--r--drivers/net/wireless/rtlwifi/stats.h1
-rw-r--r--drivers/net/wireless/ti/wl18xx/debugfs.c2
-rw-r--r--drivers/net/wireless/ti/wlcore/debugfs.h4
132 files changed, 4370 insertions, 1298 deletions
diff --git a/drivers/net/wireless/ath/ar5523/ar5523.c b/drivers/net/wireless/ath/ar5523/ar5523.c
index f92050617ae6..5147ebe4cd05 100644
--- a/drivers/net/wireless/ath/ar5523/ar5523.c
+++ b/drivers/net/wireless/ath/ar5523/ar5523.c
@@ -779,8 +779,6 @@ static void ar5523_tx(struct ieee80211_hw *hw,
779 ieee80211_stop_queues(hw); 779 ieee80211_stop_queues(hw);
780 } 780 }
781 781
782 data->skb = skb;
783
784 spin_lock_irqsave(&ar->tx_data_list_lock, flags); 782 spin_lock_irqsave(&ar->tx_data_list_lock, flags);
785 list_add_tail(&data->list, &ar->tx_queue_pending); 783 list_add_tail(&data->list, &ar->tx_queue_pending);
786 spin_unlock_irqrestore(&ar->tx_data_list_lock, flags); 784 spin_unlock_irqrestore(&ar->tx_data_list_lock, flags);
@@ -817,10 +815,13 @@ static void ar5523_tx_work_locked(struct ar5523 *ar)
817 if (!data) 815 if (!data)
818 break; 816 break;
819 817
820 skb = data->skb; 818 txi = container_of((void *)data, struct ieee80211_tx_info,
819 driver_data);
821 txqid = 0; 820 txqid = 0;
822 txi = IEEE80211_SKB_CB(skb); 821
822 skb = container_of((void *)txi, struct sk_buff, cb);
823 paylen = skb->len; 823 paylen = skb->len;
824
824 urb = usb_alloc_urb(0, GFP_KERNEL); 825 urb = usb_alloc_urb(0, GFP_KERNEL);
825 if (!urb) { 826 if (!urb) {
826 ar5523_err(ar, "Failed to allocate TX urb\n"); 827 ar5523_err(ar, "Failed to allocate TX urb\n");
diff --git a/drivers/net/wireless/ath/ar5523/ar5523.h b/drivers/net/wireless/ath/ar5523/ar5523.h
index 00c6fd346d48..9a322a65cdb5 100644
--- a/drivers/net/wireless/ath/ar5523/ar5523.h
+++ b/drivers/net/wireless/ath/ar5523/ar5523.h
@@ -74,7 +74,6 @@ struct ar5523_tx_cmd {
74struct ar5523_tx_data { 74struct ar5523_tx_data {
75 struct list_head list; 75 struct list_head list;
76 struct ar5523 *ar; 76 struct ar5523 *ar;
77 struct sk_buff *skb;
78 struct urb *urb; 77 struct urb *urb;
79}; 78};
80 79
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index 1eebe2ea3dfb..7e9481099a8e 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -131,6 +131,9 @@ struct ath_ops {
131 void (*enable_write_buffer)(void *); 131 void (*enable_write_buffer)(void *);
132 void (*write_flush) (void *); 132 void (*write_flush) (void *);
133 u32 (*rmw)(void *, u32 reg_offset, u32 set, u32 clr); 133 u32 (*rmw)(void *, u32 reg_offset, u32 set, u32 clr);
134 void (*enable_rmw_buffer)(void *);
135 void (*rmw_flush) (void *);
136
134}; 137};
135 138
136struct ath_common; 139struct ath_common;
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h
index 1ed7a88aeea9..7ca0d6f930fd 100644
--- a/drivers/net/wireless/ath/ath5k/ath5k.h
+++ b/drivers/net/wireless/ath/ath5k/ath5k.h
@@ -1283,6 +1283,7 @@ struct ath5k_hw {
1283#define ATH_STAT_PROMISC 1 1283#define ATH_STAT_PROMISC 1
1284#define ATH_STAT_LEDSOFT 2 /* enable LED gpio status */ 1284#define ATH_STAT_LEDSOFT 2 /* enable LED gpio status */
1285#define ATH_STAT_STARTED 3 /* opened & irqs enabled */ 1285#define ATH_STAT_STARTED 3 /* opened & irqs enabled */
1286#define ATH_STAT_RESET 4 /* hw reset */
1286 1287
1287 unsigned int filter_flags; /* HW flags, AR5K_RX_FILTER_* */ 1288 unsigned int filter_flags; /* HW flags, AR5K_RX_FILTER_* */
1288 unsigned int fif_filter_flags; /* Current FIF_* filter flags */ 1289 unsigned int fif_filter_flags; /* Current FIF_* filter flags */
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c
index 57a80e89822d..a6131825c9f6 100644
--- a/drivers/net/wireless/ath/ath5k/base.c
+++ b/drivers/net/wireless/ath/ath5k/base.c
@@ -1523,6 +1523,9 @@ ath5k_set_current_imask(struct ath5k_hw *ah)
1523 enum ath5k_int imask; 1523 enum ath5k_int imask;
1524 unsigned long flags; 1524 unsigned long flags;
1525 1525
1526 if (test_bit(ATH_STAT_RESET, ah->status))
1527 return;
1528
1526 spin_lock_irqsave(&ah->irqlock, flags); 1529 spin_lock_irqsave(&ah->irqlock, flags);
1527 imask = ah->imask; 1530 imask = ah->imask;
1528 if (ah->rx_pending) 1531 if (ah->rx_pending)
@@ -2858,10 +2861,12 @@ ath5k_reset(struct ath5k_hw *ah, struct ieee80211_channel *chan,
2858{ 2861{
2859 struct ath_common *common = ath5k_hw_common(ah); 2862 struct ath_common *common = ath5k_hw_common(ah);
2860 int ret, ani_mode; 2863 int ret, ani_mode;
2861 bool fast; 2864 bool fast = chan && modparam_fastchanswitch ? 1 : 0;
2862 2865
2863 ATH5K_DBG(ah, ATH5K_DEBUG_RESET, "resetting\n"); 2866 ATH5K_DBG(ah, ATH5K_DEBUG_RESET, "resetting\n");
2864 2867
2868 __set_bit(ATH_STAT_RESET, ah->status);
2869
2865 ath5k_hw_set_imr(ah, 0); 2870 ath5k_hw_set_imr(ah, 0);
2866 synchronize_irq(ah->irq); 2871 synchronize_irq(ah->irq);
2867 ath5k_stop_tasklets(ah); 2872 ath5k_stop_tasklets(ah);
@@ -2876,11 +2881,29 @@ ath5k_reset(struct ath5k_hw *ah, struct ieee80211_channel *chan,
2876 * so we should also free any remaining 2881 * so we should also free any remaining
2877 * tx buffers */ 2882 * tx buffers */
2878 ath5k_drain_tx_buffs(ah); 2883 ath5k_drain_tx_buffs(ah);
2884
2885 /* Stop PCU */
2886 ath5k_hw_stop_rx_pcu(ah);
2887
2888 /* Stop DMA
2889 *
2890 * Note: If DMA didn't stop continue
2891 * since only a reset will fix it.
2892 */
2893 ret = ath5k_hw_dma_stop(ah);
2894
2895 /* RF Bus grant won't work if we have pending
2896 * frames
2897 */
2898 if (ret && fast) {
2899 ATH5K_DBG(ah, ATH5K_DEBUG_RESET,
2900 "DMA didn't stop, falling back to normal reset\n");
2901 fast = false;
2902 }
2903
2879 if (chan) 2904 if (chan)
2880 ah->curchan = chan; 2905 ah->curchan = chan;
2881 2906
2882 fast = ((chan != NULL) && modparam_fastchanswitch) ? 1 : 0;
2883
2884 ret = ath5k_hw_reset(ah, ah->opmode, ah->curchan, fast, skip_pcu); 2907 ret = ath5k_hw_reset(ah, ah->opmode, ah->curchan, fast, skip_pcu);
2885 if (ret) { 2908 if (ret) {
2886 ATH5K_ERR(ah, "can't reset hardware (%d)\n", ret); 2909 ATH5K_ERR(ah, "can't reset hardware (%d)\n", ret);
@@ -2934,6 +2957,8 @@ ath5k_reset(struct ath5k_hw *ah, struct ieee80211_channel *chan,
2934 */ 2957 */
2935/* ath5k_chan_change(ah, c); */ 2958/* ath5k_chan_change(ah, c); */
2936 2959
2960 __clear_bit(ATH_STAT_RESET, ah->status);
2961
2937 ath5k_beacon_config(ah); 2962 ath5k_beacon_config(ah);
2938 /* intrs are enabled by ath5k_beacon_config */ 2963 /* intrs are enabled by ath5k_beacon_config */
2939 2964
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c
index b9b651ea9851..99e62f99a182 100644
--- a/drivers/net/wireless/ath/ath5k/reset.c
+++ b/drivers/net/wireless/ath/ath5k/reset.c
@@ -1169,30 +1169,6 @@ ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode,
1169 if (ah->ah_version == AR5K_AR5212) 1169 if (ah->ah_version == AR5K_AR5212)
1170 ath5k_hw_set_sleep_clock(ah, false); 1170 ath5k_hw_set_sleep_clock(ah, false);
1171 1171
1172 /*
1173 * Stop PCU
1174 */
1175 ath5k_hw_stop_rx_pcu(ah);
1176
1177 /*
1178 * Stop DMA
1179 *
1180 * Note: If DMA didn't stop continue
1181 * since only a reset will fix it.
1182 */
1183 ret = ath5k_hw_dma_stop(ah);
1184
1185 /* RF Bus grant won't work if we have pending
1186 * frames */
1187 if (ret && fast) {
1188 ATH5K_DBG(ah, ATH5K_DEBUG_RESET,
1189 "DMA didn't stop, falling back to normal reset\n");
1190 fast = false;
1191 /* Non fatal, just continue with
1192 * normal reset */
1193 ret = 0;
1194 }
1195
1196 mode = channel->hw_value; 1172 mode = channel->hw_value;
1197 switch (mode) { 1173 switch (mode) {
1198 case AR5K_MODE_11A: 1174 case AR5K_MODE_11A:
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
index 473972288a84..ecda613c2d54 100644
--- a/drivers/net/wireless/ath/ath9k/Makefile
+++ b/drivers/net/wireless/ath/ath9k/Makefile
@@ -46,7 +46,8 @@ ath9k_hw-y:= \
46ath9k_hw-$(CONFIG_ATH9K_WOW) += ar9003_wow.o 46ath9k_hw-$(CONFIG_ATH9K_WOW) += ar9003_wow.o
47 47
48ath9k_hw-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += btcoex.o \ 48ath9k_hw-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += btcoex.o \
49 ar9003_mci.o 49 ar9003_mci.o \
50 ar9003_aic.o
50 51
51ath9k_hw-$(CONFIG_ATH9K_PCOEM) += ar9003_rtt.o 52ath9k_hw-$(CONFIG_ATH9K_PCOEM) += ar9003_rtt.o
52 53
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c
index ca01d17d130f..25e45e4d1a60 100644
--- a/drivers/net/wireless/ath/ath9k/ani.c
+++ b/drivers/net/wireless/ath/ath9k/ani.c
@@ -107,11 +107,21 @@ static const struct ani_cck_level_entry cck_level_table[] = {
107static void ath9k_hw_update_mibstats(struct ath_hw *ah, 107static void ath9k_hw_update_mibstats(struct ath_hw *ah,
108 struct ath9k_mib_stats *stats) 108 struct ath9k_mib_stats *stats)
109{ 109{
110 stats->ackrcv_bad += REG_READ(ah, AR_ACK_FAIL); 110 u32 addr[5] = {AR_RTS_OK, AR_RTS_FAIL, AR_ACK_FAIL,
111 stats->rts_bad += REG_READ(ah, AR_RTS_FAIL); 111 AR_FCS_FAIL, AR_BEACON_CNT};
112 stats->fcs_bad += REG_READ(ah, AR_FCS_FAIL); 112 u32 data[5];
113 stats->rts_good += REG_READ(ah, AR_RTS_OK); 113
114 stats->beacons += REG_READ(ah, AR_BEACON_CNT); 114 REG_READ_MULTI(ah, &addr[0], &data[0], 5);
115 /* AR_RTS_OK */
116 stats->rts_good += data[0];
117 /* AR_RTS_FAIL */
118 stats->rts_bad += data[1];
119 /* AR_ACK_FAIL */
120 stats->ackrcv_bad += data[2];
121 /* AR_FCS_FAIL */
122 stats->fcs_bad += data[3];
123 /* AR_BEACON_CNT */
124 stats->beacons += data[4];
115} 125}
116 126
117static void ath9k_ani_restart(struct ath_hw *ah) 127static void ath9k_ani_restart(struct ath_hw *ah)
diff --git a/drivers/net/wireless/ath/ath9k/ar5008_phy.c b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
index f273427fdd29..6c23d279525f 100644
--- a/drivers/net/wireless/ath/ath9k/ar5008_phy.c
+++ b/drivers/net/wireless/ath/ath9k/ar5008_phy.c
@@ -681,12 +681,13 @@ static void ar5008_hw_set_channel_regs(struct ath_hw *ah,
681 phymode |= AR_PHY_FC_DYN2040_PRI_CH; 681 phymode |= AR_PHY_FC_DYN2040_PRI_CH;
682 682
683 } 683 }
684 ENABLE_REGWRITE_BUFFER(ah);
684 REG_WRITE(ah, AR_PHY_TURBO, phymode); 685 REG_WRITE(ah, AR_PHY_TURBO, phymode);
685 686
687 /* This function do only REG_WRITE, so
688 * we can include it to REGWRITE_BUFFER. */
686 ath9k_hw_set11nmac2040(ah, chan); 689 ath9k_hw_set11nmac2040(ah, chan);
687 690
688 ENABLE_REGWRITE_BUFFER(ah);
689
690 REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S); 691 REG_WRITE(ah, AR_GTXTO, 25 << AR_GTXTO_TIMEOUT_LIMIT_S);
691 REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S); 692 REG_WRITE(ah, AR_CST, 0xF << AR_CST_TIMEOUT_LIMIT_S);
692 693
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
index 42190b67c671..50fcd343c41a 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
@@ -430,46 +430,43 @@ static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset)
430 u32 regVal; 430 u32 regVal;
431 unsigned int i; 431 unsigned int i;
432 u32 regList[][2] = { 432 u32 regList[][2] = {
433 { 0x786c, 0 }, 433 { AR9285_AN_TOP3, 0 },
434 { 0x7854, 0 }, 434 { AR9285_AN_RXTXBB1, 0 },
435 { 0x7820, 0 }, 435 { AR9285_AN_RF2G1, 0 },
436 { 0x7824, 0 }, 436 { AR9285_AN_RF2G2, 0 },
437 { 0x7868, 0 }, 437 { AR9285_AN_TOP2, 0 },
438 { 0x783c, 0 }, 438 { AR9285_AN_RF2G8, 0 },
439 { 0x7838, 0 } , 439 { AR9285_AN_RF2G7, 0 },
440 { 0x7828, 0 } , 440 { AR9285_AN_RF2G3, 0 },
441 }; 441 };
442 442
443 for (i = 0; i < ARRAY_SIZE(regList); i++) 443 REG_READ_ARRAY(ah, regList, ARRAY_SIZE(regList));
444 regList[i][1] = REG_READ(ah, regList[i][0]);
445
446 regVal = REG_READ(ah, 0x7834);
447 regVal &= (~(0x1));
448 REG_WRITE(ah, 0x7834, regVal);
449 regVal = REG_READ(ah, 0x9808);
450 regVal |= (0x1 << 27);
451 REG_WRITE(ah, 0x9808, regVal);
452 444
445 ENABLE_REG_RMW_BUFFER(ah);
446 /* 7834, b1=0 */
447 REG_CLR_BIT(ah, AR9285_AN_RF2G6, 1 << 0);
448 /* 9808, b27=1 */
449 REG_SET_BIT(ah, 0x9808, 1 << 27);
453 /* 786c,b23,1, pwddac=1 */ 450 /* 786c,b23,1, pwddac=1 */
454 REG_RMW_FIELD(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC, 1); 451 REG_SET_BIT(ah, AR9285_AN_TOP3, AR9285_AN_TOP3_PWDDAC);
455 /* 7854, b5,1, pdrxtxbb=1 */ 452 /* 7854, b5,1, pdrxtxbb=1 */
456 REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1, 1); 453 REG_SET_BIT(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDRXTXBB1);
457 /* 7854, b7,1, pdv2i=1 */ 454 /* 7854, b7,1, pdv2i=1 */
458 REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I, 1); 455 REG_SET_BIT(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDV2I);
459 /* 7854, b8,1, pddacinterface=1 */ 456 /* 7854, b8,1, pddacinterface=1 */
460 REG_RMW_FIELD(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF, 1); 457 REG_SET_BIT(ah, AR9285_AN_RXTXBB1, AR9285_AN_RXTXBB1_PDDACIF);
461 /* 7824,b12,0, offcal=0 */ 458 /* 7824,b12,0, offcal=0 */
462 REG_RMW_FIELD(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL, 0); 459 REG_CLR_BIT(ah, AR9285_AN_RF2G2, AR9285_AN_RF2G2_OFFCAL);
463 /* 7838, b1,0, pwddb=0 */ 460 /* 7838, b1,0, pwddb=0 */
464 REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB, 0); 461 REG_CLR_BIT(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PWDDB);
465 /* 7820,b11,0, enpacal=0 */ 462 /* 7820,b11,0, enpacal=0 */
466 REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL, 0); 463 REG_CLR_BIT(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_ENPACAL);
467 /* 7820,b25,1, pdpadrv1=0 */ 464 /* 7820,b25,1, pdpadrv1=0 */
468 REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1, 0); 465 REG_CLR_BIT(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV1);
469 /* 7820,b24,0, pdpadrv2=0 */ 466 /* 7820,b24,0, pdpadrv2=0 */
470 REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV2, 0); 467 REG_CLR_BIT(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPADRV2);
471 /* 7820,b23,0, pdpaout=0 */ 468 /* 7820,b23,0, pdpaout=0 */
472 REG_RMW_FIELD(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT, 0); 469 REG_CLR_BIT(ah, AR9285_AN_RF2G1, AR9285_AN_RF2G1_PDPAOUT);
473 /* 783c,b14-16,7, padrvgn2tab_0=7 */ 470 /* 783c,b14-16,7, padrvgn2tab_0=7 */
474 REG_RMW_FIELD(ah, AR9285_AN_RF2G8, AR9285_AN_RF2G8_PADRVGN2TAB0, 7); 471 REG_RMW_FIELD(ah, AR9285_AN_RF2G8, AR9285_AN_RF2G8_PADRVGN2TAB0, 7);
475 /* 472 /*
@@ -477,8 +474,9 @@ static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset)
477 * does not matter since we turn it off 474 * does not matter since we turn it off
478 */ 475 */
479 REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PADRVGN2TAB0, 0); 476 REG_RMW_FIELD(ah, AR9285_AN_RF2G7, AR9285_AN_RF2G7_PADRVGN2TAB0, 0);
480 477 /* 7828, b0-11, ccom=fff */
481 REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9271_AN_RF2G3_CCOMP, 0xfff); 478 REG_RMW_FIELD(ah, AR9285_AN_RF2G3, AR9271_AN_RF2G3_CCOMP, 0xfff);
479 REG_RMW_BUFFER_FLUSH(ah);
482 480
483 /* Set: 481 /* Set:
484 * localmode=1,bmode=1,bmoderxtx=1,synthon=1, 482 * localmode=1,bmode=1,bmoderxtx=1,synthon=1,
@@ -490,15 +488,16 @@ static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset)
490 488
491 /* find off_6_1; */ 489 /* find off_6_1; */
492 for (i = 6; i > 0; i--) { 490 for (i = 6; i > 0; i--) {
493 regVal = REG_READ(ah, 0x7834); 491 regVal = REG_READ(ah, AR9285_AN_RF2G6);
494 regVal |= (1 << (20 + i)); 492 regVal |= (1 << (20 + i));
495 REG_WRITE(ah, 0x7834, regVal); 493 REG_WRITE(ah, AR9285_AN_RF2G6, regVal);
496 udelay(1); 494 udelay(1);
497 /* regVal = REG_READ(ah, 0x7834); */ 495 /* regVal = REG_READ(ah, 0x7834); */
498 regVal &= (~(0x1 << (20 + i))); 496 regVal &= (~(0x1 << (20 + i)));
499 regVal |= (MS(REG_READ(ah, 0x7840), AR9285_AN_RXTXBB1_SPARE9) 497 regVal |= (MS(REG_READ(ah, AR9285_AN_RF2G9),
498 AR9285_AN_RXTXBB1_SPARE9)
500 << (20 + i)); 499 << (20 + i));
501 REG_WRITE(ah, 0x7834, regVal); 500 REG_WRITE(ah, AR9285_AN_RF2G6, regVal);
502 } 501 }
503 502
504 regVal = (regVal >> 20) & 0x7f; 503 regVal = (regVal >> 20) & 0x7f;
@@ -515,15 +514,15 @@ static void ar9271_hw_pa_cal(struct ath_hw *ah, bool is_reset)
515 ah->pacal_info.prev_offset = regVal; 514 ah->pacal_info.prev_offset = regVal;
516 } 515 }
517 516
518 ENABLE_REGWRITE_BUFFER(ah);
519 517
520 regVal = REG_READ(ah, 0x7834); 518 ENABLE_REG_RMW_BUFFER(ah);
521 regVal |= 0x1; 519 /* 7834, b1=1 */
522 REG_WRITE(ah, 0x7834, regVal); 520 REG_SET_BIT(ah, AR9285_AN_RF2G6, 1 << 0);
523 regVal = REG_READ(ah, 0x9808); 521 /* 9808, b27=0 */
524 regVal &= (~(0x1 << 27)); 522 REG_CLR_BIT(ah, 0x9808, 1 << 27);
525 REG_WRITE(ah, 0x9808, regVal); 523 REG_RMW_BUFFER_FLUSH(ah);
526 524
525 ENABLE_REGWRITE_BUFFER(ah);
527 for (i = 0; i < ARRAY_SIZE(regList); i++) 526 for (i = 0; i < ARRAY_SIZE(regList); i++)
528 REG_WRITE(ah, regList[i][0], regList[i][1]); 527 REG_WRITE(ah, regList[i][0], regList[i][1]);
529 528
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_aic.c b/drivers/net/wireless/ath/ath9k/ar9003_aic.c
new file mode 100644
index 000000000000..1db119d77783
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9003_aic.c
@@ -0,0 +1,599 @@
1/*
2 * Copyright (c) 2015 Qualcomm Atheros Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#include "hw.h"
18#include "hw-ops.h"
19#include "ar9003_mci.h"
20#include "ar9003_aic.h"
21#include "ar9003_phy.h"
22#include "reg_aic.h"
23
24static const u8 com_att_db_table[ATH_AIC_MAX_COM_ATT_DB_TABLE] = {
25 0, 3, 9, 15, 21, 27
26};
27
28static const u16 aic_lin_table[ATH_AIC_MAX_AIC_LIN_TABLE] = {
29 8191, 7300, 6506, 5799, 5168, 4606, 4105, 3659,
30 3261, 2906, 2590, 2309, 2057, 1834, 1634, 1457,
31 1298, 1157, 1031, 919, 819, 730, 651, 580,
32 517, 461, 411, 366, 326, 291, 259, 231,
33 206, 183, 163, 146, 130, 116, 103, 92,
34 82, 73, 65, 58, 52, 46, 41, 37,
35 33, 29, 26, 23, 21, 18, 16, 15,
36 13, 12, 10, 9, 8, 7, 7, 6,
37 5, 5, 4, 4, 3
38};
39
40static bool ar9003_hw_is_aic_enabled(struct ath_hw *ah)
41{
42 struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;
43
44 /*
45 * Disable AIC for now, until we have all the
46 * HW code and the driver-layer support ready.
47 */
48 return false;
49
50 if (mci_hw->config & ATH_MCI_CONFIG_DISABLE_AIC)
51 return false;
52
53 return true;
54}
55
56static int16_t ar9003_aic_find_valid(struct ath_aic_sram_info *cal_sram,
57 bool dir, u8 index)
58{
59 int16_t i;
60
61 if (dir) {
62 for (i = index + 1; i < ATH_AIC_MAX_BT_CHANNEL; i++) {
63 if (cal_sram[i].valid)
64 break;
65 }
66 } else {
67 for (i = index - 1; i >= 0; i--) {
68 if (cal_sram[i].valid)
69 break;
70 }
71 }
72
73 if ((i >= ATH_AIC_MAX_BT_CHANNEL) || (i < 0))
74 i = -1;
75
76 return i;
77}
78
79/*
80 * type 0: aic_lin_table, 1: com_att_db_table
81 */
82static int16_t ar9003_aic_find_index(u8 type, int16_t value)
83{
84 int16_t i = -1;
85
86 if (type == 0) {
87 for (i = ATH_AIC_MAX_AIC_LIN_TABLE - 1; i >= 0; i--) {
88 if (aic_lin_table[i] >= value)
89 break;
90 }
91 } else if (type == 1) {
92 for (i = 0; i < ATH_AIC_MAX_COM_ATT_DB_TABLE; i++) {
93 if (com_att_db_table[i] > value) {
94 i--;
95 break;
96 }
97 }
98
99 if (i >= ATH_AIC_MAX_COM_ATT_DB_TABLE)
100 i = -1;
101 }
102
103 return i;
104}
105
106static void ar9003_aic_gain_table(struct ath_hw *ah)
107{
108 u32 aic_atten_word[19], i;
109
110 /* Config LNA gain difference */
111 REG_WRITE(ah, AR_PHY_BT_COEX_4, 0x2c200a00);
112 REG_WRITE(ah, AR_PHY_BT_COEX_5, 0x5c4e4438);
113
114 /* Program gain table */
115 aic_atten_word[0] = (0x1 & 0xf) << 14 | (0x1f & 0x1f) << 9 | (0x0 & 0xf) << 5 |
116 (0x1f & 0x1f); /* -01 dB: 4'd1, 5'd31, 00 dB: 4'd0, 5'd31 */
117 aic_atten_word[1] = (0x3 & 0xf) << 14 | (0x1f & 0x1f) << 9 | (0x2 & 0xf) << 5 |
118 (0x1f & 0x1f); /* -03 dB: 4'd3, 5'd31, -02 dB: 4'd2, 5'd31 */
119 aic_atten_word[2] = (0x5 & 0xf) << 14 | (0x1f & 0x1f) << 9 | (0x4 & 0xf) << 5 |
120 (0x1f & 0x1f); /* -05 dB: 4'd5, 5'd31, -04 dB: 4'd4, 5'd31 */
121 aic_atten_word[3] = (0x1 & 0xf) << 14 | (0x1e & 0x1f) << 9 | (0x0 & 0xf) << 5 |
122 (0x1e & 0x1f); /* -07 dB: 4'd1, 5'd30, -06 dB: 4'd0, 5'd30 */
123 aic_atten_word[4] = (0x3 & 0xf) << 14 | (0x1e & 0x1f) << 9 | (0x2 & 0xf) << 5 |
124 (0x1e & 0x1f); /* -09 dB: 4'd3, 5'd30, -08 dB: 4'd2, 5'd30 */
125 aic_atten_word[5] = (0x5 & 0xf) << 14 | (0x1e & 0x1f) << 9 | (0x4 & 0xf) << 5 |
126 (0x1e & 0x1f); /* -11 dB: 4'd5, 5'd30, -10 dB: 4'd4, 5'd30 */
127 aic_atten_word[6] = (0x1 & 0xf) << 14 | (0xf & 0x1f) << 9 | (0x0 & 0xf) << 5 |
128 (0xf & 0x1f); /* -13 dB: 4'd1, 5'd15, -12 dB: 4'd0, 5'd15 */
129 aic_atten_word[7] = (0x3 & 0xf) << 14 | (0xf & 0x1f) << 9 | (0x2 & 0xf) << 5 |
130 (0xf & 0x1f); /* -15 dB: 4'd3, 5'd15, -14 dB: 4'd2, 5'd15 */
131 aic_atten_word[8] = (0x5 & 0xf) << 14 | (0xf & 0x1f) << 9 | (0x4 & 0xf) << 5 |
132 (0xf & 0x1f); /* -17 dB: 4'd5, 5'd15, -16 dB: 4'd4, 5'd15 */
133 aic_atten_word[9] = (0x1 & 0xf) << 14 | (0x7 & 0x1f) << 9 | (0x0 & 0xf) << 5 |
134 (0x7 & 0x1f); /* -19 dB: 4'd1, 5'd07, -18 dB: 4'd0, 5'd07 */
135 aic_atten_word[10] = (0x3 & 0xf) << 14 | (0x7 & 0x1f) << 9 | (0x2 & 0xf) << 5 |
136 (0x7 & 0x1f); /* -21 dB: 4'd3, 5'd07, -20 dB: 4'd2, 5'd07 */
137 aic_atten_word[11] = (0x5 & 0xf) << 14 | (0x7 & 0x1f) << 9 | (0x4 & 0xf) << 5 |
138 (0x7 & 0x1f); /* -23 dB: 4'd5, 5'd07, -22 dB: 4'd4, 5'd07 */
139 aic_atten_word[12] = (0x7 & 0xf) << 14 | (0x7 & 0x1f) << 9 | (0x6 & 0xf) << 5 |
140 (0x7 & 0x1f); /* -25 dB: 4'd7, 5'd07, -24 dB: 4'd6, 5'd07 */
141 aic_atten_word[13] = (0x3 & 0xf) << 14 | (0x3 & 0x1f) << 9 | (0x2 & 0xf) << 5 |
142 (0x3 & 0x1f); /* -27 dB: 4'd3, 5'd03, -26 dB: 4'd2, 5'd03 */
143 aic_atten_word[14] = (0x5 & 0xf) << 14 | (0x3 & 0x1f) << 9 | (0x4 & 0xf) << 5 |
144 (0x3 & 0x1f); /* -29 dB: 4'd5, 5'd03, -28 dB: 4'd4, 5'd03 */
145 aic_atten_word[15] = (0x1 & 0xf) << 14 | (0x1 & 0x1f) << 9 | (0x0 & 0xf) << 5 |
146 (0x1 & 0x1f); /* -31 dB: 4'd1, 5'd01, -30 dB: 4'd0, 5'd01 */
147 aic_atten_word[16] = (0x3 & 0xf) << 14 | (0x1 & 0x1f) << 9 | (0x2 & 0xf) << 5 |
148 (0x1 & 0x1f); /* -33 dB: 4'd3, 5'd01, -32 dB: 4'd2, 5'd01 */
149 aic_atten_word[17] = (0x5 & 0xf) << 14 | (0x1 & 0x1f) << 9 | (0x4 & 0xf) << 5 |
150 (0x1 & 0x1f); /* -35 dB: 4'd5, 5'd01, -34 dB: 4'd4, 5'd01 */
151 aic_atten_word[18] = (0x7 & 0xf) << 14 | (0x1 & 0x1f) << 9 | (0x6 & 0xf) << 5 |
152 (0x1 & 0x1f); /* -37 dB: 4'd7, 5'd01, -36 dB: 4'd6, 5'd01 */
153
154 /* Write to Gain table with auto increment enabled. */
155 REG_WRITE(ah, (AR_PHY_AIC_SRAM_ADDR_B0 + 0x3000),
156 (ATH_AIC_SRAM_AUTO_INCREMENT |
157 ATH_AIC_SRAM_GAIN_TABLE_OFFSET));
158
159 for (i = 0; i < 19; i++) {
160 REG_WRITE(ah, (AR_PHY_AIC_SRAM_DATA_B0 + 0x3000),
161 aic_atten_word[i]);
162 }
163}
164
165static u8 ar9003_aic_cal_start(struct ath_hw *ah, u8 min_valid_count)
166{
167 struct ath9k_hw_aic *aic = &ah->btcoex_hw.aic;
168 int i;
169
170 /* Write to Gain table with auto increment enabled. */
171 REG_WRITE(ah, (AR_PHY_AIC_SRAM_ADDR_B0 + 0x3000),
172 (ATH_AIC_SRAM_AUTO_INCREMENT |
173 ATH_AIC_SRAM_CAL_OFFSET));
174
175 for (i = 0; i < ATH_AIC_MAX_BT_CHANNEL; i++) {
176 REG_WRITE(ah, (AR_PHY_AIC_SRAM_DATA_B0 + 0x3000), 0);
177 aic->aic_sram[i] = 0;
178 }
179
180 REG_WRITE(ah, AR_PHY_AIC_CTRL_0_B0,
181 (SM(0, AR_PHY_AIC_MON_ENABLE) |
182 SM(127, AR_PHY_AIC_CAL_MAX_HOP_COUNT) |
183 SM(min_valid_count, AR_PHY_AIC_CAL_MIN_VALID_COUNT) |
184 SM(37, AR_PHY_AIC_F_WLAN) |
185 SM(1, AR_PHY_AIC_CAL_CH_VALID_RESET) |
186 SM(0, AR_PHY_AIC_CAL_ENABLE) |
187 SM(0x40, AR_PHY_AIC_BTTX_PWR_THR) |
188 SM(0, AR_PHY_AIC_ENABLE)));
189
190 REG_WRITE(ah, AR_PHY_AIC_CTRL_0_B1,
191 (SM(0, AR_PHY_AIC_MON_ENABLE) |
192 SM(1, AR_PHY_AIC_CAL_CH_VALID_RESET) |
193 SM(0, AR_PHY_AIC_CAL_ENABLE) |
194 SM(0x40, AR_PHY_AIC_BTTX_PWR_THR) |
195 SM(0, AR_PHY_AIC_ENABLE)));
196
197 REG_WRITE(ah, AR_PHY_AIC_CTRL_1_B0,
198 (SM(8, AR_PHY_AIC_CAL_BT_REF_DELAY) |
199 SM(0, AR_PHY_AIC_BT_IDLE_CFG) |
200 SM(1, AR_PHY_AIC_STDBY_COND) |
201 SM(37, AR_PHY_AIC_STDBY_ROT_ATT_DB) |
202 SM(5, AR_PHY_AIC_STDBY_COM_ATT_DB) |
203 SM(15, AR_PHY_AIC_RSSI_MAX) |
204 SM(0, AR_PHY_AIC_RSSI_MIN)));
205
206 REG_WRITE(ah, AR_PHY_AIC_CTRL_1_B1,
207 (SM(15, AR_PHY_AIC_RSSI_MAX) |
208 SM(0, AR_PHY_AIC_RSSI_MIN)));
209
210 REG_WRITE(ah, AR_PHY_AIC_CTRL_2_B0,
211 (SM(44, AR_PHY_AIC_RADIO_DELAY) |
212 SM(8, AR_PHY_AIC_CAL_STEP_SIZE_CORR) |
213 SM(12, AR_PHY_AIC_CAL_ROT_IDX_CORR) |
214 SM(2, AR_PHY_AIC_CAL_CONV_CHECK_FACTOR) |
215 SM(5, AR_PHY_AIC_ROT_IDX_COUNT_MAX) |
216 SM(0, AR_PHY_AIC_CAL_SYNTH_TOGGLE) |
217 SM(0, AR_PHY_AIC_CAL_SYNTH_AFTER_BTRX) |
218 SM(200, AR_PHY_AIC_CAL_SYNTH_SETTLING)));
219
220 REG_WRITE(ah, AR_PHY_AIC_CTRL_3_B0,
221 (SM(2, AR_PHY_AIC_MON_MAX_HOP_COUNT) |
222 SM(1, AR_PHY_AIC_MON_MIN_STALE_COUNT) |
223 SM(1, AR_PHY_AIC_MON_PWR_EST_LONG) |
224 SM(2, AR_PHY_AIC_MON_PD_TALLY_SCALING) |
225 SM(10, AR_PHY_AIC_MON_PERF_THR) |
226 SM(2, AR_PHY_AIC_CAL_TARGET_MAG_SETTING) |
227 SM(1, AR_PHY_AIC_CAL_PERF_CHECK_FACTOR) |
228 SM(1, AR_PHY_AIC_CAL_PWR_EST_LONG)));
229
230 REG_WRITE(ah, AR_PHY_AIC_CTRL_4_B0,
231 (SM(2, AR_PHY_AIC_CAL_ROT_ATT_DB_EST_ISO) |
232 SM(3, AR_PHY_AIC_CAL_COM_ATT_DB_EST_ISO) |
233 SM(0, AR_PHY_AIC_CAL_ISO_EST_INIT_SETTING) |
234 SM(2, AR_PHY_AIC_CAL_COM_ATT_DB_BACKOFF) |
235 SM(1, AR_PHY_AIC_CAL_COM_ATT_DB_FIXED)));
236
237 REG_WRITE(ah, AR_PHY_AIC_CTRL_4_B1,
238 (SM(2, AR_PHY_AIC_CAL_ROT_ATT_DB_EST_ISO) |
239 SM(3, AR_PHY_AIC_CAL_COM_ATT_DB_EST_ISO) |
240 SM(0, AR_PHY_AIC_CAL_ISO_EST_INIT_SETTING) |
241 SM(2, AR_PHY_AIC_CAL_COM_ATT_DB_BACKOFF) |
242 SM(1, AR_PHY_AIC_CAL_COM_ATT_DB_FIXED)));
243
244 ar9003_aic_gain_table(ah);
245
246 /* Need to enable AIC reference signal in BT modem. */
247 REG_WRITE(ah, ATH_AIC_BT_JUPITER_CTRL,
248 (REG_READ(ah, ATH_AIC_BT_JUPITER_CTRL) |
249 ATH_AIC_BT_AIC_ENABLE));
250
251 aic->aic_cal_start_time = REG_READ(ah, AR_TSF_L32);
252
253 /* Start calibration */
254 REG_CLR_BIT(ah, AR_PHY_AIC_CTRL_0_B1, AR_PHY_AIC_CAL_ENABLE);
255 REG_SET_BIT(ah, AR_PHY_AIC_CTRL_0_B1, AR_PHY_AIC_CAL_CH_VALID_RESET);
256 REG_SET_BIT(ah, AR_PHY_AIC_CTRL_0_B1, AR_PHY_AIC_CAL_ENABLE);
257
258 aic->aic_caled_chan = 0;
259 aic->aic_cal_state = AIC_CAL_STATE_STARTED;
260
261 return aic->aic_cal_state;
262}
263
264static bool ar9003_aic_cal_post_process(struct ath_hw *ah)
265{
266 struct ath9k_hw_aic *aic = &ah->btcoex_hw.aic;
267 struct ath_aic_sram_info cal_sram[ATH_AIC_MAX_BT_CHANNEL];
268 struct ath_aic_out_info aic_sram[ATH_AIC_MAX_BT_CHANNEL];
269 u32 dir_path_gain_idx, quad_path_gain_idx, value;
270 u32 fixed_com_att_db;
271 int8_t dir_path_sign, quad_path_sign;
272 int16_t i;
273 bool ret = true;
274
275 memset(&cal_sram, 0, sizeof(cal_sram));
276 memset(&aic_sram, 0, sizeof(aic_sram));
277
278 for (i = 0; i < ATH_AIC_MAX_BT_CHANNEL; i++) {
279 value = aic->aic_sram[i];
280
281 cal_sram[i].valid =
282 MS(value, AR_PHY_AIC_SRAM_VALID);
283 cal_sram[i].rot_quad_att_db =
284 MS(value, AR_PHY_AIC_SRAM_ROT_QUAD_ATT_DB);
285 cal_sram[i].vga_quad_sign =
286 MS(value, AR_PHY_AIC_SRAM_VGA_QUAD_SIGN);
287 cal_sram[i].rot_dir_att_db =
288 MS(value, AR_PHY_AIC_SRAM_ROT_DIR_ATT_DB);
289 cal_sram[i].vga_dir_sign =
290 MS(value, AR_PHY_AIC_SRAM_VGA_DIR_SIGN);
291 cal_sram[i].com_att_6db =
292 MS(value, AR_PHY_AIC_SRAM_COM_ATT_6DB);
293
294 if (cal_sram[i].valid) {
295 dir_path_gain_idx = cal_sram[i].rot_dir_att_db +
296 com_att_db_table[cal_sram[i].com_att_6db];
297 quad_path_gain_idx = cal_sram[i].rot_quad_att_db +
298 com_att_db_table[cal_sram[i].com_att_6db];
299
300 dir_path_sign = (cal_sram[i].vga_dir_sign) ? 1 : -1;
301 quad_path_sign = (cal_sram[i].vga_quad_sign) ? 1 : -1;
302
303 aic_sram[i].dir_path_gain_lin = dir_path_sign *
304 aic_lin_table[dir_path_gain_idx];
305 aic_sram[i].quad_path_gain_lin = quad_path_sign *
306 aic_lin_table[quad_path_gain_idx];
307 }
308 }
309
310 for (i = 0; i < ATH_AIC_MAX_BT_CHANNEL; i++) {
311 int16_t start_idx, end_idx;
312
313 if (cal_sram[i].valid)
314 continue;
315
316 start_idx = ar9003_aic_find_valid(cal_sram, 0, i);
317 end_idx = ar9003_aic_find_valid(cal_sram, 1, i);
318
319 if (start_idx < 0) {
320 /* extrapolation */
321 start_idx = end_idx;
322 end_idx = ar9003_aic_find_valid(cal_sram, 1, start_idx);
323
324 if (end_idx < 0) {
325 ret = false;
326 break;
327 }
328
329 aic_sram[i].dir_path_gain_lin =
330 ((aic_sram[start_idx].dir_path_gain_lin -
331 aic_sram[end_idx].dir_path_gain_lin) *
332 (start_idx - i) + ((end_idx - i) >> 1)) /
333 (end_idx - i) +
334 aic_sram[start_idx].dir_path_gain_lin;
335 aic_sram[i].quad_path_gain_lin =
336 ((aic_sram[start_idx].quad_path_gain_lin -
337 aic_sram[end_idx].quad_path_gain_lin) *
338 (start_idx - i) + ((end_idx - i) >> 1)) /
339 (end_idx - i) +
340 aic_sram[start_idx].quad_path_gain_lin;
341 }
342
343 if (end_idx < 0) {
344 /* extrapolation */
345 end_idx = ar9003_aic_find_valid(cal_sram, 0, start_idx);
346
347 if (end_idx < 0) {
348 ret = false;
349 break;
350 }
351
352 aic_sram[i].dir_path_gain_lin =
353 ((aic_sram[start_idx].dir_path_gain_lin -
354 aic_sram[end_idx].dir_path_gain_lin) *
355 (i - start_idx) + ((start_idx - end_idx) >> 1)) /
356 (start_idx - end_idx) +
357 aic_sram[start_idx].dir_path_gain_lin;
358 aic_sram[i].quad_path_gain_lin =
359 ((aic_sram[start_idx].quad_path_gain_lin -
360 aic_sram[end_idx].quad_path_gain_lin) *
361 (i - start_idx) + ((start_idx - end_idx) >> 1)) /
362 (start_idx - end_idx) +
363 aic_sram[start_idx].quad_path_gain_lin;
364
365 } else if (start_idx >= 0){
366 /* interpolation */
367 aic_sram[i].dir_path_gain_lin =
368 (((end_idx - i) * aic_sram[start_idx].dir_path_gain_lin) +
369 ((i - start_idx) * aic_sram[end_idx].dir_path_gain_lin) +
370 ((end_idx - start_idx) >> 1)) /
371 (end_idx - start_idx);
372 aic_sram[i].quad_path_gain_lin =
373 (((end_idx - i) * aic_sram[start_idx].quad_path_gain_lin) +
374 ((i - start_idx) * aic_sram[end_idx].quad_path_gain_lin) +
375 ((end_idx - start_idx) >> 1))/
376 (end_idx - start_idx);
377 }
378 }
379
380 /* From dir/quad_path_gain_lin to sram. */
381 i = ar9003_aic_find_valid(cal_sram, 1, 0);
382 if (i < 0) {
383 i = 0;
384 ret = false;
385 }
386 fixed_com_att_db = com_att_db_table[cal_sram[i].com_att_6db];
387
388 for (i = 0; i < ATH_AIC_MAX_BT_CHANNEL; i++) {
389 int16_t rot_dir_path_att_db, rot_quad_path_att_db;
390
391 aic_sram[i].sram.vga_dir_sign =
392 (aic_sram[i].dir_path_gain_lin >= 0) ? 1 : 0;
393 aic_sram[i].sram.vga_quad_sign=
394 (aic_sram[i].quad_path_gain_lin >= 0) ? 1 : 0;
395
396 rot_dir_path_att_db =
397 ar9003_aic_find_index(0, abs(aic_sram[i].dir_path_gain_lin)) -
398 fixed_com_att_db;
399 rot_quad_path_att_db =
400 ar9003_aic_find_index(0, abs(aic_sram[i].quad_path_gain_lin)) -
401 fixed_com_att_db;
402
403 aic_sram[i].sram.com_att_6db =
404 ar9003_aic_find_index(1, fixed_com_att_db);
405
406 aic_sram[i].sram.valid = 1;
407
408 aic_sram[i].sram.rot_dir_att_db =
409 min(max(rot_dir_path_att_db,
410 (int16_t)ATH_AIC_MIN_ROT_DIR_ATT_DB),
411 ATH_AIC_MAX_ROT_DIR_ATT_DB);
412 aic_sram[i].sram.rot_quad_att_db =
413 min(max(rot_quad_path_att_db,
414 (int16_t)ATH_AIC_MIN_ROT_QUAD_ATT_DB),
415 ATH_AIC_MAX_ROT_QUAD_ATT_DB);
416 }
417
418 for (i = 0; i < ATH_AIC_MAX_BT_CHANNEL; i++) {
419 aic->aic_sram[i] = (SM(aic_sram[i].sram.vga_dir_sign,
420 AR_PHY_AIC_SRAM_VGA_DIR_SIGN) |
421 SM(aic_sram[i].sram.vga_quad_sign,
422 AR_PHY_AIC_SRAM_VGA_QUAD_SIGN) |
423 SM(aic_sram[i].sram.com_att_6db,
424 AR_PHY_AIC_SRAM_COM_ATT_6DB) |
425 SM(aic_sram[i].sram.valid,
426 AR_PHY_AIC_SRAM_VALID) |
427 SM(aic_sram[i].sram.rot_dir_att_db,
428 AR_PHY_AIC_SRAM_ROT_DIR_ATT_DB) |
429 SM(aic_sram[i].sram.rot_quad_att_db,
430 AR_PHY_AIC_SRAM_ROT_QUAD_ATT_DB));
431 }
432
433 return ret;
434}
435
436static void ar9003_aic_cal_done(struct ath_hw *ah)
437{
438 struct ath9k_hw_aic *aic = &ah->btcoex_hw.aic;
439
440 /* Disable AIC reference signal in BT modem. */
441 REG_WRITE(ah, ATH_AIC_BT_JUPITER_CTRL,
442 (REG_READ(ah, ATH_AIC_BT_JUPITER_CTRL) &
443 ~ATH_AIC_BT_AIC_ENABLE));
444
445 if (ar9003_aic_cal_post_process(ah))
446 aic->aic_cal_state = AIC_CAL_STATE_DONE;
447 else
448 aic->aic_cal_state = AIC_CAL_STATE_ERROR;
449}
450
451static u8 ar9003_aic_cal_continue(struct ath_hw *ah, bool cal_once)
452{
453 struct ath_common *common = ath9k_hw_common(ah);
454 struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;
455 struct ath9k_hw_aic *aic = &ah->btcoex_hw.aic;
456 int i, num_chan;
457
458 num_chan = MS(mci_hw->config, ATH_MCI_CONFIG_AIC_CAL_NUM_CHAN);
459
460 if (!num_chan) {
461 aic->aic_cal_state = AIC_CAL_STATE_ERROR;
462 return aic->aic_cal_state;
463 }
464
465 if (cal_once) {
466 for (i = 0; i < 10000; i++) {
467 if ((REG_READ(ah, AR_PHY_AIC_CTRL_0_B1) &
468 AR_PHY_AIC_CAL_ENABLE) == 0)
469 break;
470
471 udelay(100);
472 }
473 }
474
475 /*
476 * Use AR_PHY_AIC_CAL_ENABLE bit instead of AR_PHY_AIC_CAL_DONE.
477 * Sometimes CAL_DONE bit is not asserted.
478 */
479 if ((REG_READ(ah, AR_PHY_AIC_CTRL_0_B1) &
480 AR_PHY_AIC_CAL_ENABLE) != 0) {
481 ath_dbg(common, MCI, "AIC cal is not done after 40ms");
482 goto exit;
483 }
484
485 REG_WRITE(ah, AR_PHY_AIC_SRAM_ADDR_B1,
486 (ATH_AIC_SRAM_CAL_OFFSET | ATH_AIC_SRAM_AUTO_INCREMENT));
487
488 for (i = 0; i < ATH_AIC_MAX_BT_CHANNEL; i++) {
489 u32 value;
490
491 value = REG_READ(ah, AR_PHY_AIC_SRAM_DATA_B1);
492
493 if (value & 0x01) {
494 if (aic->aic_sram[i] == 0)
495 aic->aic_caled_chan++;
496
497 aic->aic_sram[i] = value;
498
499 if (!cal_once)
500 break;
501 }
502 }
503
504 if ((aic->aic_caled_chan >= num_chan) || cal_once) {
505 ar9003_aic_cal_done(ah);
506 } else {
507 /* Start calibration */
508 REG_CLR_BIT(ah, AR_PHY_AIC_CTRL_0_B1, AR_PHY_AIC_CAL_ENABLE);
509 REG_SET_BIT(ah, AR_PHY_AIC_CTRL_0_B1,
510 AR_PHY_AIC_CAL_CH_VALID_RESET);
511 REG_SET_BIT(ah, AR_PHY_AIC_CTRL_0_B1, AR_PHY_AIC_CAL_ENABLE);
512 }
513exit:
514 return aic->aic_cal_state;
515
516}
517
518u8 ar9003_aic_calibration(struct ath_hw *ah)
519{
520 struct ath9k_hw_aic *aic = &ah->btcoex_hw.aic;
521 u8 cal_ret = AIC_CAL_STATE_ERROR;
522
523 switch (aic->aic_cal_state) {
524 case AIC_CAL_STATE_IDLE:
525 cal_ret = ar9003_aic_cal_start(ah, 1);
526 break;
527 case AIC_CAL_STATE_STARTED:
528 cal_ret = ar9003_aic_cal_continue(ah, false);
529 break;
530 case AIC_CAL_STATE_DONE:
531 cal_ret = AIC_CAL_STATE_DONE;
532 break;
533 default:
534 break;
535 }
536
537 return cal_ret;
538}
539
540u8 ar9003_aic_start_normal(struct ath_hw *ah)
541{
542 struct ath9k_hw_aic *aic = &ah->btcoex_hw.aic;
543 int16_t i;
544
545 if (aic->aic_cal_state != AIC_CAL_STATE_DONE)
546 return 1;
547
548 ar9003_aic_gain_table(ah);
549
550 REG_WRITE(ah, AR_PHY_AIC_SRAM_ADDR_B1, ATH_AIC_SRAM_AUTO_INCREMENT);
551
552 for (i = 0; i < ATH_AIC_MAX_BT_CHANNEL; i++) {
553 REG_WRITE(ah, AR_PHY_AIC_SRAM_DATA_B1, aic->aic_sram[i]);
554 }
555
556 /* FIXME: Replace these with proper register names */
557 REG_WRITE(ah, 0xa6b0, 0x80);
558 REG_WRITE(ah, 0xa6b4, 0x5b2df0);
559 REG_WRITE(ah, 0xa6b8, 0x10762cc8);
560 REG_WRITE(ah, 0xa6bc, 0x1219a4b);
561 REG_WRITE(ah, 0xa6c0, 0x1e01);
562 REG_WRITE(ah, 0xb6b4, 0xf0);
563 REG_WRITE(ah, 0xb6c0, 0x1e01);
564 REG_WRITE(ah, 0xb6b0, 0x81);
565 REG_WRITE(ah, AR_PHY_65NM_CH1_RXTX4, 0x40000000);
566
567 aic->aic_enabled = true;
568
569 return 0;
570}
571
572u8 ar9003_aic_cal_reset(struct ath_hw *ah)
573{
574 struct ath9k_hw_aic *aic = &ah->btcoex_hw.aic;
575
576 aic->aic_cal_state = AIC_CAL_STATE_IDLE;
577 return aic->aic_cal_state;
578}
579
580u8 ar9003_aic_calibration_single(struct ath_hw *ah)
581{
582 struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;
583 u8 cal_ret;
584 int num_chan;
585
586 num_chan = MS(mci_hw->config, ATH_MCI_CONFIG_AIC_CAL_NUM_CHAN);
587
588 (void) ar9003_aic_cal_start(ah, num_chan);
589 cal_ret = ar9003_aic_cal_continue(ah, true);
590
591 return cal_ret;
592}
593
594void ar9003_hw_attach_aic_ops(struct ath_hw *ah)
595{
596 struct ath_hw_private_ops *priv_ops = ath9k_hw_private_ops(ah);
597
598 priv_ops->is_aic_enabled = ar9003_hw_is_aic_enabled;
599}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_aic.h b/drivers/net/wireless/ath/ath9k/ar9003_aic.h
new file mode 100644
index 000000000000..86f40644be43
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/ar9003_aic.h
@@ -0,0 +1,61 @@
1/*
2 * Copyright (c) 2015 Qualcomm Atheros Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef AR9003_AIC_H
18#define AR9003_AIC_H
19
20#define ATH_AIC_MAX_COM_ATT_DB_TABLE 6
21#define ATH_AIC_MAX_AIC_LIN_TABLE 69
22#define ATH_AIC_MIN_ROT_DIR_ATT_DB 0
23#define ATH_AIC_MIN_ROT_QUAD_ATT_DB 0
24#define ATH_AIC_MAX_ROT_DIR_ATT_DB 37
25#define ATH_AIC_MAX_ROT_QUAD_ATT_DB 37
26#define ATH_AIC_SRAM_AUTO_INCREMENT 0x80000000
27#define ATH_AIC_SRAM_GAIN_TABLE_OFFSET 0x280
28#define ATH_AIC_SRAM_CAL_OFFSET 0x140
29#define ATH_AIC_SRAM_OFFSET 0x00
30#define ATH_AIC_MEAS_MAG_THRESH 20
31#define ATH_AIC_BT_JUPITER_CTRL 0x66820
32#define ATH_AIC_BT_AIC_ENABLE 0x02
33
34enum aic_cal_state {
35 AIC_CAL_STATE_IDLE = 0,
36 AIC_CAL_STATE_STARTED,
37 AIC_CAL_STATE_DONE,
38 AIC_CAL_STATE_ERROR
39};
40
41struct ath_aic_sram_info {
42 bool valid:1;
43 bool vga_quad_sign:1;
44 bool vga_dir_sign:1;
45 u8 rot_quad_att_db;
46 u8 rot_dir_att_db;
47 u8 com_att_6db;
48};
49
50struct ath_aic_out_info {
51 int16_t dir_path_gain_lin;
52 int16_t quad_path_gain_lin;
53 struct ath_aic_sram_info sram;
54};
55
56u8 ar9003_aic_calibration(struct ath_hw *ah);
57u8 ar9003_aic_start_normal(struct ath_hw *ah);
58u8 ar9003_aic_cal_reset(struct ath_hw *ah);
59u8 ar9003_aic_calibration_single(struct ath_hw *ah);
60
61#endif /* AR9003_AIC_H */
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_hw.c b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
index 4335ccbe7d7e..79fd3b2dcbde 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_hw.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_hw.c
@@ -195,16 +195,16 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
195 INIT_INI_ARRAY(&ah->iniCckfirJapan2484, 195 INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
196 ar9485_1_1_baseband_core_txfir_coeff_japan_2484); 196 ar9485_1_1_baseband_core_txfir_coeff_japan_2484);
197 197
198 if (ah->config.no_pll_pwrsave) { 198 if (ah->config.pll_pwrsave & AR_PCIE_PLL_PWRSAVE_CONTROL) {
199 INIT_INI_ARRAY(&ah->iniPcieSerdes, 199 INIT_INI_ARRAY(&ah->iniPcieSerdes,
200 ar9485_1_1_pcie_phy_clkreq_disable_L1); 200 ar9485_1_1_pll_on_cdr_on_clkreq_disable_L1);
201 INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, 201 INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
202 ar9485_1_1_pcie_phy_clkreq_disable_L1); 202 ar9485_1_1_pll_on_cdr_on_clkreq_disable_L1);
203 } else { 203 } else {
204 INIT_INI_ARRAY(&ah->iniPcieSerdes, 204 INIT_INI_ARRAY(&ah->iniPcieSerdes,
205 ar9485_1_1_pll_on_cdr_on_clkreq_disable_L1); 205 ar9485_1_1_pcie_phy_clkreq_disable_L1);
206 INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, 206 INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
207 ar9485_1_1_pll_on_cdr_on_clkreq_disable_L1); 207 ar9485_1_1_pcie_phy_clkreq_disable_L1);
208 } 208 }
209 } else if (AR_SREV_9462_21(ah)) { 209 } else if (AR_SREV_9462_21(ah)) {
210 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], 210 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE],
@@ -231,10 +231,20 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
231 ar9462_2p1_modes_fast_clock); 231 ar9462_2p1_modes_fast_clock);
232 INIT_INI_ARRAY(&ah->iniCckfirJapan2484, 232 INIT_INI_ARRAY(&ah->iniCckfirJapan2484,
233 ar9462_2p1_baseband_core_txfir_coeff_japan_2484); 233 ar9462_2p1_baseband_core_txfir_coeff_japan_2484);
234 INIT_INI_ARRAY(&ah->iniPcieSerdes, 234
235 ar9462_2p1_pciephy_clkreq_disable_L1); 235 /* Awake -> Sleep Setting */
236 INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, 236 if ((ah->config.pll_pwrsave & AR_PCIE_PLL_PWRSAVE_CONTROL) &&
237 ar9462_2p1_pciephy_clkreq_disable_L1); 237 (ah->config.pll_pwrsave & AR_PCIE_PLL_PWRSAVE_ON_D3)) {
238 INIT_INI_ARRAY(&ah->iniPcieSerdes,
239 ar9462_2p1_pciephy_clkreq_disable_L1);
240 }
241
242 /* Sleep -> Awake Setting */
243 if ((ah->config.pll_pwrsave & AR_PCIE_PLL_PWRSAVE_CONTROL) &&
244 (ah->config.pll_pwrsave & AR_PCIE_PLL_PWRSAVE_ON_D0)) {
245 INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
246 ar9462_2p1_pciephy_clkreq_disable_L1);
247 }
238 } else if (AR_SREV_9462_20(ah)) { 248 } else if (AR_SREV_9462_20(ah)) {
239 249
240 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], ar9462_2p0_mac_core); 250 INIT_INI_ARRAY(&ah->iniMac[ATH_INI_CORE], ar9462_2p0_mac_core);
@@ -262,11 +272,18 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
262 ar9462_2p0_common_rx_gain); 272 ar9462_2p0_common_rx_gain);
263 273
264 /* Awake -> Sleep Setting */ 274 /* Awake -> Sleep Setting */
265 INIT_INI_ARRAY(&ah->iniPcieSerdes, 275 if ((ah->config.pll_pwrsave & AR_PCIE_PLL_PWRSAVE_CONTROL) &&
266 ar9462_2p0_pciephy_clkreq_disable_L1); 276 (ah->config.pll_pwrsave & AR_PCIE_PLL_PWRSAVE_ON_D3)) {
277 INIT_INI_ARRAY(&ah->iniPcieSerdes,
278 ar9462_2p0_pciephy_clkreq_disable_L1);
279 }
280
267 /* Sleep -> Awake Setting */ 281 /* Sleep -> Awake Setting */
268 INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, 282 if ((ah->config.pll_pwrsave & AR_PCIE_PLL_PWRSAVE_CONTROL) &&
269 ar9462_2p0_pciephy_clkreq_disable_L1); 283 (ah->config.pll_pwrsave & AR_PCIE_PLL_PWRSAVE_ON_D0)) {
284 INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
285 ar9462_2p0_pciephy_clkreq_disable_L1);
286 }
270 287
271 /* Fast clock modal settings */ 288 /* Fast clock modal settings */
272 INIT_INI_ARRAY(&ah->iniModesFastClock, 289 INIT_INI_ARRAY(&ah->iniModesFastClock,
@@ -456,10 +473,19 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
456 INIT_INI_ARRAY(&ah->iniModesTxGain, 473 INIT_INI_ARRAY(&ah->iniModesTxGain,
457 ar9565_1p1_Modes_lowest_ob_db_tx_gain_table); 474 ar9565_1p1_Modes_lowest_ob_db_tx_gain_table);
458 475
459 INIT_INI_ARRAY(&ah->iniPcieSerdes, 476 /* Awake -> Sleep Setting */
460 ar9565_1p1_pciephy_clkreq_disable_L1); 477 if ((ah->config.pll_pwrsave & AR_PCIE_PLL_PWRSAVE_CONTROL) &&
461 INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, 478 (ah->config.pll_pwrsave & AR_PCIE_PLL_PWRSAVE_ON_D3)) {
462 ar9565_1p1_pciephy_clkreq_disable_L1); 479 INIT_INI_ARRAY(&ah->iniPcieSerdes,
480 ar9565_1p1_pciephy_clkreq_disable_L1);
481 }
482
483 /* Sleep -> Awake Setting */
484 if ((ah->config.pll_pwrsave & AR_PCIE_PLL_PWRSAVE_CONTROL) &&
485 (ah->config.pll_pwrsave & AR_PCIE_PLL_PWRSAVE_ON_D0)) {
486 INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
487 ar9565_1p1_pciephy_clkreq_disable_L1);
488 }
463 489
464 INIT_INI_ARRAY(&ah->iniModesFastClock, 490 INIT_INI_ARRAY(&ah->iniModesFastClock,
465 ar9565_1p1_modes_fast_clock); 491 ar9565_1p1_modes_fast_clock);
@@ -491,10 +517,19 @@ static void ar9003_hw_init_mode_regs(struct ath_hw *ah)
491 INIT_INI_ARRAY(&ah->iniModesTxGain, 517 INIT_INI_ARRAY(&ah->iniModesTxGain,
492 ar9565_1p0_Modes_lowest_ob_db_tx_gain_table); 518 ar9565_1p0_Modes_lowest_ob_db_tx_gain_table);
493 519
494 INIT_INI_ARRAY(&ah->iniPcieSerdes, 520 /* Awake -> Sleep Setting */
495 ar9565_1p0_pciephy_clkreq_disable_L1); 521 if ((ah->config.pll_pwrsave & AR_PCIE_PLL_PWRSAVE_CONTROL) &&
496 INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower, 522 (ah->config.pll_pwrsave & AR_PCIE_PLL_PWRSAVE_ON_D3)) {
497 ar9565_1p0_pciephy_clkreq_disable_L1); 523 INIT_INI_ARRAY(&ah->iniPcieSerdes,
524 ar9565_1p0_pciephy_clkreq_disable_L1);
525 }
526
527 /* Sleep -> Awake Setting */
528 if ((ah->config.pll_pwrsave & AR_PCIE_PLL_PWRSAVE_CONTROL) &&
529 (ah->config.pll_pwrsave & AR_PCIE_PLL_PWRSAVE_ON_D0)) {
530 INIT_INI_ARRAY(&ah->iniPcieSerdesLowPower,
531 ar9565_1p0_pciephy_clkreq_disable_L1);
532 }
498 533
499 INIT_INI_ARRAY(&ah->iniModesFastClock, 534 INIT_INI_ARRAY(&ah->iniModesFastClock,
500 ar9565_1p0_modes_fast_clock); 535 ar9565_1p0_modes_fast_clock);
@@ -1130,6 +1165,12 @@ void ar9003_hw_attach_ops(struct ath_hw *ah)
1130 struct ath_hw_ops *ops = ath9k_hw_ops(ah); 1165 struct ath_hw_ops *ops = ath9k_hw_ops(ah);
1131 1166
1132 ar9003_hw_init_mode_regs(ah); 1167 ar9003_hw_init_mode_regs(ah);
1168
1169 if (AR_SREV_9003_PCOEM(ah)) {
1170 WARN_ON(!ah->iniPcieSerdes.ia_array);
1171 WARN_ON(!ah->iniPcieSerdesLowPower.ia_array);
1172 }
1173
1133 priv_ops->init_mode_gain_regs = ar9003_hw_init_mode_gain_regs; 1174 priv_ops->init_mode_gain_regs = ar9003_hw_init_mode_gain_regs;
1134 priv_ops->init_hang_checks = ar9003_hw_init_hang_checks; 1175 priv_ops->init_hang_checks = ar9003_hw_init_hang_checks;
1135 priv_ops->detect_mac_hang = ar9003_hw_detect_mac_hang; 1176 priv_ops->detect_mac_hang = ar9003_hw_detect_mac_hang;
@@ -1139,4 +1180,5 @@ void ar9003_hw_attach_ops(struct ath_hw *ah)
1139 ar9003_hw_attach_phy_ops(ah); 1180 ar9003_hw_attach_phy_ops(ah);
1140 ar9003_hw_attach_calib_ops(ah); 1181 ar9003_hw_attach_calib_ops(ah);
1141 ar9003_hw_attach_mac_ops(ah); 1182 ar9003_hw_attach_mac_ops(ah);
1183 ar9003_hw_attach_aic_ops(ah);
1142} 1184}
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.c b/drivers/net/wireless/ath/ath9k/ar9003_mci.c
index bd169fae32a1..af5ee416a560 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mci.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.c
@@ -19,6 +19,7 @@
19#include "hw-ops.h" 19#include "hw-ops.h"
20#include "ar9003_phy.h" 20#include "ar9003_phy.h"
21#include "ar9003_mci.h" 21#include "ar9003_mci.h"
22#include "ar9003_aic.h"
22 23
23static void ar9003_mci_reset_req_wakeup(struct ath_hw *ah) 24static void ar9003_mci_reset_req_wakeup(struct ath_hw *ah)
24{ 25{
@@ -1016,6 +1017,9 @@ int ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
1016 if (en_int) 1017 if (en_int)
1017 ar9003_mci_enable_interrupt(ah); 1018 ar9003_mci_enable_interrupt(ah);
1018 1019
1020 if (ath9k_hw_is_aic_enabled(ah))
1021 ar9003_aic_start_normal(ah);
1022
1019 return 0; 1023 return 0;
1020} 1024}
1021 1025
@@ -1362,6 +1366,22 @@ u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type)
1362 value = (!mci->unhalt_bt_gpm && mci->need_flush_btinfo) ? 1 : 0; 1366 value = (!mci->unhalt_bt_gpm && mci->need_flush_btinfo) ? 1 : 0;
1363 mci->need_flush_btinfo = false; 1367 mci->need_flush_btinfo = false;
1364 break; 1368 break;
1369 case MCI_STATE_AIC_CAL:
1370 if (ath9k_hw_is_aic_enabled(ah))
1371 value = ar9003_aic_calibration(ah);
1372 break;
1373 case MCI_STATE_AIC_START:
1374 if (ath9k_hw_is_aic_enabled(ah))
1375 ar9003_aic_start_normal(ah);
1376 break;
1377 case MCI_STATE_AIC_CAL_RESET:
1378 if (ath9k_hw_is_aic_enabled(ah))
1379 value = ar9003_aic_cal_reset(ah);
1380 break;
1381 case MCI_STATE_AIC_CAL_SINGLE:
1382 if (ath9k_hw_is_aic_enabled(ah))
1383 value = ar9003_aic_calibration_single(ah);
1384 break;
1365 default: 1385 default:
1366 break; 1386 break;
1367 } 1387 }
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
index c311b2bfdb00..fc595b92ac56 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
@@ -640,16 +640,6 @@
640#define AR_PHY_BB_THERM_ADC_4_LATEST_VOLT_VALUE 0x0000ff00 640#define AR_PHY_BB_THERM_ADC_4_LATEST_VOLT_VALUE 0x0000ff00
641#define AR_PHY_BB_THERM_ADC_4_LATEST_VOLT_VALUE_S 8 641#define AR_PHY_BB_THERM_ADC_4_LATEST_VOLT_VALUE_S 8
642 642
643/* AIC Registers */
644#define AR_PHY_AIC_CTRL_0_B0 (AR_SM_BASE + 0x4b0)
645#define AR_PHY_AIC_CTRL_1_B0 (AR_SM_BASE + 0x4b4)
646#define AR_PHY_AIC_CTRL_2_B0 (AR_SM_BASE + 0x4b8)
647#define AR_PHY_AIC_CTRL_3_B0 (AR_SM_BASE + 0x4bc)
648#define AR_PHY_AIC_STAT_0_B0 (AR_SM_BASE + 0x4c4))
649#define AR_PHY_AIC_STAT_1_B0 (AR_SM_BASE + 0x4c8))
650#define AR_PHY_AIC_CTRL_4_B0 (AR_SM_BASE + 0x4c0)
651#define AR_PHY_AIC_STAT_2_B0 (AR_SM_BASE + 0x4cc)
652
653#define AR_PHY_65NM_CH0_TXRF3 0x16048 643#define AR_PHY_65NM_CH0_TXRF3 0x16048
654#define AR_PHY_65NM_CH0_TXRF3_CAPDIV2G 0x0000001e 644#define AR_PHY_65NM_CH0_TXRF3_CAPDIV2G 0x0000001e
655#define AR_PHY_65NM_CH0_TXRF3_CAPDIV2G_S 1 645#define AR_PHY_65NM_CH0_TXRF3_CAPDIV2G_S 1
@@ -989,21 +979,6 @@
989#define AR_PHY_TX_IQCAL_STATUS_B1 (AR_SM1_BASE + 0x48c) 979#define AR_PHY_TX_IQCAL_STATUS_B1 (AR_SM1_BASE + 0x48c)
990#define AR_PHY_TX_IQCAL_CORR_COEFF_B1(_i) (AR_SM1_BASE + 0x450 + ((_i) << 2)) 980#define AR_PHY_TX_IQCAL_CORR_COEFF_B1(_i) (AR_SM1_BASE + 0x450 + ((_i) << 2))
991 981
992/* SM 1 AIC Registers */
993
994#define AR_PHY_AIC_CTRL_0_B1 (AR_SM1_BASE + 0x4b0)
995#define AR_PHY_AIC_CTRL_1_B1 (AR_SM1_BASE + 0x4b4)
996#define AR_PHY_AIC_CTRL_2_B1 (AR_SM1_BASE + 0x4b8)
997#define AR_PHY_AIC_STAT_0_B1 (AR_SM1_BASE + (AR_SREV_9462_10(ah) ? \
998 0x4c0 : 0x4c4))
999#define AR_PHY_AIC_STAT_1_B1 (AR_SM1_BASE + (AR_SREV_9462_10(ah) ? \
1000 0x4c4 : 0x4c8))
1001#define AR_PHY_AIC_CTRL_4_B1 (AR_SM1_BASE + 0x4c0)
1002#define AR_PHY_AIC_STAT_2_B1 (AR_SM1_BASE + 0x4cc)
1003
1004#define AR_PHY_AIC_SRAM_ADDR_B1 (AR_SM1_BASE + 0x5f0)
1005#define AR_PHY_AIC_SRAM_DATA_B1 (AR_SM1_BASE + 0x5f4)
1006
1007#define AR_PHY_RTT_TABLE_SW_INTF_B(i) (0x384 + ((i) ? \ 982#define AR_PHY_RTT_TABLE_SW_INTF_B(i) (0x384 + ((i) ? \
1008 AR_SM1_BASE : AR_SM_BASE)) 983 AR_SM1_BASE : AR_SM_BASE))
1009#define AR_PHY_RTT_TABLE_SW_INTF_1_B(i) (0x388 + ((i) ? \ 984#define AR_PHY_RTT_TABLE_SW_INTF_1_B(i) (0x388 + ((i) ? \
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_rtt.c b/drivers/net/wireless/ath/ath9k/ar9003_rtt.c
index 934418872e8e..e4d11fa7fe8c 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_rtt.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_rtt.c
@@ -106,7 +106,7 @@ void ar9003_hw_rtt_load_hist(struct ath_hw *ah)
106 int chain, i; 106 int chain, i;
107 107
108 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { 108 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
109 if (!(ah->rxchainmask & (1 << chain))) 109 if (!(ah->caps.rx_chainmask & (1 << chain)))
110 continue; 110 continue;
111 for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++) { 111 for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++) {
112 ar9003_hw_rtt_load_hist_entry(ah, chain, i, 112 ar9003_hw_rtt_load_hist_entry(ah, chain, i,
@@ -171,7 +171,7 @@ void ar9003_hw_rtt_fill_hist(struct ath_hw *ah)
171 int chain, i; 171 int chain, i;
172 172
173 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { 173 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
174 if (!(ah->rxchainmask & (1 << chain))) 174 if (!(ah->caps.rx_chainmask & (1 << chain)))
175 continue; 175 continue;
176 for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++) { 176 for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++) {
177 ah->caldata->rtt_table[chain][i] = 177 ah->caldata->rtt_table[chain][i] =
@@ -193,7 +193,7 @@ void ar9003_hw_rtt_clear_hist(struct ath_hw *ah)
193 int chain, i; 193 int chain, i;
194 194
195 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) { 195 for (chain = 0; chain < AR9300_MAX_CHAINS; chain++) {
196 if (!(ah->rxchainmask & (1 << chain))) 196 if (!(ah->caps.rx_chainmask & (1 << chain)))
197 continue; 197 continue;
198 for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++) 198 for (i = 0; i < MAX_RTT_TABLE_ENTRY; i++)
199 ar9003_hw_rtt_load_hist_entry(ah, chain, i, 0); 199 ar9003_hw_rtt_load_hist_entry(ah, chain, i, 0);
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 7e89236c0e13..a7a81b3969ce 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -184,12 +184,12 @@ struct ath_frame_info {
184 struct ath_buf *bf; 184 struct ath_buf *bf;
185 u16 framelen; 185 u16 framelen;
186 s8 txq; 186 s8 txq;
187 enum ath9k_key_type keytype;
188 u8 keyix; 187 u8 keyix;
189 u8 rtscts_rate; 188 u8 rtscts_rate;
190 u8 retries : 7; 189 u8 retries : 7;
191 u8 baw_tracked : 1; 190 u8 baw_tracked : 1;
192 u8 tx_power; 191 u8 tx_power;
192 enum ath9k_key_type keytype:2;
193}; 193};
194 194
195struct ath_rxbuf { 195struct ath_rxbuf {
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.h b/drivers/net/wireless/ath/ath9k/btcoex.h
index 5fe62ff2223b..cd2f0a2373cb 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.h
+++ b/drivers/net/wireless/ath/ath9k/btcoex.h
@@ -44,6 +44,9 @@
44 44
45#define AR9300_NUM_BT_WEIGHTS 4 45#define AR9300_NUM_BT_WEIGHTS 4
46#define AR9300_NUM_WLAN_WEIGHTS 4 46#define AR9300_NUM_WLAN_WEIGHTS 4
47
48#define ATH_AIC_MAX_BT_CHANNEL 79
49
47/* Defines the BT AR_BT_COEX_WGHT used */ 50/* Defines the BT AR_BT_COEX_WGHT used */
48enum ath_stomp_type { 51enum ath_stomp_type {
49 ATH_BTCOEX_STOMP_ALL, 52 ATH_BTCOEX_STOMP_ALL,
@@ -93,9 +96,18 @@ struct ath9k_hw_mci {
93 u32 last_recovery; 96 u32 last_recovery;
94}; 97};
95 98
99struct ath9k_hw_aic {
100 bool aic_enabled;
101 u8 aic_cal_state;
102 u8 aic_caled_chan;
103 u32 aic_sram[ATH_AIC_MAX_BT_CHANNEL];
104 u32 aic_cal_start_time;
105};
106
96struct ath_btcoex_hw { 107struct ath_btcoex_hw {
97 enum ath_btcoex_scheme scheme; 108 enum ath_btcoex_scheme scheme;
98 struct ath9k_hw_mci mci; 109 struct ath9k_hw_mci mci;
110 struct ath9k_hw_aic aic;
99 bool enabled; 111 bool enabled;
100 u8 wlanactive_gpio; 112 u8 wlanactive_gpio;
101 u8 btactive_gpio; 113 u8 btactive_gpio;
diff --git a/drivers/net/wireless/ath/ath9k/calib.c b/drivers/net/wireless/ath/ath9k/calib.c
index e200a6e3aca5..3e2e24e4843f 100644
--- a/drivers/net/wireless/ath/ath9k/calib.c
+++ b/drivers/net/wireless/ath/ath9k/calib.c
@@ -238,7 +238,6 @@ int ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
238{ 238{
239 struct ath9k_nfcal_hist *h = NULL; 239 struct ath9k_nfcal_hist *h = NULL;
240 unsigned i, j; 240 unsigned i, j;
241 int32_t val;
242 u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask; 241 u8 chainmask = (ah->rxchainmask << 3) | ah->rxchainmask;
243 struct ath_common *common = ath9k_hw_common(ah); 242 struct ath_common *common = ath9k_hw_common(ah);
244 s16 default_nf = ath9k_hw_get_default_nf(ah, chan); 243 s16 default_nf = ath9k_hw_get_default_nf(ah, chan);
@@ -246,6 +245,7 @@ int ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
246 if (ah->caldata) 245 if (ah->caldata)
247 h = ah->caldata->nfCalHist; 246 h = ah->caldata->nfCalHist;
248 247
248 ENABLE_REG_RMW_BUFFER(ah);
249 for (i = 0; i < NUM_NF_READINGS; i++) { 249 for (i = 0; i < NUM_NF_READINGS; i++) {
250 if (chainmask & (1 << i)) { 250 if (chainmask & (1 << i)) {
251 s16 nfval; 251 s16 nfval;
@@ -258,10 +258,8 @@ int ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
258 else 258 else
259 nfval = default_nf; 259 nfval = default_nf;
260 260
261 val = REG_READ(ah, ah->nf_regs[i]); 261 REG_RMW(ah, ah->nf_regs[i],
262 val &= 0xFFFFFE00; 262 (((u32) nfval << 1) & 0x1ff), 0x1ff);
263 val |= (((u32) nfval << 1) & 0x1ff);
264 REG_WRITE(ah, ah->nf_regs[i], val);
265 } 263 }
266 } 264 }
267 265
@@ -274,6 +272,7 @@ int ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
274 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL, 272 REG_CLR_BIT(ah, AR_PHY_AGC_CONTROL,
275 AR_PHY_AGC_CONTROL_NO_UPDATE_NF); 273 AR_PHY_AGC_CONTROL_NO_UPDATE_NF);
276 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF); 274 REG_SET_BIT(ah, AR_PHY_AGC_CONTROL, AR_PHY_AGC_CONTROL_NF);
275 REG_RMW_BUFFER_FLUSH(ah);
277 276
278 /* 277 /*
279 * Wait for load to complete, should be fast, a few 10s of us. 278 * Wait for load to complete, should be fast, a few 10s of us.
@@ -309,19 +308,17 @@ int ath9k_hw_loadnf(struct ath_hw *ah, struct ath9k_channel *chan)
309 * by the median we just loaded. This will be initial (and max) value 308 * by the median we just loaded. This will be initial (and max) value
310 * of next noise floor calibration the baseband does. 309 * of next noise floor calibration the baseband does.
311 */ 310 */
312 ENABLE_REGWRITE_BUFFER(ah); 311 ENABLE_REG_RMW_BUFFER(ah);
313 for (i = 0; i < NUM_NF_READINGS; i++) { 312 for (i = 0; i < NUM_NF_READINGS; i++) {
314 if (chainmask & (1 << i)) { 313 if (chainmask & (1 << i)) {
315 if ((i >= AR5416_MAX_CHAINS) && !IS_CHAN_HT40(chan)) 314 if ((i >= AR5416_MAX_CHAINS) && !IS_CHAN_HT40(chan))
316 continue; 315 continue;
317 316
318 val = REG_READ(ah, ah->nf_regs[i]); 317 REG_RMW(ah, ah->nf_regs[i],
319 val &= 0xFFFFFE00; 318 (((u32) (-50) << 1) & 0x1ff), 0x1ff);
320 val |= (((u32) (-50) << 1) & 0x1ff);
321 REG_WRITE(ah, ah->nf_regs[i], val);
322 } 319 }
323 } 320 }
324 REGWRITE_BUFFER_FLUSH(ah); 321 REG_RMW_BUFFER_FLUSH(ah);
325 322
326 return 0; 323 return 0;
327} 324}
diff --git a/drivers/net/wireless/ath/ath9k/dfs.c b/drivers/net/wireless/ath/ath9k/dfs.c
index 726271c7c330..e98a9eaba7ff 100644
--- a/drivers/net/wireless/ath/ath9k/dfs.c
+++ b/drivers/net/wireless/ath/ath9k/dfs.c
@@ -126,8 +126,19 @@ ath9k_postprocess_radar_event(struct ath_softc *sc,
126 DFS_STAT_INC(sc, pulses_detected); 126 DFS_STAT_INC(sc, pulses_detected);
127 return true; 127 return true;
128} 128}
129#undef PRI_CH_RADAR_FOUND 129
130#undef EXT_CH_RADAR_FOUND 130static void
131ath9k_dfs_process_radar_pulse(struct ath_softc *sc, struct pulse_event *pe)
132{
133 struct dfs_pattern_detector *pd = sc->dfs_detector;
134 DFS_STAT_INC(sc, pulses_processed);
135 if (pd == NULL)
136 return;
137 if (!pd->add_pulse(pd, pe))
138 return;
139 DFS_STAT_INC(sc, radar_detected);
140 ieee80211_radar_detected(sc->hw);
141}
131 142
132/* 143/*
133 * DFS: check PHY-error for radar pulse and feed the detector 144 * DFS: check PHY-error for radar pulse and feed the detector
@@ -176,18 +187,21 @@ void ath9k_dfs_process_phyerr(struct ath_softc *sc, void *data,
176 ard.pulse_length_pri = vdata_end[-3]; 187 ard.pulse_length_pri = vdata_end[-3];
177 pe.freq = ah->curchan->channel; 188 pe.freq = ah->curchan->channel;
178 pe.ts = mactime; 189 pe.ts = mactime;
179 if (ath9k_postprocess_radar_event(sc, &ard, &pe)) { 190 if (!ath9k_postprocess_radar_event(sc, &ard, &pe))
180 struct dfs_pattern_detector *pd = sc->dfs_detector; 191 return;
181 ath_dbg(common, DFS, 192
182 "ath9k_dfs_process_phyerr: channel=%d, ts=%llu, " 193 ath_dbg(common, DFS,
183 "width=%d, rssi=%d, delta_ts=%llu\n", 194 "ath9k_dfs_process_phyerr: type=%d, freq=%d, ts=%llu, "
184 pe.freq, pe.ts, pe.width, pe.rssi, 195 "width=%d, rssi=%d, delta_ts=%llu\n",
185 pe.ts - sc->dfs_prev_pulse_ts); 196 ard.pulse_bw_info, pe.freq, pe.ts, pe.width, pe.rssi,
186 sc->dfs_prev_pulse_ts = pe.ts; 197 pe.ts - sc->dfs_prev_pulse_ts);
187 DFS_STAT_INC(sc, pulses_processed); 198 sc->dfs_prev_pulse_ts = pe.ts;
188 if (pd != NULL && pd->add_pulse(pd, &pe)) { 199 if (ard.pulse_bw_info & PRI_CH_RADAR_FOUND)
189 DFS_STAT_INC(sc, radar_detected); 200 ath9k_dfs_process_radar_pulse(sc, &pe);
190 ieee80211_radar_detected(sc->hw); 201 if (ard.pulse_bw_info & EXT_CH_RADAR_FOUND) {
191 } 202 pe.freq += IS_CHAN_HT40PLUS(ah->curchan) ? 20 : -20;
203 ath9k_dfs_process_radar_pulse(sc, &pe);
192 } 204 }
193} 205}
206#undef PRI_CH_RADAR_FOUND
207#undef EXT_CH_RADAR_FOUND
diff --git a/drivers/net/wireless/ath/ath9k/eeprom.c b/drivers/net/wireless/ath/ath9k/eeprom.c
index 971d770722cf..cc81482c934d 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom.c
@@ -27,12 +27,7 @@ void ath9k_hw_analog_shift_regwrite(struct ath_hw *ah, u32 reg, u32 val)
27void ath9k_hw_analog_shift_rmw(struct ath_hw *ah, u32 reg, u32 mask, 27void ath9k_hw_analog_shift_rmw(struct ath_hw *ah, u32 reg, u32 mask,
28 u32 shift, u32 val) 28 u32 shift, u32 val)
29{ 29{
30 u32 regVal; 30 REG_RMW(ah, reg, ((val << shift) & mask), mask);
31
32 regVal = REG_READ(ah, reg) & ~mask;
33 regVal |= (val << shift) & mask;
34
35 REG_WRITE(ah, reg, regVal);
36 31
37 if (ah->config.analog_shiftreg) 32 if (ah->config.analog_shiftreg)
38 udelay(100); 33 udelay(100);
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_4k.c b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
index e5a78d4fd66e..4773da6dc6f2 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_4k.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_4k.c
@@ -389,6 +389,7 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
389 } 389 }
390 } 390 }
391 391
392 ENABLE_REG_RMW_BUFFER(ah);
392 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN, 393 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_NUM_PD_GAIN,
393 (numXpdGain - 1) & 0x3); 394 (numXpdGain - 1) & 0x3);
394 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1, 395 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_1,
@@ -396,6 +397,7 @@ static void ath9k_hw_set_4k_power_cal_table(struct ath_hw *ah,
396 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2, 397 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_2,
397 xpdGainValues[1]); 398 xpdGainValues[1]);
398 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3, 0); 399 REG_RMW_FIELD(ah, AR_PHY_TPCRG1, AR_PHY_TPCRG1_PD_GAIN_3, 0);
400 REG_RMW_BUFFER_FLUSH(ah);
399 401
400 for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++) { 402 for (i = 0; i < AR5416_EEP4K_MAX_CHAINS; i++) {
401 regChainOffset = i * 0x1000; 403 regChainOffset = i * 0x1000;
@@ -770,15 +772,14 @@ static void ath9k_hw_4k_set_gain(struct ath_hw *ah,
770 struct ar5416_eeprom_4k *eep, 772 struct ar5416_eeprom_4k *eep,
771 u8 txRxAttenLocal) 773 u8 txRxAttenLocal)
772{ 774{
773 REG_WRITE(ah, AR_PHY_SWITCH_CHAIN_0, 775 ENABLE_REG_RMW_BUFFER(ah);
774 pModal->antCtrlChain[0]); 776 REG_RMW(ah, AR_PHY_SWITCH_CHAIN_0,
777 pModal->antCtrlChain[0], 0);
775 778
776 REG_WRITE(ah, AR_PHY_TIMING_CTRL4(0), 779 REG_RMW(ah, AR_PHY_TIMING_CTRL4(0),
777 (REG_READ(ah, AR_PHY_TIMING_CTRL4(0)) & 780 SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
778 ~(AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF | 781 SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF),
779 AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF)) | 782 AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF | AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF);
780 SM(pModal->iqCalICh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_I_COFF) |
781 SM(pModal->iqCalQCh[0], AR_PHY_TIMING_CTRL4_IQCORR_Q_Q_COFF));
782 783
783 if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >= 784 if ((eep->baseEepHeader.version & AR5416_EEP_VER_MINOR_MASK) >=
784 AR5416_EEP_MINOR_VER_3) { 785 AR5416_EEP_MINOR_VER_3) {
@@ -817,6 +818,7 @@ static void ath9k_hw_4k_set_gain(struct ath_hw *ah,
817 AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal); 818 AR9280_PHY_RXGAIN_TXRX_ATTEN, txRxAttenLocal);
818 REG_RMW_FIELD(ah, AR_PHY_RXGAIN + 0x1000, 819 REG_RMW_FIELD(ah, AR_PHY_RXGAIN + 0x1000,
819 AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]); 820 AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[0]);
821 REG_RMW_BUFFER_FLUSH(ah);
820} 822}
821 823
822/* 824/*
@@ -928,6 +930,7 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
928 } 930 }
929 } 931 }
930 932
933 ENABLE_REG_RMW_BUFFER(ah);
931 if (AR_SREV_9271(ah)) { 934 if (AR_SREV_9271(ah)) {
932 ath9k_hw_analog_shift_rmw(ah, 935 ath9k_hw_analog_shift_rmw(ah,
933 AR9285_AN_RF2G3, 936 AR9285_AN_RF2G3,
@@ -1032,18 +1035,19 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
1032 AR9285_AN_RF2G4_DB2_4_S, 1035 AR9285_AN_RF2G4_DB2_4_S,
1033 db2[4]); 1036 db2[4]);
1034 } 1037 }
1038 REG_RMW_BUFFER_FLUSH(ah);
1035 1039
1036 1040 ENABLE_REG_RMW_BUFFER(ah);
1037 REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH, 1041 REG_RMW_FIELD(ah, AR_PHY_SETTLING, AR_PHY_SETTLING_SWITCH,
1038 pModal->switchSettling); 1042 pModal->switchSettling);
1039 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC, 1043 REG_RMW_FIELD(ah, AR_PHY_DESIRED_SZ, AR_PHY_DESIRED_SZ_ADC,
1040 pModal->adcDesiredSize); 1044 pModal->adcDesiredSize);
1041 1045
1042 REG_WRITE(ah, AR_PHY_RF_CTL4, 1046 REG_RMW(ah, AR_PHY_RF_CTL4,
1043 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) | 1047 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAA_OFF) |
1044 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) | 1048 SM(pModal->txEndToXpaOff, AR_PHY_RF_CTL4_TX_END_XPAB_OFF) |
1045 SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON) | 1049 SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAA_ON) |
1046 SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON)); 1050 SM(pModal->txFrameToXpaOn, AR_PHY_RF_CTL4_FRAME_XPAB_ON), 0);
1047 1051
1048 REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON, 1052 REG_RMW_FIELD(ah, AR_PHY_RF_CTL3, AR_PHY_TX_END_TO_A2_RX_ON,
1049 pModal->txEndToRxOn); 1053 pModal->txEndToRxOn);
@@ -1072,6 +1076,8 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
1072 pModal->swSettleHt40); 1076 pModal->swSettleHt40);
1073 } 1077 }
1074 1078
1079 REG_RMW_BUFFER_FLUSH(ah);
1080
1075 bb_desired_scale = (pModal->bb_scale_smrt_antenna & 1081 bb_desired_scale = (pModal->bb_scale_smrt_antenna &
1076 EEP_4K_BB_DESIRED_SCALE_MASK); 1082 EEP_4K_BB_DESIRED_SCALE_MASK);
1077 if ((pBase->txGainType == 0) && (bb_desired_scale != 0)) { 1083 if ((pBase->txGainType == 0) && (bb_desired_scale != 0)) {
@@ -1080,6 +1086,7 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
1080 mask = BIT(0)|BIT(5)|BIT(10)|BIT(15)|BIT(20)|BIT(25); 1086 mask = BIT(0)|BIT(5)|BIT(10)|BIT(15)|BIT(20)|BIT(25);
1081 pwrctrl = mask * bb_desired_scale; 1087 pwrctrl = mask * bb_desired_scale;
1082 clr = mask * 0x1f; 1088 clr = mask * 0x1f;
1089 ENABLE_REG_RMW_BUFFER(ah);
1083 REG_RMW(ah, AR_PHY_TX_PWRCTRL8, pwrctrl, clr); 1090 REG_RMW(ah, AR_PHY_TX_PWRCTRL8, pwrctrl, clr);
1084 REG_RMW(ah, AR_PHY_TX_PWRCTRL10, pwrctrl, clr); 1091 REG_RMW(ah, AR_PHY_TX_PWRCTRL10, pwrctrl, clr);
1085 REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL12, pwrctrl, clr); 1092 REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL12, pwrctrl, clr);
@@ -1094,6 +1101,7 @@ static void ath9k_hw_4k_set_board_values(struct ath_hw *ah,
1094 clr = mask * 0x1f; 1101 clr = mask * 0x1f;
1095 REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL11, pwrctrl, clr); 1102 REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL11, pwrctrl, clr);
1096 REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL13, pwrctrl, clr); 1103 REG_RMW(ah, AR_PHY_CH0_TX_PWRCTRL13, pwrctrl, clr);
1104 REG_RMW_BUFFER_FLUSH(ah);
1097 } 1105 }
1098} 1106}
1099 1107
diff --git a/drivers/net/wireless/ath/ath9k/eeprom_def.c b/drivers/net/wireless/ath/ath9k/eeprom_def.c
index 098059039351..056f516bf017 100644
--- a/drivers/net/wireless/ath/ath9k/eeprom_def.c
+++ b/drivers/net/wireless/ath/ath9k/eeprom_def.c
@@ -466,6 +466,7 @@ static void ath9k_hw_def_set_gain(struct ath_hw *ah,
466 struct ar5416_eeprom_def *eep, 466 struct ar5416_eeprom_def *eep,
467 u8 txRxAttenLocal, int regChainOffset, int i) 467 u8 txRxAttenLocal, int regChainOffset, int i)
468{ 468{
469 ENABLE_REG_RMW_BUFFER(ah);
469 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) { 470 if (AR5416_VER_MASK >= AR5416_EEP_MINOR_VER_3) {
470 txRxAttenLocal = pModal->txRxAttenCh[i]; 471 txRxAttenLocal = pModal->txRxAttenCh[i];
471 472
@@ -483,16 +484,12 @@ static void ath9k_hw_def_set_gain(struct ath_hw *ah,
483 AR_PHY_GAIN_2GHZ_XATTEN2_DB, 484 AR_PHY_GAIN_2GHZ_XATTEN2_DB,
484 pModal->xatten2Db[i]); 485 pModal->xatten2Db[i]);
485 } else { 486 } else {
486 REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 487 REG_RMW(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
487 (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) & 488 SM(pModal-> bswMargin[i], AR_PHY_GAIN_2GHZ_BSW_MARGIN),
488 ~AR_PHY_GAIN_2GHZ_BSW_MARGIN) 489 AR_PHY_GAIN_2GHZ_BSW_MARGIN);
489 | SM(pModal-> bswMargin[i], 490 REG_RMW(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
490 AR_PHY_GAIN_2GHZ_BSW_MARGIN)); 491 SM(pModal->bswAtten[i], AR_PHY_GAIN_2GHZ_BSW_ATTEN),
491 REG_WRITE(ah, AR_PHY_GAIN_2GHZ + regChainOffset, 492 AR_PHY_GAIN_2GHZ_BSW_ATTEN);
492 (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
493 ~AR_PHY_GAIN_2GHZ_BSW_ATTEN)
494 | SM(pModal->bswAtten[i],
495 AR_PHY_GAIN_2GHZ_BSW_ATTEN));
496 } 493 }
497 } 494 }
498 495
@@ -504,17 +501,14 @@ static void ath9k_hw_def_set_gain(struct ath_hw *ah,
504 AR_PHY_RXGAIN + regChainOffset, 501 AR_PHY_RXGAIN + regChainOffset,
505 AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[i]); 502 AR9280_PHY_RXGAIN_TXRX_MARGIN, pModal->rxTxMarginCh[i]);
506 } else { 503 } else {
507 REG_WRITE(ah, 504 REG_RMW(ah, AR_PHY_RXGAIN + regChainOffset,
508 AR_PHY_RXGAIN + regChainOffset, 505 SM(txRxAttenLocal, AR_PHY_RXGAIN_TXRX_ATTEN),
509 (REG_READ(ah, AR_PHY_RXGAIN + regChainOffset) & 506 AR_PHY_RXGAIN_TXRX_ATTEN);
510 ~AR_PHY_RXGAIN_TXRX_ATTEN) 507 REG_RMW(ah, AR_PHY_GAIN_2GHZ + regChainOffset,
511 | SM(txRxAttenLocal, AR_PHY_RXGAIN_TXRX_ATTEN)); 508 SM(pModal->rxTxMarginCh[i], AR_PHY_GAIN_2GHZ_RXTX_MARGIN),
512 REG_WRITE(ah, 509 AR_PHY_GAIN_2GHZ_RXTX_MARGIN);
513 AR_PHY_GAIN_2GHZ + regChainOffset,
514 (REG_READ(ah, AR_PHY_GAIN_2GHZ + regChainOffset) &
515 ~AR_PHY_GAIN_2GHZ_RXTX_MARGIN) |
516 SM(pModal->rxTxMarginCh[i], AR_PHY_GAIN_2GHZ_RXTX_MARGIN));
517 } 510 }
511 REG_RMW_BUFFER_FLUSH(ah);
518} 512}
519 513
520static void ath9k_hw_def_set_board_values(struct ath_hw *ah, 514static void ath9k_hw_def_set_board_values(struct ath_hw *ah,
diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h
index 300d3671d0ef..e82a0d4ce23f 100644
--- a/drivers/net/wireless/ath/ath9k/htc.h
+++ b/drivers/net/wireless/ath/ath9k/htc.h
@@ -444,6 +444,10 @@ static inline void ath9k_htc_stop_btcoex(struct ath9k_htc_priv *priv)
444#define OP_BT_SCAN BIT(4) 444#define OP_BT_SCAN BIT(4)
445#define OP_TSF_RESET BIT(6) 445#define OP_TSF_RESET BIT(6)
446 446
447enum htc_op_flags {
448 HTC_FWFLAG_NO_RMW,
449};
450
447struct ath9k_htc_priv { 451struct ath9k_htc_priv {
448 struct device *dev; 452 struct device *dev;
449 struct ieee80211_hw *hw; 453 struct ieee80211_hw *hw;
@@ -482,6 +486,7 @@ struct ath9k_htc_priv {
482 bool reconfig_beacon; 486 bool reconfig_beacon;
483 unsigned int rxfilter; 487 unsigned int rxfilter;
484 unsigned long op_flags; 488 unsigned long op_flags;
489 unsigned long fw_flags;
485 490
486 struct ath9k_hw_cal_data caldata; 491 struct ath9k_hw_cal_data caldata;
487 struct ath_spec_scan_priv spec_priv; 492 struct ath_spec_scan_priv spec_priv;
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_init.c b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
index fd229409f676..d7beefe60683 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_init.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_init.c
@@ -376,17 +376,139 @@ static void ath9k_regwrite_flush(void *hw_priv)
376 mutex_unlock(&priv->wmi->multi_write_mutex); 376 mutex_unlock(&priv->wmi->multi_write_mutex);
377} 377}
378 378
379static u32 ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 clr) 379static void ath9k_reg_rmw_buffer(void *hw_priv,
380 u32 reg_offset, u32 set, u32 clr)
381{
382 struct ath_hw *ah = (struct ath_hw *) hw_priv;
383 struct ath_common *common = ath9k_hw_common(ah);
384 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
385 u32 rsp_status;
386 int r;
387
388 mutex_lock(&priv->wmi->multi_rmw_mutex);
389
390 /* Store the register/value */
391 priv->wmi->multi_rmw[priv->wmi->multi_rmw_idx].reg =
392 cpu_to_be32(reg_offset);
393 priv->wmi->multi_rmw[priv->wmi->multi_rmw_idx].set =
394 cpu_to_be32(set);
395 priv->wmi->multi_rmw[priv->wmi->multi_rmw_idx].clr =
396 cpu_to_be32(clr);
397
398 priv->wmi->multi_rmw_idx++;
399
400 /* If the buffer is full, send it out. */
401 if (priv->wmi->multi_rmw_idx == MAX_RMW_CMD_NUMBER) {
402 r = ath9k_wmi_cmd(priv->wmi, WMI_REG_RMW_CMDID,
403 (u8 *) &priv->wmi->multi_rmw,
404 sizeof(struct register_write) * priv->wmi->multi_rmw_idx,
405 (u8 *) &rsp_status, sizeof(rsp_status),
406 100);
407 if (unlikely(r)) {
408 ath_dbg(common, WMI,
409 "REGISTER RMW FAILED, multi len: %d\n",
410 priv->wmi->multi_rmw_idx);
411 }
412 priv->wmi->multi_rmw_idx = 0;
413 }
414
415 mutex_unlock(&priv->wmi->multi_rmw_mutex);
416}
417
418static void ath9k_reg_rmw_flush(void *hw_priv)
380{ 419{
381 u32 val; 420 struct ath_hw *ah = (struct ath_hw *) hw_priv;
421 struct ath_common *common = ath9k_hw_common(ah);
422 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
423 u32 rsp_status;
424 int r;
425
426 if (test_bit(HTC_FWFLAG_NO_RMW, &priv->fw_flags))
427 return;
428
429 atomic_dec(&priv->wmi->m_rmw_cnt);
382 430
383 val = ath9k_regread(hw_priv, reg_offset); 431 mutex_lock(&priv->wmi->multi_rmw_mutex);
384 val &= ~clr; 432
385 val |= set; 433 if (priv->wmi->multi_rmw_idx) {
386 ath9k_regwrite(hw_priv, val, reg_offset); 434 r = ath9k_wmi_cmd(priv->wmi, WMI_REG_RMW_CMDID,
435 (u8 *) &priv->wmi->multi_rmw,
436 sizeof(struct register_rmw) * priv->wmi->multi_rmw_idx,
437 (u8 *) &rsp_status, sizeof(rsp_status),
438 100);
439 if (unlikely(r)) {
440 ath_dbg(common, WMI,
441 "REGISTER RMW FAILED, multi len: %d\n",
442 priv->wmi->multi_rmw_idx);
443 }
444 priv->wmi->multi_rmw_idx = 0;
445 }
446
447 mutex_unlock(&priv->wmi->multi_rmw_mutex);
448}
449
450static void ath9k_enable_rmw_buffer(void *hw_priv)
451{
452 struct ath_hw *ah = (struct ath_hw *) hw_priv;
453 struct ath_common *common = ath9k_hw_common(ah);
454 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
455
456 if (test_bit(HTC_FWFLAG_NO_RMW, &priv->fw_flags))
457 return;
458
459 atomic_inc(&priv->wmi->m_rmw_cnt);
460}
461
462static u32 ath9k_reg_rmw_single(void *hw_priv,
463 u32 reg_offset, u32 set, u32 clr)
464{
465 struct ath_hw *ah = (struct ath_hw *) hw_priv;
466 struct ath_common *common = ath9k_hw_common(ah);
467 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
468 struct register_rmw buf, buf_ret;
469 int ret;
470 u32 val = 0;
471
472 buf.reg = cpu_to_be32(reg_offset);
473 buf.set = cpu_to_be32(set);
474 buf.clr = cpu_to_be32(clr);
475
476 ret = ath9k_wmi_cmd(priv->wmi, WMI_REG_RMW_CMDID,
477 (u8 *) &buf, sizeof(buf),
478 (u8 *) &buf_ret, sizeof(buf_ret),
479 100);
480 if (unlikely(ret)) {
481 ath_dbg(common, WMI, "REGISTER RMW FAILED:(0x%04x, %d)\n",
482 reg_offset, ret);
483 }
387 return val; 484 return val;
388} 485}
389 486
487static u32 ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 clr)
488{
489 struct ath_hw *ah = (struct ath_hw *) hw_priv;
490 struct ath_common *common = ath9k_hw_common(ah);
491 struct ath9k_htc_priv *priv = (struct ath9k_htc_priv *) common->priv;
492
493 if (test_bit(HTC_FWFLAG_NO_RMW, &priv->fw_flags)) {
494 u32 val;
495
496 val = REG_READ(ah, reg_offset);
497 val &= ~clr;
498 val |= set;
499 REG_WRITE(ah, reg_offset, val);
500
501 return 0;
502 }
503
504 if (atomic_read(&priv->wmi->m_rmw_cnt))
505 ath9k_reg_rmw_buffer(hw_priv, reg_offset, set, clr);
506 else
507 ath9k_reg_rmw_single(hw_priv, reg_offset, set, clr);
508
509 return 0;
510}
511
390static void ath_usb_read_cachesize(struct ath_common *common, int *csz) 512static void ath_usb_read_cachesize(struct ath_common *common, int *csz)
391{ 513{
392 *csz = L1_CACHE_BYTES >> 2; 514 *csz = L1_CACHE_BYTES >> 2;
@@ -501,6 +623,8 @@ static int ath9k_init_priv(struct ath9k_htc_priv *priv,
501 ah->reg_ops.write = ath9k_regwrite; 623 ah->reg_ops.write = ath9k_regwrite;
502 ah->reg_ops.enable_write_buffer = ath9k_enable_regwrite_buffer; 624 ah->reg_ops.enable_write_buffer = ath9k_enable_regwrite_buffer;
503 ah->reg_ops.write_flush = ath9k_regwrite_flush; 625 ah->reg_ops.write_flush = ath9k_regwrite_flush;
626 ah->reg_ops.enable_rmw_buffer = ath9k_enable_rmw_buffer;
627 ah->reg_ops.rmw_flush = ath9k_reg_rmw_flush;
504 ah->reg_ops.rmw = ath9k_reg_rmw; 628 ah->reg_ops.rmw = ath9k_reg_rmw;
505 priv->ah = ah; 629 priv->ah = ah;
506 630
@@ -686,6 +810,12 @@ static int ath9k_init_firmware_version(struct ath9k_htc_priv *priv)
686 return -EINVAL; 810 return -EINVAL;
687 } 811 }
688 812
813 if (priv->fw_version_major == 1 && priv->fw_version_minor < 4)
814 set_bit(HTC_FWFLAG_NO_RMW, &priv->fw_flags);
815
816 dev_info(priv->dev, "FW RMW support: %s\n",
817 test_bit(HTC_FWFLAG_NO_RMW, &priv->fw_flags) ? "Off" : "On");
818
689 return 0; 819 return 0;
690} 820}
691 821
diff --git a/drivers/net/wireless/ath/ath9k/hw-ops.h b/drivers/net/wireless/ath/ath9k/hw-ops.h
index 88769b64b20b..232339b05540 100644
--- a/drivers/net/wireless/ath/ath9k/hw-ops.h
+++ b/drivers/net/wireless/ath/ath9k/hw-ops.h
@@ -108,6 +108,14 @@ static inline void ath9k_hw_set_bt_ant_diversity(struct ath_hw *ah, bool enable)
108 ath9k_hw_ops(ah)->set_bt_ant_diversity(ah, enable); 108 ath9k_hw_ops(ah)->set_bt_ant_diversity(ah, enable);
109} 109}
110 110
111static inline bool ath9k_hw_is_aic_enabled(struct ath_hw *ah)
112{
113 if (ath9k_hw_private_ops(ah)->is_aic_enabled)
114 return ath9k_hw_private_ops(ah)->is_aic_enabled(ah);
115
116 return false;
117}
118
111#endif 119#endif
112 120
113/* Private hardware call ops */ 121/* Private hardware call ops */
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 60aa8d71e753..1d9ad5bfe0c8 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -121,6 +121,36 @@ void ath9k_hw_write_array(struct ath_hw *ah, const struct ar5416IniArray *array,
121 REGWRITE_BUFFER_FLUSH(ah); 121 REGWRITE_BUFFER_FLUSH(ah);
122} 122}
123 123
124void ath9k_hw_read_array(struct ath_hw *ah, u32 array[][2], int size)
125{
126 u32 *tmp_reg_list, *tmp_data;
127 int i;
128
129 tmp_reg_list = kmalloc(size * sizeof(u32), GFP_KERNEL);
130 if (!tmp_reg_list) {
131 dev_err(ah->dev, "%s: tmp_reg_list: alloc filed\n", __func__);
132 return;
133 }
134
135 tmp_data = kmalloc(size * sizeof(u32), GFP_KERNEL);
136 if (!tmp_data) {
137 dev_err(ah->dev, "%s tmp_data: alloc filed\n", __func__);
138 goto error_tmp_data;
139 }
140
141 for (i = 0; i < size; i++)
142 tmp_reg_list[i] = array[i][0];
143
144 REG_READ_MULTI(ah, tmp_reg_list, tmp_data, size);
145
146 for (i = 0; i < size; i++)
147 array[i][1] = tmp_data[i];
148
149 kfree(tmp_data);
150error_tmp_data:
151 kfree(tmp_reg_list);
152}
153
124u32 ath9k_hw_reverse_bits(u32 val, u32 n) 154u32 ath9k_hw_reverse_bits(u32 val, u32 n)
125{ 155{
126 u32 retval; 156 u32 retval;
@@ -366,6 +396,9 @@ static void ath9k_hw_init_config(struct ath_hw *ah)
366 ah->config.rimt_first = 700; 396 ah->config.rimt_first = 700;
367 } 397 }
368 398
399 if (AR_SREV_9462(ah) || AR_SREV_9565(ah))
400 ah->config.pll_pwrsave = 7;
401
369 /* 402 /*
370 * We need this for PCI devices only (Cardbus, PCI, miniPCI) 403 * We need this for PCI devices only (Cardbus, PCI, miniPCI)
371 * _and_ if on non-uniprocessor systems (Multiprocessor/HT). 404 * _and_ if on non-uniprocessor systems (Multiprocessor/HT).
@@ -1197,6 +1230,7 @@ static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode)
1197 u32 mask = AR_STA_ID1_STA_AP | AR_STA_ID1_ADHOC; 1230 u32 mask = AR_STA_ID1_STA_AP | AR_STA_ID1_ADHOC;
1198 u32 set = AR_STA_ID1_KSRCH_MODE; 1231 u32 set = AR_STA_ID1_KSRCH_MODE;
1199 1232
1233 ENABLE_REG_RMW_BUFFER(ah);
1200 switch (opmode) { 1234 switch (opmode) {
1201 case NL80211_IFTYPE_ADHOC: 1235 case NL80211_IFTYPE_ADHOC:
1202 if (!AR_SREV_9340_13(ah)) { 1236 if (!AR_SREV_9340_13(ah)) {
@@ -1218,6 +1252,7 @@ static void ath9k_hw_set_operating_mode(struct ath_hw *ah, int opmode)
1218 break; 1252 break;
1219 } 1253 }
1220 REG_RMW(ah, AR_STA_ID1, set, mask); 1254 REG_RMW(ah, AR_STA_ID1, set, mask);
1255 REG_RMW_BUFFER_FLUSH(ah);
1221} 1256}
1222 1257
1223void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled, 1258void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled,
@@ -1930,6 +1965,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1930 if (!ath9k_hw_mci_is_enabled(ah)) 1965 if (!ath9k_hw_mci_is_enabled(ah))
1931 REG_WRITE(ah, AR_OBS, 8); 1966 REG_WRITE(ah, AR_OBS, 8);
1932 1967
1968 ENABLE_REG_RMW_BUFFER(ah);
1933 if (ah->config.rx_intr_mitigation) { 1969 if (ah->config.rx_intr_mitigation) {
1934 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, ah->config.rimt_last); 1970 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, ah->config.rimt_last);
1935 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, ah->config.rimt_first); 1971 REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, ah->config.rimt_first);
@@ -1939,6 +1975,7 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1939 REG_RMW_FIELD(ah, AR_TIMT, AR_TIMT_LAST, 300); 1975 REG_RMW_FIELD(ah, AR_TIMT, AR_TIMT_LAST, 300);
1940 REG_RMW_FIELD(ah, AR_TIMT, AR_TIMT_FIRST, 750); 1976 REG_RMW_FIELD(ah, AR_TIMT, AR_TIMT_FIRST, 750);
1941 } 1977 }
1978 REG_RMW_BUFFER_FLUSH(ah);
1942 1979
1943 ath9k_hw_init_bb(ah, chan); 1980 ath9k_hw_init_bb(ah, chan);
1944 1981
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 29a25d92add7..92fab1a54697 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -100,6 +100,18 @@
100 (_ah)->reg_ops.write_flush((_ah)); \ 100 (_ah)->reg_ops.write_flush((_ah)); \
101 } while (0) 101 } while (0)
102 102
103#define ENABLE_REG_RMW_BUFFER(_ah) \
104 do { \
105 if ((_ah)->reg_ops.enable_rmw_buffer) \
106 (_ah)->reg_ops.enable_rmw_buffer((_ah)); \
107 } while (0)
108
109#define REG_RMW_BUFFER_FLUSH(_ah) \
110 do { \
111 if ((_ah)->reg_ops.rmw_flush) \
112 (_ah)->reg_ops.rmw_flush((_ah)); \
113 } while (0)
114
103#define PR_EEP(_s, _val) \ 115#define PR_EEP(_s, _val) \
104 do { \ 116 do { \
105 len += scnprintf(buf + len, size - len, "%20s : %10d\n",\ 117 len += scnprintf(buf + len, size - len, "%20s : %10d\n",\
@@ -126,6 +138,8 @@
126 138
127#define REG_WRITE_ARRAY(iniarray, column, regWr) \ 139#define REG_WRITE_ARRAY(iniarray, column, regWr) \
128 ath9k_hw_write_array(ah, iniarray, column, &(regWr)) 140 ath9k_hw_write_array(ah, iniarray, column, &(regWr))
141#define REG_READ_ARRAY(ah, array, size) \
142 ath9k_hw_read_array(ah, array, size)
129 143
130#define AR_GPIO_OUTPUT_MUX_AS_OUTPUT 0 144#define AR_GPIO_OUTPUT_MUX_AS_OUTPUT 0
131#define AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED 1 145#define AR_GPIO_OUTPUT_MUX_AS_PCIE_ATTENTION_LED 1
@@ -309,6 +323,12 @@ enum ath9k_hw_hang_checks {
309 HW_MAC_HANG = BIT(5), 323 HW_MAC_HANG = BIT(5),
310}; 324};
311 325
326#define AR_PCIE_PLL_PWRSAVE_CONTROL BIT(0)
327#define AR_PCIE_PLL_PWRSAVE_ON_D3 BIT(1)
328#define AR_PCIE_PLL_PWRSAVE_ON_D0 BIT(2)
329#define AR_PCIE_CDR_PWRSAVE_ON_D3 BIT(3)
330#define AR_PCIE_CDR_PWRSAVE_ON_D0 BIT(4)
331
312struct ath9k_ops_config { 332struct ath9k_ops_config {
313 int dma_beacon_response_time; 333 int dma_beacon_response_time;
314 int sw_beacon_response_time; 334 int sw_beacon_response_time;
@@ -335,7 +355,7 @@ struct ath9k_ops_config {
335 u32 ant_ctrl_comm2g_switch_enable; 355 u32 ant_ctrl_comm2g_switch_enable;
336 bool xatten_margin_cfg; 356 bool xatten_margin_cfg;
337 bool alt_mingainidx; 357 bool alt_mingainidx;
338 bool no_pll_pwrsave; 358 u8 pll_pwrsave;
339 bool tx_gain_buffalo; 359 bool tx_gain_buffalo;
340 bool led_active_high; 360 bool led_active_high;
341}; 361};
@@ -647,6 +667,10 @@ struct ath_hw_private_ops {
647 667
648 /* ANI */ 668 /* ANI */
649 void (*ani_cache_ini_regs)(struct ath_hw *ah); 669 void (*ani_cache_ini_regs)(struct ath_hw *ah);
670
671#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
672 bool (*is_aic_enabled)(struct ath_hw *ah);
673#endif /* CONFIG_ATH9K_BTCOEX_SUPPORT */
650}; 674};
651 675
652/** 676/**
@@ -1008,6 +1032,7 @@ void ath9k_hw_synth_delay(struct ath_hw *ah, struct ath9k_channel *chan,
1008bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout); 1032bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout);
1009void ath9k_hw_write_array(struct ath_hw *ah, const struct ar5416IniArray *array, 1033void ath9k_hw_write_array(struct ath_hw *ah, const struct ar5416IniArray *array,
1010 int column, unsigned int *writecnt); 1034 int column, unsigned int *writecnt);
1035void ath9k_hw_read_array(struct ath_hw *ah, u32 array[][2], int size);
1011u32 ath9k_hw_reverse_bits(u32 val, u32 n); 1036u32 ath9k_hw_reverse_bits(u32 val, u32 n);
1012u16 ath9k_hw_computetxtime(struct ath_hw *ah, 1037u16 ath9k_hw_computetxtime(struct ath_hw *ah,
1013 u8 phy, int kbps, 1038 u8 phy, int kbps,
@@ -1117,6 +1142,7 @@ void ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us);
1117void ath9k_hw_setslottime(struct ath_hw *ah, u32 us); 1142void ath9k_hw_setslottime(struct ath_hw *ah, u32 us);
1118 1143
1119#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT 1144#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
1145void ar9003_hw_attach_aic_ops(struct ath_hw *ah);
1120static inline bool ath9k_hw_btcoex_is_enabled(struct ath_hw *ah) 1146static inline bool ath9k_hw_btcoex_is_enabled(struct ath_hw *ah)
1121{ 1147{
1122 return ah->btcoex_hw.enabled; 1148 return ah->btcoex_hw.enabled;
@@ -1134,6 +1160,9 @@ ath9k_hw_get_btcoex_scheme(struct ath_hw *ah)
1134 return ah->btcoex_hw.scheme; 1160 return ah->btcoex_hw.scheme;
1135} 1161}
1136#else 1162#else
1163static inline void ar9003_hw_attach_aic_ops(struct ath_hw *ah)
1164{
1165}
1137static inline bool ath9k_hw_btcoex_is_enabled(struct ath_hw *ah) 1166static inline bool ath9k_hw_btcoex_is_enabled(struct ath_hw *ah)
1138{ 1167{
1139 return false; 1168 return false;
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index 6c6e88495394..f8d11efa7b0f 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -141,6 +141,16 @@ static unsigned int ath9k_ioread32(void *hw_priv, u32 reg_offset)
141 return val; 141 return val;
142} 142}
143 143
144static void ath9k_multi_ioread32(void *hw_priv, u32 *addr,
145 u32 *val, u16 count)
146{
147 int i;
148
149 for (i = 0; i < count; i++)
150 val[i] = ath9k_ioread32(hw_priv, addr[i]);
151}
152
153
144static unsigned int __ath9k_reg_rmw(struct ath_softc *sc, u32 reg_offset, 154static unsigned int __ath9k_reg_rmw(struct ath_softc *sc, u32 reg_offset,
145 u32 set, u32 clr) 155 u32 set, u32 clr)
146{ 156{
@@ -437,8 +447,15 @@ static void ath9k_init_pcoem_platform(struct ath_softc *sc)
437 ath_info(common, "Enable WAR for ASPM D3/L1\n"); 447 ath_info(common, "Enable WAR for ASPM D3/L1\n");
438 } 448 }
439 449
450 /*
451 * The default value of pll_pwrsave is 1.
452 * For certain AR9485 cards, it is set to 0.
453 * For AR9462, AR9565 it's set to 7.
454 */
455 ah->config.pll_pwrsave = 1;
456
440 if (sc->driver_data & ATH9K_PCI_NO_PLL_PWRSAVE) { 457 if (sc->driver_data & ATH9K_PCI_NO_PLL_PWRSAVE) {
441 ah->config.no_pll_pwrsave = true; 458 ah->config.pll_pwrsave = 0;
442 ath_info(common, "Disable PLL PowerSave\n"); 459 ath_info(common, "Disable PLL PowerSave\n");
443 } 460 }
444 461
@@ -530,6 +547,7 @@ static int ath9k_init_softc(u16 devid, struct ath_softc *sc,
530 ah->hw = sc->hw; 547 ah->hw = sc->hw;
531 ah->hw_version.devid = devid; 548 ah->hw_version.devid = devid;
532 ah->reg_ops.read = ath9k_ioread32; 549 ah->reg_ops.read = ath9k_ioread32;
550 ah->reg_ops.multi_read = ath9k_multi_ioread32;
533 ah->reg_ops.write = ath9k_iowrite32; 551 ah->reg_ops.write = ath9k_iowrite32;
534 ah->reg_ops.rmw = ath9k_reg_rmw; 552 ah->reg_ops.rmw = ath9k_reg_rmw;
535 pCap = &ah->caps; 553 pCap = &ah->caps;
@@ -763,7 +781,8 @@ static const struct ieee80211_iface_combination if_comb[] = {
763 .num_different_channels = 1, 781 .num_different_channels = 1,
764 .beacon_int_infra_match = true, 782 .beacon_int_infra_match = true,
765 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) | 783 .radar_detect_widths = BIT(NL80211_CHAN_WIDTH_20_NOHT) |
766 BIT(NL80211_CHAN_WIDTH_20), 784 BIT(NL80211_CHAN_WIDTH_20) |
785 BIT(NL80211_CHAN_WIDTH_40),
767 } 786 }
768#endif 787#endif
769}; 788};
diff --git a/drivers/net/wireless/ath/ath9k/reg_aic.h b/drivers/net/wireless/ath/ath9k/reg_aic.h
new file mode 100644
index 000000000000..955147ab48a2
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/reg_aic.h
@@ -0,0 +1,168 @@
1/*
2 * Copyright (c) 2015 Qualcomm Atheros Inc.
3 *
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
16
17#ifndef REG_AIC_H
18#define REG_AIC_H
19
20#define AR_SM_BASE 0xa200
21#define AR_SM1_BASE 0xb200
22#define AR_AGC_BASE 0x9e00
23
24#define AR_PHY_AIC_CTRL_0_B0 (AR_SM_BASE + 0x4b0)
25#define AR_PHY_AIC_CTRL_1_B0 (AR_SM_BASE + 0x4b4)
26#define AR_PHY_AIC_CTRL_2_B0 (AR_SM_BASE + 0x4b8)
27#define AR_PHY_AIC_CTRL_3_B0 (AR_SM_BASE + 0x4bc)
28#define AR_PHY_AIC_CTRL_4_B0 (AR_SM_BASE + 0x4c0)
29
30#define AR_PHY_AIC_STAT_0_B0 (AR_SM_BASE + 0x4c4)
31#define AR_PHY_AIC_STAT_1_B0 (AR_SM_BASE + 0x4c8)
32#define AR_PHY_AIC_STAT_2_B0 (AR_SM_BASE + 0x4cc)
33
34#define AR_PHY_AIC_CTRL_0_B1 (AR_SM1_BASE + 0x4b0)
35#define AR_PHY_AIC_CTRL_1_B1 (AR_SM1_BASE + 0x4b4)
36#define AR_PHY_AIC_CTRL_4_B1 (AR_SM1_BASE + 0x4c0)
37
38#define AR_PHY_AIC_STAT_0_B1 (AR_SM1_BASE + 0x4c4)
39#define AR_PHY_AIC_STAT_1_B1 (AR_SM1_BASE + 0x4c8)
40#define AR_PHY_AIC_STAT_2_B1 (AR_SM1_BASE + 0x4cc)
41
42#define AR_PHY_AIC_SRAM_ADDR_B0 (AR_SM_BASE + 0x5f0)
43#define AR_PHY_AIC_SRAM_DATA_B0 (AR_SM_BASE + 0x5f4)
44
45#define AR_PHY_AIC_SRAM_ADDR_B1 (AR_SM1_BASE + 0x5f0)
46#define AR_PHY_AIC_SRAM_DATA_B1 (AR_SM1_BASE + 0x5f4)
47
48#define AR_PHY_BT_COEX_4 (AR_AGC_BASE + 0x60)
49#define AR_PHY_BT_COEX_5 (AR_AGC_BASE + 0x64)
50
51/* AIC fields */
52#define AR_PHY_AIC_MON_ENABLE 0x80000000
53#define AR_PHY_AIC_MON_ENABLE_S 31
54#define AR_PHY_AIC_CAL_MAX_HOP_COUNT 0x7F000000
55#define AR_PHY_AIC_CAL_MAX_HOP_COUNT_S 24
56#define AR_PHY_AIC_CAL_MIN_VALID_COUNT 0x00FE0000
57#define AR_PHY_AIC_CAL_MIN_VALID_COUNT_S 17
58#define AR_PHY_AIC_F_WLAN 0x0001FC00
59#define AR_PHY_AIC_F_WLAN_S 10
60#define AR_PHY_AIC_CAL_CH_VALID_RESET 0x00000200
61#define AR_PHY_AIC_CAL_CH_VALID_RESET_S 9
62#define AR_PHY_AIC_CAL_ENABLE 0x00000100
63#define AR_PHY_AIC_CAL_ENABLE_S 8
64#define AR_PHY_AIC_BTTX_PWR_THR 0x000000FE
65#define AR_PHY_AIC_BTTX_PWR_THR_S 1
66#define AR_PHY_AIC_ENABLE 0x00000001
67#define AR_PHY_AIC_ENABLE_S 0
68#define AR_PHY_AIC_CAL_BT_REF_DELAY 0x00F00000
69#define AR_PHY_AIC_CAL_BT_REF_DELAY_S 20
70#define AR_PHY_AIC_BT_IDLE_CFG 0x00080000
71#define AR_PHY_AIC_BT_IDLE_CFG_S 19
72#define AR_PHY_AIC_STDBY_COND 0x00060000
73#define AR_PHY_AIC_STDBY_COND_S 17
74#define AR_PHY_AIC_STDBY_ROT_ATT_DB 0x0001F800
75#define AR_PHY_AIC_STDBY_ROT_ATT_DB_S 11
76#define AR_PHY_AIC_STDBY_COM_ATT_DB 0x00000700
77#define AR_PHY_AIC_STDBY_COM_ATT_DB_S 8
78#define AR_PHY_AIC_RSSI_MAX 0x000000F0
79#define AR_PHY_AIC_RSSI_MAX_S 4
80#define AR_PHY_AIC_RSSI_MIN 0x0000000F
81#define AR_PHY_AIC_RSSI_MIN_S 0
82#define AR_PHY_AIC_RADIO_DELAY 0x7F000000
83#define AR_PHY_AIC_RADIO_DELAY_S 24
84#define AR_PHY_AIC_CAL_STEP_SIZE_CORR 0x00F00000
85#define AR_PHY_AIC_CAL_STEP_SIZE_CORR_S 20
86#define AR_PHY_AIC_CAL_ROT_IDX_CORR 0x000F8000
87#define AR_PHY_AIC_CAL_ROT_IDX_CORR_S 15
88#define AR_PHY_AIC_CAL_CONV_CHECK_FACTOR 0x00006000
89#define AR_PHY_AIC_CAL_CONV_CHECK_FACTOR_S 13
90#define AR_PHY_AIC_ROT_IDX_COUNT_MAX 0x00001C00
91#define AR_PHY_AIC_ROT_IDX_COUNT_MAX_S 10
92#define AR_PHY_AIC_CAL_SYNTH_TOGGLE 0x00000200
93#define AR_PHY_AIC_CAL_SYNTH_TOGGLE_S 9
94#define AR_PHY_AIC_CAL_SYNTH_AFTER_BTRX 0x00000100
95#define AR_PHY_AIC_CAL_SYNTH_AFTER_BTRX_S 8
96#define AR_PHY_AIC_CAL_SYNTH_SETTLING 0x000000FF
97#define AR_PHY_AIC_CAL_SYNTH_SETTLING_S 0
98#define AR_PHY_AIC_MON_MAX_HOP_COUNT 0x07F00000
99#define AR_PHY_AIC_MON_MAX_HOP_COUNT_S 20
100#define AR_PHY_AIC_MON_MIN_STALE_COUNT 0x000FE000
101#define AR_PHY_AIC_MON_MIN_STALE_COUNT_S 13
102#define AR_PHY_AIC_MON_PWR_EST_LONG 0x00001000
103#define AR_PHY_AIC_MON_PWR_EST_LONG_S 12
104#define AR_PHY_AIC_MON_PD_TALLY_SCALING 0x00000C00
105#define AR_PHY_AIC_MON_PD_TALLY_SCALING_S 10
106#define AR_PHY_AIC_MON_PERF_THR 0x000003E0
107#define AR_PHY_AIC_MON_PERF_THR_S 5
108#define AR_PHY_AIC_CAL_TARGET_MAG_SETTING 0x00000018
109#define AR_PHY_AIC_CAL_TARGET_MAG_SETTING_S 3
110#define AR_PHY_AIC_CAL_PERF_CHECK_FACTOR 0x00000006
111#define AR_PHY_AIC_CAL_PERF_CHECK_FACTOR_S 1
112#define AR_PHY_AIC_CAL_PWR_EST_LONG 0x00000001
113#define AR_PHY_AIC_CAL_PWR_EST_LONG_S 0
114#define AR_PHY_AIC_MON_DONE 0x80000000
115#define AR_PHY_AIC_MON_DONE_S 31
116#define AR_PHY_AIC_MON_ACTIVE 0x40000000
117#define AR_PHY_AIC_MON_ACTIVE_S 30
118#define AR_PHY_AIC_MEAS_COUNT 0x3F000000
119#define AR_PHY_AIC_MEAS_COUNT_S 24
120#define AR_PHY_AIC_CAL_ANT_ISO_EST 0x00FC0000
121#define AR_PHY_AIC_CAL_ANT_ISO_EST_S 18
122#define AR_PHY_AIC_CAL_HOP_COUNT 0x0003F800
123#define AR_PHY_AIC_CAL_HOP_COUNT_S 11
124#define AR_PHY_AIC_CAL_VALID_COUNT 0x000007F0
125#define AR_PHY_AIC_CAL_VALID_COUNT_S 4
126#define AR_PHY_AIC_CAL_BT_TOO_WEAK_ERR 0x00000008
127#define AR_PHY_AIC_CAL_BT_TOO_WEAK_ERR_S 3
128#define AR_PHY_AIC_CAL_BT_TOO_STRONG_ERR 0x00000004
129#define AR_PHY_AIC_CAL_BT_TOO_STRONG_ERR_S 2
130#define AR_PHY_AIC_CAL_DONE 0x00000002
131#define AR_PHY_AIC_CAL_DONE_S 1
132#define AR_PHY_AIC_CAL_ACTIVE 0x00000001
133#define AR_PHY_AIC_CAL_ACTIVE_S 0
134
135#define AR_PHY_AIC_MEAS_MAG_MIN 0xFFC00000
136#define AR_PHY_AIC_MEAS_MAG_MIN_S 22
137#define AR_PHY_AIC_MON_STALE_COUNT 0x003F8000
138#define AR_PHY_AIC_MON_STALE_COUNT_S 15
139#define AR_PHY_AIC_MON_HOP_COUNT 0x00007F00
140#define AR_PHY_AIC_MON_HOP_COUNT_S 8
141#define AR_PHY_AIC_CAL_AIC_SM 0x000000F8
142#define AR_PHY_AIC_CAL_AIC_SM_S 3
143#define AR_PHY_AIC_SM 0x00000007
144#define AR_PHY_AIC_SM_S 0
145#define AR_PHY_AIC_SRAM_VALID 0x00000001
146#define AR_PHY_AIC_SRAM_VALID_S 0
147#define AR_PHY_AIC_SRAM_ROT_QUAD_ATT_DB 0x0000007E
148#define AR_PHY_AIC_SRAM_ROT_QUAD_ATT_DB_S 1
149#define AR_PHY_AIC_SRAM_VGA_QUAD_SIGN 0x00000080
150#define AR_PHY_AIC_SRAM_VGA_QUAD_SIGN_S 7
151#define AR_PHY_AIC_SRAM_ROT_DIR_ATT_DB 0x00003F00
152#define AR_PHY_AIC_SRAM_ROT_DIR_ATT_DB_S 8
153#define AR_PHY_AIC_SRAM_VGA_DIR_SIGN 0x00004000
154#define AR_PHY_AIC_SRAM_VGA_DIR_SIGN_S 14
155#define AR_PHY_AIC_SRAM_COM_ATT_6DB 0x00038000
156#define AR_PHY_AIC_SRAM_COM_ATT_6DB_S 15
157#define AR_PHY_AIC_CAL_ROT_ATT_DB_EST_ISO 0x0000E000
158#define AR_PHY_AIC_CAL_ROT_ATT_DB_EST_ISO_S 13
159#define AR_PHY_AIC_CAL_COM_ATT_DB_EST_ISO 0x00001E00
160#define AR_PHY_AIC_CAL_COM_ATT_DB_EST_ISO_S 9
161#define AR_PHY_AIC_CAL_ISO_EST_INIT_SETTING 0x000001F8
162#define AR_PHY_AIC_CAL_ISO_EST_INIT_SETTING_S 3
163#define AR_PHY_AIC_CAL_COM_ATT_DB_BACKOFF 0x00000006
164#define AR_PHY_AIC_CAL_COM_ATT_DB_BACKOFF_S 1
165#define AR_PHY_AIC_CAL_COM_ATT_DB_FIXED 0x00000001
166#define AR_PHY_AIC_CAL_COM_ATT_DB_FIXED_S 0
167
168#endif /* REG_AIC_H */
diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c
index 65c8894c5f81..67a2f8c88829 100644
--- a/drivers/net/wireless/ath/ath9k/wmi.c
+++ b/drivers/net/wireless/ath/ath9k/wmi.c
@@ -61,6 +61,8 @@ static const char *wmi_cmd_to_name(enum wmi_cmd_id wmi_cmd)
61 return "WMI_REG_READ_CMDID"; 61 return "WMI_REG_READ_CMDID";
62 case WMI_REG_WRITE_CMDID: 62 case WMI_REG_WRITE_CMDID:
63 return "WMI_REG_WRITE_CMDID"; 63 return "WMI_REG_WRITE_CMDID";
64 case WMI_REG_RMW_CMDID:
65 return "WMI_REG_RMW_CMDID";
64 case WMI_RC_STATE_CHANGE_CMDID: 66 case WMI_RC_STATE_CHANGE_CMDID:
65 return "WMI_RC_STATE_CHANGE_CMDID"; 67 return "WMI_RC_STATE_CHANGE_CMDID";
66 case WMI_RC_RATE_UPDATE_CMDID: 68 case WMI_RC_RATE_UPDATE_CMDID:
@@ -101,6 +103,7 @@ struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv)
101 spin_lock_init(&wmi->event_lock); 103 spin_lock_init(&wmi->event_lock);
102 mutex_init(&wmi->op_mutex); 104 mutex_init(&wmi->op_mutex);
103 mutex_init(&wmi->multi_write_mutex); 105 mutex_init(&wmi->multi_write_mutex);
106 mutex_init(&wmi->multi_rmw_mutex);
104 init_completion(&wmi->cmd_wait); 107 init_completion(&wmi->cmd_wait);
105 INIT_LIST_HEAD(&wmi->pending_tx_events); 108 INIT_LIST_HEAD(&wmi->pending_tx_events);
106 tasklet_init(&wmi->wmi_event_tasklet, ath9k_wmi_event_tasklet, 109 tasklet_init(&wmi->wmi_event_tasklet, ath9k_wmi_event_tasklet,
diff --git a/drivers/net/wireless/ath/ath9k/wmi.h b/drivers/net/wireless/ath/ath9k/wmi.h
index 0db37f230018..aa84a335289a 100644
--- a/drivers/net/wireless/ath/ath9k/wmi.h
+++ b/drivers/net/wireless/ath/ath9k/wmi.h
@@ -112,6 +112,7 @@ enum wmi_cmd_id {
112 WMI_TX_STATS_CMDID, 112 WMI_TX_STATS_CMDID,
113 WMI_RX_STATS_CMDID, 113 WMI_RX_STATS_CMDID,
114 WMI_BITRATE_MASK_CMDID, 114 WMI_BITRATE_MASK_CMDID,
115 WMI_REG_RMW_CMDID,
115}; 116};
116 117
117enum wmi_event_id { 118enum wmi_event_id {
@@ -125,12 +126,19 @@ enum wmi_event_id {
125}; 126};
126 127
127#define MAX_CMD_NUMBER 62 128#define MAX_CMD_NUMBER 62
129#define MAX_RMW_CMD_NUMBER 15
128 130
129struct register_write { 131struct register_write {
130 __be32 reg; 132 __be32 reg;
131 __be32 val; 133 __be32 val;
132}; 134};
133 135
136struct register_rmw {
137 __be32 reg;
138 __be32 set;
139 __be32 clr;
140} __packed;
141
134struct ath9k_htc_tx_event { 142struct ath9k_htc_tx_event {
135 int count; 143 int count;
136 struct __wmi_event_txstatus txs; 144 struct __wmi_event_txstatus txs;
@@ -156,10 +164,18 @@ struct wmi {
156 164
157 spinlock_t wmi_lock; 165 spinlock_t wmi_lock;
158 166
167 /* multi write section */
159 atomic_t mwrite_cnt; 168 atomic_t mwrite_cnt;
160 struct register_write multi_write[MAX_CMD_NUMBER]; 169 struct register_write multi_write[MAX_CMD_NUMBER];
161 u32 multi_write_idx; 170 u32 multi_write_idx;
162 struct mutex multi_write_mutex; 171 struct mutex multi_write_mutex;
172
173 /* multi rmw section */
174 atomic_t m_rmw_cnt;
175 struct register_rmw multi_rmw[MAX_RMW_CMD_NUMBER];
176 u32 multi_rmw_idx;
177 struct mutex multi_rmw_mutex;
178
163}; 179};
164 180
165struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv); 181struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv);
diff --git a/drivers/net/wireless/ath/dfs_pattern_detector.c b/drivers/net/wireless/ath/dfs_pattern_detector.c
index 3d57f8772389..c657ca26a71a 100644
--- a/drivers/net/wireless/ath/dfs_pattern_detector.c
+++ b/drivers/net/wireless/ath/dfs_pattern_detector.c
@@ -289,7 +289,7 @@ dpd_add_pulse(struct dfs_pattern_detector *dpd, struct pulse_event *event)
289 "count=%d, count_false=%d\n", 289 "count=%d, count_false=%d\n",
290 event->freq, pd->rs->type_id, 290 event->freq, pd->rs->type_id,
291 ps->pri, ps->count, ps->count_falses); 291 ps->pri, ps->count, ps->count_falses);
292 channel_detector_reset(dpd, cd); 292 pd->reset(pd, dpd->last_pulse_ts);
293 return true; 293 return true;
294 } 294 }
295 } 295 }
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index 47d14db59b93..b97172667bc7 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -14,6 +14,7 @@
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */ 15 */
16 16
17#include <linux/etherdevice.h>
17#include "wil6210.h" 18#include "wil6210.h"
18#include "wmi.h" 19#include "wmi.h"
19 20
@@ -217,7 +218,7 @@ static int wil_cfg80211_dump_station(struct wiphy *wiphy,
217 if (cid < 0) 218 if (cid < 0)
218 return -ENOENT; 219 return -ENOENT;
219 220
220 memcpy(mac, wil->sta[cid].addr, ETH_ALEN); 221 ether_addr_copy(mac, wil->sta[cid].addr);
221 wil_dbg_misc(wil, "%s(%pM) CID %d\n", __func__, mac, cid); 222 wil_dbg_misc(wil, "%s(%pM) CID %d\n", __func__, mac, cid);
222 223
223 rc = wil_cid_fill_sinfo(wil, cid, sinfo); 224 rc = wil_cid_fill_sinfo(wil, cid, sinfo);
@@ -478,8 +479,8 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
478 } 479 }
479 conn.channel = ch - 1; 480 conn.channel = ch - 1;
480 481
481 memcpy(conn.bssid, bss->bssid, ETH_ALEN); 482 ether_addr_copy(conn.bssid, bss->bssid);
482 memcpy(conn.dst_mac, bss->bssid, ETH_ALEN); 483 ether_addr_copy(conn.dst_mac, bss->bssid);
483 484
484 set_bit(wil_status_fwconnecting, wil->status); 485 set_bit(wil_status_fwconnecting, wil->status);
485 486
@@ -782,8 +783,17 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy,
782 rc = wmi_pcp_start(wil, info->beacon_interval, wmi_nettype, 783 rc = wmi_pcp_start(wil, info->beacon_interval, wmi_nettype,
783 channel->hw_value); 784 channel->hw_value);
784 if (rc) 785 if (rc)
785 netif_carrier_off(ndev); 786 goto err_pcp_start;
786 787
788 rc = wil_bcast_init(wil);
789 if (rc)
790 goto err_bcast;
791
792 goto out; /* success */
793err_bcast:
794 wmi_pcp_stop(wil);
795err_pcp_start:
796 netif_carrier_off(ndev);
787out: 797out:
788 mutex_unlock(&wil->mutex); 798 mutex_unlock(&wil->mutex);
789 return rc; 799 return rc;
@@ -917,6 +927,21 @@ static int wil_cfg80211_probe_client(struct wiphy *wiphy,
917 return 0; 927 return 0;
918} 928}
919 929
930static int wil_cfg80211_change_bss(struct wiphy *wiphy,
931 struct net_device *dev,
932 struct bss_parameters *params)
933{
934 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
935
936 if (params->ap_isolate >= 0) {
937 wil_dbg_misc(wil, "%s(ap_isolate %d => %d)\n", __func__,
938 wil->ap_isolate, params->ap_isolate);
939 wil->ap_isolate = params->ap_isolate;
940 }
941
942 return 0;
943}
944
920static struct cfg80211_ops wil_cfg80211_ops = { 945static struct cfg80211_ops wil_cfg80211_ops = {
921 .scan = wil_cfg80211_scan, 946 .scan = wil_cfg80211_scan,
922 .connect = wil_cfg80211_connect, 947 .connect = wil_cfg80211_connect,
@@ -937,6 +962,7 @@ static struct cfg80211_ops wil_cfg80211_ops = {
937 .stop_ap = wil_cfg80211_stop_ap, 962 .stop_ap = wil_cfg80211_stop_ap,
938 .del_station = wil_cfg80211_del_station, 963 .del_station = wil_cfg80211_del_station,
939 .probe_client = wil_cfg80211_probe_client, 964 .probe_client = wil_cfg80211_probe_client,
965 .change_bss = wil_cfg80211_change_bss,
940}; 966};
941 967
942static void wil_wiphy_init(struct wiphy *wiphy) 968static void wil_wiphy_init(struct wiphy *wiphy)
diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c
index 3830cc20d4fa..bbc22d88f78f 100644
--- a/drivers/net/wireless/ath/wil6210/debugfs.c
+++ b/drivers/net/wireless/ath/wil6210/debugfs.c
@@ -121,12 +121,18 @@ static int wil_vring_debugfs_show(struct seq_file *s, void *data)
121 121
122 snprintf(name, sizeof(name), "tx_%2d", i); 122 snprintf(name, sizeof(name), "tx_%2d", i);
123 123
124 seq_printf(s, 124 if (cid < WIL6210_MAX_CID)
125 "\n%pM CID %d TID %d BACK([%d] %d TU A%s) [%3d|%3d] idle %s\n", 125 seq_printf(s,
126 wil->sta[cid].addr, cid, tid, 126 "\n%pM CID %d TID %d BACK([%u] %u TU A%s) [%3d|%3d] idle %s\n",
127 txdata->agg_wsize, txdata->agg_timeout, 127 wil->sta[cid].addr, cid, tid,
128 txdata->agg_amsdu ? "+" : "-", 128 txdata->agg_wsize,
129 used, avail, sidle); 129 txdata->agg_timeout,
130 txdata->agg_amsdu ? "+" : "-",
131 used, avail, sidle);
132 else
133 seq_printf(s,
134 "\nBroadcast [%3d|%3d] idle %s\n",
135 used, avail, sidle);
130 136
131 wil_print_vring(s, wil, name, vring, '_', 'H'); 137 wil_print_vring(s, wil, name, vring, '_', 'H');
132 } 138 }
@@ -1405,6 +1411,7 @@ static const struct dbg_off dbg_wil_off[] = {
1405 WIL_FIELD(fw_version, S_IRUGO, doff_u32), 1411 WIL_FIELD(fw_version, S_IRUGO, doff_u32),
1406 WIL_FIELD(hw_version, S_IRUGO, doff_x32), 1412 WIL_FIELD(hw_version, S_IRUGO, doff_x32),
1407 WIL_FIELD(recovery_count, S_IRUGO, doff_u32), 1413 WIL_FIELD(recovery_count, S_IRUGO, doff_u32),
1414 WIL_FIELD(ap_isolate, S_IRUGO, doff_u32),
1408 {}, 1415 {},
1409}; 1416};
1410 1417
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index db74e811f5c4..c2a238426425 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -68,6 +68,7 @@ MODULE_PARM_DESC(mtu_max, " Max MTU value.");
68 68
69static uint rx_ring_order = WIL_RX_RING_SIZE_ORDER_DEFAULT; 69static uint rx_ring_order = WIL_RX_RING_SIZE_ORDER_DEFAULT;
70static uint tx_ring_order = WIL_TX_RING_SIZE_ORDER_DEFAULT; 70static uint tx_ring_order = WIL_TX_RING_SIZE_ORDER_DEFAULT;
71static uint bcast_ring_order = WIL_BCAST_RING_SIZE_ORDER_DEFAULT;
71 72
72static int ring_order_set(const char *val, const struct kernel_param *kp) 73static int ring_order_set(const char *val, const struct kernel_param *kp)
73{ 74{
@@ -216,6 +217,7 @@ static void _wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid,
216 switch (wdev->iftype) { 217 switch (wdev->iftype) {
217 case NL80211_IFTYPE_STATION: 218 case NL80211_IFTYPE_STATION:
218 case NL80211_IFTYPE_P2P_CLIENT: 219 case NL80211_IFTYPE_P2P_CLIENT:
220 wil_bcast_fini(wil);
219 netif_tx_stop_all_queues(ndev); 221 netif_tx_stop_all_queues(ndev);
220 netif_carrier_off(ndev); 222 netif_carrier_off(ndev);
221 223
@@ -360,6 +362,35 @@ static int wil_find_free_vring(struct wil6210_priv *wil)
360 return -EINVAL; 362 return -EINVAL;
361} 363}
362 364
365int wil_bcast_init(struct wil6210_priv *wil)
366{
367 int ri = wil->bcast_vring, rc;
368
369 if ((ri >= 0) && wil->vring_tx[ri].va)
370 return 0;
371
372 ri = wil_find_free_vring(wil);
373 if (ri < 0)
374 return ri;
375
376 rc = wil_vring_init_bcast(wil, ri, 1 << bcast_ring_order);
377 if (rc == 0)
378 wil->bcast_vring = ri;
379
380 return rc;
381}
382
383void wil_bcast_fini(struct wil6210_priv *wil)
384{
385 int ri = wil->bcast_vring;
386
387 if (ri < 0)
388 return;
389
390 wil->bcast_vring = -1;
391 wil_vring_fini_tx(wil, ri);
392}
393
363static void wil_connect_worker(struct work_struct *work) 394static void wil_connect_worker(struct work_struct *work)
364{ 395{
365 int rc; 396 int rc;
@@ -407,6 +438,7 @@ int wil_priv_init(struct wil6210_priv *wil)
407 init_completion(&wil->wmi_call); 438 init_completion(&wil->wmi_call);
408 439
409 wil->pending_connect_cid = -1; 440 wil->pending_connect_cid = -1;
441 wil->bcast_vring = -1;
410 setup_timer(&wil->connect_timer, wil_connect_timer_fn, (ulong)wil); 442 setup_timer(&wil->connect_timer, wil_connect_timer_fn, (ulong)wil);
411 setup_timer(&wil->scan_timer, wil_scan_timer_fn, (ulong)wil); 443 setup_timer(&wil->scan_timer, wil_scan_timer_fn, (ulong)wil);
412 444
@@ -656,6 +688,7 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
656 688
657 cancel_work_sync(&wil->disconnect_worker); 689 cancel_work_sync(&wil->disconnect_worker);
658 wil6210_disconnect(wil, NULL, WLAN_REASON_DEAUTH_LEAVING, false); 690 wil6210_disconnect(wil, NULL, WLAN_REASON_DEAUTH_LEAVING, false);
691 wil_bcast_fini(wil);
659 692
660 /* prevent NAPI from being scheduled */ 693 /* prevent NAPI from being scheduled */
661 bitmap_zero(wil->status, wil_status_last); 694 bitmap_zero(wil->status, wil_status_last);
@@ -714,6 +747,7 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
714 747
715 /* init after reset */ 748 /* init after reset */
716 wil->pending_connect_cid = -1; 749 wil->pending_connect_cid = -1;
750 wil->ap_isolate = 0;
717 reinit_completion(&wil->wmi_ready); 751 reinit_completion(&wil->wmi_ready);
718 reinit_completion(&wil->wmi_call); 752 reinit_completion(&wil->wmi_call);
719 753
@@ -723,6 +757,8 @@ int wil_reset(struct wil6210_priv *wil, bool load_fw)
723 757
724 /* we just started MAC, wait for FW ready */ 758 /* we just started MAC, wait for FW ready */
725 rc = wil_wait_for_fw_ready(wil); 759 rc = wil_wait_for_fw_ready(wil);
760 if (rc == 0) /* check FW is responsive */
761 rc = wmi_echo(wil);
726 } 762 }
727 763
728 return rc; 764 return rc;
diff --git a/drivers/net/wireless/ath/wil6210/netdev.c b/drivers/net/wireless/ath/wil6210/netdev.c
index ace30c1b5c64..f2f7ea29558e 100644
--- a/drivers/net/wireless/ath/wil6210/netdev.c
+++ b/drivers/net/wireless/ath/wil6210/netdev.c
@@ -82,7 +82,7 @@ static int wil6210_netdev_poll_rx(struct napi_struct *napi, int budget)
82 wil_rx_handle(wil, &quota); 82 wil_rx_handle(wil, &quota);
83 done = budget - quota; 83 done = budget - quota;
84 84
85 if (done <= 1) { /* burst ends - only one packet processed */ 85 if (done < budget) {
86 napi_complete(napi); 86 napi_complete(napi);
87 wil6210_unmask_irq_rx(wil); 87 wil6210_unmask_irq_rx(wil);
88 wil_dbg_txrx(wil, "NAPI RX complete\n"); 88 wil_dbg_txrx(wil, "NAPI RX complete\n");
@@ -110,7 +110,7 @@ static int wil6210_netdev_poll_tx(struct napi_struct *napi, int budget)
110 tx_done += wil_tx_complete(wil, i); 110 tx_done += wil_tx_complete(wil, i);
111 } 111 }
112 112
113 if (tx_done <= 1) { /* burst ends - only one packet processed */ 113 if (tx_done < budget) {
114 napi_complete(napi); 114 napi_complete(napi);
115 wil6210_unmask_irq_tx(wil); 115 wil6210_unmask_irq_tx(wil);
116 wil_dbg_txrx(wil, "NAPI TX complete\n"); 116 wil_dbg_txrx(wil, "NAPI TX complete\n");
diff --git a/drivers/net/wireless/ath/wil6210/pcie_bus.c b/drivers/net/wireless/ath/wil6210/pcie_bus.c
index 25343cffe229..109986114abf 100644
--- a/drivers/net/wireless/ath/wil6210/pcie_bus.c
+++ b/drivers/net/wireless/ath/wil6210/pcie_bus.c
@@ -246,8 +246,6 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
246 246
247 wil6210_debugfs_init(wil); 247 wil6210_debugfs_init(wil);
248 248
249 /* check FW is alive */
250 wmi_echo(wil);
251 249
252 return 0; 250 return 0;
253 251
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index 7f2f560b8638..e8bd512d81a9 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -33,6 +33,15 @@ module_param(rtap_include_phy_info, bool, S_IRUGO);
33MODULE_PARM_DESC(rtap_include_phy_info, 33MODULE_PARM_DESC(rtap_include_phy_info,
34 " Include PHY info in the radiotap header, default - no"); 34 " Include PHY info in the radiotap header, default - no");
35 35
36bool rx_align_2;
37module_param(rx_align_2, bool, S_IRUGO);
38MODULE_PARM_DESC(rx_align_2, " align Rx buffers on 4*n+2, default - no");
39
40static inline uint wil_rx_snaplen(void)
41{
42 return rx_align_2 ? 6 : 0;
43}
44
36static inline int wil_vring_is_empty(struct vring *vring) 45static inline int wil_vring_is_empty(struct vring *vring)
37{ 46{
38 return vring->swhead == vring->swtail; 47 return vring->swhead == vring->swtail;
@@ -209,7 +218,7 @@ static int wil_vring_alloc_skb(struct wil6210_priv *wil, struct vring *vring,
209 u32 i, int headroom) 218 u32 i, int headroom)
210{ 219{
211 struct device *dev = wil_to_dev(wil); 220 struct device *dev = wil_to_dev(wil);
212 unsigned int sz = mtu_max + ETH_HLEN; 221 unsigned int sz = mtu_max + ETH_HLEN + wil_rx_snaplen();
213 struct vring_rx_desc dd, *d = &dd; 222 struct vring_rx_desc dd, *d = &dd;
214 volatile struct vring_rx_desc *_d = &vring->va[i].rx; 223 volatile struct vring_rx_desc *_d = &vring->va[i].rx;
215 dma_addr_t pa; 224 dma_addr_t pa;
@@ -365,10 +374,12 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
365 struct vring_rx_desc *d; 374 struct vring_rx_desc *d;
366 struct sk_buff *skb; 375 struct sk_buff *skb;
367 dma_addr_t pa; 376 dma_addr_t pa;
368 unsigned int sz = mtu_max + ETH_HLEN; 377 unsigned int snaplen = wil_rx_snaplen();
378 unsigned int sz = mtu_max + ETH_HLEN + snaplen;
369 u16 dmalen; 379 u16 dmalen;
370 u8 ftype; 380 u8 ftype;
371 int cid; 381 int cid;
382 int i = (int)vring->swhead;
372 struct wil_net_stats *stats; 383 struct wil_net_stats *stats;
373 384
374 BUILD_BUG_ON(sizeof(struct vring_rx_desc) > sizeof(skb->cb)); 385 BUILD_BUG_ON(sizeof(struct vring_rx_desc) > sizeof(skb->cb));
@@ -376,24 +387,28 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
376 if (unlikely(wil_vring_is_empty(vring))) 387 if (unlikely(wil_vring_is_empty(vring)))
377 return NULL; 388 return NULL;
378 389
379 _d = &vring->va[vring->swhead].rx; 390 _d = &vring->va[i].rx;
380 if (unlikely(!(_d->dma.status & RX_DMA_STATUS_DU))) { 391 if (unlikely(!(_d->dma.status & RX_DMA_STATUS_DU))) {
381 /* it is not error, we just reached end of Rx done area */ 392 /* it is not error, we just reached end of Rx done area */
382 return NULL; 393 return NULL;
383 } 394 }
384 395
385 skb = vring->ctx[vring->swhead].skb; 396 skb = vring->ctx[i].skb;
397 vring->ctx[i].skb = NULL;
398 wil_vring_advance_head(vring, 1);
399 if (!skb) {
400 wil_err(wil, "No Rx skb at [%d]\n", i);
401 return NULL;
402 }
386 d = wil_skb_rxdesc(skb); 403 d = wil_skb_rxdesc(skb);
387 *d = *_d; 404 *d = *_d;
388 pa = wil_desc_addr(&d->dma.addr); 405 pa = wil_desc_addr(&d->dma.addr);
389 vring->ctx[vring->swhead].skb = NULL;
390 wil_vring_advance_head(vring, 1);
391 406
392 dma_unmap_single(dev, pa, sz, DMA_FROM_DEVICE); 407 dma_unmap_single(dev, pa, sz, DMA_FROM_DEVICE);
393 dmalen = le16_to_cpu(d->dma.length); 408 dmalen = le16_to_cpu(d->dma.length);
394 409
395 trace_wil6210_rx(vring->swhead, d); 410 trace_wil6210_rx(i, d);
396 wil_dbg_txrx(wil, "Rx[%3d] : %d bytes\n", vring->swhead, dmalen); 411 wil_dbg_txrx(wil, "Rx[%3d] : %d bytes\n", i, dmalen);
397 wil_hex_dump_txrx("Rx ", DUMP_PREFIX_NONE, 32, 4, 412 wil_hex_dump_txrx("Rx ", DUMP_PREFIX_NONE, 32, 4,
398 (const void *)d, sizeof(*d), false); 413 (const void *)d, sizeof(*d), false);
399 414
@@ -433,7 +448,7 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
433 return NULL; 448 return NULL;
434 } 449 }
435 450
436 if (unlikely(skb->len < ETH_HLEN)) { 451 if (unlikely(skb->len < ETH_HLEN + snaplen)) {
437 wil_err(wil, "Short frame, len = %d\n", skb->len); 452 wil_err(wil, "Short frame, len = %d\n", skb->len);
438 /* TODO: process it (i.e. BAR) */ 453 /* TODO: process it (i.e. BAR) */
439 kfree_skb(skb); 454 kfree_skb(skb);
@@ -455,6 +470,17 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
455 */ 470 */
456 } 471 }
457 472
473 if (snaplen) {
474 /* Packet layout
475 * +-------+-------+---------+------------+------+
476 * | SA(6) | DA(6) | SNAP(6) | ETHTYPE(2) | DATA |
477 * +-------+-------+---------+------------+------+
478 * Need to remove SNAP, shifting SA and DA forward
479 */
480 memmove(skb->data + snaplen, skb->data, 2 * ETH_ALEN);
481 skb_pull(skb, snaplen);
482 }
483
458 return skb; 484 return skb;
459} 485}
460 486
@@ -492,17 +518,71 @@ static int wil_rx_refill(struct wil6210_priv *wil, int count)
492 */ 518 */
493void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev) 519void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev)
494{ 520{
495 gro_result_t rc; 521 gro_result_t rc = GRO_NORMAL;
496 struct wil6210_priv *wil = ndev_to_wil(ndev); 522 struct wil6210_priv *wil = ndev_to_wil(ndev);
523 struct wireless_dev *wdev = wil_to_wdev(wil);
497 unsigned int len = skb->len; 524 unsigned int len = skb->len;
498 struct vring_rx_desc *d = wil_skb_rxdesc(skb); 525 struct vring_rx_desc *d = wil_skb_rxdesc(skb);
499 int cid = wil_rxdesc_cid(d); 526 int cid = wil_rxdesc_cid(d); /* always 0..7, no need to check */
527 struct ethhdr *eth = (void *)skb->data;
528 /* here looking for DA, not A1, thus Rxdesc's 'mcast' indication
529 * is not suitable, need to look at data
530 */
531 int mcast = is_multicast_ether_addr(eth->h_dest);
500 struct wil_net_stats *stats = &wil->sta[cid].stats; 532 struct wil_net_stats *stats = &wil->sta[cid].stats;
533 struct sk_buff *xmit_skb = NULL;
534 static const char * const gro_res_str[] = {
535 [GRO_MERGED] = "GRO_MERGED",
536 [GRO_MERGED_FREE] = "GRO_MERGED_FREE",
537 [GRO_HELD] = "GRO_HELD",
538 [GRO_NORMAL] = "GRO_NORMAL",
539 [GRO_DROP] = "GRO_DROP",
540 };
501 541
502 skb_orphan(skb); 542 skb_orphan(skb);
503 543
504 rc = napi_gro_receive(&wil->napi_rx, skb); 544 if (wdev->iftype == NL80211_IFTYPE_AP && !wil->ap_isolate) {
545 if (mcast) {
546 /* send multicast frames both to higher layers in
547 * local net stack and back to the wireless medium
548 */
549 xmit_skb = skb_copy(skb, GFP_ATOMIC);
550 } else {
551 int xmit_cid = wil_find_cid(wil, eth->h_dest);
552
553 if (xmit_cid >= 0) {
554 /* The destination station is associated to
555 * this AP (in this VLAN), so send the frame
556 * directly to it and do not pass it to local
557 * net stack.
558 */
559 xmit_skb = skb;
560 skb = NULL;
561 }
562 }
563 }
564 if (xmit_skb) {
565 /* Send to wireless media and increase priority by 256 to
566 * keep the received priority instead of reclassifying
567 * the frame (see cfg80211_classify8021d).
568 */
569 xmit_skb->dev = ndev;
570 xmit_skb->priority += 256;
571 xmit_skb->protocol = htons(ETH_P_802_3);
572 skb_reset_network_header(xmit_skb);
573 skb_reset_mac_header(xmit_skb);
574 wil_dbg_txrx(wil, "Rx -> Tx %d bytes\n", len);
575 dev_queue_xmit(xmit_skb);
576 }
505 577
578 if (skb) { /* deliver to local stack */
579
580 skb->protocol = eth_type_trans(skb, ndev);
581 rc = napi_gro_receive(&wil->napi_rx, skb);
582 wil_dbg_txrx(wil, "Rx complete %d bytes => %s\n",
583 len, gro_res_str[rc]);
584 }
585 /* statistics. rc set to GRO_NORMAL for AP bridging */
506 if (unlikely(rc == GRO_DROP)) { 586 if (unlikely(rc == GRO_DROP)) {
507 ndev->stats.rx_dropped++; 587 ndev->stats.rx_dropped++;
508 stats->rx_dropped++; 588 stats->rx_dropped++;
@@ -512,17 +592,8 @@ void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev)
512 stats->rx_packets++; 592 stats->rx_packets++;
513 ndev->stats.rx_bytes += len; 593 ndev->stats.rx_bytes += len;
514 stats->rx_bytes += len; 594 stats->rx_bytes += len;
515 } 595 if (mcast)
516 { 596 ndev->stats.multicast++;
517 static const char * const gro_res_str[] = {
518 [GRO_MERGED] = "GRO_MERGED",
519 [GRO_MERGED_FREE] = "GRO_MERGED_FREE",
520 [GRO_HELD] = "GRO_HELD",
521 [GRO_NORMAL] = "GRO_NORMAL",
522 [GRO_DROP] = "GRO_DROP",
523 };
524 wil_dbg_txrx(wil, "Rx complete %d bytes => %s\n",
525 len, gro_res_str[rc]);
526 } 597 }
527} 598}
528 599
@@ -553,7 +624,6 @@ void wil_rx_handle(struct wil6210_priv *wil, int *quota)
553 skb->protocol = htons(ETH_P_802_2); 624 skb->protocol = htons(ETH_P_802_2);
554 wil_netif_rx_any(skb, ndev); 625 wil_netif_rx_any(skb, ndev);
555 } else { 626 } else {
556 skb->protocol = eth_type_trans(skb, ndev);
557 wil_rx_reorder(wil, skb); 627 wil_rx_reorder(wil, skb);
558 } 628 }
559 } 629 }
@@ -679,6 +749,72 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size,
679 return rc; 749 return rc;
680} 750}
681 751
752int wil_vring_init_bcast(struct wil6210_priv *wil, int id, int size)
753{
754 int rc;
755 struct wmi_bcast_vring_cfg_cmd cmd = {
756 .action = cpu_to_le32(WMI_VRING_CMD_ADD),
757 .vring_cfg = {
758 .tx_sw_ring = {
759 .max_mpdu_size =
760 cpu_to_le16(wil_mtu2macbuf(mtu_max)),
761 .ring_size = cpu_to_le16(size),
762 },
763 .ringid = id,
764 .encap_trans_type = WMI_VRING_ENC_TYPE_802_3,
765 },
766 };
767 struct {
768 struct wil6210_mbox_hdr_wmi wmi;
769 struct wmi_vring_cfg_done_event cmd;
770 } __packed reply;
771 struct vring *vring = &wil->vring_tx[id];
772 struct vring_tx_data *txdata = &wil->vring_tx_data[id];
773
774 wil_dbg_misc(wil, "%s() max_mpdu_size %d\n", __func__,
775 cmd.vring_cfg.tx_sw_ring.max_mpdu_size);
776
777 if (vring->va) {
778 wil_err(wil, "Tx ring [%d] already allocated\n", id);
779 rc = -EINVAL;
780 goto out;
781 }
782
783 memset(txdata, 0, sizeof(*txdata));
784 spin_lock_init(&txdata->lock);
785 vring->size = size;
786 rc = wil_vring_alloc(wil, vring);
787 if (rc)
788 goto out;
789
790 wil->vring2cid_tid[id][0] = WIL6210_MAX_CID; /* CID */
791 wil->vring2cid_tid[id][1] = 0; /* TID */
792
793 cmd.vring_cfg.tx_sw_ring.ring_mem_base = cpu_to_le64(vring->pa);
794
795 rc = wmi_call(wil, WMI_BCAST_VRING_CFG_CMDID, &cmd, sizeof(cmd),
796 WMI_VRING_CFG_DONE_EVENTID, &reply, sizeof(reply), 100);
797 if (rc)
798 goto out_free;
799
800 if (reply.cmd.status != WMI_FW_STATUS_SUCCESS) {
801 wil_err(wil, "Tx config failed, status 0x%02x\n",
802 reply.cmd.status);
803 rc = -EINVAL;
804 goto out_free;
805 }
806 vring->hwtail = le32_to_cpu(reply.cmd.tx_vring_tail_ptr);
807
808 txdata->enabled = 1;
809
810 return 0;
811 out_free:
812 wil_vring_free(wil, vring, 1);
813 out:
814
815 return rc;
816}
817
682void wil_vring_fini_tx(struct wil6210_priv *wil, int id) 818void wil_vring_fini_tx(struct wil6210_priv *wil, int id)
683{ 819{
684 struct vring *vring = &wil->vring_tx[id]; 820 struct vring *vring = &wil->vring_tx[id];
@@ -702,7 +838,7 @@ void wil_vring_fini_tx(struct wil6210_priv *wil, int id)
702 memset(txdata, 0, sizeof(*txdata)); 838 memset(txdata, 0, sizeof(*txdata));
703} 839}
704 840
705static struct vring *wil_find_tx_vring(struct wil6210_priv *wil, 841static struct vring *wil_find_tx_ucast(struct wil6210_priv *wil,
706 struct sk_buff *skb) 842 struct sk_buff *skb)
707{ 843{
708 int i; 844 int i;
@@ -735,15 +871,6 @@ static struct vring *wil_find_tx_vring(struct wil6210_priv *wil,
735 return NULL; 871 return NULL;
736} 872}
737 873
738static void wil_set_da_for_vring(struct wil6210_priv *wil,
739 struct sk_buff *skb, int vring_index)
740{
741 struct ethhdr *eth = (void *)skb->data;
742 int cid = wil->vring2cid_tid[vring_index][0];
743
744 memcpy(eth->h_dest, wil->sta[cid].addr, ETH_ALEN);
745}
746
747static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring, 874static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
748 struct sk_buff *skb); 875 struct sk_buff *skb);
749 876
@@ -764,6 +891,9 @@ static struct vring *wil_find_tx_vring_sta(struct wil6210_priv *wil,
764 continue; 891 continue;
765 892
766 cid = wil->vring2cid_tid[i][0]; 893 cid = wil->vring2cid_tid[i][0];
894 if (cid >= WIL6210_MAX_CID) /* skip BCAST */
895 continue;
896
767 if (!wil->sta[cid].data_port_open && 897 if (!wil->sta[cid].data_port_open &&
768 (skb->protocol != cpu_to_be16(ETH_P_PAE))) 898 (skb->protocol != cpu_to_be16(ETH_P_PAE)))
769 break; 899 break;
@@ -778,17 +908,51 @@ static struct vring *wil_find_tx_vring_sta(struct wil6210_priv *wil,
778 return NULL; 908 return NULL;
779} 909}
780 910
781/* 911/* Use one of 2 strategies:
782 * Find 1-st vring and return it; set dest address for this vring in skb 912 *
783 * duplicate skb and send it to other active vrings 913 * 1. New (real broadcast):
914 * use dedicated broadcast vring
915 * 2. Old (pseudo-DMS):
916 * Find 1-st vring and return it;
917 * duplicate skb and send it to other active vrings;
918 * in all cases override dest address to unicast peer's address
919 * Use old strategy when new is not supported yet:
920 * - for PBSS
921 * - for secure link
784 */ 922 */
785static struct vring *wil_tx_bcast(struct wil6210_priv *wil, 923static struct vring *wil_find_tx_bcast_1(struct wil6210_priv *wil,
786 struct sk_buff *skb) 924 struct sk_buff *skb)
925{
926 struct vring *v;
927 int i = wil->bcast_vring;
928
929 if (i < 0)
930 return NULL;
931 v = &wil->vring_tx[i];
932 if (!v->va)
933 return NULL;
934
935 return v;
936}
937
938static void wil_set_da_for_vring(struct wil6210_priv *wil,
939 struct sk_buff *skb, int vring_index)
940{
941 struct ethhdr *eth = (void *)skb->data;
942 int cid = wil->vring2cid_tid[vring_index][0];
943
944 ether_addr_copy(eth->h_dest, wil->sta[cid].addr);
945}
946
947static struct vring *wil_find_tx_bcast_2(struct wil6210_priv *wil,
948 struct sk_buff *skb)
787{ 949{
788 struct vring *v, *v2; 950 struct vring *v, *v2;
789 struct sk_buff *skb2; 951 struct sk_buff *skb2;
790 int i; 952 int i;
791 u8 cid; 953 u8 cid;
954 struct ethhdr *eth = (void *)skb->data;
955 char *src = eth->h_source;
792 956
793 /* find 1-st vring eligible for data */ 957 /* find 1-st vring eligible for data */
794 for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) { 958 for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) {
@@ -797,9 +961,15 @@ static struct vring *wil_tx_bcast(struct wil6210_priv *wil,
797 continue; 961 continue;
798 962
799 cid = wil->vring2cid_tid[i][0]; 963 cid = wil->vring2cid_tid[i][0];
964 if (cid >= WIL6210_MAX_CID) /* skip BCAST */
965 continue;
800 if (!wil->sta[cid].data_port_open) 966 if (!wil->sta[cid].data_port_open)
801 continue; 967 continue;
802 968
969 /* don't Tx back to source when re-routing Rx->Tx at the AP */
970 if (0 == memcmp(wil->sta[cid].addr, src, ETH_ALEN))
971 continue;
972
803 goto found; 973 goto found;
804 } 974 }
805 975
@@ -817,9 +987,14 @@ found:
817 if (!v2->va) 987 if (!v2->va)
818 continue; 988 continue;
819 cid = wil->vring2cid_tid[i][0]; 989 cid = wil->vring2cid_tid[i][0];
990 if (cid >= WIL6210_MAX_CID) /* skip BCAST */
991 continue;
820 if (!wil->sta[cid].data_port_open) 992 if (!wil->sta[cid].data_port_open)
821 continue; 993 continue;
822 994
995 if (0 == memcmp(wil->sta[cid].addr, src, ETH_ALEN))
996 continue;
997
823 skb2 = skb_copy(skb, GFP_ATOMIC); 998 skb2 = skb_copy(skb, GFP_ATOMIC);
824 if (skb2) { 999 if (skb2) {
825 wil_dbg_txrx(wil, "BCAST DUP -> ring %d\n", i); 1000 wil_dbg_txrx(wil, "BCAST DUP -> ring %d\n", i);
@@ -833,6 +1008,20 @@ found:
833 return v; 1008 return v;
834} 1009}
835 1010
1011static struct vring *wil_find_tx_bcast(struct wil6210_priv *wil,
1012 struct sk_buff *skb)
1013{
1014 struct wireless_dev *wdev = wil->wdev;
1015
1016 if (wdev->iftype != NL80211_IFTYPE_AP)
1017 return wil_find_tx_bcast_2(wil, skb);
1018
1019 if (wil->privacy)
1020 return wil_find_tx_bcast_2(wil, skb);
1021
1022 return wil_find_tx_bcast_1(wil, skb);
1023}
1024
836static int wil_tx_desc_map(struct vring_tx_desc *d, dma_addr_t pa, u32 len, 1025static int wil_tx_desc_map(struct vring_tx_desc *d, dma_addr_t pa, u32 len,
837 int vring_index) 1026 int vring_index)
838{ 1027{
@@ -925,6 +1114,8 @@ static int __wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
925 uint i = swhead; 1114 uint i = swhead;
926 dma_addr_t pa; 1115 dma_addr_t pa;
927 int used; 1116 int used;
1117 bool mcast = (vring_index == wil->bcast_vring);
1118 uint len = skb_headlen(skb);
928 1119
929 wil_dbg_txrx(wil, "%s()\n", __func__); 1120 wil_dbg_txrx(wil, "%s()\n", __func__);
930 1121
@@ -950,7 +1141,17 @@ static int __wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
950 return -EINVAL; 1141 return -EINVAL;
951 vring->ctx[i].mapped_as = wil_mapped_as_single; 1142 vring->ctx[i].mapped_as = wil_mapped_as_single;
952 /* 1-st segment */ 1143 /* 1-st segment */
953 wil_tx_desc_map(d, pa, skb_headlen(skb), vring_index); 1144 wil_tx_desc_map(d, pa, len, vring_index);
1145 if (unlikely(mcast)) {
1146 d->mac.d[0] |= BIT(MAC_CFG_DESC_TX_0_MCS_EN_POS); /* MCS 0 */
1147 if (unlikely(len > WIL_BCAST_MCS0_LIMIT)) {
1148 /* set MCS 1 */
1149 d->mac.d[0] |= (1 << MAC_CFG_DESC_TX_0_MCS_INDEX_POS);
1150 /* packet mode 2 */
1151 d->mac.d[1] |= BIT(MAC_CFG_DESC_TX_1_PKT_MODE_EN_POS) |
1152 (2 << MAC_CFG_DESC_TX_1_PKT_MODE_POS);
1153 }
1154 }
954 /* Process TCP/UDP checksum offloading */ 1155 /* Process TCP/UDP checksum offloading */
955 if (unlikely(wil_tx_desc_offload_cksum_set(wil, d, skb))) { 1156 if (unlikely(wil_tx_desc_offload_cksum_set(wil, d, skb))) {
956 wil_err(wil, "Tx[%2d] Failed to set cksum, drop packet\n", 1157 wil_err(wil, "Tx[%2d] Failed to set cksum, drop packet\n",
@@ -1056,6 +1257,7 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
1056{ 1257{
1057 struct wil6210_priv *wil = ndev_to_wil(ndev); 1258 struct wil6210_priv *wil = ndev_to_wil(ndev);
1058 struct ethhdr *eth = (void *)skb->data; 1259 struct ethhdr *eth = (void *)skb->data;
1260 bool bcast = is_multicast_ether_addr(eth->h_dest);
1059 struct vring *vring; 1261 struct vring *vring;
1060 static bool pr_once_fw; 1262 static bool pr_once_fw;
1061 int rc; 1263 int rc;
@@ -1083,10 +1285,8 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
1083 /* in STA mode (ESS), all to same VRING */ 1285 /* in STA mode (ESS), all to same VRING */
1084 vring = wil_find_tx_vring_sta(wil, skb); 1286 vring = wil_find_tx_vring_sta(wil, skb);
1085 } else { /* direct communication, find matching VRING */ 1287 } else { /* direct communication, find matching VRING */
1086 if (is_unicast_ether_addr(eth->h_dest)) 1288 vring = bcast ? wil_find_tx_bcast(wil, skb) :
1087 vring = wil_find_tx_vring(wil, skb); 1289 wil_find_tx_ucast(wil, skb);
1088 else
1089 vring = wil_tx_bcast(wil, skb);
1090 } 1290 }
1091 if (unlikely(!vring)) { 1291 if (unlikely(!vring)) {
1092 wil_dbg_txrx(wil, "No Tx VRING found for %pM\n", eth->h_dest); 1292 wil_dbg_txrx(wil, "No Tx VRING found for %pM\n", eth->h_dest);
@@ -1149,7 +1349,7 @@ int wil_tx_complete(struct wil6210_priv *wil, int ringid)
1149 struct vring_tx_data *txdata = &wil->vring_tx_data[ringid]; 1349 struct vring_tx_data *txdata = &wil->vring_tx_data[ringid];
1150 int done = 0; 1350 int done = 0;
1151 int cid = wil->vring2cid_tid[ringid][0]; 1351 int cid = wil->vring2cid_tid[ringid][0];
1152 struct wil_net_stats *stats = &wil->sta[cid].stats; 1352 struct wil_net_stats *stats = NULL;
1153 volatile struct vring_tx_desc *_d; 1353 volatile struct vring_tx_desc *_d;
1154 int used_before_complete; 1354 int used_before_complete;
1155 int used_new; 1355 int used_new;
@@ -1168,6 +1368,9 @@ int wil_tx_complete(struct wil6210_priv *wil, int ringid)
1168 1368
1169 used_before_complete = wil_vring_used_tx(vring); 1369 used_before_complete = wil_vring_used_tx(vring);
1170 1370
1371 if (cid < WIL6210_MAX_CID)
1372 stats = &wil->sta[cid].stats;
1373
1171 while (!wil_vring_is_empty(vring)) { 1374 while (!wil_vring_is_empty(vring)) {
1172 int new_swtail; 1375 int new_swtail;
1173 struct wil_ctx *ctx = &vring->ctx[vring->swtail]; 1376 struct wil_ctx *ctx = &vring->ctx[vring->swtail];
@@ -1209,12 +1412,15 @@ int wil_tx_complete(struct wil6210_priv *wil, int ringid)
1209 if (skb) { 1412 if (skb) {
1210 if (likely(d->dma.error == 0)) { 1413 if (likely(d->dma.error == 0)) {
1211 ndev->stats.tx_packets++; 1414 ndev->stats.tx_packets++;
1212 stats->tx_packets++;
1213 ndev->stats.tx_bytes += skb->len; 1415 ndev->stats.tx_bytes += skb->len;
1214 stats->tx_bytes += skb->len; 1416 if (stats) {
1417 stats->tx_packets++;
1418 stats->tx_bytes += skb->len;
1419 }
1215 } else { 1420 } else {
1216 ndev->stats.tx_errors++; 1421 ndev->stats.tx_errors++;
1217 stats->tx_errors++; 1422 if (stats)
1423 stats->tx_errors++;
1218 } 1424 }
1219 wil_consume_skb(skb, d->dma.error == 0); 1425 wil_consume_skb(skb, d->dma.error == 0);
1220 } 1426 }
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index b6e65c37d410..4310972c9e16 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -28,6 +28,7 @@ extern unsigned int mtu_max;
28extern unsigned short rx_ring_overflow_thrsh; 28extern unsigned short rx_ring_overflow_thrsh;
29extern int agg_wsize; 29extern int agg_wsize;
30extern u32 vring_idle_trsh; 30extern u32 vring_idle_trsh;
31extern bool rx_align_2;
31 32
32#define WIL_NAME "wil6210" 33#define WIL_NAME "wil6210"
33#define WIL_FW_NAME "wil6210.fw" /* code */ 34#define WIL_FW_NAME "wil6210.fw" /* code */
@@ -49,6 +50,8 @@ static inline u32 WIL_GET_BITS(u32 x, int b0, int b1)
49#define WIL_TX_Q_LEN_DEFAULT (4000) 50#define WIL_TX_Q_LEN_DEFAULT (4000)
50#define WIL_RX_RING_SIZE_ORDER_DEFAULT (10) 51#define WIL_RX_RING_SIZE_ORDER_DEFAULT (10)
51#define WIL_TX_RING_SIZE_ORDER_DEFAULT (10) 52#define WIL_TX_RING_SIZE_ORDER_DEFAULT (10)
53#define WIL_BCAST_RING_SIZE_ORDER_DEFAULT (7)
54#define WIL_BCAST_MCS0_LIMIT (1024) /* limit for MCS0 frame size */
52/* limit ring size in range [32..32k] */ 55/* limit ring size in range [32..32k] */
53#define WIL_RING_SIZE_ORDER_MIN (5) 56#define WIL_RING_SIZE_ORDER_MIN (5)
54#define WIL_RING_SIZE_ORDER_MAX (15) 57#define WIL_RING_SIZE_ORDER_MAX (15)
@@ -542,6 +545,7 @@ struct wil6210_priv {
542 u32 monitor_flags; 545 u32 monitor_flags;
543 u32 privacy; /* secure connection? */ 546 u32 privacy; /* secure connection? */
544 int sinfo_gen; 547 int sinfo_gen;
548 u32 ap_isolate; /* no intra-BSS communication */
545 /* interrupt moderation */ 549 /* interrupt moderation */
546 u32 tx_max_burst_duration; 550 u32 tx_max_burst_duration;
547 u32 tx_interframe_timeout; 551 u32 tx_interframe_timeout;
@@ -593,6 +597,7 @@ struct wil6210_priv {
593 struct vring_tx_data vring_tx_data[WIL6210_MAX_TX_RINGS]; 597 struct vring_tx_data vring_tx_data[WIL6210_MAX_TX_RINGS];
594 u8 vring2cid_tid[WIL6210_MAX_TX_RINGS][2]; /* [0] - CID, [1] - TID */ 598 u8 vring2cid_tid[WIL6210_MAX_TX_RINGS][2]; /* [0] - CID, [1] - TID */
595 struct wil_sta_info sta[WIL6210_MAX_CID]; 599 struct wil_sta_info sta[WIL6210_MAX_CID];
600 int bcast_vring;
596 /* scan */ 601 /* scan */
597 struct cfg80211_scan_request *scan_request; 602 struct cfg80211_scan_request *scan_request;
598 603
@@ -755,6 +760,9 @@ void wil_rx_fini(struct wil6210_priv *wil);
755int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size, 760int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size,
756 int cid, int tid); 761 int cid, int tid);
757void wil_vring_fini_tx(struct wil6210_priv *wil, int id); 762void wil_vring_fini_tx(struct wil6210_priv *wil, int id);
763int wil_vring_init_bcast(struct wil6210_priv *wil, int id, int size);
764int wil_bcast_init(struct wil6210_priv *wil);
765void wil_bcast_fini(struct wil6210_priv *wil);
758 766
759netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev); 767netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev);
760int wil_tx_complete(struct wil6210_priv *wil, int ringid); 768int wil_tx_complete(struct wil6210_priv *wil, int ringid);
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index 021313524913..9fe2085be2c5 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -466,7 +466,7 @@ static void wmi_evt_connect(struct wil6210_priv *wil, int id, void *d, int len)
466 466
467 /* FIXME FW can transmit only ucast frames to peer */ 467 /* FIXME FW can transmit only ucast frames to peer */
468 /* FIXME real ring_id instead of hard coded 0 */ 468 /* FIXME real ring_id instead of hard coded 0 */
469 memcpy(wil->sta[evt->cid].addr, evt->bssid, ETH_ALEN); 469 ether_addr_copy(wil->sta[evt->cid].addr, evt->bssid);
470 wil->sta[evt->cid].status = wil_sta_conn_pending; 470 wil->sta[evt->cid].status = wil_sta_conn_pending;
471 471
472 wil->pending_connect_cid = evt->cid; 472 wil->pending_connect_cid = evt->cid;
@@ -524,8 +524,8 @@ static void wmi_evt_eapol_rx(struct wil6210_priv *wil, int id,
524 } 524 }
525 525
526 eth = (struct ethhdr *)skb_put(skb, ETH_HLEN); 526 eth = (struct ethhdr *)skb_put(skb, ETH_HLEN);
527 memcpy(eth->h_dest, ndev->dev_addr, ETH_ALEN); 527 ether_addr_copy(eth->h_dest, ndev->dev_addr);
528 memcpy(eth->h_source, evt->src_mac, ETH_ALEN); 528 ether_addr_copy(eth->h_source, evt->src_mac);
529 eth->h_proto = cpu_to_be16(ETH_P_PAE); 529 eth->h_proto = cpu_to_be16(ETH_P_PAE);
530 memcpy(skb_put(skb, eapol_len), evt->eapol, eapol_len); 530 memcpy(skb_put(skb, eapol_len), evt->eapol, eapol_len);
531 skb->protocol = eth_type_trans(skb, ndev); 531 skb->protocol = eth_type_trans(skb, ndev);
@@ -851,7 +851,7 @@ int wmi_set_mac_address(struct wil6210_priv *wil, void *addr)
851{ 851{
852 struct wmi_set_mac_address_cmd cmd; 852 struct wmi_set_mac_address_cmd cmd;
853 853
854 memcpy(cmd.mac, addr, ETH_ALEN); 854 ether_addr_copy(cmd.mac, addr);
855 855
856 wil_dbg_wmi(wil, "Set MAC %pM\n", addr); 856 wil_dbg_wmi(wil, "Set MAC %pM\n", addr);
857 857
@@ -1109,6 +1109,11 @@ int wmi_rx_chain_add(struct wil6210_priv *wil, struct vring *vring)
1109 */ 1109 */
1110 cmd.l3_l4_ctrl |= (1 << L3_L4_CTRL_TCPIP_CHECKSUM_EN_POS); 1110 cmd.l3_l4_ctrl |= (1 << L3_L4_CTRL_TCPIP_CHECKSUM_EN_POS);
1111 } 1111 }
1112
1113 if (rx_align_2)
1114 cmd.l2_802_3_offload_ctrl |=
1115 L2_802_3_OFFLOAD_CTRL_SNAP_KEEP_MSK;
1116
1112 /* typical time for secure PCP is 840ms */ 1117 /* typical time for secure PCP is 840ms */
1113 rc = wmi_call(wil, WMI_CFG_RX_CHAIN_CMDID, &cmd, sizeof(cmd), 1118 rc = wmi_call(wil, WMI_CFG_RX_CHAIN_CMDID, &cmd, sizeof(cmd),
1114 WMI_CFG_RX_CHAIN_DONE_EVENTID, &evt, sizeof(evt), 2000); 1119 WMI_CFG_RX_CHAIN_DONE_EVENTID, &evt, sizeof(evt), 2000);
@@ -1157,7 +1162,8 @@ int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac, u16 reason)
1157 struct wmi_disconnect_sta_cmd cmd = { 1162 struct wmi_disconnect_sta_cmd cmd = {
1158 .disconnect_reason = cpu_to_le16(reason), 1163 .disconnect_reason = cpu_to_le16(reason),
1159 }; 1164 };
1160 memcpy(cmd.dst_mac, mac, ETH_ALEN); 1165
1166 ether_addr_copy(cmd.dst_mac, mac);
1161 1167
1162 wil_dbg_wmi(wil, "%s(%pM, reason %d)\n", __func__, mac, reason); 1168 wil_dbg_wmi(wil, "%s(%pM, reason %d)\n", __func__, mac, reason);
1163 1169
diff --git a/drivers/net/wireless/ath/wil6210/wmi.h b/drivers/net/wireless/ath/wil6210/wmi.h
index 8a4af613e191..b29055315350 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.h
+++ b/drivers/net/wireless/ath/wil6210/wmi.h
@@ -70,7 +70,6 @@ enum wmi_command_id {
70 WMI_SET_UCODE_IDLE_CMDID = 0x0813, 70 WMI_SET_UCODE_IDLE_CMDID = 0x0813,
71 WMI_SET_WORK_MODE_CMDID = 0x0815, 71 WMI_SET_WORK_MODE_CMDID = 0x0815,
72 WMI_LO_LEAKAGE_CALIB_CMDID = 0x0816, 72 WMI_LO_LEAKAGE_CALIB_CMDID = 0x0816,
73 WMI_MARLON_R_ACTIVATE_CMDID = 0x0817,
74 WMI_MARLON_R_READ_CMDID = 0x0818, 73 WMI_MARLON_R_READ_CMDID = 0x0818,
75 WMI_MARLON_R_WRITE_CMDID = 0x0819, 74 WMI_MARLON_R_WRITE_CMDID = 0x0819,
76 WMI_MARLON_R_TXRX_SEL_CMDID = 0x081a, 75 WMI_MARLON_R_TXRX_SEL_CMDID = 0x081a,
@@ -80,6 +79,7 @@ enum wmi_command_id {
80 WMI_RF_RX_TEST_CMDID = 0x081e, 79 WMI_RF_RX_TEST_CMDID = 0x081e,
81 WMI_CFG_RX_CHAIN_CMDID = 0x0820, 80 WMI_CFG_RX_CHAIN_CMDID = 0x0820,
82 WMI_VRING_CFG_CMDID = 0x0821, 81 WMI_VRING_CFG_CMDID = 0x0821,
82 WMI_BCAST_VRING_CFG_CMDID = 0x0822,
83 WMI_VRING_BA_EN_CMDID = 0x0823, 83 WMI_VRING_BA_EN_CMDID = 0x0823,
84 WMI_VRING_BA_DIS_CMDID = 0x0824, 84 WMI_VRING_BA_DIS_CMDID = 0x0824,
85 WMI_RCP_ADDBA_RESP_CMDID = 0x0825, 85 WMI_RCP_ADDBA_RESP_CMDID = 0x0825,
@@ -99,6 +99,7 @@ enum wmi_command_id {
99 WMI_BF_TXSS_MGMT_CMDID = 0x0837, 99 WMI_BF_TXSS_MGMT_CMDID = 0x0837,
100 WMI_BF_SM_MGMT_CMDID = 0x0838, 100 WMI_BF_SM_MGMT_CMDID = 0x0838,
101 WMI_BF_RXSS_MGMT_CMDID = 0x0839, 101 WMI_BF_RXSS_MGMT_CMDID = 0x0839,
102 WMI_BF_TRIG_CMDID = 0x083A,
102 WMI_SET_SECTORS_CMDID = 0x0849, 103 WMI_SET_SECTORS_CMDID = 0x0849,
103 WMI_MAINTAIN_PAUSE_CMDID = 0x0850, 104 WMI_MAINTAIN_PAUSE_CMDID = 0x0850,
104 WMI_MAINTAIN_RESUME_CMDID = 0x0851, 105 WMI_MAINTAIN_RESUME_CMDID = 0x0851,
@@ -596,6 +597,22 @@ struct wmi_vring_cfg_cmd {
596} __packed; 597} __packed;
597 598
598/* 599/*
600 * WMI_BCAST_VRING_CFG_CMDID
601 */
602struct wmi_bcast_vring_cfg {
603 struct wmi_sw_ring_cfg tx_sw_ring;
604 u8 ringid; /* 0-23 vrings */
605 u8 encap_trans_type;
606 u8 ds_cfg; /* 802.3 DS cfg */
607 u8 nwifi_ds_trans_type;
608} __packed;
609
610struct wmi_bcast_vring_cfg_cmd {
611 __le32 action;
612 struct wmi_bcast_vring_cfg vring_cfg;
613} __packed;
614
615/*
599 * WMI_VRING_BA_EN_CMDID 616 * WMI_VRING_BA_EN_CMDID
600 */ 617 */
601struct wmi_vring_ba_en_cmd { 618struct wmi_vring_ba_en_cmd {
@@ -687,6 +704,9 @@ struct wmi_cfg_rx_chain_cmd {
687 #define L2_802_3_OFFLOAD_CTRL_VLAN_TAG_INSERTION_POS (0) 704 #define L2_802_3_OFFLOAD_CTRL_VLAN_TAG_INSERTION_POS (0)
688 #define L2_802_3_OFFLOAD_CTRL_VLAN_TAG_INSERTION_LEN (1) 705 #define L2_802_3_OFFLOAD_CTRL_VLAN_TAG_INSERTION_LEN (1)
689 #define L2_802_3_OFFLOAD_CTRL_VLAN_TAG_INSERTION_MSK (0x1) 706 #define L2_802_3_OFFLOAD_CTRL_VLAN_TAG_INSERTION_MSK (0x1)
707 #define L2_802_3_OFFLOAD_CTRL_SNAP_KEEP_POS (1)
708 #define L2_802_3_OFFLOAD_CTRL_SNAP_KEEP_LEN (1)
709 #define L2_802_3_OFFLOAD_CTRL_SNAP_KEEP_MSK (0x2)
690 u8 l2_802_3_offload_ctrl; 710 u8 l2_802_3_offload_ctrl;
691 711
692 #define L2_NWIFI_OFFLOAD_CTRL_REMOVE_QOS_POS (0) 712 #define L2_NWIFI_OFFLOAD_CTRL_REMOVE_QOS_POS (0)
@@ -841,7 +861,6 @@ enum wmi_event_id {
841 WMI_IQ_RX_CALIB_DONE_EVENTID = 0x1812, 861 WMI_IQ_RX_CALIB_DONE_EVENTID = 0x1812,
842 WMI_SET_WORK_MODE_DONE_EVENTID = 0x1815, 862 WMI_SET_WORK_MODE_DONE_EVENTID = 0x1815,
843 WMI_LO_LEAKAGE_CALIB_DONE_EVENTID = 0x1816, 863 WMI_LO_LEAKAGE_CALIB_DONE_EVENTID = 0x1816,
844 WMI_MARLON_R_ACTIVATE_DONE_EVENTID = 0x1817,
845 WMI_MARLON_R_READ_DONE_EVENTID = 0x1818, 864 WMI_MARLON_R_READ_DONE_EVENTID = 0x1818,
846 WMI_MARLON_R_WRITE_DONE_EVENTID = 0x1819, 865 WMI_MARLON_R_WRITE_DONE_EVENTID = 0x1819,
847 WMI_MARLON_R_TXRX_SEL_DONE_EVENTID = 0x181a, 866 WMI_MARLON_R_TXRX_SEL_DONE_EVENTID = 0x181a,
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index ea4843be773c..b2f9521fe551 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -4866,7 +4866,7 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
4866 switch (dev->dev->bus_type) { 4866 switch (dev->dev->bus_type) {
4867#ifdef CONFIG_B43_BCMA 4867#ifdef CONFIG_B43_BCMA
4868 case B43_BUS_BCMA: 4868 case B43_BUS_BCMA:
4869 bcma_core_pci_irq_ctl(dev->dev->bdev->bus, 4869 bcma_host_pci_irq_ctl(dev->dev->bdev->bus,
4870 dev->dev->bdev, true); 4870 dev->dev->bdev, true);
4871 bcma_host_pci_up(dev->dev->bdev->bus); 4871 bcma_host_pci_up(dev->dev->bdev->bus);
4872 break; 4872 break;
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index c438ccdb6ed8..9b508bd3b839 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -29,6 +29,7 @@
29#include <linux/mmc/host.h> 29#include <linux/mmc/host.h>
30#include <linux/platform_device.h> 30#include <linux/platform_device.h>
31#include <linux/platform_data/brcmfmac-sdio.h> 31#include <linux/platform_data/brcmfmac-sdio.h>
32#include <linux/pm_runtime.h>
32#include <linux/suspend.h> 33#include <linux/suspend.h>
33#include <linux/errno.h> 34#include <linux/errno.h>
34#include <linux/module.h> 35#include <linux/module.h>
@@ -1006,6 +1007,7 @@ static int brcmf_sdiod_remove(struct brcmf_sdio_dev *sdiodev)
1006 sg_free_table(&sdiodev->sgtable); 1007 sg_free_table(&sdiodev->sgtable);
1007 sdiodev->sbwad = 0; 1008 sdiodev->sbwad = 0;
1008 1009
1010 pm_runtime_allow(sdiodev->func[1]->card->host->parent);
1009 return 0; 1011 return 0;
1010} 1012}
1011 1013
@@ -1074,7 +1076,7 @@ static int brcmf_sdiod_probe(struct brcmf_sdio_dev *sdiodev)
1074 ret = -ENODEV; 1076 ret = -ENODEV;
1075 goto out; 1077 goto out;
1076 } 1078 }
1077 1079 pm_runtime_forbid(host->parent);
1078out: 1080out:
1079 if (ret) 1081 if (ret)
1080 brcmf_sdiod_remove(sdiodev); 1082 brcmf_sdiod_remove(sdiodev);
@@ -1096,6 +1098,8 @@ static const struct sdio_device_id brcmf_sdmmc_ids[] = {
1096 BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43341), 1098 BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43341),
1097 BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43362), 1099 BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43362),
1098 BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4335_4339), 1100 BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4335_4339),
1101 BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_43430),
1102 BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4345),
1099 BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4354), 1103 BRCMF_SDIO_DEVICE(SDIO_DEVICE_ID_BROADCOM_4354),
1100 { /* end: all zeroes */ } 1104 { /* end: all zeroes */ }
1101}; 1105};
@@ -1194,7 +1198,7 @@ static void brcmf_ops_sdio_remove(struct sdio_func *func)
1194 brcmf_dbg(SDIO, "sdio device ID: 0x%04x\n", func->device); 1198 brcmf_dbg(SDIO, "sdio device ID: 0x%04x\n", func->device);
1195 brcmf_dbg(SDIO, "Function: %d\n", func->num); 1199 brcmf_dbg(SDIO, "Function: %d\n", func->num);
1196 1200
1197 if (func->num != 1 && func->num != 2) 1201 if (func->num != 1)
1198 return; 1202 return;
1199 1203
1200 bus_if = dev_get_drvdata(&func->dev); 1204 bus_if = dev_get_drvdata(&func->dev);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/chip.c b/drivers/net/wireless/brcm80211/brcmfmac/chip.c
index 04d2ca0d87d6..ab2fac8b2760 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c
@@ -100,9 +100,6 @@
100#define BCM4329_CORE_SOCRAM_BASE 0x18003000 100#define BCM4329_CORE_SOCRAM_BASE 0x18003000
101/* ARM Cortex M3 core, ID 0x82a */ 101/* ARM Cortex M3 core, ID 0x82a */
102#define BCM4329_CORE_ARM_BASE 0x18002000 102#define BCM4329_CORE_ARM_BASE 0x18002000
103#define BCM4329_RAMSIZE 0x48000
104/* bcm43143 */
105#define BCM43143_RAMSIZE 0x70000
106 103
107#define CORE_SB(base, field) \ 104#define CORE_SB(base, field) \
108 (base + SBCONFIGOFF + offsetof(struct sbconfig, field)) 105 (base + SBCONFIGOFF + offsetof(struct sbconfig, field))
@@ -150,6 +147,78 @@ struct sbconfig {
150 u32 sbidhigh; /* identification */ 147 u32 sbidhigh; /* identification */
151}; 148};
152 149
150/* bankidx and bankinfo reg defines corerev >= 8 */
151#define SOCRAM_BANKINFO_RETNTRAM_MASK 0x00010000
152#define SOCRAM_BANKINFO_SZMASK 0x0000007f
153#define SOCRAM_BANKIDX_ROM_MASK 0x00000100
154
155#define SOCRAM_BANKIDX_MEMTYPE_SHIFT 8
156/* socram bankinfo memtype */
157#define SOCRAM_MEMTYPE_RAM 0
158#define SOCRAM_MEMTYPE_R0M 1
159#define SOCRAM_MEMTYPE_DEVRAM 2
160
161#define SOCRAM_BANKINFO_SZBASE 8192
162#define SRCI_LSS_MASK 0x00f00000
163#define SRCI_LSS_SHIFT 20
164#define SRCI_SRNB_MASK 0xf0
165#define SRCI_SRNB_SHIFT 4
166#define SRCI_SRBSZ_MASK 0xf
167#define SRCI_SRBSZ_SHIFT 0
168#define SR_BSZ_BASE 14
169
170struct sbsocramregs {
171 u32 coreinfo;
172 u32 bwalloc;
173 u32 extracoreinfo;
174 u32 biststat;
175 u32 bankidx;
176 u32 standbyctrl;
177
178 u32 errlogstatus; /* rev 6 */
179 u32 errlogaddr; /* rev 6 */
180 /* used for patching rev 3 & 5 */
181 u32 cambankidx;
182 u32 cambankstandbyctrl;
183 u32 cambankpatchctrl;
184 u32 cambankpatchtblbaseaddr;
185 u32 cambankcmdreg;
186 u32 cambankdatareg;
187 u32 cambankmaskreg;
188 u32 PAD[1];
189 u32 bankinfo; /* corev 8 */
190 u32 bankpda;
191 u32 PAD[14];
192 u32 extmemconfig;
193 u32 extmemparitycsr;
194 u32 extmemparityerrdata;
195 u32 extmemparityerrcnt;
196 u32 extmemwrctrlandsize;
197 u32 PAD[84];
198 u32 workaround;
199 u32 pwrctl; /* corerev >= 2 */
200 u32 PAD[133];
201 u32 sr_control; /* corerev >= 15 */
202 u32 sr_status; /* corerev >= 15 */
203 u32 sr_address; /* corerev >= 15 */
204 u32 sr_data; /* corerev >= 15 */
205};
206
207#define SOCRAMREGOFFS(_f) offsetof(struct sbsocramregs, _f)
208
209#define ARMCR4_CAP (0x04)
210#define ARMCR4_BANKIDX (0x40)
211#define ARMCR4_BANKINFO (0x44)
212#define ARMCR4_BANKPDA (0x4C)
213
214#define ARMCR4_TCBBNB_MASK 0xf0
215#define ARMCR4_TCBBNB_SHIFT 4
216#define ARMCR4_TCBANB_MASK 0xf
217#define ARMCR4_TCBANB_SHIFT 0
218
219#define ARMCR4_BSZ_MASK 0x3f
220#define ARMCR4_BSZ_MULT 8192
221
153struct brcmf_core_priv { 222struct brcmf_core_priv {
154 struct brcmf_core pub; 223 struct brcmf_core pub;
155 u32 wrapbase; 224 u32 wrapbase;
@@ -419,13 +488,13 @@ static struct brcmf_core *brcmf_chip_add_core(struct brcmf_chip_priv *ci,
419 return &core->pub; 488 return &core->pub;
420} 489}
421 490
422#ifdef DEBUG
423/* safety check for chipinfo */ 491/* safety check for chipinfo */
424static int brcmf_chip_cores_check(struct brcmf_chip_priv *ci) 492static int brcmf_chip_cores_check(struct brcmf_chip_priv *ci)
425{ 493{
426 struct brcmf_core_priv *core; 494 struct brcmf_core_priv *core;
427 bool need_socram = false; 495 bool need_socram = false;
428 bool has_socram = false; 496 bool has_socram = false;
497 bool cpu_found = false;
429 int idx = 1; 498 int idx = 1;
430 499
431 list_for_each_entry(core, &ci->cores, list) { 500 list_for_each_entry(core, &ci->cores, list) {
@@ -435,22 +504,24 @@ static int brcmf_chip_cores_check(struct brcmf_chip_priv *ci)
435 504
436 switch (core->pub.id) { 505 switch (core->pub.id) {
437 case BCMA_CORE_ARM_CM3: 506 case BCMA_CORE_ARM_CM3:
507 cpu_found = true;
438 need_socram = true; 508 need_socram = true;
439 break; 509 break;
440 case BCMA_CORE_INTERNAL_MEM: 510 case BCMA_CORE_INTERNAL_MEM:
441 has_socram = true; 511 has_socram = true;
442 break; 512 break;
443 case BCMA_CORE_ARM_CR4: 513 case BCMA_CORE_ARM_CR4:
444 if (ci->pub.rambase == 0) { 514 cpu_found = true;
445 brcmf_err("RAM base not provided with ARM CR4 core\n");
446 return -ENOMEM;
447 }
448 break; 515 break;
449 default: 516 default:
450 break; 517 break;
451 } 518 }
452 } 519 }
453 520
521 if (!cpu_found) {
522 brcmf_err("CPU core not detected\n");
523 return -ENXIO;
524 }
454 /* check RAM core presence for ARM CM3 core */ 525 /* check RAM core presence for ARM CM3 core */
455 if (need_socram && !has_socram) { 526 if (need_socram && !has_socram) {
456 brcmf_err("RAM core not provided with ARM CM3 core\n"); 527 brcmf_err("RAM core not provided with ARM CM3 core\n");
@@ -458,56 +529,164 @@ static int brcmf_chip_cores_check(struct brcmf_chip_priv *ci)
458 } 529 }
459 return 0; 530 return 0;
460} 531}
461#else /* DEBUG */ 532
462static inline int brcmf_chip_cores_check(struct brcmf_chip_priv *ci) 533static u32 brcmf_chip_core_read32(struct brcmf_core_priv *core, u16 reg)
463{ 534{
464 return 0; 535 return core->chip->ops->read32(core->chip->ctx, core->pub.base + reg);
465} 536}
466#endif
467 537
468static void brcmf_chip_get_raminfo(struct brcmf_chip_priv *ci) 538static void brcmf_chip_core_write32(struct brcmf_core_priv *core,
539 u16 reg, u32 val)
469{ 540{
470 switch (ci->pub.chip) { 541 core->chip->ops->write32(core->chip->ctx, core->pub.base + reg, val);
471 case BRCM_CC_4329_CHIP_ID: 542}
472 ci->pub.ramsize = BCM4329_RAMSIZE; 543
473 break; 544static bool brcmf_chip_socram_banksize(struct brcmf_core_priv *core, u8 idx,
474 case BRCM_CC_43143_CHIP_ID: 545 u32 *banksize)
475 ci->pub.ramsize = BCM43143_RAMSIZE; 546{
476 break; 547 u32 bankinfo;
477 case BRCM_CC_43241_CHIP_ID: 548 u32 bankidx = (SOCRAM_MEMTYPE_RAM << SOCRAM_BANKIDX_MEMTYPE_SHIFT);
478 ci->pub.ramsize = 0x90000; 549
479 break; 550 bankidx |= idx;
480 case BRCM_CC_4330_CHIP_ID: 551 brcmf_chip_core_write32(core, SOCRAMREGOFFS(bankidx), bankidx);
481 ci->pub.ramsize = 0x48000; 552 bankinfo = brcmf_chip_core_read32(core, SOCRAMREGOFFS(bankinfo));
482 break; 553 *banksize = (bankinfo & SOCRAM_BANKINFO_SZMASK) + 1;
554 *banksize *= SOCRAM_BANKINFO_SZBASE;
555 return !!(bankinfo & SOCRAM_BANKINFO_RETNTRAM_MASK);
556}
557
558static void brcmf_chip_socram_ramsize(struct brcmf_core_priv *sr, u32 *ramsize,
559 u32 *srsize)
560{
561 u32 coreinfo;
562 uint nb, banksize, lss;
563 bool retent;
564 int i;
565
566 *ramsize = 0;
567 *srsize = 0;
568
569 if (WARN_ON(sr->pub.rev < 4))
570 return;
571
572 if (!brcmf_chip_iscoreup(&sr->pub))
573 brcmf_chip_resetcore(&sr->pub, 0, 0, 0);
574
575 /* Get info for determining size */
576 coreinfo = brcmf_chip_core_read32(sr, SOCRAMREGOFFS(coreinfo));
577 nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
578
579 if ((sr->pub.rev <= 7) || (sr->pub.rev == 12)) {
580 banksize = (coreinfo & SRCI_SRBSZ_MASK);
581 lss = (coreinfo & SRCI_LSS_MASK) >> SRCI_LSS_SHIFT;
582 if (lss != 0)
583 nb--;
584 *ramsize = nb * (1 << (banksize + SR_BSZ_BASE));
585 if (lss != 0)
586 *ramsize += (1 << ((lss - 1) + SR_BSZ_BASE));
587 } else {
588 nb = (coreinfo & SRCI_SRNB_MASK) >> SRCI_SRNB_SHIFT;
589 for (i = 0; i < nb; i++) {
590 retent = brcmf_chip_socram_banksize(sr, i, &banksize);
591 *ramsize += banksize;
592 if (retent)
593 *srsize += banksize;
594 }
595 }
596
597 /* hardcoded save&restore memory sizes */
598 switch (sr->chip->pub.chip) {
483 case BRCM_CC_4334_CHIP_ID: 599 case BRCM_CC_4334_CHIP_ID:
484 case BRCM_CC_43340_CHIP_ID: 600 if (sr->chip->pub.chiprev < 2)
485 ci->pub.ramsize = 0x80000; 601 *srsize = (32 * 1024);
486 break; 602 break;
487 case BRCM_CC_4335_CHIP_ID: 603 case BRCM_CC_43430_CHIP_ID:
488 ci->pub.ramsize = 0xc0000; 604 /* assume sr for now as we can not check
489 ci->pub.rambase = 0x180000; 605 * firmware sr capability at this point.
606 */
607 *srsize = (64 * 1024);
490 break; 608 break;
491 case BRCM_CC_43362_CHIP_ID: 609 default:
492 ci->pub.ramsize = 0x3c000;
493 break; 610 break;
611 }
612}
613
614/** Return the TCM-RAM size of the ARMCR4 core. */
615static u32 brcmf_chip_tcm_ramsize(struct brcmf_core_priv *cr4)
616{
617 u32 corecap;
618 u32 memsize = 0;
619 u32 nab;
620 u32 nbb;
621 u32 totb;
622 u32 bxinfo;
623 u32 idx;
624
625 corecap = brcmf_chip_core_read32(cr4, ARMCR4_CAP);
626
627 nab = (corecap & ARMCR4_TCBANB_MASK) >> ARMCR4_TCBANB_SHIFT;
628 nbb = (corecap & ARMCR4_TCBBNB_MASK) >> ARMCR4_TCBBNB_SHIFT;
629 totb = nab + nbb;
630
631 for (idx = 0; idx < totb; idx++) {
632 brcmf_chip_core_write32(cr4, ARMCR4_BANKIDX, idx);
633 bxinfo = brcmf_chip_core_read32(cr4, ARMCR4_BANKINFO);
634 memsize += ((bxinfo & ARMCR4_BSZ_MASK) + 1) * ARMCR4_BSZ_MULT;
635 }
636
637 return memsize;
638}
639
640static u32 brcmf_chip_tcm_rambase(struct brcmf_chip_priv *ci)
641{
642 switch (ci->pub.chip) {
643 case BRCM_CC_4345_CHIP_ID:
644 return 0x198000;
645 case BRCM_CC_4335_CHIP_ID:
494 case BRCM_CC_4339_CHIP_ID: 646 case BRCM_CC_4339_CHIP_ID:
495 case BRCM_CC_4354_CHIP_ID: 647 case BRCM_CC_4354_CHIP_ID:
496 case BRCM_CC_4356_CHIP_ID: 648 case BRCM_CC_4356_CHIP_ID:
497 case BRCM_CC_43567_CHIP_ID: 649 case BRCM_CC_43567_CHIP_ID:
498 case BRCM_CC_43569_CHIP_ID: 650 case BRCM_CC_43569_CHIP_ID:
499 case BRCM_CC_43570_CHIP_ID: 651 case BRCM_CC_43570_CHIP_ID:
500 ci->pub.ramsize = 0xc0000;
501 ci->pub.rambase = 0x180000;
502 break;
503 case BRCM_CC_43602_CHIP_ID: 652 case BRCM_CC_43602_CHIP_ID:
504 ci->pub.ramsize = 0xf0000; 653 return 0x180000;
505 ci->pub.rambase = 0x180000;
506 break;
507 default: 654 default:
508 brcmf_err("unknown chip: %s\n", ci->pub.name); 655 brcmf_err("unknown chip: %s\n", ci->pub.name);
509 break; 656 break;
510 } 657 }
658 return 0;
659}
660
661static int brcmf_chip_get_raminfo(struct brcmf_chip_priv *ci)
662{
663 struct brcmf_core_priv *mem_core;
664 struct brcmf_core *mem;
665
666 mem = brcmf_chip_get_core(&ci->pub, BCMA_CORE_ARM_CR4);
667 if (mem) {
668 mem_core = container_of(mem, struct brcmf_core_priv, pub);
669 ci->pub.ramsize = brcmf_chip_tcm_ramsize(mem_core);
670 ci->pub.rambase = brcmf_chip_tcm_rambase(ci);
671 if (!ci->pub.rambase) {
672 brcmf_err("RAM base not provided with ARM CR4 core\n");
673 return -EINVAL;
674 }
675 } else {
676 mem = brcmf_chip_get_core(&ci->pub, BCMA_CORE_INTERNAL_MEM);
677 mem_core = container_of(mem, struct brcmf_core_priv, pub);
678 brcmf_chip_socram_ramsize(mem_core, &ci->pub.ramsize,
679 &ci->pub.srsize);
680 }
681 brcmf_dbg(INFO, "RAM: base=0x%x size=%d (0x%x) sr=%d (0x%x)\n",
682 ci->pub.rambase, ci->pub.ramsize, ci->pub.ramsize,
683 ci->pub.srsize, ci->pub.srsize);
684
685 if (!ci->pub.ramsize) {
686 brcmf_err("RAM size is undetermined\n");
687 return -ENOMEM;
688 }
689 return 0;
511} 690}
512 691
513static u32 brcmf_chip_dmp_get_desc(struct brcmf_chip_priv *ci, u32 *eromaddr, 692static u32 brcmf_chip_dmp_get_desc(struct brcmf_chip_priv *ci, u32 *eromaddr,
@@ -660,6 +839,7 @@ static int brcmf_chip_recognition(struct brcmf_chip_priv *ci)
660 struct brcmf_core *core; 839 struct brcmf_core *core;
661 u32 regdata; 840 u32 regdata;
662 u32 socitype; 841 u32 socitype;
842 int ret;
663 843
664 /* Get CC core rev 844 /* Get CC core rev
665 * Chipid is assume to be at offset 0 from SI_ENUM_BASE 845 * Chipid is assume to be at offset 0 from SI_ENUM_BASE
@@ -712,9 +892,13 @@ static int brcmf_chip_recognition(struct brcmf_chip_priv *ci)
712 return -ENODEV; 892 return -ENODEV;
713 } 893 }
714 894
715 brcmf_chip_get_raminfo(ci); 895 ret = brcmf_chip_cores_check(ci);
896 if (ret)
897 return ret;
716 898
717 return brcmf_chip_cores_check(ci); 899 /* assure chip is passive for core access */
900 brcmf_chip_set_passive(&ci->pub);
901 return brcmf_chip_get_raminfo(ci);
718} 902}
719 903
720static void brcmf_chip_disable_arm(struct brcmf_chip_priv *chip, u16 id) 904static void brcmf_chip_disable_arm(struct brcmf_chip_priv *chip, u16 id)
@@ -778,12 +962,6 @@ static int brcmf_chip_setup(struct brcmf_chip_priv *chip)
778 if (chip->ops->setup) 962 if (chip->ops->setup)
779 ret = chip->ops->setup(chip->ctx, pub); 963 ret = chip->ops->setup(chip->ctx, pub);
780 964
781 /*
782 * Make sure any on-chip ARM is off (in case strapping is wrong),
783 * or downloaded code was already running.
784 */
785 brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CM3);
786 brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CR4);
787 return ret; 965 return ret;
788} 966}
789 967
@@ -799,7 +977,7 @@ struct brcmf_chip *brcmf_chip_attach(void *ctx,
799 err = -EINVAL; 977 err = -EINVAL;
800 if (WARN_ON(!ops->prepare)) 978 if (WARN_ON(!ops->prepare))
801 err = -EINVAL; 979 err = -EINVAL;
802 if (WARN_ON(!ops->exit_dl)) 980 if (WARN_ON(!ops->activate))
803 err = -EINVAL; 981 err = -EINVAL;
804 if (err < 0) 982 if (err < 0)
805 return ERR_PTR(-EINVAL); 983 return ERR_PTR(-EINVAL);
@@ -897,9 +1075,10 @@ void brcmf_chip_resetcore(struct brcmf_core *pub, u32 prereset, u32 reset,
897} 1075}
898 1076
899static void 1077static void
900brcmf_chip_cm3_enterdl(struct brcmf_chip_priv *chip) 1078brcmf_chip_cm3_set_passive(struct brcmf_chip_priv *chip)
901{ 1079{
902 struct brcmf_core *core; 1080 struct brcmf_core *core;
1081 struct brcmf_core_priv *sr;
903 1082
904 brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CM3); 1083 brcmf_chip_disable_arm(chip, BCMA_CORE_ARM_CM3);
905 core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_80211); 1084 core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_80211);
@@ -909,9 +1088,16 @@ brcmf_chip_cm3_enterdl(struct brcmf_chip_priv *chip)
909 D11_BCMA_IOCTL_PHYCLOCKEN); 1088 D11_BCMA_IOCTL_PHYCLOCKEN);
910 core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_INTERNAL_MEM); 1089 core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_INTERNAL_MEM);
911 brcmf_chip_resetcore(core, 0, 0, 0); 1090 brcmf_chip_resetcore(core, 0, 0, 0);
1091
1092 /* disable bank #3 remap for this device */
1093 if (chip->pub.chip == BRCM_CC_43430_CHIP_ID) {
1094 sr = container_of(core, struct brcmf_core_priv, pub);
1095 brcmf_chip_core_write32(sr, SOCRAMREGOFFS(bankidx), 3);
1096 brcmf_chip_core_write32(sr, SOCRAMREGOFFS(bankpda), 0);
1097 }
912} 1098}
913 1099
914static bool brcmf_chip_cm3_exitdl(struct brcmf_chip_priv *chip) 1100static bool brcmf_chip_cm3_set_active(struct brcmf_chip_priv *chip)
915{ 1101{
916 struct brcmf_core *core; 1102 struct brcmf_core *core;
917 1103
@@ -921,7 +1107,7 @@ static bool brcmf_chip_cm3_exitdl(struct brcmf_chip_priv *chip)
921 return false; 1107 return false;
922 } 1108 }
923 1109
924 chip->ops->exit_dl(chip->ctx, &chip->pub, 0); 1110 chip->ops->activate(chip->ctx, &chip->pub, 0);
925 1111
926 core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_ARM_CM3); 1112 core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_ARM_CM3);
927 brcmf_chip_resetcore(core, 0, 0, 0); 1113 brcmf_chip_resetcore(core, 0, 0, 0);
@@ -930,7 +1116,7 @@ static bool brcmf_chip_cm3_exitdl(struct brcmf_chip_priv *chip)
930} 1116}
931 1117
932static inline void 1118static inline void
933brcmf_chip_cr4_enterdl(struct brcmf_chip_priv *chip) 1119brcmf_chip_cr4_set_passive(struct brcmf_chip_priv *chip)
934{ 1120{
935 struct brcmf_core *core; 1121 struct brcmf_core *core;
936 1122
@@ -943,11 +1129,11 @@ brcmf_chip_cr4_enterdl(struct brcmf_chip_priv *chip)
943 D11_BCMA_IOCTL_PHYCLOCKEN); 1129 D11_BCMA_IOCTL_PHYCLOCKEN);
944} 1130}
945 1131
946static bool brcmf_chip_cr4_exitdl(struct brcmf_chip_priv *chip, u32 rstvec) 1132static bool brcmf_chip_cr4_set_active(struct brcmf_chip_priv *chip, u32 rstvec)
947{ 1133{
948 struct brcmf_core *core; 1134 struct brcmf_core *core;
949 1135
950 chip->ops->exit_dl(chip->ctx, &chip->pub, rstvec); 1136 chip->ops->activate(chip->ctx, &chip->pub, rstvec);
951 1137
952 /* restore ARM */ 1138 /* restore ARM */
953 core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_ARM_CR4); 1139 core = brcmf_chip_get_core(&chip->pub, BCMA_CORE_ARM_CR4);
@@ -956,7 +1142,7 @@ static bool brcmf_chip_cr4_exitdl(struct brcmf_chip_priv *chip, u32 rstvec)
956 return true; 1142 return true;
957} 1143}
958 1144
959void brcmf_chip_enter_download(struct brcmf_chip *pub) 1145void brcmf_chip_set_passive(struct brcmf_chip *pub)
960{ 1146{
961 struct brcmf_chip_priv *chip; 1147 struct brcmf_chip_priv *chip;
962 struct brcmf_core *arm; 1148 struct brcmf_core *arm;
@@ -966,14 +1152,14 @@ void brcmf_chip_enter_download(struct brcmf_chip *pub)
966 chip = container_of(pub, struct brcmf_chip_priv, pub); 1152 chip = container_of(pub, struct brcmf_chip_priv, pub);
967 arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CR4); 1153 arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CR4);
968 if (arm) { 1154 if (arm) {
969 brcmf_chip_cr4_enterdl(chip); 1155 brcmf_chip_cr4_set_passive(chip);
970 return; 1156 return;
971 } 1157 }
972 1158
973 brcmf_chip_cm3_enterdl(chip); 1159 brcmf_chip_cm3_set_passive(chip);
974} 1160}
975 1161
976bool brcmf_chip_exit_download(struct brcmf_chip *pub, u32 rstvec) 1162bool brcmf_chip_set_active(struct brcmf_chip *pub, u32 rstvec)
977{ 1163{
978 struct brcmf_chip_priv *chip; 1164 struct brcmf_chip_priv *chip;
979 struct brcmf_core *arm; 1165 struct brcmf_core *arm;
@@ -983,9 +1169,9 @@ bool brcmf_chip_exit_download(struct brcmf_chip *pub, u32 rstvec)
983 chip = container_of(pub, struct brcmf_chip_priv, pub); 1169 chip = container_of(pub, struct brcmf_chip_priv, pub);
984 arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CR4); 1170 arm = brcmf_chip_get_core(pub, BCMA_CORE_ARM_CR4);
985 if (arm) 1171 if (arm)
986 return brcmf_chip_cr4_exitdl(chip, rstvec); 1172 return brcmf_chip_cr4_set_active(chip, rstvec);
987 1173
988 return brcmf_chip_cm3_exitdl(chip); 1174 return brcmf_chip_cm3_set_active(chip);
989} 1175}
990 1176
991bool brcmf_chip_sr_capable(struct brcmf_chip *pub) 1177bool brcmf_chip_sr_capable(struct brcmf_chip *pub)
@@ -1016,6 +1202,10 @@ bool brcmf_chip_sr_capable(struct brcmf_chip *pub)
1016 addr = CORE_CC_REG(base, chipcontrol_data); 1202 addr = CORE_CC_REG(base, chipcontrol_data);
1017 reg = chip->ops->read32(chip->ctx, addr); 1203 reg = chip->ops->read32(chip->ctx, addr);
1018 return (reg & pmu_cc3_mask) != 0; 1204 return (reg & pmu_cc3_mask) != 0;
1205 case BRCM_CC_43430_CHIP_ID:
1206 addr = CORE_CC_REG(base, sr_control1);
1207 reg = chip->ops->read32(chip->ctx, addr);
1208 return reg != 0;
1019 default: 1209 default:
1020 addr = CORE_CC_REG(base, pmucapabilities_ext); 1210 addr = CORE_CC_REG(base, pmucapabilities_ext);
1021 reg = chip->ops->read32(chip->ctx, addr); 1211 reg = chip->ops->read32(chip->ctx, addr);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/chip.h b/drivers/net/wireless/brcm80211/brcmfmac/chip.h
index c32908da90c8..60dcb38fc77a 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/chip.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.h
@@ -30,7 +30,8 @@
30 * @pmucaps: PMU capabilities. 30 * @pmucaps: PMU capabilities.
31 * @pmurev: PMU revision. 31 * @pmurev: PMU revision.
32 * @rambase: RAM base address (only applicable for ARM CR4 chips). 32 * @rambase: RAM base address (only applicable for ARM CR4 chips).
33 * @ramsize: amount of RAM on chip. 33 * @ramsize: amount of RAM on chip including retention.
34 * @srsize: amount of retention RAM on chip.
34 * @name: string representation of the chip identifier. 35 * @name: string representation of the chip identifier.
35 */ 36 */
36struct brcmf_chip { 37struct brcmf_chip {
@@ -41,6 +42,7 @@ struct brcmf_chip {
41 u32 pmurev; 42 u32 pmurev;
42 u32 rambase; 43 u32 rambase;
43 u32 ramsize; 44 u32 ramsize;
45 u32 srsize;
44 char name[8]; 46 char name[8];
45}; 47};
46 48
@@ -64,7 +66,7 @@ struct brcmf_core {
64 * @write32: write 32-bit value over bus. 66 * @write32: write 32-bit value over bus.
65 * @prepare: prepare bus for core configuration. 67 * @prepare: prepare bus for core configuration.
66 * @setup: bus-specific core setup. 68 * @setup: bus-specific core setup.
67 * @exit_dl: exit download state. 69 * @active: chip becomes active.
68 * The callback should use the provided @rstvec when non-zero. 70 * The callback should use the provided @rstvec when non-zero.
69 */ 71 */
70struct brcmf_buscore_ops { 72struct brcmf_buscore_ops {
@@ -72,7 +74,7 @@ struct brcmf_buscore_ops {
72 void (*write32)(void *ctx, u32 addr, u32 value); 74 void (*write32)(void *ctx, u32 addr, u32 value);
73 int (*prepare)(void *ctx); 75 int (*prepare)(void *ctx);
74 int (*setup)(void *ctx, struct brcmf_chip *chip); 76 int (*setup)(void *ctx, struct brcmf_chip *chip);
75 void (*exit_dl)(void *ctx, struct brcmf_chip *chip, u32 rstvec); 77 void (*activate)(void *ctx, struct brcmf_chip *chip, u32 rstvec);
76}; 78};
77 79
78struct brcmf_chip *brcmf_chip_attach(void *ctx, 80struct brcmf_chip *brcmf_chip_attach(void *ctx,
@@ -84,8 +86,8 @@ bool brcmf_chip_iscoreup(struct brcmf_core *core);
84void brcmf_chip_coredisable(struct brcmf_core *core, u32 prereset, u32 reset); 86void brcmf_chip_coredisable(struct brcmf_core *core, u32 prereset, u32 reset);
85void brcmf_chip_resetcore(struct brcmf_core *core, u32 prereset, u32 reset, 87void brcmf_chip_resetcore(struct brcmf_core *core, u32 prereset, u32 reset,
86 u32 postreset); 88 u32 postreset);
87void brcmf_chip_enter_download(struct brcmf_chip *ci); 89void brcmf_chip_set_passive(struct brcmf_chip *ci);
88bool brcmf_chip_exit_download(struct brcmf_chip *ci, u32 rstvec); 90bool brcmf_chip_set_active(struct brcmf_chip *ci, u32 rstvec);
89bool brcmf_chip_sr_capable(struct brcmf_chip *pub); 91bool brcmf_chip_sr_capable(struct brcmf_chip *pub);
90 92
91#endif /* BRCMF_AXIDMP_H */ 93#endif /* BRCMF_AXIDMP_H */
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
index 6262612dec45..4ec9811f49c8 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.c
@@ -481,10 +481,9 @@ static int brcmf_msgbuf_ioctl_resp_wait(struct brcmf_msgbuf *msgbuf)
481 481
482static void brcmf_msgbuf_ioctl_resp_wake(struct brcmf_msgbuf *msgbuf) 482static void brcmf_msgbuf_ioctl_resp_wake(struct brcmf_msgbuf *msgbuf)
483{ 483{
484 if (waitqueue_active(&msgbuf->ioctl_resp_wait)) { 484 msgbuf->ctl_completed = true;
485 msgbuf->ctl_completed = true; 485 if (waitqueue_active(&msgbuf->ioctl_resp_wait))
486 wake_up(&msgbuf->ioctl_resp_wait); 486 wake_up(&msgbuf->ioctl_resp_wait);
487 }
488} 487}
489 488
490 489
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.h b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.h
index 77a51b8c1e12..3d513e407e3d 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.h
+++ b/drivers/net/wireless/brcm80211/brcmfmac/msgbuf.h
@@ -17,11 +17,11 @@
17 17
18#ifdef CONFIG_BRCMFMAC_PROTO_MSGBUF 18#ifdef CONFIG_BRCMFMAC_PROTO_MSGBUF
19 19
20#define BRCMF_H2D_MSGRING_CONTROL_SUBMIT_MAX_ITEM 20 20#define BRCMF_H2D_MSGRING_CONTROL_SUBMIT_MAX_ITEM 64
21#define BRCMF_H2D_MSGRING_RXPOST_SUBMIT_MAX_ITEM 256 21#define BRCMF_H2D_MSGRING_RXPOST_SUBMIT_MAX_ITEM 512
22#define BRCMF_D2H_MSGRING_CONTROL_COMPLETE_MAX_ITEM 20 22#define BRCMF_D2H_MSGRING_CONTROL_COMPLETE_MAX_ITEM 64
23#define BRCMF_D2H_MSGRING_TX_COMPLETE_MAX_ITEM 1024 23#define BRCMF_D2H_MSGRING_TX_COMPLETE_MAX_ITEM 1024
24#define BRCMF_D2H_MSGRING_RX_COMPLETE_MAX_ITEM 256 24#define BRCMF_D2H_MSGRING_RX_COMPLETE_MAX_ITEM 512
25#define BRCMF_H2D_TXFLOWRING_MAX_ITEM 512 25#define BRCMF_H2D_TXFLOWRING_MAX_ITEM 512
26 26
27#define BRCMF_H2D_MSGRING_CONTROL_SUBMIT_ITEMSIZE 40 27#define BRCMF_H2D_MSGRING_CONTROL_SUBMIT_ITEMSIZE 40
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
index 61c053a729be..1831ecd0813e 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/pcie.c
@@ -47,8 +47,6 @@ enum brcmf_pcie_state {
47 47
48#define BRCMF_PCIE_43602_FW_NAME "brcm/brcmfmac43602-pcie.bin" 48#define BRCMF_PCIE_43602_FW_NAME "brcm/brcmfmac43602-pcie.bin"
49#define BRCMF_PCIE_43602_NVRAM_NAME "brcm/brcmfmac43602-pcie.txt" 49#define BRCMF_PCIE_43602_NVRAM_NAME "brcm/brcmfmac43602-pcie.txt"
50#define BRCMF_PCIE_4354_FW_NAME "brcm/brcmfmac4354-pcie.bin"
51#define BRCMF_PCIE_4354_NVRAM_NAME "brcm/brcmfmac4354-pcie.txt"
52#define BRCMF_PCIE_4356_FW_NAME "brcm/brcmfmac4356-pcie.bin" 50#define BRCMF_PCIE_4356_FW_NAME "brcm/brcmfmac4356-pcie.bin"
53#define BRCMF_PCIE_4356_NVRAM_NAME "brcm/brcmfmac4356-pcie.txt" 51#define BRCMF_PCIE_4356_NVRAM_NAME "brcm/brcmfmac4356-pcie.txt"
54#define BRCMF_PCIE_43570_FW_NAME "brcm/brcmfmac43570-pcie.bin" 52#define BRCMF_PCIE_43570_FW_NAME "brcm/brcmfmac43570-pcie.bin"
@@ -187,8 +185,8 @@ enum brcmf_pcie_state {
187 185
188MODULE_FIRMWARE(BRCMF_PCIE_43602_FW_NAME); 186MODULE_FIRMWARE(BRCMF_PCIE_43602_FW_NAME);
189MODULE_FIRMWARE(BRCMF_PCIE_43602_NVRAM_NAME); 187MODULE_FIRMWARE(BRCMF_PCIE_43602_NVRAM_NAME);
190MODULE_FIRMWARE(BRCMF_PCIE_4354_FW_NAME); 188MODULE_FIRMWARE(BRCMF_PCIE_4356_FW_NAME);
191MODULE_FIRMWARE(BRCMF_PCIE_4354_NVRAM_NAME); 189MODULE_FIRMWARE(BRCMF_PCIE_4356_NVRAM_NAME);
192MODULE_FIRMWARE(BRCMF_PCIE_43570_FW_NAME); 190MODULE_FIRMWARE(BRCMF_PCIE_43570_FW_NAME);
193MODULE_FIRMWARE(BRCMF_PCIE_43570_NVRAM_NAME); 191MODULE_FIRMWARE(BRCMF_PCIE_43570_NVRAM_NAME);
194 192
@@ -509,8 +507,6 @@ static void brcmf_pcie_attach(struct brcmf_pciedev_info *devinfo)
509 507
510static int brcmf_pcie_enter_download_state(struct brcmf_pciedev_info *devinfo) 508static int brcmf_pcie_enter_download_state(struct brcmf_pciedev_info *devinfo)
511{ 509{
512 brcmf_chip_enter_download(devinfo->ci);
513
514 if (devinfo->ci->chip == BRCM_CC_43602_CHIP_ID) { 510 if (devinfo->ci->chip == BRCM_CC_43602_CHIP_ID) {
515 brcmf_pcie_select_core(devinfo, BCMA_CORE_ARM_CR4); 511 brcmf_pcie_select_core(devinfo, BCMA_CORE_ARM_CR4);
516 brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_ARMCR4REG_BANKIDX, 512 brcmf_pcie_write_reg32(devinfo, BRCMF_PCIE_ARMCR4REG_BANKIDX,
@@ -536,7 +532,7 @@ static int brcmf_pcie_exit_download_state(struct brcmf_pciedev_info *devinfo,
536 brcmf_chip_resetcore(core, 0, 0, 0); 532 brcmf_chip_resetcore(core, 0, 0, 0);
537 } 533 }
538 534
539 return !brcmf_chip_exit_download(devinfo->ci, resetintr); 535 return !brcmf_chip_set_active(devinfo->ci, resetintr);
540} 536}
541 537
542 538
@@ -653,10 +649,9 @@ static void brcmf_pcie_bus_console_read(struct brcmf_pciedev_info *devinfo)
653 console->log_str[console->log_idx] = ch; 649 console->log_str[console->log_idx] = ch;
654 console->log_idx++; 650 console->log_idx++;
655 } 651 }
656
657 if (ch == '\n') { 652 if (ch == '\n') {
658 console->log_str[console->log_idx] = 0; 653 console->log_str[console->log_idx] = 0;
659 brcmf_dbg(PCIE, "CONSOLE: %s\n", console->log_str); 654 brcmf_dbg(PCIE, "CONSOLE: %s", console->log_str);
660 console->log_idx = 0; 655 console->log_idx = 0;
661 } 656 }
662 } 657 }
@@ -1328,10 +1323,6 @@ static int brcmf_pcie_get_fwnames(struct brcmf_pciedev_info *devinfo)
1328 fw_name = BRCMF_PCIE_43602_FW_NAME; 1323 fw_name = BRCMF_PCIE_43602_FW_NAME;
1329 nvram_name = BRCMF_PCIE_43602_NVRAM_NAME; 1324 nvram_name = BRCMF_PCIE_43602_NVRAM_NAME;
1330 break; 1325 break;
1331 case BRCM_CC_4354_CHIP_ID:
1332 fw_name = BRCMF_PCIE_4354_FW_NAME;
1333 nvram_name = BRCMF_PCIE_4354_NVRAM_NAME;
1334 break;
1335 case BRCM_CC_4356_CHIP_ID: 1326 case BRCM_CC_4356_CHIP_ID:
1336 fw_name = BRCMF_PCIE_4356_FW_NAME; 1327 fw_name = BRCMF_PCIE_4356_FW_NAME;
1337 nvram_name = BRCMF_PCIE_4356_NVRAM_NAME; 1328 nvram_name = BRCMF_PCIE_4356_NVRAM_NAME;
@@ -1566,8 +1557,8 @@ static int brcmf_pcie_buscoreprep(void *ctx)
1566} 1557}
1567 1558
1568 1559
1569static void brcmf_pcie_buscore_exitdl(void *ctx, struct brcmf_chip *chip, 1560static void brcmf_pcie_buscore_activate(void *ctx, struct brcmf_chip *chip,
1570 u32 rstvec) 1561 u32 rstvec)
1571{ 1562{
1572 struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)ctx; 1563 struct brcmf_pciedev_info *devinfo = (struct brcmf_pciedev_info *)ctx;
1573 1564
@@ -1577,7 +1568,7 @@ static void brcmf_pcie_buscore_exitdl(void *ctx, struct brcmf_chip *chip,
1577 1568
1578static const struct brcmf_buscore_ops brcmf_pcie_buscore_ops = { 1569static const struct brcmf_buscore_ops brcmf_pcie_buscore_ops = {
1579 .prepare = brcmf_pcie_buscoreprep, 1570 .prepare = brcmf_pcie_buscoreprep,
1580 .exit_dl = brcmf_pcie_buscore_exitdl, 1571 .activate = brcmf_pcie_buscore_activate,
1581 .read32 = brcmf_pcie_buscore_read32, 1572 .read32 = brcmf_pcie_buscore_read32,
1582 .write32 = brcmf_pcie_buscore_write32, 1573 .write32 = brcmf_pcie_buscore_write32,
1583}; 1574};
@@ -1856,7 +1847,6 @@ cleanup:
1856 PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NETWORK_OTHER << 8, 0xffff00, 0 } 1847 PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NETWORK_OTHER << 8, 0xffff00, 0 }
1857 1848
1858static struct pci_device_id brcmf_pcie_devid_table[] = { 1849static struct pci_device_id brcmf_pcie_devid_table[] = {
1859 BRCMF_PCIE_DEVICE(BRCM_PCIE_4354_DEVICE_ID),
1860 BRCMF_PCIE_DEVICE(BRCM_PCIE_4356_DEVICE_ID), 1850 BRCMF_PCIE_DEVICE(BRCM_PCIE_4356_DEVICE_ID),
1861 BRCMF_PCIE_DEVICE(BRCM_PCIE_43567_DEVICE_ID), 1851 BRCMF_PCIE_DEVICE(BRCM_PCIE_43567_DEVICE_ID),
1862 BRCMF_PCIE_DEVICE(BRCM_PCIE_43570_DEVICE_ID), 1852 BRCMF_PCIE_DEVICE(BRCM_PCIE_43570_DEVICE_ID),
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
index 257ee70feb5b..ab0c89833013 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/sdio.c
@@ -432,8 +432,6 @@ struct brcmf_sdio {
432 struct brcmf_sdio_dev *sdiodev; /* sdio device handler */ 432 struct brcmf_sdio_dev *sdiodev; /* sdio device handler */
433 struct brcmf_chip *ci; /* Chip info struct */ 433 struct brcmf_chip *ci; /* Chip info struct */
434 434
435 u32 ramsize; /* Size of RAM in SOCRAM (bytes) */
436
437 u32 hostintmask; /* Copy of Host Interrupt Mask */ 435 u32 hostintmask; /* Copy of Host Interrupt Mask */
438 atomic_t intstatus; /* Intstatus bits (events) pending */ 436 atomic_t intstatus; /* Intstatus bits (events) pending */
439 atomic_t fcstate; /* State of dongle flow-control */ 437 atomic_t fcstate; /* State of dongle flow-control */
@@ -485,10 +483,9 @@ struct brcmf_sdio {
485#endif /* DEBUG */ 483#endif /* DEBUG */
486 484
487 uint clkstate; /* State of sd and backplane clock(s) */ 485 uint clkstate; /* State of sd and backplane clock(s) */
488 bool activity; /* Activity flag for clock down */
489 s32 idletime; /* Control for activity timeout */ 486 s32 idletime; /* Control for activity timeout */
490 s32 idlecount; /* Activity timeout counter */ 487 s32 idlecount; /* Activity timeout counter */
491 s32 idleclock; /* How to set bus driver when idle */ 488 s32 idleclock; /* How to set bus driver when idle */
492 bool rxflow_mode; /* Rx flow control mode */ 489 bool rxflow_mode; /* Rx flow control mode */
493 bool rxflow; /* Is rx flow control on */ 490 bool rxflow; /* Is rx flow control on */
494 bool alp_only; /* Don't use HT clock (ALP only) */ 491 bool alp_only; /* Don't use HT clock (ALP only) */
@@ -510,7 +507,8 @@ struct brcmf_sdio {
510 507
511 struct workqueue_struct *brcmf_wq; 508 struct workqueue_struct *brcmf_wq;
512 struct work_struct datawork; 509 struct work_struct datawork;
513 atomic_t dpc_tskcnt; 510 bool dpc_triggered;
511 bool dpc_running;
514 512
515 bool txoff; /* Transmit flow-controlled */ 513 bool txoff; /* Transmit flow-controlled */
516 struct brcmf_sdio_count sdcnt; 514 struct brcmf_sdio_count sdcnt;
@@ -617,6 +615,10 @@ static const struct sdiod_drive_str sdiod_drvstr_tab2_3v3[] = {
617#define BCM43362_NVRAM_NAME "brcm/brcmfmac43362-sdio.txt" 615#define BCM43362_NVRAM_NAME "brcm/brcmfmac43362-sdio.txt"
618#define BCM4339_FIRMWARE_NAME "brcm/brcmfmac4339-sdio.bin" 616#define BCM4339_FIRMWARE_NAME "brcm/brcmfmac4339-sdio.bin"
619#define BCM4339_NVRAM_NAME "brcm/brcmfmac4339-sdio.txt" 617#define BCM4339_NVRAM_NAME "brcm/brcmfmac4339-sdio.txt"
618#define BCM43430_FIRMWARE_NAME "brcm/brcmfmac43430-sdio.bin"
619#define BCM43430_NVRAM_NAME "brcm/brcmfmac43430-sdio.txt"
620#define BCM43455_FIRMWARE_NAME "brcm/brcmfmac43455-sdio.bin"
621#define BCM43455_NVRAM_NAME "brcm/brcmfmac43455-sdio.txt"
620#define BCM4354_FIRMWARE_NAME "brcm/brcmfmac4354-sdio.bin" 622#define BCM4354_FIRMWARE_NAME "brcm/brcmfmac4354-sdio.bin"
621#define BCM4354_NVRAM_NAME "brcm/brcmfmac4354-sdio.txt" 623#define BCM4354_NVRAM_NAME "brcm/brcmfmac4354-sdio.txt"
622 624
@@ -640,6 +642,10 @@ MODULE_FIRMWARE(BCM43362_FIRMWARE_NAME);
640MODULE_FIRMWARE(BCM43362_NVRAM_NAME); 642MODULE_FIRMWARE(BCM43362_NVRAM_NAME);
641MODULE_FIRMWARE(BCM4339_FIRMWARE_NAME); 643MODULE_FIRMWARE(BCM4339_FIRMWARE_NAME);
642MODULE_FIRMWARE(BCM4339_NVRAM_NAME); 644MODULE_FIRMWARE(BCM4339_NVRAM_NAME);
645MODULE_FIRMWARE(BCM43430_FIRMWARE_NAME);
646MODULE_FIRMWARE(BCM43430_NVRAM_NAME);
647MODULE_FIRMWARE(BCM43455_FIRMWARE_NAME);
648MODULE_FIRMWARE(BCM43455_NVRAM_NAME);
643MODULE_FIRMWARE(BCM4354_FIRMWARE_NAME); 649MODULE_FIRMWARE(BCM4354_FIRMWARE_NAME);
644MODULE_FIRMWARE(BCM4354_NVRAM_NAME); 650MODULE_FIRMWARE(BCM4354_NVRAM_NAME);
645 651
@@ -669,6 +675,8 @@ static const struct brcmf_firmware_names brcmf_fwname_data[] = {
669 { BRCM_CC_4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) }, 675 { BRCM_CC_4335_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4335) },
670 { BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, BRCMF_FIRMWARE_NVRAM(BCM43362) }, 676 { BRCM_CC_43362_CHIP_ID, 0xFFFFFFFE, BRCMF_FIRMWARE_NVRAM(BCM43362) },
671 { BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) }, 677 { BRCM_CC_4339_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4339) },
678 { BRCM_CC_43430_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM43430) },
679 { BRCM_CC_4345_CHIP_ID, 0xFFFFFFC0, BRCMF_FIRMWARE_NVRAM(BCM43455) },
672 { BRCM_CC_4354_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4354) } 680 { BRCM_CC_4354_CHIP_ID, 0xFFFFFFFF, BRCMF_FIRMWARE_NVRAM(BCM4354) }
673}; 681};
674 682
@@ -959,13 +967,8 @@ static int brcmf_sdio_clkctl(struct brcmf_sdio *bus, uint target, bool pendok)
959 brcmf_dbg(SDIO, "Enter\n"); 967 brcmf_dbg(SDIO, "Enter\n");
960 968
961 /* Early exit if we're already there */ 969 /* Early exit if we're already there */
962 if (bus->clkstate == target) { 970 if (bus->clkstate == target)
963 if (target == CLK_AVAIL) {
964 brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS);
965 bus->activity = true;
966 }
967 return 0; 971 return 0;
968 }
969 972
970 switch (target) { 973 switch (target) {
971 case CLK_AVAIL: 974 case CLK_AVAIL:
@@ -974,8 +977,6 @@ static int brcmf_sdio_clkctl(struct brcmf_sdio *bus, uint target, bool pendok)
974 brcmf_sdio_sdclk(bus, true); 977 brcmf_sdio_sdclk(bus, true);
975 /* Now request HT Avail on the backplane */ 978 /* Now request HT Avail on the backplane */
976 brcmf_sdio_htclk(bus, true, pendok); 979 brcmf_sdio_htclk(bus, true, pendok);
977 brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS);
978 bus->activity = true;
979 break; 980 break;
980 981
981 case CLK_SDONLY: 982 case CLK_SDONLY:
@@ -987,7 +988,6 @@ static int brcmf_sdio_clkctl(struct brcmf_sdio *bus, uint target, bool pendok)
987 else 988 else
988 brcmf_err("request for %d -> %d\n", 989 brcmf_err("request for %d -> %d\n",
989 bus->clkstate, target); 990 bus->clkstate, target);
990 brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS);
991 break; 991 break;
992 992
993 case CLK_NONE: 993 case CLK_NONE:
@@ -996,7 +996,6 @@ static int brcmf_sdio_clkctl(struct brcmf_sdio *bus, uint target, bool pendok)
996 brcmf_sdio_htclk(bus, false, false); 996 brcmf_sdio_htclk(bus, false, false);
997 /* Now remove the SD clock */ 997 /* Now remove the SD clock */
998 brcmf_sdio_sdclk(bus, false); 998 brcmf_sdio_sdclk(bus, false);
999 brcmf_sdio_wd_timer(bus, 0);
1000 break; 999 break;
1001 } 1000 }
1002#ifdef DEBUG 1001#ifdef DEBUG
@@ -1024,17 +1023,6 @@ brcmf_sdio_bus_sleep(struct brcmf_sdio *bus, bool sleep, bool pendok)
1024 1023
1025 /* Going to sleep */ 1024 /* Going to sleep */
1026 if (sleep) { 1025 if (sleep) {
1027 /* Don't sleep if something is pending */
1028 if (atomic_read(&bus->intstatus) ||
1029 atomic_read(&bus->ipend) > 0 ||
1030 bus->ctrl_frame_stat ||
1031 (!atomic_read(&bus->fcstate) &&
1032 brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) &&
1033 data_ok(bus))) {
1034 err = -EBUSY;
1035 goto done;
1036 }
1037
1038 clkcsr = brcmf_sdiod_regrb(bus->sdiodev, 1026 clkcsr = brcmf_sdiod_regrb(bus->sdiodev,
1039 SBSDIO_FUNC1_CHIPCLKCSR, 1027 SBSDIO_FUNC1_CHIPCLKCSR,
1040 &err); 1028 &err);
@@ -1045,11 +1033,7 @@ brcmf_sdio_bus_sleep(struct brcmf_sdio *bus, bool sleep, bool pendok)
1045 SBSDIO_ALP_AVAIL_REQ, &err); 1033 SBSDIO_ALP_AVAIL_REQ, &err);
1046 } 1034 }
1047 err = brcmf_sdio_kso_control(bus, false); 1035 err = brcmf_sdio_kso_control(bus, false);
1048 /* disable watchdog */
1049 if (!err)
1050 brcmf_sdio_wd_timer(bus, 0);
1051 } else { 1036 } else {
1052 bus->idlecount = 0;
1053 err = brcmf_sdio_kso_control(bus, true); 1037 err = brcmf_sdio_kso_control(bus, true);
1054 } 1038 }
1055 if (err) { 1039 if (err) {
@@ -1066,6 +1050,7 @@ end:
1066 brcmf_sdio_clkctl(bus, CLK_NONE, pendok); 1050 brcmf_sdio_clkctl(bus, CLK_NONE, pendok);
1067 } else { 1051 } else {
1068 brcmf_sdio_clkctl(bus, CLK_AVAIL, pendok); 1052 brcmf_sdio_clkctl(bus, CLK_AVAIL, pendok);
1053 brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS);
1069 } 1054 }
1070 bus->sleeping = sleep; 1055 bus->sleeping = sleep;
1071 brcmf_dbg(SDIO, "new state %s\n", 1056 brcmf_dbg(SDIO, "new state %s\n",
@@ -1085,44 +1070,47 @@ static inline bool brcmf_sdio_valid_shared_address(u32 addr)
1085static int brcmf_sdio_readshared(struct brcmf_sdio *bus, 1070static int brcmf_sdio_readshared(struct brcmf_sdio *bus,
1086 struct sdpcm_shared *sh) 1071 struct sdpcm_shared *sh)
1087{ 1072{
1088 u32 addr; 1073 u32 addr = 0;
1089 int rv; 1074 int rv;
1090 u32 shaddr = 0; 1075 u32 shaddr = 0;
1091 struct sdpcm_shared_le sh_le; 1076 struct sdpcm_shared_le sh_le;
1092 __le32 addr_le; 1077 __le32 addr_le;
1093 1078
1094 shaddr = bus->ci->rambase + bus->ramsize - 4; 1079 sdio_claim_host(bus->sdiodev->func[1]);
1080 brcmf_sdio_bus_sleep(bus, false, false);
1095 1081
1096 /* 1082 /*
1097 * Read last word in socram to determine 1083 * Read last word in socram to determine
1098 * address of sdpcm_shared structure 1084 * address of sdpcm_shared structure
1099 */ 1085 */
1100 sdio_claim_host(bus->sdiodev->func[1]); 1086 shaddr = bus->ci->rambase + bus->ci->ramsize - 4;
1101 brcmf_sdio_bus_sleep(bus, false, false); 1087 if (!bus->ci->rambase && brcmf_chip_sr_capable(bus->ci))
1102 rv = brcmf_sdiod_ramrw(bus->sdiodev, false, shaddr, (u8 *)&addr_le, 4); 1088 shaddr -= bus->ci->srsize;
1103 sdio_release_host(bus->sdiodev->func[1]); 1089 rv = brcmf_sdiod_ramrw(bus->sdiodev, false, shaddr,
1090 (u8 *)&addr_le, 4);
1104 if (rv < 0) 1091 if (rv < 0)
1105 return rv; 1092 goto fail;
1106
1107 addr = le32_to_cpu(addr_le);
1108
1109 brcmf_dbg(SDIO, "sdpcm_shared address 0x%08X\n", addr);
1110 1093
1111 /* 1094 /*
1112 * Check if addr is valid. 1095 * Check if addr is valid.
1113 * NVRAM length at the end of memory should have been overwritten. 1096 * NVRAM length at the end of memory should have been overwritten.
1114 */ 1097 */
1098 addr = le32_to_cpu(addr_le);
1115 if (!brcmf_sdio_valid_shared_address(addr)) { 1099 if (!brcmf_sdio_valid_shared_address(addr)) {
1116 brcmf_err("invalid sdpcm_shared address 0x%08X\n", 1100 brcmf_err("invalid sdpcm_shared address 0x%08X\n", addr);
1117 addr); 1101 rv = -EINVAL;
1118 return -EINVAL; 1102 goto fail;
1119 } 1103 }
1120 1104
1105 brcmf_dbg(INFO, "sdpcm_shared address 0x%08X\n", addr);
1106
1121 /* Read hndrte_shared structure */ 1107 /* Read hndrte_shared structure */
1122 rv = brcmf_sdiod_ramrw(bus->sdiodev, false, addr, (u8 *)&sh_le, 1108 rv = brcmf_sdiod_ramrw(bus->sdiodev, false, addr, (u8 *)&sh_le,
1123 sizeof(struct sdpcm_shared_le)); 1109 sizeof(struct sdpcm_shared_le));
1124 if (rv < 0) 1110 if (rv < 0)
1125 return rv; 1111 goto fail;
1112
1113 sdio_release_host(bus->sdiodev->func[1]);
1126 1114
1127 /* Endianness */ 1115 /* Endianness */
1128 sh->flags = le32_to_cpu(sh_le.flags); 1116 sh->flags = le32_to_cpu(sh_le.flags);
@@ -1139,8 +1127,13 @@ static int brcmf_sdio_readshared(struct brcmf_sdio *bus,
1139 sh->flags & SDPCM_SHARED_VERSION_MASK); 1127 sh->flags & SDPCM_SHARED_VERSION_MASK);
1140 return -EPROTO; 1128 return -EPROTO;
1141 } 1129 }
1142
1143 return 0; 1130 return 0;
1131
1132fail:
1133 brcmf_err("unable to obtain sdpcm_shared info: rv=%d (addr=0x%x)\n",
1134 rv, addr);
1135 sdio_release_host(bus->sdiodev->func[1]);
1136 return rv;
1144} 1137}
1145 1138
1146static void brcmf_sdio_get_console_addr(struct brcmf_sdio *bus) 1139static void brcmf_sdio_get_console_addr(struct brcmf_sdio *bus)
@@ -2721,11 +2714,14 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
2721 if (bus->ctrl_frame_stat && (bus->clkstate == CLK_AVAIL) && 2714 if (bus->ctrl_frame_stat && (bus->clkstate == CLK_AVAIL) &&
2722 data_ok(bus)) { 2715 data_ok(bus)) {
2723 sdio_claim_host(bus->sdiodev->func[1]); 2716 sdio_claim_host(bus->sdiodev->func[1]);
2724 err = brcmf_sdio_tx_ctrlframe(bus, bus->ctrl_frame_buf, 2717 if (bus->ctrl_frame_stat) {
2725 bus->ctrl_frame_len); 2718 err = brcmf_sdio_tx_ctrlframe(bus, bus->ctrl_frame_buf,
2719 bus->ctrl_frame_len);
2720 bus->ctrl_frame_err = err;
2721 wmb();
2722 bus->ctrl_frame_stat = false;
2723 }
2726 sdio_release_host(bus->sdiodev->func[1]); 2724 sdio_release_host(bus->sdiodev->func[1]);
2727 bus->ctrl_frame_err = err;
2728 bus->ctrl_frame_stat = false;
2729 brcmf_sdio_wait_event_wakeup(bus); 2725 brcmf_sdio_wait_event_wakeup(bus);
2730 } 2726 }
2731 /* Send queued frames (limit 1 if rx may still be pending) */ 2727 /* Send queued frames (limit 1 if rx may still be pending) */
@@ -2740,12 +2736,22 @@ static void brcmf_sdio_dpc(struct brcmf_sdio *bus)
2740 if ((bus->sdiodev->state != BRCMF_SDIOD_DATA) || (err != 0)) { 2736 if ((bus->sdiodev->state != BRCMF_SDIOD_DATA) || (err != 0)) {
2741 brcmf_err("failed backplane access over SDIO, halting operation\n"); 2737 brcmf_err("failed backplane access over SDIO, halting operation\n");
2742 atomic_set(&bus->intstatus, 0); 2738 atomic_set(&bus->intstatus, 0);
2739 if (bus->ctrl_frame_stat) {
2740 sdio_claim_host(bus->sdiodev->func[1]);
2741 if (bus->ctrl_frame_stat) {
2742 bus->ctrl_frame_err = -ENODEV;
2743 wmb();
2744 bus->ctrl_frame_stat = false;
2745 brcmf_sdio_wait_event_wakeup(bus);
2746 }
2747 sdio_release_host(bus->sdiodev->func[1]);
2748 }
2743 } else if (atomic_read(&bus->intstatus) || 2749 } else if (atomic_read(&bus->intstatus) ||
2744 atomic_read(&bus->ipend) > 0 || 2750 atomic_read(&bus->ipend) > 0 ||
2745 (!atomic_read(&bus->fcstate) && 2751 (!atomic_read(&bus->fcstate) &&
2746 brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) && 2752 brcmu_pktq_mlen(&bus->txq, ~bus->flowcontrol) &&
2747 data_ok(bus))) { 2753 data_ok(bus))) {
2748 atomic_inc(&bus->dpc_tskcnt); 2754 bus->dpc_triggered = true;
2749 } 2755 }
2750} 2756}
2751 2757
@@ -2941,20 +2947,27 @@ brcmf_sdio_bus_txctl(struct device *dev, unsigned char *msg, uint msglen)
2941 /* Send from dpc */ 2947 /* Send from dpc */
2942 bus->ctrl_frame_buf = msg; 2948 bus->ctrl_frame_buf = msg;
2943 bus->ctrl_frame_len = msglen; 2949 bus->ctrl_frame_len = msglen;
2950 wmb();
2944 bus->ctrl_frame_stat = true; 2951 bus->ctrl_frame_stat = true;
2945 2952
2946 brcmf_sdio_trigger_dpc(bus); 2953 brcmf_sdio_trigger_dpc(bus);
2947 wait_event_interruptible_timeout(bus->ctrl_wait, !bus->ctrl_frame_stat, 2954 wait_event_interruptible_timeout(bus->ctrl_wait, !bus->ctrl_frame_stat,
2948 msecs_to_jiffies(CTL_DONE_TIMEOUT)); 2955 msecs_to_jiffies(CTL_DONE_TIMEOUT));
2949 2956 ret = 0;
2950 if (!bus->ctrl_frame_stat) { 2957 if (bus->ctrl_frame_stat) {
2958 sdio_claim_host(bus->sdiodev->func[1]);
2959 if (bus->ctrl_frame_stat) {
2960 brcmf_dbg(SDIO, "ctrl_frame timeout\n");
2961 bus->ctrl_frame_stat = false;
2962 ret = -ETIMEDOUT;
2963 }
2964 sdio_release_host(bus->sdiodev->func[1]);
2965 }
2966 if (!ret) {
2951 brcmf_dbg(SDIO, "ctrl_frame complete, err=%d\n", 2967 brcmf_dbg(SDIO, "ctrl_frame complete, err=%d\n",
2952 bus->ctrl_frame_err); 2968 bus->ctrl_frame_err);
2969 rmb();
2953 ret = bus->ctrl_frame_err; 2970 ret = bus->ctrl_frame_err;
2954 } else {
2955 brcmf_dbg(SDIO, "ctrl_frame timeout\n");
2956 bus->ctrl_frame_stat = false;
2957 ret = -ETIMEDOUT;
2958 } 2971 }
2959 2972
2960 if (ret) 2973 if (ret)
@@ -3358,9 +3371,6 @@ static int brcmf_sdio_download_firmware(struct brcmf_sdio *bus,
3358 sdio_claim_host(bus->sdiodev->func[1]); 3371 sdio_claim_host(bus->sdiodev->func[1]);
3359 brcmf_sdio_clkctl(bus, CLK_AVAIL, false); 3372 brcmf_sdio_clkctl(bus, CLK_AVAIL, false);
3360 3373
3361 /* Keep arm in reset */
3362 brcmf_chip_enter_download(bus->ci);
3363
3364 rstvec = get_unaligned_le32(fw->data); 3374 rstvec = get_unaligned_le32(fw->data);
3365 brcmf_dbg(SDIO, "firmware rstvec: %x\n", rstvec); 3375 brcmf_dbg(SDIO, "firmware rstvec: %x\n", rstvec);
3366 3376
@@ -3380,7 +3390,7 @@ static int brcmf_sdio_download_firmware(struct brcmf_sdio *bus,
3380 } 3390 }
3381 3391
3382 /* Take arm out of reset */ 3392 /* Take arm out of reset */
3383 if (!brcmf_chip_exit_download(bus->ci, rstvec)) { 3393 if (!brcmf_chip_set_active(bus->ci, rstvec)) {
3384 brcmf_err("error getting out of ARM core reset\n"); 3394 brcmf_err("error getting out of ARM core reset\n");
3385 goto err; 3395 goto err;
3386 } 3396 }
@@ -3525,8 +3535,8 @@ done:
3525 3535
3526void brcmf_sdio_trigger_dpc(struct brcmf_sdio *bus) 3536void brcmf_sdio_trigger_dpc(struct brcmf_sdio *bus)
3527{ 3537{
3528 if (atomic_read(&bus->dpc_tskcnt) == 0) { 3538 if (!bus->dpc_triggered) {
3529 atomic_inc(&bus->dpc_tskcnt); 3539 bus->dpc_triggered = true;
3530 queue_work(bus->brcmf_wq, &bus->datawork); 3540 queue_work(bus->brcmf_wq, &bus->datawork);
3531 } 3541 }
3532} 3542}
@@ -3557,11 +3567,11 @@ void brcmf_sdio_isr(struct brcmf_sdio *bus)
3557 if (!bus->intr) 3567 if (!bus->intr)
3558 brcmf_err("isr w/o interrupt configured!\n"); 3568 brcmf_err("isr w/o interrupt configured!\n");
3559 3569
3560 atomic_inc(&bus->dpc_tskcnt); 3570 bus->dpc_triggered = true;
3561 queue_work(bus->brcmf_wq, &bus->datawork); 3571 queue_work(bus->brcmf_wq, &bus->datawork);
3562} 3572}
3563 3573
3564static bool brcmf_sdio_bus_watchdog(struct brcmf_sdio *bus) 3574static void brcmf_sdio_bus_watchdog(struct brcmf_sdio *bus)
3565{ 3575{
3566 brcmf_dbg(TIMER, "Enter\n"); 3576 brcmf_dbg(TIMER, "Enter\n");
3567 3577
@@ -3577,7 +3587,7 @@ static bool brcmf_sdio_bus_watchdog(struct brcmf_sdio *bus)
3577 if (!bus->intr || 3587 if (!bus->intr ||
3578 (bus->sdcnt.intrcount == bus->sdcnt.lastintrs)) { 3588 (bus->sdcnt.intrcount == bus->sdcnt.lastintrs)) {
3579 3589
3580 if (atomic_read(&bus->dpc_tskcnt) == 0) { 3590 if (!bus->dpc_triggered) {
3581 u8 devpend; 3591 u8 devpend;
3582 3592
3583 sdio_claim_host(bus->sdiodev->func[1]); 3593 sdio_claim_host(bus->sdiodev->func[1]);
@@ -3595,7 +3605,7 @@ static bool brcmf_sdio_bus_watchdog(struct brcmf_sdio *bus)
3595 bus->sdcnt.pollcnt++; 3605 bus->sdcnt.pollcnt++;
3596 atomic_set(&bus->ipend, 1); 3606 atomic_set(&bus->ipend, 1);
3597 3607
3598 atomic_inc(&bus->dpc_tskcnt); 3608 bus->dpc_triggered = true;
3599 queue_work(bus->brcmf_wq, &bus->datawork); 3609 queue_work(bus->brcmf_wq, &bus->datawork);
3600 } 3610 }
3601 } 3611 }
@@ -3622,22 +3632,25 @@ static bool brcmf_sdio_bus_watchdog(struct brcmf_sdio *bus)
3622#endif /* DEBUG */ 3632#endif /* DEBUG */
3623 3633
3624 /* On idle timeout clear activity flag and/or turn off clock */ 3634 /* On idle timeout clear activity flag and/or turn off clock */
3625 if ((bus->idletime > 0) && (bus->clkstate == CLK_AVAIL)) { 3635 if (!bus->dpc_triggered) {
3626 if (++bus->idlecount >= bus->idletime) { 3636 rmb();
3627 bus->idlecount = 0; 3637 if ((!bus->dpc_running) && (bus->idletime > 0) &&
3628 if (bus->activity) { 3638 (bus->clkstate == CLK_AVAIL)) {
3629 bus->activity = false; 3639 bus->idlecount++;
3630 brcmf_sdio_wd_timer(bus, BRCMF_WD_POLL_MS); 3640 if (bus->idlecount > bus->idletime) {
3631 } else {
3632 brcmf_dbg(SDIO, "idle\n"); 3641 brcmf_dbg(SDIO, "idle\n");
3633 sdio_claim_host(bus->sdiodev->func[1]); 3642 sdio_claim_host(bus->sdiodev->func[1]);
3643 brcmf_sdio_wd_timer(bus, 0);
3644 bus->idlecount = 0;
3634 brcmf_sdio_bus_sleep(bus, true, false); 3645 brcmf_sdio_bus_sleep(bus, true, false);
3635 sdio_release_host(bus->sdiodev->func[1]); 3646 sdio_release_host(bus->sdiodev->func[1]);
3636 } 3647 }
3648 } else {
3649 bus->idlecount = 0;
3637 } 3650 }
3651 } else {
3652 bus->idlecount = 0;
3638 } 3653 }
3639
3640 return (atomic_read(&bus->ipend) > 0);
3641} 3654}
3642 3655
3643static void brcmf_sdio_dataworker(struct work_struct *work) 3656static void brcmf_sdio_dataworker(struct work_struct *work)
@@ -3645,10 +3658,14 @@ static void brcmf_sdio_dataworker(struct work_struct *work)
3645 struct brcmf_sdio *bus = container_of(work, struct brcmf_sdio, 3658 struct brcmf_sdio *bus = container_of(work, struct brcmf_sdio,
3646 datawork); 3659 datawork);
3647 3660
3648 while (atomic_read(&bus->dpc_tskcnt)) { 3661 bus->dpc_running = true;
3649 atomic_set(&bus->dpc_tskcnt, 0); 3662 wmb();
3663 while (ACCESS_ONCE(bus->dpc_triggered)) {
3664 bus->dpc_triggered = false;
3650 brcmf_sdio_dpc(bus); 3665 brcmf_sdio_dpc(bus);
3666 bus->idlecount = 0;
3651 } 3667 }
3668 bus->dpc_running = false;
3652 if (brcmf_sdiod_freezing(bus->sdiodev)) { 3669 if (brcmf_sdiod_freezing(bus->sdiodev)) {
3653 brcmf_sdiod_change_state(bus->sdiodev, BRCMF_SDIOD_DOWN); 3670 brcmf_sdiod_change_state(bus->sdiodev, BRCMF_SDIOD_DOWN);
3654 brcmf_sdiod_try_freeze(bus->sdiodev); 3671 brcmf_sdiod_try_freeze(bus->sdiodev);
@@ -3771,8 +3788,8 @@ static int brcmf_sdio_buscoreprep(void *ctx)
3771 return 0; 3788 return 0;
3772} 3789}
3773 3790
3774static void brcmf_sdio_buscore_exitdl(void *ctx, struct brcmf_chip *chip, 3791static void brcmf_sdio_buscore_activate(void *ctx, struct brcmf_chip *chip,
3775 u32 rstvec) 3792 u32 rstvec)
3776{ 3793{
3777 struct brcmf_sdio_dev *sdiodev = ctx; 3794 struct brcmf_sdio_dev *sdiodev = ctx;
3778 struct brcmf_core *core; 3795 struct brcmf_core *core;
@@ -3815,7 +3832,7 @@ static void brcmf_sdio_buscore_write32(void *ctx, u32 addr, u32 val)
3815 3832
3816static const struct brcmf_buscore_ops brcmf_sdio_buscore_ops = { 3833static const struct brcmf_buscore_ops brcmf_sdio_buscore_ops = {
3817 .prepare = brcmf_sdio_buscoreprep, 3834 .prepare = brcmf_sdio_buscoreprep,
3818 .exit_dl = brcmf_sdio_buscore_exitdl, 3835 .activate = brcmf_sdio_buscore_activate,
3819 .read32 = brcmf_sdio_buscore_read32, 3836 .read32 = brcmf_sdio_buscore_read32,
3820 .write32 = brcmf_sdio_buscore_write32, 3837 .write32 = brcmf_sdio_buscore_write32,
3821}; 3838};
@@ -3869,13 +3886,6 @@ brcmf_sdio_probe_attach(struct brcmf_sdio *bus)
3869 drivestrength = DEFAULT_SDIO_DRIVE_STRENGTH; 3886 drivestrength = DEFAULT_SDIO_DRIVE_STRENGTH;
3870 brcmf_sdio_drivestrengthinit(bus->sdiodev, bus->ci, drivestrength); 3887 brcmf_sdio_drivestrengthinit(bus->sdiodev, bus->ci, drivestrength);
3871 3888
3872 /* Get info on the SOCRAM cores... */
3873 bus->ramsize = bus->ci->ramsize;
3874 if (!(bus->ramsize)) {
3875 brcmf_err("failed to find SOCRAM memory!\n");
3876 goto fail;
3877 }
3878
3879 /* Set card control so an SDIO card reset does a WLAN backplane reset */ 3889 /* Set card control so an SDIO card reset does a WLAN backplane reset */
3880 reg_val = brcmf_sdiod_regrb(bus->sdiodev, 3890 reg_val = brcmf_sdiod_regrb(bus->sdiodev,
3881 SDIO_CCCR_BRCM_CARDCTRL, &err); 3891 SDIO_CCCR_BRCM_CARDCTRL, &err);
@@ -4148,7 +4158,8 @@ struct brcmf_sdio *brcmf_sdio_probe(struct brcmf_sdio_dev *sdiodev)
4148 bus->watchdog_tsk = NULL; 4158 bus->watchdog_tsk = NULL;
4149 } 4159 }
4150 /* Initialize DPC thread */ 4160 /* Initialize DPC thread */
4151 atomic_set(&bus->dpc_tskcnt, 0); 4161 bus->dpc_triggered = false;
4162 bus->dpc_running = false;
4152 4163
4153 /* Assign bus interface call back */ 4164 /* Assign bus interface call back */
4154 bus->sdiodev->bus_if->dev = bus->sdiodev->dev; 4165 bus->sdiodev->bus_if->dev = bus->sdiodev->dev;
@@ -4243,14 +4254,14 @@ void brcmf_sdio_remove(struct brcmf_sdio *bus)
4243 if (bus->ci) { 4254 if (bus->ci) {
4244 if (bus->sdiodev->state != BRCMF_SDIOD_NOMEDIUM) { 4255 if (bus->sdiodev->state != BRCMF_SDIOD_NOMEDIUM) {
4245 sdio_claim_host(bus->sdiodev->func[1]); 4256 sdio_claim_host(bus->sdiodev->func[1]);
4257 brcmf_sdio_wd_timer(bus, 0);
4246 brcmf_sdio_clkctl(bus, CLK_AVAIL, false); 4258 brcmf_sdio_clkctl(bus, CLK_AVAIL, false);
4247 /* Leave the device in state where it is 4259 /* Leave the device in state where it is
4248 * 'quiet'. This is done by putting it in 4260 * 'passive'. This is done by resetting all
4249 * download_state which essentially resets 4261 * necessary cores.
4250 * all necessary cores.
4251 */ 4262 */
4252 msleep(20); 4263 msleep(20);
4253 brcmf_chip_enter_download(bus->ci); 4264 brcmf_chip_set_passive(bus->ci);
4254 brcmf_sdio_clkctl(bus, CLK_NONE, false); 4265 brcmf_sdio_clkctl(bus, CLK_NONE, false);
4255 sdio_release_host(bus->sdiodev->func[1]); 4266 sdio_release_host(bus->sdiodev->func[1]);
4256 } 4267 }
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/main.c b/drivers/net/wireless/brcm80211/brcmsmac/main.c
index c84af1dfc88f..369527e27689 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/main.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/main.c
@@ -4959,7 +4959,7 @@ static int brcms_b_up_prep(struct brcms_hardware *wlc_hw)
4959 * Configure pci/pcmcia here instead of in brcms_c_attach() 4959 * Configure pci/pcmcia here instead of in brcms_c_attach()
4960 * to allow mfg hotswap: down, hotswap (chip power cycle), up. 4960 * to allow mfg hotswap: down, hotswap (chip power cycle), up.
4961 */ 4961 */
4962 bcma_core_pci_irq_ctl(wlc_hw->d11core->bus, wlc_hw->d11core, 4962 bcma_host_pci_irq_ctl(wlc_hw->d11core->bus, wlc_hw->d11core,
4963 true); 4963 true);
4964 4964
4965 /* 4965 /*
diff --git a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
index 2124a17d0bfd..4efdd51af9c8 100644
--- a/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
+++ b/drivers/net/wireless/brcm80211/include/brcm_hw_ids.h
@@ -37,6 +37,8 @@
37#define BRCM_CC_43362_CHIP_ID 43362 37#define BRCM_CC_43362_CHIP_ID 43362
38#define BRCM_CC_4335_CHIP_ID 0x4335 38#define BRCM_CC_4335_CHIP_ID 0x4335
39#define BRCM_CC_4339_CHIP_ID 0x4339 39#define BRCM_CC_4339_CHIP_ID 0x4339
40#define BRCM_CC_43430_CHIP_ID 43430
41#define BRCM_CC_4345_CHIP_ID 0x4345
40#define BRCM_CC_4354_CHIP_ID 0x4354 42#define BRCM_CC_4354_CHIP_ID 0x4354
41#define BRCM_CC_4356_CHIP_ID 0x4356 43#define BRCM_CC_4356_CHIP_ID 0x4356
42#define BRCM_CC_43566_CHIP_ID 43566 44#define BRCM_CC_43566_CHIP_ID 43566
diff --git a/drivers/net/wireless/brcm80211/include/chipcommon.h b/drivers/net/wireless/brcm80211/include/chipcommon.h
index d242333b7559..e1fd499930a0 100644
--- a/drivers/net/wireless/brcm80211/include/chipcommon.h
+++ b/drivers/net/wireless/brcm80211/include/chipcommon.h
@@ -183,7 +183,14 @@ struct chipcregs {
183 u8 uart1lsr; 183 u8 uart1lsr;
184 u8 uart1msr; 184 u8 uart1msr;
185 u8 uart1scratch; 185 u8 uart1scratch;
186 u32 PAD[126]; 186 u32 PAD[62];
187
188 /* save/restore, corerev >= 48 */
189 u32 sr_capability; /* 0x500 */
190 u32 sr_control0; /* 0x504 */
191 u32 sr_control1; /* 0x508 */
192 u32 gpio_control; /* 0x50C */
193 u32 PAD[60];
187 194
188 /* PMU registers (corerev >= 20) */ 195 /* PMU registers (corerev >= 20) */
189 u32 pmucontrol; /* 0x600 */ 196 u32 pmucontrol; /* 0x600 */
diff --git a/drivers/net/wireless/cw1200/cw1200_spi.c b/drivers/net/wireless/cw1200/cw1200_spi.c
index 964b64ab7fe3..7603546d2de3 100644
--- a/drivers/net/wireless/cw1200/cw1200_spi.c
+++ b/drivers/net/wireless/cw1200/cw1200_spi.c
@@ -447,7 +447,7 @@ static int cw1200_spi_disconnect(struct spi_device *func)
447} 447}
448 448
449#ifdef CONFIG_PM 449#ifdef CONFIG_PM
450static int cw1200_spi_suspend(struct device *dev, pm_message_t state) 450static int cw1200_spi_suspend(struct device *dev)
451{ 451{
452 struct hwbus_priv *self = spi_get_drvdata(to_spi_device(dev)); 452 struct hwbus_priv *self = spi_get_drvdata(to_spi_device(dev));
453 453
@@ -458,10 +458,8 @@ static int cw1200_spi_suspend(struct device *dev, pm_message_t state)
458 return 0; 458 return 0;
459} 459}
460 460
461static int cw1200_spi_resume(struct device *dev) 461static SIMPLE_DEV_PM_OPS(cw1200_pm_ops, cw1200_spi_suspend, NULL);
462{ 462
463 return 0;
464}
465#endif 463#endif
466 464
467static struct spi_driver spi_driver = { 465static struct spi_driver spi_driver = {
@@ -472,8 +470,7 @@ static struct spi_driver spi_driver = {
472 .bus = &spi_bus_type, 470 .bus = &spi_bus_type,
473 .owner = THIS_MODULE, 471 .owner = THIS_MODULE,
474#ifdef CONFIG_PM 472#ifdef CONFIG_PM
475 .suspend = cw1200_spi_suspend, 473 .pm = &cw1200_pm_ops,
476 .resume = cw1200_spi_resume,
477#endif 474#endif
478 }, 475 },
479}; 476};
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
index 5707ba5ce23f..5abd62ed8cb4 100644
--- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
@@ -1114,16 +1114,17 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
1114 scd_queues &= ~(BIT(IWL_IPAN_CMD_QUEUE_NUM) | 1114 scd_queues &= ~(BIT(IWL_IPAN_CMD_QUEUE_NUM) |
1115 BIT(IWL_DEFAULT_CMD_QUEUE_NUM)); 1115 BIT(IWL_DEFAULT_CMD_QUEUE_NUM));
1116 1116
1117 if (vif) 1117 if (drop) {
1118 scd_queues &= ~BIT(vif->hw_queue[IEEE80211_AC_VO]); 1118 IWL_DEBUG_TX_QUEUES(priv, "Flushing SCD queues: 0x%x\n",
1119 1119 scd_queues);
1120 IWL_DEBUG_TX_QUEUES(priv, "Flushing SCD queues: 0x%x\n", scd_queues); 1120 if (iwlagn_txfifo_flush(priv, scd_queues)) {
1121 if (iwlagn_txfifo_flush(priv, scd_queues)) { 1121 IWL_ERR(priv, "flush request fail\n");
1122 IWL_ERR(priv, "flush request fail\n"); 1122 goto done;
1123 goto done; 1123 }
1124 } 1124 }
1125
1125 IWL_DEBUG_TX_QUEUES(priv, "wait transmit/flush all frames\n"); 1126 IWL_DEBUG_TX_QUEUES(priv, "wait transmit/flush all frames\n");
1126 iwl_trans_wait_tx_queue_empty(priv->trans, 0xffffffff); 1127 iwl_trans_wait_tx_queue_empty(priv->trans, scd_queues);
1127done: 1128done:
1128 mutex_unlock(&priv->mutex); 1129 mutex_unlock(&priv->mutex);
1129 IWL_DEBUG_MAC80211(priv, "leave\n"); 1130 IWL_DEBUG_MAC80211(priv, "leave\n");
diff --git a/drivers/net/wireless/iwlwifi/dvm/rs.c b/drivers/net/wireless/iwlwifi/dvm/rs.c
index 32b78a66536d..3bd7c86e90d9 100644
--- a/drivers/net/wireless/iwlwifi/dvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/dvm/rs.c
@@ -3153,12 +3153,13 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
3153 desc += sprintf(buff+desc, "lq type %s\n", 3153 desc += sprintf(buff+desc, "lq type %s\n",
3154 (is_legacy(tbl->lq_type)) ? "legacy" : "HT"); 3154 (is_legacy(tbl->lq_type)) ? "legacy" : "HT");
3155 if (is_Ht(tbl->lq_type)) { 3155 if (is_Ht(tbl->lq_type)) {
3156 desc += sprintf(buff+desc, " %s", 3156 desc += sprintf(buff + desc, " %s",
3157 (is_siso(tbl->lq_type)) ? "SISO" : 3157 (is_siso(tbl->lq_type)) ? "SISO" :
3158 ((is_mimo2(tbl->lq_type)) ? "MIMO2" : "MIMO3")); 3158 ((is_mimo2(tbl->lq_type)) ? "MIMO2" : "MIMO3"));
3159 desc += sprintf(buff+desc, " %s", 3159 desc += sprintf(buff + desc, " %s",
3160 (tbl->is_ht40) ? "40MHz" : "20MHz"); 3160 (tbl->is_ht40) ? "40MHz" : "20MHz");
3161 desc += sprintf(buff+desc, " %s %s %s\n", (tbl->is_SGI) ? "SGI" : "", 3161 desc += sprintf(buff + desc, " %s %s %s\n",
3162 (tbl->is_SGI) ? "SGI" : "",
3162 (lq_sta->is_green) ? "GF enabled" : "", 3163 (lq_sta->is_green) ? "GF enabled" : "",
3163 (lq_sta->is_agg) ? "AGG on" : ""); 3164 (lq_sta->is_agg) ? "AGG on" : "");
3164 } 3165 }
diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c
index 1e40a12de077..275df12a6045 100644
--- a/drivers/net/wireless/iwlwifi/dvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/dvm/tx.c
@@ -189,9 +189,9 @@ static void iwlagn_tx_cmd_build_rate(struct iwl_priv *priv,
189 rate_flags |= RATE_MCS_CCK_MSK; 189 rate_flags |= RATE_MCS_CCK_MSK;
190 190
191 /* Set up antennas */ 191 /* Set up antennas */
192 if (priv->lib->bt_params && 192 if (priv->lib->bt_params &&
193 priv->lib->bt_params->advanced_bt_coexist && 193 priv->lib->bt_params->advanced_bt_coexist &&
194 priv->bt_full_concurrent) { 194 priv->bt_full_concurrent) {
195 /* operated as 1x1 in full concurrency mode */ 195 /* operated as 1x1 in full concurrency mode */
196 priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant, 196 priv->mgmt_tx_ant = iwl_toggle_tx_ant(priv, priv->mgmt_tx_ant,
197 first_antenna(priv->nvm_data->valid_tx_ant)); 197 first_antenna(priv->nvm_data->valid_tx_ant));
diff --git a/drivers/net/wireless/iwlwifi/iwl-7000.c b/drivers/net/wireless/iwlwifi/iwl-7000.c
index 0597a9cfd2f6..36e786f0387b 100644
--- a/drivers/net/wireless/iwlwifi/iwl-7000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-7000.c
@@ -69,12 +69,12 @@
69#include "iwl-agn-hw.h" 69#include "iwl-agn-hw.h"
70 70
71/* Highest firmware API version supported */ 71/* Highest firmware API version supported */
72#define IWL7260_UCODE_API_MAX 12 72#define IWL7260_UCODE_API_MAX 13
73#define IWL3160_UCODE_API_MAX 12 73#define IWL3160_UCODE_API_MAX 13
74 74
75/* Oldest version we won't warn about */ 75/* Oldest version we won't warn about */
76#define IWL7260_UCODE_API_OK 10 76#define IWL7260_UCODE_API_OK 12
77#define IWL3160_UCODE_API_OK 10 77#define IWL3160_UCODE_API_OK 12
78 78
79/* Lowest firmware API version supported */ 79/* Lowest firmware API version supported */
80#define IWL7260_UCODE_API_MIN 10 80#define IWL7260_UCODE_API_MIN 10
diff --git a/drivers/net/wireless/iwlwifi/iwl-8000.c b/drivers/net/wireless/iwlwifi/iwl-8000.c
index d8dfa6da6307..9c396a42aec8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-8000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-8000.c
@@ -69,10 +69,10 @@
69#include "iwl-agn-hw.h" 69#include "iwl-agn-hw.h"
70 70
71/* Highest firmware API version supported */ 71/* Highest firmware API version supported */
72#define IWL8000_UCODE_API_MAX 12 72#define IWL8000_UCODE_API_MAX 13
73 73
74/* Oldest version we won't warn about */ 74/* Oldest version we won't warn about */
75#define IWL8000_UCODE_API_OK 10 75#define IWL8000_UCODE_API_OK 12
76 76
77/* Lowest firmware API version supported */ 77/* Lowest firmware API version supported */
78#define IWL8000_UCODE_API_MIN 10 78#define IWL8000_UCODE_API_MIN 10
diff --git a/drivers/net/wireless/iwlwifi/iwl-debug.h b/drivers/net/wireless/iwlwifi/iwl-debug.h
index 684254553558..9bb36d79c2bd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-debug.h
+++ b/drivers/net/wireless/iwlwifi/iwl-debug.h
@@ -157,6 +157,7 @@ do { \
157/* 0x0000F000 - 0x00001000 */ 157/* 0x0000F000 - 0x00001000 */
158#define IWL_DL_ASSOC 0x00001000 158#define IWL_DL_ASSOC 0x00001000
159#define IWL_DL_DROP 0x00002000 159#define IWL_DL_DROP 0x00002000
160#define IWL_DL_LAR 0x00004000
160#define IWL_DL_COEX 0x00008000 161#define IWL_DL_COEX 0x00008000
161/* 0x000F0000 - 0x00010000 */ 162/* 0x000F0000 - 0x00010000 */
162#define IWL_DL_FW 0x00010000 163#define IWL_DL_FW 0x00010000
@@ -219,5 +220,6 @@ do { \
219#define IWL_DEBUG_POWER(p, f, a...) IWL_DEBUG(p, IWL_DL_POWER, f, ## a) 220#define IWL_DEBUG_POWER(p, f, a...) IWL_DEBUG(p, IWL_DL_POWER, f, ## a)
220#define IWL_DEBUG_11H(p, f, a...) IWL_DEBUG(p, IWL_DL_11H, f, ## a) 221#define IWL_DEBUG_11H(p, f, a...) IWL_DEBUG(p, IWL_DL_11H, f, ## a)
221#define IWL_DEBUG_RPM(p, f, a...) IWL_DEBUG(p, IWL_DL_RPM, f, ## a) 222#define IWL_DEBUG_RPM(p, f, a...) IWL_DEBUG(p, IWL_DL_RPM, f, ## a)
223#define IWL_DEBUG_LAR(p, f, a...) IWL_DEBUG(p, IWL_DL_LAR, f, ## a)
222 224
223#endif 225#endif
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c
index 141331d41abf..66ca000f0da1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.c
@@ -1014,34 +1014,34 @@ static int validate_sec_sizes(struct iwl_drv *drv,
1014 1014
1015 /* Verify that uCode images will fit in card's SRAM. */ 1015 /* Verify that uCode images will fit in card's SRAM. */
1016 if (get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST) > 1016 if (get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST) >
1017 cfg->max_inst_size) { 1017 cfg->max_inst_size) {
1018 IWL_ERR(drv, "uCode instr len %Zd too large to fit in\n", 1018 IWL_ERR(drv, "uCode instr len %Zd too large to fit in\n",
1019 get_sec_size(pieces, IWL_UCODE_REGULAR, 1019 get_sec_size(pieces, IWL_UCODE_REGULAR,
1020 IWL_UCODE_SECTION_INST)); 1020 IWL_UCODE_SECTION_INST));
1021 return -1; 1021 return -1;
1022 } 1022 }
1023 1023
1024 if (get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA) > 1024 if (get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA) >
1025 cfg->max_data_size) { 1025 cfg->max_data_size) {
1026 IWL_ERR(drv, "uCode data len %Zd too large to fit in\n", 1026 IWL_ERR(drv, "uCode data len %Zd too large to fit in\n",
1027 get_sec_size(pieces, IWL_UCODE_REGULAR, 1027 get_sec_size(pieces, IWL_UCODE_REGULAR,
1028 IWL_UCODE_SECTION_DATA)); 1028 IWL_UCODE_SECTION_DATA));
1029 return -1; 1029 return -1;
1030 } 1030 }
1031 1031
1032 if (get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST) > 1032 if (get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST) >
1033 cfg->max_inst_size) { 1033 cfg->max_inst_size) {
1034 IWL_ERR(drv, "uCode init instr len %Zd too large to fit in\n", 1034 IWL_ERR(drv, "uCode init instr len %Zd too large to fit in\n",
1035 get_sec_size(pieces, IWL_UCODE_INIT, 1035 get_sec_size(pieces, IWL_UCODE_INIT,
1036 IWL_UCODE_SECTION_INST)); 1036 IWL_UCODE_SECTION_INST));
1037 return -1; 1037 return -1;
1038 } 1038 }
1039 1039
1040 if (get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA) > 1040 if (get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA) >
1041 cfg->max_data_size) { 1041 cfg->max_data_size) {
1042 IWL_ERR(drv, "uCode init data len %Zd too large to fit in\n", 1042 IWL_ERR(drv, "uCode init data len %Zd too large to fit in\n",
1043 get_sec_size(pieces, IWL_UCODE_REGULAR, 1043 get_sec_size(pieces, IWL_UCODE_REGULAR,
1044 IWL_UCODE_SECTION_DATA)); 1044 IWL_UCODE_SECTION_DATA));
1045 return -1; 1045 return -1;
1046 } 1046 }
1047 return 0; 1047 return 0;
@@ -1546,6 +1546,10 @@ module_param_named(d0i3_disable, iwlwifi_mod_params.d0i3_disable,
1546 bool, S_IRUGO); 1546 bool, S_IRUGO);
1547MODULE_PARM_DESC(d0i3_disable, "disable d0i3 functionality (default: Y)"); 1547MODULE_PARM_DESC(d0i3_disable, "disable d0i3 functionality (default: Y)");
1548 1548
1549module_param_named(lar_disable, iwlwifi_mod_params.lar_disable,
1550 bool, S_IRUGO);
1551MODULE_PARM_DESC(lar_disable, "disable LAR functionality (default: N)");
1552
1549module_param_named(uapsd_disable, iwlwifi_mod_params.uapsd_disable, 1553module_param_named(uapsd_disable, iwlwifi_mod_params.uapsd_disable,
1550 bool, S_IRUGO | S_IWUSR); 1554 bool, S_IRUGO | S_IWUSR);
1551#ifdef CONFIG_IWLWIFI_UAPSD 1555#ifdef CONFIG_IWLWIFI_UAPSD
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.h b/drivers/net/wireless/iwlwifi/iwl-drv.h
index adf522c756e6..67a3a241b331 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.h
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.h
@@ -68,7 +68,7 @@
68 68
69/* for all modules */ 69/* for all modules */
70#define DRV_NAME "iwlwifi" 70#define DRV_NAME "iwlwifi"
71#define DRV_COPYRIGHT "Copyright(c) 2003- 2014 Intel Corporation" 71#define DRV_COPYRIGHT "Copyright(c) 2003- 2015 Intel Corporation"
72#define DRV_AUTHOR "<ilw@linux.intel.com>" 72#define DRV_AUTHOR "<ilw@linux.intel.com>"
73 73
74/* radio config bits (actual values from NVM definition) */ 74/* radio config bits (actual values from NVM definition) */
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h
index f0548b8a64b0..5234a0bf11e4 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.h
@@ -94,6 +94,7 @@ struct iwl_nvm_data {
94 u32 nvm_version; 94 u32 nvm_version;
95 s8 max_tx_pwr_half_dbm; 95 s8 max_tx_pwr_half_dbm;
96 96
97 bool lar_enabled;
97 struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS]; 98 struct ieee80211_supported_band bands[IEEE80211_NUM_BANDS];
98 struct ieee80211_channel channels[]; 99 struct ieee80211_channel channels[];
99}; 100};
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw-file.h b/drivers/net/wireless/iwlwifi/iwl-fw-file.h
index 5ea381861d5d..291a3382aa3f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw-file.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw-file.h
@@ -240,10 +240,9 @@ enum iwl_ucode_tlv_flag {
240/** 240/**
241 * enum iwl_ucode_tlv_api - ucode api 241 * enum iwl_ucode_tlv_api - ucode api
242 * @IWL_UCODE_TLV_API_BT_COEX_SPLIT: new API for BT Coex 242 * @IWL_UCODE_TLV_API_BT_COEX_SPLIT: new API for BT Coex
243 * @IWL_UCODE_TLV_API_DISABLE_STA_TX: ucode supports tx_disable bit.
244 * @IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF: ucode supports disabling dummy notif.
245 * @IWL_UCODE_TLV_API_FRAGMENTED_SCAN: This ucode supports active dwell time 243 * @IWL_UCODE_TLV_API_FRAGMENTED_SCAN: This ucode supports active dwell time
246 * longer than the passive one, which is essential for fragmented scan. 244 * longer than the passive one, which is essential for fragmented scan.
245 * @IWL_UCODE_TLV_API_WIFI_MCC_UPDATE: ucode supports MCC updates with source.
247 * IWL_UCODE_TLV_API_HDC_PHASE_0: ucode supports finer configuration of LTR 246 * IWL_UCODE_TLV_API_HDC_PHASE_0: ucode supports finer configuration of LTR
248 * @IWL_UCODE_TLV_API_BASIC_DWELL: use only basic dwell time in scan command, 247 * @IWL_UCODE_TLV_API_BASIC_DWELL: use only basic dwell time in scan command,
249 * regardless of the band or the number of the probes. FW will calculate 248 * regardless of the band or the number of the probes. FW will calculate
@@ -258,9 +257,8 @@ enum iwl_ucode_tlv_flag {
258 */ 257 */
259enum iwl_ucode_tlv_api { 258enum iwl_ucode_tlv_api {
260 IWL_UCODE_TLV_API_BT_COEX_SPLIT = BIT(3), 259 IWL_UCODE_TLV_API_BT_COEX_SPLIT = BIT(3),
261 IWL_UCODE_TLV_API_DISABLE_STA_TX = BIT(5),
262 IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF = BIT(7),
263 IWL_UCODE_TLV_API_FRAGMENTED_SCAN = BIT(8), 260 IWL_UCODE_TLV_API_FRAGMENTED_SCAN = BIT(8),
261 IWL_UCODE_TLV_API_WIFI_MCC_UPDATE = BIT(9),
264 IWL_UCODE_TLV_API_HDC_PHASE_0 = BIT(10), 262 IWL_UCODE_TLV_API_HDC_PHASE_0 = BIT(10),
265 IWL_UCODE_TLV_API_BASIC_DWELL = BIT(13), 263 IWL_UCODE_TLV_API_BASIC_DWELL = BIT(13),
266 IWL_UCODE_TLV_API_SCD_CFG = BIT(15), 264 IWL_UCODE_TLV_API_SCD_CFG = BIT(15),
@@ -292,6 +290,7 @@ enum iwl_ucode_tlv_api {
292 * @IWL_UCODE_TLV_CAPA_HOTSPOT_SUPPORT: supports Hot Spot Command 290 * @IWL_UCODE_TLV_CAPA_HOTSPOT_SUPPORT: supports Hot Spot Command
293 * @IWL_UCODE_TLV_CAPA_RADIO_BEACON_STATS: support radio and beacon statistics 291 * @IWL_UCODE_TLV_CAPA_RADIO_BEACON_STATS: support radio and beacon statistics
294 * @IWL_UCODE_TLV_CAPA_BT_COEX_PLCR: enabled BT Coex packet level co-running 292 * @IWL_UCODE_TLV_CAPA_BT_COEX_PLCR: enabled BT Coex packet level co-running
293 * @IWL_UCODE_TLV_CAPA_BT_COEX_RRC: supports BT Coex RRC
295 */ 294 */
296enum iwl_ucode_tlv_capa { 295enum iwl_ucode_tlv_capa {
297 IWL_UCODE_TLV_CAPA_D0I3_SUPPORT = BIT(0), 296 IWL_UCODE_TLV_CAPA_D0I3_SUPPORT = BIT(0),
@@ -308,6 +307,7 @@ enum iwl_ucode_tlv_capa {
308 IWL_UCODE_TLV_CAPA_HOTSPOT_SUPPORT = BIT(18), 307 IWL_UCODE_TLV_CAPA_HOTSPOT_SUPPORT = BIT(18),
309 IWL_UCODE_TLV_CAPA_RADIO_BEACON_STATS = BIT(22), 308 IWL_UCODE_TLV_CAPA_RADIO_BEACON_STATS = BIT(22),
310 IWL_UCODE_TLV_CAPA_BT_COEX_PLCR = BIT(28), 309 IWL_UCODE_TLV_CAPA_BT_COEX_PLCR = BIT(28),
310 IWL_UCODE_TLV_CAPA_BT_COEX_RRC = BIT(30),
311}; 311};
312 312
313/* The default calibrate table size if not specified by firmware file */ 313/* The default calibrate table size if not specified by firmware file */
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c
index 03250a45272e..78cac43e2bcd 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.c
+++ b/drivers/net/wireless/iwlwifi/iwl-io.c
@@ -201,6 +201,8 @@ void iwl_force_nmi(struct iwl_trans *trans)
201 } else { 201 } else {
202 iwl_write_prph(trans, DEVICE_SET_NMI_8000B_REG, 202 iwl_write_prph(trans, DEVICE_SET_NMI_8000B_REG,
203 DEVICE_SET_NMI_8000B_VAL); 203 DEVICE_SET_NMI_8000B_VAL);
204 iwl_write_prph(trans, DEVICE_SET_NMI_REG,
205 DEVICE_SET_NMI_VAL_DRV);
204 } 206 }
205} 207}
206IWL_EXPORT_SYMBOL(iwl_force_nmi); 208IWL_EXPORT_SYMBOL(iwl_force_nmi);
diff --git a/drivers/net/wireless/iwlwifi/iwl-modparams.h b/drivers/net/wireless/iwlwifi/iwl-modparams.h
index e8eabd21ccfe..ac2b90df8413 100644
--- a/drivers/net/wireless/iwlwifi/iwl-modparams.h
+++ b/drivers/net/wireless/iwlwifi/iwl-modparams.h
@@ -103,6 +103,7 @@ enum iwl_disable_11n {
103 * @debug_level: levels are IWL_DL_* 103 * @debug_level: levels are IWL_DL_*
104 * @ant_coupling: antenna coupling in dB, default = 0 104 * @ant_coupling: antenna coupling in dB, default = 0
105 * @d0i3_disable: disable d0i3, default = 1, 105 * @d0i3_disable: disable d0i3, default = 1,
106 * @lar_disable: disable LAR (regulatory), default = 0
106 * @fw_monitor: allow to use firmware monitor 107 * @fw_monitor: allow to use firmware monitor
107 */ 108 */
108struct iwl_mod_params { 109struct iwl_mod_params {
@@ -121,6 +122,7 @@ struct iwl_mod_params {
121 char *nvm_file; 122 char *nvm_file;
122 bool uapsd_disable; 123 bool uapsd_disable;
123 bool d0i3_disable; 124 bool d0i3_disable;
125 bool lar_disable;
124 bool fw_monitor; 126 bool fw_monitor;
125}; 127};
126 128
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
index c74f1a4edf23..774637746427 100644
--- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
@@ -103,8 +103,16 @@ enum family_8000_nvm_offsets {
103 SKU_FAMILY_8000 = 4, 103 SKU_FAMILY_8000 = 4,
104 N_HW_ADDRS_FAMILY_8000 = 5, 104 N_HW_ADDRS_FAMILY_8000 = 5,
105 105
106 /* NVM PHY-SKU-Section offset (in words) for B0 */
107 RADIO_CFG_FAMILY_8000_B0 = 0,
108 SKU_FAMILY_8000_B0 = 2,
109 N_HW_ADDRS_FAMILY_8000_B0 = 3,
110
106 /* NVM REGULATORY -Section offset (in words) definitions */ 111 /* NVM REGULATORY -Section offset (in words) definitions */
107 NVM_CHANNELS_FAMILY_8000 = 0, 112 NVM_CHANNELS_FAMILY_8000 = 0,
113 NVM_LAR_OFFSET_FAMILY_8000_OLD = 0x4C7,
114 NVM_LAR_OFFSET_FAMILY_8000 = 0x507,
115 NVM_LAR_ENABLED_FAMILY_8000 = 0x7,
108 116
109 /* NVM calibration section offset (in words) definitions */ 117 /* NVM calibration section offset (in words) definitions */
110 NVM_CALIB_SECTION_FAMILY_8000 = 0x2B8, 118 NVM_CALIB_SECTION_FAMILY_8000 = 0x2B8,
@@ -146,7 +154,9 @@ static const u8 iwl_nvm_channels_family_8000[] = {
146#define NUM_2GHZ_CHANNELS_FAMILY_8000 14 154#define NUM_2GHZ_CHANNELS_FAMILY_8000 14
147#define FIRST_2GHZ_HT_MINUS 5 155#define FIRST_2GHZ_HT_MINUS 5
148#define LAST_2GHZ_HT_PLUS 9 156#define LAST_2GHZ_HT_PLUS 9
149#define LAST_5GHZ_HT 161 157#define LAST_5GHZ_HT 165
158#define LAST_5GHZ_HT_FAMILY_8000 181
159#define N_HW_ADDR_MASK 0xF
150 160
151/* rate data (static) */ 161/* rate data (static) */
152static struct ieee80211_rate iwl_cfg80211_rates[] = { 162static struct ieee80211_rate iwl_cfg80211_rates[] = {
@@ -201,9 +211,57 @@ enum iwl_nvm_channel_flags {
201#define CHECK_AND_PRINT_I(x) \ 211#define CHECK_AND_PRINT_I(x) \
202 ((ch_flags & NVM_CHANNEL_##x) ? # x " " : "") 212 ((ch_flags & NVM_CHANNEL_##x) ? # x " " : "")
203 213
214static u32 iwl_get_channel_flags(u8 ch_num, int ch_idx, bool is_5ghz,
215 u16 nvm_flags, const struct iwl_cfg *cfg)
216{
217 u32 flags = IEEE80211_CHAN_NO_HT40;
218 u32 last_5ghz_ht = LAST_5GHZ_HT;
219
220 if (cfg->device_family == IWL_DEVICE_FAMILY_8000)
221 last_5ghz_ht = LAST_5GHZ_HT_FAMILY_8000;
222
223 if (!is_5ghz && (nvm_flags & NVM_CHANNEL_40MHZ)) {
224 if (ch_num <= LAST_2GHZ_HT_PLUS)
225 flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
226 if (ch_num >= FIRST_2GHZ_HT_MINUS)
227 flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
228 } else if (ch_num <= last_5ghz_ht && (nvm_flags & NVM_CHANNEL_40MHZ)) {
229 if ((ch_idx - NUM_2GHZ_CHANNELS) % 2 == 0)
230 flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
231 else
232 flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
233 }
234 if (!(nvm_flags & NVM_CHANNEL_80MHZ))
235 flags |= IEEE80211_CHAN_NO_80MHZ;
236 if (!(nvm_flags & NVM_CHANNEL_160MHZ))
237 flags |= IEEE80211_CHAN_NO_160MHZ;
238
239 if (!(nvm_flags & NVM_CHANNEL_IBSS))
240 flags |= IEEE80211_CHAN_NO_IR;
241
242 if (!(nvm_flags & NVM_CHANNEL_ACTIVE))
243 flags |= IEEE80211_CHAN_NO_IR;
244
245 if (nvm_flags & NVM_CHANNEL_RADAR)
246 flags |= IEEE80211_CHAN_RADAR;
247
248 if (nvm_flags & NVM_CHANNEL_INDOOR_ONLY)
249 flags |= IEEE80211_CHAN_INDOOR_ONLY;
250
251 /* Set the GO concurrent flag only in case that NO_IR is set.
252 * Otherwise it is meaningless
253 */
254 if ((nvm_flags & NVM_CHANNEL_GO_CONCURRENT) &&
255 (flags & IEEE80211_CHAN_NO_IR))
256 flags |= IEEE80211_CHAN_GO_CONCURRENT;
257
258 return flags;
259}
260
204static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg, 261static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
205 struct iwl_nvm_data *data, 262 struct iwl_nvm_data *data,
206 const __le16 * const nvm_ch_flags) 263 const __le16 * const nvm_ch_flags,
264 bool lar_supported)
207{ 265{
208 int ch_idx; 266 int ch_idx;
209 int n_channels = 0; 267 int n_channels = 0;
@@ -228,9 +286,14 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
228 286
229 if (ch_idx >= num_2ghz_channels && 287 if (ch_idx >= num_2ghz_channels &&
230 !data->sku_cap_band_52GHz_enable) 288 !data->sku_cap_band_52GHz_enable)
231 ch_flags &= ~NVM_CHANNEL_VALID; 289 continue;
232 290
233 if (!(ch_flags & NVM_CHANNEL_VALID)) { 291 if (!lar_supported && !(ch_flags & NVM_CHANNEL_VALID)) {
292 /*
293 * Channels might become valid later if lar is
294 * supported, hence we still want to add them to
295 * the list of supported channels to cfg80211.
296 */
234 IWL_DEBUG_EEPROM(dev, 297 IWL_DEBUG_EEPROM(dev,
235 "Ch. %d Flags %x [%sGHz] - No traffic\n", 298 "Ch. %d Flags %x [%sGHz] - No traffic\n",
236 nvm_chan[ch_idx], 299 nvm_chan[ch_idx],
@@ -250,45 +313,6 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
250 ieee80211_channel_to_frequency( 313 ieee80211_channel_to_frequency(
251 channel->hw_value, channel->band); 314 channel->hw_value, channel->band);
252 315
253 /* TODO: Need to be dependent to the NVM */
254 channel->flags = IEEE80211_CHAN_NO_HT40;
255 if (ch_idx < num_2ghz_channels &&
256 (ch_flags & NVM_CHANNEL_40MHZ)) {
257 if (nvm_chan[ch_idx] <= LAST_2GHZ_HT_PLUS)
258 channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
259 if (nvm_chan[ch_idx] >= FIRST_2GHZ_HT_MINUS)
260 channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
261 } else if (nvm_chan[ch_idx] <= LAST_5GHZ_HT &&
262 (ch_flags & NVM_CHANNEL_40MHZ)) {
263 if ((ch_idx - num_2ghz_channels) % 2 == 0)
264 channel->flags &= ~IEEE80211_CHAN_NO_HT40PLUS;
265 else
266 channel->flags &= ~IEEE80211_CHAN_NO_HT40MINUS;
267 }
268 if (!(ch_flags & NVM_CHANNEL_80MHZ))
269 channel->flags |= IEEE80211_CHAN_NO_80MHZ;
270 if (!(ch_flags & NVM_CHANNEL_160MHZ))
271 channel->flags |= IEEE80211_CHAN_NO_160MHZ;
272
273 if (!(ch_flags & NVM_CHANNEL_IBSS))
274 channel->flags |= IEEE80211_CHAN_NO_IR;
275
276 if (!(ch_flags & NVM_CHANNEL_ACTIVE))
277 channel->flags |= IEEE80211_CHAN_NO_IR;
278
279 if (ch_flags & NVM_CHANNEL_RADAR)
280 channel->flags |= IEEE80211_CHAN_RADAR;
281
282 if (ch_flags & NVM_CHANNEL_INDOOR_ONLY)
283 channel->flags |= IEEE80211_CHAN_INDOOR_ONLY;
284
285 /* Set the GO concurrent flag only in case that NO_IR is set.
286 * Otherwise it is meaningless
287 */
288 if ((ch_flags & NVM_CHANNEL_GO_CONCURRENT) &&
289 (channel->flags & IEEE80211_CHAN_NO_IR))
290 channel->flags |= IEEE80211_CHAN_GO_CONCURRENT;
291
292 /* Initialize regulatory-based run-time data */ 316 /* Initialize regulatory-based run-time data */
293 317
294 /* 318 /*
@@ -297,6 +321,15 @@ static int iwl_init_channel_map(struct device *dev, const struct iwl_cfg *cfg,
297 */ 321 */
298 channel->max_power = IWL_DEFAULT_MAX_TX_POWER; 322 channel->max_power = IWL_DEFAULT_MAX_TX_POWER;
299 is_5ghz = channel->band == IEEE80211_BAND_5GHZ; 323 is_5ghz = channel->band == IEEE80211_BAND_5GHZ;
324
325 /* don't put limitations in case we're using LAR */
326 if (!lar_supported)
327 channel->flags = iwl_get_channel_flags(nvm_chan[ch_idx],
328 ch_idx, is_5ghz,
329 ch_flags, cfg);
330 else
331 channel->flags = 0;
332
300 IWL_DEBUG_EEPROM(dev, 333 IWL_DEBUG_EEPROM(dev,
301 "Ch. %d [%sGHz] %s%s%s%s%s%s%s(0x%02x %ddBm): Ad-Hoc %ssupported\n", 334 "Ch. %d [%sGHz] %s%s%s%s%s%s%s(0x%02x %ddBm): Ad-Hoc %ssupported\n",
302 channel->hw_value, 335 channel->hw_value,
@@ -370,8 +403,8 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
370 403
371static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg, 404static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
372 struct iwl_nvm_data *data, 405 struct iwl_nvm_data *data,
373 const __le16 *ch_section, bool enable_vht, 406 const __le16 *ch_section,
374 u8 tx_chains, u8 rx_chains) 407 u8 tx_chains, u8 rx_chains, bool lar_supported)
375{ 408{
376 int n_channels; 409 int n_channels;
377 int n_used = 0; 410 int n_used = 0;
@@ -380,11 +413,12 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
380 if (cfg->device_family != IWL_DEVICE_FAMILY_8000) 413 if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
381 n_channels = iwl_init_channel_map( 414 n_channels = iwl_init_channel_map(
382 dev, cfg, data, 415 dev, cfg, data,
383 &ch_section[NVM_CHANNELS]); 416 &ch_section[NVM_CHANNELS], lar_supported);
384 else 417 else
385 n_channels = iwl_init_channel_map( 418 n_channels = iwl_init_channel_map(
386 dev, cfg, data, 419 dev, cfg, data,
387 &ch_section[NVM_CHANNELS_FAMILY_8000]); 420 &ch_section[NVM_CHANNELS_FAMILY_8000],
421 lar_supported);
388 422
389 sband = &data->bands[IEEE80211_BAND_2GHZ]; 423 sband = &data->bands[IEEE80211_BAND_2GHZ];
390 sband->band = IEEE80211_BAND_2GHZ; 424 sband->band = IEEE80211_BAND_2GHZ;
@@ -403,7 +437,7 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
403 IEEE80211_BAND_5GHZ); 437 IEEE80211_BAND_5GHZ);
404 iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ, 438 iwl_init_ht_hw_capab(cfg, data, &sband->ht_cap, IEEE80211_BAND_5GHZ,
405 tx_chains, rx_chains); 439 tx_chains, rx_chains);
406 if (enable_vht) 440 if (data->sku_cap_11ac_enable)
407 iwl_init_vht_hw_capab(cfg, data, &sband->vht_cap, 441 iwl_init_vht_hw_capab(cfg, data, &sband->vht_cap,
408 tx_chains, rx_chains); 442 tx_chains, rx_chains);
409 443
@@ -413,10 +447,15 @@ static void iwl_init_sbands(struct device *dev, const struct iwl_cfg *cfg,
413} 447}
414 448
415static int iwl_get_sku(const struct iwl_cfg *cfg, 449static int iwl_get_sku(const struct iwl_cfg *cfg,
416 const __le16 *nvm_sw) 450 const __le16 *nvm_sw, const __le16 *phy_sku,
451 bool is_family_8000_a_step)
417{ 452{
418 if (cfg->device_family != IWL_DEVICE_FAMILY_8000) 453 if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
419 return le16_to_cpup(nvm_sw + SKU); 454 return le16_to_cpup(nvm_sw + SKU);
455
456 if (!is_family_8000_a_step)
457 return le32_to_cpup((__le32 *)(phy_sku +
458 SKU_FAMILY_8000_B0));
420 else 459 else
421 return le32_to_cpup((__le32 *)(nvm_sw + SKU_FAMILY_8000)); 460 return le32_to_cpup((__le32 *)(nvm_sw + SKU_FAMILY_8000));
422} 461}
@@ -432,23 +471,36 @@ static int iwl_get_nvm_version(const struct iwl_cfg *cfg,
432} 471}
433 472
434static int iwl_get_radio_cfg(const struct iwl_cfg *cfg, 473static int iwl_get_radio_cfg(const struct iwl_cfg *cfg,
435 const __le16 *nvm_sw) 474 const __le16 *nvm_sw, const __le16 *phy_sku,
475 bool is_family_8000_a_step)
436{ 476{
437 if (cfg->device_family != IWL_DEVICE_FAMILY_8000) 477 if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
438 return le16_to_cpup(nvm_sw + RADIO_CFG); 478 return le16_to_cpup(nvm_sw + RADIO_CFG);
479
480 if (!is_family_8000_a_step)
481 return le32_to_cpup((__le32 *)(phy_sku +
482 RADIO_CFG_FAMILY_8000_B0));
439 else 483 else
440 return le32_to_cpup((__le32 *)(nvm_sw + RADIO_CFG_FAMILY_8000)); 484 return le32_to_cpup((__le32 *)(nvm_sw + RADIO_CFG_FAMILY_8000));
485
441} 486}
442 487
443#define N_HW_ADDRS_MASK_FAMILY_8000 0xF
444static int iwl_get_n_hw_addrs(const struct iwl_cfg *cfg, 488static int iwl_get_n_hw_addrs(const struct iwl_cfg *cfg,
445 const __le16 *nvm_sw) 489 const __le16 *nvm_sw, bool is_family_8000_a_step)
446{ 490{
491 int n_hw_addr;
492
447 if (cfg->device_family != IWL_DEVICE_FAMILY_8000) 493 if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
448 return le16_to_cpup(nvm_sw + N_HW_ADDRS); 494 return le16_to_cpup(nvm_sw + N_HW_ADDRS);
495
496 if (!is_family_8000_a_step)
497 n_hw_addr = le32_to_cpup((__le32 *)(nvm_sw +
498 N_HW_ADDRS_FAMILY_8000_B0));
449 else 499 else
450 return le32_to_cpup((__le32 *)(nvm_sw + N_HW_ADDRS_FAMILY_8000)) 500 n_hw_addr = le32_to_cpup((__le32 *)(nvm_sw +
451 & N_HW_ADDRS_MASK_FAMILY_8000; 501 N_HW_ADDRS_FAMILY_8000));
502
503 return n_hw_addr & N_HW_ADDR_MASK;
452} 504}
453 505
454static void iwl_set_radio_cfg(const struct iwl_cfg *cfg, 506static void iwl_set_radio_cfg(const struct iwl_cfg *cfg,
@@ -491,7 +543,8 @@ static void iwl_set_hw_address_family_8000(struct device *dev,
491 const struct iwl_cfg *cfg, 543 const struct iwl_cfg *cfg,
492 struct iwl_nvm_data *data, 544 struct iwl_nvm_data *data,
493 const __le16 *mac_override, 545 const __le16 *mac_override,
494 const __le16 *nvm_hw) 546 const __le16 *nvm_hw,
547 u32 mac_addr0, u32 mac_addr1)
495{ 548{
496 const u8 *hw_addr; 549 const u8 *hw_addr;
497 550
@@ -515,48 +568,17 @@ static void iwl_set_hw_address_family_8000(struct device *dev,
515 } 568 }
516 569
517 if (nvm_hw) { 570 if (nvm_hw) {
518 /* read the MAC address from OTP */ 571 /* read the MAC address from HW resisters */
519 if (!dev_is_pci(dev) || (data->nvm_version < 0xE08)) { 572 hw_addr = (const u8 *)&mac_addr0;
520 /* read the mac address from the WFPM location */ 573 data->hw_addr[0] = hw_addr[3];
521 hw_addr = (const u8 *)(nvm_hw + 574 data->hw_addr[1] = hw_addr[2];
522 HW_ADDR0_WFPM_FAMILY_8000); 575 data->hw_addr[2] = hw_addr[1];
523 data->hw_addr[0] = hw_addr[3]; 576 data->hw_addr[3] = hw_addr[0];
524 data->hw_addr[1] = hw_addr[2]; 577
525 data->hw_addr[2] = hw_addr[1]; 578 hw_addr = (const u8 *)&mac_addr1;
526 data->hw_addr[3] = hw_addr[0]; 579 data->hw_addr[4] = hw_addr[1];
527 580 data->hw_addr[5] = hw_addr[0];
528 hw_addr = (const u8 *)(nvm_hw + 581
529 HW_ADDR1_WFPM_FAMILY_8000);
530 data->hw_addr[4] = hw_addr[1];
531 data->hw_addr[5] = hw_addr[0];
532 } else if ((data->nvm_version >= 0xE08) &&
533 (data->nvm_version < 0xE0B)) {
534 /* read "reverse order" from the PCIe location */
535 hw_addr = (const u8 *)(nvm_hw +
536 HW_ADDR0_PCIE_FAMILY_8000);
537 data->hw_addr[5] = hw_addr[2];
538 data->hw_addr[4] = hw_addr[1];
539 data->hw_addr[3] = hw_addr[0];
540
541 hw_addr = (const u8 *)(nvm_hw +
542 HW_ADDR1_PCIE_FAMILY_8000);
543 data->hw_addr[2] = hw_addr[3];
544 data->hw_addr[1] = hw_addr[2];
545 data->hw_addr[0] = hw_addr[1];
546 } else {
547 /* read from the PCIe location */
548 hw_addr = (const u8 *)(nvm_hw +
549 HW_ADDR0_PCIE_FAMILY_8000);
550 data->hw_addr[5] = hw_addr[0];
551 data->hw_addr[4] = hw_addr[1];
552 data->hw_addr[3] = hw_addr[2];
553
554 hw_addr = (const u8 *)(nvm_hw +
555 HW_ADDR1_PCIE_FAMILY_8000);
556 data->hw_addr[2] = hw_addr[1];
557 data->hw_addr[1] = hw_addr[2];
558 data->hw_addr[0] = hw_addr[3];
559 }
560 if (!is_valid_ether_addr(data->hw_addr)) 582 if (!is_valid_ether_addr(data->hw_addr))
561 IWL_ERR_DEV(dev, 583 IWL_ERR_DEV(dev,
562 "mac address from hw section is not valid\n"); 584 "mac address from hw section is not valid\n");
@@ -571,11 +593,15 @@ struct iwl_nvm_data *
571iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg, 593iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
572 const __le16 *nvm_hw, const __le16 *nvm_sw, 594 const __le16 *nvm_hw, const __le16 *nvm_sw,
573 const __le16 *nvm_calib, const __le16 *regulatory, 595 const __le16 *nvm_calib, const __le16 *regulatory,
574 const __le16 *mac_override, u8 tx_chains, u8 rx_chains) 596 const __le16 *mac_override, const __le16 *phy_sku,
597 u8 tx_chains, u8 rx_chains,
598 bool lar_fw_supported, bool is_family_8000_a_step,
599 u32 mac_addr0, u32 mac_addr1)
575{ 600{
576 struct iwl_nvm_data *data; 601 struct iwl_nvm_data *data;
577 u32 sku; 602 u32 sku;
578 u32 radio_cfg; 603 u32 radio_cfg;
604 u16 lar_config;
579 605
580 if (cfg->device_family != IWL_DEVICE_FAMILY_8000) 606 if (cfg->device_family != IWL_DEVICE_FAMILY_8000)
581 data = kzalloc(sizeof(*data) + 607 data = kzalloc(sizeof(*data) +
@@ -592,22 +618,25 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
592 618
593 data->nvm_version = iwl_get_nvm_version(cfg, nvm_sw); 619 data->nvm_version = iwl_get_nvm_version(cfg, nvm_sw);
594 620
595 radio_cfg = iwl_get_radio_cfg(cfg, nvm_sw); 621 radio_cfg =
622 iwl_get_radio_cfg(cfg, nvm_sw, phy_sku, is_family_8000_a_step);
596 iwl_set_radio_cfg(cfg, data, radio_cfg); 623 iwl_set_radio_cfg(cfg, data, radio_cfg);
597 if (data->valid_tx_ant) 624 if (data->valid_tx_ant)
598 tx_chains &= data->valid_tx_ant; 625 tx_chains &= data->valid_tx_ant;
599 if (data->valid_rx_ant) 626 if (data->valid_rx_ant)
600 rx_chains &= data->valid_rx_ant; 627 rx_chains &= data->valid_rx_ant;
601 628
602 sku = iwl_get_sku(cfg, nvm_sw); 629 sku = iwl_get_sku(cfg, nvm_sw, phy_sku, is_family_8000_a_step);
603 data->sku_cap_band_24GHz_enable = sku & NVM_SKU_CAP_BAND_24GHZ; 630 data->sku_cap_band_24GHz_enable = sku & NVM_SKU_CAP_BAND_24GHZ;
604 data->sku_cap_band_52GHz_enable = sku & NVM_SKU_CAP_BAND_52GHZ; 631 data->sku_cap_band_52GHz_enable = sku & NVM_SKU_CAP_BAND_52GHZ;
605 data->sku_cap_11n_enable = sku & NVM_SKU_CAP_11N_ENABLE; 632 data->sku_cap_11n_enable = sku & NVM_SKU_CAP_11N_ENABLE;
606 data->sku_cap_11ac_enable = sku & NVM_SKU_CAP_11AC_ENABLE;
607 if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_ALL) 633 if (iwlwifi_mod_params.disable_11n & IWL_DISABLE_HT_ALL)
608 data->sku_cap_11n_enable = false; 634 data->sku_cap_11n_enable = false;
635 data->sku_cap_11ac_enable = data->sku_cap_11n_enable &&
636 (sku & NVM_SKU_CAP_11AC_ENABLE);
609 637
610 data->n_hw_addrs = iwl_get_n_hw_addrs(cfg, nvm_sw); 638 data->n_hw_addrs =
639 iwl_get_n_hw_addrs(cfg, nvm_sw, is_family_8000_a_step);
611 640
612 if (cfg->device_family != IWL_DEVICE_FAMILY_8000) { 641 if (cfg->device_family != IWL_DEVICE_FAMILY_8000) {
613 /* Checking for required sections */ 642 /* Checking for required sections */
@@ -626,16 +655,23 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
626 iwl_set_hw_address(cfg, data, nvm_hw); 655 iwl_set_hw_address(cfg, data, nvm_hw);
627 656
628 iwl_init_sbands(dev, cfg, data, nvm_sw, 657 iwl_init_sbands(dev, cfg, data, nvm_sw,
629 sku & NVM_SKU_CAP_11AC_ENABLE, tx_chains, 658 tx_chains, rx_chains, lar_fw_supported);
630 rx_chains);
631 } else { 659 } else {
660 u16 lar_offset = data->nvm_version < 0xE39 ?
661 NVM_LAR_OFFSET_FAMILY_8000_OLD :
662 NVM_LAR_OFFSET_FAMILY_8000;
663
664 lar_config = le16_to_cpup(regulatory + lar_offset);
665 data->lar_enabled = !!(lar_config &
666 NVM_LAR_ENABLED_FAMILY_8000);
667
632 /* MAC address in family 8000 */ 668 /* MAC address in family 8000 */
633 iwl_set_hw_address_family_8000(dev, cfg, data, mac_override, 669 iwl_set_hw_address_family_8000(dev, cfg, data, mac_override,
634 nvm_hw); 670 nvm_hw, mac_addr0, mac_addr1);
635 671
636 iwl_init_sbands(dev, cfg, data, regulatory, 672 iwl_init_sbands(dev, cfg, data, regulatory,
637 sku & NVM_SKU_CAP_11AC_ENABLE, tx_chains, 673 tx_chains, rx_chains,
638 rx_chains); 674 lar_fw_supported && data->lar_enabled);
639 } 675 }
640 676
641 data->calib_version = 255; 677 data->calib_version = 255;
@@ -643,3 +679,164 @@ iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
643 return data; 679 return data;
644} 680}
645IWL_EXPORT_SYMBOL(iwl_parse_nvm_data); 681IWL_EXPORT_SYMBOL(iwl_parse_nvm_data);
682
683static u32 iwl_nvm_get_regdom_bw_flags(const u8 *nvm_chan,
684 int ch_idx, u16 nvm_flags,
685 const struct iwl_cfg *cfg)
686{
687 u32 flags = NL80211_RRF_NO_HT40;
688 u32 last_5ghz_ht = LAST_5GHZ_HT;
689
690 if (cfg->device_family == IWL_DEVICE_FAMILY_8000)
691 last_5ghz_ht = LAST_5GHZ_HT_FAMILY_8000;
692
693 if (ch_idx < NUM_2GHZ_CHANNELS &&
694 (nvm_flags & NVM_CHANNEL_40MHZ)) {
695 if (nvm_chan[ch_idx] <= LAST_2GHZ_HT_PLUS)
696 flags &= ~NL80211_RRF_NO_HT40PLUS;
697 if (nvm_chan[ch_idx] >= FIRST_2GHZ_HT_MINUS)
698 flags &= ~NL80211_RRF_NO_HT40MINUS;
699 } else if (nvm_chan[ch_idx] <= last_5ghz_ht &&
700 (nvm_flags & NVM_CHANNEL_40MHZ)) {
701 if ((ch_idx - NUM_2GHZ_CHANNELS) % 2 == 0)
702 flags &= ~NL80211_RRF_NO_HT40PLUS;
703 else
704 flags &= ~NL80211_RRF_NO_HT40MINUS;
705 }
706
707 if (!(nvm_flags & NVM_CHANNEL_80MHZ))
708 flags |= NL80211_RRF_NO_80MHZ;
709 if (!(nvm_flags & NVM_CHANNEL_160MHZ))
710 flags |= NL80211_RRF_NO_160MHZ;
711
712 if (!(nvm_flags & NVM_CHANNEL_ACTIVE))
713 flags |= NL80211_RRF_NO_IR;
714
715 if (nvm_flags & NVM_CHANNEL_RADAR)
716 flags |= NL80211_RRF_DFS;
717
718 if (nvm_flags & NVM_CHANNEL_INDOOR_ONLY)
719 flags |= NL80211_RRF_NO_OUTDOOR;
720
721 /* Set the GO concurrent flag only in case that NO_IR is set.
722 * Otherwise it is meaningless
723 */
724 if ((nvm_flags & NVM_CHANNEL_GO_CONCURRENT) &&
725 (flags & NL80211_RRF_NO_IR))
726 flags |= NL80211_RRF_GO_CONCURRENT;
727
728 return flags;
729}
730
731struct ieee80211_regdomain *
732iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
733 int num_of_ch, __le32 *channels, u16 fw_mcc)
734{
735 int ch_idx;
736 u16 ch_flags, prev_ch_flags = 0;
737 const u8 *nvm_chan = cfg->device_family == IWL_DEVICE_FAMILY_8000 ?
738 iwl_nvm_channels_family_8000 : iwl_nvm_channels;
739 struct ieee80211_regdomain *regd;
740 int size_of_regd;
741 struct ieee80211_reg_rule *rule;
742 enum ieee80211_band band;
743 int center_freq, prev_center_freq = 0;
744 int valid_rules = 0;
745 bool new_rule;
746 int max_num_ch = cfg->device_family == IWL_DEVICE_FAMILY_8000 ?
747 IWL_NUM_CHANNELS_FAMILY_8000 : IWL_NUM_CHANNELS;
748
749 if (WARN_ON_ONCE(num_of_ch > NL80211_MAX_SUPP_REG_RULES))
750 return ERR_PTR(-EINVAL);
751
752 if (WARN_ON(num_of_ch > max_num_ch))
753 num_of_ch = max_num_ch;
754
755 IWL_DEBUG_DEV(dev, IWL_DL_LAR, "building regdom for %d channels\n",
756 num_of_ch);
757
758 /* build a regdomain rule for every valid channel */
759 size_of_regd =
760 sizeof(struct ieee80211_regdomain) +
761 num_of_ch * sizeof(struct ieee80211_reg_rule);
762
763 regd = kzalloc(size_of_regd, GFP_KERNEL);
764 if (!regd)
765 return ERR_PTR(-ENOMEM);
766
767 for (ch_idx = 0; ch_idx < num_of_ch; ch_idx++) {
768 ch_flags = (u16)__le32_to_cpup(channels + ch_idx);
769 band = (ch_idx < NUM_2GHZ_CHANNELS) ?
770 IEEE80211_BAND_2GHZ : IEEE80211_BAND_5GHZ;
771 center_freq = ieee80211_channel_to_frequency(nvm_chan[ch_idx],
772 band);
773 new_rule = false;
774
775 if (!(ch_flags & NVM_CHANNEL_VALID)) {
776 IWL_DEBUG_DEV(dev, IWL_DL_LAR,
777 "Ch. %d Flags %x [%sGHz] - No traffic\n",
778 nvm_chan[ch_idx],
779 ch_flags,
780 (ch_idx >= NUM_2GHZ_CHANNELS) ?
781 "5.2" : "2.4");
782 continue;
783 }
784
785 /* we can't continue the same rule */
786 if (ch_idx == 0 || prev_ch_flags != ch_flags ||
787 center_freq - prev_center_freq > 20) {
788 valid_rules++;
789 new_rule = true;
790 }
791
792 rule = &regd->reg_rules[valid_rules - 1];
793
794 if (new_rule)
795 rule->freq_range.start_freq_khz =
796 MHZ_TO_KHZ(center_freq - 10);
797
798 rule->freq_range.end_freq_khz = MHZ_TO_KHZ(center_freq + 10);
799
800 /* this doesn't matter - not used by FW */
801 rule->power_rule.max_antenna_gain = DBI_TO_MBI(6);
802 rule->power_rule.max_eirp =
803 DBM_TO_MBM(IWL_DEFAULT_MAX_TX_POWER);
804
805 rule->flags = iwl_nvm_get_regdom_bw_flags(nvm_chan, ch_idx,
806 ch_flags, cfg);
807
808 /* rely on auto-calculation to merge BW of contiguous chans */
809 rule->flags |= NL80211_RRF_AUTO_BW;
810 rule->freq_range.max_bandwidth_khz = 0;
811
812 prev_ch_flags = ch_flags;
813 prev_center_freq = center_freq;
814
815 IWL_DEBUG_DEV(dev, IWL_DL_LAR,
816 "Ch. %d [%sGHz] %s%s%s%s%s%s%s%s%s(0x%02x): Ad-Hoc %ssupported\n",
817 center_freq,
818 band == IEEE80211_BAND_5GHZ ? "5.2" : "2.4",
819 CHECK_AND_PRINT_I(VALID),
820 CHECK_AND_PRINT_I(ACTIVE),
821 CHECK_AND_PRINT_I(RADAR),
822 CHECK_AND_PRINT_I(WIDE),
823 CHECK_AND_PRINT_I(40MHZ),
824 CHECK_AND_PRINT_I(80MHZ),
825 CHECK_AND_PRINT_I(160MHZ),
826 CHECK_AND_PRINT_I(INDOOR_ONLY),
827 CHECK_AND_PRINT_I(GO_CONCURRENT),
828 ch_flags,
829 ((ch_flags & NVM_CHANNEL_ACTIVE) &&
830 !(ch_flags & NVM_CHANNEL_RADAR))
831 ? "" : "not ");
832 }
833
834 regd->n_reg_rules = valid_rules;
835
836 /* set alpha2 from FW. */
837 regd->alpha2[0] = fw_mcc >> 8;
838 regd->alpha2[1] = fw_mcc & 0xff;
839
840 return regd;
841}
842IWL_EXPORT_SYMBOL(iwl_parse_nvm_mcc_info);
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h
index c9c45a39d212..c995d2cee3f6 100644
--- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h
+++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.h
@@ -62,6 +62,7 @@
62#ifndef __iwl_nvm_parse_h__ 62#ifndef __iwl_nvm_parse_h__
63#define __iwl_nvm_parse_h__ 63#define __iwl_nvm_parse_h__
64 64
65#include <net/cfg80211.h>
65#include "iwl-eeprom-parse.h" 66#include "iwl-eeprom-parse.h"
66 67
67/** 68/**
@@ -76,6 +77,22 @@ struct iwl_nvm_data *
76iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg, 77iwl_parse_nvm_data(struct device *dev, const struct iwl_cfg *cfg,
77 const __le16 *nvm_hw, const __le16 *nvm_sw, 78 const __le16 *nvm_hw, const __le16 *nvm_sw,
78 const __le16 *nvm_calib, const __le16 *regulatory, 79 const __le16 *nvm_calib, const __le16 *regulatory,
79 const __le16 *mac_override, u8 tx_chains, u8 rx_chains); 80 const __le16 *mac_override, const __le16 *phy_sku,
81 u8 tx_chains, u8 rx_chains,
82 bool lar_fw_supported, bool is_family_8000_a_step,
83 u32 mac_addr0, u32 mac_addr1);
84
85/**
86 * iwl_parse_mcc_info - parse MCC (mobile country code) info coming from FW
87 *
88 * This function parses the regulatory channel data received as a
89 * MCC_UPDATE_CMD command. It returns a newly allocation regulatory domain,
90 * to be fed into the regulatory core. An ERR_PTR is returned on error.
91 * If not given to the regulatory core, the user is responsible for freeing
92 * the regdomain returned here with kfree.
93 */
94struct ieee80211_regdomain *
95iwl_parse_nvm_mcc_info(struct device *dev, const struct iwl_cfg *cfg,
96 int num_of_ch, __le32 *channels, u16 fw_mcc);
80 97
81#endif /* __iwl_nvm_parse_h__ */ 98#endif /* __iwl_nvm_parse_h__ */
diff --git a/drivers/net/wireless/iwlwifi/iwl-prph.h b/drivers/net/wireless/iwlwifi/iwl-prph.h
index 6095088b88d9..bc962888c583 100644
--- a/drivers/net/wireless/iwlwifi/iwl-prph.h
+++ b/drivers/net/wireless/iwlwifi/iwl-prph.h
@@ -371,6 +371,33 @@ enum secure_load_status_reg {
371 371
372#define DBGC_IN_SAMPLE (0xa03c00) 372#define DBGC_IN_SAMPLE (0xa03c00)
373 373
374/* enable the ID buf for read */
375#define WFPM_PS_CTL_CLR 0xA0300C
376#define WFMP_MAC_ADDR_0 0xA03080
377#define WFMP_MAC_ADDR_1 0xA03084
378#define LMPM_PMG_EN 0xA01CEC
379#define RADIO_REG_SYS_MANUAL_DFT_0 0xAD4078
380#define RFIC_REG_RD 0xAD0470
381#define WFPM_CTRL_REG 0xA03030
382enum {
383 ENABLE_WFPM = BIT(31),
384 WFPM_AUX_CTL_AUX_IF_MAC_OWNER_MSK = 0x80000000,
385};
386
387#define AUX_MISC_REG 0xA200B0
388enum {
389 HW_STEP_LOCATION_BITS = 24,
390};
391
392#define AUX_MISC_MASTER1_EN 0xA20818
393enum aux_misc_master1_en {
394 AUX_MISC_MASTER1_EN_SBE_MSK = 0x1,
395};
396
397#define AUX_MISC_MASTER1_SMPHR_STATUS 0xA20800
398#define RSA_ENABLE 0xA24B08
399#define PREG_AUX_BUS_WPROT_0 0xA04CC0
400
374/* FW chicken bits */ 401/* FW chicken bits */
375#define LMPM_CHICK 0xA01FF8 402#define LMPM_CHICK 0xA01FF8
376enum { 403enum {
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index 542a6810c81c..11ac5c58527f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -458,6 +458,8 @@ struct iwl_trans_txq_scd_cfg {
458 * @txq_disable: de-configure a Tx queue to send AMPDUs 458 * @txq_disable: de-configure a Tx queue to send AMPDUs
459 * Must be atomic 459 * Must be atomic
460 * @wait_tx_queue_empty: wait until tx queues are empty. May sleep. 460 * @wait_tx_queue_empty: wait until tx queues are empty. May sleep.
461 * @freeze_txq_timer: prevents the timer of the queue from firing until the
462 * queue is set to awake. Must be atomic.
461 * @dbgfs_register: add the dbgfs files under this directory. Files will be 463 * @dbgfs_register: add the dbgfs files under this directory. Files will be
462 * automatically deleted. 464 * automatically deleted.
463 * @write8: write a u8 to a register at offset ofs from the BAR 465 * @write8: write a u8 to a register at offset ofs from the BAR
@@ -517,6 +519,8 @@ struct iwl_trans_ops {
517 519
518 int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir); 520 int (*dbgfs_register)(struct iwl_trans *trans, struct dentry* dir);
519 int (*wait_tx_queue_empty)(struct iwl_trans *trans, u32 txq_bm); 521 int (*wait_tx_queue_empty)(struct iwl_trans *trans, u32 txq_bm);
522 void (*freeze_txq_timer)(struct iwl_trans *trans, unsigned long txqs,
523 bool freeze);
520 524
521 void (*write8)(struct iwl_trans *trans, u32 ofs, u8 val); 525 void (*write8)(struct iwl_trans *trans, u32 ofs, u8 val);
522 void (*write32)(struct iwl_trans *trans, u32 ofs, u32 val); 526 void (*write32)(struct iwl_trans *trans, u32 ofs, u32 val);
@@ -873,6 +877,17 @@ void iwl_trans_ac_txq_enable(struct iwl_trans *trans, int queue, int fifo,
873 iwl_trans_txq_enable_cfg(trans, queue, 0, &cfg, queue_wdg_timeout); 877 iwl_trans_txq_enable_cfg(trans, queue, 0, &cfg, queue_wdg_timeout);
874} 878}
875 879
880static inline void iwl_trans_freeze_txq_timer(struct iwl_trans *trans,
881 unsigned long txqs,
882 bool freeze)
883{
884 if (unlikely(trans->state != IWL_TRANS_FW_ALIVE))
885 IWL_ERR(trans, "%s bad state = %d\n", __func__, trans->state);
886
887 if (trans->ops->freeze_txq_timer)
888 trans->ops->freeze_txq_timer(trans, txqs, freeze);
889}
890
876static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans, 891static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans,
877 u32 txqs) 892 u32 txqs)
878{ 893{
diff --git a/drivers/net/wireless/iwlwifi/mvm/coex.c b/drivers/net/wireless/iwlwifi/mvm/coex.c
index 877f19bbae7e..13a0a03158de 100644
--- a/drivers/net/wireless/iwlwifi/mvm/coex.c
+++ b/drivers/net/wireless/iwlwifi/mvm/coex.c
@@ -72,158 +72,6 @@
72#include "mvm.h" 72#include "mvm.h"
73#include "iwl-debug.h" 73#include "iwl-debug.h"
74 74
75const u32 iwl_bt_ctl_kill_msk[BT_KILL_MSK_MAX] = {
76 [BT_KILL_MSK_DEFAULT] = 0xfffffc00,
77 [BT_KILL_MSK_NEVER] = 0xffffffff,
78 [BT_KILL_MSK_ALWAYS] = 0,
79};
80
81const u8 iwl_bt_cts_kill_msk[BT_MAX_AG][BT_COEX_MAX_LUT] = {
82 {
83 BT_KILL_MSK_ALWAYS,
84 BT_KILL_MSK_ALWAYS,
85 BT_KILL_MSK_ALWAYS,
86 },
87 {
88 BT_KILL_MSK_NEVER,
89 BT_KILL_MSK_NEVER,
90 BT_KILL_MSK_NEVER,
91 },
92 {
93 BT_KILL_MSK_NEVER,
94 BT_KILL_MSK_NEVER,
95 BT_KILL_MSK_NEVER,
96 },
97 {
98 BT_KILL_MSK_DEFAULT,
99 BT_KILL_MSK_NEVER,
100 BT_KILL_MSK_DEFAULT,
101 },
102};
103
104const u8 iwl_bt_ack_kill_msk[BT_MAX_AG][BT_COEX_MAX_LUT] = {
105 {
106 BT_KILL_MSK_ALWAYS,
107 BT_KILL_MSK_ALWAYS,
108 BT_KILL_MSK_ALWAYS,
109 },
110 {
111 BT_KILL_MSK_ALWAYS,
112 BT_KILL_MSK_ALWAYS,
113 BT_KILL_MSK_ALWAYS,
114 },
115 {
116 BT_KILL_MSK_ALWAYS,
117 BT_KILL_MSK_ALWAYS,
118 BT_KILL_MSK_ALWAYS,
119 },
120 {
121 BT_KILL_MSK_DEFAULT,
122 BT_KILL_MSK_ALWAYS,
123 BT_KILL_MSK_DEFAULT,
124 },
125};
126
127static const __le32 iwl_bt_prio_boost[BT_COEX_BOOST_SIZE] = {
128 cpu_to_le32(0xf0f0f0f0), /* 50% */
129 cpu_to_le32(0xc0c0c0c0), /* 25% */
130 cpu_to_le32(0xfcfcfcfc), /* 75% */
131 cpu_to_le32(0xfefefefe), /* 87.5% */
132};
133
134static const __le32 iwl_single_shared_ant[BT_COEX_MAX_LUT][BT_COEX_LUT_SIZE] = {
135 {
136 cpu_to_le32(0x40000000),
137 cpu_to_le32(0x00000000),
138 cpu_to_le32(0x44000000),
139 cpu_to_le32(0x00000000),
140 cpu_to_le32(0x40000000),
141 cpu_to_le32(0x00000000),
142 cpu_to_le32(0x44000000),
143 cpu_to_le32(0x00000000),
144 cpu_to_le32(0xc0004000),
145 cpu_to_le32(0xf0005000),
146 cpu_to_le32(0xc0004000),
147 cpu_to_le32(0xf0005000),
148 },
149 {
150 cpu_to_le32(0x40000000),
151 cpu_to_le32(0x00000000),
152 cpu_to_le32(0x44000000),
153 cpu_to_le32(0x00000000),
154 cpu_to_le32(0x40000000),
155 cpu_to_le32(0x00000000),
156 cpu_to_le32(0x44000000),
157 cpu_to_le32(0x00000000),
158 cpu_to_le32(0xc0004000),
159 cpu_to_le32(0xf0005000),
160 cpu_to_le32(0xc0004000),
161 cpu_to_le32(0xf0005000),
162 },
163 {
164 cpu_to_le32(0x40000000),
165 cpu_to_le32(0x00000000),
166 cpu_to_le32(0x44000000),
167 cpu_to_le32(0x00000000),
168 cpu_to_le32(0x40000000),
169 cpu_to_le32(0x00000000),
170 cpu_to_le32(0x44000000),
171 cpu_to_le32(0x00000000),
172 cpu_to_le32(0xc0004000),
173 cpu_to_le32(0xf0005000),
174 cpu_to_le32(0xc0004000),
175 cpu_to_le32(0xf0005000),
176 },
177};
178
179static const __le32 iwl_combined_lookup[BT_COEX_MAX_LUT][BT_COEX_LUT_SIZE] = {
180 {
181 /* Tight */
182 cpu_to_le32(0xaaaaaaaa),
183 cpu_to_le32(0xaaaaaaaa),
184 cpu_to_le32(0xaeaaaaaa),
185 cpu_to_le32(0xaaaaaaaa),
186 cpu_to_le32(0xcc00ff28),
187 cpu_to_le32(0x0000aaaa),
188 cpu_to_le32(0xcc00aaaa),
189 cpu_to_le32(0x0000aaaa),
190 cpu_to_le32(0xc0004000),
191 cpu_to_le32(0x00004000),
192 cpu_to_le32(0xf0005000),
193 cpu_to_le32(0xf0005000),
194 },
195 {
196 /* Loose */
197 cpu_to_le32(0xaaaaaaaa),
198 cpu_to_le32(0xaaaaaaaa),
199 cpu_to_le32(0xaaaaaaaa),
200 cpu_to_le32(0xaaaaaaaa),
201 cpu_to_le32(0xcc00ff28),
202 cpu_to_le32(0x0000aaaa),
203 cpu_to_le32(0xcc00aaaa),
204 cpu_to_le32(0x0000aaaa),
205 cpu_to_le32(0x00000000),
206 cpu_to_le32(0x00000000),
207 cpu_to_le32(0xf0005000),
208 cpu_to_le32(0xf0005000),
209 },
210 {
211 /* Tx Tx disabled */
212 cpu_to_le32(0xaaaaaaaa),
213 cpu_to_le32(0xaaaaaaaa),
214 cpu_to_le32(0xeeaaaaaa),
215 cpu_to_le32(0xaaaaaaaa),
216 cpu_to_le32(0xcc00ff28),
217 cpu_to_le32(0x0000aaaa),
218 cpu_to_le32(0xcc00aaaa),
219 cpu_to_le32(0x0000aaaa),
220 cpu_to_le32(0xc0004000),
221 cpu_to_le32(0xc0004000),
222 cpu_to_le32(0xf0005000),
223 cpu_to_le32(0xf0005000),
224 },
225};
226
227/* 20MHz / 40MHz below / 40Mhz above*/ 75/* 20MHz / 40MHz below / 40Mhz above*/
228static const __le64 iwl_ci_mask[][3] = { 76static const __le64 iwl_ci_mask[][3] = {
229 /* dummy entry for channel 0 */ 77 /* dummy entry for channel 0 */
@@ -596,14 +444,6 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
596 goto send_cmd; 444 goto send_cmd;
597 } 445 }
598 446
599 bt_cmd->max_kill = cpu_to_le32(5);
600 bt_cmd->bt4_antenna_isolation_thr =
601 cpu_to_le32(IWL_MVM_BT_COEX_ANTENNA_COUPLING_THRS);
602 bt_cmd->bt4_tx_tx_delta_freq_thr = cpu_to_le32(15);
603 bt_cmd->bt4_tx_rx_max_freq0 = cpu_to_le32(15);
604 bt_cmd->override_primary_lut = cpu_to_le32(BT_COEX_INVALID_LUT);
605 bt_cmd->override_secondary_lut = cpu_to_le32(BT_COEX_INVALID_LUT);
606
607 mode = iwlwifi_mod_params.bt_coex_active ? BT_COEX_NW : BT_COEX_DISABLE; 447 mode = iwlwifi_mod_params.bt_coex_active ? BT_COEX_NW : BT_COEX_DISABLE;
608 bt_cmd->mode = cpu_to_le32(mode); 448 bt_cmd->mode = cpu_to_le32(mode);
609 449
@@ -622,18 +462,6 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
622 462
623 bt_cmd->enabled_modules |= cpu_to_le32(BT_COEX_HIGH_BAND_RET); 463 bt_cmd->enabled_modules |= cpu_to_le32(BT_COEX_HIGH_BAND_RET);
624 464
625 if (mvm->cfg->bt_shared_single_ant)
626 memcpy(&bt_cmd->decision_lut, iwl_single_shared_ant,
627 sizeof(iwl_single_shared_ant));
628 else
629 memcpy(&bt_cmd->decision_lut, iwl_combined_lookup,
630 sizeof(iwl_combined_lookup));
631
632 memcpy(&bt_cmd->mplut_prio_boost, iwl_bt_prio_boost,
633 sizeof(iwl_bt_prio_boost));
634 bt_cmd->multiprio_lut[0] = cpu_to_le32(IWL_MVM_BT_COEX_MPLUT_REG0);
635 bt_cmd->multiprio_lut[1] = cpu_to_le32(IWL_MVM_BT_COEX_MPLUT_REG1);
636
637send_cmd: 465send_cmd:
638 memset(&mvm->last_bt_notif, 0, sizeof(mvm->last_bt_notif)); 466 memset(&mvm->last_bt_notif, 0, sizeof(mvm->last_bt_notif));
639 memset(&mvm->last_bt_ci_cmd, 0, sizeof(mvm->last_bt_ci_cmd)); 467 memset(&mvm->last_bt_ci_cmd, 0, sizeof(mvm->last_bt_ci_cmd));
@@ -644,48 +472,6 @@ send_cmd:
644 return ret; 472 return ret;
645} 473}
646 474
647static int iwl_mvm_bt_udpate_sw_boost(struct iwl_mvm *mvm)
648{
649 struct iwl_bt_coex_profile_notif *notif = &mvm->last_bt_notif;
650 u32 primary_lut = le32_to_cpu(notif->primary_ch_lut);
651 u32 secondary_lut = le32_to_cpu(notif->secondary_ch_lut);
652 u32 ag = le32_to_cpu(notif->bt_activity_grading);
653 struct iwl_bt_coex_sw_boost_update_cmd cmd = {};
654 u8 ack_kill_msk[NUM_PHY_CTX] = {};
655 u8 cts_kill_msk[NUM_PHY_CTX] = {};
656 int i;
657
658 lockdep_assert_held(&mvm->mutex);
659
660 ack_kill_msk[0] = iwl_bt_ack_kill_msk[ag][primary_lut];
661 cts_kill_msk[0] = iwl_bt_cts_kill_msk[ag][primary_lut];
662
663 ack_kill_msk[1] = iwl_bt_ack_kill_msk[ag][secondary_lut];
664 cts_kill_msk[1] = iwl_bt_cts_kill_msk[ag][secondary_lut];
665
666 /* Don't send HCMD if there is no update */
667 if (!memcmp(ack_kill_msk, mvm->bt_ack_kill_msk, sizeof(ack_kill_msk)) ||
668 !memcmp(cts_kill_msk, mvm->bt_cts_kill_msk, sizeof(cts_kill_msk)))
669 return 0;
670
671 memcpy(mvm->bt_ack_kill_msk, ack_kill_msk,
672 sizeof(mvm->bt_ack_kill_msk));
673 memcpy(mvm->bt_cts_kill_msk, cts_kill_msk,
674 sizeof(mvm->bt_cts_kill_msk));
675
676 BUILD_BUG_ON(ARRAY_SIZE(ack_kill_msk) < ARRAY_SIZE(cmd.boost_values));
677
678 for (i = 0; i < ARRAY_SIZE(cmd.boost_values); i++) {
679 cmd.boost_values[i].kill_ack_msk =
680 cpu_to_le32(iwl_bt_ctl_kill_msk[ack_kill_msk[i]]);
681 cmd.boost_values[i].kill_cts_msk =
682 cpu_to_le32(iwl_bt_ctl_kill_msk[cts_kill_msk[i]]);
683 }
684
685 return iwl_mvm_send_cmd_pdu(mvm, BT_COEX_UPDATE_SW_BOOST, 0,
686 sizeof(cmd), &cmd);
687}
688
689static int iwl_mvm_bt_coex_reduced_txp(struct iwl_mvm *mvm, u8 sta_id, 475static int iwl_mvm_bt_coex_reduced_txp(struct iwl_mvm *mvm, u8 sta_id,
690 bool enable) 476 bool enable)
691{ 477{
@@ -951,9 +737,6 @@ static void iwl_mvm_bt_coex_notif_handle(struct iwl_mvm *mvm)
951 IWL_ERR(mvm, "Failed to send BT_CI cmd\n"); 737 IWL_ERR(mvm, "Failed to send BT_CI cmd\n");
952 memcpy(&mvm->last_bt_ci_cmd, &cmd, sizeof(cmd)); 738 memcpy(&mvm->last_bt_ci_cmd, &cmd, sizeof(cmd));
953 } 739 }
954
955 if (iwl_mvm_bt_udpate_sw_boost(mvm))
956 IWL_ERR(mvm, "Failed to update the ctrl_kill_msk\n");
957} 740}
958 741
959int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm, 742int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,
@@ -1074,9 +857,6 @@ void iwl_mvm_bt_rssi_event(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
1074 ieee80211_iterate_active_interfaces_atomic( 857 ieee80211_iterate_active_interfaces_atomic(
1075 mvm->hw, IEEE80211_IFACE_ITER_NORMAL, 858 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
1076 iwl_mvm_bt_rssi_iterator, &data); 859 iwl_mvm_bt_rssi_iterator, &data);
1077
1078 if (iwl_mvm_bt_udpate_sw_boost(mvm))
1079 IWL_ERR(mvm, "Failed to update the ctrl_kill_msk\n");
1080} 860}
1081 861
1082#define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000) 862#define LINK_QUAL_AGG_TIME_LIMIT_DEF (4000)
diff --git a/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c b/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c
index 5535ec9766cb..d954591e0be5 100644
--- a/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c
+++ b/drivers/net/wireless/iwlwifi/mvm/coex_legacy.c
@@ -288,6 +288,65 @@ static const __le64 iwl_ci_mask[][3] = {
288 }, 288 },
289}; 289};
290 290
291enum iwl_bt_kill_msk {
292 BT_KILL_MSK_DEFAULT,
293 BT_KILL_MSK_NEVER,
294 BT_KILL_MSK_ALWAYS,
295 BT_KILL_MSK_MAX,
296};
297
298static const u32 iwl_bt_ctl_kill_msk[BT_KILL_MSK_MAX] = {
299 [BT_KILL_MSK_DEFAULT] = 0xfffffc00,
300 [BT_KILL_MSK_NEVER] = 0xffffffff,
301 [BT_KILL_MSK_ALWAYS] = 0,
302};
303
304static const u8 iwl_bt_cts_kill_msk[BT_MAX_AG][BT_COEX_MAX_LUT] = {
305 {
306 BT_KILL_MSK_ALWAYS,
307 BT_KILL_MSK_ALWAYS,
308 BT_KILL_MSK_ALWAYS,
309 },
310 {
311 BT_KILL_MSK_NEVER,
312 BT_KILL_MSK_NEVER,
313 BT_KILL_MSK_NEVER,
314 },
315 {
316 BT_KILL_MSK_NEVER,
317 BT_KILL_MSK_NEVER,
318 BT_KILL_MSK_NEVER,
319 },
320 {
321 BT_KILL_MSK_DEFAULT,
322 BT_KILL_MSK_NEVER,
323 BT_KILL_MSK_DEFAULT,
324 },
325};
326
327static const u8 iwl_bt_ack_kill_msk[BT_MAX_AG][BT_COEX_MAX_LUT] = {
328 {
329 BT_KILL_MSK_ALWAYS,
330 BT_KILL_MSK_ALWAYS,
331 BT_KILL_MSK_ALWAYS,
332 },
333 {
334 BT_KILL_MSK_ALWAYS,
335 BT_KILL_MSK_ALWAYS,
336 BT_KILL_MSK_ALWAYS,
337 },
338 {
339 BT_KILL_MSK_ALWAYS,
340 BT_KILL_MSK_ALWAYS,
341 BT_KILL_MSK_ALWAYS,
342 },
343 {
344 BT_KILL_MSK_DEFAULT,
345 BT_KILL_MSK_ALWAYS,
346 BT_KILL_MSK_DEFAULT,
347 },
348};
349
291struct corunning_block_luts { 350struct corunning_block_luts {
292 u8 range; 351 u8 range;
293 __le32 lut20[BT_COEX_CORUN_LUT_SIZE]; 352 __le32 lut20[BT_COEX_CORUN_LUT_SIZE];
@@ -633,7 +692,7 @@ int iwl_send_bt_init_conf_old(struct iwl_mvm *mvm)
633 if (IWL_MVM_BT_COEX_TTC) 692 if (IWL_MVM_BT_COEX_TTC)
634 bt_cmd->flags |= cpu_to_le32(BT_COEX_TTC); 693 bt_cmd->flags |= cpu_to_le32(BT_COEX_TTC);
635 694
636 if (IWL_MVM_BT_COEX_RRC) 695 if (iwl_mvm_bt_is_rrc_supported(mvm))
637 bt_cmd->flags |= cpu_to_le32(BT_COEX_RRC); 696 bt_cmd->flags |= cpu_to_le32(BT_COEX_RRC);
638 697
639 if (mvm->cfg->bt_shared_single_ant) 698 if (mvm->cfg->bt_shared_single_ant)
diff --git a/drivers/net/wireless/iwlwifi/mvm/d3.c b/drivers/net/wireless/iwlwifi/mvm/d3.c
index 9bdfa95d6ce7..5f8afa5f11a3 100644
--- a/drivers/net/wireless/iwlwifi/mvm/d3.c
+++ b/drivers/net/wireless/iwlwifi/mvm/d3.c
@@ -694,6 +694,9 @@ static int iwl_mvm_d3_reprogram(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
694 if (ret) 694 if (ret)
695 IWL_ERR(mvm, "Failed to send quota: %d\n", ret); 695 IWL_ERR(mvm, "Failed to send quota: %d\n", ret);
696 696
697 if (iwl_mvm_is_lar_supported(mvm) && iwl_mvm_init_fw_regd(mvm))
698 IWL_ERR(mvm, "Failed to initialize D3 LAR information\n");
699
697 return 0; 700 return 0;
698} 701}
699 702
@@ -1596,7 +1599,7 @@ iwl_mvm_get_wakeup_status(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
1596 1599
1597 /* RF-kill already asserted again... */ 1600 /* RF-kill already asserted again... */
1598 if (!cmd.resp_pkt) { 1601 if (!cmd.resp_pkt) {
1599 ret = -ERFKILL; 1602 fw_status = ERR_PTR(-ERFKILL);
1600 goto out_free_resp; 1603 goto out_free_resp;
1601 } 1604 }
1602 1605
@@ -1605,7 +1608,7 @@ iwl_mvm_get_wakeup_status(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
1605 len = iwl_rx_packet_payload_len(cmd.resp_pkt); 1608 len = iwl_rx_packet_payload_len(cmd.resp_pkt);
1606 if (len < status_size) { 1609 if (len < status_size) {
1607 IWL_ERR(mvm, "Invalid WoWLAN status response!\n"); 1610 IWL_ERR(mvm, "Invalid WoWLAN status response!\n");
1608 ret = -EIO; 1611 fw_status = ERR_PTR(-EIO);
1609 goto out_free_resp; 1612 goto out_free_resp;
1610 } 1613 }
1611 1614
@@ -1613,7 +1616,7 @@ iwl_mvm_get_wakeup_status(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
1613 if (len != (status_size + 1616 if (len != (status_size +
1614 ALIGN(le32_to_cpu(status->wake_packet_bufsize), 4))) { 1617 ALIGN(le32_to_cpu(status->wake_packet_bufsize), 4))) {
1615 IWL_ERR(mvm, "Invalid WoWLAN status response!\n"); 1618 IWL_ERR(mvm, "Invalid WoWLAN status response!\n");
1616 ret = -EIO; 1619 fw_status = ERR_PTR(-EIO);
1617 goto out_free_resp; 1620 goto out_free_resp;
1618 } 1621 }
1619 1622
@@ -1621,7 +1624,7 @@ iwl_mvm_get_wakeup_status(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
1621 1624
1622out_free_resp: 1625out_free_resp:
1623 iwl_free_resp(&cmd); 1626 iwl_free_resp(&cmd);
1624 return ret ? ERR_PTR(ret) : fw_status; 1627 return fw_status;
1625} 1628}
1626 1629
1627/* releases the MVM mutex */ 1630/* releases the MVM mutex */
@@ -1874,6 +1877,12 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
1874 /* query SRAM first in case we want event logging */ 1877 /* query SRAM first in case we want event logging */
1875 iwl_mvm_read_d3_sram(mvm); 1878 iwl_mvm_read_d3_sram(mvm);
1876 1879
1880 /*
1881 * Query the current location and source from the D3 firmware so we
1882 * can play it back when we re-intiailize the D0 firmware
1883 */
1884 iwl_mvm_update_changed_regdom(mvm);
1885
1877 if (mvm->net_detect) { 1886 if (mvm->net_detect) {
1878 iwl_mvm_query_netdetect_reasons(mvm, vif); 1887 iwl_mvm_query_netdetect_reasons(mvm, vif);
1879 /* has unlocked the mutex, so skip that */ 1888 /* has unlocked the mutex, so skip that */
@@ -1883,9 +1892,9 @@ static int __iwl_mvm_resume(struct iwl_mvm *mvm, bool test)
1883#ifdef CONFIG_IWLWIFI_DEBUGFS 1892#ifdef CONFIG_IWLWIFI_DEBUGFS
1884 if (keep) 1893 if (keep)
1885 mvm->keep_vif = vif; 1894 mvm->keep_vif = vif;
1895#endif
1886 /* has unlocked the mutex, so skip that */ 1896 /* has unlocked the mutex, so skip that */
1887 goto out_iterate; 1897 goto out_iterate;
1888#endif
1889 } 1898 }
1890 1899
1891 out_unlock: 1900 out_unlock:
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
index 8cbe77dc1dbb..8c5229892e57 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
@@ -562,11 +562,12 @@ static ssize_t iwl_dbgfs_bt_cmd_read(struct file *file, char __user *user_buf,
562 "\tSecondary Channel Bitmap 0x%016llx\n", 562 "\tSecondary Channel Bitmap 0x%016llx\n",
563 le64_to_cpu(cmd->bt_secondary_ci)); 563 le64_to_cpu(cmd->bt_secondary_ci));
564 564
565 pos += scnprintf(buf+pos, bufsz-pos, "BT Configuration CMD\n"); 565 pos += scnprintf(buf+pos, bufsz-pos,
566 pos += scnprintf(buf+pos, bufsz-pos, "\tACK Kill Mask 0x%08x\n", 566 "BT Configuration CMD - 0=default, 1=never, 2=always\n");
567 iwl_bt_ctl_kill_msk[mvm->bt_ack_kill_msk[0]]); 567 pos += scnprintf(buf+pos, bufsz-pos, "\tACK Kill msk idx %d\n",
568 pos += scnprintf(buf+pos, bufsz-pos, "\tCTS Kill Mask 0x%08x\n", 568 mvm->bt_ack_kill_msk[0]);
569 iwl_bt_ctl_kill_msk[mvm->bt_cts_kill_msk[0]]); 569 pos += scnprintf(buf+pos, bufsz-pos, "\tCTS Kill msk idx %d\n",
570 mvm->bt_cts_kill_msk[0]);
570 571
571 } else { 572 } else {
572 struct iwl_bt_coex_ci_cmd *cmd = &mvm->last_bt_ci_cmd; 573 struct iwl_bt_coex_ci_cmd *cmd = &mvm->last_bt_ci_cmd;
@@ -579,21 +580,6 @@ static ssize_t iwl_dbgfs_bt_cmd_read(struct file *file, char __user *user_buf,
579 pos += scnprintf(buf+pos, bufsz-pos, 580 pos += scnprintf(buf+pos, bufsz-pos,
580 "\tSecondary Channel Bitmap 0x%016llx\n", 581 "\tSecondary Channel Bitmap 0x%016llx\n",
581 le64_to_cpu(cmd->bt_secondary_ci)); 582 le64_to_cpu(cmd->bt_secondary_ci));
582
583 pos += scnprintf(buf+pos, bufsz-pos, "BT Configuration CMD\n");
584 pos += scnprintf(buf+pos, bufsz-pos,
585 "\tPrimary: ACK Kill Mask 0x%08x\n",
586 iwl_bt_ctl_kill_msk[mvm->bt_ack_kill_msk[0]]);
587 pos += scnprintf(buf+pos, bufsz-pos,
588 "\tPrimary: CTS Kill Mask 0x%08x\n",
589 iwl_bt_ctl_kill_msk[mvm->bt_cts_kill_msk[0]]);
590 pos += scnprintf(buf+pos, bufsz-pos,
591 "\tSecondary: ACK Kill Mask 0x%08x\n",
592 iwl_bt_ctl_kill_msk[mvm->bt_ack_kill_msk[1]]);
593 pos += scnprintf(buf+pos, bufsz-pos,
594 "\tSecondary: CTS Kill Mask 0x%08x\n",
595 iwl_bt_ctl_kill_msk[mvm->bt_cts_kill_msk[1]]);
596
597 } 583 }
598 584
599 mutex_unlock(&mvm->mutex); 585 mutex_unlock(&mvm->mutex);
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h b/drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h
index f3b11897991e..d398a6102805 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api-coex.h
@@ -235,36 +235,12 @@ enum iwl_bt_coex_enabled_modules {
235 * struct iwl_bt_coex_cmd - bt coex configuration command 235 * struct iwl_bt_coex_cmd - bt coex configuration command
236 * @mode: enum %iwl_bt_coex_mode 236 * @mode: enum %iwl_bt_coex_mode
237 * @enabled_modules: enum %iwl_bt_coex_enabled_modules 237 * @enabled_modules: enum %iwl_bt_coex_enabled_modules
238 * @max_kill: max count of Tx retries due to kill from PTA
239 * @override_primary_lut: enum %iwl_bt_coex_lut_type: BT_COEX_INVALID_LUT
240 * should be set by default
241 * @override_secondary_lut: enum %iwl_bt_coex_lut_type: BT_COEX_INVALID_LUT
242 * should be set by default
243 * @bt4_antenna_isolation_thr: antenna threshold value
244 * @bt4_tx_tx_delta_freq_thr: TxTx delta frequency
245 * @bt4_tx_rx_max_freq0: TxRx max frequency
246 * @multiprio_lut: multi priority LUT configuration
247 * @mplut_prio_boost: BT priority boost registers
248 * @decision_lut: PTA decision LUT, per Prio-Ch
249 * 238 *
250 * The structure is used for the BT_COEX command. 239 * The structure is used for the BT_COEX command.
251 */ 240 */
252struct iwl_bt_coex_cmd { 241struct iwl_bt_coex_cmd {
253 __le32 mode; 242 __le32 mode;
254 __le32 enabled_modules; 243 __le32 enabled_modules;
255
256 __le32 max_kill;
257 __le32 override_primary_lut;
258 __le32 override_secondary_lut;
259 __le32 bt4_antenna_isolation_thr;
260
261 __le32 bt4_tx_tx_delta_freq_thr;
262 __le32 bt4_tx_rx_max_freq0;
263
264 __le32 multiprio_lut[BT_COEX_MULTI_PRIO_LUT_SIZE];
265 __le32 mplut_prio_boost[BT_COEX_BOOST_SIZE];
266
267 __le32 decision_lut[BT_COEX_MAX_LUT][BT_COEX_LUT_SIZE];
268} __packed; /* BT_COEX_CMD_API_S_VER_6 */ 244} __packed; /* BT_COEX_CMD_API_S_VER_6 */
269 245
270/** 246/**
@@ -280,29 +256,6 @@ struct iwl_bt_coex_corun_lut_update_cmd {
280} __packed; /* BT_COEX_UPDATE_CORUN_LUT_API_S_VER_1 */ 256} __packed; /* BT_COEX_UPDATE_CORUN_LUT_API_S_VER_1 */
281 257
282/** 258/**
283 * struct iwl_bt_coex_sw_boost - SW boost values
284 * @wifi_tx_prio_boost: SW boost of wifi tx priority
285 * @wifi_rx_prio_boost: SW boost of wifi rx priority
286 * @kill_ack_msk: kill ACK mask. 1 - Tx ACK, 0 - kill Tx of ACK.
287 * @kill_cts_msk: kill CTS mask. 1 - Tx CTS, 0 - kill Tx of CTS.
288 */
289struct iwl_bt_coex_sw_boost {
290 __le32 wifi_tx_prio_boost;
291 __le32 wifi_rx_prio_boost;
292 __le32 kill_ack_msk;
293 __le32 kill_cts_msk;
294};
295
296/**
297 * struct iwl_bt_coex_sw_boost_update_cmd - command to update the SW boost
298 * @boost_values: check struct %iwl_bt_coex_sw_boost - one for each channel
299 * primary / secondary / low priority
300 */
301struct iwl_bt_coex_sw_boost_update_cmd {
302 struct iwl_bt_coex_sw_boost boost_values[3];
303} __packed; /* BT_COEX_UPDATE_SW_BOOST_S_VER_1 */
304
305/**
306 * struct iwl_bt_coex_reduced_txp_update_cmd 259 * struct iwl_bt_coex_reduced_txp_update_cmd
307 * @reduced_txp: bit BT_REDUCED_TX_POWER_BIT to enable / disable, rest of the 260 * @reduced_txp: bit BT_REDUCED_TX_POWER_BIT to enable / disable, rest of the
308 * bits are the sta_id (value) 261 * bits are the sta_id (value)
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
index d95b47213731..aab68cbae754 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
@@ -212,6 +212,10 @@ enum {
212 REPLY_RX_MPDU_CMD = 0xc1, 212 REPLY_RX_MPDU_CMD = 0xc1,
213 BA_NOTIF = 0xc5, 213 BA_NOTIF = 0xc5,
214 214
215 /* Location Aware Regulatory */
216 MCC_UPDATE_CMD = 0xc8,
217 MCC_CHUB_UPDATE_CMD = 0xc9,
218
215 MARKER_CMD = 0xcb, 219 MARKER_CMD = 0xcb,
216 220
217 /* BT Coex */ 221 /* BT Coex */
@@ -362,7 +366,8 @@ enum {
362 NVM_SECTION_TYPE_CALIBRATION = 4, 366 NVM_SECTION_TYPE_CALIBRATION = 4,
363 NVM_SECTION_TYPE_PRODUCTION = 5, 367 NVM_SECTION_TYPE_PRODUCTION = 5,
364 NVM_SECTION_TYPE_MAC_OVERRIDE = 11, 368 NVM_SECTION_TYPE_MAC_OVERRIDE = 11,
365 NVM_MAX_NUM_SECTIONS = 12, 369 NVM_SECTION_TYPE_PHY_SKU = 12,
370 NVM_MAX_NUM_SECTIONS = 13,
366}; 371};
367 372
368/** 373/**
@@ -1442,7 +1447,19 @@ enum iwl_sf_scenario {
1442#define SF_W_MARK_LEGACY 4096 1447#define SF_W_MARK_LEGACY 4096
1443#define SF_W_MARK_SCAN 4096 1448#define SF_W_MARK_SCAN 4096
1444 1449
1445/* SF Scenarios timers for FULL_ON state (aligned to 32 uSec) */ 1450/* SF Scenarios timers for default configuration (aligned to 32 uSec) */
1451#define SF_SINGLE_UNICAST_IDLE_TIMER_DEF 160 /* 150 uSec */
1452#define SF_SINGLE_UNICAST_AGING_TIMER_DEF 400 /* 0.4 mSec */
1453#define SF_AGG_UNICAST_IDLE_TIMER_DEF 160 /* 150 uSec */
1454#define SF_AGG_UNICAST_AGING_TIMER_DEF 400 /* 0.4 mSec */
1455#define SF_MCAST_IDLE_TIMER_DEF 160 /* 150 mSec */
1456#define SF_MCAST_AGING_TIMER_DEF 400 /* 0.4 mSec */
1457#define SF_BA_IDLE_TIMER_DEF 160 /* 150 uSec */
1458#define SF_BA_AGING_TIMER_DEF 400 /* 0.4 mSec */
1459#define SF_TX_RE_IDLE_TIMER_DEF 160 /* 150 uSec */
1460#define SF_TX_RE_AGING_TIMER_DEF 400 /* 0.4 mSec */
1461
1462/* SF Scenarios timers for BSS MAC configuration (aligned to 32 uSec) */
1446#define SF_SINGLE_UNICAST_IDLE_TIMER 320 /* 300 uSec */ 1463#define SF_SINGLE_UNICAST_IDLE_TIMER 320 /* 300 uSec */
1447#define SF_SINGLE_UNICAST_AGING_TIMER 2016 /* 2 mSec */ 1464#define SF_SINGLE_UNICAST_AGING_TIMER 2016 /* 2 mSec */
1448#define SF_AGG_UNICAST_IDLE_TIMER 320 /* 300 uSec */ 1465#define SF_AGG_UNICAST_IDLE_TIMER 320 /* 300 uSec */
@@ -1473,6 +1490,92 @@ struct iwl_sf_cfg_cmd {
1473 __le32 full_on_timeouts[SF_NUM_SCENARIO][SF_NUM_TIMEOUT_TYPES]; 1490 __le32 full_on_timeouts[SF_NUM_SCENARIO][SF_NUM_TIMEOUT_TYPES];
1474} __packed; /* SF_CFG_API_S_VER_2 */ 1491} __packed; /* SF_CFG_API_S_VER_2 */
1475 1492
1493/***********************************
1494 * Location Aware Regulatory (LAR) API - MCC updates
1495 ***********************************/
1496
1497/**
1498 * struct iwl_mcc_update_cmd - Request the device to update geographic
1499 * regulatory profile according to the given MCC (Mobile Country Code).
1500 * The MCC is two letter-code, ascii upper case[A-Z] or '00' for world domain.
1501 * 'ZZ' MCC will be used to switch to NVM default profile; in this case, the
1502 * MCC in the cmd response will be the relevant MCC in the NVM.
1503 * @mcc: given mobile country code
1504 * @source_id: the source from where we got the MCC, see iwl_mcc_source
1505 * @reserved: reserved for alignment
1506 */
1507struct iwl_mcc_update_cmd {
1508 __le16 mcc;
1509 u8 source_id;
1510 u8 reserved;
1511} __packed; /* LAR_UPDATE_MCC_CMD_API_S */
1512
1513/**
1514 * iwl_mcc_update_resp - response to MCC_UPDATE_CMD.
1515 * Contains the new channel control profile map, if changed, and the new MCC
1516 * (mobile country code).
1517 * The new MCC may be different than what was requested in MCC_UPDATE_CMD.
1518 * @status: see &enum iwl_mcc_update_status
1519 * @mcc: the new applied MCC
1520 * @cap: capabilities for all channels which matches the MCC
1521 * @source_id: the MCC source, see iwl_mcc_source
1522 * @n_channels: number of channels in @channels_data (may be 14, 39, 50 or 51
1523 * channels, depending on platform)
1524 * @channels: channel control data map, DWORD for each channel. Only the first
1525 * 16bits are used.
1526 */
1527struct iwl_mcc_update_resp {
1528 __le32 status;
1529 __le16 mcc;
1530 u8 cap;
1531 u8 source_id;
1532 __le32 n_channels;
1533 __le32 channels[0];
1534} __packed; /* LAR_UPDATE_MCC_CMD_RESP_S */
1535
1536/**
1537 * struct iwl_mcc_chub_notif - chub notifies of mcc change
1538 * (MCC_CHUB_UPDATE_CMD = 0xc9)
1539 * The Chub (Communication Hub, CommsHUB) is a HW component that connects to
1540 * the cellular and connectivity cores that gets updates of the mcc, and
1541 * notifies the ucode directly of any mcc change.
1542 * The ucode requests the driver to request the device to update geographic
1543 * regulatory profile according to the given MCC (Mobile Country Code).
1544 * The MCC is two letter-code, ascii upper case[A-Z] or '00' for world domain.
1545 * 'ZZ' MCC will be used to switch to NVM default profile; in this case, the
1546 * MCC in the cmd response will be the relevant MCC in the NVM.
1547 * @mcc: given mobile country code
1548 * @source_id: identity of the change originator, see iwl_mcc_source
1549 * @reserved1: reserved for alignment
1550 */
1551struct iwl_mcc_chub_notif {
1552 u16 mcc;
1553 u8 source_id;
1554 u8 reserved1;
1555} __packed; /* LAR_MCC_NOTIFY_S */
1556
1557enum iwl_mcc_update_status {
1558 MCC_RESP_NEW_CHAN_PROFILE,
1559 MCC_RESP_SAME_CHAN_PROFILE,
1560 MCC_RESP_INVALID,
1561 MCC_RESP_NVM_DISABLED,
1562 MCC_RESP_ILLEGAL,
1563 MCC_RESP_LOW_PRIORITY,
1564};
1565
1566enum iwl_mcc_source {
1567 MCC_SOURCE_OLD_FW = 0,
1568 MCC_SOURCE_ME = 1,
1569 MCC_SOURCE_BIOS = 2,
1570 MCC_SOURCE_3G_LTE_HOST = 3,
1571 MCC_SOURCE_3G_LTE_DEVICE = 4,
1572 MCC_SOURCE_WIFI = 5,
1573 MCC_SOURCE_RESERVED = 6,
1574 MCC_SOURCE_DEFAULT = 7,
1575 MCC_SOURCE_UNINITIALIZED = 8,
1576 MCC_SOURCE_GET_CURRENT = 0x10
1577};
1578
1476/* DTS measurements */ 1579/* DTS measurements */
1477 1580
1478enum iwl_dts_measurement_flags { 1581enum iwl_dts_measurement_flags {
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c
index a81da4cde643..6cf7d9837ca5 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/iwlwifi/mvm/fw.c
@@ -739,6 +739,16 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
739 if (ret) 739 if (ret)
740 goto error; 740 goto error;
741 741
742 /*
743 * RTNL is not taken during Ct-kill, but we don't need to scan/Tx
744 * anyway, so don't init MCC.
745 */
746 if (!test_bit(IWL_MVM_STATUS_HW_CTKILL, &mvm->status)) {
747 ret = iwl_mvm_init_mcc(mvm);
748 if (ret)
749 goto error;
750 }
751
742 if (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN) { 752 if (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_UMAC_SCAN) {
743 ret = iwl_mvm_config_scan(mvm); 753 ret = iwl_mvm_config_scan(mvm);
744 if (ret) 754 if (ret)
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index 7396b52262b5..302c8cc50f25 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -86,6 +86,7 @@
86#include "iwl-fw-error-dump.h" 86#include "iwl-fw-error-dump.h"
87#include "iwl-prph.h" 87#include "iwl-prph.h"
88#include "iwl-csr.h" 88#include "iwl-csr.h"
89#include "iwl-nvm-parse.h"
89 90
90static const struct ieee80211_iface_limit iwl_mvm_limits[] = { 91static const struct ieee80211_iface_limit iwl_mvm_limits[] = {
91 { 92 {
@@ -301,6 +302,109 @@ static void iwl_mvm_reset_phy_ctxts(struct iwl_mvm *mvm)
301 } 302 }
302} 303}
303 304
305struct ieee80211_regdomain *iwl_mvm_get_regdomain(struct wiphy *wiphy,
306 const char *alpha2,
307 enum iwl_mcc_source src_id,
308 bool *changed)
309{
310 struct ieee80211_regdomain *regd = NULL;
311 struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
312 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
313 struct iwl_mcc_update_resp *resp;
314
315 IWL_DEBUG_LAR(mvm, "Getting regdomain data for %s from FW\n", alpha2);
316
317 lockdep_assert_held(&mvm->mutex);
318
319 resp = iwl_mvm_update_mcc(mvm, alpha2, src_id);
320 if (IS_ERR_OR_NULL(resp)) {
321 IWL_DEBUG_LAR(mvm, "Could not get update from FW %d\n",
322 PTR_RET(resp));
323 goto out;
324 }
325
326 if (changed)
327 *changed = (resp->status == MCC_RESP_NEW_CHAN_PROFILE);
328
329 regd = iwl_parse_nvm_mcc_info(mvm->trans->dev, mvm->cfg,
330 __le32_to_cpu(resp->n_channels),
331 resp->channels,
332 __le16_to_cpu(resp->mcc));
333 /* Store the return source id */
334 src_id = resp->source_id;
335 kfree(resp);
336 if (IS_ERR_OR_NULL(regd)) {
337 IWL_DEBUG_LAR(mvm, "Could not get parse update from FW %d\n",
338 PTR_RET(regd));
339 goto out;
340 }
341
342 IWL_DEBUG_LAR(mvm, "setting alpha2 from FW to %s (0x%x, 0x%x) src=%d\n",
343 regd->alpha2, regd->alpha2[0], regd->alpha2[1], src_id);
344 mvm->lar_regdom_set = true;
345 mvm->mcc_src = src_id;
346
347out:
348 return regd;
349}
350
351void iwl_mvm_update_changed_regdom(struct iwl_mvm *mvm)
352{
353 bool changed;
354 struct ieee80211_regdomain *regd;
355
356 if (!iwl_mvm_is_lar_supported(mvm))
357 return;
358
359 regd = iwl_mvm_get_current_regdomain(mvm, &changed);
360 if (!IS_ERR_OR_NULL(regd)) {
361 /* only update the regulatory core if changed */
362 if (changed)
363 regulatory_set_wiphy_regd(mvm->hw->wiphy, regd);
364
365 kfree(regd);
366 }
367}
368
369struct ieee80211_regdomain *iwl_mvm_get_current_regdomain(struct iwl_mvm *mvm,
370 bool *changed)
371{
372 return iwl_mvm_get_regdomain(mvm->hw->wiphy, "ZZ",
373 iwl_mvm_is_wifi_mcc_supported(mvm) ?
374 MCC_SOURCE_GET_CURRENT :
375 MCC_SOURCE_OLD_FW, changed);
376}
377
378int iwl_mvm_init_fw_regd(struct iwl_mvm *mvm)
379{
380 enum iwl_mcc_source used_src;
381 struct ieee80211_regdomain *regd;
382 const struct ieee80211_regdomain *r =
383 rtnl_dereference(mvm->hw->wiphy->regd);
384
385 if (!r)
386 return 0;
387
388 /* save the last source in case we overwrite it below */
389 used_src = mvm->mcc_src;
390 if (iwl_mvm_is_wifi_mcc_supported(mvm)) {
391 /* Notify the firmware we support wifi location updates */
392 regd = iwl_mvm_get_current_regdomain(mvm, NULL);
393 if (!IS_ERR_OR_NULL(regd))
394 kfree(regd);
395 }
396
397 /* Now set our last stored MCC and source */
398 regd = iwl_mvm_get_regdomain(mvm->hw->wiphy, r->alpha2, used_src, NULL);
399 if (IS_ERR_OR_NULL(regd))
400 return -EIO;
401
402 regulatory_set_wiphy_regd(mvm->hw->wiphy, regd);
403 kfree(regd);
404
405 return 0;
406}
407
304int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm) 408int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
305{ 409{
306 struct ieee80211_hw *hw = mvm->hw; 410 struct ieee80211_hw *hw = mvm->hw;
@@ -356,8 +460,12 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
356 BIT(NL80211_IFTYPE_ADHOC); 460 BIT(NL80211_IFTYPE_ADHOC);
357 461
358 hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN; 462 hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
359 hw->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG | 463 hw->wiphy->regulatory_flags |= REGULATORY_ENABLE_RELAX_NO_IR;
360 REGULATORY_DISABLE_BEACON_HINTS; 464 if (iwl_mvm_is_lar_supported(mvm))
465 hw->wiphy->regulatory_flags |= REGULATORY_WIPHY_SELF_MANAGED;
466 else
467 hw->wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG |
468 REGULATORY_DISABLE_BEACON_HINTS;
361 469
362 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_GO_UAPSD) 470 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_GO_UAPSD)
363 hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD; 471 hw->wiphy->flags |= WIPHY_FLAG_AP_UAPSD;
@@ -1193,7 +1301,7 @@ static void iwl_mvm_restart_complete(struct iwl_mvm *mvm)
1193 1301
1194 clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status); 1302 clear_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status);
1195 iwl_mvm_d0i3_enable_tx(mvm, NULL); 1303 iwl_mvm_d0i3_enable_tx(mvm, NULL);
1196 ret = iwl_mvm_update_quotas(mvm, NULL); 1304 ret = iwl_mvm_update_quotas(mvm, false, NULL);
1197 if (ret) 1305 if (ret)
1198 IWL_ERR(mvm, "Failed to update quotas after restart (%d)\n", 1306 IWL_ERR(mvm, "Failed to update quotas after restart (%d)\n",
1199 ret); 1307 ret);
@@ -1872,7 +1980,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
1872 sizeof(mvmvif->beacon_stats)); 1980 sizeof(mvmvif->beacon_stats));
1873 1981
1874 /* add quota for this interface */ 1982 /* add quota for this interface */
1875 ret = iwl_mvm_update_quotas(mvm, NULL); 1983 ret = iwl_mvm_update_quotas(mvm, true, NULL);
1876 if (ret) { 1984 if (ret) {
1877 IWL_ERR(mvm, "failed to update quotas\n"); 1985 IWL_ERR(mvm, "failed to update quotas\n");
1878 return; 1986 return;
@@ -1924,7 +2032,7 @@ static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
1924 mvm->d0i3_ap_sta_id = IWL_MVM_STATION_COUNT; 2032 mvm->d0i3_ap_sta_id = IWL_MVM_STATION_COUNT;
1925 mvmvif->ap_sta_id = IWL_MVM_STATION_COUNT; 2033 mvmvif->ap_sta_id = IWL_MVM_STATION_COUNT;
1926 /* remove quota for this interface */ 2034 /* remove quota for this interface */
1927 ret = iwl_mvm_update_quotas(mvm, NULL); 2035 ret = iwl_mvm_update_quotas(mvm, false, NULL);
1928 if (ret) 2036 if (ret)
1929 IWL_ERR(mvm, "failed to update quotas\n"); 2037 IWL_ERR(mvm, "failed to update quotas\n");
1930 2038
@@ -2043,7 +2151,7 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw,
2043 /* power updated needs to be done before quotas */ 2151 /* power updated needs to be done before quotas */
2044 iwl_mvm_power_update_mac(mvm); 2152 iwl_mvm_power_update_mac(mvm);
2045 2153
2046 ret = iwl_mvm_update_quotas(mvm, NULL); 2154 ret = iwl_mvm_update_quotas(mvm, false, NULL);
2047 if (ret) 2155 if (ret)
2048 goto out_quota_failed; 2156 goto out_quota_failed;
2049 2157
@@ -2109,7 +2217,7 @@ static void iwl_mvm_stop_ap_ibss(struct ieee80211_hw *hw,
2109 if (vif->p2p && mvm->p2p_device_vif) 2217 if (vif->p2p && mvm->p2p_device_vif)
2110 iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif, false, NULL); 2218 iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif, false, NULL);
2111 2219
2112 iwl_mvm_update_quotas(mvm, NULL); 2220 iwl_mvm_update_quotas(mvm, false, NULL);
2113 iwl_mvm_send_rm_bcast_sta(mvm, vif); 2221 iwl_mvm_send_rm_bcast_sta(mvm, vif);
2114 iwl_mvm_binding_remove_vif(mvm, vif); 2222 iwl_mvm_binding_remove_vif(mvm, vif);
2115 2223
@@ -2248,6 +2356,12 @@ static int iwl_mvm_mac_hw_scan(struct ieee80211_hw *hw,
2248 2356
2249 mutex_lock(&mvm->mutex); 2357 mutex_lock(&mvm->mutex);
2250 2358
2359 if (iwl_mvm_is_lar_supported(mvm) && !mvm->lar_regdom_set) {
2360 IWL_ERR(mvm, "scan while LAR regdomain is not set\n");
2361 ret = -EBUSY;
2362 goto out;
2363 }
2364
2251 if (mvm->scan_status != IWL_MVM_SCAN_NONE) { 2365 if (mvm->scan_status != IWL_MVM_SCAN_NONE) {
2252 ret = -EBUSY; 2366 ret = -EBUSY;
2253 goto out; 2367 goto out;
@@ -2328,25 +2442,35 @@ static void iwl_mvm_mac_sta_notify(struct ieee80211_hw *hw,
2328{ 2442{
2329 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 2443 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
2330 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta); 2444 struct iwl_mvm_sta *mvmsta = iwl_mvm_sta_from_mac80211(sta);
2445 unsigned long txqs = 0, tids = 0;
2331 int tid; 2446 int tid;
2332 2447
2448 spin_lock_bh(&mvmsta->lock);
2449 for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) {
2450 struct iwl_mvm_tid_data *tid_data = &mvmsta->tid_data[tid];
2451
2452 if (tid_data->state != IWL_AGG_ON &&
2453 tid_data->state != IWL_EMPTYING_HW_QUEUE_DELBA)
2454 continue;
2455
2456 __set_bit(tid_data->txq_id, &txqs);
2457
2458 if (iwl_mvm_tid_queued(tid_data) == 0)
2459 continue;
2460
2461 __set_bit(tid, &tids);
2462 }
2463
2333 switch (cmd) { 2464 switch (cmd) {
2334 case STA_NOTIFY_SLEEP: 2465 case STA_NOTIFY_SLEEP:
2335 if (atomic_read(&mvm->pending_frames[mvmsta->sta_id]) > 0) 2466 if (atomic_read(&mvm->pending_frames[mvmsta->sta_id]) > 0)
2336 ieee80211_sta_block_awake(hw, sta, true); 2467 ieee80211_sta_block_awake(hw, sta, true);
2337 spin_lock_bh(&mvmsta->lock);
2338 for (tid = 0; tid < IWL_MAX_TID_COUNT; tid++) {
2339 struct iwl_mvm_tid_data *tid_data;
2340 2468
2341 tid_data = &mvmsta->tid_data[tid]; 2469 for_each_set_bit(tid, &tids, IWL_MAX_TID_COUNT)
2342 if (tid_data->state != IWL_AGG_ON &&
2343 tid_data->state != IWL_EMPTYING_HW_QUEUE_DELBA)
2344 continue;
2345 if (iwl_mvm_tid_queued(tid_data) == 0)
2346 continue;
2347 ieee80211_sta_set_buffered(sta, tid, true); 2470 ieee80211_sta_set_buffered(sta, tid, true);
2348 } 2471
2349 spin_unlock_bh(&mvmsta->lock); 2472 if (txqs)
2473 iwl_trans_freeze_txq_timer(mvm->trans, txqs, true);
2350 /* 2474 /*
2351 * The fw updates the STA to be asleep. Tx packets on the Tx 2475 * The fw updates the STA to be asleep. Tx packets on the Tx
2352 * queues to this station will not be transmitted. The fw will 2476 * queues to this station will not be transmitted. The fw will
@@ -2356,11 +2480,15 @@ static void iwl_mvm_mac_sta_notify(struct ieee80211_hw *hw,
2356 case STA_NOTIFY_AWAKE: 2480 case STA_NOTIFY_AWAKE:
2357 if (WARN_ON(mvmsta->sta_id == IWL_MVM_STATION_COUNT)) 2481 if (WARN_ON(mvmsta->sta_id == IWL_MVM_STATION_COUNT))
2358 break; 2482 break;
2483
2484 if (txqs)
2485 iwl_trans_freeze_txq_timer(mvm->trans, txqs, false);
2359 iwl_mvm_sta_modify_ps_wake(mvm, sta); 2486 iwl_mvm_sta_modify_ps_wake(mvm, sta);
2360 break; 2487 break;
2361 default: 2488 default:
2362 break; 2489 break;
2363 } 2490 }
2491 spin_unlock_bh(&mvmsta->lock);
2364} 2492}
2365 2493
2366static void iwl_mvm_sta_pre_rcu_remove(struct ieee80211_hw *hw, 2494static void iwl_mvm_sta_pre_rcu_remove(struct ieee80211_hw *hw,
@@ -2598,6 +2726,12 @@ static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw,
2598 2726
2599 mutex_lock(&mvm->mutex); 2727 mutex_lock(&mvm->mutex);
2600 2728
2729 if (iwl_mvm_is_lar_supported(mvm) && !mvm->lar_regdom_set) {
2730 IWL_ERR(mvm, "sched-scan while LAR regdomain is not set\n");
2731 ret = -EBUSY;
2732 goto out;
2733 }
2734
2601 if (!vif->bss_conf.idle) { 2735 if (!vif->bss_conf.idle) {
2602 ret = -EBUSY; 2736 ret = -EBUSY;
2603 goto out; 2737 goto out;
@@ -3159,14 +3293,14 @@ static int __iwl_mvm_assign_vif_chanctx(struct iwl_mvm *mvm,
3159 */ 3293 */
3160 if (vif->type == NL80211_IFTYPE_MONITOR) { 3294 if (vif->type == NL80211_IFTYPE_MONITOR) {
3161 mvmvif->monitor_active = true; 3295 mvmvif->monitor_active = true;
3162 ret = iwl_mvm_update_quotas(mvm, NULL); 3296 ret = iwl_mvm_update_quotas(mvm, false, NULL);
3163 if (ret) 3297 if (ret)
3164 goto out_remove_binding; 3298 goto out_remove_binding;
3165 } 3299 }
3166 3300
3167 /* Handle binding during CSA */ 3301 /* Handle binding during CSA */
3168 if (vif->type == NL80211_IFTYPE_AP) { 3302 if (vif->type == NL80211_IFTYPE_AP) {
3169 iwl_mvm_update_quotas(mvm, NULL); 3303 iwl_mvm_update_quotas(mvm, false, NULL);
3170 iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL); 3304 iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL);
3171 } 3305 }
3172 3306
@@ -3190,7 +3324,7 @@ static int __iwl_mvm_assign_vif_chanctx(struct iwl_mvm *mvm,
3190 3324
3191 iwl_mvm_unref(mvm, IWL_MVM_REF_PROTECT_CSA); 3325 iwl_mvm_unref(mvm, IWL_MVM_REF_PROTECT_CSA);
3192 3326
3193 iwl_mvm_update_quotas(mvm, NULL); 3327 iwl_mvm_update_quotas(mvm, false, NULL);
3194 } 3328 }
3195 3329
3196 goto out; 3330 goto out;
@@ -3263,7 +3397,7 @@ static void __iwl_mvm_unassign_vif_chanctx(struct iwl_mvm *mvm,
3263 break; 3397 break;
3264 } 3398 }
3265 3399
3266 iwl_mvm_update_quotas(mvm, disabled_vif); 3400 iwl_mvm_update_quotas(mvm, false, disabled_vif);
3267 iwl_mvm_binding_remove_vif(mvm, vif); 3401 iwl_mvm_binding_remove_vif(mvm, vif);
3268 3402
3269out: 3403out:
@@ -3455,7 +3589,7 @@ static int __iwl_mvm_mac_testmode_cmd(struct iwl_mvm *mvm,
3455 mvm->noa_duration = noa_duration; 3589 mvm->noa_duration = noa_duration;
3456 mvm->noa_vif = vif; 3590 mvm->noa_vif = vif;
3457 3591
3458 return iwl_mvm_update_quotas(mvm, NULL); 3592 return iwl_mvm_update_quotas(mvm, false, NULL);
3459 case IWL_MVM_TM_CMD_SET_BEACON_FILTER: 3593 case IWL_MVM_TM_CMD_SET_BEACON_FILTER:
3460 /* must be associated client vif - ignore authorized */ 3594 /* must be associated client vif - ignore authorized */
3461 if (!vif || vif->type != NL80211_IFTYPE_STATION || 3595 if (!vif || vif->type != NL80211_IFTYPE_STATION ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index 95cad68ab069..4b5c8f66df8b 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -810,6 +810,9 @@ struct iwl_mvm {
810 /* system time of last beacon (for AP/GO interface) */ 810 /* system time of last beacon (for AP/GO interface) */
811 u32 ap_last_beacon_gp2; 811 u32 ap_last_beacon_gp2;
812 812
813 bool lar_regdom_set;
814 enum iwl_mcc_source mcc_src;
815
813 u8 low_latency_agg_frame_limit; 816 u8 low_latency_agg_frame_limit;
814 817
815 /* TDLS channel switch data */ 818 /* TDLS channel switch data */
@@ -910,6 +913,30 @@ static inline bool iwl_mvm_is_d0i3_supported(struct iwl_mvm *mvm)
910 (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_D0I3_SUPPORT); 913 (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_D0I3_SUPPORT);
911} 914}
912 915
916static inline bool iwl_mvm_is_lar_supported(struct iwl_mvm *mvm)
917{
918 bool nvm_lar = mvm->nvm_data->lar_enabled;
919 bool tlv_lar = mvm->fw->ucode_capa.capa[0] &
920 IWL_UCODE_TLV_CAPA_LAR_SUPPORT;
921
922 if (iwlwifi_mod_params.lar_disable)
923 return false;
924
925 /*
926 * Enable LAR only if it is supported by the FW (TLV) &&
927 * enabled in the NVM
928 */
929 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_8000)
930 return nvm_lar && tlv_lar;
931 else
932 return tlv_lar;
933}
934
935static inline bool iwl_mvm_is_wifi_mcc_supported(struct iwl_mvm *mvm)
936{
937 return mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_WIFI_MCC_UPDATE;
938}
939
913static inline bool iwl_mvm_is_scd_cfg_supported(struct iwl_mvm *mvm) 940static inline bool iwl_mvm_is_scd_cfg_supported(struct iwl_mvm *mvm)
914{ 941{
915 return mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_SCD_CFG; 942 return mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_SCD_CFG;
@@ -921,6 +948,12 @@ static inline bool iwl_mvm_bt_is_plcr_supported(struct iwl_mvm *mvm)
921 IWL_MVM_BT_COEX_CORUNNING; 948 IWL_MVM_BT_COEX_CORUNNING;
922} 949}
923 950
951static inline bool iwl_mvm_bt_is_rrc_supported(struct iwl_mvm *mvm)
952{
953 return (mvm->fw->ucode_capa.capa[0] & IWL_UCODE_TLV_CAPA_BT_COEX_RRC) &&
954 IWL_MVM_BT_COEX_RRC;
955}
956
924extern const u8 iwl_mvm_ac_to_tx_fifo[]; 957extern const u8 iwl_mvm_ac_to_tx_fifo[];
925 958
926struct iwl_rate_info { 959struct iwl_rate_info {
@@ -1106,7 +1139,7 @@ int iwl_mvm_binding_add_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
1106int iwl_mvm_binding_remove_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif); 1139int iwl_mvm_binding_remove_vif(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
1107 1140
1108/* Quota management */ 1141/* Quota management */
1109int iwl_mvm_update_quotas(struct iwl_mvm *mvm, 1142int iwl_mvm_update_quotas(struct iwl_mvm *mvm, bool force_upload,
1110 struct ieee80211_vif *disabled_vif); 1143 struct ieee80211_vif *disabled_vif);
1111 1144
1112/* Scanning */ 1145/* Scanning */
@@ -1282,17 +1315,6 @@ int iwl_mvm_rx_ant_coupling_notif_old(struct iwl_mvm *mvm,
1282 struct iwl_rx_cmd_buffer *rxb, 1315 struct iwl_rx_cmd_buffer *rxb,
1283 struct iwl_device_cmd *cmd); 1316 struct iwl_device_cmd *cmd);
1284 1317
1285enum iwl_bt_kill_msk {
1286 BT_KILL_MSK_DEFAULT,
1287 BT_KILL_MSK_NEVER,
1288 BT_KILL_MSK_ALWAYS,
1289 BT_KILL_MSK_MAX,
1290};
1291
1292extern const u8 iwl_bt_ack_kill_msk[BT_MAX_AG][BT_COEX_MAX_LUT];
1293extern const u8 iwl_bt_cts_kill_msk[BT_MAX_AG][BT_COEX_MAX_LUT];
1294extern const u32 iwl_bt_ctl_kill_msk[BT_KILL_MSK_MAX];
1295
1296/* beacon filtering */ 1318/* beacon filtering */
1297#ifdef CONFIG_IWLWIFI_DEBUGFS 1319#ifdef CONFIG_IWLWIFI_DEBUGFS
1298void 1320void
@@ -1389,6 +1411,23 @@ void iwl_mvm_tt_exit(struct iwl_mvm *mvm);
1389void iwl_mvm_set_hw_ctkill_state(struct iwl_mvm *mvm, bool state); 1411void iwl_mvm_set_hw_ctkill_state(struct iwl_mvm *mvm, bool state);
1390int iwl_mvm_get_temp(struct iwl_mvm *mvm); 1412int iwl_mvm_get_temp(struct iwl_mvm *mvm);
1391 1413
1414/* Location Aware Regulatory */
1415struct iwl_mcc_update_resp *
1416iwl_mvm_update_mcc(struct iwl_mvm *mvm, const char *alpha2,
1417 enum iwl_mcc_source src_id);
1418int iwl_mvm_init_mcc(struct iwl_mvm *mvm);
1419int iwl_mvm_rx_chub_update_mcc(struct iwl_mvm *mvm,
1420 struct iwl_rx_cmd_buffer *rxb,
1421 struct iwl_device_cmd *cmd);
1422struct ieee80211_regdomain *iwl_mvm_get_regdomain(struct wiphy *wiphy,
1423 const char *alpha2,
1424 enum iwl_mcc_source src_id,
1425 bool *changed);
1426struct ieee80211_regdomain *iwl_mvm_get_current_regdomain(struct iwl_mvm *mvm,
1427 bool *changed);
1428int iwl_mvm_init_fw_regd(struct iwl_mvm *mvm);
1429void iwl_mvm_update_changed_regdom(struct iwl_mvm *mvm);
1430
1392/* smart fifo */ 1431/* smart fifo */
1393int iwl_mvm_sf_update(struct iwl_mvm *mvm, struct ieee80211_vif *vif, 1432int iwl_mvm_sf_update(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
1394 bool added_vif); 1433 bool added_vif);
diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c
index 5383429d96c1..123e0a16aea8 100644
--- a/drivers/net/wireless/iwlwifi/mvm/nvm.c
+++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c
@@ -63,12 +63,16 @@
63 * 63 *
64 *****************************************************************************/ 64 *****************************************************************************/
65#include <linux/firmware.h> 65#include <linux/firmware.h>
66#include <linux/rtnetlink.h>
67#include <linux/pci.h>
68#include <linux/acpi.h>
66#include "iwl-trans.h" 69#include "iwl-trans.h"
67#include "iwl-csr.h" 70#include "iwl-csr.h"
68#include "mvm.h" 71#include "mvm.h"
69#include "iwl-eeprom-parse.h" 72#include "iwl-eeprom-parse.h"
70#include "iwl-eeprom-read.h" 73#include "iwl-eeprom-read.h"
71#include "iwl-nvm-parse.h" 74#include "iwl-nvm-parse.h"
75#include "iwl-prph.h"
72 76
73/* Default NVM size to read */ 77/* Default NVM size to read */
74#define IWL_NVM_DEFAULT_CHUNK_SIZE (2*1024) 78#define IWL_NVM_DEFAULT_CHUNK_SIZE (2*1024)
@@ -262,7 +266,9 @@ static struct iwl_nvm_data *
262iwl_parse_nvm_sections(struct iwl_mvm *mvm) 266iwl_parse_nvm_sections(struct iwl_mvm *mvm)
263{ 267{
264 struct iwl_nvm_section *sections = mvm->nvm_sections; 268 struct iwl_nvm_section *sections = mvm->nvm_sections;
265 const __le16 *hw, *sw, *calib, *regulatory, *mac_override; 269 const __le16 *hw, *sw, *calib, *regulatory, *mac_override, *phy_sku;
270 bool is_family_8000_a_step = false, lar_enabled;
271 u32 mac_addr0, mac_addr1;
266 272
267 /* Checking for required sections */ 273 /* Checking for required sections */
268 if (mvm->trans->cfg->device_family != IWL_DEVICE_FAMILY_8000) { 274 if (mvm->trans->cfg->device_family != IWL_DEVICE_FAMILY_8000) {
@@ -286,22 +292,43 @@ iwl_parse_nvm_sections(struct iwl_mvm *mvm)
286 "Can't parse mac_address, empty sections\n"); 292 "Can't parse mac_address, empty sections\n");
287 return NULL; 293 return NULL;
288 } 294 }
295
296 if (CSR_HW_REV_STEP(mvm->trans->hw_rev) == SILICON_A_STEP)
297 is_family_8000_a_step = true;
298
299 /* PHY_SKU section is mandatory in B0 */
300 if (!is_family_8000_a_step &&
301 !mvm->nvm_sections[NVM_SECTION_TYPE_PHY_SKU].data) {
302 IWL_ERR(mvm,
303 "Can't parse phy_sku in B0, empty sections\n");
304 return NULL;
305 }
289 } 306 }
290 307
291 if (WARN_ON(!mvm->cfg)) 308 if (WARN_ON(!mvm->cfg))
292 return NULL; 309 return NULL;
293 310
311 /* read the mac address from WFMP registers */
312 mac_addr0 = iwl_trans_read_prph(mvm->trans, WFMP_MAC_ADDR_0);
313 mac_addr1 = iwl_trans_read_prph(mvm->trans, WFMP_MAC_ADDR_1);
314
294 hw = (const __le16 *)sections[mvm->cfg->nvm_hw_section_num].data; 315 hw = (const __le16 *)sections[mvm->cfg->nvm_hw_section_num].data;
295 sw = (const __le16 *)sections[NVM_SECTION_TYPE_SW].data; 316 sw = (const __le16 *)sections[NVM_SECTION_TYPE_SW].data;
296 calib = (const __le16 *)sections[NVM_SECTION_TYPE_CALIBRATION].data; 317 calib = (const __le16 *)sections[NVM_SECTION_TYPE_CALIBRATION].data;
297 regulatory = (const __le16 *)sections[NVM_SECTION_TYPE_REGULATORY].data; 318 regulatory = (const __le16 *)sections[NVM_SECTION_TYPE_REGULATORY].data;
298 mac_override = 319 mac_override =
299 (const __le16 *)sections[NVM_SECTION_TYPE_MAC_OVERRIDE].data; 320 (const __le16 *)sections[NVM_SECTION_TYPE_MAC_OVERRIDE].data;
321 phy_sku = (const __le16 *)sections[NVM_SECTION_TYPE_PHY_SKU].data;
322
323 lar_enabled = !iwlwifi_mod_params.lar_disable &&
324 (mvm->fw->ucode_capa.capa[0] &
325 IWL_UCODE_TLV_CAPA_LAR_SUPPORT);
300 326
301 return iwl_parse_nvm_data(mvm->trans->dev, mvm->cfg, hw, sw, calib, 327 return iwl_parse_nvm_data(mvm->trans->dev, mvm->cfg, hw, sw, calib,
302 regulatory, mac_override, 328 regulatory, mac_override, phy_sku,
303 mvm->fw->valid_tx_ant, 329 mvm->fw->valid_tx_ant, mvm->fw->valid_rx_ant,
304 mvm->fw->valid_rx_ant); 330 lar_enabled, is_family_8000_a_step,
331 mac_addr0, mac_addr1);
305} 332}
306 333
307#define MAX_NVM_FILE_LEN 16384 334#define MAX_NVM_FILE_LEN 16384
@@ -570,3 +597,258 @@ int iwl_nvm_init(struct iwl_mvm *mvm, bool read_nvm_from_nic)
570 597
571 return 0; 598 return 0;
572} 599}
600
601struct iwl_mcc_update_resp *
602iwl_mvm_update_mcc(struct iwl_mvm *mvm, const char *alpha2,
603 enum iwl_mcc_source src_id)
604{
605 struct iwl_mcc_update_cmd mcc_update_cmd = {
606 .mcc = cpu_to_le16(alpha2[0] << 8 | alpha2[1]),
607 .source_id = (u8)src_id,
608 };
609 struct iwl_mcc_update_resp *mcc_resp, *resp_cp = NULL;
610 struct iwl_rx_packet *pkt;
611 struct iwl_host_cmd cmd = {
612 .id = MCC_UPDATE_CMD,
613 .flags = CMD_WANT_SKB,
614 .data = { &mcc_update_cmd },
615 };
616
617 int ret;
618 u32 status;
619 int resp_len, n_channels;
620 u16 mcc;
621
622 if (WARN_ON_ONCE(!iwl_mvm_is_lar_supported(mvm)))
623 return ERR_PTR(-EOPNOTSUPP);
624
625 cmd.len[0] = sizeof(struct iwl_mcc_update_cmd);
626
627 IWL_DEBUG_LAR(mvm, "send MCC update to FW with '%c%c' src = %d\n",
628 alpha2[0], alpha2[1], src_id);
629
630 ret = iwl_mvm_send_cmd(mvm, &cmd);
631 if (ret)
632 return ERR_PTR(ret);
633
634 pkt = cmd.resp_pkt;
635 if (pkt->hdr.flags & IWL_CMD_FAILED_MSK) {
636 IWL_ERR(mvm, "Bad return from MCC_UPDATE_COMMAND (0x%08X)\n",
637 pkt->hdr.flags);
638 ret = -EIO;
639 goto exit;
640 }
641
642 /* Extract MCC response */
643 mcc_resp = (void *)pkt->data;
644 status = le32_to_cpu(mcc_resp->status);
645
646 mcc = le16_to_cpu(mcc_resp->mcc);
647
648 /* W/A for a FW/NVM issue - returns 0x00 for the world domain */
649 if (mcc == 0) {
650 mcc = 0x3030; /* "00" - world */
651 mcc_resp->mcc = cpu_to_le16(mcc);
652 }
653
654 n_channels = __le32_to_cpu(mcc_resp->n_channels);
655 IWL_DEBUG_LAR(mvm,
656 "MCC response status: 0x%x. new MCC: 0x%x ('%c%c') change: %d n_chans: %d\n",
657 status, mcc, mcc >> 8, mcc & 0xff,
658 !!(status == MCC_RESP_NEW_CHAN_PROFILE), n_channels);
659
660 resp_len = sizeof(*mcc_resp) + n_channels * sizeof(__le32);
661 resp_cp = kmemdup(mcc_resp, resp_len, GFP_KERNEL);
662 if (!resp_cp) {
663 ret = -ENOMEM;
664 goto exit;
665 }
666
667 ret = 0;
668exit:
669 iwl_free_resp(&cmd);
670 if (ret)
671 return ERR_PTR(ret);
672 return resp_cp;
673}
674
675#ifdef CONFIG_ACPI
676#define WRD_METHOD "WRDD"
677#define WRDD_WIFI (0x07)
678#define WRDD_WIGIG (0x10)
679
680static u32 iwl_mvm_wrdd_get_mcc(struct iwl_mvm *mvm, union acpi_object *wrdd)
681{
682 union acpi_object *mcc_pkg, *domain_type, *mcc_value;
683 u32 i;
684
685 if (wrdd->type != ACPI_TYPE_PACKAGE ||
686 wrdd->package.count < 2 ||
687 wrdd->package.elements[0].type != ACPI_TYPE_INTEGER ||
688 wrdd->package.elements[0].integer.value != 0) {
689 IWL_DEBUG_LAR(mvm, "Unsupported wrdd structure\n");
690 return 0;
691 }
692
693 for (i = 1 ; i < wrdd->package.count ; ++i) {
694 mcc_pkg = &wrdd->package.elements[i];
695
696 if (mcc_pkg->type != ACPI_TYPE_PACKAGE ||
697 mcc_pkg->package.count < 2 ||
698 mcc_pkg->package.elements[0].type != ACPI_TYPE_INTEGER ||
699 mcc_pkg->package.elements[1].type != ACPI_TYPE_INTEGER) {
700 mcc_pkg = NULL;
701 continue;
702 }
703
704 domain_type = &mcc_pkg->package.elements[0];
705 if (domain_type->integer.value == WRDD_WIFI)
706 break;
707
708 mcc_pkg = NULL;
709 }
710
711 if (mcc_pkg) {
712 mcc_value = &mcc_pkg->package.elements[1];
713 return mcc_value->integer.value;
714 }
715
716 return 0;
717}
718
719static int iwl_mvm_get_bios_mcc(struct iwl_mvm *mvm, char *mcc)
720{
721 acpi_handle root_handle;
722 acpi_handle handle;
723 struct acpi_buffer wrdd = {ACPI_ALLOCATE_BUFFER, NULL};
724 acpi_status status;
725 u32 mcc_val;
726 struct pci_dev *pdev = to_pci_dev(mvm->dev);
727
728 root_handle = ACPI_HANDLE(&pdev->dev);
729 if (!root_handle) {
730 IWL_DEBUG_LAR(mvm,
731 "Could not retrieve root port ACPI handle\n");
732 return -ENOENT;
733 }
734
735 /* Get the method's handle */
736 status = acpi_get_handle(root_handle, (acpi_string)WRD_METHOD, &handle);
737 if (ACPI_FAILURE(status)) {
738 IWL_DEBUG_LAR(mvm, "WRD method not found\n");
739 return -ENOENT;
740 }
741
742 /* Call WRDD with no arguments */
743 status = acpi_evaluate_object(handle, NULL, NULL, &wrdd);
744 if (ACPI_FAILURE(status)) {
745 IWL_DEBUG_LAR(mvm, "WRDC invocation failed (0x%x)\n", status);
746 return -ENOENT;
747 }
748
749 mcc_val = iwl_mvm_wrdd_get_mcc(mvm, wrdd.pointer);
750 kfree(wrdd.pointer);
751 if (!mcc_val)
752 return -ENOENT;
753
754 mcc[0] = (mcc_val >> 8) & 0xff;
755 mcc[1] = mcc_val & 0xff;
756 mcc[2] = '\0';
757 return 0;
758}
759#else /* CONFIG_ACPI */
760static int iwl_mvm_get_bios_mcc(struct iwl_mvm *mvm, char *mcc)
761{
762 return -ENOENT;
763}
764#endif
765
766int iwl_mvm_init_mcc(struct iwl_mvm *mvm)
767{
768 bool tlv_lar;
769 bool nvm_lar;
770 int retval;
771 struct ieee80211_regdomain *regd;
772 char mcc[3];
773
774 if (mvm->cfg->device_family == IWL_DEVICE_FAMILY_8000) {
775 tlv_lar = mvm->fw->ucode_capa.capa[0] &
776 IWL_UCODE_TLV_CAPA_LAR_SUPPORT;
777 nvm_lar = mvm->nvm_data->lar_enabled;
778 if (tlv_lar != nvm_lar)
779 IWL_INFO(mvm,
780 "Conflict between TLV & NVM regarding enabling LAR (TLV = %s NVM =%s)\n",
781 tlv_lar ? "enabled" : "disabled",
782 nvm_lar ? "enabled" : "disabled");
783 }
784
785 if (!iwl_mvm_is_lar_supported(mvm))
786 return 0;
787
788 /*
789 * During HW restart, only replay the last set MCC to FW. Otherwise,
790 * queue an update to cfg80211 to retrieve the default alpha2 from FW.
791 */
792 if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) {
793 /* This should only be called during vif up and hold RTNL */
794 return iwl_mvm_init_fw_regd(mvm);
795 }
796
797 /*
798 * Driver regulatory hint for initial update, this also informs the
799 * firmware we support wifi location updates.
800 * Disallow scans that might crash the FW while the LAR regdomain
801 * is not set.
802 */
803 mvm->lar_regdom_set = false;
804
805 regd = iwl_mvm_get_current_regdomain(mvm, NULL);
806 if (IS_ERR_OR_NULL(regd))
807 return -EIO;
808
809 if (iwl_mvm_is_wifi_mcc_supported(mvm) &&
810 !iwl_mvm_get_bios_mcc(mvm, mcc)) {
811 kfree(regd);
812 regd = iwl_mvm_get_regdomain(mvm->hw->wiphy, mcc,
813 MCC_SOURCE_BIOS, NULL);
814 if (IS_ERR_OR_NULL(regd))
815 return -EIO;
816 }
817
818 retval = regulatory_set_wiphy_regd_sync_rtnl(mvm->hw->wiphy, regd);
819 kfree(regd);
820 return retval;
821}
822
823int iwl_mvm_rx_chub_update_mcc(struct iwl_mvm *mvm,
824 struct iwl_rx_cmd_buffer *rxb,
825 struct iwl_device_cmd *cmd)
826{
827 struct iwl_rx_packet *pkt = rxb_addr(rxb);
828 struct iwl_mcc_chub_notif *notif = (void *)pkt->data;
829 enum iwl_mcc_source src;
830 char mcc[3];
831 struct ieee80211_regdomain *regd;
832
833 lockdep_assert_held(&mvm->mutex);
834
835 if (WARN_ON_ONCE(!iwl_mvm_is_lar_supported(mvm)))
836 return 0;
837
838 mcc[0] = notif->mcc >> 8;
839 mcc[1] = notif->mcc & 0xff;
840 mcc[2] = '\0';
841 src = notif->source_id;
842
843 IWL_DEBUG_LAR(mvm,
844 "RX: received chub update mcc cmd (mcc '%s' src %d)\n",
845 mcc, src);
846 regd = iwl_mvm_get_regdomain(mvm->hw->wiphy, mcc, src, NULL);
847 if (IS_ERR_OR_NULL(regd))
848 return 0;
849
850 regulatory_set_wiphy_regd(mvm->hw->wiphy, regd);
851 kfree(regd);
852
853 return 0;
854}
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index fe40922a6b0d..80121e41ca22 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -82,7 +82,6 @@
82#include "rs.h" 82#include "rs.h"
83#include "fw-api-scan.h" 83#include "fw-api-scan.h"
84#include "time-event.h" 84#include "time-event.h"
85#include "iwl-fw-error-dump.h"
86 85
87#define DRV_DESCRIPTION "The new Intel(R) wireless AGN driver for Linux" 86#define DRV_DESCRIPTION "The new Intel(R) wireless AGN driver for Linux"
88MODULE_DESCRIPTION(DRV_DESCRIPTION); 87MODULE_DESCRIPTION(DRV_DESCRIPTION);
@@ -234,6 +233,7 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
234 iwl_mvm_rx_ant_coupling_notif, true), 233 iwl_mvm_rx_ant_coupling_notif, true),
235 234
236 RX_HANDLER(TIME_EVENT_NOTIFICATION, iwl_mvm_rx_time_event_notif, false), 235 RX_HANDLER(TIME_EVENT_NOTIFICATION, iwl_mvm_rx_time_event_notif, false),
236 RX_HANDLER(MCC_CHUB_UPDATE_CMD, iwl_mvm_rx_chub_update_mcc, true),
237 237
238 RX_HANDLER(EOSP_NOTIFICATION, iwl_mvm_rx_eosp_notif, false), 238 RX_HANDLER(EOSP_NOTIFICATION, iwl_mvm_rx_eosp_notif, false),
239 239
@@ -358,6 +358,7 @@ static const char *const iwl_mvm_cmd_strings[REPLY_MAX] = {
358 CMD(TDLS_CHANNEL_SWITCH_CMD), 358 CMD(TDLS_CHANNEL_SWITCH_CMD),
359 CMD(TDLS_CHANNEL_SWITCH_NOTIFICATION), 359 CMD(TDLS_CHANNEL_SWITCH_NOTIFICATION),
360 CMD(TDLS_CONFIG_CMD), 360 CMD(TDLS_CONFIG_CMD),
361 CMD(MCC_UPDATE_CMD),
361}; 362};
362#undef CMD 363#undef CMD
363 364
@@ -871,8 +872,8 @@ static void iwl_mvm_fw_error_dump_wk(struct work_struct *work)
871 872
872 /* start recording again if the firmware is not crashed */ 873 /* start recording again if the firmware is not crashed */
873 WARN_ON_ONCE((!test_bit(STATUS_FW_ERROR, &mvm->trans->status)) && 874 WARN_ON_ONCE((!test_bit(STATUS_FW_ERROR, &mvm->trans->status)) &&
874 mvm->fw->dbg_dest_tlv && 875 mvm->fw->dbg_dest_tlv &&
875 iwl_mvm_start_fw_dbg_conf(mvm, mvm->fw_dbg_conf)); 876 iwl_mvm_start_fw_dbg_conf(mvm, mvm->fw_dbg_conf));
876 877
877 mutex_unlock(&mvm->mutex); 878 mutex_unlock(&mvm->mutex);
878 879
@@ -1270,6 +1271,10 @@ static void iwl_mvm_d0i3_exit_work(struct work_struct *wk)
1270 iwl_free_resp(&get_status_cmd); 1271 iwl_free_resp(&get_status_cmd);
1271out: 1272out:
1272 iwl_mvm_d0i3_enable_tx(mvm, qos_seq); 1273 iwl_mvm_d0i3_enable_tx(mvm, qos_seq);
1274
1275 /* the FW might have updated the regdomain */
1276 iwl_mvm_update_changed_regdom(mvm);
1277
1273 iwl_mvm_unref(mvm, IWL_MVM_REF_EXIT_WORK); 1278 iwl_mvm_unref(mvm, IWL_MVM_REF_EXIT_WORK);
1274 mutex_unlock(&mvm->mutex); 1279 mutex_unlock(&mvm->mutex);
1275} 1280}
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c
index 33bbdde0046f..d2c6ba9d326b 100644
--- a/drivers/net/wireless/iwlwifi/mvm/power.c
+++ b/drivers/net/wireless/iwlwifi/mvm/power.c
@@ -358,7 +358,7 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
358 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK); 358 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK);
359 359
360 if (!vif->bss_conf.ps || iwl_mvm_vif_low_latency(mvmvif) || 360 if (!vif->bss_conf.ps || iwl_mvm_vif_low_latency(mvmvif) ||
361 !mvmvif->pm_enabled || iwl_mvm_tdls_sta_count(mvm, vif)) 361 !mvmvif->pm_enabled)
362 return; 362 return;
363 363
364 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK); 364 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK);
@@ -639,6 +639,10 @@ static void iwl_mvm_power_set_pm(struct iwl_mvm *mvm,
639 if (vifs->ap_vif) 639 if (vifs->ap_vif)
640 ap_mvmvif = iwl_mvm_vif_from_mac80211(vifs->ap_vif); 640 ap_mvmvif = iwl_mvm_vif_from_mac80211(vifs->ap_vif);
641 641
642 /* don't allow PM if any TDLS stations exist */
643 if (iwl_mvm_tdls_sta_count(mvm, NULL))
644 return;
645
642 /* enable PM on bss if bss stand alone */ 646 /* enable PM on bss if bss stand alone */
643 if (vifs->bss_active && !vifs->p2p_active && !vifs->ap_active) { 647 if (vifs->bss_active && !vifs->p2p_active && !vifs->ap_active) {
644 bss_mvmvif->pm_enabled = true; 648 bss_mvmvif->pm_enabled = true;
diff --git a/drivers/net/wireless/iwlwifi/mvm/quota.c b/drivers/net/wireless/iwlwifi/mvm/quota.c
index dbb2594390e9..509a66d05245 100644
--- a/drivers/net/wireless/iwlwifi/mvm/quota.c
+++ b/drivers/net/wireless/iwlwifi/mvm/quota.c
@@ -172,6 +172,7 @@ static void iwl_mvm_adjust_quota_for_noa(struct iwl_mvm *mvm,
172} 172}
173 173
174int iwl_mvm_update_quotas(struct iwl_mvm *mvm, 174int iwl_mvm_update_quotas(struct iwl_mvm *mvm,
175 bool force_update,
175 struct ieee80211_vif *disabled_vif) 176 struct ieee80211_vif *disabled_vif)
176{ 177{
177 struct iwl_time_quota_cmd cmd = {}; 178 struct iwl_time_quota_cmd cmd = {};
@@ -309,7 +310,7 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm,
309 "zero quota on binding %d\n", i); 310 "zero quota on binding %d\n", i);
310 } 311 }
311 312
312 if (!send) { 313 if (!send && !force_update) {
313 /* don't send a practically unchanged command, the firmware has 314 /* don't send a practically unchanged command, the firmware has
314 * to re-initialize a lot of state and that can have an adverse 315 * to re-initialize a lot of state and that can have an adverse
315 * impact on it 316 * impact on it
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c
index 6578498dd5af..dd457df9601e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.c
@@ -1065,6 +1065,37 @@ static inline bool rs_rate_column_match(struct rs_rate *a,
1065 && ant_match; 1065 && ant_match;
1066} 1066}
1067 1067
1068static inline enum rs_column rs_get_column_from_rate(struct rs_rate *rate)
1069{
1070 if (is_legacy(rate)) {
1071 if (rate->ant == ANT_A)
1072 return RS_COLUMN_LEGACY_ANT_A;
1073
1074 if (rate->ant == ANT_B)
1075 return RS_COLUMN_LEGACY_ANT_B;
1076
1077 goto err;
1078 }
1079
1080 if (is_siso(rate)) {
1081 if (rate->ant == ANT_A || rate->stbc || rate->bfer)
1082 return rate->sgi ? RS_COLUMN_SISO_ANT_A_SGI :
1083 RS_COLUMN_SISO_ANT_A;
1084
1085 if (rate->ant == ANT_B)
1086 return rate->sgi ? RS_COLUMN_SISO_ANT_B_SGI :
1087 RS_COLUMN_SISO_ANT_B;
1088
1089 goto err;
1090 }
1091
1092 if (is_mimo(rate))
1093 return rate->sgi ? RS_COLUMN_MIMO2_SGI : RS_COLUMN_MIMO2;
1094
1095err:
1096 return RS_COLUMN_INVALID;
1097}
1098
1068static u8 rs_get_tid(struct ieee80211_hdr *hdr) 1099static u8 rs_get_tid(struct ieee80211_hdr *hdr)
1069{ 1100{
1070 u8 tid = IWL_MAX_TID_COUNT; 1101 u8 tid = IWL_MAX_TID_COUNT;
@@ -1106,17 +1137,43 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
1106 return; 1137 return;
1107 } 1138 }
1108 1139
1140 /* This packet was aggregated but doesn't carry status info */
1141 if ((info->flags & IEEE80211_TX_CTL_AMPDU) &&
1142 !(info->flags & IEEE80211_TX_STAT_AMPDU))
1143 return;
1144
1145 rs_rate_from_ucode_rate(tx_resp_hwrate, info->band, &tx_resp_rate);
1146
1109#ifdef CONFIG_MAC80211_DEBUGFS 1147#ifdef CONFIG_MAC80211_DEBUGFS
1110 /* Disable last tx check if we are debugging with fixed rate */ 1148 /* Disable last tx check if we are debugging with fixed rate but
1149 * update tx stats */
1111 if (lq_sta->pers.dbg_fixed_rate) { 1150 if (lq_sta->pers.dbg_fixed_rate) {
1112 IWL_DEBUG_RATE(mvm, "Fixed rate. avoid rate scaling\n"); 1151 int index = tx_resp_rate.index;
1152 enum rs_column column;
1153 int attempts, success;
1154
1155 column = rs_get_column_from_rate(&tx_resp_rate);
1156 if (WARN_ONCE(column == RS_COLUMN_INVALID,
1157 "Can't map rate 0x%x to column",
1158 tx_resp_hwrate))
1159 return;
1160
1161 if (info->flags & IEEE80211_TX_STAT_AMPDU) {
1162 attempts = info->status.ampdu_len;
1163 success = info->status.ampdu_ack_len;
1164 } else {
1165 attempts = info->status.rates[0].count;
1166 success = !!(info->flags & IEEE80211_TX_STAT_ACK);
1167 }
1168
1169 lq_sta->pers.tx_stats[column][index].total += attempts;
1170 lq_sta->pers.tx_stats[column][index].success += success;
1171
1172 IWL_DEBUG_RATE(mvm, "Fixed rate 0x%x success %d attempts %d\n",
1173 tx_resp_hwrate, success, attempts);
1113 return; 1174 return;
1114 } 1175 }
1115#endif 1176#endif
1116 /* This packet was aggregated but doesn't carry status info */
1117 if ((info->flags & IEEE80211_TX_CTL_AMPDU) &&
1118 !(info->flags & IEEE80211_TX_STAT_AMPDU))
1119 return;
1120 1177
1121 if (time_after(jiffies, 1178 if (time_after(jiffies,
1122 (unsigned long)(lq_sta->last_tx + 1179 (unsigned long)(lq_sta->last_tx +
@@ -1142,7 +1199,6 @@ void iwl_mvm_rs_tx_status(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
1142 table = &lq_sta->lq; 1199 table = &lq_sta->lq;
1143 lq_hwrate = le32_to_cpu(table->rs_table[0]); 1200 lq_hwrate = le32_to_cpu(table->rs_table[0]);
1144 rs_rate_from_ucode_rate(lq_hwrate, info->band, &lq_rate); 1201 rs_rate_from_ucode_rate(lq_hwrate, info->band, &lq_rate);
1145 rs_rate_from_ucode_rate(tx_resp_hwrate, info->band, &tx_resp_rate);
1146 1202
1147 /* Here we actually compare this rate to the latest LQ command */ 1203 /* Here we actually compare this rate to the latest LQ command */
1148 if (!rs_rate_equal(&tx_resp_rate, &lq_rate, allow_ant_mismatch)) { 1204 if (!rs_rate_equal(&tx_resp_rate, &lq_rate, allow_ant_mismatch)) {
@@ -3343,16 +3399,16 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
3343 (is_legacy(rate)) ? "legacy" : 3399 (is_legacy(rate)) ? "legacy" :
3344 is_vht(rate) ? "VHT" : "HT"); 3400 is_vht(rate) ? "VHT" : "HT");
3345 if (!is_legacy(rate)) { 3401 if (!is_legacy(rate)) {
3346 desc += sprintf(buff+desc, " %s", 3402 desc += sprintf(buff + desc, " %s",
3347 (is_siso(rate)) ? "SISO" : "MIMO2"); 3403 (is_siso(rate)) ? "SISO" : "MIMO2");
3348 desc += sprintf(buff+desc, " %s", 3404 desc += sprintf(buff + desc, " %s",
3349 (is_ht20(rate)) ? "20MHz" : 3405 (is_ht20(rate)) ? "20MHz" :
3350 (is_ht40(rate)) ? "40MHz" : 3406 (is_ht40(rate)) ? "40MHz" :
3351 (is_ht80(rate)) ? "80Mhz" : "BAD BW"); 3407 (is_ht80(rate)) ? "80Mhz" : "BAD BW");
3352 desc += sprintf(buff+desc, " %s %s %s\n", 3408 desc += sprintf(buff + desc, " %s %s %s\n",
3353 (rate->sgi) ? "SGI" : "NGI", 3409 (rate->sgi) ? "SGI" : "NGI",
3354 (rate->ldpc) ? "LDPC" : "BCC", 3410 (rate->ldpc) ? "LDPC" : "BCC",
3355 (lq_sta->is_agg) ? "AGG on" : ""); 3411 (lq_sta->is_agg) ? "AGG on" : "");
3356 } 3412 }
3357 desc += sprintf(buff+desc, "last tx rate=0x%X\n", 3413 desc += sprintf(buff+desc, "last tx rate=0x%X\n",
3358 lq_sta->last_rate_n_flags); 3414 lq_sta->last_rate_n_flags);
@@ -3373,13 +3429,13 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
3373 ss_params = le32_to_cpu(lq_sta->lq.ss_params); 3429 ss_params = le32_to_cpu(lq_sta->lq.ss_params);
3374 desc += sprintf(buff+desc, "single stream params: %s%s%s%s\n", 3430 desc += sprintf(buff+desc, "single stream params: %s%s%s%s\n",
3375 (ss_params & LQ_SS_PARAMS_VALID) ? 3431 (ss_params & LQ_SS_PARAMS_VALID) ?
3376 "VALID," : "INVALID", 3432 "VALID" : "INVALID",
3377 (ss_params & LQ_SS_BFER_ALLOWED) ? 3433 (ss_params & LQ_SS_BFER_ALLOWED) ?
3378 "BFER," : "", 3434 ", BFER" : "",
3379 (ss_params & LQ_SS_STBC_1SS_ALLOWED) ? 3435 (ss_params & LQ_SS_STBC_1SS_ALLOWED) ?
3380 "STBC," : "", 3436 ", STBC" : "",
3381 (ss_params & LQ_SS_FORCE) ? 3437 (ss_params & LQ_SS_FORCE) ?
3382 "FORCE" : ""); 3438 ", FORCE" : "");
3383 desc += sprintf(buff+desc, 3439 desc += sprintf(buff+desc,
3384 "Start idx [0]=0x%x [1]=0x%x [2]=0x%x [3]=0x%x\n", 3440 "Start idx [0]=0x%x [1]=0x%x [2]=0x%x [3]=0x%x\n",
3385 lq_sta->lq.initial_rate_index[0], 3441 lq_sta->lq.initial_rate_index[0],
diff --git a/drivers/net/wireless/iwlwifi/mvm/sf.c b/drivers/net/wireless/iwlwifi/mvm/sf.c
index 7eb78e2c240a..b0f59fdd287c 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sf.c
+++ b/drivers/net/wireless/iwlwifi/mvm/sf.c
@@ -99,7 +99,35 @@ static void iwl_mvm_bound_iface_iterator(void *_data, u8 *mac,
99 99
100/* 100/*
101 * Aging and idle timeouts for the different possible scenarios 101 * Aging and idle timeouts for the different possible scenarios
102 * in SF_FULL_ON state. 102 * in default configuration
103 */
104static const
105__le32 sf_full_timeout_def[SF_NUM_SCENARIO][SF_NUM_TIMEOUT_TYPES] = {
106 {
107 cpu_to_le32(SF_SINGLE_UNICAST_AGING_TIMER_DEF),
108 cpu_to_le32(SF_SINGLE_UNICAST_IDLE_TIMER_DEF)
109 },
110 {
111 cpu_to_le32(SF_AGG_UNICAST_AGING_TIMER_DEF),
112 cpu_to_le32(SF_AGG_UNICAST_IDLE_TIMER_DEF)
113 },
114 {
115 cpu_to_le32(SF_MCAST_AGING_TIMER_DEF),
116 cpu_to_le32(SF_MCAST_IDLE_TIMER_DEF)
117 },
118 {
119 cpu_to_le32(SF_BA_AGING_TIMER_DEF),
120 cpu_to_le32(SF_BA_IDLE_TIMER_DEF)
121 },
122 {
123 cpu_to_le32(SF_TX_RE_AGING_TIMER_DEF),
124 cpu_to_le32(SF_TX_RE_IDLE_TIMER_DEF)
125 },
126};
127
128/*
129 * Aging and idle timeouts for the different possible scenarios
130 * in single BSS MAC configuration.
103 */ 131 */
104static const __le32 sf_full_timeout[SF_NUM_SCENARIO][SF_NUM_TIMEOUT_TYPES] = { 132static const __le32 sf_full_timeout[SF_NUM_SCENARIO][SF_NUM_TIMEOUT_TYPES] = {
105 { 133 {
@@ -124,7 +152,8 @@ static const __le32 sf_full_timeout[SF_NUM_SCENARIO][SF_NUM_TIMEOUT_TYPES] = {
124 }, 152 },
125}; 153};
126 154
127static void iwl_mvm_fill_sf_command(struct iwl_sf_cfg_cmd *sf_cmd, 155static void iwl_mvm_fill_sf_command(struct iwl_mvm *mvm,
156 struct iwl_sf_cfg_cmd *sf_cmd,
128 struct ieee80211_sta *sta) 157 struct ieee80211_sta *sta)
129{ 158{
130 int i, j, watermark; 159 int i, j, watermark;
@@ -163,24 +192,38 @@ static void iwl_mvm_fill_sf_command(struct iwl_sf_cfg_cmd *sf_cmd,
163 cpu_to_le32(SF_LONG_DELAY_AGING_TIMER); 192 cpu_to_le32(SF_LONG_DELAY_AGING_TIMER);
164 } 193 }
165 } 194 }
166 BUILD_BUG_ON(sizeof(sf_full_timeout) !=
167 sizeof(__le32) * SF_NUM_SCENARIO * SF_NUM_TIMEOUT_TYPES);
168 195
169 memcpy(sf_cmd->full_on_timeouts, sf_full_timeout, 196 if (sta || IWL_UCODE_API(mvm->fw->ucode_ver) < 13) {
170 sizeof(sf_full_timeout)); 197 BUILD_BUG_ON(sizeof(sf_full_timeout) !=
198 sizeof(__le32) * SF_NUM_SCENARIO *
199 SF_NUM_TIMEOUT_TYPES);
200
201 memcpy(sf_cmd->full_on_timeouts, sf_full_timeout,
202 sizeof(sf_full_timeout));
203 } else {
204 BUILD_BUG_ON(sizeof(sf_full_timeout_def) !=
205 sizeof(__le32) * SF_NUM_SCENARIO *
206 SF_NUM_TIMEOUT_TYPES);
207
208 memcpy(sf_cmd->full_on_timeouts, sf_full_timeout_def,
209 sizeof(sf_full_timeout_def));
210 }
211
171} 212}
172 213
173static int iwl_mvm_sf_config(struct iwl_mvm *mvm, u8 sta_id, 214static int iwl_mvm_sf_config(struct iwl_mvm *mvm, u8 sta_id,
174 enum iwl_sf_state new_state) 215 enum iwl_sf_state new_state)
175{ 216{
176 struct iwl_sf_cfg_cmd sf_cmd = { 217 struct iwl_sf_cfg_cmd sf_cmd = {
177 .state = cpu_to_le32(new_state), 218 .state = cpu_to_le32(SF_FULL_ON),
178 }; 219 };
179 struct ieee80211_sta *sta; 220 struct ieee80211_sta *sta;
180 int ret = 0; 221 int ret = 0;
181 222
182 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF && 223 if (IWL_UCODE_API(mvm->fw->ucode_ver) < 13)
183 mvm->cfg->disable_dummy_notification) 224 sf_cmd.state = cpu_to_le32(new_state);
225
226 if (mvm->cfg->disable_dummy_notification)
184 sf_cmd.state |= cpu_to_le32(SF_CFG_DUMMY_NOTIF_OFF); 227 sf_cmd.state |= cpu_to_le32(SF_CFG_DUMMY_NOTIF_OFF);
185 228
186 /* 229 /*
@@ -192,6 +235,8 @@ static int iwl_mvm_sf_config(struct iwl_mvm *mvm, u8 sta_id,
192 235
193 switch (new_state) { 236 switch (new_state) {
194 case SF_UNINIT: 237 case SF_UNINIT:
238 if (IWL_UCODE_API(mvm->fw->ucode_ver) >= 13)
239 iwl_mvm_fill_sf_command(mvm, &sf_cmd, NULL);
195 break; 240 break;
196 case SF_FULL_ON: 241 case SF_FULL_ON:
197 if (sta_id == IWL_MVM_STATION_COUNT) { 242 if (sta_id == IWL_MVM_STATION_COUNT) {
@@ -206,11 +251,11 @@ static int iwl_mvm_sf_config(struct iwl_mvm *mvm, u8 sta_id,
206 rcu_read_unlock(); 251 rcu_read_unlock();
207 return -EINVAL; 252 return -EINVAL;
208 } 253 }
209 iwl_mvm_fill_sf_command(&sf_cmd, sta); 254 iwl_mvm_fill_sf_command(mvm, &sf_cmd, sta);
210 rcu_read_unlock(); 255 rcu_read_unlock();
211 break; 256 break;
212 case SF_INIT_OFF: 257 case SF_INIT_OFF:
213 iwl_mvm_fill_sf_command(&sf_cmd, NULL); 258 iwl_mvm_fill_sf_command(mvm, &sf_cmd, NULL);
214 break; 259 break;
215 default: 260 default:
216 WARN_ONCE(1, "Invalid state: %d. not sending Smart Fifo cmd\n", 261 WARN_ONCE(1, "Invalid state: %d. not sending Smart Fifo cmd\n",
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c
index 5c23cddaaae3..50f9288368af 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.c
@@ -273,7 +273,7 @@ int iwl_mvm_add_sta(struct iwl_mvm *mvm,
273 else 273 else
274 sta_id = mvm_sta->sta_id; 274 sta_id = mvm_sta->sta_id;
275 275
276 if (WARN_ON_ONCE(sta_id == IWL_MVM_STATION_COUNT)) 276 if (sta_id == IWL_MVM_STATION_COUNT)
277 return -ENOSPC; 277 return -ENOSPC;
278 278
279 spin_lock_init(&mvm_sta->lock); 279 spin_lock_init(&mvm_sta->lock);
@@ -1681,9 +1681,6 @@ void iwl_mvm_sta_modify_disable_tx(struct iwl_mvm *mvm,
1681 }; 1681 };
1682 int ret; 1682 int ret;
1683 1683
1684 if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_DISABLE_STA_TX))
1685 return;
1686
1687 ret = iwl_mvm_send_cmd_pdu(mvm, ADD_STA, CMD_ASYNC, sizeof(cmd), &cmd); 1684 ret = iwl_mvm_send_cmd_pdu(mvm, ADD_STA, CMD_ASYNC, sizeof(cmd), &cmd);
1688 if (ret) 1685 if (ret)
1689 IWL_ERR(mvm, "Failed to send ADD_STA command (%d)\n", ret); 1686 IWL_ERR(mvm, "Failed to send ADD_STA command (%d)\n", ret);
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c
index f8d6f306dd76..8d179ab67cc2 100644
--- a/drivers/net/wireless/iwlwifi/mvm/time-event.c
+++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c
@@ -197,6 +197,8 @@ iwl_mvm_te_handle_notify_csa(struct iwl_mvm *mvm,
197 struct iwl_time_event_notif *notif) 197 struct iwl_time_event_notif *notif)
198{ 198{
199 if (!le32_to_cpu(notif->status)) { 199 if (!le32_to_cpu(notif->status)) {
200 if (te_data->vif->type == NL80211_IFTYPE_STATION)
201 ieee80211_connection_loss(te_data->vif);
200 IWL_DEBUG_TE(mvm, "CSA time event failed to start\n"); 202 IWL_DEBUG_TE(mvm, "CSA time event failed to start\n");
201 iwl_mvm_te_clear_data(mvm, te_data); 203 iwl_mvm_te_clear_data(mvm, te_data);
202 return; 204 return;
@@ -261,17 +263,23 @@ static void iwl_mvm_te_handle_notif(struct iwl_mvm *mvm,
261 "TE ended - current time %lu, estimated end %lu\n", 263 "TE ended - current time %lu, estimated end %lu\n",
262 jiffies, te_data->end_jiffies); 264 jiffies, te_data->end_jiffies);
263 265
264 if (te_data->vif->type == NL80211_IFTYPE_P2P_DEVICE) { 266 switch (te_data->vif->type) {
267 case NL80211_IFTYPE_P2P_DEVICE:
265 ieee80211_remain_on_channel_expired(mvm->hw); 268 ieee80211_remain_on_channel_expired(mvm->hw);
266 iwl_mvm_roc_finished(mvm); 269 iwl_mvm_roc_finished(mvm);
270 break;
271 case NL80211_IFTYPE_STATION:
272 /*
273 * By now, we should have finished association
274 * and know the dtim period.
275 */
276 iwl_mvm_te_check_disconnect(mvm, te_data->vif,
277 "No association and the time event is over already...");
278 break;
279 default:
280 break;
267 } 281 }
268 282
269 /*
270 * By now, we should have finished association
271 * and know the dtim period.
272 */
273 iwl_mvm_te_check_disconnect(mvm, te_data->vif,
274 "No association and the time event is over already...");
275 iwl_mvm_te_clear_data(mvm, te_data); 283 iwl_mvm_te_clear_data(mvm, te_data);
276 } else if (le32_to_cpu(notif->action) & TE_V2_NOTIF_HOST_EVENT_START) { 284 } else if (le32_to_cpu(notif->action) & TE_V2_NOTIF_HOST_EVENT_START) {
277 te_data->running = true; 285 te_data->running = true;
diff --git a/drivers/net/wireless/iwlwifi/mvm/utils.c b/drivers/net/wireless/iwlwifi/mvm/utils.c
index 2b9de63951e6..435faee0a28e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/utils.c
+++ b/drivers/net/wireless/iwlwifi/mvm/utils.c
@@ -857,7 +857,7 @@ int iwl_mvm_update_low_latency(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
857 857
858 mvmvif->low_latency = value; 858 mvmvif->low_latency = value;
859 859
860 res = iwl_mvm_update_quotas(mvm, NULL); 860 res = iwl_mvm_update_quotas(mvm, false, NULL);
861 if (res) 861 if (res)
862 return res; 862 return res;
863 863
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c
index dbd6bcf52205..2794cd2d3a64 100644
--- a/drivers/net/wireless/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/iwlwifi/pcie/drv.c
@@ -413,10 +413,35 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
413 413
414/* 8000 Series */ 414/* 8000 Series */
415 {IWL_PCI_DEVICE(0x24F3, 0x0010, iwl8260_2ac_cfg)}, 415 {IWL_PCI_DEVICE(0x24F3, 0x0010, iwl8260_2ac_cfg)},
416 {IWL_PCI_DEVICE(0x24F3, 0x0004, iwl8260_2n_cfg)}, 416 {IWL_PCI_DEVICE(0x24F3, 0x1010, iwl8260_2ac_cfg)},
417 {IWL_PCI_DEVICE(0x24F3, 0x0110, iwl8260_2ac_cfg)},
418 {IWL_PCI_DEVICE(0x24F3, 0x1110, iwl8260_2ac_cfg)},
419 {IWL_PCI_DEVICE(0x24F3, 0x0050, iwl8260_2ac_cfg)},
420 {IWL_PCI_DEVICE(0x24F3, 0x0250, iwl8260_2ac_cfg)},
421 {IWL_PCI_DEVICE(0x24F3, 0x1050, iwl8260_2ac_cfg)},
422 {IWL_PCI_DEVICE(0x24F3, 0x0150, iwl8260_2ac_cfg)},
417 {IWL_PCI_DEVICE(0x24F4, 0x0030, iwl8260_2ac_cfg)}, 423 {IWL_PCI_DEVICE(0x24F4, 0x0030, iwl8260_2ac_cfg)},
424 {IWL_PCI_DEVICE(0x24F4, 0x1130, iwl8260_2ac_cfg)},
425 {IWL_PCI_DEVICE(0x24F4, 0x1030, iwl8260_2ac_cfg)},
426 {IWL_PCI_DEVICE(0x24F3, 0xC010, iwl8260_2ac_cfg)},
427 {IWL_PCI_DEVICE(0x24F3, 0xD010, iwl8260_2ac_cfg)},
428 {IWL_PCI_DEVICE(0x24F4, 0xC030, iwl8260_2ac_cfg)},
429 {IWL_PCI_DEVICE(0x24F4, 0xD030, iwl8260_2ac_cfg)},
430 {IWL_PCI_DEVICE(0x24F3, 0xC050, iwl8260_2ac_cfg)},
431 {IWL_PCI_DEVICE(0x24F3, 0xD050, iwl8260_2ac_cfg)},
432 {IWL_PCI_DEVICE(0x24F3, 0x8010, iwl8260_2ac_cfg)},
433 {IWL_PCI_DEVICE(0x24F3, 0x9010, iwl8260_2ac_cfg)},
434 {IWL_PCI_DEVICE(0x24F4, 0x8030, iwl8260_2ac_cfg)},
435 {IWL_PCI_DEVICE(0x24F4, 0x9030, iwl8260_2ac_cfg)},
436 {IWL_PCI_DEVICE(0x24F3, 0x8050, iwl8260_2ac_cfg)},
437 {IWL_PCI_DEVICE(0x24F3, 0x9050, iwl8260_2ac_cfg)},
438 {IWL_PCI_DEVICE(0x24F3, 0x0004, iwl8260_2n_cfg)},
418 {IWL_PCI_DEVICE(0x24F5, 0x0010, iwl4165_2ac_cfg)}, 439 {IWL_PCI_DEVICE(0x24F5, 0x0010, iwl4165_2ac_cfg)},
419 {IWL_PCI_DEVICE(0x24F6, 0x0030, iwl4165_2ac_cfg)}, 440 {IWL_PCI_DEVICE(0x24F6, 0x0030, iwl4165_2ac_cfg)},
441 {IWL_PCI_DEVICE(0x24F3, 0x0810, iwl8260_2ac_cfg)},
442 {IWL_PCI_DEVICE(0x24F3, 0x0910, iwl8260_2ac_cfg)},
443 {IWL_PCI_DEVICE(0x24F3, 0x0850, iwl8260_2ac_cfg)},
444 {IWL_PCI_DEVICE(0x24F3, 0x0950, iwl8260_2ac_cfg)},
420#endif /* CONFIG_IWLMVM */ 445#endif /* CONFIG_IWLMVM */
421 446
422 {0} 447 {0}
diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h
index cae0eb8835ce..01996c9d98a7 100644
--- a/drivers/net/wireless/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/iwlwifi/pcie/internal.h
@@ -217,6 +217,8 @@ struct iwl_pcie_txq_scratch_buf {
217 * @active: stores if queue is active 217 * @active: stores if queue is active
218 * @ampdu: true if this queue is an ampdu queue for an specific RA/TID 218 * @ampdu: true if this queue is an ampdu queue for an specific RA/TID
219 * @wd_timeout: queue watchdog timeout (jiffies) - per queue 219 * @wd_timeout: queue watchdog timeout (jiffies) - per queue
220 * @frozen: tx stuck queue timer is frozen
221 * @frozen_expiry_remainder: remember how long until the timer fires
220 * 222 *
221 * A Tx queue consists of circular buffer of BDs (a.k.a. TFDs, transmit frame 223 * A Tx queue consists of circular buffer of BDs (a.k.a. TFDs, transmit frame
222 * descriptors) and required locking structures. 224 * descriptors) and required locking structures.
@@ -228,9 +230,11 @@ struct iwl_txq {
228 dma_addr_t scratchbufs_dma; 230 dma_addr_t scratchbufs_dma;
229 struct iwl_pcie_txq_entry *entries; 231 struct iwl_pcie_txq_entry *entries;
230 spinlock_t lock; 232 spinlock_t lock;
233 unsigned long frozen_expiry_remainder;
231 struct timer_list stuck_timer; 234 struct timer_list stuck_timer;
232 struct iwl_trans_pcie *trans_pcie; 235 struct iwl_trans_pcie *trans_pcie;
233 bool need_update; 236 bool need_update;
237 bool frozen;
234 u8 active; 238 u8 active;
235 bool ampdu; 239 bool ampdu;
236 unsigned long wd_timeout; 240 unsigned long wd_timeout;
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index f31a94160771..dc247325d8d7 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -682,6 +682,43 @@ static int iwl_pcie_load_section(struct iwl_trans *trans, u8 section_num,
682 return ret; 682 return ret;
683} 683}
684 684
685/*
686 * Driver Takes the ownership on secure machine before FW load
687 * and prevent race with the BT load.
688 * W/A for ROM bug. (should be remove in the next Si step)
689 */
690static int iwl_pcie_rsa_race_bug_wa(struct iwl_trans *trans)
691{
692 u32 val, loop = 1000;
693
694 /* Check the RSA semaphore is accessible - if not, we are in trouble */
695 val = iwl_read_prph(trans, PREG_AUX_BUS_WPROT_0);
696 if (val & (BIT(1) | BIT(17))) {
697 IWL_ERR(trans,
698 "can't access the RSA semaphore it is write protected\n");
699 return 0;
700 }
701
702 /* take ownership on the AUX IF */
703 iwl_write_prph(trans, WFPM_CTRL_REG, WFPM_AUX_CTL_AUX_IF_MAC_OWNER_MSK);
704 iwl_write_prph(trans, AUX_MISC_MASTER1_EN, AUX_MISC_MASTER1_EN_SBE_MSK);
705
706 do {
707 iwl_write_prph(trans, AUX_MISC_MASTER1_SMPHR_STATUS, 0x1);
708 val = iwl_read_prph(trans, AUX_MISC_MASTER1_SMPHR_STATUS);
709 if (val == 0x1) {
710 iwl_write_prph(trans, RSA_ENABLE, 0);
711 return 0;
712 }
713
714 udelay(10);
715 loop--;
716 } while (loop > 0);
717
718 IWL_ERR(trans, "Failed to take ownership on secure machine\n");
719 return -EIO;
720}
721
685static int iwl_pcie_load_cpu_sections_8000b(struct iwl_trans *trans, 722static int iwl_pcie_load_cpu_sections_8000b(struct iwl_trans *trans,
686 const struct fw_img *image, 723 const struct fw_img *image,
687 int cpu, 724 int cpu,
@@ -901,6 +938,11 @@ static int iwl_pcie_load_given_ucode_8000b(struct iwl_trans *trans,
901 if (trans->dbg_dest_tlv) 938 if (trans->dbg_dest_tlv)
902 iwl_pcie_apply_destination(trans); 939 iwl_pcie_apply_destination(trans);
903 940
941 /* TODO: remove in the next Si step */
942 ret = iwl_pcie_rsa_race_bug_wa(trans);
943 if (ret)
944 return ret;
945
904 /* configure the ucode to be ready to get the secured image */ 946 /* configure the ucode to be ready to get the secured image */
905 /* release CPU reset */ 947 /* release CPU reset */
906 iwl_write_prph(trans, RELEASE_CPU_RESET, RELEASE_CPU_RESET_BIT); 948 iwl_write_prph(trans, RELEASE_CPU_RESET, RELEASE_CPU_RESET_BIT);
@@ -1462,6 +1504,60 @@ static int iwl_trans_pcie_write_mem(struct iwl_trans *trans, u32 addr,
1462 return ret; 1504 return ret;
1463} 1505}
1464 1506
1507static void iwl_trans_pcie_freeze_txq_timer(struct iwl_trans *trans,
1508 unsigned long txqs,
1509 bool freeze)
1510{
1511 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
1512 int queue;
1513
1514 for_each_set_bit(queue, &txqs, BITS_PER_LONG) {
1515 struct iwl_txq *txq = &trans_pcie->txq[queue];
1516 unsigned long now;
1517
1518 spin_lock_bh(&txq->lock);
1519
1520 now = jiffies;
1521
1522 if (txq->frozen == freeze)
1523 goto next_queue;
1524
1525 IWL_DEBUG_TX_QUEUES(trans, "%s TXQ %d\n",
1526 freeze ? "Freezing" : "Waking", queue);
1527
1528 txq->frozen = freeze;
1529
1530 if (txq->q.read_ptr == txq->q.write_ptr)
1531 goto next_queue;
1532
1533 if (freeze) {
1534 if (unlikely(time_after(now,
1535 txq->stuck_timer.expires))) {
1536 /*
1537 * The timer should have fired, maybe it is
1538 * spinning right now on the lock.
1539 */
1540 goto next_queue;
1541 }
1542 /* remember how long until the timer fires */
1543 txq->frozen_expiry_remainder =
1544 txq->stuck_timer.expires - now;
1545 del_timer(&txq->stuck_timer);
1546 goto next_queue;
1547 }
1548
1549 /*
1550 * Wake a non-empty queue -> arm timer with the
1551 * remainder before it froze
1552 */
1553 mod_timer(&txq->stuck_timer,
1554 now + txq->frozen_expiry_remainder);
1555
1556next_queue:
1557 spin_unlock_bh(&txq->lock);
1558 }
1559}
1560
1465#define IWL_FLUSH_WAIT_MS 2000 1561#define IWL_FLUSH_WAIT_MS 2000
1466 1562
1467static int iwl_trans_pcie_wait_txq_empty(struct iwl_trans *trans, u32 txq_bm) 1563static int iwl_trans_pcie_wait_txq_empty(struct iwl_trans *trans, u32 txq_bm)
@@ -1713,7 +1809,7 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file,
1713 int ret; 1809 int ret;
1714 size_t bufsz; 1810 size_t bufsz;
1715 1811
1716 bufsz = sizeof(char) * 64 * trans->cfg->base_params->num_of_queues; 1812 bufsz = sizeof(char) * 75 * trans->cfg->base_params->num_of_queues;
1717 1813
1718 if (!trans_pcie->txq) 1814 if (!trans_pcie->txq)
1719 return -EAGAIN; 1815 return -EAGAIN;
@@ -1726,11 +1822,11 @@ static ssize_t iwl_dbgfs_tx_queue_read(struct file *file,
1726 txq = &trans_pcie->txq[cnt]; 1822 txq = &trans_pcie->txq[cnt];
1727 q = &txq->q; 1823 q = &txq->q;
1728 pos += scnprintf(buf + pos, bufsz - pos, 1824 pos += scnprintf(buf + pos, bufsz - pos,
1729 "hwq %.2d: read=%u write=%u use=%d stop=%d need_update=%d%s\n", 1825 "hwq %.2d: read=%u write=%u use=%d stop=%d need_update=%d frozen=%d%s\n",
1730 cnt, q->read_ptr, q->write_ptr, 1826 cnt, q->read_ptr, q->write_ptr,
1731 !!test_bit(cnt, trans_pcie->queue_used), 1827 !!test_bit(cnt, trans_pcie->queue_used),
1732 !!test_bit(cnt, trans_pcie->queue_stopped), 1828 !!test_bit(cnt, trans_pcie->queue_stopped),
1733 txq->need_update, 1829 txq->need_update, txq->frozen,
1734 (cnt == trans_pcie->cmd_queue ? " HCMD" : "")); 1830 (cnt == trans_pcie->cmd_queue ? " HCMD" : ""));
1735 } 1831 }
1736 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1832 ret = simple_read_from_buffer(user_buf, count, ppos, buf, pos);
@@ -1961,24 +2057,25 @@ static const struct {
1961 { .start = 0x00a01c7c, .end = 0x00a01c7c }, 2057 { .start = 0x00a01c7c, .end = 0x00a01c7c },
1962 { .start = 0x00a01c28, .end = 0x00a01c54 }, 2058 { .start = 0x00a01c28, .end = 0x00a01c54 },
1963 { .start = 0x00a01c5c, .end = 0x00a01c5c }, 2059 { .start = 0x00a01c5c, .end = 0x00a01c5c },
1964 { .start = 0x00a01c84, .end = 0x00a01c84 }, 2060 { .start = 0x00a01c60, .end = 0x00a01cdc },
1965 { .start = 0x00a01ce0, .end = 0x00a01d0c }, 2061 { .start = 0x00a01ce0, .end = 0x00a01d0c },
1966 { .start = 0x00a01d18, .end = 0x00a01d20 }, 2062 { .start = 0x00a01d18, .end = 0x00a01d20 },
1967 { .start = 0x00a01d2c, .end = 0x00a01d30 }, 2063 { .start = 0x00a01d2c, .end = 0x00a01d30 },
1968 { .start = 0x00a01d40, .end = 0x00a01d5c }, 2064 { .start = 0x00a01d40, .end = 0x00a01d5c },
1969 { .start = 0x00a01d80, .end = 0x00a01d80 }, 2065 { .start = 0x00a01d80, .end = 0x00a01d80 },
1970 { .start = 0x00a01d98, .end = 0x00a01d98 }, 2066 { .start = 0x00a01d98, .end = 0x00a01d9c },
2067 { .start = 0x00a01da8, .end = 0x00a01da8 },
2068 { .start = 0x00a01db8, .end = 0x00a01df4 },
1971 { .start = 0x00a01dc0, .end = 0x00a01dfc }, 2069 { .start = 0x00a01dc0, .end = 0x00a01dfc },
1972 { .start = 0x00a01e00, .end = 0x00a01e2c }, 2070 { .start = 0x00a01e00, .end = 0x00a01e2c },
1973 { .start = 0x00a01e40, .end = 0x00a01e60 }, 2071 { .start = 0x00a01e40, .end = 0x00a01e60 },
2072 { .start = 0x00a01e68, .end = 0x00a01e6c },
2073 { .start = 0x00a01e74, .end = 0x00a01e74 },
1974 { .start = 0x00a01e84, .end = 0x00a01e90 }, 2074 { .start = 0x00a01e84, .end = 0x00a01e90 },
1975 { .start = 0x00a01e9c, .end = 0x00a01ec4 }, 2075 { .start = 0x00a01e9c, .end = 0x00a01ec4 },
1976 { .start = 0x00a01ed0, .end = 0x00a01ed0 }, 2076 { .start = 0x00a01ed0, .end = 0x00a01ee0 },
1977 { .start = 0x00a01f00, .end = 0x00a01f14 }, 2077 { .start = 0x00a01f00, .end = 0x00a01f1c },
1978 { .start = 0x00a01f44, .end = 0x00a01f58 }, 2078 { .start = 0x00a01f44, .end = 0x00a01ffc },
1979 { .start = 0x00a01f80, .end = 0x00a01fa8 },
1980 { .start = 0x00a01fb0, .end = 0x00a01fbc },
1981 { .start = 0x00a01ff8, .end = 0x00a01ffc },
1982 { .start = 0x00a02000, .end = 0x00a02048 }, 2079 { .start = 0x00a02000, .end = 0x00a02048 },
1983 { .start = 0x00a02068, .end = 0x00a020f0 }, 2080 { .start = 0x00a02068, .end = 0x00a020f0 },
1984 { .start = 0x00a02100, .end = 0x00a02118 }, 2081 { .start = 0x00a02100, .end = 0x00a02118 },
@@ -2305,6 +2402,7 @@ static const struct iwl_trans_ops trans_ops_pcie = {
2305 .dbgfs_register = iwl_trans_pcie_dbgfs_register, 2402 .dbgfs_register = iwl_trans_pcie_dbgfs_register,
2306 2403
2307 .wait_tx_queue_empty = iwl_trans_pcie_wait_txq_empty, 2404 .wait_tx_queue_empty = iwl_trans_pcie_wait_txq_empty,
2405 .freeze_txq_timer = iwl_trans_pcie_freeze_txq_timer,
2308 2406
2309 .write8 = iwl_trans_pcie_write8, 2407 .write8 = iwl_trans_pcie_write8,
2310 .write32 = iwl_trans_pcie_write32, 2408 .write32 = iwl_trans_pcie_write32,
@@ -2423,10 +2521,45 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
2423 * "dash" value). To keep hw_rev backwards compatible - we'll store it 2521 * "dash" value). To keep hw_rev backwards compatible - we'll store it
2424 * in the old format. 2522 * in the old format.
2425 */ 2523 */
2426 if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) 2524 if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) {
2525 unsigned long flags;
2526 int ret;
2527
2427 trans->hw_rev = (trans->hw_rev & 0xfff0) | 2528 trans->hw_rev = (trans->hw_rev & 0xfff0) |
2428 (CSR_HW_REV_STEP(trans->hw_rev << 2) << 2); 2529 (CSR_HW_REV_STEP(trans->hw_rev << 2) << 2);
2429 2530
2531 /*
2532 * in-order to recognize C step driver should read chip version
2533 * id located at the AUX bus MISC address space.
2534 */
2535 iwl_set_bit(trans, CSR_GP_CNTRL,
2536 CSR_GP_CNTRL_REG_FLAG_INIT_DONE);
2537 udelay(2);
2538
2539 ret = iwl_poll_bit(trans, CSR_GP_CNTRL,
2540 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
2541 CSR_GP_CNTRL_REG_FLAG_MAC_CLOCK_READY,
2542 25000);
2543 if (ret < 0) {
2544 IWL_DEBUG_INFO(trans, "Failed to wake up the nic\n");
2545 goto out_pci_disable_msi;
2546 }
2547
2548 if (iwl_trans_grab_nic_access(trans, false, &flags)) {
2549 u32 hw_step;
2550
2551 hw_step = __iwl_read_prph(trans, WFPM_CTRL_REG);
2552 hw_step |= ENABLE_WFPM;
2553 __iwl_write_prph(trans, WFPM_CTRL_REG, hw_step);
2554 hw_step = __iwl_read_prph(trans, AUX_MISC_REG);
2555 hw_step = (hw_step >> HW_STEP_LOCATION_BITS) & 0xF;
2556 if (hw_step == 0x3)
2557 trans->hw_rev = (trans->hw_rev & 0xFFFFFFF3) |
2558 (SILICON_C_STEP << 2);
2559 iwl_trans_release_nic_access(trans, &flags);
2560 }
2561 }
2562
2430 trans->hw_id = (pdev->device << 16) + pdev->subsystem_device; 2563 trans->hw_id = (pdev->device << 16) + pdev->subsystem_device;
2431 snprintf(trans->hw_id_str, sizeof(trans->hw_id_str), 2564 snprintf(trans->hw_id_str, sizeof(trans->hw_id_str),
2432 "PCI ID: 0x%04X:0x%04X", pdev->device, pdev->subsystem_device); 2565 "PCI ID: 0x%04X:0x%04X", pdev->device, pdev->subsystem_device);
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c
index af0bce736358..06952aadfd7b 100644
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -725,33 +725,50 @@ void iwl_trans_pcie_tx_reset(struct iwl_trans *trans)
725 iwl_pcie_tx_start(trans, 0); 725 iwl_pcie_tx_start(trans, 0);
726} 726}
727 727
728static void iwl_pcie_tx_stop_fh(struct iwl_trans *trans)
729{
730 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
731 unsigned long flags;
732 int ch, ret;
733 u32 mask = 0;
734
735 spin_lock(&trans_pcie->irq_lock);
736
737 if (!iwl_trans_grab_nic_access(trans, false, &flags))
738 goto out;
739
740 /* Stop each Tx DMA channel */
741 for (ch = 0; ch < FH_TCSR_CHNL_NUM; ch++) {
742 iwl_write32(trans, FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0);
743 mask |= FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch);
744 }
745
746 /* Wait for DMA channels to be idle */
747 ret = iwl_poll_bit(trans, FH_TSSR_TX_STATUS_REG, mask, mask, 5000);
748 if (ret < 0)
749 IWL_ERR(trans,
750 "Failing on timeout while stopping DMA channel %d [0x%08x]\n",
751 ch, iwl_read32(trans, FH_TSSR_TX_STATUS_REG));
752
753 iwl_trans_release_nic_access(trans, &flags);
754
755out:
756 spin_unlock(&trans_pcie->irq_lock);
757}
758
728/* 759/*
729 * iwl_pcie_tx_stop - Stop all Tx DMA channels 760 * iwl_pcie_tx_stop - Stop all Tx DMA channels
730 */ 761 */
731int iwl_pcie_tx_stop(struct iwl_trans *trans) 762int iwl_pcie_tx_stop(struct iwl_trans *trans)
732{ 763{
733 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); 764 struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
734 int ch, txq_id, ret; 765 int txq_id;
735 766
736 /* Turn off all Tx DMA fifos */ 767 /* Turn off all Tx DMA fifos */
737 spin_lock(&trans_pcie->irq_lock);
738
739 iwl_scd_deactivate_fifos(trans); 768 iwl_scd_deactivate_fifos(trans);
740 769
741 /* Stop each Tx DMA channel, and wait for it to be idle */ 770 /* Turn off all Tx DMA channels */
742 for (ch = 0; ch < FH_TCSR_CHNL_NUM; ch++) { 771 iwl_pcie_tx_stop_fh(trans);
743 iwl_write_direct32(trans,
744 FH_TCSR_CHNL_TX_CONFIG_REG(ch), 0x0);
745 ret = iwl_poll_direct_bit(trans, FH_TSSR_TX_STATUS_REG,
746 FH_TSSR_TX_STATUS_REG_MSK_CHNL_IDLE(ch), 1000);
747 if (ret < 0)
748 IWL_ERR(trans,
749 "Failing on timeout while stopping DMA channel %d [0x%08x]\n",
750 ch,
751 iwl_read_direct32(trans,
752 FH_TSSR_TX_STATUS_REG));
753 }
754 spin_unlock(&trans_pcie->irq_lock);
755 772
756 /* 773 /*
757 * This function can be called before the op_mode disabled the 774 * This function can be called before the op_mode disabled the
@@ -912,10 +929,19 @@ error:
912 929
913static inline void iwl_pcie_txq_progress(struct iwl_txq *txq) 930static inline void iwl_pcie_txq_progress(struct iwl_txq *txq)
914{ 931{
932 lockdep_assert_held(&txq->lock);
933
915 if (!txq->wd_timeout) 934 if (!txq->wd_timeout)
916 return; 935 return;
917 936
918 /* 937 /*
938 * station is asleep and we send data - that must
939 * be uAPSD or PS-Poll. Don't rearm the timer.
940 */
941 if (txq->frozen)
942 return;
943
944 /*
919 * if empty delete timer, otherwise move timer forward 945 * if empty delete timer, otherwise move timer forward
920 * since we're making progress on this queue 946 * since we're making progress on this queue
921 */ 947 */
@@ -1248,6 +1274,9 @@ void iwl_trans_pcie_txq_disable(struct iwl_trans *trans, int txq_id,
1248 SCD_TX_STTS_QUEUE_OFFSET(txq_id); 1274 SCD_TX_STTS_QUEUE_OFFSET(txq_id);
1249 static const u32 zero_val[4] = {}; 1275 static const u32 zero_val[4] = {};
1250 1276
1277 trans_pcie->txq[txq_id].frozen_expiry_remainder = 0;
1278 trans_pcie->txq[txq_id].frozen = false;
1279
1251 /* 1280 /*
1252 * Upon HW Rfkill - we stop the device, and then stop the queues 1281 * Upon HW Rfkill - we stop the device, and then stop the queues
1253 * in the op_mode. Just for the sake of the simplicity of the op_mode, 1282 * in the op_mode. Just for the sake of the simplicity of the op_mode,
diff --git a/drivers/net/wireless/libertas_tf/if_usb.c b/drivers/net/wireless/libertas_tf/if_usb.c
index d576dd6665d3..1a20cee5febe 100644
--- a/drivers/net/wireless/libertas_tf/if_usb.c
+++ b/drivers/net/wireless/libertas_tf/if_usb.c
@@ -365,7 +365,6 @@ static int if_usb_reset_device(struct if_usb_card *cardp)
365 365
366 return ret; 366 return ret;
367} 367}
368EXPORT_SYMBOL_GPL(if_usb_reset_device);
369 368
370/** 369/**
371 * usb_tx_block - transfer data to the device 370 * usb_tx_block - transfer data to the device
@@ -907,7 +906,6 @@ restart:
907 lbtf_deb_leave_args(LBTF_DEB_USB, "ret %d", ret); 906 lbtf_deb_leave_args(LBTF_DEB_USB, "ret %d", ret);
908 return ret; 907 return ret;
909} 908}
910EXPORT_SYMBOL_GPL(if_usb_prog_firmware);
911 909
912 910
913#define if_usb_suspend NULL 911#define if_usb_suspend NULL
diff --git a/drivers/net/wireless/mwifiex/11n.c b/drivers/net/wireless/mwifiex/11n.c
index 543148d27b01..433bd6837c79 100644
--- a/drivers/net/wireless/mwifiex/11n.c
+++ b/drivers/net/wireless/mwifiex/11n.c
@@ -159,6 +159,7 @@ int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv,
159 int tid; 159 int tid;
160 struct host_cmd_ds_11n_addba_rsp *add_ba_rsp = &resp->params.add_ba_rsp; 160 struct host_cmd_ds_11n_addba_rsp *add_ba_rsp = &resp->params.add_ba_rsp;
161 struct mwifiex_tx_ba_stream_tbl *tx_ba_tbl; 161 struct mwifiex_tx_ba_stream_tbl *tx_ba_tbl;
162 struct mwifiex_ra_list_tbl *ra_list;
162 u16 block_ack_param_set = le16_to_cpu(add_ba_rsp->block_ack_param_set); 163 u16 block_ack_param_set = le16_to_cpu(add_ba_rsp->block_ack_param_set);
163 164
164 add_ba_rsp->ssn = cpu_to_le16((le16_to_cpu(add_ba_rsp->ssn)) 165 add_ba_rsp->ssn = cpu_to_le16((le16_to_cpu(add_ba_rsp->ssn))
@@ -166,7 +167,13 @@ int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv,
166 167
167 tid = (block_ack_param_set & IEEE80211_ADDBA_PARAM_TID_MASK) 168 tid = (block_ack_param_set & IEEE80211_ADDBA_PARAM_TID_MASK)
168 >> BLOCKACKPARAM_TID_POS; 169 >> BLOCKACKPARAM_TID_POS;
170 ra_list = mwifiex_wmm_get_ralist_node(priv, tid, add_ba_rsp->
171 peer_mac_addr);
169 if (le16_to_cpu(add_ba_rsp->status_code) != BA_RESULT_SUCCESS) { 172 if (le16_to_cpu(add_ba_rsp->status_code) != BA_RESULT_SUCCESS) {
173 if (ra_list) {
174 ra_list->ba_status = BA_SETUP_NONE;
175 ra_list->amsdu_in_ampdu = false;
176 }
170 mwifiex_del_ba_tbl(priv, tid, add_ba_rsp->peer_mac_addr, 177 mwifiex_del_ba_tbl(priv, tid, add_ba_rsp->peer_mac_addr,
171 TYPE_DELBA_SENT, true); 178 TYPE_DELBA_SENT, true);
172 if (add_ba_rsp->add_rsp_result != BA_RESULT_TIMEOUT) 179 if (add_ba_rsp->add_rsp_result != BA_RESULT_TIMEOUT)
@@ -185,6 +192,10 @@ int mwifiex_ret_11n_addba_req(struct mwifiex_private *priv,
185 tx_ba_tbl->amsdu = true; 192 tx_ba_tbl->amsdu = true;
186 else 193 else
187 tx_ba_tbl->amsdu = false; 194 tx_ba_tbl->amsdu = false;
195 if (ra_list) {
196 ra_list->amsdu_in_ampdu = tx_ba_tbl->amsdu;
197 ra_list->ba_status = BA_SETUP_COMPLETE;
198 }
188 } else { 199 } else {
189 dev_err(priv->adapter->dev, "BA stream not created\n"); 200 dev_err(priv->adapter->dev, "BA stream not created\n");
190 } 201 }
@@ -515,6 +526,7 @@ void mwifiex_create_ba_tbl(struct mwifiex_private *priv, u8 *ra, int tid,
515 enum mwifiex_ba_status ba_status) 526 enum mwifiex_ba_status ba_status)
516{ 527{
517 struct mwifiex_tx_ba_stream_tbl *new_node; 528 struct mwifiex_tx_ba_stream_tbl *new_node;
529 struct mwifiex_ra_list_tbl *ra_list;
518 unsigned long flags; 530 unsigned long flags;
519 531
520 if (!mwifiex_get_ba_tbl(priv, tid, ra)) { 532 if (!mwifiex_get_ba_tbl(priv, tid, ra)) {
@@ -522,7 +534,11 @@ void mwifiex_create_ba_tbl(struct mwifiex_private *priv, u8 *ra, int tid,
522 GFP_ATOMIC); 534 GFP_ATOMIC);
523 if (!new_node) 535 if (!new_node)
524 return; 536 return;
525 537 ra_list = mwifiex_wmm_get_ralist_node(priv, tid, ra);
538 if (ra_list) {
539 ra_list->ba_status = ba_status;
540 ra_list->amsdu_in_ampdu = false;
541 }
526 INIT_LIST_HEAD(&new_node->list); 542 INIT_LIST_HEAD(&new_node->list);
527 543
528 new_node->tid = tid; 544 new_node->tid = tid;
diff --git a/drivers/net/wireless/mwifiex/11n.h b/drivers/net/wireless/mwifiex/11n.h
index 8e2e39422ad8..afdd58aa90de 100644
--- a/drivers/net/wireless/mwifiex/11n.h
+++ b/drivers/net/wireless/mwifiex/11n.h
@@ -77,22 +77,6 @@ mwifiex_is_station_ampdu_allowed(struct mwifiex_private *priv,
77 return (node->ampdu_sta[tid] != BA_STREAM_NOT_ALLOWED) ? true : false; 77 return (node->ampdu_sta[tid] != BA_STREAM_NOT_ALLOWED) ? true : false;
78} 78}
79 79
80/* This function checks whether AMSDU is allowed for BA stream. */
81static inline u8
82mwifiex_is_amsdu_in_ampdu_allowed(struct mwifiex_private *priv,
83 struct mwifiex_ra_list_tbl *ptr, int tid)
84{
85 struct mwifiex_tx_ba_stream_tbl *tx_tbl;
86
87 if (is_broadcast_ether_addr(ptr->ra))
88 return false;
89 tx_tbl = mwifiex_get_ba_tbl(priv, tid, ptr->ra);
90 if (tx_tbl)
91 return tx_tbl->amsdu;
92
93 return false;
94}
95
96/* This function checks whether AMPDU is allowed or not for a particular TID. */ 80/* This function checks whether AMPDU is allowed or not for a particular TID. */
97static inline u8 81static inline u8
98mwifiex_is_ampdu_allowed(struct mwifiex_private *priv, 82mwifiex_is_ampdu_allowed(struct mwifiex_private *priv,
@@ -182,22 +166,6 @@ mwifiex_find_stream_to_delete(struct mwifiex_private *priv, int ptr_tid,
182} 166}
183 167
184/* 168/*
185 * This function checks whether BA stream is set up or not.
186 */
187static inline int
188mwifiex_is_ba_stream_setup(struct mwifiex_private *priv,
189 struct mwifiex_ra_list_tbl *ptr, int tid)
190{
191 struct mwifiex_tx_ba_stream_tbl *tx_tbl;
192
193 tx_tbl = mwifiex_get_ba_tbl(priv, tid, ptr->ra);
194 if (tx_tbl && IS_BASTREAM_SETUP(tx_tbl))
195 return true;
196
197 return false;
198}
199
200/*
201 * This function checks whether associated station is 11n enabled 169 * This function checks whether associated station is 11n enabled
202 */ 170 */
203static inline int mwifiex_is_sta_11n_enabled(struct mwifiex_private *priv, 171static inline int mwifiex_is_sta_11n_enabled(struct mwifiex_private *priv,
diff --git a/drivers/net/wireless/mwifiex/11n_aggr.c b/drivers/net/wireless/mwifiex/11n_aggr.c
index 9b983b5cebbd..6183e255e62a 100644
--- a/drivers/net/wireless/mwifiex/11n_aggr.c
+++ b/drivers/net/wireless/mwifiex/11n_aggr.c
@@ -170,7 +170,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
170 struct mwifiex_adapter *adapter = priv->adapter; 170 struct mwifiex_adapter *adapter = priv->adapter;
171 struct sk_buff *skb_aggr, *skb_src; 171 struct sk_buff *skb_aggr, *skb_src;
172 struct mwifiex_txinfo *tx_info_aggr, *tx_info_src; 172 struct mwifiex_txinfo *tx_info_aggr, *tx_info_src;
173 int pad = 0, ret; 173 int pad = 0, aggr_num = 0, ret;
174 struct mwifiex_tx_param tx_param; 174 struct mwifiex_tx_param tx_param;
175 struct txpd *ptx_pd = NULL; 175 struct txpd *ptx_pd = NULL;
176 struct timeval tv; 176 struct timeval tv;
@@ -184,7 +184,8 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
184 } 184 }
185 185
186 tx_info_src = MWIFIEX_SKB_TXCB(skb_src); 186 tx_info_src = MWIFIEX_SKB_TXCB(skb_src);
187 skb_aggr = dev_alloc_skb(adapter->tx_buf_size); 187 skb_aggr = mwifiex_alloc_dma_align_buf(adapter->tx_buf_size,
188 GFP_ATOMIC | GFP_DMA);
188 if (!skb_aggr) { 189 if (!skb_aggr) {
189 dev_err(adapter->dev, "%s: alloc skb_aggr\n", __func__); 190 dev_err(adapter->dev, "%s: alloc skb_aggr\n", __func__);
190 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, 191 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
@@ -200,6 +201,7 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
200 201
201 if (tx_info_src->flags & MWIFIEX_BUF_FLAG_TDLS_PKT) 202 if (tx_info_src->flags & MWIFIEX_BUF_FLAG_TDLS_PKT)
202 tx_info_aggr->flags |= MWIFIEX_BUF_FLAG_TDLS_PKT; 203 tx_info_aggr->flags |= MWIFIEX_BUF_FLAG_TDLS_PKT;
204 tx_info_aggr->flags |= MWIFIEX_BUF_FLAG_AGGR_PKT;
203 skb_aggr->priority = skb_src->priority; 205 skb_aggr->priority = skb_src->priority;
204 206
205 do_gettimeofday(&tv); 207 do_gettimeofday(&tv);
@@ -211,11 +213,9 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
211 break; 213 break;
212 214
213 skb_src = skb_dequeue(&pra_list->skb_head); 215 skb_src = skb_dequeue(&pra_list->skb_head);
214
215 pra_list->total_pkt_count--; 216 pra_list->total_pkt_count--;
216
217 atomic_dec(&priv->wmm.tx_pkts_queued); 217 atomic_dec(&priv->wmm.tx_pkts_queued);
218 218 aggr_num++;
219 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, 219 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
220 ra_list_flags); 220 ra_list_flags);
221 mwifiex_11n_form_amsdu_pkt(skb_aggr, skb_src, &pad); 221 mwifiex_11n_form_amsdu_pkt(skb_aggr, skb_src, &pad);
@@ -251,6 +251,12 @@ mwifiex_11n_aggregate_pkt(struct mwifiex_private *priv,
251 ptx_pd = (struct txpd *)skb_aggr->data; 251 ptx_pd = (struct txpd *)skb_aggr->data;
252 252
253 skb_push(skb_aggr, headroom); 253 skb_push(skb_aggr, headroom);
254 tx_info_aggr->aggr_num = aggr_num * 2;
255 if (adapter->data_sent || adapter->tx_lock_flag) {
256 atomic_add(aggr_num * 2, &adapter->tx_queued);
257 skb_queue_tail(&adapter->tx_data_q, skb_aggr);
258 return 0;
259 }
254 260
255 if (adapter->iface_type == MWIFIEX_USB) { 261 if (adapter->iface_type == MWIFIEX_USB) {
256 adapter->data_sent = true; 262 adapter->data_sent = true;
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c
index a2e8817b56d8..f75f8acfaca0 100644
--- a/drivers/net/wireless/mwifiex/11n_rxreorder.c
+++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c
@@ -659,6 +659,7 @@ mwifiex_del_ba_tbl(struct mwifiex_private *priv, int tid, u8 *peer_mac,
659{ 659{
660 struct mwifiex_rx_reorder_tbl *tbl; 660 struct mwifiex_rx_reorder_tbl *tbl;
661 struct mwifiex_tx_ba_stream_tbl *ptx_tbl; 661 struct mwifiex_tx_ba_stream_tbl *ptx_tbl;
662 struct mwifiex_ra_list_tbl *ra_list;
662 u8 cleanup_rx_reorder_tbl; 663 u8 cleanup_rx_reorder_tbl;
663 unsigned long flags; 664 unsigned long flags;
664 665
@@ -686,7 +687,11 @@ mwifiex_del_ba_tbl(struct mwifiex_private *priv, int tid, u8 *peer_mac,
686 "event: TID, RA not found in table\n"); 687 "event: TID, RA not found in table\n");
687 return; 688 return;
688 } 689 }
689 690 ra_list = mwifiex_wmm_get_ralist_node(priv, tid, peer_mac);
691 if (ra_list) {
692 ra_list->amsdu_in_ampdu = false;
693 ra_list->ba_status = BA_SETUP_NONE;
694 }
690 spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags); 695 spin_lock_irqsave(&priv->tx_ba_stream_tbl_lock, flags);
691 mwifiex_11n_delete_tx_ba_stream_tbl_entry(priv, ptx_tbl); 696 mwifiex_11n_delete_tx_ba_stream_tbl_entry(priv, ptx_tbl);
692 spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags); 697 spin_unlock_irqrestore(&priv->tx_ba_stream_tbl_lock, flags);
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 6f8993c12373..bf9020ff2d33 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -717,6 +717,9 @@ mwifiex_cfg80211_init_p2p_go(struct mwifiex_private *priv)
717 717
718static int mwifiex_deinit_priv_params(struct mwifiex_private *priv) 718static int mwifiex_deinit_priv_params(struct mwifiex_private *priv)
719{ 719{
720 struct mwifiex_adapter *adapter = priv->adapter;
721 unsigned long flags;
722
720 priv->mgmt_frame_mask = 0; 723 priv->mgmt_frame_mask = 0;
721 if (mwifiex_send_cmd(priv, HostCmd_CMD_MGMT_FRAME_REG, 724 if (mwifiex_send_cmd(priv, HostCmd_CMD_MGMT_FRAME_REG,
722 HostCmd_ACT_GEN_SET, 0, 725 HostCmd_ACT_GEN_SET, 0,
@@ -727,6 +730,25 @@ static int mwifiex_deinit_priv_params(struct mwifiex_private *priv)
727 } 730 }
728 731
729 mwifiex_deauthenticate(priv, NULL); 732 mwifiex_deauthenticate(priv, NULL);
733
734 spin_lock_irqsave(&adapter->main_proc_lock, flags);
735 adapter->main_locked = true;
736 if (adapter->mwifiex_processing) {
737 spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
738 flush_workqueue(adapter->workqueue);
739 } else {
740 spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
741 }
742
743 spin_lock_irqsave(&adapter->rx_proc_lock, flags);
744 adapter->rx_locked = true;
745 if (adapter->rx_processing) {
746 spin_unlock_irqrestore(&adapter->rx_proc_lock, flags);
747 flush_workqueue(adapter->rx_workqueue);
748 } else {
749 spin_unlock_irqrestore(&adapter->rx_proc_lock, flags);
750 }
751
730 mwifiex_free_priv(priv); 752 mwifiex_free_priv(priv);
731 priv->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED; 753 priv->wdev.iftype = NL80211_IFTYPE_UNSPECIFIED;
732 priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED; 754 priv->bss_mode = NL80211_IFTYPE_UNSPECIFIED;
@@ -740,6 +762,9 @@ mwifiex_init_new_priv_params(struct mwifiex_private *priv,
740 struct net_device *dev, 762 struct net_device *dev,
741 enum nl80211_iftype type) 763 enum nl80211_iftype type)
742{ 764{
765 struct mwifiex_adapter *adapter = priv->adapter;
766 unsigned long flags;
767
743 mwifiex_init_priv(priv); 768 mwifiex_init_priv(priv);
744 769
745 priv->bss_mode = type; 770 priv->bss_mode = type;
@@ -770,6 +795,14 @@ mwifiex_init_new_priv_params(struct mwifiex_private *priv,
770 return -EOPNOTSUPP; 795 return -EOPNOTSUPP;
771 } 796 }
772 797
798 spin_lock_irqsave(&adapter->main_proc_lock, flags);
799 adapter->main_locked = false;
800 spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
801
802 spin_lock_irqsave(&adapter->rx_proc_lock, flags);
803 adapter->rx_locked = false;
804 spin_unlock_irqrestore(&adapter->rx_proc_lock, flags);
805
773 return 0; 806 return 0;
774} 807}
775 808
@@ -2733,24 +2766,71 @@ mwifiex_is_pattern_supported(struct cfg80211_pkt_pattern *pat, s8 *byte_seq,
2733} 2766}
2734 2767
2735#ifdef CONFIG_PM 2768#ifdef CONFIG_PM
2736static int mwifiex_set_mef_filter(struct mwifiex_private *priv, 2769static void mwifiex_set_auto_arp_mef_entry(struct mwifiex_private *priv,
2737 struct cfg80211_wowlan *wowlan) 2770 struct mwifiex_mef_entry *mef_entry)
2771{
2772 int i, filt_num = 0, num_ipv4 = 0;
2773 struct in_device *in_dev;
2774 struct in_ifaddr *ifa;
2775 __be32 ips[MWIFIEX_MAX_SUPPORTED_IPADDR];
2776 struct mwifiex_adapter *adapter = priv->adapter;
2777
2778 mef_entry->mode = MEF_MODE_HOST_SLEEP;
2779 mef_entry->action = MEF_ACTION_AUTO_ARP;
2780
2781 /* Enable ARP offload feature */
2782 memset(ips, 0, sizeof(ips));
2783 for (i = 0; i < MWIFIEX_MAX_BSS_NUM; i++) {
2784 if (adapter->priv[i]->netdev) {
2785 in_dev = __in_dev_get_rtnl(adapter->priv[i]->netdev);
2786 if (!in_dev)
2787 continue;
2788 ifa = in_dev->ifa_list;
2789 if (!ifa || !ifa->ifa_local)
2790 continue;
2791 ips[i] = ifa->ifa_local;
2792 num_ipv4++;
2793 }
2794 }
2795
2796 for (i = 0; i < num_ipv4; i++) {
2797 if (!ips[i])
2798 continue;
2799 mef_entry->filter[filt_num].repeat = 1;
2800 memcpy(mef_entry->filter[filt_num].byte_seq,
2801 (u8 *)&ips[i], sizeof(ips[i]));
2802 mef_entry->filter[filt_num].
2803 byte_seq[MWIFIEX_MEF_MAX_BYTESEQ] =
2804 sizeof(ips[i]);
2805 mef_entry->filter[filt_num].offset = 46;
2806 mef_entry->filter[filt_num].filt_type = TYPE_EQ;
2807 if (filt_num) {
2808 mef_entry->filter[filt_num].filt_action =
2809 TYPE_OR;
2810 }
2811 filt_num++;
2812 }
2813
2814 mef_entry->filter[filt_num].repeat = 1;
2815 mef_entry->filter[filt_num].byte_seq[0] = 0x08;
2816 mef_entry->filter[filt_num].byte_seq[1] = 0x06;
2817 mef_entry->filter[filt_num].byte_seq[MWIFIEX_MEF_MAX_BYTESEQ] = 2;
2818 mef_entry->filter[filt_num].offset = 20;
2819 mef_entry->filter[filt_num].filt_type = TYPE_EQ;
2820 mef_entry->filter[filt_num].filt_action = TYPE_AND;
2821}
2822
2823static int mwifiex_set_wowlan_mef_entry(struct mwifiex_private *priv,
2824 struct mwifiex_ds_mef_cfg *mef_cfg,
2825 struct mwifiex_mef_entry *mef_entry,
2826 struct cfg80211_wowlan *wowlan)
2738{ 2827{
2739 int i, filt_num = 0, ret = 0; 2828 int i, filt_num = 0, ret = 0;
2740 bool first_pat = true; 2829 bool first_pat = true;
2741 u8 byte_seq[MWIFIEX_MEF_MAX_BYTESEQ + 1]; 2830 u8 byte_seq[MWIFIEX_MEF_MAX_BYTESEQ + 1];
2742 const u8 ipv4_mc_mac[] = {0x33, 0x33}; 2831 const u8 ipv4_mc_mac[] = {0x33, 0x33};
2743 const u8 ipv6_mc_mac[] = {0x01, 0x00, 0x5e}; 2832 const u8 ipv6_mc_mac[] = {0x01, 0x00, 0x5e};
2744 struct mwifiex_ds_mef_cfg mef_cfg;
2745 struct mwifiex_mef_entry *mef_entry;
2746 2833
2747 mef_entry = kzalloc(sizeof(*mef_entry), GFP_KERNEL);
2748 if (!mef_entry)
2749 return -ENOMEM;
2750
2751 memset(&mef_cfg, 0, sizeof(mef_cfg));
2752 mef_cfg.num_entries = 1;
2753 mef_cfg.mef_entry = mef_entry;
2754 mef_entry->mode = MEF_MODE_HOST_SLEEP; 2834 mef_entry->mode = MEF_MODE_HOST_SLEEP;
2755 mef_entry->action = MEF_ACTION_ALLOW_AND_WAKEUP_HOST; 2835 mef_entry->action = MEF_ACTION_ALLOW_AND_WAKEUP_HOST;
2756 2836
@@ -2767,20 +2847,19 @@ static int mwifiex_set_mef_filter(struct mwifiex_private *priv,
2767 if (!wowlan->patterns[i].pkt_offset) { 2847 if (!wowlan->patterns[i].pkt_offset) {
2768 if (!(byte_seq[0] & 0x01) && 2848 if (!(byte_seq[0] & 0x01) &&
2769 (byte_seq[MWIFIEX_MEF_MAX_BYTESEQ] == 1)) { 2849 (byte_seq[MWIFIEX_MEF_MAX_BYTESEQ] == 1)) {
2770 mef_cfg.criteria |= MWIFIEX_CRITERIA_UNICAST; 2850 mef_cfg->criteria |= MWIFIEX_CRITERIA_UNICAST;
2771 continue; 2851 continue;
2772 } else if (is_broadcast_ether_addr(byte_seq)) { 2852 } else if (is_broadcast_ether_addr(byte_seq)) {
2773 mef_cfg.criteria |= MWIFIEX_CRITERIA_BROADCAST; 2853 mef_cfg->criteria |= MWIFIEX_CRITERIA_BROADCAST;
2774 continue; 2854 continue;
2775 } else if ((!memcmp(byte_seq, ipv4_mc_mac, 2) && 2855 } else if ((!memcmp(byte_seq, ipv4_mc_mac, 2) &&
2776 (byte_seq[MWIFIEX_MEF_MAX_BYTESEQ] == 2)) || 2856 (byte_seq[MWIFIEX_MEF_MAX_BYTESEQ] == 2)) ||
2777 (!memcmp(byte_seq, ipv6_mc_mac, 3) && 2857 (!memcmp(byte_seq, ipv6_mc_mac, 3) &&
2778 (byte_seq[MWIFIEX_MEF_MAX_BYTESEQ] == 3))) { 2858 (byte_seq[MWIFIEX_MEF_MAX_BYTESEQ] == 3))) {
2779 mef_cfg.criteria |= MWIFIEX_CRITERIA_MULTICAST; 2859 mef_cfg->criteria |= MWIFIEX_CRITERIA_MULTICAST;
2780 continue; 2860 continue;
2781 } 2861 }
2782 } 2862 }
2783
2784 mef_entry->filter[filt_num].repeat = 1; 2863 mef_entry->filter[filt_num].repeat = 1;
2785 mef_entry->filter[filt_num].offset = 2864 mef_entry->filter[filt_num].offset =
2786 wowlan->patterns[i].pkt_offset; 2865 wowlan->patterns[i].pkt_offset;
@@ -2797,7 +2876,7 @@ static int mwifiex_set_mef_filter(struct mwifiex_private *priv,
2797 } 2876 }
2798 2877
2799 if (wowlan->magic_pkt) { 2878 if (wowlan->magic_pkt) {
2800 mef_cfg.criteria |= MWIFIEX_CRITERIA_UNICAST; 2879 mef_cfg->criteria |= MWIFIEX_CRITERIA_UNICAST;
2801 mef_entry->filter[filt_num].repeat = 16; 2880 mef_entry->filter[filt_num].repeat = 16;
2802 memcpy(mef_entry->filter[filt_num].byte_seq, priv->curr_addr, 2881 memcpy(mef_entry->filter[filt_num].byte_seq, priv->curr_addr,
2803 ETH_ALEN); 2882 ETH_ALEN);
@@ -2818,6 +2897,34 @@ static int mwifiex_set_mef_filter(struct mwifiex_private *priv,
2818 mef_entry->filter[filt_num].filt_type = TYPE_EQ; 2897 mef_entry->filter[filt_num].filt_type = TYPE_EQ;
2819 mef_entry->filter[filt_num].filt_action = TYPE_OR; 2898 mef_entry->filter[filt_num].filt_action = TYPE_OR;
2820 } 2899 }
2900 return ret;
2901}
2902
2903static int mwifiex_set_mef_filter(struct mwifiex_private *priv,
2904 struct cfg80211_wowlan *wowlan)
2905{
2906 int ret = 0, num_entries = 1;
2907 struct mwifiex_ds_mef_cfg mef_cfg;
2908 struct mwifiex_mef_entry *mef_entry;
2909
2910 if (wowlan->n_patterns || wowlan->magic_pkt)
2911 num_entries++;
2912
2913 mef_entry = kcalloc(num_entries, sizeof(*mef_entry), GFP_KERNEL);
2914 if (!mef_entry)
2915 return -ENOMEM;
2916
2917 memset(&mef_cfg, 0, sizeof(mef_cfg));
2918 mef_cfg.criteria |= MWIFIEX_CRITERIA_BROADCAST |
2919 MWIFIEX_CRITERIA_UNICAST;
2920 mef_cfg.num_entries = num_entries;
2921 mef_cfg.mef_entry = mef_entry;
2922
2923 mwifiex_set_auto_arp_mef_entry(priv, &mef_entry[0]);
2924
2925 if (wowlan->n_patterns || wowlan->magic_pkt)
2926 ret = mwifiex_set_wowlan_mef_entry(priv, &mef_cfg,
2927 &mef_entry[1], wowlan);
2821 2928
2822 if (!mef_cfg.criteria) 2929 if (!mef_cfg.criteria)
2823 mef_cfg.criteria = MWIFIEX_CRITERIA_BROADCAST | 2930 mef_cfg.criteria = MWIFIEX_CRITERIA_BROADCAST |
@@ -2825,8 +2932,8 @@ static int mwifiex_set_mef_filter(struct mwifiex_private *priv,
2825 MWIFIEX_CRITERIA_MULTICAST; 2932 MWIFIEX_CRITERIA_MULTICAST;
2826 2933
2827 ret = mwifiex_send_cmd(priv, HostCmd_CMD_MEF_CFG, 2934 ret = mwifiex_send_cmd(priv, HostCmd_CMD_MEF_CFG,
2828 HostCmd_ACT_GEN_SET, 0, &mef_cfg, true); 2935 HostCmd_ACT_GEN_SET, 0,
2829 2936 &mef_cfg, true);
2830 kfree(mef_entry); 2937 kfree(mef_entry);
2831 return ret; 2938 return ret;
2832} 2939}
@@ -2836,27 +2943,33 @@ static int mwifiex_cfg80211_suspend(struct wiphy *wiphy,
2836{ 2943{
2837 struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy); 2944 struct mwifiex_adapter *adapter = mwifiex_cfg80211_get_adapter(wiphy);
2838 struct mwifiex_ds_hs_cfg hs_cfg; 2945 struct mwifiex_ds_hs_cfg hs_cfg;
2839 int ret = 0; 2946 int i, ret = 0;
2840 struct mwifiex_private *priv = 2947 struct mwifiex_private *priv;
2841 mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA); 2948
2949 for (i = 0; i < adapter->priv_num; i++) {
2950 priv = adapter->priv[i];
2951 mwifiex_abort_cac(priv);
2952 }
2953
2954 mwifiex_cancel_all_pending_cmd(adapter);
2842 2955
2843 if (!wowlan) { 2956 if (!wowlan) {
2844 dev_warn(adapter->dev, "None of the WOWLAN triggers enabled\n"); 2957 dev_warn(adapter->dev, "None of the WOWLAN triggers enabled\n");
2845 return 0; 2958 return 0;
2846 } 2959 }
2847 2960
2961 priv = mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA);
2962
2848 if (!priv->media_connected) { 2963 if (!priv->media_connected) {
2849 dev_warn(adapter->dev, 2964 dev_warn(adapter->dev,
2850 "Can not configure WOWLAN in disconnected state\n"); 2965 "Can not configure WOWLAN in disconnected state\n");
2851 return 0; 2966 return 0;
2852 } 2967 }
2853 2968
2854 if (wowlan->n_patterns || wowlan->magic_pkt) { 2969 ret = mwifiex_set_mef_filter(priv, wowlan);
2855 ret = mwifiex_set_mef_filter(priv, wowlan); 2970 if (ret) {
2856 if (ret) { 2971 dev_err(adapter->dev, "Failed to set MEF filter\n");
2857 dev_err(adapter->dev, "Failed to set MEF filter\n"); 2972 return ret;
2858 return ret;
2859 }
2860 } 2973 }
2861 2974
2862 if (wowlan->disconnect) { 2975 if (wowlan->disconnect) {
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h
index cf2fa110e251..38f24e0427d2 100644
--- a/drivers/net/wireless/mwifiex/decl.h
+++ b/drivers/net/wireless/mwifiex/decl.h
@@ -83,6 +83,7 @@
83#define MWIFIEX_BUF_FLAG_TDLS_PKT BIT(2) 83#define MWIFIEX_BUF_FLAG_TDLS_PKT BIT(2)
84#define MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS BIT(3) 84#define MWIFIEX_BUF_FLAG_EAPOL_TX_STATUS BIT(3)
85#define MWIFIEX_BUF_FLAG_ACTION_TX_STATUS BIT(4) 85#define MWIFIEX_BUF_FLAG_ACTION_TX_STATUS BIT(4)
86#define MWIFIEX_BUF_FLAG_AGGR_PKT BIT(5)
86 87
87#define MWIFIEX_BRIDGED_PKTS_THR_HIGH 1024 88#define MWIFIEX_BRIDGED_PKTS_THR_HIGH 1024
88#define MWIFIEX_BRIDGED_PKTS_THR_LOW 128 89#define MWIFIEX_BRIDGED_PKTS_THR_LOW 128
@@ -111,6 +112,11 @@
111 112
112#define MWIFIEX_A_BAND_START_FREQ 5000 113#define MWIFIEX_A_BAND_START_FREQ 5000
113 114
115/* SDIO Aggr data packet special info */
116#define SDIO_MAX_AGGR_BUF_SIZE (256 * 255)
117#define BLOCK_NUMBER_OFFSET 15
118#define SDIO_HEADER_OFFSET 28
119
114enum mwifiex_bss_type { 120enum mwifiex_bss_type {
115 MWIFIEX_BSS_TYPE_STA = 0, 121 MWIFIEX_BSS_TYPE_STA = 0,
116 MWIFIEX_BSS_TYPE_UAP = 1, 122 MWIFIEX_BSS_TYPE_UAP = 1,
@@ -168,10 +174,11 @@ struct mwifiex_wait_queue {
168}; 174};
169 175
170struct mwifiex_rxinfo { 176struct mwifiex_rxinfo {
177 struct sk_buff *parent;
171 u8 bss_num; 178 u8 bss_num;
172 u8 bss_type; 179 u8 bss_type;
173 struct sk_buff *parent;
174 u8 use_count; 180 u8 use_count;
181 u8 buf_type;
175}; 182};
176 183
177struct mwifiex_txinfo { 184struct mwifiex_txinfo {
@@ -179,6 +186,7 @@ struct mwifiex_txinfo {
179 u8 flags; 186 u8 flags;
180 u8 bss_num; 187 u8 bss_num;
181 u8 bss_type; 188 u8 bss_type;
189 u8 aggr_num;
182 u32 pkt_len; 190 u32 pkt_len;
183 u8 ack_frame_id; 191 u8 ack_frame_id;
184 u64 cookie; 192 u64 cookie;
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index df553e86a0ad..59d8964dd0dc 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -197,6 +197,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
197 197
198#define ISSUPP_11NENABLED(FwCapInfo) (FwCapInfo & BIT(11)) 198#define ISSUPP_11NENABLED(FwCapInfo) (FwCapInfo & BIT(11))
199#define ISSUPP_TDLS_ENABLED(FwCapInfo) (FwCapInfo & BIT(14)) 199#define ISSUPP_TDLS_ENABLED(FwCapInfo) (FwCapInfo & BIT(14))
200#define ISSUPP_SDIO_SPA_ENABLED(FwCapInfo) (FwCapInfo & BIT(16))
200 201
201#define MWIFIEX_DEF_HT_CAP (IEEE80211_HT_CAP_DSSSCCK40 | \ 202#define MWIFIEX_DEF_HT_CAP (IEEE80211_HT_CAP_DSSSCCK40 | \
202 (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT) | \ 203 (1 << IEEE80211_HT_CAP_RX_STBC_SHIFT) | \
@@ -353,6 +354,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
353#define HostCmd_CMD_REMAIN_ON_CHAN 0x010d 354#define HostCmd_CMD_REMAIN_ON_CHAN 0x010d
354#define HostCmd_CMD_11AC_CFG 0x0112 355#define HostCmd_CMD_11AC_CFG 0x0112
355#define HostCmd_CMD_TDLS_OPER 0x0122 356#define HostCmd_CMD_TDLS_OPER 0x0122
357#define HostCmd_CMD_SDIO_SP_RX_AGGR_CFG 0x0223
356 358
357#define PROTOCOL_NO_SECURITY 0x01 359#define PROTOCOL_NO_SECURITY 0x01
358#define PROTOCOL_STATIC_WEP 0x02 360#define PROTOCOL_STATIC_WEP 0x02
@@ -523,9 +525,11 @@ enum P2P_MODES {
523#define TYPE_OR (MAX_OPERAND+5) 525#define TYPE_OR (MAX_OPERAND+5)
524#define MEF_MODE_HOST_SLEEP 1 526#define MEF_MODE_HOST_SLEEP 1
525#define MEF_ACTION_ALLOW_AND_WAKEUP_HOST 3 527#define MEF_ACTION_ALLOW_AND_WAKEUP_HOST 3
528#define MEF_ACTION_AUTO_ARP 0x10
526#define MWIFIEX_CRITERIA_BROADCAST BIT(0) 529#define MWIFIEX_CRITERIA_BROADCAST BIT(0)
527#define MWIFIEX_CRITERIA_UNICAST BIT(1) 530#define MWIFIEX_CRITERIA_UNICAST BIT(1)
528#define MWIFIEX_CRITERIA_MULTICAST BIT(3) 531#define MWIFIEX_CRITERIA_MULTICAST BIT(3)
532#define MWIFIEX_MAX_SUPPORTED_IPADDR 4
529 533
530#define ACT_TDLS_DELETE 0x00 534#define ACT_TDLS_DELETE 0x00
531#define ACT_TDLS_CREATE 0x01 535#define ACT_TDLS_CREATE 0x01
@@ -1240,6 +1244,12 @@ struct host_cmd_ds_chan_rpt_event {
1240 u8 tlvbuf[0]; 1244 u8 tlvbuf[0];
1241} __packed; 1245} __packed;
1242 1246
1247struct host_cmd_sdio_sp_rx_aggr_cfg {
1248 u8 action;
1249 u8 enable;
1250 __le16 block_size;
1251} __packed;
1252
1243struct mwifiex_fixed_bcn_param { 1253struct mwifiex_fixed_bcn_param {
1244 __le64 timestamp; 1254 __le64 timestamp;
1245 __le16 beacon_period; 1255 __le16 beacon_period;
@@ -1962,6 +1972,7 @@ struct host_cmd_ds_command {
1962 struct host_cmd_ds_coalesce_cfg coalesce_cfg; 1972 struct host_cmd_ds_coalesce_cfg coalesce_cfg;
1963 struct host_cmd_ds_tdls_oper tdls_oper; 1973 struct host_cmd_ds_tdls_oper tdls_oper;
1964 struct host_cmd_ds_chan_rpt_req chan_rpt_req; 1974 struct host_cmd_ds_chan_rpt_req chan_rpt_req;
1975 struct host_cmd_sdio_sp_rx_aggr_cfg sdio_rx_aggr_cfg;
1965 } params; 1976 } params;
1966} __packed; 1977} __packed;
1967 1978
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 0153ce6d5879..e12192f5cfad 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -266,18 +266,15 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
266 266
267 mwifiex_wmm_init(adapter); 267 mwifiex_wmm_init(adapter);
268 268
269 if (adapter->sleep_cfm) { 269 sleep_cfm_buf = (struct mwifiex_opt_sleep_confirm *)
270 sleep_cfm_buf = (struct mwifiex_opt_sleep_confirm *) 270 adapter->sleep_cfm->data;
271 adapter->sleep_cfm->data; 271 memset(sleep_cfm_buf, 0, adapter->sleep_cfm->len);
272 memset(sleep_cfm_buf, 0, adapter->sleep_cfm->len); 272 sleep_cfm_buf->command = cpu_to_le16(HostCmd_CMD_802_11_PS_MODE_ENH);
273 sleep_cfm_buf->command = 273 sleep_cfm_buf->size = cpu_to_le16(adapter->sleep_cfm->len);
274 cpu_to_le16(HostCmd_CMD_802_11_PS_MODE_ENH); 274 sleep_cfm_buf->result = 0;
275 sleep_cfm_buf->size = 275 sleep_cfm_buf->action = cpu_to_le16(SLEEP_CONFIRM);
276 cpu_to_le16(adapter->sleep_cfm->len); 276 sleep_cfm_buf->resp_ctrl = cpu_to_le16(RESP_NEEDED);
277 sleep_cfm_buf->result = 0; 277
278 sleep_cfm_buf->action = cpu_to_le16(SLEEP_CONFIRM);
279 sleep_cfm_buf->resp_ctrl = cpu_to_le16(RESP_NEEDED);
280 }
281 memset(&adapter->sleep_params, 0, sizeof(adapter->sleep_params)); 278 memset(&adapter->sleep_params, 0, sizeof(adapter->sleep_params));
282 memset(&adapter->sleep_period, 0, sizeof(adapter->sleep_period)); 279 memset(&adapter->sleep_period, 0, sizeof(adapter->sleep_period));
283 adapter->tx_lock_flag = false; 280 adapter->tx_lock_flag = false;
@@ -481,6 +478,7 @@ int mwifiex_init_lock_list(struct mwifiex_adapter *adapter)
481 spin_lock_init(&adapter->rx_proc_lock); 478 spin_lock_init(&adapter->rx_proc_lock);
482 479
483 skb_queue_head_init(&adapter->rx_data_q); 480 skb_queue_head_init(&adapter->rx_data_q);
481 skb_queue_head_init(&adapter->tx_data_q);
484 482
485 for (i = 0; i < adapter->priv_num; ++i) { 483 for (i = 0; i < adapter->priv_num; ++i) {
486 INIT_LIST_HEAD(&adapter->bss_prio_tbl[i].bss_prio_head); 484 INIT_LIST_HEAD(&adapter->bss_prio_tbl[i].bss_prio_head);
@@ -688,6 +686,10 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter)
688 } 686 }
689 } 687 }
690 688
689 atomic_set(&adapter->tx_queued, 0);
690 while ((skb = skb_dequeue(&adapter->tx_data_q)))
691 mwifiex_write_data_complete(adapter, skb, 0, 0);
692
691 spin_lock_irqsave(&adapter->rx_proc_lock, flags); 693 spin_lock_irqsave(&adapter->rx_proc_lock, flags);
692 694
693 while ((skb = skb_dequeue(&adapter->rx_data_q))) { 695 while ((skb = skb_dequeue(&adapter->rx_data_q))) {
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index d73a9217b9da..03a95c7d34bf 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -131,10 +131,39 @@ static int mwifiex_unregister(struct mwifiex_adapter *adapter)
131 return 0; 131 return 0;
132} 132}
133 133
134void mwifiex_queue_main_work(struct mwifiex_adapter *adapter)
135{
136 unsigned long flags;
137
138 spin_lock_irqsave(&adapter->main_proc_lock, flags);
139 if (adapter->mwifiex_processing) {
140 adapter->more_task_flag = true;
141 spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
142 } else {
143 spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
144 queue_work(adapter->workqueue, &adapter->main_work);
145 }
146}
147EXPORT_SYMBOL_GPL(mwifiex_queue_main_work);
148
149static void mwifiex_queue_rx_work(struct mwifiex_adapter *adapter)
150{
151 unsigned long flags;
152
153 spin_lock_irqsave(&adapter->rx_proc_lock, flags);
154 if (adapter->rx_processing) {
155 spin_unlock_irqrestore(&adapter->rx_proc_lock, flags);
156 } else {
157 spin_unlock_irqrestore(&adapter->rx_proc_lock, flags);
158 queue_work(adapter->rx_workqueue, &adapter->rx_work);
159 }
160}
161
134static int mwifiex_process_rx(struct mwifiex_adapter *adapter) 162static int mwifiex_process_rx(struct mwifiex_adapter *adapter)
135{ 163{
136 unsigned long flags; 164 unsigned long flags;
137 struct sk_buff *skb; 165 struct sk_buff *skb;
166 struct mwifiex_rxinfo *rx_info;
138 167
139 spin_lock_irqsave(&adapter->rx_proc_lock, flags); 168 spin_lock_irqsave(&adapter->rx_proc_lock, flags);
140 if (adapter->rx_processing || adapter->rx_locked) { 169 if (adapter->rx_processing || adapter->rx_locked) {
@@ -154,9 +183,16 @@ static int mwifiex_process_rx(struct mwifiex_adapter *adapter)
154 if (adapter->if_ops.submit_rem_rx_urbs) 183 if (adapter->if_ops.submit_rem_rx_urbs)
155 adapter->if_ops.submit_rem_rx_urbs(adapter); 184 adapter->if_ops.submit_rem_rx_urbs(adapter);
156 adapter->delay_main_work = false; 185 adapter->delay_main_work = false;
157 queue_work(adapter->workqueue, &adapter->main_work); 186 mwifiex_queue_main_work(adapter);
187 }
188 rx_info = MWIFIEX_SKB_RXCB(skb);
189 if (rx_info->buf_type == MWIFIEX_TYPE_AGGR_DATA) {
190 if (adapter->if_ops.deaggr_pkt)
191 adapter->if_ops.deaggr_pkt(adapter, skb);
192 dev_kfree_skb_any(skb);
193 } else {
194 mwifiex_handle_rx_packet(adapter, skb);
158 } 195 }
159 mwifiex_handle_rx_packet(adapter, skb);
160 } 196 }
161 spin_lock_irqsave(&adapter->rx_proc_lock, flags); 197 spin_lock_irqsave(&adapter->rx_proc_lock, flags);
162 adapter->rx_processing = false; 198 adapter->rx_processing = false;
@@ -189,7 +225,7 @@ int mwifiex_main_process(struct mwifiex_adapter *adapter)
189 spin_lock_irqsave(&adapter->main_proc_lock, flags); 225 spin_lock_irqsave(&adapter->main_proc_lock, flags);
190 226
191 /* Check if already processing */ 227 /* Check if already processing */
192 if (adapter->mwifiex_processing) { 228 if (adapter->mwifiex_processing || adapter->main_locked) {
193 adapter->more_task_flag = true; 229 adapter->more_task_flag = true;
194 spin_unlock_irqrestore(&adapter->main_proc_lock, flags); 230 spin_unlock_irqrestore(&adapter->main_proc_lock, flags);
195 goto exit_main_proc; 231 goto exit_main_proc;
@@ -214,9 +250,7 @@ process_start:
214 if (atomic_read(&adapter->rx_pending) >= HIGH_RX_PENDING && 250 if (atomic_read(&adapter->rx_pending) >= HIGH_RX_PENDING &&
215 adapter->iface_type != MWIFIEX_USB) { 251 adapter->iface_type != MWIFIEX_USB) {
216 adapter->delay_main_work = true; 252 adapter->delay_main_work = true;
217 if (!adapter->rx_processing) 253 mwifiex_queue_rx_work(adapter);
218 queue_work(adapter->rx_workqueue,
219 &adapter->rx_work);
220 break; 254 break;
221 } 255 }
222 256
@@ -229,13 +263,14 @@ process_start:
229 } 263 }
230 264
231 if (adapter->rx_work_enabled && adapter->data_received) 265 if (adapter->rx_work_enabled && adapter->data_received)
232 queue_work(adapter->rx_workqueue, &adapter->rx_work); 266 mwifiex_queue_rx_work(adapter);
233 267
234 /* Need to wake up the card ? */ 268 /* Need to wake up the card ? */
235 if ((adapter->ps_state == PS_STATE_SLEEP) && 269 if ((adapter->ps_state == PS_STATE_SLEEP) &&
236 (adapter->pm_wakeup_card_req && 270 (adapter->pm_wakeup_card_req &&
237 !adapter->pm_wakeup_fw_try) && 271 !adapter->pm_wakeup_fw_try) &&
238 (is_command_pending(adapter) || 272 (is_command_pending(adapter) ||
273 !skb_queue_empty(&adapter->tx_data_q) ||
239 !mwifiex_wmm_lists_empty(adapter))) { 274 !mwifiex_wmm_lists_empty(adapter))) {
240 adapter->pm_wakeup_fw_try = true; 275 adapter->pm_wakeup_fw_try = true;
241 mod_timer(&adapter->wakeup_timer, jiffies + (HZ*3)); 276 mod_timer(&adapter->wakeup_timer, jiffies + (HZ*3));
@@ -247,7 +282,7 @@ process_start:
247 if (IS_CARD_RX_RCVD(adapter)) { 282 if (IS_CARD_RX_RCVD(adapter)) {
248 adapter->data_received = false; 283 adapter->data_received = false;
249 adapter->pm_wakeup_fw_try = false; 284 adapter->pm_wakeup_fw_try = false;
250 del_timer_sync(&adapter->wakeup_timer); 285 del_timer(&adapter->wakeup_timer);
251 if (adapter->ps_state == PS_STATE_SLEEP) 286 if (adapter->ps_state == PS_STATE_SLEEP)
252 adapter->ps_state = PS_STATE_AWAKE; 287 adapter->ps_state = PS_STATE_AWAKE;
253 } else { 288 } else {
@@ -260,7 +295,8 @@ process_start:
260 295
261 if ((!adapter->scan_chan_gap_enabled && 296 if ((!adapter->scan_chan_gap_enabled &&
262 adapter->scan_processing) || adapter->data_sent || 297 adapter->scan_processing) || adapter->data_sent ||
263 mwifiex_wmm_lists_empty(adapter)) { 298 (mwifiex_wmm_lists_empty(adapter) &&
299 skb_queue_empty(&adapter->tx_data_q))) {
264 if (adapter->cmd_sent || adapter->curr_cmd || 300 if (adapter->cmd_sent || adapter->curr_cmd ||
265 (!is_command_pending(adapter))) 301 (!is_command_pending(adapter)))
266 break; 302 break;
@@ -312,6 +348,20 @@ process_start:
312 348
313 if ((adapter->scan_chan_gap_enabled || 349 if ((adapter->scan_chan_gap_enabled ||
314 !adapter->scan_processing) && 350 !adapter->scan_processing) &&
351 !adapter->data_sent &&
352 !skb_queue_empty(&adapter->tx_data_q)) {
353 mwifiex_process_tx_queue(adapter);
354 if (adapter->hs_activated) {
355 adapter->is_hs_configured = false;
356 mwifiex_hs_activated_event
357 (mwifiex_get_priv
358 (adapter, MWIFIEX_BSS_ROLE_ANY),
359 false);
360 }
361 }
362
363 if ((adapter->scan_chan_gap_enabled ||
364 !adapter->scan_processing) &&
315 !adapter->data_sent && !mwifiex_wmm_lists_empty(adapter)) { 365 !adapter->data_sent && !mwifiex_wmm_lists_empty(adapter)) {
316 mwifiex_wmm_process_tx(adapter); 366 mwifiex_wmm_process_tx(adapter);
317 if (adapter->hs_activated) { 367 if (adapter->hs_activated) {
@@ -325,7 +375,8 @@ process_start:
325 375
326 if (adapter->delay_null_pkt && !adapter->cmd_sent && 376 if (adapter->delay_null_pkt && !adapter->cmd_sent &&
327 !adapter->curr_cmd && !is_command_pending(adapter) && 377 !adapter->curr_cmd && !is_command_pending(adapter) &&
328 mwifiex_wmm_lists_empty(adapter)) { 378 (mwifiex_wmm_lists_empty(adapter) &&
379 skb_queue_empty(&adapter->tx_data_q))) {
329 if (!mwifiex_send_null_packet 380 if (!mwifiex_send_null_packet
330 (mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA), 381 (mwifiex_get_priv(adapter, MWIFIEX_BSS_ROLE_STA),
331 MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET | 382 MWIFIEX_TxPD_POWER_MGMT_NULL_PACKET |
@@ -606,7 +657,7 @@ int mwifiex_queue_tx_pkt(struct mwifiex_private *priv, struct sk_buff *skb)
606 atomic_inc(&priv->adapter->tx_pending); 657 atomic_inc(&priv->adapter->tx_pending);
607 mwifiex_wmm_add_buf_txqueue(priv, skb); 658 mwifiex_wmm_add_buf_txqueue(priv, skb);
608 659
609 queue_work(priv->adapter->workqueue, &priv->adapter->main_work); 660 mwifiex_queue_main_work(priv->adapter);
610 661
611 return 0; 662 return 0;
612} 663}
@@ -1098,9 +1149,6 @@ mwifiex_add_card(void *card, struct semaphore *sem,
1098 INIT_WORK(&adapter->rx_work, mwifiex_rx_work_queue); 1149 INIT_WORK(&adapter->rx_work, mwifiex_rx_work_queue);
1099 } 1150 }
1100 1151
1101 if (adapter->if_ops.iface_work)
1102 INIT_WORK(&adapter->iface_work, adapter->if_ops.iface_work);
1103
1104 /* Register the device. Fill up the private data structure with relevant 1152 /* Register the device. Fill up the private data structure with relevant
1105 information from the card. */ 1153 information from the card. */
1106 if (adapter->if_ops.register_dev(adapter)) { 1154 if (adapter->if_ops.register_dev(adapter)) {
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index ad8db61aeeef..fe1256044a6c 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -35,6 +35,7 @@
35#include <linux/ctype.h> 35#include <linux/ctype.h>
36#include <linux/of.h> 36#include <linux/of.h>
37#include <linux/idr.h> 37#include <linux/idr.h>
38#include <linux/inetdevice.h>
38 39
39#include "decl.h" 40#include "decl.h"
40#include "ioctl.h" 41#include "ioctl.h"
@@ -58,6 +59,8 @@ enum {
58 59
59#define MWIFIEX_MAX_AP 64 60#define MWIFIEX_MAX_AP 64
60 61
62#define MWIFIEX_MAX_PKTS_TXQ 16
63
61#define MWIFIEX_DEFAULT_WATCHDOG_TIMEOUT (5 * HZ) 64#define MWIFIEX_DEFAULT_WATCHDOG_TIMEOUT (5 * HZ)
62 65
63#define MWIFIEX_TIMER_10S 10000 66#define MWIFIEX_TIMER_10S 10000
@@ -118,6 +121,7 @@ enum {
118 121
119#define MWIFIEX_TYPE_CMD 1 122#define MWIFIEX_TYPE_CMD 1
120#define MWIFIEX_TYPE_DATA 0 123#define MWIFIEX_TYPE_DATA 0
124#define MWIFIEX_TYPE_AGGR_DATA 10
121#define MWIFIEX_TYPE_EVENT 3 125#define MWIFIEX_TYPE_EVENT 3
122 126
123#define MAX_BITMAP_RATES_SIZE 18 127#define MAX_BITMAP_RATES_SIZE 18
@@ -210,6 +214,12 @@ struct mwifiex_tx_aggr {
210 u8 amsdu; 214 u8 amsdu;
211}; 215};
212 216
217enum mwifiex_ba_status {
218 BA_SETUP_NONE = 0,
219 BA_SETUP_INPROGRESS,
220 BA_SETUP_COMPLETE
221};
222
213struct mwifiex_ra_list_tbl { 223struct mwifiex_ra_list_tbl {
214 struct list_head list; 224 struct list_head list;
215 struct sk_buff_head skb_head; 225 struct sk_buff_head skb_head;
@@ -218,6 +228,8 @@ struct mwifiex_ra_list_tbl {
218 u16 max_amsdu; 228 u16 max_amsdu;
219 u16 ba_pkt_count; 229 u16 ba_pkt_count;
220 u8 ba_packet_thr; 230 u8 ba_packet_thr;
231 enum mwifiex_ba_status ba_status;
232 u8 amsdu_in_ampdu;
221 u16 total_pkt_count; 233 u16 total_pkt_count;
222 bool tdls_link; 234 bool tdls_link;
223}; 235};
@@ -601,11 +613,6 @@ struct mwifiex_private {
601 struct mwifiex_11h_intf_state state_11h; 613 struct mwifiex_11h_intf_state state_11h;
602}; 614};
603 615
604enum mwifiex_ba_status {
605 BA_SETUP_NONE = 0,
606 BA_SETUP_INPROGRESS,
607 BA_SETUP_COMPLETE
608};
609 616
610struct mwifiex_tx_ba_stream_tbl { 617struct mwifiex_tx_ba_stream_tbl {
611 struct list_head list; 618 struct list_head list;
@@ -738,6 +745,7 @@ struct mwifiex_if_ops {
738 int (*clean_pcie_ring) (struct mwifiex_adapter *adapter); 745 int (*clean_pcie_ring) (struct mwifiex_adapter *adapter);
739 void (*iface_work)(struct work_struct *work); 746 void (*iface_work)(struct work_struct *work);
740 void (*submit_rem_rx_urbs)(struct mwifiex_adapter *adapter); 747 void (*submit_rem_rx_urbs)(struct mwifiex_adapter *adapter);
748 void (*deaggr_pkt)(struct mwifiex_adapter *, struct sk_buff *);
741}; 749};
742 750
743struct mwifiex_adapter { 751struct mwifiex_adapter {
@@ -771,6 +779,7 @@ struct mwifiex_adapter {
771 bool rx_processing; 779 bool rx_processing;
772 bool delay_main_work; 780 bool delay_main_work;
773 bool rx_locked; 781 bool rx_locked;
782 bool main_locked;
774 struct mwifiex_bss_prio_tbl bss_prio_tbl[MWIFIEX_MAX_BSS_NUM]; 783 struct mwifiex_bss_prio_tbl bss_prio_tbl[MWIFIEX_MAX_BSS_NUM];
775 /* spin lock for init/shutdown */ 784 /* spin lock for init/shutdown */
776 spinlock_t mwifiex_lock; 785 spinlock_t mwifiex_lock;
@@ -780,6 +789,8 @@ struct mwifiex_adapter {
780 u8 more_task_flag; 789 u8 more_task_flag;
781 u16 tx_buf_size; 790 u16 tx_buf_size;
782 u16 curr_tx_buf_size; 791 u16 curr_tx_buf_size;
792 bool sdio_rx_aggr_enable;
793 u16 sdio_rx_block_size;
783 u32 ioport; 794 u32 ioport;
784 enum MWIFIEX_HARDWARE_STATUS hw_status; 795 enum MWIFIEX_HARDWARE_STATUS hw_status;
785 u16 number_of_antenna; 796 u16 number_of_antenna;
@@ -814,6 +825,8 @@ struct mwifiex_adapter {
814 spinlock_t scan_pending_q_lock; 825 spinlock_t scan_pending_q_lock;
815 /* spin lock for RX processing routine */ 826 /* spin lock for RX processing routine */
816 spinlock_t rx_proc_lock; 827 spinlock_t rx_proc_lock;
828 struct sk_buff_head tx_data_q;
829 atomic_t tx_queued;
817 u32 scan_processing; 830 u32 scan_processing;
818 u16 region_code; 831 u16 region_code;
819 struct mwifiex_802_11d_domain_reg domain_reg; 832 struct mwifiex_802_11d_domain_reg domain_reg;
@@ -885,8 +898,6 @@ struct mwifiex_adapter {
885 bool ext_scan; 898 bool ext_scan;
886 u8 fw_api_ver; 899 u8 fw_api_ver;
887 u8 key_api_major_ver, key_api_minor_ver; 900 u8 key_api_major_ver, key_api_minor_ver;
888 struct work_struct iface_work;
889 unsigned long iface_work_flags;
890 struct memory_type_mapping *mem_type_mapping_tbl; 901 struct memory_type_mapping *mem_type_mapping_tbl;
891 u8 num_mem_types; 902 u8 num_mem_types;
892 u8 curr_mem_idx; 903 u8 curr_mem_idx;
@@ -900,6 +911,8 @@ struct mwifiex_adapter {
900 bool auto_tdls; 911 bool auto_tdls;
901}; 912};
902 913
914void mwifiex_process_tx_queue(struct mwifiex_adapter *adapter);
915
903int mwifiex_init_lock_list(struct mwifiex_adapter *adapter); 916int mwifiex_init_lock_list(struct mwifiex_adapter *adapter);
904 917
905void mwifiex_set_trans_start(struct net_device *dev); 918void mwifiex_set_trans_start(struct net_device *dev);
@@ -1422,7 +1435,8 @@ u8 mwifiex_adjust_data_rate(struct mwifiex_private *priv,
1422 u8 rx_rate, u8 ht_info); 1435 u8 rx_rate, u8 ht_info);
1423 1436
1424void mwifiex_dump_drv_info(struct mwifiex_adapter *adapter); 1437void mwifiex_dump_drv_info(struct mwifiex_adapter *adapter);
1425void *mwifiex_alloc_rx_buf(int rx_len, gfp_t flags); 1438void *mwifiex_alloc_dma_align_buf(int rx_len, gfp_t flags);
1439void mwifiex_queue_main_work(struct mwifiex_adapter *adapter);
1426 1440
1427#ifdef CONFIG_DEBUG_FS 1441#ifdef CONFIG_DEBUG_FS
1428void mwifiex_debugfs_init(void); 1442void mwifiex_debugfs_init(void);
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c
index 4b463c3b9906..bcc7751d883c 100644
--- a/drivers/net/wireless/mwifiex/pcie.c
+++ b/drivers/net/wireless/mwifiex/pcie.c
@@ -234,8 +234,6 @@ static void mwifiex_pcie_remove(struct pci_dev *pdev)
234 if (!adapter || !adapter->priv_num) 234 if (!adapter || !adapter->priv_num)
235 return; 235 return;
236 236
237 cancel_work_sync(&adapter->iface_work);
238
239 if (user_rmmod) { 237 if (user_rmmod) {
240#ifdef CONFIG_PM_SLEEP 238#ifdef CONFIG_PM_SLEEP
241 if (adapter->is_suspended) 239 if (adapter->is_suspended)
@@ -498,8 +496,8 @@ static int mwifiex_init_rxq_ring(struct mwifiex_adapter *adapter)
498 496
499 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) { 497 for (i = 0; i < MWIFIEX_MAX_TXRX_BD; i++) {
500 /* Allocate skb here so that firmware can DMA data from it */ 498 /* Allocate skb here so that firmware can DMA data from it */
501 skb = mwifiex_alloc_rx_buf(MWIFIEX_RX_DATA_BUF_SIZE, 499 skb = mwifiex_alloc_dma_align_buf(MWIFIEX_RX_DATA_BUF_SIZE,
502 GFP_KERNEL | GFP_DMA); 500 GFP_KERNEL | GFP_DMA);
503 if (!skb) { 501 if (!skb) {
504 dev_err(adapter->dev, 502 dev_err(adapter->dev,
505 "Unable to allocate skb for RX ring.\n"); 503 "Unable to allocate skb for RX ring.\n");
@@ -1298,8 +1296,8 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
1298 } 1296 }
1299 } 1297 }
1300 1298
1301 skb_tmp = mwifiex_alloc_rx_buf(MWIFIEX_RX_DATA_BUF_SIZE, 1299 skb_tmp = mwifiex_alloc_dma_align_buf(MWIFIEX_RX_DATA_BUF_SIZE,
1302 GFP_KERNEL | GFP_DMA); 1300 GFP_KERNEL | GFP_DMA);
1303 if (!skb_tmp) { 1301 if (!skb_tmp) {
1304 dev_err(adapter->dev, 1302 dev_err(adapter->dev,
1305 "Unable to allocate skb.\n"); 1303 "Unable to allocate skb.\n");
@@ -2101,7 +2099,7 @@ static irqreturn_t mwifiex_pcie_interrupt(int irq, void *context)
2101 goto exit; 2099 goto exit;
2102 2100
2103 mwifiex_interrupt_status(adapter); 2101 mwifiex_interrupt_status(adapter);
2104 queue_work(adapter->workqueue, &adapter->main_work); 2102 mwifiex_queue_main_work(adapter);
2105 2103
2106exit: 2104exit:
2107 return IRQ_HANDLED; 2105 return IRQ_HANDLED;
@@ -2373,25 +2371,26 @@ done:
2373 adapter->curr_mem_idx = 0; 2371 adapter->curr_mem_idx = 0;
2374} 2372}
2375 2373
2374static unsigned long iface_work_flags;
2375static struct mwifiex_adapter *save_adapter;
2376static void mwifiex_pcie_work(struct work_struct *work) 2376static void mwifiex_pcie_work(struct work_struct *work)
2377{ 2377{
2378 struct mwifiex_adapter *adapter =
2379 container_of(work, struct mwifiex_adapter, iface_work);
2380
2381 if (test_and_clear_bit(MWIFIEX_IFACE_WORK_FW_DUMP, 2378 if (test_and_clear_bit(MWIFIEX_IFACE_WORK_FW_DUMP,
2382 &adapter->iface_work_flags)) 2379 &iface_work_flags))
2383 mwifiex_pcie_fw_dump_work(adapter); 2380 mwifiex_pcie_fw_dump_work(save_adapter);
2384} 2381}
2385 2382
2383static DECLARE_WORK(pcie_work, mwifiex_pcie_work);
2386/* This function dumps FW information */ 2384/* This function dumps FW information */
2387static void mwifiex_pcie_fw_dump(struct mwifiex_adapter *adapter) 2385static void mwifiex_pcie_fw_dump(struct mwifiex_adapter *adapter)
2388{ 2386{
2389 if (test_bit(MWIFIEX_IFACE_WORK_FW_DUMP, &adapter->iface_work_flags)) 2387 save_adapter = adapter;
2388 if (test_bit(MWIFIEX_IFACE_WORK_FW_DUMP, &iface_work_flags))
2390 return; 2389 return;
2391 2390
2392 set_bit(MWIFIEX_IFACE_WORK_FW_DUMP, &adapter->iface_work_flags); 2391 set_bit(MWIFIEX_IFACE_WORK_FW_DUMP, &iface_work_flags);
2393 2392
2394 schedule_work(&adapter->iface_work); 2393 schedule_work(&pcie_work);
2395} 2394}
2396 2395
2397/* 2396/*
@@ -2619,7 +2618,6 @@ static struct mwifiex_if_ops pcie_ops = {
2619 .init_fw_port = mwifiex_pcie_init_fw_port, 2618 .init_fw_port = mwifiex_pcie_init_fw_port,
2620 .clean_pcie_ring = mwifiex_clean_pcie_ring_buf, 2619 .clean_pcie_ring = mwifiex_clean_pcie_ring_buf,
2621 .fw_dump = mwifiex_pcie_fw_dump, 2620 .fw_dump = mwifiex_pcie_fw_dump,
2622 .iface_work = mwifiex_pcie_work,
2623}; 2621};
2624 2622
2625/* 2623/*
@@ -2665,6 +2663,7 @@ static void mwifiex_pcie_cleanup_module(void)
2665 /* Set the flag as user is removing this module. */ 2663 /* Set the flag as user is removing this module. */
2666 user_rmmod = 1; 2664 user_rmmod = 1;
2667 2665
2666 cancel_work_sync(&pcie_work);
2668 pci_unregister_driver(&mwifiex_pcie); 2667 pci_unregister_driver(&mwifiex_pcie);
2669} 2668}
2670 2669
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index 57d85ab442bf..d10320f89bc1 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -47,6 +47,7 @@
47static u8 user_rmmod; 47static u8 user_rmmod;
48 48
49static struct mwifiex_if_ops sdio_ops; 49static struct mwifiex_if_ops sdio_ops;
50static unsigned long iface_work_flags;
50 51
51static struct semaphore add_remove_card_sem; 52static struct semaphore add_remove_card_sem;
52 53
@@ -200,8 +201,6 @@ mwifiex_sdio_remove(struct sdio_func *func)
200 if (!adapter || !adapter->priv_num) 201 if (!adapter || !adapter->priv_num)
201 return; 202 return;
202 203
203 cancel_work_sync(&adapter->iface_work);
204
205 if (user_rmmod) { 204 if (user_rmmod) {
206 if (adapter->is_suspended) 205 if (adapter->is_suspended)
207 mwifiex_sdio_resume(adapter->dev); 206 mwifiex_sdio_resume(adapter->dev);
@@ -1043,6 +1042,59 @@ static int mwifiex_check_fw_status(struct mwifiex_adapter *adapter,
1043} 1042}
1044 1043
1045/* 1044/*
1045 * This function decode sdio aggreation pkt.
1046 *
1047 * Based on the the data block size and pkt_len,
1048 * skb data will be decoded to few packets.
1049 */
1050static void mwifiex_deaggr_sdio_pkt(struct mwifiex_adapter *adapter,
1051 struct sk_buff *skb)
1052{
1053 u32 total_pkt_len, pkt_len;
1054 struct sk_buff *skb_deaggr;
1055 u32 pkt_type;
1056 u16 blk_size;
1057 u8 blk_num;
1058 u8 *data;
1059
1060 data = skb->data;
1061 total_pkt_len = skb->len;
1062
1063 while (total_pkt_len >= (SDIO_HEADER_OFFSET + INTF_HEADER_LEN)) {
1064 if (total_pkt_len < adapter->sdio_rx_block_size)
1065 break;
1066 blk_num = *(data + BLOCK_NUMBER_OFFSET);
1067 blk_size = adapter->sdio_rx_block_size * blk_num;
1068 if (blk_size > total_pkt_len) {
1069 dev_err(adapter->dev, "%s: error in pkt,\t"
1070 "blk_num=%d, blk_size=%d, total_pkt_len=%d\n",
1071 __func__, blk_num, blk_size, total_pkt_len);
1072 break;
1073 }
1074 pkt_len = le16_to_cpu(*(__le16 *)(data + SDIO_HEADER_OFFSET));
1075 pkt_type = le16_to_cpu(*(__le16 *)(data + SDIO_HEADER_OFFSET +
1076 2));
1077 if ((pkt_len + SDIO_HEADER_OFFSET) > blk_size) {
1078 dev_err(adapter->dev, "%s: error in pkt,\t"
1079 "pkt_len=%d, blk_size=%d\n",
1080 __func__, pkt_len, blk_size);
1081 break;
1082 }
1083 skb_deaggr = mwifiex_alloc_dma_align_buf(pkt_len,
1084 GFP_KERNEL | GFP_DMA);
1085 if (!skb_deaggr)
1086 break;
1087 skb_put(skb_deaggr, pkt_len);
1088 memcpy(skb_deaggr->data, data + SDIO_HEADER_OFFSET, pkt_len);
1089 skb_pull(skb_deaggr, INTF_HEADER_LEN);
1090
1091 mwifiex_handle_rx_packet(adapter, skb_deaggr);
1092 data += blk_size;
1093 total_pkt_len -= blk_size;
1094 }
1095}
1096
1097/*
1046 * This function decodes a received packet. 1098 * This function decodes a received packet.
1047 * 1099 *
1048 * Based on the type, the packet is treated as either a data, or 1100 * Based on the type, the packet is treated as either a data, or
@@ -1055,11 +1107,28 @@ static int mwifiex_decode_rx_packet(struct mwifiex_adapter *adapter,
1055 u8 *cmd_buf; 1107 u8 *cmd_buf;
1056 __le16 *curr_ptr = (__le16 *)skb->data; 1108 __le16 *curr_ptr = (__le16 *)skb->data;
1057 u16 pkt_len = le16_to_cpu(*curr_ptr); 1109 u16 pkt_len = le16_to_cpu(*curr_ptr);
1110 struct mwifiex_rxinfo *rx_info;
1058 1111
1059 skb_trim(skb, pkt_len); 1112 if (upld_typ != MWIFIEX_TYPE_AGGR_DATA) {
1060 skb_pull(skb, INTF_HEADER_LEN); 1113 skb_trim(skb, pkt_len);
1114 skb_pull(skb, INTF_HEADER_LEN);
1115 }
1061 1116
1062 switch (upld_typ) { 1117 switch (upld_typ) {
1118 case MWIFIEX_TYPE_AGGR_DATA:
1119 dev_dbg(adapter->dev, "info: --- Rx: Aggr Data packet ---\n");
1120 rx_info = MWIFIEX_SKB_RXCB(skb);
1121 rx_info->buf_type = MWIFIEX_TYPE_AGGR_DATA;
1122 if (adapter->rx_work_enabled) {
1123 skb_queue_tail(&adapter->rx_data_q, skb);
1124 atomic_inc(&adapter->rx_pending);
1125 adapter->data_received = true;
1126 } else {
1127 mwifiex_deaggr_sdio_pkt(adapter, skb);
1128 dev_kfree_skb_any(skb);
1129 }
1130 break;
1131
1063 case MWIFIEX_TYPE_DATA: 1132 case MWIFIEX_TYPE_DATA:
1064 dev_dbg(adapter->dev, "info: --- Rx: Data packet ---\n"); 1133 dev_dbg(adapter->dev, "info: --- Rx: Data packet ---\n");
1065 if (adapter->rx_work_enabled) { 1134 if (adapter->rx_work_enabled) {
@@ -1127,17 +1196,17 @@ static int mwifiex_decode_rx_packet(struct mwifiex_adapter *adapter,
1127 * provided there is space left, processed and finally uploaded. 1196 * provided there is space left, processed and finally uploaded.
1128 */ 1197 */
1129static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter, 1198static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
1130 struct sk_buff *skb, u8 port) 1199 u16 rx_len, u8 port)
1131{ 1200{
1132 struct sdio_mmc_card *card = adapter->card; 1201 struct sdio_mmc_card *card = adapter->card;
1133 s32 f_do_rx_aggr = 0; 1202 s32 f_do_rx_aggr = 0;
1134 s32 f_do_rx_cur = 0; 1203 s32 f_do_rx_cur = 0;
1135 s32 f_aggr_cur = 0; 1204 s32 f_aggr_cur = 0;
1205 s32 f_post_aggr_cur = 0;
1136 struct sk_buff *skb_deaggr; 1206 struct sk_buff *skb_deaggr;
1137 u32 pind; 1207 struct sk_buff *skb = NULL;
1138 u32 pkt_len, pkt_type, mport; 1208 u32 pkt_len, pkt_type, mport, pind;
1139 u8 *curr_ptr; 1209 u8 *curr_ptr;
1140 u32 rx_len = skb->len;
1141 1210
1142 if ((card->has_control_mask) && (port == CTRL_PORT)) { 1211 if ((card->has_control_mask) && (port == CTRL_PORT)) {
1143 /* Read the command Resp without aggr */ 1212 /* Read the command Resp without aggr */
@@ -1164,12 +1233,12 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
1164 dev_dbg(adapter->dev, "info: %s: not last packet\n", __func__); 1233 dev_dbg(adapter->dev, "info: %s: not last packet\n", __func__);
1165 1234
1166 if (MP_RX_AGGR_IN_PROGRESS(card)) { 1235 if (MP_RX_AGGR_IN_PROGRESS(card)) {
1167 if (MP_RX_AGGR_BUF_HAS_ROOM(card, skb->len)) { 1236 if (MP_RX_AGGR_BUF_HAS_ROOM(card, rx_len)) {
1168 f_aggr_cur = 1; 1237 f_aggr_cur = 1;
1169 } else { 1238 } else {
1170 /* No room in Aggr buf, do rx aggr now */ 1239 /* No room in Aggr buf, do rx aggr now */
1171 f_do_rx_aggr = 1; 1240 f_do_rx_aggr = 1;
1172 f_do_rx_cur = 1; 1241 f_post_aggr_cur = 1;
1173 } 1242 }
1174 } else { 1243 } else {
1175 /* Rx aggr not in progress */ 1244 /* Rx aggr not in progress */
@@ -1182,7 +1251,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
1182 1251
1183 if (MP_RX_AGGR_IN_PROGRESS(card)) { 1252 if (MP_RX_AGGR_IN_PROGRESS(card)) {
1184 f_do_rx_aggr = 1; 1253 f_do_rx_aggr = 1;
1185 if (MP_RX_AGGR_BUF_HAS_ROOM(card, skb->len)) 1254 if (MP_RX_AGGR_BUF_HAS_ROOM(card, rx_len))
1186 f_aggr_cur = 1; 1255 f_aggr_cur = 1;
1187 else 1256 else
1188 /* No room in Aggr buf, do rx aggr now */ 1257 /* No room in Aggr buf, do rx aggr now */
@@ -1195,7 +1264,7 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
1195 if (f_aggr_cur) { 1264 if (f_aggr_cur) {
1196 dev_dbg(adapter->dev, "info: current packet aggregation\n"); 1265 dev_dbg(adapter->dev, "info: current packet aggregation\n");
1197 /* Curr pkt can be aggregated */ 1266 /* Curr pkt can be aggregated */
1198 mp_rx_aggr_setup(card, skb, port); 1267 mp_rx_aggr_setup(card, rx_len, port);
1199 1268
1200 if (MP_RX_AGGR_PKT_LIMIT_REACHED(card) || 1269 if (MP_RX_AGGR_PKT_LIMIT_REACHED(card) ||
1201 mp_rx_aggr_port_limit_reached(card)) { 1270 mp_rx_aggr_port_limit_reached(card)) {
@@ -1238,16 +1307,29 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
1238 curr_ptr = card->mpa_rx.buf; 1307 curr_ptr = card->mpa_rx.buf;
1239 1308
1240 for (pind = 0; pind < card->mpa_rx.pkt_cnt; pind++) { 1309 for (pind = 0; pind < card->mpa_rx.pkt_cnt; pind++) {
1310 u32 *len_arr = card->mpa_rx.len_arr;
1241 1311
1242 /* get curr PKT len & type */ 1312 /* get curr PKT len & type */
1243 pkt_len = le16_to_cpu(*(__le16 *) &curr_ptr[0]); 1313 pkt_len = le16_to_cpu(*(__le16 *) &curr_ptr[0]);
1244 pkt_type = le16_to_cpu(*(__le16 *) &curr_ptr[2]); 1314 pkt_type = le16_to_cpu(*(__le16 *) &curr_ptr[2]);
1245 1315
1246 /* copy pkt to deaggr buf */ 1316 /* copy pkt to deaggr buf */
1247 skb_deaggr = card->mpa_rx.skb_arr[pind]; 1317 skb_deaggr = mwifiex_alloc_dma_align_buf(len_arr[pind],
1318 GFP_KERNEL |
1319 GFP_DMA);
1320 if (!skb_deaggr) {
1321 dev_err(adapter->dev, "skb allocation failure drop pkt len=%d type=%d\n",
1322 pkt_len, pkt_type);
1323 curr_ptr += len_arr[pind];
1324 continue;
1325 }
1248 1326
1249 if ((pkt_type == MWIFIEX_TYPE_DATA) && (pkt_len <= 1327 skb_put(skb_deaggr, len_arr[pind]);
1250 card->mpa_rx.len_arr[pind])) { 1328
1329 if ((pkt_type == MWIFIEX_TYPE_DATA ||
1330 (pkt_type == MWIFIEX_TYPE_AGGR_DATA &&
1331 adapter->sdio_rx_aggr_enable)) &&
1332 (pkt_len <= len_arr[pind])) {
1251 1333
1252 memcpy(skb_deaggr->data, curr_ptr, pkt_len); 1334 memcpy(skb_deaggr->data, curr_ptr, pkt_len);
1253 1335
@@ -1257,13 +1339,15 @@ static int mwifiex_sdio_card_to_host_mp_aggr(struct mwifiex_adapter *adapter,
1257 mwifiex_decode_rx_packet(adapter, skb_deaggr, 1339 mwifiex_decode_rx_packet(adapter, skb_deaggr,
1258 pkt_type); 1340 pkt_type);
1259 } else { 1341 } else {
1260 dev_err(adapter->dev, "wrong aggr pkt:" 1342 dev_err(adapter->dev, " drop wrong aggr pkt:\t"
1261 " type=%d len=%d max_len=%d\n", 1343 "sdio_single_port_rx_aggr=%d\t"
1344 "type=%d len=%d max_len=%d\n",
1345 adapter->sdio_rx_aggr_enable,
1262 pkt_type, pkt_len, 1346 pkt_type, pkt_len,
1263 card->mpa_rx.len_arr[pind]); 1347 len_arr[pind]);
1264 dev_kfree_skb_any(skb_deaggr); 1348 dev_kfree_skb_any(skb_deaggr);
1265 } 1349 }
1266 curr_ptr += card->mpa_rx.len_arr[pind]; 1350 curr_ptr += len_arr[pind];
1267 } 1351 }
1268 MP_RX_AGGR_BUF_RESET(card); 1352 MP_RX_AGGR_BUF_RESET(card);
1269 } 1353 }
@@ -1273,28 +1357,46 @@ rx_curr_single:
1273 dev_dbg(adapter->dev, "info: RX: port: %d, rx_len: %d\n", 1357 dev_dbg(adapter->dev, "info: RX: port: %d, rx_len: %d\n",
1274 port, rx_len); 1358 port, rx_len);
1275 1359
1360 skb = mwifiex_alloc_dma_align_buf(rx_len, GFP_KERNEL | GFP_DMA);
1361 if (!skb) {
1362 dev_err(adapter->dev, "single skb allocated fail,\t"
1363 "drop pkt port=%d len=%d\n", port, rx_len);
1364 if (mwifiex_sdio_card_to_host(adapter, &pkt_type,
1365 card->mpa_rx.buf, rx_len,
1366 adapter->ioport + port))
1367 goto error;
1368 return 0;
1369 }
1370
1371 skb_put(skb, rx_len);
1372
1276 if (mwifiex_sdio_card_to_host(adapter, &pkt_type, 1373 if (mwifiex_sdio_card_to_host(adapter, &pkt_type,
1277 skb->data, skb->len, 1374 skb->data, skb->len,
1278 adapter->ioport + port)) 1375 adapter->ioport + port))
1279 goto error; 1376 goto error;
1377 if (!adapter->sdio_rx_aggr_enable &&
1378 pkt_type == MWIFIEX_TYPE_AGGR_DATA) {
1379 dev_err(adapter->dev, "drop wrong pkt type %d\t"
1380 "current SDIO RX Aggr not enabled\n",
1381 pkt_type);
1382 dev_kfree_skb_any(skb);
1383 return 0;
1384 }
1280 1385
1281 mwifiex_decode_rx_packet(adapter, skb, pkt_type); 1386 mwifiex_decode_rx_packet(adapter, skb, pkt_type);
1282 } 1387 }
1388 if (f_post_aggr_cur) {
1389 dev_dbg(adapter->dev, "info: current packet aggregation\n");
1390 /* Curr pkt can be aggregated */
1391 mp_rx_aggr_setup(card, rx_len, port);
1392 }
1283 1393
1284 return 0; 1394 return 0;
1285
1286error: 1395error:
1287 if (MP_RX_AGGR_IN_PROGRESS(card)) { 1396 if (MP_RX_AGGR_IN_PROGRESS(card))
1288 /* Multiport-aggregation transfer failed - cleanup */
1289 for (pind = 0; pind < card->mpa_rx.pkt_cnt; pind++) {
1290 /* copy pkt to deaggr buf */
1291 skb_deaggr = card->mpa_rx.skb_arr[pind];
1292 dev_kfree_skb_any(skb_deaggr);
1293 }
1294 MP_RX_AGGR_BUF_RESET(card); 1397 MP_RX_AGGR_BUF_RESET(card);
1295 }
1296 1398
1297 if (f_do_rx_cur) 1399 if (f_do_rx_cur && skb)
1298 /* Single transfer pending. Free curr buff also */ 1400 /* Single transfer pending. Free curr buff also */
1299 dev_kfree_skb_any(skb); 1401 dev_kfree_skb_any(skb);
1300 1402
@@ -1356,8 +1458,9 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
1356 MWIFIEX_RX_DATA_BUF_SIZE) 1458 MWIFIEX_RX_DATA_BUF_SIZE)
1357 return -1; 1459 return -1;
1358 rx_len = (u16) (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE); 1460 rx_len = (u16) (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE);
1461 dev_dbg(adapter->dev, "info: rx_len = %d\n", rx_len);
1359 1462
1360 skb = mwifiex_alloc_rx_buf(rx_len, GFP_KERNEL | GFP_DMA); 1463 skb = mwifiex_alloc_dma_align_buf(rx_len, GFP_KERNEL | GFP_DMA);
1361 if (!skb) 1464 if (!skb)
1362 return -1; 1465 return -1;
1363 1466
@@ -1447,28 +1550,16 @@ static int mwifiex_process_int_status(struct mwifiex_adapter *adapter)
1447 1) / MWIFIEX_SDIO_BLOCK_SIZE; 1550 1) / MWIFIEX_SDIO_BLOCK_SIZE;
1448 if (rx_len <= INTF_HEADER_LEN || 1551 if (rx_len <= INTF_HEADER_LEN ||
1449 (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE) > 1552 (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE) >
1450 MWIFIEX_RX_DATA_BUF_SIZE) { 1553 card->mpa_rx.buf_size) {
1451 dev_err(adapter->dev, "invalid rx_len=%d\n", 1554 dev_err(adapter->dev, "invalid rx_len=%d\n",
1452 rx_len); 1555 rx_len);
1453 return -1; 1556 return -1;
1454 } 1557 }
1455 rx_len = (u16) (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE);
1456
1457 skb = mwifiex_alloc_rx_buf(rx_len,
1458 GFP_KERNEL | GFP_DMA);
1459
1460 if (!skb) {
1461 dev_err(adapter->dev, "%s: failed to alloc skb",
1462 __func__);
1463 return -1;
1464 }
1465 1558
1466 skb_put(skb, rx_len); 1559 rx_len = (u16) (rx_blocks * MWIFIEX_SDIO_BLOCK_SIZE);
1467 1560 dev_dbg(adapter->dev, "info: rx_len = %d\n", rx_len);
1468 dev_dbg(adapter->dev, "info: rx_len = %d skb->len = %d\n",
1469 rx_len, skb->len);
1470 1561
1471 if (mwifiex_sdio_card_to_host_mp_aggr(adapter, skb, 1562 if (mwifiex_sdio_card_to_host_mp_aggr(adapter, rx_len,
1472 port)) { 1563 port)) {
1473 dev_err(adapter->dev, "card_to_host_mpa failed:" 1564 dev_err(adapter->dev, "card_to_host_mpa failed:"
1474 " int status=%#x\n", sdio_ireg); 1565 " int status=%#x\n", sdio_ireg);
@@ -1736,6 +1827,7 @@ static int mwifiex_alloc_sdio_mpa_buffers(struct mwifiex_adapter *adapter,
1736 u32 mpa_tx_buf_size, u32 mpa_rx_buf_size) 1827 u32 mpa_tx_buf_size, u32 mpa_rx_buf_size)
1737{ 1828{
1738 struct sdio_mmc_card *card = adapter->card; 1829 struct sdio_mmc_card *card = adapter->card;
1830 u32 rx_buf_size;
1739 int ret = 0; 1831 int ret = 0;
1740 1832
1741 card->mpa_tx.buf = kzalloc(mpa_tx_buf_size, GFP_KERNEL); 1833 card->mpa_tx.buf = kzalloc(mpa_tx_buf_size, GFP_KERNEL);
@@ -1746,13 +1838,15 @@ static int mwifiex_alloc_sdio_mpa_buffers(struct mwifiex_adapter *adapter,
1746 1838
1747 card->mpa_tx.buf_size = mpa_tx_buf_size; 1839 card->mpa_tx.buf_size = mpa_tx_buf_size;
1748 1840
1749 card->mpa_rx.buf = kzalloc(mpa_rx_buf_size, GFP_KERNEL); 1841 rx_buf_size = max_t(u32, mpa_rx_buf_size,
1842 (u32)SDIO_MAX_AGGR_BUF_SIZE);
1843 card->mpa_rx.buf = kzalloc(rx_buf_size, GFP_KERNEL);
1750 if (!card->mpa_rx.buf) { 1844 if (!card->mpa_rx.buf) {
1751 ret = -1; 1845 ret = -1;
1752 goto error; 1846 goto error;
1753 } 1847 }
1754 1848
1755 card->mpa_rx.buf_size = mpa_rx_buf_size; 1849 card->mpa_rx.buf_size = rx_buf_size;
1756 1850
1757error: 1851error:
1758 if (ret) { 1852 if (ret) {
@@ -1951,6 +2045,7 @@ mwifiex_update_mp_end_port(struct mwifiex_adapter *adapter, u16 port)
1951 port, card->mp_data_port_mask); 2045 port, card->mp_data_port_mask);
1952} 2046}
1953 2047
2048static struct mwifiex_adapter *save_adapter;
1954static void mwifiex_sdio_card_reset_work(struct mwifiex_adapter *adapter) 2049static void mwifiex_sdio_card_reset_work(struct mwifiex_adapter *adapter)
1955{ 2050{
1956 struct sdio_mmc_card *card = adapter->card; 2051 struct sdio_mmc_card *card = adapter->card;
@@ -2019,10 +2114,8 @@ rdwr_status mwifiex_sdio_rdwr_firmware(struct mwifiex_adapter *adapter,
2019} 2114}
2020 2115
2021/* This function dump firmware memory to file */ 2116/* This function dump firmware memory to file */
2022static void mwifiex_sdio_fw_dump_work(struct work_struct *work) 2117static void mwifiex_sdio_fw_dump_work(struct mwifiex_adapter *adapter)
2023{ 2118{
2024 struct mwifiex_adapter *adapter =
2025 container_of(work, struct mwifiex_adapter, iface_work);
2026 struct sdio_mmc_card *card = adapter->card; 2119 struct sdio_mmc_card *card = adapter->card;
2027 int ret = 0; 2120 int ret = 0;
2028 unsigned int reg, reg_start, reg_end; 2121 unsigned int reg, reg_start, reg_end;
@@ -2144,36 +2237,36 @@ done:
2144 2237
2145static void mwifiex_sdio_work(struct work_struct *work) 2238static void mwifiex_sdio_work(struct work_struct *work)
2146{ 2239{
2147 struct mwifiex_adapter *adapter =
2148 container_of(work, struct mwifiex_adapter, iface_work);
2149
2150 if (test_and_clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET,
2151 &adapter->iface_work_flags))
2152 mwifiex_sdio_card_reset_work(adapter);
2153 if (test_and_clear_bit(MWIFIEX_IFACE_WORK_FW_DUMP, 2240 if (test_and_clear_bit(MWIFIEX_IFACE_WORK_FW_DUMP,
2154 &adapter->iface_work_flags)) 2241 &iface_work_flags))
2155 mwifiex_sdio_fw_dump_work(work); 2242 mwifiex_sdio_fw_dump_work(save_adapter);
2243 if (test_and_clear_bit(MWIFIEX_IFACE_WORK_CARD_RESET,
2244 &iface_work_flags))
2245 mwifiex_sdio_card_reset_work(save_adapter);
2156} 2246}
2157 2247
2248static DECLARE_WORK(sdio_work, mwifiex_sdio_work);
2158/* This function resets the card */ 2249/* This function resets the card */
2159static void mwifiex_sdio_card_reset(struct mwifiex_adapter *adapter) 2250static void mwifiex_sdio_card_reset(struct mwifiex_adapter *adapter)
2160{ 2251{
2161 if (test_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &adapter->iface_work_flags)) 2252 save_adapter = adapter;
2253 if (test_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &iface_work_flags))
2162 return; 2254 return;
2163 2255
2164 set_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &adapter->iface_work_flags); 2256 set_bit(MWIFIEX_IFACE_WORK_CARD_RESET, &iface_work_flags);
2165 2257
2166 schedule_work(&adapter->iface_work); 2258 schedule_work(&sdio_work);
2167} 2259}
2168 2260
2169/* This function dumps FW information */ 2261/* This function dumps FW information */
2170static void mwifiex_sdio_fw_dump(struct mwifiex_adapter *adapter) 2262static void mwifiex_sdio_fw_dump(struct mwifiex_adapter *adapter)
2171{ 2263{
2172 if (test_bit(MWIFIEX_IFACE_WORK_FW_DUMP, &adapter->iface_work_flags)) 2264 save_adapter = adapter;
2265 if (test_bit(MWIFIEX_IFACE_WORK_FW_DUMP, &iface_work_flags))
2173 return; 2266 return;
2174 2267
2175 set_bit(MWIFIEX_IFACE_WORK_FW_DUMP, &adapter->iface_work_flags); 2268 set_bit(MWIFIEX_IFACE_WORK_FW_DUMP, &iface_work_flags);
2176 schedule_work(&adapter->iface_work); 2269 schedule_work(&sdio_work);
2177} 2270}
2178 2271
2179/* Function to dump SDIO function registers and SDIO scratch registers in case 2272/* Function to dump SDIO function registers and SDIO scratch registers in case
@@ -2289,9 +2382,9 @@ static struct mwifiex_if_ops sdio_ops = {
2289 .cmdrsp_complete = mwifiex_sdio_cmdrsp_complete, 2382 .cmdrsp_complete = mwifiex_sdio_cmdrsp_complete,
2290 .event_complete = mwifiex_sdio_event_complete, 2383 .event_complete = mwifiex_sdio_event_complete,
2291 .card_reset = mwifiex_sdio_card_reset, 2384 .card_reset = mwifiex_sdio_card_reset,
2292 .iface_work = mwifiex_sdio_work,
2293 .fw_dump = mwifiex_sdio_fw_dump, 2385 .fw_dump = mwifiex_sdio_fw_dump,
2294 .reg_dump = mwifiex_sdio_reg_dump, 2386 .reg_dump = mwifiex_sdio_reg_dump,
2387 .deaggr_pkt = mwifiex_deaggr_sdio_pkt,
2295}; 2388};
2296 2389
2297/* 2390/*
@@ -2328,6 +2421,7 @@ mwifiex_sdio_cleanup_module(void)
2328 2421
2329 /* Set the flag as user is removing this module. */ 2422 /* Set the flag as user is removing this module. */
2330 user_rmmod = 1; 2423 user_rmmod = 1;
2424 cancel_work_sync(&sdio_work);
2331 2425
2332 sdio_unregister_driver(&mwifiex_sdio); 2426 sdio_unregister_driver(&mwifiex_sdio);
2333} 2427}
diff --git a/drivers/net/wireless/mwifiex/sdio.h b/drivers/net/wireless/mwifiex/sdio.h
index c636944c77bc..6f645cf47369 100644
--- a/drivers/net/wireless/mwifiex/sdio.h
+++ b/drivers/net/wireless/mwifiex/sdio.h
@@ -67,6 +67,8 @@
67 67
68#define MWIFIEX_MP_AGGR_BUF_SIZE_16K (16384) 68#define MWIFIEX_MP_AGGR_BUF_SIZE_16K (16384)
69#define MWIFIEX_MP_AGGR_BUF_SIZE_32K (32768) 69#define MWIFIEX_MP_AGGR_BUF_SIZE_32K (32768)
70/* we leave one block of 256 bytes for DMA alignment*/
71#define MWIFIEX_MP_AGGR_BUF_SIZE_MAX (65280)
70 72
71/* Misc. Config Register : Auto Re-enable interrupts */ 73/* Misc. Config Register : Auto Re-enable interrupts */
72#define AUTO_RE_ENABLE_INT BIT(4) 74#define AUTO_RE_ENABLE_INT BIT(4)
@@ -458,8 +460,8 @@ static const struct mwifiex_sdio_device mwifiex_sdio_sd8897 = {
458 .max_ports = 32, 460 .max_ports = 32,
459 .mp_agg_pkt_limit = 16, 461 .mp_agg_pkt_limit = 16,
460 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K, 462 .tx_buf_size = MWIFIEX_TX_DATA_BUF_SIZE_4K,
461 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_32K, 463 .mp_tx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_MAX,
462 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_32K, 464 .mp_rx_agg_buf_size = MWIFIEX_MP_AGGR_BUF_SIZE_MAX,
463 .supports_sdio_new_mode = true, 465 .supports_sdio_new_mode = true,
464 .has_control_mask = false, 466 .has_control_mask = false,
465 .can_dump_fw = true, 467 .can_dump_fw = true,
@@ -571,9 +573,9 @@ mp_tx_aggr_port_limit_reached(struct sdio_mmc_card *card)
571 573
572/* Prepare to copy current packet from card to SDIO Rx aggregation buffer */ 574/* Prepare to copy current packet from card to SDIO Rx aggregation buffer */
573static inline void mp_rx_aggr_setup(struct sdio_mmc_card *card, 575static inline void mp_rx_aggr_setup(struct sdio_mmc_card *card,
574 struct sk_buff *skb, u8 port) 576 u16 rx_len, u8 port)
575{ 577{
576 card->mpa_rx.buf_len += skb->len; 578 card->mpa_rx.buf_len += rx_len;
577 579
578 if (!card->mpa_rx.pkt_cnt) 580 if (!card->mpa_rx.pkt_cnt)
579 card->mpa_rx.start_port = port; 581 card->mpa_rx.start_port = port;
@@ -586,8 +588,8 @@ static inline void mp_rx_aggr_setup(struct sdio_mmc_card *card,
586 else 588 else
587 card->mpa_rx.ports |= 1 << (card->mpa_rx.pkt_cnt + 1); 589 card->mpa_rx.ports |= 1 << (card->mpa_rx.pkt_cnt + 1);
588 } 590 }
589 card->mpa_rx.skb_arr[card->mpa_rx.pkt_cnt] = skb; 591 card->mpa_rx.skb_arr[card->mpa_rx.pkt_cnt] = NULL;
590 card->mpa_rx.len_arr[card->mpa_rx.pkt_cnt] = skb->len; 592 card->mpa_rx.len_arr[card->mpa_rx.pkt_cnt] = rx_len;
591 card->mpa_rx.pkt_cnt++; 593 card->mpa_rx.pkt_cnt++;
592} 594}
593#endif /* _MWIFIEX_SDIO_H */ 595#endif /* _MWIFIEX_SDIO_H */
diff --git a/drivers/net/wireless/mwifiex/sta_cmd.c b/drivers/net/wireless/mwifiex/sta_cmd.c
index f7d204ffd6e9..49422f2a5380 100644
--- a/drivers/net/wireless/mwifiex/sta_cmd.c
+++ b/drivers/net/wireless/mwifiex/sta_cmd.c
@@ -1370,22 +1370,29 @@ mwifiex_cmd_mef_cfg(struct mwifiex_private *priv,
1370 struct mwifiex_ds_mef_cfg *mef) 1370 struct mwifiex_ds_mef_cfg *mef)
1371{ 1371{
1372 struct host_cmd_ds_mef_cfg *mef_cfg = &cmd->params.mef_cfg; 1372 struct host_cmd_ds_mef_cfg *mef_cfg = &cmd->params.mef_cfg;
1373 struct mwifiex_fw_mef_entry *mef_entry = NULL;
1373 u8 *pos = (u8 *)mef_cfg; 1374 u8 *pos = (u8 *)mef_cfg;
1375 u16 i;
1374 1376
1375 cmd->command = cpu_to_le16(HostCmd_CMD_MEF_CFG); 1377 cmd->command = cpu_to_le16(HostCmd_CMD_MEF_CFG);
1376 1378
1377 mef_cfg->criteria = cpu_to_le32(mef->criteria); 1379 mef_cfg->criteria = cpu_to_le32(mef->criteria);
1378 mef_cfg->num_entries = cpu_to_le16(mef->num_entries); 1380 mef_cfg->num_entries = cpu_to_le16(mef->num_entries);
1379 pos += sizeof(*mef_cfg); 1381 pos += sizeof(*mef_cfg);
1380 mef_cfg->mef_entry->mode = mef->mef_entry->mode;
1381 mef_cfg->mef_entry->action = mef->mef_entry->action;
1382 pos += sizeof(*(mef_cfg->mef_entry));
1383 1382
1384 if (mwifiex_cmd_append_rpn_expression(priv, mef->mef_entry, &pos)) 1383 for (i = 0; i < mef->num_entries; i++) {
1385 return -1; 1384 mef_entry = (struct mwifiex_fw_mef_entry *)pos;
1385 mef_entry->mode = mef->mef_entry[i].mode;
1386 mef_entry->action = mef->mef_entry[i].action;
1387 pos += sizeof(*mef_cfg->mef_entry);
1388
1389 if (mwifiex_cmd_append_rpn_expression(priv,
1390 &mef->mef_entry[i], &pos))
1391 return -1;
1386 1392
1387 mef_cfg->mef_entry->exprsize = 1393 mef_entry->exprsize =
1388 cpu_to_le16(pos - mef_cfg->mef_entry->expr); 1394 cpu_to_le16(pos - mef_entry->expr);
1395 }
1389 cmd->size = cpu_to_le16((u16) (pos - (u8 *)mef_cfg) + S_DS_GEN); 1396 cmd->size = cpu_to_le16((u16) (pos - (u8 *)mef_cfg) + S_DS_GEN);
1390 1397
1391 return 0; 1398 return 0;
@@ -1664,6 +1671,25 @@ mwifiex_cmd_tdls_oper(struct mwifiex_private *priv,
1664 1671
1665 return 0; 1672 return 0;
1666} 1673}
1674
1675/* This function prepares command of sdio rx aggr info. */
1676static int mwifiex_cmd_sdio_rx_aggr_cfg(struct host_cmd_ds_command *cmd,
1677 u16 cmd_action, void *data_buf)
1678{
1679 struct host_cmd_sdio_sp_rx_aggr_cfg *cfg =
1680 &cmd->params.sdio_rx_aggr_cfg;
1681
1682 cmd->command = cpu_to_le16(HostCmd_CMD_SDIO_SP_RX_AGGR_CFG);
1683 cmd->size =
1684 cpu_to_le16(sizeof(struct host_cmd_sdio_sp_rx_aggr_cfg) +
1685 S_DS_GEN);
1686 cfg->action = cmd_action;
1687 if (cmd_action == HostCmd_ACT_GEN_SET)
1688 cfg->enable = *(u8 *)data_buf;
1689
1690 return 0;
1691}
1692
1667/* 1693/*
1668 * This function prepares the commands before sending them to the firmware. 1694 * This function prepares the commands before sending them to the firmware.
1669 * 1695 *
@@ -1901,6 +1927,10 @@ int mwifiex_sta_prepare_cmd(struct mwifiex_private *priv, uint16_t cmd_no,
1901 ret = mwifiex_cmd_issue_chan_report_request(priv, cmd_ptr, 1927 ret = mwifiex_cmd_issue_chan_report_request(priv, cmd_ptr,
1902 data_buf); 1928 data_buf);
1903 break; 1929 break;
1930 case HostCmd_CMD_SDIO_SP_RX_AGGR_CFG:
1931 ret = mwifiex_cmd_sdio_rx_aggr_cfg(cmd_ptr, cmd_action,
1932 data_buf);
1933 break;
1904 default: 1934 default:
1905 dev_err(priv->adapter->dev, 1935 dev_err(priv->adapter->dev,
1906 "PREP_CMD: unknown cmd- %#x\n", cmd_no); 1936 "PREP_CMD: unknown cmd- %#x\n", cmd_no);
@@ -1940,6 +1970,7 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta, bool init)
1940 struct mwifiex_ds_auto_ds auto_ds; 1970 struct mwifiex_ds_auto_ds auto_ds;
1941 enum state_11d_t state_11d; 1971 enum state_11d_t state_11d;
1942 struct mwifiex_ds_11n_tx_cfg tx_cfg; 1972 struct mwifiex_ds_11n_tx_cfg tx_cfg;
1973 u8 sdio_sp_rx_aggr_enable;
1943 1974
1944 if (first_sta) { 1975 if (first_sta) {
1945 if (priv->adapter->iface_type == MWIFIEX_PCIE) { 1976 if (priv->adapter->iface_type == MWIFIEX_PCIE) {
@@ -1983,6 +2014,22 @@ int mwifiex_sta_init_cmd(struct mwifiex_private *priv, u8 first_sta, bool init)
1983 if (ret) 2014 if (ret)
1984 return -1; 2015 return -1;
1985 2016
2017 /** Set SDIO Single Port RX Aggr Info */
2018 if (priv->adapter->iface_type == MWIFIEX_SDIO &&
2019 ISSUPP_SDIO_SPA_ENABLED(priv->adapter->fw_cap_info)) {
2020 sdio_sp_rx_aggr_enable = true;
2021 ret = mwifiex_send_cmd(priv,
2022 HostCmd_CMD_SDIO_SP_RX_AGGR_CFG,
2023 HostCmd_ACT_GEN_SET, 0,
2024 &sdio_sp_rx_aggr_enable,
2025 true);
2026 if (ret) {
2027 dev_err(priv->adapter->dev,
2028 "error while enabling SP aggregation..disable it");
2029 adapter->sdio_rx_aggr_enable = false;
2030 }
2031 }
2032
1986 /* Reconfigure tx buf size */ 2033 /* Reconfigure tx buf size */
1987 ret = mwifiex_send_cmd(priv, HostCmd_CMD_RECONFIGURE_TX_BUFF, 2034 ret = mwifiex_send_cmd(priv, HostCmd_CMD_RECONFIGURE_TX_BUFF,
1988 HostCmd_ACT_GEN_SET, 0, 2035 HostCmd_ACT_GEN_SET, 0,
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index 5f8da5924666..88dc6b672ef4 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -90,6 +90,10 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv,
90 case HostCmd_CMD_MAC_CONTROL: 90 case HostCmd_CMD_MAC_CONTROL:
91 break; 91 break;
92 92
93 case HostCmd_CMD_SDIO_SP_RX_AGGR_CFG:
94 dev_err(priv->adapter->dev, "SDIO RX single-port aggregation Not support\n");
95 break;
96
93 default: 97 default:
94 break; 98 break;
95 } 99 }
@@ -943,6 +947,20 @@ static int mwifiex_ret_cfg_data(struct mwifiex_private *priv,
943 return 0; 947 return 0;
944} 948}
945 949
950/** This Function handles the command response of sdio rx aggr */
951static int mwifiex_ret_sdio_rx_aggr_cfg(struct mwifiex_private *priv,
952 struct host_cmd_ds_command *resp)
953{
954 struct mwifiex_adapter *adapter = priv->adapter;
955 struct host_cmd_sdio_sp_rx_aggr_cfg *cfg =
956 &resp->params.sdio_rx_aggr_cfg;
957
958 adapter->sdio_rx_aggr_enable = cfg->enable;
959 adapter->sdio_rx_block_size = le16_to_cpu(cfg->block_size);
960
961 return 0;
962}
963
946/* 964/*
947 * This function handles the command responses. 965 * This function handles the command responses.
948 * 966 *
@@ -1124,6 +1142,9 @@ int mwifiex_process_sta_cmdresp(struct mwifiex_private *priv, u16 cmdresp_no,
1124 break; 1142 break;
1125 case HostCmd_CMD_CHAN_REPORT_REQUEST: 1143 case HostCmd_CMD_CHAN_REPORT_REQUEST:
1126 break; 1144 break;
1145 case HostCmd_CMD_SDIO_SP_RX_AGGR_CFG:
1146 ret = mwifiex_ret_sdio_rx_aggr_cfg(priv, resp);
1147 break;
1127 default: 1148 default:
1128 dev_err(adapter->dev, "CMD_RESP: unknown cmd response %#x\n", 1149 dev_err(adapter->dev, "CMD_RESP: unknown cmd response %#x\n",
1129 resp->command); 1150 resp->command);
diff --git a/drivers/net/wireless/mwifiex/sta_event.c b/drivers/net/wireless/mwifiex/sta_event.c
index 64c4223a1e1e..0dc7a1d3993d 100644
--- a/drivers/net/wireless/mwifiex/sta_event.c
+++ b/drivers/net/wireless/mwifiex/sta_event.c
@@ -312,7 +312,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
312 adapter->ps_state = PS_STATE_AWAKE; 312 adapter->ps_state = PS_STATE_AWAKE;
313 adapter->pm_wakeup_card_req = false; 313 adapter->pm_wakeup_card_req = false;
314 adapter->pm_wakeup_fw_try = false; 314 adapter->pm_wakeup_fw_try = false;
315 del_timer_sync(&adapter->wakeup_timer); 315 del_timer(&adapter->wakeup_timer);
316 break; 316 break;
317 } 317 }
318 if (!mwifiex_send_null_packet 318 if (!mwifiex_send_null_packet
@@ -327,7 +327,7 @@ int mwifiex_process_sta_event(struct mwifiex_private *priv)
327 adapter->ps_state = PS_STATE_AWAKE; 327 adapter->ps_state = PS_STATE_AWAKE;
328 adapter->pm_wakeup_card_req = false; 328 adapter->pm_wakeup_card_req = false;
329 adapter->pm_wakeup_fw_try = false; 329 adapter->pm_wakeup_fw_try = false;
330 del_timer_sync(&adapter->wakeup_timer); 330 del_timer(&adapter->wakeup_timer);
331 331
332 break; 332 break;
333 333
diff --git a/drivers/net/wireless/mwifiex/txrx.c b/drivers/net/wireless/mwifiex/txrx.c
index ea4549f0e0b9..a245f444aeec 100644
--- a/drivers/net/wireless/mwifiex/txrx.c
+++ b/drivers/net/wireless/mwifiex/txrx.c
@@ -92,6 +92,12 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
92 else 92 else
93 head_ptr = mwifiex_process_sta_txpd(priv, skb); 93 head_ptr = mwifiex_process_sta_txpd(priv, skb);
94 94
95 if ((adapter->data_sent || adapter->tx_lock_flag) && head_ptr) {
96 skb_queue_tail(&adapter->tx_data_q, skb);
97 atomic_inc(&adapter->tx_queued);
98 return 0;
99 }
100
95 if (head_ptr) { 101 if (head_ptr) {
96 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) 102 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA)
97 local_tx_pd = (struct txpd *)(head_ptr + hroom); 103 local_tx_pd = (struct txpd *)(head_ptr + hroom);
@@ -142,6 +148,123 @@ int mwifiex_process_tx(struct mwifiex_private *priv, struct sk_buff *skb,
142 return ret; 148 return ret;
143} 149}
144 150
151static int mwifiex_host_to_card(struct mwifiex_adapter *adapter,
152 struct sk_buff *skb,
153 struct mwifiex_tx_param *tx_param)
154{
155 struct txpd *local_tx_pd = NULL;
156 u8 *head_ptr = skb->data;
157 int ret = 0;
158 struct mwifiex_private *priv;
159 struct mwifiex_txinfo *tx_info;
160
161 tx_info = MWIFIEX_SKB_TXCB(skb);
162 priv = mwifiex_get_priv_by_id(adapter, tx_info->bss_num,
163 tx_info->bss_type);
164 if (!priv) {
165 dev_err(adapter->dev, "data: priv not found. Drop TX packet\n");
166 adapter->dbg.num_tx_host_to_card_failure++;
167 mwifiex_write_data_complete(adapter, skb, 0, 0);
168 return ret;
169 }
170 if (GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) {
171 if (adapter->iface_type == MWIFIEX_USB)
172 local_tx_pd = (struct txpd *)head_ptr;
173 else
174 local_tx_pd = (struct txpd *) (head_ptr +
175 INTF_HEADER_LEN);
176 }
177
178 if (adapter->iface_type == MWIFIEX_USB) {
179 adapter->data_sent = true;
180 ret = adapter->if_ops.host_to_card(adapter,
181 MWIFIEX_USB_EP_DATA,
182 skb, NULL);
183 } else {
184 ret = adapter->if_ops.host_to_card(adapter,
185 MWIFIEX_TYPE_DATA,
186 skb, tx_param);
187 }
188 switch (ret) {
189 case -ENOSR:
190 dev_err(adapter->dev, "data: -ENOSR is returned\n");
191 break;
192 case -EBUSY:
193 if ((GET_BSS_ROLE(priv) == MWIFIEX_BSS_ROLE_STA) &&
194 (adapter->pps_uapsd_mode) &&
195 (adapter->tx_lock_flag)) {
196 priv->adapter->tx_lock_flag = false;
197 if (local_tx_pd)
198 local_tx_pd->flags = 0;
199 }
200 skb_queue_head(&adapter->tx_data_q, skb);
201 if (tx_info->flags & MWIFIEX_BUF_FLAG_AGGR_PKT)
202 atomic_add(tx_info->aggr_num, &adapter->tx_queued);
203 else
204 atomic_inc(&adapter->tx_queued);
205 dev_dbg(adapter->dev, "data: -EBUSY is returned\n");
206 break;
207 case -1:
208 if (adapter->iface_type != MWIFIEX_PCIE)
209 adapter->data_sent = false;
210 dev_err(adapter->dev, "mwifiex_write_data_async failed: 0x%X\n",
211 ret);
212 adapter->dbg.num_tx_host_to_card_failure++;
213 mwifiex_write_data_complete(adapter, skb, 0, ret);
214 break;
215 case -EINPROGRESS:
216 if (adapter->iface_type != MWIFIEX_PCIE)
217 adapter->data_sent = false;
218 break;
219 case 0:
220 mwifiex_write_data_complete(adapter, skb, 0, ret);
221 break;
222 default:
223 break;
224 }
225 return ret;
226}
227
228static int
229mwifiex_dequeue_tx_queue(struct mwifiex_adapter *adapter)
230{
231 struct sk_buff *skb, *skb_next;
232 struct mwifiex_txinfo *tx_info;
233 struct mwifiex_tx_param tx_param;
234
235 skb = skb_dequeue(&adapter->tx_data_q);
236 if (!skb)
237 return -1;
238
239 tx_info = MWIFIEX_SKB_TXCB(skb);
240 if (tx_info->flags & MWIFIEX_BUF_FLAG_AGGR_PKT)
241 atomic_sub(tx_info->aggr_num, &adapter->tx_queued);
242 else
243 atomic_dec(&adapter->tx_queued);
244
245 if (!skb_queue_empty(&adapter->tx_data_q))
246 skb_next = skb_peek(&adapter->tx_data_q);
247 else
248 skb_next = NULL;
249 tx_param.next_pkt_len = ((skb_next) ? skb_next->len : 0);
250 if (!tx_param.next_pkt_len) {
251 if (!mwifiex_wmm_lists_empty(adapter))
252 tx_param.next_pkt_len = 1;
253 }
254 return mwifiex_host_to_card(adapter, skb, &tx_param);
255}
256
257void
258mwifiex_process_tx_queue(struct mwifiex_adapter *adapter)
259{
260 do {
261 if (adapter->data_sent || adapter->tx_lock_flag)
262 break;
263 if (mwifiex_dequeue_tx_queue(adapter))
264 break;
265 } while (!skb_queue_empty(&adapter->tx_data_q));
266}
267
145/* 268/*
146 * Packet send completion callback handler. 269 * Packet send completion callback handler.
147 * 270 *
@@ -179,8 +302,11 @@ int mwifiex_write_data_complete(struct mwifiex_adapter *adapter,
179 priv->stats.tx_errors++; 302 priv->stats.tx_errors++;
180 } 303 }
181 304
182 if (tx_info->flags & MWIFIEX_BUF_FLAG_BRIDGED_PKT) 305 if (tx_info->flags & MWIFIEX_BUF_FLAG_BRIDGED_PKT) {
183 atomic_dec_return(&adapter->pending_bridged_pkts); 306 atomic_dec_return(&adapter->pending_bridged_pkts);
307 if (tx_info->flags & MWIFIEX_BUF_FLAG_AGGR_PKT)
308 goto done;
309 }
184 310
185 if (aggr) 311 if (aggr)
186 /* For skb_aggr, do not wake up tx queue */ 312 /* For skb_aggr, do not wake up tx queue */
diff --git a/drivers/net/wireless/mwifiex/usb.c b/drivers/net/wireless/mwifiex/usb.c
index 223873022ffe..fd8027f200a0 100644
--- a/drivers/net/wireless/mwifiex/usb.c
+++ b/drivers/net/wireless/mwifiex/usb.c
@@ -193,7 +193,7 @@ static void mwifiex_usb_rx_complete(struct urb *urb)
193 dev_dbg(adapter->dev, "info: recv_length=%d, status=%d\n", 193 dev_dbg(adapter->dev, "info: recv_length=%d, status=%d\n",
194 recv_length, status); 194 recv_length, status);
195 if (status == -EINPROGRESS) { 195 if (status == -EINPROGRESS) {
196 queue_work(adapter->workqueue, &adapter->main_work); 196 mwifiex_queue_main_work(adapter);
197 197
198 /* urb for data_ep is re-submitted now; 198 /* urb for data_ep is re-submitted now;
199 * urb for cmd_ep will be re-submitted in callback 199 * urb for cmd_ep will be re-submitted in callback
@@ -262,7 +262,7 @@ static void mwifiex_usb_tx_complete(struct urb *urb)
262 urb->status ? -1 : 0); 262 urb->status ? -1 : 0);
263 } 263 }
264 264
265 queue_work(adapter->workqueue, &adapter->main_work); 265 mwifiex_queue_main_work(adapter);
266 266
267 return; 267 return;
268} 268}
@@ -1006,7 +1006,7 @@ static int mwifiex_pm_wakeup_card(struct mwifiex_adapter *adapter)
1006{ 1006{
1007 /* Simulation of HS_AWAKE event */ 1007 /* Simulation of HS_AWAKE event */
1008 adapter->pm_wakeup_fw_try = false; 1008 adapter->pm_wakeup_fw_try = false;
1009 del_timer_sync(&adapter->wakeup_timer); 1009 del_timer(&adapter->wakeup_timer);
1010 adapter->pm_wakeup_card_req = false; 1010 adapter->pm_wakeup_card_req = false;
1011 adapter->ps_state = PS_STATE_AWAKE; 1011 adapter->ps_state = PS_STATE_AWAKE;
1012 1012
diff --git a/drivers/net/wireless/mwifiex/util.c b/drivers/net/wireless/mwifiex/util.c
index 2148a573396b..b8a45872354d 100644
--- a/drivers/net/wireless/mwifiex/util.c
+++ b/drivers/net/wireless/mwifiex/util.c
@@ -632,7 +632,7 @@ void mwifiex_hist_data_reset(struct mwifiex_private *priv)
632 atomic_set(&phist_data->sig_str[ix], 0); 632 atomic_set(&phist_data->sig_str[ix], 0);
633} 633}
634 634
635void *mwifiex_alloc_rx_buf(int rx_len, gfp_t flags) 635void *mwifiex_alloc_dma_align_buf(int rx_len, gfp_t flags)
636{ 636{
637 struct sk_buff *skb; 637 struct sk_buff *skb;
638 int buf_len, pad; 638 int buf_len, pad;
@@ -653,4 +653,4 @@ void *mwifiex_alloc_rx_buf(int rx_len, gfp_t flags)
653 653
654 return skb; 654 return skb;
655} 655}
656EXPORT_SYMBOL_GPL(mwifiex_alloc_rx_buf); 656EXPORT_SYMBOL_GPL(mwifiex_alloc_dma_align_buf);
diff --git a/drivers/net/wireless/mwifiex/wmm.c b/drivers/net/wireless/mwifiex/wmm.c
index 0cd4f6bed9fc..b2e99569a0f8 100644
--- a/drivers/net/wireless/mwifiex/wmm.c
+++ b/drivers/net/wireless/mwifiex/wmm.c
@@ -157,6 +157,8 @@ void mwifiex_ralist_add(struct mwifiex_private *priv, const u8 *ra)
157 157
158 ra_list->is_11n_enabled = 0; 158 ra_list->is_11n_enabled = 0;
159 ra_list->tdls_link = false; 159 ra_list->tdls_link = false;
160 ra_list->ba_status = BA_SETUP_NONE;
161 ra_list->amsdu_in_ampdu = false;
160 if (!mwifiex_queuing_ra_based(priv)) { 162 if (!mwifiex_queuing_ra_based(priv)) {
161 if (mwifiex_get_tdls_link_status(priv, ra) == 163 if (mwifiex_get_tdls_link_status(priv, ra) ==
162 TDLS_SETUP_COMPLETE) { 164 TDLS_SETUP_COMPLETE) {
@@ -574,7 +576,7 @@ mwifiex_clean_txrx(struct mwifiex_private *priv)
574 * This function retrieves a particular RA list node, matching with the 576 * This function retrieves a particular RA list node, matching with the
575 * given TID and RA address. 577 * given TID and RA address.
576 */ 578 */
577static struct mwifiex_ra_list_tbl * 579struct mwifiex_ra_list_tbl *
578mwifiex_wmm_get_ralist_node(struct mwifiex_private *priv, u8 tid, 580mwifiex_wmm_get_ralist_node(struct mwifiex_private *priv, u8 tid,
579 const u8 *ra_addr) 581 const u8 *ra_addr)
580{ 582{
@@ -942,14 +944,11 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
942 struct mwifiex_ra_list_tbl *ptr; 944 struct mwifiex_ra_list_tbl *ptr;
943 struct mwifiex_tid_tbl *tid_ptr; 945 struct mwifiex_tid_tbl *tid_ptr;
944 atomic_t *hqp; 946 atomic_t *hqp;
945 unsigned long flags_bss, flags_ra; 947 unsigned long flags_ra;
946 int i, j; 948 int i, j;
947 949
948 /* check the BSS with highest priority first */ 950 /* check the BSS with highest priority first */
949 for (j = adapter->priv_num - 1; j >= 0; --j) { 951 for (j = adapter->priv_num - 1; j >= 0; --j) {
950 spin_lock_irqsave(&adapter->bss_prio_tbl[j].bss_prio_lock,
951 flags_bss);
952
953 /* iterate over BSS with the equal priority */ 952 /* iterate over BSS with the equal priority */
954 list_for_each_entry(adapter->bss_prio_tbl[j].bss_prio_cur, 953 list_for_each_entry(adapter->bss_prio_tbl[j].bss_prio_cur,
955 &adapter->bss_prio_tbl[j].bss_prio_head, 954 &adapter->bss_prio_tbl[j].bss_prio_head,
@@ -985,19 +984,15 @@ mwifiex_wmm_get_highest_priolist_ptr(struct mwifiex_adapter *adapter,
985 } 984 }
986 } 985 }
987 986
988 spin_unlock_irqrestore(&adapter->bss_prio_tbl[j].bss_prio_lock,
989 flags_bss);
990 } 987 }
991 988
992 return NULL; 989 return NULL;
993 990
994found: 991found:
995 /* holds bss_prio_lock / ra_list_spinlock */ 992 /* holds ra_list_spinlock */
996 if (atomic_read(hqp) > i) 993 if (atomic_read(hqp) > i)
997 atomic_set(hqp, i); 994 atomic_set(hqp, i);
998 spin_unlock_irqrestore(&priv_tmp->wmm.ra_list_spinlock, flags_ra); 995 spin_unlock_irqrestore(&priv_tmp->wmm.ra_list_spinlock, flags_ra);
999 spin_unlock_irqrestore(&adapter->bss_prio_tbl[j].bss_prio_lock,
1000 flags_bss);
1001 996
1002 *priv = priv_tmp; 997 *priv = priv_tmp;
1003 *tid = tos_to_tid[i]; 998 *tid = tos_to_tid[i];
@@ -1179,6 +1174,14 @@ mwifiex_send_processed_packet(struct mwifiex_private *priv,
1179 1174
1180 skb = skb_dequeue(&ptr->skb_head); 1175 skb = skb_dequeue(&ptr->skb_head);
1181 1176
1177 if (adapter->data_sent || adapter->tx_lock_flag) {
1178 spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock,
1179 ra_list_flags);
1180 skb_queue_tail(&adapter->tx_data_q, skb);
1181 atomic_inc(&adapter->tx_queued);
1182 return;
1183 }
1184
1182 if (!skb_queue_empty(&ptr->skb_head)) 1185 if (!skb_queue_empty(&ptr->skb_head))
1183 skb_next = skb_peek(&ptr->skb_head); 1186 skb_next = skb_peek(&ptr->skb_head);
1184 else 1187 else
@@ -1276,13 +1279,13 @@ mwifiex_dequeue_tx_packet(struct mwifiex_adapter *adapter)
1276 } 1279 }
1277 1280
1278 if (!ptr->is_11n_enabled || 1281 if (!ptr->is_11n_enabled ||
1279 mwifiex_is_ba_stream_setup(priv, ptr, tid) || 1282 ptr->ba_status ||
1280 priv->wps.session_enable) { 1283 priv->wps.session_enable) {
1281 if (ptr->is_11n_enabled && 1284 if (ptr->is_11n_enabled &&
1282 mwifiex_is_ba_stream_setup(priv, ptr, tid) && 1285 ptr->ba_status &&
1283 mwifiex_is_amsdu_in_ampdu_allowed(priv, ptr, tid) && 1286 ptr->amsdu_in_ampdu &&
1284 mwifiex_is_amsdu_allowed(priv, tid) && 1287 mwifiex_is_amsdu_allowed(priv, tid) &&
1285 mwifiex_is_11n_aggragation_possible(priv, ptr, 1288 mwifiex_is_11n_aggragation_possible(priv, ptr,
1286 adapter->tx_buf_size)) 1289 adapter->tx_buf_size))
1287 mwifiex_11n_aggregate_pkt(priv, ptr, ptr_index, flags); 1290 mwifiex_11n_aggregate_pkt(priv, ptr, ptr_index, flags);
1288 /* ra_list_spinlock has been freed in 1291 /* ra_list_spinlock has been freed in
@@ -1329,11 +1332,16 @@ void
1329mwifiex_wmm_process_tx(struct mwifiex_adapter *adapter) 1332mwifiex_wmm_process_tx(struct mwifiex_adapter *adapter)
1330{ 1333{
1331 do { 1334 do {
1332 /* Check if busy */
1333 if (adapter->data_sent || adapter->tx_lock_flag)
1334 break;
1335
1336 if (mwifiex_dequeue_tx_packet(adapter)) 1335 if (mwifiex_dequeue_tx_packet(adapter))
1337 break; 1336 break;
1337 if (adapter->iface_type != MWIFIEX_SDIO) {
1338 if (adapter->data_sent ||
1339 adapter->tx_lock_flag)
1340 break;
1341 } else {
1342 if (atomic_read(&adapter->tx_queued) >=
1343 MWIFIEX_MAX_PKTS_TXQ)
1344 break;
1345 }
1338 } while (!mwifiex_wmm_lists_empty(adapter)); 1346 } while (!mwifiex_wmm_lists_empty(adapter));
1339} 1347}
diff --git a/drivers/net/wireless/mwifiex/wmm.h b/drivers/net/wireless/mwifiex/wmm.h
index 569bd73f33c5..48ece0b35591 100644
--- a/drivers/net/wireless/mwifiex/wmm.h
+++ b/drivers/net/wireless/mwifiex/wmm.h
@@ -127,4 +127,6 @@ mwifiex_wmm_get_queue_raptr(struct mwifiex_private *priv, u8 tid,
127 const u8 *ra_addr); 127 const u8 *ra_addr);
128u8 mwifiex_wmm_downgrade_tid(struct mwifiex_private *priv, u32 tid); 128u8 mwifiex_wmm_downgrade_tid(struct mwifiex_private *priv, u32 tid);
129 129
130struct mwifiex_ra_list_tbl *mwifiex_wmm_get_ralist_node(struct mwifiex_private
131 *priv, u8 tid, const u8 *ra_addr);
130#endif /* !_MWIFIEX_WMM_H_ */ 132#endif /* !_MWIFIEX_WMM_H_ */
diff --git a/drivers/net/wireless/rt2x00/rt2800usb.c b/drivers/net/wireless/rt2x00/rt2800usb.c
index 8444313eabe2..6ec2466b52b6 100644
--- a/drivers/net/wireless/rt2x00/rt2800usb.c
+++ b/drivers/net/wireless/rt2x00/rt2800usb.c
@@ -233,6 +233,7 @@ static int rt2800usb_autorun_detect(struct rt2x00_dev *rt2x00dev)
233{ 233{
234 __le32 *reg; 234 __le32 *reg;
235 u32 fw_mode; 235 u32 fw_mode;
236 int ret;
236 237
237 reg = kmalloc(sizeof(*reg), GFP_KERNEL); 238 reg = kmalloc(sizeof(*reg), GFP_KERNEL);
238 if (reg == NULL) 239 if (reg == NULL)
@@ -242,11 +243,14 @@ static int rt2800usb_autorun_detect(struct rt2x00_dev *rt2x00dev)
242 * magic value USB_MODE_AUTORUN (0x11) to the device, thus the 243 * magic value USB_MODE_AUTORUN (0x11) to the device, thus the
243 * returned value would be invalid. 244 * returned value would be invalid.
244 */ 245 */
245 rt2x00usb_vendor_request(rt2x00dev, USB_DEVICE_MODE, 246 ret = rt2x00usb_vendor_request(rt2x00dev, USB_DEVICE_MODE,
246 USB_VENDOR_REQUEST_IN, 0, USB_MODE_AUTORUN, 247 USB_VENDOR_REQUEST_IN, 0,
247 reg, sizeof(*reg), REGISTER_TIMEOUT_FIRMWARE); 248 USB_MODE_AUTORUN, reg, sizeof(*reg),
249 REGISTER_TIMEOUT_FIRMWARE);
248 fw_mode = le32_to_cpu(*reg); 250 fw_mode = le32_to_cpu(*reg);
249 kfree(reg); 251 kfree(reg);
252 if (ret < 0)
253 return ret;
250 254
251 if ((fw_mode & 0x00000003) == 2) 255 if ((fw_mode & 0x00000003) == 2)
252 return 1; 256 return 1;
@@ -289,6 +293,7 @@ static int rt2800usb_write_firmware(struct rt2x00_dev *rt2x00dev,
289 if (retval) { 293 if (retval) {
290 rt2x00_info(rt2x00dev, 294 rt2x00_info(rt2x00dev,
291 "Firmware loading not required - NIC in AutoRun mode\n"); 295 "Firmware loading not required - NIC in AutoRun mode\n");
296 __clear_bit(REQUIRE_FIRMWARE, &rt2x00dev->cap_flags);
292 } else { 297 } else {
293 rt2x00usb_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE, 298 rt2x00usb_register_multiwrite(rt2x00dev, FIRMWARE_IMAGE_BASE,
294 data + offset, length); 299 data + offset, length);
@@ -374,7 +379,6 @@ static int rt2800usb_enable_radio(struct rt2x00_dev *rt2x00dev)
374static void rt2800usb_disable_radio(struct rt2x00_dev *rt2x00dev) 379static void rt2800usb_disable_radio(struct rt2x00_dev *rt2x00dev)
375{ 380{
376 rt2800_disable_radio(rt2x00dev); 381 rt2800_disable_radio(rt2x00dev);
377 rt2x00usb_disable_radio(rt2x00dev);
378} 382}
379 383
380static int rt2800usb_set_state(struct rt2x00_dev *rt2x00dev, 384static int rt2800usb_set_state(struct rt2x00_dev *rt2x00dev,
@@ -1040,6 +1044,7 @@ static struct usb_device_id rt2800usb_device_table[] = {
1040 { USB_DEVICE(0x07d1, 0x3c17) }, 1044 { USB_DEVICE(0x07d1, 0x3c17) },
1041 { USB_DEVICE(0x2001, 0x3317) }, 1045 { USB_DEVICE(0x2001, 0x3317) },
1042 { USB_DEVICE(0x2001, 0x3c1b) }, 1046 { USB_DEVICE(0x2001, 0x3c1b) },
1047 { USB_DEVICE(0x2001, 0x3c25) },
1043 /* Draytek */ 1048 /* Draytek */
1044 { USB_DEVICE(0x07fa, 0x7712) }, 1049 { USB_DEVICE(0x07fa, 0x7712) },
1045 /* DVICO */ 1050 /* DVICO */
diff --git a/drivers/net/wireless/rt2x00/rt2x00usb.h b/drivers/net/wireless/rt2x00/rt2x00usb.h
index 8f85fbd5f237..569363da00a2 100644
--- a/drivers/net/wireless/rt2x00/rt2x00usb.h
+++ b/drivers/net/wireless/rt2x00/rt2x00usb.h
@@ -199,7 +199,7 @@ static inline void rt2x00usb_register_read(struct rt2x00_dev *rt2x00dev,
199 const unsigned int offset, 199 const unsigned int offset,
200 u32 *value) 200 u32 *value)
201{ 201{
202 __le32 reg; 202 __le32 reg = 0;
203 rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_READ, 203 rt2x00usb_vendor_request_buff(rt2x00dev, USB_MULTI_READ,
204 USB_VENDOR_REQUEST_IN, offset, 204 USB_VENDOR_REQUEST_IN, offset,
205 &reg, sizeof(reg)); 205 &reg, sizeof(reg));
@@ -219,7 +219,7 @@ static inline void rt2x00usb_register_read_lock(struct rt2x00_dev *rt2x00dev,
219 const unsigned int offset, 219 const unsigned int offset,
220 u32 *value) 220 u32 *value)
221{ 221{
222 __le32 reg; 222 __le32 reg = 0;
223 rt2x00usb_vendor_req_buff_lock(rt2x00dev, USB_MULTI_READ, 223 rt2x00usb_vendor_req_buff_lock(rt2x00dev, USB_MULTI_READ,
224 USB_VENDOR_REQUEST_IN, offset, 224 USB_VENDOR_REQUEST_IN, offset,
225 &reg, sizeof(reg), REGISTER_TIMEOUT); 225 &reg, sizeof(reg), REGISTER_TIMEOUT);
diff --git a/drivers/net/wireless/rtlwifi/base.h b/drivers/net/wireless/rtlwifi/base.h
index dee4ac2f27e2..ff9a4bfd4515 100644
--- a/drivers/net/wireless/rtlwifi/base.h
+++ b/drivers/net/wireless/rtlwifi/base.h
@@ -123,7 +123,6 @@ bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb);
123u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx); 123u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx);
124 124
125void rtl_beacon_statistic(struct ieee80211_hw *hw, struct sk_buff *skb); 125void rtl_beacon_statistic(struct ieee80211_hw *hw, struct sk_buff *skb);
126void rtl_watch_dog_timer_callback(unsigned long data);
127int rtl_tx_agg_start(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 126int rtl_tx_agg_start(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
128 struct ieee80211_sta *sta, u16 tid, u16 *ssn); 127 struct ieee80211_sta *sta, u16 tid, u16 *ssn);
129int rtl_tx_agg_stop(struct ieee80211_hw *hw, struct ieee80211_vif *vif, 128int rtl_tx_agg_stop(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c b/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c
index edc2cbb6253c..86ce5b1930e6 100644
--- a/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8188ee/hw.c
@@ -30,6 +30,7 @@
30#include "../cam.h" 30#include "../cam.h"
31#include "../ps.h" 31#include "../ps.h"
32#include "../pci.h" 32#include "../pci.h"
33#include "../pwrseqcmd.h"
33#include "reg.h" 34#include "reg.h"
34#include "def.h" 35#include "def.h"
35#include "phy.h" 36#include "phy.h"
@@ -885,7 +886,7 @@ static bool _rtl88ee_init_mac(struct ieee80211_hw *hw)
885 886
886 rtl_write_word(rtlpriv, REG_CR, 0x2ff); 887 rtl_write_word(rtlpriv, REG_CR, 0x2ff);
887 rtl_write_byte(rtlpriv, REG_CR+1, 0x06); 888 rtl_write_byte(rtlpriv, REG_CR+1, 0x06);
888 rtl_write_byte(rtlpriv, REG_CR+2, 0x00); 889 rtl_write_byte(rtlpriv, MSR, 0x00);
889 890
890 if (!rtlhal->mac_func_enable) { 891 if (!rtlhal->mac_func_enable) {
891 if (_rtl88ee_llt_table_init(hw) == false) { 892 if (_rtl88ee_llt_table_init(hw) == false) {
@@ -1277,7 +1278,7 @@ static int _rtl88ee_set_media_status(struct ieee80211_hw *hw,
1277 mode); 1278 mode);
1278 } 1279 }
1279 1280
1280 rtl_write_byte(rtlpriv, (MSR), bt_msr | mode); 1281 rtl_write_byte(rtlpriv, MSR, bt_msr | mode);
1281 rtlpriv->cfg->ops->led_control(hw, ledaction); 1282 rtlpriv->cfg->ops->led_control(hw, ledaction);
1282 if (mode == MSR_AP) 1283 if (mode == MSR_AP)
1283 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00); 1284 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
index 0c20dd74d6ec..d310d55d800e 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
@@ -1364,7 +1364,7 @@ static int _rtl92cu_set_media_status(struct ieee80211_hw *hw,
1364 "Network type %d not supported!\n", type); 1364 "Network type %d not supported!\n", type);
1365 goto error_out; 1365 goto error_out;
1366 } 1366 }
1367 rtl_write_byte(rtlpriv, (MSR), bt_msr); 1367 rtl_write_byte(rtlpriv, MSR, bt_msr);
1368 rtlpriv->cfg->ops->led_control(hw, ledaction); 1368 rtlpriv->cfg->ops->led_control(hw, ledaction);
1369 if ((bt_msr & MSR_MASK) == MSR_AP) 1369 if ((bt_msr & MSR_MASK) == MSR_AP)
1370 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00); 1370 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00);
@@ -1471,8 +1471,7 @@ static void _InitBeaconParameters(struct ieee80211_hw *hw)
1471 rtl_write_word(rtlpriv, REG_BCNTCFG, 0x66FF); 1471 rtl_write_word(rtlpriv, REG_BCNTCFG, 0x66FF);
1472} 1472}
1473 1473
1474static void _beacon_function_enable(struct ieee80211_hw *hw, bool Enable, 1474static void _beacon_function_enable(struct ieee80211_hw *hw)
1475 bool Linked)
1476{ 1475{
1477 struct rtl_priv *rtlpriv = rtl_priv(hw); 1476 struct rtl_priv *rtlpriv = rtl_priv(hw);
1478 1477
@@ -1517,7 +1516,7 @@ void rtl92cu_set_beacon_related_registers(struct ieee80211_hw *hw)
1517 rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x50); 1516 rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x50);
1518 rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x50); 1517 rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x50);
1519 } 1518 }
1520 _beacon_function_enable(hw, true, true); 1519 _beacon_function_enable(hw);
1521} 1520}
1522 1521
1523void rtl92cu_set_beacon_interval(struct ieee80211_hw *hw) 1522void rtl92cu_set_beacon_interval(struct ieee80211_hw *hw)
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c
index 133e395b7401..adb810794eef 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/mac.c
@@ -497,7 +497,7 @@ int rtl92c_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type)
497 "Network type %d not supported!\n", type); 497 "Network type %d not supported!\n", type);
498 return -EOPNOTSUPP; 498 return -EOPNOTSUPP;
499 } 499 }
500 rtl_write_byte(rtlpriv, (REG_CR + 2), value); 500 rtl_write_byte(rtlpriv, MSR, value);
501 return 0; 501 return 0;
502} 502}
503 503
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
index 90a714c189a8..23806c243a53 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
@@ -321,6 +321,7 @@ static struct usb_device_id rtl8192c_usb_ids[] = {
321 {RTL_USB_DEVICE(0x07b8, 0x8188, rtl92cu_hal_cfg)}, /*Abocom - Abocom*/ 321 {RTL_USB_DEVICE(0x07b8, 0x8188, rtl92cu_hal_cfg)}, /*Abocom - Abocom*/
322 {RTL_USB_DEVICE(0x07b8, 0x8189, rtl92cu_hal_cfg)}, /*Funai - Abocom*/ 322 {RTL_USB_DEVICE(0x07b8, 0x8189, rtl92cu_hal_cfg)}, /*Funai - Abocom*/
323 {RTL_USB_DEVICE(0x0846, 0x9041, rtl92cu_hal_cfg)}, /*NetGear WNA1000M*/ 323 {RTL_USB_DEVICE(0x0846, 0x9041, rtl92cu_hal_cfg)}, /*NetGear WNA1000M*/
324 {RTL_USB_DEVICE(0x0b05, 0x17ba, rtl92cu_hal_cfg)}, /*ASUS-Edimax*/
324 {RTL_USB_DEVICE(0x0bda, 0x5088, rtl92cu_hal_cfg)}, /*Thinkware-CC&C*/ 325 {RTL_USB_DEVICE(0x0bda, 0x5088, rtl92cu_hal_cfg)}, /*Thinkware-CC&C*/
325 {RTL_USB_DEVICE(0x0df6, 0x0052, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/ 326 {RTL_USB_DEVICE(0x0df6, 0x0052, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/
326 {RTL_USB_DEVICE(0x0df6, 0x005c, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/ 327 {RTL_USB_DEVICE(0x0df6, 0x005c, rtl92cu_hal_cfg)}, /*Sitecom - Edimax*/
@@ -377,6 +378,7 @@ static struct usb_device_id rtl8192c_usb_ids[] = {
377 {RTL_USB_DEVICE(0x2001, 0x3307, rtl92cu_hal_cfg)}, /*D-Link-Cameo*/ 378 {RTL_USB_DEVICE(0x2001, 0x3307, rtl92cu_hal_cfg)}, /*D-Link-Cameo*/
378 {RTL_USB_DEVICE(0x2001, 0x3309, rtl92cu_hal_cfg)}, /*D-Link-Alpha*/ 379 {RTL_USB_DEVICE(0x2001, 0x3309, rtl92cu_hal_cfg)}, /*D-Link-Alpha*/
379 {RTL_USB_DEVICE(0x2001, 0x330a, rtl92cu_hal_cfg)}, /*D-Link-Alpha*/ 380 {RTL_USB_DEVICE(0x2001, 0x330a, rtl92cu_hal_cfg)}, /*D-Link-Alpha*/
381 {RTL_USB_DEVICE(0x2001, 0x330d, rtl92cu_hal_cfg)}, /*D-Link DWA-131 */
380 {RTL_USB_DEVICE(0x2019, 0xab2b, rtl92cu_hal_cfg)}, /*Planex -Abocom*/ 382 {RTL_USB_DEVICE(0x2019, 0xab2b, rtl92cu_hal_cfg)}, /*Planex -Abocom*/
381 {RTL_USB_DEVICE(0x20f4, 0x624d, rtl92cu_hal_cfg)}, /*TRENDNet*/ 383 {RTL_USB_DEVICE(0x20f4, 0x624d, rtl92cu_hal_cfg)}, /*TRENDNet*/
382 {RTL_USB_DEVICE(0x2357, 0x0100, rtl92cu_hal_cfg)}, /*TP-Link WN8200ND*/ 384 {RTL_USB_DEVICE(0x2357, 0x0100, rtl92cu_hal_cfg)}, /*TP-Link WN8200ND*/
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c
index 01bcc2d218dc..f49b60d31450 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c
@@ -1126,7 +1126,7 @@ static int _rtl92de_set_media_status(struct ieee80211_hw *hw,
1126 break; 1126 break;
1127 1127
1128 } 1128 }
1129 rtl_write_byte(rtlpriv, REG_CR + 2, bt_msr); 1129 rtl_write_byte(rtlpriv, MSR, bt_msr);
1130 rtlpriv->cfg->ops->led_control(hw, ledaction); 1130 rtlpriv->cfg->ops->led_control(hw, ledaction);
1131 if ((bt_msr & MSR_MASK) == MSR_AP) 1131 if ((bt_msr & MSR_MASK) == MSR_AP)
1132 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00); 1132 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ee/hw.c b/drivers/net/wireless/rtlwifi/rtl8192ee/hw.c
index db230a3f0137..da0a6125f314 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192ee/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ee/hw.c
@@ -1510,7 +1510,7 @@ static int _rtl92ee_set_media_status(struct ieee80211_hw *hw,
1510 mode); 1510 mode);
1511 } 1511 }
1512 1512
1513 rtl_write_byte(rtlpriv, (MSR), bt_msr | mode); 1513 rtl_write_byte(rtlpriv, MSR, bt_msr | mode);
1514 rtlpriv->cfg->ops->led_control(hw, ledaction); 1514 rtlpriv->cfg->ops->led_control(hw, ledaction);
1515 if (mode == MSR_AP) 1515 if (mode == MSR_AP)
1516 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00); 1516 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00);
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c
index dee88a80bee1..12b0978ba4fa 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c
@@ -1204,7 +1204,7 @@ static int _rtl92se_set_media_status(struct ieee80211_hw *hw,
1204 if (type != NL80211_IFTYPE_AP && 1204 if (type != NL80211_IFTYPE_AP &&
1205 rtlpriv->mac80211.link_state < MAC80211_LINKED) 1205 rtlpriv->mac80211.link_state < MAC80211_LINKED)
1206 bt_msr = rtl_read_byte(rtlpriv, MSR) & ~MSR_LINK_MASK; 1206 bt_msr = rtl_read_byte(rtlpriv, MSR) & ~MSR_LINK_MASK;
1207 rtl_write_byte(rtlpriv, (MSR), bt_msr); 1207 rtl_write_byte(rtlpriv, MSR, bt_msr);
1208 1208
1209 temp = rtl_read_dword(rtlpriv, TCR); 1209 temp = rtl_read_dword(rtlpriv, TCR);
1210 rtl_write_dword(rtlpriv, TCR, temp & (~BIT(8))); 1210 rtl_write_dword(rtlpriv, TCR, temp & (~BIT(8)));
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c b/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c
index b3b094759f6d..67bb47d77b68 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/hw.c
@@ -1183,7 +1183,7 @@ static int _rtl8723e_set_media_status(struct ieee80211_hw *hw,
1183 mode); 1183 mode);
1184 } 1184 }
1185 1185
1186 rtl_write_byte(rtlpriv, (MSR), bt_msr | mode); 1186 rtl_write_byte(rtlpriv, MSR, bt_msr | mode);
1187 rtlpriv->cfg->ops->led_control(hw, ledaction); 1187 rtlpriv->cfg->ops->led_control(hw, ledaction);
1188 if (mode == MSR_AP) 1188 if (mode == MSR_AP)
1189 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00); 1189 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00);
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/hw.c b/drivers/net/wireless/rtlwifi/rtl8723be/hw.c
index b46998341c40..b681af3c7a35 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723be/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723be/hw.c
@@ -1558,7 +1558,7 @@ static int _rtl8723be_set_media_status(struct ieee80211_hw *hw,
1558 mode); 1558 mode);
1559 } 1559 }
1560 1560
1561 rtl_write_byte(rtlpriv, (MSR), bt_msr | mode); 1561 rtl_write_byte(rtlpriv, MSR, bt_msr | mode);
1562 rtlpriv->cfg->ops->led_control(hw, ledaction); 1562 rtlpriv->cfg->ops->led_control(hw, ledaction);
1563 if (mode == MSR_AP) 1563 if (mode == MSR_AP)
1564 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00); 1564 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00);
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/hw.c b/drivers/net/wireless/rtlwifi/rtl8821ae/hw.c
index 2a0a71bac00c..8704eee9f3a4 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8821ae/hw.c
@@ -423,7 +423,7 @@ void rtl8821ae_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
423 *((u16 *)(val+4)) = rtl_read_word(rtlpriv, REG_BSSID+4); 423 *((u16 *)(val+4)) = rtl_read_word(rtlpriv, REG_BSSID+4);
424 break; 424 break;
425 case HW_VAR_MEDIA_STATUS: 425 case HW_VAR_MEDIA_STATUS:
426 val[0] = rtl_read_byte(rtlpriv, REG_CR+2) & 0x3; 426 val[0] = rtl_read_byte(rtlpriv, MSR) & 0x3;
427 break; 427 break;
428 case HW_VAR_SLOT_TIME: 428 case HW_VAR_SLOT_TIME:
429 *((u8 *)(val)) = mac->slot_time; 429 *((u8 *)(val)) = mac->slot_time;
@@ -2178,7 +2178,7 @@ static int _rtl8821ae_set_media_status(struct ieee80211_hw *hw,
2178 return 1; 2178 return 1;
2179 } 2179 }
2180 2180
2181 rtl_write_byte(rtlpriv, (MSR), bt_msr); 2181 rtl_write_byte(rtlpriv, MSR, bt_msr);
2182 rtlpriv->cfg->ops->led_control(hw, ledaction); 2182 rtlpriv->cfg->ops->led_control(hw, ledaction);
2183 if ((bt_msr & 0xfc) == MSR_AP) 2183 if ((bt_msr & 0xfc) == MSR_AP)
2184 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00); 2184 rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00);
diff --git a/drivers/net/wireless/rtlwifi/rtl8821ae/trx.c b/drivers/net/wireless/rtlwifi/rtl8821ae/trx.c
index 72af4b9ee32b..174743aef943 100644
--- a/drivers/net/wireless/rtlwifi/rtl8821ae/trx.c
+++ b/drivers/net/wireless/rtlwifi/rtl8821ae/trx.c
@@ -64,6 +64,20 @@ static u16 odm_cfo(char value)
64 return ret_val; 64 return ret_val;
65} 65}
66 66
67static u8 _rtl8821ae_evm_dbm_jaguar(char value)
68{
69 char ret_val = value;
70
71 /* -33dB~0dB to 33dB ~ 0dB*/
72 if (ret_val == -128)
73 ret_val = 127;
74 else if (ret_val < 0)
75 ret_val = 0 - ret_val;
76
77 ret_val = ret_val >> 1;
78 return ret_val;
79}
80
67static void query_rxphystatus(struct ieee80211_hw *hw, 81static void query_rxphystatus(struct ieee80211_hw *hw,
68 struct rtl_stats *pstatus, u8 *pdesc, 82 struct rtl_stats *pstatus, u8 *pdesc,
69 struct rx_fwinfo_8821ae *p_drvinfo, 83 struct rx_fwinfo_8821ae *p_drvinfo,
@@ -246,7 +260,7 @@ static void query_rxphystatus(struct ieee80211_hw *hw,
246 260
247 for (i = 0; i < max_spatial_stream; i++) { 261 for (i = 0; i < max_spatial_stream; i++) {
248 evm = rtl_evm_db_to_percentage(p_phystrpt->rxevm[i]); 262 evm = rtl_evm_db_to_percentage(p_phystrpt->rxevm[i]);
249 evmdbm = rtl_evm_dbm_jaguar(p_phystrpt->rxevm[i]); 263 evmdbm = _rtl8821ae_evm_dbm_jaguar(p_phystrpt->rxevm[i]);
250 264
251 if (bpacket_match_bssid) { 265 if (bpacket_match_bssid) {
252 /* Fill value in RFD, Get the first 266 /* Fill value in RFD, Get the first
diff --git a/drivers/net/wireless/rtlwifi/stats.c b/drivers/net/wireless/rtlwifi/stats.c
index 2d0736a09fc0..d8b30690b00d 100644
--- a/drivers/net/wireless/rtlwifi/stats.c
+++ b/drivers/net/wireless/rtlwifi/stats.c
@@ -39,15 +39,8 @@ EXPORT_SYMBOL(rtl_query_rxpwrpercentage);
39 39
40u8 rtl_evm_db_to_percentage(char value) 40u8 rtl_evm_db_to_percentage(char value)
41{ 41{
42 char ret_val; 42 char ret_val = clamp(-value, 0, 33) * 3;
43 ret_val = value;
44 43
45 if (ret_val >= 0)
46 ret_val = 0;
47 if (ret_val <= -33)
48 ret_val = -33;
49 ret_val = 0 - ret_val;
50 ret_val *= 3;
51 if (ret_val == 99) 44 if (ret_val == 99)
52 ret_val = 100; 45 ret_val = 100;
53 46
@@ -55,21 +48,6 @@ u8 rtl_evm_db_to_percentage(char value)
55} 48}
56EXPORT_SYMBOL(rtl_evm_db_to_percentage); 49EXPORT_SYMBOL(rtl_evm_db_to_percentage);
57 50
58u8 rtl_evm_dbm_jaguar(char value)
59{
60 char ret_val = value;
61
62 /* -33dB~0dB to 33dB ~ 0dB*/
63 if (ret_val == -128)
64 ret_val = 127;
65 else if (ret_val < 0)
66 ret_val = 0 - ret_val;
67
68 ret_val = ret_val >> 1;
69 return ret_val;
70}
71EXPORT_SYMBOL(rtl_evm_dbm_jaguar);
72
73static long rtl_translate_todbm(struct ieee80211_hw *hw, 51static long rtl_translate_todbm(struct ieee80211_hw *hw,
74 u8 signal_strength_index) 52 u8 signal_strength_index)
75{ 53{
diff --git a/drivers/net/wireless/rtlwifi/stats.h b/drivers/net/wireless/rtlwifi/stats.h
index aa4eec80ccf7..2b57dffef572 100644
--- a/drivers/net/wireless/rtlwifi/stats.h
+++ b/drivers/net/wireless/rtlwifi/stats.h
@@ -35,7 +35,6 @@
35 35
36u8 rtl_query_rxpwrpercentage(char antpower); 36u8 rtl_query_rxpwrpercentage(char antpower);
37u8 rtl_evm_db_to_percentage(char value); 37u8 rtl_evm_db_to_percentage(char value);
38u8 rtl_evm_dbm_jaguar(char value);
39long rtl_signal_scale_mapping(struct ieee80211_hw *hw, long currsig); 38long rtl_signal_scale_mapping(struct ieee80211_hw *hw, long currsig);
40void rtl_process_phyinfo(struct ieee80211_hw *hw, u8 *buffer, 39void rtl_process_phyinfo(struct ieee80211_hw *hw, u8 *buffer,
41 struct rtl_stats *pstatus); 40 struct rtl_stats *pstatus);
diff --git a/drivers/net/wireless/ti/wl18xx/debugfs.c b/drivers/net/wireless/ti/wl18xx/debugfs.c
index c93fae95baac..5fbd2230f372 100644
--- a/drivers/net/wireless/ti/wl18xx/debugfs.c
+++ b/drivers/net/wireless/ti/wl18xx/debugfs.c
@@ -139,7 +139,7 @@ WL18XX_DEBUGFS_FWSTATS_FILE(rx_filter, protection_filter, "%u");
139WL18XX_DEBUGFS_FWSTATS_FILE(rx_filter, accum_arp_pend_requests, "%u"); 139WL18XX_DEBUGFS_FWSTATS_FILE(rx_filter, accum_arp_pend_requests, "%u");
140WL18XX_DEBUGFS_FWSTATS_FILE(rx_filter, max_arp_queue_dep, "%u"); 140WL18XX_DEBUGFS_FWSTATS_FILE(rx_filter, max_arp_queue_dep, "%u");
141 141
142WL18XX_DEBUGFS_FWSTATS_FILE(rx_rate, rx_frames_per_rates, "%u"); 142WL18XX_DEBUGFS_FWSTATS_FILE_ARRAY(rx_rate, rx_frames_per_rates, 50);
143 143
144WL18XX_DEBUGFS_FWSTATS_FILE_ARRAY(aggr_size, tx_agg_vs_rate, 144WL18XX_DEBUGFS_FWSTATS_FILE_ARRAY(aggr_size, tx_agg_vs_rate,
145 AGGR_STATS_TX_AGG*AGGR_STATS_TX_RATE); 145 AGGR_STATS_TX_AGG*AGGR_STATS_TX_RATE);
diff --git a/drivers/net/wireless/ti/wlcore/debugfs.h b/drivers/net/wireless/ti/wlcore/debugfs.h
index 0f2cfb0d2a9e..bf14676e6515 100644
--- a/drivers/net/wireless/ti/wlcore/debugfs.h
+++ b/drivers/net/wireless/ti/wlcore/debugfs.h
@@ -26,8 +26,8 @@
26 26
27#include "wlcore.h" 27#include "wlcore.h"
28 28
29int wl1271_format_buffer(char __user *userbuf, size_t count, 29__printf(4, 5) int wl1271_format_buffer(char __user *userbuf, size_t count,
30 loff_t *ppos, char *fmt, ...); 30 loff_t *ppos, char *fmt, ...);
31 31
32int wl1271_debugfs_init(struct wl1271 *wl); 32int wl1271_debugfs_init(struct wl1271 *wl);
33void wl1271_debugfs_exit(struct wl1271 *wl); 33void wl1271_debugfs_exit(struct wl1271 *wl);