linux/drivers/staging/rtlwifi/rtl8822be/phy.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/******************************************************************************
   3 *
   4 * Copyright(c) 2016  Realtek Corporation.
   5 *
   6 * Contact Information:
   7 * wlanfae <wlanfae@realtek.com>
   8 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
   9 * Hsinchu 300, Taiwan.
  10 *
  11 * Larry Finger <Larry.Finger@lwfinger.net>
  12 *
  13 *****************************************************************************/
  14
  15#include "../wifi.h"
  16#include "../pci.h"
  17#include "../ps.h"
  18#include "../base.h"
  19#include "reg.h"
  20#include "def.h"
  21#include "phy.h"
  22#include "trx.h"
  23#include "../btcoexist/halbt_precomp.h"
  24#include "hw.h"
  25#include "../efuse.h"
  26
  27static u32 _rtl8822be_phy_calculate_bit_shift(u32 bitmask);
  28static void
  29_rtl8822be_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw);
  30
  31static long _rtl8822be_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
  32                                            enum wireless_mode wirelessmode,
  33                                            u8 txpwridx);
  34static void rtl8822be_phy_set_rf_on(struct ieee80211_hw *hw);
  35static void rtl8822be_phy_set_io(struct ieee80211_hw *hw);
  36
  37static u8 cck_rates[] = {DESC_RATE1M, DESC_RATE2M, DESC_RATE5_5M, DESC_RATE11M};
  38static u8 sizes_of_cck_retes = 4;
  39static u8 ofdm_rates[] = {DESC_RATE6M,  DESC_RATE9M,  DESC_RATE12M,
  40                          DESC_RATE18M, DESC_RATE24M, DESC_RATE36M,
  41                          DESC_RATE48M, DESC_RATE54M};
  42static u8 sizes_of_ofdm_retes = 8;
  43static u8 ht_rates_1t[] = {DESC_RATEMCS0, DESC_RATEMCS1, DESC_RATEMCS2,
  44                           DESC_RATEMCS3, DESC_RATEMCS4, DESC_RATEMCS5,
  45                           DESC_RATEMCS6, DESC_RATEMCS7};
  46static u8 sizes_of_ht_retes_1t = 8;
  47static u8 ht_rates_2t[] = {DESC_RATEMCS8,  DESC_RATEMCS9,  DESC_RATEMCS10,
  48                           DESC_RATEMCS11, DESC_RATEMCS12, DESC_RATEMCS13,
  49                           DESC_RATEMCS14, DESC_RATEMCS15};
  50static u8 sizes_of_ht_retes_2t = 8;
  51static u8 vht_rates_1t[] = {DESC_RATEVHT1SS_MCS0, DESC_RATEVHT1SS_MCS1,
  52                            DESC_RATEVHT1SS_MCS2, DESC_RATEVHT1SS_MCS3,
  53                            DESC_RATEVHT1SS_MCS4, DESC_RATEVHT1SS_MCS5,
  54                            DESC_RATEVHT1SS_MCS6, DESC_RATEVHT1SS_MCS7,
  55                            DESC_RATEVHT1SS_MCS8, DESC_RATEVHT1SS_MCS9};
  56static u8 vht_rates_2t[] = {DESC_RATEVHT2SS_MCS0, DESC_RATEVHT2SS_MCS1,
  57                            DESC_RATEVHT2SS_MCS2, DESC_RATEVHT2SS_MCS3,
  58                            DESC_RATEVHT2SS_MCS4, DESC_RATEVHT2SS_MCS5,
  59                            DESC_RATEVHT2SS_MCS6, DESC_RATEVHT2SS_MCS7,
  60                            DESC_RATEVHT2SS_MCS8, DESC_RATEVHT2SS_MCS9};
  61static u8 sizes_of_vht_retes = 10;
  62
  63u32 rtl8822be_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr,
  64                               u32 bitmask)
  65{
  66        struct rtl_priv *rtlpriv = rtl_priv(hw);
  67        u32 returnvalue, originalvalue, bitshift;
  68
  69        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n",
  70                 regaddr, bitmask);
  71        originalvalue = rtl_read_dword(rtlpriv, regaddr);
  72        bitshift = _rtl8822be_phy_calculate_bit_shift(bitmask);
  73        returnvalue = (originalvalue & bitmask) >> bitshift;
  74
  75        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "BBR MASK=0x%x Addr[0x%x]=0x%x\n",
  76                 bitmask, regaddr, originalvalue);
  77
  78        return returnvalue;
  79}
  80
  81void rtl8822be_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask,
  82                              u32 data)
  83{
  84        struct rtl_priv *rtlpriv = rtl_priv(hw);
  85        u32 originalvalue, bitshift;
  86
  87        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
  88                 "regaddr(%#x), bitmask(%#x), data(%#x)\n", regaddr, bitmask,
  89                 data);
  90
  91        if (bitmask != MASKDWORD) {
  92                originalvalue = rtl_read_dword(rtlpriv, regaddr);
  93                bitshift = _rtl8822be_phy_calculate_bit_shift(bitmask);
  94                data = ((originalvalue & (~bitmask)) |
  95                        ((data << bitshift) & bitmask));
  96        }
  97
  98        rtl_write_dword(rtlpriv, regaddr, data);
  99
 100        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
 101                 "regaddr(%#x), bitmask(%#x), data(%#x)\n", regaddr, bitmask,
 102                 data);
 103}
 104
 105u32 rtl8822be_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
 106                               u32 regaddr, u32 bitmask)
 107{
 108        struct rtl_priv *rtlpriv = rtl_priv(hw);
 109        u32 /*original_value,*/ readback_value /*, bitshift*/;
 110        unsigned long flags;
 111
 112        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
 113                 "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n", regaddr, rfpath,
 114                 bitmask);
 115
 116        spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
 117
 118        readback_value = rtlpriv->phydm.ops->phydm_read_rf_reg(
 119                rtlpriv, rfpath, regaddr, bitmask);
 120
 121        spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
 122
 123        return readback_value;
 124}
 125
 126void rtl8822be_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
 127                              u32 regaddr, u32 bitmask, u32 data)
 128{
 129        struct rtl_priv *rtlpriv = rtl_priv(hw);
 130        unsigned long flags;
 131
 132        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
 133                 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
 134                 regaddr, bitmask, data, rfpath);
 135
 136        spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
 137
 138        rtlpriv->phydm.ops->phydm_write_rf_reg(rtlpriv, rfpath, regaddr,
 139                                               bitmask, data);
 140
 141        spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
 142
 143        RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
 144                 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
 145                 regaddr, bitmask, data, rfpath);
 146}
 147
 148static u32 _rtl8822be_phy_calculate_bit_shift(u32 bitmask)
 149{
 150        u32 i;
 151
 152        for (i = 0; i <= 31; i++) {
 153                if (((bitmask >> i) & 0x1) == 1)
 154                        break;
 155        }
 156        return i;
 157}
 158
 159bool rtl8822be_halmac_cb_init_mac_register(struct rtl_priv *rtlpriv)
 160{
 161        return rtlpriv->phydm.ops->phydm_phy_mac_config(rtlpriv);
 162}
 163
 164bool rtl8822be_phy_bb_config(struct ieee80211_hw *hw)
 165{
 166        bool rtstatus = true;
 167        struct rtl_priv *rtlpriv = rtl_priv(hw);
 168        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 169        u8 crystal_cap;
 170        /* u32 tmp; */
 171
 172        rtstatus = rtlpriv->phydm.ops->phydm_phy_bb_config(rtlpriv);
 173
 174        /* write 0x28[6:1] = 0x24[30:25] = CrystalCap */
 175        crystal_cap = rtlefuse->crystalcap & 0x3F;
 176        rtl_set_bbreg(hw, REG_AFE_XTAL_CTRL_8822B, 0x7E000000, crystal_cap);
 177        rtl_set_bbreg(hw, REG_AFE_PLL_CTRL_8822B, 0x7E, crystal_cap);
 178
 179        /*rtlphy->reg_837 = rtl_read_byte(rtlpriv, 0x837);*/ /*unused*/
 180
 181        return rtstatus;
 182}
 183
 184bool rtl8822be_phy_rf_config(struct ieee80211_hw *hw)
 185{
 186        struct rtl_priv *rtlpriv = rtl_priv(hw);
 187        struct rtl_phy *rtlphy = &rtlpriv->phy;
 188
 189        if (rtlphy->rf_type == RF_1T1R)
 190                rtlphy->num_total_rfpath = 1;
 191        else
 192                rtlphy->num_total_rfpath = 2;
 193
 194        return rtlpriv->phydm.ops->phydm_phy_rf_config(rtlpriv);
 195}
 196
 197bool rtl8822be_halmac_cb_init_bb_rf_register(struct rtl_priv *rtlpriv)
 198{
 199        struct ieee80211_hw *hw = rtlpriv->hw;
 200        enum radio_mask txpath, rxpath;
 201        bool tx2path;
 202        bool ret = false;
 203
 204        _rtl8822be_phy_init_bb_rf_register_definition(hw);
 205
 206        rtlpriv->halmac.ops->halmac_phy_power_switch(rtlpriv, 1);
 207
 208        /* beofre bb/rf config */
 209        rtlpriv->phydm.ops->phydm_parameter_init(rtlpriv, 0);
 210
 211        /* do bb/rf config */
 212        if (rtl8822be_phy_bb_config(hw) && rtl8822be_phy_rf_config(hw))
 213                ret = true;
 214
 215        /* after bb/rf config */
 216        rtlpriv->phydm.ops->phydm_parameter_init(rtlpriv, 1);
 217
 218        /* set trx mode (keep it to be last, r17376) */
 219        txpath = RF_MASK_A | RF_MASK_B;
 220        rxpath = RF_MASK_A | RF_MASK_B;
 221        tx2path = false;
 222        ret = rtlpriv->phydm.ops->phydm_trx_mode(rtlpriv, txpath, rxpath,
 223                                                 tx2path);
 224
 225        return ret;
 226}
 227
 228static void _rtl8822be_phy_init_tx_power_by_rate(struct ieee80211_hw *hw)
 229{
 230        struct rtl_priv *rtlpriv = rtl_priv(hw);
 231        struct rtl_phy *rtlphy = &rtlpriv->phy;
 232
 233        u8 band, rfpath, txnum, rate;
 234
 235        for (band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band)
 236                for (rfpath = 0; rfpath < TX_PWR_BY_RATE_NUM_RF; ++rfpath)
 237                        for (txnum = 0; txnum < TX_PWR_BY_RATE_NUM_RF; ++txnum)
 238                                for (rate = 0; rate < TX_PWR_BY_RATE_NUM_RATE;
 239                                     ++rate)
 240                                        rtlphy->tx_power_by_rate_offset
 241                                                [band][rfpath][txnum][rate] = 0;
 242}
 243
 244static void _rtl8822be_phy_set_txpower_by_rate_base(struct ieee80211_hw *hw,
 245                                                    u8 band, u8 path,
 246                                                    u8 rate_section, u8 txnum,
 247                                                    u8 value)
 248{
 249        struct rtl_priv *rtlpriv = rtl_priv(hw);
 250        struct rtl_phy *rtlphy = &rtlpriv->phy;
 251
 252        if (path > RF90_PATH_D) {
 253                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 254                         "Invalid Rf Path %d in phy_SetTxPowerByRatBase()\n",
 255                         path);
 256                return;
 257        }
 258
 259        if (band != BAND_ON_2_4G && band != BAND_ON_5G) {
 260                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 261                         "Invalid band %d in phy_SetTxPowerByRatBase()\n",
 262                         band);
 263                return;
 264        }
 265
 266        if (rate_section >= MAX_RATE_SECTION ||
 267            (band == BAND_ON_5G && rate_section == CCK)) {
 268                RT_TRACE(
 269                        rtlpriv, COMP_INIT, DBG_LOUD,
 270                        "Invalid rate_section %d in phy_SetTxPowerByRatBase()\n",
 271                        rate_section);
 272                return;
 273        }
 274
 275        if (band == BAND_ON_2_4G)
 276                rtlphy->txpwr_by_rate_base_24g[path][txnum][rate_section] =
 277                        value;
 278        else /* BAND_ON_5G */
 279                rtlphy->txpwr_by_rate_base_5g[path][txnum][rate_section - 1] =
 280                        value;
 281}
 282
 283static u8 _rtl8822be_phy_get_txpower_by_rate_base(struct ieee80211_hw *hw,
 284                                                  u8 band, u8 path, u8 txnum,
 285                                                  u8 rate_section)
 286{
 287        struct rtl_priv *rtlpriv = rtl_priv(hw);
 288        struct rtl_phy *rtlphy = &rtlpriv->phy;
 289        u8 value;
 290
 291        if (path > RF90_PATH_D) {
 292                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 293                         "Invalid Rf Path %d in phy_GetTxPowerByRatBase()\n",
 294                         path);
 295                return 0;
 296        }
 297
 298        if (band != BAND_ON_2_4G && band != BAND_ON_5G) {
 299                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 300                         "Invalid band %d in phy_GetTxPowerByRatBase()\n",
 301                         band);
 302                return 0;
 303        }
 304
 305        if (rate_section >= MAX_RATE_SECTION ||
 306            (band == BAND_ON_5G && rate_section == CCK)) {
 307                RT_TRACE(
 308                        rtlpriv, COMP_INIT, DBG_LOUD,
 309                        "Invalid rate_section %d in phy_GetTxPowerByRatBase()\n",
 310                        rate_section);
 311                return 0;
 312        }
 313
 314        if (band == BAND_ON_2_4G)
 315                value = rtlphy->txpwr_by_rate_base_24g[path][txnum]
 316                                                      [rate_section];
 317        else /* BAND_ON_5G */
 318                value = rtlphy->txpwr_by_rate_base_5g[path][txnum]
 319                                                     [rate_section - 1];
 320
 321        return value;
 322}
 323
 324static void _rtl8822be_phy_store_txpower_by_rate_base(struct ieee80211_hw *hw)
 325{
 326        struct rtl_priv *rtlpriv = rtl_priv(hw);
 327        struct rtl_phy *rtlphy = &rtlpriv->phy;
 328
 329        struct {
 330                enum rtl_desc_rate rate;
 331                enum rate_section section;
 332        } rate_sec_base[] = {
 333                {DESC_RATE11M, CCK},
 334                {DESC_RATE54M, OFDM},
 335                {DESC_RATEMCS7, HT_MCS0_MCS7},
 336                {DESC_RATEMCS15, HT_MCS8_MCS15},
 337                {DESC_RATEVHT1SS_MCS7, VHT_1SSMCS0_1SSMCS9},
 338                {DESC_RATEVHT2SS_MCS7, VHT_2SSMCS0_2SSMCS9},
 339        };
 340
 341        u8 band, path, rs, tx_num, base;
 342        u8 rate, section;
 343
 344        for (band = BAND_ON_2_4G; band <= BAND_ON_5G; band++) {
 345                for (path = RF90_PATH_A; path <= RF90_PATH_B; path++) {
 346                        for (rs = 0; rs < MAX_RATE_SECTION; rs++) {
 347                                rate = rate_sec_base[rs].rate;
 348                                section = rate_sec_base[rs].section;
 349
 350                                if (IS_1T_RATE(rate))
 351                                        tx_num = RF_1TX;
 352                                else
 353                                        tx_num = RF_2TX;
 354
 355                                if (band == BAND_ON_5G &&
 356                                    RX_HAL_IS_CCK_RATE(rate))
 357                                        continue;
 358
 359                                base = rtlphy->tx_power_by_rate_offset
 360                                               [band][path][tx_num][rate];
 361                                _rtl8822be_phy_set_txpower_by_rate_base(
 362                                        hw, band, path, section, tx_num, base);
 363                        }
 364                }
 365        }
 366}
 367
 368static void __rtl8822be_phy_cross_reference_core(struct ieee80211_hw *hw,
 369                                                 u8 regulation, u8 bw,
 370                                                 u8 channel)
 371{
 372        struct rtl_priv *rtlpriv = rtl_priv(hw);
 373        struct rtl_phy *rtlphy = &rtlpriv->phy;
 374        u8 rs, ref_rs;
 375        s8 pwrlmt, ref_pwrlmt;
 376
 377        for (rs = 0; rs < MAX_RATE_SECTION_NUM; ++rs) {
 378                /*5G 20M 40M VHT and HT can cross reference*/
 379                if (bw != HT_CHANNEL_WIDTH_20 && bw != HT_CHANNEL_WIDTH_20_40)
 380                        continue;
 381
 382                if (rs == HT_MCS0_MCS7)
 383                        ref_rs = VHT_1SSMCS0_1SSMCS9;
 384                else if (rs == HT_MCS8_MCS15)
 385                        ref_rs = VHT_2SSMCS0_2SSMCS9;
 386                else if (rs == VHT_1SSMCS0_1SSMCS9)
 387                        ref_rs = HT_MCS0_MCS7;
 388                else if (rs == VHT_2SSMCS0_2SSMCS9)
 389                        ref_rs = HT_MCS8_MCS15;
 390                else
 391                        continue;
 392
 393                ref_pwrlmt = rtlphy->txpwr_limit_5g[regulation][bw][ref_rs]
 394                                                   [channel][RF90_PATH_A];
 395                if (ref_pwrlmt == MAX_POWER_INDEX)
 396                        continue;
 397
 398                pwrlmt = rtlphy->txpwr_limit_5g[regulation][bw][rs][channel]
 399                                               [RF90_PATH_A];
 400                if (pwrlmt != MAX_POWER_INDEX)
 401                        continue;
 402
 403                rtlphy->txpwr_limit_5g[regulation][bw][rs][channel]
 404                                      [RF90_PATH_A] = ref_pwrlmt;
 405        }
 406}
 407
 408static void
 409_rtl8822be_phy_cross_reference_ht_and_vht_txpower_limit(struct ieee80211_hw *hw)
 410{
 411        u8 regulation, bw, channel;
 412
 413        for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
 414                for (bw = 0; bw < MAX_5G_BANDWIDTH_NUM; ++bw) {
 415                        for (channel = 0; channel < CHANNEL_MAX_NUMBER_5G;
 416                             ++channel) {
 417                                __rtl8822be_phy_cross_reference_core(
 418                                        hw, regulation, bw, channel);
 419                        }
 420                }
 421        }
 422}
 423
 424static void __rtl8822be_txpwr_limit_to_index_2g(struct ieee80211_hw *hw,
 425                                                u8 regulation, u8 bw,
 426                                                u8 channel)
 427{
 428        struct rtl_priv *rtlpriv = rtl_priv(hw);
 429        struct rtl_phy *rtlphy = &rtlpriv->phy;
 430        u8 bw40_pwr_base_dbm2_4G;
 431        u8 rate_section;
 432        s8 temp_pwrlmt;
 433        enum rf_tx_num txnum;
 434        s8 temp_value;
 435        u8 rf_path;
 436
 437        for (rate_section = 0; rate_section < MAX_RATE_SECTION_NUM;
 438             ++rate_section) {
 439                /* obtain the base dBm values in 2.4G band
 440                 * CCK => 11M, OFDM => 54M, HT 1T => MCS7, HT 2T => MCS15
 441                 */
 442
 443                temp_pwrlmt =
 444                        rtlphy->txpwr_limit_2_4g[regulation][bw][rate_section]
 445                                                [channel][RF90_PATH_A];
 446                txnum = IS_1T_RATESEC(rate_section) ? RF_1TX : RF_2TX;
 447
 448                if (temp_pwrlmt == MAX_POWER_INDEX)
 449                        continue;
 450
 451                for (rf_path = RF90_PATH_A; rf_path < MAX_RF_PATH_NUM;
 452                     ++rf_path) {
 453                        bw40_pwr_base_dbm2_4G =
 454                                _rtl8822be_phy_get_txpower_by_rate_base(
 455                                        hw, BAND_ON_2_4G, rf_path, txnum,
 456                                        rate_section);
 457
 458                        temp_value = temp_pwrlmt - bw40_pwr_base_dbm2_4G;
 459                        rtlphy->txpwr_limit_2_4g[regulation][bw][rate_section]
 460                                                [channel][rf_path] = temp_value;
 461
 462                        RT_TRACE(
 463                                rtlpriv, COMP_INIT, DBG_TRACE,
 464                                "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",
 465                                regulation, bw, rate_section, channel,
 466                                rtlphy->txpwr_limit_2_4g[regulation][bw]
 467                                                        [rate_section][channel]
 468                                                        [rf_path],
 469                                (temp_pwrlmt == 63) ? 0 : temp_pwrlmt / 2,
 470                                channel, rf_path, bw40_pwr_base_dbm2_4G);
 471                }
 472        }
 473}
 474
 475static void __rtl8822be_txpwr_limit_to_index_5g(struct ieee80211_hw *hw,
 476                                                u8 regulation, u8 bw,
 477                                                u8 channel)
 478{
 479        struct rtl_priv *rtlpriv = rtl_priv(hw);
 480        struct rtl_phy *rtlphy = &rtlpriv->phy;
 481        u8 bw40_pwr_base_dbm5G;
 482        u8 rate_section;
 483        s8 temp_pwrlmt;
 484        enum rf_tx_num txnum;
 485        s8 temp_value;
 486        u8 rf_path;
 487
 488        for (rate_section = 0; rate_section < MAX_RATE_SECTION_NUM;
 489             ++rate_section) {
 490                /* obtain the base dBm values in 5G band
 491                 * OFDM => 54M, HT 1T => MCS7, HT 2T => MCS15,
 492                 * VHT => 1SSMCS7, VHT 2T => 2SSMCS7
 493                 */
 494
 495                temp_pwrlmt =
 496                        rtlphy->txpwr_limit_5g[regulation][bw][rate_section]
 497                                              [channel][RF90_PATH_A];
 498                txnum = IS_1T_RATESEC(rate_section) ? RF_1TX : RF_2TX;
 499
 500                if (temp_pwrlmt == MAX_POWER_INDEX)
 501                        continue;
 502
 503                for (rf_path = RF90_PATH_A; rf_path < MAX_RF_PATH_NUM;
 504                     ++rf_path) {
 505                        bw40_pwr_base_dbm5G =
 506                                _rtl8822be_phy_get_txpower_by_rate_base(
 507                                        hw, BAND_ON_5G, rf_path, txnum,
 508                                        rate_section);
 509
 510                        temp_value = temp_pwrlmt - bw40_pwr_base_dbm5G;
 511                        rtlphy->txpwr_limit_5g[regulation][bw][rate_section]
 512                                              [channel][rf_path] = temp_value;
 513
 514                        RT_TRACE(
 515                                rtlpriv, COMP_INIT, DBG_TRACE,
 516                                "TxPwrLimit_5G[regulation %d][bw %d][rateSection %d][channel %d] =%d\n(TxPwrLimit in dBm %d - BW40PwrLmt5G[chnl group %d][rfPath %d] %d)\n",
 517                                regulation, bw, rate_section, channel,
 518                                rtlphy->txpwr_limit_5g[regulation][bw]
 519                                                      [rate_section][channel]
 520                                                      [rf_path],
 521                                temp_pwrlmt, channel, rf_path,
 522                                bw40_pwr_base_dbm5G);
 523                }
 524        }
 525}
 526
 527static void
 528_rtl8822be_phy_convert_txpower_limit_to_power_index(struct ieee80211_hw *hw)
 529{
 530        struct rtl_priv *rtlpriv = rtl_priv(hw);
 531        u8 regulation, bw, channel;
 532
 533        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "=====> %s()\n", __func__);
 534
 535        _rtl8822be_phy_cross_reference_ht_and_vht_txpower_limit(hw);
 536
 537        for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
 538                for (bw = 0; bw < MAX_2_4G_BANDWIDTH_NUM; ++bw) {
 539                        for (channel = 0; channel < CHANNEL_MAX_NUMBER_2G;
 540                             ++channel) {
 541                                __rtl8822be_txpwr_limit_to_index_2g(
 542                                        hw, regulation, bw, channel);
 543                        }
 544                }
 545        }
 546
 547        for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) {
 548                for (bw = 0; bw < MAX_5G_BANDWIDTH_NUM; ++bw) {
 549                        for (channel = 0; channel < CHANNEL_MAX_NUMBER_5G;
 550                             ++channel) {
 551                                __rtl8822be_txpwr_limit_to_index_5g(
 552                                        hw, regulation, bw, channel);
 553                        }
 554                }
 555        }
 556        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "<===== %s()\n", __func__);
 557}
 558
 559static void _rtl8822be_phy_init_txpower_limit(struct ieee80211_hw *hw)
 560{
 561        struct rtl_priv *rtlpriv = rtl_priv(hw);
 562        struct rtl_phy *rtlphy = &rtlpriv->phy;
 563        u8 i, j, k, l, m;
 564
 565        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "=====> %s()!\n", __func__);
 566
 567        for (i = 0; i < MAX_REGULATION_NUM; ++i) {
 568                for (j = 0; j < MAX_2_4G_BANDWIDTH_NUM; ++j)
 569                        for (k = 0; k < MAX_RATE_SECTION_NUM; ++k)
 570                                for (m = 0; m < CHANNEL_MAX_NUMBER_2G; ++m)
 571                                        for (l = 0; l < MAX_RF_PATH_NUM; ++l)
 572                                                rtlphy->txpwr_limit_2_4g[i][j]
 573                                                                        [k][m]
 574                                                                        [l] =
 575                                                        MAX_POWER_INDEX;
 576        }
 577        for (i = 0; i < MAX_REGULATION_NUM; ++i) {
 578                for (j = 0; j < MAX_5G_BANDWIDTH_NUM; ++j)
 579                        for (k = 0; k < MAX_RATE_SECTION_NUM; ++k)
 580                                for (m = 0; m < CHANNEL_MAX_NUMBER_5G; ++m)
 581                                        for (l = 0; l < MAX_RF_PATH_NUM; ++l)
 582                                                rtlphy->txpwr_limit_5g[i][j][k]
 583                                                                      [m][l] =
 584                                                        MAX_POWER_INDEX;
 585        }
 586
 587        RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "<===== %s()!\n", __func__);
 588}
 589
 590static void
 591_rtl8822be_phy_convert_txpower_dbm_to_relative_value(struct ieee80211_hw *hw)
 592{
 593        struct rtl_priv *rtlpriv = rtl_priv(hw);
 594        struct rtl_phy *rtlphy = &rtlpriv->phy;
 595
 596        u8 base = 0, i = 0, value = 0, band = 0, path = 0, txnum = 0;
 597
 598        for (band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band) {
 599                for (path = RF90_PATH_A; path <= RF90_PATH_B; ++path) {
 600                        for (txnum = RF_1TX; txnum <= RF_2TX; ++txnum) {
 601                                /* CCK */
 602                                base = rtlphy->tx_power_by_rate_offset
 603                                               [band][path][txnum]
 604                                               [DESC_RATE11M];
 605                                for (i = 0; i < sizeof(cck_rates); ++i) {
 606                                        value = rtlphy->tx_power_by_rate_offset
 607                                                        [band][path][txnum]
 608                                                        [cck_rates[i]];
 609                                        rtlphy->tx_power_by_rate_offset
 610                                                [band][path][txnum]
 611                                                [cck_rates[i]] = value - base;
 612                                }
 613
 614                                /* OFDM */
 615                                base = rtlphy->tx_power_by_rate_offset
 616                                               [band][path][txnum]
 617                                               [DESC_RATE54M];
 618                                for (i = 0; i < sizeof(ofdm_rates); ++i) {
 619                                        value = rtlphy->tx_power_by_rate_offset
 620                                                        [band][path][txnum]
 621                                                        [ofdm_rates[i]];
 622                                        rtlphy->tx_power_by_rate_offset
 623                                                [band][path][txnum]
 624                                                [ofdm_rates[i]] = value - base;
 625                                }
 626
 627                                /* HT MCS0~7 */
 628                                base = rtlphy->tx_power_by_rate_offset
 629                                               [band][path][txnum]
 630                                               [DESC_RATEMCS7];
 631                                for (i = 0; i < sizeof(ht_rates_1t); ++i) {
 632                                        value = rtlphy->tx_power_by_rate_offset
 633                                                        [band][path][txnum]
 634                                                        [ht_rates_1t[i]];
 635                                        rtlphy->tx_power_by_rate_offset
 636                                                [band][path][txnum]
 637                                                [ht_rates_1t[i]] = value - base;
 638                                }
 639
 640                                /* HT MCS8~15 */
 641                                base = rtlphy->tx_power_by_rate_offset
 642                                               [band][path][txnum]
 643                                               [DESC_RATEMCS15];
 644                                for (i = 0; i < sizeof(ht_rates_2t); ++i) {
 645                                        value = rtlphy->tx_power_by_rate_offset
 646                                                        [band][path][txnum]
 647                                                        [ht_rates_2t[i]];
 648                                        rtlphy->tx_power_by_rate_offset
 649                                                [band][path][txnum]
 650                                                [ht_rates_2t[i]] = value - base;
 651                                }
 652
 653                                /* VHT 1SS */
 654                                base = rtlphy->tx_power_by_rate_offset
 655                                               [band][path][txnum]
 656                                               [DESC_RATEVHT1SS_MCS7];
 657                                for (i = 0; i < sizeof(vht_rates_1t); ++i) {
 658                                        value = rtlphy->tx_power_by_rate_offset
 659                                                        [band][path][txnum]
 660                                                        [vht_rates_1t[i]];
 661                                        rtlphy->tx_power_by_rate_offset
 662                                                [band][path][txnum]
 663                                                [vht_rates_1t[i]] =
 664                                                value - base;
 665                                }
 666
 667                                /* VHT 2SS */
 668                                base = rtlphy->tx_power_by_rate_offset
 669                                               [band][path][txnum]
 670                                               [DESC_RATEVHT2SS_MCS7];
 671                                for (i = 0; i < sizeof(vht_rates_2t); ++i) {
 672                                        value = rtlphy->tx_power_by_rate_offset
 673                                                        [band][path][txnum]
 674                                                        [vht_rates_2t[i]];
 675                                        rtlphy->tx_power_by_rate_offset
 676                                                [band][path][txnum]
 677                                                [vht_rates_2t[i]] =
 678                                                value - base;
 679                                }
 680                        }
 681                }
 682        }
 683
 684        RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, "<===%s()\n", __func__);
 685}
 686
 687static void
 688_rtl8822be_phy_txpower_by_rate_configuration(struct ieee80211_hw *hw)
 689{
 690        /* copy rate_section from
 691         * tx_power_by_rate_offset[][rate] to txpwr_by_rate_base_24g/_5g[][rs]
 692         */
 693        _rtl8822be_phy_store_txpower_by_rate_base(hw);
 694
 695        /* convert tx_power_by_rate_offset[] to relative value */
 696        _rtl8822be_phy_convert_txpower_dbm_to_relative_value(hw);
 697}
 698
 699/* string is in decimal */
 700static bool _rtl8822be_get_integer_from_string(char *str, u8 *pint)
 701{
 702        u16 i = 0;
 703        *pint = 0;
 704
 705        while (str[i] != '\0') {
 706                if (str[i] >= '0' && str[i] <= '9') {
 707                        *pint *= 10;
 708                        *pint += (str[i] - '0');
 709                } else {
 710                        return false;
 711                }
 712                ++i;
 713        }
 714
 715        return true;
 716}
 717
 718static bool _rtl8822be_eq_n_byte(u8 *str1, u8 *str2, u32 num)
 719{
 720        if (num == 0)
 721                return false;
 722        while (num > 0) {
 723                num--;
 724                if (str1[num] != str2[num])
 725                        return false;
 726        }
 727        return true;
 728}
 729
 730static char _rtl8822be_phy_get_chnl_idx_of_txpwr_lmt(struct ieee80211_hw *hw,
 731                                                     u8 band, u8 channel)
 732{
 733        struct rtl_priv *rtlpriv = rtl_priv(hw);
 734        char channel_index = -1;
 735        u8 i = 0;
 736
 737        if (band == BAND_ON_2_4G) {
 738                channel_index = channel - 1;
 739        } else if (band == BAND_ON_5G) {
 740                for (i = 0; i < sizeof(rtl_channel5g) / sizeof(u8); ++i) {
 741                        if (rtl_channel5g[i] == channel)
 742                                channel_index = i;
 743                }
 744        } else {
 745                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid Band %d in %s",
 746                         band, __func__);
 747        }
 748
 749        if (channel_index == -1)
 750                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
 751                         "Invalid Channel %d of Band %d in %s", channel, band,
 752                         __func__);
 753
 754        return channel_index;
 755}
 756
 757void rtl8822be_phy_set_txpower_limit(struct ieee80211_hw *hw, u8 *pregulation,
 758                                     u8 *pband, u8 *pbandwidth,
 759                                     u8 *prate_section, u8 *prf_path,
 760                                     u8 *pchannel, u8 *ppower_limit)
 761{
 762        struct rtl_priv *rtlpriv = rtl_priv(hw);
 763        struct rtl_phy *rtlphy = &rtlpriv->phy;
 764        u8 regulation = 0, bandwidth = 0, rate_section = 0, channel;
 765        u8 channel_index;
 766        char power_limit = 0, prev_power_limit, ret;
 767
 768        if (!_rtl8822be_get_integer_from_string((char *)pchannel, &channel) ||
 769            !_rtl8822be_get_integer_from_string((char *)ppower_limit,
 770                                                &power_limit)) {
 771                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 772                         "Illegal index of pwr_lmt table [chnl %d][val %d]\n",
 773                         channel, power_limit);
 774        }
 775
 776        power_limit =
 777                power_limit > MAX_POWER_INDEX ? MAX_POWER_INDEX : power_limit;
 778
 779        if (_rtl8822be_eq_n_byte(pregulation, (u8 *)("FCC"), 3))
 780                regulation = 0;
 781        else if (_rtl8822be_eq_n_byte(pregulation, (u8 *)("MKK"), 3))
 782                regulation = 1;
 783        else if (_rtl8822be_eq_n_byte(pregulation, (u8 *)("ETSI"), 4))
 784                regulation = 2;
 785        else if (_rtl8822be_eq_n_byte(pregulation, (u8 *)("WW13"), 4))
 786                regulation = 3;
 787
 788        if (_rtl8822be_eq_n_byte(prate_section, (u8 *)("CCK"), 3))
 789                rate_section = CCK;
 790        else if (_rtl8822be_eq_n_byte(prate_section, (u8 *)("OFDM"), 4))
 791                rate_section = OFDM;
 792        else if (_rtl8822be_eq_n_byte(prate_section, (u8 *)("HT"), 2) &&
 793                 _rtl8822be_eq_n_byte(prf_path, (u8 *)("1T"), 2))
 794                rate_section = HT_MCS0_MCS7;
 795        else if (_rtl8822be_eq_n_byte(prate_section, (u8 *)("HT"), 2) &&
 796                 _rtl8822be_eq_n_byte(prf_path, (u8 *)("2T"), 2))
 797                rate_section = HT_MCS8_MCS15;
 798        else if (_rtl8822be_eq_n_byte(prate_section, (u8 *)("VHT"), 3) &&
 799                 _rtl8822be_eq_n_byte(prf_path, (u8 *)("1T"), 2))
 800                rate_section = VHT_1SSMCS0_1SSMCS9;
 801        else if (_rtl8822be_eq_n_byte(prate_section, (u8 *)("VHT"), 3) &&
 802                 _rtl8822be_eq_n_byte(prf_path, (u8 *)("2T"), 2))
 803                rate_section = VHT_2SSMCS0_2SSMCS9;
 804
 805        if (_rtl8822be_eq_n_byte(pbandwidth, (u8 *)("20M"), 3))
 806                bandwidth = HT_CHANNEL_WIDTH_20;
 807        else if (_rtl8822be_eq_n_byte(pbandwidth, (u8 *)("40M"), 3))
 808                bandwidth = HT_CHANNEL_WIDTH_20_40;
 809        else if (_rtl8822be_eq_n_byte(pbandwidth, (u8 *)("80M"), 3))
 810                bandwidth = HT_CHANNEL_WIDTH_80;
 811        else if (_rtl8822be_eq_n_byte(pbandwidth, (u8 *)("160M"), 4))
 812                bandwidth = 3;
 813
 814        if (_rtl8822be_eq_n_byte(pband, (u8 *)("2.4G"), 4)) {
 815                ret = _rtl8822be_phy_get_chnl_idx_of_txpwr_lmt(hw, BAND_ON_2_4G,
 816                                                               channel);
 817
 818                if (ret == -1)
 819                        return;
 820
 821                channel_index = ret;
 822
 823                prev_power_limit =
 824                        rtlphy->txpwr_limit_2_4g[regulation][bandwidth]
 825                                                [rate_section][channel_index]
 826                                                [RF90_PATH_A];
 827
 828                if (power_limit < prev_power_limit)
 829                        rtlphy->txpwr_limit_2_4g[regulation][bandwidth]
 830                                                [rate_section][channel_index]
 831                                                [RF90_PATH_A] = power_limit;
 832
 833                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 834                         "2.4G [regula %d][bw %d][sec %d][chnl %d][val %d]\n",
 835                         regulation, bandwidth, rate_section, channel_index,
 836                         rtlphy->txpwr_limit_2_4g[regulation][bandwidth]
 837                                                 [rate_section][channel_index]
 838                                                 [RF90_PATH_A]);
 839        } else if (_rtl8822be_eq_n_byte(pband, (u8 *)("5G"), 2)) {
 840                ret = _rtl8822be_phy_get_chnl_idx_of_txpwr_lmt(hw, BAND_ON_5G,
 841                                                               channel);
 842
 843                if (ret == -1)
 844                        return;
 845
 846                channel_index = ret;
 847
 848                prev_power_limit =
 849                        rtlphy->txpwr_limit_5g[regulation][bandwidth]
 850                                              [rate_section][channel_index]
 851                                              [RF90_PATH_A];
 852
 853                if (power_limit < prev_power_limit)
 854                        rtlphy->txpwr_limit_5g[regulation][bandwidth]
 855                                              [rate_section][channel_index]
 856                                              [RF90_PATH_A] = power_limit;
 857
 858                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 859                         "5G: [regul %d][bw %d][sec %d][chnl %d][val %d]\n",
 860                         regulation, bandwidth, rate_section, channel,
 861                         rtlphy->txpwr_limit_5g[regulation][bandwidth]
 862                                               [rate_section][channel_index]
 863                                               [RF90_PATH_A]);
 864
 865        } else {
 866                RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 867                         "Cannot recognize the band info in %s\n", pband);
 868                return;
 869        }
 870}
 871
 872bool rtl8822be_load_txpower_by_rate(struct ieee80211_hw *hw)
 873{
 874        struct rtl_priv *rtlpriv = rtl_priv(hw);
 875        bool rtstatus = true;
 876
 877        _rtl8822be_phy_init_tx_power_by_rate(hw);
 878
 879        rtstatus = rtlpriv->phydm.ops->phydm_load_txpower_by_rate(rtlpriv);
 880
 881        if (!rtstatus) {
 882                pr_err("BB_PG Reg Fail!!\n");
 883                return false;
 884        }
 885
 886        _rtl8822be_phy_txpower_by_rate_configuration(hw);
 887
 888        return true;
 889}
 890
 891bool rtl8822be_load_txpower_limit(struct ieee80211_hw *hw)
 892{
 893        struct rtl_priv *rtlpriv = rtl_priv(hw);
 894        struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
 895        bool rtstatus = true;
 896
 897        _rtl8822be_phy_init_txpower_limit(hw);
 898
 899        if (rtlefuse->eeprom_regulatory == 1)
 900                ;
 901        else
 902                return true;
 903
 904        rtstatus = rtlpriv->phydm.ops->phydm_load_txpower_limit(rtlpriv);
 905
 906        if (!rtstatus) {
 907                pr_err("RF TxPwr Limit Fail!!\n");
 908                return false;
 909        }
 910
 911        _rtl8822be_phy_convert_txpower_limit_to_power_index(hw);
 912
 913        return true;
 914}
 915
 916static void _rtl8822be_get_rate_values_of_tx_power_by_rate(
 917        struct ieee80211_hw *hw, u32 reg_addr, u32 bit_mask, u32 value,
 918        u8 *rate, s8 *pwr_by_rate_val, u8 *rate_num)
 919{
 920        struct rtl_priv *rtlpriv = rtl_priv(hw);
 921        u8 /*index = 0,*/ i = 0;
 922
 923        switch (reg_addr) {
 924        case 0xE00: /*rTxAGC_A_Rate18_06:*/
 925        case 0x830: /*rTxAGC_B_Rate18_06:*/
 926                rate[0] = DESC_RATE6M;
 927                rate[1] = DESC_RATE9M;
 928                rate[2] = DESC_RATE12M;
 929                rate[3] = DESC_RATE18M;
 930                for (i = 0; i < 4; ++i) {
 931                        pwr_by_rate_val[i] =
 932                                (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
 933                                     ((value >> (i * 8)) & 0xF));
 934                }
 935                *rate_num = 4;
 936                break;
 937
 938        case 0xE04: /*rTxAGC_A_Rate54_24:*/
 939        case 0x834: /*rTxAGC_B_Rate54_24:*/
 940                rate[0] = DESC_RATE24M;
 941                rate[1] = DESC_RATE36M;
 942                rate[2] = DESC_RATE48M;
 943                rate[3] = DESC_RATE54M;
 944                for (i = 0; i < 4; ++i) {
 945                        pwr_by_rate_val[i] =
 946                                (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
 947                                     ((value >> (i * 8)) & 0xF));
 948                }
 949                *rate_num = 4;
 950                break;
 951
 952        case 0xE08: /*rTxAGC_A_CCK1_Mcs32:*/
 953                rate[0] = DESC_RATE1M;
 954                pwr_by_rate_val[0] = (s8)((((value >> (8 + 4)) & 0xF)) * 10 +
 955                                          ((value >> 8) & 0xF));
 956                *rate_num = 1;
 957                break;
 958
 959        case 0x86C: /*rTxAGC_B_CCK11_A_CCK2_11:*/
 960                if (bit_mask == 0xffffff00) {
 961                        rate[0] = DESC_RATE2M;
 962                        rate[1] = DESC_RATE5_5M;
 963                        rate[2] = DESC_RATE11M;
 964                        for (i = 1; i < 4; ++i) {
 965                                pwr_by_rate_val[i - 1] = (s8)(
 966                                        (((value >> (i * 8 + 4)) & 0xF)) * 10 +
 967                                        ((value >> (i * 8)) & 0xF));
 968                        }
 969                        *rate_num = 3;
 970                } else if (bit_mask == 0x000000ff) {
 971                        rate[0] = DESC_RATE11M;
 972                        pwr_by_rate_val[0] = (s8)((((value >> 4) & 0xF)) * 10 +
 973                                                  (value & 0xF));
 974                        *rate_num = 1;
 975                }
 976                break;
 977
 978        case 0xE10: /*rTxAGC_A_Mcs03_Mcs00:*/
 979        case 0x83C: /*rTxAGC_B_Mcs03_Mcs00:*/
 980                rate[0] = DESC_RATEMCS0;
 981                rate[1] = DESC_RATEMCS1;
 982                rate[2] = DESC_RATEMCS2;
 983                rate[3] = DESC_RATEMCS3;
 984                for (i = 0; i < 4; ++i) {
 985                        pwr_by_rate_val[i] =
 986                                (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
 987                                     ((value >> (i * 8)) & 0xF));
 988                }
 989                *rate_num = 4;
 990                break;
 991
 992        case 0xE14: /*rTxAGC_A_Mcs07_Mcs04:*/
 993        case 0x848: /*rTxAGC_B_Mcs07_Mcs04:*/
 994                rate[0] = DESC_RATEMCS4;
 995                rate[1] = DESC_RATEMCS5;
 996                rate[2] = DESC_RATEMCS6;
 997                rate[3] = DESC_RATEMCS7;
 998                for (i = 0; i < 4; ++i) {
 999                        pwr_by_rate_val[i] =
1000                                (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1001                                     ((value >> (i * 8)) & 0xF));
1002                }
1003                *rate_num = 4;
1004                break;
1005
1006        case 0xE18: /*rTxAGC_A_Mcs11_Mcs08:*/
1007        case 0x84C: /*rTxAGC_B_Mcs11_Mcs08:*/
1008                rate[0] = DESC_RATEMCS8;
1009                rate[1] = DESC_RATEMCS9;
1010                rate[2] = DESC_RATEMCS10;
1011                rate[3] = DESC_RATEMCS11;
1012                for (i = 0; i < 4; ++i) {
1013                        pwr_by_rate_val[i] =
1014                                (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1015                                     ((value >> (i * 8)) & 0xF));
1016                }
1017                *rate_num = 4;
1018                break;
1019
1020        case 0xE1C: /*rTxAGC_A_Mcs15_Mcs12:*/
1021        case 0x868: /*rTxAGC_B_Mcs15_Mcs12:*/
1022                rate[0] = DESC_RATEMCS12;
1023                rate[1] = DESC_RATEMCS13;
1024                rate[2] = DESC_RATEMCS14;
1025                rate[3] = DESC_RATEMCS15;
1026                for (i = 0; i < 4; ++i) {
1027                        pwr_by_rate_val[i] =
1028                                (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1029                                     ((value >> (i * 8)) & 0xF));
1030                }
1031                *rate_num = 4;
1032
1033                break;
1034
1035        case 0x838: /*rTxAGC_B_CCK1_55_Mcs32:*/
1036                rate[0] = DESC_RATE1M;
1037                rate[1] = DESC_RATE2M;
1038                rate[2] = DESC_RATE5_5M;
1039                for (i = 1; i < 4; ++i) {
1040                        pwr_by_rate_val[i - 1] =
1041                                (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1042                                     ((value >> (i * 8)) & 0xF));
1043                }
1044                *rate_num = 3;
1045                break;
1046
1047        case 0xC20:
1048        case 0xE20:
1049        case 0x1820:
1050        case 0x1a20:
1051                rate[0] = DESC_RATE1M;
1052                rate[1] = DESC_RATE2M;
1053                rate[2] = DESC_RATE5_5M;
1054                rate[3] = DESC_RATE11M;
1055                for (i = 0; i < 4; ++i) {
1056                        pwr_by_rate_val[i] =
1057                                (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1058                                     ((value >> (i * 8)) & 0xF));
1059                }
1060                *rate_num = 4;
1061                break;
1062
1063        case 0xC24:
1064        case 0xE24:
1065        case 0x1824:
1066        case 0x1a24:
1067                rate[0] = DESC_RATE6M;
1068                rate[1] = DESC_RATE9M;
1069                rate[2] = DESC_RATE12M;
1070                rate[3] = DESC_RATE18M;
1071                for (i = 0; i < 4; ++i) {
1072                        pwr_by_rate_val[i] =
1073                                (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1074                                     ((value >> (i * 8)) & 0xF));
1075                }
1076                *rate_num = 4;
1077                break;
1078
1079        case 0xC28:
1080        case 0xE28:
1081        case 0x1828:
1082        case 0x1a28:
1083                rate[0] = DESC_RATE24M;
1084                rate[1] = DESC_RATE36M;
1085                rate[2] = DESC_RATE48M;
1086                rate[3] = DESC_RATE54M;
1087                for (i = 0; i < 4; ++i) {
1088                        pwr_by_rate_val[i] =
1089                                (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1090                                     ((value >> (i * 8)) & 0xF));
1091                }
1092                *rate_num = 4;
1093                break;
1094
1095        case 0xC2C:
1096        case 0xE2C:
1097        case 0x182C:
1098        case 0x1a2C:
1099                rate[0] = DESC_RATEMCS0;
1100                rate[1] = DESC_RATEMCS1;
1101                rate[2] = DESC_RATEMCS2;
1102                rate[3] = DESC_RATEMCS3;
1103                for (i = 0; i < 4; ++i) {
1104                        pwr_by_rate_val[i] =
1105                                (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1106                                     ((value >> (i * 8)) & 0xF));
1107                }
1108                *rate_num = 4;
1109                break;
1110
1111        case 0xC30:
1112        case 0xE30:
1113        case 0x1830:
1114        case 0x1a30:
1115                rate[0] = DESC_RATEMCS4;
1116                rate[1] = DESC_RATEMCS5;
1117                rate[2] = DESC_RATEMCS6;
1118                rate[3] = DESC_RATEMCS7;
1119                for (i = 0; i < 4; ++i) {
1120                        pwr_by_rate_val[i] =
1121                                (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1122                                     ((value >> (i * 8)) & 0xF));
1123                }
1124                *rate_num = 4;
1125                break;
1126
1127        case 0xC34:
1128        case 0xE34:
1129        case 0x1834:
1130        case 0x1a34:
1131                rate[0] = DESC_RATEMCS8;
1132                rate[1] = DESC_RATEMCS9;
1133                rate[2] = DESC_RATEMCS10;
1134                rate[3] = DESC_RATEMCS11;
1135                for (i = 0; i < 4; ++i) {
1136                        pwr_by_rate_val[i] =
1137                                (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1138                                     ((value >> (i * 8)) & 0xF));
1139                }
1140                *rate_num = 4;
1141                break;
1142
1143        case 0xC38:
1144        case 0xE38:
1145        case 0x1838:
1146        case 0x1a38:
1147                rate[0] = DESC_RATEMCS12;
1148                rate[1] = DESC_RATEMCS13;
1149                rate[2] = DESC_RATEMCS14;
1150                rate[3] = DESC_RATEMCS15;
1151                for (i = 0; i < 4; ++i) {
1152                        pwr_by_rate_val[i] =
1153                                (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1154                                     ((value >> (i * 8)) & 0xF));
1155                }
1156                *rate_num = 4;
1157                break;
1158
1159        case 0xC3C:
1160        case 0xE3C:
1161        case 0x183C:
1162        case 0x1a3C:
1163                rate[0] = DESC_RATEVHT1SS_MCS0;
1164                rate[1] = DESC_RATEVHT1SS_MCS1;
1165                rate[2] = DESC_RATEVHT1SS_MCS2;
1166                rate[3] = DESC_RATEVHT1SS_MCS3;
1167                for (i = 0; i < 4; ++i) {
1168                        pwr_by_rate_val[i] =
1169                                (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1170                                     ((value >> (i * 8)) & 0xF));
1171                }
1172                *rate_num = 4;
1173                break;
1174
1175        case 0xC40:
1176        case 0xE40:
1177        case 0x1840:
1178        case 0x1a40:
1179                rate[0] = DESC_RATEVHT1SS_MCS4;
1180                rate[1] = DESC_RATEVHT1SS_MCS5;
1181                rate[2] = DESC_RATEVHT1SS_MCS6;
1182                rate[3] = DESC_RATEVHT1SS_MCS7;
1183                for (i = 0; i < 4; ++i) {
1184                        pwr_by_rate_val[i] =
1185                                (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1186                                     ((value >> (i * 8)) & 0xF));
1187                }
1188                *rate_num = 4;
1189                break;
1190
1191        case 0xC44:
1192        case 0xE44:
1193        case 0x1844:
1194        case 0x1a44:
1195                rate[0] = DESC_RATEVHT1SS_MCS8;
1196                rate[1] = DESC_RATEVHT1SS_MCS9;
1197                rate[2] = DESC_RATEVHT2SS_MCS0;
1198                rate[3] = DESC_RATEVHT2SS_MCS1;
1199                for (i = 0; i < 4; ++i) {
1200                        pwr_by_rate_val[i] =
1201                                (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1202                                     ((value >> (i * 8)) & 0xF));
1203                }
1204                *rate_num = 4;
1205                break;
1206
1207        case 0xC48:
1208        case 0xE48:
1209        case 0x1848:
1210        case 0x1a48:
1211                rate[0] = DESC_RATEVHT2SS_MCS2;
1212                rate[1] = DESC_RATEVHT2SS_MCS3;
1213                rate[2] = DESC_RATEVHT2SS_MCS4;
1214                rate[3] = DESC_RATEVHT2SS_MCS5;
1215                for (i = 0; i < 4; ++i) {
1216                        pwr_by_rate_val[i] =
1217                                (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1218                                     ((value >> (i * 8)) & 0xF));
1219                }
1220                *rate_num = 4;
1221                break;
1222
1223        case 0xC4C:
1224        case 0xE4C:
1225        case 0x184C:
1226        case 0x1a4C:
1227                rate[0] = DESC_RATEVHT2SS_MCS6;
1228                rate[1] = DESC_RATEVHT2SS_MCS7;
1229                rate[2] = DESC_RATEVHT2SS_MCS8;
1230                rate[3] = DESC_RATEVHT2SS_MCS9;
1231                for (i = 0; i < 4; ++i) {
1232                        pwr_by_rate_val[i] =
1233                                (s8)((((value >> (i * 8 + 4)) & 0xF)) * 10 +
1234                                     ((value >> (i * 8)) & 0xF));
1235                }
1236                *rate_num = 4;
1237                break;
1238
1239        default:
1240                RT_TRACE(rtlpriv, COMP_INIT, DBG_DMESG,
1241                         "Invalid reg_addr 0x%x in %s()\n", reg_addr, __func__);
1242                break;
1243        }
1244}
1245
1246void rtl8822be_store_tx_power_by_rate(struct ieee80211_hw *hw, u32 band,
1247                                      u32 rfpath, u32 txnum, u32 regaddr,
1248                                      u32 bitmask, u32 data)
1249{
1250        struct rtl_priv *rtlpriv = rtl_priv(hw);
1251        struct rtl_phy *rtlphy = &rtlpriv->phy;
1252        u8 i = 0, rates[4] = {0}, rate_num = 0;
1253        s8 pwr_by_rate_val[4] = {0};
1254
1255        _rtl8822be_get_rate_values_of_tx_power_by_rate(
1256                hw, regaddr, bitmask, data, rates, pwr_by_rate_val, &rate_num);
1257
1258        if (band != BAND_ON_2_4G && band != BAND_ON_5G) {
1259                RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid Band %d\n",
1260                         band);
1261                band = BAND_ON_2_4G;
1262        }
1263        if (rfpath >= MAX_RF_PATH) {
1264                RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid RfPath %d\n",
1265                         rfpath);
1266                rfpath = MAX_RF_PATH - 1;
1267        }
1268        if (txnum >= MAX_RF_PATH) {
1269                RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid TxNum %d\n",
1270                         txnum);
1271                txnum = MAX_RF_PATH - 1;
1272        }
1273
1274        for (i = 0; i < rate_num; ++i) {
1275                u8 rate_idx = rates[i];
1276
1277                if (IS_1T_RATE(rates[i]))
1278                        txnum = RF_1TX;
1279                else if (IS_2T_RATE(rates[i]))
1280                        txnum = RF_2TX;
1281                else
1282                        WARN_ON(1);
1283
1284                rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_idx] =
1285                        pwr_by_rate_val[i];
1286
1287                RT_TRACE(
1288                        rtlpriv, COMP_INIT, DBG_LOUD,
1289                        "TxPwrByRateOffset[Band %d][RfPath %d][TxNum %d][rate_idx %d] = 0x%x\n",
1290                        band, rfpath, txnum, rate_idx,
1291                        rtlphy->tx_power_by_rate_offset[band][rfpath][txnum]
1292                                                       [rate_idx]);
1293        }
1294}
1295
1296static void
1297_rtl8822be_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw)
1298{
1299        struct rtl_priv *rtlpriv = rtl_priv(hw);
1300        struct rtl_phy *rtlphy = &rtlpriv->phy;
1301
1302        rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
1303        rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
1304
1305        rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
1306        rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
1307
1308        rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
1309        rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
1310
1311        rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = RA_LSSIWRITE_8822B;
1312        rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = RB_LSSIWRITE_8822B;
1313
1314        rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RHSSIREAD_8822BE;
1315        rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RHSSIREAD_8822BE;
1316
1317        rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RA_SIREAD_8822B;
1318        rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RB_SIREAD_8822B;
1319
1320        rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = RA_PIREAD_8822B;
1321        rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = RB_PIREAD_8822B;
1322}
1323
1324void rtl8822be_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
1325{
1326        struct rtl_priv *rtlpriv = rtl_priv(hw);
1327        struct rtl_phy *rtlphy = &rtlpriv->phy;
1328        u8 txpwr_level;
1329        long txpwr_dbm;
1330
1331        txpwr_level = rtlphy->cur_cck_txpwridx;
1332        txpwr_dbm = _rtl8822be_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_B,
1333                                                    txpwr_level);
1334        txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
1335        if (_rtl8822be_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, txpwr_level) >
1336            txpwr_dbm)
1337                txpwr_dbm = _rtl8822be_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
1338                                                            txpwr_level);
1339        txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
1340        if (_rtl8822be_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
1341                                            txpwr_level) > txpwr_dbm)
1342                txpwr_dbm = _rtl8822be_phy_txpwr_idx_to_dbm(
1343                        hw, WIRELESS_MODE_N_24G, txpwr_level);
1344        *powerlevel = txpwr_dbm;
1345}
1346
1347static bool _rtl8822be_phy_get_chnl_index(u8 channel, u8 *chnl_index)
1348{
1349        u8 rtl_channel5g[CHANNEL_MAX_NUMBER_5G] = {
1350                36,  38,  40,  42,  44,  46,  48, /* Band 1 */
1351                52,  54,  56,  58,  60,  62,  64, /* Band 2 */
1352                100, 102, 104, 106, 108, 110, 112, /* Band 3 */
1353                116, 118, 120, 122, 124, 126, 128, /* Band 3 */
1354                132, 134, 136, 138, 140, 142, 144, /* Band 3 */
1355                149, 151, 153, 155, 157, 159, 161, /* Band 4 */
1356                165, 167, 169, 171, 173, 175, 177}; /* Band 4 */
1357        u8 i = 0;
1358        bool in_24g = true;
1359
1360        if (channel <= 14) {
1361                in_24g = true;
1362                *chnl_index = channel - 1;
1363        } else {
1364                in_24g = false;
1365
1366                for (i = 0; i < CHANNEL_MAX_NUMBER_5G; ++i) {
1367                        if (rtl_channel5g[i] == channel) {
1368                                *chnl_index = i;
1369                                return in_24g;
1370                        }
1371                }
1372        }
1373        return in_24g;
1374}
1375
1376static char _rtl8822be_phy_get_world_wide_limit(char *limit_table)
1377{
1378        char min = limit_table[0];
1379        u8 i = 0;
1380
1381        for (i = 0; i < MAX_REGULATION_NUM; ++i) {
1382                if (limit_table[i] < min)
1383                        min = limit_table[i];
1384        }
1385        return min;
1386}
1387
1388static char _rtl8822be_phy_get_txpower_limit(struct ieee80211_hw *hw, u8 band,
1389                                             enum ht_channel_width bandwidth,
1390                                             enum radio_path rf_path, u8 rate,
1391                                             u8 channel)
1392{
1393        struct rtl_priv *rtlpriv = rtl_priv(hw);
1394        struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
1395        struct rtl_phy *rtlphy = &rtlpriv->phy;
1396        short regulation = -1, rate_section = -1, channel_index = -1;
1397        char power_limit = MAX_POWER_INDEX;
1398
1399        if (rtlefuse->eeprom_regulatory == 2)
1400                return MAX_POWER_INDEX;
1401
1402        regulation = TXPWR_LMT_WW;
1403
1404        switch (rate) {
1405        case DESC_RATE1M:
1406        case DESC_RATE2M:
1407        case DESC_RATE5_5M:
1408        case DESC_RATE11M:
1409                rate_section = CCK;
1410                break;
1411
1412        case DESC_RATE6M:
1413        case DESC_RATE9M:
1414        case DESC_RATE12M:
1415        case DESC_RATE18M:
1416        case DESC_RATE24M:
1417        case DESC_RATE36M:
1418        case DESC_RATE48M:
1419        case DESC_RATE54M:
1420                rate_section = OFDM;
1421                break;
1422
1423        case DESC_RATEMCS0:
1424        case DESC_RATEMCS1:
1425        case DESC_RATEMCS2:
1426        case DESC_RATEMCS3:
1427        case DESC_RATEMCS4:
1428        case DESC_RATEMCS5:
1429        case DESC_RATEMCS6:
1430        case DESC_RATEMCS7:
1431                rate_section = HT_MCS0_MCS7;
1432                break;
1433
1434        case DESC_RATEMCS8:
1435        case DESC_RATEMCS9:
1436        case DESC_RATEMCS10:
1437        case DESC_RATEMCS11:
1438        case DESC_RATEMCS12:
1439        case DESC_RATEMCS13:
1440        case DESC_RATEMCS14:
1441        case DESC_RATEMCS15:
1442                rate_section = HT_MCS8_MCS15;
1443                break;
1444
1445        case DESC_RATEVHT1SS_MCS0:
1446        case DESC_RATEVHT1SS_MCS1:
1447        case DESC_RATEVHT1SS_MCS2:
1448        case DESC_RATEVHT1SS_MCS3:
1449        case DESC_RATEVHT1SS_MCS4:
1450        case DESC_RATEVHT1SS_MCS5:
1451        case DESC_RATEVHT1SS_MCS6:
1452        case DESC_RATEVHT1SS_MCS7:
1453        case DESC_RATEVHT1SS_MCS8:
1454        case DESC_RATEVHT1SS_MCS9:
1455                rate_section = VHT_1SSMCS0_1SSMCS9;
1456                break;
1457
1458        case DESC_RATEVHT2SS_MCS0:
1459        case DESC_RATEVHT2SS_MCS1:
1460        case DESC_RATEVHT2SS_MCS2:
1461        case DESC_RATEVHT2SS_MCS3:
1462        case DESC_RATEVHT2SS_MCS4:
1463        case DESC_RATEVHT2SS_MCS5:
1464        case DESC_RATEVHT2SS_MCS6:
1465        case DESC_RATEVHT2SS_MCS7:
1466        case DESC_RATEVHT2SS_MCS8:
1467        case DESC_RATEVHT2SS_MCS9:
1468                rate_section = VHT_2SSMCS0_2SSMCS9;
1469                break;
1470
1471        default:
1472                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Wrong rate 0x%x\n",
1473                         rate);
1474                break;
1475        }
1476
1477        if (band == BAND_ON_5G && rate_section == 0)
1478                RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
1479                         "Wrong rate 0x%x: No CCK in 5G Band\n", rate);
1480
1481        /* workaround for wrong index combination to obtain tx power limit,
1482         * OFDM only exists in BW 20M
1483         */
1484        if (rate_section == 1)
1485                bandwidth = 0;
1486
1487        /* workaround for wrong index combination to obtain tx power limit,
1488         * CCK table will only be given in BW 20M
1489         */
1490        if (rate_section == 0)
1491                bandwidth = 0;
1492
1493        /* workaround for wrong indxe combination to obtain tx power limit,
1494         * HT on 80M will reference to HT on 40M
1495         */
1496        if ((rate_section == 2 || rate_section == 3) && band == BAND_ON_5G &&
1497            bandwidth == 2)
1498                bandwidth = 1;
1499
1500        if (band == BAND_ON_2_4G)
1501                channel_index = _rtl8822be_phy_get_chnl_idx_of_txpwr_lmt(
1502                        hw, BAND_ON_2_4G, channel);
1503        else if (band == BAND_ON_5G)
1504                channel_index = _rtl8822be_phy_get_chnl_idx_of_txpwr_lmt(
1505                        hw, BAND_ON_5G, channel);
1506        else if (band == BAND_ON_BOTH)
1507                ; /* BAND_ON_BOTH don't care temporarily */
1508
1509        if (band >= BANDMAX || regulation == -1 || bandwidth == -1 ||
1510            rate_section == -1 || channel_index == -1) {
1511                RT_TRACE(
1512                        rtlpriv, COMP_POWER, DBG_LOUD,
1513                        "Wrong index value to access power limit table [band %d][regulation %d][bandwidth %d][rf_path %d][rate_section %d][chnl %d]\n",
1514                        band, regulation, bandwidth, rf_path, rate_section,
1515                        channel_index);
1516                return MAX_POWER_INDEX;
1517        }
1518
1519        if (band == BAND_ON_2_4G) {
1520                char limits[10] = {0};
1521                u8 i = 0;
1522
1523                for (i = 0; i < 4; ++i)
1524                        limits[i] = rtlphy->txpwr_limit_2_4g[i][bandwidth]
1525                                                            [rate_section]
1526                                                            [channel_index]
1527                                                            [rf_path];
1528
1529                power_limit =
1530                        (regulation == TXPWR_LMT_WW) ?
1531                                _rtl8822be_phy_get_world_wide_limit(limits) :
1532                                rtlphy->txpwr_limit_2_4g[regulation][bandwidth]
1533                                                        [rate_section]
1534                                                        [channel_index]
1535                                                        [rf_path];
1536
1537        } else if (band == BAND_ON_5G) {
1538                char limits[10] = {0};
1539                u8 i = 0;
1540
1541                for (i = 0; i < MAX_REGULATION_NUM; ++i)
1542                        limits[i] =
1543                                rtlphy->txpwr_limit_5g[i][bandwidth]
1544                                                      [rate_section]
1545                                                      [channel_index][rf_path];
1546
1547                power_limit =
1548                        (regulation == TXPWR_LMT_WW) ?
1549                                _rtl8822be_phy_get_world_wide_limit(limits) :
1550                                rtlphy->txpwr_limit_5g[regulation]
1551                                                      [channel_index]
1552                                                      [rate_section]
1553                                                      [channel_index][rf_path];
1554        } else {
1555                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1556                         "No power limit table of the specified band\n");
1557        }
1558
1559        return power_limit;
1560}
1561
1562static char
1563_rtl8822be_phy_get_txpower_by_rate(struct ieee80211_hw *hw, u8 band, u8 path,
1564                                   u8 rate /* enum rtl_desc8822b_rate */)
1565{
1566        struct rtl_priv *rtlpriv = rtl_priv(hw);
1567        struct rtl_phy *rtlphy = &rtlpriv->phy;
1568        u8 tx_num;
1569        char tx_pwr_diff = 0;
1570
1571        if (band != BAND_ON_2_4G && band != BAND_ON_5G)
1572                return tx_pwr_diff;
1573
1574        if (path > RF90_PATH_B)
1575                return tx_pwr_diff;
1576
1577        if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) ||
1578            (rate >= DESC_RATEVHT2SS_MCS0 && rate <= DESC_RATEVHT2SS_MCS9))
1579                tx_num = RF_2TX;
1580        else
1581                tx_num = RF_1TX;
1582
1583        tx_pwr_diff = (char)(rtlphy->tx_power_by_rate_offset[band][path][tx_num]
1584                                                            [rate] &
1585                             0xff);
1586
1587        return tx_pwr_diff;
1588}
1589
1590u8 rtl8822be_get_txpower_index(struct ieee80211_hw *hw, u8 path, u8 rate,
1591                               u8 bandwidth, u8 channel)
1592{
1593        struct rtl_priv *rtlpriv = rtl_priv(hw);
1594        struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1595        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1596        u8 index = (channel - 1);
1597        u8 txpower = 0;
1598        bool in_24g = false;
1599        char limit;
1600        char powerdiff_byrate = 0;
1601
1602        if ((rtlhal->current_bandtype == BAND_ON_2_4G &&
1603             (channel > 14 || channel < 1)) ||
1604            (rtlhal->current_bandtype == BAND_ON_5G && channel <= 14)) {
1605                index = 0;
1606                RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1607                         "Illegal channel!!\n");
1608        }
1609
1610        /* 1. base tx power */
1611        in_24g = _rtl8822be_phy_get_chnl_index(channel, &index);
1612        if (in_24g) {
1613                if (RX_HAL_IS_CCK_RATE(rate))
1614                        txpower = rtlefuse->txpwrlevel_cck[path][index];
1615                else if (rate >= DESC_RATE6M)
1616                        txpower = rtlefuse->txpwrlevel_ht40_1s[path][index];
1617                else
1618                        RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1619                                 "invalid rate\n");
1620
1621                if (rate >= DESC_RATE6M && rate <= DESC_RATE54M &&
1622                    !RX_HAL_IS_CCK_RATE(rate))
1623                        txpower += rtlefuse->txpwr_legacyhtdiff[path][TX_1S];
1624
1625                if (bandwidth == HT_CHANNEL_WIDTH_20) {
1626                        if ((rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS15) ||
1627                            (rate >= DESC_RATEVHT1SS_MCS0 &&
1628                             rate <= DESC_RATEVHT2SS_MCS9))
1629                                txpower +=
1630                                        rtlefuse->txpwr_ht20diff[path][TX_1S];
1631                        if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) ||
1632                            (rate >= DESC_RATEVHT2SS_MCS0 &&
1633                             rate <= DESC_RATEVHT2SS_MCS9))
1634                                txpower +=
1635                                        rtlefuse->txpwr_ht20diff[path][TX_2S];
1636                } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
1637                        if ((rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS15) ||
1638                            (rate >= DESC_RATEVHT1SS_MCS0 &&
1639                             rate <= DESC_RATEVHT2SS_MCS9))
1640                                txpower +=
1641                                        rtlefuse->txpwr_ht40diff[path][TX_1S];
1642                        if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) ||
1643                            (rate >= DESC_RATEVHT2SS_MCS0 &&
1644                             rate <= DESC_RATEVHT2SS_MCS9))
1645                                txpower +=
1646                                        rtlefuse->txpwr_ht40diff[path][TX_2S];
1647                } else if (bandwidth == HT_CHANNEL_WIDTH_80) {
1648                        if ((rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS15) ||
1649                            (rate >= DESC_RATEVHT1SS_MCS0 &&
1650                             rate <= DESC_RATEVHT2SS_MCS9))
1651                                txpower +=
1652                                        rtlefuse->txpwr_ht40diff[path][TX_1S];
1653                        if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) ||
1654                            (rate >= DESC_RATEVHT2SS_MCS0 &&
1655                             rate <= DESC_RATEVHT2SS_MCS9))
1656                                txpower +=
1657                                        rtlefuse->txpwr_ht40diff[path][TX_2S];
1658                }
1659
1660        } else {
1661                if (rate >= DESC_RATE6M)
1662                        txpower = rtlefuse->txpwr_5g_bw40base[path][index];
1663                else
1664                        RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_WARNING,
1665                                 "INVALID Rate.\n");
1666
1667                if (rate >= DESC_RATE6M && rate <= DESC_RATE54M &&
1668                    !RX_HAL_IS_CCK_RATE(rate))
1669                        txpower += rtlefuse->txpwr_5g_ofdmdiff[path][TX_1S];
1670
1671                if (bandwidth == HT_CHANNEL_WIDTH_20) {
1672                        if ((rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS15) ||
1673                            (rate >= DESC_RATEVHT1SS_MCS0 &&
1674                             rate <= DESC_RATEVHT2SS_MCS9))
1675                                txpower += rtlefuse->txpwr_5g_bw20diff[path]
1676                                                                      [TX_1S];
1677                        if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) ||
1678                            (rate >= DESC_RATEVHT2SS_MCS0 &&
1679                             rate <= DESC_RATEVHT2SS_MCS9))
1680                                txpower += rtlefuse->txpwr_5g_bw20diff[path]
1681                                                                      [TX_2S];
1682                } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
1683                        if ((rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS15) ||
1684                            (rate >= DESC_RATEVHT1SS_MCS0 &&
1685                             rate <= DESC_RATEVHT2SS_MCS9))
1686                                txpower += rtlefuse->txpwr_5g_bw40diff[path]
1687                                                                      [TX_1S];
1688                        if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) ||
1689                            (rate >= DESC_RATEVHT2SS_MCS0 &&
1690                             rate <= DESC_RATEVHT2SS_MCS9))
1691                                txpower += rtlefuse->txpwr_5g_bw40diff[path]
1692                                                                      [TX_2S];
1693                } else if (bandwidth == HT_CHANNEL_WIDTH_80) {
1694                        u8 i = 0;
1695
1696                        for (i = 0; i < sizeof(rtl_channel5g_80m) / sizeof(u8);
1697                             ++i)
1698                                if (rtl_channel5g_80m[i] == channel)
1699                                        index = i;
1700
1701                        txpower = rtlefuse->txpwr_5g_bw80base[path][index];
1702
1703                        if ((rate >= DESC_RATEMCS0 && rate <= DESC_RATEMCS15) ||
1704                            (rate >= DESC_RATEVHT1SS_MCS0 &&
1705                             rate <= DESC_RATEVHT2SS_MCS9))
1706                                txpower += rtlefuse->txpwr_5g_bw80diff[path]
1707                                                                      [TX_1S];
1708                        if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) ||
1709                            (rate >= DESC_RATEVHT2SS_MCS0 &&
1710                             rate <= DESC_RATEVHT2SS_MCS9))
1711                                txpower += rtlefuse->txpwr_5g_bw80diff[path]
1712                                                                      [TX_2S];
1713                }
1714        }
1715
1716        /* 2. tx power by rate */
1717        if (rtlefuse->eeprom_regulatory != 2)
1718                powerdiff_byrate = _rtl8822be_phy_get_txpower_by_rate(
1719                        hw, (u8)(!in_24g), path, rate);
1720
1721        /* 3. tx power limit */
1722        if (rtlefuse->eeprom_regulatory == 1)
1723                limit = _rtl8822be_phy_get_txpower_limit(
1724                        hw, (u8)(!in_24g), bandwidth, path, rate,
1725                        channel);
1726        else
1727                limit = MAX_POWER_INDEX;
1728
1729        /* ----- */
1730        powerdiff_byrate = powerdiff_byrate > limit ? limit : powerdiff_byrate;
1731
1732        txpower += powerdiff_byrate;
1733
1734        if (txpower > MAX_POWER_INDEX)
1735                txpower = MAX_POWER_INDEX;
1736
1737        return txpower;
1738}
1739
1740static void _rtl8822be_phy_set_txpower_index(struct ieee80211_hw *hw,
1741                                             u8 power_index, u8 path, u8 rate)
1742{
1743        struct rtl_priv *rtlpriv = rtl_priv(hw);
1744        u8 shift = 0;
1745        static u32 index;
1746
1747        /*
1748         * For 8822B, phydm api use 4 bytes txagc value driver must
1749         * combine every four 1 byte to one 4 byte and send to phydm
1750         */
1751        shift = rate & 0x03;
1752        index |= ((u32)power_index << (shift * 8));
1753
1754        if (shift == 3) {
1755                rate = rate - 3;
1756
1757                if (!rtlpriv->phydm.ops->phydm_write_txagc(rtlpriv, index, path,
1758                                                           rate)) {
1759                        RT_TRACE(rtlpriv, COMP_TXAGC, DBG_LOUD,
1760                                 "%s(index:%d, rfpath:%d, rate:0x%02x) fail\n",
1761                                 __func__, index, path, rate);
1762
1763                        WARN_ON(1);
1764                }
1765                index = 0;
1766        }
1767}
1768
1769static void _rtl8822be_phy_set_txpower_level_by_path(struct ieee80211_hw *hw,
1770                                                     u8 *array, u8 path,
1771                                                     u8 channel, u8 size)
1772{
1773        struct rtl_phy *rtlphy = &(rtl_priv(hw)->phy);
1774        u8 i;
1775        u8 power_index;
1776
1777        for (i = 0; i < size; i++) {
1778                power_index = rtl8822be_get_txpower_index(
1779                        hw, path, array[i], rtlphy->current_chan_bw, channel);
1780                _rtl8822be_phy_set_txpower_index(hw, power_index, path,
1781                                                 array[i]);
1782        }
1783}
1784
1785void rtl8822be_phy_set_txpower_level_by_path(struct ieee80211_hw *hw,
1786                                             u8 channel, u8 path)
1787{
1788        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1789
1790        /*
1791         * Below order is *VERY* important!
1792         * Because _rtl8822be_phy_set_txpower_index() do actually writing
1793         * every four power values.
1794         */
1795        if (rtlhal->current_bandtype == BAND_ON_2_4G)
1796                _rtl8822be_phy_set_txpower_level_by_path(
1797                        hw, cck_rates, path, channel, sizes_of_cck_retes);
1798        _rtl8822be_phy_set_txpower_level_by_path(hw, ofdm_rates, path, channel,
1799                                                 sizes_of_ofdm_retes);
1800        _rtl8822be_phy_set_txpower_level_by_path(hw, ht_rates_1t, path, channel,
1801                                                 sizes_of_ht_retes_1t);
1802        _rtl8822be_phy_set_txpower_level_by_path(hw, ht_rates_2t, path, channel,
1803                                                 sizes_of_ht_retes_2t);
1804        _rtl8822be_phy_set_txpower_level_by_path(hw, vht_rates_1t, path,
1805                                                 channel, sizes_of_vht_retes);
1806        _rtl8822be_phy_set_txpower_level_by_path(hw, vht_rates_2t, path,
1807                                                 channel, sizes_of_vht_retes);
1808}
1809
1810void rtl8822be_phy_set_tx_power_index_by_rs(struct ieee80211_hw *hw, u8 channel,
1811                                            u8 path, enum rate_section rs)
1812{
1813        struct {
1814                u8 *array;
1815                u8 size;
1816        } rs_ref[MAX_RATE_SECTION] = {
1817                {cck_rates, sizes_of_cck_retes},
1818                {ofdm_rates, sizes_of_ofdm_retes},
1819                {ht_rates_1t, sizes_of_ht_retes_1t},
1820                {ht_rates_2t, sizes_of_ht_retes_2t},
1821                {vht_rates_1t, sizes_of_vht_retes},
1822                {vht_rates_2t, sizes_of_vht_retes},
1823        };
1824
1825        if (rs >= MAX_RATE_SECTION)
1826                return;
1827
1828        _rtl8822be_phy_set_txpower_level_by_path(hw, rs_ref[rs].array, path,
1829                                                 channel, rs_ref[rs].size);
1830}
1831
1832void rtl8822be_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
1833{
1834        struct rtl_priv *rtlpriv = rtl_priv(hw);
1835        struct rtl_phy *rtlphy = &rtlpriv->phy;
1836        u8 path = 0;
1837
1838        for (path = RF90_PATH_A; path < rtlphy->num_total_rfpath; ++path)
1839                rtl8822be_phy_set_txpower_level_by_path(hw, channel, path);
1840}
1841
1842static long _rtl8822be_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
1843                                            enum wireless_mode wirelessmode,
1844                                            u8 txpwridx)
1845{
1846        long offset;
1847        long pwrout_dbm;
1848
1849        switch (wirelessmode) {
1850        case WIRELESS_MODE_B:
1851                offset = -7;
1852                break;
1853        case WIRELESS_MODE_G:
1854        case WIRELESS_MODE_N_24G:
1855                offset = -8;
1856                break;
1857        default:
1858                offset = -8;
1859                break;
1860        }
1861        pwrout_dbm = txpwridx / 2 + offset;
1862        return pwrout_dbm;
1863}
1864
1865void rtl8822be_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
1866{
1867        struct rtl_priv *rtlpriv = rtl_priv(hw);
1868        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1869        enum io_type iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
1870
1871        if (!is_hal_stop(rtlhal)) {
1872                switch (operation) {
1873                case SCAN_OPT_BACKUP_BAND0:
1874                        iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
1875                        rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1876                                                      (u8 *)&iotype);
1877
1878                        break;
1879                case SCAN_OPT_BACKUP_BAND1:
1880                        iotype = IO_CMD_PAUSE_BAND1_DM_BY_SCAN;
1881                        rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1882                                                      (u8 *)&iotype);
1883
1884                        break;
1885                case SCAN_OPT_RESTORE:
1886                        iotype = IO_CMD_RESUME_DM_BY_SCAN;
1887                        rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1888                                                      (u8 *)&iotype);
1889                        break;
1890                default:
1891                        pr_err("Unknown Scan Backup operation.\n");
1892                        break;
1893                }
1894        }
1895}
1896
1897static u8 _rtl8822be_phy_get_pri_ch_id(struct rtl_priv *rtlpriv)
1898{
1899        struct rtl_phy *rtlphy = &rtlpriv->phy;
1900        struct rtl_mac *mac = rtl_mac(rtlpriv);
1901        u8 pri_ch_idx = 0;
1902
1903        if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80) {
1904                /* primary channel is at lower subband of 80MHz & 40MHz */
1905                if (mac->cur_40_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER &&
1906                    mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER) {
1907                        pri_ch_idx = VHT_DATA_SC_20_LOWEST_OF_80MHZ;
1908                /* primary channel is at
1909                 * lower subband of 80MHz & upper subband of 40MHz
1910                 */
1911                } else if ((mac->cur_40_prime_sc ==
1912                            HAL_PRIME_CHNL_OFFSET_UPPER) &&
1913                           (mac->cur_80_prime_sc ==
1914                            HAL_PRIME_CHNL_OFFSET_LOWER)) {
1915                        pri_ch_idx = VHT_DATA_SC_20_LOWER_OF_80MHZ;
1916                /* primary channel is at
1917                 * upper subband of 80MHz & lower subband of 40MHz
1918                 */
1919                } else if ((mac->cur_40_prime_sc ==
1920                          HAL_PRIME_CHNL_OFFSET_LOWER) &&
1921                         (mac->cur_80_prime_sc ==
1922                          HAL_PRIME_CHNL_OFFSET_UPPER)) {
1923                        pri_ch_idx = VHT_DATA_SC_20_UPPER_OF_80MHZ;
1924                /* primary channel is at
1925                 * upper subband of 80MHz & upper subband of 40MHz
1926                 */
1927                } else if ((mac->cur_40_prime_sc ==
1928                            HAL_PRIME_CHNL_OFFSET_UPPER) &&
1929                           (mac->cur_80_prime_sc ==
1930                            HAL_PRIME_CHNL_OFFSET_UPPER)) {
1931                        pri_ch_idx = VHT_DATA_SC_20_UPPERST_OF_80MHZ;
1932                } else {
1933                        if (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER)
1934                                pri_ch_idx = VHT_DATA_SC_40_LOWER_OF_80MHZ;
1935                        else if (mac->cur_80_prime_sc ==
1936                                 HAL_PRIME_CHNL_OFFSET_UPPER)
1937                                pri_ch_idx = VHT_DATA_SC_40_UPPER_OF_80MHZ;
1938                }
1939        } else if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
1940                /* primary channel is at upper subband of 40MHz */
1941                if (mac->cur_40_prime_sc == HAL_PRIME_CHNL_OFFSET_UPPER)
1942                        pri_ch_idx = VHT_DATA_SC_20_UPPER_OF_80MHZ;
1943                /* primary channel is at lower subband of 40MHz */
1944                else if (mac->cur_40_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER)
1945                        pri_ch_idx = VHT_DATA_SC_20_LOWER_OF_80MHZ;
1946                else
1947                        ;
1948        }
1949
1950        return pri_ch_idx;
1951}
1952
1953void rtl8822be_phy_set_bw_mode(struct ieee80211_hw *hw,
1954                               enum nl80211_channel_type ch_type)
1955{
1956        struct rtl_priv *rtlpriv = rtl_priv(hw);
1957        struct rtl_phy *rtlphy = &rtlpriv->phy;
1958        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1959        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1960        u8 tmp_bw = rtlphy->current_chan_bw;
1961
1962        if (rtlphy->set_bwmode_inprogress)
1963                return;
1964        rtlphy->set_bwmode_inprogress = true;
1965        if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1966                /* get primary channel index */
1967                u8 pri_ch_idx = _rtl8822be_phy_get_pri_ch_id(rtlpriv);
1968
1969                /* 3.1 set MAC register */
1970                rtlpriv->halmac.ops->halmac_set_bandwidth(
1971                        rtlpriv, rtlphy->current_channel, pri_ch_idx,
1972                        rtlphy->current_chan_bw);
1973
1974                /* 3.2 set BB/RF registet */
1975                rtlpriv->phydm.ops->phydm_switch_bandwidth(
1976                        rtlpriv, pri_ch_idx, rtlphy->current_chan_bw);
1977
1978                if (!mac->act_scanning)
1979                        rtlpriv->phydm.ops->phydm_iq_calibrate(rtlpriv);
1980
1981                rtlphy->set_bwmode_inprogress = false;
1982        } else {
1983                RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1984                         "FALSE driver sleep or unload\n");
1985                rtlphy->set_bwmode_inprogress = false;
1986                rtlphy->current_chan_bw = tmp_bw;
1987        }
1988}
1989
1990u8 rtl8822be_phy_sw_chnl(struct ieee80211_hw *hw)
1991{
1992        struct rtl_priv *rtlpriv = rtl_priv(hw);
1993        struct rtl_phy *rtlphy = &rtlpriv->phy;
1994        struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1995        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1996        u32 timeout = 1000, timecount = 0;
1997        u8 channel = rtlphy->current_channel;
1998
1999        if (rtlphy->sw_chnl_inprogress)
2000                return 0;
2001        if (rtlphy->set_bwmode_inprogress)
2002                return 0;
2003
2004        if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) {
2005                RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
2006                         "sw_chnl_inprogress false driver sleep or unload\n");
2007                return 0;
2008        }
2009        while (rtlphy->lck_inprogress && timecount < timeout) {
2010                mdelay(50);
2011                timecount += 50;
2012        }
2013
2014        if (rtlphy->current_channel > 14)
2015                rtlhal->current_bandtype = BAND_ON_5G;
2016        else if (rtlphy->current_channel <= 14)
2017                rtlhal->current_bandtype = BAND_ON_2_4G;
2018
2019        if (rtlpriv->cfg->ops->get_btc_status())
2020                rtlpriv->btcoexist.btc_ops->btc_switch_band_notify(
2021                        rtlpriv, rtlhal->current_bandtype, mac->act_scanning);
2022        else
2023                rtlpriv->btcoexist.btc_ops->btc_switch_band_notify_wifi_only(
2024                        rtlpriv, rtlhal->current_bandtype, mac->act_scanning);
2025
2026        rtlpriv->phydm.ops->phydm_switch_band(rtlpriv, rtlphy->current_channel);
2027
2028        rtlphy->sw_chnl_inprogress = true;
2029        if (channel == 0)
2030                channel = 1;
2031
2032        RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
2033                 "switch to channel%d, band type is %d\n",
2034                 rtlphy->current_channel, rtlhal->current_bandtype);
2035
2036        rtlpriv->phydm.ops->phydm_switch_channel(rtlpriv,
2037                                                 rtlphy->current_channel);
2038
2039        rtlpriv->phydm.ops->phydm_clear_txpowertracking_state(rtlpriv);
2040
2041        rtl8822be_phy_set_txpower_level(hw, rtlphy->current_channel);
2042
2043        RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
2044        rtlphy->sw_chnl_inprogress = false;
2045        return 1;
2046}
2047
2048bool rtl8822be_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
2049{
2050        struct rtl_priv *rtlpriv = rtl_priv(hw);
2051        struct rtl_phy *rtlphy = &rtlpriv->phy;
2052        bool postprocessing = false;
2053
2054        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2055                 "-->IO Cmd(%#x), set_io_inprogress(%d)\n", iotype,
2056                 rtlphy->set_io_inprogress);
2057        do {
2058                switch (iotype) {
2059                case IO_CMD_RESUME_DM_BY_SCAN:
2060                        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2061                                 "[IO CMD] Resume DM after scan.\n");
2062                        postprocessing = true;
2063                        break;
2064                case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
2065                case IO_CMD_PAUSE_BAND1_DM_BY_SCAN:
2066                        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2067                                 "[IO CMD] Pause DM before scan.\n");
2068                        postprocessing = true;
2069                        break;
2070                default:
2071                        pr_err("switch case not process\n");
2072                        break;
2073                }
2074        } while (false);
2075        if (postprocessing && !rtlphy->set_io_inprogress) {
2076                rtlphy->set_io_inprogress = true;
2077                rtlphy->current_io_type = iotype;
2078        } else {
2079                return false;
2080        }
2081        rtl8822be_phy_set_io(hw);
2082        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype);
2083        return true;
2084}
2085
2086static void rtl8822be_phy_set_io(struct ieee80211_hw *hw)
2087{
2088        struct rtl_priv *rtlpriv = rtl_priv(hw);
2089        struct rtl_phy *rtlphy = &rtlpriv->phy;
2090
2091        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2092                 "--->Cmd(%#x), set_io_inprogress(%d)\n",
2093                 rtlphy->current_io_type, rtlphy->set_io_inprogress);
2094        switch (rtlphy->current_io_type) {
2095        case IO_CMD_RESUME_DM_BY_SCAN:
2096                break;
2097        case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
2098                break;
2099        case IO_CMD_PAUSE_BAND1_DM_BY_SCAN:
2100                break;
2101        default:
2102                pr_err("switch case not process\n");
2103                break;
2104        }
2105        rtlphy->set_io_inprogress = false;
2106        RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "(%#x)\n",
2107                 rtlphy->current_io_type);
2108}
2109
2110static void rtl8822be_phy_set_rf_on(struct ieee80211_hw *hw)
2111{
2112        struct rtl_priv *rtlpriv = rtl_priv(hw);
2113
2114        rtl_write_byte(rtlpriv, REG_SPS0_CTRL_8822B, 0x2b);
2115        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN_8822B, 0xE3);
2116        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN_8822B, 0xE2);
2117        rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN_8822B, 0xE3);
2118        rtl_write_byte(rtlpriv, REG_TXPAUSE_8822B, 0x00);
2119}
2120
2121static bool _rtl8822be_phy_set_rf_power_state(struct ieee80211_hw *hw,
2122                                              enum rf_pwrstate rfpwr_state)
2123{
2124        struct rtl_priv *rtlpriv = rtl_priv(hw);
2125        struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
2126        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2127        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2128        bool bresult = true;
2129        u8 i, queue_id;
2130        struct rtl8192_tx_ring *ring = NULL;
2131
2132        switch (rfpwr_state) {
2133        case ERFON:
2134                if (ppsc->rfpwr_state == ERFOFF &&
2135                    RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
2136                        bool rtstatus = false;
2137                        u32 initialize_count = 0;
2138
2139                        do {
2140                                initialize_count++;
2141                                RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2142                                         "IPS Set eRf nic enable\n");
2143                                rtstatus = rtl_ps_enable_nic(hw);
2144                        } while ((!rtstatus) && (initialize_count < 10));
2145                        RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2146                } else {
2147                        RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2148                                 "Set ERFON slept:%d ms\n",
2149                                 jiffies_to_msecs(jiffies -
2150                                                  ppsc->last_sleep_jiffies));
2151                        ppsc->last_awake_jiffies = jiffies;
2152                        rtl8822be_phy_set_rf_on(hw);
2153                }
2154                if (mac->link_state == MAC80211_LINKED)
2155                        rtlpriv->cfg->ops->led_control(hw, LED_CTL_LINK);
2156                else
2157                        rtlpriv->cfg->ops->led_control(hw, LED_CTL_NO_LINK);
2158                break;
2159        case ERFOFF:
2160                for (queue_id = 0, i = 0;
2161                     queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
2162                        ring = &pcipriv->dev.tx_ring[queue_id];
2163                        if (queue_id == BEACON_QUEUE ||
2164                            skb_queue_len(&ring->queue) == 0) {
2165                                queue_id++;
2166                                continue;
2167                        } else {
2168                                RT_TRACE(
2169                                        rtlpriv, COMP_ERR, DBG_WARNING,
2170                                        "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
2171                                        (i + 1), queue_id,
2172                                        skb_queue_len(&ring->queue));
2173
2174                                udelay(10);
2175                                i++;
2176                        }
2177                        if (i >= MAX_DOZE_WAITING_TIMES_9x) {
2178                                RT_TRACE(
2179                                        rtlpriv, COMP_ERR, DBG_WARNING,
2180                                        "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
2181                                        MAX_DOZE_WAITING_TIMES_9x, queue_id,
2182                                        skb_queue_len(&ring->queue));
2183                                break;
2184                        }
2185                }
2186
2187                if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
2188                        RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2189                                 "IPS Set eRf nic disable\n");
2190                        rtl_ps_disable_nic(hw);
2191                        RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2192                } else {
2193                        if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
2194                                rtlpriv->cfg->ops->led_control(hw,
2195                                                               LED_CTL_NO_LINK);
2196                        } else {
2197                                rtlpriv->cfg->ops->led_control(
2198                                        hw, LED_CTL_POWER_OFF);
2199                        }
2200                }
2201                break;
2202        default:
2203                pr_err("switch case not process\n");
2204                bresult = false;
2205                break;
2206        }
2207        if (bresult)
2208                ppsc->rfpwr_state = rfpwr_state;
2209        return bresult;
2210}
2211
2212bool rtl8822be_phy_set_rf_power_state(struct ieee80211_hw *hw,
2213                                      enum rf_pwrstate rfpwr_state)
2214{
2215        struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2216
2217        bool bresult = false;
2218
2219        if (rfpwr_state == ppsc->rfpwr_state)
2220                return bresult;
2221        bresult = _rtl8822be_phy_set_rf_power_state(hw, rfpwr_state);
2222        return bresult;
2223}
2224