1 /******************************************************************************
3 * Copyright(c) 2007 - 2011 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 ******************************************************************************/
15 #define _HCI_HAL_INIT_C_
17 #include <osdep_service.h>
18 #include <drv_types.h>
19 #include <rtw_efuse.h>
21 #include <HalPwrSeqCmd.h>
22 #include <Hal8723PwrSeq.h>
23 #include <rtl8723a_hal.h>
24 #include <rtl8723a_led.h>
25 #include <linux/ieee80211.h>
30 _ConfigChipOutEP(struct rtw_adapter *pAdapter, u8 NumOutPipe)
33 struct hal_data_8723a *pHalData = GET_HAL_DATA(pAdapter);
35 pHalData->OutEpQueueSel = 0;
36 pHalData->OutEpNumber = 0;
38 /* Normal and High queue */
39 value8 = rtl8723au_read8(pAdapter, (REG_NORMAL_SIE_EP + 1));
41 if (value8 & USB_NORMAL_SIE_EP_MASK) {
42 pHalData->OutEpQueueSel |= TX_SELE_HQ;
43 pHalData->OutEpNumber++;
46 if ((value8 >> USB_NORMAL_SIE_EP_SHIFT) & USB_NORMAL_SIE_EP_MASK) {
47 pHalData->OutEpQueueSel |= TX_SELE_NQ;
48 pHalData->OutEpNumber++;
52 value8 = rtl8723au_read8(pAdapter, (REG_NORMAL_SIE_EP + 2));
53 if (value8 & USB_NORMAL_SIE_EP_MASK) {
54 pHalData->OutEpQueueSel |= TX_SELE_LQ;
55 pHalData->OutEpNumber++;
58 /* TODO: Error recovery for this case */
59 /* RT_ASSERT((NumOutPipe == pHalData->OutEpNumber),
60 ("Out EP number isn't match! %d(Descriptor) != %d (SIE reg)\n",
61 (u32)NumOutPipe, (u32)pHalData->OutEpNumber)); */
64 static bool rtl8723au_set_queue_pipe_mapping(struct rtw_adapter *pAdapter,
65 u8 NumInPipe, u8 NumOutPipe)
67 struct hal_data_8723a *pHalData = GET_HAL_DATA(pAdapter);
70 _ConfigChipOutEP(pAdapter, NumOutPipe);
72 /* Normal chip with one IN and one OUT doesn't have interrupt IN EP. */
73 if (pHalData->OutEpNumber == 1) {
78 result = Hal_MappingOutPipe23a(pAdapter, NumOutPipe);
83 void rtl8723au_chip_configure(struct rtw_adapter *padapter)
85 struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
86 struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
88 pHalData->interfaceIndex = pdvobjpriv->InterfaceNumber;
90 rtl8723au_set_queue_pipe_mapping(padapter,
91 pdvobjpriv->RtNumInPipes,
92 pdvobjpriv->RtNumOutPipes);
95 static int _InitPowerOn(struct rtw_adapter *padapter)
97 int status = _SUCCESS;
101 /* RSV_CTRL 0x1C[7:0] = 0x00
102 unlock ISO/CLK/Power control register */
103 rtl8723au_write8(padapter, REG_RSV_CTRL, 0x0);
105 /* HW Power on sequence */
106 if (!HalPwrSeqCmdParsing23a(padapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
107 PWR_INTF_USB_MSK, rtl8723AU_card_enable_flow))
110 /* 0x04[19] = 1, suggest by Jackie 2011.05.09, reset 8051 */
111 value8 = rtl8723au_read8(padapter, REG_APS_FSMCO+2);
112 rtl8723au_write8(padapter, REG_APS_FSMCO + 2, value8 | BIT(3));
114 /* Enable MAC DMA/WMAC/SCHEDULE/SEC block */
115 /* Set CR bit10 to enable 32k calibration. Suggested by SD1 Gimmy.
116 Added by tynli. 2011.08.31. */
117 value16 = rtl8723au_read16(padapter, REG_CR);
118 value16 |= (HCI_TXDMA_EN | HCI_RXDMA_EN | TXDMA_EN | RXDMA_EN |
119 PROTOCOL_EN | SCHEDULE_EN | MACTXEN | MACRXEN |
121 rtl8723au_write16(padapter, REG_CR, value16);
123 /* for Efuse PG, suggest by Jackie 2011.11.23 */
124 PHY_SetBBReg(padapter, REG_EFUSE_CTRL, BIT(28)|BIT(29)|BIT(30), 0x06);
129 /* Shall USB interface init this? */
130 static void _InitInterrupt(struct rtw_adapter *Adapter)
134 /* HISR - turn all on */
135 value32 = 0xFFFFFFFF;
136 rtl8723au_write32(Adapter, REG_HISR, value32);
138 /* HIMR - turn all on */
139 rtl8723au_write32(Adapter, REG_HIMR, value32);
142 static void _InitQueueReservedPage(struct rtw_adapter *Adapter)
144 struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
145 struct registry_priv *pregistrypriv = &Adapter->registrypriv;
152 bool bWiFiConfig = pregistrypriv->wifi_spec;
154 /* RT_ASSERT((outEPNum>= 2), ("for WMM , number of out-ep "
155 "must more than or equal to 2!\n")); */
157 numPubQ = bWiFiConfig ? WMM_NORMAL_PAGE_NUM_PUBQ : NORMAL_PAGE_NUM_PUBQ;
159 if (pHalData->OutEpQueueSel & TX_SELE_HQ) {
160 numHQ = bWiFiConfig ?
161 WMM_NORMAL_PAGE_NUM_HPQ : NORMAL_PAGE_NUM_HPQ;
164 if (pHalData->OutEpQueueSel & TX_SELE_LQ) {
165 numLQ = bWiFiConfig ?
166 WMM_NORMAL_PAGE_NUM_LPQ : NORMAL_PAGE_NUM_LPQ;
168 /* NOTE: This step shall be proceed before
169 writting REG_RQPN. */
170 if (pHalData->OutEpQueueSel & TX_SELE_NQ) {
171 numNQ = bWiFiConfig ?
172 WMM_NORMAL_PAGE_NUM_NPQ : NORMAL_PAGE_NUM_NPQ;
174 value8 = (u8)_NPQ(numNQ);
175 rtl8723au_write8(Adapter, REG_RQPN_NPQ, value8);
178 value32 = _HPQ(numHQ) | _LPQ(numLQ) | _PUBQ(numPubQ) | LD_RQPN;
179 rtl8723au_write32(Adapter, REG_RQPN, value32);
182 static void _InitTxBufferBoundary(struct rtw_adapter *Adapter)
184 struct registry_priv *pregistrypriv = &Adapter->registrypriv;
188 if (!pregistrypriv->wifi_spec)
189 txpktbuf_bndy = TX_PAGE_BOUNDARY;
191 txpktbuf_bndy = WMM_NORMAL_TX_PAGE_BOUNDARY;
193 rtl8723au_write8(Adapter, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy);
194 rtl8723au_write8(Adapter, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy);
195 rtl8723au_write8(Adapter, REG_TXPKTBUF_WMAC_LBK_BF_HD, txpktbuf_bndy);
196 rtl8723au_write8(Adapter, REG_TRXFF_BNDY, txpktbuf_bndy);
197 rtl8723au_write8(Adapter, REG_TDECTRL+1, txpktbuf_bndy);
200 static void _InitPageBoundary(struct rtw_adapter *Adapter)
202 /* RX Page Boundary */
203 /* srand(static_cast<unsigned int>(time(NULL))); */
204 u16 rxff_bndy = 0x27FF;/* rand() % 1) ? 0x27FF : 0x23FF; */
206 rtl8723au_write16(Adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
208 /* TODO: ?? shall we set tx boundary? */
212 _InitNormalChipRegPriority(struct rtw_adapter *Adapter, u16 beQ, u16 bkQ,
213 u16 viQ, u16 voQ, u16 mgtQ, u16 hiQ)
215 u16 value16 = rtl8723au_read16(Adapter, REG_TRXDMA_CTRL) & 0x7;
217 value16 |= _TXDMA_BEQ_MAP(beQ) | _TXDMA_BKQ_MAP(bkQ) |
218 _TXDMA_VIQ_MAP(viQ) | _TXDMA_VOQ_MAP(voQ) |
219 _TXDMA_MGQ_MAP(mgtQ) | _TXDMA_HIQ_MAP(hiQ);
221 rtl8723au_write16(Adapter, REG_TRXDMA_CTRL, value16);
224 static void _InitNormalChipOneOutEpPriority(struct rtw_adapter *Adapter)
226 struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
229 switch (pHalData->OutEpQueueSel) {
237 value = QUEUE_NORMAL;
240 /* RT_ASSERT(false, ("Shall not reach here!\n")); */
244 _InitNormalChipRegPriority(Adapter, value, value, value,
245 value, value, value);
248 static void _InitNormalChipTwoOutEpPriority(struct rtw_adapter *Adapter)
250 struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
251 struct registry_priv *pregistrypriv = &Adapter->registrypriv;
252 u16 beQ, bkQ, viQ, voQ, mgtQ, hiQ;
256 switch (pHalData->OutEpQueueSel) {
257 case (TX_SELE_HQ | TX_SELE_LQ):
258 valueHi = QUEUE_HIGH;
259 valueLow = QUEUE_LOW;
261 case (TX_SELE_NQ | TX_SELE_LQ):
262 valueHi = QUEUE_NORMAL;
263 valueLow = QUEUE_LOW;
265 case (TX_SELE_HQ | TX_SELE_NQ):
266 valueHi = QUEUE_HIGH;
267 valueLow = QUEUE_NORMAL;
270 /* RT_ASSERT(false, ("Shall not reach here!\n")); */
274 if (!pregistrypriv->wifi_spec) {
281 } else {/* for WMM , CONFIG_OUT_EP_WIFI_MODE */
290 _InitNormalChipRegPriority(Adapter, beQ, bkQ, viQ, voQ, mgtQ, hiQ);
293 static void _InitNormalChipThreeOutEpPriority(struct rtw_adapter *Adapter)
295 struct registry_priv *pregistrypriv = &Adapter->registrypriv;
296 u16 beQ, bkQ, viQ, voQ, mgtQ, hiQ;
298 if (!pregistrypriv->wifi_spec) {/* typical setting */
305 } else {/* for WMM */
313 _InitNormalChipRegPriority(Adapter, beQ, bkQ, viQ, voQ, mgtQ, hiQ);
316 static void _InitNormalChipQueuePriority(struct rtw_adapter *Adapter)
318 struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
320 switch (pHalData->OutEpNumber) {
322 _InitNormalChipOneOutEpPriority(Adapter);
325 _InitNormalChipTwoOutEpPriority(Adapter);
328 _InitNormalChipThreeOutEpPriority(Adapter);
331 /* RT_ASSERT(false, ("Shall not reach here!\n")); */
336 static void _InitQueuePriority(struct rtw_adapter *Adapter)
338 _InitNormalChipQueuePriority(Adapter);
341 static void _InitTransferPageSize(struct rtw_adapter *Adapter)
343 /* Tx page size is always 128. */
346 value8 = _PSRX(PBP_128) | _PSTX(PBP_128);
347 rtl8723au_write8(Adapter, REG_PBP, value8);
350 static void _InitDriverInfoSize(struct rtw_adapter *Adapter, u8 drvInfoSize)
352 rtl8723au_write8(Adapter, REG_RX_DRVINFO_SZ, drvInfoSize);
355 static void _InitWMACSetting(struct rtw_adapter *Adapter)
357 struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
359 /* don't turn on AAP, it will allow all packets to driver */
360 pHalData->ReceiveConfig = RCR_APM | RCR_AM | RCR_AB | RCR_CBSSID_DATA |
361 RCR_CBSSID_BCN | RCR_APP_ICV | RCR_AMF |
362 RCR_HTC_LOC_CTRL | RCR_APP_MIC |
365 /* some REG_RCR will be modified later by
366 phy_ConfigMACWithHeaderFile() */
367 rtl8723au_write32(Adapter, REG_RCR, pHalData->ReceiveConfig);
369 /* Accept all multicast address */
370 rtl8723au_write32(Adapter, REG_MAR, 0xFFFFFFFF);
371 rtl8723au_write32(Adapter, REG_MAR + 4, 0xFFFFFFFF);
373 /* Accept all data frames */
374 /* value16 = 0xFFFF; */
375 /* rtl8723au_write16(Adapter, REG_RXFLTMAP2, value16); */
377 /* 2010.09.08 hpfan */
378 /* Since ADF is removed from RCR, ps-poll will not be indicate
380 /* RxFilterMap should mask ps-poll to gurantee AP mode can
382 /* value16 = 0x400; */
383 /* rtl8723au_write16(Adapter, REG_RXFLTMAP1, value16); */
385 /* Accept all management frames */
386 /* value16 = 0xFFFF; */
387 /* rtl8723au_write16(Adapter, REG_RXFLTMAP0, value16); */
389 /* enable RX_SHIFT bits */
390 /* rtl8723au_write8(Adapter, REG_TRXDMA_CTRL, rtl8723au_read8(Adapter,
391 REG_TRXDMA_CTRL)|BIT(1)); */
394 static void _InitAdaptiveCtrl(struct rtw_adapter *Adapter)
399 /* Response Rate Set */
400 value32 = rtl8723au_read32(Adapter, REG_RRSR);
401 value32 &= ~RATE_BITMAP_ALL;
402 value32 |= RATE_RRSR_CCK_ONLY_1M;
403 rtl8723au_write32(Adapter, REG_RRSR, value32);
405 /* CF-END Threshold */
406 /* m_spIoBase->rtl8723au_write8(REG_CFEND_TH, 0x1); */
408 /* SIFS (used in NAV) */
409 value16 = _SPEC_SIFS_CCK(0x10) | _SPEC_SIFS_OFDM(0x10);
410 rtl8723au_write16(Adapter, REG_SPEC_SIFS, value16);
413 value16 = _LRL(0x30) | _SRL(0x30);
414 rtl8723au_write16(Adapter, REG_RL, value16);
417 static void _InitRateFallback(struct rtw_adapter *Adapter)
419 /* Set Data Auto Rate Fallback Retry Count register. */
420 rtl8723au_write32(Adapter, REG_DARFRC, 0x00000000);
421 rtl8723au_write32(Adapter, REG_DARFRC+4, 0x10080404);
422 rtl8723au_write32(Adapter, REG_RARFRC, 0x04030201);
423 rtl8723au_write32(Adapter, REG_RARFRC+4, 0x08070605);
426 static void _InitEDCA(struct rtw_adapter *Adapter)
428 /* Set Spec SIFS (used in NAV) */
429 rtl8723au_write16(Adapter, REG_SPEC_SIFS, 0x100a);
430 rtl8723au_write16(Adapter, REG_MAC_SPEC_SIFS, 0x100a);
432 /* Set SIFS for CCK */
433 rtl8723au_write16(Adapter, REG_SIFS_CTX, 0x100a);
435 /* Set SIFS for OFDM */
436 rtl8723au_write16(Adapter, REG_SIFS_TRX, 0x100a);
439 rtl8723au_write32(Adapter, REG_EDCA_BE_PARAM, 0x005EA42B);
440 rtl8723au_write32(Adapter, REG_EDCA_BK_PARAM, 0x0000A44F);
441 rtl8723au_write32(Adapter, REG_EDCA_VI_PARAM, 0x005EA324);
442 rtl8723au_write32(Adapter, REG_EDCA_VO_PARAM, 0x002FA226);
445 static void _InitHWLed(struct rtw_adapter *Adapter)
447 struct led_priv *pledpriv = &Adapter->ledpriv;
449 if (pledpriv->LedStrategy != HW_LED)
454 /* must consider cases of antenna diversity/ commbo card/solo card/mini card */
457 static void _InitRDGSetting(struct rtw_adapter *Adapter)
459 rtl8723au_write8(Adapter, REG_RD_CTRL, 0xFF);
460 rtl8723au_write16(Adapter, REG_RD_NAV_NXT, 0x200);
461 rtl8723au_write8(Adapter, REG_RD_RESP_PKT_TH, 0x05);
464 static void _InitRetryFunction(struct rtw_adapter *Adapter)
468 value8 = rtl8723au_read8(Adapter, REG_FWHW_TXQ_CTRL);
469 value8 |= EN_AMPDU_RTY_NEW;
470 rtl8723au_write8(Adapter, REG_FWHW_TXQ_CTRL, value8);
472 /* Set ACK timeout */
473 rtl8723au_write8(Adapter, REG_ACKTO, 0x40);
476 static void _InitRFType(struct rtw_adapter *Adapter)
478 struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
479 bool is92CU = IS_92C_SERIAL(pHalData->VersionID);
481 pHalData->rf_chip = RF_6052;
483 if (is92CU == false) {
484 pHalData->rf_type = RF_1T1R;
485 DBG_8723A("Set RF Chip ID to RF_6052 and RF type to 1T1R.\n");
489 /* TODO: Consider that EEPROM set 92CU to 1T1R later. */
490 /* Force to overwrite setting according to chip version. Ignore
492 /* pHalData->RF_Type = is92CU ? RF_2T2R : RF_1T1R; */
493 MSG_8723A("Set RF Chip ID to RF_6052 and RF type to %d.\n",
497 /* Set CCK and OFDM Block "ON" */
498 static void _BBTurnOnBlock(struct rtw_adapter *Adapter)
500 PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bCCKEn, 0x1);
501 PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bOFDMEn, 0x1);
504 #define MgntActSet_RF_State(...)
505 static void _RfPowerSave(struct rtw_adapter *padapter)
514 enum rt_rf_power_state RfOnOffDetect23a(struct rtw_adapter *pAdapter)
516 /* struct hal_data_8723a *pHalData = GET_HAL_DATA(pAdapter); */
518 enum rt_rf_power_state rfpowerstate = rf_off;
520 if (pAdapter->pwrctrlpriv.bHWPowerdown) {
521 val8 = rtl8723au_read8(pAdapter, REG_HSISR);
522 DBG_8723A("pwrdown, 0x5c(BIT7) =%02x\n", val8);
523 rfpowerstate = (val8 & BIT(7)) ? rf_off : rf_on;
524 } else { /* rf on/off */
525 rtl8723au_write8(pAdapter, REG_MAC_PINMUX_CFG,
526 rtl8723au_read8(pAdapter, REG_MAC_PINMUX_CFG) &
528 val8 = rtl8723au_read8(pAdapter, REG_GPIO_IO_SEL);
529 DBG_8723A("GPIO_IN =%02x\n", val8);
530 rfpowerstate = (val8 & BIT(3)) ? rf_on : rf_off;
533 } /* HalDetectPwrDownMode */
535 void _ps_open_RF23a(struct rtw_adapter *padapter);
537 int rtl8723au_hal_init(struct rtw_adapter *Adapter)
541 int status = _SUCCESS;
542 struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
543 struct pwrctrl_priv *pwrctrlpriv = &Adapter->pwrctrlpriv;
544 struct registry_priv *pregistrypriv = &Adapter->registrypriv;
546 unsigned long init_start_time = jiffies;
548 Adapter->hw_init_completed = false;
550 if (Adapter->pwrctrlpriv.bkeepfwalive) {
551 _ps_open_RF23a(Adapter);
553 if (pHalData->bIQKInitialized) {
554 rtl8723a_phy_iq_calibrate(Adapter, true);
556 rtl8723a_phy_iq_calibrate(Adapter, false);
557 pHalData->bIQKInitialized = true;
559 rtl8723a_odm_check_tx_power_tracking(Adapter);
560 rtl8723a_phy_lc_calibrate(Adapter);
565 /* Check if MAC has already power on. by tynli. 2011.05.27. */
566 val8 = rtl8723au_read8(Adapter, REG_CR);
567 RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
568 ("%s: REG_CR 0x100 = 0x%02x\n", __func__, val8));
569 /* Fix 92DU-VC S3 hang with the reason is that secondary mac is not
571 /* 0x100 value of first mac is 0xEA while 0x100 value of secondary
574 pHalData->bMACFuncEnable = false;
576 pHalData->bMACFuncEnable = true;
577 RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
578 ("%s: MAC has already power on\n", __func__));
581 status = _InitPowerOn(Adapter);
582 if (status == _FAIL) {
583 RT_TRACE(_module_hci_hal_init_c_, _drv_err_,
584 ("Failed to init power on!\n"));
588 if (!pregistrypriv->wifi_spec) {
589 boundary = TX_PAGE_BOUNDARY;
592 boundary = WMM_NORMAL_TX_PAGE_BOUNDARY;
595 if (!pHalData->bMACFuncEnable) {
596 status = InitLLTTable23a(Adapter, boundary);
597 if (status == _FAIL) {
598 RT_TRACE(_module_hci_hal_init_c_, _drv_err_,
599 ("Failed to init LLT table\n"));
604 if (pHalData->bRDGEnable)
605 _InitRDGSetting(Adapter);
607 status = rtl8723a_FirmwareDownload(Adapter);
608 if (status != _SUCCESS) {
609 Adapter->bFWReady = false;
610 pHalData->fw_ractrl = false;
611 DBG_8723A("fw download fail!\n");
614 Adapter->bFWReady = true;
615 pHalData->fw_ractrl = true;
616 DBG_8723A("fw download ok!\n");
619 rtl8723a_InitializeFirmwareVars(Adapter);
621 if (pwrctrlpriv->reg_rfoff == true) {
622 pwrctrlpriv->rf_pwrstate = rf_off;
625 /* 2010/08/09 MH We need to check if we need to turnon or off RF after detecting */
626 /* HW GPIO pin. Before PHY_RFConfig8192C. */
627 /* HalDetectPwrDownMode(Adapter); */
628 /* 2010/08/26 MH If Efuse does not support sective suspend then disable the function. */
629 /* HalDetectSelectiveSuspendMode(Adapter); */
631 /* Set RF type for BB/RF configuration */
632 _InitRFType(Adapter);/* _ReadRFType() */
634 /* Save target channel */
635 /* <Roger_Notes> Current Channel will be updated again later. */
636 pHalData->CurrentChannel = 6;/* default set to 6 */
638 status = PHY_MACConfig8723A(Adapter);
639 if (status == _FAIL) {
640 DBG_8723A("PHY_MACConfig8723A fault !!\n");
645 /* d. Initialize BB related configurations. */
647 status = PHY_BBConfig8723A(Adapter);
648 if (status == _FAIL) {
649 DBG_8723A("PHY_BBConfig8723A fault !!\n");
653 /* Add for tx power by rate fine tune. We need to call the function after BB config. */
654 /* Because the tx power by rate table is inited in BB config. */
656 status = PHY_RF6052_Config8723A(Adapter);
657 if (status == _FAIL) {
658 DBG_8723A("PHY_RF6052_Config8723A failed!!\n");
662 /* reducing 80M spur */
663 PHY_SetBBReg(Adapter, RF_T_METER, bMaskDWord, 0x0381808d);
664 PHY_SetBBReg(Adapter, RF_SYN_G4, bMaskDWord, 0xf2ffff83);
665 PHY_SetBBReg(Adapter, RF_SYN_G4, bMaskDWord, 0xf2ffff82);
666 PHY_SetBBReg(Adapter, RF_SYN_G4, bMaskDWord, 0xf2ffff83);
669 PHY_SetBBReg(Adapter, rFPGA0_TxInfo, bMaskDWord, 0x00000003); /* 0x804[14]= 0 */
670 PHY_SetBBReg(Adapter, rFPGA0_XAB_RFInterfaceSW, bMaskDWord, 0x07000760); /* 0x870[6:5]= b'11 */
671 PHY_SetBBReg(Adapter, rFPGA0_XA_RFInterfaceOE, bMaskDWord, 0x66F60210); /* 0x860[6:5]= b'00 */
673 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("%s: 0x870 = value 0x%x\n", __func__, PHY_QueryBBReg(Adapter, 0x870, bMaskDWord)));
676 /* Joseph Note: Keep RfRegChnlVal for later use. */
678 pHalData->RfRegChnlVal[0] = PHY_QueryRFReg(Adapter, (enum RF_RADIO_PATH)0, RF_CHNLBW, bRFRegOffsetMask);
679 pHalData->RfRegChnlVal[1] = PHY_QueryRFReg(Adapter, (enum RF_RADIO_PATH)1, RF_CHNLBW, bRFRegOffsetMask);
681 if (!pHalData->bMACFuncEnable) {
682 _InitQueueReservedPage(Adapter);
683 _InitTxBufferBoundary(Adapter);
685 _InitQueuePriority(Adapter);
686 _InitPageBoundary(Adapter);
687 _InitTransferPageSize(Adapter);
689 /* Get Rx PHY status in order to report RSSI and others. */
690 _InitDriverInfoSize(Adapter, DRVINFO_SZ);
692 _InitInterrupt(Adapter);
693 hw_var_set_macaddr(Adapter, Adapter->eeprompriv.mac_addr);
694 rtl8723a_set_media_status(Adapter, MSR_INFRA);
695 _InitWMACSetting(Adapter);
696 _InitAdaptiveCtrl(Adapter);
698 _InitRateFallback(Adapter);
699 _InitRetryFunction(Adapter);
700 rtl8723a_InitBeaconParameters(Adapter);
704 _BBTurnOnBlock(Adapter);
705 /* NicIFSetMacAddress(padapter, padapter->PermanentAddress); */
707 rtl8723a_cam_invalidate_all(Adapter);
709 /* 2010/12/17 MH We need to set TX power according to EFUSE content at first. */
710 PHY_SetTxPowerLevel8723A(Adapter, pHalData->CurrentChannel);
712 rtl8723a_InitAntenna_Selection(Adapter);
715 /* set 0x0 to 0xFF by tynli. Default enable HW SEQ NUM. */
716 rtl8723au_write8(Adapter, REG_HWSEQ_CTRL, 0xFF);
719 /* Disable BAR, suggested by Scott */
720 /* 2010.04.09 add by hpfan */
722 rtl8723au_write32(Adapter, REG_BAR_MODE_CTRL, 0x0201ffff);
724 if (pregistrypriv->wifi_spec)
725 rtl8723au_write16(Adapter, REG_FAST_EDCA_CTRL, 0);
727 /* Move by Neo for USB SS from above setp */
728 _RfPowerSave(Adapter);
730 /* 2010/08/26 MH Merge from 8192CE. */
731 /* sherry masked that it has been done in _RfPowerSave */
733 /* recovery for 8192cu and 9723Au 20111017 */
734 if (pwrctrlpriv->rf_pwrstate == rf_on) {
735 if (pHalData->bIQKInitialized) {
736 rtl8723a_phy_iq_calibrate(Adapter, true);
738 rtl8723a_phy_iq_calibrate(Adapter, false);
739 pHalData->bIQKInitialized = true;
742 rtl8723a_odm_check_tx_power_tracking(Adapter);
744 rtl8723a_phy_lc_calibrate(Adapter);
746 rtl8723a_dual_antenna_detection(Adapter);
749 /* fixed USB interface interference issue */
750 rtl8723au_write8(Adapter, 0xfe40, 0xe0);
751 rtl8723au_write8(Adapter, 0xfe41, 0x8d);
752 rtl8723au_write8(Adapter, 0xfe42, 0x80);
753 rtl8723au_write32(Adapter, 0x20c, 0xfd0320);
754 /* Solve too many protocol error on USB bus */
755 if (!IS_81xxC_VENDOR_UMC_A_CUT(pHalData->VersionID)) {
757 rtl8723au_write8(Adapter, 0xFE40, 0xE6);
758 rtl8723au_write8(Adapter, 0xFE41, 0x94);
759 rtl8723au_write8(Adapter, 0xFE42, 0x80);
762 rtl8723au_write8(Adapter, 0xFE40, 0xE0);
763 rtl8723au_write8(Adapter, 0xFE41, 0x19);
764 rtl8723au_write8(Adapter, 0xFE42, 0x80);
767 rtl8723au_write8(Adapter, 0xFE40, 0xE5);
768 rtl8723au_write8(Adapter, 0xFE41, 0x91);
769 rtl8723au_write8(Adapter, 0xFE42, 0x80);
772 rtl8723au_write8(Adapter, 0xFE40, 0xE2);
773 rtl8723au_write8(Adapter, 0xFE41, 0x81);
774 rtl8723au_write8(Adapter, 0xFE42, 0x80);
778 /* _InitPABias(Adapter); */
780 /* Init BT hw config. */
781 rtl8723a_BT_init_hwconfig(Adapter);
783 rtl8723a_InitHalDm(Adapter);
785 val8 = ((WiFiNavUpperUs + HAL_8723A_NAV_UPPER_UNIT - 1) /
786 HAL_8723A_NAV_UPPER_UNIT);
787 rtl8723au_write8(Adapter, REG_NAV_UPPER, val8);
789 /* 2011/03/09 MH debug only, UMC-B cut pass 2500 S5 test, but we need to fin root cause. */
790 if (((rtl8723au_read32(Adapter, rFPGA0_RFMOD) & 0xFF000000) !=
792 PHY_SetBBReg(Adapter, rFPGA0_RFMOD, BIT(24), 1);
793 RT_TRACE(_module_hci_hal_init_c_, _drv_err_, ("%s: IQK fail recorver\n", __func__));
796 /* ack for xmit mgmt frames. */
797 rtl8723au_write32(Adapter, REG_FWHW_TXQ_CTRL,
798 rtl8723au_read32(Adapter, REG_FWHW_TXQ_CTRL)|BIT(12));
801 if (status == _SUCCESS) {
802 Adapter->hw_init_completed = true;
804 if (Adapter->registrypriv.notch_filter == 1)
805 rtl8723a_notch_filter(Adapter, 1);
808 DBG_8723A("%s in %dms\n", __func__,
809 jiffies_to_msecs(jiffies - init_start_time));
813 static void phy_SsPwrSwitch92CU(struct rtw_adapter *Adapter,
814 enum rt_rf_power_state eRFPowerState,
817 struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
821 switch (eRFPowerState) {
823 if (bRegSSPwrLvl == 1) {
824 /* 1. Enable MAC Clock. Can not be enabled now. */
825 /* WriteXBYTE(REG_SYS_CLKR+1,
826 ReadXBYTE(REG_SYS_CLKR+1) | BIT(3)); */
828 /* 2. Force PWM, Enable SPS18_LDO_Marco_Block */
829 rtl8723au_write8(Adapter, REG_SPS0_CTRL,
830 rtl8723au_read8(Adapter, REG_SPS0_CTRL) |
833 /* 3. restore BB, AFE control register. */
835 if (pHalData->rf_type == RF_2T2R)
836 PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter,
839 PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter,
841 PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, 0xf0, 1);
842 PHY_SetBBReg(Adapter, rFPGA0_RFMOD, BIT(1), 0);
845 if (pHalData->rf_type == RF_2T2R)
846 PHY_SetBBReg(Adapter, rRx_Wait_CCA, bMaskDWord,
848 else if (pHalData->rf_type == RF_1T1R)
849 PHY_SetBBReg(Adapter, rRx_Wait_CCA, bMaskDWord,
852 /* 4. issue 3-wire command that RF set to Rx idle
853 mode. This is used to re-write the RX idle mode. */
854 /* We can only prvide a usual value instead and then
855 HW will modify the value by itself. */
856 PHY_SetRFReg(Adapter, RF_PATH_A, 0,
857 bRFRegOffsetMask, 0x32D95);
858 if (pHalData->rf_type == RF_2T2R) {
859 PHY_SetRFReg(Adapter, RF_PATH_B, 0,
860 bRFRegOffsetMask, 0x32D95);
862 } else { /* Level 2 or others. */
863 /* h. AFE_PLL_CTRL 0x28[7:0] = 0x80
865 rtl8723au_write8(Adapter, REG_AFE_PLL_CTRL, 0x81);
867 /* i. AFE_XTAL_CTRL 0x24[15:0] = 0x880F
868 gated AFE DIG_CLOCK */
869 rtl8723au_write16(Adapter, REG_AFE_XTAL_CTRL, 0x800F);
872 /* 2. Force PWM, Enable SPS18_LDO_Marco_Block */
873 rtl8723au_write8(Adapter, REG_SPS0_CTRL,
874 rtl8723au_read8(Adapter, REG_SPS0_CTRL) |
877 /* 3. restore BB, AFE control register. */
879 if (pHalData->rf_type == RF_2T2R)
880 PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter,
883 PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter,
885 PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, 0xf0, 1);
886 PHY_SetBBReg(Adapter, rFPGA0_RFMOD, BIT(1), 0);
889 if (pHalData->rf_type == RF_2T2R)
890 PHY_SetBBReg(Adapter, rRx_Wait_CCA,
891 bMaskDWord, 0x63DB25A0);
892 else if (pHalData->rf_type == RF_1T1R)
893 PHY_SetBBReg(Adapter, rRx_Wait_CCA,
894 bMaskDWord, 0x631B25A0);
896 /* 4. issue 3-wire command that RF set to Rx idle
897 mode. This is used to re-write the RX idle mode. */
898 /* We can only prvide a usual value instead and
899 then HW will modify the value by itself. */
900 PHY_SetRFReg(Adapter, RF_PATH_A, 0,
901 bRFRegOffsetMask, 0x32D95);
902 if (pHalData->rf_type == RF_2T2R) {
903 PHY_SetRFReg(Adapter, RF_PATH_B, 0,
904 bRFRegOffsetMask, 0x32D95);
907 /* 5. gated MAC Clock */
908 bytetmp = rtl8723au_read8(Adapter, REG_APSD_CTRL);
909 rtl8723au_write8(Adapter, REG_APSD_CTRL,
914 /* Set BB reset at first */
916 rtl8723au_write8(Adapter, REG_SYS_FUNC_EN, 0x17);
919 rtl8723au_write8(Adapter, REG_TXPAUSE, 0x0);
924 value8 = rtl8723au_read8(Adapter, REG_SPS0_CTRL) ;
925 if (IS_81xxC_VENDOR_UMC_B_CUT(pHalData->VersionID))
928 value8 &= ~(BIT(0) | BIT(3));
929 if (bRegSSPwrLvl == 1) {
930 RT_TRACE(_module_hal_init_c_, _drv_err_, ("SS LVL1\n"));
931 /* Disable RF and BB only for SelectSuspend. */
933 /* 1. Set BB/RF to shutdown. */
934 /* (1) Reg878[5:3]= 0 RF rx_code for
935 preamble power saving */
936 /* (2)Reg878[21:19]= 0 Turn off RF-B */
937 /* (3) RegC04[7:4]= 0 Turn off all paths
938 for packet detection */
939 /* (4) Reg800[1] = 1 enable preamble power
941 Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_RF0] =
942 PHY_QueryBBReg(Adapter, rFPGA0_XAB_RFParameter,
944 Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_RF1] =
945 PHY_QueryBBReg(Adapter, rOFDM0_TRxPathEnable,
947 Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_RF2] =
948 PHY_QueryBBReg(Adapter, rFPGA0_RFMOD,
950 if (pHalData->rf_type == RF_2T2R) {
951 PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter,
953 } else if (pHalData->rf_type == RF_1T1R) {
954 PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter,
957 PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, 0xf0, 0);
958 PHY_SetBBReg(Adapter, rFPGA0_RFMOD, BIT(1), 1);
960 /* 2 .AFE control register to power down. bit[30:22] */
961 Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_AFE0] =
962 PHY_QueryBBReg(Adapter, rRx_Wait_CCA,
964 if (pHalData->rf_type == RF_2T2R)
965 PHY_SetBBReg(Adapter, rRx_Wait_CCA, bMaskDWord,
967 else if (pHalData->rf_type == RF_1T1R)
968 PHY_SetBBReg(Adapter, rRx_Wait_CCA, bMaskDWord,
971 /* 3. issue 3-wire command that RF set to power down.*/
972 PHY_SetRFReg(Adapter, RF_PATH_A, 0, bRFRegOffsetMask, 0);
973 if (pHalData->rf_type == RF_2T2R)
974 PHY_SetRFReg(Adapter, RF_PATH_B, 0,
975 bRFRegOffsetMask, 0);
977 /* 4. Force PFM , disable SPS18_LDO_Marco_Block */
978 rtl8723au_write8(Adapter, REG_SPS0_CTRL, value8);
979 } else { /* Level 2 or others. */
980 RT_TRACE(_module_hal_init_c_, _drv_err_, ("SS LVL2\n"));
982 u8 eRFPath = RF_PATH_A, value8 = 0;
983 rtl8723au_write8(Adapter, REG_TXPAUSE, 0xFF);
984 PHY_SetRFReg(Adapter,
985 (enum RF_RADIO_PATH)eRFPath,
986 0x0, bMaskByte0, 0x0);
989 rtl8723au_write8(Adapter, REG_APSD_CTRL,
992 /* After switch APSD, we need to delay
996 /* Set BB reset at first */
998 value8 |= (FEN_USBD | FEN_USBA |
1001 rtl8723au_write8(Adapter, REG_SYS_FUNC_EN,
1005 /* Disable RF and BB only for SelectSuspend. */
1007 /* 1. Set BB/RF to shutdown. */
1008 /* (1) Reg878[5:3]= 0 RF rx_code for
1009 preamble power saving */
1010 /* (2)Reg878[21:19]= 0 Turn off RF-B */
1011 /* (3) RegC04[7:4]= 0 Turn off all paths for
1013 /* (4) Reg800[1] = 1 enable preamble power
1015 Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_RF0] =
1016 PHY_QueryBBReg(Adapter, rFPGA0_XAB_RFParameter,
1018 Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_RF1] =
1019 PHY_QueryBBReg(Adapter, rOFDM0_TRxPathEnable,
1021 Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_RF2] =
1022 PHY_QueryBBReg(Adapter, rFPGA0_RFMOD,
1024 if (pHalData->rf_type == RF_2T2R)
1025 PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter,
1027 else if (pHalData->rf_type == RF_1T1R)
1028 PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter,
1030 PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, 0xf0, 0);
1031 PHY_SetBBReg(Adapter, rFPGA0_RFMOD, BIT(1), 1);
1033 /* 2 .AFE control register to power down. bit[30:22] */
1034 Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_AFE0] =
1035 PHY_QueryBBReg(Adapter, rRx_Wait_CCA,
1037 if (pHalData->rf_type == RF_2T2R)
1038 PHY_SetBBReg(Adapter, rRx_Wait_CCA, bMaskDWord,
1040 else if (pHalData->rf_type == RF_1T1R)
1041 PHY_SetBBReg(Adapter, rRx_Wait_CCA, bMaskDWord,
1044 /* 3. issue 3-wire command that RF set to power down. */
1045 PHY_SetRFReg(Adapter, RF_PATH_A, 0, bRFRegOffsetMask, 0);
1046 if (pHalData->rf_type == RF_2T2R)
1047 PHY_SetRFReg(Adapter, RF_PATH_B, 0,
1048 bRFRegOffsetMask, 0);
1050 /* 4. Force PFM , disable SPS18_LDO_Marco_Block */
1051 rtl8723au_write8(Adapter, REG_SPS0_CTRL, value8);
1053 /* 2010/10/13 MH/Isaachsu exchange sequence. */
1054 /* h. AFE_PLL_CTRL 0x28[7:0] = 0x80
1056 rtl8723au_write8(Adapter, REG_AFE_PLL_CTRL, 0x80);
1059 /* i. AFE_XTAL_CTRL 0x24[15:0] = 0x880F
1060 gated AFE DIG_CLOCK */
1061 rtl8723au_write16(Adapter, REG_AFE_XTAL_CTRL, 0xA80F);
1068 } /* phy_PowerSwitch92CU */
1070 void _ps_open_RF23a(struct rtw_adapter *padapter)
1072 /* here call with bRegSSPwrLvl 1, bRegSSPwrLvl 2 needs to be verified */
1073 phy_SsPwrSwitch92CU(padapter, rf_on, 1);
1076 static void CardDisableRTL8723U(struct rtw_adapter *Adapter)
1080 DBG_8723A("CardDisableRTL8723U\n");
1081 /* USB-MF Card Disable Flow */
1082 /* 1. Run LPS WL RFOFF flow */
1083 HalPwrSeqCmdParsing23a(Adapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
1084 PWR_INTF_USB_MSK, rtl8723AU_enter_lps_flow);
1086 /* 2. 0x1F[7:0] = 0 turn off RF */
1087 rtl8723au_write8(Adapter, REG_RF_CTRL, 0x00);
1089 /* ==== Reset digital sequence ====== */
1090 if ((rtl8723au_read8(Adapter, REG_MCUFWDL) & BIT(7)) &&
1091 Adapter->bFWReady) /* 8051 RAM code */
1092 rtl8723a_FirmwareSelfReset(Adapter);
1094 /* Reset MCU. Suggested by Filen. 2011.01.26. by tynli. */
1095 u1bTmp = rtl8723au_read8(Adapter, REG_SYS_FUNC_EN+1);
1096 rtl8723au_write8(Adapter, REG_SYS_FUNC_EN+1, u1bTmp & ~BIT(2));
1098 /* g. MCUFWDL 0x80[1:0]= 0 reset MCU ready status */
1099 rtl8723au_write8(Adapter, REG_MCUFWDL, 0x00);
1101 /* ==== Reset digital sequence end ====== */
1102 /* Card disable power action flow */
1103 HalPwrSeqCmdParsing23a(Adapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
1105 rtl8723AU_card_disable_flow);
1107 /* Reset MCU IO Wrapper, added by Roger, 2011.08.30. */
1108 u1bTmp = rtl8723au_read8(Adapter, REG_RSV_CTRL + 1);
1109 rtl8723au_write8(Adapter, REG_RSV_CTRL+1, u1bTmp & ~BIT(0));
1110 u1bTmp = rtl8723au_read8(Adapter, REG_RSV_CTRL + 1);
1111 rtl8723au_write8(Adapter, REG_RSV_CTRL+1, u1bTmp | BIT(0));
1113 /* 7. RSV_CTRL 0x1C[7:0] = 0x0E lock ISO/CLK/Power control register */
1114 rtl8723au_write8(Adapter, REG_RSV_CTRL, 0x0e);
1117 int rtl8723au_hal_deinit(struct rtw_adapter *padapter)
1119 DBG_8723A("==> %s\n", __func__);
1121 #ifdef CONFIG_8723AU_BT_COEXIST
1122 BT_HaltProcess(padapter);
1124 /* 2011/02/18 To Fix RU LNA power leakage problem. We need to
1125 execute below below in Adapter init and halt sequence.
1126 According to EEchou's opinion, we can enable the ability for all */
1127 /* IC. Accord to johnny's opinion, only RU need the support. */
1128 CardDisableRTL8723U(padapter);
1130 padapter->hw_init_completed = false;
1135 int rtl8723au_inirp_init(struct rtw_adapter *Adapter)
1138 struct recv_buf *precvbuf;
1140 struct recv_priv *precvpriv = &Adapter->recvpriv;
1141 struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
1145 RT_TRACE(_module_hci_hal_init_c_, _drv_info_, ("===> usb_inirp_init\n"));
1147 /* issue Rx irp to receive data */
1148 precvbuf = (struct recv_buf *)precvpriv->precv_buf;
1149 for (i = 0; i < NR_RECVBUFF; i++) {
1150 if (rtl8723au_read_port(Adapter, RECV_BULK_IN_ADDR, 0,
1151 precvbuf) == _FAIL) {
1152 RT_TRACE(_module_hci_hal_init_c_, _drv_err_,
1153 ("usb_rx_init: usb_read_port error\n"));
1159 if (rtl8723au_read_interrupt(Adapter, RECV_INT_IN_ADDR) == _FAIL) {
1160 RT_TRACE(_module_hci_hal_init_c_, _drv_err_,
1161 ("usb_rx_init: usb_read_interrupt error\n"));
1164 pHalData->IntrMask[0] = rtl8723au_read32(Adapter, REG_USB_HIMR);
1165 MSG_8723A("pHalData->IntrMask = 0x%04x\n", pHalData->IntrMask[0]);
1166 pHalData->IntrMask[0] |= UHIMR_C2HCMD|UHIMR_CPWM;
1167 rtl8723au_write32(Adapter, REG_USB_HIMR, pHalData->IntrMask[0]);
1169 RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
1170 ("<=== usb_inirp_init\n"));
1174 int rtl8723au_inirp_deinit(struct rtw_adapter *Adapter)
1176 struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
1178 RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
1179 ("\n ===> usb_rx_deinit\n"));
1180 rtl8723au_read_port_cancel(Adapter);
1181 pHalData->IntrMask[0] = rtl8723au_read32(Adapter, REG_USB_HIMR);
1182 MSG_8723A("%s pHalData->IntrMask = 0x%04x\n", __func__,
1183 pHalData->IntrMask[0]);
1184 pHalData->IntrMask[0] = 0x0;
1185 rtl8723au_write32(Adapter, REG_USB_HIMR, pHalData->IntrMask[0]);
1186 RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
1187 ("\n <=== usb_rx_deinit\n"));
1191 static void _ReadBoardType(struct rtw_adapter *Adapter, u8 *PROMContent,
1194 struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
1195 u8 boardType = BOARD_USB_DONGLE;
1198 if (IS_8723_SERIES(pHalData->VersionID))
1199 pHalData->rf_type = RF_1T1R;
1201 pHalData->rf_type = RF_2T2R;
1202 pHalData->BoardType = boardType;
1206 boardType = PROMContent[EEPROM_NORMAL_BoardType];
1207 boardType &= BOARD_TYPE_NORMAL_MASK;/* bit[7:5] */
1210 pHalData->BoardType = boardType;
1211 MSG_8723A("_ReadBoardType(%x)\n", pHalData->BoardType);
1213 if (boardType == BOARD_USB_High_PA)
1214 pHalData->ExternalPA = 1;
1217 static void _ReadLEDSetting(struct rtw_adapter *Adapter, u8 *PROMContent,
1220 struct led_priv *pledpriv = &Adapter->ledpriv;
1222 pledpriv->LedStrategy = HW_LED;
1225 static void Hal_EfuseParsePIDVID_8723AU(struct rtw_adapter *pAdapter,
1226 u8 *hwinfo, bool AutoLoadFail)
1228 struct hal_data_8723a *pHalData = GET_HAL_DATA(pAdapter);
1231 pHalData->EEPROMVID = 0;
1232 pHalData->EEPROMPID = 0;
1235 pHalData->EEPROMVID =
1236 le16_to_cpu(*(u16 *)&hwinfo[EEPROM_VID_8723AU]);
1237 pHalData->EEPROMPID =
1238 le16_to_cpu(*(u16 *)&hwinfo[EEPROM_PID_8723AU]);
1241 MSG_8723A("EEPROM VID = 0x%4x\n", pHalData->EEPROMVID);
1242 MSG_8723A("EEPROM PID = 0x%4x\n", pHalData->EEPROMPID);
1245 static void Hal_EfuseParseMACAddr_8723AU(struct rtw_adapter *padapter,
1246 u8 *hwinfo, bool AutoLoadFail)
1249 u8 sMacAddr[ETH_ALEN] = {0x00, 0xE0, 0x4C, 0x87, 0x23, 0x00};
1250 struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
1253 for (i = 0; i < 6; i++)
1254 pEEPROM->mac_addr[i] = sMacAddr[i];
1256 /* Read Permanent MAC address */
1257 memcpy(pEEPROM->mac_addr, &hwinfo[EEPROM_MAC_ADDR_8723AU],
1261 RT_TRACE(_module_hci_hal_init_c_, _drv_notice_,
1262 ("Hal_EfuseParseMACAddr_8723AU: Permanent Address =%02x:%02x:"
1263 "%02x:%02x:%02x:%02x\n",
1264 pEEPROM->mac_addr[0], pEEPROM->mac_addr[1],
1265 pEEPROM->mac_addr[2], pEEPROM->mac_addr[3],
1266 pEEPROM->mac_addr[4], pEEPROM->mac_addr[5]));
1269 static void readAdapterInfo(struct rtw_adapter *padapter)
1271 struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
1272 /* struct hal_data_8723a * pHalData = GET_HAL_DATA(padapter); */
1273 u8 hwinfo[HWSET_MAX_SIZE];
1275 Hal_InitPGData(padapter, hwinfo);
1276 Hal_EfuseParseIDCode(padapter, hwinfo);
1277 Hal_EfuseParsePIDVID_8723AU(padapter, hwinfo,
1278 pEEPROM->bautoload_fail_flag);
1279 Hal_EfuseParseEEPROMVer(padapter, hwinfo,
1280 pEEPROM->bautoload_fail_flag);
1281 Hal_EfuseParseMACAddr_8723AU(padapter, hwinfo,
1282 pEEPROM->bautoload_fail_flag);
1283 Hal_EfuseParsetxpowerinfo_8723A(padapter, hwinfo,
1284 pEEPROM->bautoload_fail_flag);
1285 _ReadBoardType(padapter, hwinfo, pEEPROM->bautoload_fail_flag);
1286 Hal_EfuseParseBTCoexistInfo_8723A(padapter, hwinfo,
1287 pEEPROM->bautoload_fail_flag);
1289 rtl8723a_EfuseParseChnlPlan(padapter, hwinfo,
1290 pEEPROM->bautoload_fail_flag);
1291 Hal_EfuseParseThermalMeter_8723A(padapter, hwinfo,
1292 pEEPROM->bautoload_fail_flag);
1293 _ReadLEDSetting(padapter, hwinfo, pEEPROM->bautoload_fail_flag);
1294 /* _ReadRFSetting(Adapter, PROMContent, pEEPROM->bautoload_fail_flag); */
1295 /* _ReadPSSetting(Adapter, PROMContent, pEEPROM->bautoload_fail_flag); */
1296 Hal_EfuseParseAntennaDiversity(padapter, hwinfo,
1297 pEEPROM->bautoload_fail_flag);
1299 Hal_EfuseParseEEPROMVer(padapter, hwinfo, pEEPROM->bautoload_fail_flag);
1300 Hal_EfuseParseCustomerID(padapter, hwinfo,
1301 pEEPROM->bautoload_fail_flag);
1302 Hal_EfuseParseRateIndicationOption(padapter, hwinfo,
1303 pEEPROM->bautoload_fail_flag);
1304 Hal_EfuseParseXtal_8723A(padapter, hwinfo,
1305 pEEPROM->bautoload_fail_flag);
1307 /* The following part initialize some vars by PG info. */
1309 Hal_InitChannelPlan23a(padapter);
1311 /* hal_CustomizedBehavior_8723U(Adapter); */
1313 /* Adapter->bDongle = (PROMContent[EEPROM_EASY_REPLACEMENT] == 1)? 0: 1; */
1314 DBG_8723A("%s(): REPLACEMENT = %x\n", __func__, padapter->bDongle);
1317 static void _ReadPROMContent(struct rtw_adapter *Adapter)
1319 struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(Adapter);
1322 eeValue = rtl8723au_read8(Adapter, REG_9346CR);
1323 /* To check system boot selection. */
1324 pEEPROM->EepromOrEfuse = (eeValue & BOOT_FROM_EEPROM) ? true : false;
1325 pEEPROM->bautoload_fail_flag = (eeValue & EEPROM_EN) ? false : true;
1327 DBG_8723A("Boot from %s, Autoload %s !\n",
1328 (pEEPROM->EepromOrEfuse ? "EEPROM" : "EFUSE"),
1329 (pEEPROM->bautoload_fail_flag ? "Fail" : "OK"));
1331 readAdapterInfo(Adapter);
1334 static void _ReadRFType(struct rtw_adapter *Adapter)
1336 struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
1338 pHalData->rf_chip = RF_6052;
1341 static void _ReadSilmComboMode(struct rtw_adapter *Adapter)
1343 struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
1345 pHalData->SlimComboDbg = false; /* Default is not debug mode. */
1350 /* We should set Efuse cell selection to WiFi cell in default. */
1355 /* Added by Roger, 2010.11.23. */
1357 static void hal_EfuseCellSel(struct rtw_adapter *Adapter)
1361 value32 = rtl8723au_read32(Adapter, EFUSE_TEST);
1362 value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_WIFI_SEL_0);
1363 rtl8723au_write32(Adapter, EFUSE_TEST, value32);
1366 void rtl8723a_read_adapter_info(struct rtw_adapter *Adapter)
1368 unsigned long start = jiffies;
1370 /* Read EEPROM size before call any EEPROM function */
1371 Adapter->EepromAddressSize = GetEEPROMSize8723A(Adapter);
1373 MSG_8723A("====> _ReadAdapterInfo8723AU\n");
1375 hal_EfuseCellSel(Adapter);
1377 _ReadRFType(Adapter);/* rf_chip -> _InitRFType() */
1378 _ReadPROMContent(Adapter);
1380 /* 2010/10/25 MH THe function must be called after
1381 borad_type & IC-Version recognize. */
1382 _ReadSilmComboMode(Adapter);
1384 /* MSG_8723A("%s()(done), rf_chip = 0x%x, rf_type = 0x%x\n",
1385 __func__, pHalData->rf_chip, pHalData->rf_type); */
1387 MSG_8723A("<==== _ReadAdapterInfo8723AU in %d ms\n",
1388 jiffies_to_msecs(jiffies - start));
1393 /* Query setting of specified variable. */
1395 int GetHalDefVar8192CUsb(struct rtw_adapter *Adapter,
1396 enum hal_def_variable eVariable, void *pValue)
1398 struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
1399 int bResult = _SUCCESS;
1401 switch (eVariable) {
1402 case HAL_DEF_UNDERCORATEDSMOOTHEDPWDB:
1403 *((int *)pValue) = pHalData->dmpriv.UndecoratedSmoothedPWDB;
1405 case HAL_DEF_IS_SUPPORT_ANT_DIV:
1407 case HAL_DEF_CURRENT_ANTENNA:
1409 case HAL_DEF_DRVINFO_SZ:
1410 *((u32 *)pValue) = DRVINFO_SZ;
1412 case HAL_DEF_MAX_RECVBUF_SZ:
1413 *((u32 *)pValue) = MAX_RECVBUF_SZ;
1415 case HAL_DEF_RX_PACKET_OFFSET:
1416 *((u32 *)pValue) = RXDESC_SIZE + DRVINFO_SZ;
1418 case HAL_DEF_DBG_DUMP_RXPKT:
1419 *((u8 *)pValue) = pHalData->bDumpRxPkt;
1421 case HAL_DEF_DBG_DM_FUNC:
1422 *((u32 *)pValue) = pHalData->odmpriv.SupportAbility;
1424 case HW_VAR_MAX_RX_AMPDU_FACTOR:
1425 *((u32 *)pValue) = IEEE80211_HT_MAX_AMPDU_64K;
1427 case HW_DEF_ODM_DBG_FLAG:
1429 struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
1430 printk("pDM_Odm->DebugComponents = 0x%llx\n",
1431 pDM_Odm->DebugComponents);
1435 /* RT_TRACE(COMP_INIT, DBG_WARNING, ("GetHalDefVar8192CUsb(): "
1436 "Unkown variable: %d!\n", eVariable)); */
1444 void rtl8723a_update_ramask(struct rtw_adapter *padapter,
1445 u32 mac_id, u8 rssi_level)
1448 u8 networkType, raid;
1449 u32 mask, rate_bitmap;
1450 u8 shortGIrate = false;
1451 int supportRateNum = 0;
1452 struct sta_info *psta;
1453 struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
1454 struct dm_priv *pdmpriv = &pHalData->dmpriv;
1455 struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1456 struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1457 struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
1459 if (mac_id >= NUM_STA) /* CAM_SIZE */
1462 psta = pmlmeinfo->FW_sta_info[mac_id].psta;
1467 case 0:/* for infra mode */
1469 rtw_get_rateset_len23a(cur_network->SupportedRates);
1470 networkType = judge_network_type23a(padapter,
1471 cur_network->SupportedRates,
1472 supportRateNum) & 0xf;
1473 /* pmlmeext->cur_wireless_mode = networkType; */
1474 raid = networktype_to_raid23a(networkType);
1476 mask = update_supported_rate23a(cur_network->SupportedRates,
1478 mask |= (pmlmeinfo->HT_enable) ?
1479 update_MSC_rate23a(&pmlmeinfo->ht_cap) : 0;
1481 if (support_short_GI23a(padapter, &pmlmeinfo->ht_cap))
1485 case 1:/* for broadcast/multicast */
1486 supportRateNum = rtw_get_rateset_len23a(
1487 pmlmeinfo->FW_sta_info[mac_id].SupportedRates);
1488 if (pmlmeext->cur_wireless_mode & WIRELESS_11B)
1489 networkType = WIRELESS_11B;
1491 networkType = WIRELESS_11G;
1492 raid = networktype_to_raid23a(networkType);
1494 mask = update_basic_rate23a(cur_network->SupportedRates,
1498 default: /* for each sta in IBSS */
1499 supportRateNum = rtw_get_rateset_len23a(
1500 pmlmeinfo->FW_sta_info[mac_id].SupportedRates);
1501 networkType = judge_network_type23a(padapter,
1502 pmlmeinfo->FW_sta_info[mac_id].SupportedRates,
1503 supportRateNum) & 0xf;
1504 /* pmlmeext->cur_wireless_mode = networkType; */
1505 raid = networktype_to_raid23a(networkType);
1507 mask = update_supported_rate23a(cur_network->SupportedRates,
1510 /* todo: support HT in IBSS */
1514 /* mask &= 0x0fffffff; */
1515 rate_bitmap = 0x0fffffff;
1516 rate_bitmap = ODM_Get_Rate_Bitmap23a(pHalData, mac_id, mask,
1518 DBG_8723A("%s => mac_id:%d, networkType:0x%02x, "
1519 "mask:0x%08x\n\t ==> rssi_level:%d, rate_bitmap:0x%08x\n",
1520 __func__, mac_id, networkType, mask, rssi_level, rate_bitmap);
1522 mask &= rate_bitmap;
1523 mask |= ((raid<<28)&0xf0000000);
1525 init_rate = get_highest_rate_idx23a(mask)&0x3f;
1527 if (pHalData->fw_ractrl == true) {
1530 /* arg = (cam_idx-4)&0x1f;MACID */
1531 arg = mac_id&0x1f;/* MACID */
1535 if (shortGIrate == true)
1538 DBG_8723A("update raid entry, mask = 0x%x, arg = 0x%x\n",
1541 rtl8723a_set_raid_cmd(padapter, mask, arg);
1543 if (shortGIrate == true)
1544 init_rate |= BIT(6);
1546 rtl8723au_write8(padapter, (REG_INIDATA_RATE_SEL+mac_id),
1552 psta->init_rate = init_rate;
1554 /* set correct initial date rate for each mac_id */
1555 pdmpriv->INIDATA_RATE[mac_id] = init_rate;