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