linux/drivers/net/wireless/realtek/rtlwifi/rtl8192de/rf.c
<<
>>
Prefs
   1/******************************************************************************
   2 *
   3 * Copyright(c) 2009-2012  Realtek Corporation.
   4 *
   5 * This program is free software; you can redistribute it and/or modify it
   6 * under the terms of version 2 of the GNU General Public License as
   7 * published by the Free Software Foundation.
   8 *
   9 * This program is distributed in the hope that it will be useful, but WITHOUT
  10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  12 * more details.
  13 *
  14 * The full GNU General Public License is included in this distribution in the
  15 * file called LICENSE.
  16 *
  17 * Contact Information:
  18 * wlanfae <wlanfae@realtek.com>
  19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
  20 * Hsinchu 300, Taiwan.
  21 *
  22 * Larry Finger <Larry.Finger@lwfinger.net>
  23 *
  24 *****************************************************************************/
  25
  26#include "../wifi.h"
  27#include "reg.h"
  28#include "def.h"
  29#include "phy.h"
  30#include "rf.h"
  31#include "dm.h"
  32#include "hw.h"
  33
  34void rtl92d_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth)
  35{
  36        struct rtl_priv *rtlpriv = rtl_priv(hw);
  37        struct rtl_phy *rtlphy = &(rtlpriv->phy);
  38        u8 rfpath;
  39
  40        switch (bandwidth) {
  41        case HT_CHANNEL_WIDTH_20:
  42                for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) {
  43                        rtlphy->rfreg_chnlval[rfpath] = ((rtlphy->rfreg_chnlval
  44                                        [rfpath] & 0xfffff3ff) | 0x0400);
  45                        rtl_set_rfreg(hw, rfpath, RF_CHNLBW, BIT(10) |
  46                                      BIT(11), 0x01);
  47
  48                        RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
  49                                 "20M RF 0x18 = 0x%x\n",
  50                                 rtlphy->rfreg_chnlval[rfpath]);
  51                }
  52
  53                break;
  54        case HT_CHANNEL_WIDTH_20_40:
  55                for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) {
  56                        rtlphy->rfreg_chnlval[rfpath] =
  57                            ((rtlphy->rfreg_chnlval[rfpath] & 0xfffff3ff));
  58                        rtl_set_rfreg(hw, rfpath, RF_CHNLBW, BIT(10) | BIT(11),
  59                                      0x00);
  60                        RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
  61                                 "40M RF 0x18 = 0x%x\n",
  62                                 rtlphy->rfreg_chnlval[rfpath]);
  63                }
  64                break;
  65        default:
  66                pr_err("unknown bandwidth: %#X\n", bandwidth);
  67                break;
  68        }
  69}
  70
  71void rtl92d_phy_rf6052_set_cck_txpower(struct ieee80211_hw *hw,
  72                                       u8 *ppowerlevel)
  73{
  74        struct rtl_priv *rtlpriv = rtl_priv(hw);
  75        struct rtl_phy *rtlphy = &(rtlpriv->phy);
  76        struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
  77        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
  78        u32 tx_agc[2] = {0, 0}, tmpval;
  79        bool turbo_scanoff = false;
  80        u8 idx1, idx2;
  81        u8 *ptr;
  82
  83        if (rtlefuse->eeprom_regulatory != 0)
  84                turbo_scanoff = true;
  85        if (mac->act_scanning) {
  86                tx_agc[RF90_PATH_A] = 0x3f3f3f3f;
  87                tx_agc[RF90_PATH_B] = 0x3f3f3f3f;
  88                if (turbo_scanoff) {
  89                        for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
  90                                tx_agc[idx1] = ppowerlevel[idx1] |
  91                                    (ppowerlevel[idx1] << 8) |
  92                                    (ppowerlevel[idx1] << 16) |
  93                                    (ppowerlevel[idx1] << 24);
  94                        }
  95                }
  96        } else {
  97                for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
  98                        tx_agc[idx1] = ppowerlevel[idx1] |
  99                            (ppowerlevel[idx1] << 8) |
 100                            (ppowerlevel[idx1] << 16) |
 101                            (ppowerlevel[idx1] << 24);
 102                }
 103                if (rtlefuse->eeprom_regulatory == 0) {
 104                        tmpval = (rtlphy->mcs_offset[0][6]) +
 105                            (rtlphy->mcs_offset[0][7] << 8);
 106                        tx_agc[RF90_PATH_A] += tmpval;
 107                        tmpval = (rtlphy->mcs_offset[0][14]) +
 108                            (rtlphy->mcs_offset[0][15] << 24);
 109                        tx_agc[RF90_PATH_B] += tmpval;
 110                }
 111        }
 112
 113        for (idx1 = RF90_PATH_A; idx1 <= RF90_PATH_B; idx1++) {
 114                ptr = (u8 *) (&(tx_agc[idx1]));
 115                for (idx2 = 0; idx2 < 4; idx2++) {
 116                        if (*ptr > RF6052_MAX_TX_PWR)
 117                                *ptr = RF6052_MAX_TX_PWR;
 118                        ptr++;
 119                }
 120        }
 121
 122        tmpval = tx_agc[RF90_PATH_A] & 0xff;
 123        rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, tmpval);
 124        RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
 125                "CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n",
 126                tmpval, RTXAGC_A_CCK1_MCS32);
 127        tmpval = tx_agc[RF90_PATH_A] >> 8;
 128        rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, 0xffffff00, tmpval);
 129        RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
 130                "CCK PWR 2~11M (rf-A) = 0x%x (reg 0x%x)\n",
 131                tmpval, RTXAGC_B_CCK11_A_CCK2_11);
 132        tmpval = tx_agc[RF90_PATH_B] >> 24;
 133        rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, tmpval);
 134        RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
 135                "CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n",
 136                tmpval, RTXAGC_B_CCK11_A_CCK2_11);
 137        tmpval = tx_agc[RF90_PATH_B] & 0x00ffffff;
 138        rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, 0xffffff00, tmpval);
 139        RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
 140                "CCK PWR 1~5.5M (rf-B) = 0x%x (reg 0x%x)\n",
 141                tmpval, RTXAGC_B_CCK1_55_MCS32);
 142}
 143
 144static void _rtl92d_phy_get_power_base(struct ieee80211_hw *hw,
 145                                       u8 *ppowerlevel, u8 channel,
 146                                       u32 *ofdmbase, u32 *mcsbase)
 147{
 148        struct rtl_priv *rtlpriv = rtl_priv(hw);
 149        struct rtl_phy *rtlphy = &(rtlpriv->phy);
 150        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 151        u32 powerbase0, powerbase1;
 152        u8 legacy_pwrdiff, ht20_pwrdiff;
 153        u8 i, powerlevel[2];
 154
 155        for (i = 0; i < 2; i++) {
 156                powerlevel[i] = ppowerlevel[i];
 157                legacy_pwrdiff = rtlefuse->txpwr_legacyhtdiff[i][channel - 1];
 158                powerbase0 = powerlevel[i] + legacy_pwrdiff;
 159                powerbase0 = (powerbase0 << 24) | (powerbase0 << 16) |
 160                    (powerbase0 << 8) | powerbase0;
 161                *(ofdmbase + i) = powerbase0;
 162                RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
 163                        " [OFDM power base index rf(%c) = 0x%x]\n",
 164                        i == 0 ? 'A' : 'B', *(ofdmbase + i));
 165        }
 166
 167        for (i = 0; i < 2; i++) {
 168                if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) {
 169                        ht20_pwrdiff = rtlefuse->txpwr_ht20diff[i][channel - 1];
 170                        powerlevel[i] += ht20_pwrdiff;
 171                }
 172                powerbase1 = powerlevel[i];
 173                powerbase1 = (powerbase1 << 24) | (powerbase1 << 16) |
 174                             (powerbase1 << 8) | powerbase1;
 175                *(mcsbase + i) = powerbase1;
 176                RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
 177                        " [MCS power base index rf(%c) = 0x%x]\n",
 178                        i == 0 ? 'A' : 'B', *(mcsbase + i));
 179        }
 180}
 181
 182static u8 _rtl92d_phy_get_chnlgroup_bypg(u8 chnlindex)
 183{
 184        u8 group;
 185        u8 channel_info[59] = {
 186                1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
 187                36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58,
 188                60, 62, 64, 100, 102, 104, 106, 108, 110, 112,
 189                114, 116, 118, 120, 122, 124, 126, 128, 130, 132,
 190                134, 136, 138, 140, 149, 151, 153, 155, 157, 159,
 191                161, 163, 165
 192        };
 193
 194        if (channel_info[chnlindex] <= 3)       /* Chanel 1-3 */
 195                group = 0;
 196        else if (channel_info[chnlindex] <= 9)  /* Channel 4-9 */
 197                group = 1;
 198        else if (channel_info[chnlindex] <= 14) /* Channel 10-14 */
 199                group = 2;
 200        else if (channel_info[chnlindex] <= 64)
 201                group = 6;
 202        else if (channel_info[chnlindex] <= 140)
 203                group = 7;
 204        else
 205                group = 8;
 206        return group;
 207}
 208
 209static void _rtl92d_get_txpower_writeval_by_regulatory(struct ieee80211_hw *hw,
 210                                                       u8 channel, u8 index,
 211                                                       u32 *powerbase0,
 212                                                       u32 *powerbase1,
 213                                                       u32 *p_outwriteval)
 214{
 215        struct rtl_priv *rtlpriv = rtl_priv(hw);
 216        struct rtl_phy *rtlphy = &(rtlpriv->phy);
 217        struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 218        u8 i, chnlgroup = 0, pwr_diff_limit[4];
 219        u32 writeval = 0, customer_limit, rf;
 220
 221        for (rf = 0; rf < 2; rf++) {
 222                switch (rtlefuse->eeprom_regulatory) {
 223                case 0:
 224                        chnlgroup = 0;
 225                        writeval = rtlphy->mcs_offset
 226                                        [chnlgroup][index +
 227                                        (rf ? 8 : 0)] + ((index < 2) ?
 228                                        powerbase0[rf] :
 229                                        powerbase1[rf]);
 230                        RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
 231                                "RTK better performance, writeval(%c) = 0x%x\n",
 232                                rf == 0 ? 'A' : 'B', writeval);
 233                        break;
 234                case 1:
 235                        if (rtlphy->pwrgroup_cnt == 1)
 236                                chnlgroup = 0;
 237                        if (rtlphy->pwrgroup_cnt >= MAX_PG_GROUP) {
 238                                chnlgroup = _rtl92d_phy_get_chnlgroup_bypg(
 239                                                                channel - 1);
 240                                if (rtlphy->current_chan_bw ==
 241                                    HT_CHANNEL_WIDTH_20)
 242                                        chnlgroup++;
 243                                else
 244                                        chnlgroup += 4;
 245                                writeval = rtlphy->mcs_offset
 246                                                [chnlgroup][index +
 247                                                (rf ? 8 : 0)] + ((index < 2) ?
 248                                                powerbase0[rf] :
 249                                                powerbase1[rf]);
 250                                RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
 251                                        "Realtek regulatory, 20MHz, writeval(%c) = 0x%x\n",
 252                                        rf == 0 ? 'A' : 'B', writeval);
 253                        }
 254                        break;
 255                case 2:
 256                        writeval = ((index < 2) ? powerbase0[rf] :
 257                                   powerbase1[rf]);
 258                        RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
 259                                "Better regulatory, writeval(%c) = 0x%x\n",
 260                                rf == 0 ? 'A' : 'B', writeval);
 261                        break;
 262                case 3:
 263                        chnlgroup = 0;
 264                        if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
 265                                RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
 266                                        "customer's limit, 40MHz rf(%c) = 0x%x\n",
 267                                        rf == 0 ? 'A' : 'B',
 268                                        rtlefuse->pwrgroup_ht40[rf]
 269                                        [channel - 1]);
 270                        } else {
 271                                RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
 272                                        "customer's limit, 20MHz rf(%c) = 0x%x\n",
 273                                        rf == 0 ? 'A' : 'B',
 274                                        rtlefuse->pwrgroup_ht20[rf]
 275                                        [channel - 1]);
 276                        }
 277                        for (i = 0; i < 4; i++) {
 278                                pwr_diff_limit[i] = (u8)((rtlphy->mcs_offset
 279                                        [chnlgroup][index + (rf ? 8 : 0)] &
 280                                        (0x7f << (i * 8))) >> (i * 8));
 281                                if (rtlphy->current_chan_bw ==
 282                                    HT_CHANNEL_WIDTH_20_40) {
 283                                        if (pwr_diff_limit[i] >
 284                                            rtlefuse->pwrgroup_ht40[rf]
 285                                           [channel - 1])
 286                                                pwr_diff_limit[i] =
 287                                                        rtlefuse->pwrgroup_ht40
 288                                                        [rf][channel - 1];
 289                                } else {
 290                                        if (pwr_diff_limit[i] >
 291                                            rtlefuse->pwrgroup_ht20[rf][
 292                                                channel - 1])
 293                                                pwr_diff_limit[i] =
 294                                                   rtlefuse->pwrgroup_ht20[rf]
 295                                                   [channel - 1];
 296                                }
 297                        }
 298                        customer_limit = (pwr_diff_limit[3] << 24) |
 299                                         (pwr_diff_limit[2] << 16) |
 300                                         (pwr_diff_limit[1] << 8) |
 301                                         (pwr_diff_limit[0]);
 302                        RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
 303                                "Customer's limit rf(%c) = 0x%x\n",
 304                                rf == 0 ? 'A' : 'B', customer_limit);
 305                        writeval = customer_limit + ((index < 2) ?
 306                                   powerbase0[rf] : powerbase1[rf]);
 307                        RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
 308                                "Customer, writeval rf(%c)= 0x%x\n",
 309                                rf == 0 ? 'A' : 'B', writeval);
 310                        break;
 311                default:
 312                        chnlgroup = 0;
 313                        writeval = rtlphy->mcs_offset[chnlgroup][index +
 314                                   (rf ? 8 : 0)] + ((index < 2) ?
 315                                   powerbase0[rf] : powerbase1[rf]);
 316                        RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
 317                                "RTK better performance, writeval rf(%c) = 0x%x\n",
 318                                rf == 0 ? 'A' : 'B', writeval);
 319                        break;
 320                }
 321                *(p_outwriteval + rf) = writeval;
 322        }
 323}
 324
 325static void _rtl92d_write_ofdm_power_reg(struct ieee80211_hw *hw,
 326                                         u8 index, u32 *pvalue)
 327{
 328        struct rtl_priv *rtlpriv = rtl_priv(hw);
 329        struct rtl_phy *rtlphy = &(rtlpriv->phy);
 330        static u16 regoffset_a[6] = {
 331                RTXAGC_A_RATE18_06, RTXAGC_A_RATE54_24,
 332                RTXAGC_A_MCS03_MCS00, RTXAGC_A_MCS07_MCS04,
 333                RTXAGC_A_MCS11_MCS08, RTXAGC_A_MCS15_MCS12
 334        };
 335        static u16 regoffset_b[6] = {
 336                RTXAGC_B_RATE18_06, RTXAGC_B_RATE54_24,
 337                RTXAGC_B_MCS03_MCS00, RTXAGC_B_MCS07_MCS04,
 338                RTXAGC_B_MCS11_MCS08, RTXAGC_B_MCS15_MCS12
 339        };
 340        u8 i, rf, pwr_val[4];
 341        u32 writeval;
 342        u16 regoffset;
 343
 344        for (rf = 0; rf < 2; rf++) {
 345                writeval = pvalue[rf];
 346                for (i = 0; i < 4; i++) {
 347                        pwr_val[i] = (u8) ((writeval & (0x7f <<
 348                                     (i * 8))) >> (i * 8));
 349                        if (pwr_val[i] > RF6052_MAX_TX_PWR)
 350                                pwr_val[i] = RF6052_MAX_TX_PWR;
 351                }
 352                writeval = (pwr_val[3] << 24) | (pwr_val[2] << 16) |
 353                           (pwr_val[1] << 8) | pwr_val[0];
 354                if (rf == 0)
 355                        regoffset = regoffset_a[index];
 356                else
 357                        regoffset = regoffset_b[index];
 358                rtl_set_bbreg(hw, regoffset, MASKDWORD, writeval);
 359                RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
 360                        "Set 0x%x = %08x\n", regoffset, writeval);
 361                if (((get_rf_type(rtlphy) == RF_2T2R) &&
 362                    (regoffset == RTXAGC_A_MCS15_MCS12 ||
 363                    regoffset == RTXAGC_B_MCS15_MCS12)) ||
 364                    ((get_rf_type(rtlphy) != RF_2T2R) &&
 365                    (regoffset == RTXAGC_A_MCS07_MCS04 ||
 366                    regoffset == RTXAGC_B_MCS07_MCS04))) {
 367                        writeval = pwr_val[3];
 368                        if (regoffset == RTXAGC_A_MCS15_MCS12 ||
 369                            regoffset == RTXAGC_A_MCS07_MCS04)
 370                                regoffset = 0xc90;
 371                        if (regoffset == RTXAGC_B_MCS15_MCS12 ||
 372                            regoffset == RTXAGC_B_MCS07_MCS04)
 373                                regoffset = 0xc98;
 374                        for (i = 0; i < 3; i++) {
 375                                if (i != 2)
 376                                        writeval = (writeval > 8) ?
 377                                                   (writeval - 8) : 0;
 378                                else
 379                                        writeval = (writeval > 6) ?
 380                                                   (writeval - 6) : 0;
 381                                rtl_write_byte(rtlpriv, (u32) (regoffset + i),
 382                                               (u8) writeval);
 383                        }
 384                }
 385        }
 386}
 387
 388void rtl92d_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
 389                                        u8 *ppowerlevel, u8 channel)
 390{
 391        u32 writeval[2], powerbase0[2], powerbase1[2];
 392        u8 index;
 393
 394        _rtl92d_phy_get_power_base(hw, ppowerlevel, channel,
 395                        &powerbase0[0], &powerbase1[0]);
 396        for (index = 0; index < 6; index++) {
 397                _rtl92d_get_txpower_writeval_by_regulatory(hw,
 398                                channel, index, &powerbase0[0],
 399                                &powerbase1[0], &writeval[0]);
 400                _rtl92d_write_ofdm_power_reg(hw, index, &writeval[0]);
 401        }
 402}
 403
 404bool rtl92d_phy_enable_anotherphy(struct ieee80211_hw *hw, bool bmac0)
 405{
 406        struct rtl_priv *rtlpriv = rtl_priv(hw);
 407        struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
 408        u8 u1btmp;
 409        u8 direct = bmac0 ? BIT(3) | BIT(2) : BIT(3);
 410        u8 mac_reg = bmac0 ? REG_MAC1 : REG_MAC0;
 411        u8 mac_on_bit = bmac0 ? MAC1_ON : MAC0_ON;
 412        bool bresult = true; /* true: need to enable BB/RF power */
 413
 414        rtlhal->during_mac0init_radiob = false;
 415        rtlhal->during_mac1init_radioa = false;
 416        RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "===>\n");
 417        /* MAC0 Need PHY1 load radio_b.txt . Driver use DBI to write. */
 418        u1btmp = rtl_read_byte(rtlpriv, mac_reg);
 419        if (!(u1btmp & mac_on_bit)) {
 420                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "enable BB & RF\n");
 421                /* Enable BB and RF power */
 422                rtl92de_write_dword_dbi(hw, REG_SYS_ISO_CTRL,
 423                        rtl92de_read_dword_dbi(hw, REG_SYS_ISO_CTRL, direct) |
 424                                BIT(29) | BIT(16) | BIT(17), direct);
 425        } else {
 426                /* We think if MAC1 is ON,then radio_a.txt
 427                 * and radio_b.txt has been load. */
 428                bresult = false;
 429        }
 430        RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "<===\n");
 431        return bresult;
 432
 433}
 434
 435void rtl92d_phy_powerdown_anotherphy(struct ieee80211_hw *hw, bool bmac0)
 436{
 437        struct rtl_priv *rtlpriv = rtl_priv(hw);
 438        struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
 439        u8 u1btmp;
 440        u8 direct = bmac0 ? BIT(3) | BIT(2) : BIT(3);
 441        u8 mac_reg = bmac0 ? REG_MAC1 : REG_MAC0;
 442        u8 mac_on_bit = bmac0 ? MAC1_ON : MAC0_ON;
 443
 444        rtlhal->during_mac0init_radiob = false;
 445        rtlhal->during_mac1init_radioa = false;
 446        RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "====>\n");
 447        /* check MAC0 enable or not again now, if
 448         * enabled, not power down radio A. */
 449        u1btmp = rtl_read_byte(rtlpriv, mac_reg);
 450        if (!(u1btmp & mac_on_bit)) {
 451                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "power down\n");
 452                /* power down RF radio A according to YuNan's advice. */
 453                rtl92de_write_dword_dbi(hw, RFPGA0_XA_LSSIPARAMETER,
 454                                        0x00000000, direct);
 455        }
 456        RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "<====\n");
 457}
 458
 459bool rtl92d_phy_rf6052_config(struct ieee80211_hw *hw)
 460{
 461        struct rtl_priv *rtlpriv = rtl_priv(hw);
 462        struct rtl_phy *rtlphy = &(rtlpriv->phy);
 463        bool rtstatus = true;
 464        struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
 465        u32 u4_regvalue = 0;
 466        u8 rfpath;
 467        struct bb_reg_def *pphyreg;
 468        bool mac1_initradioa_first = false, mac0_initradiob_first = false;
 469        bool need_pwrdown_radioa = false, need_pwrdown_radiob = false;
 470        bool true_bpath = false;
 471
 472        if (rtlphy->rf_type == RF_1T1R)
 473                rtlphy->num_total_rfpath = 1;
 474        else
 475                rtlphy->num_total_rfpath = 2;
 476
 477        /* Single phy mode: use radio_a radio_b config path_A path_B */
 478        /* seperately by MAC0, and MAC1 needn't configure RF; */
 479        /* Dual PHY mode:MAC0 use radio_a config 1st phy path_A, */
 480        /* MAC1 use radio_b config 2nd PHY path_A. */
 481        /* DMDP,MAC0 on G band,MAC1 on A band. */
 482        if (rtlhal->macphymode == DUALMAC_DUALPHY) {
 483                if (rtlhal->current_bandtype == BAND_ON_2_4G &&
 484                    rtlhal->interfaceindex == 0) {
 485                        /* MAC0 needs PHY1 load radio_b.txt.
 486                         * Driver use DBI to write. */
 487                        if (rtl92d_phy_enable_anotherphy(hw, true)) {
 488                                rtlphy->num_total_rfpath = 2;
 489                                mac0_initradiob_first = true;
 490                        } else {
 491                                /* We think if MAC1 is ON,then radio_a.txt and
 492                                 * radio_b.txt has been load. */
 493                                return rtstatus;
 494                        }
 495                } else if (rtlhal->current_bandtype == BAND_ON_5G &&
 496                           rtlhal->interfaceindex == 1) {
 497                        /* MAC1 needs PHY0 load radio_a.txt.
 498                         * Driver use DBI to write. */
 499                        if (rtl92d_phy_enable_anotherphy(hw, false)) {
 500                                rtlphy->num_total_rfpath = 2;
 501                                mac1_initradioa_first = true;
 502                        } else {
 503                                /* We think if MAC0 is ON,then radio_a.txt and
 504                                 * radio_b.txt has been load. */
 505                                return rtstatus;
 506                        }
 507                } else if (rtlhal->interfaceindex == 1) {
 508                        /* MAC0 enabled, only init radia B.   */
 509                        true_bpath = true;
 510                }
 511        }
 512
 513        for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) {
 514                /* Mac1 use PHY0 write */
 515                if (mac1_initradioa_first) {
 516                        if (rfpath == RF90_PATH_A) {
 517                                rtlhal->during_mac1init_radioa = true;
 518                                need_pwrdown_radioa = true;
 519                        } else if (rfpath == RF90_PATH_B) {
 520                                rtlhal->during_mac1init_radioa = false;
 521                                mac1_initradioa_first = false;
 522                                rfpath = RF90_PATH_A;
 523                                true_bpath = true;
 524                                rtlphy->num_total_rfpath = 1;
 525                        }
 526                } else if (mac0_initradiob_first) {
 527                        /* Mac0 use PHY1 write */
 528                        if (rfpath == RF90_PATH_A)
 529                                rtlhal->during_mac0init_radiob = false;
 530                        if (rfpath == RF90_PATH_B) {
 531                                rtlhal->during_mac0init_radiob = true;
 532                                mac0_initradiob_first = false;
 533                                need_pwrdown_radiob = true;
 534                                rfpath = RF90_PATH_A;
 535                                true_bpath = true;
 536                                rtlphy->num_total_rfpath = 1;
 537                        }
 538                }
 539                pphyreg = &rtlphy->phyreg_def[rfpath];
 540                switch (rfpath) {
 541                case RF90_PATH_A:
 542                case RF90_PATH_C:
 543                        u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs,
 544                                                    BRFSI_RFENV);
 545                        break;
 546                case RF90_PATH_B:
 547                case RF90_PATH_D:
 548                        u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs,
 549                                BRFSI_RFENV << 16);
 550                        break;
 551                }
 552                rtl_set_bbreg(hw, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1);
 553                udelay(1);
 554                rtl_set_bbreg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1);
 555                udelay(1);
 556                /* Set bit number of Address and Data for RF register */
 557                /* Set 1 to 4 bits for 8255 */
 558                rtl_set_bbreg(hw, pphyreg->rfhssi_para2,
 559                              B3WIREADDRESSLENGTH, 0x0);
 560                udelay(1);
 561                /* Set 0 to 12  bits for 8255 */
 562                rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0);
 563                udelay(1);
 564                switch (rfpath) {
 565                case RF90_PATH_A:
 566                        if (true_bpath)
 567                                rtstatus = rtl92d_phy_config_rf_with_headerfile(
 568                                                hw, radiob_txt,
 569                                                (enum radio_path)rfpath);
 570                        else
 571                                rtstatus = rtl92d_phy_config_rf_with_headerfile(
 572                                             hw, radioa_txt,
 573                                             (enum radio_path)rfpath);
 574                        break;
 575                case RF90_PATH_B:
 576                        rtstatus =
 577                            rtl92d_phy_config_rf_with_headerfile(hw, radiob_txt,
 578                                                (enum radio_path) rfpath);
 579                        break;
 580                case RF90_PATH_C:
 581                        break;
 582                case RF90_PATH_D:
 583                        break;
 584                }
 585                switch (rfpath) {
 586                case RF90_PATH_A:
 587                case RF90_PATH_C:
 588                        rtl_set_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV,
 589                                      u4_regvalue);
 590                        break;
 591                case RF90_PATH_B:
 592                case RF90_PATH_D:
 593                        rtl_set_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV << 16,
 594                                      u4_regvalue);
 595                        break;
 596                }
 597                if (!rtstatus) {
 598                        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 599                                 "Radio[%d] Fail!!\n", rfpath);
 600                        goto phy_rf_cfg_fail;
 601                }
 602
 603        }
 604
 605        /* check MAC0 enable or not again, if enabled,
 606         * not power down radio A. */
 607        /* check MAC1 enable or not again, if enabled,
 608         * not power down radio B. */
 609        if (need_pwrdown_radioa)
 610                rtl92d_phy_powerdown_anotherphy(hw, false);
 611        else if (need_pwrdown_radiob)
 612                rtl92d_phy_powerdown_anotherphy(hw, true);
 613        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "<---\n");
 614        return rtstatus;
 615
 616phy_rf_cfg_fail:
 617        return rtstatus;
 618}
 619