Path: blob/master/ALFA-W1F1/RTL8814AU/hal/rtl8814a/rtl8814a_hal_init.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_HAL_INIT_C_1516/* #include <drv_types.h> */17#include <rtl8814a_hal.h>18#include "hal8814a_fw.h"19/* -------------------------------------------------------------------------20*21* LLT R/W/Init function22*23* ------------------------------------------------------------------------- */24void25Hal_InitEfuseVars_8814A(26PADAPTER Adapter27)28{29HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);30PEFUSE_HAL pEfuseHal = &(pHalData->EfuseHal);31u16 *ptr;3233#define INIT_EFUSE(var, value) ptr = (u16 *)&var; *ptr = value3435RTW_INFO("====> %s\n", __func__);36/* 2 Common */37INIT_EFUSE(pEfuseHal->WordUnit , EFUSE_MAX_WORD_UNIT);38RTW_INFO("====>pEfuseHal->WordUnit %d\n", pEfuseHal->WordUnit);39INIT_EFUSE(pEfuseHal->BankSize , 512);40INIT_EFUSE(pEfuseHal->OOBProtectBytes, EFUSE_OOB_PROTECT_BYTES);41RTW_INFO("====>pEfuseHal->OOBProtectBytes %d\n", pEfuseHal->OOBProtectBytes);42INIT_EFUSE(pEfuseHal->ProtectBytes , EFUSE_PROTECT_BYTES_BANK_8814A);43RTW_INFO("====>pEfuseHal->ProtectBytes %d\n", pEfuseHal->ProtectBytes);44INIT_EFUSE(pEfuseHal->BankAvailBytes , (pEfuseHal->BankSize - pEfuseHal->OOBProtectBytes));45INIT_EFUSE(pEfuseHal->TotalBankNum , EFUSE_MAX_BANK_8814A);46INIT_EFUSE(pEfuseHal->HeaderRetry , 0);47INIT_EFUSE(pEfuseHal->DataRetry , 0);4849/* 2 Wi-Fi */50INIT_EFUSE(pEfuseHal->MaxSecNum_WiFi , EFUSE_MAX_SECTION_8814A);51RTW_INFO("====>pEfuseHal->MaxSecNum_WiFi %d\n", pEfuseHal->MaxSecNum_WiFi);52INIT_EFUSE(pEfuseHal->PhysicalLen_WiFi , EFUSE_REAL_CONTENT_LEN_8814A);53RTW_INFO("====>pEfuseHal->PhysicalLen_WiFi %d\n", pEfuseHal->PhysicalLen_WiFi);54INIT_EFUSE(pEfuseHal->LogicalLen_WiFi , EFUSE_MAP_LEN_8814A);55RTW_INFO("====>pEfuseHal->LogicalLen_WiFi %d\n", pEfuseHal->LogicalLen_WiFi);56INIT_EFUSE(pEfuseHal->BankNum_WiFi , pEfuseHal->PhysicalLen_WiFi / pEfuseHal->BankSize);57INIT_EFUSE(pEfuseHal->TotalAvailBytes_WiFi, (pEfuseHal->PhysicalLen_WiFi - (pEfuseHal->TotalBankNum * pEfuseHal->OOBProtectBytes)));5859/* 2 BT */60INIT_EFUSE(pEfuseHal->MaxSecNum_BT , 0);61INIT_EFUSE(pEfuseHal->PhysicalLen_BT , 0);62INIT_EFUSE(pEfuseHal->LogicalLen_BT , 0);63INIT_EFUSE(pEfuseHal->BankNum_BT , 0);64INIT_EFUSE(pEfuseHal->TotalAvailBytes_BT, 0);6566RTW_INFO("%s <====\n", __func__);67}686970s32 InitLLTTable8814A(71PADAPTER Adapter72)73{74/* Auto-init LLT table ( Set REG:0x208[BIT0] ) */75/* Write 1 to enable HW init LLT, driver need polling to 0 meaning init success */76u8 tmp1byte = 0, testcnt = 0;77s32 Status = _SUCCESS;7879tmp1byte = rtw_read8(Adapter, REG_AUTO_LLT_8814A);80rtw_write8(Adapter, REG_AUTO_LLT_8814A, tmp1byte | BIT0);81while (tmp1byte & BIT0) {82tmp1byte = rtw_read8(Adapter, REG_AUTO_LLT_8814A);83rtw_mdelay_os(100);84testcnt++;85if (testcnt > 100) {86Status = _FAIL;87break;88}89}90return Status;91}9293#ifdef CONFIG_WOWLAN94void hal_DetectWoWMode(PADAPTER pAdapter)95{96adapter_to_pwrctl(pAdapter)->bSupportRemoteWakeup = _TRUE;97}98#endif99100void101_FWDownloadEnable_8814A(102PADAPTER Adapter,103BOOLEAN enable104)105{106u8 tmp;107u16 u2Tmp = 0;108109if (enable) {110/* MCU firmware download enable. */111u2Tmp = rtw_read16(Adapter, REG_8051FW_CTRL_8814A);112u2Tmp &= 0x3000;113u2Tmp &= (~BIT12);114u2Tmp |= BIT13;115u2Tmp |= BIT0;116rtw_write16(Adapter, REG_8051FW_CTRL_8814A, u2Tmp);117118/* Clear Rom DL enable */119/* tmp = rtw_read8(Adapter, REG_8051FW_CTRL_8814A+2); */ /* modify by gw 20130826(advice by hw) */120/* rtw_write8(Adapter, REG_8051FW_CTRL_8814A+2, tmp&0xf7); */ /* clear bit3 */121} else {122/* MCU firmware download enable. */123tmp = rtw_read8(Adapter, REG_8051FW_CTRL_8814A);124rtw_write8(Adapter, REG_8051FW_CTRL_8814A, tmp & 0xfe);125}126}127128#define MAX_REG_BOLCK_SIZE 196129130void131_BlockWrite_8814A(132PADAPTER Adapter,133void *buffer,134u32 buffSize135)136{137u32 blockSize_p1 = 4; /* (Default) Phase #1 : PCI muse use 4-byte write to download FW */138u32 blockSize_p2 = 8; /* Phase #2 : Use 8-byte, if Phase#1 use big size to write FW. */139u32 blockSize_p3 = 1; /* Phase #3 : Use 1-byte, the remnant of FW image. */140u32 blockCount_p1 = 0, blockCount_p2 = 0, blockCount_p3 = 0;141u32 remainSize_p1 = 0, remainSize_p2 = 0;142u8 *bufferPtr = (u8 *)buffer;143u32 i = 0, offset = 0;144145#ifdef CONFIG_USB_HCI146blockSize_p1 = MAX_REG_BOLCK_SIZE; /* Use 196-byte write to download FW */147/* Small block size will increase USB init speed. But prevent FW download fail */148/* use 4-Byte instead of 196-Byte to write FW. */149#endif150151/* 3 Phase #1 */152blockCount_p1 = buffSize / blockSize_p1;153remainSize_p1 = buffSize % blockSize_p1;154155156157for (i = 0 ; i < blockCount_p1 ; i++) {158#ifdef CONFIG_USB_HCI159rtw_writeN(Adapter, (FW_START_ADDRESS + i * blockSize_p1), blockSize_p1, (bufferPtr + i * blockSize_p1));160#else161rtw_write32(Adapter, (FW_START_ADDRESS + i * blockSize_p1), *((u32 *)(bufferPtr + i * blockSize_p1)));162#endif163}164165/* 3 Phase #2 */166if (remainSize_p1) {167offset = blockCount_p1 * blockSize_p1;168169blockCount_p2 = remainSize_p1 / blockSize_p2;170remainSize_p2 = remainSize_p1 % blockSize_p2;171172173174#ifdef CONFIG_USB_HCI175for (i = 0 ; i < blockCount_p2 ; i++)176rtw_writeN(Adapter, (FW_START_ADDRESS + offset + i * blockSize_p2), blockSize_p2, (bufferPtr + offset + i * blockSize_p2));177#endif178}179180/* 3 Phase #3 */181if (remainSize_p2) {182offset = (blockCount_p1 * blockSize_p1) + (blockCount_p2 * blockSize_p2);183184blockCount_p3 = remainSize_p2 / blockSize_p3;185186187for (i = 0 ; i < blockCount_p3 ; i++)188rtw_write8(Adapter, (FW_START_ADDRESS + offset + i), *(bufferPtr + offset + i));189}190}191192void193_PageWrite_8814A(194PADAPTER Adapter,195u32 page,196void *buffer,197u32 size198)199{200u8 value8;201u8 u8Page = (u8)(page & 0x07) ;202203value8 = (rtw_read8(Adapter, REG_8051FW_CTRL_8814A + 2) & 0xF8) | u8Page ;204rtw_write8(Adapter, REG_8051FW_CTRL_8814A + 2, value8);205206_BlockWrite_8814A(Adapter, buffer, size);207}208209void210_FillDummy_8814A(211u8 *pFwBuf,212u32 *pFwLen213)214{215u32 FwLen = *pFwLen;216u8 remain = (u8)(FwLen % 4);217remain = (remain == 0) ? 0 : (4 - remain);218219while (remain > 0) {220pFwBuf[FwLen] = 0;221FwLen++;222remain--;223}224225*pFwLen = FwLen;226}227228void229_WriteFW_8814A(230PADAPTER Adapter,231void *buffer,232u32 size233)234{235u32 pageNums, remainSize ;236u32 page, offset;237u8 *bufferPtr = (u8 *)buffer;238239#ifdef CONFIG_PCI_HCI240/* 20100120 Joseph: Add for 88CE normal chip. */241/* Fill in zero to make firmware image to dword alignment. */242_FillDummy_8814A(bufferPtr, &size);243#endif /* CONFIG_PCI_HCI */244245pageNums = size / MAX_PAGE_SIZE ;246247/* RT_ASSERT((pageNums <= 8), ("Page numbers should not greater then 8\n")); */248249remainSize = size % MAX_PAGE_SIZE;250251for (page = 0; page < pageNums; page++) {252offset = page * MAX_PAGE_SIZE;253_PageWrite_8814A(Adapter, page, (bufferPtr + offset), MAX_PAGE_SIZE);254rtw_udelay_os(2);255}256if (remainSize) {257offset = pageNums * MAX_PAGE_SIZE;258page = pageNums;259_PageWrite_8814A(Adapter, page, (bufferPtr + offset), remainSize);260}261}262263void264_3081Disable8814A(265PADAPTER Adapter266)267{268u8 u1bTmp;269u1bTmp = rtw_read8(Adapter, REG_SYS_FUNC_EN_8814A + 1);270rtw_write8(Adapter, REG_SYS_FUNC_EN_8814A + 1, u1bTmp & (~BIT2));271272273}274275void276_3081Enable8814A(277PADAPTER Adapter278)279{280u8 u1bTmp;281u1bTmp = rtw_read8(Adapter, REG_SYS_FUNC_EN_8814A + 1);282rtw_write8(Adapter, REG_SYS_FUNC_EN_8814A + 1, u1bTmp | BIT2);283}284285286/* add by ylb 20130814 for 3081 download FW */287static288BOOLEAN289IDDMADownLoadFW_3081(290PADAPTER Adapter,291u32 source,292u32 dest,293u32 length,294BOOLEAN fs,295BOOLEAN ls296)297{298u32 ch0ctrl = (DDMA_CHKSUM_EN | DDMA_CH_OWN);299u32 cnt;300u8 tmp;301/* check if ddma ch0 is idle */302cnt = 20;303while (rtw_read32(Adapter, REG_DDMA_CH0CTRL) & DDMA_CH_OWN) {304rtw_udelay_os(1000);305cnt--;306if (cnt == 0) {307RTW_INFO("IDDMADownLoadFW_3081, line%d: CNT fail\n", __LINE__);308return _FALSE;309}310}311ch0ctrl |= length & DDMA_LEN_MASK;312313/* check if chksum continuous */314if (fs == _FALSE)315ch0ctrl |= DDMA_CH_CHKSUM_CNT;316rtw_write32(Adapter, REG_DDMA_CH0SA, source);317rtw_write32(Adapter, REG_DDMA_CH0DA, dest);318rtw_write32(Adapter, REG_DDMA_CH0CTRL, ch0ctrl);319320cnt = 20;321while (rtw_read32(Adapter, REG_DDMA_CH0CTRL) & DDMA_CH_OWN) {322rtw_udelay_os(1000);323cnt--;324if (cnt == 0) {325RTW_INFO("IDDMADownLoadFW_3081, line%d: CNT fail\n", __LINE__);326return _FALSE;327}328}329330/* check checksum */331if (ls == _TRUE) {332tmp = rtw_read8(Adapter, REG_8051FW_CTRL_8814A);333if (0 == (rtw_read32(Adapter, REG_DDMA_CH0CTRL) & DDMA_CHKSUM_FAIL)) {334/* chksum ok */335RTW_INFO("Check sum OK\n");336/* imem */337if (dest < OCPBASE_DMEM_3081) {338tmp |= IMEM_DL_RDY;339rtw_write8(Adapter, REG_8051FW_CTRL_8814A, tmp | IMEM_CHKSUM_OK);340RTW_INFO("imem check sum tmp %d\n", tmp);341}342/* dmem */343else {344tmp |= DMEM_DL_RDY;345rtw_write8(Adapter, REG_8051FW_CTRL_8814A, tmp | DMEM_CHKSUM_OK);346RTW_INFO("dmem check sum tmp %d\n", tmp);347}348} else {349/* chksum fail */350RTW_INFO("Check sum fail\n");351ch0ctrl = rtw_read32(Adapter, REG_DDMA_CH0CTRL);352rtw_write32(Adapter, REG_DDMA_CH0CTRL, ch0ctrl | DDMA_RST_CHKSUM_STS);353354/* imem */355if (dest < OCPBASE_DMEM_3081) {356tmp &= (~IMEM_DL_RDY);357rtw_write8(Adapter, REG_8051FW_CTRL_8814A, tmp & ~IMEM_CHKSUM_OK);358}359/* dmem */360else {361tmp &= (~DMEM_DL_RDY);362rtw_write8(Adapter, REG_8051FW_CTRL_8814A, tmp & ~DMEM_CHKSUM_OK);363}364return _FALSE;365}366}367return _TRUE;368}369370371/* add by ylb 20130814 for 3081 download FW */372static373BOOLEAN374WaitDownLoadRSVDPageOK_3081(375PADAPTER Adapter376)377{378u8 BcnValidReg = 0, TxBcReg = 0;379u8 count = 0, DLBcnCount = 0;380BOOLEAN bRetValue = _FALSE;381382#if defined(CONFIG_PCI_HCI)383/* Polling Beacon Queue to send Beacon */384TxBcReg = rtw_read8(Adapter, REG_MGQ_TXBD_NUM_8814A + 3);385count = 0;386while ((count < 20) && (TxBcReg & BIT4)) {387count++;388rtw_udelay_os(10);389TxBcReg = rtw_read8(Adapter, REG_MGQ_TXBD_NUM_8814A + 3);390}391392rtw_write8(Adapter, REG_MGQ_TXBD_NUM_8814A + 3, TxBcReg | BIT4);393#endif /* #if defined(CONFIG_PCI_HCI) */394/* check rsvd page download OK. */395BcnValidReg = rtw_read8(Adapter, REG_FIFOPAGE_CTRL_2_8814A + 1);396count = 0;397while (!(BcnValidReg & BIT7) && count < 20) {398count++;399rtw_udelay_os(50);400BcnValidReg = rtw_read8(Adapter, REG_FIFOPAGE_CTRL_2_8814A + 1);401}402403/* Set 1 to Clear BIT7 by SW */404if (BcnValidReg & BIT7) {405rtw_write8(Adapter, REG_FIFOPAGE_CTRL_2_8814A + 1, (BcnValidReg | BIT7));406bRetValue = _TRUE;407} else {408RTW_INFO("WaitDownLoadRSVDPageOK_3081(): Download RSVD page failed!\n");409bRetValue = _FALSE;410}411412return bRetValue;413}414415416void417SetDownLoadFwRsvdPagePkt_8814A(418PADAPTER Adapter,419void *buffer,420u32 len421)422{423PHAL_DATA_TYPE pHalData;424struct xmit_frame *pcmdframe;425struct xmit_priv *pxmitpriv;426struct pkt_attrib *pattrib;427/* The desc lengh in Tx packet buffer of 8814A is 40 bytes. */428u16 BufIndex = 0, TxDescOffset = TXDESC_OFFSET;429u32 TotalPacketLen = len;430BOOLEAN bDLOK = FALSE;431u8 *ReservedPagePacket;432433pHalData = GET_HAL_DATA(Adapter);434pxmitpriv = &Adapter->xmitpriv;435436#ifdef CONFIG_BCN_ICF437pcmdframe = rtw_alloc_cmdxmitframe(pxmitpriv);438#else439pcmdframe = alloc_mgtxmitframe(pxmitpriv);440#endif441if (pcmdframe == NULL)442return;443444ReservedPagePacket = pcmdframe->buf_addr;445446BufIndex = TxDescOffset;447448TotalPacketLen = len + BufIndex;449450_rtw_memcpy(&ReservedPagePacket[BufIndex], buffer, len);451/* RTW_INFO("SetFwRsvdPagePkt_8814A(): HW_VAR_SET_TX_CMD: BCN, %p, %d\n", &ReservedPagePacket[BufIndex], len); */452453/* RTW_INFO("SetFwRsvdPagePkt(): TotalPacketLen=%d\n", TotalPacketLen); */454455/* update attribute */456pattrib = &pcmdframe->attrib;457update_mgntframe_attrib(Adapter, pattrib);458pattrib->qsel = QSLT_BEACON;459pattrib->pktlen = pattrib->last_txcmdsz = TotalPacketLen - TxDescOffset;460461dump_mgntframe(Adapter, pcmdframe);462463/* ReturnGenTempBuffer(pAdapter, pGenBufReservedPagePacket); */464}465466467void468HalROMDownloadFWRSVDPage8814A(469PADAPTER Adapter,470void *buffer,471u32 Len472)473{474u8 u1bTmp = 0, tmpReg422 = 0;475u8 BcnValidReg = 0, TxBcReg = 0;476BOOLEAN bSendBeacon = _FALSE, bDownLoadRSVDPageOK = _FALSE;477u8 *pbuffer = buffer;478479BOOLEAN fs = _TRUE, ls = _FALSE;480u8 FWHeaderSize = 64, PageSize = 128 ;481u16 RsvdPageNum = 0;482u32 dmem_pkt_size = 0, iram_pkt_size = 0 , MaxRsvdPageBufSize = 0;483u32 last_block_size = 0, filesize_ram_block = 0, pkt_offset = 0;484u32 txpktbuf_bndy = 0;485u32 BeaconHeaderInTxPacketBuf = 0, MEMOffsetInTxPacketBuf = 0;486u8 bcn_ctrl = rtw_read8(Adapter, REG_BCN_CTRL);487488/* Set REG_CR bit 8. DMA beacon by SW. */489u1bTmp = rtw_read8(Adapter, REG_CR_8814A + 1);490rtw_write8(Adapter, REG_CR_8814A + 1, (u1bTmp | BIT0));491/*RTW_INFO("%s-%d: enable SW BCN, REG_CR=0x%x\n", __func__, __LINE__, rtw_read32(Adapter, REG_CR));*/492493/* Disable Hw protection for a time which revserd for Hw sending beacon. */494/* Fix download reserved page packet fail that access collision with the protection time. */495/* 2010.05.11. Added by tynli. 0x550[4]=1, 0x550[3]=0 */496rtw_write8(Adapter, REG_BCN_CTRL, (bcn_ctrl & (~EN_BCN_FUNCTION)) | DIS_TSF_UDT);497498/* Set FWHW_TXQ_CTRL 0x422[6]=0 to tell Hw the packet is not a real beacon frame. 0x422[6]=0 */499tmpReg422 = rtw_read8(Adapter, REG_FWHW_TXQ_CTRL_8814A + 2);500rtw_write8(Adapter, REG_FWHW_TXQ_CTRL_8814A + 2, tmpReg422 & (~BIT6));501502if (tmpReg422 & BIT6) {503RTW_INFO("HalROMDownloadFWRSVDPage8814A(): There is an Adapter is sending beacon.\n");504bSendBeacon = _TRUE;505}506507/* Set The head page of packet of Bcnq */508rtw_hal_get_def_var(Adapter, HAL_DEF_TX_PAGE_BOUNDARY, (u16 *)&txpktbuf_bndy);509rtw_write16(Adapter, REG_FIFOPAGE_CTRL_2_8814A, txpktbuf_bndy);510511/* RTW_INFO("HalROMDownloadFWRSVDPage8814A: txpktbuf_bndy=%d\n", txpktbuf_bndy); */512513/* Clear beacon valid check bit. 0x205[7]=1 */514BcnValidReg = rtw_read8(Adapter, REG_FIFOPAGE_CTRL_2_8814A + 1);515rtw_write8(Adapter, REG_FIFOPAGE_CTRL_2_8814A + 1, (BcnValidReg | BIT7));516517/* Return Beacon TCB. */518/* ReturnBeaconQueueTcb_8814A(Adapter); */519520dmem_pkt_size = (u32)GET_FIRMWARE_HDR_TOTAL_DMEM_SZ_3081(pbuffer);521iram_pkt_size = (u32)GET_FIRMWARE_HDR_IRAM_SZ_3081(pbuffer);522dmem_pkt_size += (u32)FW_CHKSUM_DUMMY_SZ;523iram_pkt_size += (u32)FW_CHKSUM_DUMMY_SZ;524525if (dmem_pkt_size + iram_pkt_size + FWHeaderSize != Len) {526RTW_INFO("ERROR: Fw Hdr size do not match the real fw size!!\n");527RTW_INFO("dmem_pkt_size = %d, iram_pkt_size = %d,FWHeaderSize = %d, Len = %d!!\n", dmem_pkt_size, iram_pkt_size, FWHeaderSize, Len);528return;529}530RTW_INFO("dmem_pkt_size = %d, iram_pkt_size = %d,FWHeaderSize = %d, Len = %d!!\n", dmem_pkt_size, iram_pkt_size, FWHeaderSize, Len);531532/* download rsvd page. */533/* RsvdPageNum = GetTxBufferRsvdPageNum8814A(Adapter, _FALSE); */534#ifdef CONFIG_BCN_IC535/* TODO: check tx buffer and DMA size */536MaxRsvdPageBufSize = MAX_CMDBUF_SZ - TXDESC_OFFSET;537#else538MaxRsvdPageBufSize = MAX_XMIT_EXTBUF_SZ - TXDESC_OFFSET;/* RsvdPageNum*PageSize - 40 -16 modified for usb; */ /* TX_INFO_SIZE_8814AE; */539#endif540RTW_INFO("MaxRsvdPageBufSize %d, Total len %d\n", MaxRsvdPageBufSize, Len);541542BeaconHeaderInTxPacketBuf = txpktbuf_bndy * PageSize;543MEMOffsetInTxPacketBuf = OCPBASE_TXBUF_3081 + BeaconHeaderInTxPacketBuf + 40;/* TX_INFO_SIZE_8814AE; */544/* download DMEM */545while (dmem_pkt_size > 0) {546if (dmem_pkt_size > MaxRsvdPageBufSize) {547filesize_ram_block = MaxRsvdPageBufSize;548ls = _FALSE;549550last_block_size = dmem_pkt_size - MaxRsvdPageBufSize;551if (last_block_size < MaxRsvdPageBufSize) {552if (((last_block_size + 40) & 0x3F) == 0) /* Multiples of 64 */553filesize_ram_block -= 4;554}555} else {556filesize_ram_block = dmem_pkt_size;557ls = _TRUE;558}559fs = (pkt_offset == 0 ? _TRUE : _FALSE);560/* Return Beacon TCB. */561/* ReturnBeaconQueueTcb_8814A(Adapter); */562/* RTW_INFO("%d packet offset %d dmem_pkt_size %d\n", __LINE__,pkt_offset, dmem_pkt_size); */563SetDownLoadFwRsvdPagePkt_8814A(Adapter, pbuffer + FWHeaderSize + pkt_offset, filesize_ram_block);564bDownLoadRSVDPageOK = WaitDownLoadRSVDPageOK_3081(Adapter);565if (!bDownLoadRSVDPageOK) {566RTW_INFO("ERROR: DMEM bDownLoadRSVDPageOK is false!!\n");567return;568}569570IDDMADownLoadFW_3081(Adapter, MEMOffsetInTxPacketBuf, OCPBASE_DMEM_3081 + pkt_offset, filesize_ram_block, fs, ls);571dmem_pkt_size -= filesize_ram_block;572pkt_offset += filesize_ram_block;573}574575/* download IRAM */576pkt_offset = 0;577while (iram_pkt_size > 0) {578if (iram_pkt_size > MaxRsvdPageBufSize) {579filesize_ram_block = MaxRsvdPageBufSize;580ls = _FALSE;581582last_block_size = iram_pkt_size - MaxRsvdPageBufSize;583if (last_block_size < MaxRsvdPageBufSize) {584if (((last_block_size + 40) & 0x3F) == 0) /* Multiples of 64 */585filesize_ram_block -= 4;586}587} else {588filesize_ram_block = iram_pkt_size;589ls = _TRUE;590}591592fs = (pkt_offset == 0 ? _TRUE : _FALSE);593/* Return Beacon TCB. */594/* ReturnBeaconQueueTcb_8814A(Adapter); */595/* RTW_INFO("%d packet offset %d iram_pkt_size %d\n", __LINE__,pkt_offset, iram_pkt_size); */596SetDownLoadFwRsvdPagePkt_8814A(Adapter, pbuffer + Len - iram_pkt_size, filesize_ram_block);597598bDownLoadRSVDPageOK = WaitDownLoadRSVDPageOK_3081(Adapter);599if (!bDownLoadRSVDPageOK) {600RTW_INFO("ERROR: IRAM bDownLoadRSVDPageOK is false!!\n");601return;602}603604IDDMADownLoadFW_3081(Adapter, MEMOffsetInTxPacketBuf, OCPBASE_IMEM_3081 + pkt_offset, filesize_ram_block, fs, ls);605606iram_pkt_size -= filesize_ram_block;607pkt_offset += filesize_ram_block;608}609610/* restore bcn_ctrl */611rtw_write8(Adapter, REG_BCN_CTRL, bcn_ctrl);612613/* To make sure that if there exists an adapter which would like to send beacon. */614/* If exists, the origianl value of 0x422[6] will be 1, we should check this to */615/* prevent from setting 0x422[6] to 0 after download reserved page, or it will cause */616/* the beacon cannot be sent by HW. */617/* 2010.06.23. Added by tynli. */618if (bSendBeacon)619rtw_write8(Adapter, REG_FWHW_TXQ_CTRL_8814A + 2, tmpReg422);620621/* Do not enable HW DMA BCN or it will cause Pcie interface hang by timing issue. 2011.11.24. by tynli. */622/* if(!Adapter->bEnterPnpSleep) */623{624/* Clear CR[8] or beacon packet will not be send to TxBuf anymore. */625u1bTmp = rtw_read8(Adapter, REG_CR_8814A + 1);626rtw_write8(Adapter, REG_CR_8814A + 1, (u1bTmp & (~BIT0)));627}628629u1bTmp = rtw_read8(Adapter, REG_8051FW_CTRL_8814A); /* add by gw for flags to show the fw download ok 20130826 */630if (u1bTmp & DMEM_CHKSUM_OK) {631if (u1bTmp & IMEM_CHKSUM_OK) {632u8 tem;633tem = rtw_read8(Adapter, REG_8051FW_CTRL_8814A + 1);634rtw_write8(Adapter, REG_8051FW_CTRL_8814A + 1, (tem | BIT6));635}636}637}638639s32640_FWFreeToGo8814A(641PADAPTER Adapter642)643{644u32 counter = 0;645u32 value32;646647/* polling CheckSum report */648do {649rtw_mdelay_os(50);650value32 = rtw_read32(Adapter, REG_8051FW_CTRL_8814A);651652} while ((counter++ < 100) && (!(value32 & CPU_DL_READY)));653654if (counter >= 100) {655return _FAIL;656}657658659return _SUCCESS;660}661662663#ifdef CONFIG_FILE_FWIMG664u8 FwBuffer8814[FW_SIZE];665#endif /* CONFIG_FILE_FWIMG */666667s32668FirmwareDownload8814A(669PADAPTER Adapter,670BOOLEAN bUsedWoWLANFw671)672{673s32 rtStatus = _SUCCESS;674u8 write_fw = 0;675systime fwdl_start_time;676PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);677678u8 *pFwImageFileName;679u8 *pucMappedFile = NULL;680PRT_FIRMWARE_8814 pFirmware = NULL;681u8 *pFwHdr = NULL;682u8 *pFirmwareBuf;683u32 FirmwareLen;684#ifdef CONFIG_FILE_FWIMG685u8 *fwfilepath;686#endif687u32 u32tmp;688689690pFirmware = (PRT_FIRMWARE_8814)rtw_zmalloc(sizeof(RT_FIRMWARE_8814));691if (!pFirmware) {692rtStatus = _FAIL;693goto exit;694}695696#ifdef CONFIG_FILE_FWIMG697#ifdef CONFIG_WOWLAN698if (bUsedWoWLANFw)699fwfilepath = rtw_fw_wow_file_path;700else701#endif /* CONFIG_WOWLAN */702{703fwfilepath = rtw_fw_file_path;704}705706if (rtw_is_file_readable(fwfilepath) == _TRUE) {707RTW_INFO("%s acquire FW from file:%s\n", __FUNCTION__, fwfilepath);708pFirmware->eFWSource = FW_SOURCE_IMG_FILE;709} else710#endif /* CONFIG_FILE_FWIMG */711{712RTW_INFO("%s fw source from Header\n", __FUNCTION__);713pFirmware->eFWSource = FW_SOURCE_HEADER_FILE;714}715716switch (pFirmware->eFWSource) {717case FW_SOURCE_IMG_FILE:718#ifdef CONFIG_FILE_FWIMG719rtStatus = rtw_retrieve_from_file(fwfilepath, FwBuffer8814, FW_SIZE);720pFirmware->ulFwLength = rtStatus >= 0 ? rtStatus : 0;721pFirmware->szFwBuffer = FwBuffer8814;722RTW_INFO("%s fw size: %d\n", __FUNCTION__, pFirmware->ulFwLength);723#endif /* CONFIG_FILE_FWIMG */724break;725case FW_SOURCE_HEADER_FILE:726if (bUsedWoWLANFw) {727#ifdef CONFIG_WOWLAN728pFirmware->szFwBuffer = array_mp_8814a_fw_wowlan;729pFirmware->ulFwLength = array_length_mp_8814a_fw_wowlan;730RTW_INFO("%s fw:%s, size: %d\n", __FUNCTION__, "WoWLAN", pFirmware->ulFwLength);731#endif /* CONFIG_WOWLAN */732} else {733pFirmware->szFwBuffer = array_mp_8814a_fw_nic;734pFirmware->ulFwLength = array_length_mp_8814a_fw_nic;735RTW_INFO("%s fw:%s, size: %d\n", __FUNCTION__, "NIC", pFirmware->ulFwLength);736}737break;738}739740if (pFirmware->ulFwLength == 0) {741RTW_ERR("Firmware size:%u\n", pFirmware->ulFwLength);742goto exit;743}744745if ((pFirmware->ulFwLength - 64) > FW_SIZE) {746rtStatus = _FAIL;747RTW_ERR("Firmware size:%u exceed %u\n", pFirmware->ulFwLength, FW_SIZE);748goto exit;749}750751pFirmwareBuf = pFirmware->szFwBuffer;752FirmwareLen = pFirmware->ulFwLength;753pFwHdr = (u8 *)pFirmware->szFwBuffer;754755pHalData->firmware_version = (u16)GET_FIRMWARE_HDR_VERSION_3081(pFwHdr);756pHalData->firmware_sub_version = (u16)GET_FIRMWARE_HDR_SUB_VER_3081(pFwHdr);757pHalData->FirmwareSignature = (u16)GET_FIRMWARE_HDR_SIGNATURE_3081(pFwHdr);758759RTW_INFO("%s: fw_ver=%d fw_subver=%d sig=0x%x\n",760__FUNCTION__, pHalData->firmware_version, pHalData->firmware_sub_version, pHalData->FirmwareSignature);761fwdl_start_time = rtw_get_current_time();762763_FWDownloadEnable_8814A(Adapter, _TRUE);764765_3081Disable8814A(Adapter);/* add by gw 2013026 for disable mcu core */766767/* DDMA reset, suggest by MAC yodar */768u32tmp = rtw_read32(Adapter, REG_CPU_DMEM_CON_8814A);769rtw_write32(Adapter, REG_CPU_DMEM_CON_8814A, u32tmp&(~BIT16));770rtw_write32(Adapter, REG_CPU_DMEM_CON_8814A, u32tmp | BIT16);771772HalROMDownloadFWRSVDPage8814A(Adapter, pFirmwareBuf, FirmwareLen);773774_3081Enable8814A(Adapter);/* add by gw 2013026 for Enable mcu core */775776_FWDownloadEnable_8814A(Adapter, _FALSE);777778rtStatus = _FWFreeToGo8814A(Adapter);779if (_SUCCESS != rtStatus)780goto fwdl_stat;781782fwdl_stat:783RTW_INFO("FWDL %s. write_fw:%u, %dms\n"784, (rtStatus == _SUCCESS) ? "success" : "fail"785, write_fw786, rtw_get_passing_time_ms(fwdl_start_time)787);788789exit:790if (pFirmware)791rtw_mfree((u8 *)pFirmware, sizeof(RT_FIRMWARE_8814));792793InitializeFirmwareVars8814(Adapter);794795return rtStatus;796}797798799800void InitializeFirmwareVars8814(PADAPTER padapter)801{802PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);803struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);804805/* Init Fw LPS related. */806pwrpriv->bFwCurrentInPSMode = _FALSE;807808/* Init H2C cmd.*/809rtw_write8(padapter, REG_HMETFR_8814A, 0x0f);810811/* Init H2C counter. by tynli. 2009.12.09. */812pHalData->LastHMEBoxNum = 0;813}814815#if 0816/* */817/* Description: Determine the contents of H2C BT_FW_PATCH Command sent to FW. */818/* 2013.01.23 by tynli */819/* Porting from 8723B. 2013.04.01 */820/* */821void822SetFwBTFwPatchCmd(823PADAPTER Adapter,824u16 FwSize825)826{827u8 u1BTFwPatchParm[6] = {0};828829RTW_INFO("SetFwBTFwPatchCmd_8821(): FwSize = %d\n", FwSize);830831/* SET_8812_H2CCMD_BT_FW_PATCH_ENABLE(u1BTFwPatchParm, 1); */832SET_H2CCMD_BT_FW_PATCH_SIZE(u1BTFwPatchParm, FwSize);833SET_H2CCMD_BT_FW_PATCH_ADDR0(u1BTFwPatchParm, 0);834SET_H2CCMD_BT_FW_PATCH_ADDR1(u1BTFwPatchParm, 0xa0);835SET_H2CCMD_BT_FW_PATCH_ADDR2(u1BTFwPatchParm, 0x10);836SET_H2CCMD_BT_FW_PATCH_ADDR3(u1BTFwPatchParm, 0x80);837838fill_h2c_cmd_8812(Adapter, H2C_BT_FW_PATCH, 6 , u1BTFwPatchParm);839}840841842int ReservedPage_Compare(PADAPTER Adapter, PRT_MP_FIRMWARE pFirmware, u32 BTPatchSize)843{844u8 temp, ret, lastBTsz;845u32 u1bTmp = 0, address_start = 0, count = 0, i = 0;846u8 *myBTFwBuffer = NULL;847848myBTFwBuffer = rtw_zmalloc(BTPatchSize);849if (myBTFwBuffer == NULL) {850RTW_INFO("%s can't be executed due to the failed malloc.\n", __FUNCTION__);851Adapter->mppriv.bTxBufCkFail = _TRUE;852return _FALSE;853}854855temp = rtw_read8(Adapter, 0x209);856857address_start = (temp * 128) / 8;858859rtw_write32(Adapter, 0x140, 0x00000000);860rtw_write32(Adapter, 0x144, 0x00000000);861rtw_write32(Adapter, 0x148, 0x00000000);862863rtw_write8(Adapter, 0x106, 0x69);864865866for (i = 0; i < (BTPatchSize / 8); i++) {867rtw_write32(Adapter, 0x140, address_start + 5 + i) ;868869/* polling until reg 0x140[23]=1; */870do {871u1bTmp = rtw_read32(Adapter, 0x140);872if (u1bTmp & BIT(23)) {873ret = _SUCCESS;874break;875}876count++;877RTW_INFO("0x140=%x, wait for 10 ms (%d) times.\n", u1bTmp, count);878rtw_msleep_os(10); /* 10ms */879} while (!(u1bTmp & BIT(23)) && count < 50);880881myBTFwBuffer[i * 8 + 0] = rtw_read8(Adapter, 0x144);882myBTFwBuffer[i * 8 + 1] = rtw_read8(Adapter, 0x145);883myBTFwBuffer[i * 8 + 2] = rtw_read8(Adapter, 0x146);884myBTFwBuffer[i * 8 + 3] = rtw_read8(Adapter, 0x147);885myBTFwBuffer[i * 8 + 4] = rtw_read8(Adapter, 0x148);886myBTFwBuffer[i * 8 + 5] = rtw_read8(Adapter, 0x149);887myBTFwBuffer[i * 8 + 6] = rtw_read8(Adapter, 0x14a);888myBTFwBuffer[i * 8 + 7] = rtw_read8(Adapter, 0x14b);889}890891rtw_write32(Adapter, 0x140, address_start + 5 + BTPatchSize / 8) ;892893lastBTsz = BTPatchSize % 8;894895/* polling until reg 0x140[23]=1; */896u1bTmp = 0;897count = 0;898do {899u1bTmp = rtw_read32(Adapter, 0x140);900if (u1bTmp & BIT(23)) {901ret = _SUCCESS;902break;903}904count++;905RTW_INFO("0x140=%x, wait for 10 ms (%d) times.\n", u1bTmp, count);906rtw_msleep_os(10); /* 10ms */907} while (!(u1bTmp & BIT(23)) && count < 50);908909for (i = 0; i < lastBTsz; i++)910myBTFwBuffer[(BTPatchSize / 8) * 8 + i] = rtw_read8(Adapter, (0x144 + i));911912913for (i = 0; i < BTPatchSize; i++) {914if (myBTFwBuffer[i] != pFirmware->szFwBuffer[i]) {915RTW_INFO(" In direct myBTFwBuffer[%d]=%x , pFirmware->szFwBuffer=%x\n", i, myBTFwBuffer[i], pFirmware->szFwBuffer[i]);916Adapter->mppriv.bTxBufCkFail = _TRUE;917break;918}919}920921if (myBTFwBuffer != NULL)922rtw_mfree(myBTFwBuffer, BTPatchSize);923924return _TRUE;925}926927#ifdef CONFIG_RTL8821A928s32 FirmwareDownloadBT(PADAPTER padapter, PRT_MP_FIRMWARE pFirmware)929{930s32 rtStatus;931u8 *pBTFirmwareBuf;932u32 BTFirmwareLen;933u8 download_time;934s8 i;935936937rtStatus = _SUCCESS;938pBTFirmwareBuf = NULL;939BTFirmwareLen = 0;940941/* */942/* Patch BT Fw. Download BT RAM code to Tx packet buffer. */943/* */944if (GET_HAL_DATA(padapter)->bBTFWReady) {945RTW_INFO("%s: BT Firmware is ready!!\n", __FUNCTION__);946return _FAIL;947}948949#ifdef CONFIG_FILE_FWIMG950if (rtw_is_file_readable(rtw_fw_mp_bt_file_path) == _TRUE) {951RTW_INFO("%s: accquire MP BT FW from file:%s\n", __FUNCTION__, rtw_fw_mp_bt_file_path);952953rtStatus = rtw_retrieve_from_file(rtw_fw_mp_bt_file_path, FwBuffer, 0x8000);954BTFirmwareLen = rtStatus >= 0 ? rtStatus : 0;955pBTFirmwareBuf = FwBuffer;956} else957#endif /* CONFIG_FILE_FWIMG */958{959#ifdef CONFIG_EMBEDDED_FWIMG960RTW_INFO("%s: Download MP BT FW from header\n", __FUNCTION__);961962pBTFirmwareBuf = (u8 *)Rtl8821A_BT_MP_Patch_FW;963BTFirmwareLen = Rtl8812BFwBTImgArrayLength;964pFirmware->szFwBuffer = pBTFirmwareBuf;965pFirmware->ulFwLength = BTFirmwareLen;966#endif /* CONFIG_EMBEDDED_FWIMG */967}968969RTW_INFO("%s: MP BT Firmware size=%d\n", __FUNCTION__, BTFirmwareLen);970971/* for h2c cam here should be set to true */972GET_HAL_DATA(padapter)->bFWReady = _TRUE;973974download_time = (BTFirmwareLen + 4095) / 4096;975RTW_INFO("%s: download_time is %d\n", __FUNCTION__, download_time);976977/* Download BT patch Fw. */978for (i = (download_time - 1); i >= 0; i--) {979if (i == (download_time - 1)) {980rtStatus = _WriteBTFWtoTxPktBuf8812(padapter, pBTFirmwareBuf + (4096 * i), (BTFirmwareLen - (4096 * i)), 1);981RTW_INFO("%s: start %d, len %d, time 1\n", __FUNCTION__, 4096 * i, BTFirmwareLen - (4096 * i));982} else {983rtStatus = _WriteBTFWtoTxPktBuf8812(padapter, pBTFirmwareBuf + (4096 * i), 4096, (download_time - i));984RTW_INFO("%s: start %d, len 4096, time %d\n", __FUNCTION__, 4096 * i, download_time - i);985}986987if (rtStatus != _SUCCESS) {988RTW_INFO("%s: BT Firmware download to Tx packet buffer fail!\n", __FUNCTION__);989GET_HAL_DATA(padapter)->bBTFWReady = _FALSE;990return rtStatus;991}992}993994ReservedPage_Compare(padapter, pFirmware, BTFirmwareLen);995996GET_HAL_DATA(padapter)->bBTFWReady = _TRUE;997SetFwBTFwPatchCmd_8821(padapter, (u16)BTFirmwareLen);998rtStatus = _CheckWLANFwPatchBTFwReady_8821A(padapter);9991000RTW_INFO("<===%s: return %s!\n", __FUNCTION__, rtStatus == _SUCCESS ? "SUCCESS" : "FAIL");1001return rtStatus;1002}1003#endif /* CONFIG_RTL8821A */1004#endif10051006/* ***********************************************************1007* Efuse related code1008* *********************************************************** */1009void1010hal_EfuseParseBTCoexistInfo8814A(1011PADAPTER Adapter,1012u8 *hwinfo,1013BOOLEAN AutoLoadFail1014)1015{1016HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);1017u8 tempval = 0x0;10181019if (!AutoLoadFail) {1020tempval = hwinfo[EEPROM_RF_BOARD_OPTION_8814];1021if (((tempval & 0xe0) >> 5) == 0x1) /* [7:5] */1022pHalData->EEPROMBluetoothCoexist = 1;1023else1024pHalData->EEPROMBluetoothCoexist = 0;1025pHalData->EEPROMBluetoothType = BT_RTL8814A;10261027tempval = hwinfo[EEPROM_RF_BT_SETTING_8814];1028if (tempval != 0xFF)1029pHalData->EEPROMBluetoothAntNum = (tempval&0x1) ? Ant_x1 : Ant_x2;1030} else {1031pHalData->EEPROMBluetoothCoexist = 0;1032pHalData->EEPROMBluetoothType = BT_RTL8814A;1033pHalData->EEPROMBluetoothAntNum = Ant_x1;1034}10351036RTW_INFO("EEPROMBluetoothCoexist = %d, EEPROMBluetoothAntNum = %s\n",1037pHalData->EEPROMBluetoothCoexist,1038(pHalData->EEPROMBluetoothAntNum == Ant_x1) ? "Ant_x1" : "Ant_x2");1039}10401041void1042hal_ReadPROMVersion8814A(1043PADAPTER Adapter,1044u8 *PROMContent,1045BOOLEAN AutoloadFail1046)1047{1048HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);10491050if (AutoloadFail)1051pHalData->EEPROMVersion = EEPROM_Default_Version;1052else {1053pHalData->EEPROMVersion = *(u8 *)&PROMContent[EEPROM_VERSION_8814];1054if (pHalData->EEPROMVersion == 0xFF)1055pHalData->EEPROMVersion = EEPROM_Default_Version;1056}1057}10581059void1060hal_ReadTxPowerInfo8814A(1061PADAPTER Adapter,1062u8 *PROMContent,1063BOOLEAN AutoLoadFail1064)1065{1066HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);10671068/* 2010/10/19 MH Add Regulator recognize for CU. */1069if (!AutoLoadFail) {1070struct registry_priv *registry_par = &Adapter->registrypriv;10711072pHalData->EEPROMRegulatory = (PROMContent[EEPROM_RF_BOARD_OPTION_8814] & 0x7); /* bit0~2 */1073if (PROMContent[EEPROM_RF_BOARD_OPTION_8814] == 0xFF)1074pHalData->EEPROMRegulatory = (EEPROM_DEFAULT_BOARD_OPTION & 0x7); /* bit0~2 */1075} else1076pHalData->EEPROMRegulatory = 0;10771078RTW_INFO("EEPROMRegulatory = 0x%x\n", pHalData->EEPROMRegulatory);10791080}10811082void1083hal_ReadBoardType8814A(1084PADAPTER Adapter,1085u8 *PROMContent,1086BOOLEAN AutoloadFail1087)1088{108910901091HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);10921093if (!AutoloadFail) {1094pHalData->InterfaceSel = (PROMContent[EEPROM_RF_BOARD_OPTION_8814] & 0xE0) >> 5;1095if (PROMContent[EEPROM_RF_BOARD_OPTION_8814] == 0xFF)1096pHalData->InterfaceSel = (EEPROM_DEFAULT_BOARD_OPTION & 0xE0) >> 5;1097} else1098pHalData->InterfaceSel = 0;1099}11001101enum rf_type rtl8814a_rfpath_decision(_adapter *adapter)1102{1103HAL_DATA_TYPE *hal_data = GET_HAL_DATA(adapter);1104struct registry_priv *regpriv = &adapter->registrypriv;1105enum rf_type rf_path = RF_TYPE_MAX;1106u8 trx_antenna;11071108if (!hal_data->bautoload_fail_flag) {1109u8 option = hal_data->efuse_eeprom_data[EEPROM_TRX_ANTENNA_OPTION_8814];11101111if (option == 0xff) {1112trx_antenna = RF_4T4R;1113RTW_INFO("EEPROM RF set 4T4R\n");1114} else if (option == 0xee) {1115trx_antenna = RF_3T3R;1116RTW_INFO("EEPROM RF set 3T3R\n");1117} else if (option == 0x66) {1118trx_antenna = RF_2T2R;1119RTW_INFO("EEPROM RF set 2T2R\n");1120} else if (option == 0x6f) {1121trx_antenna = RF_2T4R;1122RTW_INFO("EEPROM RF set 2T4R\n");1123} else {1124trx_antenna = RF_2T4R;1125RTW_INFO("unknown EEPROM RF set, default to 2T4R\n");1126}1127} else {1128trx_antenna = RF_2T4R;1129RTW_INFO("AutoloadFail, default to 2T4R\n");1130}11311132/* if driver doesn't set rf_path in registry, use the value of EEPROM */1133if (!RF_TYPE_VALID(regpriv->rf_path)) {1134if ((trx_antenna == RF_4T4R || trx_antenna == RF_3T3R)1135#ifdef CONFIG_USB_HCI1136&& IS_SUPER_SPEED_USB(adapter)1137#endif1138)1139rf_path = RF_3T3R;1140else if (trx_antenna == RF_2T4R)1141rf_path = RF_2T4R;1142else {1143rf_path = RF_2T4R;1144RTW_INFO("default rf type: %d\n", rf_path);1145}1146} else {1147rf_path = regpriv->rf_path;1148#ifdef CONFIG_USB_HCI1149if (!IS_SUPER_SPEED_USB(adapter))1150rf_path = RF_2T4R;1151#endif1152}11531154RTW_INFO("[8814A] Final rf_config: %d\n", rf_path);11551156return rf_path;1157}11581159void1160hal_Read_TRX_antenna_8814A(1161PADAPTER Adapter,1162u8 *PROMContent,1163BOOLEAN AutoloadFail1164)1165{1166/* move to rtl8814a_rfpath_decision */1167}11681169void1170hal_ReadThermalMeter_8814A(1171PADAPTER Adapter,1172u8 *PROMContent,1173BOOLEAN AutoloadFail1174)1175{1176HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);11771178pHalData->eeprom_thermal_meter = 0xff;11791180if (!AutoloadFail)1181pHalData->eeprom_thermal_meter = PROMContent[EEPROM_THERMAL_METER_8814];11821183#if 0 /* ToDo: check with RF */1184else1185pHalData->eeprom_thermal_meter = EEPROM_Default_ThermalMeter_8814A;11861187if ((pHalData->eeprom_thermal_meter == 0xff) || (_TRUE == AutoloadFail)) {1188pHalData->odmpriv.RFCalibrateInfo.bAPKThermalMeterIgnore = _TRUE;1189pHalData->eeprom_thermal_meter = EEPROM_Default_ThermalMeter_8814A;1190}1191#endif11921193/* pHalData->ThermalMeter[0] = pHalData->eeprom_thermal_meter; */1194RTW_INFO("ThermalMeter = 0x%x\n", pHalData->eeprom_thermal_meter);1195}119611971198void hal_ReadRemoteWakeup_8814A(1199PADAPTER padapter,1200u8 *hwinfo,1201BOOLEAN AutoLoadFail1202)1203{1204HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);1205struct pwrctrl_priv *pwrctl = adapter_to_pwrctl(padapter);1206u8 tmpvalue;12071208if (AutoLoadFail) {1209pwrctl->bHWPowerdown = _FALSE;1210pwrctl->bSupportRemoteWakeup = _FALSE;1211} else {1212/* decide hw if support remote wakeup function */1213/* if hw supported, 8051 (SIE) will generate WeakUP signal( D+/D- toggle) when autoresume */1214#if 01215/* todo: wowlan should check the efuse again */1216#ifdef CONFIG_USB_HCI1217if (IS_HARDWARE_TYPE_8821U(padapter))1218pwrctl->bSupportRemoteWakeup = (hwinfo[EEPROM_USB_OPTIONAL_FUNCTION0_8811AU] & BIT1) ? _TRUE : _FALSE;1219else1220pwrctl->bSupportRemoteWakeup = (hwinfo[EEPROM_USB_OPTIONAL_FUNCTION0] & BIT1) ? _TRUE : _FALSE;1221#endif /* CONFIG_USB_HCI */1222#endif1223RTW_INFO("%s...bSupportRemoteWakeup(%x)\n", __FUNCTION__, pwrctl->bSupportRemoteWakeup);1224}1225}12261227void1228hal_ReadChannelPlan8814A(1229PADAPTER padapter,1230u8 *hwinfo,1231BOOLEAN AutoLoadFail1232)1233{1234hal_com_config_channel_plan(1235padapter1236, hwinfo ? &hwinfo[EEPROM_COUNTRY_CODE_8814] : NULL1237, hwinfo ? hwinfo[EEPROM_ChannelPlan_8814] : 0xFF1238, padapter->registrypriv.alpha21239, padapter->registrypriv.channel_plan1240, RTW_CHPLAN_REALTEK_DEFINE1241, AutoLoadFail1242);1243}12441245void hal_GetRxGainOffset_8814A(1246PADAPTER Adapter,1247u8 *PROMContent,1248BOOLEAN AutoloadFail1249)1250{1251HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);1252struct registry_priv *pregistrypriv = &Adapter->registrypriv;12531254pHalData->RxGainOffset[0] = 0;1255pHalData->RxGainOffset[1] = 0;1256pHalData->RxGainOffset[2] = 0;1257pHalData->RxGainOffset[3] = 0;12581259if (((pregistrypriv->reg_rxgain_offset_2g != 0) && (pregistrypriv->reg_rxgain_offset_5gl != 0)) &&1260((pregistrypriv->reg_rxgain_offset_5gm != 0) && (pregistrypriv->reg_rxgain_offset_5gh != 0))) {12611262pHalData->RxGainOffset[0] = pregistrypriv->reg_rxgain_offset_2g;1263pHalData->RxGainOffset[1] = pregistrypriv->reg_rxgain_offset_5gl;1264pHalData->RxGainOffset[2] = pregistrypriv->reg_rxgain_offset_5gm;1265pHalData->RxGainOffset[3] = pregistrypriv->reg_rxgain_offset_5gh;1266RTW_INFO("%s():Use registrypriv 0x%x 0x%x 0x%x 0x%x !!\n", __func__, pregistrypriv->reg_rxgain_offset_2g, pregistrypriv->reg_rxgain_offset_5gl, pregistrypriv->reg_rxgain_offset_5gm,1267pregistrypriv->reg_rxgain_offset_5gh);12681269} else {1270RTW_INFO("%s(): AutoloadFail = %d!!\n", __func__, AutoloadFail);1271pHalData->RxGainOffset[0] = PROMContent[EEPROM_IG_OFFSET_4_CD_2G_8814A];1272pHalData->RxGainOffset[0] |= (PROMContent[EEPROM_IG_OFFSET_4_AB_2G_8814A]) << 8;1273pHalData->RxGainOffset[1] = PROMContent[EEPROM_IG_OFFSET_4_CD_5GL_8814A];1274pHalData->RxGainOffset[1] |= (PROMContent[EEPROM_IG_OFFSET_4_AB_5GL_8814A]) << 8;1275pHalData->RxGainOffset[2] = PROMContent[EEPROM_IG_OFFSET_4_CD_5GM_8814A];1276pHalData->RxGainOffset[2] |= (PROMContent[EEPROM_IG_OFFSET_4_AB_5GM_8814A]) << 8;1277pHalData->RxGainOffset[3] = PROMContent[EEPROM_IG_OFFSET_4_CD_5GH_8814A];1278pHalData->RxGainOffset[3] |= (PROMContent[EEPROM_IG_OFFSET_4_AB_5GH_8814A]) << 8;1279}1280RTW_INFO("hal_GetRxGainOffset_8814A(): RegRxGainOffset_2G = 0x%x!!\n", pHalData->RxGainOffset[0]);1281RTW_INFO("hal_GetRxGainOffset_8814A(): RegRxGainOffset_5GL = 0x%x!!\n", pHalData->RxGainOffset[1]);1282RTW_INFO("hal_GetRxGainOffset_8814A(): RegRxGainOffset_5GM = 0x%x!!\n", pHalData->RxGainOffset[2]);1283RTW_INFO("hal_GetRxGainOffset_8814A(): RegRxGainOffset_5GH = 0x%x!!\n", pHalData->RxGainOffset[3]);1284}128512861287void Hal_EfuseParseKFreeData_8814A(1288PADAPTER Adapter,1289u8 *PROMContent,1290BOOLEAN AutoloadFail)1291{1292#ifdef CONFIG_RF_POWER_TRIM12931294HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);1295struct kfree_data_t *kfree_data = &pHalData->kfree_data;1296u8 kfreePhydata[KFREE_GAIN_DATA_LENGTH_8814A];1297u32 i = 0, j = 2, chidx = 0, efuseaddr = 0;1298u8 rfpath = 0;12991300if (GET_PG_KFREE_ON_8814A(PROMContent) && PROMContent[0xc8] != 0xff)1301kfree_data->flag |= KFREE_FLAG_ON;1302if (GET_PG_KFREE_THERMAL_K_ON_8814A(PROMContent) && PROMContent[0xc8] != 0xff)1303kfree_data->flag |= KFREE_FLAG_THERMAL_K_ON;13041305if (Adapter->registrypriv.RegPwrTrimEnable == 1) {1306kfree_data->flag |= KFREE_FLAG_ON;1307kfree_data->flag |= KFREE_FLAG_THERMAL_K_ON;1308}13091310_rtw_memset(kfree_data->bb_gain, 0xff, BB_GAIN_NUM * RF_PATH_MAX);13111312if (kfree_data->flag & KFREE_FLAG_ON) {13131314for (i = 0; i < KFREE_GAIN_DATA_LENGTH_8814A; i++) {1315efuseaddr = PPG_BB_GAIN_2G_TXBA_OFFSET_8814A - i;13161317if (efuseaddr <= PPG_BB_GAIN_2G_TXBA_OFFSET_8814A) {1318efuse_OneByteRead(Adapter, efuseaddr, &kfreePhydata[i], _FALSE);1319RTW_INFO("%s,kfreePhydata[%d] = %x\n", __func__, i, kfreePhydata[i]);1320}1321}1322kfree_data->bb_gain[0][RF_PATH_A]1323= (kfreePhydata[0] & PPG_BB_GAIN_2G_TX_OFFSET_MASK);1324kfree_data->bb_gain[0][RF_PATH_B]1325= (kfreePhydata[0] & PPG_BB_GAIN_2G_TXB_OFFSET_MASK) >> 4;1326kfree_data->bb_gain[0][RF_PATH_C]1327= (kfreePhydata[1] & PPG_BB_GAIN_2G_TX_OFFSET_MASK);1328kfree_data->bb_gain[0][RF_PATH_D]1329= (kfreePhydata[1] & PPG_BB_GAIN_2G_TXB_OFFSET_MASK) >> 4;13301331for (chidx = 1; chidx <= BB_GAIN_5GHB; chidx++) {1332for (rfpath = RF_PATH_A; rfpath < RF_PATH_MAX; rfpath++)1333kfree_data->bb_gain[chidx][rfpath] = kfreePhydata[j + rfpath] & PPG_BB_GAIN_5G_TX_OFFSET_MASK;13341335j = j + RF_PATH_MAX;1336}1337}13381339if (kfree_data->flag & KFREE_FLAG_THERMAL_K_ON)1340pHalData->eeprom_thermal_meter += kfree_data->thermal;13411342RTW_INFO("registrypriv.RegPwrTrimEnable = %d\n", Adapter->registrypriv.RegPwrTrimEnable);13431344RTW_INFO("kfree flag:%u\n", kfree_data->flag);1345if (Adapter->registrypriv.RegPwrTrimEnable == 1 || kfree_data->flag & KFREE_FLAG_ON) {1346for (chidx = 0 ; chidx <= BB_GAIN_5GHB; chidx++) {1347for (rfpath = RF_PATH_A; rfpath < RF_PATH_MAX; rfpath++)1348RTW_INFO("bb_gain[%d][%d]= %x\n", chidx, rfpath, kfree_data->bb_gain[chidx][rfpath]);1349}1350}13511352#endif /*CONFIG_RF_POWER_TRIM */1353}135413551356void1357hal_EfuseParseXtal_8814A(1358PADAPTER pAdapter,1359u8 *hwinfo,1360BOOLEAN AutoLoadFail1361)1362{1363HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);13641365if (!AutoLoadFail) {1366pHalData->crystal_cap = hwinfo[EEPROM_XTAL_8814];1367if (pHalData->crystal_cap == 0xFF)1368pHalData->crystal_cap = EEPROM_Default_CrystalCap_8814; /* what value should 8814 set? */1369} else1370pHalData->crystal_cap = EEPROM_Default_CrystalCap_8814;1371RTW_INFO("crystal_cap: 0x%2x\n", pHalData->crystal_cap);1372}13731374void1375hal_ReadAntennaDiversity8814A(1376PADAPTER pAdapter,1377u8 *PROMContent,1378BOOLEAN AutoLoadFail1379)1380{1381HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);13821383pHalData->AntDivCfg = 0;13841385RTW_INFO("SWAS: bHwAntDiv = %x, TRxAntDivType = %x\n",1386pHalData->AntDivCfg, pHalData->TRxAntDivType);1387}13881389void1390hal_ReadPAType_8814A(1391PADAPTER Adapter,1392u8 *PROMContent,1393BOOLEAN AutoloadFail,1394u8 *pPAType,1395u8 *pLNAType1396)1397{1398HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);1399u8 LNAType_AB, LNAType_CD;14001401if (!AutoloadFail) {1402u8 RFEType = PROMContent[EEPROM_RFE_OPTION_8814];14031404if (GetRegAmplifierType2G(Adapter) == 0) { /* AUTO */1405*pPAType = ReadLE1Byte(&PROMContent[EEPROM_PA_TYPE_8814]);14061407LNAType_AB = ReadLE1Byte(&PROMContent[EEPROM_LNA_TYPE_AB_2G_8814]);1408LNAType_CD = ReadLE1Byte(&PROMContent[EEPROM_LNA_TYPE_CD_2G_8814]);14091410if (*pPAType == 0xFF && RFEType == 0xFF)1411pHalData->ExternalPA_2G = (GetRegAmplifierType2G(Adapter) & ODM_BOARD_EXT_PA) ? 1 : 0;1412else1413pHalData->ExternalPA_2G = (*pPAType & BIT4) ? 1 : 0;14141415if (LNAType_AB == 0xFF)1416pHalData->ExternalLNA_2G = (GetRegAmplifierType2G(Adapter) & ODM_BOARD_EXT_LNA) ? 1 : 0;1417else1418pHalData->ExternalLNA_2G = (LNAType_AB & BIT3) ? 1 : 0;14191420*pLNAType = (LNAType_AB & BIT3) << 1 | (LNAType_AB & BIT7) >> 2 |1421(LNAType_CD & BIT3) << 3 | (LNAType_CD & BIT7);1422} else {1423pHalData->ExternalPA_2G = (GetRegAmplifierType2G(Adapter) & ODM_BOARD_EXT_PA) ? 1 : 0;1424pHalData->ExternalLNA_2G = (GetRegAmplifierType2G(Adapter) & ODM_BOARD_EXT_LNA) ? 1 : 0;1425}14261427if (GetRegAmplifierType5G(Adapter) == 0) { /* AUTO */1428LNAType_AB = ReadLE1Byte(&PROMContent[EEPROM_LNA_TYPE_AB_5G_8814]);1429LNAType_CD = ReadLE1Byte(&PROMContent[EEPROM_LNA_TYPE_CD_5G_8814]);14301431if (*pPAType == 0xFF && RFEType == 0xFF)1432pHalData->external_pa_5g = (GetRegAmplifierType5G(Adapter) & ODM_BOARD_EXT_PA) ? 1 : 0;1433else1434pHalData->external_pa_5g = (*pPAType & BIT0) ? 1 : 0;14351436if (LNAType_AB == 0xFF)1437pHalData->external_lna_5g = (GetRegAmplifierType5G(Adapter) & ODM_BOARD_EXT_LNA) ? 1 : 0;1438else1439pHalData->external_lna_5g = (LNAType_AB & BIT3) ? 1 : 0;14401441(*pLNAType) |= ((LNAType_AB & BIT3) >> 3 | (LNAType_AB & BIT7) >> 6 |1442(LNAType_CD & BIT3) >> 1 | (LNAType_CD & BIT7) >> 4);1443} else {1444pHalData->external_pa_5g = (GetRegAmplifierType5G(Adapter) & ODM_BOARD_EXT_PA_5G) ? 1 : 0;1445pHalData->external_lna_5g = (GetRegAmplifierType5G(Adapter) & ODM_BOARD_EXT_LNA_5G) ? 1 : 0;1446}1447} else {1448pHalData->ExternalPA_2G = EEPROM_Default_PAType;1449pHalData->external_pa_5g = 0xFF;1450pHalData->ExternalLNA_2G = EEPROM_Default_LNAType;1451pHalData->external_lna_5g = 0xFF;14521453if (GetRegAmplifierType2G(Adapter) == 0) {1454pHalData->ExternalPA_2G = 0;1455pHalData->ExternalLNA_2G = 0;1456} else {1457pHalData->ExternalPA_2G = (GetRegAmplifierType2G(Adapter) & ODM_BOARD_EXT_PA) ? 1 : 0;1458pHalData->ExternalLNA_2G = (GetRegAmplifierType2G(Adapter) & ODM_BOARD_EXT_LNA) ? 1 : 0;1459}1460if (GetRegAmplifierType5G(Adapter) == 0) {1461pHalData->external_pa_5g = 0;1462pHalData->external_lna_5g = 0;1463} else {1464pHalData->external_pa_5g = (GetRegAmplifierType5G(Adapter) & ODM_BOARD_EXT_PA_5G) ? 1 : 0;1465pHalData->external_lna_5g = (GetRegAmplifierType5G(Adapter) & ODM_BOARD_EXT_LNA_5G) ? 1 : 0;1466}1467}1468RTW_INFO("PAType is 0x%x, LNAType is 0x%x\n", *pPAType, *pLNAType);1469RTW_INFO("pHalData->ExternalPA_2G = %d, pHalData->external_pa_5g = %d\n", pHalData->ExternalPA_2G, pHalData->external_pa_5g);1470RTW_INFO("pHalData->ExternalLNA_2G = %d, pHalData->external_lna_5g = %d\n", pHalData->ExternalLNA_2G, pHalData->external_lna_5g);1471}14721473void hal_ReadAmplifierType_8814A(1474PADAPTER Adapter1475)1476{1477HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);1478switch (pHalData->rfe_type) {1479case 1: /* 8814AU */1480pHalData->external_pa_5g = pHalData->external_lna_5g = _TRUE;1481pHalData->TypeAPA = pHalData->TypeALNA = 0;/* APA and ALNA is 0 */1482break;1483case 2: /* socket board 8814AR and 8194AR */1484pHalData->ExternalPA_2G = pHalData->external_pa_5g = _TRUE;1485pHalData->ExternalLNA_2G = pHalData->external_lna_5g = _TRUE;1486pHalData->TypeAPA = pHalData->TypeALNA = 0x55;/* APA and ALNA is 1 */1487pHalData->TypeGPA = pHalData->TypeGLNA = 0x55;/* GPA and GLNA is 1 */1488break;1489case 3: /* high power on-board 8814AR and 8194AR */1490pHalData->ExternalPA_2G = pHalData->external_pa_5g = _TRUE;1491pHalData->ExternalLNA_2G = pHalData->external_lna_5g = _TRUE;1492pHalData->TypeAPA = pHalData->TypeALNA = 0xaa;/* APA and ALNA is 2 */1493pHalData->TypeGPA = pHalData->TypeGLNA = 0xaa;/* GPA and GLNA is 2 */1494break;1495case 4: /* on-board 8814AR and 8194AR */1496pHalData->ExternalPA_2G = pHalData->external_pa_5g = _TRUE;1497pHalData->ExternalLNA_2G = pHalData->external_lna_5g = _TRUE;1498pHalData->TypeAPA = 0x55;/* APA is 1 */1499pHalData->TypeALNA = 0xff; /* ALNA is 3 */1500pHalData->TypeGPA = pHalData->TypeGLNA = 0x55;/* GPA and GLNA is 1 */1501break;1502case 5:1503pHalData->ExternalPA_2G = pHalData->external_pa_5g = _TRUE;1504pHalData->ExternalLNA_2G = pHalData->external_lna_5g = _TRUE;1505pHalData->TypeAPA = 0xaa; /* APA2 */1506pHalData->TypeALNA = 0x5500; /* ALNA4 */1507pHalData->TypeGPA = pHalData->TypeGLNA = 0xaa; /* GPA2,GLNA2 */1508break;1509case 6:1510pHalData->external_lna_5g = _TRUE;1511pHalData->TypeALNA = 0; /* ALNA0 */1512break;1513case 0:1514default: /* 8814AE */1515break;1516}15171518RTW_INFO("pHalData->ExternalPA_2G = %d, pHalData->external_pa_5g = %d\n", pHalData->ExternalPA_2G, pHalData->external_pa_5g);1519RTW_INFO("pHalData->ExternalLNA_2G = %d, pHalData->external_lna_5g = %d\n", pHalData->ExternalLNA_2G, pHalData->external_lna_5g);1520RTW_INFO("pHalData->TypeGPA = 0x%X, pHalData->TypeAPA = 0x%X\n", pHalData->TypeGPA, pHalData->TypeAPA);1521RTW_INFO("pHalData->TypeGLNA = 0x%X, pHalData->TypeALNA = 0x%X\n", pHalData->TypeGLNA, pHalData->TypeALNA);1522}152315241525void1526hal_ReadRFEType_8814A(1527PADAPTER Adapter,1528u8 *PROMContent,1529BOOLEAN AutoloadFail1530)1531{1532HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);15331534if (!AutoloadFail) {1535if ((GetRegRFEType(Adapter) != 64) || 0xFF == PROMContent[EEPROM_RFE_OPTION_8814] || PROMContent[EEPROM_RFE_OPTION_8814] & BIT7) {1536if (GetRegRFEType(Adapter) != 64)1537pHalData->rfe_type = GetRegRFEType(Adapter);1538else if (IS_HARDWARE_TYPE_8814AE(Adapter))1539pHalData->rfe_type = 0;1540else if (IS_HARDWARE_TYPE_8814AU(Adapter))1541pHalData->rfe_type = 1;1542hal_ReadAmplifierType_8814A(Adapter);15431544} else {1545/* bit7==0 means RFE type defined by 0xCA[6:0] */1546pHalData->rfe_type = PROMContent[EEPROM_RFE_OPTION_8814] & 0x7F;1547hal_ReadAmplifierType_8814A(Adapter);1548}1549} else {1550if (GetRegRFEType(Adapter) != 64)1551pHalData->rfe_type = GetRegRFEType(Adapter);1552else if (IS_HARDWARE_TYPE_8814AE(Adapter))1553pHalData->rfe_type = 0;1554else if (IS_HARDWARE_TYPE_8814AU(Adapter))1555pHalData->rfe_type = 1;15561557hal_ReadAmplifierType_8814A(Adapter);1558}1559RTW_INFO("RFE Type: 0x%2x\n", pHalData->rfe_type);1560}15611562void1563hal_ReadPowerTrackingType_8814A(1564PADAPTER Adapter,1565u8 *PROMContent,1566BOOLEAN AutoloadFail1567)1568{1569HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);15701571/*Efuse 0xC8[7:6] TX Power Tracking Mode*/1572u8 PowerTrackingType = ((PROMContent[EEPROM_TX_PWR_CALIBRATE_RATE_8812] & 0xC0) >> 6);15731574if (!AutoloadFail) {1575if (GetRegPowerTrackingType(Adapter) != 64)1576pHalData->rf_power_tracking_type = GetRegPowerTrackingType(Adapter);1577} else1578pHalData->rf_power_tracking_type = 0;15791580if (PowerTrackingType == 0 || PowerTrackingType == 1 || PowerTrackingType == 2 || PowerTrackingType == 3)1581pHalData->rf_power_tracking_type = PowerTrackingType;1582else1583pHalData->rf_power_tracking_type = 0;15841585RTW_INFO("PowerTracking Type: 0x%2x\n", pHalData->rf_power_tracking_type);1586}158715881589static void1590hal_EfusePowerSwitch8814A(1591PADAPTER pAdapter,1592u8 bWrite,1593u8 PwrState)1594{1595u8 tempval;1596u16 tmpV16;1597u8 EFUSE_ACCESS_ON_8814A = 0x69;1598u8 EFUSE_ACCESS_OFF_8814A = 0x00;15991600if (PwrState == _TRUE) {1601rtw_write8(pAdapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON_8814A);16021603/* Reset: 0x0000h[28], default valid */1604tmpV16 = PlatformEFIORead2Byte(pAdapter, REG_SYS_FUNC_EN);1605if (!(tmpV16 & FEN_ELDR)) {1606tmpV16 |= FEN_ELDR ;1607rtw_write16(pAdapter, REG_SYS_FUNC_EN, tmpV16);1608}16091610/* Clock: Gated(0x0008h[5]) 8M(0x0008h[1]) clock from ANA, default valid */1611tmpV16 = PlatformEFIORead2Byte(pAdapter, REG_SYS_CLKR);1612if ((!(tmpV16 & LOADER_CLK_EN)) || (!(tmpV16 & ANA8M))) {1613tmpV16 |= (LOADER_CLK_EN | ANA8M) ;1614rtw_write16(pAdapter, REG_SYS_CLKR, tmpV16);1615}16161617if (bWrite == _TRUE) {1618/* Enable LDO 2.5V before read/write action */1619tempval = rtw_read8(pAdapter, EFUSE_TEST + 3);1620tempval &= 0x0F;1621tempval |= (VOLTAGE_V25 << 4);1622rtw_write8(pAdapter, EFUSE_TEST + 3, (tempval | 0x80));1623}1624} else {1625rtw_write8(pAdapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF_8814A);16261627if (bWrite == _TRUE) {1628/* Disable LDO 2.5V after read/write action */1629tempval = rtw_read8(pAdapter, EFUSE_TEST + 3);1630rtw_write8(pAdapter, EFUSE_TEST + 3, (tempval & 0x7F));1631}1632}1633}16341635static void1636rtl8814_EfusePowerSwitch(1637PADAPTER pAdapter,1638u8 bWrite,1639u8 PwrState)1640{1641hal_EfusePowerSwitch8814A(pAdapter, bWrite, PwrState);1642}16431644static void1645hal_EfuseReadEFuse8814A(1646PADAPTER Adapter,1647u16 _offset,1648u16 _size_byte,1649u8 *pbuf,1650BOOLEAN bPseudoTest1651)1652{1653u8 *efuseTbl = NULL;1654u16 eFuse_Addr = 0;1655u8 offset = 0, wden = 0;1656u16 i, j;1657u16 **eFuseWord = NULL;1658u16 efuse_utilized = 0;1659u8 efuse_usage = 0;1660u8 offset_2_0 = 0;1661u8 efuseHeader = 0, efuseExtHdr = 0, efuseData = 0;16621663/* */1664/* Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10. */1665/* */1666if ((_offset + _size_byte) > EFUSE_MAP_LEN_8814A) {1667/* total E-Fuse table is 512bytes */1668RTW_INFO("Hal_EfuseReadEFuse8814A(): Invalid offset(%#x) with read bytes(%#x)!!\n", _offset, _size_byte);1669goto exit;1670}16711672efuseTbl = (u8 *)rtw_zmalloc(EFUSE_MAP_LEN_8814A);1673if (efuseTbl == NULL) {1674RTW_INFO("%s: alloc efuseTbl fail!\n", __FUNCTION__);1675goto exit;1676}16771678eFuseWord = (u16 **)rtw_malloc2d(EFUSE_MAX_SECTION_8814A, EFUSE_MAX_WORD_UNIT_8814A, 2);1679if (eFuseWord == NULL) {1680RTW_INFO("%s: alloc eFuseWord fail!\n", __FUNCTION__);1681goto exit;1682}16831684/* 0. Refresh efuse init map as all oxFF. */1685for (i = 0; i < EFUSE_MAX_SECTION_8814A; i++)1686for (j = 0; j < EFUSE_MAX_WORD_UNIT_8814A; j++)1687eFuseWord[i][j] = 0xFFFF;16881689/* */1690/* 1. Read the first byte to check if efuse is empty!!! */1691/* */1692/* */1693efuse_OneByteRead(Adapter, eFuse_Addr++, &efuseHeader, bPseudoTest);16941695if (efuseHeader != 0xFF)1696efuse_utilized++;1697else {1698RTW_INFO("EFUSE is empty\n");1699efuse_utilized = 0;1700goto exit;1701}1702/* RT_DISP(FEEPROM, EFUSE_READ_ALL, ("Hal_EfuseReadEFuse8814A(): efuse_utilized: %d\n", efuse_utilized)); */17031704/* */1705/* 2. Read real efuse content. Filter PG header and every section data. */1706/* */1707while ((efuseHeader != 0xFF) && AVAILABLE_EFUSE_ADDR_8814A(eFuse_Addr)) {1708/* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("efuse_Addr-%d efuse_data=%x\n", eFuse_Addr-1, *rtemp8)); */17091710/* Check PG header for section num. */1711if (EXT_HEADER(efuseHeader)) { /* extended header */1712offset_2_0 = GET_HDR_OFFSET_2_0(efuseHeader);1713/* RT_DISP(FEEPROM, EFUSE_READ_ALL, ("extended header offset_2_0=%X\n", offset_2_0)); */17141715efuse_OneByteRead(Adapter, eFuse_Addr++, &efuseExtHdr, bPseudoTest);17161717/* RT_DISP(FEEPROM, EFUSE_READ_ALL, ("efuse[%X]=%X\n", eFuse_Addr-1, efuseExtHdr)); */17181719if (efuseExtHdr != 0xff) {1720efuse_utilized++;1721if (ALL_WORDS_DISABLED(efuseExtHdr)) {1722efuse_OneByteRead(Adapter, eFuse_Addr++, &efuseHeader, bPseudoTest);1723if (efuseHeader != 0xff)1724efuse_utilized++;1725break;1726} else {1727offset = ((efuseExtHdr & 0xF0) >> 1) | offset_2_0;1728wden = (efuseExtHdr & 0x0F);1729}1730} else {1731RTW_INFO("Error condition, extended = 0xff\n");1732/* We should handle this condition. */1733break;1734}1735} else {1736offset = ((efuseHeader >> 4) & 0x0f);1737wden = (efuseHeader & 0x0f);1738}17391740if (offset < EFUSE_MAX_SECTION_8814A) {1741/* Get word enable value from PG header */1742/* RT_DISP(FEEPROM, EFUSE_READ_ALL, ("Offset-%X Worden=%X\n", offset, wden)); */17431744for (i = 0; i < EFUSE_MAX_WORD_UNIT_8814A; i++) {1745/* Check word enable condition in the section */1746if (!(wden & (0x01 << i))) {1747efuse_OneByteRead(Adapter, eFuse_Addr++, &efuseData, bPseudoTest);1748/* RT_DISP(FEEPROM, EFUSE_READ_ALL, ("efuse[%X]=%X\n", eFuse_Addr-1, efuseData)); */1749efuse_utilized++;1750eFuseWord[offset][i] = (efuseData & 0xff);17511752if (!AVAILABLE_EFUSE_ADDR_8814A(eFuse_Addr))1753break;17541755efuse_OneByteRead(Adapter, eFuse_Addr++, &efuseData, bPseudoTest);1756/* RT_DISP(FEEPROM, EFUSE_READ_ALL, ("efuse[%X]=%X\n", eFuse_Addr-1, efuseData)); */1757efuse_utilized++;1758eFuseWord[offset][i] |= (((u16)efuseData << 8) & 0xff00);17591760if (!AVAILABLE_EFUSE_ADDR_8814A(eFuse_Addr))1761break;1762}1763}1764} else { /* deal with error offset,skip error data */1765RTW_PRINT("invalid offset:0x%02x\n", offset);1766for (i = 0; i < EFUSE_MAX_WORD_UNIT_8814A; i++) {1767/* Check word enable condition in the section */1768if (!(wden & 0x01)) {1769eFuse_Addr++;1770efuse_utilized++;1771if (!AVAILABLE_EFUSE_ADDR_8814A(eFuse_Addr))1772break;1773eFuse_Addr++;1774efuse_utilized++;1775if (!AVAILABLE_EFUSE_ADDR_8814A(eFuse_Addr))1776break;1777}1778}1779}1780/* Read next PG header */1781efuse_OneByteRead(Adapter, eFuse_Addr, &efuseHeader, bPseudoTest);1782/* RTPRINT(FEEPROM, EFUSE_READ_ALL, ("Addr=%d rtemp 0x%x\n", eFuse_Addr, *rtemp8)); */17831784if (efuseHeader != 0xFF) {1785eFuse_Addr++;1786efuse_utilized++;1787}17881789}17901791/* */1792/* 3. Collect 16 sections and 4 word unit into Efuse map. */1793/* */1794for (i = 0; i < EFUSE_MAX_SECTION_8814A; i++) {1795for (j = 0; j < EFUSE_MAX_WORD_UNIT_8814A; j++) {1796efuseTbl[(i * 8) + (j * 2)] = (eFuseWord[i][j] & 0xff);1797efuseTbl[(i * 8) + ((j * 2) + 1)] = ((eFuseWord[i][j] >> 8) & 0xff);1798}1799}18001801/* RT_DISP(FEEPROM, EFUSE_READ_ALL, ("Hal_EfuseReadEFuse8814A(): efuse_utilized: %d\n", efuse_utilized)); */18021803/* */1804/* 4. Copy from Efuse map to output pointer memory!!! */1805/* */1806for (i = 0; i < _size_byte; i++)1807pbuf[i] = efuseTbl[_offset + i];18081809/* */1810/* 5. Calculate Efuse utilization. */1811/* */1812efuse_usage = (u8)((eFuse_Addr * 100) / EFUSE_REAL_CONTENT_LEN_8814A);1813rtw_hal_set_hwreg(Adapter, HW_VAR_EFUSE_BYTES, (u8 *)&eFuse_Addr);18141815exit:1816if (efuseTbl)1817rtw_mfree(efuseTbl, EFUSE_MAP_LEN_8814A);18181819if (eFuseWord)1820rtw_mfree2d((void *)eFuseWord, EFUSE_MAX_SECTION_8814A, EFUSE_MAX_WORD_UNIT_8814A, sizeof(u16));1821}18221823static void1824rtl8814_ReadEFuse(1825PADAPTER Adapter,1826u8 efuseType,1827u16 _offset,1828u16 _size_byte,1829u8 *pbuf,1830BOOLEAN bPseudoTest1831)1832{1833hal_EfuseReadEFuse8814A(Adapter, _offset, _size_byte, pbuf, bPseudoTest);1834}18351836/* Do not support BT */1837void1838hal_EFUSEGetEfuseDefinition8814A(1839PADAPTER pAdapter,1840u8 efuseType,1841u8 type,1842void *pOut1843)1844{1845switch (type) {1846case TYPE_EFUSE_MAX_SECTION: {1847u8 *pMax_section;1848pMax_section = (u8 *)pOut;1849*pMax_section = EFUSE_MAX_SECTION_8814A;1850}1851break;1852case TYPE_EFUSE_REAL_CONTENT_LEN: {1853u16 *pu2Tmp;1854pu2Tmp = (u16 *)pOut;1855*pu2Tmp = EFUSE_REAL_CONTENT_LEN_8814A;1856}1857break;1858case TYPE_EFUSE_CONTENT_LEN_BANK: {1859u16 *pu2Tmp;1860pu2Tmp = (u16 *)pOut;1861*pu2Tmp = EFUSE_REAL_CONTENT_LEN_8814A;1862}1863break;1864case TYPE_AVAILABLE_EFUSE_BYTES_BANK: {1865u16 *pu2Tmp;1866pu2Tmp = (u16 *)pOut;1867*pu2Tmp = (u16)(EFUSE_REAL_CONTENT_LEN_8814A - EFUSE_OOB_PROTECT_BYTES);1868}1869break;1870case TYPE_AVAILABLE_EFUSE_BYTES_TOTAL: {1871u16 *pu2Tmp;1872pu2Tmp = (u16 *)pOut;1873*pu2Tmp = (u16)(EFUSE_REAL_CONTENT_LEN_8814A - EFUSE_OOB_PROTECT_BYTES);1874}1875break;1876case TYPE_EFUSE_MAP_LEN: {1877u16 *pu2Tmp;1878pu2Tmp = (u16 *)pOut;1879*pu2Tmp = (u16)EFUSE_MAP_LEN_8814A;1880}1881break;1882case TYPE_EFUSE_PROTECT_BYTES_BANK: {1883u8 *pu1Tmp;1884pu1Tmp = (u8 *)pOut;1885*pu1Tmp = (u8)(EFUSE_OOB_PROTECT_BYTES);1886}1887break;1888default: {1889u8 *pu1Tmp;1890pu1Tmp = (u8 *)pOut;1891*pu1Tmp = 0;1892}1893break;1894}1895}18961897static void1898rtl8814_EFUSE_GetEfuseDefinition(1899PADAPTER pAdapter,1900u8 efuseType,1901u8 type,1902void *pOut,1903BOOLEAN bPseudoTest1904)1905{1906hal_EFUSEGetEfuseDefinition8814A(pAdapter, efuseType, type, pOut);1907}19081909static u81910hal_EfuseWordEnableDataWrite8814A(PADAPTER pAdapter,1911u16 efuse_addr,1912u8 word_en,1913u8 *data,1914BOOLEAN bPseudoTest)1915{1916u16 readbackAddr = 0;1917u16 start_addr = efuse_addr;1918u8 badworden = 0x0F;1919u8 readbackData[PGPKT_DATA_SIZE];19201921_rtw_memset((void *)readbackData, 0xff, PGPKT_DATA_SIZE);19221923RTW_INFO("word_en = %x efuse_addr=%x\n", word_en, efuse_addr);19241925if (!(word_en & BIT0)) {1926readbackAddr = start_addr;1927efuse_OneByteWrite(pAdapter, start_addr++, data[0], bPseudoTest);1928efuse_OneByteWrite(pAdapter, start_addr++, data[1], bPseudoTest);19291930if (IS_HARDWARE_TYPE_8723B(pAdapter) || IS_HARDWARE_TYPE_8188E(pAdapter) ||1931IS_HARDWARE_TYPE_8192E(pAdapter) || IS_HARDWARE_TYPE_8703B(pAdapter) || IS_HARDWARE_TYPE_8188F(pAdapter) || IS_HARDWARE_TYPE_8814A(pAdapter))1932phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT26, 0); /* Use 10K Read, Suggested by Morris & Victor */19331934efuse_OneByteRead(pAdapter, readbackAddr, &readbackData[0], bPseudoTest);1935efuse_OneByteRead(pAdapter, readbackAddr + 1, &readbackData[1], bPseudoTest);19361937if (IS_HARDWARE_TYPE_8723B(pAdapter) || IS_HARDWARE_TYPE_8188E(pAdapter) ||1938IS_HARDWARE_TYPE_8192E(pAdapter) || IS_HARDWARE_TYPE_8703B(pAdapter) || IS_HARDWARE_TYPE_8188F(pAdapter) || IS_HARDWARE_TYPE_8814A(pAdapter))1939phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT26, 1); /* Restored to 1.5K Read, Suggested by Morris & Victor */19401941if ((data[0] != readbackData[0]) || (data[1] != readbackData[1]))1942badworden &= (~BIT0);1943}1944if (!(word_en & BIT1)) {1945readbackAddr = start_addr;1946efuse_OneByteWrite(pAdapter, start_addr++, data[2], bPseudoTest);1947efuse_OneByteWrite(pAdapter, start_addr++, data[3], bPseudoTest);19481949if (IS_HARDWARE_TYPE_8723B(pAdapter) || IS_HARDWARE_TYPE_8188E(pAdapter) ||1950IS_HARDWARE_TYPE_8192E(pAdapter) || IS_HARDWARE_TYPE_8703B(pAdapter) || IS_HARDWARE_TYPE_8188F(pAdapter) || IS_HARDWARE_TYPE_8814A(pAdapter))1951phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT26, 0); /* Use 10K Read, Suggested by Morris & Victor */19521953efuse_OneByteRead(pAdapter, readbackAddr , &readbackData[2], bPseudoTest);1954efuse_OneByteRead(pAdapter, readbackAddr + 1, &readbackData[3], bPseudoTest);19551956if (IS_HARDWARE_TYPE_8723B(pAdapter) || IS_HARDWARE_TYPE_8188E(pAdapter) ||1957IS_HARDWARE_TYPE_8192E(pAdapter) || IS_HARDWARE_TYPE_8703B(pAdapter) || IS_HARDWARE_TYPE_8188F(pAdapter) || IS_HARDWARE_TYPE_8814A(pAdapter))1958phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT26, 1); /* Restored to 1.5K Read, Suggested by Morris & Victor */19591960if ((data[2] != readbackData[2]) || (data[3] != readbackData[3]))1961badworden &= (~BIT1);1962}1963if (!(word_en & BIT2)) {1964readbackAddr = start_addr;1965efuse_OneByteWrite(pAdapter, start_addr++, data[4], bPseudoTest);1966efuse_OneByteWrite(pAdapter, start_addr++, data[5], bPseudoTest);19671968if (IS_HARDWARE_TYPE_8723B(pAdapter) || IS_HARDWARE_TYPE_8188E(pAdapter) ||1969IS_HARDWARE_TYPE_8192E(pAdapter) || IS_HARDWARE_TYPE_8703B(pAdapter) || IS_HARDWARE_TYPE_8188F(pAdapter) || IS_HARDWARE_TYPE_8814A(pAdapter))1970phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT26, 0); /* Use 10K Read, Suggested by Morris & Victor */19711972efuse_OneByteRead(pAdapter, readbackAddr, &readbackData[4], bPseudoTest);1973efuse_OneByteRead(pAdapter, readbackAddr + 1, &readbackData[5], bPseudoTest);19741975if (IS_HARDWARE_TYPE_8723B(pAdapter) || IS_HARDWARE_TYPE_8188E(pAdapter) ||1976IS_HARDWARE_TYPE_8192E(pAdapter) || IS_HARDWARE_TYPE_8703B(pAdapter) || IS_HARDWARE_TYPE_8188F(pAdapter) || IS_HARDWARE_TYPE_8814A(pAdapter))1977phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT26, 1); /* Restored to 1.5K Read, Suggested by Morris & Victor */19781979if ((data[4] != readbackData[4]) || (data[5] != readbackData[5]))1980badworden &= (~BIT2);1981}1982if (!(word_en & BIT3)) {1983readbackAddr = start_addr;1984efuse_OneByteWrite(pAdapter, start_addr++, data[6], bPseudoTest);1985efuse_OneByteWrite(pAdapter, start_addr++, data[7], bPseudoTest);19861987if (IS_HARDWARE_TYPE_8723B(pAdapter) || IS_HARDWARE_TYPE_8188E(pAdapter) ||1988IS_HARDWARE_TYPE_8192E(pAdapter) || IS_HARDWARE_TYPE_8703B(pAdapter) || IS_HARDWARE_TYPE_8188F(pAdapter) || IS_HARDWARE_TYPE_8814A(pAdapter))1989phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT26, 0); /* Use 10K Read, Suggested by Morris & Victor */19901991efuse_OneByteRead(pAdapter, readbackAddr, &readbackData[6], bPseudoTest);1992efuse_OneByteRead(pAdapter, readbackAddr + 1, &readbackData[7], bPseudoTest);19931994if (IS_HARDWARE_TYPE_8723B(pAdapter) || IS_HARDWARE_TYPE_8188E(pAdapter) ||1995IS_HARDWARE_TYPE_8192E(pAdapter) || IS_HARDWARE_TYPE_8703B(pAdapter) || IS_HARDWARE_TYPE_8188F(pAdapter) || IS_HARDWARE_TYPE_8814A(pAdapter))1996phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT26, 1); /* Restored to 1.5K Read, Suggested by Morris & Victor */19971998if ((data[6] != readbackData[6]) || (data[7] != readbackData[7]))1999badworden &= (~BIT3);2000}2001return badworden;2002}20032004static u82005rtl8814_Efuse_WordEnableDataWrite(PADAPTER pAdapter,2006u16 efuse_addr,2007u8 word_en,2008u8 *data,2009BOOLEAN bPseudoTest)2010{2011u8 ret = 0;20122013ret = hal_EfuseWordEnableDataWrite8814A(pAdapter, efuse_addr, word_en, data, bPseudoTest);20142015return ret;2016}201720182019static u16 hal_EfuseGetCurrentSize_8814A(PADAPTER pAdapter, BOOLEAN bPseudoTest)2020{2021int bContinual = _TRUE;20222023u16 efuse_addr = 0;2024u8 hoffset = 0, hworden = 0;2025u8 efuse_data, word_cnts = 0;20262027HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);2028PEFUSE_HAL pEfuseHal = &(pHalData->EfuseHal);20292030RTW_INFO("=======> %s()\n", __func__);20312032if (bPseudoTest)2033efuse_addr = (u16)(fakeEfuseUsedBytes);2034else2035rtw_hal_get_hwreg(pAdapter, HW_VAR_EFUSE_BYTES, (u8 *)&efuse_addr);2036/* RTPRINT(FEEPROM, EFUSE_PG, ("hal_EfuseGetCurrentSize_8723A(), start_efuse_addr = %d\n", efuse_addr)); */20372038while (bContinual &&2039efuse_OneByteRead(pAdapter, efuse_addr , &efuse_data, bPseudoTest) &&2040(efuse_addr < EFUSE_REAL_CONTENT_LEN_8814A)) {2041if (efuse_data != 0xFF) {2042if ((efuse_data & 0x1F) == 0x0F) { /* extended header */2043hoffset = efuse_data;2044efuse_addr++;2045efuse_OneByteRead(pAdapter, efuse_addr, &efuse_data, bPseudoTest);2046if ((efuse_data & 0x0F) == 0x0F) {2047efuse_addr++;2048continue;2049} else {2050hoffset = ((hoffset & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);2051hworden = efuse_data & 0x0F;2052}2053} else {2054hoffset = (efuse_data >> 4) & 0x0F;2055hworden = efuse_data & 0x0F;2056}2057RTW_INFO(FUNC_ADPT_FMT": Offset=%d Worden=%#X\n",2058FUNC_ADPT_ARG(pAdapter), hoffset, hworden);2059word_cnts = Efuse_CalculateWordCnts(hworden);2060/* read next header */2061efuse_addr = efuse_addr + (word_cnts * 2) + 1;2062} else2063bContinual = _FALSE ;2064}20652066if (bPseudoTest) {2067fakeEfuseUsedBytes = efuse_addr;2068pEfuseHal->fakeEfuseUsedBytes = efuse_addr;2069RTW_INFO("%s(), return %d\n", __func__, pEfuseHal->fakeEfuseUsedBytes);2070} else {2071pEfuseHal->EfuseUsedBytes = efuse_addr;2072pEfuseHal->EfuseUsedPercentage = (u8)((pEfuseHal->EfuseUsedBytes * 100) / pEfuseHal->PhysicalLen_WiFi);2073rtw_hal_set_hwreg(pAdapter, HW_VAR_EFUSE_BYTES, (u8 *)&efuse_addr);2074rtw_hal_set_hwreg(pAdapter, HW_VAR_EFUSE_USAGE, (u8 *)&(pEfuseHal->EfuseUsedPercentage));2075RTW_INFO("%s(), return %d\n", __func__, efuse_addr);2076}20772078return efuse_addr;20792080}20812082static u162083rtl8814_EfuseGetCurrentSize(2084PADAPTER pAdapter,2085u8 efuseType,2086BOOLEAN bPseudoTest)2087{2088u16 ret = 0;20892090ret = hal_EfuseGetCurrentSize_8814A(pAdapter, bPseudoTest);20912092return ret;2093}209420952096static int2097hal_EfusePgPacketRead_8814A(2098PADAPTER pAdapter,2099u8 offset,2100u8 *data,2101BOOLEAN bPseudoTest)2102{2103HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);2104PEFUSE_HAL pEfuseHal = &(pHalData->EfuseHal);2105u8 ReadState = PG_STATE_HEADER;21062107int bContinual = _TRUE;2108int bDataEmpty = _TRUE ;21092110u8 efuse_data, word_cnts = 0;2111u16 efuse_addr = 0;2112u8 hoffset = 0, hworden = 0;2113u8 tmpidx = 0;2114u8 tmpdata[8];2115u8 tmp_header = 0;21162117if (data == NULL)2118return _FALSE;2119if (offset >= EFUSE_MAX_SECTION_JAGUAR)2120return _FALSE;21212122_rtw_memset((void *)data, 0xff, sizeof(u8) * PGPKT_DATA_SIZE);2123_rtw_memset((void *)tmpdata, 0xff, sizeof(u8) * PGPKT_DATA_SIZE);21242125/* */2126/* <Roger_TODO> Efuse has been pre-programmed dummy 5Bytes at the end of Efuse by CP. */2127/* Skip dummy parts to prevent unexpected data read from Efuse. */2128/* By pass right now. 2009.02.19. */2129/* */2130while (bContinual && (efuse_addr < pEfuseHal->PhysicalLen_WiFi)) {2131/* ------- Header Read ------------- */2132if (ReadState & PG_STATE_HEADER) {2133if (efuse_OneByteRead(pAdapter, efuse_addr , &efuse_data, bPseudoTest) && (efuse_data != 0xFF)) {2134if (ALL_WORDS_DISABLED(efuse_data)) {2135tmp_header = efuse_data;2136efuse_addr++;2137efuse_OneByteRead(pAdapter, efuse_addr , &efuse_data, bPseudoTest);2138if ((efuse_data & 0x0F) != 0x0F) {2139hoffset = ((tmp_header & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);2140hworden = efuse_data & 0x0F;2141} else {2142efuse_addr++;2143break;2144}21452146} else {2147hoffset = (efuse_data >> 4) & 0x0F;2148hworden = efuse_data & 0x0F;2149}2150word_cnts = Efuse_CalculateWordCnts(hworden);2151bDataEmpty = _TRUE ;21522153if (hoffset == offset) {2154for (tmpidx = 0; tmpidx < word_cnts * 2 ; tmpidx++) {2155if (efuse_OneByteRead(pAdapter, efuse_addr + 1 + tmpidx , &efuse_data, bPseudoTest)) {2156tmpdata[tmpidx] = efuse_data;2157if (efuse_data != 0xff)2158bDataEmpty = _FALSE;2159}2160}2161if (bDataEmpty == _FALSE)2162ReadState = PG_STATE_DATA;2163else { /* read next header */2164efuse_addr = efuse_addr + (word_cnts * 2) + 1;2165ReadState = PG_STATE_HEADER;2166}2167} else { /* read next header */2168efuse_addr = efuse_addr + (word_cnts * 2) + 1;2169ReadState = PG_STATE_HEADER;2170}21712172} else2173bContinual = _FALSE ;2174}2175/* ------- Data section Read ------------- */2176else if (ReadState & PG_STATE_DATA) {2177efuse_WordEnableDataRead(hworden, tmpdata, data);2178efuse_addr = efuse_addr + (word_cnts * 2) + 1;2179ReadState = PG_STATE_HEADER;2180}21812182}21832184if ((data[0] == 0xff) && (data[1] == 0xff) && (data[2] == 0xff) && (data[3] == 0xff) &&2185(data[4] == 0xff) && (data[5] == 0xff) && (data[6] == 0xff) && (data[7] == 0xff))2186return _FALSE;2187else2188return _TRUE;2189}21902191static int2192rtl8814_Efuse_PgPacketRead(PADAPTER pAdapter,2193u8 offset,2194u8 *data,2195BOOLEAN bPseudoTest)2196{2197int ret = 0;21982199ret = hal_EfusePgPacketRead_8814A(pAdapter, offset, data, bPseudoTest);22002201return ret;2202}22032204BOOLEAN2205efuse_PgPacketCheck(2206PADAPTER pAdapter,2207u8 efuseType,2208BOOLEAN bPseudoTest2209)2210{2211HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);22122213if (Efuse_GetCurrentSize(pAdapter, efuseType, bPseudoTest) >= (EFUSE_REAL_CONTENT_LEN_8814A - EFUSE_PROTECT_BYTES_BANK_8814A)) {2214RTW_INFO("%s()error: %x >= %x\n", __func__, Efuse_GetCurrentSize(pAdapter, efuseType, bPseudoTest), (EFUSE_REAL_CONTENT_LEN_8814A - EFUSE_PROTECT_BYTES_BANK_8814A));2215return _FALSE;2216}22172218return _TRUE;2219}22202221void2222efuse_PgPacketConstruct(2223u8 offset,2224u8 word_en,2225u8 *pData,2226PPGPKT_STRUCT pTargetPkt2227)2228{2229_rtw_memset((void *)pTargetPkt->data, 0xFF, sizeof(u8) * 8);2230pTargetPkt->offset = offset;2231pTargetPkt->word_en = word_en;2232efuse_WordEnableDataRead(word_en, pData, pTargetPkt->data);2233pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en);22342235RTW_INFO("efuse_PgPacketConstruct(), targetPkt, offset=%d, word_en=0x%x, word_cnts=%d\n", pTargetPkt->offset, pTargetPkt->word_en, pTargetPkt->word_cnts);2236}223722382239u162240efuse_PgPacketExceptionHandle(2241PADAPTER pAdapter,2242u16 ErrOffset2243)2244{2245RTW_INFO("===> efuse_PgPacketExceptionHandle(), ErrOffset = 0x%X\n", ErrOffset);22462247/* ErrOffset is the offset of bad (extension) header. */2248/* if (IS_HARDWARE_TYPE_8812AU(pAdapter)) */2249/* ErrOffset = Hal_EfusePgPacketExceptionHandle_8812A(pAdapter, ErrOffset); */22502251RTW_INFO("<=== efuse_PgPacketExceptionHandle(), recovered! Jump to Offset = 0x%X\n", ErrOffset);22522253return ErrOffset;2254}225522562257BOOLEAN2258hal_EfuseCheckIfDatafollowed(2259PADAPTER pAdapter,2260u8 word_cnts,2261u16 startAddr,2262BOOLEAN bPseudoTest2263)2264{2265BOOLEAN bRet = FALSE;2266u8 i, efuse_data;22672268for (i = 0; i < (word_cnts * 2) ; i++) {2269if (efuse_OneByteRead(pAdapter, (startAddr + i) , &efuse_data, bPseudoTest) && (efuse_data != 0xFF))2270bRet = TRUE;2271}22722273return bRet;2274}22752276BOOLEAN2277hal_EfuseWordEnMatched(2278PPGPKT_STRUCT pTargetPkt,2279PPGPKT_STRUCT pCurPkt,2280u8 *pWden2281)2282{2283u8 match_word_en = 0x0F; /* default all words are disabled */22842285/* check if the same words are enabled both target and current PG packet */2286if (((pTargetPkt->word_en & BIT0) == 0) &&2287((pCurPkt->word_en & BIT0) == 0)) {2288match_word_en &= ~BIT0; /* enable word 0 */2289}2290if (((pTargetPkt->word_en & BIT1) == 0) &&2291((pCurPkt->word_en & BIT1) == 0)) {2292match_word_en &= ~BIT1; /* enable word 1 */2293}2294if (((pTargetPkt->word_en & BIT2) == 0) &&2295((pCurPkt->word_en & BIT2) == 0)) {2296match_word_en &= ~BIT2; /* enable word 2 */2297}2298if (((pTargetPkt->word_en & BIT3) == 0) &&2299((pCurPkt->word_en & BIT3) == 0)) {2300match_word_en &= ~BIT3; /* enable word 3 */2301}23022303*pWden = match_word_en;23042305if (match_word_en != 0xf)2306return TRUE;2307else2308return FALSE;2309}231023112312BOOLEAN2313efuse_PgPacketPartialWrite(2314PADAPTER pAdapter,2315u8 efuseType,2316u16 *pAddr,2317PPGPKT_STRUCT pTargetPkt,2318BOOLEAN bPseudoTest2319)2320{2321HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);2322PEFUSE_HAL pEfuseHal = &(pHalData->EfuseHal);2323BOOLEAN bRet = _FALSE;2324u8 i, efuse_data = 0, cur_header = 0;2325u8 matched_wden = 0, badworden = 0;2326u16 startAddr = 0;2327PGPKT_STRUCT curPkt;2328u16 max_sec_num = (efuseType == EFUSE_WIFI) ? pEfuseHal->MaxSecNum_WiFi : pEfuseHal->MaxSecNum_BT;2329u16 efuse_max = pEfuseHal->BankSize;2330u16 efuse_max_available_len =2331(efuseType == EFUSE_WIFI) ? pEfuseHal->TotalAvailBytes_WiFi : pEfuseHal->TotalAvailBytes_BT;23322333if (bPseudoTest) {2334pEfuseHal->fakeEfuseBank = (efuseType == EFUSE_WIFI) ? 0 : pEfuseHal->fakeEfuseBank;2335Efuse_GetCurrentSize(pAdapter, efuseType, _TRUE);2336}23372338/* EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &efuse_max_available_len, bPseudoTest); */2339/* EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_EFUSE_CONTENT_LEN_BANK, &efuse_max, bPseudoTest); */23402341if (efuseType == EFUSE_WIFI) {2342if (bPseudoTest) {2343#ifdef HAL_EFUSE_MEMORY2344startAddr = (u16)pEfuseHal->fakeEfuseUsedBytes;2345#else2346startAddr = (u16)fakeEfuseUsedBytes;2347#endif23482349} else2350rtw_hal_get_hwreg(pAdapter, HW_VAR_EFUSE_BYTES, (u8 *)&startAddr);2351} else {2352if (bPseudoTest) {2353#ifdef HAL_EFUSE_MEMORY2354startAddr = (u16)pEfuseHal->fakeBTEfuseUsedBytes;2355#else2356startAddr = (u16)fakeBTEfuseUsedBytes;2357#endif23582359} else2360rtw_hal_get_hwreg(pAdapter, HW_VAR_EFUSE_BT_BYTES, (u8 *)&startAddr);2361}23622363startAddr %= efuse_max;2364RTW_INFO("%s: startAddr=%#X\n", __FUNCTION__, startAddr);2365RTW_INFO("efuse_PgPacketPartialWrite(), startAddr = 0x%X\n", startAddr);23662367while (1) {2368if (startAddr >= efuse_max_available_len) {2369bRet = _FALSE;2370RTW_INFO("startAddr(%d) >= efuse_max_available_len(%d)\n",2371startAddr, efuse_max_available_len);2372break;2373}23742375if (efuse_OneByteRead(pAdapter, startAddr, &efuse_data, bPseudoTest) && (efuse_data != 0xFF)) {2376if (EXT_HEADER(efuse_data)) {2377cur_header = efuse_data;2378startAddr++;2379efuse_OneByteRead(pAdapter, startAddr, &efuse_data, bPseudoTest);2380if (ALL_WORDS_DISABLED(efuse_data)) {2381u16 recoveredAddr = startAddr;2382recoveredAddr = efuse_PgPacketExceptionHandle(pAdapter, startAddr - 1);23832384if (recoveredAddr == (startAddr - 1)) {2385RTW_INFO("Error! All words disabled and the recovery failed, (Addr, Data) = (0x%X, 0x%X)\n",2386startAddr, efuse_data);2387pAdapter->LastError = ERR_INVALID_DATA;2388break;2389} else {2390startAddr = recoveredAddr;2391RTW_INFO("Bad extension header but recovered => Keep going.\n");2392continue;2393}2394} else {2395curPkt.offset = ((cur_header & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);2396curPkt.word_en = efuse_data & 0x0F;2397}2398} else {2399if (ALL_WORDS_DISABLED(efuse_data)) {2400u16 recoveredAddr = startAddr;2401recoveredAddr = efuse_PgPacketExceptionHandle(pAdapter, startAddr);2402if (recoveredAddr != startAddr) {2403efuse_OneByteRead(pAdapter, startAddr, &efuse_data, bPseudoTest);2404RTW_INFO("Bad header but recovered => Read header again.\n");2405}2406}24072408cur_header = efuse_data;2409curPkt.offset = (cur_header >> 4) & 0x0F;2410curPkt.word_en = cur_header & 0x0F;2411}24122413if (curPkt.offset > max_sec_num) {2414pAdapter->LastError = ERR_OUT_OF_RANGE;2415pEfuseHal->Status = ERR_OUT_OF_RANGE;2416bRet = _FALSE;2417break;2418}24192420curPkt.word_cnts = Efuse_CalculateWordCnts(curPkt.word_en);2421/* if same header is found but no data followed */2422/* write some part of data followed by the header. */2423if ((curPkt.offset == pTargetPkt->offset) &&2424(!hal_EfuseCheckIfDatafollowed(pAdapter, curPkt.word_cnts, startAddr + 1, bPseudoTest)) &&2425hal_EfuseWordEnMatched(pTargetPkt, &curPkt, &matched_wden)) {2426RTW_INFO("Need to partial write data by the previous wrote header\n");2427/* RT_ASSERT(_FALSE, ("Error, Need to partial write data by the previous wrote header!!\n")); */2428/* Here to write partial data */2429badworden = Efuse_WordEnableDataWrite(pAdapter, startAddr + 1, matched_wden, pTargetPkt->data, bPseudoTest);2430if (badworden != 0x0F) {2431u32 PgWriteSuccess = 0;2432/* if write fail on some words, write these bad words again */24332434PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest);24352436if (!PgWriteSuccess) {2437bRet = _FALSE; /* write fail, return */2438break;2439}2440}2441/* partial write ok, update the target packet for later use */2442for (i = 0; i < 4; i++) {2443if ((matched_wden & (0x1 << i)) == 0) { /* this word has been written */2444pTargetPkt->word_en |= (0x1 << i); /* disable the word */2445}2446}2447pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en);2448}2449/* read from next header */2450startAddr = startAddr + (curPkt.word_cnts * 2) + 1;2451} else {2452/* not used header, 0xff */2453*pAddr = startAddr;2454RTW_INFO("Started from unused header offset=%d\n", startAddr);2455bRet = _TRUE;2456break;2457}2458}2459return bRet;2460}246124622463BOOLEAN2464hal_EfuseFixHeaderProcess(2465PADAPTER pAdapter,2466u8 efuseType,2467PPGPKT_STRUCT pFixPkt,2468u16 *pAddr,2469BOOLEAN bPseudoTest2470)2471{2472u8 originaldata[8], badworden = 0;2473u16 efuse_addr = *pAddr;2474u32 PgWriteSuccess = 0;24752476_rtw_memset((void *)originaldata, 0xff, 8);24772478if (Efuse_PgPacketRead(pAdapter, pFixPkt->offset, originaldata, bPseudoTest)) {2479/* check if data exist */2480badworden = Efuse_WordEnableDataWrite(pAdapter, efuse_addr + 1, pFixPkt->word_en, originaldata, bPseudoTest);24812482if (badworden != 0xf) { /* write fail */2483PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pFixPkt->offset, badworden, originaldata, bPseudoTest);2484if (!PgWriteSuccess)2485return _FALSE;2486else2487efuse_addr = Efuse_GetCurrentSize(pAdapter, efuseType, bPseudoTest);2488} else2489efuse_addr = efuse_addr + (pFixPkt->word_cnts * 2) + 1;2490} else2491efuse_addr = efuse_addr + (pFixPkt->word_cnts * 2) + 1;2492*pAddr = efuse_addr;2493return _TRUE;2494}249524962497BOOLEAN2498efuse_PgPacketWrite2ByteHeader(2499PADAPTER pAdapter,2500u8 efuseType,2501u16 *pAddr,2502PPGPKT_STRUCT pTargetPkt,2503BOOLEAN bPseudoTest)2504{2505HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);2506PEFUSE_HAL pEfuseHal = &(pHalData->EfuseHal);2507BOOLEAN bRet = _FALSE;2508u16 efuse_addr = *pAddr;2509u8 pg_header = 0, tmp_header = 0, pg_header_temp = 0;2510u8 repeatcnt = 0;2511u16 efuse_max_available_len =2512(efuseType == EFUSE_WIFI) ? pEfuseHal->TotalAvailBytes_WiFi : pEfuseHal->TotalAvailBytes_BT;25132514RTW_INFO("Wirte 2byte header\n");251525162517while (efuse_addr < efuse_max_available_len) {2518pg_header = ((pTargetPkt->offset & 0x07) << 5) | 0x0F;2519RTW_INFO("pg_header = 0x%x\n", pg_header);2520efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);25212522if (IS_HARDWARE_TYPE_8723B(pAdapter) || IS_HARDWARE_TYPE_8188E(pAdapter) ||2523IS_HARDWARE_TYPE_8192E(pAdapter) || IS_HARDWARE_TYPE_8703B(pAdapter) || IS_HARDWARE_TYPE_8188F(pAdapter) || IS_HARDWARE_TYPE_8814A(pAdapter))2524phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT26, 0); /* Use 10K Read, Suggested by Morris & Victor*/25252526efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);25272528if (IS_HARDWARE_TYPE_8723B(pAdapter) || IS_HARDWARE_TYPE_8188E(pAdapter) ||2529IS_HARDWARE_TYPE_8192E(pAdapter) || IS_HARDWARE_TYPE_8703B(pAdapter) || IS_HARDWARE_TYPE_8188F(pAdapter) || IS_HARDWARE_TYPE_8814A(pAdapter))2530phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT26, 1); /* Use 10K Read, Suggested by Morris & Victor*/25312532while (tmp_header == 0xFF || pg_header != tmp_header) {2533if (repeatcnt++ > pEfuseHal->DataRetry) {2534RTW_INFO("Repeat over limit for pg_header!!\n");2535return _FALSE;2536}25372538efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);2539efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);2540}25412542/* to write ext_header */2543if (tmp_header == pg_header) {2544efuse_addr++;2545pg_header_temp = pg_header;2546pg_header = ((pTargetPkt->offset & 0x78) << 1) | pTargetPkt->word_en;25472548efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);25492550if (IS_HARDWARE_TYPE_8723B(pAdapter) || IS_HARDWARE_TYPE_8188E(pAdapter) ||2551IS_HARDWARE_TYPE_8192E(pAdapter) || IS_HARDWARE_TYPE_8703B(pAdapter) || IS_HARDWARE_TYPE_8188F(pAdapter) || IS_HARDWARE_TYPE_8814A(pAdapter))2552phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT26, 0); /* Use 10K Read, Suggested by Morris & Victor*/25532554efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);25552556if (IS_HARDWARE_TYPE_8723B(pAdapter) || IS_HARDWARE_TYPE_8188E(pAdapter) ||2557IS_HARDWARE_TYPE_8192E(pAdapter) || IS_HARDWARE_TYPE_8703B(pAdapter) || IS_HARDWARE_TYPE_8188F(pAdapter) || IS_HARDWARE_TYPE_8814A(pAdapter))2558phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT26, 1); /* Use 10K Read, Suggested by Morris & Victor*/25592560while (tmp_header == 0xFF || pg_header != tmp_header) {2561if (repeatcnt++ > pEfuseHal->DataRetry) {2562RTW_INFO("Repeat over limit for ext_header!!\n");2563return _FALSE;2564}25652566efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);2567efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);2568}25692570if ((tmp_header & 0x0F) == 0x0F) { /* word_en PG fail */2571if (repeatcnt++ > pEfuseHal->DataRetry) {2572RTW_INFO("Repeat over limit for word_en!!\n");2573return _FALSE;2574} else {2575efuse_addr++;2576continue;2577}2578} else if (pg_header != tmp_header) { /* offset PG fail */2579PGPKT_STRUCT fixPkt;2580/* RT_ASSERT(_FALSE, ("Error, efuse_PgPacketWrite2ByteHeader(), offset PG fail, need to cover the existed data!!\n")); */2581RTW_INFO("Error condition for offset PG fail, need to cover the existed data\n");2582fixPkt.offset = ((pg_header_temp & 0xE0) >> 5) | ((tmp_header & 0xF0) >> 1);2583fixPkt.word_en = tmp_header & 0x0F;2584fixPkt.word_cnts = Efuse_CalculateWordCnts(fixPkt.word_en);2585if (!hal_EfuseFixHeaderProcess(pAdapter, efuseType, &fixPkt, &efuse_addr, bPseudoTest))2586return _FALSE;2587} else {2588bRet = _TRUE;2589break;2590}2591} else if ((tmp_header & 0x1F) == 0x0F) { /* wrong extended header */2592efuse_addr += 2;2593continue;2594}2595}25962597*pAddr = efuse_addr;2598return bRet;2599}260026012602BOOLEAN2603efuse_PgPacketWrite1ByteHeader(2604PADAPTER pAdapter,2605u8 efuseType,2606u16 *pAddr,2607PPGPKT_STRUCT pTargetPkt,2608BOOLEAN bPseudoTest)2609{2610HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);2611PEFUSE_HAL pEfuseHal = &(pHalData->EfuseHal);2612BOOLEAN bRet = _FALSE;2613u8 pg_header = 0, tmp_header = 0;2614u16 efuse_addr = *pAddr;2615u8 repeatcnt = 0;26162617RTW_INFO("Wirte 1byte header\n");2618pg_header = ((pTargetPkt->offset << 4) & 0xf0) | pTargetPkt->word_en;26192620if (IS_HARDWARE_TYPE_8723BE(pAdapter))2621efuse_OneByteWrite(pAdapter, 0x1FF, 00, _FALSE); /* increase current */262226232624efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);26252626if (IS_HARDWARE_TYPE_8723B(pAdapter) || IS_HARDWARE_TYPE_8188E(pAdapter) ||2627IS_HARDWARE_TYPE_8192E(pAdapter) || IS_HARDWARE_TYPE_8703B(pAdapter) || IS_HARDWARE_TYPE_8188F(pAdapter) || IS_HARDWARE_TYPE_8814A(pAdapter))2628phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT26, 0); /* Use 10K Read, Suggested by Morris & Victor */26292630efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);26312632if (IS_HARDWARE_TYPE_8723B(pAdapter) || IS_HARDWARE_TYPE_8188E(pAdapter) ||2633IS_HARDWARE_TYPE_8192E(pAdapter) || IS_HARDWARE_TYPE_8703B(pAdapter) || IS_HARDWARE_TYPE_8188F(pAdapter) || IS_HARDWARE_TYPE_8814A(pAdapter))2634phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT26, 1); /* Restored to 1.5K Read, Suggested by Morris & Victor */263526362637while (tmp_header == 0xFF || pg_header != tmp_header) {2638if (repeatcnt++ > pEfuseHal->HeaderRetry) {2639RTW_INFO("retry %d times fail!!\n", repeatcnt);2640return _FALSE;2641}2642efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);2643efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);2644RTW_INFO("===> efuse_PgPacketWrite1ByteHeader: Keep %d-th retrying, tmp_header = 0x%X\n", repeatcnt, tmp_header);2645}26462647if (pg_header == tmp_header)2648bRet = _TRUE;2649else {2650PGPKT_STRUCT fixPkt;2651/* RT_ASSERT(_FALSE, ("Error, efuse_PgPacketWrite1ByteHeader(), offset PG fail, need to cover the existed data!!\n")); */2652RTW_INFO(" pg_header(0x%X) != tmp_header(0x%X)\n", pg_header, tmp_header);2653RTW_INFO("Error condition for fixed PG packet, need to cover the existed data: (Addr, Data) = (0x%X, 0x%X)\n",2654efuse_addr, tmp_header);2655fixPkt.offset = (tmp_header >> 4) & 0x0F;2656fixPkt.word_en = tmp_header & 0x0F;2657fixPkt.word_cnts = Efuse_CalculateWordCnts(fixPkt.word_en);2658if (!hal_EfuseFixHeaderProcess(pAdapter, efuseType, &fixPkt, &efuse_addr, bPseudoTest))2659return _FALSE;2660}26612662*pAddr = efuse_addr;2663return bRet;2664}2665266626672668BOOLEAN2669efuse_PgPacketWriteHeader(2670PADAPTER pAdapter,2671u8 efuseType,2672u16 *pAddr,2673PPGPKT_STRUCT pTargetPkt,2674BOOLEAN bPseudoTest)2675{2676BOOLEAN bRet = _FALSE;26772678if (pTargetPkt->offset >= EFUSE_MAX_SECTION_BASE)2679bRet = efuse_PgPacketWrite2ByteHeader(pAdapter, efuseType, pAddr, pTargetPkt, bPseudoTest);2680else2681bRet = efuse_PgPacketWrite1ByteHeader(pAdapter, efuseType, pAddr, pTargetPkt, bPseudoTest);26822683return bRet;2684}26852686BOOLEAN2687efuse_PgPacketWriteData(2688PADAPTER pAdapter,2689u8 efuseType,2690u16 *pAddr,2691PPGPKT_STRUCT pTargetPkt,2692BOOLEAN bPseudoTest)2693{2694BOOLEAN bRet = _FALSE;2695u16 efuse_addr = *pAddr;2696u8 badworden = 0;2697u32 PgWriteSuccess = 0;26982699badworden = 0x0f;2700badworden = Efuse_WordEnableDataWrite(pAdapter, efuse_addr + 1, pTargetPkt->word_en, pTargetPkt->data, bPseudoTest);2701if (badworden == 0x0F) {2702RTW_INFO("efuse_PgPacketWriteData ok!!\n");2703return _TRUE;2704} else {2705/* Reorganize other pg packet */2706/* RT_ASSERT(_FALSE, ("Error, efuse_PgPacketWriteData(), wirte data fail!!\n")); */2707RTW_INFO("efuse_PgPacketWriteData Fail!!\n");27082709PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest);2710if (!PgWriteSuccess)2711return _FALSE;2712else2713return _TRUE;2714}27152716return bRet;2717}271827192720int2721hal_EfusePgPacketWrite_8814A(PADAPTER pAdapter,2722u8 offset,2723u8 word_en,2724u8 *pData,2725BOOLEAN bPseudoTest)2726{2727u8 efuseType = EFUSE_WIFI;2728PGPKT_STRUCT targetPkt;2729u16 startAddr = 0;27302731RTW_INFO("===> efuse_PgPacketWrite[%s], offset: 0x%X\n", (efuseType == EFUSE_WIFI) ? "WIFI" : "BT", offset);27322733/* 4 [1] Check if the remaining space is available to write. */2734if (!efuse_PgPacketCheck(pAdapter, efuseType, bPseudoTest)) {2735pAdapter->LastError = ERR_WRITE_PROTECT;2736RTW_INFO("efuse_PgPacketCheck(), fail!!\n");2737return _FALSE;2738}27392740/* 4 [2] Construct a packet to write: (Data, Offset, and WordEnable) */2741efuse_PgPacketConstruct(offset, word_en, pData, &targetPkt);274227432744/* 4 [3] Fix headers without data or fix bad headers, and then return the address where to get started. */2745if (!efuse_PgPacketPartialWrite(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest)) {2746pAdapter->LastError = ERR_INVALID_DATA;2747RTW_INFO("efuse_PgPacketPartialWrite(), fail!!\n");2748return _FALSE;2749}27502751/* 4 [4] Write the (extension) header. */2752if (!efuse_PgPacketWriteHeader(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest)) {2753pAdapter->LastError = ERR_IO_FAILURE;2754RTW_INFO("efuse_PgPacketWriteHeader(), fail!!\n");2755return _FALSE;2756}27572758/* 4 [5] Write the data. */2759if (!efuse_PgPacketWriteData(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest)) {2760pAdapter->LastError = ERR_IO_FAILURE;2761RTW_INFO("efuse_PgPacketWriteData(), fail!!\n");2762return _FALSE;2763}27642765RTW_INFO("<=== efuse_PgPacketWrite\n");2766return _TRUE;2767}27682769static int2770rtl8814_Efuse_PgPacketWrite(PADAPTER pAdapter,2771u8 offset,2772u8 word_en,2773u8 *data,2774BOOLEAN bPseudoTest)2775{2776int ret;27772778ret = hal_EfusePgPacketWrite_8814A(pAdapter, offset, word_en, data, bPseudoTest);27792780return ret;2781}27822783void InitRDGSetting8814A(PADAPTER padapter)2784{2785rtw_write8(padapter, REG_RD_CTRL, 0xFF);2786rtw_write16(padapter, REG_RD_NAV_NXT, 0x200);2787rtw_write8(padapter, REG_RD_RESP_PKT_TH, 0x05);2788}27892790void ReadRFType8814A(PADAPTER padapter)2791{2792PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);27932794#if DISABLE_BB_RF2795pHalData->rf_chip = RF_PSEUDO_11N;2796#else2797pHalData->rf_chip = RF_6052;2798#endif27992800/* if (pHalData->rf_type == RF_1T1R){ */2801/* pHalData->bRFPathRxEnable[0] = _TRUE; */2802/* } */2803/* else { */ /* Default unknow type is 2T2r */2804/* pHalData->bRFPathRxEnable[0] = pHalData->bRFPathRxEnable[1] = _TRUE; */2805/* } */28062807if (IsSupported24G(padapter->registrypriv.wireless_mode) &&2808is_supported_5g(padapter->registrypriv.wireless_mode))2809pHalData->BandSet = BAND_ON_BOTH;2810else if (is_supported_5g(padapter->registrypriv.wireless_mode))2811pHalData->BandSet = BAND_ON_5G;2812else2813pHalData->BandSet = BAND_ON_2_4G;28142815/* if(padapter->bInHctTest) */2816/* pHalData->BandSet = BAND_ON_2_4G; */2817}28182819void rtl8814_start_thread(PADAPTER padapter)2820{2821}28222823void rtl8814_stop_thread(PADAPTER padapter)2824{2825}28262827void hal_notch_filter_8814(_adapter *adapter, bool enable)2828{2829if (enable) {2830RTW_INFO("Enable notch filter\n");2831/* rtw_write8(adapter, rOFDM0_RxDSP+1, rtw_read8(adapter, rOFDM0_RxDSP+1) | BIT1); */2832} else {2833RTW_INFO("Disable notch filter\n");2834/* rtw_write8(adapter, rOFDM0_RxDSP+1, rtw_read8(adapter, rOFDM0_RxDSP+1) & ~BIT1); */2835}2836}28372838u82839GetEEPROMSize8814A(2840PADAPTER Adapter2841)2842{2843u8 size = 0;2844u32 curRCR;28452846curRCR = rtw_read16(Adapter, REG_SYS_EEPROM_CTRL);2847size = (curRCR & EEPROMSEL) ? 6 : 4; /* 6: EEPROM used is 93C46, 4: boot from E-Fuse. */28482849RTW_INFO("EEPROM type is %s\n", size == 4 ? "E-FUSE" : "93C46");2850/* return size; */2851return 4; /* <20120713, Kordan> The default value of HW is 6 ?!! */2852}28532854#if 02855void CheckAutoloadState8812A(PADAPTER padapter)2856{28572858u8 val8;2859PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);286028612862/* check system boot selection */2863val8 = rtw_read8(padapter, REG_9346CR);2864pHalData->EepromOrEfuse = (val8 & BOOT_FROM_EEPROM) ? _TRUE : _FALSE;2865pHalData->bautoload_fail_flag = (val8 & EEPROM_EN) ? _FALSE : _TRUE;28662867RTW_INFO("%s: 9346CR(%#x)=0x%02x, Boot from %s, Autoload %s!\n",2868__FUNCTION__, REG_9346CR, val8,2869(pHalData->EepromOrEfuse ? "EEPROM" : "EFUSE"),2870(pHalData->bautoload_fail_flag ? "Fail" : "OK"));2871}2872#endif28732874void2875hal_InitPGData_8814A(2876PADAPTER padapter,2877u8 *PROMContent2878)2879{2880HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);2881u32 i;2882u16 value16;28832884if (_FALSE == pHalData->bautoload_fail_flag) {2885/* autoload OK. */2886/* hal_ReadeFuse_8814A is FW offload read efuse, todo */2887/* #if (defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI)) && (MP_DRIVER != 1) */2888/* if(hal_ReadeFuse_8814A(pAdapter) == _FAIL) */2889/* #endif */28902891/* Read EFUSE real map to shadow. */2892EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, _FALSE);2893} else {2894/* autoload fail */2895RTW_INFO("AutoLoad Fail reported from CR9346!!\n");2896/* update to default value 0xFF */2897EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, _FALSE);2898}28992900#ifdef CONFIG_EFUSE_CONFIG_FILE2901if (check_phy_efuse_tx_power_info_valid(padapter) == _FALSE) {2902if (Hal_readPGDataFromConfigFile(padapter) != _SUCCESS)2903RTW_ERR("invalid phy efuse and read from file fail, will use driver default!!\n");2904}2905#endif2906}29072908static void read_chip_version_8814a(PADAPTER Adapter)2909{2910u32 value32;2911PHAL_DATA_TYPE pHalData;2912u8 vdr;29132914pHalData = GET_HAL_DATA(Adapter);29152916value32 = rtw_read32(Adapter, REG_SYS_CFG);2917RTW_INFO("%s SYS_CFG(0x%X)=0x%08x\n", __FUNCTION__, REG_SYS_CFG, value32);29182919pHalData->version_id.ICType = CHIP_8814A;29202921pHalData->version_id.ChipType = ((value32 & RTL_ID) ? TEST_CHIP : NORMAL_CHIP);29222923pHalData->version_id.RFType = RF_TYPE_3T3R;29242925vdr = (value32 & EXT_VENDOR_ID) >> EXT_VENDOR_ID_SHIFT;2926if (vdr == 0x00)2927pHalData->version_id.VendorType = CHIP_VENDOR_TSMC;2928else if (vdr == 0x01)2929pHalData->version_id.VendorType = CHIP_VENDOR_SMIC;2930else if (vdr == 0x02)2931pHalData->version_id.VendorType = CHIP_VENDOR_UMC;29322933pHalData->version_id.CUTVersion = (value32 & CHIP_VER_RTL_MASK) >> CHIP_VER_RTL_SHIFT; /* IC version (CUT) */29342935pHalData->MultiFunc = RT_MULTI_FUNC_NONE;29362937#if 12938dump_chip_info(pHalData->version_id);2939#endif29402941}29422943void2944hal_PatchwithJaguar_8814(2945PADAPTER Adapter,2946RT_MEDIA_STATUS MediaStatus2947)2948{2949HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);2950struct mlme_ext_priv *pmlmeext = &(Adapter->mlmeextpriv);2951struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);29522953if ((MediaStatus == RT_MEDIA_CONNECT) &&2954(pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK_JAGUAR_BCUTAP)) {2955rtw_write8(Adapter, rVhtlen_Use_Lsig_Jaguar, 0x1);2956rtw_write8(Adapter, REG_TCR + 3, BIT2);2957} else {2958rtw_write8(Adapter, rVhtlen_Use_Lsig_Jaguar, 0x3F);2959rtw_write8(Adapter, REG_TCR + 3, BIT0 | BIT1 | BIT2);2960}296129622963/*if( (MediaStatus == RT_MEDIA_CONNECT) &&2964((pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK_JAGUAR_BCUTAP) ||2965(pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_REALTEK_JAGUAR_CCUTAP)))2966{2967rtw_write8(Adapter, rBWIndication_Jaguar + 3,2968(rtw_read8(Adapter, rBWIndication_Jaguar + 3) | BIT2));2969}2970else2971{2972rtw_write8(Adapter, rBWIndication_Jaguar + 3,2973(rtw_read8(Adapter, rBWIndication_Jaguar + 3) & (~BIT2)));2974}*/2975}29762977void init_hal_spec_8814a(_adapter *adapter)2978{2979struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);29802981hal_spec->ic_name = "rtl8814a";2982hal_spec->macid_num = 128;2983hal_spec->sec_cam_ent_num = 64;2984hal_spec->sec_cap = SEC_CAP_CHK_BMC;29852986hal_spec->rfpath_num_2g = 4;2987hal_spec->rfpath_num_5g = 4;2988hal_spec->rf_reg_path_num = 4;2989hal_spec->max_tx_cnt = 3;29902991hal_spec->tx_nss_num = 3;2992hal_spec->rx_nss_num = 3;2993hal_spec->band_cap = BAND_CAP_2G | BAND_CAP_5G;2994hal_spec->bw_cap = BW_CAP_20M | BW_CAP_40M | BW_CAP_80M;2995hal_spec->port_num = 5;2996hal_spec->proto_cap = PROTO_CAP_11B | PROTO_CAP_11G | PROTO_CAP_11N | PROTO_CAP_11AC;29972998hal_spec->txgi_max = 63;2999hal_spec->txgi_pdbm = 2;30003001hal_spec->wl_func = 03002| WL_FUNC_P2P3003| WL_FUNC_MIRACAST3004| WL_FUNC_TDLS3005;30063007#if CONFIG_TX_AC_LIFETIME3008hal_spec->tx_aclt_unit_factor = 8;3009#endif30103011hal_spec->pg_txpwr_saddr = 0x10;3012hal_spec->pg_txgi_diff_factor = 1;30133014rtw_macid_ctl_init_sleep_reg(adapter_to_macidctl(adapter)3015, REG_MACID_SLEEP3016, REG_MACID_SLEEP_13017, REG_MACID_SLEEP_23018, REG_MACID_SLEEP_3);3019}30203021void InitDefaultValue8814A(PADAPTER padapter)3022{3023PHAL_DATA_TYPE pHalData;3024struct pwrctrl_priv *pwrctrlpriv;3025u8 i;30263027pHalData = GET_HAL_DATA(padapter);3028pwrctrlpriv = adapter_to_pwrctl(padapter);30293030/* init default value */3031pHalData->fw_ractrl = _FALSE;3032if (!pwrctrlpriv->bkeepfwalive)3033pHalData->LastHMEBoxNum = 0;30343035/* init dm default value */3036pHalData->bChnlBWInitialized = _FALSE;3037pHalData->bIQKInitialized = _FALSE;30383039pHalData->EfuseHal.fakeEfuseBank = 0;3040pHalData->EfuseHal.fakeEfuseUsedBytes = 0;3041_rtw_memset(pHalData->EfuseHal.fakeEfuseContent, 0xFF, EFUSE_MAX_HW_SIZE);3042_rtw_memset(pHalData->EfuseHal.fakeEfuseInitMap, 0xFF, EFUSE_MAX_MAP_LEN);3043_rtw_memset(pHalData->EfuseHal.fakeEfuseModifiedMap, 0xFF, EFUSE_MAX_MAP_LEN);3044}30453046void3047_InitBeaconParameters_8814A(3048PADAPTER Adapter3049)3050{3051HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);3052u16 val16;3053u8 val8;30543055val8 = DIS_TSF_UDT;3056val16 = val8 | (val8 << 8); /* port0 and port1 */3057#ifdef CONFIG_BT_COEXIST3058if (pHalData->EEPROMBluetoothCoexist == 1) {3059/* Enable prot0 beacon function for PSTDMA */3060val16 |= EN_BCN_FUNCTION;3061}3062#endif3063rtw_write16(Adapter, REG_BCN_CTRL, val16);30643065/* TBTT setup time */3066rtw_write8(Adapter, REG_TBTT_PROHIBIT, TBTT_PROHIBIT_SETUP_TIME);30673068/* TBTT hold time: 0x540[19:8] */3069rtw_write8(Adapter, REG_TBTT_PROHIBIT + 1, TBTT_PROHIBIT_HOLD_TIME_STOP_BCN & 0xFF);3070rtw_write8(Adapter, REG_TBTT_PROHIBIT + 2,3071(rtw_read8(Adapter, REG_TBTT_PROHIBIT + 2) & 0xF0) | (TBTT_PROHIBIT_HOLD_TIME_STOP_BCN >> 8));30723073rtw_write8(Adapter, REG_DRVERLYINT, DRIVER_EARLY_INT_TIME_8814);/* 5ms */3074rtw_write8(Adapter, REG_BCNDMATIM, BCN_DMA_ATIME_INT_TIME_8814); /* 2ms */30753076/* Suggested by designer timchen. Change beacon AIFS to the largest number */3077/* beacause test chip does not contension before sending beacon. by tynli. 2009.11.03 */3078rtw_write16(Adapter, REG_BCNTCFG, 0x4413);30793080}30813082static void3083_BeaconFunctionEnable(3084PADAPTER Adapter,3085BOOLEAN Enable,3086BOOLEAN Linked3087)3088{3089rtw_write8(Adapter, REG_BCN_CTRL, (DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_BCNQ_SUB));30903091rtw_write8(Adapter, REG_RD_CTRL + 1, 0x6F);3092}3093309430953096void SetBeaconRelatedRegisters8814A(PADAPTER padapter)3097{3098u32 value32;3099HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);3100struct mlme_ext_priv *pmlmeext = &(padapter->mlmeextpriv);3101struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);3102u32 bcn_ctrl_reg = REG_BCN_CTRL;3103/* reset TSF, enable update TSF, correcting TSF On Beacon */31043105/* REG_MBSSID_BCN_SPACE */3106/* REG_BCNDMATIM */3107/* REG_ATIMWND */3108/* REG_TBTT_PROHIBIT */3109/* REG_DRVERLYINT */3110/* REG_BCN_MAX_ERR */3111/* REG_BCNTCFG */ /* (0x510) */3112/* REG_DUAL_TSF_RST */3113/* REG_BCN_CTRL */ /* (0x550) */31143115#ifdef CONFIG_CONCURRENT_MODE3116if (padapter->hw_port == HW_PORT1)3117bcn_ctrl_reg = REG_BCN_CTRL_1;3118#endif31193120/* BCN interval */3121rtw_hal_set_hwreg(padapter, HW_VAR_BEACON_INTERVAL, (u8 *)&pmlmeinfo->bcn_interval);31223123rtw_write8(padapter, REG_ATIMWND, 0x02);/* 2ms */31243125_InitBeaconParameters_8814A(padapter);31263127rtw_write8(padapter, REG_SLOT, 0x09);31283129value32 = rtw_read32(padapter, REG_TCR);3130value32 &= ~TSFRST;3131rtw_write32(padapter, REG_TCR, value32);31323133value32 |= TSFRST;3134rtw_write32(padapter, REG_TCR, value32);31353136/* NOTE: Fix test chip's bug (about contention windows's randomness) */3137rtw_write8(padapter, REG_RXTSF_OFFSET_CCK, 0x50);3138rtw_write8(padapter, REG_RXTSF_OFFSET_OFDM, 0x50);31393140_BeaconFunctionEnable(padapter, _TRUE, _TRUE);31413142ResumeTxBeacon(padapter);31433144/* rtw_write8(padapter, 0x422, rtw_read8(padapter, 0x422)|BIT(6)); */31453146/* rtw_write8(padapter, 0x541, 0xff); */31473148/* rtw_write8(padapter, 0x542, rtw_read8(padapter, 0x541)|BIT(0)); */31493150rtw_write8(padapter, bcn_ctrl_reg, rtw_read8(padapter, bcn_ctrl_reg) | DIS_BCNQ_SUB);31513152}31533154static void hw_var_set_monitor(PADAPTER Adapter, u8 variable, u8 *val)3155{3156u32 rcr_bits;3157u16 value_rxfltmap2;3158HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);3159struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv);31603161if (*((u8 *)val) == _HW_STATE_MONITOR_) {31623163#ifdef CONFIG_CUSTOMER_ALIBABA_GENERAL3164rcr_bits = RCR_AAP | RCR_APM | RCR_AM | RCR_AB | RCR_APWRMGT | RCR_ADF | RCR_AMF | RCR_APP_PHYST_RXFF;3165#else3166/* Receive all type */3167rcr_bits = RCR_AAP | RCR_APM | RCR_AM | RCR_AB | RCR_APWRMGT | RCR_ADF | RCR_ACF | RCR_AMF | RCR_APP_PHYST_RXFF;31683169/* Append FCS */3170rcr_bits |= RCR_APPFCS;3171#endif3172#if 03173/*3174CRC and ICV packet will drop in recvbuf2recvframe()3175We no turn on it.3176*/3177rcr_bits |= (RCR_ACRC32 | RCR_AICV);3178#endif31793180rtw_hal_get_hwreg(Adapter, HW_VAR_RCR, (u8 *)&pHalData->rcr_backup);3181rtw_hal_set_hwreg(Adapter, HW_VAR_RCR, (u8 *)&rcr_bits);31823183/* Receive all data frames */3184value_rxfltmap2 = 0xFFFF;3185rtw_write16(Adapter, REG_RXFLTMAP2, value_rxfltmap2);31863187#if 03188/* tx pause */3189rtw_write8(padapter, REG_TXPAUSE, 0xFF);3190#endif3191} else {3192/* do nothing */3193}31943195}31963197static void hw_var_set_opmode(PADAPTER Adapter, u8 variable, u8 *val)3198{3199u8 val8;3200u8 mode = *((u8 *)val);3201static u8 isMonitor = _FALSE;32023203HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);32043205if (isMonitor == _TRUE) {3206/* reset RCR from backup */3207rtw_hal_set_hwreg(Adapter, HW_VAR_RCR, (u8 *)&pHalData->rcr_backup);3208rtw_hal_rcr_set_chk_bssid(Adapter, MLME_ACTION_NONE);3209isMonitor = _FALSE;3210}32113212if (mode == _HW_STATE_MONITOR_) {3213isMonitor = _TRUE;3214/* set net_type */3215Set_MSR(Adapter, _HW_STATE_NOLINK_);32163217hw_var_set_monitor(Adapter, variable, val);3218return;3219}32203221rtw_hal_set_hwreg(Adapter, HW_VAR_MAC_ADDR, adapter_mac_addr(Adapter)); /* set mac addr to mac register */32223223#ifdef CONFIG_CONCURRENT_MODE3224if (Adapter->hw_port == HW_PORT1) {3225/* disable Port1 TSF update */3226rtw_iface_disable_tsf_update(Adapter);32273228/* set net_type */3229Set_MSR(Adapter, mode);32303231RTW_INFO("%s()-%d mode = %d\n", __FUNCTION__, __LINE__, mode);32323233if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) {3234if (!rtw_mi_get_ap_num(Adapter) && !rtw_mi_get_mesh_num(Adapter)) {3235StopTxBeacon(Adapter);3236#ifdef CONFIG_PCI_HCI3237UpdateInterruptMask8814AE(Adapter, 0, 0, RT_BCN_INT_MASKS, 0);3238#else /* CONFIG_PCI_HCI */3239#ifdef CONFIG_INTERRUPT_BASED_TXBCN32403241#ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT3242rtw_write8(Adapter, REG_DRVERLYINT, 0x05);/* restore early int time to 5ms */3243UpdateInterruptMask8814AU(Adapter, _TRUE, 0, IMR_BCNDMAINT0_8812);3244#endif /* CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT */32453246#ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR3247UpdateInterruptMask8814AU(Adapter, _TRUE , 0, (IMR_TXBCN0ERR_8812 | IMR_TXBCN0OK_8812));3248#endif/* CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR */32493250#endif /* CONFIG_INTERRUPT_BASED_TXBCN */3251#endif /* CONFIG_PCI_HCI */3252}32533254rtw_write8(Adapter, REG_BCN_CTRL_1, DIS_TSF_UDT | DIS_ATIM); /* disable atim wnd and disable beacon function */3255/* rtw_write8(Adapter,REG_BCN_CTRL_1, DIS_TSF_UDT | EN_BCN_FUNCTION); */3256} else if (mode == _HW_STATE_ADHOC_) {3257#ifdef RTL8814AE_SW_BCN3258/*Beacon is polled to TXBUF*/3259rtw_write16(Adapter, REG_CR, rtw_read16(Adapter, REG_CR) | BIT(8));3260RTW_INFO("%s-%d: enable SW BCN, REG_CR=0x%x\n", __func__, __LINE__, rtw_read32(Adapter, REG_CR));3261#endif3262ResumeTxBeacon(Adapter);3263rtw_write8(Adapter, REG_BCN_CTRL_1, DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_BCNQ_SUB);3264} else if (mode == _HW_STATE_AP_) {3265#ifdef CONFIG_PCI_HCI3266UpdateInterruptMask8814AE(Adapter, RT_BCN_INT_MASKS, 0, 0, 0);3267#else3268#ifdef CONFIG_INTERRUPT_BASED_TXBCN3269#ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT3270UpdateInterruptMask8814AU(Adapter, _TRUE , IMR_BCNDMAINT0_8812, 0);3271#endif/* CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT */32723273#ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR3274UpdateInterruptMask8814AU(Adapter, _TRUE , (IMR_TXBCN0ERR_8812 | IMR_TXBCN0OK_8812), 0);3275#endif/* CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR */32763277#endif /* CONFIG_INTERRUPT_BASED_TXBCN */3278#endif32793280rtw_write8(Adapter, REG_BCN_CTRL_1, DIS_TSF_UDT | DIS_BCNQ_SUB);32813282#ifdef RTL8814AE_SW_BCN3283rtw_write16(Adapter, REG_CR, rtw_read16(Adapter, REG_CR) | BIT(8));3284RTW_INFO("%s-%d: enable SW BCN, REG_CR=0x%x\n", __func__, __LINE__, rtw_read32(Adapter, REG_CR));3285#endif32863287/* enable to rx data frame */3288rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);32893290/* Beacon Control related register for first time */3291rtw_write8(Adapter, REG_BCNDMATIM, 0x02); /* 2ms */32923293/* rtw_write8(Adapter, REG_BCN_MAX_ERR, 0xFF); */3294rtw_write8(Adapter, REG_ATIMWND_1, 0x0c); /* 12ms for port1 */32953296rtw_write16(Adapter, REG_TSFTR_SYN_OFFSET, 0x7fff);/* +32767 (~32ms) */32973298/* reset TSF2 */3299rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(1));33003301/* enable BCN1 Function for if2 */3302/* don't enable update TSF1 for if2 (due to TSF update when beacon/probe rsp are received) */3303rtw_write8(Adapter, REG_BCN_CTRL_1, (DIS_TSF_UDT | EN_BCN_FUNCTION | EN_TXBCN_RPT | DIS_BCNQ_SUB));33043305#ifdef CONFIG_CONCURRENT_MODE3306if (!rtw_mi_buddy_check_mlmeinfo_state(Adapter, WIFI_FW_ASSOC_SUCCESS))3307rtw_write8(Adapter, REG_BCN_CTRL,3308rtw_read8(Adapter, REG_BCN_CTRL) & ~EN_BCN_FUNCTION);3309#endif3310/* BCN1 TSF will sync to BCN0 TSF with offset(0x518) if if1_sta linked */3311/* rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1)|BIT(5)); */3312/* rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(3)); */33133314/* dis BCN0 ATIM WND if if1 is station */3315rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL) | DIS_ATIM);33163317#ifdef CONFIG_TSF_RESET_OFFLOAD3318/* Reset TSF for STA+AP concurrent mode */3319if (DEV_STA_LD_NUM(adapter_to_dvobj(Adapter))) {3320if (rtw_hal_reset_tsf(Adapter, HW_PORT1) == _FAIL)3321RTW_INFO("ERROR! %s()-%d: Reset port1 TSF fail\n",3322__FUNCTION__, __LINE__);3323}3324#endif /* CONFIG_TSF_RESET_OFFLOAD */3325}3326} else /* else for port0 */3327#endif /* CONFIG_CONCURRENT_MODE */3328{3329#ifdef CONFIG_MI_WITH_MBSSID_CAM /*For Port0 - MBSS CAM*/3330hw_var_set_opmode_mbid(Adapter, mode);3331#else3332/* disable Port0 TSF update */3333rtw_iface_disable_tsf_update(Adapter);33343335/* set net_type */3336Set_MSR(Adapter, mode);33373338RTW_INFO("%s()-%d mode = %d\n", __FUNCTION__, __LINE__, mode);33393340if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) {3341#ifdef CONFIG_CONCURRENT_MODE3342if (!rtw_mi_get_ap_num(Adapter) && !rtw_mi_get_mesh_num(Adapter))3343#endif /* CONFIG_CONCURRENT_MODE */3344{3345StopTxBeacon(Adapter);3346#ifdef CONFIG_PCI_HCI3347UpdateInterruptMask8814AE(Adapter, 0, 0, RT_BCN_INT_MASKS, 0);3348#else3349#ifdef CONFIG_INTERRUPT_BASED_TXBCN3350#ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT3351rtw_write8(Adapter, REG_DRVERLYINT, 0x05);/* restore early int time to 5ms */3352UpdateInterruptMask8814AU(Adapter, _TRUE, 0, IMR_BCNDMAINT0_8812);3353#endif/* CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT */33543355#ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR3356UpdateInterruptMask8814AU(Adapter, _TRUE , 0, (IMR_TXBCN0ERR_8812 | IMR_TXBCN0OK_8812));3357#endif /* CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR */33583359#endif /* CONFIG_INTERRUPT_BASED_TXBCN */3360#endif3361}33623363rtw_write8(Adapter, REG_BCN_CTRL, DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_ATIM); /* disable atim wnd */3364/* rtw_write8(Adapter,REG_BCN_CTRL, DIS_TSF_UDT | EN_BCN_FUNCTION); */3365} else if (mode == _HW_STATE_ADHOC_) {3366#ifdef RTL8814AE_SW_BCN3367rtw_write16(Adapter, REG_CR, rtw_read16(Adapter, REG_CR) | BIT(8));3368RTW_INFO("%s-%d: enable SW BCN, REG_CR=0x%x\n", __func__, __LINE__, rtw_read32(Adapter, REG_CR));3369#endif3370ResumeTxBeacon(Adapter);3371rtw_write8(Adapter, REG_BCN_CTRL, DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_BCNQ_SUB);3372} else if (mode == _HW_STATE_AP_) {3373#ifdef CONFIG_PCI_HCI3374UpdateInterruptMask8814AE(Adapter, RT_BCN_INT_MASKS, 0, 0, 0);3375#else3376#ifdef CONFIG_INTERRUPT_BASED_TXBCN3377#ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT3378UpdateInterruptMask8814AU(Adapter, _TRUE , IMR_BCNDMAINT0_8812, 0);3379#endif/* CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT */33803381#ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR3382UpdateInterruptMask8814AU(Adapter, _TRUE , (IMR_TXBCN0ERR_8812 | IMR_TXBCN0OK_8812), 0);3383#endif/* CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR */33843385#endif /* CONFIG_INTERRUPT_BASED_TXBCN */3386#endif33873388rtw_write8(Adapter, REG_BCN_CTRL, DIS_TSF_UDT | DIS_BCNQ_SUB);3389/*Beacon is polled to TXBUF*/3390#ifdef RTL8814AE_SW_BCN3391rtw_write16(Adapter, REG_CR, rtw_read16(Adapter, REG_CR) | BIT(8));3392RTW_INFO("%s-%d: enable SW BCN, REG_CR=0x%x\n", __func__, __LINE__, rtw_read32(Adapter, REG_CR));3393#endif33943395/* enable to rx data frame */3396rtw_write16(Adapter, REG_RXFLTMAP2, 0xFFFF);33973398/* Beacon Control related register for first time */3399rtw_write8(Adapter, REG_BCNDMATIM, 0x02); /* 2ms */34003401/* rtw_write8(Adapter, REG_BCN_MAX_ERR, 0xFF); */3402rtw_write8(Adapter, REG_ATIMWND, 0x0c); /* 12ms */34033404rtw_write16(Adapter, REG_TSFTR_SYN_OFFSET, 0x7fff);/* +32767 (~32ms) */34053406/* reset TSF */3407rtw_write8(Adapter, REG_DUAL_TSF_RST, BIT(0));34083409/* enable BCN0 Function for if1 */3410/* don't enable update TSF0 for if1 (due to TSF update when beacon/probe rsp are received) */3411rtw_write8(Adapter, REG_BCN_CTRL, (DIS_TSF_UDT | EN_BCN_FUNCTION | EN_TXBCN_RPT | DIS_BCNQ_SUB));34123413#ifdef CONFIG_CONCURRENT_MODE3414if (!rtw_mi_buddy_check_mlmeinfo_state(Adapter, WIFI_FW_ASSOC_SUCCESS))3415rtw_write8(Adapter, REG_BCN_CTRL_1,3416rtw_read8(Adapter, REG_BCN_CTRL_1) & ~EN_BCN_FUNCTION);3417#endif34183419/* dis BCN1 ATIM WND if if2 is station */3420rtw_write8(Adapter, REG_BCN_CTRL_1, rtw_read8(Adapter, REG_BCN_CTRL_1) | DIS_ATIM);3421#ifdef CONFIG_TSF_RESET_OFFLOAD3422/* Reset TSF for STA+AP concurrent mode */3423if (DEV_STA_LD_NUM(adapter_to_dvobj(Adapter))) {3424if (rtw_hal_reset_tsf(Adapter, HW_PORT0) == _FAIL)3425RTW_INFO("ERROR! %s()-%d: Reset port0 TSF fail\n",3426__FUNCTION__, __LINE__);3427}3428#endif /* CONFIG_TSF_RESET_OFFLOAD */3429}3430#endif /* #ifdef CONFIG_MI_WITH_MBSSID_CAM*/3431}3432}34333434static void rtw_store_all_sta_hwseq(_adapter *padapter)3435{3436_irqL irqL;3437_list *plist, *phead;3438u8 index;3439u16 hw_seq[NUM_STA];3440u32 shcut_addr = 0;3441struct sta_info *psta;3442struct sta_priv *pstapriv = &padapter->stapriv;3443struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);3444struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);34453446_rtw_memset(hw_seq, 0, NUM_STA);34473448/* save each HW sequence of mac id from report fifo */3449for (index = 0; index < macid_ctl->num && index < NUM_STA; index++) {3450if (rtw_macid_is_used(macid_ctl, index)) {3451rtw_write16(padapter, 0x140, 0x662 | ((index & BIT5) >> 5));3452shcut_addr = 0x8000;3453shcut_addr = (shcut_addr | ((index & 0x1f) << 7) | (10 << 2)) + 1;34543455/* 2 byte un-alignment handling */3456if (shcut_addr%2)3457hw_seq[index] = le16_to_cpu(rtw_read8(padapter, shcut_addr) + (rtw_read8(padapter, shcut_addr + 1) << 8));3458else3459hw_seq[index] = rtw_read16(padapter, shcut_addr);3460/* RTW_INFO("mac_id:%d is used, hw_seq[index]=%d\n", index, hw_seq[index]); */3461}3462}34633464_enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);3465for (index = 0; index < NUM_STA; index++) {3466psta = NULL;34673468phead = &(pstapriv->sta_hash[index]);3469plist = get_next(phead);34703471while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {3472psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);3473plist = get_next(plist);34743475psta->hwseq = hw_seq[psta->cmn.mac_id];3476/* RTW_INFO(" psta->mac_id=%d, psta->hwseq=%d\n" , psta->cmn.mac_id, psta->hwseq); */3477}34783479}3480_exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);348134823483}34843485static void rtw_restore_all_sta_hwseq(_adapter *padapter)3486{3487_irqL irqL;3488_list *plist, *phead;3489u8 index;3490u16 hw_seq[NUM_STA];3491u32 shcut_addr = 0;3492struct sta_info *psta;3493struct sta_priv *pstapriv = &padapter->stapriv;3494struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);3495struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);34963497_rtw_memset(hw_seq, 0, NUM_STA);34983499_enter_critical_bh(&pstapriv->sta_hash_lock, &irqL);3500for (index = 0; index < NUM_STA; index++) {3501psta = NULL;35023503phead = &(pstapriv->sta_hash[index]);3504plist = get_next(phead);35053506while ((rtw_end_of_queue_search(phead, plist)) == _FALSE) {3507psta = LIST_CONTAINOR(plist, struct sta_info, hash_list);3508plist = get_next(plist);35093510hw_seq[psta->cmn.mac_id] = psta->hwseq;3511/* RTW_INFO(" psta->mac_id=%d, psta->hwseq=%d\n", psta->mac_id, psta->hwseq); */3512}35133514}3515_exit_critical_bh(&pstapriv->sta_hash_lock, &irqL);35163517/* restore each HW sequence of mac id to report fifo */3518for (index = 0; index < macid_ctl->num && index < NUM_STA; index++) {3519if (rtw_macid_is_used(macid_ctl, index)) {3520rtw_write16(padapter, 0x140, 0x662 | ((index & BIT5) >> 5));3521shcut_addr = 0x8000;3522shcut_addr = (shcut_addr | ((index & 0x1f) << 7) | (10 << 2)) + 1;3523rtw_write16(padapter, shcut_addr, hw_seq[index]);3524/* RTW_INFO("mac_id:%d is used, hw_seq[index]=%d\n", index, hw_seq[index]); */3525}3526}352735283529}35303531u8 SetHwReg8814A(PADAPTER padapter, u8 variable, u8 *pval)3532{3533PHAL_DATA_TYPE pHalData;3534u8 ret = _SUCCESS;3535u8 val8;3536u16 val16;3537u32 val32;353835393540pHalData = GET_HAL_DATA(padapter);35413542switch (variable) {3543case HW_VAR_SET_OPMODE:3544hw_var_set_opmode(padapter, variable, pval);3545break;35463547case HW_VAR_BASIC_RATE:3548rtw_var_set_basic_rate(padapter, pval);3549break;35503551case HW_VAR_TXPAUSE:3552rtw_write8(padapter, REG_TXPAUSE, *pval);3553break;35543555case HW_VAR_SLOT_TIME:3556rtw_write8(padapter, REG_SLOT, *pval);3557break;35583559case HW_VAR_RESP_SIFS:3560/* SIFS_Timer = 0x0a0a0808; */3561/* RESP_SIFS for CCK */3562rtw_write8(padapter, REG_RESP_SIFS_CCK, pval[0]); /* SIFS_T2T_CCK (0x08) */3563rtw_write8(padapter, REG_RESP_SIFS_CCK + 1, pval[1]); /* SIFS_R2T_CCK(0x08) */3564/* RESP_SIFS for OFDM */3565rtw_write8(padapter, REG_RESP_SIFS_OFDM, pval[2]); /* SIFS_T2T_OFDM (0x0a) */3566rtw_write8(padapter, REG_RESP_SIFS_OFDM + 1, pval[3]); /* SIFS_R2T_OFDM(0x0a) */3567break;35683569case HW_VAR_ACK_PREAMBLE: {3570u8 bShortPreamble = *pval;35713572/* Joseph marked out for Netgear 3500 TKIP channel 7 issue.(Temporarily) */3573val8 = (pHalData->nCur40MhzPrimeSC) << 5;3574if (bShortPreamble)3575val8 |= 0x80;3576rtw_write8(padapter, REG_RRSR + 2, val8);3577}3578break;35793580case HW_VAR_CAM_INVALID_ALL:3581val32 = BIT(31) | BIT(30);3582rtw_write32(padapter, REG_CAMCMD, val32);3583break;35843585case HW_VAR_AC_PARAM_VO:3586rtw_write32(padapter, REG_EDCA_VO_PARAM, *(u32 *)pval);3587break;35883589case HW_VAR_AC_PARAM_VI:3590rtw_write32(padapter, REG_EDCA_VI_PARAM, *(u32 *)pval);3591break;35923593case HW_VAR_AC_PARAM_BE:3594pHalData->ac_param_be = *(u32 *)pval;3595rtw_write32(padapter, REG_EDCA_BE_PARAM, *(u32 *)pval);3596break;35973598case HW_VAR_AC_PARAM_BK:3599rtw_write32(padapter, REG_EDCA_BK_PARAM, *(u32 *)pval);3600break;36013602case HW_VAR_ACM_CTRL: {3603u8 acm_ctrl;3604u8 AcmCtrl;36053606acm_ctrl = *(u8 *)pval;3607AcmCtrl = rtw_read8(padapter, REG_ACMHWCTRL);36083609if (acm_ctrl > 1)3610AcmCtrl = AcmCtrl | 0x1;36113612if (acm_ctrl & BIT(1))3613AcmCtrl |= AcmHw_VoqEn;3614else3615AcmCtrl &= (~AcmHw_VoqEn);36163617if (acm_ctrl & BIT(2))3618AcmCtrl |= AcmHw_ViqEn;3619else3620AcmCtrl &= (~AcmHw_ViqEn);36213622if (acm_ctrl & BIT(3))3623AcmCtrl |= AcmHw_BeqEn;3624else3625AcmCtrl &= (~AcmHw_BeqEn);36263627RTW_INFO("[HW_VAR_ACM_CTRL] Write 0x%X\n", AcmCtrl);3628rtw_write8(padapter, REG_ACMHWCTRL, AcmCtrl);3629}3630break;3631#ifdef CONFIG_80211N_HT3632case HW_VAR_AMPDU_FACTOR: {3633u32 AMPDULen = *(u8 *)pval;363436353636if (AMPDULen < VHT_AGG_SIZE_256K)3637AMPDULen = (0x2000 << (*((u8 *)pval))) - 1;3638else3639AMPDULen = 0x3ffff;3640rtw_write32(padapter, REG_AMPDU_MAX_LENGTH_8814A, AMPDULen);3641/* RTW_INFO("SetHwReg8814AU(): HW_VAR_AMPDU_FACTOR %x\n" ,AMPDULen); */3642}3643break;3644#endif /* CONFIG_80211N_HT */3645case HW_VAR_H2C_FW_PWRMODE: {3646u8 psmode = *pval;3647rtl8814_set_FwPwrMode_cmd(padapter, psmode);3648}3649break;36503651case HW_VAR_H2C_FW_JOINBSSRPT:3652rtl8814_set_FwJoinBssReport_cmd(padapter, *pval);3653break;3654case HW_VAR_DL_RSVD_PAGE:3655#ifdef CONFIG_BT_COEXIST3656if (pHalData->EEPROMBluetoothCoexist == 1) {3657if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE)3658rtl8814a_download_BTCoex_AP_mode_rsvd_page(padapter);3659}3660#endif /* CONFIG_BT_COEXIST */3661break;36623663#ifdef CONFIG_P2P_PS3664case HW_VAR_H2C_FW_P2P_PS_OFFLOAD:3665rtl8814_set_p2p_ps_offload_cmd(padapter, *pval);3666break;3667#endif /* CONFIG_P2P_PS */36683669case HW_VAR_EFUSE_USAGE:3670pHalData->EfuseUsedPercentage = *pval;3671break;36723673case HW_VAR_EFUSE_BYTES:3674pHalData->EfuseUsedBytes = *(u16 *)pval;3675break;3676#if 03677case HW_VAR_EFUSE_BT_USAGE:3678#ifdef HAL_EFUSE_MEMORY3679pHalData->EfuseHal.BTEfuseUsedPercentage = *pval;3680#endif /* HAL_EFUSE_MEMORY */3681break;36823683case HW_VAR_EFUSE_BT_BYTES:3684#ifdef HAL_EFUSE_MEMORY3685pHalData->EfuseHal.BTEfuseUsedBytes = *(u16 *)pval;3686#else /* HAL_EFUSE_MEMORY */3687BTEfuseUsedBytes = *(u16 *)pval;3688#endif /* HAL_EFUSE_MEMORY */3689break;3690#endif /* 0 */3691case HW_VAR_FIFO_CLEARN_UP: {3692struct pwrctrl_priv *pwrpriv;3693u8 trycnt = 100;36943695pwrpriv = adapter_to_pwrctl(padapter);36963697/* pause tx */3698rtw_write8(padapter, REG_TXPAUSE, 0xff);36993700/* keep sn */3701rtw_store_all_sta_hwseq(padapter);37023703if (pwrpriv->bkeepfwalive != _TRUE) {3704/* RX DMA stop */3705val32 = rtw_read32(padapter, REG_RXPKT_NUM);3706val32 |= RW_RELEASE_EN;3707rtw_write32(padapter, REG_RXPKT_NUM, val32);3708do {3709val32 = rtw_read32(padapter, REG_RXPKT_NUM);3710val32 &= RXDMA_IDLE;3711if (val32)3712break;3713} while (--trycnt);3714if (trycnt == 0)3715RTW_INFO("[HW_VAR_FIFO_CLEARN_UP] Stop RX DMA failed......\n");37163717/* RQPN Load 0 */3718rtw_write16(padapter, REG_RQPN_NPQ, 0x0);3719rtw_write32(padapter, REG_RQPN, 0x80000000);3720rtw_mdelay_os(10);3721}3722}3723break;37243725case HW_VAR_RESTORE_HW_SEQ:3726rtw_restore_all_sta_hwseq(padapter);3727break;37283729case HW_VAR_CHECK_TXBUF: {3730u8 retry_limit;3731u32 reg_230 = 0, reg_234 = 0, reg_238 = 0, reg_23c = 0, reg_240 = 0;3732u32 init_reg_230 = 0, init_reg_234 = 0, init_reg_238 = 0, init_reg_23c = 0, init_reg_240 = 0;3733systime start = rtw_get_current_time();3734u32 pass_ms;3735int i = 0;37363737retry_limit = 0x01;37383739val16 = BIT_SRL(retry_limit) | BIT_LRL(retry_limit);3740rtw_write16(padapter, REG_RETRY_LIMIT, val16);37413742while (rtw_get_passing_time_ms(start) < 20003743&& !RTW_CANNOT_RUN(padapter)3744) {3745reg_230 = rtw_read32(padapter, REG_FIFOPAGE_INFO_1_8814A);3746reg_234 = rtw_read32(padapter, REG_FIFOPAGE_INFO_2_8814A);3747reg_238 = rtw_read32(padapter, REG_FIFOPAGE_INFO_3_8814A);3748reg_23c = rtw_read32(padapter, REG_FIFOPAGE_INFO_4_8814A);3749reg_240 = rtw_read32(padapter, REG_FIFOPAGE_INFO_5_8814A);37503751if (i == 0) {3752init_reg_230 = reg_230;3753init_reg_234 = reg_234;3754init_reg_238 = reg_238;3755init_reg_23c = reg_23c;3756init_reg_240 = reg_240;3757}37583759i++;3760if ((((reg_230 & 0x0c) != ((reg_230 >> 16) & 0x0c)) || ((reg_234 & 0x0c) != ((reg_234 >> 16) & 0x0c))3761|| ((reg_238 & 0x0c) != ((reg_238 >> 16) & 0x0c)) || ((reg_23c & 0x0c) != ((reg_23c >> 16) & 0x0c))3762|| ((reg_240 & 0x0c) != ((reg_240 >> 16) & 0x0c)))) {3763/* RTW_INFO("%s: (HW_VAR_CHECK_TXBUF)TXBUF NOT empty - 0x230=0x%08x, 0x234=0x%08x 0x238=0x%08x,"3764" 0x23c=0x%08x, 0x240=0x%08x (%d)\n"3765, __FUNCTION__, reg_230, reg_234, reg_238, reg_23c, reg_240, i); */3766rtw_msleep_os(10);3767} else3768break;3769}37703771pass_ms = rtw_get_passing_time_ms(start);37723773if (RTW_CANNOT_RUN(padapter))3774RTW_INFO("bDriverStopped or bSurpriseRemoved\n");3775else if (pass_ms >= 2000 || (((reg_230 & 0x0c) != ((reg_230 >> 16) & 0x0c)) || ((reg_234 & 0x0c) != ((reg_234 >> 16) & 0x0c))3776|| ((reg_238 & 0x0c) != ((reg_238 >> 16) & 0x0c)) || ((reg_23c & 0x0c) != ((reg_23c >> 16) & 0x0c))3777|| ((reg_240 & 0x0c) != ((reg_240 >> 16) & 0x0c)))) {3778RTW_PRINT("%s:(HW_VAR_CHECK_TXBUF)NOT empty(%d) in %d ms\n", __func__, i, pass_ms);3779RTW_PRINT("%s:(HW_VAR_CHECK_TXBUF) 0x230=0x%08x, 0x234=0x%08x 0x238=0x%08x, 0x23c=0x%08x, 0x240=0x%08x (0x%08x, 0x%08x, 0x%08x, 0x%08x, 0x%08x)\n", __func__,3780reg_230, reg_234, reg_238, reg_23c, reg_2403781, init_reg_230, init_reg_234, init_reg_238, init_reg_23c, init_reg_240);3782/* rtw_warn_on(1); */3783} else3784RTW_INFO("%s:(HW_VAR_CHECK_TXBUF)TXBUF Empty(%d) in %d ms\n", __FUNCTION__, i, pass_ms);37853786retry_limit = RL_VAL_STA;3787val16 = BIT_SRL(retry_limit) | BIT_LRL(retry_limit);3788rtw_write16(padapter, REG_RETRY_LIMIT, val16);3789}37903791break;37923793case HW_VAR_NAV_UPPER: {3794u32 usNavUpper = *((u32 *)pval);37953796if (usNavUpper > HAL_NAV_UPPER_UNIT * 0xFF) {3797RTW_INFO("%s: [HW_VAR_NAV_UPPER] set value(0x%08X us) is larger than (%d * 0xFF)!\n",3798__FUNCTION__, usNavUpper, HAL_NAV_UPPER_UNIT);3799break;3800}38013802/* The value of ((usNavUpper + HAL_NAV_UPPER_UNIT - 1) / HAL_NAV_UPPER_UNIT) */3803/* is getting the upper integer. */3804usNavUpper = (usNavUpper + HAL_NAV_UPPER_UNIT - 1) / HAL_NAV_UPPER_UNIT;3805rtw_write8(padapter, REG_NAV_UPPER, (u8)usNavUpper);3806}3807break;38083809case HW_VAR_BCN_VALID:3810#ifdef CONFIG_CONCURRENT_MODE3811if (padapter->hw_port == HW_PORT1) {3812/* BCN_VALID, BIT31 of REG_FIFOPAGE_CTRL_2_8814A, write 1 to clear, Clear by sw */3813val8 = rtw_read8(padapter, REG_FIFOPAGE_CTRL_2_8814A + 3);3814val8 |= BIT(7);3815rtw_write8(padapter, REG_FIFOPAGE_CTRL_2_8814A + 3, val8);3816} else3817#endif3818{3819/* BCN_VALID, BIT15 of REG_FIFOPAGE_CTRL_2_8814A, write 1 to clear, Clear by sw */3820val8 = rtw_read8(padapter, REG_FIFOPAGE_CTRL_2_8814A + 1);3821val8 |= BIT(7);3822rtw_write8(padapter, REG_FIFOPAGE_CTRL_2_8814A + 1, val8);3823}3824break;38253826case HW_VAR_DL_BCN_SEL:3827#if 0 /* for MBSSID, so far we don't need this */3828#ifdef CONFIG_CONCURRENT_MODE3829if (IS_HARDWARE_TYPE_8821(padapter) && padapter->hw_port == HW_PORT1) {3830/* SW_BCN_SEL - Port1 */3831val8 = rtw_read8(padapter, REG_AUTO_LLT_8814A);3832val8 |= BIT(2);3833rtw_write8(padapter, REG_AUTO_LLT_8814A, val8);3834} else3835#endif /* CONFIG_CONCURRENT_MODE */3836{3837/* SW_BCN_SEL - Port0 , BIT_r_EN_BCN_SW_HEAD_SEL */3838val8 = rtw_read8(padapter, REG_AUTO_LLT_8814A);3839val8 &= ~BIT(2);3840rtw_write8(padapter, REG_AUTO_LLT_8814A, val8);3841}3842#endif /* for MBSSID, so far we don't need this */3843break;38443845case HW_VAR_WIRELESS_MODE: {3846struct mlme_priv *pmlmepriv = &padapter->mlmepriv;3847struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;3848struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;3849u8 R2T_SIFS = 0, SIFS_Timer = 0;3850u8 wireless_mode = *pval;38513852if ((wireless_mode == WIRELESS_11BG) || (wireless_mode == WIRELESS_11G))3853SIFS_Timer = 0xa;3854else3855SIFS_Timer = 0xe;38563857/* SIFS for OFDM Data ACK */3858rtw_write8(padapter, REG_SIFS_CTX + 1, SIFS_Timer);3859/* SIFS for OFDM consecutive tx like CTS data! */3860rtw_write8(padapter, REG_SIFS_TRX + 1, SIFS_Timer);38613862rtw_write8(padapter, REG_SPEC_SIFS + 1, SIFS_Timer);3863rtw_write8(padapter, REG_MAC_SPEC_SIFS + 1, SIFS_Timer);38643865/* 20100719 Joseph: Revise SIFS setting due to Hardware register definition change. */3866rtw_write8(padapter, REG_RESP_SIFS_OFDM + 1, SIFS_Timer);3867rtw_write8(padapter, REG_RESP_SIFS_OFDM, SIFS_Timer);38683869/* */3870/* Adjust R2T SIFS for IOT issue. Add by hpfan 2013.01.25 */3871/* Set R2T SIFS to 0x0a for Atheros IOT. Add by hpfan 2013.02.22 */3872/* */3873/* Mac has 10 us delay so use 0xa value is enough. */3874R2T_SIFS = 0xa;3875#ifdef CONFIG_80211AC_VHT3876if (wireless_mode & WIRELESS_11_5AC &&3877/* MgntLinkStatusQuery(Adapter) && */3878TEST_FLAG(pmlmepriv->vhtpriv.ldpc_cap, LDPC_VHT_ENABLE_RX) &&3879TEST_FLAG(pmlmepriv->vhtpriv.stbc_cap, STBC_VHT_ENABLE_RX)) {3880if (pmlmeinfo->assoc_AP_vendor == HT_IOT_PEER_ATHEROS)3881R2T_SIFS = 0x8;3882else3883R2T_SIFS = 0xa;3884}3885#endif /* CONFIG_80211AC_VHT */38863887rtw_write8(padapter, REG_RESP_SIFS_OFDM + 1, R2T_SIFS);3888}3889break;38903891#ifdef CONFIG_BEAMFORMING /*PHYDM_BF - (BEAMFORMING_SUPPORT == 1)*/3892/*add by YuChen for PHYDM-TxBF AutoTest HW Timer*/3893case HW_VAR_HW_REG_TIMER_INIT: {3894HAL_HW_TIMER_TYPE TimerType = (*(PHAL_HW_TIMER_TYPE)pval) >> 16;38953896rtw_write8(padapter, 0x164, 1);38973898if (TimerType == HAL_TIMER_TXBF)3899rtw_write32(padapter, 0x15C, (*(u16 *)pval));3900else if (TimerType == HAL_TIMER_EARLYMODE)3901rtw_write32(padapter, 0x160, 0x05000190);3902break;3903}3904case HW_VAR_HW_REG_TIMER_START: {3905HAL_HW_TIMER_TYPE TimerType = *(PHAL_HW_TIMER_TYPE)pval;39063907if (TimerType == HAL_TIMER_TXBF)3908rtw_write8(padapter, 0x15F, 0x5);3909else if (TimerType == HAL_TIMER_EARLYMODE)3910rtw_write8(padapter, 0x163, 0x5);3911break;3912}3913case HW_VAR_HW_REG_TIMER_RESTART: {3914HAL_HW_TIMER_TYPE TimerType = *(PHAL_HW_TIMER_TYPE)pval;39153916if (TimerType == HAL_TIMER_TXBF) {3917rtw_write8(padapter, 0x15F, 0x0);3918rtw_write8(padapter, 0x15F, 0x5);3919} else if (TimerType == HAL_TIMER_EARLYMODE) {3920rtw_write8(padapter, 0x163, 0x0);3921rtw_write8(padapter, 0x163, 0x5);3922}3923break;3924}3925case HW_VAR_HW_REG_TIMER_STOP: {3926HAL_HW_TIMER_TYPE TimerType = *(PHAL_HW_TIMER_TYPE)pval;39273928if (TimerType == HAL_TIMER_TXBF)3929rtw_write8(padapter, 0x15F, 0);3930else if (TimerType == HAL_TIMER_EARLYMODE)3931rtw_write8(padapter, 0x163, 0x0);3932break;3933}3934#endif/*#ifdef CONFIG_BEAMFORMING*/39353936#ifdef CONFIG_GPIO_WAKEUP3937case HW_SET_GPIO_WL_CTRL: {3938u8 enable = *pval;3939u8 value = rtw_read8(padapter, 0x4e);3940if (enable && (value & BIT(6))) {3941value &= ~BIT(6);3942rtw_write8(padapter, 0x4e, value);3943} else if (enable == _FALSE) {3944value |= BIT(6);3945rtw_write8(padapter, 0x4e, value);3946}3947RTW_INFO("%s: set WL control, 0x4E=0x%02X\n",3948__func__, rtw_read8(padapter, 0x4e));3949}3950break;3951#endif39523953#if defined(CONFIG_TDLS) && defined(CONFIG_TDLS_CH_SW)3954case HW_VAR_TDLS_BCN_EARLY_C2H_RPT:3955rtl8814_set_BcnEarly_C2H_Rpt_cmd(padapter, *pval);3956break;3957#endif39583959default:3960ret = SetHwReg(padapter, variable, pval);3961break;3962}39633964return ret;3965}39663967struct qinfo_8814a {3968u32 head:11;3969u32 tail:11;3970u32 empty:1;3971u32 ac:2;3972u32 macid:7;3973};39743975struct bcn_qinfo_8814a {3976u16 head:12;3977u16 rsvd:4;3978};39793980void dump_qinfo_8814a(void *sel, struct qinfo_8814a *info, u32 pkt_num, const char *tag)3981{3982/* if (info->pkt_num) */3983RTW_PRINT_SEL(sel, "%shead:0x%02x, tail:0x%02x, pkt_num:%u, macid:%u, ac:%u\n"3984, tag ? tag : "", info->head, info->tail, pkt_num, info->macid, info->ac3985);3986}39873988void dump_bcn_qinfo_8814a(void *sel, struct bcn_qinfo_8814a *info, u32 pkt_num, const char *tag)3989{3990/* if (info->pkt_num) */3991RTW_PRINT_SEL(sel, "%shead:0x%02x, pkt_num:%u\n"3992, tag ? tag : "", info->head, pkt_num3993);3994}39953996void dump_mac_qinfo_8814a(void *sel, _adapter *adapter)3997{3998u32 q0_info;3999u32 q1_info;4000u32 q2_info;4001u32 q3_info;4002u32 q4_info;4003u32 q5_info;4004u32 q6_info;4005u32 q7_info;4006u32 mg_q_info;4007u32 hi_q_info;4008u16 bcn_q_info;4009u32 q0_q1_info;4010u32 q2_q3_info;4011u32 q4_q5_info;4012u32 q6_q7_info;4013u32 mg_hi_q_info;4014u32 cmd_bcn_q_info;401540164017q0_info = rtw_read32(adapter, REG_Q0_INFO);4018q1_info = rtw_read32(adapter, REG_Q1_INFO);4019q2_info = rtw_read32(adapter, REG_Q2_INFO);4020q3_info = rtw_read32(adapter, REG_Q3_INFO);4021q4_info = rtw_read32(adapter, REG_Q4_INFO);4022q5_info = rtw_read32(adapter, REG_Q5_INFO);4023q6_info = rtw_read32(adapter, REG_Q6_INFO);4024q7_info = rtw_read32(adapter, REG_Q7_INFO);4025mg_q_info = rtw_read32(adapter, REG_MGQ_INFO);4026hi_q_info = rtw_read32(adapter, REG_HGQ_INFO);4027bcn_q_info = rtw_read16(adapter, REG_BCNQ_INFO);40284029q0_q1_info = rtw_read32(adapter, REG_Q0_Q1_INFO_8814A);4030q2_q3_info = rtw_read32(adapter, REG_Q2_Q3_INFO_8814A);4031q4_q5_info = rtw_read32(adapter, REG_Q4_Q5_INFO_8814A);4032q6_q7_info = rtw_read32(adapter, REG_Q6_Q7_INFO_8814A);4033mg_hi_q_info = rtw_read32(adapter, REG_MGQ_HIQ_INFO_8814A);4034cmd_bcn_q_info = rtw_read32(adapter, REG_CMDQ_BCNQ_INFO_8814A);40354036dump_qinfo_8814a(sel, (struct qinfo_8814a *)&q0_info, q0_q1_info&0xFFF, "Q0 ");4037dump_qinfo_8814a(sel, (struct qinfo_8814a *)&q1_info, (q0_q1_info>>15)&0xFFF, "Q1 ");4038dump_qinfo_8814a(sel, (struct qinfo_8814a *)&q2_info, q2_q3_info&0xFFF, "Q2 ");4039dump_qinfo_8814a(sel, (struct qinfo_8814a *)&q3_info, (q2_q3_info>>15)&0xFFF, "Q3 ");4040dump_qinfo_8814a(sel, (struct qinfo_8814a *)&q4_info, q4_q5_info&0xFFF, "Q4 ");4041dump_qinfo_8814a(sel, (struct qinfo_8814a *)&q5_info, (q4_q5_info>>15)&0xFFF, "Q5 ");4042dump_qinfo_8814a(sel, (struct qinfo_8814a *)&q6_info, q6_q7_info&0xFFF, "Q6 ");4043dump_qinfo_8814a(sel, (struct qinfo_8814a *)&q7_info, (q6_q7_info>>15)&0xFFF, "Q7 ");4044dump_qinfo_8814a(sel, (struct qinfo_8814a *)&mg_q_info, mg_hi_q_info&0xFFF, "MG ");4045dump_qinfo_8814a(sel, (struct qinfo_8814a *)&hi_q_info, (mg_hi_q_info>>15)&0xFFF, "HI ");4046dump_bcn_qinfo_8814a(sel, (struct bcn_qinfo_8814a *)&bcn_q_info, cmd_bcn_q_info&0xFFF, "BCN ");4047}40484049static void dump_mac_txfifo_8814a(void *sel, _adapter *adapter)4050{4051u32 hpq, lpq, npq, epq, pubq;40524053hpq = rtw_read32(adapter, REG_FIFOPAGE_INFO_1_8814A);4054lpq = rtw_read32(adapter, REG_FIFOPAGE_INFO_2_8814A);4055npq = rtw_read32(adapter, REG_FIFOPAGE_INFO_3_8814A);4056epq = rtw_read32(adapter, REG_FIFOPAGE_INFO_4_8814A);4057pubq = rtw_read32(adapter, REG_FIFOPAGE_INFO_5_8814A);40584059hpq = (hpq & 0xFFF0000)>>16;4060lpq = (lpq & 0xFFF0000)>>16;4061npq = (npq & 0xFFF0000)>>16;4062epq = (epq & 0xFFF0000)>>16;4063pubq = (pubq & 0xFFF0000)>>16;40644065RTW_PRINT_SEL(sel, "Tx: available page num: ");4066if ((hpq == 0xAEA) && (hpq == lpq) && (hpq == pubq))4067RTW_PRINT_SEL(sel, "N/A (reg val = 0xea)\n");4068else4069RTW_PRINT_SEL(sel, "HPQ: %d, LPQ: %d, NPQ: %d, EPQ: %d, PUBQ: %d\n"4070, hpq, lpq, npq, epq, pubq);4071}40724073void rtl8814a_read_wmmedca_reg(PADAPTER adapter, u16 *vo_params, u16 *vi_params, u16 *be_params, u16 *bk_params)4074{4075u8 vo_reg_params[4];4076u8 vi_reg_params[4];4077u8 be_reg_params[4];4078u8 bk_reg_params[4];40794080GetHwReg8814A(adapter, HW_VAR_AC_PARAM_VO, vo_reg_params);4081GetHwReg8814A(adapter, HW_VAR_AC_PARAM_VI, vi_reg_params);4082GetHwReg8814A(adapter, HW_VAR_AC_PARAM_BE, be_reg_params);4083GetHwReg8814A(adapter, HW_VAR_AC_PARAM_BK, bk_reg_params);40844085vo_params[0] = vo_reg_params[0];4086vo_params[1] = vo_reg_params[1] & 0x0F;4087vo_params[2] = (vo_reg_params[1] & 0xF0) >> 4;4088vo_params[3] = ((vo_reg_params[3] << 8) | (vo_reg_params[2])) * 32;40894090vi_params[0] = vi_reg_params[0];4091vi_params[1] = vi_reg_params[1] & 0x0F;4092vi_params[2] = (vi_reg_params[1] & 0xF0) >> 4;4093vi_params[3] = ((vi_reg_params[3] << 8) | (vi_reg_params[2])) * 32;40944095be_params[0] = be_reg_params[0];4096be_params[1] = be_reg_params[1] & 0x0F;4097be_params[2] = (be_reg_params[1] & 0xF0) >> 4;4098be_params[3] = ((be_reg_params[3] << 8) | (be_reg_params[2])) * 32;40994100bk_params[0] = bk_reg_params[0];4101bk_params[1] = bk_reg_params[1] & 0x0F;4102bk_params[2] = (bk_reg_params[1] & 0xF0) >> 4;4103bk_params[3] = ((bk_reg_params[3] << 8) | (bk_reg_params[2])) * 32;41044105vo_params[1] = (1 << vo_params[1]) - 1;4106vo_params[2] = (1 << vo_params[2]) - 1;4107vi_params[1] = (1 << vi_params[1]) - 1;4108vi_params[2] = (1 << vi_params[2]) - 1;4109be_params[1] = (1 << be_params[1]) - 1;4110be_params[2] = (1 << be_params[2]) - 1;4111bk_params[1] = (1 << bk_params[1]) - 1;4112bk_params[2] = (1 << bk_params[2]) - 1;4113}41144115void GetHwReg8814A(PADAPTER padapter, u8 variable, u8 *pval)4116{4117PHAL_DATA_TYPE pHalData;4118u8 val8;4119u16 val16;4120u32 val32;412141224123pHalData = GET_HAL_DATA(padapter);41244125switch (variable) {4126case HW_VAR_TXPAUSE:4127*pval = rtw_read8(padapter, REG_TXPAUSE);4128break;41294130case HW_VAR_BCN_VALID:4131#ifdef CONFIG_CONCURRENT_MODE4132if (padapter->hw_port == HW_PORT1) {4133/* BCN_VALID, BIT31 of REG_FIFOPAGE_CTRL_2_8814A, write 1 to clear */4134val8 = rtw_read8(padapter, REG_FIFOPAGE_CTRL_2_8814A + 3);4135*pval = (BIT(7) & val8) ? _TRUE : _FALSE;4136} else4137#endif /* CONFIG_CONCURRENT_MODE */4138{4139/* BCN_VALID, BIT15 of REG_FIFOPAGE_CTRL_2_8814A, write 1 to clear */4140val8 = rtw_read8(padapter, REG_FIFOPAGE_CTRL_2_8814A + 1);4141*pval = (BIT(7) & val8) ? _TRUE : _FALSE;4142}4143break;41444145case HW_VAR_AC_PARAM_VO:4146val32 = rtw_read32(padapter, REG_EDCA_VO_PARAM);4147pval[0] = val32 & 0xFF;4148pval[1] = (val32 >> 8) & 0xFF;4149pval[2] = (val32 >> 16) & 0xFF;4150pval[3] = (val32 >> 24) & 0x07;4151break;41524153case HW_VAR_AC_PARAM_VI:4154val32 = rtw_read32(padapter, REG_EDCA_VI_PARAM);4155pval[0] = val32 & 0xFF;4156pval[1] = (val32 >> 8) & 0xFF;4157pval[2] = (val32 >> 16) & 0xFF;4158pval[3] = (val32 >> 24) & 0x07;4159break;41604161case HW_VAR_AC_PARAM_BE:4162val32 = rtw_read32(padapter, REG_EDCA_BE_PARAM);4163pval[0] = val32 & 0xFF;4164pval[1] = (val32 >> 8) & 0xFF;4165pval[2] = (val32 >> 16) & 0xFF;4166pval[3] = (val32 >> 24) & 0x07;4167break;41684169case HW_VAR_AC_PARAM_BK:4170val32 = rtw_read32(padapter, REG_EDCA_BK_PARAM);4171pval[0] = val32 & 0xFF;4172pval[1] = (val32 >> 8) & 0xFF;4173pval[2] = (val32 >> 16) & 0xFF;4174pval[3] = (val32 >> 24) & 0x07;4175break;41764177case HW_VAR_EFUSE_BYTES: /* To get EFUE total used bytes, added by Roger, 2008.12.22. */4178*(u16 *)pval = pHalData->EfuseUsedBytes;4179break;41804181case HW_VAR_CHK_HI_QUEUE_EMPTY:4182val16 = rtw_read16(padapter, REG_TXPKT_EMPTY);4183*pval = (val16 & BIT(10)) ? _TRUE : _FALSE;4184break;4185case HW_VAR_CHK_MGQ_CPU_EMPTY:4186val16 = rtw_read16(padapter, REG_TXPKT_EMPTY);4187*pval = (val16 & BIT(8)) ? _TRUE : _FALSE;4188break;4189case HW_VAR_DUMP_MAC_QUEUE_INFO:4190dump_mac_qinfo_8814a(pval, padapter);4191break;41924193case HW_VAR_DUMP_MAC_TXFIFO:4194dump_mac_txfifo_8814a(pval, padapter);4195break;41964197default:4198GetHwReg(padapter, variable, pval);4199break;4200}42014202}42034204/*4205* Description:4206* Change default setting of specified variable.4207*/4208u8 SetHalDefVar8814A(PADAPTER padapter, HAL_DEF_VARIABLE variable, void *pval)4209{4210PHAL_DATA_TYPE pHalData;4211u8 bResult;421242134214pHalData = GET_HAL_DATA(padapter);4215bResult = _SUCCESS;42164217switch (variable) {4218case HAL_DEF_EFUSE_BYTES:4219pHalData->EfuseUsedBytes = *((u16 *)pval);4220break;4221case HAL_DEF_EFUSE_USAGE:4222pHalData->EfuseUsedPercentage = *((u8 *)pval);4223break;4224default:4225bResult = SetHalDefVar(padapter, variable, pval);4226break;4227}42284229return bResult;4230}42314232/*4233* Description:4234* Query setting of specified variable.4235*/4236u8 GetHalDefVar8814A(PADAPTER padapter, HAL_DEF_VARIABLE variable, void *pval)4237{4238PHAL_DATA_TYPE pHalData;4239u8 bResult;424042414242pHalData = GET_HAL_DATA(padapter);4243bResult = _SUCCESS;42444245switch (variable) {424642474248#ifdef CONFIG_ANTENNA_DIVERSITY4249case HAL_DEF_IS_SUPPORT_ANT_DIV:4250*((u8 *)pval) = (pHalData->AntDivCfg == 0) ? _FALSE : _TRUE;4251break;4252#endif /* CONFIG_ANTENNA_DIVERSITY */42534254case HAL_DEF_DRVINFO_SZ:4255*((u32 *)pval) = DRVINFO_SZ;4256break;42574258case HAL_DEF_MAX_RECVBUF_SZ:4259*((u32 *)pval) = MAX_RECVBUF_SZ;4260break;42614262case HAL_DEF_RX_PACKET_OFFSET:4263*((u32 *)pval) = RXDESC_SIZE + DRVINFO_SZ * 8;4264break;42654266case HW_VAR_MAX_RX_AMPDU_FACTOR:4267*((u32 *)pval) = MAX_AMPDU_FACTOR_64K;4268break;42694270case HW_VAR_BEST_AMPDU_DENSITY:4271*((u32 *)pval) = AMPDU_DENSITY_VALUE_4;4272break;42734274case HAL_DEF_TX_LDPC:4275*(u8 *)pval = _TRUE;4276break;42774278case HAL_DEF_RX_LDPC:4279*(u8 *)pval = _TRUE;4280break;42814282case HAL_DEF_RX_STBC:4283*(u8 *)pval = 1;4284break;42854286case HAL_DEF_EXPLICIT_BEAMFORMER:4287if (pHalData->rf_type != RF_1T2R && pHalData->rf_type != RF_1T1R)/*1T?R not support mer*/4288*((PBOOLEAN)pval) = _TRUE;4289else4290*((PBOOLEAN)pval) = _FALSE;4291break;4292case HAL_DEF_EXPLICIT_BEAMFORMEE:4293*((PBOOLEAN)pval) = _TRUE;4294break;42954296case HW_DEF_RA_INFO_DUMP:4297#if 04298{4299u8 mac_id = *(u8 *)pval;4300u32 cmd ;4301u32 ra_info1, ra_info2;4302u32 rate_mask1, rate_mask2;4303u8 curr_tx_rate, curr_tx_sgi, hight_rate, lowest_rate;43044305RTW_INFO("============ RA status check Mac_id:%d ===================\n", mac_id);43064307cmd = 0x40000100 | mac_id;4308rtw_write32(padapter, REG_HMEBOX_E2_E3_8812, cmd);4309rtw_msleep_os(10);4310ra_info1 = rtw_read32(padapter, REG_RSVD5_8812);4311curr_tx_rate = ra_info1 & 0x7F;4312curr_tx_sgi = (ra_info1 >> 7) & 0x01;4313RTW_INFO("[ ra_info1:0x%08x ] =>cur_tx_rate= %s,cur_sgi:%d, PWRSTS = 0x%02x\n",4314ra_info1,4315HDATA_RATE(curr_tx_rate),4316curr_tx_sgi,4317(ra_info1 >> 8) & 0x07);43184319cmd = 0x40000400 | mac_id;4320rtw_write32(padapter, REG_HMEBOX_E2_E3_8812, cmd);4321rtw_msleep_os(10);4322ra_info1 = rtw_read32(padapter, REG_RSVD5_8812);4323ra_info2 = rtw_read32(padapter, REG_RSVD6_8812);4324rate_mask1 = rtw_read32(padapter, REG_RSVD7_8812);4325rate_mask2 = rtw_read32(padapter, REG_RSVD8_8812);4326hight_rate = ra_info2 & 0xFF;4327lowest_rate = (ra_info2 >> 8) & 0xFF;4328RTW_INFO("[ ra_info1:0x%08x ] =>RSSI=%d, BW_setting=0x%02x, DISRA=0x%02x, VHT_EN=0x%02x\n",4329ra_info1,4330ra_info1 & 0xFF,4331(ra_info1 >> 8) & 0xFF,4332(ra_info1 >> 16) & 0xFF,4333(ra_info1 >> 24) & 0xFF);43344335RTW_INFO("[ ra_info2:0x%08x ] =>hight_rate=%s, lowest_rate=%s, SGI=0x%02x, RateID=%d\n",4336ra_info2,4337HDATA_RATE(hight_rate),4338HDATA_RATE(lowest_rate),4339(ra_info2 >> 16) & 0xFF,4340(ra_info2 >> 24) & 0xFF);4341RTW_INFO("rate_mask2=0x%08x, rate_mask1=0x%08x\n", rate_mask2, rate_mask1);4342}4343#else /* 0 */4344RTW_INFO("%s,%d, 8814 need to fix\n", __FUNCTION__, __LINE__);4345#endif /* 0 */4346break;43474348case HAL_DEF_TX_PAGE_SIZE:4349*(u32 *)pval = PAGE_SIZE_128;4350break;43514352case HAL_DEF_TX_PAGE_BOUNDARY:4353if (!padapter->registrypriv.wifi_spec)4354*(u16 *)pval = TX_PAGE_BOUNDARY_8814A;4355else4356*(u16 *)pval = WMM_NORMAL_TX_PAGE_BOUNDARY_8814A;4357break;43584359case HAL_DEF_TX_PAGE_BOUNDARY_WOWLAN:4360*(u16 *)pval = TX_PAGE_BOUNDARY_WOWLAN_8814A;4361break;4362case HAL_DEF_EFUSE_BYTES:4363*((u16 *)(pval)) = pHalData->EfuseUsedBytes;4364break;4365case HAL_DEF_EFUSE_USAGE:4366*((u32 *)(pval)) = (pHalData->EfuseUsedPercentage << 16) | (pHalData->EfuseUsedBytes);4367break;4368case HAL_DEF_RX_DMA_SZ_WOW:4369*((u32 *)pval) = RX_DMA_BOUNDARY_8814A + 1;4370break;4371case HAL_DEF_RX_DMA_SZ:4372*((u32 *)pval) = RX_DMA_BOUNDARY_8814A + 1;4373break;4374case HAL_DEF_RX_PAGE_SIZE:4375*((u32 *)pval) = 8;4376break;4377default:4378bResult = GetHalDefVar(padapter, variable, pval);4379break;4380}43814382return bResult;4383}43844385#ifdef CONFIG_BT_COEXIST4386void rtl8814a_combo_card_WifiOnlyHwInit(PADAPTER pdapter)4387{4388u8 u1Tmp;4389RTW_INFO("%s !\n", __FUNCTION__);4390if (IS_HARDWARE_TYPE_8812(pdapter)) {4391/* 0x790[5:0]=0x5 */4392u1Tmp = rtw_read8(pdapter, 0x790);4393u1Tmp = (u1Tmp & 0xb0) | 0x05 ;4394rtw_write8(pdapter, 0x790, u1Tmp);4395/* PTA parameter */4396/* pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x6cc, 0x0); */4397/* pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c8, 0xffffff); */4398/* pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c4, 0x55555555); */4399/* pBtCoexist->fBtcWrite4Byte(pBtCoexist, 0x6c0, 0x55555555); */4400rtw_write8(pdapter, 0x6cc, 0x0);4401rtw_write32(pdapter, 0x6c8, 0xffffff);4402rtw_write32(pdapter, 0x6c4, 0x55555555);4403rtw_write32(pdapter, 0x6c0, 0x55555555);44044405/* coex parameters */4406/* pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x778, 0x3); */4407rtw_write8(pdapter, 0x778, 0x3);44084409/* enable counter statistics */4410/* pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x76e, 0xc); */4411rtw_write8(pdapter, 0x76e, 0xc);44124413/* enable PTA */4414/* pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x40, 0x20); */4415rtw_write8(pdapter, 0x40, 0x20);44164417/* bt clock related */4418/* u1Tmp = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x4); */4419/* u1Tmp |= BIT7; */4420/* pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x4, u1Tmp); */4421u1Tmp = rtw_read8(pdapter, 0x4);4422u1Tmp |= BIT7;4423rtw_write8(pdapter, 0x4, u1Tmp);44244425/* bt clock related */4426/* u1Tmp = pBtCoexist->fBtcRead1Byte(pBtCoexist, 0x7); */4427/* u1Tmp |= BIT1; */4428/* pBtCoexist->fBtcWrite1Byte(pBtCoexist, 0x7, u1Tmp); */4429u1Tmp = rtw_read8(pdapter, 0x7);4430u1Tmp |= BIT1;4431rtw_write8(pdapter, 0x7, u1Tmp);4432}443344344435}4436#endif /* CONFIG_BT_COEXIST */44374438void rtl8814_set_hal_ops(struct hal_ops *pHalFunc)4439{4440pHalFunc->dm_init = &rtl8814_init_dm_priv;4441pHalFunc->dm_deinit = &rtl8814_deinit_dm_priv;44424443pHalFunc->SetBeaconRelatedRegistersHandler = &SetBeaconRelatedRegisters8814A;44444445pHalFunc->read_chip_version = read_chip_version_8814a;44464447pHalFunc->set_chnl_bw_handler = &PHY_SetSwChnlBWMode8814;44484449pHalFunc->set_tx_power_level_handler = &PHY_SetTxPowerLevel8814;4450pHalFunc->set_tx_power_index_handler = PHY_SetTxPowerIndex_8814A;4451pHalFunc->get_tx_power_index_handler = &PHY_GetTxPowerIndex8814A;44524453pHalFunc->hal_dm_watchdog = &rtl8814_HalDmWatchDog;44544455pHalFunc->run_thread = &rtl8814_start_thread;4456pHalFunc->cancel_thread = &rtl8814_stop_thread;44574458pHalFunc->read_bbreg = &PHY_QueryBBReg8814A;4459pHalFunc->write_bbreg = &PHY_SetBBReg8814A;4460pHalFunc->read_rfreg = &PHY_QueryRFReg8814A;4461pHalFunc->write_rfreg = &PHY_SetRFReg8814A;44624463pHalFunc->read_wmmedca_reg = &rtl8814a_read_wmmedca_reg;44644465/* Efuse related function */4466pHalFunc->EfusePowerSwitch = &rtl8814_EfusePowerSwitch;4467pHalFunc->ReadEFuse = &rtl8814_ReadEFuse;4468pHalFunc->EFUSEGetEfuseDefinition = &rtl8814_EFUSE_GetEfuseDefinition;4469pHalFunc->EfuseGetCurrentSize = &rtl8814_EfuseGetCurrentSize;4470pHalFunc->Efuse_PgPacketRead = &rtl8814_Efuse_PgPacketRead;4471pHalFunc->Efuse_PgPacketWrite = &rtl8814_Efuse_PgPacketWrite;4472pHalFunc->Efuse_WordEnableDataWrite = &rtl8814_Efuse_WordEnableDataWrite;44734474#ifdef DBG_CONFIG_ERROR_DETECT4475pHalFunc->sreset_init_value = &sreset_init_value;4476pHalFunc->sreset_reset_value = &sreset_reset_value;4477pHalFunc->silentreset = &sreset_reset;4478pHalFunc->sreset_xmit_status_check = &rtl8814_sreset_xmit_status_check;4479pHalFunc->sreset_linked_status_check = &rtl8814_sreset_linked_status_check;4480pHalFunc->sreset_get_wifi_status = &sreset_get_wifi_status;4481pHalFunc->sreset_inprogress = &sreset_inprogress;4482#endif /* DBG_CONFIG_ERROR_DETECT */44834484pHalFunc->GetHalODMVarHandler = GetHalODMVar;4485pHalFunc->SetHalODMVarHandler = SetHalODMVar;4486pHalFunc->hal_notch_filter = &hal_notch_filter_8814;44874488pHalFunc->c2h_handler = c2h_handler_8814a;4489pHalFunc->reqtxrpt = &rtl8814_req_txrpt_cmd;44904491pHalFunc->fill_h2c_cmd = &FillH2CCmd_8814;4492pHalFunc->fill_fake_txdesc = &rtl8814a_fill_fake_txdesc;4493pHalFunc->fw_dl = &FirmwareDownload8814A;4494pHalFunc->hal_get_tx_buff_rsvd_page_num = &GetTxBufferRsvdPageNum8814;4495}449644974498