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 <rtl8703b_hal.h>
23 #include "hal_com_h2c.h"
25 #include "hal8703b_fw.h"
26 #define FW_DOWNLOAD_SIZE_8703B 8192
38 tmp = rtw_read8(padapter, REG_SYS_FUNC_EN + 1);
39 rtw_write8(padapter, REG_SYS_FUNC_EN + 1, tmp | 0x04);
41 tmp = rtw_read8(padapter, REG_MCUFWDL);
42 rtw_write8(padapter, REG_MCUFWDL, tmp | 0x01);
45 tmp = rtw_read8(padapter, REG_MCUFWDL);
48 rtw_write8(padapter, REG_MCUFWDL, tmp | 0x01);
50 } while (count++ < 100);
52 RTW_INFO("%s: !!!!!!!!Write 0x80 Fail!: count = %d\n", __func__, count);
55 tmp = rtw_read8(padapter, REG_MCUFWDL + 2);
56 rtw_write8(padapter, REG_MCUFWDL + 2, tmp & 0xf7);
58 /* MCU firmware download disable. */
59 tmp = rtw_read8(padapter, REG_MCUFWDL);
60 rtw_write8(padapter, REG_MCUFWDL, tmp & 0xfe);
73 u32 blockSize_p1 = 4; /* (Default) Phase #1 : PCI muse use 4-byte write to download FW */
74 u32 blockSize_p2 = 8; /* Phase #2 : Use 8-byte, if Phase#1 use big size to write FW. */
75 u32 blockSize_p3 = 1; /* Phase #3 : Use 1-byte, the remnant of FW image. */
76 u32 blockCount_p1 = 0, blockCount_p2 = 0, blockCount_p3 = 0;
77 u32 remainSize_p1 = 0, remainSize_p2 = 0;
78 u8 *bufferPtr = (u8 *)buffer;
79 u32 i = 0, offset = 0;
81 u8 remainFW[4] = {0, 0, 0, 0};
89 /* printk("====>%s %d\n", __func__, __LINE__); */
92 blockCount_p1 = buffSize / blockSize_p1;
93 remainSize_p1 = buffSize % blockSize_p1;
97 for (i = 0; i < blockCount_p1; i++) {
99 ret = rtw_writeN(padapter, (FW_8703B_START_ADDRESS + i * blockSize_p1), blockSize_p1, (bufferPtr + i * blockSize_p1));
101 ret = rtw_write32(padapter, (FW_8703B_START_ADDRESS + i * blockSize_p1), le32_to_cpu(*((u32 *)(bufferPtr + i * blockSize_p1))));
104 printk("====>%s %d i:%d\n", __func__, __LINE__, i);
109 #ifdef CONFIG_PCI_HCI
110 p = (u8 *)((u32 *)(bufferPtr + blockCount_p1 * blockSize_p1));
112 switch (remainSize_p1) {
116 remainFW[2] = *(p + 2);
118 remainFW[1] = *(p + 1);
121 ret = rtw_write32(padapter, (FW_8703B_START_ADDRESS + blockCount_p1 * blockSize_p1),
122 le32_to_cpu(*(u32 *)remainFW));
130 offset = blockCount_p1 * blockSize_p1;
132 blockCount_p2 = remainSize_p1 / blockSize_p2;
133 remainSize_p2 = remainSize_p1 % blockSize_p2;
137 #ifdef CONFIG_USB_HCI
138 for (i = 0; i < blockCount_p2; i++) {
139 ret = rtw_writeN(padapter, (FW_8703B_START_ADDRESS + offset + i * blockSize_p2), blockSize_p2, (bufferPtr + offset + i * blockSize_p2));
149 offset = (blockCount_p1 * blockSize_p1) + (blockCount_p2 * blockSize_p2);
151 blockCount_p3 = remainSize_p2 / blockSize_p3;
154 for (i = 0 ; i < blockCount_p3 ; i++) {
155 ret = rtw_write8(padapter, (FW_8703B_START_ADDRESS + offset + i), *(bufferPtr + offset + i));
158 printk("====>%s %d i:%d\n", __func__, __LINE__, i);
169 IN PADAPTER padapter,
176 u8 u8Page = (u8)(page & 0x07) ;
178 value8 = (rtw_read8(padapter, REG_MCUFWDL + 2) & 0xF8) | u8Page ;
179 rtw_write8(padapter, REG_MCUFWDL + 2, value8);
181 return _BlockWrite(padapter, buffer, size);
191 u8 remain = (u8)(FwLen % 4);
192 remain = (remain == 0) ? 0 : (4 - remain);
205 IN PADAPTER padapter,
210 /* Since we need dynamic decide method of dwonload fw, so we call this function to get chip version. */
212 u32 pageNums, remainSize ;
214 u8 *bufferPtr = (u8 *)buffer;
216 #ifdef CONFIG_PCI_HCI
217 /* 20100120 Joseph: Add for 88CE normal chip. */
218 /* Fill in zero to make firmware image to dword alignment. */
219 _FillDummy(bufferPtr, &size);
222 pageNums = size / MAX_DLFW_PAGE_SIZE ;
223 /* RT_ASSERT((pageNums <= 4), ("Page numbers should not greater then 4\n")); */
224 remainSize = size % MAX_DLFW_PAGE_SIZE;
226 for (page = 0; page < pageNums; page++) {
227 offset = page * MAX_DLFW_PAGE_SIZE;
228 ret = _PageWrite(padapter, page, bufferPtr + offset, MAX_DLFW_PAGE_SIZE);
231 printk("====>%s %d\n", __func__, __LINE__);
236 offset = pageNums * MAX_DLFW_PAGE_SIZE;
238 ret = _PageWrite(padapter, page, bufferPtr + offset, remainSize);
241 printk("====>%s %d\n", __func__, __LINE__);
250 void _8051Reset8703(PADAPTER padapter)
256 io_rst = rtw_read8(padapter, REG_RSV_CTRL);
257 rtw_write8(padapter, REG_RSV_CTRL, io_rst & (~BIT1));
260 /* Reset 8051(WLMCU) IO wrapper */
262 /* Suggested by Isaac@SD1 and Gimmy@SD1, coding by Lucas@20130624 */
263 io_rst = rtw_read8(padapter, REG_RSV_CTRL + 1);
265 rtw_write8(padapter, REG_RSV_CTRL + 1, io_rst);
267 cpu_rst = rtw_read8(padapter, REG_SYS_FUNC_EN + 1);
269 rtw_write8(padapter, REG_SYS_FUNC_EN + 1, cpu_rst);
272 io_rst = rtw_read8(padapter, REG_RSV_CTRL);
273 rtw_write8(padapter, REG_RSV_CTRL, io_rst & (~BIT1));
276 /* Enable 8051 IO wrapper */
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 RTW_INFO("%s: Finish\n", __FUNCTION__);
289 static s32 polling_fwdl_chksum(_adapter *adapter, u32 min_cnt, u32 timeout_ms)
293 u32 start = rtw_get_current_time();
296 /* polling CheckSum report */
299 value32 = rtw_read32(adapter, REG_MCUFWDL);
300 if (value32 & FWDL_ChkSum_rpt || RTW_CANNOT_IO(adapter))
303 } while (rtw_get_passing_time_ms(start) < timeout_ms || cnt < min_cnt);
305 if (!(value32 & FWDL_ChkSum_rpt))
308 if (rtw_fwdl_test_trigger_chksum_fail())
314 RTW_INFO("%s: Checksum report %s! (%u, %dms), REG_MCUFWDL:0x%08x\n", __FUNCTION__
315 , (ret == _SUCCESS) ? "OK" : "Fail", cnt, rtw_get_passing_time_ms(start), value32);
320 static s32 _FWFreeToGo(_adapter *adapter, u32 min_cnt, u32 timeout_ms)
324 u32 start = rtw_get_current_time();
326 u32 value_to_check = 0;
327 u32 value_expected = (MCUFWDL_RDY | FWDL_ChkSum_rpt | WINTINI_RDY | RAM_DL_SEL);
329 value32 = rtw_read32(adapter, REG_MCUFWDL);
330 value32 |= MCUFWDL_RDY;
331 value32 &= ~WINTINI_RDY;
332 rtw_write32(adapter, REG_MCUFWDL, value32);
334 _8051Reset8703(adapter);
336 /* polling for FW ready */
339 value32 = rtw_read32(adapter, REG_MCUFWDL);
340 value_to_check = value32 & value_expected;
341 if ((value_to_check == value_expected) || RTW_CANNOT_IO(adapter))
344 } while (rtw_get_passing_time_ms(start) < timeout_ms || cnt < min_cnt);
346 if (value_to_check != value_expected)
349 if (rtw_fwdl_test_trigger_wintint_rdy_fail())
355 RTW_INFO("%s: Polling FW ready %s! (%u, %dms), REG_MCUFWDL:0x%08x\n", __FUNCTION__
356 , (ret == _SUCCESS) ? "OK" : "Fail", cnt, rtw_get_passing_time_ms(start), value32);
361 #define IS_FW_81xxC(padapter) (((GET_HAL_DATA(padapter))->FirmwareSignature & 0xFFF0) == 0x88C0)
363 void rtl8703b_FirmwareSelfReset(PADAPTER padapter)
365 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
369 if (!(IS_FW_81xxC(padapter) &&
370 ((pHalData->firmware_version < 0x21) ||
371 (pHalData->firmware_version == 0x21 &&
372 pHalData->firmware_sub_version < 0x01)))) { /* after 88C Fw v33.1 */
373 /* 0x1cf=0x20. Inform 8051 to reset. 2009.12.25. tynli_test */
374 rtw_write8(padapter, REG_HMETFR + 3, 0x20);
376 u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN + 1);
377 while (u1bTmp & BIT2) {
382 u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN + 1);
386 /* force firmware reset */
387 u1bTmp = rtw_read8(padapter, REG_SYS_FUNC_EN + 1);
388 rtw_write8(padapter, REG_SYS_FUNC_EN + 1, u1bTmp & (~BIT2));
393 #ifdef CONFIG_FILE_FWIMG
394 extern char *rtw_fw_file_path;
395 extern char *rtw_fw_wow_file_path;
396 #ifdef CONFIG_MP_INCLUDED
397 extern char *rtw_fw_mp_bt_file_path;
398 #endif /* CONFIG_MP_INCLUDED */
399 u8 FwBuffer[FW_8703B_SIZE];
400 #endif /* CONFIG_FILE_FWIMG */
402 #ifdef CONFIG_MP_INCLUDED
403 int _WriteBTFWtoTxPktBuf8703B(
410 int rtStatus = _SUCCESS;
411 /* u4Byte value32; */
412 /* u1Byte numHQ, numLQ, numPubQ; */ /* , txpktbuf_bndy; */
413 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
414 /* PMGNT_INFO pMgntInfo = &(Adapter->MgntInfo); */
416 u1Byte count = 0, DLBcnCount = 0;
417 pu1Byte FwbufferPtr = (pu1Byte)buffer;
418 /* PRT_TCB pTcb, ptempTcb; */
419 /* PRT_TX_LOCAL_BUFFER pBuf; */
420 BOOLEAN bRecover = _FALSE;
421 pu1Byte ReservedPagePacket = NULL;
422 pu1Byte pGenBufReservedPagePacket = NULL;
423 u4Byte TotalPktLen, txpktbuf_bndy;
424 /* u1Byte tmpReg422; */
427 struct xmit_priv *pxmitpriv = &(Adapter->xmitpriv);
428 struct xmit_frame *pmgntframe;
429 struct pkt_attrib *pattrib;
430 u8 txdesc_offset = TXDESC_OFFSET;
432 #if (DEV_BUS_TYPE == RT_PCI_INTERFACE)
436 #if 1/* (DEV_BUS_TYPE == RT_PCI_INTERFACE) */
437 TotalPktLen = FwBufLen;
439 TotalPktLen = FwBufLen + pHalData->HWDescHeadLength;
442 if ((TotalPktLen + TXDESC_OFFSET) > MAX_CMDBUF_SZ) {
443 RTW_INFO(" WARNING %s => Total packet len = %d > MAX_CMDBUF_SZ:%d\n"
444 , __FUNCTION__, (TotalPktLen + TXDESC_OFFSET), MAX_CMDBUF_SZ);
448 pGenBufReservedPagePacket = rtw_zmalloc(TotalPktLen);/* GetGenTempBuffer (Adapter, TotalPktLen); */
449 if (!pGenBufReservedPagePacket)
452 ReservedPagePacket = (u1Byte *)pGenBufReservedPagePacket;
454 _rtw_memset(ReservedPagePacket, 0, TotalPktLen);
456 #if 1/* (DEV_BUS_TYPE == RT_PCI_INTERFACE) */
457 _rtw_memcpy(ReservedPagePacket, FwbufferPtr, FwBufLen);
460 PlatformMoveMemory(ReservedPagePacket + Adapter->HWDescHeadLength , FwbufferPtr, FwBufLen);
463 /* --------------------------------------------------------- */
465 /* --------------------------------------------------------- */
466 /* Set REG_CR bit 8. DMA beacon by SW. */
467 #if (DEV_BUS_TYPE == RT_PCI_INTERFACE)
468 u1bTmp = PlatformEFIORead1Byte(Adapter, REG_CR + 1);
469 PlatformEFIOWrite1Byte(Adapter, REG_CR + 1, (u1bTmp | BIT0));
471 /* Remove for temparaily because of the code on v2002 is not sync to MERGE_TMEP for USB/SDIO. */
472 /* De not remove this part on MERGE_TEMP. by tynli. */
473 /* pHalData->RegCR_1 |= (BIT0); */
474 /* PlatformEFIOWrite1Byte(Adapter, REG_CR+1, pHalData->RegCR_1); */
477 /* Disable Hw protection for a time which revserd for Hw sending beacon. */
478 /* Fix download reserved page packet fail that access collision with the protection time. */
479 /* 2010.05.11. Added by tynli. */
480 val8 = rtw_read8(Adapter, REG_BCN_CTRL);
481 val8 &= ~EN_BCN_FUNCTION;
483 rtw_write8(Adapter, REG_BCN_CTRL, val8);
485 #if 0/* (DEV_BUS_TYPE == RT_PCI_INTERFACE) */
486 tmpReg422 = PlatformEFIORead1Byte(Adapter, REG_FWHW_TXQ_CTRL + 2);
487 if (tmpReg422 & BIT6)
489 PlatformEFIOWrite1Byte(Adapter, REG_FWHW_TXQ_CTRL + 2, tmpReg422 & (~BIT6));
491 /* Set FWHW_TXQ_CTRL 0x422[6]=0 to tell Hw the packet is not a real beacon frame. */
492 if (pHalData->RegFwHwTxQCtrl & BIT(6))
494 PlatformEFIOWrite1Byte(Adapter, REG_FWHW_TXQ_CTRL + 2, (pHalData->RegFwHwTxQCtrl & (~BIT(6))));
495 pHalData->RegFwHwTxQCtrl &= (~BIT(6));
498 /* --------------------------------------------------------- */
499 /* 2. Adjust LLT table to an even boundary. */
500 /* --------------------------------------------------------- */
501 #if 0/* (DEV_BUS_TYPE == RT_SDIO_INTERFACE) */
502 txpktbuf_bndy = 10; /* rsvd page start address should be an even value. */
503 rtStatus = InitLLTTable8703BS(Adapter, txpktbuf_bndy);
504 if (RT_STATUS_SUCCESS != rtStatus) {
505 RTW_INFO("_CheckWLANFwPatchBTFwReady_8703B(): Failed to init LLT!\n");
506 return RT_STATUS_FAILURE;
509 /* Init Tx boundary. */
510 PlatformEFIOWrite1Byte(Adapter, REG_DWBCN0_CTRL_8703B + 1, (u1Byte)txpktbuf_bndy);
514 /* --------------------------------------------------------- */
515 /* 3. Write Fw to Tx packet buffer by reseverd page. */
516 /* --------------------------------------------------------- */
518 /* download rsvd page. */
519 /* Clear beacon valid check bit. */
520 BcnValidReg = PlatformEFIORead1Byte(Adapter, REG_TDECTRL + 2);
521 PlatformEFIOWrite1Byte(Adapter, REG_TDECTRL + 2, BcnValidReg & (~BIT(0)));
523 /* BT patch is big, we should set 0x209 < 0x40 suggested from Gimmy */
525 PlatformEFIOWrite1Byte(Adapter, REG_TDECTRL + 1, (0x90 - 0x20 * (times - 1)));
526 RTW_INFO("0x209:0x%x\n", PlatformEFIORead1Byte(Adapter, REG_TDECTRL + 1));
529 /* Acquice TX spin lock before GetFwBuf and send the packet to prevent system deadlock. */
530 /* Advertised by Roger. Added by tynli. 2010.02.22. */
531 PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK);
532 if (MgntGetFWBuffer(Adapter, &pTcb, &pBuf)) {
533 PlatformMoveMemory(pBuf->Buffer.VirtualAddress, ReservedPagePacket, TotalPktLen);
534 CmdSendPacket(Adapter, pTcb, pBuf, TotalPktLen, DESC_PACKET_TYPE_NORMAL, FALSE);
536 dbgdump("SetFwRsvdPagePkt(): MgntGetFWBuffer FAIL!!!!!!!!.\n");
537 PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK);
539 /*---------------------------------------------------------
540 tx reserved_page_packet
541 ----------------------------------------------------------*/
542 pmgntframe = rtw_alloc_cmdxmitframe(pxmitpriv);
543 if (pmgntframe == NULL) {
547 /* update attribute */
548 pattrib = &pmgntframe->attrib;
549 update_mgntframe_attrib(Adapter, pattrib);
551 pattrib->qsel = QSLT_BEACON;
552 pattrib->pktlen = pattrib->last_txcmdsz = FwBufLen ;
554 /* _rtw_memset(pmgntframe->buf_addr, 0, TotalPktLen+txdesc_size); */
555 /* pmgntframe->buf_addr = ReservedPagePacket ; */
557 _rtw_memcpy((u8 *)(pmgntframe->buf_addr + txdesc_offset), ReservedPagePacket, FwBufLen);
558 RTW_INFO("[%d]===>TotalPktLen + TXDESC_OFFSET TotalPacketLen:%d\n", DLBcnCount, (FwBufLen + txdesc_offset));
560 #ifdef CONFIG_PCI_HCI
561 dump_mgntframe(Adapter, pmgntframe);
563 dump_mgntframe_and_wait(Adapter, pmgntframe, 100);
568 /* check rsvd page download OK. */
569 BcnValidReg = PlatformEFIORead1Byte(Adapter, REG_TDECTRL + 2);
570 while (!(BcnValidReg & BIT(0)) && count < 200) {
572 /* PlatformSleepUs(10); */
574 BcnValidReg = PlatformEFIORead1Byte(Adapter, REG_TDECTRL + 2);
577 /* RTW_INFO("##0x208:%08x,0x210=%08x\n",PlatformEFIORead4Byte(Adapter, REG_TDECTRL),PlatformEFIORead4Byte(Adapter, 0x210)); */
579 PlatformEFIOWrite1Byte(Adapter, REG_TDECTRL + 2, BcnValidReg);
581 } while ((!(BcnValidReg & BIT(0))) && DLBcnCount < 5);
585 if (DLBcnCount >= 5) {
586 RTW_INFO(" check rsvd page download OK DLBcnCount =%d\n", DLBcnCount);
591 if (!(BcnValidReg & BIT(0))) {
592 RTW_INFO("_WriteFWtoTxPktBuf(): 1 Download RSVD page failed!\n");
597 /* --------------------------------------------------------- */
598 /* 4. Set Tx boundary to the initial value */
599 /* --------------------------------------------------------- */
602 /* --------------------------------------------------------- */
603 /* 5. Reset beacon setting to the initial value. */
604 /* After _CheckWLANFwPatchBTFwReady(). */
605 /* --------------------------------------------------------- */
609 if (pGenBufReservedPagePacket) {
610 RTW_INFO("_WriteBTFWtoTxPktBuf8703B => rtw_mfree pGenBufReservedPagePacket!\n");
611 rtw_mfree((u8 *)pGenBufReservedPagePacket, TotalPktLen);
619 * Description: Determine the contents of H2C BT_FW_PATCH Command sent to FW.
620 * 2011.10.20 by tynli
628 u8 u1BTFwPatchParm[H2C_BT_FW_PATCH_LEN] = {0};
635 SET_8703B_H2CCMD_BT_FW_PATCH_SIZE(u1BTFwPatchParm, FwSize);
636 SET_8703B_H2CCMD_BT_FW_PATCH_ADDR0(u1BTFwPatchParm, addr0);
637 SET_8703B_H2CCMD_BT_FW_PATCH_ADDR1(u1BTFwPatchParm, addr1);
638 SET_8703B_H2CCMD_BT_FW_PATCH_ADDR2(u1BTFwPatchParm, addr2);
639 SET_8703B_H2CCMD_BT_FW_PATCH_ADDR3(u1BTFwPatchParm, addr3);
641 FillH2CCmd8703B(Adapter, H2C_8703B_BT_FW_PATCH, H2C_BT_FW_PATCH_LEN, u1BTFwPatchParm);
651 u1Byte u1BTPwrIdxParm[H2C_FORCE_BT_TXPWR_LEN] = {0};
653 SET_8703B_H2CCMD_BT_PWR_IDX(u1BTPwrIdxParm, PwrIdx);
656 FillH2CCmd8703B(Adapter, H2C_8703B_FORCE_BT_TXPWR, H2C_FORCE_BT_TXPWR_LEN, u1BTPwrIdxParm);
660 * Description: WLAN Fw will write BT Fw to BT XRAM and signal driver.
662 * 2011.10.20. by tynli.
665 _CheckWLANFwPatchBTFwReady(
669 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
674 /* --------------------------------------------------------- */
675 /* Check if BT FW patch procedure is ready. */
676 /* --------------------------------------------------------- */
678 u1bTmp = PlatformEFIORead1Byte(Adapter, REG_HMEBOX_DBG_0_8703B);
679 if ((u1bTmp & BIT6) || (u1bTmp & BIT7)) {
685 rtw_msleep_os(50); /* 50ms */
686 } while (!((u1bTmp & BIT6) || (u1bTmp & BIT7)) && count < 50);
691 /* --------------------------------------------------------- */
692 /* Reset beacon setting to the initial value. */
693 /* --------------------------------------------------------- */
694 #if 0/* (DEV_BUS_TYPE == RT_PCI_INTERFACE) */
695 if (LLT_table_init(Adapter, FALSE, 0) == RT_STATUS_FAILURE) {
696 dbgdump("Init self define for BT Fw patch LLT table fail.\n");
697 /* return RT_STATUS_FAILURE; */
700 u1bTmp = rtw_read8(Adapter, REG_BCN_CTRL);
701 u1bTmp |= EN_BCN_FUNCTION;
702 u1bTmp &= ~DIS_TSF_UDT;
703 rtw_write8(Adapter, REG_BCN_CTRL, u1bTmp);
705 /* To make sure that if there exists an adapter which would like to send beacon. */
706 /* If exists, the origianl value of 0x422[6] will be 1, we should check this to */
707 /* prevent from setting 0x422[6] to 0 after download reserved page, or it will cause */
708 /* the beacon cannot be sent by HW. */
709 /* 2010.06.23. Added by tynli. */
710 #if 0/* (DEV_BUS_TYPE == RT_PCI_INTERFACE) */
711 u1bTmp = PlatformEFIORead1Byte(Adapter, REG_FWHW_TXQ_CTRL + 2);
712 PlatformEFIOWrite1Byte(Adapter, REG_FWHW_TXQ_CTRL + 2, (u1bTmp | BIT6));
714 PlatformEFIOWrite1Byte(Adapter, REG_FWHW_TXQ_CTRL + 2, (pHalData->RegFwHwTxQCtrl | BIT(6)));
715 pHalData->RegFwHwTxQCtrl |= BIT(6);
718 /* Clear CR[8] or beacon packet will not be send to TxBuf anymore. */
719 u1bTmp = PlatformEFIORead1Byte(Adapter, REG_CR + 1);
720 PlatformEFIOWrite1Byte(Adapter, REG_CR + 1, (u1bTmp & (~BIT0)));
725 int ReservedPage_Compare(PADAPTER Adapter, PRT_MP_FIRMWARE pFirmware, u32 BTPatchSize)
727 u8 temp, ret, lastBTsz;
728 u32 u1bTmp = 0, address_start = 0, count = 0, i = 0;
729 u8 *myBTFwBuffer = NULL;
731 myBTFwBuffer = rtw_zmalloc(BTPatchSize);
732 if (myBTFwBuffer == NULL) {
733 RTW_INFO("%s can't be executed due to the failed malloc.\n", __FUNCTION__);
734 Adapter->mppriv.bTxBufCkFail = _TRUE;
738 temp = rtw_read8(Adapter, 0x209);
740 address_start = (temp * 128) / 8;
742 rtw_write32(Adapter, 0x140, 0x00000000);
743 rtw_write32(Adapter, 0x144, 0x00000000);
744 rtw_write32(Adapter, 0x148, 0x00000000);
746 rtw_write8(Adapter, 0x106, 0x69);
748 for (i = 0; i < (BTPatchSize / 8); i++) {
749 rtw_write32(Adapter, 0x140, address_start + 5 + i) ;
751 /* polling until reg 0x140[23]=1; */
753 u1bTmp = rtw_read32(Adapter, 0x140);
754 if (u1bTmp & BIT(23)) {
759 RTW_INFO("0x140=%x, wait for 10 ms (%d) times.\n", u1bTmp, count);
760 rtw_msleep_os(10); /* 10ms */
761 } while (!(u1bTmp & BIT(23)) && count < 50);
763 myBTFwBuffer[i * 8 + 0] = rtw_read8(Adapter, 0x144);
764 myBTFwBuffer[i * 8 + 1] = rtw_read8(Adapter, 0x145);
765 myBTFwBuffer[i * 8 + 2] = rtw_read8(Adapter, 0x146);
766 myBTFwBuffer[i * 8 + 3] = rtw_read8(Adapter, 0x147);
767 myBTFwBuffer[i * 8 + 4] = rtw_read8(Adapter, 0x148);
768 myBTFwBuffer[i * 8 + 5] = rtw_read8(Adapter, 0x149);
769 myBTFwBuffer[i * 8 + 6] = rtw_read8(Adapter, 0x14a);
770 myBTFwBuffer[i * 8 + 7] = rtw_read8(Adapter, 0x14b);
773 rtw_write32(Adapter, 0x140, address_start + 5 + BTPatchSize / 8) ;
775 lastBTsz = BTPatchSize % 8;
777 /* polling until reg 0x140[23]=1; */
781 u1bTmp = rtw_read32(Adapter, 0x140);
782 if (u1bTmp & BIT(23)) {
787 RTW_INFO("0x140=%x, wait for 10 ms (%d) times.\n", u1bTmp, count);
788 rtw_msleep_os(10); /* 10ms */
789 } while (!(u1bTmp & BIT(23)) && count < 50);
791 for (i = 0; i < lastBTsz; i++)
792 myBTFwBuffer[(BTPatchSize / 8) * 8 + i] = rtw_read8(Adapter, (0x144 + i));
795 for (i = 0; i < BTPatchSize; i++) {
796 if (myBTFwBuffer[i] != pFirmware->szFwBuffer[i]) {
797 RTW_INFO(" In direct myBTFwBuffer[%d]=%x , pFirmware->szFwBuffer=%x\n", i, myBTFwBuffer[i], pFirmware->szFwBuffer[i]);
798 Adapter->mppriv.bTxBufCkFail = _TRUE;
803 if (myBTFwBuffer != NULL)
804 rtw_mfree(myBTFwBuffer, BTPatchSize);
809 /* As the size of bt firmware is more than 16k which is too big for some platforms, we divide it
810 * into four parts to transfer. The last parameter of _WriteBTFWtoTxPktBuf8703B is used to indicate
811 * the location of every part. We call the first 4096 byte of bt firmware as part 1, the second 4096
812 * part as part 2, the third 4096 part as part 3, the remain as part 4. First we transform the part
813 * 4 and set the register 0x209 to 0x90, then the 32 bytes description are added to the head of part
814 * 4, and those bytes are putted at the location 0x90. Second we transform the part 3 and set the
815 * register 0x209 to 0x70. The 32 bytes description and part 3(4196 bytes) are putted at the location
816 * 0x70. It can contain 4196 bytes between 0x70 and 0x90. So the last 32 bytes os part 3 will cover the
817 * 32 bytes description of part4. Using this method, we can put the whole bt firmware to 0x30 and only
818 * has 32 bytes descrption at the head of part 1.
820 s32 FirmwareDownloadBT(PADAPTER padapter, PRT_MP_FIRMWARE pFirmware)
830 pBTFirmwareBuf = NULL;
835 /* Patch BT Fw. Download BT RAM code to Tx packet buffer. */
837 if (padapter->bBTFWReady) {
838 RTW_INFO("%s: BT Firmware is ready!!\n", __FUNCTION__);
842 #ifdef CONFIG_FILE_FWIMG
843 if (rtw_is_file_readable(rtw_fw_mp_bt_file_path) == _TRUE) {
844 RTW_INFO("%s: accquire MP BT FW from file:%s\n", __FUNCTION__, rtw_fw_mp_bt_file_path);
846 rtStatus = rtw_retrieve_from_file(rtw_fw_mp_bt_file_path, FwBuffer, FW_8703B_SIZE);
847 BTFirmwareLen = rtStatus >= 0 ? rtStatus : 0;
848 pBTFirmwareBuf = FwBuffer;
850 #endif /* CONFIG_FILE_FWIMG */
852 #ifdef CONFIG_EMBEDDED_FWIMG
853 RTW_INFO("%s: Download MP BT FW from header\n", __FUNCTION__);
855 pBTFirmwareBuf = (u8 *)Rtl8703BFwBTImgArray;
856 BTFirmwareLen = Rtl8703BFwBTImgArrayLength;
857 pFirmware->szFwBuffer = pBTFirmwareBuf;
858 pFirmware->ulFwLength = BTFirmwareLen;
859 #endif /* CONFIG_EMBEDDED_FWIMG */
862 RTW_INFO("%s: MP BT Firmware size=%d\n", __FUNCTION__, BTFirmwareLen);
864 /* for h2c cam here should be set to true */
865 padapter->bFWReady = _TRUE;
867 download_time = (BTFirmwareLen + 4095) / 4096;
868 RTW_INFO("%s: download_time is %d\n", __FUNCTION__, download_time);
870 /* Download BT patch Fw. */
871 for (i = (download_time - 1); i >= 0; i--) {
872 if (i == (download_time - 1)) {
873 rtStatus = _WriteBTFWtoTxPktBuf8703B(padapter, pBTFirmwareBuf + (4096 * i), (BTFirmwareLen - (4096 * i)), 1);
874 RTW_INFO("%s: start %d, len %d, time 1\n", __FUNCTION__, 4096 * i, BTFirmwareLen - (4096 * i));
876 rtStatus = _WriteBTFWtoTxPktBuf8703B(padapter, pBTFirmwareBuf + (4096 * i), 4096, (download_time - i));
877 RTW_INFO("%s: start %d, len 4096, time %d\n", __FUNCTION__, 4096 * i, download_time - i);
880 if (rtStatus != _SUCCESS) {
881 RTW_INFO("%s: BT Firmware download to Tx packet buffer fail!\n", __FUNCTION__);
882 padapter->bBTFWReady = _FALSE;
887 ReservedPage_Compare(padapter, pFirmware, BTFirmwareLen);
889 padapter->bBTFWReady = _TRUE;
890 SetFwBTFwPatchCmd(padapter, (u16)BTFirmwareLen);
891 rtStatus = _CheckWLANFwPatchBTFwReady(padapter);
893 RTW_INFO("<===%s: return %s!\n", __FUNCTION__, rtStatus == _SUCCESS ? "SUCCESS" : "FAIL");
898 #endif /* CONFIG_MP_INCLUDED */
900 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
901 void rtl8703b_cal_txdesc_chksum(struct tx_desc *ptxdesc)
903 u16 *usPtr = (u16 *)ptxdesc;
910 ptxdesc->txdw7 &= cpu_to_le32(0xffff0000);
912 /* checksume is always calculated by first 32 bytes, */
913 /* and it doesn't depend on TX DESC length. */
914 /* Thomas,Lucas@SD4,20130515 */
917 for (index = 0; index < count; index++)
918 checksum ^= le16_to_cpu(*(usPtr + index));
920 ptxdesc->txdw7 |= cpu_to_le32(checksum & 0x0000ffff);
924 #ifdef CONFIG_SDIO_HCI
925 u8 send_fw_packet(PADAPTER padapter, u8 *pRam_code, u32 length)
927 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
928 struct xmit_buf xmit_buf_tmp;
929 struct submit_ctx sctx_tmp;
930 u8 *pTx_data_buffer = NULL;
931 u8 *pTmp_buffer = NULL;
933 u32 tmp_size, tmp_value;
937 u32 dwDataLength, writeLength;
939 /* Due to SDIO can not send 32K packet */
940 if (FW_DOWNLOAD_SIZE_8703B == length)
943 modify_ram_size = length << 2;
944 pTx_data_buffer = rtw_zmalloc(modify_ram_size);
946 if (NULL == pTx_data_buffer) {
947 RTW_INFO("Allocate buffer fail!!\n");
951 _rtw_memset(pTx_data_buffer, 0, modify_ram_size);
953 /* Transfer to new format */
954 tmp_size = length >> 1;
955 for (i = 0; i <= tmp_size; i++) {
956 *(pTx_data_buffer + i * 8) = *(pRam_code + i * 2);
957 *(pTx_data_buffer + i * 8 + 1) = *(pRam_code + i * 2 + 1);
961 _rtw_memset(pTx_data_buffer, 0, TXDESC_SIZE);
962 pTmp_buffer = pTx_data_buffer;
964 pTmp_buffer->qsel = BcnQsel;
965 pTmp_buffer->txpktsize = modify_ram_size - TXDESC_SIZE;
966 pTmp_buffer->offset = TXDESC_SIZE;
968 SET_TX_DESC_QUEUE_SEL_8703B(pTmp_buffer, QSLT_BEACON);
969 SET_TX_DESC_PKT_SIZE_8703B(pTmp_buffer, modify_ram_size - TXDESC_SIZE);
970 SET_TX_DESC_OFFSET_8703B(pTmp_buffer, TXDESC_SIZE);
972 rtl8703b_cal_txdesc_chksum((struct tx_desc *)pTmp_buffer);
977 dwDataLength = modify_ram_size;
979 overlap.OffsetHigh = 0;
980 overlap.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
981 bRet = WriteFile(HalVari.hFile_Queue[TX_BCNQ]->handle, pTx_data_buffer, dwDataLength, &writeLength, &overlap);
982 if (WaitForSingleObject(overlap.hEvent, INFINITE) == WAIT_OBJECT_0) {
984 GetOverlappedResult(HalVari.hFile_Queue[TX_BCNQ]->handle, &overlap, &writeLength, FALSE);
985 if (writeLength != dwDataLength) {
987 sprintf(editbuf, "DL FW Length Err: Write length error:bRet %d writeLength %ld dwDataLength %ld, Error Code:%ld", bRet, writeLength, dwDataLength, GetLastError());
988 AfxMessageBox(editbuf, MB_OK | MB_ICONERROR);
992 CloseHandle(overlap.hEvent);
994 xmit_buf_tmp.pdata = pTx_data_buffer;
995 xmit_buf_tmp.len = modify_ram_size;
996 rtw_sctx_init(&sctx_tmp, 10);
997 xmit_buf_tmp.sctx = &sctx_tmp;
998 if (rtw_write_port(padapter, pdvobjpriv->Queue2Pipe[BCN_QUEUE_INX], xmit_buf_tmp.len, (u8 *)&xmit_buf_tmp) == _FAIL) {
999 RTW_INFO("rtw_write_port fail\n");
1004 /* check if DMA is OK */
1008 RTW_INFO("DMA time out!!\n");
1011 value8 = rtw_read8(padapter, REG_DWBCN0_CTRL_8703B + 2);
1013 } while (0 == (value8 & BIT(0)));
1015 rtw_write8(padapter, REG_DWBCN0_CTRL_8703B + 2, value8);
1017 /* Modify ram code by IO method */
1018 tmp_value = rtw_read8(padapter, REG_MCUFWDL + 1);
1020 rtw_write8(padapter, REG_MCUFWDL + 1, (u8)tmp_value & ~(BIT(5)));
1021 tmp_value = (tmp_value >> 6) << 1;
1022 /* Set page start address */
1023 rtw_write8(padapter, REG_MCUFWDL + 2, (rtw_read8(padapter, REG_MCUFWDL + 2) & 0xF8) | tmp_value);
1024 tmp_size = TXDESC_SIZE >> 2; /* 10bytes */
1026 IO_Func.WriteRegister(0x1000, (u2Byte)tmp_size, pRam_code);
1028 _BlockWrite(padapter, pRam_code, tmp_size);
1031 if (pTmp_buffer != NULL)
1032 rtw_mfree((u8 *)pTmp_buffer, modify_ram_size);
1036 #endif /* CONFIG_SDIO_HCI */
1040 * Download 8192C firmware code.
1043 s32 rtl8703b_FirmwareDownload(PADAPTER padapter, BOOLEAN bUsedWoWLANFw)
1045 s32 rtStatus = _SUCCESS;
1047 u32 fwdl_start_time;
1048 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
1051 u8 *pFwImageFileName;
1052 #ifdef CONFIG_WOWLAN
1054 u32 FwImageWoWLANLen;
1056 u8 *pucMappedFile = NULL;
1057 PRT_FIRMWARE_8703B pFirmware = NULL;
1058 PRT_8703B_FIRMWARE_HDR pFwHdr = NULL;
1061 #ifdef CONFIG_FILE_FWIMG
1063 #endif /* CONFIG_FILE_FWIMG */
1068 u16 new_chk_sum = 0;
1069 u32 send_pkt_size, pkt_size_tmp;
1072 struct dvobj_priv *psdpriv = padapter->dvobj;
1073 struct debug_priv *pdbgpriv = &psdpriv->drv_dbg;
1074 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
1077 pFirmware = (PRT_FIRMWARE_8703B)rtw_zmalloc(sizeof(RT_FIRMWARE_8703B));
1085 u8 tmp_ps = 0, tmp_rf = 0;
1086 tmp_ps = rtw_read8(padapter, 0xa3);
1089 /* 1. write 0xA3[:2:0] = 3b'010 */
1090 rtw_write8(padapter, 0xa3, tmp_ps);
1091 /* 2. read power_state = 0xA0[1:0] */
1092 tmp_ps = rtw_read8(padapter, 0xa0);
1094 if (tmp_ps != 0x01) {
1095 RTW_INFO(FUNC_ADPT_FMT" tmp_ps=%x\n", FUNC_ADPT_ARG(padapter), tmp_ps);
1096 pdbgpriv->dbg_downloadfw_pwr_state_cnt++;
1100 #ifdef CONFIG_BT_COEXIST
1101 rtw_btcoex_PreLoadFirmware(padapter);
1102 #endif /* CONFIG_BT_COEXIST */
1104 #ifdef CONFIG_FILE_FWIMG
1105 #ifdef CONFIG_WOWLAN
1107 fwfilepath = rtw_fw_wow_file_path;
1109 #endif /* CONFIG_WOWLAN */
1111 fwfilepath = rtw_fw_file_path;
1113 #endif /* CONFIG_FILE_FWIMG */
1115 #ifdef CONFIG_FILE_FWIMG
1116 if (rtw_is_file_readable(fwfilepath) == _TRUE) {
1117 RTW_INFO("%s accquire FW from file:%s\n", __FUNCTION__, fwfilepath);
1118 pFirmware->eFWSource = FW_SOURCE_IMG_FILE;
1120 #endif /* CONFIG_FILE_FWIMG */
1122 #ifdef CONFIG_EMBEDDED_FWIMG
1123 pFirmware->eFWSource = FW_SOURCE_HEADER_FILE;
1124 #else /* !CONFIG_EMBEDDED_FWIMG */
1125 pFirmware->eFWSource = FW_SOURCE_IMG_FILE; /* We should decided by Reg. */
1126 #endif /* !CONFIG_EMBEDDED_FWIMG */
1129 switch (pFirmware->eFWSource) {
1130 case FW_SOURCE_IMG_FILE:
1131 #ifdef CONFIG_FILE_FWIMG
1132 rtStatus = rtw_retrieve_from_file(fwfilepath, FwBuffer, FW_8703B_SIZE);
1133 pFirmware->ulFwLength = rtStatus >= 0 ? rtStatus : 0;
1134 pFirmware->szFwBuffer = FwBuffer;
1135 #endif /* CONFIG_FILE_FWIMG */
1138 case FW_SOURCE_HEADER_FILE:
1139 if (bUsedWoWLANFw) {
1140 #ifdef CONFIG_WOWLAN
1141 if (pwrpriv->wowlan_mode) {
1142 pFirmware->szFwBuffer = array_mp_8703b_fw_wowlan;
1143 pFirmware->ulFwLength = array_length_mp_8703b_fw_wowlan;
1145 RTW_INFO(" ===> %s fw: %s, size: %d\n",
1146 __FUNCTION__, "WoWLAN",
1147 pFirmware->ulFwLength);
1149 #endif /*CONFIG_WOWLAN*/
1151 #ifdef CONFIG_AP_WOWLAN
1152 if (pwrpriv->wowlan_ap_mode) {
1153 pFirmware->szFwBuffer = array_mp_8703b_fw_ap;
1154 pFirmware->ulFwLength = array_length_mp_8703b_fw_ap;
1156 RTW_INFO(" ===> %s fw: %s, size: %d\n",
1157 __FUNCTION__, "AP_WoWLAN",
1158 pFirmware->ulFwLength);
1160 #endif /* CONFIG_AP_WOWLAN */
1162 pFirmware->szFwBuffer = array_mp_8703b_fw_nic;
1163 pFirmware->ulFwLength = array_length_mp_8703b_fw_nic;
1164 RTW_INFO("%s fw: %s, size: %d\n", __FUNCTION__, "FW_NIC", pFirmware->ulFwLength);
1169 if (pFirmware->ulFwLength > FW_8703B_SIZE) {
1171 RTW_ERR("Firmware size:%u exceed %u\n", pFirmware->ulFwLength, FW_8703B_SIZE);
1175 pFirmwareBuf = pFirmware->szFwBuffer;
1176 FirmwareLen = pFirmware->ulFwLength;
1178 /* To Check Fw header. Added by tynli. 2009.12.04. */
1179 pFwHdr = (PRT_8703B_FIRMWARE_HDR)pFirmwareBuf;
1181 pHalData->firmware_version = le16_to_cpu(pFwHdr->Version);
1182 pHalData->firmware_sub_version = le16_to_cpu(pFwHdr->Subversion);
1183 pHalData->FirmwareSignature = le16_to_cpu(pFwHdr->Signature);
1185 RTW_INFO("%s: fw_ver=%x fw_subver=%04x sig=0x%x, Month=%02x, Date=%02x, Hour=%02x, Minute=%02x\n",
1186 __FUNCTION__, pHalData->firmware_version, pHalData->firmware_sub_version, pHalData->FirmwareSignature
1187 , pFwHdr->Month, pFwHdr->Date, pFwHdr->Hour, pFwHdr->Minute);
1189 if (IS_FW_HEADER_EXIST_8703B(pFwHdr)) {
1190 RTW_INFO("%s(): Shift for fw header!\n", __FUNCTION__);
1191 /* Shift 32 bytes for FW header */
1192 pFirmwareBuf = pFirmwareBuf + 32;
1193 FirmwareLen = FirmwareLen - 32;
1196 fwdl_start_time = rtw_get_current_time();
1199 RTW_INFO("%s by IO write!\n", __FUNCTION__);
1202 /* To check if FW already exists before download FW */
1203 if (rtw_read8(padapter, REG_MCUFWDL) & RAM_DL_SEL) {
1204 rtw_write8(padapter, REG_MCUFWDL, 0x00);
1205 _8051Reset8703(padapter);
1208 _FWDownloadEnable(padapter, _TRUE);
1210 while (!RTW_CANNOT_IO(padapter)
1211 && (write_fw++ < 3 || rtw_get_passing_time_ms(fwdl_start_time) < 500)) {
1212 /* reset FWDL chksum */
1213 rtw_write8(padapter, REG_MCUFWDL, rtw_read8(padapter, REG_MCUFWDL) | FWDL_ChkSum_rpt);
1215 rtStatus = _WriteFW(padapter, pFirmwareBuf, FirmwareLen);
1216 if (rtStatus != _SUCCESS)
1219 rtStatus = polling_fwdl_chksum(padapter, 5, 50);
1220 if (rtStatus == _SUCCESS)
1224 RTW_INFO("%s by Tx pkt write!\n", __FUNCTION__);
1226 if ((rtw_read8(padapter, REG_MCUFWDL) & MCUFWDL_RDY) == 0) {
1227 /* DLFW use HIQ only */
1228 value32 = 0xFF | BIT(31);
1229 rtw_write32(padapter, REG_RQPN, value32);
1231 /* Set beacon boundary to TXFIFO header */
1232 rtw_write8(padapter, REG_BCNQ_BDNY, 0);
1233 rtw_write16(padapter, REG_DWBCN0_CTRL_8703B + 1, BIT(8));
1235 /* SDIO need read this register before send packet */
1236 rtw_read32(padapter, 0x10250020);
1238 _FWDownloadEnable(padapter, _TRUE);
1240 /* Get original check sum */
1241 new_chk_sum = *(pFirmwareBuf + FirmwareLen - 2) | ((u16)*(pFirmwareBuf + FirmwareLen - 1) << 8);
1243 /* Send ram code flow */
1246 pkt_size_tmp = FirmwareLen;
1247 while (0 != pkt_size_tmp) {
1248 if (pkt_size_tmp >= FW_DOWNLOAD_SIZE_8703B) {
1249 send_pkt_size = FW_DOWNLOAD_SIZE_8703B;
1250 /* Modify check sum value */
1251 new_chk_sum = (u16)(new_chk_sum ^ (((send_pkt_size - 1) << 2) - TXDESC_SIZE));
1253 send_pkt_size = pkt_size_tmp;
1254 new_chk_sum = (u16)(new_chk_sum ^ ((send_pkt_size << 2) - TXDESC_SIZE));
1258 if (send_pkt_size == pkt_size_tmp) {
1259 /* last partition packet, write new check sum to ram code file */
1260 *(pFirmwareBuf + FirmwareLen - 2) = new_chk_sum & 0xFF;
1261 *(pFirmwareBuf + FirmwareLen - 1) = (new_chk_sum & 0xFF00) >> 8;
1265 rtw_write8(padapter, REG_MCUFWDL + 1, (rtw_read8(padapter, REG_MCUFWDL + 1) & 0x3F) | (dma_iram_sel << 6));
1267 rtw_write8(padapter, REG_MCUFWDL + 1, rtw_read8(padapter, REG_MCUFWDL + 1) | BIT(5));
1269 if (_FALSE == send_fw_packet(padapter, pFirmwareBuf + mem_offset, send_pkt_size)) {
1270 RTW_INFO("%s: Send FW fail !\n", __FUNCTION__);
1276 mem_offset += send_pkt_size;
1277 pkt_size_tmp -= send_pkt_size;
1280 RTW_INFO("%s: Downlad FW fail since MCUFWDL_RDY is not set!\n", __FUNCTION__);
1286 _FWDownloadEnable(padapter, _FALSE);
1288 rtStatus = _FWFreeToGo(padapter, 10, 200);
1289 if (_SUCCESS != rtStatus)
1292 RTW_INFO("%s: DLFW OK !\n", __FUNCTION__);
1295 if (rtStatus == _FAIL) {
1296 /* Disable FWDL_EN */
1297 value8 = rtw_read8(padapter, REG_MCUFWDL);
1298 value8 = (value8 & ~(BIT(0)) & ~(BIT(1)));
1299 rtw_write8(padapter, REG_MCUFWDL, value8);
1302 RTW_INFO("%s %s. write_fw:%u, %dms\n"
1303 , __FUNCTION__, (rtStatus == _SUCCESS) ? "success" : "fail"
1305 , rtw_get_passing_time_ms(fwdl_start_time)
1310 rtw_mfree((u8 *)pFirmware, sizeof(RT_FIRMWARE_8703B));
1312 rtl8703b_InitializeFirmwareVars(padapter);
1314 RTW_INFO(" <=== %s()\n", __FUNCTION__);
1319 void rtl8703b_InitializeFirmwareVars(PADAPTER padapter)
1321 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
1323 /* Init Fw LPS related. */
1324 adapter_to_pwrctl(padapter)->bFwCurrentInPSMode = _FALSE;
1327 rtw_write8(padapter, REG_HMETFR, 0x0f);
1329 /* Init H2C counter. by tynli. 2009.12.09. */
1330 pHalData->LastHMEBoxNum = 0;
1331 /* pHalData->H2CQueueHead = 0;
1332 * pHalData->H2CQueueTail = 0;
1333 * pHalData->H2CStopInsertQueue = _FALSE; */
1336 /* ***********************************************************
1337 * Efuse related code
1338 * *********************************************************** */
1340 hal_EfuseSwitchToBank(
1347 #ifdef HAL_EFUSE_MEMORY
1348 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
1349 PEFUSE_HAL pEfuseHal = &pHalData->EfuseHal;
1353 RTW_INFO("%s: Efuse switch bank to %d\n", __FUNCTION__, bank);
1355 #ifdef HAL_EFUSE_MEMORY
1356 pEfuseHal->fakeEfuseBank = bank;
1358 fakeEfuseBank = bank;
1362 value32 = rtw_read32(padapter, EFUSE_TEST);
1366 value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_WIFI_SEL_0);
1369 value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_BT_SEL_0);
1372 value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_BT_SEL_1);
1375 value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_BT_SEL_2);
1378 value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_WIFI_SEL_0);
1382 rtw_write32(padapter, EFUSE_TEST, value32);
1389 Hal_GetEfuseDefinition(
1397 case TYPE_EFUSE_MAX_SECTION: {
1399 pMax_section = (u8 *)pOut;
1401 if (efuseType == EFUSE_WIFI)
1402 *pMax_section = EFUSE_MAX_SECTION_8703B;
1404 *pMax_section = EFUSE_BT_MAX_SECTION;
1408 case TYPE_EFUSE_REAL_CONTENT_LEN: {
1410 pu2Tmp = (u16 *)pOut;
1412 if (efuseType == EFUSE_WIFI)
1413 *pu2Tmp = EFUSE_REAL_CONTENT_LEN_8703B;
1415 *pu2Tmp = EFUSE_BT_REAL_CONTENT_LEN;
1419 case TYPE_AVAILABLE_EFUSE_BYTES_BANK: {
1421 pu2Tmp = (u16 *)pOut;
1423 if (efuseType == EFUSE_WIFI)
1424 *pu2Tmp = (EFUSE_REAL_CONTENT_LEN_8703B - EFUSE_OOB_PROTECT_BYTES);
1426 *pu2Tmp = (EFUSE_BT_REAL_BANK_CONTENT_LEN - EFUSE_PROTECT_BYTES_BANK);
1430 case TYPE_AVAILABLE_EFUSE_BYTES_TOTAL: {
1432 pu2Tmp = (u16 *)pOut;
1434 if (efuseType == EFUSE_WIFI)
1435 *pu2Tmp = (EFUSE_REAL_CONTENT_LEN_8703B - EFUSE_OOB_PROTECT_BYTES);
1437 *pu2Tmp = (EFUSE_BT_REAL_CONTENT_LEN - (EFUSE_PROTECT_BYTES_BANK * 3));
1441 case TYPE_EFUSE_MAP_LEN: {
1443 pu2Tmp = (u16 *)pOut;
1445 if (efuseType == EFUSE_WIFI)
1446 *pu2Tmp = EFUSE_MAP_LEN_8703B;
1448 *pu2Tmp = EFUSE_BT_MAP_LEN;
1452 case TYPE_EFUSE_PROTECT_BYTES_BANK: {
1454 pu1Tmp = (u8 *)pOut;
1456 if (efuseType == EFUSE_WIFI)
1457 *pu1Tmp = EFUSE_OOB_PROTECT_BYTES;
1459 *pu1Tmp = EFUSE_PROTECT_BYTES_BANK;
1463 case TYPE_EFUSE_CONTENT_LEN_BANK: {
1465 pu2Tmp = (u16 *)pOut;
1467 if (efuseType == EFUSE_WIFI)
1468 *pu2Tmp = EFUSE_REAL_CONTENT_LEN_8703B;
1470 *pu2Tmp = EFUSE_BT_REAL_BANK_CONTENT_LEN;
1476 pu1Tmp = (u8 *)pOut;
1483 #define VOLTAGE_V25 0x03
1484 #define LDOE25_SHIFT 28
1486 /* *****************************************************************
1487 * The following is for compile ok
1488 * That should be merged with the original in the future
1489 * ***************************************************************** */
1490 #define EFUSE_ACCESS_ON_8703 0x69 /* For RTL8703 only. */
1491 #define EFUSE_ACCESS_OFF_8703 0x00 /* For RTL8703 only. */
1492 #define REG_EFUSE_ACCESS_8703 0x00CF /* Efuse access protection for RTL8703 */
1494 /* ***************************************************************** */
1495 static void Hal_BT_EfusePowerSwitch(
1501 if (PwrState == _TRUE) {
1502 /* enable BT power cut */
1504 tempval = rtw_read8(padapter, 0x6B);
1506 rtw_write8(padapter, 0x6B, tempval);
1508 /* Attention!! Between 0x6A[14] and 0x6A[15] setting need 100us delay */
1509 /* So don't wirte 0x6A[14]=1 and 0x6A[15]=0 together! */
1511 /* disable BT output isolation */
1513 tempval = rtw_read8(padapter, 0x6B);
1515 rtw_write8(padapter, 0x6B, tempval);
1517 /* enable BT output isolation */
1519 tempval = rtw_read8(padapter, 0x6B);
1521 rtw_write8(padapter, 0x6B, tempval);
1523 /* Attention!! Between 0x6A[14] and 0x6A[15] setting need 100us delay */
1524 /* So don't wirte 0x6A[14]=1 and 0x6A[15]=0 together! */
1526 /* disable BT power cut */
1528 tempval = rtw_read8(padapter, 0x6B);
1530 rtw_write8(padapter, 0x6B, tempval);
1535 Hal_EfusePowerSwitch(
1544 if (PwrState == _TRUE) {
1545 /* enable BT power cut 0x6A[14] = 1*/
1546 tempval = rtw_read8(padapter, 0x6B);
1548 rtw_write8(padapter, 0x6B, tempval);
1549 #ifdef CONFIG_SDIO_HCI
1550 /* To avoid cannot access efuse regsiters after disable/enable several times during DTM test. */
1551 /* Suggested by SD1 IsaacHsu. 2013.07.08, added by tynli. */
1552 tempval = rtw_read8(padapter, SDIO_LOCAL_BASE | SDIO_REG_HSUS_CTRL);
1553 if (tempval & BIT(0)) { /* SDIO local register is suspend */
1558 rtw_write8(padapter, SDIO_LOCAL_BASE | SDIO_REG_HSUS_CTRL, tempval);
1560 /* check 0x86[1:0]=10'2h, wait power state to leave suspend */
1562 tempval = rtw_read8(padapter, SDIO_LOCAL_BASE | SDIO_REG_HSUS_CTRL);
1564 if (tempval == 0x02)
1575 RTW_INFO(FUNC_ADPT_FMT ": Leave SDIO local register suspend fail! Local 0x86=%#X\n",
1576 FUNC_ADPT_ARG(padapter), tempval);
1578 RTW_INFO(FUNC_ADPT_FMT ": Leave SDIO local register suspend OK! Local 0x86=%#X\n",
1579 FUNC_ADPT_ARG(padapter), tempval);
1582 #endif /* CONFIG_SDIO_HCI */
1584 rtw_write8(padapter, REG_EFUSE_ACCESS_8703, EFUSE_ACCESS_ON_8703);
1586 /* Reset: 0x0000h[28], default valid */
1587 tmpV16 = rtw_read16(padapter, REG_SYS_FUNC_EN);
1588 if (!(tmpV16 & FEN_ELDR)) {
1589 tmpV16 |= FEN_ELDR ;
1590 rtw_write16(padapter, REG_SYS_FUNC_EN, tmpV16);
1593 /* Clock: Gated(0x0008h[5]) 8M(0x0008h[1]) clock from ANA, default valid */
1594 tmpV16 = rtw_read16(padapter, REG_SYS_CLKR);
1595 if ((!(tmpV16 & LOADER_CLK_EN)) || (!(tmpV16 & ANA8M))) {
1596 tmpV16 |= (LOADER_CLK_EN | ANA8M) ;
1597 rtw_write16(padapter, REG_SYS_CLKR, tmpV16);
1600 if (bWrite == _TRUE) {
1601 /* Enable LDO 2.5V before read/write action */
1602 tempval = rtw_read8(padapter, EFUSE_TEST + 3);
1604 /*tempval |= (VOLTAGE_V25 << 4);*/
1605 tempval |= 0x70; /* 0x34[30:28] = 0b'111, Use LDO 2.25V, Suggested by SD1 Morris & Victor*/
1606 rtw_write8(padapter, EFUSE_TEST + 3, (tempval | 0x80));
1608 /* rtw_write8(padapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_ON); */
1612 /*enable BT output isolation 0x6A[15] = 1 */
1613 tempval = rtw_read8(padapter, 0x6B);
1615 rtw_write8(padapter, 0x6B, tempval);
1617 rtw_write8(padapter, REG_EFUSE_ACCESS, EFUSE_ACCESS_OFF);
1619 if (bWrite == _TRUE) {
1620 /* Disable LDO 2.5V after read/write action */
1621 tempval = rtw_read8(padapter, EFUSE_TEST + 3);
1622 rtw_write8(padapter, EFUSE_TEST + 3, (tempval & 0x7F));
1636 #ifdef HAL_EFUSE_MEMORY
1637 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
1638 PEFUSE_HAL pEfuseHal = &pHalData->EfuseHal;
1640 u8 *efuseTbl = NULL;
1643 u8 efuseHeader, efuseExtHdr, efuseData;
1647 /* RTW_INFO("YJ: ====>%s():_offset=%d _size_byte=%d bPseudoTest=%d\n", __func__, _offset, _size_byte, bPseudoTest); */
1649 /* Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10. */
1651 if ((_offset + _size_byte) > EFUSE_MAX_MAP_LEN) {
1652 RTW_INFO("%s: Invalid offset(%#x) with read bytes(%#x)!!\n", __FUNCTION__, _offset, _size_byte);
1656 efuseTbl = (u8 *)rtw_malloc(EFUSE_MAX_MAP_LEN);
1657 if (efuseTbl == NULL) {
1658 RTW_INFO("%s: alloc efuseTbl fail!\n", __FUNCTION__);
1661 /* 0xff will be efuse default value instead of 0x00. */
1662 _rtw_memset(efuseTbl, 0xFF, EFUSE_MAX_MAP_LEN);
1665 #ifdef CONFIG_RTW_DEBUG
1667 for (i = 0; i < 256; i++)
1668 /* ReadEFuseByte(padapter, i, &efuseTbl[i], _FALSE); */
1669 efuse_OneByteRead(padapter, i, &efuseTbl[i], _FALSE);
1670 RTW_INFO("Efuse Content:\n");
1671 for (i = 0; i < 256; i++) {
1674 printk("%02X ", efuseTbl[i]);
1681 /* switch bank back to bank 0 for later BT and wifi use. */
1682 hal_EfuseSwitchToBank(padapter, 0, bPseudoTest);
1684 while (AVAILABLE_EFUSE_ADDR(eFuse_Addr)) {
1685 /* ReadEFuseByte(padapter, eFuse_Addr++, &efuseHeader, bPseudoTest); */
1686 efuse_OneByteRead(padapter, eFuse_Addr++, &efuseHeader, bPseudoTest);
1687 if (efuseHeader == 0xFF) {
1688 RTW_INFO("%s: data end at address=%#x\n", __FUNCTION__, eFuse_Addr - 1);
1691 /* RTW_INFO("%s: efuse[0x%X]=0x%02X\n", __FUNCTION__, eFuse_Addr-1, efuseHeader); */
1693 /* Check PG header for section num. */
1694 if (EXT_HEADER(efuseHeader)) { /* extended header */
1695 offset = GET_HDR_OFFSET_2_0(efuseHeader);
1696 /* RTW_INFO("%s: extended header offset=0x%X\n", __FUNCTION__, offset); */
1698 /* ReadEFuseByte(padapter, eFuse_Addr++, &efuseExtHdr, bPseudoTest); */
1699 efuse_OneByteRead(padapter, eFuse_Addr++, &efuseExtHdr, bPseudoTest);
1700 /* RTW_INFO("%s: efuse[0x%X]=0x%02X\n", __FUNCTION__, eFuse_Addr-1, efuseExtHdr); */
1701 if (ALL_WORDS_DISABLED(efuseExtHdr))
1704 offset |= ((efuseExtHdr & 0xF0) >> 1);
1705 wden = (efuseExtHdr & 0x0F);
1707 offset = ((efuseHeader >> 4) & 0x0f);
1708 wden = (efuseHeader & 0x0f);
1710 /* RTW_INFO("%s: Offset=%d Worden=0x%X\n", __FUNCTION__, offset, wden); */
1712 if (offset < EFUSE_MAX_SECTION_8703B) {
1714 /* Get word enable value from PG header
1715 * RTW_INFO("%s: Offset=%d Worden=0x%X\n", __FUNCTION__, offset, wden); */
1717 addr = offset * PGPKT_DATA_SIZE;
1718 for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
1719 /* Check word enable condition in the section */
1720 if (!(wden & (0x01 << i))) {
1722 /* ReadEFuseByte(padapter, eFuse_Addr++, &efuseData, bPseudoTest); */
1723 efuse_OneByteRead(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
1724 /* RTW_INFO("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, eFuse_Addr-1, efuseData); */
1725 efuseTbl[addr] = efuseData;
1728 /* ReadEFuseByte(padapter, eFuse_Addr++, &efuseData, bPseudoTest); */
1729 efuse_OneByteRead(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
1730 /* RTW_INFO("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, eFuse_Addr-1, efuseData); */
1731 efuseTbl[addr + 1] = efuseData;
1736 RTW_ERR("%s: offset(%d) is illegal!!\n", __FUNCTION__, offset);
1737 eFuse_Addr += Efuse_CalculateWordCnts(wden) * 2;
1741 /* Copy from Efuse map to output pointer memory!!! */
1742 for (i = 0; i < _size_byte; i++)
1743 pbuf[i] = efuseTbl[_offset + i];
1745 /* Calculate Efuse utilization */
1747 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &total, bPseudoTest);
1748 used = eFuse_Addr - 1;
1750 efuse_usage = (u8)((used * 100) / total);
1754 #ifdef HAL_EFUSE_MEMORY
1755 pEfuseHal->fakeEfuseUsedBytes = used;
1757 fakeEfuseUsedBytes = used;
1760 rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8 *)&used);
1761 rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_USAGE, (u8 *)&efuse_usage);
1765 rtw_mfree(efuseTbl, EFUSE_MAX_MAP_LEN);
1777 #ifdef HAL_EFUSE_MEMORY
1778 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
1779 PEFUSE_HAL pEfuseHal = &pHalData->EfuseHal;
1784 u8 efuseHeader, efuseExtHdr, efuseData;
1791 /* Do NOT excess total size of EFuse table. Added by Roger, 2008.11.10. */
1793 if ((_offset + _size_byte) > EFUSE_BT_MAP_LEN) {
1794 RTW_INFO("%s: Invalid offset(%#x) with read bytes(%#x)!!\n", __FUNCTION__, _offset, _size_byte);
1798 efuseTbl = rtw_malloc(EFUSE_BT_MAP_LEN);
1799 if (efuseTbl == NULL) {
1800 RTW_INFO("%s: efuseTbl malloc fail!\n", __FUNCTION__);
1803 /* 0xff will be efuse default value instead of 0x00. */
1804 _rtw_memset(efuseTbl, 0xFF, EFUSE_BT_MAP_LEN);
1807 EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_BANK, &total, bPseudoTest);
1809 for (bank = 1; bank < 3; bank++) { /* 8703b Max bake 0~2 */
1810 if (hal_EfuseSwitchToBank(padapter, bank, bPseudoTest) == _FALSE) {
1811 RTW_INFO("%s: hal_EfuseSwitchToBank Fail!!\n", __FUNCTION__);
1817 while (AVAILABLE_EFUSE_ADDR(eFuse_Addr)) {
1818 /* ReadEFuseByte(padapter, eFuse_Addr++, &efuseHeader, bPseudoTest); */
1819 efuse_OneByteRead(padapter, eFuse_Addr++, &efuseHeader, bPseudoTest);
1820 if (efuseHeader == 0xFF)
1822 RTW_INFO("%s: efuse[%#X]=0x%02x (header)\n", __FUNCTION__, (((bank - 1) * EFUSE_REAL_CONTENT_LEN_8703B) + eFuse_Addr - 1), efuseHeader);
1824 /* Check PG header for section num. */
1825 if (EXT_HEADER(efuseHeader)) { /* extended header */
1826 offset = GET_HDR_OFFSET_2_0(efuseHeader);
1827 RTW_INFO("%s: extended header offset_2_0=0x%X\n", __FUNCTION__, offset);
1829 /* ReadEFuseByte(padapter, eFuse_Addr++, &efuseExtHdr, bPseudoTest); */
1830 efuse_OneByteRead(padapter, eFuse_Addr++, &efuseExtHdr, bPseudoTest);
1831 RTW_INFO("%s: efuse[%#X]=0x%02x (ext header)\n", __FUNCTION__, (((bank - 1) * EFUSE_REAL_CONTENT_LEN_8703B) + eFuse_Addr - 1), efuseExtHdr);
1832 if (ALL_WORDS_DISABLED(efuseExtHdr))
1835 offset |= ((efuseExtHdr & 0xF0) >> 1);
1836 wden = (efuseExtHdr & 0x0F);
1838 offset = ((efuseHeader >> 4) & 0x0f);
1839 wden = (efuseHeader & 0x0f);
1842 if (offset < EFUSE_BT_MAX_SECTION) {
1845 /* Get word enable value from PG header */
1846 RTW_INFO("%s: Offset=%d Worden=%#X\n", __FUNCTION__, offset, wden);
1848 addr = offset * PGPKT_DATA_SIZE;
1849 for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
1850 /* Check word enable condition in the section */
1851 if (!(wden & (0x01 << i))) {
1853 /* ReadEFuseByte(padapter, eFuse_Addr++, &efuseData, bPseudoTest); */
1854 efuse_OneByteRead(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
1855 RTW_INFO("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, eFuse_Addr - 1, efuseData);
1856 efuseTbl[addr] = efuseData;
1859 /* ReadEFuseByte(padapter, eFuse_Addr++, &efuseData, bPseudoTest); */
1860 efuse_OneByteRead(padapter, eFuse_Addr++, &efuseData, bPseudoTest);
1861 RTW_INFO("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, eFuse_Addr - 1, efuseData);
1862 efuseTbl[addr + 1] = efuseData;
1867 RTW_INFO("%s: offset(%d) is illegal!!\n", __FUNCTION__, offset);
1868 eFuse_Addr += Efuse_CalculateWordCnts(wden) * 2;
1872 if ((eFuse_Addr - 1) < total) {
1873 RTW_INFO("%s: bank(%d) data end at %#x\n", __FUNCTION__, bank, eFuse_Addr - 1);
1878 /* switch bank back to bank 0 for later BT and wifi use. */
1879 hal_EfuseSwitchToBank(padapter, 0, bPseudoTest);
1881 /* Copy from Efuse map to output pointer memory!!! */
1882 for (i = 0; i < _size_byte; i++)
1883 pbuf[i] = efuseTbl[_offset + i];
1886 /* Calculate Efuse utilization. */
1888 EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &total, bPseudoTest);
1889 used = (EFUSE_BT_REAL_BANK_CONTENT_LEN * (bank - 1)) + eFuse_Addr - 1;
1890 RTW_INFO("%s: bank(%d) data end at %#x ,used =%d\n", __FUNCTION__, bank, eFuse_Addr - 1, used);
1891 efuse_usage = (u8)((used * 100) / total);
1893 #ifdef HAL_EFUSE_MEMORY
1894 pEfuseHal->fakeBTEfuseUsedBytes = used;
1896 fakeBTEfuseUsedBytes = used;
1899 rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, (u8 *)&used);
1900 rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BT_USAGE, (u8 *)&efuse_usage);
1905 rtw_mfree(efuseTbl, EFUSE_BT_MAP_LEN);
1917 if (efuseType == EFUSE_WIFI)
1918 hal_ReadEFuse_WiFi(padapter, _offset, _size_byte, pbuf, bPseudoTest);
1920 hal_ReadEFuse_BT(padapter, _offset, _size_byte, pbuf, bPseudoTest);
1924 hal_EfuseGetCurrentSize_WiFi(
1928 #ifdef HAL_EFUSE_MEMORY
1929 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
1930 PEFUSE_HAL pEfuseHal = &pHalData->EfuseHal;
1933 u16 start_addr = 0; /* for debug */
1934 u8 hoffset = 0, hworden = 0;
1935 u8 efuse_data, word_cnts = 0;
1936 u32 count = 0; /* for debug */
1940 #ifdef HAL_EFUSE_MEMORY
1941 efuse_addr = (u16)pEfuseHal->fakeEfuseUsedBytes;
1943 efuse_addr = (u16)fakeEfuseUsedBytes;
1946 rtw_hal_get_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8 *)&efuse_addr);
1947 start_addr = efuse_addr;
1948 RTW_INFO("%s: start_efuse_addr=0x%X\n", __FUNCTION__, efuse_addr);
1950 /* switch bank back to bank 0 for later BT and wifi use. */
1951 hal_EfuseSwitchToBank(padapter, 0, bPseudoTest);
1953 #if 0 /* for debug test */
1954 efuse_OneByteRead(padapter, 0x1FF, &efuse_data, bPseudoTest);
1955 RTW_INFO(FUNC_ADPT_FMT ": efuse raw 0x1FF=0x%02X\n",
1956 FUNC_ADPT_ARG(padapter), efuse_data);
1958 #endif /* for debug test */
1961 while (AVAILABLE_EFUSE_ADDR(efuse_addr)) {
1963 if (efuse_OneByteRead(padapter, efuse_addr, &efuse_data, bPseudoTest) == _FALSE) {
1964 RTW_ERR("%s: efuse_OneByteRead Fail! addr=0x%X !!\n", __FUNCTION__, efuse_addr);
1968 ReadEFuseByte(padapter, efuse_addr, &efuse_data, bPseudoTest);
1971 if (efuse_data == 0xFF)
1974 if ((start_addr != 0) && (efuse_addr == start_addr)) {
1976 RTW_INFO(FUNC_ADPT_FMT ": [WARNING] efuse raw 0x%X=0x%02X not 0xFF!!(%d times)\n",
1977 FUNC_ADPT_ARG(padapter), efuse_addr, efuse_data, count);
1984 /* try again form address 0 */
1995 if (EXT_HEADER(efuse_data)) {
1996 hoffset = GET_HDR_OFFSET_2_0(efuse_data);
1998 efuse_OneByteRead(padapter, efuse_addr, &efuse_data, bPseudoTest);
1999 if (ALL_WORDS_DISABLED(efuse_data))
2002 hoffset |= ((efuse_data & 0xF0) >> 1);
2003 hworden = efuse_data & 0x0F;
2005 hoffset = (efuse_data >> 4) & 0x0F;
2006 hworden = efuse_data & 0x0F;
2009 word_cnts = Efuse_CalculateWordCnts(hworden);
2010 efuse_addr += (word_cnts * 2) + 1;
2014 #ifdef HAL_EFUSE_MEMORY
2015 pEfuseHal->fakeEfuseUsedBytes = efuse_addr;
2017 fakeEfuseUsedBytes = efuse_addr;
2020 rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8 *)&efuse_addr);
2025 /* report max size to prevent wirte efuse */
2026 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &efuse_addr, bPseudoTest);
2029 RTW_INFO("%s: CurrentSize=%d\n", __FUNCTION__, efuse_addr);
2035 hal_EfuseGetCurrentSize_BT(
2039 #ifdef HAL_EFUSE_MEMORY
2040 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
2041 PEFUSE_HAL pEfuseHal = &pHalData->EfuseHal;
2046 u8 hoffset = 0, hworden = 0;
2047 u8 efuse_data, word_cnts = 0;
2049 u8 bContinual = _TRUE;
2053 #ifdef HAL_EFUSE_MEMORY
2054 btusedbytes = pEfuseHal->fakeBTEfuseUsedBytes;
2056 btusedbytes = fakeBTEfuseUsedBytes;
2060 rtw_hal_get_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, (u8 *)&btusedbytes);
2062 efuse_addr = (u16)((btusedbytes % EFUSE_BT_REAL_BANK_CONTENT_LEN));
2063 startBank = (u8)(1 + (btusedbytes / EFUSE_BT_REAL_BANK_CONTENT_LEN));
2065 RTW_INFO("%s: start from bank=%d addr=0x%X\n", __FUNCTION__, startBank, efuse_addr);
2067 EFUSE_GetEfuseDefinition(padapter, EFUSE_BT, TYPE_AVAILABLE_EFUSE_BYTES_BANK, &retU2, bPseudoTest);
2069 for (bank = startBank; bank < 3; bank++) {
2070 if (hal_EfuseSwitchToBank(padapter, bank, bPseudoTest) == _FALSE) {
2071 RTW_ERR("%s: switch bank(%d) Fail!!\n", __FUNCTION__, bank);
2072 /* bank = EFUSE_MAX_BANK; */
2076 /* only when bank is switched we have to reset the efuse_addr. */
2077 if (bank != startBank)
2081 while (AVAILABLE_EFUSE_ADDR(efuse_addr)) {
2082 if (efuse_OneByteRead(padapter, efuse_addr, &efuse_data, bPseudoTest) == _FALSE) {
2083 RTW_ERR("%s: efuse_OneByteRead Fail! addr=0x%X !!\n", __FUNCTION__, efuse_addr);
2084 /* bank = EFUSE_MAX_BANK; */
2087 RTW_INFO("%s: efuse_OneByteRead ! addr=0x%X !efuse_data=0x%X! bank =%d\n", __FUNCTION__, efuse_addr, efuse_data, bank);
2089 if (efuse_data == 0xFF)
2092 if (EXT_HEADER(efuse_data)) {
2093 hoffset = GET_HDR_OFFSET_2_0(efuse_data);
2095 efuse_OneByteRead(padapter, efuse_addr, &efuse_data, bPseudoTest);
2096 RTW_INFO("%s: efuse_OneByteRead EXT_HEADER ! addr=0x%X !efuse_data=0x%X! bank =%d\n", __FUNCTION__, efuse_addr, efuse_data, bank);
2098 if (ALL_WORDS_DISABLED(efuse_data)) {
2103 /* hoffset = ((hoffset & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1); */
2104 hoffset |= ((efuse_data & 0xF0) >> 1);
2105 hworden = efuse_data & 0x0F;
2107 hoffset = (efuse_data >> 4) & 0x0F;
2108 hworden = efuse_data & 0x0F;
2111 RTW_INFO(FUNC_ADPT_FMT": Offset=%d Worden=%#X\n",
2112 FUNC_ADPT_ARG(padapter), hoffset, hworden);
2114 word_cnts = Efuse_CalculateWordCnts(hworden);
2115 /* read next header */
2116 efuse_addr += (word_cnts * 2) + 1;
2119 while (bContinual &&
2120 efuse_OneByteRead(padapter, efuse_addr , &efuse_data, bPseudoTest) &&
2121 AVAILABLE_EFUSE_ADDR(efuse_addr)) {
2122 if (efuse_data != 0xFF) {
2123 if ((efuse_data & 0x1F) == 0x0F) { /* extended header */
2124 hoffset = efuse_data;
2126 efuse_OneByteRead(padapter, efuse_addr , &efuse_data, bPseudoTest);
2127 if ((efuse_data & 0x0F) == 0x0F) {
2131 hoffset = ((hoffset & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
2132 hworden = efuse_data & 0x0F;
2135 hoffset = (efuse_data >> 4) & 0x0F;
2136 hworden = efuse_data & 0x0F;
2138 word_cnts = Efuse_CalculateWordCnts(hworden);
2139 /* read next header */
2140 efuse_addr = efuse_addr + (word_cnts * 2) + 1;
2142 bContinual = _FALSE ;
2147 /* Check if we need to check next bank efuse */
2148 if (efuse_addr < retU2) {
2149 break;/* don't need to check next bank. */
2153 retU2 = ((bank - 1) * EFUSE_BT_REAL_BANK_CONTENT_LEN) + efuse_addr;
2155 #ifdef HAL_EFUSE_MEMORY
2156 pEfuseHal->fakeBTEfuseUsedBytes = retU2;
2158 fakeBTEfuseUsedBytes = retU2;
2161 rtw_hal_set_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, (u8 *)&retU2);
2163 retU2 = ((bank - 1) * EFUSE_BT_REAL_BANK_CONTENT_LEN) + efuse_addr;
2165 pEfuseHal->fakeBTEfuseUsedBytes = retU2;
2166 /* RT_DISP(FEEPROM, EFUSE_PG, ("Hal_EfuseGetCurrentSize_BT92C(), already use %u bytes\n", pEfuseHal->fakeBTEfuseUsedBytes)); */
2168 pEfuseHal->BTEfuseUsedBytes = retU2;
2169 /* RT_DISP(FEEPROM, EFUSE_PG, ("Hal_EfuseGetCurrentSize_BT92C(), already use %u bytes\n", pEfuseHal->BTEfuseUsedBytes)); */
2173 RTW_INFO("%s: CurrentSize=%d\n", __FUNCTION__, retU2);
2178 Hal_EfuseGetCurrentSize(
2185 if (efuseType == EFUSE_WIFI)
2186 ret = hal_EfuseGetCurrentSize_WiFi(pAdapter, bPseudoTest);
2188 ret = hal_EfuseGetCurrentSize_BT(pAdapter, bPseudoTest);
2194 Hal_EfuseWordEnableDataWrite(
2202 u16 start_addr = efuse_addr;
2203 u8 badworden = 0x0F;
2204 u8 tmpdata[PGPKT_DATA_SIZE];
2207 /* RTW_INFO("%s: efuse_addr=%#x word_en=%#x\n", __FUNCTION__, efuse_addr, word_en); */
2208 _rtw_memset(tmpdata, 0xFF, PGPKT_DATA_SIZE);
2210 if (!(word_en & BIT(0))) {
2211 tmpaddr = start_addr;
2212 efuse_OneByteWrite(padapter, start_addr++, data[0], bPseudoTest);
2213 efuse_OneByteWrite(padapter, start_addr++, data[1], bPseudoTest);
2214 phy_set_mac_reg(padapter, EFUSE_TEST, BIT26, 0);
2215 efuse_OneByteRead(padapter, tmpaddr, &tmpdata[0], bPseudoTest);
2216 efuse_OneByteRead(padapter, tmpaddr + 1, &tmpdata[1], bPseudoTest);
2217 phy_set_mac_reg(padapter, EFUSE_TEST, BIT26, 1);
2218 if ((data[0] != tmpdata[0]) || (data[1] != tmpdata[1]))
2219 badworden &= (~BIT(0));
2221 if (!(word_en & BIT(1))) {
2222 tmpaddr = start_addr;
2223 efuse_OneByteWrite(padapter, start_addr++, data[2], bPseudoTest);
2224 efuse_OneByteWrite(padapter, start_addr++, data[3], bPseudoTest);
2225 phy_set_mac_reg(padapter, EFUSE_TEST, BIT26, 0);
2226 efuse_OneByteRead(padapter, tmpaddr, &tmpdata[2], bPseudoTest);
2227 efuse_OneByteRead(padapter, tmpaddr + 1, &tmpdata[3], bPseudoTest);
2228 phy_set_mac_reg(padapter, EFUSE_TEST, BIT26, 1);
2229 if ((data[2] != tmpdata[2]) || (data[3] != tmpdata[3]))
2230 badworden &= (~BIT(1));
2232 if (!(word_en & BIT(2))) {
2233 tmpaddr = start_addr;
2234 efuse_OneByteWrite(padapter, start_addr++, data[4], bPseudoTest);
2235 efuse_OneByteWrite(padapter, start_addr++, data[5], bPseudoTest);
2236 phy_set_mac_reg(padapter, EFUSE_TEST, BIT26, 0);
2237 efuse_OneByteRead(padapter, tmpaddr, &tmpdata[4], bPseudoTest);
2238 efuse_OneByteRead(padapter, tmpaddr + 1, &tmpdata[5], bPseudoTest);
2239 phy_set_mac_reg(padapter, EFUSE_TEST, BIT26, 1);
2240 if ((data[4] != tmpdata[4]) || (data[5] != tmpdata[5]))
2241 badworden &= (~BIT(2));
2243 if (!(word_en & BIT(3))) {
2244 tmpaddr = start_addr;
2245 efuse_OneByteWrite(padapter, start_addr++, data[6], bPseudoTest);
2246 efuse_OneByteWrite(padapter, start_addr++, data[7], bPseudoTest);
2247 phy_set_mac_reg(padapter, EFUSE_TEST, BIT26, 0);
2248 efuse_OneByteRead(padapter, tmpaddr, &tmpdata[6], bPseudoTest);
2249 efuse_OneByteRead(padapter, tmpaddr + 1, &tmpdata[7], bPseudoTest);
2250 phy_set_mac_reg(padapter, EFUSE_TEST, BIT26, 1);
2251 if ((data[6] != tmpdata[6]) || (data[7] != tmpdata[7]))
2252 badworden &= (~BIT(3));
2259 Hal_EfusePgPacketRead(
2265 u8 bDataEmpty = _TRUE;
2266 u8 efuse_data, word_cnts = 0;
2268 u8 hoffset = 0, hworden = 0;
2277 EFUSE_GetEfuseDefinition(padapter, EFUSE_WIFI, TYPE_EFUSE_MAX_SECTION, &max_section, bPseudoTest);
2278 if (offset > max_section) {
2279 RTW_INFO("%s: Packet offset(%d) is illegal(>%d)!\n", __FUNCTION__, offset, max_section);
2283 _rtw_memset(data, 0xFF, PGPKT_DATA_SIZE);
2287 /* <Roger_TODO> Efuse has been pre-programmed dummy 5Bytes at the end of Efuse by CP. */
2288 /* Skip dummy parts to prevent unexpected data read from Efuse. */
2289 /* By pass right now. 2009.02.19. */
2291 while (AVAILABLE_EFUSE_ADDR(efuse_addr)) {
2292 if (efuse_OneByteRead(padapter, efuse_addr++, &efuse_data, bPseudoTest) == _FALSE) {
2297 if (efuse_data == 0xFF)
2300 if (EXT_HEADER(efuse_data)) {
2301 hoffset = GET_HDR_OFFSET_2_0(efuse_data);
2302 efuse_OneByteRead(padapter, efuse_addr++, &efuse_data, bPseudoTest);
2303 if (ALL_WORDS_DISABLED(efuse_data)) {
2304 RTW_INFO("%s: Error!! All words disabled!\n", __FUNCTION__);
2308 hoffset |= ((efuse_data & 0xF0) >> 1);
2309 hworden = efuse_data & 0x0F;
2311 hoffset = (efuse_data >> 4) & 0x0F;
2312 hworden = efuse_data & 0x0F;
2315 if (hoffset == offset) {
2316 for (i = 0; i < EFUSE_MAX_WORD_UNIT; i++) {
2317 /* Check word enable condition in the section */
2318 if (!(hworden & (0x01 << i))) {
2319 /* ReadEFuseByte(padapter, efuse_addr++, &efuse_data, bPseudoTest); */
2320 efuse_OneByteRead(padapter, efuse_addr++, &efuse_data, bPseudoTest);
2321 /* RTW_INFO("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, efuse_addr+tmpidx, efuse_data); */
2322 data[i * 2] = efuse_data;
2324 /* ReadEFuseByte(padapter, efuse_addr++, &efuse_data, bPseudoTest); */
2325 efuse_OneByteRead(padapter, efuse_addr++, &efuse_data, bPseudoTest);
2326 /* RTW_INFO("%s: efuse[%#X]=0x%02X\n", __FUNCTION__, efuse_addr+tmpidx, efuse_data); */
2327 data[(i * 2) + 1] = efuse_data;
2331 word_cnts = Efuse_CalculateWordCnts(hworden);
2332 efuse_addr += word_cnts * 2;
2340 hal_EfusePgCheckAvailableAddr(
2345 u16 max_available = 0;
2349 EFUSE_GetEfuseDefinition(pAdapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &max_available, bPseudoTest);
2350 /* RTW_INFO("%s: max_available=%d\n", __FUNCTION__, max_available); */
2352 current_size = Efuse_GetCurrentSize(pAdapter, efuseType, bPseudoTest);
2353 if (current_size >= max_available) {
2354 RTW_INFO("%s: Error!! current_size(%d)>max_available(%d)\n", __FUNCTION__, current_size, max_available);
2361 hal_EfuseConstructPGPkt(
2365 PPGPKT_STRUCT pTargetPkt)
2367 _rtw_memset(pTargetPkt->data, 0xFF, PGPKT_DATA_SIZE);
2368 pTargetPkt->offset = offset;
2369 pTargetPkt->word_en = word_en;
2370 efuse_WordEnableDataRead(word_en, pData, pTargetPkt->data);
2371 pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en);
2377 PPGPKT_STRUCT pTargetPkt,
2378 PPGPKT_STRUCT pCurPkt,
2381 u8 match_word_en = 0x0F; /* default all words are disabled */
2384 /* check if the same words are enabled both target and current PG packet */
2385 if (((pTargetPkt->word_en & BIT(0)) == 0) &&
2386 ((pCurPkt->word_en & BIT(0)) == 0)) {
2387 match_word_en &= ~BIT(0); /* enable word 0 */
2389 if (((pTargetPkt->word_en & BIT(1)) == 0) &&
2390 ((pCurPkt->word_en & BIT(1)) == 0)) {
2391 match_word_en &= ~BIT(1); /* enable word 1 */
2393 if (((pTargetPkt->word_en & BIT(2)) == 0) &&
2394 ((pCurPkt->word_en & BIT(2)) == 0)) {
2395 match_word_en &= ~BIT(2); /* enable word 2 */
2397 if (((pTargetPkt->word_en & BIT(3)) == 0) &&
2398 ((pCurPkt->word_en & BIT(3)) == 0)) {
2399 match_word_en &= ~BIT(3); /* enable word 3 */
2402 *pWden = match_word_en;
2404 if (match_word_en != 0xf)
2411 hal_EfuseCheckIfDatafollowed(
2420 for (i = 0; i < (word_cnts * 2); i++) {
2421 if (efuse_OneByteRead(pAdapter, (startAddr + i) , &efuse_data, bPseudoTest) == _FALSE) {
2422 RTW_INFO("%s: efuse_OneByteRead FAIL!!\n", __FUNCTION__);
2427 if (efuse_data != 0xFF) {
2438 hal_EfusePartialWriteCheck(
2442 PPGPKT_STRUCT pTargetPkt,
2445 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
2446 PEFUSE_HAL pEfuseHal = &pHalData->EfuseHal;
2448 u16 startAddr = 0, efuse_max_available_len = 0, efuse_max = 0;
2451 u8 i, cur_header = 0;
2452 u8 new_wden = 0, matched_wden = 0, badworden = 0;
2453 PGPKT_STRUCT curPkt;
2457 EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_TOTAL, &efuse_max_available_len, bPseudoTest);
2458 EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_EFUSE_CONTENT_LEN_BANK, &efuse_max, bPseudoTest);
2460 if (efuseType == EFUSE_WIFI) {
2462 #ifdef HAL_EFUSE_MEMORY
2463 startAddr = (u16)pEfuseHal->fakeEfuseUsedBytes;
2465 startAddr = (u16)fakeEfuseUsedBytes;
2468 rtw_hal_get_hwreg(padapter, HW_VAR_EFUSE_BYTES, (u8 *)&startAddr);
2471 #ifdef HAL_EFUSE_MEMORY
2472 startAddr = (u16)pEfuseHal->fakeBTEfuseUsedBytes;
2474 startAddr = (u16)fakeBTEfuseUsedBytes;
2477 rtw_hal_get_hwreg(padapter, HW_VAR_EFUSE_BT_BYTES, (u8 *)&startAddr);
2479 startAddr %= efuse_max;
2480 RTW_INFO("%s: startAddr=%#X\n", __FUNCTION__, startAddr);
2483 if (startAddr >= efuse_max_available_len) {
2485 RTW_INFO("%s: startAddr(%d) >= efuse_max_available_len(%d)\n",
2486 __FUNCTION__, startAddr, efuse_max_available_len);
2490 if (efuse_OneByteRead(padapter, startAddr, &efuse_data, bPseudoTest) && (efuse_data != 0xFF)) {
2493 RTW_INFO("%s: Something Wrong! last bytes(%#X=0x%02X) is not 0xFF\n",
2494 __FUNCTION__, startAddr, efuse_data);
2497 if (EXT_HEADER(efuse_data)) {
2498 cur_header = efuse_data;
2500 efuse_OneByteRead(padapter, startAddr, &efuse_data, bPseudoTest);
2501 if (ALL_WORDS_DISABLED(efuse_data)) {
2502 RTW_INFO("%s: Error condition, all words disabled!", __FUNCTION__);
2506 curPkt.offset = ((cur_header & 0xE0) >> 5) | ((efuse_data & 0xF0) >> 1);
2507 curPkt.word_en = efuse_data & 0x0F;
2510 cur_header = efuse_data;
2511 curPkt.offset = (cur_header >> 4) & 0x0F;
2512 curPkt.word_en = cur_header & 0x0F;
2515 curPkt.word_cnts = Efuse_CalculateWordCnts(curPkt.word_en);
2516 /* if same header is found but no data followed */
2517 /* write some part of data followed by the header. */
2518 if ((curPkt.offset == pTargetPkt->offset) &&
2519 (hal_EfuseCheckIfDatafollowed(padapter, curPkt.word_cnts, startAddr + 1, bPseudoTest) == _FALSE) &&
2520 wordEnMatched(pTargetPkt, &curPkt, &matched_wden) == _TRUE) {
2521 RTW_INFO("%s: Need to partial write data by the previous wrote header\n", __FUNCTION__);
2522 /* Here to write partial data */
2523 badworden = Efuse_WordEnableDataWrite(padapter, startAddr + 1, matched_wden, pTargetPkt->data, bPseudoTest);
2524 if (badworden != 0x0F) {
2525 u32 PgWriteSuccess = 0;
2526 /* if write fail on some words, write these bad words again */
2527 if (efuseType == EFUSE_WIFI)
2528 PgWriteSuccess = Efuse_PgPacketWrite(padapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest);
2530 PgWriteSuccess = Efuse_PgPacketWrite_BT(padapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest);
2532 if (!PgWriteSuccess) {
2533 bRet = _FALSE; /* write fail, return */
2537 /* partial write ok, update the target packet for later use */
2538 for (i = 0; i < 4; i++) {
2539 if ((matched_wden & (0x1 << i)) == 0) { /* this word has been written */
2540 pTargetPkt->word_en |= (0x1 << i); /* disable the word */
2543 pTargetPkt->word_cnts = Efuse_CalculateWordCnts(pTargetPkt->word_en);
2545 /* read from next header */
2546 startAddr = startAddr + (curPkt.word_cnts * 2) + 1;
2549 /* not used header, 0xff */
2551 /* RTW_INFO("%s: Started from unused header offset=%d\n", __FUNCTION__, startAddr)); */
2561 hal_EfuseFixHeaderProcess(
2562 IN PADAPTER pAdapter,
2563 IN u1Byte efuseType,
2564 IN PPGPKT_STRUCT pFixPkt,
2566 IN BOOLEAN bPseudoTest
2569 u1Byte originaldata[8], badworden=0;
2570 u2Byte efuse_addr=*pAddr;
2571 u4Byte PgWriteSuccess=0;
2573 _rtw_memset((PVOID)originaldata, 8, 0xff);
2575 if (Efuse_PgPacketRead(pAdapter, pFixPkt->offset, originaldata, bPseudoTest)) {
2576 badworden = Hal_EfuseWordEnableDataWrite(pAdapter, efuse_addr+1, pFixPkt->word_en, originaldata, bPseudoTest);
2578 if (badworden != 0xf) {
2580 PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pFixPkt->offset, badworden, originaldata, bPseudoTest);
2581 if (!PgWriteSuccess)
2584 efuse_addr = Hal_EfuseGetCurrentSize(pAdapter, efuseType, bPseudoTest);
2586 efuse_addr = efuse_addr + (pFixPkt->word_cnts*2) +1;
2589 efuse_addr = efuse_addr + (pFixPkt->word_cnts*2) +1;
2592 *pAddr = efuse_addr;
2597 hal_EfusePgPacketWrite1ByteHeader(
2601 PPGPKT_STRUCT pTargetPkt,
2605 u8 pg_header = 0, tmp_header = 0;
2606 u16 efuse_addr = *pAddr;
2610 /* RTW_INFO("%s\n", __FUNCTION__); */
2611 pg_header = ((pTargetPkt->offset << 4) & 0xf0) | pTargetPkt->word_en;
2613 efuse_OneByteWrite(pAdapter, efuse_addr, pg_header, bPseudoTest);
2615 phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT26, 0);
2617 efuse_OneByteRead(pAdapter, efuse_addr, &tmp_header, bPseudoTest);
2619 phy_set_mac_reg(pAdapter, EFUSE_TEST, BIT26, 1);
2621 while (tmp_header == 0xFF || pg_header != tmp_header) {
2622 if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) {
2623 RTW_ERR("retry %d times fail!!\n", repeatcnt);
2626 efuse_OneByteWrite(pAdapter,efuse_addr, pg_header, bPseudoTest);
2627 efuse_OneByteRead(pAdapter,efuse_addr, &tmp_header, bPseudoTest);
2628 RTW_ERR("===>%s: Keep %d-th retrying,pg_header = 0x%X tmp_header = 0x%X\n", __FUNCTION__,repeatcnt, pg_header, tmp_header);
2631 if (pg_header == tmp_header)
2634 PGPKT_STRUCT fixPkt;
2636 RTW_ERR(" pg_header(0x%X) != tmp_header(0x%X)\n", pg_header, tmp_header);
2637 RTW_ERR("Error condition for fixed PG packet, need to cover the existed data: (Addr, Data) = (0x%X, 0x%X)\n",
2638 efuse_addr, tmp_header);
2639 fixPkt.offset = (tmp_header>>4) & 0x0F;
2640 fixPkt.word_en = tmp_header & 0x0F;
2641 fixPkt.word_cnts = Efuse_CalculateWordCnts(fixPkt.word_en);
2642 if (!hal_EfuseFixHeaderProcess(pAdapter, efuseType, &fixPkt, &efuse_addr, bPseudoTest))
2646 *pAddr = efuse_addr;
2652 hal_EfusePgPacketWrite2ByteHeader(
2656 PPGPKT_STRUCT pTargetPkt,
2659 u16 efuse_addr, efuse_max_available_len = 0;
2660 u8 pg_header = 0, tmp_header = 0, pg_header_temp = 0;
2664 /* RTW_INFO("%s\n", __FUNCTION__); */
2665 EFUSE_GetEfuseDefinition(padapter, efuseType, TYPE_AVAILABLE_EFUSE_BYTES_BANK, &efuse_max_available_len, bPseudoTest);
2667 efuse_addr = *pAddr;
2669 if (efuse_addr >= efuse_max_available_len) {
2670 RTW_INFO("%s: addr(%d) over avaliable(%d)!!\n", __FUNCTION__, efuse_addr, efuse_max_available_len);
2674 while (efuse_addr < efuse_max_available_len) {
2675 pg_header = ((pTargetPkt->offset & 0x07) << 5) | 0x0F;
2676 efuse_OneByteWrite(padapter, efuse_addr, pg_header, bPseudoTest);
2677 phy_set_mac_reg(padapter, EFUSE_TEST, BIT26, 0);
2678 efuse_OneByteRead(padapter, efuse_addr, &tmp_header, bPseudoTest);
2679 phy_set_mac_reg(padapter, EFUSE_TEST, BIT26, 1);
2681 while (tmp_header == 0xFF || pg_header != tmp_header) {
2682 if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) {
2683 RTW_INFO("%s, Repeat over limit for pg_header!!\n", __FUNCTION__);
2687 efuse_OneByteWrite(padapter, efuse_addr, pg_header, bPseudoTest);
2688 efuse_OneByteRead(padapter, efuse_addr, &tmp_header, bPseudoTest);
2691 /*to write ext_header*/
2692 if (tmp_header == pg_header) {
2694 pg_header_temp = pg_header;
2695 pg_header = ((pTargetPkt->offset & 0x78) << 1) | pTargetPkt->word_en;
2697 efuse_OneByteWrite(padapter, efuse_addr, pg_header, bPseudoTest);
2698 phy_set_mac_reg(padapter, EFUSE_TEST, BIT26, 0);
2699 efuse_OneByteRead(padapter, efuse_addr, &tmp_header, bPseudoTest);
2700 phy_set_mac_reg(padapter, EFUSE_TEST, BIT26, 1);
2702 while (tmp_header == 0xFF || pg_header != tmp_header) {
2703 if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) {
2704 RTW_INFO("%s, Repeat over limit for ext_header!!\n", __FUNCTION__);
2708 efuse_OneByteWrite(padapter, efuse_addr, pg_header, bPseudoTest);
2709 efuse_OneByteRead(padapter, efuse_addr, &tmp_header, bPseudoTest);
2712 if ((tmp_header & 0x0F) == 0x0F) {
2713 if (repeatcnt++ > EFUSE_REPEAT_THRESHOLD_) {
2714 RTW_INFO("Repeat over limit for word_en!!\n");
2720 } else if (pg_header != tmp_header) {
2721 PGPKT_STRUCT fixPkt;
2722 RTW_ERR("Error, efuse_PgPacketWrite2ByteHeader(), offset PG fail, need to cover the existed data!!\n");
2723 RTW_ERR("Error condition for offset PG fail, need to cover the existed data\n");
2724 fixPkt.offset = ((pg_header_temp & 0xE0) >> 5) | ((tmp_header & 0xF0) >> 1);
2725 fixPkt.word_en = tmp_header & 0x0F;
2726 fixPkt.word_cnts = Efuse_CalculateWordCnts(fixPkt.word_en);
2727 if (!hal_EfuseFixHeaderProcess(padapter, efuseType, &fixPkt, &efuse_addr, bPseudoTest))
2731 } else if ((tmp_header & 0x1F) == 0x0F) {/*wrong extended header*/
2737 *pAddr = efuse_addr;
2743 hal_EfusePgPacketWriteHeader(
2747 PPGPKT_STRUCT pTargetPkt,
2752 if (pTargetPkt->offset >= EFUSE_MAX_SECTION_BASE)
2753 bRet = hal_EfusePgPacketWrite2ByteHeader(padapter, efuseType, pAddr, pTargetPkt, bPseudoTest);
2755 bRet = hal_EfusePgPacketWrite1ByteHeader(padapter, efuseType, pAddr, pTargetPkt, bPseudoTest);
2761 hal_EfusePgPacketWriteData(
2765 PPGPKT_STRUCT pTargetPkt,
2770 u8 PgWriteSuccess = 0;
2773 efuse_addr = *pAddr;
2774 badworden = Efuse_WordEnableDataWrite(pAdapter, efuse_addr + 1, pTargetPkt->word_en, pTargetPkt->data, bPseudoTest);
2775 if (badworden == 0x0F) {
2776 RTW_INFO("%s: OK!!\n", __FUNCTION__);
2778 } else { /* Reorganize other pg packet */
2779 RTW_ERR ("Error, efuse_PgPacketWriteData(), wirte data fail!!\n");
2780 RTW_ERR ("efuse_PgPacketWriteData Fail!!\n");
2781 PgWriteSuccess = Efuse_PgPacketWrite(pAdapter, pTargetPkt->offset, badworden, pTargetPkt->data, bPseudoTest);
2782 if (!PgWriteSuccess)
2792 Hal_EfusePgPacketWrite(
2799 PGPKT_STRUCT targetPkt;
2801 u8 efuseType = EFUSE_WIFI;
2803 if (!hal_EfusePgCheckAvailableAddr(padapter, efuseType, bPseudoTest))
2806 hal_EfuseConstructPGPkt(offset, word_en, pData, &targetPkt);
2808 if (!hal_EfusePartialWriteCheck(padapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2811 if (!hal_EfusePgPacketWriteHeader(padapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2814 if (!hal_EfusePgPacketWriteData(padapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2821 Hal_EfusePgPacketWrite_BT(
2828 PGPKT_STRUCT targetPkt;
2830 u8 efuseType = EFUSE_BT;
2832 if (!hal_EfusePgCheckAvailableAddr(pAdapter, efuseType, bPseudoTest))
2835 hal_EfuseConstructPGPkt(offset, word_en, pData, &targetPkt);
2837 if (!hal_EfusePartialWriteCheck(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2840 if (!hal_EfusePgPacketWriteHeader(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2843 if (!hal_EfusePgPacketWriteData(pAdapter, efuseType, &startAddr, &targetPkt, bPseudoTest))
2850 static void read_chip_version_8703b(PADAPTER padapter)
2853 HAL_DATA_TYPE *pHalData;
2854 pHalData = GET_HAL_DATA(padapter);
2856 value32 = rtw_read32(padapter, REG_SYS_CFG);
2857 pHalData->version_id.ICType = CHIP_8703B;
2858 pHalData->version_id.ChipType = ((value32 & RTL_ID) ? TEST_CHIP : NORMAL_CHIP);
2859 pHalData->version_id.RFType = RF_TYPE_1T1R;
2860 pHalData->version_id.VendorType = ((value32 & VENDOR_ID) ? CHIP_VENDOR_UMC : CHIP_VENDOR_TSMC);
2861 pHalData->version_id.CUTVersion = (value32 & CHIP_VER_RTL_MASK) >> CHIP_VER_RTL_SHIFT; /* IC version (CUT) */
2863 /* For regulator mode. by tynli. 2011.01.14 */
2864 pHalData->RegulatorMode = ((value32 & SPS_SEL) ? RT_LDO_REGULATOR : RT_SWITCHING_REGULATOR);
2866 value32 = rtw_read32(padapter, REG_GPIO_OUTSTS);
2867 pHalData->version_id.ROMVer = ((value32 & RF_RL_ID) >> 20); /* ROM code version. */
2869 /* For multi-function consideration. Added by Roger, 2010.10.06. */
2870 pHalData->MultiFunc = RT_MULTI_FUNC_NONE;
2871 value32 = rtw_read32(padapter, REG_MULTI_FUNC_CTRL);
2872 pHalData->MultiFunc |= ((value32 & WL_FUNC_EN) ? RT_MULTI_FUNC_WIFI : 0);
2873 pHalData->MultiFunc |= ((value32 & BT_FUNC_EN) ? RT_MULTI_FUNC_BT : 0);
2874 pHalData->MultiFunc |= ((value32 & GPS_FUNC_EN) ? RT_MULTI_FUNC_GPS : 0);
2875 pHalData->PolarityCtl = ((value32 & WL_HWPDN_SL) ? RT_POLARITY_HIGH_ACT : RT_POLARITY_LOW_ACT);
2877 rtw_hal_config_rftype(padapter);
2880 /* mark for chage to use efuse */
2881 if (IS_B_CUT(pHalData->version_id) || IS_C_CUT(pHalData->version_id)) {
2882 RTW_INFO(" IS_B/C_CUT SWR up 1 level !!!!!!!!!!!!!!!!!\n");
2883 phy_set_mac_reg(padapter, 0x14, BIT23 | BIT22 | BIT21 | BIT20, 0x5); /* MAC reg 0x14[23:20] = 4b'0101 (SWR 1.220V) */
2884 } else if (IS_D_CUT(pHalData->version_id))
2885 RTW_INFO(" IS_D_CUT SKIP SWR !!!!!!!!!!!!!!!!!\n");
2889 dump_chip_info(pHalData->version_id);
2895 void rtl8703b_InitBeaconParameters(PADAPTER padapter)
2897 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
2903 val16 = val8 | (val8 << 8); /* port0 and port1 */
2904 #ifdef CONFIG_BT_COEXIST
2905 /* Enable prot0 beacon function for PSTDMA */
2906 val16 |= EN_BCN_FUNCTION;
2908 rtw_write16(padapter, REG_BCN_CTRL, val16);
2910 /* TODO: Remove these magic number */
2911 rtw_write16(padapter, REG_TBTT_PROHIBIT, 0x6404);/* ms */
2912 /* Firmware will control REG_DRVERLYINT when power saving is enable, */
2913 /* so don't set this register on STA mode. */
2914 if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) == _FALSE)
2915 rtw_write8(padapter, REG_DRVERLYINT, DRIVER_EARLY_INT_TIME_8703B); /* 5ms */
2916 rtw_write8(padapter, REG_BCNDMATIM, BCN_DMA_ATIME_INT_TIME_8703B); /* 2ms */
2918 /* Suggested by designer timchen. Change beacon AIFS to the largest number */
2919 /* beacause test chip does not contension before sending beacon. by tynli. 2009.11.03 */
2920 rtw_write16(padapter, REG_BCNTCFG, 0x660F);
2922 pHalData->RegBcnCtrlVal = rtw_read8(padapter, REG_BCN_CTRL);
2923 pHalData->RegTxPause = rtw_read8(padapter, REG_TXPAUSE);
2924 pHalData->RegFwHwTxQCtrl = rtw_read8(padapter, REG_FWHW_TXQ_CTRL + 2);
2925 pHalData->RegReg542 = rtw_read8(padapter, REG_TBTT_PROHIBIT + 2);
2926 pHalData->RegCR_1 = rtw_read8(padapter, REG_CR + 1);
2929 void rtl8703b_InitBeaconMaxError(PADAPTER padapter, u8 InfraMode)
2931 #ifdef CONFIG_ADHOC_WORKAROUND_SETTING
2932 rtw_write8(padapter, REG_BCN_MAX_ERR, 0xFF);
2934 /* rtw_write8(Adapter, REG_BCN_MAX_ERR, (InfraMode ? 0xFF : 0x10)); */
2938 void _InitBurstPktLen_8703BS(PADAPTER Adapter)
2940 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
2942 rtw_write8(Adapter, 0x4c7, rtw_read8(Adapter, 0x4c7) | BIT(7)); /* enable single pkt ampdu */
2943 rtw_write8(Adapter, REG_RX_PKT_LIMIT_8703B, 0x18); /* for VHT packet length 11K */
2944 rtw_write8(Adapter, REG_MAX_AGGR_NUM_8703B, 0x1F);
2945 rtw_write8(Adapter, REG_PIFS_8703B, 0x00);
2946 rtw_write8(Adapter, REG_FWHW_TXQ_CTRL_8703B, rtw_read8(Adapter, REG_FWHW_TXQ_CTRL) & (~BIT(7)));
2947 if (pHalData->AMPDUBurstMode)
2948 rtw_write8(Adapter, REG_AMPDU_BURST_MODE_8703B, 0x5F);
2949 rtw_write8(Adapter, REG_AMPDU_MAX_TIME_8703B, 0x70);
2951 /* ARFB table 9 for 11ac 5G 2SS */
2952 rtw_write32(Adapter, REG_ARFR0_8703B, 0x00000010);
2953 if (IS_NORMAL_CHIP(pHalData->version_id))
2954 rtw_write32(Adapter, REG_ARFR0_8703B + 4, 0xfffff000);
2956 rtw_write32(Adapter, REG_ARFR0_8703B + 4, 0x3e0ff000);
2958 /* ARFB table 10 for 11ac 5G 1SS */
2959 rtw_write32(Adapter, REG_ARFR1_8703B, 0x00000010);
2960 rtw_write32(Adapter, REG_ARFR1_8703B + 4, 0x003ff000);
2963 void _InitLTECoex_8703BS(PADAPTER Adapter)
2965 /* LTE COEX setting */
2966 rtw_write16(Adapter, REG_LTECOEX_WRITE_DATA, 0x7700);
2967 rtw_write32(Adapter, REG_LTECOEX_CTRL, 0xc0020038);
2968 rtw_write8(Adapter, 0x73, 0x04);
2971 void _InitMacAPLLSetting_8703B(PADAPTER Adapter)
2975 RegValue = rtw_read16(Adapter, REG_AFE_CTRL_4_8703B);
2977 RegValue |= BIT(15);
2978 rtw_write16(Adapter, REG_AFE_CTRL_4_8703B, RegValue);
2982 static void _BeaconFunctionEnable(PADAPTER padapter, u8 Enable, u8 Linked)
2984 rtw_write8(padapter, REG_BCN_CTRL, DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_BCNQ_SUB);
2985 rtw_write8(padapter, REG_RD_CTRL + 1, 0x6F);
2988 static void rtl8703b_SetBeaconRelatedRegisters(PADAPTER padapter)
2992 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
2993 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
2994 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
2997 /* reset TSF, enable update TSF, correcting TSF On Beacon */
2999 /* REG_BCN_INTERVAL */
3002 /* REG_TBTT_PROHIBIT */
3003 /* REG_DRVERLYINT */
3004 /* REG_BCN_MAX_ERR */
3005 /* REG_BCNTCFG */ /* (0x510) */
3006 /* REG_DUAL_TSF_RST */
3007 /* REG_BCN_CTRL */ /* (0x550) */
3010 bcn_ctrl_reg = REG_BCN_CTRL;
3011 #ifdef CONFIG_CONCURRENT_MODE
3012 if (padapter->hw_port == HW_PORT1)
3013 bcn_ctrl_reg = REG_BCN_CTRL_1;
3019 rtw_write16(padapter, REG_ATIMWND, 2);
3022 /* Beacon interval (in unit of TU). */
3024 rtw_write16(padapter, REG_BCN_INTERVAL, pmlmeinfo->bcn_interval);
3026 rtl8703b_InitBeaconParameters(padapter);
3028 rtw_write8(padapter, REG_SLOT, 0x09);
3031 /* Reset TSF Timer to zero, added by Roger. 2008.06.24 */
3033 value32 = rtw_read32(padapter, REG_TCR);
3035 rtw_write32(padapter, REG_TCR, value32);
3038 rtw_write32(padapter, REG_TCR, value32);
3040 /* NOTE: Fix test chip's bug (about contention windows's randomness) */
3041 if (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE | WIFI_AP_STATE) == _TRUE) {
3042 rtw_write8(padapter, REG_RXTSF_OFFSET_CCK, 0x50);
3043 rtw_write8(padapter, REG_RXTSF_OFFSET_OFDM, 0x50);
3046 _BeaconFunctionEnable(padapter, _TRUE, _TRUE);
3048 ResumeTxBeacon(padapter);
3049 val8 = rtw_read8(padapter, bcn_ctrl_reg);
3050 val8 |= DIS_BCNQ_SUB;
3051 rtw_write8(padapter, bcn_ctrl_reg, val8);
3054 void hal_notch_filter_8703b(_adapter *adapter, bool enable)
3057 RTW_INFO("Enable notch filter\n");
3058 rtw_write8(adapter, rOFDM0_RxDSP + 1, rtw_read8(adapter, rOFDM0_RxDSP + 1) | BIT1);
3060 RTW_INFO("Disable notch filter\n");
3061 rtw_write8(adapter, rOFDM0_RxDSP + 1, rtw_read8(adapter, rOFDM0_RxDSP + 1) & ~BIT1);
3065 u8 rtl8703b_MRateIdxToARFRId(PADAPTER padapter, u8 rate_idx)
3068 RT_RF_TYPE_DEF_E rftype = (RT_RF_TYPE_DEF_E)GET_RF_TYPE(padapter);
3071 case RATR_INX_WIRELESS_NGB:
3072 if (rftype == RF_1T1R)
3078 case RATR_INX_WIRELESS_N:
3079 case RATR_INX_WIRELESS_NG:
3080 if (rftype == RF_1T1R)
3086 case RATR_INX_WIRELESS_NB:
3087 if (rftype == RF_1T1R)
3093 case RATR_INX_WIRELESS_GB:
3097 case RATR_INX_WIRELESS_G:
3101 case RATR_INX_WIRELESS_B:
3105 case RATR_INX_WIRELESS_MC:
3106 if (padapter->mlmeextpriv.cur_wireless_mode & WIRELESS_11BG_24N)
3111 case RATR_INX_WIRELESS_AC_N:
3112 if (rftype == RF_1T1R) /* || padapter->MgntInfo.VHTHighestOperaRate <= MGN_VHT1SS_MCS9) */
3126 void update_ra_mask_8703b(_adapter *padapter, struct sta_info *psta, struct macid_cfg *h2c_macid_cfg)
3128 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
3130 if (pHalData->fw_ractrl == _TRUE)
3131 rtl8703b_set_FwMacIdConfig_cmd(padapter,
3132 h2c_macid_cfg->mac_id,
3133 h2c_macid_cfg->rate_id,
3134 h2c_macid_cfg->bandwidth,
3135 h2c_macid_cfg->short_gi,
3136 h2c_macid_cfg->ra_mask,
3137 h2c_macid_cfg->ignore_bw);
3141 * Description: In normal chip, we should send some packet to Hw which will be used by Fw
3142 * in FW LPS mode. The function is to fill the Tx descriptor of this packets, then
3143 * Fw can tell Hw to send these packet derectly.
3144 * Added by tynli. 2009.10.15.
3146 * type1:pspoll, type2:null */
3147 void rtl8703b_fill_fake_txdesc(
3155 /* Clear all status */
3156 _rtw_memset(pDesc, 0, TXDESC_SIZE);
3158 SET_TX_DESC_FIRST_SEG_8703B(pDesc, 1); /* bFirstSeg; */
3159 SET_TX_DESC_LAST_SEG_8703B(pDesc, 1); /* bLastSeg; */
3161 SET_TX_DESC_OFFSET_8703B(pDesc, 0x28); /* Offset = 32 */
3163 SET_TX_DESC_PKT_SIZE_8703B(pDesc, BufferLen); /* Buffer size + command header */
3164 SET_TX_DESC_QUEUE_SEL_8703B(pDesc, QSLT_MGNT); /* Fixed queue of Mgnt queue */
3166 /* Set NAVUSEHDR to prevent Ps-poll AId filed to be changed to error vlaue by Hw. */
3167 if (_TRUE == IsPsPoll)
3168 SET_TX_DESC_NAV_USE_HDR_8703B(pDesc, 1);
3170 SET_TX_DESC_HWSEQ_EN_8703B(pDesc, 1); /* Hw set sequence number */
3171 SET_TX_DESC_HWSEQ_SEL_8703B(pDesc, 0);
3174 if (_TRUE == IsBTQosNull)
3175 SET_TX_DESC_BT_INT_8703B(pDesc, 1);
3177 SET_TX_DESC_USE_RATE_8703B(pDesc, 1); /* use data rate which is set by Sw */
3178 SET_TX_DESC_OWN_8703B((pu1Byte)pDesc, 1);
3180 SET_TX_DESC_TX_RATE_8703B(pDesc, DESC8703B_RATE1M);
3183 /* Encrypt the data frame if under security mode excepct null data. Suggested by CCW. */
3185 if (_TRUE == bDataFrame) {
3188 EncAlg = padapter->securitypriv.dot11PrivacyAlgrthm;
3191 SET_TX_DESC_SEC_TYPE_8703B(pDesc, 0x0);
3196 SET_TX_DESC_SEC_TYPE_8703B(pDesc, 0x1);
3199 SET_TX_DESC_SEC_TYPE_8703B(pDesc, 0x2);
3202 SET_TX_DESC_SEC_TYPE_8703B(pDesc, 0x3);
3205 SET_TX_DESC_SEC_TYPE_8703B(pDesc, 0x0);
3210 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
3211 /* USB interface drop packet if the checksum of descriptor isn't correct. */
3212 /* Using this checksum can let hardware recovery from packet bulk out error (e.g. Cancel URC, Bulk out error.). */
3213 rtl8703b_cal_txdesc_chksum((struct tx_desc *)pDesc);
3217 void rtl8703b_InitAntenna_Selection(PADAPTER padapter)
3220 PHAL_DATA_TYPE pHalData;
3224 pHalData = GET_HAL_DATA(padapter);
3226 val = rtw_read8(padapter, REG_LEDCFG2);
3227 /* Let 8051 take control antenna settting */
3228 val |= BIT(7); /* DPDT_SEL_EN, 0x4C[23] */
3229 rtw_write8(padapter, REG_LEDCFG2, val);
3231 /* TODO: <20130114, Kordan> The following setting is only for DPDT and Fixed board type. */
3232 /* TODO: A better solution is configure it according EFUSE during the run-time. */
3233 phy_set_mac_reg(padapter, 0x64, BIT20, 0x0); /* 0x66[4]=0 */
3234 phy_set_mac_reg(padapter, 0x64, BIT24, 0x0); /* 0x66[8]=0 */
3235 phy_set_mac_reg(padapter, 0x40, BIT4, 0x0); /* 0x40[4]=0 */
3236 phy_set_mac_reg(padapter, 0x40, BIT3, 0x1); /* 0x40[3]=1 */
3237 phy_set_mac_reg(padapter, 0x4C, BIT24, 0x1); /* 0x4C[24:23]=10 */
3238 phy_set_mac_reg(padapter, 0x4C, BIT23, 0x0); /* 0x4C[24:23]=10 */
3239 phy_set_bb_reg(padapter, 0x944, BIT1 | BIT0, 0x3); /* 0x944[1:0]=11 */
3240 phy_set_bb_reg(padapter, 0x930, bMaskByte0, 0x77); /* 0x930[7:0]=77 */
3241 phy_set_mac_reg(padapter, 0x38, BIT11, 0x1); /* 0x38[11]=1 */
3246 void rtl8703b_CheckAntenna_Selection(PADAPTER padapter)
3249 PHAL_DATA_TYPE pHalData;
3253 pHalData = GET_HAL_DATA(padapter);
3255 val = rtw_read8(padapter, REG_LEDCFG2);
3256 /* Let 8051 take control antenna settting */
3257 if (!(val & BIT(7))) {
3258 val |= BIT(7); /* DPDT_SEL_EN, 0x4C[23] */
3259 rtw_write8(padapter, REG_LEDCFG2, val);
3263 void rtl8703b_DeinitAntenna_Selection(PADAPTER padapter)
3266 PHAL_DATA_TYPE pHalData;
3270 pHalData = GET_HAL_DATA(padapter);
3271 val = rtw_read8(padapter, REG_LEDCFG2);
3272 /* Let 8051 take control antenna settting */
3273 val &= ~BIT(7); /* DPDT_SEL_EN, clear 0x4C[23] */
3274 rtw_write8(padapter, REG_LEDCFG2, val);
3278 void init_hal_spec_8703b(_adapter *adapter)
3280 struct hal_spec_t *hal_spec = GET_HAL_SPEC(adapter);
3282 hal_spec->ic_name = "rtl8703b";
3283 hal_spec->macid_num = 16;
3284 hal_spec->sec_cam_ent_num = 16;
3285 hal_spec->sec_cap = 0;
3286 hal_spec->rfpath_num_2g = 1;
3287 hal_spec->rfpath_num_5g = 0;
3288 hal_spec->max_tx_cnt = 1;
3289 hal_spec->tx_nss_num = 1;
3290 hal_spec->rx_nss_num = 1;
3291 hal_spec->band_cap = BAND_CAP_2G;
3292 hal_spec->bw_cap = BW_CAP_20M | BW_CAP_40M;
3293 hal_spec->port_num = 2;
3294 hal_spec->proto_cap = PROTO_CAP_11B | PROTO_CAP_11G | PROTO_CAP_11N;
3296 hal_spec->wl_func = 0
3303 void rtl8703b_init_default_value(PADAPTER padapter)
3305 PHAL_DATA_TYPE pHalData;
3307 pHalData = GET_HAL_DATA(padapter);
3309 padapter->registrypriv.wireless_mode = WIRELESS_11BG_24N;
3311 /* init default value */
3312 pHalData->fw_ractrl = _FALSE;
3313 if (!adapter_to_pwrctl(padapter)->bkeepfwalive)
3314 pHalData->LastHMEBoxNum = 0;
3316 /* init phydm default value */
3317 pHalData->bIQKInitialized = _FALSE;
3318 pHalData->odmpriv.rf_calibrate_info.tm_trigger = 0;/* for IQK */
3319 pHalData->odmpriv.rf_calibrate_info.thermal_value_hp_index = 0;
3320 for (i = 0; i < HP_THERMAL_NUM; i++)
3321 pHalData->odmpriv.rf_calibrate_info.thermal_value_hp[i] = 0;
3323 /* init Efuse variables */
3324 pHalData->EfuseUsedBytes = 0;
3325 pHalData->EfuseUsedPercentage = 0;
3326 #ifdef HAL_EFUSE_MEMORY
3327 pHalData->EfuseHal.fakeEfuseBank = 0;
3328 pHalData->EfuseHal.fakeEfuseUsedBytes = 0;
3329 _rtw_memset(pHalData->EfuseHal.fakeEfuseContent, 0xFF, EFUSE_MAX_HW_SIZE);
3330 _rtw_memset(pHalData->EfuseHal.fakeEfuseInitMap, 0xFF, EFUSE_MAX_MAP_LEN);
3331 _rtw_memset(pHalData->EfuseHal.fakeEfuseModifiedMap, 0xFF, EFUSE_MAX_MAP_LEN);
3332 pHalData->EfuseHal.BTEfuseUsedBytes = 0;
3333 pHalData->EfuseHal.BTEfuseUsedPercentage = 0;
3334 _rtw_memset(pHalData->EfuseHal.BTEfuseContent, 0xFF, EFUSE_MAX_BT_BANK * EFUSE_MAX_HW_SIZE);
3335 _rtw_memset(pHalData->EfuseHal.BTEfuseInitMap, 0xFF, EFUSE_BT_MAX_MAP_LEN);
3336 _rtw_memset(pHalData->EfuseHal.BTEfuseModifiedMap, 0xFF, EFUSE_BT_MAX_MAP_LEN);
3337 pHalData->EfuseHal.fakeBTEfuseUsedBytes = 0;
3338 _rtw_memset(pHalData->EfuseHal.fakeBTEfuseContent, 0xFF, EFUSE_MAX_BT_BANK * EFUSE_MAX_HW_SIZE);
3339 _rtw_memset(pHalData->EfuseHal.fakeBTEfuseInitMap, 0xFF, EFUSE_BT_MAX_MAP_LEN);
3340 _rtw_memset(pHalData->EfuseHal.fakeBTEfuseModifiedMap, 0xFF, EFUSE_BT_MAX_MAP_LEN);
3344 u8 GetEEPROMSize8703B(PADAPTER padapter)
3349 cr = rtw_read16(padapter, REG_9346CR);
3350 /* 6: EEPROM used is 93C46, 4: boot from E-Fuse. */
3351 size = (cr & BOOT_FROM_EEPROM) ? 6 : 4;
3353 RTW_INFO("EEPROM type is %s\n", size == 4 ? "E-FUSE" : "93C46");
3358 /* -------------------------------------------------------------------------
3360 * LLT R/W/Init function
3362 * ------------------------------------------------------------------------- */
3363 s32 rtl8703b_InitLLTTable(PADAPTER padapter)
3365 u32 start, passing_time;
3372 val32 = rtw_read32(padapter, REG_AUTO_LLT);
3373 val32 |= BIT_AUTO_INIT_LLT;
3374 rtw_write32(padapter, REG_AUTO_LLT, val32);
3376 start = rtw_get_current_time();
3379 val32 = rtw_read32(padapter, REG_AUTO_LLT);
3380 if (!(val32 & BIT_AUTO_INIT_LLT)) {
3385 passing_time = rtw_get_passing_time_ms(start);
3386 if (passing_time > 1000) {
3387 RTW_INFO("%s: FAIL!! REG_AUTO_LLT(0x%X)=%08x\n",
3388 __FUNCTION__, REG_AUTO_LLT, val32);
3398 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
3399 void _DisableGPIO(PADAPTER padapter)
3402 /* **************************************
3403 * j. GPIO_PIN_CTRL 0x44[31:0]=0x000
3404 * k.Value = GPIO_PIN_CTRL[7:0]
3405 * l. GPIO_PIN_CTRL 0x44[31:0] = 0x00FF0000 | (value <<8); write external PIN level
3406 * m. GPIO_MUXCFG 0x42 [15:0] = 0x0780
3407 * n. LEDCFG 0x4C[15:0] = 0x8080
3408 * ************************************** */
3416 /* 1. Disable GPIO[7:0] */
3417 rtw_write16(padapter, REG_GPIO_PIN_CTRL + 2, 0x0000);
3418 value32 = rtw_read32(padapter, REG_GPIO_PIN_CTRL) & 0xFFFF00FF;
3419 u4bTmp = value32 & 0x000000FF;
3420 value32 |= ((u4bTmp << 8) | 0x00FF0000);
3421 rtw_write32(padapter, REG_GPIO_PIN_CTRL, value32);
3424 /* 2. Disable GPIO[10:8] */
3425 rtw_write8(padapter, REG_MAC_PINMUX_CFG, 0x00);
3426 value16 = rtw_read16(padapter, REG_GPIO_IO_SEL) & 0xFF0F;
3427 value8 = (u8)(value16 & 0x000F);
3428 value16 |= ((value8 << 4) | 0x0780);
3429 rtw_write16(padapter, REG_GPIO_IO_SEL, value16);
3432 /* 3. Disable LED0 & 1 */
3433 rtw_write16(padapter, REG_LEDCFG0, 0x8080);
3435 } /* end of _DisableGPIO() */
3437 void _DisableRFAFEAndResetBB8703B(PADAPTER padapter)
3440 /* *************************************
3441 * a. TXPAUSE 0x522[7:0] = 0xFF Pause MAC TX queue
3442 * b. RF path 0 offset 0x00 = 0x00 disable RF
3443 * c. APSD_CTRL 0x600[7:0] = 0x40
3444 * d. SYS_FUNC_EN 0x02[7:0] = 0x16 reset BB state machine
3445 * e. SYS_FUNC_EN 0x02[7:0] = 0x14 reset BB state machine
3446 * ************************************** */
3448 u8 eRFPath = 0, value8 = 0;
3450 rtw_write8(padapter, REG_TXPAUSE, 0xFF);
3452 phy_set_rf_reg(padapter, (RF_PATH)eRFPath, 0x0, bMaskByte0, 0x0);
3455 rtw_write8(padapter, REG_APSD_CTRL, value8);/* 0x40 */
3457 /* Set BB reset at first */
3459 value8 |= (FEN_USBD | FEN_USBA | FEN_BB_GLB_RSTn);
3460 rtw_write8(padapter, REG_SYS_FUNC_EN, value8); /* 0x16 */
3462 /* Set global reset. */
3463 value8 &= ~FEN_BB_GLB_RSTn;
3464 rtw_write8(padapter, REG_SYS_FUNC_EN, value8); /* 0x14 */
3466 /* 2010/08/12 MH We need to set BB/GLBAL reset to save power for SS mode. */
3470 void _DisableRFAFEAndResetBB(PADAPTER padapter)
3472 _DisableRFAFEAndResetBB8703B(padapter);
3475 void _ResetDigitalProcedure1_8703B(PADAPTER padapter, BOOLEAN bWithoutHWSM)
3477 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
3479 if (IS_FW_81xxC(padapter) && (pHalData->firmware_version <= 0x20)) {
3482 /* **************************** */
3483 /* f. SYS_FUNC_EN 0x03[7:0]=0x54 reset MAC register, DCORE */
3484 /* g. MCUFWDL 0x80[7:0]=0 reset MCU ready status
3485 * ***************************** */
3488 rtw_write8(padapter, REG_SYS_FUNC_EN + 1, 0x54);
3489 rtw_write8(padapter, REG_MCUFWDL, 0);
3492 /* **************************** */
3493 /* f. MCUFWDL 0x80[7:0]=0 reset MCU ready status */
3494 /* g. SYS_FUNC_EN 0x02[10]= 0 reset MCU register, (8051 reset) */
3495 /* h. SYS_FUNC_EN 0x02[15-12]= 5 reset MAC register, DCORE */
3496 /* i. SYS_FUNC_EN 0x02[10]= 1 enable MCU register, (8051 enable) */
3497 /* ***************************** */
3500 rtw_write8(padapter, REG_MCUFWDL, 0);
3502 valu16 = rtw_read16(padapter, REG_SYS_FUNC_EN);
3503 rtw_write16(padapter, REG_SYS_FUNC_EN, (valu16 & (~FEN_CPUEN)));/* reset MCU ,8051 */
3505 valu16 = rtw_read16(padapter, REG_SYS_FUNC_EN) & 0x0FFF;
3506 rtw_write16(padapter, REG_SYS_FUNC_EN, (valu16 | (FEN_HWPDN | FEN_ELDR))); /* reset MAC */
3508 valu16 = rtw_read16(padapter, REG_SYS_FUNC_EN);
3509 rtw_write16(padapter, REG_SYS_FUNC_EN, (valu16 | FEN_CPUEN));/* enable MCU ,8051 */
3514 /* 2010/08/12 MH For USB SS, we can not stop 8051 when we are trying to */
3515 /* enter IPS/HW&SW radio off. For S3/S4/S5/Disable, we can stop 8051 because */
3516 /* we will init FW when power on again. */
3517 /* if(!pDevice->RegUsbSS) */
3518 { /* If we want to SS mode, we can not reset 8051. */
3519 if (rtw_read8(padapter, REG_MCUFWDL) & BIT1) {
3520 /* IF fw in RAM code, do reset */
3523 if (padapter->bFWReady) {
3524 /* 2010/08/25 MH Accordign to RD alfred's suggestion, we need to disable other */
3525 /* HRCV INT to influence 8051 reset. */
3526 rtw_write8(padapter, REG_FWIMR, 0x20);
3527 /* 2011/02/15 MH According to Alex's suggestion, close mask to prevent incorrect FW write operation. */
3528 rtw_write8(padapter, REG_FTIMR, 0x00);
3529 rtw_write8(padapter, REG_FSIMR, 0x00);
3531 rtw_write8(padapter, REG_HMETFR + 3, 0x20); /* 8051 reset by self */
3533 while ((retry_cnts++ < 100) && (FEN_CPUEN & rtw_read16(padapter, REG_SYS_FUNC_EN))) {
3534 rtw_udelay_os(50);/* us */
3535 /* 2010/08/25 For test only We keep on reset 5051 to prevent fail. */
3536 /* rtw_write8(padapter, REG_HMETFR+3, 0x20); */ /* 8051 reset by self */
3538 /* RT_ASSERT((retry_cnts < 100), ("8051 reset failed!\n")); */
3540 if (retry_cnts >= 100) {
3541 /* if 8051 reset fail we trigger GPIO 0 for LA */
3542 /* rtw_write32( padapter, */
3543 /* REG_GPIO_PIN_CTRL, */
3545 /* 2010/08/31 MH According to Filen's info, if 8051 reset fail, reset MAC directly. */
3546 rtw_write8(padapter, REG_SYS_FUNC_EN + 1, 0x50); /* Reset MAC and Enable 8051 */
3553 rtw_write8(padapter, REG_SYS_FUNC_EN + 1, 0x54); /* Reset MAC and Enable 8051 */
3554 rtw_write8(padapter, REG_MCUFWDL, 0);
3558 /* if(pDevice->RegUsbSS) */
3559 /* bWithoutHWSM = TRUE; */ /* Sugest by Filen and Issau. */
3562 /* HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); */
3564 /* **************************** */
3565 /* Without HW auto state machine */
3566 /* g. SYS_CLKR 0x08[15:0] = 0x30A3 disable MAC clock */
3567 /* h. AFE_PLL_CTRL 0x28[7:0] = 0x80 disable AFE PLL */
3568 /* i. AFE_XTAL_CTRL 0x24[15:0] = 0x880F gated AFE DIG_CLOCK */
3569 /* j. SYS_ISO_CTRL 0x00[7:0] = 0xF9 isolated digital to PON */
3570 /* ***************************** */
3572 /* rtw_write16(padapter, REG_SYS_CLKR, 0x30A3); */
3573 /* if(!pDevice->RegUsbSS) */
3574 /* 2011/01/26 MH SD4 Scott suggest to fix UNC-B cut bug. */
3575 rtw_write16(padapter, REG_SYS_CLKR, 0x70A3); /* modify to 0x70A3 by Scott. */
3576 rtw_write8(padapter, REG_AFE_PLL_CTRL, 0x80);
3577 rtw_write16(padapter, REG_AFE_XTAL_CTRL, 0x880F);
3578 /* if(!pDevice->RegUsbSS) */
3579 rtw_write8(padapter, REG_SYS_ISO_CTRL, 0xF9);
3581 /* Disable all RF/BB power */
3582 rtw_write8(padapter, REG_RF_CTRL, 0x00);
3587 void _ResetDigitalProcedure1(PADAPTER padapter, BOOLEAN bWithoutHWSM)
3589 _ResetDigitalProcedure1_8703B(padapter, bWithoutHWSM);
3592 void _ResetDigitalProcedure2(PADAPTER padapter)
3594 /* HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter); */
3596 /* ****************************
3597 * k. SYS_FUNC_EN 0x03[7:0] = 0x44 disable ELDR runction
3598 * l. SYS_CLKR 0x08[15:0] = 0x3083 disable ELDR clock
3599 * m. SYS_ISO_CTRL 0x01[7:0] = 0x83 isolated ELDR to PON
3600 * ***************************** */
3602 /* rtw_write8(padapter, REG_SYS_FUNC_EN+1, 0x44); */ /* marked by Scott. */
3603 /* 2011/01/26 MH SD4 Scott suggest to fix UNC-B cut bug. */
3604 rtw_write16(padapter, REG_SYS_CLKR, 0x70a3); /* modify to 0x70a3 by Scott. */
3605 rtw_write8(padapter, REG_SYS_ISO_CTRL + 1, 0x82); /* modify to 0x82 by Scott. */
3608 void _DisableAnalog(PADAPTER padapter, BOOLEAN bWithoutHWSM)
3610 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
3617 /* **************************** */
3618 /* n. LDOA15_CTRL 0x20[7:0] = 0x04 disable A15 power */
3619 /* o. LDOV12D_CTRL 0x21[7:0] = 0x54 disable digital core power */
3620 /* r. When driver call disable, the ASIC will turn off remaining clock automatically */
3621 /* ***************************** */
3624 rtw_write8(padapter, REG_LDOA15_CTRL, 0x04);
3625 /* rtw_write8(padapter, REG_LDOV12D_CTRL, 0x54); */
3627 value8 = rtw_read8(padapter, REG_LDOV12D_CTRL);
3628 value8 &= (~LDV12_EN);
3629 rtw_write8(padapter, REG_LDOV12D_CTRL, value8);
3633 /* **************************** */
3634 /* h. SPS0_CTRL 0x11[7:0] = 0x23 enter PFM mode */
3635 /* i. APS_FSMCO 0x04[15:0] = 0x4802 set USB suspend */
3636 /* ***************************** */
3640 rtw_write8(padapter, REG_SPS0_CTRL, value8);
3643 /* value16 |= (APDM_HOST | AFSM_HSUS |PFM_ALDN); */
3644 /* 2010/08/31 According to Filen description, we need to use HW to shut down 8051 automatically. */
3645 /* Becasue suspend operatione need the asistance of 8051 to wait for 3ms. */
3646 value16 |= (APDM_HOST | AFSM_HSUS | PFM_ALDN);
3648 value16 |= (APDM_HOST | AFSM_HSUS | PFM_ALDN);
3650 rtw_write16(padapter, REG_APS_FSMCO, value16);/* 0x4802 */
3652 rtw_write8(padapter, REG_RSV_CTRL, 0x0e);
3655 /* tynli_test for suspend mode. */
3657 rtw_write8(padapter, 0xfe10, 0x19);
3662 /* HW Auto state machine */
3663 s32 CardDisableHWSM(PADAPTER padapter, u8 resetMCU)
3665 int rtStatus = _SUCCESS;
3668 if (RTW_CANNOT_RUN(padapter))
3671 /* ==== RF Off Sequence ==== */
3672 _DisableRFAFEAndResetBB(padapter);
3674 /* ==== Reset digital sequence ====== */
3675 _ResetDigitalProcedure1(padapter, _FALSE);
3677 /* ==== Pull GPIO PIN to balance level and LED control ====== */
3678 _DisableGPIO(padapter);
3680 /* ==== Disable analog sequence === */
3681 _DisableAnalog(padapter, _FALSE);
3687 /* without HW Auto state machine */
3688 s32 CardDisableWithoutHWSM(PADAPTER padapter)
3690 s32 rtStatus = _SUCCESS;
3693 if (RTW_CANNOT_RUN(padapter))
3697 /* ==== RF Off Sequence ==== */
3698 _DisableRFAFEAndResetBB(padapter);
3700 /* ==== Reset digital sequence ====== */
3701 _ResetDigitalProcedure1(padapter, _TRUE);
3703 /* ==== Pull GPIO PIN to balance level and LED control ====== */
3704 _DisableGPIO(padapter);
3706 /* ==== Reset digital sequence ====== */
3707 _ResetDigitalProcedure2(padapter);
3709 /* ==== Disable analog sequence === */
3710 _DisableAnalog(padapter, _TRUE);
3714 #endif /* CONFIG_USB_HCI || CONFIG_SDIO_HCI || CONFIG_GSPI_HCI */
3722 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
3726 if (_FALSE == pHalData->bautoload_fail_flag) {
3728 * if (IS_BOOT_FROM_EEPROM(padapter)) */
3729 if (_TRUE == pHalData->EepromOrEfuse) {
3730 /* Read all Content from EEPROM or EFUSE. */
3731 for (i = 0; i < HWSET_MAX_SIZE_8703B; i += 2) {
3732 /* value16 = EF2Byte(ReadEEprom(pAdapter, (u2Byte) (i>>1)));
3733 * *((u16*)(&PROMContent[i])) = value16; */
3736 /* Read EFUSE real map to shadow. */
3737 EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, _FALSE);
3738 _rtw_memcpy((void *)PROMContent, (void *)pHalData->efuse_eeprom_data, HWSET_MAX_SIZE_8703B);
3742 /* pHalData->AutoloadFailFlag = _TRUE; */
3743 /* update to default value 0xFF */
3744 if (_FALSE == pHalData->EepromOrEfuse)
3745 EFUSE_ShadowMapUpdate(padapter, EFUSE_WIFI, _FALSE);
3746 _rtw_memcpy((void *)PROMContent, (void *)pHalData->efuse_eeprom_data, HWSET_MAX_SIZE_8703B);
3749 #ifdef CONFIG_EFUSE_CONFIG_FILE
3750 if (check_phy_efuse_tx_power_info_valid(padapter) == _FALSE) {
3751 if (Hal_readPGDataFromConfigFile(padapter) != _SUCCESS)
3752 RTW_ERR("invalid phy efuse and read from file fail, will use driver default!!\n");
3758 Hal_EfuseParseIDCode(
3759 IN PADAPTER padapter,
3763 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
3767 /* Checl 0x8129 again for making sure autoload status!! */
3768 EEPROMId = le16_to_cpu(*((u16 *)hwinfo));
3769 if (EEPROMId != RTL_EEPROM_ID) {
3770 RTW_INFO("EEPROM ID(%#x) is invalid!!\n", EEPROMId);
3771 pHalData->bautoload_fail_flag = _TRUE;
3773 pHalData->bautoload_fail_flag = _FALSE;
3785 case EETYPE_TX_PWR: {
3787 pIn = (u8 *)pInValue;
3788 pOut = (u8 *)pOutValue;
3792 *pOut = EEPROM_Default_TxPowerLevel;
3802 Hal_EfuseParseTxPowerInfo_8703B(
3803 IN PADAPTER padapter,
3805 IN BOOLEAN AutoLoadFail
3808 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
3809 TxPowerInfo24G pwrInfo24G;
3811 hal_load_txpwr_info(padapter, &pwrInfo24G, NULL, PROMContent);
3813 /* 2010/10/19 MH Add Regulator recognize for CU. */
3814 if (!AutoLoadFail) {
3815 pHalData->EEPROMRegulatory = (PROMContent[EEPROM_RF_BOARD_OPTION_8703B] & 0x7); /* bit0~2 */
3816 if (PROMContent[EEPROM_RF_BOARD_OPTION_8703B] == 0xFF)
3817 pHalData->EEPROMRegulatory = (EEPROM_DEFAULT_BOARD_OPTION & 0x7); /* bit0~2 */
3819 pHalData->EEPROMRegulatory = 0;
3823 Hal_EfuseParseBoardType_8703B(
3824 IN PADAPTER Adapter,
3826 IN BOOLEAN AutoloadFail
3831 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
3833 if (!AutoloadFail) {
3834 pHalData->InterfaceSel = (PROMContent[EEPROM_RF_BOARD_OPTION_8703B] & 0xE0) >> 5;
3835 if (PROMContent[EEPROM_RF_BOARD_OPTION_8703B] == 0xFF)
3836 pHalData->InterfaceSel = (EEPROM_DEFAULT_BOARD_OPTION & 0xE0) >> 5;
3838 pHalData->InterfaceSel = 0;
3843 Hal_EfuseParseBTCoexistInfo_8703B(
3844 IN PADAPTER padapter,
3846 IN BOOLEAN AutoLoadFail
3849 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
3853 if (!AutoLoadFail) {
3854 tmpu4 = rtw_read32(padapter, REG_MULTI_FUNC_CTRL);
3855 if (tmpu4 & BT_FUNC_EN)
3856 pHalData->EEPROMBluetoothCoexist = _TRUE;
3858 pHalData->EEPROMBluetoothCoexist = _FALSE;
3860 pHalData->EEPROMBluetoothType = BT_RTL8703B;
3862 tempval = hwinfo[EEPROM_RF_BT_SETTING_8703B];
3863 if (tempval != 0xFF) {
3864 pHalData->EEPROMBluetoothAntNum = tempval & BIT(0);
3865 #ifdef CONFIG_USB_HCI
3866 /*if(rtw_get_intf_type(padapter) == RTW_USB)*/
3867 pHalData->ant_path = ODM_RF_PATH_B; /* s0 */
3868 #else /* SDIO or PCIE */
3869 /* EFUSE_0xC3[6] == 0, S1(Main)-ODM_RF_PATH_A; */
3870 /* EFUSE_0xC3[6] == 1, S0(Aux)-ODM_RF_PATH_B */
3871 pHalData->ant_path = (tempval & BIT(6)) ? ODM_RF_PATH_B : ODM_RF_PATH_A;
3874 pHalData->EEPROMBluetoothAntNum = Ant_x1;
3875 #ifdef CONFIG_USB_HCI
3876 pHalData->ant_path = ODM_RF_PATH_B;/* s0 */
3878 pHalData->ant_path = ODM_RF_PATH_A;
3882 if (padapter->registrypriv.mp_mode == 1)
3883 pHalData->EEPROMBluetoothCoexist = _TRUE;
3885 pHalData->EEPROMBluetoothCoexist = _FALSE;
3886 pHalData->EEPROMBluetoothType = BT_RTL8703B;
3887 pHalData->EEPROMBluetoothAntNum = Ant_x1;
3888 #ifdef CONFIG_USB_HCI
3889 pHalData->ant_path = ODM_RF_PATH_B;/* s0 */
3891 pHalData->ant_path = ODM_RF_PATH_A;
3895 #ifdef CONFIG_BT_COEXIST
3896 if (padapter->registrypriv.ant_num > 0) {
3897 RTW_INFO("%s: Apply driver defined antenna number(%d) to replace origin(%d)\n",
3899 padapter->registrypriv.ant_num,
3900 pHalData->EEPROMBluetoothAntNum == Ant_x2 ? 2 : 1);
3902 switch (padapter->registrypriv.ant_num) {
3904 pHalData->EEPROMBluetoothAntNum = Ant_x1;
3907 pHalData->EEPROMBluetoothAntNum = Ant_x2;
3910 RTW_INFO("%s: Discard invalid driver defined antenna number(%d)!\n",
3911 __FUNCTION__, padapter->registrypriv.ant_num);
3915 #endif /* CONFIG_BT_COEXIST */
3917 RTW_INFO("%s: %s BT-coex, ant_num=%d\n",
3919 pHalData->EEPROMBluetoothCoexist == _TRUE ? "Enable" : "Disable",
3920 pHalData->EEPROMBluetoothAntNum == Ant_x2 ? 2 : 1);
3924 Hal_EfuseParseEEPROMVer_8703B(
3925 IN PADAPTER padapter,
3927 IN BOOLEAN AutoLoadFail
3930 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
3933 pHalData->EEPROMVersion = hwinfo[EEPROM_VERSION_8703B];
3935 pHalData->EEPROMVersion = 1;
3939 Hal_EfuseParseVoltage_8703B(
3940 IN PADAPTER pAdapter,
3942 IN BOOLEAN AutoLoadFail
3945 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
3947 /* _rtw_memcpy(pHalData->adjuseVoltageVal, &hwinfo[EEPROM_Voltage_ADDR_8703B], 1); */
3948 RTW_INFO("%s hwinfo[EEPROM_Voltage_ADDR_8703B] =%02x\n", __func__, hwinfo[EEPROM_Voltage_ADDR_8703B]);
3949 pHalData->adjuseVoltageVal = (hwinfo[EEPROM_Voltage_ADDR_8703B] & 0xf0) >> 4 ;
3950 RTW_INFO("%s pHalData->adjuseVoltageVal =%x\n", __func__, pHalData->adjuseVoltageVal);
3954 Hal_EfuseParseChnlPlan_8703B(
3955 IN PADAPTER padapter,
3957 IN BOOLEAN AutoLoadFail
3960 padapter->mlmepriv.ChannelPlan = hal_com_config_channel_plan(
3962 , hwinfo ? &hwinfo[EEPROM_COUNTRY_CODE_8703B] : NULL
3963 , hwinfo ? hwinfo[EEPROM_ChannelPlan_8703B] : 0xFF
3964 , padapter->registrypriv.alpha2
3965 , padapter->registrypriv.channel_plan
3966 , RTW_CHPLAN_WORLD_NULL
3972 Hal_EfuseParseCustomerID_8703B(
3973 IN PADAPTER padapter,
3975 IN BOOLEAN AutoLoadFail
3978 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
3981 pHalData->EEPROMCustomerID = hwinfo[EEPROM_CustomID_8703B];
3983 pHalData->EEPROMCustomerID = 0;
3987 Hal_EfuseParseAntennaDiversity_8703B(
3988 IN PADAPTER pAdapter,
3990 IN BOOLEAN AutoLoadFail
3993 #ifdef CONFIG_ANTENNA_DIVERSITY
3994 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(pAdapter);
3995 struct registry_priv *registry_par = &pAdapter->registrypriv;
3997 if (pHalData->EEPROMBluetoothAntNum == Ant_x1)
3998 pHalData->AntDivCfg = 0;
4000 if (registry_par->antdiv_cfg == 2) /* 0:OFF , 1:ON, 2:By EFUSE */
4001 pHalData->AntDivCfg = 1;
4003 pHalData->AntDivCfg = registry_par->antdiv_cfg;
4006 /* If TRxAntDivType is AUTO in advanced setting, use EFUSE value instead. */
4007 if (registry_par->antdiv_type == 0) {
4008 pHalData->TRxAntDivType = hwinfo[EEPROM_RFE_OPTION_8703B];
4009 if (pHalData->TRxAntDivType == 0xFF)
4010 pHalData->TRxAntDivType = S0S1_SW_ANTDIV;/* GetRegAntDivType(pAdapter); */
4011 else if (pHalData->TRxAntDivType == 0x10)
4012 pHalData->TRxAntDivType = S0S1_SW_ANTDIV; /* intrnal switch S0S1 */
4013 else if (pHalData->TRxAntDivType == 0x11)
4014 pHalData->TRxAntDivType = S0S1_SW_ANTDIV; /* intrnal switch S0S1 */
4016 RTW_INFO("%s: efuse[0x%x]=0x%02x is unknown type\n",
4017 __FUNCTION__, EEPROM_RFE_OPTION_8703B, pHalData->TRxAntDivType);
4019 pHalData->TRxAntDivType = registry_par->antdiv_type ;/* GetRegAntDivType(pAdapter); */
4022 RTW_INFO("%s: AntDivCfg=%d, AntDivType=%d\n",
4023 __FUNCTION__, pHalData->AntDivCfg, pHalData->TRxAntDivType);
4028 Hal_EfuseParseXtal_8703B(
4029 IN PADAPTER pAdapter,
4031 IN BOOLEAN AutoLoadFail
4034 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(pAdapter);
4036 if (!AutoLoadFail) {
4037 pHalData->crystal_cap = hwinfo[EEPROM_XTAL_8703B];
4038 if (pHalData->crystal_cap == 0xFF)
4039 pHalData->crystal_cap = EEPROM_Default_CrystalCap_8703B; /* what value should 8812 set? */
4041 pHalData->crystal_cap = EEPROM_Default_CrystalCap_8703B;
4046 Hal_EfuseParseThermalMeter_8703B(
4052 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
4055 /* ThermalMeter from EEPROM */
4057 if (_FALSE == AutoLoadFail)
4058 pHalData->eeprom_thermal_meter = PROMContent[EEPROM_THERMAL_METER_8703B];
4060 pHalData->eeprom_thermal_meter = EEPROM_Default_ThermalMeter_8703B;
4062 if ((pHalData->eeprom_thermal_meter == 0xff) || (_TRUE == AutoLoadFail)) {
4063 pHalData->odmpriv.rf_calibrate_info.is_apk_thermal_meter_ignore = _TRUE;
4064 pHalData->eeprom_thermal_meter = EEPROM_Default_ThermalMeter_8703B;
4070 void Hal_ReadRFGainOffset(
4071 IN PADAPTER Adapter,
4073 IN BOOLEAN AutoloadFail)
4075 #ifdef CONFIG_RF_POWER_TRIM
4077 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
4078 struct kfree_data_t *kfree_data = &pHalData->kfree_data;
4079 u8 pg_pwrtrim = 0xFF, pg_therm = 0xFF;
4081 RTW_INFO("%s, Pwr Trim Enable config:%d\n", __func__, Adapter->registrypriv.RegPwrTrimEnable);
4083 if ((Adapter->registrypriv.RegPwrTrimEnable == 1) || !AutoloadFail) {
4084 efuse_OneByteRead(Adapter, PPG_BB_GAIN_2G_TXA_OFFSET_8703B, &pg_pwrtrim, _FALSE);
4085 efuse_OneByteRead(Adapter, PPG_THERMAL_OFFSET_8703B, &pg_therm, _FALSE);
4087 kfree_data->bb_gain[BB_GAIN_2G][RF_PATH_A]
4088 = KFREE_BB_GAIN_2G_TX_OFFSET(pg_pwrtrim & PPG_BB_GAIN_2G_TX_OFFSET_MASK);
4090 = KFREE_THERMAL_OFFSET(pg_therm & PPG_THERMAL_OFFSET_MASK);
4092 if (GET_PG_KFREE_ON_8703B(PROMContent) && PROMContent[0xc1] != 0xff)
4093 kfree_data->flag |= KFREE_FLAG_ON;
4094 if (GET_PG_KFREE_THERMAL_K_ON_8703B(PROMContent) && PROMContent[0xc8] != 0xff)
4095 kfree_data->flag |= KFREE_FLAG_THERMAL_K_ON;
4098 if (Adapter->registrypriv.RegPwrTrimEnable == 1) {
4099 kfree_data->flag |= KFREE_FLAG_ON;
4100 kfree_data->flag |= KFREE_FLAG_THERMAL_K_ON;
4103 if (kfree_data->flag & KFREE_FLAG_THERMAL_K_ON)
4104 pHalData->eeprom_thermal_meter += kfree_data->thermal;
4106 RTW_INFO("kfree flag:%u\n", kfree_data->flag);
4107 if (Adapter->registrypriv.RegPwrTrimEnable == 1 || kfree_data->flag & KFREE_FLAG_ON)
4108 RTW_INFO("bb_gain:%d\n", kfree_data->bb_gain[BB_GAIN_2G][RF_PATH_A]);
4109 if (Adapter->registrypriv.RegPwrTrimEnable == 1 || kfree_data->flag & KFREE_FLAG_THERMAL_K_ON)
4110 RTW_INFO("thermal:%d\n", kfree_data->thermal);
4112 #endif /*CONFIG_RF_POWER_TRIM */
4119 IN PADAPTER Adapter,
4120 IN struct pkt_attrib *pattrib
4123 u8 BWSettingOfDesc = 0;
4124 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
4126 /* RTW_INFO("BWMapping pHalData->current_channel_bw %d, pattrib->bwmode %d\n",pHalData->current_channel_bw,pattrib->bwmode); */
4128 if (pHalData->current_channel_bw == CHANNEL_WIDTH_80) {
4129 if (pattrib->bwmode == CHANNEL_WIDTH_80)
4130 BWSettingOfDesc = 2;
4131 else if (pattrib->bwmode == CHANNEL_WIDTH_40)
4132 BWSettingOfDesc = 1;
4134 BWSettingOfDesc = 0;
4135 } else if (pHalData->current_channel_bw == CHANNEL_WIDTH_40) {
4136 if ((pattrib->bwmode == CHANNEL_WIDTH_40) || (pattrib->bwmode == CHANNEL_WIDTH_80))
4137 BWSettingOfDesc = 1;
4139 BWSettingOfDesc = 0;
4141 BWSettingOfDesc = 0;
4143 /* if(pTcb->bBTTxPacket) */
4144 /* BWSettingOfDesc = 0; */
4146 return BWSettingOfDesc;
4149 u8 SCMapping_8703B(PADAPTER Adapter, struct pkt_attrib *pattrib)
4151 u8 SCSettingOfDesc = 0;
4152 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
4154 /* RTW_INFO("SCMapping: pHalData->current_channel_bw %d, pHalData->nCur80MhzPrimeSC %d, pHalData->nCur40MhzPrimeSC %d\n",pHalData->current_channel_bw,pHalData->nCur80MhzPrimeSC,pHalData->nCur40MhzPrimeSC); */
4156 if (pHalData->current_channel_bw == CHANNEL_WIDTH_80) {
4157 if (pattrib->bwmode == CHANNEL_WIDTH_80)
4158 SCSettingOfDesc = VHT_DATA_SC_DONOT_CARE;
4159 else if (pattrib->bwmode == CHANNEL_WIDTH_40) {
4160 if (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER)
4161 SCSettingOfDesc = VHT_DATA_SC_40_LOWER_OF_80MHZ;
4162 else if (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER)
4163 SCSettingOfDesc = VHT_DATA_SC_40_UPPER_OF_80MHZ;
4165 RTW_INFO("SCMapping: DONOT CARE Mode Setting\n");
4167 if ((pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) && (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER))
4168 SCSettingOfDesc = VHT_DATA_SC_20_LOWEST_OF_80MHZ;
4169 else if ((pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER) && (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER))
4170 SCSettingOfDesc = VHT_DATA_SC_20_LOWER_OF_80MHZ;
4171 else if ((pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) && (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER))
4172 SCSettingOfDesc = VHT_DATA_SC_20_UPPER_OF_80MHZ;
4173 else if ((pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER) && (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER))
4174 SCSettingOfDesc = VHT_DATA_SC_20_UPPERST_OF_80MHZ;
4176 RTW_INFO("SCMapping: DONOT CARE Mode Setting\n");
4178 } else if (pHalData->current_channel_bw == CHANNEL_WIDTH_40) {
4179 /* RTW_INFO("SCMapping: HT Case: pHalData->current_channel_bw %d, pHalData->nCur40MhzPrimeSC %d\n",pHalData->current_channel_bw,pHalData->nCur40MhzPrimeSC); */
4181 if (pattrib->bwmode == CHANNEL_WIDTH_40)
4182 SCSettingOfDesc = VHT_DATA_SC_DONOT_CARE;
4183 else if (pattrib->bwmode == CHANNEL_WIDTH_20) {
4184 if (pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER)
4185 SCSettingOfDesc = VHT_DATA_SC_20_UPPER_OF_80MHZ;
4186 else if (pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER)
4187 SCSettingOfDesc = VHT_DATA_SC_20_LOWER_OF_80MHZ;
4189 SCSettingOfDesc = VHT_DATA_SC_DONOT_CARE;
4192 SCSettingOfDesc = VHT_DATA_SC_DONOT_CARE;
4194 return SCSettingOfDesc;
4197 #if defined(CONFIG_CONCURRENT_MODE)
4198 void fill_txdesc_force_bmc_camid(struct pkt_attrib *pattrib, u8 *ptxdesc)
4200 if ((pattrib->encrypt > 0) && (!pattrib->bswenc)
4201 && (pattrib->bmc_camid != INVALID_SEC_MAC_CAM_ID)) {
4203 SET_TX_DESC_EN_DESC_ID_8703B(ptxdesc, 1);
4204 SET_TX_DESC_MACID_8703B(ptxdesc, pattrib->bmc_camid);
4209 static u8 fill_txdesc_sectype(struct pkt_attrib *pattrib)
4212 if ((pattrib->encrypt > 0) && !pattrib->bswenc) {
4213 switch (pattrib->encrypt) {
4222 #ifdef CONFIG_WAPI_SUPPORT
4239 static void fill_txdesc_vcs_8703b(PADAPTER padapter, struct pkt_attrib *pattrib, u8 *ptxdesc)
4241 /* RTW_INFO("cvs_mode=%d\n", pattrib->vcs_mode); */
4243 if (pattrib->vcs_mode) {
4244 switch (pattrib->vcs_mode) {
4246 SET_TX_DESC_RTS_ENABLE_8703B(ptxdesc, 1);
4247 SET_TX_DESC_HW_RTS_ENABLE_8703B(ptxdesc, 1);
4251 SET_TX_DESC_CTS2SELF_8703B(ptxdesc, 1);
4259 SET_TX_DESC_RTS_RATE_8703B(ptxdesc, 8); /* RTS Rate=24M */
4260 SET_TX_DESC_RTS_RATE_FB_LIMIT_8703B(ptxdesc, 0xF);
4262 if (padapter->mlmeextpriv.mlmext_info.preamble_mode == PREAMBLE_SHORT)
4263 SET_TX_DESC_RTS_SHORT_8703B(ptxdesc, 1);
4267 SET_TX_DESC_RTS_SC_8703B(ptxdesc, SCMapping_8703B(padapter, pattrib));
4271 static void fill_txdesc_phy_8703b(PADAPTER padapter, struct pkt_attrib *pattrib, u8 *ptxdesc)
4273 /* RTW_INFO("bwmode=%d, ch_off=%d\n", pattrib->bwmode, pattrib->ch_offset); */
4275 if (pattrib->ht_en) {
4276 SET_TX_DESC_DATA_BW_8703B(ptxdesc, BWMapping_8703B(padapter, pattrib));
4277 SET_TX_DESC_DATA_SC_8703B(ptxdesc, SCMapping_8703B(padapter, pattrib));
4281 static void rtl8703b_fill_default_txdesc(
4282 struct xmit_frame *pxmitframe,
4286 HAL_DATA_TYPE *pHalData;
4287 struct mlme_ext_priv *pmlmeext;
4288 struct mlme_ext_info *pmlmeinfo;
4289 struct pkt_attrib *pattrib;
4292 _rtw_memset(pbuf, 0, TXDESC_SIZE);
4294 padapter = pxmitframe->padapter;
4295 pHalData = GET_HAL_DATA(padapter);
4296 pmlmeext = &padapter->mlmeextpriv;
4297 pmlmeinfo = &(pmlmeext->mlmext_info);
4299 pattrib = &pxmitframe->attrib;
4300 bmcst = IS_MCAST(pattrib->ra);
4302 if (pxmitframe->frame_tag == DATA_FRAMETAG) {
4305 SET_TX_DESC_MACID_8703B(pbuf, pattrib->mac_id);
4306 SET_TX_DESC_RATE_ID_8703B(pbuf, pattrib->raid);
4307 SET_TX_DESC_QUEUE_SEL_8703B(pbuf, pattrib->qsel);
4308 SET_TX_DESC_SEQ_8703B(pbuf, pattrib->seqnum);
4310 SET_TX_DESC_SEC_TYPE_8703B(pbuf, fill_txdesc_sectype(pattrib));
4311 #if defined(CONFIG_CONCURRENT_MODE)
4313 fill_txdesc_force_bmc_camid(pattrib, pbuf);
4315 fill_txdesc_vcs_8703b(padapter, pattrib, pbuf);
4318 if (!rtw_p2p_chk_state(&padapter->wdinfo, P2P_STATE_NONE)) {
4319 if (pattrib->icmp_pkt == 1 && padapter->registrypriv.wifi_spec == 1)
4324 if ((pattrib->ether_type != 0x888e) &&
4325 (pattrib->ether_type != 0x0806) &&
4326 (pattrib->ether_type != 0x88B4) &&
4327 (pattrib->dhcp_pkt != 1) &&
4329 #ifdef CONFIG_AUTO_AP_MODE
4330 && (pattrib->pctrl != _TRUE)
4333 /* Non EAP & ARP & DHCP type data packet */
4335 if (pattrib->ampdu_en == _TRUE) {
4336 SET_TX_DESC_AGG_ENABLE_8703B(pbuf, 1);
4337 SET_TX_DESC_MAX_AGG_NUM_8703B(pbuf, 0x1F);
4338 SET_TX_DESC_AMPDU_DENSITY_8703B(pbuf, pattrib->ampdu_spacing);
4340 SET_TX_DESC_AGG_BREAK_8703B(pbuf, 1);
4342 fill_txdesc_phy_8703b(padapter, pattrib, pbuf);
4344 SET_TX_DESC_DATA_RATE_FB_LIMIT_8703B(pbuf, 0x1F);
4346 if (pHalData->fw_ractrl == _FALSE) {
4347 SET_TX_DESC_USE_RATE_8703B(pbuf, 1);
4349 if (pHalData->INIDATA_RATE[pattrib->mac_id] & BIT(7))
4350 SET_TX_DESC_DATA_SHORT_8703B(pbuf, 1);
4352 SET_TX_DESC_TX_RATE_8703B(pbuf, pHalData->INIDATA_RATE[pattrib->mac_id] & 0x7F);
4355 /* modify data rate by iwpriv */
4356 if (padapter->fix_rate != 0xFF) {
4357 SET_TX_DESC_USE_RATE_8703B(pbuf, 1);
4358 if (padapter->fix_rate & BIT(7))
4359 SET_TX_DESC_DATA_SHORT_8703B(pbuf, 1);
4360 SET_TX_DESC_TX_RATE_8703B(pbuf, padapter->fix_rate & 0x7F);
4361 if (!padapter->data_fb)
4362 SET_TX_DESC_DISABLE_FB_8703B(pbuf, 1);
4366 SET_TX_DESC_DATA_LDPC_8703B(pbuf, 1);
4369 SET_TX_DESC_DATA_STBC_8703B(pbuf, 1);
4371 #ifdef CONFIG_CMCC_TEST
4372 SET_TX_DESC_DATA_SHORT_8703B(pbuf, 1); /* use cck short premble */
4375 /* EAP data packet and ARP packet. */
4376 /* Use the 1M data rate to send the EAP/ARP packet. */
4377 /* This will maybe make the handshake smooth. */
4379 SET_TX_DESC_AGG_BREAK_8703B(pbuf, 1);
4380 SET_TX_DESC_USE_RATE_8703B(pbuf, 1);
4381 if (pmlmeinfo->preamble_mode == PREAMBLE_SHORT)
4382 SET_TX_DESC_DATA_SHORT_8703B(pbuf, 1);
4383 SET_TX_DESC_TX_RATE_8703B(pbuf, MRateToHwRate(pmlmeext->tx_rate));
4385 RTW_INFO(FUNC_ADPT_FMT ": SP Packet(0x%04X) rate=0x%x\n",
4386 FUNC_ADPT_ARG(padapter), pattrib->ether_type, MRateToHwRate(pmlmeext->tx_rate));
4389 #if defined(CONFIG_USB_TX_AGGREGATION) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
4390 SET_TX_DESC_USB_TXAGG_NUM_8703B(pbuf, pxmitframe->agg_num);
4394 #ifdef CONFIG_XMIT_ACK
4395 /* CCX-TXRPT ack for xmit mgmt frames. */
4396 if (pxmitframe->ack_report) {
4398 RTW_INFO("%s set spe_rpt\n", __func__);
4400 SET_TX_DESC_SPE_RPT_8703B(pbuf, 1);
4401 SET_TX_DESC_SW_DEFINE_8703B(pbuf, (u8)(GET_PRIMARY_ADAPTER(padapter)->xmitpriv.seq_no));
4403 #endif /* CONFIG_XMIT_ACK */
4405 } else if (pxmitframe->frame_tag == MGNT_FRAMETAG) {
4407 SET_TX_DESC_MACID_8703B(pbuf, pattrib->mac_id);
4408 SET_TX_DESC_QUEUE_SEL_8703B(pbuf, pattrib->qsel);
4409 SET_TX_DESC_RATE_ID_8703B(pbuf, pattrib->raid);
4410 SET_TX_DESC_SEQ_8703B(pbuf, pattrib->seqnum);
4411 SET_TX_DESC_USE_RATE_8703B(pbuf, 1);
4413 SET_TX_DESC_MBSSID_8703B(pbuf, pattrib->mbssid & 0xF);
4415 SET_TX_DESC_RETRY_LIMIT_ENABLE_8703B(pbuf, 1);
4416 if (pattrib->retry_ctrl == _TRUE)
4417 SET_TX_DESC_DATA_RETRY_LIMIT_8703B(pbuf, 6);
4419 SET_TX_DESC_DATA_RETRY_LIMIT_8703B(pbuf, 12);
4421 SET_TX_DESC_TX_RATE_8703B(pbuf, MRateToHwRate(pattrib->rate));
4423 #ifdef CONFIG_XMIT_ACK
4424 /* CCX-TXRPT ack for xmit mgmt frames. */
4425 if (pxmitframe->ack_report) {
4427 RTW_INFO("%s set spe_rpt\n", __FUNCTION__);
4429 SET_TX_DESC_SPE_RPT_8703B(pbuf, 1);
4430 SET_TX_DESC_SW_DEFINE_8703B(pbuf, (u8)(GET_PRIMARY_ADAPTER(padapter)->xmitpriv.seq_no));
4432 #endif /* CONFIG_XMIT_ACK */
4433 } else if (pxmitframe->frame_tag == TXAGG_FRAMETAG) {
4435 #ifdef CONFIG_MP_INCLUDED
4436 else if (pxmitframe->frame_tag == MP_FRAMETAG) {
4437 fill_txdesc_for_mp(padapter, pbuf);
4442 SET_TX_DESC_MACID_8703B(pbuf, pattrib->mac_id);
4443 SET_TX_DESC_RATE_ID_8703B(pbuf, pattrib->raid);
4444 SET_TX_DESC_QUEUE_SEL_8703B(pbuf, pattrib->qsel);
4445 SET_TX_DESC_SEQ_8703B(pbuf, pattrib->seqnum);
4446 SET_TX_DESC_USE_RATE_8703B(pbuf, 1);
4447 SET_TX_DESC_TX_RATE_8703B(pbuf, MRateToHwRate(pmlmeext->tx_rate));
4450 SET_TX_DESC_PKT_SIZE_8703B(pbuf, pattrib->last_txcmdsz);
4453 u8 pkt_offset, offset;
4456 offset = TXDESC_SIZE;
4457 #ifdef CONFIG_USB_HCI
4458 pkt_offset = pxmitframe->pkt_offset;
4459 offset += (pxmitframe->pkt_offset >> 3);
4460 #endif /* CONFIG_USB_HCI */
4462 #ifdef CONFIG_TX_EARLY_MODE
4463 if (pxmitframe->frame_tag == DATA_FRAMETAG) {
4465 offset += EARLY_MODE_INFO_SIZE;
4467 #endif /* CONFIG_TX_EARLY_MODE */
4469 SET_TX_DESC_PKT_OFFSET_8703B(pbuf, pkt_offset);
4470 SET_TX_DESC_OFFSET_8703B(pbuf, offset);
4474 SET_TX_DESC_BMC_8703B(pbuf, 1);
4476 /* 2009.11.05. tynli_test. Suggested by SD4 Filen for FW LPS. */
4477 /* (1) The sequence number of each non-Qos frame / broadcast / multicast / */
4478 /* mgnt frame should be controled by Hw because Fw will also send null data */
4479 /* which we cannot control when Fw LPS enable. */
4480 /* --> default enable non-Qos data sequense number. 2010.06.23. by tynli. */
4481 /* (2) Enable HW SEQ control for beacon packet, because we use Hw beacon. */
4482 /* (3) Use HW Qos SEQ to control the seq num of Ext port non-Qos packets. */
4483 /* 2010.06.23. Added by tynli. */
4484 if (!pattrib->qos_en)
4485 SET_TX_DESC_HWSEQ_EN_8703B(pbuf, 1);
4492 * pxmitframe xmitframe
4493 * pbuf where to fill tx desc
4495 void rtl8703b_update_txdesc(struct xmit_frame *pxmitframe, u8 *pbuf)
4497 PADAPTER padapter = pxmitframe->padapter;
4498 rtl8703b_fill_default_txdesc(pxmitframe, pbuf);
4500 #ifdef CONFIG_ANTENNA_DIVERSITY
4501 odm_set_tx_ant_by_tx_info(&GET_HAL_DATA(padapter)->odmpriv, pbuf, pxmitframe->attrib.mac_id);
4502 #endif /* CONFIG_ANTENNA_DIVERSITY */
4504 #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
4505 rtl8703b_cal_txdesc_chksum((struct tx_desc *)pbuf);
4509 #ifdef CONFIG_TSF_RESET_OFFLOAD
4510 int reset_tsf(PADAPTER Adapter, u8 reset_port)
4512 u8 reset_cnt_before = 0, reset_cnt_after = 0, loop_cnt = 0;
4513 u32 reg_reset_tsf_cnt = (HW_PORT0 == reset_port) ?
4514 REG_FW_RESET_TSF_CNT_0 : REG_FW_RESET_TSF_CNT_1;
4516 rtw_mi_buddy_scan_abort(Adapter, _FALSE); /* site survey will cause reset_tsf fail */
4517 reset_cnt_after = reset_cnt_before = rtw_read8(Adapter, reg_reset_tsf_cnt);
4518 rtl8703b_reset_tsf(Adapter, reset_port);
4520 while ((reset_cnt_after == reset_cnt_before) && (loop_cnt < 10)) {
4523 reset_cnt_after = rtw_read8(Adapter, reg_reset_tsf_cnt);
4526 return (loop_cnt >= 10) ? _FAIL : _TRUE;
4528 #endif /* CONFIG_TSF_RESET_OFFLOAD */
4530 static void hw_var_set_monitor(PADAPTER Adapter, u8 variable, u8 *val)
4532 u32 value_rcr, rcr_bits;
4533 u16 value_rxfltmap2;
4534 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(Adapter);
4535 struct mlme_priv *pmlmepriv = &(Adapter->mlmepriv);
4537 if (*((u8 *)val) == _HW_STATE_MONITOR_) {
4539 /* Receive all type */
4540 rcr_bits = RCR_AAP | RCR_APM | RCR_AM | RCR_AB | RCR_APWRMGT | RCR_ADF | RCR_ACF | RCR_AMF | RCR_APP_PHYST_RXFF;
4543 rcr_bits |= RCR_APPFCS;
4547 CRC and ICV packet will drop in recvbuf2recvframe()
4550 rcr_bits |= (RCR_ACRC32 | RCR_AICV);
4553 /* Receive all data frames */
4554 value_rxfltmap2 = 0xFFFF;
4556 value_rcr = rcr_bits;
4557 rtw_write32(Adapter, REG_RCR, value_rcr);
4559 rtw_write16(Adapter, REG_RXFLTMAP2, value_rxfltmap2);
4563 rtw_write8(padapter, REG_TXPAUSE, 0xFF);
4571 static void hw_var_set_opmode(PADAPTER padapter, u8 variable, u8 *val)
4574 u8 mode = *((u8 *)val);
4575 static u8 isMonitor = _FALSE;
4577 HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
4579 if (isMonitor == _TRUE) {
4581 rtw_write32(padapter, REG_RCR, pHalData->ReceiveConfig);
4585 if (mode == _HW_STATE_MONITOR_) {
4588 Set_MSR(padapter, _HW_STATE_NOLINK_);
4590 hw_var_set_monitor(padapter, variable, val);
4593 rtw_hal_set_hwreg(padapter, HW_VAR_MAC_ADDR, adapter_mac_addr(padapter)); /* set mac addr to mac register */
4595 #ifdef CONFIG_CONCURRENT_MODE
4596 if (padapter->hw_port == HW_PORT1) {
4597 /* disable Port1 TSF update */
4598 val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
4599 val8 |= DIS_TSF_UDT;
4600 rtw_write8(padapter, REG_BCN_CTRL_1, val8);
4602 Set_MSR(padapter, mode);
4604 RTW_INFO("#### %s()-%d hw_port(%d) mode=%d ####\n",
4605 __func__, __LINE__, padapter->hw_port, mode);
4607 if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) {
4608 if (!rtw_mi_check_status(padapter, MI_AP_MODE)) {
4609 StopTxBeacon(padapter);
4610 #ifdef CONFIG_PCI_HCI
4611 UpdateInterruptMask8703BE(padapter, 0, 0, RT_BCN_INT_MASKS, 0);
4612 #else /* !CONFIG_PCI_HCI */
4613 #ifdef CONFIG_INTERRUPT_BASED_TXBCN
4615 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
4616 rtw_write8(padapter, REG_DRVERLYINT, 0x05);/* restore early int time to 5ms */
4617 UpdateInterruptMask8703BU(padapter, _TRUE, 0, IMR_BCNDMAINT0_8703B);
4618 #endif /* CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT */
4620 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
4621 UpdateInterruptMask8703BU(padapter, _TRUE , 0, (IMR_TXBCN0ERR_8703B | IMR_TXBCN0OK_8703B));
4622 #endif /* CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR */
4624 #endif /* CONFIG_INTERRUPT_BASED_TXBCN */
4625 #endif /* !CONFIG_PCI_HCI */
4628 /* disable atim wnd and disable beacon function */
4629 rtw_write8(padapter, REG_BCN_CTRL_1, DIS_TSF_UDT | DIS_ATIM);
4630 } else if ((mode == _HW_STATE_ADHOC_) /*|| (mode == _HW_STATE_AP_)*/) {
4631 ResumeTxBeacon(padapter);
4632 rtw_write8(padapter, REG_BCN_CTRL_1, DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_BCNQ_SUB);
4633 } else if (mode == _HW_STATE_AP_) {
4634 #ifdef CONFIG_PCI_HCI
4635 UpdateInterruptMask8703BE(padapter, RT_BCN_INT_MASKS, 0, 0, 0);
4636 #else /* !CONFIG_PCI_HCI */
4637 #ifdef CONFIG_INTERRUPT_BASED_TXBCN
4639 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
4640 UpdateInterruptMask8703BU(padapter, _TRUE, IMR_BCNDMAINT0_8703B, 0);
4641 #endif /* CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT */
4643 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
4644 UpdateInterruptMask8703BU(padapter, _TRUE, (IMR_TXBCN0ERR_8703B | IMR_TXBCN0OK_8703B), 0);
4645 #endif /* CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR */
4647 #endif /* CONFIG_INTERRUPT_BASED_TXBCN */
4648 #endif /* !CONFIG_PCI_HCI */
4650 ResumeTxBeacon(padapter);
4652 rtw_write8(padapter, REG_BCN_CTRL_1, DIS_TSF_UDT | DIS_BCNQ_SUB);
4655 /* rtw_write32(padapter, REG_RCR, 0x70002a8e); */ /* CBSSID_DATA must set to 0 */
4656 /* rtw_write32(padapter, REG_RCR, 0x7000228e); */ /* CBSSID_DATA must set to 0 */
4657 if (padapter->registrypriv.wifi_spec)
4658 /* for 11n Logo 4.2.31/4.2.32, disable BSSID BCN check for AP mode */
4659 rtw_write32(padapter, REG_RCR, (0x7000208e & ~(RCR_CBSSID_BCN)));
4661 rtw_write32(padapter, REG_RCR, 0x7000208e);/* CBSSID_DATA must set to 0,reject ICV_ERR packet */
4662 /* enable to rx data frame */
4663 rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
4664 /* enable to rx ps-poll */
4665 rtw_write16(padapter, REG_RXFLTMAP1, 0x0400);
4667 /* Beacon Control related register for first time */
4668 rtw_write8(padapter, REG_BCNDMATIM, 0x02); /* 2ms */
4670 /* rtw_write8(padapter, REG_BCN_MAX_ERR, 0xFF); */
4671 rtw_write8(padapter, REG_ATIMWND_1, 0x0a); /* 10ms for port1 */
4672 rtw_write16(padapter, REG_BCNTCFG, 0x00);
4673 rtw_write16(padapter, REG_TBTT_PROHIBIT, 0xff04);
4674 rtw_write16(padapter, REG_TSFTR_SYN_OFFSET, 0x7fff);/* +32767 (~32ms) */
4677 rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(1));
4679 /* enable BCN1 Function for if2 */
4680 /* don't enable update TSF1 for if2 (due to TSF update when beacon/probe rsp are received) */
4681 rtw_write8(padapter, REG_BCN_CTRL_1, (DIS_TSF_UDT | EN_BCN_FUNCTION | EN_TXBCN_RPT | DIS_BCNQ_SUB));
4683 /* SW_BCN_SEL - Port1 */
4684 /* rtw_write8(Adapter, REG_DWBCN1_CTRL_8192E+2, rtw_read8(Adapter, REG_DWBCN1_CTRL_8192E+2)|BIT4); */
4685 rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
4687 /* select BCN on port 1 */
4688 rtw_write8(padapter, REG_CCK_CHECK_8703B,
4689 (rtw_read8(padapter, REG_CCK_CHECK_8703B) | BIT_BCN_PORT_SEL));
4691 if (!rtw_mi_buddy_check_fwstate(padapter, WIFI_FW_ASSOC_SUCCESS)) {
4692 val8 = rtw_read8(padapter, REG_BCN_CTRL);
4693 val8 &= ~EN_BCN_FUNCTION;
4694 rtw_write8(padapter, REG_BCN_CTRL, val8);
4697 /* BCN1 TSF will sync to BCN0 TSF with offset(0x518) if if1_sta linked */
4698 /* rtw_write8(padapter, REG_BCN_CTRL_1, rtw_read8(padapter, REG_BCN_CTRL_1)|BIT(5)); */
4699 /* rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(3)); */
4701 /* dis BCN0 ATIM WND if if1 is station */
4702 rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL) | DIS_ATIM);
4704 #ifdef CONFIG_TSF_RESET_OFFLOAD
4705 /* Reset TSF for STA+AP concurrent mode */
4706 if (rtw_mi_buddy_check_fwstate(padapter, (WIFI_STATION_STATE | WIFI_ASOC_STATE))) {
4707 if (reset_tsf(padapter, HW_PORT1) == _FALSE)
4708 RTW_INFO("ERROR! %s()-%d: Reset port1 TSF fail\n",
4709 __FUNCTION__, __LINE__);
4711 #endif /* CONFIG_TSF_RESET_OFFLOAD */
4713 } else /* else for port0 */
4714 #endif /* CONFIG_CONCURRENT_MODE */
4716 #ifdef CONFIG_MI_WITH_MBSSID_CAM /*For Port0 - MBSS CAM*/
4717 hw_var_set_opmode_mbid(padapter, mode);
4719 /* disable Port0 TSF update */
4720 val8 = rtw_read8(padapter, REG_BCN_CTRL);
4721 val8 |= DIS_TSF_UDT;
4722 rtw_write8(padapter, REG_BCN_CTRL, val8);
4725 Set_MSR(padapter, mode);
4726 RTW_INFO("#### %s() -%d hw_port(0) mode = %d ####\n", __func__, __LINE__, mode);
4728 if ((mode == _HW_STATE_STATION_) || (mode == _HW_STATE_NOLINK_)) {
4729 #ifdef CONFIG_CONCURRENT_MODE
4730 if (!rtw_mi_check_status(padapter, MI_AP_MODE))
4731 #endif /* CONFIG_CONCURRENT_MODE */
4733 StopTxBeacon(padapter);
4734 #ifdef CONFIG_PCI_HCI
4735 UpdateInterruptMask8703BE(padapter, 0, 0, RT_BCN_INT_MASKS, 0);
4736 #else /* !CONFIG_PCI_HCI */
4737 #ifdef CONFIG_INTERRUPT_BASED_TXBCN
4738 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
4739 rtw_write8(padapter, REG_DRVERLYINT, 0x05); /* restore early int time to 5ms */
4740 UpdateInterruptMask8812AU(padapter, _TRUE, 0, IMR_BCNDMAINT0_8703B);
4741 #endif /* CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT */
4743 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
4744 UpdateInterruptMask8812AU(padapter, _TRUE , 0, (IMR_TXBCN0ERR_8703B | IMR_TXBCN0OK_8703B));
4745 #endif /* CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR */
4747 #endif /* CONFIG_INTERRUPT_BASED_TXBCN */
4748 #endif /* !CONFIG_PCI_HCI */
4751 /* disable atim wnd */
4752 rtw_write8(padapter, REG_BCN_CTRL, DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_ATIM);
4753 /* rtw_write8(padapter,REG_BCN_CTRL, 0x18); */
4754 } else if ((mode == _HW_STATE_ADHOC_) /*|| (mode == _HW_STATE_AP_)*/) {
4755 ResumeTxBeacon(padapter);
4756 rtw_write8(padapter, REG_BCN_CTRL, DIS_TSF_UDT | EN_BCN_FUNCTION | DIS_BCNQ_SUB);
4757 } else if (mode == _HW_STATE_AP_) {
4758 #ifdef CONFIG_PCI_HCI
4759 UpdateInterruptMask8703BE(padapter, RT_BCN_INT_MASKS, 0, 0, 0);
4760 #else /* !CONFIG_PCI_HCI */
4761 #ifdef CONFIG_INTERRUPT_BASED_TXBCN
4762 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT
4763 UpdateInterruptMask8703BU(padapter, _TRUE , IMR_BCNDMAINT0_8703B, 0);
4764 #endif /* CONFIG_INTERRUPT_BASED_TXBCN_EARLY_INT */
4766 #ifdef CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR
4767 UpdateInterruptMask8703BU(padapter, _TRUE , (IMR_TXBCN0ERR_8703B | IMR_TXBCN0OK_8703B), 0);
4768 #endif /* CONFIG_INTERRUPT_BASED_TXBCN_BCN_OK_ERR */
4770 #endif /* CONFIG_INTERRUPT_BASED_TXBCN */
4773 ResumeTxBeacon(padapter);
4775 rtw_write8(padapter, REG_BCN_CTRL, DIS_TSF_UDT | DIS_BCNQ_SUB);
4778 /* rtw_write32(padapter, REG_RCR, 0x70002a8e); */ /* CBSSID_DATA must set to 0 */
4779 /* rtw_write32(padapter, REG_RCR, 0x7000228e); */ /* CBSSID_DATA must set to 0 */
4780 if (padapter->registrypriv.wifi_spec)
4781 /* for 11n Logo 4.2.31/4.2.32, disable BSSID BCN check for AP mode */
4782 rtw_write32(padapter, REG_RCR, (0x7000208e & ~(RCR_CBSSID_BCN)));
4784 rtw_write32(padapter, REG_RCR, 0x7000208e);/* CBSSID_DATA must set to 0,reject ICV_ERR packet */
4785 /* enable to rx data frame */
4786 rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
4787 /* enable to rx ps-poll */
4788 rtw_write16(padapter, REG_RXFLTMAP1, 0x0400);
4790 /* Beacon Control related register for first time */
4791 rtw_write8(padapter, REG_BCNDMATIM, 0x02); /* 2ms */
4793 /* rtw_write8(padapter, REG_BCN_MAX_ERR, 0xFF); */
4794 rtw_write8(padapter, REG_ATIMWND, 0x0a); /* 10ms */
4795 rtw_write16(padapter, REG_BCNTCFG, 0x00);
4796 rtw_write16(padapter, REG_TBTT_PROHIBIT, 0xff04);
4797 rtw_write16(padapter, REG_TSFTR_SYN_OFFSET, 0x7fff);/* +32767 (~32ms) */
4800 rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(0));
4802 /* enable BCN0 Function for if1 */
4803 /* don't enable update TSF0 for if1 (due to TSF update when beacon/probe rsp are received) */
4804 rtw_write8(padapter, REG_BCN_CTRL, (DIS_TSF_UDT | EN_BCN_FUNCTION | EN_TXBCN_RPT | DIS_BCNQ_SUB));
4806 /* SW_BCN_SEL - Port0 */
4807 /* rtw_write8(Adapter, REG_DWBCN1_CTRL_8192E+2, rtw_read8(Adapter, REG_DWBCN1_CTRL_8192E+2) & ~BIT4); */
4808 rtw_hal_set_hwreg(padapter, HW_VAR_DL_BCN_SEL, NULL);
4810 /* select BCN on port 0 */
4811 rtw_write8(padapter, REG_CCK_CHECK_8703B,
4812 (rtw_read8(padapter, REG_CCK_CHECK_8703B) & ~BIT_BCN_PORT_SEL));
4814 #ifdef CONFIG_CONCURRENT_MODE
4815 if (!rtw_mi_buddy_check_fwstate(padapter, WIFI_FW_ASSOC_SUCCESS)) {
4816 val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
4817 val8 &= ~EN_BCN_FUNCTION;
4818 rtw_write8(padapter, REG_BCN_CTRL_1, val8);
4820 #endif /* CONFIG_CONCURRENT_MODE */
4822 /* dis BCN1 ATIM WND if if2 is station */
4823 val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
4825 rtw_write8(padapter, REG_BCN_CTRL_1, val8);
4826 #ifdef CONFIG_TSF_RESET_OFFLOAD
4827 /* Reset TSF for STA+AP concurrent mode */
4828 if (rtw_mi_buddy_check_fwstate(padapter, (WIFI_STATION_STATE | WIFI_ASOC_STATE))) {
4829 if (reset_tsf(padapter, HW_PORT0) == _FALSE)
4830 RTW_INFO("ERROR! %s()-%d: Reset port0 TSF fail\n",
4831 __FUNCTION__, __LINE__);
4833 #endif /* CONFIG_TSF_RESET_OFFLOAD */
4839 static void hw_var_set_bcn_func(PADAPTER padapter, u8 variable, u8 *val)
4843 #ifdef CONFIG_CONCURRENT_MODE
4844 if (padapter->hw_port == HW_PORT1)
4845 bcn_ctrl_reg = REG_BCN_CTRL_1;
4849 bcn_ctrl_reg = REG_BCN_CTRL;
4853 rtw_write8(padapter, bcn_ctrl_reg, (EN_BCN_FUNCTION | EN_TXBCN_RPT));
4856 val8 = rtw_read8(padapter, bcn_ctrl_reg);
4857 val8 &= ~(EN_BCN_FUNCTION | EN_TXBCN_RPT);
4858 #ifdef CONFIG_BT_COEXIST
4859 /* Always enable port0 beacon function for PSTDMA */
4860 if (REG_BCN_CTRL == bcn_ctrl_reg)
4861 val8 |= EN_BCN_FUNCTION;
4863 rtw_write8(padapter, bcn_ctrl_reg, val8);
4867 static void hw_var_set_correct_tsf(PADAPTER padapter, u8 variable, u8 *val)
4869 #ifdef CONFIG_MI_WITH_MBSSID_CAM
4875 struct mlme_ext_priv *pmlmeext;
4876 struct mlme_ext_info *pmlmeinfo;
4879 pmlmeext = &padapter->mlmeextpriv;
4880 pmlmeinfo = &pmlmeext->mlmext_info;
4882 tsf = pmlmeext->TSFValue - rtw_modular64(pmlmeext->TSFValue, (pmlmeinfo->bcn_interval * 1024)) - 1024; /*us*/
4884 if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE) ||
4885 ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE))
4886 StopTxBeacon(padapter);
4888 rtw_hal_correct_tsf(padapter, padapter->hw_port, tsf);
4889 #ifdef CONFIG_CONCURRENT_MODE
4890 /* Update buddy port's TSF if it is SoftAP for beacon TX issue!*/
4891 if ((pmlmeinfo->state & 0x03) == WIFI_FW_STATION_STATE
4892 && rtw_mi_check_status(padapter, MI_AP_MODE)) {
4894 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
4898 for (i = 0; i < dvobj->iface_nums; i++) {
4899 iface = dvobj->padapters[i];
4902 if (iface == padapter)
4905 if (check_fwstate(&iface->mlmepriv, WIFI_AP_STATE) == _TRUE
4906 && check_fwstate(&iface->mlmepriv, WIFI_ASOC_STATE) == _TRUE
4908 rtw_hal_correct_tsf(iface, iface->hw_port, tsf);
4909 #ifdef CONFIG_TSF_RESET_OFFLOAD
4910 if (reset_tsf(iface, iface->hw_port) == _FALSE)
4911 RTW_INFO("%s-[ERROR] "ADPT_FMT" Reset port%d TSF fail\n", __func__, ADPT_ARG(iface), iface->hw_port);
4912 #endif /* CONFIG_TSF_RESET_OFFLOAD*/
4916 #endif /*CONFIG_CONCURRENT_MODE*/
4917 if (((pmlmeinfo->state & 0x03) == WIFI_FW_ADHOC_STATE)
4918 || ((pmlmeinfo->state & 0x03) == WIFI_FW_AP_STATE))
4919 ResumeTxBeacon(padapter);
4920 #endif /*CONFIG_MI_WITH_MBSSID_CAM*/
4923 static void hw_var_set_mlme_disconnect(PADAPTER padapter, u8 variable, u8 *val)
4927 #ifdef CONFIG_CONCURRENT_MODE
4928 if (rtw_mi_check_status(padapter, MI_LINKED) == _FALSE)
4931 /* Set RCR to not to receive data frame when NO LINK state */
4932 /* rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR) & ~RCR_ADF); */
4933 /* reject all data frames */
4934 rtw_write16(padapter, REG_RXFLTMAP2, 0);
4937 #ifdef CONFIG_CONCURRENT_MODE
4938 if (padapter->hw_port == HW_PORT1) {
4940 rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(1));
4942 /* disable update TSF1 */
4943 val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
4944 val8 |= DIS_TSF_UDT;
4945 rtw_write8(padapter, REG_BCN_CTRL_1, val8);
4947 /* disable Port1's beacon function */
4948 val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
4949 val8 &= ~EN_BCN_FUNCTION;
4950 rtw_write8(padapter, REG_BCN_CTRL_1, val8);
4955 rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(0));
4957 /* disable update TSF */
4958 val8 = rtw_read8(padapter, REG_BCN_CTRL);
4959 val8 |= DIS_TSF_UDT;
4960 rtw_write8(padapter, REG_BCN_CTRL, val8);
4964 static void hw_var_set_mlme_sitesurvey(PADAPTER padapter, u8 variable, u8 *val)
4966 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
4967 u32 value_rcr, rcr_clear_bit;
4968 u16 value_rxfltmap2;
4970 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
4974 #ifdef DBG_IFACE_STATUS
4975 DBG_IFACE_STATUS_DUMP(padapter);
4978 #ifdef CONFIG_FIND_BEST_CHANNEL
4979 rcr_clear_bit = (RCR_CBSSID_BCN | RCR_CBSSID_DATA);
4981 /* Receive all data frames */
4982 value_rxfltmap2 = 0xFFFF;
4983 #else /* CONFIG_FIND_BEST_CHANNEL */
4985 rcr_clear_bit = RCR_CBSSID_BCN;
4987 /* config RCR to receive different BSSID & not to receive data frame */
4988 value_rxfltmap2 = 0;
4990 #endif /* CONFIG_FIND_BEST_CHANNEL */
4992 if (rtw_mi_check_fwstate(padapter, WIFI_AP_STATE))
4993 rcr_clear_bit = RCR_CBSSID_BCN;
4996 /* TDLS will clear RCR_CBSSID_DATA bit for connection. */
4997 else if (padapter->tdlsinfo.link_established == _TRUE)
4998 rcr_clear_bit = RCR_CBSSID_BCN;
4999 #endif /* CONFIG_TDLS */
5001 value_rcr = rtw_read32(padapter, REG_RCR);
5003 if (*((u8 *)val)) {/* under sitesurvey */
5005 * 1. configure REG_RXFLTMAP2
5006 * 2. disable TSF update & buddy TSF update to avoid updating wrong TSF due to clear RCR_CBSSID_BCN
5007 * 3. config RCR to receive different BSSID BCN or probe rsp
5009 rtw_write16(padapter, REG_RXFLTMAP2, value_rxfltmap2);
5011 #ifdef CONFIG_MI_WITH_MBSSID_CAM
5015 /* disable update TSF */
5016 for (i = 0; i < dvobj->iface_nums; i++) {
5017 iface = dvobj->padapters[i];
5021 if (rtw_linked_check(iface) &&
5022 check_fwstate(&(iface->mlmepriv), WIFI_AP_STATE) != _TRUE) {
5023 if (iface->hw_port == HW_PORT1)
5024 rtw_write8(iface, REG_BCN_CTRL_1, rtw_read8(iface, REG_BCN_CTRL_1) | DIS_TSF_UDT);
5026 rtw_write8(iface, REG_BCN_CTRL, rtw_read8(iface, REG_BCN_CTRL) | DIS_TSF_UDT);
5028 iface->mlmeextpriv.en_hw_update_tsf = _FALSE;
5034 value_rcr &= ~(rcr_clear_bit);
5035 rtw_write32(padapter, REG_RCR, value_rcr);
5037 /* Save orignal RRSR setting.*/
5038 pHalData->RegRRSR = rtw_read16(padapter, REG_RRSR);
5040 if (rtw_mi_check_status(padapter, MI_AP_MODE))
5041 StopTxBeacon(padapter);
5042 } else {/* sitesurvey done */
5044 * 1. enable rx data frame
5045 * 2. config RCR not to receive different BSSID BCN or probe rsp
5046 * 3. doesn't enable TSF update & buddy TSF right now to avoid HW conflict
5047 * so, we enable TSF update when rx first BCN after sitesurvey done
5050 if (rtw_mi_check_fwstate(padapter, _FW_LINKED | WIFI_AP_STATE))
5051 rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF);/*enable to rx data frame*/
5053 #ifdef CONFIG_MI_WITH_MBSSID_CAM
5054 value_rcr &= ~(RCR_CBSSID_BCN | RCR_CBSSID_DATA);
5056 value_rcr |= rcr_clear_bit;
5058 /* for 11n Logo 4.2.31/4.2.32, disable BSSID BCN check for AP mode */
5059 if (padapter->registrypriv.wifi_spec && MLME_IS_AP(padapter))
5060 value_rcr &= ~(RCR_CBSSID_BCN);
5062 rtw_write32(padapter, REG_RCR, value_rcr);
5064 #ifdef CONFIG_MI_WITH_MBSSID_CAM
5065 /*if ((rtw_mi_get_assoced_sta_num(Adapter) == 1) && (!rtw_mi_check_status(Adapter, MI_AP_MODE)))
5066 rtw_write8(Adapter, REG_BCN_CTRL, rtw_read8(Adapter, REG_BCN_CTRL)&(~DIS_TSF_UDT));*/
5069 for (i = 0; i < dvobj->iface_nums; i++) {
5070 iface = dvobj->padapters[i];
5073 if (rtw_linked_check(iface) &&
5074 check_fwstate(&(iface->mlmepriv), WIFI_AP_STATE) != _TRUE) {
5075 /* enable HW TSF update when recive beacon*/
5076 /*if (iface->hw_port == HW_PORT1)
5077 rtw_write8(iface, REG_BCN_CTRL_1, rtw_read8(iface, REG_BCN_CTRL_1)&(~(DIS_TSF_UDT)));
5079 rtw_write8(iface, REG_BCN_CTRL, rtw_read8(iface, REG_BCN_CTRL)&(~(DIS_TSF_UDT)));
5081 iface->mlmeextpriv.en_hw_update_tsf = _TRUE;
5086 /*Restore orignal RRSR setting.*/
5087 rtw_write16(padapter, REG_RRSR, pHalData->RegRRSR);
5089 if (rtw_mi_check_status(padapter, MI_AP_MODE)) {
5090 ResumeTxBeacon(padapter);
5091 rtw_mi_tx_beacon_hdl(padapter);
5096 static void hw_var_set_mlme_join(PADAPTER padapter, u8 variable, u8 *val)
5103 PHAL_DATA_TYPE pHalData;
5104 struct mlme_priv *pmlmepriv;
5108 pHalData = GET_HAL_DATA(padapter);
5109 pmlmepriv = &padapter->mlmepriv;
5111 #ifdef CONFIG_CONCURRENT_MODE
5113 /* prepare to join */
5114 if (rtw_mi_check_status(padapter, MI_AP_MODE))
5115 StopTxBeacon(padapter);
5117 /* enable to rx data frame.Accept all data frame */
5118 rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
5119 #ifdef CONFIG_MI_WITH_MBSSID_CAM
5121 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) && (rtw_mi_get_assoced_sta_num(padapter) == 1))
5122 rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR)|RCR_CBSSID_DATA|RCR_CBSSID_BCN);
5123 else if ((rtw_mi_get_ap_num(Adapter) == 1) && (rtw_mi_get_assoced_sta_num(Adapter) == 1))
5124 rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR)|RCR_CBSSID_BCN);
5126 rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR) & (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN)));
5128 if (rtw_mi_check_status(padapter, MI_AP_MODE)) {
5129 val32 = rtw_read32(padapter, REG_RCR);
5130 val32 |= RCR_CBSSID_BCN;
5131 rtw_write32(padapter, REG_RCR, val32);
5133 val32 = rtw_read32(padapter, REG_RCR);
5134 val32 |= RCR_CBSSID_DATA | RCR_CBSSID_BCN;
5135 rtw_write32(padapter, REG_RCR, val32);
5138 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
5139 RetryLimit = (pHalData->CustomerID == RT_CID_CCX) ? 7 : 48;
5140 else /* Ad-hoc Mode */
5142 } else if (type == 1) {
5143 /* joinbss_event call back when join res < 0 */
5144 if (rtw_mi_check_status(padapter, MI_LINKED) == _FALSE)
5145 rtw_write16(padapter, REG_RXFLTMAP2, 0x00);
5147 if (rtw_mi_check_status(padapter, MI_AP_MODE)) {
5148 ResumeTxBeacon(padapter);
5150 /* reset TSF 1/2 after ResumeTxBeacon */
5151 rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(1) | BIT(0));
5153 } else if (type == 2) {
5154 /* sta add event call back */
5155 #ifdef CONFIG_MI_WITH_MBSSID_CAM
5156 /*if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) && (rtw_mi_get_assoced_sta_num(padapter) == 1))
5157 rtw_write8(padapter, REG_BCN_CTRL, rtw_read8(padapter, REG_BCN_CTRL)&(~DIS_TSF_UDT));*/
5159 /* enable update TSF */
5160 if (padapter->hw_port == HW_PORT1) {
5161 val8 = rtw_read8(padapter, REG_BCN_CTRL_1);
5162 val8 &= ~DIS_TSF_UDT;
5163 rtw_write8(padapter, REG_BCN_CTRL_1, val8);
5165 val8 = rtw_read8(padapter, REG_BCN_CTRL);
5166 val8 &= ~DIS_TSF_UDT;
5167 rtw_write8(padapter, REG_BCN_CTRL, val8);
5170 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE)) {
5171 rtw_write8(padapter, 0x542 , 0x02);
5175 if (rtw_mi_check_status(padapter, MI_AP_MODE)) {
5176 ResumeTxBeacon(padapter);
5178 /* reset TSF 1/2 after ResumeTxBeacon */
5179 rtw_write8(padapter, REG_DUAL_TSF_RST, BIT(1) | BIT(0));
5183 val16 = (RetryLimit << RETRY_LIMIT_SHORT_SHIFT) | (RetryLimit << RETRY_LIMIT_LONG_SHIFT);
5184 rtw_write16(padapter, REG_RL, val16);
5185 #else /* !CONFIG_CONCURRENT_MODE */
5186 if (type == 0) { /* prepare to join */
5187 /* enable to rx data frame.Accept all data frame */
5188 /* rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR)|RCR_ADF); */
5189 rtw_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
5191 val32 = rtw_read32(padapter, REG_RCR);
5192 if (padapter->in_cta_test)
5193 val32 &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);/* | RCR_ADF */
5195 val32 |= RCR_CBSSID_DATA | RCR_CBSSID_BCN;
5196 rtw_write32(padapter, REG_RCR, val32);
5198 if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) == _TRUE)
5199 RetryLimit = (pHalData->CustomerID == RT_CID_CCX) ? 7 : 48;
5200 else /* Ad-hoc Mode */
5202 } else if (type == 1) /* joinbss_event call back when join res < 0 */
5203 rtw_write16(padapter, REG_RXFLTMAP2, 0x00);
5204 else if (type == 2) { /* sta add event call back */
5205 /* enable update TSF */
5206 val8 = rtw_read8(padapter, REG_BCN_CTRL);
5207 val8 &= ~DIS_TSF_UDT;
5208 rtw_write8(padapter, REG_BCN_CTRL, val8);
5210 if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE))
5214 val16 = (RetryLimit << RETRY_LIMIT_SHORT_SHIFT) | (RetryLimit << RETRY_LIMIT_LONG_SHIFT);
5215 rtw_write16(padapter, REG_RL, val16);
5216 #endif /* !CONFIG_CONCURRENT_MODE */
5219 void CCX_FwC2HTxRpt_8703b(PADAPTER padapter, u8 *pdata, u8 len)
5223 #define GET_8703B_C2H_TX_RPT_LIFE_TIME_OVER(_Header) LE_BITS_TO_1BYTE((_Header + 0), 6, 1)
5224 #define GET_8703B_C2H_TX_RPT_RETRY_OVER(_Header) LE_BITS_TO_1BYTE((_Header + 0), 7, 1)
5226 /* RTW_INFO("%s, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n", __func__, */
5227 /* *pdata, *(pdata+1), *(pdata+2), *(pdata+3), *(pdata+4), *(pdata+5), *(pdata+6), *(pdata+7)); */
5229 seq_no = *(pdata + 6);
5231 #ifdef CONFIG_XMIT_ACK
5232 if (GET_8703B_C2H_TX_RPT_RETRY_OVER(pdata) | GET_8703B_C2H_TX_RPT_LIFE_TIME_OVER(pdata))
5233 rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_CCX_PKT_FAIL);
5235 else if(seq_no != padapter->xmitpriv.seq_no) {
5236 RTW_INFO("tx_seq_no=%d, rpt_seq_no=%d\n", padapter->xmitpriv.seq_no, seq_no);
5237 rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_CCX_PKT_FAIL);
5241 rtw_ack_tx_done(&padapter->xmitpriv, RTW_SCTX_DONE_SUCCESS);
5245 static s32 c2h_handler_8703b(_adapter *adapter, u8 id, u8 seq, u8 plen, u8 *payload)
5250 case C2H_CCX_TX_RPT:
5251 CCX_FwC2HTxRpt_8703b(adapter, payload, plen);
5262 void SetHwReg8703B(PADAPTER padapter, u8 variable, u8 *val)
5264 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
5271 case HW_VAR_SET_OPMODE:
5272 hw_var_set_opmode(padapter, variable, val);
5275 case HW_VAR_BASIC_RATE: {
5276 struct mlme_ext_info *mlmext_info = &padapter->mlmeextpriv.mlmext_info;
5277 u16 input_b = 0, masked = 0, ioted = 0, BrateCfg = 0;
5278 u16 rrsr_2g_force_mask = RRSR_CCK_RATES;
5279 u16 rrsr_2g_allow_mask = (RRSR_24M | RRSR_12M | RRSR_6M | RRSR_CCK_RATES);
5281 HalSetBrateCfg(padapter, val, &BrateCfg);
5284 /* apply force and allow mask */
5285 BrateCfg |= rrsr_2g_force_mask;
5286 BrateCfg &= rrsr_2g_allow_mask;
5289 #ifdef CONFIG_CMCC_TEST
5290 BrateCfg |= (RRSR_11M | RRSR_5_5M | RRSR_1M); /* use 11M to send ACK */
5291 BrateCfg |= (RRSR_24M | RRSR_18M | RRSR_12M); /* CMCC_OFDM_ACK 12/18/24M */
5294 /* IOT consideration */
5295 if (mlmext_info->assoc_AP_vendor == HT_IOT_PEER_CISCO) {
5296 /* if peer is cisco and didn't use ofdm rate, we enable 6M ack */
5297 if ((BrateCfg & (RRSR_24M | RRSR_12M | RRSR_6M)) == 0)
5298 BrateCfg |= RRSR_6M;
5302 pHalData->BasicRateSet = BrateCfg;
5304 RTW_INFO("HW_VAR_BASIC_RATE: %#x->%#x->%#x\n", input_b, masked, ioted);
5306 /* Set RRSR rate table. */
5307 rtw_write16(padapter, REG_RRSR, BrateCfg);
5308 rtw_write8(padapter, REG_RRSR + 2, rtw_read8(padapter, REG_RRSR + 2) & 0xf0);
5312 case HW_VAR_TXPAUSE:
5313 rtw_write8(padapter, REG_TXPAUSE, *val);
5316 case HW_VAR_BCN_FUNC:
5317 hw_var_set_bcn_func(padapter, variable, val);
5320 case HW_VAR_CORRECT_TSF:
5321 hw_var_set_correct_tsf(padapter, variable, val);
5324 case HW_VAR_CHECK_BSSID: {
5326 val32 = rtw_read32(padapter, REG_RCR);
5328 val32 |= RCR_CBSSID_DATA | RCR_CBSSID_BCN;
5330 val32 &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);
5331 rtw_write32(padapter, REG_RCR, val32);
5335 case HW_VAR_MLME_DISCONNECT:
5336 hw_var_set_mlme_disconnect(padapter, variable, val);
5339 case HW_VAR_MLME_SITESURVEY:
5340 hw_var_set_mlme_sitesurvey(padapter, variable, val);
5342 #ifdef CONFIG_BT_COEXIST
5343 rtw_btcoex_ScanNotify(padapter, *val ? _TRUE : _FALSE);
5344 #endif /* CONFIG_BT_COEXIST */
5347 case HW_VAR_MLME_JOIN:
5348 hw_var_set_mlme_join(padapter, variable, val);
5350 #ifdef CONFIG_BT_COEXIST
5353 /* Notify coex. mechanism before join */
5354 rtw_btcoex_ConnectNotify(padapter, _TRUE);
5358 /* Notify coex. mechanism after join, whether successful or failed */
5359 rtw_btcoex_ConnectNotify(padapter, _FALSE);
5362 #endif /* CONFIG_BT_COEXIST */
5365 case HW_VAR_ON_RCR_AM:
5366 val32 = rtw_read32(padapter, REG_RCR);
5368 rtw_write32(padapter, REG_RCR, val32);
5369 RTW_INFO("%s, %d, RCR= %x\n", __FUNCTION__, __LINE__, rtw_read32(padapter, REG_RCR));
5372 case HW_VAR_OFF_RCR_AM:
5373 val32 = rtw_read32(padapter, REG_RCR);
5375 rtw_write32(padapter, REG_RCR, val32);
5376 RTW_INFO("%s, %d, RCR= %x\n", __FUNCTION__, __LINE__, rtw_read32(padapter, REG_RCR));
5379 case HW_VAR_BEACON_INTERVAL:
5380 rtw_write16(padapter, REG_BCN_INTERVAL, *((u16 *)val));
5383 case HW_VAR_SLOT_TIME:
5384 rtw_write8(padapter, REG_SLOT, *val);
5387 case HW_VAR_RESP_SIFS:
5389 /* SIFS for OFDM Data ACK */
5390 rtw_write8(padapter, REG_SIFS_CTX + 1, val[0]);
5391 /* SIFS for OFDM consecutive tx like CTS data! */
5392 rtw_write8(padapter, REG_SIFS_TRX + 1, val[1]);
5394 rtw_write8(padapter, REG_SPEC_SIFS + 1, val[0]);
5395 rtw_write8(padapter, REG_MAC_SPEC_SIFS + 1, val[0]);
5397 /* 20100719 Joseph: Revise SIFS setting due to Hardware register definition change. */
5398 rtw_write8(padapter, REG_R2T_SIFS + 1, val[0]);
5399 rtw_write8(padapter, REG_T2T_SIFS + 1, val[0]);
5402 /* SIFS_Timer = 0x0a0a0808; */
5403 /* RESP_SIFS for CCK */
5404 rtw_write8(padapter, REG_RESP_SIFS_CCK, val[0]); /* SIFS_T2T_CCK (0x08) */
5405 rtw_write8(padapter, REG_RESP_SIFS_CCK + 1, val[1]); /* SIFS_R2T_CCK(0x08) */
5406 /* RESP_SIFS for OFDM */
5407 rtw_write8(padapter, REG_RESP_SIFS_OFDM, val[2]); /* SIFS_T2T_OFDM (0x0a) */
5408 rtw_write8(padapter, REG_RESP_SIFS_OFDM + 1, val[3]); /* SIFS_R2T_OFDM(0x0a) */
5412 case HW_VAR_ACK_PREAMBLE: {
5414 u8 bShortPreamble = *val;
5416 /* Joseph marked out for Netgear 3500 TKIP channel 7 issue.(Temporarily) */
5417 /* regTmp = (pHalData->nCur40MhzPrimeSC)<<5; */
5421 rtw_write8(padapter, REG_RRSR + 2, regTmp);
5425 case HW_VAR_CAM_EMPTY_ENTRY: {
5430 u32 ulEncAlgo = CAM_AES;
5432 for (i = 0; i < CAM_CONTENT_COUNT; i++) {
5433 /* filled id in CAM config 2 byte */
5435 ulContent |= (ucIndex & 0x03) | ((u16)(ulEncAlgo) << 2);
5436 /* ulContent |= CAM_VALID; */
5439 /* polling bit, and No Write enable, and address */
5440 ulCommand = CAM_CONTENT_COUNT * ucIndex + i;
5441 ulCommand = ulCommand | CAM_POLLINIG | CAM_WRITE;
5442 /* write content 0 is equall to mark invalid */
5443 rtw_write32(padapter, WCAMI, ulContent); /* delay_ms(40); */
5444 rtw_write32(padapter, RWCAM, ulCommand); /* delay_ms(40); */
5449 case HW_VAR_CAM_INVALID_ALL:
5450 rtw_write32(padapter, RWCAM, BIT(31) | BIT(30));
5453 case HW_VAR_AC_PARAM_VO:
5454 rtw_write32(padapter, REG_EDCA_VO_PARAM, *((u32 *)val));
5457 case HW_VAR_AC_PARAM_VI:
5458 rtw_write32(padapter, REG_EDCA_VI_PARAM, *((u32 *)val));
5461 case HW_VAR_AC_PARAM_BE:
5462 pHalData->ac_param_be = ((u32 *)(val))[0];
5463 rtw_write32(padapter, REG_EDCA_BE_PARAM, *((u32 *)val));
5466 case HW_VAR_AC_PARAM_BK:
5467 rtw_write32(padapter, REG_EDCA_BK_PARAM, *((u32 *)val));
5470 case HW_VAR_ACM_CTRL: {
5471 u8 ctrl = *((u8 *)val);
5475 hwctrl |= AcmHw_HwEn;
5477 if (ctrl & BIT(1)) /* BE */
5478 hwctrl |= AcmHw_BeqEn;
5480 if (ctrl & BIT(2)) /* VI */
5481 hwctrl |= AcmHw_ViqEn;
5483 if (ctrl & BIT(3)) /* VO */
5484 hwctrl |= AcmHw_VoqEn;
5487 RTW_INFO("[HW_VAR_ACM_CTRL] Write 0x%02X\n", hwctrl);
5488 rtw_write8(padapter, REG_ACMHWCTRL, hwctrl);
5492 case HW_VAR_AMPDU_FACTOR: {
5493 u32 AMPDULen = (*((u8 *)val));
5495 if (AMPDULen < HT_AGG_SIZE_32K)
5496 AMPDULen = (0x2000 << (*((u8 *)val))) - 1;
5500 rtw_write32(padapter, REG_AMPDU_MAX_LENGTH_8703B, AMPDULen);
5505 case HW_VAR_RXDMA_AGG_PG_TH:
5506 rtw_write8(padapter, REG_RXDMA_AGG_PG_TH, *val);
5510 case HW_VAR_H2C_FW_PWRMODE: {
5513 /* Forece leave RF low power mode for 1T1R to prevent conficting setting in Fw power */
5514 /* saving sequence. 2010.06.07. Added by tynli. Suggested by SD3 yschang. */
5515 if (psmode != PS_MODE_ACTIVE)
5516 odm_rf_saving(&pHalData->odmpriv, _TRUE);
5518 /* if (psmode != PS_MODE_ACTIVE) { */
5519 /* rtl8703b_set_lowpwr_lps_cmd(padapter, _TRUE); */
5521 /* rtl8703b_set_lowpwr_lps_cmd(padapter, _FALSE); */
5523 rtl8703b_set_FwPwrMode_cmd(padapter, psmode);
5526 case HW_VAR_H2C_PS_TUNE_PARAM:
5527 rtl8703b_set_FwPsTuneParam_cmd(padapter);
5530 case HW_VAR_H2C_FW_JOINBSSRPT:
5531 rtl8703b_set_FwJoinBssRpt_cmd(padapter, *val);
5535 case HW_VAR_H2C_FW_P2P_PS_OFFLOAD:
5536 rtl8703b_set_p2p_ps_offload_cmd(padapter, *val);
5538 #endif /* CONFIG_P2P */
5540 case HW_VAR_TDLS_WRCR:
5541 rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR) & (~RCR_CBSSID_DATA));
5543 case HW_VAR_TDLS_RS_RCR:
5544 rtw_write32(padapter, REG_RCR, rtw_read32(padapter, REG_RCR) | (RCR_CBSSID_DATA));
5546 #endif /* CONFIG_TDLS */
5548 case HW_VAR_EFUSE_USAGE:
5549 pHalData->EfuseUsedPercentage = *val;
5552 case HW_VAR_EFUSE_BYTES:
5553 pHalData->EfuseUsedBytes = *((u16 *)val);
5556 case HW_VAR_EFUSE_BT_USAGE:
5557 #ifdef HAL_EFUSE_MEMORY
5558 pHalData->EfuseHal.BTEfuseUsedPercentage = *val;
5562 case HW_VAR_EFUSE_BT_BYTES:
5563 #ifdef HAL_EFUSE_MEMORY
5564 pHalData->EfuseHal.BTEfuseUsedBytes = *((u16 *)val);
5566 BTEfuseUsedBytes = *((u16 *)val);
5570 case HW_VAR_FIFO_CLEARN_UP: {
5571 #define RW_RELEASE_EN BIT(18)
5572 #define RXDMA_IDLE BIT(17)
5574 struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(padapter);
5578 rtw_write8(padapter, REG_TXPAUSE, 0xff);
5581 padapter->xmitpriv.nqos_ssn = rtw_read16(padapter, REG_NQOS_SEQ);
5583 if (pwrpriv->bkeepfwalive != _TRUE) {
5585 val32 = rtw_read32(padapter, REG_RXPKT_NUM);
5586 val32 |= RW_RELEASE_EN;
5587 rtw_write32(padapter, REG_RXPKT_NUM, val32);
5589 val32 = rtw_read32(padapter, REG_RXPKT_NUM);
5590 val32 &= RXDMA_IDLE;
5594 RTW_INFO("%s: [HW_VAR_FIFO_CLEARN_UP] val=%x times:%d\n", __FUNCTION__, val32, trycnt);
5597 RTW_INFO("[HW_VAR_FIFO_CLEARN_UP] Stop RX DMA failed......\n");
5600 rtw_write16(padapter, REG_RQPN_NPQ, 0);
5601 rtw_write32(padapter, REG_RQPN, 0x80000000);
5607 case HW_VAR_RESTORE_HW_SEQ:
5608 /* restore Sequence No. */
5609 rtw_write8(padapter, 0x4dc, padapter->xmitpriv.nqos_ssn);
5612 #ifdef CONFIG_CONCURRENT_MODE
5613 case HW_VAR_CHECK_TXBUF: {
5615 u8 RetryLimit = 0x01;
5616 u32 reg_200, reg_204;
5618 val16 = RetryLimit << RETRY_LIMIT_SHORT_SHIFT | RetryLimit << RETRY_LIMIT_LONG_SHIFT;
5619 rtw_write16(padapter, REG_RL, val16);
5621 for (i = 0; i < 200; i++) { /* polling 200x10=2000 msec */
5622 reg_200 = rtw_read32(padapter, 0x200);
5623 reg_204 = rtw_read32(padapter, 0x204);
5624 if (reg_200 != reg_204) {
5625 /* RTW_INFO("packet in tx packet buffer - 0x204=%x, 0x200=%x (%d)\n", rtw_read32(padapter, 0x204), rtw_read32(padapter, 0x200), i); */
5628 RTW_INFO("[HW_VAR_CHECK_TXBUF] no packet in tx packet buffer (%d)\n", i);
5633 if (reg_200 != reg_204)
5634 RTW_INFO("packets in tx buffer - 0x204=%x, 0x200=%x\n", reg_204, reg_200);
5637 val16 = RetryLimit << RETRY_LIMIT_SHORT_SHIFT | RetryLimit << RETRY_LIMIT_LONG_SHIFT;
5638 rtw_write16(padapter, REG_RL, val16);
5641 #endif /* CONFIG_CONCURRENT_MODE */
5643 case HW_VAR_NAV_UPPER: {
5644 u32 usNavUpper = *((u32 *)val);
5646 if (usNavUpper > HAL_NAV_UPPER_UNIT_8703B * 0xFF) {
5650 /* The value of ((usNavUpper + HAL_NAV_UPPER_UNIT_8703B - 1) / HAL_NAV_UPPER_UNIT_8703B) */
5651 /* is getting the upper integer. */
5652 usNavUpper = (usNavUpper + HAL_NAV_UPPER_UNIT_8703B - 1) / HAL_NAV_UPPER_UNIT_8703B;
5653 rtw_write8(padapter, REG_NAV_UPPER, (u8)usNavUpper);
5657 case HW_VAR_BCN_VALID:
5658 #ifdef CONFIG_CONCURRENT_MODE
5659 if (padapter->hw_port == HW_PORT1) {
5660 val8 = rtw_read8(padapter, REG_DWBCN1_CTRL_8703B + 2);
5662 rtw_write8(padapter, REG_DWBCN1_CTRL_8703B + 2, val8);
5664 #endif /* CONFIG_CONCURRENT_MODE */
5666 /* BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2, write 1 to clear, Clear by sw */
5667 val8 = rtw_read8(padapter, REG_TDECTRL + 2);
5669 rtw_write8(padapter, REG_TDECTRL + 2, val8);
5673 case HW_VAR_DL_BCN_SEL:
5674 #ifdef CONFIG_CONCURRENT_MODE
5675 if (padapter->hw_port == HW_PORT1) {
5676 /* SW_BCN_SEL - Port1 */
5677 val8 = rtw_read8(padapter, REG_DWBCN1_CTRL_8703B + 2);
5679 rtw_write8(padapter, REG_DWBCN1_CTRL_8703B + 2, val8);
5681 #endif /* CONFIG_CONCURRENT_MODE */
5683 /* SW_BCN_SEL - Port0 */
5684 val8 = rtw_read8(padapter, REG_DWBCN1_CTRL_8703B + 2);
5686 rtw_write8(padapter, REG_DWBCN1_CTRL_8703B + 2, val8);
5692 pHalData->bNeedIQK = _TRUE;
5694 pHalData->bNeedIQK = _FALSE;
5697 case HW_VAR_DL_RSVD_PAGE:
5698 #ifdef CONFIG_BT_COEXIST
5699 if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) == _TRUE)
5700 rtl8703b_download_BTCoex_AP_mode_rsvd_page(padapter);
5702 #endif /* CONFIG_BT_COEXIST */
5704 rtl8703b_download_rsvd_page(padapter, RT_MEDIA_CONNECT);
5708 case HW_VAR_MACID_SLEEP: {
5709 u32 reg_macid_sleep;
5714 reg_macid_sleep = REG_MACID_SLEEP;
5716 } else if (id < 64) {
5717 reg_macid_sleep = REG_MACID_SLEEP_1;
5718 bit_shift = id - 32;
5719 } else if (id < 96) {
5720 reg_macid_sleep = REG_MACID_SLEEP_2;
5721 bit_shift = id - 64;
5722 } else if (id < 128) {
5723 reg_macid_sleep = REG_MACID_SLEEP_3;
5724 bit_shift = id - 96;
5730 val32 = rtw_read32(padapter, reg_macid_sleep);
5731 RTW_INFO(FUNC_ADPT_FMT ": [HW_VAR_MACID_SLEEP] macid=%d, org reg_0x%03x=0x%08X\n",
5732 FUNC_ADPT_ARG(padapter), id, reg_macid_sleep, val32);
5734 if (val32 & BIT(bit_shift))
5737 val32 |= BIT(bit_shift);
5738 rtw_write32(padapter, reg_macid_sleep, val32);
5742 case HW_VAR_MACID_WAKEUP: {
5743 u32 reg_macid_sleep;
5748 reg_macid_sleep = REG_MACID_SLEEP;
5750 } else if (id < 64) {
5751 reg_macid_sleep = REG_MACID_SLEEP_1;
5752 bit_shift = id - 32;
5753 } else if (id < 96) {
5754 reg_macid_sleep = REG_MACID_SLEEP_2;
5755 bit_shift = id - 64;
5756 } else if (id < 128) {
5757 reg_macid_sleep = REG_MACID_SLEEP_3;
5758 bit_shift = id - 96;
5764 val32 = rtw_read32(padapter, reg_macid_sleep);
5765 RTW_INFO(FUNC_ADPT_FMT ": [HW_VAR_MACID_WAKEUP] macid=%d, org reg_0x%03x=0x%08X\n",
5766 FUNC_ADPT_ARG(padapter), id, reg_macid_sleep, val32);
5768 if (!(val32 & BIT(bit_shift)))
5771 val32 &= ~BIT(bit_shift);
5772 rtw_write32(padapter, reg_macid_sleep, val32);
5775 #ifdef CONFIG_GPIO_WAKEUP
5776 case HW_SET_GPIO_WL_CTRL: {
5778 u8 value = rtw_read8(padapter, 0x4e);
5779 if (enable && (value & BIT(6))) {
5781 rtw_write8(padapter, 0x4e, value);
5782 } else if (enable == _FALSE) {
5784 rtw_write8(padapter, 0x4e, value);
5786 RTW_INFO("%s: set WL control, 0x4E=0x%02X\n",
5787 __func__, rtw_read8(padapter, 0x4e));
5791 #if defined(CONFIG_TDLS) && defined(CONFIG_TDLS_CH_SW)
5792 case HW_VAR_TDLS_BCN_EARLY_C2H_RPT:
5793 rtl8703b_set_BcnEarly_C2H_Rpt_cmd(padapter, *val);
5797 SetHwReg(padapter, variable, val);
5803 struct qinfo_8703b {
5811 struct bcn_qinfo_8703b {
5816 void dump_qinfo_8703b(void *sel, struct qinfo_8703b *info, const char *tag)
5818 /* if (info->pkt_num) */
5819 RTW_PRINT_SEL(sel, "%shead:0x%02x, tail:0x%02x, pkt_num:%u, macid:%u, ac:%u\n"
5820 , tag ? tag : "", info->head, info->tail, info->pkt_num, info->macid, info->ac
5824 void dump_bcn_qinfo_8703b(void *sel, struct bcn_qinfo_8703b *info, const char *tag)
5826 /* if (info->pkt_num) */
5827 RTW_PRINT_SEL(sel, "%shead:0x%02x, pkt_num:%u\n"
5828 , tag ? tag : "", info->head, info->pkt_num
5832 void dump_mac_qinfo_8703b(void *sel, _adapter *adapter)
5846 q0_info = rtw_read32(adapter, REG_Q0_INFO);
5847 q1_info = rtw_read32(adapter, REG_Q1_INFO);
5848 q2_info = rtw_read32(adapter, REG_Q2_INFO);
5849 q3_info = rtw_read32(adapter, REG_Q3_INFO);
5850 q4_info = rtw_read32(adapter, REG_Q4_INFO);
5851 q5_info = rtw_read32(adapter, REG_Q5_INFO);
5852 q6_info = rtw_read32(adapter, REG_Q6_INFO);
5853 q7_info = rtw_read32(adapter, REG_Q7_INFO);
5854 mg_q_info = rtw_read32(adapter, REG_MGQ_INFO);
5855 hi_q_info = rtw_read32(adapter, REG_HGQ_INFO);
5856 bcn_q_info = rtw_read16(adapter, REG_BCNQ_INFO);
5858 dump_qinfo_8703b(sel, (struct qinfo_8703b *)&q0_info, "Q0 ");
5859 dump_qinfo_8703b(sel, (struct qinfo_8703b *)&q1_info, "Q1 ");
5860 dump_qinfo_8703b(sel, (struct qinfo_8703b *)&q2_info, "Q2 ");
5861 dump_qinfo_8703b(sel, (struct qinfo_8703b *)&q3_info, "Q3 ");
5862 dump_qinfo_8703b(sel, (struct qinfo_8703b *)&q4_info, "Q4 ");
5863 dump_qinfo_8703b(sel, (struct qinfo_8703b *)&q5_info, "Q5 ");
5864 dump_qinfo_8703b(sel, (struct qinfo_8703b *)&q6_info, "Q6 ");
5865 dump_qinfo_8703b(sel, (struct qinfo_8703b *)&q7_info, "Q7 ");
5866 dump_qinfo_8703b(sel, (struct qinfo_8703b *)&mg_q_info, "MG ");
5867 dump_qinfo_8703b(sel, (struct qinfo_8703b *)&hi_q_info, "HI ");
5868 dump_bcn_qinfo_8703b(sel, (struct bcn_qinfo_8703b *)&bcn_q_info, "BCN ");
5871 void GetHwReg8703B(PADAPTER padapter, u8 variable, u8 *val)
5873 PHAL_DATA_TYPE pHalData = GET_HAL_DATA(padapter);
5880 case HW_VAR_TXPAUSE:
5881 *val = rtw_read8(padapter, REG_TXPAUSE);
5884 case HW_VAR_BCN_VALID:
5885 #ifdef CONFIG_CONCURRENT_MODE
5886 if (padapter->hw_port == HW_PORT1) {
5887 val8 = rtw_read8(padapter, REG_DWBCN1_CTRL_8703B + 2);
5888 *val = (BIT(0) & val8) ? _TRUE : _FALSE;
5892 /* BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2 */
5893 val8 = rtw_read8(padapter, REG_TDECTRL + 2);
5894 *val = (BIT(0) & val8) ? _TRUE : _FALSE;
5898 case HW_VAR_FWLPS_RF_ON: {
5899 /* When we halt NIC, we should check if FW LPS is leave. */
5902 if (rtw_is_surprise_removed(padapter) ||
5903 (adapter_to_pwrctl(padapter)->rf_pwrstate == rf_off)) {
5904 /* If it is in HW/SW Radio OFF or IPS state, we do not check Fw LPS Leave, */
5905 /* because Fw is unload. */
5908 valRCR = rtw_read32(padapter, REG_RCR);
5909 valRCR &= 0x00070000;
5918 case HW_VAR_EFUSE_USAGE:
5919 *val = pHalData->EfuseUsedPercentage;
5922 case HW_VAR_EFUSE_BYTES:
5923 *((u16 *)val) = pHalData->EfuseUsedBytes;
5926 case HW_VAR_EFUSE_BT_USAGE:
5927 #ifdef HAL_EFUSE_MEMORY
5928 *val = pHalData->EfuseHal.BTEfuseUsedPercentage;
5932 case HW_VAR_EFUSE_BT_BYTES:
5933 #ifdef HAL_EFUSE_MEMORY
5934 *((u16 *)val) = pHalData->EfuseHal.BTEfuseUsedBytes;
5936 *((u16 *)val) = BTEfuseUsedBytes;
5940 case HW_VAR_CHK_HI_QUEUE_EMPTY:
5941 val16 = rtw_read16(padapter, REG_TXPKT_EMPTY);
5942 *val = (val16 & BIT(10)) ? _TRUE : _FALSE;
5944 #ifdef CONFIG_WOWLAN
5945 case HW_VAR_RPWM_TOG:
5946 *val = rtw_read8(padapter, SDIO_LOCAL_BASE | SDIO_REG_HRPWM1) & BIT7;
5948 case HW_VAR_WAKEUP_REASON:
5949 *val = rtw_read8(padapter, REG_WOWLAN_WAKE_REASON);
5953 case HW_VAR_SYS_CLKR:
5954 *val = rtw_read8(padapter, REG_SYS_CLKR);
5957 case HW_VAR_DUMP_MAC_QUEUE_INFO:
5958 dump_mac_qinfo_8703b(val, padapter);
5961 GetHwReg(padapter, variable, val);
5968 * Change default setting of specified variable.
5970 u8 SetHalDefVar8703B(PADAPTER padapter, HAL_DEF_VARIABLE variable, void *pval)
5972 PHAL_DATA_TYPE pHalData;
5976 pHalData = GET_HAL_DATA(padapter);
5981 bResult = SetHalDefVar(padapter, variable, pval);
5988 void hal_ra_info_dump(_adapter *padapter , void *sel)
5993 u32 ra_info1, ra_info2, bw_set;
5994 u32 rate_mask1, rate_mask2;
5995 u8 curr_tx_rate, curr_tx_sgi, hight_rate, lowest_rate;
5996 struct dvobj_priv *dvobj = adapter_to_dvobj(padapter);
5997 struct macid_ctl_t *macid_ctl = dvobj_to_macidctl(dvobj);
5998 HAL_DATA_TYPE *HalData = GET_HAL_DATA(padapter);
6000 for (i = 0; i < macid_ctl->num; i++) {
6002 if (rtw_macid_is_used(macid_ctl, i) && !rtw_macid_is_bmc(macid_ctl, i)) {
6005 _RTW_PRINT_SEL(sel , "============ RA status check Mac_id:%d ===================\n", mac_id);
6007 cmd = 0x40000100 | mac_id;
6008 rtw_write32(padapter, REG_HMEBOX_DBG_2_8703B, cmd);
6010 ra_info1 = rtw_read32(padapter, 0x2F0);
6011 curr_tx_rate = ra_info1 & 0x7F;
6012 curr_tx_sgi = (ra_info1 >> 7) & 0x01;
6014 _RTW_PRINT_SEL(sel , "[ ra_info1:0x%08x ] =>cur_tx_rate= %s,cur_sgi:%d\n", ra_info1, HDATA_RATE(curr_tx_rate), curr_tx_sgi);
6015 _RTW_PRINT_SEL(sel , "[ ra_info1:0x%08x ] => PWRSTS = 0x%02x\n", ra_info1, (ra_info1 >> 8) & 0x07);
6017 cmd = 0x40000400 | mac_id;
6018 rtw_write32(padapter, REG_HMEBOX_DBG_2_8703B, cmd);
6020 ra_info1 = rtw_read32(padapter, 0x2F0);
6021 ra_info2 = rtw_read32(padapter, 0x2F4);
6022 rate_mask1 = rtw_read32(padapter, 0x2F8);
6023 rate_mask2 = rtw_read32(padapter, 0x2FC);
6024 hight_rate = ra_info2 & 0xFF;
6025 lowest_rate = (ra_info2 >> 8) & 0xFF;
6026 bw_set = (ra_info1 >> 8) & 0xFF;
6028 _RTW_PRINT_SEL(sel , "[ ra_info1:0x%08x ] => VHT_EN=0x%02x, ", ra_info1, (ra_info1 >> 24) & 0xFF);
6033 case CHANNEL_WIDTH_20:
6034 _RTW_PRINT_SEL(sel , "BW_setting=20M\n");
6037 case CHANNEL_WIDTH_40:
6038 _RTW_PRINT_SEL(sel , "BW_setting=40M\n");
6041 case CHANNEL_WIDTH_80:
6042 _RTW_PRINT_SEL(sel , "BW_setting=80M\n");
6045 case CHANNEL_WIDTH_160:
6046 _RTW_PRINT_SEL(sel , "BW_setting=160M\n");
6050 _RTW_PRINT_SEL(sel , "BW_setting=0x%02x\n", bw_set);
6055 _RTW_PRINT_SEL(sel , "[ ra_info1:0x%08x ] =>RSSI=%d, DISRA=0x%02x\n",
6058 (ra_info1 >> 16) & 0xFF);
6060 _RTW_PRINT_SEL(sel , "[ ra_info2:0x%08x ] =>hight_rate=%s, lowest_rate=%s, SGI=0x%02x, RateID=%d\n",
6062 HDATA_RATE(hight_rate),
6063 HDATA_RATE(lowest_rate),
6064 (ra_info2 >> 16) & 0xFF,
6065 (ra_info2 >> 24) & 0xFF);
6067 _RTW_PRINT_SEL(sel , "rate_mask2=0x%08x, rate_mask1=0x%08x\n", rate_mask2, rate_mask1);
6075 * Query setting of specified variable.
6077 u8 GetHalDefVar8703B(PADAPTER padapter, HAL_DEF_VARIABLE variable, void *pval)
6079 PHAL_DATA_TYPE pHalData;
6083 pHalData = GET_HAL_DATA(padapter);
6087 case HAL_DEF_MAX_RECVBUF_SZ:
6088 *((u32 *)pval) = MAX_RECVBUF_SZ;
6091 case HAL_DEF_RX_PACKET_OFFSET:
6092 *((u32 *)pval) = RXDESC_SIZE + DRVINFO_SZ * 8;
6095 case HW_VAR_MAX_RX_AMPDU_FACTOR:
6096 /* Stanley@BB.SD3 suggests 16K can get stable performance */
6097 /* The experiment was done on SDIO interface */
6098 /* coding by Lucas@20130730 */
6099 *(HT_CAP_AMPDU_FACTOR *)pval = MAX_AMPDU_FACTOR_16K;
6101 case HW_VAR_BEST_AMPDU_DENSITY:
6102 *((u32 *)pval) = AMPDU_DENSITY_VALUE_7;
6104 case HAL_DEF_TX_LDPC:
6105 case HAL_DEF_RX_LDPC:
6106 *((u8 *)pval) = _FALSE;
6108 case HAL_DEF_TX_STBC:
6111 case HAL_DEF_RX_STBC:
6114 case HAL_DEF_EXPLICIT_BEAMFORMER:
6115 case HAL_DEF_EXPLICIT_BEAMFORMEE:
6116 *((u8 *)pval) = _FALSE;
6119 case HW_DEF_RA_INFO_DUMP:
6120 hal_ra_info_dump(padapter, pval);
6123 case HAL_DEF_TX_PAGE_BOUNDARY:
6124 if (!padapter->registrypriv.wifi_spec)
6125 *(u8 *)pval = TX_PAGE_BOUNDARY_8703B;
6127 *(u8 *)pval = WMM_NORMAL_TX_PAGE_BOUNDARY_8703B;
6130 case HAL_DEF_MACID_SLEEP:
6131 *(u8 *)pval = _TRUE; /* support macid sleep */
6133 case HAL_DEF_TX_PAGE_SIZE:
6134 *((u32 *)pval) = PAGE_SIZE_128;
6136 case HAL_DEF_RX_DMA_SZ_WOW:
6137 *(u32 *)pval = RX_DMA_SIZE_8703B - RESV_FMWF;
6139 case HAL_DEF_RX_DMA_SZ:
6140 *(u32 *)pval = RX_DMA_BOUNDARY_8703B + 1;
6142 case HAL_DEF_RX_PAGE_SIZE:
6146 bResult = GetHalDefVar(padapter, variable, pval);
6153 #ifdef CONFIG_WOWLAN
6154 void Hal_DetectWoWMode(PADAPTER pAdapter)
6156 adapter_to_pwrctl(pAdapter)->bSupportRemoteWakeup = _TRUE;
6157 RTW_INFO("%s\n", __func__);
6159 #endif /* CONFIG_WOWLAN */
6161 void rtl8703b_start_thread(_adapter *padapter)
6163 #if (defined CONFIG_SDIO_HCI) || (defined CONFIG_GSPI_HCI)
6164 #ifndef CONFIG_SDIO_TX_TASKLET
6165 struct xmit_priv *xmitpriv = &padapter->xmitpriv;
6167 xmitpriv->SdioXmitThread = kthread_run(rtl8703bs_xmit_thread, padapter, "RTWHALXT");
6168 if (IS_ERR(xmitpriv->SdioXmitThread))
6169 RTW_ERR("%s: start rtl8703bs_xmit_thread FAIL!!\n", __func__);
6174 void rtl8703b_stop_thread(_adapter *padapter)
6176 #if (defined CONFIG_SDIO_HCI) || (defined CONFIG_GSPI_HCI)
6177 #ifndef CONFIG_SDIO_TX_TASKLET
6178 struct xmit_priv *xmitpriv = &padapter->xmitpriv;
6180 /* stop xmit_buf_thread */
6181 if (xmitpriv->SdioXmitThread) {
6182 _rtw_up_sema(&xmitpriv->SdioXmitSema);
6183 _rtw_down_sema(&xmitpriv->SdioXmitTerminateSema);
6184 xmitpriv->SdioXmitThread = 0;
6190 #if defined(CONFIG_CHECK_BT_HANG) && defined(CONFIG_BT_COEXIST)
6191 extern void check_bt_status_work(void *data);
6192 void rtl8703bs_init_checkbthang_workqueue(_adapter *adapter)
6194 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 37))
6195 adapter->priv_checkbt_wq = alloc_workqueue("sdio_wq", 0, 0);
6197 adapter->priv_checkbt_wq = create_workqueue("sdio_wq");
6199 INIT_DELAYED_WORK(&adapter->checkbt_work, (void *)check_bt_status_work);
6202 void rtl8703bs_free_checkbthang_workqueue(_adapter *adapter)
6204 if (adapter->priv_checkbt_wq) {
6205 cancel_delayed_work_sync(&adapter->checkbt_work);
6206 flush_workqueue(adapter->priv_checkbt_wq);
6207 destroy_workqueue(adapter->priv_checkbt_wq);
6208 adapter->priv_checkbt_wq = NULL;
6212 void rtl8703bs_cancle_checkbthang_workqueue(_adapter *adapter)
6214 if (adapter->priv_checkbt_wq)
6215 cancel_delayed_work_sync(&adapter->checkbt_work);
6218 void rtl8703bs_hal_check_bt_hang(_adapter *adapter)
6220 if (adapter->priv_checkbt_wq)
6221 queue_delayed_work(adapter->priv_checkbt_wq, &(adapter->checkbt_work), 0);
6225 void rtl8703b_set_hal_ops(struct hal_ops *pHalFunc)
6227 pHalFunc->dm_init = &rtl8703b_init_dm_priv;
6228 pHalFunc->dm_deinit = &rtl8703b_deinit_dm_priv;
6230 pHalFunc->read_chip_version = read_chip_version_8703b;
6232 pHalFunc->update_ra_mask_handler = update_ra_mask_8703b;
6234 pHalFunc->set_chnl_bw_handler = &PHY_SetSwChnlBWMode8703B;
6236 pHalFunc->set_tx_power_level_handler = &PHY_SetTxPowerLevel8703B;
6237 pHalFunc->get_tx_power_level_handler = &PHY_GetTxPowerLevel8703B;
6239 pHalFunc->get_tx_power_index_handler = &PHY_GetTxPowerIndex_8703B;
6241 pHalFunc->hal_dm_watchdog = &rtl8703b_HalDmWatchDog;
6242 #ifdef CONFIG_LPS_LCLK_WD_TIMER
6243 pHalFunc->hal_dm_watchdog_in_lps = &rtl8703b_HalDmWatchDog_in_LPS;
6246 pHalFunc->SetBeaconRelatedRegistersHandler = &rtl8703b_SetBeaconRelatedRegisters;
6248 pHalFunc->run_thread = &rtl8703b_start_thread;
6249 pHalFunc->cancel_thread = &rtl8703b_stop_thread;
6251 pHalFunc->read_bbreg = &PHY_QueryBBReg_8703B;
6252 pHalFunc->write_bbreg = &PHY_SetBBReg_8703B;
6253 pHalFunc->read_rfreg = &PHY_QueryRFReg_8703B;
6254 pHalFunc->write_rfreg = &PHY_SetRFReg_8703B;
6256 /* Efuse related function */
6257 pHalFunc->BTEfusePowerSwitch = &Hal_BT_EfusePowerSwitch;
6258 pHalFunc->EfusePowerSwitch = &Hal_EfusePowerSwitch;
6259 pHalFunc->ReadEFuse = &Hal_ReadEFuse;
6260 pHalFunc->EFUSEGetEfuseDefinition = &Hal_GetEfuseDefinition;
6261 pHalFunc->EfuseGetCurrentSize = &Hal_EfuseGetCurrentSize;
6262 pHalFunc->Efuse_PgPacketRead = &Hal_EfusePgPacketRead;
6263 pHalFunc->Efuse_PgPacketWrite = &Hal_EfusePgPacketWrite;
6264 pHalFunc->Efuse_WordEnableDataWrite = &Hal_EfuseWordEnableDataWrite;
6265 pHalFunc->Efuse_PgPacketWrite_BT = &Hal_EfusePgPacketWrite_BT;
6267 #ifdef DBG_CONFIG_ERROR_DETECT
6268 pHalFunc->sreset_init_value = &sreset_init_value;
6269 pHalFunc->sreset_reset_value = &sreset_reset_value;
6270 pHalFunc->silentreset = &sreset_reset;
6271 pHalFunc->sreset_xmit_status_check = &rtl8703b_sreset_xmit_status_check;
6272 pHalFunc->sreset_linked_status_check = &rtl8703b_sreset_linked_status_check;
6273 pHalFunc->sreset_get_wifi_status = &sreset_get_wifi_status;
6274 pHalFunc->sreset_inprogress = &sreset_inprogress;
6276 pHalFunc->GetHalODMVarHandler = GetHalODMVar;
6277 pHalFunc->SetHalODMVarHandler = SetHalODMVar;
6279 #ifdef CONFIG_XMIT_THREAD_MODE
6280 pHalFunc->xmit_thread_handler = &hal_xmit_handler;
6282 pHalFunc->hal_notch_filter = &hal_notch_filter_8703b;
6284 pHalFunc->c2h_handler = c2h_handler_8703b;
6286 pHalFunc->fill_h2c_cmd = &FillH2CCmd8703B;
6287 pHalFunc->fill_fake_txdesc = &rtl8703b_fill_fake_txdesc;
6288 pHalFunc->fw_dl = &rtl8703b_FirmwareDownload;
6289 pHalFunc->hal_get_tx_buff_rsvd_page_num = &GetTxBufferRsvdPageNum8703B;