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