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