linux/drivers/staging/rtl8723au/hal/hal_com.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#include <osdep_service.h>
  16#include <drv_types.h>
  17
  18#include <hal_intf.h>
  19#include <hal_com.h>
  20#include <rtl8723a_hal.h>
  21#include <usb_ops_linux.h>
  22
  23#define _HAL_INIT_C_
  24
  25#define EEPROM_CHANNEL_PLAN_BY_HW_MASK  0x80
  26
  27/* return the final channel plan decision */
  28/* hw_channel_plan:  channel plan from HW (efuse/eeprom) */
  29/* sw_channel_plan:  channel plan from SW (registry/module param) */
  30/* def_channel_plan: channel plan used when the former two is invalid */
  31u8 hal_com_get_channel_plan23a(struct rtw_adapter *padapter, u8 hw_channel_plan,
  32                            u8 sw_channel_plan, u8 def_channel_plan,
  33                            bool AutoLoadFail)
  34{
  35        u8 swConfig;
  36        u8 chnlPlan;
  37
  38        swConfig = true;
  39        if (!AutoLoadFail) {
  40                if (!rtw_is_channel_plan_valid(sw_channel_plan))
  41                        swConfig = false;
  42                if (hw_channel_plan & EEPROM_CHANNEL_PLAN_BY_HW_MASK)
  43                        swConfig = false;
  44        }
  45
  46        if (swConfig == true)
  47                chnlPlan = sw_channel_plan;
  48        else
  49                chnlPlan = hw_channel_plan & (~EEPROM_CHANNEL_PLAN_BY_HW_MASK);
  50
  51        if (!rtw_is_channel_plan_valid(chnlPlan))
  52                chnlPlan = def_channel_plan;
  53
  54        return chnlPlan;
  55}
  56
  57u8 MRateToHwRate23a(u8 rate)
  58{
  59        u8 ret = DESC_RATE1M;
  60
  61        switch (rate) {
  62                /*  CCK and OFDM non-HT rates */
  63        case IEEE80211_CCK_RATE_1MB:
  64                ret = DESC_RATE1M;
  65                break;
  66        case IEEE80211_CCK_RATE_2MB:
  67                ret = DESC_RATE2M;
  68                break;
  69        case IEEE80211_CCK_RATE_5MB:
  70                ret = DESC_RATE5_5M;
  71                break;
  72        case IEEE80211_CCK_RATE_11MB:
  73                ret = DESC_RATE11M;
  74                break;
  75        case IEEE80211_OFDM_RATE_6MB:
  76                ret = DESC_RATE6M;
  77                break;
  78        case IEEE80211_OFDM_RATE_9MB:
  79                ret = DESC_RATE9M;
  80                break;
  81        case IEEE80211_OFDM_RATE_12MB:
  82                ret = DESC_RATE12M;
  83                break;
  84        case IEEE80211_OFDM_RATE_18MB:
  85                ret = DESC_RATE18M;
  86                break;
  87        case IEEE80211_OFDM_RATE_24MB:
  88                ret = DESC_RATE24M;
  89                break;
  90        case IEEE80211_OFDM_RATE_36MB:
  91                ret = DESC_RATE36M;
  92                break;
  93        case IEEE80211_OFDM_RATE_48MB:
  94                ret = DESC_RATE48M;
  95                break;
  96        case IEEE80211_OFDM_RATE_54MB:
  97                ret = DESC_RATE54M;
  98                break;
  99
 100                /*  HT rates since here */
 101                /* case MGN_MCS0:       ret = DESC_RATEMCS0;    break; */
 102                /* case MGN_MCS1:       ret = DESC_RATEMCS1;    break; */
 103                /* case MGN_MCS2:       ret = DESC_RATEMCS2;    break; */
 104                /* case MGN_MCS3:       ret = DESC_RATEMCS3;    break; */
 105                /* case MGN_MCS4:       ret = DESC_RATEMCS4;    break; */
 106                /* case MGN_MCS5:       ret = DESC_RATEMCS5;    break; */
 107                /* case MGN_MCS6:       ret = DESC_RATEMCS6;    break; */
 108                /* case MGN_MCS7:       ret = DESC_RATEMCS7;    break; */
 109
 110        default:
 111                break;
 112        }
 113        return ret;
 114}
 115
 116void HalSetBrateCfg23a(struct rtw_adapter *padapter, u8 *mBratesOS)
 117{
 118        struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
 119        u8 i, is_brate, brate;
 120        u16 brate_cfg = 0;
 121        u8 rate_index;
 122
 123        for (i = 0; i < NDIS_802_11_LENGTH_RATES_EX; i++) {
 124                is_brate = mBratesOS[i] & IEEE80211_BASIC_RATE_MASK;
 125                brate = mBratesOS[i] & 0x7f;
 126
 127                if (is_brate) {
 128                        switch (brate) {
 129                        case IEEE80211_CCK_RATE_1MB:
 130                                brate_cfg |= RATE_1M;
 131                                break;
 132                        case IEEE80211_CCK_RATE_2MB:
 133                                brate_cfg |= RATE_2M;
 134                                break;
 135                        case IEEE80211_CCK_RATE_5MB:
 136                                brate_cfg |= RATE_5_5M;
 137                                break;
 138                        case IEEE80211_CCK_RATE_11MB:
 139                                brate_cfg |= RATE_11M;
 140                                break;
 141                        case IEEE80211_OFDM_RATE_6MB:
 142                                brate_cfg |= RATE_6M;
 143                                break;
 144                        case IEEE80211_OFDM_RATE_9MB:
 145                                brate_cfg |= RATE_9M;
 146                                break;
 147                        case IEEE80211_OFDM_RATE_12MB:
 148                                brate_cfg |= RATE_12M;
 149                                break;
 150                        case IEEE80211_OFDM_RATE_18MB:
 151                                brate_cfg |= RATE_18M;
 152                                break;
 153                        case IEEE80211_OFDM_RATE_24MB:
 154                                brate_cfg |= RATE_24M;
 155                                break;
 156                        case IEEE80211_OFDM_RATE_36MB:
 157                                brate_cfg |= RATE_36M;
 158                                break;
 159                        case IEEE80211_OFDM_RATE_48MB:
 160                                brate_cfg |= RATE_48M;
 161                                break;
 162                        case IEEE80211_OFDM_RATE_54MB:
 163                                brate_cfg |= RATE_54M;
 164                                break;
 165                        }
 166                }
 167        }
 168
 169        /*  2007.01.16, by Emily */
 170        /*  Select RRSR (in Legacy-OFDM and CCK) */
 171        /*  For 8190, we select only 24M, 12M, 6M, 11M, 5.5M, 2M,
 172            and 1M from the Basic rate. */
 173        /*  We do not use other rates. */
 174        /* 2011.03.30 add by Luke Lee */
 175        /* CCK 2M ACK should be disabled for some BCM and Atheros AP IOT */
 176        /* because CCK 2M has poor TXEVM */
 177        /* CCK 5.5M & 11M ACK should be enabled for better
 178           performance */
 179
 180        brate_cfg = (brate_cfg | 0xd) & 0x15d;
 181        pHalData->BasicRateSet = brate_cfg;
 182        brate_cfg |= 0x01;      /*  default enable 1M ACK rate */
 183        DBG_8723A("HW_VAR_BASIC_RATE: BrateCfg(%#x)\n", brate_cfg);
 184
 185        /*  Set RRSR rate table. */
 186        rtl8723au_write8(padapter, REG_RRSR, brate_cfg & 0xff);
 187        rtl8723au_write8(padapter, REG_RRSR + 1, (brate_cfg >> 8) & 0xff);
 188        rtl8723au_write8(padapter, REG_RRSR + 2,
 189                         rtl8723au_read8(padapter, REG_RRSR + 2) & 0xf0);
 190
 191        rate_index = 0;
 192        /*  Set RTS initial rate */
 193        while (brate_cfg > 0x1) {
 194                brate_cfg >>= 1;
 195                rate_index++;
 196        }
 197                /*  Ziv - Check */
 198        rtl8723au_write8(padapter, REG_INIRTS_RATE_SEL, rate_index);
 199}
 200
 201static void _OneOutPipeMapping(struct rtw_adapter *pAdapter)
 202{
 203        struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
 204
 205        pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0];   /* VO */
 206        pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0];   /* VI */
 207        pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[0];   /* BE */
 208        pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0];   /* BK */
 209
 210        pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0];   /* BCN */
 211        pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0];   /* MGT */
 212        pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0];   /* HIGH */
 213        pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0];   /* TXCMD */
 214}
 215
 216static void _TwoOutPipeMapping(struct rtw_adapter *pAdapter, bool bWIFICfg)
 217{
 218        struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
 219
 220        if (bWIFICfg) {         /* WMM */
 221                /*    BK,   BE,   VI,   VO,   BCN,  CMD,  MGT, HIGH, HCCA */
 222                /*     0,    1,    0,    1,     0,    0,    0,    0,    0 }; */
 223                /* 0:H, 1:L */
 224                pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[1]; /* VO */
 225                pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0]; /* VI */
 226                pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1]; /* BE */
 227                pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[0]; /* BK */
 228
 229                pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0]; /* BCN */
 230                pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0]; /* MGT */
 231                pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0]; /* HIGH */
 232                pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0]; /* TXCMD*/
 233        } else {                /* typical setting */
 234                /*    BK,   BE,   VI,   VO,   BCN,  CMD,  MGT, HIGH, HCCA */
 235                /*     1,    1,    0,    0,     0,    0,    0,    0,    0 }; */
 236                /* 0:H, 1:L */
 237                pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0]; /* VO */
 238                pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[0]; /* VI */
 239                pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[1]; /* BE */
 240                pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1]; /* BK */
 241
 242                pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0]; /* BCN */
 243                pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0]; /* MGT */
 244                pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0]; /* HIGH */
 245                pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0]; /* TXCMD*/
 246        }
 247}
 248
 249static void _ThreeOutPipeMapping(struct rtw_adapter *pAdapter, bool bWIFICfg)
 250{
 251        struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(pAdapter);
 252
 253        if (bWIFICfg) {         /* for WMM */
 254                /*    BK,   BE,   VI,   VO,   BCN,  CMD,  MGT, HIGH, HCCA */
 255                /*     1,    2,    1,    0,     0,    0,    0,    0,    0 }; */
 256                /* 0:H, 1:N, 2:L */
 257                pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0]; /* VO */
 258                pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1]; /* VI */
 259                pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2]; /* BE */
 260                pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[1]; /* BK */
 261
 262                pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0]; /* BCN */
 263                pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0]; /* MGT */
 264                pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0]; /* HIGH */
 265                pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0]; /* TXCMD*/
 266        } else {                /* typical setting */
 267                /*    BK,   BE,   VI,   VO,   BCN,  CMD,  MGT, HIGH, HCCA */
 268                /*     2,    2,    1,    0,     0,    0,    0,    0,    0 }; */
 269                /* 0:H, 1:N, 2:L */
 270                pdvobjpriv->Queue2Pipe[0] = pdvobjpriv->RtOutPipe[0]; /* VO */
 271                pdvobjpriv->Queue2Pipe[1] = pdvobjpriv->RtOutPipe[1]; /* VI */
 272                pdvobjpriv->Queue2Pipe[2] = pdvobjpriv->RtOutPipe[2]; /* BE */
 273                pdvobjpriv->Queue2Pipe[3] = pdvobjpriv->RtOutPipe[2]; /* BK */
 274
 275                pdvobjpriv->Queue2Pipe[4] = pdvobjpriv->RtOutPipe[0]; /* BCN */
 276                pdvobjpriv->Queue2Pipe[5] = pdvobjpriv->RtOutPipe[0]; /* MGT */
 277                pdvobjpriv->Queue2Pipe[6] = pdvobjpriv->RtOutPipe[0]; /* HIGH */
 278                pdvobjpriv->Queue2Pipe[7] = pdvobjpriv->RtOutPipe[0]; /* TXCMD*/
 279        }
 280}
 281
 282bool Hal_MappingOutPipe23a(struct rtw_adapter *pAdapter, u8 NumOutPipe)
 283{
 284        struct registry_priv *pregistrypriv = &pAdapter->registrypriv;
 285        bool bWIFICfg = (pregistrypriv->wifi_spec) ? true : false;
 286        bool result = true;
 287
 288        switch (NumOutPipe) {
 289        case 2:
 290                _TwoOutPipeMapping(pAdapter, bWIFICfg);
 291                break;
 292        case 3:
 293                _ThreeOutPipeMapping(pAdapter, bWIFICfg);
 294                break;
 295        case 1:
 296                _OneOutPipeMapping(pAdapter);
 297                break;
 298        default:
 299                result = false;
 300                break;
 301        }
 302
 303        return result;
 304}
 305
 306/*
 307* C2H event format:
 308* Field  TRIGGER                CONTENT    CMD_SEQ      CMD_LEN          CMD_ID
 309* BITS   [127:120]      [119:16]      [15:8]              [7:4]            [3:0]
 310*/
 311
 312void c2h_evt_clear23a(struct rtw_adapter *adapter)
 313{
 314        rtl8723au_write8(adapter, REG_C2HEVT_CLEAR, C2H_EVT_HOST_CLOSE);
 315}
 316
 317int c2h_evt_read23a(struct rtw_adapter *adapter, u8 *buf)
 318{
 319        int ret = _FAIL;
 320        struct c2h_evt_hdr *c2h_evt;
 321        int i;
 322        u8 trigger;
 323
 324        if (buf == NULL)
 325                goto exit;
 326
 327        trigger = rtl8723au_read8(adapter, REG_C2HEVT_CLEAR);
 328
 329        if (trigger == C2H_EVT_HOST_CLOSE)
 330                goto exit;      /* Not ready */
 331        if (trigger != C2H_EVT_FW_CLOSE)
 332                goto clear_evt; /* Not a valid value */
 333
 334        c2h_evt = (struct c2h_evt_hdr *)buf;
 335
 336        memset(c2h_evt, 0, 16);
 337
 338        *buf = rtl8723au_read8(adapter, REG_C2HEVT_MSG_NORMAL);
 339        *(buf + 1) = rtl8723au_read8(adapter, REG_C2HEVT_MSG_NORMAL + 1);
 340
 341        RT_PRINT_DATA(_module_hal_init_c_, _drv_info_, "c2h_evt_read23a(): ",
 342                      &c2h_evt, sizeof(c2h_evt));
 343
 344        if (0) {
 345                DBG_8723A("%s id:%u, len:%u, seq:%u, trigger:0x%02x\n",
 346                          __func__, c2h_evt->id, c2h_evt->plen, c2h_evt->seq,
 347                          trigger);
 348        }
 349
 350        /* Read the content */
 351        for (i = 0; i < c2h_evt->plen; i++)
 352                c2h_evt->payload[i] = rtl8723au_read8(adapter,
 353                                                REG_C2HEVT_MSG_NORMAL +
 354                                                sizeof(*c2h_evt) + i);
 355
 356        RT_PRINT_DATA(_module_hal_init_c_, _drv_info_,
 357                      "c2h_evt_read23a(): Command Content:\n", c2h_evt->payload,
 358                      c2h_evt->plen);
 359
 360        ret = _SUCCESS;
 361
 362clear_evt:
 363        /*
 364         * Clear event to notify FW we have read the command.
 365         * If this field isn't clear, the FW won't update the
 366         * next command message.
 367         */
 368        c2h_evt_clear23a(adapter);
 369exit:
 370        return ret;
 371}
 372
 373void
 374rtl8723a_set_ampdu_min_space(struct rtw_adapter *padapter, u8 MinSpacingToSet)
 375{
 376        u8 SecMinSpace;
 377
 378        if (MinSpacingToSet <= 7) {
 379                switch (padapter->securitypriv.dot11PrivacyAlgrthm) {
 380                case 0:
 381                case WLAN_CIPHER_SUITE_CCMP:
 382                        SecMinSpace = 0;
 383                        break;
 384
 385                case WLAN_CIPHER_SUITE_WEP40:
 386                case WLAN_CIPHER_SUITE_WEP104:
 387                case WLAN_CIPHER_SUITE_TKIP:
 388                        SecMinSpace = 6;
 389                        break;
 390                default:
 391                        SecMinSpace = 7;
 392                        break;
 393                }
 394
 395                if (MinSpacingToSet < SecMinSpace)
 396                        MinSpacingToSet = SecMinSpace;
 397
 398                MinSpacingToSet |=
 399                        rtl8723au_read8(padapter, REG_AMPDU_MIN_SPACE) & 0xf8;
 400                rtl8723au_write8(padapter, REG_AMPDU_MIN_SPACE,
 401                                 MinSpacingToSet);
 402        }
 403}
 404
 405void rtl8723a_set_ampdu_factor(struct rtw_adapter *padapter, u8 FactorToSet)
 406{
 407        u8 RegToSet_Normal[4] = { 0x41, 0xa8, 0x72, 0xb9 };
 408        u8 MaxAggNum;
 409        u8 *pRegToSet;
 410        u8 index = 0;
 411
 412        pRegToSet = RegToSet_Normal;    /*  0xb972a841; */
 413
 414        if (rtl8723a_BT_enabled(padapter) &&
 415            rtl8723a_BT_using_antenna_1(padapter))
 416                MaxAggNum = 0x8;
 417        else
 418                MaxAggNum = 0xF;
 419
 420        if (FactorToSet <= 3) {
 421                FactorToSet = 1 << (FactorToSet + 2);
 422                if (FactorToSet > MaxAggNum)
 423                        FactorToSet = MaxAggNum;
 424
 425                for (index = 0; index < 4; index++) {
 426                        if ((pRegToSet[index] & 0xf0) > (FactorToSet << 4))
 427                                pRegToSet[index] = (pRegToSet[index] & 0x0f) |
 428                                        (FactorToSet << 4);
 429
 430                        if ((pRegToSet[index] & 0x0f) > FactorToSet)
 431                                pRegToSet[index] = (pRegToSet[index] & 0xf0) |
 432                                        FactorToSet;
 433
 434                        rtl8723au_write8(padapter, REG_AGGLEN_LMT + index,
 435                                         pRegToSet[index]);
 436                }
 437        }
 438}
 439
 440void rtl8723a_set_acm_ctrl(struct rtw_adapter *padapter, u8 ctrl)
 441{
 442        u8 hwctrl = 0;
 443
 444        if (ctrl != 0) {
 445                hwctrl |= AcmHw_HwEn;
 446
 447                if (ctrl & BIT(1))      /*  BE */
 448                        hwctrl |= AcmHw_BeqEn;
 449
 450                if (ctrl & BIT(2))      /*  VI */
 451                        hwctrl |= AcmHw_ViqEn;
 452
 453                if (ctrl & BIT(3))      /*  VO */
 454                        hwctrl |= AcmHw_VoqEn;
 455        }
 456
 457        DBG_8723A("[HW_VAR_ACM_CTRL] Write 0x%02X\n", hwctrl);
 458        rtl8723au_write8(padapter, REG_ACMHWCTRL, hwctrl);
 459}
 460
 461void rtl8723a_set_media_status(struct rtw_adapter *padapter, u8 status)
 462{
 463        u8 val8;
 464
 465        val8 = rtl8723au_read8(padapter, MSR) & 0x0c;
 466        val8 |= status;
 467        rtl8723au_write8(padapter, MSR, val8);
 468}
 469
 470void rtl8723a_set_media_status1(struct rtw_adapter *padapter, u8 status)
 471{
 472        u8 val8;
 473
 474        val8 = rtl8723au_read8(padapter, MSR) & 0x03;
 475        val8 |= status << 2;
 476        rtl8723au_write8(padapter, MSR, val8);
 477}
 478
 479void rtl8723a_set_bcn_func(struct rtw_adapter *padapter, u8 val)
 480{
 481        if (val)
 482                SetBcnCtrlReg23a(padapter, EN_BCN_FUNCTION | EN_TXBCN_RPT, 0);
 483        else
 484                SetBcnCtrlReg23a(padapter, 0, EN_BCN_FUNCTION | EN_TXBCN_RPT);
 485}
 486
 487void rtl8723a_check_bssid(struct rtw_adapter *padapter, u8 val)
 488{
 489        u32 val32;
 490
 491        val32 = rtl8723au_read32(padapter, REG_RCR);
 492        if (val)
 493                val32 |= RCR_CBSSID_DATA | RCR_CBSSID_BCN;
 494        else
 495                val32 &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);
 496        rtl8723au_write32(padapter, REG_RCR, val32);
 497}
 498
 499void rtl8723a_mlme_sitesurvey(struct rtw_adapter *padapter, u8 flag)
 500{
 501        if (flag) {     /* under sitesurvey */
 502                u32 v32;
 503
 504                /*  config RCR to receive different BSSID & not
 505                    to receive data frame */
 506                v32 = rtl8723au_read32(padapter, REG_RCR);
 507                v32 &= ~(RCR_CBSSID_BCN);
 508                rtl8723au_write32(padapter, REG_RCR, v32);
 509                /*  reject all data frame */
 510                rtl8723au_write16(padapter, REG_RXFLTMAP2, 0);
 511
 512                /*  disable update TSF */
 513                SetBcnCtrlReg23a(padapter, DIS_TSF_UDT, 0);
 514        } else {        /* sitesurvey done */
 515
 516                struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
 517                struct mlme_ext_info *pmlmeinfo;
 518                u32 v32;
 519
 520                pmlmeinfo = &pmlmeext->mlmext_info;
 521
 522                if ((is_client_associated_to_ap23a(padapter) == true) ||
 523                    ((pmlmeinfo->state & 0x03) == MSR_ADHOC) ||
 524                    ((pmlmeinfo->state & 0x03) == MSR_AP)) {
 525                        /*  enable to rx data frame */
 526                        rtl8723au_write16(padapter, REG_RXFLTMAP2, 0xFFFF);
 527
 528                        /*  enable update TSF */
 529                        SetBcnCtrlReg23a(padapter, 0, DIS_TSF_UDT);
 530                }
 531
 532                v32 = rtl8723au_read32(padapter, REG_RCR);
 533                v32 |= RCR_CBSSID_BCN;
 534                rtl8723au_write32(padapter, REG_RCR, v32);
 535        }
 536
 537        rtl8723a_BT_wifiscan_notify(padapter, flag ? true : false);
 538}
 539
 540void rtl8723a_on_rcr_am(struct rtw_adapter *padapter)
 541{
 542        rtl8723au_write32(padapter, REG_RCR,
 543                    rtl8723au_read32(padapter, REG_RCR) | RCR_AM);
 544        DBG_8723A("%s, %d, RCR = %x\n", __func__, __LINE__,
 545                  rtl8723au_read32(padapter, REG_RCR));
 546}
 547
 548void rtl8723a_off_rcr_am(struct rtw_adapter *padapter)
 549{
 550        rtl8723au_write32(padapter, REG_RCR,
 551                    rtl8723au_read32(padapter, REG_RCR) & (~RCR_AM));
 552        DBG_8723A("%s, %d, RCR = %x\n", __func__, __LINE__,
 553                  rtl8723au_read32(padapter, REG_RCR));
 554}
 555
 556void rtl8723a_set_slot_time(struct rtw_adapter *padapter, u8 slottime)
 557{
 558        u8 u1bAIFS, aSifsTime;
 559        struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
 560        struct mlme_ext_info *pmlmeinfo = &pmlmeext->mlmext_info;
 561
 562        rtl8723au_write8(padapter, REG_SLOT, slottime);
 563
 564        if (pmlmeinfo->WMM_enable == 0) {
 565                if (pmlmeext->cur_wireless_mode == WIRELESS_11B)
 566                        aSifsTime = 10;
 567                else
 568                        aSifsTime = 16;
 569
 570                u1bAIFS = aSifsTime + (2 * pmlmeinfo->slotTime);
 571
 572                /*  <Roger_EXP> Temporary removed, 2008.06.20. */
 573                rtl8723au_write8(padapter, REG_EDCA_VO_PARAM, u1bAIFS);
 574                rtl8723au_write8(padapter, REG_EDCA_VI_PARAM, u1bAIFS);
 575                rtl8723au_write8(padapter, REG_EDCA_BE_PARAM, u1bAIFS);
 576                rtl8723au_write8(padapter, REG_EDCA_BK_PARAM, u1bAIFS);
 577        }
 578}
 579
 580void rtl8723a_ack_preamble(struct rtw_adapter *padapter, u8 bShortPreamble)
 581{
 582        struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
 583        u8 regTmp;
 584
 585        /*  Joseph marked out for Netgear 3500 TKIP
 586            channel 7 issue.(Temporarily) */
 587        regTmp = (pHalData->nCur40MhzPrimeSC) << 5;
 588        /* regTmp = 0; */
 589        if (bShortPreamble)
 590                regTmp |= 0x80;
 591        rtl8723au_write8(padapter, REG_RRSR + 2, regTmp);
 592}
 593
 594void rtl8723a_set_sec_cfg(struct rtw_adapter *padapter, u8 sec)
 595{
 596        rtl8723au_write8(padapter, REG_SECCFG, sec);
 597}
 598
 599void rtl8723a_cam_empty_entry(struct rtw_adapter *padapter, u8 ucIndex)
 600{
 601        u8 i;
 602        u32 ulCommand = 0;
 603        u32 ulContent = 0;
 604        u32 ulEncAlgo = CAM_AES;
 605
 606        for (i = 0; i < CAM_CONTENT_COUNT; i++) {
 607                /*  filled id in CAM config 2 byte */
 608                if (i == 0) {
 609                        ulContent |= (ucIndex & 0x03) |
 610                                ((u16) (ulEncAlgo) << 2);
 611                        /* ulContent |= CAM_VALID; */
 612                } else {
 613                        ulContent = 0;
 614                }
 615                /*  polling bit, and No Write enable, and address */
 616                ulCommand = CAM_CONTENT_COUNT * ucIndex + i;
 617                ulCommand = ulCommand | CAM_POLLINIG | CAM_WRITE;
 618                /*  write content 0 is equall to mark invalid */
 619                /* delay_ms(40); */
 620                rtl8723au_write32(padapter, WCAMI, ulContent);
 621                /* delay_ms(40); */
 622                rtl8723au_write32(padapter, REG_CAMCMD, ulCommand);
 623        }
 624}
 625
 626void rtl8723a_cam_invalidate_all(struct rtw_adapter *padapter)
 627{
 628        rtl8723au_write32(padapter, REG_CAMCMD, CAM_POLLINIG | BIT(30));
 629}
 630
 631void rtl8723a_cam_write(struct rtw_adapter *padapter,
 632                        u8 entry, u16 ctrl, const u8 *mac, const u8 *key)
 633{
 634        u32 cmd;
 635        unsigned int i, val, addr;
 636        int j;
 637
 638        addr = entry << 3;
 639
 640        for (j = 5; j >= 0; j--) {
 641                switch (j) {
 642                case 0:
 643                        val = ctrl | (mac[0] << 16) | (mac[1] << 24);
 644                        break;
 645                case 1:
 646                        val = mac[2] | (mac[3] << 8) |
 647                                (mac[4] << 16) | (mac[5] << 24);
 648                        break;
 649                default:
 650                        i = (j - 2) << 2;
 651                        val = key[i] | (key[i+1] << 8) |
 652                                (key[i+2] << 16) | (key[i+3] << 24);
 653                        break;
 654                }
 655
 656                rtl8723au_write32(padapter, WCAMI, val);
 657                cmd = CAM_POLLINIG | CAM_WRITE | (addr + j);
 658                rtl8723au_write32(padapter, REG_CAMCMD, cmd);
 659
 660                /* DBG_8723A("%s => cam write: %x, %x\n", __func__, cmd, val);*/
 661        }
 662}
 663
 664void rtl8723a_fifo_cleanup(struct rtw_adapter *padapter)
 665{
 666#define RW_RELEASE_EN           BIT(18)
 667#define RXDMA_IDLE              BIT(17)
 668
 669        struct pwrctrl_priv *pwrpriv = &padapter->pwrctrlpriv;
 670        u8 trycnt = 100;
 671
 672        /*  pause tx */
 673        rtl8723au_write8(padapter, REG_TXPAUSE, 0xff);
 674
 675        /*  keep sn */
 676        padapter->xmitpriv.nqos_ssn = rtl8723au_read8(padapter, REG_NQOS_SEQ);
 677
 678        if (pwrpriv->bkeepfwalive != true) {
 679                u32 v32;
 680
 681                /*  RX DMA stop */
 682                v32 = rtl8723au_read32(padapter, REG_RXPKT_NUM);
 683                v32 |= RW_RELEASE_EN;
 684                rtl8723au_write32(padapter, REG_RXPKT_NUM, v32);
 685                do {
 686                        v32 = rtl8723au_read32(padapter,
 687                                               REG_RXPKT_NUM) & RXDMA_IDLE;
 688                        if (!v32)
 689                                break;
 690                } while (trycnt--);
 691                if (trycnt == 0)
 692                        DBG_8723A("Stop RX DMA failed......\n");
 693
 694                /*  RQPN Load 0 */
 695                rtl8723au_write16(padapter, REG_RQPN_NPQ, 0);
 696                rtl8723au_write32(padapter, REG_RQPN, 0x80000000);
 697                mdelay(10);
 698        }
 699}
 700
 701void rtl8723a_bcn_valid(struct rtw_adapter *padapter)
 702{
 703        /* BCN_VALID, BIT16 of REG_TDECTRL = BIT0 of REG_TDECTRL+2,
 704           write 1 to clear, Clear by sw */
 705        rtl8723au_write8(padapter, REG_TDECTRL + 2,
 706                         rtl8723au_read8(padapter, REG_TDECTRL + 2) | BIT(0));
 707}
 708
 709bool rtl8723a_get_bcn_valid(struct rtw_adapter *padapter)
 710{
 711        bool retval;
 712
 713        retval = (rtl8723au_read8(padapter, REG_TDECTRL + 2) & BIT(0)) ? true : false;
 714
 715        return retval;
 716}
 717
 718void rtl8723a_set_beacon_interval(struct rtw_adapter *padapter, u16 interval)
 719{
 720        rtl8723au_write16(padapter, REG_BCN_INTERVAL, interval);
 721}
 722
 723void rtl8723a_set_resp_sifs(struct rtw_adapter *padapter,
 724                            u8 r2t1, u8 r2t2, u8 t2t1, u8 t2t2)
 725{
 726        /* SIFS_Timer = 0x0a0a0808; */
 727        /* RESP_SIFS for CCK */
 728        /*  SIFS_T2T_CCK (0x08) */
 729        rtl8723au_write8(padapter, REG_R2T_SIFS, r2t1);
 730        /* SIFS_R2T_CCK(0x08) */
 731        rtl8723au_write8(padapter, REG_R2T_SIFS + 1, r2t2);
 732        /* RESP_SIFS for OFDM */
 733        /* SIFS_T2T_OFDM (0x0a) */
 734        rtl8723au_write8(padapter, REG_T2T_SIFS, t2t1);
 735        /* SIFS_R2T_OFDM(0x0a) */
 736        rtl8723au_write8(padapter, REG_T2T_SIFS + 1, t2t2);
 737}
 738
 739void rtl8723a_set_ac_param_vo(struct rtw_adapter *padapter, u32 vo)
 740{
 741        rtl8723au_write32(padapter, REG_EDCA_VO_PARAM, vo);
 742}
 743
 744void rtl8723a_set_ac_param_vi(struct rtw_adapter *padapter, u32 vi)
 745{
 746        rtl8723au_write32(padapter, REG_EDCA_VI_PARAM, vi);
 747}
 748
 749void rtl8723a_set_ac_param_be(struct rtw_adapter *padapter, u32 be)
 750{
 751        struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
 752
 753        pHalData->AcParam_BE = be;
 754        rtl8723au_write32(padapter, REG_EDCA_BE_PARAM, be);
 755}
 756
 757void rtl8723a_set_ac_param_bk(struct rtw_adapter *padapter, u32 bk)
 758{
 759        rtl8723au_write32(padapter, REG_EDCA_BK_PARAM, bk);
 760}
 761
 762void rtl8723a_set_rxdma_agg_pg_th(struct rtw_adapter *padapter, u8 val)
 763{
 764        rtl8723au_write8(padapter, REG_RXDMA_AGG_PG_TH, val);
 765}
 766
 767void rtl8723a_set_initial_gain(struct rtw_adapter *padapter, u32 rx_gain)
 768{
 769        struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
 770        struct dig_t *pDigTable = &pHalData->odmpriv.DM_DigTable;
 771
 772        if (rx_gain == 0xff)    /* restore rx gain */
 773                ODM_Write_DIG23a(&pHalData->odmpriv, pDigTable->BackupIGValue);
 774        else {
 775                pDigTable->BackupIGValue = pDigTable->CurIGValue;
 776                ODM_Write_DIG23a(&pHalData->odmpriv, rx_gain);
 777        }
 778}
 779
 780void rtl8723a_odm_support_ability_restore(struct rtw_adapter *padapter)
 781{
 782        struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
 783
 784        pHalData->odmpriv.SupportAbility = pHalData->odmpriv.BK_SupportAbility;
 785}
 786
 787void rtl8723a_odm_support_ability_backup(struct rtw_adapter *padapter)
 788{
 789        struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
 790
 791        pHalData->odmpriv.BK_SupportAbility = pHalData->odmpriv.SupportAbility;
 792}
 793
 794void rtl8723a_odm_support_ability_set(struct rtw_adapter *padapter, u32 val)
 795{
 796        struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
 797
 798        if (val == DYNAMIC_ALL_FUNC_ENABLE)
 799                pHalData->odmpriv.SupportAbility = pHalData->dmpriv.InitODMFlag;
 800        else
 801                pHalData->odmpriv.SupportAbility |= val;
 802}
 803
 804void rtl8723a_odm_support_ability_clr(struct rtw_adapter *padapter, u32 val)
 805{
 806        struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
 807
 808        pHalData->odmpriv.SupportAbility &= val;
 809}
 810
 811void rtl8723a_set_rpwm(struct rtw_adapter *padapter, u8 val)
 812{
 813        rtl8723au_write8(padapter, REG_USB_HRPWM, val);
 814}
 815
 816u8 rtl8723a_get_rf_type(struct rtw_adapter *padapter)
 817{
 818        struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
 819
 820        return pHalData->rf_type;
 821}
 822
 823bool rtl8723a_get_fwlps_rf_on(struct rtw_adapter *padapter)
 824{
 825        bool retval;
 826        u32 valRCR;
 827
 828        /*  When we halt NIC, we should check if FW LPS is leave. */
 829
 830        if ((padapter->bSurpriseRemoved == true) ||
 831            (padapter->pwrctrlpriv.rf_pwrstate == rf_off)) {
 832                /*  If it is in HW/SW Radio OFF or IPS state, we do
 833                    not check Fw LPS Leave, because Fw is unload. */
 834                retval = true;
 835        } else {
 836                valRCR = rtl8723au_read32(padapter, REG_RCR);
 837                if (valRCR & 0x00070000)
 838                        retval = false;
 839                else
 840                        retval = true;
 841        }
 842
 843        return retval;
 844}
 845
 846bool rtl8723a_chk_hi_queue_empty(struct rtw_adapter *padapter)
 847{
 848        u32 hgq;
 849
 850        hgq = rtl8723au_read32(padapter, REG_HGQ_INFORMATION);
 851
 852        return ((hgq & 0x0000ff00) == 0) ? true : false;
 853}
 854