1 /******************************************************************************
3 * Copyright(c) 2013 Realtek Corporation. All rights reserved.
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.
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
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
19 ******************************************************************************/
20 #ifdef CONFIG_BT_COEXIST
22 #include <drv_types.h>
23 #include <hal_btcoex.h>
27 void rtw_btcoex_Initialize(PADAPTER padapter)
29 hal_btcoex_Initialize(padapter);
32 void rtw_btcoex_PowerOnSetting(PADAPTER padapter)
34 hal_btcoex_PowerOnSetting(padapter);
37 void rtw_btcoex_PreLoadFirmware(PADAPTER padapter)
39 hal_btcoex_PreLoadFirmware(padapter);
42 void rtw_btcoex_HAL_Initialize(PADAPTER padapter, u8 bWifiOnly)
44 hal_btcoex_InitHwConfig(padapter, bWifiOnly);
47 void rtw_btcoex_IpsNotify(PADAPTER padapter, u8 type)
49 PHAL_DATA_TYPE pHalData;
51 pHalData = GET_HAL_DATA(padapter);
52 if (_FALSE == pHalData->EEPROMBluetoothCoexist)
55 hal_btcoex_IpsNotify(padapter, type);
58 void rtw_btcoex_LpsNotify(PADAPTER padapter, u8 type)
60 PHAL_DATA_TYPE pHalData;
62 pHalData = GET_HAL_DATA(padapter);
63 if (_FALSE == pHalData->EEPROMBluetoothCoexist)
66 hal_btcoex_LpsNotify(padapter, type);
69 void rtw_btcoex_ScanNotify(PADAPTER padapter, u8 type)
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
77 pHalData = GET_HAL_DATA(padapter);
78 if (_FALSE == pHalData->EEPROMBluetoothCoexist)
81 #ifdef CONFIG_CONCURRENT_MODE
82 if ((_FALSE == type) && (padapter->pbuddy_adapter))
84 PADAPTER pbuddy = padapter->pbuddy_adapter;
85 if (check_fwstate(&pbuddy->mlmepriv, WIFI_SITE_MONITOR) == _TRUE)
90 #ifdef CONFIG_BT_COEXIST_SOCKET_TRX
91 if(pBtMgnt->ExtConfig.bEnableWifiScanNotify)
92 rtw_btcoex_SendScanNotify(padapter, type);
93 #endif //CONFIG_BT_COEXIST_SOCKET_TRX
95 hal_btcoex_ScanNotify(padapter, type);
98 void rtw_btcoex_ConnectNotify(PADAPTER padapter, u8 action)
100 PHAL_DATA_TYPE pHalData;
102 pHalData = GET_HAL_DATA(padapter);
103 if (_FALSE == pHalData->EEPROMBluetoothCoexist)
106 #ifdef DBG_CONFIG_ERROR_RESET
107 if (_TRUE == rtw_hal_sreset_inprogress(padapter))
109 DBG_8192C(FUNC_ADPT_FMT ": [BTCoex] under reset, skip notify!\n",
110 FUNC_ADPT_ARG(padapter));
113 #endif // DBG_CONFIG_ERROR_RESET
115 #ifdef CONFIG_CONCURRENT_MODE
116 if ((_FALSE == action) && (padapter->pbuddy_adapter))
118 PADAPTER pbuddy = padapter->pbuddy_adapter;
119 if (check_fwstate(&pbuddy->mlmepriv, WIFI_UNDER_LINKING) == _TRUE)
124 hal_btcoex_ConnectNotify(padapter, action);
127 void rtw_btcoex_MediaStatusNotify(PADAPTER padapter, u8 mediaStatus)
129 PHAL_DATA_TYPE pHalData;
131 pHalData = GET_HAL_DATA(padapter);
132 if (_FALSE == pHalData->EEPROMBluetoothCoexist)
135 #ifdef DBG_CONFIG_ERROR_RESET
136 if (_TRUE == rtw_hal_sreset_inprogress(padapter))
138 DBG_8192C(FUNC_ADPT_FMT ": [BTCoex] under reset, skip notify!\n",
139 FUNC_ADPT_ARG(padapter));
142 #endif // DBG_CONFIG_ERROR_RESET
144 #ifdef CONFIG_CONCURRENT_MODE
145 if ((RT_MEDIA_DISCONNECT == mediaStatus) && (padapter->pbuddy_adapter))
147 PADAPTER pbuddy = padapter->pbuddy_adapter;
148 if (check_fwstate(&pbuddy->mlmepriv, WIFI_ASOC_STATE) == _TRUE)
151 #endif // CONFIG_CONCURRENT_MODE
153 if ((RT_MEDIA_CONNECT == mediaStatus)
154 && (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE))
156 rtw_hal_set_hwreg(padapter, HW_VAR_DL_RSVD_PAGE, NULL);
159 hal_btcoex_MediaStatusNotify(padapter, mediaStatus);
162 void rtw_btcoex_SpecialPacketNotify(PADAPTER padapter, u8 pktType)
164 PHAL_DATA_TYPE pHalData;
166 pHalData = GET_HAL_DATA(padapter);
167 if (_FALSE == pHalData->EEPROMBluetoothCoexist)
170 hal_btcoex_SpecialPacketNotify(padapter, pktType);
173 void rtw_btcoex_IQKNotify(PADAPTER padapter, u8 state)
175 PHAL_DATA_TYPE pHalData;
177 pHalData = GET_HAL_DATA(padapter);
178 if (_FALSE == pHalData->EEPROMBluetoothCoexist)
181 hal_btcoex_IQKNotify(padapter, state);
184 void rtw_btcoex_BtInfoNotify(PADAPTER padapter, u8 length, u8 *tmpBuf)
186 PHAL_DATA_TYPE pHalData;
188 pHalData = GET_HAL_DATA(padapter);
189 if (_FALSE == pHalData->EEPROMBluetoothCoexist)
192 hal_btcoex_BtInfoNotify(padapter, length, tmpBuf);
195 void rtw_btcoex_SuspendNotify(PADAPTER padapter, u8 state)
197 PHAL_DATA_TYPE pHalData;
199 pHalData = GET_HAL_DATA(padapter);
200 if (_FALSE == pHalData->EEPROMBluetoothCoexist)
203 hal_btcoex_SuspendNotify(padapter, state);
206 void rtw_btcoex_HaltNotify(PADAPTER padapter)
208 PHAL_DATA_TYPE pHalData;
210 pHalData = GET_HAL_DATA(padapter);
211 if (_FALSE == pHalData->EEPROMBluetoothCoexist)
214 if (_FALSE == padapter->bup)
216 DBG_871X(FUNC_ADPT_FMT ": bup=%d Skip!\n",
217 FUNC_ADPT_ARG(padapter), padapter->bup);
222 if (_TRUE == padapter->bSurpriseRemoved)
224 DBG_871X(FUNC_ADPT_FMT ": bSurpriseRemoved=%d Skip!\n",
225 FUNC_ADPT_ARG(padapter), padapter->bSurpriseRemoved);
230 hal_btcoex_HaltNotify(padapter);
233 void rtw_btcoex_SwitchBtTRxMask(PADAPTER padapter)
235 hal_btcoex_SwitchBtTRxMask(padapter);
238 void rtw_btcoex_Switch(PADAPTER padapter, u8 enable)
240 hal_btcoex_SetBTCoexist(padapter, enable);
243 u8 rtw_btcoex_IsBtDisabled(PADAPTER padapter)
245 return hal_btcoex_IsBtDisabled(padapter);
248 void rtw_btcoex_Handler(PADAPTER padapter)
250 PHAL_DATA_TYPE pHalData;
252 pHalData = GET_HAL_DATA(padapter);
254 if (_FALSE == pHalData->EEPROMBluetoothCoexist)
257 #if defined(CONFIG_CONCURRENT_MODE)
258 if (padapter->adapter_type != PRIMARY_ADAPTER)
264 hal_btcoex_Hanlder(padapter);
267 s32 rtw_btcoex_IsBTCoexRejectAMPDU(PADAPTER padapter)
271 coexctrl = hal_btcoex_IsBTCoexRejectAMPDU(padapter);
276 s32 rtw_btcoex_IsBTCoexCtrlAMPDUSize(PADAPTER padapter)
280 coexctrl = hal_btcoex_IsBTCoexCtrlAMPDUSize(padapter);
285 u32 rtw_btcoex_GetAMPDUSize(PADAPTER padapter)
289 size = hal_btcoex_GetAMPDUSize(padapter);
294 void rtw_btcoex_SetManualControl(PADAPTER padapter, u8 manual)
298 hal_btcoex_SetManualControl(padapter, _TRUE);
302 hal_btcoex_SetManualControl(padapter, _FALSE);
306 u8 rtw_btcoex_1Ant(PADAPTER padapter)
308 return hal_btcoex_1Ant(padapter);
311 u8 rtw_btcoex_IsBtControlLps(PADAPTER padapter)
313 return hal_btcoex_IsBtControlLps(padapter);
316 u8 rtw_btcoex_IsLpsOn(PADAPTER padapter)
318 return hal_btcoex_IsLpsOn(padapter);
321 u8 rtw_btcoex_RpwmVal(PADAPTER padapter)
323 return hal_btcoex_RpwmVal(padapter);
326 u8 rtw_btcoex_LpsVal(PADAPTER padapter)
328 return hal_btcoex_LpsVal(padapter);
331 void rtw_btcoex_SetBTCoexist(PADAPTER padapter, u8 bBtExist)
333 hal_btcoex_SetBTCoexist(padapter, bBtExist);
336 void rtw_btcoex_SetChipType(PADAPTER padapter, u8 chipType)
338 hal_btcoex_SetChipType(padapter, chipType);
341 void rtw_btcoex_SetPGAntNum(PADAPTER padapter, u8 antNum)
343 hal_btcoex_SetPgAntNum(padapter, antNum);
346 u8 rtw_btcoex_GetPGAntNum(PADAPTER padapter)
348 return hal_btcoex_GetPgAntNum(padapter);
351 void rtw_btcoex_SetSingleAntPath(PADAPTER padapter, u8 singleAntPath)
353 hal_btcoex_SetSingleAntPath(padapter, singleAntPath);
356 u32 rtw_btcoex_GetRaMask(PADAPTER padapter)
358 return hal_btcoex_GetRaMask(padapter);
361 void rtw_btcoex_RecordPwrMode(PADAPTER padapter, u8 *pCmdBuf, u8 cmdLen)
363 hal_btcoex_RecordPwrMode(padapter, pCmdBuf, cmdLen);
366 void rtw_btcoex_DisplayBtCoexInfo(PADAPTER padapter, u8 *pbuf, u32 bufsize)
368 hal_btcoex_DisplayBtCoexInfo(padapter, pbuf, bufsize);
371 void rtw_btcoex_SetDBG(PADAPTER padapter, u32 *pDbgModule)
373 hal_btcoex_SetDBG(padapter, pDbgModule);
376 u32 rtw_btcoex_GetDBG(PADAPTER padapter, u8 *pStrBuf, u32 bufSize)
378 return hal_btcoex_GetDBG(padapter, pStrBuf, bufSize);
381 u8 rtw_btcoex_IncreaseScanDeviceNum(PADAPTER padapter)
383 return hal_btcoex_IncreaseScanDeviceNum(padapter);
386 u8 rtw_btcoex_IsBtLinkExist(PADAPTER padapter)
388 return hal_btcoex_IsBtLinkExist(padapter);
391 void rtw_btcoex_SetBtPatchVersion(PADAPTER padapter,u16 btHciVer, u16 btPatchVer)
393 hal_btcoex_SetBtPatchVersion(padapter,btHciVer,btPatchVer);
396 void rtw_btcoex_SetHciVersion(PADAPTER padapter, u16 hciVersion)
398 hal_btcoex_SetHciVersion(padapter, hciVersion);
401 void rtw_btcoex_StackUpdateProfileInfo(void)
403 hal_btcoex_StackUpdateProfileInfo();
406 // ==================================================
407 // Below Functions are called by BT-Coex
408 // ==================================================
409 void rtw_btcoex_rx_ampdu_apply(PADAPTER padapter)
411 rtw_rx_ampdu_apply(padapter);
414 void rtw_btcoex_LPS_Enter(PADAPTER padapter)
416 struct pwrctrl_priv *pwrpriv;
420 pwrpriv = adapter_to_pwrctl(padapter);
422 pwrpriv->bpower_saving = _TRUE;
423 lpsVal = rtw_btcoex_LpsVal(padapter);
424 rtw_set_ps_mode(padapter, PS_MODE_MIN, 0, lpsVal, "BTCOEX");
427 void rtw_btcoex_LPS_Leave(PADAPTER padapter)
429 struct pwrctrl_priv *pwrpriv;
432 pwrpriv = adapter_to_pwrctl(padapter);
434 if (pwrpriv->pwr_mode != PS_MODE_ACTIVE)
436 rtw_set_ps_mode(padapter, PS_MODE_ACTIVE, 0, 0, "BTCOEX");
437 LPS_RF_ON_check(padapter, 100);
438 pwrpriv->bpower_saving = _FALSE;
443 // ==================================================
444 // Below Functions are BT-Coex socket related function
445 // ==================================================
447 #ifdef CONFIG_BT_COEXIST_SOCKET_TRX
448 _adapter *pbtcoexadapter = NULL;
449 u8 rtw_btcoex_btinfo_cmd(_adapter *adapter, u8 *buf, u16 len)
451 struct cmd_obj *ph2c;
452 struct drvextra_cmd_parm *pdrvextra_cmd_parm;
454 struct cmd_priv *pcmdpriv = &adapter->cmdpriv;
457 ph2c = (struct cmd_obj*)rtw_zmalloc(sizeof(struct cmd_obj));
463 pdrvextra_cmd_parm = (struct drvextra_cmd_parm*)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));
464 if (pdrvextra_cmd_parm == NULL) {
465 rtw_mfree((u8*)ph2c, sizeof(struct cmd_obj));
470 btinfo = rtw_zmalloc(len);
471 if (btinfo == NULL) {
472 rtw_mfree((u8*)ph2c, sizeof(struct cmd_obj));
473 rtw_mfree((u8*)pdrvextra_cmd_parm, sizeof(struct drvextra_cmd_parm));
478 pdrvextra_cmd_parm->ec_id = BTINFO_WK_CID;
479 pdrvextra_cmd_parm->type = 0;
480 pdrvextra_cmd_parm->size = len;
481 pdrvextra_cmd_parm->pbuf = btinfo;
483 _rtw_memcpy(btinfo, buf, len);
485 init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
487 res = rtw_enqueue_cmd(pcmdpriv, ph2c);
493 u8 rtw_btcoex_send_event_to_BT(_adapter *padapter, u8 status, u8 event_code, u8 opcode_low, u8 opcode_high,u8 *dbg_msg)
497 u8 len=0,tx_event_length = 0;
498 rtw_HCI_event *pEvent;
500 pEvent = (rtw_HCI_event*)(&localBuf[0]);
502 pEvent->EventCode = event_code;
503 pEvent->Data[0] = 0x1; //packet #
504 pEvent->Data[1] = opcode_low;
505 pEvent->Data[2] = opcode_high;
508 // Return parameters starts from here
509 pRetPar = &pEvent->Data[len];
510 pRetPar[0] = status; //status
513 pEvent->Length = len;
515 //total tx event length + EventCode length + sizeof(length)
516 tx_event_length = pEvent->Length + 2;
518 rtw_btcoex_dump_tx_msg((u8 *)pEvent, tx_event_length, dbg_msg);
520 status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
528 Host Controller Interface for
529 Bluetooth 3.0 + HS V1.4 2013/02/07
531 Window team code & BT team code
535 u8 rtw_btcoex_parse_BT_info_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)
537 #define BT_INFO_LENGTH 8
539 u8 curPollEnable = pcmd[0];
540 u8 curPollTime = pcmd[1];
541 u8 btInfoReason = pcmd[2];
542 u8 btInfoLen = pcmd[3];
543 u8 btinfo[BT_INFO_LENGTH];
547 u8 len=0,tx_event_length = 0;
548 RTW_HCI_STATUS status = HCI_STATUS_SUCCESS;
549 rtw_HCI_event *pEvent;
551 DBG_871X("%s\n",__func__);
552 DBG_871X("current Poll Enable: %d, currrent Poll Time: %d\n",curPollEnable,curPollTime);
553 DBG_871X("BT Info reason: %d, BT Info length: %d\n",btInfoReason,btInfoLen);
554 /*DBG_871X("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n"
555 ,pcmd[4],pcmd[5],pcmd[6],pcmd[7],pcmd[8],pcmd[9],pcmd[10],pcmd[11]);*/
557 _rtw_memset(btinfo, 0, BT_INFO_LENGTH);
560 if(BT_INFO_LENGTH != btInfoLen)
562 status = HCI_STATUS_INVALID_HCI_CMD_PARA_VALUE;
563 DBG_871X("Error BT Info Length: %d\n",btInfoLen);
569 if(0x1 == btInfoReason || 0x2 == btInfoReason)
571 _rtw_memcpy(btinfo, &pcmd[4], btInfoLen);
572 btinfo[0] = btInfoReason;
573 rtw_btcoex_btinfo_cmd(padapter,btinfo,btInfoLen);
577 DBG_871X("Other BT info reason\n");
581 //send complete event to BT
584 pEvent = (rtw_HCI_event*)(&localBuf[0]);
586 pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;
587 pEvent->Data[0] = 0x1; //packet #
588 pEvent->Data[1] = HCIOPCODELOW(HCI_BT_INFO_NOTIFY, OGF_EXTENSION);
589 pEvent->Data[2] = HCIOPCODEHIGHT(HCI_BT_INFO_NOTIFY, OGF_EXTENSION);
592 // Return parameters starts from here
593 pRetPar = &pEvent->Data[len];
594 pRetPar[0] = status; //status
597 pEvent->Length = len;
599 //total tx event length + EventCode length + sizeof(length)
600 tx_event_length = pEvent->Length + 2;
602 rtw_btcoex_dump_tx_msg((u8 *)pEvent, tx_event_length,"BT_info_event");
604 status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
607 //bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2);
611 u8 rtw_btcoex_parse_BT_patch_ver_info_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)
613 RTW_HCI_STATUS status=HCI_STATUS_SUCCESS;
614 u16 btPatchVer=0x0, btHciVer=0x0;
619 u8 len=0, tx_event_length =0;
620 rtw_HCI_event *pEvent;
622 btHciVer = pcmd[0] | pcmd[1]<<8;
623 btPatchVer = pcmd[2] | pcmd[3]<<8;
626 DBG_871X("%s, cmd:%02x %02x %02x %02x\n",__func__, pcmd[0] ,pcmd[1] ,pcmd[2] ,pcmd[3]);
627 DBG_871X("%s, HCI Ver:%d, Patch Ver:%d\n",__func__, btHciVer,btPatchVer);
629 rtw_btcoex_SetBtPatchVersion(padapter,btHciVer,btPatchVer);
632 //send complete event to BT
634 pEvent = (rtw_HCI_event *)(&localBuf[0]);
637 pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;
638 pEvent->Data[0] = 0x1; //packet #
639 pEvent->Data[1] = HCIOPCODELOW(HCI_BT_PATCH_VERSION_NOTIFY, OGF_EXTENSION);
640 pEvent->Data[2] = HCIOPCODEHIGHT(HCI_BT_PATCH_VERSION_NOTIFY, OGF_EXTENSION);
643 // Return parameters starts from here
644 pRetPar = &pEvent->Data[len];
645 pRetPar[0] = status; //status
648 pEvent->Length = len;
650 //total tx event length + EventCode length + sizeof(length)
651 tx_event_length = pEvent->Length + 2;
653 rtw_btcoex_dump_tx_msg((u8 *)pEvent, tx_event_length,"BT_patch_event");
655 status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
657 //bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2);
661 u8 rtw_btcoex_parse_HCI_Ver_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)
663 RTW_HCI_STATUS status=HCI_STATUS_SUCCESS;
664 u16 hciver = pcmd[0] | pcmd[1] <<8;
668 u8 len=0, tx_event_length =0;
669 rtw_HCI_event *pEvent;
671 struct bt_coex_info *pcoex_info = &padapter->coex_info;
672 PBT_MGNT pBtMgnt=&pcoex_info->BtMgnt;
673 pBtMgnt->ExtConfig.HCIExtensionVer = hciver;
674 DBG_871X("%s, HCI Version: %d\n",__func__,pBtMgnt->ExtConfig.HCIExtensionVer);
675 if(pBtMgnt->ExtConfig.HCIExtensionVer < 4)
677 status = HCI_STATUS_INVALID_HCI_CMD_PARA_VALUE;
678 DBG_871X("%s, Version = %d, HCI Version < 4\n",__func__,pBtMgnt->ExtConfig.HCIExtensionVer );
682 rtw_btcoex_SetHciVersion(padapter,hciver);
684 //send complete event to BT
686 pEvent = (rtw_HCI_event *)(&localBuf[0]);
689 pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;
690 pEvent->Data[0] = 0x1; //packet #
691 pEvent->Data[1] = HCIOPCODELOW(HCI_EXTENSION_VERSION_NOTIFY, OGF_EXTENSION);
692 pEvent->Data[2] = HCIOPCODEHIGHT(HCI_EXTENSION_VERSION_NOTIFY, OGF_EXTENSION);
695 // Return parameters starts from here
696 pRetPar = &pEvent->Data[len];
697 pRetPar[0] = status; //status
700 pEvent->Length = len;
702 //total tx event length + EventCode length + sizeof(length)
703 tx_event_length = pEvent->Length + 2;
705 status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
707 //bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2);
712 u8 rtw_btcoex_parse_WIFI_scan_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)
714 RTW_HCI_STATUS status=HCI_STATUS_SUCCESS;
718 u8 len=0, tx_event_length =0;
719 rtw_HCI_event *pEvent;
721 struct bt_coex_info *pcoex_info = &padapter->coex_info;
722 PBT_MGNT pBtMgnt=&pcoex_info->BtMgnt;
723 pBtMgnt->ExtConfig.bEnableWifiScanNotify= pcmd[0];
724 DBG_871X("%s, bEnableWifiScanNotify: %d\n",__func__,pBtMgnt->ExtConfig.bEnableWifiScanNotify);
726 //send complete event to BT
728 pEvent = (rtw_HCI_event *)(&localBuf[0]);
731 pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;
732 pEvent->Data[0] = 0x1; //packet #
733 pEvent->Data[1] = HCIOPCODELOW(HCI_ENABLE_WIFI_SCAN_NOTIFY, OGF_EXTENSION);
734 pEvent->Data[2] = HCIOPCODEHIGHT(HCI_ENABLE_WIFI_SCAN_NOTIFY, OGF_EXTENSION);
737 // Return parameters starts from here
738 pRetPar = &pEvent->Data[len];
739 pRetPar[0] = status; //status
742 pEvent->Length = len;
744 //total tx event length + EventCode length + sizeof(length)
745 tx_event_length = pEvent->Length + 2;
747 status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
749 //bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2);
753 u8 rtw_btcoex_parse_HCI_link_status_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)
755 RTW_HCI_STATUS status=HCI_STATUS_SUCCESS;
756 struct bt_coex_info *pcoex_info=&padapter->coex_info;
757 PBT_MGNT pBtMgnt=&pcoex_info->BtMgnt;
758 //PBT_DBG pBtDbg=&padapter->MgntInfo.BtInfo.BtDbg;
759 u8 i, numOfHandle=0, numOfAcl=0;
761 u8 btProfile, btCoreSpec, linkRole;
766 u8 len=0, tx_event_length =0;
767 rtw_HCI_event *pEvent;
769 //pBtDbg->dbgHciInfo.hciCmdCntLinkStatusNotify++;
770 //RT_DISP_DATA(FIOCTL, IOCTL_BT_HCICMD_EXT, "LinkStatusNotify, Hex Data :\n",
771 // &pHciCmd->Data[0], pHciCmd->Length);
773 DBG_871X("BTLinkStatusNotify\n");
775 // Current only RTL8723 support this command.
776 //pBtMgnt->bSupportProfile = TRUE;
777 pBtMgnt->bSupportProfile = _FALSE;
779 pBtMgnt->ExtConfig.NumberOfACL = 0;
780 pBtMgnt->ExtConfig.NumberOfSCO = 0;
782 numOfHandle = pcmd[0];
783 //RT_DISP(FIOCTL, IOCTL_BT_HCICMD_EXT, ("numOfHandle = 0x%x\n", numOfHandle));
784 //RT_DISP(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCIExtensionVer = %d\n", pBtMgnt->ExtConfig.HCIExtensionVer));
785 DBG_871X("numOfHandle = 0x%x\n", numOfHandle);
786 DBG_871X("HCIExtensionVer = %d\n", pBtMgnt->ExtConfig.HCIExtensionVer);
789 for(i=0; i<numOfHandle; i++)
791 if(pBtMgnt->ExtConfig.HCIExtensionVer < 1)
793 conHandle = *((u8 *)&pTriple[0]);
794 btProfile = pTriple[2];
795 btCoreSpec = pTriple[3];
796 if(BT_PROFILE_SCO == btProfile)
798 pBtMgnt->ExtConfig.NumberOfSCO++;
802 pBtMgnt->ExtConfig.NumberOfACL++;
803 pBtMgnt->ExtConfig.aclLink[i].ConnectHandle = conHandle;
804 pBtMgnt->ExtConfig.aclLink[i].BTProfile = btProfile;
805 pBtMgnt->ExtConfig.aclLink[i].BTCoreSpec = btCoreSpec;
807 //RT_DISP(FIOCTL, IOCTL_BT_HCICMD_EXT,
808 // ("Connection_Handle=0x%x, BTProfile=%d, BTSpec=%d\n",
809 // conHandle, btProfile, btCoreSpec));
810 DBG_871X("Connection_Handle=0x%x, BTProfile=%d, BTSpec=%d\n", conHandle, btProfile, btCoreSpec);
813 else if(pBtMgnt->ExtConfig.HCIExtensionVer >= 1)
815 conHandle = *((pu2Byte)&pTriple[0]);
816 btProfile = pTriple[2];
817 btCoreSpec = pTriple[3];
818 linkRole = pTriple[4];
819 if(BT_PROFILE_SCO == btProfile)
821 pBtMgnt->ExtConfig.NumberOfSCO++;
825 pBtMgnt->ExtConfig.NumberOfACL++;
826 pBtMgnt->ExtConfig.aclLink[i].ConnectHandle = conHandle;
827 pBtMgnt->ExtConfig.aclLink[i].BTProfile = btProfile;
828 pBtMgnt->ExtConfig.aclLink[i].BTCoreSpec = btCoreSpec;
829 pBtMgnt->ExtConfig.aclLink[i].linkRole = linkRole;
831 //RT_DISP(FIOCTL, IOCTL_BT_HCICMD_EXT,
832 DBG_871X("Connection_Handle=0x%x, BTProfile=%d, BTSpec=%d, LinkRole=%d\n",
833 conHandle, btProfile, btCoreSpec, linkRole);
837 rtw_btcoex_StackUpdateProfileInfo();
839 //send complete event to BT
841 pEvent = (rtw_HCI_event *)(&localBuf[0]);
844 pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;
845 pEvent->Data[0] = 0x1; //packet #
846 pEvent->Data[1] = HCIOPCODELOW(HCI_LINK_STATUS_NOTIFY, OGF_EXTENSION);
847 pEvent->Data[2] = HCIOPCODEHIGHT(HCI_LINK_STATUS_NOTIFY, OGF_EXTENSION);
850 // Return parameters starts from here
851 pRetPar = &pEvent->Data[len];
852 pRetPar[0] = status; //status
855 pEvent->Length = len;
857 //total tx event length + EventCode length + sizeof(length)
858 tx_event_length = pEvent->Length + 2;
860 status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
862 //bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2);
868 u8 rtw_btcoex_parse_HCI_BT_coex_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)
872 u8 len=0, tx_event_length =0;
873 rtw_HCI_event *pEvent;
874 RTW_HCI_STATUS status=HCI_STATUS_SUCCESS;
877 pEvent = (rtw_HCI_event *)(&localBuf[0]);
880 pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;
881 pEvent->Data[0] = 0x1; //packet #
882 pEvent->Data[1] = HCIOPCODELOW(HCI_BT_COEX_NOTIFY, OGF_EXTENSION);
883 pEvent->Data[2] = HCIOPCODEHIGHT(HCI_BT_COEX_NOTIFY, OGF_EXTENSION);
886 // Return parameters starts from here
887 pRetPar = &pEvent->Data[len];
888 pRetPar[0] = status; //status
891 pEvent->Length = len;
893 //total tx event length + EventCode length + sizeof(length)
894 tx_event_length = pEvent->Length + 2;
896 status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
898 //bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2);
902 u8 rtw_btcoex_parse_HCI_BT_operation_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)
906 u8 len=0, tx_event_length =0;
907 rtw_HCI_event *pEvent;
908 RTW_HCI_STATUS status=HCI_STATUS_SUCCESS;
910 DBG_871X("%s, OP code: %d\n",__func__,pcmd[0]);
915 DBG_871X("[bt operation] : Operation None!!\n");
917 case HCI_BT_OP_INQUIRY_START:
918 DBG_871X("[bt operation] : Inquiry start!!\n");
920 case HCI_BT_OP_INQUIRY_FINISH:
921 DBG_871X("[bt operation] : Inquiry finished!!\n");
923 case HCI_BT_OP_PAGING_START:
924 DBG_871X("[bt operation] : Paging is started!!\n");
926 case HCI_BT_OP_PAGING_SUCCESS:
927 DBG_871X("[bt operation] : Paging complete successfully!!\n");
929 case HCI_BT_OP_PAGING_UNSUCCESS:
930 DBG_871X("[bt operation] : Paging complete unsuccessfully!!\n");
932 case HCI_BT_OP_PAIRING_START:
933 DBG_871X("[bt operation] : Pairing start!!\n");
935 case HCI_BT_OP_PAIRING_FINISH:
936 DBG_871X("[bt operation] : Pairing finished!!\n");
938 case HCI_BT_OP_BT_DEV_ENABLE:
939 DBG_871X("[bt operation] : BT Device is enabled!!\n");
941 case HCI_BT_OP_BT_DEV_DISABLE:
942 DBG_871X("[bt operation] : BT Device is disabled!!\n");
945 DBG_871X("[bt operation] : Unknown, error!!\n");
949 //send complete event to BT
951 pEvent = (rtw_HCI_event *)(&localBuf[0]);
954 pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;
955 pEvent->Data[0] = 0x1; //packet #
956 pEvent->Data[1] = HCIOPCODELOW(HCI_BT_OPERATION_NOTIFY, OGF_EXTENSION);
957 pEvent->Data[2] = HCIOPCODEHIGHT(HCI_BT_OPERATION_NOTIFY, OGF_EXTENSION);
960 // Return parameters starts from here
961 pRetPar = &pEvent->Data[len];
962 pRetPar[0] = status; //status
965 pEvent->Length = len;
967 //total tx event length + EventCode length + sizeof(length)
968 tx_event_length = pEvent->Length + 2;
970 status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
972 //bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2);
976 u8 rtw_btcoex_parse_BT_AFH_MAP_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)
980 u8 len=0, tx_event_length =0;
981 rtw_HCI_event *pEvent;
982 RTW_HCI_STATUS status=HCI_STATUS_SUCCESS;
985 pEvent = (rtw_HCI_event *)(&localBuf[0]);
988 pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;
989 pEvent->Data[0] = 0x1; //packet #
990 pEvent->Data[1] = HCIOPCODELOW(HCI_BT_AFH_MAP_NOTIFY, OGF_EXTENSION);
991 pEvent->Data[2] = HCIOPCODEHIGHT(HCI_BT_AFH_MAP_NOTIFY, OGF_EXTENSION);
994 // Return parameters starts from here
995 pRetPar = &pEvent->Data[len];
996 pRetPar[0] = status; //status
999 pEvent->Length = len;
1001 //total tx event length + EventCode length + sizeof(length)
1002 tx_event_length = pEvent->Length + 2;
1004 status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
1006 //bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2);
1010 u8 rtw_btcoex_parse_BT_register_val_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)
1013 u8 localBuf[6] = "";
1015 u8 len=0, tx_event_length =0;
1016 rtw_HCI_event *pEvent;
1017 RTW_HCI_STATUS status=HCI_STATUS_SUCCESS;
1020 pEvent = (rtw_HCI_event *)(&localBuf[0]);
1023 pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;
1024 pEvent->Data[0] = 0x1; //packet #
1025 pEvent->Data[1] = HCIOPCODELOW(HCI_BT_REGISTER_VALUE_NOTIFY, OGF_EXTENSION);
1026 pEvent->Data[2] = HCIOPCODEHIGHT(HCI_BT_REGISTER_VALUE_NOTIFY, OGF_EXTENSION);
1029 // Return parameters starts from here
1030 pRetPar = &pEvent->Data[len];
1031 pRetPar[0] = status; //status
1034 pEvent->Length = len;
1036 //total tx event length + EventCode length + sizeof(length)
1037 tx_event_length = pEvent->Length + 2;
1039 status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
1041 //bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2);
1045 u8 rtw_btcoex_parse_HCI_BT_abnormal_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)
1047 u8 localBuf[6] = "";
1049 u8 len=0, tx_event_length =0;
1050 rtw_HCI_event *pEvent;
1051 RTW_HCI_STATUS status=HCI_STATUS_SUCCESS;
1054 pEvent = (rtw_HCI_event *)(&localBuf[0]);
1057 pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;
1058 pEvent->Data[0] = 0x1; //packet #
1059 pEvent->Data[1] = HCIOPCODELOW(HCI_BT_ABNORMAL_NOTIFY, OGF_EXTENSION);
1060 pEvent->Data[2] = HCIOPCODEHIGHT(HCI_BT_ABNORMAL_NOTIFY, OGF_EXTENSION);
1063 // Return parameters starts from here
1064 pRetPar = &pEvent->Data[len];
1065 pRetPar[0] = status; //status
1068 pEvent->Length = len;
1070 //total tx event length + EventCode length + sizeof(length)
1071 tx_event_length = pEvent->Length + 2;
1073 status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
1075 //bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2);
1079 u8 rtw_btcoex_parse_HCI_query_RF_status_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)
1081 u8 localBuf[6] = "";
1083 u8 len=0, tx_event_length =0;
1084 rtw_HCI_event *pEvent;
1085 RTW_HCI_STATUS status=HCI_STATUS_SUCCESS;
1088 pEvent = (rtw_HCI_event *)(&localBuf[0]);
1091 pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;
1092 pEvent->Data[0] = 0x1; //packet #
1093 pEvent->Data[1] = HCIOPCODELOW(HCI_QUERY_RF_STATUS, OGF_EXTENSION);
1094 pEvent->Data[2] = HCIOPCODEHIGHT(HCI_QUERY_RF_STATUS, OGF_EXTENSION);
1097 // Return parameters starts from here
1098 pRetPar = &pEvent->Data[len];
1099 pRetPar[0] = status; //status
1102 pEvent->Length = len;
1104 //total tx event length + EventCode length + sizeof(length)
1105 tx_event_length = pEvent->Length + 2;
1107 status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
1109 //bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2);
1113 /*****************************************
1116 *| OPcode (OCF|OGF<<10) |
1118 *|Cmd para |Cmd para Length |
1120 ******************************************/
1122 //bit 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
1124 void rtw_btcoex_parse_hci_extend_cmd(_adapter *padapter, u8 *pcmd, u16 len,const u16 hci_OCF)
1127 DBG_871X("%s: OCF: %x\n",__func__,hci_OCF);
1130 case HCI_EXTENSION_VERSION_NOTIFY:
1131 DBG_871X("HCI_EXTENSION_VERSION_NOTIFY\n");
1132 rtw_btcoex_parse_HCI_Ver_notify_cmd(padapter,pcmd, len);
1134 case HCI_LINK_STATUS_NOTIFY:
1135 DBG_871X("HCI_LINK_STATUS_NOTIFY\n");
1136 rtw_btcoex_parse_HCI_link_status_notify_cmd(padapter,pcmd, len);
1138 case HCI_BT_OPERATION_NOTIFY:
1139 // only for 8723a 2ant
1140 DBG_871X("HCI_BT_OPERATION_NOTIFY\n");
1141 rtw_btcoex_parse_HCI_BT_operation_notify_cmd(padapter,pcmd, len);
1144 case HCI_ENABLE_WIFI_SCAN_NOTIFY:
1145 DBG_871X("HCI_ENABLE_WIFI_SCAN_NOTIFY\n");
1146 rtw_btcoex_parse_WIFI_scan_notify_cmd(padapter,pcmd, len);
1148 case HCI_QUERY_RF_STATUS:
1149 // only for 8723b 2ant
1150 DBG_871X("HCI_QUERY_RF_STATUS\n");
1151 rtw_btcoex_parse_HCI_query_RF_status_cmd(padapter,pcmd, len);
1153 case HCI_BT_ABNORMAL_NOTIFY:
1154 DBG_871X("HCI_BT_ABNORMAL_NOTIFY\n");
1155 rtw_btcoex_parse_HCI_BT_abnormal_notify_cmd(padapter,pcmd, len);
1157 case HCI_BT_INFO_NOTIFY:
1158 DBG_871X("HCI_BT_INFO_NOTIFY\n");
1159 rtw_btcoex_parse_BT_info_notify_cmd(padapter,pcmd, len);
1161 case HCI_BT_COEX_NOTIFY:
1162 DBG_871X("HCI_BT_COEX_NOTIFY\n");
1163 rtw_btcoex_parse_HCI_BT_coex_notify_cmd(padapter,pcmd, len);
1165 case HCI_BT_PATCH_VERSION_NOTIFY:
1166 DBG_871X("HCI_BT_PATCH_VERSION_NOTIFY\n");
1167 rtw_btcoex_parse_BT_patch_ver_info_cmd(padapter,pcmd, len);
1169 case HCI_BT_AFH_MAP_NOTIFY:
1170 DBG_871X("HCI_BT_AFH_MAP_NOTIFY\n");
1171 rtw_btcoex_parse_BT_AFH_MAP_notify_cmd(padapter,pcmd, len);
1173 case HCI_BT_REGISTER_VALUE_NOTIFY:
1174 DBG_871X("HCI_BT_REGISTER_VALUE_NOTIFY\n");
1175 rtw_btcoex_parse_BT_register_val_notify_cmd(padapter,pcmd, len);
1178 DBG_871X("ERROR!!! Unknown OCF: %x\n",hci_OCF);
1184 void rtw_btcoex_parse_hci_cmd(_adapter *padapter, u8 *pcmd, u16 len)
1186 u16 opcode = pcmd[0] | pcmd[1]<<8;
1187 u16 hci_OGF = HCI_OGF(opcode);
1188 u16 hci_OCF = HCI_OCF(opcode);
1190 u8 pare_len = pcmd[2];
1192 DBG_871X("%s\n",__func__);
1193 DBG_871X("OGF: %x,OCF: %x\n",hci_OGF,hci_OCF);
1197 DBG_871X("HCI_EXTENSION_CMD_OGF\n");
1198 rtw_btcoex_parse_hci_extend_cmd(padapter, &pcmd[3], cmdlen, hci_OCF);
1201 DBG_871X("Other OGF: %x\n",hci_OGF);
1206 u16 rtw_btcoex_parse_recv_data(u8 *msg, u8 msg_size)
1208 u8 cmp_msg1[32] = attend_ack;
1209 u8 cmp_msg2[32] = leave_ack;
1210 u8 cmp_msg3[32] = bt_leave;
1211 u8 cmp_msg4[32] = invite_req;
1212 u8 cmp_msg5[32] = attend_req;
1213 u8 cmp_msg6[32] = invite_rsp;
1216 if (_rtw_memcmp(cmp_msg1, msg, msg_size) == _TRUE) {
1217 /*DBG_871X("%s, msg:%s\n",__func__,msg);*/
1218 res = RX_ATTEND_ACK;
1219 } else if (_rtw_memcmp(cmp_msg2, msg, msg_size) == _TRUE) {
1220 /*DBG_871X("%s, msg:%s\n",__func__,msg);*/
1222 } else if (_rtw_memcmp(cmp_msg3, msg, msg_size) == _TRUE) {
1223 /*DBG_871X("%s, msg:%s\n",__func__,msg);*/
1225 } else if (_rtw_memcmp(cmp_msg4, msg, msg_size) == _TRUE) {
1226 /*DBG_871X("%s, msg:%s\n",__func__,msg);*/
1227 res = RX_INVITE_REQ;
1228 } else if (_rtw_memcmp(cmp_msg5, msg, msg_size) == _TRUE) {
1229 res = RX_ATTEND_REQ;
1230 } else if (_rtw_memcmp(cmp_msg6, msg, msg_size) == _TRUE) {
1231 res = RX_INVITE_RSP;
1233 DBG_871X("%s, %s\n", __func__, msg);
1237 DBG_871X("%s, res:%d\n", __func__, res);
1242 void rtw_btcoex_recvmsgbysocket(void *data)
1245 u8 tx_msg[255] = leave_ack;
1248 u16 recv_length = 0;
1251 u8 para_len = 0, polling_enable = 0, poling_interval = 0, reason = 0, btinfo_len = 0;
1252 u8 btinfo[BT_INFO_LEN] = {0};
1255 struct bt_coex_info *pcoex_info = NULL;
1256 struct sock *sk = NULL;
1257 struct sk_buff *skb = NULL;
1259 DBG_871X("%s\n",__func__);
1261 if (pbtcoexadapter == NULL) {
1262 DBG_871X("%s: btcoexadapter NULL!\n", __func__);
1266 pcoex_info = &pbtcoexadapter->coex_info;
1267 sk = pcoex_info->sk_store;
1270 DBG_871X("%s: critical error when receive socket data!\n", __func__);
1274 len = skb_queue_len(&sk->sk_receive_queue);
1276 skb = skb_dequeue(&sk->sk_receive_queue);
1278 /*important: cut the udp header from skb->data! header length is 8 byte*/
1279 recv_length = skb->len-8;
1280 _rtw_memset(recv_data, 0, sizeof(recv_data));
1281 _rtw_memcpy(recv_data, skb->data+8, recv_length);
1283 parse_res = rtw_btcoex_parse_recv_data(recv_data, recv_length);
1285 if (RX_ATTEND_ACK == parse_res) {
1287 pcoex_info->BT_attend = _TRUE;
1288 DBG_871X("RX_ATTEND_ACK!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);
1289 } else if (RX_ATTEND_REQ == parse_res) {
1290 //attend req from BT
1291 pcoex_info->BT_attend = _TRUE;
1292 DBG_871X("RX_BT_ATTEND_REQ!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);
1293 rtw_btcoex_sendmsgbysocket(pbtcoexadapter, attend_ack, sizeof(attend_ack), _FALSE);
1294 } else if (RX_INVITE_REQ == parse_res) {
1295 //invite req from BT
1296 pcoex_info->BT_attend = _TRUE;
1297 DBG_871X("RX_INVITE_REQ!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);
1298 rtw_btcoex_sendmsgbysocket(pbtcoexadapter, invite_rsp, sizeof(invite_rsp), _FALSE);
1299 } else if (RX_INVITE_RSP == parse_res) {
1301 pcoex_info->BT_attend = _TRUE;
1302 DBG_871X("RX_INVITE_RSP!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);
1303 } else if (RX_LEAVE_ACK == parse_res) {
1304 //mean BT know wifi will leave
1305 pcoex_info->BT_attend = _FALSE;
1306 DBG_871X("RX_LEAVE_ACK!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);
1307 } else if (RX_BT_LEAVE == parse_res) {
1309 rtw_btcoex_sendmsgbysocket(pbtcoexadapter, leave_ack, sizeof(leave_ack), _FALSE); // no ack
1310 pcoex_info->BT_attend = _FALSE;
1311 DBG_871X("RX_BT_LEAVE!sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);
1313 //todo: check if recv data are really hci cmds
1314 if (_TRUE == pcoex_info->BT_attend)
1315 rtw_btcoex_parse_hci_cmd(pbtcoexadapter, recv_data, recv_length);
1318 switch (parse_res) {
1321 pcoex_info->BT_attend = _TRUE;
1322 DBG_871X("RX_ATTEND_ACK!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);
1326 pcoex_info->BT_attend = _TRUE;
1327 DBG_871X("RX_BT_ATTEND_REQ!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);
1328 rtw_btcoex_sendmsgbysocket(pbtcoexadapter, attend_ack, sizeof(attend_ack), _FALSE);
1332 /* invite req from BT */
1333 pcoex_info->BT_attend = _TRUE;
1334 DBG_871X("RX_INVITE_REQ!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);
1335 rtw_btcoex_sendmsgbysocket(pbtcoexadapter, invite_rsp, sizeof(invite_rsp), _FALSE);
1340 pcoex_info->BT_attend = _TRUE;
1341 DBG_871X("RX_INVITE_RSP!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);
1345 /* mean BT know wifi will leave */
1346 pcoex_info->BT_attend = _FALSE;
1347 DBG_871X("RX_LEAVE_ACK!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);
1352 rtw_btcoex_sendmsgbysocket(pbtcoexadapter, leave_ack, sizeof(leave_ack), _FALSE); /* no ack */
1353 pcoex_info->BT_attend = _FALSE;
1354 DBG_871X("RX_BT_LEAVE!sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);
1358 if (_TRUE == pcoex_info->BT_attend)
1359 rtw_btcoex_parse_hci_cmd(pbtcoexadapter, recv_data, recv_length);
1361 DBG_871X("ERROR!! BT is UP\n");
1371 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 15, 0))
1372 void rtw_btcoex_recvmsg_init(struct sock *sk_in, s32 bytes)
1374 void rtw_btcoex_recvmsg_init(struct sock *sk_in)
1377 struct bt_coex_info *pcoex_info = NULL;
1379 if (pbtcoexadapter == NULL) {
1380 DBG_871X("%s: btcoexadapter NULL\n", __func__);
1383 pcoex_info = &pbtcoexadapter->coex_info;
1384 pcoex_info->sk_store = sk_in;
1385 if (pcoex_info->btcoex_wq != NULL)
1386 queue_delayed_work(pcoex_info->btcoex_wq, &pcoex_info->recvmsg_work, 0);
1388 DBG_871X("%s: BTCOEX workqueue NULL\n", __func__);
1391 u8 rtw_btcoex_sendmsgbysocket(_adapter *padapter, u8 *msg, u8 msg_size, bool force)
1394 struct msghdr udpmsg;
1397 struct bt_coex_info *pcoex_info = &padapter->coex_info;
1399 DBG_871X("%s: msg:%s, force:%s\n", __func__, msg, force == _TRUE?"TRUE":"FALSE");
1400 if (_FALSE == force) {
1401 if (_FALSE == pcoex_info->BT_attend) {
1402 DBG_871X("TX Blocked: WiFi-BT disconnected\n");
1407 iov.iov_base = (void *)msg;
1408 iov.iov_len = msg_size;
1409 udpmsg.msg_name = &pcoex_info->bt_sockaddr;
1410 udpmsg.msg_namelen = sizeof(struct sockaddr_in);
1411 udpmsg.msg_iov = &iov;
1412 udpmsg.msg_iovlen = 1;
1413 udpmsg.msg_control = NULL;
1414 udpmsg.msg_controllen = 0;
1415 udpmsg.msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL;
1418 error = sock_sendmsg(pcoex_info->udpsock, &udpmsg, msg_size);
1421 DBG_871X("Error when sendimg msg, error:%d\n", error);
1427 u8 rtw_btcoex_create_kernel_socket(_adapter *padapter)
1429 s8 kernel_socket_err;
1430 u8 tx_msg[255] = attend_req;
1431 struct bt_coex_info *pcoex_info = &padapter->coex_info;
1435 DBG_871X("%s CONNECT_PORT %d\n", __func__, CONNECT_PORT);
1437 if (NULL == pcoex_info) {
1438 DBG_871X("coex_info: NULL\n");
1442 kernel_socket_err = sock_create(PF_INET, SOCK_DGRAM, 0, &pcoex_info->udpsock);
1444 if (kernel_socket_err < 0) {
1445 DBG_871X("Error during creation of socket error:%d\n", kernel_socket_err);
1448 _rtw_memset(&(pcoex_info->wifi_sockaddr), 0, sizeof(pcoex_info->wifi_sockaddr));
1449 pcoex_info->wifi_sockaddr.sin_family = AF_INET;
1450 pcoex_info->wifi_sockaddr.sin_port = htons(CONNECT_PORT);
1451 pcoex_info->wifi_sockaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1453 _rtw_memset(&(pcoex_info->bt_sockaddr), 0, sizeof(pcoex_info->bt_sockaddr));
1454 pcoex_info->bt_sockaddr.sin_family = AF_INET;
1455 pcoex_info->bt_sockaddr.sin_port = htons(CONNECT_PORT_BT);
1456 pcoex_info->bt_sockaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
1458 pcoex_info->sk_store = NULL;
1459 kernel_socket_err = pcoex_info->udpsock->ops->bind(pcoex_info->udpsock, (struct sockaddr *)&pcoex_info->wifi_sockaddr,
1460 sizeof(pcoex_info->wifi_sockaddr));
1461 if (kernel_socket_err == 0) {
1462 DBG_871X("binding socket success\n");
1463 pcoex_info->udpsock->sk->sk_data_ready = rtw_btcoex_recvmsg_init;
1464 pcoex_info->sock_open |= KERNEL_SOCKET_OK;
1465 pcoex_info->BT_attend = _FALSE;
1466 DBG_871X("WIFI sending attend_req\n");
1467 rtw_btcoex_sendmsgbysocket(padapter, attend_req, sizeof(attend_req), _TRUE);
1470 pcoex_info->BT_attend = _FALSE;
1471 sock_release(pcoex_info->udpsock); /* bind fail release socket */
1472 DBG_871X("Error binding socket: %d\n", kernel_socket_err);
1481 void rtw_btcoex_close_kernel_socket(_adapter *padapter)
1483 struct bt_coex_info *pcoex_info = &padapter->coex_info;
1484 if (pcoex_info->sock_open & KERNEL_SOCKET_OK) {
1485 DBG_871X("release kernel socket\n");
1486 sock_release(pcoex_info->udpsock);
1487 pcoex_info->sock_open &= ~(KERNEL_SOCKET_OK);
1488 if (_TRUE == pcoex_info->BT_attend)
1489 pcoex_info->BT_attend = _FALSE;
1491 DBG_871X("sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);
1495 void rtw_btcoex_init_socket(_adapter *padapter)
1498 u8 is_invite = _FALSE;
1499 struct bt_coex_info *pcoex_info = &padapter->coex_info;
1500 DBG_871X("%s\n", __func__);
1501 if (_FALSE == pcoex_info->is_exist) {
1502 _rtw_memset(pcoex_info,0,sizeof(struct bt_coex_info));
1503 pcoex_info->btcoex_wq = create_workqueue("BTCOEX");
1504 INIT_DELAYED_WORK(&pcoex_info->recvmsg_work,
1505 (void *)rtw_btcoex_recvmsgbysocket);
1506 pbtcoexadapter = padapter;
1507 if (rtw_btcoex_create_kernel_socket(padapter) == _SUCCESS) {
1508 pcoex_info->is_exist = _TRUE;
1510 pcoex_info->is_exist = _FALSE;
1511 pbtcoexadapter = NULL;
1514 DBG_871X("%s: pbtcoexadapter:%p, coex_info->is_exist: %s\n"
1515 , __func__, pbtcoexadapter, pcoex_info->is_exist == _TRUE?"TRUE":"FALSE");
1519 void rtw_btcoex_close_socket(_adapter *padapter)
1521 struct bt_coex_info *pcoex_info = &padapter->coex_info;
1523 DBG_871X("%s--coex_info->is_exist: %s, pcoex_info->BT_attend:%s\n"
1524 , __func__, pcoex_info->is_exist == _TRUE?"TRUE":"FALSE", pcoex_info->BT_attend == _TRUE?"TRUE":"FALSE");
1526 if (_TRUE == pcoex_info->is_exist) {
1527 if (_TRUE == pcoex_info->BT_attend) {
1528 /*inform BT wifi leave*/
1529 rtw_btcoex_sendmsgbysocket(padapter, wifi_leave, sizeof(wifi_leave), _FALSE);
1532 rtw_btcoex_close_kernel_socket(padapter);
1533 pbtcoexadapter = NULL;
1534 pcoex_info->is_exist = _FALSE;
1536 if (pcoex_info->btcoex_wq != NULL) {
1537 flush_workqueue(pcoex_info->btcoex_wq);
1538 destroy_workqueue(pcoex_info->btcoex_wq);
1542 void rtw_btcoex_dump_tx_msg(u8 *tx_msg, u8 len, u8 *msg_name)
1545 DBG_871X("======> Msg name: %s\n", msg_name);
1548 printk("%02x ", tx_msg[i]);
1551 DBG_871X("Msg name: %s <======\n", msg_name);
1554 /* Porting from Windows team */
1555 void rtw_btcoex_SendEventExtBtCoexControl(PADAPTER padapter, u8 bNeedDbgRsp, u8 dataLen, void *pData)
1557 u8 len=0, tx_event_length = 0;
1558 u8 localBuf[32] = "";
1561 u8 *pInBuf=(pu1Byte)pData;
1563 rtw_HCI_event *pEvent;
1567 DBG_871X("%s, OPCode:%02x\n",__func__,opCode);
1569 pEvent = (rtw_HCI_event*)(&localBuf[0]);
1571 //len += bthci_ExtensionEventHeaderRtk(&localBuf[0],
1572 // HCI_EVENT_EXT_BT_COEX_CONTROL);
1573 pEvent->EventCode = HCI_EVENT_EXTENSION_RTK;
1574 pEvent->Data[0] = HCI_EVENT_EXT_BT_COEX_CONTROL; //extension event code
1577 // Return parameters starts from here
1578 pRetPar = &pEvent->Data[len];
1579 _rtw_memcpy(&pRetPar[0], pData, dataLen);
1583 pEvent->Length = len;
1585 //total tx event length + EventCode length + sizeof(length)
1586 tx_event_length = pEvent->Length + 2;
1588 rtw_btcoex_dump_tx_msg((u8 *)pEvent, tx_event_length, "BT COEX CONTROL", _FALSE);
1590 rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
1594 /* Porting from Windows team */
1595 void rtw_btcoex_SendEventExtBtInfoControl(PADAPTER padapter, u8 dataLen, void *pData)
1597 rtw_HCI_event *pEvent;
1599 u8 len=0, tx_event_length = 0;
1600 u8 localBuf[32] = "";
1602 struct bt_coex_info *pcoex_info = &padapter->coex_info;
1603 PBT_MGNT pBtMgnt = &pcoex_info->BtMgnt;
1605 DBG_871X("%s\n",__func__);
1606 if(pBtMgnt->ExtConfig.HCIExtensionVer < 4) //not support
1608 DBG_871X("ERROR: HCIExtensionVer = %d, HCIExtensionVer<4 !!!!\n",pBtMgnt->ExtConfig.HCIExtensionVer);
1612 pEvent = (rtw_HCI_event *)(&localBuf[0]);
1614 //len += bthci_ExtensionEventHeaderRtk(&localBuf[0],
1615 // HCI_EVENT_EXT_BT_INFO_CONTROL);
1616 pEvent->EventCode = HCI_EVENT_EXTENSION_RTK;
1617 pEvent->Data[0] = HCI_EVENT_EXT_BT_INFO_CONTROL; //extension event code
1620 // Return parameters starts from here
1621 pRetPar = &pEvent->Data[len];
1622 _rtw_memcpy(&pRetPar[0], pData, dataLen);
1626 pEvent->Length = len;
1628 //total tx event length + EventCode length + sizeof(length)
1629 tx_event_length = pEvent->Length + 2;
1631 rtw_btcoex_dump_tx_msg((u8 *)pEvent, tx_event_length, "BT INFO CONTROL");
1633 rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
1637 void rtw_btcoex_SendScanNotify(PADAPTER padapter, u8 scanType)
1639 u8 len=0, tx_event_length=0;
1640 u8 localBuf[7] = "";
1643 rtw_HCI_event *pEvent;
1644 struct bt_coex_info *pcoex_info = &padapter->coex_info;
1645 PBT_MGNT pBtMgnt = &pcoex_info->BtMgnt;
1647 // if(!pBtMgnt->BtOperationOn)
1650 pEvent = (rtw_HCI_event *)(&localBuf[0]);
1652 // len += bthci_ExtensionEventHeaderRtk(&localBuf[0],
1653 // HCI_EVENT_EXT_WIFI_SCAN_NOTIFY);
1655 pEvent->EventCode = HCI_EVENT_EXTENSION_RTK;
1656 pEvent->Data[0] = HCI_EVENT_EXT_WIFI_SCAN_NOTIFY; //extension event code
1659 // Return parameters starts from here
1660 //pRetPar = &PPacketIrpEvent->Data[len];
1661 //pu1Temp = (u8 *)&pRetPar[0];
1662 //*pu1Temp = scanType;
1663 pEvent->Data[len] = scanType;
1666 pEvent->Length = len;
1668 //total tx event length + EventCode length + sizeof(length)
1669 tx_event_length = pEvent->Length + 2;
1671 rtw_btcoex_dump_tx_msg((u8 *)pEvent, tx_event_length, "WIFI SCAN OPERATION");
1673 rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
1675 #endif //CONFIG_BT_COEXIST_SOCKET_TRX
1676 #endif // CONFIG_BT_COEXIST