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                pr_err("switch case %#x not processed\n", rfpath);
 278                break;
 279        default:
 280                break;
 281        }
 282        return true;
 283}
 284
 285void rtl92cu_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
 286{
 287        struct rtl_priv *rtlpriv = rtl_priv(hw);
 288        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 289        struct rtl_phy *rtlphy = &(rtlpriv->phy);
 290        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 291        u8 reg_bw_opmode;
 292        u8 reg_prsr_rsc;
 293
 294        RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n",
 295                 rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
 296                 "20MHz" : "40MHz");
 297        if (is_hal_stop(rtlhal)) {
 298                rtlphy->set_bwmode_inprogress = false;
 299                return;
 300        }
 301        reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
 302        reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
 303        switch (rtlphy->current_chan_bw) {
 304        case HT_CHANNEL_WIDTH_20:
 305                reg_bw_opmode |= BW_OPMODE_20MHZ;
 306                rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
 307                break;
 308        case HT_CHANNEL_WIDTH_20_40:
 309                reg_bw_opmode &= ~BW_OPMODE_20MHZ;
 310                rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
 311                reg_prsr_rsc =
 312                    (reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5);
 313                rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
 314                break;
 315        default:
 316                pr_err("unknown bandwidth: %#X\n",
 317                       rtlphy->current_chan_bw);
 318                break;
 319        }
 320        switch (rtlphy->current_chan_bw) {
 321        case HT_CHANNEL_WIDTH_20:
 322                rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
 323                rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
 324                rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1);
 325                break;
 326        case HT_CHANNEL_WIDTH_20_40:
 327                rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
 328                rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
 329                rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
 330                              (mac->cur_40_prime_sc >> 1));
 331                rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
 332                rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0);
 333                rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
 334                              (mac->cur_40_prime_sc ==
 335                               HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
 336                break;
 337        default:
 338                pr_err("unknown bandwidth: %#X\n",
 339                       rtlphy->current_chan_bw);
 340                break;
 341        }
 342        rtl92cu_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
 343        rtlphy->set_bwmode_inprogress = false;
 344        RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n");
 345}
 346
 347void rtl92cu_bb_block_on(struct ieee80211_hw *hw)
 348{
 349        struct rtl_priv *rtlpriv = rtl_priv(hw);
 350
 351        mutex_lock(&rtlpriv->io.bb_mutex);
 352        rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1);
 353        rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1);
 354        mutex_unlock(&rtlpriv->io.bb_mutex);
 355}
 356
 357void _rtl92cu_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
 358{
 359        u8 tmpreg;
 360        u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
 361        struct rtl_priv *rtlpriv = rtl_priv(hw);
 362
 363        tmpreg = rtl_read_byte(rtlpriv, 0xd03);
 364
 365        if ((tmpreg & 0x70) != 0)
 366                rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
 367        else
 368                rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
 369
 370        if ((tmpreg & 0x70) != 0) {
 371                rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS);
 372                if (is2t)
 373                        rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00,
 374                                                  MASK12BITS);
 375                rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS,
 376                              (rf_a_mode & 0x8FFFF) | 0x10000);
 377                if (is2t)
 378                        rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
 379                                      (rf_b_mode & 0x8FFFF) | 0x10000);
 380        }
 381        lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS);
 382        rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, lc_cal | 0x08000);
 383        mdelay(100);
 384        if ((tmpreg & 0x70) != 0) {
 385                rtl_write_byte(rtlpriv, 0xd03, tmpreg);
 386                rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode);
 387                if (is2t)
 388                        rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
 389                                      rf_b_mode);
 390        } else {
 391                rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
 392        }
 393}
 394
 395static bool _rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw,
 396                                            enum rf_pwrstate rfpwr_state)
 397{
 398        struct rtl_priv *rtlpriv = rtl_priv(hw);
 399        struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
 400        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 401        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
 402        bool bresult = true;
 403        u8 i, queue_id;
 404        struct rtl8192_tx_ring *ring = NULL;
 405
 406        switch (rfpwr_state) {
 407        case ERFON:
 408                if ((ppsc->rfpwr_state == ERFOFF) &&
 409                    RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
 410                        bool rtstatus;
 411                        u32 InitializeCount = 0;
 412
 413                        do {
 414                                InitializeCount++;
 415                                RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
 416                                         "IPS Set eRf nic enable\n");
 417                                rtstatus = rtl_ps_enable_nic(hw);
 418                        } while (!rtstatus && (InitializeCount < 10));
 419                        RT_CLEAR_PS_LEVEL(ppsc,
 420                                          RT_RF_OFF_LEVL_HALT_NIC);
 421                } else {
 422                        RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
 423                                 "Set ERFON sleeped:%d ms\n",
 424                                 jiffies_to_msecs(jiffies -
 425                                                  ppsc->last_sleep_jiffies));
 426                        ppsc->last_awake_jiffies = jiffies;
 427                        rtl92ce_phy_set_rf_on(hw);
 428                }
 429                if (mac->link_state == MAC80211_LINKED) {
 430                        rtlpriv->cfg->ops->led_control(hw,
 431                                                       LED_CTL_LINK);
 432                } else {
 433                        rtlpriv->cfg->ops->led_control(hw,
 434                                                       LED_CTL_NO_LINK);
 435                }
 436                break;
 437        case ERFOFF:
 438                for (queue_id = 0, i = 0;
 439                     queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
 440                        ring = &pcipriv->dev.tx_ring[queue_id];
 441                        if (skb_queue_len(&ring->queue) == 0 ||
 442                                queue_id == BEACON_QUEUE) {
 443                                queue_id++;
 444                                continue;
 445                        } else {
 446                                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
 447                                         "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
 448                                         i + 1,
 449                                         queue_id,
 450                                         skb_queue_len(&ring->queue));
 451                                udelay(10);
 452                                i++;
 453                        }
 454                        if (i >= MAX_DOZE_WAITING_TIMES_9x) {
 455                                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
 456                                         "ERFOFF: %d times TcbBusyQueue[%d] = %d !\n",
 457                                         MAX_DOZE_WAITING_TIMES_9x,
 458                                         queue_id,
 459                                         skb_queue_len(&ring->queue));
 460                                break;
 461                        }
 462                }
 463                if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
 464                        RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
 465                                 "IPS Set eRf nic disable\n");
 466                        rtl_ps_disable_nic(hw);
 467                        RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
 468                } else {
 469                        if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
 470                                rtlpriv->cfg->ops->led_control(hw,
 471                                                         LED_CTL_NO_LINK);
 472                        } else {
 473                                rtlpriv->cfg->ops->led_control(hw,
 474                                                         LED_CTL_POWER_OFF);
 475                        }
 476                }
 477                break;
 478        case ERFSLEEP:
 479                if (ppsc->rfpwr_state == ERFOFF)
 480                        return false;
 481                for (queue_id = 0, i = 0;
 482                     queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
 483                        ring = &pcipriv->dev.tx_ring[queue_id];
 484                        if (skb_queue_len(&ring->queue) == 0) {
 485                                queue_id++;
 486                                continue;
 487                        } else {
 488                                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
 489                                         "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
 490                                         i + 1, queue_id,
 491                                         skb_queue_len(&ring->queue));
 492                                udelay(10);
 493                                i++;
 494                        }
 495                        if (i >= MAX_DOZE_WAITING_TIMES_9x) {
 496                                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
 497                                         "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
 498                                         MAX_DOZE_WAITING_TIMES_9x,
 499                                         queue_id,
 500                                         skb_queue_len(&ring->queue));
 501                                break;
 502                        }
 503                }
 504                RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
 505                         "Set ERFSLEEP awaked:%d ms\n",
 506                         jiffies_to_msecs(jiffies - ppsc->last_awake_jiffies));
 507                ppsc->last_sleep_jiffies = jiffies;
 508                _rtl92c_phy_set_rf_sleep(hw);
 509                break;
 510        default:
 511                pr_err("switch case %#x not processed\n",
 512                       rfpwr_state);
 513                bresult = false;
 514                break;
 515        }
 516        if (bresult)
 517                ppsc->rfpwr_state = rfpwr_state;
 518        return bresult;
 519}
 520
 521bool rtl92cu_phy_set_rf_power_state(struct ieee80211_hw *hw,
 522                                    enum rf_pwrstate rfpwr_state)
 523{
 524        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
 525        bool bresult = false;
 526
 527        if (rfpwr_state == ppsc->rfpwr_state)
 528                return bresult;
 529        bresult = _rtl92cu_phy_set_rf_power_state(hw, rfpwr_state);
 530        return bresult;
 531}
 532