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