hal_bt_coexist.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  1. /******************************************************************************
  2. *
  3. * Copyright(c) 2009-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. #include "hal_bt_coexist.h"
  26. #include "../pci.h"
  27. #include "dm.h"
  28. #include "fw.h"
  29. #include "phy.h"
  30. #include "reg.h"
  31. #include "hal_btc.h"
  32. static bool bt_operation_on;
  33. void rtl8723e_dm_bt_reject_ap_aggregated_packet(struct ieee80211_hw *hw,
  34. bool b_reject)
  35. {
  36. }
  37. void _rtl8723_dm_bt_check_wifi_state(struct ieee80211_hw *hw)
  38. {
  39. struct rtl_priv *rtlpriv = rtl_priv(hw);
  40. struct rtl_phy *rtlphy = &(rtlpriv->phy);
  41. if (rtlpriv->link_info.busytraffic) {
  42. rtlpriv->btcoexist.cstate &=
  43. ~BT_COEX_STATE_WIFI_IDLE;
  44. if (rtlpriv->link_info.tx_busy_traffic)
  45. rtlpriv->btcoexist.cstate |=
  46. BT_COEX_STATE_WIFI_UPLINK;
  47. else
  48. rtlpriv->btcoexist.cstate &=
  49. ~BT_COEX_STATE_WIFI_UPLINK;
  50. if (rtlpriv->link_info.rx_busy_traffic)
  51. rtlpriv->btcoexist.cstate |=
  52. BT_COEX_STATE_WIFI_DOWNLINK;
  53. else
  54. rtlpriv->btcoexist.cstate &=
  55. ~BT_COEX_STATE_WIFI_DOWNLINK;
  56. } else {
  57. rtlpriv->btcoexist.cstate |= BT_COEX_STATE_WIFI_IDLE;
  58. rtlpriv->btcoexist.cstate &=
  59. ~BT_COEX_STATE_WIFI_UPLINK;
  60. rtlpriv->btcoexist.cstate &=
  61. ~BT_COEX_STATE_WIFI_DOWNLINK;
  62. }
  63. if (rtlpriv->mac80211.mode == WIRELESS_MODE_G ||
  64. rtlpriv->mac80211.mode == WIRELESS_MODE_B) {
  65. rtlpriv->btcoexist.cstate |=
  66. BT_COEX_STATE_WIFI_LEGACY;
  67. rtlpriv->btcoexist.cstate &=
  68. ~BT_COEX_STATE_WIFI_HT20;
  69. rtlpriv->btcoexist.cstate &=
  70. ~BT_COEX_STATE_WIFI_HT40;
  71. } else {
  72. rtlpriv->btcoexist.cstate &=
  73. ~BT_COEX_STATE_WIFI_LEGACY;
  74. if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
  75. rtlpriv->btcoexist.cstate |=
  76. BT_COEX_STATE_WIFI_HT40;
  77. rtlpriv->btcoexist.cstate &=
  78. ~BT_COEX_STATE_WIFI_HT20;
  79. } else {
  80. rtlpriv->btcoexist.cstate |=
  81. BT_COEX_STATE_WIFI_HT20;
  82. rtlpriv->btcoexist.cstate &=
  83. ~BT_COEX_STATE_WIFI_HT40;
  84. }
  85. }
  86. if (bt_operation_on)
  87. rtlpriv->btcoexist.cstate |= BT_COEX_STATE_BT30;
  88. else
  89. rtlpriv->btcoexist.cstate &= ~BT_COEX_STATE_BT30;
  90. }
  91. u8 rtl8723e_dm_bt_check_coex_rssi_state1(struct ieee80211_hw *hw,
  92. u8 level_num, u8 rssi_thresh,
  93. u8 rssi_thresh1)
  94. {
  95. struct rtl_priv *rtlpriv = rtl_priv(hw);
  96. long undecoratedsmoothed_pwdb;
  97. u8 bt_rssi_state = 0;
  98. undecoratedsmoothed_pwdb = rtl8723e_dm_bt_get_rx_ss(hw);
  99. if (level_num == 2) {
  100. rtlpriv->btcoexist.cstate &=
  101. ~BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
  102. if ((rtlpriv->btcoexist.bt_pre_rssi_state ==
  103. BT_RSSI_STATE_LOW) ||
  104. (rtlpriv->btcoexist.bt_pre_rssi_state ==
  105. BT_RSSI_STATE_STAY_LOW)) {
  106. if (undecoratedsmoothed_pwdb >=
  107. (rssi_thresh + BT_FW_COEX_THRESH_TOL)) {
  108. bt_rssi_state = BT_RSSI_STATE_HIGH;
  109. rtlpriv->btcoexist.cstate |=
  110. BT_COEX_STATE_WIFI_RSSI_1_HIGH;
  111. rtlpriv->btcoexist.cstate &=
  112. ~BT_COEX_STATE_WIFI_RSSI_1_LOW;
  113. RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
  114. "[DM][BT], RSSI_1 state switch to High\n");
  115. } else {
  116. bt_rssi_state = BT_RSSI_STATE_STAY_LOW;
  117. RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
  118. "[DM][BT], RSSI_1 state stay at Low\n");
  119. }
  120. } else {
  121. if (undecoratedsmoothed_pwdb < rssi_thresh) {
  122. bt_rssi_state = BT_RSSI_STATE_LOW;
  123. rtlpriv->btcoexist.cstate |=
  124. BT_COEX_STATE_WIFI_RSSI_1_LOW;
  125. rtlpriv->btcoexist.cstate &=
  126. ~BT_COEX_STATE_WIFI_RSSI_1_HIGH;
  127. RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
  128. "[DM][BT], RSSI_1 state switch to Low\n");
  129. } else {
  130. bt_rssi_state = BT_RSSI_STATE_STAY_HIGH;
  131. RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
  132. "[DM][BT], RSSI_1 state stay at High\n");
  133. }
  134. }
  135. } else if (level_num == 3) {
  136. if (rssi_thresh > rssi_thresh1) {
  137. RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
  138. "[DM][BT], RSSI_1 thresh error!!\n");
  139. return rtlpriv->btcoexist.bt_pre_rssi_state;
  140. }
  141. if ((rtlpriv->btcoexist.bt_pre_rssi_state ==
  142. BT_RSSI_STATE_LOW) ||
  143. (rtlpriv->btcoexist.bt_pre_rssi_state ==
  144. BT_RSSI_STATE_STAY_LOW)) {
  145. if (undecoratedsmoothed_pwdb >=
  146. (rssi_thresh+BT_FW_COEX_THRESH_TOL)) {
  147. bt_rssi_state = BT_RSSI_STATE_MEDIUM;
  148. rtlpriv->btcoexist.cstate |=
  149. BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
  150. rtlpriv->btcoexist.cstate &=
  151. ~BT_COEX_STATE_WIFI_RSSI_1_LOW;
  152. rtlpriv->btcoexist.cstate &=
  153. ~BT_COEX_STATE_WIFI_RSSI_1_HIGH;
  154. RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
  155. "[DM][BT], RSSI_1 state switch to Medium\n");
  156. } else {
  157. bt_rssi_state = BT_RSSI_STATE_STAY_LOW;
  158. RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
  159. "[DM][BT], RSSI_1 state stay at Low\n");
  160. }
  161. } else if ((rtlpriv->btcoexist.bt_pre_rssi_state ==
  162. BT_RSSI_STATE_MEDIUM) ||
  163. (rtlpriv->btcoexist.bt_pre_rssi_state ==
  164. BT_RSSI_STATE_STAY_MEDIUM)) {
  165. if (undecoratedsmoothed_pwdb >=
  166. (rssi_thresh1 + BT_FW_COEX_THRESH_TOL)) {
  167. bt_rssi_state = BT_RSSI_STATE_HIGH;
  168. rtlpriv->btcoexist.cstate |=
  169. BT_COEX_STATE_WIFI_RSSI_1_HIGH;
  170. rtlpriv->btcoexist.cstate &=
  171. ~BT_COEX_STATE_WIFI_RSSI_1_LOW;
  172. rtlpriv->btcoexist.cstate &=
  173. ~BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
  174. RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
  175. "[DM][BT], RSSI_1 state switch to High\n");
  176. } else if (undecoratedsmoothed_pwdb < rssi_thresh) {
  177. bt_rssi_state = BT_RSSI_STATE_LOW;
  178. rtlpriv->btcoexist.cstate |=
  179. BT_COEX_STATE_WIFI_RSSI_1_LOW;
  180. rtlpriv->btcoexist.cstate &=
  181. ~BT_COEX_STATE_WIFI_RSSI_1_HIGH;
  182. rtlpriv->btcoexist.cstate &=
  183. ~BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
  184. RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
  185. "[DM][BT], RSSI_1 state switch to Low\n");
  186. } else {
  187. bt_rssi_state = BT_RSSI_STATE_STAY_MEDIUM;
  188. RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
  189. "[DM][BT], RSSI_1 state stay at Medium\n");
  190. }
  191. } else {
  192. if (undecoratedsmoothed_pwdb < rssi_thresh1) {
  193. bt_rssi_state = BT_RSSI_STATE_MEDIUM;
  194. rtlpriv->btcoexist.cstate |=
  195. BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
  196. rtlpriv->btcoexist.cstate &=
  197. ~BT_COEX_STATE_WIFI_RSSI_1_HIGH;
  198. rtlpriv->btcoexist.cstate &=
  199. ~BT_COEX_STATE_WIFI_RSSI_1_LOW;
  200. RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
  201. "[DM][BT], RSSI_1 state switch to Medium\n");
  202. } else {
  203. bt_rssi_state = BT_RSSI_STATE_STAY_HIGH;
  204. RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
  205. "[DM][BT], RSSI_1 state stay at High\n");
  206. }
  207. }
  208. }
  209. rtlpriv->btcoexist.bt_pre_rssi_state1 = bt_rssi_state;
  210. return bt_rssi_state;
  211. }
  212. u8 rtl8723e_dm_bt_check_coex_rssi_state(struct ieee80211_hw *hw,
  213. u8 level_num,
  214. u8 rssi_thresh,
  215. u8 rssi_thresh1)
  216. {
  217. struct rtl_priv *rtlpriv = rtl_priv(hw);
  218. long undecoratedsmoothed_pwdb = 0;
  219. u8 bt_rssi_state = 0;
  220. undecoratedsmoothed_pwdb = rtl8723e_dm_bt_get_rx_ss(hw);
  221. if (level_num == 2) {
  222. rtlpriv->btcoexist.cstate &=
  223. ~BT_COEX_STATE_WIFI_RSSI_MEDIUM;
  224. if ((rtlpriv->btcoexist.bt_pre_rssi_state ==
  225. BT_RSSI_STATE_LOW) ||
  226. (rtlpriv->btcoexist.bt_pre_rssi_state ==
  227. BT_RSSI_STATE_STAY_LOW)) {
  228. if (undecoratedsmoothed_pwdb >=
  229. (rssi_thresh + BT_FW_COEX_THRESH_TOL)) {
  230. bt_rssi_state = BT_RSSI_STATE_HIGH;
  231. rtlpriv->btcoexist.cstate
  232. |= BT_COEX_STATE_WIFI_RSSI_HIGH;
  233. rtlpriv->btcoexist.cstate
  234. &= ~BT_COEX_STATE_WIFI_RSSI_LOW;
  235. RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
  236. "[DM][BT], RSSI state switch to High\n");
  237. } else {
  238. bt_rssi_state = BT_RSSI_STATE_STAY_LOW;
  239. RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
  240. "[DM][BT], RSSI state stay at Low\n");
  241. }
  242. } else {
  243. if (undecoratedsmoothed_pwdb < rssi_thresh) {
  244. bt_rssi_state = BT_RSSI_STATE_LOW;
  245. rtlpriv->btcoexist.cstate
  246. |= BT_COEX_STATE_WIFI_RSSI_LOW;
  247. rtlpriv->btcoexist.cstate
  248. &= ~BT_COEX_STATE_WIFI_RSSI_HIGH;
  249. RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
  250. "[DM][BT], RSSI state switch to Low\n");
  251. } else {
  252. bt_rssi_state = BT_RSSI_STATE_STAY_HIGH;
  253. RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
  254. "[DM][BT], RSSI state stay at High\n");
  255. }
  256. }
  257. } else if (level_num == 3) {
  258. if (rssi_thresh > rssi_thresh1) {
  259. RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
  260. "[DM][BT], RSSI thresh error!!\n");
  261. return rtlpriv->btcoexist.bt_pre_rssi_state;
  262. }
  263. if ((rtlpriv->btcoexist.bt_pre_rssi_state ==
  264. BT_RSSI_STATE_LOW) ||
  265. (rtlpriv->btcoexist.bt_pre_rssi_state ==
  266. BT_RSSI_STATE_STAY_LOW)) {
  267. if (undecoratedsmoothed_pwdb >=
  268. (rssi_thresh + BT_FW_COEX_THRESH_TOL)) {
  269. bt_rssi_state = BT_RSSI_STATE_MEDIUM;
  270. rtlpriv->btcoexist.cstate
  271. |= BT_COEX_STATE_WIFI_RSSI_MEDIUM;
  272. rtlpriv->btcoexist.cstate
  273. &= ~BT_COEX_STATE_WIFI_RSSI_LOW;
  274. rtlpriv->btcoexist.cstate
  275. &= ~BT_COEX_STATE_WIFI_RSSI_HIGH;
  276. RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
  277. "[DM][BT], RSSI state switch to Medium\n");
  278. } else {
  279. bt_rssi_state = BT_RSSI_STATE_STAY_LOW;
  280. RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
  281. "[DM][BT], RSSI state stay at Low\n");
  282. }
  283. } else if ((rtlpriv->btcoexist.bt_pre_rssi_state ==
  284. BT_RSSI_STATE_MEDIUM) ||
  285. (rtlpriv->btcoexist.bt_pre_rssi_state ==
  286. BT_RSSI_STATE_STAY_MEDIUM)) {
  287. if (undecoratedsmoothed_pwdb >=
  288. (rssi_thresh1 + BT_FW_COEX_THRESH_TOL)) {
  289. bt_rssi_state = BT_RSSI_STATE_HIGH;
  290. rtlpriv->btcoexist.cstate
  291. |= BT_COEX_STATE_WIFI_RSSI_HIGH;
  292. rtlpriv->btcoexist.cstate
  293. &= ~BT_COEX_STATE_WIFI_RSSI_LOW;
  294. rtlpriv->btcoexist.cstate
  295. &= ~BT_COEX_STATE_WIFI_RSSI_MEDIUM;
  296. RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
  297. "[DM][BT], RSSI state switch to High\n");
  298. } else if (undecoratedsmoothed_pwdb < rssi_thresh) {
  299. bt_rssi_state = BT_RSSI_STATE_LOW;
  300. rtlpriv->btcoexist.cstate
  301. |= BT_COEX_STATE_WIFI_RSSI_LOW;
  302. rtlpriv->btcoexist.cstate
  303. &= ~BT_COEX_STATE_WIFI_RSSI_HIGH;
  304. rtlpriv->btcoexist.cstate
  305. &= ~BT_COEX_STATE_WIFI_RSSI_MEDIUM;
  306. RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
  307. "[DM][BT], RSSI state switch to Low\n");
  308. } else {
  309. bt_rssi_state = BT_RSSI_STATE_STAY_MEDIUM;
  310. RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
  311. "[DM][BT], RSSI state stay at Medium\n");
  312. }
  313. } else {
  314. if (undecoratedsmoothed_pwdb < rssi_thresh1) {
  315. bt_rssi_state = BT_RSSI_STATE_MEDIUM;
  316. rtlpriv->btcoexist.cstate
  317. |= BT_COEX_STATE_WIFI_RSSI_MEDIUM;
  318. rtlpriv->btcoexist.cstate
  319. &= ~BT_COEX_STATE_WIFI_RSSI_HIGH;
  320. rtlpriv->btcoexist.cstate
  321. &= ~BT_COEX_STATE_WIFI_RSSI_LOW;
  322. RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
  323. "[DM][BT], RSSI state switch to Medium\n");
  324. } else {
  325. bt_rssi_state = BT_RSSI_STATE_STAY_HIGH;
  326. RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
  327. "[DM][BT], RSSI state stay at High\n");
  328. }
  329. }
  330. }
  331. rtlpriv->btcoexist.bt_pre_rssi_state = bt_rssi_state;
  332. return bt_rssi_state;
  333. }
  334. long rtl8723e_dm_bt_get_rx_ss(struct ieee80211_hw *hw)
  335. {
  336. struct rtl_priv *rtlpriv = rtl_priv(hw);
  337. long undecoratedsmoothed_pwdb = 0;
  338. if (rtlpriv->mac80211.link_state >= MAC80211_LINKED) {
  339. undecoratedsmoothed_pwdb =
  340. GET_UNDECORATED_AVERAGE_RSSI(rtlpriv);
  341. } else {
  342. undecoratedsmoothed_pwdb
  343. = rtlpriv->dm.entry_min_undec_sm_pwdb;
  344. }
  345. RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
  346. "rtl8723e_dm_bt_get_rx_ss() = %ld\n",
  347. undecoratedsmoothed_pwdb);
  348. return undecoratedsmoothed_pwdb;
  349. }
  350. void rtl8723e_dm_bt_balance(struct ieee80211_hw *hw,
  351. bool balance_on, u8 ms0, u8 ms1)
  352. {
  353. struct rtl_priv *rtlpriv = rtl_priv(hw);
  354. u8 h2c_parameter[3] = {0};
  355. if (balance_on) {
  356. h2c_parameter[2] = 1;
  357. h2c_parameter[1] = ms1;
  358. h2c_parameter[0] = ms0;
  359. rtlpriv->btcoexist.fw_coexist_all_off = false;
  360. } else {
  361. h2c_parameter[2] = 0;
  362. h2c_parameter[1] = 0;
  363. h2c_parameter[0] = 0;
  364. }
  365. rtlpriv->btcoexist.balance_on = balance_on;
  366. RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
  367. "[DM][BT], Balance=[%s:%dms:%dms], write 0xc=0x%x\n",
  368. balance_on ? "ON" : "OFF", ms0, ms1, h2c_parameter[0]<<16 |
  369. h2c_parameter[1]<<8 | h2c_parameter[2]);
  370. rtl8723e_fill_h2c_cmd(hw, 0xc, 3, h2c_parameter);
  371. }
  372. void rtl8723e_dm_bt_agc_table(struct ieee80211_hw *hw, u8 type)
  373. {
  374. struct rtl_priv *rtlpriv = rtl_priv(hw);
  375. if (type == BT_AGCTABLE_OFF) {
  376. RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
  377. "[BT]AGCTable Off!\n");
  378. rtl_write_dword(rtlpriv, 0xc78, 0x641c0001);
  379. rtl_write_dword(rtlpriv, 0xc78, 0x631d0001);
  380. rtl_write_dword(rtlpriv, 0xc78, 0x621e0001);
  381. rtl_write_dword(rtlpriv, 0xc78, 0x611f0001);
  382. rtl_write_dword(rtlpriv, 0xc78, 0x60200001);
  383. rtl8723e_phy_set_rf_reg(hw, RF90_PATH_A,
  384. RF_RX_AGC_HP, 0xfffff, 0x32000);
  385. rtl8723e_phy_set_rf_reg(hw, RF90_PATH_A,
  386. RF_RX_AGC_HP, 0xfffff, 0x71000);
  387. rtl8723e_phy_set_rf_reg(hw, RF90_PATH_A,
  388. RF_RX_AGC_HP, 0xfffff, 0xb0000);
  389. rtl8723e_phy_set_rf_reg(hw, RF90_PATH_A,
  390. RF_RX_AGC_HP, 0xfffff, 0xfc000);
  391. rtl8723e_phy_set_rf_reg(hw, RF90_PATH_A,
  392. RF_RX_G1, 0xfffff, 0x30355);
  393. } else if (type == BT_AGCTABLE_ON) {
  394. RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
  395. "[BT]AGCTable On!\n");
  396. rtl_write_dword(rtlpriv, 0xc78, 0x4e1c0001);
  397. rtl_write_dword(rtlpriv, 0xc78, 0x4d1d0001);
  398. rtl_write_dword(rtlpriv, 0xc78, 0x4c1e0001);
  399. rtl_write_dword(rtlpriv, 0xc78, 0x4b1f0001);
  400. rtl_write_dword(rtlpriv, 0xc78, 0x4a200001);
  401. rtl8723e_phy_set_rf_reg(hw, RF90_PATH_A,
  402. RF_RX_AGC_HP, 0xfffff, 0xdc000);
  403. rtl8723e_phy_set_rf_reg(hw, RF90_PATH_A,
  404. RF_RX_AGC_HP, 0xfffff, 0x90000);
  405. rtl8723e_phy_set_rf_reg(hw, RF90_PATH_A,
  406. RF_RX_AGC_HP, 0xfffff, 0x51000);
  407. rtl8723e_phy_set_rf_reg(hw, RF90_PATH_A,
  408. RF_RX_AGC_HP, 0xfffff, 0x12000);
  409. rtl8723e_phy_set_rf_reg(hw, RF90_PATH_A,
  410. RF_RX_G1, 0xfffff, 0x00355);
  411. rtlpriv->btcoexist.sw_coexist_all_off = false;
  412. }
  413. }
  414. void rtl8723e_dm_bt_bb_back_off_level(struct ieee80211_hw *hw, u8 type)
  415. {
  416. struct rtl_priv *rtlpriv = rtl_priv(hw);
  417. if (type == BT_BB_BACKOFF_OFF) {
  418. RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
  419. "[BT]BBBackOffLevel Off!\n");
  420. rtl_write_dword(rtlpriv, 0xc04, 0x3a05611);
  421. } else if (type == BT_BB_BACKOFF_ON) {
  422. RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
  423. "[BT]BBBackOffLevel On!\n");
  424. rtl_write_dword(rtlpriv, 0xc04, 0x3a07611);
  425. rtlpriv->btcoexist.sw_coexist_all_off = false;
  426. }
  427. }
  428. void rtl8723e_dm_bt_fw_coex_all_off(struct ieee80211_hw *hw)
  429. {
  430. struct rtl_priv *rtlpriv = rtl_priv(hw);
  431. RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
  432. "rtl8723e_dm_bt_fw_coex_all_off()\n");
  433. if (rtlpriv->btcoexist.fw_coexist_all_off)
  434. return;
  435. RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
  436. "rtl8723e_dm_bt_fw_coex_all_off(), real Do\n");
  437. rtl8723e_dm_bt_fw_coex_all_off_8723a(hw);
  438. rtlpriv->btcoexist.fw_coexist_all_off = true;
  439. }
  440. void rtl8723e_dm_bt_sw_coex_all_off(struct ieee80211_hw *hw)
  441. {
  442. struct rtl_priv *rtlpriv = rtl_priv(hw);
  443. RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
  444. "rtl8723e_dm_bt_sw_coex_all_off()\n");
  445. if (rtlpriv->btcoexist.sw_coexist_all_off)
  446. return;
  447. RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
  448. "rtl8723e_dm_bt_sw_coex_all_off(), real Do\n");
  449. rtl8723e_dm_bt_sw_coex_all_off_8723a(hw);
  450. rtlpriv->btcoexist.sw_coexist_all_off = true;
  451. }
  452. void rtl8723e_dm_bt_hw_coex_all_off(struct ieee80211_hw *hw)
  453. {
  454. struct rtl_priv *rtlpriv = rtl_priv(hw);
  455. RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
  456. "rtl8723e_dm_bt_hw_coex_all_off()\n");
  457. if (rtlpriv->btcoexist.hw_coexist_all_off)
  458. return;
  459. RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
  460. "rtl8723e_dm_bt_hw_coex_all_off(), real Do\n");
  461. rtl8723e_dm_bt_hw_coex_all_off_8723a(hw);
  462. rtlpriv->btcoexist.hw_coexist_all_off = true;
  463. }
  464. void rtl8723e_btdm_coex_all_off(struct ieee80211_hw *hw)
  465. {
  466. rtl8723e_dm_bt_fw_coex_all_off(hw);
  467. rtl8723e_dm_bt_sw_coex_all_off(hw);
  468. rtl8723e_dm_bt_hw_coex_all_off(hw);
  469. }
  470. bool rtl8723e_dm_bt_is_coexist_state_changed(struct ieee80211_hw *hw)
  471. {
  472. struct rtl_priv *rtlpriv = rtl_priv(hw);
  473. if ((rtlpriv->btcoexist.previous_state == rtlpriv->btcoexist.cstate) &&
  474. (rtlpriv->btcoexist.previous_state_h ==
  475. rtlpriv->btcoexist.cstate_h))
  476. return false;
  477. return true;
  478. }
  479. bool rtl8723e_dm_bt_is_wifi_up_link(struct ieee80211_hw *hw)
  480. {
  481. struct rtl_priv *rtlpriv = rtl_priv(hw);
  482. if (rtlpriv->link_info.tx_busy_traffic)
  483. return true;
  484. return false;
  485. }