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