1 /******************************************************************************
3 * Copyright(c) 2007 - 2013 Realtek Corporation. All rights reserved.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 ******************************************************************************/
22 #include <rtl8723b_hal.h>
23 #include "rtw_bt_mp.h"
24 #include "hal_com_h2c.h"
37 tmp = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
38 rtw_write8(padapter, REG_SYS_FUNC_EN+1, tmp|0x04);
40 tmp = rtw_read8(padapter, REG_MCUFWDL);
41 rtw_write8(padapter, REG_MCUFWDL, tmp|0x01);
44 tmp = rtw_read8(padapter, REG_MCUFWDL);
47 rtw_write8(padapter, REG_MCUFWDL, tmp|0x01);
51 DBG_871X("%s: !!!!!!!!Write 0x80 Fail!: count = %d\n", __func__, count);
54 tmp = rtw_read8(padapter, REG_MCUFWDL+2);
55 rtw_write8(padapter, REG_MCUFWDL+2, tmp&0xf7);
59 // MCU firmware download disable.
60 tmp = rtw_read8(padapter, REG_MCUFWDL);
61 rtw_write8(padapter, REG_MCUFWDL, tmp&0xfe);
74 u32 blockSize_p1 = 4; // (Default) Phase #1 : PCI muse use 4-byte write to download FW
75 u32 blockSize_p2 = 8; // Phase #2 : Use 8-byte, if Phase#1 use big size to write FW.
76 u32 blockSize_p3 = 1; // Phase #3 : Use 1-byte, the remnant of FW image.
77 u32 blockCount_p1 = 0, blockCount_p2 = 0, blockCount_p3 = 0;
78 u32 remainSize_p1 = 0, remainSize_p2 = 0;
79 u8 *bufferPtr = (u8*)buffer;
82 u8 remainFW[4] = {0, 0, 0, 0};
90 // printk("====>%s %d\n", __func__, __LINE__);
93 blockCount_p1 = buffSize / blockSize_p1;
94 remainSize_p1 = buffSize % blockSize_p1;
97 RT_TRACE(_module_hal_init_c_, _drv_notice_,
98 ("_BlockWrite: [P1] buffSize(%d) blockSize_p1(%d) blockCount_p1(%d) remainSize_p1(%d)\n",
99 buffSize, blockSize_p1, blockCount_p1, remainSize_p1));
102 for (i = 0; i < blockCount_p1; i++)
104 #ifdef CONFIG_USB_HCI
105 ret = rtw_writeN(padapter, (FW_8723B_START_ADDRESS + i * blockSize_p1), blockSize_p1, (bufferPtr + i * blockSize_p1));
107 ret = rtw_write32(padapter, (FW_8723B_START_ADDRESS + i * blockSize_p1), le32_to_cpu(*((u32*)(bufferPtr + i * blockSize_p1))));
110 printk("====>%s %d i:%d\n", __func__, __LINE__, i);
115 #ifdef CONFIG_PCI_HCI
116 p = (u8*)((u32*)(bufferPtr + blockCount_p1 * blockSize_p1));
118 switch (remainSize_p1) {
127 ret = rtw_write32(padapter, (FW_8723B_START_ADDRESS + blockCount_p1 * blockSize_p1),
128 le32_to_cpu(*(u32*)remainFW));
137 offset = blockCount_p1 * blockSize_p1;
139 blockCount_p2 = remainSize_p1/blockSize_p2;
140 remainSize_p2 = remainSize_p1%blockSize_p2;
143 RT_TRACE(_module_hal_init_c_, _drv_notice_,
144 ("_BlockWrite: [P2] buffSize_p2(%d) blockSize_p2(%d) blockCount_p2(%d) remainSize_p2(%d)\n",
145 (buffSize-offset), blockSize_p2 ,blockCount_p2, remainSize_p2));
148 #ifdef CONFIG_USB_HCI
149 for (i = 0; i < blockCount_p2; i++) {
150 ret = rtw_writeN(padapter, (FW_8723B_START_ADDRESS + offset + i*blockSize_p2), blockSize_p2, (bufferPtr + offset + i*blockSize_p2));
161 offset = (blockCount_p1 * blockSize_p1) + (blockCount_p2 * blockSize_p2);
163 blockCount_p3 = remainSize_p2 / blockSize_p3;
165 RT_TRACE(_module_hal_init_c_, _drv_notice_,
166 ("_BlockWrite: [P3] buffSize_p3(%d) blockSize_p3(%d) blockCount_p3(%d)\n",
167 (buffSize-offset), blockSize_p3, blockCount_p3));
169 for(i = 0 ; i < blockCount_p3 ; i++){
170 ret = rtw_write8(padapter, (FW_8723B_START_ADDRESS + offset + i), *(bufferPtr + offset + i));
173 printk("====>%s %d i:%d\n", __func__, __LINE__, i);
184 IN PADAPTER padapter,
191 u8 u8Page = (u8) (page & 0x07) ;
193 value8 = (rtw_read8(padapter, REG_MCUFWDL+2) & 0xF8) | u8Page ;
194 rtw_write8(padapter, REG_MCUFWDL+2,value8);
196 return _BlockWrite(padapter,buffer,size);
206 u8 remain = (u8)(FwLen%4);
207 remain = (remain==0)?0:(4-remain);
221 IN PADAPTER padapter,
226 // Since we need dynamic decide method of dwonload fw, so we call this function to get chip version.
227 // We can remove _ReadChipVersion from ReadpadapterInfo8192C later.
229 u32 pageNums,remainSize ;
231 u8 *bufferPtr = (u8*)buffer;
233 #ifdef CONFIG_PCI_HCI
234 // 20100120 Joseph: Add for 88CE normal chip.
235 // Fill in zero to make firmware image to dword alignment.
236 _FillDummy(bufferPtr, &size);
239 pageNums = size / MAX_DLFW_PAGE_SIZE ;
240 //RT_ASSERT((pageNums <= 4), ("Page numbers should not greater then 4 \n"));
241 remainSize = size % MAX_DLFW_PAGE_SIZE;
243 for (page = 0; page < pageNums; page++) {
244 offset = page * MAX_DLFW_PAGE_SIZE;
245 ret = _PageWrite(padapter, page, bufferPtr+offset, MAX_DLFW_PAGE_SIZE);
248 printk("====>%s %d\n", __func__, __LINE__);
253 offset = pageNums * MAX_DLFW_PAGE_SIZE;
255 ret = _PageWrite(padapter, page, bufferPtr+offset, remainSize);
258 printk("====>%s %d\n", __func__, __LINE__);
262 RT_TRACE(_module_hal_init_c_, _drv_info_, ("_WriteFW Done- for Normal chip.\n"));
268 void _8051Reset8723(PADAPTER padapter)
273 io_rst = rtw_read8(padapter, REG_RSV_CTRL);
274 rtw_write8(padapter, REG_RSV_CTRL, io_rst&(~BIT1));
275 // Reset 8051(WLMCU) IO wrapper
277 // Suggested by Isaac@SD1 and Gimmy@SD1, coding by Lucas@20130624
278 io_rst = rtw_read8(padapter, REG_RSV_CTRL+1);
280 rtw_write8(padapter, REG_RSV_CTRL+1, io_rst);
282 cpu_rst = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
284 rtw_write8(padapter, REG_SYS_FUNC_EN+1, cpu_rst);
286 io_rst = rtw_read8(padapter, REG_RSV_CTRL);
287 rtw_write8(padapter, REG_RSV_CTRL, io_rst&(~BIT1));
288 // Enable 8051 IO wrapper
290 io_rst = rtw_read8(padapter, REG_RSV_CTRL+1);
292 rtw_write8(padapter, REG_RSV_CTRL+1, io_rst);
294 cpu_rst = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
296 rtw_write8(padapter, REG_SYS_FUNC_EN+1, cpu_rst);
298 DBG_8192C("%s: Finish\n", __FUNCTION__);
301 static s32 polling_fwdl_chksum(_adapter *adapter, u32 min_cnt, u32 timeout_ms)
305 u32 start = rtw_get_current_time();
308 /* polling CheckSum report */
311 value32 = rtw_read32(adapter, REG_MCUFWDL);
312 if (value32 & FWDL_ChkSum_rpt || adapter->bSurpriseRemoved || adapter->bDriverStopped)
315 } while (rtw_get_passing_time_ms(start) < timeout_ms || cnt < min_cnt);
317 if (!(value32 & FWDL_ChkSum_rpt)) {
321 if (rtw_fwdl_test_trigger_chksum_fail())
327 DBG_871X("%s: Checksum report %s! (%u, %dms), REG_MCUFWDL:0x%08x\n", __FUNCTION__
328 , (ret==_SUCCESS)?"OK":"Fail", cnt, rtw_get_passing_time_ms(start), value32);
333 static s32 _FWFreeToGo(_adapter *adapter, u32 min_cnt, u32 timeout_ms)
337 u32 start = rtw_get_current_time();
340 value32 = rtw_read32(adapter, REG_MCUFWDL);
341 value32 |= MCUFWDL_RDY;
342 value32 &= ~WINTINI_RDY;
343 rtw_write32(adapter, REG_MCUFWDL, value32);
345 _8051Reset8723(adapter);
347 /* polling for FW ready */
350 value32 = rtw_read32(adapter, REG_MCUFWDL);
351 if (value32 & WINTINI_RDY || adapter->bSurpriseRemoved || adapter->bDriverStopped)
354 } while (rtw_get_passing_time_ms(start) < timeout_ms || cnt < min_cnt);
356 if (!(value32 & WINTINI_RDY)) {
360 if (rtw_fwdl_test_trigger_wintint_rdy_fail())
366 DBG_871X("%s: Polling FW ready %s! (%u, %dms), REG_MCUFWDL:0x%08x\n", __FUNCTION__
367 , (ret==_SUCCESS)?"OK":"Fail", cnt, rtw_get_passing_time_ms(start), value32);
372 #define IS_FW_81xxC(padapter) (((GET_HAL_DATA(padapter))->FirmwareSignature & 0xFFF0) == 0x88C0)
374 void rtl8723b_FirmwareSelfReset(PADAPTER padapter)
376 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
380 if (!(IS_FW_81xxC(padapter) &&
381 ((pHalData->FirmwareVersion < 0x21) ||
382 (pHalData->FirmwareVersion == 0x21 &&
383 pHalData->FirmwareSubVersion < 0x01)))) // after 88C Fw v33.1
385 //0x1cf=0x20. Inform 8051 to reset. 2009.12.25. tynli_test
386 rtw_write8(padapter, REG_HMETFR+3, 0x20);
388 u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
389 while (u1bTmp & BIT2)
395 u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
397 RT_TRACE(_module_hal_init_c_, _drv_notice_, ("-%s: 8051 reset success (%d)\n", __FUNCTION__, Delay));
401 RT_TRACE(_module_hal_init_c_, _drv_notice_, ("%s: Force 8051 reset!!!\n", __FUNCTION__));
402 //force firmware reset
403 u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN+1);
404 rtw_write8(padapter, REG_SYS_FUNC_EN+1, u1bTmp&(~BIT2));
409 #ifdef CONFIG_FILE_FWIMG
410 extern char *rtw_fw_file_path;
411 extern char *rtw_fw_wow_file_path;
412 #ifdef CONFIG_MP_INCLUDED
413 extern char *rtw_fw_mp_bt_file_path;
414 #endif // CONFIG_MP_INCLUDED
415 u8 FwBuffer[FW_8723B_SIZE];
416 #endif // CONFIG_FILE_FWIMG
418 #ifdef CONFIG_MP_INCLUDED
419 int _WriteBTFWtoTxPktBuf8723B(
426 int rtStatus = _SUCCESS;
428 //u1Byte numHQ, numLQ, numPubQ;//, txpktbuf_bndy;
429 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
430 //PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo);
432 u1Byte count=0, DLBcnCount=0;
433 pu1Byte FwbufferPtr = (pu1Byte)buffer;
434 //PRT_TCB pTcb, ptempTcb;
435 //PRT_TX_LOCAL_BUFFER pBuf;
436 BOOLEAN bRecover=_FALSE;
437 pu1Byte ReservedPagePacket = NULL;
438 pu1Byte pGenBufReservedPagePacket = NULL;
439 u4Byte TotalPktLen,txpktbuf_bndy;
443 struct xmit_priv *pxmitpriv = &(Adapter->xmitpriv);
444 struct xmit_frame *pmgntframe;
445 struct pkt_attrib *pattrib;
446 u8 txdesc_offset = TXDESC_OFFSET;
448 #if (DEV_BUS_TYPE == RT_PCI_INTERFACE)
452 #if 1//(DEV_BUS_TYPE == RT_PCI_INTERFACE)
453 TotalPktLen = FwBufLen;
455 TotalPktLen = FwBufLen+pHalData->HWDescHeadLength;
458 if((TotalPktLen+TXDESC_OFFSET) > MAX_CMDBUF_SZ)
460 DBG_871X(" WARNING %s => Total packet len = %d > MAX_CMDBUF_SZ:%d \n"
461 ,__FUNCTION__,(TotalPktLen+TXDESC_OFFSET),MAX_CMDBUF_SZ);
465 pGenBufReservedPagePacket = rtw_zmalloc(TotalPktLen);//GetGenTempBuffer (Adapter, TotalPktLen);
466 if (!pGenBufReservedPagePacket)
469 ReservedPagePacket = (u1Byte *)pGenBufReservedPagePacket;
471 _rtw_memset(ReservedPagePacket, 0, TotalPktLen);
473 #if 1//(DEV_BUS_TYPE == RT_PCI_INTERFACE)
474 _rtw_memcpy(ReservedPagePacket, FwbufferPtr, FwBufLen);
477 PlatformMoveMemory(ReservedPagePacket+Adapter->HWDescHeadLength , FwbufferPtr, FwBufLen);
480 //---------------------------------------------------------
482 //---------------------------------------------------------
483 //Set REG_CR bit 8. DMA beacon by SW.
484 #if (DEV_BUS_TYPE == RT_PCI_INTERFACE)
485 u1bTmp = PlatformEFIORead1Byte(Adapter, REG_CR+1);
486 PlatformEFIOWrite1Byte(Adapter, REG_CR+1, (u1bTmp|BIT0));
488 // Remove for temparaily because of the code on v2002 is not sync to MERGE_TMEP for USB/SDIO.
489 // De not remove this part on MERGE_TEMP. by tynli.
490 //pHalData->RegCR_1 |= (BIT0);
491 //PlatformEFIOWrite1Byte(Adapter, REG_CR+1, pHalData->RegCR_1);
494 // Disable Hw protection for a time which revserd for Hw sending beacon.
495 // Fix download reserved page packet fail that access collision with the protection time.
496 // 2010.05.11. Added by tynli.
497 val8 = rtw_read8(Adapter, REG_BCN_CTRL);
498 val8 &= ~EN_BCN_FUNCTION;
500 rtw_write8(Adapter, REG_BCN_CTRL, val8);
502 #if 0//(DEV_BUS_TYPE == RT_PCI_INTERFACE)
503 tmpReg422 = PlatformEFIORead1Byte(Adapter, REG_FWHW_TXQ_CTRL+2);
506 PlatformEFIOWrite1Byte(Adapter, REG_FWHW_TXQ_CTRL+2, tmpReg422&(~BIT6));
508 // Set FWHW_TXQ_CTRL 0x422[6]=0 to tell Hw the packet is not a real beacon frame.
509 if(pHalData->RegFwHwTxQCtrl & BIT(6))
511 PlatformEFIOWrite1Byte(Adapter, REG_FWHW_TXQ_CTRL+2, (pHalData->RegFwHwTxQCtrl&(~BIT(6))));
512 pHalData->RegFwHwTxQCtrl &= (~ BIT(6));
515 //---------------------------------------------------------
516 // 2. Adjust LLT table to an even boundary.
517 //---------------------------------------------------------
518 #if 0//(DEV_BUS_TYPE == RT_SDIO_INTERFACE)
519 txpktbuf_bndy = 10; // rsvd page start address should be an even value.
520 rtStatus = InitLLTTable8723BS(Adapter, txpktbuf_bndy);
521 if(RT_STATUS_SUCCESS != rtStatus){
522 DBG_8192C("_CheckWLANFwPatchBTFwReady_8723B(): Failed to init LLT!\n");
523 return RT_STATUS_FAILURE;
527 PlatformEFIOWrite1Byte(Adapter, REG_DWBCN0_CTRL_8723B+1, (u1Byte)txpktbuf_bndy);
531 //---------------------------------------------------------
532 // 3. Write Fw to Tx packet buffer by reseverd page.
533 //---------------------------------------------------------
536 // download rsvd page.
537 // Clear beacon valid check bit.
538 BcnValidReg = PlatformEFIORead1Byte(Adapter, REG_TDECTRL+2);
539 PlatformEFIOWrite1Byte(Adapter, REG_TDECTRL+2, BcnValidReg&(~BIT(0)));
541 //BT patch is big, we should set 0x209 < 0x40 suggested from Gimmy
542 RT_TRACE(_module_mp_, _drv_info_,("0x209:%x\n",
543 PlatformEFIORead1Byte(Adapter, REG_TDECTRL+1)));//209 < 0x40
545 PlatformEFIOWrite1Byte(Adapter, REG_TDECTRL+1, (0x90-0x20*(times-1)));
546 DBG_871X("0x209:0x%x\n", PlatformEFIORead1Byte(Adapter, REG_TDECTRL+1));
547 RT_TRACE(_module_mp_, _drv_info_,("0x209:%x\n",
548 PlatformEFIORead1Byte(Adapter, REG_TDECTRL+1)));
551 // Acquice TX spin lock before GetFwBuf and send the packet to prevent system deadlock.
552 // Advertised by Roger. Added by tynli. 2010.02.22.
553 PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK);
554 if(MgntGetFWBuffer(Adapter, &pTcb, &pBuf))
556 PlatformMoveMemory(pBuf->Buffer.VirtualAddress, ReservedPagePacket, TotalPktLen);
557 CmdSendPacket(Adapter, pTcb, pBuf, TotalPktLen, DESC_PACKET_TYPE_NORMAL, FALSE);
560 dbgdump("SetFwRsvdPagePkt(): MgntGetFWBuffer FAIL!!!!!!!!.\n");
561 PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK);
563 /*---------------------------------------------------------
564 tx reserved_page_packet
565 ----------------------------------------------------------*/
566 if ((pmgntframe = rtw_alloc_cmdxmitframe(pxmitpriv)) == NULL) {
571 pattrib = &pmgntframe->attrib;
572 update_mgntframe_attrib(Adapter, pattrib);
574 pattrib->qsel = QSLT_BEACON;
575 pattrib->pktlen = pattrib->last_txcmdsz = FwBufLen ;
577 //_rtw_memset(pmgntframe->buf_addr, 0, TotalPktLen+txdesc_size);
578 //pmgntframe->buf_addr = ReservedPagePacket ;
580 _rtw_memcpy( (u8*) (pmgntframe->buf_addr + txdesc_offset), ReservedPagePacket, FwBufLen);
581 DBG_871X("[%d]===>TotalPktLen + TXDESC_OFFSET TotalPacketLen:%d \n", DLBcnCount, (FwBufLen + txdesc_offset));
583 #ifdef CONFIG_PCI_HCI
584 dump_mgntframe(Adapter, pmgntframe);
586 dump_mgntframe_and_wait(Adapter, pmgntframe, 100);
591 // check rsvd page download OK.
592 BcnValidReg = PlatformEFIORead1Byte(Adapter, REG_TDECTRL+2);
593 while(!(BcnValidReg & BIT(0)) && count <200)
596 //PlatformSleepUs(10);
598 BcnValidReg = PlatformEFIORead1Byte(Adapter, REG_TDECTRL+2);
599 RT_TRACE(_module_mp_, _drv_notice_,("Poll 0x20A = %x\n", BcnValidReg));
602 //DBG_871X("##0x208:%08x,0x210=%08x\n",PlatformEFIORead4Byte(Adapter, REG_TDECTRL),PlatformEFIORead4Byte(Adapter, 0x210));
604 PlatformEFIOWrite1Byte(Adapter, REG_TDECTRL+2,BcnValidReg);
606 }while((!(BcnValidReg&BIT(0))) && DLBcnCount<5);
611 DBG_871X(" check rsvd page download OK DLBcnCount =%d \n",DLBcnCount);
616 if(!(BcnValidReg&BIT(0)))
618 DBG_871X("_WriteFWtoTxPktBuf(): 1 Download RSVD page failed!\n");
623 //---------------------------------------------------------
624 // 4. Set Tx boundary to the initial value
625 //---------------------------------------------------------
628 //---------------------------------------------------------
629 // 5. Reset beacon setting to the initial value.
630 // After _CheckWLANFwPatchBTFwReady().
631 //---------------------------------------------------------
635 if(pGenBufReservedPagePacket)
637 DBG_871X("_WriteBTFWtoTxPktBuf8723B => rtw_mfree pGenBufReservedPagePacket!\n");
638 rtw_mfree((u8*)pGenBufReservedPagePacket, TotalPktLen);
646 // Description: Determine the contents of H2C BT_FW_PATCH Command sent to FW.
647 // 2011.10.20 by tynli
655 u8 u1BTFwPatchParm[H2C_BT_FW_PATCH_LEN]={0};
661 RT_TRACE(_module_mp_, _drv_notice_,("SetFwBTFwPatchCmd(): FwSize = %d\n", FwSize));
663 SET_8723B_H2CCMD_BT_FW_PATCH_SIZE(u1BTFwPatchParm, FwSize);
664 SET_8723B_H2CCMD_BT_FW_PATCH_ADDR0(u1BTFwPatchParm, addr0);
665 SET_8723B_H2CCMD_BT_FW_PATCH_ADDR1(u1BTFwPatchParm, addr1);
666 SET_8723B_H2CCMD_BT_FW_PATCH_ADDR2(u1BTFwPatchParm, addr2);
667 SET_8723B_H2CCMD_BT_FW_PATCH_ADDR3(u1BTFwPatchParm, addr3);
669 FillH2CCmd8723B(Adapter, H2C_8723B_BT_FW_PATCH, H2C_BT_FW_PATCH_LEN, u1BTFwPatchParm);
671 RT_TRACE(_module_mp_, _drv_notice_,("<----SetFwBTFwPatchCmd(): FwSize = %d \n", FwSize));
680 u1Byte u1BTPwrIdxParm[H2C_FORCE_BT_TXPWR_LEN]={0};
682 RT_TRACE(_module_mp_, _drv_info_,("SetFwBTPwrCmd(): idx = %d\n", PwrIdx));
683 SET_8723B_H2CCMD_BT_PWR_IDX(u1BTPwrIdxParm, PwrIdx);
685 RT_TRACE(_module_mp_, _drv_info_,("SetFwBTPwrCmd(): %x %x %x\n",
686 u1BTPwrIdxParm[0],u1BTPwrIdxParm[1],u1BTPwrIdxParm[2]));
688 FillH2CCmd8723B(Adapter, H2C_8723B_FORCE_BT_TXPWR, H2C_FORCE_BT_TXPWR_LEN, u1BTPwrIdxParm);
692 // Description: WLAN Fw will write BT Fw to BT XRAM and signal driver.
694 // 2011.10.20. by tynli.
697 _CheckWLANFwPatchBTFwReady(
701 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
706 //---------------------------------------------------------
707 // Check if BT FW patch procedure is ready.
708 //---------------------------------------------------------
710 u1bTmp = PlatformEFIORead1Byte(Adapter, REG_HMEBOX_DBG_0_8723B);
711 if((u1bTmp&BIT6) || (u1bTmp&BIT7))
718 RT_TRACE(_module_mp_, _drv_info_,("0x88=%x, wait for 50 ms (%d) times.\n",
720 rtw_msleep_os(50); // 50ms
721 }while(!((u1bTmp&BIT6) || (u1bTmp&BIT7)) && count < 50);
723 RT_TRACE(_module_mp_, _drv_notice_,("_CheckWLANFwPatchBTFwReady():"
724 " Polling ready bit 0x88[7] for %d times.\n", count));
728 RT_TRACE(_module_mp_, _drv_notice_,("_CheckWLANFwPatchBTFwReady():"
729 " Polling ready bit 0x88[7] FAIL!!\n"));
732 //---------------------------------------------------------
733 // Reset beacon setting to the initial value.
734 //---------------------------------------------------------
735 #if 0//(DEV_BUS_TYPE == RT_PCI_INTERFACE)
736 if(LLT_table_init(Adapter, FALSE, 0) == RT_STATUS_FAILURE)
738 dbgdump("Init self define for BT Fw patch LLT table fail.\n");
739 //return RT_STATUS_FAILURE;
742 u1bTmp = rtw_read8(Adapter, REG_BCN_CTRL);
743 u1bTmp |= EN_BCN_FUNCTION;
744 u1bTmp &= ~DIS_TSF_UDT;
745 rtw_write8(Adapter, REG_BCN_CTRL, u1bTmp);
747 // To make sure that if there exists an adapter which would like to send beacon.
748 // If exists, the origianl value of 0x422[6] will be 1, we should check this to
749 // prevent from setting 0x422[6] to 0 after download reserved page, or it will cause
750 // the beacon cannot be sent by HW.
751 // 2010.06.23. Added by tynli.
752 #if 0//(DEV_BUS_TYPE == RT_PCI_INTERFACE)
753 u1bTmp = PlatformEFIORead1Byte(Adapter, REG_FWHW_TXQ_CTRL+2);
754 PlatformEFIOWrite1Byte(Adapter, REG_FWHW_TXQ_CTRL+2, (u1bTmp|BIT6));
756 PlatformEFIOWrite1Byte(Adapter, REG_FWHW_TXQ_CTRL+2, (pHalData->RegFwHwTxQCtrl|BIT(6)));
757 pHalData->RegFwHwTxQCtrl |= BIT(6);
760 // Clear CR[8] or beacon packet will not be send to TxBuf anymore.
761 u1bTmp = PlatformEFIORead1Byte(Adapter, REG_CR_8723B+1);
762 PlatformEFIOWrite1Byte(Adapter, REG_CR_8723B+1, (u1bTmp&(~BIT0)));
767 int ReservedPage_Compare(PADAPTER Adapter,PRT_MP_FIRMWARE pFirmware,u32 BTPatchSize)
769 u8 temp,ret,lastBTsz;
770 u32 u1bTmp=0,address_start=0,count=0,i=0;
771 u8 *myBTFwBuffer = NULL;
773 myBTFwBuffer = rtw_zmalloc(BTPatchSize);
774 if (myBTFwBuffer == NULL)
776 DBG_871X("%s can't be executed due to the failed malloc.\n", __FUNCTION__);
777 Adapter->mppriv.bTxBufCkFail=_TRUE;
781 temp=rtw_read8(Adapter,0x209);
783 address_start=(temp*128)/8;
785 rtw_write32(Adapter,0x140,0x00000000);
786 rtw_write32(Adapter,0x144,0x00000000);
787 rtw_write32(Adapter,0x148,0x00000000);
789 rtw_write8(Adapter,0x106,0x69);
791 for(i=0;i<(BTPatchSize/8);i++)
793 rtw_write32(Adapter,0x140,address_start+5+i) ;
795 //polling until reg 0x140[23]=1;
797 u1bTmp = rtw_read32(Adapter, 0x140);
804 DBG_871X("0x140=%x, wait for 10 ms (%d) times.\n",u1bTmp, count);
805 rtw_msleep_os(10); // 10ms
806 }while(!(u1bTmp&BIT(23)) && count < 50);
808 myBTFwBuffer[i*8+0]=rtw_read8(Adapter, 0x144);
809 myBTFwBuffer[i*8+1]=rtw_read8(Adapter, 0x145);
810 myBTFwBuffer[i*8+2]=rtw_read8(Adapter, 0x146);
811 myBTFwBuffer[i*8+3]=rtw_read8(Adapter, 0x147);
812 myBTFwBuffer[i*8+4]=rtw_read8(Adapter, 0x148);
813 myBTFwBuffer[i*8+5]=rtw_read8(Adapter, 0x149);
814 myBTFwBuffer[i*8+6]=rtw_read8(Adapter, 0x14a);
815 myBTFwBuffer[i*8+7]=rtw_read8(Adapter, 0x14b);
818 rtw_write32(Adapter,0x140,address_start+5+BTPatchSize/8) ;
820 lastBTsz=BTPatchSize%8;
822 //polling until reg 0x140[23]=1;
826 u1bTmp = rtw_read32(Adapter, 0x140);
833 DBG_871X("0x140=%x, wait for 10 ms (%d) times.\n",u1bTmp, count);
834 rtw_msleep_os(10); // 10ms
835 }while(!(u1bTmp&BIT(23)) && count < 50);
837 for(i=0;i<lastBTsz;i++)
839 myBTFwBuffer[(BTPatchSize/8)*8+i] = rtw_read8(Adapter, (0x144+i));
843 for(i=0;i<BTPatchSize;i++)
845 if(myBTFwBuffer[i]!= pFirmware->szFwBuffer[i])
847 DBG_871X(" In direct myBTFwBuffer[%d]=%x , pFirmware->szFwBuffer=%x\n",i, myBTFwBuffer[i],pFirmware->szFwBuffer[i]);
848 Adapter->mppriv.bTxBufCkFail=_TRUE;
853 if (myBTFwBuffer != NULL)
855 rtw_mfree(myBTFwBuffer, BTPatchSize);
861 /* As the size of bt firmware is more than 16k which is too big for some platforms, we divide it
862 * into four parts to transfer. The last parameter of _WriteBTFWtoTxPktBuf8723B is used to indicate
863 * the location of every part. We call the first 4096 byte of bt firmware as part 1, the second 4096
864 * part as part 2, the third 4096 part as part 3, the remain as part 4. First we transform the part
865 * 4 and set the register 0x209 to 0x90, then the 32 bytes description are added to the head of part
866 * 4, and those bytes are putted at the location 0x90. Second we transform the part 3 and set the
867 * register 0x209 to 0x70. The 32 bytes description and part 3(4196 bytes) are putted at the location
868 * 0x70. It can contain 4196 bytes between 0x70 and 0x90. So the last 32 bytes os part 3 will cover the
869 * 32 bytes description of part4. Using this method, we can put the whole bt firmware to 0x30 and only
870 * has 32 bytes descrption at the head of part 1.
872 s32 FirmwareDownloadBT(PADAPTER padapter, PRT_MP_FIRMWARE pFirmware)
882 pBTFirmwareBuf = NULL;
886 // Patch BT Fw. Download BT RAM code to Tx packet buffer.
888 if (padapter->bBTFWReady) {
889 DBG_8192C("%s: BT Firmware is ready!!\n", __FUNCTION__);
893 #ifdef CONFIG_FILE_FWIMG
894 if (rtw_is_file_readable(rtw_fw_mp_bt_file_path) == _TRUE)
896 DBG_8192C("%s: accquire MP BT FW from file:%s\n", __FUNCTION__, rtw_fw_mp_bt_file_path);
898 rtStatus = rtw_retrive_from_file(rtw_fw_mp_bt_file_path, FwBuffer, FW_8723B_SIZE);
899 BTFirmwareLen = rtStatus>=0?rtStatus:0;
900 pBTFirmwareBuf = FwBuffer;
903 #endif // CONFIG_FILE_FWIMG
905 #ifdef CONFIG_EMBEDDED_FWIMG
906 DBG_8192C("%s: Download MP BT FW from header\n", __FUNCTION__);
908 pBTFirmwareBuf = (u8*)Rtl8723BFwBTImgArray;
909 BTFirmwareLen = Rtl8723BFwBTImgArrayLength;
910 pFirmware->szFwBuffer = pBTFirmwareBuf;
911 pFirmware->ulFwLength = BTFirmwareLen;
912 #endif // CONFIG_EMBEDDED_FWIMG
915 DBG_8192C("%s: MP BT Firmware size=%d\n", __FUNCTION__, BTFirmwareLen);
917 // for h2c cam here should be set to true
918 padapter->bFWReady = _TRUE;
920 download_time = (BTFirmwareLen + 4095) / 4096;
921 DBG_8192C("%s: download_time is %d\n", __FUNCTION__, download_time);
923 // Download BT patch Fw.
924 for (i = (download_time-1); i >= 0; i--)
926 if (i == (download_time - 1))
928 rtStatus = _WriteBTFWtoTxPktBuf8723B(padapter, pBTFirmwareBuf+(4096*i), (BTFirmwareLen-(4096*i)), 1);
929 DBG_8192C("%s: start %d, len %d, time 1\n", __FUNCTION__, 4096*i, BTFirmwareLen-(4096*i));
933 rtStatus = _WriteBTFWtoTxPktBuf8723B(padapter, pBTFirmwareBuf+(4096*i), 4096, (download_time-i));
934 DBG_8192C("%s: start %d, len 4096, time %d\n", __FUNCTION__, 4096*i, download_time-i);
937 if (rtStatus != _SUCCESS)
939 DBG_8192C("%s: BT Firmware download to Tx packet buffer fail!\n", __FUNCTION__);
940 padapter->bBTFWReady = _FALSE;
945 ReservedPage_Compare(padapter,pFirmware,BTFirmwareLen);
947 padapter->bBTFWReady = _TRUE;
948 SetFwBTFwPatchCmd(padapter, (u16)BTFirmwareLen);
949 rtStatus = _CheckWLANFwPatchBTFwReady(padapter);
951 DBG_8192C("<===%s: return %s!\n", __FUNCTION__, rtStatus==_SUCCESS?"SUCCESS":"FAIL");
954 #endif // CONFIG_MP_INCLUDED
958 // Download 8192C firmware code.
961 s32 rtl8723b_FirmwareDownload(PADAPTER padapter, BOOLEAN bUsedWoWLANFw)
963 s32 rtStatus = _SUCCESS;
966 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
967 s8 R8723BFwImageFileName[] ={RTL8723B_FW_IMG};
970 u8 *pFwImageFileName;
973 u32 FwImageWoWLANLen;
975 u8 *pucMappedFile = NULL;
976 PRT_FIRMWARE_8723B pFirmware = NULL;
977 PRT_FIRMWARE_8723B pBTFirmware = NULL;
978 PRT_8723B_FIRMWARE_HDR pFwHdr = NULL;
981 #ifdef CONFIG_FILE_FWIMG
983 #endif // CONFIG_FILE_FWIMG
984 struct dvobj_priv *psdpriv = padapter->dvobj;
985 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
986 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
988 RT_TRACE(_module_hal_init_c_, _drv_info_, ("+%s\n", __FUNCTION__));
990 RT_TRACE(_module_hal_init_c_, _drv_notice_, ("+%s, bUsedWoWLANFw:%d\n", __FUNCTION__,bUsedWoWLANFw));
992 pFirmware = (PRT_FIRMWARE_8723B)rtw_zmalloc(sizeof(RT_FIRMWARE_8723B));
1001 u8 tmp_ps=0, tmp_rf=0;
1002 tmp_ps=rtw_read8(padapter,0xa3);
1005 //1. write 0xA3[:2:0] = 3b'010
1006 rtw_write8(padapter, 0xa3, tmp_ps);
1007 //2. read power_state = 0xA0[1:0]
1008 tmp_ps=rtw_read8(padapter,0xa0);
1012 DBG_871X(FUNC_ADPT_FMT" tmp_ps=%x \n",FUNC_ADPT_ARG(padapter), tmp_ps);
1013 pdbgpriv->dbg_downloadfw_pwr_state_cnt++;
1017 rtw_btcoex_PreLoadFirmware(padapter);
1019 #ifdef CONFIG_FILE_FWIMG
1020 #ifdef CONFIG_WOWLAN
1023 fwfilepath = rtw_fw_wow_file_path;
1026 #endif // CONFIG_WOWLAN
1028 fwfilepath = rtw_fw_file_path;
1030 #endif // CONFIG_FILE_FWIMG
1032 #ifdef CONFIG_FILE_FWIMG
1033 if (rtw_is_file_readable(fwfilepath) == _TRUE)
1035 DBG_8192C("%s accquire FW from file:%s\n", __FUNCTION__, fwfilepath);
1036 pFirmware->eFWSource = FW_SOURCE_IMG_FILE;
1039 #endif // CONFIG_FILE_FWIMG
1041 #ifdef CONFIG_EMBEDDED_FWIMG
1042 pFirmware->eFWSource = FW_SOURCE_HEADER_FILE;
1043 #else // !CONFIG_EMBEDDED_FWIMG
1044 pFirmware->eFWSource = FW_SOURCE_IMG_FILE; // We should decided by Reg.
1045 #endif // !CONFIG_EMBEDDED_FWIMG
1048 switch(pFirmware->eFWSource)
1050 case FW_SOURCE_IMG_FILE:
1051 #ifdef CONFIG_FILE_FWIMG
1052 rtStatus = rtw_retrive_from_file(fwfilepath, FwBuffer, FW_8723B_SIZE);
1053 pFirmware->ulFwLength = rtStatus>=0?rtStatus:0;
1054 pFirmware->szFwBuffer = FwBuffer;
1055 #endif // CONFIG_FILE_FWIMG
1058 case FW_SOURCE_HEADER_FILE:
1059 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
1060 if (bUsedWoWLANFw) {
1061 if (!pwrpriv->wowlan_ap_mode) {
1062 ODM_ConfigFWWithHeaderFile(&pHalData->odmpriv,
1064 (u8*)&pFirmware->szFwBuffer,
1065 &pFirmware->ulFwLength);
1067 DBG_8192C(" ===> %s fw: %s, size: %d\n",
1068 __FUNCTION__, "WoWLAN",
1069 pFirmware->ulFwLength);
1071 ODM_ConfigFWWithHeaderFile(&pHalData->odmpriv,
1072 CONFIG_FW_AP_WoWLAN,
1073 (u8*)&pFirmware->szFwBuffer,
1074 &pFirmware->ulFwLength);
1076 DBG_8192C(" ===> %s fw: %s, size: %d\n",
1077 __FUNCTION__, "AP_WoWLAN",
1078 pFirmware->ulFwLength);
1081 #endif // CONFIG_WOWLAN
1083 if(padapter->registrypriv.mp_mode ==0)
1085 ODM_ConfigFWWithHeaderFile(&pHalData->odmpriv, CONFIG_FW_NIC,
1086 (u8*)&pFirmware->szFwBuffer, &pFirmware->ulFwLength);
1087 DBG_8192C("%s fw: %s, size: %d\n", __FUNCTION__, "FW_NIC", pFirmware->ulFwLength);
1091 ODM_ConfigFWWithHeaderFile(&pHalData->odmpriv, CONFIG_FW_MP,
1092 (u8*)&pFirmware->szFwBuffer, &pFirmware->ulFwLength);
1093 DBG_8192C("%s fw: %s, size: %d\n", __FUNCTION__, "FW_MP", pFirmware->ulFwLength);
1099 if (pFirmware->ulFwLength > FW_8723B_SIZE) {
1101 DBG_871X_LEVEL(_drv_emerg_, "Firmware size:%u exceed %u\n", pFirmware->ulFwLength, FW_8723B_SIZE);
1105 pFirmwareBuf = pFirmware->szFwBuffer;
1106 FirmwareLen = pFirmware->ulFwLength;
1108 // To Check Fw header. Added by tynli. 2009.12.04.
1109 pFwHdr = (PRT_8723B_FIRMWARE_HDR)pFirmwareBuf;
1111 pHalData->FirmwareVersion = le16_to_cpu(pFwHdr->Version);
1112 pHalData->FirmwareSubVersion = le16_to_cpu(pFwHdr->Subversion);
1113 pHalData->FirmwareSignature = le16_to_cpu(pFwHdr->Signature);
1115 DBG_871X("%s: fw_ver=%x fw_subver=%04x sig=0x%x, Month=%02x, Date=%02x, Hour=%02x, Minute=%02x\n",
1116 __FUNCTION__, pHalData->FirmwareVersion, pHalData->FirmwareSubVersion, pHalData->FirmwareSignature
1117 ,pFwHdr->Month,pFwHdr->Date,pFwHdr->Hour,pFwHdr->Minute);
1119 if (IS_FW_HEADER_EXIST_8723B(pFwHdr))
1121 DBG_871X("%s(): Shift for fw header!\n", __func__);
1122 // Shift 32 bytes for FW header
1123 pFirmwareBuf = pFirmwareBuf + 32;
1124 FirmwareLen = FirmwareLen - 32;
1127 // Suggested by Filen. If 8051 is running in RAM code, driver should inform Fw to reset by itself,
1128 // or it will cause download Fw fail. 2010.02.01. by tynli.
1129 if (rtw_read8(padapter, REG_MCUFWDL) & RAM_DL_SEL) //8051 RAM code
1131 rtw_write8(padapter, REG_MCUFWDL, 0x00);
1132 rtl8723b_FirmwareSelfReset(padapter);
1135 _FWDownloadEnable(padapter, _TRUE);
1136 fwdl_start_time = rtw_get_current_time();
1137 while(!padapter->bDriverStopped && !padapter->bSurpriseRemoved
1138 && (write_fw++ < 3 || rtw_get_passing_time_ms(fwdl_start_time) < 500))
1140 /* reset FWDL chksum */
1141 rtw_write8(padapter, REG_MCUFWDL, rtw_read8(padapter, REG_MCUFWDL)|FWDL_ChkSum_rpt);
1143 rtStatus = _WriteFW(padapter, pFirmwareBuf, FirmwareLen);
1144 if (rtStatus != _SUCCESS)
1147 rtStatus = polling_fwdl_chksum(padapter, 5, 50);
1148 if (rtStatus == _SUCCESS)
1151 _FWDownloadEnable(padapter, _FALSE);
1152 if(_SUCCESS != rtStatus)
1155 rtStatus = _FWFreeToGo(padapter, 10, 200);
1156 if (_SUCCESS != rtStatus)
1159 #ifdef CONFIG_MP_INCLUDED//BT_MP
1160 if (padapter->registrypriv.mp_mode == 1)
1162 //rtw_write8(padapter, 0x81, rtw_read8(padapter, 0x81)|BIT0);
1163 DBG_871X("rtl8723b_FirmwareDownload go to FirmwareDownloadBT !\n");
1164 pBTFirmware = (PRT_FIRMWARE_8723B)rtw_zmalloc(sizeof(RT_FIRMWARE_8723B));
1170 FirmwareDownloadBT(padapter, (PRT_MP_FIRMWARE)pBTFirmware);
1175 DBG_871X("FWDL %s. write_fw:%u, %dms\n"
1176 , (rtStatus == _SUCCESS)?"success":"fail"
1178 , rtw_get_passing_time_ms(fwdl_start_time)
1183 rtw_mfree((u8*)pFirmware, sizeof(RT_FIRMWARE_8723B));
1185 rtw_mfree((u8*)pBTFirmware, sizeof(RT_FIRMWARE_8723B));
1186 DBG_871X(" <=== rtl8723b_FirmwareDownload()\n");
1190 void rtl8723b_InitializeFirmwareVars(PADAPTER padapter)
1192 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
1194 // Init Fw LPS related.
1195 adapter_to_pwrctl(padapter)->bFwCurrentInPSMode = _FALSE;
1198 rtw_write8(padapter, REG_HMETFR, 0x0f);
1200 // Init H2C counter. by tynli. 2009.12.09.
1201 pHalData->LastHMEBoxNum = 0;
1202 // pHalData->H2CQueueHead = 0;
1203 // pHalData->H2CQueueTail = 0;
1204 // pHalData->H2CStopInsertQueue = _FALSE;
1207 #if defined(CONFIG_WOWLAN) || defined(CONFIG_AP_WOWLAN)
1208 //===========================================
1211 // Description: Prepare some information to Fw for WoWLAN.
1212 // (1) Download wowlan Fw.
1213 // (2) Download RSVD page packets.
1214 // (3) Enable AP offload if needed.
1216 // 2011.04.12 by tynli.
1219 SetFwRelatedForWoWLAN8723b(
1220 IN PADAPTER padapter,
1221 IN u8 bHostIsGoingtoSleep
1225 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
1226 u8 bRecover = _FALSE;
1228 // 1. Before WoWLAN we need to re-download WoWLAN Fw.
1230 status = rtl8723b_FirmwareDownload(padapter, bHostIsGoingtoSleep);
1231 if(status != _SUCCESS) {
1232 DBG_871X("SetFwRelatedForWoWLAN8723b(): Re-Download Firmware failed!!\n");
1235 DBG_871X("SetFwRelatedForWoWLAN8723b(): Re-Download Firmware Success !!\n");
1238 // 2. Re-Init the variables about Fw related setting.
1240 rtl8723b_InitializeFirmwareVars(padapter);
1242 #endif //CONFIG_WOWLAN
1244 static void rtl8723b_free_hal_data(PADAPTER padapter)
1251 //===========================================================
1252 // Efuse related code
1253 //===========================================================
1255 hal_EfuseSwitchToBank(
1262 #ifdef HAL_EFUSE_MEMORY
1263 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
1264 PEFUSE_HAL pEfuseHal = &pHalData->EfuseHal;
1268 DBG_8192C("%s: Efuse switch bank to %d\n", __FUNCTION__, bank);
1271 #ifdef HAL_EFUSE_MEMORY
1272 pEfuseHal->fakeEfuseBank = bank;
1274 fakeEfuseBank = bank;
1280 value32 = rtw_read32(padapter, EFUSE_TEST);
1285 value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_WIFI_SEL_0);
1288 value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_BT_SEL_0);
1291 value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_BT_SEL_1);
1294 value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_BT_SEL_2);
1297 value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_WIFI_SEL_0);
1301 rtw_write32(padapter, EFUSE_TEST, value32);
1308 Hal_GetEfuseDefinition(
1317 case TYPE_EFUSE_MAX_SECTION:
1320 pMax_section = (u8*)pOut;
1322 if (efuseType == EFUSE_WIFI)
1323 *pMax_section = EFUSE_MAX_SECTION_8723B;
1325 *pMax_section = EFUSE_BT_MAX_SECTION;
1329 case TYPE_EFUSE_REAL_CONTENT_LEN:
1332 pu2Tmp = (u16*)pOut;
1334 if (efuseType == EFUSE_WIFI)
1335 *pu2Tmp = EFUSE_REAL_CONTENT_LEN_8723B;
1337 *pu2Tmp = EFUSE_BT_REAL_CONTENT_LEN;
1341 case TYPE_AVAILABLE_EFUSE_BYTES_BANK:
1344 pu2Tmp = (u16*)pOut;
1346 if (efuseType == EFUSE_WIFI)
1347 *pu2Tmp = (EFUSE_REAL_CONTENT_LEN_8723B-EFUSE_OOB_PROTECT_BYTES);
1349 *pu2Tmp = (EFUSE_BT_REAL_BANK_CONTENT_LEN-EFUSE_PROTECT_BYTES_BANK);
1353 case TYPE_AVAILABLE_EFUSE_BYTES_TOTAL:
1356 pu2Tmp = (u16*)pOut;
1358 if (efuseType == EFUSE_WIFI)
1359 *pu2Tmp = (EFUSE_REAL_CONTENT_LEN_8723B-EFUSE_OOB_PROTECT_BYTES);
1361 *pu2Tmp = (EFUSE_BT_REAL_CONTENT_LEN-(EFUSE_PROTECT_BYTES_BANK*3));
1365 case TYPE_EFUSE_MAP_LEN:
1368 pu2Tmp = (u16*)pOut;
1370 if (efuseType == EFUSE_WIFI)
1371 *pu2Tmp = EFUSE_MAX_MAP_LEN;
1373 *pu2Tmp = EFUSE_BT_MAP_LEN;
1377 case TYPE_EFUSE_PROTECT_BYTES_BANK:
1382 if (efuseType == EFUSE_WIFI)
1383 *pu1Tmp = EFUSE_OOB_PROTECT_BYTES;
1385 *pu1Tmp = EFUSE_PROTECT_BYTES_BANK;
1389 case TYPE_EFUSE_CONTENT_LEN_BANK:
1392 pu2Tmp = (u16*)pOut;
1394 if (efuseType == EFUSE_WIFI)
1395 *pu2Tmp = EFUSE_REAL_CONTENT_LEN_8723B;
1397 *pu2Tmp = EFUSE_BT_REAL_BANK_CONTENT_LEN;
1411 #define VOLTAGE_V25 0x03
1412 #define LDOE25_SHIFT 28
1414 //=================================================================
1415 // The following is for compile ok
1416 // That should be merged with the original in the future
1417 //=================================================================
1418 #define EFUSE_ACCESS_ON_8723 0x69 // For RTL8723 only.
1419 #define EFUSE_ACCESS_OFF_8723 0x00 // For RTL8723 only.
1420 #define REG_EFUSE_ACCESS_8723 0x00CF // Efuse access protection for RTL8723
1422 //=================================================================
1423 static void Hal_BT_EfusePowerSwitch(
1429 if (PwrState == _TRUE)
1431 // enable BT power cut
1433 tempval = rtw_read8(padapter, 0x6B);
1435 rtw_write8(padapter, 0x6B, tempval);
1437 // Attention!! Between 0x6A[14] and 0x6A[15] setting need 100us delay
1438 // So don't wirte 0x6A[14]=1 and 0x6A[15]=0 together!
1440 // disable BT output isolation
1442 tempval = rtw_read8(padapter, 0x6B);
1444 rtw_write8(padapter, 0x6B, tempval);
1448 // enable BT output isolation
1450 tempval = rtw_read8(padapter, 0x6B);
1452 rtw_write8(padapter, 0x6B, tempval);
1454 // Attention!! Between 0x6A[14] and 0x6A[15] setting need 100us delay
1455 // So don't wirte 0x6A[14]=1 and 0x6A[15]=0 together!
1457 // disable BT power cut
1459 tempval = rtw_read8(padapter, 0x6B);
1461 rtw_write8(padapter, 0x6B, tempval);
1466 Hal_EfusePowerSwitch(
1475 if (PwrState == _TRUE)
1477 #ifdef CONFIG_SDIO_HCI
1478 // To avoid cannot access efuse regsiters after disable/enable several times during DTM test.
1479 // Suggested by SD1 IsaacHsu. 2013.07.08, added by tynli.
1480 tempval = rtw_read8(padapter, SDIO_LOCAL_BASE|SDIO_REG_HSUS_CTRL);
1481 if (tempval & BIT(0)) // SDIO local register is suspend
1487 rtw_write8(padapter, SDIO_LOCAL_BASE|SDIO_REG_HSUS_CTRL, tempval);
1489 // check 0x86[1:0]=10'2h, wait power state to leave suspend
1491 tempval = rtw_read8(padapter, SDIO_LOCAL_BASE|SDIO_REG_HSUS_CTRL);
1493 if (tempval == 0x02)
1505 DBG_8192C(FUNC_ADPT_FMT ": Leave SDIO local register suspend fail! Local 0x86=%#X\n",
1506 FUNC_ADPT_ARG(padapter), tempval);
1510 DBG_8192C(FUNC_ADPT_FMT ": Leave SDIO local register suspend OK! Local 0x86=%#X\n",
1511 FUNC_ADPT_ARG(padapter), tempval);
1514 #endif // CONFIG_SDIO_HCI
1516 rtw_write8(padapter, REG_EFUSE_ACCESS_8723, EFUSE_ACCESS_ON_8723);
1518 // Reset: 0x0000h[28], default valid
1519 tmpV16 = rtw_read16(padapter, REG_SYS_FUNC_EN);
1520 if (!(tmpV16 & FEN_ELDR)) {
1521 tmpV16 |= FEN_ELDR ;
1522 rtw_write16(padapter, REG_SYS_FUNC_EN, tmpV16);
1525 // Clock: Gated(0x0008h[5]) 8M(0x0008h[1]) clock from ANA, default valid
1526 tmpV16 = rtw_read16(padapter, REG_SYS_CLKR);
1527 if ((!(tmpV16 & LOADER_CLK_EN)) || (!(tmpV16 & ANA8M))) {
1528 tmpV16 |= (LOADER_CLK_EN | ANA8M) ;
1529 rtw_write16(padapter, REG_SYS_CLKR, tmpV16);
1532 if (bWrite == _TRUE)
1534 // Enable LDO 2.5V before read/write action
1535 tempval = rtw_read8(padapter, EFUSE_TEST+3);
1537 tempval |= (VOLTAGE_V25 << 4);
1538 rtw_write8(padapter, EFUSE_TEST+3, (tempval | 0x80));
1540 //rtw_write8(padapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON);
1545 rtw_write8(padapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF);
1547 if (bWrite == _TRUE) {
1548 // Disable LDO 2.5V after read/write action
1549 tempval = rtw_read8(padapter, EFUSE_TEST+3);
1550 rtw_write8(padapter, EFUSE_TEST+3, (tempval & 0x7F));
1564 #ifdef HAL_EFUSE_MEMORY
1565 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
1566 PEFUSE_HAL pEfuseHal = &pHalData->EfuseHal;
1568 u8 *efuseTbl = NULL;
1571 u8 efuseHeader, efuseExtHdr, efuseData;
1575 //DBG_871X("YJ: ====>%s():_offset=%d _size_byte=%d bPseudoTest=%d\n", __func__, _offset, _size_byte, bPseudoTest);
1577 // Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10.
1579 if ((_offset+_size_byte) > EFUSE_MAX_MAP_LEN)
1581 DBG_8192C("%s: Invalid offset(%#x) with read bytes(%#x)!!\n", __FUNCTION__, _offset, _size_byte);
1585 efuseTbl = (u8*)rtw_malloc(EFUSE_MAX_MAP_LEN);
1586 if (efuseTbl == NULL)
1588 DBG_8192C("%s: alloc efuseTbl fail!\n", __FUNCTION__);
1591 // 0xff will be efuse default value instead of 0x00.
1592 _rtw_memset(efuseTbl, 0xFF, EFUSE_MAX_MAP_LEN);
1598 for(i=0; i<256; i++)
1599 //ReadEFuseByte(padapter, i, &efuseTbl[i], _FALSE);
1600 efuse_OneByteRead(padapter, i, &efuseTbl[i], _FALSE);
1601 DBG_871X("Efuse Content:\n");
1602 for(i=0; i<256; i++)
1606 printk("%02X ", efuseTbl[i]);
1613 // switch bank back to bank 0 for later BT and wifi use.
1614 hal_EfuseSwitchToBank(padapter, 0, bPseudoTest);
1616 while (AVAILABLE_EFUSE_ADDR(eFuse_Addr))
1618 //ReadEFuseByte(padapter, eFuse_Addr++, &efuseHeader, bPseudoTest);
1619 efuse_OneByteRead(padapter, eFuse_Addr++, &efuseHeader, bPseudoTest);
1620 if (efuseHeader == 0xFF)
1622 DBG_8192C("%s: data end at address=%#x\n", __FUNCTION__, eFuse_Addr-1);
1625 //DBG_8192C("%s: efuse[0x%X]=0x%02X\n", __FUNCTION__, eFuse_Addr-1, efuseHeader);
1627 // Check PG header for section num.
1628 if (EXT_HEADER(efuseHeader)) //extended header
1630 offset = GET_HDR_OFFSET_2_0(efuseHeader);
1631 //DBG_8192C("%s: extended header offset=0x%X\n", __FUNCTION__, offset);
1633 //ReadEFuseByte(padapter, eFuse_Addr++, &efuseExtHdr, bPseudoTest);
1634 efuse_OneByteRead(padapter, eFuse_Addr++, &efuseExtHdr, bPseudoTest);
1635 //DBG_8192C("%s: efuse[0x%X]=0x%02X\n", __FUNCTION__, eFuse_Addr-1, efuseExtHdr);
1636 if (ALL_WORDS_DISABLED(efuseExtHdr))
1641 offset |= ((efuseExtHdr & 0xF0) >> 1);
1642 wden = (efuseExtHdr & 0x0F);
1646 offset = ((efuseHeader >> 4) & 0x0f);
1647 wden = (efuseHeader & 0x0f);
1649 //DBG_8192C("%s: Offset=%d Worden=0x%X\n", __FUNCTION__, offset, wden);
1651 if (offset < EFUSE_MAX_SECTION_8723B)
1654 // Get word enable value from PG header
1655 // DBG_8192C("%s: Offset=%d Worden=0x%X\n", __FUNCTION__, offset, wden);
1657 addr = offset * PGPKT_DATA_SIZE;
1658 for (i=0; i<EFUSE_MAX_WORD_UNIT; i++)
1660 // Check word enable condition in the section
1661 if (!(wden & (0x01<<i)))
1663 //ReadEFuseByte(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
1664 efuse_OneByteRead(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
1665 // DBG_8192C("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, eFuse_Addr-1, efuseData);
1666 efuseTbl[addr] = efuseData;
1668 //ReadEFuseByte(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
1669 efuse_OneByteRead(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
1670 // DBG_8192C("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, eFuse_Addr-1, efuseData);
1671 efuseTbl[addr+1] = efuseData;
1678 DBG_8192C(KERN_ERR "%s: offset(%d) is illegal!!\n", __FUNCTION__, offset);
1679 eFuse_Addr += Efuse_CalculateWordCnts(wden)*2;
1683 // Copy from Efuse map to output pointer memory!!!
1684 for (i=0; i<_size_byte; i++)
1685 pbuf[i] = efuseTbl[_offset+i];
1690 DBG_871X("Efuse Realmap:\n");
1691 for(i=0; i<_size_byte; i++)
1695 printk("%02X ", pbuf[i]);
1700 // Calculate Efuse utilization
1701 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &total, bPseudoTest);
1702 used = eFuse_Addr - 1;
1703 efuse_usage = (u8)((used*100)/total);
1706 #ifdef HAL_EFUSE_MEMORY
1707 pEfuseHal->fakeEfuseUsedBytes = used;
1709 fakeEfuseUsedBytes = used;
1714 rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8*)&used);
1715 rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_USAGE, (u8*)&efuse_usage);
1719 rtw_mfree(efuseTbl, EFUSE_MAX_MAP_LEN);
1731 #ifdef HAL_EFUSE_MEMORY
1732 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
1733 PEFUSE_HAL pEfuseHal = &pHalData->EfuseHal;
1738 u8 efuseHeader, efuseExtHdr, efuseData;
1745 // Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10.
1747 if ((_offset+_size_byte) > EFUSE_BT_MAP_LEN)
1749 DBG_8192C("%s: Invalid offset(%#x) with read bytes(%#x)!!\n", __FUNCTION__, _offset, _size_byte);
1753 efuseTbl = rtw_malloc(EFUSE_BT_MAP_LEN);
1754 if (efuseTbl == NULL) {
1755 DBG_8192C("%s: efuseTbl malloc fail!\n", __FUNCTION__);
1758 // 0xff will be efuse default value instead of 0x00.
1759 _rtw_memset(efuseTbl, 0xFF, EFUSE_BT_MAP_LEN);
1761 EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_BANK, &total, bPseudoTest);
1763 for (bank=1; bank<3; bank++) // 8723b Max bake 0~2
1765 if (hal_EfuseSwitchToBank(padapter, bank, bPseudoTest) == _FALSE)
1767 DBG_8192C("%s: hal_EfuseSwitchToBank Fail!!\n", __FUNCTION__);
1773 while (AVAILABLE_EFUSE_ADDR(eFuse_Addr))
1775 //ReadEFuseByte(padapter, eFuse_Addr++, &efuseHeader, bPseudoTest);
1776 efuse_OneByteRead(padapter, eFuse_Addr++, &efuseHeader, bPseudoTest);
1777 if (efuseHeader == 0xFF) break;
1778 DBG_8192C("%s: efuse[%#X]=0x%02x (header)\n", __FUNCTION__, (((bank-1)*EFUSE_REAL_CONTENT_LEN_8723B)+eFuse_Addr-1), efuseHeader);
1780 // Check PG header for section num.
1781 if (EXT_HEADER(efuseHeader)) //extended header
1783 offset = GET_HDR_OFFSET_2_0(efuseHeader);
1784 DBG_8192C("%s: extended header offset_2_0=0x%X\n", __FUNCTION__, offset);
1786 //ReadEFuseByte(padapter, eFuse_Addr++, &efuseExtHdr, bPseudoTest);
1787 efuse_OneByteRead(padapter, eFuse_Addr++, &efuseExtHdr, bPseudoTest);
1788 DBG_8192C("%s: efuse[%#X]=0x%02x (ext header)\n", __FUNCTION__, (((bank-1)*EFUSE_REAL_CONTENT_LEN_8723B)+eFuse_Addr-1), efuseExtHdr);
1789 if (ALL_WORDS_DISABLED(efuseExtHdr))
1794 offset |= ((efuseExtHdr & 0xF0) >> 1);
1795 wden = (efuseExtHdr & 0x0F);
1799 offset = ((efuseHeader >> 4) & 0x0f);
1800 wden = (efuseHeader & 0x0f);
1803 if (offset < EFUSE_BT_MAX_SECTION)
1807 // Get word enable value from PG header
1808 DBG_8192C("%s: Offset=%d Worden=%#X\n", __FUNCTION__, offset, wden);
1810 addr = offset * PGPKT_DATA_SIZE;
1811 for (i=0; i<EFUSE_MAX_WORD_UNIT; i++)
1813 // Check word enable condition in the section
1814 if (!(wden & (0x01<<i)))
1816 //ReadEFuseByte(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
1817 efuse_OneByteRead(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
1818 DBG_8192C("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, eFuse_Addr-1, efuseData);
1819 efuseTbl[addr] = efuseData;
1821 //ReadEFuseByte(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
1822 efuse_OneByteRead(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
1823 DBG_8192C("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, eFuse_Addr-1, efuseData);
1824 efuseTbl[addr+1] = efuseData;
1831 DBG_8192C("%s: offset(%d) is illegal!!\n", __FUNCTION__, offset);
1832 eFuse_Addr += Efuse_CalculateWordCnts(wden)*2;
1836 if ((eFuse_Addr-1) < total)
1838 DBG_8192C("%s: bank(%d) data end at %#x\n", __FUNCTION__, bank, eFuse_Addr-1);
1843 // switch bank back to bank 0 for later BT and wifi use.
1844 hal_EfuseSwitchToBank(padapter, 0, bPseudoTest);
1846 // Copy from Efuse map to output pointer memory!!!
1847 for (i=0; i<_size_byte; i++)
1848 pbuf[i] = efuseTbl[_offset+i];
1851 // Calculate Efuse utilization.
1853 EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &total, bPseudoTest);
1854 used = (EFUSE_BT_REAL_BANK_CONTENT_LEN*(bank-1)) + eFuse_Addr - 1;
1855 DBG_8192C("%s: bank(%d) data end at %#x ,used =%d\n", __FUNCTION__, bank, eFuse_Addr-1,used);
1856 efuse_usage = (u8)((used*100)/total);
1859 #ifdef HAL_EFUSE_MEMORY
1860 pEfuseHal->fakeBTEfuseUsedBytes = used;
1862 fakeBTEfuseUsedBytes = used;
1867 rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, (u8*)&used);
1868 rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BT_USAGE, (u8*)&efuse_usage);
1873 rtw_mfree(efuseTbl, EFUSE_BT_MAP_LEN);
1885 if (efuseType == EFUSE_WIFI)
1886 hal_ReadEFuse_WiFi(padapter, _offset, _size_byte, pbuf, bPseudoTest);
1888 hal_ReadEFuse_BT(padapter, _offset, _size_byte, pbuf, bPseudoTest);
1892 hal_EfuseGetCurrentSize_WiFi(
1896 #ifdef HAL_EFUSE_MEMORY
1897 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
1898 PEFUSE_HAL pEfuseHal = &pHalData->EfuseHal;
1901 u16 start_addr = 0; // for debug
1902 u8 hoffset=0, hworden=0;
1903 u8 efuse_data, word_cnts=0;
1904 u32 count = 0; // for debug
1909 #ifdef HAL_EFUSE_MEMORY
1910 efuse_addr = (u16)pEfuseHal->fakeEfuseUsedBytes;
1912 efuse_addr = (u16)fakeEfuseUsedBytes;
1917 rtw_hal_get_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8*)&efuse_addr);
1919 start_addr = efuse_addr;
1920 DBG_8192C("%s: start_efuse_addr=0x%X\n", __FUNCTION__, efuse_addr);
1922 // switch bank back to bank 0 for later BT and wifi use.
1923 hal_EfuseSwitchToBank(padapter, 0, bPseudoTest);
1925 #if 0 // for debug test
1926 efuse_OneByteRead(padapter, 0x1FF, &efuse_data, bPseudoTest);
1927 DBG_8192C(FUNC_ADPT_FMT ": efuse raw 0x1FF=0x%02X\n",
1928 FUNC_ADPT_ARG(padapter), efuse_data);
1930 #endif // for debug test
1933 while (AVAILABLE_EFUSE_ADDR(efuse_addr))
1936 if (efuse_OneByteRead(padapter, efuse_addr, &efuse_data, bPseudoTest) == _FALSE)
1938 DBG_8192C(KERN_ERR "%s: efuse_OneByteRead Fail! addr=0x%X !!\n", __FUNCTION__, efuse_addr);
1942 ReadEFuseByte(padapter, efuse_addr, &efuse_data, bPseudoTest);
1945 if (efuse_data == 0xFF) break;
1947 if ((start_addr != 0) && (efuse_addr == start_addr))
1950 DBG_8192C(FUNC_ADPT_FMT ": [WARNING] efuse raw 0x%X=0x%02X not 0xFF!!(%d times)\n",
1951 FUNC_ADPT_ARG(padapter), efuse_addr, efuse_data, count);
1960 // try again form address 0
1971 if (EXT_HEADER(efuse_data))
1973 hoffset = GET_HDR_OFFSET_2_0(efuse_data);
1975 efuse_OneByteRead(padapter, efuse_addr, &efuse_data, bPseudoTest);
1976 if (ALL_WORDS_DISABLED(efuse_data))
1981 hoffset |= ((efuse_data & 0xF0) >> 1);
1982 hworden = efuse_data & 0x0F;
1986 hoffset = (efuse_data>>4) & 0x0F;
1987 hworden = efuse_data & 0x0F;
1990 word_cnts = Efuse_CalculateWordCnts(hworden);
1991 efuse_addr += (word_cnts*2)+1;
1996 #ifdef HAL_EFUSE_MEMORY
1997 pEfuseHal->fakeEfuseUsedBytes = efuse_addr;
1999 fakeEfuseUsedBytes = efuse_addr;
2004 rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8*)&efuse_addr);
2010 // report max size to prevent wirte efuse
2011 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &efuse_addr, bPseudoTest);
2014 DBG_8192C("%s: CurrentSize=%d\n", __FUNCTION__, efuse_addr);
2020 hal_EfuseGetCurrentSize_BT(
2024 #ifdef HAL_EFUSE_MEMORY
2025 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
2026 PEFUSE_HAL pEfuseHal = &pHalData->EfuseHal;
2031 u8 hoffset=0, hworden=0;
2032 u8 efuse_data, word_cnts=0;
2034 u8 bContinual = _TRUE;
2039 #ifdef HAL_EFUSE_MEMORY
2040 btusedbytes = pEfuseHal->fakeBTEfuseUsedBytes;
2042 btusedbytes = fakeBTEfuseUsedBytes;
2047 rtw_hal_get_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, (u8*)&btusedbytes);
2049 efuse_addr = (u16)((btusedbytes%EFUSE_BT_REAL_BANK_CONTENT_LEN));
2050 startBank = (u8)(1+(btusedbytes/EFUSE_BT_REAL_BANK_CONTENT_LEN));
2052 DBG_8192C("%s: start from bank=%d addr=0x%X\n", __FUNCTION__, startBank, efuse_addr);
2054 EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_BANK, &retU2, bPseudoTest);
2056 for (bank=startBank; bank<3; bank++)
2058 if (hal_EfuseSwitchToBank(padapter, bank, bPseudoTest) == _FALSE)
2060 DBG_8192C(KERN_ERR "%s: switch bank(%d) Fail!!\n", __FUNCTION__, bank);
2061 //bank = EFUSE_MAX_BANK;
2065 // only when bank is switched we have to reset the efuse_addr.
2066 if (bank != startBank)
2070 while (AVAILABLE_EFUSE_ADDR(efuse_addr))
2072 if (efuse_OneByteRead(padapter, efuse_addr, &efuse_data, bPseudoTest) == _FALSE)
2074 DBG_8192C(KERN_ERR "%s: efuse_OneByteRead Fail! addr=0x%X !!\n", __FUNCTION__, efuse_addr);
2075 //bank = EFUSE_MAX_BANK;
2078 DBG_8192C("%s: efuse_OneByteRead ! addr=0x%X !efuse_data=0x%X! bank =%d\n", __FUNCTION__, efuse_addr,efuse_data,bank);
2080 if (efuse_data == 0xFF) break;
2082 if (EXT_HEADER(efuse_data))
2084 hoffset = GET_HDR_OFFSET_2_0(efuse_data);
2086 efuse_OneByteRead(padapter, efuse_addr, &efuse_data, bPseudoTest);
2087 DBG_8192C("%s: efuse_OneByteRead EXT_HEADER ! addr=0x%X !efuse_data=0x%X! bank =%d\n", __FUNCTION__, efuse_addr,efuse_data,bank);
2089 if (ALL_WORDS_DISABLED(efuse_data))
2095 // hoffset = ((hoffset & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
2096 hoffset |= ((efuse_data & 0xF0) >> 1);
2097 hworden = efuse_data & 0x0F;
2101 hoffset = (efuse_data>>4) & 0x0F;
2102 hworden = efuse_data & 0x0F;
2105 DBG_8192C(FUNC_ADPT_FMT": Offset=%d Worden=%#X\n",
2106 FUNC_ADPT_ARG(padapter), hoffset, hworden);
2108 word_cnts = Efuse_CalculateWordCnts(hworden);
2110 efuse_addr += (word_cnts*2)+1;
2113 while ( bContinual &&
2114 efuse_OneByteRead(padapter, efuse_addr ,&efuse_data, bPseudoTest) &&
2115 AVAILABLE_EFUSE_ADDR(efuse_addr))
2117 if(efuse_data!=0xFF)
2119 if((efuse_data&0x1F) == 0x0F) //extended header
2121 hoffset = efuse_data;
2123 efuse_OneByteRead(padapter, efuse_addr ,&efuse_data, bPseudoTest);
2124 if((efuse_data & 0x0F) == 0x0F)
2131 hoffset = ((hoffset & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
2132 hworden = efuse_data & 0x0F;
2137 hoffset = (efuse_data>>4) & 0x0F;
2138 hworden = efuse_data & 0x0F;
2140 word_cnts = Efuse_CalculateWordCnts(hworden);
2142 efuse_addr = efuse_addr + (word_cnts*2)+1;
2146 bContinual = _FALSE ;
2152 // Check if we need to check next bank efuse
2153 if (efuse_addr < retU2)
2155 break;// don't need to check next bank.
2159 retU2 = ((bank-1)*EFUSE_BT_REAL_BANK_CONTENT_LEN) + efuse_addr;
2162 #ifdef HAL_EFUSE_MEMORY
2163 pEfuseHal->fakeBTEfuseUsedBytes = retU2;
2165 fakeBTEfuseUsedBytes = retU2;
2170 rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, (u8*)&retU2);
2173 retU2 = ((bank-1)*EFUSE_BT_REAL_BANK_CONTENT_LEN)+efuse_addr;
2176 pEfuseHal->fakeBTEfuseUsedBytes = retU2;
2177 //RT_DISP(FEEPROM, EFUSE_PG, ("Hal_EfuseGetCurrentSize_BT92C(), already use %u bytes\n", pEfuseHal->fakeBTEfuseUsedBytes));
2181 pEfuseHal->BTEfuseUsedBytes = retU2;
2182 //RT_DISP(FEEPROM, EFUSE_PG, ("Hal_EfuseGetCurrentSize_BT92C(), already use %u bytes\n", pEfuseHal->BTEfuseUsedBytes));
2186 DBG_8192C("%s: CurrentSize=%d\n", __FUNCTION__, retU2);
2191 Hal_EfuseGetCurrentSize(
2198 if (efuseType == EFUSE_WIFI)
2199 ret = hal_EfuseGetCurrentSize_WiFi(pAdapter, bPseudoTest);
2201 ret = hal_EfuseGetCurrentSize_BT(pAdapter, bPseudoTest);
2207 Hal_EfuseWordEnableDataWrite(
2215 u16 start_addr = efuse_addr;
2216 u8 badworden = 0x0F;
2217 u8 tmpdata[PGPKT_DATA_SIZE];
2220 // DBG_8192C("%s: efuse_addr=%#x word_en=%#x\n", __FUNCTION__, efuse_addr, word_en);
2221 _rtw_memset(tmpdata, 0xFF, PGPKT_DATA_SIZE);
2223 if (!(word_en & BIT(0)))
2225 tmpaddr = start_addr;
2226 efuse_OneByteWrite(padapter, start_addr++, data[0], bPseudoTest);
2227 efuse_OneByteWrite(padapter, start_addr++, data[1], bPseudoTest);
2229 efuse_OneByteRead(padapter, tmpaddr, &tmpdata[0], bPseudoTest);
2230 efuse_OneByteRead(padapter, tmpaddr+1, &tmpdata[1], bPseudoTest);
2231 if ((data[0]!=tmpdata[0]) || (data[1]!=tmpdata[1])) {
2232 badworden &= (~BIT(0));
2235 if (!(word_en & BIT(1)))
2237 tmpaddr = start_addr;
2238 efuse_OneByteWrite(padapter, start_addr++, data[2], bPseudoTest);
2239 efuse_OneByteWrite(padapter, start_addr++, data[3], bPseudoTest);
2241 efuse_OneByteRead(padapter, tmpaddr, &tmpdata[2], bPseudoTest);
2242 efuse_OneByteRead(padapter, tmpaddr+1, &tmpdata[3], bPseudoTest);
2243 if ((data[2]!=tmpdata[2]) || (data[3]!=tmpdata[3])) {
2244 badworden &= (~BIT(1));
2247 if (!(word_en & BIT(2)))
2249 tmpaddr = start_addr;
2250 efuse_OneByteWrite(padapter, start_addr++, data[4], bPseudoTest);
2251 efuse_OneByteWrite(padapter, start_addr++, data[5], bPseudoTest);
2253 efuse_OneByteRead(padapter, tmpaddr, &tmpdata[4], bPseudoTest);
2254 efuse_OneByteRead(padapter, tmpaddr+1, &tmpdata[5], bPseudoTest);
2255 if ((data[4]!=tmpdata[4]) || (data[5]!=tmpdata[5])) {
2256 badworden &= (~BIT(2));
2259 if (!(word_en & BIT(3)))
2261 tmpaddr = start_addr;
2262 efuse_OneByteWrite(padapter, start_addr++, data[6], bPseudoTest);
2263 efuse_OneByteWrite(padapter, start_addr++, data[7], bPseudoTest);
2265 efuse_OneByteRead(padapter, tmpaddr, &tmpdata[6], bPseudoTest);
2266 efuse_OneByteRead(padapter, tmpaddr+1, &tmpdata[7], bPseudoTest);
2267 if ((data[6]!=tmpdata[6]) || (data[7]!=tmpdata[7])) {
2268 badworden &= (~BIT(3));
2276 Hal_EfusePgPacketRead(
2282 u8 bDataEmpty = _TRUE;
2283 u8 efuse_data, word_cnts=0;
2285 u8 hoffset=0, hworden=0;
2294 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAX_SECTION, &max_section, bPseudoTest);
2295 if (offset > max_section)
2297 DBG_8192C("%s: Packet offset(%d) is illegal(>%d)!\n", __FUNCTION__, offset, max_section);
2301 _rtw_memset(data, 0xFF, PGPKT_DATA_SIZE);
2305 // <Roger_TODO> Efuse has been pre-programmed dummy 5Bytes at the end of Efuse by CP.
2306 // Skip dummy parts to prevent unexpected data read from Efuse.
2307 // By pass right now. 2009.02.19.
2309 while (AVAILABLE_EFUSE_ADDR(efuse_addr))
2311 if (efuse_OneByteRead(padapter, efuse_addr++, &efuse_data, bPseudoTest) == _FALSE)
2317 if (efuse_data == 0xFF) break;
2319 if (EXT_HEADER(efuse_data))
2321 hoffset = GET_HDR_OFFSET_2_0(efuse_data);
2322 efuse_OneByteRead(padapter, efuse_addr++, &efuse_data, bPseudoTest);
2323 if (ALL_WORDS_DISABLED(efuse_data))
2325 DBG_8192C("%s: Error!! All words disabled!\n", __FUNCTION__);
2329 hoffset |= ((efuse_data & 0xF0) >> 1);
2330 hworden = efuse_data & 0x0F;
2334 hoffset = (efuse_data>>4) & 0x0F;
2335 hworden = efuse_data & 0x0F;
2338 if (hoffset == offset)
2340 for (i=0; i<EFUSE_MAX_WORD_UNIT; i++)
2342 // Check word enable condition in the section
2343 if (!(hworden & (0x01<<i)))
2345 //ReadEFuseByte(padapter, efuse_addr++, &efuse_data, bPseudoTest);
2346 efuse_OneByteRead(padapter, efuse_addr++, &efuse_data, bPseudoTest);
2347 // DBG_8192C("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, efuse_addr+tmpidx, efuse_data);
2348 data[i*2] = efuse_data;
2350 //ReadEFuseByte(padapter, efuse_addr++, &efuse_data, bPseudoTest);
2351 efuse_OneByteRead(padapter, efuse_addr++, &efuse_data, bPseudoTest);
2352 // DBG_8192C("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, efuse_addr+tmpidx, efuse_data);
2353 data[(i*2)+1] = efuse_data;
2359 word_cnts = Efuse_CalculateWordCnts(hworden);
2360 efuse_addr += word_cnts*2;
2368 hal_EfusePgCheckAvailableAddr(
2373 u16 max_available=0;
2377 EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &max_available, bPseudoTest);
2378 // DBG_8192C("%s: max_available=%d\n", __FUNCTION__, max_available);
2380 current_size = Efuse_GetCurrentSize(pAdapter, efuseType, bPseudoTest);
2381 if (current_size >= max_available)
2383 DBG_8192C("%s: Error!! current_size(%d)>max_available(%d)\n", __FUNCTION__, current_size, max_available);
2390 hal_EfuseConstructPGPkt(
2394 PPGPKT_STRUCT pTargetPkt)
2396 _rtw_memset(pTargetPkt->data, 0xFF, PGPKT_DATA_SIZE);
2397 pTargetPkt->offset = offset;
2398 pTargetPkt->word_en = word_en;
2399 efuse_WordEnableDataRead(word_en, pData, pTargetPkt->data);
2400 pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en);
2406 PPGPKT_STRUCT pTargetPkt,
2407 PPGPKT_STRUCT pCurPkt,
2410 u8 match_word_en = 0x0F; // default all words are disabled
2413 // check if the same words are enabled both target and current PG packet
2414 if (((pTargetPkt->word_en & BIT(0)) == 0) &&
2415 ((pCurPkt->word_en & BIT(0)) == 0))
2417 match_word_en &= ~BIT(0); // enable word 0
2419 if (((pTargetPkt->word_en & BIT(1)) == 0) &&
2420 ((pCurPkt->word_en & BIT(1)) == 0))
2422 match_word_en &= ~BIT(1); // enable word 1
2424 if (((pTargetPkt->word_en & BIT(2)) == 0) &&
2425 ((pCurPkt->word_en & BIT(2)) == 0))
2427 match_word_en &= ~BIT(2); // enable word 2
2429 if (((pTargetPkt->word_en & BIT(3)) == 0) &&
2430 ((pCurPkt->word_en & BIT(3)) == 0))
2432 match_word_en &= ~BIT(3); // enable word 3
2435 *pWden = match_word_en;
2437 if (match_word_en != 0xf)
2444 hal_EfuseCheckIfDatafollowed(
2453 for (i=0; i<(word_cnts*2); i++)
2455 if (efuse_OneByteRead(pAdapter, (startAddr+i) ,&efuse_data, bPseudoTest) == _FALSE)
2457 DBG_8192C("%s: efuse_OneByteRead FAIL!!\n", __FUNCTION__);
2462 if (efuse_data != 0xFF)
2474 hal_EfusePartialWriteCheck(
2478 PPGPKT_STRUCT pTargetPkt,
2481 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
2482 PEFUSE_HAL pEfuseHal = &pHalData->EfuseHal;
2484 u16 startAddr=0, efuse_max_available_len=0, efuse_max=0;
2488 u8 new_wden=0, matched_wden=0, badworden=0;
2489 PGPKT_STRUCT curPkt;
2493 EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &efuse_max_available_len, bPseudoTest);
2494 EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_EFUSE_CONTENT_LEN_BANK, &efuse_max, bPseudoTest);
2496 if (efuseType == EFUSE_WIFI)
2500 #ifdef HAL_EFUSE_MEMORY
2501 startAddr = (u16)pEfuseHal->fakeEfuseUsedBytes;
2503 startAddr = (u16)fakeEfuseUsedBytes;
2508 rtw_hal_get_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8*)&startAddr);
2515 #ifdef HAL_EFUSE_MEMORY
2516 startAddr = (u16)pEfuseHal->fakeBTEfuseUsedBytes;
2518 startAddr = (u16)fakeBTEfuseUsedBytes;
2523 rtw_hal_get_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, (u8*)&startAddr);
2526 startAddr %= efuse_max;
2527 DBG_8192C("%s: startAddr=%#X\n", __FUNCTION__, startAddr);
2531 if (startAddr >= efuse_max_available_len)
2534 DBG_8192C("%s: startAddr(%d) >= efuse_max_available_len(%d)\n",
2535 __FUNCTION__, startAddr, efuse_max_available_len);
2539 if (efuse_OneByteRead(padapter, startAddr, &efuse_data, bPseudoTest) && (efuse_data!=0xFF))
2543 DBG_8192C("%s: Something Wrong! last bytes(%#X=0x%02X) is not 0xFF\n",
2544 __FUNCTION__, startAddr, efuse_data);
2547 if (EXT_HEADER(efuse_data))
2549 cur_header = efuse_data;
2551 efuse_OneByteRead(padapter, startAddr, &efuse_data, bPseudoTest);
2552 if (ALL_WORDS_DISABLED(efuse_data))
2554 DBG_8192C("%s: Error condition, all words disabled!", __FUNCTION__);
2560 curPkt.offset = ((cur_header & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
2561 curPkt.word_en = efuse_data & 0x0F;
2566 cur_header = efuse_data;
2567 curPkt.offset = (cur_header>>4) & 0x0F;
2568 curPkt.word_en = cur_header & 0x0F;
2571 curPkt.word_cnts = Efuse_CalculateWordCnts(curPkt.word_en);
2572 // if same header is found but no data followed
2573 // write some part of data followed by the header.
2574 if ((curPkt.offset == pTargetPkt->offset) &&
2575 (hal_EfuseCheckIfDatafollowed(padapter, curPkt.word_cnts, startAddr+1, bPseudoTest) == _FALSE) &&
2576 wordEnMatched(pTargetPkt, &curPkt, &matched_wden) == _TRUE)
2578 DBG_8192C("%s: Need to partial write data by the previous wrote header\n", __FUNCTION__);
2579 // Here to write partial data
2580 badworden = Efuse_WordEnableDataWrite(padapter, startAddr+1, matched_wden, pTargetPkt->data, bPseudoTest);
2581 if (badworden != 0x0F)
2583 u32 PgWriteSuccess=0;
2584 // if write fail on some words, write these bad words again
2585 if (efuseType == EFUSE_WIFI)
2586 PgWriteSuccess = Efuse_PgPacketWrite(padapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest);
2588 PgWriteSuccess = Efuse_PgPacketWrite_BT(padapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest);
2590 if (!PgWriteSuccess)
2592 bRet = _FALSE; // write fail, return
2596 // partial write ok, update the target packet for later use
2599 if ((matched_wden & (0x1<<i)) == 0) // this word has been written
2601 pTargetPkt->word_en |= (0x1<<i); // disable the word
2604 pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en);
2606 // read from next header
2607 startAddr = startAddr + (curPkt.word_cnts*2) + 1;
2612 // not used header, 0xff
2614 // DBG_8192C("%s: Started from unused header offset=%d\n", __FUNCTION__, startAddr));
2624 hal_EfusePgPacketWrite1ByteHeader(
2628 PPGPKT_STRUCT pTargetPkt,
2632 u8 pg_header=0, tmp_header=0;
2633 u16 efuse_addr=*pAddr;
2637 // DBG_8192C("%s\n", __FUNCTION__);
2638 pg_header = ((pTargetPkt->offset << 4) & 0xf0) | pTargetPkt->word_en;
2641 efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);
2642 efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);
2643 if (tmp_header != 0xFF) break;
2644 if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_)
2646 DBG_8192C("%s: Repeat over limit for pg_header!!\n", __FUNCTION__);
2651 if (tmp_header != pg_header)
2653 DBG_8192C(KERN_ERR "%s: PG Header Fail!!(pg=0x%02X read=0x%02X)\n", __FUNCTION__, pg_header, tmp_header);
2657 *pAddr = efuse_addr;
2663 hal_EfusePgPacketWrite2ByteHeader(
2667 PPGPKT_STRUCT pTargetPkt,
2670 u16 efuse_addr, efuse_max_available_len=0;
2671 u8 pg_header=0, tmp_header=0;
2675 // DBG_8192C("%s\n", __FUNCTION__);
2676 EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_BANK, &efuse_max_available_len, bPseudoTest);
2678 efuse_addr = *pAddr;
2679 if (efuse_addr >= efuse_max_available_len)
2681 DBG_8192C("%s: addr(%d) over avaliable(%d)!!\n", __FUNCTION__, efuse_addr, efuse_max_available_len);
2685 pg_header = ((pTargetPkt->offset & 0x07) << 5) | 0x0F;
2686 // DBG_8192C("%s: pg_header=0x%x\n", __FUNCTION__, pg_header);
2689 efuse_OneByteWrite(padapter, efuse_addr, pg_header, bPseudoTest);
2690 efuse_OneByteRead(padapter, efuse_addr, &tmp_header, bPseudoTest);
2691 if (tmp_header != 0xFF) break;
2692 if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_)
2694 DBG_8192C("%s: Repeat over limit for pg_header!!\n", __FUNCTION__);
2699 if (tmp_header != pg_header)
2701 DBG_8192C(KERN_ERR "%s: PG Header Fail!!(pg=0x%02X read=0x%02X)\n", __FUNCTION__, pg_header, tmp_header);
2705 // to write ext_header
2707 pg_header = ((pTargetPkt->offset & 0x78) << 1) | pTargetPkt->word_en;
2710 efuse_OneByteWrite(padapter, efuse_addr, pg_header, bPseudoTest);
2711 efuse_OneByteRead(padapter, efuse_addr, &tmp_header, bPseudoTest);
2712 if (tmp_header != 0xFF) break;
2713 if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_)
2715 DBG_8192C("%s: Repeat over limit for ext_header!!\n", __FUNCTION__);
2720 if (tmp_header != pg_header) //offset PG fail
2722 DBG_8192C(KERN_ERR "%s: PG EXT Header Fail!!(pg=0x%02X read=0x%02X)\n", __FUNCTION__, pg_header, tmp_header);
2726 *pAddr = efuse_addr;
2732 hal_EfusePgPacketWriteHeader(
2736 PPGPKT_STRUCT pTargetPkt,
2741 if (pTargetPkt->offset >= EFUSE_MAX_SECTION_BASE)
2743 bRet = hal_EfusePgPacketWrite2ByteHeader(padapter, efuseType, pAddr, pTargetPkt, bPseudoTest);
2747 bRet = hal_EfusePgPacketWrite1ByteHeader(padapter, efuseType, pAddr, pTargetPkt, bPseudoTest);
2754 hal_EfusePgPacketWriteData(
2758 PPGPKT_STRUCT pTargetPkt,
2765 efuse_addr = *pAddr;
2766 badworden = Efuse_WordEnableDataWrite(pAdapter, efuse_addr+1, pTargetPkt->word_en, pTargetPkt->data, bPseudoTest);
2767 if (badworden != 0x0F)
2769 DBG_8192C("%s: Fail!!\n", __FUNCTION__);
2773 // DBG_8192C("%s: ok\n", __FUNCTION__);
2778 Hal_EfusePgPacketWrite(
2785 PGPKT_STRUCT targetPkt;
2787 u8 efuseType=EFUSE_WIFI;
2789 if (!hal_EfusePgCheckAvailableAddr(padapter, efuseType, bPseudoTest))
2792 hal_EfuseConstructPGPkt(offset, word_en, pData, &targetPkt);
2794 if (!hal_EfusePartialWriteCheck(padapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2797 if (!hal_EfusePgPacketWriteHeader(padapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2800 if (!hal_EfusePgPacketWriteData(padapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2807 Hal_EfusePgPacketWrite_BT(
2814 PGPKT_STRUCT targetPkt;
2816 u8 efuseType=EFUSE_BT;
2818 if(!hal_EfusePgCheckAvailableAddr(pAdapter, efuseType, bPseudoTest))
2821 hal_EfuseConstructPGPkt(offset, word_en, pData, &targetPkt);
2823 if(!hal_EfusePartialWriteCheck(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2826 if(!hal_EfusePgPacketWriteHeader(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2829 if(!hal_EfusePgPacketWriteData(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2836 ReadChipVersion8723B(
2837 IN PADAPTER padapter
2841 HAL_VERSION ChipVersion;
2842 HAL_DATA_TYPE *pHalData;
2844 //YJ,TODO, move read chip type here
2845 pHalData = GET_HAL_DATA(padapter);
2847 value32 = rtw_read32(padapter, REG_SYS_CFG);
2848 ChipVersion.ICType = CHIP_8723B;
2849 ChipVersion.ChipType = ((value32 & RTL_ID) ? TEST_CHIP : NORMAL_CHIP);
2850 ChipVersion.RFType = RF_TYPE_1T1R ;
2851 ChipVersion.VendorType = ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : CHIP_VENDOR_TSMC);
2852 ChipVersion.CUTVersion = (value32 & CHIP_VER_RTL_MASK)>>CHIP_VER_RTL_SHIFT; // IC version (CUT)
2854 // For regulator mode. by tynli. 2011.01.14
2855 pHalData->RegulatorMode = ((value32 & SPS_SEL) ? RT_LDO_REGULATOR : RT_SWITCHING_REGULATOR);
2857 value32 = rtw_read32(padapter, REG_GPIO_OUTSTS);
2858 ChipVersion.ROMVer = ((value32 & RF_RL_ID) >> 20); // ROM code version.
2860 // For multi-function consideration. Added by Roger, 2010.10.06.
2861 pHalData->MultiFunc = RT_MULTI_FUNC_NONE;
2862 value32 = rtw_read32(padapter, REG_MULTI_FUNC_CTRL);
2863 pHalData->MultiFunc |= ((value32 & WL_FUNC_EN) ? RT_MULTI_FUNC_WIFI : 0);
2864 pHalData->MultiFunc |= ((value32 & BT_FUNC_EN) ? RT_MULTI_FUNC_BT : 0);
2865 pHalData->MultiFunc |= ((value32 & GPS_FUNC_EN) ? RT_MULTI_FUNC_GPS : 0);
2866 pHalData->PolarityCtl = ((value32 & WL_HWPDN_SL) ? RT_POLARITY_HIGH_ACT : RT_POLARITY_LOW_ACT);
2869 dump_chip_info(ChipVersion);
2871 pHalData->VersionID = ChipVersion;
2872 /* // mark for chage to use efuse
2873 if( IS_B_CUT(ChipVersion) || IS_C_CUT(ChipVersion))
2875 MSG_8192C(" IS_B/C_CUT SWR up 1 level !!!!!!!!!!!!!!!!!\n");
2876 PHY_SetMacReg(padapter, 0x14, BIT23|BIT22|BIT21|BIT20, 0x5); //MAC reg 0x14[23:20] = 4b'0101 (SWR 1.220V)
2877 }else if ( IS_D_CUT(ChipVersion))
2879 MSG_8192C(" IS_D_CUT SKIP SWR !!!!!!!!!!!!!!!!!\n");
2882 if (IS_1T2R(ChipVersion))
2883 pHalData->rf_type = RF_1T2R;
2884 else if (IS_2T2R(ChipVersion))
2885 pHalData->rf_type = RF_2T2R;
2887 pHalData->rf_type = RF_1T1R;
2889 MSG_8192C("RF_Type is %x!!\n", pHalData->rf_type);
2895 static void rtl8723b_read_chip_version(PADAPTER padapter)
2897 ReadChipVersion8723B(padapter);
2900 void rtl8723b_InitBeaconParameters(PADAPTER padapter)
2902 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
2908 val16 = val8 | (val8 << 8); // port0 and port1
2909 #ifdef CONFIG_BT_COEXIST
2910 // Enable prot0 beacon function for PSTDMA
2911 val16 |= EN_BCN_FUNCTION;
2913 rtw_write16(padapter, REG_BCN_CTRL, val16);
2915 // TODO: Remove these magic number
2916 rtw_write16(padapter, REG_TBTT_PROHIBIT, 0x6404);// ms
2917 // Firmware will control REG_DRVERLYINT when power saving is enable,
2918 // so don't set this register on STA mode.
2919 if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) == _FALSE)
2920 rtw_write8(padapter, REG_DRVERLYINT, DRIVER_EARLY_INT_TIME_8723B); // 5ms
2921 rtw_write8(padapter, REG_BCNDMATIM, BCN_DMA_ATIME_INT_TIME_8723B); // 2ms
2923 // Suggested by designer timchen. Change beacon AIFS to the largest number
2924 // beacause test chip does not contension before sending beacon. by tynli. 2009.11.03
2925 rtw_write16(padapter, REG_BCNTCFG, 0x660F);
2927 pHalData->RegBcnCtrlVal = rtw_read8(padapter, REG_BCN_CTRL);
2928 pHalData->RegTxPause = rtw_read8(padapter, REG_TXPAUSE);
2929 pHalData->RegFwHwTxQCtrl = rtw_read8(padapter, REG_FWHW_TXQ_CTRL+2);
2930 pHalData->RegReg542 = rtw_read8(padapter, REG_TBTT_PROHIBIT+2);
2931 pHalData->RegCR_1 = rtw_read8(padapter, REG_CR+1);
2934 void rtl8723b_InitBeaconMaxError(PADAPTER padapter, u8 InfraMode)
2936 #ifdef RTL8192CU_ADHOC_WORKAROUND_SETTING
2937 rtw_write8(padapter, REG_BCN_MAX_ERR, 0xFF);
2939 //rtw_write8(Adapter, REG_BCN_MAX_ERR, (InfraMode ? 0xFF : 0x10));
2943 void _InitBurstPktLen_8723BS(PADAPTER Adapter)
2945 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
2947 rtw_write8(Adapter, 0x4c7,rtw_read8(Adapter, 0x4c7)|BIT(7)); //enable single pkt ampdu
2948 rtw_write8(Adapter, REG_RX_PKT_LIMIT_8723B, 0x18); //for VHT packet length 11K
2949 rtw_write8(Adapter, REG_MAX_AGGR_NUM_8723B, 0x1F);
2950 rtw_write8(Adapter, REG_PIFS_8723B, 0x00);
2951 rtw_write8(Adapter, REG_FWHW_TXQ_CTRL_8723B, rtw_read8(Adapter, REG_FWHW_TXQ_CTRL)&(~BIT(7)));
2952 if(pHalData->AMPDUBurstMode)
2954 rtw_write8(Adapter,REG_AMPDU_BURST_MODE_8723B, 0x5F);
2956 rtw_write8(Adapter, REG_AMPDU_MAX_TIME_8723B, 0x70);
2958 // ARFB table 9 for 11ac 5G 2SS
2959 rtw_write32(Adapter, REG_ARFR0_8723B, 0x00000010);
2960 if(IS_NORMAL_CHIP(pHalData->VersionID))
2961 rtw_write32(Adapter, REG_ARFR0_8723B+4, 0xfffff000);
2963 rtw_write32(Adapter, REG_ARFR0_8723B+4, 0x3e0ff000);
2965 // ARFB table 10 for 11ac 5G 1SS
2966 rtw_write32(Adapter, REG_ARFR1_8723B, 0x00000010);
2967 rtw_write32(Adapter, REG_ARFR1_8723B+4, 0x003ff000);
2970 static void ResumeTxBeacon(PADAPTER padapter)
2972 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
2975 // 2010.03.01. Marked by tynli. No need to call workitem beacause we record the value
2976 // which should be read from register to a global variable.
2978 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("+ResumeTxBeacon\n"));
2980 pHalData->RegFwHwTxQCtrl |= BIT(6);
2981 rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, pHalData->RegFwHwTxQCtrl);
2982 rtw_write8(padapter, REG_TBTT_PROHIBIT+1, 0xff);
2983 pHalData->RegReg542 |= BIT(0);
2984 rtw_write8(padapter, REG_TBTT_PROHIBIT+2, pHalData->RegReg542);
2987 static void StopTxBeacon(PADAPTER padapter)
2989 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
2992 // 2010.03.01. Marked by tynli. No need to call workitem beacause we record the value
2993 // which should be read from register to a global variable.
2995 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("+StopTxBeacon\n"));
2997 pHalData->RegFwHwTxQCtrl &= ~BIT(6);
2998 rtw_write8(padapter, REG_FWHW_TXQ_CTRL+2, pHalData->RegFwHwTxQCtrl);
2999 rtw_write8(padapter, REG_TBTT_PROHIBIT+1, 0x64);
3000 pHalData->RegReg542 &= ~BIT(0);
3001 rtw_write8(padapter, REG_TBTT_PROHIBIT+2, pHalData->RegReg542);
3003 CheckFwRsvdPageContent(padapter); // 2010.06.23. Added by tynli.
3006 static void _BeaconFunctionEnable(PADAPTER padapter, u8 Enable, u8 Linked)
3008 rtw_write8(padapter, REG_BCN_CTRL, DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_BCNQ_SUB);
3009 rtw_write8(padapter, REG_RD_CTRL+1, 0x6F);
3012 static void rtl8723b_SetBeaconRelatedRegisters(PADAPTER padapter)
3016 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
3017 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3018 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
3021 //reset TSF, enable update TSF, correcting TSF On Beacon
3029 //REG_BCNTCFG //(0x510)
3031 //REG_BCN_CTRL //(0x550)
3034 bcn_ctrl_reg = REG_BCN_CTRL;
3035 #ifdef CONFIG_CONCURRENT_MODE
3036 if (padapter->iface_type == IFACE_PORT1)
3037 bcn_ctrl_reg = REG_BCN_CTRL_1;
3043 rtw_write16(padapter, REG_ATIMWND, 2);
3046 // Beacon interval (in unit of TU).
3048 rtw_write16(padapter, REG_BCN_INTERVAL, pmlmeinfo->bcn_interval);
3050 rtl8723b_InitBeaconParameters(padapter);
3052 rtw_write8(padapter, REG_SLOT, 0x09);
3055 // Reset TSF Timer to zero, added by Roger. 2008.06.24
3057 value32 = rtw_read32(padapter, REG_TCR);
3059 rtw_write32(padapter, REG_TCR, value32);
3062 rtw_write32(padapter, REG_TCR, value32);
3064 // NOTE: Fix test chip's bug (about contention windows's randomness)
3065 if (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE|WIFI_AP_STATE) == _TRUE)
3067 rtw_write8(padapter, REG_RXTSF_OFFSET_CCK, 0x50);
3068 rtw_write8(padapter, REG_RXTSF_OFFSET_OFDM, 0x50);
3071 _BeaconFunctionEnable(padapter, _TRUE, _TRUE);
3073 ResumeTxBeacon(padapter);
3074 val8 = rtw_read8(padapter, bcn_ctrl_reg);
3075 val8 |= DIS_BCNQ_SUB;
3076 rtw_write8(padapter, bcn_ctrl_reg, val8);
3079 void rtl8723b_GetHalODMVar(
3081 HAL_ODM_VARIABLE eVariable,
3085 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
3086 PDM_ODM_T podmpriv = &pHalData->odmpriv;
3089 GetHalODMVar(Adapter,eVariable,pValue1,pValue2);
3094 void rtl8723b_SetHalODMVar(
3096 HAL_ODM_VARIABLE eVariable,
3100 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
3101 PDM_ODM_T podmpriv = &pHalData->odmpriv;
3104 SetHalODMVar(Adapter,eVariable,pValue1,bSet);
3108 void hal_notch_filter_8723b(_adapter *adapter, bool enable)
3111 DBG_871X("Enable notch filter\n");
3112 rtw_write8(adapter, rOFDM0_RxDSP+1, rtw_read8(adapter, rOFDM0_RxDSP+1) | BIT1);
3114 DBG_871X("Disable notch filter\n");
3115 rtw_write8(adapter, rOFDM0_RxDSP+1, rtw_read8(adapter, rOFDM0_RxDSP+1) & ~BIT1);
3119 u8 rtl8723b_MRateIdxToARFRId(PADAPTER padapter, u8 rate_idx)
3122 RT_RF_TYPE_DEF_E rftype = (RT_RF_TYPE_DEF_E)GET_RF_TYPE(padapter);
3125 case RATR_INX_WIRELESS_NGB:
3126 if(rftype == RF_1T1R)
3132 case RATR_INX_WIRELESS_N:
3133 case RATR_INX_WIRELESS_NG:
3134 if(rftype == RF_1T1R)
3140 case RATR_INX_WIRELESS_NB:
3141 if(rftype == RF_1T1R)
3147 case RATR_INX_WIRELESS_GB:
3151 case RATR_INX_WIRELESS_G:
3155 case RATR_INX_WIRELESS_B:
3159 case RATR_INX_WIRELESS_MC:
3160 if(padapter->mlmeextpriv.cur_wireless_mode & WIRELESS_11BG_24N)
3165 case RATR_INX_WIRELESS_AC_N:
3166 if(rftype == RF_1T1R)// || padapter->MgntInfo.VHTHighestOperaRate <= MGN_VHT1SS_MCS9)
3180 void UpdateHalRAMask8723B(PADAPTER padapter, u32 mac_id, u8 rssi_level)
3182 u32 mask,rate_bitmap;
3183 u8 shortGIrate = _FALSE;
3184 struct sta_info *psta;
3185 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
3186 struct dm_priv *pdmpriv = &pHalData->dmpriv;
3187 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3188 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
3190 DBG_871X("%s(): mac_id=%d rssi_level=%d\n", __func__, mac_id, rssi_level);
3192 if (mac_id >= NUM_STA) //CAM_SIZE
3197 psta = pmlmeinfo->FW_sta_info[mac_id].psta;
3203 shortGIrate = query_ra_short_GI(psta);
3205 mask = psta->ra_mask;
3207 rate_bitmap = 0xffffffff;
3208 rate_bitmap = ODM_Get_Rate_Bitmap(&pHalData->odmpriv,mac_id,mask,rssi_level);
3209 DBG_871X("%s => mac_id:%d, networkType:0x%02x, mask:0x%08x\n\t ==> rssi_level:%d, rate_bitmap:0x%08x\n",
3210 __FUNCTION__,mac_id,psta->wireless_mode,mask,rssi_level,rate_bitmap);
3212 mask &= rate_bitmap;
3214 #ifdef CONFIG_BT_COEXIST
3215 rate_bitmap = rtw_btcoex_GetRaMask(padapter);
3216 mask &= ~rate_bitmap;
3217 #endif // CONFIG_BT_COEXIST
3219 #ifdef CONFIG_CMCC_TEST
3220 #ifdef CONFIG_BT_COEXIST
3221 if(pmlmeext->cur_wireless_mode & WIRELESS_11G) {
3223 DBG_871X("CMCC_BT update raid entry, mask=0x%x\n", mask);
3224 //mask &=0xffffffc0; //disable CCK & <12M OFDM rate for 11G mode for CMCC
3225 mask &=0xffffff00; //disable CCK & <24M OFDM rate for 11G mode for CMCC
3226 DBG_871X("CMCC_BT update raid entry, mask=0x%x\n", mask);
3232 if(pHalData->fw_ractrl == _TRUE)
3234 rtl8723b_set_FwMacIdConfig_cmd(padapter, mac_id, psta->raid, psta->bw_mode, shortGIrate, mask);
3237 //set correct initial date rate for each mac_id
3238 pdmpriv->INIDATA_RATE[mac_id] = psta->init_rate;
3239 DBG_871X("%s(): mac_id=%d raid=0x%x bw=%d mask=0x%x init_rate=0x%x\n", __func__, mac_id, psta->raid, psta->bw_mode, mask, psta->init_rate);
3242 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
3243 void rtl8723b_cal_txdesc_chksum(struct tx_desc *ptxdesc)
3245 u16 *usPtr = (u16*)ptxdesc;
3252 ptxdesc->txdw7 &= cpu_to_le32(0xffff0000);
3254 // checksume is always calculated by first 32 bytes,
3255 // and it doesn't depend on TX DESC length.
3256 // Thomas,Lucas@SD4,20130515
3259 for (index = 0; index < count; index++) {
3260 checksum ^= le16_to_cpu(*(usPtr + index));
3263 ptxdesc->txdw7 |= cpu_to_le32(checksum & 0x0000ffff);
3267 void rtl8723b_set_hal_ops(struct hal_ops *pHalFunc)
3269 pHalFunc->free_hal_data = &rtl8723b_free_hal_data;
3271 pHalFunc->dm_init = &rtl8723b_init_dm_priv;
3272 pHalFunc->dm_deinit = &rtl8723b_deinit_dm_priv;
3274 pHalFunc->read_chip_version = &rtl8723b_read_chip_version;
3276 pHalFunc->UpdateRAMaskHandler = &UpdateHalRAMask8723B;
3278 pHalFunc->set_bwmode_handler = &PHY_SetBWMode8723B;
3279 pHalFunc->set_channel_handler = &PHY_SwChnl8723B;
3280 pHalFunc->set_chnl_bw_handler = &PHY_SetSwChnlBWMode8723B;
3282 pHalFunc->set_tx_power_level_handler = &PHY_SetTxPowerLevel8723B;
3283 pHalFunc->get_tx_power_level_handler = &PHY_GetTxPowerLevel8723B;
3285 pHalFunc->hal_dm_watchdog = &rtl8723b_HalDmWatchDog;
3286 pHalFunc->hal_dm_watchdog_in_lps = &rtl8723b_HalDmWatchDog_in_LPS;
3288 #ifdef CONFIG_C2H_PACKET_EN
3289 pHalFunc->SetHwRegHandlerWithBuf = &SetHwRegWithBuf8723B;
3290 #endif // CONFIG_C2H_PACKET_EN
3292 pHalFunc->SetBeaconRelatedRegistersHandler = &rtl8723b_SetBeaconRelatedRegisters;
3294 pHalFunc->Add_RateATid = &rtl8723b_Add_RateATid;
3296 pHalFunc->run_thread= &rtl8723b_start_thread;
3297 pHalFunc->cancel_thread= &rtl8723b_stop_thread;
3299 pHalFunc->read_bbreg = &PHY_QueryBBReg_8723B;
3300 pHalFunc->write_bbreg = &PHY_SetBBReg_8723B;
3301 pHalFunc->read_rfreg = &PHY_QueryRFReg_8723B;
3302 pHalFunc->write_rfreg = &PHY_SetRFReg_8723B;
3304 // Efuse related function
3305 pHalFunc->BTEfusePowerSwitch = &Hal_BT_EfusePowerSwitch;
3306 pHalFunc->EfusePowerSwitch = &Hal_EfusePowerSwitch;
3307 pHalFunc->ReadEFuse = &Hal_ReadEFuse;
3308 pHalFunc->EFUSEGetEfuseDefinition = &Hal_GetEfuseDefinition;
3309 pHalFunc->EfuseGetCurrentSize = &Hal_EfuseGetCurrentSize;
3310 pHalFunc->Efuse_PgPacketRead = &Hal_EfusePgPacketRead;
3311 pHalFunc->Efuse_PgPacketWrite = &Hal_EfusePgPacketWrite;
3312 pHalFunc->Efuse_WordEnableDataWrite = &Hal_EfuseWordEnableDataWrite;
3313 pHalFunc->Efuse_PgPacketWrite_BT = &Hal_EfusePgPacketWrite_BT;
3315 #ifdef DBG_CONFIG_ERROR_DETECT
3316 pHalFunc->sreset_init_value = &sreset_init_value;
3317 pHalFunc->sreset_reset_value = &sreset_reset_value;
3318 pHalFunc->silentreset = &sreset_reset;
3319 pHalFunc->sreset_xmit_status_check = &rtl8723b_sreset_xmit_status_check;
3320 pHalFunc->sreset_linked_status_check = &rtl8723b_sreset_linked_status_check;
3321 pHalFunc->sreset_get_wifi_status = &sreset_get_wifi_status;
3322 pHalFunc->sreset_inprogress= &sreset_inprogress;
3324 pHalFunc->GetHalODMVarHandler = &rtl8723b_GetHalODMVar;
3325 pHalFunc->SetHalODMVarHandler = &rtl8723b_SetHalODMVar;
3327 #ifdef CONFIG_XMIT_THREAD_MODE
3328 pHalFunc->xmit_thread_handler = &hal_xmit_handler;
3330 pHalFunc->hal_notch_filter = &hal_notch_filter_8723b;
3332 pHalFunc->c2h_handler = c2h_handler_8723b;
3333 pHalFunc->c2h_id_filter_ccx = c2h_id_filter_ccx_8723b;
3335 pHalFunc->fill_h2c_cmd = &FillH2CCmd8723B;
3336 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
3337 pHalFunc->hal_cal_txdesc_chksum = &rtl8723b_cal_txdesc_chksum;
3339 #ifdef CONFIG_WOWLAN
3340 pHalFunc->hal_set_wowlan_fw = &SetFwRelatedForWoWLAN8723b;
3342 pHalFunc->hal_get_tx_buff_rsvd_page_num = &GetTxBufferRsvdPageNum8723B;
3345 void rtl8723b_InitAntenna_Selection(PADAPTER padapter)
3347 PHAL_DATA_TYPE pHalData;
3351 pHalData = GET_HAL_DATA(padapter);
3353 val = rtw_read8(padapter, REG_LEDCFG2);
3354 // Let 8051 take control antenna settting
3355 val |= BIT(7); // DPDT_SEL_EN, 0x4C[23]
3356 rtw_write8(padapter, REG_LEDCFG2, val);
3359 void rtl8723b_CheckAntenna_Selection(PADAPTER padapter)
3361 PHAL_DATA_TYPE pHalData;
3365 pHalData = GET_HAL_DATA(padapter);
3367 val = rtw_read8(padapter, REG_LEDCFG2);
3368 // Let 8051 take control antenna settting
3370 val |= BIT(7); // DPDT_SEL_EN, 0x4C[23]
3371 rtw_write8(padapter, REG_LEDCFG2, val);
3374 void rtl8723b_DeinitAntenna_Selection(PADAPTER padapter)
3376 PHAL_DATA_TYPE pHalData;
3380 pHalData = GET_HAL_DATA(padapter);
3381 val = rtw_read8(padapter, REG_LEDCFG2);
3382 // Let 8051 take control antenna settting
3383 val &= ~BIT(7); // DPDT_SEL_EN, clear 0x4C[23]
3384 rtw_write8(padapter, REG_LEDCFG2, val);
3388 void rtl8723b_init_default_value(PADAPTER padapter)
3390 PHAL_DATA_TYPE pHalData;
3391 struct dm_priv *pdmpriv;
3395 pHalData = GET_HAL_DATA(padapter);
3396 pdmpriv = &pHalData->dmpriv;
3398 padapter->registrypriv.wireless_mode = WIRELESS_11BG_24N;
3400 // init default value
3401 pHalData->fw_ractrl = _FALSE;
3402 pHalData->bIQKInitialized = _FALSE;
3403 if (!adapter_to_pwrctl(padapter)->bkeepfwalive)
3404 pHalData->LastHMEBoxNum = 0;
3406 /* hal capability values */
3407 pHalData->macid_num = MACID_NUM_8723B;
3408 pHalData->cam_entry_num = CAM_ENTRY_NUM_8723B;
3410 // init dm default value
3411 pdmpriv->TM_Trigger = 0;//for IQK
3412 // pdmpriv->binitialized = _FALSE;
3413 // pdmpriv->prv_traffic_idx = 3;
3414 // pdmpriv->initialize = 0;
3416 pdmpriv->ThermalValue_HP_index = 0;
3417 for (i=0; i<HP_THERMAL_NUM; i++)
3418 pdmpriv->ThermalValue_HP[i] = 0;
3420 // init Efuse variables
3421 pHalData->EfuseUsedBytes = 0;
3422 pHalData->EfuseUsedPercentage = 0;
3423 #ifdef HAL_EFUSE_MEMORY
3424 pHalData->EfuseHal.fakeEfuseBank = 0;
3425 pHalData->EfuseHal.fakeEfuseUsedBytes = 0;
3426 _rtw_memset(pHalData->EfuseHal.fakeEfuseContent, 0xFF, EFUSE_MAX_HW_SIZE);
3427 _rtw_memset(pHalData->EfuseHal.fakeEfuseInitMap, 0xFF, EFUSE_MAX_MAP_LEN);
3428 _rtw_memset(pHalData->EfuseHal.fakeEfuseModifiedMap, 0xFF, EFUSE_MAX_MAP_LEN);
3429 pHalData->EfuseHal.BTEfuseUsedBytes = 0;
3430 pHalData->EfuseHal.BTEfuseUsedPercentage = 0;
3431 _rtw_memset(pHalData->EfuseHal.BTEfuseContent, 0xFF, EFUSE_MAX_BT_BANK*EFUSE_MAX_HW_SIZE);
3432 _rtw_memset(pHalData->EfuseHal.BTEfuseInitMap, 0xFF, EFUSE_BT_MAX_MAP_LEN);
3433 _rtw_memset(pHalData->EfuseHal.BTEfuseModifiedMap, 0xFF, EFUSE_BT_MAX_MAP_LEN);
3434 pHalData->EfuseHal.fakeBTEfuseUsedBytes = 0;
3435 _rtw_memset(pHalData->EfuseHal.fakeBTEfuseContent, 0xFF, EFUSE_MAX_BT_BANK*EFUSE_MAX_HW_SIZE);
3436 _rtw_memset(pHalData->EfuseHal.fakeBTEfuseInitMap, 0xFF, EFUSE_BT_MAX_MAP_LEN);
3437 _rtw_memset(pHalData->EfuseHal.fakeBTEfuseModifiedMap, 0xFF, EFUSE_BT_MAX_MAP_LEN);
3441 u8 GetEEPROMSize8723B(PADAPTER padapter)
3446 cr = rtw_read16(padapter, REG_9346CR);
3447 // 6: EEPROM used is 93C46, 4: boot from E-Fuse.
3448 size = (cr & BOOT_FROM_EEPROM) ? 6 : 4;
3450 MSG_8192C("EEPROM type is %s\n", size==4 ? "E-FUSE" : "93C46");
3455 //-------------------------------------------------------------------------
3457 // LLT R/W/Init function
3459 //-------------------------------------------------------------------------
3460 s32 rtl8723b_InitLLTTable(PADAPTER padapter)
3462 u32 start, passing_time;
3469 val32 = rtw_read32(padapter, REG_AUTO_LLT);
3470 val32 |= BIT_AUTO_INIT_LLT;
3471 rtw_write32(padapter, REG_AUTO_LLT, val32);
3473 start = rtw_get_current_time();
3476 val32 = rtw_read32(padapter, REG_AUTO_LLT);
3477 if (!(val32 & BIT_AUTO_INIT_LLT))
3483 passing_time = rtw_get_passing_time_ms(start);
3484 if (passing_time > 1000)
3486 DBG_8192C("%s: FAIL!! REG_AUTO_LLT(0x%X)=%08x\n",
3487 __FUNCTION__, REG_AUTO_LLT, val32);
3497 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
3498 void _DisableGPIO(PADAPTER padapter)
3500 /***************************************
3501 j. GPIO_PIN_CTRL 0x44[31:0]=0x000 //
3502 k.Value = GPIO_PIN_CTRL[7:0]
3503 l. GPIO_PIN_CTRL 0x44[31:0] = 0x00FF0000 | (value <<8); //write external PIN level
3504 m. GPIO_MUXCFG 0x42 [15:0] = 0x0780
3505 n. LEDCFG 0x4C[15:0] = 0x8080
3506 ***************************************/
3513 //1. Disable GPIO[7:0]
3514 rtw_write16(padapter, REG_GPIO_PIN_CTRL+2, 0x0000);
3515 value32 = rtw_read32(padapter, REG_GPIO_PIN_CTRL) & 0xFFFF00FF;
3516 u4bTmp = value32 & 0x000000FF;
3517 value32 |= ((u4bTmp<<8) | 0x00FF0000);
3518 rtw_write32(padapter, REG_GPIO_PIN_CTRL, value32);
3520 if (IS_HARDWARE_TYPE_8723AU(padapter) ||
3521 IS_HARDWARE_TYPE_8723AS(padapter))
3524 // <Roger_Notes> For RTL8723u multi-function configuration which was autoload from Efuse offset 0x0a and 0x0b,
3525 // WLAN HW GPIO[9], GPS HW GPIO[10] and BT HW GPIO[11].
3526 // Added by Roger, 2010.10.07.
3528 //2. Disable GPIO[8] and GPIO[12]
3529 rtw_write16(padapter, REG_GPIO_IO_SEL_2, 0x0000); // Configure all pins as input mode.
3530 value32 = rtw_read32(padapter, REG_GPIO_PIN_CTRL_2) & 0xFFFF001F;
3531 u4bTmp = value32 & 0x0000001F;
3532 // if( IS_MULTI_FUNC_CHIP(padapter) )
3533 // value32 |= ((u4bTmp<<8) | 0x00110000); // Set pin 8 and pin 12 to output mode.
3535 value32 |= ((u4bTmp<<8) | 0x001D0000); // Set pin 8, 10, 11 and pin 12 to output mode.
3536 rtw_write32(padapter, REG_GPIO_PIN_CTRL_2, value32);
3540 //2. Disable GPIO[10:8]
3541 rtw_write8(padapter, REG_MAC_PINMUX_CFG, 0x00);
3542 value16 = rtw_read16(padapter, REG_GPIO_IO_SEL) & 0xFF0F;
3543 value8 = (u8) (value16&0x000F);
3544 value16 |= ((value8<<4) | 0x0780);
3545 rtw_write16(padapter, REG_GPIO_IO_SEL, value16);
3548 //3. Disable LED0 & 1
3549 if(IS_HARDWARE_TYPE_8192DU(padapter))
3551 rtw_write16(padapter, REG_LEDCFG0, 0x8888);
3555 rtw_write16(padapter, REG_LEDCFG0, 0x8080);
3557 // RT_TRACE(COMP_INIT, DBG_LOUD, ("======> Disable GPIO and LED.\n"));
3558 } //end of _DisableGPIO()
3560 void _DisableRFAFEAndResetBB8192C(PADAPTER padapter)
3562 /**************************************
3563 a. TXPAUSE 0x522[7:0] = 0xFF //Pause MAC TX queue
3564 b. RF path 0 offset 0x00 = 0x00 // disable RF
3565 c. APSD_CTRL 0x600[7:0] = 0x40
3566 d. SYS_FUNC_EN 0x02[7:0] = 0x16 //reset BB state machine
3567 e. SYS_FUNC_EN 0x02[7:0] = 0x14 //reset BB state machine
3568 ***************************************/
3569 u8 eRFPath = 0, value8 = 0;
3571 rtw_write8(padapter, REG_TXPAUSE, 0xFF);
3573 PHY_SetRFReg(padapter, (RF_PATH)eRFPath, 0x0, bMaskByte0, 0x0);
3576 rtw_write8(padapter, REG_APSD_CTRL, value8);//0x40
3578 // Set BB reset at first
3580 value8 |= (FEN_USBD | FEN_USBA | FEN_BB_GLB_RSTn);
3581 rtw_write8(padapter, REG_SYS_FUNC_EN, value8 );//0x16
3583 // Set global reset.
3584 value8 &= ~FEN_BB_GLB_RSTn;
3585 rtw_write8(padapter, REG_SYS_FUNC_EN, value8); //0x14
3587 // 2010/08/12 MH We need to set BB/GLBAL reset to save power for SS mode.
3589 // RT_TRACE(COMP_INIT, DBG_LOUD, ("======> RF off and reset BB.\n"));
3592 void _DisableRFAFEAndResetBB(PADAPTER padapter)
3595 if (IS_HARDWARE_TYPE_8192D(padapter))
3596 _DisableRFAFEAndResetBB8192D(padapter);
3599 _DisableRFAFEAndResetBB8192C(padapter);
3602 void _ResetDigitalProcedure1_92C(PADAPTER padapter, BOOLEAN bWithoutHWSM)
3604 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
3606 if (IS_FW_81xxC(padapter) && (pHalData->FirmwareVersion <= 0x20))
3609 /*****************************
3610 f. SYS_FUNC_EN 0x03[7:0]=0x54 // reset MAC register, DCORE
3611 g. MCUFWDL 0x80[7:0]=0 // reset MCU ready status
3612 ******************************/
3614 rtw_write8(padapter, REG_SYS_FUNC_EN+1, 0x54);
3615 rtw_write8(padapter, REG_MCUFWDL, 0);
3617 /*****************************
3618 f. MCUFWDL 0x80[7:0]=0 // reset MCU ready status
3619 g. SYS_FUNC_EN 0x02[10]= 0 // reset MCU register, (8051 reset)
3620 h. SYS_FUNC_EN 0x02[15-12]= 5 // reset MAC register, DCORE
3621 i. SYS_FUNC_EN 0x02[10]= 1 // enable MCU register, (8051 enable)
3622 ******************************/
3624 rtw_write8(padapter, REG_MCUFWDL, 0);
3626 valu16 = rtw_read16(padapter, REG_SYS_FUNC_EN);
3627 rtw_write16(padapter, REG_SYS_FUNC_EN, (valu16 & (~FEN_CPUEN)));//reset MCU ,8051
3629 valu16 = rtw_read16(padapter, REG_SYS_FUNC_EN)&0x0FFF;
3630 rtw_write16(padapter, REG_SYS_FUNC_EN, (valu16 |(FEN_HWPDN|FEN_ELDR)));//reset MAC
3632 valu16 = rtw_read16(padapter, REG_SYS_FUNC_EN);
3633 rtw_write16(padapter, REG_SYS_FUNC_EN, (valu16 | FEN_CPUEN));//enable MCU ,8051
3640 // 2010/08/12 MH For USB SS, we can not stop 8051 when we are trying to
3641 // enter IPS/HW&SW radio off. For S3/S4/S5/Disable, we can stop 8051 because
3642 // we will init FW when power on again.
3643 //if(!pDevice->RegUsbSS)
3644 { // If we want to SS mode, we can not reset 8051.
3645 if(rtw_read8(padapter, REG_MCUFWDL) & BIT1)
3646 { //IF fw in RAM code, do reset
3649 if(padapter->bFWReady)
3651 // 2010/08/25 MH Accordign to RD alfred's suggestion, we need to disable other
3652 // HRCV INT to influence 8051 reset.
3653 rtw_write8(padapter, REG_FWIMR, 0x20);
3654 // 2011/02/15 MH According to Alex's suggestion, close mask to prevent incorrect FW write operation.
3655 rtw_write8(padapter, REG_FTIMR, 0x00);
3656 rtw_write8(padapter, REG_FSIMR, 0x00);
3658 rtw_write8(padapter, REG_HMETFR+3, 0x20);//8051 reset by self
3660 while( (retry_cnts++ <100) && (FEN_CPUEN &rtw_read16(padapter, REG_SYS_FUNC_EN)))
3662 rtw_udelay_os(50);//us
3663 // 2010/08/25 For test only We keep on reset 5051 to prevent fail.
3664 //rtw_write8(padapter, REG_HMETFR+3, 0x20);//8051 reset by self
3666 // RT_ASSERT((retry_cnts < 100), ("8051 reset failed!\n"));
3668 if (retry_cnts >= 100)
3670 // if 8051 reset fail we trigger GPIO 0 for LA
3671 //rtw_write32( padapter,
3672 // REG_GPIO_PIN_CTRL,
3674 // 2010/08/31 MH According to Filen's info, if 8051 reset fail, reset MAC directly.
3675 rtw_write8(padapter, REG_SYS_FUNC_EN+1, 0x50); //Reset MAC and Enable 8051
3679 // RT_TRACE(COMP_INIT, DBG_LOUD, ("=====> 8051 reset success (%d) .\n",retry_cnts));
3684 // RT_TRACE(COMP_INIT, DBG_LOUD, ("=====> 8051 in ROM.\n"));
3686 rtw_write8(padapter, REG_SYS_FUNC_EN+1, 0x54); //Reset MAC and Enable 8051
3687 rtw_write8(padapter, REG_MCUFWDL, 0);
3691 //if(pDevice->RegUsbSS)
3692 //bWithoutHWSM = TRUE; // Sugest by Filen and Issau.
3696 //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
3697 /*****************************
3698 Without HW auto state machine
3699 g. SYS_CLKR 0x08[15:0] = 0x30A3 //disable MAC clock
3700 h. AFE_PLL_CTRL 0x28[7:0] = 0x80 //disable AFE PLL
3701 i. AFE_XTAL_CTRL 0x24[15:0] = 0x880F //gated AFE DIG_CLOCK
3702 j. SYS_ISO_CTRL 0x00[7:0] = 0xF9 // isolated digital to PON
3703 ******************************/
3704 //rtw_write16(padapter, REG_SYS_CLKR, 0x30A3);
3705 //if(!pDevice->RegUsbSS)
3706 // 2011/01/26 MH SD4 Scott suggest to fix UNC-B cut bug.
3707 //if (IS_81xxC_VENDOR_UMC_B_CUT(pHalData->VersionID))
3708 //rtw_write16(padapter, REG_SYS_CLKR, (0x70A3|BIT6)); //modify to 0x70A3 by Scott.
3710 rtw_write16(padapter, REG_SYS_CLKR, 0x70A3); //modify to 0x70A3 by Scott.
3711 rtw_write8(padapter, REG_AFE_PLL_CTRL, 0x80);
3712 rtw_write16(padapter, REG_AFE_XTAL_CTRL, 0x880F);
3713 //if(!pDevice->RegUsbSS)
3714 rtw_write8(padapter, REG_SYS_ISO_CTRL, 0xF9);
3718 // Disable all RF/BB power
3719 rtw_write8(padapter, REG_RF_CTRL, 0x00);
3721 // RT_TRACE(COMP_INIT, DBG_LOUD, ("======> Reset Digital.\n"));
3725 void _ResetDigitalProcedure1(PADAPTER padapter, BOOLEAN bWithoutHWSM)
3728 if(IS_HARDWARE_TYPE_8192D(padapter))
3729 _ResetDigitalProcedure1_92D(padapter, bWithoutHWSM);
3732 _ResetDigitalProcedure1_92C(padapter, bWithoutHWSM);
3735 void _ResetDigitalProcedure2(PADAPTER padapter)
3737 //HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
3738 /*****************************
3739 k. SYS_FUNC_EN 0x03[7:0] = 0x44 // disable ELDR runction
3740 l. SYS_CLKR 0x08[15:0] = 0x3083 // disable ELDR clock
3741 m. SYS_ISO_CTRL 0x01[7:0] = 0x83 // isolated ELDR to PON
3742 ******************************/
3743 //rtw_write8(padapter, REG_SYS_FUNC_EN+1, 0x44); //marked by Scott.
3744 // 2011/01/26 MH SD4 Scott suggest to fix UNC-B cut bug.
3745 //if (IS_81xxC_VENDOR_UMC_B_CUT(pHalData->VersionID))
3746 //rtw_write16(padapter, REG_SYS_CLKR, 0x70a3|BIT6);
3748 rtw_write16(padapter, REG_SYS_CLKR, 0x70a3); //modify to 0x70a3 by Scott.
3749 rtw_write8(padapter, REG_SYS_ISO_CTRL+1, 0x82); //modify to 0x82 by Scott.
3752 void _DisableAnalog(PADAPTER padapter, BOOLEAN bWithoutHWSM)
3754 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
3761 /*****************************
3762 n. LDOA15_CTRL 0x20[7:0] = 0x04 // disable A15 power
3763 o. LDOV12D_CTRL 0x21[7:0] = 0x54 // disable digital core power
3764 r. When driver call disable, the ASIC will turn off remaining clock automatically
3765 ******************************/
3767 rtw_write8(padapter, REG_LDOA15_CTRL, 0x04);
3768 //rtw_write8(padapter, REG_LDOV12D_CTRL, 0x54);
3770 value8 = rtw_read8(padapter, REG_LDOV12D_CTRL);
3771 value8 &= (~LDV12_EN);
3772 rtw_write8(padapter, REG_LDOV12D_CTRL, value8);
3773 // RT_TRACE(COMP_INIT, DBG_LOUD, (" REG_LDOV12D_CTRL Reg0x21:0x%02x.\n",value8));
3776 /*****************************
3777 h. SPS0_CTRL 0x11[7:0] = 0x23 //enter PFM mode
3778 i. APS_FSMCO 0x04[15:0] = 0x4802 // set USB suspend
3779 ******************************/
3781 if (IS_81xxC_VENDOR_UMC_B_CUT(pHalData->VersionID))
3784 rtw_write8(padapter, REG_SPS0_CTRL, value8);
3788 //value16 |= (APDM_HOST | /*AFSM_HSUS |*/PFM_ALDN);
3789 // 2010/08/31 According to Filen description, we need to use HW to shut down 8051 automatically.
3790 // Becasue suspend operatione need the asistance of 8051 to wait for 3ms.
3791 value16 |= (APDM_HOST | AFSM_HSUS | PFM_ALDN);
3795 value16 |= (APDM_HOST | AFSM_HSUS | PFM_ALDN);
3798 rtw_write16(padapter, REG_APS_FSMCO, value16);//0x4802
3800 rtw_write8(padapter, REG_RSV_CTRL, 0x0e);
3803 //tynli_test for suspend mode.
3805 rtw_write8(padapter, 0xfe10, 0x19);
3809 // RT_TRACE(COMP_INIT, DBG_LOUD, ("======> Disable Analog Reg0x04:0x%04x.\n",value16));
3812 // HW Auto state machine
3813 s32 CardDisableHWSM(PADAPTER padapter, u8 resetMCU)
3815 int rtStatus = _SUCCESS;
3818 if (padapter->bSurpriseRemoved){
3821 //==== RF Off Sequence ====
3822 _DisableRFAFEAndResetBB(padapter);
3824 // ==== Reset digital sequence ======
3825 _ResetDigitalProcedure1(padapter, _FALSE);
3827 // ==== Pull GPIO PIN to balance level and LED control ======
3828 _DisableGPIO(padapter);
3830 // ==== Disable analog sequence ===
3831 _DisableAnalog(padapter, _FALSE);
3833 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("======> Card disable finished.\n"));
3838 // without HW Auto state machine
3839 s32 CardDisableWithoutHWSM(PADAPTER padapter)
3841 s32 rtStatus = _SUCCESS;
3844 //RT_TRACE(COMP_INIT, DBG_LOUD, ("======> Card Disable Without HWSM .\n"));
3845 if (padapter->bSurpriseRemoved) {
3849 //==== RF Off Sequence ====
3850 _DisableRFAFEAndResetBB(padapter);
3852 // ==== Reset digital sequence ======
3853 _ResetDigitalProcedure1(padapter, _TRUE);
3855 // ==== Pull GPIO PIN to balance level and LED control ======
3856 _DisableGPIO(padapter);
3858 // ==== Reset digital sequence ======
3859 _ResetDigitalProcedure2(padapter);
3861 // ==== Disable analog sequence ===
3862 _DisableAnalog(padapter, _TRUE);
3864 //RT_TRACE(COMP_INIT, DBG_LOUD, ("<====== Card Disable Without HWSM .\n"));
3867 #endif // CONFIG_USB_HCI || CONFIG_SDIO_HCI || CONFIG_GSPI_HCI
3870 Hal_GetChnlGroup8723B(
3875 BOOLEAN bIn24G=TRUE;
3881 if (1 <= Channel && Channel <= 2 ) *pGroup = 0;
3882 else if (3 <= Channel && Channel <= 5 ) *pGroup = 1;
3883 else if (6 <= Channel && Channel <= 8 ) *pGroup = 2;
3884 else if (9 <= Channel && Channel <= 11) *pGroup = 3;
3885 else if (12 <= Channel && Channel <= 14) *pGroup = 4;
3888 RT_TRACE(_module_hci_hal_init_c_, _drv_notice_,("==>Hal_GetChnlGroup8723B in 2.4 G, but Channel %d in Group not found \n", Channel));
3895 if (36 <= Channel && Channel <= 42) *pGroup = 0;
3896 else if (44 <= Channel && Channel <= 48) *pGroup = 1;
3897 else if (50 <= Channel && Channel <= 58) *pGroup = 2;
3898 else if (60 <= Channel && Channel <= 64) *pGroup = 3;
3899 else if (100 <= Channel && Channel <= 106) *pGroup = 4;
3900 else if (108 <= Channel && Channel <= 114) *pGroup = 5;
3901 else if (116 <= Channel && Channel <= 122) *pGroup = 6;
3902 else if (124 <= Channel && Channel <= 130) *pGroup = 7;
3903 else if (132 <= Channel && Channel <= 138) *pGroup = 8;
3904 else if (140 <= Channel && Channel <= 144) *pGroup = 9;
3905 else if (149 <= Channel && Channel <= 155) *pGroup = 10;
3906 else if (157 <= Channel && Channel <= 161) *pGroup = 11;
3907 else if (165 <= Channel && Channel <= 171) *pGroup = 12;
3908 else if (173 <= Channel && Channel <= 177) *pGroup = 13;
3911 RT_TRACE(_module_hci_hal_init_c_, _drv_notice_,("==>Hal_GetChnlGroup8723B in 5G, but Channel %d in Group not found \n",Channel));
3915 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("<==Hal_GetChnlGroup8723B, (%s) Channel = %d, Group =%d,\n",
3916 (bIn24G) ? "2.4G" : "5G", Channel, *pGroup));
3925 EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
3926 // HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
3930 if(_FALSE == pEEPROM->bautoload_fail_flag)
3932 // if (IS_BOOT_FROM_EEPROM(padapter))
3933 if (_TRUE == pEEPROM->EepromOrEfuse)
3935 // Read all Content from EEPROM or EFUSE.
3936 for(i = 0; i < HWSET_MAX_SIZE_8723B; i += 2)
3938 // value16 = EF2Byte(ReadEEprom(pAdapter, (u2Byte) (i>>1)));
3939 // *((u16*)(&PROMContent[i])) = value16;
3944 // Read EFUSE real map to shadow.
3945 EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, _FALSE);
3946 _rtw_memcpy((void*)PROMContent, (void*)pEEPROM->efuse_eeprom_data, HWSET_MAX_SIZE_8723B);
3951 RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("AutoLoad Fail reported from CR9346!!\n"));
3952 // pHalData->AutoloadFailFlag = _TRUE;
3953 //update to default value 0xFF
3954 if (_FALSE == pEEPROM->EepromOrEfuse)
3955 EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, _FALSE);
3956 _rtw_memcpy((void*)PROMContent, (void*)pEEPROM->efuse_eeprom_data, HWSET_MAX_SIZE_8723B);
3961 Hal_EfuseParseIDCode(
3962 IN PADAPTER padapter,
3966 EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
3967 // HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
3971 // Checl 0x8129 again for making sure autoload status!!
3972 EEPROMId = le16_to_cpu(*((u16*)hwinfo));
3973 if (EEPROMId != RTL_EEPROM_ID)
3975 DBG_8192C("EEPROM ID(%#x) is invalid!!\n", EEPROMId);
3976 pEEPROM->bautoload_fail_flag = _TRUE;
3980 pEEPROM->bautoload_fail_flag = _FALSE;
3983 RT_TRACE(_module_hal_init_c_, _drv_notice_, ("EEPROM ID=0x%04x\n", EEPROMId));
3998 pIn = (u8*)pInValue;
3999 pOut = (u8*)pOutValue;
4006 RT_TRACE(_module_hci_hal_init_c_, _drv_err_, ("EETYPE_TX_PWR, value=%d is invalid, set to default=0x%x\n",
4007 *pIn, EEPROM_Default_TxPowerLevel));
4008 *pOut = EEPROM_Default_TxPowerLevel;
4024 if (chnl < 3) // Cjanel 1-3
4026 else if (chnl < 9) // Channel 4-9
4028 else // Channel 10-14
4035 Hal_ReadPowerValueFromPROM_8723B(
4036 IN PADAPTER Adapter,
4037 IN PTxPowerInfo24G pwrInfo24G,
4038 IN u8 * PROMContent,
4039 IN BOOLEAN AutoLoadFail
4042 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
4043 u4Byte rfPath, eeAddr=EEPROM_TX_PWR_INX_8723B, group,TxCount=0;
4045 _rtw_memset(pwrInfo24G, 0, sizeof(TxPowerInfo24G));
4047 if(0xFF == PROMContent[eeAddr+1])
4048 AutoLoadFail = TRUE;
4052 DBG_871X("%s(): Use Default value!\n", __func__);
4053 for(rfPath = 0 ; rfPath < MAX_RF_PATH ; rfPath++)
4055 //2.4G default value
4056 for(group = 0 ; group < MAX_CHNL_GROUP_24G; group++)
4058 pwrInfo24G->IndexCCK_Base[rfPath][group] = EEPROM_DEFAULT_24G_INDEX;
4059 pwrInfo24G->IndexBW40_Base[rfPath][group] = EEPROM_DEFAULT_24G_INDEX;
4061 for(TxCount=0;TxCount<MAX_TX_COUNT;TxCount++)
4065 pwrInfo24G->BW20_Diff[rfPath][0] = EEPROM_DEFAULT_24G_HT20_DIFF;
4066 pwrInfo24G->OFDM_Diff[rfPath][0] = EEPROM_DEFAULT_24G_OFDM_DIFF;
4070 pwrInfo24G->BW20_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
4071 pwrInfo24G->BW40_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
4072 pwrInfo24G->CCK_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
4073 pwrInfo24G->OFDM_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
4081 pHalData->bTXPowerDataReadFromEEPORM = TRUE; //YJ,move,120316
4083 for(rfPath = 0 ; rfPath < MAX_RF_PATH ; rfPath++)
4085 //2 2.4G default value
4086 for(group = 0 ; group < MAX_CHNL_GROUP_24G; group++)
4088 pwrInfo24G->IndexCCK_Base[rfPath][group] = PROMContent[eeAddr++];
4089 if(pwrInfo24G->IndexCCK_Base[rfPath][group] == 0xFF)
4091 pwrInfo24G->IndexCCK_Base[rfPath][group] = EEPROM_DEFAULT_24G_INDEX;
4094 for(group = 0 ; group < MAX_CHNL_GROUP_24G-1; group++)
4096 pwrInfo24G->IndexBW40_Base[rfPath][group] = PROMContent[eeAddr++];
4097 if(pwrInfo24G->IndexBW40_Base[rfPath][group] == 0xFF)
4098 pwrInfo24G->IndexBW40_Base[rfPath][group] = EEPROM_DEFAULT_24G_INDEX;
4100 for(TxCount=0;TxCount<MAX_TX_COUNT;TxCount++)
4104 pwrInfo24G->BW40_Diff[rfPath][TxCount] = 0;
4105 if(PROMContent[eeAddr] == 0xFF)
4106 pwrInfo24G->BW20_Diff[rfPath][TxCount] = EEPROM_DEFAULT_24G_HT20_DIFF;
4109 pwrInfo24G->BW20_Diff[rfPath][TxCount] = (PROMContent[eeAddr]&0xf0)>>4;
4110 if(pwrInfo24G->BW20_Diff[rfPath][TxCount] & BIT3) //4bit sign number to 8 bit sign number
4111 pwrInfo24G->BW20_Diff[rfPath][TxCount] |= 0xF0;
4114 if(PROMContent[eeAddr] == 0xFF)
4115 pwrInfo24G->OFDM_Diff[rfPath][TxCount] = EEPROM_DEFAULT_24G_OFDM_DIFF;
4118 pwrInfo24G->OFDM_Diff[rfPath][TxCount] = (PROMContent[eeAddr]&0x0f);
4119 if(pwrInfo24G->OFDM_Diff[rfPath][TxCount] & BIT3) //4bit sign number to 8 bit sign number
4120 pwrInfo24G->OFDM_Diff[rfPath][TxCount] |= 0xF0;
4122 pwrInfo24G->CCK_Diff[rfPath][TxCount] = 0;
4127 if(PROMContent[eeAddr] == 0xFF)
4128 pwrInfo24G->BW40_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
4131 pwrInfo24G->BW40_Diff[rfPath][TxCount] = (PROMContent[eeAddr]&0xf0)>>4;
4132 if(pwrInfo24G->BW40_Diff[rfPath][TxCount] & BIT3) //4bit sign number to 8 bit sign number
4133 pwrInfo24G->BW40_Diff[rfPath][TxCount] |= 0xF0;
4136 if(PROMContent[eeAddr] == 0xFF)
4137 pwrInfo24G->BW20_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
4140 pwrInfo24G->BW20_Diff[rfPath][TxCount] = (PROMContent[eeAddr]&0x0f);
4141 if(pwrInfo24G->BW20_Diff[rfPath][TxCount] & BIT3) //4bit sign number to 8 bit sign number
4142 pwrInfo24G->BW20_Diff[rfPath][TxCount] |= 0xF0;
4146 if(PROMContent[eeAddr] == 0xFF)
4147 pwrInfo24G->OFDM_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
4150 pwrInfo24G->OFDM_Diff[rfPath][TxCount] = (PROMContent[eeAddr]&0xf0)>>4;
4151 if(pwrInfo24G->OFDM_Diff[rfPath][TxCount] & BIT3) //4bit sign number to 8 bit sign number
4152 pwrInfo24G->OFDM_Diff[rfPath][TxCount] |= 0xF0;
4155 if(PROMContent[eeAddr] == 0xFF)
4156 pwrInfo24G->CCK_Diff[rfPath][TxCount] = EEPROM_DEFAULT_DIFF;
4159 pwrInfo24G->CCK_Diff[rfPath][TxCount] = (PROMContent[eeAddr]&0x0f);
4160 if(pwrInfo24G->CCK_Diff[rfPath][TxCount] & BIT3) //4bit sign number to 8 bit sign number
4161 pwrInfo24G->CCK_Diff[rfPath][TxCount] |= 0xF0;
4167 /* Ignore the unnecessary 5G parameters parsing, but still consider the efuse address offset */
4168 #define TX_PWR_DIFF_OFFSET_5G 10
4169 eeAddr += (MAX_CHNL_GROUP_5G + TX_PWR_DIFF_OFFSET_5G);
4175 Hal_EfuseParseTxPowerInfo_8723B(
4176 IN PADAPTER padapter,
4178 IN BOOLEAN AutoLoadFail
4181 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
4182 TxPowerInfo24G pwrInfo24G;
4183 u8 rfPath, ch, group, TxCount=1;
4185 // RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("%s(): AutoLoadFail = %d\n", __func__, AutoLoadFail));
4186 Hal_ReadPowerValueFromPROM_8723B(padapter, &pwrInfo24G, PROMContent, AutoLoadFail);
4187 for(rfPath = 0 ; rfPath < MAX_RF_PATH ; rfPath++)
4189 for(ch = 0 ; ch < CHANNEL_MAX_NUMBER; ch++)
4191 Hal_GetChnlGroup8723B(ch+1, &group);
4195 pHalData->Index24G_CCK_Base[rfPath][ch] = pwrInfo24G.IndexCCK_Base[rfPath][5];
4196 pHalData->Index24G_BW40_Base[rfPath][ch] = pwrInfo24G.IndexBW40_Base[rfPath][group];
4200 pHalData->Index24G_CCK_Base[rfPath][ch] = pwrInfo24G.IndexCCK_Base[rfPath][group];
4201 pHalData->Index24G_BW40_Base[rfPath][ch] = pwrInfo24G.IndexBW40_Base[rfPath][group];
4204 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("======= Path %d, ChannelIndex %d, Group %d=======\n",rfPath,ch, group));
4205 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("Index24G_CCK_Base[%d][%d] = 0x%x\n",rfPath,ch ,pHalData->Index24G_CCK_Base[rfPath][ch]));
4206 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("Index24G_BW40_Base[%d][%d] = 0x%x\n",rfPath,ch,pHalData->Index24G_BW40_Base[rfPath][ch]));
4210 for(TxCount=0;TxCount<MAX_TX_COUNT;TxCount++)
4212 pHalData->CCK_24G_Diff[rfPath][TxCount]=pwrInfo24G.CCK_Diff[rfPath][TxCount];
4213 pHalData->OFDM_24G_Diff[rfPath][TxCount]=pwrInfo24G.OFDM_Diff[rfPath][TxCount];
4214 pHalData->BW20_24G_Diff[rfPath][TxCount]=pwrInfo24G.BW20_Diff[rfPath][TxCount];
4215 pHalData->BW40_24G_Diff[rfPath][TxCount]=pwrInfo24G.BW40_Diff[rfPath][TxCount];
4218 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("--------------------------------------- 2.4G ---------------------------------------\n"));
4219 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("CCK_24G_Diff[%d][%d]= %d\n",rfPath,TxCount,pHalData->CCK_24G_Diff[rfPath][TxCount]));
4220 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("OFDM_24G_Diff[%d][%d]= %d\n",rfPath,TxCount,pHalData->OFDM_24G_Diff[rfPath][TxCount]));
4221 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("BW20_24G_Diff[%d][%d]= %d\n",rfPath,TxCount,pHalData->BW20_24G_Diff[rfPath][TxCount]));
4222 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("BW40_24G_Diff[%d][%d]= %d\n",rfPath,TxCount,pHalData->BW40_24G_Diff[rfPath][TxCount]));
4227 // 2010/10/19 MH Add Regulator recognize for CU.
4230 pHalData->EEPROMRegulatory = (PROMContent[EEPROM_RF_BOARD_OPTION_8723B]&0x7); //bit0~2
4231 if(PROMContent[EEPROM_RF_BOARD_OPTION_8723B] == 0xFF)
4232 pHalData->EEPROMRegulatory = (EEPROM_DEFAULT_BOARD_OPTION&0x7); //bit0~2
4236 pHalData->EEPROMRegulatory = 0;
4238 RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("EEPROMRegulatory = 0x%x\n", pHalData->EEPROMRegulatory));
4242 Hal_EfuseParseBTCoexistInfo_8723B(
4243 IN PADAPTER padapter,
4245 IN BOOLEAN AutoLoadFail
4248 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
4252 // RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("%s(): AutoLoadFail = %d\n", __func__, AutoLoadFail));
4255 tmpu4 = rtw_read32(padapter, REG_MULTI_FUNC_CTRL);
4256 if (tmpu4 & BT_FUNC_EN)
4257 pHalData->EEPROMBluetoothCoexist = _TRUE;
4259 pHalData->EEPROMBluetoothCoexist = _FALSE;
4261 pHalData->EEPROMBluetoothType = BT_RTL8723B;
4263 tempval = hwinfo[EEPROM_RF_BT_SETTING_8723B];
4265 pHalData->EEPROMBluetoothAntNum = tempval & BIT(0);
4266 #ifdef CONFIG_USB_HCI
4267 //if(padapter->interface_type == RTW_USB)
4268 pHalData->ant_path =ODM_RF_PATH_B;//s0
4269 #else //SDIO or PCIE
4270 // EFUSE_0xC3[6] == 0, S1(Main)-ODM_RF_PATH_A;
4271 // EFUSE_0xC3[6] == 1, S0(Aux)-ODM_RF_PATH_B
4272 pHalData->ant_path = (tempval & BIT(6))?ODM_RF_PATH_B:ODM_RF_PATH_A;
4276 pHalData->EEPROMBluetoothAntNum = Ant_x1;
4277 #ifdef CONFIG_USB_HCI
4278 pHalData->ant_path = ODM_RF_PATH_B;//s0
4280 pHalData->ant_path = ODM_RF_PATH_A;
4286 pHalData->EEPROMBluetoothCoexist = _FALSE;
4287 pHalData->EEPROMBluetoothType = BT_RTL8723B;
4288 pHalData->EEPROMBluetoothAntNum = Ant_x1;
4289 #ifdef CONFIG_USB_HCI
4290 pHalData->ant_path = ODM_RF_PATH_B;//s0
4292 pHalData->ant_path = ODM_RF_PATH_A;
4296 #ifdef CONFIG_FOR_RTL8723BS_VQ0
4297 pHalData->ant_path = ODM_RF_PATH_B;//s0
4300 #ifdef CONFIG_BT_COEXIST
4301 if (padapter->registrypriv.ant_num > 0) {
4302 DBG_8192C("%s: Apply driver defined antenna number(%d) to replace origin(%d)\n",
4304 padapter->registrypriv.ant_num,
4305 pHalData->EEPROMBluetoothAntNum==Ant_x2?2:1);
4307 switch (padapter->registrypriv.ant_num) {
4309 pHalData->EEPROMBluetoothAntNum = Ant_x1;
4312 pHalData->EEPROMBluetoothAntNum = Ant_x2;
4315 DBG_8192C("%s: Discard invalid driver defined antenna number(%d)!\n",
4316 __FUNCTION__, padapter->registrypriv.ant_num);
4321 rtw_btcoex_SetBTCoexist(padapter, pHalData->EEPROMBluetoothCoexist);
4322 rtw_btcoex_SetChipType(padapter, pHalData->EEPROMBluetoothType);
4323 rtw_btcoex_SetPGAntNum(padapter, pHalData->EEPROMBluetoothAntNum==Ant_x2?2:1);
4324 if (pHalData->EEPROMBluetoothAntNum == Ant_x1)
4326 rtw_btcoex_SetSingleAntPath(padapter, pHalData->ant_path);
4328 #endif // CONFIG_BT_COEXIST
4330 DBG_8192C("%s: %s BT-coex, ant_num=%d\n",
4332 pHalData->EEPROMBluetoothCoexist==_TRUE?"Enable":"Disable",
4333 pHalData->EEPROMBluetoothAntNum==Ant_x2?2:1);
4337 Hal_EfuseParseEEPROMVer_8723B(
4338 IN PADAPTER padapter,
4340 IN BOOLEAN AutoLoadFail
4343 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
4345 // RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("%s(): AutoLoadFail = %d\n", __func__, AutoLoadFail));
4347 pHalData->EEPROMVersion = hwinfo[EEPROM_VERSION_8723B];
4349 pHalData->EEPROMVersion = 1;
4350 RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("Hal_EfuseParseEEPROMVer(), EEVer = %d\n",
4351 pHalData->EEPROMVersion));
4357 Hal_EfuseParsePackageType_8723B(
4358 IN PADAPTER pAdapter,
4360 IN BOOLEAN AutoLoadFail
4363 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
4367 Efuse_PowerSwitch(pAdapter, _FALSE, _TRUE);
4368 efuse_OneByteRead(pAdapter, 0x1FB, &efuseContent, FALSE);
4369 DBG_871X("%s phy efuse read 0x1FB =%x \n",__func__,efuseContent);
4370 Efuse_PowerSwitch(pAdapter, _FALSE, _FALSE);
4372 package = efuseContent & 0x7;
4376 pHalData->PackageType = PACKAGE_TFBGA79;
4379 pHalData->PackageType = PACKAGE_TFBGA90;
4382 pHalData->PackageType = PACKAGE_QFN68;
4385 pHalData->PackageType = PACKAGE_TFBGA80;
4389 pHalData->PackageType = PACKAGE_DEFAULT;
4393 DBG_871X("PackageType = 0x%X\n", pHalData->PackageType);
4398 Hal_EfuseParseVoltage_8723B(
4399 IN PADAPTER pAdapter,
4401 IN BOOLEAN AutoLoadFail
4404 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
4405 EEPROM_EFUSE_PRIV *pEEPROM = GET_EEPROM_EFUSE_PRIV(pAdapter);
4407 //_rtw_memcpy(pEEPROM->adjuseVoltageVal, &hwinfo[EEPROM_Voltage_ADDR_8723B], 1);
4408 DBG_871X("%s hwinfo[EEPROM_Voltage_ADDR_8723B] =%02x \n",__func__, hwinfo[EEPROM_Voltage_ADDR_8723B]);
4409 pEEPROM->adjuseVoltageVal = (hwinfo[EEPROM_Voltage_ADDR_8723B] & 0xf0) >> 4 ;
4410 DBG_871X("%s pEEPROM->adjuseVoltageVal =%x \n",__func__,pEEPROM->adjuseVoltageVal);
4414 Hal_EfuseParseChnlPlan_8723B(
4415 IN PADAPTER padapter,
4417 IN BOOLEAN AutoLoadFail
4420 padapter->mlmepriv.ChannelPlan = hal_com_config_channel_plan(
4422 , hwinfo?hwinfo[EEPROM_ChannelPlan_8723B]:0xFF
4423 , padapter->registrypriv.channel_plan
4424 , RT_CHANNEL_DOMAIN_WORLD_NULL
4428 RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("EEPROM ChannelPlan=0x%02x\n", padapter->mlmepriv.ChannelPlan));
4432 Hal_EfuseParseCustomerID_8723B(
4433 IN PADAPTER padapter,
4435 IN BOOLEAN AutoLoadFail
4438 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
4440 // RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("%s(): AutoLoadFail = %d\n", __func__, AutoLoadFail));
4443 pHalData->EEPROMCustomerID = hwinfo[EEPROM_CustomID_8723B];
4447 pHalData->EEPROMCustomerID = 0;
4449 RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("EEPROM Customer ID: 0x%2x\n", pHalData->EEPROMCustomerID));
4453 Hal_EfuseParseAntennaDiversity_8723B(
4454 IN PADAPTER pAdapter,
4456 IN BOOLEAN AutoLoadFail
4459 #ifdef CONFIG_ANTENNA_DIVERSITY
4460 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter);
4461 struct registry_priv *registry_par = &pAdapter->registrypriv;
4463 if (pHalData->EEPROMBluetoothAntNum == Ant_x1){
4464 pHalData->AntDivCfg = 0;
4467 if(registry_par->antdiv_cfg == 2)// 0:OFF , 1:ON, 2:By EFUSE
4468 pHalData->AntDivCfg = 1;
4470 pHalData->AntDivCfg = registry_par->antdiv_cfg;
4473 // If TRxAntDivType is AUTO in advanced setting, use EFUSE value instead.
4474 if(registry_par->antdiv_type == 0) {
4475 pHalData->TRxAntDivType = hwinfo[EEPROM_RFE_OPTION_8723B];
4476 if (pHalData->TRxAntDivType == 0xFF)
4477 pHalData->TRxAntDivType = S0S1_SW_ANTDIV;//GetRegAntDivType(pAdapter);
4478 else if (pHalData->TRxAntDivType == 0x10)
4479 pHalData->TRxAntDivType = S0S1_SW_ANTDIV; //intrnal switch S0S1
4480 else if (pHalData->TRxAntDivType == 0x11)
4481 pHalData->TRxAntDivType = S0S1_SW_ANTDIV; //intrnal switch S0S1
4483 DBG_8192C("%s: efuse[0x%x]=0x%02x is unknown type\n",
4484 __FUNCTION__, EEPROM_RFE_OPTION_8723B, pHalData->TRxAntDivType);
4487 pHalData->TRxAntDivType = registry_par->antdiv_type ;//GetRegAntDivType(pAdapter);
4490 DBG_8192C("%s: AntDivCfg=%d, AntDivType=%d\n",
4491 __FUNCTION__, pHalData->AntDivCfg, pHalData->TRxAntDivType);
4496 Hal_EfuseParseXtal_8723B(
4497 IN PADAPTER pAdapter,
4499 IN BOOLEAN AutoLoadFail
4502 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
4504 // RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("%s(): AutoLoadFail = %d\n", __func__, AutoLoadFail));
4507 pHalData->CrystalCap = hwinfo[EEPROM_XTAL_8723B];
4508 if(pHalData->CrystalCap == 0xFF)
4509 pHalData->CrystalCap = EEPROM_Default_CrystalCap_8723B; //what value should 8812 set?
4513 pHalData->CrystalCap = EEPROM_Default_CrystalCap_8723B;
4515 RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("EEPROM CrystalCap: 0x%2x\n", pHalData->CrystalCap));
4520 Hal_EfuseParseThermalMeter_8723B(
4526 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
4528 // RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("%s(): AutoLoadFail = %d\n", __func__, AutoLoadFail));
4530 // ThermalMeter from EEPROM
4532 if (_FALSE == AutoLoadFail)
4533 pHalData->EEPROMThermalMeter = PROMContent[EEPROM_THERMAL_METER_8723B];
4535 pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter_8723B;
4537 if ((pHalData->EEPROMThermalMeter == 0xff) || (_TRUE == AutoLoadFail))
4539 pHalData->bAPKThermalMeterIgnore = _TRUE;
4540 pHalData->EEPROMThermalMeter = EEPROM_Default_ThermalMeter_8723B;
4543 RT_TRACE(_module_hci_hal_init_c_, _drv_notice_, ("EEPROM ThermalMeter=0x%x\n", pHalData->EEPROMThermalMeter));
4547 #ifdef CONFIG_RF_GAIN_OFFSET
4548 void Hal_ReadRFGainOffset(
4549 IN PADAPTER Adapter,
4551 IN BOOLEAN AutoloadFail)
4554 // BB_RF Gain Offset from EEPROM
4558 Adapter->eeprompriv.EEPROMRFGainOffset =PROMContent[EEPROM_RF_GAIN_OFFSET];
4559 DBG_871X("AutoloadFail =%x,\n", AutoloadFail);
4560 Adapter->eeprompriv.EEPROMRFGainVal=EFUSE_Read1Byte(Adapter, EEPROM_RF_GAIN_VAL);
4561 DBG_871X("Adapter->eeprompriv.EEPROMRFGainVal=%x\n", Adapter->eeprompriv.EEPROMRFGainVal);
4564 Adapter->eeprompriv.EEPROMRFGainOffset = 0;
4565 Adapter->eeprompriv.EEPROMRFGainVal=0xFF;
4566 DBG_871X("else AutoloadFail =%x,\n", AutoloadFail);
4568 DBG_871X("EEPRORFGainOffset = 0x%02x\n", Adapter->eeprompriv.EEPROMRFGainOffset);
4570 #endif //CONFIG_RF_GAIN_OFFSET
4574 IN PADAPTER Adapter,
4575 IN struct pkt_attrib *pattrib
4578 u8 BWSettingOfDesc = 0;
4579 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
4581 //DBG_871X("BWMapping pHalData->CurrentChannelBW %d, pattrib->bwmode %d \n",pHalData->CurrentChannelBW,pattrib->bwmode);
4583 if(pHalData->CurrentChannelBW== CHANNEL_WIDTH_80)
4585 if(pattrib->bwmode == CHANNEL_WIDTH_80)
4587 else if(pattrib->bwmode == CHANNEL_WIDTH_40)
4588 BWSettingOfDesc = 1;
4590 BWSettingOfDesc = 0;
4592 else if(pHalData->CurrentChannelBW== CHANNEL_WIDTH_40)
4594 if((pattrib->bwmode == CHANNEL_WIDTH_40) || (pattrib->bwmode == CHANNEL_WIDTH_80))
4595 BWSettingOfDesc = 1;
4597 BWSettingOfDesc = 0;
4600 BWSettingOfDesc = 0;
4602 //if(pTcb->bBTTxPacket)
4603 // BWSettingOfDesc = 0;
4605 return BWSettingOfDesc;
4608 u8 SCMapping_8723B(PADAPTER Adapter, struct pkt_attrib *pattrib)
4610 u8 SCSettingOfDesc = 0;
4611 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
4613 //DBG_871X("SCMapping: pHalData->CurrentChannelBW %d, pHalData->nCur80MhzPrimeSC %d, pHalData->nCur40MhzPrimeSC %d \n",pHalData->CurrentChannelBW,pHalData->nCur80MhzPrimeSC,pHalData->nCur40MhzPrimeSC);
4615 if(pHalData->CurrentChannelBW == CHANNEL_WIDTH_80)
4617 if(pattrib->bwmode == CHANNEL_WIDTH_80)
4619 SCSettingOfDesc = VHT_DATA_SC_DONOT_CARE;
4621 else if(pattrib->bwmode == CHANNEL_WIDTH_40)
4623 if(pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER)
4624 SCSettingOfDesc = VHT_DATA_SC_40_LOWER_OF_80MHZ;
4625 else if(pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER)
4626 SCSettingOfDesc = VHT_DATA_SC_40_UPPER_OF_80MHZ;
4628 DBG_871X("SCMapping: Not Correct Primary40MHz Setting \n");
4632 if((pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) && (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER))
4633 SCSettingOfDesc = VHT_DATA_SC_20_LOWEST_OF_80MHZ;
4634 else if((pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER) && (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER))
4635 SCSettingOfDesc = VHT_DATA_SC_20_LOWER_OF_80MHZ;
4636 else if((pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) && (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER))
4637 SCSettingOfDesc = VHT_DATA_SC_20_UPPER_OF_80MHZ;
4638 else if((pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER) && (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER))
4639 SCSettingOfDesc = VHT_DATA_SC_20_UPPERST_OF_80MHZ;
4641 DBG_871X("SCMapping: Not Correct Primary40MHz Setting \n");
4644 else if(pHalData->CurrentChannelBW== CHANNEL_WIDTH_40)
4646 //DBG_871X("SCMapping: HT Case: pHalData->CurrentChannelBW %d, pHalData->nCur40MhzPrimeSC %d \n",pHalData->CurrentChannelBW,pHalData->nCur40MhzPrimeSC);
4648 if(pattrib->bwmode == CHANNEL_WIDTH_40)
4650 SCSettingOfDesc = VHT_DATA_SC_DONOT_CARE;
4652 else if(pattrib->bwmode == CHANNEL_WIDTH_20)
4654 if(pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER)
4656 SCSettingOfDesc = VHT_DATA_SC_20_UPPER_OF_80MHZ;
4658 else if(pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER)
4660 SCSettingOfDesc = VHT_DATA_SC_20_LOWER_OF_80MHZ;
4664 SCSettingOfDesc = VHT_DATA_SC_DONOT_CARE;
4670 SCSettingOfDesc = VHT_DATA_SC_DONOT_CARE;
4673 return SCSettingOfDesc;
4677 static u8 fill_txdesc_sectype(struct pkt_attrib *pattrib)
4680 if ((pattrib->encrypt > 0) && !pattrib->bswenc)
4682 switch (pattrib->encrypt)
4692 #ifdef CONFIG_WAPI_SUPPORT
4709 static void fill_txdesc_vcs_8723b(PADAPTER padapter, struct pkt_attrib *pattrib, u8 *ptxdesc)
4711 //DBG_8192C("cvs_mode=%d\n", pattrib->vcs_mode);
4713 if (pattrib->vcs_mode) {
4714 switch (pattrib->vcs_mode) {
4716 SET_TX_DESC_RTS_ENABLE_8723B(ptxdesc, 1);
4717 SET_TX_DESC_HW_RTS_ENABLE_8723B(ptxdesc, 1);
4721 SET_TX_DESC_CTS2SELF_8723B(ptxdesc, 1);
4729 SET_TX_DESC_RTS_RATE_8723B(ptxdesc, 8); // RTS Rate=24M
4730 SET_TX_DESC_RTS_RATE_FB_LIMIT_8723B(ptxdesc, 0xF);
4732 if (padapter->mlmeextpriv.mlmext_info.preamble_mode == PREAMBLE_SHORT) {
4733 SET_TX_DESC_RTS_SHORT_8723B(ptxdesc, 1);
4737 if (pattrib->ht_en) {
4738 SET_TX_DESC_RTS_SC_8723B(ptxdesc, SCMapping_8723B(padapter, pattrib));
4743 static void fill_txdesc_phy_8723b(PADAPTER padapter, struct pkt_attrib *pattrib, u8 *ptxdesc)
4745 //DBG_8192C("bwmode=%d, ch_off=%d\n", pattrib->bwmode, pattrib->ch_offset);
4747 if (pattrib->ht_en) {
4748 SET_TX_DESC_DATA_BW_8723B(ptxdesc, BWMapping_8723B(padapter, pattrib));
4749 SET_TX_DESC_DATA_SC_8723B(ptxdesc, SCMapping_8723B(padapter, pattrib));
4753 static void rtl8723b_fill_default_txdesc(
4754 struct xmit_frame *pxmitframe,
4758 HAL_DATA_TYPE *pHalData;
4759 struct dm_priv *pdmpriv;
4760 struct mlme_ext_priv *pmlmeext;
4761 struct mlme_ext_info *pmlmeinfo;
4762 struct pkt_attrib *pattrib;
4765 _rtw_memset(pbuf, 0, TXDESC_SIZE);
4767 padapter = pxmitframe->padapter;
4768 pHalData = GET_HAL_DATA(padapter);
4769 pdmpriv = &pHalData->dmpriv;
4770 pmlmeext = &padapter->mlmeextpriv;
4771 pmlmeinfo = &(pmlmeext->mlmext_info);
4773 pattrib = &pxmitframe->attrib;
4774 bmcst = IS_MCAST(pattrib->ra);
4776 if (pxmitframe->frame_tag == DATA_FRAMETAG)
4780 SET_TX_DESC_MACID_8723B(pbuf, pattrib->mac_id);
4781 SET_TX_DESC_RATE_ID_8723B(pbuf, pattrib->raid);
4782 SET_TX_DESC_QUEUE_SEL_8723B(pbuf, pattrib->qsel);
4783 SET_TX_DESC_SEQ_8723B(pbuf, pattrib->seqnum);
4785 SET_TX_DESC_SEC_TYPE_8723B(pbuf, fill_txdesc_sectype(pattrib));
4786 fill_txdesc_vcs_8723b(padapter, pattrib, pbuf);
4788 if(pattrib->icmp_pkt ==1 && padapter->registrypriv.wifi_spec==1)
4791 if ((pattrib->ether_type != 0x888e) &&
4792 (pattrib->ether_type != 0x0806) &&
4793 (pattrib->ether_type != 0x88B4) &&
4794 (pattrib->dhcp_pkt != 1) &&
4796 #ifdef CONFIG_AUTO_AP_MODE
4797 && (pattrib->pctrl != _TRUE)
4801 // Non EAP & ARP & DHCP type data packet
4803 if (pattrib->ampdu_en == _TRUE) {
4804 SET_TX_DESC_AGG_ENABLE_8723B(pbuf, 1);
4805 SET_TX_DESC_MAX_AGG_NUM_8723B(pbuf, 0x1F);
4806 SET_TX_DESC_AMPDU_DENSITY_8723B(pbuf, pattrib->ampdu_spacing);
4809 SET_TX_DESC_AGG_BREAK_8723B(pbuf, 1);
4812 fill_txdesc_phy_8723b(padapter, pattrib, pbuf);
4814 SET_TX_DESC_DATA_RATE_FB_LIMIT_8723B(pbuf, 0x1F);
4816 if (pHalData->fw_ractrl == _FALSE) {
4817 SET_TX_DESC_USE_RATE_8723B(pbuf, 1);
4819 if (pHalData->dmpriv.INIDATA_RATE[pattrib->mac_id] & BIT(7)) {
4820 SET_TX_DESC_DATA_SHORT_8723B(pbuf, 1);
4823 SET_TX_DESC_TX_RATE_8723B(pbuf, pHalData->dmpriv.INIDATA_RATE[pattrib->mac_id] & 0x7F);
4826 // modify data rate by iwpriv
4827 if (padapter->fix_rate != 0xFF) {
4828 SET_TX_DESC_USE_RATE_8723B(pbuf, 1);
4829 if (padapter->fix_rate & BIT(7)) {
4830 SET_TX_DESC_DATA_SHORT_8723B(pbuf, 1);
4832 SET_TX_DESC_TX_RATE_8723B(pbuf, padapter->fix_rate & 0x7F);
4833 if (!padapter->data_fb) {
4834 SET_TX_DESC_DISABLE_FB_8723B(pbuf, 1);
4838 if (pattrib->ldpc) {
4839 SET_TX_DESC_DATA_LDPC_8723B(pbuf, 1);
4842 if (pattrib->stbc) {
4843 SET_TX_DESC_DATA_STBC_8723B(pbuf, 1);
4846 #ifdef CONFIG_CMCC_TEST
4847 SET_TX_DESC_DATA_SHORT_8723B(pbuf, 1); /* use cck short premble */
4852 // EAP data packet and ARP packet.
4853 // Use the 1M data rate to send the EAP/ARP packet.
4854 // This will maybe make the handshake smooth.
4856 SET_TX_DESC_AGG_BREAK_8723B(pbuf, 1);
4857 SET_TX_DESC_USE_RATE_8723B(pbuf, 1);
4858 if (pmlmeinfo->preamble_mode == PREAMBLE_SHORT) {
4859 SET_TX_DESC_DATA_SHORT_8723B(pbuf, 1);
4861 SET_TX_DESC_TX_RATE_8723B(pbuf, MRateToHwRate(pmlmeext->tx_rate));
4863 DBG_8192C(FUNC_ADPT_FMT ": SP Packet(0x%04X) rate=0x%x\n",
4864 FUNC_ADPT_ARG(padapter), pattrib->ether_type, MRateToHwRate(pmlmeext->tx_rate));
4867 #if defined(CONFIG_USB_TX_AGGREGATION) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
4868 SET_TX_DESC_USB_TXAGG_NUM_8723B(pbuf, pxmitframe->agg_num);
4871 else if (pxmitframe->frame_tag == MGNT_FRAMETAG)
4873 // RT_TRACE(_module_hal_xmit_c_, _drv_notice_, ("%s: MGNT_FRAMETAG\n", __FUNCTION__));
4875 SET_TX_DESC_MACID_8723B(pbuf, pattrib->mac_id);
4876 SET_TX_DESC_QUEUE_SEL_8723B(pbuf, pattrib->qsel);
4877 SET_TX_DESC_RATE_ID_8723B(pbuf, pattrib->raid);
4878 SET_TX_DESC_SEQ_8723B(pbuf, pattrib->seqnum);
4879 SET_TX_DESC_USE_RATE_8723B(pbuf, 1);
4881 SET_TX_DESC_MBSSID_8723B(pbuf, pattrib->mbssid & 0xF);
4883 SET_TX_DESC_RETRY_LIMIT_ENABLE_8723B(pbuf, 1);
4884 if (pattrib->retry_ctrl == _TRUE) {
4885 SET_TX_DESC_DATA_RETRY_LIMIT_8723B(pbuf, 6);
4887 SET_TX_DESC_DATA_RETRY_LIMIT_8723B(pbuf, 12);
4890 #ifdef CONFIG_INTEL_PROXIM
4891 if((padapter->proximity.proxim_on==_TRUE)&&(pattrib->intel_proxim==_TRUE)){
4892 DBG_871X("\n %s pattrib->rate=%d\n",__FUNCTION__,pattrib->rate);
4893 SET_TX_DESC_TX_RATE_8723B(pbuf, pattrib->rate);
4898 SET_TX_DESC_TX_RATE_8723B(pbuf, MRateToHwRate(pmlmeext->tx_rate));
4901 #ifdef CONFIG_XMIT_ACK
4902 // CCX-TXRPT ack for xmit mgmt frames.
4903 if (pxmitframe->ack_report) {
4905 DBG_8192C("%s set spe_rpt\n", __FUNCTION__);
4907 SET_TX_DESC_SPE_RPT_8723B(pbuf, 1);
4908 SET_TX_DESC_SW_DEFINE_8723B(pbuf, (u8)(GET_PRIMARY_ADAPTER(padapter)->xmitpriv.seq_no));
4910 #endif // CONFIG_XMIT_ACK
4912 else if (pxmitframe->frame_tag == TXAGG_FRAMETAG)
4914 RT_TRACE(_module_hal_xmit_c_, _drv_warning_, ("%s: TXAGG_FRAMETAG\n", __FUNCTION__));
4916 #ifdef CONFIG_MP_INCLUDED
4917 else if (pxmitframe->frame_tag == MP_FRAMETAG)
4919 RT_TRACE(_module_hal_xmit_c_, _drv_notice_, ("%s: MP_FRAMETAG\n", __FUNCTION__));
4920 fill_txdesc_for_mp(padapter, pbuf);
4925 RT_TRACE(_module_hal_xmit_c_, _drv_warning_, ("%s: frame_tag=0x%x\n", __FUNCTION__, pxmitframe->frame_tag));
4927 SET_TX_DESC_MACID_8723B(pbuf, pattrib->mac_id);
4928 SET_TX_DESC_RATE_ID_8723B(pbuf, pattrib->raid);
4929 SET_TX_DESC_QUEUE_SEL_8723B(pbuf, pattrib->qsel);
4930 SET_TX_DESC_SEQ_8723B(pbuf, pattrib->seqnum);
4931 SET_TX_DESC_USE_RATE_8723B(pbuf, 1);
4932 SET_TX_DESC_TX_RATE_8723B(pbuf, MRateToHwRate(pmlmeext->tx_rate));
4935 SET_TX_DESC_PKT_SIZE_8723B(pbuf, pattrib->last_txcmdsz);
4938 u8 pkt_offset, offset;
4941 offset = TXDESC_SIZE;
4942 #ifdef CONFIG_USB_HCI
4943 pkt_offset = pxmitframe->pkt_offset;
4944 offset += (pxmitframe->pkt_offset >> 3);
4945 #endif // CONFIG_USB_HCI
4947 #ifdef CONFIG_TX_EARLY_MODE
4948 if (pxmitframe->frame_tag == DATA_FRAMETAG) {
4950 offset += EARLY_MODE_INFO_SIZE;
4952 #endif // CONFIG_TX_EARLY_MODE
4954 SET_TX_DESC_PKT_OFFSET_8723B(pbuf, pkt_offset);
4955 SET_TX_DESC_OFFSET_8723B(pbuf, offset);
4959 SET_TX_DESC_BMC_8723B(pbuf, 1);
4962 // 2009.11.05. tynli_test. Suggested by SD4 Filen for FW LPS.
4963 // (1) The sequence number of each non-Qos frame / broadcast / multicast /
4964 // mgnt frame should be controled by Hw because Fw will also send null data
4965 // which we cannot control when Fw LPS enable.
4966 // --> default enable non-Qos data sequense number. 2010.06.23. by tynli.
4967 // (2) Enable HW SEQ control for beacon packet, because we use Hw beacon.
4968 // (3) Use HW Qos SEQ to control the seq num of Ext port non-Qos packets.
4969 // 2010.06.23. Added by tynli.
4970 if (!pattrib->qos_en) {
4971 SET_TX_DESC_HWSEQ_EN_8723B(pbuf, 1);
4979 * pxmitframe xmitframe
4980 * pbuf where to fill tx desc
4982 void rtl8723b_update_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf)
4984 rtl8723b_fill_default_txdesc(pxmitframe, pbuf);
4986 #ifdef CONFIG_ANTENNA_DIVERSITY
4987 ODM_SetTxAntByTxInfo(&GET_HAL_DATA(padapter)->odmpriv, pbuf, pxmitframe->attrib.mac_id);
4988 #endif // CONFIG_ANTENNA_DIVERSITY
4990 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
4991 rtl8723b_cal_txdesc_chksum((struct tx_desc*)pbuf);
4996 // Description: In normal chip, we should send some packet to Hw which will be used by Fw
4997 // in FW LPS mode. The function is to fill the Tx descriptor of this packets, then
4998 // Fw can tell Hw to send these packet derectly.
4999 // Added by tynli. 2009.10.15.
5001 //type1:pspoll, type2:null
5002 void rtl8723b_fill_fake_txdesc(
5011 _rtw_memset(pDesc, 0, TXDESC_SIZE);
5013 SET_TX_DESC_FIRST_SEG_8723B(pDesc, 1); //bFirstSeg;
5014 SET_TX_DESC_LAST_SEG_8723B(pDesc, 1); //bLastSeg;
5016 SET_TX_DESC_OFFSET_8723B(pDesc, 0x28); // Offset = 32
5018 SET_TX_DESC_PKT_SIZE_8723B(pDesc, BufferLen); // Buffer size + command header
5019 SET_TX_DESC_QUEUE_SEL_8723B(pDesc, QSLT_MGNT); // Fixed queue of Mgnt queue
5021 // Set NAVUSEHDR to prevent Ps-poll AId filed to be changed to error vlaue by Hw.
5022 if (_TRUE == IsPsPoll)
5024 SET_TX_DESC_NAV_USE_HDR_8723B(pDesc, 1);
5028 SET_TX_DESC_HWSEQ_EN_8723B(pDesc, 1); // Hw set sequence number
5029 SET_TX_DESC_HWSEQ_SEL_8723B(pDesc, 0);
5032 if (_TRUE ==IsBTQosNull)
5034 SET_TX_DESC_BT_INT_8723B(pDesc, 1);
5037 SET_TX_DESC_USE_RATE_8723B(pDesc, 1); // use data rate which is set by Sw
5038 SET_TX_DESC_OWN_8723B((pu1Byte)pDesc, 1);
5040 SET_TX_DESC_TX_RATE_8723B(pDesc, DESC8723B_RATE1M);
5043 // Encrypt the data frame if under security mode excepct null data. Suggested by CCW.
5045 if (_TRUE ==bDataFrame)
5049 EncAlg = padapter->securitypriv.dot11PrivacyAlgrthm;
5053 SET_TX_DESC_SEC_TYPE_8723B(pDesc, 0x0);
5058 SET_TX_DESC_SEC_TYPE_8723B(pDesc, 0x1);
5061 SET_TX_DESC_SEC_TYPE_8723B(pDesc, 0x2);
5064 SET_TX_DESC_SEC_TYPE_8723B(pDesc, 0x3);
5067 SET_TX_DESC_SEC_TYPE_8723B(pDesc, 0x0);
5072 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
5073 // USB interface drop packet if the checksum of descriptor isn't correct.
5074 // Using this checksum can let hardware recovery from packet bulk out error (e.g. Cancel URC, Bulk out error.).
5075 rtl8723b_cal_txdesc_chksum((struct tx_desc*)pDesc);
5079 #ifdef CONFIG_TSF_RESET_OFFLOAD
5080 int reset_tsf(PADAPTER Adapter, u8 reset_port )
5082 u8 reset_cnt_before = 0, reset_cnt_after = 0, loop_cnt = 0;
5083 u32 reg_reset_tsf_cnt = (IFACE_PORT0==reset_port) ?
5084 REG_FW_RESET_TSF_CNT_0:REG_FW_RESET_TSF_CNT_1;
5086 rtw_scan_abort(Adapter->pbuddy_adapter); /* site survey will cause reset_tsf fail */
5087 reset_cnt_after = reset_cnt_before = rtw_read8(Adapter,reg_reset_tsf_cnt);
5088 rtl8723b_reset_tsf(Adapter, reset_port);
5090 while ((reset_cnt_after == reset_cnt_before ) && (loop_cnt < 10)) {
5093 reset_cnt_after = rtw_read8(Adapter, reg_reset_tsf_cnt);
5096 return(loop_cnt >= 10) ? _FAIL : _TRUE;
5098 #endif // CONFIG_TSF_RESET_OFFLOAD
5100 static void hw_var_set_opmode(PADAPTER padapter, u8 variable, u8* val)
5103 u8 mode = *((u8 *)val);
5105 #ifdef CONFIG_CONCURRENT_MODE
5106 if (padapter->iface_type == IFACE_PORT1)
5108 // disable Port1 TSF update
5109 val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
5110 val8 |= DIS_TSF_UDT;
5111 rtw_write8(padapter, REG_BCN_CTRL_1, val8);
5113 Set_MSR(padapter, mode);
5115 DBG_871X("#### %s()-%d iface_type(%d) mode=%d ####\n",
5116 __FUNCTION__, __LINE__, padapter->iface_type, mode);
5118 if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_))
5120 if (!check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE))
5122 StopTxBeacon(padapter);
5123 #ifdef CONFIG_PCI_HCI
5124 UpdateInterruptMask8723BE(padapter, 0, 0, RT_BCN_INT_MASKS, 0);
5125 #else // !CONFIG_PCI_HCI
5126 #ifdef CONFIG_INTERRUPT_BASED_TXBCN
5128 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
5129 rtw_write8(padapter, REG_DRVERLYINT, 0x05);//restore early int time to 5ms
5130 UpdateInterruptMask8723BU(padapter, _TRUE, 0, IMR_BCNDMAINT0_8723B);
5131 #endif // CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
5133 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
5134 UpdateInterruptMask8723BU(padapter, _TRUE ,0, (IMR_TXBCN0ERR_8723B|IMR_TXBCN0OK_8723B));
5135 #endif // CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
5137 #endif // CONFIG_INTERRUPT_BASED_TXBCN
5138 #endif // !CONFIG_PCI_HCI
5141 // disable atim wnd and disable beacon function
5142 rtw_write8(padapter, REG_BCN_CTRL_1, DIS_TSF_UDT|DIS_ATIM);
5144 else if ((mode == _HW_STATE_ADHOC_) /*|| (mode == _HW_STATE_AP_)*/)
5146 ResumeTxBeacon(padapter);
5147 rtw_write8(padapter, REG_BCN_CTRL_1, DIS_TSF_UDT|EN_BCN_FUNCTION|DIS_BCNQ_SUB);
5149 else if (mode == _HW_STATE_AP_)
5151 #ifdef CONFIG_PCI_HCI
5152 UpdateInterruptMask8723BE(padapter, RT_BCN_INT_MASKS, 0, 0, 0);
5153 #else // !CONFIG_PCI_HCI
5154 #ifdef CONFIG_INTERRUPT_BASED_TXBCN
5156 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
5157 UpdateInterruptMask8723BU(padapter, _TRUE, IMR_BCNDMAINT0_8723B, 0);
5158 #endif // CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
5160 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
5161 UpdateInterruptMask8723BU(padapter, _TRUE, (IMR_TXBCN0ERR_8723B|IMR_TXBCN0OK_8723B), 0);
5162 #endif // CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
5164 #endif // CONFIG_INTERRUPT_BASED_TXBCN
5165 #endif // !CONFIG_PCI_HCI
5167 ResumeTxBeacon(padapter);
5169 rtw_write8(padapter, REG_BCN_CTRL_1, DIS_TSF_UDT|DIS_BCNQ_SUB);
5172 //rtw_write32(padapter, REG_RCR, 0x70002a8e);//CBSSID_DATA must set to 0
5173 //rtw_write32(padapter, REG_RCR, 0x7000228e);//CBSSID_DATA must set to 0
5174 rtw_write32(padapter, REG_RCR, 0x7000208e);//CBSSID_DATA must set to 0,reject ICV_ERR packet
5175 // enable to rx data frame
5176 rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
5177 // enable to rx ps-poll
5178 rtw_write16(padapter, REG_RXFLTMAP1, 0x0400);
5180 // Beacon Control related register for first time
5181 rtw_write8(padapter, REG_BCNDMATIM, 0x02); // 2ms
5183 //rtw_write8(padapter, REG_BCN_MAX_ERR, 0xFF);
5184 rtw_write8(padapter, REG_ATIMWND_1, 0x0a); // 10ms for port1
5185 rtw_write16(padapter, REG_BCNTCFG, 0x00);
5186 rtw_write16(padapter, REG_TBTT_PROHIBIT, 0xff04);
5187 rtw_write16(padapter, REG_TSFTR_SYN_OFFSET, 0x7fff);// +32767 (~32ms)
5190 rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(1));
5192 // enable BCN1 Function for if2
5193 // don't enable update TSF1 for if2 (due to TSF update when beacon/probe rsp are received)
5194 rtw_write8(padapter, REG_BCN_CTRL_1, (DIS_TSF_UDT|EN_BCN_FUNCTION | EN_TXBCN_RPT|DIS_BCNQ_SUB));
5196 //SW_BCN_SEL - Port1
5197 //rtw_write8(Adapter, REG_DWBCN1_CTRL_8192E+2, rtw_read8(Adapter, REG_DWBCN1_CTRL_8192E+2)|BIT4);
5198 rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
5200 // select BCN on port 1
5201 rtw_write8(padapter, REG_CCK_CHECK_8723B,
5202 (rtw_read8(padapter, REG_CCK_CHECK_8723B)|BIT_BCN_PORT_SEL));
5204 if (check_buddy_fwstate(padapter, WIFI_FW_NULL_STATE))
5206 val8 = rtw_read8(padapter, REG_BCN_CTRL);
5207 val8 &= ~EN_BCN_FUNCTION;
5208 rtw_write8(padapter, REG_BCN_CTRL, val8);
5211 //BCN1 TSF will sync to BCN0 TSF with offset(0x518) if if1_sta linked
5212 //rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1)|BIT(5));
5213 //rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(3));
5215 //dis BCN0 ATIM WND if if1 is station
5216 rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL)|DIS_ATIM);
5218 #ifdef CONFIG_TSF_RESET_OFFLOAD
5219 // Reset TSF for STA+AP concurrent mode
5220 if (check_buddy_fwstate(padapter, (WIFI_STATION_STATE|WIFI_ASOC_STATE)))
5222 if (reset_tsf(padapter, IFACE_PORT1) == _FALSE)
5223 DBG_871X("ERROR! %s()-%d: Reset port1 TSF fail\n",
5224 __FUNCTION__, __LINE__);
5226 #endif // CONFIG_TSF_RESET_OFFLOAD
5229 else //else for port0
5230 #endif // CONFIG_CONCURRENT_MODE
5232 // disable Port0 TSF update
5233 val8 = rtw_read8(padapter, REG_BCN_CTRL);
5234 val8 |= DIS_TSF_UDT;
5235 rtw_write8(padapter, REG_BCN_CTRL, val8);
5238 Set_MSR(padapter, mode);
5239 DBG_871X("#### %s() -%d iface_type(0) mode = %d ####\n", __FUNCTION__, __LINE__, mode);
5241 if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_))
5243 #ifdef CONFIG_CONCURRENT_MODE
5244 if (!check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE))
5245 #endif // CONFIG_CONCURRENT_MODE
5247 StopTxBeacon(padapter);
5248 #ifdef CONFIG_PCI_HCI
5249 UpdateInterruptMask8723BE(padapter, 0, 0, RT_BCN_INT_MASKS, 0);
5250 #else // !CONFIG_PCI_HCI
5251 #ifdef CONFIG_INTERRUPT_BASED_TXBCN
5252 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
5253 rtw_write8(padapter, REG_DRVERLYINT, 0x05); // restore early int time to 5ms
5254 UpdateInterruptMask8812AU(padapter, _TRUE, 0, IMR_BCNDMAINT0_8723B);
5255 #endif // CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
5257 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
5258 UpdateInterruptMask8812AU(padapter,_TRUE ,0, (IMR_TXBCN0ERR_8723B|IMR_TXBCN0OK_8723B));
5259 #endif // CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
5261 #endif // CONFIG_INTERRUPT_BASED_TXBCN
5262 #endif // !CONFIG_PCI_HCI
5266 rtw_write8(padapter, REG_BCN_CTRL, DIS_TSF_UDT|EN_BCN_FUNCTION|DIS_ATIM);
5267 //rtw_write8(padapter,REG_BCN_CTRL, 0x18);
5269 else if ((mode == _HW_STATE_ADHOC_) /*|| (mode == _HW_STATE_AP_)*/)
5271 ResumeTxBeacon(padapter);
5272 rtw_write8(padapter, REG_BCN_CTRL, DIS_TSF_UDT|EN_BCN_FUNCTION|DIS_BCNQ_SUB);
5274 else if (mode == _HW_STATE_AP_)
5276 #ifdef CONFIG_PCI_HCI
5277 UpdateInterruptMask8723BE( padapter, RT_BCN_INT_MASKS, 0, 0, 0);
5278 #else // !CONFIG_PCI_HCI
5279 #ifdef CONFIG_INTERRUPT_BASED_TXBCN
5280 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
5281 UpdateInterruptMask8723BU(padapter, _TRUE ,IMR_BCNDMAINT0_8723B, 0);
5282 #endif // CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
5284 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
5285 UpdateInterruptMask8723BU(padapter,_TRUE ,(IMR_TXBCN0ERR_8723B|IMR_TXBCN0OK_8723B), 0);
5286 #endif // CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
5288 #endif // CONFIG_INTERRUPT_BASED_TXBCN
5291 ResumeTxBeacon(padapter);
5293 rtw_write8(padapter, REG_BCN_CTRL, DIS_TSF_UDT|DIS_BCNQ_SUB);
5296 //rtw_write32(padapter, REG_RCR, 0x70002a8e);//CBSSID_DATA must set to 0
5297 //rtw_write32(padapter, REG_RCR, 0x7000228e);//CBSSID_DATA must set to 0
5298 rtw_write32(padapter, REG_RCR, 0x7000208e);//CBSSID_DATA must set to 0,reject ICV_ERR packet
5299 //enable to rx data frame
5300 rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
5301 //enable to rx ps-poll
5302 rtw_write16(padapter, REG_RXFLTMAP1, 0x0400);
5304 //Beacon Control related register for first time
5305 rtw_write8(padapter, REG_BCNDMATIM, 0x02); // 2ms
5307 //rtw_write8(padapter, REG_BCN_MAX_ERR, 0xFF);
5308 rtw_write8(padapter, REG_ATIMWND, 0x0a); // 10ms
5309 rtw_write16(padapter, REG_BCNTCFG, 0x00);
5310 rtw_write16(padapter, REG_TBTT_PROHIBIT, 0xff04);
5311 rtw_write16(padapter, REG_TSFTR_SYN_OFFSET, 0x7fff);// +32767 (~32ms)
5314 rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(0));
5316 //enable BCN0 Function for if1
5317 //don't enable update TSF0 for if1 (due to TSF update when beacon/probe rsp are received)
5318 rtw_write8(padapter, REG_BCN_CTRL, (DIS_TSF_UDT|EN_BCN_FUNCTION|EN_TXBCN_RPT|DIS_BCNQ_SUB));
5320 //SW_BCN_SEL - Port0
5321 //rtw_write8(Adapter, REG_DWBCN1_CTRL_8192E+2, rtw_read8(Adapter, REG_DWBCN1_CTRL_8192E+2) & ~BIT4);
5322 rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
5324 // select BCN on port 0
5325 rtw_write8(padapter, REG_CCK_CHECK_8723B,
5326 (rtw_read8(padapter, REG_CCK_CHECK_8723B)& ~BIT_BCN_PORT_SEL));
5328 #ifdef CONFIG_CONCURRENT_MODE
5329 if (check_buddy_fwstate(padapter, WIFI_FW_NULL_STATE))
5331 val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
5332 val8 &= ~EN_BCN_FUNCTION;
5333 rtw_write8(padapter, REG_BCN_CTRL_1, val8);
5335 #endif // CONFIG_CONCURRENT_MODE
5337 // dis BCN1 ATIM WND if if2 is station
5338 val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
5340 rtw_write8(padapter, REG_BCN_CTRL_1, val8);
5341 #ifdef CONFIG_TSF_RESET_OFFLOAD
5342 // Reset TSF for STA+AP concurrent mode
5343 if (check_buddy_fwstate(padapter, (WIFI_STATION_STATE|WIFI_ASOC_STATE)))
5345 if (reset_tsf(padapter, IFACE_PORT0) == _FALSE)
5346 DBG_871X("ERROR! %s()-%d: Reset port0 TSF fail\n",
5347 __FUNCTION__, __LINE__);
5349 #endif // CONFIG_TSF_RESET_OFFLOAD
5354 static void hw_var_set_macaddr(PADAPTER padapter, u8 variable, u8 *val)
5359 #ifdef CONFIG_CONCURRENT_MODE
5360 if (padapter->iface_type == IFACE_PORT1)
5362 reg_macid = REG_MACID1;
5367 reg_macid = REG_MACID;
5370 for (idx = 0 ; idx < 6; idx++)
5372 rtw_write8(GET_PRIMARY_ADAPTER(padapter), (reg_macid+idx), val[idx]);
5376 static void hw_var_set_bssid(PADAPTER padapter, u8 variable, u8 *val)
5381 #ifdef CONFIG_CONCURRENT_MODE
5382 if (padapter->iface_type == IFACE_PORT1)
5384 reg_bssid = REG_BSSID1;
5389 reg_bssid = REG_BSSID;
5392 for (idx = 0 ; idx < 6; idx++)
5394 rtw_write8(padapter, (reg_bssid+idx), val[idx]);
5398 static void hw_var_set_bcn_func(PADAPTER padapter, u8 variable, u8 *val)
5402 #ifdef CONFIG_CONCURRENT_MODE
5403 if (padapter->iface_type == IFACE_PORT1)
5405 bcn_ctrl_reg = REG_BCN_CTRL_1;
5410 bcn_ctrl_reg = REG_BCN_CTRL;
5415 rtw_write8(padapter, bcn_ctrl_reg, (EN_BCN_FUNCTION | EN_TXBCN_RPT));
5420 val8 = rtw_read8(padapter, bcn_ctrl_reg);
5421 val8 &= ~(EN_BCN_FUNCTION | EN_TXBCN_RPT);
5422 #ifdef CONFIG_BT_COEXIST
5423 // Always enable port0 beacon function for PSTDMA
5424 if (REG_BCN_CTRL == bcn_ctrl_reg)
5425 val8 |= EN_BCN_FUNCTION;
5427 rtw_write8(padapter, bcn_ctrl_reg, val8);
5431 static void hw_var_set_correct_tsf(PADAPTER padapter, u8 variable, u8* val)
5435 struct mlme_ext_priv *pmlmeext;
5436 struct mlme_ext_info *pmlmeinfo;
5439 pmlmeext = &padapter->mlmeextpriv;
5440 pmlmeinfo = &pmlmeext->mlmext_info;
5442 tsf = pmlmeext->TSFValue - rtw_modular64(pmlmeext->TSFValue, (pmlmeinfo->bcn_interval*1024)) -1024; //us
5444 if (((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE) ||
5445 ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
5447 StopTxBeacon(padapter);
5450 #ifdef CONFIG_CONCURRENT_MODE
5451 if (padapter->iface_type == IFACE_PORT1)
5453 // disable related TSF function
5454 val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
5455 val8 &= ~EN_BCN_FUNCTION;
5456 rtw_write8(padapter, REG_BCN_CTRL_1, val8);
5458 rtw_write32(padapter, REG_TSFTR1, tsf);
5459 rtw_write32(padapter, REG_TSFTR1+4, tsf>>32);
5462 // enable related TSF function
5463 val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
5464 val8 |= EN_BCN_FUNCTION;
5465 rtw_write8(padapter, REG_BCN_CTRL_1, val8);
5467 // Update buddy port's TSF if it is SoftAP for beacon TX issue!
5468 if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE
5469 && check_buddy_fwstate(padapter, WIFI_AP_STATE)
5472 // disable related TSF function
5473 val8 = rtw_read8(padapter, REG_BCN_CTRL);
5474 val8 &= ~EN_BCN_FUNCTION;
5475 rtw_write8(padapter, REG_BCN_CTRL, val8);
5477 rtw_write32(padapter, REG_TSFTR, tsf);
5478 rtw_write32(padapter, REG_TSFTR+4, tsf>>32);
5480 // enable related TSF function
5481 val8 = rtw_read8(padapter, REG_BCN_CTRL);
5482 val8 |= EN_BCN_FUNCTION;
5483 rtw_write8(padapter, REG_BCN_CTRL, val8);
5484 #ifdef CONFIG_TSF_RESET_OFFLOAD
5485 // Update buddy port's TSF(TBTT) if it is SoftAP for beacon TX issue!
5486 if (reset_tsf(padapter, IFACE_PORT0) == _FALSE)
5487 DBG_871X("ERROR! %s()-%d: Reset port0 TSF fail\n",
5488 __FUNCTION__, __LINE__);
5490 #endif // CONFIG_TSF_RESET_OFFLOAD
5494 #endif // CONFIG_CONCURRENT_MODE
5496 // disable related TSF function
5497 val8 = rtw_read8(padapter, REG_BCN_CTRL);
5498 val8 &= ~EN_BCN_FUNCTION;
5499 rtw_write8(padapter, REG_BCN_CTRL, val8);
5501 rtw_write32(padapter, REG_TSFTR, tsf);
5502 rtw_write32(padapter, REG_TSFTR+4, tsf>>32);
5504 // enable related TSF function
5505 val8 = rtw_read8(padapter, REG_BCN_CTRL);
5506 val8 |= EN_BCN_FUNCTION;
5507 rtw_write8(padapter, REG_BCN_CTRL, val8);
5509 #ifdef CONFIG_CONCURRENT_MODE
5510 // Update buddy port's TSF if it is SoftAP for beacon TX issue!
5511 if ((pmlmeinfo->state&0x03) == WIFI_FW_STATION_STATE
5512 && check_buddy_fwstate(padapter, WIFI_AP_STATE))
5514 // disable related TSF function
5515 val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
5516 val8 &= ~EN_BCN_FUNCTION;
5517 rtw_write8(padapter, REG_BCN_CTRL_1, val8);
5519 rtw_write32(padapter, REG_TSFTR1, tsf);
5520 rtw_write32(padapter, REG_TSFTR1+4, tsf>>32);
5522 // enable related TSF function
5523 val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
5524 val8 |= EN_BCN_FUNCTION;
5525 rtw_write8(padapter, REG_BCN_CTRL_1, val8);
5527 #ifdef CONFIG_TSF_RESET_OFFLOAD
5528 // Update buddy port's TSF if it is SoftAP for beacon TX issue!
5529 if (reset_tsf(padapter, IFACE_PORT1) == _FALSE)
5531 DBG_871X("ERROR! %s()-%d: Reset port1 TSF fail\n",
5532 __FUNCTION__, __LINE__);
5534 #endif // CONFIG_TSF_RESET_OFFLOAD
5536 #endif // CONFIG_CONCURRENT_MODE
5539 if (((pmlmeinfo->state&0x03) == WIFI_FW_ADHOC_STATE)
5540 || ((pmlmeinfo->state&0x03) == WIFI_FW_AP_STATE))
5542 ResumeTxBeacon(padapter);
5546 static void hw_var_set_mlme_disconnect(PADAPTER padapter, u8 variable, u8 *val)
5550 #ifdef CONFIG_CONCURRENT_MODE
5551 if (check_buddy_mlmeinfo_state(padapter, _HW_STATE_NOLINK_))
5554 // Set RCR to not to receive data frame when NO LINK state
5555 //rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR) & ~RCR_ADF);
5556 // reject all data frames
5557 rtw_write16(padapter, REG_RXFLTMAP2, 0);
5560 #ifdef CONFIG_CONCURRENT_MODE
5561 if (padapter->iface_type == IFACE_PORT1)
5564 rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(1));
5566 // disable update TSF1
5567 val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
5568 val8 |= DIS_TSF_UDT;
5569 rtw_write8(padapter, REG_BCN_CTRL_1, val8);
5571 // disable Port1's beacon function
5572 val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
5573 val8 &= ~EN_BCN_FUNCTION;
5574 rtw_write8(padapter, REG_BCN_CTRL_1, val8);
5580 rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(0));
5582 // disable update TSF
5583 val8 = rtw_read8(padapter, REG_BCN_CTRL);
5584 val8 |= DIS_TSF_UDT;
5585 rtw_write8(padapter, REG_BCN_CTRL, val8);
5589 static void hw_var_set_mlme_sitesurvey(PADAPTER padapter, u8 variable, u8* val)
5591 u32 value_rcr, rcr_clear_bit, reg_bcn_ctl;
5592 u16 value_rxfltmap2;
5594 PHAL_DATA_TYPE pHalData;
5595 struct mlme_priv *pmlmepriv;
5598 pHalData = GET_HAL_DATA(padapter);
5599 pmlmepriv = &padapter->mlmepriv;
5601 #ifdef CONFIG_CONCURRENT_MODE
5602 if (padapter->iface_type == IFACE_PORT1)
5603 reg_bcn_ctl = REG_BCN_CTRL_1;
5606 reg_bcn_ctl = REG_BCN_CTRL;
5608 #ifdef CONFIG_FIND_BEST_CHANNEL
5609 rcr_clear_bit = (RCR_CBSSID_BCN | RCR_CBSSID_DATA);
5611 // Recieve all data frames
5612 value_rxfltmap2 = 0xFFFF;
5613 #else // CONFIG_FIND_BEST_CHANNEL
5615 rcr_clear_bit = RCR_CBSSID_BCN;
5617 // config RCR to receive different BSSID & not to receive data frame
5618 value_rxfltmap2 = 0;
5620 #endif // CONFIG_FIND_BEST_CHANNEL
5622 if ((check_fwstate(pmlmepriv, WIFI_AP_STATE) == _TRUE)
5623 #ifdef CONFIG_CONCURRENT_MODE
5624 || (check_buddy_fwstate(padapter, WIFI_AP_STATE) == _TRUE)
5628 rcr_clear_bit = RCR_CBSSID_BCN;
5631 // TDLS will clear RCR_CBSSID_DATA bit for connection.
5632 else if (padapter->tdlsinfo.link_established == _TRUE)
5634 rcr_clear_bit = RCR_CBSSID_BCN;
5636 #endif // CONFIG_TDLS
5638 value_rcr = rtw_read32(padapter, REG_RCR);
5643 value_rcr &= ~(rcr_clear_bit);
5644 rtw_write32(padapter, REG_RCR, value_rcr);
5646 rtw_write16(padapter, REG_RXFLTMAP2, value_rxfltmap2);
5648 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE))
5650 // disable update TSF
5651 val8 = rtw_read8(padapter, reg_bcn_ctl);
5652 val8 |= DIS_TSF_UDT;
5653 rtw_write8(padapter, reg_bcn_ctl, val8);
5656 // Save orignal RRSR setting.
5657 pHalData->RegRRSR = rtw_read16(padapter, REG_RRSR);
5659 #ifdef CONFIG_CONCURRENT_MODE
5660 if (check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) &&
5661 check_buddy_fwstate(padapter, _FW_LINKED))
5663 StopTxBeacon(padapter);
5670 if (check_fwstate(pmlmepriv, (_FW_LINKED|WIFI_AP_STATE))
5671 #ifdef CONFIG_CONCURRENT_MODE
5672 || check_buddy_fwstate(padapter, (_FW_LINKED|WIFI_AP_STATE))
5676 // enable to rx data frame
5677 rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
5680 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE))
5682 // enable update TSF
5683 val8 = rtw_read8(padapter, reg_bcn_ctl);
5684 val8 &= ~DIS_TSF_UDT;
5685 rtw_write8(padapter, reg_bcn_ctl, val8);
5688 value_rcr |= rcr_clear_bit;
5689 rtw_write32(padapter, REG_RCR, value_rcr);
5691 // Restore orignal RRSR setting.
5692 rtw_write16(padapter, REG_RRSR, pHalData->RegRRSR);
5694 #ifdef CONFIG_CONCURRENT_MODE
5695 if (check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) &&
5696 check_buddy_fwstate(padapter, _FW_LINKED))
5698 ResumeTxBeacon(padapter);
5704 static void hw_var_set_mlme_join(PADAPTER padapter, u8 variable, u8 *val)
5711 PHAL_DATA_TYPE pHalData;
5712 struct mlme_priv *pmlmepriv;
5713 EEPROM_EFUSE_PRIV *pEEPROM;
5718 pHalData = GET_HAL_DATA(padapter);
5719 pmlmepriv = &padapter->mlmepriv;
5720 pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
5722 #ifdef CONFIG_CONCURRENT_MODE
5726 if (check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) &&
5727 check_buddy_fwstate(padapter, _FW_LINKED))
5729 StopTxBeacon(padapter);
5732 // enable to rx data frame.Accept all data frame
5733 rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
5735 if (check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE))
5737 val32 = rtw_read32(padapter, REG_RCR);
5738 val32 |= RCR_CBSSID_BCN;
5739 rtw_write32(padapter, REG_RCR, val32);
5743 val32 = rtw_read32(padapter, REG_RCR);
5744 val32 |= RCR_CBSSID_DATA | RCR_CBSSID_BCN;
5745 rtw_write32(padapter, REG_RCR, val32);
5748 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
5750 RetryLimit = (pEEPROM->CustomerID == RT_CID_CCX) ? 7 : 48;
5759 // joinbss_event call back when join res < 0
5760 if (check_buddy_mlmeinfo_state(padapter, _HW_STATE_NOLINK_))
5761 rtw_write16(padapter, REG_RXFLTMAP2, 0x00);
5763 if (check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) &&
5764 check_buddy_fwstate(padapter, _FW_LINKED))
5766 ResumeTxBeacon(padapter);
5768 // reset TSF 1/2 after ResumeTxBeacon
5769 rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(1)|BIT(0));
5774 // sta add event call back
5776 // enable update TSF
5777 if (padapter->iface_type == IFACE_PORT1)
5779 val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
5780 val8 &= ~DIS_TSF_UDT;
5781 rtw_write8(padapter, REG_BCN_CTRL_1, val8);
5785 val8 = rtw_read8(padapter, REG_BCN_CTRL);
5786 val8 &= ~DIS_TSF_UDT;
5787 rtw_write8(padapter, REG_BCN_CTRL, val8);
5790 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE))
5792 rtw_write8(padapter, 0x542 ,0x02);
5796 if (check_buddy_mlmeinfo_state(padapter, WIFI_FW_AP_STATE) &&
5797 check_buddy_fwstate(padapter, _FW_LINKED))
5799 ResumeTxBeacon(padapter);
5801 // reset TSF 1/2 after ResumeTxBeacon
5802 rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(1)|BIT(0));
5806 val16 = (RetryLimit << RETRY_LIMIT_SHORT_SHIFT) | (RetryLimit << RETRY_LIMIT_LONG_SHIFT);
5807 rtw_write16(padapter, REG_RL, val16);
5808 #else // !CONFIG_CONCURRENT_MODE
5809 if (type == 0) // prepare to join
5811 //enable to rx data frame.Accept all data frame
5812 //rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR)|RCR_ADF);
5813 rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
5815 val32 = rtw_read32(padapter, REG_RCR);
5816 if (padapter->in_cta_test)
5817 val32 &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);//| RCR_ADF
5819 val32 |= RCR_CBSSID_DATA|RCR_CBSSID_BCN;
5820 rtw_write32(padapter, REG_RCR, val32);
5822 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
5824 RetryLimit = (pEEPROM->CustomerID == RT_CID_CCX) ? 7 : 48;
5831 else if (type == 1) //joinbss_event call back when join res < 0
5833 rtw_write16(padapter, REG_RXFLTMAP2, 0x00);
5835 else if (type == 2) //sta add event call back
5838 val8 = rtw_read8(padapter, REG_BCN_CTRL);
5839 val8 &= ~DIS_TSF_UDT;
5840 rtw_write8(padapter, REG_BCN_CTRL, val8);
5842 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE))
5848 val16 = (RetryLimit << RETRY_LIMIT_SHORT_SHIFT) | (RetryLimit << RETRY_LIMIT_LONG_SHIFT);
5849 rtw_write16(padapter, REG_RL, val16);
5850 #endif // !CONFIG_CONCURRENT_MODE
5853 void CCX_FwC2HTxRpt_8723b(PADAPTER padapter, u8 *pdata, u8 len)
5857 #define GET_8723B_C2H_TX_RPT_LIFE_TIME_OVER(_Header) LE_BITS_TO_1BYTE((_Header + 0), 6, 1)
5858 #define GET_8723B_C2H_TX_RPT_RETRY_OVER(_Header) LE_BITS_TO_1BYTE((_Header + 0), 7, 1)
5860 //DBG_871X("%s, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n", __func__,
5861 // *pdata, *(pdata+1), *(pdata+2), *(pdata+3), *(pdata+4), *(pdata+5), *(pdata+6), *(pdata+7));
5863 seq_no = *(pdata+6);
5865 #ifdef CONFIG_XMIT_ACK
5866 if (GET_8723B_C2H_TX_RPT_RETRY_OVER(pdata) | GET_8723B_C2H_TX_RPT_LIFE_TIME_OVER(pdata)) {
5867 rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_CCX_PKT_FAIL);
5870 else if(seq_no != padapter->xmitpriv.seq_no) {
5871 DBG_871X("tx_seq_no=%d, rpt_seq_no=%d\n", padapter->xmitpriv.seq_no, seq_no);
5872 rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_CCX_PKT_FAIL);
5876 rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_SUCCESS);
5881 #ifdef CONFIG_FW_C2H_DEBUG
5883 * C2H RX package original is 128.
5884 * If enable CONFIG_FW_C2H_DEBUG, it should increase to 256.
5885 * C2H FW debug message:
5886 * without aggregate:
5887 * {C2H CmdID, Seq, SubID, Len, Content[0~n]}
5888 * Content[0~n] = { 'a' , 'b' , 'c' ,..., 'z' , '\n'}
5891 * {C2H CmdID, Seq, SubID, Len, Content[0~n]}
5892 * Content[0~n] = { 'a' , 'b' , 'c' ,..., 'z', '\n' , Extend C2H pkt 2...}
5893 * Extend C2H pkt 2 = {C2H CmdID, Seq, SubID, Len, Content = { 'a' , 'b' , 'c' ,..., 'z' , '\n'}}
5897 void Debug_FwC2H_8723b(PADAPTER padapter, u8 *pdata, u8 len)
5900 int cnt = 0, total_length = 0;
5902 u8 more_data = _FALSE;
5903 u8 *nextdata = NULL;
5911 for (i = 0 ; i < len ; i++) {
5912 printk("%02x ", pdata[i]);
5919 data_len = *(nextdata + 1);
5920 seq_no = *(nextdata + 2);
5922 for (i = 0 ; i < data_len - 2 ; i++) {
5923 cnt += sprintf((buf+cnt), "%c", nextdata[3 + i]);
5925 if (nextdata[3 + i] == 0x0a && nextdata[4 + i] == 0xff) {
5927 } else if (nextdata[3 + i] == 0x0a && nextdata[4 + i] != 0xff) {
5932 DBG_871X("[RTKFW, SEQ=%d]: %s", seq_no, buf);
5934 total_length += data_len;
5936 if (more_data == _TRUE) {
5937 _rtw_memset(buf, '\0', 128);
5939 nextdata = (pdata + total_length);
5941 } while (more_data == _TRUE);
5943 #endif //CONFIG_FW_C2H_DEBUG
5945 s32 c2h_id_filter_ccx_8723b(u8 *buf)
5947 struct c2h_evt_hdr_88xx *c2h_evt = (struct c2h_evt_hdr_88xx *)buf;
5949 if (c2h_evt->id == C2H_CCX_TX_RPT)
5956 s32 c2h_handler_8723b(PADAPTER padapter, u8 *buf)
5958 struct c2h_evt_hdr_88xx *pC2hEvent = (struct c2h_evt_hdr_88xx *)buf;
5959 PHAL_DATA_TYPE pHalData=GET_HAL_DATA(padapter);
5960 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
5961 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
5965 if (pC2hEvent == NULL) {
5966 DBG_8192C("%s(): pC2hEventis NULL\n",__FUNCTION__);
5971 switch (pC2hEvent->id)
5973 case C2H_AP_RPT_RSP:
5977 u4Byte c2h_ap_keeplink = _TRUE;
5978 if (c2hBuf[2] == 0 && c2hBuf[3] == 0)
5979 c2h_ap_keeplink = _FALSE;
5981 c2h_ap_keeplink = _TRUE;
5983 if (_TRUE == pmlmeext->try_ap_c2h_wait) {
5984 if (_FALSE == c2h_ap_keeplink) {
5985 pmlmeext->try_ap_c2h_wait = _FALSE;
5986 RT_TRACE(_module_hal_init_c_, _drv_err_,("fw tell us link is off\n"));
5987 receive_disconnect(padapter, pmlmeinfo->network.MacAddress , 65535);
5989 RT_TRACE(_module_hal_init_c_, _drv_err_,("fw tell us link is on\n"));
5992 RT_TRACE(_module_hal_init_c_, _drv_err_,("we don't need this C2H\n"));
5994 pmlmeext->check_ap_processing = _FALSE;
6000 RT_TRACE(_module_hal_init_c_, _drv_info_, ("c2h_handler_8723b: %s\n", pC2hEvent->payload));
6004 case C2H_CCX_TX_RPT:
6005 // CCX_FwC2HTxRpt(padapter, QueueID, pC2hEvent->payload);
6008 #ifdef CONFIG_BT_COEXIST
6009 #ifdef CONFIG_PCI_HCI
6011 // fwc2h_ODM(padapter, tmpBuf, &C2hEvent);
6012 //BT_FwC2hBtRssi(padapter, pC2hEvent->payload);
6017 case C2H_EXT_RA_RPT:
6018 // C2HExtRaRptHandler(padapter, pC2hEvent->payload, C2hEvent.CmdLen);
6021 case C2H_HW_INFO_EXCH:
6022 RT_TRACE(_module_hal_init_c_, _drv_info_, ("[BT], C2H_HW_INFO_EXCH\n"));
6023 for (index = 0; index < pC2hEvent->plen; index++)
6025 RT_TRACE(_module_hal_init_c_, _drv_info_, ("[BT], tmpBuf[%d]=0x%x\n", index, pC2hEvent->payload[index]));
6029 #ifdef CONFIG_BT_COEXIST
6030 case C2H_8723B_BT_INFO:
6031 rtw_btcoex_BtInfoNotify(padapter, pC2hEvent->plen, pC2hEvent->payload);
6035 #ifdef CONFIG_MP_INCLUDED
6036 case C2H_8723B_BT_MP_INFO:
6037 DBG_8192C(" %s, C2H_8723B_BT_MP_INFO pC2hEvent->plen=%d\n",__func__,pC2hEvent->plen);
6038 MPTBT_FwC2hBtMpCtrl(padapter, pC2hEvent->payload, pC2hEvent->plen);
6045 // Clear event to notify FW we have read the command.
6047 // If this field isn't clear, the FW won't update the next command message.
6048 // rtw_write8(padapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
6053 static void process_c2h_event(PADAPTER padapter, PC2H_EVT_HDR pC2hEvent, u8 *c2hBuf)
6056 PHAL_DATA_TYPE pHalData=GET_HAL_DATA(padapter);
6057 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
6058 struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
6060 if (c2hBuf == NULL) {
6061 DBG_8192C("%s c2hbuff is NULL\n",__FUNCTION__);
6065 switch (pC2hEvent->CmdID)
6067 case C2H_AP_RPT_RSP:
6071 u4Byte c2h_ap_keeplink = _TRUE;
6072 if (c2hBuf[2] == 0 && c2hBuf[3] == 0)
6073 c2h_ap_keeplink = _FALSE;
6075 c2h_ap_keeplink = _TRUE;
6077 if (_TRUE == pmlmeext->try_ap_c2h_wait) {
6078 if (_FALSE == c2h_ap_keeplink) {
6079 pmlmeext->try_ap_c2h_wait = _FALSE;
6080 RT_TRACE(_module_hal_init_c_, _drv_err_,("fw tell us link is off\n"));
6081 receive_disconnect(padapter, pmlmeinfo->network.MacAddress , 65535);
6083 RT_TRACE(_module_hal_init_c_, _drv_err_,("fw tell us link is on\n"));
6086 RT_TRACE(_module_hal_init_c_, _drv_err_,("we don't need this C2H\n"));
6088 pmlmeext->check_ap_processing = _FALSE;
6094 RT_TRACE(_module_hal_init_c_, _drv_info_, ("C2HCommandHandler: %s\n", c2hBuf));
6098 case C2H_CCX_TX_RPT:
6099 CCX_FwC2HTxRpt_8723b(padapter, c2hBuf, pC2hEvent->CmdLen);
6102 #ifdef CONFIG_BT_COEXIST
6103 #ifdef CONFIG_PCI_HCI
6105 // fwc2h_ODM(padapter, tmpBuf, &C2hEvent);
6106 //BT_FwC2hBtRssi(padapter, c2hBuf);
6111 case C2H_EXT_RA_RPT:
6112 // C2HExtRaRptHandler(padapter, tmpBuf, C2hEvent.CmdLen);
6115 case C2H_HW_INFO_EXCH:
6116 RT_TRACE(_module_hal_init_c_, _drv_info_, ("[BT], C2H_HW_INFO_EXCH\n"));
6117 for (index = 0; index < pC2hEvent->CmdLen; index++)
6119 RT_TRACE(_module_hal_init_c_, _drv_info_, ("[BT], tmpBuf[%d]=0x%x\n", index, c2hBuf[index]));
6123 #ifdef CONFIG_BT_COEXIST
6124 case C2H_8723B_BT_INFO:
6125 rtw_btcoex_BtInfoNotify(padapter, pC2hEvent->CmdLen, c2hBuf);
6129 #ifdef CONFIG_MP_INCLUDED
6130 case C2H_8723B_BT_MP_INFO:
6131 MPTBT_FwC2hBtMpCtrl(padapter, c2hBuf, pC2hEvent->CmdLen);
6135 #ifdef CONFIG_FW_C2H_DEBUG
6136 case C2H_8723B_FW_DEBUG:
6137 Debug_FwC2H_8723b(padapter, c2hBuf, pC2hEvent->CmdLen);
6139 #endif // CONFIG_FW_C2H_DEBUG
6145 #ifndef CONFIG_C2H_PACKET_EN
6146 // Clear event to notify FW we have read the command.
6148 // If this field isn't clear, the FW won't update the next command message.
6149 rtw_write8(padapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
6153 #ifdef CONFIG_C2H_PACKET_EN
6155 static void C2HPacketHandler_8723B(PADAPTER padapter, u8 *pbuffer, u16 length)
6157 C2H_EVT_HDR C2hEvent;
6159 #ifdef CONFIG_WOWLAN
6160 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
6162 if(pwrpriv->wowlan_mode == _TRUE)
6164 DBG_871X("%s(): return because wowolan_mode==TRUE! CMDID=%d\n", __func__, pbuffer[0]);
6168 C2hEvent.CmdID = pbuffer[0];
6169 C2hEvent.CmdSeq = pbuffer[1];
6170 C2hEvent.CmdLen = length - 2;
6171 tmpBuf = pbuffer + 2;
6173 //DBG_871X("%s C2hEvent.CmdID:%x C2hEvent.CmdLen:%x C2hEvent.CmdSeq:%x\n",
6174 // __func__, C2hEvent.CmdID, C2hEvent.CmdLen, C2hEvent.CmdSeq);
6175 RT_PRINT_DATA(_module_hal_init_c_, _drv_notice_, "C2HPacketHandler_8723B(): Command Content:\n", tmpBuf, C2hEvent.CmdLen);
6177 process_c2h_event(padapter, &C2hEvent, tmpBuf);
6178 //c2h_handler_8723b(padapter,&C2hEvent);
6182 void rtl8723b_c2h_packet_handler(PADAPTER padapter, u8 *pbuf, u16 length)
6184 C2H_EVT_HDR C2hEvent;
6191 C2hEvent.CmdID = pbuf[0];
6192 C2hEvent.CmdSeq = pbuf[1];
6193 C2hEvent.CmdLen = length - 2;
6196 DBG_8192C("%s: C2H, ID=%d seq=%d len=%d\n",
6197 __FUNCTION__, C2hEvent.CmdID, C2hEvent.CmdSeq, C2hEvent.CmdLen);
6199 switch (C2hEvent.CmdID) {
6200 case C2H_CCX_TX_RPT:
6201 #ifdef CONFIG_FW_C2H_DEBUG
6202 case C2H_8723B_FW_DEBUG:
6203 #endif // CONFIG_FW_C2H_DEBUG
6204 process_c2h_event(padapter, &C2hEvent, pdata);
6208 pdata = rtw_zmalloc(length);
6211 _rtw_memcpy(pdata, pbuf, length);
6212 if (rtw_c2h_packet_wk_cmd(padapter, pdata, length) == _FAIL)
6213 rtw_mfree(pdata, length);
6218 #else // !CONFIG_C2H_PACKET_EN
6221 // Field TRIGGER CONTENT CMD_SEQ CMD_LEN CMD_ID
6222 // BITS [127:120] [119:16] [15:8] [7:4] [3:0]
6223 //2009.10.08. by tynli.
6224 static void C2HCommandHandler(PADAPTER padapter)
6226 C2H_EVT_HDR C2hEvent;
6227 #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
6231 u8 bCmdMsgReady = _FALSE;
6235 _rtw_memset(&C2hEvent, 0, sizeof(C2H_EVT_HDR));
6237 C2hEvent.CmdID = rtw_read8(padapter, REG_C2HEVT_CMD_ID_8723B);
6238 C2hEvent.CmdLen = rtw_read8(padapter, REG_C2HEVT_CMD_LEN_8723B);
6239 C2hEvent.CmdSeq = rtw_read8(padapter, REG_C2HEVT_CMD_ID_8723B + 1);
6241 RT_PRINT_DATA(_module_hal_init_c_, _drv_info_, "C2HCommandHandler(): ",
6242 &C2hEvent , sizeof(C2hEvent));
6244 U1bTmp = rtw_read8(padapter, REG_C2HEVT_CLEAR);
6245 DBG_871X("%s C2hEvent.CmdID:%x C2hEvent.CmdLen:%x C2hEvent.CmdSeq:%x\n",
6246 __func__, C2hEvent.CmdID, C2hEvent.CmdLen, C2hEvent.CmdSeq);
6248 if (U1bTmp == C2H_EVT_HOST_CLOSE)
6253 else if (U1bTmp == C2H_EVT_FW_CLOSE)
6255 bCmdMsgReady = _TRUE;
6259 // Not a valid value, reset the clear event.
6263 if(C2hEvent.CmdLen == 0)
6265 tmpBuf = rtw_zmalloc(C2hEvent.CmdLen);
6270 for (index = 0; index < C2hEvent.CmdLen; index++)
6272 tmpBuf[index] = rtw_read8(padapter, REG_C2HEVT_CMD_ID_8723B + 2 + index);
6275 RT_PRINT_DATA(_module_hal_init_c_, _drv_notice_, "C2HCommandHandler(): Command Content:\n", tmpBuf, C2hEvent.CmdLen);
6277 //process_c2h_event(padapter,&C2hEvent, tmpBuf);
6278 c2h_handler_8723b(padapter,&C2hEvent);
6280 rtw_mfree(tmpBuf, C2hEvent.CmdLen);
6281 #endif // CONFIG_SDIO_HCI || CONFIG_GSPI_HCI
6283 #ifdef CONFIG_USB_HCI
6284 HAL_DATA_TYPE *pHalData=GET_HAL_DATA(padapter);
6286 _rtw_memset(&C2hEvent, 0, sizeof(C2H_EVT_HDR));
6287 C2hEvent.CmdID = pHalData->C2hArray[USB_C2H_CMDID_OFFSET] & 0xF;
6288 C2hEvent.CmdLen = (pHalData->C2hArray[USB_C2H_CMDID_OFFSET] & 0xF0) >> 4;
6289 C2hEvent.CmdSeq =pHalData->C2hArray[USB_C2H_SEQ_OFFSET];
6290 c2h_handler_8723b(padapter,(u8 *)&C2hEvent);
6291 //process_c2h_event(padapter,&C2hEvent,&pHalData->C2hArray[USB_C2H_EVENT_OFFSET]);
6292 #endif // CONFIG_USB_HCI
6294 //REG_C2HEVT_CLEAR have done in process_c2h_event
6297 rtw_write8(padapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
6301 #endif // !CONFIG_C2H_PACKET_EN
6303 void SetHwReg8723B(PADAPTER padapter, u8 variable, u8 *val)
6305 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
6314 case HW_VAR_MEDIA_STATUS:
6315 val8 = rtw_read8(padapter, MSR) & 0x0c;
6317 rtw_write8(padapter, MSR, val8);
6320 case HW_VAR_MEDIA_STATUS1:
6321 val8 = rtw_read8(padapter, MSR) & 0x03;
6323 rtw_write8(padapter, MSR, val8);
6326 case HW_VAR_SET_OPMODE:
6327 hw_var_set_opmode(padapter, variable, val);
6330 case HW_VAR_MAC_ADDR:
6331 hw_var_set_macaddr(padapter, variable, val);
6335 hw_var_set_bssid(padapter, variable, val);
6338 case HW_VAR_BASIC_RATE:
6340 struct mlme_ext_info *mlmext_info = &padapter->mlmeextpriv.mlmext_info;
6341 u16 input_b = 0, masked = 0, ioted = 0, BrateCfg = 0;
6342 u16 rrsr_2g_force_mask = (RRSR_11M|RRSR_5_5M|RRSR_1M);
6343 u16 rrsr_2g_allow_mask = (RRSR_24M|RRSR_12M|RRSR_6M|RRSR_CCK_RATES);
6345 HalSetBrateCfg(padapter, val, &BrateCfg);
6348 /* apply force and allow mask */
6349 BrateCfg |= rrsr_2g_force_mask;
6350 BrateCfg &= rrsr_2g_allow_mask;
6353 #ifdef CONFIG_CMCC_TEST
6354 BrateCfg |= (RRSR_11M|RRSR_5_5M|RRSR_1M); /* use 11M to send ACK */
6355 BrateCfg |= (RRSR_24M|RRSR_18M|RRSR_12M); //CMCC_OFDM_ACK 12/18/24M
6358 /* IOT consideration */
6359 if (mlmext_info->assoc_AP_vendor == HT_IOT_PEER_CISCO) {
6360 /* if peer is cisco and didn't use ofdm rate, we enable 6M ack */
6361 if((BrateCfg & (RRSR_24M|RRSR_12M|RRSR_6M)) == 0)
6362 BrateCfg |= RRSR_6M;
6366 pHalData->BasicRateSet = BrateCfg;
6368 DBG_8192C("HW_VAR_BASIC_RATE: %#x -> %#x -> %#x\n", input_b, masked, ioted);
6370 // Set RRSR rate table.
6371 rtw_write16(padapter, REG_RRSR, BrateCfg);
6372 rtw_write8(padapter, REG_RRSR+2, rtw_read8(padapter, REG_RRSR+2)&0xf0);
6376 case HW_VAR_TXPAUSE:
6377 rtw_write8(padapter, REG_TXPAUSE, *val);
6380 case HW_VAR_BCN_FUNC:
6381 hw_var_set_bcn_func(padapter, variable, val);
6384 case HW_VAR_CORRECT_TSF:
6385 hw_var_set_correct_tsf(padapter, variable, val);
6388 case HW_VAR_CHECK_BSSID:
6391 val32 = rtw_read32(padapter, REG_RCR);
6393 val32 |= RCR_CBSSID_DATA|RCR_CBSSID_BCN;
6395 val32 &= ~(RCR_CBSSID_DATA|RCR_CBSSID_BCN);
6396 rtw_write32(padapter, REG_RCR, val32);
6400 case HW_VAR_MLME_DISCONNECT:
6401 hw_var_set_mlme_disconnect(padapter, variable, val);
6404 case HW_VAR_MLME_SITESURVEY:
6405 hw_var_set_mlme_sitesurvey(padapter, variable, val);
6407 #ifdef CONFIG_BT_COEXIST
6408 rtw_btcoex_ScanNotify(padapter, *val?_TRUE:_FALSE);
6409 #endif // CONFIG_BT_COEXIST
6412 case HW_VAR_MLME_JOIN:
6413 hw_var_set_mlme_join(padapter, variable, val);
6415 #ifdef CONFIG_BT_COEXIST
6420 rtw_btcoex_ConnectNotify(padapter, _TRUE);
6423 // joinbss_event callback when join res < 0
6424 rtw_btcoex_ConnectNotify(padapter, _FALSE);
6427 // sta add event callback
6428 // rtw_btcoex_MediaStatusNotify(padapter, RT_MEDIA_CONNECT);
6431 #endif // CONFIG_BT_COEXIST
6434 case HW_VAR_ON_RCR_AM:
6435 val32 = rtw_read32(padapter, REG_RCR);
6437 rtw_write32(padapter, REG_RCR, val32);
6438 DBG_8192C("%s, %d, RCR= %x\n", __FUNCTION__, __LINE__, rtw_read32(padapter, REG_RCR));
6441 case HW_VAR_OFF_RCR_AM:
6442 val32 = rtw_read32(padapter, REG_RCR);
6444 rtw_write32(padapter, REG_RCR, val32);
6445 DBG_8192C("%s, %d, RCR= %x\n", __FUNCTION__, __LINE__, rtw_read32(padapter, REG_RCR));
6448 case HW_VAR_BEACON_INTERVAL:
6449 rtw_write16(padapter, REG_BCN_INTERVAL, *((u16*)val));
6452 case HW_VAR_SLOT_TIME:
6453 rtw_write8(padapter, REG_SLOT, *val);
6456 case HW_VAR_RESP_SIFS:
6458 // SIFS for OFDM Data ACK
6459 rtw_write8(padapter, REG_SIFS_CTX+1, val[0]);
6460 // SIFS for OFDM consecutive tx like CTS data!
6461 rtw_write8(padapter, REG_SIFS_TRX+1, val[1]);
6463 rtw_write8(padapter, REG_SPEC_SIFS+1, val[0]);
6464 rtw_write8(padapter, REG_MAC_SPEC_SIFS+1, val[0]);
6466 // 20100719 Joseph: Revise SIFS setting due to Hardware register definition change.
6467 rtw_write8(padapter, REG_R2T_SIFS+1, val[0]);
6468 rtw_write8(padapter, REG_T2T_SIFS+1, val[0]);
6471 //SIFS_Timer = 0x0a0a0808;
6473 rtw_write8(padapter, REG_RESP_SIFS_CCK, val[0]); // SIFS_T2T_CCK (0x08)
6474 rtw_write8(padapter, REG_RESP_SIFS_CCK+1, val[1]); //SIFS_R2T_CCK(0x08)
6475 //RESP_SIFS for OFDM
6476 rtw_write8(padapter, REG_RESP_SIFS_OFDM, val[2]); //SIFS_T2T_OFDM (0x0a)
6477 rtw_write8(padapter, REG_RESP_SIFS_OFDM+1, val[3]); //SIFS_R2T_OFDM(0x0a)
6481 case HW_VAR_ACK_PREAMBLE:
6484 u8 bShortPreamble = *val;
6486 // Joseph marked out for Netgear 3500 TKIP channel 7 issue.(Temporarily)
6487 //regTmp = (pHalData->nCur40MhzPrimeSC)<<5;
6489 if (bShortPreamble) regTmp |= 0x80;
6490 rtw_write8(padapter, REG_RRSR+2, regTmp);
6494 case HW_VAR_CAM_EMPTY_ENTRY:
6500 u32 ulEncAlgo = CAM_AES;
6502 for (i=0; i<CAM_CONTENT_COUNT; i++)
6504 // filled id in CAM config 2 byte
6507 ulContent |= (ucIndex & 0x03) | ((u16)(ulEncAlgo)<<2);
6508 //ulContent |= CAM_VALID;
6514 // polling bit, and No Write enable, and address
6515 ulCommand = CAM_CONTENT_COUNT*ucIndex+i;
6516 ulCommand = ulCommand | CAM_POLLINIG | CAM_WRITE;
6517 // write content 0 is equall to mark invalid
6518 rtw_write32(padapter, WCAMI, ulContent); //delay_ms(40);
6519 //RT_TRACE(COMP_SEC, DBG_LOUD, ("CAM_empty_entry(): WRITE A4: %lx \n",ulContent));
6520 rtw_write32(padapter, RWCAM, ulCommand); //delay_ms(40);
6521 //RT_TRACE(COMP_SEC, DBG_LOUD, ("CAM_empty_entry(): WRITE A0: %lx \n",ulCommand));
6526 case HW_VAR_CAM_INVALID_ALL:
6527 rtw_write32(padapter, RWCAM, BIT(31)|BIT(30));
6530 case HW_VAR_CAM_WRITE:
6533 u32 *cam_val = (u32*)val;
6535 rtw_write32(padapter, WCAMI, cam_val[0]);
6537 cmd = CAM_POLLINIG | CAM_WRITE | cam_val[1];
6538 rtw_write32(padapter, RWCAM, cmd);
6542 case HW_VAR_AC_PARAM_VO:
6543 rtw_write32(padapter, REG_EDCA_VO_PARAM, *((u32*)val));
6546 case HW_VAR_AC_PARAM_VI:
6547 rtw_write32(padapter, REG_EDCA_VI_PARAM, *((u32*)val));
6550 case HW_VAR_AC_PARAM_BE:
6551 pHalData->AcParam_BE = ((u32*)(val))[0];
6552 rtw_write32(padapter, REG_EDCA_BE_PARAM, *((u32*)val));
6555 case HW_VAR_AC_PARAM_BK:
6556 rtw_write32(padapter, REG_EDCA_BK_PARAM, *((u32*)val));
6559 case HW_VAR_ACM_CTRL:
6561 u8 ctrl = *((u8*)val);
6566 hwctrl |= AcmHw_HwEn;
6568 if (ctrl & BIT(1)) // BE
6569 hwctrl |= AcmHw_BeqEn;
6571 if (ctrl & BIT(2)) // VI
6572 hwctrl |= AcmHw_ViqEn;
6574 if (ctrl & BIT(3)) // VO
6575 hwctrl |= AcmHw_VoqEn;
6578 DBG_8192C("[HW_VAR_ACM_CTRL] Write 0x%02X\n", hwctrl);
6579 rtw_write8(padapter, REG_ACMHWCTRL, hwctrl);
6583 case HW_VAR_AMPDU_FACTOR:
6585 u32 AMPDULen = (*((u8 *)val));
6587 if(AMPDULen < HT_AGG_SIZE_32K)
6588 AMPDULen = (0x2000 << (*((u8 *)val))) -1;
6592 rtw_write32(padapter, REG_AMPDU_MAX_LENGTH_8723B, AMPDULen);
6597 case HW_VAR_RXDMA_AGG_PG_TH:
6598 rtw_write8(padapter, REG_RXDMA_AGG_PG_TH, *val);
6602 case HW_VAR_H2C_FW_PWRMODE:
6606 // Forece leave RF low power mode for 1T1R to prevent conficting setting in Fw power
6607 // saving sequence. 2010.06.07. Added by tynli. Suggested by SD3 yschang.
6608 if ((psmode != PS_MODE_ACTIVE) && (!IS_92C_SERIAL(pHalData->VersionID)))
6610 ODM_RF_Saving(&pHalData->odmpriv, _TRUE);
6613 //if (psmode != PS_MODE_ACTIVE) {
6614 // rtl8723b_set_lowpwr_lps_cmd(padapter, _TRUE);
6616 // rtl8723b_set_lowpwr_lps_cmd(padapter, _FALSE);
6618 rtl8723b_set_FwPwrMode_cmd(padapter, psmode);
6621 case HW_VAR_H2C_PS_TUNE_PARAM:
6622 rtl8723b_set_FwPsTuneParam_cmd(padapter);
6625 case HW_VAR_H2C_FW_JOINBSSRPT:
6626 rtl8723b_set_FwJoinBssRpt_cmd(padapter, *val);
6630 case HW_VAR_H2C_FW_P2P_PS_OFFLOAD:
6631 rtl8723b_set_p2p_ps_offload_cmd(padapter, *val);
6635 case HW_VAR_TDLS_WRCR:
6636 rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR)&(~RCR_CBSSID_DATA ));
6638 case HW_VAR_TDLS_INIT_CH_SEN:
6640 rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR)&(~ RCR_CBSSID_DATA )&(~RCR_CBSSID_BCN ));
6641 rtw_write16(padapter, REG_RXFLTMAP2,0xffff);
6643 //disable update TSF
6644 rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL)|DIS_TSF_UDT);
6647 case HW_VAR_TDLS_DONE_CH_SEN:
6650 rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL)&(~ DIS_TSF_UDT));
6651 rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR)|(RCR_CBSSID_BCN ));
6654 case HW_VAR_TDLS_RS_RCR:
6655 rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR)|(RCR_CBSSID_DATA));
6657 #endif //CONFIG_TDLS
6658 #ifdef CONFIG_SW_ANTENNA_DIVERSITY
6659 case HW_VAR_ANTENNA_DIVERSITY_LINK:
6660 //SwAntDivRestAfterLink8192C(padapter);
6661 ODM_SwAntDivRestAfterLink(&pHalData->odmpriv);
6664 case HW_VAR_ANTENNA_DIVERSITY_SELECT:
6666 u8 Optimum_antenna = *val;
6668 //DBG_8192C("==> HW_VAR_ANTENNA_DIVERSITY_SELECT , Ant_(%s)\n",(Optimum_antenna==2)?"A":"B");
6670 //PHY_SetBBReg(padapter, rFPGA0_XA_RFInterfaceOE, 0x300, Optimum_antenna);
6671 ODM_SetAntenna(&pHalData->odmpriv, Optimum_antenna);
6676 case HW_VAR_EFUSE_USAGE:
6677 pHalData->EfuseUsedPercentage = *val;
6680 case HW_VAR_EFUSE_BYTES:
6681 pHalData->EfuseUsedBytes = *((u16*)val);
6684 case HW_VAR_EFUSE_BT_USAGE:
6685 #ifdef HAL_EFUSE_MEMORY
6686 pHalData->EfuseHal.BTEfuseUsedPercentage = *val;
6690 case HW_VAR_EFUSE_BT_BYTES:
6691 #ifdef HAL_EFUSE_MEMORY
6692 pHalData->EfuseHal.BTEfuseUsedBytes = *((u16*)val);
6694 BTEfuseUsedBytes = *((u16*)val);
6698 case HW_VAR_FIFO_CLEARN_UP:
6700 #define RW_RELEASE_EN BIT(18)
6701 #define RXDMA_IDLE BIT(17)
6703 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
6707 rtw_write8(padapter, REG_TXPAUSE, 0xff);
6710 padapter->xmitpriv.nqos_ssn = rtw_read16(padapter, REG_NQOS_SEQ);
6712 if (pwrpriv->bkeepfwalive != _TRUE)
6715 val32 = rtw_read32(padapter, REG_RXPKT_NUM);
6716 val32 |= RW_RELEASE_EN;
6717 rtw_write32(padapter, REG_RXPKT_NUM, val32);
6719 val32 = rtw_read32(padapter, REG_RXPKT_NUM);
6720 val32 &= RXDMA_IDLE;
6724 DBG_871X("%s: [HW_VAR_FIFO_CLEARN_UP] val=%x times:%d\n", __FUNCTION__, val32, trycnt);
6727 DBG_8192C("[HW_VAR_FIFO_CLEARN_UP] Stop RX DMA failed......\n");
6731 rtw_write16(padapter, REG_RQPN_NPQ, 0);
6732 rtw_write32(padapter, REG_RQPN, 0x80000000);
6738 #ifdef CONFIG_CONCURRENT_MODE
6739 case HW_VAR_CHECK_TXBUF:
6742 u8 RetryLimit = 0x01;
6743 u32 reg_200, reg_204;
6745 val16 = RetryLimit << RETRY_LIMIT_SHORT_SHIFT | RetryLimit << RETRY_LIMIT_LONG_SHIFT;
6746 rtw_write16(padapter, REG_RL, val16);
6748 for (i=0; i<200; i++) // polling 200x10=2000 msec
6750 reg_200 = rtw_read32(padapter, 0x200);
6751 reg_204 = rtw_read32(padapter, 0x204);
6752 if (reg_200 != reg_204)
6754 //DBG_871X("packet in tx packet buffer - 0x204=%x, 0x200=%x (%d)\n", rtw_read32(padapter, 0x204), rtw_read32(padapter, 0x200), i);
6759 DBG_871X("[HW_VAR_CHECK_TXBUF] no packet in tx packet buffer (%d)\n", i);
6764 if (reg_200 != reg_204)
6765 DBG_871X("packets in tx buffer - 0x204=%x, 0x200=%x\n", reg_204, reg_200);
6768 val16 = RetryLimit << RETRY_LIMIT_SHORT_SHIFT | RetryLimit << RETRY_LIMIT_LONG_SHIFT;
6769 rtw_write16(padapter, REG_RL, val16);
6772 #endif // CONFIG_CONCURRENT_MODE
6774 case HW_VAR_APFM_ON_MAC:
6775 pHalData->bMacPwrCtrlOn = *val;
6776 #ifdef PLATFORM_LINUX
6777 DBG_8192C("%s: bMacPwrCtrlOn=%d\n", __func__, pHalData->bMacPwrCtrlOn);
6781 case HW_VAR_NAV_UPPER:
6783 u32 usNavUpper = *((u32*)val);
6785 if (usNavUpper > HAL_NAV_UPPER_UNIT_8723B * 0xFF)
6787 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_NAV_UPPER_UNIT_8723B));
6791 // The value of ((usNavUpper + HAL_NAV_UPPER_UNIT_8723B - 1) / HAL_NAV_UPPER_UNIT_8723B)
6792 // is getting the upper integer.
6793 usNavUpper = (usNavUpper + HAL_NAV_UPPER_UNIT_8723B - 1) / HAL_NAV_UPPER_UNIT_8723B;
6794 rtw_write8(padapter, REG_NAV_UPPER, (u8)usNavUpper);
6798 #ifndef CONFIG_C2H_PACKET_EN
6799 case HW_VAR_C2H_HANDLE:
6800 C2HCommandHandler(padapter);
6804 case HW_VAR_H2C_MEDIA_STATUS_RPT:
6806 u16 mstatus_rpt = (*(u16 *)val);
6809 mstatus = (u8) (mstatus_rpt & 0xFF);
6810 macId = (u8)(mstatus_rpt >> 8) ;
6811 rtl8723b_set_FwMediaStatusRpt_cmd(padapter , mstatus, macId);
6814 case HW_VAR_BCN_VALID:
6815 #ifdef CONFIG_CONCURRENT_MODE
6816 if (padapter->iface_type == IFACE_PORT1)
6818 val8 = rtw_read8(padapter, REG_DWBCN1_CTRL_8723B+2);
6820 rtw_write8(padapter, REG_DWBCN1_CTRL_8723B+2, val8);
6823 #endif // CONFIG_CONCURRENT_MODE
6825 // BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2, write 1 to clear, Clear by sw
6826 val8 = rtw_read8(padapter, REG_TDECTRL+2);
6828 rtw_write8(padapter, REG_TDECTRL+2, val8);
6832 case HW_VAR_DL_BCN_SEL:
6833 #ifdef CONFIG_CONCURRENT_MODE
6834 if (padapter->iface_type == IFACE_PORT1)
6836 // SW_BCN_SEL - Port1
6837 val8 = rtw_read8(padapter, REG_DWBCN1_CTRL_8723B+2);
6839 rtw_write8(padapter, REG_DWBCN1_CTRL_8723B+2, val8);
6842 #endif // CONFIG_CONCURRENT_MODE
6844 // SW_BCN_SEL - Port0
6845 val8 = rtw_read8(padapter, REG_DWBCN1_CTRL_8723B+2);
6847 rtw_write8(padapter, REG_DWBCN1_CTRL_8723B+2, val8);
6852 pHalData->bNeedIQK = _TRUE;
6855 case HW_VAR_DL_RSVD_PAGE:
6856 #ifdef CONFIG_BT_COEXIST
6857 if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE)
6859 rtl8723b_download_BTCoex_AP_mode_rsvd_page(padapter);
6862 #endif // CONFIG_BT_COEXIST
6864 rtl8723b_download_rsvd_page(padapter, RT_MEDIA_CONNECT);
6868 case HW_VAR_MACID_SLEEP:
6870 u32 reg_macid_sleep;
6875 reg_macid_sleep = REG_MACID_SLEEP;
6877 } else if (id < 64) {
6878 reg_macid_sleep = REG_MACID_SLEEP_1;
6880 } else if (id < 96) {
6881 reg_macid_sleep = REG_MACID_SLEEP_2;
6883 } else if (id < 128) {
6884 reg_macid_sleep = REG_MACID_SLEEP_3;
6891 val32 = rtw_read32(padapter, reg_macid_sleep);
6892 DBG_8192C(FUNC_ADPT_FMT ": [HW_VAR_MACID_SLEEP] macid=%d, org reg_0x%03x=0x%08X\n",
6893 FUNC_ADPT_ARG(padapter), id, reg_macid_sleep, val32);
6895 if (val32 & BIT(bit_shift))
6898 val32 |= BIT(bit_shift);
6899 rtw_write32(padapter, reg_macid_sleep, val32);
6903 case HW_VAR_MACID_WAKEUP:
6905 u32 reg_macid_sleep;
6910 reg_macid_sleep = REG_MACID_SLEEP;
6912 } else if (id < 64) {
6913 reg_macid_sleep = REG_MACID_SLEEP_1;
6915 } else if (id < 96) {
6916 reg_macid_sleep = REG_MACID_SLEEP_2;
6918 } else if (id < 128) {
6919 reg_macid_sleep = REG_MACID_SLEEP_3;
6926 val32 = rtw_read32(padapter, reg_macid_sleep);
6927 DBG_8192C(FUNC_ADPT_FMT ": [HW_VAR_MACID_WAKEUP] macid=%d, org reg_0x%03x=0x%08X\n",
6928 FUNC_ADPT_ARG(padapter), id, reg_macid_sleep, val32);
6930 if (!(val32 & BIT(bit_shift)))
6933 val32 &= ~BIT(bit_shift);
6934 rtw_write32(padapter, reg_macid_sleep, val32);
6939 SetHwReg(padapter, variable, val);
6946 struct qinfo_8723b {
6954 struct bcn_qinfo_8723b {
6959 void dump_qinfo_8723b(void *sel, struct qinfo_8723b *info, const char *tag)
6961 //if (info->pkt_num)
6962 DBG_871X_SEL_NL(sel, "%shead:0x%02x, tail:0x%02x, pkt_num:%u, macid:%u, ac:%u\n"
6963 , tag ? tag : "", info->head, info->tail, info->pkt_num, info->macid, info->ac
6967 void dump_bcn_qinfo_8723b(void *sel, struct bcn_qinfo_8723b *info, const char *tag)
6969 //if (info->pkt_num)
6970 DBG_871X_SEL_NL(sel, "%shead:0x%02x, pkt_num:%u\n"
6971 , tag ? tag : "", info->head, info->pkt_num
6975 void dump_mac_qinfo_8723b(void *sel, _adapter *adapter)
6989 q0_info = rtw_read32(adapter, REG_Q0_INFO);
6990 q1_info = rtw_read32(adapter, REG_Q1_INFO);
6991 q2_info = rtw_read32(adapter, REG_Q2_INFO);
6992 q3_info = rtw_read32(adapter, REG_Q3_INFO);
6993 q4_info = rtw_read32(adapter, REG_Q4_INFO);
6994 q5_info = rtw_read32(adapter, REG_Q5_INFO);
6995 q6_info = rtw_read32(adapter, REG_Q6_INFO);
6996 q7_info = rtw_read32(adapter, REG_Q7_INFO);
6997 mg_q_info = rtw_read32(adapter, REG_MGQ_INFO);
6998 hi_q_info = rtw_read32(adapter, REG_HGQ_INFO);
6999 bcn_q_info = rtw_read16(adapter, REG_BCNQ_INFO);
7001 dump_qinfo_8723b(sel, (struct qinfo_8723b *)&q0_info, "Q0 ");
7002 dump_qinfo_8723b(sel, (struct qinfo_8723b *)&q1_info, "Q1 ");
7003 dump_qinfo_8723b(sel, (struct qinfo_8723b *)&q2_info, "Q2 ");
7004 dump_qinfo_8723b(sel, (struct qinfo_8723b *)&q3_info, "Q3 ");
7005 dump_qinfo_8723b(sel, (struct qinfo_8723b *)&q4_info, "Q4 ");
7006 dump_qinfo_8723b(sel, (struct qinfo_8723b *)&q5_info, "Q5 ");
7007 dump_qinfo_8723b(sel, (struct qinfo_8723b *)&q6_info, "Q6 ");
7008 dump_qinfo_8723b(sel, (struct qinfo_8723b *)&q7_info, "Q7 ");
7009 dump_qinfo_8723b(sel, (struct qinfo_8723b *)&mg_q_info, "MG ");
7010 dump_qinfo_8723b(sel, (struct qinfo_8723b *)&hi_q_info, "HI ");
7011 dump_bcn_qinfo_8723b(sel, (struct bcn_qinfo_8723b *)&bcn_q_info, "BCN ");
7014 void GetHwReg8723B(PADAPTER padapter, u8 variable, u8 *val)
7016 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
7024 case HW_VAR_TXPAUSE:
7025 *val = rtw_read8(padapter, REG_TXPAUSE);
7028 case HW_VAR_BCN_VALID:
7029 #ifdef CONFIG_CONCURRENT_MODE
7030 if (padapter->iface_type == IFACE_PORT1)
7032 val8 = rtw_read8(padapter, REG_DWBCN1_CTRL_8723B+2);
7033 *val = (BIT(0) & val8) ? _TRUE:_FALSE;
7038 // BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2
7039 val8 = rtw_read8(padapter, REG_TDECTRL+2);
7040 *val = (BIT(0) & val8) ? _TRUE:_FALSE;
7044 case HW_VAR_FWLPS_RF_ON:
7046 // When we halt NIC, we should check if FW LPS is leave.
7049 if ((padapter->bSurpriseRemoved == _TRUE) ||
7050 (adapter_to_pwrctl(padapter)->rf_pwrstate == rf_off))
7052 // If it is in HW/SW Radio OFF or IPS state, we do not check Fw LPS Leave,
7053 // because Fw is unload.
7058 valRCR = rtw_read32(padapter, REG_RCR);
7059 valRCR &= 0x00070000;
7068 #ifdef CONFIG_ANTENNA_DIVERSITY
7069 case HW_VAR_CURRENT_ANTENNA:
7070 *val = pHalData->CurAntenna;
7074 case HW_VAR_EFUSE_USAGE:
7075 *val = pHalData->EfuseUsedPercentage;
7078 case HW_VAR_EFUSE_BYTES:
7079 *((u16*)val) = pHalData->EfuseUsedBytes;
7082 case HW_VAR_EFUSE_BT_USAGE:
7083 #ifdef HAL_EFUSE_MEMORY
7084 *val = pHalData->EfuseHal.BTEfuseUsedPercentage;
7088 case HW_VAR_EFUSE_BT_BYTES:
7089 #ifdef HAL_EFUSE_MEMORY
7090 *((u16*)val) = pHalData->EfuseHal.BTEfuseUsedBytes;
7092 *((u16*)val) = BTEfuseUsedBytes;
7096 case HW_VAR_APFM_ON_MAC:
7097 *val = pHalData->bMacPwrCtrlOn;
7099 case HW_VAR_CHK_HI_QUEUE_EMPTY:
7100 val16 = rtw_read16(padapter, REG_TXPKT_EMPTY);
7101 *val = (val16 & BIT(10)) ? _TRUE:_FALSE;
7103 #ifdef CONFIG_WOWLAN
7104 case HW_VAR_RPWM_TOG:
7105 *val = rtw_read8(padapter, SDIO_LOCAL_BASE|SDIO_REG_HRPWM1) & BIT7;
7107 case HW_VAR_WAKEUP_REASON:
7108 *val = rtw_read8(padapter, REG_WOWLAN_WAKE_REASON);
7112 case HW_VAR_SYS_CLKR:
7113 *val = rtw_read8(padapter, REG_SYS_CLKR);
7116 case HW_VAR_DUMP_MAC_QUEUE_INFO:
7117 dump_mac_qinfo_8723b(val, padapter);
7120 GetHwReg(padapter, variable, val);
7127 * Change default setting of specified variable.
7129 u8 SetHalDefVar8723B(PADAPTER padapter, HAL_DEF_VARIABLE variable, void *pval)
7131 PHAL_DATA_TYPE pHalData;
7135 pHalData = GET_HAL_DATA(padapter);
7141 bResult = SetHalDefVar(padapter, variable, pval);
7148 #ifdef CONFIG_C2H_PACKET_EN
7149 void SetHwRegWithBuf8723B(PADAPTER padapter, u8 variable, u8 *pbuf, int len)
7151 PHAL_DATA_TYPE pHalData;
7155 pHalData = GET_HAL_DATA(padapter);
7158 case HW_VAR_C2H_HANDLE:
7159 C2HPacketHandler_8723B(padapter, pbuf, len);
7167 #endif // CONFIG_C2H_PACKET_EN
7171 * Query setting of specified variable.
7173 u8 GetHalDefVar8723B(PADAPTER padapter, HAL_DEF_VARIABLE variable, void *pval)
7175 PHAL_DATA_TYPE pHalData;
7179 pHalData = GET_HAL_DATA(padapter);
7184 case HAL_DEF_MAX_RECVBUF_SZ:
7185 *((u32*)pval) = MAX_RECVBUF_SZ;
7188 case HAL_DEF_RX_PACKET_OFFSET:
7189 *((u32*)pval) = RXDESC_SIZE + DRVINFO_SZ*8;
7192 case HW_VAR_MAX_RX_AMPDU_FACTOR:
7193 // Stanley@BB.SD3 suggests 16K can get stable performance
7194 // The experiment was done on SDIO interface
7195 // coding by Lucas@20130730
7196 *(HT_CAP_AMPDU_FACTOR*)pval = MAX_AMPDU_FACTOR_16K;
7198 case HAL_DEF_TX_LDPC:
7199 case HAL_DEF_RX_LDPC:
7200 *((u8 *)pval) = _FALSE;
7202 case HAL_DEF_TX_STBC:
7205 case HAL_DEF_RX_STBC:
7208 case HAL_DEF_EXPLICIT_BEAMFORMER:
7209 case HAL_DEF_EXPLICIT_BEAMFORMEE:
7210 *((u8 *)pval) = _FALSE;
7213 case HW_DEF_RA_INFO_DUMP:
7215 u8 mac_id = *(u8*)pval;
7217 u32 ra_info1, ra_info2;
7218 u32 rate_mask1, rate_mask2;
7219 u8 curr_tx_rate,curr_tx_sgi,hight_rate,lowest_rate;
7221 DBG_8192C("============ RA status check Mac_id:%d ===================\n", mac_id);
7223 cmd = 0x40000100 | mac_id;
7224 rtw_write32(padapter, REG_HMEBOX_DBG_2_8723B, cmd);
7226 ra_info1 = rtw_read32(padapter, 0x2F0);
7227 curr_tx_rate = ra_info1&0x7F;
7228 curr_tx_sgi = (ra_info1>>7)&0x01;
7229 DBG_8192C("[ ra_info1:0x%08x ] =>cur_tx_rate= %s,cur_sgi:%d, PWRSTS = 0x%02x \n",
7231 HDATA_RATE(curr_tx_rate),
7233 (ra_info1>>8) & 0x07);
7235 cmd = 0x40000400 | mac_id;
7236 rtw_write32(padapter, REG_HMEBOX_DBG_2_8723B,cmd);
7238 ra_info1 = rtw_read32(padapter, 0x2F0);
7239 ra_info2 = rtw_read32(padapter, 0x2F4);
7240 rate_mask1 = rtw_read32(padapter, 0x2F8);
7241 rate_mask2 = rtw_read32(padapter, 0x2FC);
7242 hight_rate = ra_info2&0xFF;
7243 lowest_rate = (ra_info2>>8) & 0xFF;
7245 DBG_8192C("[ ra_info1:0x%08x ] =>RSSI=%d, BW_setting=0x%02x, DISRA=0x%02x, VHT_EN=0x%02x\n",
7248 (ra_info1>>8) & 0xFF,
7249 (ra_info1>>16) & 0xFF,
7250 (ra_info1>>24) & 0xFF);
7252 DBG_8192C("[ ra_info2:0x%08x ] =>hight_rate=%s, lowest_rate=%s, SGI=0x%02x, RateID=%d\n",
7254 HDATA_RATE(hight_rate),
7255 HDATA_RATE(lowest_rate),
7256 (ra_info2>>16) & 0xFF,
7257 (ra_info2>>24) & 0xFF);
7259 DBG_8192C("rate_mask2=0x%08x, rate_mask1=0x%08x\n", rate_mask2, rate_mask1);
7264 case HAL_DEF_TX_PAGE_BOUNDARY:
7265 if (!padapter->registrypriv.wifi_spec)
7267 *(u8*)pval = TX_PAGE_BOUNDARY_8723B;
7271 *(u8*)pval = WMM_NORMAL_TX_PAGE_BOUNDARY_8723B;
7275 case HAL_DEF_MACID_SLEEP:
7276 *(u8*)pval = _TRUE; // support macid sleep
7278 case HAL_DEF_TX_PAGE_SIZE:
7279 *(( u32*)pval) = PAGE_SIZE_128;
7282 bResult = GetHalDefVar(padapter, variable, pval);
7289 #ifdef CONFIG_WOWLAN
7290 void Hal_DetectWoWMode(PADAPTER pAdapter)
7292 adapter_to_pwrctl(pAdapter)->bSupportRemoteWakeup = _TRUE;
7293 DBG_871X("%s\n", __func__);
7295 #endif //CONFIG_WOWLAN
7297 void rtl8723b_start_thread(_adapter *padapter)
7299 #if (defined CONFIG_SDIO_HCI) || (defined CONFIG_GSPI_HCI)
7300 #ifndef CONFIG_SDIO_TX_TASKLET
7301 struct xmit_priv *xmitpriv = &padapter->xmitpriv;
7303 xmitpriv->SdioXmitThread = kthread_run(rtl8723bs_xmit_thread, padapter, "RTWHALXT");
7304 if (IS_ERR(xmitpriv->SdioXmitThread))
7306 RT_TRACE(_module_hal_xmit_c_, _drv_err_, ("%s: start rtl8723bs_xmit_thread FAIL!!\n", __FUNCTION__));
7312 void rtl8723b_stop_thread(_adapter *padapter)
7314 #if (defined CONFIG_SDIO_HCI) || (defined CONFIG_GSPI_HCI)
7315 #ifndef CONFIG_SDIO_TX_TASKLET
7316 struct xmit_priv *xmitpriv = &padapter->xmitpriv;
7318 // stop xmit_buf_thread
7319 if (xmitpriv->SdioXmitThread ) {
7320 _rtw_up_sema(&xmitpriv->SdioXmitSema);
7321 _rtw_down_sema(&xmitpriv->SdioXmitTerminateSema);
7322 xmitpriv->SdioXmitThread = 0;
7328 #if defined(CONFIG_CHECK_BT_HANG) && defined(CONFIG_BT_COEXIST)
7329 extern void check_bt_status_work(void *data);
7330 void rtl8723bs_init_checkbthang_workqueue(_adapter * adapter)
7332 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
7333 adapter->priv_checkbt_wq = alloc_workqueue("sdio_wq", 0, 0);
7335 adapter->priv_checkbt_wq = create_workqueue("sdio_wq");
7337 INIT_DELAYED_WORK(&adapter->checkbt_work, (void*)check_bt_status_work);
7340 void rtl8723bs_free_checkbthang_workqueue(_adapter * adapter)
7342 if (adapter->priv_checkbt_wq) {
7343 cancel_delayed_work_sync(&adapter->checkbt_work);
7344 flush_workqueue(adapter->priv_checkbt_wq);
7345 destroy_workqueue(adapter->priv_checkbt_wq);
7346 adapter->priv_checkbt_wq = NULL;
7350 void rtl8723bs_cancle_checkbthang_workqueue(_adapter * adapter)
7352 if (adapter->priv_checkbt_wq) {
7353 cancel_delayed_work_sync(&adapter->checkbt_work);
7357 void rtl8723bs_hal_check_bt_hang(_adapter * adapter)
7359 if (adapter->priv_checkbt_wq)
7360 queue_delayed_work(adapter->priv_checkbt_wq, &(adapter->checkbt_work), 0);