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