xref: /OK3568_Linux_fs/kernel/drivers/net/wireless/rockchip_wlan/rtl8822be/core/rtw_btcoex.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1 /******************************************************************************
2  *
3  * Copyright(c) 2013 Realtek Corporation. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  * published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17  *
18  *
19  ******************************************************************************/
20 #ifdef CONFIG_BT_COEXIST
21 
22 #include <drv_types.h>
23 #include <hal_btcoex.h>
24 #include <hal_data.h>
25 
26 
rtw_btcoex_Initialize(PADAPTER padapter)27 void rtw_btcoex_Initialize(PADAPTER padapter)
28 {
29 	hal_btcoex_Initialize(padapter);
30 }
31 
rtw_btcoex_PowerOnSetting(PADAPTER padapter)32 void rtw_btcoex_PowerOnSetting(PADAPTER padapter)
33 {
34 	hal_btcoex_PowerOnSetting(padapter);
35 }
36 
rtw_btcoex_PreLoadFirmware(PADAPTER padapter)37 void rtw_btcoex_PreLoadFirmware(PADAPTER padapter)
38 {
39 	hal_btcoex_PreLoadFirmware(padapter);
40 }
41 
rtw_btcoex_HAL_Initialize(PADAPTER padapter,u8 bWifiOnly)42 void rtw_btcoex_HAL_Initialize(PADAPTER padapter, u8 bWifiOnly)
43 {
44 	hal_btcoex_InitHwConfig(padapter, bWifiOnly);
45 }
46 
rtw_btcoex_IpsNotify(PADAPTER padapter,u8 type)47 void rtw_btcoex_IpsNotify(PADAPTER padapter, u8 type)
48 {
49 	PHAL_DATA_TYPE	pHalData;
50 
51 	pHalData = GET_HAL_DATA(padapter);
52 	if (_FALSE == pHalData->EEPROMBluetoothCoexist)
53 		return;
54 
55 	hal_btcoex_IpsNotify(padapter, type);
56 }
57 
rtw_btcoex_LpsNotify(PADAPTER padapter,u8 type)58 void rtw_btcoex_LpsNotify(PADAPTER padapter, u8 type)
59 {
60 	PHAL_DATA_TYPE	pHalData;
61 
62 	pHalData = GET_HAL_DATA(padapter);
63 	if (_FALSE == pHalData->EEPROMBluetoothCoexist)
64 		return;
65 
66 	hal_btcoex_LpsNotify(padapter, type);
67 }
68 
rtw_btcoex_ScanNotify(PADAPTER padapter,u8 type)69 void rtw_btcoex_ScanNotify(PADAPTER padapter, u8 type)
70 {
71 	PHAL_DATA_TYPE	pHalData;
72 #ifdef CONFIG_BT_COEXIST_SOCKET_TRX
73 	struct bt_coex_info *pcoex_info = &padapter->coex_info;
74 	PBT_MGNT	pBtMgnt = &pcoex_info->BtMgnt;
75 #endif /* CONFIG_BT_COEXIST_SOCKET_TRX */
76 
77 	pHalData = GET_HAL_DATA(padapter);
78 	if (_FALSE == pHalData->EEPROMBluetoothCoexist)
79 		return;
80 
81 #ifdef CONFIG_CONCURRENT_MODE
82 	if (_FALSE == type) {
83 		if (rtw_mi_buddy_check_fwstate(padapter, WIFI_SITE_MONITOR))
84 			return;
85 	}
86 #endif
87 
88 #ifdef CONFIG_BT_COEXIST_SOCKET_TRX
89 	if (pBtMgnt->ExtConfig.bEnableWifiScanNotify)
90 		rtw_btcoex_SendScanNotify(padapter, type);
91 #endif /* CONFIG_BT_COEXIST_SOCKET_TRX	 */
92 
93 	hal_btcoex_ScanNotify(padapter, type);
94 }
95 
rtw_btcoex_ConnectNotify(PADAPTER padapter,u8 action)96 void rtw_btcoex_ConnectNotify(PADAPTER padapter, u8 action)
97 {
98 	PHAL_DATA_TYPE	pHalData;
99 
100 	pHalData = GET_HAL_DATA(padapter);
101 	if (_FALSE == pHalData->EEPROMBluetoothCoexist)
102 		return;
103 
104 #ifdef DBG_CONFIG_ERROR_RESET
105 	if (_TRUE == rtw_hal_sreset_inprogress(padapter)) {
106 		RTW_INFO(FUNC_ADPT_FMT ": [BTCoex] under reset, skip notify!\n",
107 			 FUNC_ADPT_ARG(padapter));
108 		return;
109 	}
110 #endif /* DBG_CONFIG_ERROR_RESET */
111 
112 #ifdef CONFIG_CONCURRENT_MODE
113 	if (_FALSE == action) {
114 		if (rtw_mi_buddy_check_fwstate(padapter, WIFI_UNDER_LINKING))
115 			return;
116 	}
117 #endif
118 
119 	hal_btcoex_ConnectNotify(padapter, action);
120 }
121 
rtw_btcoex_MediaStatusNotify(PADAPTER padapter,u8 mediaStatus)122 void rtw_btcoex_MediaStatusNotify(PADAPTER padapter, u8 mediaStatus)
123 {
124 	PHAL_DATA_TYPE	pHalData;
125 
126 	pHalData = GET_HAL_DATA(padapter);
127 	if (_FALSE == pHalData->EEPROMBluetoothCoexist)
128 		return;
129 
130 #ifdef DBG_CONFIG_ERROR_RESET
131 	if (_TRUE == rtw_hal_sreset_inprogress(padapter)) {
132 		RTW_INFO(FUNC_ADPT_FMT ": [BTCoex] under reset, skip notify!\n",
133 			 FUNC_ADPT_ARG(padapter));
134 		return;
135 	}
136 #endif /* DBG_CONFIG_ERROR_RESET */
137 
138 #ifdef CONFIG_CONCURRENT_MODE
139 	if (RT_MEDIA_DISCONNECT == mediaStatus) {
140 		if (rtw_mi_buddy_check_fwstate(padapter, WIFI_ASOC_STATE))
141 			return;
142 	}
143 #endif /* CONFIG_CONCURRENT_MODE */
144 
145 	if ((RT_MEDIA_CONNECT == mediaStatus)
146 	    && (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE))
147 		rtw_hal_set_hwreg(padapter, HW_VAR_DL_RSVD_PAGE, NULL);
148 
149 	hal_btcoex_MediaStatusNotify(padapter, mediaStatus);
150 }
151 
rtw_btcoex_SpecialPacketNotify(PADAPTER padapter,u8 pktType)152 void rtw_btcoex_SpecialPacketNotify(PADAPTER padapter, u8 pktType)
153 {
154 	PHAL_DATA_TYPE	pHalData;
155 
156 	pHalData = GET_HAL_DATA(padapter);
157 	if (_FALSE == pHalData->EEPROMBluetoothCoexist)
158 		return;
159 
160 	hal_btcoex_SpecialPacketNotify(padapter, pktType);
161 }
162 
rtw_btcoex_IQKNotify(PADAPTER padapter,u8 state)163 void rtw_btcoex_IQKNotify(PADAPTER padapter, u8 state)
164 {
165 	PHAL_DATA_TYPE	pHalData;
166 
167 	pHalData = GET_HAL_DATA(padapter);
168 	if (_FALSE == pHalData->EEPROMBluetoothCoexist)
169 		return;
170 
171 	hal_btcoex_IQKNotify(padapter, state);
172 }
173 
rtw_btcoex_BtInfoNotify(PADAPTER padapter,u8 length,u8 * tmpBuf)174 void rtw_btcoex_BtInfoNotify(PADAPTER padapter, u8 length, u8 *tmpBuf)
175 {
176 	PHAL_DATA_TYPE	pHalData;
177 
178 	pHalData = GET_HAL_DATA(padapter);
179 	if (_FALSE == pHalData->EEPROMBluetoothCoexist)
180 		return;
181 
182 	hal_btcoex_BtInfoNotify(padapter, length, tmpBuf);
183 }
184 
rtw_btcoex_BtMpRptNotify(PADAPTER padapter,u8 length,u8 * tmpBuf)185 void rtw_btcoex_BtMpRptNotify(PADAPTER padapter, u8 length, u8 *tmpBuf)
186 {
187 	PHAL_DATA_TYPE	pHalData;
188 
189 	pHalData = GET_HAL_DATA(padapter);
190 	if (_FALSE == pHalData->EEPROMBluetoothCoexist)
191 		return;
192 
193 	if (padapter->registrypriv.mp_mode == 1)
194 		return;
195 
196 	hal_btcoex_BtMpRptNotify(padapter, length, tmpBuf);
197 }
198 
rtw_btcoex_SuspendNotify(PADAPTER padapter,u8 state)199 void rtw_btcoex_SuspendNotify(PADAPTER padapter, u8 state)
200 {
201 	PHAL_DATA_TYPE	pHalData;
202 
203 	pHalData = GET_HAL_DATA(padapter);
204 	if (_FALSE == pHalData->EEPROMBluetoothCoexist)
205 		return;
206 
207 	hal_btcoex_SuspendNotify(padapter, state);
208 }
209 
rtw_btcoex_HaltNotify(PADAPTER padapter)210 void rtw_btcoex_HaltNotify(PADAPTER padapter)
211 {
212 	PHAL_DATA_TYPE	pHalData;
213 	u8 do_halt = 1;
214 
215 	pHalData = GET_HAL_DATA(padapter);
216 	if (_FALSE == pHalData->EEPROMBluetoothCoexist)
217 		do_halt = 0;
218 
219 	if (_FALSE == padapter->bup) {
220 		RTW_INFO(FUNC_ADPT_FMT ": bup=%d Skip!\n",
221 			 FUNC_ADPT_ARG(padapter), padapter->bup);
222 		do_halt = 0;
223 	}
224 
225 	if (rtw_is_surprise_removed(padapter)) {
226 		RTW_INFO(FUNC_ADPT_FMT ": bSurpriseRemoved=%s Skip!\n",
227 			FUNC_ADPT_ARG(padapter), rtw_is_surprise_removed(padapter) ? "True" : "False");
228 		do_halt = 0;
229 	}
230 
231 	hal_btcoex_HaltNotify(padapter, do_halt);
232 }
233 
rtw_btcoex_ScoreBoardStatusNotify(PADAPTER padapter,u8 length,u8 * tmpBuf)234 void rtw_btcoex_ScoreBoardStatusNotify(PADAPTER padapter, u8 length, u8 *tmpBuf)
235 {
236 	PHAL_DATA_TYPE	pHalData;
237 
238 	pHalData = GET_HAL_DATA(padapter);
239 	if (_FALSE == pHalData->EEPROMBluetoothCoexist)
240 		return;
241 
242 	hal_btcoex_ScoreBoardStatusNotify(padapter, length, tmpBuf);
243 }
244 
rtw_btcoex_switchband_notify(u8 under_scan,u8 band_type)245 void rtw_btcoex_switchband_notify(u8 under_scan, u8 band_type)
246 {
247 	hal_btcoex_switchband_notify(under_scan, band_type);
248 }
249 
rtw_btcoex_SwitchBtTRxMask(PADAPTER padapter)250 void rtw_btcoex_SwitchBtTRxMask(PADAPTER padapter)
251 {
252 	hal_btcoex_SwitchBtTRxMask(padapter);
253 }
254 
rtw_btcoex_Switch(PADAPTER padapter,u8 enable)255 void rtw_btcoex_Switch(PADAPTER padapter, u8 enable)
256 {
257 	hal_btcoex_SetBTCoexist(padapter, enable);
258 }
259 
rtw_btcoex_IsBtDisabled(PADAPTER padapter)260 u8 rtw_btcoex_IsBtDisabled(PADAPTER padapter)
261 {
262 	return hal_btcoex_IsBtDisabled(padapter);
263 }
264 
rtw_btcoex_Handler(PADAPTER padapter)265 void rtw_btcoex_Handler(PADAPTER padapter)
266 {
267 	PHAL_DATA_TYPE	pHalData;
268 
269 	pHalData = GET_HAL_DATA(padapter);
270 
271 	if (_FALSE == pHalData->EEPROMBluetoothCoexist)
272 		return;
273 
274 #if defined(CONFIG_CONCURRENT_MODE)
275 	if (padapter->adapter_type != PRIMARY_ADAPTER)
276 		return;
277 #endif
278 
279 
280 
281 	hal_btcoex_Hanlder(padapter);
282 }
283 
rtw_btcoex_IsBTCoexRejectAMPDU(PADAPTER padapter)284 s32 rtw_btcoex_IsBTCoexRejectAMPDU(PADAPTER padapter)
285 {
286 	s32 coexctrl;
287 
288 	coexctrl = hal_btcoex_IsBTCoexRejectAMPDU(padapter);
289 
290 	return coexctrl;
291 }
292 
rtw_btcoex_IsBTCoexCtrlAMPDUSize(PADAPTER padapter)293 s32 rtw_btcoex_IsBTCoexCtrlAMPDUSize(PADAPTER padapter)
294 {
295 	s32 coexctrl;
296 
297 	coexctrl = hal_btcoex_IsBTCoexCtrlAMPDUSize(padapter);
298 
299 	return coexctrl;
300 }
301 
rtw_btcoex_GetAMPDUSize(PADAPTER padapter)302 u32 rtw_btcoex_GetAMPDUSize(PADAPTER padapter)
303 {
304 	u32 size;
305 
306 	size = hal_btcoex_GetAMPDUSize(padapter);
307 
308 	return size;
309 }
310 
rtw_btcoex_SetManualControl(PADAPTER padapter,u8 manual)311 void rtw_btcoex_SetManualControl(PADAPTER padapter, u8 manual)
312 {
313 	if (_TRUE == manual)
314 		hal_btcoex_SetManualControl(padapter, _TRUE);
315 	else
316 		hal_btcoex_SetManualControl(padapter, _FALSE);
317 }
318 
rtw_btcoex_1Ant(PADAPTER padapter)319 u8 rtw_btcoex_1Ant(PADAPTER padapter)
320 {
321 	return hal_btcoex_1Ant(padapter);
322 }
323 
rtw_btcoex_IsBtControlLps(PADAPTER padapter)324 u8 rtw_btcoex_IsBtControlLps(PADAPTER padapter)
325 {
326 	return hal_btcoex_IsBtControlLps(padapter);
327 }
328 
rtw_btcoex_IsLpsOn(PADAPTER padapter)329 u8 rtw_btcoex_IsLpsOn(PADAPTER padapter)
330 {
331 	return hal_btcoex_IsLpsOn(padapter);
332 }
333 
rtw_btcoex_RpwmVal(PADAPTER padapter)334 u8 rtw_btcoex_RpwmVal(PADAPTER padapter)
335 {
336 	return hal_btcoex_RpwmVal(padapter);
337 }
338 
rtw_btcoex_LpsVal(PADAPTER padapter)339 u8 rtw_btcoex_LpsVal(PADAPTER padapter)
340 {
341 	return hal_btcoex_LpsVal(padapter);
342 }
343 
rtw_btcoex_GetRaMask(PADAPTER padapter)344 u32 rtw_btcoex_GetRaMask(PADAPTER padapter)
345 {
346 	return hal_btcoex_GetRaMask(padapter);
347 }
348 
rtw_btcoex_RecordPwrMode(PADAPTER padapter,u8 * pCmdBuf,u8 cmdLen)349 void rtw_btcoex_RecordPwrMode(PADAPTER padapter, u8 *pCmdBuf, u8 cmdLen)
350 {
351 	hal_btcoex_RecordPwrMode(padapter, pCmdBuf, cmdLen);
352 }
353 
rtw_btcoex_DisplayBtCoexInfo(PADAPTER padapter,u8 * pbuf,u32 bufsize)354 void rtw_btcoex_DisplayBtCoexInfo(PADAPTER padapter, u8 *pbuf, u32 bufsize)
355 {
356 	hal_btcoex_DisplayBtCoexInfo(padapter, pbuf, bufsize);
357 }
358 
rtw_btcoex_SetDBG(PADAPTER padapter,u32 * pDbgModule)359 void rtw_btcoex_SetDBG(PADAPTER padapter, u32 *pDbgModule)
360 {
361 	hal_btcoex_SetDBG(padapter, pDbgModule);
362 }
363 
rtw_btcoex_GetDBG(PADAPTER padapter,u8 * pStrBuf,u32 bufSize)364 u32 rtw_btcoex_GetDBG(PADAPTER padapter, u8 *pStrBuf, u32 bufSize)
365 {
366 	return hal_btcoex_GetDBG(padapter, pStrBuf, bufSize);
367 }
368 
rtw_btcoex_IncreaseScanDeviceNum(PADAPTER padapter)369 u8 rtw_btcoex_IncreaseScanDeviceNum(PADAPTER padapter)
370 {
371 	return hal_btcoex_IncreaseScanDeviceNum(padapter);
372 }
373 
rtw_btcoex_IsBtLinkExist(PADAPTER padapter)374 u8 rtw_btcoex_IsBtLinkExist(PADAPTER padapter)
375 {
376 	return hal_btcoex_IsBtLinkExist(padapter);
377 }
378 
rtw_btcoex_SetBtPatchVersion(PADAPTER padapter,u16 btHciVer,u16 btPatchVer)379 void rtw_btcoex_SetBtPatchVersion(PADAPTER padapter, u16 btHciVer, u16 btPatchVer)
380 {
381 	hal_btcoex_SetBtPatchVersion(padapter, btHciVer, btPatchVer);
382 }
383 
rtw_btcoex_SetHciVersion(PADAPTER padapter,u16 hciVersion)384 void rtw_btcoex_SetHciVersion(PADAPTER  padapter, u16 hciVersion)
385 {
386 	hal_btcoex_SetHciVersion(padapter, hciVersion);
387 }
388 
rtw_btcoex_StackUpdateProfileInfo(void)389 void rtw_btcoex_StackUpdateProfileInfo(void)
390 {
391 	hal_btcoex_StackUpdateProfileInfo();
392 }
393 
rtw_btcoex_BTOffOnNotify(PADAPTER padapter,u8 bBTON)394 void rtw_btcoex_BTOffOnNotify(PADAPTER padapter, u8 bBTON)
395 {
396 	hal_btcoex_BTOffOnNotify(padapter, bBTON);
397 }
398 
399 #ifdef CONFIG_RF4CE_COEXIST
rtw_btcoex_rf4ce_voice_Notify(PADAPTER padapter,u8 type)400 void rtw_btcoex_rf4ce_voice_Notify(PADAPTER padapter, u8 type)
401 {
402 
403 	/* Notify only when state was changed */
404 
405 	#if 0 /* TODO */
406 	PHAL_DATA_TYPE	pHalData;
407 
408 	pHalData = GET_HAL_DATA(padapter);
409 	if (_FALSE == pHalData->EEPROMBluetoothCoexist)
410 		return;
411 
412 	hal_btcoex_rf4ce_voice_Notify(padapter, type);
413 	#endif
414 }
415 
rtw_btcoex_set_rf4ce_link_state(PADAPTER padapter,u8 state)416 void rtw_btcoex_set_rf4ce_link_state(PADAPTER padapter, u8 state)
417 {
418 	hal_btcoex_set_rf4ce_link_state(state);
419 }
420 
rtw_btcoex_get_rf4ce_link_state(PADAPTER padapter)421 u8 rtw_btcoex_get_rf4ce_link_state(PADAPTER padapter)
422 {
423 	return hal_btcoex_get_rf4ce_link_state();
424 }
425 
rtw_btcoex_set_rf4ce_voice_state(PADAPTER padapter,u8 state)426 void rtw_btcoex_set_rf4ce_voice_state(PADAPTER padapter, u8 state)
427 {
428 	hal_btcoex_set_rf4ce_voice_state(state);
429 }
430 
rtw_btcoex_get_rf4ce_voice_state(PADAPTER padapter)431 u8 rtw_btcoex_get_rf4ce_voice_state(PADAPTER padapter)
432 {
433 	return hal_btcoex_get_rf4ce_voice_state();
434 }
435 #endif /* CONFIG_RF4CE_COEXIST */
436 
437 /* ==================================================
438  * Below Functions are called by BT-Coex
439  * ================================================== */
rtw_btcoex_rx_ampdu_apply(PADAPTER padapter)440 void rtw_btcoex_rx_ampdu_apply(PADAPTER padapter)
441 {
442 	rtw_rx_ampdu_apply(padapter);
443 }
444 
rtw_btcoex_LPS_Enter(PADAPTER padapter)445 void rtw_btcoex_LPS_Enter(PADAPTER padapter)
446 {
447 	struct pwrctrl_priv *pwrpriv;
448 	u8 lpsVal;
449 
450 
451 	pwrpriv = adapter_to_pwrctl(padapter);
452 
453 	pwrpriv->bpower_saving = _TRUE;
454 	lpsVal = rtw_btcoex_LpsVal(padapter);
455 	rtw_set_ps_mode(padapter, PS_MODE_MIN, 0, lpsVal, "BTCOEX");
456 }
457 
rtw_btcoex_LPS_Leave(PADAPTER padapter)458 void rtw_btcoex_LPS_Leave(PADAPTER padapter)
459 {
460 	struct pwrctrl_priv *pwrpriv;
461 
462 
463 	pwrpriv = adapter_to_pwrctl(padapter);
464 
465 	if (pwrpriv->pwr_mode != PS_MODE_ACTIVE) {
466 		rtw_set_ps_mode(padapter, PS_MODE_ACTIVE, 0, 0, "BTCOEX");
467 		LPS_RF_ON_check(padapter, 100);
468 		pwrpriv->bpower_saving = _FALSE;
469 	}
470 }
471 
rtw_btcoex_btreg_read(PADAPTER padapter,u8 type,u16 addr,u32 * data)472 u16 rtw_btcoex_btreg_read(PADAPTER padapter, u8 type, u16 addr, u32 *data)
473 {
474 	return hal_btcoex_btreg_read(padapter, type, addr, data);
475 }
476 
rtw_btcoex_btreg_write(PADAPTER padapter,u8 type,u16 addr,u16 val)477 u16 rtw_btcoex_btreg_write(PADAPTER padapter, u8 type, u16 addr, u16 val)
478 {
479 	return hal_btcoex_btreg_write(padapter, type, addr, val);
480 }
481 
rtw_btcoex_get_bt_coexist(PADAPTER padapter)482 u8 rtw_btcoex_get_bt_coexist(PADAPTER padapter)
483 {
484 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
485 
486 	return pHalData->EEPROMBluetoothCoexist;
487 }
488 
rtw_btcoex_get_chip_type(PADAPTER padapter)489 u8 rtw_btcoex_get_chip_type(PADAPTER padapter)
490 {
491 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
492 
493 	return pHalData->EEPROMBluetoothType;
494 }
495 
rtw_btcoex_get_pg_ant_num(PADAPTER padapter)496 u8 rtw_btcoex_get_pg_ant_num(PADAPTER padapter)
497 {
498 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
499 
500 	return pHalData->EEPROMBluetoothAntNum == Ant_x2 ? 2 : 1;
501 }
502 
rtw_btcoex_get_pg_single_ant_path(PADAPTER padapter)503 u8 rtw_btcoex_get_pg_single_ant_path(PADAPTER padapter)
504 {
505 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
506 
507 	return pHalData->ant_path;
508 }
509 
rtw_btcoex_get_pg_rfe_type(PADAPTER padapter)510 u8 rtw_btcoex_get_pg_rfe_type(PADAPTER padapter)
511 {
512 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
513 
514 	return pHalData->RFEType;
515 }
516 
rtw_btcoex_is_tfbga_package_type(PADAPTER padapter)517 u8 rtw_btcoex_is_tfbga_package_type(PADAPTER padapter)
518 {
519 	HAL_DATA_TYPE	*pHalData = GET_HAL_DATA(padapter);
520 
521 #ifdef CONFIG_RTL8723B
522 	if ((pHalData->PackageType == PACKAGE_TFBGA79) || (pHalData->PackageType == PACKAGE_TFBGA80)
523 	    || (pHalData->PackageType == PACKAGE_TFBGA90))
524 		return _TRUE;
525 #endif
526 
527 	return _FALSE;
528 }
529 
rtw_btcoex_get_ant_div_cfg(PADAPTER padapter)530 u8 rtw_btcoex_get_ant_div_cfg(PADAPTER padapter)
531 {
532 	PHAL_DATA_TYPE pHalData;
533 
534 	pHalData = GET_HAL_DATA(padapter);
535 
536 	return (pHalData->AntDivCfg == 0) ? _FALSE : _TRUE;
537 }
538 
539 /* ==================================================
540  * Below Functions are BT-Coex socket related function
541  * ================================================== */
542 
543 #ifdef CONFIG_BT_COEXIST_SOCKET_TRX
544 _adapter *pbtcoexadapter; /* = NULL; */ /* do not initialise globals to 0 or NULL */
rtw_btcoex_btinfo_cmd(_adapter * adapter,u8 * buf,u16 len)545 u8 rtw_btcoex_btinfo_cmd(_adapter *adapter, u8 *buf, u16 len)
546 {
547 	struct cmd_obj *ph2c;
548 	struct drvextra_cmd_parm *pdrvextra_cmd_parm;
549 	u8 *btinfo;
550 	struct cmd_priv *pcmdpriv = &adapter->cmdpriv;
551 	u8	res = _SUCCESS;
552 
553 	ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
554 	if (ph2c == NULL) {
555 		res = _FAIL;
556 		goto exit;
557 	}
558 
559 	pdrvextra_cmd_parm = (struct drvextra_cmd_parm *)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
560 	if (pdrvextra_cmd_parm == NULL) {
561 		rtw_mfree((u8 *)ph2c, sizeof(struct cmd_obj));
562 		res = _FAIL;
563 		goto exit;
564 	}
565 
566 	btinfo = rtw_zmalloc(len);
567 	if (btinfo == NULL) {
568 		rtw_mfree((u8 *)ph2c, sizeof(struct cmd_obj));
569 		rtw_mfree((u8 *)pdrvextra_cmd_parm, sizeof(struct drvextra_cmd_parm));
570 		res = _FAIL;
571 		goto exit;
572 	}
573 
574 	pdrvextra_cmd_parm->ec_id = BTINFO_WK_CID;
575 	pdrvextra_cmd_parm->type = 0;
576 	pdrvextra_cmd_parm->size = len;
577 	pdrvextra_cmd_parm->pbuf = btinfo;
578 
579 	_rtw_memcpy(btinfo, buf, len);
580 
581 	init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
582 
583 	res = rtw_enqueue_cmd(pcmdpriv, ph2c);
584 
585 exit:
586 	return res;
587 }
588 
rtw_btcoex_send_event_to_BT(_adapter * padapter,u8 status,u8 event_code,u8 opcode_low,u8 opcode_high,u8 * dbg_msg)589 u8 rtw_btcoex_send_event_to_BT(_adapter *padapter, u8 status,  u8 event_code, u8 opcode_low, u8 opcode_high, u8 *dbg_msg)
590 {
591 	u8 localBuf[6] = "";
592 	u8 *pRetPar;
593 	u8	len = 0, tx_event_length = 0;
594 	rtw_HCI_event *pEvent;
595 
596 	pEvent = (rtw_HCI_event *)(&localBuf[0]);
597 
598 	pEvent->EventCode = event_code;
599 	pEvent->Data[0] = 0x1;	/* packet # */
600 	pEvent->Data[1] = opcode_low;
601 	pEvent->Data[2] = opcode_high;
602 	len = len + 3;
603 
604 	/* Return parameters starts from here */
605 	pRetPar = &pEvent->Data[len];
606 	pRetPar[0] = status;		/* status */
607 
608 	len++;
609 	pEvent->Length = len;
610 
611 	/* total tx event length + EventCode length + sizeof(length) */
612 	tx_event_length = pEvent->Length + 2;
613 #if 0
614 	rtw_btcoex_dump_tx_msg((u8 *)pEvent, tx_event_length, dbg_msg);
615 #endif
616 	status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
617 
618 	return status;
619 }
620 
621 /*
622 Ref:
623 Realtek Wi-Fi Driver
624 Host Controller Interface for
625 Bluetooth 3.0 + HS V1.4 2013/02/07
626 
627 Window team code & BT team code
628  */
629 
630 
rtw_btcoex_parse_BT_info_notify_cmd(_adapter * padapter,u8 * pcmd,u16 cmdlen)631 u8 rtw_btcoex_parse_BT_info_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)
632 {
633 #define BT_INFO_LENGTH 8
634 
635 	u8 curPollEnable = pcmd[0];
636 	u8 curPollTime = pcmd[1];
637 	u8 btInfoReason = pcmd[2];
638 	u8 btInfoLen = pcmd[3];
639 	u8 btinfo[BT_INFO_LENGTH];
640 
641 	u8 localBuf[6] = "";
642 	u8 *pRetPar;
643 	u8	len = 0, tx_event_length = 0;
644 	RTW_HCI_STATUS status = HCI_STATUS_SUCCESS;
645 	rtw_HCI_event *pEvent;
646 
647 	/* RTW_INFO("%s\n",__func__);
648 	RTW_INFO("current Poll Enable: %d, currrent Poll Time: %d\n",curPollEnable,curPollTime);
649 	RTW_INFO("BT Info reason: %d, BT Info length: %d\n",btInfoReason,btInfoLen);
650 	RTW_INFO("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n"
651 		,pcmd[4],pcmd[5],pcmd[6],pcmd[7],pcmd[8],pcmd[9],pcmd[10],pcmd[11]);*/
652 
653 	_rtw_memset(btinfo, 0, BT_INFO_LENGTH);
654 
655 #if 1
656 	if (BT_INFO_LENGTH != btInfoLen) {
657 		status = HCI_STATUS_INVALID_HCI_CMD_PARA_VALUE;
658 		RTW_INFO("Error BT Info Length: %d\n", btInfoLen);
659 		/* return _FAIL; */
660 	} else
661 #endif
662 	{
663 		if (0x1 == btInfoReason || 0x2 == btInfoReason) {
664 			_rtw_memcpy(btinfo, &pcmd[4], btInfoLen);
665 			btinfo[0] = btInfoReason;
666 			rtw_btcoex_btinfo_cmd(padapter, btinfo, btInfoLen);
667 		} else
668 			RTW_INFO("Other BT info reason\n");
669 	}
670 
671 	/* send complete event to BT */
672 	{
673 
674 		pEvent = (rtw_HCI_event *)(&localBuf[0]);
675 
676 		pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;
677 		pEvent->Data[0] = 0x1;	/* packet # */
678 		pEvent->Data[1] = HCIOPCODELOW(HCI_BT_INFO_NOTIFY, OGF_EXTENSION);
679 		pEvent->Data[2] = HCIOPCODEHIGHT(HCI_BT_INFO_NOTIFY, OGF_EXTENSION);
680 		len = len + 3;
681 
682 		/* Return parameters starts from here */
683 		pRetPar = &pEvent->Data[len];
684 		pRetPar[0] = status;		/* status */
685 
686 		len++;
687 		pEvent->Length = len;
688 
689 		/* total tx event length + EventCode length + sizeof(length) */
690 		tx_event_length = pEvent->Length + 2;
691 #if 0
692 		rtw_btcoex_dump_tx_msg((u8 *)pEvent, tx_event_length, "BT_info_event");
693 #endif
694 		status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
695 
696 		return status;
697 		/* bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); */
698 	}
699 }
700 
rtw_btcoex_parse_BT_patch_ver_info_cmd(_adapter * padapter,u8 * pcmd,u16 cmdlen)701 u8 rtw_btcoex_parse_BT_patch_ver_info_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)
702 {
703 	RTW_HCI_STATUS status = HCI_STATUS_SUCCESS;
704 	u16		btPatchVer = 0x0, btHciVer = 0x0;
705 	/* u16		*pU2tmp; */
706 
707 	u8 localBuf[6] = "";
708 	u8 *pRetPar;
709 	u8	len = 0, tx_event_length = 0;
710 	rtw_HCI_event *pEvent;
711 
712 	btHciVer = pcmd[0] | pcmd[1] << 8;
713 	btPatchVer = pcmd[2] | pcmd[3] << 8;
714 
715 
716 	RTW_INFO("%s, cmd:%02x %02x %02x %02x\n", __func__, pcmd[0] , pcmd[1] , pcmd[2] , pcmd[3]);
717 	RTW_INFO("%s, HCI Ver:%d, Patch Ver:%d\n", __func__, btHciVer, btPatchVer);
718 
719 	rtw_btcoex_SetBtPatchVersion(padapter, btHciVer, btPatchVer);
720 
721 
722 	/* send complete event to BT */
723 	{
724 		pEvent = (rtw_HCI_event *)(&localBuf[0]);
725 
726 
727 		pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;
728 		pEvent->Data[0] = 0x1;	/* packet # */
729 		pEvent->Data[1] = HCIOPCODELOW(HCI_BT_PATCH_VERSION_NOTIFY, OGF_EXTENSION);
730 		pEvent->Data[2] = HCIOPCODEHIGHT(HCI_BT_PATCH_VERSION_NOTIFY, OGF_EXTENSION);
731 		len = len + 3;
732 
733 		/* Return parameters starts from here */
734 		pRetPar = &pEvent->Data[len];
735 		pRetPar[0] = status;		/* status */
736 
737 		len++;
738 		pEvent->Length = len;
739 
740 		/* total tx event length + EventCode length + sizeof(length) */
741 		tx_event_length = pEvent->Length + 2;
742 #if 0
743 		rtw_btcoex_dump_tx_msg((u8 *)pEvent, tx_event_length, "BT_patch_event");
744 #endif
745 		status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
746 		return status;
747 		/* bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); */
748 	}
749 }
750 
rtw_btcoex_parse_HCI_Ver_notify_cmd(_adapter * padapter,u8 * pcmd,u16 cmdlen)751 u8 rtw_btcoex_parse_HCI_Ver_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)
752 {
753 	RTW_HCI_STATUS status = HCI_STATUS_SUCCESS;
754 	u16 hciver = pcmd[0] | pcmd[1] << 8;
755 
756 	u8 localBuf[6] = "";
757 	u8 *pRetPar;
758 	u8	len = 0, tx_event_length = 0;
759 	rtw_HCI_event *pEvent;
760 
761 	struct bt_coex_info *pcoex_info = &padapter->coex_info;
762 	PBT_MGNT	pBtMgnt = &pcoex_info->BtMgnt;
763 	pBtMgnt->ExtConfig.HCIExtensionVer = hciver;
764 	RTW_INFO("%s, HCI Version: %d\n", __func__, pBtMgnt->ExtConfig.HCIExtensionVer);
765 	if (pBtMgnt->ExtConfig.HCIExtensionVer  < 4) {
766 		status = HCI_STATUS_INVALID_HCI_CMD_PARA_VALUE;
767 		RTW_INFO("%s, Version = %d, HCI Version < 4\n", __func__, pBtMgnt->ExtConfig.HCIExtensionVer);
768 	} else
769 		rtw_btcoex_SetHciVersion(padapter, hciver);
770 	/* send complete event to BT */
771 	{
772 		pEvent = (rtw_HCI_event *)(&localBuf[0]);
773 
774 
775 		pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;
776 		pEvent->Data[0] = 0x1;	/* packet # */
777 		pEvent->Data[1] = HCIOPCODELOW(HCI_EXTENSION_VERSION_NOTIFY, OGF_EXTENSION);
778 		pEvent->Data[2] = HCIOPCODEHIGHT(HCI_EXTENSION_VERSION_NOTIFY, OGF_EXTENSION);
779 		len = len + 3;
780 
781 		/* Return parameters starts from here */
782 		pRetPar = &pEvent->Data[len];
783 		pRetPar[0] = status;		/* status */
784 
785 		len++;
786 		pEvent->Length = len;
787 
788 		/* total tx event length + EventCode length + sizeof(length) */
789 		tx_event_length = pEvent->Length + 2;
790 
791 		status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
792 		return status;
793 		/* bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); */
794 	}
795 
796 }
797 
rtw_btcoex_parse_WIFI_scan_notify_cmd(_adapter * padapter,u8 * pcmd,u16 cmdlen)798 u8 rtw_btcoex_parse_WIFI_scan_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)
799 {
800 	RTW_HCI_STATUS status = HCI_STATUS_SUCCESS;
801 
802 	u8 localBuf[6] = "";
803 	u8 *pRetPar;
804 	u8	len = 0, tx_event_length = 0;
805 	rtw_HCI_event *pEvent;
806 
807 	struct bt_coex_info *pcoex_info = &padapter->coex_info;
808 	PBT_MGNT	pBtMgnt = &pcoex_info->BtMgnt;
809 	pBtMgnt->ExtConfig.bEnableWifiScanNotify = pcmd[0];
810 	RTW_INFO("%s, bEnableWifiScanNotify: %d\n", __func__, pBtMgnt->ExtConfig.bEnableWifiScanNotify);
811 
812 	/* send complete event to BT */
813 	{
814 		pEvent = (rtw_HCI_event *)(&localBuf[0]);
815 
816 
817 		pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;
818 		pEvent->Data[0] = 0x1;	/* packet # */
819 		pEvent->Data[1] = HCIOPCODELOW(HCI_ENABLE_WIFI_SCAN_NOTIFY, OGF_EXTENSION);
820 		pEvent->Data[2] = HCIOPCODEHIGHT(HCI_ENABLE_WIFI_SCAN_NOTIFY, OGF_EXTENSION);
821 		len = len + 3;
822 
823 		/* Return parameters starts from here */
824 		pRetPar = &pEvent->Data[len];
825 		pRetPar[0] = status;		/* status */
826 
827 		len++;
828 		pEvent->Length = len;
829 
830 		/* total tx event length + EventCode length + sizeof(length) */
831 		tx_event_length = pEvent->Length + 2;
832 
833 		status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
834 		return status;
835 		/* bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); */
836 	}
837 }
838 
rtw_btcoex_parse_HCI_link_status_notify_cmd(_adapter * padapter,u8 * pcmd,u16 cmdlen)839 u8 rtw_btcoex_parse_HCI_link_status_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)
840 {
841 	RTW_HCI_STATUS	status = HCI_STATUS_SUCCESS;
842 	struct bt_coex_info	*pcoex_info = &padapter->coex_info;
843 	PBT_MGNT	pBtMgnt = &pcoex_info->BtMgnt;
844 	/* PBT_DBG		pBtDbg=&padapter->MgntInfo.BtInfo.BtDbg; */
845 	u8		i, numOfHandle = 0, numOfAcl = 0;
846 	u16		conHandle;
847 	u8		btProfile, btCoreSpec, linkRole;
848 	u8		*pTriple;
849 
850 	u8 localBuf[6] = "";
851 	u8 *pRetPar;
852 	u8	len = 0, tx_event_length = 0;
853 	rtw_HCI_event *pEvent;
854 
855 	/* pBtDbg->dbgHciInfo.hciCmdCntLinkStatusNotify++; */
856 	/* RT_DISP_DATA(FIOCTL, IOCTL_BT_HCICMD_EXT, "LinkStatusNotify, Hex Data :\n",  */
857 	/*		&pHciCmd->Data[0], pHciCmd->Length); */
858 
859 	RTW_INFO("BTLinkStatusNotify\n");
860 
861 	/* Current only RTL8723 support this command. */
862 	/* pBtMgnt->bSupportProfile = TRUE; */
863 	pBtMgnt->bSupportProfile = _FALSE;
864 
865 	pBtMgnt->ExtConfig.NumberOfACL = 0;
866 	pBtMgnt->ExtConfig.NumberOfSCO = 0;
867 
868 	numOfHandle = pcmd[0];
869 	/* RT_DISP(FIOCTL, IOCTL_BT_HCICMD_EXT, ("numOfHandle = 0x%x\n", numOfHandle)); */
870 	/* RT_DISP(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCIExtensionVer = %d\n", pBtMgnt->ExtConfig.HCIExtensionVer)); */
871 	RTW_INFO("numOfHandle = 0x%x\n", numOfHandle);
872 	RTW_INFO("HCIExtensionVer = %d\n", pBtMgnt->ExtConfig.HCIExtensionVer);
873 
874 	pTriple = &pcmd[1];
875 	for (i = 0; i < numOfHandle; i++) {
876 		if (pBtMgnt->ExtConfig.HCIExtensionVer < 1) {
877 			conHandle = *((u8 *)&pTriple[0]);
878 			btProfile = pTriple[2];
879 			btCoreSpec = pTriple[3];
880 			if (BT_PROFILE_SCO == btProfile)
881 				pBtMgnt->ExtConfig.NumberOfSCO++;
882 			else {
883 				pBtMgnt->ExtConfig.NumberOfACL++;
884 				pBtMgnt->ExtConfig.aclLink[i].ConnectHandle = conHandle;
885 				pBtMgnt->ExtConfig.aclLink[i].BTProfile = btProfile;
886 				pBtMgnt->ExtConfig.aclLink[i].BTCoreSpec = btCoreSpec;
887 			}
888 			/* RT_DISP(FIOCTL, IOCTL_BT_HCICMD_EXT, */
889 			/*	("Connection_Handle=0x%x, BTProfile=%d, BTSpec=%d\n", */
890 			/*		conHandle, btProfile, btCoreSpec)); */
891 			RTW_INFO("Connection_Handle=0x%x, BTProfile=%d, BTSpec=%d\n", conHandle, btProfile, btCoreSpec);
892 			pTriple += 4;
893 		} else if (pBtMgnt->ExtConfig.HCIExtensionVer >= 1) {
894 			conHandle = *((pu2Byte)&pTriple[0]);
895 			btProfile = pTriple[2];
896 			btCoreSpec = pTriple[3];
897 			linkRole = pTriple[4];
898 			if (BT_PROFILE_SCO == btProfile)
899 				pBtMgnt->ExtConfig.NumberOfSCO++;
900 			else {
901 				pBtMgnt->ExtConfig.NumberOfACL++;
902 				pBtMgnt->ExtConfig.aclLink[i].ConnectHandle = conHandle;
903 				pBtMgnt->ExtConfig.aclLink[i].BTProfile = btProfile;
904 				pBtMgnt->ExtConfig.aclLink[i].BTCoreSpec = btCoreSpec;
905 				pBtMgnt->ExtConfig.aclLink[i].linkRole = linkRole;
906 			}
907 			/* RT_DISP(FIOCTL, IOCTL_BT_HCICMD_EXT, */
908 			RTW_INFO("Connection_Handle=0x%x, BTProfile=%d, BTSpec=%d, LinkRole=%d\n",
909 				 conHandle, btProfile, btCoreSpec, linkRole);
910 			pTriple += 5;
911 		}
912 	}
913 	rtw_btcoex_StackUpdateProfileInfo();
914 
915 	/* send complete event to BT */
916 	{
917 		pEvent = (rtw_HCI_event *)(&localBuf[0]);
918 
919 
920 		pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;
921 		pEvent->Data[0] = 0x1;	/* packet # */
922 		pEvent->Data[1] = HCIOPCODELOW(HCI_LINK_STATUS_NOTIFY, OGF_EXTENSION);
923 		pEvent->Data[2] = HCIOPCODEHIGHT(HCI_LINK_STATUS_NOTIFY, OGF_EXTENSION);
924 		len = len + 3;
925 
926 		/* Return parameters starts from here */
927 		pRetPar = &pEvent->Data[len];
928 		pRetPar[0] = status;		/* status */
929 
930 		len++;
931 		pEvent->Length = len;
932 
933 		/* total tx event length + EventCode length + sizeof(length) */
934 		tx_event_length = pEvent->Length + 2;
935 
936 		status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
937 		return status;
938 		/* bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); */
939 	}
940 
941 
942 }
943 
rtw_btcoex_parse_HCI_BT_coex_notify_cmd(_adapter * padapter,u8 * pcmd,u16 cmdlen)944 u8 rtw_btcoex_parse_HCI_BT_coex_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)
945 {
946 	u8 localBuf[6] = "";
947 	u8 *pRetPar;
948 	u8	len = 0, tx_event_length = 0;
949 	rtw_HCI_event *pEvent;
950 	RTW_HCI_STATUS	status = HCI_STATUS_SUCCESS;
951 
952 	{
953 		pEvent = (rtw_HCI_event *)(&localBuf[0]);
954 
955 
956 		pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;
957 		pEvent->Data[0] = 0x1;	/* packet # */
958 		pEvent->Data[1] = HCIOPCODELOW(HCI_BT_COEX_NOTIFY, OGF_EXTENSION);
959 		pEvent->Data[2] = HCIOPCODEHIGHT(HCI_BT_COEX_NOTIFY, OGF_EXTENSION);
960 		len = len + 3;
961 
962 		/* Return parameters starts from here */
963 		pRetPar = &pEvent->Data[len];
964 		pRetPar[0] = status;		/* status */
965 
966 		len++;
967 		pEvent->Length = len;
968 
969 		/* total tx event length + EventCode length + sizeof(length) */
970 		tx_event_length = pEvent->Length + 2;
971 
972 		status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
973 		return status;
974 		/* bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); */
975 	}
976 }
977 
rtw_btcoex_parse_HCI_BT_operation_notify_cmd(_adapter * padapter,u8 * pcmd,u16 cmdlen)978 u8 rtw_btcoex_parse_HCI_BT_operation_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)
979 {
980 	u8 localBuf[6] = "";
981 	u8 *pRetPar;
982 	u8	len = 0, tx_event_length = 0;
983 	rtw_HCI_event *pEvent;
984 	RTW_HCI_STATUS	status = HCI_STATUS_SUCCESS;
985 
986 	RTW_INFO("%s, OP code: %d\n", __func__, pcmd[0]);
987 
988 	switch (pcmd[0]) {
989 	case HCI_BT_OP_NONE:
990 		RTW_INFO("[bt operation] : Operation None!!\n");
991 		break;
992 	case HCI_BT_OP_INQUIRY_START:
993 		RTW_INFO("[bt operation] : Inquiry start!!\n");
994 		break;
995 	case HCI_BT_OP_INQUIRY_FINISH:
996 		RTW_INFO("[bt operation] : Inquiry finished!!\n");
997 		break;
998 	case HCI_BT_OP_PAGING_START:
999 		RTW_INFO("[bt operation] : Paging is started!!\n");
1000 		break;
1001 	case HCI_BT_OP_PAGING_SUCCESS:
1002 		RTW_INFO("[bt operation] : Paging complete successfully!!\n");
1003 		break;
1004 	case HCI_BT_OP_PAGING_UNSUCCESS:
1005 		RTW_INFO("[bt operation] : Paging complete unsuccessfully!!\n");
1006 		break;
1007 	case HCI_BT_OP_PAIRING_START:
1008 		RTW_INFO("[bt operation] : Pairing start!!\n");
1009 		break;
1010 	case HCI_BT_OP_PAIRING_FINISH:
1011 		RTW_INFO("[bt operation] : Pairing finished!!\n");
1012 		break;
1013 	case HCI_BT_OP_BT_DEV_ENABLE:
1014 		RTW_INFO("[bt operation] : BT Device is enabled!!\n");
1015 		break;
1016 	case HCI_BT_OP_BT_DEV_DISABLE:
1017 		RTW_INFO("[bt operation] : BT Device is disabled!!\n");
1018 		break;
1019 	default:
1020 		RTW_INFO("[bt operation] : Unknown, error!!\n");
1021 		break;
1022 	}
1023 
1024 	/* send complete event to BT */
1025 	{
1026 		pEvent = (rtw_HCI_event *)(&localBuf[0]);
1027 
1028 
1029 		pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;
1030 		pEvent->Data[0] = 0x1;	/* packet # */
1031 		pEvent->Data[1] = HCIOPCODELOW(HCI_BT_OPERATION_NOTIFY, OGF_EXTENSION);
1032 		pEvent->Data[2] = HCIOPCODEHIGHT(HCI_BT_OPERATION_NOTIFY, OGF_EXTENSION);
1033 		len = len + 3;
1034 
1035 		/* Return parameters starts from here */
1036 		pRetPar = &pEvent->Data[len];
1037 		pRetPar[0] = status;		/* status */
1038 
1039 		len++;
1040 		pEvent->Length = len;
1041 
1042 		/* total tx event length + EventCode length + sizeof(length) */
1043 		tx_event_length = pEvent->Length + 2;
1044 
1045 		status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
1046 		return status;
1047 		/* bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); */
1048 	}
1049 }
1050 
rtw_btcoex_parse_BT_AFH_MAP_notify_cmd(_adapter * padapter,u8 * pcmd,u16 cmdlen)1051 u8 rtw_btcoex_parse_BT_AFH_MAP_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)
1052 {
1053 	u8 localBuf[6] = "";
1054 	u8 *pRetPar;
1055 	u8	len = 0, tx_event_length = 0;
1056 	rtw_HCI_event *pEvent;
1057 	RTW_HCI_STATUS	status = HCI_STATUS_SUCCESS;
1058 
1059 	{
1060 		pEvent = (rtw_HCI_event *)(&localBuf[0]);
1061 
1062 
1063 		pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;
1064 		pEvent->Data[0] = 0x1;	/* packet # */
1065 		pEvent->Data[1] = HCIOPCODELOW(HCI_BT_AFH_MAP_NOTIFY, OGF_EXTENSION);
1066 		pEvent->Data[2] = HCIOPCODEHIGHT(HCI_BT_AFH_MAP_NOTIFY, OGF_EXTENSION);
1067 		len = len + 3;
1068 
1069 		/* Return parameters starts from here */
1070 		pRetPar = &pEvent->Data[len];
1071 		pRetPar[0] = status;		/* status */
1072 
1073 		len++;
1074 		pEvent->Length = len;
1075 
1076 		/* total tx event length + EventCode length + sizeof(length) */
1077 		tx_event_length = pEvent->Length + 2;
1078 
1079 		status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
1080 		return status;
1081 		/* bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); */
1082 	}
1083 }
1084 
rtw_btcoex_parse_BT_register_val_notify_cmd(_adapter * padapter,u8 * pcmd,u16 cmdlen)1085 u8 rtw_btcoex_parse_BT_register_val_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)
1086 {
1087 
1088 	u8 localBuf[6] = "";
1089 	u8 *pRetPar;
1090 	u8	len = 0, tx_event_length = 0;
1091 	rtw_HCI_event *pEvent;
1092 	RTW_HCI_STATUS	status = HCI_STATUS_SUCCESS;
1093 
1094 	{
1095 		pEvent = (rtw_HCI_event *)(&localBuf[0]);
1096 
1097 
1098 		pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;
1099 		pEvent->Data[0] = 0x1;	/* packet # */
1100 		pEvent->Data[1] = HCIOPCODELOW(HCI_BT_REGISTER_VALUE_NOTIFY, OGF_EXTENSION);
1101 		pEvent->Data[2] = HCIOPCODEHIGHT(HCI_BT_REGISTER_VALUE_NOTIFY, OGF_EXTENSION);
1102 		len = len + 3;
1103 
1104 		/* Return parameters starts from here */
1105 		pRetPar = &pEvent->Data[len];
1106 		pRetPar[0] = status;		/* status */
1107 
1108 		len++;
1109 		pEvent->Length = len;
1110 
1111 		/* total tx event length + EventCode length + sizeof(length) */
1112 		tx_event_length = pEvent->Length + 2;
1113 
1114 		status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
1115 		return status;
1116 		/* bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); */
1117 	}
1118 }
1119 
rtw_btcoex_parse_HCI_BT_abnormal_notify_cmd(_adapter * padapter,u8 * pcmd,u16 cmdlen)1120 u8 rtw_btcoex_parse_HCI_BT_abnormal_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)
1121 {
1122 	u8 localBuf[6] = "";
1123 	u8 *pRetPar;
1124 	u8	len = 0, tx_event_length = 0;
1125 	rtw_HCI_event *pEvent;
1126 	RTW_HCI_STATUS	status = HCI_STATUS_SUCCESS;
1127 
1128 	{
1129 		pEvent = (rtw_HCI_event *)(&localBuf[0]);
1130 
1131 
1132 		pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;
1133 		pEvent->Data[0] = 0x1;	/* packet # */
1134 		pEvent->Data[1] = HCIOPCODELOW(HCI_BT_ABNORMAL_NOTIFY, OGF_EXTENSION);
1135 		pEvent->Data[2] = HCIOPCODEHIGHT(HCI_BT_ABNORMAL_NOTIFY, OGF_EXTENSION);
1136 		len = len + 3;
1137 
1138 		/* Return parameters starts from here */
1139 		pRetPar = &pEvent->Data[len];
1140 		pRetPar[0] = status;		/* status */
1141 
1142 		len++;
1143 		pEvent->Length = len;
1144 
1145 		/* total tx event length + EventCode length + sizeof(length) */
1146 		tx_event_length = pEvent->Length + 2;
1147 
1148 		status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
1149 		return status;
1150 		/* bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); */
1151 	}
1152 }
1153 
rtw_btcoex_parse_HCI_query_RF_status_cmd(_adapter * padapter,u8 * pcmd,u16 cmdlen)1154 u8 rtw_btcoex_parse_HCI_query_RF_status_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)
1155 {
1156 	u8 localBuf[6] = "";
1157 	u8 *pRetPar;
1158 	u8	len = 0, tx_event_length = 0;
1159 	rtw_HCI_event *pEvent;
1160 	RTW_HCI_STATUS	status = HCI_STATUS_SUCCESS;
1161 
1162 	{
1163 		pEvent = (rtw_HCI_event *)(&localBuf[0]);
1164 
1165 
1166 		pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;
1167 		pEvent->Data[0] = 0x1;	/* packet # */
1168 		pEvent->Data[1] = HCIOPCODELOW(HCI_QUERY_RF_STATUS, OGF_EXTENSION);
1169 		pEvent->Data[2] = HCIOPCODEHIGHT(HCI_QUERY_RF_STATUS, OGF_EXTENSION);
1170 		len = len + 3;
1171 
1172 		/* Return parameters starts from here */
1173 		pRetPar = &pEvent->Data[len];
1174 		pRetPar[0] = status;		/* status */
1175 
1176 		len++;
1177 		pEvent->Length = len;
1178 
1179 		/* total tx event length + EventCode length + sizeof(length) */
1180 		tx_event_length = pEvent->Length + 2;
1181 
1182 		status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
1183 		return status;
1184 		/* bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); */
1185 	}
1186 }
1187 
1188 /*****************************************
1189 * HCI cmd format :
1190 *| 15 - 0						|
1191 *| OPcode (OCF|OGF<<10)		|
1192 *| 15 - 8		|7 - 0			|
1193 *|Cmd para	|Cmd para Length	|
1194 *|Cmd para......				|
1195 ******************************************/
1196 
1197 /* bit 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
1198  *	 |	OCF			             |	   OGF       | */
rtw_btcoex_parse_hci_extend_cmd(_adapter * padapter,u8 * pcmd,u16 len,const u16 hci_OCF)1199 void rtw_btcoex_parse_hci_extend_cmd(_adapter *padapter, u8 *pcmd, u16 len, const u16 hci_OCF)
1200 {
1201 
1202 	RTW_INFO("%s: OCF: %x\n", __func__, hci_OCF);
1203 	switch (hci_OCF) {
1204 	case HCI_EXTENSION_VERSION_NOTIFY:
1205 		RTW_INFO("HCI_EXTENSION_VERSION_NOTIFY\n");
1206 		rtw_btcoex_parse_HCI_Ver_notify_cmd(padapter, pcmd, len);
1207 		break;
1208 	case HCI_LINK_STATUS_NOTIFY:
1209 		RTW_INFO("HCI_LINK_STATUS_NOTIFY\n");
1210 		rtw_btcoex_parse_HCI_link_status_notify_cmd(padapter, pcmd, len);
1211 		break;
1212 	case HCI_BT_OPERATION_NOTIFY:
1213 		/* only for 8723a 2ant */
1214 		RTW_INFO("HCI_BT_OPERATION_NOTIFY\n");
1215 		rtw_btcoex_parse_HCI_BT_operation_notify_cmd(padapter, pcmd, len);
1216 		/*  */
1217 		break;
1218 	case HCI_ENABLE_WIFI_SCAN_NOTIFY:
1219 		RTW_INFO("HCI_ENABLE_WIFI_SCAN_NOTIFY\n");
1220 		rtw_btcoex_parse_WIFI_scan_notify_cmd(padapter, pcmd, len);
1221 		break;
1222 	case HCI_QUERY_RF_STATUS:
1223 		/* only for 8723b 2ant */
1224 		RTW_INFO("HCI_QUERY_RF_STATUS\n");
1225 		rtw_btcoex_parse_HCI_query_RF_status_cmd(padapter, pcmd, len);
1226 		break;
1227 	case HCI_BT_ABNORMAL_NOTIFY:
1228 		RTW_INFO("HCI_BT_ABNORMAL_NOTIFY\n");
1229 		rtw_btcoex_parse_HCI_BT_abnormal_notify_cmd(padapter, pcmd, len);
1230 		break;
1231 	case HCI_BT_INFO_NOTIFY:
1232 		RTW_INFO("HCI_BT_INFO_NOTIFY\n");
1233 		rtw_btcoex_parse_BT_info_notify_cmd(padapter, pcmd, len);
1234 		break;
1235 	case HCI_BT_COEX_NOTIFY:
1236 		RTW_INFO("HCI_BT_COEX_NOTIFY\n");
1237 		rtw_btcoex_parse_HCI_BT_coex_notify_cmd(padapter, pcmd, len);
1238 		break;
1239 	case HCI_BT_PATCH_VERSION_NOTIFY:
1240 		RTW_INFO("HCI_BT_PATCH_VERSION_NOTIFY\n");
1241 		rtw_btcoex_parse_BT_patch_ver_info_cmd(padapter, pcmd, len);
1242 		break;
1243 	case HCI_BT_AFH_MAP_NOTIFY:
1244 		RTW_INFO("HCI_BT_AFH_MAP_NOTIFY\n");
1245 		rtw_btcoex_parse_BT_AFH_MAP_notify_cmd(padapter, pcmd, len);
1246 		break;
1247 	case HCI_BT_REGISTER_VALUE_NOTIFY:
1248 		RTW_INFO("HCI_BT_REGISTER_VALUE_NOTIFY\n");
1249 		rtw_btcoex_parse_BT_register_val_notify_cmd(padapter, pcmd, len);
1250 		break;
1251 	default:
1252 		RTW_INFO("ERROR!!! Unknown OCF: %x\n", hci_OCF);
1253 		break;
1254 
1255 	}
1256 }
1257 
rtw_btcoex_parse_hci_cmd(_adapter * padapter,u8 * pcmd,u16 len)1258 void rtw_btcoex_parse_hci_cmd(_adapter *padapter, u8 *pcmd, u16 len)
1259 {
1260 	u16 opcode = pcmd[0] | pcmd[1] << 8;
1261 	u16 hci_OGF = HCI_OGF(opcode);
1262 	u16 hci_OCF = HCI_OCF(opcode);
1263 	u8 cmdlen = len - 3;
1264 	u8 pare_len = pcmd[2];
1265 
1266 	RTW_INFO("%s OGF: %x,OCF: %x\n", __func__, hci_OGF, hci_OCF);
1267 	switch (hci_OGF) {
1268 	case OGF_EXTENSION:
1269 		RTW_INFO("HCI_EXTENSION_CMD_OGF\n");
1270 		rtw_btcoex_parse_hci_extend_cmd(padapter, &pcmd[3], cmdlen, hci_OCF);
1271 		break;
1272 	default:
1273 		RTW_INFO("Other OGF: %x\n", hci_OGF);
1274 		break;
1275 	}
1276 }
1277 
rtw_btcoex_parse_recv_data(u8 * msg,u8 msg_size)1278 u16 rtw_btcoex_parse_recv_data(u8 *msg, u8 msg_size)
1279 {
1280 	u8 cmp_msg1[32] = attend_ack;
1281 	u8 cmp_msg2[32] = leave_ack;
1282 	u8 cmp_msg3[32] = bt_leave;
1283 	u8 cmp_msg4[32] = invite_req;
1284 	u8 cmp_msg5[32] = attend_req;
1285 	u8 cmp_msg6[32] = invite_rsp;
1286 	u8 res = OTHER;
1287 
1288 	if (_rtw_memcmp(cmp_msg1, msg, msg_size) == _TRUE) {
1289 		/*RTW_INFO("%s, msg:%s\n",__func__,msg);*/
1290 		res = RX_ATTEND_ACK;
1291 	} else if (_rtw_memcmp(cmp_msg2, msg, msg_size) == _TRUE) {
1292 		/*RTW_INFO("%s, msg:%s\n",__func__,msg);*/
1293 		res = RX_LEAVE_ACK;
1294 	} else if (_rtw_memcmp(cmp_msg3, msg, msg_size) == _TRUE) {
1295 		/*RTW_INFO("%s, msg:%s\n",__func__,msg);*/
1296 		res = RX_BT_LEAVE;
1297 	} else if (_rtw_memcmp(cmp_msg4, msg, msg_size) == _TRUE) {
1298 		/*RTW_INFO("%s, msg:%s\n",__func__,msg);*/
1299 		res = RX_INVITE_REQ;
1300 	} else if (_rtw_memcmp(cmp_msg5, msg, msg_size) == _TRUE)
1301 		res = RX_ATTEND_REQ;
1302 	else if (_rtw_memcmp(cmp_msg6, msg, msg_size) == _TRUE)
1303 		res = RX_INVITE_RSP;
1304 	else {
1305 		/*RTW_INFO("%s, %s\n", __func__, msg);*/
1306 		res = OTHER;
1307 	}
1308 
1309 	/*RTW_INFO("%s, res:%d\n", __func__, res);*/
1310 
1311 	return res;
1312 }
1313 
rtw_btcoex_recvmsgbysocket(void * data)1314 void rtw_btcoex_recvmsgbysocket(void *data)
1315 {
1316 	u8 recv_data[255];
1317 	u8 tx_msg[255] = leave_ack;
1318 	u32 len = 0;
1319 	u16 recv_length = 0;
1320 	u16 parse_res = 0;
1321 #if 0
1322 	u8 para_len = 0, polling_enable = 0, poling_interval = 0, reason = 0, btinfo_len = 0;
1323 	u8 btinfo[BT_INFO_LEN] = {0};
1324 #endif
1325 
1326 	struct bt_coex_info *pcoex_info = NULL;
1327 	struct sock *sk = NULL;
1328 	struct sk_buff *skb = NULL;
1329 
1330 	/*RTW_INFO("%s\n",__func__);*/
1331 
1332 	if (pbtcoexadapter == NULL) {
1333 		RTW_INFO("%s: btcoexadapter NULL!\n", __func__);
1334 		return;
1335 	}
1336 
1337 	pcoex_info = &pbtcoexadapter->coex_info;
1338 	sk = pcoex_info->sk_store;
1339 
1340 	if (sk == NULL) {
1341 		RTW_INFO("%s: critical error when receive socket data!\n", __func__);
1342 		return;
1343 	}
1344 
1345 	len = skb_queue_len(&sk->sk_receive_queue);
1346 	while (len > 0) {
1347 		skb = skb_dequeue(&sk->sk_receive_queue);
1348 
1349 		/*important: cut the udp header from skb->data! header length is 8 byte*/
1350 		recv_length = skb->len - 8;
1351 		_rtw_memset(recv_data, 0, sizeof(recv_data));
1352 		_rtw_memcpy(recv_data, skb->data + 8, recv_length);
1353 
1354 		parse_res = rtw_btcoex_parse_recv_data(recv_data, recv_length);
1355 #if 0
1356 		if (RX_ATTEND_ACK == parse_res) {
1357 			/* attend ack */
1358 			pcoex_info->BT_attend = _TRUE;
1359 			RTW_INFO("RX_ATTEND_ACK!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);
1360 		} else if (RX_ATTEND_REQ == parse_res) {
1361 			/* attend req from BT */
1362 			pcoex_info->BT_attend = _TRUE;
1363 			RTW_INFO("RX_BT_ATTEND_REQ!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);
1364 			rtw_btcoex_sendmsgbysocket(pbtcoexadapter, attend_ack, sizeof(attend_ack), _FALSE);
1365 		} else if (RX_INVITE_REQ == parse_res) {
1366 			/* invite req from BT */
1367 			pcoex_info->BT_attend = _TRUE;
1368 			RTW_INFO("RX_INVITE_REQ!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);
1369 			rtw_btcoex_sendmsgbysocket(pbtcoexadapter, invite_rsp, sizeof(invite_rsp), _FALSE);
1370 		} else if (RX_INVITE_RSP == parse_res) {
1371 			/* invite rsp */
1372 			pcoex_info->BT_attend = _TRUE;
1373 			RTW_INFO("RX_INVITE_RSP!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);
1374 		} else if (RX_LEAVE_ACK == parse_res) {
1375 			/* mean BT know wifi  will leave */
1376 			pcoex_info->BT_attend = _FALSE;
1377 			RTW_INFO("RX_LEAVE_ACK!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);
1378 		} else if (RX_BT_LEAVE == parse_res) {
1379 			/* BT leave */
1380 			rtw_btcoex_sendmsgbysocket(pbtcoexadapter, leave_ack, sizeof(leave_ack), _FALSE); /*  no ack */
1381 			pcoex_info->BT_attend = _FALSE;
1382 			RTW_INFO("RX_BT_LEAVE!sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);
1383 		} else {
1384 			/* todo: check if recv data are really hci cmds */
1385 			if (_TRUE == pcoex_info->BT_attend)
1386 				rtw_btcoex_parse_hci_cmd(pbtcoexadapter, recv_data, recv_length);
1387 		}
1388 #endif
1389 		switch (parse_res) {
1390 		case RX_ATTEND_ACK:
1391 			/* attend ack */
1392 			pcoex_info->BT_attend = _TRUE;
1393 			RTW_INFO("RX_ATTEND_ACK!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);
1394 			rtw_btcoex_BTOffOnNotify(pbtcoexadapter, pcoex_info->BT_attend);
1395 			break;
1396 
1397 		case RX_ATTEND_REQ:
1398 			pcoex_info->BT_attend = _TRUE;
1399 			RTW_INFO("RX_BT_ATTEND_REQ!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);
1400 			rtw_btcoex_sendmsgbysocket(pbtcoexadapter, attend_ack, sizeof(attend_ack), _FALSE);
1401 			rtw_btcoex_BTOffOnNotify(pbtcoexadapter, pcoex_info->BT_attend);
1402 			break;
1403 
1404 		case RX_INVITE_REQ:
1405 			/* invite req from BT */
1406 			pcoex_info->BT_attend = _TRUE;
1407 			RTW_INFO("RX_INVITE_REQ!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);
1408 			rtw_btcoex_sendmsgbysocket(pbtcoexadapter, invite_rsp, sizeof(invite_rsp), _FALSE);
1409 			rtw_btcoex_BTOffOnNotify(pbtcoexadapter, pcoex_info->BT_attend);
1410 			break;
1411 
1412 		case RX_INVITE_RSP:
1413 			/*invite rsp*/
1414 			pcoex_info->BT_attend = _TRUE;
1415 			RTW_INFO("RX_INVITE_RSP!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);
1416 			rtw_btcoex_BTOffOnNotify(pbtcoexadapter, pcoex_info->BT_attend);
1417 			break;
1418 
1419 		case RX_LEAVE_ACK:
1420 			/* mean BT know wifi  will leave */
1421 			pcoex_info->BT_attend = _FALSE;
1422 			RTW_INFO("RX_LEAVE_ACK!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);
1423 			rtw_btcoex_BTOffOnNotify(pbtcoexadapter, pcoex_info->BT_attend);
1424 			break;
1425 
1426 		case RX_BT_LEAVE:
1427 			/* BT leave */
1428 			rtw_btcoex_sendmsgbysocket(pbtcoexadapter, leave_ack, sizeof(leave_ack), _FALSE); /* no ack */
1429 			pcoex_info->BT_attend = _FALSE;
1430 			RTW_INFO("RX_BT_LEAVE!sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);
1431 			rtw_btcoex_BTOffOnNotify(pbtcoexadapter, pcoex_info->BT_attend);
1432 			break;
1433 
1434 		default:
1435 			if (_TRUE == pcoex_info->BT_attend)
1436 				rtw_btcoex_parse_hci_cmd(pbtcoexadapter, recv_data, recv_length);
1437 			else
1438 				RTW_INFO("ERROR!! BT is UP\n");
1439 			break;
1440 
1441 		}
1442 
1443 		len--;
1444 		kfree_skb(skb);
1445 	}
1446 }
1447 
1448 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 15, 0))
rtw_btcoex_recvmsg_init(struct sock * sk_in,s32 bytes)1449 	void rtw_btcoex_recvmsg_init(struct sock *sk_in, s32 bytes)
1450 #else
1451 	void rtw_btcoex_recvmsg_init(struct sock *sk_in)
1452 #endif
1453 {
1454 	struct bt_coex_info *pcoex_info = NULL;
1455 
1456 	if (pbtcoexadapter == NULL) {
1457 		RTW_INFO("%s: btcoexadapter NULL\n", __func__);
1458 		return;
1459 	}
1460 	pcoex_info = &pbtcoexadapter->coex_info;
1461 	pcoex_info->sk_store = sk_in;
1462 	if (pcoex_info->btcoex_wq != NULL)
1463 		queue_delayed_work(pcoex_info->btcoex_wq, &pcoex_info->recvmsg_work, 0);
1464 	else
1465 		RTW_INFO("%s: BTCOEX workqueue NULL\n", __func__);
1466 }
1467 
rtw_btcoex_sendmsgbysocket(_adapter * padapter,u8 * msg,u8 msg_size,bool force)1468 u8 rtw_btcoex_sendmsgbysocket(_adapter *padapter, u8 *msg, u8 msg_size, bool force)
1469 {
1470 	u8 error;
1471 	struct msghdr	udpmsg;
1472 	mm_segment_t	oldfs;
1473 	struct iovec	iov;
1474 	struct bt_coex_info *pcoex_info = &padapter->coex_info;
1475 
1476 	/* RTW_INFO("%s: msg:%s, force:%s\n", __func__, msg, force == _TRUE?"TRUE":"FALSE"); */
1477 	if (_FALSE == force) {
1478 		if (_FALSE == pcoex_info->BT_attend) {
1479 			RTW_INFO("TX Blocked: WiFi-BT disconnected\n");
1480 			return _FAIL;
1481 		}
1482 	}
1483 
1484 	iov.iov_base	 = (void *)msg;
1485 	iov.iov_len	 = msg_size;
1486 	udpmsg.msg_name	 = &pcoex_info->bt_sockaddr;
1487 	udpmsg.msg_namelen	= sizeof(struct sockaddr_in);
1488 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0))
1489 	/* referece:sock_xmit in kernel code
1490 	 * WRITE for sock_sendmsg, READ for sock_recvmsg
1491 	 * third parameter for msg_iovlen
1492 	 * last parameter for iov_len
1493 	 */
1494 	iov_iter_init(&udpmsg.msg_iter, WRITE, &iov, 1, msg_size);
1495 #else
1496 	udpmsg.msg_iov	 = &iov;
1497 	udpmsg.msg_iovlen	= 1;
1498 #endif
1499 	udpmsg.msg_control	= NULL;
1500 	udpmsg.msg_controllen = 0;
1501 	udpmsg.msg_flags	= MSG_DONTWAIT | MSG_NOSIGNAL;
1502 	oldfs = get_fs();
1503 	set_fs(KERNEL_DS);
1504 
1505 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0))
1506 	error = sock_sendmsg(pcoex_info->udpsock, &udpmsg);
1507 #else
1508 	error = sock_sendmsg(pcoex_info->udpsock, &udpmsg, msg_size);
1509 #endif
1510 	set_fs(oldfs);
1511 	if (error < 0) {
1512 		RTW_INFO("Error when sendimg msg, error:%d\n", error);
1513 		return _FAIL;
1514 	} else
1515 		return _SUCCESS;
1516 }
1517 
rtw_btcoex_create_kernel_socket(_adapter * padapter)1518 u8 rtw_btcoex_create_kernel_socket(_adapter *padapter)
1519 {
1520 	s8 kernel_socket_err;
1521 	u8 tx_msg[255] = attend_req;
1522 	struct bt_coex_info *pcoex_info = &padapter->coex_info;
1523 	s32 sock_reuse = 1;
1524 	u8 status = _FAIL;
1525 
1526 	RTW_INFO("%s CONNECT_PORT %d\n", __func__, CONNECT_PORT);
1527 
1528 	if (NULL == pcoex_info) {
1529 		RTW_INFO("coex_info: NULL\n");
1530 		status =  _FAIL;
1531 	}
1532 
1533 	kernel_socket_err = sock_create(PF_INET, SOCK_DGRAM, 0, &pcoex_info->udpsock);
1534 
1535 	if (kernel_socket_err < 0) {
1536 		RTW_INFO("Error during creation of socket error:%d\n", kernel_socket_err);
1537 		status = _FAIL;
1538 	} else {
1539 		_rtw_memset(&(pcoex_info->wifi_sockaddr), 0, sizeof(pcoex_info->wifi_sockaddr));
1540 		pcoex_info->wifi_sockaddr.sin_family = AF_INET;
1541 		pcoex_info->wifi_sockaddr.sin_port = htons(CONNECT_PORT);
1542 		pcoex_info->wifi_sockaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1543 
1544 		_rtw_memset(&(pcoex_info->bt_sockaddr), 0, sizeof(pcoex_info->bt_sockaddr));
1545 		pcoex_info->bt_sockaddr.sin_family = AF_INET;
1546 		pcoex_info->bt_sockaddr.sin_port = htons(CONNECT_PORT_BT);
1547 		pcoex_info->bt_sockaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1548 
1549 		pcoex_info->sk_store = NULL;
1550 		kernel_socket_err = pcoex_info->udpsock->ops->bind(pcoex_info->udpsock, (struct sockaddr *)&pcoex_info->wifi_sockaddr,
1551 				    sizeof(pcoex_info->wifi_sockaddr));
1552 		if (kernel_socket_err == 0) {
1553 			RTW_INFO("binding socket success\n");
1554 			pcoex_info->udpsock->sk->sk_data_ready = rtw_btcoex_recvmsg_init;
1555 			pcoex_info->sock_open |=  KERNEL_SOCKET_OK;
1556 			pcoex_info->BT_attend = _FALSE;
1557 			RTW_INFO("WIFI sending attend_req\n");
1558 			rtw_btcoex_sendmsgbysocket(padapter, attend_req, sizeof(attend_req), _TRUE);
1559 			status = _SUCCESS;
1560 		} else {
1561 			pcoex_info->BT_attend = _FALSE;
1562 			sock_release(pcoex_info->udpsock); /* bind fail release socket */
1563 			RTW_INFO("Error binding socket: %d\n", kernel_socket_err);
1564 			status = _FAIL;
1565 		}
1566 
1567 	}
1568 
1569 	return status;
1570 }
1571 
rtw_btcoex_close_kernel_socket(_adapter * padapter)1572 void rtw_btcoex_close_kernel_socket(_adapter *padapter)
1573 {
1574 	struct bt_coex_info *pcoex_info = &padapter->coex_info;
1575 	if (pcoex_info->sock_open & KERNEL_SOCKET_OK) {
1576 		RTW_INFO("release kernel socket\n");
1577 		sock_release(pcoex_info->udpsock);
1578 		pcoex_info->sock_open &= ~(KERNEL_SOCKET_OK);
1579 		if (_TRUE == pcoex_info->BT_attend)
1580 			pcoex_info->BT_attend = _FALSE;
1581 
1582 		RTW_INFO("sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);
1583 	}
1584 }
1585 
rtw_btcoex_init_socket(_adapter * padapter)1586 void rtw_btcoex_init_socket(_adapter *padapter)
1587 {
1588 
1589 	u8 is_invite = _FALSE;
1590 	struct bt_coex_info *pcoex_info = &padapter->coex_info;
1591 	RTW_INFO("%s\n", __func__);
1592 	if (_FALSE == pcoex_info->is_exist) {
1593 		_rtw_memset(pcoex_info, 0, sizeof(struct bt_coex_info));
1594 		pcoex_info->btcoex_wq = create_workqueue("BTCOEX");
1595 		INIT_DELAYED_WORK(&pcoex_info->recvmsg_work,
1596 				  (void *)rtw_btcoex_recvmsgbysocket);
1597 		pbtcoexadapter = padapter;
1598 		/* We expect BT is off if BT don't send ack to wifi */
1599 		RTW_INFO("We expect BT is off if BT send ack to wifi\n");
1600 		rtw_btcoex_BTOffOnNotify(pbtcoexadapter, _FALSE);
1601 		if (rtw_btcoex_create_kernel_socket(padapter) == _SUCCESS)
1602 			pcoex_info->is_exist = _TRUE;
1603 		else {
1604 			pcoex_info->is_exist = _FALSE;
1605 			pbtcoexadapter = NULL;
1606 		}
1607 
1608 		RTW_INFO("%s: pbtcoexadapter:%p, coex_info->is_exist: %s\n"
1609 			, __func__, pbtcoexadapter, pcoex_info->is_exist == _TRUE ? "TRUE" : "FALSE");
1610 	}
1611 }
1612 
rtw_btcoex_close_socket(_adapter * padapter)1613 void rtw_btcoex_close_socket(_adapter *padapter)
1614 {
1615 	struct bt_coex_info *pcoex_info = &padapter->coex_info;
1616 
1617 	RTW_INFO("%s--coex_info->is_exist: %s, pcoex_info->BT_attend:%s\n"
1618 		, __func__, pcoex_info->is_exist == _TRUE ? "TRUE" : "FALSE", pcoex_info->BT_attend == _TRUE ? "TRUE" : "FALSE");
1619 
1620 	if (_TRUE == pcoex_info->is_exist) {
1621 		if (_TRUE == pcoex_info->BT_attend) {
1622 			/*inform BT wifi leave*/
1623 			rtw_btcoex_sendmsgbysocket(padapter, wifi_leave, sizeof(wifi_leave), _FALSE);
1624 			msleep(50);
1625 		}
1626 
1627 		if (pcoex_info->btcoex_wq != NULL) {
1628 			flush_workqueue(pcoex_info->btcoex_wq);
1629 			destroy_workqueue(pcoex_info->btcoex_wq);
1630 		}
1631 
1632 		rtw_btcoex_close_kernel_socket(padapter);
1633 		pbtcoexadapter = NULL;
1634 		pcoex_info->is_exist = _FALSE;
1635 	}
1636 }
1637 
rtw_btcoex_dump_tx_msg(u8 * tx_msg,u8 len,u8 * msg_name)1638 void rtw_btcoex_dump_tx_msg(u8 *tx_msg, u8 len, u8 *msg_name)
1639 {
1640 	u8	i = 0;
1641 	RTW_INFO("======> Msg name: %s\n", msg_name);
1642 	for (i = 0; i < len; i++)
1643 		printk("%02x ", tx_msg[i]);
1644 	printk("\n");
1645 	RTW_INFO("Msg name: %s <======\n", msg_name);
1646 }
1647 
1648 /* Porting from Windows team */
rtw_btcoex_SendEventExtBtCoexControl(PADAPTER padapter,u8 bNeedDbgRsp,u8 dataLen,void * pData)1649 void rtw_btcoex_SendEventExtBtCoexControl(PADAPTER padapter, u8 bNeedDbgRsp, u8 dataLen, void *pData)
1650 {
1651 	u8			len = 0, tx_event_length = 0;
1652 	u8 			localBuf[32] = "";
1653 	u8			*pRetPar;
1654 	u8			opCode = 0;
1655 	u8			*pInBuf = (pu1Byte)pData;
1656 	u8			*pOpCodeContent;
1657 	rtw_HCI_event *pEvent;
1658 
1659 	opCode = pInBuf[0];
1660 
1661 	RTW_INFO("%s, OPCode:%02x\n", __func__, opCode);
1662 
1663 	pEvent = (rtw_HCI_event *)(&localBuf[0]);
1664 
1665 	/* len += bthci_ExtensionEventHeaderRtk(&localBuf[0], */
1666 	/*	HCI_EVENT_EXT_BT_COEX_CONTROL); */
1667 	pEvent->EventCode = HCI_EVENT_EXTENSION_RTK;
1668 	pEvent->Data[0] = HCI_EVENT_EXT_BT_COEX_CONTROL;	/* extension event code */
1669 	len++;
1670 
1671 	/* Return parameters starts from here */
1672 	pRetPar = &pEvent->Data[len];
1673 	_rtw_memcpy(&pRetPar[0], pData, dataLen);
1674 
1675 	len += dataLen;
1676 
1677 	pEvent->Length = len;
1678 
1679 	/* total tx event length + EventCode length + sizeof(length) */
1680 	tx_event_length = pEvent->Length + 2;
1681 #if 0
1682 	rtw_btcoex_dump_tx_msg((u8 *)pEvent, tx_event_length, "BT COEX CONTROL", _FALSE);
1683 #endif
1684 	rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
1685 
1686 }
1687 
1688 /* Porting from Windows team */
rtw_btcoex_SendEventExtBtInfoControl(PADAPTER padapter,u8 dataLen,void * pData)1689 void rtw_btcoex_SendEventExtBtInfoControl(PADAPTER padapter, u8 dataLen, void *pData)
1690 {
1691 	rtw_HCI_event *pEvent;
1692 	u8			*pRetPar;
1693 	u8			len = 0, tx_event_length = 0;
1694 	u8 			localBuf[32] = "";
1695 
1696 	struct bt_coex_info *pcoex_info = &padapter->coex_info;
1697 	PBT_MGNT		pBtMgnt = &pcoex_info->BtMgnt;
1698 
1699 	/* RTW_INFO("%s\n",__func__);*/
1700 	if (pBtMgnt->ExtConfig.HCIExtensionVer < 4) { /* not support */
1701 		RTW_INFO("ERROR: HCIExtensionVer = %d, HCIExtensionVer<4 !!!!\n", pBtMgnt->ExtConfig.HCIExtensionVer);
1702 		return;
1703 	}
1704 
1705 	pEvent = (rtw_HCI_event *)(&localBuf[0]);
1706 
1707 	/* len += bthci_ExtensionEventHeaderRtk(&localBuf[0], */
1708 	/*		HCI_EVENT_EXT_BT_INFO_CONTROL); */
1709 	pEvent->EventCode = HCI_EVENT_EXTENSION_RTK;
1710 	pEvent->Data[0] = HCI_EVENT_EXT_BT_INFO_CONTROL;		/* extension event code */
1711 	len++;
1712 
1713 	/* Return parameters starts from here */
1714 	pRetPar = &pEvent->Data[len];
1715 	_rtw_memcpy(&pRetPar[0], pData, dataLen);
1716 
1717 	len += dataLen;
1718 
1719 	pEvent->Length = len;
1720 
1721 	/* total tx event length + EventCode length + sizeof(length) */
1722 	tx_event_length = pEvent->Length + 2;
1723 #if 0
1724 	rtw_btcoex_dump_tx_msg((u8 *)pEvent, tx_event_length, "BT INFO CONTROL");
1725 #endif
1726 	rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
1727 
1728 }
1729 
rtw_btcoex_SendScanNotify(PADAPTER padapter,u8 scanType)1730 void rtw_btcoex_SendScanNotify(PADAPTER padapter, u8 scanType)
1731 {
1732 	u8	len = 0, tx_event_length = 0;
1733 	u8 	localBuf[7] = "";
1734 	u8	*pRetPar;
1735 	u8	*pu1Temp;
1736 	rtw_HCI_event *pEvent;
1737 	struct bt_coex_info *pcoex_info = &padapter->coex_info;
1738 	PBT_MGNT		pBtMgnt = &pcoex_info->BtMgnt;
1739 
1740 	/*	if(!pBtMgnt->BtOperationOn)
1741 	 *		return; */
1742 
1743 	pEvent = (rtw_HCI_event *)(&localBuf[0]);
1744 
1745 	/*	len += bthci_ExtensionEventHeaderRtk(&localBuf[0],
1746 	 *			HCI_EVENT_EXT_WIFI_SCAN_NOTIFY); */
1747 
1748 	pEvent->EventCode = HCI_EVENT_EXTENSION_RTK;
1749 	pEvent->Data[0] = HCI_EVENT_EXT_WIFI_SCAN_NOTIFY;		/* extension event code */
1750 	len++;
1751 
1752 	/* Return parameters starts from here */
1753 	/* pRetPar = &PPacketIrpEvent->Data[len]; */
1754 	/* pu1Temp = (u8 *)&pRetPar[0]; */
1755 	/* *pu1Temp = scanType; */
1756 	pEvent->Data[len] = scanType;
1757 	len += 1;
1758 
1759 	pEvent->Length = len;
1760 
1761 	/* total tx event length + EventCode length + sizeof(length) */
1762 	tx_event_length = pEvent->Length + 2;
1763 #if 0
1764 	rtw_btcoex_dump_tx_msg((u8 *)pEvent, tx_event_length, "WIFI SCAN OPERATION");
1765 #endif
1766 	rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
1767 }
1768 #endif /* CONFIG_BT_COEXIST_SOCKET_TRX */
1769 #endif /* CONFIG_BT_COEXIST */
1770