linux/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/phy.c
<<
>>
Prefs
   1/******************************************************************************
   2 *
   3 * Copyright(c) 2009-2012  Realtek Corporation.
   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 * The full GNU General Public License is included in this distribution in the
  15 * file called LICENSE.
  16 *
  17 * Contact Information:
  18 * wlanfae <wlanfae@realtek.com>
  19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
  20 * Hsinchu 300, Taiwan.
  21 *
  22 * Larry Finger <Larry.Finger@lwfinger.net>
  23 *
  24 *****************************************************************************/
  25
  26#include "../wifi.h"
  27#include "../pci.h"
  28#include "../ps.h"
  29#include "../core.h"
  30#include "reg.h"
  31#include "def.h"
  32#include "phy.h"
  33#include "../rtl8192c/phy_common.h"
  34#include "rf.h"
  35#include "dm.h"
  36#include "../rtl8192c/dm_common.h"
  37#include "../rtl8192c/fw_common.h"
  38#include "table.h"
  39
  40u32 rtl92cu_phy_query_rf_reg(struct ieee80211_hw *hw,
  41                             enum radio_path rfpath, u32 regaddr, u32 bitmask)
  42{
  43        struct rtl_priv *rtlpriv = rtl_priv(hw);
  44        u32 original_value, readback_value, bitshift;
  45        struct rtl_phy *rtlphy = &(rtlpriv->phy);
  46
  47        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
  48                 "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
  49                 regaddr, rfpath, bitmask);
  50        if (rtlphy->rf_mode != RF_OP_BY_FW) {
  51                original_value = _rtl92c_phy_rf_serial_read(hw,
  52                                                            rfpath, regaddr);
  53        } else {
  54                original_value = _rtl92c_phy_fw_rf_serial_read(hw,
  55                                                               rfpath, regaddr);
  56        }
  57        bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
  58        readback_value = (original_value & bitmask) >> bitshift;
  59        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
  60                 "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n",
  61                 regaddr, rfpath, bitmask, original_value);
  62        return readback_value;
  63}
  64
  65void rtl92cu_phy_set_rf_reg(struct ieee80211_hw *hw,
  66                            enum radio_path rfpath,
  67                            u32 regaddr, u32 bitmask, u32 data)
  68{
  69        struct rtl_priv *rtlpriv = rtl_priv(hw);
  70        struct rtl_phy *rtlphy = &(rtlpriv->phy);
  71        u32 original_value, bitshift;
  72
  73        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
  74                 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
  75                 regaddr, bitmask, data, rfpath);
  76        if (rtlphy->rf_mode != RF_OP_BY_FW) {
  77                if (bitmask != RFREG_OFFSET_MASK) {
  78                        original_value = _rtl92c_phy_rf_serial_read(hw,
  79                                                                    rfpath,
  80                                                                    regaddr);
  81                        bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
  82                        data =
  83                            ((original_value & (~bitmask)) |
  84                             (data << bitshift));
  85                }
  86                _rtl92c_phy_rf_serial_write(hw, rfpath, regaddr, data);
  87        } else {
  88                if (bitmask != RFREG_OFFSET_MASK) {
  89                        original_value = _rtl92c_phy_fw_rf_serial_read(hw,
  90                                                                       rfpath,
  91                                                                       regaddr);
  92                        bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
  93                        data =
  94                            ((original_value & (~bitmask)) |
  95                             (data << bitshift));
  96                }
  97                _rtl92c_phy_fw_rf_serial_write(hw, rfpath, regaddr, data);
  98        }
  99        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
 100                 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
 101                 regaddr, bitmask, data, rfpath);
 102}
 103
 104bool rtl92cu_phy_mac_config(struct ieee80211_hw *hw)
 105{
 106        bool rtstatus;
 107
 108        rtstatus = _rtl92cu_phy_config_mac_with_headerfile(hw);
 109        return rtstatus;
 110}
 111
 112bool rtl92cu_phy_bb_config(struct ieee80211_hw *hw)
 113{
 114        bool rtstatus = true;
 115        struct rtl_priv *rtlpriv = rtl_priv(hw);
 116        u16 regval;
 117        u32 regval32;
 118        u8 b_reg_hwparafile = 1;
 119
 120        _rtl92c_phy_init_bb_rf_register_definition(hw);
 121        regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
 122        rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, regval | BIT(13) |
 123                       BIT(0) | BIT(1));
 124        rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x83);
 125        rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL + 1, 0xdb);
 126        rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB);
 127        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, FEN_USBA | FEN_USBD |
 128                       FEN_BB_GLB_RSTn | FEN_BBRSTB);
 129        regval32 = rtl_read_dword(rtlpriv, 0x87c);
 130        rtl_write_dword(rtlpriv, 0x87c, regval32 & (~BIT(31)));
 131        rtl_write_byte(rtlpriv, REG_LDOHCI12_CTRL, 0x0f);
 132        rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80);
 133        if (b_reg_hwparafile == 1)
 134                rtstatus = _rtl92c_phy_bb8192c_config_parafile(hw);
 135        return rtstatus;
 136}
 137
 138bool _rtl92cu_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
 139{
 140        struct rtl_priv *rtlpriv = rtl_priv(hw);
 141        struct rtl_phy *rtlphy = &(rtlpriv->phy);
 142        u32 i;
 143        u32 arraylength;
 144        u32 *ptrarray;
 145
 146        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl819XMACPHY_Array\n");
 147        arraylength =  rtlphy->hwparam_tables[MAC_REG].length ;
 148        ptrarray = rtlphy->hwparam_tables[MAC_REG].pdata;
 149        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Img:RTL8192CUMAC_2T_ARRAY\n");
 150        for (i = 0; i < arraylength; i = i + 2)
 151                rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]);
 152        return true;
 153}
 154
 155bool _rtl92cu_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
 156                                            u8 configtype)
 157{
 158        int i;
 159        u32 *phy_regarray_table;
 160        u32 *agctab_array_table;
 161        u16 phy_reg_arraylen, agctab_arraylen;
 162        struct rtl_priv *rtlpriv = rtl_priv(hw);
 163        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 164        struct rtl_phy *rtlphy = &(rtlpriv->phy);
 165
 166        if (IS_92C_SERIAL(rtlhal->version)) {
 167                agctab_arraylen = rtlphy->hwparam_tables[AGCTAB_2T].length;
 168                agctab_array_table =  rtlphy->hwparam_tables[AGCTAB_2T].pdata;
 169                phy_reg_arraylen = rtlphy->hwparam_tables[PHY_REG_2T].length;
 170                phy_regarray_table = rtlphy->hwparam_tables[PHY_REG_2T].pdata;
 171        } else {
 172                agctab_arraylen = rtlphy->hwparam_tables[AGCTAB_1T].length;
 173                agctab_array_table =  rtlphy->hwparam_tables[AGCTAB_1T].pdata;
 174                phy_reg_arraylen = rtlphy->hwparam_tables[PHY_REG_1T].length;
 175                phy_regarray_table = rtlphy->hwparam_tables[PHY_REG_1T].pdata;
 176        }
 177        if (configtype == BASEBAND_CONFIG_PHY_REG) {
 178                for (i = 0; i < phy_reg_arraylen; i = i + 2) {
 179                        rtl_addr_delay(phy_regarray_table[i]);
 180                        rtl_set_bbreg(hw, phy_regarray_table[i], MASKDWORD,
 181                                      phy_regarray_table[i + 1]);
 182                        udelay(1);
 183                        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 184                                 "The phy_regarray_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n",
 185                                 phy_regarray_table[i],
 186                                 phy_regarray_table[i + 1]);
 187                }
 188        } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
 189                for (i = 0; i < agctab_arraylen; i = i + 2) {
 190                        rtl_set_bbreg(hw, agctab_array_table[i], MASKDWORD,
 191                                      agctab_array_table[i + 1]);
 192                        udelay(1);
 193                        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 194                                 "The agctab_array_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n",
 195                                 agctab_array_table[i],
 196                                 agctab_array_table[i + 1]);
 197                }
 198        }
 199        return true;
 200}
 201
 202bool _rtl92cu_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
 203                                              u8 configtype)
 204{
 205        struct rtl_priv *rtlpriv = rtl_priv(hw);
 206        struct rtl_phy *rtlphy = &(rtlpriv->phy);
 207        int i;
 208        u32 *phy_regarray_table_pg;
 209        u16 phy_regarray_pg_len;
 210
 211        rtlphy->pwrgroup_cnt = 0;
 212        phy_regarray_pg_len = rtlphy->hwparam_tables[PHY_REG_PG].length;
 213        phy_regarray_table_pg = rtlphy->hwparam_tables[PHY_REG_PG].pdata;
 214        if (configtype == BASEBAND_CONFIG_PHY_REG) {
 215                for (i = 0; i < phy_regarray_pg_len; i = i + 3) {
 216                        rtl_addr_delay(phy_regarray_table_pg[i]);
 217                        _rtl92c_store_pwrIndex_diffrate_offset(hw,
 218                                                  phy_regarray_table_pg[i],
 219                                                  phy_regarray_table_pg[i + 1],
 220                                                  phy_regarray_table_pg[i + 2]);
 221                }
 222        } else {
 223                RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
 224                         "configtype != BaseBand_Config_PHY_REG\n");
 225        }
 226        return true;
 227}
 228
 229bool rtl92cu_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
 230                                          enum radio_path rfpath)
 231{
 232        int i;
 233        u32 *radioa_array_table;
 234        u32 *radiob_array_table;
 235        u16 radioa_arraylen, radiob_arraylen;
 236        struct rtl_priv *rtlpriv = rtl_priv(hw);
 237        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 238        struct rtl_phy *rtlphy = &(rtlpriv->phy);
 239
 240        if (IS_92C_SERIAL(rtlhal->version)) {
 241                radioa_arraylen = rtlphy->hwparam_tables[RADIOA_2T].length;
 242                radioa_array_table = rtlphy->hwparam_tables[RADIOA_2T].pdata;
 243                radiob_arraylen = rtlphy->hwparam_tables[RADIOB_2T].length;
 244                radiob_array_table = rtlphy->hwparam_tables[RADIOB_2T].pdata;
 245                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 246                         "Radio_A:RTL8192CURADIOA_2TARRAY\n");
 247                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 248                         "Radio_B:RTL8192CU_RADIOB_2TARRAY\n");
 249        } else {
 250                radioa_arraylen = rtlphy->hwparam_tables[RADIOA_1T].length;
 251                radioa_array_table = rtlphy->hwparam_tables[RADIOA_1T].pdata;
 252                radiob_arraylen = rtlphy->hwparam_tables[RADIOB_1T].length;
 253                radiob_array_table = rtlphy->hwparam_tables[RADIOB_1T].pdata;
 254                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 255                         "Radio_A:RTL8192CU_RADIOA_1TARRAY\n");
 256                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 257                         "Radio_B:RTL8192CU_RADIOB_1TARRAY\n");
 258        }
 259        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Radio No %x\n", rfpath);
 260        switch (rfpath) {
 261        case RF90_PATH_A:
 262                for (i = 0; i < radioa_arraylen; i = i + 2) {
 263                        rtl_rfreg_delay(hw, rfpath, radioa_array_table[i],
 264                                        RFREG_OFFSET_MASK,
 265                                        radioa_array_table[i + 1]);
 266                }
 267                break;
 268        case RF90_PATH_B:
 269                for (i = 0; i < radiob_arraylen; i = i + 2) {
 270                        rtl_rfreg_delay(hw, rfpath, radiob_array_table[i],
 271                                        RFREG_OFFSET_MASK,
 272                                        radiob_array_table[i + 1]);
 273                }
 274                break;
 275        case RF90_PATH_C:
 276        case RF90_PATH_D:
 277                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
 278                         "switch case %#x not processed\n", rfpath);
 279                break;
 280        default:
 281                break;
 282        }
 283        return true;
 284}
 285
 286void rtl92cu_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
 287{
 288        struct rtl_priv *rtlpriv = rtl_priv(hw);
 289        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 290        struct rtl_phy *rtlphy = &(rtlpriv->phy);
 291        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 292        u8 reg_bw_opmode;
 293        u8 reg_prsr_rsc;
 294
 295        RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n",
 296                 rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
 297                 "20MHz" : "40MHz");
 298        if (is_hal_stop(rtlhal)) {
 299                rtlphy->set_bwmode_inprogress = false;
 300                return;
 301        }
 302        reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
 303        reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
 304        switch (rtlphy->current_chan_bw) {
 305        case HT_CHANNEL_WIDTH_20:
 306                reg_bw_opmode |= BW_OPMODE_20MHZ;
 307                rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
 308                break;
 309        case HT_CHANNEL_WIDTH_20_40:
 310                reg_bw_opmode &= ~BW_OPMODE_20MHZ;
 311                rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
 312                reg_prsr_rsc =
 313                    (reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5);
 314                rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
 315                break;
 316        default:
 317                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
 318                         "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
 319                break;
 320        }
 321        switch (rtlphy->current_chan_bw) {
 322        case HT_CHANNEL_WIDTH_20:
 323                rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
 324                rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
 325                rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1);
 326                break;
 327        case HT_CHANNEL_WIDTH_20_40:
 328                rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
 329                rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
 330                rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
 331                              (mac->cur_40_prime_sc >> 1));
 332                rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
 333                rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0);
 334                rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
 335                              (mac->cur_40_prime_sc ==
 336                               HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
 337                break;
 338        default:
 339                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
 340                         "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
 341                break;
 342        }
 343        rtl92cu_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
 344        rtlphy->set_bwmode_inprogress = false;
 345        RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n");
 346}
 347
 348void rtl92cu_bb_block_on(struct ieee80211_hw *hw)
 349{
 350        struct rtl_priv *rtlpriv = rtl_priv(hw);
 351
 352        mutex_lock(&rtlpriv->io.bb_mutex);
 353        rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1);
 354        rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1);
 355        mutex_unlock(&rtlpriv->io.bb_mutex);
 356}
 357
 358void _rtl92cu_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
 359{
 360        u8 tmpreg;
 361        u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
 362        struct rtl_priv *rtlpriv = rtl_priv(hw);
 363
 364        tmpreg = rtl_read_byte(rtlpriv, 0xd03);
 365
 366        if ((tmpreg & 0x70) != 0)
 367                rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
 368        else
 369                rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
 370
 371        if ((tmpreg & 0x70) != 0) {
 372                rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS);
 373                if (is2t)
 374                        rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00,
 375                                                  MASK12BITS);
 376                rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS,
 377                              (rf_a_mode & 0x8FFFF) | 0x10000);
 378                if (is2t)
 379                        rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
 380                                      (rf_b_mode & 0x8FFFF) | 0x10000);
 381        }
 382        lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS);
 383        rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, lc_cal | 0x08000);
 384        mdelay(100);
 385        if ((tmpreg & 0x70) != 0) {
 386                rtl_write_byte(rtlpriv, 0xd03, tmpreg);
 387                rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode);
 388                if (is2t)
 389                        rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
 390                                      rf_b_mode);
 391        } else {
 392                rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
 393        }
 394}
 395
 396static bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw,
 397                                            enum rf_pwrstate rfpwr_state)
 398{
 399        struct rtl_priv *rtlpriv = rtl_priv(hw);
 400        struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
 401        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 402        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
 403        bool bresult = true;
 404        u8 i, queue_id;
 405        struct rtl8192_tx_ring *ring = NULL;
 406
 407        switch (rfpwr_state) {
 408        case ERFON:
 409                if ((ppsc->rfpwr_state == ERFOFF) &&
 410                    RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
 411                        bool rtstatus;
 412                        u32 InitializeCount = 0;
 413
 414                        do {
 415                                InitializeCount++;
 416                                RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
 417                                         "IPS Set eRf nic enable\n");
 418                                rtstatus = rtl_ps_enable_nic(hw);
 419                        } while (!rtstatus && (InitializeCount < 10));
 420                        RT_CLEAR_PS_LEVEL(ppsc,
 421                                          RT_RF_OFF_LEVL_HALT_NIC);
 422                } else {
 423                        RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
 424                                 "Set ERFON sleeped:%d ms\n",
 425                                 jiffies_to_msecs(jiffies -
 426                                                  ppsc->last_sleep_jiffies));
 427                        ppsc->last_awake_jiffies = jiffies;
 428                        rtl92ce_phy_set_rf_on(hw);
 429                }
 430                if (mac->link_state == MAC80211_LINKED) {
 431                        rtlpriv->cfg->ops->led_control(hw,
 432                                                       LED_CTL_LINK);
 433                } else {
 434                        rtlpriv->cfg->ops->led_control(hw,
 435                                                       LED_CTL_NO_LINK);
 436                }
 437                break;
 438        case ERFOFF:
 439                for (queue_id = 0, i = 0;
 440                     queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
 441                        ring = &pcipriv->dev.tx_ring[queue_id];
 442                        if (skb_queue_len(&ring->queue) == 0 ||
 443                                queue_id == BEACON_QUEUE) {
 444                                queue_id++;
 445                                continue;
 446                        } else {
 447                                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
 448                                         "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
 449                                         i + 1,
 450                                         queue_id,
 451                                         skb_queue_len(&ring->queue));
 452                                udelay(10);
 453                                i++;
 454                        }
 455                        if (i >= MAX_DOZE_WAITING_TIMES_9x) {
 456                                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
 457                                         "ERFOFF: %d times TcbBusyQueue[%d] = %d !\n",
 458                                         MAX_DOZE_WAITING_TIMES_9x,
 459                                         queue_id,
 460                                         skb_queue_len(&ring->queue));
 461                                break;
 462                        }
 463                }
 464                if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
 465                        RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
 466                                 "IPS Set eRf nic disable\n");
 467                        rtl_ps_disable_nic(hw);
 468                        RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
 469                } else {
 470                        if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
 471                                rtlpriv->cfg->ops->led_control(hw,
 472                                                         LED_CTL_NO_LINK);
 473                        } else {
 474                                rtlpriv->cfg->ops->led_control(hw,
 475                                                         LED_CTL_POWER_OFF);
 476                        }
 477                }
 478                break;
 479        case ERFSLEEP:
 480                if (ppsc->rfpwr_state == ERFOFF)
 481                        return false;
 482                for (queue_id = 0, i = 0;
 483                     queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
 484                        ring = &pcipriv->dev.tx_ring[queue_id];
 485                        if (skb_queue_len(&ring->queue) == 0) {
 486                                queue_id++;
 487                                continue;
 488                        } else {
 489                                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
 490                                         "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
 491                                         i + 1, queue_id,
 492                                         skb_queue_len(&ring->queue));
 493                                udelay(10);
 494                                i++;
 495                        }
 496                        if (i >= MAX_DOZE_WAITING_TIMES_9x) {
 497                                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
 498                                         "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
 499                                         MAX_DOZE_WAITING_TIMES_9x,
 500                                         queue_id,
 501                                         skb_queue_len(&ring->queue));
 502                                break;
 503                        }
 504                }
 505                RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
 506                         "Set ERFSLEEP awaked:%d ms\n",
 507                         jiffies_to_msecs(jiffies - ppsc->last_awake_jiffies));
 508                ppsc->last_sleep_jiffies = jiffies;
 509                _rtl92c_phy_set_rf_sleep(hw);
 510                break;
 511        default:
 512                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
 513                         "switch case %#x not processed\n", rfpwr_state);
 514                bresult = false;
 515                break;
 516        }
 517        if (bresult)
 518                ppsc->rfpwr_state = rfpwr_state;
 519        return bresult;
 520}
 521
 522bool rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw,
 523                                    enum rf_pwrstate rfpwr_state)
 524{
 525        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
 526        bool bresult = false;
 527
 528        if (rfpwr_state == ppsc->rfpwr_state)
 529                return bresult;
 530        bresult = _rtl92cu_phy_set_rf_power_state(hw, rfpwr_state);
 531        return bresult;
 532}
 533