Path: blob/master/ALFA-W1F1/RTL8814AU/core/rtw_btcoex.c
1307 views
/******************************************************************************1*2* Copyright(c) 2013 - 2017 Realtek Corporation.3*4* This program is free software; you can redistribute it and/or modify it5* under the terms of version 2 of the GNU General Public License as6* published by the Free Software Foundation.7*8* This program is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for11* more details.12*13*****************************************************************************/14#include <drv_types.h>15#include <hal_data.h>16#ifdef CONFIG_BT_COEXIST17#include <hal_btcoex.h>1819void rtw_btcoex_Initialize(PADAPTER padapter)20{21hal_btcoex_Initialize(padapter);22}2324void rtw_btcoex_PowerOnSetting(PADAPTER padapter)25{26hal_btcoex_PowerOnSetting(padapter);27}2829void rtw_btcoex_AntInfoSetting(PADAPTER padapter)30{31hal_btcoex_AntInfoSetting(padapter);32}3334void rtw_btcoex_PowerOffSetting(PADAPTER padapter)35{36hal_btcoex_PowerOffSetting(padapter);37}3839void rtw_btcoex_PreLoadFirmware(PADAPTER padapter)40{41hal_btcoex_PreLoadFirmware(padapter);42}4344void rtw_btcoex_HAL_Initialize(PADAPTER padapter, u8 bWifiOnly)45{46hal_btcoex_InitHwConfig(padapter, bWifiOnly);47}4849void rtw_btcoex_IpsNotify(PADAPTER padapter, u8 type)50{51PHAL_DATA_TYPE pHalData;5253pHalData = GET_HAL_DATA(padapter);54if (_FALSE == pHalData->EEPROMBluetoothCoexist)55return;5657hal_btcoex_IpsNotify(padapter, type);58}5960void rtw_btcoex_LpsNotify(PADAPTER padapter, u8 type)61{62PHAL_DATA_TYPE pHalData;6364pHalData = GET_HAL_DATA(padapter);65if (_FALSE == pHalData->EEPROMBluetoothCoexist)66return;6768hal_btcoex_LpsNotify(padapter, type);69}7071void rtw_btcoex_ScanNotify(PADAPTER padapter, u8 type)72{73PHAL_DATA_TYPE pHalData;74#ifdef CONFIG_BT_COEXIST_SOCKET_TRX75struct bt_coex_info *pcoex_info = &padapter->coex_info;76PBT_MGNT pBtMgnt = &pcoex_info->BtMgnt;77#endif /* CONFIG_BT_COEXIST_SOCKET_TRX */7879pHalData = GET_HAL_DATA(padapter);80if (_FALSE == pHalData->EEPROMBluetoothCoexist)81return;8283if (_FALSE == type) {84#ifdef CONFIG_CONCURRENT_MODE85if (rtw_mi_buddy_check_fwstate(padapter, WIFI_SITE_MONITOR))86return;87#endif8889if (DEV_MGMT_TX_NUM(adapter_to_dvobj(padapter))90|| DEV_ROCH_NUM(adapter_to_dvobj(padapter)))91return;92}9394#ifdef CONFIG_BT_COEXIST_SOCKET_TRX95if (pBtMgnt->ExtConfig.bEnableWifiScanNotify)96rtw_btcoex_SendScanNotify(padapter, type);97#endif /* CONFIG_BT_COEXIST_SOCKET_TRX */9899hal_btcoex_ScanNotify(padapter, type);100}101102void rtw_btcoex_ConnectNotify(PADAPTER padapter, u8 action)103{104PHAL_DATA_TYPE pHalData;105106pHalData = GET_HAL_DATA(padapter);107if (_FALSE == pHalData->EEPROMBluetoothCoexist)108return;109110#ifdef DBG_CONFIG_ERROR_RESET111if (_TRUE == rtw_hal_sreset_inprogress(padapter)) {112RTW_INFO(FUNC_ADPT_FMT ": [BTCoex] under reset, skip notify!\n",113FUNC_ADPT_ARG(padapter));114return;115}116#endif /* DBG_CONFIG_ERROR_RESET */117118#ifdef CONFIG_CONCURRENT_MODE119if (_FALSE == action) {120if (rtw_mi_buddy_check_fwstate(padapter, WIFI_UNDER_LINKING))121return;122}123#endif124125hal_btcoex_ConnectNotify(padapter, action);126}127128void rtw_btcoex_MediaStatusNotify(PADAPTER padapter, u8 mediaStatus)129{130PHAL_DATA_TYPE pHalData;131132pHalData = GET_HAL_DATA(padapter);133if (_FALSE == pHalData->EEPROMBluetoothCoexist)134return;135136#ifdef DBG_CONFIG_ERROR_RESET137if (_TRUE == rtw_hal_sreset_inprogress(padapter)) {138RTW_INFO(FUNC_ADPT_FMT ": [BTCoex] under reset, skip notify!\n",139FUNC_ADPT_ARG(padapter));140return;141}142#endif /* DBG_CONFIG_ERROR_RESET */143144#ifdef CONFIG_CONCURRENT_MODE145if (RT_MEDIA_DISCONNECT == mediaStatus) {146if (rtw_mi_buddy_check_fwstate(padapter, WIFI_ASOC_STATE))147return;148}149#endif /* CONFIG_CONCURRENT_MODE */150151if ((RT_MEDIA_CONNECT == mediaStatus)152&& (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE))153rtw_hal_set_hwreg(padapter, HW_VAR_DL_RSVD_PAGE, NULL);154155hal_btcoex_MediaStatusNotify(padapter, mediaStatus);156}157158void rtw_btcoex_SpecialPacketNotify(PADAPTER padapter, u8 pktType)159{160PHAL_DATA_TYPE pHalData;161162pHalData = GET_HAL_DATA(padapter);163if (_FALSE == pHalData->EEPROMBluetoothCoexist)164return;165166hal_btcoex_SpecialPacketNotify(padapter, pktType);167}168169void rtw_btcoex_IQKNotify(PADAPTER padapter, u8 state)170{171PHAL_DATA_TYPE pHalData;172173pHalData = GET_HAL_DATA(padapter);174if (_FALSE == pHalData->EEPROMBluetoothCoexist)175return;176177hal_btcoex_IQKNotify(padapter, state);178}179180void rtw_btcoex_BtInfoNotify(PADAPTER padapter, u8 length, u8 *tmpBuf)181{182PHAL_DATA_TYPE pHalData;183184pHalData = GET_HAL_DATA(padapter);185if (_FALSE == pHalData->EEPROMBluetoothCoexist)186return;187188hal_btcoex_BtInfoNotify(padapter, length, tmpBuf);189}190191void rtw_btcoex_BtMpRptNotify(PADAPTER padapter, u8 length, u8 *tmpBuf)192{193PHAL_DATA_TYPE pHalData;194195pHalData = GET_HAL_DATA(padapter);196if (_FALSE == pHalData->EEPROMBluetoothCoexist)197return;198199if (padapter->registrypriv.mp_mode == 1)200return;201202hal_btcoex_BtMpRptNotify(padapter, length, tmpBuf);203}204205void rtw_btcoex_SuspendNotify(PADAPTER padapter, u8 state)206{207PHAL_DATA_TYPE pHalData;208209pHalData = GET_HAL_DATA(padapter);210if (_FALSE == pHalData->EEPROMBluetoothCoexist)211return;212213hal_btcoex_SuspendNotify(padapter, state);214}215216void rtw_btcoex_HaltNotify(PADAPTER padapter)217{218PHAL_DATA_TYPE pHalData;219u8 do_halt = 1;220221pHalData = GET_HAL_DATA(padapter);222if (_FALSE == pHalData->EEPROMBluetoothCoexist)223do_halt = 0;224225if (_FALSE == padapter->bup) {226RTW_INFO(FUNC_ADPT_FMT ": bup=%d Skip!\n",227FUNC_ADPT_ARG(padapter), padapter->bup);228do_halt = 0;229}230231if (rtw_is_surprise_removed(padapter)) {232RTW_INFO(FUNC_ADPT_FMT ": bSurpriseRemoved=%s Skip!\n",233FUNC_ADPT_ARG(padapter), rtw_is_surprise_removed(padapter) ? "True" : "False");234do_halt = 0;235}236237hal_btcoex_HaltNotify(padapter, do_halt);238}239240void rtw_btcoex_switchband_notify(u8 under_scan, u8 band_type)241{242hal_btcoex_switchband_notify(under_scan, band_type);243}244245void rtw_btcoex_WlFwDbgInfoNotify(PADAPTER padapter, u8* tmpBuf, u8 length)246{247hal_btcoex_WlFwDbgInfoNotify(padapter, tmpBuf, length);248}249250void rtw_btcoex_rx_rate_change_notify(PADAPTER padapter, u8 is_data_frame, u8 rate_id)251{252hal_btcoex_rx_rate_change_notify(padapter, is_data_frame, rate_id);253}254255void rtw_btcoex_SwitchBtTRxMask(PADAPTER padapter)256{257hal_btcoex_SwitchBtTRxMask(padapter);258}259260void rtw_btcoex_Switch(PADAPTER padapter, u8 enable)261{262hal_btcoex_SetBTCoexist(padapter, enable);263}264265u8 rtw_btcoex_IsBtDisabled(PADAPTER padapter)266{267return hal_btcoex_IsBtDisabled(padapter);268}269270void rtw_btcoex_Handler(PADAPTER padapter)271{272PHAL_DATA_TYPE pHalData;273274pHalData = GET_HAL_DATA(padapter);275276if (_FALSE == pHalData->EEPROMBluetoothCoexist)277return;278279hal_btcoex_Hanlder(padapter);280}281282s32 rtw_btcoex_IsBTCoexRejectAMPDU(PADAPTER padapter)283{284s32 coexctrl;285286coexctrl = hal_btcoex_IsBTCoexRejectAMPDU(padapter);287288return coexctrl;289}290291s32 rtw_btcoex_IsBTCoexCtrlAMPDUSize(PADAPTER padapter)292{293s32 coexctrl;294295coexctrl = hal_btcoex_IsBTCoexCtrlAMPDUSize(padapter);296297return coexctrl;298}299300u32 rtw_btcoex_GetAMPDUSize(PADAPTER padapter)301{302u32 size;303304size = hal_btcoex_GetAMPDUSize(padapter);305306return size;307}308309void rtw_btcoex_SetManualControl(PADAPTER padapter, u8 manual)310{311if (_TRUE == manual)312hal_btcoex_SetManualControl(padapter, _TRUE);313else314hal_btcoex_SetManualControl(padapter, _FALSE);315}316317u8 rtw_btcoex_1Ant(PADAPTER padapter)318{319return hal_btcoex_1Ant(padapter);320}321322u8 rtw_btcoex_IsBtControlLps(PADAPTER padapter)323{324return hal_btcoex_IsBtControlLps(padapter);325}326327u8 rtw_btcoex_IsLpsOn(PADAPTER padapter)328{329return hal_btcoex_IsLpsOn(padapter);330}331332u8 rtw_btcoex_RpwmVal(PADAPTER padapter)333{334return hal_btcoex_RpwmVal(padapter);335}336337u8 rtw_btcoex_LpsVal(PADAPTER padapter)338{339return hal_btcoex_LpsVal(padapter);340}341342u32 rtw_btcoex_GetRaMask(PADAPTER padapter)343{344return hal_btcoex_GetRaMask(padapter);345}346347u8 rtw_btcoex_query_reduced_wl_pwr_lvl(PADAPTER padapter)348{349return hal_btcoex_query_reduced_wl_pwr_lvl(padapter);350}351352void rtw_btcoex_set_reduced_wl_pwr_lvl(PADAPTER padapter, u8 val)353{354hal_btcoex_set_reduced_wl_pwr_lvl(padapter, val);355}356357void rtw_btcoex_do_reduce_wl_pwr_lvl(PADAPTER padapter)358{359hal_btcoex_do_reduce_wl_pwr_lvl(padapter);360}361362void rtw_btcoex_RecordPwrMode(PADAPTER padapter, u8 *pCmdBuf, u8 cmdLen)363{364hal_btcoex_RecordPwrMode(padapter, pCmdBuf, cmdLen);365}366367void rtw_btcoex_DisplayBtCoexInfo(PADAPTER padapter, u8 *pbuf, u32 bufsize)368{369hal_btcoex_DisplayBtCoexInfo(padapter, pbuf, bufsize);370}371372void rtw_btcoex_SetDBG(PADAPTER padapter, u32 *pDbgModule)373{374hal_btcoex_SetDBG(padapter, pDbgModule);375}376377u32 rtw_btcoex_GetDBG(PADAPTER padapter, u8 *pStrBuf, u32 bufSize)378{379return hal_btcoex_GetDBG(padapter, pStrBuf, bufSize);380}381382u8 rtw_btcoex_IncreaseScanDeviceNum(PADAPTER padapter)383{384return hal_btcoex_IncreaseScanDeviceNum(padapter);385}386387u8 rtw_btcoex_IsBtLinkExist(PADAPTER padapter)388{389return hal_btcoex_IsBtLinkExist(padapter);390}391392void rtw_btcoex_SetBtPatchVersion(PADAPTER padapter, u16 btHciVer, u16 btPatchVer)393{394hal_btcoex_SetBtPatchVersion(padapter, btHciVer, btPatchVer);395}396397void rtw_btcoex_SetHciVersion(PADAPTER padapter, u16 hciVersion)398{399hal_btcoex_SetHciVersion(padapter, hciVersion);400}401402void rtw_btcoex_StackUpdateProfileInfo(void)403{404hal_btcoex_StackUpdateProfileInfo();405}406407void rtw_btcoex_pta_off_on_notify(PADAPTER padapter, u8 bBTON)408{409hal_btcoex_pta_off_on_notify(padapter, bBTON);410}411412#ifdef CONFIG_RF4CE_COEXIST413void rtw_btcoex_SetRf4ceLinkState(PADAPTER padapter, u8 state)414{415hal_btcoex_set_rf4ce_link_state(state);416}417418u8 rtw_btcoex_GetRf4ceLinkState(PADAPTER padapter)419{420return hal_btcoex_get_rf4ce_link_state();421}422#endif423424/* ==================================================425* Below Functions are called by BT-Coex426* ================================================== */427void rtw_btcoex_rx_ampdu_apply(PADAPTER padapter)428{429rtw_rx_ampdu_apply(padapter);430}431432void rtw_btcoex_LPS_Enter(PADAPTER padapter)433{434struct pwrctrl_priv *pwrpriv;435u8 lpsVal;436437438pwrpriv = adapter_to_pwrctl(padapter);439440pwrpriv->bpower_saving = _TRUE;441lpsVal = rtw_btcoex_LpsVal(padapter);442rtw_set_ps_mode(padapter, PS_MODE_MIN, 0, lpsVal, "BTCOEX");443}444445u8 rtw_btcoex_LPS_Leave(PADAPTER padapter)446{447struct pwrctrl_priv *pwrpriv;448449450pwrpriv = adapter_to_pwrctl(padapter);451452if (pwrpriv->pwr_mode != PS_MODE_ACTIVE) {453rtw_set_ps_mode(padapter, PS_MODE_ACTIVE, 0, 0, "BTCOEX");454pwrpriv->bpower_saving = _FALSE;455}456457return _TRUE;458}459460u16 rtw_btcoex_btreg_read(PADAPTER padapter, u8 type, u16 addr, u32 *data)461{462return hal_btcoex_btreg_read(padapter, type, addr, data);463}464465u16 rtw_btcoex_btreg_write(PADAPTER padapter, u8 type, u16 addr, u16 val)466{467return hal_btcoex_btreg_write(padapter, type, addr, val);468}469470u16 rtw_btcoex_btset_testmode(PADAPTER padapter, u8 type)471{472return hal_btcoex_btset_testode(padapter, type);473}474475u8 rtw_btcoex_get_reduce_wl_txpwr(PADAPTER padapter)476{477return rtw_btcoex_query_reduced_wl_pwr_lvl(padapter);478}479480u8 rtw_btcoex_get_bt_coexist(PADAPTER padapter)481{482HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);483484return pHalData->EEPROMBluetoothCoexist;485}486487u8 rtw_btcoex_get_chip_type(PADAPTER padapter)488{489HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);490491return pHalData->EEPROMBluetoothType;492}493494u8 rtw_btcoex_get_pg_ant_num(PADAPTER padapter)495{496HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);497498return pHalData->EEPROMBluetoothAntNum == Ant_x2 ? 2 : 1;499}500501u8 rtw_btcoex_get_pg_single_ant_path(PADAPTER padapter)502{503HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);504505return pHalData->ant_path;506}507508u8 rtw_btcoex_get_pg_rfe_type(PADAPTER padapter)509{510HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);511512return pHalData->rfe_type;513}514515u8 rtw_btcoex_is_tfbga_package_type(PADAPTER padapter)516{517#ifdef CONFIG_RTL8723B518HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);519520if ((pHalData->PackageType == PACKAGE_TFBGA79) || (pHalData->PackageType == PACKAGE_TFBGA80)521|| (pHalData->PackageType == PACKAGE_TFBGA90))522return _TRUE;523#endif524525return _FALSE;526}527528u8 rtw_btcoex_get_ant_div_cfg(PADAPTER padapter)529{530PHAL_DATA_TYPE pHalData;531532pHalData = GET_HAL_DATA(padapter);533534return (pHalData->AntDivCfg == 0) ? _FALSE : _TRUE;535}536537/* ==================================================538* Below Functions are BT-Coex socket related function539* ================================================== */540541#ifdef CONFIG_BT_COEXIST_SOCKET_TRX542_adapter *pbtcoexadapter; /* = NULL; */ /* do not initialise globals to 0 or NULL */543u8 rtw_btcoex_btinfo_cmd(_adapter *adapter, u8 *buf, u16 len)544{545struct cmd_obj *ph2c;546struct drvextra_cmd_parm *pdrvextra_cmd_parm;547u8 *btinfo;548struct cmd_priv *pcmdpriv = &adapter->cmdpriv;549u8 res = _SUCCESS;550551ph2c = (struct cmd_obj *)rtw_zmalloc(sizeof(struct cmd_obj));552if (ph2c == NULL) {553res = _FAIL;554goto exit;555}556557pdrvextra_cmd_parm = (struct drvextra_cmd_parm *)rtw_zmalloc(sizeof(struct drvextra_cmd_parm));558if (pdrvextra_cmd_parm == NULL) {559rtw_mfree((u8 *)ph2c, sizeof(struct cmd_obj));560res = _FAIL;561goto exit;562}563564btinfo = rtw_zmalloc(len);565if (btinfo == NULL) {566rtw_mfree((u8 *)ph2c, sizeof(struct cmd_obj));567rtw_mfree((u8 *)pdrvextra_cmd_parm, sizeof(struct drvextra_cmd_parm));568res = _FAIL;569goto exit;570}571572pdrvextra_cmd_parm->ec_id = BTINFO_WK_CID;573pdrvextra_cmd_parm->type = 0;574pdrvextra_cmd_parm->size = len;575pdrvextra_cmd_parm->pbuf = btinfo;576577_rtw_memcpy(btinfo, buf, len);578579init_h2fwcmd_w_parm_no_rsp(ph2c, pdrvextra_cmd_parm, GEN_CMD_CODE(_Set_Drv_Extra));580581res = rtw_enqueue_cmd(pcmdpriv, ph2c);582583exit:584return res;585}586587u8 rtw_btcoex_send_event_to_BT(_adapter *padapter, u8 status, u8 event_code, u8 opcode_low, u8 opcode_high, u8 *dbg_msg)588{589u8 localBuf[6] = "";590u8 *pRetPar;591u8 len = 0, tx_event_length = 0;592rtw_HCI_event *pEvent;593594pEvent = (rtw_HCI_event *)(&localBuf[0]);595596pEvent->EventCode = event_code;597pEvent->Data[0] = 0x1; /* packet # */598pEvent->Data[1] = opcode_low;599pEvent->Data[2] = opcode_high;600len = len + 3;601602/* Return parameters starts from here */603pRetPar = &pEvent->Data[len];604pRetPar[0] = status; /* status */605606len++;607pEvent->Length = len;608609/* total tx event length + EventCode length + sizeof(length) */610tx_event_length = pEvent->Length + 2;611#if 0612rtw_btcoex_dump_tx_msg((u8 *)pEvent, tx_event_length, dbg_msg);613#endif614status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);615616return status;617}618619/*620Ref:621Realtek Wi-Fi Driver622Host Controller Interface for623Bluetooth 3.0 + HS V1.4 2013/02/07624625Window team code & BT team code626*/627628629u8 rtw_btcoex_parse_BT_info_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)630{631#define BT_INFO_LENGTH 8632633u8 curPollEnable = pcmd[0];634u8 curPollTime = pcmd[1];635u8 btInfoReason = pcmd[2];636u8 btInfoLen = pcmd[3];637u8 btinfo[BT_INFO_LENGTH];638639u8 localBuf[6] = "";640u8 *pRetPar;641u8 len = 0, tx_event_length = 0;642RTW_HCI_STATUS status = HCI_STATUS_SUCCESS;643rtw_HCI_event *pEvent;644645/* RTW_INFO("%s\n",__func__);646RTW_INFO("current Poll Enable: %d, currrent Poll Time: %d\n",curPollEnable,curPollTime);647RTW_INFO("BT Info reason: %d, BT Info length: %d\n",btInfoReason,btInfoLen);648RTW_INFO("%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n"649,pcmd[4],pcmd[5],pcmd[6],pcmd[7],pcmd[8],pcmd[9],pcmd[10],pcmd[11]);*/650651_rtw_memset(btinfo, 0, BT_INFO_LENGTH);652653#if 1654if (BT_INFO_LENGTH != btInfoLen) {655status = HCI_STATUS_INVALID_HCI_CMD_PARA_VALUE;656RTW_INFO("Error BT Info Length: %d\n", btInfoLen);657/* return _FAIL; */658} else659#endif660{661if (0x1 == btInfoReason || 0x2 == btInfoReason) {662_rtw_memcpy(btinfo, &pcmd[4], btInfoLen);663btinfo[0] = btInfoReason;664rtw_btcoex_btinfo_cmd(padapter, btinfo, btInfoLen);665} else666RTW_INFO("Other BT info reason\n");667}668669/* send complete event to BT */670{671672pEvent = (rtw_HCI_event *)(&localBuf[0]);673674pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;675pEvent->Data[0] = 0x1; /* packet # */676pEvent->Data[1] = HCIOPCODELOW(HCI_BT_INFO_NOTIFY, OGF_EXTENSION);677pEvent->Data[2] = HCIOPCODEHIGHT(HCI_BT_INFO_NOTIFY, OGF_EXTENSION);678len = len + 3;679680/* Return parameters starts from here */681pRetPar = &pEvent->Data[len];682pRetPar[0] = status; /* status */683684len++;685pEvent->Length = len;686687/* total tx event length + EventCode length + sizeof(length) */688tx_event_length = pEvent->Length + 2;689#if 0690rtw_btcoex_dump_tx_msg((u8 *)pEvent, tx_event_length, "BT_info_event");691#endif692status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);693694return status;695/* bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); */696}697}698699u8 rtw_btcoex_parse_BT_patch_ver_info_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)700{701RTW_HCI_STATUS status = HCI_STATUS_SUCCESS;702u16 btPatchVer = 0x0, btHciVer = 0x0;703/* u16 *pU2tmp; */704705u8 localBuf[6] = "";706u8 *pRetPar;707u8 len = 0, tx_event_length = 0;708rtw_HCI_event *pEvent;709710btHciVer = pcmd[0] | pcmd[1] << 8;711btPatchVer = pcmd[2] | pcmd[3] << 8;712713714RTW_INFO("%s, cmd:%02x %02x %02x %02x\n", __func__, pcmd[0] , pcmd[1] , pcmd[2] , pcmd[3]);715RTW_INFO("%s, HCI Ver:%d, Patch Ver:%d\n", __func__, btHciVer, btPatchVer);716717rtw_btcoex_SetBtPatchVersion(padapter, btHciVer, btPatchVer);718719720/* send complete event to BT */721{722pEvent = (rtw_HCI_event *)(&localBuf[0]);723724725pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;726pEvent->Data[0] = 0x1; /* packet # */727pEvent->Data[1] = HCIOPCODELOW(HCI_BT_PATCH_VERSION_NOTIFY, OGF_EXTENSION);728pEvent->Data[2] = HCIOPCODEHIGHT(HCI_BT_PATCH_VERSION_NOTIFY, OGF_EXTENSION);729len = len + 3;730731/* Return parameters starts from here */732pRetPar = &pEvent->Data[len];733pRetPar[0] = status; /* status */734735len++;736pEvent->Length = len;737738/* total tx event length + EventCode length + sizeof(length) */739tx_event_length = pEvent->Length + 2;740#if 0741rtw_btcoex_dump_tx_msg((u8 *)pEvent, tx_event_length, "BT_patch_event");742#endif743status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);744return status;745/* bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); */746}747}748749u8 rtw_btcoex_parse_HCI_Ver_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)750{751RTW_HCI_STATUS status = HCI_STATUS_SUCCESS;752u16 hciver = pcmd[0] | pcmd[1] << 8;753754u8 localBuf[6] = "";755u8 *pRetPar;756u8 len = 0, tx_event_length = 0;757rtw_HCI_event *pEvent;758759struct bt_coex_info *pcoex_info = &padapter->coex_info;760PBT_MGNT pBtMgnt = &pcoex_info->BtMgnt;761pBtMgnt->ExtConfig.HCIExtensionVer = hciver;762RTW_INFO("%s, HCI Version: %d\n", __func__, pBtMgnt->ExtConfig.HCIExtensionVer);763if (pBtMgnt->ExtConfig.HCIExtensionVer < 4) {764status = HCI_STATUS_INVALID_HCI_CMD_PARA_VALUE;765RTW_INFO("%s, Version = %d, HCI Version < 4\n", __func__, pBtMgnt->ExtConfig.HCIExtensionVer);766} else767rtw_btcoex_SetHciVersion(padapter, hciver);768/* send complete event to BT */769{770pEvent = (rtw_HCI_event *)(&localBuf[0]);771772773pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;774pEvent->Data[0] = 0x1; /* packet # */775pEvent->Data[1] = HCIOPCODELOW(HCI_EXTENSION_VERSION_NOTIFY, OGF_EXTENSION);776pEvent->Data[2] = HCIOPCODEHIGHT(HCI_EXTENSION_VERSION_NOTIFY, OGF_EXTENSION);777len = len + 3;778779/* Return parameters starts from here */780pRetPar = &pEvent->Data[len];781pRetPar[0] = status; /* status */782783len++;784pEvent->Length = len;785786/* total tx event length + EventCode length + sizeof(length) */787tx_event_length = pEvent->Length + 2;788789status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);790return status;791/* bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); */792}793794}795796u8 rtw_btcoex_parse_WIFI_scan_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)797{798RTW_HCI_STATUS status = HCI_STATUS_SUCCESS;799800u8 localBuf[6] = "";801u8 *pRetPar;802u8 len = 0, tx_event_length = 0;803rtw_HCI_event *pEvent;804805struct bt_coex_info *pcoex_info = &padapter->coex_info;806PBT_MGNT pBtMgnt = &pcoex_info->BtMgnt;807pBtMgnt->ExtConfig.bEnableWifiScanNotify = pcmd[0];808RTW_INFO("%s, bEnableWifiScanNotify: %d\n", __func__, pBtMgnt->ExtConfig.bEnableWifiScanNotify);809810/* send complete event to BT */811{812pEvent = (rtw_HCI_event *)(&localBuf[0]);813814815pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;816pEvent->Data[0] = 0x1; /* packet # */817pEvent->Data[1] = HCIOPCODELOW(HCI_ENABLE_WIFI_SCAN_NOTIFY, OGF_EXTENSION);818pEvent->Data[2] = HCIOPCODEHIGHT(HCI_ENABLE_WIFI_SCAN_NOTIFY, OGF_EXTENSION);819len = len + 3;820821/* Return parameters starts from here */822pRetPar = &pEvent->Data[len];823pRetPar[0] = status; /* status */824825len++;826pEvent->Length = len;827828/* total tx event length + EventCode length + sizeof(length) */829tx_event_length = pEvent->Length + 2;830831status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);832return status;833/* bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); */834}835}836837u8 rtw_btcoex_parse_HCI_link_status_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)838{839RTW_HCI_STATUS status = HCI_STATUS_SUCCESS;840struct bt_coex_info *pcoex_info = &padapter->coex_info;841PBT_MGNT pBtMgnt = &pcoex_info->BtMgnt;842/* PBT_DBG pBtDbg=&padapter->MgntInfo.BtInfo.BtDbg; */843u8 i, numOfHandle = 0, numOfAcl = 0;844u16 conHandle;845u8 btProfile, btCoreSpec, linkRole;846u8 *pTriple;847848u8 localBuf[6] = "";849u8 *pRetPar;850u8 len = 0, tx_event_length = 0;851rtw_HCI_event *pEvent;852853/* pBtDbg->dbgHciInfo.hciCmdCntLinkStatusNotify++; */854/* RT_DISP_DATA(FIOCTL, IOCTL_BT_HCICMD_EXT, "LinkStatusNotify, Hex Data :\n", */855/* &pHciCmd->Data[0], pHciCmd->Length); */856857RTW_INFO("BTLinkStatusNotify\n");858859/* Current only RTL8723 support this command. */860/* pBtMgnt->bSupportProfile = TRUE; */861pBtMgnt->bSupportProfile = _FALSE;862863pBtMgnt->ExtConfig.NumberOfACL = 0;864pBtMgnt->ExtConfig.NumberOfSCO = 0;865866numOfHandle = pcmd[0];867/* RT_DISP(FIOCTL, IOCTL_BT_HCICMD_EXT, ("numOfHandle = 0x%x\n", numOfHandle)); */868/* RT_DISP(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCIExtensionVer = %d\n", pBtMgnt->ExtConfig.HCIExtensionVer)); */869RTW_INFO("numOfHandle = 0x%x\n", numOfHandle);870RTW_INFO("HCIExtensionVer = %d\n", pBtMgnt->ExtConfig.HCIExtensionVer);871872pTriple = &pcmd[1];873for (i = 0; i < numOfHandle; i++) {874if (pBtMgnt->ExtConfig.HCIExtensionVer < 1) {875conHandle = *((u8 *)&pTriple[0]);876btProfile = pTriple[2];877btCoreSpec = pTriple[3];878if (BT_PROFILE_SCO == btProfile)879pBtMgnt->ExtConfig.NumberOfSCO++;880else {881pBtMgnt->ExtConfig.NumberOfACL++;882pBtMgnt->ExtConfig.aclLink[i].ConnectHandle = conHandle;883pBtMgnt->ExtConfig.aclLink[i].BTProfile = btProfile;884pBtMgnt->ExtConfig.aclLink[i].BTCoreSpec = btCoreSpec;885}886/* RT_DISP(FIOCTL, IOCTL_BT_HCICMD_EXT, */887/* ("Connection_Handle=0x%x, BTProfile=%d, BTSpec=%d\n", */888/* conHandle, btProfile, btCoreSpec)); */889RTW_INFO("Connection_Handle=0x%x, BTProfile=%d, BTSpec=%d\n", conHandle, btProfile, btCoreSpec);890pTriple += 4;891} else if (pBtMgnt->ExtConfig.HCIExtensionVer >= 1) {892conHandle = *((u16 *)&pTriple[0]);893btProfile = pTriple[2];894btCoreSpec = pTriple[3];895linkRole = pTriple[4];896if (BT_PROFILE_SCO == btProfile)897pBtMgnt->ExtConfig.NumberOfSCO++;898else {899pBtMgnt->ExtConfig.NumberOfACL++;900pBtMgnt->ExtConfig.aclLink[i].ConnectHandle = conHandle;901pBtMgnt->ExtConfig.aclLink[i].BTProfile = btProfile;902pBtMgnt->ExtConfig.aclLink[i].BTCoreSpec = btCoreSpec;903pBtMgnt->ExtConfig.aclLink[i].linkRole = linkRole;904}905/* RT_DISP(FIOCTL, IOCTL_BT_HCICMD_EXT, */906RTW_INFO("Connection_Handle=0x%x, BTProfile=%d, BTSpec=%d, LinkRole=%d\n",907conHandle, btProfile, btCoreSpec, linkRole);908pTriple += 5;909}910}911rtw_btcoex_StackUpdateProfileInfo();912913/* send complete event to BT */914{915pEvent = (rtw_HCI_event *)(&localBuf[0]);916917918pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;919pEvent->Data[0] = 0x1; /* packet # */920pEvent->Data[1] = HCIOPCODELOW(HCI_LINK_STATUS_NOTIFY, OGF_EXTENSION);921pEvent->Data[2] = HCIOPCODEHIGHT(HCI_LINK_STATUS_NOTIFY, OGF_EXTENSION);922len = len + 3;923924/* Return parameters starts from here */925pRetPar = &pEvent->Data[len];926pRetPar[0] = status; /* status */927928len++;929pEvent->Length = len;930931/* total tx event length + EventCode length + sizeof(length) */932tx_event_length = pEvent->Length + 2;933934status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);935return status;936/* bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); */937}938939940}941942u8 rtw_btcoex_parse_HCI_BT_coex_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)943{944u8 localBuf[6] = "";945u8 *pRetPar;946u8 len = 0, tx_event_length = 0;947rtw_HCI_event *pEvent;948RTW_HCI_STATUS status = HCI_STATUS_SUCCESS;949950{951pEvent = (rtw_HCI_event *)(&localBuf[0]);952953954pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;955pEvent->Data[0] = 0x1; /* packet # */956pEvent->Data[1] = HCIOPCODELOW(HCI_BT_COEX_NOTIFY, OGF_EXTENSION);957pEvent->Data[2] = HCIOPCODEHIGHT(HCI_BT_COEX_NOTIFY, OGF_EXTENSION);958len = len + 3;959960/* Return parameters starts from here */961pRetPar = &pEvent->Data[len];962pRetPar[0] = status; /* status */963964len++;965pEvent->Length = len;966967/* total tx event length + EventCode length + sizeof(length) */968tx_event_length = pEvent->Length + 2;969970status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);971return status;972/* bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); */973}974}975976u8 rtw_btcoex_parse_HCI_BT_operation_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)977{978u8 localBuf[6] = "";979u8 *pRetPar;980u8 len = 0, tx_event_length = 0;981rtw_HCI_event *pEvent;982RTW_HCI_STATUS status = HCI_STATUS_SUCCESS;983984RTW_INFO("%s, OP code: %d\n", __func__, pcmd[0]);985986switch (pcmd[0]) {987case HCI_BT_OP_NONE:988RTW_INFO("[bt operation] : Operation None!!\n");989break;990case HCI_BT_OP_INQUIRY_START:991RTW_INFO("[bt operation] : Inquiry start!!\n");992break;993case HCI_BT_OP_INQUIRY_FINISH:994RTW_INFO("[bt operation] : Inquiry finished!!\n");995break;996case HCI_BT_OP_PAGING_START:997RTW_INFO("[bt operation] : Paging is started!!\n");998break;999case HCI_BT_OP_PAGING_SUCCESS:1000RTW_INFO("[bt operation] : Paging complete successfully!!\n");1001break;1002case HCI_BT_OP_PAGING_UNSUCCESS:1003RTW_INFO("[bt operation] : Paging complete unsuccessfully!!\n");1004break;1005case HCI_BT_OP_PAIRING_START:1006RTW_INFO("[bt operation] : Pairing start!!\n");1007break;1008case HCI_BT_OP_PAIRING_FINISH:1009RTW_INFO("[bt operation] : Pairing finished!!\n");1010break;1011case HCI_BT_OP_BT_DEV_ENABLE:1012RTW_INFO("[bt operation] : BT Device is enabled!!\n");1013break;1014case HCI_BT_OP_BT_DEV_DISABLE:1015RTW_INFO("[bt operation] : BT Device is disabled!!\n");1016break;1017default:1018RTW_INFO("[bt operation] : Unknown, error!!\n");1019break;1020}10211022/* send complete event to BT */1023{1024pEvent = (rtw_HCI_event *)(&localBuf[0]);102510261027pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;1028pEvent->Data[0] = 0x1; /* packet # */1029pEvent->Data[1] = HCIOPCODELOW(HCI_BT_OPERATION_NOTIFY, OGF_EXTENSION);1030pEvent->Data[2] = HCIOPCODEHIGHT(HCI_BT_OPERATION_NOTIFY, OGF_EXTENSION);1031len = len + 3;10321033/* Return parameters starts from here */1034pRetPar = &pEvent->Data[len];1035pRetPar[0] = status; /* status */10361037len++;1038pEvent->Length = len;10391040/* total tx event length + EventCode length + sizeof(length) */1041tx_event_length = pEvent->Length + 2;10421043status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);1044return status;1045/* bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); */1046}1047}10481049u8 rtw_btcoex_parse_BT_AFH_MAP_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)1050{1051u8 localBuf[6] = "";1052u8 *pRetPar;1053u8 len = 0, tx_event_length = 0;1054rtw_HCI_event *pEvent;1055RTW_HCI_STATUS status = HCI_STATUS_SUCCESS;10561057{1058pEvent = (rtw_HCI_event *)(&localBuf[0]);105910601061pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;1062pEvent->Data[0] = 0x1; /* packet # */1063pEvent->Data[1] = HCIOPCODELOW(HCI_BT_AFH_MAP_NOTIFY, OGF_EXTENSION);1064pEvent->Data[2] = HCIOPCODEHIGHT(HCI_BT_AFH_MAP_NOTIFY, OGF_EXTENSION);1065len = len + 3;10661067/* Return parameters starts from here */1068pRetPar = &pEvent->Data[len];1069pRetPar[0] = status; /* status */10701071len++;1072pEvent->Length = len;10731074/* total tx event length + EventCode length + sizeof(length) */1075tx_event_length = pEvent->Length + 2;10761077status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);1078return status;1079/* bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); */1080}1081}10821083u8 rtw_btcoex_parse_BT_register_val_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)1084{10851086u8 localBuf[6] = "";1087u8 *pRetPar;1088u8 len = 0, tx_event_length = 0;1089rtw_HCI_event *pEvent;1090RTW_HCI_STATUS status = HCI_STATUS_SUCCESS;10911092{1093pEvent = (rtw_HCI_event *)(&localBuf[0]);109410951096pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;1097pEvent->Data[0] = 0x1; /* packet # */1098pEvent->Data[1] = HCIOPCODELOW(HCI_BT_REGISTER_VALUE_NOTIFY, OGF_EXTENSION);1099pEvent->Data[2] = HCIOPCODEHIGHT(HCI_BT_REGISTER_VALUE_NOTIFY, OGF_EXTENSION);1100len = len + 3;11011102/* Return parameters starts from here */1103pRetPar = &pEvent->Data[len];1104pRetPar[0] = status; /* status */11051106len++;1107pEvent->Length = len;11081109/* total tx event length + EventCode length + sizeof(length) */1110tx_event_length = pEvent->Length + 2;11111112status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);1113return status;1114/* bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); */1115}1116}11171118u8 rtw_btcoex_parse_HCI_BT_abnormal_notify_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)1119{1120u8 localBuf[6] = "";1121u8 *pRetPar;1122u8 len = 0, tx_event_length = 0;1123rtw_HCI_event *pEvent;1124RTW_HCI_STATUS status = HCI_STATUS_SUCCESS;11251126{1127pEvent = (rtw_HCI_event *)(&localBuf[0]);112811291130pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;1131pEvent->Data[0] = 0x1; /* packet # */1132pEvent->Data[1] = HCIOPCODELOW(HCI_BT_ABNORMAL_NOTIFY, OGF_EXTENSION);1133pEvent->Data[2] = HCIOPCODEHIGHT(HCI_BT_ABNORMAL_NOTIFY, OGF_EXTENSION);1134len = len + 3;11351136/* Return parameters starts from here */1137pRetPar = &pEvent->Data[len];1138pRetPar[0] = status; /* status */11391140len++;1141pEvent->Length = len;11421143/* total tx event length + EventCode length + sizeof(length) */1144tx_event_length = pEvent->Length + 2;11451146status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);1147return status;1148/* bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); */1149}1150}11511152u8 rtw_btcoex_parse_HCI_query_RF_status_cmd(_adapter *padapter, u8 *pcmd, u16 cmdlen)1153{1154u8 localBuf[6] = "";1155u8 *pRetPar;1156u8 len = 0, tx_event_length = 0;1157rtw_HCI_event *pEvent;1158RTW_HCI_STATUS status = HCI_STATUS_SUCCESS;11591160{1161pEvent = (rtw_HCI_event *)(&localBuf[0]);116211631164pEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;1165pEvent->Data[0] = 0x1; /* packet # */1166pEvent->Data[1] = HCIOPCODELOW(HCI_QUERY_RF_STATUS, OGF_EXTENSION);1167pEvent->Data[2] = HCIOPCODEHIGHT(HCI_QUERY_RF_STATUS, OGF_EXTENSION);1168len = len + 3;11691170/* Return parameters starts from here */1171pRetPar = &pEvent->Data[len];1172pRetPar[0] = status; /* status */11731174len++;1175pEvent->Length = len;11761177/* total tx event length + EventCode length + sizeof(length) */1178tx_event_length = pEvent->Length + 2;11791180status = rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);1181return status;1182/* bthci_IndicateEvent(Adapter, PPacketIrpEvent, len+2); */1183}1184}11851186/*****************************************1187* HCI cmd format :1188*| 15 - 0 |1189*| OPcode (OCF|OGF<<10) |1190*| 15 - 8 |7 - 0 |1191*|Cmd para |Cmd para Length |1192*|Cmd para...... |1193******************************************/11941195/* bit 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 151196* | OCF | OGF | */1197void rtw_btcoex_parse_hci_extend_cmd(_adapter *padapter, u8 *pcmd, u16 len, const u16 hci_OCF)1198{11991200RTW_INFO("%s: OCF: %x\n", __func__, hci_OCF);1201switch (hci_OCF) {1202case HCI_EXTENSION_VERSION_NOTIFY:1203RTW_INFO("HCI_EXTENSION_VERSION_NOTIFY\n");1204rtw_btcoex_parse_HCI_Ver_notify_cmd(padapter, pcmd, len);1205break;1206case HCI_LINK_STATUS_NOTIFY:1207RTW_INFO("HCI_LINK_STATUS_NOTIFY\n");1208rtw_btcoex_parse_HCI_link_status_notify_cmd(padapter, pcmd, len);1209break;1210case HCI_BT_OPERATION_NOTIFY:1211/* only for 8723a 2ant */1212RTW_INFO("HCI_BT_OPERATION_NOTIFY\n");1213rtw_btcoex_parse_HCI_BT_operation_notify_cmd(padapter, pcmd, len);1214/* */1215break;1216case HCI_ENABLE_WIFI_SCAN_NOTIFY:1217RTW_INFO("HCI_ENABLE_WIFI_SCAN_NOTIFY\n");1218rtw_btcoex_parse_WIFI_scan_notify_cmd(padapter, pcmd, len);1219break;1220case HCI_QUERY_RF_STATUS:1221/* only for 8723b 2ant */1222RTW_INFO("HCI_QUERY_RF_STATUS\n");1223rtw_btcoex_parse_HCI_query_RF_status_cmd(padapter, pcmd, len);1224break;1225case HCI_BT_ABNORMAL_NOTIFY:1226RTW_INFO("HCI_BT_ABNORMAL_NOTIFY\n");1227rtw_btcoex_parse_HCI_BT_abnormal_notify_cmd(padapter, pcmd, len);1228break;1229case HCI_BT_INFO_NOTIFY:1230RTW_INFO("HCI_BT_INFO_NOTIFY\n");1231rtw_btcoex_parse_BT_info_notify_cmd(padapter, pcmd, len);1232break;1233case HCI_BT_COEX_NOTIFY:1234RTW_INFO("HCI_BT_COEX_NOTIFY\n");1235rtw_btcoex_parse_HCI_BT_coex_notify_cmd(padapter, pcmd, len);1236break;1237case HCI_BT_PATCH_VERSION_NOTIFY:1238RTW_INFO("HCI_BT_PATCH_VERSION_NOTIFY\n");1239rtw_btcoex_parse_BT_patch_ver_info_cmd(padapter, pcmd, len);1240break;1241case HCI_BT_AFH_MAP_NOTIFY:1242RTW_INFO("HCI_BT_AFH_MAP_NOTIFY\n");1243rtw_btcoex_parse_BT_AFH_MAP_notify_cmd(padapter, pcmd, len);1244break;1245case HCI_BT_REGISTER_VALUE_NOTIFY:1246RTW_INFO("HCI_BT_REGISTER_VALUE_NOTIFY\n");1247rtw_btcoex_parse_BT_register_val_notify_cmd(padapter, pcmd, len);1248break;1249default:1250RTW_INFO("ERROR!!! Unknown OCF: %x\n", hci_OCF);1251break;12521253}1254}12551256void rtw_btcoex_parse_hci_cmd(_adapter *padapter, u8 *pcmd, u16 len)1257{1258u16 opcode = pcmd[0] | pcmd[1] << 8;1259u16 hci_OGF = HCI_OGF(opcode);1260u16 hci_OCF = HCI_OCF(opcode);1261u8 cmdlen = len - 3;1262u8 pare_len = pcmd[2];12631264RTW_INFO("%s OGF: %x,OCF: %x\n", __func__, hci_OGF, hci_OCF);1265switch (hci_OGF) {1266case OGF_EXTENSION:1267RTW_INFO("HCI_EXTENSION_CMD_OGF\n");1268rtw_btcoex_parse_hci_extend_cmd(padapter, &pcmd[3], cmdlen, hci_OCF);1269break;1270default:1271RTW_INFO("Other OGF: %x\n", hci_OGF);1272break;1273}1274}12751276u16 rtw_btcoex_parse_recv_data(u8 *msg, u8 msg_size)1277{1278u8 cmp_msg1[32] = attend_ack;1279u8 cmp_msg2[32] = leave_ack;1280u8 cmp_msg3[32] = bt_leave;1281u8 cmp_msg4[32] = invite_req;1282u8 cmp_msg5[32] = attend_req;1283u8 cmp_msg6[32] = invite_rsp;1284u8 res = OTHER;12851286if (_rtw_memcmp(cmp_msg1, msg, msg_size) == _TRUE) {1287/*RTW_INFO("%s, msg:%s\n",__func__,msg);*/1288res = RX_ATTEND_ACK;1289} else if (_rtw_memcmp(cmp_msg2, msg, msg_size) == _TRUE) {1290/*RTW_INFO("%s, msg:%s\n",__func__,msg);*/1291res = RX_LEAVE_ACK;1292} else if (_rtw_memcmp(cmp_msg3, msg, msg_size) == _TRUE) {1293/*RTW_INFO("%s, msg:%s\n",__func__,msg);*/1294res = RX_BT_LEAVE;1295} else if (_rtw_memcmp(cmp_msg4, msg, msg_size) == _TRUE) {1296/*RTW_INFO("%s, msg:%s\n",__func__,msg);*/1297res = RX_INVITE_REQ;1298} else if (_rtw_memcmp(cmp_msg5, msg, msg_size) == _TRUE)1299res = RX_ATTEND_REQ;1300else if (_rtw_memcmp(cmp_msg6, msg, msg_size) == _TRUE)1301res = RX_INVITE_RSP;1302else {1303/*RTW_INFO("%s, %s\n", __func__, msg);*/1304res = OTHER;1305}13061307/*RTW_INFO("%s, res:%d\n", __func__, res);*/13081309return res;1310}13111312void rtw_btcoex_recvmsgbysocket(void *data)1313{1314u8 recv_data[255];1315u8 tx_msg[255] = leave_ack;1316u32 len = 0;1317u16 recv_length = 0;1318u16 parse_res = 0;1319#if 01320u8 para_len = 0, polling_enable = 0, poling_interval = 0, reason = 0, btinfo_len = 0;1321u8 btinfo[BT_INFO_LEN] = {0};1322#endif13231324struct bt_coex_info *pcoex_info = NULL;1325struct sock *sk = NULL;1326struct sk_buff *skb = NULL;13271328/*RTW_INFO("%s\n",__func__);*/13291330if (pbtcoexadapter == NULL) {1331RTW_INFO("%s: btcoexadapter NULL!\n", __func__);1332return;1333}13341335pcoex_info = &pbtcoexadapter->coex_info;1336sk = pcoex_info->sk_store;13371338if (sk == NULL) {1339RTW_INFO("%s: critical error when receive socket data!\n", __func__);1340return;1341}13421343len = skb_queue_len(&sk->sk_receive_queue);1344while (len > 0) {1345skb = skb_dequeue(&sk->sk_receive_queue);13461347/*important: cut the udp header from skb->data! header length is 8 byte*/1348recv_length = skb->len - 8;1349_rtw_memset(recv_data, 0, sizeof(recv_data));1350_rtw_memcpy(recv_data, skb->data + 8, recv_length);13511352parse_res = rtw_btcoex_parse_recv_data(recv_data, recv_length);1353#if 01354if (RX_ATTEND_ACK == parse_res) {1355/* attend ack */1356pcoex_info->BT_attend = _TRUE;1357RTW_INFO("RX_ATTEND_ACK!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);1358} else if (RX_ATTEND_REQ == parse_res) {1359/* attend req from BT */1360pcoex_info->BT_attend = _TRUE;1361RTW_INFO("RX_BT_ATTEND_REQ!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);1362rtw_btcoex_sendmsgbysocket(pbtcoexadapter, attend_ack, sizeof(attend_ack), _FALSE);1363} else if (RX_INVITE_REQ == parse_res) {1364/* invite req from BT */1365pcoex_info->BT_attend = _TRUE;1366RTW_INFO("RX_INVITE_REQ!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);1367rtw_btcoex_sendmsgbysocket(pbtcoexadapter, invite_rsp, sizeof(invite_rsp), _FALSE);1368} else if (RX_INVITE_RSP == parse_res) {1369/* invite rsp */1370pcoex_info->BT_attend = _TRUE;1371RTW_INFO("RX_INVITE_RSP!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);1372} else if (RX_LEAVE_ACK == parse_res) {1373/* mean BT know wifi will leave */1374pcoex_info->BT_attend = _FALSE;1375RTW_INFO("RX_LEAVE_ACK!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);1376} else if (RX_BT_LEAVE == parse_res) {1377/* BT leave */1378rtw_btcoex_sendmsgbysocket(pbtcoexadapter, leave_ack, sizeof(leave_ack), _FALSE); /* no ack */1379pcoex_info->BT_attend = _FALSE;1380RTW_INFO("RX_BT_LEAVE!sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);1381} else {1382/* todo: check if recv data are really hci cmds */1383if (_TRUE == pcoex_info->BT_attend)1384rtw_btcoex_parse_hci_cmd(pbtcoexadapter, recv_data, recv_length);1385}1386#endif1387switch (parse_res) {1388case RX_ATTEND_ACK:1389/* attend ack */1390pcoex_info->BT_attend = _TRUE;1391RTW_INFO("RX_ATTEND_ACK!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);1392rtw_btcoex_pta_off_on_notify(pbtcoexadapter, pcoex_info->BT_attend);1393break;13941395case RX_ATTEND_REQ:1396pcoex_info->BT_attend = _TRUE;1397RTW_INFO("RX_BT_ATTEND_REQ!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);1398rtw_btcoex_sendmsgbysocket(pbtcoexadapter, attend_ack, sizeof(attend_ack), _FALSE);1399rtw_btcoex_pta_off_on_notify(pbtcoexadapter, pcoex_info->BT_attend);1400break;14011402case RX_INVITE_REQ:1403/* invite req from BT */1404pcoex_info->BT_attend = _TRUE;1405RTW_INFO("RX_INVITE_REQ!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);1406rtw_btcoex_sendmsgbysocket(pbtcoexadapter, invite_rsp, sizeof(invite_rsp), _FALSE);1407rtw_btcoex_pta_off_on_notify(pbtcoexadapter, pcoex_info->BT_attend);1408break;14091410case RX_INVITE_RSP:1411/*invite rsp*/1412pcoex_info->BT_attend = _TRUE;1413RTW_INFO("RX_INVITE_RSP!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);1414rtw_btcoex_pta_off_on_notify(pbtcoexadapter, pcoex_info->BT_attend);1415break;14161417case RX_LEAVE_ACK:1418/* mean BT know wifi will leave */1419pcoex_info->BT_attend = _FALSE;1420RTW_INFO("RX_LEAVE_ACK!,sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);1421rtw_btcoex_pta_off_on_notify(pbtcoexadapter, pcoex_info->BT_attend);1422break;14231424case RX_BT_LEAVE:1425/* BT leave */1426rtw_btcoex_sendmsgbysocket(pbtcoexadapter, leave_ack, sizeof(leave_ack), _FALSE); /* no ack */1427pcoex_info->BT_attend = _FALSE;1428RTW_INFO("RX_BT_LEAVE!sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);1429rtw_btcoex_pta_off_on_notify(pbtcoexadapter, pcoex_info->BT_attend);1430break;14311432default:1433if (_TRUE == pcoex_info->BT_attend)1434rtw_btcoex_parse_hci_cmd(pbtcoexadapter, recv_data, recv_length);1435else1436RTW_INFO("ERROR!! BT is UP\n");1437break;14381439}14401441len--;1442kfree_skb(skb);1443}1444}14451446#if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 15, 0))1447void rtw_btcoex_recvmsg_init(struct sock *sk_in, s32 bytes)1448#else1449void rtw_btcoex_recvmsg_init(struct sock *sk_in)1450#endif1451{1452struct bt_coex_info *pcoex_info = NULL;14531454if (pbtcoexadapter == NULL) {1455RTW_INFO("%s: btcoexadapter NULL\n", __func__);1456return;1457}1458pcoex_info = &pbtcoexadapter->coex_info;1459pcoex_info->sk_store = sk_in;1460if (pcoex_info->btcoex_wq != NULL)1461queue_delayed_work(pcoex_info->btcoex_wq, &pcoex_info->recvmsg_work, 0);1462else1463RTW_INFO("%s: BTCOEX workqueue NULL\n", __func__);1464}14651466u8 rtw_btcoex_sendmsgbysocket(_adapter *padapter, u8 *msg, u8 msg_size, bool force)1467{1468u8 error;1469struct msghdr udpmsg;1470#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0))1471mm_segment_t oldfs;1472#endif1473struct iovec iov;1474struct bt_coex_info *pcoex_info = &padapter->coex_info;14751476/* RTW_INFO("%s: msg:%s, force:%s\n", __func__, msg, force == _TRUE?"TRUE":"FALSE"); */1477if (_FALSE == force) {1478if (_FALSE == pcoex_info->BT_attend) {1479RTW_INFO("TX Blocked: WiFi-BT disconnected\n");1480return _FAIL;1481}1482}14831484iov.iov_base = (void *)msg;1485iov.iov_len = msg_size;1486udpmsg.msg_name = &pcoex_info->bt_sockaddr;1487udpmsg.msg_namelen = sizeof(struct sockaddr_in);1488#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0))1489/* referece:sock_xmit in kernel code1490* WRITE for sock_sendmsg, READ for sock_recvmsg1491* third parameter for msg_iovlen1492* last parameter for iov_len1493*/1494iov_iter_init(&udpmsg.msg_iter, WRITE, &iov, 1, msg_size);1495#else1496udpmsg.msg_iov = &iov;1497udpmsg.msg_iovlen = 1;1498#endif1499udpmsg.msg_control = NULL;1500udpmsg.msg_controllen = 0;1501udpmsg.msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL;1502#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0))1503oldfs = get_fs();1504set_fs(KERNEL_DS);1505#endif15061507#if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0))1508error = sock_sendmsg(pcoex_info->udpsock, &udpmsg);1509#else1510error = sock_sendmsg(pcoex_info->udpsock, &udpmsg, msg_size);1511#endif1512#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 10, 0))1513set_fs(oldfs);1514#endif1515if (error < 0) {1516RTW_INFO("Error when sendimg msg, error:%d\n", error);1517return _FAIL;1518} else1519return _SUCCESS;1520}15211522u8 rtw_btcoex_create_kernel_socket(_adapter *padapter)1523{1524s8 kernel_socket_err;1525u8 tx_msg[255] = attend_req;1526struct bt_coex_info *pcoex_info = &padapter->coex_info;1527s32 sock_reuse = 1;1528u8 status = _FAIL;15291530RTW_INFO("%s CONNECT_PORT %d\n", __func__, CONNECT_PORT);15311532if (NULL == pcoex_info) {1533RTW_INFO("coex_info: NULL\n");1534status = _FAIL;1535}15361537kernel_socket_err = sock_create(PF_INET, SOCK_DGRAM, 0, &pcoex_info->udpsock);15381539if (kernel_socket_err < 0) {1540RTW_INFO("Error during creation of socket error:%d\n", kernel_socket_err);1541status = _FAIL;1542} else {1543_rtw_memset(&(pcoex_info->wifi_sockaddr), 0, sizeof(pcoex_info->wifi_sockaddr));1544pcoex_info->wifi_sockaddr.sin_family = AF_INET;1545pcoex_info->wifi_sockaddr.sin_port = htons(CONNECT_PORT);1546pcoex_info->wifi_sockaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);15471548_rtw_memset(&(pcoex_info->bt_sockaddr), 0, sizeof(pcoex_info->bt_sockaddr));1549pcoex_info->bt_sockaddr.sin_family = AF_INET;1550pcoex_info->bt_sockaddr.sin_port = htons(CONNECT_PORT_BT);1551pcoex_info->bt_sockaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);15521553pcoex_info->sk_store = NULL;1554kernel_socket_err = pcoex_info->udpsock->ops->bind(pcoex_info->udpsock, (struct sockaddr *)&pcoex_info->wifi_sockaddr,1555sizeof(pcoex_info->wifi_sockaddr));1556if (kernel_socket_err == 0) {1557RTW_INFO("binding socket success\n");1558pcoex_info->udpsock->sk->sk_data_ready = rtw_btcoex_recvmsg_init;1559pcoex_info->sock_open |= KERNEL_SOCKET_OK;1560pcoex_info->BT_attend = _FALSE;1561RTW_INFO("WIFI sending attend_req\n");1562rtw_btcoex_sendmsgbysocket(padapter, attend_req, sizeof(attend_req), _TRUE);1563status = _SUCCESS;1564} else {1565pcoex_info->BT_attend = _FALSE;1566sock_release(pcoex_info->udpsock); /* bind fail release socket */1567RTW_INFO("Error binding socket: %d\n", kernel_socket_err);1568status = _FAIL;1569}15701571}15721573return status;1574}15751576void rtw_btcoex_close_kernel_socket(_adapter *padapter)1577{1578struct bt_coex_info *pcoex_info = &padapter->coex_info;1579if (pcoex_info->sock_open & KERNEL_SOCKET_OK) {1580RTW_INFO("release kernel socket\n");1581sock_release(pcoex_info->udpsock);1582pcoex_info->sock_open &= ~(KERNEL_SOCKET_OK);1583if (_TRUE == pcoex_info->BT_attend)1584pcoex_info->BT_attend = _FALSE;15851586RTW_INFO("sock_open:%d, BT_attend:%d\n", pcoex_info->sock_open, pcoex_info->BT_attend);1587}1588}15891590void rtw_btcoex_init_socket(_adapter *padapter)1591{15921593u8 is_invite = _FALSE;1594struct bt_coex_info *pcoex_info = &padapter->coex_info;1595RTW_INFO("%s\n", __func__);1596if (_FALSE == pcoex_info->is_exist) {1597_rtw_memset(pcoex_info, 0, sizeof(struct bt_coex_info));1598pcoex_info->btcoex_wq = create_workqueue("BTCOEX");1599INIT_DELAYED_WORK(&pcoex_info->recvmsg_work,1600(void *)rtw_btcoex_recvmsgbysocket);1601pbtcoexadapter = padapter;1602/* We expect BT is off if BT don't send ack to wifi */1603RTW_INFO("We expect BT is off if BT send ack to wifi\n");1604rtw_btcoex_pta_off_on_notify(pbtcoexadapter, _FALSE);1605if (rtw_btcoex_create_kernel_socket(padapter) == _SUCCESS)1606pcoex_info->is_exist = _TRUE;1607else {1608pcoex_info->is_exist = _FALSE;1609pbtcoexadapter = NULL;1610}16111612RTW_INFO("%s: pbtcoexadapter:%p, coex_info->is_exist: %s\n"1613, __func__, pbtcoexadapter, pcoex_info->is_exist == _TRUE ? "TRUE" : "FALSE");1614}1615}16161617void rtw_btcoex_close_socket(_adapter *padapter)1618{1619struct bt_coex_info *pcoex_info = &padapter->coex_info;16201621RTW_INFO("%s--coex_info->is_exist: %s, pcoex_info->BT_attend:%s\n"1622, __func__, pcoex_info->is_exist == _TRUE ? "TRUE" : "FALSE", pcoex_info->BT_attend == _TRUE ? "TRUE" : "FALSE");16231624if (_TRUE == pcoex_info->is_exist) {1625if (_TRUE == pcoex_info->BT_attend) {1626/*inform BT wifi leave*/1627rtw_btcoex_sendmsgbysocket(padapter, wifi_leave, sizeof(wifi_leave), _FALSE);1628msleep(50);1629}16301631if (pcoex_info->btcoex_wq != NULL) {1632flush_workqueue(pcoex_info->btcoex_wq);1633destroy_workqueue(pcoex_info->btcoex_wq);1634}16351636rtw_btcoex_close_kernel_socket(padapter);1637pbtcoexadapter = NULL;1638pcoex_info->is_exist = _FALSE;1639}1640}16411642void rtw_btcoex_dump_tx_msg(u8 *tx_msg, u8 len, u8 *msg_name)1643{1644u8 i = 0;1645RTW_INFO("======> Msg name: %s\n", msg_name);1646for (i = 0; i < len; i++)1647printk("%02x ", tx_msg[i]);1648printk("\n");1649RTW_INFO("Msg name: %s <======\n", msg_name);1650}16511652/* Porting from Windows team */1653void rtw_btcoex_SendEventExtBtCoexControl(PADAPTER padapter, u8 bNeedDbgRsp, u8 dataLen, void *pData)1654{1655u8 len = 0, tx_event_length = 0;1656u8 localBuf[32] = "";1657u8 *pRetPar;1658u8 opCode = 0;1659u8 *pInBuf = (u8 *)pData;1660u8 *pOpCodeContent;1661rtw_HCI_event *pEvent;16621663opCode = pInBuf[0];16641665RTW_INFO("%s, OPCode:%02x\n", __func__, opCode);16661667pEvent = (rtw_HCI_event *)(&localBuf[0]);16681669/* len += bthci_ExtensionEventHeaderRtk(&localBuf[0], */1670/* HCI_EVENT_EXT_BT_COEX_CONTROL); */1671pEvent->EventCode = HCI_EVENT_EXTENSION_RTK;1672pEvent->Data[0] = HCI_EVENT_EXT_BT_COEX_CONTROL; /* extension event code */1673len++;16741675/* Return parameters starts from here */1676pRetPar = &pEvent->Data[len];1677_rtw_memcpy(&pRetPar[0], pData, dataLen);16781679len += dataLen;16801681pEvent->Length = len;16821683/* total tx event length + EventCode length + sizeof(length) */1684tx_event_length = pEvent->Length + 2;1685#if 01686rtw_btcoex_dump_tx_msg((u8 *)pEvent, tx_event_length, "BT COEX CONTROL", _FALSE);1687#endif1688rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);16891690}16911692/* Porting from Windows team */1693void rtw_btcoex_SendEventExtBtInfoControl(PADAPTER padapter, u8 dataLen, void *pData)1694{1695rtw_HCI_event *pEvent;1696u8 *pRetPar;1697u8 len = 0, tx_event_length = 0;1698u8 localBuf[32] = "";16991700struct bt_coex_info *pcoex_info = &padapter->coex_info;1701PBT_MGNT pBtMgnt = &pcoex_info->BtMgnt;17021703/* RTW_INFO("%s\n",__func__);*/1704if (pBtMgnt->ExtConfig.HCIExtensionVer < 4) { /* not support */1705RTW_INFO("ERROR: HCIExtensionVer = %d, HCIExtensionVer<4 !!!!\n", pBtMgnt->ExtConfig.HCIExtensionVer);1706return;1707}17081709pEvent = (rtw_HCI_event *)(&localBuf[0]);17101711/* len += bthci_ExtensionEventHeaderRtk(&localBuf[0], */1712/* HCI_EVENT_EXT_BT_INFO_CONTROL); */1713pEvent->EventCode = HCI_EVENT_EXTENSION_RTK;1714pEvent->Data[0] = HCI_EVENT_EXT_BT_INFO_CONTROL; /* extension event code */1715len++;17161717/* Return parameters starts from here */1718pRetPar = &pEvent->Data[len];1719_rtw_memcpy(&pRetPar[0], pData, dataLen);17201721len += dataLen;17221723pEvent->Length = len;17241725/* total tx event length + EventCode length + sizeof(length) */1726tx_event_length = pEvent->Length + 2;1727#if 01728rtw_btcoex_dump_tx_msg((u8 *)pEvent, tx_event_length, "BT INFO CONTROL");1729#endif1730rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);17311732}17331734void rtw_btcoex_SendScanNotify(PADAPTER padapter, u8 scanType)1735{1736u8 len = 0, tx_event_length = 0;1737u8 localBuf[7] = "";1738u8 *pRetPar;1739u8 *pu1Temp;1740rtw_HCI_event *pEvent;1741struct bt_coex_info *pcoex_info = &padapter->coex_info;1742PBT_MGNT pBtMgnt = &pcoex_info->BtMgnt;17431744/* if(!pBtMgnt->BtOperationOn)1745* return; */17461747pEvent = (rtw_HCI_event *)(&localBuf[0]);17481749/* len += bthci_ExtensionEventHeaderRtk(&localBuf[0],1750* HCI_EVENT_EXT_WIFI_SCAN_NOTIFY); */17511752pEvent->EventCode = HCI_EVENT_EXTENSION_RTK;1753pEvent->Data[0] = HCI_EVENT_EXT_WIFI_SCAN_NOTIFY; /* extension event code */1754len++;17551756/* Return parameters starts from here */1757/* pRetPar = &PPacketIrpEvent->Data[len]; */1758/* pu1Temp = (u8 *)&pRetPar[0]; */1759/* *pu1Temp = scanType; */1760pEvent->Data[len] = scanType;1761len += 1;17621763pEvent->Length = len;17641765/* total tx event length + EventCode length + sizeof(length) */1766tx_event_length = pEvent->Length + 2;1767#if 01768rtw_btcoex_dump_tx_msg((u8 *)pEvent, tx_event_length, "WIFI SCAN OPERATION");1769#endif1770rtw_btcoex_sendmsgbysocket(padapter, (u8 *)pEvent, tx_event_length, _FALSE);1771}1772#endif /* CONFIG_BT_COEXIST_SOCKET_TRX */1773#endif /* CONFIG_BT_COEXIST */17741775void rtw_btcoex_set_ant_info(PADAPTER padapter)1776{1777#ifdef CONFIG_BT_COEXIST1778PHAL_DATA_TYPE hal = GET_HAL_DATA(padapter);17791780if (hal->EEPROMBluetoothCoexist == _TRUE) {1781u8 bMacPwrCtrlOn = _FALSE;17821783rtw_btcoex_AntInfoSetting(padapter);1784rtw_hal_get_hwreg(padapter, HW_VAR_APFM_ON_MAC, &bMacPwrCtrlOn);1785if (bMacPwrCtrlOn == _TRUE)1786rtw_btcoex_PowerOnSetting(padapter);1787}1788else1789#endif1790rtw_btcoex_wifionly_AntInfoSetting(padapter);1791}1792179317941795