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