linux/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
<<
>>
Prefs
   1/******************************************************************************
   2 *
   3 * Copyright(c) 2009-2012  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 * You should have received a copy of the GNU General Public License along with
  15 * this program; if not, write to the Free Software Foundation, Inc.,
  16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
  17 *
  18 * The full GNU General Public License is included in this distribution in the
  19 * file called LICENSE.
  20 *
  21 * Contact Information:
  22 * wlanfae <wlanfae@realtek.com>
  23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
  24 * Hsinchu 300, Taiwan.
  25 *
  26 * Larry Finger <Larry.Finger@lwfinger.net>
  27 *
  28 *****************************************************************************/
  29
  30#include "../wifi.h"
  31#include "../efuse.h"
  32#include "../base.h"
  33#include "../cam.h"
  34#include "../ps.h"
  35#include "../usb.h"
  36#include "reg.h"
  37#include "def.h"
  38#include "phy.h"
  39#include "mac.h"
  40#include "dm.h"
  41#include "hw.h"
  42#include "../rtl8192ce/hw.h"
  43#include "trx.h"
  44#include "led.h"
  45#include "table.h"
  46
  47static void _rtl92cu_phy_param_tab_init(struct ieee80211_hw *hw)
  48{
  49        struct rtl_priv *rtlpriv = rtl_priv(hw);
  50        struct rtl_phy *rtlphy = &(rtlpriv->phy);
  51        struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
  52
  53        rtlphy->hwparam_tables[MAC_REG].length = RTL8192CUMAC_2T_ARRAYLENGTH;
  54        rtlphy->hwparam_tables[MAC_REG].pdata = RTL8192CUMAC_2T_ARRAY;
  55        if (IS_HIGHT_PA(rtlefuse->board_type)) {
  56                rtlphy->hwparam_tables[PHY_REG_PG].length =
  57                        RTL8192CUPHY_REG_Array_PG_HPLength;
  58                rtlphy->hwparam_tables[PHY_REG_PG].pdata =
  59                        RTL8192CUPHY_REG_Array_PG_HP;
  60        } else {
  61                rtlphy->hwparam_tables[PHY_REG_PG].length =
  62                        RTL8192CUPHY_REG_ARRAY_PGLENGTH;
  63                rtlphy->hwparam_tables[PHY_REG_PG].pdata =
  64                        RTL8192CUPHY_REG_ARRAY_PG;
  65        }
  66        /* 2T */
  67        rtlphy->hwparam_tables[PHY_REG_2T].length =
  68                        RTL8192CUPHY_REG_2TARRAY_LENGTH;
  69        rtlphy->hwparam_tables[PHY_REG_2T].pdata =
  70                        RTL8192CUPHY_REG_2TARRAY;
  71        rtlphy->hwparam_tables[RADIOA_2T].length =
  72                        RTL8192CURADIOA_2TARRAYLENGTH;
  73        rtlphy->hwparam_tables[RADIOA_2T].pdata =
  74                        RTL8192CURADIOA_2TARRAY;
  75        rtlphy->hwparam_tables[RADIOB_2T].length =
  76                        RTL8192CURADIOB_2TARRAYLENGTH;
  77        rtlphy->hwparam_tables[RADIOB_2T].pdata =
  78                        RTL8192CU_RADIOB_2TARRAY;
  79        rtlphy->hwparam_tables[AGCTAB_2T].length =
  80                        RTL8192CUAGCTAB_2TARRAYLENGTH;
  81        rtlphy->hwparam_tables[AGCTAB_2T].pdata =
  82                        RTL8192CUAGCTAB_2TARRAY;
  83        /* 1T */
  84        if (IS_HIGHT_PA(rtlefuse->board_type)) {
  85                rtlphy->hwparam_tables[PHY_REG_1T].length =
  86                        RTL8192CUPHY_REG_1T_HPArrayLength;
  87                rtlphy->hwparam_tables[PHY_REG_1T].pdata =
  88                        RTL8192CUPHY_REG_1T_HPArray;
  89                rtlphy->hwparam_tables[RADIOA_1T].length =
  90                        RTL8192CURadioA_1T_HPArrayLength;
  91                rtlphy->hwparam_tables[RADIOA_1T].pdata =
  92                        RTL8192CURadioA_1T_HPArray;
  93                rtlphy->hwparam_tables[RADIOB_1T].length =
  94                        RTL8192CURADIOB_1TARRAYLENGTH;
  95                rtlphy->hwparam_tables[RADIOB_1T].pdata =
  96                        RTL8192CU_RADIOB_1TARRAY;
  97                rtlphy->hwparam_tables[AGCTAB_1T].length =
  98                        RTL8192CUAGCTAB_1T_HPArrayLength;
  99                rtlphy->hwparam_tables[AGCTAB_1T].pdata =
 100                        Rtl8192CUAGCTAB_1T_HPArray;
 101        } else {
 102                rtlphy->hwparam_tables[PHY_REG_1T].length =
 103                         RTL8192CUPHY_REG_1TARRAY_LENGTH;
 104                rtlphy->hwparam_tables[PHY_REG_1T].pdata =
 105                        RTL8192CUPHY_REG_1TARRAY;
 106                rtlphy->hwparam_tables[RADIOA_1T].length =
 107                        RTL8192CURADIOA_1TARRAYLENGTH;
 108                rtlphy->hwparam_tables[RADIOA_1T].pdata =
 109                        RTL8192CU_RADIOA_1TARRAY;
 110                rtlphy->hwparam_tables[RADIOB_1T].length =
 111                        RTL8192CURADIOB_1TARRAYLENGTH;
 112                rtlphy->hwparam_tables[RADIOB_1T].pdata =
 113                        RTL8192CU_RADIOB_1TARRAY;
 114                rtlphy->hwparam_tables[AGCTAB_1T].length =
 115                        RTL8192CUAGCTAB_1TARRAYLENGTH;
 116                rtlphy->hwparam_tables[AGCTAB_1T].pdata =
 117                        RTL8192CUAGCTAB_1TARRAY;
 118        }
 119}
 120
 121static void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw,
 122                                                 bool autoload_fail,
 123                                                 u8 *hwinfo)
 124{
 125        struct rtl_priv *rtlpriv = rtl_priv(hw);
 126        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 127        u8 rf_path, index, tempval;
 128        u16 i;
 129
 130        for (rf_path = 0; rf_path < 2; rf_path++) {
 131                for (i = 0; i < 3; i++) {
 132                        if (!autoload_fail) {
 133                                rtlefuse->
 134                                    eeprom_chnlarea_txpwr_cck[rf_path][i] =
 135                                    hwinfo[EEPROM_TXPOWERCCK + rf_path * 3 + i];
 136                                rtlefuse->
 137                                    eeprom_chnlarea_txpwr_ht40_1s[rf_path][i] =
 138                                    hwinfo[EEPROM_TXPOWERHT40_1S + rf_path * 3 +
 139                                           i];
 140                        } else {
 141                                rtlefuse->
 142                                    eeprom_chnlarea_txpwr_cck[rf_path][i] =
 143                                    EEPROM_DEFAULT_TXPOWERLEVEL;
 144                                rtlefuse->
 145                                    eeprom_chnlarea_txpwr_ht40_1s[rf_path][i] =
 146                                    EEPROM_DEFAULT_TXPOWERLEVEL;
 147                        }
 148                }
 149        }
 150        for (i = 0; i < 3; i++) {
 151                if (!autoload_fail)
 152                        tempval = hwinfo[EEPROM_TXPOWERHT40_2SDIFF + i];
 153                else
 154                        tempval = EEPROM_DEFAULT_HT40_2SDIFF;
 155                rtlefuse->eprom_chnl_txpwr_ht40_2sdf[RF90_PATH_A][i] =
 156                    (tempval & 0xf);
 157                rtlefuse->eprom_chnl_txpwr_ht40_2sdf[RF90_PATH_B][i] =
 158                    ((tempval & 0xf0) >> 4);
 159        }
 160        for (rf_path = 0; rf_path < 2; rf_path++)
 161                for (i = 0; i < 3; i++)
 162                        RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
 163                                "RF(%d) EEPROM CCK Area(%d) = 0x%x\n",
 164                                rf_path, i,
 165                                rtlefuse->
 166                                eeprom_chnlarea_txpwr_cck[rf_path][i]);
 167        for (rf_path = 0; rf_path < 2; rf_path++)
 168                for (i = 0; i < 3; i++)
 169                        RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
 170                                "RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n",
 171                                rf_path, i,
 172                                rtlefuse->
 173                                eeprom_chnlarea_txpwr_ht40_1s[rf_path][i]);
 174        for (rf_path = 0; rf_path < 2; rf_path++)
 175                for (i = 0; i < 3; i++)
 176                        RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
 177                                "RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n",
 178                                rf_path, i,
 179                                rtlefuse->
 180                                eprom_chnl_txpwr_ht40_2sdf[rf_path][i]);
 181        for (rf_path = 0; rf_path < 2; rf_path++) {
 182                for (i = 0; i < 14; i++) {
 183                        index = _rtl92c_get_chnl_group((u8) i);
 184                        rtlefuse->txpwrlevel_cck[rf_path][i] =
 185                            rtlefuse->eeprom_chnlarea_txpwr_cck[rf_path][index];
 186                        rtlefuse->txpwrlevel_ht40_1s[rf_path][i] =
 187                            rtlefuse->
 188                            eeprom_chnlarea_txpwr_ht40_1s[rf_path][index];
 189                        if ((rtlefuse->
 190                             eeprom_chnlarea_txpwr_ht40_1s[rf_path][index] -
 191                             rtlefuse->
 192                             eprom_chnl_txpwr_ht40_2sdf[rf_path][index])
 193                            > 0) {
 194                                rtlefuse->txpwrlevel_ht40_2s[rf_path][i] =
 195                                    rtlefuse->
 196                                    eeprom_chnlarea_txpwr_ht40_1s[rf_path]
 197                                    [index] - rtlefuse->
 198                                    eprom_chnl_txpwr_ht40_2sdf[rf_path]
 199                                    [index];
 200                        } else {
 201                                rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = 0;
 202                        }
 203                }
 204                for (i = 0; i < 14; i++) {
 205                        RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
 206                                "RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = [0x%x / 0x%x / 0x%x]\n", rf_path, i,
 207                                rtlefuse->txpwrlevel_cck[rf_path][i],
 208                                rtlefuse->txpwrlevel_ht40_1s[rf_path][i],
 209                                rtlefuse->txpwrlevel_ht40_2s[rf_path][i]);
 210                }
 211        }
 212        for (i = 0; i < 3; i++) {
 213                if (!autoload_fail) {
 214                        rtlefuse->eeprom_pwrlimit_ht40[i] =
 215                            hwinfo[EEPROM_TXPWR_GROUP + i];
 216                        rtlefuse->eeprom_pwrlimit_ht20[i] =
 217                            hwinfo[EEPROM_TXPWR_GROUP + 3 + i];
 218                } else {
 219                        rtlefuse->eeprom_pwrlimit_ht40[i] = 0;
 220                        rtlefuse->eeprom_pwrlimit_ht20[i] = 0;
 221                }
 222        }
 223        for (rf_path = 0; rf_path < 2; rf_path++) {
 224                for (i = 0; i < 14; i++) {
 225                        index = _rtl92c_get_chnl_group((u8) i);
 226                        if (rf_path == RF90_PATH_A) {
 227                                rtlefuse->pwrgroup_ht20[rf_path][i] =
 228                                    (rtlefuse->eeprom_pwrlimit_ht20[index]
 229                                     & 0xf);
 230                                rtlefuse->pwrgroup_ht40[rf_path][i] =
 231                                    (rtlefuse->eeprom_pwrlimit_ht40[index]
 232                                     & 0xf);
 233                        } else if (rf_path == RF90_PATH_B) {
 234                                rtlefuse->pwrgroup_ht20[rf_path][i] =
 235                                    ((rtlefuse->eeprom_pwrlimit_ht20[index]
 236                                      & 0xf0) >> 4);
 237                                rtlefuse->pwrgroup_ht40[rf_path][i] =
 238                                    ((rtlefuse->eeprom_pwrlimit_ht40[index]
 239                                      & 0xf0) >> 4);
 240                        }
 241                        RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
 242                                "RF-%d pwrgroup_ht20[%d] = 0x%x\n",
 243                                rf_path, i,
 244                                rtlefuse->pwrgroup_ht20[rf_path][i]);
 245                        RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
 246                                "RF-%d pwrgroup_ht40[%d] = 0x%x\n",
 247                                rf_path, i,
 248                                rtlefuse->pwrgroup_ht40[rf_path][i]);
 249                }
 250        }
 251        for (i = 0; i < 14; i++) {
 252                index = _rtl92c_get_chnl_group((u8) i);
 253                if (!autoload_fail)
 254                        tempval = hwinfo[EEPROM_TXPOWERHT20DIFF + index];
 255                else
 256                        tempval = EEPROM_DEFAULT_HT20_DIFF;
 257                rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] = (tempval & 0xF);
 258                rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] =
 259                    ((tempval >> 4) & 0xF);
 260                if (rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] & BIT(3))
 261                        rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] |= 0xF0;
 262                if (rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] & BIT(3))
 263                        rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] |= 0xF0;
 264                index = _rtl92c_get_chnl_group((u8) i);
 265                if (!autoload_fail)
 266                        tempval = hwinfo[EEPROM_TXPOWER_OFDMDIFF + index];
 267                else
 268                        tempval = EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF;
 269                rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i] = (tempval & 0xF);
 270                rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i] =
 271                    ((tempval >> 4) & 0xF);
 272        }
 273        rtlefuse->legacy_ht_txpowerdiff =
 274            rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][7];
 275        for (i = 0; i < 14; i++)
 276                RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
 277                        "RF-A Ht20 to HT40 Diff[%d] = 0x%x\n",
 278                        i, rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]);
 279        for (i = 0; i < 14; i++)
 280                RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
 281                        "RF-A Legacy to Ht40 Diff[%d] = 0x%x\n",
 282                        i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]);
 283        for (i = 0; i < 14; i++)
 284                RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
 285                        "RF-B Ht20 to HT40 Diff[%d] = 0x%x\n",
 286                        i, rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]);
 287        for (i = 0; i < 14; i++)
 288                RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
 289                        "RF-B Legacy to HT40 Diff[%d] = 0x%x\n",
 290                        i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]);
 291        if (!autoload_fail)
 292                rtlefuse->eeprom_regulatory = (hwinfo[RF_OPTION1] & 0x7);
 293        else
 294                rtlefuse->eeprom_regulatory = 0;
 295        RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
 296                "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory);
 297        if (!autoload_fail) {
 298                rtlefuse->eeprom_tssi[RF90_PATH_A] = hwinfo[EEPROM_TSSI_A];
 299                rtlefuse->eeprom_tssi[RF90_PATH_B] = hwinfo[EEPROM_TSSI_B];
 300        } else {
 301                rtlefuse->eeprom_tssi[RF90_PATH_A] = EEPROM_DEFAULT_TSSI;
 302                rtlefuse->eeprom_tssi[RF90_PATH_B] = EEPROM_DEFAULT_TSSI;
 303        }
 304        RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
 305                "TSSI_A = 0x%x, TSSI_B = 0x%x\n",
 306                rtlefuse->eeprom_tssi[RF90_PATH_A],
 307                rtlefuse->eeprom_tssi[RF90_PATH_B]);
 308        if (!autoload_fail)
 309                tempval = hwinfo[EEPROM_THERMAL_METER];
 310        else
 311                tempval = EEPROM_DEFAULT_THERMALMETER;
 312        rtlefuse->eeprom_thermalmeter = (tempval & 0x1f);
 313        if (rtlefuse->eeprom_thermalmeter < 0x06 ||
 314            rtlefuse->eeprom_thermalmeter > 0x1c)
 315                rtlefuse->eeprom_thermalmeter = 0x12;
 316        if (rtlefuse->eeprom_thermalmeter == 0x1f || autoload_fail)
 317                rtlefuse->apk_thermalmeterignore = true;
 318        rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter;
 319        RTPRINT(rtlpriv, FINIT, INIT_TXPOWER,
 320                "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter);
 321}
 322
 323static void _rtl92cu_read_board_type(struct ieee80211_hw *hw, u8 *contents)
 324{
 325        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 326        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 327        u8 boardType;
 328
 329        if (IS_NORMAL_CHIP(rtlhal->version)) {
 330                boardType = ((contents[EEPROM_RF_OPT1]) &
 331                            BOARD_TYPE_NORMAL_MASK) >> 5; /*bit[7:5]*/
 332        } else {
 333                boardType = contents[EEPROM_RF_OPT4];
 334                boardType &= BOARD_TYPE_TEST_MASK;
 335        }
 336        rtlefuse->board_type = boardType;
 337        if (IS_HIGHT_PA(rtlefuse->board_type))
 338                rtlefuse->external_pa = 1;
 339        pr_info("Board Type %x\n", rtlefuse->board_type);
 340}
 341
 342static void _rtl92cu_read_adapter_info(struct ieee80211_hw *hw)
 343{
 344        struct rtl_priv *rtlpriv = rtl_priv(hw);
 345        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 346        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 347        u16 i, usvalue;
 348        u8 hwinfo[HWSET_MAX_SIZE] = {0};
 349        u16 eeprom_id;
 350
 351        if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) {
 352                rtl_efuse_shadow_map_update(hw);
 353                memcpy((void *)hwinfo,
 354                       (void *)&rtlefuse->efuse_map[EFUSE_INIT_MAP][0],
 355                       HWSET_MAX_SIZE);
 356        } else if (rtlefuse->epromtype == EEPROM_93C46) {
 357                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
 358                         "RTL819X Not boot from eeprom, check it !!\n");
 359        }
 360        RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_LOUD, "MAP",
 361                      hwinfo, HWSET_MAX_SIZE);
 362        eeprom_id = le16_to_cpu(*((__le16 *)&hwinfo[0]));
 363        if (eeprom_id != RTL8190_EEPROM_ID) {
 364                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
 365                         "EEPROM ID(%#x) is invalid!!\n", eeprom_id);
 366                rtlefuse->autoload_failflag = true;
 367        } else {
 368                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n");
 369                rtlefuse->autoload_failflag = false;
 370        }
 371        if (rtlefuse->autoload_failflag)
 372                return;
 373        for (i = 0; i < 6; i += 2) {
 374                usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR + i];
 375                *((u16 *) (&rtlefuse->dev_addr[i])) = usvalue;
 376        }
 377        pr_info("MAC address: %pM\n", rtlefuse->dev_addr);
 378        _rtl92cu_read_txpower_info_from_hwpg(hw,
 379                                           rtlefuse->autoload_failflag, hwinfo);
 380        rtlefuse->eeprom_vid = le16_to_cpu(*(__le16 *)&hwinfo[EEPROM_VID]);
 381        rtlefuse->eeprom_did = le16_to_cpu(*(__le16 *)&hwinfo[EEPROM_DID]);
 382        RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, " VID = 0x%02x PID = 0x%02x\n",
 383                 rtlefuse->eeprom_vid, rtlefuse->eeprom_did);
 384        rtlefuse->eeprom_channelplan = hwinfo[EEPROM_CHANNELPLAN];
 385        rtlefuse->eeprom_version =
 386                         le16_to_cpu(*(__le16 *)&hwinfo[EEPROM_VERSION]);
 387        rtlefuse->txpwr_fromeprom = true;
 388        rtlefuse->eeprom_oemid = hwinfo[EEPROM_CUSTOMER_ID];
 389        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROM Customer ID: 0x%2x\n",
 390                 rtlefuse->eeprom_oemid);
 391        if (rtlhal->oem_id == RT_CID_DEFAULT) {
 392                switch (rtlefuse->eeprom_oemid) {
 393                case EEPROM_CID_DEFAULT:
 394                        if (rtlefuse->eeprom_did == 0x8176) {
 395                                if ((rtlefuse->eeprom_svid == 0x103C &&
 396                                     rtlefuse->eeprom_smid == 0x1629))
 397                                        rtlhal->oem_id = RT_CID_819x_HP;
 398                                else
 399                                        rtlhal->oem_id = RT_CID_DEFAULT;
 400                        } else {
 401                                rtlhal->oem_id = RT_CID_DEFAULT;
 402                        }
 403                        break;
 404                case EEPROM_CID_TOSHIBA:
 405                        rtlhal->oem_id = RT_CID_TOSHIBA;
 406                        break;
 407                case EEPROM_CID_QMI:
 408                        rtlhal->oem_id = RT_CID_819x_QMI;
 409                        break;
 410                case EEPROM_CID_WHQL:
 411                default:
 412                        rtlhal->oem_id = RT_CID_DEFAULT;
 413                        break;
 414                }
 415        }
 416        _rtl92cu_read_board_type(hw, hwinfo);
 417}
 418
 419static void _rtl92cu_hal_customized_behavior(struct ieee80211_hw *hw)
 420{
 421        struct rtl_priv *rtlpriv = rtl_priv(hw);
 422        struct rtl_usb_priv *usb_priv = rtl_usbpriv(hw);
 423        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 424
 425        switch (rtlhal->oem_id) {
 426        case RT_CID_819x_HP:
 427                usb_priv->ledctl.led_opendrain = true;
 428                break;
 429        case RT_CID_819x_Lenovo:
 430        case RT_CID_DEFAULT:
 431        case RT_CID_TOSHIBA:
 432        case RT_CID_CCX:
 433        case RT_CID_819x_Acer:
 434        case RT_CID_WHQL:
 435        default:
 436                break;
 437        }
 438        RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "RT Customized ID: 0x%02X\n",
 439                 rtlhal->oem_id);
 440}
 441
 442void rtl92cu_read_eeprom_info(struct ieee80211_hw *hw)
 443{
 444
 445        struct rtl_priv *rtlpriv = rtl_priv(hw);
 446        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 447        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 448        u8 tmp_u1b;
 449
 450        if (!IS_NORMAL_CHIP(rtlhal->version))
 451                return;
 452        tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR);
 453        rtlefuse->epromtype = (tmp_u1b & BOOT_FROM_EEPROM) ?
 454                               EEPROM_93C46 : EEPROM_BOOT_EFUSE;
 455        RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from %s\n",
 456                 tmp_u1b & BOOT_FROM_EEPROM ? "EERROM" : "EFUSE");
 457        rtlefuse->autoload_failflag = (tmp_u1b & EEPROM_EN) ? false : true;
 458        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload %s\n",
 459                 tmp_u1b & EEPROM_EN ? "OK!!" : "ERR!!");
 460        _rtl92cu_read_adapter_info(hw);
 461        _rtl92cu_hal_customized_behavior(hw);
 462        return;
 463}
 464
 465static int _rtl92cu_init_power_on(struct ieee80211_hw *hw)
 466{
 467        struct rtl_priv *rtlpriv = rtl_priv(hw);
 468        int             status = 0;
 469        u16             value16;
 470        u8              value8;
 471        /*  polling autoload done. */
 472        u32     pollingCount = 0;
 473
 474        do {
 475                if (rtl_read_byte(rtlpriv, REG_APS_FSMCO) & PFM_ALDN) {
 476                        RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
 477                                 "Autoload Done!\n");
 478                        break;
 479                }
 480                if (pollingCount++ > 100) {
 481                        RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
 482                                 "Failed to polling REG_APS_FSMCO[PFM_ALDN] done!\n");
 483                        return -ENODEV;
 484                }
 485        } while (true);
 486        /* 0. RSV_CTRL 0x1C[7:0] = 0 unlock ISO/CLK/Power control register */
 487        rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0);
 488        /* Power on when re-enter from IPS/Radio off/card disable */
 489        /* enable SPS into PWM mode */
 490        rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
 491        udelay(100);
 492        value8 = rtl_read_byte(rtlpriv, REG_LDOV12D_CTRL);
 493        if (0 == (value8 & LDV12_EN)) {
 494                value8 |= LDV12_EN;
 495                rtl_write_byte(rtlpriv, REG_LDOV12D_CTRL, value8);
 496                RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
 497                         " power-on :REG_LDOV12D_CTRL Reg0x21:0x%02x\n",
 498                         value8);
 499                udelay(100);
 500                value8 = rtl_read_byte(rtlpriv, REG_SYS_ISO_CTRL);
 501                value8 &= ~ISO_MD2PP;
 502                rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL, value8);
 503        }
 504        /*  auto enable WLAN */
 505        pollingCount = 0;
 506        value16 = rtl_read_word(rtlpriv, REG_APS_FSMCO);
 507        value16 |= APFM_ONMAC;
 508        rtl_write_word(rtlpriv, REG_APS_FSMCO, value16);
 509        do {
 510                if (!(rtl_read_word(rtlpriv, REG_APS_FSMCO) & APFM_ONMAC)) {
 511                        pr_info("MAC auto ON okay!\n");
 512                        break;
 513                }
 514                if (pollingCount++ > 100) {
 515                        RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
 516                                 "Failed to polling REG_APS_FSMCO[APFM_ONMAC] done!\n");
 517                        return -ENODEV;
 518                }
 519        } while (true);
 520        /* Enable Radio ,GPIO ,and LED function */
 521        rtl_write_word(rtlpriv, REG_APS_FSMCO, 0x0812);
 522        /* release RF digital isolation */
 523        value16 = rtl_read_word(rtlpriv, REG_SYS_ISO_CTRL);
 524        value16 &= ~ISO_DIOR;
 525        rtl_write_word(rtlpriv, REG_SYS_ISO_CTRL, value16);
 526        /* Reconsider when to do this operation after asking HWSD. */
 527        pollingCount = 0;
 528        rtl_write_byte(rtlpriv, REG_APSD_CTRL, (rtl_read_byte(rtlpriv,
 529                                                REG_APSD_CTRL) & ~BIT(6)));
 530        do {
 531                pollingCount++;
 532        } while ((pollingCount < 200) &&
 533                 (rtl_read_byte(rtlpriv, REG_APSD_CTRL) & BIT(7)));
 534        /* Enable MAC DMA/WMAC/SCHEDULE/SEC block */
 535        value16 = rtl_read_word(rtlpriv,  REG_CR);
 536        value16 |= (HCI_TXDMA_EN | HCI_RXDMA_EN | TXDMA_EN | RXDMA_EN |
 537                    PROTOCOL_EN | SCHEDULE_EN | MACTXEN | MACRXEN | ENSEC);
 538        rtl_write_word(rtlpriv, REG_CR, value16);
 539        return status;
 540}
 541
 542static void _rtl92cu_init_queue_reserved_page(struct ieee80211_hw *hw,
 543                                              bool wmm_enable,
 544                                              u8 out_ep_num,
 545                                              u8 queue_sel)
 546{
 547        struct rtl_priv *rtlpriv = rtl_priv(hw);
 548        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 549        bool isChipN = IS_NORMAL_CHIP(rtlhal->version);
 550        u32 outEPNum = (u32)out_ep_num;
 551        u32 numHQ = 0;
 552        u32 numLQ = 0;
 553        u32 numNQ = 0;
 554        u32 numPubQ;
 555        u32 value32;
 556        u8 value8;
 557        u32 txQPageNum, txQPageUnit, txQRemainPage;
 558
 559        if (!wmm_enable) {
 560                numPubQ = (isChipN) ? CHIP_B_PAGE_NUM_PUBQ :
 561                          CHIP_A_PAGE_NUM_PUBQ;
 562                txQPageNum = TX_TOTAL_PAGE_NUMBER - numPubQ;
 563
 564                txQPageUnit = txQPageNum/outEPNum;
 565                txQRemainPage = txQPageNum % outEPNum;
 566                if (queue_sel & TX_SELE_HQ)
 567                        numHQ = txQPageUnit;
 568                if (queue_sel & TX_SELE_LQ)
 569                        numLQ = txQPageUnit;
 570                /* HIGH priority queue always present in the configuration of
 571                 * 2 out-ep. Remainder pages have assigned to High queue */
 572                if ((outEPNum > 1) && (txQRemainPage))
 573                        numHQ += txQRemainPage;
 574                /* NOTE: This step done before writting REG_RQPN. */
 575                if (isChipN) {
 576                        if (queue_sel & TX_SELE_NQ)
 577                                numNQ = txQPageUnit;
 578                        value8 = (u8)_NPQ(numNQ);
 579                        rtl_write_byte(rtlpriv,  REG_RQPN_NPQ, value8);
 580                }
 581        } else {
 582                /* for WMM ,number of out-ep must more than or equal to 2! */
 583                numPubQ = isChipN ? WMM_CHIP_B_PAGE_NUM_PUBQ :
 584                          WMM_CHIP_A_PAGE_NUM_PUBQ;
 585                if (queue_sel & TX_SELE_HQ) {
 586                        numHQ = isChipN ? WMM_CHIP_B_PAGE_NUM_HPQ :
 587                                WMM_CHIP_A_PAGE_NUM_HPQ;
 588                }
 589                if (queue_sel & TX_SELE_LQ) {
 590                        numLQ = isChipN ? WMM_CHIP_B_PAGE_NUM_LPQ :
 591                                WMM_CHIP_A_PAGE_NUM_LPQ;
 592                }
 593                /* NOTE: This step done before writting REG_RQPN. */
 594                if (isChipN) {
 595                        if (queue_sel & TX_SELE_NQ)
 596                                numNQ = WMM_CHIP_B_PAGE_NUM_NPQ;
 597                        value8 = (u8)_NPQ(numNQ);
 598                        rtl_write_byte(rtlpriv, REG_RQPN_NPQ, value8);
 599                }
 600        }
 601        /* TX DMA */
 602        value32 = _HPQ(numHQ) | _LPQ(numLQ) | _PUBQ(numPubQ) | LD_RQPN;
 603        rtl_write_dword(rtlpriv, REG_RQPN, value32);
 604}
 605
 606static void _rtl92c_init_trx_buffer(struct ieee80211_hw *hw, bool wmm_enable)
 607{
 608        struct rtl_priv *rtlpriv = rtl_priv(hw);
 609        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 610        u8      txpktbuf_bndy;
 611        u8      value8;
 612
 613        if (!wmm_enable)
 614                txpktbuf_bndy = TX_PAGE_BOUNDARY;
 615        else /* for WMM */
 616                txpktbuf_bndy = (IS_NORMAL_CHIP(rtlhal->version))
 617                                                ? WMM_CHIP_B_TX_PAGE_BOUNDARY
 618                                                : WMM_CHIP_A_TX_PAGE_BOUNDARY;
 619        rtl_write_byte(rtlpriv, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy);
 620        rtl_write_byte(rtlpriv, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy);
 621        rtl_write_byte(rtlpriv, REG_TXPKTBUF_WMAC_LBK_BF_HD, txpktbuf_bndy);
 622        rtl_write_byte(rtlpriv, REG_TRXFF_BNDY, txpktbuf_bndy);
 623        rtl_write_byte(rtlpriv, REG_TDECTRL+1, txpktbuf_bndy);
 624        rtl_write_word(rtlpriv,  (REG_TRXFF_BNDY + 2), 0x27FF);
 625        value8 = _PSRX(RX_PAGE_SIZE_REG_VALUE) | _PSTX(PBP_128);
 626        rtl_write_byte(rtlpriv, REG_PBP, value8);
 627}
 628
 629static void _rtl92c_init_chipN_reg_priority(struct ieee80211_hw *hw, u16 beQ,
 630                                            u16 bkQ, u16 viQ, u16 voQ,
 631                                            u16 mgtQ, u16 hiQ)
 632{
 633        struct rtl_priv *rtlpriv = rtl_priv(hw);
 634        u16 value16 = (rtl_read_word(rtlpriv, REG_TRXDMA_CTRL) & 0x7);
 635
 636        value16 |= _TXDMA_BEQ_MAP(beQ) | _TXDMA_BKQ_MAP(bkQ) |
 637                   _TXDMA_VIQ_MAP(viQ) | _TXDMA_VOQ_MAP(voQ) |
 638                   _TXDMA_MGQ_MAP(mgtQ) | _TXDMA_HIQ_MAP(hiQ);
 639        rtl_write_word(rtlpriv,  REG_TRXDMA_CTRL, value16);
 640}
 641
 642static void _rtl92cu_init_chipN_one_out_ep_priority(struct ieee80211_hw *hw,
 643                                                    bool wmm_enable,
 644                                                    u8 queue_sel)
 645{
 646        u16 uninitialized_var(value);
 647
 648        switch (queue_sel) {
 649        case TX_SELE_HQ:
 650                value = QUEUE_HIGH;
 651                break;
 652        case TX_SELE_LQ:
 653                value = QUEUE_LOW;
 654                break;
 655        case TX_SELE_NQ:
 656                value = QUEUE_NORMAL;
 657                break;
 658        default:
 659                WARN_ON(1); /* Shall not reach here! */
 660                break;
 661        }
 662        _rtl92c_init_chipN_reg_priority(hw, value, value, value, value,
 663                                        value, value);
 664        pr_info("Tx queue select: 0x%02x\n", queue_sel);
 665}
 666
 667static void _rtl92cu_init_chipN_two_out_ep_priority(struct ieee80211_hw *hw,
 668                                                                bool wmm_enable,
 669                                                                u8 queue_sel)
 670{
 671        u16 beQ, bkQ, viQ, voQ, mgtQ, hiQ;
 672        u16 uninitialized_var(valueHi);
 673        u16 uninitialized_var(valueLow);
 674
 675        switch (queue_sel) {
 676        case (TX_SELE_HQ | TX_SELE_LQ):
 677                valueHi = QUEUE_HIGH;
 678                valueLow = QUEUE_LOW;
 679                break;
 680        case (TX_SELE_NQ | TX_SELE_LQ):
 681                valueHi = QUEUE_NORMAL;
 682                valueLow = QUEUE_LOW;
 683                break;
 684        case (TX_SELE_HQ | TX_SELE_NQ):
 685                valueHi = QUEUE_HIGH;
 686                valueLow = QUEUE_NORMAL;
 687                break;
 688        default:
 689                WARN_ON(1);
 690                break;
 691        }
 692        if (!wmm_enable) {
 693                beQ = valueLow;
 694                bkQ = valueLow;
 695                viQ = valueHi;
 696                voQ = valueHi;
 697                mgtQ = valueHi;
 698                hiQ = valueHi;
 699        } else {/* for WMM ,CONFIG_OUT_EP_WIFI_MODE */
 700                beQ = valueHi;
 701                bkQ = valueLow;
 702                viQ = valueLow;
 703                voQ = valueHi;
 704                mgtQ = valueHi;
 705                hiQ = valueHi;
 706        }
 707        _rtl92c_init_chipN_reg_priority(hw, beQ, bkQ, viQ, voQ, mgtQ, hiQ);
 708        pr_info("Tx queue select: 0x%02x\n", queue_sel);
 709}
 710
 711static void _rtl92cu_init_chipN_three_out_ep_priority(struct ieee80211_hw *hw,
 712                                                      bool wmm_enable,
 713                                                      u8 queue_sel)
 714{
 715        u16 beQ, bkQ, viQ, voQ, mgtQ, hiQ;
 716        struct rtl_priv *rtlpriv = rtl_priv(hw);
 717
 718        if (!wmm_enable) { /* typical setting */
 719                beQ     = QUEUE_LOW;
 720                bkQ     = QUEUE_LOW;
 721                viQ     = QUEUE_NORMAL;
 722                voQ     = QUEUE_HIGH;
 723                mgtQ    = QUEUE_HIGH;
 724                hiQ     = QUEUE_HIGH;
 725        } else { /* for WMM */
 726                beQ     = QUEUE_LOW;
 727                bkQ     = QUEUE_NORMAL;
 728                viQ     = QUEUE_NORMAL;
 729                voQ     = QUEUE_HIGH;
 730                mgtQ    = QUEUE_HIGH;
 731                hiQ     = QUEUE_HIGH;
 732        }
 733        _rtl92c_init_chipN_reg_priority(hw, beQ, bkQ, viQ, voQ, mgtQ, hiQ);
 734        RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, "Tx queue select :0x%02x..\n",
 735                 queue_sel);
 736}
 737
 738static void _rtl92cu_init_chipN_queue_priority(struct ieee80211_hw *hw,
 739                                               bool wmm_enable,
 740                                               u8 out_ep_num,
 741                                               u8 queue_sel)
 742{
 743        switch (out_ep_num) {
 744        case 1:
 745                _rtl92cu_init_chipN_one_out_ep_priority(hw, wmm_enable,
 746                                                        queue_sel);
 747                break;
 748        case 2:
 749                _rtl92cu_init_chipN_two_out_ep_priority(hw, wmm_enable,
 750                                                        queue_sel);
 751                break;
 752        case 3:
 753                _rtl92cu_init_chipN_three_out_ep_priority(hw, wmm_enable,
 754                                                          queue_sel);
 755                break;
 756        default:
 757                WARN_ON(1); /* Shall not reach here! */
 758                break;
 759        }
 760}
 761
 762static void _rtl92cu_init_chipT_queue_priority(struct ieee80211_hw *hw,
 763                                               bool wmm_enable,
 764                                               u8 out_ep_num,
 765                                               u8 queue_sel)
 766{
 767        u8 hq_sele = 0;
 768        struct rtl_priv *rtlpriv = rtl_priv(hw);
 769
 770        switch (out_ep_num) {
 771        case 2: /* (TX_SELE_HQ|TX_SELE_LQ) */
 772                if (!wmm_enable) /* typical setting */
 773                        hq_sele =  HQSEL_VOQ | HQSEL_VIQ | HQSEL_MGTQ |
 774                                   HQSEL_HIQ;
 775                else    /* for WMM */
 776                        hq_sele = HQSEL_VOQ | HQSEL_BEQ | HQSEL_MGTQ |
 777                                  HQSEL_HIQ;
 778                break;
 779        case 1:
 780                if (TX_SELE_LQ == queue_sel) {
 781                        /* map all endpoint to Low queue */
 782                        hq_sele = 0;
 783                } else if (TX_SELE_HQ == queue_sel) {
 784                        /* map all endpoint to High queue */
 785                        hq_sele =  HQSEL_VOQ | HQSEL_VIQ | HQSEL_BEQ |
 786                                   HQSEL_BKQ | HQSEL_MGTQ | HQSEL_HIQ;
 787                }
 788                break;
 789        default:
 790                WARN_ON(1); /* Shall not reach here! */
 791                break;
 792        }
 793        rtl_write_byte(rtlpriv, (REG_TRXDMA_CTRL+1), hq_sele);
 794        RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG, "Tx queue select :0x%02x..\n",
 795                 hq_sele);
 796}
 797
 798static void _rtl92cu_init_queue_priority(struct ieee80211_hw *hw,
 799                                                bool wmm_enable,
 800                                                u8 out_ep_num,
 801                                                u8 queue_sel)
 802{
 803        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 804        if (IS_NORMAL_CHIP(rtlhal->version))
 805                _rtl92cu_init_chipN_queue_priority(hw, wmm_enable, out_ep_num,
 806                                                   queue_sel);
 807        else
 808                _rtl92cu_init_chipT_queue_priority(hw, wmm_enable, out_ep_num,
 809                                                   queue_sel);
 810}
 811
 812static void _rtl92cu_init_usb_aggregation(struct ieee80211_hw *hw)
 813{
 814}
 815
 816static void _rtl92cu_init_wmac_setting(struct ieee80211_hw *hw)
 817{
 818        u16                     value16;
 819
 820        struct rtl_priv *rtlpriv = rtl_priv(hw);
 821        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 822
 823        mac->rx_conf = (RCR_APM | RCR_AM | RCR_ADF | RCR_AB | RCR_APPFCS |
 824                      RCR_APP_ICV | RCR_AMF | RCR_HTC_LOC_CTRL |
 825                      RCR_APP_MIC | RCR_APP_PHYSTS | RCR_ACRC32);
 826        rtl_write_dword(rtlpriv, REG_RCR, mac->rx_conf);
 827        /* Accept all multicast address */
 828        rtl_write_dword(rtlpriv,  REG_MAR, 0xFFFFFFFF);
 829        rtl_write_dword(rtlpriv,  REG_MAR + 4, 0xFFFFFFFF);
 830        /* Accept all management frames */
 831        value16 = 0xFFFF;
 832        rtl92c_set_mgt_filter(hw, value16);
 833        /* Reject all control frame - default value is 0 */
 834        rtl92c_set_ctrl_filter(hw, 0x0);
 835        /* Accept all data frames */
 836        value16 = 0xFFFF;
 837        rtl92c_set_data_filter(hw, value16);
 838}
 839
 840static int _rtl92cu_init_mac(struct ieee80211_hw *hw)
 841{
 842        struct rtl_priv *rtlpriv = rtl_priv(hw);
 843        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 844        struct rtl_usb_priv *usb_priv = rtl_usbpriv(hw);
 845        struct rtl_usb *rtlusb = rtl_usbdev(usb_priv);
 846        int err = 0;
 847        u32     boundary = 0;
 848        u8 wmm_enable = false; /* TODO */
 849        u8 out_ep_nums = rtlusb->out_ep_nums;
 850        u8 queue_sel = rtlusb->out_queue_sel;
 851        err = _rtl92cu_init_power_on(hw);
 852
 853        if (err) {
 854                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
 855                         "Failed to init power on!\n");
 856                return err;
 857        }
 858        if (!wmm_enable) {
 859                boundary = TX_PAGE_BOUNDARY;
 860        } else { /* for WMM */
 861                boundary = (IS_NORMAL_CHIP(rtlhal->version))
 862                                        ? WMM_CHIP_B_TX_PAGE_BOUNDARY
 863                                        : WMM_CHIP_A_TX_PAGE_BOUNDARY;
 864        }
 865        if (false == rtl92c_init_llt_table(hw, boundary)) {
 866                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
 867                         "Failed to init LLT Table!\n");
 868                return -EINVAL;
 869        }
 870        _rtl92cu_init_queue_reserved_page(hw, wmm_enable, out_ep_nums,
 871                                          queue_sel);
 872        _rtl92c_init_trx_buffer(hw, wmm_enable);
 873        _rtl92cu_init_queue_priority(hw, wmm_enable, out_ep_nums,
 874                                     queue_sel);
 875        /* Get Rx PHY status in order to report RSSI and others. */
 876        rtl92c_init_driver_info_size(hw, RTL92C_DRIVER_INFO_SIZE);
 877        rtl92c_init_interrupt(hw);
 878        rtl92c_init_network_type(hw);
 879        _rtl92cu_init_wmac_setting(hw);
 880        rtl92c_init_adaptive_ctrl(hw);
 881        rtl92c_init_edca(hw);
 882        rtl92c_init_rate_fallback(hw);
 883        rtl92c_init_retry_function(hw);
 884        _rtl92cu_init_usb_aggregation(hw);
 885        rtlpriv->cfg->ops->set_bw_mode(hw, NL80211_CHAN_HT20);
 886        rtl92c_set_min_space(hw, IS_92C_SERIAL(rtlhal->version));
 887        rtl92c_init_beacon_parameters(hw, rtlhal->version);
 888        rtl92c_init_ampdu_aggregation(hw);
 889        rtl92c_init_beacon_max_error(hw, true);
 890        return err;
 891}
 892
 893void rtl92cu_enable_hw_security_config(struct ieee80211_hw *hw)
 894{
 895        struct rtl_priv *rtlpriv = rtl_priv(hw);
 896        u8 sec_reg_value = 0x0;
 897        struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
 898
 899        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 900                 "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n",
 901                 rtlpriv->sec.pairwise_enc_algorithm,
 902                 rtlpriv->sec.group_enc_algorithm);
 903        if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) {
 904                RT_TRACE(rtlpriv, COMP_SEC, DBG_DMESG,
 905                         "not open sw encryption\n");
 906                return;
 907        }
 908        sec_reg_value = SCR_TxEncEnable | SCR_RxDecEnable;
 909        if (rtlpriv->sec.use_defaultkey) {
 910                sec_reg_value |= SCR_TxUseDK;
 911                sec_reg_value |= SCR_RxUseDK;
 912        }
 913        if (IS_NORMAL_CHIP(rtlhal->version))
 914                sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK);
 915        rtl_write_byte(rtlpriv, REG_CR + 1, 0x02);
 916        RT_TRACE(rtlpriv, COMP_SEC, DBG_LOUD, "The SECR-value %x\n",
 917                 sec_reg_value);
 918        rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value);
 919}
 920
 921static void _rtl92cu_hw_configure(struct ieee80211_hw *hw)
 922{
 923        struct rtl_priv *rtlpriv = rtl_priv(hw);
 924        struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw));
 925
 926        /* To Fix MAC loopback mode fail. */
 927        rtl_write_byte(rtlpriv, REG_LDOHCI12_CTRL, 0x0f);
 928        rtl_write_byte(rtlpriv, 0x15, 0xe9);
 929        /* HW SEQ CTRL */
 930        /* set 0x0 to 0xFF by tynli. Default enable HW SEQ NUM. */
 931        rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, 0xFF);
 932        /* fixed USB interface interference issue */
 933        rtl_write_byte(rtlpriv, 0xfe40, 0xe0);
 934        rtl_write_byte(rtlpriv, 0xfe41, 0x8d);
 935        rtl_write_byte(rtlpriv, 0xfe42, 0x80);
 936        rtlusb->reg_bcn_ctrl_val = 0x18;
 937        rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8)rtlusb->reg_bcn_ctrl_val);
 938}
 939
 940static void _InitPABias(struct ieee80211_hw *hw)
 941{
 942        struct rtl_priv *rtlpriv = rtl_priv(hw);
 943        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 944        u8 pa_setting;
 945
 946        /* FIXED PA current issue */
 947        pa_setting = efuse_read_1byte(hw, 0x1FA);
 948        if (!(pa_setting & BIT(0))) {
 949                rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0FFFFF, 0x0F406);
 950                rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0FFFFF, 0x4F406);
 951                rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0FFFFF, 0x8F406);
 952                rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0FFFFF, 0xCF406);
 953        }
 954        if (!(pa_setting & BIT(1)) && IS_NORMAL_CHIP(rtlhal->version) &&
 955            IS_92C_SERIAL(rtlhal->version)) {
 956                rtl_set_rfreg(hw, RF90_PATH_B, 0x15, 0x0FFFFF, 0x0F406);
 957                rtl_set_rfreg(hw, RF90_PATH_B, 0x15, 0x0FFFFF, 0x4F406);
 958                rtl_set_rfreg(hw, RF90_PATH_B, 0x15, 0x0FFFFF, 0x8F406);
 959                rtl_set_rfreg(hw, RF90_PATH_B, 0x15, 0x0FFFFF, 0xCF406);
 960        }
 961        if (!(pa_setting & BIT(4))) {
 962                pa_setting = rtl_read_byte(rtlpriv, 0x16);
 963                pa_setting &= 0x0F;
 964                rtl_write_byte(rtlpriv, 0x16, pa_setting | 0x90);
 965        }
 966}
 967
 968static void _update_mac_setting(struct ieee80211_hw *hw)
 969{
 970        struct rtl_priv *rtlpriv = rtl_priv(hw);
 971        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 972
 973        mac->rx_conf = rtl_read_dword(rtlpriv, REG_RCR);
 974        mac->rx_mgt_filter = rtl_read_word(rtlpriv, REG_RXFLTMAP0);
 975        mac->rx_ctrl_filter = rtl_read_word(rtlpriv, REG_RXFLTMAP1);
 976        mac->rx_data_filter = rtl_read_word(rtlpriv, REG_RXFLTMAP2);
 977}
 978
 979int rtl92cu_hw_init(struct ieee80211_hw *hw)
 980{
 981        struct rtl_priv *rtlpriv = rtl_priv(hw);
 982        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 983        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 984        struct rtl_phy *rtlphy = &(rtlpriv->phy);
 985        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
 986        int err = 0;
 987        static bool iqk_initialized;
 988
 989        rtlhal->hw_type = HARDWARE_TYPE_RTL8192CU;
 990        err = _rtl92cu_init_mac(hw);
 991        if (err) {
 992                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "init mac failed!\n");
 993                return err;
 994        }
 995        err = rtl92c_download_fw(hw);
 996        if (err) {
 997                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
 998                         "Failed to download FW. Init HW without FW now..\n");
 999                err = 1;
1000                return err;
1001        }
1002        rtlhal->last_hmeboxnum = 0; /* h2c */
1003        _rtl92cu_phy_param_tab_init(hw);
1004        rtl92cu_phy_mac_config(hw);
1005        rtl92cu_phy_bb_config(hw);
1006        rtlphy->rf_mode = RF_OP_BY_SW_3WIRE;
1007        rtl92c_phy_rf_config(hw);
1008        if (IS_VENDOR_UMC_A_CUT(rtlhal->version) &&
1009            !IS_92C_SERIAL(rtlhal->version)) {
1010                rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD, 0x30255);
1011                rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G2, MASKDWORD, 0x50a00);
1012        }
1013        rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0,
1014                                                 RF_CHNLBW, RFREG_OFFSET_MASK);
1015        rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1,
1016                                                 RF_CHNLBW, RFREG_OFFSET_MASK);
1017        rtl92cu_bb_block_on(hw);
1018        rtl_cam_reset_all_entry(hw);
1019        rtl92cu_enable_hw_security_config(hw);
1020        ppsc->rfpwr_state = ERFON;
1021        rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr);
1022        if (ppsc->rfpwr_state == ERFON) {
1023                rtl92c_phy_set_rfpath_switch(hw, 1);
1024                if (iqk_initialized) {
1025                        rtl92c_phy_iq_calibrate(hw, false);
1026                } else {
1027                        rtl92c_phy_iq_calibrate(hw, false);
1028                        iqk_initialized = true;
1029                }
1030                rtl92c_dm_check_txpower_tracking(hw);
1031                rtl92c_phy_lc_calibrate(hw);
1032        }
1033        _rtl92cu_hw_configure(hw);
1034        _InitPABias(hw);
1035        _update_mac_setting(hw);
1036        rtl92c_dm_init(hw);
1037        return err;
1038}
1039
1040static void _DisableRFAFEAndResetBB(struct ieee80211_hw *hw)
1041{
1042        struct rtl_priv *rtlpriv = rtl_priv(hw);
1043/**************************************
1044a.      TXPAUSE 0x522[7:0] = 0xFF       Pause MAC TX queue
1045b.      RF path 0 offset 0x00 = 0x00    disable RF
1046c.      APSD_CTRL 0x600[7:0] = 0x40
1047d.      SYS_FUNC_EN 0x02[7:0] = 0x16    reset BB state machine
1048e.      SYS_FUNC_EN 0x02[7:0] = 0x14    reset BB state machine
1049***************************************/
1050        u8 eRFPath = 0, value8 = 0;
1051        rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
1052        rtl_set_rfreg(hw, (enum radio_path)eRFPath, 0x0, MASKBYTE0, 0x0);
1053
1054        value8 |= APSDOFF;
1055        rtl_write_byte(rtlpriv, REG_APSD_CTRL, value8); /*0x40*/
1056        value8 = 0;
1057        value8 |= (FEN_USBD | FEN_USBA | FEN_BB_GLB_RSTn);
1058        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, value8);/*0x16*/
1059        value8 &= (~FEN_BB_GLB_RSTn);
1060        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, value8); /*0x14*/
1061}
1062
1063static void  _ResetDigitalProcedure1(struct ieee80211_hw *hw, bool bWithoutHWSM)
1064{
1065        struct rtl_priv *rtlpriv = rtl_priv(hw);
1066        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1067
1068        if (rtlhal->fw_version <=  0x20) {
1069                /*****************************
1070                f. MCUFWDL 0x80[7:0]=0          reset MCU ready status
1071                g. SYS_FUNC_EN 0x02[10]= 0      reset MCU reg, (8051 reset)
1072                h. SYS_FUNC_EN 0x02[15-12]= 5   reset MAC reg, DCORE
1073                i. SYS_FUNC_EN 0x02[10]= 1      enable MCU reg, (8051 enable)
1074                ******************************/
1075                u16 valu16 = 0;
1076
1077                rtl_write_byte(rtlpriv, REG_MCUFWDL, 0);
1078                valu16 = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
1079                rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (valu16 &
1080                               (~FEN_CPUEN))); /* reset MCU ,8051 */
1081                valu16 = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN)&0x0FFF;
1082                rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (valu16 |
1083                              (FEN_HWPDN|FEN_ELDR))); /* reset MAC */
1084                valu16 = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
1085                rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (valu16 |
1086                               FEN_CPUEN)); /* enable MCU ,8051 */
1087        } else {
1088                u8 retry_cnts = 0;
1089
1090                /* IF fw in RAM code, do reset */
1091                if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(1)) {
1092                        /* reset MCU ready status */
1093                        rtl_write_byte(rtlpriv, REG_MCUFWDL, 0);
1094                        /* 8051 reset by self */
1095                        rtl_write_byte(rtlpriv, REG_HMETFR+3, 0x20);
1096                        while ((retry_cnts++ < 100) &&
1097                               (FEN_CPUEN & rtl_read_word(rtlpriv,
1098                               REG_SYS_FUNC_EN))) {
1099                                udelay(50);
1100                        }
1101                        if (retry_cnts >= 100) {
1102                                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1103                                         "#####=> 8051 reset failed!.........................\n");
1104                                /* if 8051 reset fail, reset MAC. */
1105                                rtl_write_byte(rtlpriv,
1106                                               REG_SYS_FUNC_EN + 1,
1107                                               0x50);
1108                                udelay(100);
1109                        }
1110                }
1111                /* Reset MAC and Enable 8051 */
1112                rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, 0x54);
1113                rtl_write_byte(rtlpriv, REG_MCUFWDL, 0);
1114        }
1115        if (bWithoutHWSM) {
1116                /*****************************
1117                  Without HW auto state machine
1118                g.SYS_CLKR 0x08[15:0] = 0x30A3          disable MAC clock
1119                h.AFE_PLL_CTRL 0x28[7:0] = 0x80         disable AFE PLL
1120                i.AFE_XTAL_CTRL 0x24[15:0] = 0x880F     gated AFE DIG_CLOCK
1121                j.SYS_ISu_CTRL 0x00[7:0] = 0xF9         isolated digital to PON
1122                ******************************/
1123                rtl_write_word(rtlpriv, REG_SYS_CLKR, 0x70A3);
1124                rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x80);
1125                rtl_write_word(rtlpriv, REG_AFE_XTAL_CTRL, 0x880F);
1126                rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL, 0xF9);
1127        }
1128}
1129
1130static void _ResetDigitalProcedure2(struct ieee80211_hw *hw)
1131{
1132        struct rtl_priv *rtlpriv = rtl_priv(hw);
1133/*****************************
1134k. SYS_FUNC_EN 0x03[7:0] = 0x44         disable ELDR runction
1135l. SYS_CLKR 0x08[15:0] = 0x3083         disable ELDR clock
1136m. SYS_ISO_CTRL 0x01[7:0] = 0x83        isolated ELDR to PON
1137******************************/
1138        rtl_write_word(rtlpriv, REG_SYS_CLKR, 0x70A3);
1139        rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL+1, 0x82);
1140}
1141
1142static void _DisableGPIO(struct ieee80211_hw *hw)
1143{
1144        struct rtl_priv *rtlpriv = rtl_priv(hw);
1145/***************************************
1146j. GPIO_PIN_CTRL 0x44[31:0]=0x000
1147k. Value = GPIO_PIN_CTRL[7:0]
1148l.  GPIO_PIN_CTRL 0x44[31:0] = 0x00FF0000 | (value <<8); write ext PIN level
1149m. GPIO_MUXCFG 0x42 [15:0] = 0x0780
1150n. LEDCFG 0x4C[15:0] = 0x8080
1151***************************************/
1152        u8      value8;
1153        u16     value16;
1154        u32     value32;
1155
1156        /* 1. Disable GPIO[7:0] */
1157        rtl_write_word(rtlpriv, REG_GPIO_PIN_CTRL+2, 0x0000);
1158        value32 = rtl_read_dword(rtlpriv, REG_GPIO_PIN_CTRL) & 0xFFFF00FF;
1159        value8 = (u8) (value32&0x000000FF);
1160        value32 |= ((value8<<8) | 0x00FF0000);
1161        rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, value32);
1162        /* 2. Disable GPIO[10:8] */
1163        rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG+3, 0x00);
1164        value16 = rtl_read_word(rtlpriv, REG_GPIO_MUXCFG+2) & 0xFF0F;
1165        value8 = (u8) (value16&0x000F);
1166        value16 |= ((value8<<4) | 0x0780);
1167        rtl_write_word(rtlpriv, REG_GPIO_PIN_CTRL+2, value16);
1168        /* 3. Disable LED0 & 1 */
1169        rtl_write_word(rtlpriv, REG_LEDCFG0, 0x8080);
1170}
1171
1172static void _DisableAnalog(struct ieee80211_hw *hw, bool bWithoutHWSM)
1173{
1174        struct rtl_priv *rtlpriv = rtl_priv(hw);
1175        u16 value16 = 0;
1176        u8 value8 = 0;
1177
1178        if (bWithoutHWSM) {
1179                /*****************************
1180                n. LDOA15_CTRL 0x20[7:0] = 0x04  disable A15 power
1181                o. LDOV12D_CTRL 0x21[7:0] = 0x54 disable digital core power
1182                r. When driver call disable, the ASIC will turn off remaining
1183                   clock automatically
1184                ******************************/
1185                rtl_write_byte(rtlpriv, REG_LDOA15_CTRL, 0x04);
1186                value8 = rtl_read_byte(rtlpriv, REG_LDOV12D_CTRL);
1187                value8 &= (~LDV12_EN);
1188                rtl_write_byte(rtlpriv, REG_LDOV12D_CTRL, value8);
1189        }
1190
1191/*****************************
1192h. SPS0_CTRL 0x11[7:0] = 0x23           enter PFM mode
1193i. APS_FSMCO 0x04[15:0] = 0x4802        set USB suspend
1194******************************/
1195        rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x23);
1196        value16 |= (APDM_HOST | AFSM_HSUS | PFM_ALDN);
1197        rtl_write_word(rtlpriv, REG_APS_FSMCO, (u16)value16);
1198        rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0E);
1199}
1200
1201static void _CardDisableHWSM(struct ieee80211_hw *hw)
1202{
1203        /* ==== RF Off Sequence ==== */
1204        _DisableRFAFEAndResetBB(hw);
1205        /* ==== Reset digital sequence   ====== */
1206        _ResetDigitalProcedure1(hw, false);
1207        /*  ==== Pull GPIO PIN to balance level and LED control ====== */
1208        _DisableGPIO(hw);
1209        /* ==== Disable analog sequence === */
1210        _DisableAnalog(hw, false);
1211}
1212
1213static void _CardDisableWithoutHWSM(struct ieee80211_hw *hw)
1214{
1215        /*==== RF Off Sequence ==== */
1216        _DisableRFAFEAndResetBB(hw);
1217        /*  ==== Reset digital sequence   ====== */
1218        _ResetDigitalProcedure1(hw, true);
1219        /*  ==== Pull GPIO PIN to balance level and LED control ====== */
1220        _DisableGPIO(hw);
1221        /*  ==== Reset digital sequence   ====== */
1222        _ResetDigitalProcedure2(hw);
1223        /*  ==== Disable analog sequence === */
1224        _DisableAnalog(hw, true);
1225}
1226
1227static void _rtl92cu_set_bcn_ctrl_reg(struct ieee80211_hw *hw,
1228                                      u8 set_bits, u8 clear_bits)
1229{
1230        struct rtl_priv *rtlpriv = rtl_priv(hw);
1231        struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw));
1232
1233        rtlusb->reg_bcn_ctrl_val |= set_bits;
1234        rtlusb->reg_bcn_ctrl_val &= ~clear_bits;
1235        rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8) rtlusb->reg_bcn_ctrl_val);
1236}
1237
1238static void _rtl92cu_stop_tx_beacon(struct ieee80211_hw *hw)
1239{
1240        struct rtl_priv *rtlpriv = rtl_priv(hw);
1241        struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1242        u8 tmp1byte = 0;
1243        if (IS_NORMAL_CHIP(rtlhal->version)) {
1244                tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
1245                rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2,
1246                               tmp1byte & (~BIT(6)));
1247                rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0x64);
1248                tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2);
1249                tmp1byte &= ~(BIT(0));
1250                rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte);
1251        } else {
1252                rtl_write_byte(rtlpriv, REG_TXPAUSE,
1253                               rtl_read_byte(rtlpriv, REG_TXPAUSE) | BIT(6));
1254        }
1255}
1256
1257static void _rtl92cu_resume_tx_beacon(struct ieee80211_hw *hw)
1258{
1259        struct rtl_priv *rtlpriv = rtl_priv(hw);
1260        struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1261        u8 tmp1byte = 0;
1262
1263        if (IS_NORMAL_CHIP(rtlhal->version)) {
1264                tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2);
1265                rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2,
1266                               tmp1byte | BIT(6));
1267                rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff);
1268                tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2);
1269                tmp1byte |= BIT(0);
1270                rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte);
1271        } else {
1272                rtl_write_byte(rtlpriv, REG_TXPAUSE,
1273                               rtl_read_byte(rtlpriv, REG_TXPAUSE) & (~BIT(6)));
1274        }
1275}
1276
1277static void _rtl92cu_enable_bcn_sub_func(struct ieee80211_hw *hw)
1278{
1279        struct rtl_priv *rtlpriv = rtl_priv(hw);
1280        struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1281
1282        if (IS_NORMAL_CHIP(rtlhal->version))
1283                _rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(1));
1284        else
1285                _rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(4));
1286}
1287
1288static void _rtl92cu_disable_bcn_sub_func(struct ieee80211_hw *hw)
1289{
1290        struct rtl_priv *rtlpriv = rtl_priv(hw);
1291        struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1292
1293        if (IS_NORMAL_CHIP(rtlhal->version))
1294                _rtl92cu_set_bcn_ctrl_reg(hw, BIT(1), 0);
1295        else
1296                _rtl92cu_set_bcn_ctrl_reg(hw, BIT(4), 0);
1297}
1298
1299static int _rtl92cu_set_media_status(struct ieee80211_hw *hw,
1300                                     enum nl80211_iftype type)
1301{
1302        struct rtl_priv *rtlpriv = rtl_priv(hw);
1303        u8 bt_msr = rtl_read_byte(rtlpriv, MSR);
1304        enum led_ctl_mode ledaction = LED_CTL_NO_LINK;
1305
1306        bt_msr &= 0xfc;
1307        rtl_write_byte(rtlpriv, REG_BCN_MAX_ERR, 0xFF);
1308        if (type == NL80211_IFTYPE_UNSPECIFIED || type ==
1309            NL80211_IFTYPE_STATION) {
1310                _rtl92cu_stop_tx_beacon(hw);
1311                _rtl92cu_enable_bcn_sub_func(hw);
1312        } else if (type == NL80211_IFTYPE_ADHOC || type == NL80211_IFTYPE_AP) {
1313                _rtl92cu_resume_tx_beacon(hw);
1314                _rtl92cu_disable_bcn_sub_func(hw);
1315        } else {
1316                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1317                         "Set HW_VAR_MEDIA_STATUS:No such media status(%x)\n",
1318                         type);
1319        }
1320        switch (type) {
1321        case NL80211_IFTYPE_UNSPECIFIED:
1322                bt_msr |= MSR_NOLINK;
1323                ledaction = LED_CTL_LINK;
1324                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1325                         "Set Network type to NO LINK!\n");
1326                break;
1327        case NL80211_IFTYPE_ADHOC:
1328                bt_msr |= MSR_ADHOC;
1329                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1330                         "Set Network type to Ad Hoc!\n");
1331                break;
1332        case NL80211_IFTYPE_STATION:
1333                bt_msr |= MSR_INFRA;
1334                ledaction = LED_CTL_LINK;
1335                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1336                         "Set Network type to STA!\n");
1337                break;
1338        case NL80211_IFTYPE_AP:
1339                bt_msr |= MSR_AP;
1340                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1341                         "Set Network type to AP!\n");
1342                break;
1343        default:
1344                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1345                         "Network type %d not supported!\n", type);
1346                goto error_out;
1347        }
1348        rtl_write_byte(rtlpriv, (MSR), bt_msr);
1349        rtlpriv->cfg->ops->led_control(hw, ledaction);
1350        if ((bt_msr & 0xfc) == MSR_AP)
1351                rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00);
1352        else
1353                rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66);
1354        return 0;
1355error_out:
1356        return 1;
1357}
1358
1359void rtl92cu_card_disable(struct ieee80211_hw *hw)
1360{
1361        struct rtl_priv *rtlpriv = rtl_priv(hw);
1362        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1363        struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw));
1364        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1365        enum nl80211_iftype opmode;
1366
1367        mac->link_state = MAC80211_NOLINK;
1368        opmode = NL80211_IFTYPE_UNSPECIFIED;
1369        _rtl92cu_set_media_status(hw, opmode);
1370        rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF);
1371        RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
1372        if (rtlusb->disableHWSM)
1373                _CardDisableHWSM(hw);
1374        else
1375                _CardDisableWithoutHWSM(hw);
1376}
1377
1378void rtl92cu_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid)
1379{
1380        struct rtl_priv *rtlpriv = rtl_priv(hw);
1381        struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1382        u32 reg_rcr = rtl_read_dword(rtlpriv, REG_RCR);
1383
1384        if (rtlpriv->psc.rfpwr_state != ERFON)
1385                return;
1386
1387        if (check_bssid) {
1388                u8 tmp;
1389                if (IS_NORMAL_CHIP(rtlhal->version)) {
1390                        reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN);
1391                        tmp = BIT(4);
1392                } else {
1393                        reg_rcr |= RCR_CBSSID;
1394                        tmp = BIT(4) | BIT(5);
1395                }
1396                rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR,
1397                                              (u8 *) (&reg_rcr));
1398                _rtl92cu_set_bcn_ctrl_reg(hw, 0, tmp);
1399        } else {
1400                u8 tmp;
1401                if (IS_NORMAL_CHIP(rtlhal->version)) {
1402                        reg_rcr &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN);
1403                        tmp = BIT(4);
1404                } else {
1405                        reg_rcr &= ~RCR_CBSSID;
1406                        tmp = BIT(4) | BIT(5);
1407                }
1408                reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN));
1409                rtlpriv->cfg->ops->set_hw_reg(hw,
1410                                              HW_VAR_RCR, (u8 *) (&reg_rcr));
1411                _rtl92cu_set_bcn_ctrl_reg(hw, tmp, 0);
1412        }
1413}
1414
1415/*========================================================================== */
1416
1417int rtl92cu_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type)
1418{
1419        struct rtl_priv *rtlpriv = rtl_priv(hw);
1420
1421        if (_rtl92cu_set_media_status(hw, type))
1422                return -EOPNOTSUPP;
1423
1424        if (rtlpriv->mac80211.link_state == MAC80211_LINKED) {
1425                if (type != NL80211_IFTYPE_AP)
1426                        rtl92cu_set_check_bssid(hw, true);
1427        } else {
1428                rtl92cu_set_check_bssid(hw, false);
1429        }
1430
1431        return 0;
1432}
1433
1434static void _InitBeaconParameters(struct ieee80211_hw *hw)
1435{
1436        struct rtl_priv *rtlpriv = rtl_priv(hw);
1437        struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1438
1439        rtl_write_word(rtlpriv, REG_BCN_CTRL, 0x1010);
1440
1441        /* TODO: Remove these magic number */
1442        rtl_write_word(rtlpriv, REG_TBTT_PROHIBIT, 0x6404);
1443        rtl_write_byte(rtlpriv, REG_DRVERLYINT, DRIVER_EARLY_INT_TIME);
1444        rtl_write_byte(rtlpriv, REG_BCNDMATIM, BCN_DMA_ATIME_INT_TIME);
1445        /* Change beacon AIFS to the largest number
1446         * beacause test chip does not contension before sending beacon. */
1447        if (IS_NORMAL_CHIP(rtlhal->version))
1448                rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660F);
1449        else
1450                rtl_write_word(rtlpriv, REG_BCNTCFG, 0x66FF);
1451}
1452
1453static void _beacon_function_enable(struct ieee80211_hw *hw, bool Enable,
1454                                    bool Linked)
1455{
1456        struct rtl_priv *rtlpriv = rtl_priv(hw);
1457
1458        _rtl92cu_set_bcn_ctrl_reg(hw, (BIT(4) | BIT(3) | BIT(1)), 0x00);
1459        rtl_write_byte(rtlpriv, REG_RD_CTRL+1, 0x6F);
1460}
1461
1462void rtl92cu_set_beacon_related_registers(struct ieee80211_hw *hw)
1463{
1464
1465        struct rtl_priv *rtlpriv = rtl_priv(hw);
1466        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1467        u16 bcn_interval, atim_window;
1468        u32 value32;
1469
1470        bcn_interval = mac->beacon_interval;
1471        atim_window = 2;        /*FIX MERGE */
1472        rtl_write_word(rtlpriv, REG_ATIMWND, atim_window);
1473        rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
1474        _InitBeaconParameters(hw);
1475        rtl_write_byte(rtlpriv, REG_SLOT, 0x09);
1476        /*
1477         * Force beacon frame transmission even after receiving beacon frame
1478         * from other ad hoc STA
1479         *
1480         *
1481         * Reset TSF Timer to zero, added by Roger. 2008.06.24
1482         */
1483        value32 = rtl_read_dword(rtlpriv, REG_TCR);
1484        value32 &= ~TSFRST;
1485        rtl_write_dword(rtlpriv, REG_TCR, value32);
1486        value32 |= TSFRST;
1487        rtl_write_dword(rtlpriv, REG_TCR, value32);
1488        RT_TRACE(rtlpriv, COMP_INIT|COMP_BEACON, DBG_LOUD,
1489                 "SetBeaconRelatedRegisters8192CUsb(): Set TCR(%x)\n",
1490                 value32);
1491        /* TODO: Modify later (Find the right parameters)
1492         * NOTE: Fix test chip's bug (about contention windows's randomness) */
1493        if ((mac->opmode == NL80211_IFTYPE_ADHOC) ||
1494            (mac->opmode == NL80211_IFTYPE_AP)) {
1495                rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x50);
1496                rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x50);
1497        }
1498        _beacon_function_enable(hw, true, true);
1499}
1500
1501void rtl92cu_set_beacon_interval(struct ieee80211_hw *hw)
1502{
1503        struct rtl_priv *rtlpriv = rtl_priv(hw);
1504        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1505        u16 bcn_interval = mac->beacon_interval;
1506
1507        RT_TRACE(rtlpriv, COMP_BEACON, DBG_DMESG, "beacon_interval:%d\n",
1508                 bcn_interval);
1509        rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval);
1510}
1511
1512void rtl92cu_update_interrupt_mask(struct ieee80211_hw *hw,
1513                                   u32 add_msr, u32 rm_msr)
1514{
1515}
1516
1517void rtl92cu_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
1518{
1519        struct rtl_priv *rtlpriv = rtl_priv(hw);
1520        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1521        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1522
1523        switch (variable) {
1524        case HW_VAR_RCR:
1525                *((u32 *)(val)) = mac->rx_conf;
1526                break;
1527        case HW_VAR_RF_STATE:
1528                *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state;
1529                break;
1530        case HW_VAR_FWLPS_RF_ON:{
1531                        enum rf_pwrstate rfState;
1532                        u32 val_rcr;
1533
1534                        rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE,
1535                                                      (u8 *)(&rfState));
1536                        if (rfState == ERFOFF) {
1537                                *((bool *) (val)) = true;
1538                        } else {
1539                                val_rcr = rtl_read_dword(rtlpriv, REG_RCR);
1540                                val_rcr &= 0x00070000;
1541                                if (val_rcr)
1542                                        *((bool *) (val)) = false;
1543                                else
1544                                        *((bool *) (val)) = true;
1545                        }
1546                        break;
1547                }
1548        case HW_VAR_FW_PSMODE_STATUS:
1549                *((bool *) (val)) = ppsc->fw_current_inpsmode;
1550                break;
1551        case HW_VAR_CORRECT_TSF:{
1552                        u64 tsf;
1553                        u32 *ptsf_low = (u32 *)&tsf;
1554                        u32 *ptsf_high = ((u32 *)&tsf) + 1;
1555
1556                        *ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR + 4));
1557                        *ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR);
1558                        *((u64 *)(val)) = tsf;
1559                        break;
1560                }
1561        case HW_VAR_MGT_FILTER:
1562                *((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP0);
1563                break;
1564        case HW_VAR_CTRL_FILTER:
1565                *((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP1);
1566                break;
1567        case HW_VAR_DATA_FILTER:
1568                *((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP2);
1569                break;
1570        default:
1571                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1572                         "switch case not processed\n");
1573                break;
1574        }
1575}
1576
1577void rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val)
1578{
1579        struct rtl_priv *rtlpriv = rtl_priv(hw);
1580        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1581        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1582        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1583        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1584        struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw));
1585        enum wireless_mode wirelessmode = mac->mode;
1586        u8 idx = 0;
1587
1588        switch (variable) {
1589        case HW_VAR_ETHER_ADDR:{
1590                        for (idx = 0; idx < ETH_ALEN; idx++) {
1591                                rtl_write_byte(rtlpriv, (REG_MACID + idx),
1592                                               val[idx]);
1593                        }
1594                        break;
1595                }
1596        case HW_VAR_BASIC_RATE:{
1597                        u16 rate_cfg = ((u16 *) val)[0];
1598                        u8 rate_index = 0;
1599
1600                        rate_cfg &= 0x15f;
1601                        /* TODO */
1602                        /* if (mac->current_network.vender == HT_IOT_PEER_CISCO
1603                         *     && ((rate_cfg & 0x150) == 0)) {
1604                         *        rate_cfg |= 0x010;
1605                         * } */
1606                        rate_cfg |= 0x01;
1607                        rtl_write_byte(rtlpriv, REG_RRSR, rate_cfg & 0xff);
1608                        rtl_write_byte(rtlpriv, REG_RRSR + 1,
1609                                       (rate_cfg >> 8) & 0xff);
1610                        while (rate_cfg > 0x1) {
1611                                rate_cfg >>= 1;
1612                                rate_index++;
1613                        }
1614                        rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL,
1615                                       rate_index);
1616                        break;
1617                }
1618        case HW_VAR_BSSID:{
1619                        for (idx = 0; idx < ETH_ALEN; idx++) {
1620                                rtl_write_byte(rtlpriv, (REG_BSSID + idx),
1621                                               val[idx]);
1622                        }
1623                        break;
1624                }
1625        case HW_VAR_SIFS:{
1626                        rtl_write_byte(rtlpriv, REG_SIFS_CCK + 1, val[0]);
1627                        rtl_write_byte(rtlpriv, REG_SIFS_OFDM + 1, val[1]);
1628                        rtl_write_byte(rtlpriv, REG_SPEC_SIFS + 1, val[0]);
1629                        rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]);
1630                        rtl_write_byte(rtlpriv, REG_R2T_SIFS+1, val[0]);
1631                        rtl_write_byte(rtlpriv, REG_T2T_SIFS+1, val[0]);
1632                        RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, "HW_VAR_SIFS\n");
1633                        break;
1634                }
1635        case HW_VAR_SLOT_TIME:{
1636                        u8 e_aci;
1637                        u8 QOS_MODE = 1;
1638
1639                        rtl_write_byte(rtlpriv, REG_SLOT, val[0]);
1640                        RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
1641                                 "HW_VAR_SLOT_TIME %x\n", val[0]);
1642                        if (QOS_MODE) {
1643                                for (e_aci = 0; e_aci < AC_MAX; e_aci++)
1644                                        rtlpriv->cfg->ops->set_hw_reg(hw,
1645                                                                HW_VAR_AC_PARAM,
1646                                                                &e_aci);
1647                        } else {
1648                                u8 sifstime = 0;
1649                                u8      u1bAIFS;
1650
1651                                if (IS_WIRELESS_MODE_A(wirelessmode) ||
1652                                    IS_WIRELESS_MODE_N_24G(wirelessmode) ||
1653                                    IS_WIRELESS_MODE_N_5G(wirelessmode))
1654                                        sifstime = 16;
1655                                else
1656                                        sifstime = 10;
1657                                u1bAIFS = sifstime + (2 *  val[0]);
1658                                rtl_write_byte(rtlpriv, REG_EDCA_VO_PARAM,
1659                                               u1bAIFS);
1660                                rtl_write_byte(rtlpriv, REG_EDCA_VI_PARAM,
1661                                               u1bAIFS);
1662                                rtl_write_byte(rtlpriv, REG_EDCA_BE_PARAM,
1663                                               u1bAIFS);
1664                                rtl_write_byte(rtlpriv, REG_EDCA_BK_PARAM,
1665                                               u1bAIFS);
1666                        }
1667                        break;
1668                }
1669        case HW_VAR_ACK_PREAMBLE:{
1670                        u8 reg_tmp;
1671                        u8 short_preamble = (bool)*val;
1672                        reg_tmp = 0;
1673                        if (short_preamble)
1674                                reg_tmp |= 0x80;
1675                        rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_tmp);
1676                        break;
1677                }
1678        case HW_VAR_AMPDU_MIN_SPACE:{
1679                        u8 min_spacing_to_set;
1680                        u8 sec_min_space;
1681
1682                        min_spacing_to_set = *val;
1683                        if (min_spacing_to_set <= 7) {
1684                                switch (rtlpriv->sec.pairwise_enc_algorithm) {
1685                                case NO_ENCRYPTION:
1686                                case AESCCMP_ENCRYPTION:
1687                                        sec_min_space = 0;
1688                                        break;
1689                                case WEP40_ENCRYPTION:
1690                                case WEP104_ENCRYPTION:
1691                                case TKIP_ENCRYPTION:
1692                                        sec_min_space = 6;
1693                                        break;
1694                                default:
1695                                        sec_min_space = 7;
1696                                        break;
1697                                }
1698                                if (min_spacing_to_set < sec_min_space)
1699                                        min_spacing_to_set = sec_min_space;
1700                                mac->min_space_cfg = ((mac->min_space_cfg &
1701                                                     0xf8) |
1702                                                     min_spacing_to_set);
1703                                *val = min_spacing_to_set;
1704                                RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
1705                                         "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n",
1706                                         mac->min_space_cfg);
1707                                rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
1708                                               mac->min_space_cfg);
1709                        }
1710                        break;
1711                }
1712        case HW_VAR_SHORTGI_DENSITY:{
1713                        u8 density_to_set;
1714
1715                        density_to_set = *val;
1716                        density_to_set &= 0x1f;
1717                        mac->min_space_cfg &= 0x07;
1718                        mac->min_space_cfg |= (density_to_set << 3);
1719                        RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
1720                                 "Set HW_VAR_SHORTGI_DENSITY: %#x\n",
1721                                 mac->min_space_cfg);
1722                        rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE,
1723                                       mac->min_space_cfg);
1724                        break;
1725                }
1726        case HW_VAR_AMPDU_FACTOR:{
1727                        u8 regtoset_normal[4] = {0x41, 0xa8, 0x72, 0xb9};
1728                        u8 factor_toset;
1729                        u8 *p_regtoset = NULL;
1730                        u8 index = 0;
1731
1732                        p_regtoset = regtoset_normal;
1733                        factor_toset = *val;
1734                        if (factor_toset <= 3) {
1735                                factor_toset = (1 << (factor_toset + 2));
1736                                if (factor_toset > 0xf)
1737                                        factor_toset = 0xf;
1738                                for (index = 0; index < 4; index++) {
1739                                        if ((p_regtoset[index] & 0xf0) >
1740                                            (factor_toset << 4))
1741                                                p_regtoset[index] =
1742                                                     (p_regtoset[index] & 0x0f)
1743                                                     | (factor_toset << 4);
1744                                        if ((p_regtoset[index] & 0x0f) >
1745                                             factor_toset)
1746                                                p_regtoset[index] =
1747                                                     (p_regtoset[index] & 0xf0)
1748                                                     | (factor_toset);
1749                                        rtl_write_byte(rtlpriv,
1750                                                       (REG_AGGLEN_LMT + index),
1751                                                       p_regtoset[index]);
1752                                }
1753                                RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
1754                                         "Set HW_VAR_AMPDU_FACTOR: %#x\n",
1755                                         factor_toset);
1756                        }
1757                        break;
1758                }
1759        case HW_VAR_AC_PARAM:{
1760                        u8 e_aci = *val;
1761                        u32 u4b_ac_param;
1762                        u16 cw_min = le16_to_cpu(mac->ac[e_aci].cw_min);
1763                        u16 cw_max = le16_to_cpu(mac->ac[e_aci].cw_max);
1764                        u16 tx_op = le16_to_cpu(mac->ac[e_aci].tx_op);
1765
1766                        u4b_ac_param = (u32) mac->ac[e_aci].aifs;
1767                        u4b_ac_param |= (u32) ((cw_min & 0xF) <<
1768                                         AC_PARAM_ECW_MIN_OFFSET);
1769                        u4b_ac_param |= (u32) ((cw_max & 0xF) <<
1770                                         AC_PARAM_ECW_MAX_OFFSET);
1771                        u4b_ac_param |= (u32) tx_op << AC_PARAM_TXOP_OFFSET;
1772                        RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
1773                                 "queue:%x, ac_param:%x\n",
1774                                 e_aci, u4b_ac_param);
1775                        switch (e_aci) {
1776                        case AC1_BK:
1777                                rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM,
1778                                                u4b_ac_param);
1779                                break;
1780                        case AC0_BE:
1781                                rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM,
1782                                                u4b_ac_param);
1783                                break;
1784                        case AC2_VI:
1785                                rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM,
1786                                                u4b_ac_param);
1787                                break;
1788                        case AC3_VO:
1789                                rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM,
1790                                                u4b_ac_param);
1791                                break;
1792                        default:
1793                                RT_ASSERT(false,
1794                                          "SetHwReg8185(): invalid aci: %d !\n",
1795                                          e_aci);
1796                                break;
1797                        }
1798                        if (rtlusb->acm_method != eAcmWay2_SW)
1799                                rtlpriv->cfg->ops->set_hw_reg(hw,
1800                                         HW_VAR_ACM_CTRL, &e_aci);
1801                        break;
1802                }
1803        case HW_VAR_ACM_CTRL:{
1804                        u8 e_aci = *val;
1805                        union aci_aifsn *p_aci_aifsn = (union aci_aifsn *)
1806                                                        (&(mac->ac[0].aifs));
1807                        u8 acm = p_aci_aifsn->f.acm;
1808                        u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL);
1809
1810                        acm_ctrl =
1811                            acm_ctrl | ((rtlusb->acm_method == 2) ? 0x0 : 0x1);
1812                        if (acm) {
1813                                switch (e_aci) {
1814                                case AC0_BE:
1815                                        acm_ctrl |= AcmHw_BeqEn;
1816                                        break;
1817                                case AC2_VI:
1818                                        acm_ctrl |= AcmHw_ViqEn;
1819                                        break;
1820                                case AC3_VO:
1821                                        acm_ctrl |= AcmHw_VoqEn;
1822                                        break;
1823                                default:
1824                                        RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1825                                                 "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n",
1826                                                 acm);
1827                                        break;
1828                                }
1829                        } else {
1830                                switch (e_aci) {
1831                                case AC0_BE:
1832                                        acm_ctrl &= (~AcmHw_BeqEn);
1833                                        break;
1834                                case AC2_VI:
1835                                        acm_ctrl &= (~AcmHw_ViqEn);
1836                                        break;
1837                                case AC3_VO:
1838                                        acm_ctrl &= (~AcmHw_BeqEn);
1839                                        break;
1840                                default:
1841                                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1842                                                 "switch case not processed\n");
1843                                        break;
1844                                }
1845                        }
1846                        RT_TRACE(rtlpriv, COMP_QOS, DBG_TRACE,
1847                                 "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n",
1848                                 acm_ctrl);
1849                        rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl);
1850                        break;
1851                }
1852        case HW_VAR_RCR:{
1853                        rtl_write_dword(rtlpriv, REG_RCR, ((u32 *) (val))[0]);
1854                        mac->rx_conf = ((u32 *) (val))[0];
1855                        RT_TRACE(rtlpriv, COMP_RECV, DBG_DMESG,
1856                                 "### Set RCR(0x%08x) ###\n", mac->rx_conf);
1857                        break;
1858                }
1859        case HW_VAR_RETRY_LIMIT:{
1860                        u8 retry_limit = val[0];
1861
1862                        rtl_write_word(rtlpriv, REG_RL,
1863                                       retry_limit << RETRY_LIMIT_SHORT_SHIFT |
1864                                       retry_limit << RETRY_LIMIT_LONG_SHIFT);
1865                        RT_TRACE(rtlpriv, COMP_MLME, DBG_DMESG,
1866                                 "Set HW_VAR_RETRY_LIMIT(0x%08x)\n",
1867                                 retry_limit);
1868                        break;
1869                }
1870        case HW_VAR_DUAL_TSF_RST:
1871                rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1)));
1872                break;
1873        case HW_VAR_EFUSE_BYTES:
1874                rtlefuse->efuse_usedbytes = *((u16 *) val);
1875                break;
1876        case HW_VAR_EFUSE_USAGE:
1877                rtlefuse->efuse_usedpercentage = *val;
1878                break;
1879        case HW_VAR_IO_CMD:
1880                rtl92c_phy_set_io_cmd(hw, (*(enum io_type *)val));
1881                break;
1882        case HW_VAR_WPA_CONFIG:
1883                rtl_write_byte(rtlpriv, REG_SECCFG, *val);
1884                break;
1885        case HW_VAR_SET_RPWM:{
1886                        u8 rpwm_val = rtl_read_byte(rtlpriv, REG_USB_HRPWM);
1887
1888                        if (rpwm_val & BIT(7))
1889                                rtl_write_byte(rtlpriv, REG_USB_HRPWM, *val);
1890                        else
1891                                rtl_write_byte(rtlpriv, REG_USB_HRPWM,
1892                                               *val | BIT(7));
1893                        break;
1894                }
1895        case HW_VAR_H2C_FW_PWRMODE:{
1896                        u8 psmode = *val;
1897
1898                        if ((psmode != FW_PS_ACTIVE_MODE) &&
1899                           (!IS_92C_SERIAL(rtlhal->version)))
1900                                rtl92c_dm_rf_saving(hw, true);
1901                        rtl92c_set_fw_pwrmode_cmd(hw, (*val));
1902                        break;
1903                }
1904        case HW_VAR_FW_PSMODE_STATUS:
1905                ppsc->fw_current_inpsmode = *((bool *) val);
1906                break;
1907        case HW_VAR_H2C_FW_JOINBSSRPT:{
1908                        u8 mstatus = *val;
1909                        u8 tmp_reg422;
1910                        bool recover = false;
1911
1912                        if (mstatus == RT_MEDIA_CONNECT) {
1913                                rtlpriv->cfg->ops->set_hw_reg(hw,
1914                                                         HW_VAR_AID, NULL);
1915                                rtl_write_byte(rtlpriv, REG_CR + 1, 0x03);
1916                                _rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(3));
1917                                _rtl92cu_set_bcn_ctrl_reg(hw, BIT(4), 0);
1918                                tmp_reg422 = rtl_read_byte(rtlpriv,
1919                                                        REG_FWHW_TXQ_CTRL + 2);
1920                                if (tmp_reg422 & BIT(6))
1921                                        recover = true;
1922                                rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2,
1923                                               tmp_reg422 & (~BIT(6)));
1924                                rtl92c_set_fw_rsvdpagepkt(hw, 0);
1925                                _rtl92cu_set_bcn_ctrl_reg(hw, BIT(3), 0);
1926                                _rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(4));
1927                                if (recover)
1928                                        rtl_write_byte(rtlpriv,
1929                                                 REG_FWHW_TXQ_CTRL + 2,
1930                                                tmp_reg422 | BIT(6));
1931                                rtl_write_byte(rtlpriv, REG_CR + 1, 0x02);
1932                        }
1933                        rtl92c_set_fw_joinbss_report_cmd(hw, (*val));
1934                        break;
1935                }
1936        case HW_VAR_AID:{
1937                        u16 u2btmp;
1938
1939                        u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT);
1940                        u2btmp &= 0xC000;
1941                        rtl_write_word(rtlpriv, REG_BCN_PSR_RPT,
1942                                       (u2btmp | mac->assoc_id));
1943                        break;
1944                }
1945        case HW_VAR_CORRECT_TSF:{
1946                        u8 btype_ibss = val[0];
1947
1948                        if (btype_ibss)
1949                                _rtl92cu_stop_tx_beacon(hw);
1950                        _rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(3));
1951                        rtl_write_dword(rtlpriv, REG_TSFTR, (u32)(mac->tsf &
1952                                        0xffffffff));
1953                        rtl_write_dword(rtlpriv, REG_TSFTR + 4,
1954                                        (u32)((mac->tsf >> 32) & 0xffffffff));
1955                        _rtl92cu_set_bcn_ctrl_reg(hw, BIT(3), 0);
1956                        if (btype_ibss)
1957                                _rtl92cu_resume_tx_beacon(hw);
1958                        break;
1959                }
1960        case HW_VAR_MGT_FILTER:
1961                rtl_write_word(rtlpriv, REG_RXFLTMAP0, *(u16 *)val);
1962                break;
1963        case HW_VAR_CTRL_FILTER:
1964                rtl_write_word(rtlpriv, REG_RXFLTMAP1, *(u16 *)val);
1965                break;
1966        case HW_VAR_DATA_FILTER:
1967                rtl_write_word(rtlpriv, REG_RXFLTMAP2, *(u16 *)val);
1968                break;
1969        default:
1970                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1971                         "switch case not processed\n");
1972                break;
1973        }
1974}
1975
1976static void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw,
1977                                          struct ieee80211_sta *sta)
1978{
1979        struct rtl_priv *rtlpriv = rtl_priv(hw);
1980        struct rtl_phy *rtlphy = &(rtlpriv->phy);
1981        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1982        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1983        u32 ratr_value;
1984        u8 ratr_index = 0;
1985        u8 nmode = mac->ht_enable;
1986        u8 mimo_ps = IEEE80211_SMPS_OFF;
1987        u16 shortgi_rate;
1988        u32 tmp_ratr_value;
1989        u8 curtxbw_40mhz = mac->bw_40;
1990        u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
1991                               1 : 0;
1992        u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
1993                               1 : 0;
1994        enum wireless_mode wirelessmode = mac->mode;
1995
1996        if (rtlhal->current_bandtype == BAND_ON_5G)
1997                ratr_value = sta->supp_rates[1] << 4;
1998        else
1999                ratr_value = sta->supp_rates[0];
2000        if (mac->opmode == NL80211_IFTYPE_ADHOC)
2001                ratr_value = 0xfff;
2002
2003        ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
2004                        sta->ht_cap.mcs.rx_mask[0] << 12);
2005        switch (wirelessmode) {
2006        case WIRELESS_MODE_B:
2007                if (ratr_value & 0x0000000c)
2008                        ratr_value &= 0x0000000d;
2009                else
2010                        ratr_value &= 0x0000000f;
2011                break;
2012        case WIRELESS_MODE_G:
2013                ratr_value &= 0x00000FF5;
2014                break;
2015        case WIRELESS_MODE_N_24G:
2016        case WIRELESS_MODE_N_5G:
2017                nmode = 1;
2018                if (mimo_ps == IEEE80211_SMPS_STATIC) {
2019                        ratr_value &= 0x0007F005;
2020                } else {
2021                        u32 ratr_mask;
2022
2023                        if (get_rf_type(rtlphy) == RF_1T2R ||
2024                            get_rf_type(rtlphy) == RF_1T1R)
2025                                ratr_mask = 0x000ff005;
2026                        else
2027                                ratr_mask = 0x0f0ff005;
2028
2029                        ratr_value &= ratr_mask;
2030                }
2031                break;
2032        default:
2033                if (rtlphy->rf_type == RF_1T2R)
2034                        ratr_value &= 0x000ff0ff;
2035                else
2036                        ratr_value &= 0x0f0ff0ff;
2037
2038                break;
2039        }
2040
2041        ratr_value &= 0x0FFFFFFF;
2042
2043        if (nmode && ((curtxbw_40mhz &&
2044                         curshortgi_40mhz) || (!curtxbw_40mhz &&
2045                                               curshortgi_20mhz))) {
2046
2047                ratr_value |= 0x10000000;
2048                tmp_ratr_value = (ratr_value >> 12);
2049
2050                for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) {
2051                        if ((1 << shortgi_rate) & tmp_ratr_value)
2052                                break;
2053                }
2054
2055                shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) |
2056                    (shortgi_rate << 4) | (shortgi_rate);
2057        }
2058
2059        rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value);
2060
2061        RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n",
2062                 rtl_read_dword(rtlpriv, REG_ARFR0));
2063}
2064
2065static void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw,
2066                                         struct ieee80211_sta *sta,
2067                                         u8 rssi_level)
2068{
2069        struct rtl_priv *rtlpriv = rtl_priv(hw);
2070        struct rtl_phy *rtlphy = &(rtlpriv->phy);
2071        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2072        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2073        struct rtl_sta_info *sta_entry = NULL;
2074        u32 ratr_bitmap;
2075        u8 ratr_index;
2076        u8 curtxbw_40mhz = (sta->bandwidth >= IEEE80211_STA_RX_BW_40) ? 1 : 0;
2077        u8 curshortgi_40mhz = curtxbw_40mhz &&
2078                              (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ?
2079                                1 : 0;
2080        u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ?
2081                                1 : 0;
2082        enum wireless_mode wirelessmode = 0;
2083        bool shortgi = false;
2084        u8 rate_mask[5];
2085        u8 macid = 0;
2086        u8 mimo_ps = IEEE80211_SMPS_OFF;
2087
2088        sta_entry = (struct rtl_sta_info *) sta->drv_priv;
2089        wirelessmode = sta_entry->wireless_mode;
2090        if (mac->opmode == NL80211_IFTYPE_STATION ||
2091            mac->opmode == NL80211_IFTYPE_MESH_POINT)
2092                curtxbw_40mhz = mac->bw_40;
2093        else if (mac->opmode == NL80211_IFTYPE_AP ||
2094                mac->opmode == NL80211_IFTYPE_ADHOC)
2095                macid = sta->aid + 1;
2096
2097        if (rtlhal->current_bandtype == BAND_ON_5G)
2098                ratr_bitmap = sta->supp_rates[1] << 4;
2099        else
2100                ratr_bitmap = sta->supp_rates[0];
2101        if (mac->opmode == NL80211_IFTYPE_ADHOC)
2102                ratr_bitmap = 0xfff;
2103        ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 |
2104                        sta->ht_cap.mcs.rx_mask[0] << 12);
2105        switch (wirelessmode) {
2106        case WIRELESS_MODE_B:
2107                ratr_index = RATR_INX_WIRELESS_B;
2108                if (ratr_bitmap & 0x0000000c)
2109                        ratr_bitmap &= 0x0000000d;
2110                else
2111                        ratr_bitmap &= 0x0000000f;
2112                break;
2113        case WIRELESS_MODE_G:
2114                ratr_index = RATR_INX_WIRELESS_GB;
2115
2116                if (rssi_level == 1)
2117                        ratr_bitmap &= 0x00000f00;
2118                else if (rssi_level == 2)
2119                        ratr_bitmap &= 0x00000ff0;
2120                else
2121                        ratr_bitmap &= 0x00000ff5;
2122                break;
2123        case WIRELESS_MODE_A:
2124                ratr_index = RATR_INX_WIRELESS_A;
2125                ratr_bitmap &= 0x00000ff0;
2126                break;
2127        case WIRELESS_MODE_N_24G:
2128        case WIRELESS_MODE_N_5G:
2129                ratr_index = RATR_INX_WIRELESS_NGB;
2130
2131                if (mimo_ps == IEEE80211_SMPS_STATIC) {
2132                        if (rssi_level == 1)
2133                                ratr_bitmap &= 0x00070000;
2134                        else if (rssi_level == 2)
2135                                ratr_bitmap &= 0x0007f000;
2136                        else
2137                                ratr_bitmap &= 0x0007f005;
2138                } else {
2139                        if (rtlphy->rf_type == RF_1T2R ||
2140                            rtlphy->rf_type == RF_1T1R) {
2141                                if (curtxbw_40mhz) {
2142                                        if (rssi_level == 1)
2143                                                ratr_bitmap &= 0x000f0000;
2144                                        else if (rssi_level == 2)
2145                                                ratr_bitmap &= 0x000ff000;
2146                                        else
2147                                                ratr_bitmap &= 0x000ff015;
2148                                } else {
2149                                        if (rssi_level == 1)
2150                                                ratr_bitmap &= 0x000f0000;
2151                                        else if (rssi_level == 2)
2152                                                ratr_bitmap &= 0x000ff000;
2153                                        else
2154                                                ratr_bitmap &= 0x000ff005;
2155                                }
2156                        } else {
2157                                if (curtxbw_40mhz) {
2158                                        if (rssi_level == 1)
2159                                                ratr_bitmap &= 0x0f0f0000;
2160                                        else if (rssi_level == 2)
2161                                                ratr_bitmap &= 0x0f0ff000;
2162                                        else
2163                                                ratr_bitmap &= 0x0f0ff015;
2164                                } else {
2165                                        if (rssi_level == 1)
2166                                                ratr_bitmap &= 0x0f0f0000;
2167                                        else if (rssi_level == 2)
2168                                                ratr_bitmap &= 0x0f0ff000;
2169                                        else
2170                                                ratr_bitmap &= 0x0f0ff005;
2171                                }
2172                        }
2173                }
2174
2175                if ((curtxbw_40mhz && curshortgi_40mhz) ||
2176                    (!curtxbw_40mhz && curshortgi_20mhz)) {
2177
2178                        if (macid == 0)
2179                                shortgi = true;
2180                        else if (macid == 1)
2181                                shortgi = false;
2182                }
2183                break;
2184        default:
2185                ratr_index = RATR_INX_WIRELESS_NGB;
2186
2187                if (rtlphy->rf_type == RF_1T2R)
2188                        ratr_bitmap &= 0x000ff0ff;
2189                else
2190                        ratr_bitmap &= 0x0f0ff0ff;
2191                break;
2192        }
2193        sta_entry->ratr_index = ratr_index;
2194
2195        RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
2196                 "ratr_bitmap :%x\n", ratr_bitmap);
2197        *(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) |
2198                                     (ratr_index << 28);
2199        rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80;
2200        RT_TRACE(rtlpriv, COMP_RATR, DBG_DMESG,
2201                 "Rate_index:%x, ratr_val:%x, %5phC\n",
2202                 ratr_index, ratr_bitmap, rate_mask);
2203        memcpy(rtlpriv->rate_mask, rate_mask, 5);
2204        /* rtl92c_fill_h2c_cmd() does USB I/O and will result in a
2205         * "scheduled while atomic" if called directly */
2206        schedule_work(&rtlpriv->works.fill_h2c_cmd);
2207
2208        if (macid != 0)
2209                sta_entry->ratr_index = ratr_index;
2210}
2211
2212void rtl92cu_update_hal_rate_tbl(struct ieee80211_hw *hw,
2213                                 struct ieee80211_sta *sta,
2214                                 u8 rssi_level)
2215{
2216        struct rtl_priv *rtlpriv = rtl_priv(hw);
2217
2218        if (rtlpriv->dm.useramask)
2219                rtl92cu_update_hal_rate_mask(hw, sta, rssi_level);
2220        else
2221                rtl92cu_update_hal_rate_table(hw, sta);
2222}
2223
2224void rtl92cu_update_channel_access_setting(struct ieee80211_hw *hw)
2225{
2226        struct rtl_priv *rtlpriv = rtl_priv(hw);
2227        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2228        u16 sifs_timer;
2229
2230        rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME,
2231                                      &mac->slot_time);
2232        if (!mac->ht_enable)
2233                sifs_timer = 0x0a0a;
2234        else
2235                sifs_timer = 0x0e0e;
2236        rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer);
2237}
2238
2239bool rtl92cu_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid)
2240{
2241        struct rtl_priv *rtlpriv = rtl_priv(hw);
2242        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2243        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2244        enum rf_pwrstate e_rfpowerstate_toset, cur_rfstate;
2245        u8 u1tmp = 0;
2246        bool actuallyset = false;
2247        unsigned long flag = 0;
2248        /* to do - usb autosuspend */
2249        u8 usb_autosuspend = 0;
2250
2251        if (ppsc->swrf_processing)
2252                return false;
2253        spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
2254        if (ppsc->rfchange_inprogress) {
2255                spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
2256                return false;
2257        } else {
2258                ppsc->rfchange_inprogress = true;
2259                spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
2260        }
2261        cur_rfstate = ppsc->rfpwr_state;
2262        if (usb_autosuspend) {
2263                /* to do................... */
2264        } else {
2265                if (ppsc->pwrdown_mode) {
2266                        u1tmp = rtl_read_byte(rtlpriv, REG_HSISR);
2267                        e_rfpowerstate_toset = (u1tmp & BIT(7)) ?
2268                                               ERFOFF : ERFON;
2269                        RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
2270                                 "pwrdown, 0x5c(BIT7)=%02x\n", u1tmp);
2271                } else {
2272                        rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG,
2273                                       rtl_read_byte(rtlpriv,
2274                                       REG_MAC_PINMUX_CFG) & ~(BIT(3)));
2275                        u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL);
2276                        e_rfpowerstate_toset  = (u1tmp & BIT(3)) ?
2277                                                 ERFON : ERFOFF;
2278                        RT_TRACE(rtlpriv, COMP_POWER, DBG_DMESG,
2279                                 "GPIO_IN=%02x\n", u1tmp);
2280                }
2281                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "N-SS RF =%x\n",
2282                         e_rfpowerstate_toset);
2283        }
2284        if ((ppsc->hwradiooff) && (e_rfpowerstate_toset == ERFON)) {
2285                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
2286                         "GPIOChangeRF  - HW Radio ON, RF ON\n");
2287                ppsc->hwradiooff = false;
2288                actuallyset = true;
2289        } else if ((!ppsc->hwradiooff) && (e_rfpowerstate_toset  ==
2290                    ERFOFF)) {
2291                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
2292                         "GPIOChangeRF  - HW Radio OFF\n");
2293                ppsc->hwradiooff = true;
2294                actuallyset = true;
2295        } else {
2296                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
2297                         "pHalData->bHwRadioOff and eRfPowerStateToSet do not match: pHalData->bHwRadioOff %x, eRfPowerStateToSet %x\n",
2298                         ppsc->hwradiooff, e_rfpowerstate_toset);
2299        }
2300        if (actuallyset) {
2301                ppsc->hwradiooff = true;
2302                if (e_rfpowerstate_toset == ERFON) {
2303                        if ((ppsc->reg_rfps_level  & RT_RF_OFF_LEVL_ASPM) &&
2304                             RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM))
2305                                RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM);
2306                        else if ((ppsc->reg_rfps_level  & RT_RF_OFF_LEVL_PCI_D3)
2307                                 && RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_PCI_D3))
2308                                RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_PCI_D3);
2309                }
2310                spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
2311                ppsc->rfchange_inprogress = false;
2312                spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
2313                /* For power down module, we need to enable register block
2314                 * contrl reg at 0x1c. Then enable power down control bit
2315                 * of register 0x04 BIT4 and BIT15 as 1.
2316                 */
2317                if (ppsc->pwrdown_mode && e_rfpowerstate_toset == ERFOFF) {
2318                        /* Enable register area 0x0-0xc. */
2319                        rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0);
2320                        if (IS_HARDWARE_TYPE_8723U(rtlhal)) {
2321                                /*
2322                                 * We should configure HW PDn source for WiFi
2323                                 * ONLY, and then our HW will be set in
2324                                 * power-down mode if PDn source from all
2325                                 * functions are configured.
2326                                 */
2327                                u1tmp = rtl_read_byte(rtlpriv,
2328                                                      REG_MULTI_FUNC_CTRL);
2329                                rtl_write_byte(rtlpriv, REG_MULTI_FUNC_CTRL,
2330                                               (u1tmp|WL_HWPDN_EN));
2331                        } else {
2332                                rtl_write_word(rtlpriv, REG_APS_FSMCO, 0x8812);
2333                        }
2334                }
2335                if (e_rfpowerstate_toset == ERFOFF) {
2336                        if (ppsc->reg_rfps_level  & RT_RF_OFF_LEVL_ASPM)
2337                                RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM);
2338                        else if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_PCI_D3)
2339                                RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_PCI_D3);
2340                }
2341        } else if (e_rfpowerstate_toset == ERFOFF || cur_rfstate == ERFOFF) {
2342                /* Enter D3 or ASPM after GPIO had been done. */
2343                if (ppsc->reg_rfps_level  & RT_RF_OFF_LEVL_ASPM)
2344                        RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM);
2345                else if (ppsc->reg_rfps_level  & RT_RF_OFF_LEVL_PCI_D3)
2346                        RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_PCI_D3);
2347                spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
2348                ppsc->rfchange_inprogress = false;
2349                spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
2350        } else {
2351                spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag);
2352                ppsc->rfchange_inprogress = false;
2353                spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag);
2354        }
2355        *valid = 1;
2356        return !ppsc->hwradiooff;
2357}
2358