diff options
author | David S. Miller <davem@davemloft.net> | 2015-04-01 14:27:28 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2015-04-01 14:27:28 -0400 |
commit | 45eb5168873c93b4f1c3c3867fea65aad4c6abd6 (patch) | |
tree | 4949e1083f214ce51565d41614df912cba017219 /drivers/net/wireless/ath | |
parent | b9600d2d0901cd0f91cb372e72bd53d22f49638d (diff) | |
parent | 9374e7d2fdcad3c36dafc8d3effd554bc702c4b6 (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')
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 { | |||
74 | struct ar5523_tx_data { | 74 | struct 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 | ||
136 | struct ath_common; | 139 | struct 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:= \ | |||
46 | ath9k_hw-$(CONFIG_ATH9K_WOW) += ar9003_wow.o | 46 | ath9k_hw-$(CONFIG_ATH9K_WOW) += ar9003_wow.o |
47 | 47 | ||
48 | ath9k_hw-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += btcoex.o \ | 48 | ath9k_hw-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += btcoex.o \ |
49 | ar9003_mci.o | 49 | ar9003_mci.o \ |
50 | ar9003_aic.o | ||
50 | 51 | ||
51 | ath9k_hw-$(CONFIG_ATH9K_PCOEM) += ar9003_rtt.o | 52 | ath9k_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[] = { | |||
107 | static void ath9k_hw_update_mibstats(struct ath_hw *ah, | 107 | static 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 | ||
117 | static void ath9k_ani_restart(struct ath_hw *ah) | 127 | static 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 | |||
24 | static const u8 com_att_db_table[ATH_AIC_MAX_COM_ATT_DB_TABLE] = { | ||
25 | 0, 3, 9, 15, 21, 27 | ||
26 | }; | ||
27 | |||
28 | static 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 | |||
40 | static 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 | |||
56 | static 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 | */ | ||
82 | static 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 | |||
106 | static 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 | |||
165 | static 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 | |||
264 | static 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 | |||
436 | static 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 | |||
451 | static 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 | } | ||
513 | exit: | ||
514 | return aic->aic_cal_state; | ||
515 | |||
516 | } | ||
517 | |||
518 | u8 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 | |||
540 | u8 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 | |||
572 | u8 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 | |||
580 | u8 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 | |||
594 | void 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 | |||
34 | enum 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 | |||
41 | struct 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 | |||
50 | struct 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 | |||
56 | u8 ar9003_aic_calibration(struct ath_hw *ah); | ||
57 | u8 ar9003_aic_start_normal(struct ath_hw *ah); | ||
58 | u8 ar9003_aic_cal_reset(struct ath_hw *ah); | ||
59 | u8 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 | ||
23 | static void ar9003_mci_reset_req_wakeup(struct ath_hw *ah) | 24 | static 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 | ||
195 | struct ath_rxbuf { | 195 | struct 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 */ |
48 | enum ath_stomp_type { | 51 | enum 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 | ||
99 | struct 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 | |||
96 | struct ath_btcoex_hw { | 107 | struct 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 | 130 | static void |
131 | ath9k_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) | |||
27 | void ath9k_hw_analog_shift_rmw(struct ath_hw *ah, u32 reg, u32 mask, | 27 | void 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 | ||
520 | static void ath9k_hw_def_set_board_values(struct ath_hw *ah, | 514 | static 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 | ||
447 | enum htc_op_flags { | ||
448 | HTC_FWFLAG_NO_RMW, | ||
449 | }; | ||
450 | |||
447 | struct ath9k_htc_priv { | 451 | struct 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 | ||
379 | static u32 ath9k_reg_rmw(void *hw_priv, u32 reg_offset, u32 set, u32 clr) | 379 | static 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 | |||
418 | static 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 | |||
450 | static 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 | |||
462 | static 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 | ||
487 | static 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 | |||
390 | static void ath_usb_read_cachesize(struct ath_common *common, int *csz) | 512 | static 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 | ||
111 | static 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 | ||
124 | void 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); | ||
150 | error_tmp_data: | ||
151 | kfree(tmp_reg_list); | ||
152 | } | ||
153 | |||
124 | u32 ath9k_hw_reverse_bits(u32 val, u32 n) | 154 | u32 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 | ||
1223 | void ath9k_hw_get_delta_slope_vals(struct ath_hw *ah, u32 coef_scaled, | 1258 | void 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 | |||
312 | struct ath9k_ops_config { | 332 | struct 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, | |||
1008 | bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout); | 1032 | bool ath9k_hw_wait(struct ath_hw *ah, u32 reg, u32 mask, u32 val, u32 timeout); |
1009 | void ath9k_hw_write_array(struct ath_hw *ah, const struct ar5416IniArray *array, | 1033 | void ath9k_hw_write_array(struct ath_hw *ah, const struct ar5416IniArray *array, |
1010 | int column, unsigned int *writecnt); | 1034 | int column, unsigned int *writecnt); |
1035 | void ath9k_hw_read_array(struct ath_hw *ah, u32 array[][2], int size); | ||
1011 | u32 ath9k_hw_reverse_bits(u32 val, u32 n); | 1036 | u32 ath9k_hw_reverse_bits(u32 val, u32 n); |
1012 | u16 ath9k_hw_computetxtime(struct ath_hw *ah, | 1037 | u16 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); | |||
1117 | void ath9k_hw_setslottime(struct ath_hw *ah, u32 us); | 1142 | void ath9k_hw_setslottime(struct ath_hw *ah, u32 us); |
1118 | 1143 | ||
1119 | #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT | 1144 | #ifdef CONFIG_ATH9K_BTCOEX_SUPPORT |
1145 | void ar9003_hw_attach_aic_ops(struct ath_hw *ah); | ||
1120 | static inline bool ath9k_hw_btcoex_is_enabled(struct ath_hw *ah) | 1146 | static 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 |
1163 | static inline void ar9003_hw_attach_aic_ops(struct ath_hw *ah) | ||
1164 | { | ||
1165 | } | ||
1137 | static inline bool ath9k_hw_btcoex_is_enabled(struct ath_hw *ah) | 1166 | static 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 | ||
144 | static 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 | |||
144 | static unsigned int __ath9k_reg_rmw(struct ath_softc *sc, u32 reg_offset, | 154 | static 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 | ||
117 | enum wmi_event_id { | 118 | enum 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 | ||
129 | struct register_write { | 131 | struct register_write { |
130 | __be32 reg; | 132 | __be32 reg; |
131 | __be32 val; | 133 | __be32 val; |
132 | }; | 134 | }; |
133 | 135 | ||
136 | struct register_rmw { | ||
137 | __be32 reg; | ||
138 | __be32 set; | ||
139 | __be32 clr; | ||
140 | } __packed; | ||
141 | |||
134 | struct ath9k_htc_tx_event { | 142 | struct 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 | ||
165 | struct wmi *ath9k_init_wmi(struct ath9k_htc_priv *priv); | 181 | struct 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 */ | ||
793 | err_bcast: | ||
794 | wmi_pcp_stop(wil); | ||
795 | err_pcp_start: | ||
796 | netif_carrier_off(ndev); | ||
787 | out: | 797 | out: |
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 | ||
930 | static 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 | |||
920 | static struct cfg80211_ops wil_cfg80211_ops = { | 945 | static 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 | ||
942 | static void wil_wiphy_init(struct wiphy *wiphy) | 968 | static 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 | ||
69 | static uint rx_ring_order = WIL_RX_RING_SIZE_ORDER_DEFAULT; | 69 | static uint rx_ring_order = WIL_RX_RING_SIZE_ORDER_DEFAULT; |
70 | static uint tx_ring_order = WIL_TX_RING_SIZE_ORDER_DEFAULT; | 70 | static uint tx_ring_order = WIL_TX_RING_SIZE_ORDER_DEFAULT; |
71 | static uint bcast_ring_order = WIL_BCAST_RING_SIZE_ORDER_DEFAULT; | ||
71 | 72 | ||
72 | static int ring_order_set(const char *val, const struct kernel_param *kp) | 73 | static 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 | ||
365 | int 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 | |||
383 | void 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 | |||
363 | static void wil_connect_worker(struct work_struct *work) | 394 | static 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, "a); | 82 | wil_rx_handle(wil, "a); |
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); | |||
33 | MODULE_PARM_DESC(rtap_include_phy_info, | 33 | MODULE_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 | ||
36 | bool rx_align_2; | ||
37 | module_param(rx_align_2, bool, S_IRUGO); | ||
38 | MODULE_PARM_DESC(rx_align_2, " align Rx buffers on 4*n+2, default - no"); | ||
39 | |||
40 | static inline uint wil_rx_snaplen(void) | ||
41 | { | ||
42 | return rx_align_2 ? 6 : 0; | ||
43 | } | ||
44 | |||
36 | static inline int wil_vring_is_empty(struct vring *vring) | 45 | static 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 = ⅆ | 222 | struct vring_rx_desc dd, *d = ⅆ |
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 | */ |
493 | void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev) | 519 | void 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 | ||
752 | int 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 | |||
682 | void wil_vring_fini_tx(struct wil6210_priv *wil, int id) | 818 | void 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 | ||
705 | static struct vring *wil_find_tx_vring(struct wil6210_priv *wil, | 841 | static 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 | ||
738 | static 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 | |||
747 | static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring, | 874 | static 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 | */ |
785 | static struct vring *wil_tx_bcast(struct wil6210_priv *wil, | 923 | static 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 | |||
938 | static 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 | |||
947 | static 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 | ||
1011 | static 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 | |||
836 | static int wil_tx_desc_map(struct vring_tx_desc *d, dma_addr_t pa, u32 len, | 1025 | static 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; | |||
28 | extern unsigned short rx_ring_overflow_thrsh; | 28 | extern unsigned short rx_ring_overflow_thrsh; |
29 | extern int agg_wsize; | 29 | extern int agg_wsize; |
30 | extern u32 vring_idle_trsh; | 30 | extern u32 vring_idle_trsh; |
31 | extern 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); | |||
755 | int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size, | 760 | int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size, |
756 | int cid, int tid); | 761 | int cid, int tid); |
757 | void wil_vring_fini_tx(struct wil6210_priv *wil, int id); | 762 | void wil_vring_fini_tx(struct wil6210_priv *wil, int id); |
763 | int wil_vring_init_bcast(struct wil6210_priv *wil, int id, int size); | ||
764 | int wil_bcast_init(struct wil6210_priv *wil); | ||
765 | void wil_bcast_fini(struct wil6210_priv *wil); | ||
758 | 766 | ||
759 | netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev); | 767 | netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev); |
760 | int wil_tx_complete(struct wil6210_priv *wil, int ringid); | 768 | int 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 | */ | ||
602 | struct 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 | |||
610 | struct 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 | */ |
601 | struct wmi_vring_ba_en_cmd { | 618 | struct 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, |