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