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