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