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