aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-09-26 15:19:05 -0400
committerDavid S. Miller <davem@davemloft.net>2014-09-26 15:39:24 -0400
commit57219dc7bfc5cae48c8309974054733499a0dc63 (patch)
treed078e6726dee978e3cc14c6a1467dce1fe2f3225 /drivers/net/wireless
parent6ea754eb761d9e7a8ac6fa462b05f9e4cf04fb6c (diff)
parent7a0a260a0f6ff0226c33cf28a5cc26711ab0ae5f (diff)
Merge tag 'master-2014-09-16' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless-next
John W. Linville says: ==================== pull request: wireless-next 2014-09-22 Please pull this batch of updates intended for the 3.18 stream... For the mac80211 bits, Johannes says: "This time, I have some rate minstrel improvements, support for a very small feature from CCX that Steinar reverse-engineered, dynamic ACK timeout support, a number of changes for TDLS, early support for radio resource measurement and many fixes. Also, I'm changing a number of places to clear key memory when it's freed and Intel claims copyright for code they developed." For the bluetooth bits, Johan says: "Here are some more patches intended for 3.18. Most of them are cleanups or fixes for SMP. The only exception is a fix for BR/EDR L2CAP fixed channels which should now work better together with the L2CAP information request procedure." For the iwlwifi bits, Emmanuel says: "I fix here dvm which was broken by my last pull request. Arik continues to work on TDLS and Luca solved a few issues in CT-Kill. Eyal keeps digging into rate scaling code, more to come soon. Besides this, nothing really special here." Beyond that, there are the usual big batches of updates to ath9k, b43, mwifiex, and wil6210 as well as a handful of other bits here and there. Also, rtlwifi gets some btcoexist attention from Larry. Please let me know if there are problems! ==================== Had to adjust the wil6210 code to comply with Joe Perches's recent change in net-next to make the netdev_*() routines return void instead of 'int'. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/ath/ath.h2
-rw-r--r--drivers/net/wireless/ath/ath10k/mac.c5
-rw-r--r--drivers/net/wireless/ath/ath5k/mac80211-ops.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/Kconfig9
-rw-r--r--drivers/net/wireless/ath/ath9k/Makefile3
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9002_mac.c7
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mac.c9
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h25
-rw-r--r--drivers/net/wireless/ath/ath9k/beacon.c14
-rw-r--r--drivers/net/wireless/ath/ath9k/channel.c192
-rw-r--r--drivers/net/wireless/ath/ath9k/debug.c30
-rw-r--r--drivers/net/wireless/ath/ath9k/dynack.c351
-rw-r--r--drivers/net/wireless/ath/ath9k/dynack.h103
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.c22
-rw-r--r--drivers/net/wireless/ath/ath9k/hw.h7
-rw-r--r--drivers/net/wireless/ath/ath9k/init.c7
-rw-r--r--drivers/net/wireless/ath/ath9k/mac.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/main.c173
-rw-r--r--drivers/net/wireless/ath/ath9k/recv.c51
-rw-r--r--drivers/net/wireless/ath/ath9k/tx99.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/wow.c2
-rw-r--r--drivers/net/wireless/ath/ath9k/xmit.c5
-rw-r--r--drivers/net/wireless/ath/wil6210/Kconfig9
-rw-r--r--drivers/net/wireless/ath/wil6210/Makefile3
-rw-r--r--drivers/net/wireless/ath/wil6210/cfg80211.c126
-rw-r--r--drivers/net/wireless/ath/wil6210/debug.c18
-rw-r--r--drivers/net/wireless/ath/wil6210/debugfs.c60
-rw-r--r--drivers/net/wireless/ath/wil6210/fw.c45
-rw-r--r--drivers/net/wireless/ath/wil6210/fw.h149
-rw-r--r--drivers/net/wireless/ath/wil6210/fw_inc.c495
-rw-r--r--drivers/net/wireless/ath/wil6210/interrupt.c31
-rw-r--r--drivers/net/wireless/ath/wil6210/main.c185
-rw-r--r--drivers/net/wireless/ath/wil6210/netdev.c17
-rw-r--r--drivers/net/wireless/ath/wil6210/pcie_bus.c39
-rw-r--r--drivers/net/wireless/ath/wil6210/rx_reorder.c13
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.c66
-rw-r--r--drivers/net/wireless/ath/wil6210/txrx.h9
-rw-r--r--drivers/net/wireless/ath/wil6210/wil6210.h56
-rw-r--r--drivers/net/wireless/ath/wil6210/wil_platform.c49
-rw-r--r--drivers/net/wireless/ath/wil6210/wil_platform.h34
-rw-r--r--drivers/net/wireless/ath/wil6210/wil_platform_msm.c257
-rw-r--r--drivers/net/wireless/ath/wil6210/wil_platform_msm.h24
-rw-r--r--drivers/net/wireless/ath/wil6210/wmi.c40
-rw-r--r--drivers/net/wireless/ath/wil6210/wmi.h18
-rw-r--r--drivers/net/wireless/b43/b43.h9
-rw-r--r--drivers/net/wireless/b43/main.c71
-rw-r--r--drivers/net/wireless/b43/main.h2
-rw-r--r--drivers/net/wireless/b43/phy_ht.c205
-rw-r--r--drivers/net/wireless/b43/phy_ht.h7
-rw-r--r--drivers/net/wireless/b43/phy_n.c2
-rw-r--r--drivers/net/wireless/b43/radio_2059.c341
-rw-r--r--drivers/net/wireless/b43/radio_2059.h14
-rw-r--r--drivers/net/wireless/b43/xmit.h22
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/dma.c38
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c122
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c6
-rw-r--r--drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c8
-rw-r--r--drivers/net/wireless/hostap/hostap_proc.c6
-rw-r--r--drivers/net/wireless/iwlegacy/4965-mac.c7
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/mac80211.c4
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-7000.c15
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-8000.c14
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-config.h6
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-csr.h10
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-drv.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-fw.h2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-io.c2
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-nvm-parse.c3
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-trans.h8
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/Makefile2
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/coex.c4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/constants.h8
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/debugfs.c15
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw-api.h36
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/fw.c3
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c10
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mac80211.c158
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h30
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/nvm.c3
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c18
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/power.c62
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/quota.c32
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.c68
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/rs.h10
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/scan.c4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sf.c4
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/sta.c12
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tdls.c149
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/time-event.c10
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/time-event.h8
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tt.c326
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/tx.c2
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/drv.c1
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/internal.h2
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/rx.c2
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c3
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/tx.c12
-rw-r--r--drivers/net/wireless/mac80211_hwsim.c8
-rw-r--r--drivers/net/wireless/mwifiex/11n_rxreorder.c14
-rw-r--r--drivers/net/wireless/mwifiex/cfg80211.c15
-rw-r--r--drivers/net/wireless/mwifiex/cmdevt.c4
-rw-r--r--drivers/net/wireless/mwifiex/decl.h4
-rw-r--r--drivers/net/wireless/mwifiex/fw.h10
-rw-r--r--drivers/net/wireless/mwifiex/init.c21
-rw-r--r--drivers/net/wireless/mwifiex/main.c191
-rw-r--r--drivers/net/wireless/mwifiex/main.h48
-rw-r--r--drivers/net/wireless/mwifiex/pcie.c37
-rw-r--r--drivers/net/wireless/mwifiex/pcie.h5
-rw-r--r--drivers/net/wireless/mwifiex/scan.c112
-rw-r--r--drivers/net/wireless/mwifiex/sdio.c28
-rw-r--r--drivers/net/wireless/mwifiex/sta_cmdresp.c2
-rw-r--r--drivers/net/wireless/mwifiex/sta_ioctl.c9
-rw-r--r--drivers/net/wireless/mwifiex/tdls.c4
-rw-r--r--drivers/net/wireless/p54/main.c3
-rw-r--r--drivers/net/wireless/rtlwifi/btcoexist/halbt_precomp.h6
-rw-r--r--drivers/net/wireless/rtlwifi/btcoexist/halbtc8192e2ant.c3849
-rw-r--r--drivers/net/wireless/rtlwifi/btcoexist/halbtc8192e2ant.h185
-rw-r--r--drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b1ant.c3170
-rw-r--r--drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b1ant.h184
-rw-r--r--drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.c550
-rw-r--r--drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.h31
-rw-r--r--drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a1ant.c2970
-rw-r--r--drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a1ant.h188
-rw-r--r--drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a2ant.c3879
-rw-r--r--drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a2ant.h205
-rw-r--r--drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.c52
-rw-r--r--drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.h122
-rw-r--r--drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.c27
-rw-r--r--drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.h6
-rw-r--r--drivers/net/wireless/rtlwifi/pci.c6
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8192de/phy.c8
-rw-r--r--drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c4
-rw-r--r--drivers/net/wireless/rtlwifi/wifi.h15
135 files changed, 18980 insertions, 1682 deletions
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index c1a4ade32772..a3b6e27d9121 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -234,6 +234,7 @@ void ath_printk(const char *level, const struct ath_common *common,
234 * AR9462. 234 * AR9462.
235 * @ATH_DBG_DFS: radar datection 235 * @ATH_DBG_DFS: radar datection
236 * @ATH_DBG_WOW: Wake on Wireless 236 * @ATH_DBG_WOW: Wake on Wireless
237 * @ATH_DBG_DYNACK: dynack handling
237 * @ATH_DBG_ANY: enable all debugging 238 * @ATH_DBG_ANY: enable all debugging
238 * 239 *
239 * The debug level is used to control the amount and type of debugging output 240 * The debug level is used to control the amount and type of debugging output
@@ -262,6 +263,7 @@ enum ATH_DEBUG {
262 ATH_DBG_DFS = 0x00010000, 263 ATH_DBG_DFS = 0x00010000,
263 ATH_DBG_WOW = 0x00020000, 264 ATH_DBG_WOW = 0x00020000,
264 ATH_DBG_CHAN_CTX = 0x00040000, 265 ATH_DBG_CHAN_CTX = 0x00040000,
266 ATH_DBG_DYNACK = 0x00080000,
265 ATH_DBG_ANY = 0xffffffff 267 ATH_DBG_ANY = 0xffffffff
266}; 268};
267 269
diff --git a/drivers/net/wireless/ath/ath10k/mac.c b/drivers/net/wireless/ath/ath10k/mac.c
index b858c8288196..1f35bd1ef563 100644
--- a/drivers/net/wireless/ath/ath10k/mac.c
+++ b/drivers/net/wireless/ath/ath10k/mac.c
@@ -4838,7 +4838,6 @@ int ath10k_mac_register(struct ath10k *ar)
4838 IEEE80211_HW_MFP_CAPABLE | 4838 IEEE80211_HW_MFP_CAPABLE |
4839 IEEE80211_HW_REPORTS_TX_ACK_STATUS | 4839 IEEE80211_HW_REPORTS_TX_ACK_STATUS |
4840 IEEE80211_HW_HAS_RATE_CONTROL | 4840 IEEE80211_HW_HAS_RATE_CONTROL |
4841 IEEE80211_HW_SUPPORTS_STATIC_SMPS |
4842 IEEE80211_HW_AP_LINK_PS | 4841 IEEE80211_HW_AP_LINK_PS |
4843 IEEE80211_HW_SPECTRUM_MGMT; 4842 IEEE80211_HW_SPECTRUM_MGMT;
4844 4843
@@ -4846,8 +4845,10 @@ int ath10k_mac_register(struct ath10k *ar)
4846 * bytes is used for padding/alignment if necessary. */ 4845 * bytes is used for padding/alignment if necessary. */
4847 ar->hw->extra_tx_headroom += sizeof(struct htt_data_tx_desc_frag)*2 + 4; 4846 ar->hw->extra_tx_headroom += sizeof(struct htt_data_tx_desc_frag)*2 + 4;
4848 4847
4848 ar->hw->wiphy->features |= NL80211_FEATURE_STATIC_SMPS;
4849
4849 if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS) 4850 if (ar->ht_cap_info & WMI_HT_CAP_DYNAMIC_SMPS)
4850 ar->hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS; 4851 ar->hw->wiphy->features |= NL80211_FEATURE_DYNAMIC_SMPS;
4851 4852
4852 if (ar->ht_cap_info & WMI_HT_CAP_ENABLED) { 4853 if (ar->ht_cap_info & WMI_HT_CAP_ENABLED) {
4853 ar->hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION; 4854 ar->hw->flags |= IEEE80211_HW_AMPDU_AGGREGATION;
diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
index b65c38fdaa4b..ab2709a43768 100644
--- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c
+++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c
@@ -704,7 +704,7 @@ ath5k_get_survey(struct ieee80211_hw *hw, int idx, struct survey_info *survey)
704 * reset. 704 * reset.
705 */ 705 */
706static void 706static void
707ath5k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class) 707ath5k_set_coverage_class(struct ieee80211_hw *hw, s16 coverage_class)
708{ 708{
709 struct ath5k_hw *ah = hw->priv; 709 struct ath5k_hw *ah = hw->priv;
710 710
diff --git a/drivers/net/wireless/ath/ath9k/Kconfig b/drivers/net/wireless/ath/ath9k/Kconfig
index b8f570ed39ad..896e63281b3b 100644
--- a/drivers/net/wireless/ath/ath9k/Kconfig
+++ b/drivers/net/wireless/ath/ath9k/Kconfig
@@ -92,6 +92,15 @@ config ATH9K_DFS_CERTIFIED
92 developed. At this point enabling this option won't do anything 92 developed. At this point enabling this option won't do anything
93 except increase code size. 93 except increase code size.
94 94
95config ATH9K_DYNACK
96 bool "Atheros ath9k ACK timeout estimation algorithm (EXPERIMENTAL)"
97 depends on ATH9K
98 default n
99 ---help---
100 This option enables ath9k dynamic ACK timeout estimation algorithm
101 based on ACK frame RX timestamp, TX frame timestamp and frame
102 duration
103
95config ATH9K_TX99 104config ATH9K_TX99
96 bool "Atheros ath9k TX99 testing support" 105 bool "Atheros ath9k TX99 testing support"
97 depends on ATH9K_DEBUGFS && CFG80211_CERTIFICATION_ONUS 106 depends on ATH9K_DEBUGFS && CFG80211_CERTIFICATION_ONUS
diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
index 6b4020a57984..73704c1be736 100644
--- a/drivers/net/wireless/ath/ath9k/Makefile
+++ b/drivers/net/wireless/ath/ath9k/Makefile
@@ -49,6 +49,9 @@ ath9k_hw-$(CONFIG_ATH9K_WOW) += ar9003_wow.o
49 49
50ath9k_hw-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += btcoex.o \ 50ath9k_hw-$(CONFIG_ATH9K_BTCOEX_SUPPORT) += btcoex.o \
51 ar9003_mci.o 51 ar9003_mci.o
52
53ath9k_hw-$(CONFIG_ATH9K_DYNACK) += dynack.o
54
52obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o 55obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o
53 56
54obj-$(CONFIG_ATH9K_COMMON) += ath9k_common.o 57obj-$(CONFIG_ATH9K_COMMON) += ath9k_common.o
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_mac.c b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
index 59af9f9712da..669cb3747208 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_mac.c
@@ -381,6 +381,13 @@ static int ar9002_hw_proc_txdesc(struct ath_hw *ah, void *ds,
381 ts->evm1 = ads->AR_TxEVM1; 381 ts->evm1 = ads->AR_TxEVM1;
382 ts->evm2 = ads->AR_TxEVM2; 382 ts->evm2 = ads->AR_TxEVM2;
383 383
384 status = ACCESS_ONCE(ads->ds_ctl4);
385 ts->duration[0] = MS(status, AR_PacketDur0);
386 ts->duration[1] = MS(status, AR_PacketDur1);
387 status = ACCESS_ONCE(ads->ds_ctl5);
388 ts->duration[2] = MS(status, AR_PacketDur2);
389 ts->duration[3] = MS(status, AR_PacketDur3);
390
384 return 0; 391 return 0;
385} 392}
386 393
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mac.c b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
index 71e38e85aa99..e5f7c11fa144 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mac.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mac.c
@@ -355,9 +355,11 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds,
355 struct ath_tx_status *ts) 355 struct ath_tx_status *ts)
356{ 356{
357 struct ar9003_txs *ads; 357 struct ar9003_txs *ads;
358 struct ar9003_txc *adc;
358 u32 status; 359 u32 status;
359 360
360 ads = &ah->ts_ring[ah->ts_tail]; 361 ads = &ah->ts_ring[ah->ts_tail];
362 adc = (struct ar9003_txc *)ads;
361 363
362 status = ACCESS_ONCE(ads->status8); 364 status = ACCESS_ONCE(ads->status8);
363 if ((status & AR_TxDone) == 0) 365 if ((status & AR_TxDone) == 0)
@@ -426,6 +428,13 @@ static int ar9003_hw_proc_txdesc(struct ath_hw *ah, void *ds,
426 ts->ts_rssi_ext1 = MS(status, AR_TxRSSIAnt11); 428 ts->ts_rssi_ext1 = MS(status, AR_TxRSSIAnt11);
427 ts->ts_rssi_ext2 = MS(status, AR_TxRSSIAnt12); 429 ts->ts_rssi_ext2 = MS(status, AR_TxRSSIAnt12);
428 430
431 status = ACCESS_ONCE(adc->ctl15);
432 ts->duration[0] = MS(status, AR_PacketDur0);
433 ts->duration[1] = MS(status, AR_PacketDur1);
434 status = ACCESS_ONCE(adc->ctl16);
435 ts->duration[2] = MS(status, AR_PacketDur2);
436 ts->duration[3] = MS(status, AR_PacketDur3);
437
429 memset(ads, 0, sizeof(*ads)); 438 memset(ads, 0, sizeof(*ads));
430 439
431 return 0; 440 return 0;
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index c690601f7276..8cd116efe3ea 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -274,6 +274,9 @@ struct ath_node {
274 struct ath_rx_rate_stats rx_rate_stats; 274 struct ath_rx_rate_stats rx_rate_stats;
275#endif 275#endif
276 u8 key_idx[4]; 276 u8 key_idx[4];
277
278 u32 ackto;
279 struct list_head list;
277}; 280};
278 281
279struct ath_tx_control { 282struct ath_tx_control {
@@ -314,7 +317,6 @@ struct ath_rx {
314 bool discard_next; 317 bool discard_next;
315 u32 *rxlink; 318 u32 *rxlink;
316 u32 num_pkts; 319 u32 num_pkts;
317 unsigned int rxfilter;
318 struct list_head rxbuf; 320 struct list_head rxbuf;
319 struct ath_descdma rxdma; 321 struct ath_descdma rxdma;
320 struct ath_rx_edma rx_edma[ATH9K_RX_QUEUE_MAX]; 322 struct ath_rx_edma rx_edma[ATH9K_RX_QUEUE_MAX];
@@ -350,6 +352,9 @@ struct ath_chanctx {
350 bool active; 352 bool active;
351 bool assigned; 353 bool assigned;
352 bool switch_after_beacon; 354 bool switch_after_beacon;
355
356 short nvifs;
357 unsigned int rxfilter;
353}; 358};
354 359
355enum ath_chanctx_event { 360enum ath_chanctx_event {
@@ -376,6 +381,9 @@ enum ath_chanctx_state {
376struct ath_chanctx_sched { 381struct ath_chanctx_sched {
377 bool beacon_pending; 382 bool beacon_pending;
378 bool offchannel_pending; 383 bool offchannel_pending;
384 bool wait_switch;
385 bool force_noa_update;
386 bool extend_absence;
379 enum ath_chanctx_state state; 387 enum ath_chanctx_state state;
380 u8 beacon_miss; 388 u8 beacon_miss;
381 389
@@ -449,7 +457,7 @@ void ath9k_p2p_ps_timer(void *priv);
449void ath9k_chanctx_wake_queues(struct ath_softc *sc); 457void ath9k_chanctx_wake_queues(struct ath_softc *sc);
450void ath_chanctx_check_active(struct ath_softc *sc, struct ath_chanctx *ctx); 458void ath_chanctx_check_active(struct ath_softc *sc, struct ath_chanctx *ctx);
451 459
452void ath_chanctx_beacon_recv_ev(struct ath_softc *sc, u32 ts, 460void ath_chanctx_beacon_recv_ev(struct ath_softc *sc,
453 enum ath_chanctx_event ev); 461 enum ath_chanctx_event ev);
454void ath_chanctx_beacon_sent_ev(struct ath_softc *sc, 462void ath_chanctx_beacon_sent_ev(struct ath_softc *sc,
455 enum ath_chanctx_event ev); 463 enum ath_chanctx_event ev);
@@ -478,7 +486,7 @@ static inline void ath9k_offchannel_init(struct ath_softc *sc)
478static inline void ath9k_deinit_channel_context(struct ath_softc *sc) 486static inline void ath9k_deinit_channel_context(struct ath_softc *sc)
479{ 487{
480} 488}
481static inline void ath_chanctx_beacon_recv_ev(struct ath_softc *sc, u32 ts, 489static inline void ath_chanctx_beacon_recv_ev(struct ath_softc *sc,
482 enum ath_chanctx_event ev) 490 enum ath_chanctx_event ev)
483{ 491{
484} 492}
@@ -527,7 +535,7 @@ static inline void ath_chanctx_check_active(struct ath_softc *sc,
527#endif /* CONFIG_ATH9K_CHANNEL_CONTEXT */ 535#endif /* CONFIG_ATH9K_CHANNEL_CONTEXT */
528 536
529int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan); 537int ath_reset_internal(struct ath_softc *sc, struct ath9k_channel *hchan);
530int ath_startrecv(struct ath_softc *sc); 538void ath_startrecv(struct ath_softc *sc);
531bool ath_stoprecv(struct ath_softc *sc); 539bool ath_stoprecv(struct ath_softc *sc);
532u32 ath_calcrxfilter(struct ath_softc *sc); 540u32 ath_calcrxfilter(struct ath_softc *sc);
533int ath_rx_init(struct ath_softc *sc, int nbufs); 541int ath_rx_init(struct ath_softc *sc, int nbufs);
@@ -572,6 +580,8 @@ void ath9k_release_buffered_frames(struct ieee80211_hw *hw,
572/* VIFs */ 580/* VIFs */
573/********/ 581/********/
574 582
583#define P2P_DEFAULT_CTWIN 10
584
575struct ath_vif { 585struct ath_vif {
576 struct list_head list; 586 struct list_head list;
577 587
@@ -590,8 +600,10 @@ struct ath_vif {
590 u32 offchannel_start; 600 u32 offchannel_start;
591 u32 offchannel_duration; 601 u32 offchannel_duration;
592 602
593 u32 periodic_noa_start; 603 /* These are used for both periodic and one-shot */
594 u32 periodic_noa_duration; 604 u32 noa_start;
605 u32 noa_duration;
606 bool periodic_noa;
595}; 607};
596 608
597struct ath9k_vif_iter_data { 609struct ath9k_vif_iter_data {
@@ -960,7 +972,6 @@ struct ath_softc {
960 bool ps_enabled; 972 bool ps_enabled;
961 bool ps_idle; 973 bool ps_idle;
962 short nbcnvifs; 974 short nbcnvifs;
963 short nvifs;
964 unsigned long ps_usecount; 975 unsigned long ps_usecount;
965 976
966 struct ath_rx rx; 977 struct ath_rx rx;
diff --git a/drivers/net/wireless/ath/ath9k/beacon.c b/drivers/net/wireless/ath/ath9k/beacon.c
index b2f56d8b9043..a6af855ef6ed 100644
--- a/drivers/net/wireless/ath/ath9k/beacon.c
+++ b/drivers/net/wireless/ath/ath9k/beacon.c
@@ -183,7 +183,7 @@ static struct ath_buf *ath9k_beacon_generate(struct ieee80211_hw *hw,
183 spin_unlock_bh(&cabq->axq_lock); 183 spin_unlock_bh(&cabq->axq_lock);
184 184
185 if (skb && cabq_depth) { 185 if (skb && cabq_depth) {
186 if (sc->nvifs > 1) { 186 if (sc->cur_chan->nvifs > 1) {
187 ath_dbg(common, BEACON, 187 ath_dbg(common, BEACON,
188 "Flushing previous cabq traffic\n"); 188 "Flushing previous cabq traffic\n");
189 ath_draintxq(sc, cabq); 189 ath_draintxq(sc, cabq);
@@ -514,6 +514,18 @@ static bool ath9k_allow_beacon_config(struct ath_softc *sc,
514 struct ieee80211_vif *vif) 514 struct ieee80211_vif *vif)
515{ 515{
516 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 516 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
517 struct ath_vif *avp = (void *)vif->drv_priv;
518
519 if (ath9k_is_chanctx_enabled()) {
520 /*
521 * If the VIF is not present in the current channel context,
522 * then we can't do the usual opmode checks. Allow the
523 * beacon config for the VIF to be updated in this case and
524 * return immediately.
525 */
526 if (sc->cur_chan != avp->chanctx)
527 return true;
528 }
517 529
518 if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) { 530 if (sc->sc_ah->opmode == NL80211_IFTYPE_AP) {
519 if ((vif->type != NL80211_IFTYPE_AP) || 531 if ((vif->type != NL80211_IFTYPE_AP) ||
diff --git a/drivers/net/wireless/ath/ath9k/channel.c b/drivers/net/wireless/ath/ath9k/channel.c
index 409f912a67c7..77c99eb55834 100644
--- a/drivers/net/wireless/ath/ath9k/channel.c
+++ b/drivers/net/wireless/ath/ath9k/channel.c
@@ -83,8 +83,6 @@ static int ath_set_channel(struct ath_softc *sc)
83 if (hw->conf.radar_enabled) { 83 if (hw->conf.radar_enabled) {
84 u32 rxfilter; 84 u32 rxfilter;
85 85
86 /* set HW specific DFS configuration */
87 ath9k_hw_set_radar_params(ah);
88 rxfilter = ath9k_hw_getrxfilter(ah); 86 rxfilter = ath9k_hw_getrxfilter(ah);
89 rxfilter |= ATH9K_RX_FILTER_PHYRADAR | 87 rxfilter |= ATH9K_RX_FILTER_PHYRADAR |
90 ATH9K_RX_FILTER_PHYERR; 88 ATH9K_RX_FILTER_PHYERR;
@@ -262,6 +260,9 @@ static void ath_chanctx_adjust_tbtt_delta(struct ath_softc *sc)
262 cur = sc->cur_chan; 260 cur = sc->cur_chan;
263 prev = ath_chanctx_get_next(sc, cur); 261 prev = ath_chanctx_get_next(sc, cur);
264 262
263 if (!prev->switch_after_beacon)
264 return;
265
265 getrawmonotonic(&ts); 266 getrawmonotonic(&ts);
266 cur_tsf = (u32) cur->tsf_val + 267 cur_tsf = (u32) cur->tsf_val +
267 ath9k_hw_get_tsf_offset(&cur->tsf_ts, &ts); 268 ath9k_hw_get_tsf_offset(&cur->tsf_ts, &ts);
@@ -310,7 +311,6 @@ void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif,
310 struct ath_chanctx *ctx; 311 struct ath_chanctx *ctx;
311 u32 tsf_time; 312 u32 tsf_time;
312 u32 beacon_int; 313 u32 beacon_int;
313 bool noa_changed = false;
314 314
315 if (vif) 315 if (vif)
316 avp = (struct ath_vif *) vif->drv_priv; 316 avp = (struct ath_vif *) vif->drv_priv;
@@ -333,7 +333,7 @@ void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif,
333 break; 333 break;
334 } 334 }
335 335
336 if (sc->sched.offchannel_pending) { 336 if (sc->sched.offchannel_pending && !sc->sched.wait_switch) {
337 sc->sched.offchannel_pending = false; 337 sc->sched.offchannel_pending = false;
338 sc->next_chan = &sc->offchannel.chan; 338 sc->next_chan = &sc->offchannel.chan;
339 sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_BEACON; 339 sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_BEACON;
@@ -372,44 +372,91 @@ void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif,
372 sc->sched.switch_start_time = tsf_time; 372 sc->sched.switch_start_time = tsf_time;
373 sc->cur_chan->last_beacon = sc->sched.next_tbtt; 373 sc->cur_chan->last_beacon = sc->sched.next_tbtt;
374 374
375 /* Prevent wrap-around issues */ 375 /*
376 if (avp->periodic_noa_duration && 376 * If an offchannel switch is scheduled to happen after
377 tsf_time - avp->periodic_noa_start > BIT(30)) 377 * a beacon transmission, update the NoA with one-shot
378 avp->periodic_noa_duration = 0; 378 * values and increment the index.
379 379 */
380 if (ctx->active && !avp->periodic_noa_duration) { 380 if (sc->next_chan == &sc->offchannel.chan) {
381 avp->periodic_noa_start = tsf_time; 381 avp->noa_index++;
382 avp->periodic_noa_duration = 382 avp->offchannel_start = tsf_time;
383 TU_TO_USEC(cur_conf->beacon_interval) / 2 - 383 avp->offchannel_duration = sc->sched.offchannel_duration;
384 sc->sched.channel_switch_time; 384
385 noa_changed = true; 385 ath_dbg(common, CHAN_CTX,
386 } else if (!ctx->active && avp->periodic_noa_duration) { 386 "offchannel noa_duration: %d, noa_start: %d, noa_index: %d\n",
387 avp->periodic_noa_duration = 0; 387 avp->offchannel_duration,
388 noa_changed = true; 388 avp->offchannel_start,
389 avp->noa_index);
390
391 /*
392 * When multiple contexts are active, the NoA
393 * has to be recalculated and advertised after
394 * an offchannel operation.
395 */
396 if (ctx->active && avp->noa_duration)
397 avp->noa_duration = 0;
398
399 break;
400 }
401
402 /*
403 * Clear the extend_absence flag if it had been
404 * set during the previous beacon transmission,
405 * since we need to revert to the normal NoA
406 * schedule.
407 */
408 if (ctx->active && sc->sched.extend_absence) {
409 avp->noa_duration = 0;
410 sc->sched.extend_absence = false;
389 } 411 }
390 412
391 /* If at least two consecutive beacons were missed on the STA 413 /* If at least two consecutive beacons were missed on the STA
392 * chanctx, stay on the STA channel for one extra beacon period, 414 * chanctx, stay on the STA channel for one extra beacon period,
393 * to resync the timer properly. 415 * to resync the timer properly.
394 */ 416 */
395 if (ctx->active && sc->sched.beacon_miss >= 2) 417 if (ctx->active && sc->sched.beacon_miss >= 2) {
396 sc->sched.offchannel_duration = 3 * beacon_int / 2; 418 avp->noa_duration = 0;
397 419 sc->sched.extend_absence = true;
398 if (sc->sched.offchannel_duration) {
399 noa_changed = true;
400 avp->offchannel_start = tsf_time;
401 avp->offchannel_duration =
402 sc->sched.offchannel_duration;
403 } 420 }
404 421
405 if (noa_changed) 422 /* Prevent wrap-around issues */
423 if (avp->noa_duration && tsf_time - avp->noa_start > BIT(30))
424 avp->noa_duration = 0;
425
426 /*
427 * If multiple contexts are active, start periodic
428 * NoA and increment the index for the first
429 * announcement.
430 */
431 if (ctx->active &&
432 (!avp->noa_duration || sc->sched.force_noa_update)) {
406 avp->noa_index++; 433 avp->noa_index++;
434 avp->noa_start = tsf_time;
435
436 if (sc->sched.extend_absence)
437 avp->noa_duration = (3 * beacon_int / 2) +
438 sc->sched.channel_switch_time;
439 else
440 avp->noa_duration =
441 TU_TO_USEC(cur_conf->beacon_interval) / 2 +
442 sc->sched.channel_switch_time;
443
444 if (test_bit(ATH_OP_SCANNING, &common->op_flags) ||
445 sc->sched.extend_absence)
446 avp->periodic_noa = false;
447 else
448 avp->periodic_noa = true;
407 449
408 ath_dbg(common, CHAN_CTX, 450 ath_dbg(common, CHAN_CTX,
409 "periodic_noa_duration: %d, periodic_noa_start: %d, noa_index: %d\n", 451 "noa_duration: %d, noa_start: %d, noa_index: %d, periodic: %d\n",
410 avp->periodic_noa_duration, 452 avp->noa_duration,
411 avp->periodic_noa_start, 453 avp->noa_start,
412 avp->noa_index); 454 avp->noa_index,
455 avp->periodic_noa);
456 }
457
458 if (ctx->active && sc->sched.force_noa_update)
459 sc->sched.force_noa_update = false;
413 460
414 break; 461 break;
415 case ATH_CHANCTX_EVENT_BEACON_SENT: 462 case ATH_CHANCTX_EVENT_BEACON_SENT:
@@ -490,9 +537,11 @@ void ath_chanctx_event(struct ath_softc *sc, struct ieee80211_vif *vif,
490 "Move chanctx state to WAIT_FOR_TIMER (event SWITCH)\n"); 537 "Move chanctx state to WAIT_FOR_TIMER (event SWITCH)\n");
491 538
492 sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_TIMER; 539 sc->sched.state = ATH_CHANCTX_STATE_WAIT_FOR_TIMER;
540 sc->sched.wait_switch = false;
493 541
494 tsf_time = TU_TO_USEC(cur_conf->beacon_interval) / 2; 542 tsf_time = TU_TO_USEC(cur_conf->beacon_interval) / 2;
495 if (sc->sched.beacon_miss >= 2) { 543
544 if (sc->sched.extend_absence) {
496 sc->sched.beacon_miss = 0; 545 sc->sched.beacon_miss = 0;
497 tsf_time *= 3; 546 tsf_time *= 3;
498 } 547 }
@@ -560,10 +609,9 @@ void ath_chanctx_beacon_sent_ev(struct ath_softc *sc,
560 ath_chanctx_event(sc, NULL, ev); 609 ath_chanctx_event(sc, NULL, ev);
561} 610}
562 611
563void ath_chanctx_beacon_recv_ev(struct ath_softc *sc, u32 ts, 612void ath_chanctx_beacon_recv_ev(struct ath_softc *sc,
564 enum ath_chanctx_event ev) 613 enum ath_chanctx_event ev)
565{ 614{
566 sc->sched.next_tbtt = ts;
567 ath_chanctx_event(sc, NULL, ev); 615 ath_chanctx_event(sc, NULL, ev);
568} 616}
569 617
@@ -587,8 +635,18 @@ static void ath_chanctx_switch(struct ath_softc *sc, struct ath_chanctx *ctx,
587 635
588 if (test_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags) && 636 if (test_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags) &&
589 (sc->cur_chan != ctx) && (ctx == &sc->offchannel.chan)) { 637 (sc->cur_chan != ctx) && (ctx == &sc->offchannel.chan)) {
638 if (chandef)
639 ctx->chandef = *chandef;
640
590 sc->sched.offchannel_pending = true; 641 sc->sched.offchannel_pending = true;
642 sc->sched.wait_switch = true;
643 sc->sched.offchannel_duration =
644 jiffies_to_usecs(sc->offchannel.duration) +
645 sc->sched.channel_switch_time;
646
591 spin_unlock_bh(&sc->chan_lock); 647 spin_unlock_bh(&sc->chan_lock);
648 ath_dbg(common, CHAN_CTX,
649 "Set offchannel_pending to true\n");
592 return; 650 return;
593 } 651 }
594 652
@@ -601,7 +659,7 @@ static void ath_chanctx_switch(struct ath_softc *sc, struct ath_chanctx *ctx,
601 659
602 if (sc->next_chan == &sc->offchannel.chan) { 660 if (sc->next_chan == &sc->offchannel.chan) {
603 sc->sched.offchannel_duration = 661 sc->sched.offchannel_duration =
604 TU_TO_USEC(sc->offchannel.duration) + 662 jiffies_to_usecs(sc->offchannel.duration) +
605 sc->sched.channel_switch_time; 663 sc->sched.channel_switch_time;
606 664
607 if (chandef) { 665 if (chandef) {
@@ -688,7 +746,8 @@ void ath_offchannel_next(struct ath_softc *sc)
688 } else if (sc->offchannel.roc_vif) { 746 } else if (sc->offchannel.roc_vif) {
689 vif = sc->offchannel.roc_vif; 747 vif = sc->offchannel.roc_vif;
690 sc->offchannel.chan.txpower = vif->bss_conf.txpower; 748 sc->offchannel.chan.txpower = vif->bss_conf.txpower;
691 sc->offchannel.duration = sc->offchannel.roc_duration; 749 sc->offchannel.duration =
750 msecs_to_jiffies(sc->offchannel.roc_duration);
692 sc->offchannel.state = ATH_OFFCHANNEL_ROC_START; 751 sc->offchannel.state = ATH_OFFCHANNEL_ROC_START;
693 ath_chanctx_offchan_switch(sc, sc->offchannel.roc_chan); 752 ath_chanctx_offchan_switch(sc, sc->offchannel.roc_chan);
694 } else { 753 } else {
@@ -724,6 +783,10 @@ void ath_scan_complete(struct ath_softc *sc, bool abort)
724 sc->offchannel.state = ATH_OFFCHANNEL_IDLE; 783 sc->offchannel.state = ATH_OFFCHANNEL_IDLE;
725 ieee80211_scan_completed(sc->hw, abort); 784 ieee80211_scan_completed(sc->hw, abort);
726 clear_bit(ATH_OP_SCANNING, &common->op_flags); 785 clear_bit(ATH_OP_SCANNING, &common->op_flags);
786 spin_lock_bh(&sc->chan_lock);
787 if (test_bit(ATH_OP_MULTI_CHANNEL, &common->op_flags))
788 sc->sched.force_noa_update = true;
789 spin_unlock_bh(&sc->chan_lock);
727 ath_offchannel_next(sc); 790 ath_offchannel_next(sc);
728 ath9k_ps_restore(sc); 791 ath9k_ps_restore(sc);
729} 792}
@@ -959,8 +1022,8 @@ static void ath_offchannel_channel_change(struct ath_softc *sc)
959 break; 1022 break;
960 1023
961 sc->offchannel.state = ATH_OFFCHANNEL_ROC_WAIT; 1024 sc->offchannel.state = ATH_OFFCHANNEL_ROC_WAIT;
962 mod_timer(&sc->offchannel.timer, jiffies + 1025 mod_timer(&sc->offchannel.timer,
963 msecs_to_jiffies(sc->offchannel.duration)); 1026 jiffies + sc->offchannel.duration);
964 ieee80211_ready_on_channel(sc->hw); 1027 ieee80211_ready_on_channel(sc->hw);
965 break; 1028 break;
966 case ATH_OFFCHANNEL_ROC_DONE: 1029 case ATH_OFFCHANNEL_ROC_DONE:
@@ -1022,7 +1085,10 @@ void ath_chanctx_set_next(struct ath_softc *sc, bool force)
1022 sc->cur_chan = sc->next_chan; 1085 sc->cur_chan = sc->next_chan;
1023 sc->cur_chan->stopped = false; 1086 sc->cur_chan->stopped = false;
1024 sc->next_chan = NULL; 1087 sc->next_chan = NULL;
1025 sc->sched.offchannel_duration = 0; 1088
1089 if (!sc->sched.offchannel_pending)
1090 sc->sched.offchannel_duration = 0;
1091
1026 if (sc->sched.state != ATH_CHANCTX_STATE_FORCE_ACTIVE) 1092 if (sc->sched.state != ATH_CHANCTX_STATE_FORCE_ACTIVE)
1027 sc->sched.state = ATH_CHANCTX_STATE_IDLE; 1093 sc->sched.state = ATH_CHANCTX_STATE_IDLE;
1028 1094
@@ -1165,6 +1231,30 @@ static void ath9k_update_p2p_ps(struct ath_softc *sc, struct ieee80211_vif *vif)
1165 ath9k_update_p2p_ps_timer(sc, avp); 1231 ath9k_update_p2p_ps_timer(sc, avp);
1166} 1232}
1167 1233
1234static u8 ath9k_get_ctwin(struct ath_softc *sc, struct ath_vif *avp)
1235{
1236 struct ath_beacon_config *cur_conf = &sc->cur_chan->beacon;
1237 u8 switch_time, ctwin;
1238
1239 /*
1240 * Channel switch in multi-channel mode is deferred
1241 * by a quarter beacon interval when handling
1242 * ATH_CHANCTX_EVENT_BEACON_PREPARE, so the P2P-GO
1243 * interface is guaranteed to be discoverable
1244 * for that duration after a TBTT.
1245 */
1246 switch_time = cur_conf->beacon_interval / 4;
1247
1248 ctwin = avp->vif->bss_conf.p2p_noa_attr.oppps_ctwindow;
1249 if (ctwin && (ctwin < switch_time))
1250 return ctwin;
1251
1252 if (switch_time < P2P_DEFAULT_CTWIN)
1253 return 0;
1254
1255 return P2P_DEFAULT_CTWIN;
1256}
1257
1168void ath9k_beacon_add_noa(struct ath_softc *sc, struct ath_vif *avp, 1258void ath9k_beacon_add_noa(struct ath_softc *sc, struct ath_vif *avp,
1169 struct sk_buff *skb) 1259 struct sk_buff *skb)
1170{ 1260{
@@ -1182,10 +1272,10 @@ void ath9k_beacon_add_noa(struct ath_softc *sc, struct ath_vif *avp,
1182 int noa_len, noa_desc, i = 0; 1272 int noa_len, noa_desc, i = 0;
1183 u8 *hdr; 1273 u8 *hdr;
1184 1274
1185 if (!avp->offchannel_duration && !avp->periodic_noa_duration) 1275 if (!avp->offchannel_duration && !avp->noa_duration)
1186 return; 1276 return;
1187 1277
1188 noa_desc = !!avp->offchannel_duration + !!avp->periodic_noa_duration; 1278 noa_desc = !!avp->offchannel_duration + !!avp->noa_duration;
1189 noa_len = 2 + sizeof(struct ieee80211_p2p_noa_desc) * noa_desc; 1279 noa_len = 2 + sizeof(struct ieee80211_p2p_noa_desc) * noa_desc;
1190 1280
1191 hdr = skb_put(skb, sizeof(noa_ie_hdr)); 1281 hdr = skb_put(skb, sizeof(noa_ie_hdr));
@@ -1197,13 +1287,19 @@ void ath9k_beacon_add_noa(struct ath_softc *sc, struct ath_vif *avp,
1197 memset(noa, 0, noa_len); 1287 memset(noa, 0, noa_len);
1198 1288
1199 noa->index = avp->noa_index; 1289 noa->index = avp->noa_index;
1200 if (avp->periodic_noa_duration) { 1290 noa->oppps_ctwindow = ath9k_get_ctwin(sc, avp);
1201 u32 interval = TU_TO_USEC(sc->cur_chan->beacon.beacon_interval); 1291
1292 if (avp->noa_duration) {
1293 if (avp->periodic_noa) {
1294 u32 interval = TU_TO_USEC(sc->cur_chan->beacon.beacon_interval);
1295 noa->desc[i].count = 255;
1296 noa->desc[i].interval = cpu_to_le32(interval);
1297 } else {
1298 noa->desc[i].count = 1;
1299 }
1202 1300
1203 noa->desc[i].count = 255; 1301 noa->desc[i].start_time = cpu_to_le32(avp->noa_start);
1204 noa->desc[i].start_time = cpu_to_le32(avp->periodic_noa_start); 1302 noa->desc[i].duration = cpu_to_le32(avp->noa_duration);
1205 noa->desc[i].duration = cpu_to_le32(avp->periodic_noa_duration);
1206 noa->desc[i].interval = cpu_to_le32(interval);
1207 i++; 1303 i++;
1208 } 1304 }
1209 1305
diff --git a/drivers/net/wireless/ath/ath9k/debug.c b/drivers/net/wireless/ath/ath9k/debug.c
index d2279365be6f..46f20a309b5f 100644
--- a/drivers/net/wireless/ath/ath9k/debug.c
+++ b/drivers/net/wireless/ath/ath9k/debug.c
@@ -838,7 +838,7 @@ static ssize_t read_file_misc(struct file *file, char __user *user_buf,
838 iter_data.nmeshes, iter_data.nwds); 838 iter_data.nmeshes, iter_data.nwds);
839 len += scnprintf(buf + len, sizeof(buf) - len, 839 len += scnprintf(buf + len, sizeof(buf) - len,
840 " ADHOC: %i TOTAL: %hi BEACON-VIF: %hi\n", 840 " ADHOC: %i TOTAL: %hi BEACON-VIF: %hi\n",
841 iter_data.nadhocs, sc->nvifs, sc->nbcnvifs); 841 iter_data.nadhocs, sc->cur_chan->nvifs, sc->nbcnvifs);
842 } 842 }
843 843
844 if (len > sizeof(buf)) 844 if (len > sizeof(buf))
@@ -1169,6 +1169,29 @@ static const struct file_operations fops_btcoex = {
1169}; 1169};
1170#endif 1170#endif
1171 1171
1172#ifdef CONFIG_ATH9K_DYNACK
1173static ssize_t read_file_ackto(struct file *file, char __user *user_buf,
1174 size_t count, loff_t *ppos)
1175{
1176 struct ath_softc *sc = file->private_data;
1177 struct ath_hw *ah = sc->sc_ah;
1178 char buf[32];
1179 unsigned int len;
1180
1181 len = sprintf(buf, "%u %c\n", ah->dynack.ackto,
1182 (ah->dynack.enabled) ? 'A' : 'S');
1183
1184 return simple_read_from_buffer(user_buf, count, ppos, buf, len);
1185}
1186
1187static const struct file_operations fops_ackto = {
1188 .read = read_file_ackto,
1189 .open = simple_open,
1190 .owner = THIS_MODULE,
1191 .llseek = default_llseek,
1192};
1193#endif
1194
1172/* Ethtool support for get-stats */ 1195/* Ethtool support for get-stats */
1173 1196
1174#define AMKSTR(nm) #nm "_BE", #nm "_BK", #nm "_VI", #nm "_VO" 1197#define AMKSTR(nm) #nm "_BE", #nm "_BK", #nm "_VI", #nm "_VO"
@@ -1374,5 +1397,10 @@ int ath9k_init_debug(struct ath_hw *ah)
1374 &fops_btcoex); 1397 &fops_btcoex);
1375#endif 1398#endif
1376 1399
1400#ifdef CONFIG_ATH9K_DYNACK
1401 debugfs_create_file("ack_to", S_IRUSR | S_IWUSR, sc->debug.debugfs_phy,
1402 sc, &fops_ackto);
1403#endif
1404
1377 return 0; 1405 return 0;
1378} 1406}
diff --git a/drivers/net/wireless/ath/ath9k/dynack.c b/drivers/net/wireless/ath/ath9k/dynack.c
new file mode 100644
index 000000000000..6ae8e0bc9e1f
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/dynack.c
@@ -0,0 +1,351 @@
1/*
2 * Copyright (c) 2014, Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
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 "ath9k.h"
18#include "hw.h"
19#include "dynack.h"
20
21#define COMPUTE_TO (5 * HZ)
22#define LATEACK_DELAY (10 * HZ)
23#define LATEACK_TO 256
24#define MAX_DELAY 300
25#define EWMA_LEVEL 96
26#define EWMA_DIV 128
27
28/**
29 * ath_dynack_ewma - EWMA (Exponentially Weighted Moving Average) calculation
30 *
31 */
32static inline u32 ath_dynack_ewma(u32 old, u32 new)
33{
34 return (new * (EWMA_DIV - EWMA_LEVEL) + old * EWMA_LEVEL) / EWMA_DIV;
35}
36
37/**
38 * ath_dynack_get_sifs - get sifs time based on phy used
39 * @ah: ath hw
40 * @phy: phy used
41 *
42 */
43static inline u32 ath_dynack_get_sifs(struct ath_hw *ah, int phy)
44{
45 u32 sifs = CCK_SIFS_TIME;
46
47 if (phy == WLAN_RC_PHY_OFDM) {
48 if (IS_CHAN_QUARTER_RATE(ah->curchan))
49 sifs = OFDM_SIFS_TIME_QUARTER;
50 else if (IS_CHAN_HALF_RATE(ah->curchan))
51 sifs = OFDM_SIFS_TIME_HALF;
52 else
53 sifs = OFDM_SIFS_TIME;
54 }
55 return sifs;
56}
57
58/**
59 * ath_dynack_bssidmask - filter out ACK frames based on BSSID mask
60 * @ah: ath hw
61 * @mac: receiver address
62 */
63static inline bool ath_dynack_bssidmask(struct ath_hw *ah, const u8 *mac)
64{
65 int i;
66 struct ath_common *common = ath9k_hw_common(ah);
67
68 for (i = 0; i < ETH_ALEN; i++) {
69 if ((common->macaddr[i] & common->bssidmask[i]) !=
70 (mac[i] & common->bssidmask[i]))
71 return false;
72 }
73
74 return true;
75}
76
77/**
78 * ath_dynack_compute_ackto - compute ACK timeout as the maximum STA timeout
79 * @ah: ath hw
80 *
81 * should be called while holding qlock
82 */
83static void ath_dynack_compute_ackto(struct ath_hw *ah)
84{
85 struct ath_node *an;
86 u32 to = 0;
87 struct ath_dynack *da = &ah->dynack;
88 struct ath_common *common = ath9k_hw_common(ah);
89
90 list_for_each_entry(an, &da->nodes, list)
91 if (an->ackto > to)
92 to = an->ackto;
93
94 if (to && da->ackto != to) {
95 u32 slottime;
96
97 slottime = (to - 3) / 2;
98 da->ackto = to;
99 ath_dbg(common, DYNACK, "ACK timeout %u slottime %u\n",
100 da->ackto, slottime);
101 ath9k_hw_setslottime(ah, slottime);
102 ath9k_hw_set_ack_timeout(ah, da->ackto);
103 ath9k_hw_set_cts_timeout(ah, da->ackto);
104 }
105}
106
107/**
108 * ath_dynack_compute_to - compute STA ACK timeout
109 * @ah: ath hw
110 *
111 * should be called while holding qlock
112 */
113static void ath_dynack_compute_to(struct ath_hw *ah)
114{
115 u32 ackto, ack_ts;
116 u8 *dst, *src;
117 struct ieee80211_sta *sta;
118 struct ath_node *an;
119 struct ts_info *st_ts;
120 struct ath_dynack *da = &ah->dynack;
121
122 rcu_read_lock();
123
124 while (da->st_rbf.h_rb != da->st_rbf.t_rb &&
125 da->ack_rbf.h_rb != da->ack_rbf.t_rb) {
126 ack_ts = da->ack_rbf.tstamp[da->ack_rbf.h_rb];
127 st_ts = &da->st_rbf.ts[da->st_rbf.h_rb];
128 dst = da->st_rbf.addr[da->st_rbf.h_rb].h_dest;
129 src = da->st_rbf.addr[da->st_rbf.h_rb].h_src;
130
131 ath_dbg(ath9k_hw_common(ah), DYNACK,
132 "ack_ts %u st_ts %u st_dur %u [%u-%u]\n",
133 ack_ts, st_ts->tstamp, st_ts->dur,
134 da->ack_rbf.h_rb, da->st_rbf.h_rb);
135
136 if (ack_ts > st_ts->tstamp + st_ts->dur) {
137 ackto = ack_ts - st_ts->tstamp - st_ts->dur;
138
139 if (ackto < MAX_DELAY) {
140 sta = ieee80211_find_sta_by_ifaddr(ah->hw, dst,
141 src);
142 if (sta) {
143 an = (struct ath_node *)sta->drv_priv;
144 an->ackto = ath_dynack_ewma(an->ackto,
145 ackto);
146 ath_dbg(ath9k_hw_common(ah), DYNACK,
147 "%pM to %u\n", dst, an->ackto);
148 if (time_is_before_jiffies(da->lto)) {
149 ath_dynack_compute_ackto(ah);
150 da->lto = jiffies + COMPUTE_TO;
151 }
152 }
153 INCR(da->ack_rbf.h_rb, ATH_DYN_BUF);
154 }
155 INCR(da->st_rbf.h_rb, ATH_DYN_BUF);
156 } else {
157 INCR(da->ack_rbf.h_rb, ATH_DYN_BUF);
158 }
159 }
160
161 rcu_read_unlock();
162}
163
164/**
165 * ath_dynack_sample_tx_ts - status timestamp sampling method
166 * @ah: ath hw
167 * @skb: socket buffer
168 * @ts: tx status info
169 *
170 */
171void ath_dynack_sample_tx_ts(struct ath_hw *ah, struct sk_buff *skb,
172 struct ath_tx_status *ts)
173{
174 u8 ridx;
175 struct ieee80211_hdr *hdr;
176 struct ath_dynack *da = &ah->dynack;
177 struct ath_common *common = ath9k_hw_common(ah);
178 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
179
180 if ((info->flags & IEEE80211_TX_CTL_NO_ACK) || !da->enabled)
181 return;
182
183 spin_lock_bh(&da->qlock);
184
185 hdr = (struct ieee80211_hdr *)skb->data;
186
187 /* late ACK */
188 if (ts->ts_status & ATH9K_TXERR_XRETRY) {
189 if (ieee80211_is_assoc_req(hdr->frame_control) ||
190 ieee80211_is_assoc_resp(hdr->frame_control)) {
191 ath_dbg(common, DYNACK, "late ack\n");
192 ath9k_hw_setslottime(ah, (LATEACK_TO - 3) / 2);
193 ath9k_hw_set_ack_timeout(ah, LATEACK_TO);
194 ath9k_hw_set_cts_timeout(ah, LATEACK_TO);
195 da->lto = jiffies + LATEACK_DELAY;
196 }
197
198 spin_unlock_bh(&da->qlock);
199 return;
200 }
201
202 ridx = ts->ts_rateindex;
203
204 da->st_rbf.ts[da->st_rbf.t_rb].tstamp = ts->ts_tstamp;
205 da->st_rbf.ts[da->st_rbf.t_rb].dur = ts->duration[ts->ts_rateindex];
206 ether_addr_copy(da->st_rbf.addr[da->st_rbf.t_rb].h_dest, hdr->addr1);
207 ether_addr_copy(da->st_rbf.addr[da->st_rbf.t_rb].h_src, hdr->addr2);
208
209 if (!(info->status.rates[ridx].flags & IEEE80211_TX_RC_MCS)) {
210 u32 phy, sifs;
211 const struct ieee80211_rate *rate;
212 struct ieee80211_tx_rate *rates = info->status.rates;
213
214 rate = &common->sbands[info->band].bitrates[rates[ridx].idx];
215 if (info->band == IEEE80211_BAND_2GHZ &&
216 !(rate->flags & IEEE80211_RATE_ERP_G))
217 phy = WLAN_RC_PHY_CCK;
218 else
219 phy = WLAN_RC_PHY_OFDM;
220
221 sifs = ath_dynack_get_sifs(ah, phy);
222 da->st_rbf.ts[da->st_rbf.t_rb].dur -= sifs;
223 }
224
225 ath_dbg(common, DYNACK, "{%pM} tx sample %u [dur %u][h %u-t %u]\n",
226 hdr->addr1, da->st_rbf.ts[da->st_rbf.t_rb].tstamp,
227 da->st_rbf.ts[da->st_rbf.t_rb].dur, da->st_rbf.h_rb,
228 (da->st_rbf.t_rb + 1) % ATH_DYN_BUF);
229
230 INCR(da->st_rbf.t_rb, ATH_DYN_BUF);
231 if (da->st_rbf.t_rb == da->st_rbf.h_rb)
232 INCR(da->st_rbf.h_rb, ATH_DYN_BUF);
233
234 ath_dynack_compute_to(ah);
235
236 spin_unlock_bh(&da->qlock);
237}
238EXPORT_SYMBOL(ath_dynack_sample_tx_ts);
239
240/**
241 * ath_dynack_sample_ack_ts - ACK timestamp sampling method
242 * @ah: ath hw
243 * @skb: socket buffer
244 * @ts: rx timestamp
245 *
246 */
247void ath_dynack_sample_ack_ts(struct ath_hw *ah, struct sk_buff *skb,
248 u32 ts)
249{
250 struct ath_dynack *da = &ah->dynack;
251 struct ath_common *common = ath9k_hw_common(ah);
252 struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
253
254 if (!ath_dynack_bssidmask(ah, hdr->addr1) || !da->enabled)
255 return;
256
257 spin_lock_bh(&da->qlock);
258 da->ack_rbf.tstamp[da->ack_rbf.t_rb] = ts;
259
260 ath_dbg(common, DYNACK, "rx sample %u [h %u-t %u]\n",
261 da->ack_rbf.tstamp[da->ack_rbf.t_rb],
262 da->ack_rbf.h_rb, (da->ack_rbf.t_rb + 1) % ATH_DYN_BUF);
263
264 INCR(da->ack_rbf.t_rb, ATH_DYN_BUF);
265 if (da->ack_rbf.t_rb == da->ack_rbf.h_rb)
266 INCR(da->ack_rbf.h_rb, ATH_DYN_BUF);
267
268 ath_dynack_compute_to(ah);
269
270 spin_unlock_bh(&da->qlock);
271}
272EXPORT_SYMBOL(ath_dynack_sample_ack_ts);
273
274/**
275 * ath_dynack_node_init - init ath_node related info
276 * @ah: ath hw
277 * @an: ath node
278 *
279 */
280void ath_dynack_node_init(struct ath_hw *ah, struct ath_node *an)
281{
282 /* ackto = slottime + sifs + air delay */
283 u32 ackto = ATH9K_SLOT_TIME_9 + 16 + 64;
284 struct ath_dynack *da = &ah->dynack;
285
286 an->ackto = ackto;
287
288 spin_lock(&da->qlock);
289 list_add_tail(&an->list, &da->nodes);
290 spin_unlock(&da->qlock);
291}
292EXPORT_SYMBOL(ath_dynack_node_init);
293
294/**
295 * ath_dynack_node_deinit - deinit ath_node related info
296 * @ah: ath hw
297 * @an: ath node
298 *
299 */
300void ath_dynack_node_deinit(struct ath_hw *ah, struct ath_node *an)
301{
302 struct ath_dynack *da = &ah->dynack;
303
304 spin_lock(&da->qlock);
305 list_del(&an->list);
306 spin_unlock(&da->qlock);
307}
308EXPORT_SYMBOL(ath_dynack_node_deinit);
309
310/**
311 * ath_dynack_reset - reset dynack processing
312 * @ah: ath hw
313 *
314 */
315void ath_dynack_reset(struct ath_hw *ah)
316{
317 /* ackto = slottime + sifs + air delay */
318 u32 ackto = ATH9K_SLOT_TIME_9 + 16 + 64;
319 struct ath_dynack *da = &ah->dynack;
320
321 da->lto = jiffies;
322 da->ackto = ackto;
323
324 da->st_rbf.t_rb = 0;
325 da->st_rbf.h_rb = 0;
326 da->ack_rbf.t_rb = 0;
327 da->ack_rbf.h_rb = 0;
328
329 /* init acktimeout */
330 ath9k_hw_setslottime(ah, (ackto - 3) / 2);
331 ath9k_hw_set_ack_timeout(ah, ackto);
332 ath9k_hw_set_cts_timeout(ah, ackto);
333}
334EXPORT_SYMBOL(ath_dynack_reset);
335
336/**
337 * ath_dynack_init - init dynack data structure
338 * @ah: ath hw
339 *
340 */
341void ath_dynack_init(struct ath_hw *ah)
342{
343 struct ath_dynack *da = &ah->dynack;
344
345 memset(da, 0, sizeof(struct ath_dynack));
346
347 spin_lock_init(&da->qlock);
348 INIT_LIST_HEAD(&da->nodes);
349
350 ah->hw->wiphy->features |= NL80211_FEATURE_ACKTO_ESTIMATION;
351}
diff --git a/drivers/net/wireless/ath/ath9k/dynack.h b/drivers/net/wireless/ath/ath9k/dynack.h
new file mode 100644
index 000000000000..6d7bef976742
--- /dev/null
+++ b/drivers/net/wireless/ath/ath9k/dynack.h
@@ -0,0 +1,103 @@
1/*
2 * Copyright (c) 2014, Lorenzo Bianconi <lorenzo.bianconi83@gmail.com>
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 DYNACK_H
18#define DYNACK_H
19
20#define ATH_DYN_BUF 64
21
22struct ath_hw;
23struct ath_node;
24
25/**
26 * struct ath_dyn_rxbuf - ACK frame ring buffer
27 * @h_rb: ring buffer head
28 * @t_rb: ring buffer tail
29 * @tstamp: ACK RX timestamp buffer
30 */
31struct ath_dyn_rxbuf {
32 u16 h_rb, t_rb;
33 u32 tstamp[ATH_DYN_BUF];
34};
35
36struct ts_info {
37 u32 tstamp;
38 u32 dur;
39};
40
41struct haddr_pair {
42 u8 h_dest[ETH_ALEN];
43 u8 h_src[ETH_ALEN];
44};
45
46/**
47 * struct ath_dyn_txbuf - tx frame ring buffer
48 * @h_rb: ring buffer head
49 * @t_rb: ring buffer tail
50 * @addr: dest/src address pair for a given TX frame
51 * @ts: TX frame timestamp buffer
52 */
53struct ath_dyn_txbuf {
54 u16 h_rb, t_rb;
55 struct haddr_pair addr[ATH_DYN_BUF];
56 struct ts_info ts[ATH_DYN_BUF];
57};
58
59/**
60 * struct ath_dynack - dynack processing info
61 * @enabled: enable dyn ack processing
62 * @ackto: current ACK timeout
63 * @lto: last ACK timeout computation
64 * @nodes: ath_node linked list
65 * @qlock: ts queue spinlock
66 * @ack_rbf: ACK ts ring buffer
67 * @st_rbf: status ts ring buffer
68 */
69struct ath_dynack {
70 bool enabled;
71 int ackto;
72 unsigned long lto;
73
74 struct list_head nodes;
75
76 /* protect timestamp queue access */
77 spinlock_t qlock;
78 struct ath_dyn_rxbuf ack_rbf;
79 struct ath_dyn_txbuf st_rbf;
80};
81
82#if defined(CONFIG_ATH9K_DYNACK)
83void ath_dynack_reset(struct ath_hw *ah);
84void ath_dynack_node_init(struct ath_hw *ah, struct ath_node *an);
85void ath_dynack_node_deinit(struct ath_hw *ah, struct ath_node *an);
86void ath_dynack_init(struct ath_hw *ah);
87void ath_dynack_sample_ack_ts(struct ath_hw *ah, struct sk_buff *skb, u32 ts);
88void ath_dynack_sample_tx_ts(struct ath_hw *ah, struct sk_buff *skb,
89 struct ath_tx_status *ts);
90#else
91static inline void ath_dynack_init(struct ath_hw *ah) {}
92static inline void ath_dynack_node_init(struct ath_hw *ah,
93 struct ath_node *an) {}
94static inline void ath_dynack_node_deinit(struct ath_hw *ah,
95 struct ath_node *an) {}
96static inline void ath_dynack_sample_ack_ts(struct ath_hw *ah,
97 struct sk_buff *skb, u32 ts) {}
98static inline void ath_dynack_sample_tx_ts(struct ath_hw *ah,
99 struct sk_buff *skb,
100 struct ath_tx_status *ts) {}
101#endif
102
103#endif /* DYNACK_H */
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index 5627917c5ff7..994fff1ff519 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -1722,7 +1722,7 @@ static int ath9k_htc_set_rts_threshold(struct ieee80211_hw *hw, u32 value)
1722} 1722}
1723 1723
1724static void ath9k_htc_set_coverage_class(struct ieee80211_hw *hw, 1724static void ath9k_htc_set_coverage_class(struct ieee80211_hw *hw,
1725 u8 coverage_class) 1725 s16 coverage_class)
1726{ 1726{
1727 struct ath9k_htc_priv *priv = hw->priv; 1727 struct ath9k_htc_priv *priv = hw->priv;
1728 1728
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index 69bbea1184d2..3aed729e4d5e 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -647,6 +647,8 @@ int ath9k_hw_init(struct ath_hw *ah)
647 return ret; 647 return ret;
648 } 648 }
649 649
650 ath_dynack_init(ah);
651
650 return 0; 652 return 0;
651} 653}
652EXPORT_SYMBOL(ath9k_hw_init); 654EXPORT_SYMBOL(ath9k_hw_init);
@@ -935,21 +937,21 @@ static void ath9k_hw_set_sifs_time(struct ath_hw *ah, u32 us)
935 REG_WRITE(ah, AR_D_GBL_IFS_SIFS, val); 937 REG_WRITE(ah, AR_D_GBL_IFS_SIFS, val);
936} 938}
937 939
938static void ath9k_hw_setslottime(struct ath_hw *ah, u32 us) 940void ath9k_hw_setslottime(struct ath_hw *ah, u32 us)
939{ 941{
940 u32 val = ath9k_hw_mac_to_clks(ah, us); 942 u32 val = ath9k_hw_mac_to_clks(ah, us);
941 val = min(val, (u32) 0xFFFF); 943 val = min(val, (u32) 0xFFFF);
942 REG_WRITE(ah, AR_D_GBL_IFS_SLOT, val); 944 REG_WRITE(ah, AR_D_GBL_IFS_SLOT, val);
943} 945}
944 946
945static void ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us) 947void ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us)
946{ 948{
947 u32 val = ath9k_hw_mac_to_clks(ah, us); 949 u32 val = ath9k_hw_mac_to_clks(ah, us);
948 val = min(val, (u32) MS(0xFFFFFFFF, AR_TIME_OUT_ACK)); 950 val = min(val, (u32) MS(0xFFFFFFFF, AR_TIME_OUT_ACK));
949 REG_RMW_FIELD(ah, AR_TIME_OUT, AR_TIME_OUT_ACK, val); 951 REG_RMW_FIELD(ah, AR_TIME_OUT, AR_TIME_OUT_ACK, val);
950} 952}
951 953
952static void ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us) 954void ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us)
953{ 955{
954 u32 val = ath9k_hw_mac_to_clks(ah, us); 956 u32 val = ath9k_hw_mac_to_clks(ah, us);
955 val = min(val, (u32) MS(0xFFFFFFFF, AR_TIME_OUT_CTS)); 957 val = min(val, (u32) MS(0xFFFFFFFF, AR_TIME_OUT_CTS));
@@ -1053,6 +1055,14 @@ void ath9k_hw_init_global_settings(struct ath_hw *ah)
1053 ctstimeout += 48 - sifstime - ah->slottime; 1055 ctstimeout += 48 - sifstime - ah->slottime;
1054 } 1056 }
1055 1057
1058 if (ah->dynack.enabled) {
1059 acktimeout = ah->dynack.ackto;
1060 ctstimeout = acktimeout;
1061 slottime = (acktimeout - 3) / 2;
1062 } else {
1063 ah->dynack.ackto = acktimeout;
1064 }
1065
1056 ath9k_hw_set_sifs_time(ah, sifstime); 1066 ath9k_hw_set_sifs_time(ah, sifstime);
1057 ath9k_hw_setslottime(ah, slottime); 1067 ath9k_hw_setslottime(ah, slottime);
1058 ath9k_hw_set_ack_timeout(ah, acktimeout); 1068 ath9k_hw_set_ack_timeout(ah, acktimeout);
@@ -1954,6 +1964,12 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
1954 if (AR_SREV_9565(ah) && common->bt_ant_diversity) 1964 if (AR_SREV_9565(ah) && common->bt_ant_diversity)
1955 REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON); 1965 REG_SET_BIT(ah, AR_BTCOEX_WL_LNADIV, AR_BTCOEX_WL_LNADIV_FORCE_ON);
1956 1966
1967 if (ah->hw->conf.radar_enabled) {
1968 /* set HW specific DFS configuration */
1969 ah->radar_conf.ext_channel = IS_CHAN_HT40(chan);
1970 ath9k_hw_set_radar_params(ah);
1971 }
1972
1957 return 0; 1973 return 0;
1958} 1974}
1959EXPORT_SYMBOL(ath9k_hw_reset); 1975EXPORT_SYMBOL(ath9k_hw_reset);
diff --git a/drivers/net/wireless/ath/ath9k/hw.h b/drivers/net/wireless/ath/ath9k/hw.h
index 51b4ebe04c04..b9eef3362fbb 100644
--- a/drivers/net/wireless/ath/ath9k/hw.h
+++ b/drivers/net/wireless/ath/ath9k/hw.h
@@ -29,6 +29,7 @@
29#include "reg.h" 29#include "reg.h"
30#include "phy.h" 30#include "phy.h"
31#include "btcoex.h" 31#include "btcoex.h"
32#include "dynack.h"
32 33
33#include "../regd.h" 34#include "../regd.h"
34 35
@@ -924,6 +925,8 @@ struct ath_hw {
924 int (*external_reset)(void); 925 int (*external_reset)(void);
925 926
926 const struct firmware *eeprom_blob; 927 const struct firmware *eeprom_blob;
928
929 struct ath_dynack dynack;
927}; 930};
928 931
929struct ath_bus_ops { 932struct ath_bus_ops {
@@ -1080,6 +1083,10 @@ void ar9002_hw_load_ani_reg(struct ath_hw *ah, struct ath9k_channel *chan);
1080void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning); 1083void ath9k_ani_reset(struct ath_hw *ah, bool is_scanning);
1081void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan); 1084void ath9k_hw_ani_monitor(struct ath_hw *ah, struct ath9k_channel *chan);
1082 1085
1086void ath9k_hw_set_ack_timeout(struct ath_hw *ah, u32 us);
1087void ath9k_hw_set_cts_timeout(struct ath_hw *ah, u32 us);
1088void ath9k_hw_setslottime(struct ath_hw *ah, u32 us);
1089
1083#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT 1090#ifdef CONFIG_ATH9K_BTCOEX_SUPPORT
1084static inline bool ath9k_hw_btcoex_is_enabled(struct ath_hw *ah) 1091static inline bool ath9k_hw_btcoex_is_enabled(struct ath_hw *ah)
1085{ 1092{
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c
index ca10a8b3a381..156a944134dc 100644
--- a/drivers/net/wireless/ath/ath9k/init.c
+++ b/drivers/net/wireless/ath/ath9k/init.c
@@ -763,8 +763,9 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
763 if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || ath9k_modparam_nohwcrypt) 763 if (AR_SREV_9160_10_OR_LATER(sc->sc_ah) || ath9k_modparam_nohwcrypt)
764 hw->flags |= IEEE80211_HW_MFP_CAPABLE; 764 hw->flags |= IEEE80211_HW_MFP_CAPABLE;
765 765
766 hw->wiphy->features |= (NL80211_FEATURE_ACTIVE_MONITOR | 766 hw->wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR |
767 NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE); 767 NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE |
768 NL80211_FEATURE_P2P_GO_CTWIN;
768 769
769 if (!config_enabled(CONFIG_ATH9K_TX99)) { 770 if (!config_enabled(CONFIG_ATH9K_TX99)) {
770 hw->wiphy->interface_modes = 771 hw->wiphy->interface_modes =
@@ -810,7 +811,7 @@ static void ath9k_set_hw_capab(struct ath_softc *sc, struct ieee80211_hw *hw)
810 /* allow 4 queues per channel context + 811 /* allow 4 queues per channel context +
811 * 1 cab queue + 1 offchannel tx queue 812 * 1 cab queue + 1 offchannel tx queue
812 */ 813 */
813 hw->queues = 10; 814 hw->queues = ATH9K_NUM_TX_QUEUES;
814 /* last queue for offchannel */ 815 /* last queue for offchannel */
815 hw->offchannel_tx_hw_queue = hw->queues - 1; 816 hw->offchannel_tx_hw_queue = hw->queues - 1;
816 hw->max_rates = 4; 817 hw->max_rates = 4;
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h
index 6c56cafa5ca4..cd05a7791073 100644
--- a/drivers/net/wireless/ath/ath9k/mac.h
+++ b/drivers/net/wireless/ath/ath9k/mac.h
@@ -121,6 +121,7 @@ struct ath_tx_status {
121 u32 evm0; 121 u32 evm0;
122 u32 evm1; 122 u32 evm1;
123 u32 evm2; 123 u32 evm2;
124 u32 duration[4];
124}; 125};
125 126
126struct ath_rx_status { 127struct ath_rx_status {
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c
index 4a8c9b80b08e..fbf23ac61c97 100644
--- a/drivers/net/wireless/ath/ath9k/main.c
+++ b/drivers/net/wireless/ath/ath9k/main.c
@@ -224,16 +224,11 @@ static bool ath_complete_reset(struct ath_softc *sc, bool start)
224 struct ath_common *common = ath9k_hw_common(ah); 224 struct ath_common *common = ath9k_hw_common(ah);
225 unsigned long flags; 225 unsigned long flags;
226 226
227 if (ath_startrecv(sc) != 0) { 227 ath9k_calculate_summary_state(sc, sc->cur_chan);
228 ath_err(common, "Unable to restart recv logic\n"); 228 ath_startrecv(sc);
229 return false;
230 }
231
232 ath9k_cmn_update_txpow(ah, sc->curtxpow, 229 ath9k_cmn_update_txpow(ah, sc->curtxpow,
233 sc->cur_chan->txpower, &sc->curtxpow); 230 sc->cur_chan->txpower, &sc->curtxpow);
234
235 clear_bit(ATH_OP_HW_RESET, &common->op_flags); 231 clear_bit(ATH_OP_HW_RESET, &common->op_flags);
236 ath9k_calculate_summary_state(sc, sc->cur_chan);
237 232
238 if (!sc->cur_chan->offchannel && start) { 233 if (!sc->cur_chan->offchannel && start) {
239 /* restore per chanctx TSF timer */ 234 /* restore per chanctx TSF timer */
@@ -350,12 +345,16 @@ static void ath_node_attach(struct ath_softc *sc, struct ieee80211_sta *sta,
350 memset(&an->key_idx, 0, sizeof(an->key_idx)); 345 memset(&an->key_idx, 0, sizeof(an->key_idx));
351 346
352 ath_tx_node_init(sc, an); 347 ath_tx_node_init(sc, an);
348
349 ath_dynack_node_init(sc->sc_ah, an);
353} 350}
354 351
355static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta) 352static void ath_node_detach(struct ath_softc *sc, struct ieee80211_sta *sta)
356{ 353{
357 struct ath_node *an = (struct ath_node *)sta->drv_priv; 354 struct ath_node *an = (struct ath_node *)sta->drv_priv;
358 ath_tx_node_cleanup(sc, an); 355 ath_tx_node_cleanup(sc, an);
356
357 ath_dynack_node_deinit(sc->sc_ah, an);
359} 358}
360 359
361void ath9k_tasklet(unsigned long data) 360void ath9k_tasklet(unsigned long data)
@@ -916,8 +915,6 @@ static void ath9k_vif_iter(struct ath9k_vif_iter_data *iter_data,
916 switch (vif->type) { 915 switch (vif->type) {
917 case NL80211_IFTYPE_AP: 916 case NL80211_IFTYPE_AP:
918 iter_data->naps++; 917 iter_data->naps++;
919 if (vif->bss_conf.enable_beacon)
920 iter_data->beacons = true;
921 break; 918 break;
922 case NL80211_IFTYPE_STATION: 919 case NL80211_IFTYPE_STATION:
923 iter_data->nstations++; 920 iter_data->nstations++;
@@ -960,21 +957,6 @@ void ath9k_calculate_iter_data(struct ath_softc *sc,
960 957
961 list_for_each_entry(avp, &ctx->vifs, list) 958 list_for_each_entry(avp, &ctx->vifs, list)
962 ath9k_vif_iter(iter_data, avp->vif->addr, avp->vif); 959 ath9k_vif_iter(iter_data, avp->vif->addr, avp->vif);
963
964#ifdef CONFIG_ATH9K_CHANNEL_CONTEXT
965 if (ctx == &sc->offchannel.chan) {
966 struct ieee80211_vif *vif;
967
968 if (sc->offchannel.state < ATH_OFFCHANNEL_ROC_START)
969 vif = sc->offchannel.scan_vif;
970 else
971 vif = sc->offchannel.roc_vif;
972
973 if (vif)
974 ath9k_vif_iter(iter_data, vif->addr, vif);
975 iter_data->beacons = false;
976 }
977#endif
978} 960}
979 961
980static void ath9k_set_assoc_state(struct ath_softc *sc, 962static void ath9k_set_assoc_state(struct ath_softc *sc,
@@ -985,13 +967,6 @@ static void ath9k_set_assoc_state(struct ath_softc *sc,
985 unsigned long flags; 967 unsigned long flags;
986 968
987 set_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags); 969 set_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags);
988 /* Set the AID, BSSID and do beacon-sync only when
989 * the HW opmode is STATION.
990 *
991 * But the primary bit is set above in any case.
992 */
993 if (sc->sc_ah->opmode != NL80211_IFTYPE_STATION)
994 return;
995 970
996 ether_addr_copy(common->curbssid, bss_conf->bssid); 971 ether_addr_copy(common->curbssid, bss_conf->bssid);
997 common->curaid = bss_conf->aid; 972 common->curaid = bss_conf->aid;
@@ -1014,6 +989,43 @@ static void ath9k_set_assoc_state(struct ath_softc *sc,
1014 vif->addr, common->curbssid); 989 vif->addr, common->curbssid);
1015} 990}
1016 991
992#ifdef CONFIG_ATH9K_CHANNEL_CONTEXT
993static void ath9k_set_offchannel_state(struct ath_softc *sc)
994{
995 struct ath_hw *ah = sc->sc_ah;
996 struct ath_common *common = ath9k_hw_common(ah);
997 struct ieee80211_vif *vif = NULL;
998
999 ath9k_ps_wakeup(sc);
1000
1001 if (sc->offchannel.state < ATH_OFFCHANNEL_ROC_START)
1002 vif = sc->offchannel.scan_vif;
1003 else
1004 vif = sc->offchannel.roc_vif;
1005
1006 if (WARN_ON(!vif))
1007 goto exit;
1008
1009 eth_zero_addr(common->curbssid);
1010 eth_broadcast_addr(common->bssidmask);
1011 ether_addr_copy(common->macaddr, vif->addr);
1012 common->curaid = 0;
1013 ah->opmode = vif->type;
1014 ah->imask &= ~ATH9K_INT_SWBA;
1015 ah->imask &= ~ATH9K_INT_TSFOOR;
1016 ah->slottime = ATH9K_SLOT_TIME_9;
1017
1018 ath_hw_setbssidmask(common);
1019 ath9k_hw_setopmode(ah);
1020 ath9k_hw_write_associd(sc->sc_ah);
1021 ath9k_hw_set_interrupts(ah);
1022 ath9k_hw_init_global_settings(ah);
1023
1024exit:
1025 ath9k_ps_restore(sc);
1026}
1027#endif
1028
1017/* Called with sc->mutex held. */ 1029/* Called with sc->mutex held. */
1018void ath9k_calculate_summary_state(struct ath_softc *sc, 1030void ath9k_calculate_summary_state(struct ath_softc *sc,
1019 struct ath_chanctx *ctx) 1031 struct ath_chanctx *ctx)
@@ -1021,12 +1033,18 @@ void ath9k_calculate_summary_state(struct ath_softc *sc,
1021 struct ath_hw *ah = sc->sc_ah; 1033 struct ath_hw *ah = sc->sc_ah;
1022 struct ath_common *common = ath9k_hw_common(ah); 1034 struct ath_common *common = ath9k_hw_common(ah);
1023 struct ath9k_vif_iter_data iter_data; 1035 struct ath9k_vif_iter_data iter_data;
1036 struct ath_beacon_config *cur_conf;
1024 1037
1025 ath_chanctx_check_active(sc, ctx); 1038 ath_chanctx_check_active(sc, ctx);
1026 1039
1027 if (ctx != sc->cur_chan) 1040 if (ctx != sc->cur_chan)
1028 return; 1041 return;
1029 1042
1043#ifdef CONFIG_ATH9K_CHANNEL_CONTEXT
1044 if (ctx == &sc->offchannel.chan)
1045 return ath9k_set_offchannel_state(sc);
1046#endif
1047
1030 ath9k_ps_wakeup(sc); 1048 ath9k_ps_wakeup(sc);
1031 ath9k_calculate_iter_data(sc, ctx, &iter_data); 1049 ath9k_calculate_iter_data(sc, ctx, &iter_data);
1032 1050
@@ -1037,8 +1055,11 @@ void ath9k_calculate_summary_state(struct ath_softc *sc,
1037 ath_hw_setbssidmask(common); 1055 ath_hw_setbssidmask(common);
1038 1056
1039 if (iter_data.naps > 0) { 1057 if (iter_data.naps > 0) {
1058 cur_conf = &ctx->beacon;
1040 ath9k_hw_set_tsfadjust(ah, true); 1059 ath9k_hw_set_tsfadjust(ah, true);
1041 ah->opmode = NL80211_IFTYPE_AP; 1060 ah->opmode = NL80211_IFTYPE_AP;
1061 if (cur_conf->enable_beacon)
1062 iter_data.beacons = true;
1042 } else { 1063 } else {
1043 ath9k_hw_set_tsfadjust(ah, false); 1064 ath9k_hw_set_tsfadjust(ah, false);
1044 1065
@@ -1067,13 +1088,11 @@ void ath9k_calculate_summary_state(struct ath_softc *sc,
1067 if (ah->opmode == NL80211_IFTYPE_STATION) { 1088 if (ah->opmode == NL80211_IFTYPE_STATION) {
1068 bool changed = (iter_data.primary_sta != ctx->primary_sta); 1089 bool changed = (iter_data.primary_sta != ctx->primary_sta);
1069 1090
1070 iter_data.beacons = true;
1071 if (iter_data.primary_sta) { 1091 if (iter_data.primary_sta) {
1092 iter_data.beacons = true;
1072 ath9k_set_assoc_state(sc, iter_data.primary_sta, 1093 ath9k_set_assoc_state(sc, iter_data.primary_sta,
1073 changed); 1094 changed);
1074 if (!ctx->primary_sta || 1095 ctx->primary_sta = iter_data.primary_sta;
1075 !ctx->primary_sta->bss_conf.assoc)
1076 ctx->primary_sta = iter_data.primary_sta;
1077 } else { 1096 } else {
1078 ctx->primary_sta = NULL; 1097 ctx->primary_sta = NULL;
1079 memset(common->curbssid, 0, ETH_ALEN); 1098 memset(common->curbssid, 0, ETH_ALEN);
@@ -1102,11 +1121,23 @@ void ath9k_calculate_summary_state(struct ath_softc *sc,
1102 else 1121 else
1103 clear_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags); 1122 clear_bit(ATH_OP_PRIM_STA_VIF, &common->op_flags);
1104 1123
1105 ctx->primary_sta = iter_data.primary_sta;
1106
1107 ath9k_ps_restore(sc); 1124 ath9k_ps_restore(sc);
1108} 1125}
1109 1126
1127static void ath9k_assign_hw_queues(struct ieee80211_hw *hw,
1128 struct ieee80211_vif *vif)
1129{
1130 int i;
1131
1132 for (i = 0; i < IEEE80211_NUM_ACS; i++)
1133 vif->hw_queue[i] = i;
1134
1135 if (vif->type == NL80211_IFTYPE_AP)
1136 vif->cab_queue = hw->queues - 2;
1137 else
1138 vif->cab_queue = IEEE80211_INVAL_HW_QUEUE;
1139}
1140
1110static int ath9k_add_interface(struct ieee80211_hw *hw, 1141static int ath9k_add_interface(struct ieee80211_hw *hw,
1111 struct ieee80211_vif *vif) 1142 struct ieee80211_vif *vif)
1112{ 1143{
@@ -1115,12 +1146,11 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
1115 struct ath_common *common = ath9k_hw_common(ah); 1146 struct ath_common *common = ath9k_hw_common(ah);
1116 struct ath_vif *avp = (void *)vif->drv_priv; 1147 struct ath_vif *avp = (void *)vif->drv_priv;
1117 struct ath_node *an = &avp->mcast_node; 1148 struct ath_node *an = &avp->mcast_node;
1118 int i;
1119 1149
1120 mutex_lock(&sc->mutex); 1150 mutex_lock(&sc->mutex);
1121 1151
1122 if (config_enabled(CONFIG_ATH9K_TX99)) { 1152 if (config_enabled(CONFIG_ATH9K_TX99)) {
1123 if (sc->nvifs >= 1) { 1153 if (sc->cur_chan->nvifs >= 1) {
1124 mutex_unlock(&sc->mutex); 1154 mutex_unlock(&sc->mutex);
1125 return -EOPNOTSUPP; 1155 return -EOPNOTSUPP;
1126 } 1156 }
@@ -1128,7 +1158,7 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
1128 } 1158 }
1129 1159
1130 ath_dbg(common, CONFIG, "Attach a VIF of type: %d\n", vif->type); 1160 ath_dbg(common, CONFIG, "Attach a VIF of type: %d\n", vif->type);
1131 sc->nvifs++; 1161 sc->cur_chan->nvifs++;
1132 1162
1133 if (ath9k_uses_beacons(vif->type)) 1163 if (ath9k_uses_beacons(vif->type))
1134 ath9k_beacon_assign_slot(sc, vif); 1164 ath9k_beacon_assign_slot(sc, vif);
@@ -1138,12 +1168,8 @@ static int ath9k_add_interface(struct ieee80211_hw *hw,
1138 avp->chanctx = sc->cur_chan; 1168 avp->chanctx = sc->cur_chan;
1139 list_add_tail(&avp->list, &avp->chanctx->vifs); 1169 list_add_tail(&avp->list, &avp->chanctx->vifs);
1140 } 1170 }
1141 for (i = 0; i < IEEE80211_NUM_ACS; i++) 1171
1142 vif->hw_queue[i] = i; 1172 ath9k_assign_hw_queues(hw, vif);
1143 if (vif->type == NL80211_IFTYPE_AP)
1144 vif->cab_queue = hw->queues - 2;
1145 else
1146 vif->cab_queue = IEEE80211_INVAL_HW_QUEUE;
1147 1173
1148 an->sc = sc; 1174 an->sc = sc;
1149 an->sta = NULL; 1175 an->sta = NULL;
@@ -1163,7 +1189,6 @@ static int ath9k_change_interface(struct ieee80211_hw *hw,
1163 struct ath_softc *sc = hw->priv; 1189 struct ath_softc *sc = hw->priv;
1164 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 1190 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
1165 struct ath_vif *avp = (void *)vif->drv_priv; 1191 struct ath_vif *avp = (void *)vif->drv_priv;
1166 int i;
1167 1192
1168 mutex_lock(&sc->mutex); 1193 mutex_lock(&sc->mutex);
1169 1194
@@ -1183,14 +1208,7 @@ static int ath9k_change_interface(struct ieee80211_hw *hw,
1183 if (ath9k_uses_beacons(vif->type)) 1208 if (ath9k_uses_beacons(vif->type))
1184 ath9k_beacon_assign_slot(sc, vif); 1209 ath9k_beacon_assign_slot(sc, vif);
1185 1210
1186 for (i = 0; i < IEEE80211_NUM_ACS; i++) 1211 ath9k_assign_hw_queues(hw, vif);
1187 vif->hw_queue[i] = i;
1188
1189 if (vif->type == NL80211_IFTYPE_AP)
1190 vif->cab_queue = hw->queues - 2;
1191 else
1192 vif->cab_queue = IEEE80211_INVAL_HW_QUEUE;
1193
1194 ath9k_calculate_summary_state(sc, avp->chanctx); 1212 ath9k_calculate_summary_state(sc, avp->chanctx);
1195 1213
1196 mutex_unlock(&sc->mutex); 1214 mutex_unlock(&sc->mutex);
@@ -1210,7 +1228,7 @@ static void ath9k_remove_interface(struct ieee80211_hw *hw,
1210 1228
1211 ath9k_p2p_remove_vif(sc, vif); 1229 ath9k_p2p_remove_vif(sc, vif);
1212 1230
1213 sc->nvifs--; 1231 sc->cur_chan->nvifs--;
1214 sc->tx99_vif = NULL; 1232 sc->tx99_vif = NULL;
1215 if (!ath9k_is_chanctx_enabled()) 1233 if (!ath9k_is_chanctx_enabled())
1216 list_del(&avp->list); 1234 list_del(&avp->list);
@@ -1430,7 +1448,10 @@ static void ath9k_configure_filter(struct ieee80211_hw *hw,
1430 changed_flags &= SUPPORTED_FILTERS; 1448 changed_flags &= SUPPORTED_FILTERS;
1431 *total_flags &= SUPPORTED_FILTERS; 1449 *total_flags &= SUPPORTED_FILTERS;
1432 1450
1433 sc->rx.rxfilter = *total_flags; 1451 spin_lock_bh(&sc->chan_lock);
1452 sc->cur_chan->rxfilter = *total_flags;
1453 spin_unlock_bh(&sc->chan_lock);
1454
1434 ath9k_ps_wakeup(sc); 1455 ath9k_ps_wakeup(sc);
1435 rfilt = ath_calcrxfilter(sc); 1456 rfilt = ath_calcrxfilter(sc);
1436 ath9k_hw_setrxfilter(sc->sc_ah, rfilt); 1457 ath9k_hw_setrxfilter(sc->sc_ah, rfilt);
@@ -1695,9 +1716,9 @@ static void ath9k_bss_info_changed(struct ieee80211_hw *hw,
1695 if ((changed & BSS_CHANGED_BEACON_ENABLED) || 1716 if ((changed & BSS_CHANGED_BEACON_ENABLED) ||
1696 (changed & BSS_CHANGED_BEACON_INT) || 1717 (changed & BSS_CHANGED_BEACON_INT) ||
1697 (changed & BSS_CHANGED_BEACON_INFO)) { 1718 (changed & BSS_CHANGED_BEACON_INFO)) {
1719 ath9k_beacon_config(sc, vif, changed);
1698 if (changed & BSS_CHANGED_BEACON_ENABLED) 1720 if (changed & BSS_CHANGED_BEACON_ENABLED)
1699 ath9k_calculate_summary_state(sc, avp->chanctx); 1721 ath9k_calculate_summary_state(sc, avp->chanctx);
1700 ath9k_beacon_config(sc, vif, changed);
1701 } 1722 }
1702 1723
1703 if ((avp->chanctx == sc->cur_chan) && 1724 if ((avp->chanctx == sc->cur_chan) &&
@@ -1859,7 +1880,22 @@ static int ath9k_get_survey(struct ieee80211_hw *hw, int idx,
1859 return 0; 1880 return 0;
1860} 1881}
1861 1882
1862static void ath9k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class) 1883static void ath9k_enable_dynack(struct ath_softc *sc)
1884{
1885#ifdef CONFIG_ATH9K_DYNACK
1886 u32 rfilt;
1887 struct ath_hw *ah = sc->sc_ah;
1888
1889 ath_dynack_reset(ah);
1890
1891 ah->dynack.enabled = true;
1892 rfilt = ath_calcrxfilter(sc);
1893 ath9k_hw_setrxfilter(ah, rfilt);
1894#endif
1895}
1896
1897static void ath9k_set_coverage_class(struct ieee80211_hw *hw,
1898 s16 coverage_class)
1863{ 1899{
1864 struct ath_softc *sc = hw->priv; 1900 struct ath_softc *sc = hw->priv;
1865 struct ath_hw *ah = sc->sc_ah; 1901 struct ath_hw *ah = sc->sc_ah;
@@ -1868,11 +1904,22 @@ static void ath9k_set_coverage_class(struct ieee80211_hw *hw, u8 coverage_class)
1868 return; 1904 return;
1869 1905
1870 mutex_lock(&sc->mutex); 1906 mutex_lock(&sc->mutex);
1871 ah->coverage_class = coverage_class;
1872 1907
1873 ath9k_ps_wakeup(sc); 1908 if (coverage_class >= 0) {
1874 ath9k_hw_init_global_settings(ah); 1909 ah->coverage_class = coverage_class;
1875 ath9k_ps_restore(sc); 1910 if (ah->dynack.enabled) {
1911 u32 rfilt;
1912
1913 ah->dynack.enabled = false;
1914 rfilt = ath_calcrxfilter(sc);
1915 ath9k_hw_setrxfilter(ah, rfilt);
1916 }
1917 ath9k_ps_wakeup(sc);
1918 ath9k_hw_init_global_settings(ah);
1919 ath9k_ps_restore(sc);
1920 } else if (!ah->dynack.enabled) {
1921 ath9k_enable_dynack(sc);
1922 }
1876 1923
1877 mutex_unlock(&sc->mutex); 1924 mutex_unlock(&sc->mutex);
1878} 1925}
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c
index 2aaf233ee5d6..6914e21816e4 100644
--- a/drivers/net/wireless/ath/ath9k/recv.c
+++ b/drivers/net/wireless/ath/ath9k/recv.c
@@ -387,7 +387,9 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
387 if (sc->hw->conf.radar_enabled) 387 if (sc->hw->conf.radar_enabled)
388 rfilt |= ATH9K_RX_FILTER_PHYRADAR | ATH9K_RX_FILTER_PHYERR; 388 rfilt |= ATH9K_RX_FILTER_PHYRADAR | ATH9K_RX_FILTER_PHYERR;
389 389
390 if (sc->rx.rxfilter & FIF_PROBE_REQ) 390 spin_lock_bh(&sc->chan_lock);
391
392 if (sc->cur_chan->rxfilter & FIF_PROBE_REQ)
391 rfilt |= ATH9K_RX_FILTER_PROBEREQ; 393 rfilt |= ATH9K_RX_FILTER_PROBEREQ;
392 394
393 /* 395 /*
@@ -398,24 +400,25 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
398 if (sc->sc_ah->is_monitoring) 400 if (sc->sc_ah->is_monitoring)
399 rfilt |= ATH9K_RX_FILTER_PROM; 401 rfilt |= ATH9K_RX_FILTER_PROM;
400 402
401 if (sc->rx.rxfilter & FIF_CONTROL) 403 if ((sc->cur_chan->rxfilter & FIF_CONTROL) ||
404 sc->sc_ah->dynack.enabled)
402 rfilt |= ATH9K_RX_FILTER_CONTROL; 405 rfilt |= ATH9K_RX_FILTER_CONTROL;
403 406
404 if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) && 407 if ((sc->sc_ah->opmode == NL80211_IFTYPE_STATION) &&
405 (sc->nvifs <= 1) && 408 (sc->cur_chan->nvifs <= 1) &&
406 !(sc->rx.rxfilter & FIF_BCN_PRBRESP_PROMISC)) 409 !(sc->cur_chan->rxfilter & FIF_BCN_PRBRESP_PROMISC))
407 rfilt |= ATH9K_RX_FILTER_MYBEACON; 410 rfilt |= ATH9K_RX_FILTER_MYBEACON;
408 else 411 else
409 rfilt |= ATH9K_RX_FILTER_BEACON; 412 rfilt |= ATH9K_RX_FILTER_BEACON;
410 413
411 if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) || 414 if ((sc->sc_ah->opmode == NL80211_IFTYPE_AP) ||
412 (sc->rx.rxfilter & FIF_PSPOLL)) 415 (sc->cur_chan->rxfilter & FIF_PSPOLL))
413 rfilt |= ATH9K_RX_FILTER_PSPOLL; 416 rfilt |= ATH9K_RX_FILTER_PSPOLL;
414 417
415 if (conf_is_ht(&sc->hw->conf)) 418 if (sc->cur_chandef.width != NL80211_CHAN_WIDTH_20_NOHT)
416 rfilt |= ATH9K_RX_FILTER_COMP_BAR; 419 rfilt |= ATH9K_RX_FILTER_COMP_BAR;
417 420
418 if (sc->nvifs > 1 || (sc->rx.rxfilter & FIF_OTHER_BSS)) { 421 if (sc->cur_chan->nvifs > 1 || (sc->cur_chan->rxfilter & FIF_OTHER_BSS)) {
419 /* This is needed for older chips */ 422 /* This is needed for older chips */
420 if (sc->sc_ah->hw_version.macVersion <= AR_SREV_VERSION_9160) 423 if (sc->sc_ah->hw_version.macVersion <= AR_SREV_VERSION_9160)
421 rfilt |= ATH9K_RX_FILTER_PROM; 424 rfilt |= ATH9K_RX_FILTER_PROM;
@@ -429,18 +432,20 @@ u32 ath_calcrxfilter(struct ath_softc *sc)
429 test_bit(ATH_OP_SCANNING, &common->op_flags)) 432 test_bit(ATH_OP_SCANNING, &common->op_flags))
430 rfilt |= ATH9K_RX_FILTER_BEACON; 433 rfilt |= ATH9K_RX_FILTER_BEACON;
431 434
435 spin_unlock_bh(&sc->chan_lock);
436
432 return rfilt; 437 return rfilt;
433 438
434} 439}
435 440
436int ath_startrecv(struct ath_softc *sc) 441void ath_startrecv(struct ath_softc *sc)
437{ 442{
438 struct ath_hw *ah = sc->sc_ah; 443 struct ath_hw *ah = sc->sc_ah;
439 struct ath_rxbuf *bf, *tbf; 444 struct ath_rxbuf *bf, *tbf;
440 445
441 if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) { 446 if (ah->caps.hw_caps & ATH9K_HW_CAP_EDMA) {
442 ath_edma_start_recv(sc); 447 ath_edma_start_recv(sc);
443 return 0; 448 return;
444 } 449 }
445 450
446 if (list_empty(&sc->rx.rxbuf)) 451 if (list_empty(&sc->rx.rxbuf))
@@ -463,8 +468,6 @@ int ath_startrecv(struct ath_softc *sc)
463start_recv: 468start_recv:
464 ath_opmode_init(sc); 469 ath_opmode_init(sc);
465 ath9k_hw_startpcureceive(ah, sc->cur_chan->offchannel); 470 ath9k_hw_startpcureceive(ah, sc->cur_chan->offchannel);
466
467 return 0;
468} 471}
469 472
470static void ath_flushrecv(struct ath_softc *sc) 473static void ath_flushrecv(struct ath_softc *sc)
@@ -535,6 +538,7 @@ static bool ath_beacon_dtim_pending_cab(struct sk_buff *skb)
535static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb) 538static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
536{ 539{
537 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 540 struct ath_common *common = ath9k_hw_common(sc->sc_ah);
541 bool skip_beacon = false;
538 542
539 if (skb->len < 24 + 8 + 2 + 2) 543 if (skb->len < 24 + 8 + 2 + 2)
540 return; 544 return;
@@ -545,7 +549,16 @@ static void ath_rx_ps_beacon(struct ath_softc *sc, struct sk_buff *skb)
545 sc->ps_flags &= ~PS_BEACON_SYNC; 549 sc->ps_flags &= ~PS_BEACON_SYNC;
546 ath_dbg(common, PS, 550 ath_dbg(common, PS,
547 "Reconfigure beacon timers based on synchronized timestamp\n"); 551 "Reconfigure beacon timers based on synchronized timestamp\n");
548 if (!(WARN_ON_ONCE(sc->cur_chan->beacon.beacon_interval == 0))) 552
553#ifdef CONFIG_ATH9K_CHANNEL_CONTEXT
554 if (ath9k_is_chanctx_enabled()) {
555 if (sc->cur_chan == &sc->offchannel.chan)
556 skip_beacon = true;
557 }
558#endif
559
560 if (!skip_beacon &&
561 !(WARN_ON_ONCE(sc->cur_chan->beacon.beacon_interval == 0)))
549 ath9k_set_beacon(sc); 562 ath9k_set_beacon(sc);
550 563
551 ath9k_p2p_beacon_sync(sc); 564 ath9k_p2p_beacon_sync(sc);
@@ -867,8 +880,13 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
867 * everything but the rate is checked here, the rate check is done 880 * everything but the rate is checked here, the rate check is done
868 * separately to avoid doing two lookups for a rate for each frame. 881 * separately to avoid doing two lookups for a rate for each frame.
869 */ 882 */
870 if (!ath9k_cmn_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error, sc->rx.rxfilter)) 883 spin_lock_bh(&sc->chan_lock);
884 if (!ath9k_cmn_rx_accept(common, hdr, rx_status, rx_stats, decrypt_error,
885 sc->cur_chan->rxfilter)) {
886 spin_unlock_bh(&sc->chan_lock);
871 return -EINVAL; 887 return -EINVAL;
888 }
889 spin_unlock_bh(&sc->chan_lock);
872 890
873 if (ath_is_mybeacon(common, hdr)) { 891 if (ath_is_mybeacon(common, hdr)) {
874 RX_STAT_INC(rx_beacons); 892 RX_STAT_INC(rx_beacons);
@@ -894,7 +912,7 @@ static int ath9k_rx_skb_preprocess(struct ath_softc *sc,
894 912
895 if (ath9k_is_chanctx_enabled()) { 913 if (ath9k_is_chanctx_enabled()) {
896 if (rx_stats->is_mybeacon) 914 if (rx_stats->is_mybeacon)
897 ath_chanctx_beacon_recv_ev(sc, rx_stats->rs_tstamp, 915 ath_chanctx_beacon_recv_ev(sc,
898 ATH_CHANCTX_EVENT_BEACON_RECEIVED); 916 ATH_CHANCTX_EVENT_BEACON_RECEIVED);
899 } 917 }
900 918
@@ -992,6 +1010,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
992 unsigned long flags; 1010 unsigned long flags;
993 dma_addr_t new_buf_addr; 1011 dma_addr_t new_buf_addr;
994 unsigned int budget = 512; 1012 unsigned int budget = 512;
1013 struct ieee80211_hdr *hdr;
995 1014
996 if (edma) 1015 if (edma)
997 dma_type = DMA_BIDIRECTIONAL; 1016 dma_type = DMA_BIDIRECTIONAL;
@@ -1121,6 +1140,10 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp)
1121 ath9k_apply_ampdu_details(sc, &rs, rxs); 1140 ath9k_apply_ampdu_details(sc, &rs, rxs);
1122 ath_debug_rate_stats(sc, &rs, skb); 1141 ath_debug_rate_stats(sc, &rs, skb);
1123 1142
1143 hdr = (struct ieee80211_hdr *)skb->data;
1144 if (ieee80211_is_ack(hdr->frame_control))
1145 ath_dynack_sample_ack_ts(sc->sc_ah, skb, rs.rs_tstamp);
1146
1124 ieee80211_rx(hw, skb); 1147 ieee80211_rx(hw, skb);
1125 1148
1126requeue_drop_frag: 1149requeue_drop_frag:
diff --git a/drivers/net/wireless/ath/ath9k/tx99.c b/drivers/net/wireless/ath/ath9k/tx99.c
index 23972924c774..8a69d08ec55c 100644
--- a/drivers/net/wireless/ath/ath9k/tx99.c
+++ b/drivers/net/wireless/ath/ath9k/tx99.c
@@ -174,7 +174,7 @@ static ssize_t write_file_tx99(struct file *file, const char __user *user_buf,
174 ssize_t len; 174 ssize_t len;
175 int r; 175 int r;
176 176
177 if (sc->nvifs > 1) 177 if (sc->cur_chan->nvifs > 1)
178 return -EOPNOTSUPP; 178 return -EOPNOTSUPP;
179 179
180 len = min(count, sizeof(buf) - 1); 180 len = min(count, sizeof(buf) - 1);
diff --git a/drivers/net/wireless/ath/ath9k/wow.c b/drivers/net/wireless/ath/ath9k/wow.c
index 33531d9a4d50..5f30e580d942 100644
--- a/drivers/net/wireless/ath/ath9k/wow.c
+++ b/drivers/net/wireless/ath/ath9k/wow.c
@@ -232,7 +232,7 @@ int ath9k_suspend(struct ieee80211_hw *hw,
232 goto fail_wow; 232 goto fail_wow;
233 } 233 }
234 234
235 if (sc->nvifs > 1) { 235 if (sc->cur_chan->nvifs > 1) {
236 ath_dbg(common, WOW, "WoW for multivif is not yet supported\n"); 236 ath_dbg(common, WOW, "WoW for multivif is not yet supported\n");
237 ret = 1; 237 ret = 1;
238 goto fail_wow; 238 goto fail_wow;
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c
index 281986613fb2..93ad31be0ada 100644
--- a/drivers/net/wireless/ath/ath9k/xmit.c
+++ b/drivers/net/wireless/ath/ath9k/xmit.c
@@ -587,6 +587,10 @@ static void ath_tx_complete_aggr(struct ath_softc *sc, struct ath_txq *txq,
587 memcpy(tx_info->control.rates, rates, sizeof(rates)); 587 memcpy(tx_info->control.rates, rates, sizeof(rates));
588 ath_tx_rc_status(sc, bf, ts, nframes, nbad, txok); 588 ath_tx_rc_status(sc, bf, ts, nframes, nbad, txok);
589 rc_update = false; 589 rc_update = false;
590 if (bf == bf->bf_lastbf)
591 ath_dynack_sample_tx_ts(sc->sc_ah,
592 bf->bf_mpdu,
593 ts);
590 } 594 }
591 595
592 ath_tx_complete_buf(sc, bf, txq, &bf_head, ts, 596 ath_tx_complete_buf(sc, bf, txq, &bf_head, ts,
@@ -687,6 +691,7 @@ static void ath_tx_process_buffer(struct ath_softc *sc, struct ath_txq *txq,
687 memcpy(info->control.rates, bf->rates, 691 memcpy(info->control.rates, bf->rates,
688 sizeof(info->control.rates)); 692 sizeof(info->control.rates));
689 ath_tx_rc_status(sc, bf, ts, 1, txok ? 0 : 1, txok); 693 ath_tx_rc_status(sc, bf, ts, 1, txok ? 0 : 1, txok);
694 ath_dynack_sample_tx_ts(sc->sc_ah, bf->bf_mpdu, ts);
690 } 695 }
691 ath_tx_complete_buf(sc, bf, txq, bf_head, ts, txok); 696 ath_tx_complete_buf(sc, bf, txq, bf_head, ts, txok);
692 } else 697 } else
diff --git a/drivers/net/wireless/ath/wil6210/Kconfig b/drivers/net/wireless/ath/wil6210/Kconfig
index ce8c0381825e..481680a3aa55 100644
--- a/drivers/net/wireless/ath/wil6210/Kconfig
+++ b/drivers/net/wireless/ath/wil6210/Kconfig
@@ -39,3 +39,12 @@ config WIL6210_TRACING
39 option if you are interested in debugging the driver. 39 option if you are interested in debugging the driver.
40 40
41 If unsure, say Y to make it easier to debug problems. 41 If unsure, say Y to make it easier to debug problems.
42
43config WIL6210_PLATFORM_MSM
44 bool "wil6210 MSM platform specific support"
45 depends on WIL6210
46 depends on ARCH_MSM
47 default y
48 ---help---
49 Say Y here to enable wil6210 driver support for MSM
50 platform specific features
diff --git a/drivers/net/wireless/ath/wil6210/Makefile b/drivers/net/wireless/ath/wil6210/Makefile
index c7a3465fd02a..a471d74ae409 100644
--- a/drivers/net/wireless/ath/wil6210/Makefile
+++ b/drivers/net/wireless/ath/wil6210/Makefile
@@ -10,7 +10,10 @@ wil6210-y += interrupt.o
10wil6210-y += txrx.o 10wil6210-y += txrx.o
11wil6210-y += debug.o 11wil6210-y += debug.o
12wil6210-y += rx_reorder.o 12wil6210-y += rx_reorder.o
13wil6210-y += fw.o
13wil6210-$(CONFIG_WIL6210_TRACING) += trace.o 14wil6210-$(CONFIG_WIL6210_TRACING) += trace.o
15wil6210-y += wil_platform.o
16wil6210-$(CONFIG_WIL6210_PLATFORM_MSM) += wil_platform_msm.o
14 17
15# for tracing framework to find trace.h 18# for tracing framework to find trace.h
16CFLAGS_trace.o := -I$(src) 19CFLAGS_trace.o := -I$(src)
diff --git a/drivers/net/wireless/ath/wil6210/cfg80211.c b/drivers/net/wireless/ath/wil6210/cfg80211.c
index a00f31881df9..f3a31e8c2535 100644
--- a/drivers/net/wireless/ath/wil6210/cfg80211.c
+++ b/drivers/net/wireless/ath/wil6210/cfg80211.c
@@ -296,6 +296,7 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
296 n = min(request->n_channels, 4U); 296 n = min(request->n_channels, 4U);
297 for (i = 0; i < n; i++) { 297 for (i = 0; i < n; i++) {
298 int ch = request->channels[i]->hw_value; 298 int ch = request->channels[i]->hw_value;
299
299 if (ch == 0) { 300 if (ch == 0) {
300 wil_err(wil, 301 wil_err(wil,
301 "Scan requested for unknown frequency %dMhz\n", 302 "Scan requested for unknown frequency %dMhz\n",
@@ -308,9 +309,23 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
308 request->channels[i]->center_freq); 309 request->channels[i]->center_freq);
309 } 310 }
310 311
312 if (request->ie_len)
313 print_hex_dump_bytes("Scan IE ", DUMP_PREFIX_OFFSET,
314 request->ie, request->ie_len);
315 else
316 wil_dbg_misc(wil, "Scan has no IE's\n");
317
318 rc = wmi_set_ie(wil, WMI_FRAME_PROBE_REQ, request->ie_len,
319 request->ie);
320 if (rc) {
321 wil_err(wil, "Aborting scan, set_ie failed: %d\n", rc);
322 goto out;
323 }
324
311 rc = wmi_send(wil, WMI_START_SCAN_CMDID, &cmd, sizeof(cmd.cmd) + 325 rc = wmi_send(wil, WMI_START_SCAN_CMDID, &cmd, sizeof(cmd.cmd) +
312 cmd.cmd.num_channels * sizeof(cmd.cmd.channel_list[0])); 326 cmd.cmd.num_channels * sizeof(cmd.cmd.channel_list[0]));
313 327
328out:
314 if (rc) { 329 if (rc) {
315 del_timer_sync(&wil->scan_timer); 330 del_timer_sync(&wil->scan_timer);
316 wil->scan_request = NULL; 331 wil->scan_request = NULL;
@@ -319,6 +334,22 @@ static int wil_cfg80211_scan(struct wiphy *wiphy,
319 return rc; 334 return rc;
320} 335}
321 336
337static void wil_print_connect_params(struct wil6210_priv *wil,
338 struct cfg80211_connect_params *sme)
339{
340 wil_info(wil, "Connecting to:\n");
341 if (sme->channel) {
342 wil_info(wil, " Channel: %d freq %d\n",
343 sme->channel->hw_value, sme->channel->center_freq);
344 }
345 if (sme->bssid)
346 wil_info(wil, " BSSID: %pM\n", sme->bssid);
347 if (sme->ssid)
348 print_hex_dump(KERN_INFO, " SSID: ", DUMP_PREFIX_OFFSET,
349 16, 1, sme->ssid, sme->ssid_len, true);
350 wil_info(wil, " Privacy: %s\n", sme->privacy ? "secure" : "open");
351}
352
322static int wil_cfg80211_connect(struct wiphy *wiphy, 353static int wil_cfg80211_connect(struct wiphy *wiphy,
323 struct net_device *ndev, 354 struct net_device *ndev,
324 struct cfg80211_connect_params *sme) 355 struct cfg80211_connect_params *sme)
@@ -335,6 +366,8 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
335 test_bit(wil_status_fwconnected, &wil->status)) 366 test_bit(wil_status_fwconnected, &wil->status))
336 return -EALREADY; 367 return -EALREADY;
337 368
369 wil_print_connect_params(wil, sme);
370
338 bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid, 371 bss = cfg80211_get_bss(wiphy, sme->channel, sme->bssid,
339 sme->ssid, sme->ssid_len, 372 sme->ssid, sme->ssid_len,
340 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS); 373 WLAN_CAPABILITY_ESS, WLAN_CAPABILITY_ESS);
@@ -360,22 +393,22 @@ static int wil_cfg80211_connect(struct wiphy *wiphy,
360 sme->ie_len); 393 sme->ie_len);
361 goto out; 394 goto out;
362 } 395 }
363 /* 396 /* For secure assoc, send WMI_DELETE_CIPHER_KEY_CMD */
364 * For secure assoc, send:
365 * (1) WMI_DELETE_CIPHER_KEY_CMD
366 * (2) WMI_SET_APPIE_CMD
367 */
368 rc = wmi_del_cipher_key(wil, 0, bss->bssid); 397 rc = wmi_del_cipher_key(wil, 0, bss->bssid);
369 if (rc) { 398 if (rc) {
370 wil_err(wil, "WMI_DELETE_CIPHER_KEY_CMD failed\n"); 399 wil_err(wil, "WMI_DELETE_CIPHER_KEY_CMD failed\n");
371 goto out; 400 goto out;
372 } 401 }
373 /* WMI_SET_APPIE_CMD */ 402 }
374 rc = wmi_set_ie(wil, WMI_FRAME_ASSOC_REQ, sme->ie_len, sme->ie); 403
375 if (rc) { 404 /* WMI_SET_APPIE_CMD. ie may contain rsn info as well as other info
376 wil_err(wil, "WMI_SET_APPIE_CMD failed\n"); 405 * elements. Send it also in case it's empty, to erase previously set
377 goto out; 406 * ies in FW.
378 } 407 */
408 rc = wmi_set_ie(wil, WMI_FRAME_ASSOC_REQ, sme->ie_len, sme->ie);
409 if (rc) {
410 wil_err(wil, "WMI_SET_APPIE_CMD failed\n");
411 goto out;
379 } 412 }
380 413
381 /* WMI_CONNECT_CMD */ 414 /* WMI_CONNECT_CMD */
@@ -621,6 +654,45 @@ static int wil_fix_bcon(struct wil6210_priv *wil,
621 return rc; 654 return rc;
622} 655}
623 656
657static int wil_cfg80211_change_beacon(struct wiphy *wiphy,
658 struct net_device *ndev,
659 struct cfg80211_beacon_data *bcon)
660{
661 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
662 int rc;
663
664 wil_dbg_misc(wil, "%s()\n", __func__);
665
666 if (wil_fix_bcon(wil, bcon)) {
667 wil_dbg_misc(wil, "Fixed bcon\n");
668 wil_print_bcon_data(bcon);
669 }
670
671 /* FW do not form regular beacon, so bcon IE's are not set
672 * For the DMG bcon, when it will be supported, bcon IE's will
673 * be reused; add something like:
674 * wmi_set_ie(wil, WMI_FRAME_BEACON, bcon->beacon_ies_len,
675 * bcon->beacon_ies);
676 */
677 rc = wmi_set_ie(wil, WMI_FRAME_PROBE_RESP,
678 bcon->proberesp_ies_len,
679 bcon->proberesp_ies);
680 if (rc) {
681 wil_err(wil, "set_ie(PROBE_RESP) failed\n");
682 return rc;
683 }
684
685 rc = wmi_set_ie(wil, WMI_FRAME_ASSOC_RESP,
686 bcon->assocresp_ies_len,
687 bcon->assocresp_ies);
688 if (rc) {
689 wil_err(wil, "set_ie(ASSOC_RESP) failed\n");
690 return rc;
691 }
692
693 return 0;
694}
695
624static int wil_cfg80211_start_ap(struct wiphy *wiphy, 696static int wil_cfg80211_start_ap(struct wiphy *wiphy,
625 struct net_device *ndev, 697 struct net_device *ndev,
626 struct cfg80211_ap_settings *info) 698 struct cfg80211_ap_settings *info)
@@ -658,12 +730,8 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy,
658 730
659 mutex_lock(&wil->mutex); 731 mutex_lock(&wil->mutex);
660 732
661 rc = wil_reset(wil); 733 __wil_down(wil);
662 if (rc) 734 rc = __wil_up(wil);
663 goto out;
664
665 /* Rx VRING. */
666 rc = wil_rx_init(wil);
667 if (rc) 735 if (rc)
668 goto out; 736 goto out;
669 737
@@ -671,9 +739,6 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy,
671 if (rc) 739 if (rc)
672 goto out; 740 goto out;
673 741
674 /* MAC address - pre-requisite for other commands */
675 wmi_set_mac_address(wil, ndev->dev_addr);
676
677 /* IE's */ 742 /* IE's */
678 /* bcon 'head IE's are not relevant for 60g band */ 743 /* bcon 'head IE's are not relevant for 60g band */
679 /* 744 /*
@@ -695,7 +760,6 @@ static int wil_cfg80211_start_ap(struct wiphy *wiphy,
695 if (rc) 760 if (rc)
696 goto out; 761 goto out;
697 762
698
699 netif_carrier_on(ndev); 763 netif_carrier_on(ndev);
700 764
701out: 765out:
@@ -706,7 +770,7 @@ out:
706static int wil_cfg80211_stop_ap(struct wiphy *wiphy, 770static int wil_cfg80211_stop_ap(struct wiphy *wiphy,
707 struct net_device *ndev) 771 struct net_device *ndev)
708{ 772{
709 int rc = 0; 773 int rc, rc1;
710 struct wil6210_priv *wil = wiphy_to_wil(wiphy); 774 struct wil6210_priv *wil = wiphy_to_wil(wiphy);
711 775
712 wil_dbg_misc(wil, "%s()\n", __func__); 776 wil_dbg_misc(wil, "%s()\n", __func__);
@@ -715,8 +779,12 @@ static int wil_cfg80211_stop_ap(struct wiphy *wiphy,
715 779
716 rc = wmi_pcp_stop(wil); 780 rc = wmi_pcp_stop(wil);
717 781
782 __wil_down(wil);
783 rc1 = __wil_up(wil);
784
718 mutex_unlock(&wil->mutex); 785 mutex_unlock(&wil->mutex);
719 return rc; 786
787 return min(rc, rc1);
720} 788}
721 789
722static int wil_cfg80211_del_station(struct wiphy *wiphy, 790static int wil_cfg80211_del_station(struct wiphy *wiphy,
@@ -746,6 +814,7 @@ static struct cfg80211_ops wil_cfg80211_ops = {
746 .del_key = wil_cfg80211_del_key, 814 .del_key = wil_cfg80211_del_key,
747 .set_default_key = wil_cfg80211_set_default_key, 815 .set_default_key = wil_cfg80211_set_default_key,
748 /* AP mode */ 816 /* AP mode */
817 .change_beacon = wil_cfg80211_change_beacon,
749 .start_ap = wil_cfg80211_start_ap, 818 .start_ap = wil_cfg80211_start_ap,
750 .stop_ap = wil_cfg80211_stop_ap, 819 .stop_ap = wil_cfg80211_stop_ap,
751 .del_station = wil_cfg80211_del_station, 820 .del_station = wil_cfg80211_del_station,
@@ -755,6 +824,7 @@ static void wil_wiphy_init(struct wiphy *wiphy)
755{ 824{
756 /* TODO: set real value */ 825 /* TODO: set real value */
757 wiphy->max_scan_ssids = 10; 826 wiphy->max_scan_ssids = 10;
827 wiphy->max_scan_ie_len = WMI_MAX_IE_LEN;
758 wiphy->max_num_pmkids = 0 /* TODO: */; 828 wiphy->max_num_pmkids = 0 /* TODO: */;
759 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) | 829 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
760 BIT(NL80211_IFTYPE_AP) | 830 BIT(NL80211_IFTYPE_AP) |
@@ -764,8 +834,8 @@ static void wil_wiphy_init(struct wiphy *wiphy)
764 */ 834 */
765 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME | 835 wiphy->flags |= WIPHY_FLAG_HAVE_AP_SME |
766 WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD; 836 WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
767 dev_warn(wiphy_dev(wiphy), "%s : flags = 0x%08x\n", 837 dev_dbg(wiphy_dev(wiphy), "%s : flags = 0x%08x\n",
768 __func__, wiphy->flags); 838 __func__, wiphy->flags);
769 wiphy->probe_resp_offload = 839 wiphy->probe_resp_offload =
770 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS | 840 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
771 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 | 841 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
@@ -786,7 +856,9 @@ struct wireless_dev *wil_cfg80211_init(struct device *dev)
786 int rc = 0; 856 int rc = 0;
787 struct wireless_dev *wdev; 857 struct wireless_dev *wdev;
788 858
789 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL); 859 dev_dbg(dev, "%s()\n", __func__);
860
861 wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
790 if (!wdev) 862 if (!wdev)
791 return ERR_PTR(-ENOMEM); 863 return ERR_PTR(-ENOMEM);
792 864
@@ -818,6 +890,8 @@ void wil_wdev_free(struct wil6210_priv *wil)
818{ 890{
819 struct wireless_dev *wdev = wil_to_wdev(wil); 891 struct wireless_dev *wdev = wil_to_wdev(wil);
820 892
893 dev_dbg(wil_to_dev(wil), "%s()\n", __func__);
894
821 if (!wdev) 895 if (!wdev)
822 return; 896 return;
823 897
diff --git a/drivers/net/wireless/ath/wil6210/debug.c b/drivers/net/wireless/ath/wil6210/debug.c
index 9eeabf4a5879..8d99021d27a8 100644
--- a/drivers/net/wireless/ath/wil6210/debug.c
+++ b/drivers/net/wireless/ath/wil6210/debug.c
@@ -17,43 +17,37 @@
17#include "wil6210.h" 17#include "wil6210.h"
18#include "trace.h" 18#include "trace.h"
19 19
20int wil_err(struct wil6210_priv *wil, const char *fmt, ...) 20void wil_err(struct wil6210_priv *wil, const char *fmt, ...)
21{ 21{
22 struct net_device *ndev = wil_to_ndev(wil); 22 struct net_device *ndev = wil_to_ndev(wil);
23 struct va_format vaf = { 23 struct va_format vaf = {
24 .fmt = fmt, 24 .fmt = fmt,
25 }; 25 };
26 va_list args; 26 va_list args;
27 int ret;
28 27
29 va_start(args, fmt); 28 va_start(args, fmt);
30 vaf.va = &args; 29 vaf.va = &args;
31 ret = netdev_err(ndev, "%pV", &vaf); 30 netdev_err(ndev, "%pV", &vaf);
32 trace_wil6210_log_err(&vaf); 31 trace_wil6210_log_err(&vaf);
33 va_end(args); 32 va_end(args);
34
35 return ret;
36} 33}
37 34
38int wil_info(struct wil6210_priv *wil, const char *fmt, ...) 35void wil_info(struct wil6210_priv *wil, const char *fmt, ...)
39{ 36{
40 struct net_device *ndev = wil_to_ndev(wil); 37 struct net_device *ndev = wil_to_ndev(wil);
41 struct va_format vaf = { 38 struct va_format vaf = {
42 .fmt = fmt, 39 .fmt = fmt,
43 }; 40 };
44 va_list args; 41 va_list args;
45 int ret;
46 42
47 va_start(args, fmt); 43 va_start(args, fmt);
48 vaf.va = &args; 44 vaf.va = &args;
49 ret = netdev_info(ndev, "%pV", &vaf); 45 netdev_info(ndev, "%pV", &vaf);
50 trace_wil6210_log_info(&vaf); 46 trace_wil6210_log_info(&vaf);
51 va_end(args); 47 va_end(args);
52
53 return ret;
54} 48}
55 49
56int wil_dbg_trace(struct wil6210_priv *wil, const char *fmt, ...) 50void wil_dbg_trace(struct wil6210_priv *wil, const char *fmt, ...)
57{ 51{
58 struct va_format vaf = { 52 struct va_format vaf = {
59 .fmt = fmt, 53 .fmt = fmt,
@@ -64,6 +58,4 @@ int wil_dbg_trace(struct wil6210_priv *wil, const char *fmt, ...)
64 vaf.va = &args; 58 vaf.va = &args;
65 trace_wil6210_log_dbg(&vaf); 59 trace_wil6210_log_dbg(&vaf);
66 va_end(args); 60 va_end(args);
67
68 return 0;
69} 61}
diff --git a/drivers/net/wireless/ath/wil6210/debugfs.c b/drivers/net/wireless/ath/wil6210/debugfs.c
index b1c6a7293390..eb2204e5fdd4 100644
--- a/drivers/net/wireless/ath/wil6210/debugfs.c
+++ b/drivers/net/wireless/ath/wil6210/debugfs.c
@@ -61,20 +61,22 @@ static void wil_print_vring(struct seq_file *s, struct wil6210_priv *wil,
61 if (x) 61 if (x)
62 seq_printf(s, "0x%08x\n", ioread32(x)); 62 seq_printf(s, "0x%08x\n", ioread32(x));
63 else 63 else
64 seq_printf(s, "???\n"); 64 seq_puts(s, "???\n");
65 65
66 if (vring->va && (vring->size < 1025)) { 66 if (vring->va && (vring->size < 1025)) {
67 uint i; 67 uint i;
68
68 for (i = 0; i < vring->size; i++) { 69 for (i = 0; i < vring->size; i++) {
69 volatile struct vring_tx_desc *d = &vring->va[i].tx; 70 volatile struct vring_tx_desc *d = &vring->va[i].tx;
71
70 if ((i % 64) == 0 && (i != 0)) 72 if ((i % 64) == 0 && (i != 0))
71 seq_printf(s, "\n"); 73 seq_puts(s, "\n");
72 seq_printf(s, "%c", (d->dma.status & BIT(0)) ? 74 seq_printf(s, "%c", (d->dma.status & BIT(0)) ?
73 _s : (vring->ctx[i].skb ? _h : 'h')); 75 _s : (vring->ctx[i].skb ? _h : 'h'));
74 } 76 }
75 seq_printf(s, "\n"); 77 seq_puts(s, "\n");
76 } 78 }
77 seq_printf(s, "}\n"); 79 seq_puts(s, "}\n");
78} 80}
79 81
80static int wil_vring_debugfs_show(struct seq_file *s, void *data) 82static int wil_vring_debugfs_show(struct seq_file *s, void *data)
@@ -85,7 +87,7 @@ static int wil_vring_debugfs_show(struct seq_file *s, void *data)
85 wil_print_vring(s, wil, "rx", &wil->vring_rx, 'S', '_'); 87 wil_print_vring(s, wil, "rx", &wil->vring_rx, 'S', '_');
86 88
87 for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++) { 89 for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++) {
88 struct vring *vring = &(wil->vring_tx[i]); 90 struct vring *vring = &wil->vring_tx[i];
89 struct vring_tx_data *txdata = &wil->vring_tx_data[i]; 91 struct vring_tx_data *txdata = &wil->vring_tx_data[i];
90 92
91 if (vring->va) { 93 if (vring->va) {
@@ -163,7 +165,7 @@ static void wil_print_ring(struct seq_file *s, const char *prefix,
163 if (!wmi_addr(wil, r.base) || 165 if (!wmi_addr(wil, r.base) ||
164 !wmi_addr(wil, r.tail) || 166 !wmi_addr(wil, r.tail) ||
165 !wmi_addr(wil, r.head)) { 167 !wmi_addr(wil, r.head)) {
166 seq_printf(s, " ??? pointers are garbage?\n"); 168 seq_puts(s, " ??? pointers are garbage?\n");
167 goto out; 169 goto out;
168 } 170 }
169 171
@@ -182,6 +184,7 @@ static void wil_print_ring(struct seq_file *s, const char *prefix,
182 le32_to_cpu(d.addr)); 184 le32_to_cpu(d.addr));
183 if (0 == wmi_read_hdr(wil, d.addr, &hdr)) { 185 if (0 == wmi_read_hdr(wil, d.addr, &hdr)) {
184 u16 len = le16_to_cpu(hdr.len); 186 u16 len = le16_to_cpu(hdr.len);
187
185 seq_printf(s, " -> %04x %04x %04x %02x\n", 188 seq_printf(s, " -> %04x %04x %04x %02x\n",
186 le16_to_cpu(hdr.seq), len, 189 le16_to_cpu(hdr.seq), len,
187 le16_to_cpu(hdr.type), hdr.flags); 190 le16_to_cpu(hdr.type), hdr.flags);
@@ -199,6 +202,7 @@ static void wil_print_ring(struct seq_file *s, const char *prefix,
199 wil_memcpy_fromio_32(databuf, src, len); 202 wil_memcpy_fromio_32(databuf, src, len);
200 while (n < len) { 203 while (n < len) {
201 int l = min(len - n, 16); 204 int l = min(len - n, 16);
205
202 hex_dump_to_buffer(databuf + n, l, 206 hex_dump_to_buffer(databuf + n, l,
203 16, 1, printbuf, 207 16, 1, printbuf,
204 sizeof(printbuf), 208 sizeof(printbuf),
@@ -208,11 +212,11 @@ static void wil_print_ring(struct seq_file *s, const char *prefix,
208 } 212 }
209 } 213 }
210 } else { 214 } else {
211 seq_printf(s, "\n"); 215 seq_puts(s, "\n");
212 } 216 }
213 } 217 }
214 out: 218 out:
215 seq_printf(s, "}\n"); 219 seq_puts(s, "}\n");
216} 220}
217 221
218static int wil_mbox_debugfs_show(struct seq_file *s, void *data) 222static int wil_mbox_debugfs_show(struct seq_file *s, void *data)
@@ -271,11 +275,13 @@ static int wil_debugfs_ulong_set(void *data, u64 val)
271 *(ulong *)data = val; 275 *(ulong *)data = val;
272 return 0; 276 return 0;
273} 277}
278
274static int wil_debugfs_ulong_get(void *data, u64 *val) 279static int wil_debugfs_ulong_get(void *data, u64 *val)
275{ 280{
276 *val = *(ulong *)data; 281 *val = *(ulong *)data;
277 return 0; 282 return 0;
278} 283}
284
279DEFINE_SIMPLE_ATTRIBUTE(wil_fops_ulong, wil_debugfs_ulong_get, 285DEFINE_SIMPLE_ATTRIBUTE(wil_fops_ulong, wil_debugfs_ulong_get,
280 wil_debugfs_ulong_set, "%llu\n"); 286 wil_debugfs_ulong_set, "%llu\n");
281 287
@@ -302,7 +308,7 @@ static void wil6210_debugfs_init_offset(struct wil6210_priv *wil,
302 int i; 308 int i;
303 309
304 for (i = 0; tbl[i].name; i++) { 310 for (i = 0; tbl[i].name; i++) {
305 struct dentry *f = NULL; 311 struct dentry *f;
306 312
307 switch (tbl[i].type) { 313 switch (tbl[i].type) {
308 case doff_u32: 314 case doff_u32:
@@ -322,6 +328,8 @@ static void wil6210_debugfs_init_offset(struct wil6210_priv *wil,
322 tbl[i].mode, dbg, 328 tbl[i].mode, dbg,
323 base + tbl[i].off); 329 base + tbl[i].off);
324 break; 330 break;
331 default:
332 f = ERR_PTR(-EINVAL);
325 } 333 }
326 if (IS_ERR_OR_NULL(f)) 334 if (IS_ERR_OR_NULL(f))
327 wil_err(wil, "Create file \"%s\": err %ld\n", 335 wil_err(wil, "Create file \"%s\": err %ld\n",
@@ -339,6 +347,7 @@ static const struct dbg_off isr_off[] = {
339 {"IMC", S_IWUSR, offsetof(struct RGF_ICR, IMC), doff_io32}, 347 {"IMC", S_IWUSR, offsetof(struct RGF_ICR, IMC), doff_io32},
340 {}, 348 {},
341}; 349};
350
342static int wil6210_debugfs_create_ISR(struct wil6210_priv *wil, 351static int wil6210_debugfs_create_ISR(struct wil6210_priv *wil,
343 const char *name, 352 const char *name,
344 struct dentry *parent, u32 off) 353 struct dentry *parent, u32 off)
@@ -422,7 +431,7 @@ static const struct file_operations fops_memread = {
422}; 431};
423 432
424static ssize_t wil_read_file_ioblob(struct file *file, char __user *user_buf, 433static ssize_t wil_read_file_ioblob(struct file *file, char __user *user_buf,
425 size_t count, loff_t *ppos) 434 size_t count, loff_t *ppos)
426{ 435{
427 enum { max_count = 4096 }; 436 enum { max_count = 4096 };
428 struct debugfs_blob_wrapper *blob = file->private_data; 437 struct debugfs_blob_wrapper *blob = file->private_data;
@@ -474,6 +483,7 @@ struct dentry *wil_debugfs_create_ioblob(const char *name,
474{ 483{
475 return debugfs_create_file(name, mode, parent, blob, &fops_ioblob); 484 return debugfs_create_file(name, mode, parent, blob, &fops_ioblob);
476} 485}
486
477/*---reset---*/ 487/*---reset---*/
478static ssize_t wil_write_file_reset(struct file *file, const char __user *buf, 488static ssize_t wil_write_file_reset(struct file *file, const char __user *buf,
479 size_t len, loff_t *ppos) 489 size_t len, loff_t *ppos)
@@ -499,6 +509,7 @@ static const struct file_operations fops_reset = {
499 .write = wil_write_file_reset, 509 .write = wil_write_file_reset,
500 .open = simple_open, 510 .open = simple_open,
501}; 511};
512
502/*---write channel 1..4 to rxon for it, 0 to rxoff---*/ 513/*---write channel 1..4 to rxon for it, 0 to rxoff---*/
503static ssize_t wil_write_file_rxon(struct file *file, const char __user *buf, 514static ssize_t wil_write_file_rxon(struct file *file, const char __user *buf,
504 size_t len, loff_t *ppos) 515 size_t len, loff_t *ppos)
@@ -509,6 +520,7 @@ static ssize_t wil_write_file_rxon(struct file *file, const char __user *buf,
509 bool on; 520 bool on;
510 521
511 char *kbuf = kmalloc(len + 1, GFP_KERNEL); 522 char *kbuf = kmalloc(len + 1, GFP_KERNEL);
523
512 if (!kbuf) 524 if (!kbuf)
513 return -ENOMEM; 525 return -ENOMEM;
514 if (copy_from_user(kbuf, buf, len)) { 526 if (copy_from_user(kbuf, buf, len)) {
@@ -545,6 +557,7 @@ static const struct file_operations fops_rxon = {
545 .write = wil_write_file_rxon, 557 .write = wil_write_file_rxon,
546 .open = simple_open, 558 .open = simple_open,
547}; 559};
560
548/*---tx_mgmt---*/ 561/*---tx_mgmt---*/
549/* Write mgmt frame to this file to send it */ 562/* Write mgmt frame to this file to send it */
550static ssize_t wil_write_file_txmgmt(struct file *file, const char __user *buf, 563static ssize_t wil_write_file_txmgmt(struct file *file, const char __user *buf,
@@ -555,8 +568,8 @@ static ssize_t wil_write_file_txmgmt(struct file *file, const char __user *buf,
555 struct wireless_dev *wdev = wil_to_wdev(wil); 568 struct wireless_dev *wdev = wil_to_wdev(wil);
556 struct cfg80211_mgmt_tx_params params; 569 struct cfg80211_mgmt_tx_params params;
557 int rc; 570 int rc;
558
559 void *frame = kmalloc(len, GFP_KERNEL); 571 void *frame = kmalloc(len, GFP_KERNEL);
572
560 if (!frame) 573 if (!frame)
561 return -ENOMEM; 574 return -ENOMEM;
562 575
@@ -625,8 +638,10 @@ static void wil_seq_hexdump(struct seq_file *s, void *p, int len,
625{ 638{
626 char printbuf[16 * 3 + 2]; 639 char printbuf[16 * 3 + 2];
627 int i = 0; 640 int i = 0;
641
628 while (i < len) { 642 while (i < len) {
629 int l = min(len - i, 16); 643 int l = min(len - i, 16);
644
630 hex_dump_to_buffer(p + i, l, 16, 1, printbuf, 645 hex_dump_to_buffer(p + i, l, 16, 1, printbuf,
631 sizeof(printbuf), false); 646 sizeof(printbuf), false);
632 seq_printf(s, "%s%s\n", prefix, printbuf); 647 seq_printf(s, "%s%s\n", prefix, printbuf);
@@ -664,10 +679,8 @@ static int wil_txdesc_debugfs_show(struct seq_file *s, void *data)
664 struct wil6210_priv *wil = s->private; 679 struct wil6210_priv *wil = s->private;
665 struct vring *vring; 680 struct vring *vring;
666 bool tx = (dbg_vring_index < WIL6210_MAX_TX_RINGS); 681 bool tx = (dbg_vring_index < WIL6210_MAX_TX_RINGS);
667 if (tx) 682
668 vring = &(wil->vring_tx[dbg_vring_index]); 683 vring = tx ? &wil->vring_tx[dbg_vring_index] : &wil->vring_rx;
669 else
670 vring = &wil->vring_rx;
671 684
672 if (!vring->va) { 685 if (!vring->va) {
673 if (tx) 686 if (tx)
@@ -682,7 +695,7 @@ static int wil_txdesc_debugfs_show(struct seq_file *s, void *data)
682 * only field used, .dma.length, is the same 695 * only field used, .dma.length, is the same
683 */ 696 */
684 volatile struct vring_tx_desc *d = 697 volatile struct vring_tx_desc *d =
685 &(vring->va[dbg_txdesc_index].tx); 698 &vring->va[dbg_txdesc_index].tx;
686 volatile u32 *u = (volatile u32 *)d; 699 volatile u32 *u = (volatile u32 *)d;
687 struct sk_buff *skb = vring->ctx[dbg_txdesc_index].skb; 700 struct sk_buff *skb = vring->ctx[dbg_txdesc_index].skb;
688 701
@@ -702,7 +715,7 @@ static int wil_txdesc_debugfs_show(struct seq_file *s, void *data)
702 wil_seq_print_skb(s, skb); 715 wil_seq_print_skb(s, skb);
703 kfree_skb(skb); 716 kfree_skb(skb);
704 } 717 }
705 seq_printf(s, "}\n"); 718 seq_puts(s, "}\n");
706 } else { 719 } else {
707 if (tx) 720 if (tx)
708 seq_printf(s, "[%2d] TxDesc index (%d) >= size (%d)\n", 721 seq_printf(s, "[%2d] TxDesc index (%d) >= size (%d)\n",
@@ -816,6 +829,7 @@ static const struct file_operations fops_bf = {
816 .read = seq_read, 829 .read = seq_read,
817 .llseek = seq_lseek, 830 .llseek = seq_lseek,
818}; 831};
832
819/*---------SSID------------*/ 833/*---------SSID------------*/
820static ssize_t wil_read_file_ssid(struct file *file, char __user *user_buf, 834static ssize_t wil_read_file_ssid(struct file *file, char __user *user_buf,
821 size_t count, loff_t *ppos) 835 size_t count, loff_t *ppos)
@@ -878,10 +892,10 @@ static int wil_temp_debugfs_show(struct seq_file *s, void *data)
878{ 892{
879 struct wil6210_priv *wil = s->private; 893 struct wil6210_priv *wil = s->private;
880 u32 t_m, t_r; 894 u32 t_m, t_r;
881
882 int rc = wmi_get_temperature(wil, &t_m, &t_r); 895 int rc = wmi_get_temperature(wil, &t_m, &t_r);
896
883 if (rc) { 897 if (rc) {
884 seq_printf(s, "Failed\n"); 898 seq_puts(s, "Failed\n");
885 return 0; 899 return 0;
886 } 900 }
887 901
@@ -937,6 +951,7 @@ static int wil_link_debugfs_show(struct seq_file *s, void *data)
937 for (i = 0; i < ARRAY_SIZE(wil->sta); i++) { 951 for (i = 0; i < ARRAY_SIZE(wil->sta); i++) {
938 struct wil_sta_info *p = &wil->sta[i]; 952 struct wil_sta_info *p = &wil->sta[i];
939 char *status = "unknown"; 953 char *status = "unknown";
954
940 switch (p->status) { 955 switch (p->status) {
941 case wil_sta_unused: 956 case wil_sta_unused:
942 status = "unused "; 957 status = "unused ";
@@ -997,7 +1012,6 @@ static int wil_info_debugfs_show(struct seq_file *s, void *data)
997 rxf_old = rxf; 1012 rxf_old = rxf;
998 txf_old = txf; 1013 txf_old = txf;
999 1014
1000
1001#define CHECK_QSTATE(x) (state & BIT(__QUEUE_STATE_ ## x)) ? \ 1015#define CHECK_QSTATE(x) (state & BIT(__QUEUE_STATE_ ## x)) ? \
1002 " " __stringify(x) : "" 1016 " " __stringify(x) : ""
1003 1017
@@ -1032,6 +1046,7 @@ static void wil_print_rxtid(struct seq_file *s, struct wil_tid_ampdu_rx *r)
1032{ 1046{
1033 int i; 1047 int i;
1034 u16 index = ((r->head_seq_num - r->ssn) & 0xfff) % r->buf_size; 1048 u16 index = ((r->head_seq_num - r->ssn) & 0xfff) % r->buf_size;
1049
1035 seq_printf(s, "0x%03x [", r->head_seq_num); 1050 seq_printf(s, "0x%03x [", r->head_seq_num);
1036 for (i = 0; i < r->buf_size; i++) { 1051 for (i = 0; i < r->buf_size; i++) {
1037 if (i == index) 1052 if (i == index)
@@ -1046,10 +1061,12 @@ static int wil_sta_debugfs_show(struct seq_file *s, void *data)
1046{ 1061{
1047 struct wil6210_priv *wil = s->private; 1062 struct wil6210_priv *wil = s->private;
1048 int i, tid; 1063 int i, tid;
1064 unsigned long flags;
1049 1065
1050 for (i = 0; i < ARRAY_SIZE(wil->sta); i++) { 1066 for (i = 0; i < ARRAY_SIZE(wil->sta); i++) {
1051 struct wil_sta_info *p = &wil->sta[i]; 1067 struct wil_sta_info *p = &wil->sta[i];
1052 char *status = "unknown"; 1068 char *status = "unknown";
1069
1053 switch (p->status) { 1070 switch (p->status) {
1054 case wil_sta_unused: 1071 case wil_sta_unused:
1055 status = "unused "; 1072 status = "unused ";
@@ -1065,13 +1082,16 @@ static int wil_sta_debugfs_show(struct seq_file *s, void *data)
1065 (p->data_port_open ? " data_port_open" : "")); 1082 (p->data_port_open ? " data_port_open" : ""));
1066 1083
1067 if (p->status == wil_sta_connected) { 1084 if (p->status == wil_sta_connected) {
1085 spin_lock_irqsave(&p->tid_rx_lock, flags);
1068 for (tid = 0; tid < WIL_STA_TID_NUM; tid++) { 1086 for (tid = 0; tid < WIL_STA_TID_NUM; tid++) {
1069 struct wil_tid_ampdu_rx *r = p->tid_rx[tid]; 1087 struct wil_tid_ampdu_rx *r = p->tid_rx[tid];
1088
1070 if (r) { 1089 if (r) {
1071 seq_printf(s, "[%2d] ", tid); 1090 seq_printf(s, "[%2d] ", tid);
1072 wil_print_rxtid(s, r); 1091 wil_print_rxtid(s, r);
1073 } 1092 }
1074 } 1093 }
1094 spin_unlock_irqrestore(&p->tid_rx_lock, flags);
1075 } 1095 }
1076 } 1096 }
1077 1097
diff --git a/drivers/net/wireless/ath/wil6210/fw.c b/drivers/net/wireless/ath/wil6210/fw.c
new file mode 100644
index 000000000000..8c6f3b041f77
--- /dev/null
+++ b/drivers/net/wireless/ath/wil6210/fw.c
@@ -0,0 +1,45 @@
1/*
2 * Copyright (c) 2014 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#include <linux/firmware.h>
17#include <linux/module.h>
18#include <linux/pci.h>
19#include <linux/crc32.h>
20#include "wil6210.h"
21#include "fw.h"
22
23MODULE_FIRMWARE(WIL_FW_NAME);
24
25/* target operations */
26/* register read */
27#define R(a) ioread32(wil->csr + HOSTADDR(a))
28/* register write. wmb() to make sure it is completed */
29#define W(a, v) do { iowrite32(v, wil->csr + HOSTADDR(a)); wmb(); } while (0)
30/* register set = read, OR, write */
31#define S(a, v) W(a, R(a) | v)
32/* register clear = read, AND with inverted, write */
33#define C(a, v) W(a, R(a) & ~v)
34
35static
36void wil_memset_toio_32(volatile void __iomem *dst, u32 val,
37 size_t count)
38{
39 volatile u32 __iomem *d = dst;
40
41 for (count += 4; count > 4; count -= 4)
42 __raw_writel(val, d++);
43}
44
45#include "fw_inc.c"
diff --git a/drivers/net/wireless/ath/wil6210/fw.h b/drivers/net/wireless/ath/wil6210/fw.h
new file mode 100644
index 000000000000..7a2c6c129ad5
--- /dev/null
+++ b/drivers/net/wireless/ath/wil6210/fw.h
@@ -0,0 +1,149 @@
1/*
2 * Copyright (c) 2014 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#define WIL_FW_SIGNATURE (0x36323130) /* '0126' */
18#define WIL_FW_FMT_VERSION (1) /* format version driver supports */
19
20enum wil_fw_record_type {
21 wil_fw_type_comment = 1,
22 wil_fw_type_data = 2,
23 wil_fw_type_fill = 3,
24 wil_fw_type_action = 4,
25 wil_fw_type_verify = 5,
26 wil_fw_type_file_header = 6,
27 wil_fw_type_direct_write = 7,
28 wil_fw_type_gateway_data = 8,
29 wil_fw_type_gateway_data4 = 9,
30};
31
32struct wil_fw_record_head {
33 __le16 type; /* enum wil_fw_record_type */
34 __le16 flags; /* to be defined */
35 __le32 size; /* whole record, bytes after head */
36} __packed;
37
38/* data block. write starting from @addr
39 * data_size inferred from the @head.size. For this case,
40 * data_size = @head.size - offsetof(struct wil_fw_record_data, data)
41 */
42struct wil_fw_record_data { /* type == wil_fw_type_data */
43 __le32 addr;
44 __le32 data[0]; /* [data_size], see above */
45} __packed;
46
47/* fill with constant @value, @size bytes starting from @addr */
48struct wil_fw_record_fill { /* type == wil_fw_type_fill */
49 __le32 addr;
50 __le32 value;
51 __le32 size;
52} __packed;
53
54/* free-form comment
55 * for informational purpose, data_size is @head.size from record header
56 */
57struct wil_fw_record_comment { /* type == wil_fw_type_comment */
58 u8 data[0]; /* free-form data [data_size], see above */
59} __packed;
60
61/* perform action
62 * data_size = @head.size - offsetof(struct wil_fw_record_action, data)
63 */
64struct wil_fw_record_action { /* type == wil_fw_type_action */
65 __le32 action; /* action to perform: reset, wait for fw ready etc. */
66 __le32 data[0]; /* action specific, [data_size], see above */
67} __packed;
68
69/* data block for struct wil_fw_record_direct_write */
70struct wil_fw_data_dwrite {
71 __le32 addr;
72 __le32 value;
73 __le32 mask;
74} __packed;
75
76/* write @value to the @addr,
77 * preserve original bits accordingly to the @mask
78 * data_size is @head.size where @head is record header
79 */
80struct wil_fw_record_direct_write { /* type == wil_fw_type_direct_write */
81 struct wil_fw_data_dwrite data[0];
82} __packed;
83
84/* verify condition: [@addr] & @mask == @value
85 * if condition not met, firmware download fails
86 */
87struct wil_fw_record_verify { /* type == wil_fw_verify */
88 __le32 addr; /* read from this address */
89 __le32 value; /* reference value */
90 __le32 mask; /* mask for verification */
91} __packed;
92
93/* file header
94 * First record of every file
95 */
96struct wil_fw_record_file_header {
97 __le32 signature ; /* Wilocity signature */
98 __le32 reserved;
99 __le32 crc; /* crc32 of the following data */
100 __le32 version; /* format version */
101 __le32 data_len; /* total data in file, including this record */
102 u8 comment[32]; /* short description */
103} __packed;
104
105/* 1-dword gateway */
106/* data block for the struct wil_fw_record_gateway_data */
107struct wil_fw_data_gw {
108 __le32 addr;
109 __le32 value;
110} __packed;
111
112/* gateway write block.
113 * write starting address and values from the data buffer
114 * through the gateway
115 * data_size inferred from the @head.size. For this case,
116 * data_size = @head.size - offsetof(struct wil_fw_record_gateway_data, data)
117 */
118struct wil_fw_record_gateway_data { /* type == wil_fw_type_gateway_data */
119 __le32 gateway_addr_addr;
120 __le32 gateway_value_addr;
121 __le32 gateway_cmd_addr;
122 __le32 gateway_ctrl_address;
123#define WIL_FW_GW_CTL_BUSY BIT(29) /* gateway busy performing operation */
124#define WIL_FW_GW_CTL_RUN BIT(30) /* start gateway operation */
125 __le32 command;
126 struct wil_fw_data_gw data[0]; /* total size [data_size], see above */
127} __packed;
128
129/* 4-dword gateway */
130/* data block for the struct wil_fw_record_gateway_data4 */
131struct wil_fw_data_gw4 {
132 __le32 addr;
133 __le32 value[4];
134} __packed;
135
136/* gateway write block.
137 * write starting address and values from the data buffer
138 * through the gateway
139 * data_size inferred from the @head.size. For this case,
140 * data_size = @head.size - offsetof(struct wil_fw_record_gateway_data4, data)
141 */
142struct wil_fw_record_gateway_data4 { /* type == wil_fw_type_gateway_data4 */
143 __le32 gateway_addr_addr;
144 __le32 gateway_value_addr[4];
145 __le32 gateway_cmd_addr;
146 __le32 gateway_ctrl_address; /* same logic as for 1-dword gw */
147 __le32 command;
148 struct wil_fw_data_gw4 data[0]; /* total size [data_size], see above */
149} __packed;
diff --git a/drivers/net/wireless/ath/wil6210/fw_inc.c b/drivers/net/wireless/ath/wil6210/fw_inc.c
new file mode 100644
index 000000000000..44cb71f5ea5b
--- /dev/null
+++ b/drivers/net/wireless/ath/wil6210/fw_inc.c
@@ -0,0 +1,495 @@
1/*
2 * Copyright (c) 2014 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/* Algorithmic part of the firmware download.
18 * To be included in the container file providing framework
19 */
20
21#define wil_err_fw(wil, fmt, arg...) wil_err(wil, "ERR[ FW ]" fmt, ##arg)
22#define wil_dbg_fw(wil, fmt, arg...) wil_dbg(wil, "DBG[ FW ]" fmt, ##arg)
23#define wil_hex_dump_fw(prefix_str, prefix_type, rowsize, \
24 groupsize, buf, len, ascii) \
25 print_hex_dump_debug("DBG[ FW ]" prefix_str, \
26 prefix_type, rowsize, \
27 groupsize, buf, len, ascii)
28
29#define FW_ADDR_CHECK(ioaddr, val, msg) do { \
30 ioaddr = wmi_buffer(wil, val); \
31 if (!ioaddr) { \
32 wil_err_fw(wil, "bad " msg ": 0x%08x\n", \
33 le32_to_cpu(val)); \
34 return -EINVAL; \
35 } \
36 } while (0)
37
38/**
39 * wil_fw_verify - verify firmware file validity
40 *
41 * perform various checks for the firmware file header.
42 * records are not validated.
43 *
44 * Return file size or negative error
45 */
46static int wil_fw_verify(struct wil6210_priv *wil, const u8 *data, size_t size)
47{
48 const struct wil_fw_record_head *hdr = (const void *)data;
49 struct wil_fw_record_file_header fh;
50 const struct wil_fw_record_file_header *fh_;
51 u32 crc;
52 u32 dlen;
53
54 if (size % 4) {
55 wil_err_fw(wil, "image size not aligned: %zu\n", size);
56 return -EINVAL;
57 }
58 /* have enough data for the file header? */
59 if (size < sizeof(*hdr) + sizeof(fh)) {
60 wil_err_fw(wil, "file too short: %zu bytes\n", size);
61 return -EINVAL;
62 }
63
64 /* start with the file header? */
65 if (le16_to_cpu(hdr->type) != wil_fw_type_file_header) {
66 wil_err_fw(wil, "no file header\n");
67 return -EINVAL;
68 }
69
70 /* data_len */
71 fh_ = (struct wil_fw_record_file_header *)&hdr[1];
72 dlen = le32_to_cpu(fh_->data_len);
73 if (dlen % 4) {
74 wil_err_fw(wil, "data length not aligned: %lu\n", (ulong)dlen);
75 return -EINVAL;
76 }
77 if (size < dlen) {
78 wil_err_fw(wil, "file truncated at %zu/%lu\n",
79 size, (ulong)dlen);
80 return -EINVAL;
81 }
82 if (dlen < sizeof(*hdr) + sizeof(fh)) {
83 wil_err_fw(wil, "data length too short: %lu\n", (ulong)dlen);
84 return -EINVAL;
85 }
86
87 /* signature */
88 if (le32_to_cpu(fh_->signature) != WIL_FW_SIGNATURE) {
89 wil_err_fw(wil, "bad header signature: 0x%08x\n",
90 le32_to_cpu(fh_->signature));
91 return -EINVAL;
92 }
93
94 /* version */
95 if (le32_to_cpu(fh_->version) > WIL_FW_FMT_VERSION) {
96 wil_err_fw(wil, "unsupported header version: %d\n",
97 le32_to_cpu(fh_->version));
98 return -EINVAL;
99 }
100
101 /* checksum. ~crc32(~0, data, size) when fh.crc set to 0*/
102 fh = *fh_;
103 fh.crc = 0;
104
105 crc = crc32_le(~0, (unsigned char const *)hdr, sizeof(*hdr));
106 crc = crc32_le(crc, (unsigned char const *)&fh, sizeof(fh));
107 crc = crc32_le(crc, (unsigned char const *)&fh_[1],
108 dlen - sizeof(*hdr) - sizeof(fh));
109 crc = ~crc;
110
111 if (crc != le32_to_cpu(fh_->crc)) {
112 wil_err_fw(wil, "checksum mismatch:"
113 " calculated for %lu bytes 0x%08x != 0x%08x\n",
114 (ulong)dlen, crc, le32_to_cpu(fh_->crc));
115 return -EINVAL;
116 }
117
118 return (int)dlen;
119}
120
121static int fw_handle_comment(struct wil6210_priv *wil, const void *data,
122 size_t size)
123{
124 wil_hex_dump_fw("", DUMP_PREFIX_OFFSET, 16, 1, data, size, true);
125
126 return 0;
127}
128
129static int fw_handle_data(struct wil6210_priv *wil, const void *data,
130 size_t size)
131{
132 const struct wil_fw_record_data *d = data;
133 void __iomem *dst;
134 size_t s = size - sizeof(*d);
135
136 if (size < sizeof(*d) + sizeof(u32)) {
137 wil_err_fw(wil, "data record too short: %zu\n", size);
138 return -EINVAL;
139 }
140
141 FW_ADDR_CHECK(dst, d->addr, "address");
142 wil_dbg_fw(wil, "write [0x%08x] <== %zu bytes\n", le32_to_cpu(d->addr),
143 s);
144 wil_memcpy_toio_32(dst, d->data, s);
145 wmb(); /* finish before processing next record */
146
147 return 0;
148}
149
150static int fw_handle_fill(struct wil6210_priv *wil, const void *data,
151 size_t size)
152{
153 const struct wil_fw_record_fill *d = data;
154 void __iomem *dst;
155 u32 v;
156 size_t s = (size_t)le32_to_cpu(d->size);
157
158 if (size != sizeof(*d)) {
159 wil_err_fw(wil, "bad size for fill record: %zu\n", size);
160 return -EINVAL;
161 }
162
163 if (s < sizeof(u32)) {
164 wil_err_fw(wil, "fill size too short: %zu\n", s);
165 return -EINVAL;
166 }
167
168 if (s % sizeof(u32)) {
169 wil_err_fw(wil, "fill size not aligned: %zu\n", s);
170 return -EINVAL;
171 }
172
173 FW_ADDR_CHECK(dst, d->addr, "address");
174
175 v = le32_to_cpu(d->value);
176 wil_dbg_fw(wil, "fill [0x%08x] <== 0x%08x, %zu bytes\n",
177 le32_to_cpu(d->addr), v, s);
178 wil_memset_toio_32(dst, v, s);
179 wmb(); /* finish before processing next record */
180
181 return 0;
182}
183
184static int fw_handle_file_header(struct wil6210_priv *wil, const void *data,
185 size_t size)
186{
187 const struct wil_fw_record_file_header *d = data;
188
189 if (size != sizeof(*d)) {
190 wil_err_fw(wil, "file header length incorrect: %zu\n", size);
191 return -EINVAL;
192 }
193
194 wil_dbg_fw(wil, "new file, ver. %d, %i bytes\n",
195 d->version, d->data_len);
196 wil_hex_dump_fw("", DUMP_PREFIX_OFFSET, 16, 1, d->comment,
197 sizeof(d->comment), true);
198
199 return 0;
200}
201
202static int fw_handle_direct_write(struct wil6210_priv *wil, const void *data,
203 size_t size)
204{
205 const struct wil_fw_record_direct_write *d = data;
206 const struct wil_fw_data_dwrite *block = d->data;
207 int n, i;
208
209 if (size % sizeof(*block)) {
210 wil_err_fw(wil, "record size not aligned on %zu: %zu\n",
211 sizeof(*block), size);
212 return -EINVAL;
213 }
214 n = size / sizeof(*block);
215
216 for (i = 0; i < n; i++) {
217 void __iomem *dst;
218 u32 m = le32_to_cpu(block[i].mask);
219 u32 v = le32_to_cpu(block[i].value);
220 u32 x, y;
221
222 FW_ADDR_CHECK(dst, block[i].addr, "address");
223
224 x = ioread32(dst);
225 y = (x & m) | (v & ~m);
226 wil_dbg_fw(wil, "write [0x%08x] <== 0x%08x "
227 "(old 0x%08x val 0x%08x mask 0x%08x)\n",
228 le32_to_cpu(block[i].addr), y, x, v, m);
229 iowrite32(y, dst);
230 wmb(); /* finish before processing next record */
231 }
232
233 return 0;
234}
235
236static int gw_write(struct wil6210_priv *wil, void __iomem *gwa_addr,
237 void __iomem *gwa_cmd, void __iomem *gwa_ctl, u32 gw_cmd,
238 u32 a)
239{
240 unsigned delay = 0;
241
242 iowrite32(a, gwa_addr);
243 iowrite32(gw_cmd, gwa_cmd);
244 wmb(); /* finish before activate gw */
245
246 iowrite32(WIL_FW_GW_CTL_RUN, gwa_ctl); /* activate gw */
247 do {
248 udelay(1); /* typical time is few usec */
249 if (delay++ > 100) {
250 wil_err_fw(wil, "gw timeout\n");
251 return -EINVAL;
252 }
253 } while (ioread32(gwa_ctl) & WIL_FW_GW_CTL_BUSY); /* gw done? */
254
255 return 0;
256}
257
258static int fw_handle_gateway_data(struct wil6210_priv *wil, const void *data,
259 size_t size)
260{
261 const struct wil_fw_record_gateway_data *d = data;
262 const struct wil_fw_data_gw *block = d->data;
263 void __iomem *gwa_addr;
264 void __iomem *gwa_val;
265 void __iomem *gwa_cmd;
266 void __iomem *gwa_ctl;
267 u32 gw_cmd;
268 int n, i;
269
270 if (size < sizeof(*d) + sizeof(*block)) {
271 wil_err_fw(wil, "gateway record too short: %zu\n", size);
272 return -EINVAL;
273 }
274
275 if ((size - sizeof(*d)) % sizeof(*block)) {
276 wil_err_fw(wil, "gateway record data size"
277 " not aligned on %zu: %zu\n",
278 sizeof(*block), size - sizeof(*d));
279 return -EINVAL;
280 }
281 n = (size - sizeof(*d)) / sizeof(*block);
282
283 gw_cmd = le32_to_cpu(d->command);
284
285 wil_dbg_fw(wil, "gw write record [%3d] blocks, cmd 0x%08x\n",
286 n, gw_cmd);
287
288 FW_ADDR_CHECK(gwa_addr, d->gateway_addr_addr, "gateway_addr_addr");
289 FW_ADDR_CHECK(gwa_val, d->gateway_value_addr, "gateway_value_addr");
290 FW_ADDR_CHECK(gwa_cmd, d->gateway_cmd_addr, "gateway_cmd_addr");
291 FW_ADDR_CHECK(gwa_ctl, d->gateway_ctrl_address, "gateway_ctrl_address");
292
293 wil_dbg_fw(wil, "gw addresses: addr 0x%08x val 0x%08x"
294 " cmd 0x%08x ctl 0x%08x\n",
295 le32_to_cpu(d->gateway_addr_addr),
296 le32_to_cpu(d->gateway_value_addr),
297 le32_to_cpu(d->gateway_cmd_addr),
298 le32_to_cpu(d->gateway_ctrl_address));
299
300 for (i = 0; i < n; i++) {
301 int rc;
302 u32 a = le32_to_cpu(block[i].addr);
303 u32 v = le32_to_cpu(block[i].value);
304
305 wil_dbg_fw(wil, " gw write[%3d] [0x%08x] <== 0x%08x\n",
306 i, a, v);
307
308 iowrite32(v, gwa_val);
309 rc = gw_write(wil, gwa_addr, gwa_cmd, gwa_ctl, gw_cmd, a);
310 if (rc)
311 return rc;
312 }
313
314 return 0;
315}
316
317static int fw_handle_gateway_data4(struct wil6210_priv *wil, const void *data,
318 size_t size)
319{
320 const struct wil_fw_record_gateway_data4 *d = data;
321 const struct wil_fw_data_gw4 *block = d->data;
322 void __iomem *gwa_addr;
323 void __iomem *gwa_val[ARRAY_SIZE(block->value)];
324 void __iomem *gwa_cmd;
325 void __iomem *gwa_ctl;
326 u32 gw_cmd;
327 int n, i, k;
328
329 if (size < sizeof(*d) + sizeof(*block)) {
330 wil_err_fw(wil, "gateway4 record too short: %zu\n", size);
331 return -EINVAL;
332 }
333
334 if ((size - sizeof(*d)) % sizeof(*block)) {
335 wil_err_fw(wil, "gateway4 record data size"
336 " not aligned on %zu: %zu\n",
337 sizeof(*block), size - sizeof(*d));
338 return -EINVAL;
339 }
340 n = (size - sizeof(*d)) / sizeof(*block);
341
342 gw_cmd = le32_to_cpu(d->command);
343
344 wil_dbg_fw(wil, "gw4 write record [%3d] blocks, cmd 0x%08x\n",
345 n, gw_cmd);
346
347 FW_ADDR_CHECK(gwa_addr, d->gateway_addr_addr, "gateway_addr_addr");
348 for (k = 0; k < ARRAY_SIZE(block->value); k++)
349 FW_ADDR_CHECK(gwa_val[k], d->gateway_value_addr[k],
350 "gateway_value_addr");
351 FW_ADDR_CHECK(gwa_cmd, d->gateway_cmd_addr, "gateway_cmd_addr");
352 FW_ADDR_CHECK(gwa_ctl, d->gateway_ctrl_address, "gateway_ctrl_address");
353
354 wil_dbg_fw(wil, "gw4 addresses: addr 0x%08x cmd 0x%08x ctl 0x%08x\n",
355 le32_to_cpu(d->gateway_addr_addr),
356 le32_to_cpu(d->gateway_cmd_addr),
357 le32_to_cpu(d->gateway_ctrl_address));
358 wil_hex_dump_fw("val addresses: ", DUMP_PREFIX_NONE, 16, 4,
359 d->gateway_value_addr, sizeof(d->gateway_value_addr),
360 false);
361
362 for (i = 0; i < n; i++) {
363 int rc;
364 u32 a = le32_to_cpu(block[i].addr);
365 u32 v[ARRAY_SIZE(block->value)];
366
367 for (k = 0; k < ARRAY_SIZE(block->value); k++)
368 v[k] = le32_to_cpu(block[i].value[k]);
369
370 wil_dbg_fw(wil, " gw4 write[%3d] [0x%08x] <==\n", i, a);
371 wil_hex_dump_fw(" val ", DUMP_PREFIX_NONE, 16, 4, v,
372 sizeof(v), false);
373
374 for (k = 0; k < ARRAY_SIZE(block->value); k++)
375 iowrite32(v[k], gwa_val[k]);
376 rc = gw_write(wil, gwa_addr, gwa_cmd, gwa_ctl, gw_cmd, a);
377 if (rc)
378 return rc;
379 }
380
381 return 0;
382}
383
384static const struct {
385 int type;
386 int (*handler)(struct wil6210_priv *wil, const void *data, size_t size);
387} wil_fw_handlers[] = {
388 {wil_fw_type_comment, fw_handle_comment},
389 {wil_fw_type_data, fw_handle_data},
390 {wil_fw_type_fill, fw_handle_fill},
391 /* wil_fw_type_action */
392 /* wil_fw_type_verify */
393 {wil_fw_type_file_header, fw_handle_file_header},
394 {wil_fw_type_direct_write, fw_handle_direct_write},
395 {wil_fw_type_gateway_data, fw_handle_gateway_data},
396 {wil_fw_type_gateway_data4, fw_handle_gateway_data4},
397};
398
399static int wil_fw_handle_record(struct wil6210_priv *wil, int type,
400 const void *data, size_t size)
401{
402 int i;
403
404 for (i = 0; i < ARRAY_SIZE(wil_fw_handlers); i++) {
405 if (wil_fw_handlers[i].type == type)
406 return wil_fw_handlers[i].handler(wil, data, size);
407 }
408
409 wil_err_fw(wil, "unknown record type: %d\n", type);
410 return -EINVAL;
411}
412
413/**
414 * wil_fw_load - load FW into device
415 *
416 * Load the FW and uCode code and data to the corresponding device
417 * memory regions
418 *
419 * Return error code
420 */
421static int wil_fw_load(struct wil6210_priv *wil, const void *data, size_t size)
422{
423 int rc = 0;
424 const struct wil_fw_record_head *hdr;
425 size_t s, hdr_sz;
426
427 for (hdr = data;; hdr = (const void *)hdr + s, size -= s) {
428 if (size < sizeof(*hdr))
429 break;
430 hdr_sz = le32_to_cpu(hdr->size);
431 s = sizeof(*hdr) + hdr_sz;
432 if (s > size)
433 break;
434 if (hdr_sz % 4) {
435 wil_err_fw(wil, "unaligned record size: %zu\n",
436 hdr_sz);
437 return -EINVAL;
438 }
439 rc = wil_fw_handle_record(wil, le16_to_cpu(hdr->type),
440 &hdr[1], hdr_sz);
441 if (rc)
442 return rc;
443 }
444 if (size) {
445 wil_err_fw(wil, "unprocessed bytes: %zu\n", size);
446 if (size >= sizeof(*hdr)) {
447 wil_err_fw(wil, "Stop at offset %ld"
448 " record type %d [%zd bytes]\n",
449 (const void *)hdr - data,
450 le16_to_cpu(hdr->type), hdr_sz);
451 }
452 return -EINVAL;
453 }
454 /* Mark FW as loaded from host */
455 S(RGF_USER_USAGE_6, 1);
456
457 return rc;
458}
459
460/**
461 * wil_request_firmware - Request firmware and load to device
462 *
463 * Request firmware image from the file and load it to device
464 *
465 * Return error code
466 */
467int wil_request_firmware(struct wil6210_priv *wil, const char *name)
468{
469 int rc, rc1;
470 const struct firmware *fw;
471 size_t sz;
472 const void *d;
473
474 rc = request_firmware(&fw, name, wil_to_pcie_dev(wil));
475 if (rc) {
476 wil_err_fw(wil, "Failed to load firmware %s\n", name);
477 return rc;
478 }
479 wil_dbg_fw(wil, "Loading <%s>, %zu bytes\n", name, fw->size);
480
481 for (sz = fw->size, d = fw->data; sz; sz -= rc1, d += rc1) {
482 rc1 = wil_fw_verify(wil, d, sz);
483 if (rc1 < 0) {
484 rc = rc1;
485 goto out;
486 }
487 rc = wil_fw_load(wil, d, rc1);
488 if (rc < 0)
489 goto out;
490 }
491
492out:
493 release_firmware(fw);
494 return rc;
495}
diff --git a/drivers/net/wireless/ath/wil6210/interrupt.c b/drivers/net/wireless/ath/wil6210/interrupt.c
index 98bfbb6390b7..7269bac111b9 100644
--- a/drivers/net/wireless/ath/wil6210/interrupt.c
+++ b/drivers/net/wireless/ath/wil6210/interrupt.c
@@ -135,7 +135,7 @@ static void wil6210_unmask_irq_pseudo(struct wil6210_priv *wil)
135 HOSTADDR(RGF_DMA_PSEUDO_CAUSE_MASK_SW)); 135 HOSTADDR(RGF_DMA_PSEUDO_CAUSE_MASK_SW));
136} 136}
137 137
138void wil6210_disable_irq(struct wil6210_priv *wil) 138void wil_mask_irq(struct wil6210_priv *wil)
139{ 139{
140 wil_dbg_irq(wil, "%s()\n", __func__); 140 wil_dbg_irq(wil, "%s()\n", __func__);
141 141
@@ -145,7 +145,7 @@ void wil6210_disable_irq(struct wil6210_priv *wil)
145 wil6210_mask_irq_pseudo(wil); 145 wil6210_mask_irq_pseudo(wil);
146} 146}
147 147
148void wil6210_enable_irq(struct wil6210_priv *wil) 148void wil_unmask_irq(struct wil6210_priv *wil)
149{ 149{
150 wil_dbg_irq(wil, "%s()\n", __func__); 150 wil_dbg_irq(wil, "%s()\n", __func__);
151 151
@@ -196,8 +196,13 @@ static irqreturn_t wil6210_irq_rx(int irq, void *cookie)
196 wil_dbg_irq(wil, "RX done\n"); 196 wil_dbg_irq(wil, "RX done\n");
197 isr &= ~BIT_DMA_EP_RX_ICR_RX_DONE; 197 isr &= ~BIT_DMA_EP_RX_ICR_RX_DONE;
198 if (test_bit(wil_status_reset_done, &wil->status)) { 198 if (test_bit(wil_status_reset_done, &wil->status)) {
199 wil_dbg_txrx(wil, "NAPI(Rx) schedule\n"); 199 if (test_bit(wil_status_napi_en, &wil->status)) {
200 napi_schedule(&wil->napi_rx); 200 wil_dbg_txrx(wil, "NAPI(Rx) schedule\n");
201 napi_schedule(&wil->napi_rx);
202 } else {
203 wil_err(wil, "Got Rx interrupt while "
204 "stopping interface\n");
205 }
201 } else { 206 } else {
202 wil_err(wil, "Got Rx interrupt while in reset\n"); 207 wil_err(wil, "Got Rx interrupt while in reset\n");
203 } 208 }
@@ -506,7 +511,8 @@ free0:
506 511
507 return rc; 512 return rc;
508} 513}
509/* can't use wil_ioread32_and_clear because ICC value is not ser yet */ 514
515/* can't use wil_ioread32_and_clear because ICC value is not set yet */
510static inline void wil_clear32(void __iomem *addr) 516static inline void wil_clear32(void __iomem *addr)
511{ 517{
512 u32 x = ioread32(addr); 518 u32 x = ioread32(addr);
@@ -522,11 +528,15 @@ void wil6210_clear_irq(struct wil6210_priv *wil)
522 offsetof(struct RGF_ICR, ICR)); 528 offsetof(struct RGF_ICR, ICR));
523 wil_clear32(wil->csr + HOSTADDR(RGF_DMA_EP_MISC_ICR) + 529 wil_clear32(wil->csr + HOSTADDR(RGF_DMA_EP_MISC_ICR) +
524 offsetof(struct RGF_ICR, ICR)); 530 offsetof(struct RGF_ICR, ICR));
531 wmb(); /* make sure write completed */
525} 532}
526 533
527int wil6210_init_irq(struct wil6210_priv *wil, int irq) 534int wil6210_init_irq(struct wil6210_priv *wil, int irq)
528{ 535{
529 int rc; 536 int rc;
537
538 wil_dbg_misc(wil, "%s() n_msi=%d\n", __func__, wil->n_msi);
539
530 if (wil->n_msi == 3) 540 if (wil->n_msi == 3)
531 rc = wil6210_request_3msi(wil, irq); 541 rc = wil6210_request_3msi(wil, irq);
532 else 542 else
@@ -534,17 +544,14 @@ int wil6210_init_irq(struct wil6210_priv *wil, int irq)
534 wil6210_thread_irq, 544 wil6210_thread_irq,
535 wil->n_msi ? 0 : IRQF_SHARED, 545 wil->n_msi ? 0 : IRQF_SHARED,
536 WIL_NAME, wil); 546 WIL_NAME, wil);
537 if (rc) 547 return rc;
538 return rc;
539
540 wil6210_enable_irq(wil);
541
542 return 0;
543} 548}
544 549
545void wil6210_fini_irq(struct wil6210_priv *wil, int irq) 550void wil6210_fini_irq(struct wil6210_priv *wil, int irq)
546{ 551{
547 wil6210_disable_irq(wil); 552 wil_dbg_misc(wil, "%s()\n", __func__);
553
554 wil_mask_irq(wil);
548 free_irq(irq, wil); 555 free_irq(irq, wil);
549 if (wil->n_msi == 3) { 556 if (wil->n_msi == 3) {
550 free_irq(irq + 1, wil); 557 free_irq(irq + 1, wil);
diff --git a/drivers/net/wireless/ath/wil6210/main.c b/drivers/net/wireless/ath/wil6210/main.c
index b69d90f0716f..21667e0c3d14 100644
--- a/drivers/net/wireless/ath/wil6210/main.c
+++ b/drivers/net/wireless/ath/wil6210/main.c
@@ -20,11 +20,19 @@
20 20
21#include "wil6210.h" 21#include "wil6210.h"
22#include "txrx.h" 22#include "txrx.h"
23#include "wmi.h"
24
25#define WAIT_FOR_DISCONNECT_TIMEOUT_MS 2000
26#define WAIT_FOR_DISCONNECT_INTERVAL_MS 10
23 27
24static bool no_fw_recovery; 28static bool no_fw_recovery;
25module_param(no_fw_recovery, bool, S_IRUGO | S_IWUSR); 29module_param(no_fw_recovery, bool, S_IRUGO | S_IWUSR);
26MODULE_PARM_DESC(no_fw_recovery, " disable FW error recovery"); 30MODULE_PARM_DESC(no_fw_recovery, " disable FW error recovery");
27 31
32static bool no_fw_load = true;
33module_param(no_fw_load, bool, S_IRUGO | S_IWUSR);
34MODULE_PARM_DESC(no_fw_load, " do not download FW, use one in on-card flash.");
35
28#define RST_DELAY (20) /* msec, for loop in @wil_target_reset */ 36#define RST_DELAY (20) /* msec, for loop in @wil_target_reset */
29#define RST_COUNT (1 + 1000/RST_DELAY) /* round up to be above 1 sec total */ 37#define RST_COUNT (1 + 1000/RST_DELAY) /* round up to be above 1 sec total */
30 38
@@ -67,6 +75,7 @@ static void wil_disconnect_cid(struct wil6210_priv *wil, int cid)
67 struct net_device *ndev = wil_to_ndev(wil); 75 struct net_device *ndev = wil_to_ndev(wil);
68 struct wireless_dev *wdev = wil->wdev; 76 struct wireless_dev *wdev = wil->wdev;
69 struct wil_sta_info *sta = &wil->sta[cid]; 77 struct wil_sta_info *sta = &wil->sta[cid];
78
70 wil_dbg_misc(wil, "%s(CID %d, status %d)\n", __func__, cid, 79 wil_dbg_misc(wil, "%s(CID %d, status %d)\n", __func__, cid,
71 sta->status); 80 sta->status);
72 81
@@ -86,9 +95,16 @@ static void wil_disconnect_cid(struct wil6210_priv *wil, int cid)
86 } 95 }
87 96
88 for (i = 0; i < WIL_STA_TID_NUM; i++) { 97 for (i = 0; i < WIL_STA_TID_NUM; i++) {
89 struct wil_tid_ampdu_rx *r = sta->tid_rx[i]; 98 struct wil_tid_ampdu_rx *r;
99 unsigned long flags;
100
101 spin_lock_irqsave(&sta->tid_rx_lock, flags);
102
103 r = sta->tid_rx[i];
90 sta->tid_rx[i] = NULL; 104 sta->tid_rx[i] = NULL;
91 wil_tid_ampdu_rx_free(wil, r); 105 wil_tid_ampdu_rx_free(wil, r);
106
107 spin_unlock_irqrestore(&sta->tid_rx_lock, flags);
92 } 108 }
93 for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++) { 109 for (i = 0; i < ARRAY_SIZE(wil->vring_tx); i++) {
94 if (wil->vring2cid_tid[i][0] == cid) 110 if (wil->vring2cid_tid[i][0] == cid)
@@ -205,10 +221,8 @@ static void wil_fw_error_worker(struct work_struct *work)
205 case NL80211_IFTYPE_MONITOR: 221 case NL80211_IFTYPE_MONITOR:
206 wil_info(wil, "fw error recovery started (try %d)...\n", 222 wil_info(wil, "fw error recovery started (try %d)...\n",
207 wil->recovery_count); 223 wil->recovery_count);
208 wil_reset(wil); 224 __wil_down(wil);
209 225 __wil_up(wil);
210 /* need to re-allocate Rx ring after reset */
211 wil_rx_init(wil);
212 break; 226 break;
213 case NL80211_IFTYPE_AP: 227 case NL80211_IFTYPE_AP:
214 case NL80211_IFTYPE_P2P_GO: 228 case NL80211_IFTYPE_P2P_GO:
@@ -223,6 +237,7 @@ static void wil_fw_error_worker(struct work_struct *work)
223static int wil_find_free_vring(struct wil6210_priv *wil) 237static int wil_find_free_vring(struct wil6210_priv *wil)
224{ 238{
225 int i; 239 int i;
240
226 for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) { 241 for (i = 0; i < WIL6210_MAX_TX_RINGS; i++) {
227 if (!wil->vring_tx[i].va) 242 if (!wil->vring_tx[i].va)
228 return i; 243 return i;
@@ -257,14 +272,19 @@ static void wil_connect_worker(struct work_struct *work)
257 272
258int wil_priv_init(struct wil6210_priv *wil) 273int wil_priv_init(struct wil6210_priv *wil)
259{ 274{
275 uint i;
276
260 wil_dbg_misc(wil, "%s()\n", __func__); 277 wil_dbg_misc(wil, "%s()\n", __func__);
261 278
262 memset(wil->sta, 0, sizeof(wil->sta)); 279 memset(wil->sta, 0, sizeof(wil->sta));
280 for (i = 0; i < WIL6210_MAX_CID; i++)
281 spin_lock_init(&wil->sta[i].tid_rx_lock);
263 282
264 mutex_init(&wil->mutex); 283 mutex_init(&wil->mutex);
265 mutex_init(&wil->wmi_mutex); 284 mutex_init(&wil->wmi_mutex);
266 285
267 init_completion(&wil->wmi_ready); 286 init_completion(&wil->wmi_ready);
287 init_completion(&wil->wmi_call);
268 288
269 wil->pending_connect_cid = -1; 289 wil->pending_connect_cid = -1;
270 setup_timer(&wil->connect_timer, wil_connect_timer_fn, (ulong)wil); 290 setup_timer(&wil->connect_timer, wil_connect_timer_fn, (ulong)wil);
@@ -295,12 +315,16 @@ int wil_priv_init(struct wil6210_priv *wil)
295 315
296void wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid) 316void wil6210_disconnect(struct wil6210_priv *wil, const u8 *bssid)
297{ 317{
318 wil_dbg_misc(wil, "%s()\n", __func__);
319
298 del_timer_sync(&wil->connect_timer); 320 del_timer_sync(&wil->connect_timer);
299 _wil6210_disconnect(wil, bssid); 321 _wil6210_disconnect(wil, bssid);
300} 322}
301 323
302void wil_priv_deinit(struct wil6210_priv *wil) 324void wil_priv_deinit(struct wil6210_priv *wil)
303{ 325{
326 wil_dbg_misc(wil, "%s()\n", __func__);
327
304 del_timer_sync(&wil->scan_timer); 328 del_timer_sync(&wil->scan_timer);
305 cancel_work_sync(&wil->disconnect_worker); 329 cancel_work_sync(&wil->disconnect_worker);
306 cancel_work_sync(&wil->fw_error_worker); 330 cancel_work_sync(&wil->fw_error_worker);
@@ -312,6 +336,28 @@ void wil_priv_deinit(struct wil6210_priv *wil)
312 destroy_workqueue(wil->wmi_wq); 336 destroy_workqueue(wil->wmi_wq);
313} 337}
314 338
339/* target operations */
340/* register read */
341#define R(a) ioread32(wil->csr + HOSTADDR(a))
342/* register write. wmb() to make sure it is completed */
343#define W(a, v) do { iowrite32(v, wil->csr + HOSTADDR(a)); wmb(); } while (0)
344/* register set = read, OR, write */
345#define S(a, v) W(a, R(a) | v)
346/* register clear = read, AND with inverted, write */
347#define C(a, v) W(a, R(a) & ~v)
348
349static inline void wil_halt_cpu(struct wil6210_priv *wil)
350{
351 W(RGF_USER_USER_CPU_0, BIT_USER_USER_CPU_MAN_RST);
352 W(RGF_USER_MAC_CPU_0, BIT_USER_MAC_CPU_MAN_RST);
353}
354
355static inline void wil_release_cpu(struct wil6210_priv *wil)
356{
357 /* Start CPU */
358 W(RGF_USER_USER_CPU_0, 1);
359}
360
315static int wil_target_reset(struct wil6210_priv *wil) 361static int wil_target_reset(struct wil6210_priv *wil)
316{ 362{
317 int delay = 0; 363 int delay = 0;
@@ -321,60 +367,41 @@ static int wil_target_reset(struct wil6210_priv *wil)
321 367
322 wil_dbg_misc(wil, "Resetting \"%s\"...\n", wil->board->name); 368 wil_dbg_misc(wil, "Resetting \"%s\"...\n", wil->board->name);
323 369
324 /* register read */
325#define R(a) ioread32(wil->csr + HOSTADDR(a))
326 /* register write */
327#define W(a, v) iowrite32(v, wil->csr + HOSTADDR(a))
328 /* register set = read, OR, write */
329#define S(a, v) W(a, R(a) | v)
330 /* register clear = read, AND with inverted, write */
331#define C(a, v) W(a, R(a) & ~v)
332
333 wmb(); /* If host reorder writes here -> race in NIC */
334 W(RGF_USER_MAC_CPU_0, BIT(1)); /* mac_cpu_man_rst */
335 wil->hw_version = R(RGF_USER_FW_REV_ID); 370 wil->hw_version = R(RGF_USER_FW_REV_ID);
336 rev_id = wil->hw_version & 0xff; 371 rev_id = wil->hw_version & 0xff;
337 372
338 /* Clear MAC link up */ 373 /* Clear MAC link up */
339 S(RGF_HP_CTRL, BIT(15)); 374 S(RGF_HP_CTRL, BIT(15));
340 /* hpal_perst_from_pad_src_n_mask */ 375 S(RGF_USER_CLKS_CTL_SW_RST_MASK_0, BIT_HPAL_PERST_FROM_PAD);
341 S(RGF_USER_CLKS_CTL_SW_RST_MASK_0, BIT(6)); 376 S(RGF_USER_CLKS_CTL_SW_RST_MASK_0, BIT_CAR_PERST_RST);
342 /* car_perst_rst_src_n_mask */ 377
343 S(RGF_USER_CLKS_CTL_SW_RST_MASK_0, BIT(7)); 378 wil_halt_cpu(wil);
344 wmb(); /* order is important here */ 379 C(RGF_USER_CLKS_CTL_0, BIT_USER_CLKS_CAR_AHB_SW_SEL); /* 40 MHz */
345 380
346 if (is_sparrow) { 381 if (is_sparrow) {
347 W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_0, 0x3ff81f); 382 W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_0, 0x3ff81f);
348 wmb(); /* order is important here */ 383 W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_1, 0xf);
349 } 384 }
350 385
351 W(RGF_USER_USER_CPU_0, BIT(1)); /* user_cpu_man_rst */
352 wmb(); /* If host reorder writes here -> race in NIC */
353 W(RGF_USER_MAC_CPU_0, BIT(1)); /* mac_cpu_man_rst */
354 wmb(); /* order is important here */
355
356 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0xFE000000); 386 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0xFE000000);
357 W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0x0000003F); 387 W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0x0000003F);
358 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, is_sparrow ? 0x000000B0 : 0x00000170); 388 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, is_sparrow ? 0x000000f0 : 0x00000170);
359 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0xFFE7FC00); 389 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0xFFE7FE00);
360 wmb(); /* order is important here */
361 390
362 if (is_sparrow) { 391 if (is_sparrow) {
363 W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_0, 0x0); 392 W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_0, 0x0);
364 wmb(); /* order is important here */ 393 W(RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_1, 0x0);
365 } 394 }
366 395
367 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0); 396 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0);
368 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0); 397 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0);
369 W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0); 398 W(RGF_USER_CLKS_CTL_SW_RST_VEC_1, 0);
370 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0); 399 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0);
371 wmb(); /* order is important here */
372 400
373 if (is_sparrow) { 401 if (is_sparrow) {
374 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000003); 402 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000003);
375 /* reset A2 PCIE AHB */ 403 /* reset A2 PCIE AHB */
376 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00008000); 404 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00008000);
377
378 } else { 405 } else {
379 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000001); 406 W(RGF_USER_CLKS_CTL_SW_RST_VEC_3, 0x00000001);
380 if (rev_id == 1) { 407 if (rev_id == 1) {
@@ -384,12 +411,10 @@ static int wil_target_reset(struct wil6210_priv *wil)
384 W(RGF_PCIE_LOS_COUNTER_CTL, BIT(6) | BIT(8)); 411 W(RGF_PCIE_LOS_COUNTER_CTL, BIT(6) | BIT(8));
385 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00008000); 412 W(RGF_USER_CLKS_CTL_SW_RST_VEC_2, 0x00008000);
386 } 413 }
387
388 } 414 }
389 415
390 /* TODO: check order here!!! Erez code is different */ 416 /* TODO: check order here!!! Erez code is different */
391 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0); 417 W(RGF_USER_CLKS_CTL_SW_RST_VEC_0, 0);
392 wmb(); /* order is important here */
393 418
394 /* wait until device ready. typical time is 200..250 msec */ 419 /* wait until device ready. typical time is 200..250 msec */
395 do { 420 do {
@@ -407,16 +432,15 @@ static int wil_target_reset(struct wil6210_priv *wil)
407 W(RGF_PCIE_LOS_COUNTER_CTL, BIT(8)); 432 W(RGF_PCIE_LOS_COUNTER_CTL, BIT(8));
408 433
409 C(RGF_USER_CLKS_CTL_0, BIT_USER_CLKS_RST_PWGD); 434 C(RGF_USER_CLKS_CTL_0, BIT_USER_CLKS_RST_PWGD);
410 wmb(); /* order is important here */
411 435
412 wil_dbg_misc(wil, "Reset completed in %d ms\n", delay * RST_DELAY); 436 wil_dbg_misc(wil, "Reset completed in %d ms\n", delay * RST_DELAY);
413 return 0; 437 return 0;
438}
414 439
415#undef R 440#undef R
416#undef W 441#undef W
417#undef S 442#undef S
418#undef C 443#undef C
419}
420 444
421void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r) 445void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r)
422{ 446{
@@ -431,6 +455,7 @@ static int wil_wait_for_fw_ready(struct wil6210_priv *wil)
431{ 455{
432 ulong to = msecs_to_jiffies(1000); 456 ulong to = msecs_to_jiffies(1000);
433 ulong left = wait_for_completion_timeout(&wil->wmi_ready, to); 457 ulong left = wait_for_completion_timeout(&wil->wmi_ready, to);
458
434 if (0 == left) { 459 if (0 == left) {
435 wil_err(wil, "Firmware not ready\n"); 460 wil_err(wil, "Firmware not ready\n");
436 return -ETIME; 461 return -ETIME;
@@ -450,15 +475,15 @@ int wil_reset(struct wil6210_priv *wil)
450{ 475{
451 int rc; 476 int rc;
452 477
478 wil_dbg_misc(wil, "%s()\n", __func__);
479
453 WARN_ON(!mutex_is_locked(&wil->mutex)); 480 WARN_ON(!mutex_is_locked(&wil->mutex));
481 WARN_ON(test_bit(wil_status_napi_en, &wil->status));
454 482
455 cancel_work_sync(&wil->disconnect_worker); 483 cancel_work_sync(&wil->disconnect_worker);
456 wil6210_disconnect(wil, NULL); 484 wil6210_disconnect(wil, NULL);
457 485
458 wil->status = 0; /* prevent NAPI from being scheduled */ 486 wil->status = 0; /* prevent NAPI from being scheduled */
459 if (test_bit(wil_status_napi_en, &wil->status)) {
460 napi_synchronize(&wil->napi_rx);
461 }
462 487
463 if (wil->scan_request) { 488 if (wil->scan_request) {
464 wil_dbg_misc(wil, "Abort scan_request 0x%p\n", 489 wil_dbg_misc(wil, "Abort scan_request 0x%p\n",
@@ -468,7 +493,7 @@ int wil_reset(struct wil6210_priv *wil)
468 wil->scan_request = NULL; 493 wil->scan_request = NULL;
469 } 494 }
470 495
471 wil6210_disable_irq(wil); 496 wil_mask_irq(wil);
472 497
473 wmi_event_flush(wil); 498 wmi_event_flush(wil);
474 499
@@ -480,13 +505,38 @@ int wil_reset(struct wil6210_priv *wil)
480 if (rc) 505 if (rc)
481 return rc; 506 return rc;
482 507
508 if (!no_fw_load) {
509 wil_info(wil, "Use firmware <%s>\n", WIL_FW_NAME);
510 wil_halt_cpu(wil);
511 /* Loading f/w from the file */
512 rc = wil_request_firmware(wil, WIL_FW_NAME);
513 if (rc)
514 return rc;
515
516 /* clear any interrupts which on-card-firmware may have set */
517 wil6210_clear_irq(wil);
518 { /* CAF_ICR - clear and mask */
519 u32 a = HOSTADDR(RGF_CAF_ICR) +
520 offsetof(struct RGF_ICR, ICR);
521 u32 m = HOSTADDR(RGF_CAF_ICR) +
522 offsetof(struct RGF_ICR, IMV);
523 u32 icr = ioread32(wil->csr + a);
524
525 iowrite32(icr, wil->csr + a); /* W1C */
526 iowrite32(~0, wil->csr + m);
527 wmb(); /* wait for completion */
528 }
529 wil_release_cpu(wil);
530 } else {
531 wil_info(wil, "Use firmware from on-card flash\n");
532 }
483 533
484 /* init after reset */ 534 /* init after reset */
485 wil->pending_connect_cid = -1; 535 wil->pending_connect_cid = -1;
486 reinit_completion(&wil->wmi_ready); 536 reinit_completion(&wil->wmi_ready);
537 reinit_completion(&wil->wmi_call);
487 538
488 /* TODO: release MAC reset */ 539 wil_unmask_irq(wil);
489 wil6210_enable_irq(wil);
490 540
491 /* we just started MAC, wait for FW ready */ 541 /* we just started MAC, wait for FW ready */
492 rc = wil_wait_for_fw_ready(wil); 542 rc = wil_wait_for_fw_ready(wil);
@@ -522,7 +572,7 @@ void wil_link_off(struct wil6210_priv *wil)
522 netif_carrier_off(ndev); 572 netif_carrier_off(ndev);
523} 573}
524 574
525static int __wil_up(struct wil6210_priv *wil) 575int __wil_up(struct wil6210_priv *wil)
526{ 576{
527 struct net_device *ndev = wil_to_ndev(wil); 577 struct net_device *ndev = wil_to_ndev(wil);
528 struct wireless_dev *wdev = wil->wdev; 578 struct wireless_dev *wdev = wil->wdev;
@@ -568,11 +618,15 @@ static int __wil_up(struct wil6210_priv *wil)
568 /* MAC address - pre-requisite for other commands */ 618 /* MAC address - pre-requisite for other commands */
569 wmi_set_mac_address(wil, ndev->dev_addr); 619 wmi_set_mac_address(wil, ndev->dev_addr);
570 620
571 621 wil_dbg_misc(wil, "NAPI enable\n");
572 napi_enable(&wil->napi_rx); 622 napi_enable(&wil->napi_rx);
573 napi_enable(&wil->napi_tx); 623 napi_enable(&wil->napi_tx);
574 set_bit(wil_status_napi_en, &wil->status); 624 set_bit(wil_status_napi_en, &wil->status);
575 625
626 if (wil->platform_ops.bus_request)
627 wil->platform_ops.bus_request(wil->platform_handle,
628 WIL_MAX_BUS_REQUEST_KBPS);
629
576 return 0; 630 return 0;
577} 631}
578 632
@@ -580,6 +634,8 @@ int wil_up(struct wil6210_priv *wil)
580{ 634{
581 int rc; 635 int rc;
582 636
637 wil_dbg_misc(wil, "%s()\n", __func__);
638
583 mutex_lock(&wil->mutex); 639 mutex_lock(&wil->mutex);
584 rc = __wil_up(wil); 640 rc = __wil_up(wil);
585 mutex_unlock(&wil->mutex); 641 mutex_unlock(&wil->mutex);
@@ -587,13 +643,23 @@ int wil_up(struct wil6210_priv *wil)
587 return rc; 643 return rc;
588} 644}
589 645
590static int __wil_down(struct wil6210_priv *wil) 646int __wil_down(struct wil6210_priv *wil)
591{ 647{
648 int iter = WAIT_FOR_DISCONNECT_TIMEOUT_MS /
649 WAIT_FOR_DISCONNECT_INTERVAL_MS;
650
592 WARN_ON(!mutex_is_locked(&wil->mutex)); 651 WARN_ON(!mutex_is_locked(&wil->mutex));
593 652
594 clear_bit(wil_status_napi_en, &wil->status); 653 if (wil->platform_ops.bus_request)
595 napi_disable(&wil->napi_rx); 654 wil->platform_ops.bus_request(wil->platform_handle, 0);
596 napi_disable(&wil->napi_tx); 655
656 wil_disable_irq(wil);
657 if (test_and_clear_bit(wil_status_napi_en, &wil->status)) {
658 napi_disable(&wil->napi_rx);
659 napi_disable(&wil->napi_tx);
660 wil_dbg_misc(wil, "NAPI disable\n");
661 }
662 wil_enable_irq(wil);
597 663
598 if (wil->scan_request) { 664 if (wil->scan_request) {
599 wil_dbg_misc(wil, "Abort scan_request 0x%p\n", 665 wil_dbg_misc(wil, "Abort scan_request 0x%p\n",
@@ -603,7 +669,24 @@ static int __wil_down(struct wil6210_priv *wil)
603 wil->scan_request = NULL; 669 wil->scan_request = NULL;
604 } 670 }
605 671
606 wil6210_disconnect(wil, NULL); 672 if (test_bit(wil_status_fwconnected, &wil->status) ||
673 test_bit(wil_status_fwconnecting, &wil->status))
674 wmi_send(wil, WMI_DISCONNECT_CMDID, NULL, 0);
675
676 /* make sure wil is idle (not connected) */
677 mutex_unlock(&wil->mutex);
678 while (iter--) {
679 int idle = !test_bit(wil_status_fwconnected, &wil->status) &&
680 !test_bit(wil_status_fwconnecting, &wil->status);
681 if (idle)
682 break;
683 msleep(WAIT_FOR_DISCONNECT_INTERVAL_MS);
684 }
685 mutex_lock(&wil->mutex);
686
687 if (!iter)
688 wil_err(wil, "timeout waiting for idle FW/HW\n");
689
607 wil_rx_fini(wil); 690 wil_rx_fini(wil);
608 691
609 return 0; 692 return 0;
@@ -613,6 +696,8 @@ int wil_down(struct wil6210_priv *wil)
613{ 696{
614 int rc; 697 int rc;
615 698
699 wil_dbg_misc(wil, "%s()\n", __func__);
700
616 mutex_lock(&wil->mutex); 701 mutex_lock(&wil->mutex);
617 rc = __wil_down(wil); 702 rc = __wil_down(wil);
618 mutex_unlock(&wil->mutex); 703 mutex_unlock(&wil->mutex);
diff --git a/drivers/net/wireless/ath/wil6210/netdev.c b/drivers/net/wireless/ath/wil6210/netdev.c
index a44c2b61be08..1c0c77d9a14f 100644
--- a/drivers/net/wireless/ath/wil6210/netdev.c
+++ b/drivers/net/wireless/ath/wil6210/netdev.c
@@ -17,11 +17,14 @@
17#include <linux/etherdevice.h> 17#include <linux/etherdevice.h>
18 18
19#include "wil6210.h" 19#include "wil6210.h"
20#include "txrx.h"
20 21
21static int wil_open(struct net_device *ndev) 22static int wil_open(struct net_device *ndev)
22{ 23{
23 struct wil6210_priv *wil = ndev_to_wil(ndev); 24 struct wil6210_priv *wil = ndev_to_wil(ndev);
24 25
26 wil_dbg_misc(wil, "%s()\n", __func__);
27
25 return wil_up(wil); 28 return wil_up(wil);
26} 29}
27 30
@@ -29,6 +32,8 @@ static int wil_stop(struct net_device *ndev)
29{ 32{
30 struct wil6210_priv *wil = ndev_to_wil(ndev); 33 struct wil6210_priv *wil = ndev_to_wil(ndev);
31 34
35 wil_dbg_misc(wil, "%s()\n", __func__);
36
32 return wil_down(wil); 37 return wil_down(wil);
33} 38}
34 39
@@ -36,8 +41,10 @@ static int wil_change_mtu(struct net_device *ndev, int new_mtu)
36{ 41{
37 struct wil6210_priv *wil = ndev_to_wil(ndev); 42 struct wil6210_priv *wil = ndev_to_wil(ndev);
38 43
39 if (new_mtu < 68 || new_mtu > IEEE80211_MAX_DATA_LEN_DMG) 44 if (new_mtu < 68 || new_mtu > (TX_BUF_LEN - ETH_HLEN)) {
45 wil_err(wil, "invalid MTU %d\n", new_mtu);
40 return -EINVAL; 46 return -EINVAL;
47 }
41 48
42 wil_dbg_misc(wil, "change MTU %d -> %d\n", ndev->mtu, new_mtu); 49 wil_dbg_misc(wil, "change MTU %d -> %d\n", ndev->mtu, new_mtu);
43 ndev->mtu = new_mtu; 50 ndev->mtu = new_mtu;
@@ -121,6 +128,8 @@ void *wil_if_alloc(struct device *dev, void __iomem *csr)
121 wil->csr = csr; 128 wil->csr = csr;
122 wil->wdev = wdev; 129 wil->wdev = wdev;
123 130
131 wil_dbg_misc(wil, "%s()\n", __func__);
132
124 rc = wil_priv_init(wil); 133 rc = wil_priv_init(wil);
125 if (rc) { 134 if (rc) {
126 dev_err(dev, "wil_priv_init failed\n"); 135 dev_err(dev, "wil_priv_init failed\n");
@@ -169,6 +178,8 @@ void wil_if_free(struct wil6210_priv *wil)
169{ 178{
170 struct net_device *ndev = wil_to_ndev(wil); 179 struct net_device *ndev = wil_to_ndev(wil);
171 180
181 wil_dbg_misc(wil, "%s()\n", __func__);
182
172 if (!ndev) 183 if (!ndev)
173 return; 184 return;
174 185
@@ -185,6 +196,8 @@ int wil_if_add(struct wil6210_priv *wil)
185 struct net_device *ndev = wil_to_ndev(wil); 196 struct net_device *ndev = wil_to_ndev(wil);
186 int rc; 197 int rc;
187 198
199 wil_dbg_misc(wil, "%s()\n", __func__);
200
188 rc = register_netdev(ndev); 201 rc = register_netdev(ndev);
189 if (rc < 0) { 202 if (rc < 0) {
190 dev_err(&ndev->dev, "Failed to register netdev: %d\n", rc); 203 dev_err(&ndev->dev, "Failed to register netdev: %d\n", rc);
@@ -200,5 +213,7 @@ void wil_if_remove(struct wil6210_priv *wil)
200{ 213{
201 struct net_device *ndev = wil_to_ndev(wil); 214 struct net_device *ndev = wil_to_ndev(wil);
202 215
216 wil_dbg_misc(wil, "%s()\n", __func__);
217
203 unregister_netdev(ndev); 218 unregister_netdev(ndev);
204} 219}
diff --git a/drivers/net/wireless/ath/wil6210/pcie_bus.c b/drivers/net/wireless/ath/wil6210/pcie_bus.c
index 38dcbea49d44..66626a8ee728 100644
--- a/drivers/net/wireless/ath/wil6210/pcie_bus.c
+++ b/drivers/net/wireless/ath/wil6210/pcie_bus.c
@@ -17,6 +17,7 @@
17#include <linux/module.h> 17#include <linux/module.h>
18#include <linux/pci.h> 18#include <linux/pci.h>
19#include <linux/moduleparam.h> 19#include <linux/moduleparam.h>
20#include <linux/interrupt.h>
20 21
21#include "wil6210.h" 22#include "wil6210.h"
22 23
@@ -30,6 +31,28 @@ static bool debug_fw; /* = false; */
30module_param(debug_fw, bool, S_IRUGO); 31module_param(debug_fw, bool, S_IRUGO);
31MODULE_PARM_DESC(debug_fw, " load driver if FW not ready. For FW debug"); 32MODULE_PARM_DESC(debug_fw, " load driver if FW not ready. For FW debug");
32 33
34void wil_disable_irq(struct wil6210_priv *wil)
35{
36 int irq = wil->pdev->irq;
37
38 disable_irq(irq);
39 if (wil->n_msi == 3) {
40 disable_irq(irq + 1);
41 disable_irq(irq + 2);
42 }
43}
44
45void wil_enable_irq(struct wil6210_priv *wil)
46{
47 int irq = wil->pdev->irq;
48
49 enable_irq(irq);
50 if (wil->n_msi == 3) {
51 enable_irq(irq + 1);
52 enable_irq(irq + 2);
53 }
54}
55
33/* Bus ops */ 56/* Bus ops */
34static int wil_if_pcie_enable(struct wil6210_priv *wil) 57static int wil_if_pcie_enable(struct wil6210_priv *wil)
35{ 58{
@@ -41,6 +64,8 @@ static int wil_if_pcie_enable(struct wil6210_priv *wil)
41 */ 64 */
42 int msi_only = pdev->msi_enabled; 65 int msi_only = pdev->msi_enabled;
43 66
67 wil_dbg_misc(wil, "%s()\n", __func__);
68
44 pdev->msi_enabled = 0; 69 pdev->msi_enabled = 0;
45 70
46 pci_set_master(pdev); 71 pci_set_master(pdev);
@@ -107,6 +132,8 @@ static int wil_if_pcie_disable(struct wil6210_priv *wil)
107{ 132{
108 struct pci_dev *pdev = wil->pdev; 133 struct pci_dev *pdev = wil->pdev;
109 134
135 wil_dbg_misc(wil, "%s()\n", __func__);
136
110 pci_clear_master(pdev); 137 pci_clear_master(pdev);
111 /* disable and release IRQ */ 138 /* disable and release IRQ */
112 wil6210_fini_irq(wil, pdev->irq); 139 wil6210_fini_irq(wil, pdev->irq);
@@ -180,6 +207,10 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
180 wil->board = board; 207 wil->board = board;
181 208
182 wil6210_clear_irq(wil); 209 wil6210_clear_irq(wil);
210
211 wil->platform_handle =
212 wil_platform_init(&pdev->dev, &wil->platform_ops);
213
183 /* FW should raise IRQ when ready */ 214 /* FW should raise IRQ when ready */
184 rc = wil_if_pcie_enable(wil); 215 rc = wil_if_pcie_enable(wil);
185 if (rc) { 216 if (rc) {
@@ -204,6 +235,8 @@ static int wil_pcie_probe(struct pci_dev *pdev, const struct pci_device_id *id)
204 bus_disable: 235 bus_disable:
205 wil_if_pcie_disable(wil); 236 wil_if_pcie_disable(wil);
206 if_free: 237 if_free:
238 if (wil->platform_ops.uninit)
239 wil->platform_ops.uninit(wil->platform_handle);
207 wil_if_free(wil); 240 wil_if_free(wil);
208 err_iounmap: 241 err_iounmap:
209 pci_iounmap(pdev, csr); 242 pci_iounmap(pdev, csr);
@@ -220,9 +253,13 @@ static void wil_pcie_remove(struct pci_dev *pdev)
220 struct wil6210_priv *wil = pci_get_drvdata(pdev); 253 struct wil6210_priv *wil = pci_get_drvdata(pdev);
221 void __iomem *csr = wil->csr; 254 void __iomem *csr = wil->csr;
222 255
256 wil_dbg_misc(wil, "%s()\n", __func__);
257
223 wil6210_debugfs_remove(wil); 258 wil6210_debugfs_remove(wil);
224 wil_if_pcie_disable(wil);
225 wil_if_remove(wil); 259 wil_if_remove(wil);
260 wil_if_pcie_disable(wil);
261 if (wil->platform_ops.uninit)
262 wil->platform_ops.uninit(wil->platform_handle);
226 wil_if_free(wil); 263 wil_if_free(wil);
227 pci_iounmap(pdev, csr); 264 pci_iounmap(pdev, csr);
228 pci_release_region(pdev, 0); 265 pci_release_region(pdev, 0);
diff --git a/drivers/net/wireless/ath/wil6210/rx_reorder.c b/drivers/net/wireless/ath/wil6210/rx_reorder.c
index 97c6a24716a1..489cb73d139b 100644
--- a/drivers/net/wireless/ath/wil6210/rx_reorder.c
+++ b/drivers/net/wireless/ath/wil6210/rx_reorder.c
@@ -98,22 +98,25 @@ void wil_rx_reorder(struct wil6210_priv *wil, struct sk_buff *skb)
98 int mid = wil_rxdesc_mid(d); 98 int mid = wil_rxdesc_mid(d);
99 u16 seq = wil_rxdesc_seq(d); 99 u16 seq = wil_rxdesc_seq(d);
100 struct wil_sta_info *sta = &wil->sta[cid]; 100 struct wil_sta_info *sta = &wil->sta[cid];
101 struct wil_tid_ampdu_rx *r = sta->tid_rx[tid]; 101 struct wil_tid_ampdu_rx *r;
102 u16 hseq; 102 u16 hseq;
103 int index; 103 int index;
104 unsigned long flags;
104 105
105 wil_dbg_txrx(wil, "MID %d CID %d TID %d Seq 0x%03x\n", 106 wil_dbg_txrx(wil, "MID %d CID %d TID %d Seq 0x%03x\n",
106 mid, cid, tid, seq); 107 mid, cid, tid, seq);
107 108
109 spin_lock_irqsave(&sta->tid_rx_lock, flags);
110
111 r = sta->tid_rx[tid];
108 if (!r) { 112 if (!r) {
113 spin_unlock_irqrestore(&sta->tid_rx_lock, flags);
109 wil_netif_rx_any(skb, ndev); 114 wil_netif_rx_any(skb, ndev);
110 return; 115 return;
111 } 116 }
112 117
113 hseq = r->head_seq_num; 118 hseq = r->head_seq_num;
114 119
115 spin_lock(&r->reorder_lock);
116
117 /** Due to the race between WMI events, where BACK establishment 120 /** Due to the race between WMI events, where BACK establishment
118 * reported, and data Rx, few packets may be pass up before reorder 121 * reported, and data Rx, few packets may be pass up before reorder
119 * buffer get allocated. Catch up by pretending SSN is what we 122 * buffer get allocated. Catch up by pretending SSN is what we
@@ -176,13 +179,14 @@ void wil_rx_reorder(struct wil6210_priv *wil, struct sk_buff *skb)
176 wil_reorder_release(wil, r); 179 wil_reorder_release(wil, r);
177 180
178out: 181out:
179 spin_unlock(&r->reorder_lock); 182 spin_unlock_irqrestore(&sta->tid_rx_lock, flags);
180} 183}
181 184
182struct wil_tid_ampdu_rx *wil_tid_ampdu_rx_alloc(struct wil6210_priv *wil, 185struct wil_tid_ampdu_rx *wil_tid_ampdu_rx_alloc(struct wil6210_priv *wil,
183 int size, u16 ssn) 186 int size, u16 ssn)
184{ 187{
185 struct wil_tid_ampdu_rx *r = kzalloc(sizeof(*r), GFP_KERNEL); 188 struct wil_tid_ampdu_rx *r = kzalloc(sizeof(*r), GFP_KERNEL);
189
186 if (!r) 190 if (!r)
187 return NULL; 191 return NULL;
188 192
@@ -197,7 +201,6 @@ struct wil_tid_ampdu_rx *wil_tid_ampdu_rx_alloc(struct wil6210_priv *wil,
197 return NULL; 201 return NULL;
198 } 202 }
199 203
200 spin_lock_init(&r->reorder_lock);
201 r->ssn = ssn; 204 r->ssn = ssn;
202 r->head_seq_num = ssn; 205 r->head_seq_num = ssn;
203 r->buf_size = size; 206 r->buf_size = size;
diff --git a/drivers/net/wireless/ath/wil6210/txrx.c b/drivers/net/wireless/ath/wil6210/txrx.c
index 9bd920d272bb..2936ef0c18cb 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.c
+++ b/drivers/net/wireless/ath/wil6210/txrx.c
@@ -52,6 +52,7 @@ static inline int wil_vring_is_full(struct vring *vring)
52{ 52{
53 return wil_vring_next_tail(vring) == vring->swhead; 53 return wil_vring_next_tail(vring) == vring->swhead;
54} 54}
55
55/* 56/*
56 * Available space in Tx Vring 57 * Available space in Tx Vring
57 */ 58 */
@@ -86,6 +87,8 @@ static int wil_vring_alloc(struct wil6210_priv *wil, struct vring *vring)
86 size_t sz = vring->size * sizeof(vring->va[0]); 87 size_t sz = vring->size * sizeof(vring->va[0]);
87 uint i; 88 uint i;
88 89
90 wil_dbg_misc(wil, "%s()\n", __func__);
91
89 BUILD_BUG_ON(sizeof(vring->va[0]) != 32); 92 BUILD_BUG_ON(sizeof(vring->va[0]) != 32);
90 93
91 vring->swhead = 0; 94 vring->swhead = 0;
@@ -110,7 +113,8 @@ static int wil_vring_alloc(struct wil6210_priv *wil, struct vring *vring)
110 * we can use any 113 * we can use any
111 */ 114 */
112 for (i = 0; i < vring->size; i++) { 115 for (i = 0; i < vring->size; i++) {
113 volatile struct vring_tx_desc *_d = &(vring->va[i].tx); 116 volatile struct vring_tx_desc *_d = &vring->va[i].tx;
117
114 _d->dma.status = TX_DMA_STATUS_DU; 118 _d->dma.status = TX_DMA_STATUS_DU;
115 } 119 }
116 120
@@ -125,6 +129,7 @@ static void wil_txdesc_unmap(struct device *dev, struct vring_tx_desc *d,
125{ 129{
126 dma_addr_t pa = wil_desc_addr(&d->dma.addr); 130 dma_addr_t pa = wil_desc_addr(&d->dma.addr);
127 u16 dmalen = le16_to_cpu(d->dma.length); 131 u16 dmalen = le16_to_cpu(d->dma.length);
132
128 switch (ctx->mapped_as) { 133 switch (ctx->mapped_as) {
129 case wil_mapped_as_single: 134 case wil_mapped_as_single:
130 dma_unmap_single(dev, pa, dmalen, DMA_TO_DEVICE); 135 dma_unmap_single(dev, pa, dmalen, DMA_TO_DEVICE);
@@ -143,6 +148,18 @@ static void wil_vring_free(struct wil6210_priv *wil, struct vring *vring,
143 struct device *dev = wil_to_dev(wil); 148 struct device *dev = wil_to_dev(wil);
144 size_t sz = vring->size * sizeof(vring->va[0]); 149 size_t sz = vring->size * sizeof(vring->va[0]);
145 150
151 if (tx) {
152 int vring_index = vring - wil->vring_tx;
153
154 wil_dbg_misc(wil, "free Tx vring %d [%d] 0x%p:%pad 0x%p\n",
155 vring_index, vring->size, vring->va,
156 &vring->pa, vring->ctx);
157 } else {
158 wil_dbg_misc(wil, "free Rx vring [%d] 0x%p:%pad 0x%p\n",
159 vring->size, vring->va,
160 &vring->pa, vring->ctx);
161 }
162
146 while (!wil_vring_is_empty(vring)) { 163 while (!wil_vring_is_empty(vring)) {
147 dma_addr_t pa; 164 dma_addr_t pa;
148 u16 dmalen; 165 u16 dmalen;
@@ -191,11 +208,12 @@ static int wil_vring_alloc_skb(struct wil6210_priv *wil, struct vring *vring,
191 struct device *dev = wil_to_dev(wil); 208 struct device *dev = wil_to_dev(wil);
192 unsigned int sz = RX_BUF_LEN; 209 unsigned int sz = RX_BUF_LEN;
193 struct vring_rx_desc dd, *d = &dd; 210 struct vring_rx_desc dd, *d = &dd;
194 volatile struct vring_rx_desc *_d = &(vring->va[i].rx); 211 volatile struct vring_rx_desc *_d = &vring->va[i].rx;
195 dma_addr_t pa; 212 dma_addr_t pa;
196 213
197 /* TODO align */ 214 /* TODO align */
198 struct sk_buff *skb = dev_alloc_skb(sz + headroom); 215 struct sk_buff *skb = dev_alloc_skb(sz + headroom);
216
199 if (unlikely(!skb)) 217 if (unlikely(!skb))
200 return -ENOMEM; 218 return -ENOMEM;
201 219
@@ -274,9 +292,11 @@ static void wil_rx_add_radiotap_header(struct wil6210_priv *wil,
274 */ 292 */
275 int len = min_t(int, 8 + sizeof(phy_data), 293 int len = min_t(int, 8 + sizeof(phy_data),
276 wil_rxdesc_phy_length(d)); 294 wil_rxdesc_phy_length(d));
295
277 if (len > 8) { 296 if (len > 8) {
278 void *p = skb_tail_pointer(skb); 297 void *p = skb_tail_pointer(skb);
279 void *pa = PTR_ALIGN(p, 8); 298 void *pa = PTR_ALIGN(p, 8);
299
280 if (skb_tailroom(skb) >= len + (pa - p)) { 300 if (skb_tailroom(skb) >= len + (pa - p)) {
281 phy_length = len - 8; 301 phy_length = len - 8;
282 memcpy(phy_data, pa, phy_length); 302 memcpy(phy_data, pa, phy_length);
@@ -372,13 +392,12 @@ static struct sk_buff *wil_vring_reap_rx(struct wil6210_priv *wil,
372 int cid; 392 int cid;
373 struct wil_net_stats *stats; 393 struct wil_net_stats *stats;
374 394
375
376 BUILD_BUG_ON(sizeof(struct vring_rx_desc) > sizeof(skb->cb)); 395 BUILD_BUG_ON(sizeof(struct vring_rx_desc) > sizeof(skb->cb));
377 396
378 if (wil_vring_is_empty(vring)) 397 if (wil_vring_is_empty(vring))
379 return NULL; 398 return NULL;
380 399
381 _d = &(vring->va[vring->swhead].rx); 400 _d = &vring->va[vring->swhead].rx;
382 if (!(_d->dma.status & RX_DMA_STATUS_DU)) { 401 if (!(_d->dma.status & RX_DMA_STATUS_DU)) {
383 /* it is not error, we just reached end of Rx done area */ 402 /* it is not error, we just reached end of Rx done area */
384 return NULL; 403 return NULL;
@@ -532,7 +551,7 @@ void wil_netif_rx_any(struct sk_buff *skb, struct net_device *ndev)
532 [GRO_NORMAL] = "GRO_NORMAL", 551 [GRO_NORMAL] = "GRO_NORMAL",
533 [GRO_DROP] = "GRO_DROP", 552 [GRO_DROP] = "GRO_DROP",
534 }; 553 };
535 wil_dbg_txrx(wil, "Rx complete %d bytes => %s,\n", 554 wil_dbg_txrx(wil, "Rx complete %d bytes => %s\n",
536 len, gro_res_str[rc]); 555 len, gro_res_str[rc]);
537 } 556 }
538} 557}
@@ -573,7 +592,6 @@ void wil_rx_handle(struct wil6210_priv *wil, int *quota)
573 else 592 else
574 wil_netif_rx_any(skb, ndev); 593 wil_netif_rx_any(skb, ndev);
575 } 594 }
576
577 } 595 }
578 wil_rx_refill(wil, v->size); 596 wil_rx_refill(wil, v->size);
579} 597}
@@ -583,6 +601,8 @@ int wil_rx_init(struct wil6210_priv *wil)
583 struct vring *vring = &wil->vring_rx; 601 struct vring *vring = &wil->vring_rx;
584 int rc; 602 int rc;
585 603
604 wil_dbg_misc(wil, "%s()\n", __func__);
605
586 if (vring->va) { 606 if (vring->va) {
587 wil_err(wil, "Rx ring already allocated\n"); 607 wil_err(wil, "Rx ring already allocated\n");
588 return -EINVAL; 608 return -EINVAL;
@@ -612,6 +632,8 @@ void wil_rx_fini(struct wil6210_priv *wil)
612{ 632{
613 struct vring *vring = &wil->vring_rx; 633 struct vring *vring = &wil->vring_rx;
614 634
635 wil_dbg_misc(wil, "%s()\n", __func__);
636
615 if (vring->va) 637 if (vring->va)
616 wil_vring_free(wil, vring, 0); 638 wil_vring_free(wil, vring, 0);
617} 639}
@@ -646,6 +668,9 @@ int wil_vring_init_tx(struct wil6210_priv *wil, int id, int size,
646 struct vring *vring = &wil->vring_tx[id]; 668 struct vring *vring = &wil->vring_tx[id];
647 struct vring_tx_data *txdata = &wil->vring_tx_data[id]; 669 struct vring_tx_data *txdata = &wil->vring_tx_data[id];
648 670
671 wil_dbg_misc(wil, "%s() max_mpdu_size %d\n", __func__,
672 cmd.vring_cfg.tx_sw_ring.max_mpdu_size);
673
649 if (vring->va) { 674 if (vring->va) {
650 wil_err(wil, "Tx ring [%d] already allocated\n", id); 675 wil_err(wil, "Tx ring [%d] already allocated\n", id);
651 rc = -EINVAL; 676 rc = -EINVAL;
@@ -695,6 +720,8 @@ void wil_vring_fini_tx(struct wil6210_priv *wil, int id)
695 if (!vring->va) 720 if (!vring->va)
696 return; 721 return;
697 722
723 wil_dbg_misc(wil, "%s() id=%d\n", __func__, id);
724
698 /* make sure NAPI won't touch this vring */ 725 /* make sure NAPI won't touch this vring */
699 wil->vring_tx_data[id].enabled = 0; 726 wil->vring_tx_data[id].enabled = 0;
700 if (test_bit(wil_status_napi_en, &wil->status)) 727 if (test_bit(wil_status_napi_en, &wil->status))
@@ -721,6 +748,7 @@ static struct vring *wil_find_tx_vring(struct wil6210_priv *wil,
721 for (i = 0; i < ARRAY_SIZE(wil->vring2cid_tid); i++) { 748 for (i = 0; i < ARRAY_SIZE(wil->vring2cid_tid); i++) {
722 if (wil->vring2cid_tid[i][0] == cid) { 749 if (wil->vring2cid_tid[i][0] == cid) {
723 struct vring *v = &wil->vring_tx[i]; 750 struct vring *v = &wil->vring_tx[i];
751
724 wil_dbg_txrx(wil, "%s(%pM) -> [%d]\n", 752 wil_dbg_txrx(wil, "%s(%pM) -> [%d]\n",
725 __func__, eth->h_dest, i); 753 __func__, eth->h_dest, i);
726 if (v->va) { 754 if (v->va) {
@@ -740,6 +768,7 @@ static void wil_set_da_for_vring(struct wil6210_priv *wil,
740{ 768{
741 struct ethhdr *eth = (void *)skb->data; 769 struct ethhdr *eth = (void *)skb->data;
742 int cid = wil->vring2cid_tid[vring_index][0]; 770 int cid = wil->vring2cid_tid[vring_index][0];
771
743 memcpy(eth->h_dest, wil->sta[cid].addr, ETH_ALEN); 772 memcpy(eth->h_dest, wil->sta[cid].addr, ETH_ALEN);
744} 773}
745 774
@@ -750,7 +779,7 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
750 * duplicate skb and send it to other active vrings 779 * duplicate skb and send it to other active vrings
751 */ 780 */
752static struct vring *wil_tx_bcast(struct wil6210_priv *wil, 781static struct vring *wil_tx_bcast(struct wil6210_priv *wil,
753 struct sk_buff *skb) 782 struct sk_buff *skb)
754{ 783{
755 struct vring *v, *v2; 784 struct vring *v, *v2;
756 struct sk_buff *skb2; 785 struct sk_buff *skb2;
@@ -833,8 +862,8 @@ void wil_tx_desc_set_nr_frags(struct vring_tx_desc *d, int nr_frags)
833} 862}
834 863
835static int wil_tx_desc_offload_cksum_set(struct wil6210_priv *wil, 864static int wil_tx_desc_offload_cksum_set(struct wil6210_priv *wil,
836 struct vring_tx_desc *d, 865 struct vring_tx_desc *d,
837 struct sk_buff *skb) 866 struct sk_buff *skb)
838{ 867{
839 int protocol; 868 int protocol;
840 869
@@ -902,10 +931,9 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
902 1 + nr_frags); 931 1 + nr_frags);
903 return -ENOMEM; 932 return -ENOMEM;
904 } 933 }
905 _d = &(vring->va[i].tx); 934 _d = &vring->va[i].tx;
906 935
907 pa = dma_map_single(dev, skb->data, 936 pa = dma_map_single(dev, skb->data, skb_headlen(skb), DMA_TO_DEVICE);
908 skb_headlen(skb), DMA_TO_DEVICE);
909 937
910 wil_dbg_txrx(wil, "Tx skb %d bytes 0x%p -> %pad\n", skb_headlen(skb), 938 wil_dbg_txrx(wil, "Tx skb %d bytes 0x%p -> %pad\n", skb_headlen(skb),
911 skb->data, &pa); 939 skb->data, &pa);
@@ -934,10 +962,11 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
934 const struct skb_frag_struct *frag = 962 const struct skb_frag_struct *frag =
935 &skb_shinfo(skb)->frags[f]; 963 &skb_shinfo(skb)->frags[f];
936 int len = skb_frag_size(frag); 964 int len = skb_frag_size(frag);
965
937 i = (swhead + f + 1) % vring->size; 966 i = (swhead + f + 1) % vring->size;
938 _d = &(vring->va[i].tx); 967 _d = &vring->va[i].tx;
939 pa = skb_frag_dma_map(dev, frag, 0, skb_frag_size(frag), 968 pa = skb_frag_dma_map(dev, frag, 0, skb_frag_size(frag),
940 DMA_TO_DEVICE); 969 DMA_TO_DEVICE);
941 if (unlikely(dma_mapping_error(dev, pa))) 970 if (unlikely(dma_mapping_error(dev, pa)))
942 goto dma_error; 971 goto dma_error;
943 vring->ctx[i].mapped_as = wil_mapped_as_page; 972 vring->ctx[i].mapped_as = wil_mapped_as_page;
@@ -982,7 +1011,7 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
982 1011
983 i = (swhead + f) % vring->size; 1012 i = (swhead + f) % vring->size;
984 ctx = &vring->ctx[i]; 1013 ctx = &vring->ctx[i];
985 _d = &(vring->va[i].tx); 1014 _d = &vring->va[i].tx;
986 *d = *_d; 1015 *d = *_d;
987 _d->dma.status = TX_DMA_STATUS_DU; 1016 _d->dma.status = TX_DMA_STATUS_DU;
988 wil_txdesc_unmap(dev, d, ctx); 1017 wil_txdesc_unmap(dev, d, ctx);
@@ -996,7 +1025,6 @@ static int wil_tx_vring(struct wil6210_priv *wil, struct vring *vring,
996 return -EINVAL; 1025 return -EINVAL;
997} 1026}
998 1027
999
1000netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev) 1028netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
1001{ 1029{
1002 struct wil6210_priv *wil = ndev_to_wil(ndev); 1030 struct wil6210_priv *wil = ndev_to_wil(ndev);
@@ -1024,15 +1052,15 @@ netdev_tx_t wil_start_xmit(struct sk_buff *skb, struct net_device *ndev)
1024 pr_once_fw = false; 1052 pr_once_fw = false;
1025 1053
1026 /* find vring */ 1054 /* find vring */
1027 if (is_unicast_ether_addr(eth->h_dest)) { 1055 if (is_unicast_ether_addr(eth->h_dest))
1028 vring = wil_find_tx_vring(wil, skb); 1056 vring = wil_find_tx_vring(wil, skb);
1029 } else { 1057 else
1030 vring = wil_tx_bcast(wil, skb); 1058 vring = wil_tx_bcast(wil, skb);
1031 }
1032 if (!vring) { 1059 if (!vring) {
1033 wil_dbg_txrx(wil, "No Tx VRING found for %pM\n", eth->h_dest); 1060 wil_dbg_txrx(wil, "No Tx VRING found for %pM\n", eth->h_dest);
1034 goto drop; 1061 goto drop;
1035 } 1062 }
1063
1036 /* set up vring entry */ 1064 /* set up vring entry */
1037 rc = wil_tx_vring(wil, vring, skb); 1065 rc = wil_tx_vring(wil, vring, skb);
1038 1066
diff --git a/drivers/net/wireless/ath/wil6210/txrx.h b/drivers/net/wireless/ath/wil6210/txrx.h
index a1ac4f87d47b..de046716d2b7 100644
--- a/drivers/net/wireless/ath/wil6210/txrx.h
+++ b/drivers/net/wireless/ath/wil6210/txrx.h
@@ -20,9 +20,9 @@
20#define BUF_SW_OWNED (1) 20#define BUF_SW_OWNED (1)
21#define BUF_HW_OWNED (0) 21#define BUF_HW_OWNED (0)
22 22
23/* size of max. Rx packet */ 23/* size of max. Tx/Rx buffers, as supported by FW */
24#define RX_BUF_LEN (2048) 24#define RX_BUF_LEN (2242)
25#define TX_BUF_LEN (2048) 25#define TX_BUF_LEN (2242)
26/* how many bytes to reserve for rtap header? */ 26/* how many bytes to reserve for rtap header? */
27#define WIL6210_RTAP_SIZE (128) 27#define WIL6210_RTAP_SIZE (128)
28 28
@@ -237,7 +237,6 @@ struct vring_tx_mac {
237#define DMA_CFG_DESC_TX_0_L4_TYPE_LEN 2 237#define DMA_CFG_DESC_TX_0_L4_TYPE_LEN 2
238#define DMA_CFG_DESC_TX_0_L4_TYPE_MSK 0xC0000000 /* L4 type: 0-UDP, 2-TCP */ 238#define DMA_CFG_DESC_TX_0_L4_TYPE_MSK 0xC0000000 /* L4 type: 0-UDP, 2-TCP */
239 239
240
241#define DMA_CFG_DESC_TX_OFFLOAD_CFG_MAC_LEN_POS 0 240#define DMA_CFG_DESC_TX_OFFLOAD_CFG_MAC_LEN_POS 0
242#define DMA_CFG_DESC_TX_OFFLOAD_CFG_MAC_LEN_LEN 7 241#define DMA_CFG_DESC_TX_OFFLOAD_CFG_MAC_LEN_LEN 7
243#define DMA_CFG_DESC_TX_OFFLOAD_CFG_MAC_LEN_MSK 0x7F /* MAC hdr len */ 242#define DMA_CFG_DESC_TX_OFFLOAD_CFG_MAC_LEN_MSK 0x7F /* MAC hdr len */
@@ -246,7 +245,6 @@ struct vring_tx_mac {
246#define DMA_CFG_DESC_TX_OFFLOAD_CFG_L3T_IPV4_LEN 1 245#define DMA_CFG_DESC_TX_OFFLOAD_CFG_L3T_IPV4_LEN 1
247#define DMA_CFG_DESC_TX_OFFLOAD_CFG_L3T_IPV4_MSK 0x80 /* 1-IPv4, 0-IPv6 */ 246#define DMA_CFG_DESC_TX_OFFLOAD_CFG_L3T_IPV4_MSK 0x80 /* 1-IPv4, 0-IPv6 */
248 247
249
250#define TX_DMA_STATUS_DU BIT(0) 248#define TX_DMA_STATUS_DU BIT(0)
251 249
252struct vring_tx_dma { 250struct vring_tx_dma {
@@ -347,7 +345,6 @@ struct vring_rx_mac {
347#define RX_DMA_ERROR_L3_ERR BIT(4) 345#define RX_DMA_ERROR_L3_ERR BIT(4)
348#define RX_DMA_ERROR_L4_ERR BIT(5) 346#define RX_DMA_ERROR_L4_ERR BIT(5)
349 347
350
351/* Status field */ 348/* Status field */
352#define RX_DMA_STATUS_DU BIT(0) 349#define RX_DMA_STATUS_DU BIT(0)
353#define RX_DMA_STATUS_ERROR BIT(2) 350#define RX_DMA_STATUS_ERROR BIT(2)
diff --git a/drivers/net/wireless/ath/wil6210/wil6210.h b/drivers/net/wireless/ath/wil6210/wil6210.h
index f8718fe547c4..41aa79327584 100644
--- a/drivers/net/wireless/ath/wil6210/wil6210.h
+++ b/drivers/net/wireless/ath/wil6210/wil6210.h
@@ -21,8 +21,13 @@
21#include <linux/wireless.h> 21#include <linux/wireless.h>
22#include <net/cfg80211.h> 22#include <net/cfg80211.h>
23#include <linux/timex.h> 23#include <linux/timex.h>
24#include "wil_platform.h"
25
24 26
25#define WIL_NAME "wil6210" 27#define WIL_NAME "wil6210"
28#define WIL_FW_NAME "wil6210.fw"
29
30#define WIL_MAX_BUS_REQUEST_KBPS 800000 /* ~6.1Gbps */
26 31
27struct wil_board { 32struct wil_board {
28 int board; 33 int board;
@@ -86,22 +91,29 @@ struct RGF_ICR {
86 91
87/* registers - FW addresses */ 92/* registers - FW addresses */
88#define RGF_USER_USAGE_1 (0x880004) 93#define RGF_USER_USAGE_1 (0x880004)
94#define RGF_USER_USAGE_6 (0x880018)
89#define RGF_USER_HW_MACHINE_STATE (0x8801dc) 95#define RGF_USER_HW_MACHINE_STATE (0x8801dc)
90 #define HW_MACHINE_BOOT_DONE (0x3fffffd) 96 #define HW_MACHINE_BOOT_DONE (0x3fffffd)
91#define RGF_USER_USER_CPU_0 (0x8801e0) 97#define RGF_USER_USER_CPU_0 (0x8801e0)
98 #define BIT_USER_USER_CPU_MAN_RST BIT(1) /* user_cpu_man_rst */
92#define RGF_USER_MAC_CPU_0 (0x8801fc) 99#define RGF_USER_MAC_CPU_0 (0x8801fc)
100 #define BIT_USER_MAC_CPU_MAN_RST BIT(1) /* mac_cpu_man_rst */
93#define RGF_USER_USER_SCRATCH_PAD (0x8802bc) 101#define RGF_USER_USER_SCRATCH_PAD (0x8802bc)
94#define RGF_USER_FW_REV_ID (0x880a8c) /* chip revision */ 102#define RGF_USER_FW_REV_ID (0x880a8c) /* chip revision */
95#define RGF_USER_CLKS_CTL_0 (0x880abc) 103#define RGF_USER_CLKS_CTL_0 (0x880abc)
104 #define BIT_USER_CLKS_CAR_AHB_SW_SEL BIT(1) /* ref clk/PLL */
96 #define BIT_USER_CLKS_RST_PWGD BIT(11) /* reset on "power good" */ 105 #define BIT_USER_CLKS_RST_PWGD BIT(11) /* reset on "power good" */
97#define RGF_USER_CLKS_CTL_SW_RST_VEC_0 (0x880b04) 106#define RGF_USER_CLKS_CTL_SW_RST_VEC_0 (0x880b04)
98#define RGF_USER_CLKS_CTL_SW_RST_VEC_1 (0x880b08) 107#define RGF_USER_CLKS_CTL_SW_RST_VEC_1 (0x880b08)
99#define RGF_USER_CLKS_CTL_SW_RST_VEC_2 (0x880b0c) 108#define RGF_USER_CLKS_CTL_SW_RST_VEC_2 (0x880b0c)
100#define RGF_USER_CLKS_CTL_SW_RST_VEC_3 (0x880b10) 109#define RGF_USER_CLKS_CTL_SW_RST_VEC_3 (0x880b10)
101#define RGF_USER_CLKS_CTL_SW_RST_MASK_0 (0x880b14) 110#define RGF_USER_CLKS_CTL_SW_RST_MASK_0 (0x880b14)
111 #define BIT_HPAL_PERST_FROM_PAD BIT(6)
112 #define BIT_CAR_PERST_RST BIT(7)
102#define RGF_USER_USER_ICR (0x880b4c) /* struct RGF_ICR */ 113#define RGF_USER_USER_ICR (0x880b4c) /* struct RGF_ICR */
103 #define BIT_USER_USER_ICR_SW_INT_2 BIT(18) 114 #define BIT_USER_USER_ICR_SW_INT_2 BIT(18)
104#define RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_0 (0x880c18) 115#define RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_0 (0x880c18)
116#define RGF_USER_CLKS_CTL_EXT_SW_RST_VEC_1 (0x880c2c)
105 117
106#define RGF_DMA_EP_TX_ICR (0x881bb4) /* struct RGF_ICR */ 118#define RGF_DMA_EP_TX_ICR (0x881bb4) /* struct RGF_ICR */
107 #define BIT_DMA_EP_TX_ICR_TX_DONE BIT(0) 119 #define BIT_DMA_EP_TX_ICR_TX_DONE BIT(0)
@@ -136,6 +148,8 @@ struct RGF_ICR {
136/* MAC timer, usec, for packet lifetime */ 148/* MAC timer, usec, for packet lifetime */
137#define RGF_MAC_MTRL_COUNTER_0 (0x886aa8) 149#define RGF_MAC_MTRL_COUNTER_0 (0x886aa8)
138 150
151#define RGF_CAF_ICR (0x88946c) /* struct RGF_ICR */
152
139/* popular locations */ 153/* popular locations */
140#define HOST_MBOX HOSTADDR(RGF_USER_USER_SCRATCH_PAD) 154#define HOST_MBOX HOSTADDR(RGF_USER_USER_SCRATCH_PAD)
141#define HOST_SW_INT (HOSTADDR(RGF_USER_USER_ICR) + \ 155#define HOST_SW_INT (HOSTADDR(RGF_USER_USER_ICR) + \
@@ -154,6 +168,7 @@ struct fw_map {
154 u32 host; /* PCI/Host address - BAR0 + 0x880000 */ 168 u32 host; /* PCI/Host address - BAR0 + 0x880000 */
155 const char *name; /* for debugfs */ 169 const char *name; /* for debugfs */
156}; 170};
171
157/* array size should be in sync with actual definition in the wmi.c */ 172/* array size should be in sync with actual definition in the wmi.c */
158extern const struct fw_map fw_mapping[7]; 173extern const struct fw_map fw_mapping[7];
159 174
@@ -303,18 +318,12 @@ struct pci_dev;
303 * @timeout: reset timer value (in TUs). 318 * @timeout: reset timer value (in TUs).
304 * @dialog_token: dialog token for aggregation session 319 * @dialog_token: dialog token for aggregation session
305 * @rcu_head: RCU head used for freeing this struct 320 * @rcu_head: RCU head used for freeing this struct
306 * @reorder_lock: serializes access to reorder buffer, see below.
307 * 321 *
308 * This structure's lifetime is managed by RCU, assignments to 322 * This structure's lifetime is managed by RCU, assignments to
309 * the array holding it must hold the aggregation mutex. 323 * the array holding it must hold the aggregation mutex.
310 * 324 *
311 * The @reorder_lock is used to protect the members of this
312 * struct, except for @timeout, @buf_size and @dialog_token,
313 * which are constant across the lifetime of the struct (the
314 * dialog token being used only for debugging).
315 */ 325 */
316struct wil_tid_ampdu_rx { 326struct wil_tid_ampdu_rx {
317 spinlock_t reorder_lock; /* see above */
318 struct sk_buff **reorder_buf; 327 struct sk_buff **reorder_buf;
319 unsigned long *reorder_time; 328 unsigned long *reorder_time;
320 struct timer_list session_timer; 329 struct timer_list session_timer;
@@ -363,6 +372,7 @@ struct wil_sta_info {
363 bool data_port_open; /* can send any data, not only EAPOL */ 372 bool data_port_open; /* can send any data, not only EAPOL */
364 /* Rx BACK */ 373 /* Rx BACK */
365 struct wil_tid_ampdu_rx *tid_rx[WIL_STA_TID_NUM]; 374 struct wil_tid_ampdu_rx *tid_rx[WIL_STA_TID_NUM];
375 spinlock_t tid_rx_lock; /* guarding tid_rx array */
366 unsigned long tid_rx_timer_expired[BITS_TO_LONGS(WIL_STA_TID_NUM)]; 376 unsigned long tid_rx_timer_expired[BITS_TO_LONGS(WIL_STA_TID_NUM)];
367 unsigned long tid_rx_stop_requested[BITS_TO_LONGS(WIL_STA_TID_NUM)]; 377 unsigned long tid_rx_stop_requested[BITS_TO_LONGS(WIL_STA_TID_NUM)];
368}; 378};
@@ -389,6 +399,7 @@ struct wil6210_priv {
389 struct mutex wmi_mutex; 399 struct mutex wmi_mutex;
390 struct wil6210_mbox_ctl mbox_ctl; 400 struct wil6210_mbox_ctl mbox_ctl;
391 struct completion wmi_ready; 401 struct completion wmi_ready;
402 struct completion wmi_call;
392 u16 wmi_seq; 403 u16 wmi_seq;
393 u16 reply_id; /**< wait for this WMI event */ 404 u16 reply_id; /**< wait for this WMI event */
394 void *reply_buf; 405 void *reply_buf;
@@ -426,6 +437,9 @@ struct wil6210_priv {
426 /* debugfs */ 437 /* debugfs */
427 struct dentry *debug; 438 struct dentry *debug;
428 struct debugfs_blob_wrapper blobs[ARRAY_SIZE(fw_mapping)]; 439 struct debugfs_blob_wrapper blobs[ARRAY_SIZE(fw_mapping)];
440
441 void *platform_handle;
442 struct wil_platform_ops platform_ops;
429}; 443};
430 444
431#define wil_to_wiphy(i) (i->wdev->wiphy) 445#define wil_to_wiphy(i) (i->wdev->wiphy)
@@ -435,10 +449,11 @@ struct wil6210_priv {
435#define wdev_to_wil(w) (struct wil6210_priv *)(wdev_priv(w)) 449#define wdev_to_wil(w) (struct wil6210_priv *)(wdev_priv(w))
436#define wil_to_ndev(i) (wil_to_wdev(i)->netdev) 450#define wil_to_ndev(i) (wil_to_wdev(i)->netdev)
437#define ndev_to_wil(n) (wdev_to_wil(n->ieee80211_ptr)) 451#define ndev_to_wil(n) (wdev_to_wil(n->ieee80211_ptr))
452#define wil_to_pcie_dev(i) (&i->pdev->dev)
438 453
439int wil_dbg_trace(struct wil6210_priv *wil, const char *fmt, ...); 454void wil_dbg_trace(struct wil6210_priv *wil, const char *fmt, ...);
440int wil_err(struct wil6210_priv *wil, const char *fmt, ...); 455void wil_err(struct wil6210_priv *wil, const char *fmt, ...);
441int wil_info(struct wil6210_priv *wil, const char *fmt, ...); 456void wil_info(struct wil6210_priv *wil, const char *fmt, ...);
442#define wil_dbg(wil, fmt, arg...) do { \ 457#define wil_dbg(wil, fmt, arg...) do { \
443 netdev_dbg(wil_to_ndev(wil), fmt, ##arg); \ 458 netdev_dbg(wil_to_ndev(wil), fmt, ##arg); \
444 wil_dbg_trace(wil, fmt, ##arg); \ 459 wil_dbg_trace(wil, fmt, ##arg); \
@@ -449,6 +464,7 @@ int wil_info(struct wil6210_priv *wil, const char *fmt, ...);
449#define wil_dbg_wmi(wil, fmt, arg...) wil_dbg(wil, "DBG[ WMI]" fmt, ##arg) 464#define wil_dbg_wmi(wil, fmt, arg...) wil_dbg(wil, "DBG[ WMI]" fmt, ##arg)
450#define wil_dbg_misc(wil, fmt, arg...) wil_dbg(wil, "DBG[MISC]" fmt, ##arg) 465#define wil_dbg_misc(wil, fmt, arg...) wil_dbg(wil, "DBG[MISC]" fmt, ##arg)
451 466
467#if defined(CONFIG_DYNAMIC_DEBUG)
452#define wil_hex_dump_txrx(prefix_str, prefix_type, rowsize, \ 468#define wil_hex_dump_txrx(prefix_str, prefix_type, rowsize, \
453 groupsize, buf, len, ascii) \ 469 groupsize, buf, len, ascii) \
454 print_hex_dump_debug("DBG[TXRX]" prefix_str,\ 470 print_hex_dump_debug("DBG[TXRX]" prefix_str,\
@@ -460,6 +476,19 @@ int wil_info(struct wil6210_priv *wil, const char *fmt, ...);
460 print_hex_dump_debug("DBG[ WMI]" prefix_str,\ 476 print_hex_dump_debug("DBG[ WMI]" prefix_str,\
461 prefix_type, rowsize, \ 477 prefix_type, rowsize, \
462 groupsize, buf, len, ascii) 478 groupsize, buf, len, ascii)
479#else /* defined(CONFIG_DYNAMIC_DEBUG) */
480static inline
481void wil_hex_dump_txrx(const char *prefix_str, int prefix_type, int rowsize,
482 int groupsize, const void *buf, size_t len, bool ascii)
483{
484}
485
486static inline
487void wil_hex_dump_wmi(const char *prefix_str, int prefix_type, int rowsize,
488 int groupsize, const void *buf, size_t len, bool ascii)
489{
490}
491#endif /* defined(CONFIG_DYNAMIC_DEBUG) */
463 492
464void wil_memcpy_fromio_32(void *dst, const volatile void __iomem *src, 493void wil_memcpy_fromio_32(void *dst, const volatile void __iomem *src,
465 size_t count); 494 size_t count);
@@ -477,7 +506,9 @@ void wil_fw_error_recovery(struct wil6210_priv *wil);
477void wil_link_on(struct wil6210_priv *wil); 506void wil_link_on(struct wil6210_priv *wil);
478void wil_link_off(struct wil6210_priv *wil); 507void wil_link_off(struct wil6210_priv *wil);
479int wil_up(struct wil6210_priv *wil); 508int wil_up(struct wil6210_priv *wil);
509int __wil_up(struct wil6210_priv *wil);
480int wil_down(struct wil6210_priv *wil); 510int wil_down(struct wil6210_priv *wil);
511int __wil_down(struct wil6210_priv *wil);
481void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r); 512void wil_mbox_ring_le2cpus(struct wil6210_mbox_ring *r);
482int wil_find_cid(struct wil6210_priv *wil, const u8 *mac); 513int wil_find_cid(struct wil6210_priv *wil, const u8 *mac);
483 514
@@ -510,8 +541,10 @@ int wmi_disconnect_sta(struct wil6210_priv *wil, const u8 *mac, u16 reason);
510void wil6210_clear_irq(struct wil6210_priv *wil); 541void wil6210_clear_irq(struct wil6210_priv *wil);
511int wil6210_init_irq(struct wil6210_priv *wil, int irq); 542int wil6210_init_irq(struct wil6210_priv *wil, int irq);
512void wil6210_fini_irq(struct wil6210_priv *wil, int irq); 543void wil6210_fini_irq(struct wil6210_priv *wil, int irq);
513void wil6210_disable_irq(struct wil6210_priv *wil); 544void wil_mask_irq(struct wil6210_priv *wil);
514void wil6210_enable_irq(struct wil6210_priv *wil); 545void wil_unmask_irq(struct wil6210_priv *wil);
546void wil_disable_irq(struct wil6210_priv *wil);
547void wil_enable_irq(struct wil6210_priv *wil);
515int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, 548int wil_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
516 struct cfg80211_mgmt_tx_params *params, 549 struct cfg80211_mgmt_tx_params *params,
517 u64 *cookie); 550 u64 *cookie);
@@ -547,4 +580,5 @@ void wil6210_unmask_irq_rx(struct wil6210_priv *wil);
547 580
548int wil_iftype_nl2wmi(enum nl80211_iftype type); 581int wil_iftype_nl2wmi(enum nl80211_iftype type);
549 582
583int wil_request_firmware(struct wil6210_priv *wil, const char *name);
550#endif /* __WIL6210_H__ */ 584#endif /* __WIL6210_H__ */
diff --git a/drivers/net/wireless/ath/wil6210/wil_platform.c b/drivers/net/wireless/ath/wil6210/wil_platform.c
new file mode 100644
index 000000000000..8f1d78f8a74d
--- /dev/null
+++ b/drivers/net/wireless/ath/wil6210/wil_platform.c
@@ -0,0 +1,49 @@
1/*
2 * Copyright (c) 2014 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 "linux/device.h"
18#include "wil_platform.h"
19
20#ifdef CONFIG_WIL6210_PLATFORM_MSM
21#include "wil_platform_msm.h"
22#endif
23
24/**
25 * wil_platform_init() - wil6210 platform module init
26 *
27 * The function must be called before all other functions in this module.
28 * It returns a handle which is used with the rest of the API
29 *
30 */
31void *wil_platform_init(struct device *dev, struct wil_platform_ops *ops)
32{
33 void *handle = NULL;
34
35 if (!ops) {
36 dev_err(dev, "Invalid parameter. Cannot init platform module\n");
37 return NULL;
38 }
39
40#ifdef CONFIG_WIL6210_PLATFORM_MSM
41 handle = wil_platform_msm_init(dev, ops);
42 if (handle)
43 return handle;
44#endif
45
46 /* other platform specific init functions should be called here */
47
48 return handle;
49}
diff --git a/drivers/net/wireless/ath/wil6210/wil_platform.h b/drivers/net/wireless/ath/wil6210/wil_platform.h
new file mode 100644
index 000000000000..158c73b049a9
--- /dev/null
+++ b/drivers/net/wireless/ath/wil6210/wil_platform.h
@@ -0,0 +1,34 @@
1/*
2 * Copyright (c) 2014 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 __WIL_PLATFORM_H__
18#define __WIL_PLATFORM_H__
19
20struct device;
21
22/**
23 * struct wil_platform_ops - wil platform module callbacks
24 */
25struct wil_platform_ops {
26 int (*bus_request)(void *handle, uint32_t kbps /* KBytes/Sec */);
27 int (*suspend)(void *handle);
28 int (*resume)(void *handle);
29 void (*uninit)(void *handle);
30};
31
32void *wil_platform_init(struct device *dev, struct wil_platform_ops *ops);
33
34#endif /* __WIL_PLATFORM_H__ */
diff --git a/drivers/net/wireless/ath/wil6210/wil_platform_msm.c b/drivers/net/wireless/ath/wil6210/wil_platform_msm.c
new file mode 100644
index 000000000000..b354a743240d
--- /dev/null
+++ b/drivers/net/wireless/ath/wil6210/wil_platform_msm.c
@@ -0,0 +1,257 @@
1/*
2 * Copyright (c) 2014 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 <linux/of.h>
18#include <linux/slab.h>
19#include <linux/msm-bus.h>
20
21#include "wil_platform.h"
22#include "wil_platform_msm.h"
23
24/**
25 * struct wil_platform_msm - wil6210 msm platform module info
26 *
27 * @dev: device object
28 * @msm_bus_handle: handle for using msm_bus API
29 * @pdata: bus scale info retrieved from DT
30 */
31struct wil_platform_msm {
32 struct device *dev;
33 uint32_t msm_bus_handle;
34 struct msm_bus_scale_pdata *pdata;
35};
36
37#define KBTOB(a) (a * 1000ULL)
38
39/**
40 * wil_platform_get_pdata() - Generate bus client data from device tree
41 * provided by clients.
42 *
43 * dev: device object
44 * of_node: Device tree node to extract information from
45 *
46 * The function returns a valid pointer to the allocated bus-scale-pdata
47 * if the vectors were correctly read from the client's device node.
48 * Any error in reading or parsing the device node will return NULL
49 * to the caller.
50 */
51static struct msm_bus_scale_pdata *wil_platform_get_pdata(
52 struct device *dev,
53 struct device_node *of_node)
54{
55 struct msm_bus_scale_pdata *pdata;
56 struct msm_bus_paths *usecase;
57 int i, j, ret, len;
58 unsigned int num_usecases, num_paths, mem_size;
59 const uint32_t *vec_arr;
60 struct msm_bus_vectors *vectors;
61
62 /* first read num_usecases and num_paths so we can calculate
63 * amount of memory to allocate
64 */
65 ret = of_property_read_u32(of_node, "qcom,msm-bus,num-cases",
66 &num_usecases);
67 if (ret) {
68 dev_err(dev, "Error: num-usecases not found\n");
69 return NULL;
70 }
71
72 ret = of_property_read_u32(of_node, "qcom,msm-bus,num-paths",
73 &num_paths);
74 if (ret) {
75 dev_err(dev, "Error: num_paths not found\n");
76 return NULL;
77 }
78
79 /* pdata memory layout:
80 * msm_bus_scale_pdata
81 * msm_bus_paths[num_usecases]
82 * msm_bus_vectors[num_usecases][num_paths]
83 */
84 mem_size = sizeof(struct msm_bus_scale_pdata) +
85 sizeof(struct msm_bus_paths) * num_usecases +
86 sizeof(struct msm_bus_vectors) * num_usecases * num_paths;
87
88 pdata = kzalloc(mem_size, GFP_KERNEL);
89 if (!pdata)
90 return NULL;
91
92 ret = of_property_read_string(of_node, "qcom,msm-bus,name",
93 &pdata->name);
94 if (ret) {
95 dev_err(dev, "Error: Client name not found\n");
96 goto err;
97 }
98
99 if (of_property_read_bool(of_node, "qcom,msm-bus,active-only")) {
100 pdata->active_only = 1;
101 } else {
102 dev_info(dev, "active_only flag absent.\n");
103 dev_info(dev, "Using dual context by default\n");
104 }
105
106 pdata->num_usecases = num_usecases;
107 pdata->usecase = (struct msm_bus_paths *)(pdata + 1);
108
109 vec_arr = of_get_property(of_node, "qcom,msm-bus,vectors-KBps", &len);
110 if (vec_arr == NULL) {
111 dev_err(dev, "Error: Vector array not found\n");
112 goto err;
113 }
114
115 if (len != num_usecases * num_paths * sizeof(uint32_t) * 4) {
116 dev_err(dev, "Error: Length-error on getting vectors\n");
117 goto err;
118 }
119
120 vectors = (struct msm_bus_vectors *)(pdata->usecase + num_usecases);
121 for (i = 0; i < num_usecases; i++) {
122 usecase = &pdata->usecase[i];
123 usecase->num_paths = num_paths;
124 usecase->vectors = &vectors[i];
125
126 for (j = 0; j < num_paths; j++) {
127 int index = ((i * num_paths) + j) * 4;
128
129 usecase->vectors[j].src = be32_to_cpu(vec_arr[index]);
130 usecase->vectors[j].dst =
131 be32_to_cpu(vec_arr[index + 1]);
132 usecase->vectors[j].ab = (uint64_t)
133 KBTOB(be32_to_cpu(vec_arr[index + 2]));
134 usecase->vectors[j].ib = (uint64_t)
135 KBTOB(be32_to_cpu(vec_arr[index + 3]));
136 }
137 }
138
139 return pdata;
140
141err:
142 kfree(pdata);
143
144 return NULL;
145}
146
147/* wil_platform API (callbacks) */
148
149static int wil_platform_bus_request(void *handle,
150 uint32_t kbps /* KBytes/Sec */)
151{
152 int rc, i;
153 struct wil_platform_msm *msm = (struct wil_platform_msm *)handle;
154 int vote = 0; /* vote 0 in case requested kbps cannot be satisfied */
155 struct msm_bus_paths *usecase;
156 uint32_t usecase_kbps;
157 uint32_t min_kbps = ~0;
158
159 /* find the lowest usecase that is bigger than requested kbps */
160 for (i = 0; i < msm->pdata->num_usecases; i++) {
161 usecase = &msm->pdata->usecase[i];
162 /* assume we have single path (vectors[0]). If we ever
163 * have multiple paths, need to define the behavior */
164 usecase_kbps = div64_u64(usecase->vectors[0].ib, 1000);
165 if (usecase_kbps >= kbps && usecase_kbps < min_kbps) {
166 min_kbps = usecase_kbps;
167 vote = i;
168 }
169 }
170
171 rc = msm_bus_scale_client_update_request(msm->msm_bus_handle, vote);
172 if (rc)
173 dev_err(msm->dev, "Failed msm_bus voting. kbps=%d vote=%d, rc=%d\n",
174 kbps, vote, rc);
175 else
176 /* TOOD: remove */
177 dev_info(msm->dev, "msm_bus_scale_client_update_request succeeded. kbps=%d vote=%d\n",
178 kbps, vote);
179
180 return rc;
181}
182
183static void wil_platform_uninit(void *handle)
184{
185 struct wil_platform_msm *msm = (struct wil_platform_msm *)handle;
186
187 dev_info(msm->dev, "wil_platform_uninit\n");
188
189 if (msm->msm_bus_handle)
190 msm_bus_scale_unregister_client(msm->msm_bus_handle);
191
192 kfree(msm->pdata);
193 kfree(msm);
194}
195
196static int wil_platform_msm_bus_register(struct wil_platform_msm *msm,
197 struct device_node *node)
198{
199 msm->pdata = wil_platform_get_pdata(msm->dev, node);
200 if (!msm->pdata) {
201 dev_err(msm->dev, "Failed getting DT info\n");
202 return -EINVAL;
203 }
204
205 msm->msm_bus_handle = msm_bus_scale_register_client(msm->pdata);
206 if (!msm->msm_bus_handle) {
207 dev_err(msm->dev, "Failed msm_bus registration\n");
208 return -EINVAL;
209 }
210
211 dev_info(msm->dev, "msm_bus registration succeeded! handle 0x%x\n",
212 msm->msm_bus_handle);
213
214 return 0;
215}
216
217/**
218 * wil_platform_msm_init() - wil6210 msm platform module init
219 *
220 * The function must be called before all other functions in this module.
221 * It returns a handle which is used with the rest of the API
222 *
223 */
224void *wil_platform_msm_init(struct device *dev, struct wil_platform_ops *ops)
225{
226 struct device_node *of_node;
227 struct wil_platform_msm *msm;
228 int rc;
229
230 of_node = of_find_compatible_node(NULL, NULL, "qcom,wil6210");
231 if (!of_node) {
232 /* this could mean non-msm platform */
233 dev_err(dev, "DT node not found\n");
234 return NULL;
235 }
236
237 msm = kzalloc(sizeof(*msm), GFP_KERNEL);
238 if (!msm)
239 return NULL;
240
241 msm->dev = dev;
242
243 /* register with msm_bus module for scaling requests */
244 rc = wil_platform_msm_bus_register(msm, of_node);
245 if (rc)
246 goto cleanup;
247
248 memset(ops, 0, sizeof(*ops));
249 ops->bus_request = wil_platform_bus_request;
250 ops->uninit = wil_platform_uninit;
251
252 return (void *)msm;
253
254cleanup:
255 kfree(msm);
256 return NULL;
257}
diff --git a/drivers/net/wireless/ath/wil6210/wil_platform_msm.h b/drivers/net/wireless/ath/wil6210/wil_platform_msm.h
new file mode 100644
index 000000000000..2f2229edb498
--- /dev/null
+++ b/drivers/net/wireless/ath/wil6210/wil_platform_msm.h
@@ -0,0 +1,24 @@
1/*
2 * Copyright (c) 2014 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 __WIL_PLATFORM__MSM_H__
18#define __WIL_PLATFORM_MSM_H__
19
20#include "wil_platform.h"
21
22void *wil_platform_msm_init(struct device *dev, struct wil_platform_ops *ops);
23
24#endif /* __WIL_PLATFORM__MSM_H__ */
diff --git a/drivers/net/wireless/ath/wil6210/wmi.c b/drivers/net/wireless/ath/wil6210/wmi.c
index b1aaaee997d5..bd781c7adf2a 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.c
+++ b/drivers/net/wireless/ath/wil6210/wmi.c
@@ -157,6 +157,7 @@ int wmi_read_hdr(struct wil6210_priv *wil, __le32 ptr,
157 struct wil6210_mbox_hdr *hdr) 157 struct wil6210_mbox_hdr *hdr)
158{ 158{
159 void __iomem *src = wmi_buffer(wil, ptr); 159 void __iomem *src = wmi_buffer(wil, ptr);
160
160 if (!src) 161 if (!src)
161 return -EINVAL; 162 return -EINVAL;
162 163
@@ -278,6 +279,7 @@ static void wmi_evt_ready(struct wil6210_priv *wil, int id, void *d, int len)
278 struct net_device *ndev = wil_to_ndev(wil); 279 struct net_device *ndev = wil_to_ndev(wil);
279 struct wireless_dev *wdev = wil->wdev; 280 struct wireless_dev *wdev = wil->wdev;
280 struct wmi_ready_event *evt = d; 281 struct wmi_ready_event *evt = d;
282
281 wil->fw_version = le32_to_cpu(evt->sw_version); 283 wil->fw_version = le32_to_cpu(evt->sw_version);
282 wil->n_mids = evt->numof_additional_mids; 284 wil->n_mids = evt->numof_additional_mids;
283 285
@@ -298,7 +300,7 @@ static void wmi_evt_fw_ready(struct wil6210_priv *wil, int id, void *d,
298 wil_dbg_wmi(wil, "WMI: got FW ready event\n"); 300 wil_dbg_wmi(wil, "WMI: got FW ready event\n");
299 301
300 set_bit(wil_status_fwready, &wil->status); 302 set_bit(wil_status_fwready, &wil->status);
301 /* reuse wmi_ready for the firmware ready indication */ 303 /* let the reset sequence continue */
302 complete(&wil->wmi_ready); 304 complete(&wil->wmi_ready);
303} 305}
304 306
@@ -595,27 +597,40 @@ static void wmi_evt_ba_status(struct wil6210_priv *wil, int id, void *d,
595 return; 597 return;
596 } 598 }
597 599
600 mutex_lock(&wil->mutex);
601
598 cid = wil->vring2cid_tid[evt->ringid][0]; 602 cid = wil->vring2cid_tid[evt->ringid][0];
599 if (cid >= WIL6210_MAX_CID) { 603 if (cid >= WIL6210_MAX_CID) {
600 wil_err(wil, "invalid CID %d for vring %d\n", cid, evt->ringid); 604 wil_err(wil, "invalid CID %d for vring %d\n", cid, evt->ringid);
601 return; 605 goto out;
602 } 606 }
603 607
604 sta = &wil->sta[cid]; 608 sta = &wil->sta[cid];
605 if (sta->status == wil_sta_unused) { 609 if (sta->status == wil_sta_unused) {
606 wil_err(wil, "CID %d unused\n", cid); 610 wil_err(wil, "CID %d unused\n", cid);
607 return; 611 goto out;
608 } 612 }
609 613
610 wil_dbg_wmi(wil, "BACK for CID %d %pM\n", cid, sta->addr); 614 wil_dbg_wmi(wil, "BACK for CID %d %pM\n", cid, sta->addr);
611 for (i = 0; i < WIL_STA_TID_NUM; i++) { 615 for (i = 0; i < WIL_STA_TID_NUM; i++) {
612 struct wil_tid_ampdu_rx *r = sta->tid_rx[i]; 616 struct wil_tid_ampdu_rx *r;
617 unsigned long flags;
618
619 spin_lock_irqsave(&sta->tid_rx_lock, flags);
620
621 r = sta->tid_rx[i];
613 sta->tid_rx[i] = NULL; 622 sta->tid_rx[i] = NULL;
614 wil_tid_ampdu_rx_free(wil, r); 623 wil_tid_ampdu_rx_free(wil, r);
624
625 spin_unlock_irqrestore(&sta->tid_rx_lock, flags);
626
615 if ((evt->status == WMI_BA_AGREED) && evt->agg_wsize) 627 if ((evt->status == WMI_BA_AGREED) && evt->agg_wsize)
616 sta->tid_rx[i] = wil_tid_ampdu_rx_alloc(wil, 628 sta->tid_rx[i] = wil_tid_ampdu_rx_alloc(wil,
617 evt->agg_wsize, 0); 629 evt->agg_wsize, 0);
618 } 630 }
631
632out:
633 mutex_unlock(&wil->mutex);
619} 634}
620 635
621static const struct { 636static const struct {
@@ -653,7 +668,7 @@ void wmi_recv_cmd(struct wil6210_priv *wil)
653 unsigned n; 668 unsigned n;
654 669
655 if (!test_bit(wil_status_reset_done, &wil->status)) { 670 if (!test_bit(wil_status_reset_done, &wil->status)) {
656 wil_err(wil, "Reset not completed\n"); 671 wil_err(wil, "Reset in progress. Cannot handle WMI event\n");
657 return; 672 return;
658 } 673 }
659 674
@@ -708,6 +723,7 @@ void wmi_recv_cmd(struct wil6210_priv *wil)
708 struct wil6210_mbox_hdr_wmi *wmi = &evt->event.wmi; 723 struct wil6210_mbox_hdr_wmi *wmi = &evt->event.wmi;
709 u16 id = le16_to_cpu(wmi->id); 724 u16 id = le16_to_cpu(wmi->id);
710 u32 tstamp = le32_to_cpu(wmi->timestamp); 725 u32 tstamp = le32_to_cpu(wmi->timestamp);
726
711 wil_dbg_wmi(wil, "WMI event 0x%04x MID %d @%d msec\n", 727 wil_dbg_wmi(wil, "WMI event 0x%04x MID %d @%d msec\n",
712 id, wmi->mid, tstamp); 728 id, wmi->mid, tstamp);
713 trace_wil6210_wmi_event(wmi, &wmi[1], 729 trace_wil6210_wmi_event(wmi, &wmi[1],
@@ -748,8 +764,8 @@ int wmi_call(struct wil6210_priv *wil, u16 cmdid, void *buf, u16 len,
748 wil->reply_id = reply_id; 764 wil->reply_id = reply_id;
749 wil->reply_buf = reply; 765 wil->reply_buf = reply;
750 wil->reply_size = reply_size; 766 wil->reply_size = reply_size;
751 remain = wait_for_completion_timeout(&wil->wmi_ready, 767 remain = wait_for_completion_timeout(&wil->wmi_call,
752 msecs_to_jiffies(to_msec)); 768 msecs_to_jiffies(to_msec));
753 if (0 == remain) { 769 if (0 == remain) {
754 wil_err(wil, "wmi_call(0x%04x->0x%04x) timeout %d msec\n", 770 wil_err(wil, "wmi_call(0x%04x->0x%04x) timeout %d msec\n",
755 cmdid, reply_id, to_msec); 771 cmdid, reply_id, to_msec);
@@ -953,8 +969,11 @@ int wmi_set_ie(struct wil6210_priv *wil, u8 type, u16 ie_len, const void *ie)
953 int rc; 969 int rc;
954 u16 len = sizeof(struct wmi_set_appie_cmd) + ie_len; 970 u16 len = sizeof(struct wmi_set_appie_cmd) + ie_len;
955 struct wmi_set_appie_cmd *cmd = kzalloc(len, GFP_KERNEL); 971 struct wmi_set_appie_cmd *cmd = kzalloc(len, GFP_KERNEL);
972
956 if (!cmd) 973 if (!cmd)
957 return -ENOMEM; 974 return -ENOMEM;
975 if (!ie)
976 ie_len = 0;
958 977
959 cmd->mgmt_frm_type = type; 978 cmd->mgmt_frm_type = type;
960 /* BUG: FW API define ieLen as u8. Will fix FW */ 979 /* BUG: FW API define ieLen as u8. Will fix FW */
@@ -1128,6 +1147,9 @@ static void wmi_event_handle(struct wil6210_priv *wil,
1128 struct wil6210_mbox_hdr_wmi *wmi = (void *)(&hdr[1]); 1147 struct wil6210_mbox_hdr_wmi *wmi = (void *)(&hdr[1]);
1129 void *evt_data = (void *)(&wmi[1]); 1148 void *evt_data = (void *)(&wmi[1]);
1130 u16 id = le16_to_cpu(wmi->id); 1149 u16 id = le16_to_cpu(wmi->id);
1150
1151 wil_dbg_wmi(wil, "Handle WMI 0x%04x (reply_id 0x%04x)\n",
1152 id, wil->reply_id);
1131 /* check if someone waits for this event */ 1153 /* check if someone waits for this event */
1132 if (wil->reply_id && wil->reply_id == id) { 1154 if (wil->reply_id && wil->reply_id == id) {
1133 if (wil->reply_buf) { 1155 if (wil->reply_buf) {
@@ -1138,7 +1160,7 @@ static void wmi_event_handle(struct wil6210_priv *wil,
1138 len - sizeof(*wmi)); 1160 len - sizeof(*wmi));
1139 } 1161 }
1140 wil_dbg_wmi(wil, "Complete WMI 0x%04x\n", id); 1162 wil_dbg_wmi(wil, "Complete WMI 0x%04x\n", id);
1141 complete(&wil->wmi_ready); 1163 complete(&wil->wmi_call);
1142 return; 1164 return;
1143 } 1165 }
1144 /* unsolicited event */ 1166 /* unsolicited event */
@@ -1184,9 +1206,11 @@ void wmi_event_worker(struct work_struct *work)
1184 struct pending_wmi_event *evt; 1206 struct pending_wmi_event *evt;
1185 struct list_head *lh; 1207 struct list_head *lh;
1186 1208
1209 wil_dbg_wmi(wil, "Start %s\n", __func__);
1187 while ((lh = next_wmi_ev(wil)) != NULL) { 1210 while ((lh = next_wmi_ev(wil)) != NULL) {
1188 evt = list_entry(lh, struct pending_wmi_event, list); 1211 evt = list_entry(lh, struct pending_wmi_event, list);
1189 wmi_event_handle(wil, &evt->event.hdr); 1212 wmi_event_handle(wil, &evt->event.hdr);
1190 kfree(evt); 1213 kfree(evt);
1191 } 1214 }
1215 wil_dbg_wmi(wil, "Finished %s\n", __func__);
1192} 1216}
diff --git a/drivers/net/wireless/ath/wil6210/wmi.h b/drivers/net/wireless/ath/wil6210/wmi.h
index 061618cee9f6..27b97432d1c2 100644
--- a/drivers/net/wireless/ath/wil6210/wmi.h
+++ b/drivers/net/wireless/ath/wil6210/wmi.h
@@ -179,7 +179,6 @@ enum wmi_crypto_type {
179 WMI_CRYPT_AES_GCMP = 0x20, 179 WMI_CRYPT_AES_GCMP = 0x20,
180}; 180};
181 181
182
183enum wmi_connect_ctrl_flag_bits { 182enum wmi_connect_ctrl_flag_bits {
184 WMI_CONNECT_ASSOC_POLICY_USER = 0x0001, 183 WMI_CONNECT_ASSOC_POLICY_USER = 0x0001,
185 WMI_CONNECT_SEND_REASSOC = 0x0002, 184 WMI_CONNECT_SEND_REASSOC = 0x0002,
@@ -219,7 +218,6 @@ struct wmi_disconnect_sta_cmd {
219 __le16 disconnect_reason; 218 __le16 disconnect_reason;
220} __packed; 219} __packed;
221 220
222
223/* 221/*
224 * WMI_SET_PMK_CMDID 222 * WMI_SET_PMK_CMDID
225 */ 223 */
@@ -234,7 +232,6 @@ struct wmi_set_pmk_cmd {
234 u8 pmk[WMI_PMK_LEN]; 232 u8 pmk[WMI_PMK_LEN];
235} __packed; 233} __packed;
236 234
237
238/* 235/*
239 * WMI_SET_PASSPHRASE_CMDID 236 * WMI_SET_PASSPHRASE_CMDID
240 */ 237 */
@@ -273,7 +270,6 @@ struct wmi_delete_cipher_key_cmd {
273 u8 mac[WMI_MAC_LEN]; 270 u8 mac[WMI_MAC_LEN];
274} __packed; 271} __packed;
275 272
276
277/* 273/*
278 * WMI_START_SCAN_CMDID 274 * WMI_START_SCAN_CMDID
279 * 275 *
@@ -325,7 +321,6 @@ struct wmi_probed_ssid_cmd {
325 u8 ssid[WMI_MAX_SSID_LEN]; 321 u8 ssid[WMI_MAX_SSID_LEN];
326} __packed; 322} __packed;
327 323
328
329/* 324/*
330 * WMI_SET_APPIE_CMDID 325 * WMI_SET_APPIE_CMDID
331 * Add Application specified IE to a management frame 326 * Add Application specified IE to a management frame
@@ -351,7 +346,6 @@ struct wmi_set_appie_cmd {
351 u8 ie_info[0]; 346 u8 ie_info[0];
352} __packed; 347} __packed;
353 348
354
355/* 349/*
356 * WMI_PXMT_RANGE_CFG_CMDID 350 * WMI_PXMT_RANGE_CFG_CMDID
357 */ 351 */
@@ -380,7 +374,6 @@ struct wmi_rf_mgmt_cmd {
380 __le32 rf_mgmt_type; 374 __le32 rf_mgmt_type;
381} __packed; 375} __packed;
382 376
383
384/* 377/*
385 * WMI_RF_RX_TEST_CMDID 378 * WMI_RF_RX_TEST_CMDID
386 */ 379 */
@@ -426,7 +419,6 @@ struct wmi_bcon_ctrl_cmd {
426 u8 disable_sec; 419 u8 disable_sec;
427} __packed; 420} __packed;
428 421
429
430/******* P2P ***********/ 422/******* P2P ***********/
431 423
432/* 424/*
@@ -797,7 +789,6 @@ struct wmi_temp_sense_cmd {
797 __le32 measure_marlon_r_en; 789 __le32 measure_marlon_r_en;
798} __packed; 790} __packed;
799 791
800
801/* 792/*
802 * WMI Events 793 * WMI Events
803 */ 794 */
@@ -887,7 +878,6 @@ enum wmi_event_id {
887 * Events data structures 878 * Events data structures
888 */ 879 */
889 880
890
891enum wmi_fw_status { 881enum wmi_fw_status {
892 WMI_FW_STATUS_SUCCESS, 882 WMI_FW_STATUS_SUCCESS,
893 WMI_FW_STATUS_FAILURE, 883 WMI_FW_STATUS_FAILURE,
@@ -1038,8 +1028,8 @@ struct wmi_disconnect_event {
1038 __le16 protocol_reason_status; /* reason code, see 802.11 spec. */ 1028 __le16 protocol_reason_status; /* reason code, see 802.11 spec. */
1039 u8 bssid[WMI_MAC_LEN]; /* set if known */ 1029 u8 bssid[WMI_MAC_LEN]; /* set if known */
1040 u8 disconnect_reason; /* see wmi_disconnect_reason */ 1030 u8 disconnect_reason; /* see wmi_disconnect_reason */
1041 u8 assoc_resp_len; /* not in use */ 1031 u8 assoc_resp_len; /* not used */
1042 u8 assoc_info[0]; /* not in use */ 1032 u8 assoc_info[0]; /* not used */
1043} __packed; 1033} __packed;
1044 1034
1045/* 1035/*
@@ -1081,7 +1071,6 @@ struct wmi_delba_event {
1081 __le16 reason; 1071 __le16 reason;
1082} __packed; 1072} __packed;
1083 1073
1084
1085/* 1074/*
1086 * WMI_VRING_CFG_DONE_EVENTID 1075 * WMI_VRING_CFG_DONE_EVENTID
1087 */ 1076 */
@@ -1147,7 +1136,6 @@ struct wmi_data_port_open_event {
1147 u8 reserved[3]; 1136 u8 reserved[3];
1148} __packed; 1137} __packed;
1149 1138
1150
1151/* 1139/*
1152 * WMI_GET_PCP_CHANNEL_EVENTID 1140 * WMI_GET_PCP_CHANNEL_EVENTID
1153 */ 1141 */
@@ -1156,7 +1144,6 @@ struct wmi_get_pcp_channel_event {
1156 u8 reserved[3]; 1144 u8 reserved[3];
1157} __packed; 1145} __packed;
1158 1146
1159
1160/* 1147/*
1161* WMI_PORT_ALLOCATED_EVENTID 1148* WMI_PORT_ALLOCATED_EVENTID
1162*/ 1149*/
@@ -1260,7 +1247,6 @@ struct wmi_rx_mgmt_info {
1260 u8 channel; /* From Radio MNGR */ 1247 u8 channel; /* From Radio MNGR */
1261} __packed; 1248} __packed;
1262 1249
1263
1264/* 1250/*
1265 * WMI_TX_MGMT_PACKET_EVENTID 1251 * WMI_TX_MGMT_PACKET_EVENTID
1266 */ 1252 */
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index 95a943326420..bb12586cd7cd 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -45,6 +45,7 @@
45#define B43_MMIO_RAM_DATA 0x134 45#define B43_MMIO_RAM_DATA 0x134
46#define B43_MMIO_PS_STATUS 0x140 46#define B43_MMIO_PS_STATUS 0x140
47#define B43_MMIO_RADIO_HWENABLED_HI 0x158 47#define B43_MMIO_RADIO_HWENABLED_HI 0x158
48#define B43_MMIO_MAC_HW_CAP 0x15C /* MAC capabilities (corerev >= 13) */
48#define B43_MMIO_SHM_CONTROL 0x160 49#define B43_MMIO_SHM_CONTROL 0x160
49#define B43_MMIO_SHM_DATA 0x164 50#define B43_MMIO_SHM_DATA 0x164
50#define B43_MMIO_SHM_DATA_UNALIGNED 0x166 51#define B43_MMIO_SHM_DATA_UNALIGNED 0x166
@@ -253,6 +254,8 @@ enum {
253#define B43_SHM_SH_CHAN 0x00A0 /* Current channel (low 8bit only) */ 254#define B43_SHM_SH_CHAN 0x00A0 /* Current channel (low 8bit only) */
254#define B43_SHM_SH_CHAN_5GHZ 0x0100 /* Bit set, if 5 Ghz channel */ 255#define B43_SHM_SH_CHAN_5GHZ 0x0100 /* Bit set, if 5 Ghz channel */
255#define B43_SHM_SH_CHAN_40MHZ 0x0200 /* Bit set, if 40 Mhz channel width */ 256#define B43_SHM_SH_CHAN_40MHZ 0x0200 /* Bit set, if 40 Mhz channel width */
257#define B43_SHM_SH_MACHW_L 0x00C0 /* Location where the ucode expects the MAC capabilities */
258#define B43_SHM_SH_MACHW_H 0x00C2 /* Location where the ucode expects the MAC capabilities */
256#define B43_SHM_SH_HOSTF5 0x00D4 /* Hostflags 5 for ucode options */ 259#define B43_SHM_SH_HOSTF5 0x00D4 /* Hostflags 5 for ucode options */
257#define B43_SHM_SH_BCMCFIFOID 0x0108 /* Last posted cookie to the bcast/mcast FIFO */ 260#define B43_SHM_SH_BCMCFIFOID 0x0108 /* Last posted cookie to the bcast/mcast FIFO */
258/* TSSI information */ 261/* TSSI information */
@@ -297,6 +300,7 @@ enum {
297#define B43_SHM_SH_LFFBLIM 0x0046 /* Long frame fallback retry limit */ 300#define B43_SHM_SH_LFFBLIM 0x0046 /* Long frame fallback retry limit */
298#define B43_SHM_SH_BEACPHYCTL 0x0054 /* Beacon PHY TX control word (see PHY TX control) */ 301#define B43_SHM_SH_BEACPHYCTL 0x0054 /* Beacon PHY TX control word (see PHY TX control) */
299#define B43_SHM_SH_EXTNPHYCTL 0x00B0 /* Extended bytes for beacon PHY control (N) */ 302#define B43_SHM_SH_EXTNPHYCTL 0x00B0 /* Extended bytes for beacon PHY control (N) */
303#define B43_SHM_SH_BCN_LI 0x00B6 /* beacon listen interval */
300/* SHM_SHARED ACK/CTS control */ 304/* SHM_SHARED ACK/CTS control */
301#define B43_SHM_SH_ACKCTSPHYCTL 0x0022 /* ACK/CTS PHY control word (see PHY TX control) */ 305#define B43_SHM_SH_ACKCTSPHYCTL 0x0022 /* ACK/CTS PHY control word (see PHY TX control) */
302/* SHM_SHARED probe response variables */ 306/* SHM_SHARED probe response variables */
@@ -476,6 +480,11 @@ enum {
476#define B43_MACCMD_CCA 0x00000008 /* Clear channel assessment */ 480#define B43_MACCMD_CCA 0x00000008 /* Clear channel assessment */
477#define B43_MACCMD_BGNOISE 0x00000010 /* Background noise */ 481#define B43_MACCMD_BGNOISE 0x00000010 /* Background noise */
478 482
483/* B43_MMIO_PSM_PHY_HDR bits */
484#define B43_PSM_HDR_MAC_PHY_RESET 0x00000001
485#define B43_PSM_HDR_MAC_PHY_CLOCK_EN 0x00000002
486#define B43_PSM_HDR_MAC_PHY_FORCE_CLK 0x00000004
487
479/* See BCMA_CLKCTLST_EXTRESREQ and BCMA_CLKCTLST_EXTRESST */ 488/* See BCMA_CLKCTLST_EXTRESREQ and BCMA_CLKCTLST_EXTRESST */
480#define B43_BCMA_CLKCTLST_80211_PLL_REQ 0x00000100 489#define B43_BCMA_CLKCTLST_80211_PLL_REQ 0x00000100
481#define B43_BCMA_CLKCTLST_PHY_PLL_REQ 0x00000200 490#define B43_BCMA_CLKCTLST_PHY_PLL_REQ 0x00000200
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 66ff718cc412..5d4173ee55bc 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -1204,6 +1204,36 @@ void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags)
1204 } 1204 }
1205} 1205}
1206 1206
1207/* http://bcm-v4.sipsolutions.net/802.11/PHY/BmacCorePllReset */
1208void b43_wireless_core_phy_pll_reset(struct b43_wldev *dev)
1209{
1210 struct bcma_drv_cc *bcma_cc __maybe_unused;
1211 struct ssb_chipcommon *ssb_cc __maybe_unused;
1212
1213 switch (dev->dev->bus_type) {
1214#ifdef CONFIG_B43_BCMA
1215 case B43_BUS_BCMA:
1216 bcma_cc = &dev->dev->bdev->bus->drv_cc;
1217
1218 bcma_cc_write32(bcma_cc, BCMA_CC_CHIPCTL_ADDR, 0);
1219 bcma_cc_mask32(bcma_cc, BCMA_CC_CHIPCTL_DATA, ~0x4);
1220 bcma_cc_set32(bcma_cc, BCMA_CC_CHIPCTL_DATA, 0x4);
1221 bcma_cc_mask32(bcma_cc, BCMA_CC_CHIPCTL_DATA, ~0x4);
1222 break;
1223#endif
1224#ifdef CONFIG_B43_SSB
1225 case B43_BUS_SSB:
1226 ssb_cc = &dev->dev->sdev->bus->chipco;
1227
1228 chipco_write32(ssb_cc, SSB_CHIPCO_CHIPCTL_ADDR, 0);
1229 chipco_mask32(ssb_cc, SSB_CHIPCO_CHIPCTL_DATA, ~0x4);
1230 chipco_set32(ssb_cc, SSB_CHIPCO_CHIPCTL_DATA, 0x4);
1231 chipco_mask32(ssb_cc, SSB_CHIPCO_CHIPCTL_DATA, ~0x4);
1232 break;
1233#endif
1234 }
1235}
1236
1207#ifdef CONFIG_B43_BCMA 1237#ifdef CONFIG_B43_BCMA
1208static void b43_bcma_phy_reset(struct b43_wldev *dev) 1238static void b43_bcma_phy_reset(struct b43_wldev *dev)
1209{ 1239{
@@ -2985,7 +3015,22 @@ void b43_mac_switch_freq(struct b43_wldev *dev, u8 spurmode)
2985{ 3015{
2986 u16 chip_id = dev->dev->chip_id; 3016 u16 chip_id = dev->dev->chip_id;
2987 3017
2988 if (chip_id == BCMA_CHIP_ID_BCM43131 || 3018 if (chip_id == BCMA_CHIP_ID_BCM4331) {
3019 switch (spurmode) {
3020 case 2: /* 168 Mhz: 2^26/168 = 0x61862 */
3021 b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x1862);
3022 b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x6);
3023 break;
3024 case 1: /* 164 Mhz: 2^26/164 = 0x63e70 */
3025 b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x3e70);
3026 b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x6);
3027 break;
3028 default: /* 160 Mhz: 2^26/160 = 0x66666 */
3029 b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, 0x6666);
3030 b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x6);
3031 break;
3032 }
3033 } else if (chip_id == BCMA_CHIP_ID_BCM43131 ||
2989 chip_id == BCMA_CHIP_ID_BCM43217 || 3034 chip_id == BCMA_CHIP_ID_BCM43217 ||
2990 chip_id == BCMA_CHIP_ID_BCM43222 || 3035 chip_id == BCMA_CHIP_ID_BCM43222 ||
2991 chip_id == BCMA_CHIP_ID_BCM43224 || 3036 chip_id == BCMA_CHIP_ID_BCM43224 ||
@@ -3106,6 +3151,7 @@ static void b43_rate_memory_init(struct b43_wldev *dev)
3106 case B43_PHYTYPE_HT: 3151 case B43_PHYTYPE_HT:
3107 case B43_PHYTYPE_LCN: 3152 case B43_PHYTYPE_LCN:
3108 b43_rate_memory_write(dev, B43_OFDM_RATE_6MB, 1); 3153 b43_rate_memory_write(dev, B43_OFDM_RATE_6MB, 1);
3154 b43_rate_memory_write(dev, B43_OFDM_RATE_9MB, 1);
3109 b43_rate_memory_write(dev, B43_OFDM_RATE_12MB, 1); 3155 b43_rate_memory_write(dev, B43_OFDM_RATE_12MB, 1);
3110 b43_rate_memory_write(dev, B43_OFDM_RATE_18MB, 1); 3156 b43_rate_memory_write(dev, B43_OFDM_RATE_18MB, 1);
3111 b43_rate_memory_write(dev, B43_OFDM_RATE_24MB, 1); 3157 b43_rate_memory_write(dev, B43_OFDM_RATE_24MB, 1);
@@ -3884,6 +3930,12 @@ static int b43_switch_band(struct b43_wldev *dev,
3884 return 0; 3930 return 0;
3885} 3931}
3886 3932
3933static void b43_set_beacon_listen_interval(struct b43_wldev *dev, u16 interval)
3934{
3935 interval = min_t(u16, interval, (u16)0xFF);
3936 b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_BCN_LI, interval);
3937}
3938
3887/* Write the short and long frame retry limit values. */ 3939/* Write the short and long frame retry limit values. */
3888static void b43_set_retry_limits(struct b43_wldev *dev, 3940static void b43_set_retry_limits(struct b43_wldev *dev,
3889 unsigned int short_retry, 3941 unsigned int short_retry,
@@ -3912,6 +3964,9 @@ static int b43_op_config(struct ieee80211_hw *hw, u32 changed)
3912 mutex_lock(&wl->mutex); 3964 mutex_lock(&wl->mutex);
3913 b43_mac_suspend(dev); 3965 b43_mac_suspend(dev);
3914 3966
3967 if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL)
3968 b43_set_beacon_listen_interval(dev, conf->listen_interval);
3969
3915 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { 3970 if (changed & IEEE80211_CONF_CHANGE_CHANNEL) {
3916 phy->chandef = &conf->chandef; 3971 phy->chandef = &conf->chandef;
3917 phy->channel = conf->chandef.chan->hw_value; 3972 phy->channel = conf->chandef.chan->hw_value;
@@ -4812,6 +4867,16 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
4812 hf &= ~B43_HF_SKCFPUP; 4867 hf &= ~B43_HF_SKCFPUP;
4813 b43_hf_write(dev, hf); 4868 b43_hf_write(dev, hf);
4814 4869
4870 /* tell the ucode MAC capabilities */
4871 if (dev->dev->core_rev >= 13) {
4872 u32 mac_hw_cap = b43_read32(dev, B43_MMIO_MAC_HW_CAP);
4873
4874 b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_MACHW_L,
4875 mac_hw_cap & 0xffff);
4876 b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_MACHW_H,
4877 (mac_hw_cap >> 16) & 0xffff);
4878 }
4879
4815 b43_set_retry_limits(dev, B43_DEFAULT_SHORT_RETRY_LIMIT, 4880 b43_set_retry_limits(dev, B43_DEFAULT_SHORT_RETRY_LIMIT,
4816 B43_DEFAULT_LONG_RETRY_LIMIT); 4881 B43_DEFAULT_LONG_RETRY_LIMIT);
4817 b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_SFFBLIM, 3); 4882 b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_SFFBLIM, 3);
@@ -4834,6 +4899,10 @@ static int b43_wireless_core_init(struct b43_wldev *dev)
4834 /* Maximum Contention Window */ 4899 /* Maximum Contention Window */
4835 b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MAXCONT, 0x3FF); 4900 b43_shm_write16(dev, B43_SHM_SCRATCH, B43_SHM_SC_MAXCONT, 0x3FF);
4836 4901
4902 /* write phytype and phyvers */
4903 b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_PHYTYPE, phy->type);
4904 b43_shm_write16(dev, B43_SHM_SHARED, B43_SHM_SH_PHYVER, phy->rev);
4905
4837 if (b43_bus_host_is_pcmcia(dev->dev) || 4906 if (b43_bus_host_is_pcmcia(dev->dev) ||
4838 b43_bus_host_is_sdio(dev->dev)) { 4907 b43_bus_host_is_sdio(dev->dev)) {
4839 dev->__using_pio_transfers = true; 4908 dev->__using_pio_transfers = true;
diff --git a/drivers/net/wireless/b43/main.h b/drivers/net/wireless/b43/main.h
index 9f22e4b4c132..c46430cc725c 100644
--- a/drivers/net/wireless/b43/main.h
+++ b/drivers/net/wireless/b43/main.h
@@ -96,6 +96,8 @@ void b43_controller_restart(struct b43_wldev *dev, const char *reason);
96#define B43_PS_ASLEEP (1 << 3) /* Force device asleep */ 96#define B43_PS_ASLEEP (1 << 3) /* Force device asleep */
97void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags); 97void b43_power_saving_ctl_bits(struct b43_wldev *dev, unsigned int ps_flags);
98 98
99void b43_wireless_core_phy_pll_reset(struct b43_wldev *dev);
100
99void b43_mac_suspend(struct b43_wldev *dev); 101void b43_mac_suspend(struct b43_wldev *dev);
100void b43_mac_enable(struct b43_wldev *dev); 102void b43_mac_enable(struct b43_wldev *dev);
101void b43_mac_phy_clock_set(struct b43_wldev *dev, bool on); 103void b43_mac_phy_clock_set(struct b43_wldev *dev, bool on);
diff --git a/drivers/net/wireless/b43/phy_ht.c b/drivers/net/wireless/b43/phy_ht.c
index c4dc8b020f60..bd68945965d6 100644
--- a/drivers/net/wireless/b43/phy_ht.c
+++ b/drivers/net/wireless/b43/phy_ht.c
@@ -81,80 +81,104 @@ static void b43_radio_2059_channel_setup(struct b43_wldev *dev,
81 udelay(50); 81 udelay(50);
82 82
83 /* Calibration */ 83 /* Calibration */
84 b43_radio_mask(dev, 0x2b, ~0x1); 84 b43_radio_mask(dev, R2059_RFPLL_MISC_EN, ~0x1);
85 b43_radio_mask(dev, 0x2e, ~0x4); 85 b43_radio_mask(dev, R2059_RFPLL_MISC_CAL_RESETN, ~0x4);
86 b43_radio_set(dev, 0x2e, 0x4); 86 b43_radio_set(dev, R2059_RFPLL_MISC_CAL_RESETN, 0x4);
87 b43_radio_set(dev, 0x2b, 0x1); 87 b43_radio_set(dev, R2059_RFPLL_MISC_EN, 0x1);
88 88
89 udelay(300); 89 udelay(300);
90} 90}
91 91
92static void b43_radio_2059_init(struct b43_wldev *dev) 92/* Calibrate resistors in LPF of PLL? */
93static void b43_radio_2059_rcal(struct b43_wldev *dev)
94{
95 /* Enable */
96 b43_radio_set(dev, R2059_C3 | R2059_RCAL_CONFIG, 0x1);
97 usleep_range(10, 20);
98
99 b43_radio_set(dev, R2059_C3 | 0x0BF, 0x1);
100 b43_radio_maskset(dev, R2059_C3 | 0x19B, 0x3, 0x2);
101
102 /* Start */
103 b43_radio_set(dev, R2059_C3 | R2059_RCAL_CONFIG, 0x2);
104 usleep_range(100, 200);
105
106 /* Stop */
107 b43_radio_mask(dev, R2059_C3 | R2059_RCAL_CONFIG, ~0x2);
108
109 if (!b43_radio_wait_value(dev, R2059_C3 | R2059_RCAL_STATUS, 1, 1, 100,
110 1000000))
111 b43err(dev->wl, "Radio 0x2059 rcal timeout\n");
112
113 /* Disable */
114 b43_radio_mask(dev, R2059_C3 | R2059_RCAL_CONFIG, ~0x1);
115
116 b43_radio_set(dev, 0xa, 0x60);
117}
118
119/* Calibrate the internal RC oscillator? */
120static void b43_radio_2057_rccal(struct b43_wldev *dev)
93{ 121{
94 const u16 routing[] = { R2059_C1, R2059_C2, R2059_C3 };
95 const u16 radio_values[3][2] = { 122 const u16 radio_values[3][2] = {
96 { 0x61, 0xE9 }, { 0x69, 0xD5 }, { 0x73, 0x99 }, 123 { 0x61, 0xE9 }, { 0x69, 0xD5 }, { 0x73, 0x99 },
97 }; 124 };
98 u16 i, j; 125 int i;
99 126
100 b43_radio_write(dev, R2059_ALL | 0x51, 0x0070); 127 for (i = 0; i < 3; i++) {
101 b43_radio_write(dev, R2059_ALL | 0x5a, 0x0003); 128 b43_radio_write(dev, R2059_RCCAL_MASTER, radio_values[i][0]);
129 b43_radio_write(dev, R2059_RCCAL_X1, 0x6E);
130 b43_radio_write(dev, R2059_RCCAL_TRC0, radio_values[i][1]);
102 131
103 for (i = 0; i < ARRAY_SIZE(routing); i++) 132 /* Start */
104 b43_radio_set(dev, routing[i] | 0x146, 0x3); 133 b43_radio_write(dev, R2059_RCCAL_START_R1_Q1_P1, 0x55);
105 134
106 b43_radio_set(dev, 0x2e, 0x0078); 135 /* Wait */
107 b43_radio_set(dev, 0xc0, 0x0080); 136 if (!b43_radio_wait_value(dev, R2059_RCCAL_DONE_OSCCAP, 2, 2,
108 msleep(2); 137 500, 5000000))
109 b43_radio_mask(dev, 0x2e, ~0x0078); 138 b43err(dev->wl, "Radio 0x2059 rccal timeout\n");
110 b43_radio_mask(dev, 0xc0, ~0x0080);
111 139
112 if (1) { /* FIXME */ 140 /* Stop */
113 b43_radio_set(dev, R2059_C3 | 0x4, 0x1); 141 b43_radio_write(dev, R2059_RCCAL_START_R1_Q1_P1, 0x15);
114 udelay(10); 142 }
115 b43_radio_set(dev, R2059_C3 | 0x0BF, 0x1);
116 b43_radio_maskset(dev, R2059_C3 | 0x19B, 0x3, 0x2);
117 143
118 b43_radio_set(dev, R2059_C3 | 0x4, 0x2); 144 b43_radio_mask(dev, R2059_RCCAL_MASTER, ~0x1);
119 udelay(100); 145}
120 b43_radio_mask(dev, R2059_C3 | 0x4, ~0x2);
121 146
122 for (i = 0; i < 10000; i++) { 147static void b43_radio_2059_init_pre(struct b43_wldev *dev)
123 if (b43_radio_read(dev, R2059_C3 | 0x145) & 1) { 148{
124 i = 0; 149 b43_phy_mask(dev, B43_PHY_HT_RF_CTL_CMD, ~B43_PHY_HT_RF_CTL_CMD_CHIP0_PU);
125 break; 150 b43_phy_set(dev, B43_PHY_HT_RF_CTL_CMD, B43_PHY_HT_RF_CTL_CMD_FORCE);
126 } 151 b43_phy_mask(dev, B43_PHY_HT_RF_CTL_CMD, ~B43_PHY_HT_RF_CTL_CMD_FORCE);
127 udelay(100); 152 b43_phy_set(dev, B43_PHY_HT_RF_CTL_CMD, B43_PHY_HT_RF_CTL_CMD_CHIP0_PU);
128 } 153}
129 if (i)
130 b43err(dev->wl, "radio 0x945 timeout\n");
131
132 b43_radio_mask(dev, R2059_C3 | 0x4, ~0x1);
133 b43_radio_set(dev, 0xa, 0x60);
134
135 for (i = 0; i < 3; i++) {
136 b43_radio_write(dev, 0x17F, radio_values[i][0]);
137 b43_radio_write(dev, 0x13D, 0x6E);
138 b43_radio_write(dev, 0x13E, radio_values[i][1]);
139 b43_radio_write(dev, 0x13C, 0x55);
140
141 for (j = 0; j < 10000; j++) {
142 if (b43_radio_read(dev, 0x140) & 2) {
143 j = 0;
144 break;
145 }
146 udelay(500);
147 }
148 if (j)
149 b43err(dev->wl, "radio 0x140 timeout\n");
150 154
151 b43_radio_write(dev, 0x13C, 0x15); 155static void b43_radio_2059_init(struct b43_wldev *dev)
152 } 156{
157 const u16 routing[] = { R2059_C1, R2059_C2, R2059_C3 };
158 int i;
159
160 /* Prepare (reset?) radio */
161 b43_radio_2059_init_pre(dev);
162
163 r2059_upload_inittabs(dev);
164
165 for (i = 0; i < ARRAY_SIZE(routing); i++)
166 b43_radio_set(dev, routing[i] | 0x146, 0x3);
167
168 /* Post init starts below */
169
170 b43_radio_set(dev, R2059_RFPLL_MISC_CAL_RESETN, 0x0078);
171 b43_radio_set(dev, R2059_XTAL_CONFIG2, 0x0080);
172 msleep(2);
173 b43_radio_mask(dev, R2059_RFPLL_MISC_CAL_RESETN, ~0x0078);
174 b43_radio_mask(dev, R2059_XTAL_CONFIG2, ~0x0080);
153 175
154 b43_radio_mask(dev, 0x17F, ~0x1); 176 if (1) { /* FIXME */
177 b43_radio_2059_rcal(dev);
178 b43_radio_2057_rccal(dev);
155 } 179 }
156 180
157 b43_radio_mask(dev, 0x11, ~0x0008); 181 b43_radio_mask(dev, R2059_RFPLL_MASTER, ~0x0008);
158} 182}
159 183
160/************************************************** 184/**************************************************
@@ -297,6 +321,26 @@ static void b43_phy_ht_bphy_init(struct b43_wldev *dev)
297 b43_phy_write(dev, B43_PHY_N_BMODE(0x38), 0x668); 321 b43_phy_write(dev, B43_PHY_N_BMODE(0x38), 0x668);
298} 322}
299 323
324static void b43_phy_ht_bphy_reset(struct b43_wldev *dev, bool reset)
325{
326 u16 tmp;
327
328 tmp = b43_read16(dev, B43_MMIO_PSM_PHY_HDR);
329 b43_write16(dev, B43_MMIO_PSM_PHY_HDR,
330 tmp | B43_PSM_HDR_MAC_PHY_FORCE_CLK);
331
332 /* Put BPHY in or take it out of the reset */
333 if (reset)
334 b43_phy_set(dev, B43_PHY_B_BBCFG,
335 B43_PHY_B_BBCFG_RSTCCA | B43_PHY_B_BBCFG_RSTRX);
336 else
337 b43_phy_mask(dev, B43_PHY_B_BBCFG,
338 (u16)~(B43_PHY_B_BBCFG_RSTCCA |
339 B43_PHY_B_BBCFG_RSTRX));
340
341 b43_write16(dev, B43_MMIO_PSM_PHY_HDR, tmp);
342}
343
300/************************************************** 344/**************************************************
301 * Samples 345 * Samples
302 **************************************************/ 346 **************************************************/
@@ -704,7 +748,6 @@ static void b43_phy_ht_spur_avoid(struct b43_wldev *dev,
704{ 748{
705 struct bcma_device *core = dev->dev->bdev; 749 struct bcma_device *core = dev->dev->bdev;
706 int spuravoid = 0; 750 int spuravoid = 0;
707 u16 tmp;
708 751
709 /* Check for 13 and 14 is just a guess, we don't have enough logs. */ 752 /* Check for 13 and 14 is just a guess, we don't have enough logs. */
710 if (new_channel->hw_value == 13 || new_channel->hw_value == 14) 753 if (new_channel->hw_value == 13 || new_channel->hw_value == 14)
@@ -717,22 +760,9 @@ static void b43_phy_ht_spur_avoid(struct b43_wldev *dev,
717 B43_BCMA_CLKCTLST_80211_PLL_ST | 760 B43_BCMA_CLKCTLST_80211_PLL_ST |
718 B43_BCMA_CLKCTLST_PHY_PLL_ST, false); 761 B43_BCMA_CLKCTLST_PHY_PLL_ST, false);
719 762
720 /* Values has been taken from wlc_bmac_switch_macfreq comments */ 763 b43_mac_switch_freq(dev, spuravoid);
721 switch (spuravoid) {
722 case 2: /* 126MHz */
723 tmp = 0x2082;
724 break;
725 case 1: /* 123MHz */
726 tmp = 0x5341;
727 break;
728 default: /* 120MHz */
729 tmp = 0x8889;
730 }
731
732 b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_LOW, tmp);
733 b43_write16(dev, B43_MMIO_TSF_CLK_FRAC_HIGH, 0x8);
734 764
735 /* TODO: reset PLL */ 765 b43_wireless_core_phy_pll_reset(dev);
736 766
737 if (spuravoid) 767 if (spuravoid)
738 b43_phy_set(dev, B43_PHY_HT_BBCFG, B43_PHY_HT_BBCFG_RSTRX); 768 b43_phy_set(dev, B43_PHY_HT_BBCFG, B43_PHY_HT_BBCFG_RSTRX);
@@ -747,13 +777,19 @@ static void b43_phy_ht_channel_setup(struct b43_wldev *dev,
747 const struct b43_phy_ht_channeltab_e_phy *e, 777 const struct b43_phy_ht_channeltab_e_phy *e,
748 struct ieee80211_channel *new_channel) 778 struct ieee80211_channel *new_channel)
749{ 779{
750 bool old_band_5ghz; 780 if (new_channel->band == IEEE80211_BAND_5GHZ) {
781 /* Switch to 2 GHz for a moment to access B-PHY regs */
782 b43_phy_mask(dev, B43_PHY_HT_BANDCTL, ~B43_PHY_HT_BANDCTL_5GHZ);
783
784 b43_phy_ht_bphy_reset(dev, true);
751 785
752 old_band_5ghz = b43_phy_read(dev, B43_PHY_HT_BANDCTL) & 0; /* FIXME */ 786 /* Switch to 5 GHz */
753 if (new_channel->band == IEEE80211_BAND_5GHZ && !old_band_5ghz) { 787 b43_phy_set(dev, B43_PHY_HT_BANDCTL, B43_PHY_HT_BANDCTL_5GHZ);
754 /* TODO */ 788 } else {
755 } else if (new_channel->band == IEEE80211_BAND_2GHZ && old_band_5ghz) { 789 /* Switch to 2 GHz */
756 /* TODO */ 790 b43_phy_mask(dev, B43_PHY_HT_BANDCTL, ~B43_PHY_HT_BANDCTL_5GHZ);
791
792 b43_phy_ht_bphy_reset(dev, false);
757 } 793 }
758 794
759 b43_phy_write(dev, B43_PHY_HT_BW1, e->bw1); 795 b43_phy_write(dev, B43_PHY_HT_BW1, e->bw1);
@@ -1002,19 +1038,10 @@ static void b43_phy_ht_op_software_rfkill(struct b43_wldev *dev,
1002 if (b43_read32(dev, B43_MMIO_MACCTL) & B43_MACCTL_ENABLED) 1038 if (b43_read32(dev, B43_MMIO_MACCTL) & B43_MACCTL_ENABLED)
1003 b43err(dev->wl, "MAC not suspended\n"); 1039 b43err(dev->wl, "MAC not suspended\n");
1004 1040
1005 /* In the following PHY ops we copy wl's dummy behaviour.
1006 * TODO: Find out if reads (currently hidden in masks/masksets) are
1007 * needed and replace following ops with just writes or w&r.
1008 * Note: B43_PHY_HT_RF_CTL1 register is tricky, wrong operation can
1009 * cause delayed (!) machine lock up. */
1010 if (blocked) { 1041 if (blocked) {
1011 b43_phy_mask(dev, B43_PHY_HT_RF_CTL1, 0); 1042 b43_phy_mask(dev, B43_PHY_HT_RF_CTL_CMD,
1043 ~B43_PHY_HT_RF_CTL_CMD_CHIP0_PU);
1012 } else { 1044 } else {
1013 b43_phy_mask(dev, B43_PHY_HT_RF_CTL1, 0);
1014 b43_phy_maskset(dev, B43_PHY_HT_RF_CTL1, 0, 0x1);
1015 b43_phy_mask(dev, B43_PHY_HT_RF_CTL1, 0);
1016 b43_phy_maskset(dev, B43_PHY_HT_RF_CTL1, 0, 0x2);
1017
1018 if (dev->phy.radio_ver == 0x2059) 1045 if (dev->phy.radio_ver == 0x2059)
1019 b43_radio_2059_init(dev); 1046 b43_radio_2059_init(dev);
1020 else 1047 else
diff --git a/drivers/net/wireless/b43/phy_ht.h b/drivers/net/wireless/b43/phy_ht.h
index 6cae370d1018..c086f56ce478 100644
--- a/drivers/net/wireless/b43/phy_ht.h
+++ b/drivers/net/wireless/b43/phy_ht.h
@@ -81,7 +81,9 @@
81#define B43_PHY_HT_RF_SEQ_STATUS B43_PHY_EXTG(0x004) 81#define B43_PHY_HT_RF_SEQ_STATUS B43_PHY_EXTG(0x004)
82/* Values for the status are the same as for the trigger */ 82/* Values for the status are the same as for the trigger */
83 83
84#define B43_PHY_HT_RF_CTL1 B43_PHY_EXTG(0x010) 84#define B43_PHY_HT_RF_CTL_CMD 0x810
85#define B43_PHY_HT_RF_CTL_CMD_FORCE 0x0001
86#define B43_PHY_HT_RF_CTL_CMD_CHIP0_PU 0x0002
85 87
86#define B43_PHY_HT_RF_CTL_INT_C1 B43_PHY_EXTG(0x04c) 88#define B43_PHY_HT_RF_CTL_INT_C1 B43_PHY_EXTG(0x04c)
87#define B43_PHY_HT_RF_CTL_INT_C2 B43_PHY_EXTG(0x06c) 89#define B43_PHY_HT_RF_CTL_INT_C2 B43_PHY_EXTG(0x06c)
@@ -104,6 +106,9 @@
104#define B43_PHY_HT_TXPCTL_TARG_PWR2_C3_SHIFT 0 106#define B43_PHY_HT_TXPCTL_TARG_PWR2_C3_SHIFT 0
105#define B43_PHY_HT_TX_PCTL_STATUS_C3 B43_PHY_EXTG(0x169) 107#define B43_PHY_HT_TX_PCTL_STATUS_C3 B43_PHY_EXTG(0x169)
106 108
109#define B43_PHY_B_BBCFG B43_PHY_N_BMODE(0x001)
110#define B43_PHY_B_BBCFG_RSTCCA 0x4000 /* Reset CCA */
111#define B43_PHY_B_BBCFG_RSTRX 0x8000 /* Reset RX */
107#define B43_PHY_HT_TEST B43_PHY_N_BMODE(0x00A) 112#define B43_PHY_HT_TEST B43_PHY_N_BMODE(0x00A)
108 113
109 114
diff --git a/drivers/net/wireless/b43/phy_n.c b/drivers/net/wireless/b43/phy_n.c
index cf625d8732a7..9f0bcf3b8414 100644
--- a/drivers/net/wireless/b43/phy_n.c
+++ b/drivers/net/wireless/b43/phy_n.c
@@ -6369,7 +6369,7 @@ static void b43_nphy_channel_setup(struct b43_wldev *dev,
6369 b43_mac_switch_freq(dev, spuravoid); 6369 b43_mac_switch_freq(dev, spuravoid);
6370 6370
6371 if (dev->phy.rev == 3 || dev->phy.rev == 4) 6371 if (dev->phy.rev == 3 || dev->phy.rev == 4)
6372 ; /* TODO: reset PLL */ 6372 b43_wireless_core_phy_pll_reset(dev);
6373 6373
6374 if (spuravoid) 6374 if (spuravoid)
6375 b43_phy_set(dev, B43_NPHY_BBCFG, B43_NPHY_BBCFG_RSTRX); 6375 b43_phy_set(dev, B43_NPHY_BBCFG, B43_NPHY_BBCFG_RSTRX);
diff --git a/drivers/net/wireless/b43/radio_2059.c b/drivers/net/wireless/b43/radio_2059.c
index 38e31d857e3e..a3cf9efd7e21 100644
--- a/drivers/net/wireless/b43/radio_2059.c
+++ b/drivers/net/wireless/b43/radio_2059.c
@@ -25,6 +25,13 @@
25#include "b43.h" 25#include "b43.h"
26#include "radio_2059.h" 26#include "radio_2059.h"
27 27
28/* Extracted from MMIO dump of 6.30.223.141 */
29static u16 r2059_phy_rev1_init[][2] = {
30 { 0x051, 0x70 }, { 0x05a, 0x03 }, { 0x079, 0x01 }, { 0x082, 0x70 },
31 { 0x083, 0x00 }, { 0x084, 0x70 }, { 0x09a, 0x7f }, { 0x0b6, 0x10 },
32 { 0x188, 0x05 },
33};
34
28#define RADIOREGS(r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, \ 35#define RADIOREGS(r00, r01, r02, r03, r04, r05, r06, r07, r08, r09, \
29 r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, \ 36 r10, r11, r12, r13, r14, r15, r16, r17, r18, r19, \
30 r20) \ 37 r20) \
@@ -58,73 +65,87 @@
58 .phy_regs.bw5 = r4, \ 65 .phy_regs.bw5 = r4, \
59 .phy_regs.bw6 = r5 66 .phy_regs.bw6 = r5
60 67
68/* Extracted from MMIO dump of 6.30.223.141
69 * TODO: Values for channels 12 & 13 are outdated (from some old 5.x driver)!
70 */
61static const struct b43_phy_ht_channeltab_e_radio2059 b43_phy_ht_channeltab_radio2059[] = { 71static const struct b43_phy_ht_channeltab_e_radio2059 b43_phy_ht_channeltab_radio2059[] = {
62 { .freq = 2412, 72 {
63 RADIOREGS(0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c, 73 .freq = 2412,
64 0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x03, 74 RADIOREGS(0x48, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x6c,
65 0x00, 0x00, 0x00, 0xf0, 0x00), 75 0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73,
66 PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443), 76 0x00, 0x00, 0x00, 0xd0, 0x00),
67 }, 77 PHYREGS(0x03c9, 0x03c5, 0x03c1, 0x043a, 0x043f, 0x0443),
68 { .freq = 2417, 78 },
69 RADIOREGS(0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71, 79 {
70 0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x03, 80 .freq = 2417,
71 0x00, 0x00, 0x00, 0xf0, 0x00), 81 RADIOREGS(0x4b, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x71,
72 PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441), 82 0x09, 0x0f, 0x0a, 0x00, 0x0a, 0x00, 0x61, 0x73,
73 }, 83 0x00, 0x00, 0x00, 0xd0, 0x00),
74 { .freq = 2422, 84 PHYREGS(0x03cb, 0x03c7, 0x03c3, 0x0438, 0x043d, 0x0441),
75 RADIOREGS(0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76, 85 },
76 0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x61, 0x03, 86 {
77 0x00, 0x00, 0x00, 0xf0, 0x00), 87 .freq = 2422,
78 PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f), 88 RADIOREGS(0x4e, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x76,
79 }, 89 0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x61, 0x73,
80 { .freq = 2427, 90 0x00, 0x00, 0x00, 0xd0, 0x00),
81 RADIOREGS(0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b, 91 PHYREGS(0x03cd, 0x03c9, 0x03c5, 0x0436, 0x043a, 0x043f),
82 0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x61, 0x03, 92 },
83 0x00, 0x00, 0x00, 0xf0, 0x00), 93 {
84 PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d), 94 .freq = 2427,
85 }, 95 RADIOREGS(0x52, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x7b,
86 { .freq = 2432, 96 0x09, 0x0f, 0x09, 0x00, 0x09, 0x00, 0x61, 0x73,
87 RADIOREGS(0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80, 97 0x00, 0x00, 0x00, 0xa0, 0x00),
88 0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x61, 0x03, 98 PHYREGS(0x03cf, 0x03cb, 0x03c7, 0x0434, 0x0438, 0x043d),
89 0x00, 0x00, 0x00, 0xf0, 0x00), 99 },
90 PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a), 100 {
91 }, 101 .freq = 2432,
92 { .freq = 2437, 102 RADIOREGS(0x55, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x80,
93 RADIOREGS(0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85, 103 0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x61, 0x73,
94 0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x61, 0x03, 104 0x00, 0x00, 0x00, 0xa0, 0x00),
95 0x00, 0x00, 0x00, 0xf0, 0x00), 105 PHYREGS(0x03d1, 0x03cd, 0x03c9, 0x0431, 0x0436, 0x043a),
96 PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438), 106 },
97 }, 107 {
98 { .freq = 2442, 108 .freq = 2437,
99 RADIOREGS(0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a, 109 RADIOREGS(0x58, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x85,
100 0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x61, 0x03, 110 0x09, 0x0f, 0x08, 0x00, 0x08, 0x00, 0x61, 0x73,
101 0x00, 0x00, 0x00, 0xf0, 0x00), 111 0x00, 0x00, 0x00, 0xa0, 0x00),
102 PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436), 112 PHYREGS(0x03d3, 0x03cf, 0x03cb, 0x042f, 0x0434, 0x0438),
103 }, 113 },
104 { .freq = 2447, 114 {
105 RADIOREGS(0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f, 115 .freq = 2442,
106 0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x61, 0x03, 116 RADIOREGS(0x5c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8a,
107 0x00, 0x00, 0x00, 0xf0, 0x00), 117 0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x61, 0x73,
108 PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434), 118 0x00, 0x00, 0x00, 0x80, 0x00),
109 }, 119 PHYREGS(0x03d5, 0x03d1, 0x03cd, 0x042d, 0x0431, 0x0436),
110 { .freq = 2452, 120 },
111 RADIOREGS(0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94, 121 {
112 0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x61, 0x03, 122 .freq = 2447,
113 0x00, 0x00, 0x00, 0xf0, 0x00), 123 RADIOREGS(0x5f, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x8f,
114 PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431), 124 0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x61, 0x73,
115 }, 125 0x00, 0x00, 0x00, 0x80, 0x00),
116 { .freq = 2457, 126 PHYREGS(0x03d7, 0x03d3, 0x03cf, 0x042b, 0x042f, 0x0434),
117 RADIOREGS(0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99, 127 },
118 0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x61, 0x03, 128 {
119 0x00, 0x00, 0x00, 0xf0, 0x00), 129 .freq = 2452,
120 PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f), 130 RADIOREGS(0x62, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x94,
121 }, 131 0x09, 0x0f, 0x07, 0x00, 0x07, 0x00, 0x61, 0x73,
122 { .freq = 2462, 132 0x00, 0x00, 0x00, 0x80, 0x00),
123 RADIOREGS(0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e, 133 PHYREGS(0x03d9, 0x03d5, 0x03d1, 0x0429, 0x042d, 0x0431),
124 0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x61, 0x03, 134 },
125 0x00, 0x00, 0x00, 0xf0, 0x00), 135 {
126 PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d), 136 .freq = 2457,
127 }, 137 RADIOREGS(0x66, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x99,
138 0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x61, 0x73,
139 0x00, 0x00, 0x00, 0x60, 0x00),
140 PHYREGS(0x03db, 0x03d7, 0x03d3, 0x0427, 0x042b, 0x042f),
141 },
142 {
143 .freq = 2462,
144 RADIOREGS(0x69, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0x9e,
145 0x09, 0x0f, 0x06, 0x00, 0x06, 0x00, 0x61, 0x73,
146 0x00, 0x00, 0x00, 0x60, 0x00),
147 PHYREGS(0x03dd, 0x03d9, 0x03d5, 0x0424, 0x0429, 0x042d),
148 },
128 { .freq = 2467, 149 { .freq = 2467,
129 RADIOREGS(0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3, 150 RADIOREGS(0x6c, 0x16, 0x30, 0x1b, 0x0a, 0x0a, 0x30, 0xa3,
130 0x09, 0x0f, 0x05, 0x00, 0x05, 0x00, 0x61, 0x03, 151 0x09, 0x0f, 0x05, 0x00, 0x05, 0x00, 0x61, 0x03,
@@ -137,8 +158,196 @@ static const struct b43_phy_ht_channeltab_e_radio2059 b43_phy_ht_channeltab_radi
137 0x00, 0x00, 0x00, 0xf0, 0x00), 158 0x00, 0x00, 0x00, 0xf0, 0x00),
138 PHYREGS(0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429), 159 PHYREGS(0x03e1, 0x03dd, 0x03d9, 0x0420, 0x0424, 0x0429),
139 }, 160 },
161 {
162 .freq = 5180,
163 RADIOREGS(0xbe, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x06,
164 0x02, 0x0c, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x00,
165 0x0f, 0x4f, 0xa3, 0x00, 0xfc),
166 PHYREGS(0x081c, 0x0818, 0x0814, 0x01f9, 0x01fa, 0x01fb),
167 },
168 {
169 .freq = 5200,
170 RADIOREGS(0xc5, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x08,
171 0x02, 0x0c, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x00,
172 0x0f, 0x4f, 0x93, 0x00, 0xfb),
173 PHYREGS(0x0824, 0x0820, 0x081c, 0x01f7, 0x01f8, 0x01f9),
174 },
175 {
176 .freq = 5220,
177 RADIOREGS(0xcc, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x0a,
178 0x02, 0x0c, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x00,
179 0x0f, 0x4f, 0x93, 0x00, 0xea),
180 PHYREGS(0x082c, 0x0828, 0x0824, 0x01f5, 0x01f6, 0x01f7),
181 },
182 {
183 .freq = 5240,
184 RADIOREGS(0xd2, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x0c,
185 0x02, 0x0c, 0x00, 0x0c, 0x00, 0x0c, 0x00, 0x00,
186 0x0f, 0x4f, 0x93, 0x00, 0xda),
187 PHYREGS(0x0834, 0x0830, 0x082c, 0x01f3, 0x01f4, 0x01f5),
188 },
189 {
190 .freq = 5260,
191 RADIOREGS(0xd9, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x0e,
192 0x02, 0x0b, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x00,
193 0x0f, 0x4f, 0x93, 0x00, 0xca),
194 PHYREGS(0x083c, 0x0838, 0x0834, 0x01f1, 0x01f2, 0x01f3),
195 },
196 {
197 .freq = 5280,
198 RADIOREGS(0xe0, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x10,
199 0x02, 0x0b, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x00,
200 0x0f, 0x4f, 0x93, 0x00, 0xb9),
201 PHYREGS(0x0844, 0x0840, 0x083c, 0x01f0, 0x01f0, 0x01f1),
202 },
203 {
204 .freq = 5300,
205 RADIOREGS(0xe6, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x12,
206 0x02, 0x0b, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x00,
207 0x0f, 0x4c, 0x83, 0x00, 0xb8),
208 PHYREGS(0x084c, 0x0848, 0x0844, 0x01ee, 0x01ef, 0x01f0),
209 },
210 {
211 .freq = 5320,
212 RADIOREGS(0xed, 0x16, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x14,
213 0x02, 0x0b, 0x00, 0x0b, 0x00, 0x0b, 0x00, 0x00,
214 0x0f, 0x4c, 0x83, 0x00, 0xa8),
215 PHYREGS(0x0854, 0x0850, 0x084c, 0x01ec, 0x01ed, 0x01ee),
216 },
217 {
218 .freq = 5500,
219 RADIOREGS(0x29, 0x17, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x26,
220 0x02, 0x09, 0x00, 0x09, 0x00, 0x09, 0x00, 0x00,
221 0x0a, 0x46, 0x43, 0x00, 0x75),
222 PHYREGS(0x089c, 0x0898, 0x0894, 0x01dc, 0x01dd, 0x01dd),
223 },
224 {
225 .freq = 5520,
226 RADIOREGS(0x30, 0x17, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x28,
227 0x02, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00,
228 0x0a, 0x46, 0x43, 0x00, 0x75),
229 PHYREGS(0x08a4, 0x08a0, 0x089c, 0x01da, 0x01db, 0x01dc),
230 },
231 {
232 .freq = 5540,
233 RADIOREGS(0x36, 0x17, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x2a,
234 0x02, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00,
235 0x0a, 0x46, 0x43, 0x00, 0x75),
236 PHYREGS(0x08ac, 0x08a8, 0x08a4, 0x01d8, 0x01d9, 0x01da),
237 },
238 {
239 .freq = 5560,
240 RADIOREGS(0x3d, 0x17, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x2c,
241 0x02, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00,
242 0x0a, 0x46, 0x43, 0x00, 0x75),
243 PHYREGS(0x08b4, 0x08b0, 0x08ac, 0x01d7, 0x01d7, 0x01d8),
244 },
245 {
246 .freq = 5580,
247 RADIOREGS(0x44, 0x17, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x2e,
248 0x02, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00,
249 0x0a, 0x46, 0x43, 0x00, 0x74),
250 PHYREGS(0x08bc, 0x08b8, 0x08b4, 0x01d5, 0x01d6, 0x01d7),
251 },
252 {
253 .freq = 5600,
254 RADIOREGS(0x4a, 0x17, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x30,
255 0x02, 0x08, 0x00, 0x08, 0x00, 0x08, 0x00, 0x00,
256 0x09, 0x44, 0x23, 0x00, 0x54),
257 PHYREGS(0x08c4, 0x08c0, 0x08bc, 0x01d3, 0x01d4, 0x01d5),
258 },
259 {
260 .freq = 5620,
261 RADIOREGS(0x51, 0x17, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x32,
262 0x02, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00,
263 0x09, 0x44, 0x23, 0x00, 0x54),
264 PHYREGS(0x08cc, 0x08c8, 0x08c4, 0x01d2, 0x01d2, 0x01d3),
265 },
266 {
267 .freq = 5640,
268 RADIOREGS(0x58, 0x17, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x34,
269 0x02, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00,
270 0x09, 0x44, 0x23, 0x00, 0x43),
271 PHYREGS(0x08d4, 0x08d0, 0x08cc, 0x01d0, 0x01d1, 0x01d2),
272 },
273 {
274 .freq = 5660,
275 RADIOREGS(0x5e, 0x17, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x36,
276 0x02, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00,
277 0x09, 0x43, 0x23, 0x00, 0x43),
278 PHYREGS(0x08dc, 0x08d8, 0x08d4, 0x01ce, 0x01cf, 0x01d0),
279 },
280 {
281 .freq = 5680,
282 RADIOREGS(0x65, 0x17, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x38,
283 0x02, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00,
284 0x09, 0x42, 0x23, 0x00, 0x43),
285 PHYREGS(0x08e4, 0x08e0, 0x08dc, 0x01cd, 0x01ce, 0x01ce),
286 },
287 {
288 .freq = 5700,
289 RADIOREGS(0x6c, 0x17, 0x10, 0x1f, 0x08, 0x08, 0x3f, 0x3a,
290 0x02, 0x07, 0x00, 0x07, 0x00, 0x07, 0x00, 0x00,
291 0x08, 0x42, 0x13, 0x00, 0x32),
292 PHYREGS(0x08ec, 0x08e8, 0x08e4, 0x01cb, 0x01cc, 0x01cd),
293 },
294 {
295 .freq = 5745,
296 RADIOREGS(0x7b, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x7d,
297 0x04, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00,
298 0x08, 0x42, 0x13, 0x00, 0x21),
299 PHYREGS(0x08fe, 0x08fa, 0x08f6, 0x01c8, 0x01c8, 0x01c9),
300 },
301 {
302 .freq = 5765,
303 RADIOREGS(0x81, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x81,
304 0x04, 0x06, 0x00, 0x06, 0x00, 0x06, 0x00, 0x00,
305 0x08, 0x42, 0x13, 0x00, 0x11),
306 PHYREGS(0x0906, 0x0902, 0x08fe, 0x01c6, 0x01c7, 0x01c8),
307 },
308 {
309 .freq = 5785,
310 RADIOREGS(0x88, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x85,
311 0x04, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x00,
312 0x08, 0x42, 0x13, 0x00, 0x00),
313 PHYREGS(0x090e, 0x090a, 0x0906, 0x01c4, 0x01c5, 0x01c6),
314 },
315 {
316 .freq = 5805,
317 RADIOREGS(0x8f, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x89,
318 0x04, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x00,
319 0x06, 0x41, 0x03, 0x00, 0x00),
320 PHYREGS(0x0916, 0x0912, 0x090e, 0x01c3, 0x01c4, 0x01c4),
321 },
322 {
323 .freq = 5825,
324 RADIOREGS(0x95, 0x17, 0x20, 0x1f, 0x08, 0x08, 0x3f, 0x8d,
325 0x04, 0x05, 0x00, 0x05, 0x00, 0x05, 0x00, 0x00,
326 0x06, 0x41, 0x03, 0x00, 0x00),
327 PHYREGS(0x091e, 0x091a, 0x0916, 0x01c1, 0x01c2, 0x01c3),
328 },
140}; 329};
141 330
331void r2059_upload_inittabs(struct b43_wldev *dev)
332{
333 struct b43_phy *phy = &dev->phy;
334 u16 *table = NULL;
335 u16 size, i;
336
337 switch (phy->rev) {
338 case 1:
339 table = r2059_phy_rev1_init[0];
340 size = ARRAY_SIZE(r2059_phy_rev1_init);
341 break;
342 default:
343 B43_WARN_ON(1);
344 return;
345 }
346
347 for (i = 0; i < size; i++, table += 2)
348 b43_radio_write(dev, R2059_ALL | table[0], table[1]);
349}
350
142const struct b43_phy_ht_channeltab_e_radio2059 351const struct b43_phy_ht_channeltab_e_radio2059
143*b43_phy_ht_get_channeltab_e_r2059(struct b43_wldev *dev, u16 freq) 352*b43_phy_ht_get_channeltab_e_r2059(struct b43_wldev *dev, u16 freq)
144{ 353{
diff --git a/drivers/net/wireless/b43/radio_2059.h b/drivers/net/wireless/b43/radio_2059.h
index 40a82d7f510c..9e22fb60588b 100644
--- a/drivers/net/wireless/b43/radio_2059.h
+++ b/drivers/net/wireless/b43/radio_2059.h
@@ -10,6 +10,18 @@
10#define R2059_C3 0x800 10#define R2059_C3 0x800
11#define R2059_ALL 0xC00 11#define R2059_ALL 0xC00
12 12
13#define R2059_RCAL_CONFIG 0x004
14#define R2059_RFPLL_MASTER 0x011
15#define R2059_RFPLL_MISC_EN 0x02b
16#define R2059_RFPLL_MISC_CAL_RESETN 0x02e
17#define R2059_XTAL_CONFIG2 0x0c0
18#define R2059_RCCAL_START_R1_Q1_P1 0x13c
19#define R2059_RCCAL_X1 0x13d
20#define R2059_RCCAL_TRC0 0x13e
21#define R2059_RCCAL_DONE_OSCCAP 0x140
22#define R2059_RCAL_STATUS 0x145
23#define R2059_RCCAL_MASTER 0x17f
24
13/* Values for various registers uploaded on channel switching */ 25/* Values for various registers uploaded on channel switching */
14struct b43_phy_ht_channeltab_e_radio2059 { 26struct b43_phy_ht_channeltab_e_radio2059 {
15 /* The channel frequency in MHz */ 27 /* The channel frequency in MHz */
@@ -40,6 +52,8 @@ struct b43_phy_ht_channeltab_e_radio2059 {
40 struct b43_phy_ht_channeltab_e_phy phy_regs; 52 struct b43_phy_ht_channeltab_e_phy phy_regs;
41}; 53};
42 54
55void r2059_upload_inittabs(struct b43_wldev *dev);
56
43const struct b43_phy_ht_channeltab_e_radio2059 57const struct b43_phy_ht_channeltab_e_radio2059
44*b43_phy_ht_get_channeltab_e_r2059(struct b43_wldev *dev, u16 freq); 58*b43_phy_ht_get_channeltab_e_r2059(struct b43_wldev *dev, u16 freq);
45 59
diff --git a/drivers/net/wireless/b43/xmit.h b/drivers/net/wireless/b43/xmit.h
index 98d90747836a..ba6115308068 100644
--- a/drivers/net/wireless/b43/xmit.h
+++ b/drivers/net/wireless/b43/xmit.h
@@ -97,9 +97,13 @@ struct b43_tx_legacy_rate_phy_ctl_entry {
97}; 97};
98 98
99/* MAC TX control */ 99/* MAC TX control */
100#define B43_TXH_MAC_RTS_FB_SHORTPRMBL 0x80000000 /* RTS fallback preamble */
101#define B43_TXH_MAC_RTS_SHORTPRMBL 0x40000000 /* RTS main rate preamble */
102#define B43_TXH_MAC_FB_SHORTPRMBL 0x20000000 /* Main fallback preamble */
100#define B43_TXH_MAC_USEFBR 0x10000000 /* Use fallback rate for this AMPDU */ 103#define B43_TXH_MAC_USEFBR 0x10000000 /* Use fallback rate for this AMPDU */
101#define B43_TXH_MAC_KEYIDX 0x0FF00000 /* Security key index */ 104#define B43_TXH_MAC_KEYIDX 0x0FF00000 /* Security key index */
102#define B43_TXH_MAC_KEYIDX_SHIFT 20 105#define B43_TXH_MAC_KEYIDX_SHIFT 20
106#define B43_TXH_MAC_ALT_TXPWR 0x00080000 /* Use alternate txpwr defined at loc. M_ALT_TXPWR_IDX */
103#define B43_TXH_MAC_KEYALG 0x00070000 /* Security key algorithm */ 107#define B43_TXH_MAC_KEYALG 0x00070000 /* Security key algorithm */
104#define B43_TXH_MAC_KEYALG_SHIFT 16 108#define B43_TXH_MAC_KEYALG_SHIFT 16
105#define B43_TXH_MAC_AMIC 0x00008000 /* AMIC */ 109#define B43_TXH_MAC_AMIC 0x00008000 /* AMIC */
@@ -126,25 +130,25 @@ struct b43_tx_legacy_rate_phy_ctl_entry {
126#define B43_TXH_EFT_FB 0x03 /* Data frame fallback encoding */ 130#define B43_TXH_EFT_FB 0x03 /* Data frame fallback encoding */
127#define B43_TXH_EFT_FB_CCK 0x00 /* CCK */ 131#define B43_TXH_EFT_FB_CCK 0x00 /* CCK */
128#define B43_TXH_EFT_FB_OFDM 0x01 /* OFDM */ 132#define B43_TXH_EFT_FB_OFDM 0x01 /* OFDM */
129#define B43_TXH_EFT_FB_EWC 0x02 /* EWC */ 133#define B43_TXH_EFT_FB_HT 0x02 /* HT */
130#define B43_TXH_EFT_FB_N 0x03 /* N */ 134#define B43_TXH_EFT_FB_VHT 0x03 /* VHT */
131#define B43_TXH_EFT_RTS 0x0C /* RTS/CTS encoding */ 135#define B43_TXH_EFT_RTS 0x0C /* RTS/CTS encoding */
132#define B43_TXH_EFT_RTS_CCK 0x00 /* CCK */ 136#define B43_TXH_EFT_RTS_CCK 0x00 /* CCK */
133#define B43_TXH_EFT_RTS_OFDM 0x04 /* OFDM */ 137#define B43_TXH_EFT_RTS_OFDM 0x04 /* OFDM */
134#define B43_TXH_EFT_RTS_EWC 0x08 /* EWC */ 138#define B43_TXH_EFT_RTS_HT 0x08 /* HT */
135#define B43_TXH_EFT_RTS_N 0x0C /* N */ 139#define B43_TXH_EFT_RTS_VHT 0x0C /* VHT */
136#define B43_TXH_EFT_RTSFB 0x30 /* RTS/CTS fallback encoding */ 140#define B43_TXH_EFT_RTSFB 0x30 /* RTS/CTS fallback encoding */
137#define B43_TXH_EFT_RTSFB_CCK 0x00 /* CCK */ 141#define B43_TXH_EFT_RTSFB_CCK 0x00 /* CCK */
138#define B43_TXH_EFT_RTSFB_OFDM 0x10 /* OFDM */ 142#define B43_TXH_EFT_RTSFB_OFDM 0x10 /* OFDM */
139#define B43_TXH_EFT_RTSFB_EWC 0x20 /* EWC */ 143#define B43_TXH_EFT_RTSFB_HT 0x20 /* HT */
140#define B43_TXH_EFT_RTSFB_N 0x30 /* N */ 144#define B43_TXH_EFT_RTSFB_VHT 0x30 /* VHT */
141 145
142/* PHY TX control word */ 146/* PHY TX control word */
143#define B43_TXH_PHY_ENC 0x0003 /* Data frame encoding */ 147#define B43_TXH_PHY_ENC 0x0003 /* Data frame encoding */
144#define B43_TXH_PHY_ENC_CCK 0x0000 /* CCK */ 148#define B43_TXH_PHY_ENC_CCK 0x0000 /* CCK */
145#define B43_TXH_PHY_ENC_OFDM 0x0001 /* OFDM */ 149#define B43_TXH_PHY_ENC_OFDM 0x0001 /* OFDM */
146#define B43_TXH_PHY_ENC_EWC 0x0002 /* EWC */ 150#define B43_TXH_PHY_ENC_HT 0x0002 /* HT */
147#define B43_TXH_PHY_ENC_N 0x0003 /* N */ 151#define B43_TXH_PHY_ENC_VHT 0x0003 /* VHT */
148#define B43_TXH_PHY_SHORTPRMBL 0x0010 /* Use short preamble */ 152#define B43_TXH_PHY_SHORTPRMBL 0x0010 /* Use short preamble */
149#define B43_TXH_PHY_ANT 0x03C0 /* Antenna selection */ 153#define B43_TXH_PHY_ANT 0x03C0 /* Antenna selection */
150#define B43_TXH_PHY_ANT0 0x0000 /* Use antenna 0 */ 154#define B43_TXH_PHY_ANT0 0x0000 /* Use antenna 0 */
@@ -162,7 +166,7 @@ struct b43_tx_legacy_rate_phy_ctl_entry {
162#define B43_TXH_PHY1_BW_20 0x0002 /* 20 MHz */ 166#define B43_TXH_PHY1_BW_20 0x0002 /* 20 MHz */
163#define B43_TXH_PHY1_BW_20U 0x0003 /* 20 MHz upper */ 167#define B43_TXH_PHY1_BW_20U 0x0003 /* 20 MHz upper */
164#define B43_TXH_PHY1_BW_40 0x0004 /* 40 MHz */ 168#define B43_TXH_PHY1_BW_40 0x0004 /* 40 MHz */
165#define B43_TXH_PHY1_BW_40DUP 0x0005 /* 50 MHz duplicate */ 169#define B43_TXH_PHY1_BW_40DUP 0x0005 /* 40 MHz duplicate */
166#define B43_TXH_PHY1_MODE 0x0038 /* Mode */ 170#define B43_TXH_PHY1_MODE 0x0038 /* Mode */
167#define B43_TXH_PHY1_MODE_SISO 0x0000 /* SISO */ 171#define B43_TXH_PHY1_MODE_SISO 0x0000 /* SISO */
168#define B43_TXH_PHY1_MODE_CDD 0x0008 /* CDD */ 172#define B43_TXH_PHY1_MODE_CDD 0x0008 /* CDD */
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/dma.c b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
index 4fb9635d3919..796f5f9d5d5a 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/dma.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/dma.c
@@ -746,7 +746,7 @@ dma64_dd_upd(struct dma_info *di, struct dma64desc *ddring,
746/* !! may be called with core in reset */ 746/* !! may be called with core in reset */
747void dma_detach(struct dma_pub *pub) 747void dma_detach(struct dma_pub *pub)
748{ 748{
749 struct dma_info *di = (struct dma_info *)pub; 749 struct dma_info *di = container_of(pub, struct dma_info, dma);
750 750
751 brcms_dbg_dma(di->core, "%s:\n", di->name); 751 brcms_dbg_dma(di->core, "%s:\n", di->name);
752 752
@@ -842,7 +842,7 @@ static void _dma_rxenable(struct dma_info *di)
842 842
843void dma_rxinit(struct dma_pub *pub) 843void dma_rxinit(struct dma_pub *pub)
844{ 844{
845 struct dma_info *di = (struct dma_info *)pub; 845 struct dma_info *di = container_of(pub, struct dma_info, dma);
846 846
847 brcms_dbg_dma(di->core, "%s:\n", di->name); 847 brcms_dbg_dma(di->core, "%s:\n", di->name);
848 848
@@ -924,7 +924,7 @@ static struct sk_buff *_dma_getnextrxp(struct dma_info *di, bool forceall)
924 */ 924 */
925int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list) 925int dma_rx(struct dma_pub *pub, struct sk_buff_head *skb_list)
926{ 926{
927 struct dma_info *di = (struct dma_info *)pub; 927 struct dma_info *di = container_of(pub, struct dma_info, dma);
928 struct sk_buff_head dma_frames; 928 struct sk_buff_head dma_frames;
929 struct sk_buff *p, *next; 929 struct sk_buff *p, *next;
930 uint len; 930 uint len;
@@ -1022,7 +1022,7 @@ static bool dma64_txidle(struct dma_info *di)
1022 */ 1022 */
1023bool dma_rxfill(struct dma_pub *pub) 1023bool dma_rxfill(struct dma_pub *pub)
1024{ 1024{
1025 struct dma_info *di = (struct dma_info *)pub; 1025 struct dma_info *di = container_of(pub, struct dma_info, dma);
1026 struct sk_buff *p; 1026 struct sk_buff *p;
1027 u16 rxin, rxout; 1027 u16 rxin, rxout;
1028 u32 flags = 0; 1028 u32 flags = 0;
@@ -1106,7 +1106,7 @@ bool dma_rxfill(struct dma_pub *pub)
1106 1106
1107void dma_rxreclaim(struct dma_pub *pub) 1107void dma_rxreclaim(struct dma_pub *pub)
1108{ 1108{
1109 struct dma_info *di = (struct dma_info *)pub; 1109 struct dma_info *di = container_of(pub, struct dma_info, dma);
1110 struct sk_buff *p; 1110 struct sk_buff *p;
1111 1111
1112 brcms_dbg_dma(di->core, "%s:\n", di->name); 1112 brcms_dbg_dma(di->core, "%s:\n", di->name);
@@ -1126,7 +1126,7 @@ void dma_counterreset(struct dma_pub *pub)
1126/* get the address of the var in order to change later */ 1126/* get the address of the var in order to change later */
1127unsigned long dma_getvar(struct dma_pub *pub, const char *name) 1127unsigned long dma_getvar(struct dma_pub *pub, const char *name)
1128{ 1128{
1129 struct dma_info *di = (struct dma_info *)pub; 1129 struct dma_info *di = container_of(pub, struct dma_info, dma);
1130 1130
1131 if (!strcmp(name, "&txavail")) 1131 if (!strcmp(name, "&txavail"))
1132 return (unsigned long)&(di->dma.txavail); 1132 return (unsigned long)&(di->dma.txavail);
@@ -1137,7 +1137,7 @@ unsigned long dma_getvar(struct dma_pub *pub, const char *name)
1137 1137
1138void dma_txinit(struct dma_pub *pub) 1138void dma_txinit(struct dma_pub *pub)
1139{ 1139{
1140 struct dma_info *di = (struct dma_info *)pub; 1140 struct dma_info *di = container_of(pub, struct dma_info, dma);
1141 u32 control = D64_XC_XE; 1141 u32 control = D64_XC_XE;
1142 1142
1143 brcms_dbg_dma(di->core, "%s:\n", di->name); 1143 brcms_dbg_dma(di->core, "%s:\n", di->name);
@@ -1170,7 +1170,7 @@ void dma_txinit(struct dma_pub *pub)
1170 1170
1171void dma_txsuspend(struct dma_pub *pub) 1171void dma_txsuspend(struct dma_pub *pub)
1172{ 1172{
1173 struct dma_info *di = (struct dma_info *)pub; 1173 struct dma_info *di = container_of(pub, struct dma_info, dma);
1174 1174
1175 brcms_dbg_dma(di->core, "%s:\n", di->name); 1175 brcms_dbg_dma(di->core, "%s:\n", di->name);
1176 1176
@@ -1182,7 +1182,7 @@ void dma_txsuspend(struct dma_pub *pub)
1182 1182
1183void dma_txresume(struct dma_pub *pub) 1183void dma_txresume(struct dma_pub *pub)
1184{ 1184{
1185 struct dma_info *di = (struct dma_info *)pub; 1185 struct dma_info *di = container_of(pub, struct dma_info, dma);
1186 1186
1187 brcms_dbg_dma(di->core, "%s:\n", di->name); 1187 brcms_dbg_dma(di->core, "%s:\n", di->name);
1188 1188
@@ -1194,7 +1194,7 @@ void dma_txresume(struct dma_pub *pub)
1194 1194
1195bool dma_txsuspended(struct dma_pub *pub) 1195bool dma_txsuspended(struct dma_pub *pub)
1196{ 1196{
1197 struct dma_info *di = (struct dma_info *)pub; 1197 struct dma_info *di = container_of(pub, struct dma_info, dma);
1198 1198
1199 return (di->ntxd == 0) || 1199 return (di->ntxd == 0) ||
1200 ((bcma_read32(di->core, 1200 ((bcma_read32(di->core,
@@ -1204,7 +1204,7 @@ bool dma_txsuspended(struct dma_pub *pub)
1204 1204
1205void dma_txreclaim(struct dma_pub *pub, enum txd_range range) 1205void dma_txreclaim(struct dma_pub *pub, enum txd_range range)
1206{ 1206{
1207 struct dma_info *di = (struct dma_info *)pub; 1207 struct dma_info *di = container_of(pub, struct dma_info, dma);
1208 struct sk_buff *p; 1208 struct sk_buff *p;
1209 1209
1210 brcms_dbg_dma(di->core, "%s: %s\n", 1210 brcms_dbg_dma(di->core, "%s: %s\n",
@@ -1225,7 +1225,7 @@ void dma_txreclaim(struct dma_pub *pub, enum txd_range range)
1225 1225
1226bool dma_txreset(struct dma_pub *pub) 1226bool dma_txreset(struct dma_pub *pub)
1227{ 1227{
1228 struct dma_info *di = (struct dma_info *)pub; 1228 struct dma_info *di = container_of(pub, struct dma_info, dma);
1229 u32 status; 1229 u32 status;
1230 1230
1231 if (di->ntxd == 0) 1231 if (di->ntxd == 0)
@@ -1252,7 +1252,7 @@ bool dma_txreset(struct dma_pub *pub)
1252 1252
1253bool dma_rxreset(struct dma_pub *pub) 1253bool dma_rxreset(struct dma_pub *pub)
1254{ 1254{
1255 struct dma_info *di = (struct dma_info *)pub; 1255 struct dma_info *di = container_of(pub, struct dma_info, dma);
1256 u32 status; 1256 u32 status;
1257 1257
1258 if (di->nrxd == 0) 1258 if (di->nrxd == 0)
@@ -1377,7 +1377,7 @@ static void dma_update_txavail(struct dma_info *di)
1377int dma_txfast(struct brcms_c_info *wlc, struct dma_pub *pub, 1377int dma_txfast(struct brcms_c_info *wlc, struct dma_pub *pub,
1378 struct sk_buff *p) 1378 struct sk_buff *p)
1379{ 1379{
1380 struct dma_info *di = (struct dma_info *)pub; 1380 struct dma_info *di = container_of(pub, struct dma_info, dma);
1381 struct brcms_ampdu_session *session = &di->ampdu_session; 1381 struct brcms_ampdu_session *session = &di->ampdu_session;
1382 struct ieee80211_tx_info *tx_info; 1382 struct ieee80211_tx_info *tx_info;
1383 bool is_ampdu; 1383 bool is_ampdu;
@@ -1427,7 +1427,7 @@ int dma_txfast(struct brcms_c_info *wlc, struct dma_pub *pub,
1427 1427
1428void dma_txflush(struct dma_pub *pub) 1428void dma_txflush(struct dma_pub *pub)
1429{ 1429{
1430 struct dma_info *di = (struct dma_info *)pub; 1430 struct dma_info *di = container_of(pub, struct dma_info, dma);
1431 struct brcms_ampdu_session *session = &di->ampdu_session; 1431 struct brcms_ampdu_session *session = &di->ampdu_session;
1432 1432
1433 if (!skb_queue_empty(&session->skb_list)) 1433 if (!skb_queue_empty(&session->skb_list))
@@ -1436,7 +1436,7 @@ void dma_txflush(struct dma_pub *pub)
1436 1436
1437int dma_txpending(struct dma_pub *pub) 1437int dma_txpending(struct dma_pub *pub)
1438{ 1438{
1439 struct dma_info *di = (struct dma_info *)pub; 1439 struct dma_info *di = container_of(pub, struct dma_info, dma);
1440 return ntxdactive(di, di->txin, di->txout); 1440 return ntxdactive(di, di->txin, di->txout);
1441} 1441}
1442 1442
@@ -1446,7 +1446,7 @@ int dma_txpending(struct dma_pub *pub)
1446 */ 1446 */
1447void dma_kick_tx(struct dma_pub *pub) 1447void dma_kick_tx(struct dma_pub *pub)
1448{ 1448{
1449 struct dma_info *di = (struct dma_info *)pub; 1449 struct dma_info *di = container_of(pub, struct dma_info, dma);
1450 struct brcms_ampdu_session *session = &di->ampdu_session; 1450 struct brcms_ampdu_session *session = &di->ampdu_session;
1451 1451
1452 if (!skb_queue_empty(&session->skb_list) && dma64_txidle(di)) 1452 if (!skb_queue_empty(&session->skb_list) && dma64_txidle(di))
@@ -1465,7 +1465,7 @@ void dma_kick_tx(struct dma_pub *pub)
1465 */ 1465 */
1466struct sk_buff *dma_getnexttxp(struct dma_pub *pub, enum txd_range range) 1466struct sk_buff *dma_getnexttxp(struct dma_pub *pub, enum txd_range range)
1467{ 1467{
1468 struct dma_info *di = (struct dma_info *)pub; 1468 struct dma_info *di = container_of(pub, struct dma_info, dma);
1469 u16 start, end, i; 1469 u16 start, end, i;
1470 u16 active_desc; 1470 u16 active_desc;
1471 struct sk_buff *txp; 1471 struct sk_buff *txp;
@@ -1547,7 +1547,7 @@ struct sk_buff *dma_getnexttxp(struct dma_pub *pub, enum txd_range range)
1547void dma_walk_packets(struct dma_pub *dmah, void (*callback_fnc) 1547void dma_walk_packets(struct dma_pub *dmah, void (*callback_fnc)
1548 (void *pkt, void *arg_a), void *arg_a) 1548 (void *pkt, void *arg_a), void *arg_a)
1549{ 1549{
1550 struct dma_info *di = (struct dma_info *) dmah; 1550 struct dma_info *di = container_of(dmah, struct dma_info, dma);
1551 uint i = di->txin; 1551 uint i = di->txin;
1552 uint end = di->txout; 1552 uint end = di->txout;
1553 struct sk_buff *skb; 1553 struct sk_buff *skb;
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c
index 57ecc05802e9..941b1e41f366 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_cmn.c
@@ -128,19 +128,19 @@ static const u8 ofdm_rate_lookup[] = {
128 128
129void wlc_phyreg_enter(struct brcms_phy_pub *pih) 129void wlc_phyreg_enter(struct brcms_phy_pub *pih)
130{ 130{
131 struct brcms_phy *pi = (struct brcms_phy *) pih; 131 struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro);
132 wlapi_bmac_ucode_wake_override_phyreg_set(pi->sh->physhim); 132 wlapi_bmac_ucode_wake_override_phyreg_set(pi->sh->physhim);
133} 133}
134 134
135void wlc_phyreg_exit(struct brcms_phy_pub *pih) 135void wlc_phyreg_exit(struct brcms_phy_pub *pih)
136{ 136{
137 struct brcms_phy *pi = (struct brcms_phy *) pih; 137 struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro);
138 wlapi_bmac_ucode_wake_override_phyreg_clear(pi->sh->physhim); 138 wlapi_bmac_ucode_wake_override_phyreg_clear(pi->sh->physhim);
139} 139}
140 140
141void wlc_radioreg_enter(struct brcms_phy_pub *pih) 141void wlc_radioreg_enter(struct brcms_phy_pub *pih)
142{ 142{
143 struct brcms_phy *pi = (struct brcms_phy *) pih; 143 struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro);
144 wlapi_bmac_mctrl(pi->sh->physhim, MCTL_LOCK_RADIO, MCTL_LOCK_RADIO); 144 wlapi_bmac_mctrl(pi->sh->physhim, MCTL_LOCK_RADIO, MCTL_LOCK_RADIO);
145 145
146 udelay(10); 146 udelay(10);
@@ -148,7 +148,7 @@ void wlc_radioreg_enter(struct brcms_phy_pub *pih)
148 148
149void wlc_radioreg_exit(struct brcms_phy_pub *pih) 149void wlc_radioreg_exit(struct brcms_phy_pub *pih)
150{ 150{
151 struct brcms_phy *pi = (struct brcms_phy *) pih; 151 struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro);
152 152
153 (void)bcma_read16(pi->d11core, D11REGOFFS(phyversion)); 153 (void)bcma_read16(pi->d11core, D11REGOFFS(phyversion));
154 pi->phy_wreg = 0; 154 pi->phy_wreg = 0;
@@ -586,7 +586,7 @@ err:
586 586
587void wlc_phy_detach(struct brcms_phy_pub *pih) 587void wlc_phy_detach(struct brcms_phy_pub *pih)
588{ 588{
589 struct brcms_phy *pi = (struct brcms_phy *) pih; 589 struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro);
590 590
591 if (pih) { 591 if (pih) {
592 if (--pi->refcnt) 592 if (--pi->refcnt)
@@ -613,7 +613,7 @@ bool
613wlc_phy_get_phyversion(struct brcms_phy_pub *pih, u16 *phytype, u16 *phyrev, 613wlc_phy_get_phyversion(struct brcms_phy_pub *pih, u16 *phytype, u16 *phyrev,
614 u16 *radioid, u16 *radiover) 614 u16 *radioid, u16 *radiover)
615{ 615{
616 struct brcms_phy *pi = (struct brcms_phy *) pih; 616 struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro);
617 *phytype = (u16) pi->pubpi.phy_type; 617 *phytype = (u16) pi->pubpi.phy_type;
618 *phyrev = (u16) pi->pubpi.phy_rev; 618 *phyrev = (u16) pi->pubpi.phy_rev;
619 *radioid = pi->pubpi.radioid; 619 *radioid = pi->pubpi.radioid;
@@ -624,19 +624,19 @@ wlc_phy_get_phyversion(struct brcms_phy_pub *pih, u16 *phytype, u16 *phyrev,
624 624
625bool wlc_phy_get_encore(struct brcms_phy_pub *pih) 625bool wlc_phy_get_encore(struct brcms_phy_pub *pih)
626{ 626{
627 struct brcms_phy *pi = (struct brcms_phy *) pih; 627 struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro);
628 return pi->pubpi.abgphy_encore; 628 return pi->pubpi.abgphy_encore;
629} 629}
630 630
631u32 wlc_phy_get_coreflags(struct brcms_phy_pub *pih) 631u32 wlc_phy_get_coreflags(struct brcms_phy_pub *pih)
632{ 632{
633 struct brcms_phy *pi = (struct brcms_phy *) pih; 633 struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro);
634 return pi->pubpi.coreflags; 634 return pi->pubpi.coreflags;
635} 635}
636 636
637void wlc_phy_anacore(struct brcms_phy_pub *pih, bool on) 637void wlc_phy_anacore(struct brcms_phy_pub *pih, bool on)
638{ 638{
639 struct brcms_phy *pi = (struct brcms_phy *) pih; 639 struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro);
640 640
641 if (ISNPHY(pi)) { 641 if (ISNPHY(pi)) {
642 if (on) { 642 if (on) {
@@ -673,7 +673,7 @@ void wlc_phy_anacore(struct brcms_phy_pub *pih, bool on)
673 673
674u32 wlc_phy_clk_bwbits(struct brcms_phy_pub *pih) 674u32 wlc_phy_clk_bwbits(struct brcms_phy_pub *pih)
675{ 675{
676 struct brcms_phy *pi = (struct brcms_phy *) pih; 676 struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro);
677 677
678 u32 phy_bw_clkbits = 0; 678 u32 phy_bw_clkbits = 0;
679 679
@@ -698,14 +698,14 @@ u32 wlc_phy_clk_bwbits(struct brcms_phy_pub *pih)
698 698
699void wlc_phy_por_inform(struct brcms_phy_pub *ppi) 699void wlc_phy_por_inform(struct brcms_phy_pub *ppi)
700{ 700{
701 struct brcms_phy *pi = (struct brcms_phy *) ppi; 701 struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro);
702 702
703 pi->phy_init_por = true; 703 pi->phy_init_por = true;
704} 704}
705 705
706void wlc_phy_edcrs_lock(struct brcms_phy_pub *pih, bool lock) 706void wlc_phy_edcrs_lock(struct brcms_phy_pub *pih, bool lock)
707{ 707{
708 struct brcms_phy *pi = (struct brcms_phy *) pih; 708 struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro);
709 709
710 pi->edcrs_threshold_lock = lock; 710 pi->edcrs_threshold_lock = lock;
711 711
@@ -717,14 +717,14 @@ void wlc_phy_edcrs_lock(struct brcms_phy_pub *pih, bool lock)
717 717
718void wlc_phy_initcal_enable(struct brcms_phy_pub *pih, bool initcal) 718void wlc_phy_initcal_enable(struct brcms_phy_pub *pih, bool initcal)
719{ 719{
720 struct brcms_phy *pi = (struct brcms_phy *) pih; 720 struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro);
721 721
722 pi->do_initcal = initcal; 722 pi->do_initcal = initcal;
723} 723}
724 724
725void wlc_phy_hw_clk_state_upd(struct brcms_phy_pub *pih, bool newstate) 725void wlc_phy_hw_clk_state_upd(struct brcms_phy_pub *pih, bool newstate)
726{ 726{
727 struct brcms_phy *pi = (struct brcms_phy *) pih; 727 struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro);
728 728
729 if (!pi || !pi->sh) 729 if (!pi || !pi->sh)
730 return; 730 return;
@@ -734,7 +734,7 @@ void wlc_phy_hw_clk_state_upd(struct brcms_phy_pub *pih, bool newstate)
734 734
735void wlc_phy_hw_state_upd(struct brcms_phy_pub *pih, bool newstate) 735void wlc_phy_hw_state_upd(struct brcms_phy_pub *pih, bool newstate)
736{ 736{
737 struct brcms_phy *pi = (struct brcms_phy *) pih; 737 struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro);
738 738
739 if (!pi || !pi->sh) 739 if (!pi || !pi->sh)
740 return; 740 return;
@@ -746,7 +746,7 @@ void wlc_phy_init(struct brcms_phy_pub *pih, u16 chanspec)
746{ 746{
747 u32 mc; 747 u32 mc;
748 void (*phy_init)(struct brcms_phy *) = NULL; 748 void (*phy_init)(struct brcms_phy *) = NULL;
749 struct brcms_phy *pi = (struct brcms_phy *) pih; 749 struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro);
750 750
751 if (pi->init_in_progress) 751 if (pi->init_in_progress)
752 return; 752 return;
@@ -798,7 +798,7 @@ void wlc_phy_init(struct brcms_phy_pub *pih, u16 chanspec)
798 798
799void wlc_phy_cal_init(struct brcms_phy_pub *pih) 799void wlc_phy_cal_init(struct brcms_phy_pub *pih)
800{ 800{
801 struct brcms_phy *pi = (struct brcms_phy *) pih; 801 struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro);
802 void (*cal_init)(struct brcms_phy *) = NULL; 802 void (*cal_init)(struct brcms_phy *) = NULL;
803 803
804 if (WARN((bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) & 804 if (WARN((bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
@@ -816,7 +816,7 @@ void wlc_phy_cal_init(struct brcms_phy_pub *pih)
816 816
817int wlc_phy_down(struct brcms_phy_pub *pih) 817int wlc_phy_down(struct brcms_phy_pub *pih)
818{ 818{
819 struct brcms_phy *pi = (struct brcms_phy *) pih; 819 struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro);
820 int callbacks = 0; 820 int callbacks = 0;
821 821
822 if (pi->phycal_timer 822 if (pi->phycal_timer
@@ -1070,7 +1070,7 @@ void wlc_phy_do_dummy_tx(struct brcms_phy *pi, bool ofdm, bool pa_on)
1070 1070
1071void wlc_phy_hold_upd(struct brcms_phy_pub *pih, u32 id, bool set) 1071void wlc_phy_hold_upd(struct brcms_phy_pub *pih, u32 id, bool set)
1072{ 1072{
1073 struct brcms_phy *pi = (struct brcms_phy *) pih; 1073 struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro);
1074 1074
1075 if (set) 1075 if (set)
1076 mboolset(pi->measure_hold, id); 1076 mboolset(pi->measure_hold, id);
@@ -1082,7 +1082,7 @@ void wlc_phy_hold_upd(struct brcms_phy_pub *pih, u32 id, bool set)
1082 1082
1083void wlc_phy_mute_upd(struct brcms_phy_pub *pih, bool mute, u32 flags) 1083void wlc_phy_mute_upd(struct brcms_phy_pub *pih, bool mute, u32 flags)
1084{ 1084{
1085 struct brcms_phy *pi = (struct brcms_phy *) pih; 1085 struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro);
1086 1086
1087 if (mute) 1087 if (mute)
1088 mboolset(pi->measure_hold, PHY_HOLD_FOR_MUTE); 1088 mboolset(pi->measure_hold, PHY_HOLD_FOR_MUTE);
@@ -1096,7 +1096,7 @@ void wlc_phy_mute_upd(struct brcms_phy_pub *pih, bool mute, u32 flags)
1096 1096
1097void wlc_phy_clear_tssi(struct brcms_phy_pub *pih) 1097void wlc_phy_clear_tssi(struct brcms_phy_pub *pih)
1098{ 1098{
1099 struct brcms_phy *pi = (struct brcms_phy *) pih; 1099 struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro);
1100 1100
1101 if (ISNPHY(pi)) { 1101 if (ISNPHY(pi)) {
1102 return; 1102 return;
@@ -1115,7 +1115,7 @@ static bool wlc_phy_cal_txpower_recalc_sw(struct brcms_phy *pi)
1115 1115
1116void wlc_phy_switch_radio(struct brcms_phy_pub *pih, bool on) 1116void wlc_phy_switch_radio(struct brcms_phy_pub *pih, bool on)
1117{ 1117{
1118 struct brcms_phy *pi = (struct brcms_phy *) pih; 1118 struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro);
1119 (void)bcma_read32(pi->d11core, D11REGOFFS(maccontrol)); 1119 (void)bcma_read32(pi->d11core, D11REGOFFS(maccontrol));
1120 1120
1121 if (ISNPHY(pi)) { 1121 if (ISNPHY(pi)) {
@@ -1149,35 +1149,35 @@ void wlc_phy_switch_radio(struct brcms_phy_pub *pih, bool on)
1149 1149
1150u16 wlc_phy_bw_state_get(struct brcms_phy_pub *ppi) 1150u16 wlc_phy_bw_state_get(struct brcms_phy_pub *ppi)
1151{ 1151{
1152 struct brcms_phy *pi = (struct brcms_phy *) ppi; 1152 struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro);
1153 1153
1154 return pi->bw; 1154 return pi->bw;
1155} 1155}
1156 1156
1157void wlc_phy_bw_state_set(struct brcms_phy_pub *ppi, u16 bw) 1157void wlc_phy_bw_state_set(struct brcms_phy_pub *ppi, u16 bw)
1158{ 1158{
1159 struct brcms_phy *pi = (struct brcms_phy *) ppi; 1159 struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro);
1160 1160
1161 pi->bw = bw; 1161 pi->bw = bw;
1162} 1162}
1163 1163
1164void wlc_phy_chanspec_radio_set(struct brcms_phy_pub *ppi, u16 newch) 1164void wlc_phy_chanspec_radio_set(struct brcms_phy_pub *ppi, u16 newch)
1165{ 1165{
1166 struct brcms_phy *pi = (struct brcms_phy *) ppi; 1166 struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro);
1167 pi->radio_chanspec = newch; 1167 pi->radio_chanspec = newch;
1168 1168
1169} 1169}
1170 1170
1171u16 wlc_phy_chanspec_get(struct brcms_phy_pub *ppi) 1171u16 wlc_phy_chanspec_get(struct brcms_phy_pub *ppi)
1172{ 1172{
1173 struct brcms_phy *pi = (struct brcms_phy *) ppi; 1173 struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro);
1174 1174
1175 return pi->radio_chanspec; 1175 return pi->radio_chanspec;
1176} 1176}
1177 1177
1178void wlc_phy_chanspec_set(struct brcms_phy_pub *ppi, u16 chanspec) 1178void wlc_phy_chanspec_set(struct brcms_phy_pub *ppi, u16 chanspec)
1179{ 1179{
1180 struct brcms_phy *pi = (struct brcms_phy *) ppi; 1180 struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro);
1181 u16 m_cur_channel; 1181 u16 m_cur_channel;
1182 void (*chanspec_set)(struct brcms_phy *, u16) = NULL; 1182 void (*chanspec_set)(struct brcms_phy *, u16) = NULL;
1183 m_cur_channel = CHSPEC_CHANNEL(chanspec); 1183 m_cur_channel = CHSPEC_CHANNEL(chanspec);
@@ -1226,7 +1226,7 @@ int wlc_phy_chanspec_bandrange_get(struct brcms_phy *pi, u16 chanspec)
1226void wlc_phy_chanspec_ch14_widefilter_set(struct brcms_phy_pub *ppi, 1226void wlc_phy_chanspec_ch14_widefilter_set(struct brcms_phy_pub *ppi,
1227 bool wide_filter) 1227 bool wide_filter)
1228{ 1228{
1229 struct brcms_phy *pi = (struct brcms_phy *) ppi; 1229 struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro);
1230 1230
1231 pi->channel_14_wide_filter = wide_filter; 1231 pi->channel_14_wide_filter = wide_filter;
1232 1232
@@ -1246,7 +1246,7 @@ void
1246wlc_phy_chanspec_band_validch(struct brcms_phy_pub *ppi, uint band, 1246wlc_phy_chanspec_band_validch(struct brcms_phy_pub *ppi, uint band,
1247 struct brcms_chanvec *channels) 1247 struct brcms_chanvec *channels)
1248{ 1248{
1249 struct brcms_phy *pi = (struct brcms_phy *) ppi; 1249 struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro);
1250 uint i; 1250 uint i;
1251 uint channel; 1251 uint channel;
1252 1252
@@ -1267,7 +1267,7 @@ wlc_phy_chanspec_band_validch(struct brcms_phy_pub *ppi, uint band,
1267 1267
1268u16 wlc_phy_chanspec_band_firstch(struct brcms_phy_pub *ppi, uint band) 1268u16 wlc_phy_chanspec_band_firstch(struct brcms_phy_pub *ppi, uint band)
1269{ 1269{
1270 struct brcms_phy *pi = (struct brcms_phy *) ppi; 1270 struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro);
1271 uint i; 1271 uint i;
1272 uint channel; 1272 uint channel;
1273 u16 chspec; 1273 u16 chspec;
@@ -1311,7 +1311,7 @@ u16 wlc_phy_chanspec_band_firstch(struct brcms_phy_pub *ppi, uint band)
1311 1311
1312int wlc_phy_txpower_get(struct brcms_phy_pub *ppi, uint *qdbm, bool *override) 1312int wlc_phy_txpower_get(struct brcms_phy_pub *ppi, uint *qdbm, bool *override)
1313{ 1313{
1314 struct brcms_phy *pi = (struct brcms_phy *) ppi; 1314 struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro);
1315 1315
1316 *qdbm = pi->tx_user_target[0]; 1316 *qdbm = pi->tx_user_target[0];
1317 if (override != NULL) 1317 if (override != NULL)
@@ -1323,7 +1323,7 @@ void wlc_phy_txpower_target_set(struct brcms_phy_pub *ppi,
1323 struct txpwr_limits *txpwr) 1323 struct txpwr_limits *txpwr)
1324{ 1324{
1325 bool mac_enabled = false; 1325 bool mac_enabled = false;
1326 struct brcms_phy *pi = (struct brcms_phy *) ppi; 1326 struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro);
1327 1327
1328 memcpy(&pi->tx_user_target[TXP_FIRST_CCK], 1328 memcpy(&pi->tx_user_target[TXP_FIRST_CCK],
1329 &txpwr->cck[0], BRCMS_NUM_RATES_CCK); 1329 &txpwr->cck[0], BRCMS_NUM_RATES_CCK);
@@ -1371,7 +1371,7 @@ void wlc_phy_txpower_target_set(struct brcms_phy_pub *ppi,
1371 1371
1372int wlc_phy_txpower_set(struct brcms_phy_pub *ppi, uint qdbm, bool override) 1372int wlc_phy_txpower_set(struct brcms_phy_pub *ppi, uint qdbm, bool override)
1373{ 1373{
1374 struct brcms_phy *pi = (struct brcms_phy *) ppi; 1374 struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro);
1375 int i; 1375 int i;
1376 1376
1377 if (qdbm > 127) 1377 if (qdbm > 127)
@@ -1407,7 +1407,7 @@ void
1407wlc_phy_txpower_sromlimit(struct brcms_phy_pub *ppi, uint channel, u8 *min_pwr, 1407wlc_phy_txpower_sromlimit(struct brcms_phy_pub *ppi, uint channel, u8 *min_pwr,
1408 u8 *max_pwr, int txp_rate_idx) 1408 u8 *max_pwr, int txp_rate_idx)
1409{ 1409{
1410 struct brcms_phy *pi = (struct brcms_phy *) ppi; 1410 struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro);
1411 uint i; 1411 uint i;
1412 1412
1413 *min_pwr = pi->min_txpower * BRCMS_TXPWR_DB_FACTOR; 1413 *min_pwr = pi->min_txpower * BRCMS_TXPWR_DB_FACTOR;
@@ -1456,7 +1456,7 @@ void
1456wlc_phy_txpower_sromlimit_max_get(struct brcms_phy_pub *ppi, uint chan, 1456wlc_phy_txpower_sromlimit_max_get(struct brcms_phy_pub *ppi, uint chan,
1457 u8 *max_txpwr, u8 *min_txpwr) 1457 u8 *max_txpwr, u8 *min_txpwr)
1458{ 1458{
1459 struct brcms_phy *pi = (struct brcms_phy *) ppi; 1459 struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro);
1460 u8 tx_pwr_max = 0; 1460 u8 tx_pwr_max = 0;
1461 u8 tx_pwr_min = 255; 1461 u8 tx_pwr_min = 255;
1462 u8 max_num_rate; 1462 u8 max_num_rate;
@@ -1493,14 +1493,14 @@ wlc_phy_txpower_boardlimit_band(struct brcms_phy_pub *ppi, uint bandunit,
1493 1493
1494u8 wlc_phy_txpower_get_target_min(struct brcms_phy_pub *ppi) 1494u8 wlc_phy_txpower_get_target_min(struct brcms_phy_pub *ppi)
1495{ 1495{
1496 struct brcms_phy *pi = (struct brcms_phy *) ppi; 1496 struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro);
1497 1497
1498 return pi->tx_power_min; 1498 return pi->tx_power_min;
1499} 1499}
1500 1500
1501u8 wlc_phy_txpower_get_target_max(struct brcms_phy_pub *ppi) 1501u8 wlc_phy_txpower_get_target_max(struct brcms_phy_pub *ppi)
1502{ 1502{
1503 struct brcms_phy *pi = (struct brcms_phy *) ppi; 1503 struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro);
1504 1504
1505 return pi->tx_power_max; 1505 return pi->tx_power_max;
1506} 1506}
@@ -1812,21 +1812,21 @@ wlc_phy_txpower_reg_limit_calc(struct brcms_phy *pi, struct txpwr_limits *txpwr,
1812 1812
1813void wlc_phy_txpwr_percent_set(struct brcms_phy_pub *ppi, u8 txpwr_percent) 1813void wlc_phy_txpwr_percent_set(struct brcms_phy_pub *ppi, u8 txpwr_percent)
1814{ 1814{
1815 struct brcms_phy *pi = (struct brcms_phy *) ppi; 1815 struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro);
1816 1816
1817 pi->txpwr_percent = txpwr_percent; 1817 pi->txpwr_percent = txpwr_percent;
1818} 1818}
1819 1819
1820void wlc_phy_machwcap_set(struct brcms_phy_pub *ppi, u32 machwcap) 1820void wlc_phy_machwcap_set(struct brcms_phy_pub *ppi, u32 machwcap)
1821{ 1821{
1822 struct brcms_phy *pi = (struct brcms_phy *) ppi; 1822 struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro);
1823 1823
1824 pi->sh->machwcap = machwcap; 1824 pi->sh->machwcap = machwcap;
1825} 1825}
1826 1826
1827void wlc_phy_runbist_config(struct brcms_phy_pub *ppi, bool start_end) 1827void wlc_phy_runbist_config(struct brcms_phy_pub *ppi, bool start_end)
1828{ 1828{
1829 struct brcms_phy *pi = (struct brcms_phy *) ppi; 1829 struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro);
1830 u16 rxc; 1830 u16 rxc;
1831 rxc = 0; 1831 rxc = 0;
1832 1832
@@ -1857,7 +1857,7 @@ void
1857wlc_phy_txpower_limit_set(struct brcms_phy_pub *ppi, struct txpwr_limits *txpwr, 1857wlc_phy_txpower_limit_set(struct brcms_phy_pub *ppi, struct txpwr_limits *txpwr,
1858 u16 chanspec) 1858 u16 chanspec)
1859{ 1859{
1860 struct brcms_phy *pi = (struct brcms_phy *) ppi; 1860 struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro);
1861 1861
1862 wlc_phy_txpower_reg_limit_calc(pi, txpwr, chanspec); 1862 wlc_phy_txpower_reg_limit_calc(pi, txpwr, chanspec);
1863 1863
@@ -1881,14 +1881,14 @@ wlc_phy_txpower_limit_set(struct brcms_phy_pub *ppi, struct txpwr_limits *txpwr,
1881 1881
1882void wlc_phy_ofdm_rateset_war(struct brcms_phy_pub *pih, bool war) 1882void wlc_phy_ofdm_rateset_war(struct brcms_phy_pub *pih, bool war)
1883{ 1883{
1884 struct brcms_phy *pi = (struct brcms_phy *) pih; 1884 struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro);
1885 1885
1886 pi->ofdm_rateset_war = war; 1886 pi->ofdm_rateset_war = war;
1887} 1887}
1888 1888
1889void wlc_phy_bf_preempt_enable(struct brcms_phy_pub *pih, bool bf_preempt) 1889void wlc_phy_bf_preempt_enable(struct brcms_phy_pub *pih, bool bf_preempt)
1890{ 1890{
1891 struct brcms_phy *pi = (struct brcms_phy *) pih; 1891 struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro);
1892 1892
1893 pi->bf_preempt_4306 = bf_preempt; 1893 pi->bf_preempt_4306 = bf_preempt;
1894} 1894}
@@ -1945,7 +1945,7 @@ void wlc_phy_txpower_update_shm(struct brcms_phy *pi)
1945 1945
1946bool wlc_phy_txpower_hw_ctrl_get(struct brcms_phy_pub *ppi) 1946bool wlc_phy_txpower_hw_ctrl_get(struct brcms_phy_pub *ppi)
1947{ 1947{
1948 struct brcms_phy *pi = (struct brcms_phy *) ppi; 1948 struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro);
1949 1949
1950 if (ISNPHY(pi)) 1950 if (ISNPHY(pi))
1951 return pi->nphy_txpwrctrl; 1951 return pi->nphy_txpwrctrl;
@@ -1955,7 +1955,7 @@ bool wlc_phy_txpower_hw_ctrl_get(struct brcms_phy_pub *ppi)
1955 1955
1956void wlc_phy_txpower_hw_ctrl_set(struct brcms_phy_pub *ppi, bool hwpwrctrl) 1956void wlc_phy_txpower_hw_ctrl_set(struct brcms_phy_pub *ppi, bool hwpwrctrl)
1957{ 1957{
1958 struct brcms_phy *pi = (struct brcms_phy *) ppi; 1958 struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro);
1959 bool suspend; 1959 bool suspend;
1960 1960
1961 if (!pi->hwpwrctrl_capable) 1961 if (!pi->hwpwrctrl_capable)
@@ -2038,7 +2038,7 @@ void
2038wlc_phy_txpower_get_current(struct brcms_phy_pub *ppi, struct tx_power *power, 2038wlc_phy_txpower_get_current(struct brcms_phy_pub *ppi, struct tx_power *power,
2039 uint channel) 2039 uint channel)
2040{ 2040{
2041 struct brcms_phy *pi = (struct brcms_phy *) ppi; 2041 struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro);
2042 uint rate, num_rates; 2042 uint rate, num_rates;
2043 u8 min_pwr, max_pwr; 2043 u8 min_pwr, max_pwr;
2044 2044
@@ -2136,21 +2136,21 @@ wlc_phy_txpower_get_current(struct brcms_phy_pub *ppi, struct tx_power *power,
2136 2136
2137void wlc_phy_antsel_type_set(struct brcms_phy_pub *ppi, u8 antsel_type) 2137void wlc_phy_antsel_type_set(struct brcms_phy_pub *ppi, u8 antsel_type)
2138{ 2138{
2139 struct brcms_phy *pi = (struct brcms_phy *) ppi; 2139 struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro);
2140 2140
2141 pi->antsel_type = antsel_type; 2141 pi->antsel_type = antsel_type;
2142} 2142}
2143 2143
2144bool wlc_phy_test_ison(struct brcms_phy_pub *ppi) 2144bool wlc_phy_test_ison(struct brcms_phy_pub *ppi)
2145{ 2145{
2146 struct brcms_phy *pi = (struct brcms_phy *) ppi; 2146 struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro);
2147 2147
2148 return pi->phytest_on; 2148 return pi->phytest_on;
2149} 2149}
2150 2150
2151void wlc_phy_ant_rxdiv_set(struct brcms_phy_pub *ppi, u8 val) 2151void wlc_phy_ant_rxdiv_set(struct brcms_phy_pub *ppi, u8 val)
2152{ 2152{
2153 struct brcms_phy *pi = (struct brcms_phy *) ppi; 2153 struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro);
2154 bool suspend; 2154 bool suspend;
2155 2155
2156 pi->sh->rx_antdiv = val; 2156 pi->sh->rx_antdiv = val;
@@ -2283,7 +2283,7 @@ static s8 wlc_phy_noise_read_shmem(struct brcms_phy *pi)
2283 2283
2284void wlc_phy_noise_sample_intr(struct brcms_phy_pub *pih) 2284void wlc_phy_noise_sample_intr(struct brcms_phy_pub *pih)
2285{ 2285{
2286 struct brcms_phy *pi = (struct brcms_phy *) pih; 2286 struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro);
2287 u16 jssi_aux; 2287 u16 jssi_aux;
2288 u8 channel = 0; 2288 u8 channel = 0;
2289 s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY; 2289 s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY;
@@ -2339,7 +2339,7 @@ void wlc_phy_noise_sample_intr(struct brcms_phy_pub *pih)
2339static void 2339static void
2340wlc_phy_noise_sample_request(struct brcms_phy_pub *pih, u8 reason, u8 ch) 2340wlc_phy_noise_sample_request(struct brcms_phy_pub *pih, u8 reason, u8 ch)
2341{ 2341{
2342 struct brcms_phy *pi = (struct brcms_phy *) pih; 2342 struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro);
2343 s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY; 2343 s8 noise_dbm = PHY_NOISE_FIXED_VAL_NPHY;
2344 bool sampling_in_progress = (pi->phynoise_state != 0); 2344 bool sampling_in_progress = (pi->phynoise_state != 0);
2345 bool wait_for_intr = true; 2345 bool wait_for_intr = true;
@@ -2531,7 +2531,7 @@ int wlc_phy_rssi_compute(struct brcms_phy_pub *pih,
2531{ 2531{
2532 int rssi = rxh->PhyRxStatus_1 & PRXS1_JSSI_MASK; 2532 int rssi = rxh->PhyRxStatus_1 & PRXS1_JSSI_MASK;
2533 uint radioid = pih->radioid; 2533 uint radioid = pih->radioid;
2534 struct brcms_phy *pi = (struct brcms_phy *) pih; 2534 struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro);
2535 2535
2536 if ((pi->sh->corerev >= 11) 2536 if ((pi->sh->corerev >= 11)
2537 && !(rxh->RxStatus2 & RXS_PHYRXST_VALID)) { 2537 && !(rxh->RxStatus2 & RXS_PHYRXST_VALID)) {
@@ -2591,7 +2591,7 @@ void wlc_phy_set_deaf(struct brcms_phy_pub *ppi, bool user_flag)
2591 2591
2592void wlc_phy_watchdog(struct brcms_phy_pub *pih) 2592void wlc_phy_watchdog(struct brcms_phy_pub *pih)
2593{ 2593{
2594 struct brcms_phy *pi = (struct brcms_phy *) pih; 2594 struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro);
2595 bool delay_phy_cal = false; 2595 bool delay_phy_cal = false;
2596 pi->sh->now++; 2596 pi->sh->now++;
2597 2597
@@ -2651,7 +2651,7 @@ void wlc_phy_watchdog(struct brcms_phy_pub *pih)
2651 2651
2652void wlc_phy_BSSinit(struct brcms_phy_pub *pih, bool bonlyap, int rssi) 2652void wlc_phy_BSSinit(struct brcms_phy_pub *pih, bool bonlyap, int rssi)
2653{ 2653{
2654 struct brcms_phy *pi = (struct brcms_phy *) pih; 2654 struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro);
2655 uint i; 2655 uint i;
2656 uint k; 2656 uint k;
2657 2657
@@ -2711,7 +2711,7 @@ void wlc_phy_cal_perical(struct brcms_phy_pub *pih, u8 reason)
2711 s16 nphy_currtemp = 0; 2711 s16 nphy_currtemp = 0;
2712 s16 delta_temp = 0; 2712 s16 delta_temp = 0;
2713 bool do_periodic_cal = true; 2713 bool do_periodic_cal = true;
2714 struct brcms_phy *pi = (struct brcms_phy *) pih; 2714 struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro);
2715 2715
2716 if (!ISNPHY(pi)) 2716 if (!ISNPHY(pi))
2717 return; 2717 return;
@@ -2804,7 +2804,7 @@ u8 wlc_phy_nbits(s32 value)
2804 2804
2805void wlc_phy_stf_chain_init(struct brcms_phy_pub *pih, u8 txchain, u8 rxchain) 2805void wlc_phy_stf_chain_init(struct brcms_phy_pub *pih, u8 txchain, u8 rxchain)
2806{ 2806{
2807 struct brcms_phy *pi = (struct brcms_phy *) pih; 2807 struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro);
2808 2808
2809 pi->sh->hw_phytxchain = txchain; 2809 pi->sh->hw_phytxchain = txchain;
2810 pi->sh->hw_phyrxchain = rxchain; 2810 pi->sh->hw_phyrxchain = rxchain;
@@ -2815,7 +2815,7 @@ void wlc_phy_stf_chain_init(struct brcms_phy_pub *pih, u8 txchain, u8 rxchain)
2815 2815
2816void wlc_phy_stf_chain_set(struct brcms_phy_pub *pih, u8 txchain, u8 rxchain) 2816void wlc_phy_stf_chain_set(struct brcms_phy_pub *pih, u8 txchain, u8 rxchain)
2817{ 2817{
2818 struct brcms_phy *pi = (struct brcms_phy *) pih; 2818 struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro);
2819 2819
2820 pi->sh->phytxchain = txchain; 2820 pi->sh->phytxchain = txchain;
2821 2821
@@ -2827,7 +2827,7 @@ void wlc_phy_stf_chain_set(struct brcms_phy_pub *pih, u8 txchain, u8 rxchain)
2827 2827
2828void wlc_phy_stf_chain_get(struct brcms_phy_pub *pih, u8 *txchain, u8 *rxchain) 2828void wlc_phy_stf_chain_get(struct brcms_phy_pub *pih, u8 *txchain, u8 *rxchain)
2829{ 2829{
2830 struct brcms_phy *pi = (struct brcms_phy *) pih; 2830 struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro);
2831 2831
2832 *txchain = pi->sh->phytxchain; 2832 *txchain = pi->sh->phytxchain;
2833 *rxchain = pi->sh->phyrxchain; 2833 *rxchain = pi->sh->phyrxchain;
@@ -2837,7 +2837,7 @@ u8 wlc_phy_stf_chain_active_get(struct brcms_phy_pub *pih)
2837{ 2837{
2838 s16 nphy_currtemp; 2838 s16 nphy_currtemp;
2839 u8 active_bitmap; 2839 u8 active_bitmap;
2840 struct brcms_phy *pi = (struct brcms_phy *) pih; 2840 struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro);
2841 2841
2842 active_bitmap = (pi->phy_txcore_heatedup) ? 0x31 : 0x33; 2842 active_bitmap = (pi->phy_txcore_heatedup) ? 0x31 : 0x33;
2843 2843
@@ -2867,7 +2867,7 @@ u8 wlc_phy_stf_chain_active_get(struct brcms_phy_pub *pih)
2867 2867
2868s8 wlc_phy_stf_ssmode_get(struct brcms_phy_pub *pih, u16 chanspec) 2868s8 wlc_phy_stf_ssmode_get(struct brcms_phy_pub *pih, u16 chanspec)
2869{ 2869{
2870 struct brcms_phy *pi = (struct brcms_phy *) pih; 2870 struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro);
2871 u8 siso_mcs_id, cdd_mcs_id; 2871 u8 siso_mcs_id, cdd_mcs_id;
2872 2872
2873 siso_mcs_id = 2873 siso_mcs_id =
@@ -2944,7 +2944,7 @@ s8 wlc_phy_upd_rssi_offset(struct brcms_phy *pi, s8 rssi, u16 chanspec)
2944 2944
2945bool wlc_phy_txpower_ipa_ison(struct brcms_phy_pub *ppi) 2945bool wlc_phy_txpower_ipa_ison(struct brcms_phy_pub *ppi)
2946{ 2946{
2947 struct brcms_phy *pi = (struct brcms_phy *) ppi; 2947 struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro);
2948 2948
2949 if (ISNPHY(pi)) 2949 if (ISNPHY(pi))
2950 return wlc_phy_n_txpower_ipa_ison(pi); 2950 return wlc_phy_n_txpower_ipa_ison(pi);
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
index b2d6d6da3daf..5f1366234a0d 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_lcn.c
@@ -2865,7 +2865,7 @@ static void wlc_lcnphy_idle_tssi_est(struct brcms_phy_pub *ppi)
2865{ 2865{
2866 bool suspend, tx_gain_override_old; 2866 bool suspend, tx_gain_override_old;
2867 struct lcnphy_txgains old_gains; 2867 struct lcnphy_txgains old_gains;
2868 struct brcms_phy *pi = (struct brcms_phy *) ppi; 2868 struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro);
2869 u16 idleTssi, idleTssi0_2C, idleTssi0_OB, idleTssi0_regvalue_OB, 2869 u16 idleTssi, idleTssi0_2C, idleTssi0_OB, idleTssi0_regvalue_OB,
2870 idleTssi0_regvalue_2C; 2870 idleTssi0_regvalue_2C;
2871 u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); 2871 u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
@@ -3084,7 +3084,7 @@ static void wlc_lcnphy_tx_pwr_ctrl_init(struct brcms_phy_pub *ppi)
3084 s32 a1, b0, b1; 3084 s32 a1, b0, b1;
3085 s32 tssi, pwr, maxtargetpwr, mintargetpwr; 3085 s32 tssi, pwr, maxtargetpwr, mintargetpwr;
3086 bool suspend; 3086 bool suspend;
3087 struct brcms_phy *pi = (struct brcms_phy *) ppi; 3087 struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro);
3088 3088
3089 suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) & 3089 suspend = (0 == (bcma_read32(pi->d11core, D11REGOFFS(maccontrol)) &
3090 MCTL_EN_MAC)); 3090 MCTL_EN_MAC));
@@ -4348,7 +4348,7 @@ void wlc_lcnphy_tx_power_adjustment(struct brcms_phy_pub *ppi)
4348{ 4348{
4349 s8 index; 4349 s8 index;
4350 u16 index2; 4350 u16 index2;
4351 struct brcms_phy *pi = (struct brcms_phy *) ppi; 4351 struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro);
4352 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy; 4352 struct brcms_phy_lcnphy *pi_lcn = pi->u.pi_lcnphy;
4353 u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi); 4353 u16 SAVE_txpwrctrl = wlc_lcnphy_get_tx_pwr_ctrl(pi);
4354 if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi) && 4354 if (wlc_lcnphy_tempsense_based_pwr_ctrl_enabled(pi) &&
diff --git a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c
index 93869e89aa3d..084f18f4f950 100644
--- a/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c
+++ b/drivers/net/wireless/brcm80211/brcmsmac/phy/phy_n.c
@@ -14121,7 +14121,7 @@ static u8 ant_sw_ctrl_tbl_rev8_2057v7_core1[] = {
14121 14121
14122bool wlc_phy_bist_check_phy(struct brcms_phy_pub *pih) 14122bool wlc_phy_bist_check_phy(struct brcms_phy_pub *pih)
14123{ 14123{
14124 struct brcms_phy *pi = (struct brcms_phy *) pih; 14124 struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro);
14125 u32 phybist0, phybist1, phybist2, phybist3, phybist4; 14125 u32 phybist0, phybist1, phybist2, phybist3, phybist4;
14126 14126
14127 if (NREV_GE(pi->pubpi.phy_rev, 16)) 14127 if (NREV_GE(pi->pubpi.phy_rev, 16))
@@ -19734,7 +19734,7 @@ void wlc_phy_rxcore_setstate_nphy(struct brcms_phy_pub *pih, u8 rxcore_bitmask)
19734 u16 regval; 19734 u16 regval;
19735 u16 tbl_buf[16]; 19735 u16 tbl_buf[16];
19736 uint i; 19736 uint i;
19737 struct brcms_phy *pi = (struct brcms_phy *) pih; 19737 struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro);
19738 u16 tbl_opcode; 19738 u16 tbl_opcode;
19739 bool suspend; 19739 bool suspend;
19740 19740
@@ -19812,7 +19812,7 @@ void wlc_phy_rxcore_setstate_nphy(struct brcms_phy_pub *pih, u8 rxcore_bitmask)
19812u8 wlc_phy_rxcore_getstate_nphy(struct brcms_phy_pub *pih) 19812u8 wlc_phy_rxcore_getstate_nphy(struct brcms_phy_pub *pih)
19813{ 19813{
19814 u16 regval, rxen_bits; 19814 u16 regval, rxen_bits;
19815 struct brcms_phy *pi = (struct brcms_phy *) pih; 19815 struct brcms_phy *pi = container_of(pih, struct brcms_phy, pubpi_ro);
19816 19816
19817 regval = read_phy_reg(pi, 0xa2); 19817 regval = read_phy_reg(pi, 0xa2);
19818 rxen_bits = (regval >> 4) & 0xf; 19818 rxen_bits = (regval >> 4) & 0xf;
@@ -21342,7 +21342,7 @@ void wlc_phy_chanspec_set_nphy(struct brcms_phy *pi, u16 chanspec)
21342 21342
21343void wlc_phy_antsel_init(struct brcms_phy_pub *ppi, bool lut_init) 21343void wlc_phy_antsel_init(struct brcms_phy_pub *ppi, bool lut_init)
21344{ 21344{
21345 struct brcms_phy *pi = (struct brcms_phy *) ppi; 21345 struct brcms_phy *pi = container_of(ppi, struct brcms_phy, pubpi_ro);
21346 u16 mask = 0xfc00; 21346 u16 mask = 0xfc00;
21347 u32 mc = 0; 21347 u32 mc = 0;
21348 21348
diff --git a/drivers/net/wireless/hostap/hostap_proc.c b/drivers/net/wireless/hostap/hostap_proc.c
index 4e5c0f8c9496..8efd17c52f65 100644
--- a/drivers/net/wireless/hostap/hostap_proc.c
+++ b/drivers/net/wireless/hostap/hostap_proc.c
@@ -186,11 +186,9 @@ static int prism2_bss_list_proc_show(struct seq_file *m, void *v)
186 bss->ssid[i] : '_'); 186 bss->ssid[i] : '_');
187 187
188 seq_putc(m, '\t'); 188 seq_putc(m, '\t');
189 for (i = 0; i < bss->ssid_len; i++) 189 seq_printf(m, "%*phN", (int)bss->ssid_len, bss->ssid);
190 seq_printf(m, "%02x", bss->ssid[i]);
191 seq_putc(m, '\t'); 190 seq_putc(m, '\t');
192 for (i = 0; i < bss->wpa_ie_len; i++) 191 seq_printf(m, "%*phN", (int)bss->wpa_ie_len, bss->wpa_ie);
193 seq_printf(m, "%02x", bss->wpa_ie[i]);
194 seq_putc(m, '\n'); 192 seq_putc(m, '\n');
195 return 0; 193 return 0;
196} 194}
diff --git a/drivers/net/wireless/iwlegacy/4965-mac.c b/drivers/net/wireless/iwlegacy/4965-mac.c
index 3dcbe2cd2b28..26fec54dcd03 100644
--- a/drivers/net/wireless/iwlegacy/4965-mac.c
+++ b/drivers/net/wireless/iwlegacy/4965-mac.c
@@ -4633,7 +4633,7 @@ il4965_store_tx_power(struct device *d, struct device_attribute *attr,
4633 else { 4633 else {
4634 ret = il_set_tx_power(il, val, false); 4634 ret = il_set_tx_power(il, val, false);
4635 if (ret) 4635 if (ret)
4636 IL_ERR("failed setting tx power (0x%d).\n", ret); 4636 IL_ERR("failed setting tx power (0x%08x).\n", ret);
4637 else 4637 else
4638 ret = count; 4638 ret = count;
4639 } 4639 }
@@ -5757,9 +5757,8 @@ il4965_mac_setup_register(struct il_priv *il, u32 max_probe_length)
5757 IEEE80211_HW_REPORTS_TX_ACK_STATUS | IEEE80211_HW_SUPPORTS_PS | 5757 IEEE80211_HW_REPORTS_TX_ACK_STATUS | IEEE80211_HW_SUPPORTS_PS |
5758 IEEE80211_HW_SUPPORTS_DYNAMIC_PS; 5758 IEEE80211_HW_SUPPORTS_DYNAMIC_PS;
5759 if (il->cfg->sku & IL_SKU_N) 5759 if (il->cfg->sku & IL_SKU_N)
5760 hw->flags |= 5760 hw->wiphy->features |= NL80211_FEATURE_DYNAMIC_SMPS |
5761 IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | 5761 NL80211_FEATURE_STATIC_SMPS;
5762 IEEE80211_HW_SUPPORTS_STATIC_SMPS;
5763 5762
5764 hw->sta_data_size = sizeof(struct il_station_priv); 5763 hw->sta_data_size = sizeof(struct il_station_priv);
5765 hw->vif_data_size = sizeof(struct il_vif_priv); 5764 hw->vif_data_size = sizeof(struct il_vif_priv);
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
index afb98f4fdaf3..2364a3c09b9e 100644
--- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c
@@ -125,8 +125,8 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
125 */ 125 */
126 126
127 if (priv->nvm_data->sku_cap_11n_enable) 127 if (priv->nvm_data->sku_cap_11n_enable)
128 hw->flags |= IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS | 128 hw->wiphy->features |= NL80211_FEATURE_DYNAMIC_SMPS |
129 IEEE80211_HW_SUPPORTS_STATIC_SMPS; 129 NL80211_FEATURE_STATIC_SMPS;
130 130
131 /* 131 /*
132 * Enable 11w if advertised by firmware and software crypto 132 * Enable 11w if advertised by firmware and software crypto
diff --git a/drivers/net/wireless/iwlwifi/iwl-7000.c b/drivers/net/wireless/iwlwifi/iwl-7000.c
index 8e99dffa88e8..b04b8858c690 100644
--- a/drivers/net/wireless/iwlwifi/iwl-7000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-7000.c
@@ -131,7 +131,8 @@ static const struct iwl_ht_params iwl7000_ht_params = {
131 .max_data_size = IWL60_RTC_DATA_SIZE, \ 131 .max_data_size = IWL60_RTC_DATA_SIZE, \
132 .base_params = &iwl7000_base_params, \ 132 .base_params = &iwl7000_base_params, \
133 .led_mode = IWL_LED_RF_STATE, \ 133 .led_mode = IWL_LED_RF_STATE, \
134 .nvm_hw_section_num = NVM_HW_SECTION_NUM_FAMILY_7000 134 .nvm_hw_section_num = NVM_HW_SECTION_NUM_FAMILY_7000, \
135 .non_shared_ant = ANT_A
135 136
136 137
137const struct iwl_cfg iwl7260_2ac_cfg = { 138const struct iwl_cfg iwl7260_2ac_cfg = {
@@ -220,6 +221,12 @@ static const struct iwl_pwr_tx_backoff iwl7265_pwr_tx_backoffs[] = {
220 {0}, 221 {0},
221}; 222};
222 223
224static const struct iwl_ht_params iwl7265_ht_params = {
225 .stbc = true,
226 .ldpc = true,
227 .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ),
228};
229
223const struct iwl_cfg iwl3165_2ac_cfg = { 230const struct iwl_cfg iwl3165_2ac_cfg = {
224 .name = "Intel(R) Dual Band Wireless AC 3165", 231 .name = "Intel(R) Dual Band Wireless AC 3165",
225 .fw_name_pre = IWL3165_FW_PRE, 232 .fw_name_pre = IWL3165_FW_PRE,
@@ -234,7 +241,7 @@ const struct iwl_cfg iwl7265_2ac_cfg = {
234 .name = "Intel(R) Dual Band Wireless AC 7265", 241 .name = "Intel(R) Dual Band Wireless AC 7265",
235 .fw_name_pre = IWL7265_FW_PRE, 242 .fw_name_pre = IWL7265_FW_PRE,
236 IWL_DEVICE_7000, 243 IWL_DEVICE_7000,
237 .ht_params = &iwl7000_ht_params, 244 .ht_params = &iwl7265_ht_params,
238 .nvm_ver = IWL7265_NVM_VERSION, 245 .nvm_ver = IWL7265_NVM_VERSION,
239 .nvm_calib_ver = IWL7265_TX_POWER_VERSION, 246 .nvm_calib_ver = IWL7265_TX_POWER_VERSION,
240 .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs, 247 .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
@@ -244,7 +251,7 @@ const struct iwl_cfg iwl7265_2n_cfg = {
244 .name = "Intel(R) Dual Band Wireless N 7265", 251 .name = "Intel(R) Dual Band Wireless N 7265",
245 .fw_name_pre = IWL7265_FW_PRE, 252 .fw_name_pre = IWL7265_FW_PRE,
246 IWL_DEVICE_7000, 253 IWL_DEVICE_7000,
247 .ht_params = &iwl7000_ht_params, 254 .ht_params = &iwl7265_ht_params,
248 .nvm_ver = IWL7265_NVM_VERSION, 255 .nvm_ver = IWL7265_NVM_VERSION,
249 .nvm_calib_ver = IWL7265_TX_POWER_VERSION, 256 .nvm_calib_ver = IWL7265_TX_POWER_VERSION,
250 .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs, 257 .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
@@ -254,7 +261,7 @@ const struct iwl_cfg iwl7265_n_cfg = {
254 .name = "Intel(R) Wireless N 7265", 261 .name = "Intel(R) Wireless N 7265",
255 .fw_name_pre = IWL7265_FW_PRE, 262 .fw_name_pre = IWL7265_FW_PRE,
256 IWL_DEVICE_7000, 263 IWL_DEVICE_7000,
257 .ht_params = &iwl7000_ht_params, 264 .ht_params = &iwl7265_ht_params,
258 .nvm_ver = IWL7265_NVM_VERSION, 265 .nvm_ver = IWL7265_NVM_VERSION,
259 .nvm_calib_ver = IWL7265_TX_POWER_VERSION, 266 .nvm_calib_ver = IWL7265_TX_POWER_VERSION,
260 .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs, 267 .pwr_tx_backoffs = iwl7265_pwr_tx_backoffs,
diff --git a/drivers/net/wireless/iwlwifi/iwl-8000.c b/drivers/net/wireless/iwlwifi/iwl-8000.c
index 23a67bfc086f..4ae8ba6ccfff 100644
--- a/drivers/net/wireless/iwlwifi/iwl-8000.c
+++ b/drivers/net/wireless/iwlwifi/iwl-8000.c
@@ -103,6 +103,7 @@ static const struct iwl_base_params iwl8000_base_params = {
103}; 103};
104 104
105static const struct iwl_ht_params iwl8000_ht_params = { 105static const struct iwl_ht_params iwl8000_ht_params = {
106 .ldpc = true,
106 .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ), 107 .ht40_bands = BIT(IEEE80211_BAND_2GHZ) | BIT(IEEE80211_BAND_5GHZ),
107}; 108};
108 109
@@ -115,7 +116,17 @@ static const struct iwl_ht_params iwl8000_ht_params = {
115 .max_data_size = IWL60_RTC_DATA_SIZE, \ 116 .max_data_size = IWL60_RTC_DATA_SIZE, \
116 .base_params = &iwl8000_base_params, \ 117 .base_params = &iwl8000_base_params, \
117 .led_mode = IWL_LED_RF_STATE, \ 118 .led_mode = IWL_LED_RF_STATE, \
118 .nvm_hw_section_num = NVM_HW_SECTION_NUM_FAMILY_8000 119 .nvm_hw_section_num = NVM_HW_SECTION_NUM_FAMILY_8000, \
120 .non_shared_ant = ANT_A
121
122const struct iwl_cfg iwl8260_2n_cfg = {
123 .name = "Intel(R) Dual Band Wireless N 8260",
124 .fw_name_pre = IWL8000_FW_PRE,
125 IWL_DEVICE_8000,
126 .ht_params = &iwl8000_ht_params,
127 .nvm_ver = IWL8000_NVM_VERSION,
128 .nvm_calib_ver = IWL8000_TX_POWER_VERSION,
129};
119 130
120const struct iwl_cfg iwl8260_2ac_cfg = { 131const struct iwl_cfg iwl8260_2ac_cfg = {
121 .name = "Intel(R) Dual Band Wireless AC 8260", 132 .name = "Intel(R) Dual Band Wireless AC 8260",
@@ -135,6 +146,7 @@ const struct iwl_cfg iwl8260_2ac_sdio_cfg = {
135 .nvm_calib_ver = IWL8000_TX_POWER_VERSION, 146 .nvm_calib_ver = IWL8000_TX_POWER_VERSION,
136 .default_nvm_file = DEFAULT_NVM_FILE_FAMILY_8000, 147 .default_nvm_file = DEFAULT_NVM_FILE_FAMILY_8000,
137 .max_rx_agg_size = MAX_RX_AGG_SIZE_8260_SDIO, 148 .max_rx_agg_size = MAX_RX_AGG_SIZE_8260_SDIO,
149 .disable_dummy_notification = true,
138}; 150};
139 151
140MODULE_FIRMWARE(IWL8000_MODULE_FIRMWARE(IWL8000_UCODE_API_OK)); 152MODULE_FIRMWARE(IWL8000_MODULE_FIRMWARE(IWL8000_UCODE_API_OK));
diff --git a/drivers/net/wireless/iwlwifi/iwl-config.h b/drivers/net/wireless/iwlwifi/iwl-config.h
index 3d7cc37420ae..2ef83a39ff10 100644
--- a/drivers/net/wireless/iwlwifi/iwl-config.h
+++ b/drivers/net/wireless/iwlwifi/iwl-config.h
@@ -171,6 +171,7 @@ struct iwl_base_params {
171 171
172/* 172/*
173 * @stbc: support Tx STBC and 1*SS Rx STBC 173 * @stbc: support Tx STBC and 1*SS Rx STBC
174 * @ldpc: support Tx/Rx with LDPC
174 * @use_rts_for_aggregation: use rts/cts protection for HT traffic 175 * @use_rts_for_aggregation: use rts/cts protection for HT traffic
175 * @ht40_bands: bitmap of bands (using %IEEE80211_BAND_*) that support HT40 176 * @ht40_bands: bitmap of bands (using %IEEE80211_BAND_*) that support HT40
176 */ 177 */
@@ -178,6 +179,7 @@ struct iwl_ht_params {
178 enum ieee80211_smps_mode smps_mode; 179 enum ieee80211_smps_mode smps_mode;
179 const bool ht_greenfield_support; /* if used set to true */ 180 const bool ht_greenfield_support; /* if used set to true */
180 const bool stbc; 181 const bool stbc;
182 const bool ldpc;
181 bool use_rts_for_aggregation; 183 bool use_rts_for_aggregation;
182 u8 ht40_bands; 184 u8 ht40_bands;
183}; 185};
@@ -228,6 +230,7 @@ struct iwl_pwr_tx_backoff {
228 * @max_data_size: The maximal length of the fw data section 230 * @max_data_size: The maximal length of the fw data section
229 * @valid_tx_ant: valid transmit antenna 231 * @valid_tx_ant: valid transmit antenna
230 * @valid_rx_ant: valid receive antenna 232 * @valid_rx_ant: valid receive antenna
233 * @non_shared_ant: the antenna that is for WiFi only
231 * @nvm_ver: NVM version 234 * @nvm_ver: NVM version
232 * @nvm_calib_ver: NVM calibration version 235 * @nvm_calib_ver: NVM calibration version
233 * @lib: pointer to the lib ops 236 * @lib: pointer to the lib ops
@@ -260,6 +263,7 @@ struct iwl_cfg {
260 const u32 max_inst_size; 263 const u32 max_inst_size;
261 u8 valid_tx_ant; 264 u8 valid_tx_ant;
262 u8 valid_rx_ant; 265 u8 valid_rx_ant;
266 u8 non_shared_ant;
263 bool bt_shared_single_ant; 267 bool bt_shared_single_ant;
264 u16 nvm_ver; 268 u16 nvm_ver;
265 u16 nvm_calib_ver; 269 u16 nvm_calib_ver;
@@ -280,6 +284,7 @@ struct iwl_cfg {
280 bool no_power_up_nic_in_init; 284 bool no_power_up_nic_in_init;
281 const char *default_nvm_file; 285 const char *default_nvm_file;
282 unsigned int max_rx_agg_size; 286 unsigned int max_rx_agg_size;
287 bool disable_dummy_notification;
283}; 288};
284 289
285/* 290/*
@@ -341,6 +346,7 @@ extern const struct iwl_cfg iwl3165_2ac_cfg;
341extern const struct iwl_cfg iwl7265_2ac_cfg; 346extern const struct iwl_cfg iwl7265_2ac_cfg;
342extern const struct iwl_cfg iwl7265_2n_cfg; 347extern const struct iwl_cfg iwl7265_2n_cfg;
343extern const struct iwl_cfg iwl7265_n_cfg; 348extern const struct iwl_cfg iwl7265_n_cfg;
349extern const struct iwl_cfg iwl8260_2n_cfg;
344extern const struct iwl_cfg iwl8260_2ac_cfg; 350extern const struct iwl_cfg iwl8260_2ac_cfg;
345extern const struct iwl_cfg iwl8260_2ac_sdio_cfg; 351extern const struct iwl_cfg iwl8260_2ac_sdio_cfg;
346#endif /* CONFIG_IWLMVM */ 352#endif /* CONFIG_IWLMVM */
diff --git a/drivers/net/wireless/iwlwifi/iwl-csr.h b/drivers/net/wireless/iwlwifi/iwl-csr.h
index 23d059af6476..3f6f015285e5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-csr.h
+++ b/drivers/net/wireless/iwlwifi/iwl-csr.h
@@ -295,6 +295,16 @@
295#define CSR_HW_REV_DASH(_val) (((_val) & 0x0000003) >> 0) 295#define CSR_HW_REV_DASH(_val) (((_val) & 0x0000003) >> 0)
296#define CSR_HW_REV_STEP(_val) (((_val) & 0x000000C) >> 2) 296#define CSR_HW_REV_STEP(_val) (((_val) & 0x000000C) >> 2)
297 297
298
299/**
300 * hw_rev values
301 */
302enum {
303 SILICON_A_STEP = 0,
304 SILICON_B_STEP,
305};
306
307
298#define CSR_HW_REV_TYPE_MSK (0x000FFF0) 308#define CSR_HW_REV_TYPE_MSK (0x000FFF0)
299#define CSR_HW_REV_TYPE_5300 (0x0000020) 309#define CSR_HW_REV_TYPE_5300 (0x0000020)
300#define CSR_HW_REV_TYPE_5350 (0x0000030) 310#define CSR_HW_REV_TYPE_5350 (0x0000030)
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c
index aefd94cb6e91..ed673baedfd7 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.c
@@ -1363,7 +1363,7 @@ MODULE_PARM_DESC(fw_restart, "restart firmware in case of error (default true)")
1363module_param_named(antenna_coupling, iwlwifi_mod_params.ant_coupling, 1363module_param_named(antenna_coupling, iwlwifi_mod_params.ant_coupling,
1364 int, S_IRUGO); 1364 int, S_IRUGO);
1365MODULE_PARM_DESC(antenna_coupling, 1365MODULE_PARM_DESC(antenna_coupling,
1366 "specify antenna coupling in dB (defualt: 0 dB)"); 1366 "specify antenna coupling in dB (default: 0 dB)");
1367 1367
1368module_param_named(wd_disable, iwlwifi_mod_params.wd_disable, int, S_IRUGO); 1368module_param_named(wd_disable, iwlwifi_mod_params.wd_disable, int, S_IRUGO);
1369MODULE_PARM_DESC(wd_disable, 1369MODULE_PARM_DESC(wd_disable,
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
index 07ff7e0028ee..74b796dc4242 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom-parse.c
@@ -758,6 +758,9 @@ void iwl_init_ht_hw_capab(const struct iwl_cfg *cfg,
758 ht_info->cap |= IEEE80211_HT_CAP_TX_STBC; 758 ht_info->cap |= IEEE80211_HT_CAP_TX_STBC;
759 } 759 }
760 760
761 if (cfg->ht_params->ldpc)
762 ht_info->cap |= IEEE80211_HT_CAP_LDPC_CODING;
763
761 if (iwlwifi_mod_params.amsdu_size_8K) 764 if (iwlwifi_mod_params.amsdu_size_8K)
762 ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU; 765 ht_info->cap |= IEEE80211_HT_CAP_MAX_AMSDU;
763 766
diff --git a/drivers/net/wireless/iwlwifi/iwl-fw.h b/drivers/net/wireless/iwlwifi/iwl-fw.h
index f68cba4e0444..62c46eb8b99c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-fw.h
+++ b/drivers/net/wireless/iwlwifi/iwl-fw.h
@@ -127,6 +127,7 @@ enum iwl_ucode_tlv_flag {
127 * @IWL_UCODE_TLV_API_CSA_FLOW: ucode can do unbind-bind flow for CSA. 127 * @IWL_UCODE_TLV_API_CSA_FLOW: ucode can do unbind-bind flow for CSA.
128 * @IWL_UCODE_TLV_API_DISABLE_STA_TX: ucode supports tx_disable bit. 128 * @IWL_UCODE_TLV_API_DISABLE_STA_TX: ucode supports tx_disable bit.
129 * @IWL_UCODE_TLV_API_LMAC_SCAN: This ucode uses LMAC unified scan API. 129 * @IWL_UCODE_TLV_API_LMAC_SCAN: This ucode uses LMAC unified scan API.
130 * @IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF: ucode supports disabling dummy notif.
130 * @IWL_UCODE_TLV_API_FRAGMENTED_SCAN: This ucode supports active dwell time 131 * @IWL_UCODE_TLV_API_FRAGMENTED_SCAN: This ucode supports active dwell time
131 * longer than the passive one, which is essential for fragmented scan. 132 * longer than the passive one, which is essential for fragmented scan.
132 */ 133 */
@@ -137,6 +138,7 @@ enum iwl_ucode_tlv_api {
137 IWL_UCODE_TLV_API_CSA_FLOW = BIT(4), 138 IWL_UCODE_TLV_API_CSA_FLOW = BIT(4),
138 IWL_UCODE_TLV_API_DISABLE_STA_TX = BIT(5), 139 IWL_UCODE_TLV_API_DISABLE_STA_TX = BIT(5),
139 IWL_UCODE_TLV_API_LMAC_SCAN = BIT(6), 140 IWL_UCODE_TLV_API_LMAC_SCAN = BIT(6),
141 IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF = BIT(7),
140 IWL_UCODE_TLV_API_FRAGMENTED_SCAN = BIT(8), 142 IWL_UCODE_TLV_API_FRAGMENTED_SCAN = BIT(8),
141}; 143};
142 144
diff --git a/drivers/net/wireless/iwlwifi/iwl-io.c b/drivers/net/wireless/iwlwifi/iwl-io.c
index 5eef4ae7333b..7a2cbf6f90db 100644
--- a/drivers/net/wireless/iwlwifi/iwl-io.c
+++ b/drivers/net/wireless/iwlwifi/iwl-io.c
@@ -193,7 +193,7 @@ void iwl_force_nmi(struct iwl_trans *trans)
193 * DEVICE_SET_NMI_8000B_REG - is used. 193 * DEVICE_SET_NMI_8000B_REG - is used.
194 */ 194 */
195 if ((trans->cfg->device_family != IWL_DEVICE_FAMILY_8000) || 195 if ((trans->cfg->device_family != IWL_DEVICE_FAMILY_8000) ||
196 ((trans->hw_rev & 0xc) == 0x0)) 196 (CSR_HW_REV_STEP(trans->hw_rev) == SILICON_A_STEP))
197 iwl_write_prph(trans, DEVICE_SET_NMI_REG, DEVICE_SET_NMI_VAL); 197 iwl_write_prph(trans, DEVICE_SET_NMI_REG, DEVICE_SET_NMI_VAL);
198 else 198 else
199 iwl_write_prph(trans, DEVICE_SET_NMI_8000B_REG, 199 iwl_write_prph(trans, DEVICE_SET_NMI_8000B_REG,
diff --git a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
index 40718f814f8d..c302e7468559 100644
--- a/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
+++ b/drivers/net/wireless/iwlwifi/iwl-nvm-parse.c
@@ -334,6 +334,9 @@ static void iwl_init_vht_hw_capab(const struct iwl_cfg *cfg,
334 3 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT | 334 3 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT |
335 7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT; 335 7 << IEEE80211_VHT_CAP_MAX_A_MPDU_LENGTH_EXPONENT_SHIFT;
336 336
337 if (cfg->ht_params->ldpc)
338 vht_cap->cap |= IEEE80211_VHT_CAP_RXLDPC;
339
337 if (num_tx_ants > 1) 340 if (num_tx_ants > 1)
338 vht_cap->cap |= IEEE80211_VHT_CAP_TXSTBC; 341 vht_cap->cap |= IEEE80211_VHT_CAP_TXSTBC;
339 else 342 else
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans.h b/drivers/net/wireless/iwlwifi/iwl-trans.h
index c89985a58803..9eb85249e89c 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans.h
+++ b/drivers/net/wireless/iwlwifi/iwl-trans.h
@@ -377,6 +377,7 @@ enum iwl_trans_status {
377 * if unset 4k will be the RX buffer size 377 * if unset 4k will be the RX buffer size
378 * @bc_table_dword: set to true if the BC table expects the byte count to be 378 * @bc_table_dword: set to true if the BC table expects the byte count to be
379 * in DWORD (as opposed to bytes) 379 * in DWORD (as opposed to bytes)
380 * @scd_set_active: should the transport configure the SCD for HCMD queue
380 * @queue_watchdog_timeout: time (in ms) after which queues 381 * @queue_watchdog_timeout: time (in ms) after which queues
381 * are considered stuck and will trigger device restart 382 * are considered stuck and will trigger device restart
382 * @command_names: array of command names, must be 256 entries 383 * @command_names: array of command names, must be 256 entries
@@ -392,6 +393,7 @@ struct iwl_trans_config {
392 393
393 bool rx_buf_size_8k; 394 bool rx_buf_size_8k;
394 bool bc_table_dword; 395 bool bc_table_dword;
396 bool scd_set_active;
395 unsigned int queue_watchdog_timeout; 397 unsigned int queue_watchdog_timeout;
396 const char *const *command_names; 398 const char *const *command_names;
397}; 399};
@@ -826,12 +828,6 @@ static inline void iwl_trans_ac_txq_enable(struct iwl_trans *trans, int queue,
826 iwl_trans_txq_enable_cfg(trans, queue, 0, &cfg); 828 iwl_trans_txq_enable_cfg(trans, queue, 0, &cfg);
827} 829}
828 830
829static inline void
830iwl_trans_txq_enable_no_scd(struct iwl_trans *trans, int queue, u16 ssn)
831{
832 iwl_trans_txq_enable_cfg(trans, queue, ssn, NULL);
833}
834
835static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans, 831static inline int iwl_trans_wait_tx_queue_empty(struct iwl_trans *trans,
836 u32 txq_bm) 832 u32 txq_bm)
837{ 833{
diff --git a/drivers/net/wireless/iwlwifi/mvm/Makefile b/drivers/net/wireless/iwlwifi/mvm/Makefile
index a28235913c2c..2d7c3ea3c4f8 100644
--- a/drivers/net/wireless/iwlwifi/mvm/Makefile
+++ b/drivers/net/wireless/iwlwifi/mvm/Makefile
@@ -3,7 +3,7 @@ iwlmvm-y += fw.o mac80211.o nvm.o ops.o phy-ctxt.o mac-ctxt.o
3iwlmvm-y += utils.o rx.o tx.o binding.o quota.o sta.o sf.o 3iwlmvm-y += utils.o rx.o tx.o binding.o quota.o sta.o sf.o
4iwlmvm-y += scan.o time-event.o rs.o 4iwlmvm-y += scan.o time-event.o rs.o
5iwlmvm-y += power.o coex.o coex_legacy.o 5iwlmvm-y += power.o coex.o coex_legacy.o
6iwlmvm-y += tt.o offloading.o 6iwlmvm-y += tt.o offloading.o tdls.o
7iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o debugfs-vif.o 7iwlmvm-$(CONFIG_IWLWIFI_DEBUGFS) += debugfs.o debugfs-vif.o
8iwlmvm-$(CONFIG_IWLWIFI_LEDS) += led.o 8iwlmvm-$(CONFIG_IWLWIFI_LEDS) += led.o
9iwlmvm-$(CONFIG_PM_SLEEP) += d3.o 9iwlmvm-$(CONFIG_PM_SLEEP) += d3.o
diff --git a/drivers/net/wireless/iwlwifi/mvm/coex.c b/drivers/net/wireless/iwlwifi/mvm/coex.c
index 6e8f3e2aef74..8df2021f9856 100644
--- a/drivers/net/wireless/iwlwifi/mvm/coex.c
+++ b/drivers/net/wireless/iwlwifi/mvm/coex.c
@@ -1146,6 +1146,10 @@ bool iwl_mvm_bt_coex_is_mimo_allowed(struct iwl_mvm *mvm,
1146 1146
1147bool iwl_mvm_bt_coex_is_shared_ant_avail(struct iwl_mvm *mvm) 1147bool iwl_mvm_bt_coex_is_shared_ant_avail(struct iwl_mvm *mvm)
1148{ 1148{
1149 /* there is no other antenna, shared antenna is always available */
1150 if (mvm->cfg->bt_shared_single_ant)
1151 return true;
1152
1149 if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BT_COEX_SPLIT)) 1153 if (!(mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_BT_COEX_SPLIT))
1150 return iwl_mvm_bt_coex_is_shared_ant_avail_old(mvm); 1154 return iwl_mvm_bt_coex_is_shared_ant_avail_old(mvm);
1151 1155
diff --git a/drivers/net/wireless/iwlwifi/mvm/constants.h b/drivers/net/wireless/iwlwifi/mvm/constants.h
index dd00e8f7f765..a355788b1166 100644
--- a/drivers/net/wireless/iwlwifi/mvm/constants.h
+++ b/drivers/net/wireless/iwlwifi/mvm/constants.h
@@ -65,12 +65,18 @@
65#ifndef __MVM_CONSTANTS_H 65#ifndef __MVM_CONSTANTS_H
66#define __MVM_CONSTANTS_H 66#define __MVM_CONSTANTS_H
67 67
68#include <linux/ieee80211.h>
69
68#define IWL_MVM_DEFAULT_PS_TX_DATA_TIMEOUT (100 * USEC_PER_MSEC) 70#define IWL_MVM_DEFAULT_PS_TX_DATA_TIMEOUT (100 * USEC_PER_MSEC)
69#define IWL_MVM_DEFAULT_PS_RX_DATA_TIMEOUT (100 * USEC_PER_MSEC) 71#define IWL_MVM_DEFAULT_PS_RX_DATA_TIMEOUT (100 * USEC_PER_MSEC)
70#define IWL_MVM_WOWLAN_PS_TX_DATA_TIMEOUT (10 * USEC_PER_MSEC) 72#define IWL_MVM_WOWLAN_PS_TX_DATA_TIMEOUT (10 * USEC_PER_MSEC)
71#define IWL_MVM_WOWLAN_PS_RX_DATA_TIMEOUT (10 * USEC_PER_MSEC) 73#define IWL_MVM_WOWLAN_PS_RX_DATA_TIMEOUT (10 * USEC_PER_MSEC)
72#define IWL_MVM_UAPSD_RX_DATA_TIMEOUT (50 * USEC_PER_MSEC) 74#define IWL_MVM_UAPSD_RX_DATA_TIMEOUT (50 * USEC_PER_MSEC)
73#define IWL_MVM_UAPSD_TX_DATA_TIMEOUT (50 * USEC_PER_MSEC) 75#define IWL_MVM_UAPSD_TX_DATA_TIMEOUT (50 * USEC_PER_MSEC)
76#define IWL_MVM_UAPSD_QUEUES (IEEE80211_WMM_IE_STA_QOSINFO_AC_VO |\
77 IEEE80211_WMM_IE_STA_QOSINFO_AC_VI |\
78 IEEE80211_WMM_IE_STA_QOSINFO_AC_BK |\
79 IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)
74#define IWL_MVM_PS_HEAVY_TX_THLD_PACKETS 20 80#define IWL_MVM_PS_HEAVY_TX_THLD_PACKETS 20
75#define IWL_MVM_PS_HEAVY_RX_THLD_PACKETS 8 81#define IWL_MVM_PS_HEAVY_RX_THLD_PACKETS 8
76#define IWL_MVM_PS_SNOOZE_HEAVY_TX_THLD_PACKETS 30 82#define IWL_MVM_PS_SNOOZE_HEAVY_TX_THLD_PACKETS 30
@@ -86,5 +92,7 @@
86#define IWL_MVM_BT_COEX_SYNC2SCO 1 92#define IWL_MVM_BT_COEX_SYNC2SCO 1
87#define IWL_MVM_BT_COEX_CORUNNING 1 93#define IWL_MVM_BT_COEX_CORUNNING 1
88#define IWL_MVM_BT_COEX_MPLUT 1 94#define IWL_MVM_BT_COEX_MPLUT 1
95#define IWL_MVM_FW_MCAST_FILTER_PASS_ALL 0
96#define IWL_MVM_QUOTA_THRESHOLD 8
89 97
90#endif /* __MVM_CONSTANTS_H */ 98#endif /* __MVM_CONSTANTS_H */
diff --git a/drivers/net/wireless/iwlwifi/mvm/debugfs.c b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
index d98ee109c5e9..95eb9a5ef693 100644
--- a/drivers/net/wireless/iwlwifi/mvm/debugfs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/debugfs.c
@@ -288,6 +288,9 @@ static ssize_t iwl_dbgfs_set_nic_temperature_write(struct iwl_mvm *mvm,
288{ 288{
289 int temperature; 289 int temperature;
290 290
291 if (!mvm->ucode_loaded && !mvm->temperature_test)
292 return -EIO;
293
291 if (kstrtoint(buf, 10, &temperature)) 294 if (kstrtoint(buf, 10, &temperature))
292 return -EINVAL; 295 return -EINVAL;
293 /* not a legal temperature */ 296 /* not a legal temperature */
@@ -1256,6 +1259,18 @@ static ssize_t iwl_dbgfs_d0i3_refs_read(struct file *file,
1256 PRINT_MVM_REF(IWL_MVM_REF_P2P_CLIENT); 1259 PRINT_MVM_REF(IWL_MVM_REF_P2P_CLIENT);
1257 PRINT_MVM_REF(IWL_MVM_REF_AP_IBSS); 1260 PRINT_MVM_REF(IWL_MVM_REF_AP_IBSS);
1258 PRINT_MVM_REF(IWL_MVM_REF_USER); 1261 PRINT_MVM_REF(IWL_MVM_REF_USER);
1262 PRINT_MVM_REF(IWL_MVM_REF_TX);
1263 PRINT_MVM_REF(IWL_MVM_REF_TX_AGG);
1264 PRINT_MVM_REF(IWL_MVM_REF_ADD_IF);
1265 PRINT_MVM_REF(IWL_MVM_REF_START_AP);
1266 PRINT_MVM_REF(IWL_MVM_REF_BSS_CHANGED);
1267 PRINT_MVM_REF(IWL_MVM_REF_PREPARE_TX);
1268 PRINT_MVM_REF(IWL_MVM_REF_PROTECT_TDLS);
1269 PRINT_MVM_REF(IWL_MVM_REF_CHECK_CTKILL);
1270 PRINT_MVM_REF(IWL_MVM_REF_PRPH_READ);
1271 PRINT_MVM_REF(IWL_MVM_REF_PRPH_WRITE);
1272 PRINT_MVM_REF(IWL_MVM_REF_NMI);
1273 PRINT_MVM_REF(IWL_MVM_REF_TM_CMD);
1259 PRINT_MVM_REF(IWL_MVM_REF_EXIT_WORK); 1274 PRINT_MVM_REF(IWL_MVM_REF_EXIT_WORK);
1260 1275
1261 return simple_read_from_buffer(user_buf, count, ppos, buf, pos); 1276 return simple_read_from_buffer(user_buf, count, ppos, buf, pos);
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw-api.h b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
index 541b844c6b5d..a2c662808a88 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw-api.h
+++ b/drivers/net/wireless/iwlwifi/mvm/fw-api.h
@@ -205,6 +205,10 @@ enum {
205 REPLY_SF_CFG_CMD = 0xd1, 205 REPLY_SF_CFG_CMD = 0xd1,
206 REPLY_BEACON_FILTERING_CMD = 0xd2, 206 REPLY_BEACON_FILTERING_CMD = 0xd2,
207 207
208 /* DTS measurements */
209 CMD_DTS_MEASUREMENT_TRIGGER = 0xdc,
210 DTS_MEASUREMENT_NOTIFICATION = 0xdd,
211
208 REPLY_DEBUG_CMD = 0xf0, 212 REPLY_DEBUG_CMD = 0xf0,
209 DEBUG_LOG_MSG = 0xf7, 213 DEBUG_LOG_MSG = 0xf7,
210 214
@@ -550,7 +554,7 @@ enum iwl_time_event_type {
550 TE_WIDI_TX_SYNC, 554 TE_WIDI_TX_SYNC,
551 555
552 /* Channel Switch NoA */ 556 /* Channel Switch NoA */
553 TE_P2P_GO_CSA_NOA, 557 TE_CHANNEL_SWITCH_PERIOD,
554 558
555 TE_MAX 559 TE_MAX
556}; /* MAC_EVENT_TYPE_API_E_VER_1 */ 560}; /* MAC_EVENT_TYPE_API_E_VER_1 */
@@ -1601,6 +1605,8 @@ enum iwl_sf_scenario {
1601 1605
1602#define SF_LONG_DELAY_AGING_TIMER 1000000 /* 1 Sec */ 1606#define SF_LONG_DELAY_AGING_TIMER 1000000 /* 1 Sec */
1603 1607
1608#define SF_CFG_DUMMY_NOTIF_OFF BIT(16)
1609
1604/** 1610/**
1605 * Smart Fifo configuration command. 1611 * Smart Fifo configuration command.
1606 * @state: smart fifo state, types listed in enum %iwl_sf_sate. 1612 * @state: smart fifo state, types listed in enum %iwl_sf_sate.
@@ -1616,4 +1622,32 @@ struct iwl_sf_cfg_cmd {
1616 __le32 full_on_timeouts[SF_NUM_SCENARIO][SF_NUM_TIMEOUT_TYPES]; 1622 __le32 full_on_timeouts[SF_NUM_SCENARIO][SF_NUM_TIMEOUT_TYPES];
1617} __packed; /* SF_CFG_API_S_VER_2 */ 1623} __packed; /* SF_CFG_API_S_VER_2 */
1618 1624
1625/* DTS measurements */
1626
1627enum iwl_dts_measurement_flags {
1628 DTS_TRIGGER_CMD_FLAGS_TEMP = BIT(0),
1629 DTS_TRIGGER_CMD_FLAGS_VOLT = BIT(1),
1630};
1631
1632/**
1633 * iwl_dts_measurement_cmd - request DTS temperature and/or voltage measurements
1634 *
1635 * @flags: indicates which measurements we want as specified in &enum
1636 * iwl_dts_measurement_flags
1637 */
1638struct iwl_dts_measurement_cmd {
1639 __le32 flags;
1640} __packed; /* TEMPERATURE_MEASUREMENT_TRIGGER_CMD_S */
1641
1642/**
1643 * iwl_dts_measurement_notif - notification received with the measurements
1644 *
1645 * @temp: the measured temperature
1646 * @voltage: the measured voltage
1647 */
1648struct iwl_dts_measurement_notif {
1649 __le32 temp;
1650 __le32 voltage;
1651} __packed; /* TEMPERATURE_MEASUREMENT_TRIGGER_NTFY_S */
1652
1619#endif /* __fw_api_h__ */ 1653#endif /* __fw_api_h__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/fw.c b/drivers/net/wireless/iwlwifi/mvm/fw.c
index 21d606028ca6..23fd711a67e4 100644
--- a/drivers/net/wireless/iwlwifi/mvm/fw.c
+++ b/drivers/net/wireless/iwlwifi/mvm/fw.c
@@ -454,6 +454,9 @@ int iwl_mvm_up(struct iwl_mvm *mvm)
454 for (i = 0; i < IWL_MVM_STATION_COUNT; i++) 454 for (i = 0; i < IWL_MVM_STATION_COUNT; i++)
455 RCU_INIT_POINTER(mvm->fw_id_to_mac_id[i], NULL); 455 RCU_INIT_POINTER(mvm->fw_id_to_mac_id[i], NULL);
456 456
457 /* reset quota debouncing buffer - 0xff will yield invalid data */
458 memset(&mvm->last_quota_cmd, 0xff, sizeof(mvm->last_quota_cmd));
459
457 /* Add auxiliary station for scanning */ 460 /* Add auxiliary station for scanning */
458 ret = iwl_mvm_add_aux_sta(mvm); 461 ret = iwl_mvm_add_aux_sta(mvm);
459 if (ret) 462 if (ret)
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
index 158aed501473..834267145929 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac-ctxt.c
@@ -1234,13 +1234,13 @@ static void iwl_mvm_csa_count_down(struct iwl_mvm *mvm,
1234 !iwl_mvm_te_scheduled(&mvmvif->time_event_data) && gp2) { 1234 !iwl_mvm_te_scheduled(&mvmvif->time_event_data) && gp2) {
1235 u32 rel_time = (c + 1) * 1235 u32 rel_time = (c + 1) *
1236 csa_vif->bss_conf.beacon_int - 1236 csa_vif->bss_conf.beacon_int -
1237 IWL_MVM_CHANNEL_SWITCH_TIME; 1237 IWL_MVM_CHANNEL_SWITCH_TIME_GO;
1238 u32 apply_time = gp2 + rel_time * 1024; 1238 u32 apply_time = gp2 + rel_time * 1024;
1239 1239
1240 iwl_mvm_schedule_csa_noa(mvm, csa_vif, 1240 iwl_mvm_schedule_csa_period(mvm, csa_vif,
1241 IWL_MVM_CHANNEL_SWITCH_TIME - 1241 IWL_MVM_CHANNEL_SWITCH_TIME_GO -
1242 IWL_MVM_CHANNEL_SWITCH_MARGIN, 1242 IWL_MVM_CHANNEL_SWITCH_MARGIN,
1243 apply_time); 1243 apply_time);
1244 } 1244 }
1245 } else if (!iwl_mvm_te_scheduled(&mvmvif->time_event_data)) { 1245 } else if (!iwl_mvm_te_scheduled(&mvmvif->time_event_data)) {
1246 /* we don't have CSA NoA scheduled yet, switch now */ 1246 /* we don't have CSA NoA scheduled yet, switch now */
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
index 069bb8e81c36..4c2121094a0b 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c
@@ -303,9 +303,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
303 IEEE80211_HW_AMPDU_AGGREGATION | 303 IEEE80211_HW_AMPDU_AGGREGATION |
304 IEEE80211_HW_TIMING_BEACON_ONLY | 304 IEEE80211_HW_TIMING_BEACON_ONLY |
305 IEEE80211_HW_CONNECTION_MONITOR | 305 IEEE80211_HW_CONNECTION_MONITOR |
306 IEEE80211_HW_CHANCTX_STA_CSA | 306 IEEE80211_HW_CHANCTX_STA_CSA;
307 IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
308 IEEE80211_HW_SUPPORTS_STATIC_SMPS;
309 307
310 hw->queues = mvm->first_agg_queue; 308 hw->queues = mvm->first_agg_queue;
311 hw->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE; 309 hw->offchannel_tx_hw_queue = IWL_MVM_OFFCHANNEL_QUEUE;
@@ -327,7 +325,7 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
327 IWL_UCODE_API(mvm->fw->ucode_ver) >= 9 && 325 IWL_UCODE_API(mvm->fw->ucode_ver) >= 9 &&
328 !iwlwifi_mod_params.uapsd_disable) { 326 !iwlwifi_mod_params.uapsd_disable) {
329 hw->flags |= IEEE80211_HW_SUPPORTS_UAPSD; 327 hw->flags |= IEEE80211_HW_SUPPORTS_UAPSD;
330 hw->uapsd_queues = IWL_UAPSD_AC_INFO; 328 hw->uapsd_queues = IWL_MVM_UAPSD_QUEUES;
331 hw->uapsd_max_sp_len = IWL_UAPSD_MAX_SP; 329 hw->uapsd_max_sp_len = IWL_UAPSD_MAX_SP;
332 } 330 }
333 331
@@ -409,7 +407,9 @@ int iwl_mvm_mac_setup_register(struct iwl_mvm *mvm)
409 407
410 hw->wiphy->features |= NL80211_FEATURE_P2P_GO_CTWIN | 408 hw->wiphy->features |= NL80211_FEATURE_P2P_GO_CTWIN |
411 NL80211_FEATURE_LOW_PRIORITY_SCAN | 409 NL80211_FEATURE_LOW_PRIORITY_SCAN |
412 NL80211_FEATURE_P2P_GO_OPPPS; 410 NL80211_FEATURE_P2P_GO_OPPPS |
411 NL80211_FEATURE_DYNAMIC_SMPS |
412 NL80211_FEATURE_STATIC_SMPS;
413 413
414 mvm->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD; 414 mvm->rts_threshold = IEEE80211_MAX_RTS_THRESHOLD;
415 415
@@ -670,8 +670,9 @@ static void iwl_mvm_cleanup_iterator(void *data, u8 *mac,
670} 670}
671 671
672#ifdef CONFIG_IWLWIFI_DEBUGFS 672#ifdef CONFIG_IWLWIFI_DEBUGFS
673static void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm) 673void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
674{ 674{
675 static char *env[] = { "DRIVER=iwlwifi", "EVENT=error_dump", NULL };
675 struct iwl_fw_error_dump_file *dump_file; 676 struct iwl_fw_error_dump_file *dump_file;
676 struct iwl_fw_error_dump_data *dump_data; 677 struct iwl_fw_error_dump_data *dump_data;
677 struct iwl_fw_error_dump_info *dump_info; 678 struct iwl_fw_error_dump_info *dump_info;
@@ -763,20 +764,16 @@ static void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm)
763 file_len += fw_error_dump->trans_ptr->len; 764 file_len += fw_error_dump->trans_ptr->len;
764 dump_file->file_len = cpu_to_le32(file_len); 765 dump_file->file_len = cpu_to_le32(file_len);
765 mvm->fw_error_dump = fw_error_dump; 766 mvm->fw_error_dump = fw_error_dump;
767
768 /* notify the userspace about the error we had */
769 kobject_uevent_env(&mvm->hw->wiphy->dev.kobj, KOBJ_CHANGE, env);
766} 770}
767#endif 771#endif
768 772
769static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm) 773static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
770{ 774{
771#ifdef CONFIG_IWLWIFI_DEBUGFS
772 static char *env[] = { "DRIVER=iwlwifi", "EVENT=error_dump", NULL };
773
774 iwl_mvm_fw_error_dump(mvm); 775 iwl_mvm_fw_error_dump(mvm);
775 776
776 /* notify the userspace about the error we had */
777 kobject_uevent_env(&mvm->hw->wiphy->dev.kobj, KOBJ_CHANGE, env);
778#endif
779
780 iwl_trans_stop_device(mvm->trans); 777 iwl_trans_stop_device(mvm->trans);
781 778
782 mvm->scan_status = IWL_MVM_SCAN_NONE; 779 mvm->scan_status = IWL_MVM_SCAN_NONE;
@@ -815,12 +812,11 @@ static void iwl_mvm_restart_cleanup(struct iwl_mvm *mvm)
815 mvm->rx_ba_sessions = 0; 812 mvm->rx_ba_sessions = 0;
816} 813}
817 814
818static int iwl_mvm_mac_start(struct ieee80211_hw *hw) 815int __iwl_mvm_mac_start(struct iwl_mvm *mvm)
819{ 816{
820 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
821 int ret; 817 int ret;
822 818
823 mutex_lock(&mvm->mutex); 819 lockdep_assert_held(&mvm->mutex);
824 820
825 /* Clean up some internal and mac80211 state on restart */ 821 /* Clean up some internal and mac80211 state on restart */
826 if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status)) 822 if (test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status))
@@ -837,6 +833,16 @@ static int iwl_mvm_mac_start(struct ieee80211_hw *hw)
837 iwl_mvm_d0i3_enable_tx(mvm, NULL); 833 iwl_mvm_d0i3_enable_tx(mvm, NULL);
838 } 834 }
839 835
836 return ret;
837}
838
839static int iwl_mvm_mac_start(struct ieee80211_hw *hw)
840{
841 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
842 int ret;
843
844 mutex_lock(&mvm->mutex);
845 ret = __iwl_mvm_mac_start(mvm);
840 mutex_unlock(&mvm->mutex); 846 mutex_unlock(&mvm->mutex);
841 847
842 return ret; 848 return ret;
@@ -862,14 +868,9 @@ static void iwl_mvm_mac_restart_complete(struct ieee80211_hw *hw)
862 mutex_unlock(&mvm->mutex); 868 mutex_unlock(&mvm->mutex);
863} 869}
864 870
865static void iwl_mvm_mac_stop(struct ieee80211_hw *hw) 871void __iwl_mvm_mac_stop(struct iwl_mvm *mvm)
866{ 872{
867 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 873 lockdep_assert_held(&mvm->mutex);
868
869 flush_work(&mvm->d0i3_exit_work);
870 flush_work(&mvm->async_handlers_wk);
871
872 mutex_lock(&mvm->mutex);
873 874
874 /* disallow low power states when the FW is down */ 875 /* disallow low power states when the FW is down */
875 iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN); 876 iwl_mvm_ref(mvm, IWL_MVM_REF_UCODE_DOWN);
@@ -890,6 +891,19 @@ static void iwl_mvm_mac_stop(struct ieee80211_hw *hw)
890 /* the fw is stopped, the aux sta is dead: clean up driver state */ 891 /* the fw is stopped, the aux sta is dead: clean up driver state */
891 iwl_mvm_del_aux_sta(mvm); 892 iwl_mvm_del_aux_sta(mvm);
892 893
894 mvm->ucode_loaded = false;
895}
896
897static void iwl_mvm_mac_stop(struct ieee80211_hw *hw)
898{
899 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
900
901 flush_work(&mvm->d0i3_exit_work);
902 flush_work(&mvm->async_handlers_wk);
903 flush_work(&mvm->fw_error_dump_wk);
904
905 mutex_lock(&mvm->mutex);
906 __iwl_mvm_mac_stop(mvm);
893 mutex_unlock(&mvm->mutex); 907 mutex_unlock(&mvm->mutex);
894 908
895 /* 909 /*
@@ -1198,14 +1212,15 @@ static u64 iwl_mvm_prepare_multicast(struct ieee80211_hw *hw,
1198 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); 1212 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
1199 struct iwl_mcast_filter_cmd *cmd; 1213 struct iwl_mcast_filter_cmd *cmd;
1200 struct netdev_hw_addr *addr; 1214 struct netdev_hw_addr *addr;
1201 int addr_count = netdev_hw_addr_list_count(mc_list); 1215 int addr_count;
1202 bool pass_all = false; 1216 bool pass_all;
1203 int len; 1217 int len;
1204 1218
1205 if (addr_count > MAX_MCAST_FILTERING_ADDRESSES) { 1219 addr_count = netdev_hw_addr_list_count(mc_list);
1206 pass_all = true; 1220 pass_all = addr_count > MAX_MCAST_FILTERING_ADDRESSES ||
1221 IWL_MVM_FW_MCAST_FILTER_PASS_ALL;
1222 if (pass_all)
1207 addr_count = 0; 1223 addr_count = 0;
1208 }
1209 1224
1210 len = roundup(sizeof(*cmd) + addr_count * ETH_ALEN, 4); 1225 len = roundup(sizeof(*cmd) + addr_count * ETH_ALEN, 4);
1211 cmd = kzalloc(len, GFP_ATOMIC); 1226 cmd = kzalloc(len, GFP_ATOMIC);
@@ -1405,28 +1420,6 @@ static inline int iwl_mvm_configure_bcast_filter(struct iwl_mvm *mvm,
1405} 1420}
1406#endif 1421#endif
1407 1422
1408static void iwl_mvm_teardown_tdls_peers(struct iwl_mvm *mvm)
1409{
1410 struct ieee80211_sta *sta;
1411 struct iwl_mvm_sta *mvmsta;
1412 int i;
1413
1414 lockdep_assert_held(&mvm->mutex);
1415
1416 for (i = 0; i < IWL_MVM_STATION_COUNT; i++) {
1417 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i],
1418 lockdep_is_held(&mvm->mutex));
1419 if (!sta || IS_ERR(sta) || !sta->tdls)
1420 continue;
1421
1422 mvmsta = iwl_mvm_sta_from_mac80211(sta);
1423 ieee80211_tdls_oper_request(mvmsta->vif, sta->addr,
1424 NL80211_TDLS_TEARDOWN,
1425 WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED,
1426 GFP_KERNEL);
1427 }
1428}
1429
1430static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm, 1423static void iwl_mvm_bss_info_changed_station(struct iwl_mvm *mvm,
1431 struct ieee80211_vif *vif, 1424 struct ieee80211_vif *vif,
1432 struct ieee80211_bss_conf *bss_conf, 1425 struct ieee80211_bss_conf *bss_conf,
@@ -1724,7 +1717,7 @@ iwl_mvm_bss_info_changed_ap_ibss(struct iwl_mvm *mvm,
1724 return; 1717 return;
1725 1718
1726 if (changes & (BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_HT | 1719 if (changes & (BSS_CHANGED_ERP_CTS_PROT | BSS_CHANGED_HT |
1727 BSS_CHANGED_BANDWIDTH) && 1720 BSS_CHANGED_BANDWIDTH | BSS_CHANGED_QOS) &&
1728 iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL)) 1721 iwl_mvm_mac_ctxt_changed(mvm, vif, false, NULL))
1729 IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr); 1722 IWL_ERR(mvm, "failed to update MAC %pM\n", vif->addr);
1730 1723
@@ -1955,48 +1948,6 @@ static void iwl_mvm_sta_pre_rcu_remove(struct ieee80211_hw *hw,
1955 mutex_unlock(&mvm->mutex); 1948 mutex_unlock(&mvm->mutex);
1956} 1949}
1957 1950
1958int iwl_mvm_tdls_sta_count(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
1959{
1960 struct ieee80211_sta *sta;
1961 struct iwl_mvm_sta *mvmsta;
1962 int count = 0;
1963 int i;
1964
1965 lockdep_assert_held(&mvm->mutex);
1966
1967 for (i = 0; i < IWL_MVM_STATION_COUNT; i++) {
1968 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i],
1969 lockdep_is_held(&mvm->mutex));
1970 if (!sta || IS_ERR(sta) || !sta->tdls)
1971 continue;
1972
1973 if (vif) {
1974 mvmsta = iwl_mvm_sta_from_mac80211(sta);
1975 if (mvmsta->vif != vif)
1976 continue;
1977 }
1978
1979 count++;
1980 }
1981
1982 return count;
1983}
1984
1985static void iwl_mvm_recalc_tdls_state(struct iwl_mvm *mvm,
1986 struct ieee80211_vif *vif,
1987 bool sta_added)
1988{
1989 int tdls_sta_cnt = iwl_mvm_tdls_sta_count(mvm, vif);
1990
1991 /*
1992 * Disable ps when the first TDLS sta is added and re-enable it
1993 * when the last TDLS sta is removed
1994 */
1995 if ((tdls_sta_cnt == 1 && sta_added) ||
1996 (tdls_sta_cnt == 0 && !sta_added))
1997 iwl_mvm_power_update_mac(mvm);
1998}
1999
2000static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw, 1951static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
2001 struct ieee80211_vif *vif, 1952 struct ieee80211_vif *vif,
2002 struct ieee80211_sta *sta, 1953 struct ieee80211_sta *sta,
@@ -2170,27 +2121,6 @@ static void iwl_mvm_mac_mgd_prepare_tx(struct ieee80211_hw *hw,
2170 iwl_mvm_unref(mvm, IWL_MVM_REF_PREPARE_TX); 2121 iwl_mvm_unref(mvm, IWL_MVM_REF_PREPARE_TX);
2171} 2122}
2172 2123
2173static void iwl_mvm_mac_mgd_protect_tdls_discover(struct ieee80211_hw *hw,
2174 struct ieee80211_vif *vif)
2175{
2176 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
2177 u32 duration = 2 * vif->bss_conf.dtim_period * vif->bss_conf.beacon_int;
2178
2179 /*
2180 * iwl_mvm_protect_session() reads directly from the device
2181 * (the system time), so make sure it is available.
2182 */
2183 if (iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PROTECT_TDLS))
2184 return;
2185
2186 mutex_lock(&mvm->mutex);
2187 /* Protect the session to hear the TDLS setup response on the channel */
2188 iwl_mvm_protect_session(mvm, vif, duration, duration, 100, true);
2189 mutex_unlock(&mvm->mutex);
2190
2191 iwl_mvm_unref(mvm, IWL_MVM_REF_PROTECT_TDLS);
2192}
2193
2194static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw, 2124static int iwl_mvm_mac_sched_scan_start(struct ieee80211_hw *hw,
2195 struct ieee80211_vif *vif, 2125 struct ieee80211_vif *vif,
2196 struct cfg80211_sched_scan_request *req, 2126 struct cfg80211_sched_scan_request *req,
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index e292de96e09a..552995810f9e 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -87,11 +87,11 @@
87/* A TimeUnit is 1024 microsecond */ 87/* A TimeUnit is 1024 microsecond */
88#define MSEC_TO_TU(_msec) (_msec*1000/1024) 88#define MSEC_TO_TU(_msec) (_msec*1000/1024)
89 89
90/* 90/* This value represents the number of TUs before CSA "beacon 0" TBTT
91 * The CSA NoA is scheduled IWL_MVM_CHANNEL_SWITCH_TIME TUs before "beacon 0" 91 * when the CSA time-event needs to be scheduled to start. It must be
92 * TBTT. This value should be big enough to ensure that we switch in time. 92 * big enough to ensure that we switch in time.
93 */ 93 */
94#define IWL_MVM_CHANNEL_SWITCH_TIME 40 94#define IWL_MVM_CHANNEL_SWITCH_TIME_GO 40
95 95
96/* 96/*
97 * This value (in TUs) is used to fine tune the CSA NoA end time which should 97 * This value (in TUs) is used to fine tune the CSA NoA end time which should
@@ -180,10 +180,6 @@ enum iwl_power_scheme {
180}; 180};
181 181
182#define IWL_CONN_MAX_LISTEN_INTERVAL 10 182#define IWL_CONN_MAX_LISTEN_INTERVAL 10
183#define IWL_UAPSD_AC_INFO (IEEE80211_WMM_IE_STA_QOSINFO_AC_VO |\
184 IEEE80211_WMM_IE_STA_QOSINFO_AC_VI |\
185 IEEE80211_WMM_IE_STA_QOSINFO_AC_BK |\
186 IEEE80211_WMM_IE_STA_QOSINFO_AC_BE)
187#define IWL_UAPSD_MAX_SP IEEE80211_WMM_IE_STA_QOSINFO_SP_2 183#define IWL_UAPSD_MAX_SP IEEE80211_WMM_IE_STA_QOSINFO_SP_2
188 184
189#ifdef CONFIG_IWLWIFI_DEBUGFS 185#ifdef CONFIG_IWLWIFI_DEBUGFS
@@ -274,6 +270,8 @@ enum iwl_mvm_ref_type {
274 IWL_MVM_REF_TM_CMD, 270 IWL_MVM_REF_TM_CMD,
275 IWL_MVM_REF_EXIT_WORK, 271 IWL_MVM_REF_EXIT_WORK,
276 272
273 /* update debugfs.c when changing this */
274
277 IWL_MVM_REF_COUNT, 275 IWL_MVM_REF_COUNT,
278}; 276};
279 277
@@ -649,6 +647,7 @@ struct iwl_mvm {
649 647
650 /* -1 for always, 0 for never, >0 for that many times */ 648 /* -1 for always, 0 for never, >0 for that many times */
651 s8 restart_fw; 649 s8 restart_fw;
650 struct work_struct fw_error_dump_wk;
652 struct iwl_mvm_dump_ptrs *fw_error_dump; 651 struct iwl_mvm_dump_ptrs *fw_error_dump;
653 652
654#ifdef CONFIG_IWLWIFI_LEDS 653#ifdef CONFIG_IWLWIFI_LEDS
@@ -709,6 +708,8 @@ struct iwl_mvm {
709 */ 708 */
710 bool temperature_test; /* Debug test temperature is enabled */ 709 bool temperature_test; /* Debug test temperature is enabled */
711 710
711 struct iwl_time_quota_cmd last_quota_cmd;
712
712#ifdef CONFIG_NL80211_TESTMODE 713#ifdef CONFIG_NL80211_TESTMODE
713 u32 noa_duration; 714 u32 noa_duration;
714 struct ieee80211_vif *noa_vif; 715 struct ieee80211_vif *noa_vif;
@@ -788,6 +789,9 @@ struct iwl_rate_info {
788 u8 ieee; /* MAC header: IWL_RATE_6M_IEEE, etc. */ 789 u8 ieee; /* MAC header: IWL_RATE_6M_IEEE, etc. */
789}; 790};
790 791
792void __iwl_mvm_mac_stop(struct iwl_mvm *mvm);
793int __iwl_mvm_mac_start(struct iwl_mvm *mvm);
794
791/****************** 795/******************
792 * MVM Methods 796 * MVM Methods
793 ******************/ 797 ******************/
@@ -1153,7 +1157,17 @@ int iwl_mvm_sf_update(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
1153 1157
1154/* TDLS */ 1158/* TDLS */
1155int iwl_mvm_tdls_sta_count(struct iwl_mvm *mvm, struct ieee80211_vif *vif); 1159int iwl_mvm_tdls_sta_count(struct iwl_mvm *mvm, struct ieee80211_vif *vif);
1160void iwl_mvm_teardown_tdls_peers(struct iwl_mvm *mvm);
1161void iwl_mvm_recalc_tdls_state(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
1162 bool sta_added);
1163void iwl_mvm_mac_mgd_protect_tdls_discover(struct ieee80211_hw *hw,
1164 struct ieee80211_vif *vif);
1156 1165
1157void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error); 1166void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error);
1167#ifdef CONFIG_IWLWIFI_DEBUGFS
1168void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm);
1169#else
1170static inline void iwl_mvm_fw_error_dump(struct iwl_mvm *mvm) {}
1171#endif
1158 1172
1159#endif /* __IWL_MVM_H__ */ 1173#endif /* __IWL_MVM_H__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/nvm.c b/drivers/net/wireless/iwlwifi/mvm/nvm.c
index 4fafd4bd89f4..af074563e770 100644
--- a/drivers/net/wireless/iwlwifi/mvm/nvm.c
+++ b/drivers/net/wireless/iwlwifi/mvm/nvm.c
@@ -64,6 +64,7 @@
64 *****************************************************************************/ 64 *****************************************************************************/
65#include <linux/firmware.h> 65#include <linux/firmware.h>
66#include "iwl-trans.h" 66#include "iwl-trans.h"
67#include "iwl-csr.h"
67#include "mvm.h" 68#include "mvm.h"
68#include "iwl-eeprom-parse.h" 69#include "iwl-eeprom-parse.h"
69#include "iwl-eeprom-read.h" 70#include "iwl-eeprom-read.h"
@@ -349,7 +350,7 @@ static int iwl_mvm_read_external_nvm(struct iwl_mvm *mvm)
349 /* Maximal size depends on HW family and step */ 350 /* Maximal size depends on HW family and step */
350 if (mvm->trans->cfg->device_family != IWL_DEVICE_FAMILY_8000) 351 if (mvm->trans->cfg->device_family != IWL_DEVICE_FAMILY_8000)
351 max_section_size = IWL_MAX_NVM_SECTION_SIZE; 352 max_section_size = IWL_MAX_NVM_SECTION_SIZE;
352 else if ((mvm->trans->hw_rev & 0xc) == 0) /* Family 8000 A-step */ 353 else if (CSR_HW_REV_STEP(mvm->trans->hw_rev) == SILICON_A_STEP)
353 max_section_size = IWL_MAX_NVM_8000A_SECTION_SIZE; 354 max_section_size = IWL_MAX_NVM_8000A_SECTION_SIZE;
354 else /* Family 8000 B-step */ 355 else /* Family 8000 B-step */
355 max_section_size = IWL_MAX_NVM_8000B_SECTION_SIZE; 356 max_section_size = IWL_MAX_NVM_8000B_SECTION_SIZE;
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index 87f278cc9b2c..f887779717d5 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -332,6 +332,8 @@ static const char *const iwl_mvm_cmd_strings[REPLY_MAX] = {
332 CMD(BCAST_FILTER_CMD), 332 CMD(BCAST_FILTER_CMD),
333 CMD(REPLY_SF_CFG_CMD), 333 CMD(REPLY_SF_CFG_CMD),
334 CMD(REPLY_BEACON_FILTERING_CMD), 334 CMD(REPLY_BEACON_FILTERING_CMD),
335 CMD(CMD_DTS_MEASUREMENT_TRIGGER),
336 CMD(DTS_MEASUREMENT_NOTIFICATION),
335 CMD(REPLY_THERMAL_MNG_BACKOFF), 337 CMD(REPLY_THERMAL_MNG_BACKOFF),
336 CMD(MAC_PM_POWER_TABLE), 338 CMD(MAC_PM_POWER_TABLE),
337 CMD(BT_COEX_CI), 339 CMD(BT_COEX_CI),
@@ -364,6 +366,8 @@ static u32 calc_min_backoff(struct iwl_trans *trans, const struct iwl_cfg *cfg)
364 return 0; 366 return 0;
365} 367}
366 368
369static void iwl_mvm_fw_error_dump_wk(struct work_struct *work);
370
367static struct iwl_op_mode * 371static struct iwl_op_mode *
368iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg, 372iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
369 const struct iwl_fw *fw, struct dentry *dbgfs_dir) 373 const struct iwl_fw *fw, struct dentry *dbgfs_dir)
@@ -431,6 +435,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
431 INIT_WORK(&mvm->roc_done_wk, iwl_mvm_roc_done_wk); 435 INIT_WORK(&mvm->roc_done_wk, iwl_mvm_roc_done_wk);
432 INIT_WORK(&mvm->sta_drained_wk, iwl_mvm_sta_drained_wk); 436 INIT_WORK(&mvm->sta_drained_wk, iwl_mvm_sta_drained_wk);
433 INIT_WORK(&mvm->d0i3_exit_work, iwl_mvm_d0i3_exit_work); 437 INIT_WORK(&mvm->d0i3_exit_work, iwl_mvm_d0i3_exit_work);
438 INIT_WORK(&mvm->fw_error_dump_wk, iwl_mvm_fw_error_dump_wk);
434 439
435 spin_lock_init(&mvm->d0i3_tx_lock); 440 spin_lock_init(&mvm->d0i3_tx_lock);
436 spin_lock_init(&mvm->refs_lock); 441 spin_lock_init(&mvm->refs_lock);
@@ -460,6 +465,7 @@ iwl_op_mode_mvm_start(struct iwl_trans *trans, const struct iwl_cfg *cfg,
460 465
461 trans_cfg.cmd_queue = IWL_MVM_CMD_QUEUE; 466 trans_cfg.cmd_queue = IWL_MVM_CMD_QUEUE;
462 trans_cfg.cmd_fifo = IWL_MVM_TX_FIFO_CMD; 467 trans_cfg.cmd_fifo = IWL_MVM_TX_FIFO_CMD;
468 trans_cfg.scd_set_active = true;
463 469
464 snprintf(mvm->hw->wiphy->fw_version, 470 snprintf(mvm->hw->wiphy->fw_version,
465 sizeof(mvm->hw->wiphy->fw_version), 471 sizeof(mvm->hw->wiphy->fw_version),
@@ -781,6 +787,16 @@ static void iwl_mvm_reprobe_wk(struct work_struct *wk)
781 module_put(THIS_MODULE); 787 module_put(THIS_MODULE);
782} 788}
783 789
790static void iwl_mvm_fw_error_dump_wk(struct work_struct *work)
791{
792 struct iwl_mvm *mvm =
793 container_of(work, struct iwl_mvm, fw_error_dump_wk);
794
795 mutex_lock(&mvm->mutex);
796 iwl_mvm_fw_error_dump(mvm);
797 mutex_unlock(&mvm->mutex);
798}
799
784void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error) 800void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error)
785{ 801{
786 iwl_abort_notification_waits(&mvm->notif_wait); 802 iwl_abort_notification_waits(&mvm->notif_wait);
@@ -846,6 +862,8 @@ void iwl_mvm_nic_restart(struct iwl_mvm *mvm, bool fw_error)
846 if (fw_error && mvm->restart_fw > 0) 862 if (fw_error && mvm->restart_fw > 0)
847 mvm->restart_fw--; 863 mvm->restart_fw--;
848 ieee80211_restart_hw(mvm->hw); 864 ieee80211_restart_hw(mvm->hw);
865 } else if (fw_error) {
866 schedule_work(&mvm->fw_error_dump_wk);
849 } 867 }
850} 868}
851 869
diff --git a/drivers/net/wireless/iwlwifi/mvm/power.c b/drivers/net/wireless/iwlwifi/mvm/power.c
index 5a29c193b72a..5b85b0cc7a2a 100644
--- a/drivers/net/wireless/iwlwifi/mvm/power.c
+++ b/drivers/net/wireless/iwlwifi/mvm/power.c
@@ -286,12 +286,28 @@ static bool iwl_mvm_power_allow_uapsd(struct iwl_mvm *mvm,
286 return true; 286 return true;
287} 287}
288 288
289static bool iwl_mvm_power_is_radar(struct ieee80211_vif *vif)
290{
291 struct ieee80211_chanctx_conf *chanctx_conf;
292 struct ieee80211_channel *chan;
293 bool radar_detect = false;
294
295 rcu_read_lock();
296 chanctx_conf = rcu_dereference(vif->chanctx_conf);
297 WARN_ON(!chanctx_conf);
298 if (chanctx_conf) {
299 chan = chanctx_conf->def.chan;
300 radar_detect = chan->flags & IEEE80211_CHAN_RADAR;
301 }
302 rcu_read_unlock();
303
304 return radar_detect;
305}
306
289static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm, 307static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
290 struct ieee80211_vif *vif, 308 struct ieee80211_vif *vif,
291 struct iwl_mac_power_cmd *cmd) 309 struct iwl_mac_power_cmd *cmd)
292{ 310{
293 struct ieee80211_chanctx_conf *chanctx_conf;
294 struct ieee80211_channel *chan;
295 int dtimper, dtimper_msec; 311 int dtimper, dtimper_msec;
296 int keep_alive; 312 int keep_alive;
297 bool radar_detect = false; 313 bool radar_detect = false;
@@ -320,7 +336,7 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
320 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK); 336 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_SAVE_ENA_MSK);
321 337
322 if (!vif->bss_conf.ps || iwl_mvm_vif_low_latency(mvmvif) || 338 if (!vif->bss_conf.ps || iwl_mvm_vif_low_latency(mvmvif) ||
323 !mvmvif->pm_enabled) 339 !mvmvif->pm_enabled || iwl_mvm_tdls_sta_count(mvm, vif))
324 return; 340 return;
325 341
326 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK); 342 cmd->flags |= cpu_to_le16(POWER_FLAGS_POWER_MANAGEMENT_ENA_MSK);
@@ -333,14 +349,7 @@ static void iwl_mvm_power_build_cmd(struct iwl_mvm *mvm,
333 } 349 }
334 350
335 /* Check if radar detection is required on current channel */ 351 /* Check if radar detection is required on current channel */
336 rcu_read_lock(); 352 radar_detect = iwl_mvm_power_is_radar(vif);
337 chanctx_conf = rcu_dereference(vif->chanctx_conf);
338 WARN_ON(!chanctx_conf);
339 if (chanctx_conf) {
340 chan = chanctx_conf->def.chan;
341 radar_detect = chan->flags & IEEE80211_CHAN_RADAR;
342 }
343 rcu_read_unlock();
344 353
345 /* Check skip over DTIM conditions */ 354 /* Check skip over DTIM conditions */
346 if (!radar_detect && (dtimper <= 10) && 355 if (!radar_detect && (dtimper <= 10) &&
@@ -501,8 +510,6 @@ struct iwl_power_vifs {
501 bool bss_active; 510 bool bss_active;
502 bool ap_active; 511 bool ap_active;
503 bool monitor_active; 512 bool monitor_active;
504 bool bss_tdls;
505 bool p2p_tdls;
506}; 513};
507 514
508static void iwl_mvm_power_disable_pm_iterator(void *_data, u8* mac, 515static void iwl_mvm_power_disable_pm_iterator(void *_data, u8* mac,
@@ -557,8 +564,6 @@ static void iwl_mvm_power_get_vifs_iterator(void *_data, u8 *mac,
557 /* only a single MAC of the same type */ 564 /* only a single MAC of the same type */
558 WARN_ON(power_iterator->p2p_vif); 565 WARN_ON(power_iterator->p2p_vif);
559 power_iterator->p2p_vif = vif; 566 power_iterator->p2p_vif = vif;
560 power_iterator->p2p_tdls =
561 !!iwl_mvm_tdls_sta_count(power_iterator->mvm, vif);
562 if (mvmvif->phy_ctxt) 567 if (mvmvif->phy_ctxt)
563 if (mvmvif->phy_ctxt->id < MAX_PHYS) 568 if (mvmvif->phy_ctxt->id < MAX_PHYS)
564 power_iterator->p2p_active = true; 569 power_iterator->p2p_active = true;
@@ -568,8 +573,6 @@ static void iwl_mvm_power_get_vifs_iterator(void *_data, u8 *mac,
568 /* only a single MAC of the same type */ 573 /* only a single MAC of the same type */
569 WARN_ON(power_iterator->bss_vif); 574 WARN_ON(power_iterator->bss_vif);
570 power_iterator->bss_vif = vif; 575 power_iterator->bss_vif = vif;
571 power_iterator->bss_tdls =
572 !!iwl_mvm_tdls_sta_count(power_iterator->mvm, vif);
573 if (mvmvif->phy_ctxt) 576 if (mvmvif->phy_ctxt)
574 if (mvmvif->phy_ctxt->id < MAX_PHYS) 577 if (mvmvif->phy_ctxt->id < MAX_PHYS)
575 power_iterator->bss_active = true; 578 power_iterator->bss_active = true;
@@ -612,15 +615,13 @@ static void iwl_mvm_power_set_pm(struct iwl_mvm *mvm,
612 ap_mvmvif = iwl_mvm_vif_from_mac80211(vifs->ap_vif); 615 ap_mvmvif = iwl_mvm_vif_from_mac80211(vifs->ap_vif);
613 616
614 /* enable PM on bss if bss stand alone */ 617 /* enable PM on bss if bss stand alone */
615 if (vifs->bss_active && !vifs->p2p_active && !vifs->ap_active && 618 if (vifs->bss_active && !vifs->p2p_active && !vifs->ap_active) {
616 !vifs->bss_tdls) {
617 bss_mvmvif->pm_enabled = true; 619 bss_mvmvif->pm_enabled = true;
618 return; 620 return;
619 } 621 }
620 622
621 /* enable PM on p2p if p2p stand alone */ 623 /* enable PM on p2p if p2p stand alone */
622 if (vifs->p2p_active && !vifs->bss_active && !vifs->ap_active && 624 if (vifs->p2p_active && !vifs->bss_active && !vifs->ap_active) {
623 !vifs->p2p_tdls) {
624 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_P2P_PM) 625 if (mvm->fw->ucode_capa.flags & IWL_UCODE_TLV_FLAGS_P2P_PM)
625 p2p_mvmvif->pm_enabled = true; 626 p2p_mvmvif->pm_enabled = true;
626 return; 627 return;
@@ -961,17 +962,22 @@ int iwl_mvm_update_d0i3_power_mode(struct iwl_mvm *mvm,
961 962
962 iwl_mvm_power_build_cmd(mvm, vif, &cmd); 963 iwl_mvm_power_build_cmd(mvm, vif, &cmd);
963 if (enable) { 964 if (enable) {
964 /* configure skip over dtim up to 300 msec */ 965 /* configure skip over dtim up to 306TU - 314 msec */
965 int dtimper = vif->bss_conf.dtim_period ?: 1; 966 int dtimper = vif->bss_conf.dtim_period ?: 1;
966 int dtimper_msec = dtimper * vif->bss_conf.beacon_int; 967 int dtimper_tu = dtimper * vif->bss_conf.beacon_int;
968 bool radar_detect = iwl_mvm_power_is_radar(vif);
967 969
968 if (WARN_ON(!dtimper_msec)) 970 if (WARN_ON(!dtimper_tu))
969 return 0; 971 return 0;
970 972
971 cmd.skip_dtim_periods = 300 / dtimper_msec; 973 /* Check skip over DTIM conditions */
972 if (cmd.skip_dtim_periods) 974 /* TODO: check that multicast wake lock is off */
973 cmd.flags |= 975 if (!radar_detect && (dtimper < 10)) {
974 cpu_to_le16(POWER_FLAGS_SKIP_OVER_DTIM_MSK); 976 cmd.skip_dtim_periods = 306 / dtimper_tu;
977 if (cmd.skip_dtim_periods)
978 cmd.flags |= cpu_to_le16(
979 POWER_FLAGS_SKIP_OVER_DTIM_MSK);
980 }
975 } 981 }
976 iwl_mvm_power_log(mvm, &cmd); 982 iwl_mvm_power_log(mvm, &cmd);
977#ifdef CONFIG_IWLWIFI_DEBUGFS 983#ifdef CONFIG_IWLWIFI_DEBUGFS
diff --git a/drivers/net/wireless/iwlwifi/mvm/quota.c b/drivers/net/wireless/iwlwifi/mvm/quota.c
index 5fd502db03d1..dbb2594390e9 100644
--- a/drivers/net/wireless/iwlwifi/mvm/quota.c
+++ b/drivers/net/wireless/iwlwifi/mvm/quota.c
@@ -175,12 +175,14 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm,
175 struct ieee80211_vif *disabled_vif) 175 struct ieee80211_vif *disabled_vif)
176{ 176{
177 struct iwl_time_quota_cmd cmd = {}; 177 struct iwl_time_quota_cmd cmd = {};
178 int i, idx, ret, num_active_macs, quota, quota_rem, n_non_lowlat; 178 int i, idx, err, num_active_macs, quota, quota_rem, n_non_lowlat;
179 struct iwl_mvm_quota_iterator_data data = { 179 struct iwl_mvm_quota_iterator_data data = {
180 .n_interfaces = {}, 180 .n_interfaces = {},
181 .colors = { -1, -1, -1, -1 }, 181 .colors = { -1, -1, -1, -1 },
182 .disabled_vif = disabled_vif, 182 .disabled_vif = disabled_vif,
183 }; 183 };
184 struct iwl_time_quota_cmd *last = &mvm->last_quota_cmd;
185 bool send = false;
184 186
185 lockdep_assert_held(&mvm->mutex); 187 lockdep_assert_held(&mvm->mutex);
186 188
@@ -293,15 +295,33 @@ int iwl_mvm_update_quotas(struct iwl_mvm *mvm,
293 295
294 /* check that we have non-zero quota for all valid bindings */ 296 /* check that we have non-zero quota for all valid bindings */
295 for (i = 0; i < MAX_BINDINGS; i++) { 297 for (i = 0; i < MAX_BINDINGS; i++) {
298 if (cmd.quotas[i].id_and_color != last->quotas[i].id_and_color)
299 send = true;
300 if (cmd.quotas[i].max_duration != last->quotas[i].max_duration)
301 send = true;
302 if (abs((int)le32_to_cpu(cmd.quotas[i].quota) -
303 (int)le32_to_cpu(last->quotas[i].quota))
304 > IWL_MVM_QUOTA_THRESHOLD)
305 send = true;
296 if (cmd.quotas[i].id_and_color == cpu_to_le32(FW_CTXT_INVALID)) 306 if (cmd.quotas[i].id_and_color == cpu_to_le32(FW_CTXT_INVALID))
297 continue; 307 continue;
298 WARN_ONCE(cmd.quotas[i].quota == 0, 308 WARN_ONCE(cmd.quotas[i].quota == 0,
299 "zero quota on binding %d\n", i); 309 "zero quota on binding %d\n", i);
300 } 310 }
301 311
302 ret = iwl_mvm_send_cmd_pdu(mvm, TIME_QUOTA_CMD, 0, 312 if (!send) {
303 sizeof(cmd), &cmd); 313 /* don't send a practically unchanged command, the firmware has
304 if (ret) 314 * to re-initialize a lot of state and that can have an adverse
305 IWL_ERR(mvm, "Failed to send quota: %d\n", ret); 315 * impact on it
306 return ret; 316 */
317 return 0;
318 }
319
320 err = iwl_mvm_send_cmd_pdu(mvm, TIME_QUOTA_CMD, 0, sizeof(cmd), &cmd);
321
322 if (err)
323 IWL_ERR(mvm, "Failed to send quota: %d\n", err);
324 else
325 mvm->last_quota_cmd = cmd;
326 return err;
307} 327}
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.c b/drivers/net/wireless/iwlwifi/mvm/rs.c
index 17002cf437db..f77dfe4df074 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.c
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.c
@@ -505,10 +505,10 @@ static const char *rs_pretty_lq_type(enum iwl_table_type type)
505static inline void rs_dump_rate(struct iwl_mvm *mvm, const struct rs_rate *rate, 505static inline void rs_dump_rate(struct iwl_mvm *mvm, const struct rs_rate *rate,
506 const char *prefix) 506 const char *prefix)
507{ 507{
508 IWL_DEBUG_RATE(mvm, "%s: (%s: %d) ANT: %s BW: %d SGI: %d\n", 508 IWL_DEBUG_RATE(mvm, "%s: (%s: %d) ANT: %s BW: %d SGI: %d LDPC: %d\n",
509 prefix, rs_pretty_lq_type(rate->type), 509 prefix, rs_pretty_lq_type(rate->type),
510 rate->index, rs_pretty_ant(rate->ant), 510 rate->index, rs_pretty_ant(rate->ant),
511 rate->bw, rate->sgi); 511 rate->bw, rate->sgi, rate->ldpc);
512} 512}
513 513
514static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window) 514static void rs_rate_scale_clear_window(struct iwl_rate_scale_data *window)
@@ -672,8 +672,10 @@ static int rs_collect_tx_data(struct iwl_lq_sta *lq_sta,
672 return -EINVAL; 672 return -EINVAL;
673 673
674 if (tbl->column != RS_COLUMN_INVALID) { 674 if (tbl->column != RS_COLUMN_INVALID) {
675 lq_sta->tx_stats[tbl->column][scale_index].total += attempts; 675 struct lq_sta_pers *pers = &lq_sta->pers;
676 lq_sta->tx_stats[tbl->column][scale_index].success += successes; 676
677 pers->tx_stats[tbl->column][scale_index].total += attempts;
678 pers->tx_stats[tbl->column][scale_index].success += successes;
677 } 679 }
678 680
679 /* Select window for current tx bit rate */ 681 /* Select window for current tx bit rate */
@@ -742,6 +744,8 @@ static u32 ucode_rate_from_rs_rate(struct iwl_mvm *mvm,
742 ucode_rate |= rate->bw; 744 ucode_rate |= rate->bw;
743 if (rate->sgi) 745 if (rate->sgi)
744 ucode_rate |= RATE_MCS_SGI_MSK; 746 ucode_rate |= RATE_MCS_SGI_MSK;
747 if (rate->ldpc)
748 ucode_rate |= RATE_MCS_LDPC_MSK;
745 749
746 return ucode_rate; 750 return ucode_rate;
747} 751}
@@ -779,6 +783,8 @@ static int rs_rate_from_ucode_rate(const u32 ucode_rate,
779 /* HT or VHT */ 783 /* HT or VHT */
780 if (ucode_rate & RATE_MCS_SGI_MSK) 784 if (ucode_rate & RATE_MCS_SGI_MSK)
781 rate->sgi = true; 785 rate->sgi = true;
786 if (ucode_rate & RATE_MCS_LDPC_MSK)
787 rate->ldpc = true;
782 788
783 rate->bw = ucode_rate & RATE_MCS_CHAN_WIDTH_MSK; 789 rate->bw = ucode_rate & RATE_MCS_CHAN_WIDTH_MSK;
784 790
@@ -965,13 +971,13 @@ static void rs_get_lower_rate_down_column(struct iwl_lq_sta *lq_sta,
965 rate->index > IWL_RATE_MCS_9_INDEX); 971 rate->index > IWL_RATE_MCS_9_INDEX);
966 972
967 rate->index = rs_ht_to_legacy[rate->index]; 973 rate->index = rs_ht_to_legacy[rate->index];
974 rate->ldpc = false;
968 } else { 975 } else {
969 /* Downgrade to SISO with same MCS if in MIMO */ 976 /* Downgrade to SISO with same MCS if in MIMO */
970 rate->type = is_vht_mimo2(rate) ? 977 rate->type = is_vht_mimo2(rate) ?
971 LQ_VHT_SISO : LQ_HT_SISO; 978 LQ_VHT_SISO : LQ_HT_SISO;
972 } 979 }
973 980
974
975 if (num_of_ant(rate->ant) > 1) 981 if (num_of_ant(rate->ant) > 1)
976 rate->ant = first_antenna(mvm->fw->valid_tx_ant); 982 rate->ant = first_antenna(mvm->fw->valid_tx_ant);
977 983
@@ -1621,6 +1627,7 @@ static int rs_switch_to_column(struct iwl_mvm *mvm,
1621 } 1627 }
1622 1628
1623 rate->bw = rs_bw_from_sta_bw(sta); 1629 rate->bw = rs_bw_from_sta_bw(sta);
1630 rate->ldpc = lq_sta->ldpc;
1624 search_tbl->column = col_id; 1631 search_tbl->column = col_id;
1625 rs_set_expected_tpt_table(lq_sta, search_tbl); 1632 rs_set_expected_tpt_table(lq_sta, search_tbl);
1626 1633
@@ -2031,18 +2038,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
2031 return; 2038 return;
2032 } 2039 }
2033 2040
2034 /* force user max rate if set by user */ 2041 /* TODO: handle rate_idx_mask and rate_idx_mcs_mask */
2035 if ((lq_sta->max_rate_idx != -1) &&
2036 (lq_sta->max_rate_idx < index)) {
2037 index = lq_sta->max_rate_idx;
2038 update_lq = 1;
2039 window = &(tbl->win[index]);
2040 IWL_DEBUG_RATE(mvm,
2041 "Forcing user max rate %d\n",
2042 index);
2043 goto lq_update;
2044 }
2045
2046 window = &(tbl->win[index]); 2042 window = &(tbl->win[index]);
2047 2043
2048 /* 2044 /*
@@ -2130,10 +2126,7 @@ static void rs_rate_scale_perform(struct iwl_mvm *mvm,
2130 low = high_low & 0xff; 2126 low = high_low & 0xff;
2131 high = (high_low >> 8) & 0xff; 2127 high = (high_low >> 8) & 0xff;
2132 2128
2133 /* If user set max rate, dont allow higher than user constrain */ 2129 /* TODO: handle rate_idx_mask and rate_idx_mcs_mask */
2134 if ((lq_sta->max_rate_idx != -1) &&
2135 (lq_sta->max_rate_idx < high))
2136 high = IWL_RATE_INVALID;
2137 2130
2138 sr = window->success_ratio; 2131 sr = window->success_ratio;
2139 2132
@@ -2342,6 +2335,7 @@ static void rs_initialize_lq(struct iwl_mvm *mvm,
2342 rate->index = i; 2335 rate->index = i;
2343 rate->ant = first_antenna(valid_tx_ant); 2336 rate->ant = first_antenna(valid_tx_ant);
2344 rate->sgi = false; 2337 rate->sgi = false;
2338 rate->ldpc = false;
2345 rate->bw = RATE_MCS_CHAN_WIDTH_20; 2339 rate->bw = RATE_MCS_CHAN_WIDTH_20;
2346 if (band == IEEE80211_BAND_5GHZ) 2340 if (band == IEEE80211_BAND_5GHZ)
2347 rate->type = LQ_LEGACY_A; 2341 rate->type = LQ_LEGACY_A;
@@ -2364,23 +2358,13 @@ static void rs_get_rate(void *mvm_r, struct ieee80211_sta *sta, void *mvm_sta,
2364 struct ieee80211_tx_rate_control *txrc) 2358 struct ieee80211_tx_rate_control *txrc)
2365{ 2359{
2366 struct sk_buff *skb = txrc->skb; 2360 struct sk_buff *skb = txrc->skb;
2367 struct ieee80211_supported_band *sband = txrc->sband;
2368 struct iwl_op_mode *op_mode __maybe_unused = 2361 struct iwl_op_mode *op_mode __maybe_unused =
2369 (struct iwl_op_mode *)mvm_r; 2362 (struct iwl_op_mode *)mvm_r;
2370 struct iwl_mvm *mvm __maybe_unused = IWL_OP_MODE_GET_MVM(op_mode); 2363 struct iwl_mvm *mvm __maybe_unused = IWL_OP_MODE_GET_MVM(op_mode);
2371 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb); 2364 struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
2372 struct iwl_lq_sta *lq_sta = mvm_sta; 2365 struct iwl_lq_sta *lq_sta = mvm_sta;
2373 2366
2374 /* Get max rate if user set max rate */ 2367 /* TODO: handle rate_idx_mask and rate_idx_mcs_mask */
2375 if (lq_sta) {
2376 lq_sta->max_rate_idx = txrc->max_rate_idx;
2377 if ((sband->band == IEEE80211_BAND_5GHZ) &&
2378 (lq_sta->max_rate_idx != -1))
2379 lq_sta->max_rate_idx += IWL_FIRST_OFDM_RATE;
2380 if ((lq_sta->max_rate_idx < 0) ||
2381 (lq_sta->max_rate_idx >= IWL_RATE_COUNT))
2382 lq_sta->max_rate_idx = -1;
2383 }
2384 2368
2385 /* Treat uninitialized rate scaling data same as non-existing. */ 2369 /* Treat uninitialized rate scaling data same as non-existing. */
2386 if (lq_sta && !lq_sta->pers.drv) { 2370 if (lq_sta && !lq_sta->pers.drv) {
@@ -2581,7 +2565,6 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2581 * previous packets? Need to have IEEE 802.1X auth succeed immediately 2565 * previous packets? Need to have IEEE 802.1X auth succeed immediately
2582 * after assoc.. */ 2566 * after assoc.. */
2583 2567
2584 lq_sta->max_rate_idx = -1;
2585 lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX; 2568 lq_sta->missed_rate_counter = IWL_MISSED_RATE_MAX;
2586 lq_sta->band = sband->band; 2569 lq_sta->band = sband->band;
2587 /* 2570 /*
@@ -2610,9 +2593,16 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2610 lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE; 2593 lq_sta->active_mimo2_rate <<= IWL_FIRST_OFDM_RATE;
2611 2594
2612 lq_sta->is_vht = false; 2595 lq_sta->is_vht = false;
2596 if (mvm->cfg->ht_params->ldpc &&
2597 (ht_cap->cap & IEEE80211_HT_CAP_LDPC_CODING))
2598 lq_sta->ldpc = true;
2613 } else { 2599 } else {
2614 rs_vht_set_enabled_rates(sta, vht_cap, lq_sta); 2600 rs_vht_set_enabled_rates(sta, vht_cap, lq_sta);
2615 lq_sta->is_vht = true; 2601 lq_sta->is_vht = true;
2602
2603 if (mvm->cfg->ht_params->ldpc &&
2604 (vht_cap->cap & IEEE80211_VHT_CAP_RXLDPC))
2605 lq_sta->ldpc = true;
2616 } 2606 }
2617 2607
2618 lq_sta->max_legacy_rate_idx = find_last_bit(&lq_sta->active_legacy_rate, 2608 lq_sta->max_legacy_rate_idx = find_last_bit(&lq_sta->active_legacy_rate,
@@ -2622,11 +2612,12 @@ void iwl_mvm_rs_rate_init(struct iwl_mvm *mvm, struct ieee80211_sta *sta,
2622 lq_sta->max_mimo2_rate_idx = find_last_bit(&lq_sta->active_mimo2_rate, 2612 lq_sta->max_mimo2_rate_idx = find_last_bit(&lq_sta->active_mimo2_rate,
2623 BITS_PER_LONG); 2613 BITS_PER_LONG);
2624 2614
2625 IWL_DEBUG_RATE(mvm, "RATE MASK: LEGACY=%lX SISO=%lX MIMO2=%lX VHT=%d\n", 2615 IWL_DEBUG_RATE(mvm,
2616 "RATE MASK: LEGACY=%lX SISO=%lX MIMO2=%lX VHT=%d LDPC=%d\n",
2626 lq_sta->active_legacy_rate, 2617 lq_sta->active_legacy_rate,
2627 lq_sta->active_siso_rate, 2618 lq_sta->active_siso_rate,
2628 lq_sta->active_mimo2_rate, 2619 lq_sta->active_mimo2_rate,
2629 lq_sta->is_vht); 2620 lq_sta->is_vht, lq_sta->ldpc);
2630 IWL_DEBUG_RATE(mvm, "MAX RATE: LEGACY=%d SISO=%d MIMO2=%d\n", 2621 IWL_DEBUG_RATE(mvm, "MAX RATE: LEGACY=%d SISO=%d MIMO2=%d\n",
2631 lq_sta->max_legacy_rate_idx, 2622 lq_sta->max_legacy_rate_idx,
2632 lq_sta->max_siso_rate_idx, 2623 lq_sta->max_siso_rate_idx,
@@ -3032,8 +3023,9 @@ static ssize_t rs_sta_dbgfs_scale_table_read(struct file *file,
3032 (is_ht20(rate)) ? "20MHz" : 3023 (is_ht20(rate)) ? "20MHz" :
3033 (is_ht40(rate)) ? "40MHz" : 3024 (is_ht40(rate)) ? "40MHz" :
3034 (is_ht80(rate)) ? "80Mhz" : "BAD BW"); 3025 (is_ht80(rate)) ? "80Mhz" : "BAD BW");
3035 desc += sprintf(buff+desc, " %s %s\n", 3026 desc += sprintf(buff+desc, " %s %s %s\n",
3036 (rate->sgi) ? "SGI" : "NGI", 3027 (rate->sgi) ? "SGI" : "NGI",
3028 (rate->ldpc) ? "LDPC" : "BCC",
3037 (lq_sta->is_agg) ? "AGG on" : ""); 3029 (lq_sta->is_agg) ? "AGG on" : "");
3038 } 3030 }
3039 desc += sprintf(buff+desc, "last tx rate=0x%X\n", 3031 desc += sprintf(buff+desc, "last tx rate=0x%X\n",
@@ -3181,7 +3173,7 @@ static ssize_t rs_sta_dbgfs_drv_tx_stats_read(struct file *file,
3181 "%s,", column_name[col]); 3173 "%s,", column_name[col]);
3182 3174
3183 for (rate = 0; rate < IWL_RATE_COUNT; rate++) { 3175 for (rate = 0; rate < IWL_RATE_COUNT; rate++) {
3184 stats = &(lq_sta->tx_stats[col][rate]); 3176 stats = &(lq_sta->pers.tx_stats[col][rate]);
3185 pos += scnprintf(pos, endpos - pos, 3177 pos += scnprintf(pos, endpos - pos,
3186 "%llu/%llu,", 3178 "%llu/%llu,",
3187 stats->success, 3179 stats->success,
@@ -3200,7 +3192,7 @@ static ssize_t rs_sta_dbgfs_drv_tx_stats_write(struct file *file,
3200 size_t count, loff_t *ppos) 3192 size_t count, loff_t *ppos)
3201{ 3193{
3202 struct iwl_lq_sta *lq_sta = file->private_data; 3194 struct iwl_lq_sta *lq_sta = file->private_data;
3203 memset(lq_sta->tx_stats, 0, sizeof(lq_sta->tx_stats)); 3195 memset(lq_sta->pers.tx_stats, 0, sizeof(lq_sta->pers.tx_stats));
3204 3196
3205 return count; 3197 return count;
3206} 3198}
diff --git a/drivers/net/wireless/iwlwifi/mvm/rs.h b/drivers/net/wireless/iwlwifi/mvm/rs.h
index f27b9d687a25..95c4b960fd71 100644
--- a/drivers/net/wireless/iwlwifi/mvm/rs.h
+++ b/drivers/net/wireless/iwlwifi/mvm/rs.h
@@ -207,6 +207,7 @@ struct rs_rate {
207 u8 ant; 207 u8 ant;
208 u32 bw; 208 u32 bw;
209 bool sgi; 209 bool sgi;
210 bool ldpc;
210}; 211};
211 212
212 213
@@ -329,10 +330,9 @@ struct iwl_lq_sta {
329 */ 330 */
330 u64 last_tx; 331 u64 last_tx;
331 bool is_vht; 332 bool is_vht;
333 bool ldpc; /* LDPC Rx is supported by the STA */
332 enum ieee80211_band band; 334 enum ieee80211_band band;
333 335
334 struct rs_rate_stats tx_stats[RS_COLUMN_COUNT][IWL_RATE_COUNT];
335
336 /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */ 336 /* The following are bitmaps of rates; IWL_RATE_6M_MASK, etc. */
337 unsigned long active_legacy_rate; 337 unsigned long active_legacy_rate;
338 unsigned long active_siso_rate; 338 unsigned long active_siso_rate;
@@ -343,7 +343,6 @@ struct iwl_lq_sta {
343 u8 max_siso_rate_idx; 343 u8 max_siso_rate_idx;
344 u8 max_mimo2_rate_idx; 344 u8 max_mimo2_rate_idx;
345 345
346 s8 max_rate_idx; /* Max rate set by user */
347 u8 missed_rate_counter; 346 u8 missed_rate_counter;
348 347
349 struct iwl_lq_cmd lq; 348 struct iwl_lq_cmd lq;
@@ -361,11 +360,14 @@ struct iwl_lq_sta {
361 int tpc_reduce; 360 int tpc_reduce;
362 361
363 /* persistent fields - initialized only once - keep last! */ 362 /* persistent fields - initialized only once - keep last! */
364 struct { 363 struct lq_sta_pers {
365#ifdef CONFIG_MAC80211_DEBUGFS 364#ifdef CONFIG_MAC80211_DEBUGFS
366 u32 dbg_fixed_rate; 365 u32 dbg_fixed_rate;
367 u8 dbg_fixed_txp_reduction; 366 u8 dbg_fixed_txp_reduction;
368#endif 367#endif
368 u8 chains;
369 s8 chain_signal[IEEE80211_MAX_CHAINS];
370 struct rs_rate_stats tx_stats[RS_COLUMN_COUNT][IWL_RATE_COUNT];
369 struct iwl_mvm *drv; 371 struct iwl_mvm *drv;
370 } pers; 372 } pers;
371}; 373};
diff --git a/drivers/net/wireless/iwlwifi/mvm/scan.c b/drivers/net/wireless/iwlwifi/mvm/scan.c
index bf9c63dc4a7d..09545f23b24f 100644
--- a/drivers/net/wireless/iwlwifi/mvm/scan.c
+++ b/drivers/net/wireless/iwlwifi/mvm/scan.c
@@ -160,8 +160,8 @@ static void iwl_mvm_scan_fill_ssids(struct iwl_ssid_ie *cmd_ssid,
160static u16 iwl_mvm_get_active_dwell(enum ieee80211_band band, int n_ssids) 160static u16 iwl_mvm_get_active_dwell(enum ieee80211_band band, int n_ssids)
161{ 161{
162 if (band == IEEE80211_BAND_2GHZ) 162 if (band == IEEE80211_BAND_2GHZ)
163 return 30 + 3 * (n_ssids + 1); 163 return 20 + 3 * (n_ssids + 1);
164 return 20 + 2 * (n_ssids + 1); 164 return 10 + 2 * (n_ssids + 1);
165} 165}
166 166
167static u16 iwl_mvm_get_passive_dwell(enum ieee80211_band band) 167static u16 iwl_mvm_get_passive_dwell(enum ieee80211_band band)
diff --git a/drivers/net/wireless/iwlwifi/mvm/sf.c b/drivers/net/wireless/iwlwifi/mvm/sf.c
index f88410c7cbfb..7eb78e2c240a 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sf.c
+++ b/drivers/net/wireless/iwlwifi/mvm/sf.c
@@ -179,6 +179,10 @@ static int iwl_mvm_sf_config(struct iwl_mvm *mvm, u8 sta_id,
179 struct ieee80211_sta *sta; 179 struct ieee80211_sta *sta;
180 int ret = 0; 180 int ret = 0;
181 181
182 if (mvm->fw->ucode_capa.api[0] & IWL_UCODE_TLV_API_SF_NO_DUMMY_NOTIF &&
183 mvm->cfg->disable_dummy_notification)
184 sf_cmd.state |= cpu_to_le32(SF_CFG_DUMMY_NOTIF_OFF);
185
182 /* 186 /*
183 * If an associated AP sta changed its antenna configuration, the state 187 * If an associated AP sta changed its antenna configuration, the state
184 * will remain FULL_ON but SF parameters need to be reconsidered. 188 * will remain FULL_ON but SF parameters need to be reconsidered.
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c
index dd9f3a4347f6..666f16b4bed9 100644
--- a/drivers/net/wireless/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/iwlwifi/mvm/sta.c
@@ -948,8 +948,16 @@ int iwl_mvm_sta_tx_agg_stop(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
948 } 948 }
949 949
950 tid_data->ssn = 0xffff; 950 tid_data->ssn = 0xffff;
951 tid_data->state = IWL_AGG_OFF;
952 mvm->queue_to_mac80211[txq_id] = IWL_INVALID_MAC80211_QUEUE;
953 spin_unlock_bh(&mvmsta->lock);
954
955 ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
956
957 iwl_mvm_sta_tx_agg(mvm, sta, tid, txq_id, false);
958
951 iwl_trans_txq_disable(mvm->trans, txq_id, true); 959 iwl_trans_txq_disable(mvm->trans, txq_id, true);
952 /* fall through */ 960 return 0;
953 case IWL_AGG_STARTING: 961 case IWL_AGG_STARTING:
954 case IWL_EMPTYING_HW_QUEUE_ADDBA: 962 case IWL_EMPTYING_HW_QUEUE_ADDBA:
955 /* 963 /*
@@ -1003,6 +1011,8 @@ int iwl_mvm_sta_tx_agg_flush(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
1003 if (iwl_mvm_flush_tx_path(mvm, BIT(txq_id), true)) 1011 if (iwl_mvm_flush_tx_path(mvm, BIT(txq_id), true))
1004 IWL_ERR(mvm, "Couldn't flush the AGG queue\n"); 1012 IWL_ERR(mvm, "Couldn't flush the AGG queue\n");
1005 1013
1014 iwl_mvm_sta_tx_agg(mvm, sta, tid, txq_id, false);
1015
1006 iwl_trans_txq_disable(mvm->trans, tid_data->txq_id, true); 1016 iwl_trans_txq_disable(mvm->trans, tid_data->txq_id, true);
1007 } 1017 }
1008 1018
diff --git a/drivers/net/wireless/iwlwifi/mvm/tdls.c b/drivers/net/wireless/iwlwifi/mvm/tdls.c
new file mode 100644
index 000000000000..66c82df2d0a1
--- /dev/null
+++ b/drivers/net/wireless/iwlwifi/mvm/tdls.c
@@ -0,0 +1,149 @@
1/******************************************************************************
2 *
3 * This file is provided under a dual BSD/GPLv2 license. When using or
4 * redistributing this file, you may do so under either license.
5 *
6 * GPL LICENSE SUMMARY
7 *
8 * Copyright(c) 2014 Intel Mobile Communications GmbH
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of version 2 of the GNU General Public License as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
22 * USA
23 *
24 * The full GNU General Public License is included in this distribution
25 * in the file called COPYING.
26 *
27 * Contact Information:
28 * Intel Linux Wireless <ilw@linux.intel.com>
29 * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
30 *
31 * BSD LICENSE
32 *
33 * Copyright(c) 2014 Intel Mobile Communications GmbH
34 * All rights reserved.
35 *
36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions
38 * are met:
39 *
40 * * Redistributions of source code must retain the above copyright
41 * notice, this list of conditions and the following disclaimer.
42 * * Redistributions in binary form must reproduce the above copyright
43 * notice, this list of conditions and the following disclaimer in
44 * the documentation and/or other materials provided with the
45 * distribution.
46 * * Neither the name Intel Corporation nor the names of its
47 * contributors may be used to endorse or promote products derived
48 * from this software without specific prior written permission.
49 *
50 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
51 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
52 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
53 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
54 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
55 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
56 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
57 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
58 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
60 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
61 *
62 *****************************************************************************/
63
64#include "mvm.h"
65#include "time-event.h"
66
67void iwl_mvm_teardown_tdls_peers(struct iwl_mvm *mvm)
68{
69 struct ieee80211_sta *sta;
70 struct iwl_mvm_sta *mvmsta;
71 int i;
72
73 lockdep_assert_held(&mvm->mutex);
74
75 for (i = 0; i < IWL_MVM_STATION_COUNT; i++) {
76 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i],
77 lockdep_is_held(&mvm->mutex));
78 if (!sta || IS_ERR(sta) || !sta->tdls)
79 continue;
80
81 mvmsta = iwl_mvm_sta_from_mac80211(sta);
82 ieee80211_tdls_oper_request(mvmsta->vif, sta->addr,
83 NL80211_TDLS_TEARDOWN,
84 WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED,
85 GFP_KERNEL);
86 }
87}
88
89int iwl_mvm_tdls_sta_count(struct iwl_mvm *mvm, struct ieee80211_vif *vif)
90{
91 struct ieee80211_sta *sta;
92 struct iwl_mvm_sta *mvmsta;
93 int count = 0;
94 int i;
95
96 lockdep_assert_held(&mvm->mutex);
97
98 for (i = 0; i < IWL_MVM_STATION_COUNT; i++) {
99 sta = rcu_dereference_protected(mvm->fw_id_to_mac_id[i],
100 lockdep_is_held(&mvm->mutex));
101 if (!sta || IS_ERR(sta) || !sta->tdls)
102 continue;
103
104 if (vif) {
105 mvmsta = iwl_mvm_sta_from_mac80211(sta);
106 if (mvmsta->vif != vif)
107 continue;
108 }
109
110 count++;
111 }
112
113 return count;
114}
115
116void iwl_mvm_recalc_tdls_state(struct iwl_mvm *mvm, struct ieee80211_vif *vif,
117 bool sta_added)
118{
119 int tdls_sta_cnt = iwl_mvm_tdls_sta_count(mvm, vif);
120
121 /*
122 * Disable ps when the first TDLS sta is added and re-enable it
123 * when the last TDLS sta is removed
124 */
125 if ((tdls_sta_cnt == 1 && sta_added) ||
126 (tdls_sta_cnt == 0 && !sta_added))
127 iwl_mvm_power_update_mac(mvm);
128}
129
130void iwl_mvm_mac_mgd_protect_tdls_discover(struct ieee80211_hw *hw,
131 struct ieee80211_vif *vif)
132{
133 struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw);
134 u32 duration = 2 * vif->bss_conf.dtim_period * vif->bss_conf.beacon_int;
135
136 /*
137 * iwl_mvm_protect_session() reads directly from the device
138 * (the system time), so make sure it is available.
139 */
140 if (iwl_mvm_ref_sync(mvm, IWL_MVM_REF_PROTECT_TDLS))
141 return;
142
143 mutex_lock(&mvm->mutex);
144 /* Protect the session to hear the TDLS setup response on the channel */
145 iwl_mvm_protect_session(mvm, vif, duration, duration, 100, true);
146 mutex_unlock(&mvm->mutex);
147
148 iwl_mvm_unref(mvm, IWL_MVM_REF_PROTECT_TDLS);
149}
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.c b/drivers/net/wireless/iwlwifi/mvm/time-event.c
index 447d3b1003df..b7f9e61d14e2 100644
--- a/drivers/net/wireless/iwlwifi/mvm/time-event.c
+++ b/drivers/net/wireless/iwlwifi/mvm/time-event.c
@@ -700,9 +700,9 @@ void iwl_mvm_stop_p2p_roc(struct iwl_mvm *mvm)
700 iwl_mvm_roc_finished(mvm); 700 iwl_mvm_roc_finished(mvm);
701} 701}
702 702
703int iwl_mvm_schedule_csa_noa(struct iwl_mvm *mvm, 703int iwl_mvm_schedule_csa_period(struct iwl_mvm *mvm,
704 struct ieee80211_vif *vif, 704 struct ieee80211_vif *vif,
705 u32 duration, u32 apply_time) 705 u32 duration, u32 apply_time)
706{ 706{
707 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 707 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
708 struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data; 708 struct iwl_mvm_time_event_data *te_data = &mvmvif->time_event_data;
@@ -711,14 +711,14 @@ int iwl_mvm_schedule_csa_noa(struct iwl_mvm *mvm,
711 lockdep_assert_held(&mvm->mutex); 711 lockdep_assert_held(&mvm->mutex);
712 712
713 if (te_data->running) { 713 if (te_data->running) {
714 IWL_DEBUG_TE(mvm, "CS NOA is already scheduled\n"); 714 IWL_DEBUG_TE(mvm, "CS period is already scheduled\n");
715 return -EBUSY; 715 return -EBUSY;
716 } 716 }
717 717
718 time_cmd.action = cpu_to_le32(FW_CTXT_ACTION_ADD); 718 time_cmd.action = cpu_to_le32(FW_CTXT_ACTION_ADD);
719 time_cmd.id_and_color = 719 time_cmd.id_and_color =
720 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color)); 720 cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, mvmvif->color));
721 time_cmd.id = cpu_to_le32(TE_P2P_GO_CSA_NOA); 721 time_cmd.id = cpu_to_le32(TE_CHANNEL_SWITCH_PERIOD);
722 time_cmd.apply_time = cpu_to_le32(apply_time); 722 time_cmd.apply_time = cpu_to_le32(apply_time);
723 time_cmd.max_frags = TE_V2_FRAG_NONE; 723 time_cmd.max_frags = TE_V2_FRAG_NONE;
724 time_cmd.duration = cpu_to_le32(duration); 724 time_cmd.duration = cpu_to_le32(duration);
diff --git a/drivers/net/wireless/iwlwifi/mvm/time-event.h b/drivers/net/wireless/iwlwifi/mvm/time-event.h
index bee3b2446b35..b350e47e19da 100644
--- a/drivers/net/wireless/iwlwifi/mvm/time-event.h
+++ b/drivers/net/wireless/iwlwifi/mvm/time-event.h
@@ -219,7 +219,7 @@ void iwl_mvm_te_clear_data(struct iwl_mvm *mvm,
219void iwl_mvm_roc_done_wk(struct work_struct *wk); 219void iwl_mvm_roc_done_wk(struct work_struct *wk);
220 220
221/** 221/**
222 * iwl_mvm_schedule_csa_noa - request NoA for channel switch 222 * iwl_mvm_schedule_csa_period - request channel switch absence period
223 * @mvm: the mvm component 223 * @mvm: the mvm component
224 * @vif: the virtual interface for which the channel switch is issued 224 * @vif: the virtual interface for which the channel switch is issued
225 * @duration: the duration of the NoA in TU. 225 * @duration: the duration of the NoA in TU.
@@ -228,9 +228,9 @@ void iwl_mvm_roc_done_wk(struct work_struct *wk);
228 * This function is used to schedule NoA time event and is used to perform 228 * This function is used to schedule NoA time event and is used to perform
229 * the channel switch flow. 229 * the channel switch flow.
230 */ 230 */
231int iwl_mvm_schedule_csa_noa(struct iwl_mvm *mvm, 231int iwl_mvm_schedule_csa_period(struct iwl_mvm *mvm,
232 struct ieee80211_vif *vif, 232 struct ieee80211_vif *vif,
233 u32 duration, u32 apply_time); 233 u32 duration, u32 apply_time);
234 234
235/** 235/**
236 * iwl_mvm_te_scheduled - check if the fw received the TE cmd 236 * iwl_mvm_te_scheduled - check if the fw received the TE cmd
diff --git a/drivers/net/wireless/iwlwifi/mvm/tt.c b/drivers/net/wireless/iwlwifi/mvm/tt.c
index c3e1fe4282f1..c750ca7b8269 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tt.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tt.c
@@ -69,275 +69,99 @@
69#include "iwl-csr.h" 69#include "iwl-csr.h"
70#include "iwl-prph.h" 70#include "iwl-prph.h"
71 71
72#define OTP_DTS_DIODE_DEVIATION 96 /*in words*/ 72#define IWL_MVM_TEMP_NOTIF_WAIT_TIMEOUT HZ
73/* VBG - Voltage Band Gap error data (temperature offset) */
74#define OTP_WP_DTS_VBG (OTP_DTS_DIODE_DEVIATION + 2)
75#define MEAS_VBG_MIN_VAL 2300
76#define MEAS_VBG_MAX_VAL 3000
77#define MEAS_VBG_DEFAULT_VAL 2700
78#define DTS_DIODE_VALID(flags) (flags & DTS_DIODE_REG_FLAGS_PASS_ONCE)
79#define MIN_TEMPERATURE 0
80#define MAX_TEMPERATURE 125
81#define TEMPERATURE_ERROR (MAX_TEMPERATURE + 1)
82#define PTAT_DIGITAL_VALUE_MIN_VALUE 0
83#define PTAT_DIGITAL_VALUE_MAX_VALUE 0xFF
84#define DTS_VREFS_NUM 5
85static inline u32 DTS_DIODE_GET_VREFS_ID(u32 flags)
86{
87 return (flags & DTS_DIODE_REG_FLAGS_VREFS_ID) >>
88 DTS_DIODE_REG_FLAGS_VREFS_ID_POS;
89}
90 73
91#define CALC_VREFS_MIN_DIFF 43 74static void iwl_mvm_enter_ctkill(struct iwl_mvm *mvm)
92#define CALC_VREFS_MAX_DIFF 51
93#define CALC_LUT_SIZE (1 + CALC_VREFS_MAX_DIFF - CALC_VREFS_MIN_DIFF)
94#define CALC_LUT_INDEX_OFFSET CALC_VREFS_MIN_DIFF
95#define CALC_TEMPERATURE_RESULT_SHIFT_OFFSET 23
96
97/*
98 * @digital_value: The diode's digital-value sampled (temperature/voltage)
99 * @vref_low: The lower voltage-reference (the vref just below the diode's
100 * sampled digital-value)
101 * @vref_high: The higher voltage-reference (the vref just above the diode's
102 * sampled digital-value)
103 * @flags: bits[1:0]: The ID of the Vrefs pair (lowVref,highVref)
104 * bits[6:2]: Reserved.
105 * bits[7:7]: Indicates completion of at least 1 successful sample
106 * since last DTS reset.
107 */
108struct iwl_mvm_dts_diode_bits {
109 u8 digital_value;
110 u8 vref_low;
111 u8 vref_high;
112 u8 flags;
113} __packed;
114
115union dts_diode_results {
116 u32 reg_value;
117 struct iwl_mvm_dts_diode_bits bits;
118} __packed;
119
120static s16 iwl_mvm_dts_get_volt_band_gap(struct iwl_mvm *mvm)
121{ 75{
122 struct iwl_nvm_section calib_sec; 76 u32 duration = mvm->thermal_throttle.params->ct_kill_duration;
123 const __le16 *calib;
124 u16 vbg;
125
126 /* TODO: move parsing to NVM code */
127 calib_sec = mvm->nvm_sections[NVM_SECTION_TYPE_CALIBRATION];
128 calib = (__le16 *)calib_sec.data;
129 77
130 vbg = le16_to_cpu(calib[OTP_WP_DTS_VBG]); 78 if (test_bit(IWL_MVM_STATUS_HW_CTKILL, &mvm->status))
79 return;
131 80
132 if (vbg < MEAS_VBG_MIN_VAL || vbg > MEAS_VBG_MAX_VAL) 81 IWL_ERR(mvm, "Enter CT Kill\n");
133 vbg = MEAS_VBG_DEFAULT_VAL; 82 iwl_mvm_set_hw_ctkill_state(mvm, true);
134 83
135 return vbg; 84 /* Don't schedule an exit work if we're in test mode, since
85 * the temperature will not change unless we manually set it
86 * again (or disable testing).
87 */
88 if (!mvm->temperature_test)
89 schedule_delayed_work(&mvm->thermal_throttle.ct_kill_exit,
90 round_jiffies_relative(duration * HZ));
136} 91}
137 92
138static u16 iwl_mvm_dts_get_ptat_deviation_offset(struct iwl_mvm *mvm) 93static void iwl_mvm_exit_ctkill(struct iwl_mvm *mvm)
139{ 94{
140 const u8 *calib; 95 if (!test_bit(IWL_MVM_STATUS_HW_CTKILL, &mvm->status))
141 u8 ptat, pa1, pa2, median; 96 return;
142
143 /* TODO: move parsing to NVM code */
144 calib = mvm->nvm_sections[NVM_SECTION_TYPE_CALIBRATION].data;
145 ptat = calib[OTP_DTS_DIODE_DEVIATION * 2];
146 pa1 = calib[OTP_DTS_DIODE_DEVIATION * 2 + 1];
147 pa2 = calib[OTP_DTS_DIODE_DEVIATION * 2 + 2];
148
149 /* get the median: */
150 if (ptat > pa1) {
151 if (ptat > pa2)
152 median = (pa1 > pa2) ? pa1 : pa2;
153 else
154 median = ptat;
155 } else {
156 if (pa1 > pa2)
157 median = (ptat > pa2) ? ptat : pa2;
158 else
159 median = pa1;
160 }
161 97
162 return ptat - median; 98 IWL_ERR(mvm, "Exit CT Kill\n");
99 iwl_mvm_set_hw_ctkill_state(mvm, false);
163} 100}
164 101
165static u8 iwl_mvm_dts_calibrate_ptat_deviation(struct iwl_mvm *mvm, u8 value) 102static bool iwl_mvm_temp_notif(struct iwl_notif_wait_data *notif_wait,
103 struct iwl_rx_packet *pkt, void *data)
166{ 104{
167 /* Calibrate the PTAT digital value, based on PTAT deviation data: */ 105 struct iwl_mvm *mvm =
168 s16 new_val = value - iwl_mvm_dts_get_ptat_deviation_offset(mvm); 106 container_of(notif_wait, struct iwl_mvm, notif_wait);
107 int *temp = data;
108 struct iwl_dts_measurement_notif *notif;
109 int len = iwl_rx_packet_payload_len(pkt);
110
111 if (WARN_ON_ONCE(len != sizeof(*notif))) {
112 IWL_ERR(mvm, "Invalid DTS_MEASUREMENT_NOTIFICATION\n");
113 return true;
114 }
169 115
170 if (new_val > PTAT_DIGITAL_VALUE_MAX_VALUE) 116 notif = (void *)pkt->data;
171 new_val = PTAT_DIGITAL_VALUE_MAX_VALUE;
172 else if (new_val < PTAT_DIGITAL_VALUE_MIN_VALUE)
173 new_val = PTAT_DIGITAL_VALUE_MIN_VALUE;
174 117
175 return new_val; 118 *temp = le32_to_cpu(notif->temp);
176}
177 119
178static bool dts_get_adjacent_vrefs(struct iwl_mvm *mvm, 120 /* shouldn't be negative, but since it's s32, make sure it isn't */
179 union dts_diode_results *avg_ptat) 121 if (WARN_ON_ONCE(*temp < 0))
180{ 122 *temp = 0;
181 u8 vrefs_results[DTS_VREFS_NUM];
182 u8 low_vref_index = 0, flags;
183 u32 reg;
184
185 reg = iwl_read_prph(mvm->trans, DTSC_VREF_AVG);
186 memcpy(vrefs_results, &reg, sizeof(reg));
187 reg = iwl_read_prph(mvm->trans, DTSC_VREF5_AVG);
188 vrefs_results[4] = reg & 0xff;
189
190 if (avg_ptat->bits.digital_value < vrefs_results[0] ||
191 avg_ptat->bits.digital_value > vrefs_results[4])
192 return false;
193
194 if (avg_ptat->bits.digital_value > vrefs_results[3])
195 low_vref_index = 3;
196 else if (avg_ptat->bits.digital_value > vrefs_results[2])
197 low_vref_index = 2;
198 else if (avg_ptat->bits.digital_value > vrefs_results[1])
199 low_vref_index = 1;
200
201 avg_ptat->bits.vref_low = vrefs_results[low_vref_index];
202 avg_ptat->bits.vref_high = vrefs_results[low_vref_index + 1];
203 flags = avg_ptat->bits.flags;
204 avg_ptat->bits.flags =
205 (flags & ~DTS_DIODE_REG_FLAGS_VREFS_ID) |
206 (low_vref_index & DTS_DIODE_REG_FLAGS_VREFS_ID);
207 return true;
208}
209 123
210/* 124 IWL_DEBUG_TEMP(mvm, "DTS_MEASUREMENT_NOTIFICATION - %d\n", *temp);
211 * return true it the results are valid, and false otherwise. 125 return true;
212 */
213static bool dts_read_ptat_avg_results(struct iwl_mvm *mvm,
214 union dts_diode_results *avg_ptat)
215{
216 u32 reg;
217 u8 tmp;
218
219 /* fill the diode value and pass_once with avg-reg results */
220 reg = iwl_read_prph(mvm->trans, DTSC_PTAT_AVG);
221 reg &= DTS_DIODE_REG_DIG_VAL | DTS_DIODE_REG_PASS_ONCE;
222 avg_ptat->reg_value = reg;
223
224 /* calibrate the PTAT digital value */
225 tmp = avg_ptat->bits.digital_value;
226 tmp = iwl_mvm_dts_calibrate_ptat_deviation(mvm, tmp);
227 avg_ptat->bits.digital_value = tmp;
228
229 /*
230 * fill vrefs fields, based on the avgVrefs results
231 * and the diode value
232 */
233 return dts_get_adjacent_vrefs(mvm, avg_ptat) &&
234 DTS_DIODE_VALID(avg_ptat->bits.flags);
235} 126}
236 127
237static s32 calculate_nic_temperature(union dts_diode_results avg_ptat, 128static int iwl_mvm_get_temp_cmd(struct iwl_mvm *mvm)
238 u16 volt_band_gap)
239{ 129{
240 u32 tmp_result; 130 struct iwl_dts_measurement_cmd cmd = {
241 u8 vrefs_diff; 131 .flags = cpu_to_le32(DTS_TRIGGER_CMD_FLAGS_TEMP),
242 /*
243 * For temperature calculation (at the end, shift right by 23)
244 * LUT[(D2-D1)] = ROUND{ 2^23 / ((D2-D1)*9*10) }
245 * (D2-D1) == 43 44 45 46 47 48 49 50 51
246 */
247 static const u16 calc_lut[CALC_LUT_SIZE] = {
248 2168, 2118, 2071, 2026, 1983, 1942, 1902, 1864, 1828,
249 }; 132 };
250 133
251 /* 134 return iwl_mvm_send_cmd_pdu(mvm, CMD_DTS_MEASUREMENT_TRIGGER, 0,
252 * The diff between the high and low voltage-references is assumed 135 sizeof(cmd), &cmd);
253 * to be strictly be in range of [60,68]
254 */
255 vrefs_diff = avg_ptat.bits.vref_high - avg_ptat.bits.vref_low;
256
257 if (vrefs_diff < CALC_VREFS_MIN_DIFF ||
258 vrefs_diff > CALC_VREFS_MAX_DIFF)
259 return TEMPERATURE_ERROR;
260
261 /* calculate the result: */
262 tmp_result =
263 vrefs_diff * (DTS_DIODE_GET_VREFS_ID(avg_ptat.bits.flags) + 9);
264 tmp_result += avg_ptat.bits.digital_value;
265 tmp_result -= avg_ptat.bits.vref_high;
266
267 /* multiply by the LUT value (based on the diff) */
268 tmp_result *= calc_lut[vrefs_diff - CALC_LUT_INDEX_OFFSET];
269
270 /*
271 * Get the BandGap (the voltage refereces source) error data
272 * (temperature offset)
273 */
274 tmp_result *= volt_band_gap;
275
276 /*
277 * here, tmp_result value can be up to 32-bits. We want to right-shift
278 * it *without* sign-extend.
279 */
280 tmp_result = tmp_result >> CALC_TEMPERATURE_RESULT_SHIFT_OFFSET;
281
282 /*
283 * at this point, tmp_result should be in the range:
284 * 200 <= tmp_result <= 365
285 */
286 return (s16)tmp_result - 240;
287}
288
289static s32 check_nic_temperature(struct iwl_mvm *mvm)
290{
291 u16 volt_band_gap;
292 union dts_diode_results avg_ptat;
293
294 volt_band_gap = iwl_mvm_dts_get_volt_band_gap(mvm);
295
296 /* disable DTS */
297 iwl_write_prph(mvm->trans, SHR_MISC_WFM_DTS_EN, 0);
298
299 /* SV initialization */
300 iwl_write_prph(mvm->trans, SHR_MISC_WFM_DTS_EN, 1);
301 iwl_write_prph(mvm->trans, DTSC_CFG_MODE,
302 DTSC_CFG_MODE_PERIODIC);
303
304 /* wait for results */
305 msleep(100);
306 if (!dts_read_ptat_avg_results(mvm, &avg_ptat))
307 return TEMPERATURE_ERROR;
308
309 /* disable DTS */
310 iwl_write_prph(mvm->trans, SHR_MISC_WFM_DTS_EN, 0);
311
312 return calculate_nic_temperature(avg_ptat, volt_band_gap);
313} 136}
314 137
315static void iwl_mvm_enter_ctkill(struct iwl_mvm *mvm) 138static int iwl_mvm_get_temp(struct iwl_mvm *mvm)
316{ 139{
317 u32 duration = mvm->thermal_throttle.params->ct_kill_duration; 140 struct iwl_notification_wait wait_temp_notif;
141 static const u8 temp_notif[] = { DTS_MEASUREMENT_NOTIFICATION };
142 int ret, temp;
318 143
319 if (test_bit(IWL_MVM_STATUS_HW_CTKILL, &mvm->status)) 144 lockdep_assert_held(&mvm->mutex);
320 return;
321 145
322 IWL_ERR(mvm, "Enter CT Kill\n"); 146 iwl_init_notification_wait(&mvm->notif_wait, &wait_temp_notif,
323 iwl_mvm_set_hw_ctkill_state(mvm, true); 147 temp_notif, ARRAY_SIZE(temp_notif),
148 iwl_mvm_temp_notif, &temp);
324 149
325 /* Don't schedule an exit work if we're in test mode, since 150 ret = iwl_mvm_get_temp_cmd(mvm);
326 * the temperature will not change unless we manually set it 151 if (ret) {
327 * again (or disable testing). 152 IWL_ERR(mvm, "Failed to get the temperature (err=%d)\n", ret);
328 */ 153 iwl_remove_notification(&mvm->notif_wait, &wait_temp_notif);
329 if (!mvm->temperature_test) 154 return ret;
330 schedule_delayed_work(&mvm->thermal_throttle.ct_kill_exit, 155 }
331 round_jiffies_relative(duration * HZ));
332}
333 156
334static void iwl_mvm_exit_ctkill(struct iwl_mvm *mvm) 157 ret = iwl_wait_notification(&mvm->notif_wait, &wait_temp_notif,
335{ 158 IWL_MVM_TEMP_NOTIF_WAIT_TIMEOUT);
336 if (!test_bit(IWL_MVM_STATUS_HW_CTKILL, &mvm->status)) 159 if (ret) {
337 return; 160 IWL_ERR(mvm, "Getting the temperature timed out\n");
161 return ret;
162 }
338 163
339 IWL_ERR(mvm, "Exit CT Kill\n"); 164 return temp;
340 iwl_mvm_set_hw_ctkill_state(mvm, false);
341} 165}
342 166
343static void check_exit_ctkill(struct work_struct *work) 167static void check_exit_ctkill(struct work_struct *work)
@@ -352,28 +176,36 @@ static void check_exit_ctkill(struct work_struct *work)
352 176
353 duration = tt->params->ct_kill_duration; 177 duration = tt->params->ct_kill_duration;
354 178
179 mutex_lock(&mvm->mutex);
180
181 if (__iwl_mvm_mac_start(mvm))
182 goto reschedule;
183
355 /* make sure the device is available for direct read/writes */ 184 /* make sure the device is available for direct read/writes */
356 if (iwl_mvm_ref_sync(mvm, IWL_MVM_REF_CHECK_CTKILL)) 185 if (iwl_mvm_ref_sync(mvm, IWL_MVM_REF_CHECK_CTKILL)) {
186 __iwl_mvm_mac_stop(mvm);
357 goto reschedule; 187 goto reschedule;
188 }
358 189
359 iwl_trans_start_hw(mvm->trans); 190 temp = iwl_mvm_get_temp(mvm);
360 temp = check_nic_temperature(mvm);
361 iwl_trans_stop_device(mvm->trans);
362 191
363 iwl_mvm_unref(mvm, IWL_MVM_REF_CHECK_CTKILL); 192 iwl_mvm_unref(mvm, IWL_MVM_REF_CHECK_CTKILL);
364 193
365 if (temp < MIN_TEMPERATURE || temp > MAX_TEMPERATURE) { 194 __iwl_mvm_mac_stop(mvm);
366 IWL_DEBUG_TEMP(mvm, "Failed to measure NIC temperature\n"); 195
196 if (temp < 0)
367 goto reschedule; 197 goto reschedule;
368 } 198
369 IWL_DEBUG_TEMP(mvm, "NIC temperature: %d\n", temp); 199 IWL_DEBUG_TEMP(mvm, "NIC temperature: %d\n", temp);
370 200
371 if (temp <= tt->params->ct_kill_exit) { 201 if (temp <= tt->params->ct_kill_exit) {
202 mutex_unlock(&mvm->mutex);
372 iwl_mvm_exit_ctkill(mvm); 203 iwl_mvm_exit_ctkill(mvm);
373 return; 204 return;
374 } 205 }
375 206
376reschedule: 207reschedule:
208 mutex_unlock(&mvm->mutex);
377 schedule_delayed_work(&mvm->thermal_throttle.ct_kill_exit, 209 schedule_delayed_work(&mvm->thermal_throttle.ct_kill_exit,
378 round_jiffies(duration * HZ)); 210 round_jiffies(duration * HZ));
379} 211}
diff --git a/drivers/net/wireless/iwlwifi/mvm/tx.c b/drivers/net/wireless/iwlwifi/mvm/tx.c
index ed0919465e0e..c67296efa04d 100644
--- a/drivers/net/wireless/iwlwifi/mvm/tx.c
+++ b/drivers/net/wireless/iwlwifi/mvm/tx.c
@@ -213,7 +213,7 @@ static void iwl_mvm_set_tx_cmd_rate(struct iwl_mvm *mvm,
213 213
214 if (info->band == IEEE80211_BAND_2GHZ && 214 if (info->band == IEEE80211_BAND_2GHZ &&
215 !iwl_mvm_bt_coex_is_shared_ant_avail(mvm)) 215 !iwl_mvm_bt_coex_is_shared_ant_avail(mvm))
216 rate_flags = BIT(ANT_A) << RATE_MCS_ANT_POS; 216 rate_flags = BIT(mvm->cfg->non_shared_ant) << RATE_MCS_ANT_POS;
217 else 217 else
218 rate_flags = 218 rate_flags =
219 BIT(mvm->mgmt_last_antenna_idx) << RATE_MCS_ANT_POS; 219 BIT(mvm->mgmt_last_antenna_idx) << RATE_MCS_ANT_POS;
diff --git a/drivers/net/wireless/iwlwifi/pcie/drv.c b/drivers/net/wireless/iwlwifi/pcie/drv.c
index b9d5049e52da..ca68c3ccf633 100644
--- a/drivers/net/wireless/iwlwifi/pcie/drv.c
+++ b/drivers/net/wireless/iwlwifi/pcie/drv.c
@@ -405,6 +405,7 @@ static const struct pci_device_id iwl_hw_card_ids[] = {
405 405
406/* 8000 Series */ 406/* 8000 Series */
407 {IWL_PCI_DEVICE(0x24F3, 0x0010, iwl8260_2ac_cfg)}, 407 {IWL_PCI_DEVICE(0x24F3, 0x0010, iwl8260_2ac_cfg)},
408 {IWL_PCI_DEVICE(0x24F3, 0x0004, iwl8260_2n_cfg)},
408 {IWL_PCI_DEVICE(0x24F4, 0x0030, iwl8260_2ac_cfg)}, 409 {IWL_PCI_DEVICE(0x24F4, 0x0030, iwl8260_2ac_cfg)},
409#endif /* CONFIG_IWLMVM */ 410#endif /* CONFIG_IWLMVM */
410 411
diff --git a/drivers/net/wireless/iwlwifi/pcie/internal.h b/drivers/net/wireless/iwlwifi/pcie/internal.h
index a4fedc4a7448..1aea6b66c594 100644
--- a/drivers/net/wireless/iwlwifi/pcie/internal.h
+++ b/drivers/net/wireless/iwlwifi/pcie/internal.h
@@ -257,6 +257,7 @@ iwl_pcie_get_scratchbuf_dma(struct iwl_txq *txq, int idx)
257 * @cmd_queue - command queue number 257 * @cmd_queue - command queue number
258 * @rx_buf_size_8k: 8 kB RX buffer size 258 * @rx_buf_size_8k: 8 kB RX buffer size
259 * @bc_table_dword: true if the BC table expects DWORD (as opposed to bytes) 259 * @bc_table_dword: true if the BC table expects DWORD (as opposed to bytes)
260 * @scd_set_active: should the transport configure the SCD for HCMD queue
260 * @rx_page_order: page order for receive buffer size 261 * @rx_page_order: page order for receive buffer size
261 * @wd_timeout: queue watchdog timeout (jiffies) 262 * @wd_timeout: queue watchdog timeout (jiffies)
262 * @reg_lock: protect hw register access 263 * @reg_lock: protect hw register access
@@ -306,6 +307,7 @@ struct iwl_trans_pcie {
306 307
307 bool rx_buf_size_8k; 308 bool rx_buf_size_8k;
308 bool bc_table_dword; 309 bool bc_table_dword;
310 bool scd_set_active;
309 u32 rx_page_order; 311 u32 rx_page_order;
310 312
311 const char *const *command_names; 313 const char *const *command_names;
diff --git a/drivers/net/wireless/iwlwifi/pcie/rx.c b/drivers/net/wireless/iwlwifi/pcie/rx.c
index 702f47fb16fe..7b7e2f223fb2 100644
--- a/drivers/net/wireless/iwlwifi/pcie/rx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/rx.c
@@ -640,7 +640,7 @@ static void iwl_pcie_rx_handle_rb(struct iwl_trans *trans,
640 err = iwl_op_mode_rx(trans->op_mode, &rxcb, cmd); 640 err = iwl_op_mode_rx(trans->op_mode, &rxcb, cmd);
641 641
642 if (reclaim) { 642 if (reclaim) {
643 kfree(txq->entries[cmd_index].free_buf); 643 kzfree(txq->entries[cmd_index].free_buf);
644 txq->entries[cmd_index].free_buf = NULL; 644 txq->entries[cmd_index].free_buf = NULL;
645 } 645 }
646 646
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c
index 3076e0e9a490..ae99240dcde4 100644
--- a/drivers/net/wireless/iwlwifi/pcie/trans.c
+++ b/drivers/net/wireless/iwlwifi/pcie/trans.c
@@ -1171,6 +1171,7 @@ static void iwl_trans_pcie_configure(struct iwl_trans *trans,
1171 1171
1172 trans_pcie->command_names = trans_cfg->command_names; 1172 trans_pcie->command_names = trans_cfg->command_names;
1173 trans_pcie->bc_table_dword = trans_cfg->bc_table_dword; 1173 trans_pcie->bc_table_dword = trans_cfg->bc_table_dword;
1174 trans_pcie->scd_set_active = trans_cfg->scd_set_active;
1174 1175
1175 /* Initialize NAPI here - it should be before registering to mac80211 1176 /* Initialize NAPI here - it should be before registering to mac80211
1176 * in the opmode but after the HW struct is allocated. 1177 * in the opmode but after the HW struct is allocated.
@@ -2189,7 +2190,7 @@ struct iwl_trans *iwl_trans_pcie_alloc(struct pci_dev *pdev,
2189 */ 2190 */
2190 if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000) 2191 if (trans->cfg->device_family == IWL_DEVICE_FAMILY_8000)
2191 trans->hw_rev = (trans->hw_rev & 0xfff0) | 2192 trans->hw_rev = (trans->hw_rev & 0xfff0) |
2192 ((trans->hw_rev << 2) & 0xc); 2193 (CSR_HW_REV_STEP(trans->hw_rev << 2));
2193 2194
2194 trans->hw_id = (pdev->device << 16) + pdev->subsystem_device; 2195 trans->hw_id = (pdev->device << 16) + pdev->subsystem_device;
2195 snprintf(trans->hw_id_str, sizeof(trans->hw_id_str), 2196 snprintf(trans->hw_id_str, sizeof(trans->hw_id_str),
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c
index a6336b4aa3a4..eb8e2984c5e9 100644
--- a/drivers/net/wireless/iwlwifi/pcie/tx.c
+++ b/drivers/net/wireless/iwlwifi/pcie/tx.c
@@ -620,8 +620,8 @@ static void iwl_pcie_txq_free(struct iwl_trans *trans, int txq_id)
620 /* De-alloc array of command/tx buffers */ 620 /* De-alloc array of command/tx buffers */
621 if (txq_id == trans_pcie->cmd_queue) 621 if (txq_id == trans_pcie->cmd_queue)
622 for (i = 0; i < txq->q.n_window; i++) { 622 for (i = 0; i < txq->q.n_window; i++) {
623 kfree(txq->entries[i].cmd); 623 kzfree(txq->entries[i].cmd);
624 kfree(txq->entries[i].free_buf); 624 kzfree(txq->entries[i].free_buf);
625 } 625 }
626 626
627 /* De-alloc circular buffer of TFDs */ 627 /* De-alloc circular buffer of TFDs */
@@ -1080,7 +1080,8 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn,
1080 fifo = cfg->fifo; 1080 fifo = cfg->fifo;
1081 1081
1082 /* Disable the scheduler prior configuring the cmd queue */ 1082 /* Disable the scheduler prior configuring the cmd queue */
1083 if (txq_id == trans_pcie->cmd_queue) 1083 if (txq_id == trans_pcie->cmd_queue &&
1084 trans_pcie->scd_set_active)
1084 iwl_scd_enable_set_active(trans, 0); 1085 iwl_scd_enable_set_active(trans, 0);
1085 1086
1086 /* Stop this Tx queue before configuring it */ 1087 /* Stop this Tx queue before configuring it */
@@ -1142,7 +1143,8 @@ void iwl_trans_pcie_txq_enable(struct iwl_trans *trans, int txq_id, u16 ssn,
1142 SCD_QUEUE_STTS_REG_MSK); 1143 SCD_QUEUE_STTS_REG_MSK);
1143 1144
1144 /* enable the scheduler for this queue (only) */ 1145 /* enable the scheduler for this queue (only) */
1145 if (txq_id == trans_pcie->cmd_queue) 1146 if (txq_id == trans_pcie->cmd_queue &&
1147 trans_pcie->scd_set_active)
1146 iwl_scd_enable_set_active(trans, BIT(txq_id)); 1148 iwl_scd_enable_set_active(trans, BIT(txq_id));
1147 } 1149 }
1148 1150
@@ -1407,7 +1409,7 @@ static int iwl_pcie_enqueue_hcmd(struct iwl_trans *trans,
1407 1409
1408 out_meta->flags = cmd->flags; 1410 out_meta->flags = cmd->flags;
1409 if (WARN_ON_ONCE(txq->entries[idx].free_buf)) 1411 if (WARN_ON_ONCE(txq->entries[idx].free_buf))
1410 kfree(txq->entries[idx].free_buf); 1412 kzfree(txq->entries[idx].free_buf);
1411 txq->entries[idx].free_buf = dup_buf; 1413 txq->entries[idx].free_buf = dup_buf;
1412 1414
1413 trace_iwlwifi_dev_hcmd(trans->dev, cmd, cmd_size, &out_cmd->hdr); 1415 trace_iwlwifi_dev_hcmd(trans->dev, cmd, cmd_size, &out_cmd->hdr);
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index 1326f6121835..babbdc1ce741 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -2045,8 +2045,6 @@ static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2,
2045 2045
2046 hw->flags = IEEE80211_HW_MFP_CAPABLE | 2046 hw->flags = IEEE80211_HW_MFP_CAPABLE |
2047 IEEE80211_HW_SIGNAL_DBM | 2047 IEEE80211_HW_SIGNAL_DBM |
2048 IEEE80211_HW_SUPPORTS_STATIC_SMPS |
2049 IEEE80211_HW_SUPPORTS_DYNAMIC_SMPS |
2050 IEEE80211_HW_AMPDU_AGGREGATION | 2048 IEEE80211_HW_AMPDU_AGGREGATION |
2051 IEEE80211_HW_WANT_MONITOR_VIF | 2049 IEEE80211_HW_WANT_MONITOR_VIF |
2052 IEEE80211_HW_QUEUE_CONTROL | 2050 IEEE80211_HW_QUEUE_CONTROL |
@@ -2059,8 +2057,10 @@ static int mac80211_hwsim_create_radio(int channels, const char *reg_alpha2,
2059 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL | 2057 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
2060 WIPHY_FLAG_AP_UAPSD | 2058 WIPHY_FLAG_AP_UAPSD |
2061 WIPHY_FLAG_HAS_CHANNEL_SWITCH; 2059 WIPHY_FLAG_HAS_CHANNEL_SWITCH;
2062 hw->wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR; 2060 hw->wiphy->features |= NL80211_FEATURE_ACTIVE_MONITOR |
2063 hw->wiphy->features |= NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE; 2061 NL80211_FEATURE_AP_MODE_CHAN_WIDTH_CHANGE |
2062 NL80211_FEATURE_STATIC_SMPS |
2063 NL80211_FEATURE_DYNAMIC_SMPS;
2064 2064
2065 /* ask mac80211 to reserve space for magic */ 2065 /* ask mac80211 to reserve space for magic */
2066 hw->vif_data_size = sizeof(struct hwsim_vif_priv); 2066 hw->vif_data_size = sizeof(struct hwsim_vif_priv);
diff --git a/drivers/net/wireless/mwifiex/11n_rxreorder.c b/drivers/net/wireless/mwifiex/11n_rxreorder.c
index 06a2c215ef5e..40057079ffb9 100644
--- a/drivers/net/wireless/mwifiex/11n_rxreorder.c
+++ b/drivers/net/wireless/mwifiex/11n_rxreorder.c
@@ -183,6 +183,15 @@ mwifiex_del_rx_reorder_entry(struct mwifiex_private *priv,
183 if (!tbl) 183 if (!tbl)
184 return; 184 return;
185 185
186 spin_lock_irqsave(&priv->adapter->rx_proc_lock, flags);
187 priv->adapter->rx_locked = true;
188 if (priv->adapter->rx_processing) {
189 spin_unlock_irqrestore(&priv->adapter->rx_proc_lock, flags);
190 flush_workqueue(priv->adapter->rx_workqueue);
191 } else {
192 spin_unlock_irqrestore(&priv->adapter->rx_proc_lock, flags);
193 }
194
186 start_win = (tbl->start_win + tbl->win_size) & (MAX_TID_VALUE - 1); 195 start_win = (tbl->start_win + tbl->win_size) & (MAX_TID_VALUE - 1);
187 mwifiex_11n_dispatch_pkt_until_start_win(priv, tbl, start_win); 196 mwifiex_11n_dispatch_pkt_until_start_win(priv, tbl, start_win);
188 197
@@ -194,6 +203,11 @@ mwifiex_del_rx_reorder_entry(struct mwifiex_private *priv,
194 203
195 kfree(tbl->rx_reorder_ptr); 204 kfree(tbl->rx_reorder_ptr);
196 kfree(tbl); 205 kfree(tbl);
206
207 spin_lock_irqsave(&priv->adapter->rx_proc_lock, flags);
208 priv->adapter->rx_locked = false;
209 spin_unlock_irqrestore(&priv->adapter->rx_proc_lock, flags);
210
197} 211}
198 212
199/* 213/*
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index c4723b0f5757..0dd672954ad1 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -1936,13 +1936,6 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy,
1936 1936
1937 wiphy_dbg(wiphy, "info: received scan request on %s\n", dev->name); 1937 wiphy_dbg(wiphy, "info: received scan request on %s\n", dev->name);
1938 1938
1939 if ((request->flags & NL80211_SCAN_FLAG_LOW_PRIORITY) &&
1940 atomic_read(&priv->wmm.tx_pkts_queued) >=
1941 MWIFIEX_MIN_TX_PENDING_TO_CANCEL_SCAN) {
1942 dev_dbg(priv->adapter->dev, "scan rejected due to traffic\n");
1943 return -EBUSY;
1944 }
1945
1946 /* Block scan request if scan operation or scan cleanup when interface 1939 /* Block scan request if scan operation or scan cleanup when interface
1947 * is disabled is in process 1940 * is disabled is in process
1948 */ 1941 */
@@ -1981,7 +1974,7 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy,
1981 user_scan_cfg->chan_list[i].chan_number = chan->hw_value; 1974 user_scan_cfg->chan_list[i].chan_number = chan->hw_value;
1982 user_scan_cfg->chan_list[i].radio_type = chan->band; 1975 user_scan_cfg->chan_list[i].radio_type = chan->band;
1983 1976
1984 if (chan->flags & IEEE80211_CHAN_NO_IR) 1977 if ((chan->flags & IEEE80211_CHAN_NO_IR) || !request->n_ssids)
1985 user_scan_cfg->chan_list[i].scan_type = 1978 user_scan_cfg->chan_list[i].scan_type =
1986 MWIFIEX_SCAN_TYPE_PASSIVE; 1979 MWIFIEX_SCAN_TYPE_PASSIVE;
1987 else 1980 else
@@ -1991,6 +1984,11 @@ mwifiex_cfg80211_scan(struct wiphy *wiphy,
1991 user_scan_cfg->chan_list[i].scan_time = 0; 1984 user_scan_cfg->chan_list[i].scan_time = 0;
1992 } 1985 }
1993 1986
1987 if (priv->adapter->scan_chan_gap_enabled &&
1988 mwifiex_is_any_intf_active(priv))
1989 user_scan_cfg->scan_chan_gap =
1990 priv->adapter->scan_chan_gap_time;
1991
1994 ret = mwifiex_scan_networks(priv, user_scan_cfg); 1992 ret = mwifiex_scan_networks(priv, user_scan_cfg);
1995 kfree(user_scan_cfg); 1993 kfree(user_scan_cfg);
1996 if (ret) { 1994 if (ret) {
@@ -2915,7 +2913,6 @@ int mwifiex_register_cfg80211(struct mwifiex_adapter *adapter)
2915 2913
2916 wiphy->features |= NL80211_FEATURE_HT_IBSS | 2914 wiphy->features |= NL80211_FEATURE_HT_IBSS |
2917 NL80211_FEATURE_INACTIVITY_TIMER | 2915 NL80211_FEATURE_INACTIVITY_TIMER |
2918 NL80211_FEATURE_LOW_PRIORITY_SCAN |
2919 NL80211_FEATURE_NEED_OBSS_SCAN; 2916 NL80211_FEATURE_NEED_OBSS_SCAN;
2920 2917
2921 /* Reserve space for mwifiex specific private data for BSS */ 2918 /* Reserve space for mwifiex specific private data for BSS */
diff --git a/drivers/net/wireless/mwifiex/cmdevt.c b/drivers/net/wireless/mwifiex/cmdevt.c
index 985f6c2654fb..85597200badc 100644
--- a/drivers/net/wireless/mwifiex/cmdevt.c
+++ b/drivers/net/wireless/mwifiex/cmdevt.c
@@ -1508,6 +1508,7 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
1508 } 1508 }
1509 1509
1510 adapter->fw_release_number = le32_to_cpu(hw_spec->fw_release_number); 1510 adapter->fw_release_number = le32_to_cpu(hw_spec->fw_release_number);
1511 adapter->fw_api_ver = (adapter->fw_release_number >> 16) & 0xff;
1511 adapter->number_of_antenna = le16_to_cpu(hw_spec->number_of_antenna); 1512 adapter->number_of_antenna = le16_to_cpu(hw_spec->number_of_antenna);
1512 1513
1513 if (le32_to_cpu(hw_spec->dot_11ac_dev_cap)) { 1514 if (le32_to_cpu(hw_spec->dot_11ac_dev_cap)) {
@@ -1612,5 +1613,8 @@ int mwifiex_ret_get_hw_spec(struct mwifiex_private *priv,
1612 adapter->if_ops.update_mp_end_port(adapter, 1613 adapter->if_ops.update_mp_end_port(adapter,
1613 le16_to_cpu(hw_spec->mp_end_port)); 1614 le16_to_cpu(hw_spec->mp_end_port));
1614 1615
1616 if (adapter->fw_api_ver == MWIFIEX_FW_V15)
1617 adapter->scan_chan_gap_enabled = true;
1618
1615 return 0; 1619 return 0;
1616} 1620}
diff --git a/drivers/net/wireless/mwifiex/decl.h b/drivers/net/wireless/mwifiex/decl.h
index 0e03fe39fc35..e0d00a7f0ec3 100644
--- a/drivers/net/wireless/mwifiex/decl.h
+++ b/drivers/net/wireless/mwifiex/decl.h
@@ -48,8 +48,8 @@
48#define MWIFIEX_UAP_AMPDU_DEF_RXWINSIZE 16 48#define MWIFIEX_UAP_AMPDU_DEF_RXWINSIZE 16
49#define MWIFIEX_11AC_STA_AMPDU_DEF_TXWINSIZE 64 49#define MWIFIEX_11AC_STA_AMPDU_DEF_TXWINSIZE 64
50#define MWIFIEX_11AC_STA_AMPDU_DEF_RXWINSIZE 64 50#define MWIFIEX_11AC_STA_AMPDU_DEF_RXWINSIZE 64
51#define MWIFIEX_11AC_UAP_AMPDU_DEF_TXWINSIZE 48 51#define MWIFIEX_11AC_UAP_AMPDU_DEF_TXWINSIZE 64
52#define MWIFIEX_11AC_UAP_AMPDU_DEF_RXWINSIZE 32 52#define MWIFIEX_11AC_UAP_AMPDU_DEF_RXWINSIZE 64
53 53
54#define MWIFIEX_DEFAULT_BLOCK_ACK_TIMEOUT 0xffff 54#define MWIFIEX_DEFAULT_BLOCK_ACK_TIMEOUT 0xffff
55 55
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index 6a703ea18800..1eb61739071f 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -170,7 +170,8 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
170#define TLV_TYPE_COALESCE_RULE (PROPRIETARY_TLV_BASE_ID + 154) 170#define TLV_TYPE_COALESCE_RULE (PROPRIETARY_TLV_BASE_ID + 154)
171#define TLV_TYPE_KEY_PARAM_V2 (PROPRIETARY_TLV_BASE_ID + 156) 171#define TLV_TYPE_KEY_PARAM_V2 (PROPRIETARY_TLV_BASE_ID + 156)
172#define TLV_TYPE_TDLS_IDLE_TIMEOUT (PROPRIETARY_TLV_BASE_ID + 194) 172#define TLV_TYPE_TDLS_IDLE_TIMEOUT (PROPRIETARY_TLV_BASE_ID + 194)
173#define TLV_TYPE_API_REV (PROPRIETARY_TLV_BASE_ID + 199) 173#define TLV_TYPE_SCAN_CHANNEL_GAP (PROPRIETARY_TLV_BASE_ID + 197)
174#define TLV_TYPE_API_REV (PROPRIETARY_TLV_BASE_ID + 199)
174 175
175#define MWIFIEX_TX_DATA_BUF_SIZE_2K 2048 176#define MWIFIEX_TX_DATA_BUF_SIZE_2K 2048
176 177
@@ -653,6 +654,12 @@ struct mwifiex_ie_types_num_probes {
653 __le16 num_probes; 654 __le16 num_probes;
654} __packed; 655} __packed;
655 656
657struct mwifiex_ie_types_scan_chan_gap {
658 struct mwifiex_ie_types_header header;
659 /* time gap in TUs to be used between two consecutive channels scan */
660 __le16 chan_gap;
661} __packed;
662
656struct mwifiex_ie_types_wildcard_ssid_params { 663struct mwifiex_ie_types_wildcard_ssid_params {
657 struct mwifiex_ie_types_header header; 664 struct mwifiex_ie_types_header header;
658 u8 max_ssid_length; 665 u8 max_ssid_length;
@@ -1249,6 +1256,7 @@ struct mwifiex_user_scan_cfg {
1249 u8 num_ssids; 1256 u8 num_ssids;
1250 /* Variable number (fixed maximum) of channels to scan up */ 1257 /* Variable number (fixed maximum) of channels to scan up */
1251 struct mwifiex_user_scan_chan chan_list[MWIFIEX_USER_SCAN_CHAN_MAX]; 1258 struct mwifiex_user_scan_chan chan_list[MWIFIEX_USER_SCAN_CHAN_MAX];
1259 u16 scan_chan_gap;
1252} __packed; 1260} __packed;
1253 1261
1254struct ie_body { 1262struct ie_body {
diff --git a/drivers/net/wireless/mwifiex/init.c b/drivers/net/wireless/mwifiex/init.c
index 80bda8087508..f7c97cf3840b 100644
--- a/drivers/net/wireless/mwifiex/init.c
+++ b/drivers/net/wireless/mwifiex/init.c
@@ -212,6 +212,7 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
212 adapter->specific_scan_time = MWIFIEX_SPECIFIC_SCAN_CHAN_TIME; 212 adapter->specific_scan_time = MWIFIEX_SPECIFIC_SCAN_CHAN_TIME;
213 adapter->active_scan_time = MWIFIEX_ACTIVE_SCAN_CHAN_TIME; 213 adapter->active_scan_time = MWIFIEX_ACTIVE_SCAN_CHAN_TIME;
214 adapter->passive_scan_time = MWIFIEX_PASSIVE_SCAN_CHAN_TIME; 214 adapter->passive_scan_time = MWIFIEX_PASSIVE_SCAN_CHAN_TIME;
215 adapter->scan_chan_gap_time = MWIFIEX_DEF_SCAN_CHAN_GAP_TIME;
215 216
216 adapter->scan_probes = 1; 217 adapter->scan_probes = 1;
217 218
@@ -280,7 +281,6 @@ static void mwifiex_init_adapter(struct mwifiex_adapter *adapter)
280 memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter)); 281 memset(&adapter->arp_filter, 0, sizeof(adapter->arp_filter));
281 adapter->arp_filter_size = 0; 282 adapter->arp_filter_size = 0;
282 adapter->max_mgmt_ie_index = MAX_MGMT_IE_INDEX; 283 adapter->max_mgmt_ie_index = MAX_MGMT_IE_INDEX;
283 adapter->empty_tx_q_cnt = 0;
284 adapter->ext_scan = true; 284 adapter->ext_scan = true;
285 adapter->key_api_major_ver = 0; 285 adapter->key_api_major_ver = 0;
286 adapter->key_api_minor_ver = 0; 286 adapter->key_api_minor_ver = 0;
@@ -447,8 +447,11 @@ int mwifiex_init_lock_list(struct mwifiex_adapter *adapter)
447 spin_lock_init(&adapter->cmd_free_q_lock); 447 spin_lock_init(&adapter->cmd_free_q_lock);
448 spin_lock_init(&adapter->cmd_pending_q_lock); 448 spin_lock_init(&adapter->cmd_pending_q_lock);
449 spin_lock_init(&adapter->scan_pending_q_lock); 449 spin_lock_init(&adapter->scan_pending_q_lock);
450 spin_lock_init(&adapter->rx_q_lock);
451 spin_lock_init(&adapter->rx_proc_lock);
450 452
451 skb_queue_head_init(&adapter->usb_rx_data_q); 453 skb_queue_head_init(&adapter->usb_rx_data_q);
454 skb_queue_head_init(&adapter->rx_data_q);
452 455
453 for (i = 0; i < adapter->priv_num; ++i) { 456 for (i = 0; i < adapter->priv_num; ++i) {
454 INIT_LIST_HEAD(&adapter->bss_prio_tbl[i].bss_prio_head); 457 INIT_LIST_HEAD(&adapter->bss_prio_tbl[i].bss_prio_head);
@@ -614,6 +617,7 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter)
614 int ret = -EINPROGRESS; 617 int ret = -EINPROGRESS;
615 struct mwifiex_private *priv; 618 struct mwifiex_private *priv;
616 s32 i; 619 s32 i;
620 unsigned long flags;
617 struct sk_buff *skb; 621 struct sk_buff *skb;
618 622
619 /* mwifiex already shutdown */ 623 /* mwifiex already shutdown */
@@ -648,6 +652,21 @@ mwifiex_shutdown_drv(struct mwifiex_adapter *adapter)
648 } 652 }
649 } 653 }
650 654
655 spin_lock_irqsave(&adapter->rx_proc_lock, flags);
656
657 while ((skb = skb_dequeue(&adapter->rx_data_q))) {
658 struct mwifiex_rxinfo *rx_info = MWIFIEX_SKB_RXCB(skb);
659
660 atomic_dec(&adapter->rx_pending);
661 priv = adapter->priv[rx_info->bss_num];
662 if (priv)
663 priv->stats.rx_dropped++;
664
665 dev_kfree_skb_any(skb);
666 }
667
668 spin_unlock_irqrestore(&adapter->rx_proc_lock, flags);
669
651 spin_lock(&adapter->mwifiex_lock); 670 spin_lock(&adapter->mwifiex_lock);
652 671
653 if (adapter->if_ops.data_complete) { 672 if (adapter->if_ops.data_complete) {
diff --git a/drivers/net/wireless/mwifiex/main.c b/drivers/net/wireless/mwifiex/main.c
index dfa37eadc4db..b522f7c36901 100644
--- a/drivers/net/wireless/mwifiex/main.c
+++ b/drivers/net/wireless/mwifiex/main.c
@@ -28,91 +28,6 @@ const char driver_version[] = "mwifiex " VERSION " (%s) ";
28static char *cal_data_cfg; 28static char *cal_data_cfg;
29module_param(cal_data_cfg, charp, 0); 29module_param(cal_data_cfg, charp, 0);
30 30
31static void scan_delay_timer_fn(unsigned long data)
32{
33 struct mwifiex_private *priv = (struct mwifiex_private *)data;
34 struct mwifiex_adapter *adapter = priv->adapter;
35 struct cmd_ctrl_node *cmd_node, *tmp_node;
36 spinlock_t *scan_q_lock = &adapter->scan_pending_q_lock;
37 unsigned long flags;
38
39 if (adapter->surprise_removed)
40 return;
41
42 if (adapter->scan_delay_cnt == MWIFIEX_MAX_SCAN_DELAY_CNT ||
43 !adapter->scan_processing) {
44 /*
45 * Abort scan operation by cancelling all pending scan
46 * commands
47 */
48 spin_lock_irqsave(scan_q_lock, flags);
49 list_for_each_entry_safe(cmd_node, tmp_node,
50 &adapter->scan_pending_q, list) {
51 list_del(&cmd_node->list);
52 mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
53 }
54 spin_unlock_irqrestore(scan_q_lock, flags);
55
56 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
57 adapter->scan_processing = false;
58 adapter->scan_delay_cnt = 0;
59 adapter->empty_tx_q_cnt = 0;
60 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
61
62 if (priv->scan_request) {
63 dev_dbg(adapter->dev, "info: aborting scan\n");
64 cfg80211_scan_done(priv->scan_request, 1);
65 priv->scan_request = NULL;
66 } else {
67 priv->scan_aborting = false;
68 dev_dbg(adapter->dev, "info: scan already aborted\n");
69 }
70 goto done;
71 }
72
73 if (!atomic_read(&priv->adapter->is_tx_received)) {
74 adapter->empty_tx_q_cnt++;
75 if (adapter->empty_tx_q_cnt == MWIFIEX_MAX_EMPTY_TX_Q_CNT) {
76 /*
77 * No Tx traffic for 200msec. Get scan command from
78 * scan pending queue and put to cmd pending queue to
79 * resume scan operation
80 */
81 adapter->scan_delay_cnt = 0;
82 adapter->empty_tx_q_cnt = 0;
83 spin_lock_irqsave(scan_q_lock, flags);
84
85 if (list_empty(&adapter->scan_pending_q)) {
86 spin_unlock_irqrestore(scan_q_lock, flags);
87 goto done;
88 }
89
90 cmd_node = list_first_entry(&adapter->scan_pending_q,
91 struct cmd_ctrl_node, list);
92 list_del(&cmd_node->list);
93 spin_unlock_irqrestore(scan_q_lock, flags);
94
95 mwifiex_insert_cmd_to_pending_q(adapter, cmd_node,
96 true);
97 queue_work(adapter->workqueue, &adapter->main_work);
98 goto done;
99 }
100 } else {
101 adapter->empty_tx_q_cnt = 0;
102 }
103
104 /* Delay scan operation further by 20msec */
105 mod_timer(&priv->scan_delay_timer, jiffies +
106 msecs_to_jiffies(MWIFIEX_SCAN_DELAY_MSEC));
107 adapter->scan_delay_cnt++;
108
109done:
110 if (atomic_read(&priv->adapter->is_tx_received))
111 atomic_set(&priv->adapter->is_tx_received, false);
112
113 return;
114}
115
116/* 31/*
117 * This function registers the device and performs all the necessary 32 * This function registers the device and performs all the necessary
118 * initializations. 33 * initializations.
@@ -160,10 +75,6 @@ static int mwifiex_register(void *card, struct mwifiex_if_ops *if_ops,
160 75
161 adapter->priv[i]->adapter = adapter; 76 adapter->priv[i]->adapter = adapter;
162 adapter->priv_num++; 77 adapter->priv_num++;
163
164 setup_timer(&adapter->priv[i]->scan_delay_timer,
165 scan_delay_timer_fn,
166 (unsigned long)adapter->priv[i]);
167 } 78 }
168 mwifiex_init_lock_list(adapter); 79 mwifiex_init_lock_list(adapter);
169 80
@@ -207,7 +118,6 @@ static int mwifiex_unregister(struct mwifiex_adapter *adapter)
207 for (i = 0; i < adapter->priv_num; i++) { 118 for (i = 0; i < adapter->priv_num; i++) {
208 if (adapter->priv[i]) { 119 if (adapter->priv[i]) {
209 mwifiex_free_curr_bcn(adapter->priv[i]); 120 mwifiex_free_curr_bcn(adapter->priv[i]);
210 del_timer_sync(&adapter->priv[i]->scan_delay_timer);
211 kfree(adapter->priv[i]); 121 kfree(adapter->priv[i]);
212 } 122 }
213 } 123 }
@@ -216,6 +126,42 @@ static int mwifiex_unregister(struct mwifiex_adapter *adapter)
216 return 0; 126 return 0;
217} 127}
218 128
129static int mwifiex_process_rx(struct mwifiex_adapter *adapter)
130{
131 unsigned long flags;
132 struct sk_buff *skb;
133 bool delay_main_work = adapter->delay_main_work;
134
135 spin_lock_irqsave(&adapter->rx_proc_lock, flags);
136 if (adapter->rx_processing || adapter->rx_locked) {
137 spin_unlock_irqrestore(&adapter->rx_proc_lock, flags);
138 goto exit_rx_proc;
139 } else {
140 adapter->rx_processing = true;
141 spin_unlock_irqrestore(&adapter->rx_proc_lock, flags);
142 }
143
144 /* Check for Rx data */
145 while ((skb = skb_dequeue(&adapter->rx_data_q))) {
146 atomic_dec(&adapter->rx_pending);
147 if (adapter->delay_main_work &&
148 (atomic_dec_return(&adapter->rx_pending) <
149 LOW_RX_PENDING)) {
150 adapter->delay_main_work = false;
151 queue_work(adapter->rx_workqueue, &adapter->rx_work);
152 }
153 mwifiex_handle_rx_packet(adapter, skb);
154 }
155 spin_lock_irqsave(&adapter->rx_proc_lock, flags);
156 adapter->rx_processing = false;
157 spin_unlock_irqrestore(&adapter->rx_proc_lock, flags);
158
159 if (delay_main_work)
160 queue_work(adapter->workqueue, &adapter->main_work);
161exit_rx_proc:
162 return 0;
163}
164
219/* 165/*
220 * The main process. 166 * The main process.
221 * 167 *
@@ -253,6 +199,19 @@ process_start:
253 (adapter->hw_status == MWIFIEX_HW_STATUS_NOT_READY)) 199 (adapter->hw_status == MWIFIEX_HW_STATUS_NOT_READY))
254 break; 200 break;
255 201
202 /* If we process interrupts first, it would increase RX pending
203 * even further. Avoid this by checking if rx_pending has
204 * crossed high threshold and schedule rx work queue
205 * and then process interrupts
206 */
207 if (atomic_read(&adapter->rx_pending) >= HIGH_RX_PENDING) {
208 adapter->delay_main_work = true;
209 if (!adapter->rx_processing)
210 queue_work(adapter->rx_workqueue,
211 &adapter->rx_work);
212 break;
213 }
214
256 /* Handle pending interrupt if any */ 215 /* Handle pending interrupt if any */
257 if (adapter->int_status) { 216 if (adapter->int_status) {
258 if (adapter->hs_activated) 217 if (adapter->hs_activated)
@@ -261,6 +220,9 @@ process_start:
261 adapter->if_ops.process_int_status(adapter); 220 adapter->if_ops.process_int_status(adapter);
262 } 221 }
263 222
223 if (adapter->rx_work_enabled && adapter->data_received)
224 queue_work(adapter->rx_workqueue, &adapter->rx_work);
225
264 /* Need to wake up the card ? */ 226 /* Need to wake up the card ? */
265 if ((adapter->ps_state == PS_STATE_SLEEP) && 227 if ((adapter->ps_state == PS_STATE_SLEEP) &&
266 (adapter->pm_wakeup_card_req && 228 (adapter->pm_wakeup_card_req &&
@@ -273,6 +235,7 @@ process_start:
273 } 235 }
274 236
275 if (IS_CARD_RX_RCVD(adapter)) { 237 if (IS_CARD_RX_RCVD(adapter)) {
238 adapter->data_received = false;
276 adapter->pm_wakeup_fw_try = false; 239 adapter->pm_wakeup_fw_try = false;
277 if (adapter->ps_state == PS_STATE_SLEEP) 240 if (adapter->ps_state == PS_STATE_SLEEP)
278 adapter->ps_state = PS_STATE_AWAKE; 241 adapter->ps_state = PS_STATE_AWAKE;
@@ -284,8 +247,8 @@ process_start:
284 adapter->tx_lock_flag) 247 adapter->tx_lock_flag)
285 break; 248 break;
286 249
287 if ((adapter->scan_processing && 250 if ((!adapter->scan_chan_gap_enabled &&
288 !adapter->scan_delay_cnt) || adapter->data_sent || 251 adapter->scan_processing) || adapter->data_sent ||
289 mwifiex_wmm_lists_empty(adapter)) { 252 mwifiex_wmm_lists_empty(adapter)) {
290 if (adapter->cmd_sent || adapter->curr_cmd || 253 if (adapter->cmd_sent || adapter->curr_cmd ||
291 (!is_command_pending(adapter))) 254 (!is_command_pending(adapter)))
@@ -339,7 +302,8 @@ process_start:
339 } 302 }
340 } 303 }
341 304
342 if ((!adapter->scan_processing || adapter->scan_delay_cnt) && 305 if ((adapter->scan_chan_gap_enabled ||
306 !adapter->scan_processing) &&
343 !adapter->data_sent && !mwifiex_wmm_lists_empty(adapter)) { 307 !adapter->data_sent && !mwifiex_wmm_lists_empty(adapter)) {
344 mwifiex_wmm_process_tx(adapter); 308 mwifiex_wmm_process_tx(adapter);
345 if (adapter->hs_activated) { 309 if (adapter->hs_activated) {
@@ -407,6 +371,12 @@ static void mwifiex_terminate_workqueue(struct mwifiex_adapter *adapter)
407 flush_workqueue(adapter->workqueue); 371 flush_workqueue(adapter->workqueue);
408 destroy_workqueue(adapter->workqueue); 372 destroy_workqueue(adapter->workqueue);
409 adapter->workqueue = NULL; 373 adapter->workqueue = NULL;
374
375 if (adapter->rx_workqueue) {
376 flush_workqueue(adapter->rx_workqueue);
377 destroy_workqueue(adapter->rx_workqueue);
378 adapter->rx_workqueue = NULL;
379 }
410} 380}
411 381
412/* 382/*
@@ -598,9 +568,6 @@ int mwifiex_queue_tx_pkt(struct mwifiex_private *priv, struct sk_buff *skb)
598 atomic_inc(&priv->adapter->tx_pending); 568 atomic_inc(&priv->adapter->tx_pending);
599 mwifiex_wmm_add_buf_txqueue(priv, skb); 569 mwifiex_wmm_add_buf_txqueue(priv, skb);
600 570
601 if (priv->adapter->scan_delay_cnt)
602 atomic_set(&priv->adapter->is_tx_received, true);
603
604 queue_work(priv->adapter->workqueue, &priv->adapter->main_work); 571 queue_work(priv->adapter->workqueue, &priv->adapter->main_work);
605 572
606 return 0; 573 return 0;
@@ -824,6 +791,21 @@ int is_command_pending(struct mwifiex_adapter *adapter)
824} 791}
825 792
826/* 793/*
794 * This is the RX work queue function.
795 *
796 * It handles the RX operations.
797 */
798static void mwifiex_rx_work_queue(struct work_struct *work)
799{
800 struct mwifiex_adapter *adapter =
801 container_of(work, struct mwifiex_adapter, rx_work);
802
803 if (adapter->surprise_removed)
804 return;
805 mwifiex_process_rx(adapter);
806}
807
808/*
827 * This is the main work queue function. 809 * This is the main work queue function.
828 * 810 *
829 * It handles the main process, which in turn handles the complete 811 * It handles the main process, which in turn handles the complete
@@ -879,6 +861,11 @@ mwifiex_add_card(void *card, struct semaphore *sem,
879 adapter->cmd_wait_q.status = 0; 861 adapter->cmd_wait_q.status = 0;
880 adapter->scan_wait_q_woken = false; 862 adapter->scan_wait_q_woken = false;
881 863
864 if (num_possible_cpus() > 1) {
865 adapter->rx_work_enabled = true;
866 pr_notice("rx work enabled, cpus %d\n", num_possible_cpus());
867 }
868
882 adapter->workqueue = 869 adapter->workqueue =
883 alloc_workqueue("MWIFIEX_WORK_QUEUE", 870 alloc_workqueue("MWIFIEX_WORK_QUEUE",
884 WQ_HIGHPRI | WQ_MEM_RECLAIM | WQ_UNBOUND, 1); 871 WQ_HIGHPRI | WQ_MEM_RECLAIM | WQ_UNBOUND, 1);
@@ -886,6 +873,18 @@ mwifiex_add_card(void *card, struct semaphore *sem,
886 goto err_kmalloc; 873 goto err_kmalloc;
887 874
888 INIT_WORK(&adapter->main_work, mwifiex_main_work_queue); 875 INIT_WORK(&adapter->main_work, mwifiex_main_work_queue);
876
877 if (adapter->rx_work_enabled) {
878 adapter->rx_workqueue = alloc_workqueue("MWIFIEX_RX_WORK_QUEUE",
879 WQ_HIGHPRI |
880 WQ_MEM_RECLAIM |
881 WQ_UNBOUND, 1);
882 if (!adapter->rx_workqueue)
883 goto err_kmalloc;
884
885 INIT_WORK(&adapter->rx_work, mwifiex_rx_work_queue);
886 }
887
889 if (adapter->if_ops.iface_work) 888 if (adapter->if_ops.iface_work)
890 INIT_WORK(&adapter->iface_work, adapter->if_ops.iface_work); 889 INIT_WORK(&adapter->iface_work, adapter->if_ops.iface_work);
891 890
diff --git a/drivers/net/wireless/mwifiex/main.h b/drivers/net/wireless/mwifiex/main.h
index 54399631599a..1a999999b391 100644
--- a/drivers/net/wireless/mwifiex/main.h
+++ b/drivers/net/wireless/mwifiex/main.h
@@ -58,6 +58,9 @@ enum {
58#define MAX_TX_PENDING 100 58#define MAX_TX_PENDING 100
59#define LOW_TX_PENDING 80 59#define LOW_TX_PENDING 80
60 60
61#define HIGH_RX_PENDING 50
62#define LOW_RX_PENDING 20
63
61#define MWIFIEX_UPLD_SIZE (2312) 64#define MWIFIEX_UPLD_SIZE (2312)
62 65
63#define MAX_EVENT_SIZE 2048 66#define MAX_EVENT_SIZE 2048
@@ -84,17 +87,12 @@ enum {
84#define MWIFIEX_PASSIVE_SCAN_CHAN_TIME 110 87#define MWIFIEX_PASSIVE_SCAN_CHAN_TIME 110
85#define MWIFIEX_ACTIVE_SCAN_CHAN_TIME 30 88#define MWIFIEX_ACTIVE_SCAN_CHAN_TIME 30
86#define MWIFIEX_SPECIFIC_SCAN_CHAN_TIME 30 89#define MWIFIEX_SPECIFIC_SCAN_CHAN_TIME 30
90#define MWIFIEX_DEF_SCAN_CHAN_GAP_TIME 50
87 91
88#define SCAN_RSSI(RSSI) (0x100 - ((u8)(RSSI))) 92#define SCAN_RSSI(RSSI) (0x100 - ((u8)(RSSI)))
89 93
90#define MWIFIEX_MAX_TOTAL_SCAN_TIME (MWIFIEX_TIMER_10S - MWIFIEX_TIMER_1S) 94#define MWIFIEX_MAX_TOTAL_SCAN_TIME (MWIFIEX_TIMER_10S - MWIFIEX_TIMER_1S)
91 95
92#define MWIFIEX_MAX_SCAN_DELAY_CNT 50
93#define MWIFIEX_MAX_EMPTY_TX_Q_CNT 10
94#define MWIFIEX_SCAN_DELAY_MSEC 20
95
96#define MWIFIEX_MIN_TX_PENDING_TO_CANCEL_SCAN 2
97
98#define RSN_GTK_OUI_OFFSET 2 96#define RSN_GTK_OUI_OFFSET 2
99 97
100#define MWIFIEX_OUI_NOT_PRESENT 0 98#define MWIFIEX_OUI_NOT_PRESENT 0
@@ -547,7 +545,6 @@ struct mwifiex_private {
547 u8 nick_name[16]; 545 u8 nick_name[16];
548 u16 current_key_index; 546 u16 current_key_index;
549 struct semaphore async_sem; 547 struct semaphore async_sem;
550 u8 report_scan_result;
551 struct cfg80211_scan_request *scan_request; 548 struct cfg80211_scan_request *scan_request;
552 u8 cfg_bssid[6]; 549 u8 cfg_bssid[6];
553 struct wps wps; 550 struct wps wps;
@@ -561,7 +558,6 @@ struct mwifiex_private {
561 u16 proberesp_idx; 558 u16 proberesp_idx;
562 u16 assocresp_idx; 559 u16 assocresp_idx;
563 u16 rsn_idx; 560 u16 rsn_idx;
564 struct timer_list scan_delay_timer;
565 u8 ap_11n_enabled; 561 u8 ap_11n_enabled;
566 u8 ap_11ac_enabled; 562 u8 ap_11ac_enabled;
567 u32 mgmt_frame_mask; 563 u32 mgmt_frame_mask;
@@ -721,6 +717,12 @@ struct mwifiex_adapter {
721 atomic_t cmd_pending; 717 atomic_t cmd_pending;
722 struct workqueue_struct *workqueue; 718 struct workqueue_struct *workqueue;
723 struct work_struct main_work; 719 struct work_struct main_work;
720 struct workqueue_struct *rx_workqueue;
721 struct work_struct rx_work;
722 bool rx_work_enabled;
723 bool rx_processing;
724 bool delay_main_work;
725 bool rx_locked;
724 struct mwifiex_bss_prio_tbl bss_prio_tbl[MWIFIEX_MAX_BSS_NUM]; 726 struct mwifiex_bss_prio_tbl bss_prio_tbl[MWIFIEX_MAX_BSS_NUM];
725 /* spin lock for init/shutdown */ 727 /* spin lock for init/shutdown */
726 spinlock_t mwifiex_lock; 728 spinlock_t mwifiex_lock;
@@ -761,6 +763,10 @@ struct mwifiex_adapter {
761 struct list_head scan_pending_q; 763 struct list_head scan_pending_q;
762 /* spin lock for scan_pending_q */ 764 /* spin lock for scan_pending_q */
763 spinlock_t scan_pending_q_lock; 765 spinlock_t scan_pending_q_lock;
766 /* spin lock for RX queue */
767 spinlock_t rx_q_lock;
768 /* spin lock for RX processing routine */
769 spinlock_t rx_proc_lock;
764 struct sk_buff_head usb_rx_data_q; 770 struct sk_buff_head usb_rx_data_q;
765 u32 scan_processing; 771 u32 scan_processing;
766 u16 region_code; 772 u16 region_code;
@@ -770,6 +776,7 @@ struct mwifiex_adapter {
770 u16 specific_scan_time; 776 u16 specific_scan_time;
771 u16 active_scan_time; 777 u16 active_scan_time;
772 u16 passive_scan_time; 778 u16 passive_scan_time;
779 u16 scan_chan_gap_time;
773 u8 fw_bands; 780 u8 fw_bands;
774 u8 adhoc_start_band; 781 u8 adhoc_start_band;
775 u8 config_bands; 782 u8 config_bands;
@@ -815,8 +822,6 @@ struct mwifiex_adapter {
815 spinlock_t queue_lock; /* lock for tx queues */ 822 spinlock_t queue_lock; /* lock for tx queues */
816 u8 country_code[IEEE80211_COUNTRY_STRING_LEN]; 823 u8 country_code[IEEE80211_COUNTRY_STRING_LEN];
817 u16 max_mgmt_ie_index; 824 u16 max_mgmt_ie_index;
818 u8 scan_delay_cnt;
819 u8 empty_tx_q_cnt;
820 const struct firmware *cal_data; 825 const struct firmware *cal_data;
821 struct device_node *dt_node; 826 struct device_node *dt_node;
822 827
@@ -828,7 +833,6 @@ struct mwifiex_adapter {
828 u32 usr_dot_11ac_dev_cap_a; 833 u32 usr_dot_11ac_dev_cap_a;
829 u32 usr_dot_11ac_mcs_support; 834 u32 usr_dot_11ac_mcs_support;
830 835
831 atomic_t is_tx_received;
832 atomic_t pending_bridged_pkts; 836 atomic_t pending_bridged_pkts;
833 struct semaphore *card_sem; 837 struct semaphore *card_sem;
834 bool ext_scan; 838 bool ext_scan;
@@ -839,6 +843,8 @@ struct mwifiex_adapter {
839 struct memory_type_mapping *mem_type_mapping_tbl; 843 struct memory_type_mapping *mem_type_mapping_tbl;
840 u8 num_mem_types; 844 u8 num_mem_types;
841 u8 curr_mem_idx; 845 u8 curr_mem_idx;
846 bool scan_chan_gap_enabled;
847 struct sk_buff_head rx_data_q;
842}; 848};
843 849
844int mwifiex_init_lock_list(struct mwifiex_adapter *adapter); 850int mwifiex_init_lock_list(struct mwifiex_adapter *adapter);
@@ -1139,6 +1145,25 @@ mwifiex_11h_get_csa_closed_channel(struct mwifiex_private *priv)
1139 return priv->csa_chan; 1145 return priv->csa_chan;
1140} 1146}
1141 1147
1148static inline u8 mwifiex_is_any_intf_active(struct mwifiex_private *priv)
1149{
1150 struct mwifiex_private *priv_num;
1151 int i;
1152
1153 for (i = 0; i < priv->adapter->priv_num; i++) {
1154 priv_num = priv->adapter->priv[i];
1155 if (priv_num) {
1156 if ((GET_BSS_ROLE(priv_num) == MWIFIEX_BSS_ROLE_UAP &&
1157 priv_num->bss_started) ||
1158 (GET_BSS_ROLE(priv_num) == MWIFIEX_BSS_ROLE_STA &&
1159 priv_num->media_connected))
1160 return 1;
1161 }
1162 }
1163
1164 return 0;
1165}
1166
1142int mwifiex_init_shutdown_fw(struct mwifiex_private *priv, 1167int mwifiex_init_shutdown_fw(struct mwifiex_private *priv,
1143 u32 func_init_shutdown); 1168 u32 func_init_shutdown);
1144int mwifiex_add_card(void *, struct semaphore *, struct mwifiex_if_ops *, u8); 1169int mwifiex_add_card(void *, struct semaphore *, struct mwifiex_if_ops *, u8);
@@ -1274,6 +1299,7 @@ void mwifiex_disable_all_tdls_links(struct mwifiex_private *priv);
1274bool mwifiex_is_bss_in_11ac_mode(struct mwifiex_private *priv); 1299bool mwifiex_is_bss_in_11ac_mode(struct mwifiex_private *priv);
1275u8 mwifiex_get_center_freq_index(struct mwifiex_private *priv, u8 band, 1300u8 mwifiex_get_center_freq_index(struct mwifiex_private *priv, u8 band,
1276 u32 pri_chan, u8 chan_bw); 1301 u32 pri_chan, u8 chan_bw);
1302int mwifiex_init_channel_scan_gap(struct mwifiex_adapter *adapter);
1277 1303
1278#ifdef CONFIG_DEBUG_FS 1304#ifdef CONFIG_DEBUG_FS
1279void mwifiex_debugfs_init(void); 1305void mwifiex_debugfs_init(void);
diff --git a/drivers/net/wireless/mwifiex/pcie.c b/drivers/net/wireless/mwifiex/pcie.c
index ff0545888dd0..1504b16e248e 100644
--- a/drivers/net/wireless/mwifiex/pcie.c
+++ b/drivers/net/wireless/mwifiex/pcie.c
@@ -1233,6 +1233,7 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
1233 struct sk_buff *skb_tmp = NULL; 1233 struct sk_buff *skb_tmp = NULL;
1234 struct mwifiex_pcie_buf_desc *desc; 1234 struct mwifiex_pcie_buf_desc *desc;
1235 struct mwifiex_pfu_buf_desc *desc2; 1235 struct mwifiex_pfu_buf_desc *desc2;
1236 unsigned long flags;
1236 1237
1237 if (!mwifiex_pcie_ok_to_access_hw(adapter)) 1238 if (!mwifiex_pcie_ok_to_access_hw(adapter))
1238 mwifiex_pm_wakeup_card(adapter); 1239 mwifiex_pm_wakeup_card(adapter);
@@ -1271,12 +1272,29 @@ static int mwifiex_pcie_process_recv_data(struct mwifiex_adapter *adapter)
1271 */ 1272 */
1272 pkt_len = *((__le16 *)skb_data->data); 1273 pkt_len = *((__le16 *)skb_data->data);
1273 rx_len = le16_to_cpu(pkt_len); 1274 rx_len = le16_to_cpu(pkt_len);
1274 skb_put(skb_data, rx_len); 1275 if (WARN_ON(rx_len <= INTF_HEADER_LEN ||
1275 dev_dbg(adapter->dev, 1276 rx_len > MWIFIEX_RX_DATA_BUF_SIZE)) {
1276 "info: RECV DATA: Rd=%#x, Wr=%#x, Len=%d\n", 1277 dev_err(adapter->dev,
1277 card->rxbd_rdptr, wrptr, rx_len); 1278 "Invalid RX len %d, Rd=%#x, Wr=%#x\n",
1278 skb_pull(skb_data, INTF_HEADER_LEN); 1279 rx_len, card->rxbd_rdptr, wrptr);
1279 mwifiex_handle_rx_packet(adapter, skb_data); 1280 dev_kfree_skb_any(skb_data);
1281 } else {
1282 skb_put(skb_data, rx_len);
1283 dev_dbg(adapter->dev,
1284 "info: RECV DATA: Rd=%#x, Wr=%#x, Len=%d\n",
1285 card->rxbd_rdptr, wrptr, rx_len);
1286 skb_pull(skb_data, INTF_HEADER_LEN);
1287 if (adapter->rx_work_enabled) {
1288 spin_lock_irqsave(&adapter->rx_q_lock, flags);
1289 skb_queue_tail(&adapter->rx_data_q, skb_data);
1290 spin_unlock_irqrestore(&adapter->rx_q_lock,
1291 flags);
1292 adapter->data_received = true;
1293 atomic_inc(&adapter->rx_pending);
1294 } else {
1295 mwifiex_handle_rx_packet(adapter, skb_data);
1296 }
1297 }
1280 1298
1281 skb_tmp = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE); 1299 skb_tmp = dev_alloc_skb(MWIFIEX_RX_DATA_BUF_SIZE);
1282 if (!skb_tmp) { 1300 if (!skb_tmp) {
@@ -1718,6 +1736,13 @@ static int mwifiex_pcie_process_event_ready(struct mwifiex_adapter *adapter)
1718 buffer is released. This is just to make things simpler, 1736 buffer is released. This is just to make things simpler,
1719 we need to find a better method of managing these buffers. 1737 we need to find a better method of managing these buffers.
1720 */ 1738 */
1739 } else {
1740 if (mwifiex_write_reg(adapter, PCIE_CPU_INT_EVENT,
1741 CPU_INTR_EVENT_DONE)) {
1742 dev_warn(adapter->dev,
1743 "Write register failed\n");
1744 return -1;
1745 }
1721 } 1746 }
1722 1747
1723 return 0; 1748 return 0;
diff --git a/drivers/net/wireless/mwifiex/pcie.h b/drivers/net/wireless/mwifiex/pcie.h
index a1a8fd3bc1be..200e8b0cb582 100644
--- a/drivers/net/wireless/mwifiex/pcie.h
+++ b/drivers/net/wireless/mwifiex/pcie.h
@@ -40,8 +40,8 @@
40#define MWIFIEX_TXBD_MASK 0x3F 40#define MWIFIEX_TXBD_MASK 0x3F
41#define MWIFIEX_RXBD_MASK 0x3F 41#define MWIFIEX_RXBD_MASK 0x3F
42 42
43#define MWIFIEX_MAX_EVT_BD 0x04 43#define MWIFIEX_MAX_EVT_BD 0x08
44#define MWIFIEX_EVTBD_MASK 0x07 44#define MWIFIEX_EVTBD_MASK 0x0f
45 45
46/* PCIE INTERNAL REGISTERS */ 46/* PCIE INTERNAL REGISTERS */
47#define PCIE_SCRATCH_0_REG 0xC10 47#define PCIE_SCRATCH_0_REG 0xC10
@@ -69,6 +69,7 @@
69#define CPU_INTR_DOOR_BELL BIT(1) 69#define CPU_INTR_DOOR_BELL BIT(1)
70#define CPU_INTR_SLEEP_CFM_DONE BIT(2) 70#define CPU_INTR_SLEEP_CFM_DONE BIT(2)
71#define CPU_INTR_RESET BIT(3) 71#define CPU_INTR_RESET BIT(3)
72#define CPU_INTR_EVENT_DONE BIT(5)
72 73
73#define HOST_INTR_DNLD_DONE BIT(0) 74#define HOST_INTR_DNLD_DONE BIT(0)
74#define HOST_INTR_UPLD_RDY BIT(1) 75#define HOST_INTR_UPLD_RDY BIT(1)
diff --git a/drivers/net/wireless/mwifiex/scan.c b/drivers/net/wireless/mwifiex/scan.c
index 195ef0ca343f..c09ebeee6ddf 100644
--- a/drivers/net/wireless/mwifiex/scan.c
+++ b/drivers/net/wireless/mwifiex/scan.c
@@ -799,6 +799,7 @@ mwifiex_config_scan(struct mwifiex_private *priv,
799{ 799{
800 struct mwifiex_adapter *adapter = priv->adapter; 800 struct mwifiex_adapter *adapter = priv->adapter;
801 struct mwifiex_ie_types_num_probes *num_probes_tlv; 801 struct mwifiex_ie_types_num_probes *num_probes_tlv;
802 struct mwifiex_ie_types_scan_chan_gap *chan_gap_tlv;
802 struct mwifiex_ie_types_wildcard_ssid_params *wildcard_ssid_tlv; 803 struct mwifiex_ie_types_wildcard_ssid_params *wildcard_ssid_tlv;
803 struct mwifiex_ie_types_bssid_list *bssid_tlv; 804 struct mwifiex_ie_types_bssid_list *bssid_tlv;
804 u8 *tlv_pos; 805 u8 *tlv_pos;
@@ -939,6 +940,22 @@ mwifiex_config_scan(struct mwifiex_private *priv,
939 else 940 else
940 *max_chan_per_scan = MWIFIEX_DEF_CHANNELS_PER_SCAN_CMD; 941 *max_chan_per_scan = MWIFIEX_DEF_CHANNELS_PER_SCAN_CMD;
941 942
943 if (user_scan_in->scan_chan_gap) {
944 *max_chan_per_scan = MWIFIEX_MAX_CHANNELS_PER_SPECIFIC_SCAN;
945 dev_dbg(adapter->dev, "info: scan: channel gap = %d\n",
946 user_scan_in->scan_chan_gap);
947
948 chan_gap_tlv = (void *)tlv_pos;
949 chan_gap_tlv->header.type =
950 cpu_to_le16(TLV_TYPE_SCAN_CHANNEL_GAP);
951 chan_gap_tlv->header.len =
952 cpu_to_le16(sizeof(chan_gap_tlv->chan_gap));
953 chan_gap_tlv->chan_gap =
954 cpu_to_le16((user_scan_in->scan_chan_gap));
955
956 tlv_pos += sizeof(struct mwifiex_ie_types_scan_chan_gap);
957 }
958
942 /* If the input config or adapter has the number of Probes set, 959 /* If the input config or adapter has the number of Probes set,
943 add tlv */ 960 add tlv */
944 if (num_probes) { 961 if (num_probes) {
@@ -1050,12 +1067,6 @@ mwifiex_config_scan(struct mwifiex_private *priv,
1050 *filtered_scan); 1067 *filtered_scan);
1051 } 1068 }
1052 1069
1053 /*
1054 * In associated state we will reduce the number of channels scanned per
1055 * scan command to 1 to avoid any traffic delay/loss.
1056 */
1057 if (priv->media_connected)
1058 *max_chan_per_scan = 1;
1059} 1070}
1060 1071
1061/* 1072/*
@@ -1755,7 +1766,7 @@ static void mwifiex_complete_scan(struct mwifiex_private *priv)
1755static void mwifiex_check_next_scan_command(struct mwifiex_private *priv) 1766static void mwifiex_check_next_scan_command(struct mwifiex_private *priv)
1756{ 1767{
1757 struct mwifiex_adapter *adapter = priv->adapter; 1768 struct mwifiex_adapter *adapter = priv->adapter;
1758 struct cmd_ctrl_node *cmd_node; 1769 struct cmd_ctrl_node *cmd_node, *tmp_node;
1759 unsigned long flags; 1770 unsigned long flags;
1760 1771
1761 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags); 1772 spin_lock_irqsave(&adapter->scan_pending_q_lock, flags);
@@ -1768,9 +1779,6 @@ static void mwifiex_check_next_scan_command(struct mwifiex_private *priv)
1768 if (!adapter->ext_scan) 1779 if (!adapter->ext_scan)
1769 mwifiex_complete_scan(priv); 1780 mwifiex_complete_scan(priv);
1770 1781
1771 if (priv->report_scan_result)
1772 priv->report_scan_result = false;
1773
1774 if (priv->scan_request) { 1782 if (priv->scan_request) {
1775 dev_dbg(adapter->dev, "info: notifying scan done\n"); 1783 dev_dbg(adapter->dev, "info: notifying scan done\n");
1776 cfg80211_scan_done(priv->scan_request, 0); 1784 cfg80211_scan_done(priv->scan_request, 0);
@@ -1779,37 +1787,36 @@ static void mwifiex_check_next_scan_command(struct mwifiex_private *priv)
1779 priv->scan_aborting = false; 1787 priv->scan_aborting = false;
1780 dev_dbg(adapter->dev, "info: scan already aborted\n"); 1788 dev_dbg(adapter->dev, "info: scan already aborted\n");
1781 } 1789 }
1782 } else { 1790 } else if ((priv->scan_aborting && !priv->scan_request) ||
1783 if ((priv->scan_aborting && !priv->scan_request) || 1791 priv->scan_block) {
1784 priv->scan_block) { 1792 list_for_each_entry_safe(cmd_node, tmp_node,
1785 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, 1793 &adapter->scan_pending_q, list) {
1786 flags);
1787 adapter->scan_delay_cnt = MWIFIEX_MAX_SCAN_DELAY_CNT;
1788 mod_timer(&priv->scan_delay_timer, jiffies);
1789 dev_dbg(priv->adapter->dev,
1790 "info: %s: triggerring scan abort\n", __func__);
1791 } else if (!mwifiex_wmm_lists_empty(adapter) &&
1792 (priv->scan_request && (priv->scan_request->flags &
1793 NL80211_SCAN_FLAG_LOW_PRIORITY))) {
1794 spin_unlock_irqrestore(&adapter->scan_pending_q_lock,
1795 flags);
1796 adapter->scan_delay_cnt = 1;
1797 mod_timer(&priv->scan_delay_timer, jiffies +
1798 msecs_to_jiffies(MWIFIEX_SCAN_DELAY_MSEC));
1799 dev_dbg(priv->adapter->dev,
1800 "info: %s: deferring scan\n", __func__);
1801 } else {
1802 /* Get scan command from scan_pending_q and put to
1803 * cmd_pending_q
1804 */
1805 cmd_node = list_first_entry(&adapter->scan_pending_q,
1806 struct cmd_ctrl_node, list);
1807 list_del(&cmd_node->list); 1794 list_del(&cmd_node->list);
1808 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, 1795 mwifiex_insert_cmd_to_free_q(adapter, cmd_node);
1809 flags);
1810 mwifiex_insert_cmd_to_pending_q(adapter, cmd_node,
1811 true);
1812 } 1796 }
1797 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
1798
1799 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
1800 adapter->scan_processing = false;
1801 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
1802
1803 if (priv->scan_request) {
1804 dev_dbg(adapter->dev, "info: aborting scan\n");
1805 cfg80211_scan_done(priv->scan_request, 1);
1806 priv->scan_request = NULL;
1807 } else {
1808 priv->scan_aborting = false;
1809 dev_dbg(adapter->dev, "info: scan already aborted\n");
1810 }
1811 } else {
1812 /* Get scan command from scan_pending_q and put to
1813 * cmd_pending_q
1814 */
1815 cmd_node = list_first_entry(&adapter->scan_pending_q,
1816 struct cmd_ctrl_node, list);
1817 list_del(&cmd_node->list);
1818 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, flags);
1819 mwifiex_insert_cmd_to_pending_q(adapter, cmd_node, true);
1813 } 1820 }
1814 1821
1815 return; 1822 return;
@@ -1971,9 +1978,34 @@ int mwifiex_cmd_802_11_scan_ext(struct mwifiex_private *priv,
1971/* This function handles the command response of extended scan */ 1978/* This function handles the command response of extended scan */
1972int mwifiex_ret_802_11_scan_ext(struct mwifiex_private *priv) 1979int mwifiex_ret_802_11_scan_ext(struct mwifiex_private *priv)
1973{ 1980{
1981 struct mwifiex_adapter *adapter = priv->adapter;
1982 struct host_cmd_ds_command *cmd_ptr;
1983 struct cmd_ctrl_node *cmd_node;
1984 unsigned long cmd_flags, scan_flags;
1985 bool complete_scan = false;
1986
1974 dev_dbg(priv->adapter->dev, "info: EXT scan returns successfully\n"); 1987 dev_dbg(priv->adapter->dev, "info: EXT scan returns successfully\n");
1975 1988
1976 mwifiex_complete_scan(priv); 1989 spin_lock_irqsave(&adapter->cmd_pending_q_lock, cmd_flags);
1990 spin_lock_irqsave(&adapter->scan_pending_q_lock, scan_flags);
1991 if (list_empty(&adapter->scan_pending_q)) {
1992 complete_scan = true;
1993 list_for_each_entry(cmd_node, &adapter->cmd_pending_q, list) {
1994 cmd_ptr = (void *)cmd_node->cmd_skb->data;
1995 if (le16_to_cpu(cmd_ptr->command) ==
1996 HostCmd_CMD_802_11_SCAN_EXT) {
1997 dev_dbg(priv->adapter->dev,
1998 "Scan pending in command pending list");
1999 complete_scan = false;
2000 break;
2001 }
2002 }
2003 }
2004 spin_unlock_irqrestore(&adapter->scan_pending_q_lock, scan_flags);
2005 spin_unlock_irqrestore(&adapter->cmd_pending_q_lock, cmd_flags);
2006
2007 if (complete_scan)
2008 mwifiex_complete_scan(priv);
1977 2009
1978 return 0; 2010 return 0;
1979} 2011}
diff --git a/drivers/net/wireless/mwifiex/sdio.c b/drivers/net/wireless/mwifiex/sdio.c
index 1770fa3fc1e6..ea8fc587e90f 100644
--- a/drivers/net/wireless/mwifiex/sdio.c
+++ b/drivers/net/wireless/mwifiex/sdio.c
@@ -622,22 +622,15 @@ static int mwifiex_get_wr_port_data(struct mwifiex_adapter *adapter, u32 *port)
622 622
623 dev_dbg(adapter->dev, "data: mp_wr_bitmap=0x%08x\n", wr_bitmap); 623 dev_dbg(adapter->dev, "data: mp_wr_bitmap=0x%08x\n", wr_bitmap);
624 624
625 if (card->supports_sdio_new_mode && 625 if (!(wr_bitmap & card->mp_data_port_mask)) {
626 !(wr_bitmap & reg->data_port_mask)) {
627 adapter->data_sent = true; 626 adapter->data_sent = true;
628 return -EBUSY; 627 return -EBUSY;
629 } else if (!card->supports_sdio_new_mode &&
630 !(wr_bitmap & card->mp_data_port_mask)) {
631 return -1;
632 } 628 }
633 629
634 if (card->mp_wr_bitmap & (1 << card->curr_wr_port)) { 630 if (card->mp_wr_bitmap & (1 << card->curr_wr_port)) {
635 card->mp_wr_bitmap &= (u32) (~(1 << card->curr_wr_port)); 631 card->mp_wr_bitmap &= (u32) (~(1 << card->curr_wr_port));
636 *port = card->curr_wr_port; 632 *port = card->curr_wr_port;
637 if (((card->supports_sdio_new_mode) && 633 if (++card->curr_wr_port == card->mp_end_port)
638 (++card->curr_wr_port == card->max_ports)) ||
639 ((!card->supports_sdio_new_mode) &&
640 (++card->curr_wr_port == card->mp_end_port)))
641 card->curr_wr_port = reg->start_wr_port; 634 card->curr_wr_port = reg->start_wr_port;
642 } else { 635 } else {
643 adapter->data_sent = true; 636 adapter->data_sent = true;
@@ -1046,6 +1039,7 @@ static int mwifiex_decode_rx_packet(struct mwifiex_adapter *adapter,
1046 struct sk_buff *skb, u32 upld_typ) 1039 struct sk_buff *skb, u32 upld_typ)
1047{ 1040{
1048 u8 *cmd_buf; 1041 u8 *cmd_buf;
1042 unsigned long flags;
1049 __le16 *curr_ptr = (__le16 *)skb->data; 1043 __le16 *curr_ptr = (__le16 *)skb->data;
1050 u16 pkt_len = le16_to_cpu(*curr_ptr); 1044 u16 pkt_len = le16_to_cpu(*curr_ptr);
1051 1045
@@ -1055,7 +1049,15 @@ static int mwifiex_decode_rx_packet(struct mwifiex_adapter *adapter,
1055 switch (upld_typ) { 1049 switch (upld_typ) {
1056 case MWIFIEX_TYPE_DATA: 1050 case MWIFIEX_TYPE_DATA:
1057 dev_dbg(adapter->dev, "info: --- Rx: Data packet ---\n"); 1051 dev_dbg(adapter->dev, "info: --- Rx: Data packet ---\n");
1058 mwifiex_handle_rx_packet(adapter, skb); 1052 if (adapter->rx_work_enabled) {
1053 spin_lock_irqsave(&adapter->rx_q_lock, flags);
1054 skb_queue_tail(&adapter->rx_data_q, skb);
1055 spin_unlock_irqrestore(&adapter->rx_q_lock, flags);
1056 adapter->data_received = true;
1057 atomic_inc(&adapter->rx_pending);
1058 } else {
1059 mwifiex_handle_rx_packet(adapter, skb);
1060 }
1059 break; 1061 break;
1060 1062
1061 case MWIFIEX_TYPE_CMD: 1063 case MWIFIEX_TYPE_CMD:
@@ -1527,8 +1529,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
1527 __func__); 1529 __func__);
1528 1530
1529 if (MP_TX_AGGR_IN_PROGRESS(card)) { 1531 if (MP_TX_AGGR_IN_PROGRESS(card)) {
1530 if (!mp_tx_aggr_port_limit_reached(card) && 1532 if (MP_TX_AGGR_BUF_HAS_ROOM(card, pkt_len)) {
1531 MP_TX_AGGR_BUF_HAS_ROOM(card, pkt_len)) {
1532 f_precopy_cur_buf = 1; 1533 f_precopy_cur_buf = 1;
1533 1534
1534 if (!(card->mp_wr_bitmap & 1535 if (!(card->mp_wr_bitmap &
@@ -1540,8 +1541,7 @@ static int mwifiex_host_to_card_mp_aggr(struct mwifiex_adapter *adapter,
1540 /* No room in Aggr buf, send it */ 1541 /* No room in Aggr buf, send it */
1541 f_send_aggr_buf = 1; 1542 f_send_aggr_buf = 1;
1542 1543
1543 if (mp_tx_aggr_port_limit_reached(card) || 1544 if (!(card->mp_wr_bitmap &
1544 !(card->mp_wr_bitmap &
1545 (1 << card->curr_wr_port))) 1545 (1 << card->curr_wr_port)))
1546 f_send_cur_buf = 1; 1546 f_send_cur_buf = 1;
1547 else 1547 else
diff --git a/drivers/net/wireless/mwifiex/sta_cmdresp.c b/drivers/net/wireless/mwifiex/sta_cmdresp.c
index 62866b0f0830..4aad44685f8d 100644
--- a/drivers/net/wireless/mwifiex/sta_cmdresp.c
+++ b/drivers/net/wireless/mwifiex/sta_cmdresp.c
@@ -85,8 +85,6 @@ mwifiex_process_cmdresp_error(struct mwifiex_private *priv,
85 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags); 85 spin_lock_irqsave(&adapter->mwifiex_cmd_lock, flags);
86 adapter->scan_processing = false; 86 adapter->scan_processing = false;
87 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags); 87 spin_unlock_irqrestore(&adapter->mwifiex_cmd_lock, flags);
88 if (priv->report_scan_result)
89 priv->report_scan_result = false;
90 break; 88 break;
91 89
92 case HostCmd_CMD_MAC_CONTROL: 90 case HostCmd_CMD_MAC_CONTROL:
diff --git a/drivers/net/wireless/mwifiex/sta_ioctl.c b/drivers/net/wireless/mwifiex/sta_ioctl.c
index b95a29b868d1..92f3eb839866 100644
--- a/drivers/net/wireless/mwifiex/sta_ioctl.c
+++ b/drivers/net/wireless/mwifiex/sta_ioctl.c
@@ -287,10 +287,13 @@ int mwifiex_bss_start(struct mwifiex_private *priv, struct cfg80211_bss *bss,
287 return -1; 287 return -1;
288 288
289 if (mwifiex_band_to_radio_type(bss_desc->bss_band) == 289 if (mwifiex_band_to_radio_type(bss_desc->bss_band) ==
290 HostCmd_SCAN_RADIO_TYPE_BG) 290 HostCmd_SCAN_RADIO_TYPE_BG) {
291 config_bands = BAND_B | BAND_G | BAND_GN; 291 config_bands = BAND_B | BAND_G | BAND_GN;
292 else 292 } else {
293 config_bands = BAND_A | BAND_AN | BAND_AAC; 293 config_bands = BAND_A | BAND_AN;
294 if (adapter->fw_bands & BAND_AAC)
295 config_bands |= BAND_AAC;
296 }
294 297
295 if (!((config_bands | adapter->fw_bands) & ~adapter->fw_bands)) 298 if (!((config_bands | adapter->fw_bands) & ~adapter->fw_bands))
296 adapter->config_bands = config_bands; 299 adapter->config_bands = config_bands;
diff --git a/drivers/net/wireless/mwifiex/tdls.c b/drivers/net/wireless/mwifiex/tdls.c
index 4c5fd953893d..e2949077f5b5 100644
--- a/drivers/net/wireless/mwifiex/tdls.c
+++ b/drivers/net/wireless/mwifiex/tdls.c
@@ -871,7 +871,9 @@ void mwifiex_process_tdls_action_frame(struct mwifiex_private *priv,
871 break; 871 break;
872 case WLAN_EID_RSN: 872 case WLAN_EID_RSN:
873 memcpy((u8 *)&sta_ptr->tdls_cap.rsn_ie, pos, 873 memcpy((u8 *)&sta_ptr->tdls_cap.rsn_ie, pos,
874 sizeof(struct ieee_types_header) + pos[1]); 874 sizeof(struct ieee_types_header) +
875 min_t(u8, pos[1], IEEE_MAX_IE_SIZE -
876 sizeof(struct ieee_types_header)));
875 break; 877 break;
876 case WLAN_EID_QOS_CAPA: 878 case WLAN_EID_QOS_CAPA:
877 sta_ptr->tdls_cap.qos_info = pos[2]; 879 sta_ptr->tdls_cap.qos_info = pos[2];
diff --git a/drivers/net/wireless/p54/main.c b/drivers/net/wireless/p54/main.c
index 7be3a4839640..97aeff0edb84 100644
--- a/drivers/net/wireless/p54/main.c
+++ b/drivers/net/wireless/p54/main.c
@@ -696,7 +696,8 @@ static void p54_flush(struct ieee80211_hw *dev, struct ieee80211_vif *vif,
696 WARN(total, "tx flush timeout, unresponsive firmware"); 696 WARN(total, "tx flush timeout, unresponsive firmware");
697} 697}
698 698
699static void p54_set_coverage_class(struct ieee80211_hw *dev, u8 coverage_class) 699static void p54_set_coverage_class(struct ieee80211_hw *dev,
700 s16 coverage_class)
700{ 701{
701 struct p54_common *priv = dev->priv; 702 struct p54_common *priv = dev->priv;
702 703
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbt_precomp.h b/drivers/net/wireless/rtlwifi/btcoexist/halbt_precomp.h
index d76684eb24d0..39b9a3309cfd 100644
--- a/drivers/net/wireless/rtlwifi/btcoexist/halbt_precomp.h
+++ b/drivers/net/wireless/rtlwifi/btcoexist/halbt_precomp.h
@@ -37,7 +37,13 @@
37 37
38#include "halbtcoutsrc.h" 38#include "halbtcoutsrc.h"
39 39
40#include "halbtc8192e2ant.h"
41#include "halbtc8723b1ant.h"
40#include "halbtc8723b2ant.h" 42#include "halbtc8723b2ant.h"
43#include "halbtc8821a2ant.h"
44#include "halbtc8821a1ant.h"
45
46#define GetDefaultAdapter(padapter) padapter
41 47
42#define BIT0 0x00000001 48#define BIT0 0x00000001
43#define BIT1 0x00000002 49#define BIT1 0x00000002
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8192e2ant.c b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8192e2ant.c
new file mode 100644
index 000000000000..53261d6f8578
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8192e2ant.c
@@ -0,0 +1,3849 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2012 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25/**************************************************************
26 * Description:
27 *
28 * This file is for RTL8192E Co-exist mechanism
29 *
30 * History
31 * 2012/11/15 Cosa first check in.
32 *
33 **************************************************************/
34
35/**************************************************************
36 * include files
37 **************************************************************/
38#include "halbt_precomp.h"
39/**************************************************************
40 * Global variables, these are static variables
41 **************************************************************/
42static struct coex_dm_8192e_2ant glcoex_dm_8192e_2ant;
43static struct coex_dm_8192e_2ant *coex_dm = &glcoex_dm_8192e_2ant;
44static struct coex_sta_8192e_2ant glcoex_sta_8192e_2ant;
45static struct coex_sta_8192e_2ant *coex_sta = &glcoex_sta_8192e_2ant;
46
47static const char *const GLBtInfoSrc8192e2Ant[] = {
48 "BT Info[wifi fw]",
49 "BT Info[bt rsp]",
50 "BT Info[bt auto report]",
51};
52
53static u32 glcoex_ver_date_8192e_2ant = 20130902;
54static u32 glcoex_ver_8192e_2ant = 0x34;
55
56/**************************************************************
57 * local function proto type if needed
58 **************************************************************/
59/**************************************************************
60 * local function start with halbtc8192e2ant_
61 **************************************************************/
62static u8 halbtc8192e2ant_btrssi_state(u8 level_num, u8 rssi_thresh,
63 u8 rssi_thresh1)
64{
65 int btrssi = 0;
66 u8 btrssi_state = coex_sta->pre_bt_rssi_state;
67
68 btrssi = coex_sta->bt_rssi;
69
70 if (level_num == 2) {
71 if ((coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_LOW) ||
72 (coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) {
73 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
74 "BT Rssi pre state = LOW\n");
75 if (btrssi >= (rssi_thresh +
76 BTC_RSSI_COEX_THRESH_TOL_8192E_2ANT)) {
77 btrssi_state = BTC_RSSI_STATE_HIGH;
78 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
79 "BT Rssi state switch to High\n");
80 } else {
81 btrssi_state = BTC_RSSI_STATE_STAY_LOW;
82 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
83 "BT Rssi state stay at Low\n");
84 }
85 } else {
86 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
87 "BT Rssi pre state = HIGH\n");
88 if (btrssi < rssi_thresh) {
89 btrssi_state = BTC_RSSI_STATE_LOW;
90 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
91 "BT Rssi state switch to Low\n");
92 } else {
93 btrssi_state = BTC_RSSI_STATE_STAY_HIGH;
94 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
95 "BT Rssi state stay at High\n");
96 }
97 }
98 } else if (level_num == 3) {
99 if (rssi_thresh > rssi_thresh1) {
100 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
101 "BT Rssi thresh error!!\n");
102 return coex_sta->pre_bt_rssi_state;
103 }
104
105 if ((coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_LOW) ||
106 (coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) {
107 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
108 "BT Rssi pre state = LOW\n");
109 if (btrssi >= (rssi_thresh +
110 BTC_RSSI_COEX_THRESH_TOL_8192E_2ANT)) {
111 btrssi_state = BTC_RSSI_STATE_MEDIUM;
112 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
113 "BT Rssi state switch to Medium\n");
114 } else {
115 btrssi_state = BTC_RSSI_STATE_STAY_LOW;
116 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
117 "BT Rssi state stay at Low\n");
118 }
119 } else if ((coex_sta->pre_bt_rssi_state ==
120 BTC_RSSI_STATE_MEDIUM) ||
121 (coex_sta->pre_bt_rssi_state ==
122 BTC_RSSI_STATE_STAY_MEDIUM)) {
123 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
124 "[BTCoex], BT Rssi pre state = MEDIUM\n");
125 if (btrssi >= (rssi_thresh1 +
126 BTC_RSSI_COEX_THRESH_TOL_8192E_2ANT)) {
127 btrssi_state = BTC_RSSI_STATE_HIGH;
128 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
129 "BT Rssi state switch to High\n");
130 } else if (btrssi < rssi_thresh) {
131 btrssi_state = BTC_RSSI_STATE_LOW;
132 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
133 "BT Rssi state switch to Low\n");
134 } else {
135 btrssi_state = BTC_RSSI_STATE_STAY_MEDIUM;
136 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
137 "BT Rssi state stay at Medium\n");
138 }
139 } else {
140 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
141 "BT Rssi pre state = HIGH\n");
142 if (btrssi < rssi_thresh1) {
143 btrssi_state = BTC_RSSI_STATE_MEDIUM;
144 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
145 "BT Rssi state switch to Medium\n");
146 } else {
147 btrssi_state = BTC_RSSI_STATE_STAY_HIGH;
148 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
149 "BT Rssi state stay at High\n");
150 }
151 }
152 }
153
154 coex_sta->pre_bt_rssi_state = btrssi_state;
155
156 return btrssi_state;
157}
158
159static u8 halbtc8192e2ant_wifirssi_state(struct btc_coexist *btcoexist,
160 u8 index, u8 level_num, u8 rssi_thresh,
161 u8 rssi_thresh1)
162{
163 int wifirssi = 0;
164 u8 wifirssi_state = coex_sta->pre_wifi_rssi_state[index];
165
166 btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifirssi);
167
168 if (level_num == 2) {
169 if ((coex_sta->pre_wifi_rssi_state[index] ==
170 BTC_RSSI_STATE_LOW) ||
171 (coex_sta->pre_wifi_rssi_state[index] ==
172 BTC_RSSI_STATE_STAY_LOW)) {
173 if (wifirssi >= (rssi_thresh +
174 BTC_RSSI_COEX_THRESH_TOL_8192E_2ANT)) {
175 wifirssi_state = BTC_RSSI_STATE_HIGH;
176 BTC_PRINT(BTC_MSG_ALGORITHM,
177 ALGO_WIFI_RSSI_STATE,
178 "wifi RSSI state switch to High\n");
179 } else {
180 wifirssi_state = BTC_RSSI_STATE_STAY_LOW;
181 BTC_PRINT(BTC_MSG_ALGORITHM,
182 ALGO_WIFI_RSSI_STATE,
183 "wifi RSSI state stay at Low\n");
184 }
185 } else {
186 if (wifirssi < rssi_thresh) {
187 wifirssi_state = BTC_RSSI_STATE_LOW;
188 BTC_PRINT(BTC_MSG_ALGORITHM,
189 ALGO_WIFI_RSSI_STATE,
190 "wifi RSSI state switch to Low\n");
191 } else {
192 wifirssi_state = BTC_RSSI_STATE_STAY_HIGH;
193 BTC_PRINT(BTC_MSG_ALGORITHM,
194 ALGO_WIFI_RSSI_STATE,
195 "wifi RSSI state stay at High\n");
196 }
197 }
198 } else if (level_num == 3) {
199 if (rssi_thresh > rssi_thresh1) {
200 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE,
201 "wifi RSSI thresh error!!\n");
202 return coex_sta->pre_wifi_rssi_state[index];
203 }
204
205 if ((coex_sta->pre_wifi_rssi_state[index] ==
206 BTC_RSSI_STATE_LOW) ||
207 (coex_sta->pre_wifi_rssi_state[index] ==
208 BTC_RSSI_STATE_STAY_LOW)) {
209 if (wifirssi >= (rssi_thresh +
210 BTC_RSSI_COEX_THRESH_TOL_8192E_2ANT)) {
211 wifirssi_state = BTC_RSSI_STATE_MEDIUM;
212 BTC_PRINT(BTC_MSG_ALGORITHM,
213 ALGO_WIFI_RSSI_STATE,
214 "wifi RSSI state switch to Medium\n");
215 } else {
216 wifirssi_state = BTC_RSSI_STATE_STAY_LOW;
217 BTC_PRINT(BTC_MSG_ALGORITHM,
218 ALGO_WIFI_RSSI_STATE,
219 "wifi RSSI state stay at Low\n");
220 }
221 } else if ((coex_sta->pre_wifi_rssi_state[index] ==
222 BTC_RSSI_STATE_MEDIUM) ||
223 (coex_sta->pre_wifi_rssi_state[index] ==
224 BTC_RSSI_STATE_STAY_MEDIUM)) {
225 if (wifirssi >= (rssi_thresh1 +
226 BTC_RSSI_COEX_THRESH_TOL_8192E_2ANT)) {
227 wifirssi_state = BTC_RSSI_STATE_HIGH;
228 BTC_PRINT(BTC_MSG_ALGORITHM,
229 ALGO_WIFI_RSSI_STATE,
230 "wifi RSSI state switch to High\n");
231 } else if (wifirssi < rssi_thresh) {
232 wifirssi_state = BTC_RSSI_STATE_LOW;
233 BTC_PRINT(BTC_MSG_ALGORITHM,
234 ALGO_WIFI_RSSI_STATE,
235 "wifi RSSI state switch to Low\n");
236 } else {
237 wifirssi_state = BTC_RSSI_STATE_STAY_MEDIUM;
238 BTC_PRINT(BTC_MSG_ALGORITHM,
239 ALGO_WIFI_RSSI_STATE,
240 "wifi RSSI state stay at Medium\n");
241 }
242 } else {
243 if (wifirssi < rssi_thresh1) {
244 wifirssi_state = BTC_RSSI_STATE_MEDIUM;
245 BTC_PRINT(BTC_MSG_ALGORITHM,
246 ALGO_WIFI_RSSI_STATE,
247 "wifi RSSI state switch to Medium\n");
248 } else {
249 wifirssi_state = BTC_RSSI_STATE_STAY_HIGH;
250 BTC_PRINT(BTC_MSG_ALGORITHM,
251 ALGO_WIFI_RSSI_STATE,
252 "wifi RSSI state stay at High\n");
253 }
254 }
255 }
256
257 coex_sta->pre_wifi_rssi_state[index] = wifirssi_state;
258
259 return wifirssi_state;
260}
261
262static void btc8192e2ant_monitor_bt_enable_dis(struct btc_coexist *btcoexist)
263{
264 static bool pre_bt_disabled;
265 static u32 bt_disable_cnt;
266 bool bt_active = true, bt_disabled = false;
267
268 /* This function check if bt is disabled */
269
270 if (coex_sta->high_priority_tx == 0 &&
271 coex_sta->high_priority_rx == 0 &&
272 coex_sta->low_priority_tx == 0 &&
273 coex_sta->low_priority_rx == 0)
274 bt_active = false;
275
276 if (coex_sta->high_priority_tx == 0xffff &&
277 coex_sta->high_priority_rx == 0xffff &&
278 coex_sta->low_priority_tx == 0xffff &&
279 coex_sta->low_priority_rx == 0xffff)
280 bt_active = false;
281
282 if (bt_active) {
283 bt_disable_cnt = 0;
284 bt_disabled = false;
285 btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_DISABLE,
286 &bt_disabled);
287 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR,
288 "[BTCoex], BT is enabled !!\n");
289 } else {
290 bt_disable_cnt++;
291 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR,
292 "[BTCoex], bt all counters = 0, %d times!!\n",
293 bt_disable_cnt);
294 if (bt_disable_cnt >= 2) {
295 bt_disabled = true;
296 btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_DISABLE,
297 &bt_disabled);
298 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR,
299 "[BTCoex], BT is disabled !!\n");
300 }
301 }
302 if (pre_bt_disabled != bt_disabled) {
303 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR,
304 "[BTCoex], BT is from %s to %s!!\n",
305 (pre_bt_disabled ? "disabled" : "enabled"),
306 (bt_disabled ? "disabled" : "enabled"));
307 pre_bt_disabled = bt_disabled;
308 }
309}
310
311static u32 halbtc8192e2ant_decidera_mask(struct btc_coexist *btcoexist,
312 u8 sstype, u32 ra_masktype)
313{
314 u32 disra_mask = 0x0;
315
316 switch (ra_masktype) {
317 case 0: /* normal mode */
318 if (sstype == 2)
319 disra_mask = 0x0; /* enable 2ss */
320 else
321 disra_mask = 0xfff00000;/* disable 2ss */
322 break;
323 case 1: /* disable cck 1/2 */
324 if (sstype == 2)
325 disra_mask = 0x00000003;/* enable 2ss */
326 else
327 disra_mask = 0xfff00003;/* disable 2ss */
328 break;
329 case 2: /* disable cck 1/2/5.5, ofdm 6/9/12/18/24, mcs 0/1/2/3/4 */
330 if (sstype == 2)
331 disra_mask = 0x0001f1f7;/* enable 2ss */
332 else
333 disra_mask = 0xfff1f1f7;/* disable 2ss */
334 break;
335 default:
336 break;
337 }
338
339 return disra_mask;
340}
341
342static void halbtc8192e2ant_Updatera_mask(struct btc_coexist *btcoexist,
343 bool force_exec, u32 dis_ratemask)
344{
345 coex_dm->curra_mask = dis_ratemask;
346
347 if (force_exec || (coex_dm->prera_mask != coex_dm->curra_mask))
348 btcoexist->btc_set(btcoexist, BTC_SET_ACT_UPDATE_ra_mask,
349 &coex_dm->curra_mask);
350 coex_dm->prera_mask = coex_dm->curra_mask;
351}
352
353static void btc8192e2ant_autorate_fallback_retry(struct btc_coexist *btcoexist,
354 bool force_exec, u8 type)
355{
356 bool wifi_under_bmode = false;
357
358 coex_dm->cur_arfrtype = type;
359
360 if (force_exec || (coex_dm->pre_arfrtype != coex_dm->cur_arfrtype)) {
361 switch (coex_dm->cur_arfrtype) {
362 case 0: /* normal mode */
363 btcoexist->btc_write_4byte(btcoexist, 0x430,
364 coex_dm->backup_arfr_cnt1);
365 btcoexist->btc_write_4byte(btcoexist, 0x434,
366 coex_dm->backup_arfr_cnt2);
367 break;
368 case 1:
369 btcoexist->btc_get(btcoexist,
370 BTC_GET_BL_WIFI_UNDER_B_MODE,
371 &wifi_under_bmode);
372 if (wifi_under_bmode) {
373 btcoexist->btc_write_4byte(btcoexist, 0x430,
374 0x0);
375 btcoexist->btc_write_4byte(btcoexist, 0x434,
376 0x01010101);
377 } else {
378 btcoexist->btc_write_4byte(btcoexist, 0x430,
379 0x0);
380 btcoexist->btc_write_4byte(btcoexist, 0x434,
381 0x04030201);
382 }
383 break;
384 default:
385 break;
386 }
387 }
388
389 coex_dm->pre_arfrtype = coex_dm->cur_arfrtype;
390}
391
392static void halbtc8192e2ant_retrylimit(struct btc_coexist *btcoexist,
393 bool force_exec, u8 type)
394{
395 coex_dm->cur_retrylimit_type = type;
396
397 if (force_exec || (coex_dm->pre_retrylimit_type !=
398 coex_dm->cur_retrylimit_type)) {
399 switch (coex_dm->cur_retrylimit_type) {
400 case 0: /* normal mode */
401 btcoexist->btc_write_2byte(btcoexist, 0x42a,
402 coex_dm->backup_retrylimit);
403 break;
404 case 1: /* retry limit = 8 */
405 btcoexist->btc_write_2byte(btcoexist, 0x42a,
406 0x0808);
407 break;
408 default:
409 break;
410 }
411 }
412
413 coex_dm->pre_retrylimit_type = coex_dm->cur_retrylimit_type;
414}
415
416static void halbtc8192e2ant_ampdu_maxtime(struct btc_coexist *btcoexist,
417 bool force_exec, u8 type)
418{
419 coex_dm->cur_ampdutime_type = type;
420
421 if (force_exec || (coex_dm->pre_ampdutime_type !=
422 coex_dm->cur_ampdutime_type)) {
423 switch (coex_dm->cur_ampdutime_type) {
424 case 0: /* normal mode */
425 btcoexist->btc_write_1byte(btcoexist, 0x456,
426 coex_dm->backup_ampdu_maxtime);
427 break;
428 case 1: /* AMPDU timw = 0x38 * 32us */
429 btcoexist->btc_write_1byte(btcoexist, 0x456, 0x38);
430 break;
431 default:
432 break;
433 }
434 }
435
436 coex_dm->pre_ampdutime_type = coex_dm->cur_ampdutime_type;
437}
438
439static void halbtc8192e2ant_limited_tx(struct btc_coexist *btcoexist,
440 bool force_exec, u8 ra_masktype,
441 u8 arfr_type, u8 retrylimit_type,
442 u8 ampdutime_type)
443{
444 u32 disra_mask = 0x0;
445
446 coex_dm->curra_masktype = ra_masktype;
447 disra_mask = halbtc8192e2ant_decidera_mask(btcoexist,
448 coex_dm->cur_sstype,
449 ra_masktype);
450 halbtc8192e2ant_Updatera_mask(btcoexist, force_exec, disra_mask);
451btc8192e2ant_autorate_fallback_retry(btcoexist, force_exec, arfr_type);
452 halbtc8192e2ant_retrylimit(btcoexist, force_exec, retrylimit_type);
453 halbtc8192e2ant_ampdu_maxtime(btcoexist, force_exec, ampdutime_type);
454}
455
456static void halbtc8192e2ant_limited_rx(struct btc_coexist *btcoexist,
457 bool force_exec, bool rej_ap_agg_pkt,
458 bool bt_ctrl_agg_buf_size,
459 u8 agg_buf_size)
460{
461 bool reject_rx_agg = rej_ap_agg_pkt;
462 bool bt_ctrl_rx_agg_size = bt_ctrl_agg_buf_size;
463 u8 rx_agg_size = agg_buf_size;
464
465 /*********************************************
466 * Rx Aggregation related setting
467 *********************************************/
468 btcoexist->btc_set(btcoexist, BTC_SET_BL_TO_REJ_AP_AGG_PKT,
469 &reject_rx_agg);
470 /* decide BT control aggregation buf size or not */
471 btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_CTRL_AGG_SIZE,
472 &bt_ctrl_rx_agg_size);
473 /* aggregation buf size, only work
474 * when BT control Rx aggregation size.
475 */
476 btcoexist->btc_set(btcoexist, BTC_SET_U1_AGG_BUF_SIZE, &rx_agg_size);
477 /* real update aggregation setting */
478 btcoexist->btc_set(btcoexist, BTC_SET_ACT_AGGREGATE_CTRL, NULL);
479}
480
481static void halbtc8192e2ant_monitor_bt_ctr(struct btc_coexist *btcoexist)
482{
483 u32 reg_hp_txrx, reg_lp_txrx, u32tmp;
484 u32 reg_hp_tx = 0, reg_hp_rx = 0, reg_lp_tx = 0, reg_lp_rx = 0;
485
486 reg_hp_txrx = 0x770;
487 reg_lp_txrx = 0x774;
488
489 u32tmp = btcoexist->btc_read_4byte(btcoexist, reg_hp_txrx);
490 reg_hp_tx = u32tmp & MASKLWORD;
491 reg_hp_rx = (u32tmp & MASKHWORD)>>16;
492
493 u32tmp = btcoexist->btc_read_4byte(btcoexist, reg_lp_txrx);
494 reg_lp_tx = u32tmp & MASKLWORD;
495 reg_lp_rx = (u32tmp & MASKHWORD)>>16;
496
497 coex_sta->high_priority_tx = reg_hp_tx;
498 coex_sta->high_priority_rx = reg_hp_rx;
499 coex_sta->low_priority_tx = reg_lp_tx;
500 coex_sta->low_priority_rx = reg_lp_rx;
501
502 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR,
503 "[BTCoex] High Priority Tx/Rx (reg 0x%x) = 0x%x(%d)/0x%x(%d)\n",
504 reg_hp_txrx, reg_hp_tx, reg_hp_tx, reg_hp_rx, reg_hp_rx);
505 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR,
506 "[BTCoex] Low Priority Tx/Rx (reg 0x%x) = 0x%x(%d)/0x%x(%d)\n",
507 reg_lp_txrx, reg_lp_tx, reg_lp_tx, reg_lp_rx, reg_lp_rx);
508
509 /* reset counter */
510 btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc);
511}
512
513static void halbtc8192e2ant_querybt_info(struct btc_coexist *btcoexist)
514{
515 u8 h2c_parameter[1] = {0};
516
517 coex_sta->c2h_bt_info_req_sent = true;
518
519 h2c_parameter[0] |= BIT0; /* trigger */
520
521 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
522 "[BTCoex], Query Bt Info, FW write 0x61 = 0x%x\n",
523 h2c_parameter[0]);
524
525 btcoexist->btc_fill_h2c(btcoexist, 0x61, 1, h2c_parameter);
526}
527
528static void halbtc8192e2ant_update_btlink_info(struct btc_coexist *btcoexist)
529{
530 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
531 bool bt_hson = false;
532
533 btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hson);
534
535 bt_link_info->bt_link_exist = coex_sta->bt_link_exist;
536 bt_link_info->sco_exist = coex_sta->sco_exist;
537 bt_link_info->a2dp_exist = coex_sta->a2dp_exist;
538 bt_link_info->pan_exist = coex_sta->pan_exist;
539 bt_link_info->hid_exist = coex_sta->hid_exist;
540
541 /* work around for HS mode. */
542 if (bt_hson) {
543 bt_link_info->pan_exist = true;
544 bt_link_info->bt_link_exist = true;
545 }
546
547 /* check if Sco only */
548 if (bt_link_info->sco_exist &&
549 !bt_link_info->a2dp_exist &&
550 !bt_link_info->pan_exist &&
551 !bt_link_info->hid_exist)
552 bt_link_info->sco_only = true;
553 else
554 bt_link_info->sco_only = false;
555
556 /* check if A2dp only */
557 if (!bt_link_info->sco_exist &&
558 bt_link_info->a2dp_exist &&
559 !bt_link_info->pan_exist &&
560 !bt_link_info->hid_exist)
561 bt_link_info->a2dp_only = true;
562 else
563 bt_link_info->a2dp_only = false;
564
565 /* check if Pan only */
566 if (!bt_link_info->sco_exist &&
567 !bt_link_info->a2dp_exist &&
568 bt_link_info->pan_exist &&
569 !bt_link_info->hid_exist)
570 bt_link_info->pan_only = true;
571 else
572 bt_link_info->pan_only = false;
573
574 /* check if Hid only */
575 if (!bt_link_info->sco_exist &&
576 !bt_link_info->a2dp_exist &&
577 !bt_link_info->pan_exist &&
578 bt_link_info->hid_exist)
579 bt_link_info->hid_only = true;
580 else
581 bt_link_info->hid_only = false;
582}
583
584static u8 halbtc8192e2ant_action_algorithm(struct btc_coexist *btcoexist)
585{
586 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
587 struct btc_stack_info *stack_info = &btcoexist->stack_info;
588 bool bt_hson = false;
589 u8 algorithm = BT_8192E_2ANT_COEX_ALGO_UNDEFINED;
590 u8 numdiffprofile = 0;
591
592 btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hson);
593
594 if (!bt_link_info->bt_link_exist) {
595 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
596 "No BT link exists!!!\n");
597 return algorithm;
598 }
599
600 if (bt_link_info->sco_exist)
601 numdiffprofile++;
602 if (bt_link_info->hid_exist)
603 numdiffprofile++;
604 if (bt_link_info->pan_exist)
605 numdiffprofile++;
606 if (bt_link_info->a2dp_exist)
607 numdiffprofile++;
608
609 if (numdiffprofile == 1) {
610 if (bt_link_info->sco_exist) {
611 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
612 "SCO only\n");
613 algorithm = BT_8192E_2ANT_COEX_ALGO_SCO;
614 } else {
615 if (bt_link_info->hid_exist) {
616 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
617 "HID only\n");
618 algorithm = BT_8192E_2ANT_COEX_ALGO_HID;
619 } else if (bt_link_info->a2dp_exist) {
620 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
621 "A2DP only\n");
622 algorithm = BT_8192E_2ANT_COEX_ALGO_A2DP;
623 } else if (bt_link_info->pan_exist) {
624 if (bt_hson) {
625 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
626 "PAN(HS) only\n");
627 algorithm =
628 BT_8192E_2ANT_COEX_ALGO_PANHS;
629 } else {
630 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
631 "PAN(EDR) only\n");
632 algorithm =
633 BT_8192E_2ANT_COEX_ALGO_PANEDR;
634 }
635 }
636 }
637 } else if (numdiffprofile == 2) {
638 if (bt_link_info->sco_exist) {
639 if (bt_link_info->hid_exist) {
640 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
641 "SCO + HID\n");
642 algorithm = BT_8192E_2ANT_COEX_ALGO_SCO;
643 } else if (bt_link_info->a2dp_exist) {
644 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
645 "SCO + A2DP ==> SCO\n");
646 algorithm = BT_8192E_2ANT_COEX_ALGO_PANEDR_HID;
647 } else if (bt_link_info->pan_exist) {
648 if (bt_hson) {
649 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
650 "SCO + PAN(HS)\n");
651 algorithm = BT_8192E_2ANT_COEX_ALGO_SCO;
652 } else {
653 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
654 "SCO + PAN(EDR)\n");
655 algorithm =
656 BT_8192E_2ANT_COEX_ALGO_SCO_PAN;
657 }
658 }
659 } else {
660 if (bt_link_info->hid_exist &&
661 bt_link_info->a2dp_exist) {
662 if (stack_info->num_of_hid >= 2) {
663 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
664 "HID*2 + A2DP\n");
665 algorithm =
666 BT_8192E_2ANT_COEX_ALGO_HID_A2DP_PANEDR;
667 } else {
668 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
669 "HID + A2DP\n");
670 algorithm =
671 BT_8192E_2ANT_COEX_ALGO_HID_A2DP;
672 }
673 } else if (bt_link_info->hid_exist &&
674 bt_link_info->pan_exist) {
675 if (bt_hson) {
676 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
677 "HID + PAN(HS)\n");
678 algorithm = BT_8192E_2ANT_COEX_ALGO_HID;
679 } else {
680 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
681 "HID + PAN(EDR)\n");
682 algorithm =
683 BT_8192E_2ANT_COEX_ALGO_PANEDR_HID;
684 }
685 } else if (bt_link_info->pan_exist &&
686 bt_link_info->a2dp_exist) {
687 if (bt_hson) {
688 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
689 "A2DP + PAN(HS)\n");
690 algorithm =
691 BT_8192E_2ANT_COEX_ALGO_A2DP_PANHS;
692 } else {
693 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
694 "A2DP + PAN(EDR)\n");
695 algorithm =
696 BT_8192E_2ANT_COEX_ALGO_PANEDR_A2DP;
697 }
698 }
699 }
700 } else if (numdiffprofile == 3) {
701 if (bt_link_info->sco_exist) {
702 if (bt_link_info->hid_exist &&
703 bt_link_info->a2dp_exist) {
704 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
705 "SCO + HID + A2DP ==> HID\n");
706 algorithm = BT_8192E_2ANT_COEX_ALGO_PANEDR_HID;
707 } else if (bt_link_info->hid_exist &&
708 bt_link_info->pan_exist) {
709 if (bt_hson) {
710 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
711 "SCO + HID + PAN(HS)\n");
712 algorithm = BT_8192E_2ANT_COEX_ALGO_SCO;
713 } else {
714 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
715 "SCO + HID + PAN(EDR)\n");
716 algorithm =
717 BT_8192E_2ANT_COEX_ALGO_SCO_PAN;
718 }
719 } else if (bt_link_info->pan_exist &&
720 bt_link_info->a2dp_exist) {
721 if (bt_hson) {
722 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
723 "SCO + A2DP + PAN(HS)\n");
724 algorithm = BT_8192E_2ANT_COEX_ALGO_SCO;
725 } else {
726 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
727 "SCO + A2DP + PAN(EDR)\n");
728 algorithm =
729 BT_8192E_2ANT_COEX_ALGO_PANEDR_HID;
730 }
731 }
732 } else {
733 if (bt_link_info->hid_exist &&
734 bt_link_info->pan_exist &&
735 bt_link_info->a2dp_exist) {
736 if (bt_hson) {
737 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
738 "HID + A2DP + PAN(HS)\n");
739 algorithm =
740 BT_8192E_2ANT_COEX_ALGO_HID_A2DP;
741 } else {
742 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
743 "HID + A2DP + PAN(EDR)\n");
744 algorithm =
745 BT_8192E_2ANT_COEX_ALGO_HID_A2DP_PANEDR;
746 }
747 }
748 }
749 } else if (numdiffprofile >= 3) {
750 if (bt_link_info->sco_exist) {
751 if (bt_link_info->hid_exist &&
752 bt_link_info->pan_exist &&
753 bt_link_info->a2dp_exist) {
754 if (bt_hson) {
755 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
756 "ErrorSCO+HID+A2DP+PAN(HS)\n");
757
758 } else {
759 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
760 "SCO+HID+A2DP+PAN(EDR)\n");
761 algorithm =
762 BT_8192E_2ANT_COEX_ALGO_PANEDR_HID;
763 }
764 }
765 }
766 }
767
768 return algorithm;
769}
770
771static void halbtc8192e2ant_setfw_dac_swinglevel(struct btc_coexist *btcoexist,
772 u8 dac_swinglvl)
773{
774 u8 h2c_parameter[1] = {0};
775
776 /* There are several type of dacswing
777 * 0x18/ 0x10/ 0xc/ 0x8/ 0x4/ 0x6
778 */
779 h2c_parameter[0] = dac_swinglvl;
780
781 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
782 "[BTCoex], Set Dac Swing Level = 0x%x\n", dac_swinglvl);
783 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
784 "[BTCoex], FW write 0x64 = 0x%x\n", h2c_parameter[0]);
785
786 btcoexist->btc_fill_h2c(btcoexist, 0x64, 1, h2c_parameter);
787}
788
789static void halbtc8192e2ant_set_fwdec_btpwr(struct btc_coexist *btcoexist,
790 u8 dec_btpwr_lvl)
791{
792 u8 h2c_parameter[1] = {0};
793
794 h2c_parameter[0] = dec_btpwr_lvl;
795
796 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
797 "[BTCoex] decrease Bt Power level = %d, FW write 0x62 = 0x%x\n",
798 dec_btpwr_lvl, h2c_parameter[0]);
799
800 btcoexist->btc_fill_h2c(btcoexist, 0x62, 1, h2c_parameter);
801}
802
803static void halbtc8192e2ant_dec_btpwr(struct btc_coexist *btcoexist,
804 bool force_exec, u8 dec_btpwr_lvl)
805{
806 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW,
807 "[BTCoex], %s Dec BT power level = %d\n",
808 (force_exec ? "force to" : ""), dec_btpwr_lvl);
809 coex_dm->cur_dec_bt_pwr = dec_btpwr_lvl;
810
811 if (!force_exec) {
812 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
813 "[BTCoex], preBtDecPwrLvl=%d, curBtDecPwrLvl=%d\n",
814 coex_dm->pre_dec_bt_pwr, coex_dm->cur_dec_bt_pwr);
815 }
816 halbtc8192e2ant_set_fwdec_btpwr(btcoexist, coex_dm->cur_dec_bt_pwr);
817
818 coex_dm->pre_dec_bt_pwr = coex_dm->cur_dec_bt_pwr;
819}
820
821static void halbtc8192e2ant_set_bt_autoreport(struct btc_coexist *btcoexist,
822 bool enable_autoreport)
823{
824 u8 h2c_parameter[1] = {0};
825
826 h2c_parameter[0] = 0;
827
828 if (enable_autoreport)
829 h2c_parameter[0] |= BIT0;
830
831 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
832 "[BTCoex], BT FW auto report : %s, FW write 0x68 = 0x%x\n",
833 (enable_autoreport ? "Enabled!!" : "Disabled!!"),
834 h2c_parameter[0]);
835
836 btcoexist->btc_fill_h2c(btcoexist, 0x68, 1, h2c_parameter);
837}
838
839static void halbtc8192e2ant_bt_autoreport(struct btc_coexist *btcoexist,
840 bool force_exec,
841 bool enable_autoreport)
842{
843 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW,
844 "[BTCoex], %s BT Auto report = %s\n",
845 (force_exec ? "force to" : ""),
846 ((enable_autoreport) ? "Enabled" : "Disabled"));
847 coex_dm->cur_bt_auto_report = enable_autoreport;
848
849 if (!force_exec) {
850 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
851 "[BTCoex] bPreBtAutoReport=%d, bCurBtAutoReport=%d\n",
852 coex_dm->pre_bt_auto_report,
853 coex_dm->cur_bt_auto_report);
854
855 if (coex_dm->pre_bt_auto_report == coex_dm->cur_bt_auto_report)
856 return;
857 }
858 halbtc8192e2ant_set_bt_autoreport(btcoexist,
859 coex_dm->cur_bt_auto_report);
860
861 coex_dm->pre_bt_auto_report = coex_dm->cur_bt_auto_report;
862}
863
864static void halbtc8192e2ant_fw_dac_swinglvl(struct btc_coexist *btcoexist,
865 bool force_exec, u8 fw_dac_swinglvl)
866{
867 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW,
868 "[BTCoex], %s set FW Dac Swing level = %d\n",
869 (force_exec ? "force to" : ""), fw_dac_swinglvl);
870 coex_dm->cur_fw_dac_swing_lvl = fw_dac_swinglvl;
871
872 if (!force_exec) {
873 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
874 "[BTCoex] preFwDacSwingLvl=%d, curFwDacSwingLvl=%d\n",
875 coex_dm->pre_fw_dac_swing_lvl,
876 coex_dm->cur_fw_dac_swing_lvl);
877
878 if (coex_dm->pre_fw_dac_swing_lvl ==
879 coex_dm->cur_fw_dac_swing_lvl)
880 return;
881 }
882
883 halbtc8192e2ant_setfw_dac_swinglevel(btcoexist,
884 coex_dm->cur_fw_dac_swing_lvl);
885
886 coex_dm->pre_fw_dac_swing_lvl = coex_dm->cur_fw_dac_swing_lvl;
887}
888
889static void btc8192e2ant_set_sw_rf_rx_lpf_corner(struct btc_coexist *btcoexist,
890 bool rx_rf_shrink_on)
891{
892 if (rx_rf_shrink_on) {
893 /* Shrink RF Rx LPF corner */
894 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
895 "[BTCoex], Shrink RF Rx LPF corner!!\n");
896 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1e,
897 0xfffff, 0xffffc);
898 } else {
899 /* Resume RF Rx LPF corner
900 * After initialized, we can use coex_dm->btRf0x1eBackup
901 */
902 if (btcoexist->initilized) {
903 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
904 "[BTCoex], Resume RF Rx LPF corner!!\n");
905 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1e,
906 0xfffff,
907 coex_dm->bt_rf0x1e_backup);
908 }
909 }
910}
911
912static void halbtc8192e2ant_rf_shrink(struct btc_coexist *btcoexist,
913 bool force_exec, bool rx_rf_shrink_on)
914{
915 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW,
916 "[BTCoex], %s turn Rx RF Shrink = %s\n",
917 (force_exec ? "force to" : ""),
918 ((rx_rf_shrink_on) ? "ON" : "OFF"));
919 coex_dm->cur_rf_rx_lpf_shrink = rx_rf_shrink_on;
920
921 if (!force_exec) {
922 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL,
923 "[BTCoex]bPreRfRxLpfShrink=%d,bCurRfRxLpfShrink=%d\n",
924 coex_dm->pre_rf_rx_lpf_shrink,
925 coex_dm->cur_rf_rx_lpf_shrink);
926
927 if (coex_dm->pre_rf_rx_lpf_shrink ==
928 coex_dm->cur_rf_rx_lpf_shrink)
929 return;
930 }
931 btc8192e2ant_set_sw_rf_rx_lpf_corner(btcoexist,
932 coex_dm->cur_rf_rx_lpf_shrink);
933
934 coex_dm->pre_rf_rx_lpf_shrink = coex_dm->cur_rf_rx_lpf_shrink;
935}
936
937static void halbtc8192e2ant_set_dac_swingreg(struct btc_coexist *btcoexist,
938 u32 level)
939{
940 u8 val = (u8)level;
941
942 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
943 "[BTCoex], Write SwDacSwing = 0x%x\n", level);
944 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x883, 0x3e, val);
945}
946
947static void btc8192e2ant_setsw_full_swing(struct btc_coexist *btcoexist,
948 bool sw_dac_swingon,
949 u32 sw_dac_swinglvl)
950{
951 if (sw_dac_swingon)
952 halbtc8192e2ant_set_dac_swingreg(btcoexist, sw_dac_swinglvl);
953 else
954 halbtc8192e2ant_set_dac_swingreg(btcoexist, 0x18);
955}
956
957static void halbtc8192e2ant_DacSwing(struct btc_coexist *btcoexist,
958 bool force_exec, bool dac_swingon,
959 u32 dac_swinglvl)
960{
961 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW,
962 "[BTCoex], %s turn DacSwing=%s, dac_swinglvl = 0x%x\n",
963 (force_exec ? "force to" : ""),
964 ((dac_swingon) ? "ON" : "OFF"), dac_swinglvl);
965 coex_dm->cur_dac_swing_on = dac_swingon;
966 coex_dm->cur_dac_swing_lvl = dac_swinglvl;
967
968 if (!force_exec) {
969 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL,
970 "[BTCoex], bPreDacSwingOn=%d, preDacSwingLvl = 0x%x, ",
971 coex_dm->pre_dac_swing_on,
972 coex_dm->pre_dac_swing_lvl);
973 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL,
974 "bCurDacSwingOn=%d, curDacSwingLvl = 0x%x\n",
975 coex_dm->cur_dac_swing_on,
976 coex_dm->cur_dac_swing_lvl);
977
978 if ((coex_dm->pre_dac_swing_on == coex_dm->cur_dac_swing_on) &&
979 (coex_dm->pre_dac_swing_lvl == coex_dm->cur_dac_swing_lvl))
980 return;
981 }
982 mdelay(30);
983 btc8192e2ant_setsw_full_swing(btcoexist, dac_swingon, dac_swinglvl);
984
985 coex_dm->pre_dac_swing_on = coex_dm->cur_dac_swing_on;
986 coex_dm->pre_dac_swing_lvl = coex_dm->cur_dac_swing_lvl;
987}
988
989static void halbtc8192e2ant_set_agc_table(struct btc_coexist *btcoexist,
990 bool agc_table_en)
991{
992 /* BB AGC Gain Table */
993 if (agc_table_en) {
994 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
995 "[BTCoex], BB Agc Table On!\n");
996 btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x0a1A0001);
997 btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x091B0001);
998 btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x081C0001);
999 btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x071D0001);
1000 btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x061E0001);
1001 btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x051F0001);
1002 } else {
1003 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
1004 "[BTCoex], BB Agc Table Off!\n");
1005 btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xaa1A0001);
1006 btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa91B0001);
1007 btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa81C0001);
1008 btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa71D0001);
1009 btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa61E0001);
1010 btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa51F0001);
1011 }
1012}
1013
1014static void halbtc8192e2ant_AgcTable(struct btc_coexist *btcoexist,
1015 bool force_exec, bool agc_table_en)
1016{
1017 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW,
1018 "[BTCoex], %s %s Agc Table\n",
1019 (force_exec ? "force to" : ""),
1020 ((agc_table_en) ? "Enable" : "Disable"));
1021 coex_dm->cur_agc_table_en = agc_table_en;
1022
1023 if (!force_exec) {
1024 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL,
1025 "[BTCoex], bPreAgcTableEn=%d, bCurAgcTableEn=%d\n",
1026 coex_dm->pre_agc_table_en, coex_dm->cur_agc_table_en);
1027
1028 if (coex_dm->pre_agc_table_en == coex_dm->cur_agc_table_en)
1029 return;
1030 }
1031 halbtc8192e2ant_set_agc_table(btcoexist, agc_table_en);
1032
1033 coex_dm->pre_agc_table_en = coex_dm->cur_agc_table_en;
1034}
1035
1036static void halbtc8192e2ant_set_coex_table(struct btc_coexist *btcoexist,
1037 u32 val0x6c0, u32 val0x6c4,
1038 u32 val0x6c8, u8 val0x6cc)
1039{
1040 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
1041 "[BTCoex], set coex table, set 0x6c0 = 0x%x\n", val0x6c0);
1042 btcoexist->btc_write_4byte(btcoexist, 0x6c0, val0x6c0);
1043
1044 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
1045 "[BTCoex], set coex table, set 0x6c4 = 0x%x\n", val0x6c4);
1046 btcoexist->btc_write_4byte(btcoexist, 0x6c4, val0x6c4);
1047
1048 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
1049 "[BTCoex], set coex table, set 0x6c8 = 0x%x\n", val0x6c8);
1050 btcoexist->btc_write_4byte(btcoexist, 0x6c8, val0x6c8);
1051
1052 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
1053 "[BTCoex], set coex table, set 0x6cc = 0x%x\n", val0x6cc);
1054 btcoexist->btc_write_1byte(btcoexist, 0x6cc, val0x6cc);
1055}
1056
1057static void halbtc8192e2ant_coex_table(struct btc_coexist *btcoexist,
1058 bool force_exec,
1059 u32 val0x6c0, u32 val0x6c4,
1060 u32 val0x6c8, u8 val0x6cc)
1061{
1062 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW,
1063 "[BTCoex], %s write Coex Table 0x6c0 = 0x%x, ",
1064 (force_exec ? "force to" : ""), val0x6c0);
1065 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW,
1066 "0x6c4 = 0x%x, 0x6c8 = 0x%x, 0x6cc = 0x%x\n",
1067 val0x6c4, val0x6c8, val0x6cc);
1068 coex_dm->cur_val0x6c0 = val0x6c0;
1069 coex_dm->cur_val0x6c4 = val0x6c4;
1070 coex_dm->cur_val0x6c8 = val0x6c8;
1071 coex_dm->cur_val0x6cc = val0x6cc;
1072
1073 if (!force_exec) {
1074 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL,
1075 "[BTCoex], preVal0x6c0 = 0x%x, preVal0x6c4 = 0x%x, ",
1076 coex_dm->pre_val0x6c0, coex_dm->pre_val0x6c4);
1077 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL,
1078 "preVal0x6c8 = 0x%x, preVal0x6cc = 0x%x !!\n",
1079 coex_dm->pre_val0x6c8, coex_dm->pre_val0x6cc);
1080 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL,
1081 "[BTCoex], curVal0x6c0 = 0x%x, curVal0x6c4 = 0x%x,\n",
1082 coex_dm->cur_val0x6c0, coex_dm->cur_val0x6c4);
1083 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL,
1084 "curVal0x6c8 = 0x%x, curVal0x6cc = 0x%x !!\n",
1085 coex_dm->cur_val0x6c8, coex_dm->cur_val0x6cc);
1086
1087 if ((coex_dm->pre_val0x6c0 == coex_dm->cur_val0x6c0) &&
1088 (coex_dm->pre_val0x6c4 == coex_dm->cur_val0x6c4) &&
1089 (coex_dm->pre_val0x6c8 == coex_dm->cur_val0x6c8) &&
1090 (coex_dm->pre_val0x6cc == coex_dm->cur_val0x6cc))
1091 return;
1092 }
1093 halbtc8192e2ant_set_coex_table(btcoexist, val0x6c0, val0x6c4,
1094 val0x6c8, val0x6cc);
1095
1096 coex_dm->pre_val0x6c0 = coex_dm->cur_val0x6c0;
1097 coex_dm->pre_val0x6c4 = coex_dm->cur_val0x6c4;
1098 coex_dm->pre_val0x6c8 = coex_dm->cur_val0x6c8;
1099 coex_dm->pre_val0x6cc = coex_dm->cur_val0x6cc;
1100}
1101
1102static void btc8192e2ant_coex_tbl_w_type(struct btc_coexist *btcoexist,
1103 bool force_exec, u8 type)
1104{
1105 switch (type) {
1106 case 0:
1107 halbtc8192e2ant_coex_table(btcoexist, force_exec, 0x55555555,
1108 0x5a5a5a5a, 0xffffff, 0x3);
1109 break;
1110 case 1:
1111 halbtc8192e2ant_coex_table(btcoexist, force_exec, 0x5a5a5a5a,
1112 0x5a5a5a5a, 0xffffff, 0x3);
1113 break;
1114 case 2:
1115 halbtc8192e2ant_coex_table(btcoexist, force_exec, 0x55555555,
1116 0x5ffb5ffb, 0xffffff, 0x3);
1117 break;
1118 case 3:
1119 halbtc8192e2ant_coex_table(btcoexist, force_exec, 0xdfffdfff,
1120 0x5fdb5fdb, 0xffffff, 0x3);
1121 break;
1122 case 4:
1123 halbtc8192e2ant_coex_table(btcoexist, force_exec, 0xdfffdfff,
1124 0x5ffb5ffb, 0xffffff, 0x3);
1125 break;
1126 default:
1127 break;
1128 }
1129}
1130
1131static void halbtc8192e2ant_set_fw_ignore_wlanact(struct btc_coexist *btcoexist,
1132 bool enable)
1133{
1134 u8 h2c_parameter[1] = {0};
1135
1136 if (enable)
1137 h2c_parameter[0] |= BIT0; /* function enable */
1138
1139 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
1140 "[BTCoex]set FW for BT Ignore Wlan_Act, FW write 0x63 = 0x%x\n",
1141 h2c_parameter[0]);
1142
1143 btcoexist->btc_fill_h2c(btcoexist, 0x63, 1, h2c_parameter);
1144}
1145
1146static void halbtc8192e2ant_IgnoreWlanAct(struct btc_coexist *btcoexist,
1147 bool force_exec, bool enable)
1148{
1149 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW,
1150 "[BTCoex], %s turn Ignore WlanAct %s\n",
1151 (force_exec ? "force to" : ""), (enable ? "ON" : "OFF"));
1152 coex_dm->cur_ignore_wlan_act = enable;
1153
1154 if (!force_exec) {
1155 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
1156 "[BTCoex], bPreIgnoreWlanAct = %d ",
1157 coex_dm->pre_ignore_wlan_act);
1158 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
1159 "bCurIgnoreWlanAct = %d!!\n",
1160 coex_dm->cur_ignore_wlan_act);
1161
1162 if (coex_dm->pre_ignore_wlan_act ==
1163 coex_dm->cur_ignore_wlan_act)
1164 return;
1165 }
1166 halbtc8192e2ant_set_fw_ignore_wlanact(btcoexist, enable);
1167
1168 coex_dm->pre_ignore_wlan_act = coex_dm->cur_ignore_wlan_act;
1169}
1170
1171static void halbtc8192e2ant_SetFwPstdma(struct btc_coexist *btcoexist, u8 byte1,
1172 u8 byte2, u8 byte3, u8 byte4, u8 byte5)
1173{
1174 u8 h2c_parameter[5] = {0};
1175
1176 h2c_parameter[0] = byte1;
1177 h2c_parameter[1] = byte2;
1178 h2c_parameter[2] = byte3;
1179 h2c_parameter[3] = byte4;
1180 h2c_parameter[4] = byte5;
1181
1182 coex_dm->ps_tdma_para[0] = byte1;
1183 coex_dm->ps_tdma_para[1] = byte2;
1184 coex_dm->ps_tdma_para[2] = byte3;
1185 coex_dm->ps_tdma_para[3] = byte4;
1186 coex_dm->ps_tdma_para[4] = byte5;
1187
1188 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
1189 "[BTCoex], FW write 0x60(5bytes) = 0x%x%08x\n",
1190 h2c_parameter[0],
1191 h2c_parameter[1] << 24 | h2c_parameter[2] << 16 |
1192 h2c_parameter[3] << 8 | h2c_parameter[4]);
1193
1194 btcoexist->btc_fill_h2c(btcoexist, 0x60, 5, h2c_parameter);
1195}
1196
1197static void btc8192e2ant_sw_mec1(struct btc_coexist *btcoexist,
1198 bool shrink_rx_lpf, bool low_penalty_ra,
1199 bool limited_dig, bool btlan_constrain)
1200{
1201 halbtc8192e2ant_rf_shrink(btcoexist, NORMAL_EXEC, shrink_rx_lpf);
1202}
1203
1204static void btc8192e2ant_sw_mec2(struct btc_coexist *btcoexist,
1205 bool agc_table_shift, bool adc_backoff,
1206 bool sw_dac_swing, u32 dac_swinglvl)
1207{
1208 halbtc8192e2ant_AgcTable(btcoexist, NORMAL_EXEC, agc_table_shift);
1209 halbtc8192e2ant_DacSwing(btcoexist, NORMAL_EXEC, sw_dac_swing,
1210 dac_swinglvl);
1211}
1212
1213static void halbtc8192e2ant_ps_tdma(struct btc_coexist *btcoexist,
1214 bool force_exec, bool turn_on, u8 type)
1215{
1216 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW,
1217 "[BTCoex], %s turn %s PS TDMA, type=%d\n",
1218 (force_exec ? "force to" : ""),
1219 (turn_on ? "ON" : "OFF"), type);
1220 coex_dm->cur_ps_tdma_on = turn_on;
1221 coex_dm->cur_ps_tdma = type;
1222
1223 if (!force_exec) {
1224 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
1225 "[BTCoex], bPrePsTdmaOn = %d, bCurPsTdmaOn = %d!!\n",
1226 coex_dm->pre_ps_tdma_on, coex_dm->cur_ps_tdma_on);
1227 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
1228 "[BTCoex], prePsTdma = %d, curPsTdma = %d!!\n",
1229 coex_dm->pre_ps_tdma, coex_dm->cur_ps_tdma);
1230
1231 if ((coex_dm->pre_ps_tdma_on == coex_dm->cur_ps_tdma_on) &&
1232 (coex_dm->pre_ps_tdma == coex_dm->cur_ps_tdma))
1233 return;
1234 }
1235 if (turn_on) {
1236 switch (type) {
1237 case 1:
1238 default:
1239 halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x1a,
1240 0x1a, 0xe1, 0x90);
1241 break;
1242 case 2:
1243 halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x12,
1244 0x12, 0xe1, 0x90);
1245 break;
1246 case 3:
1247 halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x1c,
1248 0x3, 0xf1, 0x90);
1249 break;
1250 case 4:
1251 halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x10,
1252 0x3, 0xf1, 0x90);
1253 break;
1254 case 5:
1255 halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x1a,
1256 0x1a, 0x60, 0x90);
1257 break;
1258 case 6:
1259 halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x12,
1260 0x12, 0x60, 0x90);
1261 break;
1262 case 7:
1263 halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x1c,
1264 0x3, 0x70, 0x90);
1265 break;
1266 case 8:
1267 halbtc8192e2ant_SetFwPstdma(btcoexist, 0xa3, 0x10,
1268 0x3, 0x70, 0x90);
1269 break;
1270 case 9:
1271 halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x1a,
1272 0x1a, 0xe1, 0x10);
1273 break;
1274 case 10:
1275 halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x12,
1276 0x12, 0xe1, 0x10);
1277 break;
1278 case 11:
1279 halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x1c,
1280 0x3, 0xf1, 0x10);
1281 break;
1282 case 12:
1283 halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x10,
1284 0x3, 0xf1, 0x10);
1285 break;
1286 case 13:
1287 halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x1a,
1288 0x1a, 0xe0, 0x10);
1289 break;
1290 case 14:
1291 halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x12,
1292 0x12, 0xe0, 0x10);
1293 break;
1294 case 15:
1295 halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x1c,
1296 0x3, 0xf0, 0x10);
1297 break;
1298 case 16:
1299 halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x12,
1300 0x3, 0xf0, 0x10);
1301 break;
1302 case 17:
1303 halbtc8192e2ant_SetFwPstdma(btcoexist, 0x61, 0x20,
1304 0x03, 0x10, 0x10);
1305 break;
1306 case 18:
1307 halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x5,
1308 0x5, 0xe1, 0x90);
1309 break;
1310 case 19:
1311 halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x25,
1312 0x25, 0xe1, 0x90);
1313 break;
1314 case 20:
1315 halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x25,
1316 0x25, 0x60, 0x90);
1317 break;
1318 case 21:
1319 halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x15,
1320 0x03, 0x70, 0x90);
1321 break;
1322 case 71:
1323 halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x1a,
1324 0x1a, 0xe1, 0x90);
1325 break;
1326 }
1327 } else {
1328 /* disable PS tdma */
1329 switch (type) {
1330 default:
1331 case 0:
1332 halbtc8192e2ant_SetFwPstdma(btcoexist, 0x8, 0x0, 0x0,
1333 0x0, 0x0);
1334 btcoexist->btc_write_1byte(btcoexist, 0x92c, 0x4);
1335 break;
1336 case 1:
1337 halbtc8192e2ant_SetFwPstdma(btcoexist, 0x0, 0x0, 0x0,
1338 0x8, 0x0);
1339 mdelay(5);
1340 btcoexist->btc_write_1byte(btcoexist, 0x92c, 0x20);
1341 break;
1342 }
1343 }
1344
1345 /* update pre state */
1346 coex_dm->pre_ps_tdma_on = coex_dm->cur_ps_tdma_on;
1347 coex_dm->pre_ps_tdma = coex_dm->cur_ps_tdma;
1348}
1349
1350static void halbtc8192e2ant_set_switch_sstype(struct btc_coexist *btcoexist,
1351 u8 sstype)
1352{
1353 u8 mimops = BTC_MIMO_PS_DYNAMIC;
1354 u32 disra_mask = 0x0;
1355
1356 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
1357 "[BTCoex], REAL set SS Type = %d\n", sstype);
1358
1359 disra_mask = halbtc8192e2ant_decidera_mask(btcoexist, sstype,
1360 coex_dm->curra_masktype);
1361 halbtc8192e2ant_Updatera_mask(btcoexist, FORCE_EXEC, disra_mask);
1362
1363 if (sstype == 1) {
1364 halbtc8192e2ant_ps_tdma(btcoexist, FORCE_EXEC, false, 1);
1365 /* switch ofdm path */
1366 btcoexist->btc_write_1byte(btcoexist, 0xc04, 0x11);
1367 btcoexist->btc_write_1byte(btcoexist, 0xd04, 0x1);
1368 btcoexist->btc_write_4byte(btcoexist, 0x90c, 0x81111111);
1369 /* switch cck patch */
1370 btcoexist->btc_write_1byte_bitmask(btcoexist, 0xe77, 0x4, 0x1);
1371 btcoexist->btc_write_1byte(btcoexist, 0xa07, 0x81);
1372 mimops = BTC_MIMO_PS_STATIC;
1373 } else if (sstype == 2) {
1374 halbtc8192e2ant_ps_tdma(btcoexist, FORCE_EXEC, false, 0);
1375 btcoexist->btc_write_1byte(btcoexist, 0xc04, 0x33);
1376 btcoexist->btc_write_1byte(btcoexist, 0xd04, 0x3);
1377 btcoexist->btc_write_4byte(btcoexist, 0x90c, 0x81121313);
1378 btcoexist->btc_write_1byte_bitmask(btcoexist, 0xe77, 0x4, 0x0);
1379 btcoexist->btc_write_1byte(btcoexist, 0xa07, 0x41);
1380 mimops = BTC_MIMO_PS_DYNAMIC;
1381 }
1382 /* set rx 1ss or 2ss */
1383 btcoexist->btc_set(btcoexist, BTC_SET_ACT_SEND_MIMO_PS, &mimops);
1384}
1385
1386static void halbtc8192e2ant_switch_sstype(struct btc_coexist *btcoexist,
1387 bool force_exec, u8 new_sstype)
1388{
1389 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
1390 "[BTCoex], %s Switch SS Type = %d\n",
1391 (force_exec ? "force to" : ""), new_sstype);
1392 coex_dm->cur_sstype = new_sstype;
1393
1394 if (!force_exec) {
1395 if (coex_dm->pre_sstype == coex_dm->cur_sstype)
1396 return;
1397 }
1398 halbtc8192e2ant_set_switch_sstype(btcoexist, coex_dm->cur_sstype);
1399
1400 coex_dm->pre_sstype = coex_dm->cur_sstype;
1401}
1402
1403static void halbtc8192e2ant_coex_alloff(struct btc_coexist *btcoexist)
1404{
1405 /* fw all off */
1406 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1);
1407 halbtc8192e2ant_fw_dac_swinglvl(btcoexist, NORMAL_EXEC, 6);
1408 halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0);
1409
1410 /* sw all off */
1411 btc8192e2ant_sw_mec1(btcoexist, false, false, false, false);
1412 btc8192e2ant_sw_mec2(btcoexist, false, false, false, 0x18);
1413
1414 /* hw all off */
1415 btc8192e2ant_coex_tbl_w_type(btcoexist, NORMAL_EXEC, 0);
1416}
1417
1418static void halbtc8192e2ant_init_coex_dm(struct btc_coexist *btcoexist)
1419{
1420 /* force to reset coex mechanism */
1421
1422 halbtc8192e2ant_ps_tdma(btcoexist, FORCE_EXEC, false, 1);
1423 halbtc8192e2ant_fw_dac_swinglvl(btcoexist, FORCE_EXEC, 6);
1424 halbtc8192e2ant_dec_btpwr(btcoexist, FORCE_EXEC, 0);
1425
1426 btc8192e2ant_coex_tbl_w_type(btcoexist, FORCE_EXEC, 0);
1427 halbtc8192e2ant_switch_sstype(btcoexist, FORCE_EXEC, 2);
1428
1429 btc8192e2ant_sw_mec1(btcoexist, false, false, false, false);
1430 btc8192e2ant_sw_mec2(btcoexist, false, false, false, 0x18);
1431}
1432
1433static void halbtc8192e2ant_action_bt_inquiry(struct btc_coexist *btcoexist)
1434{
1435 bool low_pwr_disable = true;
1436
1437 btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER,
1438 &low_pwr_disable);
1439
1440 halbtc8192e2ant_switch_sstype(btcoexist, NORMAL_EXEC, 1);
1441
1442 btc8192e2ant_coex_tbl_w_type(btcoexist, NORMAL_EXEC, 2);
1443 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3);
1444 halbtc8192e2ant_fw_dac_swinglvl(btcoexist, NORMAL_EXEC, 6);
1445 halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0);
1446
1447 btc8192e2ant_sw_mec1(btcoexist, false, false, false, false);
1448 btc8192e2ant_sw_mec2(btcoexist, false, false, false, 0x18);
1449}
1450
1451static bool halbtc8192e2ant_is_common_action(struct btc_coexist *btcoexist)
1452{
1453 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
1454 bool common = false, wifi_connected = false, wifi_busy = false;
1455 bool bt_hson = false, low_pwr_disable = false;
1456
1457 btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hson);
1458 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
1459 &wifi_connected);
1460 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
1461
1462 if (bt_link_info->sco_exist || bt_link_info->hid_exist)
1463 halbtc8192e2ant_limited_tx(btcoexist, NORMAL_EXEC, 1, 0, 0, 0);
1464 else
1465 halbtc8192e2ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0);
1466
1467 if (!wifi_connected) {
1468 low_pwr_disable = false;
1469 btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER,
1470 &low_pwr_disable);
1471
1472 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
1473 "[BTCoex], Wifi non-connected idle!!\n");
1474
1475 if ((BT_8192E_2ANT_BT_STATUS_NON_CONNECTED_IDLE ==
1476 coex_dm->bt_status) ||
1477 (BT_8192E_2ANT_BT_STATUS_CONNECTED_IDLE ==
1478 coex_dm->bt_status)) {
1479 halbtc8192e2ant_switch_sstype(btcoexist,
1480 NORMAL_EXEC, 2);
1481 btc8192e2ant_coex_tbl_w_type(btcoexist,
1482 NORMAL_EXEC, 1);
1483 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1484 false, 0);
1485 } else {
1486 halbtc8192e2ant_switch_sstype(btcoexist,
1487 NORMAL_EXEC, 1);
1488 btc8192e2ant_coex_tbl_w_type(btcoexist,
1489 NORMAL_EXEC, 0);
1490 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1491 false, 1);
1492 }
1493
1494 halbtc8192e2ant_fw_dac_swinglvl(btcoexist, NORMAL_EXEC, 6);
1495 halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0);
1496
1497 btc8192e2ant_sw_mec1(btcoexist, false, false, false, false);
1498 btc8192e2ant_sw_mec2(btcoexist, false, false, false, 0x18);
1499
1500 common = true;
1501 } else {
1502 if (BT_8192E_2ANT_BT_STATUS_NON_CONNECTED_IDLE ==
1503 coex_dm->bt_status) {
1504 low_pwr_disable = false;
1505 btcoexist->btc_set(btcoexist,
1506 BTC_SET_ACT_DISABLE_LOW_POWER,
1507 &low_pwr_disable);
1508
1509 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
1510 "Wifi connected + BT non connected-idle!!\n");
1511
1512 halbtc8192e2ant_switch_sstype(btcoexist,
1513 NORMAL_EXEC, 2);
1514 btc8192e2ant_coex_tbl_w_type(btcoexist,
1515 NORMAL_EXEC, 1);
1516 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1517 false, 0);
1518 halbtc8192e2ant_fw_dac_swinglvl(btcoexist,
1519 NORMAL_EXEC, 6);
1520 halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0);
1521
1522 btc8192e2ant_sw_mec1(btcoexist, false, false,
1523 false, false);
1524 btc8192e2ant_sw_mec2(btcoexist, false, false,
1525 false, 0x18);
1526
1527 common = true;
1528 } else if (BT_8192E_2ANT_BT_STATUS_CONNECTED_IDLE ==
1529 coex_dm->bt_status) {
1530 low_pwr_disable = true;
1531 btcoexist->btc_set(btcoexist,
1532 BTC_SET_ACT_DISABLE_LOW_POWER,
1533 &low_pwr_disable);
1534
1535 if (bt_hson)
1536 return false;
1537 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
1538 "Wifi connected + BT connected-idle!!\n");
1539
1540 halbtc8192e2ant_switch_sstype(btcoexist,
1541 NORMAL_EXEC, 2);
1542 btc8192e2ant_coex_tbl_w_type(btcoexist,
1543 NORMAL_EXEC, 1);
1544 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1545 false, 0);
1546 halbtc8192e2ant_fw_dac_swinglvl(btcoexist,
1547 NORMAL_EXEC, 6);
1548 halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0);
1549
1550 btc8192e2ant_sw_mec1(btcoexist, true, false,
1551 false, false);
1552 btc8192e2ant_sw_mec2(btcoexist, false, false,
1553 false, 0x18);
1554
1555 common = true;
1556 } else {
1557 low_pwr_disable = true;
1558 btcoexist->btc_set(btcoexist,
1559 BTC_SET_ACT_DISABLE_LOW_POWER,
1560 &low_pwr_disable);
1561
1562 if (wifi_busy) {
1563 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
1564 "Wifi Connected-Busy + BT Busy!!\n");
1565 common = false;
1566 } else {
1567 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
1568 "Wifi Connected-Idle + BT Busy!!\n");
1569
1570 halbtc8192e2ant_switch_sstype(btcoexist,
1571 NORMAL_EXEC, 1);
1572 btc8192e2ant_coex_tbl_w_type(btcoexist,
1573 NORMAL_EXEC, 2);
1574 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1575 true, 21);
1576 halbtc8192e2ant_fw_dac_swinglvl(btcoexist,
1577 NORMAL_EXEC, 6);
1578 halbtc8192e2ant_dec_btpwr(btcoexist,
1579 NORMAL_EXEC, 0);
1580 btc8192e2ant_sw_mec1(btcoexist, false,
1581 false, false, false);
1582 btc8192e2ant_sw_mec2(btcoexist, false,
1583 false, false, 0x18);
1584 common = true;
1585 }
1586 }
1587 }
1588 return common;
1589}
1590
1591static void btc8192e_int1(struct btc_coexist *btcoexist, bool tx_pause,
1592 int result)
1593{
1594 if (tx_pause) {
1595 BTC_PRINT(BTC_MSG_ALGORITHM,
1596 ALGO_TRACE_FW_DETAIL,
1597 "[BTCoex], TxPause = 1\n");
1598
1599 if (coex_dm->cur_ps_tdma == 71) {
1600 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1601 true, 5);
1602 coex_dm->tdma_adj_type = 5;
1603 } else if (coex_dm->cur_ps_tdma == 1) {
1604 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1605 true, 5);
1606 coex_dm->tdma_adj_type = 5;
1607 } else if (coex_dm->cur_ps_tdma == 2) {
1608 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1609 true, 6);
1610 coex_dm->tdma_adj_type = 6;
1611 } else if (coex_dm->cur_ps_tdma == 3) {
1612 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1613 true, 7);
1614 coex_dm->tdma_adj_type = 7;
1615 } else if (coex_dm->cur_ps_tdma == 4) {
1616 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1617 true, 8);
1618 coex_dm->tdma_adj_type = 8;
1619 }
1620 if (coex_dm->cur_ps_tdma == 9) {
1621 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1622 true, 13);
1623 coex_dm->tdma_adj_type = 13;
1624 } else if (coex_dm->cur_ps_tdma == 10) {
1625 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1626 true, 14);
1627 coex_dm->tdma_adj_type = 14;
1628 } else if (coex_dm->cur_ps_tdma == 11) {
1629 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1630 true, 15);
1631 coex_dm->tdma_adj_type = 15;
1632 } else if (coex_dm->cur_ps_tdma == 12) {
1633 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1634 true, 16);
1635 coex_dm->tdma_adj_type = 16;
1636 }
1637
1638 if (result == -1) {
1639 if (coex_dm->cur_ps_tdma == 5) {
1640 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1641 true, 6);
1642 coex_dm->tdma_adj_type = 6;
1643 } else if (coex_dm->cur_ps_tdma == 6) {
1644 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1645 true, 7);
1646 coex_dm->tdma_adj_type = 7;
1647 } else if (coex_dm->cur_ps_tdma == 7) {
1648 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1649 true, 8);
1650 coex_dm->tdma_adj_type = 8;
1651 } else if (coex_dm->cur_ps_tdma == 13) {
1652 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1653 true, 14);
1654 coex_dm->tdma_adj_type = 14;
1655 } else if (coex_dm->cur_ps_tdma == 14) {
1656 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1657 true, 15);
1658 coex_dm->tdma_adj_type = 15;
1659 } else if (coex_dm->cur_ps_tdma == 15) {
1660 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1661 true, 16);
1662 coex_dm->tdma_adj_type = 16;
1663 }
1664 } else if (result == 1) {
1665 if (coex_dm->cur_ps_tdma == 8) {
1666 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1667 true, 7);
1668 coex_dm->tdma_adj_type = 7;
1669 } else if (coex_dm->cur_ps_tdma == 7) {
1670 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1671 true, 6);
1672 coex_dm->tdma_adj_type = 6;
1673 } else if (coex_dm->cur_ps_tdma == 6) {
1674 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1675 true, 5);
1676 coex_dm->tdma_adj_type = 5;
1677 } else if (coex_dm->cur_ps_tdma == 16) {
1678 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1679 true, 15);
1680 coex_dm->tdma_adj_type = 15;
1681 } else if (coex_dm->cur_ps_tdma == 15) {
1682 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1683 true, 14);
1684 coex_dm->tdma_adj_type = 14;
1685 } else if (coex_dm->cur_ps_tdma == 14) {
1686 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1687 true, 13);
1688 coex_dm->tdma_adj_type = 13;
1689 }
1690 }
1691 } else {
1692 BTC_PRINT(BTC_MSG_ALGORITHM,
1693 ALGO_TRACE_FW_DETAIL,
1694 "[BTCoex], TxPause = 0\n");
1695 if (coex_dm->cur_ps_tdma == 5) {
1696 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1697 true, 71);
1698 coex_dm->tdma_adj_type = 71;
1699 } else if (coex_dm->cur_ps_tdma == 6) {
1700 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1701 true, 2);
1702 coex_dm->tdma_adj_type = 2;
1703 } else if (coex_dm->cur_ps_tdma == 7) {
1704 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1705 true, 3);
1706 coex_dm->tdma_adj_type = 3;
1707 } else if (coex_dm->cur_ps_tdma == 8) {
1708 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1709 true, 4);
1710 coex_dm->tdma_adj_type = 4;
1711 }
1712 if (coex_dm->cur_ps_tdma == 13) {
1713 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1714 true, 9);
1715 coex_dm->tdma_adj_type = 9;
1716 } else if (coex_dm->cur_ps_tdma == 14) {
1717 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1718 true, 10);
1719 coex_dm->tdma_adj_type = 10;
1720 } else if (coex_dm->cur_ps_tdma == 15) {
1721 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1722 true, 11);
1723 coex_dm->tdma_adj_type = 11;
1724 } else if (coex_dm->cur_ps_tdma == 16) {
1725 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1726 true, 12);
1727 coex_dm->tdma_adj_type = 12;
1728 }
1729
1730 if (result == -1) {
1731 if (coex_dm->cur_ps_tdma == 71) {
1732 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1733 true, 1);
1734 coex_dm->tdma_adj_type = 1;
1735 } else if (coex_dm->cur_ps_tdma == 1) {
1736 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1737 true, 2);
1738 coex_dm->tdma_adj_type = 2;
1739 } else if (coex_dm->cur_ps_tdma == 2) {
1740 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1741 true, 3);
1742 coex_dm->tdma_adj_type = 3;
1743 } else if (coex_dm->cur_ps_tdma == 3) {
1744 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1745 true, 4);
1746 coex_dm->tdma_adj_type = 4;
1747 } else if (coex_dm->cur_ps_tdma == 9) {
1748 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1749 true, 10);
1750 coex_dm->tdma_adj_type = 10;
1751 } else if (coex_dm->cur_ps_tdma == 10) {
1752 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1753 true, 11);
1754 coex_dm->tdma_adj_type = 11;
1755 } else if (coex_dm->cur_ps_tdma == 11) {
1756 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1757 true, 12);
1758 coex_dm->tdma_adj_type = 12;
1759 }
1760 } else if (result == 1) {
1761 if (coex_dm->cur_ps_tdma == 4) {
1762 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1763 true, 3);
1764 coex_dm->tdma_adj_type = 3;
1765 } else if (coex_dm->cur_ps_tdma == 3) {
1766 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1767 true, 2);
1768 coex_dm->tdma_adj_type = 2;
1769 } else if (coex_dm->cur_ps_tdma == 2) {
1770 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1771 true, 1);
1772 coex_dm->tdma_adj_type = 1;
1773 } else if (coex_dm->cur_ps_tdma == 1) {
1774 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1775 true, 71);
1776 coex_dm->tdma_adj_type = 71;
1777 } else if (coex_dm->cur_ps_tdma == 12) {
1778 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1779 true, 11);
1780 coex_dm->tdma_adj_type = 11;
1781 } else if (coex_dm->cur_ps_tdma == 11) {
1782 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1783 true, 10);
1784 coex_dm->tdma_adj_type = 10;
1785 } else if (coex_dm->cur_ps_tdma == 10) {
1786 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1787 true, 9);
1788 coex_dm->tdma_adj_type = 9;
1789 }
1790 }
1791 }
1792}
1793
1794static void btc8192e_int2(struct btc_coexist *btcoexist, bool tx_pause,
1795 int result)
1796{
1797 if (tx_pause) {
1798 BTC_PRINT(BTC_MSG_ALGORITHM,
1799 ALGO_TRACE_FW_DETAIL,
1800 "[BTCoex], TxPause = 1\n");
1801 if (coex_dm->cur_ps_tdma == 1) {
1802 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1803 true, 6);
1804 coex_dm->tdma_adj_type = 6;
1805 } else if (coex_dm->cur_ps_tdma == 2) {
1806 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1807 true, 6);
1808 coex_dm->tdma_adj_type = 6;
1809 } else if (coex_dm->cur_ps_tdma == 3) {
1810 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1811 true, 7);
1812 coex_dm->tdma_adj_type = 7;
1813 } else if (coex_dm->cur_ps_tdma == 4) {
1814 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1815 true, 8);
1816 coex_dm->tdma_adj_type = 8;
1817 }
1818 if (coex_dm->cur_ps_tdma == 9) {
1819 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1820 true, 14);
1821 coex_dm->tdma_adj_type = 14;
1822 } else if (coex_dm->cur_ps_tdma == 10) {
1823 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1824 true, 14);
1825 coex_dm->tdma_adj_type = 14;
1826 } else if (coex_dm->cur_ps_tdma == 11) {
1827 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1828 true, 15);
1829 coex_dm->tdma_adj_type = 15;
1830 } else if (coex_dm->cur_ps_tdma == 12) {
1831 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1832 true, 16);
1833 coex_dm->tdma_adj_type = 16;
1834 }
1835 if (result == -1) {
1836 if (coex_dm->cur_ps_tdma == 5) {
1837 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1838 true, 6);
1839 coex_dm->tdma_adj_type = 6;
1840 } else if (coex_dm->cur_ps_tdma == 6) {
1841 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1842 true, 7);
1843 coex_dm->tdma_adj_type = 7;
1844 } else if (coex_dm->cur_ps_tdma == 7) {
1845 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1846 true, 8);
1847 coex_dm->tdma_adj_type = 8;
1848 } else if (coex_dm->cur_ps_tdma == 13) {
1849 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1850 true, 14);
1851 coex_dm->tdma_adj_type = 14;
1852 } else if (coex_dm->cur_ps_tdma == 14) {
1853 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1854 true, 15);
1855 coex_dm->tdma_adj_type = 15;
1856 } else if (coex_dm->cur_ps_tdma == 15) {
1857 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1858 true, 16);
1859 coex_dm->tdma_adj_type = 16;
1860 }
1861 } else if (result == 1) {
1862 if (coex_dm->cur_ps_tdma == 8) {
1863 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1864 true, 7);
1865 coex_dm->tdma_adj_type = 7;
1866 } else if (coex_dm->cur_ps_tdma == 7) {
1867 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1868 true, 6);
1869 coex_dm->tdma_adj_type = 6;
1870 } else if (coex_dm->cur_ps_tdma == 6) {
1871 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1872 true, 6);
1873 coex_dm->tdma_adj_type = 6;
1874 } else if (coex_dm->cur_ps_tdma == 16) {
1875 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1876 true, 15);
1877 coex_dm->tdma_adj_type = 15;
1878 } else if (coex_dm->cur_ps_tdma == 15) {
1879 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1880 true, 14);
1881 coex_dm->tdma_adj_type = 14;
1882 } else if (coex_dm->cur_ps_tdma == 14) {
1883 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1884 true, 14);
1885 coex_dm->tdma_adj_type = 14;
1886 }
1887 }
1888 } else {
1889 BTC_PRINT(BTC_MSG_ALGORITHM,
1890 ALGO_TRACE_FW_DETAIL,
1891 "[BTCoex], TxPause = 0\n");
1892 if (coex_dm->cur_ps_tdma == 5) {
1893 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1894 true, 2);
1895 coex_dm->tdma_adj_type = 2;
1896 } else if (coex_dm->cur_ps_tdma == 6) {
1897 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1898 true, 2);
1899 coex_dm->tdma_adj_type = 2;
1900 } else if (coex_dm->cur_ps_tdma == 7) {
1901 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1902 true, 3);
1903 coex_dm->tdma_adj_type = 3;
1904 } else if (coex_dm->cur_ps_tdma == 8) {
1905 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1906 true, 4);
1907 coex_dm->tdma_adj_type = 4;
1908 }
1909 if (coex_dm->cur_ps_tdma == 13) {
1910 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1911 true, 10);
1912 coex_dm->tdma_adj_type = 10;
1913 } else if (coex_dm->cur_ps_tdma == 14) {
1914 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1915 true, 10);
1916 coex_dm->tdma_adj_type = 10;
1917 } else if (coex_dm->cur_ps_tdma == 15) {
1918 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1919 true, 11);
1920 coex_dm->tdma_adj_type = 11;
1921 } else if (coex_dm->cur_ps_tdma == 16) {
1922 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1923 true, 12);
1924 coex_dm->tdma_adj_type = 12;
1925 }
1926 if (result == -1) {
1927 if (coex_dm->cur_ps_tdma == 1) {
1928 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1929 true, 2);
1930 coex_dm->tdma_adj_type = 2;
1931 } else if (coex_dm->cur_ps_tdma == 2) {
1932 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1933 true, 3);
1934 coex_dm->tdma_adj_type = 3;
1935 } else if (coex_dm->cur_ps_tdma == 3) {
1936 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1937 true, 4);
1938 coex_dm->tdma_adj_type = 4;
1939 } else if (coex_dm->cur_ps_tdma == 9) {
1940 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1941 true, 10);
1942 coex_dm->tdma_adj_type = 10;
1943 } else if (coex_dm->cur_ps_tdma == 10) {
1944 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1945 true, 11);
1946 coex_dm->tdma_adj_type = 11;
1947 } else if (coex_dm->cur_ps_tdma == 11) {
1948 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1949 true, 12);
1950 coex_dm->tdma_adj_type = 12;
1951 }
1952 } else if (result == 1) {
1953 if (coex_dm->cur_ps_tdma == 4) {
1954 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1955 true, 3);
1956 coex_dm->tdma_adj_type = 3;
1957 } else if (coex_dm->cur_ps_tdma == 3) {
1958 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1959 true, 2);
1960 coex_dm->tdma_adj_type = 2;
1961 } else if (coex_dm->cur_ps_tdma == 2) {
1962 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1963 true, 2);
1964 coex_dm->tdma_adj_type = 2;
1965 } else if (coex_dm->cur_ps_tdma == 12) {
1966 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1967 true, 11);
1968 coex_dm->tdma_adj_type = 11;
1969 } else if (coex_dm->cur_ps_tdma == 11) {
1970 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1971 true, 10);
1972 coex_dm->tdma_adj_type = 10;
1973 } else if (coex_dm->cur_ps_tdma == 10) {
1974 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1975 true, 10);
1976 coex_dm->tdma_adj_type = 10;
1977 }
1978 }
1979 }
1980}
1981
1982static void btc8192e_int3(struct btc_coexist *btcoexist, bool tx_pause,
1983 int result)
1984{
1985 if (tx_pause) {
1986 BTC_PRINT(BTC_MSG_ALGORITHM,
1987 ALGO_TRACE_FW_DETAIL,
1988 "[BTCoex], TxPause = 1\n");
1989 if (coex_dm->cur_ps_tdma == 1) {
1990 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1991 true, 7);
1992 coex_dm->tdma_adj_type = 7;
1993 } else if (coex_dm->cur_ps_tdma == 2) {
1994 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1995 true, 7);
1996 coex_dm->tdma_adj_type = 7;
1997 } else if (coex_dm->cur_ps_tdma == 3) {
1998 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1999 true, 7);
2000 coex_dm->tdma_adj_type = 7;
2001 } else if (coex_dm->cur_ps_tdma == 4) {
2002 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2003 true, 8);
2004 coex_dm->tdma_adj_type = 8;
2005 }
2006 if (coex_dm->cur_ps_tdma == 9) {
2007 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2008 true, 15);
2009 coex_dm->tdma_adj_type = 15;
2010 } else if (coex_dm->cur_ps_tdma == 10) {
2011 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2012 true, 15);
2013 coex_dm->tdma_adj_type = 15;
2014 } else if (coex_dm->cur_ps_tdma == 11) {
2015 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2016 true, 15);
2017 coex_dm->tdma_adj_type = 15;
2018 } else if (coex_dm->cur_ps_tdma == 12) {
2019 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2020 true, 16);
2021 coex_dm->tdma_adj_type = 16;
2022 }
2023 if (result == -1) {
2024 if (coex_dm->cur_ps_tdma == 5) {
2025 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2026 true, 7);
2027 coex_dm->tdma_adj_type = 7;
2028 } else if (coex_dm->cur_ps_tdma == 6) {
2029 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2030 true, 7);
2031 coex_dm->tdma_adj_type = 7;
2032 } else if (coex_dm->cur_ps_tdma == 7) {
2033 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2034 true, 8);
2035 coex_dm->tdma_adj_type = 8;
2036 } else if (coex_dm->cur_ps_tdma == 13) {
2037 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2038 true, 15);
2039 coex_dm->tdma_adj_type = 15;
2040 } else if (coex_dm->cur_ps_tdma == 14) {
2041 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2042 true, 15);
2043 coex_dm->tdma_adj_type = 15;
2044 } else if (coex_dm->cur_ps_tdma == 15) {
2045 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2046 true, 16);
2047 coex_dm->tdma_adj_type = 16;
2048 }
2049 } else if (result == 1) {
2050 if (coex_dm->cur_ps_tdma == 8) {
2051 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2052 true, 7);
2053 coex_dm->tdma_adj_type = 7;
2054 } else if (coex_dm->cur_ps_tdma == 7) {
2055 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2056 true, 7);
2057 coex_dm->tdma_adj_type = 7;
2058 } else if (coex_dm->cur_ps_tdma == 6) {
2059 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2060 true, 7);
2061 coex_dm->tdma_adj_type = 7;
2062 } else if (coex_dm->cur_ps_tdma == 16) {
2063 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2064 true, 15);
2065 coex_dm->tdma_adj_type = 15;
2066 } else if (coex_dm->cur_ps_tdma == 15) {
2067 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2068 true, 15);
2069 coex_dm->tdma_adj_type = 15;
2070 } else if (coex_dm->cur_ps_tdma == 14) {
2071 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2072 true, 15);
2073 coex_dm->tdma_adj_type = 15;
2074 }
2075 }
2076 } else {
2077 BTC_PRINT(BTC_MSG_ALGORITHM,
2078 ALGO_TRACE_FW_DETAIL,
2079 "[BTCoex], TxPause = 0\n");
2080 if (coex_dm->cur_ps_tdma == 5) {
2081 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2082 true, 3);
2083 coex_dm->tdma_adj_type = 3;
2084 } else if (coex_dm->cur_ps_tdma == 6) {
2085 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2086 true, 3);
2087 coex_dm->tdma_adj_type = 3;
2088 } else if (coex_dm->cur_ps_tdma == 7) {
2089 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2090 true, 3);
2091 coex_dm->tdma_adj_type = 3;
2092 } else if (coex_dm->cur_ps_tdma == 8) {
2093 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2094 true, 4);
2095 coex_dm->tdma_adj_type = 4;
2096 }
2097 if (coex_dm->cur_ps_tdma == 13) {
2098 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2099 true, 11);
2100 coex_dm->tdma_adj_type = 11;
2101 } else if (coex_dm->cur_ps_tdma == 14) {
2102 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2103 true, 11);
2104 coex_dm->tdma_adj_type = 11;
2105 } else if (coex_dm->cur_ps_tdma == 15) {
2106 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2107 true, 11);
2108 coex_dm->tdma_adj_type = 11;
2109 } else if (coex_dm->cur_ps_tdma == 16) {
2110 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2111 true, 12);
2112 coex_dm->tdma_adj_type = 12;
2113 }
2114 if (result == -1) {
2115 if (coex_dm->cur_ps_tdma == 1) {
2116 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2117 true, 3);
2118 coex_dm->tdma_adj_type = 3;
2119 } else if (coex_dm->cur_ps_tdma == 2) {
2120 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2121 true, 3);
2122 coex_dm->tdma_adj_type = 3;
2123 } else if (coex_dm->cur_ps_tdma == 3) {
2124 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2125 true, 4);
2126 coex_dm->tdma_adj_type = 4;
2127 } else if (coex_dm->cur_ps_tdma == 9) {
2128 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2129 true, 11);
2130 coex_dm->tdma_adj_type = 11;
2131 } else if (coex_dm->cur_ps_tdma == 10) {
2132 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2133 true, 11);
2134 coex_dm->tdma_adj_type = 11;
2135 } else if (coex_dm->cur_ps_tdma == 11) {
2136 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2137 true, 12);
2138 coex_dm->tdma_adj_type = 12;
2139 }
2140 } else if (result == 1) {
2141 if (coex_dm->cur_ps_tdma == 4) {
2142 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2143 true, 3);
2144 coex_dm->tdma_adj_type = 3;
2145 } else if (coex_dm->cur_ps_tdma == 3) {
2146 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2147 true, 3);
2148 coex_dm->tdma_adj_type = 3;
2149 } else if (coex_dm->cur_ps_tdma == 2) {
2150 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2151 true, 3);
2152 coex_dm->tdma_adj_type = 3;
2153 } else if (coex_dm->cur_ps_tdma == 12) {
2154 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2155 true, 11);
2156 coex_dm->tdma_adj_type = 11;
2157 } else if (coex_dm->cur_ps_tdma == 11) {
2158 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2159 true, 11);
2160 coex_dm->tdma_adj_type = 11;
2161 } else if (coex_dm->cur_ps_tdma == 10) {
2162 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2163 true, 11);
2164 coex_dm->tdma_adj_type = 11;
2165 }
2166 }
2167 }
2168}
2169
2170static void halbtc8192e2ant_tdma_duration_adjust(struct btc_coexist *btcoexist,
2171 bool sco_hid, bool tx_pause,
2172 u8 max_interval)
2173{
2174 static int up, dn, m, n, wait_cnt;
2175 /* 0: no change, +1: increase WiFi duration,
2176 * -1: decrease WiFi duration
2177 */
2178 int result;
2179 u8 retry_cnt = 0;
2180
2181 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW,
2182 "[BTCoex], TdmaDurationAdjust()\n");
2183
2184 if (!coex_dm->auto_tdma_adjust) {
2185 coex_dm->auto_tdma_adjust = true;
2186 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
2187 "[BTCoex], first run TdmaDurationAdjust()!!\n");
2188 if (sco_hid) {
2189 if (tx_pause) {
2190 if (max_interval == 1) {
2191 halbtc8192e2ant_ps_tdma(btcoexist,
2192 NORMAL_EXEC,
2193 true, 13);
2194 coex_dm->tdma_adj_type = 13;
2195 } else if (max_interval == 2) {
2196 halbtc8192e2ant_ps_tdma(btcoexist,
2197 NORMAL_EXEC,
2198 true, 14);
2199 coex_dm->tdma_adj_type = 14;
2200 } else if (max_interval == 3) {
2201 halbtc8192e2ant_ps_tdma(btcoexist,
2202 NORMAL_EXEC,
2203 true, 15);
2204 coex_dm->tdma_adj_type = 15;
2205 } else {
2206 halbtc8192e2ant_ps_tdma(btcoexist,
2207 NORMAL_EXEC,
2208 true, 15);
2209 coex_dm->tdma_adj_type = 15;
2210 }
2211 } else {
2212 if (max_interval == 1) {
2213 halbtc8192e2ant_ps_tdma(btcoexist,
2214 NORMAL_EXEC,
2215 true, 9);
2216 coex_dm->tdma_adj_type = 9;
2217 } else if (max_interval == 2) {
2218 halbtc8192e2ant_ps_tdma(btcoexist,
2219 NORMAL_EXEC,
2220 true, 10);
2221 coex_dm->tdma_adj_type = 10;
2222 } else if (max_interval == 3) {
2223 halbtc8192e2ant_ps_tdma(btcoexist,
2224 NORMAL_EXEC,
2225 true, 11);
2226 coex_dm->tdma_adj_type = 11;
2227 } else {
2228 halbtc8192e2ant_ps_tdma(btcoexist,
2229 NORMAL_EXEC,
2230 true, 11);
2231 coex_dm->tdma_adj_type = 11;
2232 }
2233 }
2234 } else {
2235 if (tx_pause) {
2236 if (max_interval == 1) {
2237 halbtc8192e2ant_ps_tdma(btcoexist,
2238 NORMAL_EXEC,
2239 true, 5);
2240 coex_dm->tdma_adj_type = 5;
2241 } else if (max_interval == 2) {
2242 halbtc8192e2ant_ps_tdma(btcoexist,
2243 NORMAL_EXEC,
2244 true, 6);
2245 coex_dm->tdma_adj_type = 6;
2246 } else if (max_interval == 3) {
2247 halbtc8192e2ant_ps_tdma(btcoexist,
2248 NORMAL_EXEC,
2249 true, 7);
2250 coex_dm->tdma_adj_type = 7;
2251 } else {
2252 halbtc8192e2ant_ps_tdma(btcoexist,
2253 NORMAL_EXEC,
2254 true, 7);
2255 coex_dm->tdma_adj_type = 7;
2256 }
2257 } else {
2258 if (max_interval == 1) {
2259 halbtc8192e2ant_ps_tdma(btcoexist,
2260 NORMAL_EXEC,
2261 true, 1);
2262 coex_dm->tdma_adj_type = 1;
2263 } else if (max_interval == 2) {
2264 halbtc8192e2ant_ps_tdma(btcoexist,
2265 NORMAL_EXEC,
2266 true, 2);
2267 coex_dm->tdma_adj_type = 2;
2268 } else if (max_interval == 3) {
2269 halbtc8192e2ant_ps_tdma(btcoexist,
2270 NORMAL_EXEC,
2271 true, 3);
2272 coex_dm->tdma_adj_type = 3;
2273 } else {
2274 halbtc8192e2ant_ps_tdma(btcoexist,
2275 NORMAL_EXEC,
2276 true, 3);
2277 coex_dm->tdma_adj_type = 3;
2278 }
2279 }
2280 }
2281
2282 up = 0;
2283 dn = 0;
2284 m = 1;
2285 n = 3;
2286 result = 0;
2287 wait_cnt = 0;
2288 } else {
2289 /* accquire the BT TRx retry count from BT_Info byte2 */
2290 retry_cnt = coex_sta->bt_retry_cnt;
2291 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
2292 "[BTCoex], retry_cnt = %d\n", retry_cnt);
2293 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
2294 "[BTCoex], up=%d, dn=%d, m=%d, n=%d, wait_cnt=%d\n",
2295 up, dn, m, n, wait_cnt);
2296 result = 0;
2297 wait_cnt++;
2298 /* no retry in the last 2-second duration */
2299 if (retry_cnt == 0) {
2300 up++;
2301 dn--;
2302
2303 if (dn <= 0)
2304 dn = 0;
2305
2306 if (up >= n) {
2307 wait_cnt = 0;
2308 n = 3;
2309 up = 0;
2310 dn = 0;
2311 result = 1;
2312 BTC_PRINT(BTC_MSG_ALGORITHM,
2313 ALGO_TRACE_FW_DETAIL,
2314 "[BTCoex]Increase wifi duration!!\n");
2315 }
2316 } else if (retry_cnt <= 3) {
2317 up--;
2318 dn++;
2319
2320 if (up <= 0)
2321 up = 0;
2322
2323 if (dn == 2) {
2324 if (wait_cnt <= 2)
2325 m++;
2326 else
2327 m = 1;
2328
2329 if (m >= 20)
2330 m = 20;
2331
2332 n = 3 * m;
2333 up = 0;
2334 dn = 0;
2335 wait_cnt = 0;
2336 result = -1;
2337 BTC_PRINT(BTC_MSG_ALGORITHM,
2338 ALGO_TRACE_FW_DETAIL,
2339 "Reduce wifi duration for retry<3\n");
2340 }
2341 } else {
2342 if (wait_cnt == 1)
2343 m++;
2344 else
2345 m = 1;
2346
2347 if (m >= 20)
2348 m = 20;
2349
2350 n = 3*m;
2351 up = 0;
2352 dn = 0;
2353 wait_cnt = 0;
2354 result = -1;
2355 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
2356 "Decrease wifi duration for retryCounter>3!!\n");
2357 }
2358
2359 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
2360 "[BTCoex], max Interval = %d\n", max_interval);
2361 if (max_interval == 1)
2362 btc8192e_int1(btcoexist, tx_pause, result);
2363 else if (max_interval == 2)
2364 btc8192e_int2(btcoexist, tx_pause, result);
2365 else if (max_interval == 3)
2366 btc8192e_int3(btcoexist, tx_pause, result);
2367 }
2368
2369 /* if current PsTdma not match with
2370 * the recorded one (when scan, dhcp...),
2371 * then we have to adjust it back to the previous record one.
2372 */
2373 if (coex_dm->cur_ps_tdma != coex_dm->tdma_adj_type) {
2374 bool scan = false, link = false, roam = false;
2375
2376 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
2377 "[BTCoex], PsTdma type dismatch!!!, ");
2378 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
2379 "curPsTdma=%d, recordPsTdma=%d\n",
2380 coex_dm->cur_ps_tdma, coex_dm->tdma_adj_type);
2381
2382 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan);
2383 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link);
2384 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam);
2385
2386 if (!scan && !link && !roam)
2387 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2388 true,
2389 coex_dm->tdma_adj_type);
2390 else
2391 BTC_PRINT(BTC_MSG_ALGORITHM,
2392 ALGO_TRACE_FW_DETAIL,
2393 "[BTCoex], roaming/link/scan is under progress, will adjust next time!!!\n");
2394 }
2395}
2396
2397/* SCO only or SCO+PAN(HS) */
2398static void halbtc8192e2ant_action_sco(struct btc_coexist *btcoexist)
2399{
2400 u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_STAY_LOW;
2401 u32 wifi_bw;
2402
2403 wifirssi_state = halbtc8192e2ant_wifirssi_state(btcoexist, 0, 2, 15, 0);
2404
2405 halbtc8192e2ant_switch_sstype(btcoexist, NORMAL_EXEC, 1);
2406 halbtc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8);
2407
2408 halbtc8192e2ant_fw_dac_swinglvl(btcoexist, NORMAL_EXEC, 6);
2409
2410 btc8192e2ant_coex_tbl_w_type(btcoexist, NORMAL_EXEC, 4);
2411
2412 btrssi_state = halbtc8192e2ant_btrssi_state(3, 34, 42);
2413
2414 if ((btrssi_state == BTC_RSSI_STATE_LOW) ||
2415 (btrssi_state == BTC_RSSI_STATE_STAY_LOW)) {
2416 halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0);
2417 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 13);
2418 } else if ((btrssi_state == BTC_RSSI_STATE_MEDIUM) ||
2419 (btrssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) {
2420 halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 2);
2421 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 9);
2422 } else if ((btrssi_state == BTC_RSSI_STATE_HIGH) ||
2423 (btrssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2424 halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 4);
2425 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 9);
2426 }
2427
2428 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
2429
2430 /* sw mechanism */
2431 if (BTC_WIFI_BW_HT40 == wifi_bw) {
2432 if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
2433 (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2434 btc8192e2ant_sw_mec1(btcoexist, true, true,
2435 false, false);
2436 btc8192e2ant_sw_mec2(btcoexist, true, false,
2437 false, 0x6);
2438 } else {
2439 btc8192e2ant_sw_mec1(btcoexist, true, true,
2440 false, false);
2441 btc8192e2ant_sw_mec2(btcoexist, false, false,
2442 false, 0x6);
2443 }
2444 } else {
2445 if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
2446 (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2447 btc8192e2ant_sw_mec1(btcoexist, false, true,
2448 false, false);
2449 btc8192e2ant_sw_mec2(btcoexist, true, false,
2450 false, 0x6);
2451 } else {
2452 btc8192e2ant_sw_mec1(btcoexist, false, true,
2453 false, false);
2454 btc8192e2ant_sw_mec2(btcoexist, false, false,
2455 false, 0x6);
2456 }
2457 }
2458}
2459
2460static void halbtc8192e2ant_action_sco_pan(struct btc_coexist *btcoexist)
2461{
2462 u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_STAY_LOW;
2463 u32 wifi_bw;
2464
2465 wifirssi_state = halbtc8192e2ant_wifirssi_state(btcoexist, 0, 2, 15, 0);
2466
2467 halbtc8192e2ant_switch_sstype(btcoexist, NORMAL_EXEC, 1);
2468 halbtc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8);
2469
2470 halbtc8192e2ant_fw_dac_swinglvl(btcoexist, NORMAL_EXEC, 6);
2471
2472 btc8192e2ant_coex_tbl_w_type(btcoexist, NORMAL_EXEC, 4);
2473
2474 btrssi_state = halbtc8192e2ant_btrssi_state(3, 34, 42);
2475
2476 if ((btrssi_state == BTC_RSSI_STATE_LOW) ||
2477 (btrssi_state == BTC_RSSI_STATE_STAY_LOW)) {
2478 halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0);
2479 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14);
2480 } else if ((btrssi_state == BTC_RSSI_STATE_MEDIUM) ||
2481 (btrssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) {
2482 halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 2);
2483 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 10);
2484 } else if ((btrssi_state == BTC_RSSI_STATE_HIGH) ||
2485 (btrssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2486 halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 4);
2487 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 10);
2488 }
2489
2490 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
2491
2492 /* sw mechanism */
2493 if (BTC_WIFI_BW_HT40 == wifi_bw) {
2494 if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
2495 (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2496 btc8192e2ant_sw_mec1(btcoexist, true, true,
2497 false, false);
2498 btc8192e2ant_sw_mec2(btcoexist, true, false,
2499 false, 0x6);
2500 } else {
2501 btc8192e2ant_sw_mec1(btcoexist, true, true,
2502 false, false);
2503 btc8192e2ant_sw_mec2(btcoexist, false, false,
2504 false, 0x6);
2505 }
2506 } else {
2507 if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
2508 (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2509 btc8192e2ant_sw_mec1(btcoexist, false, true,
2510 false, false);
2511 btc8192e2ant_sw_mec2(btcoexist, true, false,
2512 false, 0x6);
2513 } else {
2514 btc8192e2ant_sw_mec1(btcoexist, false, true,
2515 false, false);
2516 btc8192e2ant_sw_mec2(btcoexist, false, false,
2517 false, 0x6);
2518 }
2519 }
2520}
2521
2522static void halbtc8192e2ant_action_hid(struct btc_coexist *btcoexist)
2523{
2524 u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_HIGH;
2525 u32 wifi_bw;
2526
2527 wifirssi_state = halbtc8192e2ant_wifirssi_state(btcoexist, 0, 2, 15, 0);
2528 btrssi_state = halbtc8192e2ant_btrssi_state(3, 34, 42);
2529
2530 halbtc8192e2ant_switch_sstype(btcoexist, NORMAL_EXEC, 1);
2531 halbtc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8);
2532
2533 halbtc8192e2ant_fw_dac_swinglvl(btcoexist, NORMAL_EXEC, 6);
2534
2535 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
2536
2537 btc8192e2ant_coex_tbl_w_type(btcoexist, NORMAL_EXEC, 3);
2538
2539 if ((btrssi_state == BTC_RSSI_STATE_LOW) ||
2540 (btrssi_state == BTC_RSSI_STATE_STAY_LOW)) {
2541 halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0);
2542 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 13);
2543 } else if ((btrssi_state == BTC_RSSI_STATE_MEDIUM) ||
2544 (btrssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) {
2545 halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 2);
2546 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 9);
2547 } else if ((btrssi_state == BTC_RSSI_STATE_HIGH) ||
2548 (btrssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2549 halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 4);
2550 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 9);
2551 }
2552
2553 /* sw mechanism */
2554 if (BTC_WIFI_BW_HT40 == wifi_bw) {
2555 if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
2556 (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2557 btc8192e2ant_sw_mec1(btcoexist, true, true,
2558 false, false);
2559 btc8192e2ant_sw_mec2(btcoexist, true, false,
2560 false, 0x18);
2561 } else {
2562 btc8192e2ant_sw_mec1(btcoexist, true, true,
2563 false, false);
2564 btc8192e2ant_sw_mec2(btcoexist, false, false,
2565 false, 0x18);
2566 }
2567 } else {
2568 if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
2569 (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2570 btc8192e2ant_sw_mec1(btcoexist, false, true,
2571 false, false);
2572 btc8192e2ant_sw_mec2(btcoexist, true, false,
2573 false, 0x18);
2574 } else {
2575 btc8192e2ant_sw_mec1(btcoexist, false, true,
2576 false, false);
2577 btc8192e2ant_sw_mec2(btcoexist, false, false,
2578 false, 0x18);
2579 }
2580 }
2581}
2582
2583/* A2DP only / PAN(EDR) only/ A2DP+PAN(HS) */
2584static void halbtc8192e2ant_action_a2dp(struct btc_coexist *btcoexist)
2585{
2586 u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_HIGH;
2587 u32 wifi_bw;
2588 bool long_dist = false;
2589
2590 wifirssi_state = halbtc8192e2ant_wifirssi_state(btcoexist, 0, 2, 15, 0);
2591 btrssi_state = halbtc8192e2ant_btrssi_state(3, 34, 42);
2592
2593 if ((btrssi_state == BTC_RSSI_STATE_LOW ||
2594 btrssi_state == BTC_RSSI_STATE_STAY_LOW) &&
2595 (wifirssi_state == BTC_RSSI_STATE_LOW ||
2596 wifirssi_state == BTC_RSSI_STATE_STAY_LOW)) {
2597 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2598 "[BTCoex], A2dp, wifi/bt rssi both LOW!!\n");
2599 long_dist = true;
2600 }
2601 if (long_dist) {
2602 halbtc8192e2ant_switch_sstype(btcoexist, NORMAL_EXEC, 2);
2603 halbtc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, true,
2604 0x4);
2605 } else {
2606 halbtc8192e2ant_switch_sstype(btcoexist, NORMAL_EXEC, 1);
2607 halbtc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false,
2608 0x8);
2609 }
2610
2611 halbtc8192e2ant_fw_dac_swinglvl(btcoexist, NORMAL_EXEC, 6);
2612
2613 if (long_dist)
2614 btc8192e2ant_coex_tbl_w_type(btcoexist, NORMAL_EXEC, 0);
2615 else
2616 btc8192e2ant_coex_tbl_w_type(btcoexist, NORMAL_EXEC, 2);
2617
2618 if (long_dist) {
2619 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 17);
2620 coex_dm->auto_tdma_adjust = false;
2621 halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0);
2622 } else {
2623 if ((btrssi_state == BTC_RSSI_STATE_LOW) ||
2624 (btrssi_state == BTC_RSSI_STATE_STAY_LOW)) {
2625 halbtc8192e2ant_tdma_duration_adjust(btcoexist, false,
2626 true, 1);
2627 halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0);
2628 } else if ((btrssi_state == BTC_RSSI_STATE_MEDIUM) ||
2629 (btrssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) {
2630 halbtc8192e2ant_tdma_duration_adjust(btcoexist, false,
2631 false, 1);
2632 halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 2);
2633 } else if ((btrssi_state == BTC_RSSI_STATE_HIGH) ||
2634 (btrssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2635 halbtc8192e2ant_tdma_duration_adjust(btcoexist, false,
2636 false, 1);
2637 halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 4);
2638 }
2639 }
2640
2641 /* sw mechanism */
2642 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
2643 if (BTC_WIFI_BW_HT40 == wifi_bw) {
2644 if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
2645 (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2646 btc8192e2ant_sw_mec1(btcoexist, true, false,
2647 false, false);
2648 btc8192e2ant_sw_mec2(btcoexist, true, false,
2649 false, 0x18);
2650 } else {
2651 btc8192e2ant_sw_mec1(btcoexist, true, false,
2652 false, false);
2653 btc8192e2ant_sw_mec2(btcoexist, false, false,
2654 false, 0x18);
2655 }
2656 } else {
2657 if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
2658 (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2659 btc8192e2ant_sw_mec1(btcoexist, false, false,
2660 false, false);
2661 btc8192e2ant_sw_mec2(btcoexist, true, false,
2662 false, 0x18);
2663 } else {
2664 btc8192e2ant_sw_mec1(btcoexist, false, false,
2665 false, false);
2666 btc8192e2ant_sw_mec2(btcoexist, false, false,
2667 false, 0x18);
2668 }
2669 }
2670}
2671
2672static void halbtc8192e2ant_action_a2dp_pan_hs(struct btc_coexist *btcoexist)
2673{
2674 u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_HIGH;
2675 u32 wifi_bw;
2676
2677 wifirssi_state = halbtc8192e2ant_wifirssi_state(btcoexist, 0, 2, 15, 0);
2678 btrssi_state = halbtc8192e2ant_btrssi_state(3, 34, 42);
2679
2680 halbtc8192e2ant_switch_sstype(btcoexist, NORMAL_EXEC, 1);
2681 halbtc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8);
2682
2683 halbtc8192e2ant_fw_dac_swinglvl(btcoexist, NORMAL_EXEC, 6);
2684 btc8192e2ant_coex_tbl_w_type(btcoexist, NORMAL_EXEC, 2);
2685
2686 if ((btrssi_state == BTC_RSSI_STATE_LOW) ||
2687 (btrssi_state == BTC_RSSI_STATE_STAY_LOW)) {
2688 halbtc8192e2ant_tdma_duration_adjust(btcoexist, false, true, 2);
2689 halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0);
2690 } else if ((btrssi_state == BTC_RSSI_STATE_MEDIUM) ||
2691 (btrssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) {
2692 halbtc8192e2ant_tdma_duration_adjust(btcoexist, false,
2693 false, 2);
2694 halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 2);
2695 } else if ((btrssi_state == BTC_RSSI_STATE_HIGH) ||
2696 (btrssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2697 halbtc8192e2ant_tdma_duration_adjust(btcoexist, false,
2698 false, 2);
2699 halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 4);
2700 }
2701
2702 /* sw mechanism */
2703 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
2704 if (BTC_WIFI_BW_HT40 == wifi_bw) {
2705 if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
2706 (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2707 btc8192e2ant_sw_mec1(btcoexist, true, false,
2708 false, false);
2709 btc8192e2ant_sw_mec2(btcoexist, true, false,
2710 true, 0x6);
2711 } else {
2712 btc8192e2ant_sw_mec1(btcoexist, true, false,
2713 false, false);
2714 btc8192e2ant_sw_mec2(btcoexist, false, false,
2715 true, 0x6);
2716 }
2717 } else {
2718 if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
2719 (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2720 btc8192e2ant_sw_mec1(btcoexist, false, false,
2721 false, false);
2722 btc8192e2ant_sw_mec2(btcoexist, true, false,
2723 true, 0x6);
2724 } else {
2725 btc8192e2ant_sw_mec1(btcoexist, false, false,
2726 false, false);
2727 btc8192e2ant_sw_mec2(btcoexist, false, false,
2728 true, 0x6);
2729 }
2730 }
2731}
2732
2733static void halbtc8192e2ant_action_pan_edr(struct btc_coexist *btcoexist)
2734{
2735 u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_HIGH;
2736 u32 wifi_bw;
2737
2738 wifirssi_state = halbtc8192e2ant_wifirssi_state(btcoexist, 0, 2, 15, 0);
2739 btrssi_state = halbtc8192e2ant_btrssi_state(3, 34, 42);
2740
2741 halbtc8192e2ant_switch_sstype(btcoexist, NORMAL_EXEC, 1);
2742 halbtc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8);
2743
2744 halbtc8192e2ant_fw_dac_swinglvl(btcoexist, NORMAL_EXEC, 6);
2745
2746 btc8192e2ant_coex_tbl_w_type(btcoexist, NORMAL_EXEC, 2);
2747
2748 if ((btrssi_state == BTC_RSSI_STATE_LOW) ||
2749 (btrssi_state == BTC_RSSI_STATE_STAY_LOW)) {
2750 halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0);
2751 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 5);
2752 } else if ((btrssi_state == BTC_RSSI_STATE_MEDIUM) ||
2753 (btrssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) {
2754 halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 2);
2755 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 1);
2756 } else if ((btrssi_state == BTC_RSSI_STATE_HIGH) ||
2757 (btrssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2758 halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 4);
2759 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 1);
2760 }
2761
2762 /* sw mechanism */
2763 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
2764 if (BTC_WIFI_BW_HT40 == wifi_bw) {
2765 if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
2766 (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2767 btc8192e2ant_sw_mec1(btcoexist, true, false,
2768 false, false);
2769 btc8192e2ant_sw_mec2(btcoexist, true, false,
2770 false, 0x18);
2771 } else {
2772 btc8192e2ant_sw_mec1(btcoexist, true, false,
2773 false, false);
2774 btc8192e2ant_sw_mec2(btcoexist, false, false,
2775 false, 0x18);
2776 }
2777 } else {
2778 if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
2779 (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2780 btc8192e2ant_sw_mec1(btcoexist, false, false,
2781 false, false);
2782 btc8192e2ant_sw_mec2(btcoexist, true, false,
2783 false, 0x18);
2784 } else {
2785 btc8192e2ant_sw_mec1(btcoexist, false, false,
2786 false, false);
2787 btc8192e2ant_sw_mec2(btcoexist, false, false,
2788 false, 0x18);
2789 }
2790 }
2791}
2792
2793/* PAN(HS) only */
2794static void halbtc8192e2ant_action_pan_hs(struct btc_coexist *btcoexist)
2795{
2796 u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_HIGH;
2797 u32 wifi_bw;
2798
2799 wifirssi_state = halbtc8192e2ant_wifirssi_state(btcoexist, 0, 2, 15, 0);
2800 btrssi_state = halbtc8192e2ant_btrssi_state(3, 34, 42);
2801
2802 halbtc8192e2ant_switch_sstype(btcoexist, NORMAL_EXEC, 1);
2803 halbtc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8);
2804
2805 halbtc8192e2ant_fw_dac_swinglvl(btcoexist, NORMAL_EXEC, 6);
2806
2807 btc8192e2ant_coex_tbl_w_type(btcoexist, NORMAL_EXEC, 2);
2808
2809 if ((btrssi_state == BTC_RSSI_STATE_LOW) ||
2810 (btrssi_state == BTC_RSSI_STATE_STAY_LOW)) {
2811 halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0);
2812 } else if ((btrssi_state == BTC_RSSI_STATE_MEDIUM) ||
2813 (btrssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) {
2814 halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 2);
2815 } else if ((btrssi_state == BTC_RSSI_STATE_HIGH) ||
2816 (btrssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2817 halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 4);
2818 }
2819 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1);
2820
2821 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
2822 if (BTC_WIFI_BW_HT40 == wifi_bw) {
2823 if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
2824 (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2825 btc8192e2ant_sw_mec1(btcoexist, true, false,
2826 false, false);
2827 btc8192e2ant_sw_mec2(btcoexist, true, false,
2828 false, 0x18);
2829 } else {
2830 btc8192e2ant_sw_mec1(btcoexist, true, false,
2831 false, false);
2832 btc8192e2ant_sw_mec2(btcoexist, false, false,
2833 false, 0x18);
2834 }
2835 } else {
2836 if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
2837 (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2838 btc8192e2ant_sw_mec1(btcoexist, false, false,
2839 false, false);
2840 btc8192e2ant_sw_mec2(btcoexist, true, false,
2841 false, 0x18);
2842 } else {
2843 btc8192e2ant_sw_mec1(btcoexist, false, false,
2844 false, false);
2845 btc8192e2ant_sw_mec2(btcoexist, false, false,
2846 false, 0x18);
2847 }
2848 }
2849}
2850
2851/* PAN(EDR)+A2DP */
2852static void halbtc8192e2ant_action_pan_edr_a2dp(struct btc_coexist *btcoexist)
2853{
2854 u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_HIGH;
2855 u32 wifi_bw;
2856
2857 wifirssi_state = halbtc8192e2ant_wifirssi_state(btcoexist, 0, 2, 15, 0);
2858 btrssi_state = halbtc8192e2ant_btrssi_state(3, 34, 42);
2859
2860 halbtc8192e2ant_switch_sstype(btcoexist, NORMAL_EXEC, 1);
2861 halbtc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8);
2862
2863 halbtc8192e2ant_fw_dac_swinglvl(btcoexist, NORMAL_EXEC, 6);
2864
2865 btc8192e2ant_coex_tbl_w_type(btcoexist, NORMAL_EXEC, 2);
2866
2867 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
2868
2869 if ((btrssi_state == BTC_RSSI_STATE_LOW) ||
2870 (btrssi_state == BTC_RSSI_STATE_STAY_LOW)) {
2871 halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0);
2872 halbtc8192e2ant_tdma_duration_adjust(btcoexist, false, true, 3);
2873 } else if ((btrssi_state == BTC_RSSI_STATE_MEDIUM) ||
2874 (btrssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) {
2875 halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 2);
2876 halbtc8192e2ant_tdma_duration_adjust(btcoexist, false,
2877 false, 3);
2878 } else if ((btrssi_state == BTC_RSSI_STATE_HIGH) ||
2879 (btrssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2880 halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 4);
2881 halbtc8192e2ant_tdma_duration_adjust(btcoexist, false,
2882 false, 3);
2883 }
2884
2885 /* sw mechanism */
2886 if (BTC_WIFI_BW_HT40 == wifi_bw) {
2887 if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
2888 (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2889 btc8192e2ant_sw_mec1(btcoexist, true, false,
2890 false, false);
2891 btc8192e2ant_sw_mec2(btcoexist, true, false,
2892 false, 0x18);
2893 } else {
2894 btc8192e2ant_sw_mec1(btcoexist, true, false,
2895 false, false);
2896 btc8192e2ant_sw_mec2(btcoexist, false, false,
2897 false, 0x18);
2898 }
2899 } else {
2900 if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
2901 (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2902 btc8192e2ant_sw_mec1(btcoexist, false, false,
2903 false, false);
2904 btc8192e2ant_sw_mec2(btcoexist, true, false,
2905 false, 0x18);
2906 } else {
2907 btc8192e2ant_sw_mec1(btcoexist, false, false,
2908 false, false);
2909 btc8192e2ant_sw_mec2(btcoexist, false, false,
2910 false, 0x18);
2911 }
2912 }
2913}
2914
2915static void halbtc8192e2ant_action_pan_edr_hid(struct btc_coexist *btcoexist)
2916{
2917 u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_HIGH;
2918 u32 wifi_bw;
2919
2920 wifirssi_state = halbtc8192e2ant_wifirssi_state(btcoexist, 0, 2, 15, 0);
2921 btrssi_state = halbtc8192e2ant_btrssi_state(3, 34, 42);
2922
2923 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
2924
2925 halbtc8192e2ant_switch_sstype(btcoexist, NORMAL_EXEC, 1);
2926 halbtc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8);
2927
2928 halbtc8192e2ant_fw_dac_swinglvl(btcoexist, NORMAL_EXEC, 6);
2929
2930 btc8192e2ant_coex_tbl_w_type(btcoexist, NORMAL_EXEC, 3);
2931
2932 if ((btrssi_state == BTC_RSSI_STATE_LOW) ||
2933 (btrssi_state == BTC_RSSI_STATE_STAY_LOW)) {
2934 halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0);
2935 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14);
2936 } else if ((btrssi_state == BTC_RSSI_STATE_MEDIUM) ||
2937 (btrssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) {
2938 halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 2);
2939 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2940 true, 10);
2941 } else if ((btrssi_state == BTC_RSSI_STATE_HIGH) ||
2942 (btrssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2943 halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 4);
2944 halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2945 true, 10);
2946 }
2947
2948 /* sw mechanism */
2949 if (BTC_WIFI_BW_HT40 == wifi_bw) {
2950 if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
2951 (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2952 btc8192e2ant_sw_mec1(btcoexist, true, true,
2953 false, false);
2954 btc8192e2ant_sw_mec2(btcoexist, true, false,
2955 false, 0x18);
2956 } else {
2957 btc8192e2ant_sw_mec1(btcoexist, true, true,
2958 false, false);
2959 btc8192e2ant_sw_mec2(btcoexist, false, false,
2960 false, 0x18);
2961 }
2962 } else {
2963 if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
2964 (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2965 btc8192e2ant_sw_mec1(btcoexist, false, true,
2966 false, false);
2967 btc8192e2ant_sw_mec2(btcoexist, true, false,
2968 false, 0x18);
2969 } else {
2970 btc8192e2ant_sw_mec1(btcoexist, false, true,
2971 false, false);
2972 btc8192e2ant_sw_mec2(btcoexist, false, false,
2973 false, 0x18);
2974 }
2975 }
2976}
2977
2978/* HID+A2DP+PAN(EDR) */
2979static void btc8192e2ant_action_hid_a2dp_pan_edr(struct btc_coexist *btcoexist)
2980{
2981 u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_HIGH;
2982 u32 wifi_bw;
2983
2984 wifirssi_state = halbtc8192e2ant_wifirssi_state(btcoexist, 0, 2, 15, 0);
2985 btrssi_state = halbtc8192e2ant_btrssi_state(3, 34, 42);
2986
2987 halbtc8192e2ant_switch_sstype(btcoexist, NORMAL_EXEC, 1);
2988 halbtc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8);
2989
2990 halbtc8192e2ant_fw_dac_swinglvl(btcoexist, NORMAL_EXEC, 6);
2991
2992 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
2993
2994 btc8192e2ant_coex_tbl_w_type(btcoexist, NORMAL_EXEC, 3);
2995
2996 if ((btrssi_state == BTC_RSSI_STATE_LOW) ||
2997 (btrssi_state == BTC_RSSI_STATE_STAY_LOW)) {
2998 halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0);
2999 halbtc8192e2ant_tdma_duration_adjust(btcoexist, true, true, 3);
3000 } else if ((btrssi_state == BTC_RSSI_STATE_MEDIUM) ||
3001 (btrssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) {
3002 halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 2);
3003 halbtc8192e2ant_tdma_duration_adjust(btcoexist, true, false, 3);
3004 } else if ((btrssi_state == BTC_RSSI_STATE_HIGH) ||
3005 (btrssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
3006 halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 4);
3007 halbtc8192e2ant_tdma_duration_adjust(btcoexist, true, false, 3);
3008 }
3009
3010 /* sw mechanism */
3011 if (BTC_WIFI_BW_HT40 == wifi_bw) {
3012 if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
3013 (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
3014 btc8192e2ant_sw_mec1(btcoexist, true, true,
3015 false, false);
3016 btc8192e2ant_sw_mec2(btcoexist, true, false,
3017 false, 0x18);
3018 } else {
3019 btc8192e2ant_sw_mec1(btcoexist, true, true,
3020 false, false);
3021 btc8192e2ant_sw_mec2(btcoexist, false, false,
3022 false, 0x18);
3023 }
3024 } else {
3025 if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
3026 (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
3027 btc8192e2ant_sw_mec1(btcoexist, false, true,
3028 false, false);
3029 btc8192e2ant_sw_mec2(btcoexist, true, false,
3030 false, 0x18);
3031 } else {
3032 btc8192e2ant_sw_mec1(btcoexist, false, true,
3033 false, false);
3034 btc8192e2ant_sw_mec2(btcoexist, false, false,
3035 false, 0x18);
3036 }
3037 }
3038}
3039
3040static void halbtc8192e2ant_action_hid_a2dp(struct btc_coexist *btcoexist)
3041{
3042 u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_HIGH;
3043 u32 wifi_bw;
3044
3045 wifirssi_state = halbtc8192e2ant_wifirssi_state(btcoexist, 0, 2, 15, 0);
3046 btrssi_state = halbtc8192e2ant_btrssi_state(3, 34, 42);
3047
3048 halbtc8192e2ant_switch_sstype(btcoexist, NORMAL_EXEC, 1);
3049 halbtc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8);
3050
3051 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
3052
3053 btc8192e2ant_coex_tbl_w_type(btcoexist, NORMAL_EXEC, 3);
3054
3055 if ((btrssi_state == BTC_RSSI_STATE_LOW) ||
3056 (btrssi_state == BTC_RSSI_STATE_STAY_LOW)) {
3057 halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0);
3058 halbtc8192e2ant_tdma_duration_adjust(btcoexist, true, true, 2);
3059 } else if ((btrssi_state == BTC_RSSI_STATE_MEDIUM) ||
3060 (btrssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) {
3061 halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 2);
3062 halbtc8192e2ant_tdma_duration_adjust(btcoexist, true, false, 2);
3063 } else if ((btrssi_state == BTC_RSSI_STATE_HIGH) ||
3064 (btrssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
3065 halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 4);
3066 halbtc8192e2ant_tdma_duration_adjust(btcoexist, true, false, 2);
3067 }
3068
3069 /* sw mechanism */
3070 if (BTC_WIFI_BW_HT40 == wifi_bw) {
3071 if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
3072 (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
3073 btc8192e2ant_sw_mec1(btcoexist, true, true,
3074 false, false);
3075 btc8192e2ant_sw_mec2(btcoexist, true, false,
3076 false, 0x18);
3077 } else {
3078 btc8192e2ant_sw_mec1(btcoexist, true, true,
3079 false, false);
3080 btc8192e2ant_sw_mec2(btcoexist, false, false,
3081 false, 0x18);
3082 }
3083 } else {
3084 if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
3085 (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
3086 btc8192e2ant_sw_mec1(btcoexist, false, true,
3087 false, false);
3088 btc8192e2ant_sw_mec2(btcoexist, true, false,
3089 false, 0x18);
3090 } else {
3091 btc8192e2ant_sw_mec1(btcoexist, false, true,
3092 false, false);
3093 btc8192e2ant_sw_mec2(btcoexist, false, false,
3094 false, 0x18);
3095 }
3096 }
3097}
3098
3099static void halbtc8192e2ant_run_coexist_mechanism(struct btc_coexist *btcoexist)
3100{
3101 u8 algorithm = 0;
3102
3103 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3104 "[BTCoex], RunCoexistMechanism()===>\n");
3105
3106 if (btcoexist->manual_control) {
3107 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3108 "[BTCoex], return for Manual CTRL <===\n");
3109 return;
3110 }
3111
3112 if (coex_sta->under_ips) {
3113 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3114 "[BTCoex], wifi is under IPS !!!\n");
3115 return;
3116 }
3117
3118 algorithm = halbtc8192e2ant_action_algorithm(btcoexist);
3119 if (coex_sta->c2h_bt_inquiry_page &&
3120 (BT_8192E_2ANT_COEX_ALGO_PANHS != algorithm)) {
3121 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3122 "[BTCoex], BT is under inquiry/page scan !!\n");
3123 halbtc8192e2ant_action_bt_inquiry(btcoexist);
3124 return;
3125 }
3126
3127 coex_dm->cur_algorithm = algorithm;
3128 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3129 "[BTCoex], Algorithm = %d\n", coex_dm->cur_algorithm);
3130
3131 if (halbtc8192e2ant_is_common_action(btcoexist)) {
3132 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3133 "[BTCoex], Action 2-Ant common.\n");
3134 coex_dm->auto_tdma_adjust = false;
3135 } else {
3136 if (coex_dm->cur_algorithm != coex_dm->pre_algorithm) {
3137 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3138 "[BTCoex] preAlgorithm=%d, curAlgorithm=%d\n",
3139 coex_dm->pre_algorithm,
3140 coex_dm->cur_algorithm);
3141 coex_dm->auto_tdma_adjust = false;
3142 }
3143 switch (coex_dm->cur_algorithm) {
3144 case BT_8192E_2ANT_COEX_ALGO_SCO:
3145 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3146 "Action 2-Ant, algorithm = SCO.\n");
3147 halbtc8192e2ant_action_sco(btcoexist);
3148 break;
3149 case BT_8192E_2ANT_COEX_ALGO_SCO_PAN:
3150 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3151 "Action 2-Ant, algorithm = SCO+PAN(EDR).\n");
3152 halbtc8192e2ant_action_sco_pan(btcoexist);
3153 break;
3154 case BT_8192E_2ANT_COEX_ALGO_HID:
3155 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3156 "Action 2-Ant, algorithm = HID.\n");
3157 halbtc8192e2ant_action_hid(btcoexist);
3158 break;
3159 case BT_8192E_2ANT_COEX_ALGO_A2DP:
3160 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3161 "Action 2-Ant, algorithm = A2DP.\n");
3162 halbtc8192e2ant_action_a2dp(btcoexist);
3163 break;
3164 case BT_8192E_2ANT_COEX_ALGO_A2DP_PANHS:
3165 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3166 "Action 2-Ant, algorithm = A2DP+PAN(HS).\n");
3167 halbtc8192e2ant_action_a2dp_pan_hs(btcoexist);
3168 break;
3169 case BT_8192E_2ANT_COEX_ALGO_PANEDR:
3170 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3171 "Action 2-Ant, algorithm = PAN(EDR).\n");
3172 halbtc8192e2ant_action_pan_edr(btcoexist);
3173 break;
3174 case BT_8192E_2ANT_COEX_ALGO_PANHS:
3175 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3176 "Action 2-Ant, algorithm = HS mode.\n");
3177 halbtc8192e2ant_action_pan_hs(btcoexist);
3178 break;
3179 case BT_8192E_2ANT_COEX_ALGO_PANEDR_A2DP:
3180 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3181 "Action 2-Ant, algorithm = PAN+A2DP.\n");
3182 halbtc8192e2ant_action_pan_edr_a2dp(btcoexist);
3183 break;
3184 case BT_8192E_2ANT_COEX_ALGO_PANEDR_HID:
3185 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3186 "Action 2-Ant, algorithm = PAN(EDR)+HID.\n");
3187 halbtc8192e2ant_action_pan_edr_hid(btcoexist);
3188 break;
3189 case BT_8192E_2ANT_COEX_ALGO_HID_A2DP_PANEDR:
3190 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3191 "Action 2-Ant, algorithm = HID+A2DP+PAN.\n");
3192 btc8192e2ant_action_hid_a2dp_pan_edr(btcoexist);
3193 break;
3194 case BT_8192E_2ANT_COEX_ALGO_HID_A2DP:
3195 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3196 "Action 2-Ant, algorithm = HID+A2DP.\n");
3197 halbtc8192e2ant_action_hid_a2dp(btcoexist);
3198 break;
3199 default:
3200 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3201 "Action 2-Ant, algorithm = unknown!!\n");
3202 /* halbtc8192e2ant_coex_alloff(btcoexist); */
3203 break;
3204 }
3205 coex_dm->pre_algorithm = coex_dm->cur_algorithm;
3206 }
3207}
3208
3209static void halbtc8192e2ant_init_hwconfig(struct btc_coexist *btcoexist,
3210 bool backup)
3211{
3212 u16 u16tmp = 0;
3213 u8 u8tmp = 0;
3214
3215 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
3216 "[BTCoex], 2Ant Init HW Config!!\n");
3217
3218 if (backup) {
3219 /* backup rf 0x1e value */
3220 coex_dm->bt_rf0x1e_backup =
3221 btcoexist->btc_get_rf_reg(btcoexist, BTC_RF_A,
3222 0x1e, 0xfffff);
3223
3224 coex_dm->backup_arfr_cnt1 = btcoexist->btc_read_4byte(btcoexist,
3225 0x430);
3226 coex_dm->backup_arfr_cnt2 = btcoexist->btc_read_4byte(btcoexist,
3227 0x434);
3228 coex_dm->backup_retrylimit = btcoexist->btc_read_2byte(
3229 btcoexist,
3230 0x42a);
3231 coex_dm->backup_ampdu_maxtime = btcoexist->btc_read_1byte(
3232 btcoexist,
3233 0x456);
3234 }
3235
3236 /* antenna sw ctrl to bt */
3237 btcoexist->btc_write_1byte(btcoexist, 0x4f, 0x6);
3238 btcoexist->btc_write_1byte(btcoexist, 0x944, 0x24);
3239 btcoexist->btc_write_4byte(btcoexist, 0x930, 0x700700);
3240 btcoexist->btc_write_1byte(btcoexist, 0x92c, 0x20);
3241 if (btcoexist->chip_interface == BTC_INTF_USB)
3242 btcoexist->btc_write_4byte(btcoexist, 0x64, 0x30430004);
3243 else
3244 btcoexist->btc_write_4byte(btcoexist, 0x64, 0x30030004);
3245
3246 btc8192e2ant_coex_tbl_w_type(btcoexist, FORCE_EXEC, 0);
3247
3248 /* antenna switch control parameter */
3249 btcoexist->btc_write_4byte(btcoexist, 0x858, 0x55555555);
3250
3251 /* coex parameters */
3252 btcoexist->btc_write_1byte(btcoexist, 0x778, 0x3);
3253 /* 0x790[5:0] = 0x5 */
3254 u8tmp = btcoexist->btc_read_1byte(btcoexist, 0x790);
3255 u8tmp &= 0xc0;
3256 u8tmp |= 0x5;
3257 btcoexist->btc_write_1byte(btcoexist, 0x790, u8tmp);
3258
3259 /* enable counter statistics */
3260 btcoexist->btc_write_1byte(btcoexist, 0x76e, 0x4);
3261
3262 /* enable PTA */
3263 btcoexist->btc_write_1byte(btcoexist, 0x40, 0x20);
3264 /* enable mailbox interface */
3265 u16tmp = btcoexist->btc_read_2byte(btcoexist, 0x40);
3266 u16tmp |= BIT9;
3267 btcoexist->btc_write_2byte(btcoexist, 0x40, u16tmp);
3268
3269 /* enable PTA I2C mailbox */
3270 u8tmp = btcoexist->btc_read_1byte(btcoexist, 0x101);
3271 u8tmp |= BIT4;
3272 btcoexist->btc_write_1byte(btcoexist, 0x101, u8tmp);
3273
3274 /* enable bt clock when wifi is disabled. */
3275 u8tmp = btcoexist->btc_read_1byte(btcoexist, 0x93);
3276 u8tmp |= BIT0;
3277 btcoexist->btc_write_1byte(btcoexist, 0x93, u8tmp);
3278 /* enable bt clock when suspend. */
3279 u8tmp = btcoexist->btc_read_1byte(btcoexist, 0x7);
3280 u8tmp |= BIT0;
3281 btcoexist->btc_write_1byte(btcoexist, 0x7, u8tmp);
3282}
3283
3284/*************************************************************
3285 * work around function start with wa_halbtc8192e2ant_
3286 *************************************************************/
3287
3288/************************************************************
3289 * extern function start with EXhalbtc8192e2ant_
3290 ************************************************************/
3291
3292void ex_halbtc8192e2ant_init_hwconfig(struct btc_coexist *btcoexist)
3293{
3294 halbtc8192e2ant_init_hwconfig(btcoexist, true);
3295}
3296
3297void ex_halbtc8192e2ant_init_coex_dm(struct btc_coexist *btcoexist)
3298{
3299 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
3300 "[BTCoex], Coex Mechanism Init!!\n");
3301 halbtc8192e2ant_init_coex_dm(btcoexist);
3302}
3303
3304void ex_halbtc8192e2ant_display_coex_info(struct btc_coexist *btcoexist)
3305{
3306 struct btc_board_info *board_info = &btcoexist->board_info;
3307 struct btc_stack_info *stack_info = &btcoexist->stack_info;
3308 struct rtl_priv *rtlpriv = btcoexist->adapter;
3309 u8 u8tmp[4], i, bt_info_ext, ps_tdma_case = 0;
3310 u16 u16tmp[4];
3311 u32 u32tmp[4];
3312 bool roam = false, scan = false, link = false, wifi_under_5g = false;
3313 bool bt_hson = false, wifi_busy = false;
3314 int wifirssi = 0, bt_hs_rssi = 0;
3315 u32 wifi_bw, wifi_traffic_dir;
3316 u8 wifi_dot11_chnl, wifi_hs_chnl;
3317 u32 fw_ver = 0, bt_patch_ver = 0;
3318
3319 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
3320 "\r\n ============[BT Coexist info]============");
3321
3322 if (btcoexist->manual_control) {
3323 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
3324 "\r\n ===========[Under Manual Control]===========");
3325 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
3326 "\r\n ==========================================");
3327 }
3328
3329 if (!board_info->bt_exist) {
3330 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n BT not exists !!!");
3331 return;
3332 }
3333
3334 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
3335 "\r\n %-35s = %d/ %d ", "Ant PG number/ Ant mechanism:",
3336 board_info->pg_ant_num, board_info->btdm_ant_num);
3337
3338 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %s / %d",
3339 "BT stack/ hci ext ver",
3340 ((stack_info->profile_notified) ? "Yes" : "No"),
3341 stack_info->hci_version);
3342
3343 btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER, &bt_patch_ver);
3344 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver);
3345 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
3346 "\r\n %-35s = %d_%d/ 0x%x/ 0x%x(%d)",
3347 "CoexVer/ FwVer/ PatchVer",
3348 glcoex_ver_date_8192e_2ant, glcoex_ver_8192e_2ant,
3349 fw_ver, bt_patch_ver, bt_patch_ver);
3350
3351 btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hson);
3352 btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_DOT11_CHNL,
3353 &wifi_dot11_chnl);
3354 btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_HS_CHNL, &wifi_hs_chnl);
3355 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d / %d(%d)",
3356 "Dot11 channel / HsMode(HsChnl)",
3357 wifi_dot11_chnl, bt_hson, wifi_hs_chnl);
3358
3359 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %02x %02x %02x ",
3360 "H2C Wifi inform bt chnl Info", coex_dm->wifi_chnl_info[0],
3361 coex_dm->wifi_chnl_info[1], coex_dm->wifi_chnl_info[2]);
3362
3363 btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifirssi);
3364 btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi);
3365 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d",
3366 "Wifi rssi/ HS rssi", wifirssi, bt_hs_rssi);
3367
3368 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan);
3369 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link);
3370 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam);
3371 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d/ %d ",
3372 "Wifi link/ roam/ scan", link, roam, scan);
3373
3374 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
3375 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
3376 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
3377 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION,
3378 &wifi_traffic_dir);
3379 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %s / %s/ %s ",
3380 "Wifi status", (wifi_under_5g ? "5G" : "2.4G"),
3381 ((BTC_WIFI_BW_LEGACY == wifi_bw) ? "Legacy" :
3382 (((BTC_WIFI_BW_HT40 == wifi_bw) ? "HT40" : "HT20"))),
3383 ((!wifi_busy) ? "idle" :
3384 ((BTC_WIFI_TRAFFIC_TX == wifi_traffic_dir) ?
3385 "uplink" : "downlink")));
3386
3387 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = [%s/ %d/ %d] ",
3388 "BT [status/ rssi/ retryCnt]",
3389 ((btcoexist->bt_info.bt_disabled) ? ("disabled") :
3390 ((coex_sta->c2h_bt_inquiry_page) ?
3391 ("inquiry/page scan") :
3392 ((BT_8192E_2ANT_BT_STATUS_NON_CONNECTED_IDLE ==
3393 coex_dm->bt_status) ? "non-connected idle" :
3394 ((BT_8192E_2ANT_BT_STATUS_CONNECTED_IDLE ==
3395 coex_dm->bt_status) ? "connected-idle" : "busy")))),
3396 coex_sta->bt_rssi, coex_sta->bt_retry_cnt);
3397
3398 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d / %d / %d / %d",
3399 "SCO/HID/PAN/A2DP", stack_info->sco_exist,
3400 stack_info->hid_exist, stack_info->pan_exist,
3401 stack_info->a2dp_exist);
3402 btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_BT_LINK_INFO);
3403
3404 bt_info_ext = coex_sta->bt_info_ext;
3405 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %s",
3406 "BT Info A2DP rate",
3407 (bt_info_ext&BIT0) ? "Basic rate" : "EDR rate");
3408
3409 for (i = 0; i < BT_INFO_SRC_8192E_2ANT_MAX; i++) {
3410 if (coex_sta->bt_info_c2h_cnt[i]) {
3411 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
3412 "\r\n %-35s = %02x %02x %02x %02x ",
3413 GLBtInfoSrc8192e2Ant[i],
3414 coex_sta->bt_info_c2h[i][0],
3415 coex_sta->bt_info_c2h[i][1],
3416 coex_sta->bt_info_c2h[i][2],
3417 coex_sta->bt_info_c2h[i][3]);
3418 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
3419 "%02x %02x %02x(%d)",
3420 coex_sta->bt_info_c2h[i][4],
3421 coex_sta->bt_info_c2h[i][5],
3422 coex_sta->bt_info_c2h[i][6],
3423 coex_sta->bt_info_c2h_cnt[i]);
3424 }
3425 }
3426
3427 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %s/%s",
3428 "PS state, IPS/LPS",
3429 ((coex_sta->under_ips ? "IPS ON" : "IPS OFF")),
3430 ((coex_sta->under_lps ? "LPS ON" : "LPS OFF")));
3431 btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_FW_PWR_MODE_CMD);
3432
3433 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x ", "SS Type",
3434 coex_dm->cur_sstype);
3435
3436 /* Sw mechanism */
3437 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s",
3438 "============[Sw mechanism]============");
3439 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d/ %d ",
3440 "SM1[ShRf/ LpRA/ LimDig]", coex_dm->cur_rf_rx_lpf_shrink,
3441 coex_dm->cur_low_penalty_ra, coex_dm->limited_dig);
3442 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d/ %d(0x%x) ",
3443 "SM2[AgcT/ AdcB/ SwDacSwing(lvl)]",
3444 coex_dm->cur_agc_table_en, coex_dm->cur_adc_back_off,
3445 coex_dm->cur_dac_swing_on, coex_dm->cur_dac_swing_lvl);
3446
3447 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x ", "Rate Mask",
3448 btcoexist->bt_info.ra_mask);
3449
3450 /* Fw mechanism */
3451 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s",
3452 "============[Fw mechanism]============");
3453
3454 ps_tdma_case = coex_dm->cur_ps_tdma;
3455 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
3456 "\r\n %-35s = %02x %02x %02x %02x %02x case-%d (auto:%d)",
3457 "PS TDMA", coex_dm->ps_tdma_para[0],
3458 coex_dm->ps_tdma_para[1], coex_dm->ps_tdma_para[2],
3459 coex_dm->ps_tdma_para[3], coex_dm->ps_tdma_para[4],
3460 ps_tdma_case, coex_dm->auto_tdma_adjust);
3461
3462 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d ",
3463 "DecBtPwr/ IgnWlanAct",
3464 coex_dm->cur_dec_bt_pwr, coex_dm->cur_ignore_wlan_act);
3465
3466 /* Hw setting */
3467 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s",
3468 "============[Hw setting]============");
3469
3470 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x",
3471 "RF-A, 0x1e initVal", coex_dm->bt_rf0x1e_backup);
3472
3473 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/0x%x/0x%x/0x%x",
3474 "backup ARFR1/ARFR2/RL/AMaxTime", coex_dm->backup_arfr_cnt1,
3475 coex_dm->backup_arfr_cnt2, coex_dm->backup_retrylimit,
3476 coex_dm->backup_ampdu_maxtime);
3477
3478 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x430);
3479 u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x434);
3480 u16tmp[0] = btcoexist->btc_read_2byte(btcoexist, 0x42a);
3481 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x456);
3482 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/0x%x/0x%x/0x%x",
3483 "0x430/0x434/0x42a/0x456",
3484 u32tmp[0], u32tmp[1], u16tmp[0], u8tmp[0]);
3485
3486 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xc04);
3487 u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0xd04);
3488 u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x90c);
3489 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
3490 "0xc04/ 0xd04/ 0x90c", u32tmp[0], u32tmp[1], u32tmp[2]);
3491
3492 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x778);
3493 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x", "0x778",
3494 u8tmp[0]);
3495
3496 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x92c);
3497 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x930);
3498 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x",
3499 "0x92c/ 0x930", (u8tmp[0]), u32tmp[0]);
3500
3501 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x40);
3502 u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x4f);
3503 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x",
3504 "0x40/ 0x4f", u8tmp[0], u8tmp[1]);
3505
3506 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x550);
3507 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x522);
3508 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x",
3509 "0x550(bcn ctrl)/0x522", u32tmp[0], u8tmp[0]);
3510
3511 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xc50);
3512 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x", "0xc50(dig)",
3513 u32tmp[0]);
3514
3515 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x6c0);
3516 u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x6c4);
3517 u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x6c8);
3518 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x6cc);
3519 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
3520 "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x",
3521 "0x6c0/0x6c4/0x6c8/0x6cc(coexTable)",
3522 u32tmp[0], u32tmp[1], u32tmp[2], u8tmp[0]);
3523
3524 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d",
3525 "0x770(hp rx[31:16]/tx[15:0])",
3526 coex_sta->high_priority_rx, coex_sta->high_priority_tx);
3527 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d",
3528 "0x774(lp rx[31:16]/tx[15:0])",
3529 coex_sta->low_priority_rx, coex_sta->low_priority_tx);
3530#if (BT_AUTO_REPORT_ONLY_8192E_2ANT == 1)
3531 halbtc8192e2ant_monitor_bt_ctr(btcoexist);
3532#endif
3533 btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_COEX_STATISTICS);
3534}
3535
3536void ex_halbtc8192e2ant_ips_notify(struct btc_coexist *btcoexist, u8 type)
3537{
3538 if (BTC_IPS_ENTER == type) {
3539 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3540 "[BTCoex], IPS ENTER notify\n");
3541 coex_sta->under_ips = true;
3542 halbtc8192e2ant_coex_alloff(btcoexist);
3543 } else if (BTC_IPS_LEAVE == type) {
3544 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3545 "[BTCoex], IPS LEAVE notify\n");
3546 coex_sta->under_ips = false;
3547 }
3548}
3549
3550void ex_halbtc8192e2ant_lps_notify(struct btc_coexist *btcoexist, u8 type)
3551{
3552 if (BTC_LPS_ENABLE == type) {
3553 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3554 "[BTCoex], LPS ENABLE notify\n");
3555 coex_sta->under_lps = true;
3556 } else if (BTC_LPS_DISABLE == type) {
3557 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3558 "[BTCoex], LPS DISABLE notify\n");
3559 coex_sta->under_lps = false;
3560 }
3561}
3562
3563void ex_halbtc8192e2ant_scan_notify(struct btc_coexist *btcoexist, u8 type)
3564{
3565 if (BTC_SCAN_START == type)
3566 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3567 "[BTCoex], SCAN START notify\n");
3568 else if (BTC_SCAN_FINISH == type)
3569 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3570 "[BTCoex], SCAN FINISH notify\n");
3571}
3572
3573void ex_halbtc8192e2ant_connect_notify(struct btc_coexist *btcoexist, u8 type)
3574{
3575 if (BTC_ASSOCIATE_START == type)
3576 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3577 "[BTCoex], CONNECT START notify\n");
3578 else if (BTC_ASSOCIATE_FINISH == type)
3579 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3580 "[BTCoex], CONNECT FINISH notify\n");
3581}
3582
3583void ex_halbtc8192e2ant_media_status_notify(struct btc_coexist *btcoexist,
3584 u8 type)
3585{
3586 u8 h2c_parameter[3] = {0};
3587 u32 wifi_bw;
3588 u8 wifi_center_chnl;
3589
3590 if (btcoexist->manual_control ||
3591 btcoexist->stop_coex_dm ||
3592 btcoexist->bt_info.bt_disabled)
3593 return;
3594
3595 if (BTC_MEDIA_CONNECT == type)
3596 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3597 "[BTCoex], MEDIA connect notify\n");
3598 else
3599 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3600 "[BTCoex], MEDIA disconnect notify\n");
3601
3602 /* only 2.4G we need to inform bt the chnl mask */
3603 btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_CENTRAL_CHNL,
3604 &wifi_center_chnl);
3605 if ((BTC_MEDIA_CONNECT == type) &&
3606 (wifi_center_chnl <= 14)) {
3607 h2c_parameter[0] = 0x1;
3608 h2c_parameter[1] = wifi_center_chnl;
3609 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
3610 if (BTC_WIFI_BW_HT40 == wifi_bw)
3611 h2c_parameter[2] = 0x30;
3612 else
3613 h2c_parameter[2] = 0x20;
3614 }
3615
3616 coex_dm->wifi_chnl_info[0] = h2c_parameter[0];
3617 coex_dm->wifi_chnl_info[1] = h2c_parameter[1];
3618 coex_dm->wifi_chnl_info[2] = h2c_parameter[2];
3619
3620 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
3621 "[BTCoex], FW write 0x66 = 0x%x\n",
3622 h2c_parameter[0] << 16 | h2c_parameter[1] << 8 |
3623 h2c_parameter[2]);
3624
3625 btcoexist->btc_fill_h2c(btcoexist, 0x66, 3, h2c_parameter);
3626}
3627
3628void ex_halbtc8192e2ant_special_packet_notify(struct btc_coexist *btcoexist,
3629 u8 type)
3630{
3631 if (type == BTC_PACKET_DHCP)
3632 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3633 "[BTCoex], DHCP Packet notify\n");
3634}
3635
3636void ex_halbtc8192e2ant_bt_info_notify(struct btc_coexist *btcoexist,
3637 u8 *tmp_buf, u8 length)
3638{
3639 u8 bt_info = 0;
3640 u8 i, rsp_source = 0;
3641 bool bt_busy = false, limited_dig = false;
3642 bool wifi_connected = false;
3643
3644 coex_sta->c2h_bt_info_req_sent = false;
3645
3646 rsp_source = tmp_buf[0] & 0xf;
3647 if (rsp_source >= BT_INFO_SRC_8192E_2ANT_MAX)
3648 rsp_source = BT_INFO_SRC_8192E_2ANT_WIFI_FW;
3649 coex_sta->bt_info_c2h_cnt[rsp_source]++;
3650
3651 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3652 "[BTCoex], Bt info[%d], length=%d, hex data = [",
3653 rsp_source, length);
3654 for (i = 0; i < length; i++) {
3655 coex_sta->bt_info_c2h[rsp_source][i] = tmp_buf[i];
3656 if (i == 1)
3657 bt_info = tmp_buf[i];
3658 if (i == length-1)
3659 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3660 "0x%02x]\n", tmp_buf[i]);
3661 else
3662 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3663 "0x%02x, ", tmp_buf[i]);
3664 }
3665
3666 if (BT_INFO_SRC_8192E_2ANT_WIFI_FW != rsp_source) {
3667 coex_sta->bt_retry_cnt = /* [3:0] */
3668 coex_sta->bt_info_c2h[rsp_source][2] & 0xf;
3669
3670 coex_sta->bt_rssi =
3671 coex_sta->bt_info_c2h[rsp_source][3] * 2 + 10;
3672
3673 coex_sta->bt_info_ext =
3674 coex_sta->bt_info_c2h[rsp_source][4];
3675
3676 /* Here we need to resend some wifi info to BT
3677 * because bt is reset and loss of the info.
3678 */
3679 if ((coex_sta->bt_info_ext & BIT1)) {
3680 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3681 "bit1, send wifi BW&Chnl to BT!!\n");
3682 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
3683 &wifi_connected);
3684 if (wifi_connected)
3685 ex_halbtc8192e2ant_media_status_notify(
3686 btcoexist,
3687 BTC_MEDIA_CONNECT);
3688 else
3689 ex_halbtc8192e2ant_media_status_notify(
3690 btcoexist,
3691 BTC_MEDIA_DISCONNECT);
3692 }
3693
3694 if ((coex_sta->bt_info_ext & BIT3)) {
3695 if (!btcoexist->manual_control &&
3696 !btcoexist->stop_coex_dm) {
3697 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3698 "bit3, BT NOT ignore Wlan active!\n");
3699 halbtc8192e2ant_IgnoreWlanAct(btcoexist,
3700 FORCE_EXEC,
3701 false);
3702 }
3703 } else {
3704 /* BT already NOT ignore Wlan active,
3705 * do nothing here.
3706 */
3707 }
3708
3709#if (BT_AUTO_REPORT_ONLY_8192E_2ANT == 0)
3710 if ((coex_sta->bt_info_ext & BIT4)) {
3711 /* BT auto report already enabled, do nothing */
3712 } else {
3713 halbtc8192e2ant_bt_autoreport(btcoexist, FORCE_EXEC,
3714 true);
3715 }
3716#endif
3717 }
3718
3719 /* check BIT2 first ==> check if bt is under inquiry or page scan */
3720 if (bt_info & BT_INFO_8192E_2ANT_B_INQ_PAGE)
3721 coex_sta->c2h_bt_inquiry_page = true;
3722 else
3723 coex_sta->c2h_bt_inquiry_page = false;
3724
3725 /* set link exist status */
3726 if (!(bt_info&BT_INFO_8192E_2ANT_B_CONNECTION)) {
3727 coex_sta->bt_link_exist = false;
3728 coex_sta->pan_exist = false;
3729 coex_sta->a2dp_exist = false;
3730 coex_sta->hid_exist = false;
3731 coex_sta->sco_exist = false;
3732 } else {/* connection exists */
3733 coex_sta->bt_link_exist = true;
3734 if (bt_info & BT_INFO_8192E_2ANT_B_FTP)
3735 coex_sta->pan_exist = true;
3736 else
3737 coex_sta->pan_exist = false;
3738 if (bt_info & BT_INFO_8192E_2ANT_B_A2DP)
3739 coex_sta->a2dp_exist = true;
3740 else
3741 coex_sta->a2dp_exist = false;
3742 if (bt_info & BT_INFO_8192E_2ANT_B_HID)
3743 coex_sta->hid_exist = true;
3744 else
3745 coex_sta->hid_exist = false;
3746 if (bt_info & BT_INFO_8192E_2ANT_B_SCO_ESCO)
3747 coex_sta->sco_exist = true;
3748 else
3749 coex_sta->sco_exist = false;
3750 }
3751
3752 halbtc8192e2ant_update_btlink_info(btcoexist);
3753
3754 if (!(bt_info&BT_INFO_8192E_2ANT_B_CONNECTION)) {
3755 coex_dm->bt_status = BT_8192E_2ANT_BT_STATUS_NON_CONNECTED_IDLE;
3756 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3757 "[BTCoex], BT Non-Connected idle!!!\n");
3758 } else if (bt_info == BT_INFO_8192E_2ANT_B_CONNECTION) {
3759 coex_dm->bt_status = BT_8192E_2ANT_BT_STATUS_CONNECTED_IDLE;
3760 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3761 "[BTCoex], bt_infoNotify(), BT Connected-idle!!!\n");
3762 } else if ((bt_info&BT_INFO_8192E_2ANT_B_SCO_ESCO) ||
3763 (bt_info&BT_INFO_8192E_2ANT_B_SCO_BUSY)) {
3764 coex_dm->bt_status = BT_8192E_2ANT_BT_STATUS_SCO_BUSY;
3765 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3766 "[BTCoex], bt_infoNotify(), BT SCO busy!!!\n");
3767 } else if (bt_info&BT_INFO_8192E_2ANT_B_ACL_BUSY) {
3768 coex_dm->bt_status = BT_8192E_2ANT_BT_STATUS_ACL_BUSY;
3769 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3770 "[BTCoex], bt_infoNotify(), BT ACL busy!!!\n");
3771 } else {
3772 coex_dm->bt_status = BT_8192E_2ANT_BT_STATUS_MAX;
3773 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3774 "[BTCoex]bt_infoNotify(), BT Non-Defined state!!!\n");
3775 }
3776
3777 if ((BT_8192E_2ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) ||
3778 (BT_8192E_2ANT_BT_STATUS_SCO_BUSY == coex_dm->bt_status) ||
3779 (BT_8192E_2ANT_BT_STATUS_ACL_SCO_BUSY == coex_dm->bt_status)) {
3780 bt_busy = true;
3781 limited_dig = true;
3782 } else {
3783 bt_busy = false;
3784 limited_dig = false;
3785 }
3786
3787 btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bt_busy);
3788
3789 coex_dm->limited_dig = limited_dig;
3790 btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_LIMITED_DIG, &limited_dig);
3791
3792 halbtc8192e2ant_run_coexist_mechanism(btcoexist);
3793}
3794
3795void ex_halbtc8192e2ant_stack_operation_notify(struct btc_coexist *btcoexist,
3796 u8 type)
3797{
3798}
3799
3800void ex_halbtc8192e2ant_halt_notify(struct btc_coexist *btcoexist)
3801{
3802 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, "[BTCoex], Halt notify\n");
3803
3804 halbtc8192e2ant_IgnoreWlanAct(btcoexist, FORCE_EXEC, true);
3805 ex_halbtc8192e2ant_media_status_notify(btcoexist, BTC_MEDIA_DISCONNECT);
3806}
3807
3808void ex_halbtc8192e2ant_periodical(struct btc_coexist *btcoexist)
3809{
3810 static u8 dis_ver_info_cnt;
3811 u32 fw_ver = 0, bt_patch_ver = 0;
3812 struct btc_board_info *board_info = &btcoexist->board_info;
3813 struct btc_stack_info *stack_info = &btcoexist->stack_info;
3814
3815 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3816 "=======================Periodical=======================\n");
3817 if (dis_ver_info_cnt <= 5) {
3818 dis_ver_info_cnt += 1;
3819 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
3820 "************************************************\n");
3821 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
3822 "Ant PG Num/ Ant Mech/ Ant Pos = %d/ %d/ %d\n",
3823 board_info->pg_ant_num, board_info->btdm_ant_num,
3824 board_info->btdm_ant_pos);
3825 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
3826 "BT stack/ hci ext ver = %s / %d\n",
3827 ((stack_info->profile_notified) ? "Yes" : "No"),
3828 stack_info->hci_version);
3829 btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER,
3830 &bt_patch_ver);
3831 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver);
3832 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
3833 "CoexVer/ FwVer/ PatchVer = %d_%x/ 0x%x/ 0x%x(%d)\n",
3834 glcoex_ver_date_8192e_2ant, glcoex_ver_8192e_2ant,
3835 fw_ver, bt_patch_ver, bt_patch_ver);
3836 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
3837 "************************************************\n");
3838 }
3839
3840#if (BT_AUTO_REPORT_ONLY_8192E_2ANT == 0)
3841 halbtc8192e2ant_querybt_info(btcoexist);
3842 halbtc8192e2ant_monitor_bt_ctr(btcoexist);
3843 btc8192e2ant_monitor_bt_enable_dis(btcoexist);
3844#else
3845 if (halbtc8192e2ant_iswifi_status_changed(btcoexist) ||
3846 coex_dm->auto_tdma_adjust)
3847 halbtc8192e2ant_run_coexist_mechanism(btcoexist);
3848#endif
3849}
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8192e2ant.h b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8192e2ant.h
new file mode 100644
index 000000000000..75e1f7d0db06
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8192e2ant.h
@@ -0,0 +1,185 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2012 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25/*****************************************************************
26 * The following is for 8192E 2Ant BT Co-exist definition
27 *****************************************************************/
28#define BT_AUTO_REPORT_ONLY_8192E_2ANT 0
29
30#define BT_INFO_8192E_2ANT_B_FTP BIT7
31#define BT_INFO_8192E_2ANT_B_A2DP BIT6
32#define BT_INFO_8192E_2ANT_B_HID BIT5
33#define BT_INFO_8192E_2ANT_B_SCO_BUSY BIT4
34#define BT_INFO_8192E_2ANT_B_ACL_BUSY BIT3
35#define BT_INFO_8192E_2ANT_B_INQ_PAGE BIT2
36#define BT_INFO_8192E_2ANT_B_SCO_ESCO BIT1
37#define BT_INFO_8192E_2ANT_B_CONNECTION BIT0
38
39#define BTC_RSSI_COEX_THRESH_TOL_8192E_2ANT 2
40
41enum bt_info_src_8192e_2ant {
42 BT_INFO_SRC_8192E_2ANT_WIFI_FW = 0x0,
43 BT_INFO_SRC_8192E_2ANT_BT_RSP = 0x1,
44 BT_INFO_SRC_8192E_2ANT_BT_ACTIVE_SEND = 0x2,
45 BT_INFO_SRC_8192E_2ANT_MAX
46};
47
48enum bt_8192e_2ant_bt_status {
49 BT_8192E_2ANT_BT_STATUS_NON_CONNECTED_IDLE = 0x0,
50 BT_8192E_2ANT_BT_STATUS_CONNECTED_IDLE = 0x1,
51 BT_8192E_2ANT_BT_STATUS_INQ_PAGE = 0x2,
52 BT_8192E_2ANT_BT_STATUS_ACL_BUSY = 0x3,
53 BT_8192E_2ANT_BT_STATUS_SCO_BUSY = 0x4,
54 BT_8192E_2ANT_BT_STATUS_ACL_SCO_BUSY = 0x5,
55 BT_8192E_2ANT_BT_STATUS_MAX
56};
57
58enum bt_8192e_2ant_coex_algo {
59 BT_8192E_2ANT_COEX_ALGO_UNDEFINED = 0x0,
60 BT_8192E_2ANT_COEX_ALGO_SCO = 0x1,
61 BT_8192E_2ANT_COEX_ALGO_SCO_PAN = 0x2,
62 BT_8192E_2ANT_COEX_ALGO_HID = 0x3,
63 BT_8192E_2ANT_COEX_ALGO_A2DP = 0x4,
64 BT_8192E_2ANT_COEX_ALGO_A2DP_PANHS = 0x5,
65 BT_8192E_2ANT_COEX_ALGO_PANEDR = 0x6,
66 BT_8192E_2ANT_COEX_ALGO_PANHS = 0x7,
67 BT_8192E_2ANT_COEX_ALGO_PANEDR_A2DP = 0x8,
68 BT_8192E_2ANT_COEX_ALGO_PANEDR_HID = 0x9,
69 BT_8192E_2ANT_COEX_ALGO_HID_A2DP_PANEDR = 0xa,
70 BT_8192E_2ANT_COEX_ALGO_HID_A2DP = 0xb,
71 BT_8192E_2ANT_COEX_ALGO_MAX = 0xc
72};
73
74struct coex_dm_8192e_2ant {
75 /* fw mechanism */
76 u8 pre_dec_bt_pwr;
77 u8 cur_dec_bt_pwr;
78 u8 pre_fw_dac_swing_lvl;
79 u8 cur_fw_dac_swing_lvl;
80 bool cur_ignore_wlan_act;
81 bool pre_ignore_wlan_act;
82 u8 pre_ps_tdma;
83 u8 cur_ps_tdma;
84 u8 ps_tdma_para[5];
85 u8 tdma_adj_type;
86 bool reset_tdma_adjust;
87 bool auto_tdma_adjust;
88 bool pre_ps_tdma_on;
89 bool cur_ps_tdma_on;
90 bool pre_bt_auto_report;
91 bool cur_bt_auto_report;
92
93 /* sw mechanism */
94 bool pre_rf_rx_lpf_shrink;
95 bool cur_rf_rx_lpf_shrink;
96 u32 bt_rf0x1e_backup;
97 bool pre_low_penalty_ra;
98 bool cur_low_penalty_ra;
99 bool pre_dac_swing_on;
100 u32 pre_dac_swing_lvl;
101 bool cur_dac_swing_on;
102 u32 cur_dac_swing_lvl;
103 bool pre_adc_back_off;
104 bool cur_adc_back_off;
105 bool pre_agc_table_en;
106 bool cur_agc_table_en;
107 u32 pre_val0x6c0;
108 u32 cur_val0x6c0;
109 u32 pre_val0x6c4;
110 u32 cur_val0x6c4;
111 u32 pre_val0x6c8;
112 u32 cur_val0x6c8;
113 u8 pre_val0x6cc;
114 u8 cur_val0x6cc;
115 bool limited_dig;
116
117 u32 backup_arfr_cnt1; /* Auto Rate Fallback Retry cnt */
118 u32 backup_arfr_cnt2; /* Auto Rate Fallback Retry cnt */
119 u16 backup_retrylimit;
120 u8 backup_ampdu_maxtime;
121
122 /* algorithm related */
123 u8 pre_algorithm;
124 u8 cur_algorithm;
125 u8 bt_status;
126 u8 wifi_chnl_info[3];
127
128 u8 pre_sstype;
129 u8 cur_sstype;
130
131 u32 prera_mask;
132 u32 curra_mask;
133 u8 curra_masktype;
134 u8 pre_arfrtype;
135 u8 cur_arfrtype;
136 u8 pre_retrylimit_type;
137 u8 cur_retrylimit_type;
138 u8 pre_ampdutime_type;
139 u8 cur_ampdutime_type;
140};
141
142struct coex_sta_8192e_2ant {
143 bool bt_link_exist;
144 bool sco_exist;
145 bool a2dp_exist;
146 bool hid_exist;
147 bool pan_exist;
148
149 bool under_lps;
150 bool under_ips;
151 u32 high_priority_tx;
152 u32 high_priority_rx;
153 u32 low_priority_tx;
154 u32 low_priority_rx;
155 u8 bt_rssi;
156 u8 pre_bt_rssi_state;
157 u8 pre_wifi_rssi_state[4];
158 bool c2h_bt_info_req_sent;
159 u8 bt_info_c2h[BT_INFO_SRC_8192E_2ANT_MAX][10];
160 u32 bt_info_c2h_cnt[BT_INFO_SRC_8192E_2ANT_MAX];
161 bool c2h_bt_inquiry_page;
162 u8 bt_retry_cnt;
163 u8 bt_info_ext;
164};
165
166/****************************************************************
167 * The following is interface which will notify coex module.
168 ****************************************************************/
169void ex_halbtc8192e2ant_init_hwconfig(struct btc_coexist *btcoexist);
170void ex_halbtc8192e2ant_init_coex_dm(struct btc_coexist *btcoexist);
171void ex_halbtc8192e2ant_ips_notify(struct btc_coexist *btcoexist, u8 type);
172void ex_halbtc8192e2ant_lps_notify(struct btc_coexist *btcoexist, u8 type);
173void ex_halbtc8192e2ant_scan_notify(struct btc_coexist *btcoexist, u8 type);
174void ex_halbtc8192e2ant_connect_notify(struct btc_coexist *btcoexist, u8 type);
175void ex_halbtc8192e2ant_media_status_notify(struct btc_coexist *btcoexist,
176 u8 type);
177void ex_halbtc8192e2ant_special_packet_notify(struct btc_coexist *btcoexist,
178 u8 type);
179void ex_halbtc8192e2ant_bt_info_notify(struct btc_coexist *btcoexist,
180 u8 *tmpbuf, u8 length);
181void ex_halbtc8192e2ant_stack_operation_notify(struct btc_coexist *btcoexist,
182 u8 type);
183void ex_halbtc8192e2ant_halt_notify(struct btc_coexist *btcoexist);
184void ex_halbtc8192e2ant_periodical(struct btc_coexist *btcoexist);
185void ex_halbtc8192e2ant_display_coex_info(struct btc_coexist *btcoexist);
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b1ant.c b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b1ant.c
new file mode 100644
index 000000000000..c4acd403e5f6
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b1ant.c
@@ -0,0 +1,3170 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2012 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26/***************************************************************
27 * Description:
28 *
29 * This file is for RTL8723B Co-exist mechanism
30 *
31 * History
32 * 2012/11/15 Cosa first check in.
33 *
34 ***************************************************************/
35
36/***************************************************************
37 * include files
38 ***************************************************************/
39#include "halbt_precomp.h"
40/***************************************************************
41 * Global variables, these are static variables
42 ***************************************************************/
43static struct coex_dm_8723b_1ant glcoex_dm_8723b_1ant;
44static struct coex_dm_8723b_1ant *coex_dm = &glcoex_dm_8723b_1ant;
45static struct coex_sta_8723b_1ant glcoex_sta_8723b_1ant;
46static struct coex_sta_8723b_1ant *coex_sta = &glcoex_sta_8723b_1ant;
47
48static const char *const GLBtInfoSrc8723b1Ant[] = {
49 "BT Info[wifi fw]",
50 "BT Info[bt rsp]",
51 "BT Info[bt auto report]",
52};
53
54static u32 glcoex_ver_date_8723b_1ant = 20130918;
55static u32 glcoex_ver_8723b_1ant = 0x47;
56
57/***************************************************************
58 * local function proto type if needed
59 ***************************************************************/
60/***************************************************************
61 * local function start with halbtc8723b1ant_
62 ***************************************************************/
63static u8 halbtc8723b1ant_bt_rssi_state(u8 level_num, u8 rssi_thresh,
64 u8 rssi_thresh1)
65{
66 s32 bt_rssi = 0;
67 u8 bt_rssi_state = coex_sta->pre_bt_rssi_state;
68
69 bt_rssi = coex_sta->bt_rssi;
70
71 if (level_num == 2) {
72 if ((coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_LOW) ||
73 (coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) {
74 if (bt_rssi >= rssi_thresh +
75 BTC_RSSI_COEX_THRESH_TOL_8723B_1ANT) {
76 bt_rssi_state = BTC_RSSI_STATE_HIGH;
77 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
78 "[BTCoex], BT Rssi state switch to High\n");
79 } else {
80 bt_rssi_state = BTC_RSSI_STATE_STAY_LOW;
81 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
82 "[BTCoex], BT Rssi state stay at Low\n");
83 }
84 } else {
85 if (bt_rssi < rssi_thresh) {
86 bt_rssi_state = BTC_RSSI_STATE_LOW;
87 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
88 "[BTCoex], BT Rssi state switch to Low\n");
89 } else {
90 bt_rssi_state = BTC_RSSI_STATE_STAY_HIGH;
91 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
92 "[BTCoex], BT Rssi state stay at High\n");
93 }
94 }
95 } else if (level_num == 3) {
96 if (rssi_thresh > rssi_thresh1) {
97 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
98 "[BTCoex], BT Rssi thresh error!!\n");
99 return coex_sta->pre_bt_rssi_state;
100 }
101
102 if ((coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_LOW) ||
103 (coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) {
104 if (bt_rssi >= rssi_thresh +
105 BTC_RSSI_COEX_THRESH_TOL_8723B_1ANT) {
106 bt_rssi_state = BTC_RSSI_STATE_MEDIUM;
107 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
108 "[BTCoex], BT Rssi state switch to Medium\n");
109 } else {
110 bt_rssi_state = BTC_RSSI_STATE_STAY_LOW;
111 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
112 "[BTCoex], BT Rssi state stay at Low\n");
113 }
114 } else if ((coex_sta->pre_bt_rssi_state ==
115 BTC_RSSI_STATE_MEDIUM) ||
116 (coex_sta->pre_bt_rssi_state ==
117 BTC_RSSI_STATE_STAY_MEDIUM)) {
118 if (bt_rssi >= rssi_thresh1 +
119 BTC_RSSI_COEX_THRESH_TOL_8723B_1ANT) {
120 bt_rssi_state = BTC_RSSI_STATE_HIGH;
121 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
122 "[BTCoex], BT Rssi state switch to High\n");
123 } else if (bt_rssi < rssi_thresh) {
124 bt_rssi_state = BTC_RSSI_STATE_LOW;
125 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
126 "[BTCoex], BT Rssi state switch to Low\n");
127 } else {
128 bt_rssi_state = BTC_RSSI_STATE_STAY_MEDIUM;
129 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
130 "[BTCoex], BT Rssi state stay at Medium\n");
131 }
132 } else {
133 if (bt_rssi < rssi_thresh1) {
134 bt_rssi_state = BTC_RSSI_STATE_MEDIUM;
135 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
136 "[BTCoex], BT Rssi state switch to Medium\n");
137 } else {
138 bt_rssi_state = BTC_RSSI_STATE_STAY_HIGH;
139 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
140 "[BTCoex], BT Rssi state stay at High\n");
141 }
142 }
143 }
144
145 coex_sta->pre_bt_rssi_state = bt_rssi_state;
146
147 return bt_rssi_state;
148}
149
150static u8 halbtc8723b1ant_wifi_rssi_state(struct btc_coexist *btcoexist,
151 u8 index, u8 level_num,
152 u8 rssi_thresh, u8 rssi_thresh1)
153{
154 s32 wifi_rssi = 0;
155 u8 wifi_rssi_state = coex_sta->pre_wifi_rssi_state[index];
156
157 btcoexist->btc_get(btcoexist,
158 BTC_GET_S4_WIFI_RSSI, &wifi_rssi);
159
160 if (level_num == 2) {
161 if ((coex_sta->pre_wifi_rssi_state[index] ==
162 BTC_RSSI_STATE_LOW) ||
163 (coex_sta->pre_wifi_rssi_state[index] ==
164 BTC_RSSI_STATE_STAY_LOW)) {
165 if (wifi_rssi >= rssi_thresh +
166 BTC_RSSI_COEX_THRESH_TOL_8723B_1ANT) {
167 wifi_rssi_state = BTC_RSSI_STATE_HIGH;
168 BTC_PRINT(BTC_MSG_ALGORITHM,
169 ALGO_WIFI_RSSI_STATE,
170 "[BTCoex], wifi RSSI state switch to High\n");
171 } else {
172 wifi_rssi_state = BTC_RSSI_STATE_STAY_LOW;
173 BTC_PRINT(BTC_MSG_ALGORITHM,
174 ALGO_WIFI_RSSI_STATE,
175 "[BTCoex], wifi RSSI state stay at Low\n");
176 }
177 } else {
178 if (wifi_rssi < rssi_thresh) {
179 wifi_rssi_state = BTC_RSSI_STATE_LOW;
180 BTC_PRINT(BTC_MSG_ALGORITHM,
181 ALGO_WIFI_RSSI_STATE,
182 "[BTCoex], wifi RSSI state switch to Low\n");
183 } else {
184 wifi_rssi_state = BTC_RSSI_STATE_STAY_HIGH;
185 BTC_PRINT(BTC_MSG_ALGORITHM,
186 ALGO_WIFI_RSSI_STATE,
187 "[BTCoex], wifi RSSI state stay at High\n");
188 }
189 }
190 } else if (level_num == 3) {
191 if (rssi_thresh > rssi_thresh1) {
192 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE,
193 "[BTCoex], wifi RSSI thresh error!!\n");
194 return coex_sta->pre_wifi_rssi_state[index];
195 }
196
197 if ((coex_sta->pre_wifi_rssi_state[index] ==
198 BTC_RSSI_STATE_LOW) ||
199 (coex_sta->pre_wifi_rssi_state[index] ==
200 BTC_RSSI_STATE_STAY_LOW)) {
201 if (wifi_rssi >= rssi_thresh +
202 BTC_RSSI_COEX_THRESH_TOL_8723B_1ANT) {
203 wifi_rssi_state = BTC_RSSI_STATE_MEDIUM;
204 BTC_PRINT(BTC_MSG_ALGORITHM,
205 ALGO_WIFI_RSSI_STATE,
206 "[BTCoex], wifi RSSI state switch to Medium\n");
207 } else {
208 wifi_rssi_state = BTC_RSSI_STATE_STAY_LOW;
209 BTC_PRINT(BTC_MSG_ALGORITHM,
210 ALGO_WIFI_RSSI_STATE,
211 "[BTCoex], wifi RSSI state stay at Low\n");
212 }
213 } else if ((coex_sta->pre_wifi_rssi_state[index] ==
214 BTC_RSSI_STATE_MEDIUM) ||
215 (coex_sta->pre_wifi_rssi_state[index] ==
216 BTC_RSSI_STATE_STAY_MEDIUM)) {
217 if (wifi_rssi >= rssi_thresh1 +
218 BTC_RSSI_COEX_THRESH_TOL_8723B_1ANT) {
219 wifi_rssi_state = BTC_RSSI_STATE_HIGH;
220 BTC_PRINT(BTC_MSG_ALGORITHM,
221 ALGO_WIFI_RSSI_STATE,
222 "[BTCoex], wifi RSSI state switch to High\n");
223 } else if (wifi_rssi < rssi_thresh) {
224 wifi_rssi_state = BTC_RSSI_STATE_LOW;
225 BTC_PRINT(BTC_MSG_ALGORITHM,
226 ALGO_WIFI_RSSI_STATE,
227 "[BTCoex], wifi RSSI state switch to Low\n");
228 } else {
229 wifi_rssi_state = BTC_RSSI_STATE_STAY_MEDIUM;
230 BTC_PRINT(BTC_MSG_ALGORITHM,
231 ALGO_WIFI_RSSI_STATE,
232 "[BTCoex], wifi RSSI state stay at Medium\n");
233 }
234 } else {
235 if (wifi_rssi < rssi_thresh1) {
236 wifi_rssi_state = BTC_RSSI_STATE_MEDIUM;
237 BTC_PRINT(BTC_MSG_ALGORITHM,
238 ALGO_WIFI_RSSI_STATE,
239 "[BTCoex], wifi RSSI state switch to Medium\n");
240 } else {
241 wifi_rssi_state = BTC_RSSI_STATE_STAY_HIGH;
242 BTC_PRINT(BTC_MSG_ALGORITHM,
243 ALGO_WIFI_RSSI_STATE,
244 "[BTCoex], wifi RSSI state stay at High\n");
245 }
246 }
247 }
248
249 coex_sta->pre_wifi_rssi_state[index] = wifi_rssi_state;
250
251 return wifi_rssi_state;
252}
253
254static void halbtc8723b1ant_updatera_mask(struct btc_coexist *btcoexist,
255 bool force_exec, u32 dis_rate_mask)
256{
257 coex_dm->curra_mask = dis_rate_mask;
258
259 if (force_exec || (coex_dm->prera_mask != coex_dm->curra_mask))
260 btcoexist->btc_set(btcoexist, BTC_SET_ACT_UPDATE_ra_mask,
261 &coex_dm->curra_mask);
262
263 coex_dm->prera_mask = coex_dm->curra_mask;
264}
265
266static void btc8723b1ant_auto_rate_fb_retry(struct btc_coexist *btcoexist,
267 bool force_exec, u8 type)
268{
269 bool wifi_under_bmode = false;
270
271 coex_dm->cur_arfr_type = type;
272
273 if (force_exec || (coex_dm->pre_arfr_type != coex_dm->cur_arfr_type)) {
274 switch (coex_dm->cur_arfr_type) {
275 case 0: /* normal mode */
276 btcoexist->btc_write_4byte(btcoexist, 0x430,
277 coex_dm->backup_arfr_cnt1);
278 btcoexist->btc_write_4byte(btcoexist, 0x434,
279 coex_dm->backup_arfr_cnt2);
280 break;
281 case 1:
282 btcoexist->btc_get(btcoexist,
283 BTC_GET_BL_WIFI_UNDER_B_MODE,
284 &wifi_under_bmode);
285 if (wifi_under_bmode) {
286 btcoexist->btc_write_4byte(btcoexist,
287 0x430, 0x0);
288 btcoexist->btc_write_4byte(btcoexist,
289 0x434, 0x01010101);
290 } else {
291 btcoexist->btc_write_4byte(btcoexist,
292 0x430, 0x0);
293 btcoexist->btc_write_4byte(btcoexist,
294 0x434, 0x04030201);
295 }
296 break;
297 default:
298 break;
299 }
300 }
301
302 coex_dm->pre_arfr_type = coex_dm->cur_arfr_type;
303}
304
305static void halbtc8723b1ant_retry_limit(struct btc_coexist *btcoexist,
306 bool force_exec, u8 type)
307{
308 coex_dm->cur_retry_limit_type = type;
309
310 if (force_exec || (coex_dm->pre_retry_limit_type !=
311 coex_dm->cur_retry_limit_type)) {
312 switch (coex_dm->cur_retry_limit_type) {
313 case 0: /* normal mode */
314 btcoexist->btc_write_2byte(btcoexist, 0x42a,
315 coex_dm->backup_retry_limit);
316 break;
317 case 1: /* retry limit = 8 */
318 btcoexist->btc_write_2byte(btcoexist, 0x42a, 0x0808);
319 break;
320 default:
321 break;
322 }
323 }
324
325 coex_dm->pre_retry_limit_type = coex_dm->cur_retry_limit_type;
326}
327
328static void halbtc8723b1ant_ampdu_maxtime(struct btc_coexist *btcoexist,
329 bool force_exec, u8 type)
330{
331 coex_dm->cur_ampdu_time_type = type;
332
333 if (force_exec || (coex_dm->pre_ampdu_time_type !=
334 coex_dm->cur_ampdu_time_type)) {
335 switch (coex_dm->cur_ampdu_time_type) {
336 case 0: /* normal mode */
337 btcoexist->btc_write_1byte(btcoexist, 0x456,
338 coex_dm->backup_ampdu_max_time);
339 break;
340 case 1: /* AMPDU timw = 0x38 * 32us */
341 btcoexist->btc_write_1byte(btcoexist,
342 0x456, 0x38);
343 break;
344 default:
345 break;
346 }
347 }
348
349 coex_dm->pre_ampdu_time_type = coex_dm->cur_ampdu_time_type;
350}
351
352static void halbtc8723b1ant_limited_tx(struct btc_coexist *btcoexist,
353 bool force_exec, u8 ra_masktype,
354 u8 arfr_type, u8 retry_limit_type,
355 u8 ampdu_time_type)
356{
357 switch (ra_masktype) {
358 case 0: /* normal mode */
359 halbtc8723b1ant_updatera_mask(btcoexist, force_exec, 0x0);
360 break;
361 case 1: /* disable cck 1/2 */
362 halbtc8723b1ant_updatera_mask(btcoexist, force_exec,
363 0x00000003);
364 break;
365 /* disable cck 1/2/5.5, ofdm 6/9/12/18/24, mcs 0/1/2/3/4*/
366 case 2:
367 halbtc8723b1ant_updatera_mask(btcoexist, force_exec,
368 0x0001f1f7);
369 break;
370 default:
371 break;
372 }
373
374 btc8723b1ant_auto_rate_fb_retry(btcoexist, force_exec, arfr_type);
375 halbtc8723b1ant_retry_limit(btcoexist, force_exec, retry_limit_type);
376 halbtc8723b1ant_ampdu_maxtime(btcoexist, force_exec, ampdu_time_type);
377}
378
379static void halbtc8723b1ant_limited_rx(struct btc_coexist *btcoexist,
380 bool force_exec, bool rej_ap_agg_pkt,
381 bool bt_ctrl_agg_buf_size,
382 u8 agg_buf_size)
383{
384 bool reject_rx_agg = rej_ap_agg_pkt;
385 bool bt_ctrl_rx_agg_size = bt_ctrl_agg_buf_size;
386 u8 rxaggsize = agg_buf_size;
387
388 /**********************************************
389 * Rx Aggregation related setting
390 **********************************************/
391 btcoexist->btc_set(btcoexist, BTC_SET_BL_TO_REJ_AP_AGG_PKT,
392 &reject_rx_agg);
393 /* decide BT control aggregation buf size or not */
394 btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_CTRL_AGG_SIZE,
395 &bt_ctrl_rx_agg_size);
396 /* aggregation buf size, only work
397 * when BT control Rx aggregation size.
398 */
399 btcoexist->btc_set(btcoexist, BTC_SET_U1_AGG_BUF_SIZE, &rxaggsize);
400 /* real update aggregation setting */
401 btcoexist->btc_set(btcoexist, BTC_SET_ACT_AGGREGATE_CTRL, NULL);
402}
403
404static void halbtc8723b1ant_monitor_bt_ctr(struct btc_coexist *btcoexist)
405{
406 u32 reg_hp_txrx, reg_lp_txrx, u32tmp;
407 u32 reg_hp_tx = 0, reg_hp_rx = 0;
408 u32 reg_lp_tx = 0, reg_lp_rx = 0;
409
410 reg_hp_txrx = 0x770;
411 reg_lp_txrx = 0x774;
412
413 u32tmp = btcoexist->btc_read_4byte(btcoexist, reg_hp_txrx);
414 reg_hp_tx = u32tmp & MASKLWORD;
415 reg_hp_rx = (u32tmp & MASKHWORD) >> 16;
416
417 u32tmp = btcoexist->btc_read_4byte(btcoexist, reg_lp_txrx);
418 reg_lp_tx = u32tmp & MASKLWORD;
419 reg_lp_rx = (u32tmp & MASKHWORD) >> 16;
420
421 coex_sta->high_priority_tx = reg_hp_tx;
422 coex_sta->high_priority_rx = reg_hp_rx;
423 coex_sta->low_priority_tx = reg_lp_tx;
424 coex_sta->low_priority_rx = reg_lp_rx;
425
426 /* reset counter */
427 btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc);
428}
429
430static void halbtc8723b1ant_query_bt_info(struct btc_coexist *btcoexist)
431{
432 u8 h2c_parameter[1] = {0};
433
434 coex_sta->c2h_bt_info_req_sent = true;
435
436 h2c_parameter[0] |= BIT0; /* trigger*/
437
438 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
439 "[BTCoex], Query Bt Info, FW write 0x61 = 0x%x\n",
440 h2c_parameter[0]);
441
442 btcoexist->btc_fill_h2c(btcoexist, 0x61, 1, h2c_parameter);
443}
444
445static bool btc8723b1ant_is_wifi_status_changed(struct btc_coexist *btcoexist)
446{
447 static bool pre_wifi_busy;
448 static bool pre_under_4way, pre_bt_hs_on;
449 bool wifi_busy = false, under_4way = false, bt_hs_on = false;
450 bool wifi_connected = false;
451
452 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
453 &wifi_connected);
454 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
455 btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
456 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS,
457 &under_4way);
458
459 if (wifi_connected) {
460 if (wifi_busy != pre_wifi_busy) {
461 pre_wifi_busy = wifi_busy;
462 return true;
463 }
464 if (under_4way != pre_under_4way) {
465 pre_under_4way = under_4way;
466 return true;
467 }
468 if (bt_hs_on != pre_bt_hs_on) {
469 pre_bt_hs_on = bt_hs_on;
470 return true;
471 }
472 }
473
474 return false;
475}
476
477static void halbtc8723b1ant_update_bt_link_info(struct btc_coexist *btcoexist)
478{
479 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
480 bool bt_hs_on = false;
481
482 btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
483
484 bt_link_info->bt_link_exist = coex_sta->bt_link_exist;
485 bt_link_info->sco_exist = coex_sta->sco_exist;
486 bt_link_info->a2dp_exist = coex_sta->a2dp_exist;
487 bt_link_info->pan_exist = coex_sta->pan_exist;
488 bt_link_info->hid_exist = coex_sta->hid_exist;
489
490 /* work around for HS mode. */
491 if (bt_hs_on) {
492 bt_link_info->pan_exist = true;
493 bt_link_info->bt_link_exist = true;
494 }
495
496 /* check if Sco only */
497 if (bt_link_info->sco_exist && !bt_link_info->a2dp_exist &&
498 !bt_link_info->pan_exist && !bt_link_info->hid_exist)
499 bt_link_info->sco_only = true;
500 else
501 bt_link_info->sco_only = false;
502
503 /* check if A2dp only */
504 if (!bt_link_info->sco_exist && bt_link_info->a2dp_exist &&
505 !bt_link_info->pan_exist && !bt_link_info->hid_exist)
506 bt_link_info->a2dp_only = true;
507 else
508 bt_link_info->a2dp_only = false;
509
510 /* check if Pan only */
511 if (!bt_link_info->sco_exist && !bt_link_info->a2dp_exist &&
512 bt_link_info->pan_exist && !bt_link_info->hid_exist)
513 bt_link_info->pan_only = true;
514 else
515 bt_link_info->pan_only = false;
516
517 /* check if Hid only */
518 if (!bt_link_info->sco_exist && !bt_link_info->a2dp_exist &&
519 !bt_link_info->pan_exist && bt_link_info->hid_exist)
520 bt_link_info->hid_only = true;
521 else
522 bt_link_info->hid_only = false;
523}
524
525static u8 halbtc8723b1ant_action_algorithm(struct btc_coexist *btcoexist)
526{
527 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
528 bool bt_hs_on = false;
529 u8 algorithm = BT_8723B_1ANT_COEX_ALGO_UNDEFINED;
530 u8 numdiffprofile = 0;
531
532 btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
533
534 if (!bt_link_info->bt_link_exist) {
535 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
536 "[BTCoex], No BT link exists!!!\n");
537 return algorithm;
538 }
539
540 if (bt_link_info->sco_exist)
541 numdiffprofile++;
542 if (bt_link_info->hid_exist)
543 numdiffprofile++;
544 if (bt_link_info->pan_exist)
545 numdiffprofile++;
546 if (bt_link_info->a2dp_exist)
547 numdiffprofile++;
548
549 if (numdiffprofile == 1) {
550 if (bt_link_info->sco_exist) {
551 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
552 "[BTCoex], BT Profile = SCO only\n");
553 algorithm = BT_8723B_1ANT_COEX_ALGO_SCO;
554 } else {
555 if (bt_link_info->hid_exist) {
556 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
557 "[BTCoex], BT Profile = HID only\n");
558 algorithm = BT_8723B_1ANT_COEX_ALGO_HID;
559 } else if (bt_link_info->a2dp_exist) {
560 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
561 "[BTCoex], BT Profile = A2DP only\n");
562 algorithm = BT_8723B_1ANT_COEX_ALGO_A2DP;
563 } else if (bt_link_info->pan_exist) {
564 if (bt_hs_on) {
565 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
566 "[BTCoex], BT Profile = PAN(HS) only\n");
567 algorithm =
568 BT_8723B_1ANT_COEX_ALGO_PANHS;
569 } else {
570 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
571 "[BTCoex], BT Profile = PAN(EDR) only\n");
572 algorithm =
573 BT_8723B_1ANT_COEX_ALGO_PANEDR;
574 }
575 }
576 }
577 } else if (numdiffprofile == 2) {
578 if (bt_link_info->sco_exist) {
579 if (bt_link_info->hid_exist) {
580 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
581 "[BTCoex], BT Profile = SCO + HID\n");
582 algorithm = BT_8723B_1ANT_COEX_ALGO_HID;
583 } else if (bt_link_info->a2dp_exist) {
584 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
585 "[BTCoex], BT Profile = SCO + A2DP ==> SCO\n");
586 algorithm = BT_8723B_1ANT_COEX_ALGO_SCO;
587 } else if (bt_link_info->pan_exist) {
588 if (bt_hs_on) {
589 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
590 "[BTCoex], BT Profile = SCO + PAN(HS)\n");
591 algorithm = BT_8723B_1ANT_COEX_ALGO_SCO;
592 } else {
593 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
594 "[BTCoex], BT Profile = SCO + PAN(EDR)\n");
595 algorithm =
596 BT_8723B_1ANT_COEX_ALGO_PANEDR_HID;
597 }
598 }
599 } else {
600 if (bt_link_info->hid_exist &&
601 bt_link_info->a2dp_exist) {
602 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
603 "[BTCoex], BT Profile = HID + A2DP\n");
604 algorithm = BT_8723B_1ANT_COEX_ALGO_HID_A2DP;
605 } else if (bt_link_info->hid_exist &&
606 bt_link_info->pan_exist) {
607 if (bt_hs_on) {
608 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
609 "[BTCoex], BT Profile = HID + PAN(HS)\n");
610 algorithm =
611 BT_8723B_1ANT_COEX_ALGO_HID_A2DP;
612 } else {
613 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
614 "[BTCoex], BT Profile = HID + PAN(EDR)\n");
615 algorithm =
616 BT_8723B_1ANT_COEX_ALGO_PANEDR_HID;
617 }
618 } else if (bt_link_info->pan_exist &&
619 bt_link_info->a2dp_exist) {
620 if (bt_hs_on) {
621 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
622 "[BTCoex], BT Profile = A2DP + PAN(HS)\n");
623 algorithm =
624 BT_8723B_1ANT_COEX_ALGO_A2DP_PANHS;
625 } else {
626 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
627 "[BTCoex], BT Profile = A2DP + PAN(EDR)\n");
628 algorithm =
629 BT_8723B_1ANT_COEX_ALGO_PANEDR_A2DP;
630 }
631 }
632 }
633 } else if (numdiffprofile == 3) {
634 if (bt_link_info->sco_exist) {
635 if (bt_link_info->hid_exist &&
636 bt_link_info->a2dp_exist) {
637 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
638 "[BTCoex], BT Profile = SCO + HID + A2DP ==> HID\n");
639 algorithm = BT_8723B_1ANT_COEX_ALGO_HID;
640 } else if (bt_link_info->hid_exist &&
641 bt_link_info->pan_exist) {
642 if (bt_hs_on) {
643 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
644 "[BTCoex], BT Profile = SCO + HID + PAN(HS)\n");
645 algorithm =
646 BT_8723B_1ANT_COEX_ALGO_HID_A2DP;
647 } else {
648 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
649 "[BTCoex], BT Profile = SCO + HID + PAN(EDR)\n");
650 algorithm =
651 BT_8723B_1ANT_COEX_ALGO_PANEDR_HID;
652 }
653 } else if (bt_link_info->pan_exist &&
654 bt_link_info->a2dp_exist) {
655 if (bt_hs_on) {
656 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
657 "[BTCoex], BT Profile = SCO + A2DP + PAN(HS)\n");
658 algorithm = BT_8723B_1ANT_COEX_ALGO_SCO;
659 } else {
660 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
661 "[BTCoex], BT Profile = SCO + A2DP + PAN(EDR) ==> HID\n");
662 algorithm =
663 BT_8723B_1ANT_COEX_ALGO_PANEDR_HID;
664 }
665 }
666 } else {
667 if (bt_link_info->hid_exist &&
668 bt_link_info->pan_exist &&
669 bt_link_info->a2dp_exist) {
670 if (bt_hs_on) {
671 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
672 "[BTCoex], BT Profile = HID + A2DP + PAN(HS)\n");
673 algorithm =
674 BT_8723B_1ANT_COEX_ALGO_HID_A2DP;
675 } else {
676 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
677 "[BTCoex], BT Profile = HID + A2DP + PAN(EDR)\n");
678 algorithm =
679 BT_8723B_1ANT_COEX_ALGO_HID_A2DP_PANEDR;
680 }
681 }
682 }
683 } else if (numdiffprofile >= 3) {
684 if (bt_link_info->sco_exist) {
685 if (bt_link_info->hid_exist &&
686 bt_link_info->pan_exist &&
687 bt_link_info->a2dp_exist) {
688 if (bt_hs_on) {
689 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
690 "[BTCoex], Error!!! BT Profile = SCO + HID + A2DP + PAN(HS)\n");
691 } else {
692 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
693 "[BTCoex], BT Profile = SCO + HID + A2DP + PAN(EDR)==>PAN(EDR)+HID\n");
694 algorithm =
695 BT_8723B_1ANT_COEX_ALGO_PANEDR_HID;
696 }
697 }
698 }
699 }
700
701 return algorithm;
702}
703
704static void btc8723b1ant_set_sw_pen_tx_rate_adapt(struct btc_coexist *btcoexist,
705 bool low_penalty_ra)
706{
707 u8 h2c_parameter[6] = {0};
708
709 h2c_parameter[0] = 0x6; /* opCode, 0x6= Retry_Penalty */
710
711 if (low_penalty_ra) {
712 h2c_parameter[1] |= BIT0;
713 /*normal rate except MCS7/6/5, OFDM54/48/36 */
714 h2c_parameter[2] = 0x00;
715 h2c_parameter[3] = 0xf7; /*MCS7 or OFDM54 */
716 h2c_parameter[4] = 0xf8; /*MCS6 or OFDM48 */
717 h2c_parameter[5] = 0xf9; /*MCS5 or OFDM36 */
718 }
719
720 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
721 "[BTCoex], set WiFi Low-Penalty Retry: %s",
722 (low_penalty_ra ? "ON!!" : "OFF!!"));
723
724 btcoexist->btc_fill_h2c(btcoexist, 0x69, 6, h2c_parameter);
725}
726
727static void halbtc8723b1ant_low_penalty_ra(struct btc_coexist *btcoexist,
728 bool force_exec, bool low_penalty_ra)
729{
730 coex_dm->cur_low_penalty_ra = low_penalty_ra;
731
732 if (!force_exec) {
733 if (coex_dm->pre_low_penalty_ra == coex_dm->cur_low_penalty_ra)
734 return;
735 }
736 btc8723b1ant_set_sw_pen_tx_rate_adapt(btcoexist,
737 coex_dm->cur_low_penalty_ra);
738
739 coex_dm->pre_low_penalty_ra = coex_dm->cur_low_penalty_ra;
740}
741
742static void halbtc8723b1ant_set_coex_table(struct btc_coexist *btcoexist,
743 u32 val0x6c0, u32 val0x6c4,
744 u32 val0x6c8, u8 val0x6cc)
745{
746 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
747 "[BTCoex], set coex table, set 0x6c0 = 0x%x\n", val0x6c0);
748 btcoexist->btc_write_4byte(btcoexist, 0x6c0, val0x6c0);
749
750 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
751 "[BTCoex], set coex table, set 0x6c4 = 0x%x\n", val0x6c4);
752 btcoexist->btc_write_4byte(btcoexist, 0x6c4, val0x6c4);
753
754 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
755 "[BTCoex], set coex table, set 0x6c8 = 0x%x\n", val0x6c8);
756 btcoexist->btc_write_4byte(btcoexist, 0x6c8, val0x6c8);
757
758 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
759 "[BTCoex], set coex table, set 0x6cc = 0x%x\n", val0x6cc);
760 btcoexist->btc_write_1byte(btcoexist, 0x6cc, val0x6cc);
761}
762
763static void halbtc8723b1ant_coex_table(struct btc_coexist *btcoexist,
764 bool force_exec, u32 val0x6c0,
765 u32 val0x6c4, u32 val0x6c8,
766 u8 val0x6cc)
767{
768 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW,
769 "[BTCoex], %s write Coex Table 0x6c0 = 0x%x, 0x6c4 = 0x%x, 0x6cc = 0x%x\n",
770 (force_exec ? "force to" : ""),
771 val0x6c0, val0x6c4, val0x6cc);
772 coex_dm->cur_val0x6c0 = val0x6c0;
773 coex_dm->cur_val0x6c4 = val0x6c4;
774 coex_dm->cur_val0x6c8 = val0x6c8;
775 coex_dm->cur_val0x6cc = val0x6cc;
776
777 if (!force_exec) {
778 if ((coex_dm->pre_val0x6c0 == coex_dm->cur_val0x6c0) &&
779 (coex_dm->pre_val0x6c4 == coex_dm->cur_val0x6c4) &&
780 (coex_dm->pre_val0x6c8 == coex_dm->cur_val0x6c8) &&
781 (coex_dm->pre_val0x6cc == coex_dm->cur_val0x6cc))
782 return;
783 }
784 halbtc8723b1ant_set_coex_table(btcoexist, val0x6c0, val0x6c4,
785 val0x6c8, val0x6cc);
786
787 coex_dm->pre_val0x6c0 = coex_dm->cur_val0x6c0;
788 coex_dm->pre_val0x6c4 = coex_dm->cur_val0x6c4;
789 coex_dm->pre_val0x6c8 = coex_dm->cur_val0x6c8;
790 coex_dm->pre_val0x6cc = coex_dm->cur_val0x6cc;
791}
792
793static void halbtc8723b1ant_coex_table_with_type(struct btc_coexist *btcoexist,
794 bool force_exec, u8 type)
795{
796 switch (type) {
797 case 0:
798 halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55555555,
799 0x55555555, 0xffffff, 0x3);
800 break;
801 case 1:
802 halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55555555,
803 0x5a5a5a5a, 0xffffff, 0x3);
804 break;
805 case 2:
806 halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x5a5a5a5a,
807 0x5a5a5a5a, 0xffffff, 0x3);
808 break;
809 case 3:
810 halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55555555,
811 0xaaaaaaaa, 0xffffff, 0x3);
812 break;
813 case 4:
814 halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55555555,
815 0x5aaa5aaa, 0xffffff, 0x3);
816 break;
817 case 5:
818 halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x5a5a5a5a,
819 0xaaaa5a5a, 0xffffff, 0x3);
820 break;
821 case 6:
822 halbtc8723b1ant_coex_table(btcoexist, force_exec, 0x55555555,
823 0xaaaa5a5a, 0xffffff, 0x3);
824 break;
825 case 7:
826 halbtc8723b1ant_coex_table(btcoexist, force_exec, 0xaaaaaaaa,
827 0xaaaaaaaa, 0xffffff, 0x3);
828 break;
829 default:
830 break;
831 }
832}
833
834static void halbtc8723b1ant_SetFwIgnoreWlanAct(struct btc_coexist *btcoexist,
835 bool enable)
836{
837 u8 h2c_parameter[1] = {0};
838
839 if (enable)
840 h2c_parameter[0] |= BIT0; /* function enable */
841
842 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
843 "[BTCoex], set FW for BT Ignore Wlan_Act, FW write 0x63 = 0x%x\n",
844 h2c_parameter[0]);
845
846 btcoexist->btc_fill_h2c(btcoexist, 0x63, 1, h2c_parameter);
847}
848
849static void halbtc8723b1ant_ignore_wlan_act(struct btc_coexist *btcoexist,
850 bool force_exec, bool enable)
851{
852 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW,
853 "[BTCoex], %s turn Ignore WlanAct %s\n",
854 (force_exec ? "force to" : ""), (enable ? "ON" : "OFF"));
855 coex_dm->cur_ignore_wlan_act = enable;
856
857 if (!force_exec) {
858 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
859 "[BTCoex], bPreIgnoreWlanAct = %d, bCurIgnoreWlanAct = %d!!\n",
860 coex_dm->pre_ignore_wlan_act,
861 coex_dm->cur_ignore_wlan_act);
862
863 if (coex_dm->pre_ignore_wlan_act ==
864 coex_dm->cur_ignore_wlan_act)
865 return;
866 }
867 halbtc8723b1ant_SetFwIgnoreWlanAct(btcoexist, enable);
868
869 coex_dm->pre_ignore_wlan_act = coex_dm->cur_ignore_wlan_act;
870}
871
872static void halbtc8723b1ant_set_fw_ps_tdma(struct btc_coexist *btcoexist,
873 u8 byte1, u8 byte2, u8 byte3,
874 u8 byte4, u8 byte5)
875{
876 u8 h2c_parameter[5] = {0};
877 u8 real_byte1 = byte1, real_byte5 = byte5;
878 bool ap_enable = false;
879
880 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE,
881 &ap_enable);
882
883 if (ap_enable) {
884 if ((byte1 & BIT4) && !(byte1 & BIT5)) {
885 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
886 "[BTCoex], FW for 1Ant AP mode\n");
887 real_byte1 &= ~BIT4;
888 real_byte1 |= BIT5;
889
890 real_byte5 |= BIT5;
891 real_byte5 &= ~BIT6;
892 }
893 }
894
895 h2c_parameter[0] = real_byte1;
896 h2c_parameter[1] = byte2;
897 h2c_parameter[2] = byte3;
898 h2c_parameter[3] = byte4;
899 h2c_parameter[4] = real_byte5;
900
901 coex_dm->ps_tdma_para[0] = real_byte1;
902 coex_dm->ps_tdma_para[1] = byte2;
903 coex_dm->ps_tdma_para[2] = byte3;
904 coex_dm->ps_tdma_para[3] = byte4;
905 coex_dm->ps_tdma_para[4] = real_byte5;
906
907 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
908 "[BTCoex], PS-TDMA H2C cmd =0x%x%08x\n",
909 h2c_parameter[0],
910 h2c_parameter[1] << 24 |
911 h2c_parameter[2] << 16 |
912 h2c_parameter[3] << 8 |
913 h2c_parameter[4]);
914
915 btcoexist->btc_fill_h2c(btcoexist, 0x60, 5, h2c_parameter);
916}
917
918static void halbtc8723b1ant_set_lps_rpwm(struct btc_coexist *btcoexist,
919 u8 lps_val, u8 rpwm_val)
920{
921 u8 lps = lps_val;
922 u8 rpwm = rpwm_val;
923
924 btcoexist->btc_set(btcoexist, BTC_SET_U1_LPS_VAL, &lps);
925 btcoexist->btc_set(btcoexist, BTC_SET_U1_RPWM_VAL, &rpwm);
926}
927
928static void halbtc8723b1ant_LpsRpwm(struct btc_coexist *btcoexist,
929 bool force_exec,
930 u8 lps_val, u8 rpwm_val)
931{
932 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW,
933 "[BTCoex], %s set lps/rpwm = 0x%x/0x%x\n",
934 (force_exec ? "force to" : ""), lps_val, rpwm_val);
935 coex_dm->cur_lps = lps_val;
936 coex_dm->cur_rpwm = rpwm_val;
937
938 if (!force_exec) {
939 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
940 "[BTCoex], LPS-RxBeaconMode = 0x%x , LPS-RPWM = 0x%x!!\n",
941 coex_dm->cur_lps, coex_dm->cur_rpwm);
942
943 if ((coex_dm->pre_lps == coex_dm->cur_lps) &&
944 (coex_dm->pre_rpwm == coex_dm->cur_rpwm)) {
945 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
946 "[BTCoex], LPS-RPWM_Last = 0x%x , LPS-RPWM_Now = 0x%x!!\n",
947 coex_dm->pre_rpwm, coex_dm->cur_rpwm);
948
949 return;
950 }
951 }
952 halbtc8723b1ant_set_lps_rpwm(btcoexist, lps_val, rpwm_val);
953
954 coex_dm->pre_lps = coex_dm->cur_lps;
955 coex_dm->pre_rpwm = coex_dm->cur_rpwm;
956}
957
958static void halbtc8723b1ant_sw_mechanism(struct btc_coexist *btcoexist,
959 bool low_penalty_ra)
960{
961 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR,
962 "[BTCoex], SM[LpRA] = %d\n", low_penalty_ra);
963
964 halbtc8723b1ant_low_penalty_ra(btcoexist, NORMAL_EXEC, low_penalty_ra);
965}
966
967static void halbtc8723b1ant_SetAntPath(struct btc_coexist *btcoexist,
968 u8 ant_pos_type, bool init_hw_cfg,
969 bool wifi_off)
970{
971 struct btc_board_info *board_info = &btcoexist->board_info;
972 u32 fw_ver = 0, u32tmp = 0;
973 bool pg_ext_switch = false;
974 bool use_ext_switch = false;
975 u8 h2c_parameter[2] = {0};
976
977 btcoexist->btc_get(btcoexist, BTC_GET_BL_EXT_SWITCH, &pg_ext_switch);
978 /* [31:16] = fw ver, [15:0] = fw sub ver */
979 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver);
980
981 if ((fw_ver < 0xc0000) || pg_ext_switch)
982 use_ext_switch = true;
983
984 if (init_hw_cfg) {
985 /*BT select s0/s1 is controlled by WiFi */
986 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x67, 0x20, 0x1);
987
988 /*Force GNT_BT to Normal */
989 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x765, 0x18, 0x0);
990 } else if (wifi_off) {
991 /*Force GNT_BT to High */
992 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x765, 0x18, 0x3);
993 /*BT select s0/s1 is controlled by BT */
994 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x67, 0x20, 0x0);
995
996 /* 0x4c[24:23] = 00, Set Antenna control by BT_RFE_CTRL
997 * BT Vendor 0xac = 0xf002
998 */
999 u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x4c);
1000 u32tmp &= ~BIT23;
1001 u32tmp &= ~BIT24;
1002 btcoexist->btc_write_4byte(btcoexist, 0x4c, u32tmp);
1003 }
1004
1005 if (use_ext_switch) {
1006 if (init_hw_cfg) {
1007 /* 0x4c[23] = 0, 0x4c[24] = 1
1008 * Antenna control by WL/BT
1009 */
1010 u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x4c);
1011 u32tmp &= ~BIT23;
1012 u32tmp |= BIT24;
1013 btcoexist->btc_write_4byte(btcoexist, 0x4c, u32tmp);
1014
1015 if (board_info->btdm_ant_pos ==
1016 BTC_ANTENNA_AT_MAIN_PORT) {
1017 /* Main Ant to BT for IPS case 0x4c[23] = 1 */
1018 btcoexist->btc_write_1byte_bitmask(btcoexist,
1019 0x64, 0x1,
1020 0x1);
1021
1022 /*tell firmware "no antenna inverse"*/
1023 h2c_parameter[0] = 0;
1024 h2c_parameter[1] = 1; /*ext switch type*/
1025 btcoexist->btc_fill_h2c(btcoexist, 0x65, 2,
1026 h2c_parameter);
1027 } else {
1028 /*Aux Ant to BT for IPS case 0x4c[23] = 1 */
1029 btcoexist->btc_write_1byte_bitmask(btcoexist,
1030 0x64, 0x1,
1031 0x0);
1032
1033 /*tell firmware "antenna inverse"*/
1034 h2c_parameter[0] = 1;
1035 h2c_parameter[1] = 1; /*ext switch type*/
1036 btcoexist->btc_fill_h2c(btcoexist, 0x65, 2,
1037 h2c_parameter);
1038 }
1039 }
1040
1041 /* fixed internal switch first*/
1042 /* fixed internal switch S1->WiFi, S0->BT*/
1043 if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT)
1044 btcoexist->btc_write_2byte(btcoexist, 0x948, 0x0);
1045 else/* fixed internal switch S0->WiFi, S1->BT*/
1046 btcoexist->btc_write_2byte(btcoexist, 0x948, 0x280);
1047
1048 /* ext switch setting */
1049 switch (ant_pos_type) {
1050 case BTC_ANT_PATH_WIFI:
1051 if (board_info->btdm_ant_pos ==
1052 BTC_ANTENNA_AT_MAIN_PORT)
1053 btcoexist->btc_write_1byte_bitmask(btcoexist,
1054 0x92c, 0x3,
1055 0x1);
1056 else
1057 btcoexist->btc_write_1byte_bitmask(btcoexist,
1058 0x92c, 0x3,
1059 0x2);
1060 break;
1061 case BTC_ANT_PATH_BT:
1062 if (board_info->btdm_ant_pos ==
1063 BTC_ANTENNA_AT_MAIN_PORT)
1064 btcoexist->btc_write_1byte_bitmask(btcoexist,
1065 0x92c, 0x3,
1066 0x2);
1067 else
1068 btcoexist->btc_write_1byte_bitmask(btcoexist,
1069 0x92c, 0x3,
1070 0x1);
1071 break;
1072 default:
1073 case BTC_ANT_PATH_PTA:
1074 if (board_info->btdm_ant_pos ==
1075 BTC_ANTENNA_AT_MAIN_PORT)
1076 btcoexist->btc_write_1byte_bitmask(btcoexist,
1077 0x92c, 0x3,
1078 0x1);
1079 else
1080 btcoexist->btc_write_1byte_bitmask(btcoexist,
1081 0x92c, 0x3,
1082 0x2);
1083 break;
1084 }
1085
1086 } else {
1087 if (init_hw_cfg) {
1088 /* 0x4c[23] = 1, 0x4c[24] = 0 Antenna control by 0x64*/
1089 u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x4c);
1090 u32tmp |= BIT23;
1091 u32tmp &= ~BIT24;
1092 btcoexist->btc_write_4byte(btcoexist, 0x4c, u32tmp);
1093
1094 if (board_info->btdm_ant_pos ==
1095 BTC_ANTENNA_AT_MAIN_PORT) {
1096 /*Main Ant to WiFi for IPS case 0x4c[23] = 1*/
1097 btcoexist->btc_write_1byte_bitmask(btcoexist,
1098 0x64, 0x1,
1099 0x0);
1100
1101 /*tell firmware "no antenna inverse"*/
1102 h2c_parameter[0] = 0;
1103 h2c_parameter[1] = 0; /*internal switch type*/
1104 btcoexist->btc_fill_h2c(btcoexist, 0x65, 2,
1105 h2c_parameter);
1106 } else {
1107 /*Aux Ant to BT for IPS case 0x4c[23] = 1*/
1108 btcoexist->btc_write_1byte_bitmask(btcoexist,
1109 0x64, 0x1,
1110 0x1);
1111
1112 /*tell firmware "antenna inverse"*/
1113 h2c_parameter[0] = 1;
1114 h2c_parameter[1] = 0; /*internal switch type*/
1115 btcoexist->btc_fill_h2c(btcoexist, 0x65, 2,
1116 h2c_parameter);
1117 }
1118 }
1119
1120 /* fixed external switch first*/
1121 /*Main->WiFi, Aux->BT*/
1122 if (board_info->btdm_ant_pos ==
1123 BTC_ANTENNA_AT_MAIN_PORT)
1124 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x92c,
1125 0x3, 0x1);
1126 else/*Main->BT, Aux->WiFi */
1127 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x92c,
1128 0x3, 0x2);
1129
1130 /* internal switch setting*/
1131 switch (ant_pos_type) {
1132 case BTC_ANT_PATH_WIFI:
1133 if (board_info->btdm_ant_pos ==
1134 BTC_ANTENNA_AT_MAIN_PORT)
1135 btcoexist->btc_write_2byte(btcoexist, 0x948,
1136 0x0);
1137 else
1138 btcoexist->btc_write_2byte(btcoexist, 0x948,
1139 0x280);
1140 break;
1141 case BTC_ANT_PATH_BT:
1142 if (board_info->btdm_ant_pos ==
1143 BTC_ANTENNA_AT_MAIN_PORT)
1144 btcoexist->btc_write_2byte(btcoexist, 0x948,
1145 0x280);
1146 else
1147 btcoexist->btc_write_2byte(btcoexist, 0x948,
1148 0x0);
1149 break;
1150 default:
1151 case BTC_ANT_PATH_PTA:
1152 if (board_info->btdm_ant_pos ==
1153 BTC_ANTENNA_AT_MAIN_PORT)
1154 btcoexist->btc_write_2byte(btcoexist, 0x948,
1155 0x200);
1156 else
1157 btcoexist->btc_write_2byte(btcoexist, 0x948,
1158 0x80);
1159 break;
1160 }
1161 }
1162}
1163
1164static void halbtc8723b1ant_ps_tdma(struct btc_coexist *btcoexist,
1165 bool force_exec, bool turn_on, u8 type)
1166{
1167 bool wifi_busy = false;
1168 u8 rssi_adjust_val = 0;
1169
1170 coex_dm->cur_ps_tdma_on = turn_on;
1171 coex_dm->cur_ps_tdma = type;
1172
1173 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
1174
1175 if (!force_exec) {
1176 if (coex_dm->cur_ps_tdma_on)
1177 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
1178 "[BTCoex], ******** TDMA(on, %d) *********\n",
1179 coex_dm->cur_ps_tdma);
1180 else
1181 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
1182 "[BTCoex], ******** TDMA(off, %d) ********\n",
1183 coex_dm->cur_ps_tdma);
1184
1185 if ((coex_dm->pre_ps_tdma_on == coex_dm->cur_ps_tdma_on) &&
1186 (coex_dm->pre_ps_tdma == coex_dm->cur_ps_tdma))
1187 return;
1188 }
1189 if (turn_on) {
1190 switch (type) {
1191 default:
1192 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x1a,
1193 0x1a, 0x0, 0x50);
1194 break;
1195 case 1:
1196 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x3a,
1197 0x03, 0x10, 0x50);
1198
1199 rssi_adjust_val = 11;
1200 break;
1201 case 2:
1202 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x2b,
1203 0x03, 0x10, 0x50);
1204 rssi_adjust_val = 14;
1205 break;
1206 case 3:
1207 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x1d,
1208 0x1d, 0x0, 0x52);
1209 break;
1210 case 4:
1211 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x93, 0x15,
1212 0x3, 0x14, 0x0);
1213 rssi_adjust_val = 17;
1214 break;
1215 case 5:
1216 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x61, 0x15,
1217 0x3, 0x11, 0x10);
1218 break;
1219 case 6:
1220 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x61, 0x20,
1221 0x3, 0x11, 0x13);
1222 break;
1223 case 7:
1224 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x13, 0xc,
1225 0x5, 0x0, 0x0);
1226 break;
1227 case 8:
1228 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x93, 0x25,
1229 0x3, 0x10, 0x0);
1230 break;
1231 case 9:
1232 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x21,
1233 0x3, 0x10, 0x50);
1234 rssi_adjust_val = 18;
1235 break;
1236 case 10:
1237 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x13, 0xa,
1238 0xa, 0x0, 0x40);
1239 break;
1240 case 11:
1241 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x15,
1242 0x03, 0x10, 0x50);
1243 rssi_adjust_val = 20;
1244 break;
1245 case 12:
1246 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x0a,
1247 0x0a, 0x0, 0x50);
1248 break;
1249 case 13:
1250 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x15,
1251 0x15, 0x0, 0x50);
1252 break;
1253 case 14:
1254 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x21,
1255 0x3, 0x10, 0x52);
1256 break;
1257 case 15:
1258 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x13, 0xa,
1259 0x3, 0x8, 0x0);
1260 break;
1261 case 16:
1262 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x93, 0x15,
1263 0x3, 0x10, 0x0);
1264 rssi_adjust_val = 18;
1265 break;
1266 case 18:
1267 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x93, 0x25,
1268 0x3, 0x10, 0x0);
1269 rssi_adjust_val = 14;
1270 break;
1271 case 20:
1272 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x61, 0x35,
1273 0x03, 0x11, 0x10);
1274 break;
1275 case 21:
1276 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x61, 0x25,
1277 0x03, 0x11, 0x11);
1278 break;
1279 case 22:
1280 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x61, 0x25,
1281 0x03, 0x11, 0x10);
1282 break;
1283 case 23:
1284 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x25,
1285 0x3, 0x31, 0x18);
1286 rssi_adjust_val = 22;
1287 break;
1288 case 24:
1289 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x15,
1290 0x3, 0x31, 0x18);
1291 rssi_adjust_val = 22;
1292 break;
1293 case 25:
1294 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0xa,
1295 0x3, 0x31, 0x18);
1296 rssi_adjust_val = 22;
1297 break;
1298 case 26:
1299 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0xa,
1300 0x3, 0x31, 0x18);
1301 rssi_adjust_val = 22;
1302 break;
1303 case 27:
1304 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x25,
1305 0x3, 0x31, 0x98);
1306 rssi_adjust_val = 22;
1307 break;
1308 case 28:
1309 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x69, 0x25,
1310 0x3, 0x31, 0x0);
1311 break;
1312 case 29:
1313 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xab, 0x1a,
1314 0x1a, 0x1, 0x10);
1315 break;
1316 case 30:
1317 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x14,
1318 0x3, 0x10, 0x50);
1319 break;
1320 case 31:
1321 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xd3, 0x1a,
1322 0x1a, 0, 0x58);
1323 break;
1324 case 32:
1325 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x61, 0xa,
1326 0x3, 0x10, 0x0);
1327 break;
1328 case 33:
1329 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xa3, 0x25,
1330 0x3, 0x30, 0x90);
1331 break;
1332 case 34:
1333 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x53, 0x1a,
1334 0x1a, 0x0, 0x10);
1335 break;
1336 case 35:
1337 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x63, 0x1a,
1338 0x1a, 0x0, 0x10);
1339 break;
1340 case 36:
1341 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0xd3, 0x12,
1342 0x3, 0x14, 0x50);
1343 break;
1344 /* SoftAP only with no sta associated,BT disable ,
1345 * TDMA mode for power saving
1346 * here softap mode screen off will cost 70-80mA for phone
1347 */
1348 case 40:
1349 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x23, 0x18,
1350 0x00, 0x10, 0x24);
1351 break;
1352 }
1353 } else {
1354 switch (type) {
1355 case 8: /*PTA Control */
1356 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x8, 0x0,
1357 0x0, 0x0, 0x0);
1358 halbtc8723b1ant_SetAntPath(btcoexist, BTC_ANT_PATH_PTA,
1359 false, false);
1360 break;
1361 case 0:
1362 default: /*Software control, Antenna at BT side */
1363 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x0, 0x0,
1364 0x0, 0x0, 0x0);
1365 halbtc8723b1ant_SetAntPath(btcoexist, BTC_ANT_PATH_BT,
1366 false, false);
1367 break;
1368 case 9: /*Software control, Antenna at WiFi side */
1369 halbtc8723b1ant_set_fw_ps_tdma(btcoexist, 0x0, 0x0,
1370 0x0, 0x0, 0x0);
1371 halbtc8723b1ant_SetAntPath(btcoexist, BTC_ANT_PATH_WIFI,
1372 false, false);
1373 break;
1374 }
1375 }
1376 rssi_adjust_val = 0;
1377 btcoexist->btc_set(btcoexist,
1378 BTC_SET_U1_RSSI_ADJ_VAL_FOR_1ANT_COEX_TYPE,
1379 &rssi_adjust_val);
1380
1381 /* update pre state */
1382 coex_dm->pre_ps_tdma_on = coex_dm->cur_ps_tdma_on;
1383 coex_dm->pre_ps_tdma = coex_dm->cur_ps_tdma;
1384}
1385
1386static bool halbtc8723b1ant_is_common_action(struct btc_coexist *btcoexist)
1387{
1388 bool commom = false, wifi_connected = false;
1389 bool wifi_busy = false;
1390
1391 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
1392 &wifi_connected);
1393 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
1394
1395 if (!wifi_connected &&
1396 BT_8723B_1ANT_BT_STATUS_NON_CONNECTED_IDLE == coex_dm->bt_status) {
1397 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
1398 "[BTCoex], Wifi non connected-idle + BT non connected-idle!!\n");
1399 halbtc8723b1ant_sw_mechanism(btcoexist, false);
1400 commom = true;
1401 } else if (wifi_connected &&
1402 (BT_8723B_1ANT_BT_STATUS_NON_CONNECTED_IDLE ==
1403 coex_dm->bt_status)) {
1404 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
1405 "[BTCoex], Wifi connected + BT non connected-idle!!\n");
1406 halbtc8723b1ant_sw_mechanism(btcoexist, false);
1407 commom = true;
1408 } else if (!wifi_connected &&
1409 (BT_8723B_1ANT_BT_STATUS_CONNECTED_IDLE ==
1410 coex_dm->bt_status)) {
1411 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
1412 "[BTCoex], Wifi non connected-idle + BT connected-idle!!\n");
1413 halbtc8723b1ant_sw_mechanism(btcoexist, false);
1414 commom = true;
1415 } else if (wifi_connected &&
1416 (BT_8723B_1ANT_BT_STATUS_CONNECTED_IDLE ==
1417 coex_dm->bt_status)) {
1418 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
1419 "[BTCoex], Wifi connected + BT connected-idle!!\n");
1420 halbtc8723b1ant_sw_mechanism(btcoexist, false);
1421 commom = true;
1422 } else if (!wifi_connected &&
1423 (BT_8723B_1ANT_BT_STATUS_CONNECTED_IDLE !=
1424 coex_dm->bt_status)) {
1425 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
1426 ("[BTCoex], Wifi non connected-idle + BT Busy!!\n"));
1427 halbtc8723b1ant_sw_mechanism(btcoexist, false);
1428 commom = true;
1429 } else {
1430 if (wifi_busy)
1431 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
1432 "[BTCoex], Wifi Connected-Busy + BT Busy!!\n");
1433 else
1434 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
1435 "[BTCoex], Wifi Connected-Idle + BT Busy!!\n");
1436
1437 commom = false;
1438 }
1439
1440 return commom;
1441}
1442
1443static void btc8723b1ant_tdma_dur_adj_for_acl(struct btc_coexist *btcoexist,
1444 u8 wifi_status)
1445{
1446 static s32 up, dn, m, n, wait_count;
1447 /* 0: no change, +1: increase WiFi duration,
1448 * -1: decrease WiFi duration
1449 */
1450 s32 result;
1451 u8 retry_count = 0, bt_info_ext;
1452 bool wifi_busy = false;
1453
1454 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW,
1455 "[BTCoex], TdmaDurationAdjustForAcl()\n");
1456
1457 if (BT_8723B_1ANT_WIFI_STATUS_CONNECTED_BUSY == wifi_status)
1458 wifi_busy = true;
1459 else
1460 wifi_busy = false;
1461
1462 if ((BT_8723B_1ANT_WIFI_STATUS_NON_CONNECTED_ASSO_AUTH_SCAN ==
1463 wifi_status) ||
1464 (BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SCAN == wifi_status) ||
1465 (BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SPECIAL_PKT == wifi_status)) {
1466 if (coex_dm->cur_ps_tdma != 1 && coex_dm->cur_ps_tdma != 2 &&
1467 coex_dm->cur_ps_tdma != 3 && coex_dm->cur_ps_tdma != 9) {
1468 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
1469 true, 9);
1470 coex_dm->tdma_adj_type = 9;
1471
1472 up = 0;
1473 dn = 0;
1474 m = 1;
1475 n = 3;
1476 result = 0;
1477 wait_count = 0;
1478 }
1479 return;
1480 }
1481
1482 if (!coex_dm->auto_tdma_adjust) {
1483 coex_dm->auto_tdma_adjust = true;
1484 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
1485 "[BTCoex], first run TdmaDurationAdjust()!!\n");
1486
1487 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 2);
1488 coex_dm->tdma_adj_type = 2;
1489
1490 up = 0;
1491 dn = 0;
1492 m = 1;
1493 n = 3;
1494 result = 0;
1495 wait_count = 0;
1496 } else {
1497 /*accquire the BT TRx retry count from BT_Info byte2 */
1498 retry_count = coex_sta->bt_retry_cnt;
1499 bt_info_ext = coex_sta->bt_info_ext;
1500 result = 0;
1501 wait_count++;
1502 /* no retry in the last 2-second duration */
1503 if (retry_count == 0) {
1504 up++;
1505 dn--;
1506
1507 if (dn <= 0)
1508 dn = 0;
1509
1510 if (up >= n) {
1511 wait_count = 0;
1512 n = 3;
1513 up = 0;
1514 dn = 0;
1515 result = 1;
1516 BTC_PRINT(BTC_MSG_ALGORITHM,
1517 ALGO_TRACE_FW_DETAIL,
1518 "[BTCoex], Increase wifi duration!!\n");
1519 }
1520 } else if (retry_count <= 3) {
1521 up--;
1522 dn++;
1523
1524 if (up <= 0)
1525 up = 0;
1526
1527 if (dn == 2) {
1528 if (wait_count <= 2)
1529 m++;
1530 else
1531 m = 1;
1532
1533 if (m >= 20)
1534 m = 20;
1535
1536 n = 3 * m;
1537 up = 0;
1538 dn = 0;
1539 wait_count = 0;
1540 result = -1;
1541 BTC_PRINT(BTC_MSG_ALGORITHM,
1542 ALGO_TRACE_FW_DETAIL,
1543 "[BTCoex], Decrease wifi duration for retryCounter<3!!\n");
1544 }
1545 } else {
1546 if (wait_count == 1)
1547 m++;
1548 else
1549 m = 1;
1550
1551 if (m >= 20)
1552 m = 20;
1553
1554 n = 3 * m;
1555 up = 0;
1556 dn = 0;
1557 wait_count = 0;
1558 result = -1;
1559 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
1560 "[BTCoex], Decrease wifi duration for retryCounter>3!!\n");
1561 }
1562
1563 if (result == -1) {
1564 if ((BT_INFO_8723B_1ANT_A2DP_BASIC_RATE(bt_info_ext)) &&
1565 ((coex_dm->cur_ps_tdma == 1) ||
1566 (coex_dm->cur_ps_tdma == 2))) {
1567 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
1568 true, 9);
1569 coex_dm->tdma_adj_type = 9;
1570 } else if (coex_dm->cur_ps_tdma == 1) {
1571 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
1572 true, 2);
1573 coex_dm->tdma_adj_type = 2;
1574 } else if (coex_dm->cur_ps_tdma == 2) {
1575 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
1576 true, 9);
1577 coex_dm->tdma_adj_type = 9;
1578 } else if (coex_dm->cur_ps_tdma == 9) {
1579 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
1580 true, 11);
1581 coex_dm->tdma_adj_type = 11;
1582 }
1583 } else if (result == 1) {
1584 if ((BT_INFO_8723B_1ANT_A2DP_BASIC_RATE(bt_info_ext)) &&
1585 ((coex_dm->cur_ps_tdma == 1) ||
1586 (coex_dm->cur_ps_tdma == 2))) {
1587 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
1588 true, 9);
1589 coex_dm->tdma_adj_type = 9;
1590 } else if (coex_dm->cur_ps_tdma == 11) {
1591 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
1592 true, 9);
1593 coex_dm->tdma_adj_type = 9;
1594 } else if (coex_dm->cur_ps_tdma == 9) {
1595 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
1596 true, 2);
1597 coex_dm->tdma_adj_type = 2;
1598 } else if (coex_dm->cur_ps_tdma == 2) {
1599 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
1600 true, 1);
1601 coex_dm->tdma_adj_type = 1;
1602 }
1603 } else { /*no change */
1604 /*if busy / idle change */
1605 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
1606 "[BTCoex],********* TDMA(on, %d) ********\n",
1607 coex_dm->cur_ps_tdma);
1608 }
1609
1610 if (coex_dm->cur_ps_tdma != 1 && coex_dm->cur_ps_tdma != 2 &&
1611 coex_dm->cur_ps_tdma != 9 && coex_dm->cur_ps_tdma != 11) {
1612 /* recover to previous adjust type */
1613 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
1614 coex_dm->tdma_adj_type);
1615 }
1616 }
1617}
1618
1619static void btc8723b1ant_pstdmachkpwrsave(struct btc_coexist *btcoexist,
1620 bool new_ps_state)
1621{
1622 u8 lps_mode = 0x0;
1623
1624 btcoexist->btc_get(btcoexist, BTC_GET_U1_LPS_MODE, &lps_mode);
1625
1626 if (lps_mode) { /* already under LPS state */
1627 if (new_ps_state) {
1628 /* keep state under LPS, do nothing. */
1629 } else {
1630 /* will leave LPS state, turn off psTdma first */
1631 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
1632 false, 0);
1633 }
1634 } else { /* NO PS state */
1635 if (new_ps_state) {
1636 /* will enter LPS state, turn off psTdma first */
1637 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
1638 false, 0);
1639 } else {
1640 /* keep state under NO PS state, do nothing. */
1641 }
1642 }
1643}
1644
1645static void halbtc8723b1ant_power_save_state(struct btc_coexist *btcoexist,
1646 u8 ps_type, u8 lps_val,
1647 u8 rpwm_val)
1648{
1649 bool low_pwr_disable = false;
1650
1651 switch (ps_type) {
1652 case BTC_PS_WIFI_NATIVE:
1653 /* recover to original 32k low power setting */
1654 low_pwr_disable = false;
1655 btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER,
1656 &low_pwr_disable);
1657 btcoexist->btc_set(btcoexist, BTC_SET_ACT_NORMAL_LPS, NULL);
1658 break;
1659 case BTC_PS_LPS_ON:
1660 btc8723b1ant_pstdmachkpwrsave(btcoexist, true);
1661 halbtc8723b1ant_LpsRpwm(btcoexist, NORMAL_EXEC, lps_val,
1662 rpwm_val);
1663 /* when coex force to enter LPS, do not enter 32k low power. */
1664 low_pwr_disable = true;
1665 btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER,
1666 &low_pwr_disable);
1667 /* power save must executed before psTdma. */
1668 btcoexist->btc_set(btcoexist, BTC_SET_ACT_ENTER_LPS, NULL);
1669 break;
1670 case BTC_PS_LPS_OFF:
1671 btc8723b1ant_pstdmachkpwrsave(btcoexist, false);
1672 btcoexist->btc_set(btcoexist, BTC_SET_ACT_LEAVE_LPS, NULL);
1673 break;
1674 default:
1675 break;
1676 }
1677}
1678
1679/***************************************************
1680 *
1681 * Software Coex Mechanism start
1682 *
1683 ***************************************************/
1684/* SCO only or SCO+PAN(HS) */
1685static void halbtc8723b1ant_action_sco(struct btc_coexist *btcoexist)
1686{
1687 halbtc8723b1ant_sw_mechanism(btcoexist, true);
1688}
1689
1690static void halbtc8723b1ant_action_hid(struct btc_coexist *btcoexist)
1691{
1692 halbtc8723b1ant_sw_mechanism(btcoexist, true);
1693}
1694
1695/*A2DP only / PAN(EDR) only/ A2DP+PAN(HS) */
1696static void halbtc8723b1ant_action_a2dp(struct btc_coexist *btcoexist)
1697{
1698 halbtc8723b1ant_sw_mechanism(btcoexist, false);
1699}
1700
1701static void halbtc8723b1ant_action_a2dp_pan_hs(struct btc_coexist *btcoexist)
1702{
1703 halbtc8723b1ant_sw_mechanism(btcoexist, false);
1704}
1705
1706static void halbtc8723b1ant_action_pan_edr(struct btc_coexist *btcoexist)
1707{
1708 halbtc8723b1ant_sw_mechanism(btcoexist, false);
1709}
1710
1711/* PAN(HS) only */
1712static void halbtc8723b1ant_action_pan_hs(struct btc_coexist *btcoexist)
1713{
1714 halbtc8723b1ant_sw_mechanism(btcoexist, false);
1715}
1716
1717/*PAN(EDR)+A2DP */
1718static void halbtc8723b1ant_action_pan_edr_a2dp(struct btc_coexist *btcoexist)
1719{
1720 halbtc8723b1ant_sw_mechanism(btcoexist, false);
1721}
1722
1723static void halbtc8723b1ant_action_pan_edr_hid(struct btc_coexist *btcoexist)
1724{
1725 halbtc8723b1ant_sw_mechanism(btcoexist, true);
1726}
1727
1728/* HID+A2DP+PAN(EDR) */
1729static void btc8723b1ant_action_hid_a2dp_pan_edr(struct btc_coexist *btcoexist)
1730{
1731 halbtc8723b1ant_sw_mechanism(btcoexist, true);
1732}
1733
1734static void halbtc8723b1ant_action_hid_a2dp(struct btc_coexist *btcoexist)
1735{
1736 halbtc8723b1ant_sw_mechanism(btcoexist, true);
1737}
1738
1739/*****************************************************
1740 *
1741 * Non-Software Coex Mechanism start
1742 *
1743 *****************************************************/
1744static void halbtc8723b1ant_action_wifi_multiport(struct btc_coexist *btcoexist)
1745{
1746 halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE,
1747 0x0, 0x0);
1748
1749 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
1750 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2);
1751}
1752
1753static void halbtc8723b1ant_action_hs(struct btc_coexist *btcoexist)
1754{
1755 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 5);
1756 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2);
1757}
1758
1759static void halbtc8723b1ant_action_bt_inquiry(struct btc_coexist *btcoexist)
1760{
1761 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
1762 bool wifi_connected = false, ap_enable = false;
1763
1764 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE,
1765 &ap_enable);
1766 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
1767 &wifi_connected);
1768
1769 if (!wifi_connected) {
1770 halbtc8723b1ant_power_save_state(btcoexist,
1771 BTC_PS_WIFI_NATIVE, 0x0, 0x0);
1772 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
1773 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2);
1774 } else if (bt_link_info->sco_exist || bt_link_info->hid_only) {
1775 /* SCO/HID-only busy */
1776 halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE,
1777 0x0, 0x0);
1778 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 32);
1779 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
1780 } else {
1781 if (ap_enable)
1782 halbtc8723b1ant_power_save_state(btcoexist,
1783 BTC_PS_WIFI_NATIVE,
1784 0x0, 0x0);
1785 else
1786 halbtc8723b1ant_power_save_state(btcoexist,
1787 BTC_PS_LPS_ON,
1788 0x50, 0x4);
1789
1790 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 30);
1791 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
1792 }
1793}
1794
1795static void btc8723b1ant_act_bt_sco_hid_only_busy(struct btc_coexist *btcoexist,
1796 u8 wifi_status)
1797{
1798 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
1799 bool wifi_connected = false;
1800
1801 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
1802 &wifi_connected);
1803
1804 /* tdma and coex table */
1805
1806 if (bt_link_info->sco_exist) {
1807 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 5);
1808 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2);
1809 } else { /* HID */
1810 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 6);
1811 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 5);
1812 }
1813}
1814
1815static void halbtc8723b1ant_action_wifi_connected_bt_acl_busy(
1816 struct btc_coexist *btcoexist,
1817 u8 wifi_status)
1818{
1819 u8 bt_rssi_state;
1820
1821 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
1822
1823 bt_rssi_state = halbtc8723b1ant_bt_rssi_state(2, 28, 0);
1824
1825 if (bt_link_info->hid_only) { /*HID */
1826 btc8723b1ant_act_bt_sco_hid_only_busy(btcoexist, wifi_status);
1827 coex_dm->auto_tdma_adjust = false;
1828 return;
1829 } else if (bt_link_info->a2dp_only) { /*A2DP */
1830 if (BT_8723B_1ANT_WIFI_STATUS_CONNECTED_IDLE == wifi_status) {
1831 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
1832 false, 8);
1833 halbtc8723b1ant_coex_table_with_type(btcoexist,
1834 NORMAL_EXEC, 2);
1835 coex_dm->auto_tdma_adjust = false;
1836 } else if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
1837 (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
1838 btc8723b1ant_tdma_dur_adj_for_acl(btcoexist,
1839 wifi_status);
1840 halbtc8723b1ant_coex_table_with_type(btcoexist,
1841 NORMAL_EXEC, 1);
1842 } else { /*for low BT RSSI */
1843 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
1844 true, 11);
1845 halbtc8723b1ant_coex_table_with_type(btcoexist,
1846 NORMAL_EXEC, 1);
1847 coex_dm->auto_tdma_adjust = false;
1848 }
1849 } else if (bt_link_info->hid_exist &&
1850 bt_link_info->a2dp_exist) { /*HID+A2DP */
1851 if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
1852 (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
1853 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
1854 true, 14);
1855 coex_dm->auto_tdma_adjust = false;
1856 } else { /*for low BT RSSI*/
1857 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
1858 true, 14);
1859 coex_dm->auto_tdma_adjust = false;
1860 }
1861
1862 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 6);
1863 /*PAN(OPP,FTP), HID+PAN(OPP,FTP) */
1864 } else if (bt_link_info->pan_only ||
1865 (bt_link_info->hid_exist && bt_link_info->pan_exist)) {
1866 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3);
1867 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 6);
1868 coex_dm->auto_tdma_adjust = false;
1869 /*A2DP+PAN(OPP,FTP), HID+A2DP+PAN(OPP,FTP)*/
1870 } else if ((bt_link_info->a2dp_exist && bt_link_info->pan_exist) ||
1871 (bt_link_info->hid_exist && bt_link_info->a2dp_exist &&
1872 bt_link_info->pan_exist)) {
1873 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 13);
1874 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
1875 coex_dm->auto_tdma_adjust = false;
1876 } else {
1877 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 11);
1878 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
1879 coex_dm->auto_tdma_adjust = false;
1880 }
1881}
1882
1883static void btc8723b1ant_action_wifi_not_conn(struct btc_coexist *btcoexist)
1884{
1885 /* power save state */
1886 halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE,
1887 0x0, 0x0);
1888
1889 /* tdma and coex table */
1890 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
1891 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
1892}
1893
1894static void btc8723b1ant_action_wifi_not_conn_scan(struct btc_coexist *btcoex)
1895{
1896 struct btc_bt_link_info *bt_link_info = &btcoex->bt_link_info;
1897
1898 halbtc8723b1ant_power_save_state(btcoex, BTC_PS_WIFI_NATIVE,
1899 0x0, 0x0);
1900
1901 /* tdma and coex table */
1902 if (BT_8723B_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) {
1903 if (bt_link_info->a2dp_exist && bt_link_info->pan_exist) {
1904 halbtc8723b1ant_ps_tdma(btcoex, NORMAL_EXEC,
1905 true, 22);
1906 halbtc8723b1ant_coex_table_with_type(btcoex,
1907 NORMAL_EXEC, 1);
1908 } else if (bt_link_info->pan_only) {
1909 halbtc8723b1ant_ps_tdma(btcoex, NORMAL_EXEC,
1910 true, 20);
1911 halbtc8723b1ant_coex_table_with_type(btcoex,
1912 NORMAL_EXEC, 2);
1913 } else {
1914 halbtc8723b1ant_ps_tdma(btcoex, NORMAL_EXEC,
1915 true, 20);
1916 halbtc8723b1ant_coex_table_with_type(btcoex,
1917 NORMAL_EXEC, 1);
1918 }
1919 } else if ((BT_8723B_1ANT_BT_STATUS_SCO_BUSY == coex_dm->bt_status) ||
1920 (BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY ==
1921 coex_dm->bt_status)){
1922 btc8723b1ant_act_bt_sco_hid_only_busy(btcoex,
1923 BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SCAN);
1924 } else {
1925 halbtc8723b1ant_ps_tdma(btcoex, NORMAL_EXEC, false, 8);
1926 halbtc8723b1ant_coex_table_with_type(btcoex, NORMAL_EXEC, 2);
1927 }
1928}
1929
1930static void btc8723b1ant_act_wifi_not_conn_asso_auth(struct btc_coexist *btcoex)
1931{
1932 struct btc_bt_link_info *bt_link_info = &btcoex->bt_link_info;
1933
1934 halbtc8723b1ant_power_save_state(btcoex, BTC_PS_WIFI_NATIVE,
1935 0x0, 0x0);
1936
1937 if ((BT_8723B_1ANT_BT_STATUS_CONNECTED_IDLE == coex_dm->bt_status) ||
1938 (bt_link_info->sco_exist) || (bt_link_info->hid_only) ||
1939 (bt_link_info->a2dp_only) || (bt_link_info->pan_only)) {
1940 halbtc8723b1ant_ps_tdma(btcoex, NORMAL_EXEC, false, 8);
1941 halbtc8723b1ant_coex_table_with_type(btcoex, NORMAL_EXEC, 7);
1942 } else {
1943 halbtc8723b1ant_ps_tdma(btcoex, NORMAL_EXEC, true, 20);
1944 halbtc8723b1ant_coex_table_with_type(btcoex, NORMAL_EXEC, 1);
1945 }
1946}
1947
1948static void btc8723b1ant_action_wifi_conn_scan(struct btc_coexist *btcoexist)
1949{
1950 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
1951
1952 halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE,
1953 0x0, 0x0);
1954
1955 /* tdma and coex table */
1956 if (BT_8723B_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) {
1957 if (bt_link_info->a2dp_exist && bt_link_info->pan_exist) {
1958 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
1959 true, 22);
1960 halbtc8723b1ant_coex_table_with_type(btcoexist,
1961 NORMAL_EXEC, 1);
1962 } else if (bt_link_info->pan_only) {
1963 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
1964 true, 20);
1965 halbtc8723b1ant_coex_table_with_type(btcoexist,
1966 NORMAL_EXEC, 2);
1967 } else {
1968 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
1969 true, 20);
1970 halbtc8723b1ant_coex_table_with_type(btcoexist,
1971 NORMAL_EXEC, 1);
1972 }
1973 } else if ((BT_8723B_1ANT_BT_STATUS_SCO_BUSY == coex_dm->bt_status) ||
1974 (BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY ==
1975 coex_dm->bt_status)) {
1976 btc8723b1ant_act_bt_sco_hid_only_busy(btcoexist,
1977 BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SCAN);
1978 } else {
1979 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
1980 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2);
1981 }
1982}
1983
1984static void halbtc8723b1ant_action_wifi_connected_special_packet(
1985 struct btc_coexist *btcoexist)
1986{
1987 bool hs_connecting = false;
1988 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
1989
1990 btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_CONNECTING, &hs_connecting);
1991
1992 halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE,
1993 0x0, 0x0);
1994
1995 /* tdma and coex table */
1996 if ((BT_8723B_1ANT_BT_STATUS_CONNECTED_IDLE == coex_dm->bt_status) ||
1997 (bt_link_info->sco_exist) || (bt_link_info->hid_only) ||
1998 (bt_link_info->a2dp_only) || (bt_link_info->pan_only)) {
1999 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
2000 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 7);
2001 } else {
2002 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 20);
2003 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
2004 }
2005}
2006
2007static void halbtc8723b1ant_action_wifi_connected(struct btc_coexist *btcoexist)
2008{
2009 bool wifi_busy = false;
2010 bool scan = false, link = false, roam = false;
2011 bool under_4way = false, ap_enable = false;
2012
2013 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2014 "[BTCoex], CoexForWifiConnect()===>\n");
2015
2016 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS,
2017 &under_4way);
2018 if (under_4way) {
2019 halbtc8723b1ant_action_wifi_connected_special_packet(btcoexist);
2020 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2021 "[BTCoex], CoexForWifiConnect(), return for wifi is under 4way<===\n");
2022 return;
2023 }
2024
2025 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan);
2026 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link);
2027 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam);
2028
2029 if (scan || link || roam) {
2030 if (scan)
2031 btc8723b1ant_action_wifi_conn_scan(btcoexist);
2032 else
2033 halbtc8723b1ant_action_wifi_connected_special_packet(
2034 btcoexist);
2035 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2036 "[BTCoex], CoexForWifiConnect(), return for wifi is under scan<===\n");
2037 return;
2038 }
2039
2040 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE,
2041 &ap_enable);
2042 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
2043 /* power save state */
2044 if (!ap_enable &&
2045 BT_8723B_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status &&
2046 !btcoexist->bt_link_info.hid_only) {
2047 if (!wifi_busy && btcoexist->bt_link_info.a2dp_only)
2048 halbtc8723b1ant_power_save_state(btcoexist,
2049 BTC_PS_WIFI_NATIVE,
2050 0x0, 0x0);
2051 else
2052 halbtc8723b1ant_power_save_state(btcoexist,
2053 BTC_PS_LPS_ON,
2054 0x50, 0x4);
2055 } else {
2056 halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE,
2057 0x0, 0x0);
2058 }
2059 /* tdma and coex table */
2060 if (!wifi_busy) {
2061 if (BT_8723B_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) {
2062 halbtc8723b1ant_action_wifi_connected_bt_acl_busy(btcoexist,
2063 BT_8723B_1ANT_WIFI_STATUS_CONNECTED_IDLE);
2064 } else if ((BT_8723B_1ANT_BT_STATUS_SCO_BUSY ==
2065 coex_dm->bt_status) ||
2066 (BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY ==
2067 coex_dm->bt_status)) {
2068 btc8723b1ant_act_bt_sco_hid_only_busy(btcoexist,
2069 BT_8723B_1ANT_WIFI_STATUS_CONNECTED_IDLE);
2070 } else {
2071 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
2072 false, 8);
2073 halbtc8723b1ant_coex_table_with_type(btcoexist,
2074 NORMAL_EXEC, 2);
2075 }
2076 } else {
2077 if (BT_8723B_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) {
2078 halbtc8723b1ant_action_wifi_connected_bt_acl_busy(btcoexist,
2079 BT_8723B_1ANT_WIFI_STATUS_CONNECTED_BUSY);
2080 } else if ((BT_8723B_1ANT_BT_STATUS_SCO_BUSY ==
2081 coex_dm->bt_status) ||
2082 (BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY ==
2083 coex_dm->bt_status)) {
2084 btc8723b1ant_act_bt_sco_hid_only_busy(btcoexist,
2085 BT_8723B_1ANT_WIFI_STATUS_CONNECTED_BUSY);
2086 } else {
2087 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC,
2088 false, 8);
2089 halbtc8723b1ant_coex_table_with_type(btcoexist,
2090 NORMAL_EXEC, 2);
2091 }
2092 }
2093}
2094
2095static void btc8723b1ant_run_sw_coex_mech(struct btc_coexist *btcoexist)
2096{
2097 u8 algorithm = 0;
2098
2099 algorithm = halbtc8723b1ant_action_algorithm(btcoexist);
2100 coex_dm->cur_algorithm = algorithm;
2101
2102 if (!halbtc8723b1ant_is_common_action(btcoexist)) {
2103 switch (coex_dm->cur_algorithm) {
2104 case BT_8723B_1ANT_COEX_ALGO_SCO:
2105 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2106 "[BTCoex], Action algorithm = SCO.\n");
2107 halbtc8723b1ant_action_sco(btcoexist);
2108 break;
2109 case BT_8723B_1ANT_COEX_ALGO_HID:
2110 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2111 "[BTCoex], Action algorithm = HID.\n");
2112 halbtc8723b1ant_action_hid(btcoexist);
2113 break;
2114 case BT_8723B_1ANT_COEX_ALGO_A2DP:
2115 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2116 "[BTCoex], Action algorithm = A2DP.\n");
2117 halbtc8723b1ant_action_a2dp(btcoexist);
2118 break;
2119 case BT_8723B_1ANT_COEX_ALGO_A2DP_PANHS:
2120 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2121 "[BTCoex], Action algorithm = A2DP+PAN(HS).\n");
2122 halbtc8723b1ant_action_a2dp_pan_hs(btcoexist);
2123 break;
2124 case BT_8723B_1ANT_COEX_ALGO_PANEDR:
2125 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2126 "[BTCoex], Action algorithm = PAN(EDR).\n");
2127 halbtc8723b1ant_action_pan_edr(btcoexist);
2128 break;
2129 case BT_8723B_1ANT_COEX_ALGO_PANHS:
2130 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2131 "[BTCoex], Action algorithm = HS mode.\n");
2132 halbtc8723b1ant_action_pan_hs(btcoexist);
2133 break;
2134 case BT_8723B_1ANT_COEX_ALGO_PANEDR_A2DP:
2135 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2136 "[BTCoex], Action algorithm = PAN+A2DP.\n");
2137 halbtc8723b1ant_action_pan_edr_a2dp(btcoexist);
2138 break;
2139 case BT_8723B_1ANT_COEX_ALGO_PANEDR_HID:
2140 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2141 "[BTCoex], Action algorithm = PAN(EDR)+HID.\n");
2142 halbtc8723b1ant_action_pan_edr_hid(btcoexist);
2143 break;
2144 case BT_8723B_1ANT_COEX_ALGO_HID_A2DP_PANEDR:
2145 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2146 "[BTCoex], Action algorithm = HID+A2DP+PAN.\n");
2147 btc8723b1ant_action_hid_a2dp_pan_edr(btcoexist);
2148 break;
2149 case BT_8723B_1ANT_COEX_ALGO_HID_A2DP:
2150 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2151 "[BTCoex], Action algorithm = HID+A2DP.\n");
2152 halbtc8723b1ant_action_hid_a2dp(btcoexist);
2153 break;
2154 default:
2155 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2156 "[BTCoex], Action algorithm = coexist All Off!!\n");
2157 break;
2158 }
2159 coex_dm->pre_algorithm = coex_dm->cur_algorithm;
2160 }
2161}
2162
2163static void halbtc8723b1ant_run_coexist_mechanism(struct btc_coexist *btcoexist)
2164{
2165 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
2166 bool wifi_connected = false, bt_hs_on = false;
2167 bool increase_scan_dev_num = false;
2168 bool bt_ctrl_agg_buf_size = false;
2169 u8 agg_buf_size = 5;
2170 u8 wifi_rssi_state = BTC_RSSI_STATE_HIGH;
2171 u32 wifi_link_status = 0;
2172 u32 num_of_wifi_link = 0;
2173
2174 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2175 "[BTCoex], RunCoexistMechanism()===>\n");
2176
2177 if (btcoexist->manual_control) {
2178 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2179 "[BTCoex], RunCoexistMechanism(), return for Manual CTRL <===\n");
2180 return;
2181 }
2182
2183 if (btcoexist->stop_coex_dm) {
2184 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2185 "[BTCoex], RunCoexistMechanism(), return for Stop Coex DM <===\n");
2186 return;
2187 }
2188
2189 if (coex_sta->under_ips) {
2190 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2191 "[BTCoex], wifi is under IPS !!!\n");
2192 return;
2193 }
2194
2195 if ((BT_8723B_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) ||
2196 (BT_8723B_1ANT_BT_STATUS_SCO_BUSY == coex_dm->bt_status) ||
2197 (BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY == coex_dm->bt_status)) {
2198 increase_scan_dev_num = true;
2199 }
2200
2201 btcoexist->btc_set(btcoexist, BTC_SET_BL_INC_SCAN_DEV_NUM,
2202 &increase_scan_dev_num);
2203
2204 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
2205 &wifi_connected);
2206
2207 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS,
2208 &wifi_link_status);
2209 num_of_wifi_link = wifi_link_status >> 16;
2210 if (num_of_wifi_link >= 2) {
2211 halbtc8723b1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0);
2212 halbtc8723b1ant_limited_rx(btcoexist, NORMAL_EXEC, false,
2213 bt_ctrl_agg_buf_size,
2214 agg_buf_size);
2215 halbtc8723b1ant_action_wifi_multiport(btcoexist);
2216 return;
2217 }
2218
2219 if (!bt_link_info->sco_exist && !bt_link_info->hid_exist) {
2220 halbtc8723b1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0);
2221 } else {
2222 if (wifi_connected) {
2223 wifi_rssi_state =
2224 halbtc8723b1ant_wifi_rssi_state(btcoexist,
2225 1, 2, 30, 0);
2226 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
2227 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2228 halbtc8723b1ant_limited_tx(btcoexist,
2229 NORMAL_EXEC,
2230 1, 1, 1, 1);
2231 } else {
2232 halbtc8723b1ant_limited_tx(btcoexist,
2233 NORMAL_EXEC,
2234 1, 1, 1, 1);
2235 }
2236 } else {
2237 halbtc8723b1ant_limited_tx(btcoexist, NORMAL_EXEC,
2238 0, 0, 0, 0);
2239 }
2240 }
2241
2242 if (bt_link_info->sco_exist) {
2243 bt_ctrl_agg_buf_size = true;
2244 agg_buf_size = 0x3;
2245 } else if (bt_link_info->hid_exist) {
2246 bt_ctrl_agg_buf_size = true;
2247 agg_buf_size = 0x5;
2248 } else if (bt_link_info->a2dp_exist || bt_link_info->pan_exist) {
2249 bt_ctrl_agg_buf_size = true;
2250 agg_buf_size = 0x8;
2251 }
2252 halbtc8723b1ant_limited_rx(btcoexist, NORMAL_EXEC, false,
2253 bt_ctrl_agg_buf_size, agg_buf_size);
2254
2255 btc8723b1ant_run_sw_coex_mech(btcoexist);
2256
2257 btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
2258
2259 if (coex_sta->c2h_bt_inquiry_page) {
2260 halbtc8723b1ant_action_bt_inquiry(btcoexist);
2261 return;
2262 } else if (bt_hs_on) {
2263 halbtc8723b1ant_action_hs(btcoexist);
2264 return;
2265 }
2266
2267 if (!wifi_connected) {
2268 bool scan = false, link = false, roam = false;
2269
2270 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2271 "[BTCoex], wifi is non connected-idle !!!\n");
2272
2273 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan);
2274 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link);
2275 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam);
2276
2277 if (scan || link || roam) {
2278 if (scan)
2279 btc8723b1ant_action_wifi_not_conn_scan(
2280 btcoexist);
2281 else
2282 btc8723b1ant_act_wifi_not_conn_asso_auth(
2283 btcoexist);
2284 } else {
2285 btc8723b1ant_action_wifi_not_conn(btcoexist);
2286 }
2287 } else { /* wifi LPS/Busy */
2288 halbtc8723b1ant_action_wifi_connected(btcoexist);
2289 }
2290}
2291
2292static void halbtc8723b1ant_init_coex_dm(struct btc_coexist *btcoexist)
2293{
2294 /* sw all off */
2295 halbtc8723b1ant_sw_mechanism(btcoexist, false);
2296
2297 halbtc8723b1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 8);
2298 halbtc8723b1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 0);
2299}
2300
2301static void halbtc8723b1ant_init_hw_config(struct btc_coexist *btcoexist,
2302 bool backup)
2303{
2304 u32 u32tmp = 0;
2305 u8 u8tmp = 0;
2306 u32 cnt_bt_cal_chk = 0;
2307
2308 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
2309 "[BTCoex], 1Ant Init HW Config!!\n");
2310
2311 if (backup) {/* backup rf 0x1e value */
2312 coex_dm->backup_arfr_cnt1 =
2313 btcoexist->btc_read_4byte(btcoexist, 0x430);
2314 coex_dm->backup_arfr_cnt2 =
2315 btcoexist->btc_read_4byte(btcoexist, 0x434);
2316 coex_dm->backup_retry_limit =
2317 btcoexist->btc_read_2byte(btcoexist, 0x42a);
2318 coex_dm->backup_ampdu_max_time =
2319 btcoexist->btc_read_1byte(btcoexist, 0x456);
2320 }
2321
2322 /* WiFi goto standby while GNT_BT 0-->1 */
2323 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x780);
2324 /* BT goto standby while GNT_BT 1-->0 */
2325 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x2, 0xfffff, 0x500);
2326
2327 btcoexist->btc_write_1byte(btcoexist, 0x974, 0xff);
2328 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x944, 0x3, 0x3);
2329 btcoexist->btc_write_1byte(btcoexist, 0x930, 0x77);
2330
2331 /* BT calibration check */
2332 while (cnt_bt_cal_chk <= 20) {
2333 u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x49d);
2334 cnt_bt_cal_chk++;
2335 if (u32tmp & BIT0) {
2336 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
2337 "[BTCoex], ########### BT calibration(cnt=%d) ###########\n",
2338 cnt_bt_cal_chk);
2339 mdelay(50);
2340 } else {
2341 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
2342 "[BTCoex], ********** BT NOT calibration (cnt=%d)**********\n",
2343 cnt_bt_cal_chk);
2344 break;
2345 }
2346 }
2347
2348 /* 0x790[5:0] = 0x5 */
2349 u8tmp = btcoexist->btc_read_1byte(btcoexist, 0x790);
2350 u8tmp &= 0xc0;
2351 u8tmp |= 0x5;
2352 btcoexist->btc_write_1byte(btcoexist, 0x790, u8tmp);
2353
2354 /* Enable counter statistics */
2355 /*0x76e[3] =1, WLAN_Act control by PTA */
2356 btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc);
2357 btcoexist->btc_write_1byte(btcoexist, 0x778, 0x1);
2358 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x40, 0x20, 0x1);
2359
2360 /*Antenna config */
2361 halbtc8723b1ant_SetAntPath(btcoexist, BTC_ANT_PATH_PTA, true, false);
2362 /* PTA parameter */
2363 halbtc8723b1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 0);
2364}
2365
2366static void halbtc8723b1ant_wifi_off_hw_cfg(struct btc_coexist *btcoexist)
2367{
2368 /* set wlan_act to low */
2369 btcoexist->btc_write_1byte(btcoexist, 0x76e, 0x4);
2370}
2371
2372/**************************************************************
2373 * work around function start with wa_halbtc8723b1ant_
2374 **************************************************************/
2375/**************************************************************
2376 * extern function start with EXhalbtc8723b1ant_
2377 **************************************************************/
2378
2379void ex_halbtc8723b1ant_init_hwconfig(struct btc_coexist *btcoexist)
2380{
2381 halbtc8723b1ant_init_hw_config(btcoexist, true);
2382}
2383
2384void ex_halbtc8723b1ant_init_coex_dm(struct btc_coexist *btcoexist)
2385{
2386 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
2387 "[BTCoex], Coex Mechanism Init!!\n");
2388
2389 btcoexist->stop_coex_dm = false;
2390
2391 halbtc8723b1ant_init_coex_dm(btcoexist);
2392
2393 halbtc8723b1ant_query_bt_info(btcoexist);
2394}
2395
2396void ex_halbtc8723b1ant_display_coex_info(struct btc_coexist *btcoexist)
2397{
2398 struct btc_board_info *board_info = &btcoexist->board_info;
2399 struct btc_stack_info *stack_info = &btcoexist->stack_info;
2400 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
2401 struct rtl_priv *rtlpriv = btcoexist->adapter;
2402 u8 u8tmp[4], i, bt_info_ext, pstdmacase = 0;
2403 u16 u16tmp[4];
2404 u32 u32tmp[4];
2405 bool roam = false, scan = false;
2406 bool link = false, wifi_under_5g = false;
2407 bool bt_hs_on = false, wifi_busy = false;
2408 s32 wifi_rssi = 0, bt_hs_rssi = 0;
2409 u32 wifi_bw, wifi_traffic_dir, fa_ofdm, fa_cck, wifi_link_status;
2410 u8 wifi_dot11_chnl, wifi_hs_chnl;
2411 u32 fw_ver = 0, bt_patch_ver = 0;
2412
2413 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2414 "\r\n ============[BT Coexist info]============");
2415
2416 if (btcoexist->manual_control) {
2417 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2418 "\r\n ============[Under Manual Control]==========");
2419 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2420 "\r\n ==========================================");
2421 }
2422 if (btcoexist->stop_coex_dm) {
2423 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2424 "\r\n ============[Coex is STOPPED]============");
2425 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2426 "\r\n ==========================================");
2427 }
2428
2429 if (!board_info->bt_exist) {
2430 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n BT not exists !!!");
2431 return;
2432 }
2433
2434 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d/ %d",
2435 "Ant PG Num/ Ant Mech/ Ant Pos:",
2436 board_info->pg_ant_num, board_info->btdm_ant_num,
2437 board_info->btdm_ant_pos);
2438
2439 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %s / %d",
2440 "BT stack/ hci ext ver",
2441 ((stack_info->profile_notified) ? "Yes" : "No"),
2442 stack_info->hci_version);
2443
2444 btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER, &bt_patch_ver);
2445 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver);
2446 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2447 "\r\n %-35s = %d_%x/ 0x%x/ 0x%x(%d)",
2448 "CoexVer/ FwVer/ PatchVer",
2449 glcoex_ver_date_8723b_1ant, glcoex_ver_8723b_1ant,
2450 fw_ver, bt_patch_ver, bt_patch_ver);
2451
2452 btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
2453 btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_DOT11_CHNL,
2454 &wifi_dot11_chnl);
2455 btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_HS_CHNL, &wifi_hs_chnl);
2456 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d / %d(%d)",
2457 "Dot11 channel / HsChnl(HsMode)",
2458 wifi_dot11_chnl, wifi_hs_chnl, bt_hs_on);
2459
2460 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %02x %02x %02x ",
2461 "H2C Wifi inform bt chnl Info",
2462 coex_dm->wifi_chnl_info[0], coex_dm->wifi_chnl_info[1],
2463 coex_dm->wifi_chnl_info[2]);
2464
2465 btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi);
2466 btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi);
2467 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d",
2468 "Wifi rssi/ HS rssi", wifi_rssi, bt_hs_rssi);
2469
2470 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan);
2471 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link);
2472 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam);
2473 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d/ %d ",
2474 "Wifi link/ roam/ scan", link, roam, scan);
2475
2476 btcoexist->btc_get(btcoexist , BTC_GET_BL_WIFI_UNDER_5G,
2477 &wifi_under_5g);
2478 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
2479 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
2480 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION,
2481 &wifi_traffic_dir);
2482
2483 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %s / %s/ %s ",
2484 "Wifi status", (wifi_under_5g ? "5G" : "2.4G"),
2485 ((BTC_WIFI_BW_LEGACY == wifi_bw) ? "Legacy" :
2486 (((BTC_WIFI_BW_HT40 == wifi_bw) ? "HT40" : "HT20"))),
2487 ((!wifi_busy) ? "idle" :
2488 ((BTC_WIFI_TRAFFIC_TX == wifi_traffic_dir) ?
2489 "uplink" : "downlink")));
2490
2491 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS,
2492 &wifi_link_status);
2493 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d/ %d/ %d/ %d",
2494 "sta/vwifi/hs/p2pGo/p2pGc",
2495 ((wifi_link_status & WIFI_STA_CONNECTED) ? 1 : 0),
2496 ((wifi_link_status & WIFI_AP_CONNECTED) ? 1 : 0),
2497 ((wifi_link_status & WIFI_HS_CONNECTED) ? 1 : 0),
2498 ((wifi_link_status & WIFI_P2P_GO_CONNECTED) ? 1 : 0),
2499 ((wifi_link_status & WIFI_P2P_GC_CONNECTED) ? 1 : 0));
2500
2501 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = [%s/ %d/ %d] ",
2502 "BT [status/ rssi/ retryCnt]",
2503 ((btcoexist->bt_info.bt_disabled) ? ("disabled") :
2504 ((coex_sta->c2h_bt_inquiry_page) ? ("inquiry/page scan") :
2505 ((BT_8723B_1ANT_BT_STATUS_NON_CONNECTED_IDLE ==
2506 coex_dm->bt_status) ?
2507 "non-connected idle" :
2508 ((BT_8723B_1ANT_BT_STATUS_CONNECTED_IDLE ==
2509 coex_dm->bt_status) ?
2510 "connected-idle" : "busy")))),
2511 coex_sta->bt_rssi, coex_sta->bt_retry_cnt);
2512
2513 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2514 "\r\n %-35s = %d / %d / %d / %d",
2515 "SCO/HID/PAN/A2DP", bt_link_info->sco_exist,
2516 bt_link_info->hid_exist, bt_link_info->pan_exist,
2517 bt_link_info->a2dp_exist);
2518 btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_BT_LINK_INFO);
2519
2520 bt_info_ext = coex_sta->bt_info_ext;
2521 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %s",
2522 "BT Info A2DP rate",
2523 (bt_info_ext & BIT0) ? "Basic rate" : "EDR rate");
2524
2525 for (i = 0; i < BT_INFO_SRC_8723B_1ANT_MAX; i++) {
2526 if (coex_sta->bt_info_c2h_cnt[i]) {
2527 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2528 "\r\n %-35s = %02x %02x %02x %02x %02x %02x %02x(%d)",
2529 GLBtInfoSrc8723b1Ant[i],
2530 coex_sta->bt_info_c2h[i][0],
2531 coex_sta->bt_info_c2h[i][1],
2532 coex_sta->bt_info_c2h[i][2],
2533 coex_sta->bt_info_c2h[i][3],
2534 coex_sta->bt_info_c2h[i][4],
2535 coex_sta->bt_info_c2h[i][5],
2536 coex_sta->bt_info_c2h[i][6],
2537 coex_sta->bt_info_c2h_cnt[i]);
2538 }
2539 }
2540 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2541 "\r\n %-35s = %s/%s, (0x%x/0x%x)",
2542 "PS state, IPS/LPS, (lps/rpwm)",
2543 ((coex_sta->under_ips ? "IPS ON" : "IPS OFF")),
2544 ((coex_sta->under_lps ? "LPS ON" : "LPS OFF")),
2545 btcoexist->bt_info.lps_val,
2546 btcoexist->bt_info.rpwm_val);
2547 btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_FW_PWR_MODE_CMD);
2548
2549 if (!btcoexist->manual_control) {
2550 /* Sw mechanism */
2551 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s",
2552 "============[Sw mechanism]============");
2553
2554 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/",
2555 "SM[LowPenaltyRA]", coex_dm->cur_low_penalty_ra);
2556
2557 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %s/ %s/ %d ",
2558 "DelBA/ BtCtrlAgg/ AggSize",
2559 (btcoexist->bt_info.reject_agg_pkt ? "Yes" : "No"),
2560 (btcoexist->bt_info.bt_ctrl_buf_size ? "Yes" : "No"),
2561 btcoexist->bt_info.agg_buf_size);
2562
2563 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x ",
2564 "Rate Mask", btcoexist->bt_info.ra_mask);
2565
2566 /* Fw mechanism */
2567 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s",
2568 "============[Fw mechanism]============");
2569
2570 pstdmacase = coex_dm->cur_ps_tdma;
2571 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2572 "\r\n %-35s = %02x %02x %02x %02x %02x case-%d (auto:%d)",
2573 "PS TDMA", coex_dm->ps_tdma_para[0],
2574 coex_dm->ps_tdma_para[1], coex_dm->ps_tdma_para[2],
2575 coex_dm->ps_tdma_para[3], coex_dm->ps_tdma_para[4],
2576 pstdmacase, coex_dm->auto_tdma_adjust);
2577
2578 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d ",
2579 "IgnWlanAct", coex_dm->cur_ignore_wlan_act);
2580
2581 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x ",
2582 "Latest error condition(should be 0)",
2583 coex_dm->error_condition);
2584 }
2585
2586 /* Hw setting */
2587 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s",
2588 "============[Hw setting]============");
2589
2590 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/0x%x/0x%x/0x%x",
2591 "backup ARFR1/ARFR2/RL/AMaxTime", coex_dm->backup_arfr_cnt1,
2592 coex_dm->backup_arfr_cnt2, coex_dm->backup_retry_limit,
2593 coex_dm->backup_ampdu_max_time);
2594
2595 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x430);
2596 u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x434);
2597 u16tmp[0] = btcoexist->btc_read_2byte(btcoexist, 0x42a);
2598 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x456);
2599 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/0x%x/0x%x/0x%x",
2600 "0x430/0x434/0x42a/0x456",
2601 u32tmp[0], u32tmp[1], u16tmp[0], u8tmp[0]);
2602
2603 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x778);
2604 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x6cc);
2605 u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x880);
2606 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
2607 "0x778/0x6cc/0x880[29:25]", u8tmp[0], u32tmp[0],
2608 (u32tmp[1] & 0x3e000000) >> 25);
2609
2610 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x948);
2611 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x67);
2612 u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x765);
2613 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
2614 "0x948/ 0x67[5] / 0x765",
2615 u32tmp[0], ((u8tmp[0] & 0x20) >> 5), u8tmp[1]);
2616
2617 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x92c);
2618 u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x930);
2619 u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x944);
2620 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
2621 "0x92c[1:0]/ 0x930[7:0]/0x944[1:0]",
2622 u32tmp[0] & 0x3, u32tmp[1] & 0xff, u32tmp[2] & 0x3);
2623
2624 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x39);
2625 u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x40);
2626 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x4c);
2627 u8tmp[2] = btcoexist->btc_read_1byte(btcoexist, 0x64);
2628 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2629 "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x",
2630 "0x38[11]/0x40/0x4c[24:23]/0x64[0]",
2631 ((u8tmp[0] & 0x8)>>3), u8tmp[1],
2632 ((u32tmp[0] & 0x01800000) >> 23), u8tmp[2] & 0x1);
2633
2634 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x550);
2635 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x522);
2636 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x",
2637 "0x550(bcn ctrl)/0x522", u32tmp[0], u8tmp[0]);
2638
2639 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xc50);
2640 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x49c);
2641 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x",
2642 "0xc50(dig)/0x49c(null-drop)", u32tmp[0] & 0xff, u8tmp[0]);
2643
2644 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xda0);
2645 u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0xda4);
2646 u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0xda8);
2647 u32tmp[3] = btcoexist->btc_read_4byte(btcoexist, 0xcf0);
2648
2649 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0xa5b);
2650 u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0xa5c);
2651
2652 fa_ofdm = ((u32tmp[0] & 0xffff0000) >> 16) +
2653 ((u32tmp[1] & 0xffff0000) >> 16) +
2654 (u32tmp[1] & 0xffff) +
2655 (u32tmp[2] & 0xffff) +
2656 ((u32tmp[3] & 0xffff0000) >> 16) +
2657 (u32tmp[3] & 0xffff);
2658 fa_cck = (u8tmp[0] << 8) + u8tmp[1];
2659
2660 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
2661 "OFDM-CCA/OFDM-FA/CCK-FA",
2662 u32tmp[0] & 0xffff, fa_ofdm, fa_cck);
2663
2664 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x6c0);
2665 u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x6c4);
2666 u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x6c8);
2667 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
2668 "0x6c0/0x6c4/0x6c8(coexTable)",
2669 u32tmp[0], u32tmp[1], u32tmp[2]);
2670
2671 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d",
2672 "0x770(high-pri rx/tx)", coex_sta->high_priority_rx,
2673 coex_sta->high_priority_tx);
2674 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d",
2675 "0x774(low-pri rx/tx)", coex_sta->low_priority_rx,
2676 coex_sta->low_priority_tx);
2677#if (BT_AUTO_REPORT_ONLY_8723B_1ANT == 1)
2678 halbtc8723b1ant_monitor_bt_ctr(btcoexist);
2679#endif
2680 btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_COEX_STATISTICS);
2681}
2682
2683void ex_halbtc8723b1ant_ips_notify(struct btc_coexist *btcoexist, u8 type)
2684{
2685 if (btcoexist->manual_control || btcoexist->stop_coex_dm)
2686 return;
2687
2688 if (BTC_IPS_ENTER == type) {
2689 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
2690 "[BTCoex], IPS ENTER notify\n");
2691 coex_sta->under_ips = true;
2692
2693 halbtc8723b1ant_SetAntPath(btcoexist, BTC_ANT_PATH_BT,
2694 false, true);
2695 /* set PTA control */
2696 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0);
2697 halbtc8723b1ant_coex_table_with_type(btcoexist,
2698 NORMAL_EXEC, 0);
2699 halbtc8723b1ant_wifi_off_hw_cfg(btcoexist);
2700 } else if (BTC_IPS_LEAVE == type) {
2701 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
2702 "[BTCoex], IPS LEAVE notify\n");
2703 coex_sta->under_ips = false;
2704
2705 halbtc8723b1ant_init_hw_config(btcoexist, false);
2706 halbtc8723b1ant_init_coex_dm(btcoexist);
2707 halbtc8723b1ant_query_bt_info(btcoexist);
2708 }
2709}
2710
2711void ex_halbtc8723b1ant_lps_notify(struct btc_coexist *btcoexist, u8 type)
2712{
2713 if (btcoexist->manual_control || btcoexist->stop_coex_dm)
2714 return;
2715
2716 if (BTC_LPS_ENABLE == type) {
2717 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
2718 "[BTCoex], LPS ENABLE notify\n");
2719 coex_sta->under_lps = true;
2720 } else if (BTC_LPS_DISABLE == type) {
2721 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
2722 "[BTCoex], LPS DISABLE notify\n");
2723 coex_sta->under_lps = false;
2724 }
2725}
2726
2727void ex_halbtc8723b1ant_scan_notify(struct btc_coexist *btcoexist, u8 type)
2728{
2729 bool wifi_connected = false, bt_hs_on = false;
2730 u32 wifi_link_status = 0;
2731 u32 num_of_wifi_link = 0;
2732 bool bt_ctrl_agg_buf_size = false;
2733 u8 agg_buf_size = 5;
2734
2735 if (btcoexist->manual_control || btcoexist->stop_coex_dm ||
2736 btcoexist->bt_info.bt_disabled)
2737 return;
2738
2739 btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
2740 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
2741 &wifi_connected);
2742
2743 halbtc8723b1ant_query_bt_info(btcoexist);
2744
2745 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS,
2746 &wifi_link_status);
2747 num_of_wifi_link = wifi_link_status >> 16;
2748 if (num_of_wifi_link >= 2) {
2749 halbtc8723b1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0);
2750 halbtc8723b1ant_limited_rx(btcoexist, NORMAL_EXEC, false,
2751 bt_ctrl_agg_buf_size, agg_buf_size);
2752 halbtc8723b1ant_action_wifi_multiport(btcoexist);
2753 return;
2754 }
2755
2756 if (coex_sta->c2h_bt_inquiry_page) {
2757 halbtc8723b1ant_action_bt_inquiry(btcoexist);
2758 return;
2759 } else if (bt_hs_on) {
2760 halbtc8723b1ant_action_hs(btcoexist);
2761 return;
2762 }
2763
2764 if (BTC_SCAN_START == type) {
2765 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
2766 "[BTCoex], SCAN START notify\n");
2767 if (!wifi_connected) /* non-connected scan */
2768 btc8723b1ant_action_wifi_not_conn_scan(btcoexist);
2769 else /* wifi is connected */
2770 btc8723b1ant_action_wifi_conn_scan(btcoexist);
2771 } else if (BTC_SCAN_FINISH == type) {
2772 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
2773 "[BTCoex], SCAN FINISH notify\n");
2774 if (!wifi_connected) /* non-connected scan */
2775 btc8723b1ant_action_wifi_not_conn(btcoexist);
2776 else
2777 halbtc8723b1ant_action_wifi_connected(btcoexist);
2778 }
2779}
2780
2781void ex_halbtc8723b1ant_connect_notify(struct btc_coexist *btcoexist, u8 type)
2782{
2783 bool wifi_connected = false, bt_hs_on = false;
2784 u32 wifi_link_status = 0;
2785 u32 num_of_wifi_link = 0;
2786 bool bt_ctrl_agg_buf_size = false;
2787 u8 agg_buf_size = 5;
2788
2789 if (btcoexist->manual_control || btcoexist->stop_coex_dm ||
2790 btcoexist->bt_info.bt_disabled)
2791 return;
2792
2793 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS,
2794 &wifi_link_status);
2795 num_of_wifi_link = wifi_link_status>>16;
2796 if (num_of_wifi_link >= 2) {
2797 halbtc8723b1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0);
2798 halbtc8723b1ant_limited_rx(btcoexist, NORMAL_EXEC, false,
2799 bt_ctrl_agg_buf_size, agg_buf_size);
2800 halbtc8723b1ant_action_wifi_multiport(btcoexist);
2801 return;
2802 }
2803
2804 btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
2805 if (coex_sta->c2h_bt_inquiry_page) {
2806 halbtc8723b1ant_action_bt_inquiry(btcoexist);
2807 return;
2808 } else if (bt_hs_on) {
2809 halbtc8723b1ant_action_hs(btcoexist);
2810 return;
2811 }
2812
2813 if (BTC_ASSOCIATE_START == type) {
2814 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
2815 "[BTCoex], CONNECT START notify\n");
2816 btc8723b1ant_act_wifi_not_conn_asso_auth(btcoexist);
2817 } else if (BTC_ASSOCIATE_FINISH == type) {
2818 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
2819 "[BTCoex], CONNECT FINISH notify\n");
2820
2821 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
2822 &wifi_connected);
2823 if (!wifi_connected) /* non-connected scan */
2824 btc8723b1ant_action_wifi_not_conn(btcoexist);
2825 else
2826 halbtc8723b1ant_action_wifi_connected(btcoexist);
2827 }
2828}
2829
2830void ex_halbtc8723b1ant_media_status_notify(struct btc_coexist *btcoexist,
2831 u8 type)
2832{
2833 u8 h2c_parameter[3] = {0};
2834 u32 wifi_bw;
2835 u8 wifiCentralChnl;
2836
2837 if (btcoexist->manual_control || btcoexist->stop_coex_dm ||
2838 btcoexist->bt_info.bt_disabled)
2839 return;
2840
2841 if (BTC_MEDIA_CONNECT == type)
2842 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
2843 "[BTCoex], MEDIA connect notify\n");
2844 else
2845 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
2846 "[BTCoex], MEDIA disconnect notify\n");
2847
2848 /* only 2.4G we need to inform bt the chnl mask */
2849 btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_CENTRAL_CHNL,
2850 &wifiCentralChnl);
2851
2852 if ((BTC_MEDIA_CONNECT == type) &&
2853 (wifiCentralChnl <= 14)) {
2854 h2c_parameter[0] = 0x0;
2855 h2c_parameter[1] = wifiCentralChnl;
2856 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
2857 if (BTC_WIFI_BW_HT40 == wifi_bw)
2858 h2c_parameter[2] = 0x30;
2859 else
2860 h2c_parameter[2] = 0x20;
2861 }
2862
2863 coex_dm->wifi_chnl_info[0] = h2c_parameter[0];
2864 coex_dm->wifi_chnl_info[1] = h2c_parameter[1];
2865 coex_dm->wifi_chnl_info[2] = h2c_parameter[2];
2866
2867 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
2868 "[BTCoex], FW write 0x66 = 0x%x\n",
2869 h2c_parameter[0] << 16 | h2c_parameter[1] << 8 |
2870 h2c_parameter[2]);
2871
2872 btcoexist->btc_fill_h2c(btcoexist, 0x66, 3, h2c_parameter);
2873}
2874
2875void ex_halbtc8723b1ant_special_packet_notify(struct btc_coexist *btcoexist,
2876 u8 type)
2877{
2878 bool bt_hs_on = false;
2879 u32 wifi_link_status = 0;
2880 u32 num_of_wifi_link = 0;
2881 bool bt_ctrl_agg_buf_size = false;
2882 u8 agg_buf_size = 5;
2883
2884 if (btcoexist->manual_control || btcoexist->stop_coex_dm ||
2885 btcoexist->bt_info.bt_disabled)
2886 return;
2887
2888 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS,
2889 &wifi_link_status);
2890 num_of_wifi_link = wifi_link_status >> 16;
2891 if (num_of_wifi_link >= 2) {
2892 halbtc8723b1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0);
2893 halbtc8723b1ant_limited_rx(btcoexist, NORMAL_EXEC, false,
2894 bt_ctrl_agg_buf_size, agg_buf_size);
2895 halbtc8723b1ant_action_wifi_multiport(btcoexist);
2896 return;
2897 }
2898
2899 coex_sta->special_pkt_period_cnt = 0;
2900
2901 btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
2902 if (coex_sta->c2h_bt_inquiry_page) {
2903 halbtc8723b1ant_action_bt_inquiry(btcoexist);
2904 return;
2905 } else if (bt_hs_on) {
2906 halbtc8723b1ant_action_hs(btcoexist);
2907 return;
2908 }
2909
2910 if (BTC_PACKET_DHCP == type ||
2911 BTC_PACKET_EAPOL == type) {
2912 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
2913 "[BTCoex], special Packet(%d) notify\n", type);
2914 halbtc8723b1ant_action_wifi_connected_special_packet(btcoexist);
2915 }
2916}
2917
2918void ex_halbtc8723b1ant_bt_info_notify(struct btc_coexist *btcoexist,
2919 u8 *tmp_buf, u8 length)
2920{
2921 u8 bt_info = 0;
2922 u8 i, rsp_source = 0;
2923 bool wifi_connected = false;
2924 bool bt_busy = false;
2925
2926 coex_sta->c2h_bt_info_req_sent = false;
2927
2928 rsp_source = tmp_buf[0] & 0xf;
2929 if (rsp_source >= BT_INFO_SRC_8723B_1ANT_MAX)
2930 rsp_source = BT_INFO_SRC_8723B_1ANT_WIFI_FW;
2931 coex_sta->bt_info_c2h_cnt[rsp_source]++;
2932
2933 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
2934 "[BTCoex], Bt info[%d], length=%d, hex data = [",
2935 rsp_source, length);
2936 for (i = 0; i < length; i++) {
2937 coex_sta->bt_info_c2h[rsp_source][i] = tmp_buf[i];
2938 if (i == 1)
2939 bt_info = tmp_buf[i];
2940 if (i == length - 1)
2941 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
2942 "0x%02x]\n", tmp_buf[i]);
2943 else
2944 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
2945 "0x%02x, ", tmp_buf[i]);
2946 }
2947
2948 if (BT_INFO_SRC_8723B_1ANT_WIFI_FW != rsp_source) {
2949 coex_sta->bt_retry_cnt = /* [3:0] */
2950 coex_sta->bt_info_c2h[rsp_source][2] & 0xf;
2951
2952 coex_sta->bt_rssi =
2953 coex_sta->bt_info_c2h[rsp_source][3] * 2 + 10;
2954
2955 coex_sta->bt_info_ext =
2956 coex_sta->bt_info_c2h[rsp_source][4];
2957
2958 /* Here we need to resend some wifi info to BT
2959 * because bt is reset and loss of the info.
2960 */
2961 if (coex_sta->bt_info_ext & BIT1) {
2962 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2963 "[BTCoex], BT ext info bit1 check, send wifi BW&Chnl to BT!!\n");
2964 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
2965 &wifi_connected);
2966 if (wifi_connected)
2967 ex_halbtc8723b1ant_media_status_notify(btcoexist,
2968 BTC_MEDIA_CONNECT);
2969 else
2970 ex_halbtc8723b1ant_media_status_notify(btcoexist,
2971 BTC_MEDIA_DISCONNECT);
2972 }
2973
2974 if (coex_sta->bt_info_ext & BIT3) {
2975 if (!btcoexist->manual_control &&
2976 !btcoexist->stop_coex_dm) {
2977 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2978 "[BTCoex], BT ext info bit3 check, set BT NOT ignore Wlan active!!\n");
2979 halbtc8723b1ant_ignore_wlan_act(btcoexist,
2980 FORCE_EXEC,
2981 false);
2982 }
2983 } else {
2984 /* BT already NOT ignore Wlan active, do nothing here.*/
2985 }
2986#if (BT_AUTO_REPORT_ONLY_8723B_1ANT == 0)
2987 if (coex_sta->bt_info_ext & BIT4) {
2988 /* BT auto report already enabled, do nothing */
2989 } else {
2990 halbtc8723b1ant_bt_auto_report(btcoexist, FORCE_EXEC,
2991 true);
2992 }
2993#endif
2994 }
2995
2996 /* check BIT2 first ==> check if bt is under inquiry or page scan */
2997 if (bt_info & BT_INFO_8723B_1ANT_B_INQ_PAGE)
2998 coex_sta->c2h_bt_inquiry_page = true;
2999 else
3000 coex_sta->c2h_bt_inquiry_page = false;
3001
3002 /* set link exist status */
3003 if (!(bt_info & BT_INFO_8723B_1ANT_B_CONNECTION)) {
3004 coex_sta->bt_link_exist = false;
3005 coex_sta->pan_exist = false;
3006 coex_sta->a2dp_exist = false;
3007 coex_sta->hid_exist = false;
3008 coex_sta->sco_exist = false;
3009 } else { /* connection exists */
3010 coex_sta->bt_link_exist = true;
3011 if (bt_info & BT_INFO_8723B_1ANT_B_FTP)
3012 coex_sta->pan_exist = true;
3013 else
3014 coex_sta->pan_exist = false;
3015 if (bt_info & BT_INFO_8723B_1ANT_B_A2DP)
3016 coex_sta->a2dp_exist = true;
3017 else
3018 coex_sta->a2dp_exist = false;
3019 if (bt_info & BT_INFO_8723B_1ANT_B_HID)
3020 coex_sta->hid_exist = true;
3021 else
3022 coex_sta->hid_exist = false;
3023 if (bt_info & BT_INFO_8723B_1ANT_B_SCO_ESCO)
3024 coex_sta->sco_exist = true;
3025 else
3026 coex_sta->sco_exist = false;
3027 }
3028
3029 halbtc8723b1ant_update_bt_link_info(btcoexist);
3030
3031 if (!(bt_info&BT_INFO_8723B_1ANT_B_CONNECTION)) {
3032 coex_dm->bt_status = BT_8723B_1ANT_BT_STATUS_NON_CONNECTED_IDLE;
3033 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3034 "[BTCoex], BtInfoNotify(), BT Non-Connected idle!\n");
3035 /* connection exists but no busy */
3036 } else if (bt_info == BT_INFO_8723B_1ANT_B_CONNECTION) {
3037 coex_dm->bt_status = BT_8723B_1ANT_BT_STATUS_CONNECTED_IDLE;
3038 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3039 "[BTCoex], BtInfoNotify(), BT Connected-idle!!!\n");
3040 } else if ((bt_info & BT_INFO_8723B_1ANT_B_SCO_ESCO) ||
3041 (bt_info & BT_INFO_8723B_1ANT_B_SCO_BUSY)) {
3042 coex_dm->bt_status = BT_8723B_1ANT_BT_STATUS_SCO_BUSY;
3043 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3044 "[BTCoex], BtInfoNotify(), BT SCO busy!!!\n");
3045 } else if (bt_info & BT_INFO_8723B_1ANT_B_ACL_BUSY) {
3046 if (BT_8723B_1ANT_BT_STATUS_ACL_BUSY != coex_dm->bt_status)
3047 coex_dm->auto_tdma_adjust = false;
3048
3049 coex_dm->bt_status = BT_8723B_1ANT_BT_STATUS_ACL_BUSY;
3050 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3051 "[BTCoex], BtInfoNotify(), BT ACL busy!!!\n");
3052 } else {
3053 coex_dm->bt_status =
3054 BT_8723B_1ANT_BT_STATUS_MAX;
3055 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3056 "[BTCoex], BtInfoNotify(), BT Non-Defined state!!\n");
3057 }
3058
3059 if ((BT_8723B_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) ||
3060 (BT_8723B_1ANT_BT_STATUS_SCO_BUSY == coex_dm->bt_status) ||
3061 (BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY == coex_dm->bt_status))
3062 bt_busy = true;
3063 else
3064 bt_busy = false;
3065 btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bt_busy);
3066
3067 halbtc8723b1ant_run_coexist_mechanism(btcoexist);
3068}
3069
3070void ex_halbtc8723b1ant_halt_notify(struct btc_coexist *btcoexist)
3071{
3072 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, "[BTCoex], Halt notify\n");
3073
3074 btcoexist->stop_coex_dm = true;
3075
3076 halbtc8723b1ant_SetAntPath(btcoexist, BTC_ANT_PATH_BT, false, true);
3077
3078 halbtc8723b1ant_wifi_off_hw_cfg(btcoexist);
3079 halbtc8723b1ant_ignore_wlan_act(btcoexist, FORCE_EXEC, true);
3080
3081 halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE,
3082 0x0, 0x0);
3083 halbtc8723b1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 0);
3084
3085 ex_halbtc8723b1ant_media_status_notify(btcoexist, BTC_MEDIA_DISCONNECT);
3086}
3087
3088void ex_halbtc8723b1ant_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state)
3089{
3090 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, "[BTCoex], Pnp notify\n");
3091
3092 if (BTC_WIFI_PNP_SLEEP == pnp_state) {
3093 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3094 "[BTCoex], Pnp notify to SLEEP\n");
3095 btcoexist->stop_coex_dm = true;
3096 halbtc8723b1ant_SetAntPath(btcoexist, BTC_ANT_PATH_BT, false,
3097 true);
3098 halbtc8723b1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE,
3099 0x0, 0x0);
3100 halbtc8723b1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0);
3101 halbtc8723b1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2);
3102 halbtc8723b1ant_wifi_off_hw_cfg(btcoexist);
3103 } else if (BTC_WIFI_PNP_WAKE_UP == pnp_state) {
3104 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3105 "[BTCoex], Pnp notify to WAKE UP\n");
3106 btcoexist->stop_coex_dm = false;
3107 halbtc8723b1ant_init_hw_config(btcoexist, false);
3108 halbtc8723b1ant_init_coex_dm(btcoexist);
3109 halbtc8723b1ant_query_bt_info(btcoexist);
3110 }
3111}
3112
3113void ex_halbtc8723b1ant_coex_dm_reset(struct btc_coexist *btcoexist)
3114{
3115 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3116 "[BTCoex], *****************Coex DM Reset****************\n");
3117
3118 halbtc8723b1ant_init_hw_config(btcoexist, false);
3119 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0);
3120 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x2, 0xfffff, 0x0);
3121 halbtc8723b1ant_init_coex_dm(btcoexist);
3122}
3123
3124void ex_halbtc8723b1ant_periodical(struct btc_coexist *btcoexist)
3125{
3126 struct btc_board_info *board_info = &btcoexist->board_info;
3127 struct btc_stack_info *stack_info = &btcoexist->stack_info;
3128 static u8 dis_ver_info_cnt;
3129 u32 fw_ver = 0, bt_patch_ver = 0;
3130
3131 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3132 "[BTCoex], ==========================Periodical===========================\n");
3133
3134 if (dis_ver_info_cnt <= 5) {
3135 dis_ver_info_cnt += 1;
3136 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
3137 "[BTCoex], ****************************************************************\n");
3138 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
3139 "[BTCoex], Ant PG Num/ Ant Mech/ Ant Pos = %d/ %d/ %d\n",
3140 board_info->pg_ant_num, board_info->btdm_ant_num,
3141 board_info->btdm_ant_pos);
3142 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
3143 "[BTCoex], BT stack/ hci ext ver = %s / %d\n",
3144 ((stack_info->profile_notified) ? "Yes" : "No"),
3145 stack_info->hci_version);
3146 btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER,
3147 &bt_patch_ver);
3148 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver);
3149 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
3150 "[BTCoex], CoexVer/ FwVer/ PatchVer = %d_%x/ 0x%x/ 0x%x(%d)\n",
3151 glcoex_ver_date_8723b_1ant,
3152 glcoex_ver_8723b_1ant, fw_ver,
3153 bt_patch_ver, bt_patch_ver);
3154 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
3155 "[BTCoex], ****************************************************************\n");
3156 }
3157
3158#if (BT_AUTO_REPORT_ONLY_8723B_1ANT == 0)
3159 halbtc8723b1ant_query_bt_info(btcoexist);
3160 halbtc8723b1ant_monitor_bt_ctr(btcoexist);
3161 halbtc8723b1ant_monitor_bt_enable_disable(btcoexist);
3162#else
3163 if (btc8723b1ant_is_wifi_status_changed(btcoexist) ||
3164 coex_dm->auto_tdma_adjust) {
3165 halbtc8723b1ant_run_coexist_mechanism(btcoexist);
3166 }
3167
3168 coex_sta->special_pkt_period_cnt++;
3169#endif
3170}
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b1ant.h b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b1ant.h
new file mode 100644
index 000000000000..75f8094b7a34
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b1ant.h
@@ -0,0 +1,184 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2012 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25/**********************************************************************
26 * The following is for 8723B 1ANT BT Co-exist definition
27 **********************************************************************/
28#define BT_AUTO_REPORT_ONLY_8723B_1ANT 1
29
30#define BT_INFO_8723B_1ANT_B_FTP BIT7
31#define BT_INFO_8723B_1ANT_B_A2DP BIT6
32#define BT_INFO_8723B_1ANT_B_HID BIT5
33#define BT_INFO_8723B_1ANT_B_SCO_BUSY BIT4
34#define BT_INFO_8723B_1ANT_B_ACL_BUSY BIT3
35#define BT_INFO_8723B_1ANT_B_INQ_PAGE BIT2
36#define BT_INFO_8723B_1ANT_B_SCO_ESCO BIT1
37#define BT_INFO_8723B_1ANT_B_CONNECTION BIT0
38
39#define BT_INFO_8723B_1ANT_A2DP_BASIC_RATE(_BT_INFO_EXT_) \
40 (((_BT_INFO_EXT_&BIT0)) ? true : false)
41
42#define BTC_RSSI_COEX_THRESH_TOL_8723B_1ANT 2
43
44enum _BT_INFO_SRC_8723B_1ANT {
45 BT_INFO_SRC_8723B_1ANT_WIFI_FW = 0x0,
46 BT_INFO_SRC_8723B_1ANT_BT_RSP = 0x1,
47 BT_INFO_SRC_8723B_1ANT_BT_ACTIVE_SEND = 0x2,
48 BT_INFO_SRC_8723B_1ANT_MAX
49};
50
51enum _BT_8723B_1ANT_BT_STATUS {
52 BT_8723B_1ANT_BT_STATUS_NON_CONNECTED_IDLE = 0x0,
53 BT_8723B_1ANT_BT_STATUS_CONNECTED_IDLE = 0x1,
54 BT_8723B_1ANT_BT_STATUS_INQ_PAGE = 0x2,
55 BT_8723B_1ANT_BT_STATUS_ACL_BUSY = 0x3,
56 BT_8723B_1ANT_BT_STATUS_SCO_BUSY = 0x4,
57 BT_8723B_1ANT_BT_STATUS_ACL_SCO_BUSY = 0x5,
58 BT_8723B_1ANT_BT_STATUS_MAX
59};
60
61enum _BT_8723B_1ANT_WIFI_STATUS {
62 BT_8723B_1ANT_WIFI_STATUS_NON_CONNECTED_IDLE = 0x0,
63 BT_8723B_1ANT_WIFI_STATUS_NON_CONNECTED_ASSO_AUTH_SCAN = 0x1,
64 BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SCAN = 0x2,
65 BT_8723B_1ANT_WIFI_STATUS_CONNECTED_SPECIAL_PKT = 0x3,
66 BT_8723B_1ANT_WIFI_STATUS_CONNECTED_IDLE = 0x4,
67 BT_8723B_1ANT_WIFI_STATUS_CONNECTED_BUSY = 0x5,
68 BT_8723B_1ANT_WIFI_STATUS_MAX
69};
70
71enum _BT_8723B_1ANT_COEX_ALGO {
72 BT_8723B_1ANT_COEX_ALGO_UNDEFINED = 0x0,
73 BT_8723B_1ANT_COEX_ALGO_SCO = 0x1,
74 BT_8723B_1ANT_COEX_ALGO_HID = 0x2,
75 BT_8723B_1ANT_COEX_ALGO_A2DP = 0x3,
76 BT_8723B_1ANT_COEX_ALGO_A2DP_PANHS = 0x4,
77 BT_8723B_1ANT_COEX_ALGO_PANEDR = 0x5,
78 BT_8723B_1ANT_COEX_ALGO_PANHS = 0x6,
79 BT_8723B_1ANT_COEX_ALGO_PANEDR_A2DP = 0x7,
80 BT_8723B_1ANT_COEX_ALGO_PANEDR_HID = 0x8,
81 BT_8723B_1ANT_COEX_ALGO_HID_A2DP_PANEDR = 0x9,
82 BT_8723B_1ANT_COEX_ALGO_HID_A2DP = 0xa,
83 BT_8723B_1ANT_COEX_ALGO_MAX = 0xb,
84};
85
86struct coex_dm_8723b_1ant {
87 /* fw mechanism */
88 bool cur_ignore_wlan_act;
89 bool pre_ignore_wlan_act;
90 u8 pre_ps_tdma;
91 u8 cur_ps_tdma;
92 u8 ps_tdma_para[5];
93 u8 tdma_adj_type;
94 bool auto_tdma_adjust;
95 bool pre_ps_tdma_on;
96 bool cur_ps_tdma_on;
97 bool pre_bt_auto_report;
98 bool cur_bt_auto_report;
99 u8 pre_lps;
100 u8 cur_lps;
101 u8 pre_rpwm;
102 u8 cur_rpwm;
103
104 /* sw mechanism */
105 bool pre_low_penalty_ra;
106 bool cur_low_penalty_ra;
107 u32 pre_val0x6c0;
108 u32 cur_val0x6c0;
109 u32 pre_val0x6c4;
110 u32 cur_val0x6c4;
111 u32 pre_val0x6c8;
112 u32 cur_val0x6c8;
113 u8 pre_val0x6cc;
114 u8 cur_val0x6cc;
115 bool limited_dig;
116
117 u32 backup_arfr_cnt1; /* Auto Rate Fallback Retry cnt */
118 u32 backup_arfr_cnt2; /* Auto Rate Fallback Retry cnt */
119 u16 backup_retry_limit;
120 u8 backup_ampdu_max_time;
121
122 /* algorithm related */
123 u8 pre_algorithm;
124 u8 cur_algorithm;
125 u8 bt_status;
126 u8 wifi_chnl_info[3];
127
128 u32 prera_mask;
129 u32 curra_mask;
130 u8 pre_arfr_type;
131 u8 cur_arfr_type;
132 u8 pre_retry_limit_type;
133 u8 cur_retry_limit_type;
134 u8 pre_ampdu_time_type;
135 u8 cur_ampdu_time_type;
136
137 u8 error_condition;
138};
139
140struct coex_sta_8723b_1ant {
141 bool bt_link_exist;
142 bool sco_exist;
143 bool a2dp_exist;
144 bool hid_exist;
145 bool pan_exist;
146
147 bool under_lps;
148 bool under_ips;
149 u32 special_pkt_period_cnt;
150 u32 high_priority_tx;
151 u32 high_priority_rx;
152 u32 low_priority_tx;
153 u32 low_priority_rx;
154 u8 bt_rssi;
155 u8 pre_bt_rssi_state;
156 u8 pre_wifi_rssi_state[4];
157 bool c2h_bt_info_req_sent;
158 u8 bt_info_c2h[BT_INFO_SRC_8723B_1ANT_MAX][10];
159 u32 bt_info_c2h_cnt[BT_INFO_SRC_8723B_1ANT_MAX];
160 bool c2h_bt_inquiry_page;
161 u8 bt_retry_cnt;
162 u8 bt_info_ext;
163};
164
165/*************************************************************************
166 * The following is interface which will notify coex module.
167 *************************************************************************/
168void ex_halbtc8723b1ant_init_hwconfig(struct btc_coexist *btcoexist);
169void ex_halbtc8723b1ant_init_coex_dm(struct btc_coexist *btcoexist);
170void ex_halbtc8723b1ant_ips_notify(struct btc_coexist *btcoexist, u8 type);
171void ex_halbtc8723b1ant_lps_notify(struct btc_coexist *btcoexist, u8 type);
172void ex_halbtc8723b1ant_scan_notify(struct btc_coexist *btcoexist, u8 type);
173void ex_halbtc8723b1ant_connect_notify(struct btc_coexist *btcoexist, u8 type);
174void ex_halbtc8723b1ant_media_status_notify(struct btc_coexist *btcoexist,
175 u8 type);
176void ex_halbtc8723b1ant_special_packet_notify(struct btc_coexist *btcoexist,
177 u8 type);
178void ex_halbtc8723b1ant_bt_info_notify(struct btc_coexist *btcoexist,
179 u8 *tmpbuf, u8 length);
180void ex_halbtc8723b1ant_halt_notify(struct btc_coexist *btcoexist);
181void ex_halbtc8723b1ant_pnp_notify(struct btc_coexist *btcoexist, u8 pnpstate);
182void ex_halbtc8723b1ant_coex_dm_reset(struct btc_coexist *btcoexist);
183void ex_halbtc8723b1ant_periodical(struct btc_coexist *btcoexist);
184void ex_halbtc8723b1ant_display_coex_info(struct btc_coexist *btcoexist);
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.c b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.c
index d916ab9f3c38..cefe26991421 100644
--- a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.c
+++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.c
@@ -49,8 +49,8 @@ static const char *const glbt_info_src_8723b_2ant[] = {
49 "BT Info[bt auto report]", 49 "BT Info[bt auto report]",
50}; 50};
51 51
52static u32 glcoex_ver_date_8723b_2ant = 20130731; 52static u32 glcoex_ver_date_8723b_2ant = 20131113;
53static u32 glcoex_ver_8723b_2ant = 0x3b; 53static u32 glcoex_ver_8723b_2ant = 0x3f;
54 54
55/************************************************************** 55/**************************************************************
56 * local function proto type if needed 56 * local function proto type if needed
@@ -303,6 +303,21 @@ static void btc8723b2ant_monitor_bt_ctr(struct btc_coexist *btcoexist)
303 btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc); 303 btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc);
304} 304}
305 305
306static void btc8723b2ant_query_bt_info(struct btc_coexist *btcoexist)
307{
308 u8 h2c_parameter[1] = {0};
309
310 coex_sta->c2h_bt_info_req_sent = true;
311
312 h2c_parameter[0] |= BIT0; /* trigger */
313
314 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
315 "[BTCoex], Query Bt Info, FW write 0x61 = 0x%x\n",
316 h2c_parameter[0]);
317
318 btcoexist->btc_fill_h2c(btcoexist, 0x61, 1, h2c_parameter);
319}
320
306static bool btc8723b2ant_is_wifi_status_changed(struct btc_coexist *btcoexist) 321static bool btc8723b2ant_is_wifi_status_changed(struct btc_coexist *btcoexist)
307{ 322{
308 static bool pre_wifi_busy; 323 static bool pre_wifi_busy;
@@ -604,7 +619,7 @@ static bool btc8723b_need_dec_pwr(struct btc_coexist *btcoexist)
604 if (!btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi)) 619 if (!btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi))
605 return false; 620 return false;
606 621
607 bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 35, 0); 622 bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 29, 0);
608 623
609 if (wifi_connected) { 624 if (wifi_connected) {
610 if (bt_hs_on) { 625 if (bt_hs_on) {
@@ -824,7 +839,6 @@ static void btc8723b2ant_set_sw_fulltime_dac_swing(struct btc_coexist *btcoex,
824 btc8723b2ant_set_dac_swing_reg(btcoex, 0x18); 839 btc8723b2ant_set_dac_swing_reg(btcoex, 0x18);
825} 840}
826 841
827
828static void btc8723b2ant_dac_swing(struct btc_coexist *btcoexist, 842static void btc8723b2ant_dac_swing(struct btc_coexist *btcoexist,
829 bool force_exec, bool dac_swing_on, 843 bool force_exec, bool dac_swing_on,
830 u32 dac_swing_lvl) 844 u32 dac_swing_lvl)
@@ -884,7 +898,6 @@ static void btc8723b2ant_set_agc_table(struct btc_coexist *btcoexist,
884 btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa4200001); 898 btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa4200001);
885 } 899 }
886 900
887
888 /* RF Gain */ 901 /* RF Gain */
889 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0xef, 0xfffff, 0x02000); 902 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0xef, 0xfffff, 0x02000);
890 if (agc_table_en) { 903 if (agc_table_en) {
@@ -1160,8 +1173,87 @@ static void btc8723b2ant_sw_mechanism2(struct btc_coexist *btcoexist,
1160 dac_swing_lvl); 1173 dac_swing_lvl);
1161} 1174}
1162 1175
1176static void btc8723b2ant_set_ant_path(struct btc_coexist *btcoexist,
1177 u8 antpos_type, bool init_hwcfg,
1178 bool wifi_off)
1179{
1180 struct btc_board_info *board_info = &btcoexist->board_info;
1181 u32 fw_ver = 0, u32tmp = 0;
1182 bool pg_ext_switch = false;
1183 bool use_ext_switch = false;
1184 u8 h2c_parameter[2] = {0};
1185
1186 btcoexist->btc_get(btcoexist, BTC_GET_BL_EXT_SWITCH, &pg_ext_switch);
1187 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver);
1188
1189 if ((fw_ver < 0xc0000) || pg_ext_switch)
1190 use_ext_switch = true;
1191
1192 if (init_hwcfg) {
1193 /* 0x4c[23] = 0, 0x4c[24] = 1 Antenna control by WL/BT */
1194 u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x4c);
1195 u32tmp &= ~BIT23;
1196 u32tmp |= BIT24;
1197 btcoexist->btc_write_4byte(btcoexist, 0x4c, u32tmp);
1198
1199 btcoexist->btc_write_1byte(btcoexist, 0x974, 0xff);
1200 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x944, 0x3, 0x3);
1201 btcoexist->btc_write_1byte(btcoexist, 0x930, 0x77);
1202 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x67, 0x20, 0x1);
1203
1204 /* Force GNT_BT to low */
1205 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x765, 0x18, 0x0);
1206 btcoexist->btc_write_2byte(btcoexist, 0x948, 0x0);
1207
1208 if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT) {
1209 /* tell firmware "no antenna inverse" */
1210 h2c_parameter[0] = 0;
1211 h2c_parameter[1] = 1; /* ext switch type */
1212 btcoexist->btc_fill_h2c(btcoexist, 0x65, 2,
1213 h2c_parameter);
1214 } else {
1215 /* tell firmware "antenna inverse" */
1216 h2c_parameter[0] = 1;
1217 h2c_parameter[1] = 1; /* ext switch type */
1218 btcoexist->btc_fill_h2c(btcoexist, 0x65, 2,
1219 h2c_parameter);
1220 }
1221 }
1222
1223 /* ext switch setting */
1224 if (use_ext_switch) {
1225 /* fixed internal switch S1->WiFi, S0->BT */
1226 btcoexist->btc_write_2byte(btcoexist, 0x948, 0x0);
1227 switch (antpos_type) {
1228 case BTC_ANT_WIFI_AT_MAIN:
1229 /* ext switch main at wifi */
1230 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x92c,
1231 0x3, 0x1);
1232 break;
1233 case BTC_ANT_WIFI_AT_AUX:
1234 /* ext switch aux at wifi */
1235 btcoexist->btc_write_1byte_bitmask(btcoexist,
1236 0x92c, 0x3, 0x2);
1237 break;
1238 }
1239 } else { /* internal switch */
1240 /* fixed ext switch */
1241 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x92c, 0x3, 0x1);
1242 switch (antpos_type) {
1243 case BTC_ANT_WIFI_AT_MAIN:
1244 /* fixed internal switch S1->WiFi, S0->BT */
1245 btcoexist->btc_write_2byte(btcoexist, 0x948, 0x0);
1246 break;
1247 case BTC_ANT_WIFI_AT_AUX:
1248 /* fixed internal switch S0->WiFi, S1->BT */
1249 btcoexist->btc_write_2byte(btcoexist, 0x948, 0x280);
1250 break;
1251 }
1252 }
1253}
1254
1163static void btc8723b2ant_ps_tdma(struct btc_coexist *btcoexist, bool force_exec, 1255static void btc8723b2ant_ps_tdma(struct btc_coexist *btcoexist, bool force_exec,
1164 bool turn_on, u8 type) 1256 bool turn_on, u8 type)
1165{ 1257{
1166 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, 1258 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW,
1167 "[BTCoex], %s turn %s PS TDMA, type=%d\n", 1259 "[BTCoex], %s turn %s PS TDMA, type=%d\n",
@@ -1351,7 +1443,8 @@ static void btc8723b2ant_action_bt_inquiry(struct btc_coexist *btcoexist)
1351 coex_dm->need_recover_0x948 = true; 1443 coex_dm->need_recover_0x948 = true;
1352 coex_dm->backup_0x948 = btcoexist->btc_read_2byte(btcoexist, 0x948); 1444 coex_dm->backup_0x948 = btcoexist->btc_read_2byte(btcoexist, 0x948);
1353 1445
1354 btcoexist->btc_write_2byte(btcoexist, 0x948, 0x280); 1446 btc8723b2ant_set_ant_path(btcoexist, BTC_ANT_WIFI_AT_AUX,
1447 false, false);
1355} 1448}
1356 1449
1357static bool btc8723b2ant_is_common_action(struct btc_coexist *btcoexist) 1450static bool btc8723b2ant_is_common_action(struct btc_coexist *btcoexist)
@@ -1520,7 +1613,9 @@ static void set_tdma_int1(struct btc_coexist *btcoexist, bool tx_pause,
1520 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, 1613 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1521 true, 8); 1614 true, 8);
1522 coex_dm->tdma_adj_type = 8; 1615 coex_dm->tdma_adj_type = 8;
1523 } else if (coex_dm->cur_ps_tdma == 9) { 1616 }
1617
1618 if (coex_dm->cur_ps_tdma == 9) {
1524 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, 1619 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1525 true, 13); 1620 true, 13);
1526 coex_dm->tdma_adj_type = 13; 1621 coex_dm->tdma_adj_type = 13;
@@ -1607,7 +1702,9 @@ static void set_tdma_int1(struct btc_coexist *btcoexist, bool tx_pause,
1607 } else if (coex_dm->cur_ps_tdma == 8) { 1702 } else if (coex_dm->cur_ps_tdma == 8) {
1608 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 4); 1703 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 4);
1609 coex_dm->tdma_adj_type = 4; 1704 coex_dm->tdma_adj_type = 4;
1610 } else if (coex_dm->cur_ps_tdma == 13) { 1705 }
1706
1707 if (coex_dm->cur_ps_tdma == 13) {
1611 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 9); 1708 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 9);
1612 coex_dm->tdma_adj_type = 9; 1709 coex_dm->tdma_adj_type = 9;
1613 } else if (coex_dm->cur_ps_tdma == 14) { 1710 } else if (coex_dm->cur_ps_tdma == 14) {
@@ -1652,23 +1749,34 @@ static void set_tdma_int1(struct btc_coexist *btcoexist, bool tx_pause,
1652 coex_dm->tdma_adj_type = 12; 1749 coex_dm->tdma_adj_type = 12;
1653 } 1750 }
1654 } else if (result == 1) { 1751 } else if (result == 1) {
1655 int tmp = coex_dm->cur_ps_tdma; 1752 if (coex_dm->cur_ps_tdma == 4) {
1656 switch (tmp) { 1753 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1657 case 4: 1754 true, 3);
1658 case 3: 1755 coex_dm->tdma_adj_type = 3;
1659 case 2: 1756 } else if (coex_dm->cur_ps_tdma == 3) {
1660 case 12: 1757 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1661 case 11: 1758 true, 2);
1662 case 10: 1759 coex_dm->tdma_adj_type = 2;
1663 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, 1760 } else if (coex_dm->cur_ps_tdma == 2) {
1664 true, tmp - 1); 1761 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1665 coex_dm->tdma_adj_type = tmp - 1; 1762 true, 1);
1666 break; 1763 coex_dm->tdma_adj_type = 1;
1667 case 1: 1764 } else if (coex_dm->cur_ps_tdma == 1) {
1668 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, 1765 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1669 true, 71); 1766 true, 71);
1670 coex_dm->tdma_adj_type = 71; 1767 coex_dm->tdma_adj_type = 71;
1671 break; 1768 } else if (coex_dm->cur_ps_tdma == 12) {
1769 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1770 true, 11);
1771 coex_dm->tdma_adj_type = 11;
1772 } else if (coex_dm->cur_ps_tdma == 11) {
1773 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1774 true, 10);
1775 coex_dm->tdma_adj_type = 10;
1776 } else if (coex_dm->cur_ps_tdma == 10) {
1777 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1778 true, 9);
1779 coex_dm->tdma_adj_type = 9;
1672 } 1780 }
1673 } 1781 }
1674 } 1782 }
@@ -1694,7 +1802,8 @@ static void set_tdma_int2(struct btc_coexist *btcoexist, bool tx_pause,
1694 } else if (coex_dm->cur_ps_tdma == 4) { 1802 } else if (coex_dm->cur_ps_tdma == 4) {
1695 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 8); 1803 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 8);
1696 coex_dm->tdma_adj_type = 8; 1804 coex_dm->tdma_adj_type = 8;
1697 } else if (coex_dm->cur_ps_tdma == 9) { 1805 }
1806 if (coex_dm->cur_ps_tdma == 9) {
1698 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14); 1807 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14);
1699 coex_dm->tdma_adj_type = 14; 1808 coex_dm->tdma_adj_type = 14;
1700 } else if (coex_dm->cur_ps_tdma == 10) { 1809 } else if (coex_dm->cur_ps_tdma == 10) {
@@ -1776,7 +1885,8 @@ static void set_tdma_int2(struct btc_coexist *btcoexist, bool tx_pause,
1776 } else if (coex_dm->cur_ps_tdma == 8) { 1885 } else if (coex_dm->cur_ps_tdma == 8) {
1777 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 4); 1886 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 4);
1778 coex_dm->tdma_adj_type = 4; 1887 coex_dm->tdma_adj_type = 4;
1779 } else if (coex_dm->cur_ps_tdma == 13) { 1888 }
1889 if (coex_dm->cur_ps_tdma == 13) {
1780 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 10); 1890 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 10);
1781 coex_dm->tdma_adj_type = 10; 1891 coex_dm->tdma_adj_type = 10;
1782 } else if (coex_dm->cur_ps_tdma == 14) { 1892 } else if (coex_dm->cur_ps_tdma == 14) {
@@ -1865,7 +1975,8 @@ static void set_tdma_int3(struct btc_coexist *btcoexist, bool tx_pause,
1865 } else if (coex_dm->cur_ps_tdma == 4) { 1975 } else if (coex_dm->cur_ps_tdma == 4) {
1866 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 8); 1976 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 8);
1867 coex_dm->tdma_adj_type = 8; 1977 coex_dm->tdma_adj_type = 8;
1868 } else if (coex_dm->cur_ps_tdma == 9) { 1978 }
1979 if (coex_dm->cur_ps_tdma == 9) {
1869 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 15); 1980 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 15);
1870 coex_dm->tdma_adj_type = 15; 1981 coex_dm->tdma_adj_type = 15;
1871 } else if (coex_dm->cur_ps_tdma == 10) { 1982 } else if (coex_dm->cur_ps_tdma == 10) {
@@ -1935,101 +2046,80 @@ static void set_tdma_int3(struct btc_coexist *btcoexist, bool tx_pause,
1935 BTC_PRINT(BTC_MSG_ALGORITHM, 2046 BTC_PRINT(BTC_MSG_ALGORITHM,
1936 ALGO_TRACE_FW_DETAIL, 2047 ALGO_TRACE_FW_DETAIL,
1937 "[BTCoex], TxPause = 0\n"); 2048 "[BTCoex], TxPause = 0\n");
1938 switch (coex_dm->cur_ps_tdma) { 2049 if (coex_dm->cur_ps_tdma == 5) {
1939 case 5:
1940 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3); 2050 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3);
1941 coex_dm->tdma_adj_type = 3; 2051 coex_dm->tdma_adj_type = 3;
1942 break; 2052 } else if (coex_dm->cur_ps_tdma == 6) {
1943 case 6:
1944 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3); 2053 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3);
1945 coex_dm->tdma_adj_type = 3; 2054 coex_dm->tdma_adj_type = 3;
1946 break; 2055 } else if (coex_dm->cur_ps_tdma == 7) {
1947 case 7:
1948 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3); 2056 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3);
1949 coex_dm->tdma_adj_type = 3; 2057 coex_dm->tdma_adj_type = 3;
1950 break; 2058 } else if (coex_dm->cur_ps_tdma == 8) {
1951 case 8:
1952 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 4); 2059 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 4);
1953 coex_dm->tdma_adj_type = 4; 2060 coex_dm->tdma_adj_type = 4;
1954 break; 2061 }
1955 case 13: 2062 if (coex_dm->cur_ps_tdma == 13) {
1956 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 11); 2063 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 11);
1957 coex_dm->tdma_adj_type = 11; 2064 coex_dm->tdma_adj_type = 11;
1958 break; 2065 } else if (coex_dm->cur_ps_tdma == 14) {
1959 case 14:
1960 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 11); 2066 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 11);
1961 coex_dm->tdma_adj_type = 11; 2067 coex_dm->tdma_adj_type = 11;
1962 break; 2068 } else if (coex_dm->cur_ps_tdma == 15) {
1963 case 15:
1964 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 11); 2069 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 11);
1965 coex_dm->tdma_adj_type = 11; 2070 coex_dm->tdma_adj_type = 11;
1966 break; 2071 } else if (coex_dm->cur_ps_tdma == 16) {
1967 case 16:
1968 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 12); 2072 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 12);
1969 coex_dm->tdma_adj_type = 12; 2073 coex_dm->tdma_adj_type = 12;
1970 break;
1971 } 2074 }
1972 if (result == -1) { 2075 if (result == -1) {
1973 switch (coex_dm->cur_ps_tdma) { 2076 if (coex_dm->cur_ps_tdma == 1) {
1974 case 1:
1975 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, 2077 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1976 true, 3); 2078 true, 3);
1977 coex_dm->tdma_adj_type = 3; 2079 coex_dm->tdma_adj_type = 3;
1978 break; 2080 } else if (coex_dm->cur_ps_tdma == 2) {
1979 case 2:
1980 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, 2081 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1981 true, 3); 2082 true, 3);
1982 coex_dm->tdma_adj_type = 3; 2083 coex_dm->tdma_adj_type = 3;
1983 break; 2084 } else if (coex_dm->cur_ps_tdma == 3) {
1984 case 3:
1985 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, 2085 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1986 true, 4); 2086 true, 4);
1987 coex_dm->tdma_adj_type = 4; 2087 coex_dm->tdma_adj_type = 4;
1988 break; 2088 } else if (coex_dm->cur_ps_tdma == 9) {
1989 case 9:
1990 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, 2089 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1991 true, 11); 2090 true, 11);
1992 coex_dm->tdma_adj_type = 11; 2091 coex_dm->tdma_adj_type = 11;
1993 break; 2092 } else if (coex_dm->cur_ps_tdma == 10) {
1994 case 10:
1995 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, 2093 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1996 true, 11); 2094 true, 11);
1997 coex_dm->tdma_adj_type = 11; 2095 coex_dm->tdma_adj_type = 11;
1998 break; 2096 } else if (coex_dm->cur_ps_tdma == 11) {
1999 case 11:
2000 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, 2097 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2001 true, 12); 2098 true, 12);
2002 coex_dm->tdma_adj_type = 12; 2099 coex_dm->tdma_adj_type = 12;
2003 break;
2004 } 2100 }
2005 } else if (result == 1) { 2101 } else if (result == 1) {
2006 switch (coex_dm->cur_ps_tdma) { 2102 if (coex_dm->cur_ps_tdma == 4) {
2007 case 4:
2008 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, 2103 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2009 true, 3); 2104 true, 3);
2010 coex_dm->tdma_adj_type = 3; 2105 coex_dm->tdma_adj_type = 3;
2011 break; 2106 } else if (coex_dm->cur_ps_tdma == 3) {
2012 case 3:
2013 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, 2107 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2014 true, 3); 2108 true, 3);
2015 coex_dm->tdma_adj_type = 3; 2109 coex_dm->tdma_adj_type = 3;
2016 break; 2110 } else if (coex_dm->cur_ps_tdma == 2) {
2017 case 2:
2018 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, 2111 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2019 true, 3); 2112 true, 3);
2020 coex_dm->tdma_adj_type = 3; 2113 coex_dm->tdma_adj_type = 3;
2021 break; 2114 } else if (coex_dm->cur_ps_tdma == 12) {
2022 case 12:
2023 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, 2115 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2024 true, 11); 2116 true, 11);
2025 coex_dm->tdma_adj_type = 11; 2117 coex_dm->tdma_adj_type = 11;
2026 break; 2118 } else if (coex_dm->cur_ps_tdma == 11) {
2027 case 11:
2028 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, 2119 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2029 true, 11); 2120 true, 11);
2030 coex_dm->tdma_adj_type = 11; 2121 coex_dm->tdma_adj_type = 11;
2031 break; 2122 } else if (coex_dm->cur_ps_tdma == 10) {
2032 case 10:
2033 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, 2123 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2034 true, 11); 2124 true, 11);
2035 coex_dm->tdma_adj_type = 11; 2125 coex_dm->tdma_adj_type = 11;
@@ -2328,7 +2418,7 @@ static void btc8723b2ant_action_hid(struct btc_coexist *btcoexist)
2328 2418
2329 wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist, 2419 wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist,
2330 0, 2, 15, 0); 2420 0, 2, 15, 0);
2331 bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 35, 0); 2421 bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 29, 0);
2332 2422
2333 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); 2423 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0);
2334 2424
@@ -2385,12 +2475,43 @@ static void btc8723b2ant_action_hid(struct btc_coexist *btcoexist)
2385/*A2DP only / PAN(EDR) only/ A2DP+PAN(HS)*/ 2475/*A2DP only / PAN(EDR) only/ A2DP+PAN(HS)*/
2386static void btc8723b2ant_action_a2dp(struct btc_coexist *btcoexist) 2476static void btc8723b2ant_action_a2dp(struct btc_coexist *btcoexist)
2387{ 2477{
2388 u8 wifi_rssi_state, bt_rssi_state; 2478 u8 wifi_rssi_state, wifi_rssi_state1, bt_rssi_state;
2389 u32 wifi_bw; 2479 u32 wifi_bw;
2480 u8 ap_num = 0;
2390 2481
2391 wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist, 2482 wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist,
2392 0, 2, 15, 0); 2483 0, 2, 15, 0);
2393 bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 35, 0); 2484 wifi_rssi_state1 = btc8723b2ant_wifi_rssi_state(btcoexist,
2485 1, 2, 40, 0);
2486 bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 29, 0);
2487
2488 btcoexist->btc_get(btcoexist, BTC_GET_U1_AP_NUM, &ap_num);
2489
2490 /* define the office environment */
2491 /* driver don't know AP num in Linux, so we will never enter this if */
2492 if (ap_num >= 10 && BTC_RSSI_HIGH(wifi_rssi_state1)) {
2493 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff,
2494 0x0);
2495 btc8723b2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
2496 btc8723b2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
2497 btc8723b_coex_tbl_type(btcoexist, NORMAL_EXEC, 0);
2498 btc8723b2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1);
2499
2500 /* sw mechanism */
2501 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
2502 if (BTC_WIFI_BW_HT40 == wifi_bw) {
2503 btc8723b2ant_sw_mechanism1(btcoexist, true, false,
2504 false, false);
2505 btc8723b2ant_sw_mechanism2(btcoexist, true, false,
2506 true, 0x18);
2507 } else {
2508 btc8723b2ant_sw_mechanism1(btcoexist, false, false,
2509 false, false);
2510 btc8723b2ant_sw_mechanism2(btcoexist, true, false,
2511 true, 0x18);
2512 }
2513 return;
2514 }
2394 2515
2395 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); 2516 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0);
2396 2517
@@ -2501,7 +2622,7 @@ static void btc8723b2ant_action_pan_edr(struct btc_coexist *btcoexist)
2501 2622
2502 wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist, 2623 wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist,
2503 0, 2, 15, 0); 2624 0, 2, 15, 0);
2504 bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 35, 0); 2625 bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 29, 0);
2505 2626
2506 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); 2627 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0);
2507 2628
@@ -2612,7 +2733,7 @@ static void btc8723b2ant_action_pan_edr_a2dp(struct btc_coexist *btcoexist)
2612 2733
2613 wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist, 2734 wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist,
2614 0, 2, 15, 0); 2735 0, 2, 15, 0);
2615 bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 35, 0); 2736 bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 29, 0);
2616 2737
2617 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); 2738 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0);
2618 2739
@@ -2676,7 +2797,7 @@ static void btc8723b2ant_action_pan_edr_hid(struct btc_coexist *btcoexist)
2676 2797
2677 wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist, 2798 wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist,
2678 0, 2, 15, 0); 2799 0, 2, 15, 0);
2679 bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 35, 0); 2800 bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 29, 0);
2680 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); 2801 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
2681 2802
2682 if (btc8723b_need_dec_pwr(btcoexist)) 2803 if (btc8723b_need_dec_pwr(btcoexist))
@@ -2746,7 +2867,7 @@ static void btc8723b2ant_action_hid_a2dp_pan_edr(struct btc_coexist *btcoexist)
2746 2867
2747 wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist, 2868 wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist,
2748 0, 2, 15, 0); 2869 0, 2, 15, 0);
2749 bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 35, 0); 2870 bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 29, 0);
2750 2871
2751 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); 2872 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0);
2752 2873
@@ -2809,8 +2930,8 @@ static void btc8723b2ant_action_hid_a2dp(struct btc_coexist *btcoexist)
2809 u32 wifi_bw; 2930 u32 wifi_bw;
2810 2931
2811 wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist, 2932 wifi_rssi_state = btc8723b2ant_wifi_rssi_state(btcoexist,
2812 0, 2, 15, 0); 2933 0, 2, 15, 0);
2813 bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 35, 0); 2934 bt_rssi_state = btc8723b2ant_bt_rssi_state(2, 29, 0);
2814 2935
2815 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0); 2936 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1, 0xfffff, 0x0);
2816 2937
@@ -2982,7 +3103,15 @@ static void btc8723b2ant_run_coexist_mechanism(struct btc_coexist *btcoexist)
2982 } 3103 }
2983} 3104}
2984 3105
2985 3106static void btc8723b2ant_wifioff_hwcfg(struct btc_coexist *btcoexist)
3107{
3108 /* set wlan_act to low */
3109 btcoexist->btc_write_1byte(btcoexist, 0x76e, 0x4);
3110 /* Force GNT_BT to High */
3111 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x765, 0x18, 0x3);
3112 /* BT select s0/s1 is controlled by BT */
3113 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x67, 0x20, 0x0);
3114}
2986 3115
2987/********************************************************************* 3116/*********************************************************************
2988 * work around function start with wa_btc8723b2ant_ 3117 * work around function start with wa_btc8723b2ant_
@@ -2990,98 +3119,24 @@ static void btc8723b2ant_run_coexist_mechanism(struct btc_coexist *btcoexist)
2990/********************************************************************* 3119/*********************************************************************
2991 * extern function start with EXbtc8723b2ant_ 3120 * extern function start with EXbtc8723b2ant_
2992 *********************************************************************/ 3121 *********************************************************************/
2993void ex_halbtc8723b2ant_init_hwconfig(struct btc_coexist *btcoexist) 3122void ex_btc8723b2ant_init_hwconfig(struct btc_coexist *btcoexist)
2994{ 3123{
2995 struct btc_board_info *board_info = &btcoexist->board_info;
2996 u32 u32tmp = 0, fw_ver;
2997 u8 u8tmp = 0; 3124 u8 u8tmp = 0;
2998 u8 h2c_parameter[2] = {0};
2999
3000 3125
3001 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, 3126 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
3002 "[BTCoex], 2Ant Init HW Config!!\n"); 3127 "[BTCoex], 2Ant Init HW Config!!\n");
3128 coex_dm->bt_rf0x1e_backup =
3129 btcoexist->btc_get_rf_reg(btcoexist, BTC_RF_A, 0x1e, 0xfffff);
3003 3130
3004 /* backup rf 0x1e value */ 3131 /* 0x790[5:0] = 0x5 */
3005 coex_dm->bt_rf0x1e_backup = btcoexist->btc_get_rf_reg(btcoexist,
3006 BTC_RF_A, 0x1e,
3007 0xfffff);
3008
3009 /* 0x4c[23]=0, 0x4c[24]=1 Antenna control by WL/BT */
3010 u32tmp = btcoexist->btc_read_4byte(btcoexist, 0x4c);
3011 u32tmp &= ~BIT23;
3012 u32tmp |= BIT24;
3013 btcoexist->btc_write_4byte(btcoexist, 0x4c, u32tmp);
3014
3015 btcoexist->btc_write_1byte(btcoexist, 0x974, 0xff);
3016 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x944, 0x3, 0x3);
3017 btcoexist->btc_write_1byte(btcoexist, 0x930, 0x77);
3018 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x67, 0x20, 0x1);
3019
3020 /* Antenna switch control parameter */
3021 /* btcoexist->btc_write_4byte(btcoexist, 0x858, 0x55555555);*/
3022
3023 /*Force GNT_BT to low*/
3024 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x765, 0x18, 0x0);
3025 btcoexist->btc_write_2byte(btcoexist, 0x948, 0x0);
3026
3027 /* 0x790[5:0]=0x5 */
3028 u8tmp = btcoexist->btc_read_1byte(btcoexist, 0x790); 3132 u8tmp = btcoexist->btc_read_1byte(btcoexist, 0x790);
3029 u8tmp &= 0xc0; 3133 u8tmp &= 0xc0;
3030 u8tmp |= 0x5; 3134 u8tmp |= 0x5;
3031 btcoexist->btc_write_1byte(btcoexist, 0x790, u8tmp); 3135 btcoexist->btc_write_1byte(btcoexist, 0x790, u8tmp);
3032 3136
3033 3137 /*Antenna config */
3034 /*Antenna config */ 3138 btc8723b2ant_set_ant_path(btcoexist, BTC_ANT_WIFI_AT_MAIN,
3035 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver); 3139 true, false);
3036
3037 /*ext switch for fw ver < 0xc */
3038 if (fw_ver < 0xc00) {
3039 if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT) {
3040 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x92c,
3041 0x3, 0x1);
3042 /*Main Ant to BT for IPS case 0x4c[23]=1*/
3043 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x64, 0x1,
3044 0x1);
3045
3046 /*tell firmware "no antenna inverse"*/
3047 h2c_parameter[0] = 0;
3048 h2c_parameter[1] = 1; /* ext switch type */
3049 btcoexist->btc_fill_h2c(btcoexist, 0x65, 2,
3050 h2c_parameter);
3051 } else {
3052 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x92c,
3053 0x3, 0x2);
3054 /*Aux Ant to BT for IPS case 0x4c[23]=1*/
3055 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x64, 0x1,
3056 0x0);
3057
3058 /*tell firmware "antenna inverse"*/
3059 h2c_parameter[0] = 1;
3060 h2c_parameter[1] = 1; /*ext switch type*/
3061 btcoexist->btc_fill_h2c(btcoexist, 0x65, 2,
3062 h2c_parameter);
3063 }
3064 } else {
3065 /*ext switch always at s1 (if exist) */
3066 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x92c, 0x3, 0x1);
3067 /*Main Ant to BT for IPS case 0x4c[23]=1*/
3068 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x64, 0x1, 0x1);
3069
3070 if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT) {
3071 /*tell firmware "no antenna inverse"*/
3072 h2c_parameter[0] = 0;
3073 h2c_parameter[1] = 0; /*ext switch type*/
3074 btcoexist->btc_fill_h2c(btcoexist, 0x65, 2,
3075 h2c_parameter);
3076 } else {
3077 /*tell firmware "antenna inverse"*/
3078 h2c_parameter[0] = 1;
3079 h2c_parameter[1] = 0; /*ext switch type*/
3080 btcoexist->btc_fill_h2c(btcoexist, 0x65, 2,
3081 h2c_parameter);
3082 }
3083 }
3084
3085 /* PTA parameter */ 3140 /* PTA parameter */
3086 btc8723b_coex_tbl_type(btcoexist, FORCE_EXEC, 0); 3141 btc8723b_coex_tbl_type(btcoexist, FORCE_EXEC, 0);
3087 3142
@@ -3092,19 +3147,19 @@ void ex_halbtc8723b2ant_init_hwconfig(struct btc_coexist *btcoexist)
3092 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x40, 0x20, 0x1); 3147 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x40, 0x20, 0x1);
3093} 3148}
3094 3149
3095void ex_halbtc8723b2ant_init_coex_dm(struct btc_coexist *btcoexist) 3150void ex_btc8723b2ant_init_coex_dm(struct btc_coexist *btcoexist)
3096{ 3151{
3097 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, 3152 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
3098 "[BTCoex], Coex Mechanism Init!!\n"); 3153 "[BTCoex], Coex Mechanism Init!!\n");
3099 btc8723b2ant_init_coex_dm(btcoexist); 3154 btc8723b2ant_init_coex_dm(btcoexist);
3100} 3155}
3101 3156
3102void ex_halbtc8723b2ant_display_coex_info(struct btc_coexist *btcoexist) 3157void ex_btc8723b2ant_display_coex_info(struct btc_coexist *btcoexist)
3103{ 3158{
3104 struct btc_board_info *board_info = &btcoexist->board_info; 3159 struct btc_board_info *board_info = &btcoexist->board_info;
3105 struct btc_stack_info *stack_info = &btcoexist->stack_info; 3160 struct btc_stack_info *stack_info = &btcoexist->stack_info;
3106 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info; 3161 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
3107 u8 *cli_buf = btcoexist->cli_buf; 3162 struct rtl_priv *rtlpriv = btcoexist->adapter;
3108 u8 u8tmp[4], i, bt_info_ext, ps_tdma_case = 0; 3163 u8 u8tmp[4], i, bt_info_ext, ps_tdma_case = 0;
3109 u32 u32tmp[4]; 3164 u32 u32tmp[4];
3110 bool roam = false, scan = false; 3165 bool roam = false, scan = false;
@@ -3114,106 +3169,93 @@ void ex_halbtc8723b2ant_display_coex_info(struct btc_coexist *btcoexist)
3114 u32 wifi_bw, wifi_traffic_dir, fa_ofdm, fa_cck; 3169 u32 wifi_bw, wifi_traffic_dir, fa_ofdm, fa_cck;
3115 u8 wifi_dot11_chnl, wifi_hs_chnl; 3170 u8 wifi_dot11_chnl, wifi_hs_chnl;
3116 u32 fw_ver = 0, bt_patch_ver = 0; 3171 u32 fw_ver = 0, bt_patch_ver = 0;
3172 u8 ap_num = 0;
3117 3173
3118 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, 3174 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
3119 "\r\n ============[BT Coexist info]============"); 3175 "\r\n ============[BT Coexist info]============");
3120 CL_PRINTF(cli_buf);
3121 3176
3122 if (btcoexist->manual_control) { 3177 if (btcoexist->manual_control) {
3123 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, 3178 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
3124 "\r\n ==========[Under Manual Control]============"); 3179 "\r\n ==========[Under Manual Control]============");
3125 CL_PRINTF(cli_buf); 3180 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
3126 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
3127 "\r\n =========================================="); 3181 "\r\n ==========================================");
3128 CL_PRINTF(cli_buf);
3129 } 3182 }
3130 3183
3131 if (!board_info->bt_exist) { 3184 if (!board_info->bt_exist) {
3132 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n BT not exists !!!"); 3185 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n BT not exists !!!");
3133 CL_PRINTF(cli_buf);
3134 return; 3186 return;
3135 } 3187 }
3136 3188
3137 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d ", 3189 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d ",
3138 "Ant PG number/ Ant mechanism:", 3190 "Ant PG number/ Ant mechanism:",
3139 board_info->pg_ant_num, board_info->btdm_ant_num); 3191 board_info->pg_ant_num, board_info->btdm_ant_num);
3140 CL_PRINTF(cli_buf);
3141 3192
3142 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %d", 3193 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %s / %d",
3143 "BT stack/ hci ext ver", 3194 "BT stack/ hci ext ver",
3144 ((stack_info->profile_notified) ? "Yes" : "No"), 3195 ((stack_info->profile_notified) ? "Yes" : "No"),
3145 stack_info->hci_version); 3196 stack_info->hci_version);
3146 CL_PRINTF(cli_buf);
3147 3197
3148 btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER, &bt_patch_ver); 3198 btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER, &bt_patch_ver);
3149 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver); 3199 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver);
3150 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, 3200 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
3151 "\r\n %-35s = %d_%x/ 0x%x/ 0x%x(%d)", 3201 "\r\n %-35s = %d_%x/ 0x%x/ 0x%x(%d)",
3152 "CoexVer/ FwVer/ PatchVer", 3202 "CoexVer/ FwVer/ PatchVer",
3153 glcoex_ver_date_8723b_2ant, glcoex_ver_8723b_2ant, 3203 glcoex_ver_date_8723b_2ant, glcoex_ver_8723b_2ant,
3154 fw_ver, bt_patch_ver, bt_patch_ver); 3204 fw_ver, bt_patch_ver, bt_patch_ver);
3155 CL_PRINTF(cli_buf);
3156 3205
3157 btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on); 3206 btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
3158 btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_DOT11_CHNL, 3207 btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_DOT11_CHNL,
3159 &wifi_dot11_chnl); 3208 &wifi_dot11_chnl);
3160 btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_HS_CHNL, &wifi_hs_chnl); 3209 btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_HS_CHNL, &wifi_hs_chnl);
3161 3210
3162 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d(%d)", 3211 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d / %d(%d)",
3163 "Dot11 channel / HsChnl(HsMode)", 3212 "Dot11 channel / HsChnl(HsMode)",
3164 wifi_dot11_chnl, wifi_hs_chnl, bt_hs_on); 3213 wifi_dot11_chnl, wifi_hs_chnl, bt_hs_on);
3165 CL_PRINTF(cli_buf);
3166 3214
3167 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x ", 3215 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %02x %02x %02x ",
3168 "H2C Wifi inform bt chnl Info", coex_dm->wifi_chnl_info[0], 3216 "H2C Wifi inform bt chnl Info", coex_dm->wifi_chnl_info[0],
3169 coex_dm->wifi_chnl_info[1], coex_dm->wifi_chnl_info[2]); 3217 coex_dm->wifi_chnl_info[1], coex_dm->wifi_chnl_info[2]);
3170 CL_PRINTF(cli_buf);
3171 3218
3172 btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi); 3219 btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi);
3173 btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi); 3220 btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi);
3174 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", 3221 btcoexist->btc_get(btcoexist, BTC_GET_U1_AP_NUM, &ap_num);
3175 "Wifi rssi/ HS rssi", wifi_rssi, bt_hs_rssi); 3222 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d/ %d",
3176 CL_PRINTF(cli_buf); 3223 "Wifi rssi/ HS rssi/ AP#", wifi_rssi, bt_hs_rssi, ap_num);
3177 3224
3178 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan); 3225 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan);
3179 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link); 3226 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link);
3180 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam); 3227 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam);
3181 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d ", 3228 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d/ %d ",
3182 "Wifi link/ roam/ scan", link, roam, scan); 3229 "Wifi link/ roam/ scan", link, roam, scan);
3183 CL_PRINTF(cli_buf);
3184 3230
3185 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g); 3231 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
3186 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw); 3232 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
3187 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy); 3233 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
3188 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, 3234 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION,
3189 &wifi_traffic_dir); 3235 &wifi_traffic_dir);
3190 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %s/ %s ", 3236 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %s / %s/ %s ",
3191 "Wifi status", (wifi_under_5g ? "5G" : "2.4G"), 3237 "Wifi status", (wifi_under_5g ? "5G" : "2.4G"),
3192 ((BTC_WIFI_BW_LEGACY == wifi_bw) ? "Legacy" : 3238 ((BTC_WIFI_BW_LEGACY == wifi_bw) ? "Legacy" :
3193 (((BTC_WIFI_BW_HT40 == wifi_bw) ? "HT40" : "HT20"))), 3239 (((BTC_WIFI_BW_HT40 == wifi_bw) ? "HT40" : "HT20"))),
3194 ((!wifi_busy) ? "idle" : 3240 ((!wifi_busy) ? "idle" :
3195 ((BTC_WIFI_TRAFFIC_TX == wifi_traffic_dir) ? 3241 ((BTC_WIFI_TRAFFIC_TX == wifi_traffic_dir) ?
3196 "uplink" : "downlink"))); 3242 "uplink" : "downlink")));
3197 CL_PRINTF(cli_buf);
3198 3243
3199 CL_PRINTF(cli_buf);
3200 3244
3201 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d / %d / %d", 3245 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d / %d / %d / %d",
3202 "SCO/HID/PAN/A2DP", 3246 "SCO/HID/PAN/A2DP",
3203 bt_link_info->sco_exist, bt_link_info->hid_exist, 3247 bt_link_info->sco_exist, bt_link_info->hid_exist,
3204 bt_link_info->pan_exist, bt_link_info->a2dp_exist); 3248 bt_link_info->pan_exist, bt_link_info->a2dp_exist);
3205 CL_PRINTF(cli_buf);
3206 btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_BT_LINK_INFO); 3249 btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_BT_LINK_INFO);
3207 3250
3208 bt_info_ext = coex_sta->bt_info_ext; 3251 bt_info_ext = coex_sta->bt_info_ext;
3209 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s", 3252 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %s",
3210 "BT Info A2DP rate", 3253 "BT Info A2DP rate",
3211 (bt_info_ext&BIT0) ? "Basic rate" : "EDR rate"); 3254 (bt_info_ext&BIT0) ? "Basic rate" : "EDR rate");
3212 CL_PRINTF(cli_buf);
3213 3255
3214 for (i = 0; i < BT_INFO_SRC_8723B_2ANT_MAX; i++) { 3256 for (i = 0; i < BT_INFO_SRC_8723B_2ANT_MAX; i++) {
3215 if (coex_sta->bt_info_c2h_cnt[i]) { 3257 if (coex_sta->bt_info_c2h_cnt[i]) {
3216 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, 3258 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
3217 "\r\n %-35s = %02x %02x %02x " 3259 "\r\n %-35s = %02x %02x %02x "
3218 "%02x %02x %02x %02x(%d)", 3260 "%02x %02x %02x %02x(%d)",
3219 glbt_info_src_8723b_2ant[i], 3261 glbt_info_src_8723b_2ant[i],
@@ -3225,105 +3267,88 @@ void ex_halbtc8723b2ant_display_coex_info(struct btc_coexist *btcoexist)
3225 coex_sta->bt_info_c2h[i][5], 3267 coex_sta->bt_info_c2h[i][5],
3226 coex_sta->bt_info_c2h[i][6], 3268 coex_sta->bt_info_c2h[i][6],
3227 coex_sta->bt_info_c2h_cnt[i]); 3269 coex_sta->bt_info_c2h_cnt[i]);
3228 CL_PRINTF(cli_buf);
3229 } 3270 }
3230 } 3271 }
3231 3272
3232 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/%s", 3273 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %s/%s",
3233 "PS state, IPS/LPS", 3274 "PS state, IPS/LPS",
3234 ((coex_sta->under_ips ? "IPS ON" : "IPS OFF")), 3275 ((coex_sta->under_ips ? "IPS ON" : "IPS OFF")),
3235 ((coex_sta->under_lps ? "LPS ON" : "LPS OFF"))); 3276 ((coex_sta->under_lps ? "LPS ON" : "LPS OFF")));
3236 CL_PRINTF(cli_buf);
3237 btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_FW_PWR_MODE_CMD); 3277 btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_FW_PWR_MODE_CMD);
3238 3278
3239 /* Sw mechanism */ 3279 /* Sw mechanism */
3240 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, 3280 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
3241 "\r\n %-35s", "============[Sw mechanism]============"); 3281 "\r\n %-35s", "============[Sw mechanism]============");
3242 CL_PRINTF(cli_buf); 3282 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d/ %d ",
3243 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d ",
3244 "SM1[ShRf/ LpRA/ LimDig]", coex_dm->cur_rf_rx_lpf_shrink, 3283 "SM1[ShRf/ LpRA/ LimDig]", coex_dm->cur_rf_rx_lpf_shrink,
3245 coex_dm->cur_low_penalty_ra, coex_dm->limited_dig); 3284 coex_dm->cur_low_penalty_ra, coex_dm->limited_dig);
3246 CL_PRINTF(cli_buf); 3285 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d/ %d(0x%x) ",
3247 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d(0x%x) ",
3248 "SM2[AgcT/ AdcB/ SwDacSwing(lvl)]", 3286 "SM2[AgcT/ AdcB/ SwDacSwing(lvl)]",
3249 coex_dm->cur_agc_table_en, coex_dm->cur_adc_back_off, 3287 coex_dm->cur_agc_table_en, coex_dm->cur_adc_back_off,
3250 coex_dm->cur_dac_swing_on, coex_dm->cur_dac_swing_lvl); 3288 coex_dm->cur_dac_swing_on, coex_dm->cur_dac_swing_lvl);
3251 CL_PRINTF(cli_buf);
3252 3289
3253 /* Fw mechanism */ 3290 /* Fw mechanism */
3254 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s", 3291 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s",
3255 "============[Fw mechanism]============"); 3292 "============[Fw mechanism]============");
3256 CL_PRINTF(cli_buf);
3257 3293
3258 ps_tdma_case = coex_dm->cur_ps_tdma; 3294 ps_tdma_case = coex_dm->cur_ps_tdma;
3259 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, 3295 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
3260 "\r\n %-35s = %02x %02x %02x %02x %02x case-%d (auto:%d)", 3296 "\r\n %-35s = %02x %02x %02x %02x %02x case-%d (auto:%d)",
3261 "PS TDMA", coex_dm->ps_tdma_para[0], 3297 "PS TDMA", coex_dm->ps_tdma_para[0],
3262 coex_dm->ps_tdma_para[1], coex_dm->ps_tdma_para[2], 3298 coex_dm->ps_tdma_para[1], coex_dm->ps_tdma_para[2],
3263 coex_dm->ps_tdma_para[3], coex_dm->ps_tdma_para[4], 3299 coex_dm->ps_tdma_para[3], coex_dm->ps_tdma_para[4],
3264 ps_tdma_case, coex_dm->auto_tdma_adjust); 3300 ps_tdma_case, coex_dm->auto_tdma_adjust);
3265 CL_PRINTF(cli_buf);
3266 3301
3267 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d ", 3302 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d ",
3268 "DecBtPwr/ IgnWlanAct", coex_dm->cur_dec_bt_pwr, 3303 "DecBtPwr/ IgnWlanAct", coex_dm->cur_dec_bt_pwr,
3269 coex_dm->cur_ignore_wlan_act); 3304 coex_dm->cur_ignore_wlan_act);
3270 CL_PRINTF(cli_buf);
3271 3305
3272 /* Hw setting */ 3306 /* Hw setting */
3273 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s", 3307 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s",
3274 "============[Hw setting]============"); 3308 "============[Hw setting]============");
3275 CL_PRINTF(cli_buf);
3276 3309
3277 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", 3310 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x",
3278 "RF-A, 0x1e initVal", coex_dm->bt_rf0x1e_backup); 3311 "RF-A, 0x1e initVal", coex_dm->bt_rf0x1e_backup);
3279 CL_PRINTF(cli_buf);
3280 3312
3281 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x778); 3313 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x778);
3282 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x880); 3314 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x880);
3283 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", 3315 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x",
3284 "0x778/0x880[29:25]", u8tmp[0], 3316 "0x778/0x880[29:25]", u8tmp[0],
3285 (u32tmp[0]&0x3e000000) >> 25); 3317 (u32tmp[0]&0x3e000000) >> 25);
3286 CL_PRINTF(cli_buf);
3287 3318
3288 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x948); 3319 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x948);
3289 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x67); 3320 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x67);
3290 u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x765); 3321 u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x765);
3291 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", 3322 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
3292 "0x948/ 0x67[5] / 0x765", 3323 "0x948/ 0x67[5] / 0x765",
3293 u32tmp[0], ((u8tmp[0]&0x20) >> 5), u8tmp[1]); 3324 u32tmp[0], ((u8tmp[0]&0x20) >> 5), u8tmp[1]);
3294 CL_PRINTF(cli_buf);
3295 3325
3296 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x92c); 3326 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x92c);
3297 u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x930); 3327 u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x930);
3298 u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x944); 3328 u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x944);
3299 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", 3329 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
3300 "0x92c[1:0]/ 0x930[7:0]/0x944[1:0]", 3330 "0x92c[1:0]/ 0x930[7:0]/0x944[1:0]",
3301 u32tmp[0]&0x3, u32tmp[1]&0xff, u32tmp[2]&0x3); 3331 u32tmp[0]&0x3, u32tmp[1]&0xff, u32tmp[2]&0x3);
3302 CL_PRINTF(cli_buf);
3303
3304 3332
3305 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x39); 3333 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x39);
3306 u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x40); 3334 u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x40);
3307 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x4c); 3335 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x4c);
3308 u8tmp[2] = btcoexist->btc_read_1byte(btcoexist, 0x64); 3336 u8tmp[2] = btcoexist->btc_read_1byte(btcoexist, 0x64);
3309 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, 3337 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
3310 "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", 3338 "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x",
3311 "0x38[11]/0x40/0x4c[24:23]/0x64[0]", 3339 "0x38[11]/0x40/0x4c[24:23]/0x64[0]",
3312 ((u8tmp[0] & 0x8)>>3), u8tmp[1], 3340 ((u8tmp[0] & 0x8)>>3), u8tmp[1],
3313 ((u32tmp[0]&0x01800000)>>23), u8tmp[2]&0x1); 3341 ((u32tmp[0]&0x01800000)>>23), u8tmp[2]&0x1);
3314 CL_PRINTF(cli_buf);
3315 3342
3316 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x550); 3343 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x550);
3317 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x522); 3344 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x522);
3318 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", 3345 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x",
3319 "0x550(bcn ctrl)/0x522", u32tmp[0], u8tmp[0]); 3346 "0x550(bcn ctrl)/0x522", u32tmp[0], u8tmp[0]);
3320 CL_PRINTF(cli_buf);
3321 3347
3322 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xc50); 3348 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xc50);
3323 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x49c); 3349 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x49c);
3324 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", 3350 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x",
3325 "0xc50(dig)/0x49c(null-drop)", u32tmp[0]&0xff, u8tmp[0]); 3351 "0xc50(dig)/0x49c(null-drop)", u32tmp[0]&0xff, u8tmp[0]);
3326 CL_PRINTF(cli_buf);
3327 3352
3328 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xda0); 3353 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xda0);
3329 u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0xda4); 3354 u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0xda4);
@@ -3341,29 +3366,25 @@ void ex_halbtc8723b2ant_display_coex_info(struct btc_coexist *btcoexist)
3341 (u32tmp[3] & 0xffff); 3366 (u32tmp[3] & 0xffff);
3342 fa_cck = (u8tmp[0] << 8) + u8tmp[1]; 3367 fa_cck = (u8tmp[0] << 8) + u8tmp[1];
3343 3368
3344 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", 3369 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
3345 "OFDM-CCA/OFDM-FA/CCK-FA", 3370 "OFDM-CCA/OFDM-FA/CCK-FA",
3346 u32tmp[0]&0xffff, fa_ofdm, fa_cck); 3371 u32tmp[0]&0xffff, fa_ofdm, fa_cck);
3347 CL_PRINTF(cli_buf);
3348 3372
3349 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x6c0); 3373 u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x6c0);
3350 u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x6c4); 3374 u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x6c4);
3351 u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x6c8); 3375 u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x6c8);
3352 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x6cc); 3376 u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x6cc);
3353 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, 3377 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
3354 "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", 3378 "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x",
3355 "0x6c0/0x6c4/0x6c8/0x6cc(coexTable)", 3379 "0x6c0/0x6c4/0x6c8/0x6cc(coexTable)",
3356 u32tmp[0], u32tmp[1], u32tmp[2], u8tmp[0]); 3380 u32tmp[0], u32tmp[1], u32tmp[2], u8tmp[0]);
3357 CL_PRINTF(cli_buf);
3358 3381
3359 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", 3382 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d",
3360 "0x770(high-pri rx/tx)", 3383 "0x770(high-pri rx/tx)",
3361 coex_sta->high_priority_rx, coex_sta->high_priority_tx); 3384 coex_sta->high_priority_rx, coex_sta->high_priority_tx);
3362 CL_PRINTF(cli_buf); 3385 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d",
3363 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d",
3364 "0x774(low-pri rx/tx)", coex_sta->low_priority_rx, 3386 "0x774(low-pri rx/tx)", coex_sta->low_priority_rx,
3365 coex_sta->low_priority_tx); 3387 coex_sta->low_priority_tx);
3366 CL_PRINTF(cli_buf);
3367#if (BT_AUTO_REPORT_ONLY_8723B_2ANT == 1) 3388#if (BT_AUTO_REPORT_ONLY_8723B_2ANT == 1)
3368 btc8723b2ant_monitor_bt_ctr(btcoexist); 3389 btc8723b2ant_monitor_bt_ctr(btcoexist);
3369#endif 3390#endif
@@ -3371,22 +3392,26 @@ void ex_halbtc8723b2ant_display_coex_info(struct btc_coexist *btcoexist)
3371 BTC_DBG_DISP_COEX_STATISTICS); 3392 BTC_DBG_DISP_COEX_STATISTICS);
3372} 3393}
3373 3394
3374 3395void ex_btc8723b2ant_ips_notify(struct btc_coexist *btcoexist, u8 type)
3375void ex_halbtc8723b2ant_ips_notify(struct btc_coexist *btcoexist, u8 type)
3376{ 3396{
3377 if (BTC_IPS_ENTER == type) { 3397 if (BTC_IPS_ENTER == type) {
3378 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, 3398 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3379 "[BTCoex], IPS ENTER notify\n"); 3399 "[BTCoex], IPS ENTER notify\n");
3380 coex_sta->under_ips = true; 3400 coex_sta->under_ips = true;
3401 btc8723b2ant_wifioff_hwcfg(btcoexist);
3402 btc8723b2ant_ignore_wlan_act(btcoexist, FORCE_EXEC, true);
3381 btc8723b2ant_coex_alloff(btcoexist); 3403 btc8723b2ant_coex_alloff(btcoexist);
3382 } else if (BTC_IPS_LEAVE == type) { 3404 } else if (BTC_IPS_LEAVE == type) {
3383 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, 3405 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3384 "[BTCoex], IPS LEAVE notify\n"); 3406 "[BTCoex], IPS LEAVE notify\n");
3385 coex_sta->under_ips = false; 3407 coex_sta->under_ips = false;
3408 ex_btc8723b2ant_init_hwconfig(btcoexist);
3409 btc8723b2ant_init_coex_dm(btcoexist);
3410 btc8723b2ant_query_bt_info(btcoexist);
3386 } 3411 }
3387} 3412}
3388 3413
3389void ex_halbtc8723b2ant_lps_notify(struct btc_coexist *btcoexist, u8 type) 3414void ex_btc8723b2ant_lps_notify(struct btc_coexist *btcoexist, u8 type)
3390{ 3415{
3391 if (BTC_LPS_ENABLE == type) { 3416 if (BTC_LPS_ENABLE == type) {
3392 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, 3417 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
@@ -3399,7 +3424,7 @@ void ex_halbtc8723b2ant_lps_notify(struct btc_coexist *btcoexist, u8 type)
3399 } 3424 }
3400} 3425}
3401 3426
3402void ex_halbtc8723b2ant_scan_notify(struct btc_coexist *btcoexist, u8 type) 3427void ex_btc8723b2ant_scan_notify(struct btc_coexist *btcoexist, u8 type)
3403{ 3428{
3404 if (BTC_SCAN_START == type) 3429 if (BTC_SCAN_START == type)
3405 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, 3430 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
@@ -3409,7 +3434,7 @@ void ex_halbtc8723b2ant_scan_notify(struct btc_coexist *btcoexist, u8 type)
3409 "[BTCoex], SCAN FINISH notify\n"); 3434 "[BTCoex], SCAN FINISH notify\n");
3410} 3435}
3411 3436
3412void ex_halbtc8723b2ant_connect_notify(struct btc_coexist *btcoexist, u8 type) 3437void ex_btc8723b2ant_connect_notify(struct btc_coexist *btcoexist, u8 type)
3413{ 3438{
3414 if (BTC_ASSOCIATE_START == type) 3439 if (BTC_ASSOCIATE_START == type)
3415 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, 3440 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
@@ -3419,8 +3444,8 @@ void ex_halbtc8723b2ant_connect_notify(struct btc_coexist *btcoexist, u8 type)
3419 "[BTCoex], CONNECT FINISH notify\n"); 3444 "[BTCoex], CONNECT FINISH notify\n");
3420} 3445}
3421 3446
3422void btc8723b_med_stat_notify(struct btc_coexist *btcoexist, 3447void ex_btc8723b2ant_media_status_notify(struct btc_coexist *btcoexist,
3423 u8 type) 3448 u8 type)
3424{ 3449{
3425 u8 h2c_parameter[3] = {0}; 3450 u8 h2c_parameter[3] = {0};
3426 u32 wifi_bw; 3451 u32 wifi_bw;
@@ -3460,16 +3485,16 @@ void btc8723b_med_stat_notify(struct btc_coexist *btcoexist,
3460 btcoexist->btc_fill_h2c(btcoexist, 0x66, 3, h2c_parameter); 3485 btcoexist->btc_fill_h2c(btcoexist, 0x66, 3, h2c_parameter);
3461} 3486}
3462 3487
3463void ex_halbtc8723b2ant_special_packet_notify(struct btc_coexist *btcoexist, 3488void ex_btc8723b2ant_special_packet_notify(struct btc_coexist *btcoexist,
3464 u8 type) 3489 u8 type)
3465{ 3490{
3466 if (type == BTC_PACKET_DHCP) 3491 if (type == BTC_PACKET_DHCP)
3467 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, 3492 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3468 "[BTCoex], DHCP Packet notify\n"); 3493 "[BTCoex], DHCP Packet notify\n");
3469} 3494}
3470 3495
3471void ex_halbtc8723b2ant_bt_info_notify(struct btc_coexist *btcoexist, 3496void ex_btc8723b2ant_bt_info_notify(struct btc_coexist *btcoexist,
3472 u8 *tmpbuf, u8 length) 3497 u8 *tmpbuf, u8 length)
3473{ 3498{
3474 u8 bt_info = 0; 3499 u8 bt_info = 0;
3475 u8 i, rsp_source = 0; 3500 u8 i, rsp_source = 0;
@@ -3516,7 +3541,7 @@ void ex_halbtc8723b2ant_bt_info_notify(struct btc_coexist *btcoexist,
3516 coex_sta->bt_info_c2h[rsp_source][4]; 3541 coex_sta->bt_info_c2h[rsp_source][4];
3517 3542
3518 /* Here we need to resend some wifi info to BT 3543 /* Here we need to resend some wifi info to BT
3519 * because bt is reset and loss of the info. 3544 because bt is reset and loss of the info.
3520 */ 3545 */
3521 if ((coex_sta->bt_info_ext & BIT1)) { 3546 if ((coex_sta->bt_info_ext & BIT1)) {
3522 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, 3547 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
@@ -3525,11 +3550,13 @@ void ex_halbtc8723b2ant_bt_info_notify(struct btc_coexist *btcoexist,
3525 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, 3550 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
3526 &wifi_connected); 3551 &wifi_connected);
3527 if (wifi_connected) 3552 if (wifi_connected)
3528 btc8723b_med_stat_notify(btcoexist, 3553 ex_btc8723b2ant_media_status_notify(
3529 BTC_MEDIA_CONNECT); 3554 btcoexist,
3555 BTC_MEDIA_CONNECT);
3530 else 3556 else
3531 btc8723b_med_stat_notify(btcoexist, 3557 ex_btc8723b2ant_media_status_notify(
3532 BTC_MEDIA_DISCONNECT); 3558 btcoexist,
3559 BTC_MEDIA_DISCONNECT);
3533 } 3560 }
3534 3561
3535 if ((coex_sta->bt_info_ext & BIT3)) { 3562 if ((coex_sta->bt_info_ext & BIT3)) {
@@ -3564,7 +3591,7 @@ void ex_halbtc8723b2ant_bt_info_notify(struct btc_coexist *btcoexist,
3564 coex_sta->a2dp_exist = false; 3591 coex_sta->a2dp_exist = false;
3565 coex_sta->hid_exist = false; 3592 coex_sta->hid_exist = false;
3566 coex_sta->sco_exist = false; 3593 coex_sta->sco_exist = false;
3567 } else { /* connection exists */ 3594 } else { /* connection exists */
3568 coex_sta->bt_link_exist = true; 3595 coex_sta->bt_link_exist = true;
3569 if (bt_info & BT_INFO_8723B_2ANT_B_FTP) 3596 if (bt_info & BT_INFO_8723B_2ANT_B_FTP)
3570 coex_sta->pan_exist = true; 3597 coex_sta->pan_exist = true;
@@ -3601,7 +3628,7 @@ void ex_halbtc8723b2ant_bt_info_notify(struct btc_coexist *btcoexist,
3601 coex_dm->bt_status = BT_8723B_2ANT_BT_STATUS_SCO_BUSY; 3628 coex_dm->bt_status = BT_8723B_2ANT_BT_STATUS_SCO_BUSY;
3602 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, 3629 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3603 "[BTCoex], BtInfoNotify(), BT SCO busy!!!\n"); 3630 "[BTCoex], BtInfoNotify(), BT SCO busy!!!\n");
3604 } else if (bt_info & BT_INFO_8723B_2ANT_B_ACL_BUSY) { 3631 } else if (bt_info&BT_INFO_8723B_2ANT_B_ACL_BUSY) {
3605 coex_dm->bt_status = BT_8723B_2ANT_BT_STATUS_ACL_BUSY; 3632 coex_dm->bt_status = BT_8723B_2ANT_BT_STATUS_ACL_BUSY;
3606 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, 3633 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3607 "[BTCoex], BtInfoNotify(), BT ACL busy!!!\n"); 3634 "[BTCoex], BtInfoNotify(), BT ACL busy!!!\n");
@@ -3630,26 +3657,16 @@ void ex_halbtc8723b2ant_bt_info_notify(struct btc_coexist *btcoexist,
3630 btc8723b2ant_run_coexist_mechanism(btcoexist); 3657 btc8723b2ant_run_coexist_mechanism(btcoexist);
3631} 3658}
3632 3659
3633void ex_halbtc8723b2ant_stack_operation_notify(struct btc_coexist *btcoexist, 3660void ex_btc8723b2ant_halt_notify(struct btc_coexist *btcoexist)
3634 u8 type)
3635{
3636 if (BTC_STACK_OP_INQ_PAGE_PAIR_START == type)
3637 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3638 "[BTCoex],StackOP Inquiry/page/pair start notify\n");
3639 else if (BTC_STACK_OP_INQ_PAGE_PAIR_FINISH == type)
3640 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3641 "[BTCoex],StackOP Inquiry/page/pair finish notify\n");
3642}
3643
3644void ex_halbtc8723b2ant_halt_notify(struct btc_coexist *btcoexist)
3645{ 3661{
3646 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, "[BTCoex], Halt notify\n"); 3662 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, "[BTCoex], Halt notify\n");
3647 3663
3664 btc8723b2ant_wifioff_hwcfg(btcoexist);
3648 btc8723b2ant_ignore_wlan_act(btcoexist, FORCE_EXEC, true); 3665 btc8723b2ant_ignore_wlan_act(btcoexist, FORCE_EXEC, true);
3649 btc8723b_med_stat_notify(btcoexist, BTC_MEDIA_DISCONNECT); 3666 ex_btc8723b2ant_media_status_notify(btcoexist, BTC_MEDIA_DISCONNECT);
3650} 3667}
3651 3668
3652void ex_halbtc8723b2ant_periodical(struct btc_coexist *btcoexist) 3669void ex_btc8723b2ant_periodical(struct btc_coexist *btcoexist)
3653{ 3670{
3654 struct btc_board_info *board_info = &btcoexist->board_info; 3671 struct btc_board_info *board_info = &btcoexist->board_info;
3655 struct btc_stack_info *stack_info = &btcoexist->stack_info; 3672 struct btc_stack_info *stack_info = &btcoexist->stack_info;
@@ -3677,8 +3694,7 @@ void ex_halbtc8723b2ant_periodical(struct btc_coexist *btcoexist)
3677 &bt_patch_ver); 3694 &bt_patch_ver);
3678 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver); 3695 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver);
3679 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, 3696 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
3680 "[BTCoex], CoexVer/ FwVer/ PatchVer = " 3697 "[BTCoex], CoexVer/ fw_ver/ PatchVer = %d_%x/ 0x%x/ 0x%x(%d)\n",
3681 "%d_%x/ 0x%x/ 0x%x(%d)\n",
3682 glcoex_ver_date_8723b_2ant, glcoex_ver_8723b_2ant, 3698 glcoex_ver_date_8723b_2ant, glcoex_ver_8723b_2ant,
3683 fw_ver, bt_patch_ver, bt_patch_ver); 3699 fw_ver, bt_patch_ver, bt_patch_ver);
3684 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, 3700 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.h b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.h
index e0ad8e545f82..567f354caf95 100644
--- a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.h
+++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8723b2ant.h
@@ -153,21 +153,20 @@ struct coex_sta_8723b_2ant {
153/********************************************************************* 153/*********************************************************************
154 * The following is interface which will notify coex module. 154 * The following is interface which will notify coex module.
155 *********************************************************************/ 155 *********************************************************************/
156void ex_halbtc8723b2ant_init_hwconfig(struct btc_coexist *btcoexist); 156void ex_btc8723b2ant_init_hwconfig(struct btc_coexist *btcoexist);
157void ex_halbtc8723b2ant_init_coex_dm(struct btc_coexist *btcoexist); 157void ex_btc8723b2ant_init_coex_dm(struct btc_coexist *btcoexist);
158void ex_halbtc8723b2ant_ips_notify(struct btc_coexist *btcoexist, u8 type); 158void ex_btc8723b2ant_ips_notify(struct btc_coexist *btcoexist, u8 type);
159void ex_halbtc8723b2ant_lps_notify(struct btc_coexist *btcoexist, u8 type); 159void ex_btc8723b2ant_lps_notify(struct btc_coexist *btcoexist, u8 type);
160void ex_halbtc8723b2ant_scan_notify(struct btc_coexist *btcoexist, u8 type); 160void ex_btc8723b2ant_scan_notify(struct btc_coexist *btcoexist, u8 type);
161void ex_halbtc8723b2ant_connect_notify(struct btc_coexist *btcoexist, u8 type); 161void ex_btc8723b2ant_connect_notify(struct btc_coexist *btcoexist, u8 type);
162void btc8723b_med_stat_notify(struct btc_coexist *btcoexist, u8 type); 162void ex_btc8723b2ant_media_status_notify(struct btc_coexist *btcoexist,
163void ex_halbtc8723b2ant_special_packet_notify(struct btc_coexist *btcoexist, 163 u8 type);
164 u8 type); 164void ex_btc8723b2ant_special_packet_notify(struct btc_coexist *btcoexist,
165void ex_halbtc8723b2ant_bt_info_notify(struct btc_coexist *btcoexist, 165 u8 type);
166 u8 *tmpbuf, u8 length); 166void ex_btc8723b2ant_bt_info_notify(struct btc_coexist *btcoexist,
167void ex_halbtc8723b2ant_stack_operation_notify(struct btc_coexist *btcoexist, 167 u8 *tmpbuf, u8 length);
168 u8 type); 168void ex_btc8723b2ant_halt_notify(struct btc_coexist *btcoexist);
169void ex_halbtc8723b2ant_halt_notify(struct btc_coexist *btcoexist); 169void ex_btc8723b2ant_periodical(struct btc_coexist *btcoexist);
170void ex_halbtc8723b2ant_periodical(struct btc_coexist *btcoexist); 170void ex_btc8723b2ant_display_coex_info(struct btc_coexist *btcoexist);
171void ex_halbtc8723b2ant_display_coex_info(struct btc_coexist *btcoexist);
172 171
173#endif 172#endif
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a1ant.c b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a1ant.c
new file mode 100644
index 000000000000..b72e5377bdbc
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a1ant.c
@@ -0,0 +1,2970 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2012 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26/*============================================================
27 * Description:
28 *
29 * This file is for RTL8821A Co-exist mechanism
30 *
31 * History
32 * 2012/11/15 Cosa first check in.
33 *
34 *============================================================
35*/
36/*============================================================
37 * include files
38 *============================================================
39 */
40#include "halbt_precomp.h"
41/*============================================================
42 * Global variables, these are static variables
43 *============================================================
44 */
45static struct coex_dm_8821a_1ant glcoex_dm_8821a_1ant;
46static struct coex_dm_8821a_1ant *coex_dm = &glcoex_dm_8821a_1ant;
47static struct coex_sta_8821a_1ant glcoex_sta_8821a_1ant;
48static struct coex_sta_8821a_1ant *coex_sta = &glcoex_sta_8821a_1ant;
49
50static const char *const glbt_info_src_8821a_1ant[] = {
51 "BT Info[wifi fw]",
52 "BT Info[bt rsp]",
53 "BT Info[bt auto report]",
54};
55
56static u32 glcoex_ver_date_8821a_1ant = 20130816;
57static u32 glcoex_ver_8821a_1ant = 0x41;
58
59/*============================================================
60 * local function proto type if needed
61 *
62 * local function start with halbtc8821a1ant_
63 *============================================================
64 */
65static u8 halbtc8821a1ant_bt_rssi_state(u8 level_num, u8 rssi_thresh,
66 u8 rssi_thresh1)
67{
68 long bt_rssi = 0;
69 u8 bt_rssi_state = coex_sta->pre_bt_rssi_state;
70
71 bt_rssi = coex_sta->bt_rssi;
72
73 if (level_num == 2) {
74 if ((coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_LOW) ||
75 (coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) {
76 if (bt_rssi >= (rssi_thresh +
77 BTC_RSSI_COEX_THRESH_TOL_8821A_1ANT)) {
78 bt_rssi_state = BTC_RSSI_STATE_HIGH;
79 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
80 "[BTCoex], BT Rssi state switch to High\n");
81 } else {
82 bt_rssi_state = BTC_RSSI_STATE_STAY_LOW;
83 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
84 "[BTCoex], BT Rssi state stay at Low\n");
85 }
86 } else {
87 if (bt_rssi < rssi_thresh) {
88 bt_rssi_state = BTC_RSSI_STATE_LOW;
89 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
90 "[BTCoex], BT Rssi state switch to Low\n");
91 } else {
92 bt_rssi_state = BTC_RSSI_STATE_STAY_HIGH;
93 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
94 "[BTCoex], BT Rssi state stay at High\n");
95 }
96 }
97 } else if (level_num == 3) {
98 if (rssi_thresh > rssi_thresh1) {
99 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
100 "[BTCoex], BT Rssi thresh error!!\n");
101 return coex_sta->pre_bt_rssi_state;
102 }
103
104 if ((coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_LOW) ||
105 (coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) {
106 if (bt_rssi >= (rssi_thresh +
107 BTC_RSSI_COEX_THRESH_TOL_8821A_1ANT)) {
108 bt_rssi_state = BTC_RSSI_STATE_MEDIUM;
109 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
110 "[BTCoex], BT Rssi state switch to Medium\n");
111 } else {
112 bt_rssi_state = BTC_RSSI_STATE_STAY_LOW;
113 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
114 "[BTCoex], BT Rssi state stay at Low\n");
115 }
116 } else if ((coex_sta->pre_bt_rssi_state ==
117 BTC_RSSI_STATE_MEDIUM) ||
118 (coex_sta->pre_bt_rssi_state ==
119 BTC_RSSI_STATE_STAY_MEDIUM)) {
120 if (bt_rssi >= (rssi_thresh1 +
121 BTC_RSSI_COEX_THRESH_TOL_8821A_1ANT)) {
122 bt_rssi_state = BTC_RSSI_STATE_HIGH;
123 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
124 "[BTCoex], BT Rssi state switch to High\n");
125 } else if (bt_rssi < rssi_thresh) {
126 bt_rssi_state = BTC_RSSI_STATE_LOW;
127 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
128 "[BTCoex], BT Rssi state switch to Low\n");
129 } else {
130 bt_rssi_state = BTC_RSSI_STATE_STAY_MEDIUM;
131 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
132 "[BTCoex], BT Rssi state stay at Medium\n");
133 }
134 } else {
135 if (bt_rssi < rssi_thresh1) {
136 bt_rssi_state = BTC_RSSI_STATE_MEDIUM;
137 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
138 "[BTCoex], BT Rssi state switch to Medium\n");
139 } else {
140 bt_rssi_state = BTC_RSSI_STATE_STAY_HIGH;
141 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
142 "[BTCoex], BT Rssi state stay at High\n");
143 }
144 }
145 }
146 coex_sta->pre_bt_rssi_state = bt_rssi_state;
147
148 return bt_rssi_state;
149}
150
151static u8 halbtc8821a1ant_WifiRssiState(struct btc_coexist *btcoexist,
152 u8 index, u8 level_num, u8 rssi_thresh,
153 u8 rssi_thresh1)
154{
155 long wifi_rssi = 0;
156 u8 wifi_rssi_state = coex_sta->pre_wifi_rssi_state[index];
157
158 btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi);
159
160 if (level_num == 2) {
161 if ((coex_sta->pre_wifi_rssi_state[index] ==
162 BTC_RSSI_STATE_LOW) ||
163 (coex_sta->pre_wifi_rssi_state[index] ==
164 BTC_RSSI_STATE_STAY_LOW)) {
165 if (wifi_rssi >=
166 (rssi_thresh+BTC_RSSI_COEX_THRESH_TOL_8821A_1ANT)) {
167 wifi_rssi_state = BTC_RSSI_STATE_HIGH;
168 BTC_PRINT(BTC_MSG_ALGORITHM,
169 ALGO_WIFI_RSSI_STATE,
170 "[BTCoex], wifi RSSI state switch to High\n");
171 } else {
172 wifi_rssi_state = BTC_RSSI_STATE_STAY_LOW;
173 BTC_PRINT(BTC_MSG_ALGORITHM,
174 ALGO_WIFI_RSSI_STATE,
175 "[BTCoex], wifi RSSI state stay at Low\n");
176 }
177 } else {
178 if (wifi_rssi < rssi_thresh) {
179 wifi_rssi_state = BTC_RSSI_STATE_LOW;
180 BTC_PRINT(BTC_MSG_ALGORITHM,
181 ALGO_WIFI_RSSI_STATE,
182 "[BTCoex], wifi RSSI state switch to Low\n");
183 } else {
184 wifi_rssi_state = BTC_RSSI_STATE_STAY_HIGH;
185 BTC_PRINT(BTC_MSG_ALGORITHM,
186 ALGO_WIFI_RSSI_STATE,
187 "[BTCoex], wifi RSSI state stay at High\n");
188 }
189 }
190 } else if (level_num == 3) {
191 if (rssi_thresh > rssi_thresh1) {
192 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE,
193 "[BTCoex], wifi RSSI thresh error!!\n");
194 return coex_sta->pre_wifi_rssi_state[index];
195 }
196
197 if ((coex_sta->pre_wifi_rssi_state[index] ==
198 BTC_RSSI_STATE_LOW) ||
199 (coex_sta->pre_wifi_rssi_state[index] ==
200 BTC_RSSI_STATE_STAY_LOW)) {
201 if (wifi_rssi >=
202 (rssi_thresh+BTC_RSSI_COEX_THRESH_TOL_8821A_1ANT)) {
203 wifi_rssi_state = BTC_RSSI_STATE_MEDIUM;
204 BTC_PRINT(BTC_MSG_ALGORITHM,
205 ALGO_WIFI_RSSI_STATE,
206 "[BTCoex], wifi RSSI state switch to Medium\n");
207 } else {
208 wifi_rssi_state = BTC_RSSI_STATE_STAY_LOW;
209 BTC_PRINT(BTC_MSG_ALGORITHM,
210 ALGO_WIFI_RSSI_STATE,
211 "[BTCoex], wifi RSSI state stay at Low\n");
212 }
213 } else if ((coex_sta->pre_wifi_rssi_state[index] ==
214 BTC_RSSI_STATE_MEDIUM) ||
215 (coex_sta->pre_wifi_rssi_state[index] ==
216 BTC_RSSI_STATE_STAY_MEDIUM)) {
217 if (wifi_rssi >=
218 (rssi_thresh1 +
219 BTC_RSSI_COEX_THRESH_TOL_8821A_1ANT)) {
220 wifi_rssi_state = BTC_RSSI_STATE_HIGH;
221 BTC_PRINT(BTC_MSG_ALGORITHM,
222 ALGO_WIFI_RSSI_STATE,
223 "[BTCoex], wifi RSSI state switch to High\n");
224 } else if (wifi_rssi < rssi_thresh) {
225 wifi_rssi_state = BTC_RSSI_STATE_LOW;
226 BTC_PRINT(BTC_MSG_ALGORITHM,
227 ALGO_WIFI_RSSI_STATE,
228 "[BTCoex], wifi RSSI state switch to Low\n");
229 } else {
230 wifi_rssi_state = BTC_RSSI_STATE_STAY_MEDIUM;
231 BTC_PRINT(BTC_MSG_ALGORITHM,
232 ALGO_WIFI_RSSI_STATE,
233 "[BTCoex], wifi RSSI state stay at Medium\n");
234 }
235 } else {
236 if (wifi_rssi < rssi_thresh1) {
237 wifi_rssi_state = BTC_RSSI_STATE_MEDIUM;
238 BTC_PRINT(BTC_MSG_ALGORITHM,
239 ALGO_WIFI_RSSI_STATE,
240 "[BTCoex], wifi RSSI state switch to Medium\n");
241 } else {
242 wifi_rssi_state = BTC_RSSI_STATE_STAY_HIGH;
243 BTC_PRINT(BTC_MSG_ALGORITHM,
244 ALGO_WIFI_RSSI_STATE,
245 "[BTCoex], wifi RSSI state stay at High\n");
246 }
247 }
248 }
249 coex_sta->pre_wifi_rssi_state[index] = wifi_rssi_state;
250
251 return wifi_rssi_state;
252}
253
254static void halbtc8821a1ant_update_ra_mask(struct btc_coexist *btcoexist,
255 bool force_exec, u32 dis_rate_mask)
256{
257 coex_dm->cur_ra_mask = dis_rate_mask;
258
259 if (force_exec ||
260 (coex_dm->pre_ra_mask != coex_dm->cur_ra_mask)) {
261 btcoexist->btc_set(btcoexist, BTC_SET_ACT_UPDATE_ra_mask,
262 &coex_dm->cur_ra_mask);
263 }
264 coex_dm->pre_ra_mask = coex_dm->cur_ra_mask;
265}
266
267static void btc8821a1ant_auto_rate_fb_retry(struct btc_coexist *btcoexist,
268 bool force_exec, u8 type)
269{
270 bool wifi_under_b_mode = false;
271
272 coex_dm->cur_arfr_type = type;
273
274 if (force_exec ||
275 (coex_dm->pre_arfr_type != coex_dm->cur_arfr_type)) {
276 switch (coex_dm->cur_arfr_type) {
277 case 0: /* normal mode*/
278 btcoexist->btc_write_4byte(btcoexist, 0x430,
279 coex_dm->backup_arfr_cnt1);
280 btcoexist->btc_write_4byte(btcoexist, 0x434,
281 coex_dm->backup_arfr_cnt2);
282 break;
283 case 1:
284 btcoexist->btc_get(btcoexist,
285 BTC_GET_BL_WIFI_UNDER_B_MODE,
286 &wifi_under_b_mode);
287 if (wifi_under_b_mode) {
288 btcoexist->btc_write_4byte(btcoexist, 0x430,
289 0x0);
290 btcoexist->btc_write_4byte(btcoexist, 0x434,
291 0x01010101);
292 } else {
293 btcoexist->btc_write_4byte(btcoexist, 0x430,
294 0x0);
295 btcoexist->btc_write_4byte(btcoexist, 0x434,
296 0x04030201);
297 }
298 break;
299 default:
300 break;
301 }
302 }
303
304 coex_dm->pre_arfr_type = coex_dm->cur_arfr_type;
305}
306
307static void halbtc8821a1ant_retry_limit(struct btc_coexist *btcoexist,
308 bool force_exec, u8 type)
309{
310 coex_dm->cur_retry_limit_type = type;
311
312 if (force_exec ||
313 (coex_dm->pre_retry_limit_type != coex_dm->cur_retry_limit_type)) {
314 switch (coex_dm->cur_retry_limit_type) {
315 case 0: /* normal mode*/
316 btcoexist->btc_write_2byte(btcoexist, 0x42a,
317 coex_dm->backup_retry_limit);
318 break;
319 case 1: /* retry limit = 8*/
320 btcoexist->btc_write_2byte(btcoexist, 0x42a, 0x0808);
321 break;
322 default:
323 break;
324 }
325 }
326 coex_dm->pre_retry_limit_type = coex_dm->cur_retry_limit_type;
327}
328
329static void halbtc8821a1ant_ampdu_max_time(struct btc_coexist *btcoexist,
330 bool force_exec, u8 type)
331{
332 coex_dm->cur_ampdu_time_type = type;
333
334 if (force_exec ||
335 (coex_dm->pre_ampdu_time_type != coex_dm->cur_ampdu_time_type)) {
336 switch (coex_dm->cur_ampdu_time_type) {
337 case 0: /* normal mode*/
338 btcoexist->btc_write_1byte(btcoexist, 0x456,
339 coex_dm->backup_ampdu_max_time);
340 break;
341 case 1: /* AMPDU timw = 0x38 * 32us*/
342 btcoexist->btc_write_1byte(btcoexist, 0x456, 0x38);
343 break;
344 default:
345 break;
346 }
347 }
348
349 coex_dm->pre_ampdu_time_type = coex_dm->cur_ampdu_time_type;
350}
351
352static void halbtc8821a1ant_limited_tx(struct btc_coexist *btcoexist,
353 bool force_exec, u8 ra_mask_type,
354 u8 arfr_type, u8 retry_limit_type,
355 u8 ampdu_time_type)
356{
357 switch (ra_mask_type) {
358 case 0: /* normal mode*/
359 halbtc8821a1ant_update_ra_mask(btcoexist, force_exec, 0x0);
360 break;
361 case 1: /* disable cck 1/2*/
362 halbtc8821a1ant_update_ra_mask(btcoexist, force_exec,
363 0x00000003);
364 break;
365 case 2: /* disable cck 1/2/5.5, ofdm 6/9/12/18/24, mcs 0/1/2/3/4*/
366 halbtc8821a1ant_update_ra_mask(btcoexist, force_exec,
367 0x0001f1f7);
368 break;
369 default:
370 break;
371 }
372
373 btc8821a1ant_auto_rate_fb_retry(btcoexist, force_exec, arfr_type);
374 halbtc8821a1ant_retry_limit(btcoexist, force_exec, retry_limit_type);
375 halbtc8821a1ant_ampdu_max_time(btcoexist, force_exec, ampdu_time_type);
376}
377
378static void halbtc8821a1ant_limited_rx(struct btc_coexist *btcoexist,
379 bool force_exec, bool rej_ap_agg_pkt,
380 bool bt_ctrl_agg_buf_size,
381 u8 agg_buf_size)
382{
383 bool reject_rx_agg = rej_ap_agg_pkt;
384 bool bt_ctrl_rx_agg_size = bt_ctrl_agg_buf_size;
385 u8 rx_agg_size = agg_buf_size;
386
387 /*============================================*/
388 /* Rx Aggregation related setting*/
389 /*============================================*/
390 btcoexist->btc_set(btcoexist,
391 BTC_SET_BL_TO_REJ_AP_AGG_PKT, &reject_rx_agg);
392 /* decide BT control aggregation buf size or not*/
393 btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_CTRL_AGG_SIZE,
394 &bt_ctrl_rx_agg_size);
395 /* aggregation buf size, only work when BT control Rx agg size.*/
396 btcoexist->btc_set(btcoexist, BTC_SET_U1_AGG_BUF_SIZE, &rx_agg_size);
397 /* real update aggregation setting*/
398 btcoexist->btc_set(btcoexist, BTC_SET_ACT_AGGREGATE_CTRL, NULL);
399}
400
401static void halbtc8821a1ant_monitor_bt_ctr(struct btc_coexist *btcoexist)
402{
403 u32 reg_hp_tx_rx, reg_lp_tx_rx, u4_tmp;
404 u32 reg_hp_tx = 0, reg_hp_rx = 0, reg_lp_tx = 0, reg_lp_rx = 0;
405
406 reg_hp_tx_rx = 0x770;
407 reg_lp_tx_rx = 0x774;
408
409 u4_tmp = btcoexist->btc_read_4byte(btcoexist, reg_hp_tx_rx);
410 reg_hp_tx = u4_tmp & MASKLWORD;
411 reg_hp_rx = (u4_tmp & MASKHWORD)>>16;
412
413 u4_tmp = btcoexist->btc_read_4byte(btcoexist, reg_lp_tx_rx);
414 reg_lp_tx = u4_tmp & MASKLWORD;
415 reg_lp_rx = (u4_tmp & MASKHWORD)>>16;
416
417 coex_sta->high_priority_tx = reg_hp_tx;
418 coex_sta->high_priority_rx = reg_hp_rx;
419 coex_sta->low_priority_tx = reg_lp_tx;
420 coex_sta->low_priority_rx = reg_lp_rx;
421
422 /* reset counter*/
423 btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc);
424}
425
426static void halbtc8821a1ant_query_bt_info(struct btc_coexist *btcoexist)
427{
428 u8 h2c_parameter[1] = {0};
429
430 coex_sta->c2h_bt_info_req_sent = true;
431
432 h2c_parameter[0] |= BIT0; /* trigger*/
433
434 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
435 "[BTCoex], Query Bt Info, FW write 0x61 = 0x%x\n",
436 h2c_parameter[0]);
437
438 btcoexist->btc_fill_h2c(btcoexist, 0x61, 1, h2c_parameter);
439}
440
441static void halbtc8821a1ant_update_bt_link_info(struct btc_coexist *btcoexist)
442{
443 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
444 bool bt_hs_on = false;
445
446 btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
447
448 bt_link_info->bt_link_exist = coex_sta->bt_link_exist;
449 bt_link_info->sco_exist = coex_sta->sco_exist;
450 bt_link_info->a2dp_exist = coex_sta->a2dp_exist;
451 bt_link_info->pan_exist = coex_sta->pan_exist;
452 bt_link_info->hid_exist = coex_sta->hid_exist;
453
454 /* work around for HS mode.*/
455 if (bt_hs_on) {
456 bt_link_info->pan_exist = true;
457 bt_link_info->bt_link_exist = true;
458 }
459
460 /* check if Sco only*/
461 if (bt_link_info->sco_exist &&
462 !bt_link_info->a2dp_exist &&
463 !bt_link_info->pan_exist &&
464 !bt_link_info->hid_exist)
465 bt_link_info->sco_only = true;
466 else
467 bt_link_info->sco_only = false;
468
469 /* check if A2dp only*/
470 if (!bt_link_info->sco_exist &&
471 bt_link_info->a2dp_exist &&
472 !bt_link_info->pan_exist &&
473 !bt_link_info->hid_exist)
474 bt_link_info->a2dp_only = true;
475 else
476 bt_link_info->a2dp_only = false;
477
478 /* check if Pan only*/
479 if (!bt_link_info->sco_exist &&
480 !bt_link_info->a2dp_exist &&
481 bt_link_info->pan_exist &&
482 !bt_link_info->hid_exist)
483 bt_link_info->pan_only = true;
484 else
485 bt_link_info->pan_only = false;
486
487 /* check if Hid only*/
488 if (!bt_link_info->sco_exist &&
489 !bt_link_info->a2dp_exist &&
490 !bt_link_info->pan_exist &&
491 bt_link_info->hid_exist)
492 bt_link_info->hid_only = true;
493 else
494 bt_link_info->hid_only = false;
495}
496
497static u8 halbtc8821a1ant_action_algorithm(struct btc_coexist *btcoexist)
498{
499 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
500 bool bt_hs_on = false;
501 u8 algorithm = BT_8821A_1ANT_COEX_ALGO_UNDEFINED;
502 u8 num_of_diff_profile = 0;
503
504 btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
505
506 if (!bt_link_info->bt_link_exist) {
507 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
508 "[BTCoex], No BT link exists!!!\n");
509 return algorithm;
510 }
511
512 if (bt_link_info->sco_exist)
513 num_of_diff_profile++;
514 if (bt_link_info->hid_exist)
515 num_of_diff_profile++;
516 if (bt_link_info->pan_exist)
517 num_of_diff_profile++;
518 if (bt_link_info->a2dp_exist)
519 num_of_diff_profile++;
520
521 if (num_of_diff_profile == 1) {
522 if (bt_link_info->sco_exist) {
523 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
524 "[BTCoex], BT Profile = SCO only\n");
525 algorithm = BT_8821A_1ANT_COEX_ALGO_SCO;
526 } else {
527 if (bt_link_info->hid_exist) {
528 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
529 "[BTCoex], BT Profile = HID only\n");
530 algorithm = BT_8821A_1ANT_COEX_ALGO_HID;
531 } else if (bt_link_info->a2dp_exist) {
532 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
533 "[BTCoex], BT Profile = A2DP only\n");
534 algorithm = BT_8821A_1ANT_COEX_ALGO_A2DP;
535 } else if (bt_link_info->pan_exist) {
536 if (bt_hs_on) {
537 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
538 "[BTCoex], BT Profile = PAN(HS) only\n");
539 algorithm = BT_8821A_1ANT_COEX_ALGO_PANHS;
540 } else {
541 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
542 "[BTCoex], BT Profile = PAN(EDR) only\n");
543 algorithm = BT_8821A_1ANT_COEX_ALGO_PANEDR;
544 }
545 }
546 }
547 } else if (num_of_diff_profile == 2) {
548 if (bt_link_info->sco_exist) {
549 if (bt_link_info->hid_exist) {
550 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
551 "[BTCoex], BT Profile = SCO + HID\n");
552 algorithm = BT_8821A_1ANT_COEX_ALGO_HID;
553 } else if (bt_link_info->a2dp_exist) {
554 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
555 "[BTCoex], BT Profile = SCO + A2DP ==> SCO\n");
556 algorithm = BT_8821A_1ANT_COEX_ALGO_SCO;
557 } else if (bt_link_info->pan_exist) {
558 if (bt_hs_on) {
559 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
560 "[BTCoex], BT Profile = SCO + PAN(HS)\n");
561 algorithm = BT_8821A_1ANT_COEX_ALGO_SCO;
562 } else {
563 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
564 "[BTCoex], BT Profile = SCO + PAN(EDR)\n");
565 algorithm = BT_8821A_1ANT_COEX_ALGO_PANEDR_HID;
566 }
567 }
568 } else {
569 if (bt_link_info->hid_exist &&
570 bt_link_info->a2dp_exist) {
571 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
572 "[BTCoex], BT Profile = HID + A2DP\n");
573 algorithm = BT_8821A_1ANT_COEX_ALGO_HID_A2DP;
574 } else if (bt_link_info->hid_exist &&
575 bt_link_info->pan_exist) {
576 if (bt_hs_on) {
577 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
578 "[BTCoex], BT Profile = HID + PAN(HS)\n");
579 algorithm = BT_8821A_1ANT_COEX_ALGO_HID_A2DP;
580 } else {
581 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
582 "[BTCoex], BT Profile = HID + PAN(EDR)\n");
583 algorithm = BT_8821A_1ANT_COEX_ALGO_PANEDR_HID;
584 }
585 } else if (bt_link_info->pan_exist &&
586 bt_link_info->a2dp_exist) {
587 if (bt_hs_on) {
588 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
589 "[BTCoex], BT Profile = A2DP + PAN(HS)\n");
590 algorithm = BT_8821A_1ANT_COEX_ALGO_A2DP_PANHS;
591 } else {
592 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
593 "[BTCoex], BT Profile = A2DP + PAN(EDR)\n");
594 algorithm = BT_8821A_1ANT_COEX_ALGO_PANEDR_A2DP;
595 }
596 }
597 }
598 } else if (num_of_diff_profile == 3) {
599 if (bt_link_info->sco_exist) {
600 if (bt_link_info->hid_exist &&
601 bt_link_info->a2dp_exist) {
602 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
603 "[BTCoex], BT Profile = SCO + HID + A2DP ==> HID\n");
604 algorithm = BT_8821A_1ANT_COEX_ALGO_HID;
605 } else if (bt_link_info->hid_exist &&
606 bt_link_info->pan_exist) {
607 if (bt_hs_on) {
608 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
609 "[BTCoex], BT Profile = SCO + HID + PAN(HS)\n");
610 algorithm = BT_8821A_1ANT_COEX_ALGO_HID_A2DP;
611 } else {
612 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
613 "[BTCoex], BT Profile = SCO + HID + PAN(EDR)\n");
614 algorithm = BT_8821A_1ANT_COEX_ALGO_PANEDR_HID;
615 }
616 } else if (bt_link_info->pan_exist &&
617 bt_link_info->a2dp_exist) {
618 if (bt_hs_on) {
619 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
620 "[BTCoex], BT Profile = SCO + A2DP + PAN(HS)\n");
621 algorithm = BT_8821A_1ANT_COEX_ALGO_SCO;
622 } else {
623 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
624 "[BTCoex], BT Profile = SCO + A2DP + PAN(EDR) ==> HID\n");
625 algorithm = BT_8821A_1ANT_COEX_ALGO_PANEDR_HID;
626 }
627 }
628 } else {
629 if (bt_link_info->hid_exist &&
630 bt_link_info->pan_exist &&
631 bt_link_info->a2dp_exist) {
632 if (bt_hs_on) {
633 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
634 "[BTCoex], BT Profile = HID + A2DP + PAN(HS)\n");
635 algorithm = BT_8821A_1ANT_COEX_ALGO_HID_A2DP;
636 } else {
637 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
638 "[BTCoex], BT Profile = HID + A2DP + PAN(EDR)\n");
639 algorithm = BT_8821A_1ANT_COEX_ALGO_HID_A2DP_PANEDR;
640 }
641 }
642 }
643 } else if (num_of_diff_profile >= 3) {
644 if (bt_link_info->sco_exist) {
645 if (bt_link_info->hid_exist &&
646 bt_link_info->pan_exist &&
647 bt_link_info->a2dp_exist) {
648 if (bt_hs_on) {
649 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
650 "[BTCoex], Error!!! BT Profile = SCO + HID + A2DP + PAN(HS)\n");
651
652 } else {
653 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
654 "[BTCoex], BT Profile = SCO + HID + A2DP + PAN(EDR)==>PAN(EDR)+HID\n");
655 algorithm = BT_8821A_1ANT_COEX_ALGO_PANEDR_HID;
656 }
657 }
658 }
659 }
660 return algorithm;
661}
662
663static void halbtc8821a1ant_set_bt_auto_report(struct btc_coexist *btcoexist,
664 bool enable_auto_report)
665{
666 u8 h2c_parameter[1] = {0};
667
668 h2c_parameter[0] = 0;
669
670 if (enable_auto_report)
671 h2c_parameter[0] |= BIT0;
672
673 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
674 "[BTCoex], BT FW auto report : %s, FW write 0x68 = 0x%x\n",
675 (enable_auto_report ? "Enabled!!" : "Disabled!!"),
676 h2c_parameter[0]);
677
678 btcoexist->btc_fill_h2c(btcoexist, 0x68, 1, h2c_parameter);
679}
680
681static void halbtc8821a1ant_bt_auto_report(struct btc_coexist *btcoexist,
682 bool force_exec,
683 bool enable_auto_report)
684{
685 BTC_PRINT(BTC_MSG_ALGORITHM,
686 ALGO_TRACE_FW, "[BTCoex], %s BT Auto report = %s\n",
687 (force_exec ? "force to" : ""), ((enable_auto_report) ?
688 "Enabled" : "Disabled"));
689 coex_dm->cur_bt_auto_report = enable_auto_report;
690
691 if (!force_exec) {
692 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
693 "[BTCoex], pre_bt_auto_report = %d, cur_bt_auto_report = %d\n",
694 coex_dm->pre_bt_auto_report,
695 coex_dm->cur_bt_auto_report);
696
697 if (coex_dm->pre_bt_auto_report == coex_dm->cur_bt_auto_report)
698 return;
699 }
700 halbtc8821a1ant_set_bt_auto_report(btcoexist, coex_dm->cur_bt_auto_report);
701
702 coex_dm->pre_bt_auto_report = coex_dm->cur_bt_auto_report;
703}
704
705static void btc8821a1ant_set_sw_pen_tx_rate(struct btc_coexist *btcoexist,
706 bool low_penalty_ra)
707{
708 u8 h2c_parameter[6] = {0};
709
710 h2c_parameter[0] = 0x6; /* opCode, 0x6= Retry_Penalty*/
711
712 if (low_penalty_ra) {
713 h2c_parameter[1] |= BIT0;
714 /*normal rate except MCS7/6/5, OFDM54/48/36*/
715 h2c_parameter[2] = 0x00;
716 h2c_parameter[3] = 0xf7; /*MCS7 or OFDM54*/
717 h2c_parameter[4] = 0xf8; /*MCS6 or OFDM48*/
718 h2c_parameter[5] = 0xf9; /*MCS5 or OFDM36*/
719 }
720
721 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
722 "[BTCoex], set WiFi Low-Penalty Retry: %s",
723 (low_penalty_ra ? "ON!!" : "OFF!!"));
724
725 btcoexist->btc_fill_h2c(btcoexist, 0x69, 6, h2c_parameter);
726}
727
728static void halbtc8821a1ant_low_penalty_ra(struct btc_coexist *btcoexist,
729 bool force_exec, bool low_penalty_ra)
730{
731 coex_dm->cur_low_penalty_ra = low_penalty_ra;
732
733 if (!force_exec) {
734 if (coex_dm->pre_low_penalty_ra == coex_dm->cur_low_penalty_ra)
735 return;
736 }
737 btc8821a1ant_set_sw_pen_tx_rate(btcoexist, coex_dm->cur_low_penalty_ra);
738
739 coex_dm->pre_low_penalty_ra = coex_dm->cur_low_penalty_ra;
740}
741
742static void halbtc8821a1ant_set_coex_table(struct btc_coexist *btcoexist,
743 u32 val0x6c0, u32 val0x6c4,
744 u32 val0x6c8, u8 val0x6cc)
745{
746 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
747 "[BTCoex], set coex table, set 0x6c0 = 0x%x\n", val0x6c0);
748 btcoexist->btc_write_4byte(btcoexist, 0x6c0, val0x6c0);
749
750 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
751 "[BTCoex], set coex table, set 0x6c4 = 0x%x\n", val0x6c4);
752 btcoexist->btc_write_4byte(btcoexist, 0x6c4, val0x6c4);
753
754 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
755 "[BTCoex], set coex table, set 0x6c8 = 0x%x\n", val0x6c8);
756 btcoexist->btc_write_4byte(btcoexist, 0x6c8, val0x6c8);
757
758 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
759 "[BTCoex], set coex table, set 0x6cc = 0x%x\n", val0x6cc);
760 btcoexist->btc_write_1byte(btcoexist, 0x6cc, val0x6cc);
761}
762
763static void halbtc8821a1ant_coex_table(struct btc_coexist *btcoexist,
764 bool force_exec, u32 val0x6c0,
765 u32 val0x6c4, u32 val0x6c8, u8 val0x6cc)
766{
767 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW,
768 "[BTCoex], %s write Coex Table 0x6c0 = 0x%x, 0x6c4 = 0x%x, 0x6c8 = 0x%x, 0x6cc = 0x%x\n",
769 (force_exec ? "force to" : ""), val0x6c0, val0x6c4,
770 val0x6c8, val0x6cc);
771 coex_dm->cur_val_0x6c0 = val0x6c0;
772 coex_dm->cur_val_0x6c4 = val0x6c4;
773 coex_dm->cur_val_0x6c8 = val0x6c8;
774 coex_dm->cur_val_0x6cc = val0x6cc;
775
776 if (!force_exec) {
777 if ((coex_dm->pre_val_0x6c0 == coex_dm->cur_val_0x6c0) &&
778 (coex_dm->pre_val_0x6c4 == coex_dm->cur_val_0x6c4) &&
779 (coex_dm->pre_val_0x6c8 == coex_dm->cur_val_0x6c8) &&
780 (coex_dm->pre_val_0x6cc == coex_dm->cur_val_0x6cc))
781 return;
782 }
783 halbtc8821a1ant_set_coex_table(btcoexist, val0x6c0, val0x6c4,
784 val0x6c8, val0x6cc);
785
786 coex_dm->pre_val_0x6c0 = coex_dm->cur_val_0x6c0;
787 coex_dm->pre_val_0x6c4 = coex_dm->cur_val_0x6c4;
788 coex_dm->pre_val_0x6c8 = coex_dm->cur_val_0x6c8;
789 coex_dm->pre_val_0x6cc = coex_dm->cur_val_0x6cc;
790}
791
792static void halbtc8821a1ant_coex_table_with_type(struct btc_coexist *btcoexist,
793 bool force_exec, u8 type)
794{
795 switch (type) {
796 case 0:
797 halbtc8821a1ant_coex_table(btcoexist, force_exec, 0x55555555,
798 0x55555555, 0xffffff, 0x3);
799 break;
800 case 1:
801 halbtc8821a1ant_coex_table(btcoexist, force_exec,
802 0x55555555, 0x5a5a5a5a,
803 0xffffff, 0x3);
804 break;
805 case 2:
806 halbtc8821a1ant_coex_table(btcoexist, force_exec, 0x5a5a5a5a,
807 0x5a5a5a5a, 0xffffff, 0x3);
808 break;
809 case 3:
810 halbtc8821a1ant_coex_table(btcoexist, force_exec, 0x55555555,
811 0xaaaaaaaa, 0xffffff, 0x3);
812 break;
813 case 4:
814 halbtc8821a1ant_coex_table(btcoexist, force_exec, 0xffffffff,
815 0xffffffff, 0xffffff, 0x3);
816 break;
817 case 5:
818 halbtc8821a1ant_coex_table(btcoexist, force_exec, 0x5fff5fff,
819 0x5fff5fff, 0xffffff, 0x3);
820 break;
821 case 6:
822 halbtc8821a1ant_coex_table(btcoexist, force_exec, 0x55ff55ff,
823 0x5a5a5a5a, 0xffffff, 0x3);
824 break;
825 case 7:
826 halbtc8821a1ant_coex_table(btcoexist, force_exec, 0x5afa5afa,
827 0x5afa5afa, 0xffffff, 0x3);
828 break;
829 default:
830 break;
831 }
832}
833
834static void btc8821a1ant_set_fw_ignore_wlan_act(struct btc_coexist *btcoexist,
835 bool enable)
836{
837 u8 h2c_parameter[1] = {0};
838
839 if (enable)
840 h2c_parameter[0] |= BIT0; /* function enable*/
841
842 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
843 "[BTCoex], set FW for BT Ignore Wlan_Act, FW write 0x63 = 0x%x\n",
844 h2c_parameter[0]);
845
846 btcoexist->btc_fill_h2c(btcoexist, 0x63, 1, h2c_parameter);
847}
848
849static void halbtc8821a1ant_ignore_wlan_act(struct btc_coexist *btcoexist,
850 bool force_exec, bool enable)
851{
852 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW,
853 "[BTCoex], %s turn Ignore WlanAct %s\n",
854 (force_exec ? "force to" : ""), (enable ? "ON" : "OFF"));
855 coex_dm->cur_ignore_wlan_act = enable;
856
857 if (!force_exec) {
858 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
859 "[BTCoex], pre_ignore_wlan_act = %d, cur_ignore_wlan_act = %d!!\n",
860 coex_dm->pre_ignore_wlan_act,
861 coex_dm->cur_ignore_wlan_act);
862
863 if (coex_dm->pre_ignore_wlan_act ==
864 coex_dm->cur_ignore_wlan_act)
865 return;
866 }
867 btc8821a1ant_set_fw_ignore_wlan_act(btcoexist, enable);
868
869 coex_dm->pre_ignore_wlan_act = coex_dm->cur_ignore_wlan_act;
870}
871
872static void halbtc8821a1ant_set_fw_pstdma(struct btc_coexist *btcoexist,
873 u8 byte1, u8 byte2, u8 byte3,
874 u8 byte4, u8 byte5)
875{
876 u8 h2c_parameter[5] = {0};
877
878 h2c_parameter[0] = byte1;
879 h2c_parameter[1] = byte2;
880 h2c_parameter[2] = byte3;
881 h2c_parameter[3] = byte4;
882 h2c_parameter[4] = byte5;
883
884 coex_dm->ps_tdma_para[0] = byte1;
885 coex_dm->ps_tdma_para[1] = byte2;
886 coex_dm->ps_tdma_para[2] = byte3;
887 coex_dm->ps_tdma_para[3] = byte4;
888 coex_dm->ps_tdma_para[4] = byte5;
889
890 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
891 "[BTCoex], PS-TDMA H2C cmd =0x%x%08x\n",
892 h2c_parameter[0],
893 h2c_parameter[1]<<24 |
894 h2c_parameter[2]<<16 |
895 h2c_parameter[3]<<8 |
896 h2c_parameter[4]);
897 btcoexist->btc_fill_h2c(btcoexist, 0x60, 5, h2c_parameter);
898}
899
900static void halbtc8821a1ant_set_lps_rpwm(struct btc_coexist *btcoexist,
901 u8 lps_val, u8 rpwm_val)
902{
903 u8 lps = lps_val;
904 u8 rpwm = rpwm_val;
905
906 btcoexist->btc_set(btcoexist, BTC_SET_U1_LPS_VAL, &lps);
907 btcoexist->btc_set(btcoexist, BTC_SET_U1_RPWM_VAL, &rpwm);
908}
909
910static void halbtc8821a1ant_lps_rpwm(struct btc_coexist *btcoexist,
911 bool force_exec, u8 lps_val, u8 rpwm_val)
912{
913 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW,
914 "[BTCoex], %s set lps/rpwm = 0x%x/0x%x\n",
915 (force_exec ? "force to" : ""), lps_val, rpwm_val);
916 coex_dm->cur_lps = lps_val;
917 coex_dm->cur_rpwm = rpwm_val;
918
919 if (!force_exec) {
920 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
921 "[BTCoex], LPS-RxBeaconMode = 0x%x, LPS-RPWM = 0x%x!!\n",
922 coex_dm->cur_lps, coex_dm->cur_rpwm);
923
924 if ((coex_dm->pre_lps == coex_dm->cur_lps) &&
925 (coex_dm->pre_rpwm == coex_dm->cur_rpwm)) {
926 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
927 "[BTCoex], LPS-RPWM_Last = 0x%x, LPS-RPWM_Now = 0x%x!!\n",
928 coex_dm->pre_rpwm, coex_dm->cur_rpwm);
929
930 return;
931 }
932 }
933 halbtc8821a1ant_set_lps_rpwm(btcoexist, lps_val, rpwm_val);
934
935 coex_dm->pre_lps = coex_dm->cur_lps;
936 coex_dm->pre_rpwm = coex_dm->cur_rpwm;
937}
938
939static void halbtc8821a1ant_sw_mechanism(struct btc_coexist *btcoexist,
940 bool low_penalty_ra)
941{
942 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR,
943 "[BTCoex], SM[LpRA] = %d\n", low_penalty_ra);
944
945 halbtc8821a1ant_low_penalty_ra(btcoexist, NORMAL_EXEC, low_penalty_ra);
946}
947
948static void halbtc8821a1ant_set_ant_path(struct btc_coexist *btcoexist,
949 u8 ant_pos_type, bool init_hw_cfg,
950 bool wifi_off)
951{
952 struct btc_board_info *board_info = &btcoexist->board_info;
953 u32 u4_tmp = 0;
954 u8 h2c_parameter[2] = {0};
955
956 if (init_hw_cfg) {
957 /* 0x4c[23] = 0, 0x4c[24] = 1 Antenna control by WL/BT*/
958 u4_tmp = btcoexist->btc_read_4byte(btcoexist, 0x4c);
959 u4_tmp &= ~BIT23;
960 u4_tmp |= BIT24;
961 btcoexist->btc_write_4byte(btcoexist, 0x4c, u4_tmp);
962
963 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x975, 0x3, 0x3);
964 btcoexist->btc_write_1byte(btcoexist, 0xcb4, 0x77);
965
966 if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT) {
967 /*tell firmware "antenna inverse" ==>
968 * WRONG firmware antenna control code.==>need fw to fix
969 */
970 h2c_parameter[0] = 1;
971 h2c_parameter[1] = 1;
972 btcoexist->btc_fill_h2c(btcoexist, 0x65, 2,
973 h2c_parameter);
974 /*Main Ant to BT for IPS case 0x4c[23] = 1*/
975 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x64,
976 0x1, 0x1);
977 } else {
978 /*tell firmware "no antenna inverse" ==>
979 * WRONG firmware antenna control code.==>need fw to fix
980 */
981 h2c_parameter[0] = 0;
982 h2c_parameter[1] = 1;
983 btcoexist->btc_fill_h2c(btcoexist, 0x65, 2,
984 h2c_parameter);
985 /*Aux Ant to BT for IPS case 0x4c[23] = 1*/
986 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x64,
987 0x1, 0x0);
988 }
989 } else if (wifi_off) {
990 /* 0x4c[24:23] = 00, Set Antenna control
991 * by BT_RFE_CTRL BT Vendor 0xac = 0xf002
992 */
993 u4_tmp = btcoexist->btc_read_4byte(btcoexist, 0x4c);
994 u4_tmp &= ~BIT23;
995 u4_tmp &= ~BIT24;
996 btcoexist->btc_write_4byte(btcoexist, 0x4c, u4_tmp);
997 }
998
999 /* ext switch setting*/
1000 switch (ant_pos_type) {
1001 case BTC_ANT_PATH_WIFI:
1002 if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT)
1003 btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb7,
1004 0x30, 0x1);
1005 else
1006 btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb7,
1007 0x30, 0x2);
1008 break;
1009 case BTC_ANT_PATH_BT:
1010 if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT)
1011 btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb7,
1012 0x30, 0x2);
1013 else
1014 btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb7,
1015 0x30, 0x1);
1016 break;
1017 default:
1018 case BTC_ANT_PATH_PTA:
1019 if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT)
1020 btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb7,
1021 0x30, 0x1);
1022 else
1023 btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb7,
1024 0x30, 0x2);
1025 break;
1026 }
1027}
1028
1029static void halbtc8821a1ant_ps_tdma(struct btc_coexist *btcoexist,
1030 bool force_exec, bool turn_on, u8 type)
1031{
1032 u8 rssi_adjust_val = 0;
1033
1034 coex_dm->cur_ps_tdma_on = turn_on;
1035 coex_dm->cur_ps_tdma = type;
1036
1037 if (!force_exec) {
1038 if (coex_dm->cur_ps_tdma_on) {
1039 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
1040 "[BTCoex], ********** TDMA(on, %d) **********\n",
1041 coex_dm->cur_ps_tdma);
1042 } else {
1043 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
1044 "[BTCoex], ********** TDMA(off, %d) **********\n",
1045 coex_dm->cur_ps_tdma);
1046 }
1047 if ((coex_dm->pre_ps_tdma_on == coex_dm->cur_ps_tdma_on) &&
1048 (coex_dm->pre_ps_tdma == coex_dm->cur_ps_tdma))
1049 return;
1050 }
1051 if (turn_on) {
1052 switch (type) {
1053 default:
1054 halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x51, 0x1a,
1055 0x1a, 0x0, 0x50);
1056 break;
1057 case 1:
1058 halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x51, 0x3a,
1059 0x03, 0x10, 0x50);
1060 rssi_adjust_val = 11;
1061 break;
1062 case 2:
1063 halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x51, 0x2b,
1064 0x03, 0x10, 0x50);
1065 rssi_adjust_val = 14;
1066 break;
1067 case 3:
1068 halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x51, 0x1d,
1069 0x1d, 0x0, 0x10);
1070 break;
1071 case 4:
1072 halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x93, 0x15,
1073 0x3, 0x14, 0x0);
1074 rssi_adjust_val = 17;
1075 break;
1076 case 5:
1077 halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x61, 0x15,
1078 0x3, 0x11, 0x10);
1079 break;
1080 case 6:
1081 halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x13, 0xa,
1082 0x3, 0x0, 0x0);
1083 break;
1084 case 7:
1085 halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x13, 0xc,
1086 0x5, 0x0, 0x0);
1087 break;
1088 case 8:
1089 halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x93, 0x25,
1090 0x3, 0x10, 0x0);
1091 break;
1092 case 9:
1093 halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x51, 0x21,
1094 0x3, 0x10, 0x50);
1095 rssi_adjust_val = 18;
1096 break;
1097 case 10:
1098 halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x13, 0xa,
1099 0xa, 0x0, 0x40);
1100 break;
1101 case 11:
1102 halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x51, 0x14,
1103 0x03, 0x10, 0x10);
1104 rssi_adjust_val = 20;
1105 break;
1106 case 12:
1107 halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x51, 0x0a,
1108 0x0a, 0x0, 0x50);
1109 break;
1110 case 13:
1111 halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x51, 0x18,
1112 0x18, 0x0, 0x10);
1113 break;
1114 case 14:
1115 halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x51, 0x21,
1116 0x3, 0x10, 0x10);
1117 break;
1118 case 15:
1119 halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x13, 0xa,
1120 0x3, 0x8, 0x0);
1121 break;
1122 case 16:
1123 halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x93, 0x15,
1124 0x3, 0x10, 0x0);
1125 rssi_adjust_val = 18;
1126 break;
1127 case 18:
1128 halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x93, 0x25,
1129 0x3, 0x10, 0x0);
1130 rssi_adjust_val = 14;
1131 break;
1132 case 20:
1133 halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x61, 0x35,
1134 0x03, 0x11, 0x10);
1135 break;
1136 case 21:
1137 halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x61, 0x15,
1138 0x03, 0x11, 0x10);
1139 break;
1140 case 22:
1141 halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x61, 0x25,
1142 0x03, 0x11, 0x10);
1143 break;
1144 case 23:
1145 halbtc8821a1ant_set_fw_pstdma(btcoexist, 0xe3, 0x25,
1146 0x3, 0x31, 0x18);
1147 rssi_adjust_val = 22;
1148 break;
1149 case 24:
1150 halbtc8821a1ant_set_fw_pstdma(btcoexist, 0xe3, 0x15,
1151 0x3, 0x31, 0x18);
1152 rssi_adjust_val = 22;
1153 break;
1154 case 25:
1155 halbtc8821a1ant_set_fw_pstdma(btcoexist, 0xe3, 0xa,
1156 0x3, 0x31, 0x18);
1157 rssi_adjust_val = 22;
1158 break;
1159 case 26:
1160 halbtc8821a1ant_set_fw_pstdma(btcoexist, 0xe3, 0xa,
1161 0x3, 0x31, 0x18);
1162 rssi_adjust_val = 22;
1163 break;
1164 case 27:
1165 halbtc8821a1ant_set_fw_pstdma(btcoexist, 0xe3, 0x25,
1166 0x3, 0x31, 0x98);
1167 rssi_adjust_val = 22;
1168 break;
1169 case 28:
1170 halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x69, 0x25,
1171 0x3, 0x31, 0x0);
1172 break;
1173 case 29:
1174 halbtc8821a1ant_set_fw_pstdma(btcoexist, 0xab, 0x1a,
1175 0x1a, 0x1, 0x10);
1176 break;
1177 case 30:
1178 halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x51, 0x14,
1179 0x3, 0x10, 0x50);
1180 break;
1181 case 31:
1182 halbtc8821a1ant_set_fw_pstdma(btcoexist, 0xd3, 0x1a,
1183 0x1a, 0, 0x58);
1184 break;
1185 case 32:
1186 halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x61, 0xa,
1187 0x3, 0x10, 0x0);
1188 break;
1189 case 33:
1190 halbtc8821a1ant_set_fw_pstdma(btcoexist, 0xa3, 0x25,
1191 0x3, 0x30, 0x90);
1192 break;
1193 case 34:
1194 halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x53, 0x1a,
1195 0x1a, 0x0, 0x10);
1196 break;
1197 case 35:
1198 halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x63, 0x1a,
1199 0x1a, 0x0, 0x10);
1200 break;
1201 case 36:
1202 halbtc8821a1ant_set_fw_pstdma(btcoexist, 0xd3, 0x12,
1203 0x3, 0x14, 0x50);
1204 break;
1205 }
1206 } else {
1207 /* disable PS tdma*/
1208 switch (type) {
1209 case 8: /*PTA Control*/
1210 halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x8, 0x0, 0x0,
1211 0x0, 0x0);
1212 halbtc8821a1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA,
1213 false, false);
1214 break;
1215 case 0:
1216 default: /*Software control, Antenna at BT side*/
1217 halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x0, 0x0, 0x0,
1218 0x0, 0x0);
1219 halbtc8821a1ant_set_ant_path(btcoexist, BTC_ANT_PATH_BT,
1220 false, false);
1221 break;
1222 case 9: /*Software control, Antenna at WiFi side*/
1223 halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x0, 0x0, 0x0,
1224 0x0, 0x0);
1225 halbtc8821a1ant_set_ant_path(btcoexist, BTC_ANT_PATH_WIFI,
1226 false, false);
1227 break;
1228 case 10: /* under 5G*/
1229 halbtc8821a1ant_set_fw_pstdma(btcoexist, 0x0, 0x0, 0x0,
1230 0x8, 0x0);
1231 halbtc8821a1ant_set_ant_path(btcoexist, BTC_ANT_PATH_BT,
1232 false, false);
1233 break;
1234 }
1235 }
1236 rssi_adjust_val = 0;
1237 btcoexist->btc_set(btcoexist,
1238 BTC_SET_U1_RSSI_ADJ_VAL_FOR_1ANT_COEX_TYPE, &rssi_adjust_val);
1239
1240 /* update pre state*/
1241 coex_dm->pre_ps_tdma_on = coex_dm->cur_ps_tdma_on;
1242 coex_dm->pre_ps_tdma = coex_dm->cur_ps_tdma;
1243}
1244
1245static bool halbtc8821a1ant_is_common_action(struct btc_coexist *btcoexist)
1246{
1247 bool common = false, wifi_connected = false, wifi_busy = false;
1248
1249 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
1250 &wifi_connected);
1251 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
1252
1253 if (!wifi_connected &&
1254 BT_8821A_1ANT_BT_STATUS_NON_CONNECTED_IDLE ==
1255 coex_dm->bt_status) {
1256 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
1257 "[BTCoex], Wifi non connected-idle + BT non connected-idle!!\n");
1258 halbtc8821a1ant_sw_mechanism(btcoexist, false);
1259
1260 common = true;
1261 } else if (wifi_connected &&
1262 (BT_8821A_1ANT_BT_STATUS_NON_CONNECTED_IDLE ==
1263 coex_dm->bt_status)) {
1264 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
1265 "[BTCoex], Wifi connected + BT non connected-idle!!\n");
1266 halbtc8821a1ant_sw_mechanism(btcoexist, false);
1267
1268 common = true;
1269 } else if (!wifi_connected &&
1270 (BT_8821A_1ANT_BT_STATUS_CONNECTED_IDLE ==
1271 coex_dm->bt_status)) {
1272 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
1273 "[BTCoex], Wifi non connected-idle + BT connected-idle!!\n");
1274 halbtc8821a1ant_sw_mechanism(btcoexist, false);
1275
1276 common = true;
1277 } else if (wifi_connected &&
1278 (BT_8821A_1ANT_BT_STATUS_CONNECTED_IDLE ==
1279 coex_dm->bt_status)) {
1280 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
1281 "[BTCoex], Wifi connected + BT connected-idle!!\n");
1282 halbtc8821a1ant_sw_mechanism(btcoexist, false);
1283
1284 common = true;
1285 } else if (!wifi_connected &&
1286 (BT_8821A_1ANT_BT_STATUS_CONNECTED_IDLE !=
1287 coex_dm->bt_status)) {
1288 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
1289 "[BTCoex], Wifi non connected-idle + BT Busy!!\n");
1290 halbtc8821a1ant_sw_mechanism(btcoexist, false);
1291
1292 common = true;
1293 } else {
1294 if (wifi_busy) {
1295 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
1296 "[BTCoex], Wifi Connected-Busy + BT Busy!!\n");
1297 } else {
1298 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
1299 "[BTCoex], Wifi Connected-Idle + BT Busy!!\n");
1300 }
1301
1302 common = false;
1303 }
1304
1305 return common;
1306}
1307
1308static void btc8821a1ant_tdma_dur_adj(struct btc_coexist *btcoexist,
1309 u8 wifi_status)
1310{
1311 static long up, dn, m, n, wait_count;
1312 /*0: no change, +1: increase WiFi duration, -1: decrease WiFi duration*/
1313 long result;
1314 u8 retry_count = 0, bt_info_ext;
1315
1316 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW,
1317 "[BTCoex], TdmaDurationAdjustForAcl()\n");
1318
1319 if ((BT_8821A_1ANT_WIFI_STATUS_NON_CONNECTED_ASSO_AUTH_SCAN ==
1320 wifi_status) ||
1321 (BT_8821A_1ANT_WIFI_STATUS_CONNECTED_SCAN ==
1322 wifi_status) ||
1323 (BT_8821A_1ANT_WIFI_STATUS_CONNECTED_SPECIAL_PKT ==
1324 wifi_status)) {
1325 if (coex_dm->cur_ps_tdma != 1 &&
1326 coex_dm->cur_ps_tdma != 2 &&
1327 coex_dm->cur_ps_tdma != 3 &&
1328 coex_dm->cur_ps_tdma != 9) {
1329 halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC,
1330 true, 9);
1331 coex_dm->tdma_adj_type = 9;
1332
1333 up = 0;
1334 dn = 0;
1335 m = 1;
1336 n = 3;
1337 result = 0;
1338 wait_count = 0;
1339 }
1340 return;
1341 }
1342
1343 if (!coex_dm->auto_tdma_adjust) {
1344 coex_dm->auto_tdma_adjust = true;
1345 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
1346 "[BTCoex], first run TdmaDurationAdjust()!!\n");
1347
1348 halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 2);
1349 coex_dm->tdma_adj_type = 2;
1350 /*============*/
1351 up = 0;
1352 dn = 0;
1353 m = 1;
1354 n = 3;
1355 result = 0;
1356 wait_count = 0;
1357 } else {
1358 /*accquire the BT TRx retry count from BT_Info byte2*/
1359 retry_count = coex_sta->bt_retry_cnt;
1360 bt_info_ext = coex_sta->bt_info_ext;
1361 result = 0;
1362 wait_count++;
1363
1364 if (retry_count == 0) {
1365 /* no retry in the last 2-second duration*/
1366 up++;
1367 dn--;
1368
1369 if (dn <= 0)
1370 dn = 0;
1371
1372 if (up >= n) {
1373 /* if (retry count == 0) for 2*n seconds ,
1374 * make WiFi duration wider
1375 */
1376 wait_count = 0;
1377 n = 3;
1378 up = 0;
1379 dn = 0;
1380 result = 1;
1381 BTC_PRINT(BTC_MSG_ALGORITHM,
1382 ALGO_TRACE_FW_DETAIL,
1383 "[BTCoex], Increase wifi duration!!\n");
1384 }
1385 } else if (retry_count <= 3) {
1386 /* <=3 retry in the last 2-second duration*/
1387 up--;
1388 dn++;
1389
1390 if (up <= 0)
1391 up = 0;
1392
1393 if (dn == 2) {
1394 /* if retry count< 3 for 2*2 seconds,
1395 * shrink wifi duration
1396 */
1397 if (wait_count <= 2)
1398 m++; /* avoid bounce in two levels */
1399 else
1400 m = 1;
1401
1402 if (m >= 20) {
1403 /* m max value is 20, max time is 120 s,
1404 * recheck if adjust WiFi duration.
1405 */
1406 m = 20;
1407 }
1408 n = 3*m;
1409 up = 0;
1410 dn = 0;
1411 wait_count = 0;
1412 result = -1;
1413 BTC_PRINT(BTC_MSG_ALGORITHM,
1414 ALGO_TRACE_FW_DETAIL,
1415 "[BTCoex], Decrease wifi duration for retryCounter<3!!\n");
1416 }
1417 } else {
1418 /* retry count > 3, if retry count > 3 happens once,
1419 * shrink WiFi duration
1420 */
1421 if (wait_count == 1)
1422 m++; /* avoid bounce in two levels */
1423 else
1424 m = 1;
1425 /* m max value is 20, max time is 120 second,
1426 * recheck if adjust WiFi duration.
1427 */
1428 if (m >= 20)
1429 m = 20;
1430
1431 n = 3*m;
1432 up = 0;
1433 dn = 0;
1434 wait_count = 0;
1435 result = -1;
1436 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
1437 "[BTCoex], Decrease wifi duration for retryCounter>3!!\n");
1438 }
1439
1440 if (result == -1) {
1441 if ((BT_INFO_8821A_1ANT_A2DP_BASIC_RATE(bt_info_ext)) &&
1442 ((coex_dm->cur_ps_tdma == 1) ||
1443 (coex_dm->cur_ps_tdma == 2))) {
1444 halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC,
1445 true, 9);
1446 coex_dm->tdma_adj_type = 9;
1447 } else if (coex_dm->cur_ps_tdma == 1) {
1448 halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC,
1449 true, 2);
1450 coex_dm->tdma_adj_type = 2;
1451 } else if (coex_dm->cur_ps_tdma == 2) {
1452 halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC,
1453 true, 9);
1454 coex_dm->tdma_adj_type = 9;
1455 } else if (coex_dm->cur_ps_tdma == 9) {
1456 halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC,
1457 true, 11);
1458 coex_dm->tdma_adj_type = 11;
1459 }
1460 } else if (result == 1) {
1461 if ((BT_INFO_8821A_1ANT_A2DP_BASIC_RATE(bt_info_ext)) &&
1462 ((coex_dm->cur_ps_tdma == 1) ||
1463 (coex_dm->cur_ps_tdma == 2))) {
1464 halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC,
1465 true, 9);
1466 coex_dm->tdma_adj_type = 9;
1467 } else if (coex_dm->cur_ps_tdma == 11) {
1468 halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC,
1469 true, 9);
1470 coex_dm->tdma_adj_type = 9;
1471 } else if (coex_dm->cur_ps_tdma == 9) {
1472 halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC,
1473 true, 2);
1474 coex_dm->tdma_adj_type = 2;
1475 } else if (coex_dm->cur_ps_tdma == 2) {
1476 halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC,
1477 true, 1);
1478 coex_dm->tdma_adj_type = 1;
1479 }
1480 } else {
1481 /*no change*/
1482 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
1483 "[BTCoex], ********** TDMA(on, %d) **********\n",
1484 coex_dm->cur_ps_tdma);
1485 }
1486
1487 if (coex_dm->cur_ps_tdma != 1 &&
1488 coex_dm->cur_ps_tdma != 2 &&
1489 coex_dm->cur_ps_tdma != 9 &&
1490 coex_dm->cur_ps_tdma != 11) {
1491 /* recover to previous adjust type*/
1492 halbtc8821a1ant_ps_tdma(btcoexist,
1493 NORMAL_EXEC, true,
1494 coex_dm->tdma_adj_type);
1495 }
1496 }
1497}
1498
1499static void btc8821a1ant_ps_tdma_check_for_pwr_save(struct btc_coexist *btcoex,
1500 bool new_ps_state)
1501{
1502 u8 lps_mode = 0x0;
1503
1504 btcoex->btc_get(btcoex, BTC_GET_U1_LPS_MODE, &lps_mode);
1505
1506 if (lps_mode) {
1507 /* already under LPS state*/
1508 if (new_ps_state) {
1509 /* keep state under LPS, do nothing.*/
1510 } else {
1511 /* will leave LPS state, turn off psTdma first*/
1512 halbtc8821a1ant_ps_tdma(btcoex, NORMAL_EXEC, false, 0);
1513 }
1514 } else {
1515 /* NO PS state*/
1516 if (new_ps_state) {
1517 /* will enter LPS state, turn off psTdma first*/
1518 halbtc8821a1ant_ps_tdma(btcoex, NORMAL_EXEC, false, 0);
1519 } else {
1520 /* keep state under NO PS state, do nothing.*/
1521 }
1522 }
1523}
1524
1525static void halbtc8821a1ant_power_save_state(struct btc_coexist *btcoexist,
1526 u8 ps_type, u8 lps_val,
1527 u8 rpwm_val)
1528{
1529 bool low_pwr_disable = false;
1530
1531 switch (ps_type) {
1532 case BTC_PS_WIFI_NATIVE:
1533 /* recover to original 32k low power setting*/
1534 low_pwr_disable = false;
1535 btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER,
1536 &low_pwr_disable);
1537 btcoexist->btc_set(btcoexist, BTC_SET_ACT_NORMAL_LPS, NULL);
1538 break;
1539 case BTC_PS_LPS_ON:
1540 btc8821a1ant_ps_tdma_check_for_pwr_save(btcoexist,
1541 true);
1542 halbtc8821a1ant_lps_rpwm(btcoexist,
1543 NORMAL_EXEC, lps_val, rpwm_val);
1544 /* when coex force to enter LPS, do not enter 32k low power.*/
1545 low_pwr_disable = true;
1546 btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER,
1547 &low_pwr_disable);
1548 /* power save must executed before psTdma.*/
1549 btcoexist->btc_set(btcoexist, BTC_SET_ACT_ENTER_LPS, NULL);
1550 break;
1551 case BTC_PS_LPS_OFF:
1552 btc8821a1ant_ps_tdma_check_for_pwr_save(btcoexist, false);
1553 btcoexist->btc_set(btcoexist, BTC_SET_ACT_LEAVE_LPS, NULL);
1554 break;
1555 default:
1556 break;
1557 }
1558}
1559
1560static void halbtc8821a1ant_coex_under_5g(struct btc_coexist *btcoexist)
1561{
1562 halbtc8821a1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE,
1563 0x0, 0x0);
1564 halbtc8821a1ant_ignore_wlan_act(btcoexist, NORMAL_EXEC, true);
1565
1566 halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 10);
1567
1568 halbtc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
1569
1570 halbtc8821a1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0);
1571
1572 halbtc8821a1ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 5);
1573}
1574
1575static void halbtc8821a1ant_action_wifi_only(struct btc_coexist *btcoexist)
1576{
1577 halbtc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
1578 halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 9);
1579}
1580
1581static void btc8821a1ant_mon_bt_en_dis(struct btc_coexist *btcoexist)
1582{
1583 static bool pre_bt_disabled;
1584 static u32 bt_disable_cnt;
1585 bool bt_active = true, bt_disabled = false;
1586
1587 /* This function check if bt is disabled*/
1588
1589 if (coex_sta->high_priority_tx == 0 &&
1590 coex_sta->high_priority_rx == 0 &&
1591 coex_sta->low_priority_tx == 0 &&
1592 coex_sta->low_priority_rx == 0) {
1593 bt_active = false;
1594 }
1595 if (coex_sta->high_priority_tx == 0xffff &&
1596 coex_sta->high_priority_rx == 0xffff &&
1597 coex_sta->low_priority_tx == 0xffff &&
1598 coex_sta->low_priority_rx == 0xffff) {
1599 bt_active = false;
1600 }
1601 if (bt_active) {
1602 bt_disable_cnt = 0;
1603 bt_disabled = false;
1604 btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_DISABLE,
1605 &bt_disabled);
1606 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR,
1607 "[BTCoex], BT is enabled !!\n");
1608 } else {
1609 bt_disable_cnt++;
1610 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR,
1611 "[BTCoex], bt all counters = 0, %d times!!\n",
1612 bt_disable_cnt);
1613 if (bt_disable_cnt >= 2) {
1614 bt_disabled = true;
1615 btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_DISABLE,
1616 &bt_disabled);
1617 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR,
1618 "[BTCoex], BT is disabled !!\n");
1619 halbtc8821a1ant_action_wifi_only(btcoexist);
1620 }
1621 }
1622 if (pre_bt_disabled != bt_disabled) {
1623 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR,
1624 "[BTCoex], BT is from %s to %s!!\n",
1625 (pre_bt_disabled ? "disabled" : "enabled"),
1626 (bt_disabled ? "disabled" : "enabled"));
1627 pre_bt_disabled = bt_disabled;
1628 if (bt_disabled) {
1629 btcoexist->btc_set(btcoexist, BTC_SET_ACT_LEAVE_LPS,
1630 NULL);
1631 btcoexist->btc_set(btcoexist, BTC_SET_ACT_NORMAL_LPS,
1632 NULL);
1633 }
1634 }
1635}
1636
1637/*=============================================*/
1638/**/
1639/* Software Coex Mechanism start*/
1640/**/
1641/*=============================================*/
1642
1643/* SCO only or SCO+PAN(HS)*/
1644static void halbtc8821a1ant_action_sco(struct btc_coexist *btcoexist)
1645{
1646 halbtc8821a1ant_sw_mechanism(btcoexist, true);
1647}
1648
1649static void halbtc8821a1ant_action_hid(struct btc_coexist *btcoexist)
1650{
1651 halbtc8821a1ant_sw_mechanism(btcoexist, true);
1652}
1653
1654/*A2DP only / PAN(EDR) only/ A2DP+PAN(HS)*/
1655static void halbtc8821a1ant_action_a2dp(struct btc_coexist *btcoexist)
1656{
1657 halbtc8821a1ant_sw_mechanism(btcoexist, false);
1658}
1659
1660static void halbtc8821a1ant_action_a2dp_pan_hs(struct btc_coexist *btcoexist)
1661{
1662 halbtc8821a1ant_sw_mechanism(btcoexist, false);
1663}
1664
1665static void halbtc8821a1ant_action_pan_edr(struct btc_coexist *btcoexist)
1666{
1667 halbtc8821a1ant_sw_mechanism(btcoexist, false);
1668}
1669
1670/*PAN(HS) only*/
1671static void halbtc8821a1ant_action_pan_hs(struct btc_coexist *btcoexist)
1672{
1673 halbtc8821a1ant_sw_mechanism(btcoexist, false);
1674}
1675
1676/*PAN(EDR)+A2DP*/
1677static void halbtc8821a1ant_action_pan_edr_a2dp(struct btc_coexist *btcoexist)
1678{
1679 halbtc8821a1ant_sw_mechanism(btcoexist, false);
1680}
1681
1682static void halbtc8821a1ant_action_pan_edr_hid(struct btc_coexist *btcoexist)
1683{
1684 halbtc8821a1ant_sw_mechanism(btcoexist, true);
1685}
1686
1687/* HID+A2DP+PAN(EDR)*/
1688static void btc8821a1ant_action_hid_a2dp_pan_edr(struct btc_coexist *btcoexist)
1689{
1690 halbtc8821a1ant_sw_mechanism(btcoexist, true);
1691}
1692
1693static void halbtc8821a1ant_action_hid_a2dp(struct btc_coexist *btcoexist)
1694{
1695 halbtc8821a1ant_sw_mechanism(btcoexist, true);
1696}
1697
1698/*=============================================*/
1699/**/
1700/* Non-Software Coex Mechanism start*/
1701/**/
1702/*=============================================*/
1703
1704static void halbtc8821a1ant_action_hs(struct btc_coexist *btcoexist)
1705{
1706 halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 5);
1707 halbtc8821a1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 2);
1708}
1709
1710static void halbtc8821a1ant_action_bt_inquiry(struct btc_coexist *btcoexist)
1711{
1712 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
1713 bool wifi_connected = false;
1714
1715 btcoexist->btc_get(btcoexist,
1716 BTC_GET_BL_WIFI_CONNECTED, &wifi_connected);
1717
1718 if (!wifi_connected) {
1719 halbtc8821a1ant_power_save_state(btcoexist,
1720 BTC_PS_WIFI_NATIVE, 0x0, 0x0);
1721 halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 5);
1722 halbtc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
1723 } else if ((bt_link_info->sco_exist) ||
1724 (bt_link_info->hid_only)) {
1725 /* SCO/HID-only busy*/
1726 halbtc8821a1ant_power_save_state(btcoexist,
1727 BTC_PS_WIFI_NATIVE, 0x0, 0x0);
1728 halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 32);
1729 halbtc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
1730 } else {
1731 halbtc8821a1ant_power_save_state(btcoexist, BTC_PS_LPS_ON,
1732 0x50, 0x4);
1733 halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 30);
1734 halbtc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
1735 }
1736}
1737
1738static void btc8821a1ant_act_bt_sco_hid_only_busy(struct btc_coexist *btcoexist,
1739 u8 wifi_status) {
1740 /* tdma and coex table*/
1741 halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 5);
1742
1743 if (BT_8821A_1ANT_WIFI_STATUS_NON_CONNECTED_ASSO_AUTH_SCAN ==
1744 wifi_status)
1745 halbtc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
1746 else
1747 halbtc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
1748}
1749
1750static void btc8821a1ant_act_wifi_con_bt_acl_busy(struct btc_coexist *btcoexist,
1751 u8 wifi_status)
1752{
1753 u8 bt_rssi_state;
1754
1755 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
1756
1757 bt_rssi_state = halbtc8821a1ant_bt_rssi_state(2, 28, 0);
1758
1759 if (bt_link_info->hid_only) {
1760 /*HID*/
1761 btc8821a1ant_act_bt_sco_hid_only_busy(btcoexist,
1762 wifi_status);
1763 coex_dm->auto_tdma_adjust = false;
1764 return;
1765 } else if (bt_link_info->a2dp_only) {
1766 /*A2DP*/
1767 if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
1768 (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
1769 btc8821a1ant_tdma_dur_adj(btcoexist, wifi_status);
1770 } else {
1771 /*for low BT RSSI*/
1772 halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC,
1773 true, 11);
1774 coex_dm->auto_tdma_adjust = false;
1775 }
1776
1777 halbtc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
1778 } else if (bt_link_info->hid_exist && bt_link_info->a2dp_exist) {
1779 /*HID+A2DP*/
1780 if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
1781 (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
1782 halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC,
1783 true, 14);
1784 coex_dm->auto_tdma_adjust = false;
1785 } else {
1786 /*for low BT RSSI*/
1787 halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC,
1788 true, 11);
1789 coex_dm->auto_tdma_adjust = false;
1790 }
1791
1792 halbtc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
1793 } else if ((bt_link_info->pan_only) ||
1794 (bt_link_info->hid_exist && bt_link_info->pan_exist)) {
1795 /*PAN(OPP, FTP), HID+PAN(OPP, FTP)*/
1796 halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3);
1797 halbtc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
1798 coex_dm->auto_tdma_adjust = false;
1799 } else if (((bt_link_info->a2dp_exist) && (bt_link_info->pan_exist)) ||
1800 (bt_link_info->hid_exist && bt_link_info->a2dp_exist &&
1801 bt_link_info->pan_exist)) {
1802 /*A2DP+PAN(OPP, FTP), HID+A2DP+PAN(OPP, FTP)*/
1803 halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 13);
1804 halbtc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
1805 coex_dm->auto_tdma_adjust = false;
1806 } else {
1807 halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 11);
1808 halbtc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
1809 coex_dm->auto_tdma_adjust = false;
1810 }
1811}
1812
1813static void halbtc8821a1ant_action_wifi_not_connected(
1814 struct btc_coexist *btcoexist)
1815{
1816 /* power save state*/
1817 halbtc8821a1ant_power_save_state(btcoexist,
1818 BTC_PS_WIFI_NATIVE, 0x0, 0x0);
1819
1820 /* tdma and coex table*/
1821 halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
1822 halbtc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
1823}
1824
1825static void btc8821a1ant_act_wifi_not_conn_scan(struct btc_coexist *btcoexist)
1826{
1827 halbtc8821a1ant_power_save_state(btcoexist,
1828 BTC_PS_WIFI_NATIVE, 0x0, 0x0);
1829
1830 halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 22);
1831 halbtc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
1832}
1833
1834static void halbtc8821a1ant_action_wifi_connected_scan(
1835 struct btc_coexist *btcoexist) {
1836 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
1837
1838 /* power save state*/
1839 halbtc8821a1ant_power_save_state(btcoexist,
1840 BTC_PS_WIFI_NATIVE, 0x0, 0x0);
1841
1842 /* tdma and coex table*/
1843 if (BT_8821A_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) {
1844 if (bt_link_info->a2dp_exist && bt_link_info->pan_exist) {
1845 halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC,
1846 true, 22);
1847 halbtc8821a1ant_coex_table_with_type(btcoexist,
1848 NORMAL_EXEC, 1);
1849 } else {
1850 halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 20);
1851 halbtc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
1852 }
1853 } else if ((BT_8821A_1ANT_BT_STATUS_SCO_BUSY ==
1854 coex_dm->bt_status) ||
1855 (BT_8821A_1ANT_BT_STATUS_ACL_SCO_BUSY ==
1856 coex_dm->bt_status)) {
1857 btc8821a1ant_act_bt_sco_hid_only_busy(btcoexist,
1858 BT_8821A_1ANT_WIFI_STATUS_CONNECTED_SCAN);
1859 } else {
1860 halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 20);
1861 halbtc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
1862 }
1863}
1864
1865static void btc8821a1ant_act_wifi_conn_sp_pkt(struct btc_coexist *btcoexist)
1866{
1867 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
1868 bool hs_connecting = false;
1869
1870 btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_CONNECTING, &hs_connecting);
1871
1872 halbtc8821a1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE,
1873 0x0, 0x0);
1874
1875 /* tdma and coex table*/
1876 if (BT_8821A_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) {
1877 if (bt_link_info->a2dp_exist && bt_link_info->pan_exist) {
1878 halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC,
1879 true, 22);
1880 halbtc8821a1ant_coex_table_with_type(btcoexist,
1881 NORMAL_EXEC, 1);
1882 } else {
1883 halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC,
1884 true, 20);
1885 halbtc8821a1ant_coex_table_with_type(btcoexist,
1886 NORMAL_EXEC, 1);
1887 }
1888 } else {
1889 halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 20);
1890 halbtc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
1891 }
1892}
1893
1894static void halbtc8821a1ant_action_wifi_connected(struct btc_coexist *btcoexist)
1895{
1896 bool wifi_busy = false;
1897 bool scan = false, link = false, roam = false;
1898 bool under_4way = false;
1899
1900 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
1901 "[BTCoex], CoexForWifiConnect()===>\n");
1902
1903 btcoexist->btc_get(btcoexist,
1904 BTC_GET_BL_WIFI_4_WAY_PROGRESS, &under_4way);
1905 if (under_4way) {
1906 btc8821a1ant_act_wifi_conn_sp_pkt(btcoexist);
1907 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
1908 "[BTCoex], CoexForWifiConnect(), return for wifi is under 4way<===\n");
1909 return;
1910 }
1911
1912 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan);
1913 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link);
1914 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam);
1915 if (scan || link || roam) {
1916 halbtc8821a1ant_action_wifi_connected_scan(btcoexist);
1917 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
1918 "[BTCoex], CoexForWifiConnect(), return for wifi is under scan<===\n");
1919 return;
1920 }
1921
1922 /* power save state*/
1923 if (BT_8821A_1ANT_BT_STATUS_ACL_BUSY ==
1924 coex_dm->bt_status && !btcoexist->bt_link_info.hid_only)
1925 halbtc8821a1ant_power_save_state(btcoexist,
1926 BTC_PS_LPS_ON, 0x50, 0x4);
1927 else
1928 halbtc8821a1ant_power_save_state(btcoexist,
1929 BTC_PS_WIFI_NATIVE,
1930 0x0, 0x0);
1931
1932 /* tdma and coex table*/
1933 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
1934 if (!wifi_busy) {
1935 if (BT_8821A_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) {
1936 btc8821a1ant_act_wifi_con_bt_acl_busy(btcoexist,
1937 BT_8821A_1ANT_WIFI_STATUS_CONNECTED_IDLE);
1938 } else if ((BT_8821A_1ANT_BT_STATUS_SCO_BUSY ==
1939 coex_dm->bt_status) ||
1940 (BT_8821A_1ANT_BT_STATUS_ACL_SCO_BUSY ==
1941 coex_dm->bt_status)) {
1942 btc8821a1ant_act_bt_sco_hid_only_busy(btcoexist,
1943 BT_8821A_1ANT_WIFI_STATUS_CONNECTED_IDLE);
1944 } else {
1945 halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC,
1946 true, 5);
1947 halbtc8821a1ant_coex_table_with_type(btcoexist,
1948 NORMAL_EXEC, 2);
1949 }
1950 } else {
1951 if (BT_8821A_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) {
1952 btc8821a1ant_act_wifi_con_bt_acl_busy(btcoexist,
1953 BT_8821A_1ANT_WIFI_STATUS_CONNECTED_BUSY);
1954 } else if ((BT_8821A_1ANT_BT_STATUS_SCO_BUSY ==
1955 coex_dm->bt_status) ||
1956 (BT_8821A_1ANT_BT_STATUS_ACL_SCO_BUSY ==
1957 coex_dm->bt_status)) {
1958 btc8821a1ant_act_bt_sco_hid_only_busy(btcoexist,
1959 BT_8821A_1ANT_WIFI_STATUS_CONNECTED_BUSY);
1960 } else {
1961 halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC,
1962 true, 5);
1963 halbtc8821a1ant_coex_table_with_type(btcoexist,
1964 NORMAL_EXEC, 2);
1965 }
1966 }
1967}
1968
1969static void btc8821a1ant_run_sw_coex_mech(struct btc_coexist *btcoexist)
1970{
1971 u8 algorithm = 0;
1972
1973 algorithm = halbtc8821a1ant_action_algorithm(btcoexist);
1974 coex_dm->cur_algorithm = algorithm;
1975
1976 if (!halbtc8821a1ant_is_common_action(btcoexist)) {
1977 switch (coex_dm->cur_algorithm) {
1978 case BT_8821A_1ANT_COEX_ALGO_SCO:
1979 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
1980 "[BTCoex], Action algorithm = SCO.\n");
1981 halbtc8821a1ant_action_sco(btcoexist);
1982 break;
1983 case BT_8821A_1ANT_COEX_ALGO_HID:
1984 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
1985 "[BTCoex], Action algorithm = HID.\n");
1986 halbtc8821a1ant_action_hid(btcoexist);
1987 break;
1988 case BT_8821A_1ANT_COEX_ALGO_A2DP:
1989 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
1990 "[BTCoex], Action algorithm = A2DP.\n");
1991 halbtc8821a1ant_action_a2dp(btcoexist);
1992 break;
1993 case BT_8821A_1ANT_COEX_ALGO_A2DP_PANHS:
1994 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
1995 "[BTCoex], Action algorithm = A2DP+PAN(HS).\n");
1996 halbtc8821a1ant_action_a2dp_pan_hs(btcoexist);
1997 break;
1998 case BT_8821A_1ANT_COEX_ALGO_PANEDR:
1999 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2000 "[BTCoex], Action algorithm = PAN(EDR).\n");
2001 halbtc8821a1ant_action_pan_edr(btcoexist);
2002 break;
2003 case BT_8821A_1ANT_COEX_ALGO_PANHS:
2004 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2005 "[BTCoex], Action algorithm = HS mode.\n");
2006 halbtc8821a1ant_action_pan_hs(btcoexist);
2007 break;
2008 case BT_8821A_1ANT_COEX_ALGO_PANEDR_A2DP:
2009 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2010 "[BTCoex], Action algorithm = PAN+A2DP.\n");
2011 halbtc8821a1ant_action_pan_edr_a2dp(btcoexist);
2012 break;
2013 case BT_8821A_1ANT_COEX_ALGO_PANEDR_HID:
2014 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2015 "[BTCoex], Action algorithm = PAN(EDR)+HID.\n");
2016 halbtc8821a1ant_action_pan_edr_hid(btcoexist);
2017 break;
2018 case BT_8821A_1ANT_COEX_ALGO_HID_A2DP_PANEDR:
2019 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2020 "[BTCoex], Action algorithm = HID+A2DP+PAN.\n");
2021 btc8821a1ant_action_hid_a2dp_pan_edr(btcoexist);
2022 break;
2023 case BT_8821A_1ANT_COEX_ALGO_HID_A2DP:
2024 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2025 "[BTCoex], Action algorithm = HID+A2DP.\n");
2026 halbtc8821a1ant_action_hid_a2dp(btcoexist);
2027 break;
2028 default:
2029 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2030 "[BTCoex], Action algorithm = coexist All Off!!\n");
2031 /*halbtc8821a1ant_coex_all_off(btcoexist);*/
2032 break;
2033 }
2034 coex_dm->pre_algorithm = coex_dm->cur_algorithm;
2035 }
2036}
2037
2038static void halbtc8821a1ant_run_coexist_mechanism(struct btc_coexist *btcoexist)
2039{
2040 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
2041 bool wifi_connected = false, bt_hs_on = false;
2042 bool increase_scan_dev_num = false;
2043 bool bt_ctrl_agg_buf_size = false;
2044 u8 agg_buf_size = 5;
2045 u8 wifi_rssi_state = BTC_RSSI_STATE_HIGH;
2046 bool wifi_under_5g = false;
2047
2048 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2049 "[BTCoex], RunCoexistMechanism()===>\n");
2050
2051 if (btcoexist->manual_control) {
2052 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2053 "[BTCoex], RunCoexistMechanism(), return for Manual CTRL <===\n");
2054 return;
2055 }
2056
2057 if (btcoexist->stop_coex_dm) {
2058 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2059 "[BTCoex], RunCoexistMechanism(), return for Stop Coex DM <===\n");
2060 return;
2061 }
2062
2063 if (coex_sta->under_ips) {
2064 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2065 "[BTCoex], wifi is under IPS !!!\n");
2066 return;
2067 }
2068
2069 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
2070 if (wifi_under_5g) {
2071 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2072 "[BTCoex], RunCoexistMechanism(), return for 5G <===\n");
2073 halbtc8821a1ant_coex_under_5g(btcoexist);
2074 return;
2075 }
2076
2077 if ((BT_8821A_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) ||
2078 (BT_8821A_1ANT_BT_STATUS_SCO_BUSY == coex_dm->bt_status) ||
2079 (BT_8821A_1ANT_BT_STATUS_ACL_SCO_BUSY == coex_dm->bt_status))
2080 increase_scan_dev_num = true;
2081
2082 btcoexist->btc_set(btcoexist, BTC_SET_BL_INC_SCAN_DEV_NUM,
2083 &increase_scan_dev_num);
2084
2085 btcoexist->btc_get(btcoexist,
2086 BTC_GET_BL_WIFI_CONNECTED, &wifi_connected);
2087
2088 if (!bt_link_info->sco_exist && !bt_link_info->hid_exist) {
2089 halbtc8821a1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0);
2090 } else {
2091 if (wifi_connected) {
2092 wifi_rssi_state =
2093 halbtc8821a1ant_WifiRssiState(btcoexist, 1, 2,
2094 30, 0);
2095 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
2096 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2097 halbtc8821a1ant_limited_tx(btcoexist,
2098 NORMAL_EXEC, 1, 1,
2099 1, 1);
2100 } else {
2101 halbtc8821a1ant_limited_tx(btcoexist,
2102 NORMAL_EXEC, 1, 1,
2103 1, 1);
2104 }
2105 } else {
2106 halbtc8821a1ant_limited_tx(btcoexist, NORMAL_EXEC,
2107 0, 0, 0, 0);
2108 }
2109 }
2110
2111 if (bt_link_info->sco_exist) {
2112 bt_ctrl_agg_buf_size = true;
2113 agg_buf_size = 0x3;
2114 } else if (bt_link_info->hid_exist) {
2115 bt_ctrl_agg_buf_size = true;
2116 agg_buf_size = 0x5;
2117 } else if (bt_link_info->a2dp_exist || bt_link_info->pan_exist) {
2118 bt_ctrl_agg_buf_size = true;
2119 agg_buf_size = 0x8;
2120 }
2121 halbtc8821a1ant_limited_rx(btcoexist, NORMAL_EXEC, false,
2122 bt_ctrl_agg_buf_size, agg_buf_size);
2123
2124 btc8821a1ant_run_sw_coex_mech(btcoexist);
2125
2126 btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
2127 if (coex_sta->c2h_bt_inquiry_page) {
2128 halbtc8821a1ant_action_bt_inquiry(btcoexist);
2129 return;
2130 } else if (bt_hs_on) {
2131 halbtc8821a1ant_action_hs(btcoexist);
2132 return;
2133 }
2134
2135 if (!wifi_connected) {
2136 bool scan = false, link = false, roam = false;
2137
2138 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2139 "[BTCoex], wifi is non connected-idle !!!\n");
2140
2141 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan);
2142 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link);
2143 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam);
2144
2145 if (scan || link || roam)
2146 btc8821a1ant_act_wifi_not_conn_scan(btcoexist);
2147 else
2148 halbtc8821a1ant_action_wifi_not_connected(btcoexist);
2149 } else {
2150 /* wifi LPS/Busy*/
2151 halbtc8821a1ant_action_wifi_connected(btcoexist);
2152 }
2153}
2154
2155static void halbtc8821a1ant_init_coex_dm(struct btc_coexist *btcoexist)
2156{
2157 /* force to reset coex mechanism*/
2158 /* sw all off*/
2159 halbtc8821a1ant_sw_mechanism(btcoexist, false);
2160
2161 halbtc8821a1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 8);
2162 halbtc8821a1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 0);
2163}
2164
2165static void halbtc8821a1ant_init_hw_config(struct btc_coexist *btcoexist,
2166 bool back_up)
2167{
2168 u8 u1_tmp = 0;
2169 bool wifi_under_5g = false;
2170
2171 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
2172 "[BTCoex], 1Ant Init HW Config!!\n");
2173
2174 if (back_up) {
2175 coex_dm->backup_arfr_cnt1 = btcoexist->btc_read_4byte(btcoexist,
2176 0x430);
2177 coex_dm->backup_arfr_cnt2 = btcoexist->btc_read_4byte(btcoexist,
2178 0x434);
2179 coex_dm->backup_retry_limit =
2180 btcoexist->btc_read_2byte(btcoexist, 0x42a);
2181 coex_dm->backup_ampdu_max_time =
2182 btcoexist->btc_read_1byte(btcoexist, 0x456);
2183 }
2184
2185 /* 0x790[5:0] = 0x5*/
2186 u1_tmp = btcoexist->btc_read_1byte(btcoexist, 0x790);
2187 u1_tmp &= 0xc0;
2188 u1_tmp |= 0x5;
2189 btcoexist->btc_write_1byte(btcoexist, 0x790, u1_tmp);
2190
2191 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
2192
2193 /*Antenna config*/
2194 if (wifi_under_5g)
2195 halbtc8821a1ant_set_ant_path(btcoexist, BTC_ANT_PATH_BT,
2196 true, false);
2197 else
2198 halbtc8821a1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA,
2199 true, false);
2200 /* PTA parameter*/
2201 halbtc8821a1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 0);
2202
2203 /* Enable counter statistics*/
2204 /*0x76e[3] =1, WLAN_Act control by PTA*/
2205 btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc);
2206 btcoexist->btc_write_1byte(btcoexist, 0x778, 0x3);
2207 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x40, 0x20, 0x1);
2208}
2209
2210/*============================================================*/
2211/* work around function start with wa_halbtc8821a1ant_*/
2212/*============================================================*/
2213/*============================================================*/
2214/* extern function start with EXhalbtc8821a1ant_*/
2215/*============================================================*/
2216void ex_halbtc8821a1ant_init_hwconfig(struct btc_coexist *btcoexist)
2217{
2218 halbtc8821a1ant_init_hw_config(btcoexist, true);
2219}
2220
2221void ex_halbtc8821a1ant_init_coex_dm(struct btc_coexist *btcoexist)
2222{
2223 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
2224 "[BTCoex], Coex Mechanism Init!!\n");
2225
2226 btcoexist->stop_coex_dm = false;
2227
2228 halbtc8821a1ant_init_coex_dm(btcoexist);
2229
2230 halbtc8821a1ant_query_bt_info(btcoexist);
2231}
2232
2233void ex_halbtc8821a1ant_display_coex_info(struct btc_coexist *btcoexist)
2234{
2235 struct btc_board_info *board_info = &btcoexist->board_info;
2236 struct btc_stack_info *stack_info = &btcoexist->stack_info;
2237 struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
2238 struct rtl_priv *rtlpriv = btcoexist->adapter;
2239 u8 u1_tmp[4], i, bt_info_ext, ps_tdma_case = 0;
2240 u16 u2_tmp[4];
2241 u32 u4_tmp[4];
2242 bool roam = false, scan = false, link = false, wifi_under_5g = false;
2243 bool bt_hs_on = false, wifi_busy = false;
2244 long wifi_rssi = 0, bt_hs_rssi = 0;
2245 u32 wifi_bw, wifi_traffic_dir;
2246 u8 wifi_dot11_chnl, wifi_hs_chnl;
2247 u32 fw_ver = 0, bt_patch_ver = 0;
2248
2249 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2250 "\r\n ============[BT Coexist info]============");
2251
2252 if (btcoexist->manual_control) {
2253 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2254 "\r\n ============[Under Manual Control]============");
2255 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2256 "\r\n ==========================================");
2257 }
2258 if (btcoexist->stop_coex_dm) {
2259 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2260 "\r\n ============[Coex is STOPPED]============");
2261 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2262 "\r\n ==========================================");
2263 }
2264
2265 if (!board_info->bt_exist) {
2266 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n BT not exists !!!");
2267 return;
2268 }
2269
2270 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2271 "\r\n %-35s = %d/ %d/ %d",
2272 "Ant PG Num/ Ant Mech/ Ant Pos:",
2273 board_info->pg_ant_num,
2274 board_info->btdm_ant_num,
2275 board_info->btdm_ant_pos);
2276
2277 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2278 "\r\n %-35s = %s / %d", "BT stack/ hci ext ver",
2279 ((stack_info->profile_notified) ? "Yes" : "No"),
2280 stack_info->hci_version);
2281
2282 btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER,
2283 &bt_patch_ver);
2284 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver);
2285 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2286 "\r\n %-35s = %d_%x/ 0x%x/ 0x%x(%d)",
2287 "CoexVer/ FwVer/ PatchVer",
2288 glcoex_ver_date_8821a_1ant,
2289 glcoex_ver_8821a_1ant,
2290 fw_ver, bt_patch_ver,
2291 bt_patch_ver);
2292
2293 btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION,
2294 &bt_hs_on);
2295 btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_DOT11_CHNL,
2296 &wifi_dot11_chnl);
2297 btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_HS_CHNL,
2298 &wifi_hs_chnl);
2299 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2300 "\r\n %-35s = %d / %d(%d)",
2301 "Dot11 channel / HsChnl(HsMode)",
2302 wifi_dot11_chnl, wifi_hs_chnl, bt_hs_on);
2303
2304 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2305 "\r\n %-35s = %02x %02x %02x ",
2306 "H2C Wifi inform bt chnl Info",
2307 coex_dm->wifi_chnl_info[0], coex_dm->wifi_chnl_info[1],
2308 coex_dm->wifi_chnl_info[2]);
2309
2310 btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi);
2311 btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi);
2312 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2313 "\r\n %-35s = %d/ %d", "Wifi rssi/ HS rssi",
2314 (int)wifi_rssi, (int)bt_hs_rssi);
2315
2316 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan);
2317 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link);
2318 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam);
2319 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2320 "\r\n %-35s = %d/ %d/ %d ", "Wifi link/ roam/ scan",
2321 link, roam, scan);
2322
2323 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G,
2324 &wifi_under_5g);
2325 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW,
2326 &wifi_bw);
2327 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY,
2328 &wifi_busy);
2329 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION,
2330 &wifi_traffic_dir);
2331 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2332 "\r\n %-35s = %s / %s/ %s ", "Wifi status",
2333 (wifi_under_5g ? "5G" : "2.4G"),
2334 ((BTC_WIFI_BW_LEGACY == wifi_bw) ? "Legacy" :
2335 (((BTC_WIFI_BW_HT40 == wifi_bw) ? "HT40" : "HT20"))),
2336 ((!wifi_busy) ? "idle" :
2337 ((BTC_WIFI_TRAFFIC_TX == wifi_traffic_dir) ?
2338 "uplink" : "downlink")));
2339 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2340 "\r\n %-35s = [%s/ %d/ %d] ", "BT [status/ rssi/ retryCnt]",
2341 ((btcoexist->bt_info.bt_disabled) ? ("disabled") :
2342 ((coex_sta->c2h_bt_inquiry_page) ? ("inquiry/page scan") :
2343 ((BT_8821A_1ANT_BT_STATUS_NON_CONNECTED_IDLE ==
2344 coex_dm->bt_status) ?
2345 "non-connected idle" :
2346 ((BT_8821A_1ANT_BT_STATUS_CONNECTED_IDLE ==
2347 coex_dm->bt_status) ?
2348 "connected-idle" : "busy")))),
2349 coex_sta->bt_rssi, coex_sta->bt_retry_cnt);
2350
2351 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2352 "\r\n %-35s = %d / %d / %d / %d", "SCO/HID/PAN/A2DP",
2353 bt_link_info->sco_exist,
2354 bt_link_info->hid_exist,
2355 bt_link_info->pan_exist,
2356 bt_link_info->a2dp_exist);
2357 btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_BT_LINK_INFO);
2358
2359 bt_info_ext = coex_sta->bt_info_ext;
2360 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2361 "\r\n %-35s = %s",
2362 "BT Info A2DP rate",
2363 (bt_info_ext&BIT0) ?
2364 "Basic rate" : "EDR rate");
2365
2366 for (i = 0; i < BT_INFO_SRC_8821A_1ANT_MAX; i++) {
2367 if (coex_sta->bt_info_c2h_cnt[i]) {
2368 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2369 "\r\n %-35s = %02x %02x %02x %02x %02x %02x %02x(%d)",
2370 glbt_info_src_8821a_1ant[i],
2371 coex_sta->bt_info_c2h[i][0],
2372 coex_sta->bt_info_c2h[i][1],
2373 coex_sta->bt_info_c2h[i][2],
2374 coex_sta->bt_info_c2h[i][3],
2375 coex_sta->bt_info_c2h[i][4],
2376 coex_sta->bt_info_c2h[i][5],
2377 coex_sta->bt_info_c2h[i][6],
2378 coex_sta->bt_info_c2h_cnt[i]);
2379 }
2380 }
2381 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2382 "\r\n %-35s = %s/%s, (0x%x/0x%x)",
2383 "PS state, IPS/LPS, (lps/rpwm)",
2384 ((coex_sta->under_ips ? "IPS ON" : "IPS OFF")),
2385 ((coex_sta->under_Lps ? "LPS ON" : "LPS OFF")),
2386 btcoexist->bt_info.lps_val,
2387 btcoexist->bt_info.rpwm_val);
2388 btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_FW_PWR_MODE_CMD);
2389
2390 if (!btcoexist->manual_control) {
2391 /* Sw mechanism*/
2392 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2393 "\r\n %-35s", "============[Sw mechanism]============");
2394
2395 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2396 "\r\n %-35s = %d", "SM[LowPenaltyRA]",
2397 coex_dm->cur_low_penalty_ra);
2398
2399 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2400 "\r\n %-35s = %s/ %s/ %d ",
2401 "DelBA/ BtCtrlAgg/ AggSize",
2402 (btcoexist->bt_info.reject_agg_pkt ? "Yes" : "No"),
2403 (btcoexist->bt_info.bt_ctrl_buf_size ? "Yes" : "No"),
2404 btcoexist->bt_info.agg_buf_size);
2405 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2406 "\r\n %-35s = 0x%x ", "Rate Mask",
2407 btcoexist->bt_info.ra_mask);
2408
2409 /* Fw mechanism*/
2410 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s",
2411 "============[Fw mechanism]============");
2412
2413 ps_tdma_case = coex_dm->cur_ps_tdma;
2414 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2415 "\r\n %-35s = %02x %02x %02x %02x %02x case-%d (auto:%d)",
2416 "PS TDMA",
2417 coex_dm->ps_tdma_para[0],
2418 coex_dm->ps_tdma_para[1],
2419 coex_dm->ps_tdma_para[2],
2420 coex_dm->ps_tdma_para[3],
2421 coex_dm->ps_tdma_para[4],
2422 ps_tdma_case,
2423 coex_dm->auto_tdma_adjust);
2424
2425 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2426 "\r\n %-35s = 0x%x ",
2427 "Latest error condition(should be 0)",
2428 coex_dm->error_condition);
2429
2430 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2431 "\r\n %-35s = %d ", "IgnWlanAct",
2432 coex_dm->cur_ignore_wlan_act);
2433 }
2434
2435 /* Hw setting*/
2436 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2437 "\r\n %-35s", "============[Hw setting]============");
2438
2439 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2440 "\r\n %-35s = 0x%x/0x%x/0x%x/0x%x",
2441 "backup ARFR1/ARFR2/RL/AMaxTime",
2442 coex_dm->backup_arfr_cnt1,
2443 coex_dm->backup_arfr_cnt2,
2444 coex_dm->backup_retry_limit,
2445 coex_dm->backup_ampdu_max_time);
2446
2447 u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x430);
2448 u4_tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x434);
2449 u2_tmp[0] = btcoexist->btc_read_2byte(btcoexist, 0x42a);
2450 u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x456);
2451 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2452 "\r\n %-35s = 0x%x/0x%x/0x%x/0x%x",
2453 "0x430/0x434/0x42a/0x456",
2454 u4_tmp[0], u4_tmp[1], u2_tmp[0], u1_tmp[0]);
2455
2456 u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x778);
2457 u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xc58);
2458 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2459 "\r\n %-35s = 0x%x/ 0x%x", "0x778/ 0xc58[29:25]",
2460 u1_tmp[0], (u4_tmp[0]&0x3e000000) >> 25);
2461
2462 u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x8db);
2463 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2464 "\r\n %-35s = 0x%x", "0x8db[6:5]",
2465 ((u1_tmp[0]&0x60)>>5));
2466
2467 u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x975);
2468 u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xcb4);
2469 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2470 "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
2471 "0xcb4[29:28]/0xcb4[7:0]/0x974[9:8]",
2472 (u4_tmp[0] & 0x30000000)>>28,
2473 u4_tmp[0] & 0xff,
2474 u1_tmp[0] & 0x3);
2475
2476 u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x40);
2477 u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x4c);
2478 u1_tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x64);
2479 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2480 "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
2481 "0x40/0x4c[24:23]/0x64[0]",
2482 u1_tmp[0], ((u4_tmp[0]&0x01800000)>>23), u1_tmp[1]&0x1);
2483
2484 u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x550);
2485 u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x522);
2486 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2487 "\r\n %-35s = 0x%x/ 0x%x", "0x550(bcn ctrl)/0x522",
2488 u4_tmp[0], u1_tmp[0]);
2489
2490 u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xc50);
2491 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2492 "\r\n %-35s = 0x%x", "0xc50(dig)",
2493 u4_tmp[0]&0xff);
2494
2495 u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xf48);
2496 u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0xa5d);
2497 u1_tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0xa5c);
2498 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2499 "\r\n %-35s = 0x%x/ 0x%x", "OFDM-FA/ CCK-FA",
2500 u4_tmp[0], (u1_tmp[0]<<8) + u1_tmp[1]);
2501
2502 u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x6c0);
2503 u4_tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x6c4);
2504 u4_tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x6c8);
2505 u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x6cc);
2506 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2507 "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x",
2508 "0x6c0/0x6c4/0x6c8/0x6cc(coexTable)",
2509 u4_tmp[0], u4_tmp[1], u4_tmp[2], u1_tmp[0]);
2510
2511 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2512 "\r\n %-35s = %d/ %d", "0x770(high-pri rx/tx)",
2513 coex_sta->high_priority_rx, coex_sta->high_priority_tx);
2514 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2515 "\r\n %-35s = %d/ %d", "0x774(low-pri rx/tx)",
2516 coex_sta->low_priority_rx, coex_sta->low_priority_tx);
2517#if (BT_AUTO_REPORT_ONLY_8821A_1ANT == 1)
2518 halbtc8821a1ant_monitor_bt_ctr(btcoexist);
2519#endif
2520 btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_COEX_STATISTICS);
2521}
2522
2523void ex_halbtc8821a1ant_ips_notify(struct btc_coexist *btcoexist, u8 type)
2524{
2525 if (btcoexist->manual_control || btcoexist->stop_coex_dm)
2526 return;
2527
2528 if (BTC_IPS_ENTER == type) {
2529 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
2530 "[BTCoex], IPS ENTER notify\n");
2531 coex_sta->under_ips = true;
2532 halbtc8821a1ant_set_ant_path(btcoexist,
2533 BTC_ANT_PATH_BT, false, true);
2534 /*set PTA control*/
2535 halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
2536 halbtc8821a1ant_coex_table_with_type(btcoexist,
2537 NORMAL_EXEC, 0);
2538 } else if (BTC_IPS_LEAVE == type) {
2539 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
2540 "[BTCoex], IPS LEAVE notify\n");
2541 coex_sta->under_ips = false;
2542
2543 halbtc8821a1ant_run_coexist_mechanism(btcoexist);
2544 }
2545}
2546
2547void ex_halbtc8821a1ant_lps_notify(struct btc_coexist *btcoexist, u8 type)
2548{
2549 if (btcoexist->manual_control || btcoexist->stop_coex_dm)
2550 return;
2551
2552 if (BTC_LPS_ENABLE == type) {
2553 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
2554 "[BTCoex], LPS ENABLE notify\n");
2555 coex_sta->under_Lps = true;
2556 } else if (BTC_LPS_DISABLE == type) {
2557 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
2558 "[BTCoex], LPS DISABLE notify\n");
2559 coex_sta->under_Lps = false;
2560 }
2561}
2562
2563void ex_halbtc8821a1ant_scan_notify(struct btc_coexist *btcoexist, u8 type)
2564{
2565 bool wifi_connected = false, bt_hs_on = false;
2566
2567 if (btcoexist->manual_control ||
2568 btcoexist->stop_coex_dm ||
2569 btcoexist->bt_info.bt_disabled)
2570 return;
2571
2572 btcoexist->btc_get(btcoexist,
2573 BTC_GET_BL_HS_OPERATION, &bt_hs_on);
2574 btcoexist->btc_get(btcoexist,
2575 BTC_GET_BL_WIFI_CONNECTED, &wifi_connected);
2576
2577 halbtc8821a1ant_query_bt_info(btcoexist);
2578
2579 if (coex_sta->c2h_bt_inquiry_page) {
2580 halbtc8821a1ant_action_bt_inquiry(btcoexist);
2581 return;
2582 } else if (bt_hs_on) {
2583 halbtc8821a1ant_action_hs(btcoexist);
2584 return;
2585 }
2586
2587 if (BTC_SCAN_START == type) {
2588 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
2589 "[BTCoex], SCAN START notify\n");
2590 if (!wifi_connected) {
2591 /* non-connected scan*/
2592 btc8821a1ant_act_wifi_not_conn_scan(btcoexist);
2593 } else {
2594 /* wifi is connected*/
2595 halbtc8821a1ant_action_wifi_connected_scan(btcoexist);
2596 }
2597 } else if (BTC_SCAN_FINISH == type) {
2598 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
2599 "[BTCoex], SCAN FINISH notify\n");
2600 if (!wifi_connected) {
2601 /* non-connected scan*/
2602 halbtc8821a1ant_action_wifi_not_connected(btcoexist);
2603 } else {
2604 halbtc8821a1ant_action_wifi_connected(btcoexist);
2605 }
2606 }
2607}
2608
2609void ex_halbtc8821a1ant_connect_notify(struct btc_coexist *btcoexist, u8 type)
2610{
2611 bool wifi_connected = false, bt_hs_on = false;
2612
2613 if (btcoexist->manual_control ||
2614 btcoexist->stop_coex_dm ||
2615 btcoexist->bt_info.bt_disabled)
2616 return;
2617
2618 btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
2619 if (coex_sta->c2h_bt_inquiry_page) {
2620 halbtc8821a1ant_action_bt_inquiry(btcoexist);
2621 return;
2622 } else if (bt_hs_on) {
2623 halbtc8821a1ant_action_hs(btcoexist);
2624 return;
2625 }
2626
2627 if (BTC_ASSOCIATE_START == type) {
2628 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
2629 "[BTCoex], CONNECT START notify\n");
2630 btc8821a1ant_act_wifi_not_conn_scan(btcoexist);
2631 } else if (BTC_ASSOCIATE_FINISH == type) {
2632 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
2633 "[BTCoex], CONNECT FINISH notify\n");
2634
2635 btcoexist->btc_get(btcoexist,
2636 BTC_GET_BL_WIFI_CONNECTED, &wifi_connected);
2637 if (!wifi_connected) {
2638 /* non-connected scan*/
2639 halbtc8821a1ant_action_wifi_not_connected(btcoexist);
2640 } else {
2641 halbtc8821a1ant_action_wifi_connected(btcoexist);
2642 }
2643 }
2644}
2645
2646void ex_halbtc8821a1ant_media_status_notify(struct btc_coexist *btcoexist,
2647 u8 type)
2648{
2649 u8 h2c_parameter[3] = {0};
2650 u32 wifi_bw;
2651 u8 wifi_central_chnl;
2652
2653 if (btcoexist->manual_control ||
2654 btcoexist->stop_coex_dm ||
2655 btcoexist->bt_info.bt_disabled)
2656 return;
2657
2658 if (BTC_MEDIA_CONNECT == type) {
2659 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
2660 "[BTCoex], MEDIA connect notify\n");
2661 } else {
2662 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
2663 "[BTCoex], MEDIA disconnect notify\n");
2664 }
2665
2666 /* only 2.4G we need to inform bt the chnl mask*/
2667 btcoexist->btc_get(btcoexist,
2668 BTC_GET_U1_WIFI_CENTRAL_CHNL,
2669 &wifi_central_chnl);
2670 if ((BTC_MEDIA_CONNECT == type) &&
2671 (wifi_central_chnl <= 14)) {
2672 /*h2c_parameter[0] = 0x1;*/
2673 h2c_parameter[0] = 0x0;
2674 h2c_parameter[1] = wifi_central_chnl;
2675 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
2676 if (BTC_WIFI_BW_HT40 == wifi_bw)
2677 h2c_parameter[2] = 0x30;
2678 else
2679 h2c_parameter[2] = 0x20;
2680 }
2681
2682 coex_dm->wifi_chnl_info[0] = h2c_parameter[0];
2683 coex_dm->wifi_chnl_info[1] = h2c_parameter[1];
2684 coex_dm->wifi_chnl_info[2] = h2c_parameter[2];
2685
2686 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
2687 "[BTCoex], FW write 0x66 = 0x%x\n",
2688 h2c_parameter[0]<<16|h2c_parameter[1]<<8|h2c_parameter[2]);
2689
2690 btcoexist->btc_fill_h2c(btcoexist, 0x66, 3, h2c_parameter);
2691}
2692
2693void ex_halbtc8821a1ant_special_packet_notify(struct btc_coexist *btcoexist,
2694 u8 type)
2695{
2696 bool bt_hs_on = false;
2697
2698 if (btcoexist->manual_control ||
2699 btcoexist->stop_coex_dm ||
2700 btcoexist->bt_info.bt_disabled)
2701 return;
2702
2703 coex_sta->special_pkt_period_cnt = 0;
2704
2705 btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
2706 if (coex_sta->c2h_bt_inquiry_page) {
2707 halbtc8821a1ant_action_bt_inquiry(btcoexist);
2708 return;
2709 } else if (bt_hs_on) {
2710 halbtc8821a1ant_action_hs(btcoexist);
2711 return;
2712 }
2713
2714 if (BTC_PACKET_DHCP == type ||
2715 BTC_PACKET_EAPOL == type) {
2716 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
2717 "[BTCoex], special Packet(%d) notify\n", type);
2718 btc8821a1ant_act_wifi_conn_sp_pkt(btcoexist);
2719 }
2720}
2721
2722void ex_halbtc8821a1ant_bt_info_notify(struct btc_coexist *btcoexist,
2723 u8 *tmp_buf, u8 length)
2724{
2725 u8 bt_info = 0;
2726 u8 i, rsp_source = 0;
2727 bool wifi_connected = false;
2728 bool bt_busy = false;
2729 bool wifi_under_5g = false;
2730
2731 coex_sta->c2h_bt_info_req_sent = false;
2732
2733 btcoexist->btc_get(btcoexist,
2734 BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
2735
2736 rsp_source = tmp_buf[0]&0xf;
2737 if (rsp_source >= BT_INFO_SRC_8821A_1ANT_MAX)
2738 rsp_source = BT_INFO_SRC_8821A_1ANT_WIFI_FW;
2739 coex_sta->bt_info_c2h_cnt[rsp_source]++;
2740
2741 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
2742 "[BTCoex], Bt info[%d], length = %d, hex data = [",
2743 rsp_source, length);
2744 for (i = 0; i < length; i++) {
2745 coex_sta->bt_info_c2h[rsp_source][i] = tmp_buf[i];
2746 if (i == 1)
2747 bt_info = tmp_buf[i];
2748 if (i == length-1) {
2749 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
2750 "0x%02x]\n", tmp_buf[i]);
2751 } else {
2752 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
2753 "0x%02x, ", tmp_buf[i]);
2754 }
2755 }
2756
2757 if (BT_INFO_SRC_8821A_1ANT_WIFI_FW != rsp_source) {
2758 coex_sta->bt_retry_cnt = /* [3:0]*/
2759 coex_sta->bt_info_c2h[rsp_source][2]&0xf;
2760
2761 coex_sta->bt_rssi =
2762 coex_sta->bt_info_c2h[rsp_source][3]*2+10;
2763
2764 coex_sta->bt_info_ext =
2765 coex_sta->bt_info_c2h[rsp_source][4];
2766
2767 /* Here we need to resend some wifi info to BT*/
2768 /* because bt is reset and loss of the info.*/
2769 if (coex_sta->bt_info_ext & BIT1) {
2770 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2771 "[BTCoex], BT ext info bit1 check, send wifi BW&Chnl to BT!!\n");
2772 btcoexist->btc_get(btcoexist,
2773 BTC_GET_BL_WIFI_CONNECTED,
2774 &wifi_connected);
2775 if (wifi_connected) {
2776 ex_halbtc8821a1ant_media_status_notify(btcoexist,
2777 BTC_MEDIA_CONNECT);
2778 } else {
2779 ex_halbtc8821a1ant_media_status_notify(btcoexist,
2780 BTC_MEDIA_DISCONNECT);
2781 }
2782 }
2783
2784 if ((coex_sta->bt_info_ext & BIT3) && !wifi_under_5g) {
2785 if (!btcoexist->manual_control &&
2786 !btcoexist->stop_coex_dm) {
2787 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2788 "[BTCoex], BT ext info bit3 check, set BT NOT to ignore Wlan active!!\n");
2789 halbtc8821a1ant_ignore_wlan_act(btcoexist,
2790 FORCE_EXEC,
2791 false);
2792 }
2793 }
2794#if (BT_AUTO_REPORT_ONLY_8821A_1ANT == 0)
2795 if (!(coex_sta->bt_info_ext & BIT4)) {
2796 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2797 "[BTCoex], BT ext info bit4 check, set BT to enable Auto Report!!\n");
2798 halbtc8821a1ant_bt_auto_report(btcoexist,
2799 FORCE_EXEC, true);
2800 }
2801#endif
2802 }
2803
2804 /* check BIT2 first ==> check if bt is under inquiry or page scan*/
2805 if (bt_info & BT_INFO_8821A_1ANT_B_INQ_PAGE)
2806 coex_sta->c2h_bt_inquiry_page = true;
2807 else
2808 coex_sta->c2h_bt_inquiry_page = false;
2809
2810 /* set link exist status*/
2811 if (!(bt_info&BT_INFO_8821A_1ANT_B_CONNECTION)) {
2812 coex_sta->bt_link_exist = false;
2813 coex_sta->pan_exist = false;
2814 coex_sta->a2dp_exist = false;
2815 coex_sta->hid_exist = false;
2816 coex_sta->sco_exist = false;
2817 } else {
2818 /* connection exists*/
2819 coex_sta->bt_link_exist = true;
2820 if (bt_info & BT_INFO_8821A_1ANT_B_FTP)
2821 coex_sta->pan_exist = true;
2822 else
2823 coex_sta->pan_exist = false;
2824 if (bt_info & BT_INFO_8821A_1ANT_B_A2DP)
2825 coex_sta->a2dp_exist = true;
2826 else
2827 coex_sta->a2dp_exist = false;
2828 if (bt_info & BT_INFO_8821A_1ANT_B_HID)
2829 coex_sta->hid_exist = true;
2830 else
2831 coex_sta->hid_exist = false;
2832 if (bt_info & BT_INFO_8821A_1ANT_B_SCO_ESCO)
2833 coex_sta->sco_exist = true;
2834 else
2835 coex_sta->sco_exist = false;
2836 }
2837
2838 halbtc8821a1ant_update_bt_link_info(btcoexist);
2839
2840 if (!(bt_info&BT_INFO_8821A_1ANT_B_CONNECTION)) {
2841 coex_dm->bt_status = BT_8821A_1ANT_BT_STATUS_NON_CONNECTED_IDLE;
2842 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2843 "[BTCoex], BtInfoNotify(), BT Non-Connected idle!!!\n");
2844 } else if (bt_info == BT_INFO_8821A_1ANT_B_CONNECTION) {
2845 /* connection exists but no busy*/
2846 coex_dm->bt_status = BT_8821A_1ANT_BT_STATUS_CONNECTED_IDLE;
2847 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2848 "[BTCoex], BtInfoNotify(), BT Connected-idle!!!\n");
2849 } else if ((bt_info&BT_INFO_8821A_1ANT_B_SCO_ESCO) ||
2850 (bt_info&BT_INFO_8821A_1ANT_B_SCO_BUSY)) {
2851 coex_dm->bt_status = BT_8821A_1ANT_BT_STATUS_SCO_BUSY;
2852 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2853 "[BTCoex], BtInfoNotify(), BT SCO busy!!!\n");
2854 } else if (bt_info&BT_INFO_8821A_1ANT_B_ACL_BUSY) {
2855 if (BT_8821A_1ANT_BT_STATUS_ACL_BUSY != coex_dm->bt_status)
2856 coex_dm->auto_tdma_adjust = false;
2857 coex_dm->bt_status = BT_8821A_1ANT_BT_STATUS_ACL_BUSY;
2858 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2859 "[BTCoex], BtInfoNotify(), BT ACL busy!!!\n");
2860 } else {
2861 coex_dm->bt_status = BT_8821A_1ANT_BT_STATUS_MAX;
2862 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2863 "[BTCoex], BtInfoNotify(), BT Non-Defined state!!!\n");
2864 }
2865
2866 if ((BT_8821A_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) ||
2867 (BT_8821A_1ANT_BT_STATUS_SCO_BUSY == coex_dm->bt_status) ||
2868 (BT_8821A_1ANT_BT_STATUS_ACL_SCO_BUSY == coex_dm->bt_status))
2869 bt_busy = true;
2870 else
2871 bt_busy = false;
2872 btcoexist->btc_set(btcoexist,
2873 BTC_SET_BL_BT_TRAFFIC_BUSY, &bt_busy);
2874
2875 halbtc8821a1ant_run_coexist_mechanism(btcoexist);
2876}
2877
2878void ex_halbtc8821a1ant_halt_notify(struct btc_coexist *btcoexist)
2879{
2880 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
2881 "[BTCoex], Halt notify\n");
2882
2883 btcoexist->stop_coex_dm = true;
2884
2885 halbtc8821a1ant_set_ant_path(btcoexist,
2886 BTC_ANT_PATH_BT, false, true);
2887 halbtc8821a1ant_ignore_wlan_act(btcoexist, FORCE_EXEC, true);
2888
2889 halbtc8821a1ant_power_save_state(btcoexist,
2890 BTC_PS_WIFI_NATIVE, 0x0, 0x0);
2891 halbtc8821a1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 0);
2892
2893 ex_halbtc8821a1ant_media_status_notify(btcoexist,
2894 BTC_MEDIA_DISCONNECT);
2895}
2896
2897void ex_halbtc8821a1ant_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state)
2898{
2899 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
2900 "[BTCoex], Pnp notify\n");
2901
2902 if (BTC_WIFI_PNP_SLEEP == pnp_state) {
2903 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
2904 "[BTCoex], Pnp notify to SLEEP\n");
2905 btcoexist->stop_coex_dm = true;
2906 halbtc8821a1ant_ignore_wlan_act(btcoexist, FORCE_EXEC, true);
2907 halbtc8821a1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE,
2908 0x0, 0x0);
2909 halbtc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 9);
2910 } else if (BTC_WIFI_PNP_WAKE_UP == pnp_state) {
2911 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
2912 "[BTCoex], Pnp notify to WAKE UP\n");
2913 btcoexist->stop_coex_dm = false;
2914 halbtc8821a1ant_init_hw_config(btcoexist, false);
2915 halbtc8821a1ant_init_coex_dm(btcoexist);
2916 halbtc8821a1ant_query_bt_info(btcoexist);
2917 }
2918}
2919
2920void
2921ex_halbtc8821a1ant_periodical(
2922 struct btc_coexist *btcoexist) {
2923 static u8 dis_ver_info_cnt;
2924 u32 fw_ver = 0, bt_patch_ver = 0;
2925 struct btc_board_info *board_info = &btcoexist->board_info;
2926 struct btc_stack_info *stack_info = &btcoexist->stack_info;
2927
2928 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
2929 "[BTCoex], ==========================Periodical===========================\n");
2930
2931 if (dis_ver_info_cnt <= 5) {
2932 dis_ver_info_cnt += 1;
2933 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
2934 "[BTCoex], ****************************************************************\n");
2935 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
2936 "[BTCoex], Ant PG Num/ Ant Mech/ Ant Pos = %d/ %d/ %d\n",
2937 board_info->pg_ant_num,
2938 board_info->btdm_ant_num,
2939 board_info->btdm_ant_pos);
2940 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
2941 "[BTCoex], BT stack/ hci ext ver = %s / %d\n",
2942 ((stack_info->profile_notified) ? "Yes" : "No"),
2943 stack_info->hci_version);
2944 btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER,
2945 &bt_patch_ver);
2946 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver);
2947 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
2948 "[BTCoex], CoexVer/ FwVer/ PatchVer = %d_%x/ 0x%x/ 0x%x(%d)\n",
2949 glcoex_ver_date_8821a_1ant,
2950 glcoex_ver_8821a_1ant,
2951 fw_ver, bt_patch_ver,
2952 bt_patch_ver);
2953 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
2954 "[BTCoex], ****************************************************************\n");
2955 }
2956
2957#if (BT_AUTO_REPORT_ONLY_8821A_1ANT == 0)
2958 halbtc8821a1ant_query_bt_info(btcoexist);
2959 halbtc8821a1ant_monitor_bt_ctr(btcoexist);
2960 btc8821a1ant_mon_bt_en_dis(btcoexist);
2961#else
2962 if (halbtc8821a1ant_Is_wifi_status_changed(btcoexist) ||
2963 coex_dm->auto_tdma_adjust) {
2964 if (coex_sta->special_pkt_period_cnt > 2)
2965 halbtc8821a1ant_run_coexist_mechanism(btcoexist);
2966 }
2967
2968 coex_sta->special_pkt_period_cnt++;
2969#endif
2970}
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a1ant.h b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a1ant.h
new file mode 100644
index 000000000000..20e904890fc2
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a1ant.h
@@ -0,0 +1,188 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2012 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26/*===========================================
27 * The following is for 8821A 1ANT BT Co-exist definition
28 *===========================================
29 */
30#define BT_AUTO_REPORT_ONLY_8821A_1ANT 0
31
32#define BT_INFO_8821A_1ANT_B_FTP BIT7
33#define BT_INFO_8821A_1ANT_B_A2DP BIT6
34#define BT_INFO_8821A_1ANT_B_HID BIT5
35#define BT_INFO_8821A_1ANT_B_SCO_BUSY BIT4
36#define BT_INFO_8821A_1ANT_B_ACL_BUSY BIT3
37#define BT_INFO_8821A_1ANT_B_INQ_PAGE BIT2
38#define BT_INFO_8821A_1ANT_B_SCO_ESCO BIT1
39#define BT_INFO_8821A_1ANT_B_CONNECTION BIT0
40
41#define BT_INFO_8821A_1ANT_A2DP_BASIC_RATE(_BT_INFO_EXT_) \
42 (((_BT_INFO_EXT_&BIT0)) ? true : false)
43
44#define BTC_RSSI_COEX_THRESH_TOL_8821A_1ANT 2
45
46enum _BT_INFO_SRC_8821A_1ANT {
47 BT_INFO_SRC_8821A_1ANT_WIFI_FW = 0x0,
48 BT_INFO_SRC_8821A_1ANT_BT_RSP = 0x1,
49 BT_INFO_SRC_8821A_1ANT_BT_ACTIVE_SEND = 0x2,
50 BT_INFO_SRC_8821A_1ANT_MAX
51};
52
53enum _BT_8821A_1ANT_BT_STATUS {
54 BT_8821A_1ANT_BT_STATUS_NON_CONNECTED_IDLE = 0x0,
55 BT_8821A_1ANT_BT_STATUS_CONNECTED_IDLE = 0x1,
56 BT_8821A_1ANT_BT_STATUS_INQ_PAGE = 0x2,
57 BT_8821A_1ANT_BT_STATUS_ACL_BUSY = 0x3,
58 BT_8821A_1ANT_BT_STATUS_SCO_BUSY = 0x4,
59 BT_8821A_1ANT_BT_STATUS_ACL_SCO_BUSY = 0x5,
60 BT_8821A_1ANT_BT_STATUS_MAX
61};
62
63enum _BT_8821A_1ANT_WIFI_STATUS {
64 BT_8821A_1ANT_WIFI_STATUS_NON_CONNECTED_IDLE = 0x0,
65 BT_8821A_1ANT_WIFI_STATUS_NON_CONNECTED_ASSO_AUTH_SCAN = 0x1,
66 BT_8821A_1ANT_WIFI_STATUS_CONNECTED_SCAN = 0x2,
67 BT_8821A_1ANT_WIFI_STATUS_CONNECTED_SPECIAL_PKT = 0x3,
68 BT_8821A_1ANT_WIFI_STATUS_CONNECTED_IDLE = 0x4,
69 BT_8821A_1ANT_WIFI_STATUS_CONNECTED_BUSY = 0x5,
70 BT_8821A_1ANT_WIFI_STATUS_MAX
71};
72
73enum BT_8821A_1ANT_COEX_ALGO {
74 BT_8821A_1ANT_COEX_ALGO_UNDEFINED = 0x0,
75 BT_8821A_1ANT_COEX_ALGO_SCO = 0x1,
76 BT_8821A_1ANT_COEX_ALGO_HID = 0x2,
77 BT_8821A_1ANT_COEX_ALGO_A2DP = 0x3,
78 BT_8821A_1ANT_COEX_ALGO_A2DP_PANHS = 0x4,
79 BT_8821A_1ANT_COEX_ALGO_PANEDR = 0x5,
80 BT_8821A_1ANT_COEX_ALGO_PANHS = 0x6,
81 BT_8821A_1ANT_COEX_ALGO_PANEDR_A2DP = 0x7,
82 BT_8821A_1ANT_COEX_ALGO_PANEDR_HID = 0x8,
83 BT_8821A_1ANT_COEX_ALGO_HID_A2DP_PANEDR = 0x9,
84 BT_8821A_1ANT_COEX_ALGO_HID_A2DP = 0xa,
85 BT_8821A_1ANT_COEX_ALGO_MAX = 0xb,
86};
87
88struct coex_dm_8821a_1ant {
89 /* fw mechanism */
90 bool cur_ignore_wlan_act;
91 bool pre_ignore_wlan_act;
92 u8 pre_ps_tdma;
93 u8 cur_ps_tdma;
94 u8 ps_tdma_para[5];
95 u8 tdma_adj_type;
96 bool auto_tdma_adjust;
97 bool pre_ps_tdma_on;
98 bool cur_ps_tdma_on;
99 bool pre_bt_auto_report;
100 bool cur_bt_auto_report;
101 u8 pre_lps;
102 u8 cur_lps;
103 u8 pre_rpwm;
104 u8 cur_rpwm;
105
106 /* sw mechanism */
107 bool pre_low_penalty_ra;
108 bool cur_low_penalty_ra;
109 u32 pre_val_0x6c0;
110 u32 cur_val_0x6c0;
111 u32 pre_val_0x6c4;
112 u32 cur_val_0x6c4;
113 u32 pre_val_0x6c8;
114 u32 cur_val_0x6c8;
115 u8 pre_val_0x6cc;
116 u8 cur_val_0x6cc;
117 /* Auto Rate Fallback Retry cnt */
118 u32 backup_arfr_cnt1;
119 /* Auto Rate Fallback Retry cnt */
120 u32 backup_arfr_cnt2;
121 u16 backup_retry_limit;
122 u8 backup_ampdu_max_time;
123
124 /* algorithm related */
125 u8 pre_algorithm;
126 u8 cur_algorithm;
127 u8 bt_status;
128 u8 wifi_chnl_info[3];
129
130 u32 pre_ra_mask;
131 u32 cur_ra_mask;
132 u8 pre_arfr_type;
133 u8 cur_arfr_type;
134 u8 pre_retry_limit_type;
135 u8 cur_retry_limit_type;
136 u8 pre_ampdu_time_type;
137 u8 cur_ampdu_time_type;
138
139 u8 error_condition;
140};
141
142struct coex_sta_8821a_1ant {
143 bool bt_link_exist;
144 bool sco_exist;
145 bool a2dp_exist;
146 bool hid_exist;
147 bool pan_exist;
148
149 bool under_Lps;
150 bool under_ips;
151 u32 special_pkt_period_cnt;
152 u32 high_priority_tx;
153 u32 high_priority_rx;
154 u32 low_priority_tx;
155 u32 low_priority_rx;
156 u8 bt_rssi;
157 u8 pre_bt_rssi_state;
158 u8 pre_wifi_rssi_state[4];
159 bool c2h_bt_info_req_sent;
160 u8 bt_info_c2h[BT_INFO_SRC_8821A_1ANT_MAX][10];
161 u32 bt_info_c2h_cnt[BT_INFO_SRC_8821A_1ANT_MAX];
162 bool c2h_bt_inquiry_page;
163 u8 bt_retry_cnt;
164 u8 bt_info_ext;
165};
166
167/*===========================================
168 * The following is interface which will notify coex module.
169 *===========================================
170 */
171void ex_halbtc8821a1ant_init_hwconfig(struct btc_coexist *btcoexist);
172void ex_halbtc8821a1ant_init_coex_dm(struct btc_coexist *btcoexist);
173void ex_halbtc8821a1ant_ips_notify(struct btc_coexist *btcoexist, u8 type);
174void ex_halbtc8821a1ant_lps_notify(struct btc_coexist *btcoexist, u8 type);
175void ex_halbtc8821a1ant_scan_notify(struct btc_coexist *btcoexist, u8 type);
176void ex_halbtc8821a1ant_connect_notify(struct btc_coexist *btcoexist, u8 type);
177void ex_halbtc8821a1ant_media_status_notify(struct btc_coexist *btcoexist,
178 u8 type);
179void ex_halbtc8821a1ant_special_packet_notify(struct btc_coexist *btcoexist,
180 u8 type);
181void ex_halbtc8821a1ant_bt_info_notify(struct btc_coexist *btcoexist,
182 u8 *tmpbuf, u8 length);
183void ex_halbtc8821a1ant_halt_notify(struct btc_coexist *btcoexist);
184void ex_halbtc8821a1ant_pnp_notify(struct btc_coexist *btcoexist, u8 pnpstate);
185void ex_halbtc8821a1ant_periodical(struct btc_coexist *btcoexist);
186void ex_halbtc8821a1ant_display_coex_info(struct btc_coexist *btcoexist);
187void ex_halbtc8821a1ant_dbg_control(struct btc_coexist *btcoexist, u8 op_code,
188 u8 op_len, u8 *data);
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a2ant.c b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a2ant.c
new file mode 100644
index 000000000000..cf819f02ed23
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a2ant.c
@@ -0,0 +1,3879 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2012 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26/*============================================================
27 * Description:
28 *
29 * This file is for RTL8821A Co-exist mechanism
30 *
31 * History
32 * 2012/08/22 Cosa first check in.
33 * 2012/11/14 Cosa Revise for 8821A 2Ant out sourcing.
34 *
35 *============================================================
36 */
37
38/*============================================================
39 * include files
40 *============================================================
41*/
42#include "halbt_precomp.h"
43/*============================================================
44 * Global variables, these are static variables
45 *============================================================
46 */
47static struct coex_dm_8821a_2ant glcoex_dm_8821a_2ant;
48static struct coex_dm_8821a_2ant *coex_dm = &glcoex_dm_8821a_2ant;
49static struct coex_sta_8821a_2ant glcoex_sta_8821a_2ant;
50static struct coex_sta_8821a_2ant *coex_sta = &glcoex_sta_8821a_2ant;
51
52static const char *const glbt_info_src_8821a_2ant[] = {
53 "BT Info[wifi fw]",
54 "BT Info[bt rsp]",
55 "BT Info[bt auto report]",
56};
57
58static u32 glcoex_ver_date_8821a_2ant = 20130618;
59static u32 glcoex_ver_8821a_2ant = 0x5050;
60
61/*============================================================
62 * local function proto type if needed
63 *============================================================
64 *============================================================
65 * local function start with halbtc8821a2ant_
66 *============================================================
67 */
68static u8 halbtc8821a2ant_bt_rssi_state(u8 level_num, u8 rssi_thresh,
69 u8 rssi_thresh1)
70{
71 long bt_rssi = 0;
72 u8 bt_rssi_state = coex_sta->pre_bt_rssi_state;
73
74 bt_rssi = coex_sta->bt_rssi;
75
76 if (level_num == 2) {
77 if ((coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_LOW) ||
78 (coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) {
79 long tmp = rssi_thresh +
80 BTC_RSSI_COEX_THRESH_TOL_8821A_2ANT;
81 if (bt_rssi >= tmp) {
82 bt_rssi_state = BTC_RSSI_STATE_HIGH;
83 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
84 "[BTCoex], BT Rssi state switch to High\n");
85 } else {
86 bt_rssi_state = BTC_RSSI_STATE_STAY_LOW;
87 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
88 "[BTCoex], BT Rssi state stay at Low\n");
89 }
90 } else {
91 if (bt_rssi < rssi_thresh) {
92 bt_rssi_state = BTC_RSSI_STATE_LOW;
93 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
94 "[BTCoex], BT Rssi state switch to Low\n");
95 } else {
96 bt_rssi_state = BTC_RSSI_STATE_STAY_HIGH;
97 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
98 "[BTCoex], BT Rssi state stay at High\n");
99 }
100 }
101 } else if (level_num == 3) {
102 if (rssi_thresh > rssi_thresh1) {
103 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
104 "[BTCoex], BT Rssi thresh error!!\n");
105 return coex_sta->pre_bt_rssi_state;
106 }
107
108 if ((coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_LOW) ||
109 (coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) {
110 if (bt_rssi >=
111 (rssi_thresh+BTC_RSSI_COEX_THRESH_TOL_8821A_2ANT)) {
112 bt_rssi_state = BTC_RSSI_STATE_MEDIUM;
113 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
114 "[BTCoex], BT Rssi state switch to Medium\n");
115 } else {
116 bt_rssi_state = BTC_RSSI_STATE_STAY_LOW;
117 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
118 "[BTCoex], BT Rssi state stay at Low\n");
119 }
120 } else if ((coex_sta->pre_bt_rssi_state ==
121 BTC_RSSI_STATE_MEDIUM) ||
122 (coex_sta->pre_bt_rssi_state ==
123 BTC_RSSI_STATE_STAY_MEDIUM)) {
124 if (bt_rssi >=
125 (rssi_thresh1 +
126 BTC_RSSI_COEX_THRESH_TOL_8821A_2ANT)) {
127 bt_rssi_state = BTC_RSSI_STATE_HIGH;
128 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
129 "[BTCoex], BT Rssi state switch to High\n");
130 } else if (bt_rssi < rssi_thresh) {
131 bt_rssi_state = BTC_RSSI_STATE_LOW;
132 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
133 "[BTCoex], BT Rssi state switch to Low\n");
134 } else {
135 bt_rssi_state = BTC_RSSI_STATE_STAY_MEDIUM;
136 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
137 "[BTCoex], BT Rssi state stay at Medium\n");
138 }
139 } else {
140 if (bt_rssi < rssi_thresh1) {
141 bt_rssi_state = BTC_RSSI_STATE_MEDIUM;
142 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
143 "[BTCoex], BT Rssi state switch to Medium\n");
144 } else {
145 bt_rssi_state = BTC_RSSI_STATE_STAY_HIGH;
146 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
147 "[BTCoex], BT Rssi state stay at High\n");
148 }
149 }
150 }
151
152 coex_sta->pre_bt_rssi_state = bt_rssi_state;
153
154 return bt_rssi_state;
155}
156
157static u8 halbtc8821a2ant_wifi_rssi_state(struct btc_coexist *btcoexist,
158 u8 index, u8 level_num,
159 u8 rssi_thresh, u8 rssi_thresh1)
160{
161 long wifi_rssi = 0;
162 u8 wifi_rssi_state = coex_sta->pre_wifi_rssi_state[index];
163
164 btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi);
165
166 if (level_num == 2) {
167 if ((coex_sta->pre_wifi_rssi_state[index] ==
168 BTC_RSSI_STATE_LOW) ||
169 (coex_sta->pre_wifi_rssi_state[index] ==
170 BTC_RSSI_STATE_STAY_LOW)) {
171 if (wifi_rssi >=
172 (rssi_thresh+BTC_RSSI_COEX_THRESH_TOL_8821A_2ANT)) {
173 wifi_rssi_state = BTC_RSSI_STATE_HIGH;
174 BTC_PRINT(BTC_MSG_ALGORITHM,
175 ALGO_WIFI_RSSI_STATE,
176 "[BTCoex], wifi RSSI state switch to High\n");
177 } else {
178 wifi_rssi_state = BTC_RSSI_STATE_STAY_LOW;
179 BTC_PRINT(BTC_MSG_ALGORITHM,
180 ALGO_WIFI_RSSI_STATE,
181 "[BTCoex], wifi RSSI state stay at Low\n");
182 }
183 } else {
184 if (wifi_rssi < rssi_thresh) {
185 wifi_rssi_state = BTC_RSSI_STATE_LOW;
186 BTC_PRINT(BTC_MSG_ALGORITHM,
187 ALGO_WIFI_RSSI_STATE,
188 "[BTCoex], wifi RSSI state switch to Low\n");
189 } else {
190 wifi_rssi_state = BTC_RSSI_STATE_STAY_HIGH;
191 BTC_PRINT(BTC_MSG_ALGORITHM,
192 ALGO_WIFI_RSSI_STATE,
193 "[BTCoex], wifi RSSI state stay at High\n");
194 }
195 }
196 } else if (level_num == 3) {
197 if (rssi_thresh > rssi_thresh1) {
198 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE,
199 "[BTCoex], wifi RSSI thresh error!!\n");
200 return coex_sta->pre_wifi_rssi_state[index];
201 }
202
203 if ((coex_sta->pre_wifi_rssi_state[index] ==
204 BTC_RSSI_STATE_LOW) ||
205 (coex_sta->pre_wifi_rssi_state[index] ==
206 BTC_RSSI_STATE_STAY_LOW)) {
207 if (wifi_rssi >=
208 (rssi_thresh+BTC_RSSI_COEX_THRESH_TOL_8821A_2ANT)) {
209 wifi_rssi_state = BTC_RSSI_STATE_MEDIUM;
210 BTC_PRINT(BTC_MSG_ALGORITHM,
211 ALGO_WIFI_RSSI_STATE,
212 "[BTCoex], wifi RSSI state switch to Medium\n");
213 } else {
214 wifi_rssi_state = BTC_RSSI_STATE_STAY_LOW;
215 BTC_PRINT(BTC_MSG_ALGORITHM,
216 ALGO_WIFI_RSSI_STATE,
217 "[BTCoex], wifi RSSI state stay at Low\n");
218 }
219 } else if ((coex_sta->pre_wifi_rssi_state[index] ==
220 BTC_RSSI_STATE_MEDIUM) ||
221 (coex_sta->pre_wifi_rssi_state[index] ==
222 BTC_RSSI_STATE_STAY_MEDIUM)) {
223 if (wifi_rssi >= (rssi_thresh1 +
224 BTC_RSSI_COEX_THRESH_TOL_8821A_2ANT)) {
225 wifi_rssi_state = BTC_RSSI_STATE_HIGH;
226 BTC_PRINT(BTC_MSG_ALGORITHM,
227 ALGO_WIFI_RSSI_STATE,
228 "[BTCoex], wifi RSSI state switch to High\n");
229 } else if (wifi_rssi < rssi_thresh) {
230 wifi_rssi_state = BTC_RSSI_STATE_LOW;
231 BTC_PRINT(BTC_MSG_ALGORITHM,
232 ALGO_WIFI_RSSI_STATE,
233 "[BTCoex], wifi RSSI state switch to Low\n");
234 } else {
235 wifi_rssi_state = BTC_RSSI_STATE_STAY_MEDIUM;
236 BTC_PRINT(BTC_MSG_ALGORITHM,
237 ALGO_WIFI_RSSI_STATE,
238 "[BTCoex], wifi RSSI state stay at Medium\n");
239 }
240 } else {
241 if (wifi_rssi < rssi_thresh1) {
242 wifi_rssi_state = BTC_RSSI_STATE_MEDIUM;
243 BTC_PRINT(BTC_MSG_ALGORITHM,
244 ALGO_WIFI_RSSI_STATE,
245 "[BTCoex], wifi RSSI state switch to Medium\n");
246 } else {
247 wifi_rssi_state = BTC_RSSI_STATE_STAY_HIGH;
248 BTC_PRINT(BTC_MSG_ALGORITHM,
249 ALGO_WIFI_RSSI_STATE,
250 "[BTCoex], wifi RSSI state stay at High\n");
251 }
252 }
253 }
254 coex_sta->pre_wifi_rssi_state[index] = wifi_rssi_state;
255
256 return wifi_rssi_state;
257}
258
259static void btc8821a2ant_mon_bt_en_dis(struct btc_coexist *btcoexist)
260{
261 static bool pre_bt_disabled;
262 static u32 bt_disable_cnt;
263 bool bt_active = true, bt_disabled = false;
264
265 /* This function check if bt is disabled*/
266
267 if (coex_sta->high_priority_tx == 0 &&
268 coex_sta->high_priority_rx == 0 &&
269 coex_sta->low_priority_tx == 0 &&
270 coex_sta->low_priority_rx == 0)
271 bt_active = false;
272 if (coex_sta->high_priority_tx == 0xffff &&
273 coex_sta->high_priority_rx == 0xffff &&
274 coex_sta->low_priority_tx == 0xffff &&
275 coex_sta->low_priority_rx == 0xffff)
276 bt_active = false;
277 if (bt_active) {
278 bt_disable_cnt = 0;
279 bt_disabled = false;
280 btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_DISABLE,
281 &bt_disabled);
282 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR,
283 "[BTCoex], BT is enabled !!\n");
284 } else {
285 bt_disable_cnt++;
286 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR,
287 "[BTCoex], bt all counters = 0, %d times!!\n",
288 bt_disable_cnt);
289 if (bt_disable_cnt >= 2) {
290 bt_disabled = true;
291 btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_DISABLE,
292 &bt_disabled);
293 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR,
294 "[BTCoex], BT is disabled !!\n");
295 }
296 }
297 if (pre_bt_disabled != bt_disabled) {
298 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR,
299 "[BTCoex], BT is from %s to %s!!\n",
300 (pre_bt_disabled ? "disabled" : "enabled"),
301 (bt_disabled ? "disabled" : "enabled"));
302 pre_bt_disabled = bt_disabled;
303 }
304}
305
306static void halbtc8821a2ant_monitor_bt_ctr(struct btc_coexist *btcoexist)
307{
308 u32 reg_hp_txrx, reg_lp_txrx, u4tmp;
309 u32 reg_hp_tx = 0, reg_hp_rx = 0, reg_lp_tx = 0, reg_lp_rx = 0;
310
311 reg_hp_txrx = 0x770;
312 reg_lp_txrx = 0x774;
313
314 u4tmp = btcoexist->btc_read_4byte(btcoexist, reg_hp_txrx);
315 reg_hp_tx = u4tmp & MASKLWORD;
316 reg_hp_rx = (u4tmp & MASKHWORD)>>16;
317
318 u4tmp = btcoexist->btc_read_4byte(btcoexist, reg_lp_txrx);
319 reg_lp_tx = u4tmp & MASKLWORD;
320 reg_lp_rx = (u4tmp & MASKHWORD)>>16;
321
322 coex_sta->high_priority_tx = reg_hp_tx;
323 coex_sta->high_priority_rx = reg_hp_rx;
324 coex_sta->low_priority_tx = reg_lp_tx;
325 coex_sta->low_priority_rx = reg_lp_rx;
326
327 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR,
328 "[BTCoex], High Priority Tx/Rx (reg 0x%x) = 0x%x(%d)/0x%x(%d)\n",
329 reg_hp_txrx, reg_hp_tx, reg_hp_tx, reg_hp_rx, reg_hp_rx);
330 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR,
331 "[BTCoex], Low Priority Tx/Rx (reg 0x%x) = 0x%x(%d)/0x%x(%d)\n",
332 reg_lp_txrx, reg_lp_tx, reg_lp_tx, reg_lp_rx, reg_lp_rx);
333
334 /* reset counter */
335 btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc);
336}
337
338static void halbtc8821a2ant_query_bt_info(struct btc_coexist *btcoexist)
339{
340 u8 h2c_parameter[1] = {0};
341
342 coex_sta->c2h_bt_info_req_sent = true;
343
344 h2c_parameter[0] |= BIT0; /* trigger */
345
346 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
347 "[BTCoex], Query Bt Info, FW write 0x61 = 0x%x\n",
348 h2c_parameter[0]);
349
350 btcoexist->btc_fill_h2c(btcoexist, 0x61, 1, h2c_parameter);
351}
352
353static u8 halbtc8821a2ant_action_algorithm(struct btc_coexist *btcoexist)
354{
355 struct btc_stack_info *stack_info = &btcoexist->stack_info;
356 bool bt_hs_on = false;
357 u8 algorithm = BT_8821A_2ANT_COEX_ALGO_UNDEFINED;
358 u8 num_of_diff_profile = 0;
359
360 btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
361
362 /*for win-8 stack HID report error*/
363 /* sync BTInfo with BT firmware and stack */
364 if (!stack_info->hid_exist)
365 stack_info->hid_exist = coex_sta->hid_exist;
366 /* when stack HID report error, here we use the info from bt fw. */
367 if (!stack_info->bt_link_exist)
368 stack_info->bt_link_exist = coex_sta->bt_link_exist;
369
370 if (!coex_sta->bt_link_exist) {
371 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
372 "[BTCoex], No profile exists!!!\n");
373 return algorithm;
374 }
375
376 if (coex_sta->sco_exist)
377 num_of_diff_profile++;
378 if (coex_sta->hid_exist)
379 num_of_diff_profile++;
380 if (coex_sta->pan_exist)
381 num_of_diff_profile++;
382 if (coex_sta->a2dp_exist)
383 num_of_diff_profile++;
384
385 if (num_of_diff_profile == 1) {
386 if (coex_sta->sco_exist) {
387 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
388 "[BTCoex], SCO only\n");
389 algorithm = BT_8821A_2ANT_COEX_ALGO_SCO;
390 } else {
391 if (coex_sta->hid_exist) {
392 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
393 "[BTCoex], HID only\n");
394 algorithm = BT_8821A_2ANT_COEX_ALGO_HID;
395 } else if (coex_sta->a2dp_exist) {
396 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
397 "[BTCoex], A2DP only\n");
398 algorithm = BT_8821A_2ANT_COEX_ALGO_A2DP;
399 } else if (coex_sta->pan_exist) {
400 if (bt_hs_on) {
401 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
402 "[BTCoex], PAN(HS) only\n");
403 algorithm = BT_8821A_2ANT_COEX_ALGO_PANHS;
404 } else {
405 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
406 "[BTCoex], PAN(EDR) only\n");
407 algorithm = BT_8821A_2ANT_COEX_ALGO_PANEDR;
408 }
409 }
410 }
411 } else if (num_of_diff_profile == 2) {
412 if (coex_sta->sco_exist) {
413 if (coex_sta->hid_exist) {
414 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
415 "[BTCoex], SCO + HID\n");
416 algorithm = BT_8821A_2ANT_COEX_ALGO_PANEDR_HID;
417 } else if (coex_sta->a2dp_exist) {
418 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
419 "[BTCoex], SCO + A2DP ==> SCO\n");
420 algorithm = BT_8821A_2ANT_COEX_ALGO_PANEDR_HID;
421 } else if (coex_sta->pan_exist) {
422 if (bt_hs_on) {
423 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
424 "[BTCoex], SCO + PAN(HS)\n");
425 algorithm = BT_8821A_2ANT_COEX_ALGO_SCO;
426 } else {
427 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
428 "[BTCoex], SCO + PAN(EDR)\n");
429 algorithm = BT_8821A_2ANT_COEX_ALGO_PANEDR_HID;
430 }
431 }
432 } else {
433 if (coex_sta->hid_exist &&
434 coex_sta->a2dp_exist) {
435 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
436 "[BTCoex], HID + A2DP\n");
437 algorithm = BT_8821A_2ANT_COEX_ALGO_HID_A2DP;
438 } else if (coex_sta->hid_exist &&
439 coex_sta->pan_exist) {
440 if (bt_hs_on) {
441 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
442 "[BTCoex], HID + PAN(HS)\n");
443 algorithm = BT_8821A_2ANT_COEX_ALGO_HID;
444 } else {
445 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
446 "[BTCoex], HID + PAN(EDR)\n");
447 algorithm = BT_8821A_2ANT_COEX_ALGO_PANEDR_HID;
448 }
449 } else if (coex_sta->pan_exist &&
450 coex_sta->a2dp_exist) {
451 if (bt_hs_on) {
452 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
453 "[BTCoex], A2DP + PAN(HS)\n");
454 algorithm = BT_8821A_2ANT_COEX_ALGO_A2DP_PANHS;
455 } else {
456 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
457 "[BTCoex], A2DP + PAN(EDR)\n");
458 algorithm = BT_8821A_2ANT_COEX_ALGO_PANEDR_A2DP;
459 }
460 }
461 }
462 } else if (num_of_diff_profile == 3) {
463 if (coex_sta->sco_exist) {
464 if (coex_sta->hid_exist &&
465 coex_sta->a2dp_exist) {
466 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
467 "[BTCoex], SCO + HID + A2DP ==> HID\n");
468 algorithm = BT_8821A_2ANT_COEX_ALGO_PANEDR_HID;
469 } else if (coex_sta->hid_exist &&
470 coex_sta->pan_exist) {
471 if (bt_hs_on) {
472 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
473 "[BTCoex], SCO + HID + PAN(HS)\n");
474 algorithm = BT_8821A_2ANT_COEX_ALGO_PANEDR_HID;
475 } else {
476 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
477 "[BTCoex], SCO + HID + PAN(EDR)\n");
478 algorithm = BT_8821A_2ANT_COEX_ALGO_PANEDR_HID;
479 }
480 } else if (coex_sta->pan_exist &&
481 coex_sta->a2dp_exist) {
482 if (bt_hs_on) {
483 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
484 "[BTCoex], SCO + A2DP + PAN(HS)\n");
485 algorithm = BT_8821A_2ANT_COEX_ALGO_PANEDR_HID;
486 } else {
487 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
488 "[BTCoex], SCO + A2DP + PAN(EDR) ==> HID\n");
489 algorithm = BT_8821A_2ANT_COEX_ALGO_PANEDR_HID;
490 }
491 }
492 } else {
493 if (coex_sta->hid_exist &&
494 coex_sta->pan_exist &&
495 coex_sta->a2dp_exist) {
496 if (bt_hs_on) {
497 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
498 "[BTCoex], HID + A2DP + PAN(HS)\n");
499 algorithm = BT_8821A_2ANT_COEX_ALGO_HID_A2DP;
500 } else {
501 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
502 "[BTCoex], HID + A2DP + PAN(EDR)\n");
503 algorithm = BT_8821A_2ANT_COEX_ALGO_HID_A2DP_PANEDR;
504 }
505 }
506 }
507 } else if (num_of_diff_profile >= 3) {
508 if (coex_sta->sco_exist) {
509 if (coex_sta->hid_exist &&
510 coex_sta->pan_exist &&
511 coex_sta->a2dp_exist) {
512 if (bt_hs_on) {
513 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
514 "[BTCoex], Error!!! SCO + HID + A2DP + PAN(HS)\n");
515
516 } else {
517 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
518 "[BTCoex], SCO + HID + A2DP + PAN(EDR)==>PAN(EDR)+HID\n");
519 algorithm = BT_8821A_2ANT_COEX_ALGO_PANEDR_HID;
520 }
521 }
522 }
523 }
524 return algorithm;
525}
526
527static bool halbtc8821a2ant_need_to_dec_bt_pwr(struct btc_coexist *btcoexist)
528{
529 bool ret = false;
530 bool bt_hs_on = false, wifi_connected = false;
531 long bt_hs_rssi = 0;
532 u8 bt_rssi_state;
533
534 if (!btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on))
535 return false;
536 if (!btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
537 &wifi_connected))
538 return false;
539 if (!btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi))
540 return false;
541
542 bt_rssi_state = halbtc8821a2ant_bt_rssi_state(2, 35, 0);
543
544 if (wifi_connected) {
545 if (bt_hs_on) {
546 if (bt_hs_rssi > 37) {
547 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW,
548 "[BTCoex], Need to decrease bt power for HS mode!!\n");
549 ret = true;
550 }
551 } else {
552 if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
553 (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
554 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW,
555 "[BTCoex], Need to decrease bt power for Wifi is connected!!\n");
556 ret = true;
557 }
558 }
559 }
560 return ret;
561}
562
563static void btc8821a2ant_set_fw_dac_swing_lev(struct btc_coexist *btcoexist,
564 u8 dac_swing_lvl)
565{
566 u8 h2c_parameter[1] = {0};
567
568 /* There are several type of dacswing
569 * 0x18/ 0x10/ 0xc/ 0x8/ 0x4/ 0x6
570 */
571 h2c_parameter[0] = dac_swing_lvl;
572
573 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
574 "[BTCoex], Set Dac Swing Level = 0x%x\n", dac_swing_lvl);
575 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
576 "[BTCoex], FW write 0x64 = 0x%x\n", h2c_parameter[0]);
577
578 btcoexist->btc_fill_h2c(btcoexist, 0x64, 1, h2c_parameter);
579}
580
581static void halbtc8821a2ant_set_fw_dec_bt_pwr(struct btc_coexist *btcoexist,
582 bool dec_bt_pwr)
583{
584 u8 h2c_parameter[1] = {0};
585
586 h2c_parameter[0] = 0;
587
588 if (dec_bt_pwr)
589 h2c_parameter[0] |= BIT1;
590
591 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
592 "[BTCoex], decrease Bt Power : %s, FW write 0x62 = 0x%x\n",
593 (dec_bt_pwr ? "Yes!!" : "No!!"), h2c_parameter[0]);
594
595 btcoexist->btc_fill_h2c(btcoexist, 0x62, 1, h2c_parameter);
596}
597
598static void halbtc8821a2ant_dec_bt_pwr(struct btc_coexist *btcoexist,
599 bool force_exec, bool dec_bt_pwr)
600{
601 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW,
602 "[BTCoex], %s Dec BT power = %s\n",
603 (force_exec ? "force to" : ""),
604 ((dec_bt_pwr) ? "ON" : "OFF"));
605 coex_dm->cur_dec_bt_pwr = dec_bt_pwr;
606
607 if (!force_exec) {
608 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
609 "[BTCoex], pre_dec_bt_pwr = %d, cur_dec_bt_pwr = %d\n",
610 coex_dm->pre_dec_bt_pwr, coex_dm->cur_dec_bt_pwr);
611
612 if (coex_dm->pre_dec_bt_pwr == coex_dm->cur_dec_bt_pwr)
613 return;
614 }
615 halbtc8821a2ant_set_fw_dec_bt_pwr(btcoexist, coex_dm->cur_dec_bt_pwr);
616
617 coex_dm->pre_dec_bt_pwr = coex_dm->cur_dec_bt_pwr;
618}
619
620static void btc8821a2ant_set_fw_bt_lna_constr(struct btc_coexist *btcoexist,
621 bool bt_lna_cons_on)
622{
623 u8 h2c_parameter[2] = {0};
624
625 h2c_parameter[0] = 0x3; /* opCode, 0x3 = BT_SET_LNA_CONSTRAIN */
626
627 if (bt_lna_cons_on)
628 h2c_parameter[1] |= BIT0;
629
630 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
631 "[BTCoex], set BT LNA Constrain: %s, FW write 0x69 = 0x%x\n",
632 (bt_lna_cons_on ? "ON!!" : "OFF!!"),
633 h2c_parameter[0]<<8|h2c_parameter[1]);
634
635 btcoexist->btc_fill_h2c(btcoexist, 0x69, 2, h2c_parameter);
636}
637
638static void btc8821a2_set_bt_lna_const(struct btc_coexist *btcoexist,
639 bool force_exec, bool bt_lna_cons_on)
640{
641 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW,
642 "[BTCoex], %s BT Constrain = %s\n",
643 (force_exec ? "force" : ""),
644 ((bt_lna_cons_on) ? "ON" : "OFF"));
645 coex_dm->cur_bt_lna_constrain = bt_lna_cons_on;
646
647 if (!force_exec) {
648 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
649 "[BTCoex], pre_bt_lna_constrain = %d,cur_bt_lna_constrain = %d\n",
650 coex_dm->pre_bt_lna_constrain,
651 coex_dm->cur_bt_lna_constrain);
652
653 if (coex_dm->pre_bt_lna_constrain ==
654 coex_dm->cur_bt_lna_constrain)
655 return;
656 }
657 btc8821a2ant_set_fw_bt_lna_constr(btcoexist,
658 coex_dm->cur_bt_lna_constrain);
659
660 coex_dm->pre_bt_lna_constrain = coex_dm->cur_bt_lna_constrain;
661}
662
663static void halbtc8821a2ant_set_fw_bt_psd_mode(struct btc_coexist *btcoexist,
664 u8 bt_psd_mode)
665{
666 u8 h2c_parameter[2] = {0};
667
668 h2c_parameter[0] = 0x2; /* opCode, 0x2 = BT_SET_PSD_MODE */
669
670 h2c_parameter[1] = bt_psd_mode;
671
672 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
673 "[BTCoex], set BT PSD mode = 0x%x, FW write 0x69 = 0x%x\n",
674 h2c_parameter[1],
675 h2c_parameter[0]<<8|h2c_parameter[1]);
676
677 btcoexist->btc_fill_h2c(btcoexist, 0x69, 2, h2c_parameter);
678}
679
680static void halbtc8821a2ant_set_bt_psd_mode(struct btc_coexist *btcoexist,
681 bool force_exec, u8 bt_psd_mode)
682{
683 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW,
684 "[BTCoex], %s BT PSD mode = 0x%x\n",
685 (force_exec ? "force" : ""), bt_psd_mode);
686 coex_dm->cur_bt_psd_mode = bt_psd_mode;
687
688 if (!force_exec) {
689 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
690 "[BTCoex], pre_bt_psd_mode = 0x%x, cur_bt_psd_mode = 0x%x\n",
691 coex_dm->pre_bt_psd_mode, coex_dm->cur_bt_psd_mode);
692
693 if (coex_dm->pre_bt_psd_mode == coex_dm->cur_bt_psd_mode)
694 return;
695 }
696 halbtc8821a2ant_set_fw_bt_psd_mode(btcoexist,
697 coex_dm->cur_bt_psd_mode);
698
699 coex_dm->pre_bt_psd_mode = coex_dm->cur_bt_psd_mode;
700}
701
702static void halbtc8821a2ant_set_bt_auto_report(struct btc_coexist *btcoexist,
703 bool enable_auto_report)
704{
705 u8 h2c_parameter[1] = {0};
706
707 h2c_parameter[0] = 0;
708
709 if (enable_auto_report)
710 h2c_parameter[0] |= BIT0;
711
712 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
713 "[BTCoex], BT FW auto report : %s, FW write 0x68 = 0x%x\n",
714 (enable_auto_report ? "Enabled!!" : "Disabled!!"),
715 h2c_parameter[0]);
716
717 btcoexist->btc_fill_h2c(btcoexist, 0x68, 1, h2c_parameter);
718}
719
720static void halbtc8821a2ant_bt_auto_report(struct btc_coexist *btcoexist,
721 bool force_exec,
722 bool enable_auto_report)
723{
724 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW,
725 "[BTCoex], %s BT Auto report = %s\n",
726 (force_exec ? "force to" : ""),
727 ((enable_auto_report) ? "Enabled" : "Disabled"));
728 coex_dm->cur_bt_auto_report = enable_auto_report;
729
730 if (!force_exec) {
731 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
732 "[BTCoex], pre_bt_auto_report = %d, cur_bt_auto_report = %d\n",
733 coex_dm->pre_bt_auto_report,
734 coex_dm->cur_bt_auto_report);
735
736 if (coex_dm->pre_bt_auto_report == coex_dm->cur_bt_auto_report)
737 return;
738 }
739 halbtc8821a2ant_set_bt_auto_report(btcoexist,
740 coex_dm->cur_bt_auto_report);
741
742 coex_dm->pre_bt_auto_report = coex_dm->cur_bt_auto_report;
743}
744
745static void halbtc8821a2ant_fw_dac_swing_lvl(struct btc_coexist *btcoexist,
746 bool force_exec,
747 u8 fw_dac_swing_lvl)
748{
749 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW,
750 "[BTCoex], %s set FW Dac Swing level = %d\n",
751 (force_exec ? "force to" : ""), fw_dac_swing_lvl);
752 coex_dm->cur_fw_dac_swing_lvl = fw_dac_swing_lvl;
753
754 if (!force_exec) {
755 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
756 "[BTCoex], pre_fw_dac_swing_lvl = %d, cur_fw_dac_swing_lvl = %d\n",
757 coex_dm->pre_fw_dac_swing_lvl,
758 coex_dm->cur_fw_dac_swing_lvl);
759
760 if (coex_dm->pre_fw_dac_swing_lvl ==
761 coex_dm->cur_fw_dac_swing_lvl)
762 return;
763 }
764
765 btc8821a2ant_set_fw_dac_swing_lev(btcoexist,
766 coex_dm->cur_fw_dac_swing_lvl);
767
768 coex_dm->pre_fw_dac_swing_lvl = coex_dm->cur_fw_dac_swing_lvl;
769}
770
771static void btc8821a2ant_set_sw_rf_rx_lpf_corner(struct btc_coexist *btcoexist,
772 bool rx_rf_shrink_on)
773{
774 if (rx_rf_shrink_on) {
775 /* Shrink RF Rx LPF corner */
776 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
777 "[BTCoex], Shrink RF Rx LPF corner!!\n");
778 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1e,
779 0xfffff, 0xffffc);
780 } else {
781 /* Resume RF Rx LPF corner
782 * After initialized, we can use coex_dm->bt_rf0x1e_backup
783 */
784 if (btcoexist->initilized) {
785 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
786 "[BTCoex], Resume RF Rx LPF corner!!\n");
787 btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A,
788 0x1e, 0xfffff,
789 coex_dm->bt_rf0x1e_backup);
790 }
791 }
792}
793
794static void halbtc8821a2ant_RfShrink(struct btc_coexist *btcoexist,
795 bool force_exec, bool rx_rf_shrink_on)
796{
797 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW,
798 "[BTCoex], %s turn Rx RF Shrink = %s\n",
799 (force_exec ? "force to" : ""),
800 ((rx_rf_shrink_on) ? "ON" : "OFF"));
801 coex_dm->cur_rf_rx_lpf_shrink = rx_rf_shrink_on;
802
803 if (!force_exec) {
804 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL,
805 "[BTCoex], pre_rf_rx_lpf_shrink = %d, cur_rf_rx_lpf_shrink = %d\n",
806 coex_dm->pre_rf_rx_lpf_shrink,
807 coex_dm->cur_rf_rx_lpf_shrink);
808
809 if (coex_dm->pre_rf_rx_lpf_shrink ==
810 coex_dm->cur_rf_rx_lpf_shrink)
811 return;
812 }
813 btc8821a2ant_set_sw_rf_rx_lpf_corner(btcoexist,
814 coex_dm->cur_rf_rx_lpf_shrink);
815
816 coex_dm->pre_rf_rx_lpf_shrink = coex_dm->cur_rf_rx_lpf_shrink;
817}
818
819static void btc8821a2ant_SetSwPenTxRateAdapt(struct btc_coexist *btcoexist,
820 bool low_penalty_ra)
821{
822 u8 h2c_parameter[6] = {0};
823
824 h2c_parameter[0] = 0x6; /* opCode, 0x6 = Retry_Penalty */
825
826 if (low_penalty_ra) {
827 h2c_parameter[1] |= BIT0;
828 /*normal rate except MCS7/6/5, OFDM54/48/36 */
829 h2c_parameter[2] = 0x00;
830 /*MCS7 or OFDM54 */
831 h2c_parameter[3] = 0xf7;
832 /*MCS6 or OFDM48 */
833 h2c_parameter[4] = 0xf8;
834 /*MCS5 or OFDM36 */
835 h2c_parameter[5] = 0xf9;
836 }
837
838 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
839 "[BTCoex], set WiFi Low-Penalty Retry: %s",
840 (low_penalty_ra ? "ON!!" : "OFF!!"));
841
842 btcoexist->btc_fill_h2c(btcoexist, 0x69, 6, h2c_parameter);
843}
844
845static void halbtc8821a2ant_low_penalty_ra(struct btc_coexist *btcoexist,
846 bool force_exec, bool low_penalty_ra)
847{
848 /*return;*/
849 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW,
850 "[BTCoex], %s turn LowPenaltyRA = %s\n",
851 (force_exec ? "force to" : ""),
852 ((low_penalty_ra) ? "ON" : "OFF"));
853 coex_dm->cur_low_penalty_ra = low_penalty_ra;
854
855 if (!force_exec) {
856 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL,
857 "[BTCoex], pre_low_penalty_ra = %d, cur_low_penalty_ra = %d\n",
858 coex_dm->pre_low_penalty_ra,
859 coex_dm->cur_low_penalty_ra);
860
861 if (coex_dm->pre_low_penalty_ra == coex_dm->cur_low_penalty_ra)
862 return;
863 }
864 btc8821a2ant_SetSwPenTxRateAdapt(btcoexist,
865 coex_dm->cur_low_penalty_ra);
866
867 coex_dm->pre_low_penalty_ra = coex_dm->cur_low_penalty_ra;
868}
869
870static void halbtc8821a2ant_set_dac_swing_reg(struct btc_coexist *btcoexist,
871 u32 level)
872{
873 u8 val = (u8)level;
874
875 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
876 "[BTCoex], Write SwDacSwing = 0x%x\n", level);
877 btcoexist->btc_write_1byte_bitmask(btcoexist, 0xc5b, 0x3e, val);
878}
879
880static void btc8821a2ant_set_sw_full_dac_swing(struct btc_coexist *btcoexist,
881 bool sw_dac_swing_on,
882 u32 sw_dac_swing_lvl)
883{
884 if (sw_dac_swing_on)
885 halbtc8821a2ant_set_dac_swing_reg(btcoexist, sw_dac_swing_lvl);
886 else
887 halbtc8821a2ant_set_dac_swing_reg(btcoexist, 0x18);
888}
889
890static void halbtc8821a2ant_dac_swing(struct btc_coexist *btcoexist,
891 bool force_exec, bool dac_swing_on,
892 u32 dac_swing_lvl)
893{
894 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW,
895 "[BTCoex], %s turn DacSwing = %s, dac_swing_lvl = 0x%x\n",
896 (force_exec ? "force to" : ""),
897 ((dac_swing_on) ? "ON" : "OFF"),
898 dac_swing_lvl);
899 coex_dm->cur_dac_swing_on = dac_swing_on;
900 coex_dm->cur_dac_swing_lvl = dac_swing_lvl;
901
902 if (!force_exec) {
903 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL,
904 "[BTCoex], pre_dac_swing_on = %d, pre_dac_swing_lvl = 0x%x, cur_dac_swing_on = %d, cur_dac_swing_lvl = 0x%x\n",
905 coex_dm->pre_dac_swing_on,
906 coex_dm->pre_dac_swing_lvl,
907 coex_dm->cur_dac_swing_on,
908 coex_dm->cur_dac_swing_lvl);
909
910 if ((coex_dm->pre_dac_swing_on == coex_dm->cur_dac_swing_on) &&
911 (coex_dm->pre_dac_swing_lvl ==
912 coex_dm->cur_dac_swing_lvl))
913 return;
914 }
915 mdelay(30);
916 btc8821a2ant_set_sw_full_dac_swing(btcoexist, dac_swing_on,
917 dac_swing_lvl);
918
919 coex_dm->pre_dac_swing_on = coex_dm->cur_dac_swing_on;
920 coex_dm->pre_dac_swing_lvl = coex_dm->cur_dac_swing_lvl;
921}
922
923static void halbtc8821a2ant_set_adc_back_off(struct btc_coexist *btcoexist,
924 bool adc_back_off)
925{
926 if (adc_back_off) {
927 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
928 "[BTCoex], BB BackOff Level On!\n");
929 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x8db, 0x60, 0x3);
930 } else {
931 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
932 "[BTCoex], BB BackOff Level Off!\n");
933 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x8db, 0x60, 0x1);
934 }
935}
936
937static void halbtc8821a2ant_adc_back_off(struct btc_coexist *btcoexist,
938 bool force_exec, bool adc_back_off)
939{
940 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW,
941 "[BTCoex], %s turn AdcBackOff = %s\n",
942 (force_exec ? "force to" : ""),
943 ((adc_back_off) ? "ON" : "OFF"));
944 coex_dm->cur_adc_back_off = adc_back_off;
945
946 if (!force_exec) {
947 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL,
948 "[BTCoex], pre_adc_back_off = %d, cur_adc_back_off = %d\n",
949 coex_dm->pre_adc_back_off, coex_dm->cur_adc_back_off);
950
951 if (coex_dm->pre_adc_back_off == coex_dm->cur_adc_back_off)
952 return;
953 }
954 halbtc8821a2ant_set_adc_back_off(btcoexist, coex_dm->cur_adc_back_off);
955
956 coex_dm->pre_adc_back_off = coex_dm->cur_adc_back_off;
957}
958
959static void halbtc8821a2ant_set_coex_table(struct btc_coexist *btcoexist,
960 u32 val0x6c0, u32 val0x6c4,
961 u32 val0x6c8, u8 val0x6cc)
962{
963 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
964 "[BTCoex], set coex table, set 0x6c0 = 0x%x\n", val0x6c0);
965 btcoexist->btc_write_4byte(btcoexist, 0x6c0, val0x6c0);
966
967 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
968 "[BTCoex], set coex table, set 0x6c4 = 0x%x\n", val0x6c4);
969 btcoexist->btc_write_4byte(btcoexist, 0x6c4, val0x6c4);
970
971 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
972 "[BTCoex], set coex table, set 0x6c8 = 0x%x\n", val0x6c8);
973 btcoexist->btc_write_4byte(btcoexist, 0x6c8, val0x6c8);
974
975 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
976 "[BTCoex], set coex table, set 0x6cc = 0x%x\n", val0x6cc);
977 btcoexist->btc_write_1byte(btcoexist, 0x6cc, val0x6cc);
978}
979
980static void halbtc8821a2ant_coex_table(struct btc_coexist *btcoexist,
981 bool force_exec, u32 val0x6c0,
982 u32 val0x6c4, u32 val0x6c8, u8 val0x6cc)
983{
984 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW,
985 "[BTCoex], %s write Coex Table 0x6c0 = 0x%x, 0x6c4 = 0x%x, 0x6c8 = 0x%x, 0x6cc = 0x%x\n",
986 (force_exec ? "force to" : ""),
987 val0x6c0, val0x6c4, val0x6c8, val0x6cc);
988 coex_dm->cur_val0x6c0 = val0x6c0;
989 coex_dm->cur_val0x6c4 = val0x6c4;
990 coex_dm->cur_val0x6c8 = val0x6c8;
991 coex_dm->cur_val0x6cc = val0x6cc;
992
993 if (!force_exec) {
994 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL,
995 "[BTCoex], pre_val0x6c0 = 0x%x, pre_val0x6c4 = 0x%x, pre_val0x6c8 = 0x%x, pre_val0x6cc = 0x%x !!\n",
996 coex_dm->pre_val0x6c0,
997 coex_dm->pre_val0x6c4,
998 coex_dm->pre_val0x6c8,
999 coex_dm->pre_val0x6cc);
1000 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL,
1001 "[BTCoex], cur_val0x6c0 = 0x%x, cur_val0x6c4 = 0x%x, cur_val0x6c8 = 0x%x, cur_val0x6cc = 0x%x !!\n",
1002 coex_dm->cur_val0x6c0,
1003 coex_dm->cur_val0x6c4,
1004 coex_dm->cur_val0x6c8,
1005 coex_dm->cur_val0x6cc);
1006
1007 if ((coex_dm->pre_val0x6c0 == coex_dm->cur_val0x6c0) &&
1008 (coex_dm->pre_val0x6c4 == coex_dm->cur_val0x6c4) &&
1009 (coex_dm->pre_val0x6c8 == coex_dm->cur_val0x6c8) &&
1010 (coex_dm->pre_val0x6cc == coex_dm->cur_val0x6cc))
1011 return;
1012 }
1013 halbtc8821a2ant_set_coex_table(btcoexist, val0x6c0, val0x6c4, val0x6c8,
1014 val0x6cc);
1015
1016 coex_dm->pre_val0x6c0 = coex_dm->cur_val0x6c0;
1017 coex_dm->pre_val0x6c4 = coex_dm->cur_val0x6c4;
1018 coex_dm->pre_val0x6c8 = coex_dm->cur_val0x6c8;
1019 coex_dm->pre_val0x6cc = coex_dm->cur_val0x6cc;
1020}
1021
1022static void halbtc8821a2ant_set_fw_ignore_wlan_act(struct btc_coexist *btcoex,
1023 bool enable)
1024{
1025 u8 h2c_parameter[1] = {0};
1026
1027 if (enable)
1028 h2c_parameter[0] |= BIT0;/* function enable */
1029
1030 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
1031 "[BTCoex], set FW for BT Ignore Wlan_Act, FW write 0x63 = 0x%x\n",
1032 h2c_parameter[0]);
1033
1034 btcoex->btc_fill_h2c(btcoex, 0x63, 1, h2c_parameter);
1035}
1036
1037static void halbtc8821a2ant_ignore_wlan_act(struct btc_coexist *btcoexist,
1038 bool force_exec, bool enable)
1039{
1040 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW,
1041 "[BTCoex], %s turn Ignore WlanAct %s\n",
1042 (force_exec ? "force to" : ""), (enable ? "ON" : "OFF"));
1043 coex_dm->cur_ignore_wlan_act = enable;
1044
1045 if (!force_exec) {
1046 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
1047 "[BTCoex], pre_ignore_wlan_act = %d, cur_ignore_wlan_act = %d!!\n",
1048 coex_dm->pre_ignore_wlan_act,
1049 coex_dm->cur_ignore_wlan_act);
1050
1051 if (coex_dm->pre_ignore_wlan_act ==
1052 coex_dm->cur_ignore_wlan_act)
1053 return;
1054 }
1055 halbtc8821a2ant_set_fw_ignore_wlan_act(btcoexist, enable);
1056
1057 coex_dm->pre_ignore_wlan_act = coex_dm->cur_ignore_wlan_act;
1058}
1059
1060static void halbtc8821a2ant_set_fw_pstdma(struct btc_coexist *btcoexist,
1061 u8 byte1, u8 byte2, u8 byte3,
1062 u8 byte4, u8 byte5)
1063{
1064 u8 h2c_parameter[5];
1065
1066 h2c_parameter[0] = byte1;
1067 h2c_parameter[1] = byte2;
1068 h2c_parameter[2] = byte3;
1069 h2c_parameter[3] = byte4;
1070 h2c_parameter[4] = byte5;
1071
1072 coex_dm->ps_tdma_para[0] = byte1;
1073 coex_dm->ps_tdma_para[1] = byte2;
1074 coex_dm->ps_tdma_para[2] = byte3;
1075 coex_dm->ps_tdma_para[3] = byte4;
1076 coex_dm->ps_tdma_para[4] = byte5;
1077
1078 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
1079 "[BTCoex], FW write 0x60(5bytes) = 0x%x%08x\n",
1080 h2c_parameter[0],
1081 h2c_parameter[1]<<24|
1082 h2c_parameter[2]<<16|
1083 h2c_parameter[3]<<8|
1084 h2c_parameter[4]);
1085
1086 btcoexist->btc_fill_h2c(btcoexist, 0x60, 5, h2c_parameter);
1087}
1088
1089static void btc8821a2ant_sw_mech1(struct btc_coexist *btcoexist,
1090 bool shrink_rx_lpf,
1091 bool low_penalty_ra, bool limited_dig,
1092 bool bt_lna_constrain)
1093{
1094 u32 wifi_bw;
1095
1096 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
1097
1098 if (BTC_WIFI_BW_HT40 != wifi_bw) {
1099 /*only shrink RF Rx LPF for HT40*/
1100 if (shrink_rx_lpf)
1101 shrink_rx_lpf = false;
1102 }
1103
1104 halbtc8821a2ant_RfShrink(btcoexist, NORMAL_EXEC, shrink_rx_lpf);
1105 halbtc8821a2ant_low_penalty_ra(btcoexist,
1106 NORMAL_EXEC, low_penalty_ra);
1107
1108 /* no limited DIG
1109 * btc8821a2_set_bt_lna_const(btcoexist,
1110 NORMAL_EXEC, bBTLNAConstrain);
1111 */
1112}
1113
1114static void btc8821a2ant_sw_mech2(struct btc_coexist *btcoexist,
1115 bool agc_table_shift,
1116 bool adc_back_off, bool sw_dac_swing,
1117 u32 dac_swing_lvl)
1118{
1119 /* halbtc8821a2ant_AgcTable(btcoexist, NORMAL_EXEC, bAGCTableShift); */
1120 halbtc8821a2ant_adc_back_off(btcoexist, NORMAL_EXEC, adc_back_off);
1121 halbtc8821a2ant_dac_swing(btcoexist, NORMAL_EXEC, sw_dac_swing,
1122 sw_dac_swing);
1123}
1124
1125static void halbtc8821a2ant_set_ant_path(struct btc_coexist *btcoexist,
1126 u8 ant_pos_type, bool init_hw_cfg,
1127 bool wifi_off)
1128{
1129 struct btc_board_info *board_info = &btcoexist->board_info;
1130 u32 u4tmp = 0;
1131 u8 h2c_parameter[2] = {0};
1132
1133 if (init_hw_cfg) {
1134 /* 0x4c[23] = 0, 0x4c[24] = 1 Antenna control by WL/BT */
1135 u4tmp = btcoexist->btc_read_4byte(btcoexist, 0x4c);
1136 u4tmp &= ~BIT23;
1137 u4tmp |= BIT24;
1138 btcoexist->btc_write_4byte(btcoexist, 0x4c, u4tmp);
1139
1140 btcoexist->btc_write_4byte(btcoexist, 0x974, 0x3ff);
1141 btcoexist->btc_write_1byte(btcoexist, 0xcb4, 0x77);
1142
1143 if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT) {
1144 /* tell firmware "antenna inverse" ==>
1145 * WRONG firmware antenna control code.
1146 * ==>need fw to fix
1147 */
1148 h2c_parameter[0] = 1;
1149 h2c_parameter[1] = 1;
1150 btcoexist->btc_fill_h2c(btcoexist, 0x65, 2,
1151 h2c_parameter);
1152 } else {
1153 /* tell firmware "no antenna inverse"
1154 * ==> WRONG firmware antenna control code.
1155 * ==>need fw to fix
1156 */
1157 h2c_parameter[0] = 0;
1158 h2c_parameter[1] = 1;
1159 btcoexist->btc_fill_h2c(btcoexist, 0x65, 2,
1160 h2c_parameter);
1161 }
1162 }
1163
1164 /* ext switch setting */
1165 switch (ant_pos_type) {
1166 case BTC_ANT_WIFI_AT_MAIN:
1167 btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb7, 0x30, 0x1);
1168 break;
1169 case BTC_ANT_WIFI_AT_AUX:
1170 btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb7, 0x30, 0x2);
1171 break;
1172 }
1173}
1174
1175static void halbtc8821a2ant_ps_tdma(struct btc_coexist *btcoexist,
1176 bool force_exec, bool turn_on, u8 type)
1177{
1178 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW,
1179 "[BTCoex], %s turn %s PS TDMA, type = %d\n",
1180 (force_exec ? "force to" : ""), (turn_on ? "ON" : "OFF"),
1181 type);
1182 coex_dm->cur_ps_tdma_on = turn_on;
1183 coex_dm->cur_ps_tdma = type;
1184
1185 if (!force_exec) {
1186 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
1187 "[BTCoex], pre_ps_tdma_on = %d, cur_ps_tdma_on = %d!!\n",
1188 coex_dm->pre_ps_tdma_on, coex_dm->cur_ps_tdma_on);
1189 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
1190 "[BTCoex], pre_ps_tdma = %d, cur_ps_tdma = %d!!\n",
1191 coex_dm->pre_ps_tdma, coex_dm->cur_ps_tdma);
1192
1193 if ((coex_dm->pre_ps_tdma_on == coex_dm->cur_ps_tdma_on) &&
1194 (coex_dm->pre_ps_tdma == coex_dm->cur_ps_tdma))
1195 return;
1196 }
1197 if (turn_on) {
1198 switch (type) {
1199 case 1:
1200 default:
1201 halbtc8821a2ant_set_fw_pstdma(btcoexist, 0xe3, 0x1a,
1202 0x1a, 0xe1, 0x90);
1203 break;
1204 case 2:
1205 halbtc8821a2ant_set_fw_pstdma(btcoexist, 0xe3, 0x12,
1206 0x12, 0xe1, 0x90);
1207 break;
1208 case 3:
1209 halbtc8821a2ant_set_fw_pstdma(btcoexist, 0xe3, 0x1c,
1210 0x3, 0xf1, 0x90);
1211 break;
1212 case 4:
1213 halbtc8821a2ant_set_fw_pstdma(btcoexist, 0xe3, 0x10,
1214 0x03, 0xf1, 0x90);
1215 break;
1216 case 5:
1217 halbtc8821a2ant_set_fw_pstdma(btcoexist, 0xe3, 0x1a,
1218 0x1a, 0x60, 0x90);
1219 break;
1220 case 6:
1221 halbtc8821a2ant_set_fw_pstdma(btcoexist, 0xe3, 0x12,
1222 0x12, 0x60, 0x90);
1223 break;
1224 case 7:
1225 halbtc8821a2ant_set_fw_pstdma(btcoexist, 0xe3, 0x1c,
1226 0x3, 0x70, 0x90);
1227 break;
1228 case 8:
1229 halbtc8821a2ant_set_fw_pstdma(btcoexist, 0xa3, 0x10,
1230 0x3, 0x70, 0x90);
1231 break;
1232 case 9:
1233 halbtc8821a2ant_set_fw_pstdma(btcoexist, 0xe3, 0x1a,
1234 0x1a, 0xe1, 0x90);
1235 break;
1236 case 10:
1237 halbtc8821a2ant_set_fw_pstdma(btcoexist, 0xe3, 0x12,
1238 0x12, 0xe1, 0x90);
1239 break;
1240 case 11:
1241 halbtc8821a2ant_set_fw_pstdma(btcoexist, 0xe3, 0xa,
1242 0xa, 0xe1, 0x90);
1243 break;
1244 case 12:
1245 halbtc8821a2ant_set_fw_pstdma(btcoexist, 0xe3, 0x5,
1246 0x5, 0xe1, 0x90);
1247 break;
1248 case 13:
1249 halbtc8821a2ant_set_fw_pstdma(btcoexist, 0xe3, 0x1a,
1250 0x1a, 0x60, 0x90);
1251 break;
1252 case 14:
1253 halbtc8821a2ant_set_fw_pstdma(btcoexist, 0xe3,
1254 0x12, 0x12, 0x60, 0x90);
1255 break;
1256 case 15:
1257 halbtc8821a2ant_set_fw_pstdma(btcoexist, 0xe3, 0xa,
1258 0xa, 0x60, 0x90);
1259 break;
1260 case 16:
1261 halbtc8821a2ant_set_fw_pstdma(btcoexist, 0xe3, 0x5,
1262 0x5, 0x60, 0x90);
1263 break;
1264 case 17:
1265 halbtc8821a2ant_set_fw_pstdma(btcoexist, 0xa3, 0x2f,
1266 0x2f, 0x60, 0x90);
1267 break;
1268 case 18:
1269 halbtc8821a2ant_set_fw_pstdma(btcoexist, 0xe3, 0x5,
1270 0x5, 0xe1, 0x90);
1271 break;
1272 case 19:
1273 halbtc8821a2ant_set_fw_pstdma(btcoexist, 0xe3, 0x25,
1274 0x25, 0xe1, 0x90);
1275 break;
1276 case 20:
1277 halbtc8821a2ant_set_fw_pstdma(btcoexist, 0xe3, 0x25,
1278 0x25, 0x60, 0x90);
1279 break;
1280 case 21:
1281 halbtc8821a2ant_set_fw_pstdma(btcoexist, 0xe3, 0x15,
1282 0x03, 0x70, 0x90);
1283 break;
1284 case 71:
1285 halbtc8821a2ant_set_fw_pstdma(btcoexist, 0xe3, 0x1a,
1286 0x1a, 0xe1, 0x90);
1287 break;
1288 }
1289 } else {
1290 /* disable PS tdma */
1291 switch (type) {
1292 case 0:
1293 halbtc8821a2ant_set_fw_pstdma(btcoexist, 0x0, 0x0, 0x0,
1294 0x40, 0x0);
1295 break;
1296 case 1:
1297 halbtc8821a2ant_set_fw_pstdma(btcoexist, 0x0, 0x0, 0x0,
1298 0x48, 0x0);
1299 break;
1300 default:
1301 halbtc8821a2ant_set_fw_pstdma(btcoexist, 0x0, 0x0, 0x0,
1302 0x40, 0x0);
1303 break;
1304 }
1305 }
1306
1307 /* update pre state */
1308 coex_dm->pre_ps_tdma_on = coex_dm->cur_ps_tdma_on;
1309 coex_dm->pre_ps_tdma = coex_dm->cur_ps_tdma;
1310}
1311
1312static void halbtc8821a2ant_coex_all_off(struct btc_coexist *btcoexist)
1313{
1314 /* fw all off */
1315 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1);
1316 halbtc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
1317 halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
1318
1319 /* sw all off */
1320 btc8821a2ant_sw_mech1(btcoexist, false, false, false, false);
1321 btc8821a2ant_sw_mech2(btcoexist, false, false, false, 0x18);
1322
1323 /* hw all off */
1324 halbtc8821a2ant_coex_table(btcoexist, NORMAL_EXEC,
1325 0x55555555, 0x55555555, 0xffff, 0x3);
1326}
1327
1328static void halbtc8821a2ant_coex_under_5g(struct btc_coexist *btcoexist)
1329{
1330 halbtc8821a2ant_coex_all_off(btcoexist);
1331}
1332
1333static void halbtc8821a2ant_init_coex_dm(struct btc_coexist *btcoexist)
1334{
1335 /* force to reset coex mechanism */
1336 halbtc8821a2ant_coex_table(btcoexist, FORCE_EXEC, 0x55555555,
1337 0x55555555, 0xffff, 0x3);
1338
1339 halbtc8821a2ant_ps_tdma(btcoexist, FORCE_EXEC, false, 1);
1340 halbtc8821a2ant_fw_dac_swing_lvl(btcoexist, FORCE_EXEC, 6);
1341 halbtc8821a2ant_dec_bt_pwr(btcoexist, FORCE_EXEC, false);
1342
1343 btc8821a2ant_sw_mech1(btcoexist, false, false, false, false);
1344 btc8821a2ant_sw_mech2(btcoexist, false, false, false, 0x18);
1345}
1346
1347static void halbtc8821a2ant_bt_inquiry_page(struct btc_coexist *btcoexist)
1348{
1349 bool low_pwr_disable = true;
1350
1351 btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER,
1352 &low_pwr_disable);
1353
1354 halbtc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, 0x55ff55ff,
1355 0x5afa5afa, 0xffff, 0x3);
1356 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3);
1357}
1358
1359static bool halbtc8821a2ant_is_common_action(struct btc_coexist *btcoexist)
1360{
1361 bool common = false, wifi_connected = false, wifi_busy = false;
1362 bool low_pwr_disable = false;
1363
1364 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
1365 &wifi_connected);
1366 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
1367
1368 halbtc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, 0x55ff55ff,
1369 0x5afa5afa, 0xffff, 0x3);
1370
1371 if (!wifi_connected &&
1372 BT_8821A_2ANT_BT_STATUS_IDLE == coex_dm->bt_status) {
1373 low_pwr_disable = false;
1374 btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER,
1375 &low_pwr_disable);
1376
1377 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
1378 "[BTCoex], Wifi IPS + BT IPS!!\n");
1379
1380 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1);
1381 halbtc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
1382 halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
1383
1384 btc8821a2ant_sw_mech1(btcoexist, false, false, false, false);
1385 btc8821a2ant_sw_mech2(btcoexist, false, false, false, 0x18);
1386
1387 common = true;
1388 } else if (wifi_connected &&
1389 (BT_8821A_2ANT_BT_STATUS_IDLE == coex_dm->bt_status)) {
1390 low_pwr_disable = false;
1391 btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER,
1392 &low_pwr_disable);
1393
1394 if (wifi_busy) {
1395 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
1396 "[BTCoex], Wifi Busy + BT IPS!!\n");
1397 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1398 false, 1);
1399 } else {
1400 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
1401 "[BTCoex], Wifi LPS + BT IPS!!\n");
1402 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1403 false, 1);
1404 }
1405
1406 halbtc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
1407 halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
1408
1409 btc8821a2ant_sw_mech1(btcoexist, false, false, false, false);
1410 btc8821a2ant_sw_mech2(btcoexist, false, false, false, 0x18);
1411
1412 common = true;
1413 } else if (!wifi_connected &&
1414 (BT_8821A_2ANT_BT_STATUS_CON_IDLE == coex_dm->bt_status)) {
1415 low_pwr_disable = true;
1416 btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER,
1417 &low_pwr_disable);
1418
1419 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
1420 "[BTCoex], Wifi IPS + BT LPS!!\n");
1421
1422 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1);
1423 halbtc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
1424 halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
1425
1426 btc8821a2ant_sw_mech1(btcoexist, false, false, false, false);
1427 btc8821a2ant_sw_mech2(btcoexist, false, false, false, 0x18);
1428 common = true;
1429 } else if (wifi_connected &&
1430 (BT_8821A_2ANT_BT_STATUS_CON_IDLE == coex_dm->bt_status)) {
1431 low_pwr_disable = true;
1432 btcoexist->btc_set(btcoexist,
1433 BTC_SET_ACT_DISABLE_LOW_POWER, &low_pwr_disable);
1434
1435 if (wifi_busy) {
1436 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
1437 "[BTCoex], Wifi Busy + BT LPS!!\n");
1438 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1439 false, 1);
1440 } else {
1441 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
1442 "[BTCoex], Wifi LPS + BT LPS!!\n");
1443 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1444 false, 1);
1445 }
1446
1447 halbtc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
1448 halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
1449
1450 btc8821a2ant_sw_mech1(btcoexist, true, true, true, true);
1451 btc8821a2ant_sw_mech2(btcoexist, false, false, false, 0x18);
1452
1453 common = true;
1454 } else if (!wifi_connected &&
1455 (BT_8821A_2ANT_BT_STATUS_NON_IDLE ==
1456 coex_dm->bt_status)) {
1457 low_pwr_disable = false;
1458 btcoexist->btc_set(btcoexist,
1459 BTC_SET_ACT_DISABLE_LOW_POWER, &low_pwr_disable);
1460
1461 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
1462 "[BTCoex], Wifi IPS + BT Busy!!\n");
1463
1464 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1);
1465 halbtc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
1466 halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
1467
1468 btc8821a2ant_sw_mech1(btcoexist, false, false,
1469 false, false);
1470 btc8821a2ant_sw_mech2(btcoexist, false, false,
1471 false, 0x18);
1472
1473 common = true;
1474 } else {
1475 low_pwr_disable = true;
1476 btcoexist->btc_set(btcoexist,
1477 BTC_SET_ACT_DISABLE_LOW_POWER,
1478 &low_pwr_disable);
1479
1480 if (wifi_busy) {
1481 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
1482 "[BTCoex], Wifi Busy + BT Busy!!\n");
1483 common = false;
1484 } else {
1485 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
1486 "[BTCoex], Wifi LPS + BT Busy!!\n");
1487 halbtc8821a2ant_ps_tdma(btcoexist,
1488 NORMAL_EXEC, true, 21);
1489
1490 if (halbtc8821a2ant_need_to_dec_bt_pwr(btcoexist))
1491 halbtc8821a2ant_dec_bt_pwr(btcoexist,
1492 NORMAL_EXEC, true);
1493 else
1494 halbtc8821a2ant_dec_bt_pwr(btcoexist,
1495 NORMAL_EXEC, false);
1496
1497 common = true;
1498 }
1499 btc8821a2ant_sw_mech1(btcoexist, true, true, true, true);
1500 }
1501 return common;
1502}
1503
1504static void btc8821a2_int1(struct btc_coexist *btcoexist, bool tx_pause,
1505 int result)
1506{
1507 if (tx_pause) {
1508 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
1509 "[BTCoex], TxPause = 1\n");
1510
1511 if (coex_dm->cur_ps_tdma == 71) {
1512 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1513 true, 5);
1514 coex_dm->tdma_adj_type = 5;
1515 } else if (coex_dm->cur_ps_tdma == 1) {
1516 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1517 true, 5);
1518 coex_dm->tdma_adj_type = 5;
1519 } else if (coex_dm->cur_ps_tdma == 2) {
1520 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1521 true, 6);
1522 coex_dm->tdma_adj_type = 6;
1523 } else if (coex_dm->cur_ps_tdma == 3) {
1524 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1525 true, 7);
1526 coex_dm->tdma_adj_type = 7;
1527 } else if (coex_dm->cur_ps_tdma == 4) {
1528 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1529 true, 8);
1530 coex_dm->tdma_adj_type = 8;
1531 }
1532 if (coex_dm->cur_ps_tdma == 9) {
1533 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1534 true, 13);
1535 coex_dm->tdma_adj_type = 13;
1536 } else if (coex_dm->cur_ps_tdma == 10) {
1537 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1538 true, 14);
1539 coex_dm->tdma_adj_type = 14;
1540 } else if (coex_dm->cur_ps_tdma == 11) {
1541 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1542 true, 15);
1543 coex_dm->tdma_adj_type = 15;
1544 } else if (coex_dm->cur_ps_tdma == 12) {
1545 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1546 true, 16);
1547 coex_dm->tdma_adj_type = 16;
1548 }
1549
1550 if (result == -1) {
1551 if (coex_dm->cur_ps_tdma == 5) {
1552 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1553 true, 6);
1554 coex_dm->tdma_adj_type = 6;
1555 } else if (coex_dm->cur_ps_tdma == 6) {
1556 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1557 true, 7);
1558 coex_dm->tdma_adj_type = 7;
1559 } else if (coex_dm->cur_ps_tdma == 7) {
1560 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1561 true, 8);
1562 coex_dm->tdma_adj_type = 8;
1563 } else if (coex_dm->cur_ps_tdma == 13) {
1564 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1565 true, 14);
1566 coex_dm->tdma_adj_type = 14;
1567 } else if (coex_dm->cur_ps_tdma == 14) {
1568 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1569 true, 15);
1570 coex_dm->tdma_adj_type = 15;
1571 } else if (coex_dm->cur_ps_tdma == 15) {
1572 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1573 true, 16);
1574 coex_dm->tdma_adj_type = 16;
1575 }
1576 } else if (result == 1) {
1577 if (coex_dm->cur_ps_tdma == 8) {
1578 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1579 true, 7);
1580 coex_dm->tdma_adj_type = 7;
1581 } else if (coex_dm->cur_ps_tdma == 7) {
1582 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1583 true, 6);
1584 coex_dm->tdma_adj_type = 6;
1585 } else if (coex_dm->cur_ps_tdma == 6) {
1586 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1587 true, 5);
1588 coex_dm->tdma_adj_type = 5;
1589 } else if (coex_dm->cur_ps_tdma == 16) {
1590 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1591 true, 15);
1592 coex_dm->tdma_adj_type = 15;
1593 } else if (coex_dm->cur_ps_tdma == 15) {
1594 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1595 true, 14);
1596 coex_dm->tdma_adj_type = 14;
1597 } else if (coex_dm->cur_ps_tdma == 14) {
1598 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1599 true, 13);
1600 coex_dm->tdma_adj_type = 13;
1601 }
1602 }
1603 } else {
1604 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
1605 "[BTCoex], TxPause = 0\n");
1606 if (coex_dm->cur_ps_tdma == 5) {
1607 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1608 true, 71);
1609 coex_dm->tdma_adj_type = 71;
1610 } else if (coex_dm->cur_ps_tdma == 6) {
1611 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1612 true, 2);
1613 coex_dm->tdma_adj_type = 2;
1614 } else if (coex_dm->cur_ps_tdma == 7) {
1615 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1616 true, 3);
1617 coex_dm->tdma_adj_type = 3;
1618 } else if (coex_dm->cur_ps_tdma == 8) {
1619 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1620 true, 4);
1621 coex_dm->tdma_adj_type = 4;
1622 }
1623 if (coex_dm->cur_ps_tdma == 13) {
1624 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1625 true, 9);
1626 coex_dm->tdma_adj_type = 9;
1627 } else if (coex_dm->cur_ps_tdma == 14) {
1628 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1629 true, 10);
1630 coex_dm->tdma_adj_type = 10;
1631 } else if (coex_dm->cur_ps_tdma == 15) {
1632 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1633 true, 11);
1634 coex_dm->tdma_adj_type = 11;
1635 } else if (coex_dm->cur_ps_tdma == 16) {
1636 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1637 true, 12);
1638 coex_dm->tdma_adj_type = 12;
1639 }
1640
1641 if (result == -1) {
1642 if (coex_dm->cur_ps_tdma == 71) {
1643 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1644 true, 1);
1645 coex_dm->tdma_adj_type = 1;
1646 } else if (coex_dm->cur_ps_tdma == 1) {
1647 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1648 true, 2);
1649 coex_dm->tdma_adj_type = 2;
1650 } else if (coex_dm->cur_ps_tdma == 2) {
1651 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1652 true, 3);
1653 coex_dm->tdma_adj_type = 3;
1654 } else if (coex_dm->cur_ps_tdma == 3) {
1655 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1656 true, 4);
1657 coex_dm->tdma_adj_type = 4;
1658 } else if (coex_dm->cur_ps_tdma == 9) {
1659 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1660 true, 10);
1661 coex_dm->tdma_adj_type = 10;
1662 } else if (coex_dm->cur_ps_tdma == 10) {
1663 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1664 true, 11);
1665 coex_dm->tdma_adj_type = 11;
1666 } else if (coex_dm->cur_ps_tdma == 11) {
1667 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1668 true, 12);
1669 coex_dm->tdma_adj_type = 12;
1670 }
1671 } else if (result == 1) {
1672 if (coex_dm->cur_ps_tdma == 4) {
1673 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1674 true, 3);
1675 coex_dm->tdma_adj_type = 3;
1676 } else if (coex_dm->cur_ps_tdma == 3) {
1677 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1678 true, 2);
1679 coex_dm->tdma_adj_type = 2;
1680 } else if (coex_dm->cur_ps_tdma == 2) {
1681 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1682 true, 1);
1683 coex_dm->tdma_adj_type = 1;
1684 } else if (coex_dm->cur_ps_tdma == 1) {
1685 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1686 true, 71);
1687 coex_dm->tdma_adj_type = 71;
1688 } else if (coex_dm->cur_ps_tdma == 12) {
1689 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1690 true, 11);
1691 coex_dm->tdma_adj_type = 11;
1692 } else if (coex_dm->cur_ps_tdma == 11) {
1693 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1694 true, 10);
1695 coex_dm->tdma_adj_type = 10;
1696 } else if (coex_dm->cur_ps_tdma == 10) {
1697 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1698 true, 9);
1699 coex_dm->tdma_adj_type = 9;
1700 }
1701 }
1702 }
1703}
1704
1705static void btc8821a2_int2(struct btc_coexist *btcoexist, bool tx_pause,
1706 int result)
1707{
1708 if (tx_pause) {
1709 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
1710 "[BTCoex], TxPause = 1\n");
1711 if (coex_dm->cur_ps_tdma == 1) {
1712 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1713 true, 6);
1714 coex_dm->tdma_adj_type = 6;
1715 } else if (coex_dm->cur_ps_tdma == 2) {
1716 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1717 true, 6);
1718 coex_dm->tdma_adj_type = 6;
1719 } else if (coex_dm->cur_ps_tdma == 3) {
1720 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1721 true, 7);
1722 coex_dm->tdma_adj_type = 7;
1723 } else if (coex_dm->cur_ps_tdma == 4) {
1724 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1725 true, 8);
1726 coex_dm->tdma_adj_type = 8;
1727 }
1728 if (coex_dm->cur_ps_tdma == 9) {
1729 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1730 true, 14);
1731 coex_dm->tdma_adj_type = 14;
1732 } else if (coex_dm->cur_ps_tdma == 10) {
1733 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1734 true, 14);
1735 coex_dm->tdma_adj_type = 14;
1736 } else if (coex_dm->cur_ps_tdma == 11) {
1737 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1738 true, 15);
1739 coex_dm->tdma_adj_type = 15;
1740 } else if (coex_dm->cur_ps_tdma == 12) {
1741 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1742 true, 16);
1743 coex_dm->tdma_adj_type = 16;
1744 }
1745 if (result == -1) {
1746 if (coex_dm->cur_ps_tdma == 5) {
1747 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1748 true, 6);
1749 coex_dm->tdma_adj_type = 6;
1750 } else if (coex_dm->cur_ps_tdma == 6) {
1751 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1752 true, 7);
1753 coex_dm->tdma_adj_type = 7;
1754 } else if (coex_dm->cur_ps_tdma == 7) {
1755 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1756 true, 8);
1757 coex_dm->tdma_adj_type = 8;
1758 } else if (coex_dm->cur_ps_tdma == 13) {
1759 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1760 true, 14);
1761 coex_dm->tdma_adj_type = 14;
1762 } else if (coex_dm->cur_ps_tdma == 14) {
1763 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1764 true, 15);
1765 coex_dm->tdma_adj_type = 15;
1766 } else if (coex_dm->cur_ps_tdma == 15) {
1767 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1768 true, 16);
1769 coex_dm->tdma_adj_type = 16;
1770 }
1771 } else if (result == 1) {
1772 if (coex_dm->cur_ps_tdma == 8) {
1773 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1774 true, 7);
1775 coex_dm->tdma_adj_type = 7;
1776 } else if (coex_dm->cur_ps_tdma == 7) {
1777 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1778 true, 6);
1779 coex_dm->tdma_adj_type = 6;
1780 } else if (coex_dm->cur_ps_tdma == 6) {
1781 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1782 true, 6);
1783 coex_dm->tdma_adj_type = 6;
1784 } else if (coex_dm->cur_ps_tdma == 16) {
1785 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1786 true, 15);
1787 coex_dm->tdma_adj_type = 15;
1788 } else if (coex_dm->cur_ps_tdma == 15) {
1789 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1790 true, 14);
1791 coex_dm->tdma_adj_type = 14;
1792 } else if (coex_dm->cur_ps_tdma == 14) {
1793 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1794 true, 14);
1795 coex_dm->tdma_adj_type = 14;
1796 }
1797 }
1798 } else {
1799 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
1800 "[BTCoex], TxPause = 0\n");
1801 if (coex_dm->cur_ps_tdma == 5) {
1802 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1803 true, 2);
1804 coex_dm->tdma_adj_type = 2;
1805 } else if (coex_dm->cur_ps_tdma == 6) {
1806 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1807 true, 2);
1808 coex_dm->tdma_adj_type = 2;
1809 } else if (coex_dm->cur_ps_tdma == 7) {
1810 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1811 true, 3);
1812 coex_dm->tdma_adj_type = 3;
1813 } else if (coex_dm->cur_ps_tdma == 8) {
1814 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1815 true, 4);
1816 coex_dm->tdma_adj_type = 4;
1817 }
1818 if (coex_dm->cur_ps_tdma == 13) {
1819 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1820 true, 10);
1821 coex_dm->tdma_adj_type = 10;
1822 } else if (coex_dm->cur_ps_tdma == 14) {
1823 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1824 true, 10);
1825 coex_dm->tdma_adj_type = 10;
1826 } else if (coex_dm->cur_ps_tdma == 15) {
1827 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1828 true, 11);
1829 coex_dm->tdma_adj_type = 11;
1830 } else if (coex_dm->cur_ps_tdma == 16) {
1831 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1832 true, 12);
1833 coex_dm->tdma_adj_type = 12;
1834 }
1835 if (result == -1) {
1836 if (coex_dm->cur_ps_tdma == 1) {
1837 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1838 true, 2);
1839 coex_dm->tdma_adj_type = 2;
1840 } else if (coex_dm->cur_ps_tdma == 2) {
1841 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1842 true, 3);
1843 coex_dm->tdma_adj_type = 3;
1844 } else if (coex_dm->cur_ps_tdma == 3) {
1845 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1846 true, 4);
1847 coex_dm->tdma_adj_type = 4;
1848 } else if (coex_dm->cur_ps_tdma == 9) {
1849 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1850 true, 10);
1851 coex_dm->tdma_adj_type = 10;
1852 } else if (coex_dm->cur_ps_tdma == 10) {
1853 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1854 true, 11);
1855 coex_dm->tdma_adj_type = 11;
1856 } else if (coex_dm->cur_ps_tdma == 11) {
1857 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1858 true, 12);
1859 coex_dm->tdma_adj_type = 12;
1860 }
1861 } else if (result == 1) {
1862 if (coex_dm->cur_ps_tdma == 4) {
1863 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1864 true, 3);
1865 coex_dm->tdma_adj_type = 3;
1866 } else if (coex_dm->cur_ps_tdma == 3) {
1867 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1868 true, 2);
1869 coex_dm->tdma_adj_type = 2;
1870 } else if (coex_dm->cur_ps_tdma == 2) {
1871 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1872 true, 2);
1873 coex_dm->tdma_adj_type = 2;
1874 } else if (coex_dm->cur_ps_tdma == 12) {
1875 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1876 true, 11);
1877 coex_dm->tdma_adj_type = 11;
1878 } else if (coex_dm->cur_ps_tdma == 11) {
1879 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1880 true, 10);
1881 coex_dm->tdma_adj_type = 10;
1882 } else if (coex_dm->cur_ps_tdma == 10) {
1883 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1884 true, 10);
1885 coex_dm->tdma_adj_type = 10;
1886 }
1887 }
1888 }
1889}
1890
1891static void btc8821a2_int3(struct btc_coexist *btcoexist, bool tx_pause,
1892 int result)
1893{
1894 if (tx_pause) {
1895 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
1896 "[BTCoex], TxPause = 1\n");
1897 if (coex_dm->cur_ps_tdma == 1) {
1898 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1899 true, 7);
1900 coex_dm->tdma_adj_type = 7;
1901 } else if (coex_dm->cur_ps_tdma == 2) {
1902 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1903 true, 7);
1904 coex_dm->tdma_adj_type = 7;
1905 } else if (coex_dm->cur_ps_tdma == 3) {
1906 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1907 true, 7);
1908 coex_dm->tdma_adj_type = 7;
1909 } else if (coex_dm->cur_ps_tdma == 4) {
1910 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1911 true, 8);
1912 coex_dm->tdma_adj_type = 8;
1913 }
1914 if (coex_dm->cur_ps_tdma == 9) {
1915 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1916 true, 15);
1917 coex_dm->tdma_adj_type = 15;
1918 } else if (coex_dm->cur_ps_tdma == 10) {
1919 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1920 true, 15);
1921 coex_dm->tdma_adj_type = 15;
1922 } else if (coex_dm->cur_ps_tdma == 11) {
1923 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1924 true, 15);
1925 coex_dm->tdma_adj_type = 15;
1926 } else if (coex_dm->cur_ps_tdma == 12) {
1927 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1928 true, 16);
1929 coex_dm->tdma_adj_type = 16;
1930 }
1931 if (result == -1) {
1932 if (coex_dm->cur_ps_tdma == 5) {
1933 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1934 true, 7);
1935 coex_dm->tdma_adj_type = 7;
1936 } else if (coex_dm->cur_ps_tdma == 6) {
1937 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1938 true, 7);
1939 coex_dm->tdma_adj_type = 7;
1940 } else if (coex_dm->cur_ps_tdma == 7) {
1941 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1942 true, 8);
1943 coex_dm->tdma_adj_type = 8;
1944 } else if (coex_dm->cur_ps_tdma == 13) {
1945 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1946 true, 15);
1947 coex_dm->tdma_adj_type = 15;
1948 } else if (coex_dm->cur_ps_tdma == 14) {
1949 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1950 true, 15);
1951 coex_dm->tdma_adj_type = 15;
1952 } else if (coex_dm->cur_ps_tdma == 15) {
1953 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1954 true, 16);
1955 coex_dm->tdma_adj_type = 16;
1956 }
1957 } else if (result == 1) {
1958 if (coex_dm->cur_ps_tdma == 8) {
1959 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1960 true, 7);
1961 coex_dm->tdma_adj_type = 7;
1962 } else if (coex_dm->cur_ps_tdma == 7) {
1963 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1964 true, 7);
1965 coex_dm->tdma_adj_type = 7;
1966 } else if (coex_dm->cur_ps_tdma == 6) {
1967 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1968 true, 7);
1969 coex_dm->tdma_adj_type = 7;
1970 } else if (coex_dm->cur_ps_tdma == 16) {
1971 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1972 true, 15);
1973 coex_dm->tdma_adj_type = 15;
1974 } else if (coex_dm->cur_ps_tdma == 15) {
1975 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1976 true, 15);
1977 coex_dm->tdma_adj_type = 15;
1978 } else if (coex_dm->cur_ps_tdma == 14) {
1979 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1980 true, 15);
1981 coex_dm->tdma_adj_type = 15;
1982 }
1983 }
1984 } else {
1985 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
1986 "[BTCoex], TxPause = 0\n");
1987 if (coex_dm->cur_ps_tdma == 5) {
1988 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1989 true, 3);
1990 coex_dm->tdma_adj_type = 3;
1991 } else if (coex_dm->cur_ps_tdma == 6) {
1992 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1993 true, 3);
1994 coex_dm->tdma_adj_type = 3;
1995 } else if (coex_dm->cur_ps_tdma == 7) {
1996 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
1997 true, 3);
1998 coex_dm->tdma_adj_type = 3;
1999 } else if (coex_dm->cur_ps_tdma == 8) {
2000 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2001 true, 4);
2002 coex_dm->tdma_adj_type = 4;
2003 }
2004 if (coex_dm->cur_ps_tdma == 13) {
2005 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2006 true, 11);
2007 coex_dm->tdma_adj_type = 11;
2008 } else if (coex_dm->cur_ps_tdma == 14) {
2009 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2010 true, 11);
2011 coex_dm->tdma_adj_type = 11;
2012 } else if (coex_dm->cur_ps_tdma == 15) {
2013 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2014 true, 11);
2015 coex_dm->tdma_adj_type = 11;
2016 } else if (coex_dm->cur_ps_tdma == 16) {
2017 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2018 true, 12);
2019 coex_dm->tdma_adj_type = 12;
2020 }
2021 if (result == -1) {
2022 if (coex_dm->cur_ps_tdma == 1) {
2023 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2024 true, 3);
2025 coex_dm->tdma_adj_type = 3;
2026 } else if (coex_dm->cur_ps_tdma == 2) {
2027 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2028 true, 3);
2029 coex_dm->tdma_adj_type = 3;
2030 } else if (coex_dm->cur_ps_tdma == 3) {
2031 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2032 true, 4);
2033 coex_dm->tdma_adj_type = 4;
2034 } else if (coex_dm->cur_ps_tdma == 9) {
2035 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2036 true, 11);
2037 coex_dm->tdma_adj_type = 11;
2038 } else if (coex_dm->cur_ps_tdma == 10) {
2039 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2040 true, 11);
2041 coex_dm->tdma_adj_type = 11;
2042 } else if (coex_dm->cur_ps_tdma == 11) {
2043 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2044 true, 12);
2045 coex_dm->tdma_adj_type = 12;
2046 }
2047 } else if (result == 1) {
2048 if (coex_dm->cur_ps_tdma == 4) {
2049 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2050 true, 3);
2051 coex_dm->tdma_adj_type = 3;
2052 } else if (coex_dm->cur_ps_tdma == 3) {
2053 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2054 true, 3);
2055 coex_dm->tdma_adj_type = 3;
2056 } else if (coex_dm->cur_ps_tdma == 2) {
2057 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2058 true, 3);
2059 coex_dm->tdma_adj_type = 3;
2060 } else if (coex_dm->cur_ps_tdma == 12) {
2061 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2062 true, 11);
2063 coex_dm->tdma_adj_type = 11;
2064 } else if (coex_dm->cur_ps_tdma == 11) {
2065 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2066 true, 11);
2067 coex_dm->tdma_adj_type = 11;
2068 } else if (coex_dm->cur_ps_tdma == 10) {
2069 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2070 true, 11);
2071 coex_dm->tdma_adj_type = 11;
2072 }
2073 }
2074 }
2075}
2076
2077static void btc8821a2ant_tdma_dur_adj(struct btc_coexist *btcoexist,
2078 bool sco_hid, bool tx_pause,
2079 u8 max_interval)
2080{
2081 static long up, dn, m, n, wait_count;
2082 /* 0: no change, +1: increase WiFi duration,
2083 * -1: decrease WiFi duration
2084 */
2085 int result;
2086 u8 retry_count = 0;
2087
2088 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW,
2089 "[BTCoex], TdmaDurationAdjust()\n");
2090
2091 if (coex_dm->reset_tdma_adjust) {
2092 coex_dm->reset_tdma_adjust = false;
2093 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
2094 "[BTCoex], first run TdmaDurationAdjust()!!\n");
2095 if (sco_hid) {
2096 if (tx_pause) {
2097 if (max_interval == 1) {
2098 halbtc8821a2ant_ps_tdma(btcoexist,
2099 NORMAL_EXEC,
2100 true, 13);
2101 coex_dm->tdma_adj_type = 13;
2102 } else if (max_interval == 2) {
2103 halbtc8821a2ant_ps_tdma(btcoexist,
2104 NORMAL_EXEC,
2105 true, 14);
2106 coex_dm->tdma_adj_type = 14;
2107 } else if (max_interval == 3) {
2108 halbtc8821a2ant_ps_tdma(btcoexist,
2109 NORMAL_EXEC,
2110 true, 15);
2111 coex_dm->tdma_adj_type = 15;
2112 } else {
2113 halbtc8821a2ant_ps_tdma(btcoexist,
2114 NORMAL_EXEC,
2115 true, 15);
2116 coex_dm->tdma_adj_type = 15;
2117 }
2118 } else {
2119 if (max_interval == 1) {
2120 halbtc8821a2ant_ps_tdma(btcoexist,
2121 NORMAL_EXEC,
2122 true, 9);
2123 coex_dm->tdma_adj_type = 9;
2124 } else if (max_interval == 2) {
2125 halbtc8821a2ant_ps_tdma(btcoexist,
2126 NORMAL_EXEC,
2127 true, 10);
2128 coex_dm->tdma_adj_type = 10;
2129 } else if (max_interval == 3) {
2130 halbtc8821a2ant_ps_tdma(btcoexist,
2131 NORMAL_EXEC,
2132 true, 11);
2133 coex_dm->tdma_adj_type = 11;
2134 } else {
2135 halbtc8821a2ant_ps_tdma(btcoexist,
2136 NORMAL_EXEC,
2137 true, 11);
2138 coex_dm->tdma_adj_type = 11;
2139 }
2140 }
2141 } else {
2142 if (tx_pause) {
2143 if (max_interval == 1) {
2144 halbtc8821a2ant_ps_tdma(btcoexist,
2145 NORMAL_EXEC,
2146 true, 5);
2147 coex_dm->tdma_adj_type = 5;
2148 } else if (max_interval == 2) {
2149 halbtc8821a2ant_ps_tdma(btcoexist,
2150 NORMAL_EXEC,
2151 true, 6);
2152 coex_dm->tdma_adj_type = 6;
2153 } else if (max_interval == 3) {
2154 halbtc8821a2ant_ps_tdma(btcoexist,
2155 NORMAL_EXEC,
2156 true, 7);
2157 coex_dm->tdma_adj_type = 7;
2158 } else {
2159 halbtc8821a2ant_ps_tdma(btcoexist,
2160 NORMAL_EXEC,
2161 true, 7);
2162 coex_dm->tdma_adj_type = 7;
2163 }
2164 } else {
2165 if (max_interval == 1) {
2166 halbtc8821a2ant_ps_tdma(btcoexist,
2167 NORMAL_EXEC,
2168 true, 1);
2169 coex_dm->tdma_adj_type = 1;
2170 } else if (max_interval == 2) {
2171 halbtc8821a2ant_ps_tdma(btcoexist,
2172 NORMAL_EXEC,
2173 true, 2);
2174 coex_dm->tdma_adj_type = 2;
2175 } else if (max_interval == 3) {
2176 halbtc8821a2ant_ps_tdma(btcoexist,
2177 NORMAL_EXEC,
2178 true, 3);
2179 coex_dm->tdma_adj_type = 3;
2180 } else {
2181 halbtc8821a2ant_ps_tdma(btcoexist,
2182 NORMAL_EXEC,
2183 true, 3);
2184 coex_dm->tdma_adj_type = 3;
2185 }
2186 }
2187 }
2188
2189 up = 0;
2190 dn = 0;
2191 m = 1;
2192 n = 3;
2193 result = 0;
2194 wait_count = 0;
2195 } else {
2196 /* accquire the BT TRx retry count from BT_Info byte2 */
2197 retry_count = coex_sta->bt_retry_cnt;
2198 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
2199 "[BTCoex], retry_count = %d\n", retry_count);
2200 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
2201 "[BTCoex], up = %d, dn = %d, m = %d, n = %d, wait_count = %d\n",
2202 (int)up, (int)dn, (int)m, (int)n, (int)wait_count);
2203 result = 0;
2204 wait_count++;
2205
2206 if (retry_count == 0) {
2207 /* no retry in the last 2-second duration */
2208 up++;
2209 dn--;
2210
2211 if (dn <= 0)
2212 dn = 0;
2213
2214 if (up >= n) {
2215 /* if (retry count == 0) for 2*n seconds,
2216 * make WiFi duration wider
2217 */
2218 wait_count = 0;
2219 n = 3;
2220 up = 0;
2221 dn = 0;
2222 result = 1;
2223 BTC_PRINT(BTC_MSG_ALGORITHM,
2224 ALGO_TRACE_FW_DETAIL,
2225 "[BTCoex], Increase wifi duration!!\n");
2226 }
2227 } else if (retry_count <= 3) {
2228 /* <=3 retry in the last 2-second duration */
2229 up--;
2230 dn++;
2231
2232 if (up <= 0)
2233 up = 0;
2234
2235 if (dn == 2) {
2236 /* if retry count< 3 for 2*2 seconds,
2237 * shrink wifi duration
2238 */
2239 if (wait_count <= 2)
2240 m++; /* avoid bounce in two levels */
2241 else
2242 m = 1;
2243 /* m max value is 20, max time is 120 second,
2244 * recheck if adjust WiFi duration.
2245 */
2246 if (m >= 20)
2247 m = 20;
2248
2249 n = 3*m;
2250 up = 0;
2251 dn = 0;
2252 wait_count = 0;
2253 result = -1;
2254 BTC_PRINT(BTC_MSG_ALGORITHM,
2255 ALGO_TRACE_FW_DETAIL,
2256 "[BTCoex], Decrease wifi duration for retryCounter<3!!\n");
2257 }
2258 } else {
2259 /* retry count > 3, if retry count > 3 happens once,
2260 * shrink WiFi duration
2261 */
2262 if (wait_count == 1)
2263 m++; /* avoid bounce in two levels */
2264 else
2265 m = 1;
2266 /* m max value is 20, max time is 120 second,
2267 * recheck if adjust WiFi duration.
2268 */
2269 if (m >= 20)
2270 m = 20;
2271
2272 n = 3*m;
2273 up = 0;
2274 dn = 0;
2275 wait_count = 0;
2276 result = -1;
2277 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
2278 "[BTCoex], Decrease wifi duration for retryCounter>3!!\n");
2279 }
2280
2281 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
2282 "[BTCoex], max Interval = %d\n", max_interval);
2283 if (max_interval == 1)
2284 btc8821a2_int1(btcoexist, tx_pause, result);
2285 else if (max_interval == 2)
2286 btc8821a2_int2(btcoexist, tx_pause, result);
2287 else if (max_interval == 3)
2288 btc8821a2_int3(btcoexist, tx_pause, result);
2289 }
2290
2291 /* if current PsTdma not match with the recorded one
2292 * (when scan, dhcp...), then we have to adjust it back to
2293 * the previous recorded one.
2294 */
2295 if (coex_dm->cur_ps_tdma != coex_dm->tdma_adj_type) {
2296 bool scan = false, link = false, roam = false;
2297
2298 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
2299 "[BTCoex], PsTdma type dismatch!!!, cur_ps_tdma = %d, recordPsTdma = %d\n",
2300 coex_dm->cur_ps_tdma, coex_dm->tdma_adj_type);
2301
2302 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan);
2303 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link);
2304 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam);
2305
2306 if (!scan && !link && !roam) {
2307 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
2308 coex_dm->tdma_adj_type);
2309 } else {
2310 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
2311 "[BTCoex], roaming/link/scan is under progress, will adjust next time!!!\n");
2312 }
2313 }
2314
2315 halbtc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 0x6);
2316}
2317
2318/* SCO only or SCO+PAN(HS)*/
2319static void halbtc8821a2ant_action_sco(struct btc_coexist *btcoexist)
2320{
2321 u8 wifi_rssi_state, bt_rssi_state;
2322 u32 wifi_bw;
2323
2324 wifi_rssi_state = halbtc8821a2ant_wifi_rssi_state(btcoexist, 0, 2,
2325 15, 0);
2326 bt_rssi_state = halbtc8821a2ant_bt_rssi_state(2, 35, 0);
2327
2328 halbtc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 4);
2329
2330 if (halbtc8821a2ant_need_to_dec_bt_pwr(btcoexist))
2331 halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true);
2332 else
2333 halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
2334
2335 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
2336
2337 if (BTC_WIFI_BW_LEGACY == wifi_bw) {
2338 /* for SCO quality at 11b/g mode */
2339 halbtc8821a2ant_coex_table(btcoexist, NORMAL_EXEC,
2340 0x5a5a5a5a, 0x5a5a5a5a, 0xffff, 0x3);
2341 } else {
2342 /* for SCO quality & wifi performance balance at 11n mode */
2343 halbtc8821a2ant_coex_table(btcoexist, NORMAL_EXEC,
2344 0x5aea5aea, 0x5aea5aea, 0xffff, 0x3);
2345 }
2346
2347 if (BTC_WIFI_BW_HT40 == wifi_bw) {
2348 /* fw mechanism
2349 * halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 5);
2350 */
2351
2352 if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
2353 (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2354 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2355 false, 0); /*for voice quality*/
2356 } else {
2357 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2358 false, 0); /*for voice quality*/
2359 }
2360
2361 /* sw mechanism */
2362 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
2363 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2364 btc8821a2ant_sw_mech1(btcoexist, true, true,
2365 false, false);
2366 btc8821a2ant_sw_mech2(btcoexist, true, false,
2367 false, 0x18);
2368 } else {
2369 btc8821a2ant_sw_mech1(btcoexist, true, true,
2370 false, false);
2371 btc8821a2ant_sw_mech2(btcoexist, false, false,
2372 false, 0x18);
2373 }
2374 } else {
2375 /* fw mechanism
2376 * halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 5);
2377 */
2378 if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
2379 (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2380 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2381 false, 0); /*for voice quality*/
2382 } else {
2383 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2384 false, 0); /*for voice quality*/
2385 }
2386
2387 /* sw mechanism */
2388 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
2389 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2390 btc8821a2ant_sw_mech1(btcoexist, false, true,
2391 false, false);
2392 btc8821a2ant_sw_mech2(btcoexist, true, false,
2393 false, 0x18);
2394 } else {
2395 btc8821a2ant_sw_mech1(btcoexist, false, true,
2396 false, false);
2397 btc8821a2ant_sw_mech2(btcoexist, false, false,
2398 false, 0x18);
2399 }
2400 }
2401}
2402
2403static void halbtc8821a2ant_action_hid(struct btc_coexist *btcoexist)
2404{
2405 u8 wifi_rssi_state, bt_rssi_state;
2406 u32 wifi_bw;
2407
2408 wifi_rssi_state = halbtc8821a2ant_wifi_rssi_state(btcoexist,
2409 0, 2, 15, 0);
2410 bt_rssi_state = halbtc8821a2ant_bt_rssi_state(2, 35, 0);
2411
2412 halbtc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
2413
2414 if (halbtc8821a2ant_need_to_dec_bt_pwr(btcoexist))
2415 halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true);
2416 else
2417 halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
2418
2419 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
2420
2421 if (BTC_WIFI_BW_LEGACY == wifi_bw) {
2422 /* for HID at 11b/g mode */
2423 halbtc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, 0x55ff55ff,
2424 0x5a5a5a5a, 0xffff, 0x3);
2425 } else {
2426 /* for HID quality & wifi performance balance at 11n mode */
2427 halbtc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, 0x55ff55ff,
2428 0x5aea5aea, 0xffff, 0x3);
2429 }
2430
2431 if (BTC_WIFI_BW_HT40 == wifi_bw) {
2432 /* fw mechanism */
2433 if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
2434 (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2435 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2436 true, 9);
2437 } else {
2438 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2439 true, 13);
2440 }
2441
2442 /* sw mechanism */
2443 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
2444 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2445 btc8821a2ant_sw_mech1(btcoexist, true, true,
2446 false, false);
2447 btc8821a2ant_sw_mech2(btcoexist, true, false,
2448 false, 0x18);
2449 } else {
2450 btc8821a2ant_sw_mech1(btcoexist, true, true,
2451 false, false);
2452 btc8821a2ant_sw_mech2(btcoexist, false, false,
2453 false, 0x18);
2454 }
2455 } else {
2456 /* fw mechanism */
2457 if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
2458 (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2459 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2460 true, 9);
2461 } else {
2462 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2463 true, 13);
2464 }
2465
2466 /* sw mechanism */
2467 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
2468 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2469 btc8821a2ant_sw_mech1(btcoexist, false, true,
2470 false, false);
2471 btc8821a2ant_sw_mech2(btcoexist, true, false,
2472 false, 0x18);
2473 } else {
2474 btc8821a2ant_sw_mech1(btcoexist, false, true,
2475 false, false);
2476 btc8821a2ant_sw_mech2(btcoexist, false, false,
2477 false, 0x18);
2478 }
2479 }
2480}
2481
2482/* A2DP only / PAN(EDR) only/ A2DP+PAN(HS) */
2483static void halbtc8821a2ant_action_a2dp(struct btc_coexist *btcoexist)
2484{
2485 u8 wifi_rssi_state, bt_rssi_state;
2486 u32 wifi_bw;
2487
2488 wifi_rssi_state = halbtc8821a2ant_wifi_rssi_state(btcoexist, 0, 2,
2489 15, 0);
2490 bt_rssi_state = halbtc8821a2ant_bt_rssi_state(2, 35, 0);
2491
2492 /* fw dac swing is called in btc8821a2ant_tdma_dur_adj()
2493 * halbtc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
2494 */
2495
2496 if (halbtc8821a2ant_need_to_dec_bt_pwr(btcoexist))
2497 halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true);
2498 else
2499 halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
2500
2501 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
2502
2503 if (BTC_WIFI_BW_HT40 == wifi_bw) {
2504 /* fw mechanism */
2505 if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
2506 (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2507 btc8821a2ant_tdma_dur_adj(btcoexist, false, false, 1);
2508 } else {
2509 btc8821a2ant_tdma_dur_adj(btcoexist, false, true, 1);
2510 }
2511
2512 /* sw mechanism */
2513 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
2514 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2515 btc8821a2ant_sw_mech1(btcoexist, true, false,
2516 false, false);
2517 btc8821a2ant_sw_mech2(btcoexist, true, false,
2518 false, 0x18);
2519 } else {
2520 btc8821a2ant_sw_mech1(btcoexist, true, false,
2521 false, false);
2522 btc8821a2ant_sw_mech2(btcoexist, false, false,
2523 false, 0x18);
2524 }
2525 } else {
2526 /* fw mechanism */
2527 if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
2528 (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2529 btc8821a2ant_tdma_dur_adj(btcoexist, false, false, 1);
2530 } else {
2531 btc8821a2ant_tdma_dur_adj(btcoexist, false, true, 1);
2532 }
2533
2534 /* sw mechanism */
2535 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
2536 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2537 btc8821a2ant_sw_mech1(btcoexist, false, false,
2538 false, false);
2539 btc8821a2ant_sw_mech2(btcoexist, true, false,
2540 false, 0x18);
2541 } else {
2542 btc8821a2ant_sw_mech1(btcoexist, false, false,
2543 false, false);
2544 btc8821a2ant_sw_mech2(btcoexist, false, false,
2545 false, 0x18);
2546 }
2547 }
2548}
2549
2550static void halbtc8821a2ant_action_a2dp_pan_hs(struct btc_coexist *btcoexist)
2551{
2552 u8 wifi_rssi_state, bt_rssi_state, bt_info_ext;
2553 u32 wifi_bw;
2554
2555 bt_info_ext = coex_sta->bt_info_ext;
2556 wifi_rssi_state = halbtc8821a2ant_wifi_rssi_state(btcoexist, 0, 2,
2557 15, 0);
2558 bt_rssi_state = halbtc8821a2ant_bt_rssi_state(2, 35, 0);
2559
2560 /*fw dac swing is called in btc8821a2ant_tdma_dur_adj()
2561 *halbtc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
2562 */
2563
2564 if (halbtc8821a2ant_need_to_dec_bt_pwr(btcoexist))
2565 halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true);
2566 else
2567 halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
2568
2569 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
2570
2571 if (BTC_WIFI_BW_HT40 == wifi_bw) {
2572 /* fw mechanism */
2573 if (bt_info_ext&BIT0) {
2574 /*a2dp basic rate*/
2575 btc8821a2ant_tdma_dur_adj(btcoexist, false, true, 2);
2576 } else {
2577 /*a2dp edr rate*/
2578 btc8821a2ant_tdma_dur_adj(btcoexist, false, true, 1);
2579 }
2580
2581 /* sw mechanism */
2582 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
2583 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2584 btc8821a2ant_sw_mech1(btcoexist, true, false,
2585 false, false);
2586 btc8821a2ant_sw_mech2(btcoexist, true, false,
2587 false, 0x18);
2588 } else {
2589 btc8821a2ant_sw_mech1(btcoexist, true, false,
2590 false, false);
2591 btc8821a2ant_sw_mech2(btcoexist, false, false,
2592 false, 0x18);
2593 }
2594 } else {
2595 /* fw mechanism */
2596 if (bt_info_ext&BIT0) {
2597 /* a2dp basic rate */
2598 btc8821a2ant_tdma_dur_adj(btcoexist, false, true, 2);
2599 } else {
2600 /* a2dp edr rate */
2601 btc8821a2ant_tdma_dur_adj(btcoexist, false, true, 1);
2602 }
2603
2604 /* sw mechanism */
2605 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
2606 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2607 btc8821a2ant_sw_mech1(btcoexist, false, false,
2608 false, false);
2609 btc8821a2ant_sw_mech2(btcoexist, true, false,
2610 false, 0x18);
2611 } else {
2612 btc8821a2ant_sw_mech1(btcoexist, false, false,
2613 false, false);
2614 btc8821a2ant_sw_mech2(btcoexist, false, false,
2615 false, 0x18);
2616 }
2617 }
2618}
2619
2620static void halbtc8821a2ant_action_pan_edr(struct btc_coexist *btcoexist)
2621{
2622 u8 wifi_rssi_state, bt_rssi_state;
2623 u32 wifi_bw;
2624
2625 wifi_rssi_state = halbtc8821a2ant_wifi_rssi_state(btcoexist, 0, 2,
2626 15, 0);
2627 bt_rssi_state = halbtc8821a2ant_bt_rssi_state(2, 35, 0);
2628
2629 halbtc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
2630
2631 if (halbtc8821a2ant_need_to_dec_bt_pwr(btcoexist))
2632 halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true);
2633 else
2634 halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
2635
2636 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
2637
2638 if (BTC_WIFI_BW_LEGACY == wifi_bw) {
2639 /* for HID at 11b/g mode */
2640 halbtc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, 0x55ff55ff,
2641 0x5aff5aff, 0xffff, 0x3);
2642 } else {
2643 /* for HID quality & wifi performance balance at 11n mode */
2644 halbtc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, 0x55ff55ff,
2645 0x5aff5aff, 0xffff, 0x3);
2646 }
2647
2648 if (BTC_WIFI_BW_HT40 == wifi_bw) {
2649 /* fw mechanism */
2650 if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
2651 (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2652 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2653 true, 1);
2654 } else {
2655 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2656 true, 5);
2657 }
2658
2659 /* sw mechanism */
2660 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
2661 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2662 btc8821a2ant_sw_mech1(btcoexist, true, false,
2663 false, false);
2664 btc8821a2ant_sw_mech2(btcoexist, true, false,
2665 false, 0x18);
2666 } else {
2667 btc8821a2ant_sw_mech1(btcoexist, true, false,
2668 false, false);
2669 btc8821a2ant_sw_mech2(btcoexist, false, false,
2670 false, 0x18);
2671 }
2672 } else {
2673 /* fw mechanism */
2674 if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
2675 (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2676 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2677 true, 1);
2678 } else {
2679 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2680 true, 5);
2681 }
2682
2683 /* sw mechanism */
2684 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
2685 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2686 btc8821a2ant_sw_mech1(btcoexist, false, false,
2687 false, false);
2688 btc8821a2ant_sw_mech2(btcoexist, true, false,
2689 false, 0x18);
2690 } else {
2691 btc8821a2ant_sw_mech1(btcoexist, false, false,
2692 false, false);
2693 btc8821a2ant_sw_mech2(btcoexist, false, false,
2694 false, 0x18);
2695 }
2696 }
2697}
2698
2699/* PAN(HS) only */
2700static void halbtc8821a2ant_action_pan_hs(struct btc_coexist *btcoexist)
2701{
2702 u8 wifi_rssi_state, bt_rssi_state;
2703 u32 wifi_bw;
2704
2705 wifi_rssi_state = halbtc8821a2ant_wifi_rssi_state(btcoexist,
2706 0, 2, 15, 0);
2707 bt_rssi_state = halbtc8821a2ant_bt_rssi_state(2, 35, 0);
2708
2709 halbtc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
2710
2711 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
2712
2713 if (BTC_WIFI_BW_HT40 == wifi_bw) {
2714 /* fw mechanism */
2715 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
2716 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2717 halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC,
2718 true);
2719 } else {
2720 halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC,
2721 false);
2722 }
2723 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1);
2724
2725 /* sw mechanism */
2726 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
2727 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2728 btc8821a2ant_sw_mech1(btcoexist, true, false,
2729 false, false);
2730 btc8821a2ant_sw_mech2(btcoexist, true, false,
2731 false, 0x18);
2732 } else {
2733 btc8821a2ant_sw_mech1(btcoexist, true, false,
2734 false, false);
2735 btc8821a2ant_sw_mech2(btcoexist, false, false,
2736 false, 0x18);
2737 }
2738 } else {
2739 /* fw mechanism */
2740 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
2741 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2742 halbtc8821a2ant_dec_bt_pwr(btcoexist,
2743 NORMAL_EXEC, true);
2744 } else {
2745 halbtc8821a2ant_dec_bt_pwr(btcoexist,
2746 NORMAL_EXEC, false);
2747 }
2748
2749 if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
2750 (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2751 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2752 false, 1);
2753 } else {
2754 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2755 false, 1);
2756 }
2757
2758 /* sw mechanism */
2759 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
2760 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2761 btc8821a2ant_sw_mech1(btcoexist, false, false,
2762 false, false);
2763 btc8821a2ant_sw_mech2(btcoexist, true, false,
2764 false, 0x18);
2765 } else {
2766 btc8821a2ant_sw_mech1(btcoexist, false, false,
2767 false, false);
2768 btc8821a2ant_sw_mech2(btcoexist, false, false,
2769 false, 0x18);
2770 }
2771 }
2772}
2773
2774/* PAN(EDR)+A2DP */
2775static void halbtc8821a2ant_action_pan_edr_a2dp(struct btc_coexist *btcoexist)
2776{
2777 u8 wifi_rssi_state, bt_rssi_state, bt_info_ext;
2778 u32 wifi_bw;
2779
2780 bt_info_ext = coex_sta->bt_info_ext;
2781 wifi_rssi_state = halbtc8821a2ant_wifi_rssi_state(btcoexist, 0, 2,
2782 15, 0);
2783 bt_rssi_state = halbtc8821a2ant_bt_rssi_state(2, 35, 0);
2784
2785 halbtc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
2786
2787 if (halbtc8821a2ant_need_to_dec_bt_pwr(btcoexist))
2788 halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true);
2789 else
2790 halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
2791
2792 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
2793
2794 if (BTC_WIFI_BW_LEGACY == wifi_bw) {
2795 /* for HID at 11b/g mode */
2796 halbtc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, 0x55ff55ff,
2797 0x5afa5afa, 0xffff, 0x3);
2798 } else {
2799 /* for HID quality & wifi performance balance at 11n mode */
2800 halbtc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, 0x55ff55ff,
2801 0x5afa5afa, 0xffff, 0x3);
2802 }
2803
2804 if (BTC_WIFI_BW_HT40 == wifi_bw) {
2805 /* fw mechanism */
2806 if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
2807 (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2808 if (bt_info_ext&BIT0) {
2809 /* a2dp basic rate */
2810 btc8821a2ant_tdma_dur_adj(btcoexist, false,
2811 false, 3);
2812 } else {
2813 /* a2dp edr rate */
2814 btc8821a2ant_tdma_dur_adj(btcoexist, false,
2815 false, 3);
2816 }
2817 } else {
2818 if (bt_info_ext&BIT0) {
2819 /* a2dp basic rate */
2820 btc8821a2ant_tdma_dur_adj(btcoexist, false,
2821 true, 3);
2822 } else {
2823 /* a2dp edr rate */
2824 btc8821a2ant_tdma_dur_adj(btcoexist, false,
2825 true, 3);
2826 }
2827 }
2828
2829 /* sw mechanism */
2830 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
2831 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2832 btc8821a2ant_sw_mech1(btcoexist, true, false,
2833 false, false);
2834 btc8821a2ant_sw_mech2(btcoexist, true, false,
2835 false, 0x18);
2836 } else {
2837 btc8821a2ant_sw_mech1(btcoexist, true, false,
2838 false, false);
2839 btc8821a2ant_sw_mech2(btcoexist, false, false,
2840 false, 0x18);
2841 };
2842 } else {
2843 /* fw mechanism */
2844 if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
2845 (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2846 if (bt_info_ext&BIT0) {
2847 /* a2dp basic rate */
2848 btc8821a2ant_tdma_dur_adj(btcoexist, false,
2849 false, 3);
2850 } else {
2851 /* a2dp edr rate */
2852 btc8821a2ant_tdma_dur_adj(btcoexist, false,
2853 false, 3);
2854 }
2855 } else {
2856 if (bt_info_ext&BIT0) {
2857 /* a2dp basic rate */
2858 btc8821a2ant_tdma_dur_adj(btcoexist, false,
2859 true, 3);
2860 } else {
2861 /* a2dp edr rate */
2862 btc8821a2ant_tdma_dur_adj(btcoexist, false,
2863 true, 3);
2864 }
2865 }
2866
2867 /* sw mechanism */
2868 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
2869 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2870 btc8821a2ant_sw_mech1(btcoexist, false, false,
2871 false, false);
2872 btc8821a2ant_sw_mech2(btcoexist, true, false,
2873 false, 0x18);
2874 } else {
2875 btc8821a2ant_sw_mech1(btcoexist, false, false,
2876 false, false);
2877 btc8821a2ant_sw_mech2(btcoexist, false, false,
2878 false, 0x18);
2879 }
2880 }
2881}
2882
2883static void halbtc8821a2ant_action_pan_edr_hid(struct btc_coexist *btcoexist)
2884{
2885 u8 wifi_rssi_state, bt_rssi_state;
2886 u32 wifi_bw;
2887
2888 wifi_rssi_state = halbtc8821a2ant_wifi_rssi_state(btcoexist, 0, 2,
2889 15, 0);
2890 bt_rssi_state = halbtc8821a2ant_bt_rssi_state(2, 35, 0);
2891
2892 halbtc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
2893
2894 if (halbtc8821a2ant_need_to_dec_bt_pwr(btcoexist))
2895 halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true);
2896 else
2897 halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
2898
2899 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
2900
2901 if (BTC_WIFI_BW_LEGACY == wifi_bw) {
2902 /* for HID at 11b/g mode */
2903 halbtc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, 0x55ff55ff,
2904 0x5a5f5a5f, 0xffff, 0x3);
2905 } else {
2906 /* for HID quality & wifi performance balance at 11n mode */
2907 halbtc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, 0x55ff55ff,
2908 0x5a5f5a5f, 0xffff, 0x3);
2909 }
2910
2911 if (BTC_WIFI_BW_HT40 == wifi_bw) {
2912 halbtc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 3);
2913 /* fw mechanism */
2914 if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
2915 (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2916 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2917 true, 10);
2918 } else {
2919 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2920 true, 14);
2921 }
2922
2923 /* sw mechanism */
2924 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
2925 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2926 btc8821a2ant_sw_mech1(btcoexist, true, true,
2927 false, false);
2928 btc8821a2ant_sw_mech2(btcoexist, true, false,
2929 false, 0x18);
2930 } else {
2931 btc8821a2ant_sw_mech1(btcoexist, true, true,
2932 false, false);
2933 btc8821a2ant_sw_mech2(btcoexist, false, false,
2934 false, 0x18);
2935 }
2936 } else {
2937 halbtc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
2938 /* fw mechanism */
2939 if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
2940 (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2941 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2942 true, 10);
2943 } else {
2944 halbtc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
2945 true, 14);
2946 }
2947
2948 /* sw mechanism */
2949 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
2950 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2951 btc8821a2ant_sw_mech1(btcoexist, false, true,
2952 false, false);
2953 btc8821a2ant_sw_mech2(btcoexist, true, false,
2954 false, 0x18);
2955 } else {
2956 btc8821a2ant_sw_mech1(btcoexist, false, true,
2957 false, false);
2958 btc8821a2ant_sw_mech2(btcoexist, false, false,
2959 false, 0x18);
2960 }
2961 }
2962}
2963
2964/* HID+A2DP+PAN(EDR) */
2965static void btc8821a2ant_act_hid_a2dp_pan_edr(struct btc_coexist *btcoexist)
2966{
2967 u8 wifi_rssi_state, bt_rssi_state, bt_info_ext;
2968 u32 wifi_bw;
2969
2970 bt_info_ext = coex_sta->bt_info_ext;
2971 wifi_rssi_state = halbtc8821a2ant_wifi_rssi_state(btcoexist,
2972 0, 2, 15, 0);
2973 bt_rssi_state = halbtc8821a2ant_bt_rssi_state(2, 35, 0);
2974
2975 halbtc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
2976
2977 if (halbtc8821a2ant_need_to_dec_bt_pwr(btcoexist))
2978 halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true);
2979 else
2980 halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
2981
2982 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
2983
2984 if (BTC_WIFI_BW_LEGACY == wifi_bw) {
2985 /* for HID at 11b/g mode */
2986 halbtc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, 0x55ff55ff,
2987 0x5a5a5a5a, 0xffff, 0x3);
2988 } else {
2989 /* for HID quality & wifi performance balance at 11n mode */
2990 halbtc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, 0x55ff55ff,
2991 0x5a5a5a5a, 0xffff, 0x3);
2992 }
2993
2994 if (BTC_WIFI_BW_HT40 == wifi_bw) {
2995 /* fw mechanism */
2996 if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
2997 (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2998 if (bt_info_ext&BIT0) {
2999 /* a2dp basic rate */
3000 btc8821a2ant_tdma_dur_adj(btcoexist, true,
3001 true, 3);
3002 } else {
3003 /* a2dp edr rate */
3004 btc8821a2ant_tdma_dur_adj(btcoexist, true,
3005 true, 3);
3006 }
3007 } else {
3008 if (bt_info_ext&BIT0) {
3009 /* a2dp basic rate */
3010 btc8821a2ant_tdma_dur_adj(btcoexist, true,
3011 true, 3);
3012 } else {
3013 /* a2dp edr rate */
3014 btc8821a2ant_tdma_dur_adj(btcoexist, true,
3015 true, 3);
3016 }
3017 }
3018
3019 /* sw mechanism */
3020 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
3021 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
3022 btc8821a2ant_sw_mech1(btcoexist, true, true,
3023 false, false);
3024 btc8821a2ant_sw_mech2(btcoexist, true, false,
3025 false, 0x18);
3026 } else {
3027 btc8821a2ant_sw_mech1(btcoexist, true, true,
3028 false, false);
3029 btc8821a2ant_sw_mech2(btcoexist, false, false,
3030 false, 0x18);
3031 }
3032 } else {
3033 /* fw mechanism */
3034 if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
3035 (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
3036 if (bt_info_ext&BIT0) {
3037 /* a2dp basic rate */
3038 btc8821a2ant_tdma_dur_adj(btcoexist, true,
3039 false, 3);
3040 } else {
3041 /* a2dp edr rate */
3042 btc8821a2ant_tdma_dur_adj(btcoexist, true,
3043 false, 3);
3044 }
3045 } else {
3046 if (bt_info_ext&BIT0) {
3047 /* a2dp basic rate */
3048 btc8821a2ant_tdma_dur_adj(btcoexist, true,
3049 true, 3);
3050 } else {
3051 /* a2dp edr rate */
3052 btc8821a2ant_tdma_dur_adj(btcoexist, true,
3053 true, 3);
3054 }
3055 }
3056
3057 /* sw mechanism */
3058 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
3059 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
3060 btc8821a2ant_sw_mech1(btcoexist, false, true,
3061 false, false);
3062 btc8821a2ant_sw_mech2(btcoexist, true, false,
3063 false, 0x18);
3064 } else {
3065 btc8821a2ant_sw_mech1(btcoexist, false, true,
3066 false, false);
3067 btc8821a2ant_sw_mech2(btcoexist, false, false,
3068 false, 0x18);
3069 }
3070 }
3071}
3072
3073static void halbtc8821a2ant_action_hid_a2dp(struct btc_coexist *btcoexist)
3074{
3075 u8 wifi_rssi_state, bt_rssi_state, bt_info_ext;
3076 u32 wifi_bw;
3077
3078 bt_info_ext = coex_sta->bt_info_ext;
3079 wifi_rssi_state = halbtc8821a2ant_wifi_rssi_state(btcoexist, 0, 2,
3080 15, 0);
3081 bt_rssi_state = halbtc8821a2ant_bt_rssi_state(2, 35, 0);
3082
3083 if (halbtc8821a2ant_need_to_dec_bt_pwr(btcoexist))
3084 halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true);
3085 else
3086 halbtc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
3087
3088 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
3089
3090 if (BTC_WIFI_BW_LEGACY == wifi_bw) {
3091 /* for HID at 11b/g mode */
3092 halbtc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, 0x55ff55ff,
3093 0x5f5b5f5b, 0xffffff, 0x3);
3094 } else {
3095 /*for HID quality & wifi performance balance at 11n mode*/
3096 halbtc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, 0x55ff55ff,
3097 0x5f5b5f5b, 0xffffff, 0x3);
3098 }
3099
3100 if (BTC_WIFI_BW_HT40 == wifi_bw) {
3101 /* fw mechanism */
3102 if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
3103 (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
3104 if (bt_info_ext&BIT0) {
3105 /* a2dp basic rate */
3106 btc8821a2ant_tdma_dur_adj(btcoexist,
3107 true, true, 2);
3108 } else {
3109 /* a2dp edr rate */
3110 btc8821a2ant_tdma_dur_adj(btcoexist,
3111 true, true, 2);
3112 }
3113 } else {
3114 if (bt_info_ext&BIT0) {
3115 /* a2dp basic rate */
3116 btc8821a2ant_tdma_dur_adj(btcoexist,
3117 true, true, 2);
3118 } else {
3119 /* a2dp edr rate */
3120 btc8821a2ant_tdma_dur_adj(btcoexist,
3121 true, true, 2);
3122 }
3123 }
3124
3125 /* sw mechanism */
3126 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
3127 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
3128 btc8821a2ant_sw_mech1(btcoexist, true, true,
3129 false, false);
3130 btc8821a2ant_sw_mech2(btcoexist, true, false,
3131 false, 0x18);
3132 } else {
3133 btc8821a2ant_sw_mech1(btcoexist, true, true,
3134 false, false);
3135 btc8821a2ant_sw_mech2(btcoexist, false, false,
3136 false, 0x18);
3137 }
3138 } else {
3139 /* fw mechanism */
3140 if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
3141 (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
3142 if (bt_info_ext&BIT0) {
3143 /* a2dp basic rate */
3144 btc8821a2ant_tdma_dur_adj(btcoexist,
3145 true, true, 2);
3146
3147 } else {
3148 /* a2dp edr rate */
3149 btc8821a2ant_tdma_dur_adj(btcoexist,
3150 true, true, 2);
3151 }
3152 } else {
3153 if (bt_info_ext&BIT0) {
3154 /*a2dp basic rate*/
3155 btc8821a2ant_tdma_dur_adj(btcoexist,
3156 true, true, 2);
3157 } else {
3158 /*a2dp edr rate*/
3159 btc8821a2ant_tdma_dur_adj(btcoexist,
3160 true, true, 2);
3161 }
3162 }
3163
3164 /* sw mechanism */
3165 if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
3166 (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
3167 btc8821a2ant_sw_mech1(btcoexist, false, true,
3168 false, false);
3169 btc8821a2ant_sw_mech2(btcoexist, true, false,
3170 false, 0x18);
3171 } else {
3172 btc8821a2ant_sw_mech1(btcoexist, false, true,
3173 false, false);
3174 btc8821a2ant_sw_mech2(btcoexist, false, false,
3175 false, 0x18);
3176 }
3177 }
3178}
3179
3180static void halbtc8821a2ant_run_coexist_mechanism(struct btc_coexist *btcoexist)
3181{
3182 bool wifi_under_5g = false;
3183 u8 algorithm = 0;
3184
3185 if (btcoexist->manual_control) {
3186 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3187 "[BTCoex], Manual control!!!\n");
3188 return;
3189 }
3190
3191 btcoexist->btc_get(btcoexist,
3192 BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
3193
3194 if (wifi_under_5g) {
3195 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3196 "[BTCoex], RunCoexistMechanism(), run 5G coex setting!!<===\n");
3197 halbtc8821a2ant_coex_under_5g(btcoexist);
3198 return;
3199 }
3200
3201 algorithm = halbtc8821a2ant_action_algorithm(btcoexist);
3202 if (coex_sta->c2h_bt_inquiry_page &&
3203 (BT_8821A_2ANT_COEX_ALGO_PANHS != algorithm)) {
3204 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3205 "[BTCoex], BT is under inquiry/page scan !!\n");
3206 halbtc8821a2ant_bt_inquiry_page(btcoexist);
3207 return;
3208 }
3209
3210 coex_dm->cur_algorithm = algorithm;
3211 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3212 "[BTCoex], Algorithm = %d\n", coex_dm->cur_algorithm);
3213
3214 if (halbtc8821a2ant_is_common_action(btcoexist)) {
3215 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3216 "[BTCoex], Action 2-Ant common.\n");
3217 coex_dm->reset_tdma_adjust = true;
3218 } else {
3219 if (coex_dm->cur_algorithm != coex_dm->pre_algorithm) {
3220 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3221 "[BTCoex], pre_algorithm = %d, cur_algorithm = %d\n",
3222 coex_dm->pre_algorithm, coex_dm->cur_algorithm);
3223 coex_dm->reset_tdma_adjust = true;
3224 }
3225 switch (coex_dm->cur_algorithm) {
3226 case BT_8821A_2ANT_COEX_ALGO_SCO:
3227 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3228 "[BTCoex], Action 2-Ant, algorithm = SCO.\n");
3229 halbtc8821a2ant_action_sco(btcoexist);
3230 break;
3231 case BT_8821A_2ANT_COEX_ALGO_HID:
3232 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3233 "[BTCoex], Action 2-Ant, algorithm = HID.\n");
3234 halbtc8821a2ant_action_hid(btcoexist);
3235 break;
3236 case BT_8821A_2ANT_COEX_ALGO_A2DP:
3237 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3238 "[BTCoex], Action 2-Ant, algorithm = A2DP.\n");
3239 halbtc8821a2ant_action_a2dp(btcoexist);
3240 break;
3241 case BT_8821A_2ANT_COEX_ALGO_A2DP_PANHS:
3242 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3243 "[BTCoex], Action 2-Ant, algorithm = A2DP+PAN(HS).\n");
3244 halbtc8821a2ant_action_a2dp_pan_hs(btcoexist);
3245 break;
3246 case BT_8821A_2ANT_COEX_ALGO_PANEDR:
3247 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3248 "[BTCoex], Action 2-Ant, algorithm = PAN(EDR).\n");
3249 halbtc8821a2ant_action_pan_edr(btcoexist);
3250 break;
3251 case BT_8821A_2ANT_COEX_ALGO_PANHS:
3252 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3253 "[BTCoex], Action 2-Ant, algorithm = HS mode.\n");
3254 halbtc8821a2ant_action_pan_hs(btcoexist);
3255 break;
3256 case BT_8821A_2ANT_COEX_ALGO_PANEDR_A2DP:
3257 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3258 "[BTCoex], Action 2-Ant, algorithm = PAN+A2DP.\n");
3259 halbtc8821a2ant_action_pan_edr_a2dp(btcoexist);
3260 break;
3261 case BT_8821A_2ANT_COEX_ALGO_PANEDR_HID:
3262 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3263 "[BTCoex], Action 2-Ant, algorithm = PAN(EDR)+HID.\n");
3264 halbtc8821a2ant_action_pan_edr_hid(btcoexist);
3265 break;
3266 case BT_8821A_2ANT_COEX_ALGO_HID_A2DP_PANEDR:
3267 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3268 "[BTCoex], Action 2-Ant, algorithm = HID+A2DP+PAN.\n");
3269 btc8821a2ant_act_hid_a2dp_pan_edr(btcoexist);
3270 break;
3271 case BT_8821A_2ANT_COEX_ALGO_HID_A2DP:
3272 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3273 "[BTCoex], Action 2-Ant, algorithm = HID+A2DP.\n");
3274 halbtc8821a2ant_action_hid_a2dp(btcoexist);
3275 break;
3276 default:
3277 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3278 "[BTCoex], Action 2-Ant, algorithm = coexist All Off!!\n");
3279 halbtc8821a2ant_coex_all_off(btcoexist);
3280 break;
3281 }
3282 coex_dm->pre_algorithm = coex_dm->cur_algorithm;
3283 }
3284}
3285
3286/*============================================================
3287 *work around function start with wa_halbtc8821a2ant_
3288 *============================================================
3289 *============================================================
3290 * extern function start with EXhalbtc8821a2ant_
3291 *============================================================
3292 */
3293void ex_halbtc8821a2ant_init_hwconfig(struct btc_coexist *btcoexist)
3294{
3295 u8 u1tmp = 0;
3296
3297 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
3298 "[BTCoex], 2Ant Init HW Config!!\n");
3299
3300 /* backup rf 0x1e value */
3301 coex_dm->bt_rf0x1e_backup =
3302 btcoexist->btc_get_rf_reg(btcoexist, BTC_RF_A, 0x1e, 0xfffff);
3303
3304 /* 0x790[5:0] = 0x5 */
3305 u1tmp = btcoexist->btc_read_1byte(btcoexist, 0x790);
3306 u1tmp &= 0xc0;
3307 u1tmp |= 0x5;
3308 btcoexist->btc_write_1byte(btcoexist, 0x790, u1tmp);
3309
3310 /*Antenna config */
3311 halbtc8821a2ant_set_ant_path(btcoexist,
3312 BTC_ANT_WIFI_AT_MAIN, true, false);
3313
3314 /* PTA parameter */
3315 halbtc8821a2ant_coex_table(btcoexist,
3316 FORCE_EXEC, 0x55555555, 0x55555555,
3317 0xffff, 0x3);
3318
3319 /* Enable counter statistics */
3320 /*0x76e[3] = 1, WLAN_Act control by PTA*/
3321 btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc);
3322 btcoexist->btc_write_1byte(btcoexist, 0x778, 0x3);
3323 btcoexist->btc_write_1byte_bitmask(btcoexist, 0x40, 0x20, 0x1);
3324}
3325
3326void
3327ex_halbtc8821a2ant_init_coex_dm(
3328 struct btc_coexist *btcoexist
3329 )
3330{
3331 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
3332 "[BTCoex], Coex Mechanism Init!!\n");
3333
3334 halbtc8821a2ant_init_coex_dm(btcoexist);
3335}
3336
3337void
3338ex_halbtc8821a2ant_display_coex_info(
3339 struct btc_coexist *btcoexist
3340 )
3341{
3342 struct btc_board_info *board_info = &btcoexist->board_info;
3343 struct btc_stack_info *stack_info = &btcoexist->stack_info;
3344 struct rtl_priv *rtlpriv = btcoexist->adapter;
3345 u8 u1tmp[4], i, bt_info_ext, ps_tdma_case = 0;
3346 u32 u4tmp[4];
3347 bool roam = false, scan = false, link = false, wifi_under_5g = false;
3348 bool bt_hs_on = false, wifi_busy = false;
3349 long wifi_rssi = 0, bt_hs_rssi = 0;
3350 u32 wifi_bw, wifi_traffic_dir;
3351 u8 wifi_dot_11_chnl, wifi_hs_chnl;
3352 u32 fw_ver = 0, bt_patch_ver = 0;
3353
3354 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
3355 "\r\n ============[BT Coexist info]============");
3356
3357 if (!board_info->bt_exist) {
3358 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n BT not exists !!!");
3359 return;
3360 }
3361
3362 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
3363 "\r\n %-35s = %d/ %d ", "Ant PG number/ Ant mechanism:",
3364 board_info->pg_ant_num, board_info->btdm_ant_num);
3365
3366 if (btcoexist->manual_control) {
3367 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
3368 "\r\n %-35s", "[Action Manual control]!!");
3369 }
3370
3371 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
3372 "\r\n %-35s = %s / %d", "BT stack/ hci ext ver",
3373 ((stack_info->profile_notified) ? "Yes" : "No"),
3374 stack_info->hci_version);
3375
3376 btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER, &bt_patch_ver);
3377 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver);
3378 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
3379 "\r\n %-35s = %d_%d/ 0x%x/ 0x%x(%d)",
3380 "CoexVer/ FwVer/ PatchVer",
3381 glcoex_ver_date_8821a_2ant, glcoex_ver_8821a_2ant,
3382 fw_ver, bt_patch_ver, bt_patch_ver);
3383
3384 btcoexist->btc_get(btcoexist,
3385 BTC_GET_BL_HS_OPERATION, &bt_hs_on);
3386 btcoexist->btc_get(btcoexist,
3387 BTC_GET_U1_WIFI_DOT11_CHNL, &wifi_dot_11_chnl);
3388 btcoexist->btc_get(btcoexist,
3389 BTC_GET_U1_WIFI_HS_CHNL, &wifi_hs_chnl);
3390 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
3391 "\r\n %-35s = %d / %d(%d)",
3392 "Dot11 channel / HsMode(HsChnl)",
3393 wifi_dot_11_chnl, bt_hs_on, wifi_hs_chnl);
3394
3395 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
3396 "\r\n %-35s = %02x %02x %02x ",
3397 "H2C Wifi inform bt chnl Info",
3398 coex_dm->wifi_chnl_info[0], coex_dm->wifi_chnl_info[1],
3399 coex_dm->wifi_chnl_info[2]);
3400
3401 btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi);
3402 btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi);
3403 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
3404 "\r\n %-35s = %ld/ %ld", "Wifi rssi/ HS rssi",
3405 wifi_rssi, bt_hs_rssi);
3406
3407 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan);
3408 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link);
3409 btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam);
3410 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
3411 "\r\n %-35s = %d/ %d/ %d ", "Wifi link/ roam/ scan",
3412 link, roam, scan);
3413
3414 btcoexist->btc_get(btcoexist,
3415 BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
3416 btcoexist->btc_get(btcoexist,
3417 BTC_GET_U4_WIFI_BW, &wifi_bw);
3418 btcoexist->btc_get(btcoexist,
3419 BTC_GET_BL_WIFI_BUSY, &wifi_busy);
3420 btcoexist->btc_get(btcoexist,
3421 BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, &wifi_traffic_dir);
3422 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
3423 "\r\n %-35s = %s / %s/ %s ", "Wifi status",
3424 (wifi_under_5g ? "5G" : "2.4G"),
3425 ((BTC_WIFI_BW_LEGACY == wifi_bw) ? "Legacy" :
3426 (((BTC_WIFI_BW_HT40 == wifi_bw) ? "HT40" : "HT20"))),
3427 ((!wifi_busy) ? "idle" :
3428 ((BTC_WIFI_TRAFFIC_TX == wifi_traffic_dir) ?
3429 "uplink" : "downlink")));
3430
3431 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
3432 "\r\n %-35s = [%s/ %d/ %d] ", "BT [status/ rssi/ retryCnt]",
3433 ((coex_sta->c2h_bt_inquiry_page) ? ("inquiry/page scan") :
3434 ((BT_8821A_2ANT_BT_STATUS_IDLE == coex_dm->bt_status)
3435 ? "idle" : ((BT_8821A_2ANT_BT_STATUS_CON_IDLE ==
3436 coex_dm->bt_status) ? "connected-idle" : "busy"))),
3437 coex_sta->bt_rssi, coex_sta->bt_retry_cnt);
3438
3439 if (stack_info->profile_notified) {
3440 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
3441 "\r\n %-35s = %d / %d / %d / %d", "SCO/HID/PAN/A2DP",
3442 stack_info->sco_exist, stack_info->hid_exist,
3443 stack_info->pan_exist, stack_info->a2dp_exist);
3444
3445 btcoexist->btc_disp_dbg_msg(btcoexist,
3446 BTC_DBG_DISP_BT_LINK_INFO);
3447 }
3448
3449 bt_info_ext = coex_sta->bt_info_ext;
3450 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %s",
3451 "BT Info A2DP rate",
3452 (bt_info_ext&BIT0) ? "Basic rate" : "EDR rate");
3453
3454 for (i = 0; i < BT_INFO_SRC_8821A_2ANT_MAX; i++) {
3455 if (coex_sta->bt_info_c2h_cnt[i]) {
3456 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
3457 "\r\n %-35s = %02x %02x %02x %02x %02x %02x %02x(%d)",
3458 glbt_info_src_8821a_2ant[i],
3459 coex_sta->bt_info_c2h[i][0],
3460 coex_sta->bt_info_c2h[i][1],
3461 coex_sta->bt_info_c2h[i][2],
3462 coex_sta->bt_info_c2h[i][3],
3463 coex_sta->bt_info_c2h[i][4],
3464 coex_sta->bt_info_c2h[i][5],
3465 coex_sta->bt_info_c2h[i][6],
3466 coex_sta->bt_info_c2h_cnt[i]);
3467 }
3468 }
3469
3470 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %s/%s",
3471 "PS state, IPS/LPS",
3472 ((coex_sta->under_ips ? "IPS ON" : "IPS OFF")),
3473 ((coex_sta->under_lps ? "LPS ON" : "LPS OFF")));
3474 btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_FW_PWR_MODE_CMD);
3475
3476 /* Sw mechanism*/
3477 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s",
3478 "============[Sw mechanism]============");
3479 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
3480 "\r\n %-35s = %d/ %d/ %d/ %d ",
3481 "SM1[ShRf/ LpRA/ LimDig/ btLna]",
3482 coex_dm->cur_rf_rx_lpf_shrink, coex_dm->cur_low_penalty_ra,
3483 coex_dm->limited_dig, coex_dm->cur_bt_lna_constrain);
3484 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
3485 "\r\n %-35s = %d/ %d/ %d(0x%x) ",
3486 "SM2[AgcT/ AdcB/ SwDacSwing(lvl)]",
3487 coex_dm->cur_agc_table_en, coex_dm->cur_adc_back_off,
3488 coex_dm->cur_dac_swing_on, coex_dm->cur_dac_swing_lvl);
3489
3490 /* Fw mechanism*/
3491 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s",
3492 "============[Fw mechanism]============");
3493
3494 if (!btcoexist->manual_control) {
3495 ps_tdma_case = coex_dm->cur_ps_tdma;
3496 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
3497 "\r\n %-35s = %02x %02x %02x %02x %02x case-%d",
3498 "PS TDMA",
3499 coex_dm->ps_tdma_para[0], coex_dm->ps_tdma_para[1],
3500 coex_dm->ps_tdma_para[2], coex_dm->ps_tdma_para[3],
3501 coex_dm->ps_tdma_para[4], ps_tdma_case);
3502
3503 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
3504 "\r\n %-35s = %d/ %d ", "DecBtPwr/ IgnWlanAct",
3505 coex_dm->cur_dec_bt_pwr,
3506 coex_dm->cur_ignore_wlan_act);
3507 }
3508
3509 /* Hw setting*/
3510 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
3511 "\r\n %-35s", "============[Hw setting]============");
3512
3513 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
3514 "\r\n %-35s = 0x%x", "RF-A, 0x1e initVal",
3515 coex_dm->bt_rf0x1e_backup);
3516
3517 u1tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x778);
3518 u1tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x6cc);
3519 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x ",
3520 "0x778 (W_Act)/ 0x6cc (CoTab Sel)",
3521 u1tmp[0], u1tmp[1]);
3522
3523 u1tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x8db);
3524 u1tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0xc5b);
3525 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x",
3526 "0x8db(ADC)/0xc5b[29:25](DAC)",
3527 ((u1tmp[0]&0x60)>>5), ((u1tmp[1]&0x3e)>>1));
3528
3529 u4tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xcb4);
3530 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x",
3531 "0xcb4[7:0](ctrl)/ 0xcb4[29:28](val)",
3532 u4tmp[0]&0xff, ((u4tmp[0]&0x30000000)>>28));
3533
3534 u1tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x40);
3535 u4tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x4c);
3536 u4tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x974);
3537 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
3538 "0x40/ 0x4c[24:23]/ 0x974",
3539 u1tmp[0], ((u4tmp[0]&0x01800000)>>23), u4tmp[1]);
3540
3541 u4tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x550);
3542 u1tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x522);
3543 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x",
3544 "0x550(bcn ctrl)/0x522",
3545 u4tmp[0], u1tmp[0]);
3546
3547 u4tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xc50);
3548 u1tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0xa0a);
3549 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x",
3550 "0xc50(DIG)/0xa0a(CCK-TH)",
3551 u4tmp[0], u1tmp[0]);
3552
3553 u4tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xf48);
3554 u1tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0xa5b);
3555 u1tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0xa5c);
3556 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x",
3557 "OFDM-FA/ CCK-FA",
3558 u4tmp[0], (u1tmp[0]<<8) + u1tmp[1]);
3559
3560 u4tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x6c0);
3561 u4tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x6c4);
3562 u4tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x6c8);
3563 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
3564 "0x6c0/0x6c4/0x6c8",
3565 u4tmp[0], u4tmp[1], u4tmp[2]);
3566
3567 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d",
3568 "0x770 (hi-pri Rx/Tx)",
3569 coex_sta->high_priority_rx, coex_sta->high_priority_tx);
3570 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d",
3571 "0x774(low-pri Rx/Tx)",
3572 coex_sta->low_priority_rx, coex_sta->low_priority_tx);
3573
3574 /* Tx mgnt queue hang or not, 0x41b should = 0xf, ex: 0xd ==>hang*/
3575 u1tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x41b);
3576 RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x",
3577 "0x41b (mgntQ hang chk == 0xf)",
3578 u1tmp[0]);
3579
3580 btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_COEX_STATISTICS);
3581}
3582
3583void ex_halbtc8821a2ant_ips_notify(struct btc_coexist *btcoexist, u8 type)
3584{
3585 if (BTC_IPS_ENTER == type) {
3586 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3587 "[BTCoex], IPS ENTER notify\n");
3588 coex_sta->under_ips = true;
3589 halbtc8821a2ant_coex_all_off(btcoexist);
3590 } else if (BTC_IPS_LEAVE == type) {
3591 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3592 "[BTCoex], IPS LEAVE notify\n");
3593 coex_sta->under_ips = false;
3594 /*halbtc8821a2ant_init_coex_dm(btcoexist);*/
3595 }
3596}
3597
3598void ex_halbtc8821a2ant_lps_notify(struct btc_coexist *btcoexist, u8 type)
3599{
3600 if (BTC_LPS_ENABLE == type) {
3601 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3602 "[BTCoex], LPS ENABLE notify\n");
3603 coex_sta->under_lps = true;
3604 } else if (BTC_LPS_DISABLE == type) {
3605 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3606 "[BTCoex], LPS DISABLE notify\n");
3607 coex_sta->under_lps = false;
3608 }
3609}
3610
3611void ex_halbtc8821a2ant_scan_notify(struct btc_coexist *btcoexist, u8 type)
3612{
3613 if (BTC_SCAN_START == type) {
3614 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3615 "[BTCoex], SCAN START notify\n");
3616 } else if (BTC_SCAN_FINISH == type) {
3617 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3618 "[BTCoex], SCAN FINISH notify\n");
3619 }
3620}
3621
3622void ex_halbtc8821a2ant_connect_notify(struct btc_coexist *btcoexist, u8 type)
3623{
3624 if (BTC_ASSOCIATE_START == type) {
3625 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3626 "[BTCoex], CONNECT START notify\n");
3627 } else if (BTC_ASSOCIATE_FINISH == type) {
3628 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3629 "[BTCoex], CONNECT FINISH notify\n");
3630 }
3631}
3632
3633void ex_halbtc8821a2ant_media_status_notify(struct btc_coexist *btcoexist,
3634 u8 type)
3635{
3636 u8 h2c_parameter[3] = {0};
3637 u32 wifi_bw;
3638 u8 wifi_central_chnl;
3639
3640 if (BTC_MEDIA_CONNECT == type) {
3641 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3642 "[BTCoex], MEDIA connect notify\n");
3643 } else {
3644 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3645 "[BTCoex], MEDIA disconnect notify\n");
3646 }
3647
3648 /* only 2.4G we need to inform bt the chnl mask*/
3649 btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_CENTRAL_CHNL,
3650 &wifi_central_chnl);
3651 if ((BTC_MEDIA_CONNECT == type) &&
3652 (wifi_central_chnl <= 14)) {
3653 h2c_parameter[0] = 0x1;
3654 h2c_parameter[1] = wifi_central_chnl;
3655 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
3656 if (BTC_WIFI_BW_HT40 == wifi_bw)
3657 h2c_parameter[2] = 0x30;
3658 else
3659 h2c_parameter[2] = 0x20;
3660 }
3661
3662 coex_dm->wifi_chnl_info[0] = h2c_parameter[0];
3663 coex_dm->wifi_chnl_info[1] = h2c_parameter[1];
3664 coex_dm->wifi_chnl_info[2] = h2c_parameter[2];
3665
3666 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
3667 "[BTCoex], FW write 0x66 = 0x%x\n",
3668 h2c_parameter[0]<<16|h2c_parameter[1]<<8|h2c_parameter[2]);
3669
3670 btcoexist->btc_fill_h2c(btcoexist, 0x66, 3, h2c_parameter);
3671}
3672
3673void ex_halbtc8821a2ant_special_packet_notify(struct btc_coexist *btcoexist,
3674 u8 type) {
3675 if (type == BTC_PACKET_DHCP) {
3676 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3677 "[BTCoex], DHCP Packet notify\n");
3678 }
3679}
3680
3681void ex_halbtc8821a2ant_bt_info_notify(struct btc_coexist *btcoexist,
3682 u8 *tmp_buf, u8 length)
3683{
3684 u8 bt_info = 0;
3685 u8 i, rsp_source = 0;
3686 static u32 set_bt_lna_cnt, set_bt_psd_mode;
3687 bool bt_busy = false, limited_dig = false;
3688 bool wifi_connected = false, bt_hs_on = false;
3689
3690 coex_sta->c2h_bt_info_req_sent = false;
3691
3692 rsp_source = tmp_buf[0]&0xf;
3693 if (rsp_source >= BT_INFO_SRC_8821A_2ANT_MAX)
3694 rsp_source = BT_INFO_SRC_8821A_2ANT_WIFI_FW;
3695 coex_sta->bt_info_c2h_cnt[rsp_source]++;
3696
3697 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3698 "[BTCoex], Bt info[%d], length = %d, hex data = [",
3699 rsp_source, length);
3700 for (i = 0; i < length; i++) {
3701 coex_sta->bt_info_c2h[rsp_source][i] = tmp_buf[i];
3702 if (i == 1)
3703 bt_info = tmp_buf[i];
3704 if (i == length-1) {
3705 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3706 "0x%02x]\n", tmp_buf[i]);
3707 } else {
3708 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3709 "0x%02x, ", tmp_buf[i]);
3710 }
3711 }
3712
3713 if (BT_INFO_SRC_8821A_2ANT_WIFI_FW != rsp_source) {
3714 coex_sta->bt_retry_cnt = /* [3:0]*/
3715 coex_sta->bt_info_c2h[rsp_source][2]&0xf;
3716
3717 coex_sta->bt_rssi =
3718 coex_sta->bt_info_c2h[rsp_source][3]*2+10;
3719
3720 coex_sta->bt_info_ext =
3721 coex_sta->bt_info_c2h[rsp_source][4];
3722
3723 /* Here we need to resend some wifi info to BT*/
3724 /* because bt is reset and loss of the info.*/
3725 if ((coex_sta->bt_info_ext & BIT1)) {
3726 btcoexist->btc_get(btcoexist,
3727 BTC_GET_BL_WIFI_CONNECTED, &wifi_connected);
3728 if (wifi_connected) {
3729 ex_halbtc8821a2ant_media_status_notify(btcoexist,
3730 BTC_MEDIA_CONNECT);
3731 } else {
3732 ex_halbtc8821a2ant_media_status_notify(btcoexist,
3733 BTC_MEDIA_DISCONNECT);
3734 }
3735
3736 set_bt_psd_mode = 0;
3737 }
3738 if (set_bt_psd_mode <= 3) {
3739 halbtc8821a2ant_set_bt_psd_mode(btcoexist, FORCE_EXEC,
3740 0x0); /*fix CH-BW mode*/
3741 set_bt_psd_mode++;
3742 }
3743
3744 if (coex_dm->cur_bt_lna_constrain) {
3745 if (!(coex_sta->bt_info_ext & BIT2)) {
3746 if (set_bt_lna_cnt <= 3) {
3747 btc8821a2_set_bt_lna_const(btcoexist,
3748 FORCE_EXEC,
3749 true);
3750 set_bt_lna_cnt++;
3751 }
3752 }
3753 } else {
3754 set_bt_lna_cnt = 0;
3755 }
3756
3757 if ((coex_sta->bt_info_ext & BIT3)) {
3758 halbtc8821a2ant_ignore_wlan_act(btcoexist,
3759 FORCE_EXEC, false);
3760 } else {
3761 /* BT already NOT ignore Wlan active, do nothing here.*/
3762 }
3763
3764 if ((coex_sta->bt_info_ext & BIT4)) {
3765 /* BT auto report already enabled, do nothing*/
3766 } else {
3767 halbtc8821a2ant_bt_auto_report(btcoexist,
3768 FORCE_EXEC, true);
3769 }
3770 }
3771
3772 btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
3773 /* check BIT2 first ==> check if bt is under inquiry or page scan*/
3774 if (bt_info & BT_INFO_8821A_2ANT_B_INQ_PAGE) {
3775 coex_sta->c2h_bt_inquiry_page = true;
3776 coex_dm->bt_status = BT_8821A_2ANT_BT_STATUS_NON_IDLE;
3777 } else {
3778 coex_sta->c2h_bt_inquiry_page = false;
3779 if (bt_info == 0x1) {
3780 /* connection exists but not busy*/
3781 coex_sta->bt_link_exist = true;
3782 coex_dm->bt_status = BT_8821A_2ANT_BT_STATUS_CON_IDLE;
3783 } else if (bt_info & BT_INFO_8821A_2ANT_B_CONNECTION) {
3784 /* connection exists and some link is busy*/
3785 coex_sta->bt_link_exist = true;
3786 if (bt_info & BT_INFO_8821A_2ANT_B_FTP)
3787 coex_sta->pan_exist = true;
3788 else
3789 coex_sta->pan_exist = false;
3790 if (bt_info & BT_INFO_8821A_2ANT_B_A2DP)
3791 coex_sta->a2dp_exist = true;
3792 else
3793 coex_sta->a2dp_exist = false;
3794 if (bt_info & BT_INFO_8821A_2ANT_B_HID)
3795 coex_sta->hid_exist = true;
3796 else
3797 coex_sta->hid_exist = false;
3798 if (bt_info & BT_INFO_8821A_2ANT_B_SCO_ESCO)
3799 coex_sta->sco_exist = true;
3800 else
3801 coex_sta->sco_exist = false;
3802 coex_dm->bt_status = BT_8821A_2ANT_BT_STATUS_NON_IDLE;
3803 } else {
3804 coex_sta->bt_link_exist = false;
3805 coex_sta->pan_exist = false;
3806 coex_sta->a2dp_exist = false;
3807 coex_sta->hid_exist = false;
3808 coex_sta->sco_exist = false;
3809 coex_dm->bt_status = BT_8821A_2ANT_BT_STATUS_IDLE;
3810 }
3811
3812 if (bt_hs_on)
3813 coex_dm->bt_status = BT_8821A_2ANT_BT_STATUS_NON_IDLE;
3814 }
3815
3816 if (BT_8821A_2ANT_BT_STATUS_NON_IDLE == coex_dm->bt_status)
3817 bt_busy = true;
3818 else
3819 bt_busy = false;
3820 btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bt_busy);
3821
3822 if (BT_8821A_2ANT_BT_STATUS_IDLE != coex_dm->bt_status)
3823 limited_dig = true;
3824 else
3825 limited_dig = false;
3826 coex_dm->limited_dig = limited_dig;
3827 btcoexist->btc_set(btcoexist,
3828 BTC_SET_BL_BT_LIMITED_DIG, &limited_dig);
3829
3830 halbtc8821a2ant_run_coexist_mechanism(btcoexist);
3831}
3832
3833void ex_halbtc8821a2ant_halt_notify(struct btc_coexist *btcoexist)
3834{
3835 BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
3836 "[BTCoex], Halt notify\n");
3837
3838 halbtc8821a2ant_ignore_wlan_act(btcoexist, FORCE_EXEC, true);
3839 ex_halbtc8821a2ant_media_status_notify(btcoexist, BTC_MEDIA_DISCONNECT);
3840}
3841
3842void ex_halbtc8821a2ant_periodical(struct btc_coexist *btcoexist)
3843{
3844 static u8 dis_ver_info_cnt;
3845 u32 fw_ver = 0, bt_patch_ver = 0;
3846 struct btc_board_info *board_info = &btcoexist->board_info;
3847 struct btc_stack_info *stack_info = &btcoexist->stack_info;
3848
3849 BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
3850 "[BTCoex], ==========================Periodical===========================\n");
3851
3852 if (dis_ver_info_cnt <= 5) {
3853 dis_ver_info_cnt += 1;
3854 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
3855 "[BTCoex], ****************************************************************\n");
3856 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
3857 "[BTCoex], Ant PG Num/ Ant Mech/ Ant Pos = %d/ %d/ %d\n",
3858 board_info->pg_ant_num,
3859 board_info->btdm_ant_num,
3860 board_info->btdm_ant_pos);
3861 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
3862 "[BTCoex], BT stack/ hci ext ver = %s / %d\n",
3863 ((stack_info->profile_notified) ? "Yes" : "No"),
3864 stack_info->hci_version);
3865 btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER,
3866 &bt_patch_ver);
3867 btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver);
3868 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
3869 "[BTCoex], CoexVer/ FwVer/ PatchVer = %d_%x/ 0x%x/ 0x%x(%d)\n",
3870 glcoex_ver_date_8821a_2ant, glcoex_ver_8821a_2ant,
3871 fw_ver, bt_patch_ver, bt_patch_ver);
3872 BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
3873 "[BTCoex], ****************************************************************\n");
3874 }
3875
3876 halbtc8821a2ant_query_bt_info(btcoexist);
3877 halbtc8821a2ant_monitor_bt_ctr(btcoexist);
3878 btc8821a2ant_mon_bt_en_dis(btcoexist);
3879}
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a2ant.h b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a2ant.h
new file mode 100644
index 000000000000..b4cf1f53d510
--- /dev/null
+++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtc8821a2ant.h
@@ -0,0 +1,205 @@
1/******************************************************************************
2 *
3 * Copyright(c) 2012 Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
16 *
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
21 *
22 * Larry Finger <Larry.Finger@lwfinger.net>
23 *
24 *****************************************************************************/
25
26/*===========================================
27 * The following is for 8821A 2Ant BT Co-exist definition
28 *===========================================
29*/
30#define BT_INFO_8821A_2ANT_B_FTP BIT7
31#define BT_INFO_8821A_2ANT_B_A2DP BIT6
32#define BT_INFO_8821A_2ANT_B_HID BIT5
33#define BT_INFO_8821A_2ANT_B_SCO_BUSY BIT4
34#define BT_INFO_8821A_2ANT_B_ACL_BUSY BIT3
35#define BT_INFO_8821A_2ANT_B_INQ_PAGE BIT2
36#define BT_INFO_8821A_2ANT_B_SCO_ESCO BIT1
37#define BT_INFO_8821A_2ANT_B_CONNECTION BIT0
38
39#define BTC_RSSI_COEX_THRESH_TOL_8821A_2ANT 2
40
41enum _BT_INFO_SRC_8821A_2ANT {
42 BT_INFO_SRC_8821A_2ANT_WIFI_FW = 0x0,
43 BT_INFO_SRC_8821A_2ANT_BT_RSP = 0x1,
44 BT_INFO_SRC_8821A_2ANT_BT_ACTIVE_SEND = 0x2,
45 BT_INFO_SRC_8821A_2ANT_MAX
46};
47
48enum _BT_8821A_2ANT_BT_STATUS {
49 BT_8821A_2ANT_BT_STATUS_IDLE = 0x0,
50 BT_8821A_2ANT_BT_STATUS_CON_IDLE = 0x1,
51 BT_8821A_2ANT_BT_STATUS_NON_IDLE = 0x2,
52 BT_8821A_2ANT_BT_STATUS_MAX
53};
54
55enum _BT_8821A_2ANT_COEX_ALGO {
56 BT_8821A_2ANT_COEX_ALGO_UNDEFINED = 0x0,
57 BT_8821A_2ANT_COEX_ALGO_SCO = 0x1,
58 BT_8821A_2ANT_COEX_ALGO_HID = 0x2,
59 BT_8821A_2ANT_COEX_ALGO_A2DP = 0x3,
60 BT_8821A_2ANT_COEX_ALGO_A2DP_PANHS = 0x4,
61 BT_8821A_2ANT_COEX_ALGO_PANEDR = 0x5,
62 BT_8821A_2ANT_COEX_ALGO_PANHS = 0x6,
63 BT_8821A_2ANT_COEX_ALGO_PANEDR_A2DP = 0x7,
64 BT_8821A_2ANT_COEX_ALGO_PANEDR_HID = 0x8,
65 BT_8821A_2ANT_COEX_ALGO_HID_A2DP_PANEDR = 0x9,
66 BT_8821A_2ANT_COEX_ALGO_HID_A2DP = 0xa,
67 BT_8821A_2ANT_COEX_ALGO_MAX = 0xb,
68};
69
70struct coex_dm_8821a_2ant {
71 /* fw mechanism */
72 bool pre_dec_bt_pwr;
73 bool cur_dec_bt_pwr;
74 bool pre_bt_lna_constrain;
75 bool cur_bt_lna_constrain;
76 u8 pre_bt_psd_mode;
77 u8 cur_bt_psd_mode;
78 u8 pre_fw_dac_swing_lvl;
79 u8 cur_fw_dac_swing_lvl;
80 bool cur_ignore_wlan_act;
81 bool pre_ignore_wlan_act;
82 u8 pre_ps_tdma;
83 u8 cur_ps_tdma;
84 u8 ps_tdma_para[5];
85 u8 tdma_adj_type;
86 bool reset_tdma_adjust;
87 bool pre_ps_tdma_on;
88 bool cur_ps_tdma_on;
89 bool pre_bt_auto_report;
90 bool cur_bt_auto_report;
91
92 /* sw mechanism */
93 bool pre_rf_rx_lpf_shrink;
94 bool cur_rf_rx_lpf_shrink;
95 u32 bt_rf0x1e_backup;
96 bool pre_low_penalty_ra;
97 bool cur_low_penalty_ra;
98 bool pre_dac_swing_on;
99 u32 pre_dac_swing_lvl;
100 bool cur_dac_swing_on;
101 u32 cur_dac_swing_lvl;
102 bool pre_adc_back_off;
103 bool cur_adc_back_off;
104 bool pre_agc_table_en;
105 bool cur_agc_table_en;
106 u32 pre_val0x6c0;
107 u32 cur_val0x6c0;
108 u32 pre_val0x6c4;
109 u32 cur_val0x6c4;
110 u32 pre_val0x6c8;
111 u32 cur_val0x6c8;
112 u8 pre_val0x6cc;
113 u8 cur_val0x6cc;
114 bool limited_dig;
115
116 /* algorithm related */
117 u8 pre_algorithm;
118 u8 cur_algorithm;
119 u8 bt_status;
120 u8 wifi_chnl_info[3];
121};
122
123struct coex_sta_8821a_2ant {
124 bool bt_link_exist;
125 bool sco_exist;
126 bool a2dp_exist;
127 bool hid_exist;
128 bool pan_exist;
129 bool under_lps;
130 bool under_ips;
131 u32 high_priority_tx;
132 u32 high_priority_rx;
133 u32 low_priority_tx;
134 u32 low_priority_rx;
135 u8 bt_rssi;
136 u8 pre_bt_rssi_state;
137 u8 pre_wifi_rssi_state[4];
138 bool c2h_bt_info_req_sent;
139 u8 bt_info_c2h[BT_INFO_SRC_8821A_2ANT_MAX][10];
140 u32 bt_info_c2h_cnt[BT_INFO_SRC_8821A_2ANT_MAX];
141 bool c2h_bt_inquiry_page;
142 u8 bt_retry_cnt;
143 u8 bt_info_ext;
144};
145
146/*===========================================
147 * The following is interface which will notify coex module.
148 *===========================================
149 */
150void
151ex_halbtc8821a2ant_init_hwconfig(
152 struct btc_coexist *btcoexist
153 );
154void
155ex_halbtc8821a2ant_init_coex_dm(
156 struct btc_coexist *btcoexist
157 );
158void
159ex_halbtc8821a2ant_ips_notify(
160 struct btc_coexist *btcoexist,
161 u8 type
162 );
163void
164ex_halbtc8821a2ant_lps_notify(
165 struct btc_coexist *btcoexist,
166 u8 type
167 );
168void
169ex_halbtc8821a2ant_scan_notify(
170 struct btc_coexist *btcoexist,
171 u8 type
172 );
173void
174ex_halbtc8821a2ant_connect_notify(
175 struct btc_coexist *btcoexist,
176 u8 type
177 );
178void
179ex_halbtc8821a2ant_media_status_notify(
180 struct btc_coexist *btcoexist,
181 u8 type
182 );
183void
184ex_halbtc8821a2ant_special_packet_notify(
185 struct btc_coexist *btcoexist,
186 u8 type
187 );
188void
189ex_halbtc8821a2ant_bt_info_notify(
190 struct btc_coexist *btcoexist,
191 u8 *tmp_buf,
192 u8 length
193 );
194void
195ex_halbtc8821a2ant_halt_notify(
196 struct btc_coexist *btcoexist
197 );
198void
199ex_halbtc8821a2ant_periodical(
200 struct btc_coexist *btcoexist
201 );
202void
203ex_halbtc8821a2ant_display_coex_info(
204 struct btc_coexist *btcoexist
205 );
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.c b/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.c
index d4bd550f505c..fcf7459b5d66 100644
--- a/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.c
+++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.c
@@ -32,7 +32,6 @@
32struct btc_coexist gl_bt_coexist; 32struct btc_coexist gl_bt_coexist;
33 33
34u32 btc_dbg_type[BTC_MSG_MAX]; 34u32 btc_dbg_type[BTC_MSG_MAX];
35static u8 btc_dbg_buf[100];
36 35
37/*************************************************** 36/***************************************************
38 * Debug related function 37 * Debug related function
@@ -389,7 +388,7 @@ static bool halbtc_set(void *void_btcoexist, u8 set_type, void *in_buf)
389 btcoexist->bt_info.reject_agg_pkt = *bool_tmp; 388 btcoexist->bt_info.reject_agg_pkt = *bool_tmp;
390 break; 389 break;
391 case BTC_SET_BL_BT_CTRL_AGG_SIZE: 390 case BTC_SET_BL_BT_CTRL_AGG_SIZE:
392 btcoexist->bt_info.b_bt_ctrl_buf_size = *bool_tmp; 391 btcoexist->bt_info.bt_ctrl_buf_size = *bool_tmp;
393 break; 392 break;
394 case BTC_SET_BL_INC_SCAN_DEV_NUM: 393 case BTC_SET_BL_INC_SCAN_DEV_NUM:
395 btcoexist->bt_info.increase_scan_dev_num = *bool_tmp; 394 btcoexist->bt_info.increase_scan_dev_num = *bool_tmp;
@@ -417,10 +416,10 @@ static bool halbtc_set(void *void_btcoexist, u8 set_type, void *in_buf)
417 /* rtlpriv->mlmepriv.scan_compensation = *u8_tmp; */ 416 /* rtlpriv->mlmepriv.scan_compensation = *u8_tmp; */
418 break; 417 break;
419 case BTC_SET_U1_1ANT_LPS: 418 case BTC_SET_U1_1ANT_LPS:
420 btcoexist->bt_info.lps_1ant = *u8_tmp; 419 btcoexist->bt_info.lps_val = *u8_tmp;
421 break; 420 break;
422 case BTC_SET_U1_1ANT_RPWM: 421 case BTC_SET_U1_1ANT_RPWM:
423 btcoexist->bt_info.rpwm_1ant = *u8_tmp; 422 btcoexist->bt_info.rpwm_val = *u8_tmp;
424 break; 423 break;
425 /* the following are some action which will be triggered */ 424 /* the following are some action which will be triggered */
426 case BTC_SET_ACT_LEAVE_LPS: 425 case BTC_SET_ACT_LEAVE_LPS:
@@ -497,7 +496,7 @@ static u32 halbtc_read_4byte(void *bt_context, u32 reg_addr)
497 return rtl_read_dword(rtlpriv, reg_addr); 496 return rtl_read_dword(rtlpriv, reg_addr);
498} 497}
499 498
500static void halbtc_write_1byte(void *bt_context, u32 reg_addr, u8 data) 499static void halbtc_write_1byte(void *bt_context, u32 reg_addr, u32 data)
501{ 500{
502 struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context; 501 struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
503 struct rtl_priv *rtlpriv = btcoexist->adapter; 502 struct rtl_priv *rtlpriv = btcoexist->adapter;
@@ -506,7 +505,7 @@ static void halbtc_write_1byte(void *bt_context, u32 reg_addr, u8 data)
506} 505}
507 506
508static void halbtc_bitmask_write_1byte(void *bt_context, u32 reg_addr, 507static void halbtc_bitmask_write_1byte(void *bt_context, u32 reg_addr,
509 u32 bit_mask, u8 data) 508 u8 bit_mask, u8 data)
510{ 509{
511 struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context; 510 struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
512 struct rtl_priv *rtlpriv = btcoexist->adapter; 511 struct rtl_priv *rtlpriv = btcoexist->adapter;
@@ -652,9 +651,7 @@ bool exhalbtc_initlize_variables(struct rtl_priv *adapter)
652 btcoexist->btc_get = halbtc_get; 651 btcoexist->btc_get = halbtc_get;
653 btcoexist->btc_set = halbtc_set; 652 btcoexist->btc_set = halbtc_set;
654 653
655 btcoexist->cli_buf = &btc_dbg_buf[0]; 654 btcoexist->bt_info.bt_ctrl_buf_size = false;
656
657 btcoexist->bt_info.b_bt_ctrl_buf_size = false;
658 btcoexist->bt_info.agg_buf_size = 5; 655 btcoexist->bt_info.agg_buf_size = 5;
659 656
660 btcoexist->bt_info.increase_scan_dev_num = false; 657 btcoexist->bt_info.increase_scan_dev_num = false;
@@ -672,7 +669,7 @@ void exhalbtc_init_hw_config(struct btc_coexist *btcoexist)
672 btcoexist->statistics.cnt_init_hw_config++; 669 btcoexist->statistics.cnt_init_hw_config++;
673 670
674 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) 671 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE)
675 ex_halbtc8723b2ant_init_hwconfig(btcoexist); 672 ex_btc8723b2ant_init_hwconfig(btcoexist);
676} 673}
677 674
678void exhalbtc_init_coex_dm(struct btc_coexist *btcoexist) 675void exhalbtc_init_coex_dm(struct btc_coexist *btcoexist)
@@ -686,7 +683,7 @@ void exhalbtc_init_coex_dm(struct btc_coexist *btcoexist)
686 btcoexist->statistics.cnt_init_coex_dm++; 683 btcoexist->statistics.cnt_init_coex_dm++;
687 684
688 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) 685 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE)
689 ex_halbtc8723b2ant_init_coex_dm(btcoexist); 686 ex_btc8723b2ant_init_coex_dm(btcoexist);
690 687
691 btcoexist->initilized = true; 688 btcoexist->initilized = true;
692} 689}
@@ -711,7 +708,7 @@ void exhalbtc_ips_notify(struct btc_coexist *btcoexist, u8 type)
711 halbtc_leave_low_power(); 708 halbtc_leave_low_power();
712 709
713 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) 710 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE)
714 ex_halbtc8723b2ant_ips_notify(btcoexist, ips_type); 711 ex_btc8723b2ant_ips_notify(btcoexist, ips_type);
715 712
716 halbtc_nomal_low_power(); 713 halbtc_nomal_low_power();
717} 714}
@@ -734,7 +731,7 @@ void exhalbtc_lps_notify(struct btc_coexist *btcoexist, u8 type)
734 lps_type = BTC_LPS_ENABLE; 731 lps_type = BTC_LPS_ENABLE;
735 732
736 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) 733 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE)
737 ex_halbtc8723b2ant_lps_notify(btcoexist, lps_type); 734 ex_btc8723b2ant_lps_notify(btcoexist, lps_type);
738} 735}
739 736
740void exhalbtc_scan_notify(struct btc_coexist *btcoexist, u8 type) 737void exhalbtc_scan_notify(struct btc_coexist *btcoexist, u8 type)
@@ -757,7 +754,7 @@ void exhalbtc_scan_notify(struct btc_coexist *btcoexist, u8 type)
757 halbtc_leave_low_power(); 754 halbtc_leave_low_power();
758 755
759 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) 756 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE)
760 ex_halbtc8723b2ant_scan_notify(btcoexist, scan_type); 757 ex_btc8723b2ant_scan_notify(btcoexist, scan_type);
761 758
762 halbtc_nomal_low_power(); 759 halbtc_nomal_low_power();
763} 760}
@@ -782,14 +779,12 @@ void exhalbtc_connect_notify(struct btc_coexist *btcoexist, u8 action)
782 halbtc_leave_low_power(); 779 halbtc_leave_low_power();
783 780
784 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) 781 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE)
785 ex_halbtc8723b2ant_connect_notify(btcoexist, asso_type); 782 ex_btc8723b2ant_connect_notify(btcoexist, asso_type);
786} 783}
787 784
788void exhalbtc_mediastatus_notify(struct btc_coexist *btcoexist, 785void exhalbtc_mediastatus_notify(struct btc_coexist *btcoexist,
789 enum _RT_MEDIA_STATUS media_status) 786 enum rt_media_status media_status)
790{ 787{
791 struct rtl_priv *rtlpriv = btcoexist->adapter;
792 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
793 u8 status; 788 u8 status;
794 789
795 if (!halbtc_is_bt_coexist_available(btcoexist)) 790 if (!halbtc_is_bt_coexist_available(btcoexist))
@@ -805,9 +800,6 @@ void exhalbtc_mediastatus_notify(struct btc_coexist *btcoexist,
805 800
806 halbtc_leave_low_power(); 801 halbtc_leave_low_power();
807 802
808 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE)
809 btc8723b_med_stat_notify(btcoexist, status);
810
811 halbtc_nomal_low_power(); 803 halbtc_nomal_low_power();
812} 804}
813 805
@@ -828,8 +820,8 @@ void exhalbtc_special_packet_notify(struct btc_coexist *btcoexist, u8 pkt_type)
828 halbtc_leave_low_power(); 820 halbtc_leave_low_power();
829 821
830 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) 822 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE)
831 ex_halbtc8723b2ant_special_packet_notify(btcoexist, 823 ex_btc8723b2ant_special_packet_notify(btcoexist,
832 packet_type); 824 packet_type);
833 825
834 halbtc_nomal_low_power(); 826 halbtc_nomal_low_power();
835} 827}
@@ -844,13 +836,11 @@ void exhalbtc_bt_info_notify(struct btc_coexist *btcoexist,
844 btcoexist->statistics.cnt_bt_info_notify++; 836 btcoexist->statistics.cnt_bt_info_notify++;
845 837
846 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) 838 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE)
847 ex_halbtc8723b2ant_bt_info_notify(btcoexist, tmp_buf, length); 839 ex_btc8723b2ant_bt_info_notify(btcoexist, tmp_buf, length);
848} 840}
849 841
850void exhalbtc_stack_operation_notify(struct btc_coexist *btcoexist, u8 type) 842void exhalbtc_stack_operation_notify(struct btc_coexist *btcoexist, u8 type)
851{ 843{
852 struct rtl_priv *rtlpriv = btcoexist->adapter;
853 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
854 u8 stack_op_type; 844 u8 stack_op_type;
855 845
856 if (!halbtc_is_bt_coexist_available(btcoexist)) 846 if (!halbtc_is_bt_coexist_available(btcoexist))
@@ -863,10 +853,6 @@ void exhalbtc_stack_operation_notify(struct btc_coexist *btcoexist, u8 type)
863 853
864 halbtc_leave_low_power(); 854 halbtc_leave_low_power();
865 855
866 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE)
867 ex_halbtc8723b2ant_stack_operation_notify(btcoexist,
868 stack_op_type);
869
870 halbtc_nomal_low_power(); 856 halbtc_nomal_low_power();
871} 857}
872 858
@@ -878,7 +864,7 @@ void exhalbtc_halt_notify(struct btc_coexist *btcoexist)
878 return; 864 return;
879 865
880 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) 866 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE)
881 ex_halbtc8723b2ant_halt_notify(btcoexist); 867 ex_btc8723b2ant_halt_notify(btcoexist);
882} 868}
883 869
884void exhalbtc_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state) 870void exhalbtc_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state)
@@ -898,7 +884,7 @@ void exhalbtc_periodical(struct btc_coexist *btcoexist)
898 halbtc_leave_low_power(); 884 halbtc_leave_low_power();
899 885
900 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) 886 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE)
901 ex_halbtc8723b2ant_periodical(btcoexist); 887 ex_btc8723b2ant_periodical(btcoexist);
902 888
903 halbtc_nomal_low_power(); 889 halbtc_nomal_low_power();
904} 890}
@@ -997,5 +983,5 @@ void exhalbtc_display_bt_coex_info(struct btc_coexist *btcoexist)
997 return; 983 return;
998 984
999 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE) 985 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8723BE)
1000 ex_halbtc8723b2ant_display_coex_info(btcoexist); 986 ex_btc8723b2ant_display_coex_info(btcoexist);
1001} 987}
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.h b/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.h
index 049f4c8d98a8..1345545f66bc 100644
--- a/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.h
+++ b/drivers/net/wireless/rtlwifi/btcoexist/halbtcoutsrc.h
@@ -55,9 +55,16 @@
55#define BTC_RATE_DISABLE 0 55#define BTC_RATE_DISABLE 0
56#define BTC_RATE_ENABLE 1 56#define BTC_RATE_ENABLE 1
57 57
58/* single Antenna definition */
58#define BTC_ANT_PATH_WIFI 0 59#define BTC_ANT_PATH_WIFI 0
59#define BTC_ANT_PATH_BT 1 60#define BTC_ANT_PATH_BT 1
60#define BTC_ANT_PATH_PTA 2 61#define BTC_ANT_PATH_PTA 2
62/* dual Antenna definition */
63#define BTC_ANT_WIFI_AT_MAIN 0
64#define BTC_ANT_WIFI_AT_AUX 1
65/* coupler Antenna definition */
66#define BTC_ANT_WIFI_AT_CPL_MAIN 0
67#define BTC_ANT_WIFI_AT_CPL_AUX 1
61 68
62enum btc_chip_interface { 69enum btc_chip_interface {
63 BTC_INTF_UNKNOWN = 0, 70 BTC_INTF_UNKNOWN = 0,
@@ -68,7 +75,7 @@ enum btc_chip_interface {
68 BTC_INTF_MAX 75 BTC_INTF_MAX
69}; 76};
70 77
71enum BTC_CHIP_TYPE { 78enum btc_chip_type {
72 BTC_CHIP_UNDEF = 0, 79 BTC_CHIP_UNDEF = 0,
73 BTC_CHIP_CSR_BC4 = 1, 80 BTC_CHIP_CSR_BC4 = 1,
74 BTC_CHIP_CSR_BC8 = 2, 81 BTC_CHIP_CSR_BC8 = 2,
@@ -78,11 +85,12 @@ enum BTC_CHIP_TYPE {
78 BTC_CHIP_MAX 85 BTC_CHIP_MAX
79}; 86};
80 87
81enum BTC_MSG_TYPE { 88enum btc_msg_type {
82 BTC_MSG_INTERFACE = 0x0, 89 BTC_MSG_INTERFACE = 0x0,
83 BTC_MSG_ALGORITHM = 0x1, 90 BTC_MSG_ALGORITHM = 0x1,
84 BTC_MSG_MAX 91 BTC_MSG_MAX
85}; 92};
93
86extern u32 btc_dbg_type[]; 94extern u32 btc_dbg_type[];
87 95
88/* following is for BTC_MSG_INTERFACE */ 96/* following is for BTC_MSG_INTERFACE */
@@ -101,20 +109,12 @@ extern u32 btc_dbg_type[];
101#define ALGO_TRACE_SW_DETAIL BIT8 109#define ALGO_TRACE_SW_DETAIL BIT8
102#define ALGO_TRACE_SW_EXEC BIT9 110#define ALGO_TRACE_SW_EXEC BIT9
103 111
104#define BT_COEX_ANT_TYPE_PG 0 112/* following is for wifi link status */
105#define BT_COEX_ANT_TYPE_ANTDIV 1 113#define WIFI_STA_CONNECTED BIT0
106#define BT_COEX_ANT_TYPE_DETECTED 2 114#define WIFI_AP_CONNECTED BIT1
107#define BTC_MIMO_PS_STATIC 0 115#define WIFI_HS_CONNECTED BIT2
108#define BTC_MIMO_PS_DYNAMIC 1 116#define WIFI_P2P_GO_CONNECTED BIT3
109#define BTC_RATE_DISABLE 0 117#define WIFI_P2P_GC_CONNECTED BIT4
110#define BTC_RATE_ENABLE 1
111#define BTC_ANT_PATH_WIFI 0
112#define BTC_ANT_PATH_BT 1
113#define BTC_ANT_PATH_PTA 2
114
115
116#define CL_SPRINTF snprintf
117#define CL_PRINTF(buf) printk("%s", buf)
118 118
119#define BTC_PRINT(dbgtype, dbgflag, printstr, ...) \ 119#define BTC_PRINT(dbgtype, dbgflag, printstr, ...) \
120 do { \ 120 do { \
@@ -123,46 +123,15 @@ extern u32 btc_dbg_type[];
123 } \ 123 } \
124 } while (0) 124 } while (0)
125 125
126#define BTC_PRINT_F(dbgtype, dbgflag, printstr, ...) \ 126#define BTC_RSSI_HIGH(_rssi_) \
127 do { \ 127 ((_rssi_ == BTC_RSSI_STATE_HIGH || \
128 if (unlikely(btc_dbg_type[dbgtype] & dbgflag)) {\ 128 _rssi_ == BTC_RSSI_STATE_STAY_HIGH) ? true : false)
129 pr_info("%s: ", __func__); \ 129#define BTC_RSSI_MEDIUM(_rssi_) \
130 printk(printstr, ##__VA_ARGS__); \ 130 ((_rssi_ == BTC_RSSI_STATE_MEDIUM || \
131 } \ 131 _rssi_ == BTC_RSSI_STATE_STAY_MEDIUM) ? true : false)
132 } while (0) 132#define BTC_RSSI_LOW(_rssi_) \
133 133 ((_rssi_ == BTC_RSSI_STATE_LOW || \
134#define BTC_PRINT_ADDR(dbgtype, dbgflag, printstr, _ptr) \ 134 _rssi_ == BTC_RSSI_STATE_STAY_LOW) ? true : false)
135 do { \
136 if (unlikely(btc_dbg_type[dbgtype] & dbgflag)) { \
137 int __i; \
138 u8 *__ptr = (u8 *)_ptr; \
139 printk printstr; \
140 for (__i = 0; __i < 6; __i++) \
141 printk("%02X%s", __ptr[__i], (__i == 5) ? \
142 "" : "-"); \
143 pr_info("\n"); \
144 } \
145 } while (0)
146
147#define BTC_PRINT_DATA(dbgtype, dbgflag, _titlestring, _hexdata, _hexdatalen) \
148 do { \
149 if (unlikely(btc_dbg_type[dbgtype] & dbgflag)) { \
150 int __i; \
151 u8 *__ptr = (u8 *)_hexdata; \
152 printk(_titlestring); \
153 for (__i = 0; __i < (int)_hexdatalen; __i++) { \
154 printk("%02X%s", __ptr[__i], (((__i + 1) % 4) \
155 == 0) ? " " : " ");\
156 if (((__i + 1) % 16) == 0) \
157 printk("\n"); \
158 } \
159 pr_debug("\n"); \
160 } \
161 } while (0)
162
163#define BTC_ANT_PATH_WIFI 0
164#define BTC_ANT_PATH_BT 1
165#define BTC_ANT_PATH_PTA 2
166 135
167enum btc_power_save_type { 136enum btc_power_save_type {
168 BTC_PS_WIFI_NATIVE = 0, 137 BTC_PS_WIFI_NATIVE = 0,
@@ -224,7 +193,6 @@ enum btc_wifi_pnp {
224 BTC_WIFI_PNP_MAX 193 BTC_WIFI_PNP_MAX
225}; 194};
226 195
227
228enum btc_get_type { 196enum btc_get_type {
229 /* type bool */ 197 /* type bool */
230 BTC_GET_BL_HS_OPERATION, 198 BTC_GET_BL_HS_OPERATION,
@@ -253,6 +221,7 @@ enum btc_get_type {
253 BTC_GET_U4_WIFI_BW, 221 BTC_GET_U4_WIFI_BW,
254 BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, 222 BTC_GET_U4_WIFI_TRAFFIC_DIRECTION,
255 BTC_GET_U4_WIFI_FW_VER, 223 BTC_GET_U4_WIFI_FW_VER,
224 BTC_GET_U4_WIFI_LINK_STATUS,
256 BTC_GET_U4_BT_PATCH_VER, 225 BTC_GET_U4_BT_PATCH_VER,
257 226
258 /* type u1Byte */ 227 /* type u1Byte */
@@ -260,6 +229,7 @@ enum btc_get_type {
260 BTC_GET_U1_WIFI_CENTRAL_CHNL, 229 BTC_GET_U1_WIFI_CENTRAL_CHNL,
261 BTC_GET_U1_WIFI_HS_CHNL, 230 BTC_GET_U1_WIFI_HS_CHNL,
262 BTC_GET_U1_MAC_PHY_MODE, 231 BTC_GET_U1_MAC_PHY_MODE,
232 BTC_GET_U1_AP_NUM,
263 233
264 /* for 1Ant */ 234 /* for 1Ant */
265 BTC_GET_U1_LPS_MODE, 235 BTC_GET_U1_LPS_MODE,
@@ -270,7 +240,6 @@ enum btc_get_type {
270 BTC_GET_MAX 240 BTC_GET_MAX
271}; 241};
272 242
273
274enum btc_set_type { 243enum btc_set_type {
275 /* type bool */ 244 /* type bool */
276 BTC_SET_BL_BT_DISABLE, 245 BTC_SET_BL_BT_DISABLE,
@@ -283,7 +252,6 @@ enum btc_set_type {
283 252
284 /* type u1Byte */ 253 /* type u1Byte */
285 BTC_SET_U1_RSSI_ADJ_VAL_FOR_AGC_TABLE_ON, 254 BTC_SET_U1_RSSI_ADJ_VAL_FOR_AGC_TABLE_ON,
286 BTC_SET_U1_RSSI_ADJ_VAL_FOR_1ANT_COEX_TYPE,
287 BTC_SET_UI_SCAN_SIG_COMPENSATION, 255 BTC_SET_UI_SCAN_SIG_COMPENSATION,
288 BTC_SET_U1_AGG_BUF_SIZE, 256 BTC_SET_U1_AGG_BUF_SIZE,
289 257
@@ -295,6 +263,9 @@ enum btc_set_type {
295 /* type bool */ 263 /* type bool */
296 BTC_SET_BL_BT_SCO_BUSY, 264 BTC_SET_BL_BT_SCO_BUSY,
297 /* type u1Byte */ 265 /* type u1Byte */
266 BTC_SET_U1_RSSI_ADJ_VAL_FOR_1ANT_COEX_TYPE,
267 BTC_SET_U1_LPS_VAL,
268 BTC_SET_U1_RPWM_VAL,
298 BTC_SET_U1_1ANT_LPS, 269 BTC_SET_U1_1ANT_LPS,
299 BTC_SET_U1_1ANT_RPWM, 270 BTC_SET_U1_1ANT_RPWM,
300 /* type trigger some action */ 271 /* type trigger some action */
@@ -358,6 +329,20 @@ enum btc_notify_type_special_packet {
358 BTC_PACKET_MAX 329 BTC_PACKET_MAX
359}; 330};
360 331
332enum hci_ext_bt_operation {
333 HCI_BT_OP_NONE = 0x0,
334 HCI_BT_OP_INQUIRY_START = 0x1,
335 HCI_BT_OP_INQUIRY_FINISH = 0x2,
336 HCI_BT_OP_PAGING_START = 0x3,
337 HCI_BT_OP_PAGING_SUCCESS = 0x4,
338 HCI_BT_OP_PAGING_UNSUCCESS = 0x5,
339 HCI_BT_OP_PAIRING_START = 0x6,
340 HCI_BT_OP_PAIRING_FINISH = 0x7,
341 HCI_BT_OP_BT_DEV_ENABLE = 0x8,
342 HCI_BT_OP_BT_DEV_DISABLE = 0x9,
343 HCI_BT_OP_MAX
344};
345
361enum btc_notify_type_stack_operation { 346enum btc_notify_type_stack_operation {
362 BTC_STACK_OP_NONE = 0x0, 347 BTC_STACK_OP_NONE = 0x0,
363 BTC_STACK_OP_INQ_PAGE_PAIR_START = 0x1, 348 BTC_STACK_OP_INQ_PAGE_PAIR_START = 0x1,
@@ -365,17 +350,16 @@ enum btc_notify_type_stack_operation {
365 BTC_STACK_OP_MAX 350 BTC_STACK_OP_MAX
366}; 351};
367 352
368
369typedef u8 (*bfp_btc_r1)(void *btc_context, u32 reg_addr); 353typedef u8 (*bfp_btc_r1)(void *btc_context, u32 reg_addr);
370 354
371typedef u16 (*bfp_btc_r2)(void *btc_context, u32 reg_addr); 355typedef u16 (*bfp_btc_r2)(void *btc_context, u32 reg_addr);
372 356
373typedef u32 (*bfp_btc_r4)(void *btc_context, u32 reg_addr); 357typedef u32 (*bfp_btc_r4)(void *btc_context, u32 reg_addr);
374 358
375typedef void (*bfp_btc_w1)(void *btc_context, u32 reg_addr, u8 data); 359typedef void (*bfp_btc_w1)(void *btc_context, u32 reg_addr, u32 data);
376 360
377typedef void (*bfp_btc_w1_bit_mak)(void *btc_context, u32 reg_addr, 361typedef void (*bfp_btc_w1_bit_mak)(void *btc_context, u32 reg_addr,
378 u32 bit_mask, u8 data1b); 362 u8 bit_mask, u8 data1b);
379 363
380typedef void (*bfp_btc_w2)(void *btc_context, u32 reg_addr, u16 data); 364typedef void (*bfp_btc_w2)(void *btc_context, u32 reg_addr, u16 data);
381 365
@@ -413,20 +397,22 @@ struct btc_bt_info {
413 u8 agg_buf_size; 397 u8 agg_buf_size;
414 bool limited_dig; 398 bool limited_dig;
415 bool reject_agg_pkt; 399 bool reject_agg_pkt;
416 bool b_bt_ctrl_buf_size; 400 bool bt_ctrl_buf_size;
417 bool increase_scan_dev_num; 401 bool increase_scan_dev_num;
418 u16 bt_hci_ver; 402 u16 bt_hci_ver;
419 u16 bt_real_fw_ver; 403 u16 bt_real_fw_ver;
420 u8 bt_fw_ver; 404 u8 bt_fw_ver;
421 405
406 bool bt_disable_low_pwr;
407
422 /* the following is for 1Ant solution */ 408 /* the following is for 1Ant solution */
423 bool bt_ctrl_lps; 409 bool bt_ctrl_lps;
424 bool bt_pwr_save_mode; 410 bool bt_pwr_save_mode;
425 bool bt_lps_on; 411 bool bt_lps_on;
426 bool force_to_roam; 412 bool force_to_roam;
427 u8 force_exec_pwr_cmd_cnt; 413 u8 force_exec_pwr_cmd_cnt;
428 u8 lps_1ant; 414 u8 lps_val;
429 u8 rpwm_1ant; 415 u8 rpwm_val;
430 u32 ra_mask; 416 u32 ra_mask;
431}; 417};
432 418
@@ -457,6 +443,7 @@ struct btc_statistics {
457 u32 cnt_special_packet_notify; 443 u32 cnt_special_packet_notify;
458 u32 cnt_bt_info_notify; 444 u32 cnt_bt_info_notify;
459 u32 cnt_periodical; 445 u32 cnt_periodical;
446 u32 cnt_coex_dm_switch;
460 u32 cnt_stack_operation_notify; 447 u32 cnt_stack_operation_notify;
461 u32 cnt_dbg_ctrl; 448 u32 cnt_dbg_ctrl;
462}; 449};
@@ -493,7 +480,6 @@ struct btc_coexist {
493 bool initilized; 480 bool initilized;
494 bool stop_coex_dm; 481 bool stop_coex_dm;
495 bool manual_control; 482 bool manual_control;
496 u8 *cli_buf;
497 struct btc_statistics statistics; 483 struct btc_statistics statistics;
498 u8 pwr_mode_val[10]; 484 u8 pwr_mode_val[10];
499 485
@@ -509,7 +495,6 @@ struct btc_coexist {
509 bfp_btc_set_bb_reg btc_set_bb_reg; 495 bfp_btc_set_bb_reg btc_set_bb_reg;
510 bfp_btc_get_bb_reg btc_get_bb_reg; 496 bfp_btc_get_bb_reg btc_get_bb_reg;
511 497
512
513 bfp_btc_set_rf_reg btc_set_rf_reg; 498 bfp_btc_set_rf_reg btc_set_rf_reg;
514 bfp_btc_get_rf_reg btc_get_rf_reg; 499 bfp_btc_get_rf_reg btc_get_rf_reg;
515 500
@@ -533,13 +518,14 @@ void exhalbtc_lps_notify(struct btc_coexist *btcoexist, u8 type);
533void exhalbtc_scan_notify(struct btc_coexist *btcoexist, u8 type); 518void exhalbtc_scan_notify(struct btc_coexist *btcoexist, u8 type);
534void exhalbtc_connect_notify(struct btc_coexist *btcoexist, u8 action); 519void exhalbtc_connect_notify(struct btc_coexist *btcoexist, u8 action);
535void exhalbtc_mediastatus_notify(struct btc_coexist *btcoexist, 520void exhalbtc_mediastatus_notify(struct btc_coexist *btcoexist,
536 enum _RT_MEDIA_STATUS media_status); 521 enum rt_media_status media_status);
537void exhalbtc_special_packet_notify(struct btc_coexist *btcoexist, u8 pkt_type); 522void exhalbtc_special_packet_notify(struct btc_coexist *btcoexist, u8 pkt_type);
538void exhalbtc_bt_info_notify(struct btc_coexist *btcoexist, u8 *tmp_buf, 523void exhalbtc_bt_info_notify(struct btc_coexist *btcoexist, u8 *tmp_buf,
539 u8 length); 524 u8 length);
540void exhalbtc_stack_operation_notify(struct btc_coexist *btcoexist, u8 type); 525void exhalbtc_stack_operation_notify(struct btc_coexist *btcoexist, u8 type);
541void exhalbtc_halt_notify(struct btc_coexist *btcoexist); 526void exhalbtc_halt_notify(struct btc_coexist *btcoexist);
542void exhalbtc_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state); 527void exhalbtc_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state);
528void exhalbtc_coex_dm_switch(struct btc_coexist *btcoexist);
543void exhalbtc_periodical(struct btc_coexist *btcoexist); 529void exhalbtc_periodical(struct btc_coexist *btcoexist);
544void exhalbtc_dbg_control(struct btc_coexist *btcoexist, u8 code, u8 len, 530void exhalbtc_dbg_control(struct btc_coexist *btcoexist, u8 code, u8 len,
545 u8 *data); 531 u8 *data);
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.c b/drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.c
index 0ab94fe4cbbe..b9b0cb7af8ea 100644
--- a/drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.c
+++ b/drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.c
@@ -22,19 +22,19 @@
22 * Larry Finger <Larry.Finger@lwfinger.net> 22 * Larry Finger <Larry.Finger@lwfinger.net>
23 * 23 *
24 *****************************************************************************/ 24 *****************************************************************************/
25
26#include "../wifi.h" 25#include "../wifi.h"
27#include "rtl_btc.h"
28#include "halbt_precomp.h"
29
30#include <linux/vmalloc.h> 26#include <linux/vmalloc.h>
31#include <linux/module.h> 27#include <linux/module.h>
32 28
29#include "rtl_btc.h"
30#include "halbt_precomp.h"
31
33static struct rtl_btc_ops rtl_btc_operation = { 32static struct rtl_btc_ops rtl_btc_operation = {
34 .btc_init_variables = rtl_btc_init_variables, 33 .btc_init_variables = rtl_btc_init_variables,
35 .btc_init_hal_vars = rtl_btc_init_hal_vars, 34 .btc_init_hal_vars = rtl_btc_init_hal_vars,
36 .btc_init_hw_config = rtl_btc_init_hw_config, 35 .btc_init_hw_config = rtl_btc_init_hw_config,
37 .btc_ips_notify = rtl_btc_ips_notify, 36 .btc_ips_notify = rtl_btc_ips_notify,
37 .btc_lps_notify = rtl_btc_lps_notify,
38 .btc_scan_notify = rtl_btc_scan_notify, 38 .btc_scan_notify = rtl_btc_scan_notify,
39 .btc_connect_notify = rtl_btc_connect_notify, 39 .btc_connect_notify = rtl_btc_connect_notify,
40 .btc_mediastatus_notify = rtl_btc_mediastatus_notify, 40 .btc_mediastatus_notify = rtl_btc_mediastatus_notify,
@@ -44,6 +44,7 @@ static struct rtl_btc_ops rtl_btc_operation = {
44 .btc_is_limited_dig = rtl_btc_is_limited_dig, 44 .btc_is_limited_dig = rtl_btc_is_limited_dig,
45 .btc_is_disable_edca_turbo = rtl_btc_is_disable_edca_turbo, 45 .btc_is_disable_edca_turbo = rtl_btc_is_disable_edca_turbo,
46 .btc_is_bt_disabled = rtl_btc_is_bt_disabled, 46 .btc_is_bt_disabled = rtl_btc_is_bt_disabled,
47 .btc_special_packet_notify = rtl_btc_special_packet_notify,
47}; 48};
48 49
49void rtl_btc_init_variables(struct rtl_priv *rtlpriv) 50void rtl_btc_init_variables(struct rtl_priv *rtlpriv)
@@ -85,6 +86,11 @@ void rtl_btc_ips_notify(struct rtl_priv *rtlpriv, u8 type)
85 exhalbtc_ips_notify(&gl_bt_coexist, type); 86 exhalbtc_ips_notify(&gl_bt_coexist, type);
86} 87}
87 88
89void rtl_btc_lps_notify(struct rtl_priv *rtlpriv, u8 type)
90{
91 exhalbtc_lps_notify(&gl_bt_coexist, type);
92}
93
88void rtl_btc_scan_notify(struct rtl_priv *rtlpriv, u8 scantype) 94void rtl_btc_scan_notify(struct rtl_priv *rtlpriv, u8 scantype)
89{ 95{
90 exhalbtc_scan_notify(&gl_bt_coexist, scantype); 96 exhalbtc_scan_notify(&gl_bt_coexist, scantype);
@@ -96,13 +102,14 @@ void rtl_btc_connect_notify(struct rtl_priv *rtlpriv, u8 action)
96} 102}
97 103
98void rtl_btc_mediastatus_notify(struct rtl_priv *rtlpriv, 104void rtl_btc_mediastatus_notify(struct rtl_priv *rtlpriv,
99 enum _RT_MEDIA_STATUS mstatus) 105 enum rt_media_status mstatus)
100{ 106{
101 exhalbtc_mediastatus_notify(&gl_bt_coexist, mstatus); 107 exhalbtc_mediastatus_notify(&gl_bt_coexist, mstatus);
102} 108}
103 109
104void rtl_btc_periodical(struct rtl_priv *rtlpriv) 110void rtl_btc_periodical(struct rtl_priv *rtlpriv)
105{ 111{
112 /*rtl_bt_dm_monitor();*/
106 exhalbtc_periodical(&gl_bt_coexist); 113 exhalbtc_periodical(&gl_bt_coexist);
107} 114}
108 115
@@ -150,12 +157,18 @@ bool rtl_btc_is_disable_edca_turbo(struct rtl_priv *rtlpriv)
150 157
151bool rtl_btc_is_bt_disabled(struct rtl_priv *rtlpriv) 158bool rtl_btc_is_bt_disabled(struct rtl_priv *rtlpriv)
152{ 159{
160 /* It seems 'bt_disabled' is never be initialized or set. */
153 if (gl_bt_coexist.bt_info.bt_disabled) 161 if (gl_bt_coexist.bt_info.bt_disabled)
154 return true; 162 return true;
155 else 163 else
156 return false; 164 return false;
157} 165}
158 166
167void rtl_btc_special_packet_notify(struct rtl_priv *rtlpriv, u8 pkt_type)
168{
169 return exhalbtc_special_packet_notify(&gl_bt_coexist, pkt_type);
170}
171
159struct rtl_btc_ops *rtl_btc_get_ops_pointer(void) 172struct rtl_btc_ops *rtl_btc_get_ops_pointer(void)
160{ 173{
161 return &rtl_btc_operation; 174 return &rtl_btc_operation;
@@ -174,11 +187,11 @@ u8 rtl_get_hwpg_ant_num(struct rtl_priv *rtlpriv)
174 return num; 187 return num;
175} 188}
176 189
177enum _RT_MEDIA_STATUS mgnt_link_status_query(struct ieee80211_hw *hw) 190enum rt_media_status mgnt_link_status_query(struct ieee80211_hw *hw)
178{ 191{
179 struct rtl_priv *rtlpriv = rtl_priv(hw); 192 struct rtl_priv *rtlpriv = rtl_priv(hw);
180 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 193 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
181 enum _RT_MEDIA_STATUS m_status = RT_MEDIA_DISCONNECT; 194 enum rt_media_status m_status = RT_MEDIA_DISCONNECT;
182 195
183 u8 bibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? 1 : 0; 196 u8 bibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? 1 : 0;
184 197
diff --git a/drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.h b/drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.h
index 805b22cc8fc8..ccd5a0f91e3b 100644
--- a/drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.h
+++ b/drivers/net/wireless/rtlwifi/btcoexist/rtl_btc.h
@@ -31,22 +31,24 @@ void rtl_btc_init_variables(struct rtl_priv *rtlpriv);
31void rtl_btc_init_hal_vars(struct rtl_priv *rtlpriv); 31void rtl_btc_init_hal_vars(struct rtl_priv *rtlpriv);
32void rtl_btc_init_hw_config(struct rtl_priv *rtlpriv); 32void rtl_btc_init_hw_config(struct rtl_priv *rtlpriv);
33void rtl_btc_ips_notify(struct rtl_priv *rtlpriv, u8 type); 33void rtl_btc_ips_notify(struct rtl_priv *rtlpriv, u8 type);
34void rtl_btc_lps_notify(struct rtl_priv *rtlpriv, u8 type);
34void rtl_btc_scan_notify(struct rtl_priv *rtlpriv, u8 scantype); 35void rtl_btc_scan_notify(struct rtl_priv *rtlpriv, u8 scantype);
35void rtl_btc_connect_notify(struct rtl_priv *rtlpriv, u8 action); 36void rtl_btc_connect_notify(struct rtl_priv *rtlpriv, u8 action);
36void rtl_btc_mediastatus_notify(struct rtl_priv *rtlpriv, 37void rtl_btc_mediastatus_notify(struct rtl_priv *rtlpriv,
37 enum _RT_MEDIA_STATUS mstatus); 38 enum rt_media_status mstatus);
38void rtl_btc_periodical(struct rtl_priv *rtlpriv); 39void rtl_btc_periodical(struct rtl_priv *rtlpriv);
39void rtl_btc_halt_notify(void); 40void rtl_btc_halt_notify(void);
40void rtl_btc_btinfo_notify(struct rtl_priv *rtlpriv, u8 *tmpbuf, u8 length); 41void rtl_btc_btinfo_notify(struct rtl_priv *rtlpriv, u8 *tmpbuf, u8 length);
41bool rtl_btc_is_limited_dig(struct rtl_priv *rtlpriv); 42bool rtl_btc_is_limited_dig(struct rtl_priv *rtlpriv);
42bool rtl_btc_is_disable_edca_turbo(struct rtl_priv *rtlpriv); 43bool rtl_btc_is_disable_edca_turbo(struct rtl_priv *rtlpriv);
43bool rtl_btc_is_bt_disabled(struct rtl_priv *rtlpriv); 44bool rtl_btc_is_bt_disabled(struct rtl_priv *rtlpriv);
45void rtl_btc_special_packet_notify(struct rtl_priv *rtlpriv, u8 pkt_type);
44 46
45struct rtl_btc_ops *rtl_btc_get_ops_pointer(void); 47struct rtl_btc_ops *rtl_btc_get_ops_pointer(void);
46 48
47u8 rtl_get_hwpg_ant_num(struct rtl_priv *rtlpriv); 49u8 rtl_get_hwpg_ant_num(struct rtl_priv *rtlpriv);
48u8 rtl_get_hwpg_bt_exist(struct rtl_priv *rtlpriv); 50u8 rtl_get_hwpg_bt_exist(struct rtl_priv *rtlpriv);
49u8 rtl_get_hwpg_bt_type(struct rtl_priv *rtlpriv); 51u8 rtl_get_hwpg_bt_type(struct rtl_priv *rtlpriv);
50enum _RT_MEDIA_STATUS mgnt_link_status_query(struct ieee80211_hw *hw); 52enum rt_media_status mgnt_link_status_query(struct ieee80211_hw *hw);
51 53
52#endif 54#endif
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c
index 67d1ee6edcad..74a8ba4b8844 100644
--- a/drivers/net/wireless/rtlwifi/pci.c
+++ b/drivers/net/wireless/rtlwifi/pci.c
@@ -646,7 +646,7 @@ static void _rtl_pci_tx_isr(struct ieee80211_hw *hw, int prio)
646 == 2) { 646 == 2) {
647 647
648 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, 648 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
649 "more desc left, wake skb_queue@%d, ring->idx = %d, skb_queue_len = 0x%d\n", 649 "more desc left, wake skb_queue@%d, ring->idx = %d, skb_queue_len = 0x%x\n",
650 prio, ring->idx, 650 prio, ring->idx,
651 skb_queue_len(&ring->queue)); 651 skb_queue_len(&ring->queue));
652 652
@@ -1469,7 +1469,7 @@ static int rtl_pci_tx(struct ieee80211_hw *hw,
1469 1469
1470 if ((own == 1) && (hw_queue != BEACON_QUEUE)) { 1470 if ((own == 1) && (hw_queue != BEACON_QUEUE)) {
1471 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, 1471 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1472 "No more TX desc@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%d\n", 1472 "No more TX desc@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%x\n",
1473 hw_queue, ring->idx, idx, 1473 hw_queue, ring->idx, idx,
1474 skb_queue_len(&ring->queue)); 1474 skb_queue_len(&ring->queue));
1475 1475
@@ -1511,7 +1511,7 @@ static int rtl_pci_tx(struct ieee80211_hw *hw,
1511 if ((ring->entries - skb_queue_len(&ring->queue)) < 2 && 1511 if ((ring->entries - skb_queue_len(&ring->queue)) < 2 &&
1512 hw_queue != BEACON_QUEUE) { 1512 hw_queue != BEACON_QUEUE) {
1513 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, 1513 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
1514 "less desc left, stop skb_queue@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%d\n", 1514 "less desc left, stop skb_queue@%d, ring->idx = %d, idx = %d, skb_queue_len = 0x%x\n",
1515 hw_queue, ring->idx, idx, 1515 hw_queue, ring->idx, idx,
1516 skb_queue_len(&ring->queue)); 1516 skb_queue_len(&ring->queue));
1517 1517
diff --git a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c
index 592125a5f19c..1961b8e28dc1 100644
--- a/drivers/net/wireless/rtlwifi/rtl8192de/phy.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/phy.c
@@ -677,7 +677,7 @@ static void _rtl92d_store_pwrindex_diffrate_offset(struct ieee80211_hw *hw,
677 677
678 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][index] = data; 678 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][index] = data;
679 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, 679 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
680 "MCSTxPowerLevelOriginalOffset[%d][%d] = 0x%ulx\n", 680 "MCSTxPowerLevelOriginalOffset[%d][%d] = 0x%x\n",
681 rtlphy->pwrgroup_cnt, index, 681 rtlphy->pwrgroup_cnt, index,
682 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][index]); 682 rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][index]);
683 if (index == 13) 683 if (index == 13)
@@ -2531,7 +2531,7 @@ static void _rtl92d_phy_reload_lck_setting(struct ieee80211_hw *hw,
2531 if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G) {/* Path-A for 5G */ 2531 if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G) {/* Path-A for 5G */
2532 u4tmp = curveindex_5g[channel-1]; 2532 u4tmp = curveindex_5g[channel-1];
2533 RTPRINT(rtlpriv, FINIT, INIT_IQK, 2533 RTPRINT(rtlpriv, FINIT, INIT_IQK,
2534 "ver 1 set RF-A, 5G, 0x28 = 0x%ulx !!\n", u4tmp); 2534 "ver 1 set RF-A, 5G, 0x28 = 0x%x !!\n", u4tmp);
2535 if (rtlpriv->rtlhal.macphymode == DUALMAC_DUALPHY && 2535 if (rtlpriv->rtlhal.macphymode == DUALMAC_DUALPHY &&
2536 rtlpriv->rtlhal.interfaceindex == 1) { 2536 rtlpriv->rtlhal.interfaceindex == 1) {
2537 bneed_powerdown_radio = 2537 bneed_powerdown_radio =
@@ -2550,7 +2550,7 @@ static void _rtl92d_phy_reload_lck_setting(struct ieee80211_hw *hw,
2550 } else if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G) { 2550 } else if (rtlpriv->rtlhal.current_bandtype == BAND_ON_2_4G) {
2551 u4tmp = curveindex_2g[channel-1]; 2551 u4tmp = curveindex_2g[channel-1];
2552 RTPRINT(rtlpriv, FINIT, INIT_IQK, 2552 RTPRINT(rtlpriv, FINIT, INIT_IQK,
2553 "ver 3 set RF-B, 2G, 0x28 = 0x%ulx !!\n", u4tmp); 2553 "ver 3 set RF-B, 2G, 0x28 = 0x%x !!\n", u4tmp);
2554 if (rtlpriv->rtlhal.macphymode == DUALMAC_DUALPHY && 2554 if (rtlpriv->rtlhal.macphymode == DUALMAC_DUALPHY &&
2555 rtlpriv->rtlhal.interfaceindex == 0) { 2555 rtlpriv->rtlhal.interfaceindex == 0) {
2556 bneed_powerdown_radio = 2556 bneed_powerdown_radio =
@@ -2562,7 +2562,7 @@ static void _rtl92d_phy_reload_lck_setting(struct ieee80211_hw *hw,
2562 } 2562 }
2563 rtl_set_rfreg(hw, erfpath, RF_SYN_G4, 0x3f800, u4tmp); 2563 rtl_set_rfreg(hw, erfpath, RF_SYN_G4, 0x3f800, u4tmp);
2564 RTPRINT(rtlpriv, FINIT, INIT_IQK, 2564 RTPRINT(rtlpriv, FINIT, INIT_IQK,
2565 "ver 3 set RF-B, 2G, 0x28 = 0x%ulx !!\n", 2565 "ver 3 set RF-B, 2G, 0x28 = 0x%x !!\n",
2566 rtl_get_rfreg(hw, erfpath, RF_SYN_G4, 0x3f800)); 2566 rtl_get_rfreg(hw, erfpath, RF_SYN_G4, 0x3f800));
2567 if (bneed_powerdown_radio) 2567 if (bneed_powerdown_radio)
2568 _rtl92d_phy_restore_rf_env(hw, erfpath, &u4regvalue); 2568 _rtl92d_phy_restore_rf_env(hw, erfpath, &u4regvalue);
diff --git a/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c b/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c
index 5d534df8d90c..f76c50f5ab80 100644
--- a/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c
+++ b/drivers/net/wireless/rtlwifi/rtl8723ae/hal_btc.c
@@ -56,11 +56,11 @@ void rtl8723ae_bt_coex_off_before_lps(struct ieee80211_hw *hw)
56 } 56 }
57} 57}
58 58
59static enum _RT_MEDIA_STATUS mgnt_link_status_query(struct ieee80211_hw *hw) 59static enum rt_media_status mgnt_link_status_query(struct ieee80211_hw *hw)
60{ 60{
61 struct rtl_priv *rtlpriv = rtl_priv(hw); 61 struct rtl_priv *rtlpriv = rtl_priv(hw);
62 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 62 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
63 enum _RT_MEDIA_STATUS m_status = RT_MEDIA_DISCONNECT; 63 enum rt_media_status m_status = RT_MEDIA_DISCONNECT;
64 64
65 u8 bibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? 1 : 0; 65 u8 bibss = (mac->opmode == NL80211_IFTYPE_ADHOC) ? 1 : 0;
66 66
diff --git a/drivers/net/wireless/rtlwifi/wifi.h b/drivers/net/wireless/rtlwifi/wifi.h
index 407a7936d364..541b077ae867 100644
--- a/drivers/net/wireless/rtlwifi/wifi.h
+++ b/drivers/net/wireless/rtlwifi/wifi.h
@@ -170,6 +170,11 @@ enum rf_tx_num {
170 RF_TX_NUM_NONIMPLEMENT, 170 RF_TX_NUM_NONIMPLEMENT,
171}; 171};
172 172
173#define PACKET_NORMAL 0
174#define PACKET_DHCP 1
175#define PACKET_ARP 2
176#define PACKET_EAPOL 3
177
173struct txpower_info_2g { 178struct txpower_info_2g {
174 u8 index_cck_base[MAX_RF_PATH][MAX_CHNL_GROUP_24G]; 179 u8 index_cck_base[MAX_RF_PATH][MAX_CHNL_GROUP_24G];
175 u8 index_bw40_base[MAX_RF_PATH][MAX_CHNL_GROUP_24G]; 180 u8 index_bw40_base[MAX_RF_PATH][MAX_CHNL_GROUP_24G];
@@ -234,8 +239,9 @@ enum hardware_type {
234 HARDWARE_TYPE_RTL8192DU, 239 HARDWARE_TYPE_RTL8192DU,
235 HARDWARE_TYPE_RTL8723AE, 240 HARDWARE_TYPE_RTL8723AE,
236 HARDWARE_TYPE_RTL8723U, 241 HARDWARE_TYPE_RTL8723U,
237 HARDWARE_TYPE_RTL8723BE,
238 HARDWARE_TYPE_RTL8188EE, 242 HARDWARE_TYPE_RTL8188EE,
243 HARDWARE_TYPE_RTL8723BE,
244 HARDWARE_TYPE_RTL8192EE,
239 HARDWARE_TYPE_RTL8821AE, 245 HARDWARE_TYPE_RTL8821AE,
240 HARDWARE_TYPE_RTL8812AE, 246 HARDWARE_TYPE_RTL8812AE,
241 247
@@ -428,7 +434,7 @@ enum hw_variables {
428 HW_VAR_DATA_FILTER, 434 HW_VAR_DATA_FILTER,
429}; 435};
430 436
431enum _RT_MEDIA_STATUS { 437enum rt_media_status {
432 RT_MEDIA_DISCONNECT = 0, 438 RT_MEDIA_DISCONNECT = 0,
433 RT_MEDIA_CONNECT = 1 439 RT_MEDIA_CONNECT = 1
434}; 440};
@@ -2312,10 +2318,11 @@ struct rtl_btc_ops {
2312 void (*btc_init_hal_vars) (struct rtl_priv *rtlpriv); 2318 void (*btc_init_hal_vars) (struct rtl_priv *rtlpriv);
2313 void (*btc_init_hw_config) (struct rtl_priv *rtlpriv); 2319 void (*btc_init_hw_config) (struct rtl_priv *rtlpriv);
2314 void (*btc_ips_notify) (struct rtl_priv *rtlpriv, u8 type); 2320 void (*btc_ips_notify) (struct rtl_priv *rtlpriv, u8 type);
2321 void (*btc_lps_notify)(struct rtl_priv *rtlpriv, u8 type);
2315 void (*btc_scan_notify) (struct rtl_priv *rtlpriv, u8 scantype); 2322 void (*btc_scan_notify) (struct rtl_priv *rtlpriv, u8 scantype);
2316 void (*btc_connect_notify) (struct rtl_priv *rtlpriv, u8 action); 2323 void (*btc_connect_notify) (struct rtl_priv *rtlpriv, u8 action);
2317 void (*btc_mediastatus_notify) (struct rtl_priv *rtlpriv, 2324 void (*btc_mediastatus_notify) (struct rtl_priv *rtlpriv,
2318 enum _RT_MEDIA_STATUS mstatus); 2325 enum rt_media_status mstatus);
2319 void (*btc_periodical) (struct rtl_priv *rtlpriv); 2326 void (*btc_periodical) (struct rtl_priv *rtlpriv);
2320 void (*btc_halt_notify) (void); 2327 void (*btc_halt_notify) (void);
2321 void (*btc_btinfo_notify) (struct rtl_priv *rtlpriv, 2328 void (*btc_btinfo_notify) (struct rtl_priv *rtlpriv,
@@ -2323,6 +2330,8 @@ struct rtl_btc_ops {
2323 bool (*btc_is_limited_dig) (struct rtl_priv *rtlpriv); 2330 bool (*btc_is_limited_dig) (struct rtl_priv *rtlpriv);
2324 bool (*btc_is_disable_edca_turbo) (struct rtl_priv *rtlpriv); 2331 bool (*btc_is_disable_edca_turbo) (struct rtl_priv *rtlpriv);
2325 bool (*btc_is_bt_disabled) (struct rtl_priv *rtlpriv); 2332 bool (*btc_is_bt_disabled) (struct rtl_priv *rtlpriv);
2333 void (*btc_special_packet_notify)(struct rtl_priv *rtlpriv,
2334 u8 pkt_type);
2326}; 2335};
2327 2336
2328struct proxim { 2337struct proxim {