aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2015-04-01 14:27:28 -0400
committerDavid S. Miller <davem@davemloft.net>2015-04-01 14:27:28 -0400
commit45eb5168873c93b4f1c3c3867fea65aad4c6abd6 (patch)
tree4949e1083f214ce51565d41614df912cba017219 /drivers/net/wireless/ath
parentb9600d2d0901cd0f91cb372e72bd53d22f49638d (diff)
parent9374e7d2fdcad3c36dafc8d3effd554bc702c4b6 (diff)
Merge tag 'wireless-drivers-next-for-davem-2015-04-01' of git://git.kernel.org/pub/scm/linux/kernel/git/kvalo/wireless-drivers-next
Kalle Valo says: ==================== Major changes: ath9k: * add Active Interference Cancellation, a method implemented in the HW to counter WLAN RX > sensitivity degradation when BT is transmitting at the same time. This feature is supported by cards like WB222 based on AR9462. iwlwifi: * Location Aware Regulatory was added by Arik * 8000 device family work * update to the BT Coex firmware API brmcfmac: * add new BCM43455 and BCM43457 SDIO device support * add new BCM43430 SDIO device support wil6210: * take care of AP bridging * fix NAPI behavior * found approach to achieve 4*n+2 alignment of Rx frames rt2x00: * add new rt2800usb device DWA 130 rtlwifi: * add USB ID for D-Link DWA-131 * add USB ID ASUS N10 WiFi dongle mwifiex: * throughput enhancements ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/wireless/ath')
-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
42 files changed, 1728 insertions, 274 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,