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