1 /******************************************************************************
2  *
3  * Copyright(c) 2012  Realtek Corporation.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
12  * more details.
13  *
14  * The full GNU General Public License is included in this distribution in the
15  * file called LICENSE.
16  *
17  * Contact Information:
18  * wlanfae <wlanfae@realtek.com>
19  * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20  * Hsinchu 300, Taiwan.
21  *
22  * Larry Finger <Larry.Finger@lwfinger.net>
23  *
24  *****************************************************************************/
25 
26 /**************************************************************
27  * Description:
28  *
29  * This file is for RTL8821A Co-exist mechanism
30  *
31  * History
32  * 2012/11/15 Cosa first check in.
33  *
34  **************************************************************/
35 
36 /**************************************************************
37  * include files
38  **************************************************************/
39 #include "halbt_precomp.h"
40 /**************************************************************
41  * Global variables, these are static variables
42  **************************************************************/
43 static struct coex_dm_8821a_1ant glcoex_dm_8821a_1ant;
44 static struct coex_dm_8821a_1ant *coex_dm = &glcoex_dm_8821a_1ant;
45 static struct coex_sta_8821a_1ant glcoex_sta_8821a_1ant;
46 static struct coex_sta_8821a_1ant *coex_sta = &glcoex_sta_8821a_1ant;
47 static void btc8821a1ant_act_bt_sco_hid_only_busy(struct btc_coexist *btcoexist,
48 						  u8 wifi_status);
49 
50 static const char *const glbt_info_src_8821a_1ant[] = {
51 	  "BT Info[wifi fw]",
52 	  "BT Info[bt rsp]",
53 	  "BT Info[bt auto report]",
54 };
55 
56 static u32 glcoex_ver_date_8821a_1ant = 20130816;
57 static u32 glcoex_ver_8821a_1ant = 0x41;
58 
59 /**************************************************************
60  * local function proto type if needed
61  *
62  * local function start with btc8821a1ant_
63  **************************************************************/
64 static u8 btc8821a1ant_bt_rssi_state(struct btc_coexist *btcoexist,
65 				     u8 level_num, u8 rssi_thresh,
66 				     u8 rssi_thresh1)
67 {
68 	struct rtl_priv *rtlpriv = btcoexist->adapter;
69 	long bt_rssi = 0;
70 	u8 bt_rssi_state = coex_sta->pre_bt_rssi_state;
71 
72 	bt_rssi = coex_sta->bt_rssi;
73 
74 	if (level_num == 2) {
75 		if ((coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_LOW) ||
76 		    (coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) {
77 			if (bt_rssi >= (rssi_thresh +
78 					BTC_RSSI_COEX_THRESH_TOL_8821A_1ANT)) {
79 				bt_rssi_state = BTC_RSSI_STATE_HIGH;
80 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
81 					 "[BTCoex], BT Rssi state switch to High\n");
82 			} else {
83 				bt_rssi_state = BTC_RSSI_STATE_STAY_LOW;
84 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
85 					 "[BTCoex], BT Rssi state stay at Low\n");
86 			}
87 		} else {
88 			if (bt_rssi < rssi_thresh) {
89 				bt_rssi_state = BTC_RSSI_STATE_LOW;
90 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
91 					 "[BTCoex], BT Rssi state switch to Low\n");
92 			} else {
93 				bt_rssi_state = BTC_RSSI_STATE_STAY_HIGH;
94 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
95 					 "[BTCoex], BT Rssi state stay at High\n");
96 			}
97 		}
98 	} else if (level_num == 3) {
99 		if (rssi_thresh > rssi_thresh1) {
100 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
101 				 "[BTCoex], BT Rssi thresh error!!\n");
102 			return coex_sta->pre_bt_rssi_state;
103 		}
104 
105 		if ((coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_LOW) ||
106 		    (coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) {
107 			if (bt_rssi >= (rssi_thresh +
108 					BTC_RSSI_COEX_THRESH_TOL_8821A_1ANT)) {
109 				bt_rssi_state = BTC_RSSI_STATE_MEDIUM;
110 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
111 					 "[BTCoex], BT Rssi state switch to Medium\n");
112 			} else {
113 				bt_rssi_state = BTC_RSSI_STATE_STAY_LOW;
114 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
115 					 "[BTCoex], BT Rssi state stay at Low\n");
116 			}
117 		} else if ((coex_sta->pre_bt_rssi_state ==
118 			   BTC_RSSI_STATE_MEDIUM) ||
119 			   (coex_sta->pre_bt_rssi_state ==
120 			    BTC_RSSI_STATE_STAY_MEDIUM)) {
121 			if (bt_rssi >= (rssi_thresh1 +
122 					BTC_RSSI_COEX_THRESH_TOL_8821A_1ANT)) {
123 				bt_rssi_state = BTC_RSSI_STATE_HIGH;
124 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
125 					 "[BTCoex], BT Rssi state switch to High\n");
126 			} else if (bt_rssi < rssi_thresh) {
127 				bt_rssi_state = BTC_RSSI_STATE_LOW;
128 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
129 					 "[BTCoex], BT Rssi state switch to Low\n");
130 			} else {
131 				bt_rssi_state = BTC_RSSI_STATE_STAY_MEDIUM;
132 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
133 					 "[BTCoex], BT Rssi state stay at Medium\n");
134 			}
135 		} else {
136 			if (bt_rssi < rssi_thresh1) {
137 				bt_rssi_state = BTC_RSSI_STATE_MEDIUM;
138 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
139 					 "[BTCoex], BT Rssi state switch to Medium\n");
140 			} else {
141 				bt_rssi_state = BTC_RSSI_STATE_STAY_HIGH;
142 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
143 					 "[BTCoex], BT Rssi state stay at High\n");
144 			}
145 		}
146 	}
147 	coex_sta->pre_bt_rssi_state = bt_rssi_state;
148 
149 	return bt_rssi_state;
150 }
151 
152 static u8 btc8821a1ant_wifi_rssi_state(struct btc_coexist *btcoexist,
153 				       u8 index, u8 level_num, u8 rssi_thresh,
154 				       u8 rssi_thresh1)
155 {
156 	struct rtl_priv *rtlpriv = btcoexist->adapter;
157 	long	wifi_rssi = 0;
158 	u8	wifi_rssi_state = coex_sta->pre_wifi_rssi_state[index];
159 
160 	btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi);
161 
162 	if (level_num == 2) {
163 		if ((coex_sta->pre_wifi_rssi_state[index] ==
164 		     BTC_RSSI_STATE_LOW) ||
165 		    (coex_sta->pre_wifi_rssi_state[index] ==
166 		     BTC_RSSI_STATE_STAY_LOW)) {
167 			if (wifi_rssi >= (rssi_thresh +
168 					BTC_RSSI_COEX_THRESH_TOL_8821A_1ANT)) {
169 				wifi_rssi_state = BTC_RSSI_STATE_HIGH;
170 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
171 					 "[BTCoex], wifi RSSI state switch to High\n");
172 			} else {
173 				wifi_rssi_state = BTC_RSSI_STATE_STAY_LOW;
174 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
175 					 "[BTCoex], wifi RSSI state stay at Low\n");
176 			}
177 		} else {
178 			if (wifi_rssi < rssi_thresh) {
179 				wifi_rssi_state = BTC_RSSI_STATE_LOW;
180 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
181 					 "[BTCoex], wifi RSSI state switch to Low\n");
182 			} else {
183 				wifi_rssi_state = BTC_RSSI_STATE_STAY_HIGH;
184 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
185 					 "[BTCoex], wifi RSSI state stay at High\n");
186 			}
187 		}
188 	} else if (level_num == 3) {
189 		if (rssi_thresh > rssi_thresh1) {
190 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
191 				 "[BTCoex], wifi RSSI thresh error!!\n");
192 			return coex_sta->pre_wifi_rssi_state[index];
193 		}
194 
195 		if ((coex_sta->pre_wifi_rssi_state[index] ==
196 		     BTC_RSSI_STATE_LOW) ||
197 		    (coex_sta->pre_wifi_rssi_state[index] ==
198 		     BTC_RSSI_STATE_STAY_LOW)) {
199 			if (wifi_rssi >= (rssi_thresh +
200 					BTC_RSSI_COEX_THRESH_TOL_8821A_1ANT)) {
201 				wifi_rssi_state = BTC_RSSI_STATE_MEDIUM;
202 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
203 					 "[BTCoex], wifi RSSI state switch to Medium\n");
204 			} else {
205 				wifi_rssi_state = BTC_RSSI_STATE_STAY_LOW;
206 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
207 					 "[BTCoex], wifi RSSI state stay at Low\n");
208 			}
209 		} else if ((coex_sta->pre_wifi_rssi_state[index] ==
210 			BTC_RSSI_STATE_MEDIUM) ||
211 			(coex_sta->pre_wifi_rssi_state[index] ==
212 			BTC_RSSI_STATE_STAY_MEDIUM)) {
213 			if (wifi_rssi >= (rssi_thresh1 +
214 					BTC_RSSI_COEX_THRESH_TOL_8821A_1ANT)) {
215 				wifi_rssi_state = BTC_RSSI_STATE_HIGH;
216 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
217 					 "[BTCoex], wifi RSSI state switch to High\n");
218 			} else if (wifi_rssi < rssi_thresh) {
219 				wifi_rssi_state = BTC_RSSI_STATE_LOW;
220 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
221 					 "[BTCoex], wifi RSSI state switch to Low\n");
222 			} else {
223 				wifi_rssi_state = BTC_RSSI_STATE_STAY_MEDIUM;
224 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
225 					 "[BTCoex], wifi RSSI state stay at Medium\n");
226 			}
227 		} else {
228 			if (wifi_rssi < rssi_thresh1) {
229 				wifi_rssi_state = BTC_RSSI_STATE_MEDIUM;
230 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
231 					 "[BTCoex], wifi RSSI state switch to Medium\n");
232 			} else {
233 				wifi_rssi_state = BTC_RSSI_STATE_STAY_HIGH;
234 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
235 					 "[BTCoex], wifi RSSI state stay at High\n");
236 			}
237 		}
238 	}
239 	coex_sta->pre_wifi_rssi_state[index] = wifi_rssi_state;
240 
241 	return wifi_rssi_state;
242 }
243 
244 static void btc8821a1ant_update_ra_mask(struct btc_coexist *btcoexist,
245 					bool force_exec, u32 dis_rate_mask)
246 {
247 	coex_dm->cur_ra_mask = dis_rate_mask;
248 
249 	if (force_exec ||
250 	    (coex_dm->pre_ra_mask != coex_dm->cur_ra_mask)) {
251 		btcoexist->btc_set(btcoexist, BTC_SET_ACT_UPDATE_RAMASK,
252 				   &coex_dm->cur_ra_mask);
253 	}
254 	coex_dm->pre_ra_mask = coex_dm->cur_ra_mask;
255 }
256 
257 static void btc8821a1ant_auto_rate_fb_retry(struct btc_coexist *btcoexist,
258 					    bool force_exec, u8 type)
259 {
260 	bool wifi_under_b_mode = false;
261 
262 	coex_dm->cur_arfr_type = type;
263 
264 	if (force_exec ||
265 	    (coex_dm->pre_arfr_type != coex_dm->cur_arfr_type)) {
266 		switch (coex_dm->cur_arfr_type) {
267 		case 0:	/* normal mode */
268 			btcoexist->btc_write_4byte(btcoexist, 0x430,
269 						   coex_dm->backup_arfr_cnt1);
270 			btcoexist->btc_write_4byte(btcoexist, 0x434,
271 						   coex_dm->backup_arfr_cnt2);
272 			break;
273 		case 1:
274 			btcoexist->btc_get(btcoexist,
275 					   BTC_GET_BL_WIFI_UNDER_B_MODE,
276 					   &wifi_under_b_mode);
277 			if (wifi_under_b_mode) {
278 				btcoexist->btc_write_4byte(btcoexist, 0x430,
279 							   0x0);
280 				btcoexist->btc_write_4byte(btcoexist, 0x434,
281 							   0x01010101);
282 			} else {
283 				btcoexist->btc_write_4byte(btcoexist, 0x430,
284 							   0x0);
285 				btcoexist->btc_write_4byte(btcoexist, 0x434,
286 							   0x04030201);
287 			}
288 			break;
289 		default:
290 			break;
291 		}
292 	}
293 
294 	coex_dm->pre_arfr_type = coex_dm->cur_arfr_type;
295 }
296 
297 static void btc8821a1ant_retry_limit(struct btc_coexist *btcoexist,
298 				     bool force_exec, u8 type)
299 {
300 	coex_dm->cur_retry_limit_type = type;
301 
302 	if (force_exec ||
303 	    (coex_dm->pre_retry_limit_type != coex_dm->cur_retry_limit_type)) {
304 		switch (coex_dm->cur_retry_limit_type) {
305 		case 0:	/* normal mode */
306 			btcoexist->btc_write_2byte(btcoexist, 0x42a,
307 						   coex_dm->backup_retry_limit);
308 			break;
309 		case 1:	/* retry limit = 8 */
310 			btcoexist->btc_write_2byte(btcoexist, 0x42a, 0x0808);
311 			break;
312 		default:
313 			break;
314 		}
315 	}
316 	coex_dm->pre_retry_limit_type = coex_dm->cur_retry_limit_type;
317 }
318 
319 static void btc8821a1ant_ampdu_max_time(struct btc_coexist *btcoexist,
320 					bool force_exec, u8 type)
321 {
322 	coex_dm->cur_ampdu_time_type = type;
323 
324 	if (force_exec ||
325 	    (coex_dm->pre_ampdu_time_type != coex_dm->cur_ampdu_time_type)) {
326 		switch (coex_dm->cur_ampdu_time_type) {
327 		case 0:	/* normal mode */
328 			btcoexist->btc_write_1byte(btcoexist, 0x456,
329 						   coex_dm->backup_ampdu_max_time);
330 			break;
331 		case 1:	/* AMPDU time = 0x38 * 32us */
332 			btcoexist->btc_write_1byte(btcoexist, 0x456, 0x38);
333 			break;
334 		default:
335 			break;
336 		}
337 	}
338 
339 	coex_dm->pre_ampdu_time_type = coex_dm->cur_ampdu_time_type;
340 }
341 
342 static void btc8821a1ant_limited_tx(struct btc_coexist *btcoexist,
343 				    bool force_exec, u8 ra_mask_type,
344 				    u8 arfr_type, u8 retry_limit_type,
345 				    u8 ampdu_time_type)
346 {
347 	switch (ra_mask_type) {
348 	case 0:	/* normal mode */
349 		btc8821a1ant_update_ra_mask(btcoexist, force_exec, 0x0);
350 		break;
351 	case 1:	/* disable cck 1/2 */
352 		btc8821a1ant_update_ra_mask(btcoexist, force_exec,
353 					    0x00000003);
354 		break;
355 	case 2:	/* disable cck 1/2/5.5, ofdm 6/9/12/18/24, mcs 0/1/2/3/4 */
356 		btc8821a1ant_update_ra_mask(btcoexist, force_exec,
357 					    0x0001f1f7);
358 		break;
359 	default:
360 		break;
361 	}
362 
363 	btc8821a1ant_auto_rate_fb_retry(btcoexist, force_exec, arfr_type);
364 	btc8821a1ant_retry_limit(btcoexist, force_exec, retry_limit_type);
365 	btc8821a1ant_ampdu_max_time(btcoexist, force_exec, ampdu_time_type);
366 }
367 
368 static void btc8821a1ant_limited_rx(struct btc_coexist *btcoexist,
369 				    bool force_exec, bool rej_ap_agg_pkt,
370 				    bool bt_ctrl_agg_buf_size, u8 agg_buf_size)
371 {
372 	bool reject_rx_agg = rej_ap_agg_pkt;
373 	bool bt_ctrl_rx_agg_size = bt_ctrl_agg_buf_size;
374 	u8 rx_agg_size = agg_buf_size;
375 
376 	/* Rx Aggregation related setting */
377 	btcoexist->btc_set(btcoexist,
378 		 BTC_SET_BL_TO_REJ_AP_AGG_PKT, &reject_rx_agg);
379 	/* decide BT control aggregation buf size or not */
380 	btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_CTRL_AGG_SIZE,
381 			   &bt_ctrl_rx_agg_size);
382 	/* aggregation buf size, only work when BT control Rx agg size */
383 	btcoexist->btc_set(btcoexist, BTC_SET_U1_AGG_BUF_SIZE, &rx_agg_size);
384 	/* real update aggregation setting */
385 	btcoexist->btc_set(btcoexist, BTC_SET_ACT_AGGREGATE_CTRL, NULL);
386 }
387 
388 static void btc8821a1ant_monitor_bt_ctr(struct btc_coexist *btcoexist)
389 {
390 	u32 reg_hp_tx_rx, reg_lp_tx_rx, u4_tmp;
391 	u32 reg_hp_tx = 0, reg_hp_rx = 0, reg_lp_tx = 0, reg_lp_rx = 0;
392 
393 	reg_hp_tx_rx = 0x770;
394 	reg_lp_tx_rx = 0x774;
395 
396 	u4_tmp = btcoexist->btc_read_4byte(btcoexist, reg_hp_tx_rx);
397 	reg_hp_tx = u4_tmp & MASKLWORD;
398 	reg_hp_rx = (u4_tmp & MASKHWORD) >> 16;
399 
400 	u4_tmp = btcoexist->btc_read_4byte(btcoexist, reg_lp_tx_rx);
401 	reg_lp_tx = u4_tmp & MASKLWORD;
402 	reg_lp_rx = (u4_tmp & MASKHWORD) >> 16;
403 
404 	coex_sta->high_priority_tx = reg_hp_tx;
405 	coex_sta->high_priority_rx = reg_hp_rx;
406 	coex_sta->low_priority_tx = reg_lp_tx;
407 	coex_sta->low_priority_rx = reg_lp_rx;
408 
409 	/* reset counter */
410 	btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc);
411 }
412 
413 static void btc8821a1ant_query_bt_info(struct btc_coexist *btcoexist)
414 {
415 	struct rtl_priv *rtlpriv = btcoexist->adapter;
416 	u8 h2c_parameter[1] = {0};
417 
418 	coex_sta->c2h_bt_info_req_sent = true;
419 
420 	h2c_parameter[0] |= BIT0; /* trigger */
421 
422 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
423 		 "[BTCoex], Query Bt Info, FW write 0x61 = 0x%x\n",
424 		 h2c_parameter[0]);
425 
426 	btcoexist->btc_fill_h2c(btcoexist, 0x61, 1, h2c_parameter);
427 }
428 
429 bool btc8821a1ant_is_wifi_status_changed(struct btc_coexist *btcoexist)
430 {
431 	static bool pre_wifi_busy = true;
432 	static bool pre_under_4way = true;
433 	static bool pre_bt_hs_on = true;
434 	bool wifi_busy = false, under_4way = false, bt_hs_on = false;
435 	bool wifi_connected = false;
436 
437 	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
438 			   &wifi_connected);
439 	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
440 	btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
441 	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS,
442 			   &under_4way);
443 
444 	if (wifi_connected) {
445 		if (wifi_busy != pre_wifi_busy) {
446 			pre_wifi_busy = wifi_busy;
447 			return true;
448 		}
449 		if (under_4way != pre_under_4way) {
450 			pre_under_4way = under_4way;
451 			return true;
452 		}
453 		if (bt_hs_on != pre_bt_hs_on) {
454 			pre_bt_hs_on = bt_hs_on;
455 			return true;
456 		}
457 	}
458 
459 	return false;
460 }
461 
462 static void btc8821a1ant_update_bt_link_info(struct btc_coexist *btcoexist)
463 {
464 	struct btc_bt_link_info	*bt_link_info = &btcoexist->bt_link_info;
465 	bool bt_hs_on = false;
466 
467 	btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
468 
469 	bt_link_info->bt_link_exist = coex_sta->bt_link_exist;
470 	bt_link_info->sco_exist = coex_sta->sco_exist;
471 	bt_link_info->a2dp_exist = coex_sta->a2dp_exist;
472 	bt_link_info->pan_exist = coex_sta->pan_exist;
473 	bt_link_info->hid_exist = coex_sta->hid_exist;
474 
475 	/* work around for HS mode */
476 	if (bt_hs_on) {
477 		bt_link_info->pan_exist = true;
478 		bt_link_info->bt_link_exist = true;
479 	}
480 
481 	/* check if Sco only */
482 	if (bt_link_info->sco_exist &&
483 	    !bt_link_info->a2dp_exist &&
484 	    !bt_link_info->pan_exist &&
485 	    !bt_link_info->hid_exist)
486 		bt_link_info->sco_only = true;
487 	else
488 		bt_link_info->sco_only = false;
489 
490 	/* check if A2dp only */
491 	if (!bt_link_info->sco_exist &&
492 	    bt_link_info->a2dp_exist &&
493 	    !bt_link_info->pan_exist &&
494 	    !bt_link_info->hid_exist)
495 		bt_link_info->a2dp_only = true;
496 	else
497 		bt_link_info->a2dp_only = false;
498 
499 	/* check if Pan only */
500 	if (!bt_link_info->sco_exist &&
501 	    !bt_link_info->a2dp_exist &&
502 	    bt_link_info->pan_exist &&
503 	    !bt_link_info->hid_exist)
504 		bt_link_info->pan_only = true;
505 	else
506 		bt_link_info->pan_only = false;
507 
508 	/* check if Hid only */
509 	if (!bt_link_info->sco_exist &&
510 	    !bt_link_info->a2dp_exist &&
511 	    !bt_link_info->pan_exist &&
512 	    bt_link_info->hid_exist)
513 		bt_link_info->hid_only = true;
514 	else
515 		bt_link_info->hid_only = false;
516 }
517 
518 static u8 btc8821a1ant_action_algorithm(struct btc_coexist *btcoexist)
519 {
520 	struct rtl_priv *rtlpriv = btcoexist->adapter;
521 	struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
522 	bool bt_hs_on = false;
523 	u8 algorithm = BT_8821A_1ANT_COEX_ALGO_UNDEFINED;
524 	u8 num_of_diff_profile = 0;
525 
526 	btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
527 
528 	if (!bt_link_info->bt_link_exist) {
529 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
530 			 "[BTCoex], No BT link exists!!!\n");
531 		return algorithm;
532 	}
533 
534 	if (bt_link_info->sco_exist)
535 		num_of_diff_profile++;
536 	if (bt_link_info->hid_exist)
537 		num_of_diff_profile++;
538 	if (bt_link_info->pan_exist)
539 		num_of_diff_profile++;
540 	if (bt_link_info->a2dp_exist)
541 		num_of_diff_profile++;
542 
543 	if (num_of_diff_profile == 1) {
544 		if (bt_link_info->sco_exist) {
545 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
546 				 "[BTCoex], BT Profile = SCO only\n");
547 			algorithm = BT_8821A_1ANT_COEX_ALGO_SCO;
548 		} else {
549 			if (bt_link_info->hid_exist) {
550 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
551 					 "[BTCoex], BT Profile = HID only\n");
552 				algorithm = BT_8821A_1ANT_COEX_ALGO_HID;
553 			} else if (bt_link_info->a2dp_exist) {
554 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
555 					 "[BTCoex], BT Profile = A2DP only\n");
556 				algorithm = BT_8821A_1ANT_COEX_ALGO_A2DP;
557 			} else if (bt_link_info->pan_exist) {
558 				if (bt_hs_on) {
559 					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
560 						 DBG_LOUD,
561 						 "[BTCoex], BT Profile = PAN(HS) only\n");
562 					algorithm = BT_8821A_1ANT_COEX_ALGO_PANHS;
563 				} else {
564 					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
565 						 DBG_LOUD,
566 						 "[BTCoex], BT Profile = PAN(EDR) only\n");
567 					algorithm = BT_8821A_1ANT_COEX_ALGO_PANEDR;
568 				}
569 			}
570 		}
571 	} else if (num_of_diff_profile == 2) {
572 		if (bt_link_info->sco_exist) {
573 			if (bt_link_info->hid_exist) {
574 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
575 					 "[BTCoex], BT Profile = SCO + HID\n");
576 				algorithm = BT_8821A_1ANT_COEX_ALGO_HID;
577 			} else if (bt_link_info->a2dp_exist) {
578 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
579 					 "[BTCoex], BT Profile = SCO + A2DP ==> SCO\n");
580 				algorithm = BT_8821A_1ANT_COEX_ALGO_SCO;
581 			} else if (bt_link_info->pan_exist) {
582 				if (bt_hs_on) {
583 					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
584 						 DBG_LOUD,
585 						 "[BTCoex], BT Profile = SCO + PAN(HS)\n");
586 					algorithm = BT_8821A_1ANT_COEX_ALGO_SCO;
587 				} else {
588 					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
589 						 DBG_LOUD,
590 						 "[BTCoex], BT Profile = SCO + PAN(EDR)\n");
591 					algorithm = BT_8821A_1ANT_COEX_ALGO_PANEDR_HID;
592 				}
593 			}
594 		} else {
595 			if (bt_link_info->hid_exist &&
596 			    bt_link_info->a2dp_exist) {
597 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
598 					 "[BTCoex], BT Profile = HID + A2DP\n");
599 				algorithm = BT_8821A_1ANT_COEX_ALGO_HID_A2DP;
600 			} else if (bt_link_info->hid_exist &&
601 				   bt_link_info->pan_exist) {
602 				if (bt_hs_on) {
603 					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
604 						 DBG_LOUD,
605 						 "[BTCoex], BT Profile = HID + PAN(HS)\n");
606 					algorithm = BT_8821A_1ANT_COEX_ALGO_HID_A2DP;
607 				} else {
608 					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
609 						 DBG_LOUD,
610 						 "[BTCoex], BT Profile = HID + PAN(EDR)\n");
611 					algorithm = BT_8821A_1ANT_COEX_ALGO_PANEDR_HID;
612 				}
613 			} else if (bt_link_info->pan_exist &&
614 				   bt_link_info->a2dp_exist) {
615 				if (bt_hs_on) {
616 					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
617 						 DBG_LOUD,
618 						 "[BTCoex], BT Profile = A2DP + PAN(HS)\n");
619 					algorithm = BT_8821A_1ANT_COEX_ALGO_A2DP_PANHS;
620 				} else {
621 					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
622 						 DBG_LOUD,
623 						 "[BTCoex], BT Profile = A2DP + PAN(EDR)\n");
624 					algorithm = BT_8821A_1ANT_COEX_ALGO_PANEDR_A2DP;
625 				}
626 			}
627 		}
628 	} else if (num_of_diff_profile == 3) {
629 		if (bt_link_info->sco_exist) {
630 			if (bt_link_info->hid_exist &&
631 			    bt_link_info->a2dp_exist) {
632 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
633 					 "[BTCoex], BT Profile = SCO + HID + A2DP ==> HID\n");
634 				algorithm = BT_8821A_1ANT_COEX_ALGO_HID;
635 			} else if (bt_link_info->hid_exist &&
636 				   bt_link_info->pan_exist) {
637 				if (bt_hs_on) {
638 					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
639 						 DBG_LOUD,
640 						 "[BTCoex], BT Profile = SCO + HID + PAN(HS)\n");
641 					algorithm = BT_8821A_1ANT_COEX_ALGO_HID_A2DP;
642 				} else {
643 					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
644 						 DBG_LOUD,
645 						 "[BTCoex], BT Profile = SCO + HID + PAN(EDR)\n");
646 					algorithm = BT_8821A_1ANT_COEX_ALGO_PANEDR_HID;
647 				}
648 			} else if (bt_link_info->pan_exist &&
649 				   bt_link_info->a2dp_exist) {
650 				if (bt_hs_on) {
651 					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
652 						 DBG_LOUD,
653 						 "[BTCoex], BT Profile = SCO + A2DP + PAN(HS)\n");
654 					algorithm = BT_8821A_1ANT_COEX_ALGO_SCO;
655 				} else {
656 					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
657 						 DBG_LOUD,
658 						 "[BTCoex], BT Profile = SCO + A2DP + PAN(EDR) ==> HID\n");
659 					algorithm = BT_8821A_1ANT_COEX_ALGO_PANEDR_HID;
660 				}
661 			}
662 		} else {
663 			if (bt_link_info->hid_exist &&
664 			    bt_link_info->pan_exist &&
665 			    bt_link_info->a2dp_exist) {
666 				if (bt_hs_on) {
667 					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
668 						 DBG_LOUD,
669 						 "[BTCoex], BT Profile = HID + A2DP + PAN(HS)\n");
670 					algorithm = BT_8821A_1ANT_COEX_ALGO_HID_A2DP;
671 				} else {
672 					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
673 						 DBG_LOUD,
674 						 "[BTCoex], BT Profile = HID + A2DP + PAN(EDR)\n");
675 					algorithm = BT_8821A_1ANT_COEX_ALGO_HID_A2DP_PANEDR;
676 				}
677 			}
678 		}
679 	} else if (num_of_diff_profile >= 3) {
680 		if (bt_link_info->sco_exist) {
681 			if (bt_link_info->hid_exist &&
682 			    bt_link_info->pan_exist &&
683 			    bt_link_info->a2dp_exist) {
684 				if (bt_hs_on) {
685 					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
686 						 DBG_LOUD,
687 						 "[BTCoex], Error!!! BT Profile = SCO + HID + A2DP + PAN(HS)\n");
688 
689 				} else {
690 					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
691 						 DBG_LOUD,
692 						 "[BTCoex], BT Profile = SCO + HID + A2DP + PAN(EDR)==>PAN(EDR)+HID\n");
693 					algorithm = BT_8821A_1ANT_COEX_ALGO_PANEDR_HID;
694 				}
695 			}
696 		}
697 	}
698 	return algorithm;
699 }
700 
701 static void btc8821a1ant_set_sw_penalty_tx_rate(struct btc_coexist *btcoexist,
702 						bool low_penalty_ra)
703 {
704 	struct rtl_priv *rtlpriv = btcoexist->adapter;
705 	u8 h2c_parameter[6] = {0};
706 
707 	h2c_parameter[0] = 0x6;	/* opCode, 0x6= Retry_Penalty*/
708 
709 	if (low_penalty_ra) {
710 		h2c_parameter[1] |= BIT0;
711 		/* normal rate except MCS7/6/5, OFDM54/48/36 */
712 		h2c_parameter[2] = 0x00;
713 		h2c_parameter[3] = 0xf7; /* MCS7 or OFDM54 */
714 		h2c_parameter[4] = 0xf8; /* MCS6 or OFDM48 */
715 		h2c_parameter[5] = 0xf9; /* MCS5 or OFDM36 */
716 	}
717 
718 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
719 		 "[BTCoex], set WiFi Low-Penalty Retry: %s",
720 		 (low_penalty_ra ? "ON!!" : "OFF!!"));
721 
722 	btcoexist->btc_fill_h2c(btcoexist, 0x69, 6, h2c_parameter);
723 }
724 
725 static void btc8821a1ant_low_penalty_ra(struct btc_coexist *btcoexist,
726 					bool force_exec, bool low_penalty_ra)
727 {
728 	coex_dm->cur_low_penalty_ra = low_penalty_ra;
729 
730 	if (!force_exec) {
731 		if (coex_dm->pre_low_penalty_ra == coex_dm->cur_low_penalty_ra)
732 			return;
733 	}
734 	btc8821a1ant_set_sw_penalty_tx_rate(btcoexist,
735 					    coex_dm->cur_low_penalty_ra);
736 
737 	coex_dm->pre_low_penalty_ra = coex_dm->cur_low_penalty_ra;
738 }
739 
740 static void btc8821a1ant_set_coex_table(struct btc_coexist *btcoexist,
741 					u32 val0x6c0, u32 val0x6c4,
742 					u32 val0x6c8, u8 val0x6cc)
743 {
744 	struct rtl_priv *rtlpriv = btcoexist->adapter;
745 
746 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
747 		 "[BTCoex], set coex table, set 0x6c0 = 0x%x\n", val0x6c0);
748 	btcoexist->btc_write_4byte(btcoexist, 0x6c0, val0x6c0);
749 
750 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
751 		 "[BTCoex], set coex table, set 0x6c4 = 0x%x\n", val0x6c4);
752 	btcoexist->btc_write_4byte(btcoexist, 0x6c4, val0x6c4);
753 
754 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
755 		 "[BTCoex], set coex table, set 0x6c8 = 0x%x\n", val0x6c8);
756 	btcoexist->btc_write_4byte(btcoexist, 0x6c8, val0x6c8);
757 
758 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
759 		 "[BTCoex], set coex table, set 0x6cc = 0x%x\n", val0x6cc);
760 	btcoexist->btc_write_1byte(btcoexist, 0x6cc, val0x6cc);
761 }
762 
763 static void btc8821a1ant_coex_table(struct btc_coexist *btcoexist,
764 				    bool force_exec, u32 val0x6c0, u32 val0x6c4,
765 				    u32 val0x6c8, u8 val0x6cc)
766 {
767 	struct rtl_priv *rtlpriv = btcoexist->adapter;
768 
769 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
770 		 "[BTCoex], %s write Coex Table 0x6c0 = 0x%x, 0x6c4 = 0x%x, 0x6c8 = 0x%x, 0x6cc = 0x%x\n",
771 		    (force_exec ? "force to" : ""), val0x6c0, val0x6c4,
772 		    val0x6c8, val0x6cc);
773 	coex_dm->cur_val_0x6c0 = val0x6c0;
774 	coex_dm->cur_val_0x6c4 = val0x6c4;
775 	coex_dm->cur_val_0x6c8 = val0x6c8;
776 	coex_dm->cur_val_0x6cc = val0x6cc;
777 
778 	if (!force_exec) {
779 		if ((coex_dm->pre_val_0x6c0 == coex_dm->cur_val_0x6c0) &&
780 		    (coex_dm->pre_val_0x6c4 == coex_dm->cur_val_0x6c4) &&
781 		    (coex_dm->pre_val_0x6c8 == coex_dm->cur_val_0x6c8) &&
782 		    (coex_dm->pre_val_0x6cc == coex_dm->cur_val_0x6cc))
783 			return;
784 	}
785 	btc8821a1ant_set_coex_table(btcoexist, val0x6c0, val0x6c4,
786 				    val0x6c8, val0x6cc);
787 
788 	coex_dm->pre_val_0x6c0 = coex_dm->cur_val_0x6c0;
789 	coex_dm->pre_val_0x6c4 = coex_dm->cur_val_0x6c4;
790 	coex_dm->pre_val_0x6c8 = coex_dm->cur_val_0x6c8;
791 	coex_dm->pre_val_0x6cc = coex_dm->cur_val_0x6cc;
792 }
793 
794 static void btc8821a1ant_coex_table_with_type(struct btc_coexist *btcoexist,
795 					      bool force_exec, u8 type)
796 {
797 	switch (type) {
798 	case 0:
799 		btc8821a1ant_coex_table(btcoexist, force_exec, 0x55555555,
800 					0x55555555, 0xffffff, 0x3);
801 		break;
802 	case 1:
803 		btc8821a1ant_coex_table(btcoexist, force_exec, 0x55555555,
804 					0x5a5a5a5a, 0xffffff, 0x3);
805 		break;
806 	case 2:
807 		btc8821a1ant_coex_table(btcoexist, force_exec, 0x5a5a5a5a,
808 					0x5a5a5a5a, 0xffffff, 0x3);
809 		break;
810 	case 3:
811 		btc8821a1ant_coex_table(btcoexist, force_exec, 0x5a5a5a5a,
812 					0xaaaaaaaa, 0xffffff, 0x3);
813 		break;
814 	case 4:
815 		btc8821a1ant_coex_table(btcoexist, force_exec, 0x55555555,
816 					0x5a5a5a5a, 0xffffff, 0x3);
817 		break;
818 	case 5:
819 		btc8821a1ant_coex_table(btcoexist, force_exec, 0x5a5a5a5a,
820 					0xaaaa5a5a, 0xffffff, 0x3);
821 		break;
822 	case 6:
823 		btc8821a1ant_coex_table(btcoexist, force_exec, 0x55555555,
824 					0xaaaa5a5a, 0xffffff, 0x3);
825 		break;
826 	case 7:
827 		btc8821a1ant_coex_table(btcoexist, force_exec, 0xaaaaaaaa,
828 					0xaaaaaaaa, 0xffffff, 0x3);
829 		break;
830 	default:
831 		break;
832 	}
833 }
834 
835 static void btc8821a1ant_set_fw_ignore_wlan_act(struct btc_coexist *btcoexist,
836 						bool enable)
837 {
838 	struct rtl_priv *rtlpriv = btcoexist->adapter;
839 	u8 h2c_parameter[1] = {0};
840 
841 	if (enable)
842 		h2c_parameter[0] |= BIT0; /* function enable */
843 
844 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
845 		 "[BTCoex], set FW for BT Ignore Wlan_Act, FW write 0x63 = 0x%x\n",
846 		 h2c_parameter[0]);
847 
848 	btcoexist->btc_fill_h2c(btcoexist, 0x63, 1, h2c_parameter);
849 }
850 
851 static void btc8821a1ant_ignore_wlan_act(struct btc_coexist *btcoexist,
852 					 bool force_exec, bool enable)
853 {
854 	struct rtl_priv *rtlpriv = btcoexist->adapter;
855 
856 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
857 		 "[BTCoex], %s turn Ignore WlanAct %s\n",
858 		 (force_exec ? "force to" : ""), (enable ? "ON" : "OFF"));
859 	coex_dm->cur_ignore_wlan_act = enable;
860 
861 	if (!force_exec) {
862 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
863 			 "[BTCoex], pre_ignore_wlan_act = %d, cur_ignore_wlan_act = %d!!\n",
864 			 coex_dm->pre_ignore_wlan_act,
865 			 coex_dm->cur_ignore_wlan_act);
866 
867 		if (coex_dm->pre_ignore_wlan_act ==
868 		    coex_dm->cur_ignore_wlan_act)
869 			return;
870 	}
871 	btc8821a1ant_set_fw_ignore_wlan_act(btcoexist, enable);
872 
873 	coex_dm->pre_ignore_wlan_act = coex_dm->cur_ignore_wlan_act;
874 }
875 
876 static void btc8821a1ant_set_fw_ps_tdma(struct btc_coexist *btcoexist, u8 byte1,
877 					u8 byte2, u8 byte3, u8 byte4, u8 byte5)
878 {
879 	struct rtl_priv *rtlpriv = btcoexist->adapter;
880 	u8 h2c_parameter[5] = {0};
881 	u8 real_byte1 = byte1, real_byte5 = byte5;
882 	bool ap_enable = false;
883 
884 	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE,
885 			   &ap_enable);
886 
887 	if (ap_enable) {
888 		if (byte1 & BIT4 && !(byte1 & BIT5)) {
889 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
890 				 "[BTCoex], FW for 1Ant AP mode\n");
891 			real_byte1 &= ~BIT4;
892 			real_byte1 |= BIT5;
893 
894 			real_byte5 |= BIT5;
895 			real_byte5 &= ~BIT6;
896 		}
897 	}
898 
899 	h2c_parameter[0] = real_byte1;
900 	h2c_parameter[1] = byte2;
901 	h2c_parameter[2] = byte3;
902 	h2c_parameter[3] = byte4;
903 	h2c_parameter[4] = real_byte5;
904 
905 	coex_dm->ps_tdma_para[0] = real_byte1;
906 	coex_dm->ps_tdma_para[1] = byte2;
907 	coex_dm->ps_tdma_para[2] = byte3;
908 	coex_dm->ps_tdma_para[3] = byte4;
909 	coex_dm->ps_tdma_para[4] = real_byte5;
910 
911 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
912 		 "[BTCoex], PS-TDMA H2C cmd =0x%x%08x\n",
913 		 h2c_parameter[0],
914 		 h2c_parameter[1] << 24 |
915 		 h2c_parameter[2] << 16 |
916 		 h2c_parameter[3] << 8 |
917 		 h2c_parameter[4]);
918 	btcoexist->btc_fill_h2c(btcoexist, 0x60, 5, h2c_parameter);
919 }
920 
921 static void btc8821a1ant_set_lps_rpwm(struct btc_coexist *btcoexist,
922 				      u8 lps_val, u8 rpwm_val)
923 {
924 	u8 lps = lps_val;
925 	u8 rpwm = rpwm_val;
926 
927 	btcoexist->btc_set(btcoexist, BTC_SET_U1_LPS_VAL, &lps);
928 	btcoexist->btc_set(btcoexist, BTC_SET_U1_RPWM_VAL, &rpwm);
929 }
930 
931 static void btc8821a1ant_lps_rpwm(struct btc_coexist *btcoexist,
932 				  bool force_exec, u8 lps_val, u8 rpwm_val)
933 {
934 	struct rtl_priv *rtlpriv = btcoexist->adapter;
935 
936 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
937 		 "[BTCoex], %s set lps/rpwm = 0x%x/0x%x\n",
938 		 (force_exec ? "force to" : ""), lps_val, rpwm_val);
939 	coex_dm->cur_lps = lps_val;
940 	coex_dm->cur_rpwm = rpwm_val;
941 
942 	if (!force_exec) {
943 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
944 			 "[BTCoex], LPS-RxBeaconMode = 0x%x, LPS-RPWM = 0x%x!!\n",
945 			 coex_dm->cur_lps, coex_dm->cur_rpwm);
946 
947 		if ((coex_dm->pre_lps == coex_dm->cur_lps) &&
948 		    (coex_dm->pre_rpwm == coex_dm->cur_rpwm)) {
949 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
950 				 "[BTCoex], LPS-RPWM_Last = 0x%x, LPS-RPWM_Now = 0x%x!!\n",
951 				 coex_dm->pre_rpwm, coex_dm->cur_rpwm);
952 
953 			return;
954 		}
955 	}
956 	btc8821a1ant_set_lps_rpwm(btcoexist, lps_val, rpwm_val);
957 
958 	coex_dm->pre_lps = coex_dm->cur_lps;
959 	coex_dm->pre_rpwm = coex_dm->cur_rpwm;
960 }
961 
962 static void btc8821a1ant_sw_mechanism(struct btc_coexist *btcoexist,
963 				      bool low_penalty_ra)
964 {
965 	struct rtl_priv *rtlpriv = btcoexist->adapter;
966 
967 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
968 		 "[BTCoex], SM[LpRA] = %d\n", low_penalty_ra);
969 
970 	btc8821a1ant_low_penalty_ra(btcoexist, NORMAL_EXEC, low_penalty_ra);
971 }
972 
973 static void btc8821a1ant_set_ant_path(struct btc_coexist *btcoexist,
974 				      u8 ant_pos_type, bool init_hw_cfg,
975 				      bool wifi_off)
976 {
977 	struct btc_board_info *board_info = &btcoexist->board_info;
978 	u32 u4_tmp = 0;
979 	u8 h2c_parameter[2] = {0};
980 
981 	if (init_hw_cfg) {
982 		/* 0x4c[23] = 0, 0x4c[24] = 1  Antenna control by WL/BT */
983 		u4_tmp = btcoexist->btc_read_4byte(btcoexist, 0x4c);
984 		u4_tmp &= ~BIT23;
985 		u4_tmp |= BIT24;
986 		btcoexist->btc_write_4byte(btcoexist, 0x4c, u4_tmp);
987 
988 		btcoexist->btc_write_1byte_bitmask(btcoexist, 0x975, 0x3, 0x3);
989 		btcoexist->btc_write_1byte(btcoexist, 0xcb4, 0x77);
990 
991 		if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT) {
992 			/* tell firmware "antenna inverse"
993 			 * WRONG firmware antenna control code, need fw to fix
994 			 */
995 			h2c_parameter[0] = 1;
996 			h2c_parameter[1] = 1;
997 			btcoexist->btc_fill_h2c(btcoexist, 0x65, 2,
998 						h2c_parameter);
999 		} else {
1000 			/* tell firmware "no antenna inverse"
1001 			 * WRONG firmware antenna control code, need fw to fix
1002 			 */
1003 			h2c_parameter[0] = 0;
1004 			h2c_parameter[1] = 1;
1005 			btcoexist->btc_fill_h2c(btcoexist, 0x65, 2,
1006 						h2c_parameter);
1007 		}
1008 	} else if (wifi_off) {
1009 		/* 0x4c[24:23] = 00, Set Antenna control
1010 		 * by BT_RFE_CTRL BT Vendor 0xac = 0xf002
1011 		 */
1012 		u4_tmp = btcoexist->btc_read_4byte(btcoexist, 0x4c);
1013 		u4_tmp &= ~BIT23;
1014 		u4_tmp &= ~BIT24;
1015 		btcoexist->btc_write_4byte(btcoexist, 0x4c, u4_tmp);
1016 
1017 		/* 0x765 = 0x18 */
1018 		btcoexist->btc_write_1byte_bitmask(btcoexist, 0x765, 0x18, 0x3);
1019 	} else {
1020 		/* 0x765 = 0x0 */
1021 		btcoexist->btc_write_1byte_bitmask(btcoexist, 0x765, 0x18, 0x0);
1022 	}
1023 
1024 	/* ext switch setting */
1025 	switch (ant_pos_type) {
1026 	case BTC_ANT_PATH_WIFI:
1027 		btcoexist->btc_write_1byte(btcoexist, 0xcb4, 0x77);
1028 		if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT)
1029 			btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb7,
1030 							   0x30, 0x1);
1031 		else
1032 			btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb7,
1033 							   0x30, 0x2);
1034 		break;
1035 	case BTC_ANT_PATH_BT:
1036 		btcoexist->btc_write_1byte(btcoexist, 0xcb4, 0x77);
1037 		if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT)
1038 			btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb7,
1039 							   0x30, 0x2);
1040 		else
1041 			btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb7,
1042 							   0x30, 0x1);
1043 		break;
1044 	default:
1045 	case BTC_ANT_PATH_PTA:
1046 		btcoexist->btc_write_1byte(btcoexist, 0xcb4, 0x66);
1047 		if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT)
1048 			btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb7,
1049 							   0x30, 0x1);
1050 		else
1051 			btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb7,
1052 							   0x30, 0x2);
1053 		break;
1054 	}
1055 }
1056 
1057 static void btc8821a1ant_ps_tdma(struct btc_coexist *btcoexist,
1058 				 bool force_exec, bool turn_on, u8 type)
1059 {
1060 	struct rtl_priv *rtlpriv = btcoexist->adapter;
1061 	u8 rssi_adjust_val = 0;
1062 
1063 	coex_dm->cur_ps_tdma_on = turn_on;
1064 	coex_dm->cur_ps_tdma = type;
1065 
1066 	if (!force_exec) {
1067 		if (coex_dm->cur_ps_tdma_on) {
1068 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
1069 				 "[BTCoex], ********** TDMA(on, %d) **********\n",
1070 				 coex_dm->cur_ps_tdma);
1071 		} else {
1072 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
1073 				 "[BTCoex], ********** TDMA(off, %d) **********\n",
1074 				 coex_dm->cur_ps_tdma);
1075 		}
1076 		if ((coex_dm->pre_ps_tdma_on == coex_dm->cur_ps_tdma_on) &&
1077 		    (coex_dm->pre_ps_tdma == coex_dm->cur_ps_tdma))
1078 			return;
1079 	}
1080 	if (turn_on) {
1081 		switch (type) {
1082 		default:
1083 			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x1a,
1084 						    0x1a, 0x0, 0x50);
1085 			break;
1086 		case 1:
1087 			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x3a,
1088 						    0x03, 0x10, 0x50);
1089 			rssi_adjust_val = 11;
1090 			break;
1091 		case 2:
1092 			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x2b,
1093 						    0x03, 0x10, 0x50);
1094 			rssi_adjust_val = 14;
1095 			break;
1096 		case 3:
1097 			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x1d,
1098 						    0x1d, 0x0, 0x10);
1099 			break;
1100 		case 4:
1101 			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x93, 0x15,
1102 						    0x3, 0x14, 0x0);
1103 			rssi_adjust_val = 17;
1104 			break;
1105 		case 5:
1106 			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x61, 0x15,
1107 						    0x3, 0x11, 0x10);
1108 			break;
1109 		case 6:
1110 			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x61, 0x20,
1111 						    0x3, 0x11, 0x13);
1112 			break;
1113 		case 7:
1114 			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x13, 0xc,
1115 						    0x5, 0x0, 0x0);
1116 			break;
1117 		case 8:
1118 			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x93, 0x25,
1119 						    0x3, 0x10, 0x0);
1120 			break;
1121 		case 9:
1122 			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x21,
1123 						    0x3, 0x10, 0x50);
1124 			rssi_adjust_val = 18;
1125 			break;
1126 		case 10:
1127 			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x13, 0xa,
1128 						    0xa, 0x0, 0x40);
1129 			break;
1130 		case 11:
1131 			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x15,
1132 						    0x03, 0x10, 0x50);
1133 			rssi_adjust_val = 20;
1134 			break;
1135 		case 12:
1136 			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x0a,
1137 						    0x0a, 0x0, 0x50);
1138 			break;
1139 		case 13:
1140 			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x12,
1141 						    0x12, 0x0, 0x50);
1142 			break;
1143 		case 14:
1144 			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x1e,
1145 						    0x3, 0x10, 0x14);
1146 			break;
1147 		case 15:
1148 			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x13, 0xa,
1149 						    0x3, 0x8, 0x0);
1150 			break;
1151 		case 16:
1152 			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x93, 0x15,
1153 						    0x3, 0x10, 0x0);
1154 			rssi_adjust_val = 18;
1155 			break;
1156 		case 18:
1157 			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x93, 0x25,
1158 						    0x3, 0x10, 0x0);
1159 			rssi_adjust_val = 14;
1160 			break;
1161 		case 20:
1162 			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x61, 0x35,
1163 						    0x03, 0x11, 0x10);
1164 			break;
1165 		case 21:
1166 			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x61, 0x25,
1167 						    0x03, 0x11, 0x11);
1168 			break;
1169 		case 22:
1170 			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x61, 0x25,
1171 						    0x03, 0x11, 0x10);
1172 			break;
1173 		case 23:
1174 			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x25,
1175 						    0x3, 0x31, 0x18);
1176 			rssi_adjust_val = 22;
1177 			break;
1178 		case 24:
1179 			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x15,
1180 						    0x3, 0x31, 0x18);
1181 			rssi_adjust_val = 22;
1182 			break;
1183 		case 25:
1184 			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0xa,
1185 						    0x3, 0x31, 0x18);
1186 			rssi_adjust_val = 22;
1187 			break;
1188 		case 26:
1189 			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0xa,
1190 						    0x3, 0x31, 0x18);
1191 			rssi_adjust_val = 22;
1192 			break;
1193 		case 27:
1194 			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x25,
1195 						    0x3, 0x31, 0x98);
1196 			rssi_adjust_val = 22;
1197 			break;
1198 		case 28:
1199 			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x69, 0x25,
1200 						    0x3, 0x31, 0x0);
1201 			break;
1202 		case 29:
1203 			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0xab, 0x1a,
1204 						    0x1a, 0x1, 0x10);
1205 			break;
1206 		case 30:
1207 			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x30,
1208 						    0x3, 0x10, 0x10);
1209 			break;
1210 		case 31:
1211 			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0xd3, 0x1a,
1212 						    0x1a, 0, 0x58);
1213 			break;
1214 		case 32:
1215 			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x61, 0x35,
1216 						    0x3, 0x11, 0x11);
1217 			break;
1218 		case 33:
1219 			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0xa3, 0x25,
1220 						    0x3, 0x30, 0x90);
1221 			break;
1222 		case 34:
1223 			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x53, 0x1a,
1224 						    0x1a, 0x0, 0x10);
1225 			break;
1226 		case 35:
1227 			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x63, 0x1a,
1228 						    0x1a, 0x0, 0x10);
1229 			break;
1230 		case 36:
1231 			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0xd3, 0x12,
1232 						    0x3, 0x14, 0x50);
1233 			break;
1234 		case 40:
1235 			/* SoftAP only with no sta associated, BT disable, TDMA
1236 			 * mode for power saving
1237 			 *
1238 			 * here softap mode screen off will cost 70-80mA for
1239 			 * phone
1240 			 */
1241 			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x23, 0x18,
1242 						    0x00, 0x10, 0x24);
1243 			break;
1244 		case 41:
1245 			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x15,
1246 						    0x3, 0x11, 0x11);
1247 			break;
1248 		case 42:
1249 			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x20,
1250 						    0x3, 0x11, 0x11);
1251 			break;
1252 		case 43:
1253 			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x30,
1254 						    0x3, 0x10, 0x11);
1255 			break;
1256 		}
1257 	} else {
1258 		/* disable PS tdma */
1259 		switch (type) {
1260 		case 8:
1261 			/* PTA Control */
1262 			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x8, 0x0, 0x0,
1263 						    0x0, 0x0);
1264 			btc8821a1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA,
1265 						  false, false);
1266 			break;
1267 		case 0:
1268 		default:
1269 			/* Software control, Antenna at BT side */
1270 			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x0, 0x0, 0x0,
1271 						    0x0, 0x0);
1272 			btc8821a1ant_set_ant_path(btcoexist, BTC_ANT_PATH_BT,
1273 						  false, false);
1274 			break;
1275 		case 9:
1276 			/* Software control, Antenna at WiFi side */
1277 			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x0, 0x0, 0x0,
1278 						    0x0, 0x0);
1279 			btc8821a1ant_set_ant_path(btcoexist, BTC_ANT_PATH_WIFI,
1280 						  false, false);
1281 			break;
1282 		case 10:
1283 			/* under 5G */
1284 			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x0, 0x0, 0x0,
1285 						    0x8, 0x0);
1286 			btc8821a1ant_set_ant_path(btcoexist, BTC_ANT_PATH_BT,
1287 						  false, false);
1288 			break;
1289 		}
1290 	}
1291 	rssi_adjust_val = 0;
1292 	btcoexist->btc_set(btcoexist,
1293 		 BTC_SET_U1_RSSI_ADJ_VAL_FOR_1ANT_COEX_TYPE, &rssi_adjust_val);
1294 
1295 	/* update pre state */
1296 	coex_dm->pre_ps_tdma_on = coex_dm->cur_ps_tdma_on;
1297 	coex_dm->pre_ps_tdma = coex_dm->cur_ps_tdma;
1298 }
1299 
1300 static bool btc8821a1ant_is_common_action(struct btc_coexist *btcoexist)
1301 {
1302 	struct rtl_priv *rtlpriv = btcoexist->adapter;
1303 	bool common = false, wifi_connected = false, wifi_busy = false;
1304 
1305 	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
1306 			   &wifi_connected);
1307 	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
1308 
1309 	if (!wifi_connected &&
1310 	    BT_8821A_1ANT_BT_STATUS_NON_CONNECTED_IDLE ==
1311 	    coex_dm->bt_status) {
1312 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
1313 			 "[BTCoex], Wifi non connected-idle + BT non connected-idle!!\n");
1314 		btc8821a1ant_sw_mechanism(btcoexist, false);
1315 
1316 		common = true;
1317 	} else if (wifi_connected &&
1318 		   (BT_8821A_1ANT_BT_STATUS_NON_CONNECTED_IDLE ==
1319 		    coex_dm->bt_status)) {
1320 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
1321 			 "[BTCoex], Wifi connected + BT non connected-idle!!\n");
1322 		btc8821a1ant_sw_mechanism(btcoexist, false);
1323 
1324 		common = true;
1325 	} else if (!wifi_connected &&
1326 		   (BT_8821A_1ANT_BT_STATUS_CONNECTED_IDLE ==
1327 		    coex_dm->bt_status)) {
1328 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
1329 			 "[BTCoex], Wifi non connected-idle + BT connected-idle!!\n");
1330 		btc8821a1ant_sw_mechanism(btcoexist, false);
1331 
1332 		common = true;
1333 	} else if (wifi_connected &&
1334 		   (BT_8821A_1ANT_BT_STATUS_CONNECTED_IDLE ==
1335 		    coex_dm->bt_status)) {
1336 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
1337 			 "[BTCoex], Wifi connected + BT connected-idle!!\n");
1338 		btc8821a1ant_sw_mechanism(btcoexist, false);
1339 
1340 		common = true;
1341 	} else if (!wifi_connected &&
1342 		   (BT_8821A_1ANT_BT_STATUS_CONNECTED_IDLE !=
1343 		    coex_dm->bt_status)) {
1344 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
1345 			 "[BTCoex], Wifi non connected-idle + BT Busy!!\n");
1346 		btc8821a1ant_sw_mechanism(btcoexist, false);
1347 
1348 		common = true;
1349 	} else {
1350 		if (wifi_busy) {
1351 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
1352 				 "[BTCoex], Wifi Connected-Busy + BT Busy!!\n");
1353 		} else {
1354 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
1355 				 "[BTCoex], Wifi Connected-Idle + BT Busy!!\n");
1356 		}
1357 
1358 		common = false;
1359 	}
1360 
1361 	return common;
1362 }
1363 
1364 static void btc8821a1ant_ps_tdma_check_for_pwr_save(struct btc_coexist *btcoex,
1365 						    bool new_ps_state)
1366 {
1367 	u8 lps_mode = 0x0;
1368 
1369 	btcoex->btc_get(btcoex, BTC_GET_U1_LPS_MODE, &lps_mode);
1370 
1371 	if (lps_mode) {
1372 		/* already under LPS state */
1373 		if (new_ps_state) {
1374 			/* keep state under LPS, do nothing */
1375 		} else {
1376 			/* will leave LPS state, turn off psTdma first */
1377 			btc8821a1ant_ps_tdma(btcoex, NORMAL_EXEC, false, 0);
1378 		}
1379 	} else {
1380 		/* NO PS state*/
1381 		if (new_ps_state) {
1382 			/* will enter LPS state, turn off psTdma first */
1383 			btc8821a1ant_ps_tdma(btcoex, NORMAL_EXEC, false, 0);
1384 		} else {
1385 			/* keep state under NO PS state, do nothing */
1386 		}
1387 	}
1388 }
1389 
1390 static void btc8821a1ant_power_save_state(struct btc_coexist *btcoexist,
1391 					  u8 ps_type, u8 lps_val, u8 rpwm_val)
1392 {
1393 	bool low_pwr_disable = false;
1394 
1395 	switch (ps_type) {
1396 	case BTC_PS_WIFI_NATIVE:
1397 		/* recover to original 32k low power setting */
1398 		low_pwr_disable = false;
1399 		btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER,
1400 				   &low_pwr_disable);
1401 		btcoexist->btc_set(btcoexist, BTC_SET_ACT_NORMAL_LPS, NULL);
1402 		break;
1403 	case BTC_PS_LPS_ON:
1404 		btc8821a1ant_ps_tdma_check_for_pwr_save(btcoexist,
1405 							true);
1406 		btc8821a1ant_lps_rpwm(btcoexist, NORMAL_EXEC, lps_val,
1407 				      rpwm_val);
1408 		/* when coex force to enter LPS, do not enter 32k low power */
1409 		low_pwr_disable = true;
1410 		btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER,
1411 				   &low_pwr_disable);
1412 		/* power save must executed before psTdma */
1413 		btcoexist->btc_set(btcoexist, BTC_SET_ACT_ENTER_LPS, NULL);
1414 		break;
1415 	case BTC_PS_LPS_OFF:
1416 		btc8821a1ant_ps_tdma_check_for_pwr_save(btcoexist, false);
1417 		btcoexist->btc_set(btcoexist, BTC_SET_ACT_LEAVE_LPS, NULL);
1418 		break;
1419 	default:
1420 		break;
1421 	}
1422 }
1423 
1424 static void btc8821a1ant_coex_under_5g(struct btc_coexist *btcoexist)
1425 {
1426 	btc8821a1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE,
1427 				      0x0, 0x0);
1428 	btc8821a1ant_ignore_wlan_act(btcoexist, NORMAL_EXEC, true);
1429 
1430 	btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 10);
1431 
1432 	btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
1433 
1434 	btc8821a1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0);
1435 
1436 	btc8821a1ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 5);
1437 }
1438 
1439 /***********************************************
1440  *
1441  *	Software Coex Mechanism start
1442  *
1443  ***********************************************/
1444 
1445 /* SCO only or SCO+PAN(HS) */
1446 static void btc8821a1ant_action_sco(struct btc_coexist *btcoexist)
1447 {
1448 	btc8821a1ant_sw_mechanism(btcoexist, true);
1449 }
1450 
1451 static void btc8821a1ant_action_hid(struct btc_coexist *btcoexist)
1452 {
1453 	btc8821a1ant_sw_mechanism(btcoexist, true);
1454 }
1455 
1456 /* A2DP only / PAN(EDR) only/ A2DP+PAN(HS) */
1457 static void btc8821a1ant_action_a2dp(struct btc_coexist *btcoexist)
1458 {
1459 	btc8821a1ant_sw_mechanism(btcoexist, false);
1460 }
1461 
1462 static void btc8821a1ant_action_a2dp_pan_hs(struct btc_coexist *btcoexist)
1463 {
1464 	btc8821a1ant_sw_mechanism(btcoexist, false);
1465 }
1466 
1467 static void btc8821a1ant_action_pan_edr(struct btc_coexist *btcoexist)
1468 {
1469 	btc8821a1ant_sw_mechanism(btcoexist, false);
1470 }
1471 
1472 /* PAN(HS) only */
1473 static void btc8821a1ant_action_pan_hs(struct btc_coexist *btcoexist)
1474 {
1475 	btc8821a1ant_sw_mechanism(btcoexist, false);
1476 }
1477 
1478 /* PAN(EDR)+A2DP */
1479 static void btc8821a1ant_action_pan_edr_a2dp(struct btc_coexist *btcoexist)
1480 {
1481 	btc8821a1ant_sw_mechanism(btcoexist, false);
1482 }
1483 
1484 static void btc8821a1ant_action_pan_edr_hid(struct btc_coexist *btcoexist)
1485 {
1486 	btc8821a1ant_sw_mechanism(btcoexist, true);
1487 }
1488 
1489 /* HID+A2DP+PAN(EDR) */
1490 static void btc8821a1ant_action_hid_a2dp_pan_edr(struct btc_coexist *btcoexist)
1491 {
1492 	btc8821a1ant_sw_mechanism(btcoexist, true);
1493 }
1494 
1495 static void btc8821a1ant_action_hid_a2dp(struct btc_coexist *btcoexist)
1496 {
1497 	btc8821a1ant_sw_mechanism(btcoexist, true);
1498 }
1499 
1500 /***********************************************
1501  *
1502  *	Non-Software Coex Mechanism start
1503  *
1504  ***********************************************/
1505 static
1506 void btc8821a1ant_action_wifi_multi_port(struct btc_coexist *btcoexist)
1507 {
1508 	struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
1509 
1510 	btc8821a1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0);
1511 	/* tdma and coex table */
1512 	if (coex_dm->bt_status == BT_8821A_1ANT_BT_STATUS_ACL_BUSY) {
1513 		if (bt_link_info->a2dp_exist) {
1514 			btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14);
1515 			btc8821a1ant_coex_table_with_type(btcoexist,
1516 							  NORMAL_EXEC, 1);
1517 		} else if (bt_link_info->a2dp_exist &&
1518 			   bt_link_info->pan_exist) {
1519 			btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
1520 			btc8821a1ant_coex_table_with_type(btcoexist,
1521 							  NORMAL_EXEC, 4);
1522 		} else {
1523 			btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 20);
1524 			btc8821a1ant_coex_table_with_type(btcoexist,
1525 							  NORMAL_EXEC, 4);
1526 		}
1527 	} else if ((coex_dm->bt_status == BT_8821A_1ANT_BT_STATUS_SCO_BUSY) ||
1528 		   (BT_8821A_1ANT_BT_STATUS_ACL_SCO_BUSY ==
1529 		    coex_dm->bt_status)) {
1530 		btc8821a1ant_act_bt_sco_hid_only_busy(btcoexist,
1531 				BT_8821A_1ANT_WIFI_STATUS_CONNECTED_SCAN);
1532 	} else {
1533 		btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
1534 		btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2);
1535 	}
1536 }
1537 
1538 static
1539 void btc8821a1ant_action_wifi_not_connected_asso_auth(
1540 					struct btc_coexist *btcoexist)
1541 {
1542 	struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
1543 
1544 	btc8821a1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 0x0,
1545 				      0x0);
1546 
1547 	/* tdma and coex table */
1548 	if ((bt_link_info->sco_exist) || (bt_link_info->hid_exist)) {
1549 		btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14);
1550 		btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
1551 	} else if ((bt_link_info->a2dp_exist) || (bt_link_info->pan_exist)) {
1552 		btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 20);
1553 		btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4);
1554 	} else {
1555 		btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
1556 		btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2);
1557 	}
1558 }
1559 
1560 
1561 static void btc8821a1ant_action_hs(struct btc_coexist *btcoexist)
1562 {
1563 	btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 5);
1564 	btc8821a1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 2);
1565 }
1566 
1567 static void btc8821a1ant_action_bt_inquiry(struct btc_coexist *btcoexist)
1568 {
1569 	struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
1570 	bool wifi_connected = false;
1571 	bool ap_enable = false;
1572 	bool wifi_busy = false, bt_busy = false;
1573 
1574 	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
1575 			   &wifi_connected);
1576 	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE,
1577 			   &ap_enable);
1578 	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
1579 	btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bt_busy);
1580 
1581 	if (!wifi_connected && !coex_sta->wifi_is_high_pri_task) {
1582 		btc8821a1ant_power_save_state(btcoexist,
1583 					      BTC_PS_WIFI_NATIVE, 0x0, 0x0);
1584 		btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
1585 		btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
1586 	} else if ((bt_link_info->sco_exist) || (bt_link_info->a2dp_exist) ||
1587 		   (bt_link_info->hid_only)) {
1588 		/* SCO/HID-only busy */
1589 		btc8821a1ant_power_save_state(btcoexist,
1590 					      BTC_PS_WIFI_NATIVE, 0x0, 0x0);
1591 		btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 32);
1592 		btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4);
1593 	} else if ((bt_link_info->a2dp_exist) && (bt_link_info->hid_exist)) {
1594 		/* A2DP+HID busy */
1595 		btc8821a1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE,
1596 					      0x0, 0x0);
1597 		btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14);
1598 
1599 		btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
1600 	} else if ((bt_link_info->pan_exist) || (wifi_busy)) {
1601 		btc8821a1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE,
1602 					      0x0, 0x0);
1603 		btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 20);
1604 
1605 		btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4);
1606 	} else {
1607 		btc8821a1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE,
1608 					      0x0, 0x0);
1609 		btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
1610 		btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 7);
1611 	}
1612 }
1613 
1614 static void btc8821a1ant_act_bt_sco_hid_only_busy(struct btc_coexist *btcoexist,
1615 						  u8 wifi_status)
1616 {
1617 	/* tdma and coex table */
1618 	btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 5);
1619 
1620 	if (BT_8821A_1ANT_WIFI_STATUS_NON_CONNECTED_ASSO_AUTH_SCAN ==
1621 	    wifi_status)
1622 		btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
1623 	else
1624 		btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
1625 }
1626 
1627 static void btc8821a1ant_act_wifi_con_bt_acl_busy(struct btc_coexist *btcoexist,
1628 						  u8 wifi_status)
1629 {
1630 	u8 bt_rssi_state;
1631 
1632 	struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
1633 
1634 	bt_rssi_state = btc8821a1ant_bt_rssi_state(btcoexist, 2, 28, 0);
1635 
1636 	if (bt_link_info->hid_only) {
1637 		/* HID */
1638 		btc8821a1ant_act_bt_sco_hid_only_busy(btcoexist,
1639 						      wifi_status);
1640 		coex_dm->auto_tdma_adjust = false;
1641 		return;
1642 	} else if (bt_link_info->a2dp_only) {
1643 		/* A2DP */
1644 		if (wifi_status == BT_8821A_1ANT_WIFI_STATUS_CONNECTED_IDLE) {
1645 			btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 32);
1646 			btc8821a1ant_coex_table_with_type(btcoexist,
1647 							  NORMAL_EXEC, 1);
1648 			coex_dm->auto_tdma_adjust = false;
1649 		} else if ((bt_rssi_state != BTC_RSSI_STATE_HIGH) &&
1650 			   (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
1651 			btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14);
1652 			btc8821a1ant_coex_table_with_type(btcoexist,
1653 							  NORMAL_EXEC, 1);
1654 		} else {
1655 			/* for low BT RSSI */
1656 			btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14);
1657 			btc8821a1ant_coex_table_with_type(btcoexist,
1658 							  NORMAL_EXEC, 1);
1659 			coex_dm->auto_tdma_adjust = false;
1660 		}
1661 	} else if (bt_link_info->hid_exist && bt_link_info->a2dp_exist) {
1662 		/* HID+A2DP */
1663 		if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
1664 		    (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
1665 			btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC,
1666 					     true, 14);
1667 			coex_dm->auto_tdma_adjust = false;
1668 		} else {
1669 			/*for low BT RSSI*/
1670 			btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC,
1671 					     true, 14);
1672 			coex_dm->auto_tdma_adjust = false;
1673 		}
1674 
1675 		btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
1676 	} else if ((bt_link_info->pan_only) ||
1677 		(bt_link_info->hid_exist && bt_link_info->pan_exist)) {
1678 		/* PAN(OPP, FTP), HID+PAN(OPP, FTP) */
1679 		btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3);
1680 		btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 6);
1681 		coex_dm->auto_tdma_adjust = false;
1682 	} else if (((bt_link_info->a2dp_exist) && (bt_link_info->pan_exist)) ||
1683 		   (bt_link_info->hid_exist && bt_link_info->a2dp_exist &&
1684 		    bt_link_info->pan_exist)) {
1685 		/* A2DP+PAN(OPP, FTP), HID+A2DP+PAN(OPP, FTP) */
1686 		btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 43);
1687 		btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
1688 		coex_dm->auto_tdma_adjust = false;
1689 	} else {
1690 		btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 11);
1691 		btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
1692 		coex_dm->auto_tdma_adjust = false;
1693 	}
1694 }
1695 
1696 static
1697 void btc8821a1ant_action_wifi_not_connected(struct btc_coexist *btcoexist)
1698 {
1699 	/* power save state */
1700 	btc8821a1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0);
1701 
1702 	/* tdma and coex table */
1703 	btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
1704 	btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
1705 }
1706 
1707 static void btc8821a1ant_act_wifi_not_conn_scan(struct btc_coexist *btcoexist)
1708 {
1709 	struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
1710 
1711 	btc8821a1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0);
1712 
1713 	/* tdma and coex table */
1714 	if (coex_dm->bt_status == BT_8821A_1ANT_BT_STATUS_ACL_BUSY) {
1715 		if (bt_link_info->a2dp_exist) {
1716 			btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14);
1717 			btc8821a1ant_coex_table_with_type(btcoexist,
1718 							  NORMAL_EXEC, 1);
1719 		} else if (bt_link_info->a2dp_exist &&
1720 			   bt_link_info->pan_exist) {
1721 			btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 22);
1722 			btc8821a1ant_coex_table_with_type(btcoexist,
1723 							  NORMAL_EXEC, 4);
1724 		} else {
1725 			btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 20);
1726 			btc8821a1ant_coex_table_with_type(btcoexist,
1727 							  NORMAL_EXEC, 4);
1728 		}
1729 	} else if ((coex_dm->bt_status == BT_8821A_1ANT_BT_STATUS_SCO_BUSY) ||
1730 		   (BT_8821A_1ANT_BT_STATUS_ACL_SCO_BUSY ==
1731 		    coex_dm->bt_status)) {
1732 		btc8821a1ant_act_bt_sco_hid_only_busy(btcoexist,
1733 				BT_8821A_1ANT_WIFI_STATUS_CONNECTED_SCAN);
1734 	} else {
1735 		btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
1736 		btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2);
1737 	}
1738 }
1739 
1740 static
1741 void btc8821a1ant_action_wifi_connected_scan(struct btc_coexist *btcoexist)
1742 {
1743 	struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
1744 
1745 	/* power save state */
1746 	btc8821a1ant_power_save_state(btcoexist,
1747 				      BTC_PS_WIFI_NATIVE, 0x0, 0x0);
1748 
1749 	/* tdma and coex table */
1750 	if (BT_8821A_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) {
1751 		if (bt_link_info->a2dp_exist) {
1752 			btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14);
1753 			btc8821a1ant_coex_table_with_type(btcoexist,
1754 							  NORMAL_EXEC, 1);
1755 		} else {
1756 			btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 20);
1757 			btc8821a1ant_coex_table_with_type(btcoexist,
1758 							  NORMAL_EXEC, 4);
1759 		}
1760 	} else if ((coex_dm->bt_status == BT_8821A_1ANT_BT_STATUS_SCO_BUSY) ||
1761 		   (coex_dm->bt_status ==
1762 		    BT_8821A_1ANT_BT_STATUS_ACL_SCO_BUSY)) {
1763 		btc8821a1ant_act_bt_sco_hid_only_busy(btcoexist,
1764 			BT_8821A_1ANT_WIFI_STATUS_CONNECTED_SCAN);
1765 	} else {
1766 		btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
1767 		btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2);
1768 	}
1769 }
1770 
1771 static void btc8821a1ant_act_wifi_conn_sp_pkt(struct btc_coexist *btcoexist)
1772 {
1773 	struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
1774 
1775 	btc8821a1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE,
1776 				      0x0, 0x0);
1777 
1778 	/* tdma and coex table */
1779 	if ((bt_link_info->sco_exist) || (bt_link_info->hid_exist) ||
1780 	    (bt_link_info->a2dp_exist)) {
1781 		btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 32);
1782 		btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4);
1783 	}
1784 
1785 	if ((bt_link_info->hid_exist) && (bt_link_info->a2dp_exist)) {
1786 		btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14);
1787 		btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
1788 	} else if (bt_link_info->pan_exist) {
1789 		btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 20);
1790 		btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4);
1791 	} else {
1792 		btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
1793 		btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2);
1794 	}
1795 }
1796 
1797 static void btc8821a1ant_action_wifi_connected(struct btc_coexist *btcoexist)
1798 {
1799 	struct rtl_priv *rtlpriv = btcoexist->adapter;
1800 	bool wifi_busy = false;
1801 	bool scan = false, link = false, roam = false;
1802 	bool under_4way = false;
1803 	bool ap_enable = false;
1804 
1805 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
1806 		 "[BTCoex], CoexForWifiConnect()===>\n");
1807 
1808 	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS,
1809 			   &under_4way);
1810 	if (under_4way) {
1811 		btc8821a1ant_act_wifi_conn_sp_pkt(btcoexist);
1812 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
1813 			 "[BTCoex], CoexForWifiConnect(), return for wifi is under 4way<===\n");
1814 		return;
1815 	}
1816 
1817 	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan);
1818 	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link);
1819 	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam);
1820 	if (scan || link || roam) {
1821 		if (scan)
1822 			btc8821a1ant_action_wifi_connected_scan(btcoexist);
1823 		else
1824 			btc8821a1ant_act_wifi_conn_sp_pkt(btcoexist);
1825 
1826 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
1827 			 "[BTCoex], CoexForWifiConnect(), return for wifi is under scan<===\n");
1828 		return;
1829 	}
1830 
1831 	/* power save state*/
1832 	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE,
1833 			   &ap_enable);
1834 	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
1835 	if (BT_8821A_1ANT_BT_STATUS_ACL_BUSY ==
1836 	    coex_dm->bt_status && !ap_enable &&
1837 	    !btcoexist->bt_link_info.hid_only) {
1838 		if (!wifi_busy && btcoexist->bt_link_info.a2dp_only)
1839 			/* A2DP */
1840 			btc8821a1ant_power_save_state(btcoexist,
1841 						BTC_PS_WIFI_NATIVE, 0x0, 0x0);
1842 		else
1843 			btc8821a1ant_power_save_state(btcoexist, BTC_PS_LPS_ON,
1844 						      0x50, 0x4);
1845 	} else {
1846 		btc8821a1ant_power_save_state(btcoexist,
1847 					      BTC_PS_WIFI_NATIVE,
1848 					      0x0, 0x0);
1849 	}
1850 
1851 	/* tdma and coex table */
1852 	if (!wifi_busy) {
1853 		if (BT_8821A_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) {
1854 			btc8821a1ant_act_wifi_con_bt_acl_busy(btcoexist,
1855 				BT_8821A_1ANT_WIFI_STATUS_CONNECTED_IDLE);
1856 		} else if ((BT_8821A_1ANT_BT_STATUS_SCO_BUSY ==
1857 			    coex_dm->bt_status) ||
1858 			   (BT_8821A_1ANT_BT_STATUS_ACL_SCO_BUSY ==
1859 			    coex_dm->bt_status)) {
1860 			btc8821a1ant_act_bt_sco_hid_only_busy(btcoexist,
1861 				BT_8821A_1ANT_WIFI_STATUS_CONNECTED_IDLE);
1862 		} else {
1863 			btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
1864 			btc8821a1ant_coex_table_with_type(btcoexist,
1865 							  NORMAL_EXEC, 2);
1866 		}
1867 	} else {
1868 		if (BT_8821A_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) {
1869 			btc8821a1ant_act_wifi_con_bt_acl_busy(btcoexist,
1870 				BT_8821A_1ANT_WIFI_STATUS_CONNECTED_BUSY);
1871 		} else if ((BT_8821A_1ANT_BT_STATUS_SCO_BUSY ==
1872 			    coex_dm->bt_status) ||
1873 			   (BT_8821A_1ANT_BT_STATUS_ACL_SCO_BUSY ==
1874 			    coex_dm->bt_status)) {
1875 			btc8821a1ant_act_bt_sco_hid_only_busy(btcoexist,
1876 				BT_8821A_1ANT_WIFI_STATUS_CONNECTED_BUSY);
1877 		} else {
1878 			btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
1879 			btc8821a1ant_coex_table_with_type(btcoexist,
1880 							  NORMAL_EXEC, 2);
1881 		}
1882 	}
1883 }
1884 
1885 static void btc8821a1ant_run_sw_coex_mech(struct btc_coexist *btcoexist)
1886 {
1887 	struct rtl_priv *rtlpriv = btcoexist->adapter;
1888 	u8 algorithm = 0;
1889 
1890 	algorithm = btc8821a1ant_action_algorithm(btcoexist);
1891 	coex_dm->cur_algorithm = algorithm;
1892 
1893 	if (!btc8821a1ant_is_common_action(btcoexist)) {
1894 		switch (coex_dm->cur_algorithm) {
1895 		case BT_8821A_1ANT_COEX_ALGO_SCO:
1896 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
1897 				 "[BTCoex], Action algorithm = SCO\n");
1898 			btc8821a1ant_action_sco(btcoexist);
1899 			break;
1900 		case BT_8821A_1ANT_COEX_ALGO_HID:
1901 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
1902 				 "[BTCoex], Action algorithm = HID\n");
1903 			btc8821a1ant_action_hid(btcoexist);
1904 			break;
1905 		case BT_8821A_1ANT_COEX_ALGO_A2DP:
1906 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
1907 				 "[BTCoex], Action algorithm = A2DP\n");
1908 			btc8821a1ant_action_a2dp(btcoexist);
1909 			break;
1910 		case BT_8821A_1ANT_COEX_ALGO_A2DP_PANHS:
1911 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
1912 				 "[BTCoex], Action algorithm = A2DP+PAN(HS)\n");
1913 			btc8821a1ant_action_a2dp_pan_hs(btcoexist);
1914 			break;
1915 		case BT_8821A_1ANT_COEX_ALGO_PANEDR:
1916 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
1917 				 "[BTCoex], Action algorithm = PAN(EDR)\n");
1918 			btc8821a1ant_action_pan_edr(btcoexist);
1919 			break;
1920 		case BT_8821A_1ANT_COEX_ALGO_PANHS:
1921 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
1922 				 "[BTCoex], Action algorithm = HS mode\n");
1923 			btc8821a1ant_action_pan_hs(btcoexist);
1924 			break;
1925 		case BT_8821A_1ANT_COEX_ALGO_PANEDR_A2DP:
1926 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
1927 				 "[BTCoex], Action algorithm = PAN+A2DP\n");
1928 			btc8821a1ant_action_pan_edr_a2dp(btcoexist);
1929 			break;
1930 		case BT_8821A_1ANT_COEX_ALGO_PANEDR_HID:
1931 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
1932 				 "[BTCoex], Action algorithm = PAN(EDR)+HID\n");
1933 			btc8821a1ant_action_pan_edr_hid(btcoexist);
1934 			break;
1935 		case BT_8821A_1ANT_COEX_ALGO_HID_A2DP_PANEDR:
1936 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
1937 				 "[BTCoex], Action algorithm = HID+A2DP+PAN\n");
1938 			btc8821a1ant_action_hid_a2dp_pan_edr(btcoexist);
1939 			break;
1940 		case BT_8821A_1ANT_COEX_ALGO_HID_A2DP:
1941 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
1942 				 "[BTCoex], Action algorithm = HID+A2DP\n");
1943 			btc8821a1ant_action_hid_a2dp(btcoexist);
1944 			break;
1945 		default:
1946 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
1947 				 "[BTCoex], Action algorithm = coexist All Off!!\n");
1948 			/*btc8821a1ant_coex_all_off(btcoexist);*/
1949 			break;
1950 		}
1951 		coex_dm->pre_algorithm = coex_dm->cur_algorithm;
1952 	}
1953 }
1954 
1955 static void btc8821a1ant_run_coexist_mechanism(struct btc_coexist *btcoexist)
1956 {
1957 	struct rtl_priv *rtlpriv = btcoexist->adapter;
1958 	struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
1959 	bool wifi_connected = false, bt_hs_on = false;
1960 	bool increase_scan_dev_num = false;
1961 	bool bt_ctrl_agg_buf_size = false;
1962 	u8 agg_buf_size = 5;
1963 	u8 wifi_rssi_state = BTC_RSSI_STATE_HIGH;
1964 	u32 wifi_link_status = 0;
1965 	u32 num_of_wifi_link = 0;
1966 	bool wifi_under_5g = false;
1967 
1968 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
1969 		 "[BTCoex], RunCoexistMechanism()===>\n");
1970 
1971 	if (btcoexist->manual_control) {
1972 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
1973 			 "[BTCoex], RunCoexistMechanism(), return for Manual CTRL <===\n");
1974 		return;
1975 	}
1976 
1977 	if (btcoexist->stop_coex_dm) {
1978 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
1979 			 "[BTCoex], RunCoexistMechanism(), return for Stop Coex DM <===\n");
1980 		return;
1981 	}
1982 
1983 	if (coex_sta->under_ips) {
1984 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
1985 			 "[BTCoex], wifi is under IPS !!!\n");
1986 		return;
1987 	}
1988 
1989 	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
1990 	if (wifi_under_5g) {
1991 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
1992 			 "[BTCoex], RunCoexistMechanism(), return for 5G <===\n");
1993 		btc8821a1ant_coex_under_5g(btcoexist);
1994 		return;
1995 	}
1996 
1997 	if ((BT_8821A_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) ||
1998 	    (BT_8821A_1ANT_BT_STATUS_SCO_BUSY == coex_dm->bt_status) ||
1999 	    (BT_8821A_1ANT_BT_STATUS_ACL_SCO_BUSY == coex_dm->bt_status))
2000 		increase_scan_dev_num = true;
2001 
2002 	btcoexist->btc_set(btcoexist, BTC_SET_BL_INC_SCAN_DEV_NUM,
2003 			   &increase_scan_dev_num);
2004 
2005 	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
2006 			   &wifi_connected);
2007 
2008 	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS,
2009 			   &wifi_link_status);
2010 	num_of_wifi_link = wifi_link_status >> 16;
2011 	if ((num_of_wifi_link >= 2) ||
2012 	    (wifi_link_status & WIFI_P2P_GO_CONNECTED)) {
2013 		btc8821a1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0);
2014 		btc8821a1ant_limited_rx(btcoexist, NORMAL_EXEC, false,
2015 					bt_ctrl_agg_buf_size, agg_buf_size);
2016 		btc8821a1ant_action_wifi_multi_port(btcoexist);
2017 		return;
2018 	}
2019 
2020 	if (!bt_link_info->sco_exist && !bt_link_info->hid_exist) {
2021 		btc8821a1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0);
2022 	} else {
2023 		if (wifi_connected) {
2024 			wifi_rssi_state =
2025 				btc8821a1ant_wifi_rssi_state(btcoexist, 1, 2,
2026 							     30, 0);
2027 			if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
2028 			    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2029 				btc8821a1ant_limited_tx(btcoexist,
2030 							NORMAL_EXEC, 1, 1,
2031 							0, 1);
2032 			} else {
2033 				btc8821a1ant_limited_tx(btcoexist,
2034 							NORMAL_EXEC, 1, 1,
2035 							0, 1);
2036 			}
2037 		} else {
2038 			btc8821a1ant_limited_tx(btcoexist, NORMAL_EXEC,
2039 						0, 0, 0, 0);
2040 		}
2041 	}
2042 
2043 	if (bt_link_info->sco_exist) {
2044 		bt_ctrl_agg_buf_size = true;
2045 		agg_buf_size = 0x3;
2046 	} else if (bt_link_info->hid_exist) {
2047 		bt_ctrl_agg_buf_size = true;
2048 		agg_buf_size = 0x5;
2049 	} else if (bt_link_info->a2dp_exist || bt_link_info->pan_exist) {
2050 		bt_ctrl_agg_buf_size = true;
2051 		agg_buf_size = 0x8;
2052 	}
2053 	btc8821a1ant_limited_rx(btcoexist, NORMAL_EXEC, false,
2054 				bt_ctrl_agg_buf_size, agg_buf_size);
2055 
2056 	btc8821a1ant_run_sw_coex_mech(btcoexist);
2057 
2058 	btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
2059 	if (coex_sta->c2h_bt_inquiry_page) {
2060 		btc8821a1ant_action_bt_inquiry(btcoexist);
2061 		return;
2062 	} else if (bt_hs_on) {
2063 		btc8821a1ant_action_hs(btcoexist);
2064 		return;
2065 	}
2066 
2067 	if (!wifi_connected) {
2068 		bool scan = false, link = false, roam = false;
2069 
2070 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
2071 			 "[BTCoex], wifi is non connected-idle !!!\n");
2072 
2073 		btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan);
2074 		btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link);
2075 		btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam);
2076 
2077 		if (scan || link || roam) {
2078 			if (scan)
2079 				btc8821a1ant_act_wifi_not_conn_scan(btcoexist);
2080 			else
2081 				btc8821a1ant_action_wifi_not_connected_asso_auth(
2082 					btcoexist);
2083 		} else {
2084 			btc8821a1ant_action_wifi_not_connected(btcoexist);
2085 		}
2086 	} else {
2087 		/* wifi LPS/Busy */
2088 		btc8821a1ant_action_wifi_connected(btcoexist);
2089 	}
2090 }
2091 
2092 static void btc8821a1ant_init_coex_dm(struct btc_coexist *btcoexist)
2093 {
2094 	/* force to reset coex mechanism
2095 	 * sw all off
2096 	 */
2097 	btc8821a1ant_sw_mechanism(btcoexist, false);
2098 
2099 	btc8821a1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 0);
2100 }
2101 
2102 static void btc8821a1ant_init_hw_config(struct btc_coexist *btcoexist,
2103 					bool back_up, bool wifi_only)
2104 {
2105 	struct rtl_priv *rtlpriv = btcoexist->adapter;
2106 	u8 u1_tmp = 0;
2107 	bool wifi_under_5g = false;
2108 
2109 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
2110 		 "[BTCoex], 1Ant Init HW Config!!\n");
2111 
2112 	if (wifi_only)
2113 		return;
2114 
2115 	if (back_up) {
2116 		coex_dm->backup_arfr_cnt1 = btcoexist->btc_read_4byte(btcoexist,
2117 								      0x430);
2118 		coex_dm->backup_arfr_cnt2 = btcoexist->btc_read_4byte(btcoexist,
2119 								      0x434);
2120 		coex_dm->backup_retry_limit =
2121 			btcoexist->btc_read_2byte(btcoexist, 0x42a);
2122 		coex_dm->backup_ampdu_max_time =
2123 			btcoexist->btc_read_1byte(btcoexist, 0x456);
2124 	}
2125 
2126 	/* 0x790[5:0] = 0x5 */
2127 	u1_tmp = btcoexist->btc_read_1byte(btcoexist, 0x790);
2128 	u1_tmp &= 0xc0;
2129 	u1_tmp |= 0x5;
2130 	btcoexist->btc_write_1byte(btcoexist, 0x790, u1_tmp);
2131 
2132 	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
2133 
2134 	/* Antenna config */
2135 	if (wifi_under_5g)
2136 		btc8821a1ant_set_ant_path(btcoexist, BTC_ANT_PATH_BT,
2137 					  true, false);
2138 	else
2139 		btc8821a1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA,
2140 					  true, false);
2141 	/* PTA parameter */
2142 	btc8821a1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 0);
2143 
2144 	/* Enable counter statistics
2145 	 * 0x76e[3] =1, WLAN_Act control by PTA
2146 	 */
2147 	btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc);
2148 	btcoexist->btc_write_1byte(btcoexist, 0x778, 0x3);
2149 	btcoexist->btc_write_1byte_bitmask(btcoexist, 0x40, 0x20, 0x1);
2150 }
2151 
2152 /**************************************************************
2153  * extern function start with ex_btc8821a1ant_
2154  **************************************************************/
2155 void ex_btc8821a1ant_init_hwconfig(struct btc_coexist *btcoexist, bool wifionly)
2156 {
2157 	btc8821a1ant_init_hw_config(btcoexist, true, wifionly);
2158 	btcoexist->auto_report_1ant = true;
2159 }
2160 
2161 void ex_btc8821a1ant_init_coex_dm(struct btc_coexist *btcoexist)
2162 {
2163 	struct rtl_priv *rtlpriv = btcoexist->adapter;
2164 
2165 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
2166 		 "[BTCoex], Coex Mechanism Init!!\n");
2167 
2168 	btcoexist->stop_coex_dm = false;
2169 
2170 	btc8821a1ant_init_coex_dm(btcoexist);
2171 
2172 	btc8821a1ant_query_bt_info(btcoexist);
2173 }
2174 
2175 void ex_btc8821a1ant_display_coex_info(struct btc_coexist *btcoexist)
2176 {
2177 	struct btc_board_info *board_info = &btcoexist->board_info;
2178 	struct btc_stack_info *stack_info = &btcoexist->stack_info;
2179 	struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
2180 	struct rtl_priv *rtlpriv = btcoexist->adapter;
2181 	u8 u1_tmp[4], i, bt_info_ext, ps_tdma_case = 0;
2182 	u16 u2_tmp[4];
2183 	u32 u4_tmp[4];
2184 	bool roam = false, scan = false, link = false, wifi_under_5g = false;
2185 	bool bt_hs_on = false, wifi_busy = false;
2186 	long wifi_rssi = 0, bt_hs_rssi = 0;
2187 	u32 wifi_bw, wifi_traffic_dir;
2188 	u8 wifi_dot11_chnl, wifi_hs_chnl;
2189 	u32 fw_ver = 0, bt_patch_ver = 0;
2190 
2191 	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2192 		 "\r\n ============[BT Coexist info]============");
2193 
2194 	if (btcoexist->manual_control) {
2195 		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2196 			 "\r\n ============[Under Manual Control]============");
2197 		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2198 			 "\r\n ==========================================");
2199 	}
2200 	if (btcoexist->stop_coex_dm) {
2201 		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2202 			 "\r\n ============[Coex is STOPPED]============");
2203 		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2204 			 "\r\n ==========================================");
2205 	}
2206 
2207 	if (!board_info->bt_exist) {
2208 		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n BT not exists !!!");
2209 		return;
2210 	}
2211 
2212 	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2213 		 "\r\n %-35s = %d/ %d/ %d",
2214 		 "Ant PG Num/ Ant Mech/ Ant Pos:",
2215 		 board_info->pg_ant_num,
2216 		 board_info->btdm_ant_num,
2217 		 board_info->btdm_ant_pos);
2218 
2219 	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2220 		 "\r\n %-35s = %s / %d", "BT stack/ hci ext ver",
2221 		 ((stack_info->profile_notified) ? "Yes" : "No"),
2222 		 stack_info->hci_version);
2223 
2224 	btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER,
2225 			   &bt_patch_ver);
2226 	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver);
2227 	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2228 		 "\r\n %-35s = %d_%x/ 0x%x/ 0x%x(%d)",
2229 		 "CoexVer/ FwVer/ PatchVer",
2230 		 glcoex_ver_date_8821a_1ant,
2231 		 glcoex_ver_8821a_1ant,
2232 		 fw_ver, bt_patch_ver,
2233 		 bt_patch_ver);
2234 
2235 	btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION,
2236 			   &bt_hs_on);
2237 	btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_DOT11_CHNL,
2238 			   &wifi_dot11_chnl);
2239 	btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_HS_CHNL,
2240 			   &wifi_hs_chnl);
2241 	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2242 		 "\r\n %-35s = %d / %d(%d)",
2243 		 "Dot11 channel / HsChnl(HsMode)",
2244 		 wifi_dot11_chnl, wifi_hs_chnl, bt_hs_on);
2245 
2246 	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2247 		 "\r\n %-35s = %3ph ",
2248 		 "H2C Wifi inform bt chnl Info",
2249 		 coex_dm->wifi_chnl_info);
2250 
2251 	btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi);
2252 	btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi);
2253 	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2254 		 "\r\n %-35s = %d/ %d", "Wifi rssi/ HS rssi",
2255 		 (int)wifi_rssi, (int)bt_hs_rssi);
2256 
2257 	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan);
2258 	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link);
2259 	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam);
2260 	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2261 		 "\r\n %-35s = %d/ %d/ %d ", "Wifi link/ roam/ scan",
2262 		 link, roam, scan);
2263 
2264 	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G,
2265 			   &wifi_under_5g);
2266 	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW,
2267 			   &wifi_bw);
2268 	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY,
2269 			   &wifi_busy);
2270 	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION,
2271 			   &wifi_traffic_dir);
2272 	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2273 		 "\r\n %-35s = %s / %s/ %s ", "Wifi status",
2274 		 (wifi_under_5g ? "5G" : "2.4G"),
2275 		 ((wifi_bw == BTC_WIFI_BW_LEGACY) ? "Legacy" :
2276 		 (((wifi_bw == BTC_WIFI_BW_HT40) ? "HT40" : "HT20"))),
2277 		 ((!wifi_busy) ? "idle" :
2278 		 ((wifi_traffic_dir == BTC_WIFI_TRAFFIC_TX) ?
2279 		 "uplink" : "downlink")));
2280 	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2281 		   "\r\n %-35s = [%s/ %d/ %d] ", "BT [status/ rssi/ retryCnt]",
2282 		   ((coex_sta->bt_disabled) ? ("disabled") :
2283 		   ((coex_sta->c2h_bt_inquiry_page) ? ("inquiry/page scan") :
2284 		   ((BT_8821A_1ANT_BT_STATUS_NON_CONNECTED_IDLE ==
2285 		     coex_dm->bt_status) ?
2286 		   "non-connected idle" :
2287 		   ((BT_8821A_1ANT_BT_STATUS_CONNECTED_IDLE ==
2288 		     coex_dm->bt_status) ?
2289 		   "connected-idle" : "busy")))),
2290 		   coex_sta->bt_rssi, coex_sta->bt_retry_cnt);
2291 
2292 	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2293 		 "\r\n %-35s = %d / %d / %d / %d", "SCO/HID/PAN/A2DP",
2294 		 bt_link_info->sco_exist,
2295 		 bt_link_info->hid_exist,
2296 		 bt_link_info->pan_exist,
2297 		 bt_link_info->a2dp_exist);
2298 	btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_BT_LINK_INFO);
2299 
2300 	bt_info_ext = coex_sta->bt_info_ext;
2301 	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2302 		 "\r\n %-35s = %s",
2303 		 "BT Info A2DP rate",
2304 		 (bt_info_ext & BIT0) ?
2305 		 "Basic rate" : "EDR rate");
2306 
2307 	for (i = 0; i < BT_INFO_SRC_8821A_1ANT_MAX; i++) {
2308 		if (coex_sta->bt_info_c2h_cnt[i]) {
2309 			RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2310 				 "\r\n %-35s = %7ph(%d)",
2311 				 glbt_info_src_8821a_1ant[i],
2312 				 coex_sta->bt_info_c2h[i],
2313 				 coex_sta->bt_info_c2h_cnt[i]);
2314 		}
2315 	}
2316 	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2317 		 "\r\n %-35s = %s/%s, (0x%x/0x%x)",
2318 		 "PS state, IPS/LPS, (lps/rpwm)",
2319 		 ((coex_sta->under_ips ? "IPS ON" : "IPS OFF")),
2320 		 ((coex_sta->under_lps ? "LPS ON" : "LPS OFF")),
2321 		 btcoexist->bt_info.lps_val,
2322 		 btcoexist->bt_info.rpwm_val);
2323 	btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_FW_PWR_MODE_CMD);
2324 
2325 	if (!btcoexist->manual_control) {
2326 		/* Sw mechanism*/
2327 		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2328 			 "\r\n %-35s",
2329 			 "============[Sw mechanism]============");
2330 
2331 		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2332 			 "\r\n %-35s = %d", "SM[LowPenaltyRA]",
2333 			 coex_dm->cur_low_penalty_ra);
2334 
2335 		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2336 			 "\r\n %-35s = %s/ %s/ %d ",
2337 			 "DelBA/ BtCtrlAgg/ AggSize",
2338 			 (btcoexist->bt_info.reject_agg_pkt ? "Yes" : "No"),
2339 			 (btcoexist->bt_info.bt_ctrl_buf_size ? "Yes" : "No"),
2340 			 btcoexist->bt_info.agg_buf_size);
2341 		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2342 			 "\r\n %-35s = 0x%x ", "Rate Mask",
2343 			 btcoexist->bt_info.ra_mask);
2344 
2345 		/* Fw mechanism */
2346 		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s",
2347 			 "============[Fw mechanism]============");
2348 
2349 		ps_tdma_case = coex_dm->cur_ps_tdma;
2350 		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2351 			 "\r\n %-35s = %5ph case-%d (auto:%d)",
2352 			 "PS TDMA",
2353 			 coex_dm->ps_tdma_para,
2354 			 ps_tdma_case,
2355 			 coex_dm->auto_tdma_adjust);
2356 
2357 		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2358 			 "\r\n %-35s = 0x%x ",
2359 			 "Latest error condition(should be 0)",
2360 			   coex_dm->error_condition);
2361 
2362 		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2363 			 "\r\n %-35s = %d ", "IgnWlanAct",
2364 			 coex_dm->cur_ignore_wlan_act);
2365 	}
2366 
2367 	/* Hw setting */
2368 	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2369 		 "\r\n %-35s", "============[Hw setting]============");
2370 
2371 	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2372 		 "\r\n %-35s = 0x%x/0x%x/0x%x/0x%x",
2373 		 "backup ARFR1/ARFR2/RL/AMaxTime",
2374 		 coex_dm->backup_arfr_cnt1,
2375 		 coex_dm->backup_arfr_cnt2,
2376 		 coex_dm->backup_retry_limit,
2377 		 coex_dm->backup_ampdu_max_time);
2378 
2379 	u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x430);
2380 	u4_tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x434);
2381 	u2_tmp[0] = btcoexist->btc_read_2byte(btcoexist, 0x42a);
2382 	u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x456);
2383 	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2384 		 "\r\n %-35s = 0x%x/0x%x/0x%x/0x%x",
2385 		 "0x430/0x434/0x42a/0x456",
2386 		 u4_tmp[0], u4_tmp[1], u2_tmp[0], u1_tmp[0]);
2387 
2388 	u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x778);
2389 	u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xc58);
2390 	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2391 		 "\r\n %-35s = 0x%x/ 0x%x", "0x778/ 0xc58[29:25]",
2392 		 u1_tmp[0], (u4_tmp[0] & 0x3e000000) >> 25);
2393 
2394 	u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x8db);
2395 	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2396 		 "\r\n %-35s = 0x%x", "0x8db[6:5]",
2397 		 ((u1_tmp[0] & 0x60) >> 5));
2398 
2399 	u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x975);
2400 	u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xcb4);
2401 	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2402 		 "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
2403 		 "0xcb4[29:28]/0xcb4[7:0]/0x974[9:8]",
2404 		 (u4_tmp[0] & 0x30000000) >> 28,
2405 		  u4_tmp[0] & 0xff,
2406 		  u1_tmp[0] & 0x3);
2407 
2408 	u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x40);
2409 	u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x4c);
2410 	u1_tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x64);
2411 	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2412 		 "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
2413 		 "0x40/0x4c[24:23]/0x64[0]",
2414 		 u1_tmp[0], ((u4_tmp[0] & 0x01800000) >> 23), u1_tmp[1] & 0x1);
2415 
2416 	u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x550);
2417 	u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x522);
2418 	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2419 		 "\r\n %-35s = 0x%x/ 0x%x", "0x550(bcn ctrl)/0x522",
2420 		 u4_tmp[0], u1_tmp[0]);
2421 
2422 	u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xc50);
2423 	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2424 		 "\r\n %-35s = 0x%x", "0xc50(dig)",
2425 		 u4_tmp[0] & 0xff);
2426 
2427 	u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xf48);
2428 	u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0xa5d);
2429 	u1_tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0xa5c);
2430 	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2431 		 "\r\n %-35s = 0x%x/ 0x%x", "OFDM-FA/ CCK-FA",
2432 		 u4_tmp[0], (u1_tmp[0] << 8) + u1_tmp[1]);
2433 
2434 	u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x6c0);
2435 	u4_tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x6c4);
2436 	u4_tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x6c8);
2437 	u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x6cc);
2438 	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2439 		 "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x",
2440 		 "0x6c0/0x6c4/0x6c8/0x6cc(coexTable)",
2441 		   u4_tmp[0], u4_tmp[1], u4_tmp[2], u1_tmp[0]);
2442 
2443 	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2444 		 "\r\n %-35s = %d/ %d", "0x770(high-pri rx/tx)",
2445 		 coex_sta->high_priority_rx, coex_sta->high_priority_tx);
2446 	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2447 		 "\r\n %-35s = %d/ %d", "0x774(low-pri rx/tx)",
2448 		 coex_sta->low_priority_rx, coex_sta->low_priority_tx);
2449 	if (btcoexist->auto_report_1ant)
2450 		btc8821a1ant_monitor_bt_ctr(btcoexist);
2451 	btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_COEX_STATISTICS);
2452 }
2453 
2454 void ex_btc8821a1ant_ips_notify(struct btc_coexist *btcoexist, u8 type)
2455 {
2456 	struct rtl_priv *rtlpriv = btcoexist->adapter;
2457 	bool wifi_under_5g = false;
2458 
2459 	if (btcoexist->manual_control || btcoexist->stop_coex_dm)
2460 		return;
2461 	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
2462 	if (wifi_under_5g) {
2463 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
2464 			 "[BTCoex], RunCoexistMechanism(), return for 5G <===\n");
2465 		btc8821a1ant_coex_under_5g(btcoexist);
2466 		return;
2467 	}
2468 
2469 	if (BTC_IPS_ENTER == type) {
2470 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
2471 			 "[BTCoex], IPS ENTER notify\n");
2472 		coex_sta->under_ips = true;
2473 		btc8821a1ant_set_ant_path(btcoexist,
2474 					  BTC_ANT_PATH_BT, false, true);
2475 		/* set PTA control */
2476 		btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0);
2477 		btc8821a1ant_coex_table_with_type(btcoexist,
2478 						  NORMAL_EXEC, 0);
2479 	} else if (BTC_IPS_LEAVE == type) {
2480 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
2481 			 "[BTCoex], IPS LEAVE notify\n");
2482 		coex_sta->under_ips = false;
2483 
2484 		btc8821a1ant_init_hw_config(btcoexist, false, false);
2485 		btc8821a1ant_init_coex_dm(btcoexist);
2486 		btc8821a1ant_query_bt_info(btcoexist);
2487 	}
2488 }
2489 
2490 void ex_btc8821a1ant_lps_notify(struct btc_coexist *btcoexist, u8 type)
2491 {
2492 	struct rtl_priv *rtlpriv = btcoexist->adapter;
2493 
2494 	if (btcoexist->manual_control || btcoexist->stop_coex_dm)
2495 		return;
2496 
2497 	if (BTC_LPS_ENABLE == type) {
2498 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
2499 			 "[BTCoex], LPS ENABLE notify\n");
2500 		coex_sta->under_lps = true;
2501 	} else if (BTC_LPS_DISABLE == type) {
2502 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
2503 			 "[BTCoex], LPS DISABLE notify\n");
2504 		coex_sta->under_lps = false;
2505 	}
2506 }
2507 
2508 void ex_btc8821a1ant_scan_notify(struct btc_coexist *btcoexist, u8 type)
2509 {
2510 	struct rtl_priv *rtlpriv = btcoexist->adapter;
2511 	bool wifi_connected = false, bt_hs_on = false;
2512 	bool bt_ctrl_agg_buf_size = false;
2513 	bool wifi_under_5g = false;
2514 	u32 wifi_link_status = 0;
2515 	u32 num_of_wifi_link = 0;
2516 	u8 agg_buf_size = 5;
2517 
2518 	if (btcoexist->manual_control || btcoexist->stop_coex_dm)
2519 		return;
2520 	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
2521 	if (wifi_under_5g) {
2522 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
2523 			 "[BTCoex], RunCoexistMechanism(), return for 5G <===\n");
2524 		btc8821a1ant_coex_under_5g(btcoexist);
2525 		return;
2526 	}
2527 
2528 	if (type == BTC_SCAN_START) {
2529 		coex_sta->wifi_is_high_pri_task = true;
2530 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
2531 			 "[BTCoex], SCAN START notify\n");
2532 
2533 		/* Force antenna setup for no scan result issue */
2534 		btc8821a1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 8);
2535 	} else {
2536 		coex_sta->wifi_is_high_pri_task = false;
2537 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
2538 			 "[BTCoex], SCAN FINISH notify\n");
2539 	}
2540 
2541 	if (coex_sta->bt_disabled)
2542 		return;
2543 
2544 	btcoexist->btc_get(btcoexist,
2545 		 BTC_GET_BL_HS_OPERATION, &bt_hs_on);
2546 	btcoexist->btc_get(btcoexist,
2547 		 BTC_GET_BL_WIFI_CONNECTED, &wifi_connected);
2548 
2549 	btc8821a1ant_query_bt_info(btcoexist);
2550 
2551 	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS,
2552 			   &wifi_link_status);
2553 	num_of_wifi_link = wifi_link_status >> 16;
2554 	if (num_of_wifi_link >= 2) {
2555 		btc8821a1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0);
2556 		btc8821a1ant_limited_rx(btcoexist, NORMAL_EXEC, false,
2557 					bt_ctrl_agg_buf_size, agg_buf_size);
2558 		btc8821a1ant_action_wifi_multi_port(btcoexist);
2559 		return;
2560 	}
2561 
2562 	if (coex_sta->c2h_bt_inquiry_page) {
2563 		btc8821a1ant_action_bt_inquiry(btcoexist);
2564 		return;
2565 	} else if (bt_hs_on) {
2566 		btc8821a1ant_action_hs(btcoexist);
2567 		return;
2568 	}
2569 
2570 	if (BTC_SCAN_START == type) {
2571 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
2572 			 "[BTCoex], SCAN START notify\n");
2573 		if (!wifi_connected) {
2574 			/* non-connected scan */
2575 			btc8821a1ant_act_wifi_not_conn_scan(btcoexist);
2576 		} else {
2577 			/* wifi is connected */
2578 			btc8821a1ant_action_wifi_connected_scan(btcoexist);
2579 		}
2580 	} else if (BTC_SCAN_FINISH == type) {
2581 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
2582 			 "[BTCoex], SCAN FINISH notify\n");
2583 		if (!wifi_connected) {
2584 			/* non-connected scan */
2585 			btc8821a1ant_action_wifi_not_connected(btcoexist);
2586 		} else {
2587 			btc8821a1ant_action_wifi_connected(btcoexist);
2588 		}
2589 	}
2590 }
2591 
2592 void ex_btc8821a1ant_connect_notify(struct btc_coexist *btcoexist, u8 type)
2593 {
2594 	struct rtl_priv *rtlpriv = btcoexist->adapter;
2595 	bool wifi_connected = false, bt_hs_on = false;
2596 	u32 wifi_link_status = 0;
2597 	u32 num_of_wifi_link = 0;
2598 	bool bt_ctrl_agg_buf_size = false;
2599 	bool wifi_under_5g = false;
2600 	u8 agg_buf_size = 5;
2601 
2602 	if (btcoexist->manual_control || btcoexist->stop_coex_dm ||
2603 	    coex_sta->bt_disabled)
2604 		return;
2605 	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
2606 	if (wifi_under_5g) {
2607 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
2608 			 "[BTCoex], RunCoexistMechanism(), return for 5G <===\n");
2609 		btc8821a1ant_coex_under_5g(btcoexist);
2610 		return;
2611 	}
2612 
2613 	if (type == BTC_ASSOCIATE_START) {
2614 		coex_sta->wifi_is_high_pri_task = true;
2615 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
2616 			 "[BTCoex], CONNECT START notify\n");
2617 		coex_dm->arp_cnt = 0;
2618 	} else {
2619 		coex_sta->wifi_is_high_pri_task = false;
2620 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
2621 			 "[BTCoex], CONNECT FINISH notify\n");
2622 		coex_dm->arp_cnt = 0;
2623 	}
2624 
2625 	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS,
2626 			   &wifi_link_status);
2627 	num_of_wifi_link = wifi_link_status >> 16;
2628 	if (num_of_wifi_link >= 2) {
2629 		btc8821a1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0);
2630 		btc8821a1ant_limited_rx(btcoexist, NORMAL_EXEC, false,
2631 					bt_ctrl_agg_buf_size, agg_buf_size);
2632 		btc8821a1ant_action_wifi_multi_port(btcoexist);
2633 		return;
2634 	}
2635 
2636 	btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
2637 	if (coex_sta->c2h_bt_inquiry_page) {
2638 		btc8821a1ant_action_bt_inquiry(btcoexist);
2639 		return;
2640 	} else if (bt_hs_on) {
2641 		btc8821a1ant_action_hs(btcoexist);
2642 		return;
2643 	}
2644 
2645 	if (BTC_ASSOCIATE_START == type) {
2646 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
2647 			 "[BTCoex], CONNECT START notify\n");
2648 		btc8821a1ant_act_wifi_not_conn_scan(btcoexist);
2649 	} else if (BTC_ASSOCIATE_FINISH == type) {
2650 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
2651 			 "[BTCoex], CONNECT FINISH notify\n");
2652 
2653 		btcoexist->btc_get(btcoexist,
2654 			 BTC_GET_BL_WIFI_CONNECTED, &wifi_connected);
2655 		if (!wifi_connected) {
2656 			/* non-connected scan */
2657 			btc8821a1ant_action_wifi_not_connected(btcoexist);
2658 		} else {
2659 			btc8821a1ant_action_wifi_connected(btcoexist);
2660 		}
2661 	}
2662 }
2663 
2664 void ex_btc8821a1ant_media_status_notify(struct btc_coexist *btcoexist,
2665 					 u8 type)
2666 {
2667 	struct rtl_priv *rtlpriv = btcoexist->adapter;
2668 	u8 h2c_parameter[3] = {0};
2669 	u32 wifi_bw;
2670 	u8 wifi_central_chnl;
2671 	bool wifi_under_5g = false;
2672 
2673 	if (btcoexist->manual_control || btcoexist->stop_coex_dm ||
2674 	    coex_sta->bt_disabled)
2675 		return;
2676 	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
2677 	if (wifi_under_5g) {
2678 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
2679 			 "[BTCoex], RunCoexistMechanism(), return for 5G <===\n");
2680 		btc8821a1ant_coex_under_5g(btcoexist);
2681 		return;
2682 	}
2683 
2684 	if (BTC_MEDIA_CONNECT == type) {
2685 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
2686 			 "[BTCoex], MEDIA connect notify\n");
2687 	} else {
2688 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
2689 			 "[BTCoex], MEDIA disconnect notify\n");
2690 		coex_dm->arp_cnt = 0;
2691 	}
2692 
2693 	/* only 2.4G we need to inform bt the chnl mask */
2694 	btcoexist->btc_get(btcoexist,
2695 			   BTC_GET_U1_WIFI_CENTRAL_CHNL,
2696 			   &wifi_central_chnl);
2697 	if ((type == BTC_MEDIA_CONNECT) &&
2698 	    (wifi_central_chnl <= 14)) {
2699 		h2c_parameter[0] = 0x0;
2700 		h2c_parameter[1] = wifi_central_chnl;
2701 		btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
2702 		if (wifi_bw == BTC_WIFI_BW_HT40)
2703 			h2c_parameter[2] = 0x30;
2704 		else
2705 			h2c_parameter[2] = 0x20;
2706 	}
2707 
2708 	coex_dm->wifi_chnl_info[0] = h2c_parameter[0];
2709 	coex_dm->wifi_chnl_info[1] = h2c_parameter[1];
2710 	coex_dm->wifi_chnl_info[2] = h2c_parameter[2];
2711 
2712 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
2713 		 "[BTCoex], FW write 0x66 = 0x%x\n",
2714 		 h2c_parameter[0] << 16 |
2715 		 h2c_parameter[1] << 8 |
2716 		 h2c_parameter[2]);
2717 
2718 	btcoexist->btc_fill_h2c(btcoexist, 0x66, 3, h2c_parameter);
2719 }
2720 
2721 void ex_btc8821a1ant_special_packet_notify(struct btc_coexist *btcoexist,
2722 					   u8 type)
2723 {
2724 	struct rtl_priv *rtlpriv = btcoexist->adapter;
2725 	bool bt_hs_on = false;
2726 	bool bt_ctrl_agg_buf_size = false;
2727 	bool wifi_under_5g = false;
2728 	u32 wifi_link_status = 0;
2729 	u32 num_of_wifi_link = 0;
2730 	u8 agg_buf_size = 5;
2731 
2732 	if (btcoexist->manual_control || btcoexist->stop_coex_dm ||
2733 	    coex_sta->bt_disabled)
2734 		return;
2735 
2736 	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
2737 	if (wifi_under_5g) {
2738 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
2739 			 "[BTCoex], RunCoexistMechanism(), return for 5G <===\n");
2740 		btc8821a1ant_coex_under_5g(btcoexist);
2741 		return;
2742 	}
2743 
2744 	if (type == BTC_PACKET_DHCP || type == BTC_PACKET_EAPOL ||
2745 	    type == BTC_PACKET_ARP) {
2746 		coex_sta->wifi_is_high_pri_task = true;
2747 
2748 		if (type == BTC_PACKET_ARP) {
2749 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
2750 				 "[BTCoex], specific Packet ARP notify\n");
2751 		} else {
2752 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
2753 				 "[BTCoex], specific Packet DHCP or EAPOL notify\n");
2754 		}
2755 	} else {
2756 		coex_sta->wifi_is_high_pri_task = false;
2757 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
2758 			 "[BTCoex], specific Packet [Type = %d] notify\n",
2759 			 type);
2760 	}
2761 
2762 	coex_sta->special_pkt_period_cnt = 0;
2763 
2764 	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS,
2765 			   &wifi_link_status);
2766 	num_of_wifi_link = wifi_link_status >> 16;
2767 	if (num_of_wifi_link >= 2) {
2768 		btc8821a1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0);
2769 		btc8821a1ant_limited_rx(btcoexist, NORMAL_EXEC, false,
2770 					bt_ctrl_agg_buf_size, agg_buf_size);
2771 		btc8821a1ant_action_wifi_multi_port(btcoexist);
2772 		return;
2773 	}
2774 
2775 	btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
2776 	if (coex_sta->c2h_bt_inquiry_page) {
2777 		btc8821a1ant_action_bt_inquiry(btcoexist);
2778 		return;
2779 	} else if (bt_hs_on) {
2780 		btc8821a1ant_action_hs(btcoexist);
2781 		return;
2782 	}
2783 
2784 	if (type == BTC_PACKET_DHCP || type == BTC_PACKET_EAPOL ||
2785 	    type == BTC_PACKET_ARP) {
2786 		if (type == BTC_PACKET_ARP) {
2787 			coex_dm->arp_cnt++;
2788 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
2789 				 "[BTCoex], ARP Packet Count = %d\n",
2790 				 coex_dm->arp_cnt);
2791 			if (coex_dm->arp_cnt >= 10)
2792 				/* if APR PKT > 10 after connect, do not go to
2793 				 * btc8821a1ant_act_wifi_conn_sp_pkt
2794 				 */
2795 				return;
2796 		}
2797 
2798 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
2799 			 "[BTCoex], special Packet(%d) notify\n", type);
2800 		btc8821a1ant_act_wifi_conn_sp_pkt(btcoexist);
2801 	}
2802 }
2803 
2804 void ex_btc8821a1ant_bt_info_notify(struct btc_coexist *btcoexist,
2805 				    u8 *tmp_buf, u8 length)
2806 {
2807 	struct rtl_priv *rtlpriv = btcoexist->adapter;
2808 	u8 i;
2809 	u8 bt_info = 0;
2810 	u8 rsp_source = 0;
2811 	bool wifi_connected = false;
2812 	bool bt_busy = false;
2813 	bool wifi_under_5g = false;
2814 
2815 	coex_sta->c2h_bt_info_req_sent = false;
2816 
2817 	btcoexist->btc_get(btcoexist,
2818 		 BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
2819 
2820 	rsp_source = tmp_buf[0] & 0xf;
2821 	if (rsp_source >= BT_INFO_SRC_8821A_1ANT_MAX)
2822 		rsp_source = BT_INFO_SRC_8821A_1ANT_WIFI_FW;
2823 	coex_sta->bt_info_c2h_cnt[rsp_source]++;
2824 
2825 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
2826 		 "[BTCoex], Bt info[%d], length = %d, hex data = [",
2827 		 rsp_source, length);
2828 	for (i = 0; i < length; i++) {
2829 		coex_sta->bt_info_c2h[rsp_source][i] = tmp_buf[i];
2830 		if (i == 1)
2831 			bt_info = tmp_buf[i];
2832 		if (i == length - 1) {
2833 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
2834 				 "0x%02x]\n", tmp_buf[i]);
2835 		} else {
2836 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
2837 				 "0x%02x, ", tmp_buf[i]);
2838 		}
2839 	}
2840 
2841 	if (BT_INFO_SRC_8821A_1ANT_WIFI_FW != rsp_source) {
2842 		/* [3:0] */
2843 		coex_sta->bt_retry_cnt =
2844 			coex_sta->bt_info_c2h[rsp_source][2] & 0xf;
2845 
2846 		coex_sta->bt_rssi =
2847 			coex_sta->bt_info_c2h[rsp_source][3] * 2 + 10;
2848 
2849 		coex_sta->bt_info_ext = coex_sta->bt_info_c2h[rsp_source][4];
2850 
2851 		coex_sta->bt_tx_rx_mask =
2852 			(coex_sta->bt_info_c2h[rsp_source][2] & 0x40);
2853 		btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_TX_RX_MASK,
2854 				   &coex_sta->bt_tx_rx_mask);
2855 		if (!coex_sta->bt_tx_rx_mask) {
2856 			/* BT into is responded by BT FW and BT RF REG 0x3C !=
2857 			 * 0x15 => Need to switch BT TRx Mask
2858 			 */
2859 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
2860 				 "[BTCoex], Switch BT TRx Mask since BT RF REG 0x3C != 0x15\n");
2861 			btcoexist->btc_set_bt_reg(btcoexist, BTC_BT_REG_RF,
2862 						  0x3c, 0x15);
2863 		}
2864 
2865 		/* Here we need to resend some wifi info to BT
2866 		 * because bt is reset and lost the info
2867 		 */
2868 		if (coex_sta->bt_info_ext & BIT1) {
2869 			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
2870 				 "[BTCoex], BT ext info bit1 check, send wifi BW&Chnl to BT!!\n");
2871 			btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
2872 					   &wifi_connected);
2873 			if (wifi_connected) {
2874 				ex_btc8821a1ant_media_status_notify(btcoexist,
2875 							       BTC_MEDIA_CONNECT);
2876 			} else {
2877 				ex_btc8821a1ant_media_status_notify(btcoexist,
2878 							       BTC_MEDIA_DISCONNECT);
2879 			}
2880 		}
2881 
2882 		if ((coex_sta->bt_info_ext & BIT3) && !wifi_under_5g) {
2883 			if (!btcoexist->manual_control &&
2884 			    !btcoexist->stop_coex_dm) {
2885 				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
2886 					 "[BTCoex], BT ext info bit3 check, set BT NOT to ignore Wlan active!!\n");
2887 				btc8821a1ant_ignore_wlan_act(btcoexist,
2888 							     FORCE_EXEC,
2889 							     false);
2890 			}
2891 		}
2892 	}
2893 
2894 	/* check BIT2 first ==> check if bt is under inquiry or page scan */
2895 	if (bt_info & BT_INFO_8821A_1ANT_B_INQ_PAGE)
2896 		coex_sta->c2h_bt_inquiry_page = true;
2897 	else
2898 		coex_sta->c2h_bt_inquiry_page = false;
2899 
2900 	/* set link exist status */
2901 	if (!(bt_info & BT_INFO_8821A_1ANT_B_CONNECTION)) {
2902 		coex_sta->bt_link_exist = false;
2903 		coex_sta->pan_exist = false;
2904 		coex_sta->a2dp_exist = false;
2905 		coex_sta->hid_exist = false;
2906 		coex_sta->sco_exist = false;
2907 	} else {
2908 		/* connection exists */
2909 		coex_sta->bt_link_exist = true;
2910 		if (bt_info & BT_INFO_8821A_1ANT_B_FTP)
2911 			coex_sta->pan_exist = true;
2912 		else
2913 			coex_sta->pan_exist = false;
2914 		if (bt_info & BT_INFO_8821A_1ANT_B_A2DP)
2915 			coex_sta->a2dp_exist = true;
2916 		else
2917 			coex_sta->a2dp_exist = false;
2918 		if (bt_info & BT_INFO_8821A_1ANT_B_HID)
2919 			coex_sta->hid_exist = true;
2920 		else
2921 			coex_sta->hid_exist = false;
2922 		if (bt_info & BT_INFO_8821A_1ANT_B_SCO_ESCO)
2923 			coex_sta->sco_exist = true;
2924 		else
2925 			coex_sta->sco_exist = false;
2926 	}
2927 
2928 	btc8821a1ant_update_bt_link_info(btcoexist);
2929 
2930 	/* mask profile bit for connect-ilde identification
2931 	 * (for CSR case: A2DP idle --> 0x41)
2932 	 */
2933 	bt_info = bt_info & 0x1f;
2934 
2935 	if (!(bt_info & BT_INFO_8821A_1ANT_B_CONNECTION)) {
2936 		coex_dm->bt_status = BT_8821A_1ANT_BT_STATUS_NON_CONNECTED_IDLE;
2937 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
2938 			 "[BTCoex], BtInfoNotify(), BT Non-Connected idle!!!\n");
2939 	} else if (bt_info == BT_INFO_8821A_1ANT_B_CONNECTION) {
2940 		/* connection exists but no busy */
2941 		coex_dm->bt_status = BT_8821A_1ANT_BT_STATUS_CONNECTED_IDLE;
2942 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
2943 			 "[BTCoex], BtInfoNotify(), BT Connected-idle!!!\n");
2944 	} else if ((bt_info&BT_INFO_8821A_1ANT_B_SCO_ESCO) ||
2945 		(bt_info & BT_INFO_8821A_1ANT_B_SCO_BUSY)) {
2946 		coex_dm->bt_status = BT_8821A_1ANT_BT_STATUS_SCO_BUSY;
2947 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
2948 			 "[BTCoex], BtInfoNotify(), BT SCO busy!!!\n");
2949 	} else if (bt_info & BT_INFO_8821A_1ANT_B_ACL_BUSY) {
2950 		if (BT_8821A_1ANT_BT_STATUS_ACL_BUSY != coex_dm->bt_status)
2951 			coex_dm->auto_tdma_adjust = false;
2952 		coex_dm->bt_status = BT_8821A_1ANT_BT_STATUS_ACL_BUSY;
2953 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
2954 			 "[BTCoex], BtInfoNotify(), BT ACL busy!!!\n");
2955 	} else {
2956 		coex_dm->bt_status = BT_8821A_1ANT_BT_STATUS_MAX;
2957 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
2958 			 "[BTCoex], BtInfoNotify(), BT Non-Defined state!!!\n");
2959 	}
2960 
2961 	if ((BT_8821A_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) ||
2962 	    (BT_8821A_1ANT_BT_STATUS_SCO_BUSY == coex_dm->bt_status) ||
2963 	    (BT_8821A_1ANT_BT_STATUS_ACL_SCO_BUSY == coex_dm->bt_status))
2964 		bt_busy = true;
2965 	else
2966 		bt_busy = false;
2967 	btcoexist->btc_set(btcoexist,
2968 			   BTC_SET_BL_BT_TRAFFIC_BUSY, &bt_busy);
2969 
2970 	btc8821a1ant_run_coexist_mechanism(btcoexist);
2971 }
2972 
2973 void ex_btc8821a1ant_halt_notify(struct btc_coexist *btcoexist)
2974 {
2975 	struct rtl_priv *rtlpriv = btcoexist->adapter;
2976 	bool wifi_under_5g = false;
2977 
2978 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
2979 		 "[BTCoex], Halt notify\n");
2980 	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
2981 	if (wifi_under_5g) {
2982 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
2983 			 "[BTCoex], RunCoexistMechanism(), return for 5G <===\n");
2984 		btc8821a1ant_coex_under_5g(btcoexist);
2985 		return;
2986 	}
2987 
2988 
2989 	btcoexist->stop_coex_dm = true;
2990 
2991 	btc8821a1ant_set_ant_path(btcoexist, BTC_ANT_PATH_BT, false, true);
2992 	btc8821a1ant_ignore_wlan_act(btcoexist, FORCE_EXEC, true);
2993 
2994 	btc8821a1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0);
2995 	btc8821a1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 0);
2996 
2997 	ex_btc8821a1ant_media_status_notify(btcoexist, BTC_MEDIA_DISCONNECT);
2998 }
2999 
3000 void ex_btc8821a1ant_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state)
3001 {
3002 	struct rtl_priv *rtlpriv = btcoexist->adapter;
3003 	bool wifi_under_5g = false;
3004 
3005 	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
3006 	if (wifi_under_5g) {
3007 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
3008 			 "[BTCoex], RunCoexistMechanism(), return for 5G <===\n");
3009 		btc8821a1ant_coex_under_5g(btcoexist);
3010 		return;
3011 	}
3012 
3013 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
3014 		 "[BTCoex], Pnp notify\n");
3015 
3016 	if (BTC_WIFI_PNP_SLEEP == pnp_state) {
3017 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
3018 			 "[BTCoex], Pnp notify to SLEEP\n");
3019 		/* BT should clear UnderIPS/UnderLPS state to avoid mismatch
3020 		 * state after wakeup.
3021 		 */
3022 		coex_sta->under_ips = false;
3023 		coex_sta->under_lps = false;
3024 		btcoexist->stop_coex_dm = true;
3025 		btc8821a1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE,
3026 					      0x0, 0x0);
3027 		btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0);
3028 		btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2);
3029 		btc8821a1ant_set_ant_path(btcoexist, BTC_ANT_PATH_BT, false,
3030 					  true);
3031 	} else if (BTC_WIFI_PNP_WAKE_UP == pnp_state) {
3032 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
3033 			 "[BTCoex], Pnp notify to WAKE UP\n");
3034 		btcoexist->stop_coex_dm = false;
3035 		btc8821a1ant_init_hw_config(btcoexist, false, false);
3036 		btc8821a1ant_init_coex_dm(btcoexist);
3037 		btc8821a1ant_query_bt_info(btcoexist);
3038 	}
3039 }
3040 
3041 void ex_btc8821a1ant_periodical(struct btc_coexist *btcoexist)
3042 {
3043 	struct rtl_priv *rtlpriv = btcoexist->adapter;
3044 	static u8 dis_ver_info_cnt;
3045 	u32 fw_ver = 0, bt_patch_ver = 0;
3046 	struct btc_board_info *board_info = &btcoexist->board_info;
3047 	struct btc_stack_info *stack_info = &btcoexist->stack_info;
3048 
3049 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
3050 		 "[BTCoex], ==========================Periodical===========================\n");
3051 
3052 	if (dis_ver_info_cnt <= 5) {
3053 		dis_ver_info_cnt += 1;
3054 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
3055 			 "[BTCoex], ****************************************************************\n");
3056 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
3057 			 "[BTCoex], Ant PG Num/ Ant Mech/ Ant Pos = %d/ %d/ %d\n",
3058 			      board_info->pg_ant_num,
3059 			      board_info->btdm_ant_num,
3060 			      board_info->btdm_ant_pos);
3061 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
3062 			 "[BTCoex], BT stack/ hci ext ver = %s / %d\n",
3063 			      stack_info->profile_notified ? "Yes" : "No",
3064 			      stack_info->hci_version);
3065 		btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER,
3066 				   &bt_patch_ver);
3067 		btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver);
3068 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
3069 			 "[BTCoex], CoexVer/ FwVer/ PatchVer = %d_%x/ 0x%x/ 0x%x(%d)\n",
3070 			      glcoex_ver_date_8821a_1ant,
3071 			      glcoex_ver_8821a_1ant,
3072 			      fw_ver, bt_patch_ver,
3073 			      bt_patch_ver);
3074 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
3075 			 "[BTCoex], ****************************************************************\n");
3076 	}
3077 
3078 	if (!btcoexist->auto_report_1ant) {
3079 		btc8821a1ant_query_bt_info(btcoexist);
3080 		btc8821a1ant_monitor_bt_ctr(btcoexist);
3081 	} else {
3082 		coex_sta->special_pkt_period_cnt++;
3083 	}
3084 }
3085