halbtc8821a2ant.c 91.2 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 34
 * Description:
 *
 * This file is for RTL8821A Co-exist mechanism
 *
 * History
 * 2012/08/22 Cosa first check in.
 * 2012/11/14 Cosa Revise for 8821A 2Ant out sourcing.
 *
35
 ************************************************************/
36

37
/************************************************************
38
 * include files
39
 ************************************************************/
40
#include "halbt_precomp.h"
41
/************************************************************
42
 * Global variables, these are static variables
43 44 45 46 47
 ************************************************************/
static struct coex_dm_8821a_2ant glcoex_dm_8821a_2ant;
static struct coex_dm_8821a_2ant *coex_dm = &glcoex_dm_8821a_2ant;
static struct coex_sta_8821a_2ant glcoex_sta_8821a_2ant;
static struct coex_sta_8821a_2ant *coex_sta = &glcoex_sta_8821a_2ant;
48 49 50 51 52 53 54

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

55 56
static u32 glcoex_ver_date_8821a_2ant = 20130618;
static u32 glcoex_ver_8821a_2ant = 0x5050;
57

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

	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)) {
76 77
			if (bt_rssi >=
			    rssi_thresh + BTC_RSSI_COEX_THRESH_TOL_8821A_2ANT) {
78
				bt_rssi_state = BTC_RSSI_STATE_HIGH;
79 80
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], BT Rssi state switch to High\n");
81 82
			} else {
				bt_rssi_state = BTC_RSSI_STATE_STAY_LOW;
83 84
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], BT Rssi state stay at Low\n");
85 86 87 88
			}
		} else {
			if (bt_rssi < rssi_thresh) {
				bt_rssi_state = BTC_RSSI_STATE_LOW;
89 90
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], BT Rssi state switch to Low\n");
91 92
			} else {
				bt_rssi_state = BTC_RSSI_STATE_STAY_HIGH;
93 94
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], BT Rssi state stay at High\n");
95 96 97 98
			}
		}
	} else if (level_num == 3) {
		if (rssi_thresh > rssi_thresh1) {
99 100
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "[BTCoex], BT Rssi thresh error!!\n");
101 102 103 104 105 106
			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 >=
107 108
			    (rssi_thresh +
			     BTC_RSSI_COEX_THRESH_TOL_8821A_2ANT)) {
109
				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 124
			}
		} 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_2ANT)) {
				bt_rssi_state = BTC_RSSI_STATE_HIGH;
125 126
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], BT Rssi state switch to High\n");
127 128
			} else if (bt_rssi < rssi_thresh) {
				bt_rssi_state = BTC_RSSI_STATE_LOW;
129 130
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], BT Rssi state switch to Low\n");
131 132
			} else {
				bt_rssi_state = BTC_RSSI_STATE_STAY_MEDIUM;
133 134
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], BT Rssi state stay at Medium\n");
135 136 137 138
			}
		} else {
			if (bt_rssi < rssi_thresh1) {
				bt_rssi_state = BTC_RSSI_STATE_MEDIUM;
139 140
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], BT Rssi state switch to Medium\n");
141 142
			} else {
				bt_rssi_state = BTC_RSSI_STATE_STAY_HIGH;
143 144
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], BT Rssi state stay at High\n");
145 146 147 148 149 150 151 152 153
			}
		}
	}

	coex_sta->pre_bt_rssi_state = bt_rssi_state;

	return bt_rssi_state;
}

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

	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)) {
			if (wifi_rssi >=
			    (rssi_thresh+BTC_RSSI_COEX_THRESH_TOL_8821A_2ANT)) {
				wifi_rssi_state = BTC_RSSI_STATE_HIGH;
172 173
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], wifi RSSI state switch to High\n");
174 175
			} else {
				wifi_rssi_state = BTC_RSSI_STATE_STAY_LOW;
176 177
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], wifi RSSI state stay at Low\n");
178 179 180 181
			}
		} else {
			if (wifi_rssi < rssi_thresh) {
				wifi_rssi_state = BTC_RSSI_STATE_LOW;
182 183
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], wifi RSSI state switch to Low\n");
184 185
			} else {
				wifi_rssi_state = BTC_RSSI_STATE_STAY_HIGH;
186 187
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], wifi RSSI state stay at High\n");
188 189 190 191
			}
		}
	} else if (level_num == 3) {
		if (rssi_thresh > rssi_thresh1) {
192 193
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "[BTCoex], wifi RSSI thresh error!!\n");
194 195 196 197 198 199 200 201
			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)) {
			if (wifi_rssi >=
202 203
			    (rssi_thresh +
			     BTC_RSSI_COEX_THRESH_TOL_8821A_2ANT)) {
204
				wifi_rssi_state = BTC_RSSI_STATE_MEDIUM;
205 206
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], wifi RSSI state switch to Medium\n");
207 208
			} else {
				wifi_rssi_state = BTC_RSSI_STATE_STAY_LOW;
209 210
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], wifi RSSI state stay at Low\n");
211 212 213 214 215 216 217 218
			}
		} 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)) {
			if (wifi_rssi >= (rssi_thresh1 +
			    BTC_RSSI_COEX_THRESH_TOL_8821A_2ANT)) {
				wifi_rssi_state = BTC_RSSI_STATE_HIGH;
219 220
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], wifi RSSI state switch to High\n");
221 222
			} else if (wifi_rssi < rssi_thresh) {
				wifi_rssi_state = BTC_RSSI_STATE_LOW;
223 224
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], wifi RSSI state switch to Low\n");
225 226
			} else {
				wifi_rssi_state = BTC_RSSI_STATE_STAY_MEDIUM;
227 228
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], wifi RSSI state stay at Medium\n");
229 230 231 232
			}
		} else {
			if (wifi_rssi < rssi_thresh1) {
				wifi_rssi_state = BTC_RSSI_STATE_MEDIUM;
233 234
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], wifi RSSI state switch to Medium\n");
235 236
			} else {
				wifi_rssi_state = BTC_RSSI_STATE_STAY_HIGH;
237 238
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], wifi RSSI state stay at High\n");
239 240 241 242 243 244 245 246
			}
		}
	}
	coex_sta->pre_wifi_rssi_state[index] = wifi_rssi_state;

	return wifi_rssi_state;
}

247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267
static
void btc8821a2ant_limited_rx(struct btc_coexist *btcoexist, bool force_exec,
			     bool rej_ap_agg_pkt, bool bt_ctrl_agg_buf_size,
			     u8 agg_buf_size)
{
	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;

	/* Rx Aggregation related setting */
	btcoexist->btc_set(btcoexist, BTC_SET_BL_TO_REJ_AP_AGG_PKT,
			   &reject_rx_agg);
	/* decide BT control aggregation buf size or not */
	btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_CTRL_AGG_SIZE,
			   &bt_ctrl_rx_agg_size);
	/* aggregation buf size, works when BT control Rx aggregation size */
	btcoexist->btc_set(btcoexist, BTC_SET_U1_AGG_BUF_SIZE, &rx_agg_size);
	/* real update aggregation setting */
	btcoexist->btc_set(btcoexist, BTC_SET_ACT_AGGREGATE_CTRL, NULL);
}

268
static void btc8821a2ant_monitor_bt_ctr(struct btc_coexist *btcoexist)
269
{
270
	struct rtl_priv *rtlpriv = btcoexist->adapter;
271
	struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
272 273
	u32 reg_hp_txrx, reg_lp_txrx, u4tmp;
	u32 reg_hp_tx = 0, reg_hp_rx = 0, reg_lp_tx = 0, reg_lp_rx = 0;
274 275 276 277 278 279

	reg_hp_txrx = 0x770;
	reg_lp_txrx = 0x774;

	u4tmp = btcoexist->btc_read_4byte(btcoexist, reg_hp_txrx);
	reg_hp_tx = u4tmp & MASKLWORD;
280
	reg_hp_rx = (u4tmp & MASKHWORD) >> 16;
281 282 283

	u4tmp = btcoexist->btc_read_4byte(btcoexist, reg_lp_txrx);
	reg_lp_tx = u4tmp & MASKLWORD;
284
	reg_lp_rx = (u4tmp & MASKHWORD) >> 16;
285 286 287 288 289 290

	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;

291 292 293 294 295 296 297
	if ((coex_sta->low_priority_rx >= 950) &&
	    (coex_sta->low_priority_rx >= coex_sta->low_priority_tx) &&
	    (!coex_sta->under_ips))
		bt_link_info->slave_role = true;
	else
		bt_link_info->slave_role = false;

298 299
	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
		 "[BTCoex], High Priority Tx/Rx (reg 0x%x) = 0x%x(%d)/0x%x(%d)\n",
300
		    reg_hp_txrx, reg_hp_tx, reg_hp_tx, reg_hp_rx, reg_hp_rx);
301 302 303
	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
		 "[BTCoex], Low Priority Tx/Rx (reg 0x%x) = 0x%x(%d)/0x%x(%d)\n",
		 reg_lp_txrx, reg_lp_tx, reg_lp_tx, reg_lp_rx, reg_lp_rx);
304 305 306 307 308

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

309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345
static void btc8821a2ant_monitor_wifi_ctr(struct btc_coexist *btcoexist)
{
	if (coex_sta->under_ips) {
		coex_sta->crc_ok_cck = 0;
		coex_sta->crc_ok_11g = 0;
		coex_sta->crc_ok_11n = 0;
		coex_sta->crc_ok_11n_agg = 0;

		coex_sta->crc_err_cck = 0;
		coex_sta->crc_err_11g = 0;
		coex_sta->crc_err_11n = 0;
		coex_sta->crc_err_11n_agg = 0;
	} else {
		coex_sta->crc_ok_cck =
			btcoexist->btc_read_4byte(btcoexist, 0xf88);
		coex_sta->crc_ok_11g =
			btcoexist->btc_read_2byte(btcoexist, 0xf94);
		coex_sta->crc_ok_11n =
			btcoexist->btc_read_2byte(btcoexist, 0xf90);
		coex_sta->crc_ok_11n_agg =
			btcoexist->btc_read_2byte(btcoexist, 0xfb8);

		coex_sta->crc_err_cck =
			btcoexist->btc_read_4byte(btcoexist, 0xf84);
		coex_sta->crc_err_11g =
			btcoexist->btc_read_2byte(btcoexist, 0xf96);
		coex_sta->crc_err_11n =
			btcoexist->btc_read_2byte(btcoexist, 0xf92);
		coex_sta->crc_err_11n_agg =
			btcoexist->btc_read_2byte(btcoexist, 0xfba);
	}

	/* reset counter */
	btcoexist->btc_write_1byte_bitmask(btcoexist, 0xf16, 0x1, 0x1);
	btcoexist->btc_write_1byte_bitmask(btcoexist, 0xf16, 0x1, 0x0);
}

346
static void btc8821a2ant_query_bt_info(struct btc_coexist *btcoexist)
347
{
348 349
	struct rtl_priv *rtlpriv = btcoexist->adapter;
	u8 h2c_parameter[1] = {0};
350 351 352

	coex_sta->c2h_bt_info_req_sent = true;

353
	h2c_parameter[0] |= BIT0; /* trigger */
354

355 356 357
	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
		 "[BTCoex], Query Bt Info, FW write 0x61 = 0x%x\n",
		 h2c_parameter[0]);
358 359 360 361

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

362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409
static void btc8821a2ant_update_bt_link_info(struct btc_coexist *btcoexist)
{
	struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
	bool bt_hs_on = false;

	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;

	/* work around for HS mode. */
	if (bt_hs_on) {
		bt_link_info->pan_exist = true;
		bt_link_info->bt_link_exist = true;
	}

	/* check if Sco only */
	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;

	/* check if A2dp only */
	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;

	/* check if Pan only */
	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;

	/* check if Hid only */
	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;
}

410
static u8 btc8821a2ant_action_algorithm(struct btc_coexist *btcoexist)
411
{
412
	struct rtl_priv *rtlpriv = btcoexist->adapter;
413
	struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
414 415 416 417 418 419
	bool bt_hs_on = false;
	u8 algorithm = BT_8821A_2ANT_COEX_ALGO_UNDEFINED;
	u8 num_of_diff_profile = 0;

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

420
	if (!bt_link_info->bt_link_exist) {
421
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
422
			"[BTCoex], No BT link exists!!!\n");
423 424 425
		return algorithm;
	}

426
	if (bt_link_info->sco_exist)
427
		num_of_diff_profile++;
428
	if (bt_link_info->hid_exist)
429
		num_of_diff_profile++;
430
	if (bt_link_info->pan_exist)
431
		num_of_diff_profile++;
432
	if (bt_link_info->a2dp_exist)
433 434 435
		num_of_diff_profile++;

	if (num_of_diff_profile == 1) {
436
		if (bt_link_info->sco_exist) {
437 438
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "[BTCoex], SCO only\n");
439 440
			algorithm = BT_8821A_2ANT_COEX_ALGO_SCO;
		} else {
441
			if (bt_link_info->hid_exist) {
442 443
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], HID only\n");
444
				algorithm = BT_8821A_2ANT_COEX_ALGO_HID;
445
			} else if (bt_link_info->a2dp_exist) {
446 447
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], A2DP only\n");
448
				algorithm = BT_8821A_2ANT_COEX_ALGO_A2DP;
449
			} else if (bt_link_info->pan_exist) {
450
				if (bt_hs_on) {
451 452 453
					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
						 DBG_LOUD,
						 "[BTCoex], PAN(HS) only\n");
454 455
					algorithm = BT_8821A_2ANT_COEX_ALGO_PANHS;
				} else {
456 457 458
					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
						 DBG_LOUD,
						 "[BTCoex], PAN(EDR) only\n");
459 460 461 462 463
					algorithm = BT_8821A_2ANT_COEX_ALGO_PANEDR;
				}
			}
		}
	} else if (num_of_diff_profile == 2) {
464 465
		if (bt_link_info->sco_exist) {
			if (bt_link_info->hid_exist) {
466 467
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], SCO + HID\n");
468 469
				algorithm = BT_8821A_2ANT_COEX_ALGO_SCO;
			} else if (bt_link_info->a2dp_exist) {
470 471
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], SCO + A2DP ==> SCO\n");
472 473
				algorithm = BT_8821A_2ANT_COEX_ALGO_SCO;
			} else if (bt_link_info->pan_exist) {
474
				if (bt_hs_on) {
475 476 477
					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
						 DBG_LOUD,
						 "[BTCoex], SCO + PAN(HS)\n");
478 479
					algorithm = BT_8821A_2ANT_COEX_ALGO_SCO;
				} else {
480 481 482
					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
						 DBG_LOUD,
						 "[BTCoex], SCO + PAN(EDR)\n");
483
					algorithm = BT_8821A_2ANT_COEX_ALGO_SCO;
484 485 486
				}
			}
		} else {
487 488
			if (bt_link_info->hid_exist &&
			    bt_link_info->a2dp_exist) {
489 490
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], HID + A2DP\n");
491
				algorithm = BT_8821A_2ANT_COEX_ALGO_HID_A2DP;
492 493
			} else if (bt_link_info->hid_exist &&
				bt_link_info->pan_exist) {
494
				if (bt_hs_on) {
495 496 497
					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
						 DBG_LOUD,
						 "[BTCoex], HID + PAN(HS)\n");
498
					algorithm = BT_8821A_2ANT_COEX_ALGO_HID;
499
				} else {
500 501 502
					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
						 DBG_LOUD,
						 "[BTCoex], HID + PAN(EDR)\n");
503 504
					algorithm =
					    BT_8821A_2ANT_COEX_ALGO_PANEDR_HID;
505
				}
506 507
			} else if (bt_link_info->pan_exist &&
				bt_link_info->a2dp_exist) {
508
				if (bt_hs_on) {
509 510 511
					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
						 DBG_LOUD,
						 "[BTCoex], A2DP + PAN(HS)\n");
512 513
					algorithm =
					    BT_8821A_2ANT_COEX_ALGO_A2DP_PANHS;
514
				} else {
515 516 517
					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
						 DBG_LOUD,
						 "[BTCoex], A2DP + PAN(EDR)\n");
518 519
					algorithm =
					    BT_8821A_2ANT_COEX_ALGO_PANEDR_A2DP;
520 521 522 523
				}
			}
		}
	} else if (num_of_diff_profile == 3) {
524 525 526
		if (bt_link_info->sco_exist) {
			if (bt_link_info->hid_exist &&
			    bt_link_info->a2dp_exist) {
527 528
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], SCO + HID + A2DP ==> HID\n");
529 530 531
				algorithm = BT_8821A_2ANT_COEX_ALGO_SCO;
			} else if (bt_link_info->hid_exist &&
				bt_link_info->pan_exist) {
532
				if (bt_hs_on) {
533 534 535
					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
						 DBG_LOUD,
						 "[BTCoex], SCO + HID + PAN(HS)\n");
536
					algorithm = BT_8821A_2ANT_COEX_ALGO_SCO;
537
				} else {
538 539 540
					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
						 DBG_LOUD,
						 "[BTCoex], SCO + HID + PAN(EDR)\n");
541
					algorithm = BT_8821A_2ANT_COEX_ALGO_SCO;
542
				}
543 544
			} else if (bt_link_info->pan_exist &&
				   bt_link_info->a2dp_exist) {
545
				if (bt_hs_on) {
546 547 548
					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
						 DBG_LOUD,
						 "[BTCoex], SCO + A2DP + PAN(HS)\n");
549
					algorithm = BT_8821A_2ANT_COEX_ALGO_SCO;
550
				} else {
551 552 553
					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
						 DBG_LOUD,
						 "[BTCoex], SCO + A2DP + PAN(EDR) ==> HID\n");
554
					algorithm = BT_8821A_2ANT_COEX_ALGO_SCO;
555 556 557
				}
			}
		} else {
558 559 560
			if (bt_link_info->hid_exist &&
			    bt_link_info->pan_exist &&
			    bt_link_info->a2dp_exist) {
561
				if (bt_hs_on) {
562 563 564
					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
						 DBG_LOUD,
						 "[BTCoex], HID + A2DP + PAN(HS)\n");
565 566
					algorithm =
					    BT_8821A_2ANT_COEX_ALGO_HID_A2DP;
567
				} else {
568 569 570
					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
						 DBG_LOUD,
						 "[BTCoex], HID + A2DP + PAN(EDR)\n");
571 572
					algorithm =
					BT_8821A_2ANT_COEX_ALGO_HID_A2DP_PANEDR;
573 574 575 576
				}
			}
		}
	} else if (num_of_diff_profile >= 3) {
577 578 579 580
		if (bt_link_info->sco_exist) {
			if (bt_link_info->hid_exist &&
			    bt_link_info->pan_exist &&
			    bt_link_info->a2dp_exist) {
581
				if (bt_hs_on) {
582 583 584
					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
						 DBG_LOUD,
						 "[BTCoex], Error!!! SCO + HID + A2DP + PAN(HS)\n");
585 586

				} else {
587 588 589
					RT_TRACE(rtlpriv, COMP_BT_COEXIST,
						 DBG_LOUD,
						 "[BTCoex], SCO + HID + A2DP + PAN(EDR)==>PAN(EDR)+HID\n");
590
					algorithm = BT_8821A_2ANT_COEX_ALGO_SCO;
591 592 593 594 595 596 597
				}
			}
		}
	}
	return algorithm;
}

598
static void btc8821a2ant_set_fw_dac_swing_lvl(struct btc_coexist *btcoexist,
599 600
					      u8 dac_swing_lvl)
{
601 602
	struct rtl_priv *rtlpriv = btcoexist->adapter;
	u8 h2c_parameter[1] = {0};
603 604 605 606 607 608

	/* There are several type of dacswing
	 * 0x18/ 0x10/ 0xc/ 0x8/ 0x4/ 0x6
	 */
	h2c_parameter[0] = dac_swing_lvl;

609 610 611 612
	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
		 "[BTCoex], Set Dac Swing Level = 0x%x\n", dac_swing_lvl);
	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
		 "[BTCoex], FW write 0x64 = 0x%x\n", h2c_parameter[0]);
613 614 615 616

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

617
static void btc8821a2ant_set_fw_dec_bt_pwr(struct btc_coexist *btcoexist,
618
					   u8 dec_bt_pwr_lvl)
619
{
620 621
	struct rtl_priv *rtlpriv = btcoexist->adapter;
	u8 h2c_parameter[1] = {0};
622

623
	h2c_parameter[0] = dec_bt_pwr_lvl;
624

625
	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
626 627
		 "[BTCoex], decrease Bt Power Level : %u, FW write 0x62 = 0x%x\n",
		 dec_bt_pwr_lvl, h2c_parameter[0]);
628 629 630 631

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

632
static void btc8821a2ant_dec_bt_pwr(struct btc_coexist *btcoexist,
633
				    bool force_exec, u8 dec_bt_pwr_lvl)
634
{
635 636 637
	struct rtl_priv *rtlpriv = btcoexist->adapter;

	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
638 639 640
		 "[BTCoex], %s Dec BT power level = %u\n",
		    (force_exec ? "force to" : ""), dec_bt_pwr_lvl);
	coex_dm->cur_dec_bt_pwr_lvl = dec_bt_pwr_lvl;
641 642

	if (!force_exec) {
643
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
644 645 646
			 "[BTCoex], pre_dec_bt_pwr_lvl = %d, cur_dec_bt_pwr_lvl = %d\n",
			    coex_dm->pre_dec_bt_pwr_lvl,
			    coex_dm->cur_dec_bt_pwr_lvl);
647

648
		if (coex_dm->pre_dec_bt_pwr_lvl == coex_dm->cur_dec_bt_pwr_lvl)
649 650
			return;
	}
651
	btc8821a2ant_set_fw_dec_bt_pwr(btcoexist, coex_dm->cur_dec_bt_pwr_lvl);
652

653
	coex_dm->pre_dec_bt_pwr_lvl = coex_dm->cur_dec_bt_pwr_lvl;
654 655
}

656 657
static void btc8821a2ant_fw_dac_swing_lvl(struct btc_coexist *btcoexist,
					  bool force_exec, u8 fw_dac_swing_lvl)
658
{
659 660 661 662 663
	struct rtl_priv *rtlpriv = btcoexist->adapter;

	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
		 "[BTCoex], %s set FW Dac Swing level = %d\n",
		 (force_exec ? "force to" : ""), fw_dac_swing_lvl);
664 665 666
	coex_dm->cur_fw_dac_swing_lvl = fw_dac_swing_lvl;

	if (!force_exec) {
667 668 669 670
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], pre_fw_dac_swing_lvl = %d, cur_fw_dac_swing_lvl = %d\n",
			 coex_dm->pre_fw_dac_swing_lvl,
			 coex_dm->cur_fw_dac_swing_lvl);
671 672 673 674 675 676

		if (coex_dm->pre_fw_dac_swing_lvl ==
		    coex_dm->cur_fw_dac_swing_lvl)
			return;
	}

677
	btc8821a2ant_set_fw_dac_swing_lvl(btcoexist,
678 679 680 681 682
					  coex_dm->cur_fw_dac_swing_lvl);

	coex_dm->pre_fw_dac_swing_lvl = coex_dm->cur_fw_dac_swing_lvl;
}

683 684
static void btc8821a2ant_set_sw_penalty_tx_rate_adaptive(
		struct btc_coexist *btcoexist, bool low_penalty_ra)
685
{
686
	struct rtl_priv *rtlpriv = btcoexist->adapter;
687 688 689 690 691 692
	u8 h2c_parameter[6] = {0};

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

	if (low_penalty_ra) {
		h2c_parameter[1] |= BIT0;
693
		/* normal rate except MCS7/6/5, OFDM54/48/36 */
694
		h2c_parameter[2] = 0x00;
695
		/* MCS7 or OFDM54 */
696
		h2c_parameter[3] = 0xf7;
697
		/* MCS6 or OFDM48 */
698
		h2c_parameter[4] = 0xf8;
699
		/* MCS5 or OFDM36 */
700 701 702
		h2c_parameter[5] = 0xf9;
	}

703 704 705
	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
		 "[BTCoex], set WiFi Low-Penalty Retry: %s",
		 (low_penalty_ra ? "ON!!" : "OFF!!"));
706 707 708 709

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

710 711
static void btc8821a2ant_low_penalty_ra(struct btc_coexist *btcoexist,
					bool force_exec, bool low_penalty_ra)
712
{
713 714 715 716 717 718
	struct rtl_priv *rtlpriv = btcoexist->adapter;

	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
		 "[BTCoex], %s turn LowPenaltyRA = %s\n",
		 (force_exec ? "force to" : ""),
		 ((low_penalty_ra) ? "ON" : "OFF"));
719 720 721
	coex_dm->cur_low_penalty_ra = low_penalty_ra;

	if (!force_exec) {
722 723 724
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], pre_low_penalty_ra = %d, cur_low_penalty_ra = %d\n",
			 coex_dm->pre_low_penalty_ra,
725
			 coex_dm->cur_low_penalty_ra);
726 727 728 729

		if (coex_dm->pre_low_penalty_ra == coex_dm->cur_low_penalty_ra)
			return;
	}
730
	btc8821a2ant_set_sw_penalty_tx_rate_adaptive(btcoexist,
731 732 733 734 735
					 coex_dm->cur_low_penalty_ra);

	coex_dm->pre_low_penalty_ra = coex_dm->cur_low_penalty_ra;
}

736 737
static void btc8821a2ant_set_dac_swing_reg(struct btc_coexist *btcoexist,
					   u32 level)
738
{
739
	struct rtl_priv *rtlpriv = btcoexist->adapter;
740 741
	u8 val = (u8)level;

742 743
	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
		 "[BTCoex], Write SwDacSwing = 0x%x\n", level);
744 745 746 747 748 749 750 751
	btcoexist->btc_write_1byte_bitmask(btcoexist, 0xc5b, 0x3e, val);
}

static void btc8821a2ant_set_sw_full_dac_swing(struct btc_coexist *btcoexist,
					       bool sw_dac_swing_on,
					       u32 sw_dac_swing_lvl)
{
	if (sw_dac_swing_on)
752
		btc8821a2ant_set_dac_swing_reg(btcoexist, sw_dac_swing_lvl);
753
	else
754
		btc8821a2ant_set_dac_swing_reg(btcoexist, 0x18);
755 756
}

757 758 759
static void btc8821a2ant_dac_swing(struct btc_coexist *btcoexist,
				   bool force_exec, bool dac_swing_on,
				   u32 dac_swing_lvl)
760
{
761 762 763 764 765 766 767
	struct rtl_priv *rtlpriv = btcoexist->adapter;

	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
		 "[BTCoex], %s turn DacSwing = %s, dac_swing_lvl = 0x%x\n",
		 (force_exec ? "force to" : ""),
		 ((dac_swing_on) ? "ON" : "OFF"),
		 dac_swing_lvl);
768 769 770 771
	coex_dm->cur_dac_swing_on = dac_swing_on;
	coex_dm->cur_dac_swing_lvl = dac_swing_lvl;

	if (!force_exec) {
772 773 774 775 776 777
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], pre_dac_swing_on = %d, pre_dac_swing_lvl = 0x%x, cur_dac_swing_on = %d, cur_dac_swing_lvl = 0x%x\n",
			 coex_dm->pre_dac_swing_on,
			 coex_dm->pre_dac_swing_lvl,
			 coex_dm->cur_dac_swing_on,
			 coex_dm->cur_dac_swing_lvl);
778 779 780 781 782 783 784 785 786 787 788 789 790 791

		if ((coex_dm->pre_dac_swing_on == coex_dm->cur_dac_swing_on) &&
		    (coex_dm->pre_dac_swing_lvl ==
		     coex_dm->cur_dac_swing_lvl))
			return;
	}
	mdelay(30);
	btc8821a2ant_set_sw_full_dac_swing(btcoexist, dac_swing_on,
					   dac_swing_lvl);

	coex_dm->pre_dac_swing_on = coex_dm->cur_dac_swing_on;
	coex_dm->pre_dac_swing_lvl = coex_dm->cur_dac_swing_lvl;
}

792 793 794
static void btc8821a2ant_set_coex_table(struct btc_coexist *btcoexist,
					u32 val0x6c0, u32 val0x6c4,
					u32 val0x6c8, u8 val0x6cc)
795
{
796 797 798 799
	struct rtl_priv *rtlpriv = btcoexist->adapter;

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

802 803
	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
		 "[BTCoex], set coex table, set 0x6c4 = 0x%x\n", val0x6c4);
804 805
	btcoexist->btc_write_4byte(btcoexist, 0x6c4, val0x6c4);

806 807
	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
		 "[BTCoex], set coex table, set 0x6c8 = 0x%x\n", val0x6c8);
808 809
	btcoexist->btc_write_4byte(btcoexist, 0x6c8, val0x6c8);

810 811
	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
		 "[BTCoex], set coex table, set 0x6cc = 0x%x\n", val0x6cc);
812 813 814
	btcoexist->btc_write_1byte(btcoexist, 0x6cc, val0x6cc);
}

815 816 817
static void btc8821a2ant_coex_table(struct btc_coexist *btcoexist,
				    bool force_exec, u32 val0x6c0,
				    u32 val0x6c4, u32 val0x6c8, u8 val0x6cc)
818
{
819 820 821 822 823 824
	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",
		 (force_exec ? "force to" : ""),
		 val0x6c0, val0x6c4, val0x6c8, val0x6cc);
825 826 827 828 829 830
	coex_dm->cur_val0x6c0 = val0x6c0;
	coex_dm->cur_val0x6c4 = val0x6c4;
	coex_dm->cur_val0x6c8 = val0x6c8;
	coex_dm->cur_val0x6cc = val0x6cc;

	if (!force_exec) {
831 832 833 834 835 836 837 838 839 840 841 842
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], pre_val0x6c0 = 0x%x, pre_val0x6c4 = 0x%x, pre_val0x6c8 = 0x%x, pre_val0x6cc = 0x%x !!\n",
			 coex_dm->pre_val0x6c0,
			 coex_dm->pre_val0x6c4,
			 coex_dm->pre_val0x6c8,
			 coex_dm->pre_val0x6cc);
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], cur_val0x6c0 = 0x%x, cur_val0x6c4 = 0x%x, cur_val0x6c8 = 0x%x, cur_val0x6cc = 0x%x !!\n",
			 coex_dm->cur_val0x6c0,
			 coex_dm->cur_val0x6c4,
			 coex_dm->cur_val0x6c8,
			 coex_dm->cur_val0x6cc);
843 844 845 846 847 848 849

		if ((coex_dm->pre_val0x6c0 == coex_dm->cur_val0x6c0) &&
		    (coex_dm->pre_val0x6c4 == coex_dm->cur_val0x6c4) &&
		    (coex_dm->pre_val0x6c8 == coex_dm->cur_val0x6c8) &&
		    (coex_dm->pre_val0x6cc == coex_dm->cur_val0x6cc))
			return;
	}
850 851
	btc8821a2ant_set_coex_table(btcoexist, val0x6c0, val0x6c4, val0x6c8,
				    val0x6cc);
852 853 854 855 856 857 858

	coex_dm->pre_val0x6c0 = coex_dm->cur_val0x6c0;
	coex_dm->pre_val0x6c4 = coex_dm->cur_val0x6c4;
	coex_dm->pre_val0x6c8 = coex_dm->cur_val0x6c8;
	coex_dm->pre_val0x6cc = coex_dm->cur_val0x6cc;
}

859 860
static void btc8821a2ant_set_fw_ignore_wlan_act(struct btc_coexist *btcoex,
						bool enable)
861
{
862
	struct rtl_priv *rtlpriv = btcoex->adapter;
863 864 865
	u8 h2c_parameter[1] = {0};

	if (enable)
866
		h2c_parameter[0] |= BIT0; /* function enable */
867

868 869 870
	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]);
871 872 873 874

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

875 876
static void btc8821a2ant_ignore_wlan_act(struct btc_coexist *btcoexist,
					 bool force_exec, bool enable)
877
{
878 879 880 881 882
	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"));
883 884 885
	coex_dm->cur_ignore_wlan_act = enable;

	if (!force_exec) {
886 887 888 889
		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);
890 891 892 893 894

		if (coex_dm->pre_ignore_wlan_act ==
		    coex_dm->cur_ignore_wlan_act)
			return;
	}
895
	btc8821a2ant_set_fw_ignore_wlan_act(btcoexist, enable);
896 897 898 899

	coex_dm->pre_ignore_wlan_act = coex_dm->cur_ignore_wlan_act;
}

900 901 902
static void btc8821a2ant_set_fw_ps_tdma(struct btc_coexist *btcoexist,
					u8 byte1, u8 byte2, u8 byte3,
					u8 byte4, u8 byte5)
903
{
904
	struct rtl_priv *rtlpriv = btcoexist->adapter;
905 906 907 908 909 910 911 912 913 914 915 916 917 918
	u8 h2c_parameter[5];

	h2c_parameter[0] = byte1;
	h2c_parameter[1] = byte2;
	h2c_parameter[2] = byte3;
	h2c_parameter[3] = byte4;
	h2c_parameter[4] = byte5;

	coex_dm->ps_tdma_para[0] = byte1;
	coex_dm->ps_tdma_para[1] = byte2;
	coex_dm->ps_tdma_para[2] = byte3;
	coex_dm->ps_tdma_para[3] = byte4;
	coex_dm->ps_tdma_para[4] = byte5;

919 920 921 922 923 924 925
	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
		 "[BTCoex], FW write 0x60(5bytes) = 0x%x%08x\n",
		 h2c_parameter[0],
		 h2c_parameter[1] << 24 |
		 h2c_parameter[2] << 16 |
		 h2c_parameter[3] << 8 |
		 h2c_parameter[4]);
926 927 928 929

	btcoexist->btc_fill_h2c(btcoexist, 0x60, 5, h2c_parameter);
}

930 931 932
static void btc8821a2ant_sw_mechanism1(struct btc_coexist *btcoexist,
				       bool shrink_rx_lpf, bool low_penalty_ra,
				       bool limited_dig, bool bt_lna_constrain)
933 934 935 936 937 938 939 940 941 942 943
{
	u32 wifi_bw;

	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);

	if (BTC_WIFI_BW_HT40 != wifi_bw) {
		/*only shrink RF Rx LPF for HT40*/
		if (shrink_rx_lpf)
			shrink_rx_lpf = false;
	}

944
	btc8821a2ant_low_penalty_ra(btcoexist, NORMAL_EXEC, low_penalty_ra);
945 946
}

947 948 949
static void btc8821a2ant_sw_mechanism2(struct btc_coexist *btcoexist,
				       bool agc_table_shift, bool adc_back_off,
				       bool sw_dac_swing, u32 dac_swing_lvl)
950
{
951
	btc8821a2ant_dac_swing(btcoexist, NORMAL_EXEC, sw_dac_swing,
952
			       sw_dac_swing);
953 954
}

955 956 957
static void btc8821a2ant_set_ant_path(struct btc_coexist *btcoexist,
				      u8 ant_pos_type, bool init_hw_cfg,
				      bool wifi_off)
958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973
{
	struct btc_board_info *board_info = &btcoexist->board_info;
	u32 u4tmp = 0;
	u8 h2c_parameter[2] = {0};

	if (init_hw_cfg) {
		/*  0x4c[23] = 0, 0x4c[24] = 1  Antenna control by WL/BT */
		u4tmp = btcoexist->btc_read_4byte(btcoexist, 0x4c);
		u4tmp &= ~BIT23;
		u4tmp |= BIT24;
		btcoexist->btc_write_4byte(btcoexist, 0x4c, u4tmp);

		btcoexist->btc_write_4byte(btcoexist, 0x974, 0x3ff);
		btcoexist->btc_write_1byte(btcoexist, 0xcb4, 0x77);

		if (board_info->btdm_ant_pos == BTC_ANTENNA_AT_MAIN_PORT) {
974 975
			/* tell firmware "antenna inverse"  ==> WRONG firmware
			 * antenna control code ==>need fw to fix
976 977 978 979 980 981
			 */
			h2c_parameter[0] = 1;
			h2c_parameter[1] = 1;
			btcoexist->btc_fill_h2c(btcoexist, 0x65, 2,
						h2c_parameter);
		} else {
982 983
			/* tell firmware "no antenna inverse" ==> WRONG firmware
			 * antenna control code ==>need fw to fix
984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002
			 */
			h2c_parameter[0] = 0;
			h2c_parameter[1] = 1;
			btcoexist->btc_fill_h2c(btcoexist, 0x65, 2,
						h2c_parameter);
		}
	}

	/* ext switch setting */
	switch (ant_pos_type) {
	case BTC_ANT_WIFI_AT_MAIN:
		btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb7, 0x30, 0x1);
		break;
	case BTC_ANT_WIFI_AT_AUX:
		btcoexist->btc_write_1byte_bitmask(btcoexist, 0xcb7, 0x30, 0x2);
		break;
	}
}

1003 1004
static void btc8821a2ant_ps_tdma(struct btc_coexist *btcoexist,
				 bool force_exec, bool turn_on, u8 type)
1005
{
1006 1007 1008 1009 1010 1011
	struct rtl_priv *rtlpriv = btcoexist->adapter;

	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
		 "[BTCoex], %s turn %s PS TDMA, type = %d\n",
		 (force_exec ? "force to" : ""), (turn_on ? "ON" : "OFF"),
		 type);
1012 1013 1014 1015
	coex_dm->cur_ps_tdma_on = turn_on;
	coex_dm->cur_ps_tdma = type;

	if (!force_exec) {
1016 1017 1018 1019 1020 1021
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], pre_ps_tdma_on = %d, cur_ps_tdma_on = %d!!\n",
			 coex_dm->pre_ps_tdma_on, coex_dm->cur_ps_tdma_on);
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], pre_ps_tdma = %d, cur_ps_tdma = %d!!\n",
			 coex_dm->pre_ps_tdma, coex_dm->cur_ps_tdma);
1022 1023 1024 1025 1026 1027 1028 1029 1030

		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) {
		case 1:
		default:
1031 1032
			btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1a,
						    0x1a, 0xe1, 0x90);
1033 1034
			break;
		case 2:
1035 1036
			btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x12,
						    0x12, 0xe1, 0x90);
1037 1038
			break;
		case 3:
1039 1040
			btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1c,
						    0x3, 0xf1, 0x90);
1041 1042
			break;
		case 4:
1043 1044
			btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x10,
						    0x03, 0xf1, 0x90);
1045 1046
			break;
		case 5:
1047 1048
			btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1a,
						    0x1a, 0x60, 0x90);
1049 1050
			break;
		case 6:
1051 1052
			btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x12,
						    0x12, 0x60, 0x90);
1053 1054
			break;
		case 7:
1055 1056
			btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1c,
						    0x3, 0x70, 0x90);
1057 1058
			break;
		case 8:
1059 1060
			btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xa3, 0x10,
						    0x3, 0x70, 0x90);
1061 1062
			break;
		case 9:
1063 1064
			btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1a,
						    0x1a, 0xe1, 0x90);
1065 1066
			break;
		case 10:
1067 1068
			btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x12,
						    0x12, 0xe1, 0x90);
1069 1070
			break;
		case 11:
1071 1072
			btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0xa,
						    0xa, 0xe1, 0x90);
1073 1074
			break;
		case 12:
1075 1076
			btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x5,
						    0x5, 0xe1, 0x90);
1077 1078
			break;
		case 13:
1079 1080
			btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1a,
						    0x1a, 0x60, 0x90);
1081 1082
			break;
		case 14:
1083 1084
			btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3,
						    0x12, 0x12, 0x60, 0x90);
1085 1086
			break;
		case 15:
1087 1088
			btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0xa,
						    0xa, 0x60, 0x90);
1089 1090
			break;
		case 16:
1091 1092
			btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x5,
						    0x5, 0x60, 0x90);
1093 1094
			break;
		case 17:
1095 1096
			btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xa3, 0x2f,
						    0x2f, 0x60, 0x90);
1097 1098
			break;
		case 18:
1099 1100
			btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x5,
						    0x5, 0xe1, 0x90);
1101 1102
			break;
		case 19:
1103 1104
			btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x25,
						    0x25, 0xe1, 0x90);
1105 1106
			break;
		case 20:
1107 1108
			btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x25,
						    0x25, 0x60, 0x90);
1109 1110
			break;
		case 21:
1111 1112
			btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x15,
						    0x03, 0x70, 0x90);
1113 1114
			break;
		case 71:
1115 1116
			btc8821a2ant_set_fw_ps_tdma(btcoexist, 0xe3, 0x1a,
						    0x1a, 0xe1, 0x90);
1117 1118 1119 1120 1121 1122
			break;
		}
	} else {
		/* disable PS tdma */
		switch (type) {
		case 0:
1123 1124
			btc8821a2ant_set_fw_ps_tdma(btcoexist, 0x0, 0x0, 0x0,
						    0x40, 0x0);
1125 1126
			break;
		case 1:
1127 1128
			btc8821a2ant_set_fw_ps_tdma(btcoexist, 0x0, 0x0, 0x0,
						    0x48, 0x0);
1129 1130
			break;
		default:
1131 1132
			btc8821a2ant_set_fw_ps_tdma(btcoexist, 0x0, 0x0, 0x0,
						    0x40, 0x0);
1133 1134 1135 1136 1137 1138 1139 1140 1141
			break;
		}
	}

	/* update pre state */
	coex_dm->pre_ps_tdma_on = coex_dm->cur_ps_tdma_on;
	coex_dm->pre_ps_tdma = coex_dm->cur_ps_tdma;
}

1142
static void btc8821a2ant_coex_all_off(struct btc_coexist *btcoexist)
1143 1144
{
	/* fw all off */
1145 1146
	btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1);
	btc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
1147
	btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0);
1148 1149

	/* sw all off */
1150 1151
	btc8821a2ant_sw_mechanism1(btcoexist, false, false, false, false);
	btc8821a2ant_sw_mechanism2(btcoexist, false, false, false, 0x18);
1152 1153

	/* hw all off */
1154 1155
	btc8821a2ant_coex_table(btcoexist, NORMAL_EXEC,
				0x55555555, 0x55555555, 0xffff, 0x3);
1156 1157
}

1158
static void btc8821a2ant_coex_under_5g(struct btc_coexist *btcoexist)
1159
{
1160
	btc8821a2ant_coex_all_off(btcoexist);
1161 1162
}

1163
static void btc8821a2ant_init_coex_dm(struct btc_coexist *btcoexist)
1164 1165
{
	/* force to reset coex mechanism */
1166 1167
	btc8821a2ant_coex_table(btcoexist, FORCE_EXEC, 0x55555555,
				0x55555555, 0xffff, 0x3);
1168

1169 1170
	btc8821a2ant_ps_tdma(btcoexist, FORCE_EXEC, false, 1);
	btc8821a2ant_fw_dac_swing_lvl(btcoexist, FORCE_EXEC, 6);
1171
	btc8821a2ant_dec_bt_pwr(btcoexist, FORCE_EXEC, 0);
1172

1173 1174
	btc8821a2ant_sw_mechanism1(btcoexist, false, false, false, false);
	btc8821a2ant_sw_mechanism2(btcoexist, false, false, false, 0x18);
1175 1176
}

1177
static void btc8821a2ant_bt_inquiry_page(struct btc_coexist *btcoexist)
1178 1179 1180 1181 1182 1183
{
	bool low_pwr_disable = true;

	btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER,
			   &low_pwr_disable);

1184 1185 1186
	btc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, 0x55ff55ff,
				0x5afa5afa, 0xffff, 0x3);
	btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3);
1187 1188
}

1189
static bool btc8821a2ant_is_common_action(struct btc_coexist *btcoexist)
1190
{
1191
	struct rtl_priv *rtlpriv = btcoexist->adapter;
1192 1193 1194 1195 1196 1197 1198
	bool common = false, wifi_connected = false, wifi_busy = false;
	bool low_pwr_disable = false;

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

1199 1200
	btc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, 0x55ff55ff,
				0x5afa5afa, 0xffff, 0x3);
1201 1202 1203 1204 1205 1206 1207

	if (!wifi_connected &&
	    BT_8821A_2ANT_BT_STATUS_IDLE == coex_dm->bt_status) {
		low_pwr_disable = false;
		btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER,
				   &low_pwr_disable);

1208 1209
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], Wifi IPS + BT IPS!!\n");
1210

1211 1212 1213
		btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1);
		btc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
		btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
1214

1215 1216 1217 1218
		btc8821a2ant_sw_mechanism1(btcoexist, false, false, false,
					   false);
		btc8821a2ant_sw_mechanism2(btcoexist, false, false, false,
					   0x18);
1219 1220 1221 1222 1223 1224 1225 1226 1227

		common = true;
	} else if (wifi_connected &&
		   (BT_8821A_2ANT_BT_STATUS_IDLE == coex_dm->bt_status)) {
		low_pwr_disable = false;
		btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER,
				   &low_pwr_disable);

		if (wifi_busy) {
1228 1229
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "[BTCoex], Wifi Busy + BT IPS!!\n");
1230 1231
			btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
					     false, 1);
1232
		} else {
1233 1234
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "[BTCoex], Wifi LPS + BT IPS!!\n");
1235 1236
			btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
					     false, 1);
1237 1238
		}

1239 1240
		btc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
		btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
1241

1242 1243 1244 1245
		btc8821a2ant_sw_mechanism1(btcoexist, false, false, false,
					   false);
		btc8821a2ant_sw_mechanism2(btcoexist, false, false, false,
					   0x18);
1246 1247 1248 1249 1250 1251 1252

		common = true;
	} else if (!wifi_connected &&
		   (BT_8821A_2ANT_BT_STATUS_CON_IDLE == coex_dm->bt_status)) {
		low_pwr_disable = true;
		btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER,
				   &low_pwr_disable);
1253 1254
		btc8821a2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false,
					0x8);
1255

1256 1257
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], Wifi IPS + BT LPS!!\n");
1258

1259 1260
		btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1);
		btc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
1261
		btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0);
1262

1263 1264 1265 1266
		btc8821a2ant_sw_mechanism1(btcoexist, false, false, false,
					   false);
		btc8821a2ant_sw_mechanism2(btcoexist, false, false, false,
					   0x18);
1267 1268 1269 1270 1271 1272 1273 1274
		common = true;
	} else if (wifi_connected &&
		   (BT_8821A_2ANT_BT_STATUS_CON_IDLE == coex_dm->bt_status)) {
		low_pwr_disable = true;
		btcoexist->btc_set(btcoexist,
			BTC_SET_ACT_DISABLE_LOW_POWER, &low_pwr_disable);

		if (wifi_busy) {
1275 1276
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "[BTCoex], Wifi Busy + BT LPS!!\n");
1277 1278
			btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
					     false, 1);
1279
		} else {
1280 1281
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "[BTCoex], Wifi LPS + BT LPS!!\n");
1282 1283
			btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
					     false, 1);
1284 1285
		}

1286 1287
		btc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
		btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
1288

1289 1290 1291
		btc8821a2ant_sw_mechanism1(btcoexist, true, true, true, true);
		btc8821a2ant_sw_mechanism2(btcoexist, false, false, false,
					   0x18);
1292 1293 1294

		common = true;
	} else if (!wifi_connected &&
1295
		   (coex_dm->bt_status == BT_8821A_2ANT_BT_STATUS_NON_IDLE)) {
1296
		low_pwr_disable = false;
1297 1298
		btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER,
				   &low_pwr_disable);
1299

1300 1301
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], Wifi IPS + BT Busy!!\n");
1302

1303 1304 1305
		btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1);
		btc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
		btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
1306

1307 1308 1309 1310
		btc8821a2ant_sw_mechanism1(btcoexist, false, false,
					   false, false);
		btc8821a2ant_sw_mechanism2(btcoexist, false, false,
					   false, 0x18);
1311 1312 1313 1314 1315 1316 1317 1318 1319

		common = true;
	} else {
		low_pwr_disable = true;
		btcoexist->btc_set(btcoexist,
				   BTC_SET_ACT_DISABLE_LOW_POWER,
				   &low_pwr_disable);

		if (wifi_busy) {
1320 1321
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "[BTCoex], Wifi Busy + BT Busy!!\n");
1322 1323
			common = false;
		} else {
1324 1325
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "[BTCoex], Wifi LPS + BT Busy!!\n");
1326 1327
			btc8821a2ant_ps_tdma(btcoexist,
					     NORMAL_EXEC, true, 21);
1328 1329 1330

			common = true;
		}
1331
		btc8821a2ant_sw_mechanism1(btcoexist, true, true, true, true);
1332 1333 1334 1335 1336 1337 1338 1339
	}
	return common;
}

static void btc8821a2ant_tdma_dur_adj(struct btc_coexist *btcoexist,
				      bool sco_hid, bool tx_pause,
				      u8 max_interval)
{
1340
	struct rtl_priv *rtlpriv = btcoexist->adapter;
1341 1342 1343
	static long up, dn, m, n, wait_count;
	 /* 0 : no change
	  * +1: increase WiFi duration
1344 1345
	  * -1: decrease WiFi duration
	  */
1346 1347
	int result;
	u8 retry_count = 0;
1348

1349 1350
	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
		 "[BTCoex], TdmaDurationAdjust()\n");
1351 1352 1353

	if (coex_dm->reset_tdma_adjust) {
		coex_dm->reset_tdma_adjust = false;
1354 1355
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], first run TdmaDurationAdjust()!!\n");
1356 1357 1358
		if (sco_hid) {
			if (tx_pause) {
				if (max_interval == 1) {
1359 1360 1361
					btc8821a2ant_ps_tdma(btcoexist,
							     NORMAL_EXEC,
							     true, 13);
1362 1363
					coex_dm->tdma_adj_type = 13;
				} else if (max_interval == 2) {
1364 1365 1366
					btc8821a2ant_ps_tdma(btcoexist,
							     NORMAL_EXEC,
							     true, 14);
1367 1368
					coex_dm->tdma_adj_type = 14;
				} else {
1369 1370 1371
					btc8821a2ant_ps_tdma(btcoexist,
							     NORMAL_EXEC,
							     true, 15);
1372 1373 1374 1375
					coex_dm->tdma_adj_type = 15;
				}
			} else {
				if (max_interval == 1) {
1376 1377 1378
					btc8821a2ant_ps_tdma(btcoexist,
							     NORMAL_EXEC,
							     true, 9);
1379 1380
					coex_dm->tdma_adj_type = 9;
				} else if (max_interval == 2) {
1381 1382 1383
					btc8821a2ant_ps_tdma(btcoexist,
							     NORMAL_EXEC,
							     true, 10);
1384 1385
					coex_dm->tdma_adj_type = 10;
				} else {
1386 1387 1388
					btc8821a2ant_ps_tdma(btcoexist,
							     NORMAL_EXEC,
							     true, 11);
1389 1390 1391 1392 1393 1394
					coex_dm->tdma_adj_type = 11;
				}
			}
		} else {
			if (tx_pause) {
				if (max_interval == 1) {
1395 1396 1397
					btc8821a2ant_ps_tdma(btcoexist,
							     NORMAL_EXEC,
							     true, 5);
1398 1399
					coex_dm->tdma_adj_type = 5;
				} else if (max_interval == 2) {
1400 1401 1402
					btc8821a2ant_ps_tdma(btcoexist,
							     NORMAL_EXEC,
							     true, 6);
1403 1404
					coex_dm->tdma_adj_type = 6;
				} else {
1405 1406 1407
					btc8821a2ant_ps_tdma(btcoexist,
							     NORMAL_EXEC,
							     true, 7);
1408 1409 1410 1411
					coex_dm->tdma_adj_type = 7;
				}
			} else {
				if (max_interval == 1) {
1412 1413 1414
					btc8821a2ant_ps_tdma(btcoexist,
							     NORMAL_EXEC,
							     true, 1);
1415 1416
					coex_dm->tdma_adj_type = 1;
				} else if (max_interval == 2) {
1417 1418 1419
					btc8821a2ant_ps_tdma(btcoexist,
							     NORMAL_EXEC,
							     true, 2);
1420 1421
					coex_dm->tdma_adj_type = 2;
				} else {
1422 1423 1424
					btc8821a2ant_ps_tdma(btcoexist,
							     NORMAL_EXEC,
							     true, 3);
1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438
					coex_dm->tdma_adj_type = 3;
				}
			}
		}

		up = 0;
		dn = 0;
		m = 1;
		n = 3;
		result = 0;
		wait_count = 0;
	} else {
		/* accquire the BT TRx retry count from BT_Info byte2 */
		retry_count = coex_sta->bt_retry_cnt;
1439 1440 1441 1442
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], retry_count = %d\n", retry_count);
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], up = %d, dn = %d, m = %d, n = %d, wait_count = %d\n",
1443
			    (int)up, (int)dn, (int)m, (int)n, (int)wait_count);
1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463
		result = 0;
		wait_count++;

		if (retry_count == 0) {
			/* no retry in the last 2-second duration */
			up++;
			dn--;

			if (dn <= 0)
				dn = 0;

			if (up >= n) {
				/* if (retry count == 0) for 2*n seconds,
				 * make WiFi duration wider
				 */
				wait_count = 0;
				n = 3;
				up = 0;
				dn = 0;
				result = 1;
1464 1465
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], Increase wifi duration!!\n");
1466 1467 1468 1469 1470 1471 1472 1473 1474 1475
			}
		} else if (retry_count <= 3) {
			/* <=3 retry in the last 2-second duration */
			up--;
			dn++;

			if (up <= 0)
				up = 0;

			if (dn == 2) {
1476
				/* if retry count < 3 for 2*2 seconds,
1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488
				 * shrink wifi duration
				 */
				if (wait_count <= 2)
					m++; /* avoid bounce in two levels */
				else
					m = 1;
				/* m max value is 20, max time is 120 second,
				 * recheck if adjust WiFi duration.
				 */
				if (m >= 20)
					m = 20;

1489
				n = 3 * m;
1490 1491 1492 1493
				up = 0;
				dn = 0;
				wait_count = 0;
				result = -1;
1494 1495
				RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
					 "[BTCoex], Decrease wifi duration for retryCounter<3!!\n");
1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510
			}
		} else {
			/* retry count > 3, if retry count > 3 happens once,
			 * shrink WiFi duration
			 */
			if (wait_count == 1)
				m++; /* avoid bounce in two levels */
			else
				m = 1;
			/* m max value is 20, max time is 120 second,
			 * recheck if adjust WiFi duration.
			 */
			if (m >= 20)
				m = 20;

1511
			n = 3 * m;
1512 1513 1514 1515
			up = 0;
			dn = 0;
			wait_count = 0;
			result = -1;
1516 1517
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "[BTCoex], Decrease wifi duration for retryCounter>3!!\n");
1518 1519
		}

1520 1521
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], max Interval = %d\n", max_interval);
1522 1523 1524 1525 1526 1527 1528 1529 1530
	}

	/* if current PsTdma not match with the recorded one
	 * (when scan, dhcp...), then we have to adjust it back to
	 * the previous recorded one.
	 */
	if (coex_dm->cur_ps_tdma != coex_dm->tdma_adj_type) {
		bool	scan = false, link = false, roam = false;

1531 1532
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], PsTdma type dismatch!!!, cur_ps_tdma = %d, recordPsTdma = %d\n",
1533
			 coex_dm->cur_ps_tdma, coex_dm->tdma_adj_type);
1534 1535 1536 1537 1538 1539

		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) {
1540 1541
			btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, true,
					     coex_dm->tdma_adj_type);
1542
		} else {
1543 1544
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "[BTCoex], roaming/link/scan is under progress, will adjust next time!!!\n");
1545 1546 1547
		}
	}

1548
	btc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 0x6);
1549 1550 1551
}

/* SCO only or SCO+PAN(HS)*/
1552
static void btc8821a2ant_action_sco(struct btc_coexist *btcoexist)
1553
{
1554
	u8 wifi_rssi_state, bt_rssi_state;
1555 1556
	u32 wifi_bw;

1557 1558 1559
	wifi_rssi_state = btc8821a2ant_wifi_rssi_state(btcoexist, 0, 2,
						       15, 0);
	bt_rssi_state = btc8821a2ant_bt_rssi_state(btcoexist, 2, 35, 0);
1560

1561
	btc8821a2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8);
1562
	btc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 4);
1563

1564
	if (BTC_RSSI_HIGH(bt_rssi_state))
1565
		btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true);
1566
	else
1567
		btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
1568 1569 1570

	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);

1571
	if (wifi_bw == BTC_WIFI_BW_LEGACY) {
1572
		/* for SCO quality at 11b/g mode */
1573 1574
		btc8821a2ant_coex_table(btcoexist, NORMAL_EXEC,
					0x5a5a5a5a, 0x5a5a5a5a, 0xffff, 0x3);
1575 1576
	} else {
		/* for SCO quality & wifi performance balance at 11n mode */
1577 1578
		btc8821a2ant_coex_table(btcoexist, NORMAL_EXEC,
					0x5aea5aea, 0x5aea5aea, 0xffff, 0x3);
1579 1580
	}

1581
	if (wifi_bw == BTC_WIFI_BW_HT40) {
1582

1583 1584 1585 1586 1587 1588 1589 1590 1591 1592
		if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
		    (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
			/* for voice quality */
			btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
					     false, 0);
		} else {
			/* for voice quality */
			btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
					     false, 0);
		}
1593 1594 1595 1596

		/* sw mechanism */
		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
1597 1598 1599 1600
			btc8821a2ant_sw_mechanism1(btcoexist, true, true,
						   false, false);
			btc8821a2ant_sw_mechanism2(btcoexist, true, false,
						   false, 0x18);
1601
		} else {
1602 1603 1604 1605
			btc8821a2ant_sw_mechanism1(btcoexist, true, true,
						   false, false);
			btc8821a2ant_sw_mechanism2(btcoexist, false, false,
						   false, 0x18);
1606 1607 1608 1609
		}
	} else {
		if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
		    (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
1610 1611
			/* for voice quality */
			btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0);
1612
		} else {
1613 1614
			/* for voice quality */
			btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 0);
1615 1616 1617 1618 1619
		}

		/* sw mechanism */
		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
1620 1621 1622 1623
			btc8821a2ant_sw_mechanism1(btcoexist, false, true,
						   false, false);
			btc8821a2ant_sw_mechanism2(btcoexist, true, false,
						   false, 0x18);
1624
		} else {
1625 1626 1627 1628
			btc8821a2ant_sw_mechanism1(btcoexist, false, true,
						   false, false);
			btc8821a2ant_sw_mechanism2(btcoexist, false, false,
						   false, 0x18);
1629 1630 1631 1632
		}
	}
}

1633
static void btc8821a2ant_action_hid(struct btc_coexist *btcoexist)
1634
{
1635 1636
	u8 wifi_rssi_state, bt_rssi_state;
	u32 wifi_bw;
1637

1638 1639
	wifi_rssi_state = btc8821a2ant_wifi_rssi_state(btcoexist, 0, 2, 15, 0);
	bt_rssi_state = btc8821a2ant_bt_rssi_state(btcoexist, 2, 35, 0);
1640

1641
	btc8821a2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8);
1642
	btc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
1643

1644
	if (BTC_RSSI_HIGH(bt_rssi_state))
1645
		btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true);
1646
	else
1647
		btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
1648 1649 1650

	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);

1651
	if (wifi_bw == BTC_WIFI_BW_LEGACY) {
1652
		/* for HID at 11b/g mode */
1653 1654
		btc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, 0x55ff55ff,
					0x5a5a5a5a, 0xffff, 0x3);
1655 1656
	} else {
		/* for HID quality & wifi performance balance at 11n mode */
1657 1658
		btc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, 0x55ff55ff,
					0x5aea5aea, 0xffff, 0x3);
1659 1660
	}

1661
	if (wifi_bw == BTC_WIFI_BW_HT40) {
1662 1663 1664
		/* fw mechanism */
		if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
		    (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
1665 1666
			btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
					     true, 9);
1667
		} else {
1668 1669
			btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
					     true, 13);
1670 1671 1672 1673 1674
		}

		/* sw mechanism */
		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
1675 1676 1677 1678
			btc8821a2ant_sw_mechanism1(btcoexist, true, true,
						   false, false);
			btc8821a2ant_sw_mechanism2(btcoexist, true, false,
						   false, 0x18);
1679
		} else {
1680 1681 1682 1683
			btc8821a2ant_sw_mechanism1(btcoexist, true, true,
						   false, false);
			btc8821a2ant_sw_mechanism2(btcoexist, false, false,
						   false, 0x18);
1684 1685 1686 1687 1688
		}
	} else {
		/* fw mechanism */
		if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
		    (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
1689 1690
			btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
					     true, 9);
1691
		} else {
1692 1693
			btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
					     true, 13);
1694 1695 1696 1697 1698
		}

		/* sw mechanism */
		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
1699 1700 1701 1702
			btc8821a2ant_sw_mechanism1(btcoexist, false, true,
						   false, false);
			btc8821a2ant_sw_mechanism2(btcoexist, true, false,
						   false, 0x18);
1703
		} else {
1704 1705 1706 1707
			btc8821a2ant_sw_mechanism1(btcoexist, false, true,
						   false, false);
			btc8821a2ant_sw_mechanism2(btcoexist, false, false,
						   false, 0x18);
1708 1709 1710 1711 1712
		}
	}
}

/* A2DP only / PAN(EDR) only/ A2DP+PAN(HS) */
1713
static void btc8821a2ant_action_a2dp(struct btc_coexist *btcoexist)
1714
{
1715 1716
	u8 wifi_rssi_state, bt_rssi_state;
	u32 wifi_bw;
1717

1718 1719 1720
	wifi_rssi_state = btc8821a2ant_wifi_rssi_state(btcoexist, 0, 2,
						       15, 0);
	bt_rssi_state = btc8821a2ant_bt_rssi_state(btcoexist, 2, 35, 0);
1721 1722

	/* fw dac swing is called in btc8821a2ant_tdma_dur_adj()
1723
	 * btc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
1724 1725
	 */

1726
	if (BTC_RSSI_HIGH(bt_rssi_state))
1727
		btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true);
1728
	else
1729
		btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744

	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);

	if (BTC_WIFI_BW_HT40 == wifi_bw) {
		/* fw mechanism */
		if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
		    (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
			btc8821a2ant_tdma_dur_adj(btcoexist, false, false, 1);
		} else {
			btc8821a2ant_tdma_dur_adj(btcoexist, false, true, 1);
		}

		/* sw mechanism */
		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
1745 1746 1747 1748
			btc8821a2ant_sw_mechanism1(btcoexist, true, false,
						   false, false);
			btc8821a2ant_sw_mechanism2(btcoexist, true, false,
						   false, 0x18);
1749
		} else {
1750 1751 1752 1753
			btc8821a2ant_sw_mechanism1(btcoexist, true, false,
						   false, false);
			btc8821a2ant_sw_mechanism2(btcoexist, false, false,
						   false, 0x18);
1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766
		}
	} else {
		/* fw mechanism */
		if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
		    (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
			btc8821a2ant_tdma_dur_adj(btcoexist, false, false, 1);
		} else {
			btc8821a2ant_tdma_dur_adj(btcoexist, false, true, 1);
		}

		/* sw mechanism */
		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
1767 1768 1769 1770
			btc8821a2ant_sw_mechanism1(btcoexist, false, false,
						   false, false);
			btc8821a2ant_sw_mechanism2(btcoexist, true, false,
						   false, 0x18);
1771
		} else {
1772 1773 1774 1775
			btc8821a2ant_sw_mechanism1(btcoexist, false, false,
						   false, false);
			btc8821a2ant_sw_mechanism2(btcoexist, false, false,
						   false, 0x18);
1776 1777 1778 1779
		}
	}
}

1780
static void btc8821a2ant_action_a2dp_pan_hs(struct btc_coexist *btcoexist)
1781
{
1782 1783
	u8 wifi_rssi_state, bt_rssi_state, bt_info_ext;
	u32 wifi_bw;
1784 1785

	bt_info_ext = coex_sta->bt_info_ext;
1786 1787
	wifi_rssi_state = btc8821a2ant_wifi_rssi_state(btcoexist, 0, 2, 15, 0);
	bt_rssi_state = btc8821a2ant_bt_rssi_state(btcoexist, 2, 35, 0);
1788

1789
	if (BTC_RSSI_HIGH(bt_rssi_state))
1790
		btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 2);
1791
	else
1792
		btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0);
1793 1794 1795

	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);

1796
	if (wifi_bw == BTC_WIFI_BW_HT40) {
1797 1798
		/* fw mechanism */
		if (bt_info_ext&BIT0) {
1799
			/* a2dp basic rate */
1800 1801
			btc8821a2ant_tdma_dur_adj(btcoexist, false, true, 2);
		} else {
1802
			/* a2dp edr rate */
1803 1804 1805 1806 1807 1808
			btc8821a2ant_tdma_dur_adj(btcoexist, false, true, 1);
		}

		/* sw mechanism */
		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
1809 1810 1811 1812
			btc8821a2ant_sw_mechanism1(btcoexist, true, false,
						   false, false);
			btc8821a2ant_sw_mechanism2(btcoexist, true, false,
						   false, 0x18);
1813
		} else {
1814 1815 1816 1817
			btc8821a2ant_sw_mechanism1(btcoexist, true, false,
						   false, false);
			btc8821a2ant_sw_mechanism2(btcoexist, false, false,
						   false, 0x18);
1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831
		}
	} else {
		/* fw mechanism */
		if (bt_info_ext&BIT0) {
			/* a2dp basic rate */
			btc8821a2ant_tdma_dur_adj(btcoexist, false, true, 2);
		} else {
			/* a2dp edr rate */
			btc8821a2ant_tdma_dur_adj(btcoexist, false, true, 1);
		}

		/* sw mechanism */
		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
1832 1833 1834 1835
			btc8821a2ant_sw_mechanism1(btcoexist, false, false,
						   false, false);
			btc8821a2ant_sw_mechanism2(btcoexist, true, false,
						   false, 0x18);
1836
		} else {
1837 1838 1839 1840
			btc8821a2ant_sw_mechanism1(btcoexist, false, false,
						   false, false);
			btc8821a2ant_sw_mechanism2(btcoexist, false, false,
						   false, 0x18);
1841 1842 1843 1844
		}
	}
}

1845
static void btc8821a2ant_action_pan_edr(struct btc_coexist *btcoexist)
1846
{
1847 1848
	u8 wifi_rssi_state, bt_rssi_state;
	u32 wifi_bw;
1849

1850 1851
	wifi_rssi_state = btc8821a2ant_wifi_rssi_state(btcoexist, 0, 2, 15, 0);
	bt_rssi_state = btc8821a2ant_bt_rssi_state(btcoexist, 2, 35, 0);
1852

1853
	btc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
1854

1855
	if (BTC_RSSI_HIGH(bt_rssi_state))
1856
		btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true);
1857
	else
1858
		btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
1859 1860 1861 1862 1863

	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);

	if (BTC_WIFI_BW_LEGACY == wifi_bw) {
		/* for HID at 11b/g mode */
1864 1865
		btc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, 0x55ff55ff,
					0x5aff5aff, 0xffff, 0x3);
1866 1867
	} else {
		/* for HID quality & wifi performance balance at 11n mode */
1868 1869
		btc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, 0x55ff55ff,
					0x5aff5aff, 0xffff, 0x3);
1870 1871 1872 1873 1874 1875
	}

	if (BTC_WIFI_BW_HT40 == wifi_bw) {
		/* fw mechanism */
		if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
		    (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
1876 1877
			btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
					     true, 1);
1878
		} else {
1879 1880
			btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
					     true, 5);
1881 1882 1883 1884 1885
		}

		/* sw mechanism */
		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
1886 1887 1888 1889
			btc8821a2ant_sw_mechanism1(btcoexist, true, false,
						   false, false);
			btc8821a2ant_sw_mechanism2(btcoexist, true, false,
						   false, 0x18);
1890
		} else {
1891 1892 1893 1894
			btc8821a2ant_sw_mechanism1(btcoexist, true, false,
						   false, false);
			btc8821a2ant_sw_mechanism2(btcoexist, false, false,
						   false, 0x18);
1895 1896 1897 1898 1899
		}
	} else {
		/* fw mechanism */
		if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
		    (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
1900 1901
			btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
					     true, 1);
1902
		} else {
1903 1904
			btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
					     true, 5);
1905 1906 1907 1908 1909
		}

		/* sw mechanism */
		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
1910 1911 1912 1913
			btc8821a2ant_sw_mechanism1(btcoexist, false, false,
						   false, false);
			btc8821a2ant_sw_mechanism2(btcoexist, true, false,
						   false, 0x18);
1914
		} else {
1915 1916 1917 1918
			btc8821a2ant_sw_mechanism1(btcoexist, false, false,
						   false, false);
			btc8821a2ant_sw_mechanism2(btcoexist, false, false,
						   false, 0x18);
1919 1920 1921 1922 1923
		}
	}
}

/* PAN(HS) only */
1924
static void btc8821a2ant_action_pan_hs(struct btc_coexist *btcoexist)
1925
{
1926 1927
	u8 wifi_rssi_state, bt_rssi_state;
	u32 wifi_bw;
1928

1929 1930
	wifi_rssi_state = btc8821a2ant_wifi_rssi_state(btcoexist, 0, 2, 15, 0);
	bt_rssi_state = btc8821a2ant_bt_rssi_state(btcoexist, 2, 35, 0);
1931

1932
	btc8821a2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8);
1933
	btc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
1934 1935 1936 1937 1938 1939 1940

	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);

	if (BTC_WIFI_BW_HT40 == wifi_bw) {
		/* fw mechanism */
		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
1941
			btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true);
1942
		} else {
1943
			btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
1944
		}
1945
		btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1);
1946 1947 1948 1949

		/* sw mechanism */
		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
1950 1951 1952 1953
			btc8821a2ant_sw_mechanism1(btcoexist, true, false,
						   false, false);
			btc8821a2ant_sw_mechanism2(btcoexist, true, false,
						   false, 0x18);
1954
		} else {
1955 1956 1957 1958
			btc8821a2ant_sw_mechanism1(btcoexist, true, false,
						   false, false);
			btc8821a2ant_sw_mechanism2(btcoexist, false, false,
						   false, 0x18);
1959 1960 1961 1962 1963
		}
	} else {
		/* fw mechanism */
		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
1964
			btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true);
1965
		} else {
1966
			btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
1967 1968
		}

1969 1970 1971 1972 1973 1974
		if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
		    (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
			btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1);
		} else {
			btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1);
		}
1975 1976 1977 1978

		/* sw mechanism */
		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
1979 1980 1981 1982
			btc8821a2ant_sw_mechanism1(btcoexist, false, false,
						   false, false);
			btc8821a2ant_sw_mechanism2(btcoexist, true, false,
						   false, 0x18);
1983
		} else {
1984 1985 1986 1987
			btc8821a2ant_sw_mechanism1(btcoexist, false, false,
						   false, false);
			btc8821a2ant_sw_mechanism2(btcoexist, false, false,
						   false, 0x18);
1988 1989 1990 1991 1992
		}
	}
}

/* PAN(EDR)+A2DP */
1993
static void btc8821a2ant_action_pan_edr_a2dp(struct btc_coexist *btcoexist)
1994 1995 1996 1997 1998
{
	u8	wifi_rssi_state, bt_rssi_state, bt_info_ext;
	u32	wifi_bw;

	bt_info_ext = coex_sta->bt_info_ext;
1999 2000
	wifi_rssi_state = btc8821a2ant_wifi_rssi_state(btcoexist, 0, 2, 15, 0);
	bt_rssi_state = btc8821a2ant_bt_rssi_state(btcoexist, 2, 35, 0);
2001

2002
	btc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
2003

2004
	if (BTC_RSSI_HIGH(bt_rssi_state))
2005
		btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 2);
2006
	else
2007
		btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0);
2008 2009 2010

	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);

2011 2012 2013 2014 2015 2016 2017 2018 2019
	if (wifi_bw == BTC_WIFI_BW_LEGACY) {
		/* for HID at 11b/g mode */
		btc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, 0x55ff55ff,
					0x5afa5afa, 0xffff, 0x3);
	} else {
		/* for HID quality & wifi performance balance at 11n mode */
		btc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, 0x55ff55ff,
					0x5afa5afa, 0xffff, 0x3);
	}
2020 2021 2022 2023

	if (BTC_WIFI_BW_HT40 == wifi_bw) {
		/* fw mechanism */
		if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
2024 2025 2026 2027 2028 2029
		    (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH))
			btc8821a2ant_tdma_dur_adj(btcoexist, false,
						  false, 3);
		else
			btc8821a2ant_tdma_dur_adj(btcoexist, false,
						  true, 3);
2030 2031 2032 2033

		/* sw mechanism */
		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2034 2035 2036 2037
			btc8821a2ant_sw_mechanism1(btcoexist, true, false,
						   false, false);
			btc8821a2ant_sw_mechanism2(btcoexist, true, false,
						   false, 0x18);
2038
		} else {
2039 2040 2041 2042 2043
			btc8821a2ant_sw_mechanism1(btcoexist, true, false,
						   false, false);
			btc8821a2ant_sw_mechanism2(btcoexist, false, false,
						   false, 0x18);
		};
2044 2045 2046
	} else {
		/* fw mechanism */
		if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
2047 2048 2049 2050
		    (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH))
			btc8821a2ant_tdma_dur_adj(btcoexist, false, false, 3);
		else
			btc8821a2ant_tdma_dur_adj(btcoexist, false, true, 3);
2051 2052 2053 2054

		/* sw mechanism */
		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2055 2056 2057 2058
			btc8821a2ant_sw_mechanism1(btcoexist, false, false,
						   false, false);
			btc8821a2ant_sw_mechanism2(btcoexist, true, false,
						   false, 0x18);
2059
		} else {
2060 2061 2062 2063
			btc8821a2ant_sw_mechanism1(btcoexist, false, false,
						   false, false);
			btc8821a2ant_sw_mechanism2(btcoexist, false, false,
						   false, 0x18);
2064 2065 2066 2067
		}
	}
}

2068
static void btc8821a2ant_action_pan_edr_hid(struct btc_coexist *btcoexist)
2069
{
2070 2071
	u8 wifi_rssi_state, bt_rssi_state;
	u32 wifi_bw;
2072

2073 2074
	wifi_rssi_state = btc8821a2ant_wifi_rssi_state(btcoexist, 0, 2, 15, 0);
	bt_rssi_state = btc8821a2ant_bt_rssi_state(btcoexist, 2, 35, 0);
2075

2076
	btc8821a2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8);
2077
	btc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
2078

2079
	if (BTC_RSSI_HIGH(bt_rssi_state))
2080
		btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true);
2081
	else
2082
		btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
2083 2084 2085

	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);

2086 2087 2088 2089 2090 2091 2092 2093 2094
	if (wifi_bw == BTC_WIFI_BW_LEGACY) {
		/* for HID at 11b/g mode */
		btc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, 0x55ff55ff,
					0x5a5f5a5f, 0xffff, 0x3);
	} else {
		/* for HID quality & wifi performance balance at 11n mode */
		btc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, 0x55ff55ff,
					0x5a5f5a5f, 0xffff, 0x3);
	}
2095

2096 2097
	if (wifi_bw == BTC_WIFI_BW_HT40) {
		btc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 3);
2098 2099 2100
		/* fw mechanism */
		if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
		    (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2101 2102
			btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC,
					     true, 10);
2103
		} else {
2104
			btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14);
2105 2106 2107 2108 2109
		}

		/* sw mechanism */
		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2110 2111 2112 2113
			btc8821a2ant_sw_mechanism1(btcoexist, true, true,
						   false, false);
			btc8821a2ant_sw_mechanism2(btcoexist, true, false,
						   false, 0x18);
2114
		} else {
2115 2116 2117 2118
			btc8821a2ant_sw_mechanism1(btcoexist, true, true,
						   false, false);
			btc8821a2ant_sw_mechanism2(btcoexist, false, false,
						   false, 0x18);
2119 2120
		}
	} else {
2121
		btc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
2122 2123 2124
		/* fw mechanism */
		if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
		    (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2125
			btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 10);
2126
		} else {
2127
			btc8821a2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14);
2128 2129 2130 2131 2132
		}

		/* sw mechanism */
		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2133 2134 2135 2136
			btc8821a2ant_sw_mechanism1(btcoexist, false, true,
						   false, false);
			btc8821a2ant_sw_mechanism2(btcoexist, true, false,
						   false, 0x18);
2137
		} else {
2138 2139 2140 2141
			btc8821a2ant_sw_mechanism1(btcoexist, false, true,
						   false, false);
			btc8821a2ant_sw_mechanism2(btcoexist, false, false,
						   false, 0x18);
2142 2143 2144 2145 2146 2147 2148
		}
	}
}

/* HID+A2DP+PAN(EDR) */
static void btc8821a2ant_act_hid_a2dp_pan_edr(struct btc_coexist *btcoexist)
{
2149 2150
	u8 wifi_rssi_state, bt_rssi_state, bt_info_ext;
	u32 wifi_bw;
2151 2152

	bt_info_ext = coex_sta->bt_info_ext;
2153 2154
	wifi_rssi_state = btc8821a2ant_wifi_rssi_state(btcoexist, 0, 2, 15, 0);
	bt_rssi_state = btc8821a2ant_bt_rssi_state(btcoexist, 2, 35, 0);
2155

2156
	btc8821a2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8);
2157
	btc8821a2ant_fw_dac_swing_lvl(btcoexist, NORMAL_EXEC, 6);
2158

2159
	if (BTC_RSSI_HIGH(bt_rssi_state))
2160
		btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 2);
2161
	else
2162
		btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, 0);
2163 2164 2165

	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);

2166 2167 2168 2169 2170 2171 2172 2173 2174
	if (wifi_bw == BTC_WIFI_BW_LEGACY) {
		/* for HID at 11b/g mode */
		btc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, 0x55ff55ff,
					0x5a5a5a5a, 0xffff, 0x3);
	} else {
		/* for HID quality & wifi performance balance at 11n mode */
		btc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, 0x55ff55ff,
					0x5a5a5a5a, 0xffff, 0x3);
	}
2175 2176 2177

	if (BTC_WIFI_BW_HT40 == wifi_bw) {
		/* fw mechanism */
2178
		btc8821a2ant_tdma_dur_adj(btcoexist, true, true, 3);
2179 2180 2181 2182

		/* sw mechanism */
		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2183 2184 2185 2186
			btc8821a2ant_sw_mechanism1(btcoexist, true, true,
						   false, false);
			btc8821a2ant_sw_mechanism2(btcoexist, true, false,
						   false, 0x18);
2187
		} else {
2188 2189 2190 2191
			btc8821a2ant_sw_mechanism1(btcoexist, true, true,
						   false, false);
			btc8821a2ant_sw_mechanism2(btcoexist, false, false,
						   false, 0x18);
2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220
		}
	} else {
		/* fw mechanism */
		if ((bt_rssi_state == BTC_RSSI_STATE_HIGH) ||
		    (bt_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
			if (bt_info_ext&BIT0) {
				/* a2dp basic rate */
				btc8821a2ant_tdma_dur_adj(btcoexist, true,
							  false, 3);
			} else {
				/* a2dp edr rate */
				btc8821a2ant_tdma_dur_adj(btcoexist, true,
							  false, 3);
			}
		} else {
			if (bt_info_ext&BIT0) {
				/* a2dp basic rate */
				btc8821a2ant_tdma_dur_adj(btcoexist, true,
							  true, 3);
			} else {
				/* a2dp edr rate */
				btc8821a2ant_tdma_dur_adj(btcoexist, true,
							  true, 3);
			}
		}

		/* sw mechanism */
		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2221 2222 2223 2224
			btc8821a2ant_sw_mechanism1(btcoexist, false, true,
						   false, false);
			btc8821a2ant_sw_mechanism2(btcoexist, true, false,
						   false, 0x18);
2225
		} else {
2226 2227 2228 2229
			btc8821a2ant_sw_mechanism1(btcoexist, false, true,
						   false, false);
			btc8821a2ant_sw_mechanism2(btcoexist, false, false,
						   false, 0x18);
2230 2231 2232 2233
		}
	}
}

2234
static void btc8821a2ant_action_hid_a2dp(struct btc_coexist *btcoexist)
2235
{
2236 2237
	u8 wifi_rssi_state, bt_rssi_state, bt_info_ext;
	u32 wifi_bw;
2238 2239

	bt_info_ext = coex_sta->bt_info_ext;
2240 2241
	wifi_rssi_state = btc8821a2ant_wifi_rssi_state(btcoexist, 0, 2, 15, 0);
	bt_rssi_state = btc8821a2ant_bt_rssi_state(btcoexist, 2, 35, 0);
2242

2243
	if (BTC_RSSI_HIGH(bt_rssi_state))
2244
		btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, true);
2245
	else
2246
		btc8821a2ant_dec_bt_pwr(btcoexist, NORMAL_EXEC, false);
2247 2248 2249

	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);

2250 2251 2252 2253 2254 2255 2256 2257 2258
	if (wifi_bw == BTC_WIFI_BW_LEGACY) {
		/* for HID at 11b/g mode */
		btc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, 0x55ff55ff,
					0x5f5b5f5b, 0xffffff, 0x3);
	} else {
		/* for HID quality & wifi performance balance at 11n mode */
		btc8821a2ant_coex_table(btcoexist, NORMAL_EXEC, 0x55ff55ff,
					0x5f5b5f5b, 0xffffff, 0x3);
	}
2259 2260 2261

	if (BTC_WIFI_BW_HT40 == wifi_bw) {
		/* fw mechanism */
2262
		btc8821a2ant_tdma_dur_adj(btcoexist, true, true, 2);
2263 2264 2265 2266

		/* sw mechanism */
		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2267 2268 2269 2270
			btc8821a2ant_sw_mechanism1(btcoexist, true, true,
						   false, false);
			btc8821a2ant_sw_mechanism2(btcoexist, true, false,
						   false, 0x18);
2271
		} else {
2272 2273 2274 2275
			btc8821a2ant_sw_mechanism1(btcoexist, true, true,
						   false, false);
			btc8821a2ant_sw_mechanism2(btcoexist, false, false,
						   false, 0x18);
2276 2277 2278
		}
	} else {
		/* fw mechanism */
2279
		btc8821a2ant_tdma_dur_adj(btcoexist, true, true, 2);
2280 2281 2282 2283

		/* sw mechanism */
		if ((wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
		    (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
2284 2285 2286 2287
			btc8821a2ant_sw_mechanism1(btcoexist, false, true,
						   false, false);
			btc8821a2ant_sw_mechanism2(btcoexist, true, false,
						   false, 0x18);
2288
		} else {
2289 2290 2291 2292
			btc8821a2ant_sw_mechanism1(btcoexist, false, true,
						   false, false);
			btc8821a2ant_sw_mechanism2(btcoexist, false, false,
						   false, 0x18);
2293 2294 2295 2296
		}
	}
}

2297
static void btc8821a2ant_run_coexist_mechanism(struct btc_coexist *btcoexist)
2298
{
2299
	struct rtl_priv *rtlpriv = btcoexist->adapter;
2300 2301
	bool wifi_under_5g = false;
	u8 algorithm = 0;
2302 2303

	if (btcoexist->manual_control) {
2304 2305
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], Manual control!!!\n");
2306 2307 2308 2309 2310 2311 2312
		return;
	}

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

	if (wifi_under_5g) {
2313 2314
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], RunCoexistMechanism(), run 5G coex setting!!<===\n");
2315
		btc8821a2ant_coex_under_5g(btcoexist);
2316 2317 2318
		return;
	}

2319
	algorithm = btc8821a2ant_action_algorithm(btcoexist);
2320 2321
	if (coex_sta->c2h_bt_inquiry_page &&
	    (BT_8821A_2ANT_COEX_ALGO_PANHS != algorithm)) {
2322 2323
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], BT is under inquiry/page scan !!\n");
2324
		btc8821a2ant_bt_inquiry_page(btcoexist);
2325 2326 2327 2328
		return;
	}

	coex_dm->cur_algorithm = algorithm;
2329 2330
	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
		 "[BTCoex], Algorithm = %d\n", coex_dm->cur_algorithm);
2331

2332
	if (btc8821a2ant_is_common_action(btcoexist)) {
2333 2334
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], Action 2-Ant common\n");
2335 2336 2337
		coex_dm->reset_tdma_adjust = true;
	} else {
		if (coex_dm->cur_algorithm != coex_dm->pre_algorithm) {
2338 2339
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "[BTCoex], pre_algorithm = %d, cur_algorithm = %d\n",
2340 2341
				    coex_dm->pre_algorithm,
				    coex_dm->cur_algorithm);
2342 2343 2344 2345
			coex_dm->reset_tdma_adjust = true;
		}
		switch (coex_dm->cur_algorithm) {
		case BT_8821A_2ANT_COEX_ALGO_SCO:
2346 2347
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "[BTCoex], Action 2-Ant, algorithm = SCO\n");
2348
			btc8821a2ant_action_sco(btcoexist);
2349 2350
			break;
		case BT_8821A_2ANT_COEX_ALGO_HID:
2351 2352
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "[BTCoex], Action 2-Ant, algorithm = HID\n");
2353
			btc8821a2ant_action_hid(btcoexist);
2354 2355
			break;
		case BT_8821A_2ANT_COEX_ALGO_A2DP:
2356 2357
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "[BTCoex], Action 2-Ant, algorithm = A2DP\n");
2358
			btc8821a2ant_action_a2dp(btcoexist);
2359 2360
			break;
		case BT_8821A_2ANT_COEX_ALGO_A2DP_PANHS:
2361 2362
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "[BTCoex], Action 2-Ant, algorithm = A2DP+PAN(HS)\n");
2363
			btc8821a2ant_action_a2dp_pan_hs(btcoexist);
2364 2365
			break;
		case BT_8821A_2ANT_COEX_ALGO_PANEDR:
2366 2367
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "[BTCoex], Action 2-Ant, algorithm = PAN(EDR)\n");
2368
			btc8821a2ant_action_pan_edr(btcoexist);
2369 2370
			break;
		case BT_8821A_2ANT_COEX_ALGO_PANHS:
2371 2372
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "[BTCoex], Action 2-Ant, algorithm = HS mode\n");
2373
			btc8821a2ant_action_pan_hs(btcoexist);
2374 2375
			break;
		case BT_8821A_2ANT_COEX_ALGO_PANEDR_A2DP:
2376 2377
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "[BTCoex], Action 2-Ant, algorithm = PAN+A2DP\n");
2378
			btc8821a2ant_action_pan_edr_a2dp(btcoexist);
2379 2380
			break;
		case BT_8821A_2ANT_COEX_ALGO_PANEDR_HID:
2381 2382
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "[BTCoex], Action 2-Ant, algorithm = PAN(EDR)+HID\n");
2383
			btc8821a2ant_action_pan_edr_hid(btcoexist);
2384 2385
			break;
		case BT_8821A_2ANT_COEX_ALGO_HID_A2DP_PANEDR:
2386 2387
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "[BTCoex], Action 2-Ant, algorithm = HID+A2DP+PAN\n");
2388 2389 2390
			btc8821a2ant_act_hid_a2dp_pan_edr(btcoexist);
			break;
		case BT_8821A_2ANT_COEX_ALGO_HID_A2DP:
2391 2392
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "[BTCoex], Action 2-Ant, algorithm = HID+A2DP\n");
2393
			btc8821a2ant_action_hid_a2dp(btcoexist);
2394 2395
			break;
		default:
2396 2397
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "[BTCoex], Action 2-Ant, algorithm = coexist All Off!!\n");
2398
			btc8821a2ant_coex_all_off(btcoexist);
2399 2400 2401 2402 2403 2404
			break;
		}
		coex_dm->pre_algorithm = coex_dm->cur_algorithm;
	}
}

2405 2406 2407 2408
/**************************************************************
 * extern function start with ex_btc8821a2ant_
 **************************************************************/
void ex_btc8821a2ant_init_hwconfig(struct btc_coexist *btcoexist)
2409
{
2410
	struct rtl_priv *rtlpriv = btcoexist->adapter;
2411 2412
	u8 u1tmp = 0;

2413 2414
	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
		 "[BTCoex], 2Ant Init HW Config!!\n");
2415 2416 2417 2418 2419 2420 2421 2422 2423 2424 2425 2426

	/* backup rf 0x1e value */
	coex_dm->bt_rf0x1e_backup =
		btcoexist->btc_get_rf_reg(btcoexist, BTC_RF_A, 0x1e, 0xfffff);

	/* 0x790[5:0] = 0x5 */
	u1tmp = btcoexist->btc_read_1byte(btcoexist, 0x790);
	u1tmp &= 0xc0;
	u1tmp |= 0x5;
	btcoexist->btc_write_1byte(btcoexist, 0x790, u1tmp);

	/*Antenna config */
2427
	btc8821a2ant_set_ant_path(btcoexist, BTC_ANT_WIFI_AT_MAIN, true, false);
2428 2429

	/* PTA parameter */
2430 2431
	btc8821a2ant_coex_table(btcoexist, FORCE_EXEC, 0x55555555, 0x55555555,
				0xffff, 0x3);
2432 2433 2434 2435 2436 2437 2438 2439

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

2440
void ex_btc8821a2ant_init_coex_dm(struct btc_coexist *btcoexist)
2441
{
2442 2443 2444 2445
	struct rtl_priv *rtlpriv = btcoexist->adapter;

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

2447
	btc8821a2ant_init_coex_dm(btcoexist);
2448 2449
}

2450
void ex_btc8821a2ant_display_coex_info(struct btc_coexist *btcoexist)
2451 2452 2453
{
	struct btc_board_info *board_info = &btcoexist->board_info;
	struct btc_stack_info *stack_info = &btcoexist->stack_info;
2454
	struct rtl_priv *rtlpriv = btcoexist->adapter;
2455 2456 2457 2458 2459 2460 2461 2462 2463
	u8 u1tmp[4], i, bt_info_ext, ps_tdma_case = 0;
	u32 u4tmp[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_dot_11_chnl, wifi_hs_chnl;
	u32 fw_ver = 0, bt_patch_ver = 0;

2464
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2465
		 "\r\n ============[BT Coexist info]============");
2466 2467

	if (!board_info->bt_exist) {
2468
		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n BT not exists !!!");
2469 2470 2471
		return;
	}

2472
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2473 2474
		 "\r\n %-35s = %d/ %d ", "Ant PG number/ Ant mechanism:",
		 board_info->pg_ant_num, board_info->btdm_ant_num);
2475 2476

	if (btcoexist->manual_control) {
2477
		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2478
			 "\r\n %-35s", "[Action Manual control]!!");
2479 2480
	}

2481
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2482
		 "\r\n %-35s = %s / %d", "BT stack/ hci ext ver",
2483 2484 2485 2486 2487
		   ((stack_info->profile_notified) ? "Yes" : "No"),
		   stack_info->hci_version);

	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);
2488
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2489
		 "\r\n %-35s = %d_%d/ 0x%x/ 0x%x(%d)",
2490 2491 2492 2493 2494 2495 2496 2497 2498 2499
		   "CoexVer/ FwVer/ PatchVer",
		   glcoex_ver_date_8821a_2ant, glcoex_ver_8821a_2ant,
		   fw_ver, bt_patch_ver, bt_patch_ver);

	btcoexist->btc_get(btcoexist,
		BTC_GET_BL_HS_OPERATION, &bt_hs_on);
	btcoexist->btc_get(btcoexist,
		BTC_GET_U1_WIFI_DOT11_CHNL, &wifi_dot_11_chnl);
	btcoexist->btc_get(btcoexist,
		BTC_GET_U1_WIFI_HS_CHNL, &wifi_hs_chnl);
2500
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2501
		 "\r\n %-35s = %d / %d(%d)",
2502 2503 2504
		   "Dot11 channel / HsMode(HsChnl)",
		   wifi_dot_11_chnl, bt_hs_on, wifi_hs_chnl);

2505
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2506
		 "\r\n %-35s = %3ph ",
2507
		   "H2C Wifi inform bt chnl Info",
2508
		   coex_dm->wifi_chnl_info);
2509 2510 2511

	btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi);
	btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi);
2512
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2513
		 "\r\n %-35s = %ld/ %ld", "Wifi rssi/ HS rssi",
2514 2515 2516 2517 2518
		   wifi_rssi, bt_hs_rssi);

	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);
2519
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2520
		 "\r\n %-35s = %d/ %d/ %d ", "Wifi link/ roam/ scan",
2521 2522 2523 2524 2525 2526 2527 2528 2529 2530
		   link, roam, scan);

	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);
2531
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2532
		 "\r\n %-35s = %s / %s/ %s ", "Wifi status",
2533 2534 2535 2536 2537 2538 2539
		   (wifi_under_5g ? "5G" : "2.4G"),
		   ((BTC_WIFI_BW_LEGACY == wifi_bw) ? "Legacy" :
		    (((BTC_WIFI_BW_HT40 == wifi_bw) ? "HT40" : "HT20"))),
		   ((!wifi_busy) ? "idle" :
		    ((BTC_WIFI_TRAFFIC_TX == wifi_traffic_dir) ?
		     "uplink" : "downlink")));

2540
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2541
		 "\r\n %-35s = [%s/ %d/ %d] ", "BT [status/ rssi/ retryCnt]",
2542 2543 2544 2545 2546 2547 2548
		   ((coex_sta->c2h_bt_inquiry_page) ? ("inquiry/page scan") :
		    ((BT_8821A_2ANT_BT_STATUS_IDLE == coex_dm->bt_status)
		     ? "idle" : ((BT_8821A_2ANT_BT_STATUS_CON_IDLE ==
		     coex_dm->bt_status) ? "connected-idle" : "busy"))),
		    coex_sta->bt_rssi, coex_sta->bt_retry_cnt);

	if (stack_info->profile_notified) {
2549
		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2550
			 "\r\n %-35s = %d / %d / %d / %d", "SCO/HID/PAN/A2DP",
2551 2552 2553 2554 2555 2556 2557 2558
			   stack_info->sco_exist, stack_info->hid_exist,
			   stack_info->pan_exist, stack_info->a2dp_exist);

		btcoexist->btc_disp_dbg_msg(btcoexist,
					    BTC_DBG_DISP_BT_LINK_INFO);
	}

	bt_info_ext = coex_sta->bt_info_ext;
2559
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %s",
2560
		 "BT Info A2DP rate",
2561 2562 2563 2564
		   (bt_info_ext&BIT0) ? "Basic rate" : "EDR rate");

	for (i = 0; i < BT_INFO_SRC_8821A_2ANT_MAX; i++) {
		if (coex_sta->bt_info_c2h_cnt[i]) {
2565
			RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2566 2567 2568 2569
				 "\r\n %-35s = %7ph(%d)",
				 glbt_info_src_8821a_2ant[i],
				 coex_sta->bt_info_c2h[i],
				 coex_sta->bt_info_c2h_cnt[i]);
2570 2571 2572
		}
	}

2573
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %s/%s",
2574 2575 2576
		 "PS state, IPS/LPS",
		 ((coex_sta->under_ips ? "IPS ON" : "IPS OFF")),
		 ((coex_sta->under_lps ? "LPS ON" : "LPS OFF")));
2577 2578 2579
	btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_FW_PWR_MODE_CMD);

	/* Sw mechanism*/
2580
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s",
2581
		 "============[Sw mechanism]============");
2582
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2583 2584 2585 2586
		 "\r\n %-35s = %d/ %d/ %d/ %d ",
		 "SM1[ShRf/ LpRA/ LimDig/ btLna]",
		 coex_dm->cur_rf_rx_lpf_shrink, coex_dm->cur_low_penalty_ra,
		 coex_dm->limited_dig, coex_dm->cur_bt_lna_constrain);
2587
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2588 2589 2590 2591
		 "\r\n %-35s = %d/ %d/ %d(0x%x) ",
		 "SM2[AgcT/ AdcB/ SwDacSwing(lvl)]",
		 coex_dm->cur_agc_table_en, coex_dm->cur_adc_back_off,
		 coex_dm->cur_dac_swing_on, coex_dm->cur_dac_swing_lvl);
2592 2593

	/* Fw mechanism*/
2594
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s",
2595
		 "============[Fw mechanism]============");
2596 2597 2598

	if (!btcoexist->manual_control) {
		ps_tdma_case = coex_dm->cur_ps_tdma;
2599
		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2600 2601 2602
			 "\r\n %-35s = %5ph case-%d",
			 "PS TDMA",
			 coex_dm->ps_tdma_para, ps_tdma_case);
2603

2604
		RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2605
			 "\r\n %-35s = %d/ %d ", "DecBtPwr/ IgnWlanAct",
2606
			 coex_dm->cur_dec_bt_pwr_lvl,
2607
			 coex_dm->cur_ignore_wlan_act);
2608 2609 2610
	}

	/* Hw setting*/
2611
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2612
		 "\r\n %-35s", "============[Hw setting]============");
2613

2614
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
2615 2616
		 "\r\n %-35s = 0x%x", "RF-A, 0x1e initVal",
		 coex_dm->bt_rf0x1e_backup);
2617 2618 2619

	u1tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x778);
	u1tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x6cc);
2620
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x ",
2621 2622
		 "0x778 (W_Act)/ 0x6cc (CoTab Sel)",
		 u1tmp[0], u1tmp[1]);
2623 2624 2625

	u1tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x8db);
	u1tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0xc5b);
2626
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x",
2627 2628
		 "0x8db(ADC)/0xc5b[29:25](DAC)",
		 ((u1tmp[0] & 0x60) >> 5), ((u1tmp[1] & 0x3e) >> 1));
2629 2630

	u4tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xcb4);
2631
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x",
2632 2633
		 "0xcb4[7:0](ctrl)/ 0xcb4[29:28](val)",
		 u4tmp[0] & 0xff, ((u4tmp[0] & 0x30000000) >> 28));
2634 2635 2636 2637

	u1tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x40);
	u4tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x4c);
	u4tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x974);
2638
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
2639 2640
		 "0x40/ 0x4c[24:23]/ 0x974",
		 u1tmp[0], ((u4tmp[0] & 0x01800000) >> 23), u4tmp[1]);
2641 2642 2643

	u4tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x550);
	u1tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x522);
2644
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x",
2645 2646
		 "0x550(bcn ctrl)/0x522",
		 u4tmp[0], u1tmp[0]);
2647 2648 2649

	u4tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xc50);
	u1tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0xa0a);
2650
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x",
2651 2652
		 "0xc50(DIG)/0xa0a(CCK-TH)",
		 u4tmp[0], u1tmp[0]);
2653 2654 2655 2656

	u4tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xf48);
	u1tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0xa5b);
	u1tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0xa5c);
2657
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x",
2658 2659
		 "OFDM-FA/ CCK-FA",
		 u4tmp[0], (u1tmp[0] << 8) + u1tmp[1]);
2660 2661 2662 2663

	u4tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x6c0);
	u4tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x6c4);
	u4tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x6c8);
2664
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
2665 2666
		 "0x6c0/0x6c4/0x6c8",
		 u4tmp[0], u4tmp[1], u4tmp[2]);
2667

2668
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d",
2669 2670
		 "0x770 (hi-pri Rx/Tx)",
		 coex_sta->high_priority_rx, coex_sta->high_priority_tx);
2671
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = %d/ %d",
2672 2673 2674 2675 2676
		   "0x774(low-pri Rx/Tx)",
		   coex_sta->low_priority_rx, coex_sta->low_priority_tx);

	/* Tx mgnt queue hang or not, 0x41b should = 0xf, ex: 0xd ==>hang*/
	u1tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x41b);
2677
	RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "\r\n %-35s = 0x%x",
2678 2679
		 "0x41b (mgntQ hang chk == 0xf)",
		 u1tmp[0]);
2680 2681 2682 2683

	btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_COEX_STATISTICS);
}

2684
void ex_btc8821a2ant_ips_notify(struct btc_coexist *btcoexist, u8 type)
2685
{
2686 2687
	struct rtl_priv *rtlpriv = btcoexist->adapter;

2688
	if (BTC_IPS_ENTER == type) {
2689 2690
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], IPS ENTER notify\n");
2691
		coex_sta->under_ips = true;
2692
		btc8821a2ant_coex_all_off(btcoexist);
2693
	} else if (BTC_IPS_LEAVE == type) {
2694 2695
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], IPS LEAVE notify\n");
2696 2697 2698 2699
		coex_sta->under_ips = false;
	}
}

2700
void ex_btc8821a2ant_lps_notify(struct btc_coexist *btcoexist, u8 type)
2701
{
2702 2703
	struct rtl_priv *rtlpriv = btcoexist->adapter;

2704
	if (BTC_LPS_ENABLE == type) {
2705 2706
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], LPS ENABLE notify\n");
2707 2708
		coex_sta->under_lps = true;
	} else if (BTC_LPS_DISABLE == type) {
2709 2710
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], LPS DISABLE notify\n");
2711 2712 2713 2714
		coex_sta->under_lps = false;
	}
}

2715
void ex_btc8821a2ant_scan_notify(struct btc_coexist *btcoexist, u8 type)
2716
{
2717 2718
	struct rtl_priv *rtlpriv = btcoexist->adapter;

2719
	if (BTC_SCAN_START == type) {
2720 2721
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], SCAN START notify\n");
2722
	} else if (BTC_SCAN_FINISH == type) {
2723 2724
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], SCAN FINISH notify\n");
2725 2726 2727
	}
}

2728
void ex_btc8821a2ant_connect_notify(struct btc_coexist *btcoexist, u8 type)
2729
{
2730 2731
	struct rtl_priv *rtlpriv = btcoexist->adapter;

2732
	if (BTC_ASSOCIATE_START == type) {
2733 2734
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], CONNECT START notify\n");
2735
	} else if (BTC_ASSOCIATE_FINISH == type) {
2736 2737
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], CONNECT FINISH notify\n");
2738 2739 2740
	}
}

2741 2742
void ex_btc8821a2ant_media_status_notify(struct btc_coexist *btcoexist,
					 u8 type)
2743
{
2744
	struct rtl_priv *rtlpriv = btcoexist->adapter;
2745 2746 2747
	u8 h2c_parameter[3] = {0};
	u32 wifi_bw;
	u8 wifi_central_chnl;
2748 2749

	if (BTC_MEDIA_CONNECT == type) {
2750 2751
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], MEDIA connect notify\n");
2752
	} else {
2753 2754
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], MEDIA disconnect notify\n");
2755 2756
	}

2757
	/* only 2.4G we need to inform bt the chnl mask */
2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774
	btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_CENTRAL_CHNL,
			   &wifi_central_chnl);
	if ((BTC_MEDIA_CONNECT == type) &&
	    (wifi_central_chnl <= 14)) {
		h2c_parameter[0] = 0x1;
		h2c_parameter[1] = wifi_central_chnl;
		btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
		if (BTC_WIFI_BW_HT40 == wifi_bw)
			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];

2775 2776 2777 2778 2779
	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]);
2780 2781 2782 2783

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

2784 2785 2786
void ex_btc8821a2ant_special_packet_notify(struct btc_coexist *btcoexist,
					   u8 type)
{
2787 2788
	struct rtl_priv *rtlpriv = btcoexist->adapter;

2789
	if (type == BTC_PACKET_DHCP) {
2790 2791
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], DHCP Packet notify\n");
2792 2793 2794
	}
}

2795 2796
void ex_btc8821a2ant_bt_info_notify(struct btc_coexist *btcoexist,
				    u8 *tmp_buf, u8 length)
2797
{
2798
	struct rtl_priv *rtlpriv = btcoexist->adapter;
2799 2800 2801 2802
	u8 bt_info = 0;
	u8 i, rsp_source = 0;
	bool bt_busy = false, limited_dig = false;
	bool wifi_connected = false, bt_hs_on = false;
2803 2804 2805

	coex_sta->c2h_bt_info_req_sent = false;

2806
	rsp_source = tmp_buf[0] & 0xf;
2807 2808 2809 2810
	if (rsp_source >= BT_INFO_SRC_8821A_2ANT_MAX)
		rsp_source = BT_INFO_SRC_8821A_2ANT_WIFI_FW;
	coex_sta->bt_info_c2h_cnt[rsp_source]++;

2811 2812
	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
		 "[BTCoex], Bt info[%d], length = %d, hex data = [",
2813
		      rsp_source, length);
2814 2815 2816 2817
	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];
2818
		if (i == length - 1) {
2819 2820
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "0x%02x]\n", tmp_buf[i]);
2821
		} else {
2822 2823
			RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
				 "0x%02x, ", tmp_buf[i]);
2824 2825 2826 2827
		}
	}

	if (BT_INFO_SRC_8821A_2ANT_WIFI_FW != rsp_source) {
2828 2829
		/* [3:0] */
		coex_sta->bt_retry_cnt =
2830 2831 2832 2833 2834 2835 2836 2837
			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];

2838 2839 2840
		/* Here we need to resend some wifi info to BT
		 * because bt is reset and loss of the info
		 */
2841 2842 2843 2844
		if ((coex_sta->bt_info_ext & BIT1)) {
			btcoexist->btc_get(btcoexist,
				BTC_GET_BL_WIFI_CONNECTED, &wifi_connected);
			if (wifi_connected) {
2845
				ex_btc8821a2ant_media_status_notify(btcoexist,
2846 2847
					BTC_MEDIA_CONNECT);
			} else {
2848
				ex_btc8821a2ant_media_status_notify(btcoexist,
2849 2850 2851 2852 2853 2854
					BTC_MEDIA_DISCONNECT);
			}

		}

		if ((coex_sta->bt_info_ext & BIT3)) {
2855 2856
			btc8821a2ant_ignore_wlan_act(btcoexist,
						     FORCE_EXEC, false);
2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901
		} else {
			/* BT already NOT ignore Wlan active, do nothing here.*/
		}
	}

	btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
	/* check BIT2 first ==> check if bt is under inquiry or page scan*/
	if (bt_info & BT_INFO_8821A_2ANT_B_INQ_PAGE) {
		coex_sta->c2h_bt_inquiry_page = true;
		coex_dm->bt_status = BT_8821A_2ANT_BT_STATUS_NON_IDLE;
	} else {
		coex_sta->c2h_bt_inquiry_page = false;
		if (bt_info == 0x1) {
			/* connection exists but not busy*/
			coex_sta->bt_link_exist = true;
			coex_dm->bt_status = BT_8821A_2ANT_BT_STATUS_CON_IDLE;
		} else if (bt_info & BT_INFO_8821A_2ANT_B_CONNECTION) {
			/* connection exists and some link is busy*/
			coex_sta->bt_link_exist = true;
			if (bt_info & BT_INFO_8821A_2ANT_B_FTP)
				coex_sta->pan_exist = true;
			else
				coex_sta->pan_exist = false;
			if (bt_info & BT_INFO_8821A_2ANT_B_A2DP)
				coex_sta->a2dp_exist = true;
			else
				coex_sta->a2dp_exist = false;
			if (bt_info & BT_INFO_8821A_2ANT_B_HID)
				coex_sta->hid_exist = true;
			else
				coex_sta->hid_exist = false;
			if (bt_info & BT_INFO_8821A_2ANT_B_SCO_ESCO)
				coex_sta->sco_exist = true;
			else
				coex_sta->sco_exist = false;
			coex_dm->bt_status = BT_8821A_2ANT_BT_STATUS_NON_IDLE;
		} else {
			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;
			coex_dm->bt_status = BT_8821A_2ANT_BT_STATUS_IDLE;
		}

2902
		btc8821a2ant_update_bt_link_info(btcoexist);
2903 2904 2905 2906 2907 2908 2909 2910 2911 2912 2913 2914 2915 2916 2917 2918
	}

	if (BT_8821A_2ANT_BT_STATUS_NON_IDLE == coex_dm->bt_status)
		bt_busy = true;
	else
		bt_busy = false;
	btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bt_busy);

	if (BT_8821A_2ANT_BT_STATUS_IDLE != coex_dm->bt_status)
		limited_dig = true;
	else
		limited_dig = false;
	coex_dm->limited_dig = limited_dig;
	btcoexist->btc_set(btcoexist,
		BTC_SET_BL_BT_LIMITED_DIG, &limited_dig);

2919
	btc8821a2ant_run_coexist_mechanism(btcoexist);
2920 2921
}

2922
void ex_btc8821a2ant_halt_notify(struct btc_coexist *btcoexist)
2923
{
2924 2925 2926 2927
	struct rtl_priv *rtlpriv = btcoexist->adapter;

	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
		 "[BTCoex], Halt notify\n");
2928

2929 2930
	btc8821a2ant_ignore_wlan_act(btcoexist, FORCE_EXEC, true);
	ex_btc8821a2ant_media_status_notify(btcoexist, BTC_MEDIA_DISCONNECT);
2931 2932
}

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

2941 2942
	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
		 "[BTCoex], ==========================Periodical===========================\n");
2943 2944 2945

	if (dis_ver_info_cnt <= 5) {
		dis_ver_info_cnt += 1;
2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956
		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",
			 board_info->pg_ant_num,
			 board_info->btdm_ant_num,
			 board_info->btdm_ant_pos);
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], BT stack/ hci ext ver = %s / %d\n",
			 stack_info->profile_notified ? "Yes" : "No",
			 stack_info->hci_version);
2957 2958 2959
		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);
2960 2961 2962 2963 2964 2965
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], CoexVer/ FwVer/ PatchVer = %d_%x/ 0x%x/ 0x%x(%d)\n",
			 glcoex_ver_date_8821a_2ant, glcoex_ver_8821a_2ant,
			 fw_ver, bt_patch_ver, bt_patch_ver);
		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
			 "[BTCoex], ****************************************************************\n");
2966 2967
	}

2968 2969
	btc8821a2ant_query_bt_info(btcoexist);
	btc8821a2ant_monitor_bt_ctr(btcoexist);
2970
	btc8821a2ant_monitor_wifi_ctr(btcoexist);
2971
}