1f1d2b4d3SLarry Finger /******************************************************************************
2f1d2b4d3SLarry Finger  *
3f1d2b4d3SLarry Finger  * Copyright(c) 2007 - 2013 Realtek Corporation. All rights reserved.
4f1d2b4d3SLarry Finger  *
5f1d2b4d3SLarry Finger  * This program is free software; you can redistribute it and/or modify it
6f1d2b4d3SLarry Finger  * under the terms of version 2 of the GNU General Public License as
7f1d2b4d3SLarry Finger  * published by the Free Software Foundation.
8f1d2b4d3SLarry Finger  *
9f1d2b4d3SLarry Finger  * This program is distributed in the hope that it will be useful, but WITHOUT
10f1d2b4d3SLarry Finger  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11f1d2b4d3SLarry Finger  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12f1d2b4d3SLarry Finger  * more details.
13f1d2b4d3SLarry Finger  *
14f1d2b4d3SLarry Finger  * The full GNU General Public License is included in this distribution in the
15f1d2b4d3SLarry Finger  * file called LICENSE.
16f1d2b4d3SLarry Finger  *
17f1d2b4d3SLarry Finger  * Contact Information:
18f1d2b4d3SLarry Finger  * wlanfae <wlanfae@realtek.com>
19f1d2b4d3SLarry Finger  * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20f1d2b4d3SLarry Finger  * Hsinchu 300, Taiwan.
21f1d2b4d3SLarry Finger  *
22f1d2b4d3SLarry Finger  * Larry Finger <Larry.Finger@lwfinger.net>
23f1d2b4d3SLarry Finger  *
24f1d2b4d3SLarry Finger  ******************************************************************************/
25f1d2b4d3SLarry Finger 
26f1d2b4d3SLarry Finger #include "halbt_precomp.h"
27f1d2b4d3SLarry Finger 
28f1d2b4d3SLarry Finger /***************************************************
29f1d2b4d3SLarry Finger  *		Debug related function
30f1d2b4d3SLarry Finger  ***************************************************/
31c42ea613SYan-Hsuan Chuang 
32c42ea613SYan-Hsuan Chuang const char *const gl_btc_wifi_bw_string[] = {
33c42ea613SYan-Hsuan Chuang 	"11bg",
34c42ea613SYan-Hsuan Chuang 	"HT20",
35c42ea613SYan-Hsuan Chuang 	"HT40",
36c42ea613SYan-Hsuan Chuang 	"HT80",
37c42ea613SYan-Hsuan Chuang 	"HT160"
38c42ea613SYan-Hsuan Chuang };
39c42ea613SYan-Hsuan Chuang 
40c42ea613SYan-Hsuan Chuang const char *const gl_btc_wifi_freq_string[] = {
41c42ea613SYan-Hsuan Chuang 	"2.4G",
42c42ea613SYan-Hsuan Chuang 	"5G"
43c42ea613SYan-Hsuan Chuang };
44c42ea613SYan-Hsuan Chuang 
45f1d2b4d3SLarry Finger static bool halbtc_is_bt_coexist_available(struct btc_coexist *btcoexist)
46f1d2b4d3SLarry Finger {
47f1d2b4d3SLarry Finger 	if (!btcoexist->binded || NULL == btcoexist->adapter)
48f1d2b4d3SLarry Finger 		return false;
49f1d2b4d3SLarry Finger 
50f1d2b4d3SLarry Finger 	return true;
51f1d2b4d3SLarry Finger }
52f1d2b4d3SLarry Finger 
53f1d2b4d3SLarry Finger static bool halbtc_is_wifi_busy(struct rtl_priv *rtlpriv)
54f1d2b4d3SLarry Finger {
55f1d2b4d3SLarry Finger 	if (rtlpriv->link_info.busytraffic)
56f1d2b4d3SLarry Finger 		return true;
57f1d2b4d3SLarry Finger 	else
58f1d2b4d3SLarry Finger 		return false;
59f1d2b4d3SLarry Finger }
60f1d2b4d3SLarry Finger 
61f1d2b4d3SLarry Finger static void halbtc_dbg_init(void)
62f1d2b4d3SLarry Finger {
63c42ea613SYan-Hsuan Chuang }
64f1d2b4d3SLarry Finger 
65c42ea613SYan-Hsuan Chuang /***************************************************
66c42ea613SYan-Hsuan Chuang  *		helper function
67c42ea613SYan-Hsuan Chuang  ***************************************************/
68c42ea613SYan-Hsuan Chuang static bool is_any_client_connect_to_ap(struct btc_coexist *btcoexist)
69c42ea613SYan-Hsuan Chuang {
70c42ea613SYan-Hsuan Chuang 	struct rtl_priv *rtlpriv = btcoexist->adapter;
71c42ea613SYan-Hsuan Chuang 	struct rtl_mac *mac = rtl_mac(rtlpriv);
72c42ea613SYan-Hsuan Chuang 	struct rtl_sta_info *drv_priv;
73c42ea613SYan-Hsuan Chuang 	u8 cnt = 0;
74f1d2b4d3SLarry Finger 
75c42ea613SYan-Hsuan Chuang 	if (mac->opmode == NL80211_IFTYPE_ADHOC ||
76c42ea613SYan-Hsuan Chuang 	    mac->opmode == NL80211_IFTYPE_MESH_POINT ||
77c42ea613SYan-Hsuan Chuang 	    mac->opmode == NL80211_IFTYPE_AP) {
78c42ea613SYan-Hsuan Chuang 		if (in_interrupt() > 0) {
79c42ea613SYan-Hsuan Chuang 			list_for_each_entry(drv_priv, &rtlpriv->entry_list,
80c42ea613SYan-Hsuan Chuang 					    list) {
81c42ea613SYan-Hsuan Chuang 				cnt++;
82c42ea613SYan-Hsuan Chuang 			}
83c42ea613SYan-Hsuan Chuang 		} else {
84c42ea613SYan-Hsuan Chuang 			spin_lock_bh(&rtlpriv->locks.entry_list_lock);
85c42ea613SYan-Hsuan Chuang 			list_for_each_entry(drv_priv, &rtlpriv->entry_list,
86c42ea613SYan-Hsuan Chuang 					    list) {
87c42ea613SYan-Hsuan Chuang 				cnt++;
88c42ea613SYan-Hsuan Chuang 			}
89c42ea613SYan-Hsuan Chuang 			spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
90c42ea613SYan-Hsuan Chuang 		}
91c42ea613SYan-Hsuan Chuang 	}
92c42ea613SYan-Hsuan Chuang 	if (cnt > 0)
93c42ea613SYan-Hsuan Chuang 		return true;
94c42ea613SYan-Hsuan Chuang 	else
95c42ea613SYan-Hsuan Chuang 		return false;
96f1d2b4d3SLarry Finger }
97f1d2b4d3SLarry Finger 
98f1d2b4d3SLarry Finger static bool halbtc_legacy(struct rtl_priv *adapter)
99f1d2b4d3SLarry Finger {
100f1d2b4d3SLarry Finger 	struct rtl_priv *rtlpriv = adapter;
101f1d2b4d3SLarry Finger 	struct rtl_mac *mac = rtl_mac(rtlpriv);
102f1d2b4d3SLarry Finger 
103f1d2b4d3SLarry Finger 	bool is_legacy = false;
104f1d2b4d3SLarry Finger 
105f1d2b4d3SLarry Finger 	if ((mac->mode == WIRELESS_MODE_B) || (mac->mode == WIRELESS_MODE_G))
106f1d2b4d3SLarry Finger 		is_legacy = true;
107f1d2b4d3SLarry Finger 
108f1d2b4d3SLarry Finger 	return is_legacy;
109f1d2b4d3SLarry Finger }
110f1d2b4d3SLarry Finger 
111f1d2b4d3SLarry Finger bool halbtc_is_wifi_uplink(struct rtl_priv *adapter)
112f1d2b4d3SLarry Finger {
113f1d2b4d3SLarry Finger 	struct rtl_priv *rtlpriv = adapter;
114f1d2b4d3SLarry Finger 
115f1d2b4d3SLarry Finger 	if (rtlpriv->link_info.tx_busy_traffic)
116f1d2b4d3SLarry Finger 		return true;
117f1d2b4d3SLarry Finger 	else
118f1d2b4d3SLarry Finger 		return false;
119f1d2b4d3SLarry Finger }
120f1d2b4d3SLarry Finger 
121f1d2b4d3SLarry Finger static u32 halbtc_get_wifi_bw(struct btc_coexist *btcoexist)
122f1d2b4d3SLarry Finger {
12366d0f9deSPing-Ke Shih 	struct rtl_priv *rtlpriv = btcoexist->adapter;
12466d0f9deSPing-Ke Shih 	struct rtl_phy *rtlphy = &rtlpriv->phy;
125f1d2b4d3SLarry Finger 	u32 wifi_bw = BTC_WIFI_BW_HT20;
126f1d2b4d3SLarry Finger 
12766d0f9deSPing-Ke Shih 	if (halbtc_legacy(rtlpriv)) {
128f1d2b4d3SLarry Finger 		wifi_bw = BTC_WIFI_BW_LEGACY;
12966d0f9deSPing-Ke Shih 	} else {
13066d0f9deSPing-Ke Shih 		switch (rtlphy->current_chan_bw) {
13166d0f9deSPing-Ke Shih 		case HT_CHANNEL_WIDTH_20:
132f1d2b4d3SLarry Finger 			wifi_bw = BTC_WIFI_BW_HT20;
13366d0f9deSPing-Ke Shih 			break;
13466d0f9deSPing-Ke Shih 		case HT_CHANNEL_WIDTH_20_40:
13566d0f9deSPing-Ke Shih 			wifi_bw = BTC_WIFI_BW_HT40;
13666d0f9deSPing-Ke Shih 			break;
13766d0f9deSPing-Ke Shih 		case HT_CHANNEL_WIDTH_80:
13866d0f9deSPing-Ke Shih 			wifi_bw = BTC_WIFI_BW_HT80;
13966d0f9deSPing-Ke Shih 			break;
140f1d2b4d3SLarry Finger 		}
14166d0f9deSPing-Ke Shih 	}
14266d0f9deSPing-Ke Shih 
143f1d2b4d3SLarry Finger 	return wifi_bw;
144f1d2b4d3SLarry Finger }
145f1d2b4d3SLarry Finger 
146f1d2b4d3SLarry Finger static u8 halbtc_get_wifi_central_chnl(struct btc_coexist *btcoexist)
147f1d2b4d3SLarry Finger {
148f1d2b4d3SLarry Finger 	struct rtl_priv *rtlpriv = btcoexist->adapter;
149f1d2b4d3SLarry Finger 	struct rtl_phy	*rtlphy = &(rtlpriv->phy);
150f1d2b4d3SLarry Finger 	u8 chnl = 1;
151f1d2b4d3SLarry Finger 
152f1d2b4d3SLarry Finger 	if (rtlphy->current_channel != 0)
153f1d2b4d3SLarry Finger 		chnl = rtlphy->current_channel;
15441880bb3SLarry Finger 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
155f1d2b4d3SLarry Finger 		 "static halbtc_get_wifi_central_chnl:%d\n", chnl);
156f1d2b4d3SLarry Finger 	return chnl;
157f1d2b4d3SLarry Finger }
158f1d2b4d3SLarry Finger 
159db8cb009SPing-Ke Shih u8 rtl_get_hwpg_single_ant_path(struct rtl_priv *rtlpriv)
160db8cb009SPing-Ke Shih {
1616d622692SLarry Finger 	struct rtl_mod_params *mod_params = rtlpriv->cfg->mod_params;
1626d622692SLarry Finger 
1636d622692SLarry Finger 	/* override ant_num / ant_path */
1646d622692SLarry Finger 	if (mod_params->ant_sel) {
1656d622692SLarry Finger 		rtlpriv->btcoexist.btc_info.ant_num =
1666d622692SLarry Finger 			(mod_params->ant_sel == 1 ? ANT_X2 : ANT_X1);
1676d622692SLarry Finger 
1686d622692SLarry Finger 		rtlpriv->btcoexist.btc_info.single_ant_path =
1696d622692SLarry Finger 			(mod_params->ant_sel == 1 ? 0 : 1);
1706d622692SLarry Finger 	}
171db8cb009SPing-Ke Shih 	return rtlpriv->btcoexist.btc_info.single_ant_path;
172db8cb009SPing-Ke Shih }
173db8cb009SPing-Ke Shih 
174e0215c14SPing-Ke Shih u8 rtl_get_hwpg_bt_type(struct rtl_priv *rtlpriv)
175e0215c14SPing-Ke Shih {
176e0215c14SPing-Ke Shih 	return rtlpriv->btcoexist.btc_info.bt_type;
177e0215c14SPing-Ke Shih }
178e0215c14SPing-Ke Shih 
1790de9b5dbSPing-Ke Shih u8 rtl_get_hwpg_ant_num(struct rtl_priv *rtlpriv)
1800de9b5dbSPing-Ke Shih {
1816d622692SLarry Finger 	struct rtl_mod_params *mod_params = rtlpriv->cfg->mod_params;
1820de9b5dbSPing-Ke Shih 	u8 num;
1830de9b5dbSPing-Ke Shih 
1840de9b5dbSPing-Ke Shih 	if (rtlpriv->btcoexist.btc_info.ant_num == ANT_X2)
1850de9b5dbSPing-Ke Shih 		num = 2;
1860de9b5dbSPing-Ke Shih 	else
1870de9b5dbSPing-Ke Shih 		num = 1;
1880de9b5dbSPing-Ke Shih 
1896d622692SLarry Finger 	/* override ant_num / ant_path */
1906d622692SLarry Finger 	if (mod_params->ant_sel)
1916d622692SLarry Finger 		num = (mod_params->ant_sel == 1 ? ANT_X2 : ANT_X1) + 1;
1926d622692SLarry Finger 
1930de9b5dbSPing-Ke Shih 	return num;
1940de9b5dbSPing-Ke Shih }
1950de9b5dbSPing-Ke Shih 
1967fe1fe75SPing-Ke Shih u8 rtl_get_hwpg_package_type(struct rtl_priv *rtlpriv)
1977fe1fe75SPing-Ke Shih {
1987fe1fe75SPing-Ke Shih 	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1997fe1fe75SPing-Ke Shih 
2007fe1fe75SPing-Ke Shih 	return rtlhal->package_type;
2017fe1fe75SPing-Ke Shih }
2027fe1fe75SPing-Ke Shih 
203b2283dadSPing-Ke Shih static
204188b6b09SPing-Ke Shih u8 rtl_get_hwpg_rfe_type(struct rtl_priv *rtlpriv)
205188b6b09SPing-Ke Shih {
206188b6b09SPing-Ke Shih 	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
207188b6b09SPing-Ke Shih 
208188b6b09SPing-Ke Shih 	return rtlhal->rfe_type;
209188b6b09SPing-Ke Shih }
210188b6b09SPing-Ke Shih 
211188b6b09SPing-Ke Shih static
212b2283dadSPing-Ke Shih bool halbtc_is_hw_mailbox_exist(struct btc_coexist *btcoexist)
213b2283dadSPing-Ke Shih {
214b2283dadSPing-Ke Shih 	if (IS_HARDWARE_TYPE_8812(btcoexist->adapter))
215b2283dadSPing-Ke Shih 		return false;
216b2283dadSPing-Ke Shih 	else
217b2283dadSPing-Ke Shih 		return true;
218b2283dadSPing-Ke Shih }
219b2283dadSPing-Ke Shih 
220b2283dadSPing-Ke Shih static
221b2283dadSPing-Ke Shih bool halbtc_send_bt_mp_operation(struct btc_coexist *btcoexist, u8 op_code,
222b2283dadSPing-Ke Shih 				 u8 *cmd, u32 len, unsigned long wait_ms)
223b2283dadSPing-Ke Shih {
224b2283dadSPing-Ke Shih 	struct rtl_priv *rtlpriv;
225b2283dadSPing-Ke Shih 	const u8 oper_ver = 0;
226b2283dadSPing-Ke Shih 	u8 req_num;
227b2283dadSPing-Ke Shih 
228b2283dadSPing-Ke Shih 	if (!halbtc_is_hw_mailbox_exist(btcoexist))
229b2283dadSPing-Ke Shih 		return false;
230b2283dadSPing-Ke Shih 
231b2283dadSPing-Ke Shih 	if (wait_ms)	/* before h2c to avoid race condition */
232b2283dadSPing-Ke Shih 		reinit_completion(&btcoexist->bt_mp_comp);
233b2283dadSPing-Ke Shih 
234b2283dadSPing-Ke Shih 	rtlpriv = btcoexist->adapter;
235b2283dadSPing-Ke Shih 
236b2283dadSPing-Ke Shih 	/* fill req_num by op_code, and rtl_btc_btmpinfo_notify() use it
237b2283dadSPing-Ke Shih 	 * to know message type
238b2283dadSPing-Ke Shih 	 */
239b2283dadSPing-Ke Shih 	switch (op_code) {
240b2283dadSPing-Ke Shih 	case BT_OP_GET_BT_VERSION:
241b2283dadSPing-Ke Shih 		req_num = BT_SEQ_GET_BT_VERSION;
242b2283dadSPing-Ke Shih 		break;
243b2283dadSPing-Ke Shih 	case BT_OP_GET_AFH_MAP_L:
244b2283dadSPing-Ke Shih 		req_num = BT_SEQ_GET_AFH_MAP_L;
245b2283dadSPing-Ke Shih 		break;
246b2283dadSPing-Ke Shih 	case BT_OP_GET_AFH_MAP_M:
247b2283dadSPing-Ke Shih 		req_num = BT_SEQ_GET_AFH_MAP_M;
248b2283dadSPing-Ke Shih 		break;
249b2283dadSPing-Ke Shih 	case BT_OP_GET_AFH_MAP_H:
250b2283dadSPing-Ke Shih 		req_num = BT_SEQ_GET_AFH_MAP_H;
251b2283dadSPing-Ke Shih 		break;
252b2283dadSPing-Ke Shih 	case BT_OP_GET_BT_COEX_SUPPORTED_FEATURE:
253b2283dadSPing-Ke Shih 		req_num = BT_SEQ_GET_BT_COEX_SUPPORTED_FEATURE;
254b2283dadSPing-Ke Shih 		break;
255b2283dadSPing-Ke Shih 	case BT_OP_GET_BT_COEX_SUPPORTED_VERSION:
256b2283dadSPing-Ke Shih 		req_num = BT_SEQ_GET_BT_COEX_SUPPORTED_VERSION;
257b2283dadSPing-Ke Shih 		break;
258b2283dadSPing-Ke Shih 	case BT_OP_GET_BT_ANT_DET_VAL:
259b2283dadSPing-Ke Shih 		req_num = BT_SEQ_GET_BT_ANT_DET_VAL;
260b2283dadSPing-Ke Shih 		break;
261b2283dadSPing-Ke Shih 	case BT_OP_GET_BT_BLE_SCAN_PARA:
262b2283dadSPing-Ke Shih 		req_num = BT_SEQ_GET_BT_BLE_SCAN_PARA;
263b2283dadSPing-Ke Shih 		break;
264b2283dadSPing-Ke Shih 	case BT_OP_GET_BT_BLE_SCAN_TYPE:
265b2283dadSPing-Ke Shih 		req_num = BT_SEQ_GET_BT_BLE_SCAN_TYPE;
266b2283dadSPing-Ke Shih 		break;
267b2283dadSPing-Ke Shih 	case BT_OP_GET_BT_DEVICE_INFO:
268b2283dadSPing-Ke Shih 		req_num = BT_SEQ_GET_BT_DEVICE_INFO;
269b2283dadSPing-Ke Shih 		break;
270b2283dadSPing-Ke Shih 	case BT_OP_GET_BT_FORBIDDEN_SLOT_VAL:
271b2283dadSPing-Ke Shih 		req_num = BT_SEQ_GET_BT_FORB_SLOT_VAL;
272b2283dadSPing-Ke Shih 		break;
273b2283dadSPing-Ke Shih 	case BT_OP_WRITE_REG_ADDR:
274b2283dadSPing-Ke Shih 	case BT_OP_WRITE_REG_VALUE:
275b2283dadSPing-Ke Shih 	case BT_OP_READ_REG:
276b2283dadSPing-Ke Shih 	default:
277b2283dadSPing-Ke Shih 		req_num = BT_SEQ_DONT_CARE;
278b2283dadSPing-Ke Shih 		break;
279b2283dadSPing-Ke Shih 	}
280b2283dadSPing-Ke Shih 
281b2283dadSPing-Ke Shih 	cmd[0] |= (oper_ver & 0x0f);		/* Set OperVer */
282b2283dadSPing-Ke Shih 	cmd[0] |= ((req_num << 4) & 0xf0);	/* Set ReqNum */
283b2283dadSPing-Ke Shih 	cmd[1] = op_code;
284b2283dadSPing-Ke Shih 	rtlpriv->cfg->ops->fill_h2c_cmd(rtlpriv->mac80211.hw, 0x67, len, cmd);
285b2283dadSPing-Ke Shih 
286b2283dadSPing-Ke Shih 	/* wait? */
287b2283dadSPing-Ke Shih 	if (!wait_ms)
288b2283dadSPing-Ke Shih 		return true;
289b2283dadSPing-Ke Shih 
290b2283dadSPing-Ke Shih 	RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
291b2283dadSPing-Ke Shih 		 "btmpinfo wait req_num=%d wait=%ld\n", req_num, wait_ms);
292b2283dadSPing-Ke Shih 
293b2283dadSPing-Ke Shih 	if (in_interrupt())
294b2283dadSPing-Ke Shih 		return false;
295b2283dadSPing-Ke Shih 
296b2283dadSPing-Ke Shih 	if (wait_for_completion_timeout(&btcoexist->bt_mp_comp,
297b2283dadSPing-Ke Shih 					msecs_to_jiffies(wait_ms)) == 0) {
298b2283dadSPing-Ke Shih 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
299b2283dadSPing-Ke Shih 			 "btmpinfo wait (req_num=%d) timeout\n", req_num);
300b2283dadSPing-Ke Shih 
301b2283dadSPing-Ke Shih 		return false;	/* timeout */
302b2283dadSPing-Ke Shih 	}
303b2283dadSPing-Ke Shih 
304b2283dadSPing-Ke Shih 	return true;
305b2283dadSPing-Ke Shih }
306b2283dadSPing-Ke Shih 
307f1d2b4d3SLarry Finger static void halbtc_leave_lps(struct btc_coexist *btcoexist)
308f1d2b4d3SLarry Finger {
309f1d2b4d3SLarry Finger 	struct rtl_priv *rtlpriv;
310f1d2b4d3SLarry Finger 	struct rtl_ps_ctl *ppsc;
311f1d2b4d3SLarry Finger 	bool ap_enable = false;
312f1d2b4d3SLarry Finger 
313f1d2b4d3SLarry Finger 	rtlpriv = btcoexist->adapter;
314f1d2b4d3SLarry Finger 	ppsc = rtl_psc(rtlpriv);
315f1d2b4d3SLarry Finger 
316f1d2b4d3SLarry Finger 	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE,
317f1d2b4d3SLarry Finger 			   &ap_enable);
318f1d2b4d3SLarry Finger 
319f1d2b4d3SLarry Finger 	if (ap_enable) {
320c42ea613SYan-Hsuan Chuang 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
321c42ea613SYan-Hsuan Chuang 			 "%s()<--dont leave lps under AP mode\n", __func__);
322f1d2b4d3SLarry Finger 		return;
323f1d2b4d3SLarry Finger 	}
324f1d2b4d3SLarry Finger 
325f1d2b4d3SLarry Finger 	btcoexist->bt_info.bt_ctrl_lps = true;
326f1d2b4d3SLarry Finger 	btcoexist->bt_info.bt_lps_on = false;
327c42ea613SYan-Hsuan Chuang 	rtl_lps_leave(rtlpriv->mac80211.hw);
328f1d2b4d3SLarry Finger }
329f1d2b4d3SLarry Finger 
330f1d2b4d3SLarry Finger static void halbtc_enter_lps(struct btc_coexist *btcoexist)
331f1d2b4d3SLarry Finger {
332f1d2b4d3SLarry Finger 	struct rtl_priv *rtlpriv;
333f1d2b4d3SLarry Finger 	struct rtl_ps_ctl *ppsc;
334f1d2b4d3SLarry Finger 	bool ap_enable = false;
335f1d2b4d3SLarry Finger 
336f1d2b4d3SLarry Finger 	rtlpriv = btcoexist->adapter;
337f1d2b4d3SLarry Finger 	ppsc = rtl_psc(rtlpriv);
338f1d2b4d3SLarry Finger 
339f1d2b4d3SLarry Finger 	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE,
340f1d2b4d3SLarry Finger 			   &ap_enable);
341f1d2b4d3SLarry Finger 
342f1d2b4d3SLarry Finger 	if (ap_enable) {
343c42ea613SYan-Hsuan Chuang 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
344c42ea613SYan-Hsuan Chuang 			 "%s()<--dont enter lps under AP mode\n", __func__);
345f1d2b4d3SLarry Finger 		return;
346f1d2b4d3SLarry Finger 	}
347f1d2b4d3SLarry Finger 
348f1d2b4d3SLarry Finger 	btcoexist->bt_info.bt_ctrl_lps = true;
34942213f2fSPing-Ke Shih 	btcoexist->bt_info.bt_lps_on = true;
350c42ea613SYan-Hsuan Chuang 	rtl_lps_enter(rtlpriv->mac80211.hw);
351f1d2b4d3SLarry Finger }
352f1d2b4d3SLarry Finger 
353f1d2b4d3SLarry Finger static void halbtc_normal_lps(struct btc_coexist *btcoexist)
354f1d2b4d3SLarry Finger {
35542213f2fSPing-Ke Shih 	struct rtl_priv *rtlpriv;
35642213f2fSPing-Ke Shih 
35742213f2fSPing-Ke Shih 	rtlpriv = btcoexist->adapter;
35842213f2fSPing-Ke Shih 
359f1d2b4d3SLarry Finger 	if (btcoexist->bt_info.bt_ctrl_lps) {
360f1d2b4d3SLarry Finger 		btcoexist->bt_info.bt_lps_on = false;
36142213f2fSPing-Ke Shih 		rtl_lps_leave(rtlpriv->mac80211.hw);
362f1d2b4d3SLarry Finger 		btcoexist->bt_info.bt_ctrl_lps = false;
363f1d2b4d3SLarry Finger 	}
364f1d2b4d3SLarry Finger }
365f1d2b4d3SLarry Finger 
3667937f02dSYan-Hsuan Chuang static void halbtc_leave_low_power(struct btc_coexist *btcoexist)
367f1d2b4d3SLarry Finger {
368f1d2b4d3SLarry Finger }
369f1d2b4d3SLarry Finger 
3707937f02dSYan-Hsuan Chuang static void halbtc_normal_low_power(struct btc_coexist *btcoexist)
371f1d2b4d3SLarry Finger {
372f1d2b4d3SLarry Finger }
373f1d2b4d3SLarry Finger 
374c42ea613SYan-Hsuan Chuang static void halbtc_disable_low_power(struct btc_coexist *btcoexist,
375c42ea613SYan-Hsuan Chuang 				     bool low_pwr_disable)
376f1d2b4d3SLarry Finger {
377c42ea613SYan-Hsuan Chuang 	/* TODO: original/leave 32k low power */
378c42ea613SYan-Hsuan Chuang 	btcoexist->bt_info.bt_disable_low_pwr = low_pwr_disable;
379f1d2b4d3SLarry Finger }
380f1d2b4d3SLarry Finger 
381c42ea613SYan-Hsuan Chuang static void halbtc_aggregation_check(struct btc_coexist *btcoexist)
382f1d2b4d3SLarry Finger {
383c42ea613SYan-Hsuan Chuang 	bool need_to_act = false;
3842635664eSPing-Ke Shih 	static unsigned long pre_time;
3852635664eSPing-Ke Shih 	unsigned long cur_time = 0;
3862635664eSPing-Ke Shih 	struct rtl_priv *rtlpriv = btcoexist->adapter;
387c42ea613SYan-Hsuan Chuang 
388c42ea613SYan-Hsuan Chuang 	/* To void continuous deleteBA=>addBA=>deleteBA=>addBA
389c42ea613SYan-Hsuan Chuang 	 * This function is not allowed to continuous called
390c42ea613SYan-Hsuan Chuang 	 * It can only be called after 8 seconds
391c42ea613SYan-Hsuan Chuang 	 */
392c42ea613SYan-Hsuan Chuang 
3932635664eSPing-Ke Shih 	cur_time = jiffies;
3942635664eSPing-Ke Shih 	if (jiffies_to_msecs(cur_time - pre_time) <= 8000) {
3952635664eSPing-Ke Shih 		/* over 8 seconds you can execute this function again. */
3962635664eSPing-Ke Shih 		return;
3972635664eSPing-Ke Shih 	}
3982635664eSPing-Ke Shih 	pre_time = cur_time;
3992635664eSPing-Ke Shih 
400c42ea613SYan-Hsuan Chuang 	if (btcoexist->bt_info.reject_agg_pkt) {
4012635664eSPing-Ke Shih 		need_to_act = true;
402c42ea613SYan-Hsuan Chuang 		btcoexist->bt_info.pre_reject_agg_pkt =
403c42ea613SYan-Hsuan Chuang 			btcoexist->bt_info.reject_agg_pkt;
404c42ea613SYan-Hsuan Chuang 	} else {
405c42ea613SYan-Hsuan Chuang 		if (btcoexist->bt_info.pre_reject_agg_pkt) {
406c42ea613SYan-Hsuan Chuang 			need_to_act = true;
407c42ea613SYan-Hsuan Chuang 			btcoexist->bt_info.pre_reject_agg_pkt =
408c42ea613SYan-Hsuan Chuang 				btcoexist->bt_info.reject_agg_pkt;
409c42ea613SYan-Hsuan Chuang 		}
410c42ea613SYan-Hsuan Chuang 
411c42ea613SYan-Hsuan Chuang 		if (btcoexist->bt_info.pre_bt_ctrl_agg_buf_size !=
412c42ea613SYan-Hsuan Chuang 		    btcoexist->bt_info.bt_ctrl_agg_buf_size) {
413c42ea613SYan-Hsuan Chuang 			need_to_act = true;
414c42ea613SYan-Hsuan Chuang 			btcoexist->bt_info.pre_bt_ctrl_agg_buf_size =
415c42ea613SYan-Hsuan Chuang 				btcoexist->bt_info.bt_ctrl_agg_buf_size;
416c42ea613SYan-Hsuan Chuang 		}
417c42ea613SYan-Hsuan Chuang 
418c42ea613SYan-Hsuan Chuang 		if (btcoexist->bt_info.bt_ctrl_agg_buf_size) {
419c42ea613SYan-Hsuan Chuang 			if (btcoexist->bt_info.pre_agg_buf_size !=
420c42ea613SYan-Hsuan Chuang 			    btcoexist->bt_info.agg_buf_size) {
421c42ea613SYan-Hsuan Chuang 				need_to_act = true;
422c42ea613SYan-Hsuan Chuang 			}
423c42ea613SYan-Hsuan Chuang 			btcoexist->bt_info.pre_agg_buf_size =
424c42ea613SYan-Hsuan Chuang 				btcoexist->bt_info.agg_buf_size;
425c42ea613SYan-Hsuan Chuang 		}
426c42ea613SYan-Hsuan Chuang 
4272635664eSPing-Ke Shih 		if (need_to_act)
4282635664eSPing-Ke Shih 			rtl_rx_ampdu_apply(rtlpriv);
4292635664eSPing-Ke Shih 	}
430f1d2b4d3SLarry Finger }
431f1d2b4d3SLarry Finger 
432f1d2b4d3SLarry Finger static u32 halbtc_get_bt_patch_version(struct btc_coexist *btcoexist)
433f1d2b4d3SLarry Finger {
4346aad6075SPing-Ke Shih 	u8 cmd_buffer[4] = {0};
4356aad6075SPing-Ke Shih 
4366aad6075SPing-Ke Shih 	if (btcoexist->bt_info.bt_real_fw_ver)
4376aad6075SPing-Ke Shih 		goto label_done;
4386aad6075SPing-Ke Shih 
439b2283dadSPing-Ke Shih 	/* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */
440b2283dadSPing-Ke Shih 	halbtc_send_bt_mp_operation(btcoexist, BT_OP_GET_BT_VERSION,
441b2283dadSPing-Ke Shih 				    cmd_buffer, 4, 200);
4426aad6075SPing-Ke Shih 
4436aad6075SPing-Ke Shih label_done:
4446aad6075SPing-Ke Shih 	return btcoexist->bt_info.bt_real_fw_ver;
445f1d2b4d3SLarry Finger }
446f1d2b4d3SLarry Finger 
447b2283dadSPing-Ke Shih static u32 halbtc_get_bt_coex_supported_feature(void *btc_context)
448b2283dadSPing-Ke Shih {
449b2283dadSPing-Ke Shih 	struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context;
450b2283dadSPing-Ke Shih 	u8 cmd_buffer[4] = {0};
451b2283dadSPing-Ke Shih 
452b2283dadSPing-Ke Shih 	if (btcoexist->bt_info.bt_supported_feature)
453b2283dadSPing-Ke Shih 		goto label_done;
454b2283dadSPing-Ke Shih 
455b2283dadSPing-Ke Shih 	/* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */
456b2283dadSPing-Ke Shih 	halbtc_send_bt_mp_operation(btcoexist,
457b2283dadSPing-Ke Shih 				    BT_OP_GET_BT_COEX_SUPPORTED_FEATURE,
458b2283dadSPing-Ke Shih 				    cmd_buffer, 4, 200);
459b2283dadSPing-Ke Shih 
460b2283dadSPing-Ke Shih label_done:
461b2283dadSPing-Ke Shih 	return btcoexist->bt_info.bt_supported_feature;
462b2283dadSPing-Ke Shih }
463b2283dadSPing-Ke Shih 
464b2283dadSPing-Ke Shih static u32 halbtc_get_bt_coex_supported_version(void *btc_context)
465b2283dadSPing-Ke Shih {
466b2283dadSPing-Ke Shih 	struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context;
467b2283dadSPing-Ke Shih 	u8 cmd_buffer[4] = {0};
468b2283dadSPing-Ke Shih 
469b2283dadSPing-Ke Shih 	if (btcoexist->bt_info.bt_supported_version)
470b2283dadSPing-Ke Shih 		goto label_done;
471b2283dadSPing-Ke Shih 
472b2283dadSPing-Ke Shih 	/* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */
473b2283dadSPing-Ke Shih 	halbtc_send_bt_mp_operation(btcoexist,
474b2283dadSPing-Ke Shih 				    BT_OP_GET_BT_COEX_SUPPORTED_VERSION,
475b2283dadSPing-Ke Shih 				    cmd_buffer, 4, 200);
476b2283dadSPing-Ke Shih 
477b2283dadSPing-Ke Shih label_done:
478b2283dadSPing-Ke Shih 	return btcoexist->bt_info.bt_supported_version;
479b2283dadSPing-Ke Shih }
480b2283dadSPing-Ke Shih 
481b2283dadSPing-Ke Shih static u32 halbtc_get_bt_device_info(void *btc_context)
482b2283dadSPing-Ke Shih {
483b2283dadSPing-Ke Shih 	struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context;
484b2283dadSPing-Ke Shih 	u8 cmd_buffer[4] = {0};
485b2283dadSPing-Ke Shih 
486b2283dadSPing-Ke Shih 	/* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */
487b2283dadSPing-Ke Shih 	halbtc_send_bt_mp_operation(btcoexist,
488b2283dadSPing-Ke Shih 				    BT_OP_GET_BT_DEVICE_INFO,
489b2283dadSPing-Ke Shih 				    cmd_buffer, 4, 200);
490b2283dadSPing-Ke Shih 
491b2283dadSPing-Ke Shih 	return btcoexist->bt_info.bt_device_info;
492b2283dadSPing-Ke Shih }
493b2283dadSPing-Ke Shih 
494b2283dadSPing-Ke Shih static u32 halbtc_get_bt_forbidden_slot_val(void *btc_context)
495b2283dadSPing-Ke Shih {
496b2283dadSPing-Ke Shih 	struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context;
497b2283dadSPing-Ke Shih 	u8 cmd_buffer[4] = {0};
498b2283dadSPing-Ke Shih 
499b2283dadSPing-Ke Shih 	/* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */
500b2283dadSPing-Ke Shih 	halbtc_send_bt_mp_operation(btcoexist,
501b2283dadSPing-Ke Shih 				    BT_OP_GET_BT_FORBIDDEN_SLOT_VAL,
502b2283dadSPing-Ke Shih 				    cmd_buffer, 4, 200);
503b2283dadSPing-Ke Shih 
504b2283dadSPing-Ke Shih 	return btcoexist->bt_info.bt_forb_slot_val;
505b2283dadSPing-Ke Shih }
506b2283dadSPing-Ke Shih 
507c42ea613SYan-Hsuan Chuang u32 halbtc_get_wifi_link_status(struct btc_coexist *btcoexist)
508f1d2b4d3SLarry Finger {
509c42ea613SYan-Hsuan Chuang 	/* return value:
510c42ea613SYan-Hsuan Chuang 	 * [31:16] => connected port number
511c42ea613SYan-Hsuan Chuang 	 * [15:0]  => port connected bit define
512c42ea613SYan-Hsuan Chuang 	 */
513c42ea613SYan-Hsuan Chuang 	struct rtl_priv *rtlpriv = btcoexist->adapter;
514c42ea613SYan-Hsuan Chuang 	struct rtl_mac *mac = rtl_mac(rtlpriv);
515c42ea613SYan-Hsuan Chuang 	u32 ret_val = 0;
516c42ea613SYan-Hsuan Chuang 	u32 port_connected_status = 0, num_of_connected_port = 0;
517c42ea613SYan-Hsuan Chuang 
518c42ea613SYan-Hsuan Chuang 	if (mac->opmode == NL80211_IFTYPE_STATION &&
519c42ea613SYan-Hsuan Chuang 	    mac->link_state >= MAC80211_LINKED) {
520c42ea613SYan-Hsuan Chuang 		port_connected_status |= WIFI_STA_CONNECTED;
521c42ea613SYan-Hsuan Chuang 		num_of_connected_port++;
522c42ea613SYan-Hsuan Chuang 	}
523c42ea613SYan-Hsuan Chuang 	/* AP & ADHOC & MESH */
524c42ea613SYan-Hsuan Chuang 	if (is_any_client_connect_to_ap(btcoexist)) {
525c42ea613SYan-Hsuan Chuang 		port_connected_status |= WIFI_AP_CONNECTED;
526c42ea613SYan-Hsuan Chuang 		num_of_connected_port++;
527c42ea613SYan-Hsuan Chuang 	}
528c42ea613SYan-Hsuan Chuang 	/* TODO: P2P Connected Status */
529c42ea613SYan-Hsuan Chuang 
530c42ea613SYan-Hsuan Chuang 	ret_val = (num_of_connected_port << 16) | port_connected_status;
531c42ea613SYan-Hsuan Chuang 
532c42ea613SYan-Hsuan Chuang 	return ret_val;
533c42ea613SYan-Hsuan Chuang }
534c42ea613SYan-Hsuan Chuang 
535c42ea613SYan-Hsuan Chuang static s32 halbtc_get_wifi_rssi(struct rtl_priv *rtlpriv)
536c42ea613SYan-Hsuan Chuang {
537c42ea613SYan-Hsuan Chuang 	int undec_sm_pwdb = 0;
538f1d2b4d3SLarry Finger 
539f1d2b4d3SLarry Finger 	if (rtlpriv->mac80211.link_state >= MAC80211_LINKED)
540f1d2b4d3SLarry Finger 		undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb;
541f1d2b4d3SLarry Finger 	else /* associated entry pwdb */
542f1d2b4d3SLarry Finger 		undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb;
543f1d2b4d3SLarry Finger 	return undec_sm_pwdb;
544f1d2b4d3SLarry Finger }
545f1d2b4d3SLarry Finger 
546f1d2b4d3SLarry Finger static bool halbtc_get(void *void_btcoexist, u8 get_type, void *out_buf)
547f1d2b4d3SLarry Finger {
548f1d2b4d3SLarry Finger 	struct btc_coexist *btcoexist = (struct btc_coexist *)void_btcoexist;
549f1d2b4d3SLarry Finger 	struct rtl_priv *rtlpriv = btcoexist->adapter;
550f1d2b4d3SLarry Finger 	struct rtl_phy *rtlphy = &(rtlpriv->phy);
551f1d2b4d3SLarry Finger 	struct rtl_mac *mac = rtl_mac(rtlpriv);
552f1d2b4d3SLarry Finger 	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
553f1d2b4d3SLarry Finger 	bool *bool_tmp = (bool *)out_buf;
554f1d2b4d3SLarry Finger 	int *s32_tmp = (int *)out_buf;
555f1d2b4d3SLarry Finger 	u32 *u32_tmp = (u32 *)out_buf;
556f1d2b4d3SLarry Finger 	u8 *u8_tmp = (u8 *)out_buf;
557f1d2b4d3SLarry Finger 	bool tmp = false;
558838dd0d3SPing-Ke Shih 	bool ret = true;
559f1d2b4d3SLarry Finger 
560f1d2b4d3SLarry Finger 	if (!halbtc_is_bt_coexist_available(btcoexist))
561f1d2b4d3SLarry Finger 		return false;
562f1d2b4d3SLarry Finger 
563f1d2b4d3SLarry Finger 	switch (get_type) {
564f1d2b4d3SLarry Finger 	case BTC_GET_BL_HS_OPERATION:
565f1d2b4d3SLarry Finger 		*bool_tmp = false;
566838dd0d3SPing-Ke Shih 		ret = false;
567f1d2b4d3SLarry Finger 		break;
568f1d2b4d3SLarry Finger 	case BTC_GET_BL_HS_CONNECTING:
569f1d2b4d3SLarry Finger 		*bool_tmp = false;
570838dd0d3SPing-Ke Shih 		ret = false;
571f1d2b4d3SLarry Finger 		break;
572f1d2b4d3SLarry Finger 	case BTC_GET_BL_WIFI_CONNECTED:
573c42ea613SYan-Hsuan Chuang 		if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_STATION &&
574c42ea613SYan-Hsuan Chuang 		    rtlpriv->mac80211.link_state >= MAC80211_LINKED)
575c42ea613SYan-Hsuan Chuang 			tmp = true;
576c42ea613SYan-Hsuan Chuang 		if (is_any_client_connect_to_ap(btcoexist))
577f1d2b4d3SLarry Finger 			tmp = true;
578f1d2b4d3SLarry Finger 		*bool_tmp = tmp;
579f1d2b4d3SLarry Finger 		break;
580f1d2b4d3SLarry Finger 	case BTC_GET_BL_WIFI_BUSY:
581f1d2b4d3SLarry Finger 		if (halbtc_is_wifi_busy(rtlpriv))
582f1d2b4d3SLarry Finger 			*bool_tmp = true;
583f1d2b4d3SLarry Finger 		else
584f1d2b4d3SLarry Finger 			*bool_tmp = false;
585f1d2b4d3SLarry Finger 		break;
586f1d2b4d3SLarry Finger 	case BTC_GET_BL_WIFI_SCAN:
587f1d2b4d3SLarry Finger 		if (mac->act_scanning)
588f1d2b4d3SLarry Finger 			*bool_tmp = true;
589f1d2b4d3SLarry Finger 		else
590f1d2b4d3SLarry Finger 			*bool_tmp = false;
591f1d2b4d3SLarry Finger 		break;
592f1d2b4d3SLarry Finger 	case BTC_GET_BL_WIFI_LINK:
593f1d2b4d3SLarry Finger 		if (mac->link_state == MAC80211_LINKING)
594f1d2b4d3SLarry Finger 			*bool_tmp = true;
595f1d2b4d3SLarry Finger 		else
596f1d2b4d3SLarry Finger 			*bool_tmp = false;
597f1d2b4d3SLarry Finger 		break;
598c42ea613SYan-Hsuan Chuang 	case BTC_GET_BL_WIFI_ROAM:
599f1d2b4d3SLarry Finger 		if (mac->link_state == MAC80211_LINKING)
600f1d2b4d3SLarry Finger 			*bool_tmp = true;
601f1d2b4d3SLarry Finger 		else
602f1d2b4d3SLarry Finger 			*bool_tmp = false;
603f1d2b4d3SLarry Finger 		break;
604c42ea613SYan-Hsuan Chuang 	case BTC_GET_BL_WIFI_4_WAY_PROGRESS:
60576f146b6SPing-Ke Shih 		*bool_tmp = rtlpriv->btcoexist.btc_info.in_4way;
606f1d2b4d3SLarry Finger 		break;
607f1d2b4d3SLarry Finger 	case BTC_GET_BL_WIFI_UNDER_5G:
608838dd0d3SPing-Ke Shih 		if (rtlhal->current_bandtype == BAND_ON_5G)
609838dd0d3SPing-Ke Shih 			*bool_tmp = true;
610838dd0d3SPing-Ke Shih 		else
611f1d2b4d3SLarry Finger 			*bool_tmp = false;
612f1d2b4d3SLarry Finger 		break;
613f1d2b4d3SLarry Finger 	case BTC_GET_BL_WIFI_AP_MODE_ENABLE:
614838dd0d3SPing-Ke Shih 		if (mac->opmode == NL80211_IFTYPE_AP)
615838dd0d3SPing-Ke Shih 			*bool_tmp = true;
616838dd0d3SPing-Ke Shih 		else
617f1d2b4d3SLarry Finger 			*bool_tmp = false;
618f1d2b4d3SLarry Finger 		break;
619f1d2b4d3SLarry Finger 	case BTC_GET_BL_WIFI_ENABLE_ENCRYPTION:
620f1d2b4d3SLarry Finger 		if (NO_ENCRYPTION == rtlpriv->sec.pairwise_enc_algorithm)
621f1d2b4d3SLarry Finger 			*bool_tmp = false;
622f1d2b4d3SLarry Finger 		else
623f1d2b4d3SLarry Finger 			*bool_tmp = true;
624f1d2b4d3SLarry Finger 		break;
625f1d2b4d3SLarry Finger 	case BTC_GET_BL_WIFI_UNDER_B_MODE:
626c42ea613SYan-Hsuan Chuang 		if (rtlpriv->mac80211.mode == WIRELESS_MODE_B)
627c42ea613SYan-Hsuan Chuang 			*bool_tmp = true;
628c42ea613SYan-Hsuan Chuang 		else
629c42ea613SYan-Hsuan Chuang 			*bool_tmp = false;
630f1d2b4d3SLarry Finger 		break;
631f1d2b4d3SLarry Finger 	case BTC_GET_BL_EXT_SWITCH:
632f1d2b4d3SLarry Finger 		*bool_tmp = false;
633f1d2b4d3SLarry Finger 		break;
634c42ea613SYan-Hsuan Chuang 	case BTC_GET_BL_WIFI_IS_IN_MP_MODE:
635c42ea613SYan-Hsuan Chuang 		*bool_tmp = false;
636c42ea613SYan-Hsuan Chuang 		break;
637c42ea613SYan-Hsuan Chuang 	case BTC_GET_BL_IS_ASUS_8723B:
638c42ea613SYan-Hsuan Chuang 		*bool_tmp = false;
639c42ea613SYan-Hsuan Chuang 		break;
640f1d2b4d3SLarry Finger 	case BTC_GET_S4_WIFI_RSSI:
641f1d2b4d3SLarry Finger 		*s32_tmp = halbtc_get_wifi_rssi(rtlpriv);
642f1d2b4d3SLarry Finger 		break;
643c42ea613SYan-Hsuan Chuang 	case BTC_GET_S4_HS_RSSI:
644838dd0d3SPing-Ke Shih 		*s32_tmp = 0;
645838dd0d3SPing-Ke Shih 		ret = false;
646f1d2b4d3SLarry Finger 		break;
647f1d2b4d3SLarry Finger 	case BTC_GET_U4_WIFI_BW:
648f1d2b4d3SLarry Finger 		*u32_tmp = halbtc_get_wifi_bw(btcoexist);
649f1d2b4d3SLarry Finger 		break;
650f1d2b4d3SLarry Finger 	case BTC_GET_U4_WIFI_TRAFFIC_DIRECTION:
651f1d2b4d3SLarry Finger 		if (halbtc_is_wifi_uplink(rtlpriv))
652f1d2b4d3SLarry Finger 			*u32_tmp = BTC_WIFI_TRAFFIC_TX;
653f1d2b4d3SLarry Finger 		else
654f1d2b4d3SLarry Finger 			*u32_tmp = BTC_WIFI_TRAFFIC_RX;
655f1d2b4d3SLarry Finger 		break;
656f1d2b4d3SLarry Finger 	case BTC_GET_U4_WIFI_FW_VER:
657c42ea613SYan-Hsuan Chuang 		*u32_tmp = (rtlhal->fw_version << 16) | rtlhal->fw_subversion;
658c42ea613SYan-Hsuan Chuang 		break;
659c42ea613SYan-Hsuan Chuang 	case BTC_GET_U4_WIFI_LINK_STATUS:
660c42ea613SYan-Hsuan Chuang 		*u32_tmp = halbtc_get_wifi_link_status(btcoexist);
661f1d2b4d3SLarry Finger 		break;
662f1d2b4d3SLarry Finger 	case BTC_GET_U4_BT_PATCH_VER:
663f1d2b4d3SLarry Finger 		*u32_tmp = halbtc_get_bt_patch_version(btcoexist);
664f1d2b4d3SLarry Finger 		break;
6651a281473SPing-Ke Shih 	case BTC_GET_U4_VENDOR:
6661a281473SPing-Ke Shih 		*u32_tmp = BTC_VENDOR_OTHER;
6671a281473SPing-Ke Shih 		break;
668b2283dadSPing-Ke Shih 	case BTC_GET_U4_SUPPORTED_VERSION:
669b2283dadSPing-Ke Shih 		*u32_tmp = halbtc_get_bt_coex_supported_version(btcoexist);
670b2283dadSPing-Ke Shih 		break;
671b2283dadSPing-Ke Shih 	case BTC_GET_U4_SUPPORTED_FEATURE:
672b2283dadSPing-Ke Shih 		*u32_tmp = halbtc_get_bt_coex_supported_feature(btcoexist);
673b2283dadSPing-Ke Shih 		break;
674b2283dadSPing-Ke Shih 	case BTC_GET_U4_BT_DEVICE_INFO:
675b2283dadSPing-Ke Shih 		*u32_tmp = halbtc_get_bt_device_info(btcoexist);
676b2283dadSPing-Ke Shih 		break;
677b2283dadSPing-Ke Shih 	case BTC_GET_U4_BT_FORBIDDEN_SLOT_VAL:
678b2283dadSPing-Ke Shih 		*u32_tmp = halbtc_get_bt_forbidden_slot_val(btcoexist);
679b2283dadSPing-Ke Shih 		break;
680f1d2b4d3SLarry Finger 	case BTC_GET_U1_WIFI_DOT11_CHNL:
681f1d2b4d3SLarry Finger 		*u8_tmp = rtlphy->current_channel;
682f1d2b4d3SLarry Finger 		break;
683f1d2b4d3SLarry Finger 	case BTC_GET_U1_WIFI_CENTRAL_CHNL:
684f1d2b4d3SLarry Finger 		*u8_tmp = halbtc_get_wifi_central_chnl(btcoexist);
685f1d2b4d3SLarry Finger 		break;
686f1d2b4d3SLarry Finger 	case BTC_GET_U1_WIFI_HS_CHNL:
687838dd0d3SPing-Ke Shih 		*u8_tmp = 0;
688838dd0d3SPing-Ke Shih 		ret = false;
689f1d2b4d3SLarry Finger 		break;
690c42ea613SYan-Hsuan Chuang 	case BTC_GET_U1_AP_NUM:
691f1cb27edSPing-Ke Shih 		*u8_tmp = rtlpriv->btcoexist.btc_info.ap_num;
692c42ea613SYan-Hsuan Chuang 		break;
693c42ea613SYan-Hsuan Chuang 	case BTC_GET_U1_ANT_TYPE:
694c42ea613SYan-Hsuan Chuang 		*u8_tmp = (u8)BTC_ANT_TYPE_0;
695c42ea613SYan-Hsuan Chuang 		break;
696c42ea613SYan-Hsuan Chuang 	case BTC_GET_U1_IOT_PEER:
697c42ea613SYan-Hsuan Chuang 		*u8_tmp = 0;
698f1d2b4d3SLarry Finger 		break;
699f1d2b4d3SLarry Finger 
700f1d2b4d3SLarry Finger 		/************* 1Ant **************/
701f1d2b4d3SLarry Finger 	case BTC_GET_U1_LPS_MODE:
702f1d2b4d3SLarry Finger 		*u8_tmp = btcoexist->pwr_mode_val[0];
703f1d2b4d3SLarry Finger 		break;
704f1d2b4d3SLarry Finger 
705f1d2b4d3SLarry Finger 	default:
706838dd0d3SPing-Ke Shih 		ret = false;
707f1d2b4d3SLarry Finger 		break;
708f1d2b4d3SLarry Finger 	}
709f1d2b4d3SLarry Finger 
710838dd0d3SPing-Ke Shih 	return ret;
711f1d2b4d3SLarry Finger }
712f1d2b4d3SLarry Finger 
713f1d2b4d3SLarry Finger static bool halbtc_set(void *void_btcoexist, u8 set_type, void *in_buf)
714f1d2b4d3SLarry Finger {
715f1d2b4d3SLarry Finger 	struct btc_coexist *btcoexist = (struct btc_coexist *)void_btcoexist;
716f1d2b4d3SLarry Finger 	bool *bool_tmp = (bool *)in_buf;
717f1d2b4d3SLarry Finger 	u8 *u8_tmp = (u8 *)in_buf;
718f1d2b4d3SLarry Finger 	u32 *u32_tmp = (u32 *)in_buf;
7198488e211SPing-Ke Shih 	bool ret = true;
720f1d2b4d3SLarry Finger 
721f1d2b4d3SLarry Finger 	if (!halbtc_is_bt_coexist_available(btcoexist))
722f1d2b4d3SLarry Finger 		return false;
723f1d2b4d3SLarry Finger 
724f1d2b4d3SLarry Finger 	switch (set_type) {
725f1d2b4d3SLarry Finger 	/* set some bool type variables. */
726f1d2b4d3SLarry Finger 	case BTC_SET_BL_BT_DISABLE:
727f1d2b4d3SLarry Finger 		btcoexist->bt_info.bt_disabled = *bool_tmp;
728f1d2b4d3SLarry Finger 		break;
729f1d2b4d3SLarry Finger 	case BTC_SET_BL_BT_TRAFFIC_BUSY:
730f1d2b4d3SLarry Finger 		btcoexist->bt_info.bt_busy = *bool_tmp;
731f1d2b4d3SLarry Finger 		break;
732f1d2b4d3SLarry Finger 	case BTC_SET_BL_BT_LIMITED_DIG:
733f1d2b4d3SLarry Finger 		btcoexist->bt_info.limited_dig = *bool_tmp;
734f1d2b4d3SLarry Finger 		break;
735f1d2b4d3SLarry Finger 	case BTC_SET_BL_FORCE_TO_ROAM:
736f1d2b4d3SLarry Finger 		btcoexist->bt_info.force_to_roam = *bool_tmp;
737f1d2b4d3SLarry Finger 		break;
738f1d2b4d3SLarry Finger 	case BTC_SET_BL_TO_REJ_AP_AGG_PKT:
739f1d2b4d3SLarry Finger 		btcoexist->bt_info.reject_agg_pkt = *bool_tmp;
740f1d2b4d3SLarry Finger 		break;
741f1d2b4d3SLarry Finger 	case BTC_SET_BL_BT_CTRL_AGG_SIZE:
742c42ea613SYan-Hsuan Chuang 		btcoexist->bt_info.bt_ctrl_agg_buf_size = *bool_tmp;
743f1d2b4d3SLarry Finger 		break;
744f1d2b4d3SLarry Finger 	case BTC_SET_BL_INC_SCAN_DEV_NUM:
745f1d2b4d3SLarry Finger 		btcoexist->bt_info.increase_scan_dev_num = *bool_tmp;
746f1d2b4d3SLarry Finger 		break;
747c42ea613SYan-Hsuan Chuang 	case BTC_SET_BL_BT_TX_RX_MASK:
748c42ea613SYan-Hsuan Chuang 		btcoexist->bt_info.bt_tx_rx_mask = *bool_tmp;
749c42ea613SYan-Hsuan Chuang 		break;
750c42ea613SYan-Hsuan Chuang 	case BTC_SET_BL_MIRACAST_PLUS_BT:
751c42ea613SYan-Hsuan Chuang 		btcoexist->bt_info.miracast_plus_bt = *bool_tmp;
752c42ea613SYan-Hsuan Chuang 		break;
753f1d2b4d3SLarry Finger 		/* set some u1Byte type variables. */
754f1d2b4d3SLarry Finger 	case BTC_SET_U1_RSSI_ADJ_VAL_FOR_AGC_TABLE_ON:
755f1d2b4d3SLarry Finger 		btcoexist->bt_info.rssi_adjust_for_agc_table_on = *u8_tmp;
756f1d2b4d3SLarry Finger 		break;
757f1d2b4d3SLarry Finger 	case BTC_SET_U1_AGG_BUF_SIZE:
758f1d2b4d3SLarry Finger 		btcoexist->bt_info.agg_buf_size = *u8_tmp;
759f1d2b4d3SLarry Finger 		break;
760c42ea613SYan-Hsuan Chuang 
761f1d2b4d3SLarry Finger 	/* the following are some action which will be triggered */
762f1d2b4d3SLarry Finger 	case BTC_SET_ACT_GET_BT_RSSI:
7638488e211SPing-Ke Shih 		ret = false;
764f1d2b4d3SLarry Finger 		break;
765f1d2b4d3SLarry Finger 	case BTC_SET_ACT_AGGREGATE_CTRL:
766c42ea613SYan-Hsuan Chuang 		halbtc_aggregation_check(btcoexist);
767f1d2b4d3SLarry Finger 		break;
768f1d2b4d3SLarry Finger 
769f1d2b4d3SLarry Finger 	/* 1Ant */
770f1d2b4d3SLarry Finger 	case BTC_SET_U1_RSSI_ADJ_VAL_FOR_1ANT_COEX_TYPE:
771f1d2b4d3SLarry Finger 		btcoexist->bt_info.rssi_adjust_for_1ant_coex_type = *u8_tmp;
772f1d2b4d3SLarry Finger 		break;
773f1d2b4d3SLarry Finger 	case BTC_SET_UI_SCAN_SIG_COMPENSATION:
774f1d2b4d3SLarry Finger 		break;
775c42ea613SYan-Hsuan Chuang 	case BTC_SET_U1_LPS_VAL:
776f1d2b4d3SLarry Finger 		btcoexist->bt_info.lps_val = *u8_tmp;
777f1d2b4d3SLarry Finger 		break;
778c42ea613SYan-Hsuan Chuang 	case BTC_SET_U1_RPWM_VAL:
779f1d2b4d3SLarry Finger 		btcoexist->bt_info.rpwm_val = *u8_tmp;
780f1d2b4d3SLarry Finger 		break;
781f1d2b4d3SLarry Finger 	/* the following are some action which will be triggered  */
782f1d2b4d3SLarry Finger 	case BTC_SET_ACT_LEAVE_LPS:
783f1d2b4d3SLarry Finger 		halbtc_leave_lps(btcoexist);
784f1d2b4d3SLarry Finger 		break;
785f1d2b4d3SLarry Finger 	case BTC_SET_ACT_ENTER_LPS:
786f1d2b4d3SLarry Finger 		halbtc_enter_lps(btcoexist);
787f1d2b4d3SLarry Finger 		break;
788f1d2b4d3SLarry Finger 	case BTC_SET_ACT_NORMAL_LPS:
789f1d2b4d3SLarry Finger 		halbtc_normal_lps(btcoexist);
790f1d2b4d3SLarry Finger 		break;
791f1d2b4d3SLarry Finger 	case BTC_SET_ACT_DISABLE_LOW_POWER:
792c42ea613SYan-Hsuan Chuang 		halbtc_disable_low_power(btcoexist, *bool_tmp);
793f1d2b4d3SLarry Finger 		break;
794c6821613SYan-Hsuan Chuang 	case BTC_SET_ACT_UPDATE_RAMASK:
795f1d2b4d3SLarry Finger 		btcoexist->bt_info.ra_mask = *u32_tmp;
796f1d2b4d3SLarry Finger 		break;
797f1d2b4d3SLarry Finger 	case BTC_SET_ACT_SEND_MIMO_PS:
798f1d2b4d3SLarry Finger 		break;
799f1d2b4d3SLarry Finger 	case BTC_SET_ACT_CTRL_BT_INFO: /*wait for 8812/8821*/
800f1d2b4d3SLarry Finger 		break;
801f1d2b4d3SLarry Finger 	case BTC_SET_ACT_CTRL_BT_COEX:
802f1d2b4d3SLarry Finger 		break;
803c42ea613SYan-Hsuan Chuang 	case BTC_SET_ACT_CTRL_8723B_ANT:
804c42ea613SYan-Hsuan Chuang 		break;
805f1d2b4d3SLarry Finger 	default:
806f1d2b4d3SLarry Finger 		break;
807f1d2b4d3SLarry Finger 	}
808f1d2b4d3SLarry Finger 
8098488e211SPing-Ke Shih 	return ret;
810f1d2b4d3SLarry Finger }
811f1d2b4d3SLarry Finger 
81208431b62SPing-Ke Shih static void halbtc_display_coex_statistics(struct btc_coexist *btcoexist,
81308431b62SPing-Ke Shih 					   struct seq_file *m)
81408431b62SPing-Ke Shih {
81508431b62SPing-Ke Shih }
81608431b62SPing-Ke Shih 
81708431b62SPing-Ke Shih static void halbtc_display_bt_link_info(struct btc_coexist *btcoexist,
81808431b62SPing-Ke Shih 					struct seq_file *m)
81908431b62SPing-Ke Shih {
82008431b62SPing-Ke Shih }
82108431b62SPing-Ke Shih 
82208431b62SPing-Ke Shih static void halbtc_display_wifi_status(struct btc_coexist *btcoexist,
82308431b62SPing-Ke Shih 				       struct seq_file *m)
82408431b62SPing-Ke Shih {
82508431b62SPing-Ke Shih 	struct rtl_priv *rtlpriv = btcoexist->adapter;
82608431b62SPing-Ke Shih 	s32 wifi_rssi = 0, bt_hs_rssi = 0;
82708431b62SPing-Ke Shih 	bool scan = false, link = false, roam = false, wifi_busy = false;
82808431b62SPing-Ke Shih 	bool wifi_under_b_mode = false;
82908431b62SPing-Ke Shih 	bool wifi_under_5g = false;
83008431b62SPing-Ke Shih 	u32 wifi_bw = BTC_WIFI_BW_HT20;
83108431b62SPing-Ke Shih 	u32 wifi_traffic_dir = BTC_WIFI_TRAFFIC_TX;
83208431b62SPing-Ke Shih 	u32 wifi_freq = BTC_FREQ_2_4G;
83308431b62SPing-Ke Shih 	u32 wifi_link_status = 0x0;
83408431b62SPing-Ke Shih 	bool bt_hs_on = false, under_ips = false, under_lps = false;
83508431b62SPing-Ke Shih 	bool low_power = false, dc_mode = false;
8367e2c4922SColin Ian King 	u8 wifi_chnl = 0, wifi_hs_chnl = 0;
83708431b62SPing-Ke Shih 	u8 ap_num = 0;
83808431b62SPing-Ke Shih 
83908431b62SPing-Ke Shih 	wifi_link_status = halbtc_get_wifi_link_status(btcoexist);
84008431b62SPing-Ke Shih 	seq_printf(m, "\n %-35s = %d/ %d/ %d/ %d/ %d",
84108431b62SPing-Ke Shih 		   "STA/vWifi/HS/p2pGo/p2pGc",
84208431b62SPing-Ke Shih 		   ((wifi_link_status & WIFI_STA_CONNECTED) ? 1 : 0),
84308431b62SPing-Ke Shih 		   ((wifi_link_status & WIFI_AP_CONNECTED) ? 1 : 0),
84408431b62SPing-Ke Shih 		   ((wifi_link_status & WIFI_HS_CONNECTED) ? 1 : 0),
84508431b62SPing-Ke Shih 		   ((wifi_link_status & WIFI_P2P_GO_CONNECTED) ? 1 : 0),
84608431b62SPing-Ke Shih 		   ((wifi_link_status & WIFI_P2P_GC_CONNECTED) ? 1 : 0));
84708431b62SPing-Ke Shih 
84808431b62SPing-Ke Shih 	btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
84908431b62SPing-Ke Shih 	btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_DOT11_CHNL, &wifi_chnl);
85008431b62SPing-Ke Shih 	btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_HS_CHNL, &wifi_hs_chnl);
85108431b62SPing-Ke Shih 	seq_printf(m, "\n %-35s = %d / %d(%d)",
85208431b62SPing-Ke Shih 		   "Dot11 channel / HsChnl(High Speed)",
85308431b62SPing-Ke Shih 		   wifi_chnl, wifi_hs_chnl, bt_hs_on);
85408431b62SPing-Ke Shih 
85508431b62SPing-Ke Shih 	btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi);
85608431b62SPing-Ke Shih 	btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi);
85708431b62SPing-Ke Shih 	seq_printf(m, "\n %-35s = %d/ %d",
85808431b62SPing-Ke Shih 		   "Wifi rssi/ HS rssi",
85908431b62SPing-Ke Shih 		   wifi_rssi - 100, bt_hs_rssi - 100);
86008431b62SPing-Ke Shih 
86108431b62SPing-Ke Shih 	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan);
86208431b62SPing-Ke Shih 	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link);
86308431b62SPing-Ke Shih 	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam);
86408431b62SPing-Ke Shih 	seq_printf(m, "\n %-35s = %d/ %d/ %d ",
86508431b62SPing-Ke Shih 		   "Wifi link/ roam/ scan",
86608431b62SPing-Ke Shih 		   link, roam, scan);
86708431b62SPing-Ke Shih 
86808431b62SPing-Ke Shih 	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
86908431b62SPing-Ke Shih 	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
87008431b62SPing-Ke Shih 	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
87108431b62SPing-Ke Shih 	btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION,
87208431b62SPing-Ke Shih 			   &wifi_traffic_dir);
87308431b62SPing-Ke Shih 	btcoexist->btc_get(btcoexist, BTC_GET_U1_AP_NUM, &ap_num);
87408431b62SPing-Ke Shih 	wifi_freq = (wifi_under_5g ? BTC_FREQ_5G : BTC_FREQ_2_4G);
87508431b62SPing-Ke Shih 	btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_B_MODE,
87608431b62SPing-Ke Shih 			   &wifi_under_b_mode);
87708431b62SPing-Ke Shih 
87808431b62SPing-Ke Shih 	seq_printf(m, "\n %-35s = %s / %s/ %s/ AP=%d ",
87908431b62SPing-Ke Shih 		   "Wifi freq/ bw/ traffic",
88008431b62SPing-Ke Shih 		   gl_btc_wifi_freq_string[wifi_freq],
88108431b62SPing-Ke Shih 		   ((wifi_under_b_mode) ? "11b" :
88208431b62SPing-Ke Shih 		    gl_btc_wifi_bw_string[wifi_bw]),
88308431b62SPing-Ke Shih 		   ((!wifi_busy) ? "idle" : ((BTC_WIFI_TRAFFIC_TX ==
88408431b62SPing-Ke Shih 					      wifi_traffic_dir) ? "uplink" :
88508431b62SPing-Ke Shih 					     "downlink")),
88608431b62SPing-Ke Shih 		   ap_num);
88708431b62SPing-Ke Shih 
88808431b62SPing-Ke Shih 	/* power status	 */
88908431b62SPing-Ke Shih 	dc_mode = true;	/*TODO*/
89008431b62SPing-Ke Shih 	under_ips = rtlpriv->psc.inactive_pwrstate == ERFOFF ? 1 : 0;
89108431b62SPing-Ke Shih 	under_lps = rtlpriv->psc.dot11_psmode == EACTIVE ? 0 : 1;
89208431b62SPing-Ke Shih 	low_power = 0; /*TODO*/
89308431b62SPing-Ke Shih 	seq_printf(m, "\n %-35s = %s%s%s%s",
89408431b62SPing-Ke Shih 		   "Power Status",
89508431b62SPing-Ke Shih 		   (dc_mode ? "DC mode" : "AC mode"),
89608431b62SPing-Ke Shih 		   (under_ips ? ", IPS ON" : ""),
89708431b62SPing-Ke Shih 		   (under_lps ? ", LPS ON" : ""),
89808431b62SPing-Ke Shih 		   (low_power ? ", 32k" : ""));
89908431b62SPing-Ke Shih 
90008431b62SPing-Ke Shih 	seq_printf(m,
90108431b62SPing-Ke Shih 		   "\n %-35s = %02x %02x %02x %02x %02x %02x (0x%x/0x%x)",
90208431b62SPing-Ke Shih 		   "Power mode cmd(lps/rpwm)",
90308431b62SPing-Ke Shih 		   btcoexist->pwr_mode_val[0], btcoexist->pwr_mode_val[1],
90408431b62SPing-Ke Shih 		   btcoexist->pwr_mode_val[2], btcoexist->pwr_mode_val[3],
90508431b62SPing-Ke Shih 		   btcoexist->pwr_mode_val[4], btcoexist->pwr_mode_val[5],
90608431b62SPing-Ke Shih 		   btcoexist->bt_info.lps_val,
90708431b62SPing-Ke Shih 		   btcoexist->bt_info.rpwm_val);
90808431b62SPing-Ke Shih }
90908431b62SPing-Ke Shih 
910f1d2b4d3SLarry Finger /************************************************************
911f1d2b4d3SLarry Finger  *		IO related function
912f1d2b4d3SLarry Finger  ************************************************************/
913f1d2b4d3SLarry Finger static u8 halbtc_read_1byte(void *bt_context, u32 reg_addr)
914f1d2b4d3SLarry Finger {
915f1d2b4d3SLarry Finger 	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
916f1d2b4d3SLarry Finger 	struct rtl_priv *rtlpriv = btcoexist->adapter;
917f1d2b4d3SLarry Finger 
918f1d2b4d3SLarry Finger 	return	rtl_read_byte(rtlpriv, reg_addr);
919f1d2b4d3SLarry Finger }
920f1d2b4d3SLarry Finger 
921f1d2b4d3SLarry Finger static u16 halbtc_read_2byte(void *bt_context, u32 reg_addr)
922f1d2b4d3SLarry Finger {
923f1d2b4d3SLarry Finger 	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
924f1d2b4d3SLarry Finger 	struct rtl_priv *rtlpriv = btcoexist->adapter;
925f1d2b4d3SLarry Finger 
926f1d2b4d3SLarry Finger 	return	rtl_read_word(rtlpriv, reg_addr);
927f1d2b4d3SLarry Finger }
928f1d2b4d3SLarry Finger 
929f1d2b4d3SLarry Finger static u32 halbtc_read_4byte(void *bt_context, u32 reg_addr)
930f1d2b4d3SLarry Finger {
931f1d2b4d3SLarry Finger 	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
932f1d2b4d3SLarry Finger 	struct rtl_priv *rtlpriv = btcoexist->adapter;
933f1d2b4d3SLarry Finger 
934f1d2b4d3SLarry Finger 	return	rtl_read_dword(rtlpriv, reg_addr);
935f1d2b4d3SLarry Finger }
936f1d2b4d3SLarry Finger 
937f1d2b4d3SLarry Finger static void halbtc_write_1byte(void *bt_context, u32 reg_addr, u32 data)
938f1d2b4d3SLarry Finger {
939f1d2b4d3SLarry Finger 	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
940f1d2b4d3SLarry Finger 	struct rtl_priv *rtlpriv = btcoexist->adapter;
941f1d2b4d3SLarry Finger 
942f1d2b4d3SLarry Finger 	rtl_write_byte(rtlpriv, reg_addr, data);
943f1d2b4d3SLarry Finger }
944f1d2b4d3SLarry Finger 
945f1d2b4d3SLarry Finger static void halbtc_bitmask_write_1byte(void *bt_context, u32 reg_addr,
946f1d2b4d3SLarry Finger 				       u32 bit_mask, u8 data)
947f1d2b4d3SLarry Finger {
948f1d2b4d3SLarry Finger 	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
949f1d2b4d3SLarry Finger 	struct rtl_priv *rtlpriv = btcoexist->adapter;
950f1d2b4d3SLarry Finger 	u8 original_value, bit_shift = 0;
951f1d2b4d3SLarry Finger 	u8 i;
952f1d2b4d3SLarry Finger 
953f1d2b4d3SLarry Finger 	if (bit_mask != MASKDWORD) {/*if not "double word" write*/
954f1d2b4d3SLarry Finger 		original_value = rtl_read_byte(rtlpriv, reg_addr);
955f1d2b4d3SLarry Finger 		for (i = 0; i <= 7; i++) {
956f1d2b4d3SLarry Finger 			if ((bit_mask>>i) & 0x1)
957f1d2b4d3SLarry Finger 				break;
958f1d2b4d3SLarry Finger 		}
959f1d2b4d3SLarry Finger 		bit_shift = i;
960f1d2b4d3SLarry Finger 		data = (original_value & (~bit_mask)) |
961f1d2b4d3SLarry Finger 			((data << bit_shift) & bit_mask);
962f1d2b4d3SLarry Finger 	}
963f1d2b4d3SLarry Finger 	rtl_write_byte(rtlpriv, reg_addr, data);
964f1d2b4d3SLarry Finger }
965f1d2b4d3SLarry Finger 
966f1d2b4d3SLarry Finger static void halbtc_write_2byte(void *bt_context, u32 reg_addr, u16 data)
967f1d2b4d3SLarry Finger {
968f1d2b4d3SLarry Finger 	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
969f1d2b4d3SLarry Finger 	struct rtl_priv *rtlpriv = btcoexist->adapter;
970f1d2b4d3SLarry Finger 
971f1d2b4d3SLarry Finger 	rtl_write_word(rtlpriv, reg_addr, data);
972f1d2b4d3SLarry Finger }
973f1d2b4d3SLarry Finger 
974f1d2b4d3SLarry Finger static void halbtc_write_4byte(void *bt_context, u32 reg_addr, u32 data)
975f1d2b4d3SLarry Finger {
976f1d2b4d3SLarry Finger 	struct btc_coexist *btcoexist =
977f1d2b4d3SLarry Finger 		(struct btc_coexist *)bt_context;
978f1d2b4d3SLarry Finger 	struct rtl_priv *rtlpriv = btcoexist->adapter;
979f1d2b4d3SLarry Finger 
980f1d2b4d3SLarry Finger 	rtl_write_dword(rtlpriv, reg_addr, data);
981f1d2b4d3SLarry Finger }
982f1d2b4d3SLarry Finger 
983c42ea613SYan-Hsuan Chuang void halbtc_write_local_reg_1byte(void *btc_context, u32 reg_addr, u8 data)
984c42ea613SYan-Hsuan Chuang {
985c42ea613SYan-Hsuan Chuang 	struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context;
986c42ea613SYan-Hsuan Chuang 	struct rtl_priv *rtlpriv = btcoexist->adapter;
987c42ea613SYan-Hsuan Chuang 
988c42ea613SYan-Hsuan Chuang 	if (btcoexist->chip_interface == BTC_INTF_SDIO)
989c42ea613SYan-Hsuan Chuang 		;
990c42ea613SYan-Hsuan Chuang 	else if (btcoexist->chip_interface == BTC_INTF_PCI)
991c42ea613SYan-Hsuan Chuang 		rtl_write_byte(rtlpriv, reg_addr, data);
992c42ea613SYan-Hsuan Chuang 	else if (btcoexist->chip_interface == BTC_INTF_USB)
993c42ea613SYan-Hsuan Chuang 		rtl_write_byte(rtlpriv, reg_addr, data);
994c42ea613SYan-Hsuan Chuang }
995c42ea613SYan-Hsuan Chuang 
996c42ea613SYan-Hsuan Chuang void halbtc_set_macreg(void *btc_context, u32 reg_addr, u32 bit_mask, u32 data)
997c42ea613SYan-Hsuan Chuang {
998c42ea613SYan-Hsuan Chuang 	struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context;
999c42ea613SYan-Hsuan Chuang 	struct rtl_priv *rtlpriv = btcoexist->adapter;
1000c42ea613SYan-Hsuan Chuang 
1001c42ea613SYan-Hsuan Chuang 	rtl_set_bbreg(rtlpriv->mac80211.hw, reg_addr, bit_mask, data);
1002c42ea613SYan-Hsuan Chuang }
1003c42ea613SYan-Hsuan Chuang 
1004c42ea613SYan-Hsuan Chuang u32 halbtc_get_macreg(void *btc_context, u32 reg_addr, u32 bit_mask)
1005c42ea613SYan-Hsuan Chuang {
1006c42ea613SYan-Hsuan Chuang 	struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context;
1007c42ea613SYan-Hsuan Chuang 	struct rtl_priv *rtlpriv = btcoexist->adapter;
1008c42ea613SYan-Hsuan Chuang 
1009c42ea613SYan-Hsuan Chuang 	return rtl_get_bbreg(rtlpriv->mac80211.hw, reg_addr, bit_mask);
1010c42ea613SYan-Hsuan Chuang }
1011c42ea613SYan-Hsuan Chuang 
1012f1d2b4d3SLarry Finger static void halbtc_set_bbreg(void *bt_context, u32 reg_addr, u32 bit_mask,
1013f1d2b4d3SLarry Finger 			     u32 data)
1014f1d2b4d3SLarry Finger {
1015f1d2b4d3SLarry Finger 	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
1016f1d2b4d3SLarry Finger 	struct rtl_priv *rtlpriv = btcoexist->adapter;
1017f1d2b4d3SLarry Finger 
1018f1d2b4d3SLarry Finger 	rtl_set_bbreg(rtlpriv->mac80211.hw, reg_addr, bit_mask, data);
1019f1d2b4d3SLarry Finger }
1020f1d2b4d3SLarry Finger 
1021f1d2b4d3SLarry Finger static u32 halbtc_get_bbreg(void *bt_context, u32 reg_addr, u32 bit_mask)
1022f1d2b4d3SLarry Finger {
1023f1d2b4d3SLarry Finger 	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
1024f1d2b4d3SLarry Finger 	struct rtl_priv *rtlpriv = btcoexist->adapter;
1025f1d2b4d3SLarry Finger 
1026f1d2b4d3SLarry Finger 	return rtl_get_bbreg(rtlpriv->mac80211.hw, reg_addr, bit_mask);
1027f1d2b4d3SLarry Finger }
1028f1d2b4d3SLarry Finger 
1029f1d2b4d3SLarry Finger static void halbtc_set_rfreg(void *bt_context, u8 rf_path, u32 reg_addr,
1030f1d2b4d3SLarry Finger 			     u32 bit_mask, u32 data)
1031f1d2b4d3SLarry Finger {
1032f1d2b4d3SLarry Finger 	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
1033f1d2b4d3SLarry Finger 	struct rtl_priv *rtlpriv = btcoexist->adapter;
1034f1d2b4d3SLarry Finger 
1035f1d2b4d3SLarry Finger 	rtl_set_rfreg(rtlpriv->mac80211.hw, rf_path, reg_addr, bit_mask, data);
1036f1d2b4d3SLarry Finger }
1037f1d2b4d3SLarry Finger 
1038f1d2b4d3SLarry Finger static u32 halbtc_get_rfreg(void *bt_context, u8 rf_path, u32 reg_addr,
1039f1d2b4d3SLarry Finger 			    u32 bit_mask)
1040f1d2b4d3SLarry Finger {
1041f1d2b4d3SLarry Finger 	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
1042f1d2b4d3SLarry Finger 	struct rtl_priv *rtlpriv = btcoexist->adapter;
1043f1d2b4d3SLarry Finger 
1044f1d2b4d3SLarry Finger 	return rtl_get_rfreg(rtlpriv->mac80211.hw, rf_path, reg_addr, bit_mask);
1045f1d2b4d3SLarry Finger }
1046f1d2b4d3SLarry Finger 
1047f1d2b4d3SLarry Finger static void halbtc_fill_h2c_cmd(void *bt_context, u8 element_id,
1048f1d2b4d3SLarry Finger 				u32 cmd_len, u8 *cmd_buf)
1049f1d2b4d3SLarry Finger {
1050f1d2b4d3SLarry Finger 	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
1051f1d2b4d3SLarry Finger 	struct rtl_priv *rtlpriv = btcoexist->adapter;
1052f1d2b4d3SLarry Finger 
1053f1d2b4d3SLarry Finger 	rtlpriv->cfg->ops->fill_h2c_cmd(rtlpriv->mac80211.hw, element_id,
1054f1d2b4d3SLarry Finger 					cmd_len, cmd_buf);
1055f1d2b4d3SLarry Finger }
1056f1d2b4d3SLarry Finger 
1057c42ea613SYan-Hsuan Chuang void halbtc_set_bt_reg(void *btc_context, u8 reg_type, u32 offset, u32 set_val)
1058c42ea613SYan-Hsuan Chuang {
1059c42ea613SYan-Hsuan Chuang 	struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context;
1060c42ea613SYan-Hsuan Chuang 	u8 cmd_buffer1[4] = {0};
1061c42ea613SYan-Hsuan Chuang 	u8 cmd_buffer2[4] = {0};
1062c42ea613SYan-Hsuan Chuang 
1063b2283dadSPing-Ke Shih 	/* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */
1064b2283dadSPing-Ke Shih 	*((__le16 *)&cmd_buffer1[2]) = cpu_to_le16((u16)set_val);
1065b2283dadSPing-Ke Shih 	if (!halbtc_send_bt_mp_operation(btcoexist, BT_OP_WRITE_REG_VALUE,
1066b2283dadSPing-Ke Shih 					 cmd_buffer1, 4, 200))
1067b2283dadSPing-Ke Shih 		return;
1068c42ea613SYan-Hsuan Chuang 
1069b2283dadSPing-Ke Shih 	/* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */
1070b2283dadSPing-Ke Shih 	cmd_buffer2[2] = reg_type;
1071b2283dadSPing-Ke Shih 	*((u8 *)&cmd_buffer2[3]) = (u8)offset;
1072b2283dadSPing-Ke Shih 	halbtc_send_bt_mp_operation(btcoexist, BT_OP_WRITE_REG_ADDR,
1073b2283dadSPing-Ke Shih 				    cmd_buffer2, 4, 200);
1074c42ea613SYan-Hsuan Chuang }
1075c42ea613SYan-Hsuan Chuang 
107608431b62SPing-Ke Shih static void halbtc_display_dbg_msg(void *bt_context, u8 disp_type,
107708431b62SPing-Ke Shih 				   struct seq_file *m)
107808431b62SPing-Ke Shih {
107908431b62SPing-Ke Shih 	struct btc_coexist *btcoexist = (struct btc_coexist *)bt_context;
108008431b62SPing-Ke Shih 
108108431b62SPing-Ke Shih 	switch (disp_type) {
108208431b62SPing-Ke Shih 	case BTC_DBG_DISP_COEX_STATISTICS:
108308431b62SPing-Ke Shih 		halbtc_display_coex_statistics(btcoexist, m);
108408431b62SPing-Ke Shih 		break;
108508431b62SPing-Ke Shih 	case BTC_DBG_DISP_BT_LINK_INFO:
108608431b62SPing-Ke Shih 		halbtc_display_bt_link_info(btcoexist, m);
108708431b62SPing-Ke Shih 		break;
108808431b62SPing-Ke Shih 	case BTC_DBG_DISP_WIFI_STATUS:
108908431b62SPing-Ke Shih 		halbtc_display_wifi_status(btcoexist, m);
109008431b62SPing-Ke Shih 		break;
109108431b62SPing-Ke Shih 	default:
109208431b62SPing-Ke Shih 		break;
109308431b62SPing-Ke Shih 	}
109408431b62SPing-Ke Shih }
109508431b62SPing-Ke Shih 
10967937f02dSYan-Hsuan Chuang bool halbtc_under_ips(struct btc_coexist *btcoexist)
10977937f02dSYan-Hsuan Chuang {
10987937f02dSYan-Hsuan Chuang 	struct rtl_priv *rtlpriv = btcoexist->adapter;
10997937f02dSYan-Hsuan Chuang 	struct rtl_ps_ctl *ppsc = rtl_psc(rtlpriv);
11007937f02dSYan-Hsuan Chuang 	enum rf_pwrstate rtstate;
11017937f02dSYan-Hsuan Chuang 
11027937f02dSYan-Hsuan Chuang 	if (ppsc->inactiveps) {
11037937f02dSYan-Hsuan Chuang 		rtstate = ppsc->rfpwr_state;
11047937f02dSYan-Hsuan Chuang 
11057937f02dSYan-Hsuan Chuang 		if (rtstate != ERFON &&
11067937f02dSYan-Hsuan Chuang 		    ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
11077937f02dSYan-Hsuan Chuang 			return true;
11087937f02dSYan-Hsuan Chuang 		}
11097937f02dSYan-Hsuan Chuang 	}
11107937f02dSYan-Hsuan Chuang 
11117937f02dSYan-Hsuan Chuang 	return false;
11127937f02dSYan-Hsuan Chuang }
11137937f02dSYan-Hsuan Chuang 
1114b2283dadSPing-Ke Shih static u8 halbtc_get_ant_det_val_from_bt(void *btc_context)
1115b2283dadSPing-Ke Shih {
1116b2283dadSPing-Ke Shih 	struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context;
1117b2283dadSPing-Ke Shih 	u8 cmd_buffer[4] = {0};
1118b2283dadSPing-Ke Shih 
1119b2283dadSPing-Ke Shih 	/* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */
1120b2283dadSPing-Ke Shih 	halbtc_send_bt_mp_operation(btcoexist, BT_OP_GET_BT_ANT_DET_VAL,
1121b2283dadSPing-Ke Shih 				    cmd_buffer, 4, 200);
1122b2283dadSPing-Ke Shih 
1123b2283dadSPing-Ke Shih 	/* need wait completion to return correct value */
1124b2283dadSPing-Ke Shih 
1125b2283dadSPing-Ke Shih 	return btcoexist->bt_info.bt_ant_det_val;
1126b2283dadSPing-Ke Shih }
1127b2283dadSPing-Ke Shih 
1128b2283dadSPing-Ke Shih static u8 halbtc_get_ble_scan_type_from_bt(void *btc_context)
1129b2283dadSPing-Ke Shih {
1130b2283dadSPing-Ke Shih 	struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context;
1131b2283dadSPing-Ke Shih 	u8 cmd_buffer[4] = {0};
1132b2283dadSPing-Ke Shih 
1133b2283dadSPing-Ke Shih 	/* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */
1134b2283dadSPing-Ke Shih 	halbtc_send_bt_mp_operation(btcoexist, BT_OP_GET_BT_BLE_SCAN_TYPE,
1135b2283dadSPing-Ke Shih 				    cmd_buffer, 4, 200);
1136b2283dadSPing-Ke Shih 
1137b2283dadSPing-Ke Shih 	/* need wait completion to return correct value */
1138b2283dadSPing-Ke Shih 
1139b2283dadSPing-Ke Shih 	return btcoexist->bt_info.bt_ble_scan_type;
1140b2283dadSPing-Ke Shih }
1141b2283dadSPing-Ke Shih 
1142b2283dadSPing-Ke Shih static u32 halbtc_get_ble_scan_para_from_bt(void *btc_context, u8 scan_type)
1143b2283dadSPing-Ke Shih {
1144b2283dadSPing-Ke Shih 	struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context;
1145b2283dadSPing-Ke Shih 	u8 cmd_buffer[4] = {0};
1146b2283dadSPing-Ke Shih 
1147b2283dadSPing-Ke Shih 	/* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */
1148b2283dadSPing-Ke Shih 	halbtc_send_bt_mp_operation(btcoexist, BT_OP_GET_BT_BLE_SCAN_PARA,
1149b2283dadSPing-Ke Shih 				    cmd_buffer, 4, 200);
1150b2283dadSPing-Ke Shih 
1151b2283dadSPing-Ke Shih 	/* need wait completion to return correct value */
1152b2283dadSPing-Ke Shih 
1153b2283dadSPing-Ke Shih 	return btcoexist->bt_info.bt_ble_scan_para;
1154b2283dadSPing-Ke Shih }
1155b2283dadSPing-Ke Shih 
1156b2283dadSPing-Ke Shih static bool halbtc_get_bt_afh_map_from_bt(void *btc_context, u8 map_type,
1157b2283dadSPing-Ke Shih 					  u8 *afh_map)
1158b2283dadSPing-Ke Shih {
1159b2283dadSPing-Ke Shih 	struct btc_coexist *btcoexist = (struct btc_coexist *)btc_context;
1160b2283dadSPing-Ke Shih 	u8 cmd_buffer[2] = {0};
1161b2283dadSPing-Ke Shih 	bool ret;
1162b2283dadSPing-Ke Shih 	u32 *afh_map_l = (u32 *)afh_map;
1163b2283dadSPing-Ke Shih 	u32 *afh_map_m = (u32 *)(afh_map + 4);
1164b2283dadSPing-Ke Shih 	u16 *afh_map_h = (u16 *)(afh_map + 8);
1165b2283dadSPing-Ke Shih 
1166b2283dadSPing-Ke Shih 	/* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */
1167b2283dadSPing-Ke Shih 	ret = halbtc_send_bt_mp_operation(btcoexist, BT_OP_GET_AFH_MAP_L,
1168b2283dadSPing-Ke Shih 					  cmd_buffer, 2, 200);
1169b2283dadSPing-Ke Shih 	if (!ret)
1170b2283dadSPing-Ke Shih 		goto exit;
1171b2283dadSPing-Ke Shih 
1172b2283dadSPing-Ke Shih 	*afh_map_l = btcoexist->bt_info.afh_map_l;
1173b2283dadSPing-Ke Shih 
1174b2283dadSPing-Ke Shih 	/* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */
1175b2283dadSPing-Ke Shih 	ret = halbtc_send_bt_mp_operation(btcoexist, BT_OP_GET_AFH_MAP_M,
1176b2283dadSPing-Ke Shih 					  cmd_buffer, 2, 200);
1177b2283dadSPing-Ke Shih 	if (!ret)
1178b2283dadSPing-Ke Shih 		goto exit;
1179b2283dadSPing-Ke Shih 
1180b2283dadSPing-Ke Shih 	*afh_map_m = btcoexist->bt_info.afh_map_m;
1181b2283dadSPing-Ke Shih 
1182b2283dadSPing-Ke Shih 	/* cmd_buffer[0] and [1] is filled by halbtc_send_bt_mp_operation() */
1183b2283dadSPing-Ke Shih 	ret = halbtc_send_bt_mp_operation(btcoexist, BT_OP_GET_AFH_MAP_H,
1184b2283dadSPing-Ke Shih 					  cmd_buffer, 2, 200);
1185b2283dadSPing-Ke Shih 	if (!ret)
1186b2283dadSPing-Ke Shih 		goto exit;
1187b2283dadSPing-Ke Shih 
1188b2283dadSPing-Ke Shih 	*afh_map_h = btcoexist->bt_info.afh_map_h;
1189b2283dadSPing-Ke Shih 
1190b2283dadSPing-Ke Shih exit:
1191b2283dadSPing-Ke Shih 	return ret;
1192b2283dadSPing-Ke Shih }
1193b2283dadSPing-Ke Shih 
1194f1d2b4d3SLarry Finger /*****************************************************************
1195f1d2b4d3SLarry Finger  *         Extern functions called by other module
1196f1d2b4d3SLarry Finger  *****************************************************************/
119740d9dd4fSPing-Ke Shih bool exhalbtc_initlize_variables(struct rtl_priv *rtlpriv)
1198f1d2b4d3SLarry Finger {
119940d9dd4fSPing-Ke Shih 	struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv);
120040d9dd4fSPing-Ke Shih 
120140d9dd4fSPing-Ke Shih 	if (!btcoexist)
120240d9dd4fSPing-Ke Shih 		return false;
1203f1d2b4d3SLarry Finger 
1204f1d2b4d3SLarry Finger 	halbtc_dbg_init();
1205f1d2b4d3SLarry Finger 
1206f1d2b4d3SLarry Finger 	btcoexist->btc_read_1byte = halbtc_read_1byte;
1207f1d2b4d3SLarry Finger 	btcoexist->btc_write_1byte = halbtc_write_1byte;
1208f1d2b4d3SLarry Finger 	btcoexist->btc_write_1byte_bitmask = halbtc_bitmask_write_1byte;
1209f1d2b4d3SLarry Finger 	btcoexist->btc_read_2byte = halbtc_read_2byte;
1210f1d2b4d3SLarry Finger 	btcoexist->btc_write_2byte = halbtc_write_2byte;
1211f1d2b4d3SLarry Finger 	btcoexist->btc_read_4byte = halbtc_read_4byte;
1212f1d2b4d3SLarry Finger 	btcoexist->btc_write_4byte = halbtc_write_4byte;
1213c42ea613SYan-Hsuan Chuang 	btcoexist->btc_write_local_reg_1byte = halbtc_write_local_reg_1byte;
1214f1d2b4d3SLarry Finger 
1215f1d2b4d3SLarry Finger 	btcoexist->btc_set_bb_reg = halbtc_set_bbreg;
1216f1d2b4d3SLarry Finger 	btcoexist->btc_get_bb_reg = halbtc_get_bbreg;
1217f1d2b4d3SLarry Finger 
1218f1d2b4d3SLarry Finger 	btcoexist->btc_set_rf_reg = halbtc_set_rfreg;
1219f1d2b4d3SLarry Finger 	btcoexist->btc_get_rf_reg = halbtc_get_rfreg;
1220f1d2b4d3SLarry Finger 
1221f1d2b4d3SLarry Finger 	btcoexist->btc_fill_h2c = halbtc_fill_h2c_cmd;
122208431b62SPing-Ke Shih 	btcoexist->btc_disp_dbg_msg = halbtc_display_dbg_msg;
1223f1d2b4d3SLarry Finger 
1224f1d2b4d3SLarry Finger 	btcoexist->btc_get = halbtc_get;
1225f1d2b4d3SLarry Finger 	btcoexist->btc_set = halbtc_set;
1226c42ea613SYan-Hsuan Chuang 	btcoexist->btc_set_bt_reg = halbtc_set_bt_reg;
1227c42ea613SYan-Hsuan Chuang 
1228f1d2b4d3SLarry Finger 	btcoexist->bt_info.bt_ctrl_buf_size = false;
1229f1d2b4d3SLarry Finger 	btcoexist->bt_info.agg_buf_size = 5;
1230f1d2b4d3SLarry Finger 
1231f1d2b4d3SLarry Finger 	btcoexist->bt_info.increase_scan_dev_num = false;
1232b2283dadSPing-Ke Shih 
1233b2283dadSPing-Ke Shih 	btcoexist->btc_get_bt_coex_supported_feature =
1234b2283dadSPing-Ke Shih 					halbtc_get_bt_coex_supported_feature;
1235b2283dadSPing-Ke Shih 	btcoexist->btc_get_bt_coex_supported_version =
1236b2283dadSPing-Ke Shih 					halbtc_get_bt_coex_supported_version;
1237b2283dadSPing-Ke Shih 	btcoexist->btc_get_ant_det_val_from_bt = halbtc_get_ant_det_val_from_bt;
1238b2283dadSPing-Ke Shih 	btcoexist->btc_get_ble_scan_type_from_bt =
1239b2283dadSPing-Ke Shih 					halbtc_get_ble_scan_type_from_bt;
1240b2283dadSPing-Ke Shih 	btcoexist->btc_get_ble_scan_para_from_bt =
1241b2283dadSPing-Ke Shih 					halbtc_get_ble_scan_para_from_bt;
1242b2283dadSPing-Ke Shih 	btcoexist->btc_get_bt_afh_map_from_bt =
1243b2283dadSPing-Ke Shih 					halbtc_get_bt_afh_map_from_bt;
1244b2283dadSPing-Ke Shih 
1245b2283dadSPing-Ke Shih 	init_completion(&btcoexist->bt_mp_comp);
1246b2283dadSPing-Ke Shih 
1247f1d2b4d3SLarry Finger 	return true;
1248f1d2b4d3SLarry Finger }
1249f1d2b4d3SLarry Finger 
12500199103eSYan-Hsuan Chuang bool exhalbtc_bind_bt_coex_withadapter(void *adapter)
12510199103eSYan-Hsuan Chuang {
12520199103eSYan-Hsuan Chuang 	struct rtl_priv *rtlpriv = adapter;
125340d9dd4fSPing-Ke Shih 	struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv);
125440d9dd4fSPing-Ke Shih 	u8 ant_num = 2, chip_type, single_ant_path = 0;
125540d9dd4fSPing-Ke Shih 
125640d9dd4fSPing-Ke Shih 	if (!btcoexist)
125740d9dd4fSPing-Ke Shih 		return false;
12580199103eSYan-Hsuan Chuang 
12590199103eSYan-Hsuan Chuang 	if (btcoexist->binded)
12600199103eSYan-Hsuan Chuang 		return false;
12610199103eSYan-Hsuan Chuang 
126243f5644aSPing-Ke Shih 	switch (rtlpriv->rtlhal.interface) {
126343f5644aSPing-Ke Shih 	case INTF_PCI:
126443f5644aSPing-Ke Shih 		btcoexist->chip_interface = BTC_INTF_PCI;
126543f5644aSPing-Ke Shih 		break;
126643f5644aSPing-Ke Shih 	case INTF_USB:
126743f5644aSPing-Ke Shih 		btcoexist->chip_interface = BTC_INTF_USB;
126843f5644aSPing-Ke Shih 		break;
126943f5644aSPing-Ke Shih 	default:
127043f5644aSPing-Ke Shih 		btcoexist->chip_interface = BTC_INTF_UNKNOWN;
127143f5644aSPing-Ke Shih 		break;
127243f5644aSPing-Ke Shih 	}
127343f5644aSPing-Ke Shih 
12740199103eSYan-Hsuan Chuang 	btcoexist->binded = true;
12750199103eSYan-Hsuan Chuang 	btcoexist->statistics.cnt_bind++;
12760199103eSYan-Hsuan Chuang 
12770199103eSYan-Hsuan Chuang 	btcoexist->adapter = adapter;
12780199103eSYan-Hsuan Chuang 
12790199103eSYan-Hsuan Chuang 	btcoexist->stack_info.profile_notified = false;
12800199103eSYan-Hsuan Chuang 
12810199103eSYan-Hsuan Chuang 	btcoexist->bt_info.bt_ctrl_agg_buf_size = false;
12820199103eSYan-Hsuan Chuang 	btcoexist->bt_info.agg_buf_size = 5;
12830199103eSYan-Hsuan Chuang 
12840199103eSYan-Hsuan Chuang 	btcoexist->bt_info.increase_scan_dev_num = false;
12850199103eSYan-Hsuan Chuang 	btcoexist->bt_info.miracast_plus_bt = false;
12860199103eSYan-Hsuan Chuang 
12870199103eSYan-Hsuan Chuang 	chip_type = rtl_get_hwpg_bt_type(rtlpriv);
128840d9dd4fSPing-Ke Shih 	exhalbtc_set_chip_type(btcoexist, chip_type);
12890199103eSYan-Hsuan Chuang 	ant_num = rtl_get_hwpg_ant_num(rtlpriv);
12900199103eSYan-Hsuan Chuang 	exhalbtc_set_ant_num(rtlpriv, BT_COEX_ANT_TYPE_PG, ant_num);
12910199103eSYan-Hsuan Chuang 
129240d9dd4fSPing-Ke Shih 	/* set default antenna position to main  port */
129340d9dd4fSPing-Ke Shih 	btcoexist->board_info.btdm_ant_pos = BTC_ANTENNA_AT_MAIN_PORT;
129440d9dd4fSPing-Ke Shih 
129540d9dd4fSPing-Ke Shih 	single_ant_path = rtl_get_hwpg_single_ant_path(rtlpriv);
129640d9dd4fSPing-Ke Shih 	exhalbtc_set_single_ant_path(btcoexist, single_ant_path);
129740d9dd4fSPing-Ke Shih 
12980199103eSYan-Hsuan Chuang 	if (rtl_get_hwpg_package_type(rtlpriv) == 0)
12990199103eSYan-Hsuan Chuang 		btcoexist->board_info.tfbga_package = false;
13000199103eSYan-Hsuan Chuang 	else if (rtl_get_hwpg_package_type(rtlpriv) == 1)
13010199103eSYan-Hsuan Chuang 		btcoexist->board_info.tfbga_package = false;
13020199103eSYan-Hsuan Chuang 	else
13030199103eSYan-Hsuan Chuang 		btcoexist->board_info.tfbga_package = true;
13040199103eSYan-Hsuan Chuang 
13050199103eSYan-Hsuan Chuang 	if (btcoexist->board_info.tfbga_package)
13060199103eSYan-Hsuan Chuang 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
13070199103eSYan-Hsuan Chuang 			 "[BTCoex], Package Type = TFBGA\n");
13080199103eSYan-Hsuan Chuang 	else
13090199103eSYan-Hsuan Chuang 		RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
13100199103eSYan-Hsuan Chuang 			 "[BTCoex], Package Type = Non-TFBGA\n");
13110199103eSYan-Hsuan Chuang 
1312188b6b09SPing-Ke Shih 	btcoexist->board_info.rfe_type = rtl_get_hwpg_rfe_type(rtlpriv);
1313188b6b09SPing-Ke Shih 
13140199103eSYan-Hsuan Chuang 	return true;
13150199103eSYan-Hsuan Chuang }
13160199103eSYan-Hsuan Chuang 
131760f44100SYan-Hsuan Chuang void exhalbtc_power_on_setting(struct btc_coexist *btcoexist)
131860f44100SYan-Hsuan Chuang {
131960f44100SYan-Hsuan Chuang 	if (!halbtc_is_bt_coexist_available(btcoexist))
132060f44100SYan-Hsuan Chuang 		return;
132160f44100SYan-Hsuan Chuang 
132260f44100SYan-Hsuan Chuang 	btcoexist->statistics.cnt_power_on++;
132360f44100SYan-Hsuan Chuang 
132460f44100SYan-Hsuan Chuang 	if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) {
132560f44100SYan-Hsuan Chuang 		if (btcoexist->board_info.btdm_ant_num == 2)
132660f44100SYan-Hsuan Chuang 			ex_btc8723b2ant_power_on_setting(btcoexist);
132760f44100SYan-Hsuan Chuang 		else if (btcoexist->board_info.btdm_ant_num == 1)
132860f44100SYan-Hsuan Chuang 			ex_btc8723b1ant_power_on_setting(btcoexist);
132960f44100SYan-Hsuan Chuang 	}
133060f44100SYan-Hsuan Chuang }
133160f44100SYan-Hsuan Chuang 
13326fbbc82aSYan-Hsuan Chuang void exhalbtc_pre_load_firmware(struct btc_coexist *btcoexist)
13336fbbc82aSYan-Hsuan Chuang {
13346fbbc82aSYan-Hsuan Chuang 	if (!halbtc_is_bt_coexist_available(btcoexist))
13356fbbc82aSYan-Hsuan Chuang 		return;
13366fbbc82aSYan-Hsuan Chuang 
13376fbbc82aSYan-Hsuan Chuang 	btcoexist->statistics.cnt_pre_load_firmware++;
13386fbbc82aSYan-Hsuan Chuang 
13396fbbc82aSYan-Hsuan Chuang 	if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) {
13406fbbc82aSYan-Hsuan Chuang 		if (btcoexist->board_info.btdm_ant_num == 2)
13416fbbc82aSYan-Hsuan Chuang 			ex_btc8723b2ant_pre_load_firmware(btcoexist);
13426fbbc82aSYan-Hsuan Chuang 	}
13436fbbc82aSYan-Hsuan Chuang }
13446fbbc82aSYan-Hsuan Chuang 
134543f5644aSPing-Ke Shih void exhalbtc_init_hw_config(struct btc_coexist *btcoexist, bool wifi_only)
1346f1d2b4d3SLarry Finger {
1347f1d2b4d3SLarry Finger 	if (!halbtc_is_bt_coexist_available(btcoexist))
1348f1d2b4d3SLarry Finger 		return;
1349f1d2b4d3SLarry Finger 
1350f1d2b4d3SLarry Finger 	btcoexist->statistics.cnt_init_hw_config++;
1351f1d2b4d3SLarry Finger 
13527937f02dSYan-Hsuan Chuang 	if (IS_HARDWARE_TYPE_8821(btcoexist->adapter)) {
13537937f02dSYan-Hsuan Chuang 		if (btcoexist->board_info.btdm_ant_num == 2)
13547937f02dSYan-Hsuan Chuang 			ex_btc8821a2ant_init_hwconfig(btcoexist);
13557937f02dSYan-Hsuan Chuang 		else if (btcoexist->board_info.btdm_ant_num == 1)
13567937f02dSYan-Hsuan Chuang 			ex_btc8821a1ant_init_hwconfig(btcoexist, wifi_only);
13577937f02dSYan-Hsuan Chuang 	} else if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) {
13587937f02dSYan-Hsuan Chuang 		if (btcoexist->board_info.btdm_ant_num == 2)
1359f1d2b4d3SLarry Finger 			ex_btc8723b2ant_init_hwconfig(btcoexist);
13607937f02dSYan-Hsuan Chuang 		else if (btcoexist->board_info.btdm_ant_num == 1)
13617937f02dSYan-Hsuan Chuang 			ex_btc8723b1ant_init_hwconfig(btcoexist, wifi_only);
13627937f02dSYan-Hsuan Chuang 	} else if (IS_HARDWARE_TYPE_8723A(btcoexist->adapter)) {
13637937f02dSYan-Hsuan Chuang 		/* 8723A has no this function */
13647937f02dSYan-Hsuan Chuang 	} else if (IS_HARDWARE_TYPE_8192E(btcoexist->adapter)) {
13657937f02dSYan-Hsuan Chuang 		if (btcoexist->board_info.btdm_ant_num == 2)
13667937f02dSYan-Hsuan Chuang 			ex_btc8192e2ant_init_hwconfig(btcoexist);
13677937f02dSYan-Hsuan Chuang 	}
1368f1d2b4d3SLarry Finger }
1369f1d2b4d3SLarry Finger 
1370f1d2b4d3SLarry Finger void exhalbtc_init_coex_dm(struct btc_coexist *btcoexist)
1371f1d2b4d3SLarry Finger {
1372f1d2b4d3SLarry Finger 	if (!halbtc_is_bt_coexist_available(btcoexist))
1373f1d2b4d3SLarry Finger 		return;
1374f1d2b4d3SLarry Finger 
1375f1d2b4d3SLarry Finger 	btcoexist->statistics.cnt_init_coex_dm++;
1376f1d2b4d3SLarry Finger 
13777937f02dSYan-Hsuan Chuang 	if (IS_HARDWARE_TYPE_8821(btcoexist->adapter)) {
13787937f02dSYan-Hsuan Chuang 		if (btcoexist->board_info.btdm_ant_num == 2)
13797937f02dSYan-Hsuan Chuang 			ex_btc8821a2ant_init_coex_dm(btcoexist);
13807937f02dSYan-Hsuan Chuang 		else if (btcoexist->board_info.btdm_ant_num == 1)
13817937f02dSYan-Hsuan Chuang 			ex_btc8821a1ant_init_coex_dm(btcoexist);
13827937f02dSYan-Hsuan Chuang 	} else if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) {
13837937f02dSYan-Hsuan Chuang 		if (btcoexist->board_info.btdm_ant_num == 2)
1384f1d2b4d3SLarry Finger 			ex_btc8723b2ant_init_coex_dm(btcoexist);
13857937f02dSYan-Hsuan Chuang 		else if (btcoexist->board_info.btdm_ant_num == 1)
13867937f02dSYan-Hsuan Chuang 			ex_btc8723b1ant_init_coex_dm(btcoexist);
13877937f02dSYan-Hsuan Chuang 	} else if (IS_HARDWARE_TYPE_8192E(btcoexist->adapter)) {
13887937f02dSYan-Hsuan Chuang 		if (btcoexist->board_info.btdm_ant_num == 2)
13897937f02dSYan-Hsuan Chuang 			ex_btc8192e2ant_init_coex_dm(btcoexist);
13907937f02dSYan-Hsuan Chuang 	}
1391f1d2b4d3SLarry Finger 
1392f1d2b4d3SLarry Finger 	btcoexist->initilized = true;
1393f1d2b4d3SLarry Finger }
1394f1d2b4d3SLarry Finger 
1395f1d2b4d3SLarry Finger void exhalbtc_ips_notify(struct btc_coexist *btcoexist, u8 type)
1396f1d2b4d3SLarry Finger {
1397f1d2b4d3SLarry Finger 	u8 ips_type;
1398f1d2b4d3SLarry Finger 
1399f1d2b4d3SLarry Finger 	if (!halbtc_is_bt_coexist_available(btcoexist))
1400f1d2b4d3SLarry Finger 		return;
1401f1d2b4d3SLarry Finger 	btcoexist->statistics.cnt_ips_notify++;
1402f1d2b4d3SLarry Finger 	if (btcoexist->manual_control)
1403f1d2b4d3SLarry Finger 		return;
1404f1d2b4d3SLarry Finger 
1405f1d2b4d3SLarry Finger 	if (ERFOFF == type)
1406f1d2b4d3SLarry Finger 		ips_type = BTC_IPS_ENTER;
1407f1d2b4d3SLarry Finger 	else
1408f1d2b4d3SLarry Finger 		ips_type = BTC_IPS_LEAVE;
1409f1d2b4d3SLarry Finger 
14107937f02dSYan-Hsuan Chuang 	halbtc_leave_low_power(btcoexist);
1411f1d2b4d3SLarry Finger 
14127937f02dSYan-Hsuan Chuang 	if (IS_HARDWARE_TYPE_8821(btcoexist->adapter)) {
14137937f02dSYan-Hsuan Chuang 		if (btcoexist->board_info.btdm_ant_num == 2)
14147937f02dSYan-Hsuan Chuang 			ex_btc8821a2ant_ips_notify(btcoexist, ips_type);
14157937f02dSYan-Hsuan Chuang 		else if (btcoexist->board_info.btdm_ant_num == 1)
14167937f02dSYan-Hsuan Chuang 			ex_btc8821a1ant_ips_notify(btcoexist, ips_type);
14177937f02dSYan-Hsuan Chuang 	} else if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) {
14187937f02dSYan-Hsuan Chuang 		if (btcoexist->board_info.btdm_ant_num == 2)
1419f1d2b4d3SLarry Finger 			ex_btc8723b2ant_ips_notify(btcoexist, ips_type);
14207937f02dSYan-Hsuan Chuang 		else if (btcoexist->board_info.btdm_ant_num == 1)
14217937f02dSYan-Hsuan Chuang 			ex_btc8723b1ant_ips_notify(btcoexist, ips_type);
14227937f02dSYan-Hsuan Chuang 	} else if (IS_HARDWARE_TYPE_8192E(btcoexist->adapter)) {
14237937f02dSYan-Hsuan Chuang 		if (btcoexist->board_info.btdm_ant_num == 2)
14247937f02dSYan-Hsuan Chuang 			ex_btc8192e2ant_ips_notify(btcoexist, ips_type);
14257937f02dSYan-Hsuan Chuang 	}
1426f1d2b4d3SLarry Finger 
14277937f02dSYan-Hsuan Chuang 	halbtc_normal_low_power(btcoexist);
1428f1d2b4d3SLarry Finger }
1429f1d2b4d3SLarry Finger 
1430f1d2b4d3SLarry Finger void exhalbtc_lps_notify(struct btc_coexist *btcoexist, u8 type)
1431f1d2b4d3SLarry Finger {
1432f1d2b4d3SLarry Finger 	u8 lps_type;
1433f1d2b4d3SLarry Finger 
1434f1d2b4d3SLarry Finger 	if (!halbtc_is_bt_coexist_available(btcoexist))
1435f1d2b4d3SLarry Finger 		return;
1436f1d2b4d3SLarry Finger 	btcoexist->statistics.cnt_lps_notify++;
1437f1d2b4d3SLarry Finger 	if (btcoexist->manual_control)
1438f1d2b4d3SLarry Finger 		return;
1439f1d2b4d3SLarry Finger 
1440f1d2b4d3SLarry Finger 	if (EACTIVE == type)
1441f1d2b4d3SLarry Finger 		lps_type = BTC_LPS_DISABLE;
1442f1d2b4d3SLarry Finger 	else
1443f1d2b4d3SLarry Finger 		lps_type = BTC_LPS_ENABLE;
1444f1d2b4d3SLarry Finger 
14457937f02dSYan-Hsuan Chuang 	if (IS_HARDWARE_TYPE_8821(btcoexist->adapter)) {
14467937f02dSYan-Hsuan Chuang 		if (btcoexist->board_info.btdm_ant_num == 2)
14477937f02dSYan-Hsuan Chuang 			ex_btc8821a2ant_lps_notify(btcoexist, lps_type);
14487937f02dSYan-Hsuan Chuang 		else if (btcoexist->board_info.btdm_ant_num == 1)
14497937f02dSYan-Hsuan Chuang 			ex_btc8821a1ant_lps_notify(btcoexist, lps_type);
14507937f02dSYan-Hsuan Chuang 	} else if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) {
14517937f02dSYan-Hsuan Chuang 		if (btcoexist->board_info.btdm_ant_num == 2)
1452f1d2b4d3SLarry Finger 			ex_btc8723b2ant_lps_notify(btcoexist, lps_type);
14537937f02dSYan-Hsuan Chuang 		else if (btcoexist->board_info.btdm_ant_num == 1)
14547937f02dSYan-Hsuan Chuang 			ex_btc8723b1ant_lps_notify(btcoexist, lps_type);
14557937f02dSYan-Hsuan Chuang 	} else if (IS_HARDWARE_TYPE_8192E(btcoexist->adapter)) {
14567937f02dSYan-Hsuan Chuang 		if (btcoexist->board_info.btdm_ant_num == 2)
14577937f02dSYan-Hsuan Chuang 			ex_btc8192e2ant_lps_notify(btcoexist, lps_type);
14587937f02dSYan-Hsuan Chuang 	}
1459f1d2b4d3SLarry Finger }
1460f1d2b4d3SLarry Finger 
1461f1d2b4d3SLarry Finger void exhalbtc_scan_notify(struct btc_coexist *btcoexist, u8 type)
1462f1d2b4d3SLarry Finger {
1463f1d2b4d3SLarry Finger 	u8 scan_type;
1464f1d2b4d3SLarry Finger 
1465f1d2b4d3SLarry Finger 	if (!halbtc_is_bt_coexist_available(btcoexist))
1466f1d2b4d3SLarry Finger 		return;
1467f1d2b4d3SLarry Finger 	btcoexist->statistics.cnt_scan_notify++;
1468f1d2b4d3SLarry Finger 	if (btcoexist->manual_control)
1469f1d2b4d3SLarry Finger 		return;
1470f1d2b4d3SLarry Finger 
1471f1d2b4d3SLarry Finger 	if (type)
1472f1d2b4d3SLarry Finger 		scan_type = BTC_SCAN_START;
1473f1d2b4d3SLarry Finger 	else
1474f1d2b4d3SLarry Finger 		scan_type = BTC_SCAN_FINISH;
1475f1d2b4d3SLarry Finger 
14767937f02dSYan-Hsuan Chuang 	halbtc_leave_low_power(btcoexist);
1477f1d2b4d3SLarry Finger 
14787937f02dSYan-Hsuan Chuang 	if (IS_HARDWARE_TYPE_8821(btcoexist->adapter)) {
14797937f02dSYan-Hsuan Chuang 		if (btcoexist->board_info.btdm_ant_num == 2)
14807937f02dSYan-Hsuan Chuang 			ex_btc8821a2ant_scan_notify(btcoexist, scan_type);
14817937f02dSYan-Hsuan Chuang 		else if (btcoexist->board_info.btdm_ant_num == 1)
14827937f02dSYan-Hsuan Chuang 			ex_btc8821a1ant_scan_notify(btcoexist, scan_type);
14837937f02dSYan-Hsuan Chuang 	} else if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) {
14847937f02dSYan-Hsuan Chuang 		if (btcoexist->board_info.btdm_ant_num == 2)
1485f1d2b4d3SLarry Finger 			ex_btc8723b2ant_scan_notify(btcoexist, scan_type);
14867937f02dSYan-Hsuan Chuang 		else if (btcoexist->board_info.btdm_ant_num == 1)
14877937f02dSYan-Hsuan Chuang 			ex_btc8723b1ant_scan_notify(btcoexist, scan_type);
14887937f02dSYan-Hsuan Chuang 	} else if (IS_HARDWARE_TYPE_8192E(btcoexist->adapter)) {
14897937f02dSYan-Hsuan Chuang 		if (btcoexist->board_info.btdm_ant_num == 2)
14907937f02dSYan-Hsuan Chuang 			ex_btc8192e2ant_scan_notify(btcoexist, scan_type);
14917937f02dSYan-Hsuan Chuang 	}
1492f1d2b4d3SLarry Finger 
14937937f02dSYan-Hsuan Chuang 	halbtc_normal_low_power(btcoexist);
1494f1d2b4d3SLarry Finger }
1495f1d2b4d3SLarry Finger 
1496f1d2b4d3SLarry Finger void exhalbtc_connect_notify(struct btc_coexist *btcoexist, u8 action)
1497f1d2b4d3SLarry Finger {
1498f1d2b4d3SLarry Finger 	u8 asso_type;
1499f1d2b4d3SLarry Finger 
1500f1d2b4d3SLarry Finger 	if (!halbtc_is_bt_coexist_available(btcoexist))
1501f1d2b4d3SLarry Finger 		return;
1502f1d2b4d3SLarry Finger 	btcoexist->statistics.cnt_connect_notify++;
1503f1d2b4d3SLarry Finger 	if (btcoexist->manual_control)
1504f1d2b4d3SLarry Finger 		return;
1505f1d2b4d3SLarry Finger 
1506f1d2b4d3SLarry Finger 	if (action)
1507f1d2b4d3SLarry Finger 		asso_type = BTC_ASSOCIATE_START;
1508f1d2b4d3SLarry Finger 	else
1509f1d2b4d3SLarry Finger 		asso_type = BTC_ASSOCIATE_FINISH;
1510f1d2b4d3SLarry Finger 
15117937f02dSYan-Hsuan Chuang 	halbtc_leave_low_power(btcoexist);
1512f1d2b4d3SLarry Finger 
15137937f02dSYan-Hsuan Chuang 	if (IS_HARDWARE_TYPE_8821(btcoexist->adapter)) {
15147937f02dSYan-Hsuan Chuang 		if (btcoexist->board_info.btdm_ant_num == 2)
15157937f02dSYan-Hsuan Chuang 			ex_btc8821a2ant_connect_notify(btcoexist, asso_type);
15167937f02dSYan-Hsuan Chuang 		else if (btcoexist->board_info.btdm_ant_num == 1)
15177937f02dSYan-Hsuan Chuang 			ex_btc8821a1ant_connect_notify(btcoexist, asso_type);
15187937f02dSYan-Hsuan Chuang 	} else if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) {
15197937f02dSYan-Hsuan Chuang 		if (btcoexist->board_info.btdm_ant_num == 2)
1520f1d2b4d3SLarry Finger 			ex_btc8723b2ant_connect_notify(btcoexist, asso_type);
15217937f02dSYan-Hsuan Chuang 		else if (btcoexist->board_info.btdm_ant_num == 1)
15227937f02dSYan-Hsuan Chuang 			ex_btc8723b1ant_connect_notify(btcoexist, asso_type);
15237937f02dSYan-Hsuan Chuang 	} else if (IS_HARDWARE_TYPE_8192E(btcoexist->adapter)) {
15247937f02dSYan-Hsuan Chuang 		if (btcoexist->board_info.btdm_ant_num == 2)
15257937f02dSYan-Hsuan Chuang 			ex_btc8192e2ant_connect_notify(btcoexist, asso_type);
15267937f02dSYan-Hsuan Chuang 	}
15277937f02dSYan-Hsuan Chuang 
15287937f02dSYan-Hsuan Chuang 	halbtc_normal_low_power(btcoexist);
1529f1d2b4d3SLarry Finger }
1530f1d2b4d3SLarry Finger 
1531f1d2b4d3SLarry Finger void exhalbtc_mediastatus_notify(struct btc_coexist *btcoexist,
1532f1d2b4d3SLarry Finger 				 enum rt_media_status media_status)
1533f1d2b4d3SLarry Finger {
1534f1d2b4d3SLarry Finger 	u8 status;
1535f1d2b4d3SLarry Finger 
1536f1d2b4d3SLarry Finger 	if (!halbtc_is_bt_coexist_available(btcoexist))
1537f1d2b4d3SLarry Finger 		return;
1538f1d2b4d3SLarry Finger 	btcoexist->statistics.cnt_media_status_notify++;
1539f1d2b4d3SLarry Finger 	if (btcoexist->manual_control)
1540f1d2b4d3SLarry Finger 		return;
1541f1d2b4d3SLarry Finger 
1542f1d2b4d3SLarry Finger 	if (RT_MEDIA_CONNECT == media_status)
1543f1d2b4d3SLarry Finger 		status = BTC_MEDIA_CONNECT;
1544f1d2b4d3SLarry Finger 	else
1545f1d2b4d3SLarry Finger 		status = BTC_MEDIA_DISCONNECT;
1546f1d2b4d3SLarry Finger 
15477937f02dSYan-Hsuan Chuang 	halbtc_leave_low_power(btcoexist);
1548f1d2b4d3SLarry Finger 
15497937f02dSYan-Hsuan Chuang 	if (IS_HARDWARE_TYPE_8821(btcoexist->adapter)) {
15507937f02dSYan-Hsuan Chuang 		if (btcoexist->board_info.btdm_ant_num == 2)
15517937f02dSYan-Hsuan Chuang 			ex_btc8821a2ant_media_status_notify(btcoexist, status);
15527937f02dSYan-Hsuan Chuang 		else if (btcoexist->board_info.btdm_ant_num == 1)
15537937f02dSYan-Hsuan Chuang 			ex_btc8821a1ant_media_status_notify(btcoexist, status);
15547937f02dSYan-Hsuan Chuang 	} else if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) {
15557937f02dSYan-Hsuan Chuang 		if (btcoexist->board_info.btdm_ant_num == 2)
15567937f02dSYan-Hsuan Chuang 			ex_btc8723b2ant_media_status_notify(btcoexist, status);
15577937f02dSYan-Hsuan Chuang 		else if (btcoexist->board_info.btdm_ant_num == 1)
15587937f02dSYan-Hsuan Chuang 			ex_btc8723b1ant_media_status_notify(btcoexist, status);
15597937f02dSYan-Hsuan Chuang 	} else if (IS_HARDWARE_TYPE_8192E(btcoexist->adapter)) {
15607937f02dSYan-Hsuan Chuang 		if (btcoexist->board_info.btdm_ant_num == 2)
15617937f02dSYan-Hsuan Chuang 			ex_btc8192e2ant_media_status_notify(btcoexist, status);
15627937f02dSYan-Hsuan Chuang 	}
15637937f02dSYan-Hsuan Chuang 
15647937f02dSYan-Hsuan Chuang 	halbtc_normal_low_power(btcoexist);
1565f1d2b4d3SLarry Finger }
1566f1d2b4d3SLarry Finger 
1567f1d2b4d3SLarry Finger void exhalbtc_special_packet_notify(struct btc_coexist *btcoexist, u8 pkt_type)
1568f1d2b4d3SLarry Finger {
1569f1d2b4d3SLarry Finger 	u8 packet_type;
1570f1d2b4d3SLarry Finger 
1571f1d2b4d3SLarry Finger 	if (!halbtc_is_bt_coexist_available(btcoexist))
1572f1d2b4d3SLarry Finger 		return;
1573f1d2b4d3SLarry Finger 	btcoexist->statistics.cnt_special_packet_notify++;
1574f1d2b4d3SLarry Finger 	if (btcoexist->manual_control)
1575f1d2b4d3SLarry Finger 		return;
1576f1d2b4d3SLarry Finger 
15777937f02dSYan-Hsuan Chuang 	if (pkt_type == PACKET_DHCP) {
1578f1d2b4d3SLarry Finger 		packet_type = BTC_PACKET_DHCP;
15797937f02dSYan-Hsuan Chuang 	} else if (pkt_type == PACKET_EAPOL) {
15807937f02dSYan-Hsuan Chuang 		packet_type = BTC_PACKET_EAPOL;
15817937f02dSYan-Hsuan Chuang 	} else if (pkt_type == PACKET_ARP) {
15827937f02dSYan-Hsuan Chuang 		packet_type = BTC_PACKET_ARP;
15837937f02dSYan-Hsuan Chuang 	} else {
15847937f02dSYan-Hsuan Chuang 		packet_type = BTC_PACKET_UNKNOWN;
15857937f02dSYan-Hsuan Chuang 		return;
15867937f02dSYan-Hsuan Chuang 	}
1587f1d2b4d3SLarry Finger 
15887937f02dSYan-Hsuan Chuang 	halbtc_leave_low_power(btcoexist);
1589f1d2b4d3SLarry Finger 
15907937f02dSYan-Hsuan Chuang 	if (IS_HARDWARE_TYPE_8821(btcoexist->adapter)) {
15917937f02dSYan-Hsuan Chuang 		if (btcoexist->board_info.btdm_ant_num == 2)
15927937f02dSYan-Hsuan Chuang 			ex_btc8821a2ant_special_packet_notify(btcoexist,
15937937f02dSYan-Hsuan Chuang 							      packet_type);
15947937f02dSYan-Hsuan Chuang 		else if (btcoexist->board_info.btdm_ant_num == 1)
15957937f02dSYan-Hsuan Chuang 			ex_btc8821a1ant_special_packet_notify(btcoexist,
15967937f02dSYan-Hsuan Chuang 							      packet_type);
15977937f02dSYan-Hsuan Chuang 	} else if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) {
15987937f02dSYan-Hsuan Chuang 		if (btcoexist->board_info.btdm_ant_num == 2)
1599f1d2b4d3SLarry Finger 			ex_btc8723b2ant_special_packet_notify(btcoexist,
1600f1d2b4d3SLarry Finger 							      packet_type);
16017937f02dSYan-Hsuan Chuang 		else if (btcoexist->board_info.btdm_ant_num == 1)
16027937f02dSYan-Hsuan Chuang 			ex_btc8723b1ant_special_packet_notify(btcoexist,
16037937f02dSYan-Hsuan Chuang 							      packet_type);
16047937f02dSYan-Hsuan Chuang 	} else if (IS_HARDWARE_TYPE_8192E(btcoexist->adapter)) {
16057937f02dSYan-Hsuan Chuang 		if (btcoexist->board_info.btdm_ant_num == 2)
16067937f02dSYan-Hsuan Chuang 			ex_btc8192e2ant_special_packet_notify(btcoexist,
16077937f02dSYan-Hsuan Chuang 							      packet_type);
16087937f02dSYan-Hsuan Chuang 	}
1609f1d2b4d3SLarry Finger 
16107937f02dSYan-Hsuan Chuang 	halbtc_normal_low_power(btcoexist);
1611f1d2b4d3SLarry Finger }
1612f1d2b4d3SLarry Finger 
1613f1d2b4d3SLarry Finger void exhalbtc_bt_info_notify(struct btc_coexist *btcoexist,
1614f1d2b4d3SLarry Finger 			     u8 *tmp_buf, u8 length)
1615f1d2b4d3SLarry Finger {
1616f1d2b4d3SLarry Finger 	if (!halbtc_is_bt_coexist_available(btcoexist))
1617f1d2b4d3SLarry Finger 		return;
1618f1d2b4d3SLarry Finger 	btcoexist->statistics.cnt_bt_info_notify++;
1619f1d2b4d3SLarry Finger 
16207937f02dSYan-Hsuan Chuang 	halbtc_leave_low_power(btcoexist);
16217937f02dSYan-Hsuan Chuang 
16227937f02dSYan-Hsuan Chuang 	if (IS_HARDWARE_TYPE_8821(btcoexist->adapter)) {
16237937f02dSYan-Hsuan Chuang 		if (btcoexist->board_info.btdm_ant_num == 2)
16247937f02dSYan-Hsuan Chuang 			ex_btc8821a2ant_bt_info_notify(btcoexist, tmp_buf,
16257937f02dSYan-Hsuan Chuang 						       length);
16267937f02dSYan-Hsuan Chuang 		else if (btcoexist->board_info.btdm_ant_num == 1)
16277937f02dSYan-Hsuan Chuang 			ex_btc8821a1ant_bt_info_notify(btcoexist, tmp_buf,
16287937f02dSYan-Hsuan Chuang 						       length);
16297937f02dSYan-Hsuan Chuang 	} else if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) {
16307937f02dSYan-Hsuan Chuang 		if (btcoexist->board_info.btdm_ant_num == 2)
16317937f02dSYan-Hsuan Chuang 			ex_btc8723b2ant_bt_info_notify(btcoexist, tmp_buf,
16327937f02dSYan-Hsuan Chuang 						       length);
16337937f02dSYan-Hsuan Chuang 		else if (btcoexist->board_info.btdm_ant_num == 1)
16347937f02dSYan-Hsuan Chuang 			ex_btc8723b1ant_bt_info_notify(btcoexist, tmp_buf,
16357937f02dSYan-Hsuan Chuang 						       length);
16367937f02dSYan-Hsuan Chuang 	} else if (IS_HARDWARE_TYPE_8192E(btcoexist->adapter)) {
16377937f02dSYan-Hsuan Chuang 		if (btcoexist->board_info.btdm_ant_num == 2)
16387937f02dSYan-Hsuan Chuang 			ex_btc8192e2ant_bt_info_notify(btcoexist, tmp_buf,
16397937f02dSYan-Hsuan Chuang 						       length);
16407937f02dSYan-Hsuan Chuang 	}
16417937f02dSYan-Hsuan Chuang 
16427937f02dSYan-Hsuan Chuang 	halbtc_normal_low_power(btcoexist);
16437937f02dSYan-Hsuan Chuang }
16447937f02dSYan-Hsuan Chuang 
16457937f02dSYan-Hsuan Chuang void exhalbtc_rf_status_notify(struct btc_coexist *btcoexist, u8 type)
16467937f02dSYan-Hsuan Chuang {
16477937f02dSYan-Hsuan Chuang 	if (!halbtc_is_bt_coexist_available(btcoexist))
16487937f02dSYan-Hsuan Chuang 		return;
16497937f02dSYan-Hsuan Chuang 
16507937f02dSYan-Hsuan Chuang 	if (IS_HARDWARE_TYPE_8821(btcoexist->adapter)) {
16517937f02dSYan-Hsuan Chuang 	} else if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) {
16527937f02dSYan-Hsuan Chuang 		if (btcoexist->board_info.btdm_ant_num == 1)
16537937f02dSYan-Hsuan Chuang 			ex_btc8723b1ant_rf_status_notify(btcoexist, type);
16547937f02dSYan-Hsuan Chuang 	} else if (IS_HARDWARE_TYPE_8192E(btcoexist->adapter)) {
16557937f02dSYan-Hsuan Chuang 	}
1656f1d2b4d3SLarry Finger }
1657f1d2b4d3SLarry Finger 
1658f1d2b4d3SLarry Finger void exhalbtc_stack_operation_notify(struct btc_coexist *btcoexist, u8 type)
1659f1d2b4d3SLarry Finger {
1660f1d2b4d3SLarry Finger 	u8 stack_op_type;
1661f1d2b4d3SLarry Finger 
1662f1d2b4d3SLarry Finger 	if (!halbtc_is_bt_coexist_available(btcoexist))
1663f1d2b4d3SLarry Finger 		return;
1664f1d2b4d3SLarry Finger 	btcoexist->statistics.cnt_stack_operation_notify++;
1665f1d2b4d3SLarry Finger 	if (btcoexist->manual_control)
1666f1d2b4d3SLarry Finger 		return;
1667f1d2b4d3SLarry Finger 
16687937f02dSYan-Hsuan Chuang 	if ((type == HCI_BT_OP_INQUIRY_START) ||
16697937f02dSYan-Hsuan Chuang 	    (type == HCI_BT_OP_PAGING_START) ||
16707937f02dSYan-Hsuan Chuang 	    (type == HCI_BT_OP_PAIRING_START)) {
16717937f02dSYan-Hsuan Chuang 		stack_op_type = BTC_STACK_OP_INQ_PAGE_PAIR_START;
16727937f02dSYan-Hsuan Chuang 	} else if ((type == HCI_BT_OP_INQUIRY_FINISH) ||
16737937f02dSYan-Hsuan Chuang 		   (type == HCI_BT_OP_PAGING_SUCCESS) ||
16747937f02dSYan-Hsuan Chuang 		   (type == HCI_BT_OP_PAGING_UNSUCCESS) ||
16757937f02dSYan-Hsuan Chuang 		   (type == HCI_BT_OP_PAIRING_FINISH)) {
16767937f02dSYan-Hsuan Chuang 		stack_op_type = BTC_STACK_OP_INQ_PAGE_PAIR_FINISH;
16777937f02dSYan-Hsuan Chuang 	} else {
1678f1d2b4d3SLarry Finger 		stack_op_type = BTC_STACK_OP_NONE;
16797937f02dSYan-Hsuan Chuang 	}
1680f1d2b4d3SLarry Finger }
1681f1d2b4d3SLarry Finger 
1682f1d2b4d3SLarry Finger void exhalbtc_halt_notify(struct btc_coexist *btcoexist)
1683f1d2b4d3SLarry Finger {
1684f1d2b4d3SLarry Finger 	if (!halbtc_is_bt_coexist_available(btcoexist))
1685f1d2b4d3SLarry Finger 		return;
1686f1d2b4d3SLarry Finger 
16877937f02dSYan-Hsuan Chuang 	if (IS_HARDWARE_TYPE_8821(btcoexist->adapter)) {
16887937f02dSYan-Hsuan Chuang 		if (btcoexist->board_info.btdm_ant_num == 2)
16897937f02dSYan-Hsuan Chuang 			ex_btc8821a2ant_halt_notify(btcoexist);
16907937f02dSYan-Hsuan Chuang 		else if (btcoexist->board_info.btdm_ant_num == 1)
16917937f02dSYan-Hsuan Chuang 			ex_btc8821a1ant_halt_notify(btcoexist);
16927937f02dSYan-Hsuan Chuang 	} else if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) {
16937937f02dSYan-Hsuan Chuang 		if (btcoexist->board_info.btdm_ant_num == 2)
1694f1d2b4d3SLarry Finger 			ex_btc8723b2ant_halt_notify(btcoexist);
16957937f02dSYan-Hsuan Chuang 		else if (btcoexist->board_info.btdm_ant_num == 1)
16967937f02dSYan-Hsuan Chuang 			ex_btc8723b1ant_halt_notify(btcoexist);
16977937f02dSYan-Hsuan Chuang 	} else if (IS_HARDWARE_TYPE_8192E(btcoexist->adapter)) {
16987937f02dSYan-Hsuan Chuang 		if (btcoexist->board_info.btdm_ant_num == 2)
16997937f02dSYan-Hsuan Chuang 			ex_btc8192e2ant_halt_notify(btcoexist);
17007937f02dSYan-Hsuan Chuang 	}
17017937f02dSYan-Hsuan Chuang 
17027937f02dSYan-Hsuan Chuang 	btcoexist->binded = false;
1703f1d2b4d3SLarry Finger }
1704f1d2b4d3SLarry Finger 
1705f1d2b4d3SLarry Finger void exhalbtc_pnp_notify(struct btc_coexist *btcoexist, u8 pnp_state)
1706f1d2b4d3SLarry Finger {
1707f1d2b4d3SLarry Finger 	if (!halbtc_is_bt_coexist_available(btcoexist))
1708f1d2b4d3SLarry Finger 		return;
170986f9ab2eSYan-Hsuan Chuang 
171086f9ab2eSYan-Hsuan Chuang 	/* currently only 1ant we have to do the notification,
171186f9ab2eSYan-Hsuan Chuang 	 * once pnp is notified to sleep state, we have to leave LPS that
171286f9ab2eSYan-Hsuan Chuang 	 * we can sleep normally.
171386f9ab2eSYan-Hsuan Chuang 	 */
171486f9ab2eSYan-Hsuan Chuang 
171586f9ab2eSYan-Hsuan Chuang 	if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) {
171686f9ab2eSYan-Hsuan Chuang 		if (btcoexist->board_info.btdm_ant_num == 1)
171786f9ab2eSYan-Hsuan Chuang 			ex_btc8723b1ant_pnp_notify(btcoexist, pnp_state);
171886f9ab2eSYan-Hsuan Chuang 		else if (btcoexist->board_info.btdm_ant_num == 2)
171986f9ab2eSYan-Hsuan Chuang 			ex_btc8723b2ant_pnp_notify(btcoexist, pnp_state);
172086f9ab2eSYan-Hsuan Chuang 	} else if (IS_HARDWARE_TYPE_8821(btcoexist->adapter)) {
172186f9ab2eSYan-Hsuan Chuang 		if (btcoexist->board_info.btdm_ant_num == 1)
172286f9ab2eSYan-Hsuan Chuang 			ex_btc8821a1ant_pnp_notify(btcoexist, pnp_state);
172386f9ab2eSYan-Hsuan Chuang 		else if (btcoexist->board_info.btdm_ant_num == 2)
172486f9ab2eSYan-Hsuan Chuang 			ex_btc8821a2ant_pnp_notify(btcoexist, pnp_state);
172586f9ab2eSYan-Hsuan Chuang 	} else if (IS_HARDWARE_TYPE_8192E(btcoexist->adapter)) {
172686f9ab2eSYan-Hsuan Chuang 	}
1727f1d2b4d3SLarry Finger }
1728f1d2b4d3SLarry Finger 
17297937f02dSYan-Hsuan Chuang void exhalbtc_coex_dm_switch(struct btc_coexist *btcoexist)
1730f1d2b4d3SLarry Finger {
1731f1d2b4d3SLarry Finger 	struct rtl_priv *rtlpriv = btcoexist->adapter;
17327937f02dSYan-Hsuan Chuang 
17337937f02dSYan-Hsuan Chuang 	if (!halbtc_is_bt_coexist_available(btcoexist))
17347937f02dSYan-Hsuan Chuang 		return;
17357937f02dSYan-Hsuan Chuang 	btcoexist->statistics.cnt_coex_dm_switch++;
17367937f02dSYan-Hsuan Chuang 
17377937f02dSYan-Hsuan Chuang 	halbtc_leave_low_power(btcoexist);
17387937f02dSYan-Hsuan Chuang 
17397937f02dSYan-Hsuan Chuang 	if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) {
17407937f02dSYan-Hsuan Chuang 		if (btcoexist->board_info.btdm_ant_num == 1) {
17417937f02dSYan-Hsuan Chuang 			btcoexist->stop_coex_dm = true;
17427937f02dSYan-Hsuan Chuang 			ex_btc8723b1ant_coex_dm_reset(btcoexist);
17437937f02dSYan-Hsuan Chuang 			exhalbtc_set_ant_num(rtlpriv,
17447937f02dSYan-Hsuan Chuang 					     BT_COEX_ANT_TYPE_DETECTED, 2);
17457937f02dSYan-Hsuan Chuang 			ex_btc8723b2ant_init_hwconfig(btcoexist);
17467937f02dSYan-Hsuan Chuang 			ex_btc8723b2ant_init_coex_dm(btcoexist);
17477937f02dSYan-Hsuan Chuang 			btcoexist->stop_coex_dm = false;
17487937f02dSYan-Hsuan Chuang 		}
17497937f02dSYan-Hsuan Chuang 	}
17507937f02dSYan-Hsuan Chuang 
17517937f02dSYan-Hsuan Chuang 	halbtc_normal_low_power(btcoexist);
17527937f02dSYan-Hsuan Chuang }
17537937f02dSYan-Hsuan Chuang 
17547937f02dSYan-Hsuan Chuang void exhalbtc_periodical(struct btc_coexist *btcoexist)
17557937f02dSYan-Hsuan Chuang {
1756f1d2b4d3SLarry Finger 	if (!halbtc_is_bt_coexist_available(btcoexist))
1757f1d2b4d3SLarry Finger 		return;
1758f1d2b4d3SLarry Finger 	btcoexist->statistics.cnt_periodical++;
1759f1d2b4d3SLarry Finger 
17607937f02dSYan-Hsuan Chuang 	halbtc_leave_low_power(btcoexist);
1761f1d2b4d3SLarry Finger 
17627937f02dSYan-Hsuan Chuang 	if (IS_HARDWARE_TYPE_8821(btcoexist->adapter)) {
17637937f02dSYan-Hsuan Chuang 		if (btcoexist->board_info.btdm_ant_num == 2)
17647937f02dSYan-Hsuan Chuang 			ex_btc8821a2ant_periodical(btcoexist);
17657937f02dSYan-Hsuan Chuang 		else if (btcoexist->board_info.btdm_ant_num == 1)
17667937f02dSYan-Hsuan Chuang 			if (!halbtc_under_ips(btcoexist))
17677937f02dSYan-Hsuan Chuang 				ex_btc8821a1ant_periodical(btcoexist);
17687937f02dSYan-Hsuan Chuang 	} else if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) {
17697937f02dSYan-Hsuan Chuang 		if (btcoexist->board_info.btdm_ant_num == 2)
1770f1d2b4d3SLarry Finger 			ex_btc8723b2ant_periodical(btcoexist);
17717937f02dSYan-Hsuan Chuang 		else if (btcoexist->board_info.btdm_ant_num == 1)
17727937f02dSYan-Hsuan Chuang 			ex_btc8723b1ant_periodical(btcoexist);
17737937f02dSYan-Hsuan Chuang 	} else if (IS_HARDWARE_TYPE_8192E(btcoexist->adapter)) {
17747937f02dSYan-Hsuan Chuang 		if (btcoexist->board_info.btdm_ant_num == 2)
17757937f02dSYan-Hsuan Chuang 			ex_btc8192e2ant_periodical(btcoexist);
17767937f02dSYan-Hsuan Chuang 	}
1777f1d2b4d3SLarry Finger 
17787937f02dSYan-Hsuan Chuang 	halbtc_normal_low_power(btcoexist);
1779f1d2b4d3SLarry Finger }
1780f1d2b4d3SLarry Finger 
1781f1d2b4d3SLarry Finger void exhalbtc_dbg_control(struct btc_coexist *btcoexist,
1782f1d2b4d3SLarry Finger 			  u8 code, u8 len, u8 *data)
1783f1d2b4d3SLarry Finger {
1784f1d2b4d3SLarry Finger 	if (!halbtc_is_bt_coexist_available(btcoexist))
1785f1d2b4d3SLarry Finger 		return;
1786f1d2b4d3SLarry Finger 	btcoexist->statistics.cnt_dbg_ctrl++;
17877937f02dSYan-Hsuan Chuang 
17887937f02dSYan-Hsuan Chuang 	halbtc_leave_low_power(btcoexist);
17897937f02dSYan-Hsuan Chuang 
17907937f02dSYan-Hsuan Chuang 	halbtc_normal_low_power(btcoexist);
17917937f02dSYan-Hsuan Chuang }
17927937f02dSYan-Hsuan Chuang 
17937937f02dSYan-Hsuan Chuang void exhalbtc_antenna_detection(struct btc_coexist *btcoexist, u32 cent_freq,
17947937f02dSYan-Hsuan Chuang 				u32 offset, u32 span, u32 seconds)
17957937f02dSYan-Hsuan Chuang {
17967937f02dSYan-Hsuan Chuang 	if (!halbtc_is_bt_coexist_available(btcoexist))
17977937f02dSYan-Hsuan Chuang 		return;
1798f1d2b4d3SLarry Finger }
1799f1d2b4d3SLarry Finger 
1800f1d2b4d3SLarry Finger void exhalbtc_stack_update_profile_info(void)
1801f1d2b4d3SLarry Finger {
1802f1d2b4d3SLarry Finger }
1803f1d2b4d3SLarry Finger 
180440d9dd4fSPing-Ke Shih void exhalbtc_update_min_bt_rssi(struct btc_coexist *btcoexist, s8 bt_rssi)
1805f1d2b4d3SLarry Finger {
1806f1d2b4d3SLarry Finger 	if (!halbtc_is_bt_coexist_available(btcoexist))
1807f1d2b4d3SLarry Finger 		return;
1808f1d2b4d3SLarry Finger 
1809f1d2b4d3SLarry Finger 	btcoexist->stack_info.min_bt_rssi = bt_rssi;
1810f1d2b4d3SLarry Finger }
1811f1d2b4d3SLarry Finger 
181240d9dd4fSPing-Ke Shih void exhalbtc_set_hci_version(struct btc_coexist *btcoexist, u16 hci_version)
1813f1d2b4d3SLarry Finger {
1814f1d2b4d3SLarry Finger 	if (!halbtc_is_bt_coexist_available(btcoexist))
1815f1d2b4d3SLarry Finger 		return;
1816f1d2b4d3SLarry Finger 
1817f1d2b4d3SLarry Finger 	btcoexist->stack_info.hci_version = hci_version;
1818f1d2b4d3SLarry Finger }
1819f1d2b4d3SLarry Finger 
182040d9dd4fSPing-Ke Shih void exhalbtc_set_bt_patch_version(struct btc_coexist *btcoexist,
182140d9dd4fSPing-Ke Shih 				   u16 bt_hci_version, u16 bt_patch_version)
1822f1d2b4d3SLarry Finger {
1823f1d2b4d3SLarry Finger 	if (!halbtc_is_bt_coexist_available(btcoexist))
1824f1d2b4d3SLarry Finger 		return;
1825f1d2b4d3SLarry Finger 
1826f1d2b4d3SLarry Finger 	btcoexist->bt_info.bt_real_fw_ver = bt_patch_version;
1827f1d2b4d3SLarry Finger 	btcoexist->bt_info.bt_hci_ver = bt_hci_version;
1828f1d2b4d3SLarry Finger }
1829f1d2b4d3SLarry Finger 
183040d9dd4fSPing-Ke Shih void exhalbtc_set_chip_type(struct btc_coexist *btcoexist, u8 chip_type)
1831f1d2b4d3SLarry Finger {
1832f1d2b4d3SLarry Finger 	switch (chip_type) {
1833f1d2b4d3SLarry Finger 	default:
1834f1d2b4d3SLarry Finger 	case BT_2WIRE:
1835f1d2b4d3SLarry Finger 	case BT_ISSC_3WIRE:
1836f1d2b4d3SLarry Finger 	case BT_ACCEL:
1837f1d2b4d3SLarry Finger 	case BT_RTL8756:
183840d9dd4fSPing-Ke Shih 		btcoexist->board_info.bt_chip_type = BTC_CHIP_UNDEF;
1839f1d2b4d3SLarry Finger 		break;
1840f1d2b4d3SLarry Finger 	case BT_CSR_BC4:
184140d9dd4fSPing-Ke Shih 		btcoexist->board_info.bt_chip_type = BTC_CHIP_CSR_BC4;
1842f1d2b4d3SLarry Finger 		break;
1843f1d2b4d3SLarry Finger 	case BT_CSR_BC8:
184440d9dd4fSPing-Ke Shih 		btcoexist->board_info.bt_chip_type = BTC_CHIP_CSR_BC8;
1845f1d2b4d3SLarry Finger 		break;
1846f1d2b4d3SLarry Finger 	case BT_RTL8723A:
184740d9dd4fSPing-Ke Shih 		btcoexist->board_info.bt_chip_type = BTC_CHIP_RTL8723A;
1848f1d2b4d3SLarry Finger 		break;
1849f1d2b4d3SLarry Finger 	case BT_RTL8821A:
185040d9dd4fSPing-Ke Shih 		btcoexist->board_info.bt_chip_type = BTC_CHIP_RTL8821;
1851f1d2b4d3SLarry Finger 		break;
1852f1d2b4d3SLarry Finger 	case BT_RTL8723B:
185340d9dd4fSPing-Ke Shih 		btcoexist->board_info.bt_chip_type = BTC_CHIP_RTL8723B;
1854f1d2b4d3SLarry Finger 		break;
1855f1d2b4d3SLarry Finger 	}
1856f1d2b4d3SLarry Finger }
1857f1d2b4d3SLarry Finger 
1858baa17022SLarry Finger void exhalbtc_set_ant_num(struct rtl_priv *rtlpriv, u8 type, u8 ant_num)
1859f1d2b4d3SLarry Finger {
186040d9dd4fSPing-Ke Shih 	struct btc_coexist *btcoexist = rtl_btc_coexist(rtlpriv);
186140d9dd4fSPing-Ke Shih 
186240d9dd4fSPing-Ke Shih 	if (!btcoexist)
186340d9dd4fSPing-Ke Shih 		return;
186440d9dd4fSPing-Ke Shih 
1865f1d2b4d3SLarry Finger 	if (BT_COEX_ANT_TYPE_PG == type) {
186640d9dd4fSPing-Ke Shih 		btcoexist->board_info.pg_ant_num = ant_num;
186740d9dd4fSPing-Ke Shih 		btcoexist->board_info.btdm_ant_num = ant_num;
1868f1d2b4d3SLarry Finger 	} else if (BT_COEX_ANT_TYPE_ANTDIV == type) {
186940d9dd4fSPing-Ke Shih 		btcoexist->board_info.btdm_ant_num = ant_num;
1870baa17022SLarry Finger 	} else if (type == BT_COEX_ANT_TYPE_DETECTED) {
187140d9dd4fSPing-Ke Shih 		btcoexist->board_info.btdm_ant_num = ant_num;
1872baa17022SLarry Finger 		if (rtlpriv->cfg->mod_params->ant_sel == 1)
187340d9dd4fSPing-Ke Shih 			btcoexist->board_info.btdm_ant_pos =
1874baa17022SLarry Finger 				BTC_ANTENNA_AT_AUX_PORT;
1875baa17022SLarry Finger 		else
187640d9dd4fSPing-Ke Shih 			btcoexist->board_info.btdm_ant_pos =
1877baa17022SLarry Finger 				BTC_ANTENNA_AT_MAIN_PORT;
1878f1d2b4d3SLarry Finger 	}
1879f1d2b4d3SLarry Finger }
1880f1d2b4d3SLarry Finger 
18810199103eSYan-Hsuan Chuang /* Currently used by 8723b only, S0 or S1 */
188240d9dd4fSPing-Ke Shih void exhalbtc_set_single_ant_path(struct btc_coexist *btcoexist,
188340d9dd4fSPing-Ke Shih 				  u8 single_ant_path)
18840199103eSYan-Hsuan Chuang {
188540d9dd4fSPing-Ke Shih 	btcoexist->board_info.single_ant_path = single_ant_path;
18860199103eSYan-Hsuan Chuang }
18870199103eSYan-Hsuan Chuang 
1888610247f4SPing-Ke Shih void exhalbtc_display_bt_coex_info(struct btc_coexist *btcoexist,
1889610247f4SPing-Ke Shih 				   struct seq_file *m)
1890f1d2b4d3SLarry Finger {
1891f1d2b4d3SLarry Finger 	if (!halbtc_is_bt_coexist_available(btcoexist))
1892f1d2b4d3SLarry Finger 		return;
1893f1d2b4d3SLarry Finger 
1894c42ea613SYan-Hsuan Chuang 	halbtc_leave_low_power(btcoexist);
1895c42ea613SYan-Hsuan Chuang 
1896c42ea613SYan-Hsuan Chuang 	if (IS_HARDWARE_TYPE_8821(btcoexist->adapter)) {
1897c42ea613SYan-Hsuan Chuang 		if (btcoexist->board_info.btdm_ant_num == 2)
189808431b62SPing-Ke Shih 			ex_btc8821a2ant_display_coex_info(btcoexist, m);
1899c42ea613SYan-Hsuan Chuang 		else if (btcoexist->board_info.btdm_ant_num == 1)
190008431b62SPing-Ke Shih 			ex_btc8821a1ant_display_coex_info(btcoexist, m);
1901c42ea613SYan-Hsuan Chuang 	} else if (IS_HARDWARE_TYPE_8723B(btcoexist->adapter)) {
1902c42ea613SYan-Hsuan Chuang 		if (btcoexist->board_info.btdm_ant_num == 2)
190308431b62SPing-Ke Shih 			ex_btc8723b2ant_display_coex_info(btcoexist, m);
1904c42ea613SYan-Hsuan Chuang 		else if (btcoexist->board_info.btdm_ant_num == 1)
190508431b62SPing-Ke Shih 			ex_btc8723b1ant_display_coex_info(btcoexist, m);
1906c42ea613SYan-Hsuan Chuang 	} else if (IS_HARDWARE_TYPE_8192E(btcoexist->adapter)) {
1907c42ea613SYan-Hsuan Chuang 		if (btcoexist->board_info.btdm_ant_num == 2)
190808431b62SPing-Ke Shih 			ex_btc8192e2ant_display_coex_info(btcoexist, m);
1909c42ea613SYan-Hsuan Chuang 	}
1910c42ea613SYan-Hsuan Chuang 
1911c42ea613SYan-Hsuan Chuang 	halbtc_normal_low_power(btcoexist);
1912f1d2b4d3SLarry Finger }
191317bf8510SPing-Ke Shih 
191417bf8510SPing-Ke Shih void exhalbtc_switch_band_notify(struct btc_coexist *btcoexist, u8 type)
191517bf8510SPing-Ke Shih {
191617bf8510SPing-Ke Shih 	if (!halbtc_is_bt_coexist_available(btcoexist))
191717bf8510SPing-Ke Shih 		return;
191817bf8510SPing-Ke Shih 
191917bf8510SPing-Ke Shih 	if (btcoexist->manual_control)
192017bf8510SPing-Ke Shih 		return;
192117bf8510SPing-Ke Shih 
192217bf8510SPing-Ke Shih 	halbtc_leave_low_power(btcoexist);
192317bf8510SPing-Ke Shih 
192417bf8510SPing-Ke Shih 	halbtc_normal_low_power(btcoexist);
192517bf8510SPing-Ke Shih }
1926