1 /******************************************************************************
3 * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 ******************************************************************************/
22 #include <drv_types.h>
23 #include <rtw_efuse.h>
25 #include <rtl8723a_hal.h>
39 tmp = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
40 rtw_write8(padapter, REG_SYS_FUNC_EN+1, tmp|0x04);
42 // MCU firmware download enable.
43 tmp = rtw_read8(padapter, REG_MCUFWDL);
44 rtw_write8(padapter, REG_MCUFWDL, tmp|0x01);
47 tmp = rtw_read8(padapter, REG_MCUFWDL+2);
48 rtw_write8(padapter, REG_MCUFWDL+2, tmp&0xf7);
52 // MCU firmware download disable.
53 tmp = rtw_read8(padapter, REG_MCUFWDL);
54 rtw_write8(padapter, REG_MCUFWDL, tmp&0xfe);
56 // Reserved for fw extension.
57 rtw_write8(padapter, REG_MCUFWDL+1, 0x00);
69 u32 blockSize_p1 = 4; // (Default) Phase #1 : PCI muse use 4-byte write to download FW
70 u32 blockSize_p2 = 8; // Phase #2 : Use 8-byte, if Phase#1 use big size to write FW.
71 u32 blockSize_p3 = 1; // Phase #3 : Use 1-byte, the remnant of FW image.
72 u32 blockCount_p1 = 0, blockCount_p2 = 0, blockCount_p3 = 0;
73 u32 remainSize_p1 = 0, remainSize_p2 = 0;
74 u8 *bufferPtr = (u8*)buffer;
82 blockCount_p1 = buffSize / blockSize_p1;
83 remainSize_p1 = buffSize % blockSize_p1;
86 RT_TRACE(_module_hal_init_c_, _drv_notice_,
87 ("_BlockWrite: [P1] buffSize(%d) blockSize_p1(%d) blockCount_p1(%d) remainSize_p1(%d)\n",
88 buffSize, blockSize_p1, blockCount_p1, remainSize_p1));
91 for (i = 0; i < blockCount_p1; i++)
94 ret = rtw_writeN(padapter, (FW_8723A_START_ADDRESS + i * blockSize_p1), blockSize_p1, (bufferPtr + i * blockSize_p1));
96 ret = rtw_write32(padapter, (FW_8723A_START_ADDRESS + i * blockSize_p1), le32_to_cpu(*((u32*)(bufferPtr + i * blockSize_p1))));
105 offset = blockCount_p1 * blockSize_p1;
107 blockCount_p2 = remainSize_p1/blockSize_p2;
108 remainSize_p2 = remainSize_p1%blockSize_p2;
111 RT_TRACE(_module_hal_init_c_, _drv_notice_,
112 ("_BlockWrite: [P2] buffSize_p2(%d) blockSize_p2(%d) blockCount_p2(%d) remainSize_p2(%d)\n",
113 (buffSize-offset), blockSize_p2 ,blockCount_p2, remainSize_p2));
116 #ifdef CONFIG_USB_HCI
117 for (i = 0; i < blockCount_p2; i++) {
118 ret = rtw_writeN(padapter, (FW_8723A_START_ADDRESS + offset + i*blockSize_p2), blockSize_p2, (bufferPtr + offset + i*blockSize_p2));
129 offset = (blockCount_p1 * blockSize_p1) + (blockCount_p2 * blockSize_p2);
131 blockCount_p3 = remainSize_p2 / blockSize_p3;
133 RT_TRACE(_module_hal_init_c_, _drv_notice_,
134 ("_BlockWrite: [P3] buffSize_p3(%d) blockSize_p3(%d) blockCount_p3(%d)\n",
135 (buffSize-offset), blockSize_p3, blockCount_p3));
137 for(i = 0 ; i < blockCount_p3 ; i++){
138 ret = rtw_write8(padapter, (FW_8723A_START_ADDRESS + offset + i), *(bufferPtr + offset + i));
151 IN PADAPTER padapter,
158 u8 u8Page = (u8) (page & 0x07) ;
160 value8 = (rtw_read8(padapter, REG_MCUFWDL+2) & 0xF8) | u8Page ;
161 rtw_write8(padapter, REG_MCUFWDL+2,value8);
163 return _BlockWrite(padapter,buffer,size);
173 u8 remain = (u8)(FwLen%4);
174 remain = (remain==0)?0:(4-remain);
188 IN PADAPTER padapter,
193 // Since we need dynamic decide method of dwonload fw, so we call this function to get chip version.
194 // We can remove _ReadChipVersion from ReadpadapterInfo8192C later.
196 u32 pageNums,remainSize ;
198 u8 *bufferPtr = (u8*)buffer;
200 #ifdef CONFIG_PCI_HCI
201 // 20100120 Joseph: Add for 88CE normal chip.
202 // Fill in zero to make firmware image to dword alignment.
203 _FillDummy(bufferPtr, &size);
206 pageNums = size / MAX_PAGE_SIZE ;
207 //RT_ASSERT((pageNums <= 4), ("Page numbers should not greater then 4 \n"));
208 remainSize = size % MAX_PAGE_SIZE;
210 for (page = 0; page < pageNums; page++) {
211 offset = page * MAX_PAGE_SIZE;
212 ret = _PageWrite(padapter, page, bufferPtr+offset, MAX_PAGE_SIZE);
218 offset = pageNums * MAX_PAGE_SIZE;
220 ret = _PageWrite(padapter, page, bufferPtr+offset, remainSize);
225 RT_TRACE(_module_hal_init_c_, _drv_info_, ("_WriteFW Done- for Normal chip.\n"));
231 static s32 _FWFreeToGo(PADAPTER padapter)
236 // polling CheckSum report
238 value32 = rtw_read32(padapter, REG_MCUFWDL);
239 if (value32 & FWDL_ChkSum_rpt) break;
240 } while (counter++ < POLLING_READY_TIMEOUT_COUNT);
242 if (counter >= POLLING_READY_TIMEOUT_COUNT) {
243 RT_TRACE(_module_hal_init_c_, _drv_err_, ("%s: chksum report fail! REG_MCUFWDL:0x%08x\n", __FUNCTION__, value32));
246 RT_TRACE(_module_hal_init_c_, _drv_info_, ("%s: Checksum report OK! REG_MCUFWDL:0x%08x\n", __FUNCTION__, value32));
248 value32 = rtw_read32(padapter, REG_MCUFWDL);
249 value32 |= MCUFWDL_RDY;
250 value32 &= ~WINTINI_RDY;
251 rtw_write32(padapter, REG_MCUFWDL, value32);
253 // polling for FW ready
256 value32 = rtw_read32(padapter, REG_MCUFWDL);
257 if (value32 & WINTINI_RDY) {
258 RT_TRACE(_module_hal_init_c_, _drv_info_, ("%s: Polling FW ready success!! REG_MCUFWDL:0x%08x\n", __FUNCTION__, value32));
262 } while (counter++ < POLLING_READY_TIMEOUT_COUNT);
264 RT_TRACE(_module_hal_init_c_, _drv_err_, ("%s: Polling FW ready fail!! REG_MCUFWDL:0x%08x\n", __FUNCTION__, value32));
268 #define IS_FW_81xxC(padapter) (((GET_HAL_DATA(padapter))->FirmwareSignature & 0xFFF0) == 0x88C0)
270 void rtl8723a_FirmwareSelfReset(PADAPTER padapter)
272 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
277 if (!(IS_FW_81xxC(padapter) &&
278 ((pHalData->FirmwareVersion < 0x21) ||
279 (pHalData->FirmwareVersion == 0x21 &&
280 pHalData->FirmwareSubVersion < 0x01)))) // after 88C Fw v33.1
282 //0x1cf=0x20. Inform 8051 to reset. 2009.12.25. tynli_test
283 rtw_write8(padapter, REG_HMETFR+3, 0x20);
285 u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
286 while (u1bTmp & BIT2)
292 u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
294 RT_TRACE(_module_hal_init_c_, _drv_info_, ("-%s: 8051 reset success (%d)\n", __FUNCTION__, Delay));
297 //force firmware reset
298 u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
299 rtw_write8(padapter, REG_SYS_FUNC_EN+1, u1bTmp&(~BIT2));
305 #ifdef CONFIG_FILE_FWIMG
306 extern char *rtw_fw_file_path;
307 u8 fw_buffer_8723a[FW_8723A_SIZE];
308 #endif //CONFIG_FILE_FWIMG
311 // Download 8192C firmware code.
314 s32 rtl8723a_FirmwareDownload(PADAPTER padapter)
316 s32 rtStatus = _SUCCESS;
317 u8 writeFW_retry = 0;
319 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
320 s8 R8723FwImageFileName_UMC[] ={RTL8723_FW_UMC_IMG};
321 s8 R8723FwImageFileName_UMC_B[] ={RTL8723_FW_UMC_B_IMG};
324 u8 *pFwImageFileName;
325 u8 *pucMappedFile = NULL;
326 PRT_FIRMWARE_8723A pFirmware = NULL;
327 PRT_FIRMWARE_8723A pBTFirmware = NULL;
328 PRT_8723A_FIRMWARE_HDR pFwHdr = NULL;
333 RT_TRACE(_module_hal_init_c_, _drv_info_, ("+%s\n", __FUNCTION__));
334 pFirmware = (PRT_FIRMWARE_8723A)kzalloc(sizeof(RT_FIRMWARE_8723A),
336 pBTFirmware = (PRT_FIRMWARE_8723A)kzalloc(sizeof(RT_FIRMWARE_8723A),
339 if(!pFirmware||!pBTFirmware)
345 if (IS_8723A_A_CUT(pHalData->VersionID)) {
346 pFwImageFileName = R8723FwImageFileName_UMC;
347 FwImage = (u8*)Rtl8723_FwImageArray;
348 FwImageLen = Rtl8723_ImgArrayLength;
349 RT_TRACE(_module_hal_init_c_, _drv_info_, ("rtl8723a_FirmwareDownload: R8723FwImageArray_UMC for RTL8723A A CUT\n"));
350 } else if (IS_8723A_B_CUT(pHalData->VersionID)) {
352 if (padapter->registrypriv.wifi_spec == 1) {
353 FwImage = (u8*)Rtl8723_FwUMCBCutImageArrayWithoutBT;
354 FwImageLen = Rtl8723_UMCBCutImgArrayWithoutBTLength;
355 DBG_8723A(" Rtl8723_FwUMCBCutImageArrayWithoutBT for RTL8723A B CUT\n");
357 #ifdef CONFIG_BT_COEXIST
358 FwImage = (u8*)Rtl8723_FwUMCBCutImageArrayWithBT;
359 FwImageLen = Rtl8723_UMCBCutImgArrayWithBTLength;
360 DBG_8723A(" Rtl8723_FwUMCBCutImageArrayWithBT for RTL8723A B CUT\n");
362 FwImage = (u8*)Rtl8723_FwUMCBCutImageArrayWithoutBT;
363 FwImageLen = Rtl8723_UMCBCutImgArrayWithoutBTLength;
364 DBG_8723A(" Rtl8723_FwUMCBCutImageArrayWithoutBT for RTL8723A B CUT\n");
367 pFwImageFileName = R8723FwImageFileName_UMC_B;
369 // <Roger_TODO> We should download proper RAM Code here to match the ROM code.
370 RT_TRACE(_module_hal_init_c_, _drv_err_, ("%s: unknow version!\n", __FUNCTION__));
376 #ifdef CONFIG_FILE_FWIMG
377 if(rtw_is_file_readable(rtw_fw_file_path) == _TRUE)
379 DBG_8723A("%s accquire FW from file:%s\n", __FUNCTION__, rtw_fw_file_path);
380 pFirmware->eFWSource = FW_SOURCE_IMG_FILE; // We should decided by Reg.
383 #endif //CONFIG_FILE_FWIMG
385 DBG_8723A("%s accquire FW from embedded image\n", __FUNCTION__);
386 pFirmware->eFWSource = FW_SOURCE_HEADER_FILE;
389 switch(pFirmware->eFWSource)
391 case FW_SOURCE_IMG_FILE:
392 #ifdef CONFIG_FILE_FWIMG
393 rtStatus = rtw_retrive_from_file(rtw_fw_file_path, fw_buffer_8723a, FW_8723A_SIZE);
394 pFirmware->ulFwLength = rtStatus>=0?rtStatus:0;
395 pFirmware->szFwBuffer = fw_buffer_8723a;
396 #endif //CONFIG_FILE_FWIMG
398 if(pFirmware->ulFwLength <= 0)
404 case FW_SOURCE_HEADER_FILE:
405 if (FwImageLen > FW_8723A_SIZE) {
407 RT_TRACE(_module_hal_init_c_, _drv_err_, ("Firmware size exceed 0x%X. Check it.\n", FW_8723A_SIZE) );
411 pFirmware->szFwBuffer = FwImage;
412 pFirmware->ulFwLength = FwImageLen;
416 #ifdef DBG_FW_STORE_FILE_PATH //used to store firmware to file...
417 if(pFirmware->ulFwLength > 0)
419 rtw_store_to_file(DBG_FW_STORE_FILE_PATH, pFirmware->szFwBuffer, pFirmware->ulFwLength);
423 pFirmwareBuf = pFirmware->szFwBuffer;
424 FirmwareLen = pFirmware->ulFwLength;
426 // To Check Fw header. Added by tynli. 2009.12.04.
427 pFwHdr = (PRT_8723A_FIRMWARE_HDR)pFirmware->szFwBuffer;
429 pHalData->FirmwareVersion = le16_to_cpu(pFwHdr->Version);
430 pHalData->FirmwareSubVersion = pFwHdr->Subversion;
431 pHalData->FirmwareSignature = le16_to_cpu(pFwHdr->Signature);
433 DBG_8723A("%s: fw_ver=%d fw_subver=%d sig=0x%x\n",
434 __FUNCTION__, pHalData->FirmwareVersion, pHalData->FirmwareSubVersion, pHalData->FirmwareSignature);
436 if (IS_FW_HEADER_EXIST(pFwHdr))
438 // Shift 32 bytes for FW header
439 pFirmwareBuf = pFirmwareBuf + 32;
440 FirmwareLen = FirmwareLen - 32;
443 // Suggested by Filen. If 8051 is running in RAM code, driver should inform Fw to reset by itself,
444 // or it will cause download Fw fail. 2010.02.01. by tynli.
445 if (rtw_read8(padapter, REG_MCUFWDL) & RAM_DL_SEL) //8051 RAM code
447 rtl8723a_FirmwareSelfReset(padapter);
448 rtw_write8(padapter, REG_MCUFWDL, 0x00);
451 _FWDownloadEnable(padapter, _TRUE);
452 fwdl_start_time = rtw_get_current_time();
454 //reset the FWDL chksum
455 rtw_write8(padapter, REG_MCUFWDL, rtw_read8(padapter, REG_MCUFWDL)|FWDL_ChkSum_rpt);
457 rtStatus = _WriteFW(padapter, pFirmwareBuf, FirmwareLen);
459 if(rtStatus == _SUCCESS
460 ||(rtw_get_passing_time_ms(fwdl_start_time) > 500 && writeFW_retry++ >= 3)
464 DBG_8723A("%s writeFW_retry:%u, time after fwdl_start_time:%ums\n", __FUNCTION__
466 , rtw_get_passing_time_ms(fwdl_start_time)
469 _FWDownloadEnable(padapter, _FALSE);
470 if(_SUCCESS != rtStatus){
471 DBG_8723A("DL Firmware failed!\n");
475 rtStatus = _FWFreeToGo(padapter);
476 if (_SUCCESS != rtStatus) {
477 RT_TRACE(_module_hal_init_c_, _drv_err_, ("DL Firmware failed!\n"));
480 RT_TRACE(_module_hal_init_c_, _drv_info_, ("Firmware is ready to run!\n"));
483 DBG_8723A("rtl8723a_FirmwareDownload Exit kfree pFirmware !\n");
486 DBG_8723A("rtl8723a_FirmwareDownload Exit kmfree pBTFirmware !\n");
489 //RT_TRACE(COMP_INIT, DBG_LOUD, (" <=== FirmwareDownload91C()\n"));
493 void rtl8723a_InitializeFirmwareVars(PADAPTER padapter)
495 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
497 // Init Fw LPS related.
498 padapter->pwrctrlpriv.bFwCurrentInPSMode = _FALSE;
500 // Init H2C counter. by tynli. 2009.12.09.
501 pHalData->LastHMEBoxNum = 0;
502 // pHalData->H2CQueueHead = 0;
503 // pHalData->H2CQueueTail = 0;
504 // pHalData->H2CStopInsertQueue = _FALSE;
507 static void rtl8723a_free_hal_data(PADAPTER padapter)
510 if (padapter->HalData) {
511 kfree(padapter->HalData);
512 padapter->HalData = NULL;
517 //===========================================================
518 // Efuse related code
519 //===========================================================
521 hal_EfuseSwitchToBank(
528 #ifdef HAL_EFUSE_MEMORY
529 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
530 PEFUSE_HAL pEfuseHal = &pHalData->EfuseHal;
534 DBG_8723A("%s: Efuse switch bank to %d\n", __FUNCTION__, bank);
537 #ifdef HAL_EFUSE_MEMORY
538 pEfuseHal->fakeEfuseBank = bank;
540 fakeEfuseBank = bank;
546 value32 = rtw_read32(padapter, EFUSE_TEST);
551 value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_WIFI_SEL_0);
554 value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_BT_SEL_0);
557 value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_BT_SEL_1);
560 value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_BT_SEL_2);
563 value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_WIFI_SEL_0);
567 rtw_write32(padapter, EFUSE_TEST, value32);
574 Hal_GetEfuseDefinition(
583 case TYPE_EFUSE_MAX_SECTION:
586 pMax_section = (u8*)pOut;
588 if (efuseType == EFUSE_WIFI)
589 *pMax_section = EFUSE_MAX_SECTION_8723A;
591 *pMax_section = EFUSE_BT_MAX_SECTION;
595 case TYPE_EFUSE_REAL_CONTENT_LEN:
600 if (efuseType == EFUSE_WIFI)
601 *pu2Tmp = EFUSE_REAL_CONTENT_LEN_8723A;
603 *pu2Tmp = EFUSE_BT_REAL_CONTENT_LEN;
607 case TYPE_AVAILABLE_EFUSE_BYTES_BANK:
612 if (efuseType == EFUSE_WIFI)
613 *pu2Tmp = (EFUSE_REAL_CONTENT_LEN_8723A-EFUSE_OOB_PROTECT_BYTES);
615 *pu2Tmp = (EFUSE_BT_REAL_BANK_CONTENT_LEN-EFUSE_PROTECT_BYTES_BANK);
619 case TYPE_AVAILABLE_EFUSE_BYTES_TOTAL:
624 if (efuseType == EFUSE_WIFI)
625 *pu2Tmp = (EFUSE_REAL_CONTENT_LEN_8723A-EFUSE_OOB_PROTECT_BYTES);
627 *pu2Tmp = (EFUSE_BT_REAL_CONTENT_LEN-(EFUSE_PROTECT_BYTES_BANK*3));
631 case TYPE_EFUSE_MAP_LEN:
636 if (efuseType == EFUSE_WIFI)
637 *pu2Tmp = EFUSE_MAP_LEN_8723A;
639 *pu2Tmp = EFUSE_BT_MAP_LEN;
643 case TYPE_EFUSE_PROTECT_BYTES_BANK:
648 if (efuseType == EFUSE_WIFI)
649 *pu1Tmp = EFUSE_OOB_PROTECT_BYTES;
651 *pu1Tmp = EFUSE_PROTECT_BYTES_BANK;
655 case TYPE_EFUSE_CONTENT_LEN_BANK:
660 if (efuseType == EFUSE_WIFI)
661 *pu2Tmp = EFUSE_REAL_CONTENT_LEN_8723A;
663 *pu2Tmp = EFUSE_BT_REAL_BANK_CONTENT_LEN;
677 #define VOLTAGE_V25 0x03
678 #define LDOE25_SHIFT 28
681 Hal_EfusePowerSwitch(
689 if (PwrState == _TRUE)
691 rtw_write8(padapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON);
693 // 1.2V Power: From VDDON with Power Cut(0x0000h[15]), defualt valid
694 tmpV16 = rtw_read16(padapter, REG_SYS_ISO_CTRL);
695 if (!(tmpV16 & PWC_EV12V)) {
696 tmpV16 |= PWC_EV12V ;
697 rtw_write16(padapter, REG_SYS_ISO_CTRL, tmpV16);
699 // Reset: 0x0000h[28], default valid
700 tmpV16 = rtw_read16(padapter, REG_SYS_FUNC_EN);
701 if (!(tmpV16 & FEN_ELDR)) {
703 rtw_write16(padapter, REG_SYS_FUNC_EN, tmpV16);
706 // Clock: Gated(0x0008h[5]) 8M(0x0008h[1]) clock from ANA, default valid
707 tmpV16 = rtw_read16(padapter, REG_SYS_CLKR);
708 if ((!(tmpV16 & LOADER_CLK_EN)) || (!(tmpV16 & ANA8M))) {
709 tmpV16 |= (LOADER_CLK_EN | ANA8M) ;
710 rtw_write16(padapter, REG_SYS_CLKR, tmpV16);
715 // Enable LDO 2.5V before read/write action
716 tempval = rtw_read8(padapter, EFUSE_TEST+3);
718 tempval |= (VOLTAGE_V25 << 4);
719 rtw_write8(padapter, EFUSE_TEST+3, (tempval | 0x80));
724 rtw_write8(padapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF);
726 if (bWrite == _TRUE) {
727 // Disable LDO 2.5V after read/write action
728 tempval = rtw_read8(padapter, EFUSE_TEST+3);
729 rtw_write8(padapter, EFUSE_TEST+3, (tempval & 0x7F));
742 #ifdef HAL_EFUSE_MEMORY
743 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
744 PEFUSE_HAL pEfuseHal = &pHalData->EfuseHal;
749 u8 efuseHeader, efuseExtHdr, efuseData;
755 // Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10.
757 if ((_offset+_size_byte) > EFUSE_MAP_LEN_8723A)
759 DBG_8723A("%s: Invalid offset(%#x) with read bytes(%#x)!!\n", __FUNCTION__, _offset, _size_byte);
763 efuseTbl = (u8*)kmalloc(EFUSE_MAP_LEN_8723A, GFP_KERNEL);
764 if (efuseTbl == NULL)
766 DBG_8723A("%s: alloc efuseTbl fail!\n", __FUNCTION__);
769 // 0xff will be efuse default value instead of 0x00.
770 memset(efuseTbl, 0xFF, EFUSE_MAP_LEN_8723A);
772 // switch bank back to bank 0 for later BT and wifi use.
773 hal_EfuseSwitchToBank(padapter, 0, bPseudoTest);
775 while (AVAILABLE_EFUSE_ADDR(eFuse_Addr))
777 ReadEFuseByte(padapter, eFuse_Addr++, &efuseHeader, bPseudoTest);
778 if (efuseHeader == 0xFF)
780 DBG_8723A("%s: data end at address=%#x\n", __FUNCTION__, eFuse_Addr);
783 // DBG_8723A("%s: efuse[0x%X]=0x%02X\n", __FUNCTION__, eFuse_Addr-1, efuseHeader);
785 // Check PG header for section num.
786 if (EXT_HEADER(efuseHeader)) //extended header
788 offset = GET_HDR_OFFSET_2_0(efuseHeader);
789 // DBG_8723A("%s: extended header offset_2_0=0x%X\n", __FUNCTION__, offset_2_0);
791 ReadEFuseByte(padapter, eFuse_Addr++, &efuseExtHdr, bPseudoTest);
792 // DBG_8723A("%s: efuse[0x%X]=0x%02X\n", __FUNCTION__, eFuse_Addr-1, efuseExtHdr);
793 if (ALL_WORDS_DISABLED(efuseExtHdr))
798 offset |= ((efuseExtHdr & 0xF0) >> 1);
799 wden = (efuseExtHdr & 0x0F);
803 offset = ((efuseHeader >> 4) & 0x0f);
804 wden = (efuseHeader & 0x0f);
807 if (offset < EFUSE_MAX_SECTION_8723A)
810 // Get word enable value from PG header
811 // DBG_8723A("%s: Offset=%d Worden=0x%X\n", __FUNCTION__, offset, wden);
813 addr = offset * PGPKT_DATA_SIZE;
814 for (i=0; i<EFUSE_MAX_WORD_UNIT; i++)
816 // Check word enable condition in the section
817 if (!(wden & (0x01<<i)))
819 ReadEFuseByte(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
820 // DBG_8723A("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, eFuse_Addr-1, efuseData);
821 efuseTbl[addr] = efuseData;
823 ReadEFuseByte(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
824 // DBG_8723A("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, eFuse_Addr-1, efuseData);
825 efuseTbl[addr+1] = efuseData;
832 DBG_8723A(KERN_ERR "%s: offset(%d) is illegal!!\n", __FUNCTION__, offset);
833 eFuse_Addr += Efuse_CalculateWordCnts(wden)*2;
837 // Copy from Efuse map to output pointer memory!!!
838 for (i=0; i<_size_byte; i++)
839 pbuf[i] = efuseTbl[_offset+i];
841 // Calculate Efuse utilization
842 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &total, bPseudoTest);
843 used = eFuse_Addr - 1;
844 efuse_usage = (u8)((used*100)/total);
847 #ifdef HAL_EFUSE_MEMORY
848 pEfuseHal->fakeEfuseUsedBytes = used;
850 fakeEfuseUsedBytes = used;
855 rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8*)&used);
856 rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_USAGE, (u8*)&efuse_usage);
872 #ifdef HAL_EFUSE_MEMORY
873 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
874 PEFUSE_HAL pEfuseHal = &pHalData->EfuseHal;
879 u8 efuseHeader, efuseExtHdr, efuseData;
886 // Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10.
888 if ((_offset+_size_byte) > EFUSE_BT_MAP_LEN)
890 DBG_8723A("%s: Invalid offset(%#x) with read bytes(%#x)!!\n", __FUNCTION__, _offset, _size_byte);
894 efuseTbl = kmalloc(EFUSE_BT_MAP_LEN, GFP_KERNEL);
895 if (efuseTbl == NULL) {
896 DBG_8723A("%s: efuseTbl malloc fail!\n", __FUNCTION__);
899 // 0xff will be efuse default value instead of 0x00.
900 memset(efuseTbl, 0xFF, EFUSE_BT_MAP_LEN);
902 EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_BANK, &total, bPseudoTest);
904 for (bank=1; bank<EFUSE_MAX_BANK; bank++)
906 if (hal_EfuseSwitchToBank(padapter, bank, bPseudoTest) == _FALSE)
908 DBG_8723A("%s: hal_EfuseSwitchToBank Fail!!\n", __FUNCTION__);
914 while (AVAILABLE_EFUSE_ADDR(eFuse_Addr))
916 ReadEFuseByte(padapter, eFuse_Addr++, &efuseHeader, bPseudoTest);
917 if (efuseHeader == 0xFF) break;
918 // DBG_8723A("%s: efuse[%#X]=0x%02x (header)\n", __FUNCTION__, (((bank-1)*EFUSE_REAL_CONTENT_LEN)+eFuse_Addr-1), efuseHeader);
920 // Check PG header for section num.
921 if (EXT_HEADER(efuseHeader)) //extended header
923 offset = GET_HDR_OFFSET_2_0(efuseHeader);
924 // DBG_8723A("%s: extended header offset_2_0=0x%X\n", __FUNCTION__, offset_2_0);
926 ReadEFuseByte(padapter, eFuse_Addr++, &efuseExtHdr, bPseudoTest);
927 // DBG_8723A("%s: efuse[%#X]=0x%02x (ext header)\n", __FUNCTION__, (((bank-1)*EFUSE_REAL_CONTENT_LEN)+eFuse_Addr-1), efuseExtHdr);
928 if (ALL_WORDS_DISABLED(efuseExtHdr))
933 offset |= ((efuseExtHdr & 0xF0) >> 1);
934 wden = (efuseExtHdr & 0x0F);
938 offset = ((efuseHeader >> 4) & 0x0f);
939 wden = (efuseHeader & 0x0f);
942 if (offset < EFUSE_BT_MAX_SECTION)
946 // Get word enable value from PG header
947 // DBG_8723A("%s: Offset=%d Worden=%#X\n", __FUNCTION__, offset, wden);
949 addr = offset * PGPKT_DATA_SIZE;
950 for (i=0; i<EFUSE_MAX_WORD_UNIT; i++)
952 // Check word enable condition in the section
953 if (!(wden & (0x01<<i)))
955 ReadEFuseByte(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
956 // DBG_8723A("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, eFuse_Addr-1, efuseData);
957 efuseTbl[addr] = efuseData;
959 ReadEFuseByte(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
960 // DBG_8723A("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, eFuse_Addr-1, efuseData);
961 efuseTbl[addr+1] = efuseData;
968 DBG_8723A(KERN_ERR "%s: offset(%d) is illegal!!\n", __FUNCTION__, offset);
969 eFuse_Addr += Efuse_CalculateWordCnts(wden)*2;
973 if ((eFuse_Addr-1) < total)
975 DBG_8723A("%s: bank(%d) data end at %#x\n", __FUNCTION__, bank, eFuse_Addr-1);
980 // switch bank back to bank 0 for later BT and wifi use.
981 hal_EfuseSwitchToBank(padapter, 0, bPseudoTest);
983 // Copy from Efuse map to output pointer memory!!!
984 for (i=0; i<_size_byte; i++)
985 pbuf[i] = efuseTbl[_offset+i];
988 // Calculate Efuse utilization.
990 EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &total, bPseudoTest);
991 used = (EFUSE_BT_REAL_BANK_CONTENT_LEN*(bank-1)) + eFuse_Addr - 1;
992 efuse_usage = (u8)((used*100)/total);
995 #ifdef HAL_EFUSE_MEMORY
996 pEfuseHal->fakeBTEfuseUsedBytes = used;
998 fakeBTEfuseUsedBytes = used;
1003 rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, (u8*)&used);
1004 rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BT_USAGE, (u8*)&efuse_usage);
1021 if (efuseType == EFUSE_WIFI)
1022 hal_ReadEFuse_WiFi(padapter, _offset, _size_byte, pbuf, bPseudoTest);
1024 hal_ReadEFuse_BT(padapter, _offset, _size_byte, pbuf, bPseudoTest);
1028 hal_EfuseGetCurrentSize_WiFi(
1032 #ifdef HAL_EFUSE_MEMORY
1033 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
1034 PEFUSE_HAL pEfuseHal = &pHalData->EfuseHal;
1037 u8 hoffset=0, hworden=0;
1038 u8 efuse_data, word_cnts=0;
1043 #ifdef HAL_EFUSE_MEMORY
1044 efuse_addr = (u16)pEfuseHal->fakeEfuseUsedBytes;
1046 efuse_addr = (u16)fakeEfuseUsedBytes;
1051 rtw_hal_get_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8*)&efuse_addr);
1053 DBG_8723A("%s: start_efuse_addr=0x%X\n", __FUNCTION__, efuse_addr);
1055 // switch bank back to bank 0 for later BT and wifi use.
1056 hal_EfuseSwitchToBank(padapter, 0, bPseudoTest);
1058 while (AVAILABLE_EFUSE_ADDR(efuse_addr))
1060 if (efuse_OneByteRead(padapter, efuse_addr, &efuse_data, bPseudoTest) == _FALSE)
1062 DBG_8723A(KERN_ERR "%s: efuse_OneByteRead Fail! addr=0x%X !!\n", __FUNCTION__, efuse_addr);
1066 if (efuse_data == 0xFF) break;
1068 if (EXT_HEADER(efuse_data))
1070 hoffset = GET_HDR_OFFSET_2_0(efuse_data);
1072 efuse_OneByteRead(padapter, efuse_addr, &efuse_data, bPseudoTest);
1073 if (ALL_WORDS_DISABLED(efuse_data))
1078 hoffset |= ((efuse_data & 0xF0) >> 1);
1079 hworden = efuse_data & 0x0F;
1083 hoffset = (efuse_data>>4) & 0x0F;
1084 hworden = efuse_data & 0x0F;
1087 word_cnts = Efuse_CalculateWordCnts(hworden);
1088 efuse_addr += (word_cnts*2)+1;
1093 #ifdef HAL_EFUSE_MEMORY
1094 pEfuseHal->fakeEfuseUsedBytes = efuse_addr;
1096 fakeEfuseUsedBytes = efuse_addr;
1101 rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8*)&efuse_addr);
1103 DBG_8723A("%s: CurrentSize=%d\n", __FUNCTION__, efuse_addr);
1109 hal_EfuseGetCurrentSize_BT(
1113 #ifdef HAL_EFUSE_MEMORY
1114 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
1115 PEFUSE_HAL pEfuseHal = &pHalData->EfuseHal;
1120 u8 hoffset=0, hworden=0;
1121 u8 efuse_data, word_cnts=0;
1127 #ifdef HAL_EFUSE_MEMORY
1128 btusedbytes = pEfuseHal->fakeBTEfuseUsedBytes;
1130 btusedbytes = fakeBTEfuseUsedBytes;
1135 rtw_hal_get_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, (u8*)&btusedbytes);
1137 efuse_addr = (u16)((btusedbytes%EFUSE_BT_REAL_BANK_CONTENT_LEN));
1138 startBank = (u8)(1+(btusedbytes/EFUSE_BT_REAL_BANK_CONTENT_LEN));
1140 DBG_8723A("%s: start from bank=%d addr=0x%X\n", __FUNCTION__, startBank, efuse_addr);
1142 EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_BANK, &retU2, bPseudoTest);
1144 for (bank=startBank; bank<EFUSE_MAX_BANK; bank++)
1146 if (hal_EfuseSwitchToBank(padapter, bank, bPseudoTest) == _FALSE)
1148 DBG_8723A(KERN_ERR "%s: switch bank(%d) Fail!!\n", __FUNCTION__, bank);
1149 bank = EFUSE_MAX_BANK;
1153 // only when bank is switched we have to reset the efuse_addr.
1154 if (bank != startBank)
1157 while (AVAILABLE_EFUSE_ADDR(efuse_addr))
1159 if (efuse_OneByteRead(padapter, efuse_addr, &efuse_data, bPseudoTest) == _FALSE)
1161 DBG_8723A(KERN_ERR "%s: efuse_OneByteRead Fail! addr=0x%X !!\n", __FUNCTION__, efuse_addr);
1162 bank = EFUSE_MAX_BANK;
1166 if (efuse_data == 0xFF) break;
1168 if (EXT_HEADER(efuse_data))
1170 hoffset = GET_HDR_OFFSET_2_0(efuse_data);
1172 efuse_OneByteRead(padapter, efuse_addr, &efuse_data, bPseudoTest);
1173 if (ALL_WORDS_DISABLED(efuse_data))
1179 hoffset |= ((efuse_data & 0xF0) >> 1);
1180 hworden = efuse_data & 0x0F;
1184 hoffset = (efuse_data>>4) & 0x0F;
1185 hworden = efuse_data & 0x0F;
1187 word_cnts = Efuse_CalculateWordCnts(hworden);
1189 efuse_addr += (word_cnts*2)+1;
1192 // Check if we need to check next bank efuse
1193 if (efuse_addr < retU2)
1195 break;// don't need to check next bank.
1199 retU2 = ((bank-1)*EFUSE_BT_REAL_BANK_CONTENT_LEN) + efuse_addr;
1202 #ifdef HAL_EFUSE_MEMORY
1203 pEfuseHal->fakeBTEfuseUsedBytes = retU2;
1205 fakeBTEfuseUsedBytes = retU2;
1210 rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, (u8*)&retU2);
1213 DBG_8723A("%s: CurrentSize=%d\n", __FUNCTION__, retU2);
1218 Hal_EfuseGetCurrentSize(
1225 if (efuseType == EFUSE_WIFI)
1226 ret = hal_EfuseGetCurrentSize_WiFi(pAdapter, bPseudoTest);
1228 ret = hal_EfuseGetCurrentSize_BT(pAdapter, bPseudoTest);
1234 Hal_EfuseWordEnableDataWrite(
1242 u16 start_addr = efuse_addr;
1243 u8 badworden = 0x0F;
1244 u8 tmpdata[PGPKT_DATA_SIZE];
1247 // DBG_8723A("%s: efuse_addr=%#x word_en=%#x\n", __FUNCTION__, efuse_addr, word_en);
1248 memset(tmpdata, 0xFF, PGPKT_DATA_SIZE);
1250 if (!(word_en & BIT(0)))
1252 tmpaddr = start_addr;
1253 efuse_OneByteWrite(padapter, start_addr++, data[0], bPseudoTest);
1254 efuse_OneByteWrite(padapter, start_addr++, data[1], bPseudoTest);
1256 efuse_OneByteRead(padapter, tmpaddr, &tmpdata[0], bPseudoTest);
1257 efuse_OneByteRead(padapter, tmpaddr+1, &tmpdata[1], bPseudoTest);
1258 if ((data[0]!=tmpdata[0]) || (data[1]!=tmpdata[1])) {
1259 badworden &= (~BIT(0));
1262 if (!(word_en & BIT(1)))
1264 tmpaddr = start_addr;
1265 efuse_OneByteWrite(padapter, start_addr++, data[2], bPseudoTest);
1266 efuse_OneByteWrite(padapter, start_addr++, data[3], bPseudoTest);
1268 efuse_OneByteRead(padapter, tmpaddr, &tmpdata[2], bPseudoTest);
1269 efuse_OneByteRead(padapter, tmpaddr+1, &tmpdata[3], bPseudoTest);
1270 if ((data[2]!=tmpdata[2]) || (data[3]!=tmpdata[3])) {
1271 badworden &= (~BIT(1));
1274 if (!(word_en & BIT(2)))
1276 tmpaddr = start_addr;
1277 efuse_OneByteWrite(padapter, start_addr++, data[4], bPseudoTest);
1278 efuse_OneByteWrite(padapter, start_addr++, data[5], bPseudoTest);
1280 efuse_OneByteRead(padapter, tmpaddr, &tmpdata[4], bPseudoTest);
1281 efuse_OneByteRead(padapter, tmpaddr+1, &tmpdata[5], bPseudoTest);
1282 if ((data[4]!=tmpdata[4]) || (data[5]!=tmpdata[5])) {
1283 badworden &= (~BIT(2));
1286 if (!(word_en & BIT(3)))
1288 tmpaddr = start_addr;
1289 efuse_OneByteWrite(padapter, start_addr++, data[6], bPseudoTest);
1290 efuse_OneByteWrite(padapter, start_addr++, data[7], bPseudoTest);
1292 efuse_OneByteRead(padapter, tmpaddr, &tmpdata[6], bPseudoTest);
1293 efuse_OneByteRead(padapter, tmpaddr+1, &tmpdata[7], bPseudoTest);
1294 if ((data[6]!=tmpdata[6]) || (data[7]!=tmpdata[7])) {
1295 badworden &= (~BIT(3));
1303 Hal_EfusePgPacketRead(
1309 u8 bDataEmpty = _TRUE;
1310 u8 efuse_data, word_cnts=0;
1312 u8 hoffset=0, hworden=0;
1321 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAX_SECTION, &max_section, bPseudoTest);
1322 if (offset > max_section)
1324 DBG_8723A("%s: Packet offset(%d) is illegal(>%d)!\n", __FUNCTION__, offset, max_section);
1328 memset(data, 0xFF, PGPKT_DATA_SIZE);
1332 // <Roger_TODO> Efuse has been pre-programmed dummy 5Bytes at the end of Efuse by CP.
1333 // Skip dummy parts to prevent unexpected data read from Efuse.
1334 // By pass right now. 2009.02.19.
1336 while (AVAILABLE_EFUSE_ADDR(efuse_addr))
1338 if (efuse_OneByteRead(padapter, efuse_addr++, &efuse_data, bPseudoTest) == _FALSE)
1344 if (efuse_data == 0xFF) break;
1346 if (EXT_HEADER(efuse_data))
1348 hoffset = GET_HDR_OFFSET_2_0(efuse_data);
1349 efuse_OneByteRead(padapter, efuse_addr++, &efuse_data, bPseudoTest);
1350 if (ALL_WORDS_DISABLED(efuse_data))
1352 DBG_8723A("%s: Error!! All words disabled!\n", __FUNCTION__);
1356 hoffset |= ((efuse_data & 0xF0) >> 1);
1357 hworden = efuse_data & 0x0F;
1361 hoffset = (efuse_data>>4) & 0x0F;
1362 hworden = efuse_data & 0x0F;
1365 if (hoffset == offset)
1367 for (i=0; i<EFUSE_MAX_WORD_UNIT; i++)
1369 // Check word enable condition in the section
1370 if (!(hworden & (0x01<<i)))
1372 ReadEFuseByte(padapter, efuse_addr++, &efuse_data, bPseudoTest);
1373 // DBG_8723A("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, efuse_addr+tmpidx, efuse_data);
1374 data[i*2] = efuse_data;
1376 ReadEFuseByte(padapter, efuse_addr++, &efuse_data, bPseudoTest);
1377 // DBG_8723A("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, efuse_addr+tmpidx, efuse_data);
1378 data[(i*2)+1] = efuse_data;
1384 word_cnts = Efuse_CalculateWordCnts(hworden);
1385 efuse_addr += word_cnts*2;
1393 hal_EfusePgCheckAvailableAddr(
1398 u16 max_available=0;
1402 EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &max_available, bPseudoTest);
1403 // DBG_8723A("%s: max_available=%d\n", __FUNCTION__, max_available);
1405 current_size = Efuse_GetCurrentSize(pAdapter, efuseType, bPseudoTest);
1406 if (current_size >= max_available)
1408 DBG_8723A("%s: Error!! current_size(%d)>max_available(%d)\n", __FUNCTION__, current_size, max_available);
1415 hal_EfuseConstructPGPkt(
1419 PPGPKT_STRUCT pTargetPkt)
1421 memset(pTargetPkt->data, 0xFF, PGPKT_DATA_SIZE);
1422 pTargetPkt->offset = offset;
1423 pTargetPkt->word_en = word_en;
1424 efuse_WordEnableDataRead(word_en, pData, pTargetPkt->data);
1425 pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en);
1431 PPGPKT_STRUCT pTargetPkt,
1432 PPGPKT_STRUCT pCurPkt,
1435 u8 match_word_en = 0x0F; // default all words are disabled
1438 // check if the same words are enabled both target and current PG packet
1439 if (((pTargetPkt->word_en & BIT(0)) == 0) &&
1440 ((pCurPkt->word_en & BIT(0)) == 0))
1442 match_word_en &= ~BIT(0); // enable word 0
1444 if (((pTargetPkt->word_en & BIT(1)) == 0) &&
1445 ((pCurPkt->word_en & BIT(1)) == 0))
1447 match_word_en &= ~BIT(1); // enable word 1
1449 if (((pTargetPkt->word_en & BIT(2)) == 0) &&
1450 ((pCurPkt->word_en & BIT(2)) == 0))
1452 match_word_en &= ~BIT(2); // enable word 2
1454 if (((pTargetPkt->word_en & BIT(3)) == 0) &&
1455 ((pCurPkt->word_en & BIT(3)) == 0))
1457 match_word_en &= ~BIT(3); // enable word 3
1460 *pWden = match_word_en;
1462 if (match_word_en != 0xf)
1469 hal_EfuseCheckIfDatafollowed(
1478 for (i=0; i<(word_cnts*2); i++)
1480 if (efuse_OneByteRead(pAdapter, (startAddr+i) ,&efuse_data, bPseudoTest) == _FALSE)
1482 DBG_8723A("%s: efuse_OneByteRead FAIL!!\n", __FUNCTION__);
1487 if (efuse_data != 0xFF)
1499 hal_EfusePartialWriteCheck(
1503 PPGPKT_STRUCT pTargetPkt,
1506 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
1507 PEFUSE_HAL pEfuseHal = &pHalData->EfuseHal;
1509 u16 startAddr=0, efuse_max_available_len=0, efuse_max=0;
1513 u8 new_wden=0, matched_wden=0, badworden=0;
1514 PGPKT_STRUCT curPkt;
1518 EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &efuse_max_available_len, bPseudoTest);
1519 EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_EFUSE_CONTENT_LEN_BANK, &efuse_max, bPseudoTest);
1521 if (efuseType == EFUSE_WIFI)
1525 #ifdef HAL_EFUSE_MEMORY
1526 startAddr = (u16)pEfuseHal->fakeEfuseUsedBytes;
1528 startAddr = (u16)fakeEfuseUsedBytes;
1533 rtw_hal_get_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8*)&startAddr);
1540 #ifdef HAL_EFUSE_MEMORY
1541 startAddr = (u16)pEfuseHal->fakeBTEfuseUsedBytes;
1543 startAddr = (u16)fakeBTEfuseUsedBytes;
1548 rtw_hal_get_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, (u8*)&startAddr);
1551 startAddr %= efuse_max;
1552 // DBG_8723A("%s: startAddr=%#X\n", __FUNCTION__, startAddr);
1556 if (startAddr >= efuse_max_available_len)
1559 DBG_8723A("%s: startAddr(%d) >= efuse_max_available_len(%d)\n",
1560 __FUNCTION__, startAddr, efuse_max_available_len);
1564 if (efuse_OneByteRead(padapter, startAddr, &efuse_data, bPseudoTest) && (efuse_data!=0xFF))
1568 DBG_8723A("%s: Something Wrong! last bytes(%#X=0x%02X) is not 0xFF\n",
1569 __FUNCTION__, startAddr, efuse_data);
1572 if (EXT_HEADER(efuse_data))
1574 cur_header = efuse_data;
1576 efuse_OneByteRead(padapter, startAddr, &efuse_data, bPseudoTest);
1577 if (ALL_WORDS_DISABLED(efuse_data))
1579 DBG_8723A("%s: Error condition, all words disabled!", __FUNCTION__);
1585 curPkt.offset = ((cur_header & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
1586 curPkt.word_en = efuse_data & 0x0F;
1591 cur_header = efuse_data;
1592 curPkt.offset = (cur_header>>4) & 0x0F;
1593 curPkt.word_en = cur_header & 0x0F;
1596 curPkt.word_cnts = Efuse_CalculateWordCnts(curPkt.word_en);
1597 // if same header is found but no data followed
1598 // write some part of data followed by the header.
1599 if ((curPkt.offset == pTargetPkt->offset) &&
1600 (hal_EfuseCheckIfDatafollowed(padapter, curPkt.word_cnts, startAddr+1, bPseudoTest) == _FALSE) &&
1601 wordEnMatched(pTargetPkt, &curPkt, &matched_wden) == _TRUE)
1603 DBG_8723A("%s: Need to partial write data by the previous wrote header\n", __FUNCTION__);
1604 // Here to write partial data
1605 badworden = Efuse_WordEnableDataWrite(padapter, startAddr+1, matched_wden, pTargetPkt->data, bPseudoTest);
1606 if (badworden != 0x0F)
1608 u32 PgWriteSuccess=0;
1609 // if write fail on some words, write these bad words again
1610 if (efuseType == EFUSE_WIFI)
1611 PgWriteSuccess = Efuse_PgPacketWrite(padapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest);
1613 PgWriteSuccess = Efuse_PgPacketWrite_BT(padapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest);
1615 if (!PgWriteSuccess)
1617 bRet = _FALSE; // write fail, return
1621 // partial write ok, update the target packet for later use
1624 if ((matched_wden & (0x1<<i)) == 0) // this word has been written
1626 pTargetPkt->word_en |= (0x1<<i); // disable the word
1629 pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en);
1631 // read from next header
1632 startAddr = startAddr + (curPkt.word_cnts*2) + 1;
1637 // not used header, 0xff
1639 // DBG_8723A("%s: Started from unused header offset=%d\n", __FUNCTION__, startAddr));
1649 hal_EfusePgPacketWrite1ByteHeader(
1653 PPGPKT_STRUCT pTargetPkt,
1657 u8 pg_header=0, tmp_header=0;
1658 u16 efuse_addr=*pAddr;
1662 // DBG_8723A("%s\n", __FUNCTION__);
1663 pg_header = ((pTargetPkt->offset << 4) & 0xf0) | pTargetPkt->word_en;
1666 efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);
1667 efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);
1668 if (tmp_header != 0xFF) break;
1669 if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_)
1671 DBG_8723A("%s: Repeat over limit for pg_header!!\n", __FUNCTION__);
1676 if (tmp_header != pg_header)
1678 DBG_8723A(KERN_ERR "%s: PG Header Fail!!(pg=0x%02X read=0x%02X)\n", __FUNCTION__, pg_header, tmp_header);
1682 *pAddr = efuse_addr;
1688 hal_EfusePgPacketWrite2ByteHeader(
1692 PPGPKT_STRUCT pTargetPkt,
1695 u16 efuse_addr, efuse_max_available_len=0;
1696 u8 pg_header=0, tmp_header=0;
1700 // DBG_8723A("%s\n", __FUNCTION__);
1701 EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_BANK, &efuse_max_available_len, bPseudoTest);
1703 efuse_addr = *pAddr;
1704 if (efuse_addr >= efuse_max_available_len)
1706 DBG_8723A("%s: addr(%d) over avaliable(%d)!!\n", __FUNCTION__, efuse_addr, efuse_max_available_len);
1710 pg_header = ((pTargetPkt->offset & 0x07) << 5) | 0x0F;
1711 // DBG_8723A("%s: pg_header=0x%x\n", __FUNCTION__, pg_header);
1714 efuse_OneByteWrite(padapter, efuse_addr, pg_header, bPseudoTest);
1715 efuse_OneByteRead(padapter, efuse_addr, &tmp_header, bPseudoTest);
1716 if (tmp_header != 0xFF) break;
1717 if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_)
1719 DBG_8723A("%s: Repeat over limit for pg_header!!\n", __FUNCTION__);
1724 if (tmp_header != pg_header)
1726 DBG_8723A(KERN_ERR "%s: PG Header Fail!!(pg=0x%02X read=0x%02X)\n", __FUNCTION__, pg_header, tmp_header);
1730 // to write ext_header
1732 pg_header = ((pTargetPkt->offset & 0x78) << 1) | pTargetPkt->word_en;
1735 efuse_OneByteWrite(padapter, efuse_addr, pg_header, bPseudoTest);
1736 efuse_OneByteRead(padapter, efuse_addr, &tmp_header, bPseudoTest);
1737 if (tmp_header != 0xFF) break;
1738 if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_)
1740 DBG_8723A("%s: Repeat over limit for ext_header!!\n", __FUNCTION__);
1745 if (tmp_header != pg_header) //offset PG fail
1747 DBG_8723A(KERN_ERR "%s: PG EXT Header Fail!!(pg=0x%02X read=0x%02X)\n", __FUNCTION__, pg_header, tmp_header);
1751 *pAddr = efuse_addr;
1757 hal_EfusePgPacketWriteHeader(
1761 PPGPKT_STRUCT pTargetPkt,
1766 if (pTargetPkt->offset >= EFUSE_MAX_SECTION_BASE)
1768 bRet = hal_EfusePgPacketWrite2ByteHeader(padapter, efuseType, pAddr, pTargetPkt, bPseudoTest);
1772 bRet = hal_EfusePgPacketWrite1ByteHeader(padapter, efuseType, pAddr, pTargetPkt, bPseudoTest);
1779 hal_EfusePgPacketWriteData(
1783 PPGPKT_STRUCT pTargetPkt,
1790 efuse_addr = *pAddr;
1791 badworden = Efuse_WordEnableDataWrite(pAdapter, efuse_addr+1, pTargetPkt->word_en, pTargetPkt->data, bPseudoTest);
1792 if (badworden != 0x0F)
1794 DBG_8723A("%s: Fail!!\n", __FUNCTION__);
1798 // DBG_8723A("%s: ok\n", __FUNCTION__);
1803 Hal_EfusePgPacketWrite(
1810 PGPKT_STRUCT targetPkt;
1812 u8 efuseType=EFUSE_WIFI;
1814 if (!hal_EfusePgCheckAvailableAddr(padapter, efuseType, bPseudoTest))
1817 hal_EfuseConstructPGPkt(offset, word_en, pData, &targetPkt);
1819 if (!hal_EfusePartialWriteCheck(padapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
1822 if (!hal_EfusePgPacketWriteHeader(padapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
1825 if (!hal_EfusePgPacketWriteData(padapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
1832 Hal_EfusePgPacketWrite_BT(
1839 PGPKT_STRUCT targetPkt;
1841 u8 efuseType=EFUSE_BT;
1843 if(!hal_EfusePgCheckAvailableAddr(pAdapter, efuseType, bPseudoTest))
1846 hal_EfuseConstructPGPkt(offset, word_en, pData, &targetPkt);
1848 if(!hal_EfusePartialWriteCheck(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
1851 if(!hal_EfusePgPacketWriteHeader(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
1854 if(!hal_EfusePgPacketWriteData(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
1861 ReadChipVersion8723A(
1862 IN PADAPTER padapter
1866 HAL_VERSION ChipVersion;
1867 HAL_DATA_TYPE *pHalData;
1870 pHalData = GET_HAL_DATA(padapter);
1872 value32 = rtw_read32(padapter, REG_SYS_CFG);
1873 ChipVersion.ICType = CHIP_8723A;
1874 ChipVersion.ChipType = ((value32 & RTL_ID) ? TEST_CHIP : NORMAL_CHIP);
1875 ChipVersion.RFType = RF_TYPE_1T1R ;
1876 ChipVersion.VendorType = ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : CHIP_VENDOR_TSMC);
1877 ChipVersion.CUTVersion = (value32 & CHIP_VER_RTL_MASK)>>CHIP_VER_RTL_SHIFT; // IC version (CUT)
1879 // For regulator mode. by tynli. 2011.01.14
1880 pHalData->RegulatorMode = ((value32 & SPS_SEL) ? RT_LDO_REGULATOR : RT_SWITCHING_REGULATOR);
1882 value32 = rtw_read32(padapter, REG_GPIO_OUTSTS);
1883 ChipVersion.ROMVer = ((value32 & RF_RL_ID) >> 20); // ROM code version.
1885 // For multi-function consideration. Added by Roger, 2010.10.06.
1886 pHalData->MultiFunc = RT_MULTI_FUNC_NONE;
1887 value32 = rtw_read32(padapter, REG_MULTI_FUNC_CTRL);
1888 pHalData->MultiFunc |= ((value32 & WL_FUNC_EN) ? RT_MULTI_FUNC_WIFI : 0);
1889 pHalData->MultiFunc |= ((value32 & BT_FUNC_EN) ? RT_MULTI_FUNC_BT : 0);
1890 pHalData->MultiFunc |= ((value32 & GPS_FUNC_EN) ? RT_MULTI_FUNC_GPS : 0);
1891 pHalData->PolarityCtl = ((value32 & WL_HWPDN_SL) ? RT_POLARITY_HIGH_ACT : RT_POLARITY_LOW_ACT);
1894 dump_chip_info(ChipVersion);
1896 pHalData->VersionID = ChipVersion;
1898 if (IS_1T2R(ChipVersion))
1899 pHalData->rf_type = RF_1T2R;
1900 else if (IS_2T2R(ChipVersion))
1901 pHalData->rf_type = RF_2T2R;
1903 pHalData->rf_type = RF_1T1R;
1905 MSG_8723A("RF_Type is %x!!\n", pHalData->rf_type);
1911 static void rtl8723a_read_chip_version(PADAPTER padapter)
1913 ReadChipVersion8723A(padapter);
1916 //====================================================================================
1919 // This function is used only for 92C to set REG_BCN_CTRL(0x550) register.
1920 // We just reserve the value of the register in variable pHalData->RegBcnCtrlVal and then operate
1921 // the value of the register via atomic operation.
1922 // This prevents from race condition when setting this register.
1923 // The value of pHalData->RegBcnCtrlVal is initialized in HwConfigureRTL8192CE() function.
1925 void SetBcnCtrlReg(PADAPTER padapter, u8 SetBits, u8 ClearBits)
1927 PHAL_DATA_TYPE pHalData;
1932 pHalData = GET_HAL_DATA(padapter);
1933 pRegBcnCtrlVal = (u8*)&pHalData->RegBcnCtrlVal;
1935 #ifdef CONFIG_CONCURRENT_MODE
1936 if (padapter->iface_type == IFACE_PORT1)
1938 addr = REG_BCN_CTRL_1;
1944 addr = REG_BCN_CTRL;
1947 *pRegBcnCtrlVal = rtw_read8(padapter, addr);
1948 *pRegBcnCtrlVal |= SetBits;
1949 *pRegBcnCtrlVal &= ~ClearBits;
1952 //#ifdef CONFIG_SDIO_HCI
1953 if (pHalData->sdio_himr & (SDIO_HIMR_TXBCNOK_MSK | SDIO_HIMR_TXBCNERR_MSK))
1954 *pRegBcnCtrlVal |= EN_TXBCN_RPT;
1957 rtw_write8(padapter, addr, *pRegBcnCtrlVal);
1960 void rtl8723a_InitBeaconParameters(PADAPTER padapter)
1962 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
1965 rtw_write16(padapter, REG_BCN_CTRL, 0x1010);
1966 pHalData->RegBcnCtrlVal = 0x1010;
1968 // TODO: Remove these magic number
1969 rtw_write16(padapter, REG_TBTT_PROHIBIT, 0x6404);// ms
1970 // Firmware will control REG_DRVERLYINT when power saving is enable,
1971 // so don't set this register on STA mode.
1972 if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) == _FALSE)
1973 rtw_write8(padapter, REG_DRVERLYINT, DRIVER_EARLY_INT_TIME); // 5ms
1974 rtw_write8(padapter, REG_BCNDMATIM, BCN_DMA_ATIME_INT_TIME); // 2ms
1976 // Suggested by designer timchen. Change beacon AIFS to the largest number
1977 // beacause test chip does not contension before sending beacon. by tynli. 2009.11.03
1978 rtw_write16(padapter, REG_BCNTCFG, 0x660F);
1981 void rtl8723a_InitBeaconMaxError(PADAPTER padapter, u8 InfraMode)
1983 #ifdef RTL8192CU_ADHOC_WORKAROUND_SETTING
1984 rtw_write8(padapter, REG_BCN_MAX_ERR, 0xFF);
1986 //rtw_write8(Adapter, REG_BCN_MAX_ERR, (InfraMode ? 0xFF : 0x10));
1990 static void ResumeTxBeacon(PADAPTER padapter)
1992 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
1995 // 2010.03.01. Marked by tynli. No need to call workitem beacause we record the value
1996 // which should be read from register to a global variable.
1998 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("+ResumeTxBeacon\n"));
2000 pHalData->RegFwHwTxQCtrl |= BIT(6);
2001 rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, pHalData->RegFwHwTxQCtrl);
2002 rtw_write8(padapter, REG_TBTT_PROHIBIT+1, 0xff);
2003 pHalData->RegReg542 |= BIT(0);
2004 rtw_write8(padapter, REG_TBTT_PROHIBIT+2, pHalData->RegReg542);
2007 static void StopTxBeacon(PADAPTER padapter)
2009 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
2012 // 2010.03.01. Marked by tynli. No need to call workitem beacause we record the value
2013 // which should be read from register to a global variable.
2015 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("+StopTxBeacon\n"));
2017 pHalData->RegFwHwTxQCtrl &= ~BIT(6);
2018 rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, pHalData->RegFwHwTxQCtrl);
2019 rtw_write8(padapter, REG_TBTT_PROHIBIT+1, 0x64);
2020 pHalData->RegReg542 &= ~BIT(0);
2021 rtw_write8(padapter, REG_TBTT_PROHIBIT+2, pHalData->RegReg542);
2023 CheckFwRsvdPageContent(padapter); // 2010.06.23. Added by tynli.
2026 static void _BeaconFunctionEnable(PADAPTER padapter, u8 Enable, u8 Linked)
2028 SetBcnCtrlReg(padapter, DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_BCNQ_SUB, 0);
2029 rtw_write8(padapter, REG_RD_CTRL+1, 0x6F);
2032 static void rtl8723a_SetBeaconRelatedRegisters(PADAPTER padapter)
2035 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
2036 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2037 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2040 //reset TSF, enable update TSF, correcting TSF On Beacon
2048 //REG_BCNTCFG //(0x510)
2050 //REG_BCN_CTRL //(0x550)
2055 rtw_write16(padapter, REG_ATIMWND, 2);
2058 // Beacon interval (in unit of TU).
2060 rtw_write16(padapter, REG_BCN_INTERVAL, pmlmeinfo->bcn_interval);
2062 rtl8723a_InitBeaconParameters(padapter);
2064 rtw_write8(padapter, REG_SLOT, 0x09);
2067 // Reset TSF Timer to zero, added by Roger. 2008.06.24
2069 value32 = rtw_read32(padapter, REG_TCR);
2071 rtw_write32(padapter, REG_TCR, value32);
2074 rtw_write32(padapter, REG_TCR, value32);
2076 // NOTE: Fix test chip's bug (about contention windows's randomness)
2077 if (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE) == _TRUE)
2079 rtw_write8(padapter, REG_RXTSF_OFFSET_CCK, 0x50);
2080 rtw_write8(padapter, REG_RXTSF_OFFSET_OFDM, 0x50);
2083 _BeaconFunctionEnable(padapter, _TRUE, _TRUE);
2085 ResumeTxBeacon(padapter);
2086 SetBcnCtrlReg(padapter, DIS_BCNQ_SUB, 0);
2089 void rtl8723a_GetHalODMVar(
2091 HAL_ODM_VARIABLE eVariable,
2095 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
2096 PDM_ODM_T podmpriv = &pHalData->odmpriv;
2098 case HAL_ODM_STA_INFO:
2105 void rtl8723a_SetHalODMVar(
2107 HAL_ODM_VARIABLE eVariable,
2111 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
2112 PDM_ODM_T podmpriv = &pHalData->odmpriv;
2114 case HAL_ODM_STA_INFO:
2116 struct sta_info *psta = (struct sta_info *)pValue1;
2117 #ifdef CONFIG_CONCURRENT_MODE
2118 //get Primary adapter's odmpriv
2119 if(Adapter->adapter_type > PRIMARY_ADAPTER && Adapter->pbuddy_adapter){
2120 pHalData = GET_HAL_DATA(Adapter->pbuddy_adapter);
2121 podmpriv = &pHalData->odmpriv;
2126 DBG_8723A("Set STA_(%d) info\n",psta->mac_id);
2127 ODM_CmnInfoPtrArrayHook(podmpriv, ODM_CMNINFO_STA_STATUS,psta->mac_id,psta);
2130 DBG_8723A("Clean STA_(%d) info\n",psta->mac_id);
2131 ODM_CmnInfoPtrArrayHook(podmpriv, ODM_CMNINFO_STA_STATUS,psta->mac_id,NULL);
2135 case HAL_ODM_P2P_STATE:
2136 ODM_CmnInfoUpdate(podmpriv,ODM_CMNINFO_WIFI_DIRECT,bSet);
2138 case HAL_ODM_WIFI_DISPLAY_STATE:
2139 ODM_CmnInfoUpdate(podmpriv,ODM_CMNINFO_WIFI_DISPLAY,bSet);
2145 void hal_notch_filter_8723a(_adapter *adapter, bool enable)
2148 DBG_8723A("Enable notch filter\n");
2149 rtw_write8(adapter, rOFDM0_RxDSP+1, rtw_read8(adapter, rOFDM0_RxDSP+1) | BIT1);
2151 DBG_8723A("Disable notch filter\n");
2152 rtw_write8(adapter, rOFDM0_RxDSP+1, rtw_read8(adapter, rOFDM0_RxDSP+1) & ~BIT1);
2156 s32 c2h_id_filter_ccx_8723a(u8 id)
2159 if (id == C2H_CCX_TX_RPT)
2165 static s32 c2h_handler_8723a(_adapter *padapter, struct c2h_evt_hdr *c2h_evt)
2170 if (c2h_evt == NULL) {
2171 DBG_8723A("%s c2h_evt is NULL\n",__FUNCTION__);
2176 switch (c2h_evt->id) {
2178 RT_TRACE(_module_hal_init_c_, _drv_info_, ("C2HCommandHandler: %s\n", c2h_evt->payload));
2181 case C2H_CCX_TX_RPT:
2182 handle_txrpt_ccx_8723a(padapter, c2h_evt->payload);
2185 #ifdef CONFIG_BT_COEXIST
2186 #ifdef CONFIG_PCI_HCI
2188 BT_FwC2hBtRssi(padapter, c2h_evt->payload);
2193 case C2H_EXT_RA_RPT:
2194 // C2HExtRaRptHandler(padapter, tmpBuf, C2hEvent.CmdLen);
2197 case C2H_HW_INFO_EXCH:
2198 RT_TRACE(_module_hal_init_c_, _drv_info_, ("[BT], C2H_HW_INFO_EXCH\n"));
2199 for (i = 0; i < c2h_evt->plen; i++) {
2200 RT_TRACE(_module_hal_init_c_, _drv_info_, ("[BT], tmpBuf[%d]=0x%x\n", i, c2h_evt->payload[i]));
2204 case C2H_C2H_H2C_TEST:
2205 RT_TRACE(_module_hal_init_c_, _drv_info_, ("[BT], C2H_H2C_TEST\n"));
2206 RT_TRACE(_module_hal_init_c_, _drv_info_, ("[BT], tmpBuf[0]/[1]/[2]/[3]/[4]=0x%x/ 0x%x/ 0x%x/ 0x%x/ 0x%x\n",
2207 c2h_evt->payload[0], c2h_evt->payload[1], c2h_evt->payload[2], c2h_evt->payload[3], c2h_evt->payload[4]));
2210 #ifdef CONFIG_BT_COEXIST
2212 DBG_8723A("%s , Got C2H_BT_INFO \n",__FUNCTION__);
2213 BT_FwC2hBtInfo(padapter, c2h_evt->payload, c2h_evt->plen);
2226 void rtl8723a_set_hal_ops(struct hal_ops *pHalFunc)
2228 pHalFunc->free_hal_data = &rtl8723a_free_hal_data;
2230 pHalFunc->dm_init = &rtl8723a_init_dm_priv;
2231 pHalFunc->dm_deinit = &rtl8723a_deinit_dm_priv;
2233 pHalFunc->read_chip_version = &rtl8723a_read_chip_version;
2235 pHalFunc->set_bwmode_handler = &PHY_SetBWMode8192C;
2236 pHalFunc->set_channel_handler = &PHY_SwChnl8192C;
2238 pHalFunc->hal_dm_watchdog = &rtl8723a_HalDmWatchDog;
2240 pHalFunc->SetBeaconRelatedRegistersHandler = &rtl8723a_SetBeaconRelatedRegisters;
2242 pHalFunc->Add_RateATid = &rtl8192c_Add_RateATid;
2243 #ifdef CONFIG_CONCURRENT_MODE
2244 pHalFunc->clone_haldata = &rtl8723a_clone_haldata;
2246 pHalFunc->run_thread= &rtl8723a_start_thread;
2247 pHalFunc->cancel_thread= &rtl8723a_stop_thread;
2249 #ifdef CONFIG_ANTENNA_DIVERSITY
2250 pHalFunc->AntDivBeforeLinkHandler = &odm_AntDivBeforeLink8192C;
2251 pHalFunc->AntDivCompareHandler = &odm_AntDivCompare8192C;
2254 pHalFunc->read_bbreg = &rtl8192c_PHY_QueryBBReg;
2255 pHalFunc->write_bbreg = &rtl8192c_PHY_SetBBReg;
2256 pHalFunc->read_rfreg = &rtl8192c_PHY_QueryRFReg;
2257 pHalFunc->write_rfreg = &rtl8192c_PHY_SetRFReg;
2259 // Efuse related function
2260 pHalFunc->EfusePowerSwitch = &Hal_EfusePowerSwitch;
2261 pHalFunc->ReadEFuse = &Hal_ReadEFuse;
2262 pHalFunc->EFUSEGetEfuseDefinition = &Hal_GetEfuseDefinition;
2263 pHalFunc->EfuseGetCurrentSize = &Hal_EfuseGetCurrentSize;
2264 pHalFunc->Efuse_PgPacketRead = &Hal_EfusePgPacketRead;
2265 pHalFunc->Efuse_PgPacketWrite = &Hal_EfusePgPacketWrite;
2266 pHalFunc->Efuse_WordEnableDataWrite = &Hal_EfuseWordEnableDataWrite;
2267 pHalFunc->Efuse_PgPacketWrite_BT = &Hal_EfusePgPacketWrite_BT;
2269 #ifdef DBG_CONFIG_ERROR_DETECT
2270 pHalFunc->sreset_init_value = &sreset_init_value;
2271 pHalFunc->sreset_reset_value = &sreset_reset_value;
2272 pHalFunc->silentreset = &sreset_reset;
2273 pHalFunc->sreset_xmit_status_check = &rtl8723a_sreset_xmit_status_check;
2274 pHalFunc->sreset_linked_status_check = &rtl8723a_sreset_linked_status_check;
2275 pHalFunc->sreset_get_wifi_status = &sreset_get_wifi_status;
2276 pHalFunc->sreset_inprogress= &sreset_inprogress;
2278 pHalFunc->GetHalODMVarHandler = &rtl8723a_GetHalODMVar;
2279 pHalFunc->SetHalODMVarHandler = &rtl8723a_SetHalODMVar;
2281 #ifdef CONFIG_XMIT_THREAD_MODE
2282 pHalFunc->xmit_thread_handler = &hal_xmit_handler;
2284 pHalFunc->hal_notch_filter = &hal_notch_filter_8723a;
2286 pHalFunc->c2h_handler = c2h_handler_8723a;
2287 pHalFunc->c2h_id_filter_ccx = c2h_id_filter_ccx_8723a;
2289 #if defined(CONFIG_CHECK_BT_HANG) && defined(CONFIG_BT_COEXIST)
2290 pHalFunc->hal_init_checkbthang_workqueue = &rtl8723a_init_checkbthang_workqueue;
2291 pHalFunc->hal_free_checkbthang_workqueue = &rtl8723a_free_checkbthang_workqueue;
2292 pHalFunc->hal_cancel_checkbthang_workqueue = &rtl8723a_cancel_checkbthang_workqueue;
2293 pHalFunc->hal_checke_bt_hang = &rtl8723a_hal_check_bt_hang;
2297 void rtl8723a_InitAntenna_Selection(PADAPTER padapter)
2299 PHAL_DATA_TYPE pHalData;
2303 pHalData = GET_HAL_DATA(padapter);
2305 val = rtw_read8(padapter, REG_LEDCFG2);
2306 // Let 8051 take control antenna settting
2307 val |= BIT(7); // DPDT_SEL_EN, 0x4C[23]
2308 rtw_write8(padapter, REG_LEDCFG2, val);
2311 void rtl8723a_CheckAntenna_Selection(PADAPTER padapter)
2313 PHAL_DATA_TYPE pHalData;
2317 pHalData = GET_HAL_DATA(padapter);
2319 val = rtw_read8(padapter, REG_LEDCFG2);
2320 // Let 8051 take control antenna settting
2322 val |= BIT(7); // DPDT_SEL_EN, 0x4C[23]
2323 rtw_write8(padapter, REG_LEDCFG2, val);
2326 void rtl8723a_DeinitAntenna_Selection(PADAPTER padapter)
2328 PHAL_DATA_TYPE pHalData;
2332 pHalData = GET_HAL_DATA(padapter);
2333 val = rtw_read8(padapter, REG_LEDCFG2);
2334 // Let 8051 take control antenna settting
2335 val &= ~BIT(7); // DPDT_SEL_EN, clear 0x4C[23]
2336 rtw_write8(padapter, REG_LEDCFG2, val);
2340 void rtl8723a_init_default_value(PADAPTER padapter)
2342 PHAL_DATA_TYPE pHalData;
2343 struct dm_priv *pdmpriv;
2347 pHalData = GET_HAL_DATA(padapter);
2348 pdmpriv = &pHalData->dmpriv;
2350 // init default value
2351 pHalData->fw_ractrl = _FALSE;
2352 pHalData->bIQKInitialized = _FALSE;
2353 if (!padapter->pwrctrlpriv.bkeepfwalive)
2354 pHalData->LastHMEBoxNum = 0;
2356 pHalData->bIQKInitialized = _FALSE;
2358 // init dm default value
2359 pdmpriv->TM_Trigger = 0;//for IQK
2360 // pdmpriv->binitialized = _FALSE;
2361 // pdmpriv->prv_traffic_idx = 3;
2362 // pdmpriv->initialize = 0;
2364 pdmpriv->ThermalValue_HP_index = 0;
2365 for (i=0; i<HP_THERMAL_NUM; i++)
2366 pdmpriv->ThermalValue_HP[i] = 0;
2368 // init Efuse variables
2369 pHalData->EfuseUsedBytes = 0;
2370 pHalData->EfuseUsedPercentage = 0;
2371 #ifdef HAL_EFUSE_MEMORY
2372 pHalData->EfuseHal.fakeEfuseBank = 0;
2373 pHalData->EfuseHal.fakeEfuseUsedBytes = 0;
2374 memset(pHalData->EfuseHal.fakeEfuseContent, 0xFF, EFUSE_MAX_HW_SIZE);
2375 memset(pHalData->EfuseHal.fakeEfuseInitMap, 0xFF, EFUSE_MAX_MAP_LEN);
2376 memset(pHalData->EfuseHal.fakeEfuseModifiedMap, 0xFF, EFUSE_MAX_MAP_LEN);
2377 pHalData->EfuseHal.BTEfuseUsedBytes = 0;
2378 pHalData->EfuseHal.BTEfuseUsedPercentage = 0;
2379 memset(pHalData->EfuseHal.BTEfuseContent, 0xFF, EFUSE_MAX_BT_BANK*EFUSE_MAX_HW_SIZE);
2380 memset(pHalData->EfuseHal.BTEfuseInitMap, 0xFF, EFUSE_BT_MAX_MAP_LEN);
2381 memset(pHalData->EfuseHal.BTEfuseModifiedMap, 0xFF, EFUSE_BT_MAX_MAP_LEN);
2382 pHalData->EfuseHal.fakeBTEfuseUsedBytes = 0;
2383 memset(pHalData->EfuseHal.fakeBTEfuseContent, 0xFF, EFUSE_MAX_BT_BANK*EFUSE_MAX_HW_SIZE);
2384 memset(pHalData->EfuseHal.fakeBTEfuseInitMap, 0xFF, EFUSE_BT_MAX_MAP_LEN);
2385 memset(pHalData->EfuseHal.fakeBTEfuseModifiedMap, 0xFF, EFUSE_BT_MAX_MAP_LEN);
2389 u8 GetEEPROMSize8723A(PADAPTER padapter)
2394 cr = rtw_read16(padapter, REG_9346CR);
2395 // 6: EEPROM used is 93C46, 4: boot from E-Fuse.
2396 size = (cr & BOOT_FROM_EEPROM) ? 6 : 4;
2398 MSG_8723A("EEPROM type is %s\n", size==4 ? "E-FUSE" : "93C46");
2403 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
2404 //-------------------------------------------------------------------------
2406 // LLT R/W/Init function
2408 //-------------------------------------------------------------------------
2409 s32 _LLTWrite(PADAPTER padapter, u32 address, u32 data)
2411 s32 status = _SUCCESS;
2413 u32 value = _LLT_INIT_ADDR(address) | _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS);
2414 u16 LLTReg = REG_LLT_INIT;
2417 rtw_write32(padapter, LLTReg, value);
2421 value = rtw_read32(padapter, LLTReg);
2422 if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value)) {
2426 if (count > POLLING_LLT_THRESHOLD) {
2427 RT_TRACE(_module_hal_init_c_, _drv_err_, ("Failed to polling write LLT done at address %d!\n", address));
2436 u8 _LLTRead(PADAPTER padapter, u32 address)
2439 u32 value = _LLT_INIT_ADDR(address) | _LLT_OP(_LLT_READ_ACCESS);
2440 u16 LLTReg = REG_LLT_INIT;
2443 rtw_write32(padapter, LLTReg, value);
2445 //polling and get value
2447 value = rtw_read32(padapter, LLTReg);
2448 if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value)) {
2452 if (count > POLLING_LLT_THRESHOLD) {
2453 RT_TRACE(_module_hal_init_c_, _drv_err_, ("Failed to polling read LLT done at address %d!\n", address));
2461 s32 InitLLTTable(PADAPTER padapter, u32 boundary)
2463 s32 status = _SUCCESS;
2465 u32 txpktbuf_bndy = boundary;
2466 u32 Last_Entry_Of_TxPktBuf = LAST_ENTRY_OF_TX_PKT_BUFFER;
2467 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
2469 for (i = 0; i < (txpktbuf_bndy - 1); i++) {
2470 status = _LLTWrite(padapter, i, i + 1);
2471 if (_SUCCESS != status) {
2477 status = _LLTWrite(padapter, (txpktbuf_bndy - 1), 0xFF);
2478 if (_SUCCESS != status) {
2482 // Make the other pages as ring buffer
2483 // This ring buffer is used as beacon buffer if we config this MAC as two MAC transfer.
2484 // Otherwise used as local loopback buffer.
2485 for (i = txpktbuf_bndy; i < Last_Entry_Of_TxPktBuf; i++) {
2486 status = _LLTWrite(padapter, i, (i + 1));
2487 if (_SUCCESS != status) {
2492 // Let last entry point to the start entry of ring buffer
2493 status = _LLTWrite(padapter, Last_Entry_Of_TxPktBuf, txpktbuf_bndy);
2494 if (_SUCCESS != status) {
2502 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
2503 void _DisableGPIO(PADAPTER padapter)
2505 /***************************************
2506 j. GPIO_PIN_CTRL 0x44[31:0]=0x000 //
2507 k.Value = GPIO_PIN_CTRL[7:0]
2508 l. GPIO_PIN_CTRL 0x44[31:0] = 0x00FF0000 | (value <<8); //write external PIN level
2509 m. GPIO_MUXCFG 0x42 [15:0] = 0x0780
2510 n. LEDCFG 0x4C[15:0] = 0x8080
2511 ***************************************/
2518 //1. Disable GPIO[7:0]
2519 rtw_write16(padapter, REG_GPIO_PIN_CTRL+2, 0x0000);
2520 value32 = rtw_read32(padapter, REG_GPIO_PIN_CTRL) & 0xFFFF00FF;
2521 u4bTmp = value32 & 0x000000FF;
2522 value32 |= ((u4bTmp<<8) | 0x00FF0000);
2523 rtw_write32(padapter, REG_GPIO_PIN_CTRL, value32);
2526 // <Roger_Notes> For RTL8723u multi-function configuration which was autoload from Efuse offset 0x0a and 0x0b,
2527 // WLAN HW GPIO[9], GPS HW GPIO[10] and BT HW GPIO[11].
2528 // Added by Roger, 2010.10.07.
2530 //2. Disable GPIO[8] and GPIO[12]
2531 rtw_write16(padapter, REG_GPIO_IO_SEL_2, 0x0000); // Configure all pins as input mode.
2532 value32 = rtw_read32(padapter, REG_GPIO_PIN_CTRL_2) & 0xFFFF001F;
2533 u4bTmp = value32 & 0x0000001F;
2534 value32 |= ((u4bTmp<<8) | 0x001D0000); // Set pin 8, 10, 11 and pin 12 to output mode.
2535 rtw_write32(padapter, REG_GPIO_PIN_CTRL_2, value32);
2537 //3. Disable LED0 & 1
2538 rtw_write16(padapter, REG_LEDCFG0, 0x8080);
2539 } //end of _DisableGPIO()
2541 void _DisableRFAFEAndResetBB8192C(PADAPTER padapter)
2543 /**************************************
2544 a. TXPAUSE 0x522[7:0] = 0xFF //Pause MAC TX queue
2545 b. RF path 0 offset 0x00 = 0x00 // disable RF
2546 c. APSD_CTRL 0x600[7:0] = 0x40
2547 d. SYS_FUNC_EN 0x02[7:0] = 0x16 //reset BB state machine
2548 e. SYS_FUNC_EN 0x02[7:0] = 0x14 //reset BB state machine
2549 ***************************************/
2550 u8 eRFPath = 0, value8 = 0;
2552 rtw_write8(padapter, REG_TXPAUSE, 0xFF);
2554 PHY_SetRFReg(padapter, (RF_RADIO_PATH_E)eRFPath, 0x0, bMaskByte0, 0x0);
2557 rtw_write8(padapter, REG_APSD_CTRL, value8);//0x40
2559 // Set BB reset at first
2561 value8 |= (FEN_USBD | FEN_USBA | FEN_BB_GLB_RSTn);
2562 rtw_write8(padapter, REG_SYS_FUNC_EN, value8 );//0x16
2564 // Set global reset.
2565 value8 &= ~FEN_BB_GLB_RSTn;
2566 rtw_write8(padapter, REG_SYS_FUNC_EN, value8); //0x14
2568 // 2010/08/12 MH We need to set BB/GLBAL reset to save power for SS mode.
2570 // RT_TRACE(COMP_INIT, DBG_LOUD, ("======> RF off and reset BB.\n"));
2573 void _DisableRFAFEAndResetBB(PADAPTER padapter)
2575 _DisableRFAFEAndResetBB8192C(padapter);
2578 void _ResetDigitalProcedure1_92C(PADAPTER padapter, bool bWithoutHWSM)
2580 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
2582 if (IS_FW_81xxC(padapter) && (pHalData->FirmwareVersion <= 0x20)) {
2583 /*****************************
2584 f. MCUFWDL 0x80[7:0]=0 // reset MCU ready status
2585 g. SYS_FUNC_EN 0x02[10]= 0 // reset MCU register, (8051 reset)
2586 h. SYS_FUNC_EN 0x02[15-12]= 5 // reset MAC register, DCORE
2587 i. SYS_FUNC_EN 0x02[10]= 1 // enable MCU register, (8051 enable)
2588 ******************************/
2590 rtw_write8(padapter, REG_MCUFWDL, 0);
2592 valu16 = rtw_read16(padapter, REG_SYS_FUNC_EN);
2593 rtw_write16(padapter, REG_SYS_FUNC_EN, (valu16 & (~FEN_CPUEN)));//reset MCU ,8051
2595 valu16 = rtw_read16(padapter, REG_SYS_FUNC_EN)&0x0FFF;
2596 rtw_write16(padapter, REG_SYS_FUNC_EN, (valu16 |(FEN_HWPDN|FEN_ELDR)));//reset MAC
2598 valu16 = rtw_read16(padapter, REG_SYS_FUNC_EN);
2599 rtw_write16(padapter, REG_SYS_FUNC_EN, (valu16 | FEN_CPUEN));//enable MCU ,8051
2603 // 2010/08/12 MH For USB SS, we can not stop 8051 when we are trying to
2604 // enter IPS/HW&SW radio off. For S3/S4/S5/Disable, we can stop 8051 because
2605 // we will init FW when power on again.
2606 //if(!pDevice->RegUsbSS)
2607 { // If we want to SS mode, we can not reset 8051.
2608 if(rtw_read8(padapter, REG_MCUFWDL) & BIT1)
2609 { //IF fw in RAM code, do reset
2612 if(padapter->bFWReady)
2614 // 2010/08/25 MH Accordign to RD alfred's suggestion, we need to disable other
2615 // HRCV INT to influence 8051 reset.
2616 rtw_write8(padapter, REG_FWIMR, 0x20);
2617 // 2011/02/15 MH According to Alex's suggestion, close mask to prevent incorrect FW write operation.
2618 rtw_write8(padapter, REG_FTIMR, 0x00);
2619 rtw_write8(padapter, REG_FSIMR, 0x00);
2621 rtw_write8(padapter, REG_HMETFR+3, 0x20);//8051 reset by self
2623 while( (retry_cnts++ <100) && (FEN_CPUEN &rtw_read16(padapter, REG_SYS_FUNC_EN)))
2625 rtw_udelay_os(50);//us
2626 // 2010/08/25 For test only We keep on reset 5051 to prevent fail.
2627 //rtw_write8(padapter, REG_HMETFR+3, 0x20);//8051 reset by self
2629 // RT_ASSERT((retry_cnts < 100), ("8051 reset failed!\n"));
2631 if (retry_cnts >= 100)
2633 // if 8051 reset fail we trigger GPIO 0 for LA
2634 //rtw_write32( padapter,
2635 // REG_GPIO_PIN_CTRL,
2637 // 2010/08/31 MH According to Filen's info, if 8051 reset fail, reset MAC directly.
2638 rtw_write8(padapter, REG_SYS_FUNC_EN+1, 0x50); //Reset MAC and Enable 8051
2642 // RT_TRACE(COMP_INIT, DBG_LOUD, ("=====> 8051 reset success (%d) .\n",retry_cnts));
2647 // RT_TRACE(COMP_INIT, DBG_LOUD, ("=====> 8051 in ROM.\n"));
2649 rtw_write8(padapter, REG_SYS_FUNC_EN+1, 0x54); //Reset MAC and Enable 8051
2650 rtw_write8(padapter, REG_MCUFWDL, 0);
2654 //if(pDevice->RegUsbSS)
2655 //bWithoutHWSM = TRUE; // Sugest by Filen and Issau.
2659 //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
2660 /*****************************
2661 Without HW auto state machine
2662 g. SYS_CLKR 0x08[15:0] = 0x30A3 //disable MAC clock
2663 h. AFE_PLL_CTRL 0x28[7:0] = 0x80 //disable AFE PLL
2664 i. AFE_XTAL_CTRL 0x24[15:0] = 0x880F //gated AFE DIG_CLOCK
2665 j. SYS_ISO_CTRL 0x00[7:0] = 0xF9 // isolated digital to PON
2666 ******************************/
2667 //rtw_write16(padapter, REG_SYS_CLKR, 0x30A3);
2668 //if(!pDevice->RegUsbSS)
2669 // 2011/01/26 MH SD4 Scott suggest to fix UNC-B cut bug.
2670 //if (IS_81xxC_VENDOR_UMC_B_CUT(pHalData->VersionID))
2671 //rtw_write16(padapter, REG_SYS_CLKR, (0x70A3|BIT6)); //modify to 0x70A3 by Scott.
2673 rtw_write16(padapter, REG_SYS_CLKR, 0x70A3); //modify to 0x70A3 by Scott.
2674 rtw_write8(padapter, REG_AFE_PLL_CTRL, 0x80);
2675 rtw_write16(padapter, REG_AFE_XTAL_CTRL, 0x880F);
2676 //if(!pDevice->RegUsbSS)
2677 rtw_write8(padapter, REG_SYS_ISO_CTRL, 0xF9);
2681 // Disable all RF/BB power
2682 rtw_write8(padapter, REG_RF_CTRL, 0x00);
2684 // RT_TRACE(COMP_INIT, DBG_LOUD, ("======> Reset Digital.\n"));
2688 void _ResetDigitalProcedure1(PADAPTER padapter, bool bWithoutHWSM)
2690 _ResetDigitalProcedure1_92C(padapter, bWithoutHWSM);
2693 void _ResetDigitalProcedure2(PADAPTER padapter)
2695 /*****************************
2696 k. SYS_FUNC_EN 0x03[7:0] = 0x44 // disable ELDR runction
2697 l. SYS_CLKR 0x08[15:0] = 0x3083 // disable ELDR clock
2698 m. SYS_ISO_CTRL 0x01[7:0] = 0x83 // isolated ELDR to PON
2699 ******************************/
2700 rtw_write16(padapter, REG_SYS_CLKR, 0x70a3); //modify to 0x70a3 by Scott.
2701 rtw_write8(padapter, REG_SYS_ISO_CTRL+1, 0x82); //modify to 0x82 by Scott.
2704 void _DisableAnalog(PADAPTER padapter, bool bWithoutHWSM)
2706 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
2713 /*****************************
2714 n. LDOA15_CTRL 0x20[7:0] = 0x04 // disable A15 power
2715 o. LDOV12D_CTRL 0x21[7:0] = 0x54 // disable digital core power
2716 r. When driver call disable, the ASIC will turn off remaining clock automatically
2717 ******************************/
2719 rtw_write8(padapter, REG_LDOA15_CTRL, 0x04);
2720 //rtw_write8(padapter, REG_LDOV12D_CTRL, 0x54);
2722 value8 = rtw_read8(padapter, REG_LDOV12D_CTRL);
2723 value8 &= (~LDV12_EN);
2724 rtw_write8(padapter, REG_LDOV12D_CTRL, value8);
2725 // RT_TRACE(COMP_INIT, DBG_LOUD, (" REG_LDOV12D_CTRL Reg0x21:0x%02x.\n",value8));
2728 /*****************************
2729 h. SPS0_CTRL 0x11[7:0] = 0x23 //enter PFM mode
2730 i. APS_FSMCO 0x04[15:0] = 0x4802 // set USB suspend
2731 ******************************/
2733 if (IS_81xxC_VENDOR_UMC_B_CUT(pHalData->VersionID))
2736 rtw_write8(padapter, REG_SPS0_CTRL, value8);
2740 //value16 |= (APDM_HOST | /*AFSM_HSUS |*/PFM_ALDN);
2741 // 2010/08/31 According to Filen description, we need to use HW to shut down 8051 automatically.
2742 // Becasue suspend operatione need the asistance of 8051 to wait for 3ms.
2743 value16 |= (APDM_HOST | AFSM_HSUS | PFM_ALDN);
2747 value16 |= (APDM_HOST | AFSM_HSUS | PFM_ALDN);
2750 rtw_write16(padapter, REG_APS_FSMCO, value16);//0x4802
2752 rtw_write8(padapter, REG_RSV_CTRL, 0x0e);
2755 //tynli_test for suspend mode.
2757 rtw_write8(padapter, 0xfe10, 0x19);
2761 // RT_TRACE(COMP_INIT, DBG_LOUD, ("======> Disable Analog Reg0x04:0x%04x.\n",value16));
2764 // HW Auto state machine
2765 s32 CardDisableHWSM(PADAPTER padapter, u8 resetMCU)
2767 int rtStatus = _SUCCESS;
2770 if (padapter->bSurpriseRemoved){
2773 //==== RF Off Sequence ====
2774 _DisableRFAFEAndResetBB(padapter);
2776 // ==== Reset digital sequence ======
2777 _ResetDigitalProcedure1(padapter, _FALSE);
2779 // ==== Pull GPIO PIN to balance level and LED control ======
2780 _DisableGPIO(padapter);
2782 // ==== Disable analog sequence ===
2783 _DisableAnalog(padapter, _FALSE);
2785 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("======> Card disable finished.\n"));
2790 // without HW Auto state machine
2791 s32 CardDisableWithoutHWSM(PADAPTER padapter)
2793 s32 rtStatus = _SUCCESS;
2796 //RT_TRACE(COMP_INIT, DBG_LOUD, ("======> Card Disable Without HWSM .\n"));
2797 if (padapter->bSurpriseRemoved) {
2801 //==== RF Off Sequence ====
2802 _DisableRFAFEAndResetBB(padapter);
2804 // ==== Reset digital sequence ======
2805 _ResetDigitalProcedure1(padapter, _TRUE);
2807 // ==== Pull GPIO PIN to balance level and LED control ======
2808 _DisableGPIO(padapter);
2810 // ==== Reset digital sequence ======
2811 _ResetDigitalProcedure2(padapter);
2813 // ==== Disable analog sequence ===
2814 _DisableAnalog(padapter, _TRUE);
2816 //RT_TRACE(COMP_INIT, DBG_LOUD, ("<====== Card Disable Without HWSM .\n"));
2827 EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
2828 // HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
2832 if(_FALSE == pEEPROM->bautoload_fail_flag)
2834 // if (IS_BOOT_FROM_EEPROM(padapter))
2835 if (_TRUE == pEEPROM->EepromOrEfuse)
2837 // Read all Content from EEPROM or EFUSE.
2838 for(i = 0; i < HWSET_MAX_SIZE; i += 2)
2840 // value16 = EF2Byte(ReadEEprom(pAdapter, (u2Byte) (i>>1)));
2841 // *((u16*)(&PROMContent[i])) = value16;
2846 // Read EFUSE real map to shadow.
2847 EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, _FALSE);
2848 memcpy((void*)PROMContent, (void*)pEEPROM->efuse_eeprom_data, HWSET_MAX_SIZE);
2853 RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("AutoLoad Fail reported from CR9346!!\n"));
2854 // pHalData->AutoloadFailFlag = _TRUE;
2855 //update to default value 0xFF
2856 if (_FALSE == pEEPROM->EepromOrEfuse)
2857 EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, _FALSE);
2858 memcpy((void*)PROMContent, (void*)pEEPROM->efuse_eeprom_data, HWSET_MAX_SIZE);
2863 Hal_EfuseParseIDCode(
2864 IN PADAPTER padapter,
2868 EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
2869 // HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
2873 // Checl 0x8129 again for making sure autoload status!!
2874 EEPROMId = le16_to_cpu(*((u16*)hwinfo));
2875 if (EEPROMId != RTL_EEPROM_ID)
2877 DBG_8723A("EEPROM ID(%#x) is invalid!!\n", EEPROMId);
2878 pEEPROM->bautoload_fail_flag = _TRUE;
2882 pEEPROM->bautoload_fail_flag = _FALSE;
2885 RT_TRACE(_module_hal_init_c_, _drv_info_, ("EEPROM ID=0x%04x\n", EEPROMId));
2892 OUT void * pOutValue
2900 pIn = (u8*)pInValue;
2901 pOut = (u8*)pOutValue;
2902 if(*pIn >= 0 && *pIn <= 63)
2908 RT_TRACE(_module_hci_hal_init_c_, _drv_err_, ("EETYPE_TX_PWR, value=%d is invalid, set to default=0x%x\n",
2909 *pIn, EEPROM_Default_TxPowerLevel));
2910 *pOut = EEPROM_Default_TxPowerLevel;
2920 Hal_ReadPowerValueFromPROM_8723A(
2921 IN PTxPowerInfo pwrInfo,
2923 IN bool AutoLoadFail
2926 u32 rfPath, eeAddr, group, rfPathMax=1;
2928 memset(pwrInfo, 0, sizeof(TxPowerInfo));
2932 for (group = 0; group < MAX_CHNL_GROUP; group++)
2934 for(rfPath = 0 ; rfPath < rfPathMax ; rfPath++)
2936 pwrInfo->CCKIndex[rfPath][group] = EEPROM_Default_TxPowerLevel;
2937 pwrInfo->HT40_1SIndex[rfPath][group] = EEPROM_Default_TxPowerLevel;
2938 pwrInfo->HT40_2SIndexDiff[rfPath][group]= EEPROM_Default_HT40_2SDiff;
2939 pwrInfo->HT20IndexDiff[rfPath][group] = EEPROM_Default_HT20_Diff;
2940 pwrInfo->OFDMIndexDiff[rfPath][group] = EEPROM_Default_LegacyHTTxPowerDiff;
2941 pwrInfo->HT40MaxOffset[rfPath][group] = EEPROM_Default_HT40_PwrMaxOffset;
2942 pwrInfo->HT20MaxOffset[rfPath][group] = EEPROM_Default_HT20_PwrMaxOffset;
2945 pwrInfo->TSSI_A[0] = EEPROM_Default_TSSI;
2949 for(rfPath = 0 ; rfPath < rfPathMax ; rfPath++)
2951 for (group = 0; group < MAX_CHNL_GROUP; group++)
2953 eeAddr = EEPROM_CCK_TX_PWR_INX_8723A + (rfPath * 3) + group;
2954 //pwrInfo->CCKIndex[rfPath][group] = PROMContent[eeAddr];
2955 Hal_EEValueCheck(EETYPE_TX_PWR, &PROMContent[eeAddr], &pwrInfo->CCKIndex[rfPath][group]);
2956 eeAddr = EEPROM_HT40_1S_TX_PWR_INX_8723A + (rfPath * 3) + group;
2957 //pwrInfo->HT40_1SIndex[rfPath][group] = PROMContent[eeAddr];
2958 Hal_EEValueCheck(EETYPE_TX_PWR, &PROMContent[eeAddr], &pwrInfo->HT40_1SIndex[rfPath][group]);
2962 for (group = 0; group < MAX_CHNL_GROUP; group++)
2964 for(rfPath = 0 ; rfPath < rfPathMax ; rfPath++)
2966 pwrInfo->HT40_2SIndexDiff[rfPath][group] = 0;
2967 pwrInfo->HT20IndexDiff[rfPath][group] =
2968 (PROMContent[EEPROM_HT20_TX_PWR_INX_DIFF_8723A + group] >> (rfPath * 4)) & 0xF;
2969 if(pwrInfo->HT20IndexDiff[rfPath][group] & BIT3) //4bit sign number to 8 bit sign number
2970 pwrInfo->HT20IndexDiff[rfPath][group] |= 0xF0;
2972 pwrInfo->OFDMIndexDiff[rfPath][group] =
2973 (PROMContent[EEPROM_OFDM_TX_PWR_INX_DIFF_8723A + group] >> (rfPath * 4)) & 0xF;
2975 pwrInfo->HT40MaxOffset[rfPath][group] =
2976 (PROMContent[EEPROM_HT40_MAX_PWR_OFFSET_8723A + group] >> (rfPath * 4)) & 0xF;
2978 pwrInfo->HT20MaxOffset[rfPath][group] =
2979 (PROMContent[EEPROM_HT20_MAX_PWR_OFFSET_8723A + group] >> (rfPath * 4)) & 0xF;
2983 pwrInfo->TSSI_A[0] = PROMContent[EEPROM_TSSI_A_8723A];
2993 if (chnl < 3) // Cjanel 1-3
2995 else if (chnl < 9) // Channel 4-9
2997 else // Channel 10-14
3004 Hal_EfuseParseTxPowerInfo_8723A(
3005 IN PADAPTER padapter,
3007 IN bool AutoLoadFail
3010 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
3011 TxPowerInfo pwrInfo;
3012 u8 rfPath, ch, group, rfPathMax=1;
3015 Hal_ReadPowerValueFromPROM_8723A(&pwrInfo, PROMContent, AutoLoadFail);
3016 for(rfPath = 0 ; rfPath < rfPathMax ; rfPath++)
3018 for(ch = 0 ; ch < CHANNEL_MAX_NUMBER ; ch++)
3020 group = Hal_GetChnlGroup(ch);
3022 pHalData->TxPwrLevelCck[rfPath][ch] = pwrInfo.CCKIndex[rfPath][group];
3023 pHalData->TxPwrLevelHT40_1S[rfPath][ch] = pwrInfo.HT40_1SIndex[rfPath][group];
3025 pHalData->TxPwrHt20Diff[rfPath][ch] = pwrInfo.HT20IndexDiff[rfPath][group];
3026 pHalData->TxPwrLegacyHtDiff[rfPath][ch] = pwrInfo.OFDMIndexDiff[rfPath][group];
3027 pHalData->PwrGroupHT20[rfPath][ch] = pwrInfo.HT20MaxOffset[rfPath][group];
3028 pHalData->PwrGroupHT40[rfPath][ch] = pwrInfo.HT40MaxOffset[rfPath][group];
3030 pwr = pwrInfo.HT40_1SIndex[rfPath][group];
3031 diff = pwrInfo.HT40_2SIndexDiff[rfPath][group];
3033 pHalData->TxPwrLevelHT40_2S[rfPath][ch] = (pwr > diff) ? (pwr - diff) : 0;
3037 for(rfPath = 0 ; rfPath < RF_PATH_MAX ; rfPath++)
3039 for(ch = 0 ; ch < CHANNEL_MAX_NUMBER ; ch++)
3041 RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
3042 ("RF(%u)-Ch(%u) [CCK / HT40_1S / HT40_2S] = [0x%x / 0x%x / 0x%x]\n",
3043 rfPath, ch, pHalData->TxPwrLevelCck[rfPath][ch],
3044 pHalData->TxPwrLevelHT40_1S[rfPath][ch],
3045 pHalData->TxPwrLevelHT40_2S[rfPath][ch]));
3049 for(ch = 0 ; ch < CHANNEL_MAX_NUMBER ; ch++)
3051 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("RF-A Ht20 to HT40 Diff[%u] = 0x%x(%d)\n", ch,
3052 pHalData->TxPwrHt20Diff[RF_PATH_A][ch], pHalData->TxPwrHt20Diff[RF_PATH_A][ch]));
3054 for(ch = 0 ; ch < CHANNEL_MAX_NUMBER ; ch++)
3056 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("RF-A Legacy to Ht40 Diff[%u] = 0x%x\n", ch, pHalData->TxPwrLegacyHtDiff[RF_PATH_A][ch]));
3058 for(ch = 0 ; ch < CHANNEL_MAX_NUMBER ; ch++)
3060 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("RF-B Ht20 to HT40 Diff[%u] = 0x%x(%d)\n", ch,
3061 pHalData->TxPwrHt20Diff[RF_PATH_B][ch], pHalData->TxPwrHt20Diff[RF_PATH_B][ch]));
3063 for(ch = 0 ; ch < CHANNEL_MAX_NUMBER ; ch++)
3065 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("RF-B Legacy to HT40 Diff[%u] = 0x%x\n", ch, pHalData->TxPwrLegacyHtDiff[RF_PATH_B][ch]));
3070 struct registry_priv *registry_par = &padapter->registrypriv;
3071 if( registry_par->regulatory_tid == 0xff){
3072 if( PROMContent[RF_OPTION1_8723A] == 0xff)
3073 pHalData->EEPROMRegulatory = 0 ;
3075 pHalData->EEPROMRegulatory = PROMContent[RF_OPTION1_8723A]&0x7; //bit0~2
3078 pHalData->EEPROMRegulatory = registry_par->regulatory_tid;
3083 pHalData->EEPROMRegulatory = 0;
3085 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("EEPROMRegulatory = 0x%x\n", pHalData->EEPROMRegulatory));
3088 pHalData->bTXPowerDataReadFromEEPORM = _TRUE;
3092 Hal_EfuseParseBTCoexistInfo_8723A(
3093 IN PADAPTER padapter,
3095 IN bool AutoLoadFail
3098 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
3104 tmpu4 = rtw_read32(padapter, REG_MULTI_FUNC_CTRL);
3105 if (tmpu4 & BT_FUNC_EN)
3106 pHalData->EEPROMBluetoothCoexist = 1;
3108 pHalData->EEPROMBluetoothCoexist = 0;
3109 pHalData->EEPROMBluetoothType = BT_RTL8723A;
3111 // The following need to be checked with newer version of
3113 tempval = hwinfo[RF_OPTION4_8723A];
3114 pHalData->EEPROMBluetoothAntNum = (tempval&0x1); // bit [0]
3115 pHalData->EEPROMBluetoothAntIsolation = ((tempval&0x10)>>4); // bit [4]
3116 pHalData->EEPROMBluetoothRadioShared = ((tempval&0x20)>>5); // bit [5]
3120 pHalData->EEPROMBluetoothCoexist = 0;
3121 pHalData->EEPROMBluetoothType = BT_RTL8723A;
3122 pHalData->EEPROMBluetoothAntNum = Ant_x2;
3123 pHalData->EEPROMBluetoothAntIsolation = 0;
3124 pHalData->EEPROMBluetoothRadioShared = BT_Radio_Shared;
3126 #ifdef CONFIG_BT_COEXIST
3127 BT_InitHalVars(padapter);
3132 Hal_EfuseParseEEPROMVer(
3133 IN PADAPTER padapter,
3135 IN bool AutoLoadFail
3138 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
3141 pHalData->EEPROMVersion = hwinfo[EEPROM_VERSION_8723A];
3143 pHalData->EEPROMVersion = 1;
3144 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("Hal_EfuseParseEEPROMVer(), EEVer = %d\n",
3145 pHalData->EEPROMVersion));
3149 rtl8723a_EfuseParseChnlPlan(
3150 IN PADAPTER padapter,
3152 IN bool AutoLoadFail
3155 padapter->mlmepriv.ChannelPlan = hal_com_get_channel_plan(
3157 , hwinfo?hwinfo[EEPROM_ChannelPlan_8723A]:0xFF
3158 , padapter->registrypriv.channel_plan
3159 , RT_CHANNEL_DOMAIN_WORLD_WIDE_13
3163 DBG_8723A("mlmepriv.ChannelPlan=0x%02x\n", padapter->mlmepriv.ChannelPlan);
3167 Hal_EfuseParseCustomerID(
3168 IN PADAPTER padapter,
3170 IN bool AutoLoadFail
3173 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
3177 pHalData->EEPROMCustomerID = hwinfo[EEPROM_CustomID_8723A];
3178 pHalData->EEPROMSubCustomerID = hwinfo[EEPROM_SubCustomID_8723A];
3182 pHalData->EEPROMCustomerID = 0;
3183 pHalData->EEPROMSubCustomerID = 0;
3185 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("EEPROM Customer ID: 0x%2x\n", pHalData->EEPROMCustomerID));
3186 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("EEPROM SubCustomer ID: 0x%02x\n", pHalData->EEPROMSubCustomerID));
3190 Hal_EfuseParseAntennaDiversity(
3191 IN PADAPTER padapter,
3193 IN bool AutoLoadFail
3196 #ifdef CONFIG_ANTENNA_DIVERSITY
3197 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
3198 struct registry_priv *registry_par = &padapter->registrypriv;
3203 // Antenna Diversity setting.
3204 if(registry_par->antdiv_cfg == 2) // 2: From Efuse
3205 pHalData->AntDivCfg = (hwinfo[RF_OPTION1_8723A]&0x18)>>3;
3207 pHalData->AntDivCfg = registry_par->antdiv_cfg ; // 0:OFF , 1:ON,
3209 if(pHalData->EEPROMBluetoothCoexist!=0 && pHalData->EEPROMBluetoothAntNum==Ant_x1)
3210 pHalData->AntDivCfg = 0;
3212 DBG_8723A("### AntDivCfg(%x) EEPROMBluetoothCoexist(%x) EEPROMBluetoothAntNum(%x)\n"
3213 ,pHalData->AntDivCfg,pHalData->EEPROMBluetoothCoexist,pHalData->EEPROMBluetoothAntNum);
3217 pHalData->AntDivCfg = 0;
3220 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("SWAS: bHwAntDiv = %x\n", pHalData->AntDivCfg));
3225 Hal_EfuseParseRateIndicationOption(
3226 IN PADAPTER padapter,
3228 IN bool AutoLoadFail
3232 PMGNT_INFO pMgntInfo = &(padapter->MgntInfo);
3234 // Rate indication option
3235 if(pMgntInfo->ShowRateMode == 0)
3239 switch((hwinfo[RF_OPTION3_8723A] & 0x0c) >> 2)
3242 pMgntInfo->bForcedShowRxRate = TRUE;
3245 case 2: // Max Rx rate
3246 pMgntInfo->bForcedShowRateStill = TRUE;
3247 pMgntInfo->bForcedShowRxRate = TRUE;
3256 pMgntInfo->bForcedShowRxRate = TRUE;
3259 else if(pMgntInfo->ShowRateMode == 2)
3261 pMgntInfo->bForcedShowRxRate = TRUE;
3263 else if(pMgntInfo->ShowRateMode == 3)
3265 pMgntInfo->bForcedShowRxRate = TRUE;
3266 pMgntInfo->bForcedShowRxRate = TRUE;
3272 Hal_EfuseParseXtal_8723A(
3279 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter);
3282 pHalData->CrystalCap = hwinfo[EEPROM_XTAL_K_8723A];
3283 if(pHalData->CrystalCap == 0xFF)
3284 pHalData->CrystalCap = EEPROM_Default_CrystalCap_8723A;
3287 pHalData->CrystalCap = EEPROM_Default_CrystalCap_8723A;
3289 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("%s: CrystalCap=0x%2x\n", __FUNCTION__, pHalData->CrystalCap));
3294 Hal_EfuseParseThermalMeter_8723A(
3300 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
3304 // ThermalMeter from EEPROM
3306 if (_FALSE == AutoloadFail)
3307 pHalData->EEPROMThermalMeter = PROMContent[EEPROM_THERMAL_METER_8723A];
3309 pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
3311 if ((pHalData->EEPROMThermalMeter == 0xff) || (_TRUE == AutoloadFail))
3313 pHalData->bAPKThermalMeterIgnore = _TRUE;
3314 pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter;
3317 DBG_8723A("%s: ThermalMeter=0x%x\n", __FUNCTION__, pHalData->EEPROMThermalMeter);
3321 Hal_InitChannelPlan(
3322 IN PADAPTER padapter
3326 PMGNT_INFO pMgntInfo = &(padapter->MgntInfo);
3327 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
3329 if((pMgntInfo->RegChannelPlan >= RT_CHANNEL_DOMAIN_MAX) || (pHalData->EEPROMChannelPlan & EEPROM_CHANNEL_PLAN_BY_HW_MASK))
3331 pMgntInfo->ChannelPlan = hal_MapChannelPlan8192C(padapter, (pHalData->EEPROMChannelPlan & (~(EEPROM_CHANNEL_PLAN_BY_HW_MASK))));
3332 pMgntInfo->bChnlPlanFromHW = (pHalData->EEPROMChannelPlan & EEPROM_CHANNEL_PLAN_BY_HW_MASK) ? _TRUE : _FALSE; // User cannot change channel plan.
3336 pMgntInfo->ChannelPlan = (RT_CHANNEL_DOMAIN)pMgntInfo->RegChannelPlan;
3339 switch(pMgntInfo->ChannelPlan)
3341 case RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN:
3343 PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(pMgntInfo);
3345 pDot11dInfo->bEnabled = TRUE;
3347 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("ReadAdapterInfo8187(): Enable dot11d when RT_CHANNEL_DOMAIN_GLOBAL_DOAMIN!\n"));
3350 default: //for MacOSX compiler warning.
3354 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("RegChannelPlan(%d) EEPROMChannelPlan(%d)", pMgntInfo->RegChannelPlan, pHalData->EEPROMChannelPlan));
3355 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("Mgnt ChannelPlan = %d\n" , pMgntInfo->ChannelPlan));
3359 void rtl8723a_cal_txdesc_chksum(struct tx_desc *ptxdesc)
3361 u16 *usPtr = (u16*)ptxdesc;
3362 u32 count = 16; // (32 bytes / 2 bytes per XOR) => 16 times
3368 ptxdesc->txdw7 &= cpu_to_le32(0xffff0000);
3370 for (index = 0; index < count; index++) {
3371 checksum ^= le16_to_cpu(*(usPtr + index));
3374 ptxdesc->txdw7 |= cpu_to_le32(checksum & 0x0000ffff);
3377 static void fill_txdesc_sectype(struct pkt_attrib *pattrib, PTXDESC ptxdesc)
3379 if ((pattrib->encrypt > 0) && !pattrib->bswenc)
3381 switch (pattrib->encrypt)
3388 ptxdesc->sectype = 1;
3391 #ifdef CONFIG_WAPI_SUPPORT
3393 ptxdesc->sectype = 2;
3397 ptxdesc->sectype = 3;
3407 static void fill_txdesc_vcs(struct pkt_attrib *pattrib, PTXDESC ptxdesc)
3409 //DBG_8723A("cvs_mode=%d\n", pattrib->vcs_mode);
3411 switch (pattrib->vcs_mode)
3418 ptxdesc->cts2self = 1;
3426 if(pattrib->vcs_mode) {
3427 ptxdesc->hw_rts_en = 1; // ENABLE HW RTS
3432 if (pattrib->bwmode & HT_CHANNEL_WIDTH_40)
3433 ptxdesc->rts_bw = 1;
3435 switch (pattrib->ch_offset)
3437 case HAL_PRIME_CHNL_OFFSET_DONT_CARE:
3438 ptxdesc->rts_sc = 0;
3441 case HAL_PRIME_CHNL_OFFSET_LOWER:
3442 ptxdesc->rts_sc = 1;
3445 case HAL_PRIME_CHNL_OFFSET_UPPER:
3446 ptxdesc->rts_sc = 2;
3450 ptxdesc->rts_sc = 3; // Duplicate
3457 static void fill_txdesc_phy(struct pkt_attrib *pattrib, PTXDESC ptxdesc)
3459 //DBG_8723A("bwmode=%d, ch_off=%d\n", pattrib->bwmode, pattrib->ch_offset);
3463 if (pattrib->bwmode & HT_CHANNEL_WIDTH_40)
3464 ptxdesc->data_bw = 1;
3466 switch (pattrib->ch_offset)
3468 case HAL_PRIME_CHNL_OFFSET_DONT_CARE:
3469 ptxdesc->data_sc = 0;
3472 case HAL_PRIME_CHNL_OFFSET_LOWER:
3473 ptxdesc->data_sc = 1;
3476 case HAL_PRIME_CHNL_OFFSET_UPPER:
3477 ptxdesc->data_sc = 2;
3481 ptxdesc->data_sc = 3; // Duplicate
3487 void rtl8723a_fill_default_txdesc(
3488 struct xmit_frame *pxmitframe,
3492 HAL_DATA_TYPE *pHalData;
3493 struct dm_priv *pdmpriv;
3494 struct mlme_ext_priv *pmlmeext;
3495 struct mlme_ext_info *pmlmeinfo;
3496 struct pkt_attrib *pattrib;
3501 padapter = pxmitframe->padapter;
3502 pHalData = GET_HAL_DATA(padapter);
3503 pdmpriv = &pHalData->dmpriv;
3504 pmlmeext = &padapter->mlmeextpriv;
3505 pmlmeinfo = &(pmlmeext->mlmext_info);
3507 pattrib = &pxmitframe->attrib;
3508 bmcst = IS_MCAST(pattrib->ra);
3510 ptxdesc = (PTXDESC)pbuf;
3512 if (pxmitframe->frame_tag == DATA_FRAMETAG)
3514 ptxdesc->macid = pattrib->mac_id; // CAM_ID(MAC_ID)
3516 if (pattrib->ampdu_en == _TRUE)
3517 ptxdesc->agg_en = 1; // AGG EN
3519 ptxdesc->bk = 1; // AGG BK
3521 ptxdesc->qsel = pattrib->qsel;
3522 ptxdesc->rate_id = pattrib->raid;
3524 fill_txdesc_sectype(pattrib, ptxdesc);
3526 ptxdesc->seq = pattrib->seqnum;
3528 if ((pattrib->ether_type != 0x888e) &&
3529 (pattrib->ether_type != 0x0806) &&
3530 (pattrib->dhcp_pkt != 1))
3532 // Non EAP & ARP & DHCP type data packet
3534 fill_txdesc_vcs(pattrib, ptxdesc);
3535 fill_txdesc_phy(pattrib, ptxdesc);
3537 ptxdesc->rtsrate = 8; // RTS Rate=24M
3538 ptxdesc->data_ratefb_lmt = 0x1F;
3539 ptxdesc->rts_ratefb_lmt = 0xF;
3541 // use REG_INIDATA_RATE_SEL value
3542 ptxdesc->datarate = pdmpriv->INIDATA_RATE[pattrib->mac_id];
3545 ptxdesc->userate = 1; // driver uses rate
3548 ptxdesc->sgi = 1; // SGI
3550 ptxdesc->datarate = 0x13; // init rate - mcs7
3555 // EAP data packet and ARP packet.
3556 // Use the 1M data rate to send the EAP/ARP packet.
3557 // This will maybe make the handshake smooth.
3559 ptxdesc->bk = 1; // AGG BK
3560 ptxdesc->userate = 1; // driver uses rate
3561 if (pmlmeinfo->preamble_mode == PREAMBLE_SHORT)
3562 ptxdesc->data_short = 1;// DATA_SHORT
3563 ptxdesc->datarate = MRateToHwRate(pmlmeext->tx_rate);
3565 #if defined(CONFIG_USB_TX_AGGREGATION) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
3566 ptxdesc->usb_txagg_num = pxmitframe->agg_num;
3569 else if (pxmitframe->frame_tag == MGNT_FRAMETAG)
3571 // RT_TRACE(_module_hal_xmit_c_, _drv_notice_, ("%s: MGNT_FRAMETAG\n", __FUNCTION__));
3573 ptxdesc->macid = pattrib->mac_id; // CAM_ID(MAC_ID)
3574 ptxdesc->qsel = pattrib->qsel;
3575 ptxdesc->rate_id = pattrib->raid; // Rate ID
3576 ptxdesc->seq = pattrib->seqnum;
3577 ptxdesc->userate = 1; // driver uses rate, 1M
3578 ptxdesc->rty_lmt_en = 1; // retry limit enable
3579 ptxdesc->data_rt_lmt = 6; // retry limit = 6
3581 #ifdef CONFIG_XMIT_ACK
3582 //CCX-TXRPT ack for xmit mgmt frames.
3583 if (pxmitframe->ack_report) {
3585 static u16 ccx_sw = 0x123;
3586 txdesc_set_ccx_sw_8723a(ptxdesc, ccx_sw);
3587 DBG_8723A("%s set ccx, sw:0x%03x\n", __func__, ccx_sw);
3588 ccx_sw = (ccx_sw+1)%0xfff;
3592 #endif //CONFIG_XMIT_ACK
3594 #ifdef CONFIG_INTEL_PROXIM
3595 if((padapter->proximity.proxim_on==_TRUE)&&(pattrib->intel_proxim==_TRUE)){
3596 DBG_8723A("\n %s pattrib->rate=%d\n",__FUNCTION__,pattrib->rate);
3597 ptxdesc->datarate = pattrib->rate;
3602 ptxdesc->datarate = MRateToHwRate(pmlmeext->tx_rate);
3605 else if (pxmitframe->frame_tag == TXAGG_FRAMETAG)
3607 RT_TRACE(_module_hal_xmit_c_, _drv_warning_, ("%s: TXAGG_FRAMETAG\n", __FUNCTION__));
3611 RT_TRACE(_module_hal_xmit_c_, _drv_warning_, ("%s: frame_tag=0x%x\n", __FUNCTION__, pxmitframe->frame_tag));
3613 ptxdesc->macid = 4; // CAM_ID(MAC_ID)
3614 ptxdesc->rate_id = 6; // Rate ID
3615 ptxdesc->seq = pattrib->seqnum;
3616 ptxdesc->userate = 1; // driver uses rate
3617 ptxdesc->datarate = MRateToHwRate(pmlmeext->tx_rate);
3620 ptxdesc->pktlen = pattrib->last_txcmdsz;
3621 ptxdesc->offset = TXDESC_SIZE + OFFSET_SZ;
3622 if (bmcst) ptxdesc->bmc = 1;
3627 // 2009.11.05. tynli_test. Suggested by SD4 Filen for FW LPS.
3628 // (1) The sequence number of each non-Qos frame / broadcast / multicast /
3629 // mgnt frame should be controled by Hw because Fw will also send null data
3630 // which we cannot control when Fw LPS enable.
3631 // --> default enable non-Qos data sequense number. 2010.06.23. by tynli.
3632 // (2) Enable HW SEQ control for beacon packet, because we use Hw beacon.
3633 // (3) Use HW Qos SEQ to control the seq num of Ext port non-Qos packets.
3634 // 2010.06.23. Added by tynli.
3635 if (!pattrib->qos_en)
3637 // Hw set sequence number
3638 ptxdesc->hwseq_en = 1; // HWSEQ_EN
3639 ptxdesc->hwseq_sel = 0; // HWSEQ_SEL
3647 * pxmitframe xmitframe
3648 * pbuf where to fill tx desc
3650 void rtl8723a_update_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf)
3652 struct tx_desc *pdesc;
3655 pdesc = (struct tx_desc*)pbuf;
3656 memset(pdesc, 0, sizeof(struct tx_desc));
3658 rtl8723a_fill_default_txdesc(pxmitframe, pbuf);
3660 pdesc->txdw0 = cpu_to_le32(pdesc->txdw0);
3661 pdesc->txdw1 = cpu_to_le32(pdesc->txdw1);
3662 pdesc->txdw2 = cpu_to_le32(pdesc->txdw2);
3663 pdesc->txdw3 = cpu_to_le32(pdesc->txdw3);
3664 pdesc->txdw4 = cpu_to_le32(pdesc->txdw4);
3665 pdesc->txdw5 = cpu_to_le32(pdesc->txdw5);
3666 pdesc->txdw6 = cpu_to_le32(pdesc->txdw6);
3667 pdesc->txdw7 = cpu_to_le32(pdesc->txdw7);
3668 #ifdef CONFIG_PCI_HCI
3669 pdesc->txdw8 = cpu_to_le32(pdesc->txdw8);
3670 pdesc->txdw9 = cpu_to_le32(pdesc->txdw9);
3671 pdesc->txdw10 = cpu_to_le32(pdesc->txdw10);
3672 pdesc->txdw11 = cpu_to_le32(pdesc->txdw11);
3673 pdesc->txdw12 = cpu_to_le32(pdesc->txdw12);
3674 pdesc->txdw13 = cpu_to_le32(pdesc->txdw13);
3675 pdesc->txdw14 = cpu_to_le32(pdesc->txdw14);
3676 pdesc->txdw15 = cpu_to_le32(pdesc->txdw15);
3679 rtl8723a_cal_txdesc_chksum(pdesc);
3683 // Description: In normal chip, we should send some packet to Hw which will be used by Fw
3684 // in FW LPS mode. The function is to fill the Tx descriptor of this packets, then
3685 // Fw can tell Hw to send these packet derectly.
3686 // Added by tynli. 2009.10.15.
3688 void rtl8723a_fill_fake_txdesc(
3695 struct tx_desc *ptxdesc;
3699 ptxdesc = (struct tx_desc*)pDesc;
3700 memset(pDesc, 0, TXDESC_SIZE);
3703 ptxdesc->txdw0 |= cpu_to_le32( OWN | FSG | LSG); //own, bFirstSeg, bLastSeg;
3705 ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE+OFFSET_SZ)<<OFFSET_SHT)&0x00ff0000); //32 bytes for TX Desc
3707 ptxdesc->txdw0 |= cpu_to_le32(BufferLen&0x0000ffff); // Buffer size + command header
3710 ptxdesc->txdw1 |= cpu_to_le32((QSLT_MGNT<<QSEL_SHT)&0x00001f00); // Fixed queue of Mgnt queue
3712 //Set NAVUSEHDR to prevent Ps-poll AId filed to be changed to error vlaue by Hw.
3715 ptxdesc->txdw1 |= cpu_to_le32(NAVUSEHDR);
3719 ptxdesc->txdw4 |= cpu_to_le32(BIT(7)); // Hw set sequence number
3720 ptxdesc->txdw3 |= cpu_to_le32((8 <<28)); //set bit3 to 1. Suugested by TimChen. 2009.12.29.
3723 if (_TRUE == IsBTQosNull)
3725 ptxdesc->txdw2 |= cpu_to_le32(BIT(23)); // BT NULL
3729 ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate
3731 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI)
3732 // USB interface drop packet if the checksum of descriptor isn't correct.
3733 // Using this checksum can let hardware recovery from packet bulk out error (e.g. Cancel URC, Bulk out error.).
3734 rtl8723a_cal_txdesc_chksum(ptxdesc);
3738 #ifdef CONFIG_CONCURRENT_MODE
3739 int reset_tsf(PADAPTER Adapter, u8 reset_port )
3741 u8 reset_cnt_before = 0, reset_cnt_after = 0, loop_cnt = 0;
3742 u32 reg_reset_tsf_cnt = (IFACE_PORT0==reset_port) ?
3743 REG_FW_RESET_TSF_CNT_0:REG_FW_RESET_TSF_CNT_1;
3745 rtw_scan_abort(Adapter->pbuddy_adapter); /* site survey will cause reset_tsf fail */
3746 reset_cnt_after = reset_cnt_before = rtw_read8(Adapter,reg_reset_tsf_cnt);
3747 rtl8723c_reset_tsf(Adapter, reset_port);
3749 while ((reset_cnt_after == reset_cnt_before ) && (loop_cnt < 10)) {
3752 reset_cnt_after = rtw_read8(Adapter, reg_reset_tsf_cnt);
3755 return(loop_cnt >= 10) ? _FAIL : _TRUE;
3759 static void hw_var_set_opmode(PADAPTER padapter, u8 variable, u8 *val)
3763 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
3766 if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_))
3768 #ifdef CONFIG_CONCURRENT_MODE
3769 if (!check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE))
3772 StopTxBeacon(padapter);
3776 val8 = DIS_TSF_UDT|EN_BCN_FUNCTION|DIS_ATIM;
3777 SetBcnCtrlReg(padapter, val8, ~val8);
3779 else if ((mode == _HW_STATE_ADHOC_) /*|| (mode == _HW_STATE_AP_)*/)
3781 ResumeTxBeacon(padapter);
3783 val8 = DIS_TSF_UDT|EN_BCN_FUNCTION|DIS_BCNQ_SUB;
3784 SetBcnCtrlReg(padapter, val8, ~val8);
3786 else if (mode == _HW_STATE_AP_)
3788 #ifdef CONFIG_BT_COEXIST
3789 // add NULL Data and BT NULL Data Packets to FW RSVD Page
3790 rtl8723a_set_BTCoex_AP_mode_FwRsvdPkt_cmd(padapter);
3793 ResumeTxBeacon(padapter);
3795 val8 = DIS_TSF_UDT|DIS_BCNQ_SUB;
3796 SetBcnCtrlReg(padapter, val8, ~val8);
3799 //rtw_write32(padapter, REG_RCR, 0x70002a8e);//CBSSID_DATA must set to 0
3800 rtw_write32(padapter, REG_RCR, 0x7000228e);//CBSSID_DATA must set to 0
3801 // enable to rx data frame
3802 rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
3803 // enable to rx ps-poll
3804 rtw_write16(padapter, REG_RXFLTMAP1, 0x0400);
3806 // Beacon Control related register for first time
3807 rtw_write8(padapter, REG_BCNDMATIM, 0x02); // 2ms
3808 rtw_write8(padapter, REG_DRVERLYINT, 0x05); // 5ms
3809 //rtw_write8(padapter, REG_BCN_MAX_ERR, 0xFF);
3810 #ifdef CONFIG_CONCURRENT_MODE
3811 if (padapter->iface_type == IFACE_PORT1)
3812 rtw_write8(padapter, REG_ATIMWND_1, 0x0a); // 10ms for port1
3816 rtw_write8(padapter, REG_ATIMWND, 0x0a); // 10ms for port0
3818 rtw_write16(padapter, REG_BCNTCFG, 0x00);
3819 rtw_write16(padapter, REG_TBTT_PROHIBIT, 0xff04);
3820 rtw_write16(padapter, REG_TSFTR_SYN_OFFSET, 0x7fff);// +32767 (~32ms)
3823 #ifdef CONFIG_CONCURRENT_MODE
3824 if (padapter->iface_type == IFACE_PORT1)
3825 rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(1));
3829 rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(0));
3832 // enable BCN Function
3833 // don't enable update TSF (due to TSF update when beacon/probe rsp are received)
3834 val8 = DIS_TSF_UDT | EN_BCN_FUNCTION | EN_TXBCN_RPT | DIS_BCNQ_SUB;
3835 SetBcnCtrlReg(padapter, val8, ~val8);
3837 // dis BCN ATIM WND of another port if it is station
3838 #ifdef CONFIG_CONCURRENT_MODE
3839 if (padapter->iface_type == IFACE_PORT1) {
3840 if(check_buddy_fwstate(padapter, WIFI_FW_NULL_STATE))
3841 rtw_write8(padapter, REG_BCN_CTRL,
3842 rtw_read8(padapter, REG_BCN_CTRL) & ~EN_BCN_FUNCTION);
3844 if(check_buddy_fwstate(padapter, WIFI_FW_NULL_STATE))
3845 rtw_write8(padapter, REG_BCN_CTRL_1,
3846 rtw_read8(padapter, REG_BCN_CTRL_1) & ~EN_BCN_FUNCTION);
3849 if (padapter->pbuddy_adapter)
3850 SetBcnCtrlReg(padapter->pbuddy_adapter, DIS_ATIM, 0);
3852 // val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
3853 // val8 |= DIS_ATIM;
3854 // rtw_write8(padapter, REG_BCN_CTRL_1, val8);
3857 #ifdef CONFIG_TSF_RESET_OFFLOAD
3858 // Reset TSF for STA+AP concurrent mode
3859 if ( check_buddy_fwstate(padapter, (WIFI_STATION_STATE|WIFI_ASOC_STATE)) ) {
3860 if (reset_tsf(padapter, padapter->iface_type) == _FALSE)
3861 DBG_8723A("ERROR! %s()-%d: Reset port%d TSF fail\n",
3862 __FUNCTION__, __LINE__,
3863 (padapter->iface_type==IFACE_PORT1)? 1 : 0);
3865 #endif // CONFIG_TSF_RESET_OFFLOAD
3868 val8 = rtw_read8(padapter, MSR);
3869 #ifdef CONFIG_CONCURRENT_MODE
3870 if (padapter->iface_type == IFACE_PORT1)
3871 val8 = (val8 & 0x3) | (mode << 2);
3875 val8 = (val8 & 0xC) | mode;
3877 rtw_write8(padapter, MSR, val8);
3880 static void hw_var_set_macaddr(PADAPTER padapter, u8 variable, u8 *val)
3885 #ifdef CONFIG_CONCURRENT_MODE
3886 if (padapter->iface_type == IFACE_PORT1)
3888 reg_macid = REG_MACID1;
3893 reg_macid = REG_MACID;
3896 for (idx = 0 ; idx < 6; idx++)
3898 rtw_write8(padapter, (reg_macid+idx), val[idx]);
3902 static void hw_var_set_bssid(PADAPTER padapter, u8 variable, u8 *val)
3907 #ifdef CONFIG_CONCURRENT_MODE
3908 if (padapter->iface_type == IFACE_PORT1)
3910 reg_bssid = REG_BSSID1;
3915 reg_bssid = REG_BSSID;
3918 for (idx = 0 ; idx < 6; idx++)
3920 rtw_write8(padapter, (reg_bssid+idx), val[idx]);
3924 static void hw_var_set_correct_tsf(PADAPTER padapter, u8 variable, u8 *val)
3928 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3929 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3932 //tsf = pmlmeext->TSFValue - ((u32)pmlmeext->TSFValue % (pmlmeinfo->bcn_interval*1024)) - 1024; //us
3933 tsf = pmlmeext->TSFValue - rtw_modular64(pmlmeext->TSFValue, (pmlmeinfo->bcn_interval*1024)) - 1024; //us
3935 if (((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) ||
3936 ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
3938 //pHalData->RegTxPause |= STOP_BCNQ;BIT(6)
3939 //rtw_write8(padapter, REG_TXPAUSE, (rtw_read8(Adapter, REG_TXPAUSE)|BIT(6)));
3940 StopTxBeacon(padapter);
3943 #ifdef CONFIG_CONCURRENT_MODE
3944 if (padapter->iface_type == IFACE_PORT1)
3946 reg_tsftr = REG_TSFTR1;
3951 reg_tsftr = REG_TSFTR;
3954 // disable related TSF function
3955 SetBcnCtrlReg(padapter, 0, EN_BCN_FUNCTION);
3957 rtw_write32(padapter, reg_tsftr, tsf);
3958 rtw_write32(padapter, reg_tsftr+4, tsf>>32);
3960 #ifdef CONFIG_CONCURRENT_MODE
3962 // Update buddy port's TSF if it is SoftAP for beacon TX issue!
3963 if ( (pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE
3964 && check_buddy_fwstate(padapter, WIFI_AP_STATE)
3966 //disable related TSF function
3967 if (padapter->pbuddy_adapter)
3968 SetBcnCtrlReg(padapter->pbuddy_adapter, 0, EN_BCN_FUNCTION);
3969 if (padapter->iface_type == IFACE_PORT1)
3971 reg_tsftr = REG_TSFTR;
3975 reg_tsftr = REG_TSFTR1;
3978 rtw_write32(padapter, reg_tsftr, tsf);
3979 rtw_write32(padapter, reg_tsftr+4, tsf>>32);
3981 //enable related TSF function
3982 if (padapter->pbuddy_adapter)
3983 SetBcnCtrlReg(padapter->pbuddy_adapter, EN_BCN_FUNCTION,0);
3986 //enable related TSF function
3987 SetBcnCtrlReg(padapter, EN_BCN_FUNCTION, 0);
3989 #ifdef CONFIG_TSF_RESET_OFFLOAD
3990 // Reset TSF for STA+AP concurrent mode
3991 if ( (pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE
3992 && check_buddy_fwstate(padapter, WIFI_AP_STATE) ) {
3993 if (padapter->iface_type == IFACE_PORT1) {
3994 if (reset_tsf(padapter, IFACE_PORT0) == _FALSE)
3995 DBG_8723A("ERROR! %s()-%d: Reset port0 TSF fail\n",
3996 __FUNCTION__, __LINE__);
3998 if (reset_tsf(padapter, IFACE_PORT1) == _FALSE)
3999 DBG_8723A("ERROR! %s()-%d: Reset port1 TSF fail\n",
4000 __FUNCTION__, __LINE__);
4003 #endif // CONFIG_TSF_RESET_OFFLOAD
4005 if (((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) ||
4006 ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
4008 //pHalData->RegTxPause &= (~STOP_BCNQ);
4009 //rtw_write8(padapter, REG_TXPAUSE, (rtw_read8(padapter, REG_TXPAUSE)&(~BIT(6))));
4010 ResumeTxBeacon(padapter);
4014 static void hw_var_set_mlme_disconnect(PADAPTER padapter, u8 variable, u8 *val)
4016 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
4017 #ifdef CONFIG_CONCURRENT_MODE
4018 if (check_buddy_mlmeinfo_state(padapter, _HW_STATE_NOLINK_))
4021 // Set RCR to not to receive data frame when NO LINK state
4022 //rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR) & ~RCR_ADF);
4023 // reject all data frames
4024 rtw_write16(padapter, REG_RXFLTMAP2, 0);
4027 #ifdef CONFIG_CONCURRENT_MODE
4028 if (padapter->iface_type == IFACE_PORT1)
4031 rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(1));
4033 // disable update TSF1
4034 SetBcnCtrlReg(padapter, DIS_TSF_UDT, 0);
4040 rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(0));
4042 // disable update TSF
4043 SetBcnCtrlReg(padapter, DIS_TSF_UDT, 0);
4047 #ifdef CONFIG_CONCURRENT_MODE
4048 static void hw_var_set_mlme_sitesurvey(PADAPTER padapter, u8 variable, u8 *val)
4050 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
4052 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4053 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
4057 if (*val)//under sitesurvey
4059 // config RCR to receive different BSSID & not to receive data frame
4060 v32 = rtw_read32(padapter, REG_RCR);
4061 v32 &= ~(RCR_CBSSID_BCN);
4062 rtw_write32(padapter, REG_RCR, v32);
4064 // disable update TSF
4065 if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE)
4066 SetBcnCtrlReg(padapter, DIS_TSF_UDT, 0);
4068 if (check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) &&
4069 (check_buddy_fwstate(padapter, _FW_LINKED) == _TRUE))
4071 StopTxBeacon(padapter);
4074 else//sitesurvey done
4076 // enable to rx data frame
4077 //write32(padapter, REG_RCR, read32(padapter, REG_RCR)|RCR_ADF);
4078 rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
4080 // enable update TSF
4081 SetBcnCtrlReg(padapter, 0, DIS_TSF_UDT);
4083 v32 = rtw_read32(padapter, REG_RCR);
4084 v32 |= RCR_CBSSID_BCN;
4085 rtw_write32(padapter, REG_RCR, v32);
4087 if (check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) &&
4088 (check_buddy_fwstate(padapter, _FW_LINKED) == _TRUE))
4090 ResumeTxBeacon(padapter);
4092 // reset TSF 1/2 after ResumeTxBeacon
4093 if (pbuddy_adapter->iface_type == IFACE_PORT1)
4094 rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(1));
4096 rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(0));
4104 static void hw_var_set_mlme_join(PADAPTER padapter, u8 variable, u8 *val)
4106 u8 RetryLimit = 0x30;
4109 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
4110 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
4112 if (type == 0) // prepare to join
4116 #ifdef CONFIG_CONCURRENT_MODE
4117 if (check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) &&
4118 (check_buddy_fwstate(padapter, _FW_LINKED) == _TRUE))
4120 StopTxBeacon(padapter);
4124 // enable to rx data frame.Accept all data frame
4125 //rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR)|RCR_ADF);
4126 rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
4128 v32 = rtw_read32(padapter, REG_RCR);
4129 #ifdef CONFIG_CONCURRENT_MODE
4130 if (check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE))
4131 v32 |= RCR_CBSSID_BCN;
4135 v32 |= RCR_CBSSID_DATA | RCR_CBSSID_BCN;
4137 rtw_write32(padapter, REG_RCR, v32);
4139 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
4140 RetryLimit = (pHalData->CustomerID == RT_CID_CCX) ? 7 : 48;
4144 else if (type == 1) // joinbss_event callback when join res < 0
4146 #ifdef CONFIG_CONCURRENT_MODE
4147 if (check_buddy_mlmeinfo_state(padapter, _HW_STATE_NOLINK_))
4148 rtw_write16(padapter, REG_RXFLTMAP2, 0);
4150 if (check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) &&
4151 (check_buddy_fwstate(padapter, _FW_LINKED) == _TRUE))
4153 ResumeTxBeacon(padapter);
4155 // reset TSF 1/2 after ResumeTxBeacon
4156 rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(1)|BIT(0));
4159 // config RCR to receive different BSSID & not to receive data frame during linking
4160 //v32 = rtw_read32(padapter, REG_RCR);
4161 //v32 &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);//| RCR_ADF
4162 //rtw_write32(padapter, REG_RCR, v32);
4163 rtw_write16(padapter, REG_RXFLTMAP2, 0);
4166 else if (type == 2) // sta add event callback
4168 // enable update TSF
4169 SetBcnCtrlReg(padapter, 0, DIS_TSF_UDT);
4171 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE) == _TRUE)
4173 // fixed beacon issue for 8191su...........
4174 rtw_write8(padapter, 0x542, 0x02);
4178 #ifdef CONFIG_CONCURRENT_MODE
4179 if (check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) &&
4180 (check_buddy_fwstate(padapter, _FW_LINKED) == _TRUE))
4182 ResumeTxBeacon(padapter);
4184 // reset TSF 1/2 after ResumeTxBeacon
4185 rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(1)|BIT(0));
4190 rtw_write16(padapter, REG_RL, RetryLimit << RETRY_LIMIT_SHORT_SHIFT | RetryLimit << RETRY_LIMIT_LONG_SHIFT);
4193 void SetHwReg8723A(PADAPTER padapter, u8 variable, u8 *val)
4195 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
4201 case HW_VAR_MEDIA_STATUS:
4205 val8 = rtw_read8(padapter, MSR) & 0x0c;
4207 rtw_write8(padapter, MSR, val8);
4211 case HW_VAR_MEDIA_STATUS1:
4215 val8 = rtw_read8(padapter, MSR) & 0x03;
4217 rtw_write8(padapter, MSR, val8);
4221 case HW_VAR_SET_OPMODE:
4222 hw_var_set_opmode(padapter, variable, val);
4225 case HW_VAR_MAC_ADDR:
4226 hw_var_set_macaddr(padapter, variable, val);
4230 hw_var_set_bssid(padapter, variable, val);
4233 case HW_VAR_BASIC_RATE:
4238 // 2007.01.16, by Emily
4239 // Select RRSR (in Legacy-OFDM and CCK)
4240 // For 8190, we select only 24M, 12M, 6M, 11M, 5.5M, 2M, and 1M from the Basic rate.
4241 // We do not use other rates.
4242 HalSetBrateCfg(padapter, val, &BrateCfg);
4244 //2011.03.30 add by Luke Lee
4245 //CCK 2M ACK should be disabled for some BCM and Atheros AP IOT
4246 //because CCK 2M has poor TXEVM
4247 //CCK 5.5M & 11M ACK should be enabled for better performance
4249 pHalData->BasicRateSet = BrateCfg = (BrateCfg |0xd) & 0x15d;
4250 BrateCfg |= 0x01; // default enable 1M ACK rate
4251 DBG_8723A("HW_VAR_BASIC_RATE: BrateCfg(%#x)\n", BrateCfg);
4253 // Set RRSR rate table.
4254 rtw_write8(padapter, REG_RRSR, BrateCfg&0xff);
4255 rtw_write8(padapter, REG_RRSR+1, (BrateCfg>>8)&0xff);
4256 rtw_write8(padapter, REG_RRSR+2, rtw_read8(padapter, REG_RRSR+2)&0xf0);
4258 // Set RTS initial rate
4259 while (BrateCfg > 0x1)
4261 BrateCfg = (BrateCfg >> 1);
4265 rtw_write8(padapter, REG_INIRTS_RATE_SEL, RateIndex);
4269 case HW_VAR_TXPAUSE:
4270 rtw_write8(padapter, REG_TXPAUSE, *val);
4273 case HW_VAR_BCN_FUNC:
4275 SetBcnCtrlReg(padapter, EN_BCN_FUNCTION | EN_TXBCN_RPT, 0);
4277 SetBcnCtrlReg(padapter, 0, EN_BCN_FUNCTION | EN_TXBCN_RPT);
4280 case HW_VAR_CORRECT_TSF:
4281 hw_var_set_correct_tsf(padapter, variable, val);
4284 case HW_VAR_CHECK_BSSID:
4287 val32 = rtw_read32(padapter, REG_RCR);
4289 val32 |= RCR_CBSSID_DATA|RCR_CBSSID_BCN;
4291 val32 &= ~(RCR_CBSSID_DATA|RCR_CBSSID_BCN);
4292 rtw_write32(padapter, REG_RCR, val32);
4296 case HW_VAR_MLME_DISCONNECT:
4297 hw_var_set_mlme_disconnect(padapter, variable, val);
4300 case HW_VAR_MLME_SITESURVEY:
4301 #ifdef CONFIG_CONCURRENT_MODE
4302 hw_var_set_mlme_sitesurvey(padapter, variable, val);
4304 if (*val)//under sitesurvey
4308 // config RCR to receive different BSSID & not to receive data frame
4309 v32 = rtw_read32(padapter, REG_RCR);
4310 v32 &= ~(RCR_CBSSID_BCN);
4311 rtw_write32(padapter, REG_RCR, v32);
4312 // reject all data frame
4313 rtw_write16(padapter, REG_RXFLTMAP2, 0);
4315 // disable update TSF
4316 SetBcnCtrlReg(padapter, DIS_TSF_UDT, 0);
4318 else//sitesurvey done
4320 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4321 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4324 if ((is_client_associated_to_ap(padapter) == _TRUE) ||
4325 ((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) ||
4326 ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
4328 // enable to rx data frame
4330 v32 = rtw_read32(padapter, REG_RCR);
4332 rtw_write32(padapter, REG_RCR, v32);
4334 rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
4337 // enable update TSF
4338 SetBcnCtrlReg(padapter, 0, DIS_TSF_UDT);
4341 v32 = rtw_read32(padapter, REG_RCR);
4342 v32 |= RCR_CBSSID_BCN;
4343 rtw_write32(padapter, REG_RCR, v32);
4347 #ifdef CONFIG_BT_COEXIST
4348 BT_WifiScanNotify(padapter, *val?_TRUE:_FALSE);
4352 case HW_VAR_MLME_JOIN:
4353 hw_var_set_mlme_join(padapter, variable, val);
4355 #ifdef CONFIG_BT_COEXIST
4360 BT_WifiAssociateNotify(padapter, _TRUE);
4363 // joinbss_event callback when join res < 0
4364 BT_WifiAssociateNotify(padapter, _FALSE);
4367 // sta add event callback
4368 // BT_WifiMediaStatusNotify(padapter, RT_MEDIA_CONNECT);
4374 case HW_VAR_ON_RCR_AM:
4375 rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR)|RCR_AM);
4376 DBG_8723A("%s, %d, RCR= %x \n", __FUNCTION__,__LINE__, rtw_read32(padapter, REG_RCR));
4379 case HW_VAR_OFF_RCR_AM:
4380 rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR)& (~RCR_AM));
4381 DBG_8723A("%s, %d, RCR= %x \n", __FUNCTION__,__LINE__, rtw_read32(padapter, REG_RCR));
4384 case HW_VAR_BEACON_INTERVAL:
4385 rtw_write16(padapter, REG_BCN_INTERVAL, *((u16*)val));
4388 case HW_VAR_SLOT_TIME:
4390 u8 u1bAIFS, aSifsTime;
4391 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
4392 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
4394 rtw_write8(padapter, REG_SLOT, *val);
4396 if (pmlmeinfo->WMM_enable == 0)
4398 if (pmlmeext->cur_wireless_mode == WIRELESS_11B)
4403 u1bAIFS = aSifsTime + (2 * pmlmeinfo->slotTime);
4405 // <Roger_EXP> Temporary removed, 2008.06.20.
4406 rtw_write8(padapter, REG_EDCA_VO_PARAM, u1bAIFS);
4407 rtw_write8(padapter, REG_EDCA_VI_PARAM, u1bAIFS);
4408 rtw_write8(padapter, REG_EDCA_BE_PARAM, u1bAIFS);
4409 rtw_write8(padapter, REG_EDCA_BK_PARAM, u1bAIFS);
4414 case HW_VAR_RESP_SIFS:
4416 // SIFS for OFDM Data ACK
4417 rtw_write8(padapter, REG_SIFS_CTX+1, val[0]);
4418 // SIFS for OFDM consecutive tx like CTS data!
4419 rtw_write8(padapter, REG_SIFS_TRX+1, val[1]);
4421 rtw_write8(padapter, REG_SPEC_SIFS+1, val[0]);
4422 rtw_write8(padapter, REG_MAC_SPEC_SIFS+1, val[0]);
4424 // 20100719 Joseph: Revise SIFS setting due to Hardware register definition change.
4425 rtw_write8(padapter, REG_R2T_SIFS+1, val[0]);
4426 rtw_write8(padapter, REG_T2T_SIFS+1, val[0]);
4429 //SIFS_Timer = 0x0a0a0808;
4431 rtw_write8(padapter, REG_R2T_SIFS, val[0]); // SIFS_T2T_CCK (0x08)
4432 rtw_write8(padapter, REG_R2T_SIFS+1, val[1]); //SIFS_R2T_CCK(0x08)
4433 //RESP_SIFS for OFDM
4434 rtw_write8(padapter, REG_T2T_SIFS, val[2]); //SIFS_T2T_OFDM (0x0a)
4435 rtw_write8(padapter, REG_T2T_SIFS+1, val[3]); //SIFS_R2T_OFDM(0x0a)
4439 case HW_VAR_ACK_PREAMBLE:
4442 u8 bShortPreamble = *val;
4444 // Joseph marked out for Netgear 3500 TKIP channel 7 issue.(Temporarily)
4445 regTmp = (pHalData->nCur40MhzPrimeSC)<<5;
4447 if (bShortPreamble) regTmp |= 0x80;
4448 rtw_write8(padapter, REG_RRSR+2, regTmp);
4452 case HW_VAR_SEC_CFG:
4453 #ifdef CONFIG_CONCURRENT_MODE
4454 rtw_write8(padapter, REG_SECCFG, 0x0c|BIT(5));// enable tx enc and rx dec engine, and no key search for MC/BC
4456 rtw_write8(padapter, REG_SECCFG, *val);
4460 case HW_VAR_DM_FLAG:
4461 pHalData->odmpriv.SupportAbility = *((u32*)val);
4464 case HW_VAR_DM_FUNC_OP:
4465 if (*val) // save dm flag
4466 pHalData->odmpriv.BK_SupportAbility = pHalData->odmpriv.SupportAbility;
4467 else // restore dm flag
4468 pHalData->odmpriv.SupportAbility = pHalData->odmpriv.BK_SupportAbility;
4471 case HW_VAR_DM_FUNC_SET:
4472 if (*((u32*)val) == DYNAMIC_ALL_FUNC_ENABLE) {
4473 pHalData->dmpriv.DMFlag = pHalData->dmpriv.InitDMFlag;
4474 pHalData->odmpriv.SupportAbility = pHalData->dmpriv.InitODMFlag;
4476 pHalData->odmpriv.SupportAbility |= *((u32*)val);
4480 case HW_VAR_DM_FUNC_CLR:
4481 pHalData->odmpriv.SupportAbility &= *((u32*)val);
4484 case HW_VAR_CAM_EMPTY_ENTRY:
4490 u32 ulEncAlgo = CAM_AES;
4492 for (i=0; i<CAM_CONTENT_COUNT; i++)
4494 // filled id in CAM config 2 byte
4497 ulContent |= (ucIndex & 0x03) | ((u16)(ulEncAlgo)<<2);
4498 //ulContent |= CAM_VALID;
4504 // polling bit, and No Write enable, and address
4505 ulCommand = CAM_CONTENT_COUNT*ucIndex+i;
4506 ulCommand = ulCommand | CAM_POLLINIG | CAM_WRITE;
4507 // write content 0 is equall to mark invalid
4508 rtw_write32(padapter, WCAMI, ulContent); //delay_ms(40);
4509 //RT_TRACE(COMP_SEC, DBG_LOUD, ("CAM_empty_entry(): WRITE A4: %lx \n",ulContent));
4510 rtw_write32(padapter, RWCAM, ulCommand); //delay_ms(40);
4511 //RT_TRACE(COMP_SEC, DBG_LOUD, ("CAM_empty_entry(): WRITE A0: %lx \n",ulCommand));
4516 case HW_VAR_CAM_INVALID_ALL:
4517 rtw_write32(padapter, RWCAM, BIT(31)|BIT(30));
4520 case HW_VAR_CAM_WRITE:
4523 u32 *cam_val = (u32*)val;
4525 rtw_write32(padapter, WCAMI, cam_val[0]);
4527 cmd = CAM_POLLINIG | CAM_WRITE | cam_val[1];
4528 rtw_write32(padapter, RWCAM, cmd);
4532 case HW_VAR_AC_PARAM_VO:
4533 rtw_write32(padapter, REG_EDCA_VO_PARAM, *((u32*)val));
4536 case HW_VAR_AC_PARAM_VI:
4537 rtw_write32(padapter, REG_EDCA_VI_PARAM, *((u32*)val));
4540 case HW_VAR_AC_PARAM_BE:
4541 pHalData->AcParam_BE = ((u32*)(val))[0];
4542 rtw_write32(padapter, REG_EDCA_BE_PARAM, *((u32*)val));
4545 case HW_VAR_AC_PARAM_BK:
4546 rtw_write32(padapter, REG_EDCA_BK_PARAM, *((u32*)val));
4549 case HW_VAR_ACM_CTRL:
4551 u8 ctrl = *((u8*)val);
4556 hwctrl |= AcmHw_HwEn;
4558 if (ctrl & BIT(1)) // BE
4559 hwctrl |= AcmHw_BeqEn;
4561 if (ctrl & BIT(2)) // VI
4562 hwctrl |= AcmHw_ViqEn;
4564 if (ctrl & BIT(3)) // VO
4565 hwctrl |= AcmHw_VoqEn;
4568 DBG_8723A("[HW_VAR_ACM_CTRL] Write 0x%02X\n", hwctrl);
4569 rtw_write8(padapter, REG_ACMHWCTRL, hwctrl);
4573 case HW_VAR_AMPDU_MIN_SPACE:
4578 MinSpacingToSet = *val;
4579 if (MinSpacingToSet <= 7)
4581 switch (padapter->securitypriv.dot11PrivacyAlgrthm)
4599 if (MinSpacingToSet < SecMinSpace)
4600 MinSpacingToSet = SecMinSpace;
4602 //RT_TRACE(COMP_MLME, DBG_LOUD, ("Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", padapter->MgntInfo.MinSpaceCfg));
4603 MinSpacingToSet |= rtw_read8(padapter, REG_AMPDU_MIN_SPACE) & 0xf8;
4604 rtw_write8(padapter, REG_AMPDU_MIN_SPACE, MinSpacingToSet);
4609 case HW_VAR_AMPDU_FACTOR:
4611 u8 RegToSet_Normal[4] = {0x41,0xa8,0x72, 0xb9};
4617 pRegToSet = RegToSet_Normal; // 0xb972a841;
4618 #ifdef CONFIG_BT_COEXIST
4619 if ((BT_IsBtDisabled(padapter) == _FALSE) &&
4620 (BT_1Ant(padapter) == _TRUE))
4625 #endif // CONFIG_BT_COEXIST
4631 if (FactorToSet <= 3)
4633 FactorToSet = (1 << (FactorToSet + 2));
4634 if (FactorToSet > MaxAggNum)
4635 FactorToSet = MaxAggNum;
4637 for (index=0; index<4; index++)
4639 if ((pRegToSet[index] & 0xf0) > (FactorToSet << 4))
4640 pRegToSet[index] = (pRegToSet[index] & 0x0f) | (FactorToSet << 4);
4642 if ((pRegToSet[index] & 0x0f) > FactorToSet)
4643 pRegToSet[index] = (pRegToSet[index] & 0xf0) | FactorToSet;
4645 rtw_write8(padapter, REG_AGGLEN_LMT+index, pRegToSet[index]);
4648 //RT_TRACE(COMP_MLME, DBG_LOUD, ("Set HW_VAR_AMPDU_FACTOR: %#x\n", FactorToSet));
4653 case HW_VAR_RXDMA_AGG_PG_TH:
4654 rtw_write8(padapter, REG_RXDMA_AGG_PG_TH, *val);
4657 case HW_VAR_H2C_FW_PWRMODE:
4661 // Forece leave RF low power mode for 1T1R to prevent conficting setting in Fw power
4662 // saving sequence. 2010.06.07. Added by tynli. Suggested by SD3 yschang.
4663 if ((psmode != PS_MODE_ACTIVE) && (!IS_92C_SERIAL(pHalData->VersionID)))
4665 ODM_RF_Saving(&pHalData->odmpriv, _TRUE);
4667 rtl8723a_set_FwPwrMode_cmd(padapter, psmode);
4671 case HW_VAR_H2C_FW_JOINBSSRPT:
4672 rtl8723a_set_FwJoinBssReport_cmd(padapter, *val);
4675 #ifdef CONFIG_P2P_PS
4676 case HW_VAR_H2C_FW_P2P_PS_OFFLOAD:
4677 rtl8192c_set_p2p_ps_offload_cmd(padapter, *val);
4679 #endif //CONFIG_P2P_PS
4681 case HW_VAR_INITIAL_GAIN:
4683 DIG_T *pDigTable = &pHalData->odmpriv.DM_DigTable;
4684 u32 rx_gain = *(u32*)val;
4686 if (rx_gain == 0xff) {//restore rx gain
4687 ODM_Write_DIG(&pHalData->odmpriv, pDigTable->BackupIGValue);
4689 pDigTable->BackupIGValue = pDigTable->CurIGValue;
4690 ODM_Write_DIG(&pHalData->odmpriv, rx_gain);
4695 #ifdef CONFIG_SW_ANTENNA_DIVERSITY
4696 case HW_VAR_ANTENNA_DIVERSITY_LINK:
4697 //SwAntDivRestAfterLink8192C(padapter);
4698 ODM_SwAntDivRestAfterLink(&pHalData->odmpriv);
4701 case HW_VAR_ANTENNA_DIVERSITY_SELECT:
4703 u8 Optimum_antenna = *val;
4705 //DBG_8723A("==> HW_VAR_ANTENNA_DIVERSITY_SELECT , Ant_(%s)\n",(Optimum_antenna==2)?"A":"B");
4707 //PHY_SetBBReg(padapter, rFPGA0_XA_RFInterfaceOE, 0x300, Optimum_antenna);
4708 ODM_SetAntenna(&pHalData->odmpriv, Optimum_antenna);
4713 case HW_VAR_EFUSE_USAGE:
4714 pHalData->EfuseUsedPercentage = *val;
4717 case HW_VAR_EFUSE_BYTES:
4718 pHalData->EfuseUsedBytes = *((u16*)val);
4721 case HW_VAR_EFUSE_BT_USAGE:
4722 #ifdef HAL_EFUSE_MEMORY
4723 pHalData->EfuseHal.BTEfuseUsedPercentage = *val;
4727 case HW_VAR_EFUSE_BT_BYTES:
4728 #ifdef HAL_EFUSE_MEMORY
4729 pHalData->EfuseHal.BTEfuseUsedBytes = *((u16*)val);
4731 BTEfuseUsedBytes = *((u16*)val);
4735 case HW_VAR_FIFO_CLEARN_UP:
4737 #define RW_RELEASE_EN BIT(18)
4738 #define RXDMA_IDLE BIT(17)
4740 struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
4744 rtw_write8(padapter, REG_TXPAUSE, 0xff);
4747 padapter->xmitpriv.nqos_ssn = rtw_read16(padapter, REG_NQOS_SEQ);
4749 if (pwrpriv->bkeepfwalive != _TRUE)
4754 v32 = rtw_read32(padapter, REG_RXPKT_NUM);
4755 v32 |= RW_RELEASE_EN;
4756 rtw_write32(padapter, REG_RXPKT_NUM, v32);
4758 v32 = rtw_read32(padapter, REG_RXPKT_NUM) & RXDMA_IDLE;
4762 DBG_8723A("Stop RX DMA failed......\n");
4766 rtw_write16(padapter, REG_RQPN_NPQ, 0);
4767 rtw_write32(padapter, REG_RQPN, 0x80000000);
4773 case HW_VAR_CHECK_TXBUF:
4774 #ifdef CONFIG_CONCURRENT_MODE
4778 u8 RetryLimit = 0x01;
4780 //rtw_write16(padapter, REG_RL,0x0101);
4781 v16 = RetryLimit << RETRY_LIMIT_SHORT_SHIFT | RetryLimit << RETRY_LIMIT_LONG_SHIFT;
4782 rtw_write16(padapter, REG_RL, v16);
4784 for (i=0; i<1000; i++)
4786 if (rtw_read32(padapter, 0x200) != rtw_read32(padapter, 0x204))
4788 //DBG_8723A("packet in tx packet buffer - 0x204=%x, 0x200=%x (%d)\n", rtw_read32(padapter, 0x204), rtw_read32(padapter, 0x200), i);
4793 DBG_8723A("no packet in tx packet buffer (%d)\n", i);
4799 v16 = RetryLimit << RETRY_LIMIT_SHORT_SHIFT | RetryLimit << RETRY_LIMIT_LONG_SHIFT;
4800 rtw_write16(padapter, REG_RL, v16);
4805 case HW_VAR_APFM_ON_MAC:
4806 pHalData->bMacPwrCtrlOn = *val;
4807 DBG_8723A("%s: bMacPwrCtrlOn=%d\n", __func__, pHalData->bMacPwrCtrlOn);
4810 case HW_VAR_NAV_UPPER:
4812 u32 usNavUpper = *((u32*)val);
4814 if (usNavUpper > HAL_8723A_NAV_UPPER_UNIT * 0xFF)
4816 RT_TRACE(_module_hal_init_c_, _drv_notice_, ("The setting value (0x%08X us) of NAV_UPPER is larger than (%d * 0xFF)!!!\n", usNavUpper, HAL_8723A_NAV_UPPER_UNIT));
4820 // The value of ((usNavUpper + HAL_8723A_NAV_UPPER_UNIT - 1) / HAL_8723A_NAV_UPPER_UNIT)
4821 // is getting the upper integer.
4822 usNavUpper = (usNavUpper + HAL_8723A_NAV_UPPER_UNIT - 1) / HAL_8723A_NAV_UPPER_UNIT;
4823 rtw_write8(padapter, REG_NAV_UPPER, (u8)usNavUpper);
4827 case HW_VAR_BCN_VALID:
4828 //BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2, write 1 to clear, Clear by sw
4829 rtw_write8(padapter, REG_TDECTRL+2, rtw_read8(padapter, REG_TDECTRL+2) | BIT0);
4839 void GetHwReg8723A(PADAPTER padapter, u8 variable, u8 *val)
4841 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
4846 case HW_VAR_BASIC_RATE:
4847 *((u16*)val) = pHalData->BasicRateSet;
4850 case HW_VAR_TXPAUSE:
4851 *val = rtw_read8(padapter, REG_TXPAUSE);
4854 case HW_VAR_BCN_VALID:
4855 //BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2
4856 val[0] = (BIT0 & rtw_read8(padapter, REG_TDECTRL+2))?_TRUE:_FALSE;
4859 case HW_VAR_RF_TYPE:
4860 *val = pHalData->rf_type;
4863 case HW_VAR_DM_FLAG:
4865 PDM_ODM_T podmpriv = &pHalData->odmpriv;
4866 *((u32*)val) = podmpriv->SupportAbility;
4870 case HW_VAR_FWLPS_RF_ON:
4872 // When we halt NIC, we should check if FW LPS is leave.
4875 if ((padapter->bSurpriseRemoved == _TRUE) ||
4876 (padapter->pwrctrlpriv.rf_pwrstate == rf_off))
4878 // If it is in HW/SW Radio OFF or IPS state, we do not check Fw LPS Leave,
4879 // because Fw is unload.
4884 valRCR = rtw_read32(padapter, REG_RCR);
4885 valRCR &= 0x00070000;
4894 #ifdef CONFIG_ANTENNA_DIVERSITY
4895 case HW_VAR_CURRENT_ANTENNA:
4896 *val = pHalData->CurAntenna;
4900 case HW_VAR_EFUSE_USAGE:
4901 *val = pHalData->EfuseUsedPercentage;
4904 case HW_VAR_EFUSE_BYTES:
4905 *((u16*)val) = pHalData->EfuseUsedBytes;
4908 case HW_VAR_EFUSE_BT_USAGE:
4909 #ifdef HAL_EFUSE_MEMORY
4910 *val = pHalData->EfuseHal.BTEfuseUsedPercentage;
4914 case HW_VAR_EFUSE_BT_BYTES:
4915 #ifdef HAL_EFUSE_MEMORY
4916 *((u16*)val) = pHalData->EfuseHal.BTEfuseUsedBytes;
4918 *((u16*)val) = BTEfuseUsedBytes;
4922 case HW_VAR_APFM_ON_MAC:
4923 *val = pHalData->bMacPwrCtrlOn;
4925 case HW_VAR_CHK_HI_QUEUE_EMPTY:
4926 *val = ((rtw_read32(padapter, REG_HGQ_INFORMATION)&0x0000ff00)==0) ? _TRUE:_FALSE;
4931 #ifdef CONFIG_BT_COEXIST
4933 void rtl8723a_SingleDualAntennaDetection(PADAPTER padapter)
4935 PHAL_DATA_TYPE pHalData;
4937 pSWAT_T pDM_SWAT_Table;
4942 pHalData = GET_HAL_DATA(padapter);
4943 pDM_Odm = &pHalData->odmpriv;
4944 pDM_SWAT_Table= &pDM_Odm->DM_SWAT_Table;
4947 // <Roger_Notes> RTL8723A Single and Dual antenna dynamic detection mechanism when RF power state is on.
4948 // We should take power tracking, IQK, LCK, RCK RF read/write operation into consideration.
4951 if (!pHalData->bAntennaDetected) {
4952 u8 btAntNum = BT_GetPGAntNum(padapter);
4954 // Set default antenna B status
4955 if (btAntNum == Ant_x2)
4956 pDM_SWAT_Table->ANTB_ON = _TRUE;
4957 else if (btAntNum == Ant_x1)
4958 pDM_SWAT_Table->ANTB_ON = _FALSE;
4960 pDM_SWAT_Table->ANTB_ON = _TRUE;
4962 if (pHalData->CustomerID != RT_CID_TOSHIBA )
4964 for (i=0; i<MAX_ANTENNA_DETECTION_CNT; i++)
4966 if (ODM_SingleDualAntennaDetection(&pHalData->odmpriv, ANTTESTALL) == _TRUE)
4970 // Set default antenna number for BT coexistence
4971 if (btAntNum == Ant_x2)
4972 BT_SetBtCoexCurrAntNum(padapter, pDM_SWAT_Table->ANTB_ON ? 2 : 1);
4974 pHalData->bAntennaDetected = _TRUE;
4977 #endif // CONFIG_BT_COEXIST
4979 void rtl8723a_clone_haldata(_adapter* dst_adapter, _adapter* src_adapter)
4981 #ifdef CONFIG_SDIO_HCI
4982 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(dst_adapter);
4983 //_thread_hdl_ SdioXmitThread;
4984 _sema temp_SdioXmitSema;
4985 _sema temp_SdioXmitTerminateSema;
4986 //u8 SdioTxFIFOFreePage[SDIO_TX_FREE_PG_QUEUE];
4987 _lock temp_SdioTxFIFOFreePageLock;
4989 memcpy(&temp_SdioXmitSema, &(pHalData->SdioXmitSema), sizeof(_sema));
4990 memcpy(&temp_SdioXmitTerminateSema, &(pHalData->SdioXmitTerminateSema), sizeof(_sema));
4991 memcpy(&temp_SdioTxFIFOFreePageLock, &(pHalData->SdioTxFIFOFreePageLock), sizeof(_lock));
4993 memcpy(dst_adapter->HalData, src_adapter->HalData, dst_adapter->hal_data_sz);
4995 memcpy(&(pHalData->SdioXmitSema), &temp_SdioXmitSema, sizeof(_sema));
4996 memcpy(&(pHalData->SdioXmitTerminateSema), &temp_SdioXmitTerminateSema, sizeof(_sema));
4997 memcpy(&(pHalData->SdioTxFIFOFreePageLock), &temp_SdioTxFIFOFreePageLock, sizeof(_lock));
5000 memcpy(dst_adapter->HalData, src_adapter->HalData, dst_adapter->hal_data_sz);
5005 void rtl8723a_start_thread(_adapter *padapter)
5007 #if (defined CONFIG_SDIO_HCI) || (defined CONFIG_GSPI_HCI)
5008 #ifndef CONFIG_SDIO_TX_TASKLET
5009 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
5011 pHalData->SdioXmitThread = kthread_run(rtl8723as_xmit_thread, padapter, "RTWHALXT");
5012 if (IS_ERR(pHalData->SdioXmitThread))
5014 RT_TRACE(_module_hal_xmit_c_, _drv_err_, ("%s: start rtl8723as_xmit_thread FAIL!!\n", __FUNCTION__));
5020 void rtl8723a_stop_thread(_adapter *padapter)
5022 #if (defined CONFIG_SDIO_HCI) || (defined CONFIG_GSPI_HCI)
5023 #ifndef CONFIG_SDIO_TX_TASKLET
5024 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
5026 // stop xmit_buf_thread
5027 if (pHalData->SdioXmitThread ) {
5028 up(&pHalData->SdioXmitSema);
5029 down(&pHalData->SdioXmitTerminateSema);
5030 pHalData->SdioXmitThread = 0;