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_PowerOffSetting(PADAPTER padapter)
39 hal_btcoex_PowerOffSetting(padapter);
42 void rtw_btcoex_PreLoadFirmware(PADAPTER padapter)
44 hal_btcoex_PreLoadFirmware(padapter);
47 void rtw_btcoex_HAL_Initialize(PADAPTER padapter, u8 bWifiOnly)
49 hal_btcoex_InitHwConfig(padapter, bWifiOnly);
52 void rtw_btcoex_IpsNotify(PADAPTER padapter, u8 type)
54 PHAL_DATA_TYPE pHalData;
56 pHalData = GET_HAL_DATA(padapter);
57 if (_FALSE == pHalData->EEPROMBluetoothCoexist)
60 hal_btcoex_IpsNotify(padapter, type);
63 void rtw_btcoex_LpsNotify(PADAPTER padapter, u8 type)
65 PHAL_DATA_TYPE pHalData;
67 pHalData = GET_HAL_DATA(padapter);
68 if (_FALSE == pHalData->EEPROMBluetoothCoexist)
71 hal_btcoex_LpsNotify(padapter, type);
74 void rtw_btcoex_ScanNotify(PADAPTER padapter, u8 type)
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 */
82 pHalData = GET_HAL_DATA(padapter);
83 if (_FALSE == pHalData->EEPROMBluetoothCoexist)
87 #ifdef CONFIG_CONCURRENT_MODE
88 if (rtw_mi_buddy_check_fwstate(padapter, WIFI_SITE_MONITOR))
92 if (DEV_MGMT_TX_NUM(adapter_to_dvobj(padapter))
93 || DEV_ROCH_NUM(adapter_to_dvobj(padapter)))
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 */
102 hal_btcoex_ScanNotify(padapter, type);
105 void rtw_btcoex_ConnectNotify(PADAPTER padapter, u8 action)
107 PHAL_DATA_TYPE pHalData;
109 pHalData = GET_HAL_DATA(padapter);
110 if (_FALSE == pHalData->EEPROMBluetoothCoexist)
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));
119 #endif /* DBG_CONFIG_ERROR_RESET */
121 #ifdef CONFIG_CONCURRENT_MODE
122 if (_FALSE == action) {
123 if (rtw_mi_buddy_check_fwstate(padapter, WIFI_UNDER_LINKING))
128 hal_btcoex_ConnectNotify(padapter, action);
131 void rtw_btcoex_MediaStatusNotify(PADAPTER padapter, u8 mediaStatus)
133 PHAL_DATA_TYPE pHalData;
135 pHalData = GET_HAL_DATA(padapter);
136 if (_FALSE == pHalData->EEPROMBluetoothCoexist)
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));
145 #endif /* DBG_CONFIG_ERROR_RESET */
147 #ifdef CONFIG_CONCURRENT_MODE
148 if (RT_MEDIA_DISCONNECT == mediaStatus) {
149 if (rtw_mi_buddy_check_fwstate(padapter, WIFI_ASOC_STATE))
152 #endif /* CONFIG_CONCURRENT_MODE */
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);
158 hal_btcoex_MediaStatusNotify(padapter, mediaStatus);
161 void rtw_btcoex_SpecialPacketNotify(PADAPTER padapter, u8 pktType)
163 PHAL_DATA_TYPE pHalData;
165 pHalData = GET_HAL_DATA(padapter);
166 if (_FALSE == pHalData->EEPROMBluetoothCoexist)
169 hal_btcoex_SpecialPacketNotify(padapter, pktType);
172 void rtw_btcoex_IQKNotify(PADAPTER padapter, u8 state)
174 PHAL_DATA_TYPE pHalData;
176 pHalData = GET_HAL_DATA(padapter);
177 if (_FALSE == pHalData->EEPROMBluetoothCoexist)
180 hal_btcoex_IQKNotify(padapter, state);
183 void rtw_btcoex_BtInfoNotify(PADAPTER padapter, u8 length, u8 *tmpBuf)
185 PHAL_DATA_TYPE pHalData;
187 pHalData = GET_HAL_DATA(padapter);
188 if (_FALSE == pHalData->EEPROMBluetoothCoexist)
191 hal_btcoex_BtInfoNotify(padapter, length, tmpBuf);
194 void rtw_btcoex_BtMpRptNotify(PADAPTER padapter, u8 length, u8 *tmpBuf)
196 PHAL_DATA_TYPE pHalData;
198 pHalData = GET_HAL_DATA(padapter);
199 if (_FALSE == pHalData->EEPROMBluetoothCoexist)
202 if (padapter->registrypriv.mp_mode == 1)
205 hal_btcoex_BtMpRptNotify(padapter, length, tmpBuf);
208 void rtw_btcoex_SuspendNotify(PADAPTER padapter, u8 state)
210 PHAL_DATA_TYPE pHalData;
212 pHalData = GET_HAL_DATA(padapter);
213 if (_FALSE == pHalData->EEPROMBluetoothCoexist)
216 hal_btcoex_SuspendNotify(padapter, state);
219 void rtw_btcoex_HaltNotify(PADAPTER padapter)
221 PHAL_DATA_TYPE pHalData;
224 pHalData = GET_HAL_DATA(padapter);
225 if (_FALSE == pHalData->EEPROMBluetoothCoexist)
228 if (_FALSE == padapter->bup) {
229 RTW_INFO(FUNC_ADPT_FMT ": bup=%d Skip!\n",
230 FUNC_ADPT_ARG(padapter), padapter->bup);
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");
240 hal_btcoex_HaltNotify(padapter, do_halt);
243 void rtw_btcoex_switchband_notify(u8 under_scan, u8 band_type)
245 hal_btcoex_switchband_notify(under_scan, band_type);
248 void rtw_btcoex_SwitchBtTRxMask(PADAPTER padapter)
250 hal_btcoex_SwitchBtTRxMask(padapter);
253 void rtw_btcoex_Switch(PADAPTER padapter, u8 enable)
255 hal_btcoex_SetBTCoexist(padapter, enable);
258 u8 rtw_btcoex_IsBtDisabled(PADAPTER padapter)
260 return hal_btcoex_IsBtDisabled(padapter);
263 void rtw_btcoex_Handler(PADAPTER padapter)
265 PHAL_DATA_TYPE pHalData;
267 pHalData = GET_HAL_DATA(padapter);
269 if (_FALSE == pHalData->EEPROMBluetoothCoexist)
272 hal_btcoex_Hanlder(padapter);
275 s32 rtw_btcoex_IsBTCoexRejectAMPDU(PADAPTER padapter)
279 coexctrl = hal_btcoex_IsBTCoexRejectAMPDU(padapter);
284 s32 rtw_btcoex_IsBTCoexCtrlAMPDUSize(PADAPTER padapter)
288 coexctrl = hal_btcoex_IsBTCoexCtrlAMPDUSize(padapter);
293 u32 rtw_btcoex_GetAMPDUSize(PADAPTER padapter)
297 size = hal_btcoex_GetAMPDUSize(padapter);
302 void rtw_btcoex_SetManualControl(PADAPTER padapter, u8 manual)
305 hal_btcoex_SetManualControl(padapter, _TRUE);
307 hal_btcoex_SetManualControl(padapter, _FALSE);
310 u8 rtw_btcoex_1Ant(PADAPTER padapter)
312 return hal_btcoex_1Ant(padapter);
315 u8 rtw_btcoex_IsBtControlLps(PADAPTER padapter)
317 return hal_btcoex_IsBtControlLps(padapter);
320 u8 rtw_btcoex_IsLpsOn(PADAPTER padapter)
322 return hal_btcoex_IsLpsOn(padapter);
325 u8 rtw_btcoex_RpwmVal(PADAPTER padapter)
327 return hal_btcoex_RpwmVal(padapter);
330 u8 rtw_btcoex_LpsVal(PADAPTER padapter)
332 return hal_btcoex_LpsVal(padapter);
335 u32 rtw_btcoex_GetRaMask(PADAPTER padapter)
337 return hal_btcoex_GetRaMask(padapter);
340 void rtw_btcoex_RecordPwrMode(PADAPTER padapter, u8 *pCmdBuf, u8 cmdLen)
342 hal_btcoex_RecordPwrMode(padapter, pCmdBuf, cmdLen);
345 void rtw_btcoex_DisplayBtCoexInfo(PADAPTER padapter, u8 *pbuf, u32 bufsize)
347 hal_btcoex_DisplayBtCoexInfo(padapter, pbuf, bufsize);
350 void rtw_btcoex_SetDBG(PADAPTER padapter, u32 *pDbgModule)
352 hal_btcoex_SetDBG(padapter, pDbgModule);
355 u32 rtw_btcoex_GetDBG(PADAPTER padapter, u8 *pStrBuf, u32 bufSize)
357 return hal_btcoex_GetDBG(padapter, pStrBuf, bufSize);
360 u8 rtw_btcoex_IncreaseScanDeviceNum(PADAPTER padapter)
362 return hal_btcoex_IncreaseScanDeviceNum(padapter);
365 u8 rtw_btcoex_IsBtLinkExist(PADAPTER padapter)
367 return hal_btcoex_IsBtLinkExist(padapter);
370 void rtw_btcoex_SetBtPatchVersion(PADAPTER padapter, u16 btHciVer, u16 btPatchVer)
372 hal_btcoex_SetBtPatchVersion(padapter, btHciVer, btPatchVer);
375 void rtw_btcoex_SetHciVersion(PADAPTER padapter, u16 hciVersion)
377 hal_btcoex_SetHciVersion(padapter, hciVersion);
380 void rtw_btcoex_StackUpdateProfileInfo(void)
382 hal_btcoex_StackUpdateProfileInfo();
385 void rtw_btcoex_pta_off_on_notify(PADAPTER padapter, u8 bBTON)
387 hal_btcoex_pta_off_on_notify(padapter, bBTON);
390 /* ==================================================
391 * Below Functions are called by BT-Coex
392 * ================================================== */
393 void rtw_btcoex_rx_ampdu_apply(PADAPTER padapter)
395 rtw_rx_ampdu_apply(padapter);
398 void rtw_btcoex_LPS_Enter(PADAPTER padapter)
400 struct pwrctrl_priv *pwrpriv;
404 pwrpriv = adapter_to_pwrctl(padapter);
406 pwrpriv->bpower_saving = _TRUE;
407 lpsVal = rtw_btcoex_LpsVal(padapter);
408 rtw_set_ps_mode(padapter, PS_MODE_MIN, 0, lpsVal, "BTCOEX");
411 void rtw_btcoex_LPS_Leave(PADAPTER padapter)
413 struct pwrctrl_priv *pwrpriv;
416 pwrpriv = adapter_to_pwrctl(padapter);
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;
425 u16 rtw_btcoex_btreg_read(PADAPTER padapter, u8 type, u16 addr, u32 *data)
427 return hal_btcoex_btreg_read(padapter, type, addr, data);
430 u16 rtw_btcoex_btreg_write(PADAPTER padapter, u8 type, u16 addr, u16 val)
432 return hal_btcoex_btreg_write(padapter, type, addr, val);
435 u8 rtw_btcoex_get_bt_coexist(PADAPTER padapter)
437 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
439 return pHalData->EEPROMBluetoothCoexist;
442 u8 rtw_btcoex_get_chip_type(PADAPTER padapter)
444 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
446 return pHalData->EEPROMBluetoothType;
449 u8 rtw_btcoex_get_pg_ant_num(PADAPTER padapter)
451 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
453 return pHalData->EEPROMBluetoothAntNum == Ant_x2 ? 2 : 1;
456 u8 rtw_btcoex_get_pg_single_ant_path(PADAPTER padapter)
458 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
460 return pHalData->ant_path;
463 u8 rtw_btcoex_get_pg_rfe_type(PADAPTER padapter)
465 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
467 return pHalData->rfe_type;
470 u8 rtw_btcoex_is_tfbga_package_type(PADAPTER padapter)
472 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
474 #ifdef CONFIG_RTL8723B
475 if ((pHalData->PackageType == PACKAGE_TFBGA79) || (pHalData->PackageType == PACKAGE_TFBGA80)
476 || (pHalData->PackageType == PACKAGE_TFBGA90))
483 u8 rtw_btcoex_get_ant_div_cfg(PADAPTER padapter)
485 PHAL_DATA_TYPE pHalData;
487 pHalData = GET_HAL_DATA(padapter);
489 return (pHalData->AntDivCfg == 0) ? _FALSE : _TRUE;
492 /* ==================================================
493 * Below Functions are BT-Coex socket related function
494 * ================================================== */
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)
500 struct cmd_obj *ph2c;
501 struct drvextra_cmd_parm *pdrvextra_cmd_parm;
503 struct cmd_priv *pcmdpriv = &adapter->cmdpriv;
506 ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));
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));
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));
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;
532 _rtw_memcpy(btinfo, buf, len);
534 init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));
536 res = rtw_enqueue_cmd(pcmdpriv, ph2c);
542 u8 rtw_btcoex_send_event_to_BT(_adapter *padapter, u8 status, u8 event_code, u8 opcode_low, u8 opcode_high, u8 *dbg_msg)
546 u8 len = 0, tx_event_length = 0;
547 rtw_HCI_event *pEvent;
549 pEvent = (rtw_HCI_event *)(&localBuf[0]);
551 pEvent->EventCode = event_code;
552 pEvent->Data[0] = 0x1; /* packet # */
553 pEvent->Data[1] = opcode_low;
554 pEvent->Data[2] = opcode_high;
557 /* Return parameters starts from here */
558 pRetPar = &pEvent->Data[len];
559 pRetPar[0] = status; /* status */
562 pEvent->Length = len;
564 /* total tx event length + EventCode length + sizeof(length) */
565 tx_event_length = pEvent->Length + 2;
567 rtw_btcoex_dump_tx_msg((u8 *)pEvent, tx_event_length, dbg_msg);
569 status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
577 Host Controller Interface for
578 Bluetooth 3.0 + HS V1.4 2013/02/07
580 Window team code & BT team code
584 u8 rtw_btcoex_parse_BT_info_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)
586 #define BT_INFO_LENGTH 8
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];
596 u8 len = 0, tx_event_length = 0;
597 RTW_HCI_STATUS status = HCI_STATUS_SUCCESS;
598 rtw_HCI_event *pEvent;
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]);*/
606 _rtw_memset(btinfo, 0, BT_INFO_LENGTH);
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);
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);
621 RTW_INFO("Other BT info reason\n");
624 /* send complete event to BT */
627 pEvent = (rtw_HCI_event *)(&localBuf[0]);
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);
635 /* Return parameters starts from here */
636 pRetPar = &pEvent->Data[len];
637 pRetPar[0] = status; /* status */
640 pEvent->Length = len;
642 /* total tx event length + EventCode length + sizeof(length) */
643 tx_event_length = pEvent->Length + 2;
645 rtw_btcoex_dump_tx_msg((u8 *)pEvent, tx_event_length, "BT_info_event");
647 status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
650 /* bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); */
654 u8 rtw_btcoex_parse_BT_patch_ver_info_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)
656 RTW_HCI_STATUS status = HCI_STATUS_SUCCESS;
657 u16 btPatchVer = 0x0, btHciVer = 0x0;
662 u8 len = 0, tx_event_length = 0;
663 rtw_HCI_event *pEvent;
665 btHciVer = pcmd[0] | pcmd[1] << 8;
666 btPatchVer = pcmd[2] | pcmd[3] << 8;
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);
672 rtw_btcoex_SetBtPatchVersion(padapter, btHciVer, btPatchVer);
675 /* send complete event to BT */
677 pEvent = (rtw_HCI_event *)(&localBuf[0]);
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);
686 /* Return parameters starts from here */
687 pRetPar = &pEvent->Data[len];
688 pRetPar[0] = status; /* status */
691 pEvent->Length = len;
693 /* total tx event length + EventCode length + sizeof(length) */
694 tx_event_length = pEvent->Length + 2;
696 rtw_btcoex_dump_tx_msg((u8 *)pEvent, tx_event_length, "BT_patch_event");
698 status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
700 /* bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); */
704 u8 rtw_btcoex_parse_HCI_Ver_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)
706 RTW_HCI_STATUS status = HCI_STATUS_SUCCESS;
707 u16 hciver = pcmd[0] | pcmd[1] << 8;
711 u8 len = 0, tx_event_length = 0;
712 rtw_HCI_event *pEvent;
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);
722 rtw_btcoex_SetHciVersion(padapter, hciver);
723 /* send complete event to BT */
725 pEvent = (rtw_HCI_event *)(&localBuf[0]);
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);
734 /* Return parameters starts from here */
735 pRetPar = &pEvent->Data[len];
736 pRetPar[0] = status; /* status */
739 pEvent->Length = len;
741 /* total tx event length + EventCode length + sizeof(length) */
742 tx_event_length = pEvent->Length + 2;
744 status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
746 /* bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); */
751 u8 rtw_btcoex_parse_WIFI_scan_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)
753 RTW_HCI_STATUS status = HCI_STATUS_SUCCESS;
757 u8 len = 0, tx_event_length = 0;
758 rtw_HCI_event *pEvent;
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);
765 /* send complete event to BT */
767 pEvent = (rtw_HCI_event *)(&localBuf[0]);
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);
776 /* Return parameters starts from here */
777 pRetPar = &pEvent->Data[len];
778 pRetPar[0] = status; /* status */
781 pEvent->Length = len;
783 /* total tx event length + EventCode length + sizeof(length) */
784 tx_event_length = pEvent->Length + 2;
786 status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
788 /* bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); */
792 u8 rtw_btcoex_parse_HCI_link_status_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)
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;
800 u8 btProfile, btCoreSpec, linkRole;
805 u8 len = 0, tx_event_length = 0;
806 rtw_HCI_event *pEvent;
808 /* pBtDbg->dbgHciInfo.hciCmdCntLinkStatusNotify++; */
809 /* RT_DISP_DATA(FIOCTL, IOCTL_BT_HCICMD_EXT, "LinkStatusNotify, Hex Data :\n", */
810 /* &pHciCmd->Data[0], pHciCmd->Length); */
812 RTW_INFO("BTLinkStatusNotify\n");
814 /* Current only RTL8723 support this command. */
815 /* pBtMgnt->bSupportProfile = TRUE; */
816 pBtMgnt->bSupportProfile = _FALSE;
818 pBtMgnt->ExtConfig.NumberOfACL = 0;
819 pBtMgnt->ExtConfig.NumberOfSCO = 0;
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);
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++;
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;
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);
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++;
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;
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);
866 rtw_btcoex_StackUpdateProfileInfo();
868 /* send complete event to BT */
870 pEvent = (rtw_HCI_event *)(&localBuf[0]);
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);
879 /* Return parameters starts from here */
880 pRetPar = &pEvent->Data[len];
881 pRetPar[0] = status; /* status */
884 pEvent->Length = len;
886 /* total tx event length + EventCode length + sizeof(length) */
887 tx_event_length = pEvent->Length + 2;
889 status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
891 /* bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); */
897 u8 rtw_btcoex_parse_HCI_BT_coex_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)
901 u8 len = 0, tx_event_length = 0;
902 rtw_HCI_event *pEvent;
903 RTW_HCI_STATUS status = HCI_STATUS_SUCCESS;
906 pEvent = (rtw_HCI_event *)(&localBuf[0]);
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);
915 /* Return parameters starts from here */
916 pRetPar = &pEvent->Data[len];
917 pRetPar[0] = status; /* status */
920 pEvent->Length = len;
922 /* total tx event length + EventCode length + sizeof(length) */
923 tx_event_length = pEvent->Length + 2;
925 status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
927 /* bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); */
931 u8 rtw_btcoex_parse_HCI_BT_operation_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)
935 u8 len = 0, tx_event_length = 0;
936 rtw_HCI_event *pEvent;
937 RTW_HCI_STATUS status = HCI_STATUS_SUCCESS;
939 RTW_INFO("%s, OP code: %d\n", __func__, pcmd[0]);
943 RTW_INFO("[bt operation] : Operation None!!\n");
945 case HCI_BT_OP_INQUIRY_START:
946 RTW_INFO("[bt operation] : Inquiry start!!\n");
948 case HCI_BT_OP_INQUIRY_FINISH:
949 RTW_INFO("[bt operation] : Inquiry finished!!\n");
951 case HCI_BT_OP_PAGING_START:
952 RTW_INFO("[bt operation] : Paging is started!!\n");
954 case HCI_BT_OP_PAGING_SUCCESS:
955 RTW_INFO("[bt operation] : Paging complete successfully!!\n");
957 case HCI_BT_OP_PAGING_UNSUCCESS:
958 RTW_INFO("[bt operation] : Paging complete unsuccessfully!!\n");
960 case HCI_BT_OP_PAIRING_START:
961 RTW_INFO("[bt operation] : Pairing start!!\n");
963 case HCI_BT_OP_PAIRING_FINISH:
964 RTW_INFO("[bt operation] : Pairing finished!!\n");
966 case HCI_BT_OP_BT_DEV_ENABLE:
967 RTW_INFO("[bt operation] : BT Device is enabled!!\n");
969 case HCI_BT_OP_BT_DEV_DISABLE:
970 RTW_INFO("[bt operation] : BT Device is disabled!!\n");
973 RTW_INFO("[bt operation] : Unknown, error!!\n");
977 /* send complete event to BT */
979 pEvent = (rtw_HCI_event *)(&localBuf[0]);
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);
988 /* Return parameters starts from here */
989 pRetPar = &pEvent->Data[len];
990 pRetPar[0] = status; /* status */
993 pEvent->Length = len;
995 /* total tx event length + EventCode length + sizeof(length) */
996 tx_event_length = pEvent->Length + 2;
998 status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
1000 /* bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); */
1004 u8 rtw_btcoex_parse_BT_AFH_MAP_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)
1006 u8 localBuf[6] = "";
1008 u8 len = 0, tx_event_length = 0;
1009 rtw_HCI_event *pEvent;
1010 RTW_HCI_STATUS status = HCI_STATUS_SUCCESS;
1013 pEvent = (rtw_HCI_event *)(&localBuf[0]);
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);
1022 /* Return parameters starts from here */
1023 pRetPar = &pEvent->Data[len];
1024 pRetPar[0] = status; /* status */
1027 pEvent->Length = len;
1029 /* total tx event length + EventCode length + sizeof(length) */
1030 tx_event_length = pEvent->Length + 2;
1032 status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
1034 /* bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); */
1038 u8 rtw_btcoex_parse_BT_register_val_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)
1041 u8 localBuf[6] = "";
1043 u8 len = 0, tx_event_length = 0;
1044 rtw_HCI_event *pEvent;
1045 RTW_HCI_STATUS status = HCI_STATUS_SUCCESS;
1048 pEvent = (rtw_HCI_event *)(&localBuf[0]);
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);
1057 /* Return parameters starts from here */
1058 pRetPar = &pEvent->Data[len];
1059 pRetPar[0] = status; /* status */
1062 pEvent->Length = len;
1064 /* total tx event length + EventCode length + sizeof(length) */
1065 tx_event_length = pEvent->Length + 2;
1067 status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
1069 /* bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); */
1073 u8 rtw_btcoex_parse_HCI_BT_abnormal_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)
1075 u8 localBuf[6] = "";
1077 u8 len = 0, tx_event_length = 0;
1078 rtw_HCI_event *pEvent;
1079 RTW_HCI_STATUS status = HCI_STATUS_SUCCESS;
1082 pEvent = (rtw_HCI_event *)(&localBuf[0]);
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);
1091 /* Return parameters starts from here */
1092 pRetPar = &pEvent->Data[len];
1093 pRetPar[0] = status; /* status */
1096 pEvent->Length = len;
1098 /* total tx event length + EventCode length + sizeof(length) */
1099 tx_event_length = pEvent->Length + 2;
1101 status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
1103 /* bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); */
1107 u8 rtw_btcoex_parse_HCI_query_RF_status_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)
1109 u8 localBuf[6] = "";
1111 u8 len = 0, tx_event_length = 0;
1112 rtw_HCI_event *pEvent;
1113 RTW_HCI_STATUS status = HCI_STATUS_SUCCESS;
1116 pEvent = (rtw_HCI_event *)(&localBuf[0]);
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);
1125 /* Return parameters starts from here */
1126 pRetPar = &pEvent->Data[len];
1127 pRetPar[0] = status; /* status */
1130 pEvent->Length = len;
1132 /* total tx event length + EventCode length + sizeof(length) */
1133 tx_event_length = pEvent->Length + 2;
1135 status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
1137 /* bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); */
1141 /*****************************************
1144 *| OPcode (OCF|OGF<<10) |
1146 *|Cmd para |Cmd para Length |
1148 ******************************************/
1150 /* bit 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
1152 void rtw_btcoex_parse_hci_extend_cmd(_adapter *padapter, u8 *pcmd, u16 len, const u16 hci_OCF)
1155 RTW_INFO("%s: OCF: %x\n", __func__, 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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
1205 RTW_INFO("ERROR!!! Unknown OCF: %x\n", hci_OCF);
1211 void rtw_btcoex_parse_hci_cmd(_adapter *padapter, u8 *pcmd, u16 len)
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];
1219 RTW_INFO("%s OGF: %x,OCF: %x\n", __func__, hci_OGF, hci_OCF);
1222 RTW_INFO("HCI_EXTENSION_CMD_OGF\n");
1223 rtw_btcoex_parse_hci_extend_cmd(padapter, &pcmd[3], cmdlen, hci_OCF);
1226 RTW_INFO("Other OGF: %x\n", hci_OGF);
1231 u16 rtw_btcoex_parse_recv_data(u8 *msg, u8 msg_size)
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;
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);*/
1247 } else if (_rtw_memcmp(cmp_msg3, msg, msg_size) == _TRUE) {
1248 /*RTW_INFO("%s, msg:%s\n",__func__,msg);*/
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;
1258 /*RTW_INFO("%s, %s\n", __func__, msg);*/
1262 /*RTW_INFO("%s, res:%d\n", __func__, res);*/
1267 void rtw_btcoex_recvmsgbysocket(void *data)
1270 u8 tx_msg[255] = leave_ack;
1272 u16 recv_length = 0;
1275 u8 para_len = 0, polling_enable = 0, poling_interval = 0, reason = 0, btinfo_len = 0;
1276 u8 btinfo[BT_INFO_LEN] = {0};
1279 struct bt_coex_info *pcoex_info = NULL;
1280 struct sock *sk = NULL;
1281 struct sk_buff *skb = NULL;
1283 /*RTW_INFO("%s\n",__func__);*/
1285 if (pbtcoexadapter == NULL) {
1286 RTW_INFO("%s: btcoexadapter NULL!\n", __func__);
1290 pcoex_info = &pbtcoexadapter->coex_info;
1291 sk = pcoex_info->sk_store;
1294 RTW_INFO("%s: critical error when receive socket data!\n", __func__);
1298 len = skb_queue_len(&sk->sk_receive_queue);
1300 skb = skb_dequeue(&sk->sk_receive_queue);
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);
1307 parse_res = rtw_btcoex_parse_recv_data(recv_data, recv_length);
1309 if (RX_ATTEND_ACK == parse_res) {
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) {
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) {
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);
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);
1342 switch (parse_res) {
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);
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);
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);
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);
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);
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);
1388 if (_TRUE == pcoex_info->BT_attend)
1389 rtw_btcoex_parse_hci_cmd(pbtcoexadapter, recv_data, recv_length);
1391 RTW_INFO("ERROR!! BT is UP\n");
1401 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 15, 0))
1402 void rtw_btcoex_recvmsg_init(struct sock *sk_in, s32 bytes)
1404 void rtw_btcoex_recvmsg_init(struct sock *sk_in)
1407 struct bt_coex_info *pcoex_info = NULL;
1409 if (pbtcoexadapter == NULL) {
1410 RTW_INFO("%s: btcoexadapter NULL\n", __func__);
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);
1418 RTW_INFO("%s: BTCOEX workqueue NULL\n", __func__);
1421 u8 rtw_btcoex_sendmsgbysocket(_adapter *padapter, u8 *msg, u8 msg_size, bool force)
1424 struct msghdr udpmsg;
1427 struct bt_coex_info *pcoex_info = &padapter->coex_info;
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");
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
1447 iov_iter_init(&udpmsg.msg_iter, WRITE, &iov, 1, msg_size);
1449 udpmsg.msg_iov = &iov;
1450 udpmsg.msg_iovlen = 1;
1452 udpmsg.msg_control = NULL;
1453 udpmsg.msg_controllen = 0;
1454 udpmsg.msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL;
1458 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0))
1459 error = sock_sendmsg(pcoex_info->udpsock, &udpmsg);
1461 error = sock_sendmsg(pcoex_info->udpsock, &udpmsg, msg_size);
1465 RTW_INFO("Error when sendimg msg, error:%d\n", error);
1471 u8 rtw_btcoex_create_kernel_socket(_adapter *padapter)
1473 s8 kernel_socket_err;
1474 u8 tx_msg[255] = attend_req;
1475 struct bt_coex_info *pcoex_info = &padapter->coex_info;
1479 RTW_INFO("%s CONNECT_PORT %d\n", __func__, CONNECT_PORT);
1481 if (NULL == pcoex_info) {
1482 RTW_INFO("coex_info: NULL\n");
1486 kernel_socket_err = sock_create(PF_INET, SOCK_DGRAM, 0, &pcoex_info->udpsock);
1488 if (kernel_socket_err < 0) {
1489 RTW_INFO("Error during creation of socket error:%d\n", kernel_socket_err);
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);
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);
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);
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);
1525 void rtw_btcoex_close_kernel_socket(_adapter *padapter)
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;
1535 RTW_INFO("sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);
1539 void rtw_btcoex_init_socket(_adapter *padapter)
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;
1557 pcoex_info->is_exist = _FALSE;
1558 pbtcoexadapter = NULL;
1561 RTW_INFO("%s: pbtcoexadapter:%p, coex_info->is_exist: %s\n"
1562 , __func__, pbtcoexadapter, pcoex_info->is_exist == _TRUE ? "TRUE" : "FALSE");
1566 void rtw_btcoex_close_socket(_adapter *padapter)
1568 struct bt_coex_info *pcoex_info = &padapter->coex_info;
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");
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);
1580 if (pcoex_info->btcoex_wq != NULL) {
1581 flush_workqueue(pcoex_info->btcoex_wq);
1582 destroy_workqueue(pcoex_info->btcoex_wq);
1585 rtw_btcoex_close_kernel_socket(padapter);
1586 pbtcoexadapter = NULL;
1587 pcoex_info->is_exist = _FALSE;
1591 void rtw_btcoex_dump_tx_msg(u8 *tx_msg, u8 len, u8 *msg_name)
1594 RTW_INFO("======> Msg name: %s\n", msg_name);
1595 for (i = 0; i < len; i++)
1596 printk("%02x ", tx_msg[i]);
1598 RTW_INFO("Msg name: %s <======\n", msg_name);
1601 /* Porting from Windows team */
1602 void rtw_btcoex_SendEventExtBtCoexControl(PADAPTER padapter, u8 bNeedDbgRsp, u8 dataLen, void *pData)
1604 u8 len = 0, tx_event_length = 0;
1605 u8 localBuf[32] = "";
1608 u8 *pInBuf = (pu1Byte)pData;
1610 rtw_HCI_event *pEvent;
1614 RTW_INFO("%s, OPCode:%02x\n", __func__, opCode);
1616 pEvent = (rtw_HCI_event *)(&localBuf[0]);
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 */
1624 /* Return parameters starts from here */
1625 pRetPar = &pEvent->Data[len];
1626 _rtw_memcpy(&pRetPar[0], pData, dataLen);
1630 pEvent->Length = len;
1632 /* total tx event length + EventCode length + sizeof(length) */
1633 tx_event_length = pEvent->Length + 2;
1635 rtw_btcoex_dump_tx_msg((u8 *)pEvent, tx_event_length, "BT COEX CONTROL", _FALSE);
1637 rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
1641 /* Porting from Windows team */
1642 void rtw_btcoex_SendEventExtBtInfoControl(PADAPTER padapter, u8 dataLen, void *pData)
1644 rtw_HCI_event *pEvent;
1646 u8 len = 0, tx_event_length = 0;
1647 u8 localBuf[32] = "";
1649 struct bt_coex_info *pcoex_info = &padapter->coex_info;
1650 PBT_MGNT pBtMgnt = &pcoex_info->BtMgnt;
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);
1658 pEvent = (rtw_HCI_event *)(&localBuf[0]);
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 */
1666 /* Return parameters starts from here */
1667 pRetPar = &pEvent->Data[len];
1668 _rtw_memcpy(&pRetPar[0], pData, dataLen);
1672 pEvent->Length = len;
1674 /* total tx event length + EventCode length + sizeof(length) */
1675 tx_event_length = pEvent->Length + 2;
1677 rtw_btcoex_dump_tx_msg((u8 *)pEvent, tx_event_length, "BT INFO CONTROL");
1679 rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
1683 void rtw_btcoex_SendScanNotify(PADAPTER padapter, u8 scanType)
1685 u8 len = 0, tx_event_length = 0;
1686 u8 localBuf[7] = "";
1689 rtw_HCI_event *pEvent;
1690 struct bt_coex_info *pcoex_info = &padapter->coex_info;
1691 PBT_MGNT pBtMgnt = &pcoex_info->BtMgnt;
1693 /* if(!pBtMgnt->BtOperationOn)
1696 pEvent = (rtw_HCI_event *)(&localBuf[0]);
1698 /* len += bthci_ExtensionEventHeaderRtk(&localBuf[0],
1699 * HCI_EVENT_EXT_WIFI_SCAN_NOTIFY); */
1701 pEvent->EventCode = HCI_EVENT_EXTENSION_RTK;
1702 pEvent->Data[0] = HCI_EVENT_EXT_WIFI_SCAN_NOTIFY; /* extension event code */
1705 /* Return parameters starts from here */
1706 /* pRetPar = &PPacketIrpEvent->Data[len]; */
1707 /* pu1Temp = (u8 *)&pRetPar[0]; */
1708 /* *pu1Temp = scanType; */
1709 pEvent->Data[len] = scanType;
1712 pEvent->Length = len;
1714 /* total tx event length + EventCode length + sizeof(length) */
1715 tx_event_length = pEvent->Length + 2;
1717 rtw_btcoex_dump_tx_msg((u8 *)pEvent, tx_event_length, "WIFI SCAN OPERATION");
1719 rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);
1721 #endif /* CONFIG_BT_COEXIST_SOCKET_TRX */
1722 #endif /* CONFIG_BT_COEXIST */