1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2013 Realtek Corporation. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * The full GNU General Public License is included in this distribution in the
15  * file called LICENSE.
16  *
17  * Contact Information:
18  * wlanfae <wlanfae@realtek.com>
19  * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20  * Hsinchu 300, Taiwan.
21  *
22  * Larry Finger <Larry.Finger@lwfinger.net>
23  *
24  ******************************************************************************/
25 
26 #include "halbt_precomp.h"
27 
28 /***********************************************
29  *		Global variables
30  ***********************************************/
31 
32 struct btc_coexist gl_bt_coexist;
33 
34 u32 btc_dbg_type[BTC_MSG_MAX];
35 
36 /***************************************************
37  *		Debug related function
38  ***************************************************/
39 
40 const char *const gl_btc_wifi_bw_string[] = {
41 	"11bg",
42 	"HT20",
43 	"HT40",
44 	"HT80",
45 	"HT160"
46 };
47 
48 const char *const gl_btc_wifi_freq_string[] = {
49 	"2.4G",
50 	"5G"
51 };
52 
53 static bool halbtc_is_bt_coexist_available(struct btc_coexist *btcoexist)
54 {
55 	if (!btcoexist->binded || NULL == btcoexist->adapter)
56 		return false;
57 
58 	return true;
59 }
60 
61 static bool halbtc_is_wifi_busy(struct rtl_priv *rtlpriv)
62 {
63 	if (rtlpriv->link_info.busytraffic)
64 		return true;
65 	else
66 		return false;
67 }
68 
69 static void halbtc_dbg_init(void)
70 {
71 }
72 
73 /***************************************************
74  *		helper function
75  ***************************************************/
76 static bool is_any_client_connect_to_ap(struct btc_coexist *btcoexist)
77 {
78 	struct rtl_priv *rtlpriv = btcoexist->adapter;
79 	struct rtl_mac *mac = rtl_mac(rtlpriv);
80 	struct rtl_sta_info *drv_priv;
81 	u8 cnt = 0;
82 
83 	if (mac->opmode == NL80211_IFTYPE_ADHOC ||
84 	    mac->opmode == NL80211_IFTYPE_MESH_POINT ||
85 	    mac->opmode == NL80211_IFTYPE_AP) {
86 		if (in_interrupt() > 0) {
87 			list_for_each_entry(drv_priv, &rtlpriv->entry_list,
88 					    list) {
89 				cnt++;
90 			}
91 		} else {
92 			spin_lock_bh(&rtlpriv->locks.entry_list_lock);
93 			list_for_each_entry(drv_priv, &rtlpriv->entry_list,
94 					    list) {
95 				cnt++;
96 			}
97 			spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
98 		}
99 	}
100 	if (cnt > 0)
101 		return true;
102 	else
103 		return false;
104 }
105 
106 static bool halbtc_is_bt40(struct rtl_priv *adapter)
107 {
108 	struct rtl_priv *rtlpriv = adapter;
109 	struct rtl_phy *rtlphy = &(rtlpriv->phy);
110 	bool is_ht40 = true;
111 	enum ht_channel_width bw = rtlphy->current_chan_bw;
112 
113 	if (bw == HT_CHANNEL_WIDTH_20)
114 		is_ht40 = false;
115 	else if (bw == HT_CHANNEL_WIDTH_20_40)
116 		is_ht40 = true;
117 
118 	return is_ht40;
119 }
120 
121 static bool halbtc_legacy(struct rtl_priv *adapter)
122 {
123 	struct rtl_priv *rtlpriv = adapter;
124 	struct rtl_mac *mac = rtl_mac(rtlpriv);
125 
126 	bool is_legacy = false;
127 
128 	if ((mac->mode == WIRELESS_MODE_B) || (mac->mode == WIRELESS_MODE_G))
129 		is_legacy = true;
130 
131 	return is_legacy;
132 }
133 
134 bool halbtc_is_wifi_uplink(struct rtl_priv *adapter)
135 {
136 	struct rtl_priv *rtlpriv = adapter;
137 
138 	if (rtlpriv->link_info.tx_busy_traffic)
139 		return true;
140 	else
141 		return false;
142 }
143 
144 static u32 halbtc_get_wifi_bw(struct btc_coexist *btcoexist)
145 {
146 	struct rtl_priv *rtlpriv =
147 		(struct rtl_priv *)btcoexist->adapter;
148 	u32 wifi_bw = BTC_WIFI_BW_HT20;
149 
150 	if (halbtc_is_bt40(rtlpriv)) {
151 		wifi_bw = BTC_WIFI_BW_HT40;
152 	} else {
153 		if (halbtc_legacy(rtlpriv))
154 			wifi_bw = BTC_WIFI_BW_LEGACY;
155 		else
156 			wifi_bw = BTC_WIFI_BW_HT20;
157 	}
158 	return wifi_bw;
159 }
160 
161 static u8 halbtc_get_wifi_central_chnl(struct btc_coexist *btcoexist)
162 {
163 	struct rtl_priv *rtlpriv = btcoexist->adapter;
164 	struct rtl_phy	*rtlphy = &(rtlpriv->phy);
165 	u8 chnl = 1;
166 
167 	if (rtlphy->current_channel != 0)
168 		chnl = rtlphy->current_channel;
169 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
170 		 "static halbtc_get_wifi_central_chnl:%d\n", chnl);
171 	return chnl;
172 }
173 
174 u8 rtl_get_hwpg_single_ant_path(struct rtl_priv *rtlpriv)
175 {
176 	struct rtl_mod_params *mod_params = rtlpriv->cfg->mod_params;
177 
178 	/* override ant_num / ant_path */
179 	if (mod_params->ant_sel) {
180 		rtlpriv->btcoexist.btc_info.ant_num =
181 			(mod_params->ant_sel == 1 ? ANT_X2 : ANT_X1);
182 
183 		rtlpriv->btcoexist.btc_info.single_ant_path =
184 			(mod_params->ant_sel == 1 ? 0 : 1);
185 	}
186 	return rtlpriv->btcoexist.btc_info.single_ant_path;
187 }
188 
189 u8 rtl_get_hwpg_bt_type(struct rtl_priv *rtlpriv)
190 {
191 	return rtlpriv->btcoexist.btc_info.bt_type;
192 }
193 
194 u8 rtl_get_hwpg_ant_num(struct rtl_priv *rtlpriv)
195 {
196 	struct rtl_mod_params *mod_params = rtlpriv->cfg->mod_params;
197 	u8 num;
198 
199 	if (rtlpriv->btcoexist.btc_info.ant_num == ANT_X2)
200 		num = 2;
201 	else
202 		num = 1;
203 
204 	/* override ant_num / ant_path */
205 	if (mod_params->ant_sel)
206 		num = (mod_params->ant_sel == 1 ? ANT_X2 : ANT_X1) + 1;
207 
208 	return num;
209 }
210 
211 u8 rtl_get_hwpg_package_type(struct rtl_priv *rtlpriv)
212 {
213 	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
214 
215 	return rtlhal->package_type;
216 }
217 
218 static void halbtc_leave_lps(struct btc_coexist *btcoexist)
219 {
220 	struct rtl_priv *rtlpriv;
221 	struct rtl_ps_ctl *ppsc;
222 	bool ap_enable = false;
223 
224 	rtlpriv = btcoexist->adapter;
225 	ppsc = rtl_psc(rtlpriv);
226 
227 	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE,
228 			   &ap_enable);
229 
230 	if (ap_enable) {
231 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
232 			 "%s()<--dont leave lps under AP mode\n", __func__);
233 		return;
234 	}
235 
236 	btcoexist->bt_info.bt_ctrl_lps = true;
237 	btcoexist->bt_info.bt_lps_on = false;
238 	rtl_lps_leave(rtlpriv->mac80211.hw);
239 }
240 
241 static void halbtc_enter_lps(struct btc_coexist *btcoexist)
242 {
243 	struct rtl_priv *rtlpriv;
244 	struct rtl_ps_ctl *ppsc;
245 	bool ap_enable = false;
246 
247 	rtlpriv = btcoexist->adapter;
248 	ppsc = rtl_psc(rtlpriv);
249 
250 	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE,
251 			   &ap_enable);
252 
253 	if (ap_enable) {
254 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
255 			 "%s()<--dont enter lps under AP mode\n", __func__);
256 		return;
257 	}
258 
259 	btcoexist->bt_info.bt_ctrl_lps = true;
260 	btcoexist->bt_info.bt_lps_on = true;
261 	rtl_lps_enter(rtlpriv->mac80211.hw);
262 }
263 
264 static void halbtc_normal_lps(struct btc_coexist *btcoexist)
265 {
266 	struct rtl_priv *rtlpriv;
267 
268 	rtlpriv = btcoexist->adapter;
269 
270 	if (btcoexist->bt_info.bt_ctrl_lps) {
271 		btcoexist->bt_info.bt_lps_on = false;
272 		rtl_lps_leave(rtlpriv->mac80211.hw);
273 		btcoexist->bt_info.bt_ctrl_lps = false;
274 	}
275 }
276 
277 static void halbtc_leave_low_power(struct btc_coexist *btcoexist)
278 {
279 }
280 
281 static void halbtc_normal_low_power(struct btc_coexist *btcoexist)
282 {
283 }
284 
285 static void halbtc_disable_low_power(struct btc_coexist *btcoexist,
286 				     bool low_pwr_disable)
287 {
288 	/* TODO: original/leave 32k low power */
289 	btcoexist->bt_info.bt_disable_low_pwr = low_pwr_disable;
290 }
291 
292 static void halbtc_aggregation_check(struct btc_coexist *btcoexist)
293 {
294 	bool need_to_act = false;
295 	static unsigned long pre_time;
296 	unsigned long cur_time = 0;
297 	struct rtl_priv *rtlpriv = btcoexist->adapter;
298 
299 	/* To void continuous deleteBA=>addBA=>deleteBA=>addBA
300 	 * This function is not allowed to continuous called
301 	 * It can only be called after 8 seconds
302 	 */
303 
304 	cur_time = jiffies;
305 	if (jiffies_to_msecs(cur_time - pre_time) <= 8000) {
306 		/* over 8 seconds you can execute this function again. */
307 		return;
308 	}
309 	pre_time = cur_time;
310 
311 	if (btcoexist->bt_info.reject_agg_pkt) {
312 		need_to_act = true;
313 		btcoexist->bt_info.pre_reject_agg_pkt =
314 			btcoexist->bt_info.reject_agg_pkt;
315 	} else {
316 		if (btcoexist->bt_info.pre_reject_agg_pkt) {
317 			need_to_act = true;
318 			btcoexist->bt_info.pre_reject_agg_pkt =
319 				btcoexist->bt_info.reject_agg_pkt;
320 		}
321 
322 		if (btcoexist->bt_info.pre_bt_ctrl_agg_buf_size !=
323 		    btcoexist->bt_info.bt_ctrl_agg_buf_size) {
324 			need_to_act = true;
325 			btcoexist->bt_info.pre_bt_ctrl_agg_buf_size =
326 				btcoexist->bt_info.bt_ctrl_agg_buf_size;
327 		}
328 
329 		if (btcoexist->bt_info.bt_ctrl_agg_buf_size) {
330 			if (btcoexist->bt_info.pre_agg_buf_size !=
331 			    btcoexist->bt_info.agg_buf_size) {
332 				need_to_act = true;
333 			}
334 			btcoexist->bt_info.pre_agg_buf_size =
335 				btcoexist->bt_info.agg_buf_size;
336 		}
337 
338 		if (need_to_act)
339 			rtl_rx_ampdu_apply(rtlpriv);
340 	}
341 }
342 
343 static u32 halbtc_get_bt_patch_version(struct btc_coexist *btcoexist)
344 {
345 	struct rtl_priv *rtlpriv = btcoexist->adapter;
346 	u8 cmd_buffer[4] = {0};
347 	u8 oper_ver = 0;
348 	u8 req_num = 0x0E;
349 
350 	if (btcoexist->bt_info.bt_real_fw_ver)
351 		goto label_done;
352 
353 	cmd_buffer[0] |= (oper_ver & 0x0f);	/* Set OperVer */
354 	cmd_buffer[0] |= ((req_num << 4) & 0xf0);	/* Set ReqNum */
355 	cmd_buffer[1] = 0; /* BT_OP_GET_BT_VERSION = 0 */
356 	rtlpriv->cfg->ops->fill_h2c_cmd(rtlpriv->mac80211.hw, 0x67, 4,
357 					&cmd_buffer[0]);
358 
359 label_done:
360 	return btcoexist->bt_info.bt_real_fw_ver;
361 }
362 
363 u32 halbtc_get_wifi_link_status(struct btc_coexist *btcoexist)
364 {
365 	/* return value:
366 	 * [31:16] => connected port number
367 	 * [15:0]  => port connected bit define
368 	 */
369 	struct rtl_priv *rtlpriv = btcoexist->adapter;
370 	struct rtl_mac *mac = rtl_mac(rtlpriv);
371 	u32 ret_val = 0;
372 	u32 port_connected_status = 0, num_of_connected_port = 0;
373 
374 	if (mac->opmode == NL80211_IFTYPE_STATION &&
375 	    mac->link_state >= MAC80211_LINKED) {
376 		port_connected_status |= WIFI_STA_CONNECTED;
377 		num_of_connected_port++;
378 	}
379 	/* AP & ADHOC & MESH */
380 	if (is_any_client_connect_to_ap(btcoexist)) {
381 		port_connected_status |= WIFI_AP_CONNECTED;
382 		num_of_connected_port++;
383 	}
384 	/* TODO: P2P Connected Status */
385 
386 	ret_val = (num_of_connected_port << 16) | port_connected_status;
387 
388 	return ret_val;
389 }
390 
391 static s32 halbtc_get_wifi_rssi(struct rtl_priv *rtlpriv)
392 {
393 	int undec_sm_pwdb = 0;
394 
395 	if (rtlpriv->mac80211.link_state >= MAC80211_LINKED)
396 		undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb;
397 	else /* associated entry pwdb */
398 		undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb;
399 	return undec_sm_pwdb;
400 }
401 
402 static bool halbtc_get(void *void_btcoexist, u8 get_type, void *out_buf)
403 {
404 	struct btc_coexist *btcoexist = (struct btc_coexist *)void_btcoexist;
405 	struct rtl_priv *rtlpriv = btcoexist->adapter;
406 	struct rtl_phy *rtlphy = &(rtlpriv->phy);
407 	struct rtl_mac *mac = rtl_mac(rtlpriv);
408 	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
409 	bool *bool_tmp = (bool *)out_buf;
410 	int *s32_tmp = (int *)out_buf;
411 	u32 *u32_tmp = (u32 *)out_buf;
412 	u8 *u8_tmp = (u8 *)out_buf;
413 	bool tmp = false;
414 	bool ret = true;
415 
416 	if (!halbtc_is_bt_coexist_available(btcoexist))
417 		return false;
418 
419 	switch (get_type) {
420 	case BTC_GET_BL_HS_OPERATION:
421 		*bool_tmp = false;
422 		ret = false;
423 		break;
424 	case BTC_GET_BL_HS_CONNECTING:
425 		*bool_tmp = false;
426 		ret = false;
427 		break;
428 	case BTC_GET_BL_WIFI_CONNECTED:
429 		if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_STATION &&
430 		    rtlpriv->mac80211.link_state >= MAC80211_LINKED)
431 			tmp = true;
432 		if (is_any_client_connect_to_ap(btcoexist))
433 			tmp = true;
434 		*bool_tmp = tmp;
435 		break;
436 	case BTC_GET_BL_WIFI_BUSY:
437 		if (halbtc_is_wifi_busy(rtlpriv))
438 			*bool_tmp = true;
439 		else
440 			*bool_tmp = false;
441 		break;
442 	case BTC_GET_BL_WIFI_SCAN:
443 		if (mac->act_scanning)
444 			*bool_tmp = true;
445 		else
446 			*bool_tmp = false;
447 		break;
448 	case BTC_GET_BL_WIFI_LINK:
449 		if (mac->link_state == MAC80211_LINKING)
450 			*bool_tmp = true;
451 		else
452 			*bool_tmp = false;
453 		break;
454 	case BTC_GET_BL_WIFI_ROAM:
455 		if (mac->link_state == MAC80211_LINKING)
456 			*bool_tmp = true;
457 		else
458 			*bool_tmp = false;
459 		break;
460 	case BTC_GET_BL_WIFI_4_WAY_PROGRESS:
461 		*bool_tmp = rtlpriv->btcoexist.btc_info.in_4way;
462 		break;
463 	case BTC_GET_BL_WIFI_UNDER_5G:
464 		if (rtlhal->current_bandtype == BAND_ON_5G)
465 			*bool_tmp = true;
466 		else
467 			*bool_tmp = false;
468 		break;
469 	case BTC_GET_BL_WIFI_AP_MODE_ENABLE:
470 		if (mac->opmode == NL80211_IFTYPE_AP)
471 			*bool_tmp = true;
472 		else
473 			*bool_tmp = false;
474 		break;
475 	case BTC_GET_BL_WIFI_ENABLE_ENCRYPTION:
476 		if (NO_ENCRYPTION == rtlpriv->sec.pairwise_enc_algorithm)
477 			*bool_tmp = false;
478 		else
479 			*bool_tmp = true;
480 		break;
481 	case BTC_GET_BL_WIFI_UNDER_B_MODE:
482 		if (rtlpriv->mac80211.mode == WIRELESS_MODE_B)
483 			*bool_tmp = true;
484 		else
485 			*bool_tmp = false;
486 		break;
487 	case BTC_GET_BL_EXT_SWITCH:
488 		*bool_tmp = false;
489 		break;
490 	case BTC_GET_BL_WIFI_IS_IN_MP_MODE:
491 		*bool_tmp = false;
492 		break;
493 	case BTC_GET_BL_IS_ASUS_8723B:
494 		*bool_tmp = false;
495 		break;
496 	case BTC_GET_S4_WIFI_RSSI:
497 		*s32_tmp = halbtc_get_wifi_rssi(rtlpriv);
498 		break;
499 	case BTC_GET_S4_HS_RSSI:
500 		*s32_tmp = 0;
501 		ret = false;
502 		break;
503 	case BTC_GET_U4_WIFI_BW:
504 		*u32_tmp = halbtc_get_wifi_bw(btcoexist);
505 		break;
506 	case BTC_GET_U4_WIFI_TRAFFIC_DIRECTION:
507 		if (halbtc_is_wifi_uplink(rtlpriv))
508 			*u32_tmp = BTC_WIFI_TRAFFIC_TX;
509 		else
510 			*u32_tmp = BTC_WIFI_TRAFFIC_RX;
511 		break;
512 	case BTC_GET_U4_WIFI_FW_VER:
513 		*u32_tmp = (rtlhal->fw_version << 16) | rtlhal->fw_subversion;
514 		break;
515 	case BTC_GET_U4_WIFI_LINK_STATUS:
516 		*u32_tmp = halbtc_get_wifi_link_status(btcoexist);
517 		break;
518 	case BTC_GET_U4_BT_PATCH_VER:
519 		*u32_tmp = halbtc_get_bt_patch_version(btcoexist);
520 		break;
521 	case BTC_GET_U4_VENDOR:
522 		*u32_tmp = BTC_VENDOR_OTHER;
523 		break;
524 	case BTC_GET_U1_WIFI_DOT11_CHNL:
525 		*u8_tmp = rtlphy->current_channel;
526 		break;
527 	case BTC_GET_U1_WIFI_CENTRAL_CHNL:
528 		*u8_tmp = halbtc_get_wifi_central_chnl(btcoexist);
529 		break;
530 	case BTC_GET_U1_WIFI_HS_CHNL:
531 		*u8_tmp = 0;
532 		ret = false;
533 		break;
534 	case BTC_GET_U1_AP_NUM:
535 		*u8_tmp = rtlpriv->btcoexist.btc_info.ap_num;
536 		break;
537 	case BTC_GET_U1_ANT_TYPE:
538 		*u8_tmp = (u8)BTC_ANT_TYPE_0;
539 		break;
540 	case BTC_GET_U1_IOT_PEER:
541 		*u8_tmp = 0;
542 		break;
543 
544 		/************* 1Ant **************/
545 	case BTC_GET_U1_LPS_MODE:
546 		*u8_tmp = btcoexist->pwr_mode_val[0];
547 		break;
548 
549 	default:
550 		ret = false;
551 		break;
552 	}
553 
554 	return ret;
555 }
556 
557 static bool halbtc_set(void *void_btcoexist, u8 set_type, void *in_buf)
558 {
559 	struct btc_coexist *btcoexist = (struct btc_coexist *)void_btcoexist;
560 	bool *bool_tmp = (bool *)in_buf;
561 	u8 *u8_tmp = (u8 *)in_buf;
562 	u32 *u32_tmp = (u32 *)in_buf;
563 	bool ret = true;
564 
565 	if (!halbtc_is_bt_coexist_available(btcoexist))
566 		return false;
567 
568 	switch (set_type) {
569 	/* set some bool type variables. */
570 	case BTC_SET_BL_BT_DISABLE:
571 		btcoexist->bt_info.bt_disabled = *bool_tmp;
572 		break;
573 	case BTC_SET_BL_BT_TRAFFIC_BUSY:
574 		btcoexist->bt_info.bt_busy = *bool_tmp;
575 		break;
576 	case BTC_SET_BL_BT_LIMITED_DIG:
577 		btcoexist->bt_info.limited_dig = *bool_tmp;
578 		break;
579 	case BTC_SET_BL_FORCE_TO_ROAM:
580 		btcoexist->bt_info.force_to_roam = *bool_tmp;
581 		break;
582 	case BTC_SET_BL_TO_REJ_AP_AGG_PKT:
583 		btcoexist->bt_info.reject_agg_pkt = *bool_tmp;
584 		break;
585 	case BTC_SET_BL_BT_CTRL_AGG_SIZE:
586 		btcoexist->bt_info.bt_ctrl_agg_buf_size = *bool_tmp;
587 		break;
588 	case BTC_SET_BL_INC_SCAN_DEV_NUM:
589 		btcoexist->bt_info.increase_scan_dev_num = *bool_tmp;
590 		break;
591 	case BTC_SET_BL_BT_TX_RX_MASK:
592 		btcoexist->bt_info.bt_tx_rx_mask = *bool_tmp;
593 		break;
594 	case BTC_SET_BL_MIRACAST_PLUS_BT:
595 		btcoexist->bt_info.miracast_plus_bt = *bool_tmp;
596 		break;
597 		/* set some u1Byte type variables. */
598 	case BTC_SET_U1_RSSI_ADJ_VAL_FOR_AGC_TABLE_ON:
599 		btcoexist->bt_info.rssi_adjust_for_agc_table_on = *u8_tmp;
600 		break;
601 	case BTC_SET_U1_AGG_BUF_SIZE:
602 		btcoexist->bt_info.agg_buf_size = *u8_tmp;
603 		break;
604 
605 	/* the following are some action which will be triggered */
606 	case BTC_SET_ACT_GET_BT_RSSI:
607 		ret = false;
608 		break;
609 	case BTC_SET_ACT_AGGREGATE_CTRL:
610 		halbtc_aggregation_check(btcoexist);
611 		break;
612 
613 	/* 1Ant */
614 	case BTC_SET_U1_RSSI_ADJ_VAL_FOR_1ANT_COEX_TYPE:
615 		btcoexist->bt_info.rssi_adjust_for_1ant_coex_type = *u8_tmp;
616 		break;
617 	case BTC_SET_UI_SCAN_SIG_COMPENSATION:
618 		break;
619 	case BTC_SET_U1_LPS_VAL:
620 		btcoexist->bt_info.lps_val = *u8_tmp;
621 		break;
622 	case BTC_SET_U1_RPWM_VAL:
623 		btcoexist->bt_info.rpwm_val = *u8_tmp;
624 		break;
625 	/* the following are some action which will be triggered  */
626 	case BTC_SET_ACT_LEAVE_LPS:
627 		halbtc_leave_lps(btcoexist);
628 		break;
629 	case BTC_SET_ACT_ENTER_LPS:
630 		halbtc_enter_lps(btcoexist);
631 		break;
632 	case BTC_SET_ACT_NORMAL_LPS:
633 		halbtc_normal_lps(btcoexist);
634 		break;
635 	case BTC_SET_ACT_DISABLE_LOW_POWER:
636 		halbtc_disable_low_power(btcoexist, *bool_tmp);
637 		break;
638 	case BTC_SET_ACT_UPDATE_RAMASK:
639 		btcoexist->bt_info.ra_mask = *u32_tmp;
640 		break;
641 	case BTC_SET_ACT_SEND_MIMO_PS:
642 		break;
643 	case BTC_SET_ACT_CTRL_BT_INFO: /*wait for 8812/8821*/
644 		break;
645 	case BTC_SET_ACT_CTRL_BT_COEX:
646 		break;
647 	case BTC_SET_ACT_CTRL_8723B_ANT:
648 		break;
649 	default:
650 		break;
651 	}
652 
653 	return ret;
654 }
655 
656 /************************************************************
657  *		IO related function
658  ************************************************************/
659 static u8 halbtc_read_1byte(void *bt_context, u32 reg_addr)
660 {
661 	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
662 	struct rtl_priv *rtlpriv = btcoexist->adapter;
663 
664 	return	rtl_read_byte(rtlpriv, reg_addr);
665 }
666 
667 static u16 halbtc_read_2byte(void *bt_context, u32 reg_addr)
668 {
669 	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
670 	struct rtl_priv *rtlpriv = btcoexist->adapter;
671 
672 	return	rtl_read_word(rtlpriv, reg_addr);
673 }
674 
675 static u32 halbtc_read_4byte(void *bt_context, u32 reg_addr)
676 {
677 	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
678 	struct rtl_priv *rtlpriv = btcoexist->adapter;
679 
680 	return	rtl_read_dword(rtlpriv, reg_addr);
681 }
682 
683 static void halbtc_write_1byte(void *bt_context, u32 reg_addr, u32 data)
684 {
685 	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
686 	struct rtl_priv *rtlpriv = btcoexist->adapter;
687 
688 	rtl_write_byte(rtlpriv, reg_addr, data);
689 }
690 
691 static void halbtc_bitmask_write_1byte(void *bt_context, u32 reg_addr,
692 				       u32 bit_mask, u8 data)
693 {
694 	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
695 	struct rtl_priv *rtlpriv = btcoexist->adapter;
696 	u8 original_value, bit_shift = 0;
697 	u8 i;
698 
699 	if (bit_mask != MASKDWORD) {/*if not "double word" write*/
700 		original_value = rtl_read_byte(rtlpriv, reg_addr);
701 		for (i = 0; i <= 7; i++) {
702 			if ((bit_mask>>i) & 0x1)
703 				break;
704 		}
705 		bit_shift = i;
706 		data = (original_value & (~bit_mask)) |
707 			((data << bit_shift) & bit_mask);
708 	}
709 	rtl_write_byte(rtlpriv, reg_addr, data);
710 }
711 
712 static void halbtc_write_2byte(void *bt_context, u32 reg_addr, u16 data)
713 {
714 	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
715 	struct rtl_priv *rtlpriv = btcoexist->adapter;
716 
717 	rtl_write_word(rtlpriv, reg_addr, data);
718 }
719 
720 static void halbtc_write_4byte(void *bt_context, u32 reg_addr, u32 data)
721 {
722 	struct btc_coexist *btcoexist =
723 		(struct btc_coexist *)bt_context;
724 	struct rtl_priv *rtlpriv = btcoexist->adapter;
725 
726 	rtl_write_dword(rtlpriv, reg_addr, data);
727 }
728 
729 void halbtc_write_local_reg_1byte(void *btc_context, u32 reg_addr, u8 data)
730 {
731 	struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context;
732 	struct rtl_priv *rtlpriv = btcoexist->adapter;
733 
734 	if (btcoexist->chip_interface == BTC_INTF_SDIO)
735 		;
736 	else if (btcoexist->chip_interface == BTC_INTF_PCI)
737 		rtl_write_byte(rtlpriv, reg_addr, data);
738 	else if (btcoexist->chip_interface == BTC_INTF_USB)
739 		rtl_write_byte(rtlpriv, reg_addr, data);
740 }
741 
742 void halbtc_set_macreg(void *btc_context, u32 reg_addr, u32 bit_mask, u32 data)
743 {
744 	struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context;
745 	struct rtl_priv *rtlpriv = btcoexist->adapter;
746 
747 	rtl_set_bbreg(rtlpriv->mac80211.hw, reg_addr, bit_mask, data);
748 }
749 
750 u32 halbtc_get_macreg(void *btc_context, u32 reg_addr, u32 bit_mask)
751 {
752 	struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context;
753 	struct rtl_priv *rtlpriv = btcoexist->adapter;
754 
755 	return rtl_get_bbreg(rtlpriv->mac80211.hw, reg_addr, bit_mask);
756 }
757 
758 static void halbtc_set_bbreg(void *bt_context, u32 reg_addr, u32 bit_mask,
759 			     u32 data)
760 {
761 	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
762 	struct rtl_priv *rtlpriv = btcoexist->adapter;
763 
764 	rtl_set_bbreg(rtlpriv->mac80211.hw, reg_addr, bit_mask, data);
765 }
766 
767 static u32 halbtc_get_bbreg(void *bt_context, u32 reg_addr, u32 bit_mask)
768 {
769 	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
770 	struct rtl_priv *rtlpriv = btcoexist->adapter;
771 
772 	return rtl_get_bbreg(rtlpriv->mac80211.hw, reg_addr, bit_mask);
773 }
774 
775 static void halbtc_set_rfreg(void *bt_context, u8 rf_path, u32 reg_addr,
776 			     u32 bit_mask, u32 data)
777 {
778 	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
779 	struct rtl_priv *rtlpriv = btcoexist->adapter;
780 
781 	rtl_set_rfreg(rtlpriv->mac80211.hw, rf_path, reg_addr, bit_mask, data);
782 }
783 
784 static u32 halbtc_get_rfreg(void *bt_context, u8 rf_path, u32 reg_addr,
785 			    u32 bit_mask)
786 {
787 	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
788 	struct rtl_priv *rtlpriv = btcoexist->adapter;
789 
790 	return rtl_get_rfreg(rtlpriv->mac80211.hw, rf_path, reg_addr, bit_mask);
791 }
792 
793 static void halbtc_fill_h2c_cmd(void *bt_context, u8 element_id,
794 				u32 cmd_len, u8 *cmd_buf)
795 {
796 	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
797 	struct rtl_priv *rtlpriv = btcoexist->adapter;
798 
799 	rtlpriv->cfg->ops->fill_h2c_cmd(rtlpriv->mac80211.hw, element_id,
800 					cmd_len, cmd_buf);
801 }
802 
803 void halbtc_set_bt_reg(void *btc_context, u8 reg_type, u32 offset, u32 set_val)
804 {
805 	struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context;
806 	struct rtl_priv *rtlpriv = btcoexist->adapter;
807 	u8 cmd_buffer1[4] = {0};
808 	u8 cmd_buffer2[4] = {0};
809 	u8 *addr_to_set = (u8 *)&offset;
810 	u8 *value_to_set = (u8 *)&set_val;
811 	u8 oper_ver = 0;
812 	u8 req_num = 0;
813 
814 	if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) {
815 		cmd_buffer1[0] |= (oper_ver & 0x0f);	/* Set OperVer */
816 		cmd_buffer1[0] |= ((req_num << 4) & 0xf0);	/* Set ReqNum */
817 		cmd_buffer1[1] = 0x0d;	/* OpCode: BT_LO_OP_WRITE_REG_VALUE */
818 		cmd_buffer1[2] = value_to_set[0];	/* Set WriteRegValue */
819 		rtlpriv->cfg->ops->fill_h2c_cmd(rtlpriv->mac80211.hw, 0x67, 4,
820 						&cmd_buffer1[0]);
821 
822 		msleep(200);
823 		req_num++;
824 
825 		cmd_buffer2[0] |= (oper_ver & 0x0f);	/* Set OperVer */
826 		cmd_buffer2[0] |= ((req_num << 4) & 0xf0);	/* Set ReqNum */
827 		cmd_buffer2[1] = 0x0c;	/* OpCode: BT_LO_OP_WRITE_REG_ADDR */
828 		cmd_buffer2[3] = addr_to_set[0];	/* Set WriteRegAddr */
829 		rtlpriv->cfg->ops->fill_h2c_cmd(rtlpriv->mac80211.hw, 0x67, 4,
830 						&cmd_buffer2[0]);
831 	}
832 }
833 
834 bool halbtc_under_ips(struct btc_coexist *btcoexist)
835 {
836 	struct rtl_priv *rtlpriv = btcoexist->adapter;
837 	struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv);
838 	enum rf_pwrstate rtstate;
839 
840 	if (ppsc->inactiveps) {
841 		rtstate = ppsc->rfpwr_state;
842 
843 		if (rtstate != ERFON &&
844 		    ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
845 			return true;
846 		}
847 	}
848 
849 	return false;
850 }
851 
852 /*****************************************************************
853  *         Extern functions called by other module
854  *****************************************************************/
855 bool exhalbtc_initlize_variables(void)
856 {
857 	struct btc_coexist *btcoexist = &gl_bt_coexist;
858 
859 	halbtc_dbg_init();
860 
861 	btcoexist->btc_read_1byte = halbtc_read_1byte;
862 	btcoexist->btc_write_1byte = halbtc_write_1byte;
863 	btcoexist->btc_write_1byte_bitmask = halbtc_bitmask_write_1byte;
864 	btcoexist->btc_read_2byte = halbtc_read_2byte;
865 	btcoexist->btc_write_2byte = halbtc_write_2byte;
866 	btcoexist->btc_read_4byte = halbtc_read_4byte;
867 	btcoexist->btc_write_4byte = halbtc_write_4byte;
868 	btcoexist->btc_write_local_reg_1byte = halbtc_write_local_reg_1byte;
869 
870 	btcoexist->btc_set_bb_reg = halbtc_set_bbreg;
871 	btcoexist->btc_get_bb_reg = halbtc_get_bbreg;
872 
873 	btcoexist->btc_set_rf_reg = halbtc_set_rfreg;
874 	btcoexist->btc_get_rf_reg = halbtc_get_rfreg;
875 
876 	btcoexist->btc_fill_h2c = halbtc_fill_h2c_cmd;
877 
878 	btcoexist->btc_get = halbtc_get;
879 	btcoexist->btc_set = halbtc_set;
880 	btcoexist->btc_set_bt_reg = halbtc_set_bt_reg;
881 
882 
883 	btcoexist->bt_info.bt_ctrl_buf_size = false;
884 	btcoexist->bt_info.agg_buf_size = 5;
885 
886 	btcoexist->bt_info.increase_scan_dev_num = false;
887 	return true;
888 }
889 
890 bool exhalbtc_bind_bt_coex_withadapter(void *adapter)
891 {
892 	struct btc_coexist *btcoexist = &gl_bt_coexist;
893 	struct rtl_priv *rtlpriv = adapter;
894 	u8 ant_num = 2, chip_type;
895 
896 	if (btcoexist->binded)
897 		return false;
898 
899 	switch (rtlpriv->rtlhal.interface) {
900 	case INTF_PCI:
901 		btcoexist->chip_interface = BTC_INTF_PCI;
902 		break;
903 	case INTF_USB:
904 		btcoexist->chip_interface = BTC_INTF_USB;
905 		break;
906 	default:
907 		btcoexist->chip_interface = BTC_INTF_UNKNOWN;
908 		break;
909 	}
910 
911 	btcoexist->binded = true;
912 	btcoexist->statistics.cnt_bind++;
913 
914 	btcoexist->adapter = adapter;
915 
916 	btcoexist->stack_info.profile_notified = false;
917 
918 	btcoexist->bt_info.bt_ctrl_agg_buf_size = false;
919 	btcoexist->bt_info.agg_buf_size = 5;
920 
921 	btcoexist->bt_info.increase_scan_dev_num = false;
922 	btcoexist->bt_info.miracast_plus_bt = false;
923 
924 	chip_type = rtl_get_hwpg_bt_type(rtlpriv);
925 	exhalbtc_set_chip_type(chip_type);
926 	ant_num = rtl_get_hwpg_ant_num(rtlpriv);
927 	exhalbtc_set_ant_num(rtlpriv, BT_COEX_ANT_TYPE_PG, ant_num);
928 
929 	if (rtl_get_hwpg_package_type(rtlpriv) == 0)
930 		btcoexist->board_info.tfbga_package = false;
931 	else if (rtl_get_hwpg_package_type(rtlpriv) == 1)
932 		btcoexist->board_info.tfbga_package = false;
933 	else
934 		btcoexist->board_info.tfbga_package = true;
935 
936 	if (btcoexist->board_info.tfbga_package)
937 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
938 			 "[BTCoex], Package Type = TFBGA\n");
939 	else
940 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
941 			 "[BTCoex], Package Type = Non-TFBGA\n");
942 
943 	return true;
944 }
945 
946 void exhalbtc_power_on_setting(struct btc_coexist *btcoexist)
947 {
948 	if (!halbtc_is_bt_coexist_available(btcoexist))
949 		return;
950 
951 	btcoexist->statistics.cnt_power_on++;
952 
953 	if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) {
954 		if (btcoexist->board_info.btdm_ant_num == 2)
955 			ex_btc8723b2ant_power_on_setting(btcoexist);
956 		else if (btcoexist->board_info.btdm_ant_num == 1)
957 			ex_btc8723b1ant_power_on_setting(btcoexist);
958 	}
959 }
960 
961 void exhalbtc_pre_load_firmware(struct btc_coexist *btcoexist)
962 {
963 	if (!halbtc_is_bt_coexist_available(btcoexist))
964 		return;
965 
966 	btcoexist->statistics.cnt_pre_load_firmware++;
967 
968 	if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) {
969 		if (btcoexist->board_info.btdm_ant_num == 2)
970 			ex_btc8723b2ant_pre_load_firmware(btcoexist);
971 	}
972 }
973 
974 void exhalbtc_init_hw_config(struct btc_coexist *btcoexist, bool wifi_only)
975 {
976 	if (!halbtc_is_bt_coexist_available(btcoexist))
977 		return;
978 
979 	btcoexist->statistics.cnt_init_hw_config++;
980 
981 	if (IS_HARDWARE_TYPE_8821(btcoexist->adapter)) {
982 		if (btcoexist->board_info.btdm_ant_num == 2)
983 			ex_btc8821a2ant_init_hwconfig(btcoexist);
984 		else if (btcoexist->board_info.btdm_ant_num == 1)
985 			ex_btc8821a1ant_init_hwconfig(btcoexist, wifi_only);
986 	} else if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) {
987 		if (btcoexist->board_info.btdm_ant_num == 2)
988 			ex_btc8723b2ant_init_hwconfig(btcoexist);
989 		else if (btcoexist->board_info.btdm_ant_num == 1)
990 			ex_btc8723b1ant_init_hwconfig(btcoexist, wifi_only);
991 	} else if (IS_HARDWARE_TYPE_8723A(btcoexist->adapter)) {
992 		/* 8723A has no this function */
993 	} else if (IS_HARDWARE_TYPE_8192E(btcoexist->adapter)) {
994 		if (btcoexist->board_info.btdm_ant_num == 2)
995 			ex_btc8192e2ant_init_hwconfig(btcoexist);
996 	}
997 }
998 
999 void exhalbtc_init_coex_dm(struct btc_coexist *btcoexist)
1000 {
1001 	if (!halbtc_is_bt_coexist_available(btcoexist))
1002 		return;
1003 
1004 	btcoexist->statistics.cnt_init_coex_dm++;
1005 
1006 	if (IS_HARDWARE_TYPE_8821(btcoexist->adapter)) {
1007 		if (btcoexist->board_info.btdm_ant_num == 2)
1008 			ex_btc8821a2ant_init_coex_dm(btcoexist);
1009 		else if (btcoexist->board_info.btdm_ant_num == 1)
1010 			ex_btc8821a1ant_init_coex_dm(btcoexist);
1011 	} else if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) {
1012 		if (btcoexist->board_info.btdm_ant_num == 2)
1013 			ex_btc8723b2ant_init_coex_dm(btcoexist);
1014 		else if (btcoexist->board_info.btdm_ant_num == 1)
1015 			ex_btc8723b1ant_init_coex_dm(btcoexist);
1016 	} else if (IS_HARDWARE_TYPE_8192E(btcoexist->adapter)) {
1017 		if (btcoexist->board_info.btdm_ant_num == 2)
1018 			ex_btc8192e2ant_init_coex_dm(btcoexist);
1019 	}
1020 
1021 	btcoexist->initilized = true;
1022 }
1023 
1024 void exhalbtc_ips_notify(struct btc_coexist *btcoexist, u8 type)
1025 {
1026 	u8 ips_type;
1027 
1028 	if (!halbtc_is_bt_coexist_available(btcoexist))
1029 		return;
1030 	btcoexist->statistics.cnt_ips_notify++;
1031 	if (btcoexist->manual_control)
1032 		return;
1033 
1034 	if (ERFOFF == type)
1035 		ips_type = BTC_IPS_ENTER;
1036 	else
1037 		ips_type = BTC_IPS_LEAVE;
1038 
1039 	halbtc_leave_low_power(btcoexist);
1040 
1041 	if (IS_HARDWARE_TYPE_8821(btcoexist->adapter)) {
1042 		if (btcoexist->board_info.btdm_ant_num == 2)
1043 			ex_btc8821a2ant_ips_notify(btcoexist, ips_type);
1044 		else if (btcoexist->board_info.btdm_ant_num == 1)
1045 			ex_btc8821a1ant_ips_notify(btcoexist, ips_type);
1046 	} else if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) {
1047 		if (btcoexist->board_info.btdm_ant_num == 2)
1048 			ex_btc8723b2ant_ips_notify(btcoexist, ips_type);
1049 		else if (btcoexist->board_info.btdm_ant_num == 1)
1050 			ex_btc8723b1ant_ips_notify(btcoexist, ips_type);
1051 	} else if (IS_HARDWARE_TYPE_8192E(btcoexist->adapter)) {
1052 		if (btcoexist->board_info.btdm_ant_num == 2)
1053 			ex_btc8192e2ant_ips_notify(btcoexist, ips_type);
1054 	}
1055 
1056 	halbtc_normal_low_power(btcoexist);
1057 }
1058 
1059 void exhalbtc_lps_notify(struct btc_coexist *btcoexist, u8 type)
1060 {
1061 	u8 lps_type;
1062 
1063 	if (!halbtc_is_bt_coexist_available(btcoexist))
1064 		return;
1065 	btcoexist->statistics.cnt_lps_notify++;
1066 	if (btcoexist->manual_control)
1067 		return;
1068 
1069 	if (EACTIVE == type)
1070 		lps_type = BTC_LPS_DISABLE;
1071 	else
1072 		lps_type = BTC_LPS_ENABLE;
1073 
1074 	if (IS_HARDWARE_TYPE_8821(btcoexist->adapter)) {
1075 		if (btcoexist->board_info.btdm_ant_num == 2)
1076 			ex_btc8821a2ant_lps_notify(btcoexist, lps_type);
1077 		else if (btcoexist->board_info.btdm_ant_num == 1)
1078 			ex_btc8821a1ant_lps_notify(btcoexist, lps_type);
1079 	} else if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) {
1080 		if (btcoexist->board_info.btdm_ant_num == 2)
1081 			ex_btc8723b2ant_lps_notify(btcoexist, lps_type);
1082 		else if (btcoexist->board_info.btdm_ant_num == 1)
1083 			ex_btc8723b1ant_lps_notify(btcoexist, lps_type);
1084 	} else if (IS_HARDWARE_TYPE_8192E(btcoexist->adapter)) {
1085 		if (btcoexist->board_info.btdm_ant_num == 2)
1086 			ex_btc8192e2ant_lps_notify(btcoexist, lps_type);
1087 	}
1088 }
1089 
1090 void exhalbtc_scan_notify(struct btc_coexist *btcoexist, u8 type)
1091 {
1092 	u8 scan_type;
1093 
1094 	if (!halbtc_is_bt_coexist_available(btcoexist))
1095 		return;
1096 	btcoexist->statistics.cnt_scan_notify++;
1097 	if (btcoexist->manual_control)
1098 		return;
1099 
1100 	if (type)
1101 		scan_type = BTC_SCAN_START;
1102 	else
1103 		scan_type = BTC_SCAN_FINISH;
1104 
1105 	halbtc_leave_low_power(btcoexist);
1106 
1107 	if (IS_HARDWARE_TYPE_8821(btcoexist->adapter)) {
1108 		if (btcoexist->board_info.btdm_ant_num == 2)
1109 			ex_btc8821a2ant_scan_notify(btcoexist, scan_type);
1110 		else if (btcoexist->board_info.btdm_ant_num == 1)
1111 			ex_btc8821a1ant_scan_notify(btcoexist, scan_type);
1112 	} else if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) {
1113 		if (btcoexist->board_info.btdm_ant_num == 2)
1114 			ex_btc8723b2ant_scan_notify(btcoexist, scan_type);
1115 		else if (btcoexist->board_info.btdm_ant_num == 1)
1116 			ex_btc8723b1ant_scan_notify(btcoexist, scan_type);
1117 	} else if (IS_HARDWARE_TYPE_8192E(btcoexist->adapter)) {
1118 		if (btcoexist->board_info.btdm_ant_num == 2)
1119 			ex_btc8192e2ant_scan_notify(btcoexist, scan_type);
1120 	}
1121 
1122 	halbtc_normal_low_power(btcoexist);
1123 }
1124 
1125 void exhalbtc_connect_notify(struct btc_coexist *btcoexist, u8 action)
1126 {
1127 	u8 asso_type;
1128 
1129 	if (!halbtc_is_bt_coexist_available(btcoexist))
1130 		return;
1131 	btcoexist->statistics.cnt_connect_notify++;
1132 	if (btcoexist->manual_control)
1133 		return;
1134 
1135 	if (action)
1136 		asso_type = BTC_ASSOCIATE_START;
1137 	else
1138 		asso_type = BTC_ASSOCIATE_FINISH;
1139 
1140 	halbtc_leave_low_power(btcoexist);
1141 
1142 	if (IS_HARDWARE_TYPE_8821(btcoexist->adapter)) {
1143 		if (btcoexist->board_info.btdm_ant_num == 2)
1144 			ex_btc8821a2ant_connect_notify(btcoexist, asso_type);
1145 		else if (btcoexist->board_info.btdm_ant_num == 1)
1146 			ex_btc8821a1ant_connect_notify(btcoexist, asso_type);
1147 	} else if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) {
1148 		if (btcoexist->board_info.btdm_ant_num == 2)
1149 			ex_btc8723b2ant_connect_notify(btcoexist, asso_type);
1150 		else if (btcoexist->board_info.btdm_ant_num == 1)
1151 			ex_btc8723b1ant_connect_notify(btcoexist, asso_type);
1152 	} else if (IS_HARDWARE_TYPE_8192E(btcoexist->adapter)) {
1153 		if (btcoexist->board_info.btdm_ant_num == 2)
1154 			ex_btc8192e2ant_connect_notify(btcoexist, asso_type);
1155 	}
1156 
1157 	halbtc_normal_low_power(btcoexist);
1158 }
1159 
1160 void exhalbtc_mediastatus_notify(struct btc_coexist *btcoexist,
1161 				 enum rt_media_status media_status)
1162 {
1163 	u8 status;
1164 
1165 	if (!halbtc_is_bt_coexist_available(btcoexist))
1166 		return;
1167 	btcoexist->statistics.cnt_media_status_notify++;
1168 	if (btcoexist->manual_control)
1169 		return;
1170 
1171 	if (RT_MEDIA_CONNECT == media_status)
1172 		status = BTC_MEDIA_CONNECT;
1173 	else
1174 		status = BTC_MEDIA_DISCONNECT;
1175 
1176 	halbtc_leave_low_power(btcoexist);
1177 
1178 	if (IS_HARDWARE_TYPE_8821(btcoexist->adapter)) {
1179 		if (btcoexist->board_info.btdm_ant_num == 2)
1180 			ex_btc8821a2ant_media_status_notify(btcoexist, status);
1181 		else if (btcoexist->board_info.btdm_ant_num == 1)
1182 			ex_btc8821a1ant_media_status_notify(btcoexist, status);
1183 	} else if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) {
1184 		if (btcoexist->board_info.btdm_ant_num == 2)
1185 			ex_btc8723b2ant_media_status_notify(btcoexist, status);
1186 		else if (btcoexist->board_info.btdm_ant_num == 1)
1187 			ex_btc8723b1ant_media_status_notify(btcoexist, status);
1188 	} else if (IS_HARDWARE_TYPE_8192E(btcoexist->adapter)) {
1189 		if (btcoexist->board_info.btdm_ant_num == 2)
1190 			ex_btc8192e2ant_media_status_notify(btcoexist, status);
1191 	}
1192 
1193 	halbtc_normal_low_power(btcoexist);
1194 }
1195 
1196 void exhalbtc_special_packet_notify(struct btc_coexist *btcoexist, u8 pkt_type)
1197 {
1198 	u8 packet_type;
1199 
1200 	if (!halbtc_is_bt_coexist_available(btcoexist))
1201 		return;
1202 	btcoexist->statistics.cnt_special_packet_notify++;
1203 	if (btcoexist->manual_control)
1204 		return;
1205 
1206 	if (pkt_type == PACKET_DHCP) {
1207 		packet_type = BTC_PACKET_DHCP;
1208 	} else if (pkt_type == PACKET_EAPOL) {
1209 		packet_type = BTC_PACKET_EAPOL;
1210 	} else if (pkt_type == PACKET_ARP) {
1211 		packet_type = BTC_PACKET_ARP;
1212 	} else {
1213 		packet_type = BTC_PACKET_UNKNOWN;
1214 		return;
1215 	}
1216 
1217 	halbtc_leave_low_power(btcoexist);
1218 
1219 	if (IS_HARDWARE_TYPE_8821(btcoexist->adapter)) {
1220 		if (btcoexist->board_info.btdm_ant_num == 2)
1221 			ex_btc8821a2ant_special_packet_notify(btcoexist,
1222 							      packet_type);
1223 		else if (btcoexist->board_info.btdm_ant_num == 1)
1224 			ex_btc8821a1ant_special_packet_notify(btcoexist,
1225 							      packet_type);
1226 	} else if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) {
1227 		if (btcoexist->board_info.btdm_ant_num == 2)
1228 			ex_btc8723b2ant_special_packet_notify(btcoexist,
1229 							      packet_type);
1230 		else if (btcoexist->board_info.btdm_ant_num == 1)
1231 			ex_btc8723b1ant_special_packet_notify(btcoexist,
1232 							      packet_type);
1233 	} else if (IS_HARDWARE_TYPE_8192E(btcoexist->adapter)) {
1234 		if (btcoexist->board_info.btdm_ant_num == 2)
1235 			ex_btc8192e2ant_special_packet_notify(btcoexist,
1236 							      packet_type);
1237 	}
1238 
1239 	halbtc_normal_low_power(btcoexist);
1240 }
1241 
1242 void exhalbtc_bt_info_notify(struct btc_coexist *btcoexist,
1243 			     u8 *tmp_buf, u8 length)
1244 {
1245 	if (!halbtc_is_bt_coexist_available(btcoexist))
1246 		return;
1247 	btcoexist->statistics.cnt_bt_info_notify++;
1248 
1249 	halbtc_leave_low_power(btcoexist);
1250 
1251 	if (IS_HARDWARE_TYPE_8821(btcoexist->adapter)) {
1252 		if (btcoexist->board_info.btdm_ant_num == 2)
1253 			ex_btc8821a2ant_bt_info_notify(btcoexist, tmp_buf,
1254 						       length);
1255 		else if (btcoexist->board_info.btdm_ant_num == 1)
1256 			ex_btc8821a1ant_bt_info_notify(btcoexist, tmp_buf,
1257 						       length);
1258 	} else if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) {
1259 		if (btcoexist->board_info.btdm_ant_num == 2)
1260 			ex_btc8723b2ant_bt_info_notify(btcoexist, tmp_buf,
1261 						       length);
1262 		else if (btcoexist->board_info.btdm_ant_num == 1)
1263 			ex_btc8723b1ant_bt_info_notify(btcoexist, tmp_buf,
1264 						       length);
1265 	} else if (IS_HARDWARE_TYPE_8192E(btcoexist->adapter)) {
1266 		if (btcoexist->board_info.btdm_ant_num == 2)
1267 			ex_btc8192e2ant_bt_info_notify(btcoexist, tmp_buf,
1268 						       length);
1269 	}
1270 
1271 	halbtc_normal_low_power(btcoexist);
1272 }
1273 
1274 void exhalbtc_rf_status_notify(struct btc_coexist *btcoexist, u8 type)
1275 {
1276 	if (!halbtc_is_bt_coexist_available(btcoexist))
1277 		return;
1278 
1279 	if (IS_HARDWARE_TYPE_8821(btcoexist->adapter)) {
1280 	} else if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) {
1281 		if (btcoexist->board_info.btdm_ant_num == 1)
1282 			ex_btc8723b1ant_rf_status_notify(btcoexist, type);
1283 	} else if (IS_HARDWARE_TYPE_8192E(btcoexist->adapter)) {
1284 	}
1285 }
1286 
1287 void exhalbtc_stack_operation_notify(struct btc_coexist *btcoexist, u8 type)
1288 {
1289 	u8 stack_op_type;
1290 
1291 	if (!halbtc_is_bt_coexist_available(btcoexist))
1292 		return;
1293 	btcoexist->statistics.cnt_stack_operation_notify++;
1294 	if (btcoexist->manual_control)
1295 		return;
1296 
1297 	if ((type == HCI_BT_OP_INQUIRY_START) ||
1298 	    (type == HCI_BT_OP_PAGING_START) ||
1299 	    (type == HCI_BT_OP_PAIRING_START)) {
1300 		stack_op_type = BTC_STACK_OP_INQ_PAGE_PAIR_START;
1301 	} else if ((type == HCI_BT_OP_INQUIRY_FINISH) ||
1302 		   (type == HCI_BT_OP_PAGING_SUCCESS) ||
1303 		   (type == HCI_BT_OP_PAGING_UNSUCCESS) ||
1304 		   (type == HCI_BT_OP_PAIRING_FINISH)) {
1305 		stack_op_type = BTC_STACK_OP_INQ_PAGE_PAIR_FINISH;
1306 	} else {
1307 		stack_op_type = BTC_STACK_OP_NONE;
1308 	}
1309 }
1310 
1311 void exhalbtc_halt_notify(struct btc_coexist *btcoexist)
1312 {
1313 	if (!halbtc_is_bt_coexist_available(btcoexist))
1314 		return;
1315 
1316 	if (IS_HARDWARE_TYPE_8821(btcoexist->adapter)) {
1317 		if (btcoexist->board_info.btdm_ant_num == 2)
1318 			ex_btc8821a2ant_halt_notify(btcoexist);
1319 		else if (btcoexist->board_info.btdm_ant_num == 1)
1320 			ex_btc8821a1ant_halt_notify(btcoexist);
1321 	} else if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) {
1322 		if (btcoexist->board_info.btdm_ant_num == 2)
1323 			ex_btc8723b2ant_halt_notify(btcoexist);
1324 		else if (btcoexist->board_info.btdm_ant_num == 1)
1325 			ex_btc8723b1ant_halt_notify(btcoexist);
1326 	} else if (IS_HARDWARE_TYPE_8192E(btcoexist->adapter)) {
1327 		if (btcoexist->board_info.btdm_ant_num == 2)
1328 			ex_btc8192e2ant_halt_notify(btcoexist);
1329 	}
1330 
1331 	btcoexist->binded = false;
1332 }
1333 
1334 void exhalbtc_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state)
1335 {
1336 	if (!halbtc_is_bt_coexist_available(btcoexist))
1337 		return;
1338 
1339 	/* currently only 1ant we have to do the notification,
1340 	 * once pnp is notified to sleep state, we have to leave LPS that
1341 	 * we can sleep normally.
1342 	 */
1343 
1344 	if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) {
1345 		if (btcoexist->board_info.btdm_ant_num == 1)
1346 			ex_btc8723b1ant_pnp_notify(btcoexist, pnp_state);
1347 		else if (btcoexist->board_info.btdm_ant_num == 2)
1348 			ex_btc8723b2ant_pnp_notify(btcoexist, pnp_state);
1349 	} else if (IS_HARDWARE_TYPE_8821(btcoexist->adapter)) {
1350 		if (btcoexist->board_info.btdm_ant_num == 1)
1351 			ex_btc8821a1ant_pnp_notify(btcoexist, pnp_state);
1352 		else if (btcoexist->board_info.btdm_ant_num == 2)
1353 			ex_btc8821a2ant_pnp_notify(btcoexist, pnp_state);
1354 	} else if (IS_HARDWARE_TYPE_8192E(btcoexist->adapter)) {
1355 	}
1356 }
1357 
1358 void exhalbtc_coex_dm_switch(struct btc_coexist *btcoexist)
1359 {
1360 	struct rtl_priv *rtlpriv = btcoexist->adapter;
1361 
1362 	if (!halbtc_is_bt_coexist_available(btcoexist))
1363 		return;
1364 	btcoexist->statistics.cnt_coex_dm_switch++;
1365 
1366 	halbtc_leave_low_power(btcoexist);
1367 
1368 	if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) {
1369 		if (btcoexist->board_info.btdm_ant_num == 1) {
1370 			btcoexist->stop_coex_dm = true;
1371 			ex_btc8723b1ant_coex_dm_reset(btcoexist);
1372 			exhalbtc_set_ant_num(rtlpriv,
1373 					     BT_COEX_ANT_TYPE_DETECTED, 2);
1374 			ex_btc8723b2ant_init_hwconfig(btcoexist);
1375 			ex_btc8723b2ant_init_coex_dm(btcoexist);
1376 			btcoexist->stop_coex_dm = false;
1377 		}
1378 	}
1379 
1380 	halbtc_normal_low_power(btcoexist);
1381 }
1382 
1383 void exhalbtc_periodical(struct btc_coexist *btcoexist)
1384 {
1385 	if (!halbtc_is_bt_coexist_available(btcoexist))
1386 		return;
1387 	btcoexist->statistics.cnt_periodical++;
1388 
1389 	halbtc_leave_low_power(btcoexist);
1390 
1391 	if (IS_HARDWARE_TYPE_8821(btcoexist->adapter)) {
1392 		if (btcoexist->board_info.btdm_ant_num == 2)
1393 			ex_btc8821a2ant_periodical(btcoexist);
1394 		else if (btcoexist->board_info.btdm_ant_num == 1)
1395 			if (!halbtc_under_ips(btcoexist))
1396 				ex_btc8821a1ant_periodical(btcoexist);
1397 	} else if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) {
1398 		if (btcoexist->board_info.btdm_ant_num == 2)
1399 			ex_btc8723b2ant_periodical(btcoexist);
1400 		else if (btcoexist->board_info.btdm_ant_num == 1)
1401 			ex_btc8723b1ant_periodical(btcoexist);
1402 	} else if (IS_HARDWARE_TYPE_8192E(btcoexist->adapter)) {
1403 		if (btcoexist->board_info.btdm_ant_num == 2)
1404 			ex_btc8192e2ant_periodical(btcoexist);
1405 	}
1406 
1407 	halbtc_normal_low_power(btcoexist);
1408 }
1409 
1410 void exhalbtc_dbg_control(struct btc_coexist *btcoexist,
1411 			  u8 code, u8 len, u8 *data)
1412 {
1413 	if (!halbtc_is_bt_coexist_available(btcoexist))
1414 		return;
1415 	btcoexist->statistics.cnt_dbg_ctrl++;
1416 
1417 	halbtc_leave_low_power(btcoexist);
1418 
1419 	halbtc_normal_low_power(btcoexist);
1420 }
1421 
1422 void exhalbtc_antenna_detection(struct btc_coexist *btcoexist, u32 cent_freq,
1423 				u32 offset, u32 span, u32 seconds)
1424 {
1425 	if (!halbtc_is_bt_coexist_available(btcoexist))
1426 		return;
1427 }
1428 
1429 void exhalbtc_stack_update_profile_info(void)
1430 {
1431 }
1432 
1433 void exhalbtc_update_min_bt_rssi(s8 bt_rssi)
1434 {
1435 	struct btc_coexist *btcoexist = &gl_bt_coexist;
1436 
1437 	if (!halbtc_is_bt_coexist_available(btcoexist))
1438 		return;
1439 
1440 	btcoexist->stack_info.min_bt_rssi = bt_rssi;
1441 }
1442 
1443 void exhalbtc_set_hci_version(u16 hci_version)
1444 {
1445 	struct btc_coexist *btcoexist = &gl_bt_coexist;
1446 
1447 	if (!halbtc_is_bt_coexist_available(btcoexist))
1448 		return;
1449 
1450 	btcoexist->stack_info.hci_version = hci_version;
1451 }
1452 
1453 void exhalbtc_set_bt_patch_version(u16 bt_hci_version, u16 bt_patch_version)
1454 {
1455 	struct btc_coexist *btcoexist = &gl_bt_coexist;
1456 
1457 	if (!halbtc_is_bt_coexist_available(btcoexist))
1458 		return;
1459 
1460 	btcoexist->bt_info.bt_real_fw_ver = bt_patch_version;
1461 	btcoexist->bt_info.bt_hci_ver = bt_hci_version;
1462 }
1463 
1464 void exhalbtc_set_chip_type(u8 chip_type)
1465 {
1466 	switch (chip_type) {
1467 	default:
1468 	case BT_2WIRE:
1469 	case BT_ISSC_3WIRE:
1470 	case BT_ACCEL:
1471 	case BT_RTL8756:
1472 		gl_bt_coexist.board_info.bt_chip_type = BTC_CHIP_UNDEF;
1473 		break;
1474 	case BT_CSR_BC4:
1475 		gl_bt_coexist.board_info.bt_chip_type = BTC_CHIP_CSR_BC4;
1476 		break;
1477 	case BT_CSR_BC8:
1478 		gl_bt_coexist.board_info.bt_chip_type = BTC_CHIP_CSR_BC8;
1479 		break;
1480 	case BT_RTL8723A:
1481 		gl_bt_coexist.board_info.bt_chip_type = BTC_CHIP_RTL8723A;
1482 		break;
1483 	case BT_RTL8821A:
1484 		gl_bt_coexist.board_info.bt_chip_type = BTC_CHIP_RTL8821;
1485 		break;
1486 	case BT_RTL8723B:
1487 		gl_bt_coexist.board_info.bt_chip_type = BTC_CHIP_RTL8723B;
1488 		break;
1489 	}
1490 }
1491 
1492 void exhalbtc_set_ant_num(struct rtl_priv *rtlpriv, u8 type, u8 ant_num)
1493 {
1494 	if (BT_COEX_ANT_TYPE_PG == type) {
1495 		gl_bt_coexist.board_info.pg_ant_num = ant_num;
1496 		gl_bt_coexist.board_info.btdm_ant_num = ant_num;
1497 	} else if (BT_COEX_ANT_TYPE_ANTDIV == type) {
1498 		gl_bt_coexist.board_info.btdm_ant_num = ant_num;
1499 	} else if (type == BT_COEX_ANT_TYPE_DETECTED) {
1500 		gl_bt_coexist.board_info.btdm_ant_num = ant_num;
1501 		if (rtlpriv->cfg->mod_params->ant_sel == 1)
1502 			gl_bt_coexist.board_info.btdm_ant_pos =
1503 				BTC_ANTENNA_AT_AUX_PORT;
1504 		else
1505 			gl_bt_coexist.board_info.btdm_ant_pos =
1506 				BTC_ANTENNA_AT_MAIN_PORT;
1507 	}
1508 }
1509 
1510 /* Currently used by 8723b only, S0 or S1 */
1511 void exhalbtc_set_single_ant_path(u8 single_ant_path)
1512 {
1513 	gl_bt_coexist.board_info.single_ant_path = single_ant_path;
1514 }
1515 
1516 void exhalbtc_display_bt_coex_info(struct btc_coexist *btcoexist)
1517 {
1518 	if (!halbtc_is_bt_coexist_available(btcoexist))
1519 		return;
1520 
1521 	halbtc_leave_low_power(btcoexist);
1522 
1523 	if (IS_HARDWARE_TYPE_8821(btcoexist->adapter)) {
1524 		if (btcoexist->board_info.btdm_ant_num == 2)
1525 			ex_btc8821a2ant_display_coex_info(btcoexist);
1526 		else if (btcoexist->board_info.btdm_ant_num == 1)
1527 			ex_btc8821a1ant_display_coex_info(btcoexist);
1528 	} else if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) {
1529 		if (btcoexist->board_info.btdm_ant_num == 2)
1530 			ex_btc8723b2ant_display_coex_info(btcoexist);
1531 		else if (btcoexist->board_info.btdm_ant_num == 1)
1532 			ex_btc8723b1ant_display_coex_info(btcoexist);
1533 	} else if (IS_HARDWARE_TYPE_8192E(btcoexist->adapter)) {
1534 		if (btcoexist->board_info.btdm_ant_num == 2)
1535 			ex_btc8192e2ant_display_coex_info(btcoexist);
1536 	}
1537 
1538 	halbtc_normal_low_power(btcoexist);
1539 }
1540