linux/drivers/net/wireless/realtek/rtlwifi/rtl8192ee/phy.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/* Copyright(c) 2009-2014  Realtek Corporation.*/
   3
   4#include "../wifi.h"
   5#include "../pci.h"
   6#include "../ps.h"
   7#include "reg.h"
   8#include "def.h"
   9#include "phy.h"
  10#include "rf.h"
  11#include "dm.h"
  12#include "table.h"
  13
  14static u32 _rtl92ee_phy_rf_serial_read(struct ieee80211_hw *hw,
  15                                       enum radio_path rfpath, u32 offset);
  16static void _rtl92ee_phy_rf_serial_write(struct ieee80211_hw *hw,
  17                                         enum radio_path rfpath, u32 offset,
  18                                         u32 data);
  19static u32 _rtl92ee_phy_calculate_bit_shift(u32 bitmask);
  20static bool _rtl92ee_phy_bb8192ee_config_parafile(struct ieee80211_hw *hw);
  21static bool _rtl92ee_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);
  22static bool phy_config_bb_with_hdr_file(struct ieee80211_hw *hw,
  23                                        u8 configtype);
  24static bool phy_config_bb_with_pghdrfile(struct ieee80211_hw *hw,
  25                                         u8 configtype);
  26static void phy_init_bb_rf_register_def(struct ieee80211_hw *hw);
  27static bool _rtl92ee_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
  28                                              u32 cmdtableidx, u32 cmdtablesz,
  29                                              enum swchnlcmd_id cmdid,
  30                                              u32 para1, u32 para2,
  31                                              u32 msdelay);
  32static bool _rtl92ee_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
  33                                              u8 channel, u8 *stage,
  34                                              u8 *step, u32 *delay);
  35static long _rtl92ee_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
  36                                          enum wireless_mode wirelessmode,
  37                                          u8 txpwridx);
  38static void rtl92ee_phy_set_rf_on(struct ieee80211_hw *hw);
  39static void rtl92ee_phy_set_io(struct ieee80211_hw *hw);
  40
  41u32 rtl92ee_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask)
  42{
  43        struct rtl_priv *rtlpriv = rtl_priv(hw);
  44        u32 returnvalue, originalvalue, bitshift;
  45
  46        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
  47                 "regaddr(%#x), bitmask(%#x)\n", regaddr, bitmask);
  48        originalvalue = rtl_read_dword(rtlpriv, regaddr);
  49        bitshift = _rtl92ee_phy_calculate_bit_shift(bitmask);
  50        returnvalue = (originalvalue & bitmask) >> bitshift;
  51
  52        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
  53                 "BBR MASK=0x%x Addr[0x%x]=0x%x\n",
  54                  bitmask, regaddr, originalvalue);
  55
  56        return returnvalue;
  57}
  58
  59void rtl92ee_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr,
  60                            u32 bitmask, u32 data)
  61{
  62        struct rtl_priv *rtlpriv = rtl_priv(hw);
  63        u32 originalvalue, bitshift;
  64
  65        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
  66                 "regaddr(%#x), bitmask(%#x), data(%#x)\n",
  67                  regaddr, bitmask, data);
  68
  69        if (bitmask != MASKDWORD) {
  70                originalvalue = rtl_read_dword(rtlpriv, regaddr);
  71                bitshift = _rtl92ee_phy_calculate_bit_shift(bitmask);
  72                data = ((originalvalue & (~bitmask)) | (data << bitshift));
  73        }
  74
  75        rtl_write_dword(rtlpriv, regaddr, data);
  76
  77        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
  78                 "regaddr(%#x), bitmask(%#x), data(%#x)\n",
  79                  regaddr, bitmask, data);
  80}
  81
  82u32 rtl92ee_phy_query_rf_reg(struct ieee80211_hw *hw,
  83                             enum radio_path rfpath, u32 regaddr, u32 bitmask)
  84{
  85        struct rtl_priv *rtlpriv = rtl_priv(hw);
  86        u32 original_value, readback_value, bitshift;
  87        unsigned long flags;
  88
  89        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
  90                 "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
  91                  regaddr, rfpath, bitmask);
  92
  93        spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
  94
  95        original_value = _rtl92ee_phy_rf_serial_read(hw , rfpath, regaddr);
  96        bitshift = _rtl92ee_phy_calculate_bit_shift(bitmask);
  97        readback_value = (original_value & bitmask) >> bitshift;
  98
  99        spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
 100
 101        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
 102                 "regaddr(%#x),rfpath(%#x),bitmask(%#x),original_value(%#x)\n",
 103                  regaddr, rfpath, bitmask, original_value);
 104
 105        return readback_value;
 106}
 107
 108void rtl92ee_phy_set_rf_reg(struct ieee80211_hw *hw,
 109                            enum radio_path rfpath,
 110                            u32 addr, u32 bitmask, u32 data)
 111{
 112        struct rtl_priv *rtlpriv = rtl_priv(hw);
 113        u32 original_value, bitshift;
 114        unsigned long flags;
 115
 116        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
 117                 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
 118                  addr, bitmask, data, rfpath);
 119
 120        spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
 121
 122        if (bitmask != RFREG_OFFSET_MASK) {
 123                original_value = _rtl92ee_phy_rf_serial_read(hw, rfpath, addr);
 124                bitshift = _rtl92ee_phy_calculate_bit_shift(bitmask);
 125                data = (original_value & (~bitmask)) | (data << bitshift);
 126        }
 127
 128        _rtl92ee_phy_rf_serial_write(hw, rfpath, addr, data);
 129
 130        spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
 131
 132        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
 133                 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
 134                  addr, bitmask, data, rfpath);
 135}
 136
 137static u32 _rtl92ee_phy_rf_serial_read(struct ieee80211_hw *hw,
 138                                       enum radio_path rfpath, u32 offset)
 139{
 140        struct rtl_priv *rtlpriv = rtl_priv(hw);
 141        struct rtl_phy *rtlphy = &rtlpriv->phy;
 142        struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
 143        u32 newoffset;
 144        u32 tmplong, tmplong2;
 145        u8 rfpi_enable = 0;
 146        u32 retvalue;
 147
 148        offset &= 0xff;
 149        newoffset = offset;
 150        if (RT_CANNOT_IO(hw)) {
 151                pr_err("return all one\n");
 152                return 0xFFFFFFFF;
 153        }
 154        tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD);
 155        if (rfpath == RF90_PATH_A)
 156                tmplong2 = tmplong;
 157        else
 158                tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD);
 159        tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) |
 160                   (newoffset << 23) | BLSSIREADEDGE;
 161        rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,
 162                      tmplong & (~BLSSIREADEDGE));
 163        mdelay(1);
 164        rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2);
 165        mdelay(2);
 166        if (rfpath == RF90_PATH_A)
 167                rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1,
 168                                                BIT(8));
 169        else if (rfpath == RF90_PATH_B)
 170                rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1,
 171                                                BIT(8));
 172        if (rfpi_enable)
 173                retvalue = rtl_get_bbreg(hw, pphyreg->rf_rbpi,
 174                                         BLSSIREADBACKDATA);
 175        else
 176                retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb,
 177                                         BLSSIREADBACKDATA);
 178        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
 179                 "RFR-%d Addr[0x%x]=0x%x\n",
 180                  rfpath, pphyreg->rf_rb, retvalue);
 181        return retvalue;
 182}
 183
 184static void _rtl92ee_phy_rf_serial_write(struct ieee80211_hw *hw,
 185                                         enum radio_path rfpath, u32 offset,
 186                                         u32 data)
 187{
 188        u32 data_and_addr;
 189        u32 newoffset;
 190        struct rtl_priv *rtlpriv = rtl_priv(hw);
 191        struct rtl_phy *rtlphy = &rtlpriv->phy;
 192        struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
 193
 194        if (RT_CANNOT_IO(hw)) {
 195                pr_err("stop\n");
 196                return;
 197        }
 198        offset &= 0xff;
 199        newoffset = offset;
 200        data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff;
 201        rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr);
 202        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
 203                 "RFW-%d Addr[0x%x]=0x%x\n", rfpath,
 204                 pphyreg->rf3wire_offset, data_and_addr);
 205}
 206
 207static u32 _rtl92ee_phy_calculate_bit_shift(u32 bitmask)
 208{
 209        u32 i;
 210
 211        for (i = 0; i <= 31; i++) {
 212                if (((bitmask >> i) & 0x1) == 1)
 213                        break;
 214        }
 215        return i;
 216}
 217
 218bool rtl92ee_phy_mac_config(struct ieee80211_hw *hw)
 219{
 220        return _rtl92ee_phy_config_mac_with_headerfile(hw);
 221}
 222
 223bool rtl92ee_phy_bb_config(struct ieee80211_hw *hw)
 224{
 225        struct rtl_priv *rtlpriv = rtl_priv(hw);
 226        bool rtstatus = true;
 227        u16 regval;
 228        u32 tmp;
 229        u8 crystal_cap;
 230
 231        phy_init_bb_rf_register_def(hw);
 232        regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
 233        rtl_write_word(rtlpriv, REG_SYS_FUNC_EN,
 234                       regval | BIT(13) | BIT(0) | BIT(1));
 235
 236        rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB);
 237        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN,
 238                       FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE |
 239                       FEN_BB_GLB_RSTN | FEN_BBRSTB);
 240
 241        rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80);
 242
 243        tmp = rtl_read_dword(rtlpriv, 0x4c);
 244        rtl_write_dword(rtlpriv, 0x4c, tmp | BIT(23));
 245
 246        rtstatus = _rtl92ee_phy_bb8192ee_config_parafile(hw);
 247
 248        crystal_cap = rtlpriv->efuse.eeprom_crystalcap & 0x3F;
 249        rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000,
 250                      (crystal_cap | (crystal_cap << 6)));
 251        return rtstatus;
 252}
 253
 254bool rtl92ee_phy_rf_config(struct ieee80211_hw *hw)
 255{
 256        return rtl92ee_phy_rf6052_config(hw);
 257}
 258
 259static bool _check_condition(struct ieee80211_hw *hw,
 260                             const u32  condition)
 261{
 262        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 263        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 264        u32 _board = rtlefuse->board_type; /*need efuse define*/
 265        u32 _interface = rtlhal->interface;
 266        u32 _platform = 0x08;/*SupportPlatform */
 267        u32 cond = condition;
 268
 269        if (condition == 0xCDCDCDCD)
 270                return true;
 271
 272        cond = condition & 0xFF;
 273        if ((_board != cond) && (cond != 0xFF))
 274                return false;
 275
 276        cond = condition & 0xFF00;
 277        cond = cond >> 8;
 278        if ((_interface & cond) == 0 && cond != 0x07)
 279                return false;
 280
 281        cond = condition & 0xFF0000;
 282        cond = cond >> 16;
 283        if ((_platform & cond) == 0 && cond != 0x0F)
 284                return false;
 285
 286        return true;
 287}
 288
 289static void _rtl92ee_config_rf_reg(struct ieee80211_hw *hw, u32 addr, u32 data,
 290                                   enum radio_path rfpath, u32 regaddr)
 291{
 292        if (addr == 0xfe || addr == 0xffe) {
 293                mdelay(50);
 294        } else {
 295                rtl_set_rfreg(hw, rfpath, regaddr, RFREG_OFFSET_MASK, data);
 296                udelay(1);
 297
 298                if (addr == 0xb6) {
 299                        u32 getvalue;
 300                        u8 count = 0;
 301
 302                        getvalue = rtl_get_rfreg(hw, rfpath, addr, MASKDWORD);
 303                        udelay(1);
 304
 305                        while ((getvalue >> 8) != (data >> 8)) {
 306                                count++;
 307                                rtl_set_rfreg(hw, rfpath, regaddr,
 308                                              RFREG_OFFSET_MASK, data);
 309                                udelay(1);
 310                                getvalue = rtl_get_rfreg(hw, rfpath, addr,
 311                                                         MASKDWORD);
 312                                if (count > 5)
 313                                        break;
 314                        }
 315                }
 316
 317                if (addr == 0xb2) {
 318                        u32 getvalue;
 319                        u8 count = 0;
 320
 321                        getvalue = rtl_get_rfreg(hw, rfpath, addr, MASKDWORD);
 322                        udelay(1);
 323
 324                        while (getvalue != data) {
 325                                count++;
 326                                rtl_set_rfreg(hw, rfpath, regaddr,
 327                                              RFREG_OFFSET_MASK, data);
 328                                udelay(1);
 329                                rtl_set_rfreg(hw, rfpath, 0x18,
 330                                              RFREG_OFFSET_MASK, 0x0fc07);
 331                                udelay(1);
 332                                getvalue = rtl_get_rfreg(hw, rfpath, addr,
 333                                                         MASKDWORD);
 334                                if (count > 5)
 335                                        break;
 336                        }
 337                }
 338        }
 339}
 340
 341static void _rtl92ee_config_rf_radio_a(struct ieee80211_hw *hw,
 342                                       u32 addr, u32 data)
 343{
 344        u32 content = 0x1000; /*RF Content: radio_a_txt*/
 345        u32 maskforphyset = (u32)(content & 0xE000);
 346
 347        _rtl92ee_config_rf_reg(hw, addr, data, RF90_PATH_A,
 348                               addr | maskforphyset);
 349}
 350
 351static void _rtl92ee_config_rf_radio_b(struct ieee80211_hw *hw,
 352                                       u32 addr, u32 data)
 353{
 354        u32 content = 0x1001; /*RF Content: radio_b_txt*/
 355        u32 maskforphyset = (u32)(content & 0xE000);
 356
 357        _rtl92ee_config_rf_reg(hw, addr, data, RF90_PATH_B,
 358                               addr | maskforphyset);
 359}
 360
 361static void _rtl92ee_config_bb_reg(struct ieee80211_hw *hw,
 362                                   u32 addr, u32 data)
 363{
 364        if (addr == 0xfe)
 365                mdelay(50);
 366        else if (addr == 0xfd)
 367                mdelay(5);
 368        else if (addr == 0xfc)
 369                mdelay(1);
 370        else if (addr == 0xfb)
 371                udelay(50);
 372        else if (addr == 0xfa)
 373                udelay(5);
 374        else if (addr == 0xf9)
 375                udelay(1);
 376        else
 377                rtl_set_bbreg(hw, addr, MASKDWORD , data);
 378
 379        udelay(1);
 380}
 381
 382static void _rtl92ee_phy_init_tx_power_by_rate(struct ieee80211_hw *hw)
 383{
 384        struct rtl_priv *rtlpriv = rtl_priv(hw);
 385        struct rtl_phy *rtlphy = &rtlpriv->phy;
 386
 387        u8 band = BAND_ON_2_4G, rf = 0, txnum = 0, sec = 0;
 388
 389        for (; band <= BAND_ON_5G; ++band)
 390                for (; rf < TX_PWR_BY_RATE_NUM_RF; ++rf)
 391                        for (; txnum < TX_PWR_BY_RATE_NUM_RF; ++txnum)
 392                                for (; sec < TX_PWR_BY_RATE_NUM_SECTION; ++sec)
 393                                        rtlphy->tx_power_by_rate_offset
 394                                             [band][rf][txnum][sec] = 0;
 395}
 396
 397static void _rtl92ee_phy_set_txpower_by_rate_base(struct ieee80211_hw *hw,
 398                                                  u8 band, u8 path,
 399                                                  u8 rate_section, u8 txnum,
 400                                                  u8 value)
 401{
 402        struct rtl_priv *rtlpriv = rtl_priv(hw);
 403        struct rtl_phy *rtlphy = &rtlpriv->phy;
 404
 405        if (path > RF90_PATH_D) {
 406                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 407                         "Invalid Rf Path %d\n", path);
 408                return;
 409        }
 410
 411        if (band == BAND_ON_2_4G) {
 412                switch (rate_section) {
 413                case CCK:
 414                        rtlphy->txpwr_by_rate_base_24g[path][txnum][0] = value;
 415                        break;
 416                case OFDM:
 417                        rtlphy->txpwr_by_rate_base_24g[path][txnum][1] = value;
 418                        break;
 419                case HT_MCS0_MCS7:
 420                        rtlphy->txpwr_by_rate_base_24g[path][txnum][2] = value;
 421                        break;
 422                case HT_MCS8_MCS15:
 423                        rtlphy->txpwr_by_rate_base_24g[path][txnum][3] = value;
 424                        break;
 425                default:
 426                        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 427                                 "Invalid RateSection %d in 2.4G,Rf %d,%dTx\n",
 428                                  rate_section, path, txnum);
 429                        break;
 430                }
 431        } else {
 432                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 433                         "Invalid Band %d\n", band);
 434        }
 435}
 436
 437static u8 _rtl92ee_phy_get_txpower_by_rate_base(struct ieee80211_hw *hw,
 438                                                u8 band, u8 path, u8 txnum,
 439                                                u8 rate_section)
 440{
 441        struct rtl_priv *rtlpriv = rtl_priv(hw);
 442        struct rtl_phy *rtlphy = &rtlpriv->phy;
 443        u8 value = 0;
 444
 445        if (path > RF90_PATH_D) {
 446                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 447                         "Invalid Rf Path %d\n", path);
 448                return 0;
 449        }
 450
 451        if (band == BAND_ON_2_4G) {
 452                switch (rate_section) {
 453                case CCK:
 454                        value = rtlphy->txpwr_by_rate_base_24g[path][txnum][0];
 455                        break;
 456                case OFDM:
 457                        value = rtlphy->txpwr_by_rate_base_24g[path][txnum][1];
 458                        break;
 459                case HT_MCS0_MCS7:
 460                        value = rtlphy->txpwr_by_rate_base_24g[path][txnum][2];
 461                        break;
 462                case HT_MCS8_MCS15:
 463                        value = rtlphy->txpwr_by_rate_base_24g[path][txnum][3];
 464                        break;
 465                default:
 466                        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 467                                 "Invalid RateSection %d in 2.4G,Rf %d,%dTx\n",
 468                                  rate_section, path, txnum);
 469                        break;
 470                }
 471        } else {
 472                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 473                         "Invalid Band %d()\n", band);
 474        }
 475        return value;
 476}
 477
 478static void _rtl92ee_phy_store_txpower_by_rate_base(struct ieee80211_hw *hw)
 479{
 480        struct rtl_priv *rtlpriv = rtl_priv(hw);
 481        struct rtl_phy *rtlphy = &rtlpriv->phy;
 482        u16 raw = 0;
 483        u8 base = 0, path = 0;
 484
 485        for (path = RF90_PATH_A; path <= RF90_PATH_B; ++path) {
 486                if (path == RF90_PATH_A) {
 487                        raw = (u16)(rtlphy->tx_power_by_rate_offset
 488                                    [BAND_ON_2_4G][path][RF_1TX][3] >> 24) &
 489                                    0xFF;
 490                        base = (raw >> 4) * 10 + (raw & 0xF);
 491                        _rtl92ee_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G,
 492                                                              path, CCK, RF_1TX,
 493                                                              base);
 494                } else if (path == RF90_PATH_B) {
 495                        raw = (u16)(rtlphy->tx_power_by_rate_offset
 496                                    [BAND_ON_2_4G][path][RF_1TX][3] >> 0) &
 497                                    0xFF;
 498                        base = (raw >> 4) * 10 + (raw & 0xF);
 499                        _rtl92ee_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G,
 500                                                              path, CCK, RF_1TX,
 501                                                              base);
 502                }
 503                raw = (u16)(rtlphy->tx_power_by_rate_offset
 504                            [BAND_ON_2_4G][path][RF_1TX][1] >> 24) & 0xFF;
 505                base = (raw >> 4) * 10 + (raw & 0xF);
 506                _rtl92ee_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path,
 507                                                      OFDM, RF_1TX, base);
 508
 509                raw = (u16)(rtlphy->tx_power_by_rate_offset
 510                            [BAND_ON_2_4G][path][RF_1TX][5] >> 24) & 0xFF;
 511                base = (raw >> 4) * 10 + (raw & 0xF);
 512                _rtl92ee_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path,
 513                                                      HT_MCS0_MCS7, RF_1TX,
 514                                                      base);
 515
 516                raw = (u16)(rtlphy->tx_power_by_rate_offset
 517                            [BAND_ON_2_4G][path][RF_2TX][7] >> 24) & 0xFF;
 518                base = (raw >> 4) * 10 + (raw & 0xF);
 519                _rtl92ee_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path,
 520                                                      HT_MCS8_MCS15, RF_2TX,
 521                                                      base);
 522        }
 523}
 524
 525static void _phy_convert_txpower_dbm_to_relative_value(u32 *data, u8 start,
 526                                                       u8 end, u8 base)
 527{
 528        s8 i = 0;
 529        u8 tmp = 0;
 530        u32 temp_data = 0;
 531
 532        for (i = 3; i >= 0; --i) {
 533                if (i >= start && i <= end) {
 534                        /* Get the exact value */
 535                        tmp = (u8)(*data >> (i * 8)) & 0xF;
 536                        tmp += ((u8)((*data >> (i * 8 + 4)) & 0xF)) * 10;
 537
 538                        /* Change the value to a relative value */
 539                        tmp = (tmp > base) ? tmp - base : base - tmp;
 540                } else {
 541                        tmp = (u8)(*data >> (i * 8)) & 0xFF;
 542                }
 543                temp_data <<= 8;
 544                temp_data |= tmp;
 545        }
 546        *data = temp_data;
 547}
 548
 549static void phy_convert_txpwr_dbm_to_rel_val(struct ieee80211_hw *hw)
 550{
 551        struct rtl_priv *rtlpriv = rtl_priv(hw);
 552        struct rtl_phy *rtlphy = &rtlpriv->phy;
 553        u8 base = 0, rf = 0, band = BAND_ON_2_4G;
 554
 555        for (rf = RF90_PATH_A; rf <= RF90_PATH_B; ++rf) {
 556                if (rf == RF90_PATH_A) {
 557                        base = _rtl92ee_phy_get_txpower_by_rate_base(hw, band,
 558                                                                     rf, RF_1TX,
 559                                                                     CCK);
 560                        _phy_convert_txpower_dbm_to_relative_value(
 561                                &rtlphy->tx_power_by_rate_offset
 562                                [band][rf][RF_1TX][2],
 563                                1, 1, base);
 564                        _phy_convert_txpower_dbm_to_relative_value(
 565                                &rtlphy->tx_power_by_rate_offset
 566                                [band][rf][RF_1TX][3],
 567                                1, 3, base);
 568                } else if (rf == RF90_PATH_B) {
 569                        base = _rtl92ee_phy_get_txpower_by_rate_base(hw, band,
 570                                                                     rf, RF_1TX,
 571                                                                     CCK);
 572                        _phy_convert_txpower_dbm_to_relative_value(
 573                                &rtlphy->tx_power_by_rate_offset
 574                                [band][rf][RF_1TX][3],
 575                                0, 0, base);
 576                        _phy_convert_txpower_dbm_to_relative_value(
 577                                &rtlphy->tx_power_by_rate_offset
 578                                [band][rf][RF_1TX][2],
 579                                1, 3, base);
 580                }
 581                base = _rtl92ee_phy_get_txpower_by_rate_base(hw, band, rf,
 582                                                             RF_1TX, OFDM);
 583                _phy_convert_txpower_dbm_to_relative_value(
 584                        &rtlphy->tx_power_by_rate_offset[band][rf][RF_1TX][0],
 585                        0, 3, base);
 586                _phy_convert_txpower_dbm_to_relative_value(
 587                        &rtlphy->tx_power_by_rate_offset[band][rf][RF_1TX][1],
 588                        0, 3, base);
 589
 590                base = _rtl92ee_phy_get_txpower_by_rate_base(hw, band, rf,
 591                                                             RF_1TX,
 592                                                             HT_MCS0_MCS7);
 593                _phy_convert_txpower_dbm_to_relative_value(
 594                        &rtlphy->tx_power_by_rate_offset[band][rf][RF_1TX][4],
 595                        0, 3, base);
 596                _phy_convert_txpower_dbm_to_relative_value(
 597                        &rtlphy->tx_power_by_rate_offset[band][rf][RF_1TX][5],
 598                        0, 3, base);
 599
 600                base = _rtl92ee_phy_get_txpower_by_rate_base(hw, band, rf,
 601                                                             RF_2TX,
 602                                                             HT_MCS8_MCS15);
 603                _phy_convert_txpower_dbm_to_relative_value(
 604                        &rtlphy->tx_power_by_rate_offset[band][rf][RF_2TX][6],
 605                        0, 3, base);
 606
 607                _phy_convert_txpower_dbm_to_relative_value(
 608                        &rtlphy->tx_power_by_rate_offset[band][rf][RF_2TX][7],
 609                        0, 3, base);
 610        }
 611
 612        RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
 613                 "<==phy_convert_txpwr_dbm_to_rel_val()\n");
 614}
 615
 616static void _rtl92ee_phy_txpower_by_rate_configuration(struct ieee80211_hw *hw)
 617{
 618        _rtl92ee_phy_store_txpower_by_rate_base(hw);
 619        phy_convert_txpwr_dbm_to_rel_val(hw);
 620}
 621
 622static bool _rtl92ee_phy_bb8192ee_config_parafile(struct ieee80211_hw *hw)
 623{
 624        struct rtl_priv *rtlpriv = rtl_priv(hw);
 625        struct rtl_phy *rtlphy = &rtlpriv->phy;
 626        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 627        bool rtstatus;
 628
 629        rtstatus = phy_config_bb_with_hdr_file(hw, BASEBAND_CONFIG_PHY_REG);
 630        if (!rtstatus) {
 631                pr_err("Write BB Reg Fail!!\n");
 632                return false;
 633        }
 634
 635        _rtl92ee_phy_init_tx_power_by_rate(hw);
 636        if (!rtlefuse->autoload_failflag) {
 637                rtlphy->pwrgroup_cnt = 0;
 638                rtstatus =
 639                  phy_config_bb_with_pghdrfile(hw, BASEBAND_CONFIG_PHY_REG);
 640        }
 641        _rtl92ee_phy_txpower_by_rate_configuration(hw);
 642        if (!rtstatus) {
 643                pr_err("BB_PG Reg Fail!!\n");
 644                return false;
 645        }
 646        rtstatus = phy_config_bb_with_hdr_file(hw, BASEBAND_CONFIG_AGC_TAB);
 647        if (!rtstatus) {
 648                pr_err("AGC Table Fail\n");
 649                return false;
 650        }
 651        rtlphy->cck_high_power = (bool)(rtl_get_bbreg(hw,
 652                                                      RFPGA0_XA_HSSIPARAMETER2,
 653                                                      0x200));
 654
 655        return true;
 656}
 657
 658static bool _rtl92ee_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
 659{
 660        struct rtl_priv *rtlpriv = rtl_priv(hw);
 661        u32 i;
 662        u32 arraylength;
 663        u32 *ptrarray;
 664
 665        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl8192EMACPHY_Array\n");
 666        arraylength = RTL8192EE_MAC_ARRAY_LEN;
 667        ptrarray = RTL8192EE_MAC_ARRAY;
 668        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 669                 "Img:RTL8192EE_MAC_ARRAY LEN %d\n" , arraylength);
 670        for (i = 0; i < arraylength; i = i + 2)
 671                rtl_write_byte(rtlpriv, ptrarray[i], (u8)ptrarray[i + 1]);
 672        return true;
 673}
 674
 675#define READ_NEXT_PAIR(v1, v2, i) \
 676        do { \
 677                i += 2; \
 678                v1 = array[i]; \
 679                v2 = array[i+1]; \
 680        } while (0)
 681
 682static bool phy_config_bb_with_hdr_file(struct ieee80211_hw *hw,
 683                                        u8 configtype)
 684{
 685        int i;
 686        u32 *array;
 687        u16 len;
 688        struct rtl_priv *rtlpriv = rtl_priv(hw);
 689        u32 v1 = 0, v2 = 0;
 690
 691        if (configtype == BASEBAND_CONFIG_PHY_REG) {
 692                len = RTL8192EE_PHY_REG_ARRAY_LEN;
 693                array = RTL8192EE_PHY_REG_ARRAY;
 694
 695                for (i = 0; i < len; i = i + 2) {
 696                        v1 = array[i];
 697                        v2 = array[i+1];
 698                        if (v1 < 0xcdcdcdcd) {
 699                                _rtl92ee_config_bb_reg(hw, v1, v2);
 700                        } else {/*This line is the start line of branch.*/
 701                                /* to protect READ_NEXT_PAIR not overrun */
 702                                if (i >= len - 2)
 703                                        break;
 704
 705                                if (!_check_condition(hw , array[i])) {
 706                                        /*Discard the following pairs*/
 707                                        READ_NEXT_PAIR(v1, v2, i);
 708                                        while (v2 != 0xDEAD &&
 709                                               v2 != 0xCDEF &&
 710                                               v2 != 0xCDCD && i < len - 2) {
 711                                                READ_NEXT_PAIR(v1, v2, i);
 712                                        }
 713                                        i -= 2; /* prevent from for-loop += 2*/
 714                                } else {
 715                                        /* Configure matched pairs and
 716                                         * skip to end of if-else.
 717                                         */
 718                                        READ_NEXT_PAIR(v1, v2, i);
 719                                        while (v2 != 0xDEAD &&
 720                                               v2 != 0xCDEF &&
 721                                               v2 != 0xCDCD && i < len - 2) {
 722                                                _rtl92ee_config_bb_reg(hw, v1,
 723                                                                       v2);
 724                                                READ_NEXT_PAIR(v1, v2, i);
 725                                        }
 726
 727                                        while (v2 != 0xDEAD && i < len - 2)
 728                                                READ_NEXT_PAIR(v1, v2, i);
 729                                }
 730                        }
 731                }
 732        } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
 733                len = RTL8192EE_AGC_TAB_ARRAY_LEN;
 734                array = RTL8192EE_AGC_TAB_ARRAY;
 735
 736                for (i = 0; i < len; i = i + 2) {
 737                        v1 = array[i];
 738                        v2 = array[i+1];
 739                        if (v1 < 0xCDCDCDCD) {
 740                                rtl_set_bbreg(hw, array[i], MASKDWORD,
 741                                              array[i + 1]);
 742                                udelay(1);
 743                                continue;
 744                    } else{/*This line is the start line of branch.*/
 745                          /* to protect READ_NEXT_PAIR not overrun */
 746                                if (i >= len - 2)
 747                                        break;
 748
 749                                if (!_check_condition(hw , array[i])) {
 750                                        /*Discard the following pairs*/
 751                                        READ_NEXT_PAIR(v1, v2, i);
 752                                        while (v2 != 0xDEAD &&
 753                                               v2 != 0xCDEF &&
 754                                               v2 != 0xCDCD &&
 755                                               i < len - 2) {
 756                                                READ_NEXT_PAIR(v1, v2, i);
 757                                        }
 758                                        i -= 2; /* prevent from for-loop += 2*/
 759                                } else {
 760                                        /* Configure matched pairs and
 761                                         * skip to end of if-else.
 762                                         */
 763                                        READ_NEXT_PAIR(v1, v2, i);
 764                                        while (v2 != 0xDEAD &&
 765                                               v2 != 0xCDEF &&
 766                                               v2 != 0xCDCD &&
 767                                               i < len - 2) {
 768                                                rtl_set_bbreg(hw,
 769                                                              array[i],
 770                                                              MASKDWORD,
 771                                                              array[i + 1]);
 772                                                udelay(1);
 773                                                READ_NEXT_PAIR(v1 , v2 , i);
 774                                        }
 775
 776                                        while (v2 != 0xDEAD &&
 777                                               i < len - 2) {
 778                                                READ_NEXT_PAIR(v1 , v2 , i);
 779                                        }
 780                                }
 781                        }
 782                        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 783                                 "The agctab_array_table[0] is %x Rtl818EEPHY_REGArray[1] is %x\n",
 784                                 array[i],
 785                                 array[i + 1]);
 786                }
 787        }
 788        return true;
 789}
 790
 791static u8 _rtl92ee_get_rate_section_index(u32 regaddr)
 792{
 793        u8 index = 0;
 794
 795        switch (regaddr) {
 796        case RTXAGC_A_RATE18_06:
 797        case RTXAGC_B_RATE18_06:
 798                index = 0;
 799                break;
 800        case RTXAGC_A_RATE54_24:
 801        case RTXAGC_B_RATE54_24:
 802                index = 1;
 803                break;
 804        case RTXAGC_A_CCK1_MCS32:
 805        case RTXAGC_B_CCK1_55_MCS32:
 806                index = 2;
 807                break;
 808        case RTXAGC_B_CCK11_A_CCK2_11:
 809                index = 3;
 810                break;
 811        case RTXAGC_A_MCS03_MCS00:
 812        case RTXAGC_B_MCS03_MCS00:
 813                index = 4;
 814                break;
 815        case RTXAGC_A_MCS07_MCS04:
 816        case RTXAGC_B_MCS07_MCS04:
 817                index = 5;
 818                break;
 819        case RTXAGC_A_MCS11_MCS08:
 820        case RTXAGC_B_MCS11_MCS08:
 821                index = 6;
 822                break;
 823        case RTXAGC_A_MCS15_MCS12:
 824        case RTXAGC_B_MCS15_MCS12:
 825                index = 7;
 826                break;
 827        default:
 828                regaddr &= 0xFFF;
 829                if (regaddr >= 0xC20 && regaddr <= 0xC4C)
 830                        index = (u8)((regaddr - 0xC20) / 4);
 831                else if (regaddr >= 0xE20 && regaddr <= 0xE4C)
 832                        index = (u8)((regaddr - 0xE20) / 4);
 833                break;
 834        }
 835        return index;
 836}
 837
 838static void _rtl92ee_store_tx_power_by_rate(struct ieee80211_hw *hw,
 839                                            enum band_type band,
 840                                            enum radio_path rfpath,
 841                                            u32 txnum, u32 regaddr,
 842                                            u32 bitmask, u32 data)
 843{
 844        struct rtl_priv *rtlpriv = rtl_priv(hw);
 845        struct rtl_phy *rtlphy = &rtlpriv->phy;
 846        u8 section = _rtl92ee_get_rate_section_index(regaddr);
 847
 848        if (band != BAND_ON_2_4G && band != BAND_ON_5G) {
 849                RT_TRACE(rtlpriv, FPHY, PHY_TXPWR, "Invalid Band %d\n", band);
 850                return;
 851        }
 852
 853        if (rfpath > MAX_RF_PATH - 1) {
 854                RT_TRACE(rtlpriv, FPHY, PHY_TXPWR,
 855                         "Invalid RfPath %d\n", rfpath);
 856                return;
 857        }
 858        if (txnum > MAX_RF_PATH - 1) {
 859                RT_TRACE(rtlpriv, FPHY, PHY_TXPWR, "Invalid TxNum %d\n", txnum);
 860                return;
 861        }
 862
 863        rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][section] = data;
 864}
 865
 866static bool phy_config_bb_with_pghdrfile(struct ieee80211_hw *hw,
 867                                         u8 configtype)
 868{
 869        struct rtl_priv *rtlpriv = rtl_priv(hw);
 870        int i;
 871        u32 *phy_regarray_table_pg;
 872        u16 phy_regarray_pg_len;
 873        u32 v1 = 0, v2 = 0, v3 = 0, v4 = 0, v5 = 0, v6 = 0;
 874
 875        phy_regarray_pg_len = RTL8192EE_PHY_REG_ARRAY_PG_LEN;
 876        phy_regarray_table_pg = RTL8192EE_PHY_REG_ARRAY_PG;
 877
 878        if (configtype == BASEBAND_CONFIG_PHY_REG) {
 879                for (i = 0; i < phy_regarray_pg_len; i = i + 6) {
 880                        v1 = phy_regarray_table_pg[i];
 881                        v2 = phy_regarray_table_pg[i+1];
 882                        v3 = phy_regarray_table_pg[i+2];
 883                        v4 = phy_regarray_table_pg[i+3];
 884                        v5 = phy_regarray_table_pg[i+4];
 885                        v6 = phy_regarray_table_pg[i+5];
 886
 887                        if (v1 < 0xcdcdcdcd) {
 888                                _rtl92ee_store_tx_power_by_rate(hw, v1, v2, v3,
 889                                                                v4, v5, v6);
 890                                continue;
 891                        }
 892                }
 893        } else {
 894                RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
 895                         "configtype != BaseBand_Config_PHY_REG\n");
 896        }
 897        return true;
 898}
 899
 900#define READ_NEXT_RF_PAIR(v1, v2, i) \
 901        do { \
 902                i += 2; \
 903                v1 = array[i]; \
 904                v2 = array[i+1]; \
 905        } while (0)
 906
 907bool rtl92ee_phy_config_rf_with_headerfile(struct ieee80211_hw  *hw,
 908                                           enum radio_path rfpath)
 909{
 910        struct rtl_priv *rtlpriv = rtl_priv(hw);
 911        int i;
 912        u32 *array;
 913        u16 len;
 914        u32 v1 = 0, v2 = 0;
 915
 916        switch (rfpath) {
 917        case RF90_PATH_A:
 918                len = RTL8192EE_RADIOA_ARRAY_LEN;
 919                array = RTL8192EE_RADIOA_ARRAY;
 920                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 921                         "Radio_A:RTL8192EE_RADIOA_ARRAY %d\n" , len);
 922                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
 923                for (i = 0; i < len; i = i + 2) {
 924                        v1 = array[i];
 925                        v2 = array[i+1];
 926                        if (v1 < 0xcdcdcdcd) {
 927                                _rtl92ee_config_rf_radio_a(hw, v1, v2);
 928                                continue;
 929                        } else {/*This line is the start line of branch.*/
 930                                /* to protect READ_NEXT_PAIR not overrun */
 931                                if (i >= len - 2)
 932                                        break;
 933
 934                                if (!_check_condition(hw , array[i])) {
 935                                        /*Discard the following pairs*/
 936                                        READ_NEXT_RF_PAIR(v1, v2, i);
 937                                        while (v2 != 0xDEAD &&
 938                                               v2 != 0xCDEF &&
 939                                               v2 != 0xCDCD && i < len - 2) {
 940                                                READ_NEXT_RF_PAIR(v1, v2, i);
 941                                        }
 942                                        i -= 2; /* prevent from for-loop += 2*/
 943                                } else {
 944                                        /* Configure matched pairs and
 945                                         * skip to end of if-else.
 946                                         */
 947                                        READ_NEXT_RF_PAIR(v1, v2, i);
 948                                        while (v2 != 0xDEAD &&
 949                                               v2 != 0xCDEF &&
 950                                               v2 != 0xCDCD && i < len - 2) {
 951                                                _rtl92ee_config_rf_radio_a(hw,
 952                                                                           v1,
 953                                                                           v2);
 954                                                READ_NEXT_RF_PAIR(v1, v2, i);
 955                                        }
 956
 957                                        while (v2 != 0xDEAD && i < len - 2)
 958                                                READ_NEXT_RF_PAIR(v1, v2, i);
 959                                }
 960                        }
 961                }
 962                break;
 963
 964        case RF90_PATH_B:
 965                len = RTL8192EE_RADIOB_ARRAY_LEN;
 966                array = RTL8192EE_RADIOB_ARRAY;
 967                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 968                         "Radio_A:RTL8192EE_RADIOB_ARRAY %d\n" , len);
 969                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
 970                for (i = 0; i < len; i = i + 2) {
 971                        v1 = array[i];
 972                        v2 = array[i+1];
 973                        if (v1 < 0xcdcdcdcd) {
 974                                _rtl92ee_config_rf_radio_b(hw, v1, v2);
 975                                continue;
 976                        } else {/*This line is the start line of branch.*/
 977                                /* to protect READ_NEXT_PAIR not overrun */
 978                                if (i >= len - 2)
 979                                        break;
 980
 981                                if (!_check_condition(hw , array[i])) {
 982                                        /*Discard the following pairs*/
 983                                        READ_NEXT_RF_PAIR(v1, v2, i);
 984                                        while (v2 != 0xDEAD &&
 985                                               v2 != 0xCDEF &&
 986                                               v2 != 0xCDCD && i < len - 2) {
 987                                                READ_NEXT_RF_PAIR(v1, v2, i);
 988                                        }
 989                                        i -= 2; /* prevent from for-loop += 2*/
 990                                } else {
 991                                        /* Configure matched pairs and
 992                                         * skip to end of if-else.
 993                                         */
 994                                        READ_NEXT_RF_PAIR(v1, v2, i);
 995                                        while (v2 != 0xDEAD &&
 996                                               v2 != 0xCDEF &&
 997                                               v2 != 0xCDCD && i < len - 2) {
 998                                                _rtl92ee_config_rf_radio_b(hw,
 999                                                                           v1,
1000                                                                           v2);
1001                                                READ_NEXT_RF_PAIR(v1, v2, i);
1002                                        }
1003
1004                                        while (v2 != 0xDEAD && i < len - 2)
1005                                                READ_NEXT_RF_PAIR(v1, v2, i);
1006                                }
1007                        }
1008                }
1009                break;
1010        case RF90_PATH_C:
1011        case RF90_PATH_D:
1012                break;
1013        }
1014        return true;
1015}
1016
1017void rtl92ee_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
1018{
1019        struct rtl_priv *rtlpriv = rtl_priv(hw);
1020        struct rtl_phy *rtlphy = &rtlpriv->phy;
1021
1022        rtlphy->default_initialgain[0] =
1023                (u8)rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
1024        rtlphy->default_initialgain[1] =
1025                (u8)rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
1026        rtlphy->default_initialgain[2] =
1027                (u8)rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
1028        rtlphy->default_initialgain[3] =
1029                (u8)rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
1030
1031        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1032                 "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n",
1033                  rtlphy->default_initialgain[0],
1034                  rtlphy->default_initialgain[1],
1035                  rtlphy->default_initialgain[2],
1036                  rtlphy->default_initialgain[3]);
1037
1038        rtlphy->framesync = (u8)rtl_get_bbreg(hw,
1039                                              ROFDM0_RXDETECTOR3, MASKBYTE0);
1040        rtlphy->framesync_c34 = rtl_get_bbreg(hw,
1041                                              ROFDM0_RXDETECTOR2, MASKDWORD);
1042
1043        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1044                 "Default framesync (0x%x) = 0x%x\n",
1045                  ROFDM0_RXDETECTOR3, rtlphy->framesync);
1046}
1047
1048static void phy_init_bb_rf_register_def(struct ieee80211_hw *hw)
1049{
1050        struct rtl_priv *rtlpriv = rtl_priv(hw);
1051        struct rtl_phy *rtlphy = &rtlpriv->phy;
1052
1053        rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
1054        rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
1055
1056        rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
1057        rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
1058
1059        rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
1060        rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
1061
1062        rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset =
1063                                                        RFPGA0_XA_LSSIPARAMETER;
1064        rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset =
1065                                                        RFPGA0_XB_LSSIPARAMETER;
1066
1067        rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2;
1068        rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2;
1069
1070        rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RFPGA0_XA_LSSIREADBACK;
1071        rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RFPGA0_XB_LSSIREADBACK;
1072
1073        rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = TRANSCEIVEA_HSPI_READBACK;
1074        rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = TRANSCEIVEB_HSPI_READBACK;
1075}
1076
1077void rtl92ee_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
1078{
1079        struct rtl_priv *rtlpriv = rtl_priv(hw);
1080        struct rtl_phy *rtlphy = &rtlpriv->phy;
1081        u8 txpwr_level;
1082        long txpwr_dbm;
1083
1084        txpwr_level = rtlphy->cur_cck_txpwridx;
1085        txpwr_dbm = _rtl92ee_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_B,
1086                                                  txpwr_level);
1087        txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
1088        if (_rtl92ee_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, txpwr_level) >
1089            txpwr_dbm)
1090                txpwr_dbm = _rtl92ee_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
1091                                                          txpwr_level);
1092        txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
1093        if (_rtl92ee_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
1094                                          txpwr_level) > txpwr_dbm)
1095                txpwr_dbm = _rtl92ee_phy_txpwr_idx_to_dbm(hw,
1096                                                          WIRELESS_MODE_N_24G,
1097                                                          txpwr_level);
1098        *powerlevel = txpwr_dbm;
1099}
1100
1101static u8 _rtl92ee_phy_get_ratesection_intxpower_byrate(enum radio_path path,
1102                                                        u8 rate)
1103{
1104        u8 rate_section = 0;
1105
1106        switch (rate) {
1107        case DESC92C_RATE1M:
1108                rate_section = 2;
1109                break;
1110        case DESC92C_RATE2M:
1111        case DESC92C_RATE5_5M:
1112                if (path == RF90_PATH_A)
1113                        rate_section = 3;
1114                else if (path == RF90_PATH_B)
1115                        rate_section = 2;
1116                break;
1117        case DESC92C_RATE11M:
1118                rate_section = 3;
1119                break;
1120        case DESC92C_RATE6M:
1121        case DESC92C_RATE9M:
1122        case DESC92C_RATE12M:
1123        case DESC92C_RATE18M:
1124                rate_section = 0;
1125                break;
1126        case DESC92C_RATE24M:
1127        case DESC92C_RATE36M:
1128        case DESC92C_RATE48M:
1129        case DESC92C_RATE54M:
1130                rate_section = 1;
1131                break;
1132        case DESC92C_RATEMCS0:
1133        case DESC92C_RATEMCS1:
1134        case DESC92C_RATEMCS2:
1135        case DESC92C_RATEMCS3:
1136                rate_section = 4;
1137                break;
1138        case DESC92C_RATEMCS4:
1139        case DESC92C_RATEMCS5:
1140        case DESC92C_RATEMCS6:
1141        case DESC92C_RATEMCS7:
1142                rate_section = 5;
1143                break;
1144        case DESC92C_RATEMCS8:
1145        case DESC92C_RATEMCS9:
1146        case DESC92C_RATEMCS10:
1147        case DESC92C_RATEMCS11:
1148                rate_section = 6;
1149                break;
1150        case DESC92C_RATEMCS12:
1151        case DESC92C_RATEMCS13:
1152        case DESC92C_RATEMCS14:
1153        case DESC92C_RATEMCS15:
1154                rate_section = 7;
1155                break;
1156        default:
1157                WARN_ONCE(true, "rtl8192ee: Rate_Section is Illegal\n");
1158                break;
1159        }
1160        return rate_section;
1161}
1162
1163static u8 _rtl92ee_get_txpower_by_rate(struct ieee80211_hw *hw,
1164                                       enum band_type band,
1165                                       enum radio_path rf, u8 rate)
1166{
1167        struct rtl_priv *rtlpriv = rtl_priv(hw);
1168        struct rtl_phy *rtlphy = &rtlpriv->phy;
1169        u8 shift = 0, sec, tx_num;
1170        s8 diff = 0;
1171
1172        sec = _rtl92ee_phy_get_ratesection_intxpower_byrate(rf, rate);
1173        tx_num = RF_TX_NUM_NONIMPLEMENT;
1174
1175        if (tx_num == RF_TX_NUM_NONIMPLEMENT) {
1176                if ((rate >= DESC92C_RATEMCS8 && rate <= DESC92C_RATEMCS15))
1177                        tx_num = RF_2TX;
1178                else
1179                        tx_num = RF_1TX;
1180        }
1181
1182        switch (rate) {
1183        case DESC92C_RATE1M:
1184        case DESC92C_RATE6M:
1185        case DESC92C_RATE24M:
1186        case DESC92C_RATEMCS0:
1187        case DESC92C_RATEMCS4:
1188        case DESC92C_RATEMCS8:
1189        case DESC92C_RATEMCS12:
1190                shift = 0;
1191                break;
1192        case DESC92C_RATE2M:
1193        case DESC92C_RATE9M:
1194        case DESC92C_RATE36M:
1195        case DESC92C_RATEMCS1:
1196        case DESC92C_RATEMCS5:
1197        case DESC92C_RATEMCS9:
1198        case DESC92C_RATEMCS13:
1199                shift = 8;
1200                break;
1201        case DESC92C_RATE5_5M:
1202        case DESC92C_RATE12M:
1203        case DESC92C_RATE48M:
1204        case DESC92C_RATEMCS2:
1205        case DESC92C_RATEMCS6:
1206        case DESC92C_RATEMCS10:
1207        case DESC92C_RATEMCS14:
1208                shift = 16;
1209                break;
1210        case DESC92C_RATE11M:
1211        case DESC92C_RATE18M:
1212        case DESC92C_RATE54M:
1213        case DESC92C_RATEMCS3:
1214        case DESC92C_RATEMCS7:
1215        case DESC92C_RATEMCS11:
1216        case DESC92C_RATEMCS15:
1217                shift = 24;
1218                break;
1219        default:
1220                WARN_ONCE(true, "rtl8192ee: Rate_Section is Illegal\n");
1221                break;
1222        }
1223
1224        diff = (u8)(rtlphy->tx_power_by_rate_offset[band][rf][tx_num][sec] >>
1225                    shift) & 0xff;
1226
1227        return  diff;
1228}
1229
1230static u8 _rtl92ee_get_txpower_index(struct ieee80211_hw *hw,
1231                                     enum radio_path rfpath, u8 rate,
1232                                     u8 bw, u8 channel)
1233{
1234        struct rtl_priv *rtlpriv = rtl_priv(hw);
1235        struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
1236        u8 index = (channel - 1);
1237        u8 tx_power = 0;
1238        u8 diff = 0;
1239
1240        if (channel < 1 || channel > 14) {
1241                index = 0;
1242                RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_DMESG,
1243                         "Illegal channel!!\n");
1244        }
1245
1246        if (IS_CCK_RATE((s8)rate))
1247                tx_power = rtlefuse->txpwrlevel_cck[rfpath][index];
1248        else if (DESC92C_RATE6M <= rate)
1249                tx_power = rtlefuse->txpwrlevel_ht40_1s[rfpath][index];
1250
1251        /* OFDM-1T*/
1252        if (DESC92C_RATE6M <= rate && rate <= DESC92C_RATE54M &&
1253            !IS_CCK_RATE((s8)rate))
1254                tx_power += rtlefuse->txpwr_legacyhtdiff[rfpath][TX_1S];
1255
1256        /* BW20-1S, BW20-2S */
1257        if (bw == HT_CHANNEL_WIDTH_20) {
1258                if (DESC92C_RATEMCS0 <= rate && rate <= DESC92C_RATEMCS15)
1259                        tx_power += rtlefuse->txpwr_ht20diff[rfpath][TX_1S];
1260                if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15)
1261                        tx_power += rtlefuse->txpwr_ht20diff[rfpath][TX_2S];
1262        } else if (bw == HT_CHANNEL_WIDTH_20_40) {/* BW40-1S, BW40-2S */
1263                if (DESC92C_RATEMCS0 <= rate && rate <= DESC92C_RATEMCS15)
1264                        tx_power += rtlefuse->txpwr_ht40diff[rfpath][TX_1S];
1265                if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15)
1266                        tx_power += rtlefuse->txpwr_ht40diff[rfpath][TX_2S];
1267        }
1268
1269        if (rtlefuse->eeprom_regulatory != 2)
1270                diff = _rtl92ee_get_txpower_by_rate(hw, BAND_ON_2_4G,
1271                                                    rfpath, rate);
1272
1273        tx_power += diff;
1274
1275        if (tx_power > MAX_POWER_INDEX)
1276                tx_power = MAX_POWER_INDEX;
1277
1278        return tx_power;
1279}
1280
1281static void _rtl92ee_set_txpower_index(struct ieee80211_hw *hw, u8 pwr_idx,
1282                                       enum radio_path rfpath, u8 rate)
1283{
1284        struct rtl_priv *rtlpriv = rtl_priv(hw);
1285
1286        if (rfpath == RF90_PATH_A) {
1287                switch (rate) {
1288                case DESC92C_RATE1M:
1289                        rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1,
1290                                      pwr_idx);
1291                        break;
1292                case DESC92C_RATE2M:
1293                        rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE1,
1294                                      pwr_idx);
1295                        break;
1296                case DESC92C_RATE5_5M:
1297                        rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE2,
1298                                      pwr_idx);
1299                        break;
1300                case DESC92C_RATE11M:
1301                        rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE3,
1302                                      pwr_idx);
1303                        break;
1304                case DESC92C_RATE6M:
1305                        rtl_set_bbreg(hw, RTXAGC_A_RATE18_06, MASKBYTE0,
1306                                      pwr_idx);
1307                        break;
1308                case DESC92C_RATE9M:
1309                        rtl_set_bbreg(hw, RTXAGC_A_RATE18_06, MASKBYTE1,
1310                                      pwr_idx);
1311                        break;
1312                case DESC92C_RATE12M:
1313                        rtl_set_bbreg(hw, RTXAGC_A_RATE18_06, MASKBYTE2,
1314                                      pwr_idx);
1315                        break;
1316                case DESC92C_RATE18M:
1317                        rtl_set_bbreg(hw, RTXAGC_A_RATE18_06, MASKBYTE3,
1318                                      pwr_idx);
1319                        break;
1320                case DESC92C_RATE24M:
1321                        rtl_set_bbreg(hw, RTXAGC_A_RATE54_24, MASKBYTE0,
1322                                      pwr_idx);
1323                        break;
1324                case DESC92C_RATE36M:
1325                        rtl_set_bbreg(hw, RTXAGC_A_RATE54_24, MASKBYTE1,
1326                                      pwr_idx);
1327                        break;
1328                case DESC92C_RATE48M:
1329                        rtl_set_bbreg(hw, RTXAGC_A_RATE54_24, MASKBYTE2,
1330                                      pwr_idx);
1331                        break;
1332                case DESC92C_RATE54M:
1333                        rtl_set_bbreg(hw, RTXAGC_A_RATE54_24, MASKBYTE3,
1334                                      pwr_idx);
1335                        break;
1336                case DESC92C_RATEMCS0:
1337                        rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00, MASKBYTE0,
1338                                      pwr_idx);
1339                        break;
1340                case DESC92C_RATEMCS1:
1341                        rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00, MASKBYTE1,
1342                                      pwr_idx);
1343                        break;
1344                case DESC92C_RATEMCS2:
1345                        rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00, MASKBYTE2,
1346                                      pwr_idx);
1347                        break;
1348                case DESC92C_RATEMCS3:
1349                        rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00, MASKBYTE3,
1350                                      pwr_idx);
1351                        break;
1352                case DESC92C_RATEMCS4:
1353                        rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04, MASKBYTE0,
1354                                      pwr_idx);
1355                        break;
1356                case DESC92C_RATEMCS5:
1357                        rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04, MASKBYTE1,
1358                                      pwr_idx);
1359                        break;
1360                case DESC92C_RATEMCS6:
1361                        rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04, MASKBYTE2,
1362                                      pwr_idx);
1363                        break;
1364                case DESC92C_RATEMCS7:
1365                        rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04, MASKBYTE3,
1366                                      pwr_idx);
1367                        break;
1368                case DESC92C_RATEMCS8:
1369                        rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08, MASKBYTE0,
1370                                      pwr_idx);
1371                        break;
1372                case DESC92C_RATEMCS9:
1373                        rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08, MASKBYTE1,
1374                                      pwr_idx);
1375                        break;
1376                case DESC92C_RATEMCS10:
1377                        rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08, MASKBYTE2,
1378                                      pwr_idx);
1379                        break;
1380                case DESC92C_RATEMCS11:
1381                        rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08, MASKBYTE3,
1382                                      pwr_idx);
1383                        break;
1384                case DESC92C_RATEMCS12:
1385                        rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12, MASKBYTE0,
1386                                      pwr_idx);
1387                        break;
1388                case DESC92C_RATEMCS13:
1389                        rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12, MASKBYTE1,
1390                                      pwr_idx);
1391                        break;
1392                case DESC92C_RATEMCS14:
1393                        rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12, MASKBYTE2,
1394                                      pwr_idx);
1395                        break;
1396                case DESC92C_RATEMCS15:
1397                        rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12, MASKBYTE3,
1398                                      pwr_idx);
1399                        break;
1400                default:
1401                        RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
1402                                 "Invalid Rate!!\n");
1403                        break;
1404                }
1405        } else if (rfpath == RF90_PATH_B) {
1406                switch (rate) {
1407                case DESC92C_RATE1M:
1408                        rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, MASKBYTE1,
1409                                      pwr_idx);
1410                        break;
1411                case DESC92C_RATE2M:
1412                        rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, MASKBYTE2,
1413                                      pwr_idx);
1414                        break;
1415                case DESC92C_RATE5_5M:
1416                        rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, MASKBYTE3,
1417                                      pwr_idx);
1418                        break;
1419                case DESC92C_RATE11M:
1420                        rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0,
1421                                      pwr_idx);
1422                        break;
1423                case DESC92C_RATE6M:
1424                        rtl_set_bbreg(hw, RTXAGC_B_RATE18_06, MASKBYTE0,
1425                                      pwr_idx);
1426                        break;
1427                case DESC92C_RATE9M:
1428                        rtl_set_bbreg(hw, RTXAGC_B_RATE18_06, MASKBYTE1,
1429                                      pwr_idx);
1430                        break;
1431                case DESC92C_RATE12M:
1432                        rtl_set_bbreg(hw, RTXAGC_B_RATE18_06, MASKBYTE2,
1433                                      pwr_idx);
1434                        break;
1435                case DESC92C_RATE18M:
1436                        rtl_set_bbreg(hw, RTXAGC_B_RATE18_06, MASKBYTE3,
1437                                      pwr_idx);
1438                        break;
1439                case DESC92C_RATE24M:
1440                        rtl_set_bbreg(hw, RTXAGC_B_RATE54_24, MASKBYTE0,
1441                                      pwr_idx);
1442                        break;
1443                case DESC92C_RATE36M:
1444                        rtl_set_bbreg(hw, RTXAGC_B_RATE54_24, MASKBYTE1,
1445                                      pwr_idx);
1446                        break;
1447                case DESC92C_RATE48M:
1448                        rtl_set_bbreg(hw, RTXAGC_B_RATE54_24, MASKBYTE2,
1449                                      pwr_idx);
1450                        break;
1451                case DESC92C_RATE54M:
1452                        rtl_set_bbreg(hw, RTXAGC_B_RATE54_24, MASKBYTE3,
1453                                      pwr_idx);
1454                        break;
1455                case DESC92C_RATEMCS0:
1456                        rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00, MASKBYTE0,
1457                                      pwr_idx);
1458                        break;
1459                case DESC92C_RATEMCS1:
1460                        rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00, MASKBYTE1,
1461                                      pwr_idx);
1462                        break;
1463                case DESC92C_RATEMCS2:
1464                        rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00, MASKBYTE2,
1465                                      pwr_idx);
1466                        break;
1467                case DESC92C_RATEMCS3:
1468                        rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00, MASKBYTE3,
1469                                      pwr_idx);
1470                        break;
1471                case DESC92C_RATEMCS4:
1472                        rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04, MASKBYTE0,
1473                                      pwr_idx);
1474                        break;
1475                case DESC92C_RATEMCS5:
1476                        rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04, MASKBYTE1,
1477                                      pwr_idx);
1478                        break;
1479                case DESC92C_RATEMCS6:
1480                        rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04, MASKBYTE2,
1481                                      pwr_idx);
1482                        break;
1483                case DESC92C_RATEMCS7:
1484                        rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04, MASKBYTE3,
1485                                      pwr_idx);
1486                        break;
1487                case DESC92C_RATEMCS8:
1488                        rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08, MASKBYTE0,
1489                                      pwr_idx);
1490                        break;
1491                case DESC92C_RATEMCS9:
1492                        rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08, MASKBYTE1,
1493                                      pwr_idx);
1494                        break;
1495                case DESC92C_RATEMCS10:
1496                        rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08, MASKBYTE2,
1497                                      pwr_idx);
1498                        break;
1499                case DESC92C_RATEMCS11:
1500                        rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08, MASKBYTE3,
1501                                      pwr_idx);
1502                        break;
1503                case DESC92C_RATEMCS12:
1504                        rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12, MASKBYTE0,
1505                                      pwr_idx);
1506                        break;
1507                case DESC92C_RATEMCS13:
1508                        rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12, MASKBYTE1,
1509                                      pwr_idx);
1510                        break;
1511                case DESC92C_RATEMCS14:
1512                        rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12, MASKBYTE2,
1513                                      pwr_idx);
1514                        break;
1515                case DESC92C_RATEMCS15:
1516                        rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12, MASKBYTE3,
1517                                      pwr_idx);
1518                        break;
1519                default:
1520                        RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
1521                                 "Invalid Rate!!\n");
1522                        break;
1523                }
1524        } else {
1525                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid RFPath!!\n");
1526        }
1527}
1528
1529static void phy_set_txpower_index_by_rate_array(struct ieee80211_hw *hw,
1530                                                enum radio_path rfpath, u8 bw,
1531                                                u8 channel, u8 *rates, u8 size)
1532{
1533        u8 i;
1534        u8 power_index;
1535
1536        for (i = 0; i < size; i++) {
1537                power_index = _rtl92ee_get_txpower_index(hw, rfpath, rates[i],
1538                                                         bw, channel);
1539                _rtl92ee_set_txpower_index(hw, power_index, rfpath, rates[i]);
1540        }
1541}
1542
1543static void phy_set_txpower_index_by_rate_section(struct ieee80211_hw *hw,
1544                                                  enum radio_path rfpath,
1545                                                  u8 channel,
1546                                                  enum rate_section section)
1547{
1548        struct rtl_priv *rtlpriv = rtl_priv(hw);
1549        struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1550        struct rtl_phy *rtlphy = &rtlpriv->phy;
1551
1552        if (section == CCK) {
1553                u8 cck_rates[] = {DESC92C_RATE1M, DESC92C_RATE2M,
1554                                  DESC92C_RATE5_5M, DESC92C_RATE11M};
1555                if (rtlhal->current_bandtype == BAND_ON_2_4G)
1556                        phy_set_txpower_index_by_rate_array(hw, rfpath,
1557                                                        rtlphy->current_chan_bw,
1558                                                        channel, cck_rates, 4);
1559        } else if (section == OFDM) {
1560                u8 ofdm_rates[] = {DESC92C_RATE6M, DESC92C_RATE9M,
1561                                   DESC92C_RATE12M, DESC92C_RATE18M,
1562                                   DESC92C_RATE24M, DESC92C_RATE36M,
1563                                   DESC92C_RATE48M, DESC92C_RATE54M};
1564                phy_set_txpower_index_by_rate_array(hw, rfpath,
1565                                                    rtlphy->current_chan_bw,
1566                                                    channel, ofdm_rates, 8);
1567        } else if (section == HT_MCS0_MCS7) {
1568                u8 ht_rates1t[]  = {DESC92C_RATEMCS0, DESC92C_RATEMCS1,
1569                                    DESC92C_RATEMCS2, DESC92C_RATEMCS3,
1570                                    DESC92C_RATEMCS4, DESC92C_RATEMCS5,
1571                                    DESC92C_RATEMCS6, DESC92C_RATEMCS7};
1572                phy_set_txpower_index_by_rate_array(hw, rfpath,
1573                                                    rtlphy->current_chan_bw,
1574                                                    channel, ht_rates1t, 8);
1575        } else if (section == HT_MCS8_MCS15) {
1576                u8 ht_rates2t[]  = {DESC92C_RATEMCS8, DESC92C_RATEMCS9,
1577                                    DESC92C_RATEMCS10, DESC92C_RATEMCS11,
1578                                    DESC92C_RATEMCS12, DESC92C_RATEMCS13,
1579                                    DESC92C_RATEMCS14, DESC92C_RATEMCS15};
1580                phy_set_txpower_index_by_rate_array(hw, rfpath,
1581                                                    rtlphy->current_chan_bw,
1582                                                    channel, ht_rates2t, 8);
1583        } else
1584                RT_TRACE(rtlpriv, FPHY, PHY_TXPWR,
1585                         "Invalid RateSection %d\n", section);
1586}
1587
1588void rtl92ee_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
1589{
1590        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1591        struct rtl_phy *rtlphy = &rtl_priv(hw)->phy;
1592        enum radio_path rfpath;
1593
1594        if (!rtlefuse->txpwr_fromeprom)
1595                return;
1596        for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;
1597             rfpath++) {
1598                phy_set_txpower_index_by_rate_section(hw, rfpath,
1599                                                      channel, CCK);
1600                phy_set_txpower_index_by_rate_section(hw, rfpath,
1601                                                      channel, OFDM);
1602                phy_set_txpower_index_by_rate_section(hw, rfpath,
1603                                                      channel,
1604                                                      HT_MCS0_MCS7);
1605
1606                if (rtlphy->num_total_rfpath >= 2)
1607                        phy_set_txpower_index_by_rate_section(hw,
1608                                                              rfpath, channel,
1609                                                              HT_MCS8_MCS15);
1610        }
1611}
1612
1613static long _rtl92ee_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
1614                                          enum wireless_mode wirelessmode,
1615                                          u8 txpwridx)
1616{
1617        long offset;
1618        long pwrout_dbm;
1619
1620        switch (wirelessmode) {
1621        case WIRELESS_MODE_B:
1622                offset = -7;
1623                break;
1624        case WIRELESS_MODE_G:
1625        case WIRELESS_MODE_N_24G:
1626                offset = -8;
1627                break;
1628        default:
1629                offset = -8;
1630                break;
1631        }
1632        pwrout_dbm = txpwridx / 2 + offset;
1633        return pwrout_dbm;
1634}
1635
1636void rtl92ee_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
1637{
1638        struct rtl_priv *rtlpriv = rtl_priv(hw);
1639        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1640        enum io_type iotype;
1641
1642        if (!is_hal_stop(rtlhal)) {
1643                switch (operation) {
1644                case SCAN_OPT_BACKUP_BAND0:
1645                        iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
1646                        rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1647                                                      (u8 *)&iotype);
1648
1649                        break;
1650                case SCAN_OPT_RESTORE:
1651                        iotype = IO_CMD_RESUME_DM_BY_SCAN;
1652                        rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1653                                                      (u8 *)&iotype);
1654                        break;
1655                default:
1656                        pr_err("Unknown Scan Backup operation.\n");
1657                        break;
1658                }
1659        }
1660}
1661
1662void rtl92ee_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
1663{
1664        struct rtl_priv *rtlpriv = rtl_priv(hw);
1665        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1666        struct rtl_phy *rtlphy = &rtlpriv->phy;
1667        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1668        u8 reg_bw_opmode;
1669        u8 reg_prsr_rsc;
1670
1671        RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
1672                 "Switch to %s bandwidth\n",
1673                  rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
1674                  "20MHz" : "40MHz");
1675
1676        if (is_hal_stop(rtlhal)) {
1677                rtlphy->set_bwmode_inprogress = false;
1678                return;
1679        }
1680
1681        reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
1682        reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
1683
1684        switch (rtlphy->current_chan_bw) {
1685        case HT_CHANNEL_WIDTH_20:
1686                reg_bw_opmode |= BW_OPMODE_20MHZ;
1687                rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1688                break;
1689        case HT_CHANNEL_WIDTH_20_40:
1690                reg_bw_opmode &= ~BW_OPMODE_20MHZ;
1691                rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1692                reg_prsr_rsc = (reg_prsr_rsc & 0x90) |
1693                               (mac->cur_40_prime_sc << 5);
1694                rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
1695                break;
1696        default:
1697                pr_err("unknown bandwidth: %#X\n",
1698                       rtlphy->current_chan_bw);
1699                break;
1700        }
1701
1702        switch (rtlphy->current_chan_bw) {
1703        case HT_CHANNEL_WIDTH_20:
1704                rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
1705                rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
1706                rtl_set_bbreg(hw, ROFDM0_TXPSEUDONOISEWGT,
1707                              (BIT(31) | BIT(30)), 0);
1708                break;
1709        case HT_CHANNEL_WIDTH_20_40:
1710                rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
1711                rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
1712                rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
1713                              (mac->cur_40_prime_sc >> 1));
1714                rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00,
1715                              mac->cur_40_prime_sc);
1716
1717                rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
1718                              (mac->cur_40_prime_sc ==
1719                               HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
1720                break;
1721        default:
1722                pr_err("unknown bandwidth: %#X\n",
1723                       rtlphy->current_chan_bw);
1724                break;
1725        }
1726        rtl92ee_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
1727        rtlphy->set_bwmode_inprogress = false;
1728        RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, "\n");
1729}
1730
1731void rtl92ee_phy_set_bw_mode(struct ieee80211_hw *hw,
1732                             enum nl80211_channel_type ch_type)
1733{
1734        struct rtl_priv *rtlpriv = rtl_priv(hw);
1735        struct rtl_phy *rtlphy = &rtlpriv->phy;
1736        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1737        u8 tmp_bw = rtlphy->current_chan_bw;
1738
1739        if (rtlphy->set_bwmode_inprogress)
1740                return;
1741        rtlphy->set_bwmode_inprogress = true;
1742        if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1743                rtl92ee_phy_set_bw_mode_callback(hw);
1744        } else {
1745                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1746                         "false driver sleep or unload\n");
1747                rtlphy->set_bwmode_inprogress = false;
1748                rtlphy->current_chan_bw = tmp_bw;
1749        }
1750}
1751
1752void rtl92ee_phy_sw_chnl_callback(struct ieee80211_hw *hw)
1753{
1754        struct rtl_priv *rtlpriv = rtl_priv(hw);
1755        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1756        struct rtl_phy *rtlphy = &rtlpriv->phy;
1757        u32 delay;
1758
1759        RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
1760                 "switch to channel%d\n", rtlphy->current_channel);
1761        if (is_hal_stop(rtlhal))
1762                return;
1763        do {
1764                if (!rtlphy->sw_chnl_inprogress)
1765                        break;
1766                if (!_rtl92ee_phy_sw_chnl_step_by_step
1767                    (hw, rtlphy->current_channel, &rtlphy->sw_chnl_stage,
1768                     &rtlphy->sw_chnl_step, &delay)) {
1769                        if (delay > 0)
1770                                mdelay(delay);
1771                        else
1772                                continue;
1773                } else {
1774                        rtlphy->sw_chnl_inprogress = false;
1775                }
1776                break;
1777        } while (true);
1778        RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
1779}
1780
1781u8 rtl92ee_phy_sw_chnl(struct ieee80211_hw *hw)
1782{
1783        struct rtl_priv *rtlpriv = rtl_priv(hw);
1784        struct rtl_phy *rtlphy = &rtlpriv->phy;
1785        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1786
1787        if (rtlphy->sw_chnl_inprogress)
1788                return 0;
1789        if (rtlphy->set_bwmode_inprogress)
1790                return 0;
1791        WARN_ONCE((rtlphy->current_channel > 14),
1792                  "rtl8192ee: WIRELESS_MODE_G but channel>14");
1793        rtlphy->sw_chnl_inprogress = true;
1794        rtlphy->sw_chnl_stage = 0;
1795        rtlphy->sw_chnl_step = 0;
1796        if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1797                rtl92ee_phy_sw_chnl_callback(hw);
1798                RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
1799                         "sw_chnl_inprogress false schedule workitem current channel %d\n",
1800                         rtlphy->current_channel);
1801                rtlphy->sw_chnl_inprogress = false;
1802        } else {
1803                RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
1804                         "sw_chnl_inprogress false driver sleep or unload\n");
1805                rtlphy->sw_chnl_inprogress = false;
1806        }
1807        return 1;
1808}
1809
1810static bool _rtl92ee_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
1811                                              u8 channel, u8 *stage, u8 *step,
1812                                              u32 *delay)
1813{
1814        struct rtl_priv *rtlpriv = rtl_priv(hw);
1815        struct rtl_phy *rtlphy = &rtlpriv->phy;
1816        struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];
1817        u32 precommoncmdcnt;
1818        struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];
1819        u32 postcommoncmdcnt;
1820        struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];
1821        u32 rfdependcmdcnt;
1822        struct swchnlcmd *currentcmd = NULL;
1823        u8 rfpath;
1824        u8 num_total_rfpath = rtlphy->num_total_rfpath;
1825
1826        precommoncmdcnt = 0;
1827        _rtl92ee_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
1828                                          MAX_PRECMD_CNT,
1829                                          CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0);
1830        _rtl92ee_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
1831                                          MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
1832
1833        postcommoncmdcnt = 0;
1834
1835        _rtl92ee_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
1836                                          MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0);
1837
1838        rfdependcmdcnt = 0;
1839
1840        WARN_ONCE((channel < 1 || channel > 14),
1841                  "rtl8192ee: illegal channel for Zebra: %d\n", channel);
1842
1843        _rtl92ee_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
1844                                          MAX_RFDEPENDCMD_CNT,
1845                                          CMDID_RF_WRITEREG,
1846                                          RF_CHNLBW, channel, 10);
1847
1848        _rtl92ee_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
1849                                          MAX_RFDEPENDCMD_CNT, CMDID_END,
1850                                          0, 0, 0);
1851
1852        do {
1853                switch (*stage) {
1854                case 0:
1855                        currentcmd = &precommoncmd[*step];
1856                        break;
1857                case 1:
1858                        currentcmd = &rfdependcmd[*step];
1859                        break;
1860                case 2:
1861                        currentcmd = &postcommoncmd[*step];
1862                        break;
1863                default:
1864                        pr_err("Invalid 'stage' = %d, Check it!\n",
1865                               *stage);
1866                        return true;
1867                }
1868
1869                if (currentcmd->cmdid == CMDID_END) {
1870                        if ((*stage) == 2)
1871                                return true;
1872                        (*stage)++;
1873                        (*step) = 0;
1874                        continue;
1875                }
1876
1877                switch (currentcmd->cmdid) {
1878                case CMDID_SET_TXPOWEROWER_LEVEL:
1879                        rtl92ee_phy_set_txpower_level(hw, channel);
1880                        break;
1881                case CMDID_WRITEPORT_ULONG:
1882                        rtl_write_dword(rtlpriv, currentcmd->para1,
1883                                        currentcmd->para2);
1884                        break;
1885                case CMDID_WRITEPORT_USHORT:
1886                        rtl_write_word(rtlpriv, currentcmd->para1,
1887                                       (u16)currentcmd->para2);
1888                        break;
1889                case CMDID_WRITEPORT_UCHAR:
1890                        rtl_write_byte(rtlpriv, currentcmd->para1,
1891                                       (u8)currentcmd->para2);
1892                        break;
1893                case CMDID_RF_WRITEREG:
1894                        for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
1895                                rtlphy->rfreg_chnlval[rfpath] =
1896                                        ((rtlphy->rfreg_chnlval[rfpath] &
1897                                          0xfffff00) | currentcmd->para2);
1898
1899                                rtl_set_rfreg(hw, (enum radio_path)rfpath,
1900                                              currentcmd->para1,
1901                                              0x3ff,
1902                                              rtlphy->rfreg_chnlval[rfpath]);
1903                        }
1904                        break;
1905                default:
1906                        RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
1907                                 "switch case %#x not processed\n",
1908                                 currentcmd->cmdid);
1909                        break;
1910                }
1911
1912                break;
1913        } while (true);
1914
1915        (*delay) = currentcmd->msdelay;
1916        (*step)++;
1917        return false;
1918}
1919
1920static bool _rtl92ee_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
1921                                              u32 cmdtableidx, u32 cmdtablesz,
1922                                              enum swchnlcmd_id cmdid,
1923                                              u32 para1, u32 para2, u32 msdelay)
1924{
1925        struct swchnlcmd *pcmd;
1926
1927        if (cmdtable == NULL) {
1928                WARN_ONCE(true, "rtl8192ee: cmdtable cannot be NULL.\n");
1929                return false;
1930        }
1931
1932        if (cmdtableidx >= cmdtablesz)
1933                return false;
1934
1935        pcmd = cmdtable + cmdtableidx;
1936        pcmd->cmdid = cmdid;
1937        pcmd->para1 = para1;
1938        pcmd->para2 = para2;
1939        pcmd->msdelay = msdelay;
1940        return true;
1941}
1942
1943static u8 _rtl92ee_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb)
1944{
1945        u32 reg_eac, reg_e94, reg_e9c;
1946        u8 result = 0x00;
1947        /* path-A IQK setting */
1948        /* PA/PAD controlled by 0x0 */
1949        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1950        rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0x180);
1951        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1952
1953        rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1954        rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1955        rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1956        rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1957
1958        rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82140303);
1959        rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x68160000);
1960
1961        /*LO calibration setting*/
1962        rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x00462911);
1963
1964        /*One shot, path A LOK & IQK*/
1965        rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1966        rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1967
1968        mdelay(IQK_DELAY_TIME);
1969
1970        reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
1971        reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD);
1972        reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD);
1973
1974        if (!(reg_eac & BIT(28)) &&
1975            (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1976            (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1977                result |= 0x01;
1978        else
1979                return result;
1980
1981        return result;
1982}
1983
1984static u8 _rtl92ee_phy_path_b_iqk(struct ieee80211_hw *hw)
1985{
1986        u32 reg_eac, reg_eb4, reg_ebc;
1987        u8 result = 0x00;
1988
1989        /* PA/PAD controlled by 0x0 */
1990        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1991        rtl_set_rfreg(hw, RF90_PATH_B, 0xdf, RFREG_OFFSET_MASK, 0x180);
1992        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1993
1994        rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000);
1995        rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
1996
1997        rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1998        rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1999        rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x18008c1c);
2000        rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
2001
2002        rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x821403e2);
2003        rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x68160000);
2004
2005        /* LO calibration setting */
2006        rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x00462911);
2007
2008        /*One shot, path B LOK & IQK*/
2009        rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xfa000000);
2010        rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
2011
2012        mdelay(IQK_DELAY_TIME);
2013
2014        reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
2015        reg_eb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD);
2016        reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD);
2017
2018        if (!(reg_eac & BIT(31)) &&
2019            (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) &&
2020            (((reg_ebc & 0x03FF0000) >> 16) != 0x42))
2021                result |= 0x01;
2022        else
2023                return result;
2024
2025        return result;
2026}
2027
2028static u8 _rtl92ee_phy_path_a_rx_iqk(struct ieee80211_hw *hw, bool config_pathb)
2029{
2030        u32 reg_eac, reg_e94, reg_e9c, reg_ea4 , u32temp;
2031        u8 result = 0x00;
2032
2033        /*Get TXIMR Setting*/
2034        /*Modify RX IQK mode table*/
2035        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
2036
2037        rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0);
2038        rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
2039        rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0000f);
2040        rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf117b);
2041
2042        /*PA/PAD control by 0x56, and set = 0x0*/
2043        rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0x980);
2044        rtl_set_rfreg(hw, RF90_PATH_A, 0x56, RFREG_OFFSET_MASK, 0x51000);
2045
2046        /*enter IQK mode*/
2047        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
2048
2049        /*IQK Setting*/
2050        rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
2051        rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
2052
2053        /*path a IQK setting*/
2054        rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
2055        rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
2056        rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
2057        rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
2058
2059        rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160c1f);
2060        rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x68160c1f);
2061
2062        /*LO calibration Setting*/
2063        rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911);
2064
2065        /*one shot,path A LOK & iqk*/
2066        rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xfa000000);
2067        rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
2068
2069        mdelay(IQK_DELAY_TIME);
2070
2071        /* Check failed */
2072        reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
2073        reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD);
2074        reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD);
2075
2076        if (!(reg_eac & BIT(28)) &&
2077            (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
2078            (((reg_e9c & 0x03FF0000) >> 16) != 0x42)) {
2079                result |= 0x01;
2080        } else {
2081                /*      PA/PAD controlled by 0x0 */
2082                rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
2083                rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0x180);
2084                return result;
2085        }
2086
2087        u32temp = 0x80007C00 | (reg_e94 & 0x3FF0000)  |
2088                  ((reg_e9c & 0x3FF0000) >> 16);
2089        rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, u32temp);
2090        /*RX IQK*/
2091        /*Modify RX IQK mode table*/
2092        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
2093
2094        rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0);
2095
2096        rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
2097        rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0000f);
2098        rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7ffa);
2099
2100        /*PA/PAD control by 0x56, and set = 0x0*/
2101        rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0x980);
2102        rtl_set_rfreg(hw, RF90_PATH_A, 0x56, RFREG_OFFSET_MASK, 0x51000);
2103
2104        /*enter IQK mode*/
2105        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
2106
2107        /*IQK Setting*/
2108        rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
2109
2110        /*path a IQK setting*/
2111        rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
2112        rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
2113        rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
2114        rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
2115
2116        rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160c1f);
2117        rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28160c1f);
2118
2119        /*LO calibration Setting*/
2120        rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a891);
2121        /*one shot,path A LOK & iqk*/
2122        rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xfa000000);
2123        rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
2124
2125        mdelay(IQK_DELAY_TIME);
2126        /*Check failed*/
2127        reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
2128        reg_ea4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2, MASKDWORD);
2129
2130        /*PA/PAD controlled by 0x0*/
2131        /*leave IQK mode*/
2132        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
2133        rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0x180);
2134        /*if Tx is OK, check whether Rx is OK*/
2135        if (!(reg_eac & BIT(27)) &&
2136            (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) &&
2137            (((reg_eac & 0x03FF0000) >> 16) != 0x36))
2138                result |= 0x02;
2139
2140        return result;
2141}
2142
2143static u8 _rtl92ee_phy_path_b_rx_iqk(struct ieee80211_hw *hw, bool config_pathb)
2144{
2145        struct rtl_priv *rtlpriv = rtl_priv(hw);
2146        u32 reg_eac, reg_eb4, reg_ebc, reg_ecc, reg_ec4, u32temp;
2147        u8 result = 0x00;
2148
2149        /*Get TXIMR Setting*/
2150        /*Modify RX IQK mode table*/
2151        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
2152
2153        rtl_set_rfreg(hw, RF90_PATH_B, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0);
2154        rtl_set_rfreg(hw, RF90_PATH_B, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
2155        rtl_set_rfreg(hw, RF90_PATH_B, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0000f);
2156        rtl_set_rfreg(hw, RF90_PATH_B, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf117b);
2157
2158        /*PA/PAD all off*/
2159        rtl_set_rfreg(hw, RF90_PATH_B, 0xdf, RFREG_OFFSET_MASK, 0x980);
2160        rtl_set_rfreg(hw, RF90_PATH_B, 0x56, RFREG_OFFSET_MASK, 0x51000);
2161
2162        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
2163
2164        /*IQK Setting*/
2165        rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
2166        rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
2167
2168        /*path a IQK setting*/
2169        rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
2170        rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
2171        rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x18008c1c);
2172        rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
2173
2174        rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82160c1f);
2175        rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x68160c1f);
2176
2177        /*LO calibration Setting*/
2178        rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911);
2179
2180        /*one shot,path A LOK & iqk*/
2181        rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xfa000000);
2182        rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
2183
2184        mdelay(IQK_DELAY_TIME);
2185
2186        /* Check failed */
2187        reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
2188        reg_eb4 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_B, MASKDWORD);
2189        reg_ebc = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_B, MASKDWORD);
2190
2191        if (!(reg_eac & BIT(31)) &&
2192            (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) &&
2193            (((reg_ebc & 0x03FF0000) >> 16) != 0x42)) {
2194                result |= 0x01;
2195        } else {
2196                /*      PA/PAD controlled by 0x0 */
2197                rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
2198                rtl_set_rfreg(hw, RF90_PATH_B, 0xdf, RFREG_OFFSET_MASK, 0x180);
2199                return result;
2200        }
2201
2202        u32temp = 0x80007C00 | (reg_eb4 & 0x3FF0000) |
2203                  ((reg_ebc & 0x3FF0000) >> 16);
2204        rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, u32temp);
2205        /*RX IQK*/
2206        /*Modify RX IQK mode table*/
2207        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
2208        rtl_set_rfreg(hw, RF90_PATH_B, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0);
2209
2210        rtl_set_rfreg(hw, RF90_PATH_B, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
2211        rtl_set_rfreg(hw, RF90_PATH_B, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0000f);
2212        rtl_set_rfreg(hw, RF90_PATH_B, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7ffa);
2213
2214        /*PA/PAD all off*/
2215        rtl_set_rfreg(hw, RF90_PATH_B, 0xdf, RFREG_OFFSET_MASK, 0x980);
2216        rtl_set_rfreg(hw, RF90_PATH_B, 0x56, RFREG_OFFSET_MASK, 0x51000);
2217
2218        /*enter IQK mode*/
2219        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
2220
2221        /*IQK Setting*/
2222        rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
2223
2224        /*path b IQK setting*/
2225        rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
2226        rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
2227        rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
2228        rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x18008c1c);
2229
2230        rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82160c1f);
2231        rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28160c1f);
2232
2233        /*LO calibration Setting*/
2234        rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a891);
2235        /*one shot,path A LOK & iqk*/
2236        rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xfa000000);
2237        rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
2238
2239        mdelay(IQK_DELAY_TIME);
2240        /*Check failed*/
2241        reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
2242        reg_ec4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_B_2, MASKDWORD);
2243        reg_ecc = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_B_2, MASKDWORD);
2244        /*PA/PAD controlled by 0x0*/
2245        /*leave IQK mode*/
2246        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
2247        rtl_set_rfreg(hw, RF90_PATH_B, 0xdf, RFREG_OFFSET_MASK, 0x180);
2248        /*if Tx is OK, check whether Rx is OK*/
2249        if (!(reg_eac & BIT(30)) &&
2250            (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) &&
2251            (((reg_ecc & 0x03FF0000) >> 16) != 0x36))
2252                result |= 0x02;
2253        else
2254                RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "Path B Rx IQK fail!!\n");
2255
2256        return result;
2257}
2258
2259static void _rtl92ee_phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw,
2260                                                bool b_iqk_ok, long result[][8],
2261                                                u8 final_candidate,
2262                                                bool btxonly)
2263{
2264        u32 oldval_0, x, tx0_a, reg;
2265        long y, tx0_c;
2266
2267        if (final_candidate == 0xFF) {
2268                return;
2269        } else if (b_iqk_ok) {
2270                oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
2271                                          MASKDWORD) >> 22) & 0x3FF;
2272                x = result[final_candidate][0];
2273                if ((x & 0x00000200) != 0)
2274                        x = x | 0xFFFFFC00;
2275                tx0_a = (x * oldval_0) >> 8;
2276                rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx0_a);
2277                rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(31),
2278                              ((x * oldval_0 >> 7) & 0x1));
2279                y = result[final_candidate][1];
2280                if ((y & 0x00000200) != 0)
2281                        y = y | 0xFFFFFC00;
2282                tx0_c = (y * oldval_0) >> 8;
2283                rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000,
2284                              ((tx0_c & 0x3C0) >> 6));
2285                rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x003F0000,
2286                              (tx0_c & 0x3F));
2287                rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(29),
2288                              ((y * oldval_0 >> 7) & 0x1));
2289
2290                if (btxonly)
2291                        return;
2292
2293                reg = result[final_candidate][2];
2294                rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg);
2295
2296                reg = result[final_candidate][3] & 0x3F;
2297                rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg);
2298
2299                reg = (result[final_candidate][3] >> 6) & 0xF;
2300                rtl_set_bbreg(hw, ROFDM0_RXIQEXTANTA, 0xF0000000, reg);
2301        }
2302}
2303
2304static void _rtl92ee_phy_path_b_fill_iqk_matrix(struct ieee80211_hw *hw,
2305                                                bool b_iqk_ok, long result[][8],
2306                                                u8 final_candidate,
2307                                                bool btxonly)
2308{
2309        u32 oldval_1, x, tx1_a, reg;
2310        long y, tx1_c;
2311
2312        if (final_candidate == 0xFF) {
2313                return;
2314        } else if (b_iqk_ok) {
2315                oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
2316                                          MASKDWORD) >> 22) & 0x3FF;
2317                x = result[final_candidate][4];
2318                if ((x & 0x00000200) != 0)
2319                        x = x | 0xFFFFFC00;
2320                tx1_a = (x * oldval_1) >> 8;
2321                rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx1_a);
2322                rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(27),
2323                              ((x * oldval_1 >> 7) & 0x1));
2324                y = result[final_candidate][5];
2325                if ((y & 0x00000200) != 0)
2326                        y = y | 0xFFFFFC00;
2327                tx1_c = (y * oldval_1) >> 8;
2328                rtl_set_bbreg(hw, ROFDM0_XDTXAFE, 0xF0000000,
2329                              ((tx1_c & 0x3C0) >> 6));
2330                rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x003F0000,
2331                              (tx1_c & 0x3F));
2332                rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(25),
2333                              ((y * oldval_1 >> 7) & 0x1));
2334
2335                if (btxonly)
2336                        return;
2337
2338                reg = result[final_candidate][6];
2339                rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg);
2340
2341                reg = result[final_candidate][7] & 0x3F;
2342                rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg);
2343
2344                reg = (result[final_candidate][7] >> 6) & 0xF;
2345                rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, 0xF0000000, reg);
2346        }
2347}
2348
2349static void _rtl92ee_phy_save_adda_registers(struct ieee80211_hw *hw,
2350                                             u32 *addareg, u32 *addabackup,
2351                                             u32 registernum)
2352{
2353        u32 i;
2354
2355        for (i = 0; i < registernum; i++)
2356                addabackup[i] = rtl_get_bbreg(hw, addareg[i], MASKDWORD);
2357}
2358
2359static void _rtl92ee_phy_save_mac_registers(struct ieee80211_hw *hw,
2360                                            u32 *macreg, u32 *macbackup)
2361{
2362        struct rtl_priv *rtlpriv = rtl_priv(hw);
2363        u32 i;
2364
2365        for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
2366                macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]);
2367
2368        macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]);
2369}
2370
2371static void _rtl92ee_phy_reload_adda_registers(struct ieee80211_hw *hw,
2372                                               u32 *addareg, u32 *addabackup,
2373                                               u32 regiesternum)
2374{
2375        u32 i;
2376
2377        for (i = 0; i < regiesternum; i++)
2378                rtl_set_bbreg(hw, addareg[i], MASKDWORD, addabackup[i]);
2379}
2380
2381static void _rtl92ee_phy_reload_mac_registers(struct ieee80211_hw *hw,
2382                                              u32 *macreg, u32 *macbackup)
2383{
2384        struct rtl_priv *rtlpriv = rtl_priv(hw);
2385        u32 i;
2386
2387        for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
2388                rtl_write_byte(rtlpriv, macreg[i], (u8)macbackup[i]);
2389        rtl_write_dword(rtlpriv, macreg[i], macbackup[i]);
2390}
2391
2392static void _rtl92ee_phy_path_adda_on(struct ieee80211_hw *hw, u32 *addareg,
2393                                      bool is_patha_on, bool is2t)
2394{
2395        u32 i;
2396
2397        for (i = 0; i < IQK_ADDA_REG_NUM; i++)
2398                rtl_set_bbreg(hw, addareg[i], MASKDWORD, 0x0fc01616);
2399}
2400
2401static void _rtl92ee_phy_mac_setting_calibration(struct ieee80211_hw *hw,
2402                                                 u32 *macreg, u32 *macbackup)
2403{
2404        rtl_set_bbreg(hw, 0x520, 0x00ff0000, 0xff);
2405}
2406
2407static void _rtl92ee_phy_path_a_standby(struct ieee80211_hw *hw)
2408{
2409        rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0);
2410        rtl_set_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK, 0x10000);
2411        rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
2412}
2413
2414static bool _rtl92ee_phy_simularity_compare(struct ieee80211_hw *hw,
2415                                            long result[][8], u8 c1, u8 c2)
2416{
2417        u32 i, j, diff, simularity_bitmap, bound;
2418
2419        u8 final_candidate[2] = { 0xFF, 0xFF };
2420        bool bresult = true/*, is2t = true*/;
2421        s32 tmp1, tmp2;
2422
2423        bound = 8;
2424
2425        simularity_bitmap = 0;
2426
2427        for (i = 0; i < bound; i++) {
2428                if ((i == 1) || (i == 3) || (i == 5) || (i == 7)) {
2429                        if ((result[c1][i] & 0x00000200) != 0)
2430                                tmp1 = result[c1][i] | 0xFFFFFC00;
2431                        else
2432                                tmp1 = result[c1][i];
2433
2434                        if ((result[c2][i] & 0x00000200) != 0)
2435                                tmp2 = result[c2][i] | 0xFFFFFC00;
2436                        else
2437                                tmp2 = result[c2][i];
2438                } else {
2439                        tmp1 = result[c1][i];
2440                        tmp2 = result[c2][i];
2441                }
2442
2443                diff = (tmp1 > tmp2) ? (tmp1 - tmp2) : (tmp2 - tmp1);
2444
2445                if (diff > MAX_TOLERANCE) {
2446                        if ((i == 2 || i == 6) && !simularity_bitmap) {
2447                                if (result[c1][i] + result[c1][i + 1] == 0)
2448                                        final_candidate[(i / 4)] = c2;
2449                                else if (result[c2][i] + result[c2][i + 1] == 0)
2450                                        final_candidate[(i / 4)] = c1;
2451                                else
2452                                        simularity_bitmap |= (1 << i);
2453                        } else {
2454                                simularity_bitmap |= (1 << i);
2455                        }
2456                }
2457        }
2458
2459        if (simularity_bitmap == 0) {
2460                for (i = 0; i < (bound / 4); i++) {
2461                        if (final_candidate[i] != 0xFF) {
2462                                for (j = i * 4; j < (i + 1) * 4 - 2; j++)
2463                                        result[3][j] =
2464                                                result[final_candidate[i]][j];
2465                                bresult = false;
2466                        }
2467                }
2468                return bresult;
2469        }
2470        if (!(simularity_bitmap & 0x03)) {/*path A TX OK*/
2471                for (i = 0; i < 2; i++)
2472                        result[3][i] = result[c1][i];
2473        }
2474        if (!(simularity_bitmap & 0x0c)) {/*path A RX OK*/
2475                for (i = 2; i < 4; i++)
2476                        result[3][i] = result[c1][i];
2477        }
2478        if (!(simularity_bitmap & 0x30)) {/*path B TX OK*/
2479                for (i = 4; i < 6; i++)
2480                        result[3][i] = result[c1][i];
2481        }
2482        if (!(simularity_bitmap & 0xc0)) {/*path B RX OK*/
2483                for (i = 6; i < 8; i++)
2484                        result[3][i] = result[c1][i];
2485        }
2486        return false;
2487}
2488
2489static void _rtl92ee_phy_iq_calibrate(struct ieee80211_hw *hw,
2490                                      long result[][8], u8 t, bool is2t)
2491{
2492        struct rtl_priv *rtlpriv = rtl_priv(hw);
2493        struct rtl_phy *rtlphy = &rtlpriv->phy;
2494        u32 i;
2495        u8 patha_ok, pathb_ok;
2496        u8 tmp_0xc50 = (u8)rtl_get_bbreg(hw, 0xc50, MASKBYTE0);
2497        u8 tmp_0xc58 = (u8)rtl_get_bbreg(hw, 0xc58, MASKBYTE0);
2498        u32 adda_reg[IQK_ADDA_REG_NUM] = {
2499                0x85c, 0xe6c, 0xe70, 0xe74,
2500                0xe78, 0xe7c, 0xe80, 0xe84,
2501                0xe88, 0xe8c, 0xed0, 0xed4,
2502                0xed8, 0xedc, 0xee0, 0xeec
2503        };
2504        u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
2505                0x522, 0x550, 0x551, 0x040
2506        };
2507        u32 iqk_bb_reg[IQK_BB_REG_NUM] = {
2508                ROFDM0_TRXPATHENABLE, ROFDM0_TRMUXPAR,
2509                RFPGA0_XCD_RFINTERFACESW, 0xb68, 0xb6c,
2510                0x870, 0x860,
2511                0x864, 0x800
2512        };
2513        const u32 retrycount = 2;
2514
2515        if (t == 0) {
2516                _rtl92ee_phy_save_adda_registers(hw, adda_reg,
2517                                                 rtlphy->adda_backup,
2518                                                 IQK_ADDA_REG_NUM);
2519                _rtl92ee_phy_save_mac_registers(hw, iqk_mac_reg,
2520                                                rtlphy->iqk_mac_backup);
2521                _rtl92ee_phy_save_adda_registers(hw, iqk_bb_reg,
2522                                                 rtlphy->iqk_bb_backup,
2523                                                 IQK_BB_REG_NUM);
2524        }
2525
2526        _rtl92ee_phy_path_adda_on(hw, adda_reg, true, is2t);
2527
2528        /*BB setting*/
2529        rtl_set_bbreg(hw, RFPGA0_RFMOD, BIT(24), 0x00);
2530        rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKDWORD, 0x03a05600);
2531        rtl_set_bbreg(hw, ROFDM0_TRMUXPAR, MASKDWORD, 0x000800e4);
2532        rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, MASKDWORD, 0x22208200);
2533
2534        rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BIT(10), 0x01);
2535        rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BIT(26), 0x01);
2536        rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, BIT(10), 0x01);
2537        rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, BIT(10), 0x01);
2538
2539        _rtl92ee_phy_mac_setting_calibration(hw, iqk_mac_reg,
2540                                             rtlphy->iqk_mac_backup);
2541        /* Page B init*/
2542        /* IQ calibration setting*/
2543        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
2544        rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
2545        rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
2546
2547        for (i = 0 ; i < retrycount ; i++) {
2548                patha_ok = _rtl92ee_phy_path_a_iqk(hw, is2t);
2549
2550                if (patha_ok == 0x01) {
2551                        RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
2552                                 "Path A Tx IQK Success!!\n");
2553                        result[t][0] = (rtl_get_bbreg(hw,
2554                                                      RTX_POWER_BEFORE_IQK_A,
2555                                                      MASKDWORD) & 0x3FF0000)
2556                                                      >> 16;
2557                        result[t][1] = (rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A,
2558                                                      MASKDWORD) & 0x3FF0000)
2559                                                      >> 16;
2560                        break;
2561                }
2562                RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
2563                         "Path A Tx IQK Fail!!, ret = 0x%x\n",
2564                         patha_ok);
2565        }
2566
2567        for (i = 0 ; i < retrycount ; i++) {
2568                patha_ok = _rtl92ee_phy_path_a_rx_iqk(hw, is2t);
2569
2570                if (patha_ok == 0x03) {
2571                        RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
2572                                 "Path A Rx IQK Success!!\n");
2573                        result[t][2] = (rtl_get_bbreg(hw,
2574                                                      RRX_POWER_BEFORE_IQK_A_2,
2575                                                      MASKDWORD) & 0x3FF0000)
2576                                                      >> 16;
2577                        result[t][3] = (rtl_get_bbreg(hw,
2578                                                      RRX_POWER_AFTER_IQK_A_2,
2579                                                      MASKDWORD) & 0x3FF0000)
2580                                                      >> 16;
2581                        break;
2582                }
2583                RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
2584                         "Path A Rx IQK Fail!!, ret = 0x%x\n",
2585                          patha_ok);
2586        }
2587
2588        if (0x00 == patha_ok)
2589                RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
2590                         "Path A IQK failed!!, ret = 0\n");
2591        if (is2t) {
2592                _rtl92ee_phy_path_a_standby(hw);
2593                /* Turn Path B ADDA on */
2594                _rtl92ee_phy_path_adda_on(hw, adda_reg, false, is2t);
2595
2596                /* IQ calibration setting */
2597                rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
2598                rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
2599                rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
2600
2601                for (i = 0 ; i < retrycount ; i++) {
2602                        pathb_ok = _rtl92ee_phy_path_b_iqk(hw);
2603                        if (pathb_ok == 0x01) {
2604                                RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
2605                                         "Path B Tx IQK Success!!\n");
2606                                result[t][4] = (rtl_get_bbreg(hw,
2607                                                        RTX_POWER_BEFORE_IQK_B,
2608                                                        MASKDWORD) & 0x3FF0000)
2609                                                        >> 16;
2610                                result[t][5] = (rtl_get_bbreg(hw,
2611                                                        RTX_POWER_AFTER_IQK_B,
2612                                                        MASKDWORD) & 0x3FF0000)
2613                                                        >> 16;
2614                                break;
2615                        }
2616                        RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
2617                                 "Path B Tx IQK Fail!!, ret = 0x%x\n",
2618                                 pathb_ok);
2619                }
2620
2621                for (i = 0 ; i < retrycount ; i++) {
2622                        pathb_ok = _rtl92ee_phy_path_b_rx_iqk(hw, is2t);
2623                        if (pathb_ok == 0x03) {
2624                                RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
2625                                         "Path B Rx IQK Success!!\n");
2626                                result[t][6] = (rtl_get_bbreg(hw,
2627                                                       RRX_POWER_BEFORE_IQK_B_2,
2628                                                       MASKDWORD) & 0x3FF0000)
2629                                                       >> 16;
2630                                result[t][7] = (rtl_get_bbreg(hw,
2631                                                       RRX_POWER_AFTER_IQK_B_2,
2632                                                       MASKDWORD) & 0x3FF0000)
2633                                                       >> 16;
2634                                break;
2635                        }
2636                        RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
2637                                 "Path B Rx IQK Fail!!, ret = 0x%x\n",
2638                                 pathb_ok);
2639                }
2640
2641                if (0x00 == pathb_ok)
2642                        RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
2643                                 "Path B IQK failed!!, ret = 0\n");
2644        }
2645        /* Back to BB mode, load original value */
2646        RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
2647                 "IQK:Back to BB mode, load original value!\n");
2648        rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0);
2649
2650        if (t != 0) {
2651                /* Reload ADDA power saving parameters */
2652                _rtl92ee_phy_reload_adda_registers(hw, adda_reg,
2653                                                   rtlphy->adda_backup,
2654                                                   IQK_ADDA_REG_NUM);
2655
2656                /* Reload MAC parameters */
2657                _rtl92ee_phy_reload_mac_registers(hw, iqk_mac_reg,
2658                                                  rtlphy->iqk_mac_backup);
2659
2660                _rtl92ee_phy_reload_adda_registers(hw, iqk_bb_reg,
2661                                                   rtlphy->iqk_bb_backup,
2662                                                   IQK_BB_REG_NUM);
2663
2664                /* Restore RX initial gain */
2665                rtl_set_bbreg(hw, 0xc50, MASKBYTE0, 0x50);
2666                rtl_set_bbreg(hw, 0xc50, MASKBYTE0, tmp_0xc50);
2667                if (is2t) {
2668                        rtl_set_bbreg(hw, 0xc50, MASKBYTE0, 0x50);
2669                        rtl_set_bbreg(hw, 0xc58, MASKBYTE0, tmp_0xc58);
2670                }
2671
2672                /* load 0xe30 IQC default value */
2673                rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x01008c00);
2674                rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x01008c00);
2675        }
2676}
2677
2678static void _rtl92ee_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
2679{
2680        u8 tmpreg;
2681        u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
2682        struct rtl_priv *rtlpriv = rtl_priv(hw);
2683
2684        tmpreg = rtl_read_byte(rtlpriv, 0xd03);
2685
2686        if ((tmpreg & 0x70) != 0)
2687                rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
2688        else
2689                rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
2690
2691        if ((tmpreg & 0x70) != 0) {
2692                rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS);
2693
2694                if (is2t)
2695                        rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00,
2696                                                  MASK12BITS);
2697
2698                rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS,
2699                              (rf_a_mode & 0x8FFFF) | 0x10000);
2700
2701                if (is2t)
2702                        rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
2703                                      (rf_b_mode & 0x8FFFF) | 0x10000);
2704        }
2705        lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS);
2706
2707        rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, lc_cal | 0x08000);
2708
2709        mdelay(100);
2710
2711        if ((tmpreg & 0x70) != 0) {
2712                rtl_write_byte(rtlpriv, 0xd03, tmpreg);
2713                rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode);
2714
2715                if (is2t)
2716                        rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
2717                                      rf_b_mode);
2718        } else {
2719                rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
2720        }
2721}
2722
2723static void _rtl92ee_phy_set_rfpath_switch(struct ieee80211_hw *hw,
2724                                           bool bmain, bool is2t)
2725{
2726        struct rtl_priv *rtlpriv = rtl_priv(hw);
2727        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2728        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2729
2730        RT_TRACE(rtlpriv, COMP_INIT , DBG_LOUD , "\n");
2731
2732        if (is_hal_stop(rtlhal)) {
2733                u8 u1btmp;
2734
2735                u1btmp = rtl_read_byte(rtlpriv, REG_LEDCFG0);
2736                rtl_write_byte(rtlpriv, REG_LEDCFG0, u1btmp | BIT(7));
2737                rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(13), 0x01);
2738        }
2739        if (is2t) {
2740                if (bmain)
2741                        rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
2742                                      BIT(5) | BIT(6), 0x1);
2743                else
2744                        rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
2745                                      BIT(5) | BIT(6), 0x2);
2746        } else {
2747                rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BIT(8) | BIT(9), 0);
2748                rtl_set_bbreg(hw, 0x914, MASKLWORD, 0x0201);
2749
2750                /* We use the RF definition of MAIN and AUX,
2751                 * left antenna and right antenna repectively.
2752                 * Default output at AUX.
2753                 */
2754                if (bmain) {
2755                        rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE,
2756                                      BIT(14) | BIT(13) | BIT(12), 0);
2757                        rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
2758                                      BIT(5) | BIT(4) | BIT(3), 0);
2759                        if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV)
2760                                rtl_set_bbreg(hw, RCONFIG_RAM64x16, BIT(31), 0);
2761                } else {
2762                        rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE,
2763                                      BIT(14) | BIT(13) | BIT(12), 1);
2764                        rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
2765                                      BIT(5) | BIT(4) | BIT(3), 1);
2766                        if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV)
2767                                rtl_set_bbreg(hw, RCONFIG_RAM64x16, BIT(31), 1);
2768                }
2769        }
2770}
2771
2772#undef IQK_ADDA_REG_NUM
2773#undef IQK_DELAY_TIME
2774
2775static u8 rtl92ee_get_rightchnlplace_for_iqk(u8 chnl)
2776{
2777        u8 channel_all[59] = {
2778                1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
2779                36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58,
2780                60, 62, 64, 100, 102, 104, 106, 108, 110, 112,
2781                114, 116, 118, 120, 122, 124, 126, 128, 130,
2782                132, 134, 136, 138, 140, 149, 151, 153, 155,
2783                157, 159, 161, 163, 165
2784        };
2785        u8 place = chnl;
2786
2787        if (chnl > 14) {
2788                for (place = 14; place < sizeof(channel_all); place++) {
2789                        if (channel_all[place] == chnl)
2790                                return place - 13;
2791                }
2792        }
2793
2794        return 0;
2795}
2796
2797void rtl92ee_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
2798{
2799        struct rtl_priv *rtlpriv = rtl_priv(hw);
2800        struct rtl_phy *rtlphy = &rtlpriv->phy;
2801        long result[4][8];
2802        u8 i, final_candidate;
2803        bool b_patha_ok, b_pathb_ok;
2804        long reg_e94, reg_e9c, reg_ea4, reg_eac;
2805        long reg_eb4, reg_ebc, reg_ec4, reg_ecc;
2806        bool is12simular, is13simular, is23simular;
2807        u8 idx;
2808        u32 iqk_bb_reg[IQK_BB_REG_NUM] = {
2809                ROFDM0_XARXIQIMBALANCE,
2810                ROFDM0_XBRXIQIMBALANCE,
2811                ROFDM0_ECCATHRESHOLD,
2812                ROFDM0_AGCRSSITABLE,
2813                ROFDM0_XATXIQIMBALANCE,
2814                ROFDM0_XBTXIQIMBALANCE,
2815                ROFDM0_XCTXAFE,
2816                ROFDM0_XDTXAFE,
2817                ROFDM0_RXIQEXTANTA
2818        };
2819
2820        if (b_recovery) {
2821                _rtl92ee_phy_reload_adda_registers(hw, iqk_bb_reg,
2822                                                   rtlphy->iqk_bb_backup, 9);
2823                return;
2824        }
2825
2826        for (i = 0; i < 8; i++) {
2827                result[0][i] = 0;
2828                result[1][i] = 0;
2829                result[2][i] = 0;
2830
2831                if ((i == 0) || (i == 2) || (i == 4)  || (i == 6))
2832                        result[3][i] = 0x100;
2833                else
2834                        result[3][i] = 0;
2835        }
2836        final_candidate = 0xff;
2837        b_patha_ok = false;
2838        b_pathb_ok = false;
2839        is12simular = false;
2840        is23simular = false;
2841        is13simular = false;
2842        for (i = 0; i < 3; i++) {
2843                _rtl92ee_phy_iq_calibrate(hw, result, i, true);
2844                if (i == 1) {
2845                        is12simular = _rtl92ee_phy_simularity_compare(hw,
2846                                                                      result,
2847                                                                      0, 1);
2848                        if (is12simular) {
2849                                final_candidate = 0;
2850                                break;
2851                        }
2852                }
2853
2854                if (i == 2) {
2855                        is13simular = _rtl92ee_phy_simularity_compare(hw,
2856                                                                      result,
2857                                                                      0, 2);
2858                        if (is13simular) {
2859                                final_candidate = 0;
2860                                break;
2861                        }
2862                        is23simular = _rtl92ee_phy_simularity_compare(hw,
2863                                                                      result,
2864                                                                      1, 2);
2865                        if (is23simular)
2866                                final_candidate = 1;
2867                        else
2868                                final_candidate = 3;
2869                }
2870        }
2871
2872        for (i = 0; i < 4; i++) {
2873                reg_e94 = result[i][0];
2874                reg_e9c = result[i][1];
2875                reg_ea4 = result[i][2];
2876                reg_eac = result[i][3];
2877                reg_eb4 = result[i][4];
2878                reg_ebc = result[i][5];
2879                reg_ec4 = result[i][6];
2880                reg_ecc = result[i][7];
2881        }
2882
2883        if (final_candidate != 0xff) {
2884                reg_e94 = result[final_candidate][0];
2885                rtlphy->reg_e94 = reg_e94;
2886                reg_e9c = result[final_candidate][1];
2887                rtlphy->reg_e9c = reg_e9c;
2888                reg_ea4 = result[final_candidate][2];
2889                reg_eac = result[final_candidate][3];
2890                reg_eb4 = result[final_candidate][4];
2891                rtlphy->reg_eb4 = reg_eb4;
2892                reg_ebc = result[final_candidate][5];
2893                rtlphy->reg_ebc = reg_ebc;
2894                reg_ec4 = result[final_candidate][6];
2895                reg_ecc = result[final_candidate][7];
2896                b_patha_ok = true;
2897                b_pathb_ok = true;
2898        } else {
2899                rtlphy->reg_e94 = 0x100;
2900                rtlphy->reg_eb4 = 0x100;
2901                rtlphy->reg_e9c = 0x0;
2902                rtlphy->reg_ebc = 0x0;
2903        }
2904
2905        if (reg_e94 != 0)
2906                _rtl92ee_phy_path_a_fill_iqk_matrix(hw, b_patha_ok, result,
2907                                                    final_candidate,
2908                                                    (reg_ea4 == 0));
2909
2910        _rtl92ee_phy_path_b_fill_iqk_matrix(hw, b_pathb_ok, result,
2911                                            final_candidate,
2912                                            (reg_ec4 == 0));
2913
2914        idx = rtl92ee_get_rightchnlplace_for_iqk(rtlphy->current_channel);
2915
2916        /* To Fix BSOD when final_candidate is 0xff */
2917        if (final_candidate < 4) {
2918                for (i = 0; i < IQK_MATRIX_REG_NUM; i++)
2919                        rtlphy->iqk_matrix[idx].value[0][i] =
2920                                result[final_candidate][i];
2921
2922                rtlphy->iqk_matrix[idx].iqk_done = true;
2923        }
2924        _rtl92ee_phy_save_adda_registers(hw, iqk_bb_reg,
2925                                         rtlphy->iqk_bb_backup, 9);
2926}
2927
2928void rtl92ee_phy_lc_calibrate(struct ieee80211_hw *hw)
2929{
2930        struct rtl_priv *rtlpriv = rtl_priv(hw);
2931        struct rtl_phy *rtlphy = &rtlpriv->phy;
2932        struct rtl_hal *rtlhal = &rtlpriv->rtlhal;
2933        u32 timeout = 2000, timecount = 0;
2934
2935        while (rtlpriv->mac80211.act_scanning && timecount < timeout) {
2936                udelay(50);
2937                timecount += 50;
2938        }
2939
2940        rtlphy->lck_inprogress = true;
2941        RTPRINT(rtlpriv, FINIT, INIT_IQK,
2942                "LCK:Start!!! currentband %x delay %d ms\n",
2943                 rtlhal->current_bandtype, timecount);
2944
2945        _rtl92ee_phy_lc_calibrate(hw, false);
2946
2947        rtlphy->lck_inprogress = false;
2948}
2949
2950void rtl92ee_phy_ap_calibrate(struct ieee80211_hw *hw, s8 delta)
2951{
2952}
2953
2954void rtl92ee_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
2955{
2956        _rtl92ee_phy_set_rfpath_switch(hw, bmain, false);
2957}
2958
2959bool rtl92ee_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
2960{
2961        struct rtl_priv *rtlpriv = rtl_priv(hw);
2962        struct rtl_phy *rtlphy = &rtlpriv->phy;
2963        bool postprocessing = false;
2964
2965        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2966                 "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
2967                  iotype, rtlphy->set_io_inprogress);
2968        do {
2969                switch (iotype) {
2970                case IO_CMD_RESUME_DM_BY_SCAN:
2971                        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2972                                 "[IO CMD] Resume DM after scan.\n");
2973                        postprocessing = true;
2974                        break;
2975                case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
2976                        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2977                                 "[IO CMD] Pause DM before scan.\n");
2978                        postprocessing = true;
2979                        break;
2980                default:
2981                        RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
2982                                 "switch case %#x not processed\n", iotype);
2983                        break;
2984                }
2985        } while (false);
2986        if (postprocessing && !rtlphy->set_io_inprogress) {
2987                rtlphy->set_io_inprogress = true;
2988                rtlphy->current_io_type = iotype;
2989        } else {
2990                return false;
2991        }
2992        rtl92ee_phy_set_io(hw);
2993        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype);
2994        return true;
2995}
2996
2997static void rtl92ee_phy_set_io(struct ieee80211_hw *hw)
2998{
2999        struct rtl_priv *rtlpriv = rtl_priv(hw);
3000        struct rtl_phy *rtlphy = &rtlpriv->phy;
3001        struct dig_t *dm_dig = &rtlpriv->dm_digtable;
3002
3003        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
3004                 "--->Cmd(%#x), set_io_inprogress(%d)\n",
3005                  rtlphy->current_io_type, rtlphy->set_io_inprogress);
3006        switch (rtlphy->current_io_type) {
3007        case IO_CMD_RESUME_DM_BY_SCAN:
3008                rtl92ee_dm_write_dig(hw, rtlphy->initgain_backup.xaagccore1);
3009                rtl92ee_dm_write_cck_cca_thres(hw, rtlphy->initgain_backup.cca);
3010                RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE , "no set txpower\n");
3011                rtl92ee_phy_set_txpower_level(hw, rtlphy->current_channel);
3012                break;
3013        case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
3014                /* 8192eebt */
3015                rtlphy->initgain_backup.xaagccore1 = dm_dig->cur_igvalue;
3016                rtl92ee_dm_write_dig(hw, 0x17);
3017                rtlphy->initgain_backup.cca = dm_dig->cur_cck_cca_thres;
3018                rtl92ee_dm_write_cck_cca_thres(hw, 0x40);
3019                break;
3020        default:
3021                RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
3022                         "switch case %#x not processed\n",
3023                         rtlphy->current_io_type);
3024                break;
3025        }
3026        rtlphy->set_io_inprogress = false;
3027        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
3028                 "(%#x)\n", rtlphy->current_io_type);
3029}
3030
3031static void rtl92ee_phy_set_rf_on(struct ieee80211_hw *hw)
3032{
3033        struct rtl_priv *rtlpriv = rtl_priv(hw);
3034
3035        rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
3036        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
3037        /*rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);*/
3038        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
3039        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
3040        rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
3041}
3042
3043static void _rtl92ee_phy_set_rf_sleep(struct ieee80211_hw *hw)
3044{
3045        struct rtl_priv *rtlpriv = rtl_priv(hw);
3046
3047        rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
3048        rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
3049
3050        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
3051        rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
3052}
3053
3054static bool _rtl92ee_phy_set_rf_power_state(struct ieee80211_hw *hw,
3055                                            enum rf_pwrstate rfpwr_state)
3056{
3057        struct rtl_priv *rtlpriv = rtl_priv(hw);
3058        struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
3059        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
3060        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
3061        bool bresult = true;
3062        u8 i, queue_id;
3063        struct rtl8192_tx_ring *ring = NULL;
3064
3065        switch (rfpwr_state) {
3066        case ERFON:
3067                if ((ppsc->rfpwr_state == ERFOFF) &&
3068                    RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
3069                        bool rtstatus;
3070                        u32 initializecount = 0;
3071
3072                        do {
3073                                initializecount++;
3074                                RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
3075                                         "IPS Set eRf nic enable\n");
3076                                rtstatus = rtl_ps_enable_nic(hw);
3077                        } while (!rtstatus && (initializecount < 10));
3078                        RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
3079                } else {
3080                        RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
3081                                 "Set ERFON sleeping:%d ms\n",
3082                                  jiffies_to_msecs(jiffies -
3083                                                   ppsc->last_sleep_jiffies));
3084                        ppsc->last_awake_jiffies = jiffies;
3085                        rtl92ee_phy_set_rf_on(hw);
3086                }
3087                if (mac->link_state == MAC80211_LINKED)
3088                        rtlpriv->cfg->ops->led_control(hw, LED_CTL_LINK);
3089                else
3090                        rtlpriv->cfg->ops->led_control(hw, LED_CTL_NO_LINK);
3091                break;
3092        case ERFOFF:
3093                for (queue_id = 0, i = 0;
3094                     queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
3095                        ring = &pcipriv->dev.tx_ring[queue_id];
3096                        if (queue_id == BEACON_QUEUE ||
3097                            skb_queue_len(&ring->queue) == 0) {
3098                                queue_id++;
3099                                continue;
3100                        } else {
3101                                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
3102                                         "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
3103                                         (i + 1), queue_id,
3104                                         skb_queue_len(&ring->queue));
3105
3106                                udelay(10);
3107                                i++;
3108                        }
3109                        if (i >= MAX_DOZE_WAITING_TIMES_9x) {
3110                                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
3111                                         "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
3112                                          MAX_DOZE_WAITING_TIMES_9x,
3113                                          queue_id,
3114                                          skb_queue_len(&ring->queue));
3115                                break;
3116                        }
3117                }
3118
3119                if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
3120                        RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
3121                                 "IPS Set eRf nic disable\n");
3122                        rtl_ps_disable_nic(hw);
3123                        RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
3124                } else {
3125                        if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
3126                                rtlpriv->cfg->ops->led_control(hw,
3127                                                        LED_CTL_NO_LINK);
3128                        } else {
3129                                rtlpriv->cfg->ops->led_control(hw,
3130                                                        LED_CTL_POWER_OFF);
3131                        }
3132                }
3133                break;
3134        case ERFSLEEP:
3135                if (ppsc->rfpwr_state == ERFOFF)
3136                        break;
3137                for (queue_id = 0, i = 0;
3138                     queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
3139                        ring = &pcipriv->dev.tx_ring[queue_id];
3140                        if (skb_queue_len(&ring->queue) == 0) {
3141                                queue_id++;
3142                                continue;
3143                        } else {
3144                                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
3145                                         "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
3146                                         (i + 1), queue_id,
3147                                         skb_queue_len(&ring->queue));
3148                                udelay(10);
3149                                i++;
3150                        }
3151                        if (i >= MAX_DOZE_WAITING_TIMES_9x) {
3152                                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
3153                                         "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
3154                                          MAX_DOZE_WAITING_TIMES_9x,
3155                                          queue_id,
3156                                          skb_queue_len(&ring->queue));
3157                                break;
3158                        }
3159                }
3160                RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
3161                         "Set ERFSLEEP awaked:%d ms\n",
3162                          jiffies_to_msecs(jiffies -
3163                                           ppsc->last_awake_jiffies));
3164                ppsc->last_sleep_jiffies = jiffies;
3165                _rtl92ee_phy_set_rf_sleep(hw);
3166                break;
3167        default:
3168                RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
3169                         "switch case %#x not processed\n", rfpwr_state);
3170                bresult = false;
3171                break;
3172        }
3173        if (bresult)
3174                ppsc->rfpwr_state = rfpwr_state;
3175        return bresult;
3176}
3177
3178bool rtl92ee_phy_set_rf_power_state(struct ieee80211_hw *hw,
3179                                    enum rf_pwrstate rfpwr_state)
3180{
3181        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
3182
3183        bool bresult = false;
3184
3185        if (rfpwr_state == ppsc->rfpwr_state)
3186                return bresult;
3187        bresult = _rtl92ee_phy_set_rf_power_state(hw, rfpwr_state);
3188        return bresult;
3189}
3190