halbtc8821a1ant.c 91.9 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
/******************************************************************************
 *
 * Copyright(c) 2012  Realtek Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * The full GNU General Public License is included in this distribution in the
 * file called LICENSE.
 *
 * Contact Information:
 * wlanfae <wlanfae@realtek.com>
 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
 * Hsinchu 300, Taiwan.
 *
 * Larry Finger <Larry.Finger@lwfinger.net>
 *
 *****************************************************************************/

26
/**************************************************************
27 28 29 30 31 32 33
 * Description:
 *
 * This file is for RTL8821A Co-exist mechanism
 *
 * History
 * 2012/11/15 Cosa first check in.
 *
34 35 36
 **************************************************************/

/**************************************************************
37
 * include files
38
 **************************************************************/
39
#include "halbt_precomp.h"
40
/**************************************************************
41
 * Global variables, these are static variables
42
 **************************************************************/
43 44 45 46
static struct coex_dm_8821a_1ant glcoex_dm_8821a_1ant;
static struct coex_dm_8821a_1ant *coex_dm = &glcoex_dm_8821a_1ant;
static struct coex_sta_8821a_1ant glcoex_sta_8821a_1ant;
static struct coex_sta_8821a_1ant *coex_sta = &glcoex_sta_8821a_1ant;
47 48
static void btc8821a1ant_act_bt_sco_hid_only_busy(struct btc_coexist *btcoexist,
						  u8 wifi_status);
49 50 51 52 53 54 55

static const char *const glbt_info_src_8821a_1ant[] = {
	  "BT Info[wifi fw]",
	  "BT Info[bt rsp]",
	  "BT Info[bt auto report]",
};

56 57
static u32 glcoex_ver_date_8821a_1ant = 20130816;
static u32 glcoex_ver_8821a_1ant = 0x41;
58

59
/**************************************************************
60 61
 * local function proto type if needed
 *
62 63 64 65 66
 * local function start with btc8821a1ant_
 **************************************************************/
static u8 btc8821a1ant_bt_rssi_state(struct btc_coexist *btcoexist,
				     u8 level_num, u8 rssi_thresh,
				     u8 rssi_thresh1)
67
{
68
	struct rtl_priv *rtlpriv = btcoexist->adapter;
69 70
	long bt_rssi = 0;
	u8 bt_rssi_state = coex_sta->pre_bt_rssi_state;
71 72 73 74 75 76 77 78 79

	bt_rssi = coex_sta->bt_rssi;

	if (level_num == 2) {
		if ((coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_LOW) ||
		    (coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) {
			if (bt_rssi >= (rssi_thresh +
					BTC_RSSI_COEX_THRESH_TOL_8821A_1ANT)) {
				bt_rssi_state = BTC_RSSI_STATE_HIGH;
80 81
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], BT Rssi state switch to High\n");
82 83
			} else {
				bt_rssi_state = BTC_RSSI_STATE_STAY_LOW;
84 85
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], BT Rssi state stay at Low\n");
86 87 88 89
			}
		} else {
			if (bt_rssi < rssi_thresh) {
				bt_rssi_state = BTC_RSSI_STATE_LOW;
90 91
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], BT Rssi state switch to Low\n");
92 93
			} else {
				bt_rssi_state = BTC_RSSI_STATE_STAY_HIGH;
94 95
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], BT Rssi state stay at High\n");
96 97 98 99
			}
		}
	} else if (level_num == 3) {
		if (rssi_thresh > rssi_thresh1) {
100 101
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "[BTCoex], BT Rssi thresh error!!\n");
102 103 104 105 106 107 108 109
			return coex_sta->pre_bt_rssi_state;
		}

		if ((coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_LOW) ||
		    (coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) {
			if (bt_rssi >= (rssi_thresh +
					BTC_RSSI_COEX_THRESH_TOL_8821A_1ANT)) {
				bt_rssi_state = BTC_RSSI_STATE_MEDIUM;
110 111
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], BT Rssi state switch to Medium\n");
112 113
			} else {
				bt_rssi_state = BTC_RSSI_STATE_STAY_LOW;
114 115
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], BT Rssi state stay at Low\n");
116 117 118 119 120 121 122 123
			}
		} else if ((coex_sta->pre_bt_rssi_state ==
			   BTC_RSSI_STATE_MEDIUM) ||
			   (coex_sta->pre_bt_rssi_state ==
			    BTC_RSSI_STATE_STAY_MEDIUM)) {
			if (bt_rssi >= (rssi_thresh1 +
					BTC_RSSI_COEX_THRESH_TOL_8821A_1ANT)) {
				bt_rssi_state = BTC_RSSI_STATE_HIGH;
124 125
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], BT Rssi state switch to High\n");
126 127
			} else if (bt_rssi < rssi_thresh) {
				bt_rssi_state = BTC_RSSI_STATE_LOW;
128 129
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], BT Rssi state switch to Low\n");
130 131
			} else {
				bt_rssi_state = BTC_RSSI_STATE_STAY_MEDIUM;
132 133
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], BT Rssi state stay at Medium\n");
134 135 136 137
			}
		} else {
			if (bt_rssi < rssi_thresh1) {
				bt_rssi_state = BTC_RSSI_STATE_MEDIUM;
138 139
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], BT Rssi state switch to Medium\n");
140 141
			} else {
				bt_rssi_state = BTC_RSSI_STATE_STAY_HIGH;
142 143
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], BT Rssi state stay at High\n");
144 145 146 147 148 149 150 151
			}
		}
	}
	coex_sta->pre_bt_rssi_state = bt_rssi_state;

	return bt_rssi_state;
}

152 153 154
static u8 btc8821a1ant_wifi_rssi_state(struct btc_coexist *btcoexist,
				       u8 index, u8 level_num, u8 rssi_thresh,
				       u8 rssi_thresh1)
155
{
156
	struct rtl_priv *rtlpriv = btcoexist->adapter;
157 158 159 160 161 162 163 164 165 166
	long	wifi_rssi = 0;
	u8	wifi_rssi_state = coex_sta->pre_wifi_rssi_state[index];

	btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi);

	if (level_num == 2) {
		if ((coex_sta->pre_wifi_rssi_state[index] ==
		     BTC_RSSI_STATE_LOW) ||
		    (coex_sta->pre_wifi_rssi_state[index] ==
		     BTC_RSSI_STATE_STAY_LOW)) {
167 168
			if (wifi_rssi >= (rssi_thresh +
					BTC_RSSI_COEX_THRESH_TOL_8821A_1ANT)) {
169
				wifi_rssi_state = BTC_RSSI_STATE_HIGH;
170 171
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], wifi RSSI state switch to High\n");
172 173
			} else {
				wifi_rssi_state = BTC_RSSI_STATE_STAY_LOW;
174 175
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], wifi RSSI state stay at Low\n");
176 177 178 179
			}
		} else {
			if (wifi_rssi < rssi_thresh) {
				wifi_rssi_state = BTC_RSSI_STATE_LOW;
180 181
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], wifi RSSI state switch to Low\n");
182 183
			} else {
				wifi_rssi_state = BTC_RSSI_STATE_STAY_HIGH;
184 185
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], wifi RSSI state stay at High\n");
186 187 188 189
			}
		}
	} else if (level_num == 3) {
		if (rssi_thresh > rssi_thresh1) {
190 191
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "[BTCoex], wifi RSSI thresh error!!\n");
192 193 194 195 196 197 198
			return coex_sta->pre_wifi_rssi_state[index];
		}

		if ((coex_sta->pre_wifi_rssi_state[index] ==
		     BTC_RSSI_STATE_LOW) ||
		    (coex_sta->pre_wifi_rssi_state[index] ==
		     BTC_RSSI_STATE_STAY_LOW)) {
199 200
			if (wifi_rssi >= (rssi_thresh +
					BTC_RSSI_COEX_THRESH_TOL_8821A_1ANT)) {
201
				wifi_rssi_state = BTC_RSSI_STATE_MEDIUM;
202 203
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], wifi RSSI state switch to Medium\n");
204 205
			} else {
				wifi_rssi_state = BTC_RSSI_STATE_STAY_LOW;
206 207
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], wifi RSSI state stay at Low\n");
208 209 210 211 212
			}
		} else if ((coex_sta->pre_wifi_rssi_state[index] ==
			BTC_RSSI_STATE_MEDIUM) ||
			(coex_sta->pre_wifi_rssi_state[index] ==
			BTC_RSSI_STATE_STAY_MEDIUM)) {
213 214
			if (wifi_rssi >= (rssi_thresh1 +
					BTC_RSSI_COEX_THRESH_TOL_8821A_1ANT)) {
215
				wifi_rssi_state = BTC_RSSI_STATE_HIGH;
216 217
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], wifi RSSI state switch to High\n");
218 219
			} else if (wifi_rssi < rssi_thresh) {
				wifi_rssi_state = BTC_RSSI_STATE_LOW;
220 221
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], wifi RSSI state switch to Low\n");
222 223
			} else {
				wifi_rssi_state = BTC_RSSI_STATE_STAY_MEDIUM;
224 225
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], wifi RSSI state stay at Medium\n");
226 227 228 229
			}
		} else {
			if (wifi_rssi < rssi_thresh1) {
				wifi_rssi_state = BTC_RSSI_STATE_MEDIUM;
230 231
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], wifi RSSI state switch to Medium\n");
232 233
			} else {
				wifi_rssi_state = BTC_RSSI_STATE_STAY_HIGH;
234 235
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], wifi RSSI state stay at High\n");
236 237 238 239 240 241 242 243
			}
		}
	}
	coex_sta->pre_wifi_rssi_state[index] = wifi_rssi_state;

	return wifi_rssi_state;
}

244 245
static void btc8821a1ant_update_ra_mask(struct btc_coexist *btcoexist,
					bool force_exec, u32 dis_rate_mask)
246 247 248 249 250
{
	coex_dm->cur_ra_mask = dis_rate_mask;

	if (force_exec ||
	    (coex_dm->pre_ra_mask != coex_dm->cur_ra_mask)) {
251
		btcoexist->btc_set(btcoexist, BTC_SET_ACT_UPDATE_RAMASK,
252 253 254 255 256 257 258 259
				   &coex_dm->cur_ra_mask);
	}
	coex_dm->pre_ra_mask = coex_dm->cur_ra_mask;
}

static void btc8821a1ant_auto_rate_fb_retry(struct btc_coexist *btcoexist,
					    bool force_exec, u8 type)
{
260
	bool wifi_under_b_mode = false;
261 262 263 264 265 266

	coex_dm->cur_arfr_type = type;

	if (force_exec ||
	    (coex_dm->pre_arfr_type != coex_dm->cur_arfr_type)) {
		switch (coex_dm->cur_arfr_type) {
267
		case 0:	/* normal mode */
268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296
			btcoexist->btc_write_4byte(btcoexist, 0x430,
						   coex_dm->backup_arfr_cnt1);
			btcoexist->btc_write_4byte(btcoexist, 0x434,
						   coex_dm->backup_arfr_cnt2);
			break;
		case 1:
			btcoexist->btc_get(btcoexist,
					   BTC_GET_BL_WIFI_UNDER_B_MODE,
					   &wifi_under_b_mode);
			if (wifi_under_b_mode) {
				btcoexist->btc_write_4byte(btcoexist, 0x430,
							   0x0);
				btcoexist->btc_write_4byte(btcoexist, 0x434,
							   0x01010101);
			} else {
				btcoexist->btc_write_4byte(btcoexist, 0x430,
							   0x0);
				btcoexist->btc_write_4byte(btcoexist, 0x434,
							   0x04030201);
			}
			break;
		default:
			break;
		}
	}

	coex_dm->pre_arfr_type = coex_dm->cur_arfr_type;
}

297 298
static void btc8821a1ant_retry_limit(struct btc_coexist *btcoexist,
				     bool force_exec, u8 type)
299 300 301 302 303 304
{
	coex_dm->cur_retry_limit_type = type;

	if (force_exec ||
	    (coex_dm->pre_retry_limit_type != coex_dm->cur_retry_limit_type)) {
		switch (coex_dm->cur_retry_limit_type) {
305
		case 0:	/* normal mode */
306 307 308
			btcoexist->btc_write_2byte(btcoexist, 0x42a,
						   coex_dm->backup_retry_limit);
			break;
309
		case 1:	/* retry limit = 8 */
310 311 312 313 314 315 316 317 318
			btcoexist->btc_write_2byte(btcoexist, 0x42a, 0x0808);
			break;
		default:
			break;
		}
	}
	coex_dm->pre_retry_limit_type = coex_dm->cur_retry_limit_type;
}

319 320
static void btc8821a1ant_ampdu_max_time(struct btc_coexist *btcoexist,
					bool force_exec, u8 type)
321 322 323 324 325 326
{
	coex_dm->cur_ampdu_time_type = type;

	if (force_exec ||
	    (coex_dm->pre_ampdu_time_type != coex_dm->cur_ampdu_time_type)) {
		switch (coex_dm->cur_ampdu_time_type) {
327
		case 0:	/* normal mode */
328 329 330
			btcoexist->btc_write_1byte(btcoexist, 0x456,
						   coex_dm->backup_ampdu_max_time);
			break;
331
		case 1:	/* AMPDU time = 0x38 * 32us */
332 333 334 335 336 337 338 339 340 341
			btcoexist->btc_write_1byte(btcoexist, 0x456, 0x38);
			break;
		default:
			break;
		}
	}

	coex_dm->pre_ampdu_time_type = coex_dm->cur_ampdu_time_type;
}

342 343 344 345
static void btc8821a1ant_limited_tx(struct btc_coexist *btcoexist,
				    bool force_exec, u8 ra_mask_type,
				    u8 arfr_type, u8 retry_limit_type,
				    u8 ampdu_time_type)
346 347
{
	switch (ra_mask_type) {
348 349
	case 0:	/* normal mode */
		btc8821a1ant_update_ra_mask(btcoexist, force_exec, 0x0);
350
		break;
351 352 353
	case 1:	/* disable cck 1/2 */
		btc8821a1ant_update_ra_mask(btcoexist, force_exec,
					    0x00000003);
354
		break;
355 356 357
	case 2:	/* disable cck 1/2/5.5, ofdm 6/9/12/18/24, mcs 0/1/2/3/4 */
		btc8821a1ant_update_ra_mask(btcoexist, force_exec,
					    0x0001f1f7);
358 359 360 361 362 363
		break;
	default:
		break;
	}

	btc8821a1ant_auto_rate_fb_retry(btcoexist, force_exec, arfr_type);
364 365
	btc8821a1ant_retry_limit(btcoexist, force_exec, retry_limit_type);
	btc8821a1ant_ampdu_max_time(btcoexist, force_exec, ampdu_time_type);
366 367
}

368 369 370
static void btc8821a1ant_limited_rx(struct btc_coexist *btcoexist,
				    bool force_exec, bool rej_ap_agg_pkt,
				    bool bt_ctrl_agg_buf_size, u8 agg_buf_size)
371 372 373 374 375
{
	bool reject_rx_agg = rej_ap_agg_pkt;
	bool bt_ctrl_rx_agg_size = bt_ctrl_agg_buf_size;
	u8 rx_agg_size = agg_buf_size;

376
	/* Rx Aggregation related setting */
377 378
	btcoexist->btc_set(btcoexist,
		 BTC_SET_BL_TO_REJ_AP_AGG_PKT, &reject_rx_agg);
379
	/* decide BT control aggregation buf size or not */
380 381
	btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_CTRL_AGG_SIZE,
			   &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 386 387
	btcoexist->btc_set(btcoexist, BTC_SET_ACT_AGGREGATE_CTRL, NULL);
}

388
static void btc8821a1ant_monitor_bt_ctr(struct btc_coexist *btcoexist)
389
{
390 391
	u32 reg_hp_tx_rx, reg_lp_tx_rx, u4_tmp;
	u32 reg_hp_tx = 0, reg_hp_rx = 0, reg_lp_tx = 0, reg_lp_rx = 0;
392 393 394 395 396 397

	reg_hp_tx_rx = 0x770;
	reg_lp_tx_rx = 0x774;

	u4_tmp = btcoexist->btc_read_4byte(btcoexist, reg_hp_tx_rx);
	reg_hp_tx = u4_tmp & MASKLWORD;
398
	reg_hp_rx = (u4_tmp & MASKHWORD) >> 16;
399 400 401

	u4_tmp = btcoexist->btc_read_4byte(btcoexist, reg_lp_tx_rx);
	reg_lp_tx = u4_tmp & MASKLWORD;
402
	reg_lp_rx = (u4_tmp & MASKHWORD) >> 16;
403 404 405 406 407 408

	coex_sta->high_priority_tx = reg_hp_tx;
	coex_sta->high_priority_rx = reg_hp_rx;
	coex_sta->low_priority_tx = reg_lp_tx;
	coex_sta->low_priority_rx = reg_lp_rx;

409
	/* reset counter */
410 411 412
	btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc);
}

413
static void btc8821a1ant_query_bt_info(struct btc_coexist *btcoexist)
414
{
415
	struct rtl_priv *rtlpriv = btcoexist->adapter;
416 417 418 419
	u8 h2c_parameter[1] = {0};

	coex_sta->c2h_bt_info_req_sent = true;

420
	h2c_parameter[0] |= BIT0; /* trigger */
421

422 423 424
	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
		 "[BTCoex], Query Bt Info, FW write 0x61 = 0x%x\n",
		 h2c_parameter[0]);
425 426 427 428

	btcoexist->btc_fill_h2c(btcoexist, 0x61, 1, h2c_parameter);
}

429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461
bool btc8821a1ant_is_wifi_status_changed(struct btc_coexist *btcoexist)
{
	static bool pre_wifi_busy = true;
	static bool pre_under_4way = true;
	static bool pre_bt_hs_on = true;
	bool wifi_busy = false, under_4way = false, bt_hs_on = false;
	bool wifi_connected = false;

	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
			   &wifi_connected);
	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
	btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS,
			   &under_4way);

	if (wifi_connected) {
		if (wifi_busy != pre_wifi_busy) {
			pre_wifi_busy = wifi_busy;
			return true;
		}
		if (under_4way != pre_under_4way) {
			pre_under_4way = under_4way;
			return true;
		}
		if (bt_hs_on != pre_bt_hs_on) {
			pre_bt_hs_on = bt_hs_on;
			return true;
		}
	}

	return false;
}

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 468 469 470 471 472 473 474

	btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);

	bt_link_info->bt_link_exist = coex_sta->bt_link_exist;
	bt_link_info->sco_exist = coex_sta->sco_exist;
	bt_link_info->a2dp_exist = coex_sta->a2dp_exist;
	bt_link_info->pan_exist = coex_sta->pan_exist;
	bt_link_info->hid_exist = coex_sta->hid_exist;

475
	/* work around for HS mode */
476 477 478 479 480
	if (bt_hs_on) {
		bt_link_info->pan_exist = true;
		bt_link_info->bt_link_exist = true;
	}

481
	/* check if Sco only */
482 483 484 485 486 487 488 489
	if (bt_link_info->sco_exist &&
	    !bt_link_info->a2dp_exist &&
	    !bt_link_info->pan_exist &&
	    !bt_link_info->hid_exist)
		bt_link_info->sco_only = true;
	else
		bt_link_info->sco_only = false;

490
	/* check if A2dp only */
491 492 493 494 495 496 497 498
	if (!bt_link_info->sco_exist &&
	    bt_link_info->a2dp_exist &&
	    !bt_link_info->pan_exist &&
	    !bt_link_info->hid_exist)
		bt_link_info->a2dp_only = true;
	else
		bt_link_info->a2dp_only = false;

499
	/* check if Pan only */
500 501 502 503 504 505 506 507
	if (!bt_link_info->sco_exist &&
	    !bt_link_info->a2dp_exist &&
	    bt_link_info->pan_exist &&
	    !bt_link_info->hid_exist)
		bt_link_info->pan_only = true;
	else
		bt_link_info->pan_only = false;

508
	/* check if Hid only */
509 510 511 512 513 514 515 516 517
	if (!bt_link_info->sco_exist &&
	    !bt_link_info->a2dp_exist &&
	    !bt_link_info->pan_exist &&
	    bt_link_info->hid_exist)
		bt_link_info->hid_only = true;
	else
		bt_link_info->hid_only = false;
}

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 523 524
	bool bt_hs_on = false;
	u8 algorithm = BT_8821A_1ANT_COEX_ALGO_UNDEFINED;
	u8 num_of_diff_profile = 0;
525 526 527 528

	btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);

	if (!bt_link_info->bt_link_exist) {
529 530
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], No BT link exists!!!\n");
531 532 533 534 535 536 537 538 539 540 541 542 543 544
		return algorithm;
	}

	if (bt_link_info->sco_exist)
		num_of_diff_profile++;
	if (bt_link_info->hid_exist)
		num_of_diff_profile++;
	if (bt_link_info->pan_exist)
		num_of_diff_profile++;
	if (bt_link_info->a2dp_exist)
		num_of_diff_profile++;

	if (num_of_diff_profile == 1) {
		if (bt_link_info->sco_exist) {
545 546
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "[BTCoex], BT Profile = SCO only\n");
547 548 549
			algorithm = BT_8821A_1ANT_COEX_ALGO_SCO;
		} else {
			if (bt_link_info->hid_exist) {
550 551
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], BT Profile = HID only\n");
552 553
				algorithm = BT_8821A_1ANT_COEX_ALGO_HID;
			} else if (bt_link_info->a2dp_exist) {
554 555
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], BT Profile = A2DP only\n");
556 557 558
				algorithm = BT_8821A_1ANT_COEX_ALGO_A2DP;
			} else if (bt_link_info->pan_exist) {
				if (bt_hs_on) {
559 560 561
					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
						 DBG_LOUD,
						 "[BTCoex], BT Profile = PAN(HS) only\n");
562 563
					algorithm = BT_8821A_1ANT_COEX_ALGO_PANHS;
				} else {
564 565 566
					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
						 DBG_LOUD,
						 "[BTCoex], BT Profile = PAN(EDR) only\n");
567 568 569 570 571 572 573
					algorithm = BT_8821A_1ANT_COEX_ALGO_PANEDR;
				}
			}
		}
	} else if (num_of_diff_profile == 2) {
		if (bt_link_info->sco_exist) {
			if (bt_link_info->hid_exist) {
574 575
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], BT Profile = SCO + HID\n");
576 577
				algorithm = BT_8821A_1ANT_COEX_ALGO_HID;
			} else if (bt_link_info->a2dp_exist) {
578 579
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], BT Profile = SCO + A2DP ==> SCO\n");
580 581 582
				algorithm = BT_8821A_1ANT_COEX_ALGO_SCO;
			} else if (bt_link_info->pan_exist) {
				if (bt_hs_on) {
583 584 585
					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
						 DBG_LOUD,
						 "[BTCoex], BT Profile = SCO + PAN(HS)\n");
586 587
					algorithm = BT_8821A_1ANT_COEX_ALGO_SCO;
				} else {
588 589 590
					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
						 DBG_LOUD,
						 "[BTCoex], BT Profile = SCO + PAN(EDR)\n");
591 592 593 594 595 596
					algorithm = BT_8821A_1ANT_COEX_ALGO_PANEDR_HID;
				}
			}
		} else {
			if (bt_link_info->hid_exist &&
			    bt_link_info->a2dp_exist) {
597 598
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], BT Profile = HID + A2DP\n");
599 600 601 602
				algorithm = BT_8821A_1ANT_COEX_ALGO_HID_A2DP;
			} else if (bt_link_info->hid_exist &&
				   bt_link_info->pan_exist) {
				if (bt_hs_on) {
603 604 605
					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
						 DBG_LOUD,
						 "[BTCoex], BT Profile = HID + PAN(HS)\n");
606 607
					algorithm = BT_8821A_1ANT_COEX_ALGO_HID_A2DP;
				} else {
608 609 610
					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
						 DBG_LOUD,
						 "[BTCoex], BT Profile = HID + PAN(EDR)\n");
611 612 613 614 615
					algorithm = BT_8821A_1ANT_COEX_ALGO_PANEDR_HID;
				}
			} else if (bt_link_info->pan_exist &&
				   bt_link_info->a2dp_exist) {
				if (bt_hs_on) {
616 617 618
					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
						 DBG_LOUD,
						 "[BTCoex], BT Profile = A2DP + PAN(HS)\n");
619 620
					algorithm = BT_8821A_1ANT_COEX_ALGO_A2DP_PANHS;
				} else {
621 622 623
					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
						 DBG_LOUD,
						 "[BTCoex], BT Profile = A2DP + PAN(EDR)\n");
624 625 626 627 628 629 630 631
					algorithm = BT_8821A_1ANT_COEX_ALGO_PANEDR_A2DP;
				}
			}
		}
	} else if (num_of_diff_profile == 3) {
		if (bt_link_info->sco_exist) {
			if (bt_link_info->hid_exist &&
			    bt_link_info->a2dp_exist) {
632 633
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], BT Profile = SCO + HID + A2DP ==> HID\n");
634 635
				algorithm = BT_8821A_1ANT_COEX_ALGO_HID;
			} else if (bt_link_info->hid_exist &&
636
				   bt_link_info->pan_exist) {
637
				if (bt_hs_on) {
638 639 640
					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
						 DBG_LOUD,
						 "[BTCoex], BT Profile = SCO + HID + PAN(HS)\n");
641 642
					algorithm = BT_8821A_1ANT_COEX_ALGO_HID_A2DP;
				} else {
643 644 645
					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
						 DBG_LOUD,
						 "[BTCoex], BT Profile = SCO + HID + PAN(EDR)\n");
646 647 648
					algorithm = BT_8821A_1ANT_COEX_ALGO_PANEDR_HID;
				}
			} else if (bt_link_info->pan_exist &&
649
				   bt_link_info->a2dp_exist) {
650
				if (bt_hs_on) {
651 652 653
					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
						 DBG_LOUD,
						 "[BTCoex], BT Profile = SCO + A2DP + PAN(HS)\n");
654 655
					algorithm = BT_8821A_1ANT_COEX_ALGO_SCO;
				} else {
656 657 658
					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
						 DBG_LOUD,
						 "[BTCoex], BT Profile = SCO + A2DP + PAN(EDR) ==> HID\n");
659 660 661 662 663 664 665 666
					algorithm = BT_8821A_1ANT_COEX_ALGO_PANEDR_HID;
				}
			}
		} else {
			if (bt_link_info->hid_exist &&
			    bt_link_info->pan_exist &&
			    bt_link_info->a2dp_exist) {
				if (bt_hs_on) {
667 668 669
					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
						 DBG_LOUD,
						 "[BTCoex], BT Profile = HID + A2DP + PAN(HS)\n");
670 671
					algorithm = BT_8821A_1ANT_COEX_ALGO_HID_A2DP;
				} else {
672 673 674
					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
						 DBG_LOUD,
						 "[BTCoex], BT Profile = HID + A2DP + PAN(EDR)\n");
675 676 677 678 679 680 681 682 683 684
					algorithm = BT_8821A_1ANT_COEX_ALGO_HID_A2DP_PANEDR;
				}
			}
		}
	} else if (num_of_diff_profile >= 3) {
		if (bt_link_info->sco_exist) {
			if (bt_link_info->hid_exist &&
			    bt_link_info->pan_exist &&
			    bt_link_info->a2dp_exist) {
				if (bt_hs_on) {
685 686 687
					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
						 DBG_LOUD,
						 "[BTCoex], Error!!! BT Profile = SCO + HID + A2DP + PAN(HS)\n");
688 689

				} else {
690 691 692
					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
						 DBG_LOUD,
						 "[BTCoex], BT Profile = SCO + HID + A2DP + PAN(EDR)==>PAN(EDR)+HID\n");
693 694 695 696 697 698 699 700
					algorithm = BT_8821A_1ANT_COEX_ALGO_PANEDR_HID;
				}
			}
		}
	}
	return algorithm;
}

701 702
static void btc8821a1ant_set_sw_penalty_tx_rate(struct btc_coexist *btcoexist,
						bool low_penalty_ra)
703
{
704
	struct rtl_priv *rtlpriv = btcoexist->adapter;
705 706 707 708 709 710
	u8 h2c_parameter[6] = {0};

	h2c_parameter[0] = 0x6;	/* opCode, 0x6= Retry_Penalty*/

	if (low_penalty_ra) {
		h2c_parameter[1] |= BIT0;
711
		/* normal rate except MCS7/6/5, OFDM54/48/36 */
712
		h2c_parameter[2] = 0x00;
713 714 715
		h2c_parameter[3] = 0xf7; /* MCS7 or OFDM54 */
		h2c_parameter[4] = 0xf8; /* MCS6 or OFDM48 */
		h2c_parameter[5] = 0xf9; /* MCS5 or OFDM36 */
716 717
	}

718 719 720
	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
		 "[BTCoex], set WiFi Low-Penalty Retry: %s",
		 (low_penalty_ra ? "ON!!" : "OFF!!"));
721 722 723 724

	btcoexist->btc_fill_h2c(btcoexist, 0x69, 6, h2c_parameter);
}

725 726
static void btc8821a1ant_low_penalty_ra(struct btc_coexist *btcoexist,
					bool force_exec, bool low_penalty_ra)
727 728 729 730 731 732 733
{
	coex_dm->cur_low_penalty_ra = low_penalty_ra;

	if (!force_exec) {
		if (coex_dm->pre_low_penalty_ra == coex_dm->cur_low_penalty_ra)
			return;
	}
734 735
	btc8821a1ant_set_sw_penalty_tx_rate(btcoexist,
					    coex_dm->cur_low_penalty_ra);
736 737 738 739

	coex_dm->pre_low_penalty_ra = coex_dm->cur_low_penalty_ra;
}

740 741 742
static void btc8821a1ant_set_coex_table(struct btc_coexist *btcoexist,
					u32 val0x6c0, u32 val0x6c4,
					u32 val0x6c8, u8 val0x6cc)
743
{
744 745 746 747
	struct rtl_priv *rtlpriv = btcoexist->adapter;

	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
		 "[BTCoex], set coex table, set 0x6c0 = 0x%x\n", val0x6c0);
748 749
	btcoexist->btc_write_4byte(btcoexist, 0x6c0, val0x6c0);

750 751
	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
		 "[BTCoex], set coex table, set 0x6c4 = 0x%x\n", val0x6c4);
752 753
	btcoexist->btc_write_4byte(btcoexist, 0x6c4, val0x6c4);

754 755
	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
		 "[BTCoex], set coex table, set 0x6c8 = 0x%x\n", val0x6c8);
756 757
	btcoexist->btc_write_4byte(btcoexist, 0x6c8, val0x6c8);

758 759
	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
		 "[BTCoex], set coex table, set 0x6cc = 0x%x\n", val0x6cc);
760 761 762
	btcoexist->btc_write_1byte(btcoexist, 0x6cc, val0x6cc);
}

763 764 765
static void btc8821a1ant_coex_table(struct btc_coexist *btcoexist,
				    bool force_exec, u32 val0x6c0, u32 val0x6c4,
				    u32 val0x6c8, u8 val0x6cc)
766
{
767 768 769 770
	struct rtl_priv *rtlpriv = btcoexist->adapter;

	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
		 "[BTCoex], %s write Coex Table 0x6c0 = 0x%x, 0x6c4 = 0x%x, 0x6c8 = 0x%x, 0x6cc = 0x%x\n",
771 772
		    (force_exec ? "force to" : ""), val0x6c0, val0x6c4,
		    val0x6c8, val0x6cc);
773 774 775 776 777 778 779 780 781 782 783 784
	coex_dm->cur_val_0x6c0 = val0x6c0;
	coex_dm->cur_val_0x6c4 = val0x6c4;
	coex_dm->cur_val_0x6c8 = val0x6c8;
	coex_dm->cur_val_0x6cc = val0x6cc;

	if (!force_exec) {
		if ((coex_dm->pre_val_0x6c0 == coex_dm->cur_val_0x6c0) &&
		    (coex_dm->pre_val_0x6c4 == coex_dm->cur_val_0x6c4) &&
		    (coex_dm->pre_val_0x6c8 == coex_dm->cur_val_0x6c8) &&
		    (coex_dm->pre_val_0x6cc == coex_dm->cur_val_0x6cc))
			return;
	}
785 786
	btc8821a1ant_set_coex_table(btcoexist, val0x6c0, val0x6c4,
				    val0x6c8, val0x6cc);
787 788 789 790 791 792 793

	coex_dm->pre_val_0x6c0 = coex_dm->cur_val_0x6c0;
	coex_dm->pre_val_0x6c4 = coex_dm->cur_val_0x6c4;
	coex_dm->pre_val_0x6c8 = coex_dm->cur_val_0x6c8;
	coex_dm->pre_val_0x6cc = coex_dm->cur_val_0x6cc;
}

794 795
static void btc8821a1ant_coex_table_with_type(struct btc_coexist *btcoexist,
					      bool force_exec, u8 type)
796 797 798
{
	switch (type) {
	case 0:
799 800
		btc8821a1ant_coex_table(btcoexist, force_exec, 0x55555555,
					0x55555555, 0xffffff, 0x3);
801 802
		break;
	case 1:
803 804 805
		btc8821a1ant_coex_table(btcoexist, force_exec, 0x55555555,
					0x5a5a5a5a, 0xffffff, 0x3);
		break;
806
	case 2:
807 808
		btc8821a1ant_coex_table(btcoexist, force_exec, 0x5a5a5a5a,
					0x5a5a5a5a, 0xffffff, 0x3);
809 810
		break;
	case 3:
811
		btc8821a1ant_coex_table(btcoexist, force_exec, 0x5a5a5a5a,
812
					0xaaaaaaaa, 0xffffff, 0x3);
813 814
		break;
	case 4:
815 816
		btc8821a1ant_coex_table(btcoexist, force_exec, 0x55555555,
					0x5a5a5a5a, 0xffffff, 0x3);
817 818
		break;
	case 5:
819 820
		btc8821a1ant_coex_table(btcoexist, force_exec, 0x5a5a5a5a,
					0xaaaa5a5a, 0xffffff, 0x3);
821 822
		break;
	case 6:
823 824
		btc8821a1ant_coex_table(btcoexist, force_exec, 0x55555555,
					0xaaaa5a5a, 0xffffff, 0x3);
825 826
		break;
	case 7:
827 828
		btc8821a1ant_coex_table(btcoexist, force_exec, 0xaaaaaaaa,
					0xaaaaaaaa, 0xffffff, 0x3);
829 830 831 832 833 834 835 836 837
		break;
	default:
		break;
	}
}

static void btc8821a1ant_set_fw_ignore_wlan_act(struct btc_coexist *btcoexist,
						bool enable)
{
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 845 846
	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
		 "[BTCoex], set FW for BT Ignore Wlan_Act, FW write 0x63 = 0x%x\n",
		 h2c_parameter[0]);
847 848 849 850

	btcoexist->btc_fill_h2c(btcoexist, 0x63, 1, h2c_parameter);
}

851 852
static void btc8821a1ant_ignore_wlan_act(struct btc_coexist *btcoexist,
					 bool force_exec, bool enable)
853
{
854 855 856 857 858
	struct rtl_priv *rtlpriv = btcoexist->adapter;

	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
		 "[BTCoex], %s turn Ignore WlanAct %s\n",
		 (force_exec ? "force to" : ""), (enable ? "ON" : "OFF"));
859 860 861
	coex_dm->cur_ignore_wlan_act = enable;

	if (!force_exec) {
862 863 864 865
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], pre_ignore_wlan_act = %d, cur_ignore_wlan_act = %d!!\n",
			 coex_dm->pre_ignore_wlan_act,
			 coex_dm->cur_ignore_wlan_act);
866 867 868 869 870 871 872 873 874 875

		if (coex_dm->pre_ignore_wlan_act ==
		    coex_dm->cur_ignore_wlan_act)
			return;
	}
	btc8821a1ant_set_fw_ignore_wlan_act(btcoexist, enable);

	coex_dm->pre_ignore_wlan_act = coex_dm->cur_ignore_wlan_act;
}

876 877
static void btc8821a1ant_set_fw_ps_tdma(struct btc_coexist *btcoexist, u8 byte1,
					u8 byte2, u8 byte3, u8 byte4, u8 byte5)
878
{
879
	struct rtl_priv *rtlpriv = btcoexist->adapter;
880
	u8 h2c_parameter[5] = {0};
881 882
	u8 real_byte1 = byte1, real_byte5 = byte5;
	bool ap_enable = false;
883

884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899
	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE,
			   &ap_enable);

	if (ap_enable) {
		if (byte1 & BIT4 && !(byte1 & BIT5)) {
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "[BTCoex], FW for 1Ant AP mode\n");
			real_byte1 &= ~BIT4;
			real_byte1 |= BIT5;

			real_byte5 |= BIT5;
			real_byte5 &= ~BIT6;
		}
	}

	h2c_parameter[0] = real_byte1;
900 901 902
	h2c_parameter[1] = byte2;
	h2c_parameter[2] = byte3;
	h2c_parameter[3] = byte4;
903
	h2c_parameter[4] = real_byte5;
904

905
	coex_dm->ps_tdma_para[0] = real_byte1;
906 907 908
	coex_dm->ps_tdma_para[1] = byte2;
	coex_dm->ps_tdma_para[2] = byte3;
	coex_dm->ps_tdma_para[3] = byte4;
909
	coex_dm->ps_tdma_para[4] = real_byte5;
910

911 912 913 914 915 916 917
	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
		 "[BTCoex], PS-TDMA H2C cmd =0x%x%08x\n",
		 h2c_parameter[0],
		 h2c_parameter[1] << 24 |
		 h2c_parameter[2] << 16 |
		 h2c_parameter[3] << 8 |
		 h2c_parameter[4]);
918 919 920
	btcoexist->btc_fill_h2c(btcoexist, 0x60, 5, h2c_parameter);
}

921 922
static void btc8821a1ant_set_lps_rpwm(struct btc_coexist *btcoexist,
				      u8 lps_val, u8 rpwm_val)
923
{
924 925
	u8 lps = lps_val;
	u8 rpwm = rpwm_val;
926 927 928 929 930

	btcoexist->btc_set(btcoexist, BTC_SET_U1_LPS_VAL, &lps);
	btcoexist->btc_set(btcoexist, BTC_SET_U1_RPWM_VAL, &rpwm);
}

931 932
static void btc8821a1ant_lps_rpwm(struct btc_coexist *btcoexist,
				  bool force_exec, u8 lps_val, u8 rpwm_val)
933
{
934 935 936 937 938
	struct rtl_priv *rtlpriv = btcoexist->adapter;

	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
		 "[BTCoex], %s set lps/rpwm = 0x%x/0x%x\n",
		 (force_exec ? "force to" : ""), lps_val, rpwm_val);
939 940 941 942
	coex_dm->cur_lps = lps_val;
	coex_dm->cur_rpwm = rpwm_val;

	if (!force_exec) {
943 944 945
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], LPS-RxBeaconMode = 0x%x, LPS-RPWM = 0x%x!!\n",
			 coex_dm->cur_lps, coex_dm->cur_rpwm);
946 947 948

		if ((coex_dm->pre_lps == coex_dm->cur_lps) &&
		    (coex_dm->pre_rpwm == coex_dm->cur_rpwm)) {
949 950 951
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "[BTCoex], LPS-RPWM_Last = 0x%x, LPS-RPWM_Now = 0x%x!!\n",
				 coex_dm->pre_rpwm, coex_dm->cur_rpwm);
952 953 954 955

			return;
		}
	}
956
	btc8821a1ant_set_lps_rpwm(btcoexist, lps_val, rpwm_val);
957 958 959 960 961

	coex_dm->pre_lps = coex_dm->cur_lps;
	coex_dm->pre_rpwm = coex_dm->cur_rpwm;
}

962 963
static void btc8821a1ant_sw_mechanism(struct btc_coexist *btcoexist,
				      bool low_penalty_ra)
964
{
965 966 967 968
	struct rtl_priv *rtlpriv = btcoexist->adapter;

	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
		 "[BTCoex], SM[LpRA] = %d\n", low_penalty_ra);
969

970
	btc8821a1ant_low_penalty_ra(btcoexist, NORMAL_EXEC, low_penalty_ra);
971 972
}

973 974 975
static void btc8821a1ant_set_ant_path(struct btc_coexist *btcoexist,
				      u8 ant_pos_type, bool init_hw_cfg,
				      bool wifi_off)
976 977 978 979 980 981
{
	struct btc_board_info *board_info = &btcoexist->board_info;
	u32 u4_tmp = 0;
	u8 h2c_parameter[2] = {0};

	if (init_hw_cfg) {
982
		/* 0x4c[23] = 0, 0x4c[24] = 1  Antenna control by WL/BT */
983 984 985 986 987 988 989 990 991
		u4_tmp = btcoexist->btc_read_4byte(btcoexist, 0x4c);
		u4_tmp &= ~BIT23;
		u4_tmp |= BIT24;
		btcoexist->btc_write_4byte(btcoexist, 0x4c, u4_tmp);

		btcoexist->btc_write_1byte_bitmask(btcoexist, 0x975, 0x3, 0x3);
		btcoexist->btc_write_1byte(btcoexist, 0xcb4, 0x77);

		if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT) {
992 993
			/* tell firmware "antenna inverse"
			 * WRONG firmware antenna control code, need fw to fix
994 995 996 997 998 999
			 */
			h2c_parameter[0] = 1;
			h2c_parameter[1] = 1;
			btcoexist->btc_fill_h2c(btcoexist, 0x65, 2,
						h2c_parameter);
		} else {
1000 1001
			/* tell firmware "no antenna inverse"
			 * WRONG firmware antenna control code, need fw to fix
1002 1003 1004 1005 1006 1007 1008 1009
			 */
			h2c_parameter[0] = 0;
			h2c_parameter[1] = 1;
			btcoexist->btc_fill_h2c(btcoexist, 0x65, 2,
						h2c_parameter);
		}
	} else if (wifi_off) {
		/* 0x4c[24:23] = 00, Set Antenna control
1010
		 * by BT_RFE_CTRL BT Vendor 0xac = 0xf002
1011 1012 1013 1014 1015
		 */
		u4_tmp = btcoexist->btc_read_4byte(btcoexist, 0x4c);
		u4_tmp &= ~BIT23;
		u4_tmp &= ~BIT24;
		btcoexist->btc_write_4byte(btcoexist, 0x4c, u4_tmp);
1016 1017 1018 1019 1020 1021

		/* 0x765 = 0x18 */
		btcoexist->btc_write_1byte_bitmask(btcoexist, 0x765, 0x18, 0x3);
	} else {
		/* 0x765 = 0x0 */
		btcoexist->btc_write_1byte_bitmask(btcoexist, 0x765, 0x18, 0x0);
1022 1023
	}

1024
	/* ext switch setting */
1025 1026
	switch (ant_pos_type) {
	case BTC_ANT_PATH_WIFI:
1027
		btcoexist->btc_write_1byte(btcoexist, 0xcb4, 0x77);
1028 1029 1030 1031 1032 1033 1034 1035
		if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT)
			btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb7,
							   0x30, 0x1);
		else
			btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb7,
							   0x30, 0x2);
		break;
	case BTC_ANT_PATH_BT:
1036
		btcoexist->btc_write_1byte(btcoexist, 0xcb4, 0x77);
1037 1038 1039 1040 1041 1042 1043 1044 1045
		if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT)
			btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb7,
							   0x30, 0x2);
		else
			btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb7,
							   0x30, 0x1);
		break;
	default:
	case BTC_ANT_PATH_PTA:
1046
		btcoexist->btc_write_1byte(btcoexist, 0xcb4, 0x66);
1047 1048 1049 1050 1051 1052 1053 1054 1055 1056
		if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT)
			btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb7,
							   0x30, 0x1);
		else
			btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb7,
							   0x30, 0x2);
		break;
	}
}

1057 1058
static void btc8821a1ant_ps_tdma(struct btc_coexist *btcoexist,
				 bool force_exec, bool turn_on, u8 type)
1059
{
1060
	struct rtl_priv *rtlpriv = btcoexist->adapter;
1061 1062 1063 1064 1065 1066 1067
	u8 rssi_adjust_val = 0;

	coex_dm->cur_ps_tdma_on = turn_on;
	coex_dm->cur_ps_tdma = type;

	if (!force_exec) {
		if (coex_dm->cur_ps_tdma_on) {
1068 1069 1070
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "[BTCoex], ********** TDMA(on, %d) **********\n",
				 coex_dm->cur_ps_tdma);
1071
		} else {
1072 1073 1074
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "[BTCoex], ********** TDMA(off, %d) **********\n",
				 coex_dm->cur_ps_tdma);
1075 1076 1077 1078 1079 1080 1081 1082
		}
		if ((coex_dm->pre_ps_tdma_on == coex_dm->cur_ps_tdma_on) &&
		    (coex_dm->pre_ps_tdma == coex_dm->cur_ps_tdma))
			return;
	}
	if (turn_on) {
		switch (type) {
		default:
1083 1084
			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x1a,
						    0x1a, 0x0, 0x50);
1085 1086
			break;
		case 1:
1087 1088
			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x3a,
						    0x03, 0x10, 0x50);
1089 1090 1091
			rssi_adjust_val = 11;
			break;
		case 2:
1092 1093
			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x2b,
						    0x03, 0x10, 0x50);
1094 1095 1096
			rssi_adjust_val = 14;
			break;
		case 3:
1097 1098
			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x1d,
						    0x1d, 0x0, 0x10);
1099 1100
			break;
		case 4:
1101 1102
			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x93, 0x15,
						    0x3, 0x14, 0x0);
1103 1104 1105
			rssi_adjust_val = 17;
			break;
		case 5:
1106 1107
			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x61, 0x15,
						    0x3, 0x11, 0x10);
1108 1109
			break;
		case 6:
1110 1111
			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x13, 0xa,
						    0x3, 0x0, 0x0);
1112 1113
			break;
		case 7:
1114 1115
			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x13, 0xc,
						    0x5, 0x0, 0x0);
1116 1117
			break;
		case 8:
1118 1119
			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x93, 0x25,
						    0x3, 0x10, 0x0);
1120 1121
			break;
		case 9:
1122 1123
			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x21,
						    0x3, 0x10, 0x50);
1124 1125 1126
			rssi_adjust_val = 18;
			break;
		case 10:
1127 1128
			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x13, 0xa,
						    0xa, 0x0, 0x40);
1129 1130
			break;
		case 11:
1131 1132
			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x14,
						    0x03, 0x10, 0x10);
1133 1134 1135
			rssi_adjust_val = 20;
			break;
		case 12:
1136 1137
			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x0a,
						    0x0a, 0x0, 0x50);
1138 1139
			break;
		case 13:
1140 1141
			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x18,
						    0x18, 0x0, 0x10);
1142 1143
			break;
		case 14:
1144 1145
			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x1e,
						    0x3, 0x10, 0x14);
1146 1147
			break;
		case 15:
1148 1149
			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x13, 0xa,
						    0x3, 0x8, 0x0);
1150 1151
			break;
		case 16:
1152 1153
			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x93, 0x15,
						    0x3, 0x10, 0x0);
1154 1155 1156
			rssi_adjust_val = 18;
			break;
		case 18:
1157 1158
			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x93, 0x25,
						    0x3, 0x10, 0x0);
1159 1160 1161
			rssi_adjust_val = 14;
			break;
		case 20:
1162 1163
			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x61, 0x35,
						    0x03, 0x11, 0x10);
1164 1165
			break;
		case 21:
1166 1167
			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x61, 0x15,
						    0x03, 0x11, 0x10);
1168 1169
			break;
		case 22:
1170 1171
			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x61, 0x25,
						    0x03, 0x11, 0x10);
1172 1173
			break;
		case 23:
1174 1175
			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x25,
						    0x3, 0x31, 0x18);
1176 1177 1178
			rssi_adjust_val = 22;
			break;
		case 24:
1179 1180
			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x15,
						    0x3, 0x31, 0x18);
1181 1182 1183
			rssi_adjust_val = 22;
			break;
		case 25:
1184 1185
			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0xa,
						    0x3, 0x31, 0x18);
1186 1187 1188
			rssi_adjust_val = 22;
			break;
		case 26:
1189 1190
			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0xa,
						    0x3, 0x31, 0x18);
1191 1192 1193
			rssi_adjust_val = 22;
			break;
		case 27:
1194 1195
			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x25,
						    0x3, 0x31, 0x98);
1196 1197 1198
			rssi_adjust_val = 22;
			break;
		case 28:
1199 1200
			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x69, 0x25,
						    0x3, 0x31, 0x0);
1201 1202
			break;
		case 29:
1203 1204
			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0xab, 0x1a,
						    0x1a, 0x1, 0x10);
1205 1206
			break;
		case 30:
1207 1208
			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x51, 0x14,
						    0x3, 0x10, 0x50);
1209 1210
			break;
		case 31:
1211 1212
			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0xd3, 0x1a,
						    0x1a, 0, 0x58);
1213 1214
			break;
		case 32:
1215 1216
			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x61, 0xa,
						    0x3, 0x10, 0x0);
1217 1218
			break;
		case 33:
1219 1220
			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0xa3, 0x25,
						    0x3, 0x30, 0x90);
1221 1222
			break;
		case 34:
1223 1224
			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x53, 0x1a,
						    0x1a, 0x0, 0x10);
1225 1226
			break;
		case 35:
1227 1228
			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x63, 0x1a,
						    0x1a, 0x0, 0x10);
1229 1230
			break;
		case 36:
1231 1232
			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0xd3, 0x12,
						    0x3, 0x14, 0x50);
1233 1234 1235
			break;
		}
	} else {
1236
		/* disable PS tdma */
1237
		switch (type) {
1238 1239 1240 1241 1242 1243
		case 8:
			/* PTA Control */
			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x8, 0x0, 0x0,
						    0x0, 0x0);
			btc8821a1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA,
						  false, false);
1244 1245
			break;
		case 0:
1246 1247 1248 1249 1250 1251
		default:
			/* Software control, Antenna at BT side */
			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x0, 0x0, 0x0,
						    0x0, 0x0);
			btc8821a1ant_set_ant_path(btcoexist, BTC_ANT_PATH_BT,
						  false, false);
1252
			break;
1253 1254 1255 1256 1257 1258
		case 9:
			/* Software control, Antenna at WiFi side */
			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x0, 0x0, 0x0,
						    0x0, 0x0);
			btc8821a1ant_set_ant_path(btcoexist, BTC_ANT_PATH_WIFI,
						  false, false);
1259
			break;
1260 1261 1262 1263 1264 1265
		case 10:
			/* under 5G */
			btc8821a1ant_set_fw_ps_tdma(btcoexist, 0x0, 0x0, 0x0,
						    0x8, 0x0);
			btc8821a1ant_set_ant_path(btcoexist, BTC_ANT_PATH_BT,
						  false, false);
1266 1267 1268 1269 1270 1271 1272
			break;
		}
	}
	rssi_adjust_val = 0;
	btcoexist->btc_set(btcoexist,
		 BTC_SET_U1_RSSI_ADJ_VAL_FOR_1ANT_COEX_TYPE, &rssi_adjust_val);

1273
	/* update pre state */
1274 1275 1276 1277
	coex_dm->pre_ps_tdma_on = coex_dm->cur_ps_tdma_on;
	coex_dm->pre_ps_tdma = coex_dm->cur_ps_tdma;
}

1278
static bool btc8821a1ant_is_common_action(struct btc_coexist *btcoexist)
1279
{
1280
	struct rtl_priv *rtlpriv = btcoexist->adapter;
1281
	bool common = false, wifi_connected = false, wifi_busy = false;
1282 1283 1284 1285 1286 1287 1288 1289

	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
			   &wifi_connected);
	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);

	if (!wifi_connected &&
	    BT_8821A_1ANT_BT_STATUS_NON_CONNECTED_IDLE ==
	    coex_dm->bt_status) {
1290 1291
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], Wifi non connected-idle + BT non connected-idle!!\n");
1292
		btc8821a1ant_sw_mechanism(btcoexist, false);
1293 1294 1295 1296 1297

		common = true;
	} else if (wifi_connected &&
		   (BT_8821A_1ANT_BT_STATUS_NON_CONNECTED_IDLE ==
		    coex_dm->bt_status)) {
1298 1299
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], Wifi connected + BT non connected-idle!!\n");
1300
		btc8821a1ant_sw_mechanism(btcoexist, false);
1301 1302 1303 1304 1305

		common = true;
	} else if (!wifi_connected &&
		   (BT_8821A_1ANT_BT_STATUS_CONNECTED_IDLE ==
		    coex_dm->bt_status)) {
1306 1307
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], Wifi non connected-idle + BT connected-idle!!\n");
1308
		btc8821a1ant_sw_mechanism(btcoexist, false);
1309 1310 1311 1312

		common = true;
	} else if (wifi_connected &&
		   (BT_8821A_1ANT_BT_STATUS_CONNECTED_IDLE ==
1313
		    coex_dm->bt_status)) {
1314 1315
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], Wifi connected + BT connected-idle!!\n");
1316
		btc8821a1ant_sw_mechanism(btcoexist, false);
1317 1318 1319 1320 1321

		common = true;
	} else if (!wifi_connected &&
		   (BT_8821A_1ANT_BT_STATUS_CONNECTED_IDLE !=
		    coex_dm->bt_status)) {
1322 1323
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], Wifi non connected-idle + BT Busy!!\n");
1324
		btc8821a1ant_sw_mechanism(btcoexist, false);
1325 1326 1327 1328

		common = true;
	} else {
		if (wifi_busy) {
1329 1330
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "[BTCoex], Wifi Connected-Busy + BT Busy!!\n");
1331
		} else {
1332 1333
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "[BTCoex], Wifi Connected-Idle + BT Busy!!\n");
1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344
		}

		common = false;
	}

	return common;
}

static void btc8821a1ant_ps_tdma_check_for_pwr_save(struct btc_coexist *btcoex,
						    bool new_ps_state)
{
1345
	u8 lps_mode = 0x0;
1346 1347 1348 1349

	btcoex->btc_get(btcoex, BTC_GET_U1_LPS_MODE, &lps_mode);

	if (lps_mode) {
1350
		/* already under LPS state */
1351
		if (new_ps_state) {
1352
			/* keep state under LPS, do nothing */
1353
		} else {
1354 1355
			/* will leave LPS state, turn off psTdma first */
			btc8821a1ant_ps_tdma(btcoex, NORMAL_EXEC, false, 0);
1356 1357 1358 1359
		}
	} else {
		/* NO PS state*/
		if (new_ps_state) {
1360 1361
			/* will enter LPS state, turn off psTdma first */
			btc8821a1ant_ps_tdma(btcoex, NORMAL_EXEC, false, 0);
1362
		} else {
1363
			/* keep state under NO PS state, do nothing */
1364 1365 1366 1367
		}
	}
}

1368 1369
static void btc8821a1ant_power_save_state(struct btc_coexist *btcoexist,
					  u8 ps_type, u8 lps_val, u8 rpwm_val)
1370 1371 1372 1373 1374
{
	bool low_pwr_disable = false;

	switch (ps_type) {
	case BTC_PS_WIFI_NATIVE:
1375
		/* recover to original 32k low power setting */
1376 1377 1378 1379 1380 1381 1382 1383
		low_pwr_disable = false;
		btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER,
				   &low_pwr_disable);
		btcoexist->btc_set(btcoexist, BTC_SET_ACT_NORMAL_LPS, NULL);
		break;
	case BTC_PS_LPS_ON:
		btc8821a1ant_ps_tdma_check_for_pwr_save(btcoexist,
							true);
1384 1385 1386
		btc8821a1ant_lps_rpwm(btcoexist, NORMAL_EXEC, lps_val,
				      rpwm_val);
		/* when coex force to enter LPS, do not enter 32k low power */
1387 1388 1389
		low_pwr_disable = true;
		btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER,
				   &low_pwr_disable);
1390
		/* power save must executed before psTdma */
1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401
		btcoexist->btc_set(btcoexist, BTC_SET_ACT_ENTER_LPS, NULL);
		break;
	case BTC_PS_LPS_OFF:
		btc8821a1ant_ps_tdma_check_for_pwr_save(btcoexist, false);
		btcoexist->btc_set(btcoexist, BTC_SET_ACT_LEAVE_LPS, NULL);
		break;
	default:
		break;
	}
}

1402
static void btc8821a1ant_coex_under_5g(struct btc_coexist *btcoexist)
1403
{
1404 1405 1406
	btc8821a1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE,
				      0x0, 0x0);
	btc8821a1ant_ignore_wlan_act(btcoexist, NORMAL_EXEC, true);
1407

1408
	btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 10);
1409

1410
	btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
1411

1412
	btc8821a1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0);
1413

1414
	btc8821a1ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 5);
1415 1416
}

1417 1418 1419 1420 1421
/***********************************************
 *
 *	Software Coex Mechanism start
 *
 ***********************************************/
1422

1423 1424
/* SCO only or SCO+PAN(HS) */
static void btc8821a1ant_action_sco(struct btc_coexist *btcoexist)
1425
{
1426
	btc8821a1ant_sw_mechanism(btcoexist, true);
1427 1428
}

1429
static void btc8821a1ant_action_hid(struct btc_coexist *btcoexist)
1430
{
1431
	btc8821a1ant_sw_mechanism(btcoexist, true);
1432 1433
}

1434 1435
/* A2DP only / PAN(EDR) only/ A2DP+PAN(HS) */
static void btc8821a1ant_action_a2dp(struct btc_coexist *btcoexist)
1436
{
1437
	btc8821a1ant_sw_mechanism(btcoexist, false);
1438 1439
}

1440
static void btc8821a1ant_action_a2dp_pan_hs(struct btc_coexist *btcoexist)
1441
{
1442
	btc8821a1ant_sw_mechanism(btcoexist, false);
1443 1444
}

1445
static void btc8821a1ant_action_pan_edr(struct btc_coexist *btcoexist)
1446
{
1447
	btc8821a1ant_sw_mechanism(btcoexist, false);
1448 1449
}

1450 1451
/* PAN(HS) only */
static void btc8821a1ant_action_pan_hs(struct btc_coexist *btcoexist)
1452
{
1453
	btc8821a1ant_sw_mechanism(btcoexist, false);
1454 1455
}

1456 1457
/* PAN(EDR)+A2DP */
static void btc8821a1ant_action_pan_edr_a2dp(struct btc_coexist *btcoexist)
1458
{
1459
	btc8821a1ant_sw_mechanism(btcoexist, false);
1460 1461
}

1462
static void btc8821a1ant_action_pan_edr_hid(struct btc_coexist *btcoexist)
1463
{
1464
	btc8821a1ant_sw_mechanism(btcoexist, true);
1465 1466
}

1467
/* HID+A2DP+PAN(EDR) */
1468 1469
static void btc8821a1ant_action_hid_a2dp_pan_edr(struct btc_coexist *btcoexist)
{
1470
	btc8821a1ant_sw_mechanism(btcoexist, true);
1471 1472
}

1473
static void btc8821a1ant_action_hid_a2dp(struct btc_coexist *btcoexist)
1474
{
1475
	btc8821a1ant_sw_mechanism(btcoexist, true);
1476 1477
}

1478 1479 1480 1481 1482
/***********************************************
 *
 *	Non-Software Coex Mechanism start
 *
 ***********************************************/
1483 1484 1485
static
void btc8821a1ant_action_wifi_multi_port(struct btc_coexist *btcoexist)
{
1486 1487
	struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;

1488
	btc8821a1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0);
1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513
	/* tdma and coex table */
	if (coex_dm->bt_status == BT_8821A_1ANT_BT_STATUS_ACL_BUSY) {
		if (bt_link_info->a2dp_exist) {
			btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14);
			btc8821a1ant_coex_table_with_type(btcoexist,
							  NORMAL_EXEC, 1);
		} else if (bt_link_info->a2dp_exist &&
			   bt_link_info->pan_exist) {
			btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
			btc8821a1ant_coex_table_with_type(btcoexist,
							  NORMAL_EXEC, 4);
		} else {
			btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 20);
			btc8821a1ant_coex_table_with_type(btcoexist,
							  NORMAL_EXEC, 4);
		}
	} else if ((coex_dm->bt_status == BT_8821A_1ANT_BT_STATUS_SCO_BUSY) ||
		   (BT_8821A_1ANT_BT_STATUS_ACL_SCO_BUSY ==
		    coex_dm->bt_status)) {
		btc8821a1ant_act_bt_sco_hid_only_busy(btcoexist,
				BT_8821A_1ANT_WIFI_STATUS_CONNECTED_SCAN);
	} else {
		btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
		btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2);
	}
1514 1515
}

1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537
static
void btc8821a1ant_action_wifi_not_connected_asso_auth(
					struct btc_coexist *btcoexist)
{
	struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;

	btc8821a1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 0x0,
				      0x0);

	/* tdma and coex table */
	if ((bt_link_info->sco_exist) || (bt_link_info->hid_exist)) {
		btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14);
		btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
	} else if ((bt_link_info->a2dp_exist) || (bt_link_info->pan_exist)) {
		btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 20);
		btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4);
	} else {
		btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
		btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2);
	}
}

1538

1539
static void btc8821a1ant_action_hs(struct btc_coexist *btcoexist)
1540
{
1541 1542
	btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 5);
	btc8821a1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 2);
1543 1544
}

1545
static void btc8821a1ant_action_bt_inquiry(struct btc_coexist *btcoexist)
1546 1547 1548
{
	struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
	bool wifi_connected = false;
1549 1550
	bool ap_enable = false;
	bool wifi_busy = false, bt_busy = false;
1551

1552 1553 1554 1555 1556 1557
	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
			   &wifi_connected);
	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE,
			   &ap_enable);
	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
	btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bt_busy);
1558

1559
	if (!wifi_connected && !coex_sta->wifi_is_high_pri_task) {
1560 1561
		btc8821a1ant_power_save_state(btcoexist,
					      BTC_PS_WIFI_NATIVE, 0x0, 0x0);
1562 1563 1564
		btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
		btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
	} else if ((bt_link_info->sco_exist) || (bt_link_info->a2dp_exist) ||
1565
		   (bt_link_info->hid_only)) {
1566 1567 1568 1569
		/* SCO/HID-only busy */
		btc8821a1ant_power_save_state(btcoexist,
					      BTC_PS_WIFI_NATIVE, 0x0, 0x0);
		btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 32);
1570 1571 1572 1573 1574 1575 1576
		btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4);
	} else if ((bt_link_info->a2dp_exist) && (bt_link_info->hid_exist)) {
		/* A2DP+HID busy */
		btc8821a1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE,
					      0x0, 0x0);
		btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14);

1577
		btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
1578 1579 1580 1581 1582 1583
	} else if ((bt_link_info->pan_exist) || (wifi_busy)) {
		btc8821a1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE,
					      0x0, 0x0);
		btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 20);

		btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4);
1584
	} else {
1585 1586 1587 1588
		btc8821a1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE,
					      0x0, 0x0);
		btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
		btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 7);
1589 1590 1591 1592
	}
}

static void btc8821a1ant_act_bt_sco_hid_only_busy(struct btc_coexist *btcoexist,
1593 1594
						  u8 wifi_status)
{
1595 1596
	/* tdma and coex table */
	btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 5);
1597

1598 1599 1600 1601 1602
	if (BT_8821A_1ANT_WIFI_STATUS_NON_CONNECTED_ASSO_AUTH_SCAN ==
	    wifi_status)
		btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
	else
		btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
1603 1604 1605 1606 1607
}

static void btc8821a1ant_act_wifi_con_bt_acl_busy(struct btc_coexist *btcoexist,
						  u8 wifi_status)
{
1608
	u8 bt_rssi_state;
1609 1610 1611

	struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;

1612
	bt_rssi_state = btc8821a1ant_bt_rssi_state(btcoexist, 2, 28, 0);
1613 1614

	if (bt_link_info->hid_only) {
1615
		/* HID */
1616 1617 1618 1619 1620
		btc8821a1ant_act_bt_sco_hid_only_busy(btcoexist,
						      wifi_status);
		coex_dm->auto_tdma_adjust = false;
		return;
	} else if (bt_link_info->a2dp_only) {
1621
		/* A2DP */
1622 1623
		if ((bt_rssi_state != BTC_RSSI_STATE_HIGH) &&
		    (bt_rssi_state != BTC_RSSI_STATE_STAY_HIGH)) {
1624 1625 1626
			/* for low BT RSSI */
			btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC,
					     true, 11);
1627 1628 1629
			coex_dm->auto_tdma_adjust = false;
		}

1630
		btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
1631
	} else if (bt_link_info->hid_exist && bt_link_info->a2dp_exist) {
1632
		/* HID+A2DP */
1633 1634
		if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
		    (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
1635 1636
			btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC,
					     true, 14);
1637 1638 1639
			coex_dm->auto_tdma_adjust = false;
		} else {
			/*for low BT RSSI*/
1640 1641
			btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC,
					     true, 11);
1642 1643 1644
			coex_dm->auto_tdma_adjust = false;
		}

1645
		btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
1646 1647
	} else if ((bt_link_info->pan_only) ||
		(bt_link_info->hid_exist && bt_link_info->pan_exist)) {
1648 1649 1650
		/* PAN(OPP, FTP), HID+PAN(OPP, FTP) */
		btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3);
		btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
1651 1652 1653 1654
		coex_dm->auto_tdma_adjust = false;
	} else if (((bt_link_info->a2dp_exist) && (bt_link_info->pan_exist)) ||
		   (bt_link_info->hid_exist && bt_link_info->a2dp_exist &&
		    bt_link_info->pan_exist)) {
1655 1656 1657
		/* A2DP+PAN(OPP, FTP), HID+A2DP+PAN(OPP, FTP) */
		btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 13);
		btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
1658 1659
		coex_dm->auto_tdma_adjust = false;
	} else {
1660 1661
		btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 11);
		btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
1662 1663 1664 1665
		coex_dm->auto_tdma_adjust = false;
	}
}

1666 1667
static
void btc8821a1ant_action_wifi_not_connected(struct btc_coexist *btcoexist)
1668
{
1669 1670
	/* power save state */
	btc8821a1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0);
1671

1672 1673 1674
	/* tdma and coex table */
	btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
	btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
1675 1676 1677 1678
}

static void btc8821a1ant_act_wifi_not_conn_scan(struct btc_coexist *btcoexist)
{
1679
	struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
1680

1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707
	btc8821a1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0);

	/* tdma and coex table */
	if (coex_dm->bt_status == BT_8821A_1ANT_BT_STATUS_ACL_BUSY) {
		if (bt_link_info->a2dp_exist) {
			btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14);
			btc8821a1ant_coex_table_with_type(btcoexist,
							  NORMAL_EXEC, 1);
		} else if (bt_link_info->a2dp_exist &&
			   bt_link_info->pan_exist) {
			btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 22);
			btc8821a1ant_coex_table_with_type(btcoexist,
							  NORMAL_EXEC, 4);
		} else {
			btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 20);
			btc8821a1ant_coex_table_with_type(btcoexist,
							  NORMAL_EXEC, 4);
		}
	} else if ((coex_dm->bt_status == BT_8821A_1ANT_BT_STATUS_SCO_BUSY) ||
		   (BT_8821A_1ANT_BT_STATUS_ACL_SCO_BUSY ==
		    coex_dm->bt_status)) {
		btc8821a1ant_act_bt_sco_hid_only_busy(btcoexist,
				BT_8821A_1ANT_WIFI_STATUS_CONNECTED_SCAN);
	} else {
		btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
		btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2);
	}
1708 1709
}

1710 1711 1712
static
void btc8821a1ant_action_wifi_connected_scan(struct btc_coexist *btcoexist)
{
1713 1714
	struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;

1715 1716 1717
	/* power save state */
	btc8821a1ant_power_save_state(btcoexist,
				      BTC_PS_WIFI_NATIVE, 0x0, 0x0);
1718

1719
	/* tdma and coex table */
1720 1721
	if (BT_8821A_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) {
		if (bt_link_info->a2dp_exist && bt_link_info->pan_exist) {
1722 1723 1724
			btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 22);
			btc8821a1ant_coex_table_with_type(btcoexist,
							  NORMAL_EXEC, 1);
1725
		} else {
1726 1727
		btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 20);
		btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
1728 1729 1730 1731 1732 1733 1734 1735
	}
	} else if ((BT_8821A_1ANT_BT_STATUS_SCO_BUSY ==
		    coex_dm->bt_status) ||
		   (BT_8821A_1ANT_BT_STATUS_ACL_SCO_BUSY ==
		    coex_dm->bt_status)) {
		btc8821a1ant_act_bt_sco_hid_only_busy(btcoexist,
			BT_8821A_1ANT_WIFI_STATUS_CONNECTED_SCAN);
	} else {
1736 1737
		btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 20);
		btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
1738 1739 1740 1741 1742 1743
	}
}

static void btc8821a1ant_act_wifi_conn_sp_pkt(struct btc_coexist *btcoexist)
{
	struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
1744
	bool hs_connecting = false;
1745 1746 1747

	btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_CONNECTING, &hs_connecting);

1748 1749
	btc8821a1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE,
				      0x0, 0x0);
1750

1751 1752
	/* tdma and coex table */
	if (coex_dm->bt_status == BT_8821A_1ANT_BT_STATUS_ACL_BUSY) {
1753
		if (bt_link_info->a2dp_exist && bt_link_info->pan_exist) {
1754 1755 1756 1757
			btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC,
					     true, 22);
			btc8821a1ant_coex_table_with_type(btcoexist,
							  NORMAL_EXEC, 1);
1758
		} else {
1759 1760 1761 1762
			btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC,
					     true, 20);
			btc8821a1ant_coex_table_with_type(btcoexist,
							  NORMAL_EXEC, 1);
1763 1764
		}
	} else {
1765 1766
		btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 20);
		btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 1);
1767 1768 1769
	}
}

1770
static void btc8821a1ant_action_wifi_connected(struct btc_coexist *btcoexist)
1771
{
1772
	struct rtl_priv *rtlpriv = btcoexist->adapter;
1773 1774 1775
	bool wifi_busy = false;
	bool scan = false, link = false, roam = false;
	bool under_4way = false;
1776

1777 1778
	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
		 "[BTCoex], CoexForWifiConnect()===>\n");
1779

1780 1781
	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS,
			   &under_4way);
1782 1783
	if (under_4way) {
		btc8821a1ant_act_wifi_conn_sp_pkt(btcoexist);
1784 1785
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], CoexForWifiConnect(), return for wifi is under 4way<===\n");
1786 1787 1788 1789 1790 1791 1792
		return;
	}

	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan);
	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link);
	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam);
	if (scan || link || roam) {
1793
		btc8821a1ant_action_wifi_connected_scan(btcoexist);
1794 1795
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], CoexForWifiConnect(), return for wifi is under scan<===\n");
1796 1797 1798 1799 1800 1801
		return;
	}

	/* power save state*/
	if (BT_8821A_1ANT_BT_STATUS_ACL_BUSY ==
			coex_dm->bt_status && !btcoexist->bt_link_info.hid_only)
1802 1803
		btc8821a1ant_power_save_state(btcoexist,
					      BTC_PS_LPS_ON, 0x50, 0x4);
1804
	else
1805 1806 1807
		btc8821a1ant_power_save_state(btcoexist,
					      BTC_PS_WIFI_NATIVE,
					      0x0, 0x0);
1808

1809
	/* tdma and coex table */
1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821
	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
	if (!wifi_busy) {
		if (BT_8821A_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) {
			btc8821a1ant_act_wifi_con_bt_acl_busy(btcoexist,
				BT_8821A_1ANT_WIFI_STATUS_CONNECTED_IDLE);
		} else if ((BT_8821A_1ANT_BT_STATUS_SCO_BUSY ==
			    coex_dm->bt_status) ||
			   (BT_8821A_1ANT_BT_STATUS_ACL_SCO_BUSY ==
			    coex_dm->bt_status)) {
			btc8821a1ant_act_bt_sco_hid_only_busy(btcoexist,
				BT_8821A_1ANT_WIFI_STATUS_CONNECTED_IDLE);
		} else {
1822 1823 1824 1825
			btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC,
					     true, 5);
			btc8821a1ant_coex_table_with_type(btcoexist,
							  NORMAL_EXEC, 2);
1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837
		}
	} else {
		if (BT_8821A_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) {
			btc8821a1ant_act_wifi_con_bt_acl_busy(btcoexist,
				BT_8821A_1ANT_WIFI_STATUS_CONNECTED_BUSY);
		} else if ((BT_8821A_1ANT_BT_STATUS_SCO_BUSY ==
			    coex_dm->bt_status) ||
			   (BT_8821A_1ANT_BT_STATUS_ACL_SCO_BUSY ==
			    coex_dm->bt_status)) {
			btc8821a1ant_act_bt_sco_hid_only_busy(btcoexist,
				BT_8821A_1ANT_WIFI_STATUS_CONNECTED_BUSY);
		} else {
1838 1839 1840
			btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 5);
			btc8821a1ant_coex_table_with_type(btcoexist,
							  NORMAL_EXEC, 2);
1841 1842 1843 1844 1845 1846
		}
	}
}

static void btc8821a1ant_run_sw_coex_mech(struct btc_coexist *btcoexist)
{
1847
	struct rtl_priv *rtlpriv = btcoexist->adapter;
1848
	u8 algorithm = 0;
1849

1850
	algorithm = btc8821a1ant_action_algorithm(btcoexist);
1851 1852
	coex_dm->cur_algorithm = algorithm;

1853
	if (!btc8821a1ant_is_common_action(btcoexist)) {
1854 1855
		switch (coex_dm->cur_algorithm) {
		case BT_8821A_1ANT_COEX_ALGO_SCO:
1856 1857
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "[BTCoex], Action algorithm = SCO\n");
1858
			btc8821a1ant_action_sco(btcoexist);
1859 1860
			break;
		case BT_8821A_1ANT_COEX_ALGO_HID:
1861 1862
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "[BTCoex], Action algorithm = HID\n");
1863
			btc8821a1ant_action_hid(btcoexist);
1864 1865
			break;
		case BT_8821A_1ANT_COEX_ALGO_A2DP:
1866 1867
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "[BTCoex], Action algorithm = A2DP\n");
1868
			btc8821a1ant_action_a2dp(btcoexist);
1869 1870
			break;
		case BT_8821A_1ANT_COEX_ALGO_A2DP_PANHS:
1871 1872
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "[BTCoex], Action algorithm = A2DP+PAN(HS)\n");
1873
			btc8821a1ant_action_a2dp_pan_hs(btcoexist);
1874 1875
			break;
		case BT_8821A_1ANT_COEX_ALGO_PANEDR:
1876 1877
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "[BTCoex], Action algorithm = PAN(EDR)\n");
1878
			btc8821a1ant_action_pan_edr(btcoexist);
1879 1880
			break;
		case BT_8821A_1ANT_COEX_ALGO_PANHS:
1881 1882
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "[BTCoex], Action algorithm = HS mode\n");
1883
			btc8821a1ant_action_pan_hs(btcoexist);
1884 1885
			break;
		case BT_8821A_1ANT_COEX_ALGO_PANEDR_A2DP:
1886 1887
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "[BTCoex], Action algorithm = PAN+A2DP\n");
1888
			btc8821a1ant_action_pan_edr_a2dp(btcoexist);
1889 1890
			break;
		case BT_8821A_1ANT_COEX_ALGO_PANEDR_HID:
1891 1892
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "[BTCoex], Action algorithm = PAN(EDR)+HID\n");
1893
			btc8821a1ant_action_pan_edr_hid(btcoexist);
1894 1895
			break;
		case BT_8821A_1ANT_COEX_ALGO_HID_A2DP_PANEDR:
1896 1897
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "[BTCoex], Action algorithm = HID+A2DP+PAN\n");
1898 1899 1900
			btc8821a1ant_action_hid_a2dp_pan_edr(btcoexist);
			break;
		case BT_8821A_1ANT_COEX_ALGO_HID_A2DP:
1901 1902
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "[BTCoex], Action algorithm = HID+A2DP\n");
1903
			btc8821a1ant_action_hid_a2dp(btcoexist);
1904 1905
			break;
		default:
1906 1907
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "[BTCoex], Action algorithm = coexist All Off!!\n");
1908
			/*btc8821a1ant_coex_all_off(btcoexist);*/
1909 1910 1911 1912 1913 1914
			break;
		}
		coex_dm->pre_algorithm = coex_dm->cur_algorithm;
	}
}

1915
static void btc8821a1ant_run_coexist_mechanism(struct btc_coexist *btcoexist)
1916
{
1917
	struct rtl_priv *rtlpriv = btcoexist->adapter;
1918
	struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
1919 1920 1921 1922 1923
	bool wifi_connected = false, bt_hs_on = false;
	bool increase_scan_dev_num = false;
	bool bt_ctrl_agg_buf_size = false;
	u8 agg_buf_size = 5;
	u8 wifi_rssi_state = BTC_RSSI_STATE_HIGH;
1924 1925
	u32 wifi_link_status = 0;
	u32 num_of_wifi_link = 0;
1926
	bool wifi_under_5g = false;
1927

1928 1929
	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
		 "[BTCoex], RunCoexistMechanism()===>\n");
1930 1931

	if (btcoexist->manual_control) {
1932 1933
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], RunCoexistMechanism(), return for Manual CTRL <===\n");
1934 1935 1936 1937
		return;
	}

	if (btcoexist->stop_coex_dm) {
1938 1939
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], RunCoexistMechanism(), return for Stop Coex DM <===\n");
1940 1941 1942 1943
		return;
	}

	if (coex_sta->under_ips) {
1944 1945
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], wifi is under IPS !!!\n");
1946 1947 1948 1949 1950
		return;
	}

	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
	if (wifi_under_5g) {
1951 1952
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], RunCoexistMechanism(), return for 5G <===\n");
1953
		btc8821a1ant_coex_under_5g(btcoexist);
1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964
		return;
	}

	if ((BT_8821A_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) ||
	    (BT_8821A_1ANT_BT_STATUS_SCO_BUSY == coex_dm->bt_status) ||
	    (BT_8821A_1ANT_BT_STATUS_ACL_SCO_BUSY == coex_dm->bt_status))
		increase_scan_dev_num = true;

	btcoexist->btc_set(btcoexist, BTC_SET_BL_INC_SCAN_DEV_NUM,
			   &increase_scan_dev_num);

1965 1966
	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
			   &wifi_connected);
1967

1968 1969 1970 1971 1972 1973 1974 1975 1976 1977 1978 1979
	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS,
			   &wifi_link_status);
	num_of_wifi_link = wifi_link_status >> 16;
	if ((num_of_wifi_link >= 2) ||
	    (wifi_link_status & WIFI_P2P_GO_CONNECTED)) {
		btc8821a1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0);
		btc8821a1ant_limited_rx(btcoexist, NORMAL_EXEC, false,
					bt_ctrl_agg_buf_size, agg_buf_size);
		btc8821a1ant_action_wifi_multi_port(btcoexist);
		return;
	}

1980
	if (!bt_link_info->sco_exist && !bt_link_info->hid_exist) {
1981
		btc8821a1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0);
1982 1983 1984
	} else {
		if (wifi_connected) {
			wifi_rssi_state =
1985 1986 1987 1988 1989 1990 1991 1992 1993 1994 1995 1996
				btc8821a1ant_wifi_rssi_state(btcoexist, 1, 2,
							     30, 0);
			if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
			    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
				btc8821a1ant_limited_tx(btcoexist,
							NORMAL_EXEC, 1, 1,
							1, 1);
			} else {
				btc8821a1ant_limited_tx(btcoexist,
							NORMAL_EXEC, 1, 1,
							1, 1);
			}
1997
		} else {
1998 1999
			btc8821a1ant_limited_tx(btcoexist, NORMAL_EXEC,
						0, 0, 0, 0);
2000 2001 2002 2003 2004 2005 2006 2007 2008 2009 2010 2011 2012
		}
	}

	if (bt_link_info->sco_exist) {
		bt_ctrl_agg_buf_size = true;
		agg_buf_size = 0x3;
	} else if (bt_link_info->hid_exist) {
		bt_ctrl_agg_buf_size = true;
		agg_buf_size = 0x5;
	} else if (bt_link_info->a2dp_exist || bt_link_info->pan_exist) {
		bt_ctrl_agg_buf_size = true;
		agg_buf_size = 0x8;
	}
2013 2014
	btc8821a1ant_limited_rx(btcoexist, NORMAL_EXEC, false,
				bt_ctrl_agg_buf_size, agg_buf_size);
2015 2016 2017 2018 2019

	btc8821a1ant_run_sw_coex_mech(btcoexist);

	btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
	if (coex_sta->c2h_bt_inquiry_page) {
2020
		btc8821a1ant_action_bt_inquiry(btcoexist);
2021 2022
		return;
	} else if (bt_hs_on) {
2023
		btc8821a1ant_action_hs(btcoexist);
2024 2025 2026 2027
		return;
	}

	if (!wifi_connected) {
2028
		bool scan = false, link = false, roam = false;
2029

2030 2031
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], wifi is non connected-idle !!!\n");
2032 2033 2034 2035 2036

		btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan);
		btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link);
		btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam);

2037 2038 2039 2040 2041 2042 2043
		if (scan || link || roam) {
			if (scan)
				btc8821a1ant_act_wifi_not_conn_scan(btcoexist);
			else
				btc8821a1ant_action_wifi_not_connected_asso_auth(
					btcoexist);
		} else {
2044
			btc8821a1ant_action_wifi_not_connected(btcoexist);
2045
		}
2046
	} else {
2047 2048
		/* wifi LPS/Busy */
		btc8821a1ant_action_wifi_connected(btcoexist);
2049 2050 2051
	}
}

2052
static void btc8821a1ant_init_coex_dm(struct btc_coexist *btcoexist)
2053
{
2054 2055 2056 2057
	/* force to reset coex mechanism
	 * sw all off
	 */
	btc8821a1ant_sw_mechanism(btcoexist, false);
2058

2059 2060
	btc8821a1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 8);
	btc8821a1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 0);
2061 2062
}

2063
static void btc8821a1ant_init_hw_config(struct btc_coexist *btcoexist,
2064
					bool back_up, bool wifi_only)
2065
{
2066
	struct rtl_priv *rtlpriv = btcoexist->adapter;
2067 2068
	u8 u1_tmp = 0;
	bool wifi_under_5g = false;
2069

2070 2071
	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
		 "[BTCoex], 1Ant Init HW Config!!\n");
2072

2073 2074 2075
	if (wifi_only)
		return;

2076 2077 2078 2079 2080 2081
	if (back_up) {
		coex_dm->backup_arfr_cnt1 = btcoexist->btc_read_4byte(btcoexist,
								      0x430);
		coex_dm->backup_arfr_cnt2 = btcoexist->btc_read_4byte(btcoexist,
								      0x434);
		coex_dm->backup_retry_limit =
2082
			btcoexist->btc_read_2byte(btcoexist, 0x42a);
2083
		coex_dm->backup_ampdu_max_time =
2084
			btcoexist->btc_read_1byte(btcoexist, 0x456);
2085 2086
	}

2087
	/* 0x790[5:0] = 0x5 */
2088 2089 2090 2091 2092 2093 2094
	u1_tmp = btcoexist->btc_read_1byte(btcoexist, 0x790);
	u1_tmp &= 0xc0;
	u1_tmp |= 0x5;
	btcoexist->btc_write_1byte(btcoexist, 0x790, u1_tmp);

	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);

2095
	/* Antenna config */
2096
	if (wifi_under_5g)
2097 2098
		btc8821a1ant_set_ant_path(btcoexist, BTC_ANT_PATH_BT,
					  true, false);
2099
	else
2100 2101 2102 2103 2104 2105 2106 2107
		btc8821a1ant_set_ant_path(btcoexist, BTC_ANT_PATH_PTA,
					  true, false);
	/* PTA parameter */
	btc8821a1ant_coex_table_with_type(btcoexist, FORCE_EXEC, 0);

	/* Enable counter statistics
	 * 0x76e[3] =1, WLAN_Act control by PTA
	 */
2108 2109 2110 2111 2112
	btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc);
	btcoexist->btc_write_1byte(btcoexist, 0x778, 0x3);
	btcoexist->btc_write_1byte_bitmask(btcoexist, 0x40, 0x20, 0x1);
}

2113 2114 2115
/**************************************************************
 * extern function start with ex_btc8821a1ant_
 **************************************************************/
2116
void ex_btc8821a1ant_init_hwconfig(struct btc_coexist *btcoexist, bool wifionly)
2117
{
2118
	btc8821a1ant_init_hw_config(btcoexist, true, wifionly);
2119
	btcoexist->auto_report_1ant = true;
2120 2121
}

2122
void ex_btc8821a1ant_init_coex_dm(struct btc_coexist *btcoexist)
2123
{
2124 2125 2126 2127
	struct rtl_priv *rtlpriv = btcoexist->adapter;

	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
		 "[BTCoex], Coex Mechanism Init!!\n");
2128 2129 2130

	btcoexist->stop_coex_dm = false;

2131
	btc8821a1ant_init_coex_dm(btcoexist);
2132

2133
	btc8821a1ant_query_bt_info(btcoexist);
2134 2135
}

2136
void ex_btc8821a1ant_display_coex_info(struct btc_coexist *btcoexist)
2137 2138 2139 2140
{
	struct btc_board_info *board_info = &btcoexist->board_info;
	struct btc_stack_info *stack_info = &btcoexist->stack_info;
	struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
2141
	struct rtl_priv *rtlpriv = btcoexist->adapter;
2142 2143 2144 2145 2146 2147 2148 2149 2150 2151
	u8 u1_tmp[4], i, bt_info_ext, ps_tdma_case = 0;
	u16 u2_tmp[4];
	u32 u4_tmp[4];
	bool roam = false, scan = false, link = false, wifi_under_5g = false;
	bool bt_hs_on = false, wifi_busy = false;
	long wifi_rssi = 0, bt_hs_rssi = 0;
	u32 wifi_bw, wifi_traffic_dir;
	u8 wifi_dot11_chnl, wifi_hs_chnl;
	u32 fw_ver = 0, bt_patch_ver = 0;

2152
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2153
		 "\r\n ============[BT Coexist info]============");
2154 2155

	if (btcoexist->manual_control) {
2156
		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2157
			 "\r\n ============[Under Manual Control]============");
2158
		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2159
			 "\r\n ==========================================");
2160 2161
	}
	if (btcoexist->stop_coex_dm) {
2162
		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2163
			 "\r\n ============[Coex is STOPPED]============");
2164
		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2165
			 "\r\n ==========================================");
2166 2167 2168
	}

	if (!board_info->bt_exist) {
2169
		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n BT not exists !!!");
2170 2171 2172
		return;
	}

2173
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2174 2175 2176 2177 2178
		 "\r\n %-35s = %d/ %d/ %d",
		 "Ant PG Num/ Ant Mech/ Ant Pos:",
		 board_info->pg_ant_num,
		 board_info->btdm_ant_num,
		 board_info->btdm_ant_pos);
2179

2180
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2181 2182 2183
		 "\r\n %-35s = %s / %d", "BT stack/ hci ext ver",
		 ((stack_info->profile_notified) ? "Yes" : "No"),
		 stack_info->hci_version);
2184 2185 2186 2187

	btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER,
			   &bt_patch_ver);
	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver);
2188
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2189 2190 2191 2192 2193 2194
		 "\r\n %-35s = %d_%x/ 0x%x/ 0x%x(%d)",
		 "CoexVer/ FwVer/ PatchVer",
		 glcoex_ver_date_8821a_1ant,
		 glcoex_ver_8821a_1ant,
		 fw_ver, bt_patch_ver,
		 bt_patch_ver);
2195 2196 2197 2198 2199 2200 2201

	btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION,
			   &bt_hs_on);
	btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_DOT11_CHNL,
			   &wifi_dot11_chnl);
	btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_HS_CHNL,
			   &wifi_hs_chnl);
2202
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2203 2204 2205
		 "\r\n %-35s = %d / %d(%d)",
		 "Dot11 channel / HsChnl(HsMode)",
		 wifi_dot11_chnl, wifi_hs_chnl, bt_hs_on);
2206

2207
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2208 2209 2210
		 "\r\n %-35s = %3ph ",
		 "H2C Wifi inform bt chnl Info",
		 coex_dm->wifi_chnl_info);
2211 2212 2213

	btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi);
	btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi);
2214
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2215 2216
		 "\r\n %-35s = %d/ %d", "Wifi rssi/ HS rssi",
		 (int)wifi_rssi, (int)bt_hs_rssi);
2217 2218 2219 2220

	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan);
	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link);
	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam);
2221
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2222 2223
		 "\r\n %-35s = %d/ %d/ %d ", "Wifi link/ roam/ scan",
		 link, roam, scan);
2224 2225 2226 2227 2228 2229 2230 2231 2232

	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G,
			   &wifi_under_5g);
	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW,
			   &wifi_bw);
	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY,
			   &wifi_busy);
	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION,
			   &wifi_traffic_dir);
2233
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2234 2235 2236 2237 2238 2239 2240
		 "\r\n %-35s = %s / %s/ %s ", "Wifi status",
		 (wifi_under_5g ? "5G" : "2.4G"),
		 ((wifi_bw == BTC_WIFI_BW_LEGACY) ? "Legacy" :
		 (((wifi_bw == BTC_WIFI_BW_HT40) ? "HT40" : "HT20"))),
		 ((!wifi_busy) ? "idle" :
		 ((wifi_traffic_dir == BTC_WIFI_TRAFFIC_TX) ?
		 "uplink" : "downlink")));
2241
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2242
		   "\r\n %-35s = [%s/ %d/ %d] ", "BT [status/ rssi/ retryCnt]",
2243
		   ((coex_sta->bt_disabled) ? ("disabled") :
2244 2245 2246 2247 2248 2249 2250 2251 2252
		   ((coex_sta->c2h_bt_inquiry_page) ? ("inquiry/page scan") :
		   ((BT_8821A_1ANT_BT_STATUS_NON_CONNECTED_IDLE ==
		     coex_dm->bt_status) ?
		   "non-connected idle" :
		   ((BT_8821A_1ANT_BT_STATUS_CONNECTED_IDLE ==
		     coex_dm->bt_status) ?
		   "connected-idle" : "busy")))),
		   coex_sta->bt_rssi, coex_sta->bt_retry_cnt);

2253
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2254 2255 2256 2257 2258
		 "\r\n %-35s = %d / %d / %d / %d", "SCO/HID/PAN/A2DP",
		 bt_link_info->sco_exist,
		 bt_link_info->hid_exist,
		 bt_link_info->pan_exist,
		 bt_link_info->a2dp_exist);
2259 2260 2261
	btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_BT_LINK_INFO);

	bt_info_ext = coex_sta->bt_info_ext;
2262
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2263 2264 2265 2266
		 "\r\n %-35s = %s",
		 "BT Info A2DP rate",
		 (bt_info_ext & BIT0) ?
		 "Basic rate" : "EDR rate");
2267 2268 2269

	for (i = 0; i < BT_INFO_SRC_8821A_1ANT_MAX; i++) {
		if (coex_sta->bt_info_c2h_cnt[i]) {
2270
			RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2271 2272 2273 2274
				 "\r\n %-35s = %7ph(%d)",
				 glbt_info_src_8821a_1ant[i],
				 coex_sta->bt_info_c2h[i],
				 coex_sta->bt_info_c2h_cnt[i]);
2275 2276
		}
	}
2277
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2278 2279 2280
		 "\r\n %-35s = %s/%s, (0x%x/0x%x)",
		 "PS state, IPS/LPS, (lps/rpwm)",
		 ((coex_sta->under_ips ? "IPS ON" : "IPS OFF")),
2281
		 ((coex_sta->under_lps ? "LPS ON" : "LPS OFF")),
2282 2283
		 btcoexist->bt_info.lps_val,
		 btcoexist->bt_info.rpwm_val);
2284 2285 2286 2287
	btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_FW_PWR_MODE_CMD);

	if (!btcoexist->manual_control) {
		/* Sw mechanism*/
2288
		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2289 2290
			 "\r\n %-35s",
			 "============[Sw mechanism]============");
2291

2292
		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2293 2294
			 "\r\n %-35s = %d", "SM[LowPenaltyRA]",
			 coex_dm->cur_low_penalty_ra);
2295

2296
		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2297 2298 2299 2300 2301
			 "\r\n %-35s = %s/ %s/ %d ",
			 "DelBA/ BtCtrlAgg/ AggSize",
			 (btcoexist->bt_info.reject_agg_pkt ? "Yes" : "No"),
			 (btcoexist->bt_info.bt_ctrl_buf_size ? "Yes" : "No"),
			 btcoexist->bt_info.agg_buf_size);
2302
		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2303 2304
			 "\r\n %-35s = 0x%x ", "Rate Mask",
			 btcoexist->bt_info.ra_mask);
2305

2306
		/* Fw mechanism */
2307
		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s",
2308
			 "============[Fw mechanism]============");
2309 2310

		ps_tdma_case = coex_dm->cur_ps_tdma;
2311
		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2312 2313 2314 2315 2316
			 "\r\n %-35s = %5ph case-%d (auto:%d)",
			 "PS TDMA",
			 coex_dm->ps_tdma_para,
			 ps_tdma_case,
			 coex_dm->auto_tdma_adjust);
2317

2318
		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2319 2320
			 "\r\n %-35s = 0x%x ",
			 "Latest error condition(should be 0)",
2321 2322
			   coex_dm->error_condition);

2323
		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2324 2325
			 "\r\n %-35s = %d ", "IgnWlanAct",
			 coex_dm->cur_ignore_wlan_act);
2326 2327
	}

2328
	/* Hw setting */
2329
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2330
		 "\r\n %-35s", "============[Hw setting]============");
2331

2332
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2333 2334 2335 2336 2337 2338
		 "\r\n %-35s = 0x%x/0x%x/0x%x/0x%x",
		 "backup ARFR1/ARFR2/RL/AMaxTime",
		 coex_dm->backup_arfr_cnt1,
		 coex_dm->backup_arfr_cnt2,
		 coex_dm->backup_retry_limit,
		 coex_dm->backup_ampdu_max_time);
2339 2340 2341 2342 2343

	u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x430);
	u4_tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x434);
	u2_tmp[0] = btcoexist->btc_read_2byte(btcoexist, 0x42a);
	u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x456);
2344
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2345 2346 2347
		 "\r\n %-35s = 0x%x/0x%x/0x%x/0x%x",
		 "0x430/0x434/0x42a/0x456",
		 u4_tmp[0], u4_tmp[1], u2_tmp[0], u1_tmp[0]);
2348 2349 2350

	u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x778);
	u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xc58);
2351
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2352 2353
		 "\r\n %-35s = 0x%x/ 0x%x", "0x778/ 0xc58[29:25]",
		 u1_tmp[0], (u4_tmp[0] & 0x3e000000) >> 25);
2354 2355

	u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x8db);
2356
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2357 2358
		 "\r\n %-35s = 0x%x", "0x8db[6:5]",
		 ((u1_tmp[0] & 0x60) >> 5));
2359 2360 2361

	u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x975);
	u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xcb4);
2362
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2363 2364 2365 2366 2367
		 "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
		 "0xcb4[29:28]/0xcb4[7:0]/0x974[9:8]",
		 (u4_tmp[0] & 0x30000000) >> 28,
		  u4_tmp[0] & 0xff,
		  u1_tmp[0] & 0x3);
2368 2369 2370 2371

	u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x40);
	u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x4c);
	u1_tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x64);
2372
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2373 2374 2375
		 "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
		 "0x40/0x4c[24:23]/0x64[0]",
		 u1_tmp[0], ((u4_tmp[0] & 0x01800000) >> 23), u1_tmp[1] & 0x1);
2376 2377 2378

	u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x550);
	u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x522);
2379
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2380 2381
		 "\r\n %-35s = 0x%x/ 0x%x", "0x550(bcn ctrl)/0x522",
		 u4_tmp[0], u1_tmp[0]);
2382 2383

	u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xc50);
2384
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2385 2386
		 "\r\n %-35s = 0x%x", "0xc50(dig)",
		 u4_tmp[0] & 0xff);
2387 2388 2389 2390

	u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xf48);
	u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0xa5d);
	u1_tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0xa5c);
2391
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2392 2393
		 "\r\n %-35s = 0x%x/ 0x%x", "OFDM-FA/ CCK-FA",
		 u4_tmp[0], (u1_tmp[0] << 8) + u1_tmp[1]);
2394 2395 2396 2397 2398

	u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x6c0);
	u4_tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x6c4);
	u4_tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x6c8);
	u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x6cc);
2399
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2400 2401
		 "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x",
		 "0x6c0/0x6c4/0x6c8/0x6cc(coexTable)",
2402 2403
		   u4_tmp[0], u4_tmp[1], u4_tmp[2], u1_tmp[0]);

2404
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2405 2406
		 "\r\n %-35s = %d/ %d", "0x770(high-pri rx/tx)",
		 coex_sta->high_priority_rx, coex_sta->high_priority_tx);
2407
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2408 2409
		 "\r\n %-35s = %d/ %d", "0x774(low-pri rx/tx)",
		 coex_sta->low_priority_rx, coex_sta->low_priority_tx);
2410 2411
	if (btcoexist->auto_report_1ant)
		btc8821a1ant_monitor_bt_ctr(btcoexist);
2412 2413 2414
	btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_COEX_STATISTICS);
}

2415
void ex_btc8821a1ant_ips_notify(struct btc_coexist *btcoexist, u8 type)
2416
{
2417
	struct rtl_priv *rtlpriv = btcoexist->adapter;
2418
	bool wifi_under_5g = false;
2419

2420 2421
	if (btcoexist->manual_control || btcoexist->stop_coex_dm)
		return;
2422 2423 2424 2425 2426 2427 2428
	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
	if (wifi_under_5g) {
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], RunCoexistMechanism(), return for 5G <===\n");
		btc8821a1ant_coex_under_5g(btcoexist);
		return;
	}
2429 2430

	if (BTC_IPS_ENTER == type) {
2431 2432
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], IPS ENTER notify\n");
2433
		coex_sta->under_ips = true;
2434 2435 2436 2437 2438 2439
		btc8821a1ant_set_ant_path(btcoexist,
					  BTC_ANT_PATH_BT, false, true);
		/* set PTA control */
		btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 8);
		btc8821a1ant_coex_table_with_type(btcoexist,
						  NORMAL_EXEC, 0);
2440
	} else if (BTC_IPS_LEAVE == type) {
2441 2442
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], IPS LEAVE notify\n");
2443 2444
		coex_sta->under_ips = false;

2445
		btc8821a1ant_run_coexist_mechanism(btcoexist);
2446 2447 2448
	}
}

2449
void ex_btc8821a1ant_lps_notify(struct btc_coexist *btcoexist, u8 type)
2450
{
2451 2452
	struct rtl_priv *rtlpriv = btcoexist->adapter;

2453 2454 2455 2456
	if (btcoexist->manual_control || btcoexist->stop_coex_dm)
		return;

	if (BTC_LPS_ENABLE == type) {
2457 2458
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], LPS ENABLE notify\n");
2459
		coex_sta->under_lps = true;
2460
	} else if (BTC_LPS_DISABLE == type) {
2461 2462
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], LPS DISABLE notify\n");
2463
		coex_sta->under_lps = false;
2464 2465 2466
	}
}

2467
void ex_btc8821a1ant_scan_notify(struct btc_coexist *btcoexist, u8 type)
2468
{
2469
	struct rtl_priv *rtlpriv = btcoexist->adapter;
2470
	bool wifi_connected = false, bt_hs_on = false;
2471
	bool bt_ctrl_agg_buf_size = false;
2472
	bool wifi_under_5g = false;
2473 2474 2475
	u32 wifi_link_status = 0;
	u32 num_of_wifi_link = 0;
	u8 agg_buf_size = 5;
2476

2477 2478
	if (btcoexist->manual_control || btcoexist->stop_coex_dm)
		return;
2479 2480 2481 2482 2483 2484 2485
	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
	if (wifi_under_5g) {
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], RunCoexistMechanism(), return for 5G <===\n");
		btc8821a1ant_coex_under_5g(btcoexist);
		return;
	}
2486 2487

	if (coex_sta->bt_disabled)
2488 2489 2490 2491 2492 2493 2494
		return;

	btcoexist->btc_get(btcoexist,
		 BTC_GET_BL_HS_OPERATION, &bt_hs_on);
	btcoexist->btc_get(btcoexist,
		 BTC_GET_BL_WIFI_CONNECTED, &wifi_connected);

2495
	btc8821a1ant_query_bt_info(btcoexist);
2496

2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507
	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS,
			   &wifi_link_status);
	num_of_wifi_link = wifi_link_status >> 16;
	if (num_of_wifi_link >= 2) {
		btc8821a1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0);
		btc8821a1ant_limited_rx(btcoexist, NORMAL_EXEC, false,
					bt_ctrl_agg_buf_size, agg_buf_size);
		btc8821a1ant_action_wifi_multi_port(btcoexist);
		return;
	}

2508
	if (coex_sta->c2h_bt_inquiry_page) {
2509
		btc8821a1ant_action_bt_inquiry(btcoexist);
2510 2511
		return;
	} else if (bt_hs_on) {
2512
		btc8821a1ant_action_hs(btcoexist);
2513 2514 2515 2516
		return;
	}

	if (BTC_SCAN_START == type) {
2517 2518
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], SCAN START notify\n");
2519
		if (!wifi_connected) {
2520
			/* non-connected scan */
2521 2522
			btc8821a1ant_act_wifi_not_conn_scan(btcoexist);
		} else {
2523 2524
			/* wifi is connected */
			btc8821a1ant_action_wifi_connected_scan(btcoexist);
2525 2526
		}
	} else if (BTC_SCAN_FINISH == type) {
2527 2528
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], SCAN FINISH notify\n");
2529
		if (!wifi_connected) {
2530 2531
			/* non-connected scan */
			btc8821a1ant_action_wifi_not_connected(btcoexist);
2532
		} else {
2533
			btc8821a1ant_action_wifi_connected(btcoexist);
2534 2535 2536 2537
		}
	}
}

2538
void ex_btc8821a1ant_connect_notify(struct btc_coexist *btcoexist, u8 type)
2539
{
2540
	struct rtl_priv *rtlpriv = btcoexist->adapter;
2541
	bool	wifi_connected = false, bt_hs_on = false;
2542 2543 2544
	u32 wifi_link_status = 0;
	u32 num_of_wifi_link = 0;
	bool bt_ctrl_agg_buf_size = false;
2545
	bool wifi_under_5g = false;
2546
	u8 agg_buf_size = 5;
2547

2548 2549
	if (btcoexist->manual_control || btcoexist->stop_coex_dm ||
	    coex_sta->bt_disabled)
2550
		return;
2551 2552 2553 2554 2555 2556 2557
	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
	if (wifi_under_5g) {
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], RunCoexistMechanism(), return for 5G <===\n");
		btc8821a1ant_coex_under_5g(btcoexist);
		return;
	}
2558

2559 2560 2561 2562 2563 2564 2565 2566 2567 2568 2569
	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS,
			   &wifi_link_status);
	num_of_wifi_link = wifi_link_status >> 16;
	if (num_of_wifi_link >= 2) {
		btc8821a1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0);
		btc8821a1ant_limited_rx(btcoexist, NORMAL_EXEC, false,
					bt_ctrl_agg_buf_size, agg_buf_size);
		btc8821a1ant_action_wifi_multi_port(btcoexist);
		return;
	}

2570 2571
	btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
	if (coex_sta->c2h_bt_inquiry_page) {
2572
		btc8821a1ant_action_bt_inquiry(btcoexist);
2573 2574
		return;
	} else if (bt_hs_on) {
2575
		btc8821a1ant_action_hs(btcoexist);
2576 2577 2578 2579
		return;
	}

	if (BTC_ASSOCIATE_START == type) {
2580 2581
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], CONNECT START notify\n");
2582 2583
		btc8821a1ant_act_wifi_not_conn_scan(btcoexist);
	} else if (BTC_ASSOCIATE_FINISH == type) {
2584 2585
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], CONNECT FINISH notify\n");
2586 2587 2588 2589

		btcoexist->btc_get(btcoexist,
			 BTC_GET_BL_WIFI_CONNECTED, &wifi_connected);
		if (!wifi_connected) {
2590 2591
			/* non-connected scan */
			btc8821a1ant_action_wifi_not_connected(btcoexist);
2592
		} else {
2593
			btc8821a1ant_action_wifi_connected(btcoexist);
2594 2595 2596 2597
		}
	}
}

2598 2599
void ex_btc8821a1ant_media_status_notify(struct btc_coexist *btcoexist,
					 u8 type)
2600
{
2601
	struct rtl_priv *rtlpriv = btcoexist->adapter;
2602 2603 2604
	u8 h2c_parameter[3] = {0};
	u32 wifi_bw;
	u8 wifi_central_chnl;
2605
	bool wifi_under_5g = false;
2606

2607 2608
	if (btcoexist->manual_control || btcoexist->stop_coex_dm ||
	    coex_sta->bt_disabled)
2609
		return;
2610 2611 2612 2613 2614 2615 2616
	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
	if (wifi_under_5g) {
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], RunCoexistMechanism(), return for 5G <===\n");
		btc8821a1ant_coex_under_5g(btcoexist);
		return;
	}
2617 2618

	if (BTC_MEDIA_CONNECT == type) {
2619 2620
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], MEDIA connect notify\n");
2621
	} else {
2622 2623
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], MEDIA disconnect notify\n");
2624 2625
	}

2626
	/* only 2.4G we need to inform bt the chnl mask */
2627 2628 2629
	btcoexist->btc_get(btcoexist,
			   BTC_GET_U1_WIFI_CENTRAL_CHNL,
			   &wifi_central_chnl);
2630
	if ((type == BTC_MEDIA_CONNECT) &&
2631 2632 2633 2634
	    (wifi_central_chnl <= 14)) {
		h2c_parameter[0] = 0x0;
		h2c_parameter[1] = wifi_central_chnl;
		btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
2635
		if (wifi_bw == BTC_WIFI_BW_HT40)
2636 2637 2638 2639 2640 2641 2642 2643 2644
			h2c_parameter[2] = 0x30;
		else
			h2c_parameter[2] = 0x20;
	}

	coex_dm->wifi_chnl_info[0] = h2c_parameter[0];
	coex_dm->wifi_chnl_info[1] = h2c_parameter[1];
	coex_dm->wifi_chnl_info[2] = h2c_parameter[2];

2645 2646 2647 2648 2649
	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
		 "[BTCoex], FW write 0x66 = 0x%x\n",
		 h2c_parameter[0] << 16 |
		 h2c_parameter[1] << 8 |
		 h2c_parameter[2]);
2650 2651 2652 2653

	btcoexist->btc_fill_h2c(btcoexist, 0x66, 3, h2c_parameter);
}

2654 2655
void ex_btc8821a1ant_special_packet_notify(struct btc_coexist *btcoexist,
					   u8 type)
2656
{
2657
	struct rtl_priv *rtlpriv = btcoexist->adapter;
2658
	bool bt_hs_on = false;
2659
	bool bt_ctrl_agg_buf_size = false;
2660
	bool wifi_under_5g = false;
2661 2662 2663
	u32 wifi_link_status = 0;
	u32 num_of_wifi_link = 0;
	u8 agg_buf_size = 5;
2664

2665 2666
	if (btcoexist->manual_control || btcoexist->stop_coex_dm ||
	    coex_sta->bt_disabled)
2667 2668
		return;

2669 2670 2671 2672 2673 2674 2675 2676
	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
	if (wifi_under_5g) {
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], RunCoexistMechanism(), return for 5G <===\n");
		btc8821a1ant_coex_under_5g(btcoexist);
		return;
	}

2677 2678
	coex_sta->special_pkt_period_cnt = 0;

2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689
	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_LINK_STATUS,
			   &wifi_link_status);
	num_of_wifi_link = wifi_link_status >> 16;
	if (num_of_wifi_link >= 2) {
		btc8821a1ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0);
		btc8821a1ant_limited_rx(btcoexist, NORMAL_EXEC, false,
					bt_ctrl_agg_buf_size, agg_buf_size);
		btc8821a1ant_action_wifi_multi_port(btcoexist);
		return;
	}

2690 2691
	btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
	if (coex_sta->c2h_bt_inquiry_page) {
2692
		btc8821a1ant_action_bt_inquiry(btcoexist);
2693 2694
		return;
	} else if (bt_hs_on) {
2695
		btc8821a1ant_action_hs(btcoexist);
2696 2697 2698 2699 2700
		return;
	}

	if (BTC_PACKET_DHCP == type ||
	    BTC_PACKET_EAPOL == type) {
2701 2702
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], special Packet(%d) notify\n", type);
2703 2704 2705 2706
		btc8821a1ant_act_wifi_conn_sp_pkt(btcoexist);
	}
}

2707 2708
void ex_btc8821a1ant_bt_info_notify(struct btc_coexist *btcoexist,
				    u8 *tmp_buf, u8 length)
2709
{
2710
	struct rtl_priv *rtlpriv = btcoexist->adapter;
2711
	u8 i;
2712
	u8 bt_info = 0;
2713
	u8 rsp_source = 0;
2714 2715 2716 2717 2718 2719 2720 2721 2722
	bool wifi_connected = false;
	bool bt_busy = false;
	bool wifi_under_5g = false;

	coex_sta->c2h_bt_info_req_sent = false;

	btcoexist->btc_get(btcoexist,
		 BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);

2723
	rsp_source = tmp_buf[0] & 0xf;
2724 2725 2726 2727
	if (rsp_source >= BT_INFO_SRC_8821A_1ANT_MAX)
		rsp_source = BT_INFO_SRC_8821A_1ANT_WIFI_FW;
	coex_sta->bt_info_c2h_cnt[rsp_source]++;

2728 2729 2730
	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
		 "[BTCoex], Bt info[%d], length = %d, hex data = [",
		 rsp_source, length);
2731 2732 2733 2734
	for (i = 0; i < length; i++) {
		coex_sta->bt_info_c2h[rsp_source][i] = tmp_buf[i];
		if (i == 1)
			bt_info = tmp_buf[i];
2735
		if (i == length - 1) {
2736 2737
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "0x%02x]\n", tmp_buf[i]);
2738
		} else {
2739 2740
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "0x%02x, ", tmp_buf[i]);
2741 2742 2743 2744 2745 2746 2747 2748 2749 2750 2751 2752 2753
		}
	}

	if (BT_INFO_SRC_8821A_1ANT_WIFI_FW != rsp_source) {
		coex_sta->bt_retry_cnt =	/* [3:0]*/
			coex_sta->bt_info_c2h[rsp_source][2]&0xf;

		coex_sta->bt_rssi =
			coex_sta->bt_info_c2h[rsp_source][3]*2+10;

		coex_sta->bt_info_ext =
			coex_sta->bt_info_c2h[rsp_source][4];

2754 2755 2756
		/* Here we need to resend some wifi info to BT
		 * because bt is reset and lost the info
		 */
2757
		if (coex_sta->bt_info_ext & BIT1) {
2758 2759
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "[BTCoex], BT ext info bit1 check, send wifi BW&Chnl to BT!!\n");
2760
			btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
2761 2762
					   &wifi_connected);
			if (wifi_connected) {
2763
				ex_btc8821a1ant_media_status_notify(btcoexist,
2764 2765
							       BTC_MEDIA_CONNECT);
			} else {
2766
				ex_btc8821a1ant_media_status_notify(btcoexist,
2767 2768 2769 2770 2771 2772 2773
							       BTC_MEDIA_DISCONNECT);
			}
		}

		if ((coex_sta->bt_info_ext & BIT3) && !wifi_under_5g) {
			if (!btcoexist->manual_control &&
			    !btcoexist->stop_coex_dm) {
2774 2775
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], BT ext info bit3 check, set BT NOT to ignore Wlan active!!\n");
2776 2777 2778
				btc8821a1ant_ignore_wlan_act(btcoexist,
							     FORCE_EXEC,
							     false);
2779 2780 2781 2782
			}
		}
	}

2783
	/* check BIT2 first ==> check if bt is under inquiry or page scan */
2784 2785 2786 2787 2788
	if (bt_info & BT_INFO_8821A_1ANT_B_INQ_PAGE)
		coex_sta->c2h_bt_inquiry_page = true;
	else
		coex_sta->c2h_bt_inquiry_page = false;

2789 2790
	/* set link exist status */
	if (!(bt_info & BT_INFO_8821A_1ANT_B_CONNECTION)) {
2791 2792 2793 2794 2795 2796
		coex_sta->bt_link_exist = false;
		coex_sta->pan_exist = false;
		coex_sta->a2dp_exist = false;
		coex_sta->hid_exist = false;
		coex_sta->sco_exist = false;
	} else {
2797
		/* connection exists */
2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816
		coex_sta->bt_link_exist = true;
		if (bt_info & BT_INFO_8821A_1ANT_B_FTP)
			coex_sta->pan_exist = true;
		else
			coex_sta->pan_exist = false;
		if (bt_info & BT_INFO_8821A_1ANT_B_A2DP)
			coex_sta->a2dp_exist = true;
		else
			coex_sta->a2dp_exist = false;
		if (bt_info & BT_INFO_8821A_1ANT_B_HID)
			coex_sta->hid_exist = true;
		else
			coex_sta->hid_exist = false;
		if (bt_info & BT_INFO_8821A_1ANT_B_SCO_ESCO)
			coex_sta->sco_exist = true;
		else
			coex_sta->sco_exist = false;
	}

2817
	btc8821a1ant_update_bt_link_info(btcoexist);
2818

2819 2820 2821 2822 2823 2824
	/* mask profile bit for connect-ilde identification
	 * (for CSR case: A2DP idle --> 0x41)
	 */
	bt_info = bt_info & 0x1f;

	if (!(bt_info & BT_INFO_8821A_1ANT_B_CONNECTION)) {
2825
		coex_dm->bt_status = BT_8821A_1ANT_BT_STATUS_NON_CONNECTED_IDLE;
2826 2827
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], BtInfoNotify(), BT Non-Connected idle!!!\n");
2828
	} else if (bt_info == BT_INFO_8821A_1ANT_B_CONNECTION) {
2829
		/* connection exists but no busy */
2830
		coex_dm->bt_status = BT_8821A_1ANT_BT_STATUS_CONNECTED_IDLE;
2831 2832
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], BtInfoNotify(), BT Connected-idle!!!\n");
2833 2834 2835
	} else if ((bt_info&BT_INFO_8821A_1ANT_B_SCO_ESCO) ||
		(bt_info&BT_INFO_8821A_1ANT_B_SCO_BUSY)) {
		coex_dm->bt_status = BT_8821A_1ANT_BT_STATUS_SCO_BUSY;
2836 2837
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], BtInfoNotify(), BT SCO busy!!!\n");
2838 2839 2840 2841
	} else if (bt_info&BT_INFO_8821A_1ANT_B_ACL_BUSY) {
		if (BT_8821A_1ANT_BT_STATUS_ACL_BUSY != coex_dm->bt_status)
			coex_dm->auto_tdma_adjust = false;
		coex_dm->bt_status = BT_8821A_1ANT_BT_STATUS_ACL_BUSY;
2842 2843
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], BtInfoNotify(), BT ACL busy!!!\n");
2844 2845
	} else {
		coex_dm->bt_status = BT_8821A_1ANT_BT_STATUS_MAX;
2846 2847
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], BtInfoNotify(), BT Non-Defined state!!!\n");
2848 2849 2850 2851 2852 2853 2854 2855 2856 2857 2858
	}

	if ((BT_8821A_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) ||
	    (BT_8821A_1ANT_BT_STATUS_SCO_BUSY == coex_dm->bt_status) ||
	    (BT_8821A_1ANT_BT_STATUS_ACL_SCO_BUSY == coex_dm->bt_status))
		bt_busy = true;
	else
		bt_busy = false;
	btcoexist->btc_set(btcoexist,
			   BTC_SET_BL_BT_TRAFFIC_BUSY, &bt_busy);

2859
	btc8821a1ant_run_coexist_mechanism(btcoexist);
2860 2861
}

2862
void ex_btc8821a1ant_halt_notify(struct btc_coexist *btcoexist)
2863
{
2864
	struct rtl_priv *rtlpriv = btcoexist->adapter;
2865
	bool wifi_under_5g = false;
2866 2867 2868

	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
		 "[BTCoex], Halt notify\n");
2869 2870 2871 2872 2873 2874 2875 2876
	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
	if (wifi_under_5g) {
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], RunCoexistMechanism(), return for 5G <===\n");
		btc8821a1ant_coex_under_5g(btcoexist);
		return;
	}

2877 2878 2879

	btcoexist->stop_coex_dm = true;

2880 2881
	btc8821a1ant_set_ant_path(btcoexist, BTC_ANT_PATH_BT, false, true);
	btc8821a1ant_ignore_wlan_act(btcoexist, FORCE_EXEC, true);
2882

2883 2884
	btc8821a1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0);
	btc8821a1ant_ps_tdma(btcoexist, FORCE_EXEC, false, 0);
2885

2886
	ex_btc8821a1ant_media_status_notify(btcoexist, BTC_MEDIA_DISCONNECT);
2887 2888
}

2889
void ex_btc8821a1ant_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state)
2890
{
2891
	struct rtl_priv *rtlpriv = btcoexist->adapter;
2892 2893 2894 2895 2896 2897 2898 2899 2900
	bool wifi_under_5g = false;

	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
	if (wifi_under_5g) {
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], RunCoexistMechanism(), return for 5G <===\n");
		btc8821a1ant_coex_under_5g(btcoexist);
		return;
	}
2901 2902 2903

	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
		 "[BTCoex], Pnp notify\n");
2904 2905

	if (BTC_WIFI_PNP_SLEEP == pnp_state) {
2906 2907
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], Pnp notify to SLEEP\n");
2908 2909 2910 2911 2912
		/* BT should clear UnderIPS/UnderLPS state to avoid mismatch
		 * state after wakeup.
		 */
		coex_sta->under_ips = false;
		coex_sta->under_lps = false;
2913
		btcoexist->stop_coex_dm = true;
2914 2915
		btc8821a1ant_power_save_state(btcoexist, BTC_PS_WIFI_NATIVE,
					      0x0, 0x0);
2916 2917 2918 2919
		btc8821a1ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0);
		btc8821a1ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2);
		btc8821a1ant_set_ant_path(btcoexist, BTC_ANT_PATH_BT, false,
					  true);
2920
	} else if (BTC_WIFI_PNP_WAKE_UP == pnp_state) {
2921 2922
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], Pnp notify to WAKE UP\n");
2923
		btcoexist->stop_coex_dm = false;
2924
		btc8821a1ant_init_hw_config(btcoexist, false, false);
2925 2926
		btc8821a1ant_init_coex_dm(btcoexist);
		btc8821a1ant_query_bt_info(btcoexist);
2927 2928 2929
	}
}

2930
void ex_btc8821a1ant_periodical(struct btc_coexist *btcoexist)
2931 2932
{
	struct rtl_priv *rtlpriv = btcoexist->adapter;
2933 2934
	static u8 dis_ver_info_cnt;
	u32 fw_ver = 0, bt_patch_ver = 0;
2935 2936 2937
	struct btc_board_info *board_info = &btcoexist->board_info;
	struct btc_stack_info *stack_info = &btcoexist->stack_info;

2938 2939
	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
		 "[BTCoex], ==========================Periodical===========================\n");
2940 2941 2942

	if (dis_ver_info_cnt <= 5) {
		dis_ver_info_cnt += 1;
2943 2944 2945 2946
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], ****************************************************************\n");
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], Ant PG Num/ Ant Mech/ Ant Pos = %d/ %d/ %d\n",
2947 2948 2949
			      board_info->pg_ant_num,
			      board_info->btdm_ant_num,
			      board_info->btdm_ant_pos);
2950 2951
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], BT stack/ hci ext ver = %s / %d\n",
2952 2953
			      stack_info->profile_notified ? "Yes" : "No",
			      stack_info->hci_version);
2954 2955 2956
		btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER,
				   &bt_patch_ver);
		btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver);
2957 2958
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], CoexVer/ FwVer/ PatchVer = %d_%x/ 0x%x/ 0x%x(%d)\n",
2959 2960 2961 2962
			      glcoex_ver_date_8821a_1ant,
			      glcoex_ver_8821a_1ant,
			      fw_ver, bt_patch_ver,
			      bt_patch_ver);
2963 2964
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], ****************************************************************\n");
2965 2966
	}

2967 2968 2969 2970 2971 2972
	if (!btcoexist->auto_report_1ant) {
		btc8821a1ant_query_bt_info(btcoexist);
		btc8821a1ant_monitor_bt_ctr(btcoexist);
	} else {
		coex_sta->special_pkt_period_cnt++;
	}
2973
}