Path: blob/master/ALFA-W1F1/RTL8814AU/hal/rtl8814a/rtl8814a_cmd.c
1307 views
/******************************************************************************1*2* Copyright(c) 2007 - 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#define _RTL8814A_CMD_C_1516/* #include <drv_types.h> */17#include <rtl8814a_hal.h>1819#define CONFIG_H2C_EF2021#define RTL8814_MAX_H2C_BOX_NUMS 422#define RTL8814_MAX_CMD_LEN 723#define RTL8814_MESSAGE_BOX_SIZE 424#define RTL8814_EX_MESSAGE_BOX_SIZE 4252627static u8 _is_fw_read_cmd_down(_adapter *padapter, u8 msgbox_num)28{29u8 read_down = _FALSE;30int retry_cnts = 100;3132u8 valid;3334/* RTW_INFO(" _is_fw_read_cmd_down ,reg_1cc(%x),msg_box(%d)...\n",rtw_read8(padapter,REG_HMETFR),msgbox_num); */3536do {37valid = rtw_read8(padapter, REG_HMETFR) & BIT(msgbox_num);38if (0 == valid)39read_down = _TRUE;40else41rtw_msleep_os(1);42} while ((!read_down) && (retry_cnts--));4344return read_down;4546}474849/*****************************************50* H2C Msg format :51* 0x1DF - 0x1D052*| 31 - 8 | 7-5 4 - 0 |53*| h2c_msg |Class_ID CMD_ID |54*55* Extend 0x1FF - 0x1F056*|31 - 0 |57*|ext_msg|58******************************************/59s32 FillH2CCmd_8814(PADAPTER padapter, u8 ElementID, u32 CmdLen, u8 *pCmdBuffer)60{61u8 h2c_box_num;62u32 msgbox_addr;63u32 msgbox_ex_addr = 0;64HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);65u8 cmd_idx ;66u32 h2c_cmd = 0;67u32 h2c_cmd_ex = 0;68s32 ret = _FAIL;697071padapter = GET_PRIMARY_ADAPTER(padapter);72pHalData = GET_HAL_DATA(padapter);737475if (pHalData->bFWReady == _FALSE) {76/* RTW_INFO("FillH2CCmd_8814(): return H2C cmd because fw is not ready\n"); */77return ret;78}7980_enter_critical_mutex(&(adapter_to_dvobj(padapter)->h2c_fwcmd_mutex), NULL);818283if (!pCmdBuffer)84goto exit;8586if (CmdLen > RTL8814_MAX_CMD_LEN) {87RTW_WARN("%s, CmdLen: %d > %d, return!\n", __func__, CmdLen, RTL8814_MAX_CMD_LEN);88goto exit;89}9091if (rtw_is_surprise_removed(padapter))92goto exit;9394/* pay attention to if race condition happened in H2C cmd setting. */95do {96h2c_box_num = pHalData->LastHMEBoxNum;9798if (!_is_fw_read_cmd_down(padapter, h2c_box_num)) {99RTW_INFO(" fw read cmd failed...\n");100goto exit;101}102103*(u8 *)(&h2c_cmd) = ElementID;104105if (CmdLen <= 3) {106_rtw_memcpy((u8 *)(&h2c_cmd) + 1, pCmdBuffer, CmdLen);107h2c_cmd_ex = 0;108} else {109_rtw_memcpy((u8 *)(&h2c_cmd) + 1, pCmdBuffer, 3);110_rtw_memcpy((u8 *)(&h2c_cmd_ex), pCmdBuffer + 3, CmdLen - 3);111}112113/* Write Ext command */114msgbox_ex_addr = REG_HMEBOX_EXT0_8814A + (h2c_box_num * RTL8814_EX_MESSAGE_BOX_SIZE);115#ifdef CONFIG_H2C_EF116for (cmd_idx = 0; cmd_idx < RTL8814_MESSAGE_BOX_SIZE; cmd_idx++)117rtw_write8(padapter, msgbox_ex_addr + cmd_idx, *((u8 *)(&h2c_cmd_ex) + cmd_idx));118#else119h2c_cmd_ex = le32_to_cpu(h2c_cmd_ex);120rtw_write32(padapter, msgbox_ex_addr, h2c_cmd_ex);121#endif122123/* Write command */124msgbox_addr = REG_HMEBOX_0 + (h2c_box_num * RTL8814_MESSAGE_BOX_SIZE);125#ifdef CONFIG_H2C_EF126for (cmd_idx = 0; cmd_idx < RTL8814_MESSAGE_BOX_SIZE; cmd_idx++)127rtw_write8(padapter, msgbox_addr + cmd_idx, *((u8 *)(&h2c_cmd) + cmd_idx));128#else129h2c_cmd = le32_to_cpu(h2c_cmd);130rtw_write32(padapter, msgbox_addr, h2c_cmd);131#endif132133/* RTW_INFO("MSG_BOX:%d,CmdLen(%d), reg:0x%x =>h2c_cmd:0x%x, reg:0x%x =>h2c_cmd_ex:0x%x ..\n" */134/* ,pHalData->LastHMEBoxNum ,CmdLen,msgbox_addr,h2c_cmd,msgbox_ex_addr,h2c_cmd_ex); */135136pHalData->LastHMEBoxNum = (h2c_box_num + 1) % RTL8814_MAX_H2C_BOX_NUMS;137138} while (0);139140ret = _SUCCESS;141142exit:143144_exit_critical_mutex(&(adapter_to_dvobj(padapter)->h2c_fwcmd_mutex), NULL);145146147return ret;148}149#ifdef CONFIG_FW_CORRECT_BCN150void rtl8814_fw_update_beacon_cmd(_adapter *padapter)151{152u8 param[2] = {0};153u16 txpktbuf_bndy;154155156157SET_8814A_H2CCMD_BCNHWSEQ_EN(param, 1);158SET_8814A_H2CCMD_BCNHWSEQ_BCN_NUMBER(param, 0);159SET_8814A_H2CCMD_BCNHWSEQ_HWSEQ(param, 1);160SET_8814A_H2CCMD_BCNHWSEQ_EXHWSEQ(param, 0);161SET_8814A_H2CCMD_BCNHWSEQ_PAGE(param, 0);162if (GET_HAL_DATA(padapter)->firmware_version < 23)163/* FW v21, v22 use H2C_BCNHWSEQ = 0xC2 */164FillH2CCmd_8814(padapter, 0xC2, 2, param);165else166FillH2CCmd_8814(padapter, H2C_BCNHWSEQ, 2, param);167168/*RTW_INFO("%s, %d, correct beacon HW sequence, FirmwareVersion=%d, H2C_BCNHWSEQ=%d\n", __func__, __LINE__, GET_HAL_DATA(padapter)->firmware_version, H2C_BCNHWSEQ);*/169170}171#endif172u8 Get_VHT_ENI(173u32 IOTAction,174u32 WirelessMode,175u32 ratr_bitmap176)177{178u8 Ret = 0;179180if (WirelessMode == WIRELESS_11_24AC) {181if (ratr_bitmap & 0xfff00000) /* Mix , 2SS */182Ret = 3;183else /* Mix, 1SS */184Ret = 2;185} else if (WirelessMode == WIRELESS_11_5AC) {186Ret = 1; /* VHT */187}188189return Ret << 4;190}191192BOOLEAN193Get_RA_ShortGI_8814(194PADAPTER Adapter,195struct sta_info *psta,196u8 shortGIrate,197u32 ratr_bitmap198)199{200BOOLEAN bShortGI;201struct mlme_ext_priv *pmlmeext = &Adapter->mlmeextpriv;202struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);203204bShortGI = shortGIrate;205206#ifdef CONFIG_80211AC_VHT207if (bShortGI &&208is_supported_vht(psta->wireless_mode) &&209(pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK_JAGUAR_CCUTAP) &&210TEST_FLAG(psta->vhtpriv.ldpc_cap, LDPC_VHT_ENABLE_TX)211) {212if (ratr_bitmap & 0xC0000000)213bShortGI = _FALSE;214}215#endif /* CONFIG_80211AC_VHT */216217return bShortGI;218}219220221void222Set_RA_LDPC_8814(223struct sta_info *psta,224BOOLEAN bLDPC225)226{227if (psta == NULL)228return;229#ifdef CONFIG_80211AC_VHT230if (psta->wireless_mode == WIRELESS_11_5AC) {231if (bLDPC && TEST_FLAG(psta->vhtpriv.ldpc_cap, LDPC_VHT_CAP_TX))232SET_FLAG(psta->vhtpriv.ldpc_cap, LDPC_VHT_ENABLE_TX);233else234CLEAR_FLAG(psta->vhtpriv.ldpc_cap, LDPC_VHT_ENABLE_TX);235} else if (is_supported_ht(psta->wireless_mode) || is_supported_vht(psta->wireless_mode)) {236if (bLDPC && TEST_FLAG(psta->htpriv.ldpc_cap, LDPC_HT_CAP_TX))237SET_FLAG(psta->htpriv.ldpc_cap, LDPC_HT_ENABLE_TX);238else239CLEAR_FLAG(psta->htpriv.ldpc_cap, LDPC_HT_ENABLE_TX);240}241242update_ldpc_stbc_cap(psta);243#endif /* CONFIG_80211AC_VHT */244245/* RTW_INFO("MacId %d bLDPC %d\n", psta->cmn.mac_id, bLDPC); */246}247248void rtl8814_req_txrpt_cmd(PADAPTER padapter, u8 macid)249{250u8 u1H2CApReqRptParm[H2C_AP_REQ_TXRPT_LEN] = {0};251252SET_8814A_H2CCMD_TXREP_PARM_STA1(u1H2CApReqRptParm, macid);253SET_8814A_H2CCMD_TXREP_PARM_STA2(u1H2CApReqRptParm, 0xff);254SET_8814A_H2CCMD_TXREP_PARM_RTY(u1H2CApReqRptParm, 0x00);255FillH2CCmd_8814(padapter, H2C_AP_REQ_TXRPT, H2C_AP_REQ_TXRPT_LEN, u1H2CApReqRptParm);256SET_8814A_H2CCMD_TXREP_PARM_RTY(u1H2CApReqRptParm, 0x02);257FillH2CCmd_8814(padapter, H2C_AP_REQ_TXRPT, H2C_AP_REQ_TXRPT_LEN, u1H2CApReqRptParm);258}259260void rtl8814_set_FwPwrMode_cmd(PADAPTER padapter, u8 PSMode)261{262u8 u1H2CSetPwrMode[H2C_PWRMODE_LEN] = {0};263struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);264u8 Mode = 0, RLBM = 0, PowerState = 0, LPSAwakeIntvl = 2;265HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);266u8 allQueueUAPSD = 0;267268RTW_INFO("%s: Mode=%d SmartPS=%d\n", __FUNCTION__, PSMode, pwrpriv->smart_ps);269270switch (PSMode) {271case PS_MODE_ACTIVE:272Mode = 0;273break;274case PS_MODE_MIN:275Mode = 1;276break;277case PS_MODE_MAX:278RLBM = 1;279Mode = 1;280break;281case PS_MODE_DTIM:282RLBM = 2;283Mode = 1;284break;285case PS_MODE_UAPSD_WMM:286Mode = 2;287break;288default:289Mode = 0;290break;291}292293if (Mode > PS_MODE_ACTIVE) {294#ifdef CONFIG_BT_COEXIST295if ((rtw_btcoex_IsBtControlLps(padapter) == _TRUE) && (_TRUE == pHalData->EEPROMBluetoothCoexist))296PowerState = rtw_btcoex_RpwmVal(padapter);297else298#endif /* CONFIG_BT_COEXIST */299PowerState = 0x00;/* AllON(0x0C), RFON(0x04), RFOFF(0x00) */300301#ifdef CONFIG_EXT_CLK302Mode |= BIT(7);/* supporting 26M XTAL CLK_Request feature. */303#endif /* CONFIG_EXT_CLK */304} else305PowerState = 0x0C;/* AllON(0x0C), RFON(0x04), RFOFF(0x00) */306307/* 0: Active, 1: LPS, 2: WMMPS */308SET_8814A_H2CCMD_PWRMODE_PARM_MODE(u1H2CSetPwrMode, Mode);309310/* 0:Min, 1:Max , 2:User define */311SET_8814A_H2CCMD_PWRMODE_PARM_RLBM(u1H2CSetPwrMode, RLBM);312313/* (LPS) smart_ps: 0: PS_Poll, 1: PS_Poll , 2: NullData */314/* (WMM)smart_ps: 0:PS_Poll, 1:NullData */315SET_8814A_H2CCMD_PWRMODE_PARM_SMART_PS(u1H2CSetPwrMode, pwrpriv->smart_ps);316317/* AwakeInterval: Unit is beacon interval, this field is only valid in PS_DTIM mode */318SET_8814A_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1H2CSetPwrMode, LPSAwakeIntvl);319320/* (WMM only)bAllQueueUAPSD */321SET_8814A_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1H2CSetPwrMode, allQueueUAPSD);322323/* AllON(0x0C), RFON(0x04), RFOFF(0x00) */324SET_8814A_H2CCMD_PWRMODE_PARM_PWR_STATE(u1H2CSetPwrMode, PowerState);325326#ifdef CONFIG_BT_COEXIST327if (_TRUE == pHalData->EEPROMBluetoothCoexist)328rtw_btcoex_RecordPwrMode(padapter, u1H2CSetPwrMode, sizeof(u1H2CSetPwrMode));329#endif /* CONFIG_BT_COEXIST */330/* RTW_INFO("u1H2CSetPwrMode="MAC_FMT"\n", MAC_ARG(u1H2CSetPwrMode)); */331FillH2CCmd_8814(padapter, H2C_SET_PWR_MODE, sizeof(u1H2CSetPwrMode), u1H2CSetPwrMode);332333}334335#ifdef CONFIG_TDLS336#ifdef CONFIG_TDLS_CH_SW337void rtl8814_set_BcnEarly_C2H_Rpt_cmd(PADAPTER padapter, u8 enable)338{339u8 u1H2CSetPwrMode[H2C_PWRMODE_LEN] = {0};340341SET_8814A_H2CCMD_PWRMODE_PARM_MODE(u1H2CSetPwrMode, 1);342SET_8814A_H2CCMD_PWRMODE_PARM_RLBM(u1H2CSetPwrMode, 1);343SET_8814A_H2CCMD_PWRMODE_PARM_SMART_PS(u1H2CSetPwrMode, 0);344SET_8814A_H2CCMD_PWRMODE_PARM_BCN_PASS_TIME(u1H2CSetPwrMode, 0);345SET_8814A_H2CCMD_PWRMODE_PARM_ALL_QUEUE_UAPSD(u1H2CSetPwrMode, 0);346SET_8814A_H2CCMD_PWRMODE_PARM_BCN_EARLY_C2H_RPT(u1H2CSetPwrMode, enable);347SET_8814A_H2CCMD_PWRMODE_PARM_PWR_STATE(u1H2CSetPwrMode, 0x0C);348FillH2CCmd_8814(padapter, H2C_SET_PWR_MODE, sizeof(u1H2CSetPwrMode), u1H2CSetPwrMode);349}350#endif351#endif352353void rtl8814a_set_FwPwrModeInIPS_cmd(PADAPTER padapter, u8 cmd_param)354{355struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);356u8 parm[H2C_INACTIVE_PS_LEN] = {0};357358/* u8 cmd_param; */ /* BIT0:enable, BIT1:NoConnect32k */359if (cmd_param) {360361#ifdef CONFIG_BT_COEXIST362rtw_btcoex_IpsNotify(padapter, pwrpriv->ips_mode_req);363#endif364/* Enter IPS */365RTW_INFO("%s: issue H2C to FW when entering IPS\n", __func__);366367parm[0] = 0x1;/* suggest by Isaac.Hsu*/368369rtw_hal_fill_h2c_cmd(padapter, /* H2C_FWLPS_IN_IPS_, */370H2C_INACTIVE_PS_,371H2C_INACTIVE_PS_LEN, parm);372} else {373/* Leave IPS */374RTW_INFO("%s: Leaving IPS in FWLPS state\n", __func__);375376parm[0] = 0x0;377parm[1] = 0x0;378parm[2] = 0x0;379rtw_hal_fill_h2c_cmd(padapter, H2C_INACTIVE_PS_,380H2C_INACTIVE_PS_LEN, parm);381#ifdef CONFIG_BT_COEXIST382rtw_btcoex_IpsNotify(padapter, IPS_NONE);383#endif384}385}386387/*388* Description: Get the reserved page number in Tx packet buffer.389* Retrun value: the page number.390* 2012.08.09, by tynli.391* */392u8393GetTxBufferRsvdPageNum8814(_adapter *Adapter, bool bWoWLANBoundary)394{395HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);396u8 RsvdPageNum = 0;397u16 TxPageBndy = LAST_ENTRY_OF_TX_PKT_BUFFER_8814A; /* default reseved 1 page for the IC type which is undefined. */398399if (bWoWLANBoundary)400rtw_hal_get_def_var(Adapter, HAL_DEF_TX_PAGE_BOUNDARY_WOWLAN, (u8 *)&TxPageBndy);401else402rtw_hal_get_def_var(Adapter, HAL_DEF_TX_PAGE_BOUNDARY, (u8 *)&TxPageBndy);403404RsvdPageNum = LAST_ENTRY_OF_TX_PKT_BUFFER_8814A - TxPageBndy + 1;405406return RsvdPageNum;407}408409void rtl8814_download_rsvd_page(PADAPTER padapter, u8 mstatus)410{411HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);412struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);413struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);414BOOLEAN bSendBeacon = _FALSE;415BOOLEAN bcn_valid = _FALSE;416u8 DLBcnCount = 0;417u32 poll = 0;418u8 RegFwHwTxQCtrl;419420RTW_INFO("%s mstatus(%x)\n", __FUNCTION__, mstatus);421422if (mstatus == 1) {423u8 bcn_ctrl = rtw_read8(padapter, REG_BCN_CTRL);424425/* We should set AID, correct TSF, HW seq enable before set JoinBssReport to Fw in 88/92C. */426/* Suggested by filen. Added by tynli. */427rtw_write16(padapter, REG_BCN_PSR_RPT, (0xC000 | pmlmeinfo->aid));428/* Hw sequende enable by dedault. 2010.06.23. by tynli. */429/* rtw_write16(padapter, REG_NQOS_SEQ, ((pmlmeext->mgnt_seq+100)&0xFFF)); */430/* rtw_write8(padapter, REG_HWSEQ_CTRL, 0xFF); */431432/* Set REG_CR bit 8. DMA beacon by SW. */433rtw_write8(padapter, REG_CR + 1,434rtw_read8(padapter, REG_CR + 1) | BIT0);435436/*RTW_INFO("%s-%d: enable SW BCN, REG_CR=0x%x\n", __func__, __LINE__, rtw_read32(padapter, REG_CR));*/437438/* Disable Hw protection for a time which revserd for Hw sending beacon. */439/* Fix download reserved page packet fail that access collision with the protection time. */440/* 2010.05.11. Added by tynli. */441rtw_write8(padapter, REG_BCN_CTRL, (bcn_ctrl & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);442443RegFwHwTxQCtrl = rtw_read8(padapter, REG_FWHW_TXQ_CTRL + 2);444if (RegFwHwTxQCtrl & BIT6) {445RTW_INFO("HalDownloadRSVDPage(): There is an Adapter is sending beacon.\n");446bSendBeacon = _TRUE;447}448449/* Set FWHW_TXQ_CTRL 0x422[6]=0 to tell Hw the packet is not a real beacon frame. */450RegFwHwTxQCtrl &= (~BIT6);451rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2, RegFwHwTxQCtrl);452453/* Clear beacon valid check bit. */454rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);455DLBcnCount = 0;456poll = 0;457do {458/* download rsvd page. */459rtw_hal_set_fw_rsvd_page(padapter, _FALSE);460DLBcnCount++;461do {462rtw_yield_os();463/* rtw_mdelay_os(10); */464/* check rsvd page download OK. */465rtw_hal_get_hwreg(padapter, HW_VAR_BCN_VALID, (u8 *)(&bcn_valid));466poll++;467} while (!bcn_valid && (poll % 10) != 0 && !RTW_CANNOT_RUN(padapter));468469} while (!bcn_valid && DLBcnCount <= 100 && !RTW_CANNOT_RUN(padapter));470471/* RT_ASSERT(bcn_valid, ("HalDownloadRSVDPage88ES(): 1 Download RSVD page failed!\n")); */472if (RTW_CANNOT_RUN(padapter))473;474else if (!bcn_valid)475RTW_ERR(ADPT_FMT": 1 DL RSVD page failed! DLBcnCount:%u, poll:%u\n",476ADPT_ARG(padapter) , DLBcnCount, poll);477else {478struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);479480pwrctl->fw_psmode_iface_id = padapter->iface_id;481rtw_hal_set_fw_rsvd_page(padapter, _TRUE);482RTW_INFO(ADPT_FMT": 1 DL RSVD page success! DLBcnCount:%u, poll:%u\n",483ADPT_ARG(padapter), DLBcnCount, poll);484}485486/* restore bcn_ctrl */487rtw_write8(padapter, REG_BCN_CTRL, bcn_ctrl);488489/* To make sure that if there exists an adapter which would like to send beacon. */490/* If exists, the origianl value of 0x422[6] will be 1, we should check this to */491/* prevent from setting 0x422[6] to 0 after download reserved page, or it will cause */492/* the beacon cannot be sent by HW. */493/* 2010.06.23. Added by tynli. */494if (bSendBeacon) {495RegFwHwTxQCtrl |= BIT6;496rtw_write8(padapter, REG_FWHW_TXQ_CTRL + 2, RegFwHwTxQCtrl);497}498499/* */500/* Update RSVD page location H2C to Fw. */501/* */502if (bcn_valid) {503rtw_hal_set_hwreg(padapter, HW_VAR_BCN_VALID, NULL);504RTW_INFO("Set RSVD page location to Fw.\n");505/* FillH2CCmd88E(Adapter, H2C_88E_RSVDPAGE, H2C_RSVDPAGE_LOC_LENGTH, pMgntInfo->u1RsvdPageLoc); */506}507508/* Do not enable HW DMA BCN or it will cause Pcie interface hang by timing issue. 2011.11.24. by tynli. */509/* if(!padapter->bEnterPnpSleep) */510#ifndef CONFIG_PCI_HCI511{512#ifndef RTL8814AE_SW_BCN513/* Clear CR[8] or beacon packet will not be send to TxBuf anymore. */514rtw_write8(padapter, REG_CR + 1,515rtw_read8(padapter, REG_CR + 1) & (~BIT0));516517/*RTW_INFO("%s-%d: disable SW BCN, REG_CR=0x%x\n", __func__, __LINE__, rtw_read32(padapter, REG_CR));*/518#endif519}520#endif /* !CONFIG_PCI_HCI */521}522}523524void rtl8814_set_FwJoinBssReport_cmd(PADAPTER padapter, u8 mstatus)525{526if (mstatus == 1)527rtl8814_download_rsvd_page(padapter, RT_MEDIA_CONNECT);528}529530#ifdef CONFIG_P2P_PS531void rtl8814_set_p2p_ps_offload_cmd(_adapter *padapter, u8 p2p_ps_state)532{533HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);534struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);535struct wifidirect_info *pwdinfo = &(padapter->wdinfo);536u8 *p2p_ps_offload = (u8 *)&pHalData->p2p_ps_offload;537u8 i;538539540#if 1541switch (p2p_ps_state) {542case P2P_PS_DISABLE:543RTW_INFO("P2P_PS_DISABLE\n");544_rtw_memset(p2p_ps_offload, 0, 1);545break;546case P2P_PS_ENABLE:547RTW_INFO("P2P_PS_ENABLE\n");548/* update CTWindow value. */549if (pwdinfo->ctwindow > 0) {550SET_8814A_H2CCMD_P2P_PS_OFFLOAD_CTWINDOW_EN(p2p_ps_offload, 1);551rtw_write8(padapter, REG_P2P_CTWIN, pwdinfo->ctwindow);552}553554/* hw only support 2 set of NoA */555for (i = 0 ; i < pwdinfo->noa_num ; i++) {556/* To control the register setting for which NOA */557rtw_write8(padapter, REG_NOA_DESC_SEL, (i << 4));558if (i == 0)559SET_8814A_H2CCMD_P2P_PS_OFFLOAD_NOA0_EN(p2p_ps_offload, 1);560else561SET_8814A_H2CCMD_P2P_PS_OFFLOAD_NOA1_EN(p2p_ps_offload, 1);562563/* config P2P NoA Descriptor Register */564/* RTW_INFO("%s(): noa_duration = %x\n",__FUNCTION__,pwdinfo->noa_duration[i]); */565rtw_write32(padapter, REG_NOA_DESC_DURATION, pwdinfo->noa_duration[i]);566567/* RTW_INFO("%s(): noa_interval = %x\n",__FUNCTION__,pwdinfo->noa_interval[i]); */568rtw_write32(padapter, REG_NOA_DESC_INTERVAL, pwdinfo->noa_interval[i]);569570/* RTW_INFO("%s(): start_time = %x\n",__FUNCTION__,pwdinfo->noa_start_time[i]); */571rtw_write32(padapter, REG_NOA_DESC_START, pwdinfo->noa_start_time[i]);572573/* RTW_INFO("%s(): noa_count = %x\n",__FUNCTION__,pwdinfo->noa_count[i]); */574rtw_write8(padapter, REG_NOA_DESC_COUNT, pwdinfo->noa_count[i]);575}576577if ((pwdinfo->opp_ps == 1) || (pwdinfo->noa_num > 0)) {578/* rst p2p circuit: reg 0x5F0 */579rtw_write8(padapter, REG_P2P_RST_8814A, BIT(0)); /* rst p2p 0 circuit NOA 0 */580581SET_8814A_H2CCMD_P2P_PS_OFFLOAD_ENABLE(p2p_ps_offload, 1);582583if (pwdinfo->role == P2P_ROLE_GO) {584/* 1: Owner, 0: Client */585SET_8814A_H2CCMD_P2P_PS_OFFLOAD_ROLE(p2p_ps_offload, 1);586SET_8814A_H2CCMD_P2P_PS_OFFLOAD_ALLSTASLEEP(p2p_ps_offload, 0);587} else {588/* 1: Owner, 0: Client */589SET_8814A_H2CCMD_P2P_PS_OFFLOAD_ROLE(p2p_ps_offload, 0);590}591592SET_8814A_H2CCMD_P2P_PS_OFFLOAD_DISCOVERY(p2p_ps_offload, 0);593}594break;595case P2P_PS_SCAN:596RTW_INFO("P2P_PS_SCAN\n");597SET_8814A_H2CCMD_P2P_PS_OFFLOAD_DISCOVERY(p2p_ps_offload, 1);598break;599case P2P_PS_SCAN_DONE:600RTW_INFO("P2P_PS_SCAN_DONE\n");601SET_8814A_H2CCMD_P2P_PS_OFFLOAD_DISCOVERY(p2p_ps_offload, 0);602pwdinfo->p2p_ps_state = P2P_PS_ENABLE;603break;604default:605break;606}607608RTW_INFO("P2P_PS_OFFLOAD : %x\n", p2p_ps_offload[0]);609FillH2CCmd_8814(padapter, H2C_P2P_PS_OFFLOAD, 1, p2p_ps_offload);610#endif611612613}614#endif /* CONFIG_P2P */615616617618static void619C2HTxBeamformingHandler_8814(620PADAPTER Adapter,621u8 *CmdBuf,622u8 CmdLen623)624{625#ifdef CONFIG_BEAMFORMING /*PHYDM_BF - (BEAMFORMING_SUPPORT == 1)*/626u8 status = CmdBuf[0] & BIT0;627HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);628struct dm_struct *pDM_Odm = &pHalData->odmpriv;629/*beamforming_check_sounding_success(Adapter, status);*/630phydm_beamforming_end_sw(pDM_Odm, status);631#endif /*CONFIG_BEAMFORMING*/632}633634static void635C2HTxFeedbackHandler_8814(636PADAPTER Adapter,637u8 *CmdBuf,638u8 CmdLen639)640{641#ifdef CONFIG_XMIT_ACK642if (GET_8814A_C2H_TX_RPT_RETRY_OVER(CmdBuf) | GET_8814A_C2H_TX_RPT_LIFE_TIME_OVER(CmdBuf))643rtw_ack_tx_done(&Adapter->xmitpriv, RTW_SCTX_DONE_CCX_PKT_FAIL);644else645rtw_ack_tx_done(&Adapter->xmitpriv, RTW_SCTX_DONE_SUCCESS);646#endif647}648649static void650C2HTxRPTHandler_8814(651PADAPTER Adapter,652u8 *CmdBuf,653u8 CmdLen654)655{656_irqL irqL;657u8 macid = 0, IniRate = 0;658u16 TxOK = 0, TxFail = 0;659struct sta_priv *pstapriv = &(GET_PRIMARY_ADAPTER(Adapter))->stapriv, *pstapriv_original = NULL;660struct sta_info *psta = NULL;661struct sta_info *pbcmc_stainfo = rtw_get_bcmc_stainfo(Adapter);662_list *plist, *phead;663PADAPTER adapter_ognl = NULL;664665if(!pstapriv->gotc2h) {666RTW_WARN("%s,%d: No gotc2h!\n", __FUNCTION__, __LINE__);667return;668}669670adapter_ognl = rtw_get_iface_by_id(GET_PRIMARY_ADAPTER(Adapter), pstapriv->c2h_adapter_id);671if(!adapter_ognl) {672RTW_WARN("%s: No adapter!\n", __FUNCTION__);673return;674}675676psta = rtw_get_stainfo(&adapter_ognl->stapriv, pstapriv->c2h_sta_mac);677if (!psta) {678RTW_WARN("%s: No corresponding sta_info!\n", __FUNCTION__);679return;680}681682macid = GET_8814A_C2H_TC2H_APREQ_TXRPT_MACID1(CmdBuf);683TxOK = GET_8814A_C2H_TC2H_APREQ_TXRPT_TXOK1(CmdBuf);684TxFail = GET_8814A_C2H_TC2H_APREQ_TXRPT_TXFAIL1(CmdBuf);685IniRate = GET_8814A_C2H_TC2H_APREQ_TXRPT_INIRATE1(CmdBuf);686psta->sta_stats.tx_ok_cnt = TxOK;687psta->sta_stats.tx_fail_cnt = TxFail;688689}690691static void692C2HSPC_STAT_8814(693PADAPTER Adapter,694u8 *CmdBuf,695u8 CmdLen696)697{698_irqL irqL;699struct sta_priv *pstapriv = &(GET_PRIMARY_ADAPTER(Adapter))->stapriv;700struct sta_info *psta = NULL;701_list *plist, *phead;702PADAPTER adapter_ognl = NULL;703704if(!pstapriv->gotc2h) {705RTW_WARN("%s, %d: No gotc2h!\n", __FUNCTION__, __LINE__);706return;707}708709adapter_ognl = rtw_get_iface_by_id(GET_PRIMARY_ADAPTER(Adapter), pstapriv->c2h_adapter_id);710if(!adapter_ognl) {711RTW_WARN("%s: No adapter!\n", __FUNCTION__);712return;713}714715psta = rtw_get_stainfo(&adapter_ognl->stapriv, pstapriv->c2h_sta_mac);716if (!psta) {717RTW_WARN("%s: No corresponding sta_info!\n", __FUNCTION__);718return;719}720psta->sta_stats.tx_retry_cnt = GET_8814A_C2H_SPC_STAT_TYPEB_RETRY1(CmdBuf);721rtw_sctx_done(&pstapriv->gotc2h);722}723724s32 c2h_handler_8814a(_adapter *adapter, u8 id, u8 seq, u8 plen, u8 *payload)725{726s32 ret = _SUCCESS;727728switch (id) {729case C2H_TXBF:730RTW_INFO("[C2H], C2H_TXBF!!\n");731C2HTxBeamformingHandler_8814(adapter, payload, plen);732break;733case C2H_CCX_TX_RPT:734C2HTxFeedbackHandler_8814(adapter, payload, plen);735break;736case C2H_AP_REQ_TXRPT:737C2HTxRPTHandler_8814(adapter, payload, plen);738break;739case C2H_SPC_STAT:740C2HSPC_STAT_8814(adapter, payload, plen);741break;742default:743ret = _FAIL;744break;745}746747return ret;748}749750#ifdef CONFIG_BT_COEXIST751#if 0752static void rtl8814_set_FwRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)753{754u8 u1H2CRsvdPageParm[H2C_RSVDPAGE_LOC_LEN] = {0};755756RTW_INFO("8812au/8821/8811 RsvdPageLoc: ProbeRsp=%d PsPoll=%d Null=%d QoSNull=%d BTNull=%d\n",757rsvdpageloc->LocProbeRsp, rsvdpageloc->LocPsPoll,758rsvdpageloc->LocNullData, rsvdpageloc->LocQosNull,759rsvdpageloc->LocBTQosNull);760761SET_H2CCMD_RSVDPAGE_LOC_PROBE_RSP(u1H2CRsvdPageParm, rsvdpageloc->LocProbeRsp);762SET_H2CCMD_RSVDPAGE_LOC_PSPOLL(u1H2CRsvdPageParm, rsvdpageloc->LocPsPoll);763SET_H2CCMD_RSVDPAGE_LOC_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocNullData);764SET_H2CCMD_RSVDPAGE_LOC_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocQosNull);765SET_H2CCMD_RSVDPAGE_LOC_BT_QOS_NULL_DATA(u1H2CRsvdPageParm, rsvdpageloc->LocBTQosNull);766767RTW_DBG_DUMP("u1H2CRsvdPageParm:", u1H2CRsvdPageParm, H2C_RSVDPAGE_LOC_LEN);768FillH2CCmd_8814(padapter, H2C_RSVD_PAGE, H2C_RSVDPAGE_LOC_LEN, u1H2CRsvdPageParm);769}770771#ifdef CONFIG_WOWLAN772static void rtl8814_set_FwAoacRsvdPage_cmd(PADAPTER padapter, PRSVDPAGE_LOC rsvdpageloc)773{774struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);775struct mlme_priv *pmlmepriv = &padapter->mlmepriv;776u8 res = 0, count = 0;777#ifdef CONFIG_WOWLAN778u8 u1H2CAoacRsvdPageParm[H2C_AOAC_RSVDPAGE_LOC_LEN] = {0};779780RTW_INFO("rtl8814_set_FwAoacRsvdPage_cmd: RWC=%d ArpRsp=%d NbrAdv=%d GtkRsp=%d GtkInfo=%d ProbeReq=%d NetworkList=%d\n",781rsvdpageloc->LocRemoteCtrlInfo, rsvdpageloc->LocArpRsp,782rsvdpageloc->LocNbrAdv, rsvdpageloc->LocGTKRsp,783rsvdpageloc->LocGTKInfo, rsvdpageloc->LocProbeReq,784rsvdpageloc->LocNetList);785786#ifdef CONFIG_PNO_SUPPORT787RTW_INFO("NLO_INFO=%d\n", rsvdpageloc->LocPNOInfo);788#endif789if (check_fwstate(pmlmepriv, _FW_LINKED)) {790SET_H2CCMD_AOAC_RSVDPAGE_LOC_REMOTE_WAKE_CTRL_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocRemoteCtrlInfo);791SET_H2CCMD_AOAC_RSVDPAGE_LOC_ARP_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocArpRsp);792/* SET_H2CCMD_AOAC_RSVDPAGE_LOC_NEIGHBOR_ADV(u1H2CAoacRsvdPageParm, rsvdpageloc->LocNbrAdv); */793SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_RSP(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKRsp);794SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKInfo);795#ifdef CONFIG_GTK_OL796SET_H2CCMD_AOAC_RSVDPAGE_LOC_GTK_EXT_MEM(u1H2CAoacRsvdPageParm, rsvdpageloc->LocGTKEXTMEM);797#endif /* CONFIG_GTK_OL */798} else {799#ifdef CONFIG_PNO_SUPPORT800if (!pwrpriv->wowlan_in_resume)801SET_H2CCMD_AOAC_RSVDPAGE_LOC_NLO_INFO(u1H2CAoacRsvdPageParm, rsvdpageloc->LocPNOInfo);802#endif803}804805RTW_DBG_DUMP("u1H2CAoacRsvdPageParm:", u1H2CAoacRsvdPageParm, H2C_AOAC_RSVDPAGE_LOC_LEN);806FillH2CCmd_8814(padapter, H2C_AOAC_RSVD_PAGE, H2C_AOAC_RSVDPAGE_LOC_LEN, u1H2CAoacRsvdPageParm);807808#ifdef CONFIG_PNO_SUPPORT809if (!MLME_IS_AP(padapter) && !MLME_IS_MESH(padapter) &&810!check_fwstate(pmlmepriv, _FW_LINKED) &&811pwrpriv->wowlan_in_resume == _FALSE) {812813res = rtw_read8(padapter, 0x1b8);814while (res == 0 && count < 25) {815RTW_INFO("[%d] FW loc_NLOInfo: %d\n", count, res);816res = rtw_read8(padapter, 0x1b8);817count++;818rtw_msleep_os(2);819}820}821#endif /* CONFIG_PNO_SUPPORT */822#endif /* CONFIG_WOWLAN */823}824#endif825826static void SetFwRsvdPagePkt_BTCoex(PADAPTER padapter)827{828PHAL_DATA_TYPE pHalData;829struct xmit_frame *pcmdframe;830struct pkt_attrib *pattrib;831struct xmit_priv *pxmitpriv;832struct pwrctrl_priv *pwrctl;833struct mlme_priv *pmlmepriv = &padapter->mlmepriv;834u32 BeaconLength = 0;835u32 NullDataLength = 0, QosNullLength = 0, BTQosNullLength = 0;836u32 ProbeReqLength = 0;837u8 *ReservedPagePacket;838u8 TxDescLen = TXDESC_SIZE, TxDescOffset = TXDESC_OFFSET;839u8 TotalPageNum = 0, CurtPktPageNum = 0, RsvdPageNum = 0;840u16 BufIndex, PageSize = PAGE_SIZE_TX_8814;841u32 TotalPacketLen, MaxRsvdPageBufSize = 0;842RSVDPAGE_LOC RsvdPageLoc;843844pHalData = GET_HAL_DATA(padapter);845846pxmitpriv = &padapter->xmitpriv;847pwrctl = adapter_to_pwrctl(padapter);848849/* RsvdPageNum = BCNQ_PAGE_NUM_8723B + WOWLAN_PAGE_NUM_8723B; */850851RsvdPageNum = BCNQ_PAGE_NUM_8814;852MaxRsvdPageBufSize = RsvdPageNum * PageSize;853854pcmdframe = rtw_alloc_cmdxmitframe(pxmitpriv);855if (pcmdframe == NULL) {856RTW_INFO("%s: alloc ReservedPagePacket fail!\n", __FUNCTION__);857return;858}859860ReservedPagePacket = pcmdframe->buf_addr;861_rtw_memset(&RsvdPageLoc, 0, sizeof(RSVDPAGE_LOC));862863/* 3 (1) beacon */864BufIndex = TxDescOffset;865rtw_hal_construct_beacon(padapter,866&ReservedPagePacket[BufIndex], &BeaconLength);867868/* When we count the first page size, we need to reserve description size for the RSVD */869/* packet, it will be filled in front of the packet in TXPKTBUF. */870CurtPktPageNum = (u8)PageNum(TxDescLen + BeaconLength, PageSize);871872/* If we don't add 1 more page, the WOWLAN function has a problem. Baron thinks it's a bug of firmware */873if (CurtPktPageNum == 1)874CurtPktPageNum += 1;875TotalPageNum += CurtPktPageNum;876877BufIndex += (CurtPktPageNum * PageSize);878879/* Jump to lastest page */880if (BufIndex < (MaxRsvdPageBufSize - PageSize)) {881BufIndex = TxDescOffset + (MaxRsvdPageBufSize - PageSize);882TotalPageNum = BCNQ_PAGE_NUM_8814 - 1;883884}885886/* 3 (6) BT Qos null data */887RsvdPageLoc.LocBTQosNull = TotalPageNum;888rtw_hal_construct_NullFunctionData(889padapter,890&ReservedPagePacket[BufIndex],891&BTQosNullLength,892_TRUE, 0, 0, _FALSE);893rtl8814a_fill_fake_txdesc(padapter, &ReservedPagePacket[BufIndex - TxDescLen], BTQosNullLength, _FALSE, _TRUE, _FALSE);894895/* RTW_INFO("%s(): HW_VAR_SET_TX_CMD: BT QOS NULL DATA %p %d\n", */896/* __FUNCTION__, &ReservedPagePacket[BufIndex-TxDescLen], (BTQosNullLength+TxDescLen)); */897898CurtPktPageNum = (u8)PageNum(TxDescLen + BTQosNullLength, PageSize);899900TotalPageNum += CurtPktPageNum;901902TotalPacketLen = BufIndex + BTQosNullLength;903if (TotalPacketLen > MaxRsvdPageBufSize) {904RTW_INFO("%s(): ERROR: The rsvd page size is not enough!!TotalPacketLen %d, MaxRsvdPageBufSize %d\n", __FUNCTION__,905TotalPacketLen, MaxRsvdPageBufSize);906goto error;907} else {908/* update attribute */909pattrib = &pcmdframe->attrib;910update_mgntframe_attrib(padapter, pattrib);911pattrib->qsel = QSLT_BEACON;912pattrib->pktlen = pattrib->last_txcmdsz = TotalPacketLen - TxDescOffset;913#ifdef CONFIG_PCI_HCI914dump_mgntframe(padapter, pcmdframe);915#else916dump_mgntframe_and_wait(padapter, pcmdframe, 100);917#endif918}919920RTW_INFO("%s: Set RSVD page location to Fw ,TotalPacketLen(%d), TotalPageNum(%d)\n", __FUNCTION__, TotalPacketLen, TotalPageNum);921if (check_fwstate(pmlmepriv, _FW_LINKED)) {922rtl8814_set_FwRsvdPage_cmd(padapter, &RsvdPageLoc);923#ifdef CONFIG_WOWLAN924rtl8814_set_FwAoacRsvdPage_cmd(padapter, &RsvdPageLoc);925#endif926}927928return;929930error:931932rtw_free_xmitframe(pxmitpriv, pcmdframe);933}934#endif935936void rtl8814a_download_BTCoex_AP_mode_rsvd_page(PADAPTER padapter)937{938rtl8814_download_rsvd_page(padapter, RT_MEDIA_CONNECT);939}940941#endif /* CONFIG_BT_COEXIST */942943944