linux/drivers/staging/rtl8723au/hal/usb_halinit.c
<<
>>
Prefs
   1/******************************************************************************
   2 *
   3 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
   4 *
   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.
   8 *
   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
  12 * more details.
  13 *
  14 ******************************************************************************/
  15#define _HCI_HAL_INIT_C_
  16
  17#include <osdep_service.h>
  18#include <drv_types.h>
  19#include <rtw_efuse.h>
  20
  21#include <HalPwrSeqCmd.h>
  22#include <Hal8723PwrSeq.h>
  23#include <rtl8723a_hal.h>
  24#include <linux/ieee80211.h>
  25
  26#include <usb_ops.h>
  27
  28static void phy_SsPwrSwitch92CU(struct rtw_adapter *Adapter,
  29                                enum rt_rf_power_state eRFPowerState);
  30
  31static void
  32_ConfigChipOutEP(struct rtw_adapter *pAdapter, u8 NumOutPipe)
  33{
  34        u8 value8;
  35        struct hal_data_8723a *pHalData = GET_HAL_DATA(pAdapter);
  36
  37        pHalData->OutEpQueueSel = 0;
  38        pHalData->OutEpNumber = 0;
  39
  40        /*  Normal and High queue */
  41        value8 = rtl8723au_read8(pAdapter, (REG_NORMAL_SIE_EP + 1));
  42
  43        if (value8 & USB_NORMAL_SIE_EP_MASK) {
  44                pHalData->OutEpQueueSel |= TX_SELE_HQ;
  45                pHalData->OutEpNumber++;
  46        }
  47
  48        if ((value8 >> USB_NORMAL_SIE_EP_SHIFT) & USB_NORMAL_SIE_EP_MASK) {
  49                pHalData->OutEpQueueSel |= TX_SELE_NQ;
  50                pHalData->OutEpNumber++;
  51        }
  52
  53        /*  Low queue */
  54        value8 = rtl8723au_read8(pAdapter, (REG_NORMAL_SIE_EP + 2));
  55        if (value8 & USB_NORMAL_SIE_EP_MASK) {
  56                pHalData->OutEpQueueSel |= TX_SELE_LQ;
  57                pHalData->OutEpNumber++;
  58        }
  59
  60        /*  TODO: Error recovery for this case */
  61        /* RT_ASSERT((NumOutPipe == pHalData->OutEpNumber),
  62           ("Out EP number isn't match! %d(Descriptor) != %d (SIE reg)\n",
  63           (u32)NumOutPipe, (u32)pHalData->OutEpNumber)); */
  64}
  65
  66bool rtl8723au_chip_configure(struct rtw_adapter *padapter)
  67{
  68        struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
  69        struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
  70        u8 NumInPipe = pdvobjpriv->RtNumInPipes;
  71        u8 NumOutPipe = pdvobjpriv->RtNumOutPipes;
  72
  73        _ConfigChipOutEP(padapter, NumOutPipe);
  74
  75        /*  Normal chip with one IN and one OUT doesn't have interrupt IN EP. */
  76        if (pHalData->OutEpNumber == 1) {
  77                if (NumInPipe != 1)
  78                        return false;
  79        }
  80
  81        return Hal_MappingOutPipe23a(padapter, NumOutPipe);
  82}
  83
  84static int _InitPowerOn(struct rtw_adapter *padapter)
  85{
  86        u16 value16;
  87        u8 value8;
  88
  89        /*  RSV_CTRL 0x1C[7:0] = 0x00
  90            unlock ISO/CLK/Power control register */
  91        rtl8723au_write8(padapter, REG_RSV_CTRL, 0x0);
  92
  93        /*  HW Power on sequence */
  94        if (!HalPwrSeqCmdParsing23a(padapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
  95                                 PWR_INTF_USB_MSK, rtl8723AU_card_enable_flow))
  96                return _FAIL;
  97
  98        /*  0x04[19] = 1, suggest by Jackie 2011.05.09, reset 8051 */
  99        value8 = rtl8723au_read8(padapter, REG_APS_FSMCO+2);
 100        rtl8723au_write8(padapter, REG_APS_FSMCO + 2, value8 | BIT(3));
 101
 102        /*  Enable MAC DMA/WMAC/SCHEDULE/SEC block */
 103        /*  Set CR bit10 to enable 32k calibration. Suggested by SD1 Gimmy.
 104            Added by tynli. 2011.08.31. */
 105        value16 = rtl8723au_read16(padapter, REG_CR);
 106        value16 |= (HCI_TXDMA_EN | HCI_RXDMA_EN | TXDMA_EN | RXDMA_EN |
 107                    PROTOCOL_EN | SCHEDULE_EN | MACTXEN | MACRXEN |
 108                    ENSEC | CALTMR_EN);
 109        rtl8723au_write16(padapter, REG_CR, value16);
 110
 111        /* for Efuse PG, suggest by Jackie 2011.11.23 */
 112        PHY_SetBBReg(padapter, REG_EFUSE_CTRL, BIT(28)|BIT(29)|BIT(30), 0x06);
 113
 114        return _SUCCESS;
 115}
 116
 117/*  Shall USB interface init this? */
 118static void _InitInterrupt(struct rtw_adapter *Adapter)
 119{
 120        u32 value32;
 121
 122        /*  HISR - turn all on */
 123        value32 = 0xFFFFFFFF;
 124        rtl8723au_write32(Adapter, REG_HISR, value32);
 125
 126        /*  HIMR - turn all on */
 127        rtl8723au_write32(Adapter, REG_HIMR, value32);
 128}
 129
 130static void _InitQueueReservedPage(struct rtw_adapter *Adapter)
 131{
 132        struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
 133        struct registry_priv *pregistrypriv = &Adapter->registrypriv;
 134        u32 numHQ = 0;
 135        u32 numLQ = 0;
 136        u32 numNQ = 0;
 137        u32 numPubQ;
 138        u32 value32;
 139        u8 value8;
 140        bool bWiFiConfig = pregistrypriv->wifi_spec;
 141
 142        /* RT_ASSERT((outEPNum>= 2), ("for WMM , number of out-ep "
 143           "must more than or equal to 2!\n")); */
 144
 145        numPubQ = bWiFiConfig ? WMM_NORMAL_PAGE_NUM_PUBQ : NORMAL_PAGE_NUM_PUBQ;
 146
 147        if (pHalData->OutEpQueueSel & TX_SELE_HQ) {
 148                numHQ = bWiFiConfig ?
 149                        WMM_NORMAL_PAGE_NUM_HPQ : NORMAL_PAGE_NUM_HPQ;
 150        }
 151
 152        if (pHalData->OutEpQueueSel & TX_SELE_LQ) {
 153                numLQ = bWiFiConfig ?
 154                        WMM_NORMAL_PAGE_NUM_LPQ : NORMAL_PAGE_NUM_LPQ;
 155        }
 156        /*  NOTE: This step shall be proceed before
 157            writting REG_RQPN. */
 158        if (pHalData->OutEpQueueSel & TX_SELE_NQ) {
 159                numNQ = bWiFiConfig ?
 160                        WMM_NORMAL_PAGE_NUM_NPQ : NORMAL_PAGE_NUM_NPQ;
 161        }
 162        value8 = (u8)_NPQ(numNQ);
 163        rtl8723au_write8(Adapter, REG_RQPN_NPQ, value8);
 164
 165        /*  TX DMA */
 166        value32 = _HPQ(numHQ) | _LPQ(numLQ) | _PUBQ(numPubQ) | LD_RQPN;
 167        rtl8723au_write32(Adapter, REG_RQPN, value32);
 168}
 169
 170static void _InitTxBufferBoundary(struct rtw_adapter *Adapter)
 171{
 172        struct registry_priv *pregistrypriv = &Adapter->registrypriv;
 173
 174        u8 txpktbuf_bndy;
 175
 176        if (!pregistrypriv->wifi_spec)
 177                txpktbuf_bndy = TX_PAGE_BOUNDARY;
 178        else /* for WMM */
 179                txpktbuf_bndy = WMM_NORMAL_TX_PAGE_BOUNDARY;
 180
 181        rtl8723au_write8(Adapter, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy);
 182        rtl8723au_write8(Adapter, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy);
 183        rtl8723au_write8(Adapter, REG_TXPKTBUF_WMAC_LBK_BF_HD, txpktbuf_bndy);
 184        rtl8723au_write8(Adapter, REG_TRXFF_BNDY, txpktbuf_bndy);
 185        rtl8723au_write8(Adapter, REG_TDECTRL+1, txpktbuf_bndy);
 186}
 187
 188static void _InitPageBoundary(struct rtw_adapter *Adapter)
 189{
 190        /*  RX Page Boundary */
 191        /* srand(static_cast<unsigned int>(time(NULL))); */
 192        u16 rxff_bndy = 0x27FF;/* rand() % 1) ? 0x27FF : 0x23FF; */
 193
 194        rtl8723au_write16(Adapter, (REG_TRXFF_BNDY + 2), rxff_bndy);
 195
 196        /*  TODO: ?? shall we set tx boundary? */
 197}
 198
 199static void
 200_InitNormalChipRegPriority(struct rtw_adapter *Adapter, u16 beQ, u16 bkQ,
 201                           u16 viQ, u16 voQ, u16 mgtQ, u16 hiQ)
 202{
 203        u16 value16 = rtl8723au_read16(Adapter, REG_TRXDMA_CTRL) & 0x7;
 204
 205        value16 |= _TXDMA_BEQ_MAP(beQ) | _TXDMA_BKQ_MAP(bkQ) |
 206                _TXDMA_VIQ_MAP(viQ) | _TXDMA_VOQ_MAP(voQ) |
 207                _TXDMA_MGQ_MAP(mgtQ) | _TXDMA_HIQ_MAP(hiQ);
 208
 209        rtl8723au_write16(Adapter, REG_TRXDMA_CTRL, value16);
 210}
 211
 212static void _InitNormalChipOneOutEpPriority(struct rtw_adapter *Adapter)
 213{
 214        struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
 215        u16 value = 0;
 216
 217        switch (pHalData->OutEpQueueSel) {
 218        case TX_SELE_HQ:
 219                value = QUEUE_HIGH;
 220                break;
 221        case TX_SELE_LQ:
 222                value = QUEUE_LOW;
 223                break;
 224        case TX_SELE_NQ:
 225                value = QUEUE_NORMAL;
 226                break;
 227        default:
 228                /* RT_ASSERT(false, ("Shall not reach here!\n")); */
 229                break;
 230        }
 231
 232        _InitNormalChipRegPriority(Adapter, value, value, value,
 233                                   value, value, value);
 234}
 235
 236static void _InitNormalChipTwoOutEpPriority(struct rtw_adapter *Adapter)
 237{
 238        struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
 239        struct registry_priv *pregistrypriv = &Adapter->registrypriv;
 240        u16 beQ, bkQ, viQ, voQ, mgtQ, hiQ;
 241        u16 valueHi = 0;
 242        u16 valueLow = 0;
 243
 244        switch (pHalData->OutEpQueueSel) {
 245        case (TX_SELE_HQ | TX_SELE_LQ):
 246                valueHi = QUEUE_HIGH;
 247                valueLow = QUEUE_LOW;
 248                break;
 249        case (TX_SELE_NQ | TX_SELE_LQ):
 250                valueHi = QUEUE_NORMAL;
 251                valueLow = QUEUE_LOW;
 252                break;
 253        case (TX_SELE_HQ | TX_SELE_NQ):
 254                valueHi = QUEUE_HIGH;
 255                valueLow = QUEUE_NORMAL;
 256                break;
 257        default:
 258                /* RT_ASSERT(false, ("Shall not reach here!\n")); */
 259                break;
 260        }
 261
 262        if (!pregistrypriv->wifi_spec) {
 263                beQ = valueLow;
 264                bkQ = valueLow;
 265                viQ = valueHi;
 266                voQ = valueHi;
 267                mgtQ = valueHi;
 268                hiQ = valueHi;
 269        } else {/* for WMM , CONFIG_OUT_EP_WIFI_MODE */
 270                beQ = valueLow;
 271                bkQ = valueHi;
 272                viQ = valueHi;
 273                voQ = valueLow;
 274                mgtQ = valueHi;
 275                hiQ = valueHi;
 276        }
 277
 278        _InitNormalChipRegPriority(Adapter, beQ, bkQ, viQ, voQ, mgtQ, hiQ);
 279}
 280
 281static void _InitNormalChipThreeOutEpPriority(struct rtw_adapter *Adapter)
 282{
 283        struct registry_priv *pregistrypriv = &Adapter->registrypriv;
 284        u16 beQ, bkQ, viQ, voQ, mgtQ, hiQ;
 285
 286        if (!pregistrypriv->wifi_spec) {/*  typical setting */
 287                beQ = QUEUE_LOW;
 288                bkQ = QUEUE_LOW;
 289                viQ = QUEUE_NORMAL;
 290                voQ = QUEUE_HIGH;
 291                mgtQ = QUEUE_HIGH;
 292                hiQ = QUEUE_HIGH;
 293        } else {/*  for WMM */
 294                beQ = QUEUE_LOW;
 295                bkQ = QUEUE_NORMAL;
 296                viQ = QUEUE_NORMAL;
 297                voQ = QUEUE_HIGH;
 298                mgtQ = QUEUE_HIGH;
 299                hiQ = QUEUE_HIGH;
 300        }
 301        _InitNormalChipRegPriority(Adapter, beQ, bkQ, viQ, voQ, mgtQ, hiQ);
 302}
 303
 304static void _InitQueuePriority(struct rtw_adapter *Adapter)
 305{
 306        struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
 307
 308        switch (pHalData->OutEpNumber) {
 309        case 1:
 310                _InitNormalChipOneOutEpPriority(Adapter);
 311                break;
 312        case 2:
 313                _InitNormalChipTwoOutEpPriority(Adapter);
 314                break;
 315        case 3:
 316                _InitNormalChipThreeOutEpPriority(Adapter);
 317                break;
 318        default:
 319                /* RT_ASSERT(false, ("Shall not reach here!\n")); */
 320                break;
 321        }
 322}
 323
 324static void _InitTransferPageSize(struct rtw_adapter *Adapter)
 325{
 326        /*  Tx page size is always 128. */
 327
 328        u8 value8;
 329        value8 = _PSRX(PBP_128) | _PSTX(PBP_128);
 330        rtl8723au_write8(Adapter, REG_PBP, value8);
 331}
 332
 333static void _InitDriverInfoSize(struct rtw_adapter *Adapter, u8 drvInfoSize)
 334{
 335        rtl8723au_write8(Adapter, REG_RX_DRVINFO_SZ, drvInfoSize);
 336}
 337
 338static void _InitWMACSetting(struct rtw_adapter *Adapter)
 339{
 340        struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
 341
 342        /*  don't turn on AAP, it will allow all packets to driver */
 343        pHalData->ReceiveConfig = RCR_APM | RCR_AM | RCR_AB | RCR_CBSSID_DATA |
 344                                  RCR_CBSSID_BCN | RCR_APP_ICV | RCR_AMF |
 345                                  RCR_HTC_LOC_CTRL | RCR_APP_MIC |
 346                                  RCR_APP_PHYSTS;
 347
 348        /*  some REG_RCR will be modified later by
 349            phy_ConfigMACWithHeaderFile() */
 350        rtl8723au_write32(Adapter, REG_RCR, pHalData->ReceiveConfig);
 351
 352        /*  Accept all multicast address */
 353        rtl8723au_write32(Adapter, REG_MAR, 0xFFFFFFFF);
 354        rtl8723au_write32(Adapter, REG_MAR + 4, 0xFFFFFFFF);
 355
 356        /*  Accept all data frames */
 357        /* value16 = 0xFFFF; */
 358        /* rtl8723au_write16(Adapter, REG_RXFLTMAP2, value16); */
 359
 360        /*  2010.09.08 hpfan */
 361        /*  Since ADF is removed from RCR, ps-poll will not be indicate
 362            to driver, */
 363        /*  RxFilterMap should mask ps-poll to guarantee AP mode can
 364            rx ps-poll. */
 365        /* value16 = 0x400; */
 366        /* rtl8723au_write16(Adapter, REG_RXFLTMAP1, value16); */
 367
 368        /*  Accept all management frames */
 369        /* value16 = 0xFFFF; */
 370        /* rtl8723au_write16(Adapter, REG_RXFLTMAP0, value16); */
 371
 372        /* enable RX_SHIFT bits */
 373        /* rtl8723au_write8(Adapter, REG_TRXDMA_CTRL, rtl8723au_read8(Adapter,
 374           REG_TRXDMA_CTRL)|BIT(1)); */
 375}
 376
 377static void _InitAdaptiveCtrl(struct rtw_adapter *Adapter)
 378{
 379        u16 value16;
 380        u32 value32;
 381
 382        /*  Response Rate Set */
 383        value32 = rtl8723au_read32(Adapter, REG_RRSR);
 384        value32 &= ~RATE_BITMAP_ALL;
 385        value32 |= RATE_RRSR_CCK_ONLY_1M;
 386        rtl8723au_write32(Adapter, REG_RRSR, value32);
 387
 388        /*  CF-END Threshold */
 389        /* m_spIoBase->rtl8723au_write8(REG_CFEND_TH, 0x1); */
 390
 391        /*  SIFS (used in NAV) */
 392        value16 = _SPEC_SIFS_CCK(0x10) | _SPEC_SIFS_OFDM(0x10);
 393        rtl8723au_write16(Adapter, REG_SPEC_SIFS, value16);
 394
 395        /*  Retry Limit */
 396        value16 = _LRL(0x30) | _SRL(0x30);
 397        rtl8723au_write16(Adapter, REG_RL, value16);
 398}
 399
 400static void _InitRateFallback(struct rtw_adapter *Adapter)
 401{
 402        /*  Set Data Auto Rate Fallback Retry Count register. */
 403        rtl8723au_write32(Adapter, REG_DARFRC, 0x00000000);
 404        rtl8723au_write32(Adapter, REG_DARFRC+4, 0x10080404);
 405        rtl8723au_write32(Adapter, REG_RARFRC, 0x04030201);
 406        rtl8723au_write32(Adapter, REG_RARFRC+4, 0x08070605);
 407}
 408
 409static void _InitEDCA(struct rtw_adapter *Adapter)
 410{
 411        /*  Set Spec SIFS (used in NAV) */
 412        rtl8723au_write16(Adapter, REG_SPEC_SIFS, 0x100a);
 413        rtl8723au_write16(Adapter, REG_MAC_SPEC_SIFS, 0x100a);
 414
 415        /*  Set SIFS for CCK */
 416        rtl8723au_write16(Adapter, REG_SIFS_CTX, 0x100a);
 417
 418        /*  Set SIFS for OFDM */
 419        rtl8723au_write16(Adapter, REG_SIFS_TRX, 0x100a);
 420
 421        /*  TXOP */
 422        rtl8723au_write32(Adapter, REG_EDCA_BE_PARAM, 0x005EA42B);
 423        rtl8723au_write32(Adapter, REG_EDCA_BK_PARAM, 0x0000A44F);
 424        rtl8723au_write32(Adapter, REG_EDCA_VI_PARAM, 0x005EA324);
 425        rtl8723au_write32(Adapter, REG_EDCA_VO_PARAM, 0x002FA226);
 426}
 427
 428static void _InitRDGSetting(struct rtw_adapter *Adapter)
 429{
 430        rtl8723au_write8(Adapter, REG_RD_CTRL, 0xFF);
 431        rtl8723au_write16(Adapter, REG_RD_NAV_NXT, 0x200);
 432        rtl8723au_write8(Adapter, REG_RD_RESP_PKT_TH, 0x05);
 433}
 434
 435static void _InitRetryFunction(struct rtw_adapter *Adapter)
 436{
 437        u8 value8;
 438
 439        value8 = rtl8723au_read8(Adapter, REG_FWHW_TXQ_CTRL);
 440        value8 |= EN_AMPDU_RTY_NEW;
 441        rtl8723au_write8(Adapter, REG_FWHW_TXQ_CTRL, value8);
 442
 443        /*  Set ACK timeout */
 444        rtl8723au_write8(Adapter, REG_ACKTO, 0x40);
 445}
 446
 447static void _InitRFType(struct rtw_adapter *Adapter)
 448{
 449        struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
 450
 451        pHalData->rf_type = RF_1T1R;
 452}
 453
 454/*  Set CCK and OFDM Block "ON" */
 455static void _BBTurnOnBlock(struct rtw_adapter *Adapter)
 456{
 457        PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bCCKEn, 0x1);
 458        PHY_SetBBReg(Adapter, rFPGA0_RFMOD, bOFDMEn, 0x1);
 459}
 460
 461#define MgntActSet_RF_State(...)
 462static void _RfPowerSave(struct rtw_adapter *padapter)
 463{
 464}
 465
 466enum {
 467        Antenna_Lfet = 1,
 468        Antenna_Right = 2,
 469};
 470
 471enum rt_rf_power_state RfOnOffDetect23a(struct rtw_adapter *pAdapter)
 472{
 473        /* struct hal_data_8723a *pHalData = GET_HAL_DATA(pAdapter); */
 474        u8 val8;
 475        enum rt_rf_power_state rfpowerstate = rf_off;
 476
 477        rtl8723au_write8(pAdapter, REG_MAC_PINMUX_CFG,
 478                         rtl8723au_read8(pAdapter,
 479                                         REG_MAC_PINMUX_CFG) & ~BIT(3));
 480        val8 = rtl8723au_read8(pAdapter, REG_GPIO_IO_SEL);
 481        DBG_8723A("GPIO_IN =%02x\n", val8);
 482        rfpowerstate = (val8 & BIT(3)) ? rf_on : rf_off;
 483
 484        return rfpowerstate;
 485}
 486
 487int rtl8723au_hal_init(struct rtw_adapter *Adapter)
 488{
 489        struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
 490        struct pwrctrl_priv *pwrctrlpriv = &Adapter->pwrctrlpriv;
 491        struct registry_priv *pregistrypriv = &Adapter->registrypriv;
 492        u8 val8 = 0;
 493        u32 boundary;
 494        int status = _SUCCESS;
 495        bool mac_on;
 496
 497        unsigned long init_start_time = jiffies;
 498
 499        Adapter->hw_init_completed = false;
 500
 501        if (Adapter->pwrctrlpriv.bkeepfwalive) {
 502                phy_SsPwrSwitch92CU(Adapter, rf_on);
 503
 504                if (pHalData->bIQKInitialized) {
 505                        rtl8723a_phy_iq_calibrate(Adapter, true);
 506                } else {
 507                        rtl8723a_phy_iq_calibrate(Adapter, false);
 508                        pHalData->bIQKInitialized = true;
 509                }
 510                rtl8723a_odm_check_tx_power_tracking(Adapter);
 511                rtl8723a_phy_lc_calibrate(Adapter);
 512
 513                goto exit;
 514        }
 515
 516        /*  Check if MAC has already power on. by tynli. 2011.05.27. */
 517        val8 = rtl8723au_read8(Adapter, REG_CR);
 518        RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
 519                 "%s: REG_CR 0x100 = 0x%02x\n", __func__, val8);
 520        /* Fix 92DU-VC S3 hang with the reason is that secondary mac is not
 521           initialized. */
 522        /* 0x100 value of first mac is 0xEA while 0x100 value of secondary
 523           is 0x00 */
 524        if (val8 == 0xEA) {
 525                mac_on = false;
 526        } else {
 527                mac_on = true;
 528                RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
 529                         "%s: MAC has already power on\n", __func__);
 530        }
 531
 532        status = _InitPowerOn(Adapter);
 533        if (status == _FAIL) {
 534                RT_TRACE(_module_hci_hal_init_c_, _drv_err_,
 535                         "Failed to init power on!\n");
 536                goto exit;
 537        }
 538
 539        if (!pregistrypriv->wifi_spec) {
 540                boundary = TX_PAGE_BOUNDARY;
 541        } else {
 542                /*  for WMM */
 543                boundary = WMM_NORMAL_TX_PAGE_BOUNDARY;
 544        }
 545
 546        if (!mac_on) {
 547                status =  InitLLTTable23a(Adapter, boundary);
 548                if (status == _FAIL) {
 549                        RT_TRACE(_module_hci_hal_init_c_, _drv_err_,
 550                                 "Failed to init LLT table\n");
 551                        goto exit;
 552                }
 553        }
 554
 555        if (pHalData->bRDGEnable)
 556                _InitRDGSetting(Adapter);
 557
 558        status = rtl8723a_FirmwareDownload(Adapter);
 559        if (status != _SUCCESS) {
 560                Adapter->bFWReady = false;
 561                DBG_8723A("fw download fail!\n");
 562                goto exit;
 563        } else {
 564                Adapter->bFWReady = true;
 565                DBG_8723A("fw download ok!\n");
 566        }
 567
 568        rtl8723a_InitializeFirmwareVars(Adapter);
 569
 570        if (pwrctrlpriv->reg_rfoff == true) {
 571                pwrctrlpriv->rf_pwrstate = rf_off;
 572        }
 573
 574        /*  2010/08/09 MH We need to check if we need to turnon or off RF after detecting */
 575        /*  HW GPIO pin. Before PHY_RFConfig8192C. */
 576        /* HalDetectPwrDownMode(Adapter); */
 577        /*  2010/08/26 MH If Efuse does not support sective suspend then disable the function. */
 578        /* HalDetectSelectiveSuspendMode(Adapter); */
 579
 580        /*  Set RF type for BB/RF configuration */
 581        _InitRFType(Adapter);/* _ReadRFType() */
 582
 583        /*  Save target channel */
 584        /*  <Roger_Notes> Current Channel will be updated again later. */
 585        pHalData->CurrentChannel = 6;/* default set to 6 */
 586
 587        status = PHY_MACConfig8723A(Adapter);
 588        if (status == _FAIL) {
 589                DBG_8723A("PHY_MACConfig8723A fault !!\n");
 590                goto exit;
 591        }
 592
 593        /*  */
 594        /* d. Initialize BB related configurations. */
 595        /*  */
 596        status = PHY_BBConfig8723A(Adapter);
 597        if (status == _FAIL) {
 598                DBG_8723A("PHY_BBConfig8723A fault !!\n");
 599                goto exit;
 600        }
 601
 602        /*  Add for tx power by rate fine tune. We need to call the function after BB config. */
 603        /*  Because the tx power by rate table is inited in BB config. */
 604
 605        status = PHY_RF6052_Config8723A(Adapter);
 606        if (status == _FAIL) {
 607                DBG_8723A("PHY_RF6052_Config8723A failed!!\n");
 608                goto exit;
 609        }
 610
 611        /* reducing 80M spur */
 612        rtl8723au_write32(Adapter, REG_AFE_XTAL_CTRL, 0x0381808d);
 613        rtl8723au_write32(Adapter, REG_AFE_PLL_CTRL, 0xf0ffff83);
 614        rtl8723au_write32(Adapter, REG_AFE_PLL_CTRL, 0xf0ffff82);
 615        rtl8723au_write32(Adapter, REG_AFE_PLL_CTRL, 0xf0ffff83);
 616
 617        /* RFSW Control */
 618        /* 0x804[14]= 0 */
 619        rtl8723au_write32(Adapter, rFPGA0_TxInfo, 0x00000003);
 620        /* 0x870[6:5]= b'11 */
 621        rtl8723au_write32(Adapter, rFPGA0_XAB_RFInterfaceSW, 0x07000760);
 622        /* 0x860[6:5]= b'00 */
 623        rtl8723au_write32(Adapter, rFPGA0_XA_RFInterfaceOE, 0x66F60210);
 624
 625        RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
 626                 "%s: 0x870 = value 0x%x\n", __func__,
 627                 rtl8723au_read32(Adapter, 0x870));
 628
 629        /*  */
 630        /*  Joseph Note: Keep RfRegChnlVal for later use. */
 631        /*  */
 632        pHalData->RfRegChnlVal[0] = PHY_QueryRFReg(Adapter, RF_PATH_A,
 633                                                   RF_CHNLBW, bRFRegOffsetMask);
 634        pHalData->RfRegChnlVal[1] = PHY_QueryRFReg(Adapter, RF_PATH_B,
 635                                                   RF_CHNLBW, bRFRegOffsetMask);
 636
 637        if (!mac_on) {
 638                _InitQueueReservedPage(Adapter);
 639                _InitTxBufferBoundary(Adapter);
 640        }
 641        _InitQueuePriority(Adapter);
 642        _InitPageBoundary(Adapter);
 643        _InitTransferPageSize(Adapter);
 644
 645        /*  Get Rx PHY status in order to report RSSI and others. */
 646        _InitDriverInfoSize(Adapter, DRVINFO_SZ);
 647
 648        _InitInterrupt(Adapter);
 649        hw_var_set_macaddr(Adapter, Adapter->eeprompriv.mac_addr);
 650        rtl8723a_set_media_status(Adapter, MSR_INFRA);
 651        _InitWMACSetting(Adapter);
 652        _InitAdaptiveCtrl(Adapter);
 653        _InitEDCA(Adapter);
 654        _InitRateFallback(Adapter);
 655        _InitRetryFunction(Adapter);
 656        rtl8723a_InitBeaconParameters(Adapter);
 657
 658        _BBTurnOnBlock(Adapter);
 659        /* NicIFSetMacAddress(padapter, padapter->PermanentAddress); */
 660
 661        rtl8723a_cam_invalidate_all(Adapter);
 662
 663        /*  2010/12/17 MH We need to set TX power according to EFUSE content at first. */
 664        PHY_SetTxPowerLevel8723A(Adapter, pHalData->CurrentChannel);
 665
 666        rtl8723a_InitAntenna_Selection(Adapter);
 667
 668        /*  HW SEQ CTRL */
 669        /* set 0x0 to 0xFF by tynli. Default enable HW SEQ NUM. */
 670        rtl8723au_write8(Adapter, REG_HWSEQ_CTRL, 0xFF);
 671
 672        /*  */
 673        /*  Disable BAR, suggested by Scott */
 674        /*  2010.04.09 add by hpfan */
 675        /*  */
 676        rtl8723au_write32(Adapter, REG_BAR_MODE_CTRL, 0x0201ffff);
 677
 678        if (pregistrypriv->wifi_spec)
 679                rtl8723au_write16(Adapter, REG_FAST_EDCA_CTRL, 0);
 680
 681        /*  Move by Neo for USB SS from above setp */
 682        _RfPowerSave(Adapter);
 683
 684        /*  2010/08/26 MH Merge from 8192CE. */
 685        /* sherry masked that it has been done in _RfPowerSave */
 686        /* 20110927 */
 687        /* recovery for 8192cu and 9723Au 20111017 */
 688        if (pwrctrlpriv->rf_pwrstate == rf_on) {
 689                if (pHalData->bIQKInitialized) {
 690                        rtl8723a_phy_iq_calibrate(Adapter, true);
 691                } else {
 692                        rtl8723a_phy_iq_calibrate(Adapter, false);
 693                        pHalData->bIQKInitialized = true;
 694                }
 695
 696                rtl8723a_odm_check_tx_power_tracking(Adapter);
 697
 698                rtl8723a_phy_lc_calibrate(Adapter);
 699
 700                rtl8723a_dual_antenna_detection(Adapter);
 701        }
 702
 703        /* fixed USB interface interference issue */
 704        rtl8723au_write8(Adapter, 0xfe40, 0xe0);
 705        rtl8723au_write8(Adapter, 0xfe41, 0x8d);
 706        rtl8723au_write8(Adapter, 0xfe42, 0x80);
 707        rtl8723au_write32(Adapter, 0x20c, 0xfd0320);
 708        /* Solve too many protocol error on USB bus */
 709        if (!IS_81xxC_VENDOR_UMC_A_CUT(pHalData->VersionID)) {
 710                /*  0xE6 = 0x94 */
 711                rtl8723au_write8(Adapter, 0xFE40, 0xE6);
 712                rtl8723au_write8(Adapter, 0xFE41, 0x94);
 713                rtl8723au_write8(Adapter, 0xFE42, 0x80);
 714
 715                /*  0xE0 = 0x19 */
 716                rtl8723au_write8(Adapter, 0xFE40, 0xE0);
 717                rtl8723au_write8(Adapter, 0xFE41, 0x19);
 718                rtl8723au_write8(Adapter, 0xFE42, 0x80);
 719
 720                /*  0xE5 = 0x91 */
 721                rtl8723au_write8(Adapter, 0xFE40, 0xE5);
 722                rtl8723au_write8(Adapter, 0xFE41, 0x91);
 723                rtl8723au_write8(Adapter, 0xFE42, 0x80);
 724
 725                /*  0xE2 = 0x81 */
 726                rtl8723au_write8(Adapter, 0xFE40, 0xE2);
 727                rtl8723au_write8(Adapter, 0xFE41, 0x81);
 728                rtl8723au_write8(Adapter, 0xFE42, 0x80);
 729
 730        }
 731
 732/*      _InitPABias(Adapter); */
 733
 734        /*  Init BT hw config. */
 735        rtl8723a_BT_init_hwconfig(Adapter);
 736
 737        rtl8723a_InitHalDm(Adapter);
 738
 739        val8 = (WiFiNavUpperUs + HAL_8723A_NAV_UPPER_UNIT - 1) /
 740                HAL_8723A_NAV_UPPER_UNIT;
 741        rtl8723au_write8(Adapter, REG_NAV_UPPER, val8);
 742
 743        /*  2011/03/09 MH debug only, UMC-B cut pass 2500 S5 test, but we need to fin root cause. */
 744        if (((rtl8723au_read32(Adapter, rFPGA0_RFMOD) & 0xFF000000) !=
 745             0x83000000)) {
 746                PHY_SetBBReg(Adapter, rFPGA0_RFMOD, BIT(24), 1);
 747                RT_TRACE(_module_hci_hal_init_c_, _drv_err_,
 748                         "%s: IQK fail recover\n", __func__);
 749        }
 750
 751        /* ack for xmit mgmt frames. */
 752        rtl8723au_write32(Adapter, REG_FWHW_TXQ_CTRL,
 753                          rtl8723au_read32(Adapter, REG_FWHW_TXQ_CTRL)|BIT(12));
 754
 755exit:
 756        if (status == _SUCCESS) {
 757                Adapter->hw_init_completed = true;
 758
 759                if (Adapter->registrypriv.notch_filter == 1)
 760                        rtl8723a_notch_filter(Adapter, 1);
 761        }
 762
 763        DBG_8723A("%s in %dms\n", __func__,
 764                  jiffies_to_msecs(jiffies - init_start_time));
 765        return status;
 766}
 767
 768static void phy_SsPwrSwitch92CU(struct rtw_adapter *Adapter,
 769                                enum rt_rf_power_state eRFPowerState)
 770{
 771        struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
 772        u8 sps0;
 773
 774        sps0 = rtl8723au_read8(Adapter, REG_SPS0_CTRL);
 775
 776        switch (eRFPowerState) {
 777        case rf_on:
 778                /*  1. Enable MAC Clock. Can not be enabled now. */
 779                /* WriteXBYTE(REG_SYS_CLKR+1,
 780                   ReadXBYTE(REG_SYS_CLKR+1) | BIT(3)); */
 781
 782                /*  2. Force PWM, Enable SPS18_LDO_Marco_Block */
 783                rtl8723au_write8(Adapter, REG_SPS0_CTRL,
 784                                 sps0 | BIT(0) | BIT(3));
 785
 786                /*  3. restore BB, AFE control register. */
 787                /* RF */
 788                if (pHalData->rf_type ==  RF_2T2R)
 789                        PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter,
 790                                     0x380038, 1);
 791                else
 792                        PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter,
 793                                     0x38, 1);
 794                PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, 0xf0, 1);
 795                PHY_SetBBReg(Adapter, rFPGA0_RFMOD, BIT(1), 0);
 796
 797                /* AFE */
 798                if (pHalData->rf_type ==  RF_2T2R)
 799                        rtl8723au_write32(Adapter, rRx_Wait_CCA, 0x63DB25A0);
 800                else if (pHalData->rf_type ==  RF_1T1R)
 801                        rtl8723au_write32(Adapter, rRx_Wait_CCA, 0x631B25A0);
 802
 803                /*  4. issue 3-wire command that RF set to Rx idle
 804                    mode. This is used to re-write the RX idle mode. */
 805                /*  We can only prvide a usual value instead and then
 806                    HW will modify the value by itself. */
 807                PHY_SetRFReg(Adapter, RF_PATH_A, RF_AC,
 808                             bRFRegOffsetMask, 0x32D95);
 809                if (pHalData->rf_type ==  RF_2T2R) {
 810                        PHY_SetRFReg(Adapter, RF_PATH_B, RF_AC,
 811                                     bRFRegOffsetMask, 0x32D95);
 812                }
 813                break;
 814        case rf_sleep:
 815        case rf_off:
 816                if (IS_81xxC_VENDOR_UMC_B_CUT(pHalData->VersionID))
 817                        sps0 &= ~BIT(0);
 818                else
 819                        sps0 &= ~(BIT(0) | BIT(3));
 820
 821                RT_TRACE(_module_hal_init_c_, _drv_err_, "SS LVL1\n");
 822                /*  Disable RF and BB only for SelectSuspend. */
 823
 824                /*  1. Set BB/RF to shutdown. */
 825                /*      (1) Reg878[5:3]= 0      RF rx_code for
 826                                                preamble power saving */
 827                /*      (2)Reg878[21:19]= 0     Turn off RF-B */
 828                /*      (3) RegC04[7:4]= 0      Turn off all paths
 829                                                for packet detection */
 830                /*      (4) Reg800[1] = 1       enable preamble power saving */
 831                Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_RF0] =
 832                        rtl8723au_read32(Adapter, rFPGA0_XAB_RFParameter);
 833                Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_RF1] =
 834                        rtl8723au_read32(Adapter, rOFDM0_TRxPathEnable);
 835                Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_RF2] =
 836                        rtl8723au_read32(Adapter, rFPGA0_RFMOD);
 837                if (pHalData->rf_type ==  RF_2T2R) {
 838                        PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter,
 839                                     0x380038, 0);
 840                } else if (pHalData->rf_type ==  RF_1T1R) {
 841                        PHY_SetBBReg(Adapter, rFPGA0_XAB_RFParameter, 0x38, 0);
 842                }
 843                PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, 0xf0, 0);
 844                PHY_SetBBReg(Adapter, rFPGA0_RFMOD, BIT(1), 1);
 845
 846                /*  2 .AFE control register to power down. bit[30:22] */
 847                Adapter->pwrctrlpriv.PS_BBRegBackup[PSBBREG_AFE0] =
 848                        rtl8723au_read32(Adapter, rRx_Wait_CCA);
 849                if (pHalData->rf_type ==  RF_2T2R)
 850                        rtl8723au_write32(Adapter, rRx_Wait_CCA, 0x00DB25A0);
 851                else if (pHalData->rf_type ==  RF_1T1R)
 852                        rtl8723au_write32(Adapter, rRx_Wait_CCA, 0x001B25A0);
 853
 854                /*  3. issue 3-wire command that RF set to power down.*/
 855                PHY_SetRFReg(Adapter, RF_PATH_A, RF_AC, bRFRegOffsetMask, 0);
 856                if (pHalData->rf_type ==  RF_2T2R)
 857                        PHY_SetRFReg(Adapter, RF_PATH_B, RF_AC,
 858                                     bRFRegOffsetMask, 0);
 859
 860                /*  4. Force PFM , disable SPS18_LDO_Marco_Block */
 861                rtl8723au_write8(Adapter, REG_SPS0_CTRL, sps0);
 862                break;
 863        default:
 864                break;
 865        }
 866}
 867
 868static void CardDisableRTL8723U(struct rtw_adapter *Adapter)
 869{
 870        u8              u1bTmp;
 871
 872        DBG_8723A("CardDisableRTL8723U\n");
 873        /*  USB-MF Card Disable Flow */
 874        /*  1. Run LPS WL RFOFF flow */
 875        HalPwrSeqCmdParsing23a(Adapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
 876                            PWR_INTF_USB_MSK, rtl8723AU_enter_lps_flow);
 877
 878        /*  2. 0x1F[7:0] = 0            turn off RF */
 879        rtl8723au_write8(Adapter, REG_RF_CTRL, 0x00);
 880
 881        /*      ==== Reset digital sequence   ====== */
 882        if ((rtl8723au_read8(Adapter, REG_MCUFWDL) & BIT(7)) &&
 883            Adapter->bFWReady) /* 8051 RAM code */
 884                rtl8723a_FirmwareSelfReset(Adapter);
 885
 886        /*  Reset MCU. Suggested by Filen. 2011.01.26. by tynli. */
 887        u1bTmp = rtl8723au_read8(Adapter, REG_SYS_FUNC_EN+1);
 888        rtl8723au_write8(Adapter, REG_SYS_FUNC_EN+1, u1bTmp & ~BIT(2));
 889
 890        /*  g.  MCUFWDL 0x80[1:0]= 0            reset MCU ready status */
 891        rtl8723au_write8(Adapter, REG_MCUFWDL, 0x00);
 892
 893        /*      ==== Reset digital sequence end ====== */
 894        /*  Card disable power action flow */
 895        HalPwrSeqCmdParsing23a(Adapter, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK,
 896                               PWR_INTF_USB_MSK,
 897                               rtl8723AU_card_disable_flow);
 898
 899        /*  Reset MCU IO Wrapper, added by Roger, 2011.08.30. */
 900        u1bTmp = rtl8723au_read8(Adapter, REG_RSV_CTRL + 1);
 901        rtl8723au_write8(Adapter, REG_RSV_CTRL+1, u1bTmp & ~BIT(0));
 902        u1bTmp = rtl8723au_read8(Adapter, REG_RSV_CTRL + 1);
 903        rtl8723au_write8(Adapter, REG_RSV_CTRL+1, u1bTmp | BIT(0));
 904
 905        /*  7. RSV_CTRL 0x1C[7:0] = 0x0E  lock ISO/CLK/Power control register */
 906        rtl8723au_write8(Adapter, REG_RSV_CTRL, 0x0e);
 907}
 908
 909int rtl8723au_hal_deinit(struct rtw_adapter *padapter)
 910{
 911        DBG_8723A("==> %s\n", __func__);
 912
 913#ifdef CONFIG_8723AU_BT_COEXIST
 914        BT_HaltProcess(padapter);
 915#endif
 916        /*  2011/02/18 To Fix RU LNA  power leakage problem. We need to
 917            execute below below in Adapter init and halt sequence.
 918            According to EEchou's opinion, we can enable the ability for all */
 919        /*  IC. Accord to johnny's opinion, only RU need the support. */
 920        CardDisableRTL8723U(padapter);
 921
 922        padapter->hw_init_completed = false;
 923
 924        return _SUCCESS;
 925}
 926
 927int rtl8723au_inirp_init(struct rtw_adapter *Adapter)
 928{
 929        u8 i;
 930        struct recv_buf *precvbuf;
 931        int status;
 932        struct recv_priv *precvpriv = &Adapter->recvpriv;
 933        struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
 934
 935        status = _SUCCESS;
 936
 937        RT_TRACE(_module_hci_hal_init_c_, _drv_info_, "===> usb_inirp_init\n");
 938
 939        /* issue Rx irp to receive data */
 940        precvbuf = (struct recv_buf *)precvpriv->precv_buf;
 941        for (i = 0; i < NR_RECVBUFF; i++) {
 942                if (rtl8723au_read_port(Adapter, 0, precvbuf) == _FAIL) {
 943                        RT_TRACE(_module_hci_hal_init_c_, _drv_err_,
 944                                 "usb_rx_init: usb_read_port error\n");
 945                        status = _FAIL;
 946                        goto exit;
 947                }
 948                precvbuf++;
 949        }
 950        if (rtl8723au_read_interrupt(Adapter) == _FAIL) {
 951                RT_TRACE(_module_hci_hal_init_c_, _drv_err_,
 952                         "%s: usb_read_interrupt error\n", __func__);
 953                status = _FAIL;
 954        }
 955        pHalData->IntrMask[0] = rtl8723au_read32(Adapter, REG_USB_HIMR);
 956        MSG_8723A("pHalData->IntrMask = 0x%04x\n", pHalData->IntrMask[0]);
 957        pHalData->IntrMask[0] |= UHIMR_C2HCMD|UHIMR_CPWM;
 958        rtl8723au_write32(Adapter, REG_USB_HIMR, pHalData->IntrMask[0]);
 959exit:
 960        RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
 961                 "<=== usb_inirp_init\n");
 962        return status;
 963}
 964
 965int rtl8723au_inirp_deinit(struct rtw_adapter *Adapter)
 966{
 967        struct hal_data_8723a   *pHalData = GET_HAL_DATA(Adapter);
 968
 969        RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
 970                 "===> usb_rx_deinit\n");
 971        rtl8723au_read_port_cancel(Adapter);
 972        pHalData->IntrMask[0] = rtl8723au_read32(Adapter, REG_USB_HIMR);
 973        MSG_8723A("%s pHalData->IntrMask = 0x%04x\n", __func__,
 974                  pHalData->IntrMask[0]);
 975        pHalData->IntrMask[0] = 0x0;
 976        rtl8723au_write32(Adapter, REG_USB_HIMR, pHalData->IntrMask[0]);
 977        RT_TRACE(_module_hci_hal_init_c_, _drv_info_,
 978                 "<=== usb_rx_deinit\n");
 979        return _SUCCESS;
 980}
 981
 982static void _ReadBoardType(struct rtw_adapter *Adapter, u8 *PROMContent,
 983                           bool AutoloadFail)
 984{
 985        struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
 986        u8 boardType = BOARD_USB_DONGLE;
 987
 988        if (AutoloadFail) {
 989                if (IS_8723_SERIES(pHalData->VersionID))
 990                        pHalData->rf_type = RF_1T1R;
 991                else
 992                        pHalData->rf_type = RF_2T2R;
 993                pHalData->BoardType = boardType;
 994                return;
 995        }
 996
 997        boardType = PROMContent[EEPROM_NORMAL_BoardType];
 998        boardType &= BOARD_TYPE_NORMAL_MASK;/* bit[7:5] */
 999        boardType >>= 5;
1000
1001        pHalData->BoardType = boardType;
1002        MSG_8723A("_ReadBoardType(%x)\n", pHalData->BoardType);
1003
1004        if (boardType == BOARD_USB_High_PA)
1005                pHalData->ExternalPA = 1;
1006}
1007
1008static void Hal_EfuseParseMACAddr_8723AU(struct rtw_adapter *padapter,
1009                                         u8 *hwinfo, bool AutoLoadFail)
1010{
1011        u16 i;
1012        u8 sMacAddr[ETH_ALEN] = {0x00, 0xE0, 0x4C, 0x87, 0x23, 0x00};
1013        struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
1014
1015        if (AutoLoadFail) {
1016                for (i = 0; i < 6; i++)
1017                        pEEPROM->mac_addr[i] = sMacAddr[i];
1018        } else {
1019                /* Read Permanent MAC address */
1020                memcpy(pEEPROM->mac_addr, &hwinfo[EEPROM_MAC_ADDR_8723AU],
1021                       ETH_ALEN);
1022        }
1023
1024        RT_TRACE(_module_hci_hal_init_c_, _drv_notice_,
1025                 "Hal_EfuseParseMACAddr_8723AU: Permanent Address =%02x:%02x:%02x:%02x:%02x:%02x\n",
1026                 pEEPROM->mac_addr[0], pEEPROM->mac_addr[1],
1027                 pEEPROM->mac_addr[2], pEEPROM->mac_addr[3],
1028                 pEEPROM->mac_addr[4], pEEPROM->mac_addr[5]);
1029}
1030
1031static void readAdapterInfo(struct rtw_adapter *padapter)
1032{
1033        struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(padapter);
1034        /* struct hal_data_8723a * pHalData = GET_HAL_DATA(padapter); */
1035        u8 hwinfo[HWSET_MAX_SIZE];
1036
1037        Hal_InitPGData(padapter, hwinfo);
1038        Hal_EfuseParseIDCode(padapter, hwinfo);
1039        Hal_EfuseParseEEPROMVer(padapter, hwinfo,
1040                                pEEPROM->bautoload_fail_flag);
1041        Hal_EfuseParseMACAddr_8723AU(padapter, hwinfo,
1042                                     pEEPROM->bautoload_fail_flag);
1043        Hal_EfuseParsetxpowerinfo_8723A(padapter, hwinfo,
1044                                        pEEPROM->bautoload_fail_flag);
1045        _ReadBoardType(padapter, hwinfo, pEEPROM->bautoload_fail_flag);
1046        Hal_EfuseParseBTCoexistInfo_8723A(padapter, hwinfo,
1047                                          pEEPROM->bautoload_fail_flag);
1048
1049        rtl8723a_EfuseParseChnlPlan(padapter, hwinfo,
1050                                    pEEPROM->bautoload_fail_flag);
1051        Hal_EfuseParseThermalMeter_8723A(padapter, hwinfo,
1052                                         pEEPROM->bautoload_fail_flag);
1053/*      _ReadRFSetting(Adapter, PROMContent, pEEPROM->bautoload_fail_flag); */
1054/*      _ReadPSSetting(Adapter, PROMContent, pEEPROM->bautoload_fail_flag); */
1055        Hal_EfuseParseAntennaDiversity(padapter, hwinfo,
1056                                       pEEPROM->bautoload_fail_flag);
1057
1058        Hal_EfuseParseEEPROMVer(padapter, hwinfo, pEEPROM->bautoload_fail_flag);
1059        Hal_EfuseParseCustomerID(padapter, hwinfo,
1060                                 pEEPROM->bautoload_fail_flag);
1061        Hal_EfuseParseRateIndicationOption(padapter, hwinfo,
1062                                           pEEPROM->bautoload_fail_flag);
1063        Hal_EfuseParseXtal_8723A(padapter, hwinfo,
1064                                 pEEPROM->bautoload_fail_flag);
1065
1066        /* hal_CustomizedBehavior_8723U(Adapter); */
1067
1068/*      Adapter->bDongle = (PROMContent[EEPROM_EASY_REPLACEMENT] == 1)? 0: 1; */
1069        DBG_8723A("%s(): REPLACEMENT = %x\n", __func__, padapter->bDongle);
1070}
1071
1072static void _ReadPROMContent(struct rtw_adapter *Adapter)
1073{
1074        struct eeprom_priv *pEEPROM = GET_EEPROM_EFUSE_PRIV(Adapter);
1075        u8 eeValue;
1076
1077        eeValue = rtl8723au_read8(Adapter, REG_9346CR);
1078        /*  To check system boot selection. */
1079        pEEPROM->EepromOrEfuse = (eeValue & BOOT_FROM_EEPROM) ? true : false;
1080        pEEPROM->bautoload_fail_flag = (eeValue & EEPROM_EN) ? false : true;
1081
1082        DBG_8723A("Boot from %s, Autoload %s !\n",
1083                  (pEEPROM->EepromOrEfuse ? "EEPROM" : "EFUSE"),
1084                  (pEEPROM->bautoload_fail_flag ? "Fail" : "OK"));
1085
1086        readAdapterInfo(Adapter);
1087}
1088
1089/*  */
1090/*      Description: */
1091/*              We should set Efuse cell selection to WiFi cell in default. */
1092/*  */
1093/*      Assumption: */
1094/*              PASSIVE_LEVEL */
1095/*  */
1096/*      Added by Roger, 2010.11.23. */
1097/*  */
1098static void hal_EfuseCellSel(struct rtw_adapter *Adapter)
1099{
1100        u32 value32;
1101
1102        value32 = rtl8723au_read32(Adapter, EFUSE_TEST);
1103        value32 = (value32 & ~EFUSE_SEL_MASK) | EFUSE_SEL(EFUSE_WIFI_SEL_0);
1104        rtl8723au_write32(Adapter, EFUSE_TEST, value32);
1105}
1106
1107void rtl8723a_read_adapter_info(struct rtw_adapter *Adapter)
1108{
1109        unsigned long start = jiffies;
1110
1111        /*  Read EEPROM size before call any EEPROM function */
1112        Adapter->EepromAddressSize = GetEEPROMSize8723A(Adapter);
1113
1114        MSG_8723A("====> _ReadAdapterInfo8723AU\n");
1115
1116        hal_EfuseCellSel(Adapter);
1117
1118        _ReadPROMContent(Adapter);
1119
1120        MSG_8723A("<==== _ReadAdapterInfo8723AU in %d ms\n",
1121                  jiffies_to_msecs(jiffies - start));
1122}
1123
1124/*  */
1125/*      Description: */
1126/*              Query setting of specified variable. */
1127/*  */
1128int GetHalDefVar8192CUsb(struct rtw_adapter *Adapter,
1129                         enum hal_def_variable eVariable, void *pValue)
1130{
1131        struct hal_data_8723a *pHalData = GET_HAL_DATA(Adapter);
1132        int bResult = _SUCCESS;
1133
1134        switch (eVariable) {
1135        case HAL_DEF_UNDERCORATEDSMOOTHEDPWDB:
1136                *((int *)pValue) = pHalData->dmpriv.UndecoratedSmoothedPWDB;
1137                break;
1138        case HAL_DEF_IS_SUPPORT_ANT_DIV:
1139                break;
1140        case HAL_DEF_CURRENT_ANTENNA:
1141                break;
1142        case HAL_DEF_DRVINFO_SZ:
1143                *((u32 *)pValue) = DRVINFO_SZ;
1144                break;
1145        case HAL_DEF_MAX_RECVBUF_SZ:
1146                *((u32 *)pValue) = MAX_RECVBUF_SZ;
1147                break;
1148        case HAL_DEF_RX_PACKET_OFFSET:
1149                *((u32 *)pValue) = RXDESC_SIZE + DRVINFO_SZ;
1150                break;
1151        case HAL_DEF_DBG_DUMP_RXPKT:
1152                *((u8 *)pValue) = pHalData->bDumpRxPkt;
1153                break;
1154        case HAL_DEF_DBG_DM_FUNC:
1155                *((u32 *)pValue) = pHalData->odmpriv.SupportAbility;
1156                break;
1157        case HW_VAR_MAX_RX_AMPDU_FACTOR:
1158                *((u32 *)pValue) = IEEE80211_HT_MAX_AMPDU_64K;
1159                break;
1160        case HW_DEF_ODM_DBG_FLAG:
1161        {
1162                struct dm_odm_t *pDM_Odm = &pHalData->odmpriv;
1163                printk("pDM_Odm->DebugComponents = 0x%llx\n",
1164                       pDM_Odm->DebugComponents);
1165        }
1166                break;
1167        default:
1168                bResult = _FAIL;
1169                break;
1170        }
1171
1172        return bResult;
1173}
1174
1175void rtl8723a_update_ramask(struct rtw_adapter *padapter,
1176                            u32 mac_id, u8 rssi_level)
1177{
1178        struct sta_info *psta;
1179        struct FW_Sta_Info *fw_sta;
1180        struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
1181        struct dm_priv *pdmpriv = &pHalData->dmpriv;
1182        struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
1183        struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
1184        struct wlan_bssid_ex *cur_network = &pmlmeinfo->network;
1185        u8 init_rate, networkType, raid, arg;
1186        u32 mask, rate_bitmap;
1187        u8 shortGIrate = false;
1188        int supportRateNum;
1189
1190        if (mac_id >= NUM_STA) /* CAM_SIZE */
1191                return;
1192
1193        psta = pmlmeinfo->FW_sta_info[mac_id].psta;
1194        if (psta == NULL)
1195                return;
1196
1197        switch (mac_id) {
1198        case 0:/*  for infra mode */
1199                supportRateNum =
1200                        rtw_get_rateset_len23a(cur_network->SupportedRates);
1201                networkType = judge_network_type23a(padapter,
1202                                                 cur_network->SupportedRates,
1203                                                 supportRateNum) & 0xf;
1204                /* pmlmeext->cur_wireless_mode = networkType; */
1205                raid = networktype_to_raid23a(networkType);
1206
1207                mask = update_supported_rate23a(cur_network->SupportedRates,
1208                                             supportRateNum);
1209                mask |= (pmlmeinfo->HT_enable) ?
1210                        update_MSC_rate23a(&pmlmeinfo->ht_cap) : 0;
1211
1212                if (support_short_GI23a(padapter, &pmlmeinfo->ht_cap))
1213                        shortGIrate = true;
1214                break;
1215
1216        case 1:/* for broadcast/multicast */
1217                fw_sta = &pmlmeinfo->FW_sta_info[mac_id]; 
1218                supportRateNum = rtw_get_rateset_len23a(fw_sta->SupportedRates);
1219                if (pmlmeext->cur_wireless_mode & WIRELESS_11B)
1220                        networkType = WIRELESS_11B;
1221                else
1222                        networkType = WIRELESS_11G;
1223                raid = networktype_to_raid23a(networkType);
1224
1225                mask = update_basic_rate23a(cur_network->SupportedRates,
1226                                         supportRateNum);
1227                break;
1228
1229        default: /* for each sta in IBSS */
1230                fw_sta = &pmlmeinfo->FW_sta_info[mac_id]; 
1231                supportRateNum = rtw_get_rateset_len23a(fw_sta->SupportedRates);
1232                networkType = judge_network_type23a(padapter,
1233                                                    fw_sta->SupportedRates,
1234                                                    supportRateNum) & 0xf;
1235                /* pmlmeext->cur_wireless_mode = networkType; */
1236                raid = networktype_to_raid23a(networkType);
1237
1238                mask = update_supported_rate23a(cur_network->SupportedRates,
1239                                                supportRateNum);
1240
1241                /* todo: support HT in IBSS */
1242                break;
1243        }
1244
1245        /* mask &= 0x0fffffff; */
1246        rate_bitmap = ODM_Get_Rate_Bitmap23a(pHalData, mac_id, mask,
1247                                             rssi_level);
1248        DBG_8723A("%s => mac_id:%d, networkType:0x%02x, "
1249                  "mask:0x%08x\n\t ==> rssi_level:%d, rate_bitmap:0x%08x\n",
1250                  __func__, mac_id, networkType, mask, rssi_level, rate_bitmap);
1251
1252        mask &= rate_bitmap;
1253        mask |= ((raid << 28) & 0xf0000000);
1254
1255        init_rate = get_highest_rate_idx23a(mask) & 0x3f;
1256
1257        arg = mac_id & 0x1f;/* MACID */
1258        arg |= BIT(7);
1259
1260        if (shortGIrate == true)
1261                arg |= BIT(5);
1262
1263        DBG_8723A("update raid entry, mask = 0x%x, arg = 0x%x\n", mask, arg);
1264
1265        rtl8723a_set_raid_cmd(padapter, mask, arg);
1266
1267        /* set ra_id */
1268        psta->raid = raid;
1269        psta->init_rate = init_rate;
1270
1271        /* set correct initial date rate for each mac_id */
1272        pdmpriv->INIDATA_RATE[mac_id] = init_rate;
1273}
1274