1 /******************************************************************************
2 *
3 * Copyright(c) 2016 - 2017 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 *****************************************************************************/
15
16 #include "mp_precomp.h"
17
18 #if (BT_SUPPORT == 1 && COEX_SUPPORT == 1)
19
20 #if (RTL8821C_SUPPORT == 1)
21 static u8 *trace_buf = &gl_btc_trace_buf[0];
22
23 const char *const glbt_info_src_8821c_2ant[] = {
24 "BT Info[wifi fw]",
25 "BT Info[bt rsp]",
26 "BT Info[bt auto report]",
27 };
28
29 u32 glcoex_ver_date_8821c_2ant = 20210319;
30 u32 glcoex_ver_8821c_2ant = 0x55;
31 u32 glcoex_ver_btdesired_8821c_2ant = 0x53;
32 u32 glcoex_ver_wldesired_8821c_2ant = 0x170011;
33
34 static
halbtc8821c2ant_bt_rssi_state(struct btc_coexist * btc,u8 * ppre_bt_rssi_state,u8 level_num,u8 rssi_thresh,u8 rssi_thresh1)35 u8 halbtc8821c2ant_bt_rssi_state(struct btc_coexist *btc,
36 u8 *ppre_bt_rssi_state, u8 level_num,
37 u8 rssi_thresh, u8 rssi_thresh1)
38 {
39 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
40 s32 bt_rssi = 0;
41 u8 bt_rssi_state = *ppre_bt_rssi_state;
42
43 bt_rssi = coex_sta->bt_rssi;
44
45 if (level_num == 2) {
46 if ((*ppre_bt_rssi_state == BTC_RSSI_STATE_LOW) ||
47 (*ppre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) {
48 if (bt_rssi >= (rssi_thresh +
49 BTC_RSSI_COEX_THRESH_TOL_8821C_2ANT))
50 bt_rssi_state = BTC_RSSI_STATE_HIGH;
51 else
52 bt_rssi_state = BTC_RSSI_STATE_STAY_LOW;
53 } else {
54 if (bt_rssi < rssi_thresh)
55 bt_rssi_state = BTC_RSSI_STATE_LOW;
56 else
57 bt_rssi_state = BTC_RSSI_STATE_STAY_HIGH;
58 }
59 } else if (level_num == 3) {
60 if (rssi_thresh > rssi_thresh1) {
61 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
62 "[BTCoex], BT Rssi thresh error!!\n");
63 BTC_TRACE(trace_buf);
64 return *ppre_bt_rssi_state;
65 }
66
67 if ((*ppre_bt_rssi_state == BTC_RSSI_STATE_LOW) ||
68 (*ppre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) {
69 if (bt_rssi >= (rssi_thresh +
70 BTC_RSSI_COEX_THRESH_TOL_8821C_2ANT))
71 bt_rssi_state = BTC_RSSI_STATE_MEDIUM;
72 else
73 bt_rssi_state = BTC_RSSI_STATE_STAY_LOW;
74 } else if ((*ppre_bt_rssi_state == BTC_RSSI_STATE_MEDIUM) ||
75 (*ppre_bt_rssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) {
76 if (bt_rssi >= (rssi_thresh1 +
77 BTC_RSSI_COEX_THRESH_TOL_8821C_2ANT))
78 bt_rssi_state = BTC_RSSI_STATE_HIGH;
79 else if (bt_rssi < rssi_thresh)
80 bt_rssi_state = BTC_RSSI_STATE_LOW;
81 else
82 bt_rssi_state = BTC_RSSI_STATE_STAY_MEDIUM;
83 } else {
84 if (bt_rssi < rssi_thresh1)
85 bt_rssi_state = BTC_RSSI_STATE_MEDIUM;
86 else
87 bt_rssi_state = BTC_RSSI_STATE_STAY_HIGH;
88 }
89 }
90
91 *ppre_bt_rssi_state = bt_rssi_state;
92
93 return bt_rssi_state;
94 }
95
96 static
halbtc8821c2ant_wifi_rssi_state(struct btc_coexist * btc,u8 * pprewifi_rssi_state,u8 level_num,u8 rssi_thresh,u8 rssi_thresh1)97 u8 halbtc8821c2ant_wifi_rssi_state(struct btc_coexist *btc,
98 u8 *pprewifi_rssi_state,
99 u8 level_num,
100 u8 rssi_thresh, u8 rssi_thresh1)
101 {
102 s32 wifi_rssi = 0;
103 u8 wifi_rssi_state = *pprewifi_rssi_state;
104
105 btc->btc_get(btc, BTC_GET_S4_WIFI_RSSI, &wifi_rssi);
106
107 if (level_num == 2) {
108 if ((*pprewifi_rssi_state == BTC_RSSI_STATE_LOW) ||
109 (*pprewifi_rssi_state == BTC_RSSI_STATE_STAY_LOW)) {
110 if (wifi_rssi >= (rssi_thresh +
111 BTC_RSSI_COEX_THRESH_TOL_8821C_2ANT))
112 wifi_rssi_state = BTC_RSSI_STATE_HIGH;
113 else
114 wifi_rssi_state = BTC_RSSI_STATE_STAY_LOW;
115 } else {
116 if (wifi_rssi < rssi_thresh)
117 wifi_rssi_state = BTC_RSSI_STATE_LOW;
118 else
119 wifi_rssi_state = BTC_RSSI_STATE_STAY_HIGH;
120 }
121 } else if (level_num == 3) {
122 if (rssi_thresh > rssi_thresh1) {
123 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
124 "[BTCoex], wifi RSSI thresh error!!\n");
125 BTC_TRACE(trace_buf);
126 return *pprewifi_rssi_state;
127 }
128
129 if ((*pprewifi_rssi_state == BTC_RSSI_STATE_LOW) ||
130 (*pprewifi_rssi_state == BTC_RSSI_STATE_STAY_LOW)) {
131 if (wifi_rssi >= (rssi_thresh +
132 BTC_RSSI_COEX_THRESH_TOL_8821C_2ANT))
133 wifi_rssi_state = BTC_RSSI_STATE_MEDIUM;
134 else
135 wifi_rssi_state = BTC_RSSI_STATE_STAY_LOW;
136 } else if ((*pprewifi_rssi_state == BTC_RSSI_STATE_MEDIUM) ||
137 (*pprewifi_rssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) {
138 if (wifi_rssi >= (rssi_thresh1 +
139 BTC_RSSI_COEX_THRESH_TOL_8821C_2ANT))
140 wifi_rssi_state = BTC_RSSI_STATE_HIGH;
141 else if (wifi_rssi < rssi_thresh)
142 wifi_rssi_state = BTC_RSSI_STATE_LOW;
143 else
144 wifi_rssi_state = BTC_RSSI_STATE_STAY_MEDIUM;
145 } else {
146 if (wifi_rssi < rssi_thresh1)
147 wifi_rssi_state = BTC_RSSI_STATE_MEDIUM;
148 else
149 wifi_rssi_state = BTC_RSSI_STATE_STAY_HIGH;
150 }
151 }
152
153 *pprewifi_rssi_state = wifi_rssi_state;
154
155 return wifi_rssi_state;
156 }
157
158 static void
halbtc8821c2ant_limited_tx(struct btc_coexist * btc,boolean force_exec,boolean tx_limit_en,boolean ampdu_limit_en)159 halbtc8821c2ant_limited_tx(struct btc_coexist *btc, boolean force_exec,
160 boolean tx_limit_en, boolean ampdu_limit_en)
161 {
162 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
163 struct wifi_link_info_8821c_2ant *wifi_link_info_ext =
164 &btc->wifi_link_info_8821c_2ant;
165 boolean wifi_under_b_mode = FALSE;
166
167 /* Force Max Tx retry limit = 8*/
168 if (!coex_sta->wl_tx_limit_en) {
169 coex_sta->wl_0x430_backup = btc->btc_read_4byte(btc, 0x430);
170 coex_sta->wl_0x434_backup = btc->btc_read_4byte(btc, 0x434);
171 coex_sta->wl_0x42a_backup = btc->btc_read_2byte(btc, 0x42a);
172 }
173
174 if (!coex_sta->wl_ampdu_limit_en)
175 coex_sta->wl_0x455_backup = btc->btc_read_1byte(btc, 0x455);
176
177 if (!force_exec && tx_limit_en == coex_sta->wl_tx_limit_en &&
178 ampdu_limit_en == coex_sta->wl_ampdu_limit_en)
179 return;
180
181 coex_sta->wl_tx_limit_en = tx_limit_en;
182 coex_sta->wl_ampdu_limit_en = ampdu_limit_en;
183
184 if (tx_limit_en) {
185 /* Set BT polluted packet on for Tx rate adaptive not
186 * including Tx retry break by PTA, 0x45c[19] =1
187 * Set queue life time to avoid can't reach tx retry limit
188 * if tx is always break by GNT_BT.
189 */
190 btc->btc_write_1byte_bitmask(btc, 0x45e, 0x8, 0x1);
191 btc->btc_write_1byte_bitmask(btc, 0x426, 0xf, 0xf);
192
193 /* Max Tx retry limit = 8*/
194 btc->btc_write_2byte(btc, 0x42a, 0x0808);
195
196 btc->btc_get(btc, BTC_GET_BL_WIFI_UNDER_B_MODE,
197 &wifi_under_b_mode);
198
199 /* Auto rate fallback step within 8 retry*/
200 if (wifi_under_b_mode) {
201 btc->btc_write_4byte(btc, 0x430, 0x1000000);
202 btc->btc_write_4byte(btc, 0x434, 0x1010101);
203 } else {
204 btc->btc_write_4byte(btc, 0x430, 0x1000000);
205 btc->btc_write_4byte(btc, 0x434, 0x4030201);
206 }
207 } else {
208 /* Set BT polluted packet on for Tx rate adaptive not
209 *including Tx retry break by PTA, 0x45c[19] =1
210 */
211 btc->btc_write_1byte_bitmask(btc, 0x45e, 0x8, 0x0);
212 btc->btc_write_1byte_bitmask(btc, 0x426, 0xf, 0x0);
213
214 /* Set queue life time to avoid can't reach tx retry limit
215 * if tx is always break by GNT_BT.
216 */
217 if (wifi_link_info_ext->num_of_active_port == 1)
218 btc->btc_write_1byte_bitmask(btc, 0x426, 0xf, 0x0);
219
220 /* Recovery Max Tx retry limit*/
221 btc->btc_write_2byte(btc, 0x42a, coex_sta->wl_0x42a_backup);
222 btc->btc_write_4byte(btc, 0x430, coex_sta->wl_0x430_backup);
223 btc->btc_write_4byte(btc, 0x434, coex_sta->wl_0x434_backup);
224 }
225
226 if (ampdu_limit_en)
227 btc->btc_write_1byte(btc, 0x455, 0x20);
228 else
229 btc->btc_write_1byte(btc, 0x455, coex_sta->wl_0x455_backup);
230 }
231
232 static void
halbtc8821c2ant_limited_rx(struct btc_coexist * btc,boolean force_exec,boolean rej_ap_agg_pkt,boolean bt_ctrl_agg_buf_size,u8 agg_buf_size)233 halbtc8821c2ant_limited_rx(struct btc_coexist *btc, boolean force_exec,
234 boolean rej_ap_agg_pkt, boolean bt_ctrl_agg_buf_size,
235 u8 agg_buf_size)
236 {
237 #if 0
238 struct coex_sta_8822b_2ant *coex_sta = &btc->coex_sta_8822b_2ant;
239 boolean reject_rx_agg = rej_ap_agg_pkt;
240 boolean bt_ctrl_rx_agg_size = bt_ctrl_agg_buf_size;
241 u8 rx_agg_size = agg_buf_size;
242
243 if (!force_exec &&
244 bt_ctrl_agg_buf_size == coex_sta->wl_rxagg_limit_en &&
245 agg_buf_size == coex_sta->wl_rxagg_size)
246 return;
247
248 coex_sta->wl_rxagg_limit_en = bt_ctrl_agg_buf_size;
249 coex_sta->wl_rxagg_size = agg_buf_size;
250
251 /*btc->btc_set(btc, BTC_SET_BL_TO_REJ_AP_AGG_PKT, &reject_rx_agg);*/
252 /* decide BT control aggregation buf size or not */
253 btc->btc_set(btc, BTC_SET_BL_BT_CTRL_AGG_SIZE, &bt_ctrl_rx_agg_size);
254 /* aggregation buf size, only work when BT control Rx aggregation size*/
255 btc->btc_set(btc, BTC_SET_U1_AGG_BUF_SIZE, &rx_agg_size);
256 /* real update aggregation setting */
257 btc->btc_set(btc, BTC_SET_ACT_AGGREGATE_CTRL, NULL);
258 #endif
259 }
260
261 static void
halbtc8821c2ant_ccklock_action(struct btc_coexist * btc)262 halbtc8821c2ant_ccklock_action(struct btc_coexist *btc)
263 {
264 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
265 u8 h2c_parameter[2] = {0};
266 static u8 cnt;
267 boolean wifi_busy = FALSE;
268
269 btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
270
271 if (!coex_sta->gl_wifi_busy ||
272 coex_sta->wl_iot_peer == BTC_IOT_PEER_CISCO) {
273 cnt = 0;
274 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
275 "[BTCoex], wifi is not busy or CISCO AP, return!!\n");
276 BTC_TRACE(trace_buf);
277 return;
278 }
279
280 if (!coex_sta->is_no_wl_5ms_extend && coex_sta->force_lps_ctrl &&
281 !coex_sta->cck_lock_ever) {
282 if (coex_sta->wl_fw_dbg_info[7] <= 5 && wifi_busy)
283 cnt++;
284 else
285 cnt = 0;
286
287 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
288 "[BTCoex], 5ms WL slot extend cnt = %d!!\n", cnt);
289 BTC_TRACE(trace_buf);
290
291 if (cnt == 7) {
292 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
293 "[BTCoex], set h2c 0x69 opcode 12 to turn off 5ms WL slot extend!!\n");
294 BTC_TRACE(trace_buf);
295
296 h2c_parameter[0] = 0xc;
297 h2c_parameter[1] = 0x1;
298 btc->btc_fill_h2c(btc, 0x69, 2, h2c_parameter);
299 coex_sta->is_no_wl_5ms_extend = TRUE;
300 cnt = 0;
301 }
302 } else if (coex_sta->is_no_wl_5ms_extend && coex_sta->cck_lock) {
303 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
304 "[BTCoex], set h2c 0x69 opcode 12 to turn on 5ms WL slot extend!!\n");
305 BTC_TRACE(trace_buf);
306
307 h2c_parameter[0] = 0xc;
308 h2c_parameter[1] = 0x0;
309 btc->btc_fill_h2c(btc, 0x69, 2, h2c_parameter);
310 coex_sta->is_no_wl_5ms_extend = FALSE;
311 }
312 }
313
314 static void
halbtc8821c2ant_ccklock_detect(struct btc_coexist * btc)315 halbtc8821c2ant_ccklock_detect(struct btc_coexist *btc)
316 {
317 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
318 struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant;
319 struct wifi_link_info_8821c_2ant *link_info_ext =
320 &btc->wifi_link_info_8821c_2ant;
321 boolean is_cck_lock_rate = FALSE;
322
323 if (coex_dm->bt_status == BTC_BTSTATUS_INQ_PAGE ||
324 coex_sta->is_setup_link)
325 return;
326
327 if (coex_sta->wl_rx_rate <= BTC_CCK_2 ||
328 coex_sta->wl_rts_rx_rate <= BTC_CCK_2)
329 is_cck_lock_rate = TRUE;
330
331 if (link_info_ext->is_connected && coex_sta->gl_wifi_busy &&
332 (coex_dm->bt_status == BT_8821C_2ANT_BSTATUS_ACL_BUSY ||
333 coex_dm->bt_status == BT_8821C_2ANT_BSTATUS_ACL_SCO_BUSY ||
334 coex_dm->bt_status == BT_8821C_2ANT_BSTATUS_SCO_BUSY)) {
335 if (coex_sta->wl_rx_rate == BTC_CCK_5_5 ||
336 coex_sta->wl_rx_rate == BTC_OFDM_6 ||
337 coex_sta->wl_rx_rate == BTC_MCS_0) {
338 coex_sta->cck_lock_warn = TRUE;
339
340 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
341 "[BTCoex], cck lock warning...\n");
342 BTC_TRACE(trace_buf);
343 } else if ((coex_sta->wl_rx_rate == BTC_CCK_1) ||
344 (coex_sta->wl_rx_rate == BTC_CCK_2) ||
345 (coex_sta->wl_rts_rx_rate == BTC_CCK_1) ||
346 (coex_sta->wl_rts_rx_rate == BTC_CCK_2)) {
347 coex_sta->cck_lock = TRUE;
348
349 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
350 "[BTCoex], cck locking...\n");
351 BTC_TRACE(trace_buf);
352 } else {
353 coex_sta->cck_lock_warn = FALSE;
354 coex_sta->cck_lock = FALSE;
355
356 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
357 "[BTCoex], cck unlock...\n");
358 BTC_TRACE(trace_buf);
359 }
360 } else {
361 coex_sta->cck_lock_warn = FALSE;
362 coex_sta->cck_lock = FALSE;
363 }
364 }
365
366 static void
halbtc8821c2ant_set_tdma_timer_base(struct btc_coexist * btc,u8 type)367 halbtc8821c2ant_set_tdma_timer_base(struct btc_coexist *btc, u8 type)
368 {
369 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
370 u16 tbtt_interval = 100;
371 u8 h2c_para[2] = {0xb, 0x1};
372
373 btc->btc_get(btc, BTC_GET_U2_BEACON_PERIOD, &tbtt_interval);
374
375 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
376 "[BTCoex], tbtt_interval = %d\n", tbtt_interval);
377 BTC_TRACE(trace_buf);
378
379 /* Add for JIRA coex-256 */
380 if (type == 3 && tbtt_interval >= 100) { /* 50ms-slot */
381 if (coex_sta->tdma_timer_base == 3)
382 return;
383
384 h2c_para[1] = (tbtt_interval / 50) - 1;
385 h2c_para[1] = h2c_para[1] | 0xc0; /* 50ms-slot */
386 coex_sta->tdma_timer_base = 3;
387 } else if (tbtt_interval < 80 && tbtt_interval > 0) {
388 if (coex_sta->tdma_timer_base == 2)
389 return;
390 h2c_para[1] = (100 / tbtt_interval);
391
392 if (100 % tbtt_interval != 0)
393 h2c_para[1] = h2c_para[1] + 1;
394
395 h2c_para[1] = h2c_para[1] & 0x3f;
396 coex_sta->tdma_timer_base = 2;
397 } else if (tbtt_interval >= 180) {
398 if (coex_sta->tdma_timer_base == 1)
399 return;
400 h2c_para[1] = (tbtt_interval / 100);
401
402 if (tbtt_interval % 100 <= 80)
403 h2c_para[1] = h2c_para[1] - 1;
404
405 h2c_para[1] = h2c_para[1] & 0x3f;
406 h2c_para[1] = h2c_para[1] | 0x80;
407 coex_sta->tdma_timer_base = 1;
408 } else {
409 if (coex_sta->tdma_timer_base == 0)
410 return;
411 h2c_para[1] = 0x1;
412 coex_sta->tdma_timer_base = 0;
413 }
414
415 btc->btc_fill_h2c(btc, 0x69, 2, h2c_para);
416
417 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
418 "[BTCoex], %s() h2c_0x69 = 0x%x\n", __func__, h2c_para[1]);
419 BTC_TRACE(trace_buf);
420 }
421
422 static
halbtc8821c2ant_coex_switch_thres(struct btc_coexist * btc,u8 isolation_measuared)423 void halbtc8821c2ant_coex_switch_thres(struct btc_coexist *btc,
424 u8 isolation_measuared)
425 {
426 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
427 s8 interference_wl_tx = 0, interference_bt_tx = 0;
428
429 interference_wl_tx = BT_8821C_2ANT_WIFI_MAX_TX_POWER -
430 isolation_measuared;
431 interference_bt_tx = BT_8821C_2ANT_BT_MAX_TX_POWER -
432 isolation_measuared;
433
434 coex_sta->wifi_coex_thres = BT_8821C_2ANT_WIFI_RSSI_COEXSWITCH_THRES1;
435 coex_sta->wifi_coex_thres2 = BT_8821C_2ANT_WIFI_RSSI_COEXSWITCH_THRES2;
436
437 coex_sta->bt_coex_thres = BT_8821C_2ANT_BT_RSSI_COEXSWITCH_THRES1;
438 coex_sta->bt_coex_thres2 = BT_8821C_2ANT_BT_RSSI_COEXSWITCH_THRES2;
439 }
440
441 static
halbtc8821c2ant_low_penalty_ra(struct btc_coexist * btc,boolean force_exec,boolean low_penalty_ra,u8 thres)442 void halbtc8821c2ant_low_penalty_ra(struct btc_coexist *btc,
443 boolean force_exec, boolean low_penalty_ra,
444 u8 thres)
445 {
446 struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant;
447 static u8 cur_thres;
448
449 if (!force_exec) {
450 if (low_penalty_ra == coex_dm->cur_low_penalty_ra &&
451 thres == cur_thres)
452 return;
453 }
454
455 if (low_penalty_ra)
456 btc->btc_phydm_modify_RA_PCR_threshold(btc, 0, thres);
457 else
458 btc->btc_phydm_modify_RA_PCR_threshold(btc, 0, 0);
459
460 coex_dm->cur_low_penalty_ra = low_penalty_ra;
461 cur_thres = thres;
462 }
463
464 static
halbtc8821c2ant_set_antdiv_hwsw(struct btc_coexist * btc,boolean force_exec,boolean is_hw_div)465 void halbtc8821c2ant_set_antdiv_hwsw(struct btc_coexist *btc,
466 boolean force_exec, boolean is_hw_div)
467 {
468 struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant;
469 static u8 pre_antdiv_type;
470
471 coex_dm->cur_antdiv_type = ((is_hw_div) ? 1 : 0);
472
473 if (!force_exec) {
474 if (coex_dm->cur_antdiv_type == pre_antdiv_type)
475 return;
476 }
477
478 btc->btc_phydm_modify_antdiv_hwsw(btc, coex_dm->cur_antdiv_type);
479
480 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
481 "[BTCoex], %s = %d!!\n", __func__,
482 coex_dm->cur_antdiv_type);
483 BTC_TRACE(trace_buf);
484
485 pre_antdiv_type = coex_dm->cur_antdiv_type;
486 }
487
488 static boolean
halbtc8821c2ant_freerun_check(struct btc_coexist * btc)489 halbtc8821c2ant_freerun_check(struct btc_coexist *btc)
490 {
491 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
492 static u8 prewifi_rssi_state = BTC_RSSI_STATE_LOW;
493 static u8 pre_bt_rssi_state = BTC_RSSI_STATE_LOW;
494 u8 wifi_rssi_state, bt_rssi_state;
495
496 wifi_rssi_state =
497 halbtc8821c2ant_wifi_rssi_state(btc, &prewifi_rssi_state, 2,
498 coex_sta->wifi_coex_thres, 0);
499
500 bt_rssi_state =
501 halbtc8821c2ant_bt_rssi_state(btc, &pre_bt_rssi_state, 2,
502 coex_sta->bt_coex_thres, 0);
503
504 if (btc->board_info.ant_distance >= 40)
505 return TRUE;
506
507 if (btc->board_info.ant_distance <= 5)
508 return FALSE;
509
510 /* ant_distance = 5 ~ 40 */
511 if (BTC_RSSI_HIGH(wifi_rssi_state) &&
512 BTC_RSSI_HIGH(bt_rssi_state) && coex_sta->gl_wifi_busy)
513 return TRUE;
514 else
515 return FALSE;
516 }
517
518 static
halbtc8821c2ant_write_scbd(struct btc_coexist * btc,u16 bitpos,boolean state)519 void halbtc8821c2ant_write_scbd(struct btc_coexist *btc, u16 bitpos,
520 boolean state)
521 {
522 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
523 static u16 originalval = 0x8002, preval;
524
525 if (state)
526 originalval = originalval | bitpos;
527 else
528 originalval = originalval & (~bitpos);
529
530 coex_sta->score_board_WB = originalval;
531
532 if (originalval != preval) {
533 preval = originalval;
534 btc->btc_write_2byte(btc, 0xaa, originalval);
535 } else {
536 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
537 "[BTCoex], %s: return for nochange\n", __func__);
538 BTC_TRACE(trace_buf);
539 }
540 }
541
542 static
halbtc8821c2ant_read_scbd(struct btc_coexist * btc,u16 * score_board_val)543 void halbtc8821c2ant_read_scbd(struct btc_coexist *btc, u16 *score_board_val)
544 {
545 *score_board_val = (btc->btc_read_2byte(btc, 0xaa)) & 0x7fff;
546 }
547
548 static
halbtc8821c2ant_query_bt_info(struct btc_coexist * btc)549 void halbtc8821c2ant_query_bt_info(struct btc_coexist *btc)
550 {
551 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
552 u8 h2c_parameter[1] = {0};
553
554 if (coex_sta->bt_disabled) {
555 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
556 "[BTCoex], No query BT info because BT is disabled!\n");
557 BTC_TRACE(trace_buf);
558 return;
559 }
560
561 h2c_parameter[0] |= BIT(0); /* trigger */
562
563 btc->btc_fill_h2c(btc, 0x61, 1, h2c_parameter);
564 }
565
566 static
halbtc8821c2ant_enable_gnt_to_gpio(struct btc_coexist * btc,boolean isenable)567 void halbtc8821c2ant_enable_gnt_to_gpio(struct btc_coexist *btc,
568 boolean isenable)
569 {
570 static u8 bit_val[5] = {0, 0, 0, 0, 0};
571 static boolean state;
572
573 if (!btc->dbg_mode)
574 return;
575
576 if (state == isenable)
577 return;
578
579 state = isenable;
580
581 if (isenable) {
582 /* enable GNT_WL, GNT_BT to GPIO for debug */
583 btc->btc_write_1byte_bitmask(btc, 0x73, 0x8, 0x1);
584
585 /* store original value */
586 /*0x66[4] */
587 bit_val[0] = (btc->btc_read_1byte(btc, 0x66) & BIT(4)) >> 4;
588 /*0x66[8] */
589 bit_val[1] = (btc->btc_read_1byte(btc, 0x67) & BIT(0));
590 /*0x40[19] */
591 bit_val[2] = (btc->btc_read_1byte(btc, 0x42) & BIT(3)) >> 3;
592 /*0x64[15] */
593 bit_val[3] = (btc->btc_read_1byte(btc, 0x65) & BIT(7)) >> 7;
594 /*0x70[18] */
595 bit_val[4] = (btc->btc_read_1byte(btc, 0x72) & BIT(2)) >> 2;
596
597 /* switch GPIO Mux */
598 /*0x66[4] = 0 */
599 btc->btc_write_1byte_bitmask(btc, 0x66, BIT(4), 0x0);
600 /*0x66[8] = 0 */
601 btc->btc_write_1byte_bitmask(btc, 0x67, BIT(0), 0x0);
602 /*0x40[19] = 0 */
603 btc->btc_write_1byte_bitmask(btc, 0x42, BIT(3), 0x0);
604 /*0x64[15] = 0 */
605 btc->btc_write_1byte_bitmask(btc, 0x65, BIT(7), 0x0);
606 /*0x70[18] = 0 */
607 btc->btc_write_1byte_bitmask(btc, 0x72, BIT(2), 0x0);
608 } else {
609 btc->btc_write_1byte_bitmask(btc, 0x73, 0x8, 0x0);
610
611 /* Restore original value */
612 /* switch GPIO Mux */
613 /*0x66[4] = 0 */
614 btc->btc_write_1byte_bitmask(btc, 0x66, BIT(4), bit_val[0]);
615 /*0x66[8] = 0 */
616 btc->btc_write_1byte_bitmask(btc, 0x67, BIT(0), bit_val[1]);
617 /*0x40[19] = 0 */
618 btc->btc_write_1byte_bitmask(btc, 0x42, BIT(3), bit_val[2]);
619 /*0x64[15] = 0 */
620 btc->btc_write_1byte_bitmask(btc, 0x65, BIT(7), bit_val[3]);
621 /*0x70[18] = 0 */
622 btc->btc_write_1byte_bitmask(btc, 0x72, BIT(2), bit_val[4]);
623 }
624 }
625
626 static
halbtc8821c2ant_monitor_bt_ctr(struct btc_coexist * btc)627 boolean halbtc8821c2ant_monitor_bt_ctr(struct btc_coexist *btc)
628 {
629 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
630 struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant;
631 u32 reg_hp_txrx, reg_lp_txrx, u32tmp, cnt_bt_all;
632 u32 reg_hp_tx = 0, reg_hp_rx = 0, reg_lp_tx = 0, reg_lp_rx = 0;
633 static u8 cnt_overhead;
634 static u32 cnt_bt_pre = 0;
635 struct btc_bt_link_info *bt_link_info = &btc->bt_link_info;
636 boolean is_run_coex = FALSE;
637
638 reg_hp_txrx = 0x770;
639 reg_lp_txrx = 0x774;
640
641 u32tmp = btc->btc_read_4byte(btc, reg_hp_txrx);
642 reg_hp_tx = u32tmp & MASKLWORD;
643 reg_hp_rx = (u32tmp & MASKHWORD) >> 16;
644
645 u32tmp = btc->btc_read_4byte(btc, reg_lp_txrx);
646 reg_lp_tx = u32tmp & MASKLWORD;
647 reg_lp_rx = (u32tmp & MASKHWORD) >> 16;
648
649 coex_sta->high_priority_tx = reg_hp_tx;
650 coex_sta->high_priority_rx = reg_hp_rx;
651 coex_sta->low_priority_tx = reg_lp_tx;
652 coex_sta->low_priority_rx = reg_lp_rx;
653
654 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
655 "[BTCoex], Hi-Pri Rx/Tx: %d/%d, Lo-Pri Rx/Tx: %d/%d\n",
656 reg_hp_rx, reg_hp_tx, reg_lp_rx, reg_lp_tx);
657
658 BTC_TRACE(trace_buf);
659
660 /* reset counter */
661 btc->btc_write_1byte(btc, 0x76e, 0xc);
662
663 if (coex_sta->under_lps || coex_sta->under_ips ||
664 (coex_sta->high_priority_tx == 65535 &&
665 coex_sta->high_priority_rx == 65535 &&
666 coex_sta->low_priority_tx == 65535 &&
667 coex_sta->low_priority_rx == 65535))
668 coex_sta->bt_ctr_ok = FALSE;
669 else
670 coex_sta->bt_ctr_ok = TRUE;
671
672 if (!coex_sta->bt_ctr_ok)
673 return FALSE;
674
675 if (coex_dm->bt_status == BT_8821C_2ANT_BSTATUS_NCON_IDLE) {
676 if (coex_sta->high_priority_rx >= 15) {
677 if (cnt_overhead < 3)
678 cnt_overhead++;
679 if (cnt_overhead == 3)
680 coex_sta->is_hi_pri_rx_overhead = TRUE;
681 } else {
682 if (cnt_overhead > 0)
683 cnt_overhead--;
684 if (cnt_overhead == 0)
685 coex_sta->is_hi_pri_rx_overhead = FALSE;
686 }
687 } else {
688 coex_sta->is_hi_pri_rx_overhead = FALSE;
689 }
690
691 if (coex_sta->low_priority_tx > 1150 &&
692 !coex_sta->c2h_bt_inquiry_page)
693 coex_sta->pop_event_cnt++;
694
695 if (coex_sta->sco_exist) {
696 if (coex_sta->high_priority_tx >= 400 &&
697 coex_sta->high_priority_rx >= 400)
698 coex_sta->is_esco_mode = FALSE;
699 else
700 coex_sta->is_esco_mode = TRUE;
701 }
702
703 if (bt_link_info->hid_only) {
704 if (coex_sta->low_priority_tx > 100)
705 coex_sta->is_hid_low_pri_tx_overhead = true;
706 else
707 coex_sta->is_hid_low_pri_tx_overhead = false;
708 }
709
710 cnt_bt_all = coex_sta->high_priority_tx +
711 coex_sta->high_priority_rx +
712 coex_sta->low_priority_tx +
713 coex_sta->low_priority_rx;
714
715 if ((cnt_bt_pre > (cnt_bt_all + 50) ||
716 cnt_bt_all > (cnt_bt_pre + 50)) &&
717 coex_dm->bt_status == BT_8821C_2ANT_BSTATUS_NCON_IDLE)
718 is_run_coex = TRUE;
719
720 cnt_bt_pre = cnt_bt_all;
721
722 return is_run_coex;
723 }
724
725 static
halbtc8821c2ant_monitor_wifi_ctr(struct btc_coexist * btc)726 void halbtc8821c2ant_monitor_wifi_ctr(struct btc_coexist *btc)
727 {
728 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
729 struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant;
730 boolean wifi_busy = FALSE, wifi_scan = FALSE;
731 static u8 wl_noisy_count0, wl_noisy_count1 = 3, wl_noisy_count2;
732 u32 cnt_cck, fw_ver = 0;
733 static u8 cnt_ccklocking;
734 u8 h2c_parameter[1] = {0};
735
736 btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
737 btc->btc_get(btc, BTC_GET_BL_WIFI_SCAN, &wifi_scan);
738 btc->btc_get(btc, BTC_GET_U4_WIFI_FW_VER, &fw_ver);
739
740 /* Only enable for windows in old fw version (COEX-308)
741 * because 8821cu H2C 0x69 unknown fail @ linux
742 */
743 if (btc->chip_interface != BTC_INTF_USB ||
744 (fw_ver < 0x170000 && fw_ver < 0x17000c) ||
745 (fw_ver < 0x180000 && fw_ver < 0x180009) ||
746 (fw_ver < 0x190000 && fw_ver < 0x190002)) {
747 /*send h2c to query WL FW dbg info */
748 if (coex_dm->cur_ps_tdma_on) {
749 h2c_parameter[0] = 0x8;
750 btc->btc_fill_h2c(btc, 0x69, 1, h2c_parameter);
751 }
752 }
753
754 coex_sta->crc_ok_cck =
755 btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_CRC32_OK_CCK);
756 coex_sta->crc_ok_11g =
757 btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_CRC32_OK_LEGACY);
758 coex_sta->crc_ok_11n =
759 btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_CRC32_OK_HT);
760 coex_sta->crc_ok_11n_vht =
761 btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_CRC32_OK_VHT);
762
763 coex_sta->crc_err_cck =
764 btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_CRC32_ERROR_CCK);
765 coex_sta->crc_err_11g =
766 btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_CRC32_ERROR_LEGACY);
767 coex_sta->crc_err_11n =
768 btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_CRC32_ERROR_HT);
769 coex_sta->crc_err_11n_vht =
770 btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_CRC32_ERROR_VHT);
771
772 /* CCK lock identification */
773 if (coex_sta->cck_lock)
774 cnt_ccklocking++;
775 else if (cnt_ccklocking != 0)
776 cnt_ccklocking--;
777
778 if (cnt_ccklocking >= 3) {
779 cnt_ccklocking = 3;
780 coex_sta->cck_lock_ever = TRUE;
781 }
782
783 /* WiFi environment noisy identification */
784 cnt_cck = coex_sta->crc_ok_cck + coex_sta->crc_err_cck;
785
786 if (!wifi_busy && !coex_sta->cck_lock) {
787 if (cnt_cck > 250) {
788 if (wl_noisy_count2 < 3)
789 wl_noisy_count2++;
790
791 if (wl_noisy_count2 == 3) {
792 wl_noisy_count0 = 0;
793 wl_noisy_count1 = 0;
794 }
795
796 } else if (cnt_cck < 100) {
797 if (wl_noisy_count0 < 3)
798 wl_noisy_count0++;
799
800 if (wl_noisy_count0 == 3) {
801 wl_noisy_count1 = 0;
802 wl_noisy_count2 = 0;
803 }
804
805 } else {
806 if (wl_noisy_count1 < 3)
807 wl_noisy_count1++;
808
809 if (wl_noisy_count1 == 3) {
810 wl_noisy_count0 = 0;
811 wl_noisy_count2 = 0;
812 }
813 }
814
815 if (wl_noisy_count2 == 3)
816 coex_sta->wl_noisy_level = 2;
817 else if (wl_noisy_count1 == 3)
818 coex_sta->wl_noisy_level = 1;
819 else
820 coex_sta->wl_noisy_level = 0;
821 }
822 }
823
824 static
halbtc8821c2ant_monitor_bt_enable(struct btc_coexist * btc)825 void halbtc8821c2ant_monitor_bt_enable(struct btc_coexist *btc)
826 {
827 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
828 static u32 bt_disable_cnt;
829 boolean bt_active = TRUE, bt_disabled = FALSE;
830 u16 u16tmp;
831
832 /* Read BT on/off status from scoreboard[1],
833 * enable this only if BT patch support this feature
834 */
835 halbtc8821c2ant_read_scbd(btc, &u16tmp);
836
837 bt_active = u16tmp & BIT(1);
838
839 if (bt_active) {
840 bt_disable_cnt = 0;
841 bt_disabled = FALSE;
842 btc->btc_set(btc, BTC_SET_BL_BT_DISABLE, &bt_disabled);
843 } else {
844 bt_disable_cnt++;
845 if (bt_disable_cnt >= 2) {
846 bt_disabled = TRUE;
847 bt_disable_cnt = 2;
848 }
849
850 btc->btc_set(btc, BTC_SET_BL_BT_DISABLE, &bt_disabled);
851 }
852
853 if (coex_sta->bt_disabled != bt_disabled) {
854 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
855 "[BTCoex], BT is from %s to %s!!\n",
856 (coex_sta->bt_disabled ? "disabled" : "enabled"),
857 (bt_disabled ? "disabled" : "enabled"));
858 BTC_TRACE(trace_buf);
859 coex_sta->bt_disabled = bt_disabled;
860
861 /*for win10 BT disable->enable trigger wifi scan issue */
862 if (!coex_sta->bt_disabled) {
863 coex_sta->is_bt_reenable = TRUE;
864 coex_sta->cnt_bt_reenable = 15;
865 } else {
866 coex_sta->is_bt_reenable = FALSE;
867 coex_sta->cnt_bt_reenable = 0;
868 }
869 }
870 }
871
872 static
halbtc8821c2ant_moniter_wifibt_status(struct btc_coexist * btc)873 boolean halbtc8821c2ant_moniter_wifibt_status(struct btc_coexist
874 *btc)
875 {
876 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
877 struct wifi_link_info_8821c_2ant *wifi_link_info_ext =
878 &btc->wifi_link_info_8821c_2ant;
879 static boolean pre_wifi_busy, pre_under_4way,
880 pre_bt_off, pre_bt_slave, pre_hid_low_pri_tx_overhead,
881 pre_wifi_under_lps, pre_bt_setup_link,
882 pre_cck_lock, pre_cck_lock_warn;
883 static u8 pre_hid_busy_num, pre_wl_noisy_level;
884 boolean wifi_busy = FALSE, under_4way = FALSE;
885 boolean wifi_connected = FALSE;
886 struct btc_bt_link_info *bt_link_info = &btc->bt_link_info;
887 static u8 cnt_wifi_busytoidle;
888 u32 num_of_wifi_link = 0, wifi_link_mode = 0;
889 static u32 pre_num_of_wifi_link, pre_wifi_link_mode;
890 boolean miracast_plus_bt = FALSE;
891
892 btc->btc_get(btc, BTC_GET_BL_WIFI_CONNECTED, &wifi_connected);
893 btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
894 btc->btc_get(btc, BTC_GET_BL_WIFI_4_WAY_PROGRESS, &under_4way);
895
896 if (wifi_busy) {
897 coex_sta->gl_wifi_busy = TRUE;
898 cnt_wifi_busytoidle = 6;
899 } else {
900 if (coex_sta->gl_wifi_busy && cnt_wifi_busytoidle > 0)
901 cnt_wifi_busytoidle--;
902 else if (cnt_wifi_busytoidle == 0)
903 coex_sta->gl_wifi_busy = FALSE;
904 }
905
906 if (coex_sta->bt_disabled != pre_bt_off) {
907 pre_bt_off = coex_sta->bt_disabled;
908
909 if (coex_sta->bt_disabled)
910 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
911 "[BTCoex], BT is disabled !!\n");
912 else
913 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
914 "[BTCoex], BT is enabled !!\n");
915
916 BTC_TRACE(trace_buf);
917
918 coex_sta->bt_coex_supported_feature = 0;
919 coex_sta->bt_coex_supported_version = 0;
920 coex_sta->bt_ble_scan_type = 0;
921 coex_sta->bt_ble_scan_para[0] = 0;
922 coex_sta->bt_ble_scan_para[1] = 0;
923 coex_sta->bt_ble_scan_para[2] = 0;
924 coex_sta->bt_reg_vendor_ac = 0xffff;
925 coex_sta->bt_reg_vendor_ae = 0xffff;
926 coex_sta->bt_a2dp_vendor_id = 0;
927 coex_sta->bt_a2dp_device_name = 0;
928 btc->bt_info.bt_get_fw_ver = 0;
929 return TRUE;
930 }
931
932 num_of_wifi_link = wifi_link_info_ext->num_of_active_port;
933
934 if (num_of_wifi_link != pre_num_of_wifi_link) {
935 pre_num_of_wifi_link = num_of_wifi_link;
936
937 if (wifi_link_info_ext->is_p2p_connected) {
938 if (bt_link_info->bt_link_exist)
939 miracast_plus_bt = TRUE;
940 else
941 miracast_plus_bt = FALSE;
942
943 btc->btc_set(btc, BTC_SET_BL_MIRACAST_PLUS_BT,
944 &miracast_plus_bt);
945 }
946 return TRUE;
947 }
948
949 wifi_link_mode = btc->wifi_link_info.link_mode;
950 if (wifi_link_mode != pre_wifi_link_mode) {
951 pre_wifi_link_mode = wifi_link_mode;
952 return TRUE;
953 }
954
955 if (wifi_connected) {
956 if (wifi_busy != pre_wifi_busy) {
957 pre_wifi_busy = wifi_busy;
958 return TRUE;
959 }
960 if (under_4way != pre_under_4way) {
961 pre_under_4way = under_4way;
962 return TRUE;
963 }
964
965 if (coex_sta->wl_noisy_level != pre_wl_noisy_level) {
966 pre_wl_noisy_level = coex_sta->wl_noisy_level;
967 return TRUE;
968 }
969 if (coex_sta->under_lps != pre_wifi_under_lps) {
970 pre_wifi_under_lps = coex_sta->under_lps;
971 if (coex_sta->under_lps)
972 return TRUE;
973 }
974 if (coex_sta->cck_lock != pre_cck_lock) {
975 pre_cck_lock = coex_sta->cck_lock;
976 return TRUE;
977 }
978 if (coex_sta->cck_lock_warn != pre_cck_lock_warn) {
979 pre_cck_lock_warn = coex_sta->cck_lock_warn;
980 return TRUE;
981 }
982 }
983
984 if (!coex_sta->bt_disabled) {
985 #if 0
986 if (coex_sta->acl_busy != pre_bt_acl_busy) {
987 pre_bt_acl_busy = coex_sta->acl_busy;
988 btc->btc_set(btc, BTC_SET_BL_BT_LNA_CONSTRAIN_LEVEL,
989 &lna_lvl);
990 return TRUE;
991 }
992 #endif
993 if (coex_sta->hid_busy_num != pre_hid_busy_num) {
994 pre_hid_busy_num = coex_sta->hid_busy_num;
995 return TRUE;
996 }
997
998 if (bt_link_info->slave_role != pre_bt_slave) {
999 pre_bt_slave = bt_link_info->slave_role;
1000 return TRUE;
1001 }
1002
1003 if (pre_hid_low_pri_tx_overhead !=
1004 coex_sta->is_hid_low_pri_tx_overhead) {
1005 pre_hid_low_pri_tx_overhead =
1006 coex_sta->is_hid_low_pri_tx_overhead;
1007 return TRUE;
1008 }
1009
1010 if (pre_bt_setup_link != coex_sta->is_setup_link) {
1011 pre_bt_setup_link = coex_sta->is_setup_link;
1012 return TRUE;
1013 }
1014 }
1015
1016 return FALSE;
1017 }
1018
1019 static
halbtc8821c2ant_update_wifi_link_info(struct btc_coexist * btc,u8 reason)1020 void halbtc8821c2ant_update_wifi_link_info(struct btc_coexist *btc, u8 reason)
1021 {
1022 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
1023 struct wifi_link_info_8821c_2ant *wifi_link_info_ext =
1024 &btc->wifi_link_info_8821c_2ant;
1025 struct btc_wifi_link_info wifi_link_info;
1026 struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant;
1027 u8 wifi_central_chnl = 0, num_of_wifi_link = 0;
1028 boolean isunder5G = FALSE, ismcc25g = FALSE, isp2pconnected = FALSE;
1029 u32 wifi_link_status = 0;
1030
1031 btc->btc_get(btc, BTC_GET_BL_WIFI_CONNECTED,
1032 &wifi_link_info_ext->is_connected);
1033
1034 btc->btc_get(btc, BTC_GET_U4_WIFI_LINK_STATUS, &wifi_link_status);
1035 wifi_link_info_ext->port_connect_status = wifi_link_status & 0xffff;
1036
1037 btc->btc_get(btc, BTC_GET_BL_WIFI_LINK_INFO, &wifi_link_info);
1038 btc->wifi_link_info = wifi_link_info;
1039
1040 btc->btc_get(btc, BTC_GET_U1_WIFI_CENTRAL_CHNL, &wifi_central_chnl);
1041 coex_sta->wl_center_channel = wifi_central_chnl;
1042
1043 /* Check scan/connect/special-pkt action first */
1044 switch (reason) {
1045 case BT_8821C_2ANT_RSN_5GSCANSTART:
1046 case BT_8821C_2ANT_RSN_5GSWITCHBAND:
1047 case BT_8821C_2ANT_RSN_5GCONSTART:
1048 isunder5G = TRUE;
1049 break;
1050 case BT_8821C_2ANT_RSN_2GSCANSTART:
1051 case BT_8821C_2ANT_RSN_2GSWITCHBAND:
1052 case BT_8821C_2ANT_RSN_2GCONSTART:
1053 isunder5G = FALSE;
1054 break;
1055 case BT_8821C_2ANT_RSN_2GCONFINISH:
1056 case BT_8821C_2ANT_RSN_5GCONFINISH:
1057 case BT_8821C_2ANT_RSN_2GMEDIA:
1058 case BT_8821C_2ANT_RSN_5GMEDIA:
1059 case BT_8821C_2ANT_RSN_BTINFO:
1060 case BT_8821C_2ANT_RSN_PERIODICAL:
1061 case BT_8821C_2ANT_RSN_2GSPECIALPKT:
1062 case BT_8821C_2ANT_RSN_5GSPECIALPKT:
1063 default:
1064 switch (wifi_link_info.link_mode) {
1065 case BTC_LINK_5G_MCC_GO_STA:
1066 case BTC_LINK_5G_MCC_GC_STA:
1067 case BTC_LINK_5G_SCC_GO_STA:
1068 case BTC_LINK_5G_SCC_GC_STA:
1069 isunder5G = TRUE;
1070 break;
1071 case BTC_LINK_2G_MCC_GO_STA:
1072 case BTC_LINK_2G_MCC_GC_STA:
1073 case BTC_LINK_2G_SCC_GO_STA:
1074 case BTC_LINK_2G_SCC_GC_STA:
1075 isunder5G = FALSE;
1076 break;
1077 case BTC_LINK_25G_MCC_GO_STA:
1078 case BTC_LINK_25G_MCC_GC_STA:
1079 isunder5G = FALSE;
1080 ismcc25g = TRUE;
1081 break;
1082 case BTC_LINK_ONLY_STA:
1083 if (wifi_link_info.sta_center_channel > 14)
1084 isunder5G = TRUE;
1085 else
1086 isunder5G = FALSE;
1087 break;
1088 case BTC_LINK_ONLY_GO:
1089 case BTC_LINK_ONLY_GC:
1090 case BTC_LINK_ONLY_AP:
1091 default:
1092 if (wifi_link_info.p2p_center_channel > 14)
1093 isunder5G = TRUE;
1094 else
1095 isunder5G = FALSE;
1096
1097 break;
1098 }
1099 break;
1100 }
1101
1102 wifi_link_info_ext->is_all_under_5g = isunder5G;
1103 wifi_link_info_ext->is_mcc_25g = ismcc25g;
1104
1105 if (wifi_link_status & WIFI_STA_CONNECTED)
1106 num_of_wifi_link++;
1107
1108 if (wifi_link_status & WIFI_AP_CONNECTED)
1109 num_of_wifi_link++;
1110
1111 if (wifi_link_status & WIFI_P2P_GO_CONNECTED) {
1112 num_of_wifi_link++;
1113 isp2pconnected = TRUE;
1114 }
1115
1116 if (wifi_link_status & WIFI_P2P_GC_CONNECTED) {
1117 num_of_wifi_link++;
1118 isp2pconnected = TRUE;
1119 }
1120
1121 wifi_link_info_ext->num_of_active_port = num_of_wifi_link;
1122 wifi_link_info_ext->is_p2p_connected = isp2pconnected;
1123
1124 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
1125 "[BTCoex], wifi_link_info: link_mode=%d, STA_Ch=%d, P2P_Ch=%d, AnyClient_Join_Go=%d !\n",
1126 btc->wifi_link_info.link_mode,
1127 btc->wifi_link_info.sta_center_channel,
1128 btc->wifi_link_info.p2p_center_channel,
1129 btc->wifi_link_info.bany_client_join_go);
1130 BTC_TRACE(trace_buf);
1131
1132 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
1133 "[BTCoex], wifi_link_info: center_ch=%d, is_all_under_5g=%d, is_mcc_25g=%d!\n",
1134 coex_sta->wl_center_channel,
1135 wifi_link_info_ext->is_all_under_5g,
1136 wifi_link_info_ext->is_mcc_25g);
1137 BTC_TRACE(trace_buf);
1138
1139 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
1140 "[BTCoex], wifi_link_info: port_connect_status=0x%x, active_port_cnt=%d, P2P_Connect=%d!\n",
1141 wifi_link_info_ext->port_connect_status,
1142 wifi_link_info_ext->num_of_active_port,
1143 wifi_link_info_ext->is_p2p_connected);
1144 BTC_TRACE(trace_buf);
1145
1146 switch (reason) {
1147 case BT_8821C_2ANT_RSN_2GSCANSTART:
1148 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
1149 "[BTCoex], Update reason = %s\n", "2GSCANSTART");
1150 break;
1151 case BT_8821C_2ANT_RSN_5GSCANSTART:
1152 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
1153 "[BTCoex], Update reason = %s\n", "5GSCANSTART");
1154 break;
1155 case BT_8821C_2ANT_RSN_SCANFINISH:
1156 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
1157 "[BTCoex], Update reason = %s\n", "SCANFINISH");
1158 break;
1159 case BT_8821C_2ANT_RSN_2GSWITCHBAND:
1160 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
1161 "[BTCoex], Update reason = %s\n", "2GSWITCHBAND");
1162 break;
1163 case BT_8821C_2ANT_RSN_5GSWITCHBAND:
1164 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
1165 "[BTCoex], Update reason = %s\n", "5GSWITCHBAND");
1166 break;
1167 case BT_8821C_2ANT_RSN_2GCONSTART:
1168 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
1169 "[BTCoex], Update reason = %s\n", "2GCONNECTSTART");
1170 break;
1171 case BT_8821C_2ANT_RSN_5GCONSTART:
1172 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
1173 "[BTCoex], Update reason = %s\n", "5GCONNECTSTART");
1174 break;
1175 case BT_8821C_2ANT_RSN_2GCONFINISH:
1176 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
1177 "[BTCoex], Update reason = %s\n",
1178 "2GCONNECTFINISH");
1179 break;
1180 case BT_8821C_2ANT_RSN_5GCONFINISH:
1181 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
1182 "[BTCoex], Update reason = %s\n",
1183 "5GCONNECTFINISH");
1184 break;
1185 case BT_8821C_2ANT_RSN_2GMEDIA:
1186 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
1187 "[BTCoex], Update reason = %s\n", "2GMEDIASTATUS");
1188 break;
1189 case BT_8821C_2ANT_RSN_5GMEDIA:
1190 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
1191 "[BTCoex], Update reason = %s\n", "5GMEDIASTATUS");
1192 break;
1193 case BT_8821C_2ANT_RSN_MEDIADISCON:
1194 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
1195 "[BTCoex], Update reason = %s\n",
1196 "MEDIADISCONNECT");
1197 break;
1198 case BT_8821C_2ANT_RSN_2GSPECIALPKT:
1199 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
1200 "[BTCoex], Update reason = %s\n", "2GSPECIALPKT");
1201 break;
1202 case BT_8821C_2ANT_RSN_5GSPECIALPKT:
1203 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
1204 "[BTCoex], Update reason = %s\n", "5GSPECIALPKT");
1205 break;
1206 case BT_8821C_2ANT_RSN_BTINFO:
1207 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
1208 "[BTCoex], Update reason = %s\n", "BTINFO");
1209 break;
1210 case BT_8821C_2ANT_RSN_PERIODICAL:
1211 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
1212 "[BTCoex], Update reason = %s\n", "PERIODICAL");
1213 break;
1214 case BT_8821C_2ANT_RSN_PNP:
1215 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
1216 "[BTCoex], Update reason = %s\n", "PNPNotify");
1217 break;
1218 default:
1219 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
1220 "[BTCoex], Update reason = %s\n", "UNKNOWN");
1221 break;
1222 }
1223
1224 BTC_TRACE(trace_buf);
1225
1226 if (btc->manual_control || btc->stop_coex_dm)
1227 return;
1228
1229 if (wifi_link_info_ext->is_all_under_5g || num_of_wifi_link == 0 ||
1230 coex_dm->bt_status == BT_8821C_2ANT_BSTATUS_NCON_IDLE) {
1231 halbtc8821c2ant_low_penalty_ra(btc, NM_EXCU, FALSE, 0);
1232 halbtc8821c2ant_limited_tx(btc, NM_EXCU, FALSE, FALSE);
1233 halbtc8821c2ant_limited_rx(btc, NM_EXCU, FALSE, TRUE, 64);
1234 } else if (wifi_link_info_ext->num_of_active_port > 1) {
1235 halbtc8821c2ant_low_penalty_ra(btc, NM_EXCU, TRUE, 30);
1236 halbtc8821c2ant_limited_tx(btc, NM_EXCU, FALSE, TRUE);
1237 halbtc8821c2ant_limited_rx(btc, NM_EXCU, FALSE, TRUE, 16);
1238 } else {
1239 halbtc8821c2ant_low_penalty_ra(btc, NM_EXCU, TRUE, 15);
1240
1241 if (coex_sta->hid_exist || coex_sta->hid_pair_cnt > 0 ||
1242 coex_sta->sco_exist) {
1243 halbtc8821c2ant_limited_tx(btc, NM_EXCU, TRUE, TRUE);
1244 halbtc8821c2ant_limited_rx(btc, NM_EXCU, FALSE, TRUE,
1245 16);
1246 } else {
1247 halbtc8821c2ant_limited_tx(btc, NM_EXCU, TRUE, FALSE);
1248 halbtc8821c2ant_limited_rx(btc, NM_EXCU, FALSE, TRUE,
1249 64);
1250 }
1251 }
1252
1253 /* coex-276 P2P-Go beacon request can't release issue
1254 * Only PCIe/USB can set 0x454[6] = 1 to solve this issue,
1255 * WL SDIO/USB interface need driver support.
1256 */
1257 #ifdef PLATFORM_WINDOWS
1258 if (btc->chip_interface != BTC_INTF_SDIO)
1259 btc->btc_write_1byte_bitmask(btc, 0x454, BIT(6), 0x1);
1260 else
1261 btc->btc_write_1byte_bitmask(btc, 0x454, BIT(6), 0x0);
1262 #endif
1263 }
1264
1265 static
halbtc8821c2ant_update_bt_link_info(struct btc_coexist * btc)1266 void halbtc8821c2ant_update_bt_link_info(struct btc_coexist *btc)
1267 {
1268 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
1269 struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant;
1270 struct btc_bt_link_info *bt_link_info = &btc->bt_link_info;
1271 boolean bt_busy = FALSE, increase_scan_dev_num = FALSE;
1272 u32 val = 0;
1273 static u8 pre_num_of_profile, cur_num_of_profile, cnt, ble_cnt;
1274
1275 if (++ble_cnt >= 3)
1276 ble_cnt = 0;
1277
1278 if (coex_sta->is_ble_scan_en && ble_cnt == 0) {
1279 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
1280 "[BTCoex], BT ext info bit4 check, query BLE Scan type!!\n");
1281 BTC_TRACE(trace_buf);
1282 coex_sta->bt_ble_scan_type =
1283 btc->btc_get_ble_scan_type_from_bt(btc);
1284
1285 if ((coex_sta->bt_ble_scan_type & 0x1) == 0x1)
1286 coex_sta->bt_ble_scan_para[0] =
1287 btc->btc_get_ble_scan_para_from_bt(btc, 0x1);
1288 if ((coex_sta->bt_ble_scan_type & 0x2) == 0x2)
1289 coex_sta->bt_ble_scan_para[1] =
1290 btc->btc_get_ble_scan_para_from_bt(btc, 0x2);
1291 if ((coex_sta->bt_ble_scan_type & 0x4) == 0x4)
1292 coex_sta->bt_ble_scan_para[2] =
1293 btc->btc_get_ble_scan_para_from_bt(btc, 0x4);
1294 }
1295
1296 coex_sta->num_of_profile = 0;
1297
1298 /* set link exist status */
1299 if (!(coex_sta->bt_info_lb2 & BT_INFO_8821C_2ANT_B_CONNECTION)) {
1300 coex_sta->bt_link_exist = FALSE;
1301 coex_sta->pan_exist = FALSE;
1302 coex_sta->a2dp_exist = FALSE;
1303 coex_sta->hid_exist = FALSE;
1304 coex_sta->sco_exist = FALSE;
1305 coex_sta->msft_mr_exist = FALSE;
1306 } else { /* connection exists */
1307 coex_sta->bt_link_exist = TRUE;
1308 if (coex_sta->bt_info_lb2 & BT_INFO_8821C_2ANT_B_FTP) {
1309 coex_sta->pan_exist = TRUE;
1310 coex_sta->num_of_profile++;
1311 } else {
1312 coex_sta->pan_exist = FALSE;
1313 }
1314
1315 if (coex_sta->bt_info_lb2 & BT_INFO_8821C_2ANT_B_A2DP) {
1316 coex_sta->a2dp_exist = TRUE;
1317 coex_sta->num_of_profile++;
1318 } else {
1319 coex_sta->a2dp_exist = FALSE;
1320 }
1321
1322 if (coex_sta->bt_info_lb2 & BT_INFO_8821C_2ANT_B_HID) {
1323 coex_sta->hid_exist = TRUE;
1324 coex_sta->num_of_profile++;
1325 } else {
1326 coex_sta->hid_exist = FALSE;
1327 }
1328
1329 if (coex_sta->bt_info_lb2 & BT_INFO_8821C_2ANT_B_SCO_ESCO) {
1330 coex_sta->sco_exist = TRUE;
1331 coex_sta->num_of_profile++;
1332 } else {
1333 coex_sta->sco_exist = FALSE;
1334 }
1335 #if 0
1336 if (coex_sta->hid_busy_num == 0 &&
1337 coex_sta->hid_pair_cnt > 0 &&
1338 coex_sta->low_priority_tx > 1000 &&
1339 coex_sta->low_priority_rx > 1000 &&
1340 !coex_sta->c2h_bt_inquiry_page)
1341 coex_sta->msft_mr_exist = true;
1342 else
1343 coex_sta->msft_mr_exist = false;
1344 #endif
1345 }
1346
1347 bt_link_info->bt_link_exist = coex_sta->bt_link_exist;
1348 bt_link_info->sco_exist = coex_sta->sco_exist;
1349 bt_link_info->a2dp_exist = coex_sta->a2dp_exist;
1350 bt_link_info->pan_exist = coex_sta->pan_exist;
1351 bt_link_info->hid_exist = coex_sta->hid_exist;
1352 bt_link_info->acl_busy = coex_sta->acl_busy;
1353
1354 /* check if Sco only */
1355 if (bt_link_info->sco_exist &&
1356 !bt_link_info->a2dp_exist &&
1357 !bt_link_info->pan_exist &&
1358 !bt_link_info->hid_exist)
1359 bt_link_info->sco_only = TRUE;
1360 else
1361 bt_link_info->sco_only = FALSE;
1362
1363 /* check if A2dp only */
1364 if (!bt_link_info->sco_exist &&
1365 bt_link_info->a2dp_exist &&
1366 !bt_link_info->pan_exist &&
1367 !bt_link_info->hid_exist)
1368 bt_link_info->a2dp_only = TRUE;
1369 else
1370 bt_link_info->a2dp_only = FALSE;
1371
1372 /* check if Pan only */
1373 if (!bt_link_info->sco_exist &&
1374 !bt_link_info->a2dp_exist &&
1375 bt_link_info->pan_exist &&
1376 !bt_link_info->hid_exist)
1377 bt_link_info->pan_only = TRUE;
1378 else
1379 bt_link_info->pan_only = FALSE;
1380
1381 /* check if Hid only */
1382 if (!bt_link_info->sco_exist &&
1383 !bt_link_info->a2dp_exist &&
1384 !bt_link_info->pan_exist &&
1385 bt_link_info->hid_exist)
1386 bt_link_info->hid_only = TRUE;
1387 else
1388 bt_link_info->hid_only = FALSE;
1389
1390 if (coex_sta->bt_info_lb2 & BT_INFO_8821C_2ANT_B_INQ_PAGE) {
1391 coex_dm->bt_status = BT_8821C_2ANT_BSTATUS_INQ_PAGE;
1392 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
1393 "[BTCoex], BtInfoNotify(), BT Inq/page!!!\n");
1394 } else if (!(coex_sta->bt_info_lb2 & BT_INFO_8821C_2ANT_B_CONNECTION)) {
1395 coex_dm->bt_status = BT_8821C_2ANT_BSTATUS_NCON_IDLE;
1396 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
1397 "[BTCoex], BtInfoNotify(), BT Non-Connected idle!!!\n");
1398 } else if (coex_sta->bt_info_lb2 == BT_INFO_8821C_2ANT_B_CONNECTION) {
1399 /* connection exists but no busy */
1400 if (coex_sta->msft_mr_exist) {
1401 coex_dm->bt_status = BT_8821C_2ANT_BSTATUS_ACL_BUSY;
1402 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
1403 "[BTCoex], BtInfoNotify(), BT ACL busy!!\n");
1404 } else {
1405 coex_dm->bt_status = BT_8821C_2ANT_BSTATUS_CON_IDLE;
1406 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
1407 "[BTCoex], BtInfoNotify(), BT Connected-idle!!!\n");
1408 }
1409 } else if (((coex_sta->bt_info_lb2 & BT_INFO_8821C_2ANT_B_SCO_ESCO) ||
1410 (coex_sta->bt_info_lb2 & BT_INFO_8821C_2ANT_B_SCO_BUSY)) &&
1411 (coex_sta->bt_info_lb2 & BT_INFO_8821C_2ANT_B_ACL_BUSY)) {
1412 coex_dm->bt_status = BT_8821C_2ANT_BSTATUS_ACL_SCO_BUSY;
1413 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
1414 "[BTCoex], BtInfoNotify(), BT ACL SCO busy!!!\n");
1415 } else if ((coex_sta->bt_info_lb2 & BT_INFO_8821C_2ANT_B_SCO_ESCO) ||
1416 (coex_sta->bt_info_lb2 & BT_INFO_8821C_2ANT_B_SCO_BUSY)) {
1417 coex_dm->bt_status = BT_8821C_2ANT_BSTATUS_SCO_BUSY;
1418 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
1419 "[BTCoex], BtInfoNotify(), BT SCO busy!!!\n");
1420 } else if (coex_sta->bt_info_lb2 & BT_INFO_8821C_2ANT_B_ACL_BUSY) {
1421 coex_dm->bt_status = BT_8821C_2ANT_BSTATUS_ACL_BUSY;
1422 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
1423 "[BTCoex], BtInfoNotify(), BT ACL busy!!!\n");
1424 } else {
1425 coex_dm->bt_status = BT_8821C_2ANT_BSTATUS_MAX;
1426 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
1427 "[BTCoex], BtInfoNotify(), BT Non-Defined state!!!\n");
1428 }
1429
1430 BTC_TRACE(trace_buf);
1431
1432 if (coex_dm->bt_status == BT_8821C_2ANT_BSTATUS_ACL_BUSY ||
1433 coex_dm->bt_status == BT_8821C_2ANT_BSTATUS_SCO_BUSY ||
1434 coex_dm->bt_status == BT_8821C_2ANT_BSTATUS_ACL_SCO_BUSY) {
1435 bt_busy = TRUE;
1436 increase_scan_dev_num = TRUE;
1437 } else {
1438 bt_busy = FALSE;
1439 increase_scan_dev_num = FALSE;
1440 }
1441
1442 btc->btc_set(btc, BTC_SET_BL_BT_TRAFFIC_BUSY, &bt_busy);
1443 btc->btc_set(btc, BTC_SET_BL_INC_SCAN_DEV_NUM, &increase_scan_dev_num);
1444
1445 cur_num_of_profile = coex_sta->num_of_profile;
1446
1447 if (cur_num_of_profile != pre_num_of_profile)
1448 cnt = 2;
1449
1450 if (btc->board_info.customer_id == RT_CID_LENOVO_CHINA) {
1451 if (cur_num_of_profile > 0)
1452 halbtc8821c2ant_set_antdiv_hwsw(btc, NM_EXCU, TRUE);
1453 else
1454 halbtc8821c2ant_set_antdiv_hwsw(btc, NM_EXCU, FALSE);
1455 }
1456
1457 if (bt_link_info->a2dp_exist && cnt > 0) {
1458 cnt--;
1459 if (coex_sta->bt_a2dp_vendor_id == 0 &&
1460 coex_sta->bt_a2dp_device_name == 0) {
1461 btc->btc_get(btc, BTC_GET_U4_BT_DEVICE_INFO, &val);
1462
1463 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
1464 "[BTCoex], BtInfoNotify(), get BT DEVICE_INFO = %x\n",
1465 val);
1466 BTC_TRACE(trace_buf);
1467
1468 coex_sta->bt_a2dp_vendor_id = (u8)(val & 0xff);
1469 coex_sta->bt_a2dp_device_name = (val & 0xffffff00) >> 8;
1470
1471 btc->btc_get(btc, BTC_GET_U4_BT_A2DP_FLUSH_VAL, &val);
1472 coex_sta->bt_a2dp_flush_time = val;
1473 }
1474 } else if (!bt_link_info->a2dp_exist) {
1475 coex_sta->bt_a2dp_vendor_id = 0;
1476 coex_sta->bt_a2dp_device_name = 0;
1477 coex_sta->bt_a2dp_flush_time = 0;
1478 }
1479
1480 pre_num_of_profile = coex_sta->num_of_profile;
1481 }
1482
1483 static
halbtc8821c2ant_update_wifi_ch_info(struct btc_coexist * btc,u8 type)1484 void halbtc8821c2ant_update_wifi_ch_info(struct btc_coexist *btc, u8 type)
1485 {
1486 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
1487 struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant;
1488 struct wifi_link_info_8821c_2ant *wifi_link_info_ext =
1489 &btc->wifi_link_info_8821c_2ant;
1490 u8 h2c_parameter[3] = {0}, i;
1491 u32 wifi_bw;
1492 u8 wl_ch = 0;
1493 u8 wl_5g_ch[] = {0};
1494 u8 bt_skip_ch[] = {0};
1495 u8 bt_skip_span[] = {0};
1496
1497 if (btc->manual_control)
1498 return;
1499
1500 btc->btc_get(btc, BTC_GET_U4_WIFI_BW, &wifi_bw);
1501
1502 if (btc->stop_coex_dm || btc->wl_rf_state_off) {
1503 wl_ch = 0;
1504 } else if (type != BTC_MEDIA_DISCONNECT ||
1505 (type == BTC_MEDIA_DISCONNECT &&
1506 wifi_link_info_ext->num_of_active_port > 0)) {
1507 if (wifi_link_info_ext->num_of_active_port == 1) {
1508 if (wifi_link_info_ext->is_p2p_connected)
1509 wl_ch = btc->wifi_link_info.p2p_center_channel;
1510 else
1511 wl_ch = btc->wifi_link_info.sta_center_channel;
1512 } else { /* port > 2 */
1513 if (btc->wifi_link_info.p2p_center_channel > 14 &&
1514 btc->wifi_link_info.sta_center_channel > 14)
1515 wl_ch = btc->wifi_link_info.p2p_center_channel;
1516 else if (btc->wifi_link_info.p2p_center_channel <= 14)
1517 wl_ch = btc->wifi_link_info.p2p_center_channel;
1518 else if (btc->wifi_link_info.sta_center_channel <= 14)
1519 wl_ch = btc->wifi_link_info.sta_center_channel;
1520 }
1521 }
1522
1523 if (wl_ch > 0) {
1524 if (wl_ch <= 14) {
1525 h2c_parameter[0] = 0x1;
1526 h2c_parameter[1] = wl_ch;
1527
1528 if (wifi_bw == BTC_WIFI_BW_HT40)
1529 h2c_parameter[2] = 0x36;
1530 else
1531 h2c_parameter[2] = 0x24;
1532 } else { /* for 5G */
1533 #if 0
1534 for (i = 0; i < ARRAY_SIZE(wl_5g_ch); i++) {
1535 if (wl_ch == wl_5g_ch[i]) {
1536 h2c_parameter[0] = 0x3;
1537 h2c_parameter[1] = bt_skip_ch[i];
1538 h2c_parameter[2] = bt_skip_span[i];
1539 break;
1540 }
1541 }
1542 #endif
1543 }
1544 }
1545
1546 /* Only send mailbox if ch info change */
1547 if (coex_dm->wifi_chnl_info[0] != h2c_parameter[0] &&
1548 coex_dm->wifi_chnl_info[1] != h2c_parameter[1] &&
1549 coex_dm->wifi_chnl_info[2] != h2c_parameter[2]) {
1550
1551 coex_dm->wifi_chnl_info[0] = h2c_parameter[0];
1552 coex_dm->wifi_chnl_info[1] = h2c_parameter[1];
1553 coex_dm->wifi_chnl_info[2] = h2c_parameter[2];
1554 btc->btc_fill_h2c(btc, 0x66, 3, h2c_parameter);
1555 }
1556
1557 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
1558 "[BTCoex], para[0:2] = 0x%x 0x%x 0x%x\n", h2c_parameter[0],
1559 h2c_parameter[1], h2c_parameter[2]);
1560 BTC_TRACE(trace_buf);
1561 }
1562
1563 static
halbtc8821c2ant_set_wl_tx_power(struct btc_coexist * btc,boolean force_exec,u8 wl_pwr_lvl)1564 void halbtc8821c2ant_set_wl_tx_power(struct btc_coexist *btc,
1565 boolean force_exec, u8 wl_pwr_lvl)
1566 {
1567 struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant;
1568
1569 if (!force_exec) {
1570 if (wl_pwr_lvl == coex_dm->cur_wl_pwr_lvl)
1571 return;
1572 }
1573
1574 /* btc->btc_write_1byte_bitmask(btc, 0xc5b, 0xff, wl_pwr_lvl); */
1575 coex_dm->cur_wl_pwr_lvl = wl_pwr_lvl;
1576 }
1577
1578 static
halbtc8821c2ant_set_bt_tx_power(struct btc_coexist * btc,boolean force_exec,u8 bt_pwr_lvl)1579 void halbtc8821c2ant_set_bt_tx_power(struct btc_coexist *btc,
1580 boolean force_exec, u8 bt_pwr_lvl)
1581 {
1582 struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant;
1583 u8 h2c_parameter[1] = {0};
1584
1585 if (!force_exec) {
1586 if (bt_pwr_lvl == coex_dm->cur_bt_pwr_lvl)
1587 return;
1588 }
1589
1590 h2c_parameter[0] = 0 - bt_pwr_lvl;
1591 btc->btc_fill_h2c(btc, 0x62, 1, h2c_parameter);
1592
1593 coex_dm->cur_bt_pwr_lvl = bt_pwr_lvl;
1594 }
1595
1596 static u32
halbtc8821c2ant_wait_indirect_reg_ready(struct btc_coexist * btc)1597 halbtc8821c2ant_wait_indirect_reg_ready(struct btc_coexist *btc)
1598 {
1599 u32 delay_count = 0;
1600
1601 /* wait for ready bit before access 0x1700 */
1602 while (1) {
1603 if ((btc->btc_read_1byte(btc, 0x1703) & BIT(5)) == 0) {
1604 delay_ms(10);
1605 if (++delay_count >= 10)
1606 break;
1607 } else {
1608 break;
1609 }
1610 }
1611
1612 return delay_count;
1613 }
1614
1615 static
halbtc8821c2ant_read_indirect_reg(struct btc_coexist * btc,u16 reg_addr)1616 u32 halbtc8821c2ant_read_indirect_reg(struct btc_coexist *btc, u16 reg_addr)
1617 {
1618 u32 j = 0, delay_count = 0;
1619
1620 halbtc8821c2ant_wait_indirect_reg_ready(btc);
1621
1622 /* wait for ready bit before access 0x1700 */
1623 btc->btc_write_4byte(btc, 0x1700, 0x800F0000 | reg_addr);
1624
1625 return btc->btc_read_4byte(btc, 0x1708); /* get read data */
1626 }
1627
1628 static
halbtc8821c2ant_write_indirect_reg(struct btc_coexist * btc,u16 reg_addr,u32 bit_mask,u32 reg_value)1629 void halbtc8821c2ant_write_indirect_reg(struct btc_coexist *btc, u16 reg_addr,
1630 u32 bit_mask, u32 reg_value)
1631 {
1632 u32 val, i = 0, j = 0, bitpos = 0, delay_count = 0;
1633
1634 if (bit_mask == 0x0)
1635 return;
1636 if (bit_mask == 0xffffffff) {
1637 /* wait for ready bit before access 0x1700/0x1704 */
1638 halbtc8821c2ant_wait_indirect_reg_ready(btc);
1639
1640 /* put write data */
1641 btc->btc_write_4byte(btc, 0x1704, reg_value);
1642 btc->btc_write_4byte(btc, 0x1700, 0xc00F0000 | reg_addr);
1643 } else {
1644 for (i = 0; i <= 31; i++) {
1645 if (((bit_mask >> i) & 0x1) == 0x1) {
1646 bitpos = i;
1647 break;
1648 }
1649 }
1650
1651 /* read back register value before write */
1652 val = halbtc8821c2ant_read_indirect_reg(btc, reg_addr);
1653 val = (val & (~bit_mask)) | (reg_value << bitpos);
1654
1655 /* wait for ready bit before access 0x1700/0x1704 */
1656 halbtc8821c2ant_wait_indirect_reg_ready(btc);
1657
1658 /* put write data */
1659 btc->btc_write_4byte(btc, 0x1704, val);
1660 btc->btc_write_4byte(btc, 0x1700, 0xc00F0000 | reg_addr);
1661 }
1662 }
1663
1664 static
halbtc8821c2ant_ltecoex_enable(struct btc_coexist * btc,boolean enable)1665 void halbtc8821c2ant_ltecoex_enable(struct btc_coexist *btc, boolean enable)
1666 {
1667 u8 val;
1668
1669 /* 0x38[7] */
1670 val = (enable) ? 1 : 0;
1671 halbtc8821c2ant_write_indirect_reg(btc, 0x38, BIT(7), val);
1672 }
1673
1674 static
halbtc8821c2ant_ltecoex_table(struct btc_coexist * btc,u8 table_type,u16 val)1675 void halbtc8821c2ant_ltecoex_table(struct btc_coexist *btc, u8 table_type,
1676 u16 val)
1677 {
1678 u16 reg_addr = 0x0000;
1679
1680 switch (table_type) {
1681 case BT_8821C_2ANT_CTT_WL_VS_LTE:
1682 reg_addr = 0xa0;
1683 break;
1684 case BT_8821C_2ANT_CTT_BT_VS_LTE:
1685 reg_addr = 0xa4;
1686 break;
1687 }
1688
1689 /* 0xa0[15:0] or 0xa4[15:0] */
1690 if (reg_addr != 0x0000)
1691 halbtc8821c2ant_write_indirect_reg(btc, reg_addr, 0xffff, val);
1692 }
1693
1694 static
halbtc8821c2ant_coex_ctrl_owner(struct btc_coexist * btc,boolean wifi_control)1695 void halbtc8821c2ant_coex_ctrl_owner(struct btc_coexist *btc,
1696 boolean wifi_control)
1697 {
1698 u8 val;
1699
1700 /* 0x70[26] */
1701 val = (wifi_control) ? 1 : 0;
1702 btc->btc_write_1byte_bitmask(btc, 0x73, BIT(2), val);
1703 }
1704
1705 static void
halbtc8821c2ant_set_gnt_bt(struct btc_coexist * btc,u8 state)1706 halbtc8821c2ant_set_gnt_bt(struct btc_coexist *btc, u8 state)
1707 {
1708 switch (state) {
1709 case BTC_GNT_SET_SW_LOW:
1710 halbtc8821c2ant_write_indirect_reg(btc, 0x38, 0xc000, 0x1);
1711 halbtc8821c2ant_write_indirect_reg(btc, 0x38, 0x0c00, 0x1);
1712 break;
1713 case BTC_GNT_SET_SW_HIGH:
1714 halbtc8821c2ant_write_indirect_reg(btc, 0x38, 0xc000, 0x3);
1715 halbtc8821c2ant_write_indirect_reg(btc, 0x38, 0x0c00, 0x3);
1716 break;
1717 case BTC_GNT_SET_HW_PTA:
1718 default:
1719 halbtc8821c2ant_write_indirect_reg(btc, 0x38, 0xc000, 0x0);
1720 halbtc8821c2ant_write_indirect_reg(btc, 0x38, 0x0c00, 0x0);
1721 break;
1722 }
1723 }
1724
1725 static void
halbtc8821c2ant_set_gnt_wl(struct btc_coexist * btc,u8 state)1726 halbtc8821c2ant_set_gnt_wl(struct btc_coexist *btc, u8 state)
1727 {
1728 switch (state) {
1729 case BTC_GNT_SET_SW_LOW:
1730 halbtc8821c2ant_write_indirect_reg(btc, 0x38, 0x3000, 0x1);
1731 halbtc8821c2ant_write_indirect_reg(btc, 0x38, 0x0300, 0x1);
1732 break;
1733 case BTC_GNT_SET_SW_HIGH:
1734 halbtc8821c2ant_write_indirect_reg(btc, 0x38, 0x3000, 0x3);
1735 halbtc8821c2ant_write_indirect_reg(btc, 0x38, 0x0300, 0x3);
1736 break;
1737 case BTC_GNT_SET_HW_PTA:
1738 default:
1739 halbtc8821c2ant_write_indirect_reg(btc, 0x38, 0x3000, 0x0);
1740 halbtc8821c2ant_write_indirect_reg(btc, 0x38, 0x0300, 0x0);
1741 break;
1742 }
1743 }
1744
1745 static
halbtc8821c2ant_set_table(struct btc_coexist * btc,boolean force_exec,u32 val0x6c0,u32 val0x6c4,u32 val0x6c8,u8 val0x6cc)1746 void halbtc8821c2ant_set_table(struct btc_coexist *btc,
1747 boolean force_exec, u32 val0x6c0,
1748 u32 val0x6c4, u32 val0x6c8,
1749 u8 val0x6cc)
1750 {
1751 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
1752 struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant;
1753
1754 if (!force_exec && !coex_sta->wl_slot_toggle_change) {
1755 coex_dm->cur_val0x6c0 = btc->btc_read_4byte(btc, 0x6c0);
1756 coex_dm->cur_val0x6c4 = btc->btc_read_4byte(btc, 0x6c4);
1757
1758 if (val0x6c0 == coex_dm->cur_val0x6c0 &&
1759 val0x6c4 == coex_dm->cur_val0x6c4)
1760 return;
1761 }
1762
1763 btc->btc_write_4byte(btc, 0x6c0, val0x6c0);
1764 btc->btc_write_4byte(btc, 0x6c4, val0x6c4);
1765 btc->btc_write_4byte(btc, 0x6c8, val0x6c8);
1766 btc->btc_write_1byte(btc, 0x6cc, val0x6cc);
1767
1768 coex_dm->cur_val0x6c8 = val0x6c8;
1769 coex_dm->cur_val0x6cc = val0x6cc;
1770 }
1771
halbtc8821c2ant_table(struct btc_coexist * btc,boolean force_exec,u8 type)1772 void halbtc8821c2ant_table(struct btc_coexist *btc, boolean force_exec, u8 type)
1773 {
1774 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
1775 u32 break_table;
1776 u8 select_table;
1777
1778 coex_sta->coex_table_type = type;
1779
1780 if (coex_sta->concurrent_rx_mode_on == TRUE) {
1781 /* set WL hi-pri can break BT */
1782 break_table = 0xf0ffffff;
1783 /* set Tx response = Hi-Pri (ex: Transmitting ACK,BA,CTS) */
1784 select_table = 0x1b;
1785 } else {
1786 break_table = 0xffffff;
1787 select_table = 0x13;
1788 }
1789
1790 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
1791 "[BTCoex], ********** Table-%d **********\n",
1792 coex_sta->coex_table_type);
1793 BTC_TRACE(trace_buf);
1794
1795 switch (type) {
1796 case 0:
1797 halbtc8821c2ant_set_table(btc, force_exec, 0xffffffff,
1798 0xffffffff, break_table,
1799 select_table);
1800 break;
1801 case 1:
1802 halbtc8821c2ant_set_table(btc, force_exec, 0x55555555,
1803 0xfafafafa, break_table,
1804 select_table);
1805 break;
1806 case 2:
1807 halbtc8821c2ant_set_table(btc, force_exec, 0x5a5a5a5a,
1808 0x5a5a5a5a, break_table,
1809 select_table);
1810 break;
1811 case 3:
1812 halbtc8821c2ant_set_table(btc, force_exec, 0x66555555,
1813 0x6a5a5a5a, break_table,
1814 select_table);
1815 break;
1816 case 4:
1817 halbtc8821c2ant_set_table(btc, force_exec, 0xffff55ff,
1818 0xfafafafa, break_table,
1819 select_table);
1820 break;
1821 case 5:
1822 halbtc8821c2ant_set_table(btc, force_exec, 0x55555555,
1823 0x55555555, break_table,
1824 select_table);
1825 break;
1826 case 6: /* not use */
1827 halbtc8821c2ant_set_table(btc, force_exec, 0xaaffffaa,
1828 0x5afa5afa, break_table,
1829 select_table);
1830 break;
1831 case 7:
1832 halbtc8821c2ant_set_table(btc, force_exec, 0xaaffffaa,
1833 0xfafafafa, break_table,
1834 select_table);
1835 break;
1836 case 8:
1837 halbtc8821c2ant_set_table(btc, force_exec, 0xffff55ff,
1838 0xfafafafa, break_table,
1839 select_table);
1840 break;
1841 case 9:
1842 halbtc8821c2ant_set_table(btc, force_exec, 0x5a5a5a5a,
1843 0xaaaa5aaa, break_table,
1844 select_table);
1845 break;
1846 case 10:
1847 halbtc8821c2ant_set_table(btc, force_exec, 0xaaaaaaaa,
1848 0xaaaaaaaa, break_table,
1849 select_table);
1850 break;
1851 case 11:
1852 halbtc8821c2ant_set_table(btc, force_exec, 0xffffffff,
1853 0xfafafafa, break_table,
1854 select_table);
1855 break;
1856 case 12:
1857 halbtc8821c2ant_set_table(btc, force_exec, 0xffff55ff,
1858 0x5afa5afa, break_table,
1859 select_table);
1860 break;
1861 case 14:
1862 halbtc8821c2ant_set_table(btc, force_exec, 0xffff55ff,
1863 0xaaaaaaaa, break_table,
1864 select_table);
1865 break;
1866 case 15:
1867 halbtc8821c2ant_set_table(btc, force_exec, 0x66555555,
1868 0xaaaaaaaa, break_table,
1869 select_table);
1870 break;
1871 case 18:
1872 halbtc8821c2ant_set_table(btc, force_exec, 0xffff55ff,
1873 0xffff55ff, break_table,
1874 select_table);
1875 break;
1876 default:
1877 break;
1878 }
1879 }
1880
1881 #if 0
1882 static void
1883 halbtc8821c2ant_wltoggle_table(IN struct btc_coexist *btc,
1884 IN boolean force_exec, IN u8 interval,
1885 IN u8 val0x6c4_b0, IN u8 val0x6c4_b1,
1886 IN u8 val0x6c4_b2, IN u8 val0x6c4_b3)
1887 {
1888 static u8 pre_h2c_parameter[6] = {0};
1889 u8 cur_h2c_parameter[6] = {0};
1890 u8 i, match_cnt = 0;
1891
1892 cur_h2c_parameter[0] = 0x7; /* op_code, 0x7= wlan toggle slot*/
1893
1894 cur_h2c_parameter[1] = interval;
1895 cur_h2c_parameter[2] = val0x6c4_b0;
1896 cur_h2c_parameter[3] = val0x6c4_b1;
1897 cur_h2c_parameter[4] = val0x6c4_b2;
1898 cur_h2c_parameter[5] = val0x6c4_b3;
1899 #if 0
1900 if (!force_exec) {
1901 for (i = 1; i <= 5; i++) {
1902 if (cur_h2c_parameter[i] != pre_h2c_parameter[i])
1903 break;
1904
1905 match_cnt++;
1906 }
1907
1908 if (match_cnt == 5)
1909 return;
1910 }
1911 #endif
1912 for (i = 1; i <= 5; i++)
1913 pre_h2c_parameter[i] = cur_h2c_parameter[i];
1914
1915 btc->btc_fill_h2c(btc, 0x69, 6, cur_h2c_parameter);
1916 }
1917 #endif
1918
1919 static
halbtc8821c2ant_ignore_wlan_act(struct btc_coexist * btc,boolean force_exec,boolean enable)1920 void halbtc8821c2ant_ignore_wlan_act(struct btc_coexist *btc,
1921 boolean force_exec, boolean enable)
1922 {
1923 struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant;
1924 u8 h2c_parameter[1] = {0};
1925
1926 if (btc->manual_control || btc->stop_coex_dm)
1927 return;
1928
1929 if (!force_exec) {
1930 if (enable == coex_dm->cur_ignore_wlan_act)
1931 return;
1932 }
1933
1934 if (enable)
1935 h2c_parameter[0] |= BIT(0); /* function enable */
1936
1937 btc->btc_fill_h2c(btc, 0x63, 1, h2c_parameter);
1938
1939 coex_dm->cur_ignore_wlan_act = enable;
1940 }
1941
1942 static
halbtc8821c2ant_lps_rpwm(struct btc_coexist * btc,boolean force_exec,u8 lps_val,u8 rpwm_val)1943 void halbtc8821c2ant_lps_rpwm(struct btc_coexist *btc, boolean force_exec,
1944 u8 lps_val, u8 rpwm_val)
1945 {
1946 struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant;
1947
1948 if (!force_exec) {
1949 if (lps_val == coex_dm->cur_lps &&
1950 rpwm_val == coex_dm->cur_rpwm)
1951 return;
1952 }
1953
1954 btc->btc_set(btc, BTC_SET_U1_LPS_VAL, &lps_val);
1955 btc->btc_set(btc, BTC_SET_U1_RPWM_VAL, &rpwm_val);
1956
1957 coex_dm->cur_lps = lps_val;
1958 coex_dm->cur_rpwm = rpwm_val;
1959 }
1960
1961 static
halbtc8821c2ant_tdma_check(struct btc_coexist * btc,boolean new_ps_state)1962 void halbtc8821c2ant_tdma_check(struct btc_coexist *btc, boolean new_ps_state)
1963 {
1964 u8 lps_mode = 0x0;
1965 u8 h2c_parameter[5] = {0, 0, 0, 0x40, 0};
1966
1967 btc->btc_get(btc, BTC_GET_U1_LPS_MODE, &lps_mode);
1968
1969 if (lps_mode) { /* already under LPS state */
1970 if (new_ps_state) {
1971 /* keep state under LPS, do nothing. */
1972 } else {
1973 /* will leave LPS state, turn off psTdma first */
1974 btc->btc_fill_h2c(btc, 0x60, 5, h2c_parameter);
1975 }
1976 } else { /* NO PS state */
1977 if (new_ps_state) {
1978 /* will enter LPS state, turn off psTdma first */
1979 btc->btc_fill_h2c(btc, 0x60, 5, h2c_parameter);
1980 } else {
1981 /* keep state under NO PS state, do nothing. */
1982 }
1983 }
1984 }
1985
1986 static
halbtc8821c2ant_power_save_state(struct btc_coexist * btc,u8 ps_type,u8 lps_val,u8 rpwm_val)1987 boolean halbtc8821c2ant_power_save_state(struct btc_coexist *btc, u8 ps_type,
1988 u8 lps_val, u8 rpwm_val)
1989 {
1990 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
1991 boolean low_pwr_disable = FALSE, result = TRUE;
1992
1993 switch (ps_type) {
1994 case BTC_PS_WIFI_NATIVE:
1995 coex_sta->force_lps_ctrl = FALSE;
1996 /* recover to original 32k low power setting */
1997 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
1998 "[BTCoex], %s == BTC_PS_WIFI_NATIVE\n", __func__);
1999 BTC_TRACE(trace_buf);
2000
2001 low_pwr_disable = FALSE;
2002 /* btc->btc_set(btc, BTC_SET_ACT_DISABLE_LOW_POWER,
2003 * &low_pwr_disable);
2004 */
2005 btc->btc_set(btc, BTC_SET_ACT_PRE_NORMAL_LPS, NULL);
2006 break;
2007 case BTC_PS_LPS_ON:
2008 coex_sta->force_lps_ctrl = TRUE;
2009 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
2010 "[BTCoex], %s == BTC_PS_LPS_ON\n", __func__);
2011 BTC_TRACE(trace_buf);
2012
2013 halbtc8821c2ant_tdma_check(btc, TRUE);
2014 halbtc8821c2ant_lps_rpwm(btc, NM_EXCU, lps_val, rpwm_val);
2015 /* when coex force to enter LPS, do not enter 32k low power. */
2016 low_pwr_disable = TRUE;
2017 btc->btc_set(btc, BTC_SET_ACT_DISABLE_LOW_POWER,
2018 &low_pwr_disable);
2019 /* power save must executed before psTdma.*/
2020 btc->btc_set(btc, BTC_SET_ACT_ENTER_LPS, NULL);
2021 break;
2022 case BTC_PS_LPS_OFF:
2023 coex_sta->force_lps_ctrl = TRUE;
2024 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
2025 "[BTCoex], %s == BTC_PS_LPS_OFF\n", __func__);
2026 BTC_TRACE(trace_buf);
2027
2028 halbtc8821c2ant_tdma_check(btc, FALSE);
2029 result = btc->btc_set(btc, BTC_SET_ACT_LEAVE_LPS, NULL);
2030 break;
2031 default:
2032 break;
2033 }
2034
2035 return result;
2036 }
2037
2038 static
halbtc8821c2ant_set_tdma(struct btc_coexist * btc,u8 byte1,u8 byte2,u8 byte3,u8 byte4,u8 byte5)2039 void halbtc8821c2ant_set_tdma(struct btc_coexist *btc, u8 byte1, u8 byte2,
2040 u8 byte3, u8 byte4, u8 byte5)
2041 {
2042 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
2043 struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant;
2044 u8 h2c_parameter[5] = {0};
2045 u8 real_byte1 = byte1, real_byte5 = byte5;
2046 boolean ap_enable = FALSE, result = FALSE;
2047 u8 ps_type = BTC_PS_WIFI_NATIVE;
2048
2049 if (byte5 & BIT(2))
2050 coex_sta->is_tdma_btautoslot = TRUE;
2051 else
2052 coex_sta->is_tdma_btautoslot = FALSE;
2053
2054 if (btc->wifi_link_info.link_mode == BTC_LINK_ONLY_GO &&
2055 btc->wifi_link_info.bhotspot &&
2056 btc->wifi_link_info.bany_client_join_go)
2057 ap_enable = TRUE;
2058
2059 if ((ap_enable) && (byte1 & BIT(4) && !(byte1 & BIT(5)))) {
2060 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
2061 "[BTCoex], %s == FW for AP mode\n", __func__);
2062 BTC_TRACE(trace_buf);
2063
2064 real_byte1 &= ~BIT(4);
2065 real_byte1 |= BIT(5);
2066
2067 real_byte5 |= BIT(5);
2068 real_byte5 &= ~BIT(6);
2069
2070 ps_type = BTC_PS_WIFI_NATIVE;
2071 halbtc8821c2ant_power_save_state(btc, ps_type, 0x0, 0x0);
2072 } else if (byte1 & BIT(4) && !(byte1 & BIT(5))) {
2073 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
2074 "[BTCoex], %s == Force LPS (byte1 = 0x%x)\n",
2075 __func__, byte1);
2076 BTC_TRACE(trace_buf);
2077
2078 ps_type = BTC_PS_LPS_OFF;
2079 if (!halbtc8821c2ant_power_save_state(btc, ps_type, 0x50, 0x4))
2080 result = TRUE;
2081 } else {
2082 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
2083 "[BTCoex], %s == Native LPS (byte1 = 0x%x)\n",
2084 __func__, byte1);
2085 BTC_TRACE(trace_buf);
2086
2087 ps_type = BTC_PS_WIFI_NATIVE;
2088 halbtc8821c2ant_power_save_state(btc, ps_type, 0x0, 0x0);
2089 }
2090
2091 coex_sta->is_set_ps_state_fail = result;
2092
2093 if (!coex_sta->is_set_ps_state_fail) {
2094 h2c_parameter[0] = real_byte1;
2095 h2c_parameter[1] = byte2;
2096 h2c_parameter[2] = byte3;
2097 h2c_parameter[3] = byte4;
2098 h2c_parameter[4] = real_byte5;
2099
2100 coex_dm->ps_tdma_para[0] = real_byte1;
2101 coex_dm->ps_tdma_para[1] = byte2;
2102 coex_dm->ps_tdma_para[2] = byte3;
2103 coex_dm->ps_tdma_para[3] = byte4;
2104 coex_dm->ps_tdma_para[4] = real_byte5;
2105
2106 btc->btc_fill_h2c(btc, 0x60, 5, h2c_parameter);
2107
2108 if (real_byte1 & BIT(2)) {
2109 coex_sta->wl_slot_toggle = TRUE;
2110 coex_sta->wl_slot_toggle_change = FALSE;
2111 } else {
2112 if (coex_sta->wl_slot_toggle)
2113 coex_sta->wl_slot_toggle_change = TRUE;
2114 else
2115 coex_sta->wl_slot_toggle_change = FALSE;
2116 coex_sta->wl_slot_toggle = FALSE;
2117 }
2118 } else {
2119 coex_sta->cnt_set_ps_state_fail++;
2120 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
2121 "[BTCoex], %s == Force Leave LPS Fail (cnt = %d)\n",
2122 __func__, coex_sta->cnt_set_ps_state_fail);
2123 BTC_TRACE(trace_buf);
2124 }
2125
2126 if (ps_type == BTC_PS_WIFI_NATIVE)
2127 btc->btc_set(btc, BTC_SET_ACT_POST_NORMAL_LPS, NULL);
2128 }
2129
2130 static
halbtc8821c2ant_tdma(struct btc_coexist * btc,boolean force_exec,boolean turn_on,u32 tcase)2131 void halbtc8821c2ant_tdma(struct btc_coexist *btc,
2132 boolean force_exec, boolean turn_on, u32 tcase)
2133 {
2134 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
2135 struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant;
2136 u8 type;
2137 boolean wifi_busy;
2138
2139 btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
2140
2141 btc->btc_set_atomic(btc, &coex_dm->setting_tdma, TRUE);
2142
2143 /* tcase: bit0~7 --> tdma case index
2144 * bit8 --> for 4-slot (50ms) mode
2145 */
2146 if (tcase & TDMA_4SLOT)/* 4-slot (50ms) mode */
2147 halbtc8821c2ant_set_tdma_timer_base(btc, 3);
2148 else
2149 halbtc8821c2ant_set_tdma_timer_base(btc, 0);
2150
2151 type = (u8)(tcase & 0xff);
2152
2153 /* To avoid TDMA H2C fail before Last LPS enter */
2154 if (!force_exec && coex_sta->coex_run_reason != BTC_RSN_LPS) {
2155 if (turn_on == coex_dm->cur_ps_tdma_on &&
2156 type == coex_dm->cur_ps_tdma) {
2157 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
2158 "[BTCoex], Skip TDMA because no change TDMA(%s, %d)\n",
2159 (coex_dm->cur_ps_tdma_on ? "on" : "off"),
2160 coex_dm->cur_ps_tdma);
2161 BTC_TRACE(trace_buf);
2162
2163 btc->btc_set_atomic(btc, &coex_dm->setting_tdma, FALSE);
2164 return;
2165 }
2166 }
2167
2168 if (!wifi_busy ||
2169 (coex_sta->a2dp_exist && coex_sta->bt_inq_page_remain))
2170 halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_TDMA,
2171 FALSE);
2172 else
2173 halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_TDMA,
2174 TRUE);
2175
2176 if (turn_on) {
2177 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
2178 "[BTCoex], ********** TDMA(on, %d) **********\n",
2179 type);
2180 BTC_TRACE(trace_buf);
2181
2182 /* enable TBTT nterrupt */
2183 btc->btc_write_1byte_bitmask(btc, 0x550, 0x8, 0x1);
2184
2185 switch (type) {
2186 case 1:
2187 halbtc8821c2ant_set_tdma(btc, 0x61, 0x10, 0x03, 0x91,
2188 0x50);
2189 break;
2190 case 2:
2191 default:
2192 halbtc8821c2ant_set_tdma(btc, 0x61, 0x35, 0x03, 0x11,
2193 0x11);
2194 break;
2195 case 3:
2196 halbtc8821c2ant_set_tdma(btc, 0x61, 0x30, 0x3, 0x91,
2197 0x10);
2198 break;
2199 case 4:
2200 halbtc8821c2ant_set_tdma(btc, 0x61, 0x21, 0x3, 0x91,
2201 0x10);
2202 break;
2203 case 5:
2204 halbtc8821c2ant_set_tdma(btc, 0x61, 0x25, 0x3, 0x91,
2205 0x10);
2206 break;
2207 case 6:
2208 halbtc8821c2ant_set_tdma(btc, 0x61, 0x10, 0x3, 0x91,
2209 0x10);
2210 break;
2211 case 7:
2212 halbtc8821c2ant_set_tdma(btc, 0x61, 0x20, 0x3, 0x91,
2213 0x10);
2214 break;
2215 case 8:
2216 halbtc8821c2ant_set_tdma(btc, 0x61, 0x15, 0x03, 0x11,
2217 0x11);
2218 break;
2219 case 10:
2220 halbtc8821c2ant_set_tdma(btc, 0x61, 0x30, 0x03, 0x11,
2221 0x10);
2222 break;
2223 case 11:
2224 halbtc8821c2ant_set_tdma(btc, 0x61, 0x35, 0x03, 0x11,
2225 0x10);
2226 break;
2227 case 12:
2228 halbtc8821c2ant_set_tdma(btc, 0x61, 0x35, 0x03, 0x11,
2229 0x11);
2230 break;
2231 case 13:
2232 halbtc8821c2ant_set_tdma(btc, 0x61, 0x20, 0x03, 0x11,
2233 0x10);
2234 break;
2235 case 14:
2236 halbtc8821c2ant_set_tdma(btc, 0x61, 0x20, 0x03, 0x11,
2237 0x11);
2238 break;
2239 case 15:
2240 halbtc8821c2ant_set_tdma(btc, 0x61, 0x10, 0x03, 0x11,
2241 0x10);
2242 break;
2243 case 16:
2244 halbtc8821c2ant_set_tdma(btc, 0x61, 0x10, 0x03, 0x11,
2245 0x11);
2246 break;
2247 case 17:
2248 halbtc8821c2ant_set_tdma(btc, 0x61, 0x08, 0x03, 0x11,
2249 0x14);
2250 break;
2251 case 21:
2252 halbtc8821c2ant_set_tdma(btc, 0x61, 0x30, 0x03, 0x11,
2253 0x10);
2254 break;
2255 case 22:
2256 halbtc8821c2ant_set_tdma(btc, 0x61, 0x25, 0x03, 0x11,
2257 0x10);
2258 break;
2259 case 23:
2260 halbtc8821c2ant_set_tdma(btc, 0x61, 0x10, 0x03, 0x11,
2261 0x10);
2262 break;
2263 case 25:
2264 halbtc8821c2ant_set_tdma(btc, 0x51, 0x3a, 0x3, 0x11,
2265 0x50);
2266 break;
2267 case 51:
2268 halbtc8821c2ant_set_tdma(btc, 0x61, 0x10, 0x03, 0x91,
2269 0x10);
2270 break;
2271 case 101:
2272 halbtc8821c2ant_set_tdma(btc, 0x51, 0x08, 0x03, 0x10,
2273 0x54);
2274 break;
2275 case 102:
2276 halbtc8821c2ant_set_tdma(btc, 0x61, 0x35, 0x03, 0x11,
2277 0x11);
2278 break;
2279 case 103:
2280 halbtc8821c2ant_set_tdma(btc, 0x51, 0x30, 0x3, 0x10,
2281 0x50);
2282 break;
2283 case 104:
2284 halbtc8821c2ant_set_tdma(btc, 0x51, 0x21, 0x3, 0x10,
2285 0x50);
2286 break;
2287 case 105:
2288 halbtc8821c2ant_set_tdma(btc, 0x51, 0x45, 0x3, 0x10,
2289 0x50);
2290 break;
2291 case 106:
2292 halbtc8821c2ant_set_tdma(btc, 0x51, 0x1a, 0x3, 0x10,
2293 0x50);
2294 break;
2295 case 107:
2296 halbtc8821c2ant_set_tdma(btc, 0x51, 0x08, 0x7, 0x10,
2297 0x54);
2298 break;
2299 case 108:
2300 halbtc8821c2ant_set_tdma(btc, 0x51, 0x30, 0x3, 0x10,
2301 0x50);
2302 break;
2303 case 109:
2304 halbtc8821c2ant_set_tdma(btc, 0x51, 0x08, 0x03, 0x10,
2305 0x54);
2306 break;
2307 case 110:
2308 halbtc8821c2ant_set_tdma(btc, 0x51, 0x30, 0x03, 0x10,
2309 0x50);
2310 break;
2311 case 111:
2312 halbtc8821c2ant_set_tdma(btc, 0x61, 0x25, 0x03, 0x11,
2313 0x11);
2314 break;
2315 case 112:
2316 halbtc8821c2ant_set_tdma(btc, 0x51, 0x4a, 0x3, 0x10,
2317 0x50);
2318 break;
2319 case 113:
2320 halbtc8821c2ant_set_tdma(btc, 0x61, 0x45, 0x03, 0x11,
2321 0x10);
2322 break;
2323 case 115:
2324 halbtc8821c2ant_set_tdma(btc, 0x51, 0x30, 0x03, 0x10,
2325 0x50);
2326 break;
2327 case 116:
2328 halbtc8821c2ant_set_tdma(btc, 0x51, 0x08, 0x03, 0x10,
2329 0x50);
2330 break;
2331 case 117:
2332 halbtc8821c2ant_set_tdma(btc, 0x61, 0x08, 0x03, 0x11,
2333 0x11);
2334 break;
2335 case 119:
2336 halbtc8821c2ant_set_tdma(btc, 0x61, 0x08, 0x03, 0x10,
2337 0x14);
2338 break;
2339 case 120:
2340 halbtc8821c2ant_set_tdma(btc, 0x61, 0x08, 0x03, 0x10,
2341 0x15);
2342 break;
2343 case 151:
2344 halbtc8821c2ant_set_tdma(btc, 0x51, 0x10, 0x03, 0x10,
2345 0x50);
2346 break;
2347 }
2348 } else {
2349 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
2350 "[BTCoex], ********** TDMA(off, %d) **********\n",
2351 type);
2352 BTC_TRACE(trace_buf);
2353
2354 halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_TDMA, FALSE);
2355
2356 /* disable PS tdma */
2357 switch (type) {
2358 case 0:
2359 halbtc8821c2ant_set_tdma(btc, 0x0, 0x0, 0x0, 0x40, 0x0);
2360 break;
2361 case 1:
2362 halbtc8821c2ant_set_tdma(btc, 0x0, 0x0, 0x0, 0x48, 0x0);
2363 break;
2364 default:
2365 halbtc8821c2ant_set_tdma(btc, 0x0, 0x0, 0x0, 0x40, 0x0);
2366 break;
2367 }
2368 }
2369
2370 coex_dm->cur_ps_tdma_on = turn_on;
2371 coex_dm->cur_ps_tdma = type;
2372
2373 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "change TDMA(%s, %d)\n",
2374 (coex_dm->cur_ps_tdma_on ? "on" : "off"),
2375 coex_dm->cur_ps_tdma);
2376 BTC_TRACE(trace_buf);
2377
2378 btc->btc_set_atomic(btc, &coex_dm->setting_tdma, FALSE);
2379 }
2380
2381 static
halbtc8821c2ant_set_ant_switch(struct btc_coexist * btc,boolean force_exec,u8 ctrl_type,u8 pos_type)2382 void halbtc8821c2ant_set_ant_switch(struct btc_coexist *btc,
2383 boolean force_exec, u8 ctrl_type,
2384 u8 pos_type)
2385 {
2386 struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant;
2387 struct rfe_type_8821c_2ant *rfe_type = &btc->rfe_type_8821c_2ant;
2388 struct btc_board_info *board_info = &btc->board_info;
2389 boolean polarity_inverse = FALSE;
2390 u8 val = 0;
2391 u32 u32tmp1 = 0, u32tmp2 = 0, u32tmp3 = 0;
2392
2393 if (!rfe_type->ext_ant_switch_exist)
2394 return;
2395
2396 if (!force_exec) {
2397 if (((ctrl_type << 8) + pos_type) ==
2398 coex_dm->cur_ext_ant_switch_status)
2399 return;
2400 }
2401
2402 coex_dm->cur_ext_ant_switch_status = (ctrl_type << 8) + pos_type;
2403
2404 /* swap control polarity if use different switch control polarity
2405 * Normal switch polarity for DPDT,
2406 * 0xcb4[29:28] = 2b'01 => BTG to Main, WLG to Aux,
2407 * 0xcb4[29:28] = 2b'10 => BTG to Aux, WLG to Main
2408 * Normal switch polarity for SPDT,
2409 * 0xcb4[29:28] = 2b'01 => Ant to BTG,
2410 * 0xcb4[29:28] = 2b'10 => Ant to WLG
2411 */
2412 if (rfe_type->ext_ant_switch_ctrl_polarity)
2413 polarity_inverse = !polarity_inverse;
2414
2415 /* swap control polarity if 1-Ant at Aux */
2416 if (rfe_type->ant_at_main_port == FALSE)
2417 polarity_inverse = !polarity_inverse;
2418
2419 switch (pos_type) {
2420 default:
2421 case BT_8821C_2ANT_TO_BT:
2422 case BT_8821C_2ANT_TO_NOCARE:
2423 case BT_8821C_2ANT_TO_WLA:
2424
2425 break;
2426 case BT_8821C_2ANT_TO_WLG:
2427 if (!rfe_type->wlg_locate_at_btg)
2428 polarity_inverse = !polarity_inverse;
2429
2430 break;
2431 }
2432
2433 if (board_info->ant_div_cfg && ctrl_type == BT_8821C_2ANT_CTRL_BY_BBSW)
2434 ctrl_type = BT_8821C_2ANT_CTRL_BY_ANTDIV;
2435
2436 switch (ctrl_type) {
2437 default:
2438 case BT_8821C_2ANT_CTRL_BY_BBSW:
2439 /* 0x4c[23] = 0 */
2440 btc->btc_write_1byte_bitmask(btc, 0x4e, 0x80, 0x0);
2441 /* 0x4c[24] = 1 */
2442 btc->btc_write_1byte_bitmask(btc, 0x4f, 0x01, 0x1);
2443 /* BB SW, DPDT use RFE_ctrl8 and RFE_ctrl9 as control pin */
2444 btc->btc_write_1byte_bitmask(btc, 0xcb4, 0xff, 0x77);
2445 /* 0xcb4[29:28] = 2b'01 for no switch_polarity_inverse,
2446 * DPDT_SEL_N =1, DPDT_SEL_P =0
2447 */
2448 val = (!polarity_inverse ? 0x1 : 0x2);
2449 btc->btc_write_1byte_bitmask(btc, 0xcb7, 0x30, val);
2450 break;
2451 case BT_8821C_2ANT_CTRL_BY_PTA:
2452 /* 0x4c[23] = 0 */
2453 btc->btc_write_1byte_bitmask(btc, 0x4e, 0x80, 0x0);
2454 /* 0x4c[24] = 1 */
2455 btc->btc_write_1byte_bitmask(btc, 0x4f, 0x01, 0x1);
2456 /* PTA, DPDT use RFE_ctrl8 and RFE_ctrl9 as control pin */
2457 btc->btc_write_1byte_bitmask(btc, 0xcb4, 0xff, 0x66);
2458 /* 0xcb4[29:28] = 2b'10 for no switch_polatiry_inverse,
2459 * DPDT_SEL_N =1, DPDT_SEL_P =0 @ GNT_BT=1
2460 */
2461 val = (!polarity_inverse ? 0x2 : 0x1);
2462 btc->btc_write_1byte_bitmask(btc, 0xcb7, 0x30, val);
2463 break;
2464 case BT_8821C_2ANT_CTRL_BY_ANTDIV:
2465 /* 0x4c[23] = 0 */
2466 btc->btc_write_1byte_bitmask(btc, 0x4e, 0x80, 0x0);
2467 /* 0x4c[24] = 1 */
2468 btc->btc_write_1byte_bitmask(btc, 0x4f, 0x01, 0x1);
2469 btc->btc_write_1byte_bitmask(btc, 0xcb4, 0xff, 0x88);
2470
2471 /* no regval_0xcb7 setup required, because antenna switch
2472 * control value by antenna diversity
2473 */
2474 break;
2475 case BT_8821C_2ANT_CTRL_BY_MAC:
2476 /* 0x4c[23] = 1 */
2477 btc->btc_write_1byte_bitmask(btc, 0x4e, 0x80, 0x1);
2478 /* 0x64[0] = 1b'0 for no switch_polarity_inverse,
2479 * DPDT_SEL_N =1, DPDT_SEL_P =0
2480 */
2481 val = (!polarity_inverse ? 0x0 : 0x1);
2482 btc->btc_write_1byte_bitmask(btc, 0x64, 0x1, val);
2483 break;
2484 case BT_8821C_2ANT_CTRL_BY_FW:
2485 /* 0x4c[23] = 0 */
2486 btc->btc_write_1byte_bitmask(btc, 0x4e, 0x80, 0x0);
2487 /* 0x4c[24] = 1 */
2488 btc->btc_write_1byte_bitmask(btc, 0x4f, 0x01, 0x1);
2489 break;
2490 case BT_8821C_2ANT_CTRL_BY_BT:
2491 /* 0x4c[23] = 0 */
2492 btc->btc_write_1byte_bitmask(btc, 0x4e, 0x80, 0x0);
2493 /* 0x4c[24] = 0 */
2494 btc->btc_write_1byte_bitmask(btc, 0x4f, 0x01, 0x0);
2495 /* no setup required, because antenna switch control value
2496 * by BT vendor 0xac[1:0]
2497 */
2498 break;
2499 }
2500
2501 /* PAPE, LNA_ON control by BT while WLAN off
2502 * for current leakage issue
2503 */
2504 if (ctrl_type == BT_8821C_2ANT_CTRL_BY_BT) {
2505 /* PAPE 0x64[29] = 0 */
2506 btc->btc_write_1byte_bitmask(btc, 0x67, 0x20, 0x0);
2507 /* LNA_ON 0x64[28] = 0 */
2508 btc->btc_write_1byte_bitmask(btc, 0x67, 0x10, 0x0);
2509 } else {
2510 /* PAPE 0x64[29] = 1 */
2511 btc->btc_write_1byte_bitmask(btc, 0x67, 0x20, 0x1);
2512 /* LNA_ON 0x64[28] = 1 */
2513 btc->btc_write_1byte_bitmask(btc, 0x67, 0x10, 0x1);
2514 }
2515 }
2516
2517 static
halbtc8821c2ant_set_rfe_type(struct btc_coexist * btc)2518 void halbtc8821c2ant_set_rfe_type(struct btc_coexist *btc)
2519 {
2520 struct rfe_type_8821c_2ant *rfe_type = &btc->rfe_type_8821c_2ant;
2521 struct btc_board_info *board_info = &btc->board_info;
2522
2523 /* the following setup should be got from Efuse in the future */
2524 rfe_type->rfe_module_type = board_info->rfe_type & 0x1f;
2525
2526 rfe_type->ext_ant_switch_ctrl_polarity = 0;
2527
2528 switch (rfe_type->rfe_module_type) {
2529 case 0:
2530 case 8:
2531 default: /*2-Ant, DPDT, WLG*/
2532 rfe_type->ext_ant_switch_exist = TRUE;
2533 rfe_type->ext_ant_switch_type = BT_8821C_2ANT_USE_DPDT;
2534 rfe_type->wlg_locate_at_btg = FALSE;
2535 rfe_type->ant_at_main_port = TRUE;
2536 break;
2537 case 1:
2538 case 9: /*1-Ant, Main, WLG */
2539 rfe_type->ext_ant_switch_exist = TRUE;
2540 rfe_type->ext_ant_switch_type = BT_8821C_2ANT_USE_SPDT;
2541 rfe_type->wlg_locate_at_btg = FALSE;
2542 rfe_type->ant_at_main_port = TRUE;
2543 break;
2544 case 2:
2545 case 10: /*1-Ant, Main, BTG */
2546 rfe_type->ext_ant_switch_exist = TRUE;
2547 rfe_type->ext_ant_switch_type = BT_8821C_2ANT_USE_SPDT;
2548 rfe_type->wlg_locate_at_btg = TRUE;
2549 rfe_type->ant_at_main_port = TRUE;
2550 break;
2551 case 3:
2552 case 11: /*1-Ant, Aux, WLG */
2553 rfe_type->ext_ant_switch_exist = TRUE;
2554 rfe_type->ext_ant_switch_type = BT_8821C_2ANT_USE_DPDT;
2555 rfe_type->wlg_locate_at_btg = FALSE;
2556 rfe_type->ant_at_main_port = FALSE;
2557 break;
2558 case 4:
2559 case 12: /*1-Ant, Aux, BTG */
2560 rfe_type->ext_ant_switch_exist = TRUE;
2561 rfe_type->ext_ant_switch_type = BT_8821C_2ANT_USE_DPDT;
2562 rfe_type->wlg_locate_at_btg = TRUE;
2563 rfe_type->ant_at_main_port = FALSE;
2564 break;
2565 case 5:
2566 case 13: /*2-Ant, no switch, WLG*/
2567 rfe_type->ext_ant_switch_exist = FALSE;
2568 rfe_type->ext_ant_switch_type = BT_8821C_2ANT_SWITCH_NONE;
2569 rfe_type->wlg_locate_at_btg = FALSE;
2570 rfe_type->ant_at_main_port = TRUE;
2571 break;
2572 case 6:
2573 case 14: /*2-Ant, no antenna switch, WLG*/
2574 rfe_type->ext_ant_switch_exist = FALSE;
2575 rfe_type->ext_ant_switch_type = BT_8821C_2ANT_SWITCH_NONE;
2576 rfe_type->wlg_locate_at_btg = FALSE;
2577 rfe_type->ant_at_main_port = TRUE;
2578 break;
2579 case 7:
2580 case 15: /*2-Ant, DPDT, BTG*/
2581 rfe_type->ext_ant_switch_exist = TRUE;
2582 rfe_type->ext_ant_switch_type = BT_8821C_2ANT_USE_DPDT;
2583 rfe_type->wlg_locate_at_btg = TRUE;
2584 rfe_type->ant_at_main_port = TRUE;
2585 break;
2586 }
2587 }
2588
2589 static
halbtc8821c2ant_set_ant_path(struct btc_coexist * btc,u8 ant_pos_type,boolean force_exec,u8 phase)2590 void halbtc8821c2ant_set_ant_path(struct btc_coexist *btc,
2591 u8 ant_pos_type, boolean force_exec,
2592 u8 phase)
2593 {
2594 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
2595 struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant;
2596 struct btc_board_info *board_info = &btc->board_info;
2597 u32 cnt_bt_cal_chk = 0, u32tmp1 = 0, u32tmp2 = 0;
2598 u8 u8tmp = 0, ctrl_type, pos_type;
2599
2600 if (!force_exec) {
2601 if (coex_dm->cur_ant_pos_type == ((ant_pos_type << 8) + phase))
2602 return;
2603 }
2604
2605 coex_dm->cur_ant_pos_type = (ant_pos_type << 8) + phase;
2606
2607 if (btc->dbg_mode) {
2608 u32tmp1 = btc->btc_read_4byte(btc, 0xcb4);
2609 u32tmp2 = btc->btc_read_4byte(btc, 0xcbc);
2610 u8tmp = btc->btc_read_1byte(btc, 0x73);
2611
2612 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
2613 "[BTCoex], (Before Ant Setup) 0xcb4 = 0x%x, 0xcbc = 0x%x, 0x73 = 0x%x\n",
2614 u32tmp1, u32tmp2, u8tmp);
2615 BTC_TRACE(trace_buf);
2616 }
2617
2618 switch (phase) {
2619 case BT_8821C_2ANT_PHASE_POWERON:
2620 /* set Path control owner to WL at initial step */
2621 halbtc8821c2ant_coex_ctrl_owner(btc, BT_8821C_2ANT_PCO_BTSIDE);
2622
2623 if (ant_pos_type == BTC_ANT_PATH_AUTO) {
2624 if (board_info->btdm_ant_pos ==
2625 BTC_ANTENNA_AT_MAIN_PORT)
2626 ant_pos_type = BTC_ANT_WIFI_AT_MAIN;
2627 else
2628 ant_pos_type = BTC_ANT_WIFI_AT_AUX;
2629 }
2630
2631 coex_sta->run_time_state = FALSE;
2632 break;
2633 case BT_8821C_2ANT_PHASE_INIT:
2634 /* Disable LTE Coex Function in WiFi side
2635 * (this should be on if LTE coex is required)
2636 */
2637 halbtc8821c2ant_ltecoex_enable(btc, 0x0);
2638
2639 /* GNT_WL_LTE always = 1
2640 * (this should be config if LTE coex is required)
2641 */
2642 halbtc8821c2ant_ltecoex_table(btc, BT_8821C_2ANT_CTT_WL_VS_LTE,
2643 0xffff);
2644
2645 /* GNT_BT_LTE always = 1
2646 * (this should be config if LTE coex is required)
2647 */
2648 halbtc8821c2ant_ltecoex_table(btc, BT_8821C_2ANT_CTT_BT_VS_LTE,
2649 0xffff);
2650
2651 /* Wait If BT IQK running, because Path control owner
2652 * is at BT during BT IQK (setup by WiFi firmware)
2653 */
2654 while (cnt_bt_cal_chk <= 20) {
2655 u8tmp = btc->btc_read_1byte(btc, 0x49c);
2656 cnt_bt_cal_chk++;
2657
2658 if (u8tmp & BIT(1)) {
2659 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
2660 "[BTCoex], ########### BT is calibrating (wait cnt=%d)\n",
2661 cnt_bt_cal_chk);
2662 BTC_TRACE(trace_buf);
2663 delay_ms(10);
2664 } else {
2665 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
2666 "[BTCoex], ********** BT is NOT calibrating (wait cnt=%d)\n",
2667 cnt_bt_cal_chk);
2668 BTC_TRACE(trace_buf);
2669 break;
2670 }
2671 }
2672
2673 /* set Path control owner to WL at initial step */
2674 halbtc8821c2ant_coex_ctrl_owner(btc, BT_8821C_2ANT_PCO_WLSIDE);
2675
2676 /* set GNT_BT to SW high */
2677 halbtc8821c2ant_set_gnt_bt(btc, BTC_GNT_SET_SW_HIGH);
2678 /* Set GNT_WL to SW high */
2679 halbtc8821c2ant_set_gnt_wl(btc, BTC_GNT_SET_SW_HIGH);
2680
2681 coex_sta->run_time_state = FALSE;
2682
2683 if (ant_pos_type == BTC_ANT_PATH_AUTO) {
2684 if (board_info->btdm_ant_pos ==
2685 BTC_ANTENNA_AT_MAIN_PORT)
2686 ant_pos_type = BTC_ANT_WIFI_AT_MAIN;
2687 else
2688 ant_pos_type = BTC_ANT_WIFI_AT_AUX;
2689 }
2690 break;
2691 case BT_8821C_2ANT_PHASE_WONLY:
2692 /* Disable LTE Coex Function in WiFi side
2693 * (this should be on if LTE coex is required)
2694 */
2695 halbtc8821c2ant_ltecoex_enable(btc, 0x0);
2696
2697 /* GNT_WL_LTE always = 1
2698 * (this should be config if LTE coex is required)
2699 */
2700 halbtc8821c2ant_ltecoex_table(btc, BT_8821C_2ANT_CTT_WL_VS_LTE,
2701 0xffff);
2702
2703 /* GNT_BT_LTE always = 1
2704 * (this should be config if LTE coex is required)
2705 */
2706 halbtc8821c2ant_ltecoex_table(btc, BT_8821C_2ANT_CTT_BT_VS_LTE,
2707 0xffff);
2708
2709 /* set Path control owner to WL at initial step */
2710 halbtc8821c2ant_coex_ctrl_owner(btc, BT_8821C_2ANT_PCO_WLSIDE);
2711
2712 /* set GNT_BT to SW Low */
2713 halbtc8821c2ant_set_gnt_bt(btc, BTC_GNT_SET_SW_LOW);
2714 /* Set GNT_WL to SW high */
2715 halbtc8821c2ant_set_gnt_wl(btc, BTC_GNT_SET_SW_HIGH);
2716
2717 coex_sta->run_time_state = FALSE;
2718
2719 if (ant_pos_type == BTC_ANT_PATH_AUTO) {
2720 if (board_info->btdm_ant_pos ==
2721 BTC_ANTENNA_AT_MAIN_PORT)
2722 ant_pos_type = BTC_ANT_WIFI_AT_MAIN;
2723 else
2724 ant_pos_type = BTC_ANT_WIFI_AT_AUX;
2725 }
2726
2727 break;
2728 case BT_8821C_2ANT_PHASE_WOFF:
2729 /* Disable LTE Coex Function in WiFi side */
2730 halbtc8821c2ant_ltecoex_enable(btc, 0x0);
2731
2732 /* set Path control owner to BT */
2733 halbtc8821c2ant_coex_ctrl_owner(btc, BT_8821C_2ANT_PCO_BTSIDE);
2734
2735 coex_sta->run_time_state = FALSE;
2736 break;
2737 case BT_8821C_2ANT_PHASE_2G:
2738 while (cnt_bt_cal_chk <= 20) {
2739 /* 0x49c[0]=1 WL IQK, 0x49c[1]=1 BT IQK*/
2740 u8tmp = btc->btc_read_1byte(btc, 0x49c);
2741
2742 cnt_bt_cal_chk++;
2743 if (u8tmp & BIT(0)) {
2744 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
2745 "[BTCoex], ########### WL is IQK (wait cnt=%d)\n",
2746 cnt_bt_cal_chk);
2747 BTC_TRACE(trace_buf);
2748 delay_ms(10);
2749 } else if (u8tmp & BIT(1)) {
2750 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
2751 "[BTCoex], ########### BT is IQK (wait cnt=%d)\n",
2752 cnt_bt_cal_chk);
2753 BTC_TRACE(trace_buf);
2754 delay_ms(10);
2755 } else {
2756 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
2757 "[BTCoex], ********** WL and BT is NOT IQK (wait cnt=%d)\n",
2758 cnt_bt_cal_chk);
2759 BTC_TRACE(trace_buf);
2760 break;
2761 }
2762 }
2763
2764 /* set Path control owner to WL at runtime step */
2765 halbtc8821c2ant_coex_ctrl_owner(btc, BT_8821C_2ANT_PCO_WLSIDE);
2766
2767 /* set GNT_BT to PTA */
2768 halbtc8821c2ant_set_gnt_bt(btc, BTC_GNT_SET_HW_PTA);
2769
2770 /* Set GNT_WL to PTA */
2771 halbtc8821c2ant_set_gnt_wl(btc, BTC_GNT_SET_HW_PTA);
2772
2773 coex_sta->run_time_state = TRUE;
2774
2775 if (ant_pos_type == BTC_ANT_PATH_AUTO) {
2776 if (board_info->btdm_ant_pos ==
2777 BTC_ANTENNA_AT_MAIN_PORT)
2778 ant_pos_type = BTC_ANT_WIFI_AT_MAIN;
2779 else
2780 ant_pos_type = BTC_ANT_WIFI_AT_AUX;
2781 }
2782
2783 break;
2784 case BT_8821C_2ANT_PHASE_5G:
2785 /* set Path control owner to WL at runtime step */
2786 halbtc8821c2ant_coex_ctrl_owner(btc, BT_8821C_2ANT_PCO_WLSIDE);
2787
2788 /* set GNT_BT to PTA */
2789 halbtc8821c2ant_set_gnt_bt(btc, BTC_GNT_SET_HW_PTA);
2790
2791 /* Set GNT_WL to SW Hi */
2792 halbtc8821c2ant_set_gnt_wl(btc, BTC_GNT_SET_SW_HIGH);
2793
2794 coex_sta->run_time_state = TRUE;
2795
2796 if (ant_pos_type == BTC_ANT_PATH_AUTO) {
2797 if (board_info->btdm_ant_pos ==
2798 BTC_ANTENNA_AT_MAIN_PORT)
2799 ant_pos_type = BTC_ANT_WIFI_AT_MAIN;
2800 else
2801 ant_pos_type = BTC_ANT_WIFI_AT_AUX;
2802 }
2803
2804 break;
2805 case BT_8821C_2ANT_PHASE_BTMP:
2806 /* Disable LTE Coex Function in WiFi side */
2807 halbtc8821c2ant_ltecoex_enable(btc, 0x0);
2808
2809 /* set Path control owner to WL */
2810 halbtc8821c2ant_coex_ctrl_owner(btc, BT_8821C_2ANT_PCO_WLSIDE);
2811
2812 /* set GNT_BT to SW Hi */
2813 halbtc8821c2ant_set_gnt_bt(btc, BTC_GNT_SET_SW_HIGH);
2814
2815 /* Set GNT_WL to SW Lo */
2816 halbtc8821c2ant_set_gnt_wl(btc, BTC_GNT_SET_SW_LOW);
2817
2818 coex_sta->run_time_state = FALSE;
2819
2820 if (ant_pos_type == BTC_ANT_PATH_AUTO) {
2821 if (board_info->btdm_ant_pos ==
2822 BTC_ANTENNA_AT_MAIN_PORT)
2823 ant_pos_type = BTC_ANT_WIFI_AT_MAIN;
2824 else
2825 ant_pos_type = BTC_ANT_WIFI_AT_AUX;
2826 }
2827
2828 break;
2829 case BT_8821C_2ANT_PHASE_ANTDET:
2830 halbtc8821c2ant_coex_ctrl_owner(btc, BT_8821C_2ANT_PCO_WLSIDE);
2831
2832 /* set GNT_BT to high */
2833 halbtc8821c2ant_set_gnt_bt(btc, BTC_GNT_SET_SW_HIGH);
2834 /* Set GNT_WL to high */
2835 halbtc8821c2ant_set_gnt_wl(btc, BTC_GNT_SET_SW_HIGH);
2836
2837 if (ant_pos_type == BTC_ANT_PATH_AUTO) {
2838 if (board_info->btdm_ant_pos ==
2839 BTC_ANTENNA_AT_MAIN_PORT)
2840 ant_pos_type = BTC_ANT_WIFI_AT_MAIN;
2841 else
2842 ant_pos_type = BTC_ANT_WIFI_AT_AUX;
2843 }
2844
2845 coex_sta->run_time_state = FALSE;
2846 break;
2847 }
2848
2849 if (phase == BT_8821C_2ANT_PHASE_WOFF) {
2850 /* Set Ext Ant Switch to BT control at wifi off step */
2851 ctrl_type = BT_8821C_2ANT_CTRL_BY_BT;
2852 pos_type = BT_8821C_2ANT_TO_NOCARE;
2853 } else {
2854 switch (ant_pos_type) {
2855 default:
2856 case BTC_ANT_WIFI_AT_MAIN:
2857 ctrl_type = BT_8821C_2ANT_CTRL_BY_BBSW;
2858 pos_type = BT_8821C_2ANT_TO_WLG;
2859 break;
2860 case BTC_ANT_WIFI_AT_AUX:
2861 ctrl_type = BT_8821C_2ANT_CTRL_BY_BBSW;
2862 pos_type = BT_8821C_2ANT_TO_BT;
2863 break;
2864 case BTC_ANT_WIFI_AT_DIVERSITY:
2865 ctrl_type = BT_8821C_2ANT_CTRL_BY_ANTDIV;
2866 pos_type = BT_8821C_2ANT_TO_NOCARE;
2867 break;
2868 }
2869 }
2870
2871 halbtc8821c2ant_set_ant_switch(btc, force_exec, ctrl_type, pos_type);
2872
2873 if (btc->dbg_mode) {
2874 u32tmp1 = btc->btc_read_4byte(btc, 0xcbc);
2875 u32tmp2 = btc->btc_read_4byte(btc, 0xcb4);
2876 u8tmp = btc->btc_read_1byte(btc, 0x73);
2877
2878 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
2879 "[BTCoex], (After Ant Setup) 0xcb4 = 0x%x, 0xcbc = 0x%x, 0x73 = 0x%x\n",
2880 u32tmp1, u32tmp2, u8tmp);
2881 BTC_TRACE(trace_buf);
2882 }
2883 }
2884
2885 static
halbtc8821c2ant_action_algorithm(struct btc_coexist * btc)2886 u8 halbtc8821c2ant_action_algorithm(struct btc_coexist *btc)
2887 {
2888 struct btc_bt_link_info *bt_link_info = &btc->bt_link_info;
2889 u8 algorithm = BT_8821C_2ANT_COEX_UNDEFINED;
2890 u8 profile_map = 0;
2891
2892 if (bt_link_info->sco_exist)
2893 profile_map = profile_map | BIT(0);
2894
2895 if (bt_link_info->hid_exist)
2896 profile_map = profile_map | BIT(1);
2897
2898 if (bt_link_info->a2dp_exist)
2899 profile_map = profile_map | BIT(2);
2900
2901 if (bt_link_info->pan_exist)
2902 profile_map = profile_map | BIT(3);
2903
2904 switch (profile_map) {
2905 case 0:
2906 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
2907 "[BTCoex], No BT link exists!!!\n");
2908 BTC_TRACE(trace_buf);
2909 algorithm = BT_8821C_2ANT_COEX_UNDEFINED;
2910 break;
2911 case 1:
2912 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
2913 "[BTCoex], BT Profile = SCO only\n");
2914 BTC_TRACE(trace_buf);
2915 algorithm = BT_8821C_2ANT_COEX_SCO;
2916 break;
2917 case 2:
2918 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
2919 "[BTCoex], BT Profile = HID only\n");
2920 BTC_TRACE(trace_buf);
2921 algorithm = BT_8821C_2ANT_COEX_HID;
2922 break;
2923 case 3:
2924 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
2925 "[BTCoex], BT Profile = SCO + HID ==> HID\n");
2926 BTC_TRACE(trace_buf);
2927 algorithm = BT_8821C_2ANT_COEX_HID;
2928 break;
2929 case 4:
2930 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
2931 "[BTCoex], BT Profile = A2DP only\n");
2932 BTC_TRACE(trace_buf);
2933 algorithm = BT_8821C_2ANT_COEX_A2DP;
2934 break;
2935 case 5:
2936 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
2937 "[BTCoex], BT Profile = SCO + A2DP ==> HID + A2DP\n");
2938 BTC_TRACE(trace_buf);
2939 algorithm = BT_8821C_2ANT_COEX_HID_A2DP;
2940 break;
2941 case 6:
2942 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
2943 "[BTCoex], BT Profile = HID + A2DP\n");
2944 BTC_TRACE(trace_buf);
2945 algorithm = BT_8821C_2ANT_COEX_HID_A2DP;
2946 break;
2947 case 7:
2948 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
2949 "[BTCoex], BT Profile = SCO + HID + A2DP ==> HID + A2DP\n");
2950 BTC_TRACE(trace_buf);
2951 algorithm = BT_8821C_2ANT_COEX_HID_A2DP;
2952 break;
2953 case 8:
2954 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
2955 "[BTCoex], BT Profile = PAN(EDR) only\n");
2956 BTC_TRACE(trace_buf);
2957 algorithm = BT_8821C_2ANT_COEX_PAN;
2958 break;
2959 case 9:
2960 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
2961 "[BTCoex], BT Profile = SCO + PAN(EDR) ==> HID + PAN(EDR)\n");
2962 BTC_TRACE(trace_buf);
2963 algorithm = BT_8821C_2ANT_COEX_PAN_HID;
2964 break;
2965 case 10:
2966 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
2967 "[BTCoex], BT Profile = HID + PAN(EDR)\n");
2968 BTC_TRACE(trace_buf);
2969 algorithm = BT_8821C_2ANT_COEX_PAN_HID;
2970 break;
2971 case 11:
2972 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
2973 "[BTCoex], BT Profile = SCO + HID + PAN(EDR) ==> HID + PAN(EDR)\n");
2974 BTC_TRACE(trace_buf);
2975 algorithm = BT_8821C_2ANT_COEX_PAN_HID;
2976 break;
2977 case 12:
2978 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
2979 "[BTCoex], BT Profile = A2DP + PAN(EDR)\n");
2980 BTC_TRACE(trace_buf);
2981 algorithm = BT_8821C_2ANT_COEX_PAN_A2DP;
2982 break;
2983 case 13:
2984 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
2985 "[BTCoex], BT Profile = SCO + A2DP + PAN(EDR) ==> A2DP + PAN(EDR)\n");
2986 BTC_TRACE(trace_buf);
2987 algorithm = BT_8821C_2ANT_COEX_PAN_A2DP;
2988 break;
2989 case 14:
2990 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
2991 "[BTCoex], BT Profile = HID + A2DP + PAN(EDR) ==> A2DP + PAN(EDR)\n");
2992 BTC_TRACE(trace_buf);
2993 algorithm = BT_8821C_2ANT_COEX_PAN_A2DP;
2994 break;
2995 case 15:
2996 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
2997 "[BTCoex], BT Profile = SCO + HID + A2DP + PAN(EDR) ==> A2DP + PAN(EDR)\n");
2998 BTC_TRACE(trace_buf);
2999 algorithm = BT_8821C_2ANT_COEX_PAN_A2DP;
3000 break;
3001 }
3002
3003 return algorithm;
3004 }
3005
halbtc8821c2ant_action_freerun(struct btc_coexist * btc)3006 static void halbtc8821c2ant_action_freerun(struct btc_coexist *btc)
3007 {
3008 halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8);
3009 halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0);
3010
3011 halbtc8821c2ant_table(btc, NM_EXCU, 0);
3012 halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0);
3013 }
3014
3015 static
halbtc8821c2ant_action_coex_all_off(struct btc_coexist * btc)3016 void halbtc8821c2ant_action_coex_all_off(struct btc_coexist *btc)
3017 {
3018 halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8);
3019 halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0);
3020
3021 halbtc8821c2ant_table(btc, NM_EXCU, 0);
3022 halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0);
3023 }
3024
3025 static
halbtc8821c2ant_action_bt_whql_test(struct btc_coexist * btc)3026 void halbtc8821c2ant_action_bt_whql_test(struct btc_coexist *btc)
3027 {
3028 halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8);
3029 halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0);
3030
3031 halbtc8821c2ant_table(btc, NM_EXCU, 0);
3032 halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0);
3033 }
3034
3035 static
halbtc8821c2ant_action_bt_inquiry(struct btc_coexist * btc)3036 void halbtc8821c2ant_action_bt_inquiry(struct btc_coexist *btc)
3037 {
3038 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
3039 struct btc_bt_link_info *bt_link_info = &btc->bt_link_info;
3040 boolean wifi_connected = FALSE, wifi_busy = FALSE;
3041
3042 halbtc8821c2ant_set_wl_tx_power(btc, FC_EXCU, 0xd8);
3043 halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0);
3044
3045 btc->btc_get(btc, BTC_GET_BL_WIFI_CONNECTED, &wifi_connected);
3046 btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
3047
3048 if (coex_sta->is_wifi_linkscan_process ||
3049 coex_sta->wifi_high_pri_task1 ||
3050 coex_sta->wifi_high_pri_task2) {
3051 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3052 "[BTCoex], bt inq/page + wifi hi-pri task\n");
3053 BTC_TRACE(trace_buf);
3054
3055 halbtc8821c2ant_table(btc, NM_EXCU, 8);
3056
3057 if (bt_link_info->bt_link_exist)
3058 halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 15);
3059 else if (coex_sta->wifi_high_pri_task1)
3060 halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 113);
3061 else if (!coex_sta->bt_create_connection)
3062 halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 10);
3063 else
3064 halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 13);
3065 } else if (wifi_busy) {
3066 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3067 "[BTCoex], bt inq/page + wifi busy\n");
3068 BTC_TRACE(trace_buf);
3069
3070 halbtc8821c2ant_table(btc, NM_EXCU, 8);
3071 halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 151);
3072 } else if (wifi_connected) {
3073 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3074 "[BTCoex], bt inq/page + wifi connected\n");
3075 BTC_TRACE(trace_buf);
3076
3077 halbtc8821c2ant_table(btc, NM_EXCU, 8);
3078 halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 117);
3079 } else {
3080 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3081 "[BTCoex], bt inq/page + wifi not-connected\n");
3082 BTC_TRACE(trace_buf);
3083 halbtc8821c2ant_table(btc, NM_EXCU, 0);
3084 halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0);
3085 }
3086 }
3087
3088 static
halbtc8821c2ant_action_bt_relink(struct btc_coexist * btc)3089 void halbtc8821c2ant_action_bt_relink(struct btc_coexist *btc)
3090 {
3091 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
3092
3093 if (coex_sta->gl_wifi_busy)
3094 halbtc8821c2ant_table(btc, NM_EXCU, 18);
3095 else
3096 halbtc8821c2ant_table(btc, NM_EXCU, 5);
3097
3098 halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0);
3099 }
3100
3101 static
halbtc8821c2ant_action_bt_idle(struct btc_coexist * btc)3102 void halbtc8821c2ant_action_bt_idle(struct btc_coexist *btc)
3103 {
3104 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
3105 struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant;
3106 static u8 prewifi_rssi_state = BTC_RSSI_STATE_LOW;
3107 u8 wifi_rssi_state;
3108
3109 wifi_rssi_state =
3110 halbtc8821c2ant_wifi_rssi_state(btc, &prewifi_rssi_state, 2,
3111 40, 0);
3112
3113 if (!coex_sta->gl_wifi_busy) {
3114 halbtc8821c2ant_table(btc, NM_EXCU, 8);
3115 halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 14);
3116 } else { /* if wl busy */
3117 if ((coex_sta->bt_ble_scan_type & 0x2) &&
3118 coex_dm->bt_status == BT_8821C_2ANT_BSTATUS_NCON_IDLE) {
3119 halbtc8821c2ant_table(btc, NM_EXCU, 14);
3120 halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 12);
3121 } else {
3122 if (BTC_RSSI_HIGH(wifi_rssi_state))
3123 halbtc8821c2ant_table(btc, NM_EXCU, 8);
3124 else
3125 halbtc8821c2ant_table(btc, NM_EXCU, 3);
3126 halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 12);
3127 }
3128 }
3129
3130 halbtc8821c2ant_set_wl_tx_power(btc, FC_EXCU, 0xd8);
3131 halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0);
3132 }
3133
3134 static
halbtc8821c2ant_action_bt_mr(struct btc_coexist * btc)3135 void halbtc8821c2ant_action_bt_mr(struct btc_coexist *btc)
3136 {
3137 struct wifi_link_info_8821c_2ant *wifi_link_info_ext =
3138 &btc->wifi_link_info_8821c_2ant;
3139
3140 if (!wifi_link_info_ext->is_all_under_5g) {
3141 halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, NM_EXCU,
3142 BT_8821C_2ANT_PHASE_2G);
3143
3144 halbtc8821c2ant_table(btc, NM_EXCU, 0);
3145 halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0);
3146 } else {
3147 halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, NM_EXCU,
3148 BT_8821C_2ANT_PHASE_5G);
3149
3150 halbtc8821c2ant_table(btc, NM_EXCU, 0);
3151 halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0);
3152 }
3153 }
3154
3155 static
halbtc8821c2ant_action_sco(struct btc_coexist * btc)3156 void halbtc8821c2ant_action_sco(struct btc_coexist *btc)
3157 {
3158 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
3159
3160 halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8);
3161 halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0);
3162
3163 if (coex_sta->is_bt_multi_link) {
3164 halbtc8821c2ant_table(btc, NM_EXCU, 8);
3165 halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 25);
3166 } else {
3167 if (coex_sta->is_esco_mode)
3168 halbtc8821c2ant_table(btc, NM_EXCU, 1);
3169 else /* 2-Ant free run if SCO mode */
3170 halbtc8821c2ant_table(btc, NM_EXCU, 0);
3171
3172 halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 8);
3173 }
3174 }
3175
3176 static
halbtc8821c2ant_action_hid(struct btc_coexist * btc)3177 void halbtc8821c2ant_action_hid(struct btc_coexist *btc)
3178 {
3179 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
3180 boolean wifi_busy = FALSE;
3181
3182 btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
3183
3184 halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8);
3185 halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0);
3186
3187 if (coex_sta->is_hid_low_pri_tx_overhead) {
3188 halbtc8821c2ant_table(btc, NM_EXCU, 12);
3189 halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 108);
3190 } else if (coex_sta->is_hid_rcu) {
3191 halbtc8821c2ant_table(btc, NM_EXCU, 12);
3192
3193 if (wifi_busy)
3194 halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 113);
3195 else
3196 halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 111);
3197 } else {
3198 halbtc8821c2ant_table(btc, NM_EXCU, 12);
3199 halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 111);
3200 }
3201 }
3202
3203 static
halbtc8821c2ant_action_a2dpsink(struct btc_coexist * btc)3204 void halbtc8821c2ant_action_a2dpsink(struct btc_coexist *btc)
3205 {
3206 boolean ap_enable = FALSE;
3207
3208 if (btc->wifi_link_info.link_mode == BTC_LINK_ONLY_GO &&
3209 btc->wifi_link_info.bhotspot &&
3210 btc->wifi_link_info.bany_client_join_go)
3211 ap_enable = TRUE;
3212
3213 halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8);
3214 halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0);
3215
3216 if (ap_enable) {
3217 halbtc8821c2ant_table(btc, NM_EXCU, 0);
3218 halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0);
3219 } else {
3220 halbtc8821c2ant_table(btc, NM_EXCU, 8);
3221 halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 104);
3222 }
3223 }
3224
3225 static
halbtc8821c2ant_action_a2dp(struct btc_coexist * btc)3226 void halbtc8821c2ant_action_a2dp(struct btc_coexist *btc)
3227 {
3228 static u8 prewifi_rssi_state = BTC_RSSI_STATE_LOW;
3229 u8 wifi_rssi_state;
3230 boolean wifi_busy = FALSE;
3231
3232 btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
3233
3234 wifi_rssi_state =
3235 halbtc8821c2ant_wifi_rssi_state(btc, &prewifi_rssi_state, 2,
3236 45, 0);
3237
3238 halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8);
3239 halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0);
3240
3241 halbtc8821c2ant_table(btc, NM_EXCU, 8);
3242
3243 if (!wifi_busy)
3244 halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 120 | TDMA_4SLOT);
3245 else if (BTC_RSSI_HIGH(wifi_rssi_state))
3246 halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 119 | TDMA_4SLOT);
3247 else
3248 halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 101 | TDMA_4SLOT);
3249 }
3250
3251 static
halbtc8821c2ant_action_pan(struct btc_coexist * btc)3252 void halbtc8821c2ant_action_pan(struct btc_coexist *btc)
3253 {
3254 boolean wifi_busy = FALSE;
3255
3256 static u8 prewifi_rssi_state = BTC_RSSI_STATE_LOW;
3257 u8 wifi_rssi_state;
3258
3259 btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
3260
3261 wifi_rssi_state =
3262 halbtc8821c2ant_wifi_rssi_state(btc, &prewifi_rssi_state, 2,
3263 58, 0);
3264
3265 halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8);
3266 halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0);
3267
3268 /* for Lenovo CPT_For_WiFi OPP test */
3269 if (btc->board_info.customer_id == RT_CID_LENOVO_CHINA &&
3270 BTC_RSSI_HIGH(wifi_rssi_state) && wifi_busy) {
3271 halbtc8821c2ant_table(btc, NM_EXCU, 8);
3272
3273 halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 103);
3274 } else {
3275 halbtc8821c2ant_table(btc, NM_EXCU, 8);
3276
3277 if (wifi_busy)
3278 halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 103);
3279 else
3280 halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 104);
3281 }
3282 }
3283
3284 static
halbtc8821c2ant_action_hid_a2dp(struct btc_coexist * btc)3285 void halbtc8821c2ant_action_hid_a2dp(struct btc_coexist *btc)
3286 {
3287 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
3288 static u8 prewifi_rssi_state = BTC_RSSI_STATE_LOW;
3289 u8 wifi_rssi_state;
3290 u32 slot_type = 0;
3291
3292 wifi_rssi_state =
3293 halbtc8821c2ant_wifi_rssi_state(btc, &prewifi_rssi_state, 2,
3294 45, 0);
3295
3296 halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8);
3297 halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0);
3298
3299 /*BLE HID should use 2-slot to avoid HID lag issue (COEX-357)*/
3300 if (!coex_sta->bt_ble_hid_exist)
3301 slot_type = TDMA_4SLOT;
3302
3303 halbtc8821c2ant_table(btc, NM_EXCU, 12);
3304
3305 if (BTC_RSSI_HIGH(wifi_rssi_state))
3306 halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 119 | slot_type);
3307 else
3308 halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 109 | slot_type);
3309 }
3310
3311 static
halbtc8821c2ant_action_pan_a2dp(struct btc_coexist * btc)3312 void halbtc8821c2ant_action_pan_a2dp(struct btc_coexist *btc)
3313 {
3314 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
3315 static u8 prewifi_rssi_state = BTC_RSSI_STATE_LOW;
3316 u8 wifi_rssi_state;
3317 boolean wifi_busy = FALSE;
3318 u8 iot_peer = BTC_IOT_PEER_UNKNOWN;
3319
3320 btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
3321 btc->btc_get(btc, BTC_GET_U1_IOT_PEER, &iot_peer);
3322
3323 if (!wifi_busy)
3324 wifi_busy = coex_sta->gl_wifi_busy;
3325
3326 wifi_rssi_state =
3327 halbtc8821c2ant_wifi_rssi_state(btc, &prewifi_rssi_state, 2,
3328 42, 0);
3329
3330 halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8);
3331
3332 /* for Lenovo coex test case */
3333 if (btc->board_info.customer_id == RT_CID_LENOVO_CHINA &&
3334 coex_sta->scan_ap_num <= 10 &&
3335 iot_peer == BTC_IOT_PEER_ATHEROS) {
3336 /* for CPT_for_WiFi */
3337 if (BTC_RSSI_LOW(wifi_rssi_state)) {
3338 halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 20);
3339 if (wifi_busy) {
3340 halbtc8821c2ant_table(btc, NM_EXCU, 7);
3341 halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 110);
3342 } else {
3343 halbtc8821c2ant_table(btc, NM_EXCU, 7);
3344 halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 107);
3345 }
3346 } else { /* for CPT_for_BT */
3347 halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0);
3348 halbtc8821c2ant_table(btc, NM_EXCU, 8);
3349 halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 116);
3350 }
3351 } else {
3352 halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0);
3353 halbtc8821c2ant_table(btc, NM_EXCU, 8);
3354
3355 if (wifi_busy)
3356 halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 107);
3357 else
3358 halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 106);
3359 }
3360 }
3361
3362 static
halbtc8821c2ant_action_pan_hid(struct btc_coexist * btc)3363 void halbtc8821c2ant_action_pan_hid(struct btc_coexist *btc)
3364 {
3365 boolean wifi_busy = FALSE;
3366
3367 btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
3368
3369 halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8);
3370 halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0);
3371
3372 halbtc8821c2ant_table(btc, NM_EXCU, 8);
3373
3374 if (wifi_busy)
3375 halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 103);
3376 else
3377 halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 104);
3378 }
3379
3380 static
halbtc8821c2ant_action_hid_a2dp_pan(struct btc_coexist * btc)3381 void halbtc8821c2ant_action_hid_a2dp_pan(struct btc_coexist *btc)
3382 {
3383 boolean wifi_busy = FALSE;
3384
3385 btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
3386
3387 halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8);
3388 halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0);
3389
3390 halbtc8821c2ant_table(btc, NM_EXCU, 12);
3391
3392 if (wifi_busy)
3393 halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 107);
3394 else
3395 halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 106);
3396 }
3397
3398 static
halbtc8821c2ant_action_wifi_under5g(struct btc_coexist * btc)3399 void halbtc8821c2ant_action_wifi_under5g(struct btc_coexist *btc)
3400 {
3401 halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8);
3402 halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0);
3403
3404 halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, NM_EXCU,
3405 BT_8821C_2ANT_PHASE_5G);
3406 /* fw all off */
3407 halbtc8821c2ant_table(btc, NM_EXCU, 0);
3408 halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0);
3409 }
3410
3411 static
halbtc8821c2ant_action_wifi_native_lps(struct btc_coexist * btc)3412 void halbtc8821c2ant_action_wifi_native_lps(struct btc_coexist *btc)
3413 {
3414 halbtc8821c2ant_table(btc, NM_EXCU, 4);
3415 halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0);
3416 }
3417
3418 static
halbtc8821c2ant_action_wifi_linkscan(struct btc_coexist * btc)3419 void halbtc8821c2ant_action_wifi_linkscan(struct btc_coexist *btc)
3420 {
3421 struct btc_bt_link_info *bt_link_info = &btc->bt_link_info;
3422
3423 halbtc8821c2ant_set_wl_tx_power(btc, FC_EXCU, 0xd8);
3424 halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0);
3425
3426 halbtc8821c2ant_table(btc, NM_EXCU, 8);
3427
3428 if (bt_link_info->pan_exist)
3429 halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 22);
3430 else if (bt_link_info->a2dp_exist)
3431 halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 16);
3432 else
3433 halbtc8821c2ant_tdma(btc, NM_EXCU, TRUE, 21);
3434 }
3435
3436 static
halbtc8821c2ant_action_wifi_not_connected(struct btc_coexist * btc)3437 void halbtc8821c2ant_action_wifi_not_connected(struct btc_coexist *btc)
3438 {
3439 halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8);
3440 halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0);
3441
3442 halbtc8821c2ant_table(btc, NM_EXCU, 0);
3443 halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0);
3444 }
3445
3446 static
halbtc8821c2ant_action_wifi_connected(struct btc_coexist * btc)3447 void halbtc8821c2ant_action_wifi_connected(struct btc_coexist *btc)
3448 {
3449 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
3450 struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant;
3451
3452 coex_dm->cur_algorithm = halbtc8821c2ant_action_algorithm(btc);
3453
3454 if (halbtc8821c2ant_freerun_check(btc)) {
3455 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3456 "[BTCoex], Action 2-Ant, Frerun().\n");
3457 BTC_TRACE(trace_buf);
3458 halbtc8821c2ant_action_freerun(btc);
3459 return;
3460 }
3461
3462 switch (coex_dm->cur_algorithm) {
3463 case BT_8821C_2ANT_COEX_SCO:
3464 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3465 "[BTCoex], Action 2-Ant, algorithm = SCO.\n");
3466 BTC_TRACE(trace_buf);
3467 halbtc8821c2ant_action_sco(btc);
3468 break;
3469 case BT_8821C_2ANT_COEX_HID:
3470 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3471 "[BTCoex], Action 2-Ant, algorithm = HID.\n");
3472 BTC_TRACE(trace_buf);
3473 halbtc8821c2ant_action_hid(btc);
3474 break;
3475 case BT_8821C_2ANT_COEX_A2DP:
3476 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3477 "[BTCoex], Action 2-Ant, algorithm = A2DP.\n");
3478 BTC_TRACE(trace_buf);
3479
3480 /* for A2DP + OPP test but BTinfo is
3481 * A2DP only in Lenovo test case
3482 */
3483 if (coex_sta->is_bt_multi_link && coex_sta->hid_pair_cnt == 0)
3484 halbtc8821c2ant_action_pan_a2dp(btc);
3485 else if (coex_sta->is_bt_a2dp_sink)
3486 halbtc8821c2ant_action_a2dpsink(btc);
3487 else
3488 halbtc8821c2ant_action_a2dp(btc);
3489 break;
3490 case BT_8821C_2ANT_COEX_PAN:
3491 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3492 "[BTCoex], Action 2-Ant, algorithm = PAN(EDR).\n");
3493 BTC_TRACE(trace_buf);
3494 halbtc8821c2ant_action_pan(btc);
3495 break;
3496 case BT_8821C_2ANT_COEX_PAN_A2DP:
3497 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3498 "[BTCoex], Action 2-Ant, algorithm = PAN+A2DP.\n");
3499 BTC_TRACE(trace_buf);
3500 halbtc8821c2ant_action_pan_a2dp(btc);
3501 break;
3502 case BT_8821C_2ANT_COEX_PAN_HID:
3503 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3504 "[BTCoex], Action 2-Ant, algorithm = PAN(EDR)+HID.\n");
3505 BTC_TRACE(trace_buf);
3506 halbtc8821c2ant_action_pan_hid(btc);
3507 break;
3508 case BT_8821C_2ANT_COEX_HID_A2DP_PAN:
3509 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3510 "[BTCoex], Action 2-Ant, algorithm = HID+A2DP+PAN.\n");
3511 BTC_TRACE(trace_buf);
3512 halbtc8821c2ant_action_hid_a2dp_pan(btc);
3513 break;
3514 case BT_8821C_2ANT_COEX_HID_A2DP:
3515 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3516 "[BTCoex], Action 2-Ant, algorithm = HID+A2DP.\n");
3517 BTC_TRACE(trace_buf);
3518 halbtc8821c2ant_action_hid_a2dp(btc);
3519 break;
3520 default:
3521 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3522 "[BTCoex], Action 2-Ant, algorithm = coexist All Off!!\n");
3523 BTC_TRACE(trace_buf);
3524 halbtc8821c2ant_action_coex_all_off(btc);
3525 break;
3526 }
3527 }
3528
3529 static
halbtc8821c2ant_action_wifi_multiport25g(struct btc_coexist * btc)3530 void halbtc8821c2ant_action_wifi_multiport25g(struct btc_coexist *btc)
3531 {
3532 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
3533
3534 halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8);
3535 halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0);
3536
3537 halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_BTCQDDR, TRUE);
3538
3539 if (coex_sta->is_setup_link || coex_sta->bt_relink_downcount != 0) {
3540 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3541 "[BTCoex], wifi_multiport25g(), BT Relink!!\n");
3542 BTC_TRACE(trace_buf);
3543
3544 halbtc8821c2ant_table(btc, NM_EXCU, 0);
3545 halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0);
3546 } else if (coex_sta->c2h_bt_inquiry_page) {
3547 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3548 "[BTCoex], wifi_multiport25g(), BT Inq-Page!!\n");
3549 BTC_TRACE(trace_buf);
3550
3551 halbtc8821c2ant_table(btc, NM_EXCU, 11);
3552 halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0);
3553 } else {
3554 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3555 "[BTCoex], wifi_multiport25g(), BT idle or busy!!\n");
3556 BTC_TRACE(trace_buf);
3557
3558 halbtc8821c2ant_table(btc, NM_EXCU, 11);
3559 halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0);
3560 }
3561 }
3562
3563 static
halbtc8821c2ant_action_wifi_multiport2g(struct btc_coexist * btc)3564 void halbtc8821c2ant_action_wifi_multiport2g(struct btc_coexist *btc)
3565 {
3566 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
3567 struct btc_concurrent_setting multiport_tdma_para;
3568 u32 traffic_dir;
3569
3570 btc->btc_get(btc, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, &traffic_dir);
3571
3572 halbtc8821c2ant_set_wl_tx_power(btc, NM_EXCU, 0xd8);
3573 halbtc8821c2ant_set_bt_tx_power(btc, NM_EXCU, 0);
3574
3575 halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_BTCQDDR, TRUE);
3576
3577 if (coex_sta->is_setup_link || coex_sta->bt_relink_downcount != 0) {
3578 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3579 "[BTCoex], wifi_multiport2g, BT Relink!!\n");
3580 BTC_TRACE(trace_buf);
3581
3582 halbtc8821c2ant_table(btc, NM_EXCU, 0);
3583 halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0);
3584 } else if (coex_sta->c2h_bt_inquiry_page) {
3585 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3586 "[BTCoex], wifi_multiport2g, BT Inq-Page!!\n");
3587 BTC_TRACE(trace_buf);
3588
3589 halbtc8821c2ant_table(btc, NM_EXCU, 0);
3590 halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0);
3591 } else if (coex_sta->num_of_profile == 0) {
3592 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3593 "[BTCoex], wifi_multiport2g, BT idle!!\n");
3594 BTC_TRACE(trace_buf);
3595
3596 if (btc->chip_interface == BTC_INTF_PCI &&
3597 (btc->wifi_link_info.link_mode == BTC_LINK_ONLY_GO ||
3598 btc->wifi_link_info.link_mode == BTC_LINK_ONLY_GC))
3599 halbtc8821c2ant_table(btc, NM_EXCU, 10);
3600 else
3601 halbtc8821c2ant_table(btc, NM_EXCU, 0);
3602
3603 halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0);
3604 } else if (coex_sta->is_wifi_linkscan_process) {
3605 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3606 "[BTCoex], wifi_multiport2g, WL scan!!\n");
3607 BTC_TRACE(trace_buf);
3608
3609 halbtc8821c2ant_action_wifi_linkscan(btc);
3610 } else {
3611 switch (btc->wifi_link_info.link_mode) {
3612 case BTC_LINK_ONLY_GO:
3613 case BTC_LINK_ONLY_GC:
3614 if (btc->chip_interface == BTC_INTF_PCI &&
3615 coex_sta->a2dp_exist && !coex_sta->is_bt_multi_link)
3616 halbtc8821c2ant_table(btc, NM_EXCU, 10);
3617 else
3618 halbtc8821c2ant_table(btc, NM_EXCU, 0);
3619 halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0);
3620 break;
3621 default:
3622 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3623 "[BTCoex], wifi_multiport2g, Other multi-port + BT busy!!\n");
3624 BTC_TRACE(trace_buf);
3625
3626 halbtc8821c2ant_table(btc, NM_EXCU, 0);
3627 halbtc8821c2ant_tdma(btc, NM_EXCU, FALSE, 0);
3628 break;
3629 }
3630 }
3631 }
3632
3633 static
halbtc8821c2ant_run_coex(struct btc_coexist * btc,u8 reason)3634 void halbtc8821c2ant_run_coex(struct btc_coexist *btc, u8 reason)
3635 {
3636 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
3637 struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant;
3638 struct wifi_link_info_8821c_2ant *wifi_link_info_ext =
3639 &btc->wifi_link_info_8821c_2ant;
3640 boolean wifi_connected = FALSE, wifi_32k = FALSE;
3641 boolean scan = FALSE, link = FALSE, roam = FALSE, under_4way = FALSE;
3642
3643 btc->btc_get(btc, BTC_GET_BL_WIFI_SCAN, &scan);
3644 btc->btc_get(btc, BTC_GET_BL_WIFI_LINK, &link);
3645 btc->btc_get(btc, BTC_GET_BL_WIFI_ROAM, &roam);
3646 btc->btc_get(btc, BTC_GET_BL_WIFI_4_WAY_PROGRESS, &under_4way);
3647 btc->btc_get(btc, BTC_GET_BL_WIFI_CONNECTED, &wifi_connected);
3648 btc->btc_get(btc, BTC_GET_BL_WIFI_LW_PWR_STATE, &wifi_32k);
3649
3650 if (scan || link || roam || under_4way ||
3651 reason == BT_8821C_2ANT_RSN_2GSCANSTART ||
3652 reason == BT_8821C_2ANT_RSN_2GSWITCHBAND ||
3653 reason == BT_8821C_2ANT_RSN_2GCONSTART ||
3654 reason == BT_8821C_2ANT_RSN_2GSPECIALPKT) {
3655 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3656 "[BTCoex], scan = %d, link = %d, roam = %d 4way = %d!!!\n",
3657 scan, link, roam, under_4way);
3658 BTC_TRACE(trace_buf);
3659 coex_sta->is_wifi_linkscan_process = TRUE;
3660 } else {
3661 coex_sta->is_wifi_linkscan_process = FALSE;
3662 }
3663
3664 /* update wifi_link_info_ext variable */
3665 halbtc8821c2ant_update_wifi_link_info(btc, reason);
3666
3667 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3668 "[BTCoex], RunCoexistMechanism()===> reason = %d\n",
3669 reason);
3670 BTC_TRACE(trace_buf);
3671
3672 coex_sta->coex_run_reason = reason;
3673
3674 if (btc->manual_control) {
3675 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3676 "[BTCoex], RunCoexistMechanism(), return for Manual CTRL <===\n");
3677 BTC_TRACE(trace_buf);
3678 return;
3679 }
3680
3681 if (btc->stop_coex_dm) {
3682 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3683 "[BTCoex], RunCoexistMechanism(), return for Stop Coex DM <===\n");
3684 BTC_TRACE(trace_buf);
3685 return;
3686 }
3687
3688 if (coex_sta->under_ips) {
3689 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3690 "[BTCoex], RunCoexistMechanism(), return for wifi is under IPS !!!\n");
3691 BTC_TRACE(trace_buf);
3692 return;
3693 }
3694
3695 if (coex_sta->under_lps && wifi_32k) {
3696 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3697 "[BTCoex], RunCoexistMechanism(), return for wifi is under LPS-32K !!!\n");
3698 BTC_TRACE(trace_buf);
3699 return;
3700 }
3701
3702 if (!coex_sta->run_time_state) {
3703 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3704 "[BTCoex], return for run_time_state = FALSE !!!\n");
3705 BTC_TRACE(trace_buf);
3706 return;
3707 }
3708
3709 if (coex_sta->freeze_coexrun_by_btinfo && !coex_sta->is_setup_link) {
3710 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3711 "[BTCoex], return for freeze_coexrun_by_btinfo\n");
3712 BTC_TRACE(trace_buf);
3713 return;
3714 }
3715
3716 coex_sta->coex_run_cnt++;
3717
3718 if (coex_sta->msft_mr_exist && wifi_connected) {
3719 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3720 "[BTCoex], RunCoexistMechanism(), microsoft MR!!\n");
3721 BTC_TRACE(trace_buf);
3722
3723 coex_sta->wl_coex_mode = BT_8821C_2ANT_WLINK_BTMR;
3724 halbtc8821c2ant_action_bt_mr(btc);
3725 return;
3726 }
3727
3728 if (wifi_link_info_ext->is_all_under_5g) {
3729 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3730 "[BTCoex], WiFi is under 5G!!!\n");
3731 BTC_TRACE(trace_buf);
3732
3733 coex_sta->wl_coex_mode = BT_8821C_2ANT_WLINK_5G;
3734 halbtc8821c2ant_action_wifi_under5g(btc);
3735 return;
3736 }
3737
3738 if (wifi_link_info_ext->is_mcc_25g) { /* not iclude scan action */
3739 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3740 "[BTCoex], WiFi is under mcc dual-band!!!\n");
3741 BTC_TRACE(trace_buf);
3742
3743 coex_sta->wl_coex_mode = BT_8821C_2ANT_WLINK_25GMPORT;
3744 halbtc8821c2ant_action_wifi_multiport25g(btc);
3745 return;
3746 }
3747
3748 if (wifi_link_info_ext->num_of_active_port > 1 ||
3749 (btc->wifi_link_info.link_mode == BTC_LINK_ONLY_GO &&
3750 !btc->wifi_link_info.bhotspot &&
3751 btc->wifi_link_info.bany_client_join_go)) {
3752 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3753 "[BTCoex], WiFi is under scc-2g/mcc-2g/p2pGO-only!!!\n");
3754 BTC_TRACE(trace_buf);
3755
3756 if (btc->wifi_link_info.link_mode == BTC_LINK_ONLY_GO)
3757 coex_sta->wl_coex_mode = BT_8821C_2ANT_WLINK_2GGO;
3758 else
3759 coex_sta->wl_coex_mode = BT_8821C_2ANT_WLINK_2GMPORT;
3760 halbtc8821c2ant_action_wifi_multiport2g(btc);
3761 return;
3762 }
3763
3764 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3765 "[BTCoex], WiFi is single-port 2G!!!\n");
3766 BTC_TRACE(trace_buf);
3767
3768 coex_sta->wl_coex_mode = BT_8821C_2ANT_WLINK_2G1PORT;
3769
3770 halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, NM_EXCU,
3771 BT_8821C_2ANT_PHASE_2G);
3772
3773 /*For Asus airpods 2 + HID glitch issue*/
3774 if (coex_sta->bt_a2dp_vendor_id == 0x4c && coex_sta->is_bt_multi_link)
3775 halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_BTCQDDR,
3776 FALSE);
3777 else
3778 halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_BTCQDDR,
3779 TRUE);
3780
3781 if (coex_sta->bt_disabled) {
3782 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3783 "[BTCoex], BT is disabled !!!\n");
3784 BTC_TRACE(trace_buf);
3785 halbtc8821c2ant_action_coex_all_off(btc);
3786 return;
3787 }
3788
3789 if (coex_sta->under_lps && !coex_sta->force_lps_ctrl &&
3790 !coex_sta->acl_busy) {
3791 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3792 "[BTCoex], RunCoexistMechanism(), wifi is under LPS !!!\n");
3793 BTC_TRACE(trace_buf);
3794 halbtc8821c2ant_action_wifi_native_lps(btc);
3795 return;
3796 }
3797
3798 if (coex_sta->bt_whck_test) {
3799 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3800 "[BTCoex], BT is under WHCK TEST!!!\n");
3801 BTC_TRACE(trace_buf);
3802 halbtc8821c2ant_action_bt_whql_test(btc);
3803 return;
3804 }
3805
3806 if (coex_sta->is_setup_link || coex_sta->bt_relink_downcount != 0) {
3807 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3808 "[BTCoex], BT is re-link !!!\n");
3809 BTC_TRACE(trace_buf);
3810 halbtc8821c2ant_action_bt_relink(btc);
3811 return;
3812 }
3813
3814 if (coex_sta->c2h_bt_inquiry_page) {
3815 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3816 "[BTCoex], BT is under inquiry/page scan !!\n");
3817 BTC_TRACE(trace_buf);
3818 halbtc8821c2ant_action_bt_inquiry(btc);
3819 return;
3820 }
3821
3822 if ((coex_dm->bt_status == BT_8821C_2ANT_BSTATUS_NCON_IDLE ||
3823 coex_dm->bt_status == BT_8821C_2ANT_BSTATUS_CON_IDLE) &&
3824 wifi_link_info_ext->is_connected) {
3825 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3826 "############# [BTCoex], BT Is idle\n");
3827 BTC_TRACE(trace_buf);
3828 halbtc8821c2ant_action_bt_idle(btc);
3829 return;
3830 }
3831
3832 if (coex_sta->is_wifi_linkscan_process) {
3833 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3834 "[BTCoex], wifi is under linkscan process!!\n");
3835 BTC_TRACE(trace_buf);
3836 halbtc8821c2ant_action_wifi_linkscan(btc);
3837 return;
3838 }
3839
3840 if (wifi_connected) {
3841 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3842 "[BTCoex], wifi is under connected!!\n");
3843 BTC_TRACE(trace_buf);
3844
3845 halbtc8821c2ant_action_wifi_connected(btc);
3846 } else {
3847 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3848 "[BTCoex], wifi is under not-connected!!\n");
3849 BTC_TRACE(trace_buf);
3850
3851 halbtc8821c2ant_action_wifi_not_connected(btc);
3852 }
3853 }
3854
halbtc8821c2ant_init_coex_var(struct btc_coexist * btc)3855 static void halbtc8821c2ant_init_coex_var(struct btc_coexist *btc)
3856 {
3857 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
3858
3859 /* Reset Coex variable */
3860 btc->btc_set(btc, BTC_SET_RESET_COEX_VAR, NULL);
3861
3862 coex_sta->bt_reg_vendor_ac = 0xffff;
3863 coex_sta->bt_reg_vendor_ae = 0xffff;
3864
3865 coex_sta->isolation_btween_wb = BT_8821C_2ANT_DEFAULT_ISOLATION;
3866 btc->bt_info.bt_get_fw_ver = 0;
3867 }
3868
3869 static
halbtc8821c2ant_init_coex_dm(struct btc_coexist * btc)3870 void halbtc8821c2ant_init_coex_dm(struct btc_coexist *btc)
3871 {
3872 }
3873
3874 static
halbtc8821c2ant_init_hw_config(struct btc_coexist * btc,boolean wifi_only)3875 void halbtc8821c2ant_init_hw_config(struct btc_coexist *btc, boolean wifi_only)
3876 {
3877 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
3878 u8 u8tmp = 0;
3879 u32 vendor;
3880 u32 u32tmp0 = 0, u32tmp1 = 0, u32tmp2 = 0, u32tmp3 = 0;
3881 u8 i;
3882
3883 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], %s()!\n", __func__);
3884 BTC_TRACE(trace_buf);
3885
3886 #if 0
3887 u32tmp3 = btc->btc_read_4byte(btc, 0xcb4);
3888 u32tmp1 = halbtc8821c2ant_read_indirect_reg(btc, 0x38);
3889 u32tmp2 = halbtc8821c2ant_read_indirect_reg(btc, 0x54);
3890
3891 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3892 "[BTCoex], (Before Init HW config) 0xcb4 = 0x%x, 0x38= 0x%x, 0x54= 0x%x\n",
3893 u32tmp3, u32tmp1, u32tmp2);
3894 BTC_TRACE(trace_buf);
3895 #endif
3896
3897 halbtc8821c2ant_init_coex_var(btc);
3898
3899 /* 0xf0[15:12] --> kt_ver */
3900 coex_sta->kt_ver = (btc->btc_read_1byte(btc, 0xf1) & 0xf0) >> 4;
3901
3902 halbtc8821c2ant_coex_switch_thres(btc, coex_sta->isolation_btween_wb);
3903 /* enable TBTT nterrupt */
3904 btc->btc_write_1byte_bitmask(btc, 0x550, 0x8, 0x1);
3905
3906 /* BT report packet sample rate */
3907 btc->btc_write_1byte(btc, 0x790, 0x5);
3908
3909 /* Init 0x778 = 0x1 for 2-Ant */
3910 btc->btc_write_1byte(btc, 0x778, 0x1);
3911
3912 /* Enable PTA (3-wire function form BT side) */
3913 btc->btc_write_1byte_bitmask(btc, 0x40, 0x20, 0x1);
3914 btc->btc_write_1byte_bitmask(btc, 0x41, 0x02, 0x1);
3915
3916 /* Enable PTA (tx/rx signal form WiFi side) */
3917 btc->btc_write_1byte_bitmask(btc, 0x4c6, 0x30, 0x1);
3918
3919 /* set GNT_BT=1 for coex table select both */
3920 btc->btc_write_1byte_bitmask(btc, 0x763, 0x10, 0x1);
3921
3922 halbtc8821c2ant_enable_gnt_to_gpio(btc, TRUE);
3923
3924 /* Enable counter statistics */
3925 /* 0x76e[3] =1, WLAN_Act control by PTA */
3926 btc->btc_write_1byte(btc, 0x76e, 0x4);
3927
3928 if (btc->wl_rf_state_off) {
3929 halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, FC_EXCU,
3930 BT_8821C_2ANT_PHASE_WOFF);
3931 halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_ALL, FALSE);
3932 btc->stop_coex_dm = TRUE;
3933 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3934 "[BTCoex], %s: RF Off\n", __func__);
3935 BTC_TRACE(trace_buf);
3936 } else if (wifi_only) {
3937 coex_sta->concurrent_rx_mode_on = FALSE;
3938 /* Path config */
3939 /* Set Antenna Path */
3940 halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, FC_EXCU,
3941 BT_8821C_2ANT_PHASE_WONLY);
3942 halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_ACTIVE |
3943 BT_8821C_2ANT_SCBD_ONOFF,
3944 TRUE);
3945 btc->stop_coex_dm = TRUE;
3946 } else {
3947 coex_sta->concurrent_rx_mode_on = TRUE;
3948 /* btc->btc_write_1byte_bitmask(btc, 0x953, 0x2, 0x1); */
3949
3950 /* RF 0x1[1] = 0->Set GNT_WL_RF_Rx always = 1
3951 * for con-current Rx, mask Tx only
3952 */
3953 btc->btc_set_rf_reg(btc, BTC_RF_A, 0x1, 0x2, 0x0);
3954
3955 /* Set Antenna Path */
3956 halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, FC_EXCU,
3957 BT_8821C_2ANT_PHASE_INIT);
3958 halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_ACTIVE |
3959 BT_8821C_2ANT_SCBD_ONOFF,
3960 TRUE);
3961 btc->stop_coex_dm = FALSE;
3962 }
3963
3964 halbtc8821c2ant_table(btc, FC_EXCU, 0);
3965 halbtc8821c2ant_tdma(btc, FC_EXCU, FALSE, 0);
3966
3967 halbtc8821c2ant_query_bt_info(btc);
3968 }
3969
ex_halbtc8821c2ant_power_on_setting(struct btc_coexist * btc)3970 void ex_halbtc8821c2ant_power_on_setting(struct btc_coexist *btc)
3971 {
3972 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
3973 struct btc_board_info *board_info = &btc->board_info;
3974 u8 u8tmp = 0x0;
3975 u16 u16tmp = 0x0;
3976
3977 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
3978 "[BTCoex], Execute %s !!\n", __func__);
3979 BTC_TRACE(trace_buf);
3980
3981 btc->stop_coex_dm = TRUE;
3982 btc->wl_rf_state_off = FALSE;
3983
3984 /* enable BB, REG_SYS_FUNC_EN such that
3985 * we can write BB Register correctly.
3986 */
3987 u16tmp = btc->btc_read_2byte(btc, 0x2);
3988 btc->btc_write_2byte(btc, 0x2, u16tmp | BIT(0) | BIT(1));
3989
3990 /* Local setting bit define
3991 * BIT0: "0" for no antenna inverse; "1" for antenna inverse
3992 * BIT1: "0" for internal switch; "1" for external switch
3993 * BIT2: "0" for one antenna; "1" for two antenna
3994 * NOTE: here default all internal switch and 1-antenna
3995 * ==> BIT1=0 and BIT2=0
3996 */
3997
3998 /* Check efuse 0xc3[6] for Single Antenna Path */
3999 if (board_info->single_ant_path == 0) {
4000 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
4001 "[BTCoex], Single Antenna, Antenna at Aux Port\n");
4002 BTC_TRACE(trace_buf);
4003
4004 board_info->btdm_ant_pos = BTC_ANTENNA_AT_AUX_PORT;
4005 u8tmp = 7;
4006 } else if (board_info->single_ant_path == 1) {
4007 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
4008 "[BTCoex], Single Antenna, Antenna at Main Port\n");
4009 BTC_TRACE(trace_buf);
4010
4011 board_info->btdm_ant_pos = BTC_ANTENNA_AT_MAIN_PORT;
4012 u8tmp = 6;
4013 }
4014
4015 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
4016 "[BTCoex], (Power On) single_ant_path = %d, btdm_ant_pos = %d\n",
4017 board_info->single_ant_path , board_info->btdm_ant_pos);
4018 BTC_TRACE(trace_buf);
4019
4020 /* Setup RF front end type */
4021 halbtc8821c2ant_set_rfe_type(btc);
4022
4023 /* Set Antenna Path to BT side */
4024 halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, FC_EXCU,
4025 BT_8821C_2ANT_PHASE_POWERON);
4026
4027 halbtc8821c2ant_table(btc, FC_EXCU, 0);
4028
4029 /* Save"single antenna position" info in Local register setting
4030 * for FW reading, because FW may not ready at power on
4031 */
4032 if (btc->chip_interface == BTC_INTF_PCI)
4033 btc->btc_write_local_reg_1byte(btc, 0x3e0, u8tmp);
4034 else if (btc->chip_interface == BTC_INTF_USB)
4035 btc->btc_write_local_reg_1byte(btc, 0xfe08, u8tmp);
4036 else if (btc->chip_interface == BTC_INTF_SDIO)
4037 btc->btc_write_local_reg_1byte(btc, 0x60, u8tmp);
4038
4039 /* enable GNT_WL/GNT_BT debug signal to GPIO14/15 */
4040 halbtc8821c2ant_enable_gnt_to_gpio(btc, TRUE);
4041
4042 if (btc->dbg_mode) {
4043 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
4044 "[BTCoex], LTE coex Reg 0x38 (Power-On) = 0x%x\n",
4045 halbtc8821c2ant_read_indirect_reg(btc, 0x38));
4046 BTC_TRACE(trace_buf);
4047
4048 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
4049 "[BTCoex], MACReg 0x70/ BBReg 0xcb4 (Power-On) = 0x%x/ 0x%x\n",
4050 btc->btc_read_4byte(btc, 0x70),
4051 btc->btc_read_4byte(btc, 0xcb4));
4052 BTC_TRACE(trace_buf);
4053 }
4054 }
4055
ex_halbtc8821c2ant_pre_load_firmware(struct btc_coexist * btc)4056 void ex_halbtc8821c2ant_pre_load_firmware(struct btc_coexist *btc)
4057 {
4058 struct btc_board_info *board_info = &btc->board_info;
4059 u8 u8tmp = 0x4; /* Set BIT2 by default since it's 2ant case */
4060
4061 /* S0 or S1 setting and Local register setting
4062 *(By the setting fw can get ant number, S0/S1, ... info)
4063 * Local setting bit define
4064 * BIT0: "0" for no antenna inverse; "1" for antenna inverse
4065 * BIT1: "0" for internal switch; "1" for external switch
4066 * BIT2: "0" for one antenna; "1" for two antenna
4067 * NOTE: here default all internal switch
4068 * and 1-antenna ==> BIT1=0 and BIT2=0
4069 */
4070 if (btc->chip_interface == BTC_INTF_USB) {
4071 /* fixed at S0 for USB interface */
4072 u8tmp |= 0x1; /* antenna inverse */
4073 btc->btc_write_local_reg_1byte(btc, 0xfe08, u8tmp);
4074 } else {
4075 /* for PCIE and SDIO interface, we check efuse 0xc3[6] */
4076 if (board_info->single_ant_path == 0) {
4077 } else if (board_info->single_ant_path == 1) {
4078 /* set to S0 */
4079 u8tmp |= 0x1; /* antenna inverse */
4080 }
4081
4082 if (btc->chip_interface == BTC_INTF_PCI)
4083 btc->btc_write_local_reg_1byte(btc, 0x3e0, u8tmp);
4084 else if (btc->chip_interface == BTC_INTF_SDIO)
4085 btc->btc_write_local_reg_1byte(btc, 0x60, u8tmp);
4086 }
4087 }
4088
4089
ex_halbtc8821c2ant_init_hw_config(struct btc_coexist * btc,boolean wifi_only)4090 void ex_halbtc8821c2ant_init_hw_config(struct btc_coexist *btc,
4091 boolean wifi_only)
4092 {
4093 halbtc8821c2ant_init_hw_config(btc, wifi_only);
4094 }
4095
ex_halbtc8821c2ant_init_coex_dm(struct btc_coexist * btc)4096 void ex_halbtc8821c2ant_init_coex_dm(struct btc_coexist *btc)
4097 {
4098 btc->stop_coex_dm = FALSE;
4099 btc->auto_report = TRUE;
4100 btc->dbg_mode = FALSE;
4101 halbtc8821c2ant_init_coex_dm(btc);
4102 }
4103
ex_halbtc8821c2ant_display_simple_coex_info(struct btc_coexist * btc)4104 void ex_halbtc8821c2ant_display_simple_coex_info(struct btc_coexist *btc)
4105 {
4106 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
4107 struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant;
4108 struct btc_board_info *board_info = &btc->board_info;
4109 struct btc_bt_link_info *bt_link_info = &btc->bt_link_info;
4110
4111 u8 *cli_buf = btc->cli_buf;
4112 u32 bt_patch_ver = 0, bt_coex_ver = 0;
4113 static u8 cnt;
4114 u8 * const p = &coex_sta->bt_afh_map[0];
4115
4116 if (!coex_sta->bt_disabled &&
4117 (coex_sta->bt_coex_supported_version == 0 ||
4118 coex_sta->bt_coex_supported_version == 0xffff) &&
4119 cnt == 0) {
4120 btc->btc_get(btc, BTC_GET_U4_SUPPORTED_FEATURE,
4121 &coex_sta->bt_coex_supported_feature);
4122
4123 btc->btc_get(btc, BTC_GET_U4_SUPPORTED_VERSION,
4124 &coex_sta->bt_coex_supported_version);
4125
4126 coex_sta->bt_reg_vendor_ac = (u16)(btc->btc_get_bt_reg(btc, 3,
4127 0xac) &
4128 0xffff);
4129
4130 coex_sta->bt_reg_vendor_ae = (u16)(btc->btc_get_bt_reg(btc, 3,
4131 0xae) &
4132 0xffff);
4133
4134 btc->btc_get(btc, BTC_GET_U4_BT_PATCH_VER, &bt_patch_ver);
4135 btc->bt_info.bt_get_fw_ver = bt_patch_ver;
4136
4137 if (coex_sta->num_of_profile > 0)
4138 btc->btc_get_bt_afh_map_from_bt(btc, 0, p);
4139 }
4140
4141 if (++cnt >= 3)
4142 cnt = 0;
4143
4144 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4145 "\r\n _____[BT Coexist info]____");
4146 CL_PRINTF(cli_buf);
4147
4148 if (btc->manual_control) {
4149 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4150 "\r\n __[Under Manual Control]_");
4151 CL_PRINTF(cli_buf);
4152 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4153 "\r\n _________________________");
4154 CL_PRINTF(cli_buf);
4155 }
4156
4157 if (btc->stop_coex_dm) {
4158 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4159 "\r\n ____[Coex is STOPPED]____");
4160 CL_PRINTF(cli_buf);
4161 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4162 "\r\n _________________________");
4163 CL_PRINTF(cli_buf);
4164 }
4165
4166 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4167 "\r\n %-35s = %d/ %d/ %s / 0x%x",
4168 "Ant PG Num/ Mech/ Pos/ RFE",
4169 board_info->pg_ant_num, board_info->btdm_ant_num,
4170 (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT
4171 ? "Main" : "Aux"),
4172 board_info->rfe_type);
4173 CL_PRINTF(cli_buf);
4174
4175 bt_coex_ver = (coex_sta->bt_coex_supported_version & 0xff);
4176 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4177 "\r\n %-35s = %d_%02x/ 0x%02x/ 0x%02x (%s)",
4178 "CoexVer WL/ BT_Desired/ BT_Report",
4179 glcoex_ver_date_8821c_2ant, glcoex_ver_8821c_2ant,
4180 glcoex_ver_btdesired_8821c_2ant,
4181 bt_coex_ver,
4182 (bt_coex_ver == 0xff ? "Unknown" :
4183 (coex_sta->bt_disabled ? "BT-disable" :
4184 (bt_coex_ver >= glcoex_ver_btdesired_8821c_2ant ?
4185 "Match" : "Mis-Match"))));
4186 CL_PRINTF(cli_buf);
4187
4188 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s ", "BT status",
4189 ((coex_sta->bt_disabled) ? ("disabled") :
4190 ((coex_sta->c2h_bt_inquiry_page) ? ("inquiry/page")
4191 : ((BT_8821C_2ANT_BSTATUS_NCON_IDLE ==
4192 coex_dm->bt_status) ? "non-connected idle" :
4193 ((BT_8821C_2ANT_BSTATUS_CON_IDLE ==
4194 coex_dm->bt_status) ? "connected-idle" : "busy")))));
4195 CL_PRINTF(cli_buf);
4196
4197 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d",
4198 "0x770(Hi-pri rx/tx)",
4199 coex_sta->high_priority_rx, coex_sta->high_priority_tx);
4200 CL_PRINTF(cli_buf);
4201
4202 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d %s",
4203 "0x774(Lo-pri rx/tx)",
4204 coex_sta->low_priority_rx, coex_sta->low_priority_tx,
4205 (bt_link_info->slave_role ? "(Slave!!)" : " "));
4206 CL_PRINTF(cli_buf);
4207 }
4208
ex_halbtc8821c2ant_display_coex_info(struct btc_coexist * btc)4209 void ex_halbtc8821c2ant_display_coex_info(struct btc_coexist *btc)
4210 {
4211 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
4212 struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant;
4213 struct btc_board_info *board_info = &btc->board_info;
4214 struct btc_bt_link_info *bt_link_info = &btc->bt_link_info;
4215
4216 u8 *cli_buf = btc->cli_buf;
4217 u8 u8tmp[4], i, ps_tdma_case = 0;
4218 u32 u32tmp[4];
4219 u16 u16tmp[4];
4220 u32 fa_ofdm, fa_cck, cca_ofdm, cca_cck;
4221 u32 fw_ver = 0, bt_patch_ver = 0, bt_coex_ver = 0;
4222 static u8 pop_report_in_10s;
4223 u32 phyver = 0, val = 0;
4224 boolean lte_coex_on = FALSE, is_bt_reply = FALSE;
4225 static u8 cnt;
4226 u32 ratio_crc, cnt_ok, cnt_err;
4227 u8 * const p = &coex_sta->bt_afh_map[0];
4228
4229 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4230 "\r\n ============[BT Coexist info 8821C]============");
4231 CL_PRINTF(cli_buf);
4232
4233 if (btc->manual_control) {
4234 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4235 "\r\n ============[Under Manual Control]============");
4236 CL_PRINTF(cli_buf);
4237 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4238 "\r\n ==========================================");
4239 CL_PRINTF(cli_buf);
4240 } else if (btc->stop_coex_dm) {
4241 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4242 "\r\n ============[Coex is STOPPED]============");
4243 CL_PRINTF(cli_buf);
4244 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4245 "\r\n ==========================================");
4246 CL_PRINTF(cli_buf);
4247 } else if (!coex_sta->run_time_state) {
4248 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4249 "\r\n ============[Run Time State = False]============");
4250 CL_PRINTF(cli_buf);
4251 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4252 "\r\n ==========================================");
4253 CL_PRINTF(cli_buf);
4254 } else if (coex_sta->freeze_coexrun_by_btinfo) {
4255 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4256 "\r\n ============[freeze_coexrun_by_btinfo]============");
4257 CL_PRINTF(cli_buf);
4258 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4259 "\r\n ==========================================");
4260 CL_PRINTF(cli_buf);
4261 }
4262
4263 if (!coex_sta->bt_disabled && cnt == 0) {
4264 if (coex_sta->bt_coex_supported_version == 0 ||
4265 coex_sta->bt_coex_supported_version == 0xffff) {
4266 btc->btc_get(btc, BTC_GET_U4_SUPPORTED_VERSION,
4267 &coex_sta->bt_coex_supported_version);
4268
4269 if (coex_sta->bt_coex_supported_version > 0 &&
4270 coex_sta->bt_coex_supported_version < 0xffff)
4271 is_bt_reply = TRUE;
4272 } else {
4273 is_bt_reply = TRUE;
4274 }
4275
4276 if (coex_sta->num_of_profile > 0)
4277 btc->btc_get_bt_afh_map_from_bt(btc, 0, p);
4278 }
4279
4280 if (is_bt_reply) {
4281 if (coex_sta->bt_coex_supported_feature == 0)
4282 btc->btc_get(btc, BTC_GET_U4_SUPPORTED_FEATURE,
4283 &coex_sta->bt_coex_supported_feature);
4284
4285 if (coex_sta->bt_reg_vendor_ac == 0xffff) {
4286 val = btc->btc_get_bt_reg(btc, 3, 0xac);
4287 coex_sta->bt_reg_vendor_ac = (u16)(val & 0xffff);
4288 }
4289
4290 if (coex_sta->bt_reg_vendor_ae == 0xffff) {
4291 val = btc->btc_get_bt_reg(btc, 3, 0xae);
4292 coex_sta->bt_reg_vendor_ae = (u16)(val & 0xffff);
4293 }
4294
4295 if (btc->bt_info.bt_get_fw_ver == 0) {
4296 btc->btc_get(btc, BTC_GET_U4_BT_PATCH_VER,
4297 &bt_patch_ver);
4298 btc->bt_info.bt_get_fw_ver = bt_patch_ver;
4299 }
4300 }
4301
4302 if (++cnt >= 3)
4303 cnt = 0;
4304
4305 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4306 "\r\n %-35s = %d/ %s/ %s / 0x%x",
4307 "Ant PG Num/ Mech/ Pos/ RFE",
4308 board_info->pg_ant_num,
4309 (board_info->btdm_ant_num == 1 ? "Shared" : "Non-Shared"),
4310 (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT
4311 ? "Main" : "Aux"),
4312 board_info->rfe_type);
4313 CL_PRINTF(cli_buf);
4314
4315 bt_patch_ver = btc->bt_info.bt_get_fw_ver;
4316 btc->btc_get(btc, BTC_GET_U4_WIFI_FW_VER, &fw_ver);
4317 phyver = btc->btc_get_bt_phydm_version(btc);
4318 bt_coex_ver = (coex_sta->bt_coex_supported_version & 0xff);
4319
4320 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4321 "\r\n %-35s = %d_%02x/ 0x%02x/ 0x%02x (%s)",
4322 "CoexVer WL/ BT_Desired/ BT_Report",
4323 glcoex_ver_date_8821c_2ant, glcoex_ver_8821c_2ant,
4324 glcoex_ver_btdesired_8821c_2ant,
4325 bt_coex_ver,
4326 (bt_coex_ver == 0xff ? "Unknown" :
4327 (coex_sta->bt_disabled ? "BT-disable" :
4328 (bt_coex_ver >= glcoex_ver_btdesired_8821c_2ant ?
4329 "Match" : "Mis-Match"))));
4330 CL_PRINTF(cli_buf);
4331
4332 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4333 "\r\n %-35s = 0x%x(%s)/ 0x%x/ v%d/ %c",
4334 "W_FW/ B_FW/ Phy/ Kt", fw_ver,
4335 (fw_ver >= glcoex_ver_wldesired_8821c_2ant ?
4336 "Match" :
4337 "Mis-Match"),
4338 bt_patch_ver, phyver, coex_sta->kt_ver + 65);
4339 CL_PRINTF(cli_buf);
4340
4341 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4342 "\r\n %-35s = %02x %02x %02x (RF-Ch = %d)",
4343 "AFH Map to BT",
4344 coex_dm->wifi_chnl_info[0], coex_dm->wifi_chnl_info[1],
4345 coex_dm->wifi_chnl_info[2], coex_sta->wl_center_channel);
4346 CL_PRINTF(cli_buf);
4347
4348 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d / %d ",
4349 "Isolation/WL_Thres/BT_Thres",
4350 coex_sta->isolation_btween_wb,
4351 coex_sta->wifi_coex_thres,
4352 coex_sta->bt_coex_thres);
4353 CL_PRINTF(cli_buf);
4354
4355 /* wifi status */
4356 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s",
4357 "============[Wifi Status]============");
4358 CL_PRINTF(cli_buf);
4359 btc->btc_disp_dbg_msg(btc, BTC_DBG_DISP_WIFI_STATUS);
4360
4361 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s",
4362 "============[BT Status]============");
4363 CL_PRINTF(cli_buf);
4364
4365 pop_report_in_10s++;
4366 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4367 "\r\n %-35s = %s/ %ddBm/ %d/ %d",
4368 "BT status/ rssi/ retryCnt/ popCnt",
4369 ((coex_sta->bt_disabled) ? ("disabled") : ((
4370 coex_sta->c2h_bt_inquiry_page) ? ("inquiry-page")
4371 : ((BT_8821C_2ANT_BSTATUS_NCON_IDLE ==
4372 coex_dm->bt_status) ? "non-connected-idle" :
4373 ((coex_dm->bt_status == BT_8821C_2ANT_BSTATUS_CON_IDLE)
4374 ? "connected-idle" : "busy")))),
4375 coex_sta->bt_rssi - 100, coex_sta->bt_retry_cnt,
4376 coex_sta->pop_event_cnt);
4377 CL_PRINTF(cli_buf);
4378
4379 if (pop_report_in_10s >= 5) {
4380 coex_sta->pop_event_cnt = 0;
4381 pop_report_in_10s = 0;
4382 }
4383
4384 if (coex_sta->num_of_profile != 0)
4385 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4386 "\r\n %-35s = %s%s%s%s%s%s (multilink = %d)",
4387 "Profiles", ((bt_link_info->a2dp_exist) ?
4388 ((coex_sta->is_bt_a2dp_sink) ? "A2DP sink," :
4389 "A2DP,") : ""),
4390 ((bt_link_info->sco_exist) ? "HFP," : ""),
4391 ((bt_link_info->hid_exist) ?
4392 ((coex_sta->is_hid_rcu) ? "HID(RCU)" :
4393 ((coex_sta->hid_busy_num >= 2) ? "HID(4/18)," :
4394 (coex_sta->bt_ble_hid_exist ? "HID(BLE)" :
4395 "HID(2/18),"))) : ""), ((bt_link_info->pan_exist) ?
4396 ((coex_sta->is_bt_opp_exist) ? "OPP," : "PAN,") :
4397 ""), ((coex_sta->voice_over_HOGP) ? "Voice," : ""),
4398 ((coex_sta->msft_mr_exist) ? "MR" : ""),
4399 coex_sta->is_bt_multi_link);
4400 else
4401 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4402 "\r\n %-35s = %s", "Profiles",
4403 (coex_sta->msft_mr_exist) ? "MR" : "None");
4404
4405 CL_PRINTF(cli_buf);
4406
4407 if (bt_link_info->a2dp_exist) {
4408 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4409 "\r\n %-35s = %s/ %d/ 0x%x/ 0x%x/ %d",
4410 "CQDDR/Bitpool/V_ID/D_name/Flush",
4411 ((coex_sta->is_A2DP_3M) ? "On" : "Off"),
4412 coex_sta->a2dp_bit_pool,
4413 coex_sta->bt_a2dp_vendor_id,
4414 coex_sta->bt_a2dp_device_name,
4415 coex_sta->bt_a2dp_flush_time);
4416 CL_PRINTF(cli_buf);
4417 }
4418
4419 if (bt_link_info->hid_exist) {
4420 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d",
4421 "HID PairNum",
4422 coex_sta->hid_pair_cnt);
4423 CL_PRINTF(cli_buf);
4424 }
4425
4426 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/ %d/ %s/ 0x%x",
4427 "Role/RoleSwCnt/IgnWlact/Feature",
4428 ((bt_link_info->slave_role) ? "Slave" : "Master"),
4429 coex_sta->cnt_role_switch,
4430 ((coex_dm->cur_ignore_wlan_act) ? "Yes" : "No"),
4431 coex_sta->bt_coex_supported_feature);
4432 CL_PRINTF(cli_buf);
4433
4434 if (coex_sta->is_ble_scan_en) {
4435 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4436 "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x",
4437 "BLEScan Type/TV/Init/Ble",
4438 coex_sta->bt_ble_scan_type,
4439 (coex_sta->bt_ble_scan_type & 0x1 ?
4440 coex_sta->bt_ble_scan_para[0] : 0x0),
4441 (coex_sta->bt_ble_scan_type & 0x2 ?
4442 coex_sta->bt_ble_scan_para[1] : 0x0),
4443 (coex_sta->bt_ble_scan_type & 0x4 ?
4444 coex_sta->bt_ble_scan_para[2] : 0x0));
4445 CL_PRINTF(cli_buf);
4446 }
4447
4448 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4449 "\r\n %-35s = %d/ %d/ %d/ %d/ %d %s",
4450 "ReInit/ReLink/IgnWlact/Page/NameReq", coex_sta->cnt_reinit,
4451 coex_sta->cnt_setup_link, coex_sta->cnt_ign_wlan_act,
4452 coex_sta->cnt_page, coex_sta->cnt_remote_name_req,
4453 (coex_sta->is_setup_link ? "(Relink!!)" : ""));
4454 CL_PRINTF(cli_buf);
4455
4456 halbtc8821c2ant_read_scbd(btc, &u16tmp[0]);
4457
4458 if (coex_sta->bt_reg_vendor_ae == 0xffff ||
4459 coex_sta->bt_reg_vendor_ac == 0xffff)
4460 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4461 "\r\n %-35s = x/ x/ 0x%04x",
4462 "0xae[4]/0xac[1:0]/ScBd(B->W)", u16tmp[0]);
4463 else
4464 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4465 "\r\n %-35s = 0x%x/ 0x%x/ 0x%04x",
4466 "0xae[4]/0xac[1:0]/ScBd(B->W)",
4467 (int)((coex_sta->bt_reg_vendor_ae & BIT(4)) >> 4),
4468 coex_sta->bt_reg_vendor_ac & 0x3, u16tmp[0]);
4469 CL_PRINTF(cli_buf);
4470
4471 if (coex_sta->num_of_profile > 0) {
4472 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4473 "\r\n %-35s = %02x%02x%02x%02x %02x%02x%02x%02x %02x%02x",
4474 "AFH MAP",
4475 coex_sta->bt_afh_map[0],
4476 coex_sta->bt_afh_map[1],
4477 coex_sta->bt_afh_map[2],
4478 coex_sta->bt_afh_map[3],
4479 coex_sta->bt_afh_map[4],
4480 coex_sta->bt_afh_map[5],
4481 coex_sta->bt_afh_map[6],
4482 coex_sta->bt_afh_map[7],
4483 coex_sta->bt_afh_map[8],
4484 coex_sta->bt_afh_map[9]);
4485 CL_PRINTF(cli_buf);
4486 }
4487
4488 for (i = 0; i < BT_8821C_2ANT_INFO_SRC_MAX; i++) {
4489 if (coex_sta->bt_info_c2h_cnt[i]) {
4490 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4491 "\r\n %-35s = %02x %02x %02x %02x %02x %02x %02x (%d)",
4492 glbt_info_src_8821c_2ant[i],
4493 coex_sta->bt_info_c2h[i][0],
4494 coex_sta->bt_info_c2h[i][1],
4495 coex_sta->bt_info_c2h[i][2],
4496 coex_sta->bt_info_c2h[i][3],
4497 coex_sta->bt_info_c2h[i][4],
4498 coex_sta->bt_info_c2h[i][5],
4499 coex_sta->bt_info_c2h[i][6],
4500 coex_sta->bt_info_c2h_cnt[i]);
4501 CL_PRINTF(cli_buf);
4502 }
4503 }
4504
4505 /* Sw mechanism */
4506 if (btc->manual_control)
4507 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s",
4508 "============[mechanism] (before Manual)============");
4509 else
4510 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s",
4511 "============[Mechanism]============");
4512
4513 CL_PRINTF(cli_buf);
4514
4515 ps_tdma_case = coex_dm->cur_ps_tdma;
4516 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4517 "\r\n %-35s = %02x %02x %02x %02x %02x (case-%d, %s, Timer:%d)",
4518 "TDMA",
4519 coex_dm->ps_tdma_para[0], coex_dm->ps_tdma_para[1],
4520 coex_dm->ps_tdma_para[2], coex_dm->ps_tdma_para[3],
4521 coex_dm->ps_tdma_para[4], ps_tdma_case,
4522 (coex_dm->cur_ps_tdma_on ? "On" : "Off"),
4523 coex_sta->tdma_timer_base);
4524 CL_PRINTF(cli_buf);
4525
4526 switch (coex_sta->wl_coex_mode) {
4527 case BT_8821C_2ANT_WLINK_2G1PORT:
4528 default:
4529 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4530 "\r\n %-35s = %s", "Coex_Mode", "2G-SP");
4531 break;
4532 case BT_8821C_2ANT_WLINK_2GMPORT:
4533 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4534 "\r\n %-35s = %s", "Coex_Mode", "2G-MP");
4535 break;
4536 case BT_8821C_2ANT_WLINK_25GMPORT:
4537 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4538 "\r\n %-35s = %s", "Coex_Mode", "25G-MP");
4539 break;
4540 case BT_8821C_2ANT_WLINK_5G:
4541 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4542 "\r\n %-35s = %s", "Coex_Mode", "5G");
4543 break;
4544 case BT_8821C_2ANT_WLINK_2GGO:
4545 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4546 "\r\n %-35s = %s", "Coex_Mode", "2G-P2P");
4547 break;
4548 case BT_8821C_2ANT_WLINK_BTMR:
4549 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4550 "\r\n %-35s = %s", "Coex_Mode", "BT-MR");
4551 break;
4552 }
4553 CL_PRINTF(cli_buf);
4554
4555 u32tmp[0] = btc->btc_read_4byte(btc, 0x6c0);
4556 u32tmp[1] = btc->btc_read_4byte(btc, 0x6c4);
4557 u32tmp[2] = btc->btc_read_4byte(btc, 0x6c8);
4558 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4559 "\r\n %-35s = %d/ 0x%x/ 0x%x/ 0x%x",
4560 "Table/0x6c0/0x6c4/0x6c8",
4561 coex_sta->coex_table_type, u32tmp[0], u32tmp[1], u32tmp[2]);
4562 CL_PRINTF(cli_buf);
4563
4564 u8tmp[0] = btc->btc_read_1byte(btc, 0x778);
4565 u32tmp[0] = btc->btc_read_4byte(btc, 0x6cc);
4566 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4567 "\r\n %-35s = 0x%x/ 0x%x/ 0x%04x/ %d/ %d",
4568 "0x778/0x6cc/ScBd(W->B)/RunCnt/Rsn", u8tmp[0], u32tmp[0],
4569 coex_sta->score_board_WB, coex_sta->coex_run_cnt,
4570 coex_sta->coex_run_reason);
4571 CL_PRINTF(cli_buf);
4572
4573 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/ %s/ %s/ %d/ %d",
4574 "AntDiv/BtCtrlLPS/LPRA/PsFail/g_busy",
4575 ((board_info->ant_div_cfg) ?
4576 ((coex_dm->cur_antdiv_type) ? "On(Hw)" : "On(Sw)") : "Off"),
4577 ((coex_sta->force_lps_ctrl) ? "On" : "Off"),
4578 ((coex_dm->cur_low_penalty_ra) ? "On" : "Off"),
4579 coex_sta->cnt_set_ps_state_fail,
4580 coex_sta->gl_wifi_busy);
4581 CL_PRINTF(cli_buf);
4582
4583 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x",
4584 "WL_Pwr/ BT_Pwr", coex_dm->cur_wl_pwr_lvl,
4585 coex_dm->cur_bt_pwr_lvl);
4586 CL_PRINTF(cli_buf);
4587
4588 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d/ %d/ %d",
4589 "Null All/Retry/Ack/BT_Empty/BT_Late",
4590 coex_sta->wl_fw_dbg_info[1],
4591 coex_sta->wl_fw_dbg_info[2],
4592 coex_sta->wl_fw_dbg_info[3],
4593 coex_sta->wl_fw_dbg_info[4],
4594 coex_sta->wl_fw_dbg_info[5]);
4595 CL_PRINTF(cli_buf);
4596
4597 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %s/ %d",
4598 "cnt TDMA_Togg/LK5ms/LK5ms_off/fw",
4599 coex_sta->wl_fw_dbg_info[6], coex_sta->wl_fw_dbg_info[7],
4600 ((coex_sta->is_no_wl_5ms_extend) ? "Yes" : "No"),
4601 coex_sta->cnt_wl_fw_notify);
4602 CL_PRINTF(cli_buf);
4603
4604 u32tmp[0] = halbtc8821c2ant_read_indirect_reg(btc, 0x38);
4605 lte_coex_on = ((u32tmp[0] & BIT(7)) >> 7) ? TRUE : FALSE;
4606
4607 if (lte_coex_on) {
4608 u32tmp[0] = halbtc8821c2ant_read_indirect_reg(btc, 0xa0);
4609 u32tmp[1] = halbtc8821c2ant_read_indirect_reg(btc, 0xa4);
4610 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x",
4611 "LTE Coex Table W_L/B_L", u32tmp[0] & 0xffff,
4612 u32tmp[1] & 0xffff);
4613 CL_PRINTF(cli_buf);
4614
4615 u32tmp[0] = halbtc8821c2ant_read_indirect_reg(btc, 0xa8);
4616 u32tmp[1] = halbtc8821c2ant_read_indirect_reg(btc, 0xac);
4617 u32tmp[2] = halbtc8821c2ant_read_indirect_reg(btc, 0xb0);
4618 u32tmp[3] = halbtc8821c2ant_read_indirect_reg(btc, 0xb4);
4619 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4620 "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x",
4621 "LTE Break Table W_L/B_L/L_W/L_B",
4622 u32tmp[0] & 0xffff, u32tmp[1] & 0xffff,
4623 u32tmp[2] & 0xffff, u32tmp[3] & 0xffff);
4624 CL_PRINTF(cli_buf);
4625 }
4626
4627 /* Hw setting */
4628 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s",
4629 "============[Hw setting]============");
4630 CL_PRINTF(cli_buf);
4631
4632 u32tmp[0] = halbtc8821c2ant_read_indirect_reg(btc, 0x38);
4633 u32tmp[1] = halbtc8821c2ant_read_indirect_reg(btc, 0x54);
4634 u8tmp[0] = btc->btc_read_1byte(btc, 0x73);
4635
4636 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/ %s",
4637 "LTE Coex/Path Owner",
4638 ((lte_coex_on) ? "On" : "Off") ,
4639 ((u8tmp[0] & BIT(2)) ? "WL" : "BT"));
4640 CL_PRINTF(cli_buf);
4641
4642 if (lte_coex_on) {
4643 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4644 "\r\n %-35s = %d/ %d/ %d/ %d",
4645 "LTE 3Wire/OPMode/UART/UARTMode",
4646 (int)((u32tmp[0] & BIT(6)) >> 6),
4647 (int)((u32tmp[0] & (BIT(5) | BIT(4))) >> 4),
4648 (int)((u32tmp[0] & BIT(3)) >> 3),
4649 (int)(u32tmp[0] & (BIT(2) | BIT(1) | BIT(0))));
4650 CL_PRINTF(cli_buf);
4651
4652 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d",
4653 "LTE_Busy/UART_Busy",
4654 (int)((u32tmp[1] & BIT(1)) >> 1),
4655 (int)(u32tmp[1] & BIT(0)));
4656 CL_PRINTF(cli_buf);
4657 }
4658 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4659 "\r\n %-35s = %s (BB:%s)/ %s (BB:%s)/ %s (gnt_err = %d)",
4660 "GNT_WL_Ctrl/GNT_BT_Ctrl/Dbg",
4661 ((u32tmp[0] & BIT(12)) ? "SW" : "HW"),
4662 ((u32tmp[0] & BIT(8)) ? "SW" : "HW"),
4663 ((u32tmp[0] & BIT(14)) ? "SW" : "HW"),
4664 ((u32tmp[0] & BIT(10)) ? "SW" : "HW"),
4665 ((u8tmp[0] & BIT(3)) ? "On" : "Off"),
4666 coex_sta->gnt_error_cnt);
4667 CL_PRINTF(cli_buf);
4668
4669 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ 0x%x",
4670 "GNT_WL/GNT_BT/ RF_0x1",
4671 (int)((u32tmp[1] & BIT(2)) >> 2),
4672 (int)((u32tmp[1] & BIT(3)) >> 3),
4673 btc->btc_get_rf_reg(btc, BTC_RF_A, 0x1, 0xfffff));
4674 CL_PRINTF(cli_buf);
4675
4676 u32tmp[0] = btc->btc_read_4byte(btc, 0xcb0);
4677 u32tmp[1] = btc->btc_read_4byte(btc, 0xcb4);
4678 u8tmp[0] = btc->btc_read_1byte(btc, 0xcba);
4679
4680 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4681 "\r\n %-35s = 0x%04x/ 0x%04x/ 0x%02x %s",
4682 "0xcb0/0xcb4/0xcb8[23:16]",
4683 u32tmp[0], u32tmp[1], u8tmp[0],
4684 ((u8tmp[0] & 0x1) == 0x1 ? "(BTG)" : "(WL_A+G)"));
4685 CL_PRINTF(cli_buf);
4686
4687 u32tmp[0] = btc->btc_read_4byte(btc, 0x430);
4688 u32tmp[1] = btc->btc_read_4byte(btc, 0x434);
4689 u16tmp[0] = btc->btc_read_2byte(btc, 0x42a);
4690 u8tmp[0] = btc->btc_read_1byte(btc, 0x426);
4691 u8tmp[1] = btc->btc_read_1byte(btc, 0x45e);
4692 u8tmp[2] = btc->btc_read_1byte(btc, 0x455);
4693 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4694 "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x/ 0x%x/ 0x%x",
4695 "430/434/42a/426/45e[3]/455",
4696 u32tmp[0], u32tmp[1], u16tmp[0], u8tmp[0],
4697 (int)((u8tmp[1] & BIT(3)) >> 3), u8tmp[2]);
4698 CL_PRINTF(cli_buf);
4699
4700 u32tmp[0] = btc->btc_read_4byte(btc, 0x4c);
4701 u8tmp[2] = btc->btc_read_1byte(btc, 0x64);
4702 u8tmp[0] = btc->btc_read_1byte(btc, 0x4c6);
4703 u8tmp[1] = btc->btc_read_1byte(btc, 0x40);
4704
4705 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4706 "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x",
4707 "4c[24:23]/64[0]/4c6[4]/40[5]",
4708 (int)(u32tmp[0] & (BIT(24) | BIT(23))) >> 23,
4709 u8tmp[2] & 0x1, (int)((u8tmp[0] & BIT(4)) >> 4),
4710 (int)((u8tmp[1] & BIT(5)) >> 5));
4711 CL_PRINTF(cli_buf);
4712
4713 u32tmp[0] = btc->btc_read_4byte(btc, 0x550);
4714 u8tmp[0] = btc->btc_read_1byte(btc, 0x522);
4715 u8tmp[1] = btc->btc_read_1byte(btc, 0x953);
4716 u8tmp[2] = btc->btc_read_1byte(btc, 0xc50);
4717
4718 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4719 "\r\n %-35s = 0x%x/ 0x%x/ %s/ 0x%x",
4720 "0x550/0x522/4-RxAGC/0xc50", u32tmp[0], u8tmp[0],
4721 (u8tmp[1] & 0x2) ? "On" : "Off", u8tmp[2]);
4722 CL_PRINTF(cli_buf);
4723
4724 fa_ofdm = btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_FA_OFDM);
4725 fa_cck = btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_FA_CCK);
4726 cca_ofdm = btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_CCA_OFDM);
4727 cca_cck = btc->btc_phydm_query_PHY_counter(btc, PHYDM_INFO_CCA_CCK);
4728
4729 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4730 "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x",
4731 "CCK-CCA/CCK-FA/OFDM-CCA/OFDM-FA",
4732 cca_cck, fa_cck, cca_ofdm, fa_ofdm);
4733 CL_PRINTF(cli_buf);
4734
4735 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d/ %d",
4736 "CRC_OK CCK/11g/11n/11ac",
4737 coex_sta->crc_ok_cck, coex_sta->crc_ok_11g,
4738 coex_sta->crc_ok_11n, coex_sta->crc_ok_11n_vht);
4739 CL_PRINTF(cli_buf);
4740
4741 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d/ %d",
4742 "CRC_Err CCK/11g/11n/11ac",
4743 coex_sta->crc_err_cck, coex_sta->crc_err_11g,
4744 coex_sta->crc_err_11n, coex_sta->crc_err_11n_vht);
4745 CL_PRINTF(cli_buf);
4746
4747 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
4748 "\r\n %-35s = %d/ %d/ %s-%d/ %d (Tx macid: %d)",
4749 "Rate RxD/RxRTS/TxD/TxRetry_ratio",
4750 coex_sta->wl_rx_rate, coex_sta->wl_rts_rx_rate,
4751 (coex_sta->wl_tx_rate & 0x80 ? "SGI" : "LGI"),
4752 coex_sta->wl_tx_rate & 0x7f,
4753 coex_sta->wl_tx_retry_ratio,
4754 coex_sta->wl_tx_macid);
4755 CL_PRINTF(cli_buf);
4756
4757 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/ %s/ %s/ %s/ %d",
4758 "HiPr/ Locking/ warn/ Locked/ Noisy",
4759 (coex_sta->wifi_high_pri_task1 ? "Yes" : "No"),
4760 (coex_sta->cck_lock ? "Yes" : "No"),
4761 (coex_sta->cck_lock_warn ? "Yes" : "No"),
4762 (coex_sta->cck_lock_ever ? "Yes" : "No"),
4763 coex_sta->wl_noisy_level);
4764 CL_PRINTF(cli_buf);
4765
4766 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d",
4767 "0x770(Hi-pri rx/tx)",
4768 coex_sta->high_priority_rx, coex_sta->high_priority_tx);
4769 CL_PRINTF(cli_buf);
4770
4771 CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d %s",
4772 "0x774(Lo-pri rx/tx)",
4773 coex_sta->low_priority_rx, coex_sta->low_priority_tx,
4774 (bt_link_info->slave_role ? "(Slave!!)" : " "));
4775 CL_PRINTF(cli_buf);
4776
4777 btc->btc_disp_dbg_msg(btc, BTC_DBG_DISP_COEX_STATISTICS);
4778 }
4779
ex_halbtc8821c2ant_ips_notify(struct btc_coexist * btc,u8 type)4780 void ex_halbtc8821c2ant_ips_notify(struct btc_coexist *btc, u8 type)
4781 {
4782 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
4783
4784 if (btc->manual_control || btc->stop_coex_dm)
4785 return;
4786
4787 if (type == BTC_IPS_ENTER) {
4788 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
4789 "[BTCoex], IPS ENTER notify\n");
4790 BTC_TRACE(trace_buf);
4791 coex_sta->under_ips = TRUE;
4792 coex_sta->under_lps = FALSE;
4793
4794 halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_ACTIVE |
4795 BT_8821C_2ANT_SCBD_ONOFF |
4796 BT_8821C_2ANT_SCBD_SCAN |
4797 BT_8821C_2ANT_SCBD_UNDERTEST,
4798 FALSE);
4799
4800 halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, FC_EXCU,
4801 BT_8821C_2ANT_PHASE_WOFF);
4802
4803 halbtc8821c2ant_action_coex_all_off(btc);
4804 } else if (type == BTC_IPS_LEAVE) {
4805 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
4806 "[BTCoex], IPS LEAVE notify\n");
4807 BTC_TRACE(trace_buf);
4808 coex_sta->under_ips = FALSE;
4809
4810 halbtc8821c2ant_init_hw_config(btc, FALSE);
4811 halbtc8821c2ant_init_coex_dm(btc);
4812 halbtc8821c2ant_query_bt_info(btc);
4813 }
4814 }
4815
ex_halbtc8821c2ant_lps_notify(struct btc_coexist * btc,u8 type)4816 void ex_halbtc8821c2ant_lps_notify(struct btc_coexist *btc, u8 type)
4817 {
4818 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
4819
4820 if (btc->manual_control || btc->stop_coex_dm)
4821 return;
4822
4823 if (type == BTC_LPS_ENABLE) {
4824 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
4825 "[BTCoex], LPS ENABLE notify\n");
4826 BTC_TRACE(trace_buf);
4827 coex_sta->under_lps = TRUE;
4828 coex_sta->under_ips = FALSE;
4829
4830 if (coex_sta->force_lps_ctrl == TRUE) { /* LPS No-32K */
4831 /* Write WL "Active" in Score-board for PS-TDMA */
4832 halbtc8821c2ant_write_scbd(btc,
4833 BT_8821C_2ANT_SCBD_ACTIVE,
4834 TRUE);
4835
4836 } else { /* LPS-32K, need check if this h2c 0x71 can work?? (2015/08/28) */
4837 /* Write WL "Non-Active" in Score-board for Native-PS */
4838 halbtc8821c2ant_write_scbd(btc,
4839 BT_8821C_2ANT_SCBD_ACTIVE,
4840 FALSE);
4841
4842 halbtc8821c2ant_action_wifi_native_lps(btc);
4843 }
4844
4845 } else if (type == BTC_LPS_DISABLE) {
4846 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
4847 "[BTCoex], LPS DISABLE notify\n");
4848 BTC_TRACE(trace_buf);
4849 coex_sta->under_lps = FALSE;
4850
4851 halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_ACTIVE,
4852 TRUE);
4853
4854 if (!coex_sta->force_lps_ctrl) {
4855 halbtc8821c2ant_query_bt_info(btc);
4856 halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_LPS);
4857 }
4858 }
4859 }
4860
ex_halbtc8821c2ant_scan_notify(struct btc_coexist * btc,u8 type)4861 void ex_halbtc8821c2ant_scan_notify(struct btc_coexist *btc, u8 type)
4862 {
4863 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
4864 boolean wifi_connected = FALSE;
4865
4866 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
4867 "[BTCoex], SCAN notify()\n");
4868 BTC_TRACE(trace_buf);
4869
4870 if (btc->manual_control || btc->stop_coex_dm)
4871 return;
4872
4873 btc->btc_get(btc, BTC_GET_BL_WIFI_CONNECTED, &wifi_connected);
4874
4875 if (wifi_connected)
4876 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
4877 "[BTCoex], ********** WL connected before SCAN\n");
4878 else
4879 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
4880 "[BTCoex], ********** WL is not connected before SCAN\n");
4881
4882 BTC_TRACE(trace_buf);
4883
4884 /* this can't be removed for RF off_on event,
4885 * r BT would dis-connect
4886 */
4887 if (type != BTC_SCAN_FINISH) {
4888 halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_ACTIVE |
4889 BT_8821C_2ANT_SCBD_SCAN |
4890 BT_8821C_2ANT_SCBD_ONOFF, TRUE);
4891 }
4892
4893 if (type == BTC_SCAN_START_5G) {
4894 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
4895 "[BTCoex], SCAN START notify (5G)\n");
4896 BTC_TRACE(trace_buf);
4897
4898 halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO,
4899 FC_EXCU, BT_8821C_2ANT_PHASE_5G);
4900
4901 halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_5GSCANSTART);
4902 } else if (type == BTC_SCAN_START_2G || type == BTC_SCAN_START) {
4903 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
4904 "[BTCoex], SCAN START notify (2G)\n");
4905 BTC_TRACE(trace_buf);
4906
4907 if (!wifi_connected)
4908 coex_sta->wifi_high_pri_task2 = TRUE;
4909
4910 halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, FC_EXCU,
4911 BT_8821C_2ANT_PHASE_2G);
4912
4913 halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_2GSCANSTART);
4914 } else if (type == BTC_SCAN_FINISH) {
4915 btc->btc_get(btc, BTC_GET_U1_AP_NUM, &coex_sta->scan_ap_num);
4916
4917 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
4918 "[BTCoex], SCAN FINISH notify (Scan-AP = %d)\n",
4919 coex_sta->scan_ap_num);
4920 BTC_TRACE(trace_buf);
4921
4922 coex_sta->wifi_high_pri_task2 = FALSE;
4923
4924 halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_SCANFINISH);
4925 }
4926 }
4927
ex_halbtc8821c2ant_switchband_notify(struct btc_coexist * btc,u8 type)4928 void ex_halbtc8821c2ant_switchband_notify(struct btc_coexist *btc, u8 type)
4929 {
4930 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
4931
4932 if (btc->manual_control || btc->stop_coex_dm)
4933 return;
4934
4935 coex_sta->switch_band_notify_to = type;
4936
4937 if (type == BTC_SWITCH_TO_5G) {
4938 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
4939 "[BTCoex], switchband_notify --- switch to 5G\n");
4940 BTC_TRACE(trace_buf);
4941
4942 halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_5GSWITCHBAND);
4943 } else if (type == BTC_SWITCH_TO_24G_NOFORSCAN) {
4944 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
4945 "[BTCoex], switchband_notify --- BTC_SWITCH_TO_2G (no for scan)\n");
4946 BTC_TRACE(trace_buf);
4947
4948 halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_2GSWITCHBAND);
4949 } else {
4950 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
4951 "[BTCoex], switchband_notify --- switch to 2G\n");
4952 BTC_TRACE(trace_buf);
4953
4954 ex_halbtc8821c2ant_scan_notify(btc, BTC_SCAN_START_2G);
4955 }
4956
4957 coex_sta->switch_band_notify_to = BTC_NOT_SWITCH;
4958 }
4959
ex_halbtc8821c2ant_connect_notify(struct btc_coexist * btc,u8 type)4960 void ex_halbtc8821c2ant_connect_notify(struct btc_coexist *btc,
4961 u8 type)
4962 {
4963 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
4964 struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant;
4965
4966 if (btc->manual_control || btc->stop_coex_dm)
4967 return;
4968
4969 halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_ACTIVE |
4970 BT_8821C_2ANT_SCBD_SCAN |
4971 BT_8821C_2ANT_SCBD_ONOFF, TRUE);
4972
4973 if (type == BTC_ASSOCIATE_5G_START ||
4974 type == BTC_ASSOCIATE_5G_FINISH) {
4975 halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, FC_EXCU,
4976 BT_8821C_2ANT_PHASE_5G);
4977
4978 if (type == BTC_ASSOCIATE_5G_START) {
4979 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
4980 "[BTCoex], CONNECT START notify (5G)\n");
4981 BTC_TRACE(trace_buf);
4982
4983 halbtc8821c2ant_run_coex(btc,
4984 BT_8821C_2ANT_RSN_5GCONSTART);
4985 } else {
4986 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
4987 "[BTCoex], CONNECT FINISH notify (5G)\n");
4988 BTC_TRACE(trace_buf);
4989
4990 halbtc8821c2ant_run_coex(btc,
4991 BT_8821C_2ANT_RSN_5GCONFINISH);
4992 }
4993 } else if (type == BTC_ASSOCIATE_START) {
4994 coex_sta->wifi_high_pri_task1 = TRUE;
4995
4996 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
4997 "[BTCoex], CONNECT START notify (2G)\n");
4998 BTC_TRACE(trace_buf);
4999
5000 halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, FC_EXCU,
5001 BT_8821C_2ANT_PHASE_2G);
5002
5003 halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_2GCONSTART);
5004
5005 /* To keep TDMA case during connect process,
5006 to avoid changed by Btinfo and runcoexmechanism */
5007 coex_sta->freeze_coexrun_by_btinfo = TRUE;
5008 coex_dm->arp_cnt = 0;
5009 } else if (type == BTC_ASSOCIATE_FINISH) {
5010 coex_sta->wifi_high_pri_task1 = FALSE;
5011 coex_sta->freeze_coexrun_by_btinfo = FALSE;
5012
5013 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
5014 "[BTCoex], CONNECT FINISH notify (2G)\n");
5015 BTC_TRACE(trace_buf);
5016
5017 halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_2GCONFINISH);
5018 }
5019 }
5020
ex_halbtc8821c2ant_media_status_notify(struct btc_coexist * btc,u8 type)5021 void ex_halbtc8821c2ant_media_status_notify(struct btc_coexist *btc, u8 type)
5022 {
5023 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
5024 boolean wifi_under_b_mode = FALSE;
5025 u8 h2c_parameter[2] = {0};
5026
5027 if (btc->manual_control || btc->stop_coex_dm)
5028 return;
5029
5030 if (type == BTC_MEDIA_CONNECT || type == BTC_MEDIA_CONNECT_5G) {
5031 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
5032 "[BTCoex], MEDIA connect notify\n");
5033 BTC_TRACE(trace_buf);
5034
5035 halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_ACTIVE |
5036 BT_8821C_2ANT_SCBD_ONOFF, TRUE);
5037
5038 if (type == BTC_MEDIA_CONNECT_5G) {
5039 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
5040 "[BTCoex], WiFi is under 5G!!!\n");
5041 BTC_TRACE(trace_buf);
5042
5043 halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO,
5044 FC_EXCU,
5045 BT_8821C_2ANT_PHASE_5G);
5046
5047 halbtc8821c2ant_run_coex(btc,
5048 BT_8821C_2ANT_RSN_5GMEDIA);
5049 } else {
5050 halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO,
5051 FC_EXCU,
5052 BT_8821C_2ANT_PHASE_2G);
5053
5054 btc->btc_get(btc, BTC_GET_BL_WIFI_UNDER_B_MODE,
5055 &wifi_under_b_mode);
5056
5057 /* Set CCK Tx/Rx high Pri except 11b mode */
5058 if (wifi_under_b_mode)
5059 btc->btc_write_1byte_bitmask(btc, 0x6cf, BIT(4),
5060 0x0);
5061 else
5062 btc->btc_write_1byte_bitmask(btc, 0x6cf, BIT(4),
5063 0x1);
5064
5065 /*Leak-AP protection will reopen when connecting AP*/
5066 h2c_parameter[0] = 0xc;
5067 h2c_parameter[1] = 0x0;
5068 btc->btc_fill_h2c(btc, 0x69, 2, h2c_parameter);
5069 coex_sta->is_no_wl_5ms_extend = FALSE;
5070
5071 halbtc8821c2ant_run_coex(btc,
5072 BT_8821C_2ANT_RSN_2GMEDIA);
5073 }
5074 } else {
5075 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
5076 "[BTCoex], MEDIA disconnect notify\n");
5077 BTC_TRACE(trace_buf);
5078
5079 btc->btc_write_1byte_bitmask(btc, 0x6cf, BIT(4), 0x0);
5080
5081 coex_sta->cck_lock_ever = FALSE;
5082 coex_sta->cck_lock_warn = FALSE;
5083 coex_sta->cck_lock = FALSE;
5084
5085 halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_MEDIADISCON);
5086 }
5087 btc->btc_get(btc, BTC_GET_U1_IOT_PEER, &coex_sta->wl_iot_peer);
5088 halbtc8821c2ant_update_wifi_ch_info(btc, type);
5089 }
5090
ex_halbtc8821c2ant_specific_packet_notify(struct btc_coexist * btc,u8 type)5091 void ex_halbtc8821c2ant_specific_packet_notify(struct btc_coexist *btc, u8 type)
5092 {
5093 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
5094 struct coex_dm_8821c_2ant *coex_dm = &btc->coex_dm_8821c_2ant;
5095 boolean under_4way = FALSE;
5096
5097 if (btc->manual_control || btc->stop_coex_dm)
5098 return;
5099
5100 if (type & BTC_5G_BAND) {
5101 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
5102 "[BTCoex], 5g special packet notify\n");
5103 BTC_TRACE(trace_buf);
5104
5105 halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_5GSPECIALPKT);
5106 return;
5107 }
5108
5109 btc->btc_get(btc, BTC_GET_BL_WIFI_4_WAY_PROGRESS, &under_4way);
5110
5111 if (under_4way) {
5112 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
5113 "[BTCoex], specific Packet ---- under_4way!!\n");
5114 BTC_TRACE(trace_buf);
5115
5116 coex_sta->wifi_high_pri_task1 = TRUE;
5117 coex_sta->specific_pkt_period_cnt = 2;
5118 } else if (type == BTC_PACKET_ARP) {
5119 coex_dm->arp_cnt++;
5120 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
5121 "[BTCoex], specific Packet ARP notify -cnt = %d\n",
5122 coex_dm->arp_cnt);
5123 BTC_TRACE(trace_buf);
5124 } else {
5125 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
5126 "[BTCoex], specific Packet DHCP or EAPOL notify [Type = %d]\n",
5127 type);
5128 BTC_TRACE(trace_buf);
5129
5130 coex_sta->wifi_high_pri_task1 = TRUE;
5131 coex_sta->specific_pkt_period_cnt = 2;
5132 }
5133
5134 if (coex_sta->wifi_high_pri_task1) {
5135 halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_SCAN, TRUE);
5136 halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_2GSPECIALPKT);
5137 }
5138 }
5139
ex_halbtc8821c2ant_bt_info_notify(struct btc_coexist * btc,u8 * tmp_buf,u8 length)5140 void ex_halbtc8821c2ant_bt_info_notify(struct btc_coexist *btc, u8 *tmp_buf,
5141 u8 length)
5142 {
5143 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
5144 struct btc_bt_link_info *bt_link_info = &btc->bt_link_info;
5145 u8 i, rsp_source = 0;
5146 boolean wifi_connected = FALSE;
5147 boolean wifi_busy = FALSE;
5148 static boolean is_scoreboard_scan;
5149 const u16 type_is_scan = BT_8821C_2ANT_SCBD_SCAN;
5150 u8 type;
5151
5152 rsp_source = tmp_buf[0] & 0xf;
5153 if (rsp_source >= BT_8821C_2ANT_INFO_SRC_MAX)
5154 rsp_source = BT_8821C_2ANT_INFO_SRC_WIFI_FW;
5155 coex_sta->bt_info_c2h_cnt[rsp_source]++;
5156
5157 if (rsp_source == BT_8821C_2ANT_INFO_SRC_BT_RSP ||
5158 rsp_source == BT_8821C_2ANT_INFO_SRC_BT_ACT) {
5159 if (coex_sta->bt_disabled) {
5160 coex_sta->bt_disabled = FALSE;
5161 coex_sta->is_bt_reenable = TRUE;
5162 coex_sta->cnt_bt_reenable = 15;
5163
5164 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
5165 "[BTCoex], BT enable detected by bt_info\n");
5166 BTC_TRACE(trace_buf);
5167 }
5168 }
5169
5170 if (rsp_source == BT_8821C_2ANT_INFO_SRC_WIFI_FW) {
5171 #if 0
5172 halbtc8821c2ant_update_bt_link_info(btc);
5173 halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_BTINFO);
5174 #endif
5175 return;
5176 }
5177
5178 if (length != 7) {
5179 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
5180 "[BTCoex], Bt_info length = %d invalid!!\n",
5181 length);
5182 BTC_TRACE(trace_buf);
5183 return;
5184 }
5185
5186 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
5187 "[BTCoex], Bt_info[%d], len=%d, data=[%02x %02x %02x %02x %02x %02x]\n",
5188 tmp_buf[0], length, tmp_buf[1], tmp_buf[2], tmp_buf[3],
5189 tmp_buf[4], tmp_buf[5], tmp_buf[6]);
5190 BTC_TRACE(trace_buf);
5191
5192 for (i = 0; i < 7; i++)
5193 coex_sta->bt_info_c2h[rsp_source][i] = tmp_buf[i];
5194
5195 if (coex_sta->bt_info_c2h[rsp_source][1] == coex_sta->bt_info_lb2 &&
5196 coex_sta->bt_info_c2h[rsp_source][2] == coex_sta->bt_info_lb3 &&
5197 coex_sta->bt_info_c2h[rsp_source][3] == coex_sta->bt_info_hb0 &&
5198 coex_sta->bt_info_c2h[rsp_source][4] == coex_sta->bt_info_hb1 &&
5199 coex_sta->bt_info_c2h[rsp_source][5] == coex_sta->bt_info_hb2 &&
5200 coex_sta->bt_info_c2h[rsp_source][6] == coex_sta->bt_info_hb3) {
5201 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
5202 "[BTCoex], Return because Btinfo duplicate!!\n");
5203 BTC_TRACE(trace_buf);
5204 return;
5205 }
5206
5207 coex_sta->bt_info_lb2 = coex_sta->bt_info_c2h[rsp_source][1];
5208 coex_sta->bt_info_lb3 = coex_sta->bt_info_c2h[rsp_source][2];
5209 coex_sta->bt_info_hb0 = coex_sta->bt_info_c2h[rsp_source][3];
5210 coex_sta->bt_info_hb1 = coex_sta->bt_info_c2h[rsp_source][4];
5211 coex_sta->bt_info_hb2 = coex_sta->bt_info_c2h[rsp_source][5];
5212 coex_sta->bt_info_hb3 = coex_sta->bt_info_c2h[rsp_source][6];
5213
5214 /* if 0xff, it means BT is under WHCK test */
5215 coex_sta->bt_whck_test =
5216 ((coex_sta->bt_info_lb2 == 0xff) ? TRUE : FALSE);
5217
5218 coex_sta->bt_create_connection =
5219 ((coex_sta->bt_info_lb3 & BIT(7)) ? TRUE : FALSE);
5220
5221 /* unit: %, value-100 to translate to unit: dBm */
5222 coex_sta->bt_rssi = coex_sta->bt_info_hb0 * 2 + 10;
5223
5224 coex_sta->c2h_bt_remote_name_req =
5225 ((coex_sta->bt_info_lb3 & BIT(5)) ? TRUE : FALSE);
5226
5227 coex_sta->is_A2DP_3M =
5228 ((coex_sta->bt_info_lb3 & BIT(4)) ? TRUE : FALSE);
5229
5230 coex_sta->acl_busy =
5231 ((coex_sta->bt_info_lb2 & BIT(3)) ? TRUE : FALSE);
5232
5233 coex_sta->voice_over_HOGP =
5234 ((coex_sta->bt_info_hb1 & BIT(4)) ? TRUE : FALSE);
5235
5236 coex_sta->c2h_bt_inquiry_page =
5237 ((coex_sta->bt_info_lb2 & BIT(2)) ? TRUE : FALSE);
5238
5239 if (coex_sta->bt_inq_page_pre != coex_sta->c2h_bt_inquiry_page) {
5240 coex_sta->bt_inq_page_pre = coex_sta->c2h_bt_inquiry_page;
5241 coex_sta->bt_inq_page_remain = TRUE;
5242
5243 if (!coex_sta->c2h_bt_inquiry_page)
5244 coex_sta->bt_inq_page_downcount = 2;
5245 }
5246
5247 if ((coex_sta->bt_info_lb2 & 0x49) == 0x49)
5248 coex_sta->a2dp_bit_pool = (coex_sta->bt_info_hb3 & 0x7f);
5249 else
5250 coex_sta->a2dp_bit_pool = 0;
5251
5252 coex_sta->is_bt_a2dp_sink =
5253 (coex_sta->bt_info_hb3 & BIT(7)) ? TRUE : FALSE;
5254
5255 coex_sta->bt_retry_cnt = coex_sta->bt_info_lb3 & 0xf;
5256
5257 bt_link_info->slave_role = coex_sta->bt_info_hb2 & 0x8;
5258
5259 coex_sta->bt_a2dp_active = coex_sta->bt_info_hb2 & 0x4;
5260
5261 coex_sta->hid_busy_num = (coex_sta->bt_info_hb2 & 0x30) >> 4;
5262
5263 coex_sta->hid_pair_cnt = (coex_sta->bt_info_hb2 & 0xc0) >> 6;
5264
5265 if (coex_sta->hid_pair_cnt > 0 && coex_sta->hid_busy_num >= 2) {
5266 coex_sta->bt_418_hid_exist = TRUE;
5267 } else if (coex_sta->hid_pair_cnt == 0 ||
5268 coex_sta->hid_busy_num == 1) {
5269 coex_sta->bt_418_hid_exist = FALSE;
5270 coex_sta->bt_ble_hid_exist = FALSE;
5271 }
5272
5273 coex_sta->is_bt_opp_exist =
5274 (coex_sta->bt_info_hb2 & BIT(0)) ? TRUE : FALSE;
5275
5276 if (coex_sta->bt_retry_cnt >= 1)
5277 coex_sta->pop_event_cnt++;
5278
5279 if (coex_sta->c2h_bt_remote_name_req)
5280 coex_sta->cnt_remote_name_req++;
5281
5282 if (coex_sta->bt_info_hb1 & BIT(1))
5283 coex_sta->cnt_reinit++;
5284
5285 if ((coex_sta->bt_info_hb1 & BIT(2)) ||
5286 (coex_sta->bt_create_connection &&
5287 coex_sta->wl_pnp_wakeup_downcnt > 0)) {
5288 coex_sta->cnt_setup_link++;
5289 coex_sta->is_setup_link = TRUE;
5290
5291 if (coex_sta->is_bt_reenable)
5292 coex_sta->bt_relink_downcount = 6;
5293 else
5294 coex_sta->bt_relink_downcount = 2;
5295 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
5296 "[BTCoex], Re-Link start in BT info!!\n");
5297 BTC_TRACE(trace_buf);
5298 }
5299
5300 if (coex_sta->bt_info_hb1 & BIT(3))
5301 coex_sta->cnt_ign_wlan_act++;
5302
5303 if (coex_sta->bt_info_hb1 & BIT(6))
5304 coex_sta->cnt_role_switch++;
5305
5306 if (coex_sta->bt_info_hb1 & BIT(7))
5307 coex_sta->is_bt_multi_link = TRUE;
5308 else
5309 coex_sta->is_bt_multi_link = FALSE;
5310
5311 if (coex_sta->bt_info_lb2 & BIT(5)) {
5312 if (coex_sta->bt_info_hb1 & BIT(0)) {
5313 /*BLE HID*/
5314 coex_sta->bt_ble_hid_exist = TRUE;
5315 coex_sta->is_hid_rcu = FALSE;
5316 }
5317 } else if (coex_sta->bt_info_hb1 & BIT(0)) {
5318 /*RCU*/
5319 coex_sta->is_hid_rcu = TRUE;
5320 } else {
5321 coex_sta->bt_ble_hid_exist = FALSE;
5322 coex_sta->is_hid_rcu = FALSE;
5323 }
5324
5325 if (coex_sta->bt_info_hb1 & BIT(5))
5326 coex_sta->is_ble_scan_en = TRUE;
5327 else
5328 coex_sta->is_ble_scan_en = FALSE;
5329
5330 if (coex_sta->bt_create_connection) {
5331 coex_sta->cnt_page++;
5332
5333 btc->btc_get(btc, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
5334
5335 if (coex_sta->is_wifi_linkscan_process ||
5336 coex_sta->wifi_high_pri_task1 ||
5337 coex_sta->wifi_high_pri_task2 || wifi_busy) {
5338 is_scoreboard_scan = TRUE;
5339 halbtc8821c2ant_write_scbd(btc, type_is_scan, TRUE);
5340 } else {
5341 halbtc8821c2ant_write_scbd(btc, type_is_scan, FALSE);
5342 }
5343 } else {
5344 if (is_scoreboard_scan) {
5345 halbtc8821c2ant_write_scbd(btc, type_is_scan, FALSE);
5346 is_scoreboard_scan = FALSE;
5347 }
5348 }
5349
5350 /* Here we need to resend some wifi info to BT */
5351 /* because bt is reset and loss of the info. */
5352 btc->btc_get(btc, BTC_GET_BL_WIFI_CONNECTED, &wifi_connected);
5353 /* Re-Init */
5354 if ((coex_sta->bt_info_hb1 & BIT(1))) {
5355 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
5356 "[BTCoex], BT ext info bit1 check, send wifi BW&Chnl to BT!!\n");
5357 BTC_TRACE(trace_buf);
5358 if (wifi_connected)
5359 type = BTC_MEDIA_CONNECT;
5360 else
5361 type = BTC_MEDIA_DISCONNECT;
5362 halbtc8821c2ant_update_wifi_ch_info(btc, type);
5363 }
5364
5365 /* If Ignore_WLanAct && not SetUp_Link */
5366 if ((coex_sta->bt_info_hb1 & BIT(3)) &&
5367 (!(coex_sta->bt_info_hb1 & BIT(2)))) {
5368 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
5369 "[BTCoex], BT ext info bit3 check, set BT NOT to ignore Wlan active!!\n");
5370 BTC_TRACE(trace_buf);
5371 halbtc8821c2ant_ignore_wlan_act(btc, FC_EXCU, FALSE);
5372 }
5373
5374 halbtc8821c2ant_update_bt_link_info(btc);
5375 halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_BTINFO);
5376 }
5377
ex_halbtc8821c2ant_wl_fwdbginfo_notify(struct btc_coexist * btc,u8 * tmp_buf,u8 length)5378 void ex_halbtc8821c2ant_wl_fwdbginfo_notify(struct btc_coexist *btc,
5379 u8 *tmp_buf, u8 length)
5380 {
5381 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
5382 u8 i = 0;
5383 static u8 tmp_buf_pre[10];
5384
5385 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
5386 "[BTCoex], WiFi Fw Dbg info = %d %d %d %d %d %d %d %d (len = %d)\n",
5387 tmp_buf[0], tmp_buf[1], tmp_buf[2], tmp_buf[3], tmp_buf[4],
5388 tmp_buf[5], tmp_buf[6], tmp_buf[7], length);
5389 BTC_TRACE(trace_buf);
5390
5391 if (tmp_buf[0] == 0x8) {
5392 for (i = 1; i <= 7; i++) {
5393 coex_sta->wl_fw_dbg_info[i] =
5394 (tmp_buf[i] >= tmp_buf_pre[i]) ?
5395 (tmp_buf[i] - tmp_buf_pre[i]) :
5396 (255 - tmp_buf_pre[i] + tmp_buf[i]);
5397
5398 tmp_buf_pre[i] = tmp_buf[i];
5399 }
5400 }
5401
5402 coex_sta->cnt_wl_fw_notify++;
5403 halbtc8821c2ant_ccklock_action(btc);
5404 }
5405
ex_halbtc8821c2ant_rx_rate_change_notify(struct btc_coexist * btc,BOOLEAN is_data_frame,u8 btc_rate_id)5406 void ex_halbtc8821c2ant_rx_rate_change_notify(struct btc_coexist *btc,
5407 BOOLEAN is_data_frame,
5408 u8 btc_rate_id)
5409 {
5410 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
5411
5412 if (is_data_frame) {
5413 coex_sta->wl_rx_rate = btc_rate_id;
5414
5415 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
5416 "[BTCoex], rx_rate_change_notify data rate id = %d, RTS_Rate = %d\n",
5417 coex_sta->wl_rx_rate, coex_sta->wl_rts_rx_rate);
5418 BTC_TRACE(trace_buf);
5419 } else {
5420 coex_sta->wl_rts_rx_rate = btc_rate_id;
5421
5422 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
5423 "[BTCoex], rts_rate_change_notify RTS rate id = %d, RTS_Rate = %d\n",
5424 coex_sta->wl_rts_rx_rate, coex_sta->wl_rts_rx_rate);
5425 BTC_TRACE(trace_buf);
5426 }
5427
5428 halbtc8821c2ant_ccklock_detect(btc);
5429 }
5430
ex_halbtc8821c2ant_tx_rate_change_notify(struct btc_coexist * btc,u8 tx_rate,u8 tx_retry_ratio,u8 macid)5431 void ex_halbtc8821c2ant_tx_rate_change_notify(struct btc_coexist *btc,
5432 u8 tx_rate, u8 tx_retry_ratio,
5433 u8 macid)
5434 {
5435 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
5436
5437 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
5438 "[BTCoex], tx_rate_change_notify Tx_Rate = %d, Tx_Retry_Ratio = %d, macid =%d\n",
5439 tx_rate, tx_retry_ratio, macid);
5440 BTC_TRACE(trace_buf);
5441
5442 coex_sta->wl_tx_rate = tx_rate;
5443 coex_sta->wl_tx_retry_ratio = tx_retry_ratio;
5444 coex_sta->wl_tx_macid = macid;
5445 }
5446
ex_halbtc8821c2ant_rf_status_notify(struct btc_coexist * btc,u8 type)5447 void ex_halbtc8821c2ant_rf_status_notify(struct btc_coexist *btc, u8 type)
5448 {
5449 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
5450
5451 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], RF Status notify\n");
5452 BTC_TRACE(trace_buf);
5453
5454 if (type == BTC_RF_ON) {
5455 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
5456 "[BTCoex], RF is turned ON!!\n");
5457 BTC_TRACE(trace_buf);
5458
5459 btc->stop_coex_dm = FALSE;
5460 btc->wl_rf_state_off = FALSE;
5461 } else if (type == BTC_RF_OFF) {
5462 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
5463 "[BTCoex], RF is turned OFF!!\n");
5464 BTC_TRACE(trace_buf);
5465
5466 halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_ACTIVE |
5467 BT_8821C_2ANT_SCBD_ONOFF |
5468 BT_8821C_2ANT_SCBD_SCAN |
5469 BT_8821C_2ANT_SCBD_UNDERTEST,
5470 FALSE);
5471
5472 halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, FC_EXCU,
5473 BT_8821C_2ANT_PHASE_WOFF);
5474
5475 halbtc8821c2ant_action_coex_all_off(btc);
5476
5477 btc->stop_coex_dm = TRUE;
5478 btc->wl_rf_state_off = TRUE;
5479 /* must place in the last step */
5480 halbtc8821c2ant_update_wifi_ch_info(btc, BTC_MEDIA_DISCONNECT);
5481 }
5482 }
5483
ex_halbtc8821c2ant_halt_notify(struct btc_coexist * btc)5484 void ex_halbtc8821c2ant_halt_notify(struct btc_coexist *btc)
5485 {
5486 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], Halt notify\n");
5487 BTC_TRACE(trace_buf);
5488
5489 halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_ACTIVE |
5490 BT_8821C_2ANT_SCBD_ONOFF |
5491 BT_8821C_2ANT_SCBD_SCAN |
5492 BT_8821C_2ANT_SCBD_UNDERTEST,
5493 FALSE);
5494
5495 halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, FC_EXCU,
5496 BT_8821C_2ANT_PHASE_WOFF);
5497
5498 halbtc8821c2ant_action_coex_all_off(btc);
5499
5500 btc->stop_coex_dm = TRUE;
5501
5502 /* must place in the last step */
5503 halbtc8821c2ant_update_wifi_ch_info(btc, BTC_MEDIA_DISCONNECT);
5504 }
5505
ex_halbtc8821c2ant_pnp_notify(struct btc_coexist * btc,u8 pnp_state)5506 void ex_halbtc8821c2ant_pnp_notify(struct btc_coexist *btc, u8 pnp_state)
5507 {
5508 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
5509 struct wifi_link_info_8821c_2ant *wifi_link_info_ext =
5510 &btc->wifi_link_info_8821c_2ant;
5511 static u8 pre_pnp_state;
5512 u8 phase;
5513
5514 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE, "[BTCoex], Pnp notify\n");
5515 BTC_TRACE(trace_buf);
5516
5517 if (pnp_state == BTC_WIFI_PNP_SLEEP ||
5518 pnp_state == BTC_WIFI_PNP_SLEEP_KEEP_ANT) {
5519 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
5520 "[BTCoex], Pnp notify to SLEEP\n");
5521 BTC_TRACE(trace_buf);
5522
5523 /* Sinda 20150819, workaround for driver skip
5524 * leave IPS/LPS to speed up sleep time.
5525 * Driver do not leave IPS/LPS when driver is going to sleep,
5526 * so BTCoexistence think wifi is still under IPS/LPS
5527 * BT should clear UnderIPS/UnderLPS state to avoid mismatch
5528 * state after wakeup.
5529 */
5530 coex_sta->under_ips = FALSE;
5531 coex_sta->under_lps = FALSE;
5532
5533 halbtc8821c2ant_write_scbd(btc, BT_8821C_2ANT_SCBD_ACTIVE |
5534 BT_8821C_2ANT_SCBD_ONOFF |
5535 BT_8821C_2ANT_SCBD_SCAN |
5536 BT_8821C_2ANT_SCBD_UNDERTEST,
5537 FALSE);
5538
5539 if (pnp_state == BTC_WIFI_PNP_SLEEP_KEEP_ANT) {
5540 if (wifi_link_info_ext->is_all_under_5g)
5541 phase = BT_8821C_2ANT_PHASE_5G;
5542 else
5543 phase = BT_8821C_2ANT_PHASE_2G;
5544 } else {
5545 phase = BT_8821C_2ANT_PHASE_WOFF;
5546 }
5547
5548 halbtc8821c2ant_set_ant_path(btc, BTC_ANT_PATH_AUTO, FC_EXCU,
5549 phase);
5550 btc->stop_coex_dm = TRUE;
5551 } else {
5552 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
5553 "[BTCoex], Pnp notify to WAKE UP\n");
5554 BTC_TRACE(trace_buf);
5555 coex_sta->wl_pnp_wakeup_downcnt = 3;
5556
5557 /*WoWLAN*/
5558 if (pre_pnp_state == BTC_WIFI_PNP_SLEEP_KEEP_ANT ||
5559 pnp_state == BTC_WIFI_PNP_WOWLAN) {
5560 coex_sta->run_time_state = TRUE;
5561 btc->stop_coex_dm = FALSE;
5562 halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_PNP);
5563 }
5564 }
5565
5566 pre_pnp_state = pnp_state;
5567 }
5568
ex_halbtc8821c2ant_periodical(struct btc_coexist * btc)5569 void ex_halbtc8821c2ant_periodical(struct btc_coexist *btc)
5570 {
5571 struct coex_sta_8821c_2ant *coex_sta = &btc->coex_sta_8821c_2ant;
5572 struct btc_board_info *board_info = &btc->board_info;
5573 boolean bt_relink_finish = FALSE, is_defreeze = FALSE,
5574 bt_ctr_change = FALSE;
5575 static u8 freeze_cnt;
5576
5577 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
5578 "[BTCoex], ************* Periodical *************\n");
5579 BTC_TRACE(trace_buf);
5580
5581 if (!btc->auto_report)
5582 halbtc8821c2ant_query_bt_info(btc);
5583
5584 bt_ctr_change = halbtc8821c2ant_monitor_bt_ctr(btc);
5585 halbtc8821c2ant_monitor_wifi_ctr(btc);
5586 halbtc8821c2ant_update_wifi_link_info(btc,
5587 BT_8821C_2ANT_RSN_PERIODICAL);
5588 halbtc8821c2ant_monitor_bt_enable(btc);
5589
5590 if (coex_sta->bt_relink_downcount != 0) {
5591 coex_sta->bt_relink_downcount--;
5592 if (coex_sta->bt_relink_downcount == 0) {
5593 coex_sta->is_setup_link = FALSE;
5594 bt_relink_finish = TRUE;
5595 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
5596 "[BTCoex], Re-Link stop by periodical count-down!!\n");
5597 BTC_TRACE(trace_buf);
5598 }
5599 }
5600
5601 if (coex_sta->bt_inq_page_downcount != 0) {
5602 coex_sta->bt_inq_page_downcount--;
5603 if (coex_sta->bt_inq_page_downcount == 0)
5604 coex_sta->bt_inq_page_remain = FALSE;
5605 }
5606
5607 if (coex_sta->freeze_coexrun_by_btinfo) {
5608 freeze_cnt++;
5609
5610 if (freeze_cnt >= 5) {
5611 freeze_cnt = 0;
5612 coex_sta->freeze_coexrun_by_btinfo = FALSE;
5613 is_defreeze = TRUE;
5614 }
5615 } else {
5616 freeze_cnt = 0;
5617 }
5618
5619 /* for 4-way, DHCP, EAPOL packet */
5620 if (coex_sta->specific_pkt_period_cnt > 0) {
5621 coex_sta->specific_pkt_period_cnt--;
5622
5623 if (!coex_sta->freeze_coexrun_by_btinfo &&
5624 coex_sta->specific_pkt_period_cnt == 0)
5625 coex_sta->wifi_high_pri_task1 = FALSE;
5626
5627 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
5628 "[BTCoex], Hi-Pri Task = %s\n",
5629 (coex_sta->wifi_high_pri_task1 ? "Yes" : "No"));
5630 BTC_TRACE(trace_buf);
5631 }
5632
5633 if (coex_sta->wl_pnp_wakeup_downcnt > 0) {
5634 coex_sta->wl_pnp_wakeup_downcnt--;
5635 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
5636 "[BTCoex], wl_pnp_wakeup_downcnt = %d!!\n",
5637 coex_sta->wl_pnp_wakeup_downcnt);
5638 BTC_TRACE(trace_buf);
5639 }
5640
5641 if (coex_sta->cnt_bt_reenable > 0) {
5642 coex_sta->cnt_bt_reenable--;
5643 if (coex_sta->cnt_bt_reenable == 0) {
5644 coex_sta->is_bt_reenable = FALSE;
5645 BTC_SPRINTF(trace_buf, BT_TMP_BUF_SIZE,
5646 "[BTCoex], BT renable 30s finish!!\n");
5647 BTC_TRACE(trace_buf);
5648 }
5649 }
5650
5651 if (halbtc8821c2ant_moniter_wifibt_status(btc) || bt_relink_finish ||
5652 coex_sta->is_set_ps_state_fail || is_defreeze || bt_ctr_change)
5653 halbtc8821c2ant_run_coex(btc, BT_8821C_2ANT_RSN_PERIODICAL);
5654 }
5655 /*#pragma optimize( "", off )*/
5656
5657 #endif
5658
5659 #endif /* #if (RTL8821C_SUPPORT == 1) */
5660