linux/drivers/net/wireless/rtlwifi/rtl8821ae/phy.c
<<
>>
Prefs
   1/******************************************************************************
   2 *
   3 * Copyright(c) 2009-2010  Realtek Corporation.
   4 *
   5 * This program is free software; you can redistribute it and/or modify it
   6 * under the terms of version 2 of the GNU General Public License as
   7 * published by the Free Software Foundation.
   8 *
   9 * This program is distributed in the hope that it will be useful, but WITHOUT
  10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  12 * more details.
  13 *
  14 * 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#include "trx.h"
  36#include "../btcoexist/halbt_precomp.h"
  37#include "hw.h"
  38#include "../efuse.h"
  39
  40#define READ_NEXT_PAIR(array_table, v1, v2, i) \
  41        do { \
  42                i += 2; \
  43                v1 = array_table[i]; \
  44                v2 = array_table[i+1]; \
  45        } while (0)
  46
  47static u32 _rtl8821ae_phy_rf_serial_read(struct ieee80211_hw *hw,
  48                                         enum radio_path rfpath, u32 offset);
  49static void _rtl8821ae_phy_rf_serial_write(struct ieee80211_hw *hw,
  50                                           enum radio_path rfpath, u32 offset,
  51                                           u32 data);
  52static u32 _rtl8821ae_phy_calculate_bit_shift(u32 bitmask);
  53static bool _rtl8821ae_phy_bb8821a_config_parafile(struct ieee80211_hw *hw);
  54/*static bool _rtl8812ae_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);*/
  55static bool _rtl8821ae_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);
  56static bool _rtl8821ae_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
  57                                                     u8 configtype);
  58static bool _rtl8821ae_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
  59                                                       u8 configtype);
  60static void phy_init_bb_rf_register_definition(struct ieee80211_hw *hw);
  61
  62static long _rtl8821ae_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
  63                                            enum wireless_mode wirelessmode,
  64                                            u8 txpwridx);
  65static void rtl8821ae_phy_set_rf_on(struct ieee80211_hw *hw);
  66static void rtl8821ae_phy_set_io(struct ieee80211_hw *hw);
  67
  68static void rtl8812ae_fixspur(struct ieee80211_hw *hw,
  69                              enum ht_channel_width band_width, u8 channel)
  70{
  71        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
  72
  73        /*C cut Item12 ADC FIFO CLOCK*/
  74        if (IS_VENDOR_8812A_C_CUT(rtlhal->version)) {
  75                if (band_width == HT_CHANNEL_WIDTH_20_40 && channel == 11)
  76                        rtl_set_bbreg(hw, RRFMOD, 0xC00, 0x3);
  77                        /* 0x8AC[11:10] = 2'b11*/
  78                else
  79                        rtl_set_bbreg(hw, RRFMOD, 0xC00, 0x2);
  80                        /* 0x8AC[11:10] = 2'b10*/
  81
  82                /* <20120914, Kordan> A workarould to resolve
  83                 * 2480Mhz spur by setting ADC clock as 160M. (Asked by Binson)
  84                 */
  85                if (band_width == HT_CHANNEL_WIDTH_20 &&
  86                    (channel == 13 || channel == 14)) {
  87                        rtl_set_bbreg(hw, RRFMOD, 0x300, 0x3);
  88                        /*0x8AC[9:8] = 2'b11*/
  89                        rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 1);
  90                        /* 0x8C4[30] = 1*/
  91                } else if (band_width == HT_CHANNEL_WIDTH_20_40 &&
  92                           channel == 11) {
  93                        rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 1);
  94                        /*0x8C4[30] = 1*/
  95                } else if (band_width != HT_CHANNEL_WIDTH_80) {
  96                        rtl_set_bbreg(hw, RRFMOD, 0x300, 0x2);
  97                        /*0x8AC[9:8] = 2'b10*/
  98                        rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 0);
  99                        /*0x8C4[30] = 0*/
 100                }
 101        } else if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
 102                /* <20120914, Kordan> A workarould to resolve
 103                 * 2480Mhz spur by setting ADC clock as 160M.
 104                 */
 105                if (band_width == HT_CHANNEL_WIDTH_20 &&
 106                    (channel == 13 || channel == 14))
 107                        rtl_set_bbreg(hw, RRFMOD, 0x300, 0x3);
 108                        /*0x8AC[9:8] = 11*/
 109                else if (channel  <= 14) /*2.4G only*/
 110                        rtl_set_bbreg(hw, RRFMOD, 0x300, 0x2);
 111                        /*0x8AC[9:8] = 10*/
 112        }
 113}
 114
 115u32 rtl8821ae_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr,
 116                               u32 bitmask)
 117{
 118        struct rtl_priv *rtlpriv = rtl_priv(hw);
 119        u32 returnvalue, originalvalue, bitshift;
 120
 121        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
 122                 "regaddr(%#x), bitmask(%#x)\n",
 123                 regaddr, bitmask);
 124        originalvalue = rtl_read_dword(rtlpriv, regaddr);
 125        bitshift = _rtl8821ae_phy_calculate_bit_shift(bitmask);
 126        returnvalue = (originalvalue & bitmask) >> bitshift;
 127
 128        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
 129                 "BBR MASK=0x%x Addr[0x%x]=0x%x\n",
 130                 bitmask, regaddr, originalvalue);
 131        return returnvalue;
 132}
 133
 134void rtl8821ae_phy_set_bb_reg(struct ieee80211_hw *hw,
 135                              u32 regaddr, u32 bitmask, u32 data)
 136{
 137        struct rtl_priv *rtlpriv = rtl_priv(hw);
 138        u32 originalvalue, bitshift;
 139
 140        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
 141                 "regaddr(%#x), bitmask(%#x), data(%#x)\n",
 142                 regaddr, bitmask, data);
 143
 144        if (bitmask != MASKDWORD) {
 145                originalvalue = rtl_read_dword(rtlpriv, regaddr);
 146                bitshift = _rtl8821ae_phy_calculate_bit_shift(bitmask);
 147                data = ((originalvalue & (~bitmask)) |
 148                        ((data << bitshift) & bitmask));
 149        }
 150
 151        rtl_write_dword(rtlpriv, regaddr, data);
 152
 153        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
 154                 "regaddr(%#x), bitmask(%#x), data(%#x)\n",
 155                 regaddr, bitmask, data);
 156}
 157
 158u32 rtl8821ae_phy_query_rf_reg(struct ieee80211_hw *hw,
 159                               enum radio_path rfpath, u32 regaddr,
 160                               u32 bitmask)
 161{
 162        struct rtl_priv *rtlpriv = rtl_priv(hw);
 163        u32 original_value, readback_value, bitshift;
 164        unsigned long flags;
 165
 166        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
 167                 "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
 168                 regaddr, rfpath, bitmask);
 169
 170        spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
 171
 172        original_value = _rtl8821ae_phy_rf_serial_read(hw, rfpath, regaddr);
 173        bitshift = _rtl8821ae_phy_calculate_bit_shift(bitmask);
 174        readback_value = (original_value & bitmask) >> bitshift;
 175
 176        spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
 177
 178        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
 179                 "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n",
 180                 regaddr, rfpath, bitmask, original_value);
 181
 182        return readback_value;
 183}
 184
 185void rtl8821ae_phy_set_rf_reg(struct ieee80211_hw *hw,
 186                           enum radio_path rfpath,
 187                           u32 regaddr, u32 bitmask, u32 data)
 188{
 189        struct rtl_priv *rtlpriv = rtl_priv(hw);
 190        u32 original_value, bitshift;
 191        unsigned long flags;
 192
 193        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
 194                 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
 195                  regaddr, bitmask, data, rfpath);
 196
 197        spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
 198
 199        if (bitmask != RFREG_OFFSET_MASK) {
 200                original_value =
 201                   _rtl8821ae_phy_rf_serial_read(hw, rfpath, regaddr);
 202                bitshift = _rtl8821ae_phy_calculate_bit_shift(bitmask);
 203                data = ((original_value & (~bitmask)) | (data << bitshift));
 204        }
 205
 206        _rtl8821ae_phy_rf_serial_write(hw, rfpath, regaddr, data);
 207
 208        spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
 209
 210        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
 211                 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
 212                 regaddr, bitmask, data, rfpath);
 213}
 214
 215static u32 _rtl8821ae_phy_rf_serial_read(struct ieee80211_hw *hw,
 216                                         enum radio_path rfpath, u32 offset)
 217{
 218        struct rtl_priv *rtlpriv = rtl_priv(hw);
 219        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 220        bool is_pi_mode = false;
 221        u32 retvalue = 0;
 222
 223        /* 2009/06/17 MH We can not execute IO for power
 224        save or other accident mode.*/
 225        if (RT_CANNOT_IO(hw)) {
 226                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "return all one\n");
 227                return 0xFFFFFFFF;
 228        }
 229        /* <20120809, Kordan> CCA OFF(when entering),
 230                asked by James to avoid reading the wrong value.
 231            <20120828, Kordan> Toggling CCA would affect RF 0x0, skip it!*/
 232        if (offset != 0x0 &&
 233            !((rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) ||
 234            (IS_VENDOR_8812A_C_CUT(rtlhal->version))))
 235                rtl_set_bbreg(hw, RCCAONSEC, 0x8, 1);
 236        offset &= 0xff;
 237
 238        if (rfpath == RF90_PATH_A)
 239                is_pi_mode = (bool)rtl_get_bbreg(hw, 0xC00, 0x4);
 240        else if (rfpath == RF90_PATH_B)
 241                is_pi_mode = (bool)rtl_get_bbreg(hw, 0xE00, 0x4);
 242
 243        rtl_set_bbreg(hw, RHSSIREAD_8821AE, 0xff, offset);
 244
 245        if ((rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) ||
 246            (IS_VENDOR_8812A_C_CUT(rtlhal->version)))
 247                udelay(20);
 248
 249        if (is_pi_mode) {
 250                if (rfpath == RF90_PATH_A)
 251                        retvalue =
 252                          rtl_get_bbreg(hw, RA_PIREAD_8821A, BLSSIREADBACKDATA);
 253                else if (rfpath == RF90_PATH_B)
 254                        retvalue =
 255                          rtl_get_bbreg(hw, RB_PIREAD_8821A, BLSSIREADBACKDATA);
 256        } else {
 257                if (rfpath == RF90_PATH_A)
 258                        retvalue =
 259                          rtl_get_bbreg(hw, RA_SIREAD_8821A, BLSSIREADBACKDATA);
 260                else if (rfpath == RF90_PATH_B)
 261                        retvalue =
 262                          rtl_get_bbreg(hw, RB_SIREAD_8821A, BLSSIREADBACKDATA);
 263        }
 264
 265        /*<20120809, Kordan> CCA ON(when exiting),
 266         * asked by James to avoid reading the wrong value.
 267         *   <20120828, Kordan> Toggling CCA would affect RF 0x0, skip it!
 268         */
 269        if (offset != 0x0 &&
 270            !((rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) ||
 271            (IS_VENDOR_8812A_C_CUT(rtlhal->version))))
 272                rtl_set_bbreg(hw, RCCAONSEC, 0x8, 0);
 273        return retvalue;
 274}
 275
 276static void _rtl8821ae_phy_rf_serial_write(struct ieee80211_hw *hw,
 277                                           enum radio_path rfpath, u32 offset,
 278                                           u32 data)
 279{
 280        struct rtl_priv *rtlpriv = rtl_priv(hw);
 281        struct rtl_phy *rtlphy = &rtlpriv->phy;
 282        struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
 283        u32 data_and_addr;
 284        u32 newoffset;
 285
 286        if (RT_CANNOT_IO(hw)) {
 287                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "stop\n");
 288                return;
 289        }
 290        offset &= 0xff;
 291        newoffset = offset;
 292        data_and_addr = ((newoffset << 20) |
 293                         (data & 0x000fffff)) & 0x0fffffff;
 294        rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr);
 295        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
 296                 "RFW-%d Addr[0x%x]=0x%x\n",
 297                 rfpath, pphyreg->rf3wire_offset, data_and_addr);
 298}
 299
 300static u32 _rtl8821ae_phy_calculate_bit_shift(u32 bitmask)
 301{
 302        u32 i;
 303
 304        for (i = 0; i <= 31; i++) {
 305                if (((bitmask >> i) & 0x1) == 1)
 306                        break;
 307        }
 308        return i;
 309}
 310
 311bool rtl8821ae_phy_mac_config(struct ieee80211_hw *hw)
 312{
 313        bool rtstatus = 0;
 314
 315        rtstatus = _rtl8821ae_phy_config_mac_with_headerfile(hw);
 316
 317        return rtstatus;
 318}
 319
 320bool rtl8821ae_phy_bb_config(struct ieee80211_hw *hw)
 321{
 322        bool rtstatus = true;
 323        struct rtl_priv *rtlpriv = rtl_priv(hw);
 324        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 325        struct rtl_phy *rtlphy = &rtlpriv->phy;
 326        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 327        u8 regval;
 328        u8 crystal_cap;
 329
 330        phy_init_bb_rf_register_definition(hw);
 331
 332        regval = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN);
 333        regval |= FEN_PCIEA;
 334        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, regval);
 335        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN,
 336                       regval | FEN_BB_GLB_RSTN | FEN_BBRSTB);
 337
 338        rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x7);
 339        rtl_write_byte(rtlpriv, REG_OPT_CTRL + 2, 0x7);
 340
 341        rtstatus = _rtl8821ae_phy_bb8821a_config_parafile(hw);
 342
 343        if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
 344                crystal_cap = rtlefuse->crystalcap & 0x3F;
 345                rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0x7FF80000,
 346                              (crystal_cap | (crystal_cap << 6)));
 347        } else {
 348                crystal_cap = rtlefuse->crystalcap & 0x3F;
 349                rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000,
 350                              (crystal_cap | (crystal_cap << 6)));
 351        }
 352        rtlphy->reg_837 = rtl_read_byte(rtlpriv, 0x837);
 353
 354        return rtstatus;
 355}
 356
 357bool rtl8821ae_phy_rf_config(struct ieee80211_hw *hw)
 358{
 359        return rtl8821ae_phy_rf6052_config(hw);
 360}
 361
 362u32 phy_get_tx_swing_8812A(struct ieee80211_hw *hw, u8  band,
 363                           u8 rf_path)
 364{
 365        struct rtl_priv *rtlpriv = rtl_priv(hw);
 366        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 367        struct rtl_dm *rtldm = rtl_dm(rtlpriv);
 368        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 369        char reg_swing_2g = -1;/* 0xff; */
 370        char reg_swing_5g = -1;/* 0xff; */
 371        char swing_2g = -1 * reg_swing_2g;
 372        char swing_5g = -1 * reg_swing_5g;
 373        u32  out = 0x200;
 374        const char auto_temp = -1;
 375
 376        RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
 377                 "===> PHY_GetTxBBSwing_8812A, bbSwing_2G: %d, bbSwing_5G: %d,autoload_failflag=%d.\n",
 378                 (int)swing_2g, (int)swing_5g,
 379                 (int)rtlefuse->autoload_failflag);
 380
 381        if (rtlefuse->autoload_failflag) {
 382                if (band == BAND_ON_2_4G) {
 383                        rtldm->swing_diff_2g = swing_2g;
 384                        if (swing_2g == 0) {
 385                                out = 0x200; /* 0 dB */
 386                        } else if (swing_2g == -3) {
 387                                out = 0x16A; /* -3 dB */
 388                        } else if (swing_2g == -6) {
 389                                out = 0x101; /* -6 dB */
 390                        } else if (swing_2g == -9) {
 391                                out = 0x0B6; /* -9 dB */
 392                        } else {
 393                                rtldm->swing_diff_2g = 0;
 394                                out = 0x200;
 395                        }
 396                } else if (band == BAND_ON_5G) {
 397                        rtldm->swing_diff_5g = swing_5g;
 398                        if (swing_5g == 0) {
 399                                out = 0x200; /* 0 dB */
 400                        } else if (swing_5g == -3) {
 401                                out = 0x16A; /* -3 dB */
 402                        } else if (swing_5g == -6) {
 403                                out = 0x101; /* -6 dB */
 404                        } else if (swing_5g == -9) {
 405                                out = 0x0B6; /* -9 dB */
 406                        } else {
 407                                if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
 408                                        rtldm->swing_diff_5g = -3;
 409                                        out = 0x16A;
 410                                } else {
 411                                        rtldm->swing_diff_5g = 0;
 412                                        out = 0x200;
 413                                }
 414                        }
 415                } else {
 416                        rtldm->swing_diff_2g = -3;
 417                        rtldm->swing_diff_5g = -3;
 418                        out = 0x16A; /* -3 dB */
 419                }
 420        } else {
 421            u32 swing = 0, swing_a = 0, swing_b = 0;
 422
 423            if (band == BAND_ON_2_4G) {
 424                        if (reg_swing_2g == auto_temp) {
 425                                efuse_shadow_read(hw, 1, 0xC6, (u32 *)&swing);
 426                                swing = (swing == 0xFF) ? 0x00 : swing;
 427                        } else if (swing_2g ==  0) {
 428                                swing = 0x00; /* 0 dB */
 429                        } else if (swing_2g == -3) {
 430                                swing = 0x05; /* -3 dB */
 431                        } else if (swing_2g == -6) {
 432                                swing = 0x0A; /* -6 dB */
 433                        } else if (swing_2g == -9) {
 434                                swing = 0xFF; /* -9 dB */
 435                        } else {
 436                                swing = 0x00;
 437                        }
 438                } else {
 439                        if (reg_swing_5g == auto_temp) {
 440                                efuse_shadow_read(hw, 1, 0xC7, (u32 *)&swing);
 441                                swing = (swing == 0xFF) ? 0x00 : swing;
 442                        } else if (swing_5g ==  0) {
 443                                swing = 0x00; /* 0 dB */
 444                        } else if (swing_5g == -3) {
 445                                swing = 0x05; /* -3 dB */
 446                        } else if (swing_5g == -6) {
 447                                swing = 0x0A; /* -6 dB */
 448                        } else if (swing_5g == -9) {
 449                                swing = 0xFF; /* -9 dB */
 450                        } else {
 451                                swing = 0x00;
 452                        }
 453                }
 454
 455                swing_a = (swing & 0x3) >> 0; /* 0xC6/C7[1:0] */
 456                swing_b = (swing & 0xC) >> 2; /* 0xC6/C7[3:2] */
 457                RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
 458                         "===> PHY_GetTxBBSwing_8812A, swingA: 0x%X, swingB: 0x%X\n",
 459                         swing_a, swing_b);
 460
 461                /* 3 Path-A */
 462                if (swing_a == 0x0) {
 463                        if (band == BAND_ON_2_4G)
 464                                rtldm->swing_diff_2g = 0;
 465                        else
 466                                rtldm->swing_diff_5g = 0;
 467                        out = 0x200; /* 0 dB */
 468                } else if (swing_a == 0x1) {
 469                        if (band == BAND_ON_2_4G)
 470                                rtldm->swing_diff_2g = -3;
 471                        else
 472                                rtldm->swing_diff_5g = -3;
 473                        out = 0x16A; /* -3 dB */
 474                } else if (swing_a == 0x2) {
 475                        if (band == BAND_ON_2_4G)
 476                                rtldm->swing_diff_2g = -6;
 477                        else
 478                                rtldm->swing_diff_5g = -6;
 479                        out = 0x101; /* -6 dB */
 480                } else if (swing_a == 0x3) {
 481                        if (band == BAND_ON_2_4G)
 482                                rtldm->swing_diff_2g = -9;
 483                        else
 484                                rtldm->swing_diff_5g = -9;
 485                        out = 0x0B6; /* -9 dB */
 486                }
 487                /* 3 Path-B */
 488                if (swing_b == 0x0) {
 489                        if (band == BAND_ON_2_4G)
 490                                rtldm->swing_diff_2g = 0;
 491                        else
 492                                rtldm->swing_diff_5g = 0;
 493                        out = 0x200; /* 0 dB */
 494                } else if (swing_b == 0x1) {
 495                        if (band == BAND_ON_2_4G)
 496                                rtldm->swing_diff_2g = -3;
 497                        else
 498                                rtldm->swing_diff_5g = -3;
 499                        out = 0x16A; /* -3 dB */
 500                } else if (swing_b == 0x2) {
 501                        if (band == BAND_ON_2_4G)
 502                                rtldm->swing_diff_2g = -6;
 503                        else
 504                                rtldm->swing_diff_5g = -6;
 505                        out = 0x101; /* -6 dB */
 506                } else if (swing_b == 0x3) {
 507                        if (band == BAND_ON_2_4G)
 508                                rtldm->swing_diff_2g = -9;
 509                        else
 510                                rtldm->swing_diff_5g = -9;
 511                        out = 0x0B6; /* -9 dB */
 512                }
 513        }
 514
 515        RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
 516                 "<=== PHY_GetTxBBSwing_8812A, out = 0x%X\n", out);
 517         return out;
 518}
 519
 520void rtl8821ae_phy_switch_wirelessband(struct ieee80211_hw *hw, u8 band)
 521{
 522        struct rtl_priv *rtlpriv = rtl_priv(hw);
 523        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 524        struct rtl_dm *rtldm = rtl_dm(rtlpriv);
 525        u8 current_band = rtlhal->current_bandtype;
 526        u32 txpath, rxpath;
 527        char bb_diff_between_band;
 528
 529        txpath = rtl8821ae_phy_query_bb_reg(hw, RTXPATH, 0xf0);
 530        rxpath = rtl8821ae_phy_query_bb_reg(hw, RCCK_RX, 0x0f000000);
 531        rtlhal->current_bandtype = (enum band_type) band;
 532        /* reconfig BB/RF according to wireless mode */
 533        if (rtlhal->current_bandtype == BAND_ON_2_4G) {
 534                /* BB & RF Config */
 535                rtl_set_bbreg(hw, ROFDMCCKEN, BOFDMEN|BCCKEN, 0x03);
 536
 537                if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
 538                        /* 0xCB0[15:12] = 0x7 (LNA_On)*/
 539                        rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xF000, 0x7);
 540                        /* 0xCB0[7:4] = 0x7 (PAPE_A)*/
 541                        rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xF0, 0x7);
 542                }
 543
 544                if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
 545                        /*0x834[1:0] = 0x1*/
 546                        rtl_set_bbreg(hw, 0x834, 0x3, 0x1);
 547                }
 548
 549                if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
 550                        /* 0xC1C[11:8] = 0 */
 551                        rtl_set_bbreg(hw, RA_TXSCALE, 0xF00, 0);
 552                } else {
 553                        /* 0x82C[1:0] = 2b'00 */
 554                        rtl_set_bbreg(hw, 0x82c, 0x3, 0);
 555                }
 556                if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
 557                        rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD,
 558                                      0x77777777);
 559                        rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD,
 560                                      0x77777777);
 561                        rtl_set_bbreg(hw, RA_RFE_INV, 0x3ff00000, 0x000);
 562                        rtl_set_bbreg(hw, RB_RFE_INV, 0x3ff00000, 0x000);
 563                }
 564
 565                rtl_set_bbreg(hw, RTXPATH, 0xf0, 0x1);
 566                rtl_set_bbreg(hw, RCCK_RX, 0x0f000000, 0x1);
 567
 568                rtl_write_byte(rtlpriv, REG_CCK_CHECK, 0x0);
 569        } else {/* 5G band */
 570                u16 count, reg_41a;
 571
 572                if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
 573                        /*0xCB0[15:12] = 0x5 (LNA_On)*/
 574                        rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xF000, 0x5);
 575                        /*0xCB0[7:4] = 0x4 (PAPE_A)*/
 576                        rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xF0, 0x4);
 577                }
 578                /*CCK_CHECK_en*/
 579                rtl_write_byte(rtlpriv, REG_CCK_CHECK, 0x80);
 580
 581                count = 0;
 582                reg_41a = rtl_read_word(rtlpriv, REG_TXPKT_EMPTY);
 583                RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
 584                         "Reg41A value %d", reg_41a);
 585                reg_41a &= 0x30;
 586                while ((reg_41a != 0x30) && (count < 50)) {
 587                        udelay(50);
 588                        RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, "Delay 50us\n");
 589
 590                        reg_41a = rtl_read_word(rtlpriv, REG_TXPKT_EMPTY);
 591                        reg_41a &= 0x30;
 592                        count++;
 593                        RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
 594                                 "Reg41A value %d", reg_41a);
 595                }
 596                if (count != 0)
 597                        RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD,
 598                                 "PHY_SwitchWirelessBand8812(): Switch to 5G Band. Count = %d reg41A=0x%x\n",
 599                                 count, reg_41a);
 600
 601                /* 2012/02/01, Sinda add registry to switch workaround
 602                without long-run verification for scan issue. */
 603                rtl_set_bbreg(hw, ROFDMCCKEN, BOFDMEN|BCCKEN, 0x03);
 604
 605                if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
 606                        /*0x834[1:0] = 0x2*/
 607                        rtl_set_bbreg(hw, 0x834, 0x3, 0x2);
 608                }
 609
 610                if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
 611                        /* AGC table select */
 612                        /* 0xC1C[11:8] = 1*/
 613                        rtl_set_bbreg(hw, RA_TXSCALE, 0xF00, 1);
 614                } else
 615                        /* 0x82C[1:0] = 2'b00 */
 616                        rtl_set_bbreg(hw, 0x82c, 0x3, 1);
 617
 618                if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
 619                        rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD,
 620                                      0x77337777);
 621                        rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD,
 622                                      0x77337777);
 623                        rtl_set_bbreg(hw, RA_RFE_INV, 0x3ff00000, 0x010);
 624                        rtl_set_bbreg(hw, RB_RFE_INV, 0x3ff00000, 0x010);
 625                }
 626
 627                rtl_set_bbreg(hw, RTXPATH, 0xf0, 0);
 628                rtl_set_bbreg(hw, RCCK_RX, 0x0f000000, 0xf);
 629
 630                RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD,
 631                         "==>PHY_SwitchWirelessBand8812() BAND_ON_5G settings OFDM index 0x%x\n",
 632                         rtlpriv->dm.ofdm_index[RF90_PATH_A]);
 633        }
 634
 635        if ((rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) ||
 636            (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)) {
 637                /* 0xC1C[31:21] */
 638                rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000,
 639                              phy_get_tx_swing_8812A(hw, band, RF90_PATH_A));
 640                /* 0xE1C[31:21] */
 641                rtl_set_bbreg(hw, RB_TXSCALE, 0xFFE00000,
 642                              phy_get_tx_swing_8812A(hw, band, RF90_PATH_B));
 643
 644                /* <20121005, Kordan> When TxPowerTrack is ON,
 645                 *      we should take care of the change of BB swing.
 646                 *   That is, reset all info to trigger Tx power tracking.
 647                 */
 648                if (band != current_band) {
 649                        bb_diff_between_band =
 650                                (rtldm->swing_diff_2g - rtldm->swing_diff_5g);
 651                        bb_diff_between_band = (band == BAND_ON_2_4G) ?
 652                                                bb_diff_between_band :
 653                                                (-1 * bb_diff_between_band);
 654                        rtldm->default_ofdm_index += bb_diff_between_band * 2;
 655                }
 656                rtl8821ae_dm_clear_txpower_tracking_state(hw);
 657        }
 658
 659        RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
 660                 "<==rtl8821ae_phy_switch_wirelessband():Switch Band OK.\n");
 661        return;
 662}
 663
 664static bool _rtl8821ae_check_condition(struct ieee80211_hw *hw,
 665                                       const u32 condition)
 666{
 667        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 668        u32 _board = rtlefuse->board_type; /*need efuse define*/
 669        u32 _interface = 0x01; /* ODM_ITRF_PCIE */
 670        u32 _platform = 0x08;/* ODM_WIN */
 671        u32 cond = condition;
 672
 673        if (condition == 0xCDCDCDCD)
 674                return true;
 675
 676        cond = condition & 0xFF;
 677        if ((_board != cond) && cond != 0xFF)
 678                return false;
 679
 680        cond = condition & 0xFF00;
 681        cond = cond >> 8;
 682        if ((_interface & cond) == 0 && cond != 0x07)
 683                return false;
 684
 685        cond = condition & 0xFF0000;
 686        cond = cond >> 16;
 687        if ((_platform & cond) == 0 && cond != 0x0F)
 688                return false;
 689        return true;
 690}
 691
 692static void _rtl8821ae_config_rf_reg(struct ieee80211_hw *hw,
 693                                     u32 addr, u32 data,
 694                                     enum radio_path rfpath, u32 regaddr)
 695{
 696        if (addr == 0xfe || addr == 0xffe) {
 697                /* In order not to disturb BT music when
 698                 * wifi init.(1ant NIC only)
 699                 */
 700                mdelay(50);
 701        } else {
 702                rtl_set_rfreg(hw, rfpath, regaddr, RFREG_OFFSET_MASK, data);
 703                udelay(1);
 704        }
 705}
 706
 707static void _rtl8821ae_config_rf_radio_a(struct ieee80211_hw *hw,
 708                                         u32 addr, u32 data)
 709{
 710        u32 content = 0x1000; /*RF Content: radio_a_txt*/
 711        u32 maskforphyset = (u32)(content & 0xE000);
 712
 713        _rtl8821ae_config_rf_reg(hw, addr, data,
 714                                 RF90_PATH_A, addr | maskforphyset);
 715}
 716
 717static void _rtl8821ae_config_rf_radio_b(struct ieee80211_hw *hw,
 718                                         u32 addr, u32 data)
 719{
 720        u32 content = 0x1001; /*RF Content: radio_b_txt*/
 721        u32 maskforphyset = (u32)(content & 0xE000);
 722
 723        _rtl8821ae_config_rf_reg(hw, addr, data,
 724                                 RF90_PATH_B, addr | maskforphyset);
 725}
 726
 727static void _rtl8821ae_config_bb_reg(struct ieee80211_hw *hw,
 728                                     u32 addr, u32 data)
 729{
 730        if (addr == 0xfe)
 731                mdelay(50);
 732        else if (addr == 0xfd)
 733                mdelay(5);
 734        else if (addr == 0xfc)
 735                mdelay(1);
 736        else if (addr == 0xfb)
 737                udelay(50);
 738        else if (addr == 0xfa)
 739                udelay(5);
 740        else if (addr == 0xf9)
 741                udelay(1);
 742        else
 743                rtl_set_bbreg(hw, addr, MASKDWORD, data);
 744
 745        udelay(1);
 746}
 747
 748static void _rtl8821ae_phy_init_tx_power_by_rate(struct ieee80211_hw *hw)
 749{
 750        struct rtl_priv *rtlpriv = rtl_priv(hw);
 751        struct rtl_phy *rtlphy = &rtlpriv->phy;
 752        u8 band, rfpath, txnum, rate_section;
 753
 754        for (band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band)
 755                for (rfpath = 0; rfpath < TX_PWR_BY_RATE_NUM_RF; ++rfpath)
 756                        for (txnum = 0; txnum < TX_PWR_BY_RATE_NUM_RF; ++txnum)
 757                                for (rate_section = 0;
 758                                     rate_section < TX_PWR_BY_RATE_NUM_SECTION;
 759                                     ++rate_section)
 760                                        rtlphy->tx_power_by_rate_offset[band]
 761                                            [rfpath][txnum][rate_section] = 0;
 762}
 763
 764static void _rtl8821ae_phy_set_txpower_by_rate_base(struct ieee80211_hw *hw,
 765                                          u8 band, u8 path,
 766                                          u8 rate_section,
 767                                          u8 txnum, u8 value)
 768{
 769        struct rtl_priv *rtlpriv = rtl_priv(hw);
 770        struct rtl_phy *rtlphy = &rtlpriv->phy;
 771
 772        if (path > RF90_PATH_D) {
 773                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 774                        "Invalid Rf Path %d in phy_SetTxPowerByRatBase()\n", path);
 775                return;
 776        }
 777
 778        if (band == BAND_ON_2_4G) {
 779                switch (rate_section) {
 780                case CCK:
 781                        rtlphy->txpwr_by_rate_base_24g[path][txnum][0] = value;
 782                        break;
 783                case OFDM:
 784                        rtlphy->txpwr_by_rate_base_24g[path][txnum][1] = value;
 785                        break;
 786                case HT_MCS0_MCS7:
 787                        rtlphy->txpwr_by_rate_base_24g[path][txnum][2] = value;
 788                        break;
 789                case HT_MCS8_MCS15:
 790                        rtlphy->txpwr_by_rate_base_24g[path][txnum][3] = value;
 791                        break;
 792                case VHT_1SSMCS0_1SSMCS9:
 793                        rtlphy->txpwr_by_rate_base_24g[path][txnum][4] = value;
 794                        break;
 795                case VHT_2SSMCS0_2SSMCS9:
 796                        rtlphy->txpwr_by_rate_base_24g[path][txnum][5] = value;
 797                        break;
 798                default:
 799                        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 800                                 "Invalid RateSection %d in Band 2.4G,Rf Path %d, %dTx in PHY_SetTxPowerByRateBase()\n",
 801                                 rate_section, path, txnum);
 802                        break;
 803                }
 804        } else if (band == BAND_ON_5G) {
 805                switch (rate_section) {
 806                case OFDM:
 807                        rtlphy->txpwr_by_rate_base_5g[path][txnum][0] = value;
 808                        break;
 809                case HT_MCS0_MCS7:
 810                        rtlphy->txpwr_by_rate_base_5g[path][txnum][1] = value;
 811                        break;
 812                case HT_MCS8_MCS15:
 813                        rtlphy->txpwr_by_rate_base_5g[path][txnum][2] = value;
 814                        break;
 815                case VHT_1SSMCS0_1SSMCS9:
 816                        rtlphy->txpwr_by_rate_base_5g[path][txnum][3] = value;
 817                        break;
 818                case VHT_2SSMCS0_2SSMCS9:
 819                        rtlphy->txpwr_by_rate_base_5g[path][txnum][4] = value;
 820                        break;
 821                default:
 822                        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 823                                "Invalid RateSection %d in Band 5G, Rf Path %d, %dTx in PHY_SetTxPowerByRateBase()\n",
 824                                rate_section, path, txnum);
 825                        break;
 826                }
 827        } else {
 828                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 829                        "Invalid Band %d in PHY_SetTxPowerByRateBase()\n", band);
 830        }
 831}
 832
 833static u8 _rtl8821ae_phy_get_txpower_by_rate_base(struct ieee80211_hw *hw,
 834                                                  u8 band, u8 path,
 835                                                  u8 txnum, u8 rate_section)
 836{
 837        struct rtl_priv *rtlpriv = rtl_priv(hw);
 838        struct rtl_phy *rtlphy = &rtlpriv->phy;
 839        u8 value = 0;
 840
 841        if (path > RF90_PATH_D) {
 842                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 843                         "Invalid Rf Path %d in PHY_GetTxPowerByRateBase()\n",
 844                         path);
 845                return 0;
 846        }
 847
 848        if (band == BAND_ON_2_4G) {
 849                switch (rate_section) {
 850                case CCK:
 851                        value = rtlphy->txpwr_by_rate_base_24g[path][txnum][0];
 852                        break;
 853                case OFDM:
 854                        value = rtlphy->txpwr_by_rate_base_24g[path][txnum][1];
 855                        break;
 856                case HT_MCS0_MCS7:
 857                        value = rtlphy->txpwr_by_rate_base_24g[path][txnum][2];
 858                        break;
 859                case HT_MCS8_MCS15:
 860                        value = rtlphy->txpwr_by_rate_base_24g[path][txnum][3];
 861                        break;
 862                case VHT_1SSMCS0_1SSMCS9:
 863                        value = rtlphy->txpwr_by_rate_base_24g[path][txnum][4];
 864                        break;
 865                case VHT_2SSMCS0_2SSMCS9:
 866                        value = rtlphy->txpwr_by_rate_base_24g[path][txnum][5];
 867                        break;
 868                default:
 869                        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 870                                 "Invalid RateSection %d in Band 2.4G, Rf Path %d, %dTx in PHY_GetTxPowerByRateBase()\n",
 871                                 rate_section, path, txnum);
 872                        break;
 873                }
 874        } else if (band == BAND_ON_5G) {
 875                switch (rate_section) {
 876                case OFDM:
 877                        value = rtlphy->txpwr_by_rate_base_5g[path][txnum][0];
 878                        break;
 879                case HT_MCS0_MCS7:
 880                        value = rtlphy->txpwr_by_rate_base_5g[path][txnum][1];
 881                        break;
 882                case HT_MCS8_MCS15:
 883                        value = rtlphy->txpwr_by_rate_base_5g[path][txnum][2];
 884                        break;
 885                case VHT_1SSMCS0_1SSMCS9:
 886                        value = rtlphy->txpwr_by_rate_base_5g[path][txnum][3];
 887                        break;
 888                case VHT_2SSMCS0_2SSMCS9:
 889                        value = rtlphy->txpwr_by_rate_base_5g[path][txnum][4];
 890                        break;
 891                default:
 892                        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 893                                 "Invalid RateSection %d in Band 5G, Rf Path %d, %dTx in PHY_GetTxPowerByRateBase()\n",
 894                                 rate_section, path, txnum);
 895                        break;
 896                }
 897        } else {
 898                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 899                         "Invalid Band %d in PHY_GetTxPowerByRateBase()\n", band);
 900        }
 901
 902        return value;
 903}
 904
 905static void _rtl8821ae_phy_store_txpower_by_rate_base(struct ieee80211_hw *hw)
 906{
 907        struct rtl_priv *rtlpriv = rtl_priv(hw);
 908        struct rtl_phy *rtlphy = &rtlpriv->phy;
 909        u16 rawValue = 0;
 910        u8 base = 0, path = 0;
 911
 912        for (path = RF90_PATH_A; path <= RF90_PATH_B; ++path) {
 913                rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_1TX][0] >> 24) & 0xFF;
 914                base = (rawValue >> 4) * 10 + (rawValue & 0xF);
 915                _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, CCK, RF_1TX, base);
 916
 917                rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_1TX][2] >> 24) & 0xFF;
 918                base = (rawValue >> 4) * 10 + (rawValue & 0xF);
 919                _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, OFDM, RF_1TX, base);
 920
 921                rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_1TX][4] >> 24) & 0xFF;
 922                base = (rawValue >> 4) * 10 + (rawValue & 0xF);
 923                _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, HT_MCS0_MCS7, RF_1TX, base);
 924
 925                rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_2TX][6] >> 24) & 0xFF;
 926                base = (rawValue >> 4) * 10 + (rawValue & 0xF);
 927                _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, HT_MCS8_MCS15, RF_2TX, base);
 928
 929                rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_1TX][8] >> 24) & 0xFF;
 930                base = (rawValue >> 4) * 10 + (rawValue & 0xF);
 931                _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, VHT_1SSMCS0_1SSMCS9, RF_1TX, base);
 932
 933                rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_2TX][11] >> 8) & 0xFF;
 934                base = (rawValue >> 4) * 10 + (rawValue & 0xF);
 935                _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, VHT_2SSMCS0_2SSMCS9, RF_2TX, base);
 936
 937                rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_1TX][2] >> 24) & 0xFF;
 938                base = (rawValue >> 4) * 10 + (rawValue & 0xF);
 939                _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, OFDM, RF_1TX, base);
 940
 941                rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_1TX][4] >> 24) & 0xFF;
 942                base = (rawValue >> 4) * 10 + (rawValue & 0xF);
 943                _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, HT_MCS0_MCS7, RF_1TX, base);
 944
 945                rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_2TX][6] >> 24) & 0xFF;
 946                base = (rawValue >> 4) * 10 + (rawValue & 0xF);
 947                _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, HT_MCS8_MCS15, RF_2TX, base);
 948
 949                rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_1TX][8] >> 24) & 0xFF;
 950                base = (rawValue >> 4) * 10 + (rawValue & 0xF);
 951                _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, VHT_1SSMCS0_1SSMCS9, RF_1TX, base);
 952
 953                rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_2TX][11] >> 8) & 0xFF;
 954                base = (rawValue >> 4) * 10 + (rawValue & 0xF);
 955                _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, VHT_2SSMCS0_2SSMCS9, RF_2TX, base);
 956        }
 957}
 958
 959static void _phy_convert_txpower_dbm_to_relative_value(u32 *data, u8 start,
 960                                                u8 end, u8 base_val)
 961{
 962        char i = 0;
 963        u8 temp_value = 0;
 964        u32 temp_data = 0;
 965
 966        for (i = 3; i >= 0; --i) {
 967                if (i >= start && i <= end) {
 968                        /* Get the exact value */
 969                        temp_value = (u8)(*data >> (i * 8)) & 0xF;
 970                        temp_value += ((u8)((*data >> (i * 8 + 4)) & 0xF)) * 10;
 971
 972                        /* Change the value to a relative value */
 973                        temp_value = (temp_value > base_val) ? temp_value -
 974                                        base_val : base_val - temp_value;
 975                } else {
 976                        temp_value = (u8)(*data >> (i * 8)) & 0xFF;
 977                }
 978                temp_data <<= 8;
 979                temp_data |= temp_value;
 980        }
 981        *data = temp_data;
 982}
 983
 984static void _rtl8812ae_phy_cross_reference_ht_and_vht_txpower_limit(struct ieee80211_hw *hw)
 985{
 986        struct rtl_priv *rtlpriv = rtl_priv(hw);
 987        struct rtl_phy *rtlphy = &rtlpriv->phy;
 988        u8 regulation, bw, channel, rate_section;
 989        char temp_pwrlmt = 0;
 990
 991        for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
 992                for (bw = 0; bw < MAX_5G_BANDWITH_NUM; ++bw) {
 993                        for (channel = 0; channel < CHANNEL_MAX_NUMBER_5G; ++channel) {
 994                                for (rate_section = 0; rate_section < MAX_RATE_SECTION_NUM; ++rate_section) {
 995                                        temp_pwrlmt = rtlphy->txpwr_limit_5g[regulation]
 996                                                [bw][rate_section][channel][RF90_PATH_A];
 997                                        if (temp_pwrlmt == MAX_POWER_INDEX) {
 998                                                if (bw == 0 || bw == 1) { /*5G 20M 40M VHT and HT can cross reference*/
 999                                                        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1000                                                                "No power limit table of the specified band %d, bandwidth %d, ratesection %d, channel %d, rf path %d\n",
1001                                                                1, bw, rate_section, channel, RF90_PATH_A);
1002                                                        if (rate_section == 2) {
1003                                                                rtlphy->txpwr_limit_5g[regulation][bw][2][channel][RF90_PATH_A] =
1004                                                                        rtlphy->txpwr_limit_5g[regulation][bw][4][channel][RF90_PATH_A];
1005                                                        } else if (rate_section == 4) {
1006                                                                rtlphy->txpwr_limit_5g[regulation][bw][4][channel][RF90_PATH_A] =
1007                                                                        rtlphy->txpwr_limit_5g[regulation][bw][2][channel][RF90_PATH_A];
1008                                                        } else if (rate_section == 3) {
1009                                                                rtlphy->txpwr_limit_5g[regulation][bw][3][channel][RF90_PATH_A] =
1010                                                                        rtlphy->txpwr_limit_5g[regulation][bw][5][channel][RF90_PATH_A];
1011                                                        } else if (rate_section == 5) {
1012                                                                rtlphy->txpwr_limit_5g[regulation][bw][5][channel][RF90_PATH_A] =
1013                                                                        rtlphy->txpwr_limit_5g[regulation][bw][3][channel][RF90_PATH_A];
1014                                                        }
1015
1016                                                        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "use other value %d", temp_pwrlmt);
1017                                                }
1018                                        }
1019                                }
1020                        }
1021                }
1022        }
1023}
1024
1025static u8 _rtl8812ae_phy_get_txpower_by_rate_base_index(struct ieee80211_hw *hw,
1026                                                   enum band_type band, u8 rate)
1027{
1028        struct rtl_priv *rtlpriv = rtl_priv(hw);
1029        u8 index = 0;
1030        if (band == BAND_ON_2_4G) {
1031                switch (rate) {
1032                case MGN_1M:
1033                case MGN_2M:
1034                case MGN_5_5M:
1035                case MGN_11M:
1036                        index = 0;
1037                        break;
1038
1039                case MGN_6M:
1040                case MGN_9M:
1041                case MGN_12M:
1042                case MGN_18M:
1043                case MGN_24M:
1044                case MGN_36M:
1045                case MGN_48M:
1046                case MGN_54M:
1047                        index = 1;
1048                        break;
1049
1050                case MGN_MCS0:
1051                case MGN_MCS1:
1052                case MGN_MCS2:
1053                case MGN_MCS3:
1054                case MGN_MCS4:
1055                case MGN_MCS5:
1056                case MGN_MCS6:
1057                case MGN_MCS7:
1058                        index = 2;
1059                        break;
1060
1061                case MGN_MCS8:
1062                case MGN_MCS9:
1063                case MGN_MCS10:
1064                case MGN_MCS11:
1065                case MGN_MCS12:
1066                case MGN_MCS13:
1067                case MGN_MCS14:
1068                case MGN_MCS15:
1069                        index = 3;
1070                        break;
1071
1072                default:
1073                        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1074                                "Wrong rate 0x%x to obtain index in 2.4G in PHY_GetTxPowerByRateBaseIndex()\n",
1075                                rate);
1076                        break;
1077                }
1078        } else if (band == BAND_ON_5G) {
1079                switch (rate) {
1080                case MGN_6M:
1081                case MGN_9M:
1082                case MGN_12M:
1083                case MGN_18M:
1084                case MGN_24M:
1085                case MGN_36M:
1086                case MGN_48M:
1087                case MGN_54M:
1088                        index = 0;
1089                        break;
1090
1091                case MGN_MCS0:
1092                case MGN_MCS1:
1093                case MGN_MCS2:
1094                case MGN_MCS3:
1095                case MGN_MCS4:
1096                case MGN_MCS5:
1097                case MGN_MCS6:
1098                case MGN_MCS7:
1099                        index = 1;
1100                        break;
1101
1102                case MGN_MCS8:
1103                case MGN_MCS9:
1104                case MGN_MCS10:
1105                case MGN_MCS11:
1106                case MGN_MCS12:
1107                case MGN_MCS13:
1108                case MGN_MCS14:
1109                case MGN_MCS15:
1110                        index = 2;
1111                        break;
1112
1113                case MGN_VHT1SS_MCS0:
1114                case MGN_VHT1SS_MCS1:
1115                case MGN_VHT1SS_MCS2:
1116                case MGN_VHT1SS_MCS3:
1117                case MGN_VHT1SS_MCS4:
1118                case MGN_VHT1SS_MCS5:
1119                case MGN_VHT1SS_MCS6:
1120                case MGN_VHT1SS_MCS7:
1121                case MGN_VHT1SS_MCS8:
1122                case MGN_VHT1SS_MCS9:
1123                        index = 3;
1124                        break;
1125
1126                case MGN_VHT2SS_MCS0:
1127                case MGN_VHT2SS_MCS1:
1128                case MGN_VHT2SS_MCS2:
1129                case MGN_VHT2SS_MCS3:
1130                case MGN_VHT2SS_MCS4:
1131                case MGN_VHT2SS_MCS5:
1132                case MGN_VHT2SS_MCS6:
1133                case MGN_VHT2SS_MCS7:
1134                case MGN_VHT2SS_MCS8:
1135                case MGN_VHT2SS_MCS9:
1136                        index = 4;
1137                        break;
1138
1139                default:
1140                        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1141                                "Wrong rate 0x%x to obtain index in 5G in PHY_GetTxPowerByRateBaseIndex()\n",
1142                                rate);
1143                        break;
1144                }
1145        }
1146
1147        return index;
1148}
1149
1150static void _rtl8812ae_phy_convert_txpower_limit_to_power_index(struct ieee80211_hw *hw)
1151{
1152        struct rtl_priv *rtlpriv = rtl_priv(hw);
1153        struct rtl_phy *rtlphy = &rtlpriv->phy;
1154        u8 bw40_pwr_base_dbm2_4G, bw40_pwr_base_dbm5G;
1155        u8 regulation, bw, channel, rate_section;
1156        u8 base_index2_4G = 0;
1157        u8 base_index5G = 0;
1158        char temp_value = 0, temp_pwrlmt = 0;
1159        u8 rf_path = 0;
1160
1161        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1162                "=====> _rtl8812ae_phy_convert_txpower_limit_to_power_index()\n");
1163
1164        _rtl8812ae_phy_cross_reference_ht_and_vht_txpower_limit(hw);
1165
1166        for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
1167                for (bw = 0; bw < MAX_2_4G_BANDWITH_NUM; ++bw) {
1168                        for (channel = 0; channel < CHANNEL_MAX_NUMBER_2G; ++channel) {
1169                                for (rate_section = 0; rate_section < MAX_RATE_SECTION_NUM; ++rate_section) {
1170                                        /* obtain the base dBm values in 2.4G band
1171                                         CCK => 11M, OFDM => 54M, HT 1T => MCS7, HT 2T => MCS15*/
1172                                        if (rate_section == 0) { /*CCK*/
1173                                                base_index2_4G =
1174                                                        _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1175                                                        BAND_ON_2_4G, MGN_11M);
1176                                        } else if (rate_section == 1) { /*OFDM*/
1177                                                base_index2_4G =
1178                                                        _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1179                                                        BAND_ON_2_4G, MGN_54M);
1180                                        } else if (rate_section == 2) { /*HT IT*/
1181                                                base_index2_4G =
1182                                                        _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1183                                                        BAND_ON_2_4G, MGN_MCS7);
1184                                        } else if (rate_section == 3) { /*HT 2T*/
1185                                                base_index2_4G =
1186                                                        _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1187                                                        BAND_ON_2_4G, MGN_MCS15);
1188                                        }
1189
1190                                        temp_pwrlmt = rtlphy->txpwr_limit_2_4g[regulation]
1191                                                [bw][rate_section][channel][RF90_PATH_A];
1192
1193                                        for (rf_path = RF90_PATH_A;
1194                                                rf_path < MAX_RF_PATH_NUM;
1195                                                ++rf_path) {
1196                                                if (rate_section == 3)
1197                                                        bw40_pwr_base_dbm2_4G =
1198                                                        rtlphy->txpwr_by_rate_base_24g[rf_path][RF_2TX][base_index2_4G];
1199                                                else
1200                                                        bw40_pwr_base_dbm2_4G =
1201                                                        rtlphy->txpwr_by_rate_base_24g[rf_path][RF_1TX][base_index2_4G];
1202
1203                                                if (temp_pwrlmt != MAX_POWER_INDEX) {
1204                                                        temp_value = temp_pwrlmt - bw40_pwr_base_dbm2_4G;
1205                                                        rtlphy->txpwr_limit_2_4g[regulation]
1206                                                                [bw][rate_section][channel][rf_path] =
1207                                                                temp_value;
1208                                                }
1209
1210                                                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1211                                                        "TxPwrLimit_2_4G[regulation %d][bw %d][rateSection %d][channel %d] = %d\n(TxPwrLimit in dBm %d - BW40PwrLmt2_4G[channel %d][rfPath %d] %d)\n",
1212                                                        regulation, bw, rate_section, channel,
1213                                                        rtlphy->txpwr_limit_2_4g[regulation][bw]
1214                                                        [rate_section][channel][rf_path], (temp_pwrlmt == 63)
1215                                                        ? 0 : temp_pwrlmt/2, channel, rf_path,
1216                                                        bw40_pwr_base_dbm2_4G);
1217                                        }
1218                                }
1219                        }
1220                }
1221        }
1222        for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
1223                for (bw = 0; bw < MAX_5G_BANDWITH_NUM; ++bw) {
1224                        for (channel = 0; channel < CHANNEL_MAX_NUMBER_5G; ++channel) {
1225                                for (rate_section = 0; rate_section < MAX_RATE_SECTION_NUM; ++rate_section) {
1226                                        /* obtain the base dBm values in 5G band
1227                                         OFDM => 54M, HT 1T => MCS7, HT 2T => MCS15,
1228                                        VHT => 1SSMCS7, VHT 2T => 2SSMCS7*/
1229                                        if (rate_section == 1) { /*OFDM*/
1230                                                base_index5G =
1231                                                        _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1232                                                        BAND_ON_5G, MGN_54M);
1233                                        } else if (rate_section == 2) { /*HT 1T*/
1234                                                base_index5G =
1235                                                        _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1236                                                        BAND_ON_5G, MGN_MCS7);
1237                                        } else if (rate_section == 3) { /*HT 2T*/
1238                                                base_index5G =
1239                                                        _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1240                                                        BAND_ON_5G, MGN_MCS15);
1241                                        } else if (rate_section == 4) { /*VHT 1T*/
1242                                                base_index5G =
1243                                                        _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1244                                                        BAND_ON_5G, MGN_VHT1SS_MCS7);
1245                                        } else if (rate_section == 5) { /*VHT 2T*/
1246                                                base_index5G =
1247                                                        _rtl8812ae_phy_get_txpower_by_rate_base_index(hw,
1248                                                        BAND_ON_5G, MGN_VHT2SS_MCS7);
1249                                        }
1250
1251                                        temp_pwrlmt = rtlphy->txpwr_limit_5g[regulation]
1252                                                [bw][rate_section][channel]
1253                                                [RF90_PATH_A];
1254
1255                                        for (rf_path = RF90_PATH_A;
1256                                             rf_path < MAX_RF_PATH_NUM;
1257                                             ++rf_path) {
1258                                                if (rate_section == 3 || rate_section == 5)
1259                                                        bw40_pwr_base_dbm5G =
1260                                                        rtlphy->txpwr_by_rate_base_5g[rf_path]
1261                                                        [RF_2TX][base_index5G];
1262                                                else
1263                                                        bw40_pwr_base_dbm5G =
1264                                                        rtlphy->txpwr_by_rate_base_5g[rf_path]
1265                                                        [RF_1TX][base_index5G];
1266
1267                                                if (temp_pwrlmt != MAX_POWER_INDEX) {
1268                                                        temp_value =
1269                                                                temp_pwrlmt - bw40_pwr_base_dbm5G;
1270                                                        rtlphy->txpwr_limit_5g[regulation]
1271                                                                [bw][rate_section][channel]
1272                                                                [rf_path] = temp_value;
1273                                                }
1274
1275                                                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1276                                                        "TxPwrLimit_5G[regulation %d][bw %d][rateSection %d][channel %d] =%d\n(TxPwrLimit in dBm %d - BW40PwrLmt5G[chnl group %d][rfPath %d] %d)\n",
1277                                                        regulation, bw, rate_section,
1278                                                        channel, rtlphy->txpwr_limit_5g[regulation]
1279                                                        [bw][rate_section][channel][rf_path],
1280                                                        temp_pwrlmt, channel, rf_path, bw40_pwr_base_dbm5G);
1281                                        }
1282                                }
1283                        }
1284                }
1285        }
1286        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1287                 "<===== _rtl8812ae_phy_convert_txpower_limit_to_power_index()\n");
1288}
1289
1290static void _rtl8821ae_phy_init_txpower_limit(struct ieee80211_hw *hw)
1291{
1292        struct rtl_priv *rtlpriv = rtl_priv(hw);
1293        struct rtl_phy *rtlphy = &rtlpriv->phy;
1294        u8 i, j, k, l, m;
1295
1296        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1297                 "=====> _rtl8821ae_phy_init_txpower_limit()!\n");
1298
1299        for (i = 0; i < MAX_REGULATION_NUM; ++i) {
1300                for (j = 0; j < MAX_2_4G_BANDWITH_NUM; ++j)
1301                        for (k = 0; k < MAX_RATE_SECTION_NUM; ++k)
1302                                for (m = 0; m < CHANNEL_MAX_NUMBER_2G; ++m)
1303                                        for (l = 0; l < MAX_RF_PATH_NUM; ++l)
1304                                                rtlphy->txpwr_limit_2_4g
1305                                                                [i][j][k][m][l]
1306                                                        = MAX_POWER_INDEX;
1307        }
1308        for (i = 0; i < MAX_REGULATION_NUM; ++i) {
1309                for (j = 0; j < MAX_5G_BANDWITH_NUM; ++j)
1310                        for (k = 0; k < MAX_RATE_SECTION_NUM; ++k)
1311                                for (m = 0; m < CHANNEL_MAX_NUMBER_5G; ++m)
1312                                        for (l = 0; l < MAX_RF_PATH_NUM; ++l)
1313                                                rtlphy->txpwr_limit_5g
1314                                                                [i][j][k][m][l]
1315                                                        = MAX_POWER_INDEX;
1316        }
1317
1318        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1319                 "<===== _rtl8821ae_phy_init_txpower_limit()!\n");
1320}
1321
1322static void _rtl8821ae_phy_convert_txpower_dbm_to_relative_value(struct ieee80211_hw *hw)
1323{
1324        struct rtl_priv *rtlpriv = rtl_priv(hw);
1325        struct rtl_phy *rtlphy = &rtlpriv->phy;
1326        u8 base = 0, rfPath = 0;
1327
1328        for (rfPath = RF90_PATH_A; rfPath <= RF90_PATH_B; ++rfPath) {
1329                base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_1TX, CCK);
1330                _phy_convert_txpower_dbm_to_relative_value(
1331                        &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][0],
1332                        0, 3, base);
1333
1334                base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_1TX, OFDM);
1335                _phy_convert_txpower_dbm_to_relative_value(
1336                        &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][1],
1337                        0, 3, base);
1338                _phy_convert_txpower_dbm_to_relative_value(
1339                        &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][2],
1340                        0, 3, base);
1341
1342                base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_1TX, HT_MCS0_MCS7);
1343                _phy_convert_txpower_dbm_to_relative_value(
1344                        &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][3],
1345                        0, 3, base);
1346                _phy_convert_txpower_dbm_to_relative_value(
1347                        &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][4],
1348                        0, 3, base);
1349
1350                base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_2TX, HT_MCS8_MCS15);
1351
1352                _phy_convert_txpower_dbm_to_relative_value(
1353                        &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_2TX][5],
1354                        0, 3, base);
1355
1356                _phy_convert_txpower_dbm_to_relative_value(
1357                        &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_2TX][6],
1358                        0, 3, base);
1359
1360                base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_1TX, VHT_1SSMCS0_1SSMCS9);
1361                _phy_convert_txpower_dbm_to_relative_value(
1362                        &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][7],
1363                        0, 3, base);
1364                _phy_convert_txpower_dbm_to_relative_value(
1365                        &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][8],
1366                        0, 3, base);
1367                _phy_convert_txpower_dbm_to_relative_value(
1368                        &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][9],
1369                        0, 1, base);
1370
1371                base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_2TX, VHT_2SSMCS0_2SSMCS9);
1372                _phy_convert_txpower_dbm_to_relative_value(
1373                        &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][9],
1374                        2, 3, base);
1375                _phy_convert_txpower_dbm_to_relative_value(
1376                        &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_2TX][10],
1377                        0, 3, base);
1378                _phy_convert_txpower_dbm_to_relative_value(
1379                        &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_2TX][11],
1380                        0, 3, base);
1381
1382                base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_1TX, OFDM);
1383                _phy_convert_txpower_dbm_to_relative_value(
1384                        &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][1],
1385                        0, 3, base);
1386                _phy_convert_txpower_dbm_to_relative_value(
1387                        &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][2],
1388                        0, 3, base);
1389
1390                base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_1TX, HT_MCS0_MCS7);
1391                _phy_convert_txpower_dbm_to_relative_value(
1392                        &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][3],
1393                        0, 3, base);
1394                _phy_convert_txpower_dbm_to_relative_value(
1395                        &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][4],
1396                        0, 3, base);
1397
1398                base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_2TX, HT_MCS8_MCS15);
1399                _phy_convert_txpower_dbm_to_relative_value(
1400                        &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_2TX][5],
1401                        0, 3, base);
1402                _phy_convert_txpower_dbm_to_relative_value(
1403                        &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_2TX][6],
1404                        0, 3, base);
1405
1406                base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_1TX, VHT_1SSMCS0_1SSMCS9);
1407                _phy_convert_txpower_dbm_to_relative_value(
1408                        &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][7],
1409                        0, 3, base);
1410                _phy_convert_txpower_dbm_to_relative_value(
1411                        &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][8],
1412                        0, 3, base);
1413                _phy_convert_txpower_dbm_to_relative_value(
1414                        &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][9],
1415                        0, 1, base);
1416
1417                base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_2TX, VHT_2SSMCS0_2SSMCS9);
1418                _phy_convert_txpower_dbm_to_relative_value(
1419                        &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][9],
1420                        2, 3, base);
1421                _phy_convert_txpower_dbm_to_relative_value(
1422                        &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_2TX][10],
1423                        0, 3, base);
1424                _phy_convert_txpower_dbm_to_relative_value(
1425                        &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_2TX][11],
1426                        0, 3, base);
1427        }
1428
1429        RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
1430                "<===_rtl8821ae_phy_convert_txpower_dbm_to_relative_value()\n");
1431}
1432
1433static void _rtl8821ae_phy_txpower_by_rate_configuration(struct ieee80211_hw *hw)
1434{
1435        _rtl8821ae_phy_store_txpower_by_rate_base(hw);
1436        _rtl8821ae_phy_convert_txpower_dbm_to_relative_value(hw);
1437}
1438
1439/* string is in decimal */
1440static bool _rtl8812ae_get_integer_from_string(char *str, u8 *pint)
1441{
1442        u16 i = 0;
1443        *pint = 0;
1444
1445        while (str[i] != '\0') {
1446                if (str[i] >= '0' && str[i] <= '9') {
1447                        *pint *= 10;
1448                        *pint += (str[i] - '0');
1449                } else {
1450                        return false;
1451                }
1452                ++i;
1453        }
1454
1455        return true;
1456}
1457
1458static bool _rtl8812ae_eq_n_byte(u8 *str1, u8 *str2, u32 num)
1459{
1460        if (num == 0)
1461                return false;
1462        while (num > 0) {
1463                num--;
1464                if (str1[num] != str2[num])
1465                        return false;
1466        }
1467        return true;
1468}
1469
1470static char _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(struct ieee80211_hw *hw,
1471                                              u8 band, u8 channel)
1472{
1473        struct rtl_priv *rtlpriv = rtl_priv(hw);
1474        char channel_index = -1;
1475        u8 channel_5g[CHANNEL_MAX_NUMBER_5G] = {
1476                36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64,
1477                100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122,
1478                124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 149,
1479                151, 153, 155, 157, 159, 161, 163, 165, 167, 168, 169, 171,
1480                173, 175, 177};
1481        u8  i = 0;
1482        if (band == BAND_ON_2_4G)
1483                channel_index = channel - 1;
1484        else if (band == BAND_ON_5G) {
1485                for (i = 0; i < sizeof(channel_5g)/sizeof(u8); ++i) {
1486                        if (channel_5g[i] == channel)
1487                                channel_index = i;
1488                }
1489        } else
1490                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid Band %d in %s",
1491                         band,  __func__);
1492
1493        if (channel_index == -1)
1494                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
1495                         "Invalid Channel %d of Band %d in %s", channel,
1496                         band, __func__);
1497
1498        return channel_index;
1499}
1500
1501static void _rtl8812ae_phy_set_txpower_limit(struct ieee80211_hw *hw, u8 *pregulation,
1502                                      u8 *pband, u8 *pbandwidth,
1503                                      u8 *prate_section, u8 *prf_path,
1504                                      u8 *pchannel, u8 *ppower_limit)
1505{
1506        struct rtl_priv *rtlpriv = rtl_priv(hw);
1507        struct rtl_phy *rtlphy = &rtlpriv->phy;
1508        u8 regulation = 0, bandwidth = 0, rate_section = 0, channel;
1509        u8 channel_index;
1510        char power_limit = 0, prev_power_limit, ret;
1511
1512        if (!_rtl8812ae_get_integer_from_string((char *)pchannel, &channel) ||
1513            !_rtl8812ae_get_integer_from_string((char *)ppower_limit,
1514                                                &power_limit)) {
1515                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1516                         "Illegal index of pwr_lmt table [chnl %d][val %d]\n",
1517                          channel, power_limit);
1518        }
1519
1520        power_limit = power_limit > MAX_POWER_INDEX ?
1521                      MAX_POWER_INDEX : power_limit;
1522
1523        if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("FCC"), 3))
1524                regulation = 0;
1525        else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("MKK"), 3))
1526                regulation = 1;
1527        else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("ETSI"), 4))
1528                regulation = 2;
1529        else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("WW13"), 4))
1530                regulation = 3;
1531
1532        if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("CCK"), 3))
1533                rate_section = 0;
1534        else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("OFDM"), 4))
1535                rate_section = 1;
1536        else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("HT"), 2) &&
1537                 _rtl8812ae_eq_n_byte(prf_path, (u8 *)("1T"), 2))
1538                rate_section = 2;
1539        else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("HT"), 2) &&
1540                 _rtl8812ae_eq_n_byte(prf_path, (u8 *)("2T"), 2))
1541                rate_section = 3;
1542        else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("VHT"), 3) &&
1543                 _rtl8812ae_eq_n_byte(prf_path, (u8 *)("1T"), 2))
1544                rate_section = 4;
1545        else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("VHT"), 3) &&
1546                 _rtl8812ae_eq_n_byte(prf_path, (u8 *)("2T"), 2))
1547                rate_section = 5;
1548
1549        if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("20M"), 3))
1550                bandwidth = 0;
1551        else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("40M"), 3))
1552                bandwidth = 1;
1553        else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("80M"), 3))
1554                bandwidth = 2;
1555        else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("160M"), 4))
1556                bandwidth = 3;
1557
1558        if (_rtl8812ae_eq_n_byte(pband, (u8 *)("2.4G"), 4)) {
1559                ret = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
1560                                                               BAND_ON_2_4G,
1561                                                               channel);
1562
1563                if (ret == -1)
1564                        return;
1565
1566                channel_index = ret;
1567
1568                prev_power_limit = rtlphy->txpwr_limit_2_4g[regulation]
1569                                                [bandwidth][rate_section]
1570                                                [channel_index][RF90_PATH_A];
1571
1572                if (power_limit < prev_power_limit)
1573                        rtlphy->txpwr_limit_2_4g[regulation][bandwidth]
1574                                [rate_section][channel_index][RF90_PATH_A] =
1575                                                                   power_limit;
1576
1577                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1578                         "2.4G [regula %d][bw %d][sec %d][chnl %d][val %d]\n",
1579                          regulation, bandwidth, rate_section, channel_index,
1580                          rtlphy->txpwr_limit_2_4g[regulation][bandwidth]
1581                                [rate_section][channel_index][RF90_PATH_A]);
1582        } else if (_rtl8812ae_eq_n_byte(pband, (u8 *)("5G"), 2)) {
1583                ret = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
1584                                                               BAND_ON_5G,
1585                                                               channel);
1586
1587                if (ret == -1)
1588                        return;
1589
1590                channel_index = ret;
1591
1592                prev_power_limit = rtlphy->txpwr_limit_5g[regulation][bandwidth]
1593                                                [rate_section][channel_index]
1594                                                [RF90_PATH_A];
1595
1596                if (power_limit < prev_power_limit)
1597                        rtlphy->txpwr_limit_5g[regulation][bandwidth]
1598                        [rate_section][channel_index][RF90_PATH_A] = power_limit;
1599
1600                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1601                         "5G: [regul %d][bw %d][sec %d][chnl %d][val %d]\n",
1602                          regulation, bandwidth, rate_section, channel,
1603                          rtlphy->txpwr_limit_5g[regulation][bandwidth]
1604                                [rate_section][channel_index][RF90_PATH_A]);
1605        } else {
1606                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1607                         "Cannot recognize the band info in %s\n", pband);
1608                return;
1609        }
1610}
1611
1612static void _rtl8812ae_phy_config_bb_txpwr_lmt(struct ieee80211_hw *hw,
1613                                          u8 *regulation, u8 *band,
1614                                          u8 *bandwidth, u8 *rate_section,
1615                                          u8 *rf_path, u8 *channel,
1616                                          u8 *power_limit)
1617{
1618        _rtl8812ae_phy_set_txpower_limit(hw, regulation, band, bandwidth,
1619                                         rate_section, rf_path, channel,
1620                                         power_limit);
1621}
1622
1623static void _rtl8821ae_phy_read_and_config_txpwr_lmt(struct ieee80211_hw *hw)
1624{
1625        struct rtl_priv *rtlpriv = rtl_priv(hw);
1626        struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1627        u32 i = 0;
1628        u32 array_len;
1629        u8 **array;
1630
1631        if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
1632                array_len = RTL8812AE_TXPWR_LMT_ARRAY_LEN;
1633                array = RTL8812AE_TXPWR_LMT;
1634        } else {
1635                array_len = RTL8821AE_TXPWR_LMT_ARRAY_LEN;
1636                array = RTL8821AE_TXPWR_LMT;
1637        }
1638
1639        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1640                 "\n");
1641
1642        for (i = 0; i < array_len; i += 7) {
1643                u8 *regulation = array[i];
1644                u8 *band = array[i+1];
1645                u8 *bandwidth = array[i+2];
1646                u8 *rate = array[i+3];
1647                u8 *rf_path = array[i+4];
1648                u8 *chnl = array[i+5];
1649                u8 *val = array[i+6];
1650
1651                _rtl8812ae_phy_config_bb_txpwr_lmt(hw, regulation, band,
1652                                                   bandwidth, rate, rf_path,
1653                                                   chnl, val);
1654        }
1655}
1656
1657static bool _rtl8821ae_phy_bb8821a_config_parafile(struct ieee80211_hw *hw)
1658{
1659        struct rtl_priv *rtlpriv = rtl_priv(hw);
1660        struct rtl_phy *rtlphy = &rtlpriv->phy;
1661        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1662        bool rtstatus;
1663
1664        _rtl8821ae_phy_init_txpower_limit(hw);
1665
1666        /* RegEnableTxPowerLimit == 1 for 8812a & 8821a */
1667        if (rtlefuse->eeprom_regulatory != 2)
1668                _rtl8821ae_phy_read_and_config_txpwr_lmt(hw);
1669
1670        rtstatus = _rtl8821ae_phy_config_bb_with_headerfile(hw,
1671                                                       BASEBAND_CONFIG_PHY_REG);
1672        if (rtstatus != true) {
1673                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!");
1674                return false;
1675        }
1676        _rtl8821ae_phy_init_tx_power_by_rate(hw);
1677        if (rtlefuse->autoload_failflag == false) {
1678                rtstatus = _rtl8821ae_phy_config_bb_with_pgheaderfile(hw,
1679                                                    BASEBAND_CONFIG_PHY_REG);
1680        }
1681        if (rtstatus != true) {
1682                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!");
1683                return false;
1684        }
1685
1686        _rtl8821ae_phy_txpower_by_rate_configuration(hw);
1687
1688        /* RegEnableTxPowerLimit == 1 for 8812a & 8821a */
1689        if (rtlefuse->eeprom_regulatory != 2)
1690                _rtl8812ae_phy_convert_txpower_limit_to_power_index(hw);
1691
1692        rtstatus = _rtl8821ae_phy_config_bb_with_headerfile(hw,
1693                                                BASEBAND_CONFIG_AGC_TAB);
1694
1695        if (rtstatus != true) {
1696                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n");
1697                return false;
1698        }
1699        rtlphy->cck_high_power = (bool)(rtl_get_bbreg(hw,
1700                        RFPGA0_XA_HSSIPARAMETER2, 0x200));
1701        return true;
1702}
1703
1704static bool _rtl8821ae_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
1705{
1706        struct rtl_priv *rtlpriv = rtl_priv(hw);
1707        struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1708        u32 i, v1, v2;
1709        u32 arraylength;
1710        u32 *ptrarray;
1711
1712        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read MAC_REG_Array\n");
1713        if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
1714                arraylength = RTL8821AEMAC_1T_ARRAYLEN;
1715                ptrarray = RTL8821AE_MAC_REG_ARRAY;
1716        } else {
1717                arraylength = RTL8812AEMAC_1T_ARRAYLEN;
1718                ptrarray = RTL8812AE_MAC_REG_ARRAY;
1719        }
1720        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1721                 "Img: MAC_REG_ARRAY LEN %d\n", arraylength);
1722        for (i = 0; i < arraylength; i += 2) {
1723                v1 = ptrarray[i];
1724                v2 = (u8)ptrarray[i + 1];
1725                if (v1 < 0xCDCDCDCD) {
1726                        rtl_write_byte(rtlpriv, v1, (u8)v2);
1727                        continue;
1728                } else {
1729                        if (!_rtl8821ae_check_condition(hw, v1)) {
1730                                /*Discard the following (offset, data) pairs*/
1731                                READ_NEXT_PAIR(ptrarray, v1, v2, i);
1732                                while (v2 != 0xDEAD &&
1733                                       v2 != 0xCDEF &&
1734                                       v2 != 0xCDCD && i < arraylength - 2) {
1735                                        READ_NEXT_PAIR(ptrarray, v1, v2, i);
1736                                }
1737                                i -= 2; /* prevent from for-loop += 2*/
1738                        } else {/*Configure matched pairs and skip to end of if-else.*/
1739                                READ_NEXT_PAIR(ptrarray, v1, v2, i);
1740                                while (v2 != 0xDEAD &&
1741                                       v2 != 0xCDEF &&
1742                                       v2 != 0xCDCD && i < arraylength - 2) {
1743                                        rtl_write_byte(rtlpriv, v1, v2);
1744                                        READ_NEXT_PAIR(ptrarray, v1, v2, i);
1745                                }
1746
1747                                while (v2 != 0xDEAD && i < arraylength - 2)
1748                                        READ_NEXT_PAIR(ptrarray, v1, v2, i);
1749                        }
1750                }
1751        }
1752        return true;
1753}
1754
1755static bool _rtl8821ae_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
1756                                                     u8 configtype)
1757{
1758        struct rtl_priv *rtlpriv = rtl_priv(hw);
1759        struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1760        int i;
1761        u32 *array_table;
1762        u16 arraylen;
1763        u32 v1 = 0, v2 = 0;
1764
1765        if (configtype == BASEBAND_CONFIG_PHY_REG) {
1766                if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
1767                        arraylen = RTL8812AEPHY_REG_1TARRAYLEN;
1768                        array_table = RTL8812AE_PHY_REG_ARRAY;
1769                } else {
1770                        arraylen = RTL8821AEPHY_REG_1TARRAYLEN;
1771                        array_table = RTL8821AE_PHY_REG_ARRAY;
1772                }
1773
1774                for (i = 0; i < arraylen; i += 2) {
1775                        v1 = array_table[i];
1776                        v2 = array_table[i + 1];
1777                        if (v1 < 0xCDCDCDCD) {
1778                                _rtl8821ae_config_bb_reg(hw, v1, v2);
1779                                continue;
1780                        } else {/*This line is the start line of branch.*/
1781                                if (!_rtl8821ae_check_condition(hw, v1)) {
1782                                        /*Discard the following (offset, data) pairs*/
1783                                        READ_NEXT_PAIR(array_table, v1, v2, i);
1784                                        while (v2 != 0xDEAD &&
1785                                               v2 != 0xCDEF &&
1786                                               v2 != 0xCDCD &&
1787                                               i < arraylen - 2) {
1788                                                READ_NEXT_PAIR(array_table, v1,
1789                                                                v2, i);
1790                                        }
1791
1792                                        i -= 2; /* prevent from for-loop += 2*/
1793                                } else {/*Configure matched pairs and skip to end of if-else.*/
1794                                        READ_NEXT_PAIR(array_table, v1, v2, i);
1795                                        while (v2 != 0xDEAD &&
1796                                               v2 != 0xCDEF &&
1797                                               v2 != 0xCDCD &&
1798                                               i < arraylen - 2) {
1799                                                _rtl8821ae_config_bb_reg(hw, v1,
1800                                                                         v2);
1801                                                READ_NEXT_PAIR(array_table, v1,
1802                                                               v2, i);
1803                                        }
1804
1805                                        while (v2 != 0xDEAD &&
1806                                               i < arraylen - 2) {
1807                                                READ_NEXT_PAIR(array_table, v1,
1808                                                               v2, i);
1809                                        }
1810                                }
1811                        }
1812                }
1813        } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
1814                if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
1815                        arraylen = RTL8812AEAGCTAB_1TARRAYLEN;
1816                        array_table = RTL8812AE_AGC_TAB_ARRAY;
1817                } else {
1818                        arraylen = RTL8821AEAGCTAB_1TARRAYLEN;
1819                        array_table = RTL8821AE_AGC_TAB_ARRAY;
1820                }
1821
1822                for (i = 0; i < arraylen; i = i + 2) {
1823                        v1 = array_table[i];
1824                        v2 = array_table[i+1];
1825                        if (v1 < 0xCDCDCDCD) {
1826                                rtl_set_bbreg(hw, v1, MASKDWORD, v2);
1827                                udelay(1);
1828                                continue;
1829                        } else {/*This line is the start line of branch.*/
1830                                if (!_rtl8821ae_check_condition(hw, v1)) {
1831                                        /*Discard the following (offset, data) pairs*/
1832                                        READ_NEXT_PAIR(array_table, v1, v2, i);
1833                                        while (v2 != 0xDEAD &&
1834                                               v2 != 0xCDEF &&
1835                                               v2 != 0xCDCD &&
1836                                               i < arraylen - 2) {
1837                                                READ_NEXT_PAIR(array_table, v1,
1838                                                                v2, i);
1839                                        }
1840                                        i -= 2; /* prevent from for-loop += 2*/
1841                                } else {/*Configure matched pairs and skip to end of if-else.*/
1842                                        READ_NEXT_PAIR(array_table, v1, v2, i);
1843                                        while (v2 != 0xDEAD &&
1844                                               v2 != 0xCDEF &&
1845                                               v2 != 0xCDCD &&
1846                                               i < arraylen - 2) {
1847                                                rtl_set_bbreg(hw, v1, MASKDWORD,
1848                                                              v2);
1849                                                udelay(1);
1850                                                READ_NEXT_PAIR(array_table, v1,
1851                                                               v2, i);
1852                                        }
1853
1854                                        while (v2 != 0xDEAD &&
1855                                                i < arraylen - 2) {
1856                                                READ_NEXT_PAIR(array_table, v1,
1857                                                                v2, i);
1858                                        }
1859                                }
1860                                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1861                                         "The agctab_array_table[0] is %x Rtl818EEPHY_REGArray[1] is %x\n",
1862                                          array_table[i],  array_table[i + 1]);
1863                        }
1864                }
1865        }
1866        return true;
1867}
1868
1869static u8 _rtl8821ae_get_rate_section_index(u32 regaddr)
1870{
1871        u8 index = 0;
1872        regaddr &= 0xFFF;
1873        if (regaddr >= 0xC20 && regaddr <= 0xC4C)
1874                index = (u8)((regaddr - 0xC20) / 4);
1875        else if (regaddr >= 0xE20 && regaddr <= 0xE4C)
1876                index = (u8)((regaddr - 0xE20) / 4);
1877        else
1878                RT_ASSERT(!COMP_INIT,
1879                          "Invalid RegAddr 0x%x\n", regaddr);
1880        return index;
1881}
1882
1883static void _rtl8821ae_store_tx_power_by_rate(struct ieee80211_hw *hw,
1884                                              u32 band, u32 rfpath,
1885                                              u32 txnum, u32 regaddr,
1886                                              u32 bitmask, u32 data)
1887{
1888        struct rtl_priv *rtlpriv = rtl_priv(hw);
1889        struct rtl_phy *rtlphy = &rtlpriv->phy;
1890        u8 rate_section = _rtl8821ae_get_rate_section_index(regaddr);
1891
1892        if (band != BAND_ON_2_4G && band != BAND_ON_5G) {
1893                RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid Band %d\n", band);
1894                band = BAND_ON_2_4G;
1895        }
1896        if (rfpath >= MAX_RF_PATH) {
1897                RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid RfPath %d\n", rfpath);
1898                rfpath = MAX_RF_PATH - 1;
1899        }
1900        if (txnum >= MAX_RF_PATH) {
1901                RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid TxNum %d\n", txnum);
1902                txnum = MAX_RF_PATH - 1;
1903        }
1904        rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section] = data;
1905        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1906                 "TxPwrByRateOffset[Band %d][RfPath %d][TxNum %d][RateSection %d] = 0x%x\n",
1907                 band, rfpath, txnum, rate_section,
1908                 rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section]);
1909}
1910
1911static bool _rtl8821ae_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
1912                                                        u8 configtype)
1913{
1914        struct rtl_priv *rtlpriv = rtl_priv(hw);
1915        struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1916        int i;
1917        u32 *array;
1918        u16 arraylen;
1919        u32 v1, v2, v3, v4, v5, v6;
1920
1921        if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
1922                arraylen = RTL8812AEPHY_REG_ARRAY_PGLEN;
1923                array = RTL8812AE_PHY_REG_ARRAY_PG;
1924        } else {
1925                arraylen = RTL8821AEPHY_REG_ARRAY_PGLEN;
1926                array = RTL8821AE_PHY_REG_ARRAY_PG;
1927        }
1928
1929        if (configtype != BASEBAND_CONFIG_PHY_REG) {
1930                RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
1931                         "configtype != BaseBand_Config_PHY_REG\n");
1932                return true;
1933        }
1934        for (i = 0; i < arraylen; i += 6) {
1935                v1 = array[i];
1936                v2 = array[i+1];
1937                v3 = array[i+2];
1938                v4 = array[i+3];
1939                v5 = array[i+4];
1940                v6 = array[i+5];
1941
1942                if (v1 < 0xCDCDCDCD) {
1943                        if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE &&
1944                                (v4 == 0xfe || v4 == 0xffe)) {
1945                                msleep(50);
1946                                continue;
1947                        }
1948
1949                        if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
1950                                if (v4 == 0xfe)
1951                                        msleep(50);
1952                                else if (v4 == 0xfd)
1953                                        mdelay(5);
1954                                else if (v4 == 0xfc)
1955                                        mdelay(1);
1956                                else if (v4 == 0xfb)
1957                                        udelay(50);
1958                                else if (v4 == 0xfa)
1959                                        udelay(5);
1960                                else if (v4 == 0xf9)
1961                                        udelay(1);
1962                        }
1963                        _rtl8821ae_store_tx_power_by_rate(hw, v1, v2, v3,
1964                                                          v4, v5, v6);
1965                        continue;
1966                } else {
1967                         /*don't need the hw_body*/
1968                        if (!_rtl8821ae_check_condition(hw, v1)) {
1969                                i += 2; /* skip the pair of expression*/
1970                                v1 = array[i];
1971                                v2 = array[i+1];
1972                                v3 = array[i+2];
1973                                while (v2 != 0xDEAD) {
1974                                        i += 3;
1975                                        v1 = array[i];
1976                                        v2 = array[i+1];
1977                                        v3 = array[i+2];
1978                                }
1979                        }
1980                }
1981        }
1982
1983        return true;
1984}
1985
1986bool rtl8812ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
1987                                             enum radio_path rfpath)
1988{
1989        int i;
1990        bool rtstatus = true;
1991        u32 *radioa_array_table_a, *radioa_array_table_b;
1992        u16 radioa_arraylen_a, radioa_arraylen_b;
1993        struct rtl_priv *rtlpriv = rtl_priv(hw);
1994        u32 v1 = 0, v2 = 0;
1995
1996        radioa_arraylen_a = RTL8812AE_RADIOA_1TARRAYLEN;
1997        radioa_array_table_a = RTL8812AE_RADIOA_ARRAY;
1998        radioa_arraylen_b = RTL8812AE_RADIOB_1TARRAYLEN;
1999        radioa_array_table_b = RTL8812AE_RADIOB_ARRAY;
2000        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2001                 "Radio_A:RTL8821AE_RADIOA_ARRAY %d\n", radioa_arraylen_a);
2002        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
2003        rtstatus = true;
2004        switch (rfpath) {
2005        case RF90_PATH_A:
2006                for (i = 0; i < radioa_arraylen_a; i = i + 2) {
2007                        v1 = radioa_array_table_a[i];
2008                        v2 = radioa_array_table_a[i+1];
2009                        if (v1 < 0xcdcdcdcd) {
2010                                _rtl8821ae_config_rf_radio_a(hw, v1, v2);
2011                                continue;
2012                        } else{/*This line is the start line of branch.*/
2013                                if (!_rtl8821ae_check_condition(hw, v1)) {
2014                                        /*Discard the following (offset, data) pairs*/
2015                                        READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
2016                                        while (v2 != 0xDEAD &&
2017                                               v2 != 0xCDEF &&
2018                                               v2 != 0xCDCD && i < radioa_arraylen_a-2)
2019                                                READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
2020
2021                                        i -= 2; /* prevent from for-loop += 2*/
2022                                } else {/*Configure matched pairs and skip to end of if-else.*/
2023                                        READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
2024                                        while (v2 != 0xDEAD &&
2025                                               v2 != 0xCDEF &&
2026                                               v2 != 0xCDCD && i < radioa_arraylen_a - 2) {
2027                                                _rtl8821ae_config_rf_radio_a(hw, v1, v2);
2028                                                READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
2029                                        }
2030
2031                                        while (v2 != 0xDEAD && i < radioa_arraylen_a-2)
2032                                                READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i);
2033
2034                                }
2035                        }
2036                }
2037                break;
2038        case RF90_PATH_B:
2039                for (i = 0; i < radioa_arraylen_b; i = i + 2) {
2040                        v1 = radioa_array_table_b[i];
2041                        v2 = radioa_array_table_b[i+1];
2042                        if (v1 < 0xcdcdcdcd) {
2043                                _rtl8821ae_config_rf_radio_b(hw, v1, v2);
2044                                continue;
2045                        } else{/*This line is the start line of branch.*/
2046                                if (!_rtl8821ae_check_condition(hw, v1)) {
2047                                        /*Discard the following (offset, data) pairs*/
2048                                        READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
2049                                        while (v2 != 0xDEAD &&
2050                                               v2 != 0xCDEF &&
2051                                               v2 != 0xCDCD && i < radioa_arraylen_b-2)
2052                                                READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
2053
2054                                        i -= 2; /* prevent from for-loop += 2*/
2055                                } else {/*Configure matched pairs and skip to end of if-else.*/
2056                                        READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
2057                                        while (v2 != 0xDEAD &&
2058                                               v2 != 0xCDEF &&
2059                                               v2 != 0xCDCD && i < radioa_arraylen_b-2) {
2060                                                _rtl8821ae_config_rf_radio_b(hw, v1, v2);
2061                                                READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
2062                                        }
2063
2064                                        while (v2 != 0xDEAD && i < radioa_arraylen_b-2)
2065                                                READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i);
2066                                }
2067                        }
2068                }
2069                break;
2070        case RF90_PATH_C:
2071                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2072                         "switch case not process\n");
2073                break;
2074        case RF90_PATH_D:
2075                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2076                         "switch case not process\n");
2077                break;
2078        }
2079        return true;
2080}
2081
2082bool rtl8821ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
2083                                                enum radio_path rfpath)
2084{
2085        #define READ_NEXT_RF_PAIR(v1, v2, i) \
2086        do { \
2087                i += 2; \
2088                v1 = radioa_array_table[i]; \
2089                v2 = radioa_array_table[i+1]; \
2090        } \
2091        while (0)
2092
2093        int i;
2094        bool rtstatus = true;
2095        u32 *radioa_array_table;
2096        u16 radioa_arraylen;
2097        struct rtl_priv *rtlpriv = rtl_priv(hw);
2098        /* struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); */
2099        u32 v1 = 0, v2 = 0;
2100
2101        radioa_arraylen = RTL8821AE_RADIOA_1TARRAYLEN;
2102        radioa_array_table = RTL8821AE_RADIOA_ARRAY;
2103        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2104                 "Radio_A:RTL8821AE_RADIOA_ARRAY %d\n", radioa_arraylen);
2105        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
2106        rtstatus = true;
2107        switch (rfpath) {
2108        case RF90_PATH_A:
2109                for (i = 0; i < radioa_arraylen; i = i + 2) {
2110                        v1 = radioa_array_table[i];
2111                        v2 = radioa_array_table[i+1];
2112                        if (v1 < 0xcdcdcdcd)
2113                                _rtl8821ae_config_rf_radio_a(hw, v1, v2);
2114                        else{/*This line is the start line of branch.*/
2115                                if (!_rtl8821ae_check_condition(hw, v1)) {
2116                                        /*Discard the following (offset, data) pairs*/
2117                                        READ_NEXT_RF_PAIR(v1, v2, i);
2118                                        while (v2 != 0xDEAD &&
2119                                                v2 != 0xCDEF &&
2120                                                v2 != 0xCDCD && i < radioa_arraylen - 2)
2121                                                READ_NEXT_RF_PAIR(v1, v2, i);
2122
2123                                        i -= 2; /* prevent from for-loop += 2*/
2124                                } else {/*Configure matched pairs and skip to end of if-else.*/
2125                                        READ_NEXT_RF_PAIR(v1, v2, i);
2126                                        while (v2 != 0xDEAD &&
2127                                               v2 != 0xCDEF &&
2128                                               v2 != 0xCDCD && i < radioa_arraylen - 2) {
2129                                                _rtl8821ae_config_rf_radio_a(hw, v1, v2);
2130                                                READ_NEXT_RF_PAIR(v1, v2, i);
2131                                        }
2132
2133                                        while (v2 != 0xDEAD && i < radioa_arraylen - 2)
2134                                                READ_NEXT_RF_PAIR(v1, v2, i);
2135                                }
2136                        }
2137                }
2138                break;
2139
2140        case RF90_PATH_B:
2141                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2142                         "switch case not process\n");
2143                break;
2144        case RF90_PATH_C:
2145                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2146                         "switch case not process\n");
2147                break;
2148        case RF90_PATH_D:
2149                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2150                         "switch case not process\n");
2151                break;
2152        }
2153        return true;
2154}
2155
2156void rtl8821ae_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
2157{
2158        struct rtl_priv *rtlpriv = rtl_priv(hw);
2159        struct rtl_phy *rtlphy = &rtlpriv->phy;
2160
2161        rtlphy->default_initialgain[0] =
2162            (u8)rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
2163        rtlphy->default_initialgain[1] =
2164            (u8)rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
2165        rtlphy->default_initialgain[2] =
2166            (u8)rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
2167        rtlphy->default_initialgain[3] =
2168            (u8)rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
2169
2170        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
2171                 "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n",
2172                  rtlphy->default_initialgain[0],
2173                  rtlphy->default_initialgain[1],
2174                  rtlphy->default_initialgain[2],
2175                  rtlphy->default_initialgain[3]);
2176
2177        rtlphy->framesync = (u8)rtl_get_bbreg(hw,
2178                                               ROFDM0_RXDETECTOR3, MASKBYTE0);
2179        rtlphy->framesync_c34 = rtl_get_bbreg(hw,
2180                                              ROFDM0_RXDETECTOR2, MASKDWORD);
2181
2182        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
2183                 "Default framesync (0x%x) = 0x%x\n",
2184                  ROFDM0_RXDETECTOR3, rtlphy->framesync);
2185}
2186
2187static void phy_init_bb_rf_register_definition(struct ieee80211_hw *hw)
2188{
2189        struct rtl_priv *rtlpriv = rtl_priv(hw);
2190        struct rtl_phy *rtlphy = &rtlpriv->phy;
2191
2192        rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
2193        rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
2194
2195        rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
2196        rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
2197
2198        rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
2199        rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
2200
2201        rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = RA_LSSIWRITE_8821A;
2202        rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = RB_LSSIWRITE_8821A;
2203
2204        rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RHSSIREAD_8821AE;
2205        rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RHSSIREAD_8821AE;
2206
2207        rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RA_SIREAD_8821A;
2208        rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RB_SIREAD_8821A;
2209
2210        rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = RA_PIREAD_8821A;
2211        rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = RB_PIREAD_8821A;
2212}
2213
2214void rtl8821ae_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
2215{
2216        struct rtl_priv *rtlpriv = rtl_priv(hw);
2217        struct rtl_phy *rtlphy = &rtlpriv->phy;
2218        u8 txpwr_level;
2219        long txpwr_dbm;
2220
2221        txpwr_level = rtlphy->cur_cck_txpwridx;
2222        txpwr_dbm = _rtl8821ae_phy_txpwr_idx_to_dbm(hw,
2223                                                 WIRELESS_MODE_B, txpwr_level);
2224        txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
2225        if (_rtl8821ae_phy_txpwr_idx_to_dbm(hw,
2226                                         WIRELESS_MODE_G,
2227                                         txpwr_level) > txpwr_dbm)
2228                txpwr_dbm =
2229                    _rtl8821ae_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
2230                                                 txpwr_level);
2231        txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
2232        if (_rtl8821ae_phy_txpwr_idx_to_dbm(hw,
2233                                         WIRELESS_MODE_N_24G,
2234                                         txpwr_level) > txpwr_dbm)
2235                txpwr_dbm =
2236                    _rtl8821ae_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
2237                                                 txpwr_level);
2238        *powerlevel = txpwr_dbm;
2239}
2240
2241static bool _rtl8821ae_phy_get_chnl_index(u8 channel, u8 *chnl_index)
2242{
2243        u8 channel_5g[CHANNEL_MAX_NUMBER_5G] = {
2244                36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62,
2245                64, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118,
2246                120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140,
2247                142, 144, 149, 151, 153, 155, 157, 159, 161, 163, 165,
2248                167, 168, 169, 171, 173, 175, 177
2249        };
2250        u8 i = 0;
2251        bool in_24g = true;
2252
2253        if (channel <= 14) {
2254                in_24g = true;
2255                *chnl_index = channel - 1;
2256        } else {
2257                in_24g = false;
2258
2259                for (i = 0; i < CHANNEL_MAX_NUMBER_5G; ++i) {
2260                        if (channel_5g[i] == channel) {
2261                                *chnl_index = i;
2262                                return in_24g;
2263                        }
2264                }
2265        }
2266        return in_24g;
2267}
2268
2269static char _rtl8821ae_phy_get_ratesection_intxpower_byrate(u8 path, u8 rate)
2270{
2271        char rate_section = 0;
2272        switch (rate) {
2273        case DESC_RATE1M:
2274        case DESC_RATE2M:
2275        case DESC_RATE5_5M:
2276        case DESC_RATE11M:
2277                rate_section = 0;
2278                break;
2279        case DESC_RATE6M:
2280        case DESC_RATE9M:
2281        case DESC_RATE12M:
2282        case DESC_RATE18M:
2283                rate_section = 1;
2284                break;
2285        case DESC_RATE24M:
2286        case DESC_RATE36M:
2287        case DESC_RATE48M:
2288        case DESC_RATE54M:
2289                rate_section = 2;
2290                break;
2291        case DESC_RATEMCS0:
2292        case DESC_RATEMCS1:
2293        case DESC_RATEMCS2:
2294        case DESC_RATEMCS3:
2295                rate_section = 3;
2296                break;
2297        case DESC_RATEMCS4:
2298        case DESC_RATEMCS5:
2299        case DESC_RATEMCS6:
2300        case DESC_RATEMCS7:
2301                rate_section = 4;
2302                break;
2303        case DESC_RATEMCS8:
2304        case DESC_RATEMCS9:
2305        case DESC_RATEMCS10:
2306        case DESC_RATEMCS11:
2307                rate_section = 5;
2308                break;
2309        case DESC_RATEMCS12:
2310        case DESC_RATEMCS13:
2311        case DESC_RATEMCS14:
2312        case DESC_RATEMCS15:
2313                rate_section = 6;
2314                break;
2315        case DESC_RATEVHT1SS_MCS0:
2316        case DESC_RATEVHT1SS_MCS1:
2317        case DESC_RATEVHT1SS_MCS2:
2318        case DESC_RATEVHT1SS_MCS3:
2319                rate_section = 7;
2320                break;
2321        case DESC_RATEVHT1SS_MCS4:
2322        case DESC_RATEVHT1SS_MCS5:
2323        case DESC_RATEVHT1SS_MCS6:
2324        case DESC_RATEVHT1SS_MCS7:
2325                rate_section = 8;
2326                break;
2327        case DESC_RATEVHT1SS_MCS8:
2328        case DESC_RATEVHT1SS_MCS9:
2329        case DESC_RATEVHT2SS_MCS0:
2330        case DESC_RATEVHT2SS_MCS1:
2331                rate_section = 9;
2332                break;
2333        case DESC_RATEVHT2SS_MCS2:
2334        case DESC_RATEVHT2SS_MCS3:
2335        case DESC_RATEVHT2SS_MCS4:
2336        case DESC_RATEVHT2SS_MCS5:
2337                rate_section = 10;
2338                break;
2339        case DESC_RATEVHT2SS_MCS6:
2340        case DESC_RATEVHT2SS_MCS7:
2341        case DESC_RATEVHT2SS_MCS8:
2342        case DESC_RATEVHT2SS_MCS9:
2343                rate_section = 11;
2344                break;
2345        default:
2346                RT_ASSERT(true, "Rate_Section is Illegal\n");
2347                break;
2348        }
2349
2350        return rate_section;
2351}
2352
2353static char _rtl8812ae_phy_get_world_wide_limit(char  *limit_table)
2354{
2355        char min = limit_table[0];
2356        u8 i = 0;
2357
2358        for (i = 0; i < MAX_REGULATION_NUM; ++i) {
2359                if (limit_table[i] < min)
2360                        min = limit_table[i];
2361        }
2362        return min;
2363}
2364
2365static char _rtl8812ae_phy_get_txpower_limit(struct ieee80211_hw *hw,
2366                                             u8 band,
2367                                             enum ht_channel_width bandwidth,
2368                                             enum radio_path rf_path,
2369                                             u8 rate, u8 channel)
2370{
2371        struct rtl_priv *rtlpriv = rtl_priv(hw);
2372        struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
2373        struct rtl_phy *rtlphy = &rtlpriv->phy;
2374        short band_temp = -1, regulation = -1, bandwidth_temp = -1,
2375                 rate_section = -1, channel_temp = -1;
2376        u16 bd, regu, bdwidth, sec, chnl;
2377        char power_limit = MAX_POWER_INDEX;
2378
2379        if (rtlefuse->eeprom_regulatory == 2)
2380                return MAX_POWER_INDEX;
2381
2382        regulation = TXPWR_LMT_WW;
2383
2384        if (band == BAND_ON_2_4G)
2385                band_temp = 0;
2386        else if (band == BAND_ON_5G)
2387                band_temp = 1;
2388
2389        if (bandwidth == HT_CHANNEL_WIDTH_20)
2390                bandwidth_temp = 0;
2391        else if (bandwidth == HT_CHANNEL_WIDTH_20_40)
2392                bandwidth_temp = 1;
2393        else if (bandwidth == HT_CHANNEL_WIDTH_80)
2394                bandwidth_temp = 2;
2395
2396        switch (rate) {
2397        case DESC_RATE1M:
2398        case DESC_RATE2M:
2399        case DESC_RATE5_5M:
2400        case DESC_RATE11M:
2401                rate_section = 0;
2402                break;
2403        case DESC_RATE6M:
2404        case DESC_RATE9M:
2405        case DESC_RATE12M:
2406        case DESC_RATE18M:
2407        case DESC_RATE24M:
2408        case DESC_RATE36M:
2409        case DESC_RATE48M:
2410        case DESC_RATE54M:
2411                rate_section = 1;
2412                break;
2413        case DESC_RATEMCS0:
2414        case DESC_RATEMCS1:
2415        case DESC_RATEMCS2:
2416        case DESC_RATEMCS3:
2417        case DESC_RATEMCS4:
2418        case DESC_RATEMCS5:
2419        case DESC_RATEMCS6:
2420        case DESC_RATEMCS7:
2421                rate_section = 2;
2422                break;
2423        case DESC_RATEMCS8:
2424        case DESC_RATEMCS9:
2425        case DESC_RATEMCS10:
2426        case DESC_RATEMCS11:
2427        case DESC_RATEMCS12:
2428        case DESC_RATEMCS13:
2429        case DESC_RATEMCS14:
2430        case DESC_RATEMCS15:
2431                rate_section = 3;
2432                break;
2433        case DESC_RATEVHT1SS_MCS0:
2434        case DESC_RATEVHT1SS_MCS1:
2435        case DESC_RATEVHT1SS_MCS2:
2436        case DESC_RATEVHT1SS_MCS3:
2437        case DESC_RATEVHT1SS_MCS4:
2438        case DESC_RATEVHT1SS_MCS5:
2439        case DESC_RATEVHT1SS_MCS6:
2440        case DESC_RATEVHT1SS_MCS7:
2441        case DESC_RATEVHT1SS_MCS8:
2442        case DESC_RATEVHT1SS_MCS9:
2443                rate_section = 4;
2444                break;
2445        case DESC_RATEVHT2SS_MCS0:
2446        case DESC_RATEVHT2SS_MCS1:
2447        case DESC_RATEVHT2SS_MCS2:
2448        case DESC_RATEVHT2SS_MCS3:
2449        case DESC_RATEVHT2SS_MCS4:
2450        case DESC_RATEVHT2SS_MCS5:
2451        case DESC_RATEVHT2SS_MCS6:
2452        case DESC_RATEVHT2SS_MCS7:
2453        case DESC_RATEVHT2SS_MCS8:
2454        case DESC_RATEVHT2SS_MCS9:
2455                rate_section = 5;
2456                break;
2457        default:
2458                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
2459                        "Wrong rate 0x%x\n", rate);
2460                break;
2461        }
2462
2463        if (band_temp == BAND_ON_5G  && rate_section == 0)
2464                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
2465                         "Wrong rate 0x%x: No CCK in 5G Band\n", rate);
2466
2467        /*workaround for wrong index combination to obtain tx power limit,
2468          OFDM only exists in BW 20M*/
2469        if (rate_section == 1)
2470                bandwidth_temp = 0;
2471
2472        /*workaround for wrong index combination to obtain tx power limit,
2473         *HT on 80M will reference to HT on 40M
2474         */
2475        if ((rate_section == 2 || rate_section == 3) && band == BAND_ON_5G &&
2476            bandwidth_temp == 2)
2477                bandwidth_temp = 1;
2478
2479        if (band == BAND_ON_2_4G)
2480                channel_temp = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
2481                BAND_ON_2_4G, channel);
2482        else if (band == BAND_ON_5G)
2483                channel_temp = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw,
2484                BAND_ON_5G, channel);
2485        else if (band == BAND_ON_BOTH)
2486                ;/* BAND_ON_BOTH don't care temporarily */
2487
2488        if (band_temp == -1 || regulation == -1 || bandwidth_temp == -1 ||
2489                rate_section == -1 || channel_temp == -1) {
2490                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
2491                         "Wrong index value to access power limit table [band %d][regulation %d][bandwidth %d][rf_path %d][rate_section %d][chnl %d]\n",
2492                         band_temp, regulation, bandwidth_temp, rf_path,
2493                         rate_section, channel_temp);
2494                return MAX_POWER_INDEX;
2495        }
2496
2497        bd = band_temp;
2498        regu = regulation;
2499        bdwidth = bandwidth_temp;
2500        sec = rate_section;
2501        chnl = channel_temp;
2502
2503        if (band == BAND_ON_2_4G) {
2504                char limits[10] = {0};
2505                u8 i;
2506
2507                for (i = 0; i < 4; ++i)
2508                        limits[i] = rtlphy->txpwr_limit_2_4g[i][bdwidth]
2509                        [sec][chnl][rf_path];
2510
2511                power_limit = (regulation == TXPWR_LMT_WW) ?
2512                        _rtl8812ae_phy_get_world_wide_limit(limits) :
2513                        rtlphy->txpwr_limit_2_4g[regu][bdwidth]
2514                                        [sec][chnl][rf_path];
2515        } else if (band == BAND_ON_5G) {
2516                char limits[10] = {0};
2517                u8 i;
2518
2519                for (i = 0; i < MAX_REGULATION_NUM; ++i)
2520                        limits[i] = rtlphy->txpwr_limit_5g[i][bdwidth]
2521                        [sec][chnl][rf_path];
2522
2523                power_limit = (regulation == TXPWR_LMT_WW) ?
2524                        _rtl8812ae_phy_get_world_wide_limit(limits) :
2525                        rtlphy->txpwr_limit_5g[regu][chnl]
2526                        [sec][chnl][rf_path];
2527        } else {
2528                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2529                         "No power limit table of the specified band\n");
2530        }
2531        return power_limit;
2532}
2533
2534static char _rtl8821ae_phy_get_txpower_by_rate(struct ieee80211_hw *hw,
2535                                        u8 band, u8 path, u8 rate)
2536{
2537        struct rtl_priv *rtlpriv = rtl_priv(hw);
2538        struct rtl_phy *rtlphy = &rtlpriv->phy;
2539        u8 shift = 0, rate_section, tx_num;
2540        char tx_pwr_diff = 0;
2541        char limit = 0;
2542
2543        rate_section = _rtl8821ae_phy_get_ratesection_intxpower_byrate(path, rate);
2544        tx_num = RF_TX_NUM_NONIMPLEMENT;
2545
2546        if (tx_num == RF_TX_NUM_NONIMPLEMENT) {
2547                if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) ||
2548                        (rate >= DESC_RATEVHT2SS_MCS2 && rate <= DESC_RATEVHT2SS_MCS9))
2549                        tx_num = RF_2TX;
2550                else
2551                        tx_num = RF_1TX;
2552        }
2553
2554        switch (rate) {
2555        case DESC_RATE1M:
2556        case DESC_RATE6M:
2557        case DESC_RATE24M:
2558        case DESC_RATEMCS0:
2559        case DESC_RATEMCS4:
2560        case DESC_RATEMCS8:
2561        case DESC_RATEMCS12:
2562        case DESC_RATEVHT1SS_MCS0:
2563        case DESC_RATEVHT1SS_MCS4:
2564        case DESC_RATEVHT1SS_MCS8:
2565        case DESC_RATEVHT2SS_MCS2:
2566        case DESC_RATEVHT2SS_MCS6:
2567                shift = 0;
2568                break;
2569        case DESC_RATE2M:
2570        case DESC_RATE9M:
2571        case DESC_RATE36M:
2572        case DESC_RATEMCS1:
2573        case DESC_RATEMCS5:
2574        case DESC_RATEMCS9:
2575        case DESC_RATEMCS13:
2576        case DESC_RATEVHT1SS_MCS1:
2577        case DESC_RATEVHT1SS_MCS5:
2578        case DESC_RATEVHT1SS_MCS9:
2579        case DESC_RATEVHT2SS_MCS3:
2580        case DESC_RATEVHT2SS_MCS7:
2581                shift = 8;
2582                break;
2583        case DESC_RATE5_5M:
2584        case DESC_RATE12M:
2585        case DESC_RATE48M:
2586        case DESC_RATEMCS2:
2587        case DESC_RATEMCS6:
2588        case DESC_RATEMCS10:
2589        case DESC_RATEMCS14:
2590        case DESC_RATEVHT1SS_MCS2:
2591        case DESC_RATEVHT1SS_MCS6:
2592        case DESC_RATEVHT2SS_MCS0:
2593        case DESC_RATEVHT2SS_MCS4:
2594        case DESC_RATEVHT2SS_MCS8:
2595                shift = 16;
2596                break;
2597        case DESC_RATE11M:
2598        case DESC_RATE18M:
2599        case DESC_RATE54M:
2600        case DESC_RATEMCS3:
2601        case DESC_RATEMCS7:
2602        case DESC_RATEMCS11:
2603        case DESC_RATEMCS15:
2604        case DESC_RATEVHT1SS_MCS3:
2605        case DESC_RATEVHT1SS_MCS7:
2606        case DESC_RATEVHT2SS_MCS1:
2607        case DESC_RATEVHT2SS_MCS5:
2608        case DESC_RATEVHT2SS_MCS9:
2609                shift = 24;
2610                break;
2611        default:
2612                RT_ASSERT(true, "Rate_Section is Illegal\n");
2613                break;
2614        }
2615
2616        tx_pwr_diff = (u8)(rtlphy->tx_power_by_rate_offset[band][path]
2617                [tx_num][rate_section] >> shift) & 0xff;
2618
2619        /* RegEnableTxPowerLimit == 1 for 8812a & 8821a */
2620        if (rtlpriv->efuse.eeprom_regulatory != 2) {
2621                limit = _rtl8812ae_phy_get_txpower_limit(hw, band,
2622                        rtlphy->current_chan_bw, path, rate,
2623                        rtlphy->current_channel);
2624
2625                if (rate == DESC_RATEVHT1SS_MCS8 || rate == DESC_RATEVHT1SS_MCS9  ||
2626                         rate == DESC_RATEVHT2SS_MCS8 || rate == DESC_RATEVHT2SS_MCS9) {
2627                        if (limit < 0) {
2628                                if (tx_pwr_diff < (-limit))
2629                                        tx_pwr_diff = -limit;
2630                        }
2631                } else {
2632                        if (limit < 0)
2633                                tx_pwr_diff = limit;
2634                        else
2635                                tx_pwr_diff = tx_pwr_diff > limit ? limit : tx_pwr_diff;
2636                }
2637                RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2638                        "Maximum power by rate %d, final power by rate %d\n",
2639                        limit, tx_pwr_diff);
2640        }
2641
2642        return  tx_pwr_diff;
2643}
2644
2645static u8 _rtl8821ae_get_txpower_index(struct ieee80211_hw *hw, u8 path,
2646                                        u8 rate, u8 bandwidth, u8 channel)
2647{
2648        struct rtl_priv *rtlpriv = rtl_priv(hw);
2649        struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
2650        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2651        u8 index = (channel - 1);
2652        u8 txpower = 0;
2653        bool in_24g = false;
2654        char powerdiff_byrate = 0;
2655
2656        if (((rtlhal->current_bandtype == BAND_ON_2_4G) &&
2657            (channel > 14 || channel < 1)) ||
2658            ((rtlhal->current_bandtype == BAND_ON_5G) && (channel <= 14))) {
2659                index = 0;
2660                RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
2661                        "Illegal channel!!\n");
2662        }
2663
2664        in_24g = _rtl8821ae_phy_get_chnl_index(channel, &index);
2665        if (in_24g) {
2666                if (RTL8821AE_RX_HAL_IS_CCK_RATE(rate))
2667                        txpower = rtlefuse->txpwrlevel_cck[path][index];
2668                else if (DESC_RATE6M <= rate)
2669                        txpower = rtlefuse->txpwrlevel_ht40_1s[path][index];
2670                else
2671                        RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "invalid rate\n");
2672
2673                if (DESC_RATE6M <= rate && rate <= DESC_RATE54M &&
2674                    !RTL8821AE_RX_HAL_IS_CCK_RATE(rate))
2675                        txpower += rtlefuse->txpwr_legacyhtdiff[path][TX_1S];
2676
2677                if (bandwidth == HT_CHANNEL_WIDTH_20) {
2678                        if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2679                                (DESC_RATEVHT1SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
2680                                txpower += rtlefuse->txpwr_ht20diff[path][TX_1S];
2681                        if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2682                                (DESC_RATEVHT2SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
2683                                txpower += rtlefuse->txpwr_ht20diff[path][TX_2S];
2684                } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
2685                        if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2686                                (DESC_RATEVHT1SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
2687                                txpower += rtlefuse->txpwr_ht40diff[path][TX_1S];
2688                        if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2689                                (DESC_RATEVHT2SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9))
2690                                txpower += rtlefuse->txpwr_ht40diff[path][TX_2S];
2691                } else if (bandwidth == HT_CHANNEL_WIDTH_80) {
2692                        if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2693                            (DESC_RATEVHT1SS_MCS0 <= rate &&
2694                             rate <= DESC_RATEVHT2SS_MCS9))
2695                                txpower += rtlefuse->txpwr_ht40diff[path][TX_1S];
2696                        if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2697                            (DESC_RATEVHT2SS_MCS0 <= rate &&
2698                             rate <= DESC_RATEVHT2SS_MCS9))
2699                                txpower += rtlefuse->txpwr_ht40diff[path][TX_2S];
2700                }
2701        } else {
2702                if (DESC_RATE6M <= rate)
2703                        txpower = rtlefuse->txpwr_5g_bw40base[path][index];
2704                else
2705                        RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_WARNING,
2706                                 "INVALID Rate.\n");
2707
2708                if (DESC_RATE6M <= rate && rate <= DESC_RATE54M &&
2709                    !RTL8821AE_RX_HAL_IS_CCK_RATE(rate))
2710                        txpower += rtlefuse->txpwr_5g_ofdmdiff[path][TX_1S];
2711
2712                if (bandwidth == HT_CHANNEL_WIDTH_20) {
2713                        if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2714                            (DESC_RATEVHT1SS_MCS0 <= rate &&
2715                             rate <= DESC_RATEVHT2SS_MCS9))
2716                                txpower += rtlefuse->txpwr_5g_bw20diff[path][TX_1S];
2717                        if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2718                            (DESC_RATEVHT2SS_MCS0 <= rate &&
2719                             rate <= DESC_RATEVHT2SS_MCS9))
2720                                txpower += rtlefuse->txpwr_5g_bw20diff[path][TX_2S];
2721                } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
2722                        if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2723                            (DESC_RATEVHT1SS_MCS0 <= rate &&
2724                             rate <= DESC_RATEVHT2SS_MCS9))
2725                                txpower += rtlefuse->txpwr_5g_bw40diff[path][TX_1S];
2726                        if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2727                            (DESC_RATEVHT2SS_MCS0 <= rate &&
2728                             rate <= DESC_RATEVHT2SS_MCS9))
2729                                txpower += rtlefuse->txpwr_5g_bw40diff[path][TX_2S];
2730                } else if (bandwidth == HT_CHANNEL_WIDTH_80) {
2731                        u8 channel_5g_80m[CHANNEL_MAX_NUMBER_5G_80M] = {
2732                                42, 58, 106, 122, 138, 155, 171
2733                        };
2734                        u8 i;
2735
2736                        for (i = 0; i < sizeof(channel_5g_80m) / sizeof(u8); ++i)
2737                                if (channel_5g_80m[i] == channel)
2738                                        index = i;
2739
2740                        if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) ||
2741                            (DESC_RATEVHT1SS_MCS0 <= rate &&
2742                             rate <= DESC_RATEVHT2SS_MCS9))
2743                                txpower = rtlefuse->txpwr_5g_bw80base[path][index]
2744                                        + rtlefuse->txpwr_5g_bw80diff[path][TX_1S];
2745                        if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) ||
2746                            (DESC_RATEVHT2SS_MCS0 <= rate &&
2747                             rate <= DESC_RATEVHT2SS_MCS9))
2748                                txpower = rtlefuse->txpwr_5g_bw80base[path][index]
2749                                        + rtlefuse->txpwr_5g_bw80diff[path][TX_1S]
2750                                        + rtlefuse->txpwr_5g_bw80diff[path][TX_2S];
2751                    }
2752        }
2753        if (rtlefuse->eeprom_regulatory != 2)
2754                powerdiff_byrate =
2755                  _rtl8821ae_phy_get_txpower_by_rate(hw, (u8)(!in_24g),
2756                                                     path, rate);
2757
2758        if (rate == DESC_RATEVHT1SS_MCS8 || rate == DESC_RATEVHT1SS_MCS9 ||
2759            rate == DESC_RATEVHT2SS_MCS8 || rate == DESC_RATEVHT2SS_MCS9)
2760                txpower -= powerdiff_byrate;
2761        else
2762                txpower += powerdiff_byrate;
2763
2764        if (rate > DESC_RATE11M)
2765                txpower += rtlpriv->dm.remnant_ofdm_swing_idx[path];
2766        else
2767                txpower += rtlpriv->dm.remnant_cck_idx;
2768
2769        if (txpower > MAX_POWER_INDEX)
2770                txpower = MAX_POWER_INDEX;
2771
2772        return txpower;
2773}
2774
2775static void _rtl8821ae_phy_set_txpower_index(struct ieee80211_hw *hw,
2776                                             u8 power_index, u8 path, u8 rate)
2777{
2778        struct rtl_priv *rtlpriv = rtl_priv(hw);
2779
2780        if (path == RF90_PATH_A) {
2781                switch (rate) {
2782                case DESC_RATE1M:
2783                        rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2784                                      MASKBYTE0, power_index);
2785                        break;
2786                case DESC_RATE2M:
2787                        rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2788                                      MASKBYTE1, power_index);
2789                        break;
2790                case DESC_RATE5_5M:
2791                        rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2792                                      MASKBYTE2, power_index);
2793                        break;
2794                case DESC_RATE11M:
2795                        rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1,
2796                                      MASKBYTE3, power_index);
2797                        break;
2798                case DESC_RATE6M:
2799                        rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2800                                      MASKBYTE0, power_index);
2801                        break;
2802                case DESC_RATE9M:
2803                        rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2804                                      MASKBYTE1, power_index);
2805                        break;
2806                case DESC_RATE12M:
2807                        rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2808                                      MASKBYTE2, power_index);
2809                        break;
2810                case DESC_RATE18M:
2811                        rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6,
2812                                      MASKBYTE3, power_index);
2813                        break;
2814                case DESC_RATE24M:
2815                        rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2816                                      MASKBYTE0, power_index);
2817                        break;
2818                case DESC_RATE36M:
2819                        rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2820                                      MASKBYTE1, power_index);
2821                        break;
2822                case DESC_RATE48M:
2823                        rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2824                                      MASKBYTE2, power_index);
2825                        break;
2826                case DESC_RATE54M:
2827                        rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24,
2828                                      MASKBYTE3, power_index);
2829                        break;
2830                case DESC_RATEMCS0:
2831                        rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2832                                      MASKBYTE0, power_index);
2833                        break;
2834                case DESC_RATEMCS1:
2835                        rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2836                                      MASKBYTE1, power_index);
2837                        break;
2838                case DESC_RATEMCS2:
2839                        rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2840                                      MASKBYTE2, power_index);
2841                        break;
2842                case DESC_RATEMCS3:
2843                        rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00,
2844                                      MASKBYTE3, power_index);
2845                        break;
2846                case DESC_RATEMCS4:
2847                        rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2848                                      MASKBYTE0, power_index);
2849                        break;
2850                case DESC_RATEMCS5:
2851                        rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2852                                      MASKBYTE1, power_index);
2853                        break;
2854                case DESC_RATEMCS6:
2855                        rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2856                                      MASKBYTE2, power_index);
2857                        break;
2858                case DESC_RATEMCS7:
2859                        rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04,
2860                                      MASKBYTE3, power_index);
2861                        break;
2862                case DESC_RATEMCS8:
2863                        rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2864                                      MASKBYTE0, power_index);
2865                        break;
2866                case DESC_RATEMCS9:
2867                        rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2868                                      MASKBYTE1, power_index);
2869                        break;
2870                case DESC_RATEMCS10:
2871                        rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2872                                      MASKBYTE2, power_index);
2873                        break;
2874                case DESC_RATEMCS11:
2875                        rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08,
2876                                      MASKBYTE3, power_index);
2877                        break;
2878                case DESC_RATEMCS12:
2879                        rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2880                                      MASKBYTE0, power_index);
2881                        break;
2882                case DESC_RATEMCS13:
2883                        rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2884                                      MASKBYTE1, power_index);
2885                        break;
2886                case DESC_RATEMCS14:
2887                        rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2888                                      MASKBYTE2, power_index);
2889                        break;
2890                case DESC_RATEMCS15:
2891                        rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12,
2892                                      MASKBYTE3, power_index);
2893                        break;
2894                case DESC_RATEVHT1SS_MCS0:
2895                        rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2896                                      MASKBYTE0, power_index);
2897                        break;
2898                case DESC_RATEVHT1SS_MCS1:
2899                        rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2900                                      MASKBYTE1, power_index);
2901                        break;
2902                case DESC_RATEVHT1SS_MCS2:
2903                        rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2904                                      MASKBYTE2, power_index);
2905                        break;
2906                case DESC_RATEVHT1SS_MCS3:
2907                        rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0,
2908                                      MASKBYTE3, power_index);
2909                        break;
2910                case DESC_RATEVHT1SS_MCS4:
2911                        rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
2912                                      MASKBYTE0, power_index);
2913                        break;
2914                case DESC_RATEVHT1SS_MCS5:
2915                        rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
2916                                      MASKBYTE1, power_index);
2917                        break;
2918                case DESC_RATEVHT1SS_MCS6:
2919                        rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
2920                                      MASKBYTE2, power_index);
2921                        break;
2922                case DESC_RATEVHT1SS_MCS7:
2923                        rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4,
2924                                      MASKBYTE3, power_index);
2925                        break;
2926                case DESC_RATEVHT1SS_MCS8:
2927                        rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
2928                                      MASKBYTE0, power_index);
2929                        break;
2930                case DESC_RATEVHT1SS_MCS9:
2931                        rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
2932                                      MASKBYTE1, power_index);
2933                        break;
2934                case DESC_RATEVHT2SS_MCS0:
2935                        rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
2936                                      MASKBYTE2, power_index);
2937                        break;
2938                case DESC_RATEVHT2SS_MCS1:
2939                        rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8,
2940                                      MASKBYTE3, power_index);
2941                        break;
2942                case DESC_RATEVHT2SS_MCS2:
2943                        rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
2944                                      MASKBYTE0, power_index);
2945                        break;
2946                case DESC_RATEVHT2SS_MCS3:
2947                        rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
2948                                      MASKBYTE1, power_index);
2949                        break;
2950                case DESC_RATEVHT2SS_MCS4:
2951                        rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
2952                                      MASKBYTE2, power_index);
2953                        break;
2954                case DESC_RATEVHT2SS_MCS5:
2955                        rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2,
2956                                      MASKBYTE3, power_index);
2957                        break;
2958                case DESC_RATEVHT2SS_MCS6:
2959                        rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
2960                                      MASKBYTE0, power_index);
2961                        break;
2962                case DESC_RATEVHT2SS_MCS7:
2963                        rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
2964                                      MASKBYTE1, power_index);
2965                        break;
2966                case DESC_RATEVHT2SS_MCS8:
2967                        rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
2968                                      MASKBYTE2, power_index);
2969                        break;
2970                case DESC_RATEVHT2SS_MCS9:
2971                        rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6,
2972                                      MASKBYTE3, power_index);
2973                        break;
2974                default:
2975                        RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
2976                                "Invalid Rate!!\n");
2977                        break;
2978                }
2979        } else if (path == RF90_PATH_B) {
2980                switch (rate) {
2981                case DESC_RATE1M:
2982                        rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
2983                                      MASKBYTE0, power_index);
2984                        break;
2985                case DESC_RATE2M:
2986                        rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
2987                                      MASKBYTE1, power_index);
2988                        break;
2989                case DESC_RATE5_5M:
2990                        rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
2991                                      MASKBYTE2, power_index);
2992                        break;
2993                case DESC_RATE11M:
2994                        rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1,
2995                                      MASKBYTE3, power_index);
2996                        break;
2997                case DESC_RATE6M:
2998                        rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
2999                                      MASKBYTE0, power_index);
3000                        break;
3001                case DESC_RATE9M:
3002                        rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
3003                                      MASKBYTE1, power_index);
3004                        break;
3005                case DESC_RATE12M:
3006                        rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
3007                                      MASKBYTE2, power_index);
3008                        break;
3009                case DESC_RATE18M:
3010                        rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6,
3011                                      MASKBYTE3, power_index);
3012                        break;
3013                case DESC_RATE24M:
3014                        rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
3015                                      MASKBYTE0, power_index);
3016                        break;
3017                case DESC_RATE36M:
3018                        rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
3019                                      MASKBYTE1, power_index);
3020                        break;
3021                case DESC_RATE48M:
3022                        rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
3023                                      MASKBYTE2, power_index);
3024                        break;
3025                case DESC_RATE54M:
3026                        rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24,
3027                                      MASKBYTE3, power_index);
3028                        break;
3029                case DESC_RATEMCS0:
3030                        rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
3031                                      MASKBYTE0, power_index);
3032                        break;
3033                case DESC_RATEMCS1:
3034                        rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
3035                                      MASKBYTE1, power_index);
3036                        break;
3037                case DESC_RATEMCS2:
3038                        rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
3039                                      MASKBYTE2, power_index);
3040                        break;
3041                case DESC_RATEMCS3:
3042                        rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00,
3043                                      MASKBYTE3, power_index);
3044                        break;
3045                case DESC_RATEMCS4:
3046                        rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
3047                                      MASKBYTE0, power_index);
3048                        break;
3049                case DESC_RATEMCS5:
3050                        rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
3051                                      MASKBYTE1, power_index);
3052                        break;
3053                case DESC_RATEMCS6:
3054                        rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
3055                                      MASKBYTE2, power_index);
3056                        break;
3057                case DESC_RATEMCS7:
3058                        rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04,
3059                                      MASKBYTE3, power_index);
3060                        break;
3061                case DESC_RATEMCS8:
3062                        rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3063                                      MASKBYTE0, power_index);
3064                        break;
3065                case DESC_RATEMCS9:
3066                        rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3067                                      MASKBYTE1, power_index);
3068                        break;
3069                case DESC_RATEMCS10:
3070                        rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3071                                      MASKBYTE2, power_index);
3072                        break;
3073                case DESC_RATEMCS11:
3074                        rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08,
3075                                      MASKBYTE3, power_index);
3076                        break;
3077                case DESC_RATEMCS12:
3078                        rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3079                                      MASKBYTE0, power_index);
3080                        break;
3081                case DESC_RATEMCS13:
3082                        rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3083                                      MASKBYTE1, power_index);
3084                        break;
3085                case DESC_RATEMCS14:
3086                        rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3087                                      MASKBYTE2, power_index);
3088                        break;
3089                case DESC_RATEMCS15:
3090                        rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12,
3091                                      MASKBYTE3, power_index);
3092                        break;
3093                case DESC_RATEVHT1SS_MCS0:
3094                        rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3095                                      MASKBYTE0, power_index);
3096                        break;
3097                case DESC_RATEVHT1SS_MCS1:
3098                        rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3099                                      MASKBYTE1, power_index);
3100                        break;
3101                case DESC_RATEVHT1SS_MCS2:
3102                        rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3103                                      MASKBYTE2, power_index);
3104                        break;
3105                case DESC_RATEVHT1SS_MCS3:
3106                        rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0,
3107                                      MASKBYTE3, power_index);
3108                        break;
3109                case DESC_RATEVHT1SS_MCS4:
3110                        rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3111                                      MASKBYTE0, power_index);
3112                        break;
3113                case DESC_RATEVHT1SS_MCS5:
3114                        rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3115                                      MASKBYTE1, power_index);
3116                        break;
3117                case DESC_RATEVHT1SS_MCS6:
3118                        rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3119                                      MASKBYTE2, power_index);
3120                        break;
3121                case DESC_RATEVHT1SS_MCS7:
3122                        rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4,
3123                                      MASKBYTE3, power_index);
3124                        break;
3125                case DESC_RATEVHT1SS_MCS8:
3126                        rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3127                                      MASKBYTE0, power_index);
3128                        break;
3129                case DESC_RATEVHT1SS_MCS9:
3130                        rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3131                                      MASKBYTE1, power_index);
3132                        break;
3133                case DESC_RATEVHT2SS_MCS0:
3134                        rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3135                                      MASKBYTE2, power_index);
3136                        break;
3137                case DESC_RATEVHT2SS_MCS1:
3138                        rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8,
3139                                      MASKBYTE3, power_index);
3140                        break;
3141                case DESC_RATEVHT2SS_MCS2:
3142                        rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3143                                      MASKBYTE0, power_index);
3144                        break;
3145                case DESC_RATEVHT2SS_MCS3:
3146                        rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3147                                      MASKBYTE1, power_index);
3148                        break;
3149                case DESC_RATEVHT2SS_MCS4:
3150                        rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3151                                      MASKBYTE2, power_index);
3152                        break;
3153                case DESC_RATEVHT2SS_MCS5:
3154                        rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2,
3155                                      MASKBYTE3, power_index);
3156                        break;
3157                case DESC_RATEVHT2SS_MCS6:
3158                        rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3159                                      MASKBYTE0, power_index);
3160                        break;
3161                case DESC_RATEVHT2SS_MCS7:
3162                        rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3163                                      MASKBYTE1, power_index);
3164                        break;
3165                case DESC_RATEVHT2SS_MCS8:
3166                        rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3167                                      MASKBYTE2, power_index);
3168                        break;
3169                case DESC_RATEVHT2SS_MCS9:
3170                        rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6,
3171                                      MASKBYTE3, power_index);
3172                        break;
3173                default:
3174                        RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
3175                                 "Invalid Rate!!\n");
3176                        break;
3177                }
3178        } else {
3179                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
3180                         "Invalid RFPath!!\n");
3181        }
3182}
3183
3184static void _rtl8821ae_phy_set_txpower_level_by_path(struct ieee80211_hw *hw,
3185                                                     u8 *array, u8 path,
3186                                                     u8 channel, u8 size)
3187{
3188        struct rtl_priv *rtlpriv = rtl_priv(hw);
3189        struct rtl_phy *rtlphy = &rtlpriv->phy;
3190        u8 i;
3191        u8 power_index;
3192
3193        for (i = 0; i < size; i++) {
3194                power_index =
3195                  _rtl8821ae_get_txpower_index(hw, path, array[i],
3196                                               rtlphy->current_chan_bw,
3197                                               channel);
3198                _rtl8821ae_phy_set_txpower_index(hw, power_index, path,
3199                                                 array[i]);
3200        }
3201}
3202
3203static void _rtl8821ae_phy_txpower_training_by_path(struct ieee80211_hw *hw,
3204                                                    u8 bw, u8 channel, u8 path)
3205{
3206        struct rtl_priv *rtlpriv = rtl_priv(hw);
3207        struct rtl_phy *rtlphy = &rtlpriv->phy;
3208
3209        u8 i;
3210        u32 power_level, data, offset;
3211
3212        if (path >= rtlphy->num_total_rfpath)
3213                return;
3214
3215        data = 0;
3216        if (path == RF90_PATH_A) {
3217                power_level =
3218                        _rtl8821ae_get_txpower_index(hw, RF90_PATH_A,
3219                        DESC_RATEMCS7, bw, channel);
3220                offset =  RA_TXPWRTRAING;
3221        } else {
3222                power_level =
3223                        _rtl8821ae_get_txpower_index(hw, RF90_PATH_B,
3224                        DESC_RATEMCS7, bw, channel);
3225                offset =  RB_TXPWRTRAING;
3226        }
3227
3228        for (i = 0; i < 3; i++) {
3229                if (i == 0)
3230                        power_level = power_level - 10;
3231                else if (i == 1)
3232                        power_level = power_level - 8;
3233                else
3234                        power_level = power_level - 6;
3235
3236                data |= (((power_level > 2) ? (power_level) : 2) << (i * 8));
3237        }
3238        rtl_set_bbreg(hw, offset, 0xffffff, data);
3239}
3240
3241void rtl8821ae_phy_set_txpower_level_by_path(struct ieee80211_hw *hw,
3242                                             u8 channel, u8 path)
3243{
3244        /* struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); */
3245        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3246        struct rtl_priv *rtlpriv = rtl_priv(hw);
3247        struct rtl_phy *rtlphy = &rtlpriv->phy;
3248        u8 cck_rates[]  = {DESC_RATE1M, DESC_RATE2M, DESC_RATE5_5M,
3249                              DESC_RATE11M};
3250        u8 sizes_of_cck_retes = 4;
3251        u8 ofdm_rates[]  = {DESC_RATE6M, DESC_RATE9M, DESC_RATE12M,
3252                                DESC_RATE18M, DESC_RATE24M, DESC_RATE36M,
3253                                DESC_RATE48M, DESC_RATE54M};
3254        u8 sizes_of_ofdm_retes = 8;
3255        u8 ht_rates_1t[]  = {DESC_RATEMCS0, DESC_RATEMCS1, DESC_RATEMCS2,
3256                                DESC_RATEMCS3, DESC_RATEMCS4, DESC_RATEMCS5,
3257                                DESC_RATEMCS6, DESC_RATEMCS7};
3258        u8 sizes_of_ht_retes_1t = 8;
3259        u8 ht_rates_2t[]  = {DESC_RATEMCS8, DESC_RATEMCS9,
3260                                DESC_RATEMCS10, DESC_RATEMCS11,
3261                                DESC_RATEMCS12, DESC_RATEMCS13,
3262                                DESC_RATEMCS14, DESC_RATEMCS15};
3263        u8 sizes_of_ht_retes_2t = 8;
3264        u8 vht_rates_1t[]  = {DESC_RATEVHT1SS_MCS0, DESC_RATEVHT1SS_MCS1,
3265                                DESC_RATEVHT1SS_MCS2, DESC_RATEVHT1SS_MCS3,
3266                                DESC_RATEVHT1SS_MCS4, DESC_RATEVHT1SS_MCS5,
3267                                DESC_RATEVHT1SS_MCS6, DESC_RATEVHT1SS_MCS7,
3268                             DESC_RATEVHT1SS_MCS8, DESC_RATEVHT1SS_MCS9};
3269        u8 vht_rates_2t[]  = {DESC_RATEVHT2SS_MCS0, DESC_RATEVHT2SS_MCS1,
3270                                DESC_RATEVHT2SS_MCS2, DESC_RATEVHT2SS_MCS3,
3271                                DESC_RATEVHT2SS_MCS4, DESC_RATEVHT2SS_MCS5,
3272                                DESC_RATEVHT2SS_MCS6, DESC_RATEVHT2SS_MCS7,
3273                                DESC_RATEVHT2SS_MCS8, DESC_RATEVHT2SS_MCS9};
3274        u8 sizes_of_vht_retes = 10;
3275
3276        if (rtlhal->current_bandtype == BAND_ON_2_4G)
3277                _rtl8821ae_phy_set_txpower_level_by_path(hw, cck_rates, path, channel,
3278                                                         sizes_of_cck_retes);
3279
3280        _rtl8821ae_phy_set_txpower_level_by_path(hw, ofdm_rates, path, channel,
3281                                                 sizes_of_ofdm_retes);
3282        _rtl8821ae_phy_set_txpower_level_by_path(hw, ht_rates_1t, path, channel,
3283                                                 sizes_of_ht_retes_1t);
3284        _rtl8821ae_phy_set_txpower_level_by_path(hw, vht_rates_1t, path, channel,
3285                                                 sizes_of_vht_retes);
3286
3287        if (rtlphy->num_total_rfpath >= 2) {
3288                _rtl8821ae_phy_set_txpower_level_by_path(hw, ht_rates_2t, path,
3289                                                         channel,
3290                                                         sizes_of_ht_retes_2t);
3291                _rtl8821ae_phy_set_txpower_level_by_path(hw, vht_rates_2t, path,
3292                                                         channel,
3293                                                         sizes_of_vht_retes);
3294        }
3295
3296        _rtl8821ae_phy_txpower_training_by_path(hw, rtlphy->current_chan_bw,
3297                                                channel, path);
3298}
3299
3300/*just in case, write txpower in DW, to reduce time*/
3301void rtl8821ae_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
3302{
3303        struct rtl_priv *rtlpriv = rtl_priv(hw);
3304        struct rtl_phy *rtlphy = &rtlpriv->phy;
3305        u8 path = 0;
3306
3307        for (path = RF90_PATH_A; path < rtlphy->num_total_rfpath; ++path)
3308                rtl8821ae_phy_set_txpower_level_by_path(hw, channel, path);
3309}
3310
3311static long _rtl8821ae_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
3312                                            enum wireless_mode wirelessmode,
3313                                            u8 txpwridx)
3314{
3315        long offset;
3316        long pwrout_dbm;
3317
3318        switch (wirelessmode) {
3319        case WIRELESS_MODE_B:
3320                offset = -7;
3321                break;
3322        case WIRELESS_MODE_G:
3323        case WIRELESS_MODE_N_24G:
3324                offset = -8;
3325                break;
3326        default:
3327                offset = -8;
3328                break;
3329        }
3330        pwrout_dbm = txpwridx / 2 + offset;
3331        return pwrout_dbm;
3332}
3333
3334void rtl8821ae_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
3335{
3336        struct rtl_priv *rtlpriv = rtl_priv(hw);
3337        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3338        enum io_type iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
3339
3340        if (!is_hal_stop(rtlhal)) {
3341                switch (operation) {
3342                case SCAN_OPT_BACKUP_BAND0:
3343                        iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
3344                        rtlpriv->cfg->ops->set_hw_reg(hw,
3345                                                      HW_VAR_IO_CMD,
3346                                                      (u8 *)&iotype);
3347
3348                        break;
3349                case SCAN_OPT_BACKUP_BAND1:
3350                        iotype = IO_CMD_PAUSE_BAND1_DM_BY_SCAN;
3351                        rtlpriv->cfg->ops->set_hw_reg(hw,
3352                                                      HW_VAR_IO_CMD,
3353                                                      (u8 *)&iotype);
3354
3355                        break;
3356                case SCAN_OPT_RESTORE:
3357                        iotype = IO_CMD_RESUME_DM_BY_SCAN;
3358                        rtlpriv->cfg->ops->set_hw_reg(hw,
3359                                                      HW_VAR_IO_CMD,
3360                                                      (u8 *)&iotype);
3361                        break;
3362                default:
3363                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
3364                                 "Unknown Scan Backup operation.\n");
3365                        break;
3366                }
3367        }
3368}
3369
3370static void _rtl8821ae_phy_set_reg_bw(struct rtl_priv *rtlpriv, u8 bw)
3371{
3372        u16 reg_rf_mode_bw, tmp = 0;
3373
3374        reg_rf_mode_bw = rtl_read_word(rtlpriv, REG_TRXPTCL_CTL);
3375        switch (bw) {
3376        case HT_CHANNEL_WIDTH_20:
3377                rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, reg_rf_mode_bw & 0xFE7F);
3378                break;
3379        case HT_CHANNEL_WIDTH_20_40:
3380                tmp = reg_rf_mode_bw | BIT(7);
3381                rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, tmp & 0xFEFF);
3382                break;
3383        case HT_CHANNEL_WIDTH_80:
3384                tmp = reg_rf_mode_bw | BIT(8);
3385                rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, tmp & 0xFF7F);
3386                break;
3387        default:
3388                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, "unknown Bandwidth: 0x%x\n", bw);
3389                break;
3390        }
3391}
3392
3393static u8 _rtl8821ae_phy_get_secondary_chnl(struct rtl_priv *rtlpriv)
3394{
3395        struct rtl_phy *rtlphy = &rtlpriv->phy;
3396        struct rtl_mac *mac = rtl_mac(rtlpriv);
3397        u8 sc_set_40 = 0, sc_set_20 = 0;
3398
3399        if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80) {
3400                if (mac->cur_80_prime_sc == PRIME_CHNL_OFFSET_LOWER)
3401                        sc_set_40 = VHT_DATA_SC_40_LOWER_OF_80MHZ;
3402                else if (mac->cur_80_prime_sc == PRIME_CHNL_OFFSET_UPPER)
3403                        sc_set_40 = VHT_DATA_SC_40_UPPER_OF_80MHZ;
3404                else
3405                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
3406                                "SCMapping: Not Correct Primary40MHz Setting\n");
3407
3408                if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER) &&
3409                        (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER))
3410                        sc_set_20 = VHT_DATA_SC_20_LOWEST_OF_80MHZ;
3411                else if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER) &&
3412                        (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER))
3413                        sc_set_20 = VHT_DATA_SC_20_LOWER_OF_80MHZ;
3414                else if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER) &&
3415                        (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_UPPER))
3416                        sc_set_20 = VHT_DATA_SC_20_UPPER_OF_80MHZ;
3417                else if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER) &&
3418                        (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_UPPER))
3419                        sc_set_20 = VHT_DATA_SC_20_UPPERST_OF_80MHZ;
3420                else
3421                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
3422                                "SCMapping: Not Correct Primary40MHz Setting\n");
3423        } else if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
3424                if (mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER)
3425                        sc_set_20 = VHT_DATA_SC_20_UPPER_OF_80MHZ;
3426                else if (mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER)
3427                        sc_set_20 = VHT_DATA_SC_20_LOWER_OF_80MHZ;
3428                else
3429                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
3430                         "SCMapping: Not Correct Primary40MHz Setting\n");
3431        }
3432        return (sc_set_40 << 4) | sc_set_20;
3433}
3434
3435void rtl8821ae_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
3436{
3437        struct rtl_priv *rtlpriv = rtl_priv(hw);
3438        struct rtl_phy *rtlphy = &rtlpriv->phy;
3439        u8 sub_chnl = 0;
3440        u8 l1pk_val = 0;
3441
3442        RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
3443                 "Switch to %s bandwidth\n",
3444                  (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
3445                  "20MHz" :
3446                  (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40 ?
3447                  "40MHz" : "80MHz")));
3448
3449        _rtl8821ae_phy_set_reg_bw(rtlpriv, rtlphy->current_chan_bw);
3450        sub_chnl = _rtl8821ae_phy_get_secondary_chnl(rtlpriv);
3451        rtl_write_byte(rtlpriv, 0x0483, sub_chnl);
3452
3453        switch (rtlphy->current_chan_bw) {
3454        case HT_CHANNEL_WIDTH_20:
3455                rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300200);
3456                rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 0);
3457
3458                if (rtlphy->rf_type == RF_2T2R)
3459                        rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, 7);
3460                else
3461                        rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, 8);
3462                break;
3463        case HT_CHANNEL_WIDTH_20_40:
3464                rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300201);
3465                rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 0);
3466                rtl_set_bbreg(hw, RRFMOD, 0x3C, sub_chnl);
3467                rtl_set_bbreg(hw, RCCAONSEC, 0xf0000000, sub_chnl);
3468
3469                if (rtlphy->reg_837 & BIT(2))
3470                        l1pk_val = 6;
3471                else {
3472                        if (rtlphy->rf_type == RF_2T2R)
3473                                l1pk_val = 7;
3474                        else
3475                                l1pk_val = 8;
3476                }
3477                /* 0x848[25:22] = 0x6 */
3478                rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, l1pk_val);
3479
3480                if (sub_chnl == VHT_DATA_SC_20_UPPER_OF_80MHZ)
3481                        rtl_set_bbreg(hw, RCCK_SYSTEM, BCCK_SYSTEM, 1);
3482                else
3483                        rtl_set_bbreg(hw, RCCK_SYSTEM, BCCK_SYSTEM, 0);
3484                break;
3485
3486        case HT_CHANNEL_WIDTH_80:
3487                 /* 0x8ac[21,20,9:6,1,0]=8'b11100010 */
3488                rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300202);
3489                /* 0x8c4[30] = 1 */
3490                rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 1);
3491                rtl_set_bbreg(hw, RRFMOD, 0x3C, sub_chnl);
3492                rtl_set_bbreg(hw, RCCAONSEC, 0xf0000000, sub_chnl);
3493
3494                if (rtlphy->reg_837 & BIT(2))
3495                        l1pk_val = 5;
3496                else {
3497                        if (rtlphy->rf_type == RF_2T2R)
3498                                l1pk_val = 6;
3499                        else
3500                                l1pk_val = 7;
3501                }
3502                rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, l1pk_val);
3503
3504                break;
3505        default:
3506                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
3507                         "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
3508                break;
3509        }
3510
3511        rtl8812ae_fixspur(hw, rtlphy->current_chan_bw, rtlphy->current_channel);
3512
3513        rtl8821ae_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
3514        rtlphy->set_bwmode_inprogress = false;
3515
3516        RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, "\n");
3517}
3518
3519void rtl8821ae_phy_set_bw_mode(struct ieee80211_hw *hw,
3520                            enum nl80211_channel_type ch_type)
3521{
3522        struct rtl_priv *rtlpriv = rtl_priv(hw);
3523        struct rtl_phy *rtlphy = &rtlpriv->phy;
3524        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3525        u8 tmp_bw = rtlphy->current_chan_bw;
3526
3527        if (rtlphy->set_bwmode_inprogress)
3528                return;
3529        rtlphy->set_bwmode_inprogress = true;
3530        if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw)))
3531                rtl8821ae_phy_set_bw_mode_callback(hw);
3532        else {
3533                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
3534                         "FALSE driver sleep or unload\n");
3535                rtlphy->set_bwmode_inprogress = false;
3536                rtlphy->current_chan_bw = tmp_bw;
3537        }
3538}
3539
3540void rtl8821ae_phy_sw_chnl_callback(struct ieee80211_hw *hw)
3541{
3542        struct rtl_priv *rtlpriv = rtl_priv(hw);
3543        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3544        struct rtl_phy *rtlphy = &rtlpriv->phy;
3545        u8 channel = rtlphy->current_channel;
3546        u8 path;
3547        u32 data;
3548
3549        RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
3550                 "switch to channel%d\n", rtlphy->current_channel);
3551        if (is_hal_stop(rtlhal))
3552                return;
3553
3554        if (36 <= channel && channel <= 48)
3555                data = 0x494;
3556        else if (50 <= channel && channel <= 64)
3557                data = 0x453;
3558        else if (100 <= channel && channel <= 116)
3559                data = 0x452;
3560        else if (118 <= channel)
3561                data = 0x412;
3562        else
3563                data = 0x96a;
3564        rtl_set_bbreg(hw, RFC_AREA, 0x1ffe0000, data);
3565
3566        for (path = RF90_PATH_A; path < rtlphy->num_total_rfpath; path++) {
3567                if (36 <= channel && channel <= 64)
3568                        data = 0x101;
3569                else if (100 <= channel && channel <= 140)
3570                        data = 0x301;
3571                else if (140 < channel)
3572                        data = 0x501;
3573                else
3574                        data = 0x000;
3575                rtl8821ae_phy_set_rf_reg(hw, path, RF_CHNLBW,
3576                        BIT(18)|BIT(17)|BIT(16)|BIT(9)|BIT(8), data);
3577
3578                rtl8821ae_phy_set_rf_reg(hw, path, RF_CHNLBW,
3579                        BMASKBYTE0, channel);
3580
3581                if (channel > 14) {
3582                        if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
3583                                if (36 <= channel && channel <= 64)
3584                                        data = 0x114E9;
3585                                else if (100 <= channel && channel <= 140)
3586                                        data = 0x110E9;
3587                                else
3588                                        data = 0x110E9;
3589                                rtl8821ae_phy_set_rf_reg(hw, path, RF_APK,
3590                                        BRFREGOFFSETMASK, data);
3591                        }
3592                }
3593        }
3594        RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
3595}
3596
3597u8 rtl8821ae_phy_sw_chnl(struct ieee80211_hw *hw)
3598{
3599        struct rtl_priv *rtlpriv = rtl_priv(hw);
3600        struct rtl_phy *rtlphy = &rtlpriv->phy;
3601        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3602        u32 timeout = 1000, timecount = 0;
3603        u8 channel = rtlphy->current_channel;
3604
3605        if (rtlphy->sw_chnl_inprogress)
3606                return 0;
3607        if (rtlphy->set_bwmode_inprogress)
3608                return 0;
3609
3610        if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) {
3611                RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
3612                         "sw_chnl_inprogress false driver sleep or unload\n");
3613                return 0;
3614        }
3615        while (rtlphy->lck_inprogress && timecount < timeout) {
3616                mdelay(50);
3617                timecount += 50;
3618        }
3619
3620        if (rtlphy->current_channel > 14 && rtlhal->current_bandtype != BAND_ON_5G)
3621                rtl8821ae_phy_switch_wirelessband(hw, BAND_ON_5G);
3622        else if (rtlphy->current_channel <= 14 && rtlhal->current_bandtype != BAND_ON_2_4G)
3623                rtl8821ae_phy_switch_wirelessband(hw, BAND_ON_2_4G);
3624
3625        rtlphy->sw_chnl_inprogress = true;
3626        if (channel == 0)
3627                channel = 1;
3628
3629        RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
3630                 "switch to channel%d, band type is %d\n",
3631                 rtlphy->current_channel, rtlhal->current_bandtype);
3632
3633        rtl8821ae_phy_sw_chnl_callback(hw);
3634
3635        rtl8821ae_dm_clear_txpower_tracking_state(hw);
3636        rtl8821ae_phy_set_txpower_level(hw, rtlphy->current_channel);
3637
3638        RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
3639        rtlphy->sw_chnl_inprogress = false;
3640        return 1;
3641}
3642
3643u8 _rtl8812ae_get_right_chnl_place_for_iqk(u8 chnl)
3644{
3645        u8 channel_all[TARGET_CHNL_NUM_2G_5G_8812] = {
3646                1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
3647                14, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54,
3648                56, 58, 60, 62, 64, 100, 102, 104, 106, 108,
3649                110, 112, 114, 116, 118, 120, 122, 124, 126,
3650                128, 130, 132, 134, 136, 138, 140, 149, 151,
3651                153, 155, 157, 159, 161, 163, 165};
3652        u8 place = chnl;
3653
3654        if (chnl > 14) {
3655                for (place = 14; place < sizeof(channel_all); place++)
3656                        if (channel_all[place] == chnl)
3657                                return place-13;
3658        }
3659
3660        return 0;
3661}
3662
3663#define MACBB_REG_NUM 10
3664#define AFE_REG_NUM 14
3665#define RF_REG_NUM 3
3666
3667static void _rtl8821ae_iqk_backup_macbb(struct ieee80211_hw *hw,
3668                                        u32 *macbb_backup,
3669                                        u32 *backup_macbb_reg, u32 mac_bb_num)
3670{
3671        struct rtl_priv *rtlpriv = rtl_priv(hw);
3672        u32 i;
3673
3674        rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3675        /*save MACBB default value*/
3676        for (i = 0; i < mac_bb_num; i++)
3677                macbb_backup[i] = rtl_read_dword(rtlpriv, backup_macbb_reg[i]);
3678
3679        RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "BackupMacBB Success!!!!\n");
3680}
3681
3682static void _rtl8821ae_iqk_backup_afe(struct ieee80211_hw *hw, u32 *afe_backup,
3683                                      u32 *backup_afe_REG, u32 afe_num)
3684{
3685        struct rtl_priv *rtlpriv = rtl_priv(hw);
3686        u32 i;
3687
3688        rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3689        /*Save AFE Parameters */
3690        for (i = 0; i < afe_num; i++)
3691                afe_backup[i] = rtl_read_dword(rtlpriv, backup_afe_REG[i]);
3692        RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "BackupAFE Success!!!!\n");
3693}
3694
3695static void _rtl8821ae_iqk_backup_rf(struct ieee80211_hw *hw, u32 *rfa_backup,
3696                                     u32 *rfb_backup, u32 *backup_rf_reg,
3697                                     u32 rf_num)
3698{
3699        struct rtl_priv *rtlpriv = rtl_priv(hw);
3700        u32 i;
3701
3702        rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3703        /*Save RF Parameters*/
3704        for (i = 0; i < rf_num; i++) {
3705                rfa_backup[i] = rtl_get_rfreg(hw, RF90_PATH_A, backup_rf_reg[i],
3706                                              BMASKDWORD);
3707                rfb_backup[i] = rtl_get_rfreg(hw, RF90_PATH_B, backup_rf_reg[i],
3708                                              BMASKDWORD);
3709        }
3710        RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "BackupRF Success!!!!\n");
3711}
3712
3713static void _rtl8821ae_iqk_configure_mac(
3714                struct ieee80211_hw *hw
3715                )
3716{
3717        struct rtl_priv *rtlpriv = rtl_priv(hw);
3718        /* ========MAC register setting========*/
3719        rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3720        rtl_write_byte(rtlpriv, 0x522, 0x3f);
3721        rtl_set_bbreg(hw, 0x550, BIT(11) | BIT(3), 0x0);
3722        rtl_write_byte(rtlpriv, 0x808, 0x00);           /*RX ante off*/
3723        rtl_set_bbreg(hw, 0x838, 0xf, 0xc);             /*CCA off*/
3724}
3725
3726static void _rtl8821ae_iqk_tx_fill_iqc(struct ieee80211_hw *hw,
3727                                       enum radio_path path, u32 tx_x, u32 tx_y)
3728{
3729        struct rtl_priv *rtlpriv = rtl_priv(hw);
3730        switch (path) {
3731        case RF90_PATH_A:
3732                /* [31] = 1 --> Page C1 */
3733                rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1);
3734                rtl_write_dword(rtlpriv, 0xc90, 0x00000080);
3735                rtl_write_dword(rtlpriv, 0xcc4, 0x20040000);
3736                rtl_write_dword(rtlpriv, 0xcc8, 0x20000000);
3737                rtl_set_bbreg(hw, 0xccc, 0x000007ff, tx_y);
3738                rtl_set_bbreg(hw, 0xcd4, 0x000007ff, tx_x);
3739                RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3740                         "TX_X = %x;;TX_Y = %x =====> fill to IQC\n",
3741                         tx_x, tx_y);
3742                RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3743                         "0xcd4 = %x;;0xccc = %x ====>fill to IQC\n",
3744                         rtl_get_bbreg(hw, 0xcd4, 0x000007ff),
3745                         rtl_get_bbreg(hw, 0xccc, 0x000007ff));
3746                break;
3747        default:
3748                break;
3749        }
3750}
3751
3752static void _rtl8821ae_iqk_rx_fill_iqc(struct ieee80211_hw *hw,
3753                                       enum radio_path path, u32 rx_x, u32 rx_y)
3754{
3755        struct rtl_priv *rtlpriv = rtl_priv(hw);
3756        switch (path) {
3757        case RF90_PATH_A:
3758                rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
3759                rtl_set_bbreg(hw, 0xc10, 0x000003ff, rx_x>>1);
3760                rtl_set_bbreg(hw, 0xc10, 0x03ff0000, rx_y>>1);
3761                RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3762                         "rx_x = %x;;rx_y = %x ====>fill to IQC\n",
3763                         rx_x>>1, rx_y>>1);
3764                RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3765                         "0xc10 = %x ====>fill to IQC\n",
3766                         rtl_read_dword(rtlpriv, 0xc10));
3767                break;
3768        default:
3769                break;
3770        }
3771}
3772
3773#define cal_num 10
3774
3775static void _rtl8821ae_iqk_tx(struct ieee80211_hw *hw, enum radio_path path)
3776{
3777        struct rtl_priv *rtlpriv = rtl_priv(hw);
3778        struct rtl_phy *rtlphy = &rtlpriv->phy;
3779        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
3780
3781        u32     tx_fail, rx_fail, delay_count, iqk_ready, cal_retry, cal = 0, temp_reg65;
3782        int     tx_x = 0, tx_y = 0, rx_x = 0, rx_y = 0, tx_average = 0, rx_average = 0;
3783        int     tx_x0[cal_num], tx_y0[cal_num], tx_x0_rxk[cal_num],
3784                tx_y0_rxk[cal_num], rx_x0[cal_num], rx_y0[cal_num];
3785        bool    tx0iqkok = false, rx0iqkok = false;
3786        bool    vdf_enable = false;
3787        int     i, k, vdf_y[3], vdf_x[3], tx_dt[3], rx_dt[3],
3788                ii, dx = 0, dy = 0, tx_finish = 0, rx_finish = 0;
3789
3790        RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3791                        "BandWidth = %d.\n",
3792                         rtlphy->current_chan_bw);
3793        if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80)
3794                vdf_enable = true;
3795
3796        while (cal < cal_num) {
3797                switch (path) {
3798                case RF90_PATH_A:
3799                        temp_reg65 = rtl_get_rfreg(hw, path, 0x65, 0xffffffff);
3800                        /* Path-A LOK */
3801                        rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/
3802                        /*========Path-A AFE all on========*/
3803                        /*Port 0 DAC/ADC on*/
3804                        rtl_write_dword(rtlpriv, 0xc60, 0x77777777);
3805                        rtl_write_dword(rtlpriv, 0xc64, 0x77777777);
3806                        rtl_write_dword(rtlpriv, 0xc68, 0x19791979);
3807                        rtl_write_dword(rtlpriv, 0xc6c, 0x19791979);
3808                        rtl_write_dword(rtlpriv, 0xc70, 0x19791979);
3809                        rtl_write_dword(rtlpriv, 0xc74, 0x19791979);
3810                        rtl_write_dword(rtlpriv, 0xc78, 0x19791979);
3811                        rtl_write_dword(rtlpriv, 0xc7c, 0x19791979);
3812                        rtl_write_dword(rtlpriv, 0xc80, 0x19791979);
3813                        rtl_write_dword(rtlpriv, 0xc84, 0x19791979);
3814
3815                        rtl_set_bbreg(hw, 0xc00, 0xf, 0x4); /*hardware 3-wire off*/
3816
3817                        /* LOK Setting */
3818                        /* ====== LOK ====== */
3819                        /*DAC/ADC sampling rate (160 MHz)*/
3820                        rtl_set_bbreg(hw, 0xc5c, BIT(26) | BIT(25) | BIT(24), 0x7);
3821
3822                        /* 2. LoK RF Setting (at BW = 20M) */
3823                        rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80002);
3824                        rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x3);     /* BW 20M */
3825                        rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x20000);
3826                        rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0003f);
3827                        rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xf3fc3);
3828                        rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d5);
3829                        rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
3830                        rtl_set_bbreg(hw, 0xcb8, 0xf, 0xd);
3831                        rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
3832                        rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
3833                        rtl_set_bbreg(hw, 0xc94, BIT(0), 0x1);
3834                        rtl_write_dword(rtlpriv, 0x978, 0x29002000);/* TX (X,Y) */
3835                        rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);/* RX (X,Y) */
3836                        rtl_write_dword(rtlpriv, 0x984, 0x00462910);/* [0]:AGC_en, [15]:idac_K_Mask */
3837
3838                        rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
3839                        rtl_write_dword(rtlpriv, 0xc88, 0x821403f4);
3840
3841                        if (rtlhal->current_bandtype)
3842                                rtl_write_dword(rtlpriv, 0xc8c, 0x68163e96);
3843                        else
3844                                rtl_write_dword(rtlpriv, 0xc8c, 0x28163e96);
3845
3846                        rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3847                        rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3848                        rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8ϥ\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
3849                        rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
3850                        rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
3851
3852                        mdelay(10); /* Delay 10ms */
3853                        rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
3854
3855                        rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
3856                        rtl_set_rfreg(hw, path, 0x58, 0x7fe00, rtl_get_rfreg(hw, path, 0x8, 0xffc00)); /* Load LOK */
3857
3858                        switch (rtlphy->current_chan_bw) {
3859                        case 1:
3860                                rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x1);
3861                                break;
3862                        case 2:
3863                                rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x0);
3864                                break;
3865                        default:
3866                                break;
3867                        }
3868
3869                        rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
3870
3871                        /* 3. TX RF Setting */
3872                        rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
3873                        rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
3874                        rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x20000);
3875                        rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0003f);
3876                        rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xf3fc3);
3877                        rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d5);
3878                        rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
3879                        rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
3880                        /* ODM_SetBBReg(pDM_Odm, 0xcb8, 0xf, 0xd); */
3881                        rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
3882                        rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
3883                        rtl_set_bbreg(hw, 0xc94, BIT(0), 0x1);
3884                        rtl_write_dword(rtlpriv, 0x978, 0x29002000);/* TX (X,Y) */
3885                        rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);/* RX (X,Y) */
3886                        rtl_write_dword(rtlpriv, 0x984, 0x0046a910);/* [0]:AGC_en, [15]:idac_K_Mask */
3887
3888                        rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
3889                        rtl_write_dword(rtlpriv, 0xc88, 0x821403f1);
3890                        if (rtlhal->current_bandtype)
3891                                rtl_write_dword(rtlpriv, 0xc8c, 0x40163e96);
3892                        else
3893                                rtl_write_dword(rtlpriv, 0xc8c, 0x00163e96);
3894
3895                        if (vdf_enable == 1) {
3896                                RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "VDF_enable\n");
3897                                for (k = 0; k <= 2; k++) {
3898                                        switch (k) {
3899                                        case 0:
3900                                                rtl_write_dword(rtlpriv, 0xc80, 0x18008c38);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3901                                                rtl_write_dword(rtlpriv, 0xc84, 0x38008c38);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3902                                                rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0);
3903                                                break;
3904                                        case 1:
3905                                                rtl_set_bbreg(hw, 0xc80, BIT(28), 0x0);
3906                                                rtl_set_bbreg(hw, 0xc84, BIT(28), 0x0);
3907                                                rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0);
3908                                                break;
3909                                        case 2:
3910                                                RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3911                                                        "vdf_y[1] = %x;;;vdf_y[0] = %x\n", vdf_y[1]>>21 & 0x00007ff, vdf_y[0]>>21 & 0x00007ff);
3912                                                RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
3913                                                        "vdf_x[1] = %x;;;vdf_x[0] = %x\n", vdf_x[1]>>21 & 0x00007ff, vdf_x[0]>>21 & 0x00007ff);
3914                                                tx_dt[cal] = (vdf_y[1]>>20)-(vdf_y[0]>>20);
3915                                                tx_dt[cal] = ((16*tx_dt[cal])*10000/15708);
3916                                                tx_dt[cal] = (tx_dt[cal] >> 1)+(tx_dt[cal] & BIT(0));
3917                                                rtl_write_dword(rtlpriv, 0xc80, 0x18008c20);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3918                                                rtl_write_dword(rtlpriv, 0xc84, 0x38008c20);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3919                                                rtl_set_bbreg(hw, 0xce8, BIT(31), 0x1);
3920                                                rtl_set_bbreg(hw, 0xce8, 0x3fff0000, tx_dt[cal] & 0x00003fff);
3921                                                break;
3922                                        default:
3923                                                break;
3924                                        }
3925                                        rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8ϥ\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
3926                                        cal_retry = 0;
3927                                        while (1) {
3928                                                /* one shot */
3929                                                rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
3930                                                rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
3931
3932                                                mdelay(10); /* Delay 10ms */
3933                                                rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
3934                                                delay_count = 0;
3935                                                while (1) {
3936                                                        iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
3937                                                        if ((~iqk_ready) || (delay_count > 20))
3938                                                                break;
3939                                                        else{
3940                                                                mdelay(1);
3941                                                                delay_count++;
3942                                                        }
3943                                                }
3944
3945                                                if (delay_count < 20) {                                                 /* If 20ms No Result, then cal_retry++ */
3946                                                        /* ============TXIQK Check============== */
3947                                                        tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
3948
3949                                                        if (~tx_fail) {
3950                                                                rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
3951                                                                vdf_x[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
3952                                                                rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
3953                                                                vdf_y[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
3954                                                                tx0iqkok = true;
3955                                                                break;
3956                                                        } else {
3957                                                                rtl_set_bbreg(hw, 0xccc, 0x000007ff, 0x0);
3958                                                                rtl_set_bbreg(hw, 0xcd4, 0x000007ff, 0x200);
3959                                                                tx0iqkok = false;
3960                                                                cal_retry++;
3961                                                                if (cal_retry == 10)
3962                                                                        break;
3963                                                        }
3964                                                } else {
3965                                                        tx0iqkok = false;
3966                                                        cal_retry++;
3967                                                        if (cal_retry == 10)
3968                                                                break;
3969                                                }
3970                                        }
3971                                }
3972                                if (k == 3) {
3973                                        tx_x0[cal] = vdf_x[k-1];
3974                                        tx_y0[cal] = vdf_y[k-1];
3975                                }
3976                        } else {
3977                                rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
3978                                rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
3979                                rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8ϥ\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
3980                                cal_retry = 0;
3981                                while (1) {
3982                                        /* one shot */
3983                                        rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
3984                                        rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
3985
3986                                        mdelay(10); /* Delay 10ms */
3987                                        rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
3988                                        delay_count = 0;
3989                                        while (1) {
3990                                                iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
3991                                                if ((~iqk_ready) || (delay_count > 20))
3992                                                        break;
3993                                                else{
3994                                                        mdelay(1);
3995                                                        delay_count++;
3996                                                }
3997                                        }
3998
3999                                        if (delay_count < 20) {                                                 /* If 20ms No Result, then cal_retry++ */
4000                                                /* ============TXIQK Check============== */
4001                                                tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
4002
4003                                                if (~tx_fail) {
4004                                                        rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
4005                                                        tx_x0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4006                                                        rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
4007                                                        tx_y0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4008                                                        tx0iqkok = true;
4009                                                        break;
4010                                                } else {
4011                                                        rtl_set_bbreg(hw, 0xccc, 0x000007ff, 0x0);
4012                                                        rtl_set_bbreg(hw, 0xcd4, 0x000007ff, 0x200);
4013                                                        tx0iqkok = false;
4014                                                        cal_retry++;
4015                                                        if (cal_retry == 10)
4016                                                                break;
4017                                                }
4018                                        } else {
4019                                                tx0iqkok = false;
4020                                                cal_retry++;
4021                                                if (cal_retry == 10)
4022                                                        break;
4023                                        }
4024                                }
4025                        }
4026
4027                        if (tx0iqkok == false)
4028                                break;                          /* TXK fail, Don't do RXK */
4029
4030                        if (vdf_enable == 1) {
4031                                rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0);    /* TX VDF Disable */
4032                                RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "RXVDF Start\n");
4033                                for (k = 0; k <= 2; k++) {
4034                                        /* ====== RX mode TXK (RXK Step 1) ====== */
4035                                        rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4036                                        /* 1. TX RF Setting */
4037                                        rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4038                                        rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4039                                        rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x00029);
4040                                        rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xd7ffb);
4041                                        rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65);
4042                                        rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
4043                                        rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4044
4045                                        rtl_set_bbreg(hw, 0xcb8, 0xf, 0xd);
4046                                        rtl_write_dword(rtlpriv, 0x978, 0x29002000);/* TX (X,Y) */
4047                                        rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);/* RX (X,Y) */
4048                                        rtl_write_dword(rtlpriv, 0x984, 0x0046a910);/* [0]:AGC_en, [15]:idac_K_Mask */
4049                                        rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4050                                        rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
4051                                        rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4052                                        switch (k) {
4053                                        case 0:
4054                                                {
4055                                                        rtl_write_dword(rtlpriv, 0xc80, 0x18008c38);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4056                                                        rtl_write_dword(rtlpriv, 0xc84, 0x38008c38);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4057                                                        rtl_set_bbreg(hw, 0xce8, BIT(30), 0x0);
4058                                                }
4059                                                break;
4060                                        case 1:
4061                                                {
4062                                                        rtl_write_dword(rtlpriv, 0xc80, 0x08008c38);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4063                                                        rtl_write_dword(rtlpriv, 0xc84, 0x28008c38);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4064                                                        rtl_set_bbreg(hw, 0xce8, BIT(30), 0x0);
4065                                                }
4066                                                break;
4067                                        case 2:
4068                                                {
4069                                                        RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4070                                                        "VDF_Y[1] = %x;;;VDF_Y[0] = %x\n",
4071                                                        vdf_y[1]>>21 & 0x00007ff, vdf_y[0]>>21 & 0x00007ff);
4072                                                        RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4073                                                        "VDF_X[1] = %x;;;VDF_X[0] = %x\n",
4074                                                        vdf_x[1]>>21 & 0x00007ff, vdf_x[0]>>21 & 0x00007ff);
4075                                                        rx_dt[cal] = (vdf_y[1]>>20)-(vdf_y[0]>>20);
4076                                                        RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "Rx_dt = %d\n", rx_dt[cal]);
4077                                                        rx_dt[cal] = ((16*rx_dt[cal])*10000/13823);
4078                                                        rx_dt[cal] = (rx_dt[cal] >> 1)+(rx_dt[cal] & BIT(0));
4079                                                        rtl_write_dword(rtlpriv, 0xc80, 0x18008c20);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4080                                                        rtl_write_dword(rtlpriv, 0xc84, 0x38008c20);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4081                                                        rtl_set_bbreg(hw, 0xce8, 0x00003fff, rx_dt[cal] & 0x00003fff);
4082                                                }
4083                                                break;
4084                                        default:
4085                                                break;
4086                                        }
4087                                        rtl_write_dword(rtlpriv, 0xc88, 0x821603e0);
4088                                        rtl_write_dword(rtlpriv, 0xc8c, 0x68163e96);
4089                                        rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8ϥ\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4090                                        cal_retry = 0;
4091                                        while (1) {
4092                                                /* one shot */
4093                                                rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4094                                                rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4095
4096                                                mdelay(10); /* Delay 10ms */
4097                                                rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4098                                                delay_count = 0;
4099                                                while (1) {
4100                                                        iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4101                                                        if ((~iqk_ready) || (delay_count > 20))
4102                                                                break;
4103                                                        else{
4104                                                                mdelay(1);
4105                                                                delay_count++;
4106                                                        }
4107                                                }
4108
4109                                                if (delay_count < 20) {                                                 /* If 20ms No Result, then cal_retry++ */
4110                                                        /* ============TXIQK Check============== */
4111                                                        tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
4112
4113                                                        if (~tx_fail) {
4114                                                                rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
4115                                                                tx_x0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4116                                                                rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
4117                                                                tx_y0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4118                                                                tx0iqkok = true;
4119                                                                break;
4120                                                        } else{
4121                                                                tx0iqkok = false;
4122                                                                cal_retry++;
4123                                                                if (cal_retry == 10)
4124                                                                        break;
4125                                                        }
4126                                                } else {
4127                                                        tx0iqkok = false;
4128                                                        cal_retry++;
4129                                                        if (cal_retry == 10)
4130                                                                break;
4131                                                }
4132                                        }
4133
4134                                        if (tx0iqkok == false) {   /* If RX mode TXK fail, then take TXK Result */
4135                                                tx_x0_rxk[cal] = tx_x0[cal];
4136                                                tx_y0_rxk[cal] = tx_y0[cal];
4137                                                tx0iqkok = true;
4138                                                RT_TRACE(rtlpriv,
4139                                                         COMP_IQK,
4140                                                         DBG_LOUD,
4141                                                         "RXK Step 1 fail\n");
4142                                        }
4143
4144                                        /* ====== RX IQK ====== */
4145                                        rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4146                                        /* 1. RX RF Setting */
4147                                        rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4148                                        rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4149                                        rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0002f);
4150                                        rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xfffbb);
4151                                        rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x88001);
4152                                        rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d8);
4153                                        rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4154
4155                                        rtl_set_bbreg(hw, 0x978, 0x03FF8000, (tx_x0_rxk[cal])>>21&0x000007ff);
4156                                        rtl_set_bbreg(hw, 0x978, 0x000007FF, (tx_y0_rxk[cal])>>21&0x000007ff);
4157                                        rtl_set_bbreg(hw, 0x978, BIT(31), 0x1);
4158                                        rtl_set_bbreg(hw, 0x97c, BIT(31), 0x0);
4159                                        rtl_set_bbreg(hw, 0xcb8, 0xF, 0xe);
4160                                        rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4161                                        rtl_write_dword(rtlpriv, 0x984, 0x0046a911);
4162
4163                                        rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4164                                        rtl_set_bbreg(hw, 0xc80, BIT(29), 0x1);
4165                                        rtl_set_bbreg(hw, 0xc84, BIT(29), 0x0);
4166                                        rtl_write_dword(rtlpriv, 0xc88, 0x02140119);
4167
4168                                        rtl_write_dword(rtlpriv, 0xc8c, 0x28160d00); /* pDM_Odm->SupportInterface == 1 */
4169
4170                                        if (k == 2)
4171                                                rtl_set_bbreg(hw, 0xce8, BIT(30), 0x1);  /* RX VDF Enable */
4172                                        rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8ϥ\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4173
4174                                        cal_retry = 0;
4175                                        while (1) {
4176                                                /* one shot */
4177                                                rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4178                                                rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4179
4180                                                mdelay(10); /* Delay 10ms */
4181                                                rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4182                                                delay_count = 0;
4183                                                while (1) {
4184                                                        iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4185                                                        if ((~iqk_ready) || (delay_count > 20))
4186                                                                break;
4187                                                        else{
4188                                                                mdelay(1);
4189                                                                delay_count++;
4190                                                        }
4191                                                }
4192
4193                                                if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
4194                                                        /* ============RXIQK Check============== */
4195                                                        rx_fail = rtl_get_bbreg(hw, 0xd00, BIT(11));
4196                                                        if (rx_fail == 0) {
4197                                                                rtl_write_dword(rtlpriv, 0xcb8, 0x06000000);
4198                                                                vdf_x[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4199                                                                rtl_write_dword(rtlpriv, 0xcb8, 0x08000000);
4200                                                                vdf_y[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4201                                                                rx0iqkok = true;
4202                                                                break;
4203                                                        } else {
4204                                                                rtl_set_bbreg(hw, 0xc10, 0x000003ff, 0x200>>1);
4205                                                                rtl_set_bbreg(hw, 0xc10, 0x03ff0000, 0x0>>1);
4206                                                                rx0iqkok = false;
4207                                                                cal_retry++;
4208                                                                if (cal_retry == 10)
4209                                                                        break;
4210
4211                                                        }
4212                                                } else{
4213                                                        rx0iqkok = false;
4214                                                        cal_retry++;
4215                                                        if (cal_retry == 10)
4216                                                                break;
4217                                                }
4218                                        }
4219
4220                                }
4221                                if (k == 3) {
4222                                        rx_x0[cal] = vdf_x[k-1];
4223                                        rx_y0[cal] = vdf_y[k-1];
4224                                }
4225                                rtl_set_bbreg(hw, 0xce8, BIT(31), 0x1);    /* TX VDF Enable */
4226                        }
4227
4228                        else{
4229                                /* ====== RX mode TXK (RXK Step 1) ====== */
4230                                rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4231                                /* 1. TX RF Setting */
4232                                rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4233                                rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4234                                rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x00029);
4235                                rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xd7ffb);
4236                                rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65);
4237                                rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001);
4238                                rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4239                                rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4240                                rtl_write_dword(rtlpriv, 0xb00, 0x03000100);
4241                                rtl_write_dword(rtlpriv, 0x984, 0x0046a910);/* [0]:AGC_en, [15]:idac_K_Mask */
4242
4243                                rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4244                                rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4245                                rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4246                                rtl_write_dword(rtlpriv, 0xc88, 0x821603e0);
4247                                /* ODM_Write4Byte(pDM_Odm, 0xc8c, 0x68163e96); */
4248                                rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8ϥ\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4249                                cal_retry = 0;
4250                                while (1) {
4251                                        /* one shot */
4252                                        rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4253                                        rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4254
4255                                        mdelay(10); /* Delay 10ms */
4256                                        rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4257                                        delay_count = 0;
4258                                        while (1) {
4259                                                iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4260                                                if ((~iqk_ready) || (delay_count > 20))
4261                                                        break;
4262                                                else{
4263                                                        mdelay(1);
4264                                                        delay_count++;
4265                                                }
4266                                        }
4267
4268                                        if (delay_count < 20) {                                                 /* If 20ms No Result, then cal_retry++ */
4269                                                /* ============TXIQK Check============== */
4270                                                tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12));
4271
4272                                                if (~tx_fail) {
4273                                                        rtl_write_dword(rtlpriv, 0xcb8, 0x02000000);
4274                                                        tx_x0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4275                                                        rtl_write_dword(rtlpriv, 0xcb8, 0x04000000);
4276                                                        tx_y0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4277                                                        tx0iqkok = true;
4278                                                        break;
4279                                                } else {
4280                                                        tx0iqkok = false;
4281                                                        cal_retry++;
4282                                                        if (cal_retry == 10)
4283                                                                break;
4284                                                }
4285                                        } else{
4286                                                tx0iqkok = false;
4287                                                cal_retry++;
4288                                                if (cal_retry == 10)
4289                                                        break;
4290                                        }
4291                                }
4292
4293                                if (tx0iqkok == false) {   /* If RX mode TXK fail, then take TXK Result */
4294                                        tx_x0_rxk[cal] = tx_x0[cal];
4295                                        tx_y0_rxk[cal] = tx_y0[cal];
4296                                        tx0iqkok = true;
4297                                        RT_TRACE(rtlpriv, COMP_IQK,
4298                                                 DBG_LOUD, "1");
4299                                }
4300
4301                                /* ====== RX IQK ====== */
4302                                rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4303                                /* 1. RX RF Setting */
4304                                rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000);
4305                                rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000);
4306                                rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0002f);
4307                                rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xfffbb);
4308                                rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x88001);
4309                                rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d8);
4310                                rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000);
4311
4312                                rtl_set_bbreg(hw, 0x978, 0x03FF8000, (tx_x0_rxk[cal])>>21&0x000007ff);
4313                                rtl_set_bbreg(hw, 0x978, 0x000007FF, (tx_y0_rxk[cal])>>21&0x000007ff);
4314                                rtl_set_bbreg(hw, 0x978, BIT(31), 0x1);
4315                                rtl_set_bbreg(hw, 0x97c, BIT(31), 0x0);
4316                                /* ODM_SetBBReg(pDM_Odm, 0xcb8, 0xF, 0xe); */
4317                                rtl_write_dword(rtlpriv, 0x90c, 0x00008000);
4318                                rtl_write_dword(rtlpriv, 0x984, 0x0046a911);
4319
4320                                rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4321                                rtl_write_dword(rtlpriv, 0xc80, 0x38008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */
4322                                rtl_write_dword(rtlpriv, 0xc84, 0x18008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */
4323                                rtl_write_dword(rtlpriv, 0xc88, 0x02140119);
4324
4325                                rtl_write_dword(rtlpriv, 0xc8c, 0x28160d00); /*pDM_Odm->SupportInterface == 1*/
4326
4327                                rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8ϥ\CE\C5v\A4\C1\B5\B9 iqk_dpk module */
4328
4329                                cal_retry = 0;
4330                                while (1) {
4331                                        /* one shot */
4332                                        rtl_write_dword(rtlpriv, 0x980, 0xfa000000);
4333                                        rtl_write_dword(rtlpriv, 0x980, 0xf8000000);
4334
4335                                        mdelay(10); /* Delay 10ms */
4336                                        rtl_write_dword(rtlpriv, 0xcb8, 0x00000000);
4337                                        delay_count = 0;
4338                                        while (1) {
4339                                                iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10));
4340                                                if ((~iqk_ready) || (delay_count > 20))
4341                                                        break;
4342                                                else{
4343                                                        mdelay(1);
4344                                                        delay_count++;
4345                                                }
4346                                        }
4347
4348                                        if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */
4349                                                /* ============RXIQK Check============== */
4350                                                rx_fail = rtl_get_bbreg(hw, 0xd00, BIT(11));
4351                                                if (rx_fail == 0) {
4352                                                        rtl_write_dword(rtlpriv, 0xcb8, 0x06000000);
4353                                                        rx_x0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4354                                                        rtl_write_dword(rtlpriv, 0xcb8, 0x08000000);
4355                                                        rx_y0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21;
4356                                                        rx0iqkok = true;
4357                                                        break;
4358                                                } else{
4359                                                        rtl_set_bbreg(hw, 0xc10, 0x000003ff, 0x200>>1);
4360                                                        rtl_set_bbreg(hw, 0xc10, 0x03ff0000, 0x0>>1);
4361                                                        rx0iqkok = false;
4362                                                        cal_retry++;
4363                                                        if (cal_retry == 10)
4364                                                                break;
4365
4366                                                }
4367                                        } else{
4368                                                rx0iqkok = false;
4369                                                cal_retry++;
4370                                                if (cal_retry == 10)
4371                                                        break;
4372                                        }
4373                                }
4374                        }
4375
4376                        if (tx0iqkok)
4377                                tx_average++;
4378                        if (rx0iqkok)
4379                                rx_average++;
4380                        rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4381                        rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65);
4382                        break;
4383                default:
4384                        break;
4385                }
4386                cal++;
4387        }
4388
4389        /* FillIQK Result */
4390        switch (path) {
4391        case RF90_PATH_A:
4392                RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4393                         "========Path_A =======\n");
4394                if (tx_average == 0)
4395                        break;
4396
4397                for (i = 0; i < tx_average; i++) {
4398                        RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4399                                 "TX_X0_RXK[%d] = %x ;; TX_Y0_RXK[%d] = %x\n", i,
4400                                 (tx_x0_rxk[i])>>21&0x000007ff, i,
4401                                 (tx_y0_rxk[i])>>21&0x000007ff);
4402                        RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4403                                 "TX_X0[%d] = %x ;; TX_Y0[%d] = %x\n", i,
4404                                 (tx_x0[i])>>21&0x000007ff, i,
4405                                 (tx_y0[i])>>21&0x000007ff);
4406                }
4407                for (i = 0; i < tx_average; i++) {
4408                        for (ii = i+1; ii < tx_average; ii++) {
4409                                dx = (tx_x0[i]>>21) - (tx_x0[ii]>>21);
4410                                if (dx < 3 && dx > -3) {
4411                                        dy = (tx_y0[i]>>21) - (tx_y0[ii]>>21);
4412                                        if (dy < 3 && dy > -3) {
4413                                                tx_x = ((tx_x0[i]>>21) + (tx_x0[ii]>>21))/2;
4414                                                tx_y = ((tx_y0[i]>>21) + (tx_y0[ii]>>21))/2;
4415                                                tx_finish = 1;
4416                                                break;
4417                                        }
4418                                }
4419                        }
4420                        if (tx_finish == 1)
4421                                break;
4422                }
4423
4424                if (tx_finish == 1)
4425                        _rtl8821ae_iqk_tx_fill_iqc(hw, path, tx_x, tx_y); /* ? */
4426                else
4427                        _rtl8821ae_iqk_tx_fill_iqc(hw, path, 0x200, 0x0);
4428
4429                if (rx_average == 0)
4430                        break;
4431
4432                for (i = 0; i < rx_average; i++)
4433                        RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4434                                "RX_X0[%d] = %x ;; RX_Y0[%d] = %x\n", i,
4435                                (rx_x0[i])>>21&0x000007ff, i,
4436                                (rx_y0[i])>>21&0x000007ff);
4437                for (i = 0; i < rx_average; i++) {
4438                        for (ii = i+1; ii < rx_average; ii++) {
4439                                dx = (rx_x0[i]>>21) - (rx_x0[ii]>>21);
4440                                if (dx < 4 && dx > -4) {
4441                                        dy = (rx_y0[i]>>21) - (rx_y0[ii]>>21);
4442                                        if (dy < 4 && dy > -4) {
4443                                                rx_x = ((rx_x0[i]>>21) + (rx_x0[ii]>>21))/2;
4444                                                rx_y = ((rx_y0[i]>>21) + (rx_y0[ii]>>21))/2;
4445                                                rx_finish = 1;
4446                                                break;
4447                                        }
4448                                }
4449                        }
4450                        if (rx_finish == 1)
4451                                break;
4452                }
4453
4454                if (rx_finish == 1)
4455                        _rtl8821ae_iqk_rx_fill_iqc(hw, path, rx_x, rx_y);
4456                else
4457                        _rtl8821ae_iqk_rx_fill_iqc(hw, path, 0x200, 0x0);
4458                break;
4459        default:
4460                break;
4461        }
4462}
4463
4464static void _rtl8821ae_iqk_restore_rf(struct ieee80211_hw *hw,
4465                                      enum radio_path path,
4466                                      u32 *backup_rf_reg,
4467                                      u32 *rf_backup, u32 rf_reg_num)
4468{
4469        struct rtl_priv *rtlpriv = rtl_priv(hw);
4470        u32 i;
4471
4472        rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4473        for (i = 0; i < RF_REG_NUM; i++)
4474                rtl_set_rfreg(hw, path, backup_rf_reg[i], RFREG_OFFSET_MASK,
4475                              rf_backup[i]);
4476
4477        switch (path) {
4478        case RF90_PATH_A:
4479                RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4480                         "RestoreRF Path A Success!!!!\n");
4481                break;
4482        default:
4483                        break;
4484        }
4485}
4486
4487static void _rtl8821ae_iqk_restore_afe(struct ieee80211_hw *hw,
4488                                       u32 *afe_backup, u32 *backup_afe_reg,
4489                                       u32 afe_num)
4490{
4491        u32 i;
4492        struct rtl_priv *rtlpriv = rtl_priv(hw);
4493
4494        rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4495        /* Reload AFE Parameters */
4496        for (i = 0; i < afe_num; i++)
4497                rtl_write_dword(rtlpriv, backup_afe_reg[i], afe_backup[i]);
4498        rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */
4499        rtl_write_dword(rtlpriv, 0xc80, 0x0);
4500        rtl_write_dword(rtlpriv, 0xc84, 0x0);
4501        rtl_write_dword(rtlpriv, 0xc88, 0x0);
4502        rtl_write_dword(rtlpriv, 0xc8c, 0x3c000000);
4503        rtl_write_dword(rtlpriv, 0xc90, 0x00000080);
4504        rtl_write_dword(rtlpriv, 0xc94, 0x00000000);
4505        rtl_write_dword(rtlpriv, 0xcc4, 0x20040000);
4506        rtl_write_dword(rtlpriv, 0xcc8, 0x20000000);
4507        rtl_write_dword(rtlpriv, 0xcb8, 0x0);
4508        RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "RestoreAFE Success!!!!\n");
4509}
4510
4511static void _rtl8821ae_iqk_restore_macbb(struct ieee80211_hw *hw,
4512                                         u32 *macbb_backup,
4513                                         u32 *backup_macbb_reg,
4514                                         u32 macbb_num)
4515{
4516        u32 i;
4517        struct rtl_priv *rtlpriv = rtl_priv(hw);
4518
4519        rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */
4520        /* Reload MacBB Parameters */
4521        for (i = 0; i < macbb_num; i++)
4522                rtl_write_dword(rtlpriv, backup_macbb_reg[i], macbb_backup[i]);
4523        RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "RestoreMacBB Success!!!!\n");
4524}
4525
4526#undef MACBB_REG_NUM
4527#undef AFE_REG_NUM
4528#undef RF_REG_NUM
4529
4530#define MACBB_REG_NUM 11
4531#define AFE_REG_NUM 12
4532#define RF_REG_NUM 3
4533
4534static void _rtl8821ae_phy_iq_calibrate(struct ieee80211_hw *hw)
4535{
4536        u32     macbb_backup[MACBB_REG_NUM];
4537        u32 afe_backup[AFE_REG_NUM];
4538        u32 rfa_backup[RF_REG_NUM];
4539        u32 rfb_backup[RF_REG_NUM];
4540        u32 backup_macbb_reg[MACBB_REG_NUM] = {
4541                0xb00, 0x520, 0x550, 0x808, 0x90c, 0xc00, 0xc50,
4542                0xe00, 0xe50, 0x838, 0x82c
4543        };
4544        u32 backup_afe_reg[AFE_REG_NUM] = {
4545                0xc5c, 0xc60, 0xc64, 0xc68, 0xc6c, 0xc70, 0xc74,
4546                0xc78, 0xc7c, 0xc80, 0xc84, 0xcb8
4547        };
4548        u32     backup_rf_reg[RF_REG_NUM] = {0x65, 0x8f, 0x0};
4549
4550        _rtl8821ae_iqk_backup_macbb(hw, macbb_backup, backup_macbb_reg,
4551                                    MACBB_REG_NUM);
4552        _rtl8821ae_iqk_backup_afe(hw, afe_backup, backup_afe_reg, AFE_REG_NUM);
4553        _rtl8821ae_iqk_backup_rf(hw, rfa_backup, rfb_backup, backup_rf_reg,
4554                                 RF_REG_NUM);
4555
4556        _rtl8821ae_iqk_configure_mac(hw);
4557        _rtl8821ae_iqk_tx(hw, RF90_PATH_A);
4558        _rtl8821ae_iqk_restore_rf(hw, RF90_PATH_A, backup_rf_reg, rfa_backup,
4559                                  RF_REG_NUM);
4560
4561        _rtl8821ae_iqk_restore_afe(hw, afe_backup, backup_afe_reg, AFE_REG_NUM);
4562        _rtl8821ae_iqk_restore_macbb(hw, macbb_backup, backup_macbb_reg,
4563                                     MACBB_REG_NUM);
4564}
4565
4566static void _rtl8821ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool main)
4567{
4568        struct rtl_priv *rtlpriv = rtl_priv(hw);
4569        /* struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); */
4570        /* struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); */
4571        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
4572
4573        if (main)
4574                rtl_set_bbreg(hw, RA_RFE_PINMUX + 4, BIT(29) | BIT(28), 0x1);
4575        else
4576                rtl_set_bbreg(hw, RA_RFE_PINMUX + 4, BIT(29) | BIT(28), 0x2);
4577}
4578
4579#undef IQK_ADDA_REG_NUM
4580#undef IQK_DELAY_TIME
4581
4582void rtl8812ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
4583{
4584}
4585
4586void rtl8812ae_do_iqk(struct ieee80211_hw *hw, u8 delta_thermal_index,
4587                      u8 thermal_value, u8 threshold)
4588{
4589        struct rtl_dm   *rtldm = rtl_dm(rtl_priv(hw));
4590
4591        rtldm->thermalvalue_iqk = thermal_value;
4592        rtl8812ae_phy_iq_calibrate(hw, false);
4593}
4594
4595void rtl8821ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
4596{
4597        struct rtl_priv *rtlpriv = rtl_priv(hw);
4598        struct rtl_phy *rtlphy = &rtlpriv->phy;
4599
4600        if (!rtlphy->lck_inprogress) {
4601                spin_lock(&rtlpriv->locks.iqk_lock);
4602                rtlphy->lck_inprogress = true;
4603                spin_unlock(&rtlpriv->locks.iqk_lock);
4604
4605                _rtl8821ae_phy_iq_calibrate(hw);
4606
4607                spin_lock(&rtlpriv->locks.iqk_lock);
4608                rtlphy->lck_inprogress = false;
4609                spin_unlock(&rtlpriv->locks.iqk_lock);
4610        }
4611}
4612
4613void rtl8821ae_reset_iqk_result(struct ieee80211_hw *hw)
4614{
4615        struct rtl_priv *rtlpriv = rtl_priv(hw);
4616        struct rtl_phy *rtlphy = &rtlpriv->phy;
4617        u8 i;
4618
4619        RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD,
4620                 "rtl8812ae_dm_reset_iqk_result:: settings regs %d default regs %d\n",
4621                 (int)(sizeof(rtlphy->iqk_matrix) /
4622                 sizeof(struct iqk_matrix_regs)),
4623                 IQK_MATRIX_SETTINGS_NUM);
4624
4625        for (i = 0; i < IQK_MATRIX_SETTINGS_NUM; i++) {
4626                rtlphy->iqk_matrix[i].value[0][0] = 0x100;
4627                rtlphy->iqk_matrix[i].value[0][2] = 0x100;
4628                rtlphy->iqk_matrix[i].value[0][4] = 0x100;
4629                rtlphy->iqk_matrix[i].value[0][6] = 0x100;
4630
4631                rtlphy->iqk_matrix[i].value[0][1] = 0x0;
4632                rtlphy->iqk_matrix[i].value[0][3] = 0x0;
4633                rtlphy->iqk_matrix[i].value[0][5] = 0x0;
4634                rtlphy->iqk_matrix[i].value[0][7] = 0x0;
4635
4636                rtlphy->iqk_matrix[i].iqk_done = false;
4637        }
4638}
4639
4640void rtl8821ae_do_iqk(struct ieee80211_hw *hw, u8 delta_thermal_index,
4641                      u8 thermal_value, u8 threshold)
4642{
4643        struct rtl_dm   *rtldm = rtl_dm(rtl_priv(hw));
4644
4645        rtl8821ae_reset_iqk_result(hw);
4646
4647        rtldm->thermalvalue_iqk = thermal_value;
4648        rtl8821ae_phy_iq_calibrate(hw, false);
4649}
4650
4651void rtl8821ae_phy_lc_calibrate(struct ieee80211_hw *hw)
4652{
4653}
4654
4655void rtl8821ae_phy_ap_calibrate(struct ieee80211_hw *hw, char delta)
4656{
4657}
4658
4659void rtl8821ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
4660{
4661        _rtl8821ae_phy_set_rfpath_switch(hw, bmain);
4662}
4663
4664bool rtl8821ae_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
4665{
4666        struct rtl_priv *rtlpriv = rtl_priv(hw);
4667        struct rtl_phy *rtlphy = &rtlpriv->phy;
4668        bool postprocessing = false;
4669
4670        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4671                 "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
4672                  iotype, rtlphy->set_io_inprogress);
4673        do {
4674                switch (iotype) {
4675                case IO_CMD_RESUME_DM_BY_SCAN:
4676                        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4677                                 "[IO CMD] Resume DM after scan.\n");
4678                        postprocessing = true;
4679                        break;
4680                case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
4681                case IO_CMD_PAUSE_BAND1_DM_BY_SCAN:
4682                        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4683                                 "[IO CMD] Pause DM before scan.\n");
4684                        postprocessing = true;
4685                        break;
4686                default:
4687                        RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
4688                                 "switch case not process\n");
4689                        break;
4690                }
4691        } while (false);
4692        if (postprocessing && !rtlphy->set_io_inprogress) {
4693                rtlphy->set_io_inprogress = true;
4694                rtlphy->current_io_type = iotype;
4695        } else {
4696                return false;
4697        }
4698        rtl8821ae_phy_set_io(hw);
4699        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype);
4700        return true;
4701}
4702
4703static void rtl8821ae_phy_set_io(struct ieee80211_hw *hw)
4704{
4705        struct rtl_priv *rtlpriv = rtl_priv(hw);
4706        struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
4707        struct rtl_phy *rtlphy = &rtlpriv->phy;
4708
4709        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4710                 "--->Cmd(%#x), set_io_inprogress(%d)\n",
4711                  rtlphy->current_io_type, rtlphy->set_io_inprogress);
4712        switch (rtlphy->current_io_type) {
4713        case IO_CMD_RESUME_DM_BY_SCAN:
4714                if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC)
4715                        _rtl8821ae_resume_tx_beacon(hw);
4716                rtl8821ae_dm_write_dig(hw, rtlphy->initgain_backup.xaagccore1);
4717                rtl8821ae_dm_write_cck_cca_thres(hw,
4718                                                 rtlphy->initgain_backup.cca);
4719                break;
4720        case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
4721                if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC)
4722                        _rtl8821ae_stop_tx_beacon(hw);
4723                rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue;
4724                rtl8821ae_dm_write_dig(hw, 0x17);
4725                rtlphy->initgain_backup.cca = dm_digtable->cur_cck_cca_thres;
4726                rtl8821ae_dm_write_cck_cca_thres(hw, 0x40);
4727                break;
4728        case IO_CMD_PAUSE_BAND1_DM_BY_SCAN:
4729                break;
4730        default:
4731                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
4732                         "switch case not process\n");
4733                break;
4734        }
4735        rtlphy->set_io_inprogress = false;
4736        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
4737                 "(%#x)\n", rtlphy->current_io_type);
4738}
4739
4740static void rtl8821ae_phy_set_rf_on(struct ieee80211_hw *hw)
4741{
4742        struct rtl_priv *rtlpriv = rtl_priv(hw);
4743
4744        rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
4745        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
4746        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
4747        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
4748        rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
4749}
4750
4751static bool _rtl8821ae_phy_set_rf_power_state(struct ieee80211_hw *hw,
4752                                              enum rf_pwrstate rfpwr_state)
4753{
4754        struct rtl_priv *rtlpriv = rtl_priv(hw);
4755        struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
4756        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
4757        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
4758        bool bresult = true;
4759        u8 i, queue_id;
4760        struct rtl8192_tx_ring *ring = NULL;
4761
4762        switch (rfpwr_state) {
4763        case ERFON:
4764                if ((ppsc->rfpwr_state == ERFOFF) &&
4765                    RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
4766                        bool rtstatus = false;
4767                        u32 initializecount = 0;
4768
4769                        do {
4770                                initializecount++;
4771                                RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
4772                                         "IPS Set eRf nic enable\n");
4773                                rtstatus = rtl_ps_enable_nic(hw);
4774                        } while (!rtstatus && (initializecount < 10));
4775                        RT_CLEAR_PS_LEVEL(ppsc,
4776                                          RT_RF_OFF_LEVL_HALT_NIC);
4777                } else {
4778                        RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
4779                                 "Set ERFON sleeped:%d ms\n",
4780                                  jiffies_to_msecs(jiffies -
4781                                                   ppsc->
4782                                                   last_sleep_jiffies));
4783                        ppsc->last_awake_jiffies = jiffies;
4784                        rtl8821ae_phy_set_rf_on(hw);
4785                }
4786                if (mac->link_state == MAC80211_LINKED) {
4787                        rtlpriv->cfg->ops->led_control(hw,
4788                                                       LED_CTL_LINK);
4789                } else {
4790                        rtlpriv->cfg->ops->led_control(hw,
4791                                                       LED_CTL_NO_LINK);
4792                }
4793                break;
4794        case ERFOFF:
4795                for (queue_id = 0, i = 0;
4796                     queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
4797                        ring = &pcipriv->dev.tx_ring[queue_id];
4798                        if (queue_id == BEACON_QUEUE ||
4799                            skb_queue_len(&ring->queue) == 0) {
4800                                queue_id++;
4801                                continue;
4802                        } else {
4803                                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
4804                                         "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
4805                                         (i + 1), queue_id,
4806                                         skb_queue_len(&ring->queue));
4807
4808                                udelay(10);
4809                                i++;
4810                        }
4811                        if (i >= MAX_DOZE_WAITING_TIMES_9x) {
4812                                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
4813                                         "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
4814                                          MAX_DOZE_WAITING_TIMES_9x,
4815                                          queue_id,
4816                                          skb_queue_len(&ring->queue));
4817                                break;
4818                        }
4819                }
4820
4821                if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
4822                        RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
4823                                 "IPS Set eRf nic disable\n");
4824                        rtl_ps_disable_nic(hw);
4825                        RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
4826                } else {
4827                        if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
4828                                rtlpriv->cfg->ops->led_control(hw,
4829                                                               LED_CTL_NO_LINK);
4830                        } else {
4831                                rtlpriv->cfg->ops->led_control(hw,
4832                                                               LED_CTL_POWER_OFF);
4833                        }
4834                }
4835                break;
4836        default:
4837                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
4838                         "switch case not process\n");
4839                bresult = false;
4840                break;
4841        }
4842        if (bresult)
4843                ppsc->rfpwr_state = rfpwr_state;
4844        return bresult;
4845}
4846
4847bool rtl8821ae_phy_set_rf_power_state(struct ieee80211_hw *hw,
4848                                      enum rf_pwrstate rfpwr_state)
4849{
4850        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
4851
4852        bool bresult = false;
4853
4854        if (rfpwr_state == ppsc->rfpwr_state)
4855                return bresult;
4856        bresult = _rtl8821ae_phy_set_rf_power_state(hw, rfpwr_state);
4857        return bresult;
4858}
4859