linux/drivers/net/wireless/rtlwifi/rtl8192de/rf.c
<<
>>
Prefs
   1/******************************************************************************
   2 *
   3 * Copyright(c) 2009-2010  Realtek Corporation.
   4 *
   5 * This program is free software; you can redistribute it and/or modify it
   6 * under the terms of version 2 of the GNU General Public License as
   7 * published by the Free Software Foundation.
   8 *
   9 * This program is distributed in the hope that it will be useful, but WITHOUT
  10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  12 * more details.
  13 *
  14 * 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_txpwrlevel_origoffset[0][6]) +
 110                            (rtlphy->mcs_txpwrlevel_origoffset[0][7] << 8);
 111                        tx_agc[RF90_PATH_A] += tmpval;
 112                        tmpval = (rtlphy->mcs_txpwrlevel_origoffset[0][14]) +
 113                            (rtlphy->mcs_txpwrlevel_origoffset[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", tmpval,
 131                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", tmpval,
 136                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", tmpval,
 141                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", tmpval,
 146                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_txpwrlevel_origoffset
 231                                        [chnlgroup][index +
 232                                        (rf ? 8 : 0)] + ((index < 2) ?
 233                                        powerbase0[rf] :
 234                                        powerbase1[rf]);
 235                        RTPRINT(rtlpriv, FPHY, PHY_TXPWR, ("RTK better "
 236                                "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_txpwrlevel_origoffset
 251                                                [chnlgroup][index +
 252                                                (rf ? 8 : 0)] + ((index < 2) ?
 253                                                powerbase0[rf] :
 254                                                powerbase1[rf]);
 255                                RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
 256                                        ("Realtek regulatory, "
 257                                        "20MHz, writeval(%c) = 0x%x\n",
 258                                        ((rf == 0) ? 'A' : 'B'),
 259                                        writeval));
 260                        }
 261                        break;
 262                case 2:
 263                        writeval = ((index < 2) ? powerbase0[rf] :
 264                                   powerbase1[rf]);
 265                        RTPRINT(rtlpriv, FPHY, PHY_TXPWR, ("Better regulatory, "
 266                                "writeval(%c) = 0x%x\n",
 267                                ((rf == 0) ? 'A' : 'B'), writeval));
 268                        break;
 269                case 3:
 270                        chnlgroup = 0;
 271                        if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
 272                                RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
 273                                        ("customer's limit, 40MHz rf(%c) = "
 274                                        "0x%x\n", ((rf == 0) ? 'A' : 'B'),
 275                                        rtlefuse->pwrgroup_ht40[rf]
 276                                        [channel - 1]));
 277                        } else {
 278                                RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
 279                                        ("customer's limit, 20MHz rf(%c) = "
 280                                        "0x%x\n", ((rf == 0) ? 'A' : 'B'),
 281                                        rtlefuse->pwrgroup_ht20[rf]
 282                                        [channel - 1]));
 283                        }
 284                        for (i = 0; i < 4; i++) {
 285                                pwr_diff_limit[i] =
 286                                        (u8)((rtlphy->mcs_txpwrlevel_origoffset
 287                                        [chnlgroup][index + (rf ? 8 : 0)] &
 288                                        (0x7f << (i * 8))) >> (i * 8));
 289                                if (rtlphy->current_chan_bw ==
 290                                    HT_CHANNEL_WIDTH_20_40) {
 291                                        if (pwr_diff_limit[i] >
 292                                            rtlefuse->pwrgroup_ht40[rf]
 293                                           [channel - 1])
 294                                                pwr_diff_limit[i] =
 295                                                        rtlefuse->pwrgroup_ht40
 296                                                        [rf][channel - 1];
 297                                } else {
 298                                        if (pwr_diff_limit[i] >
 299                                            rtlefuse->pwrgroup_ht20[rf][
 300                                                channel - 1])
 301                                                pwr_diff_limit[i] =
 302                                                   rtlefuse->pwrgroup_ht20[rf]
 303                                                   [channel - 1];
 304                                }
 305                        }
 306                        customer_limit = (pwr_diff_limit[3] << 24) |
 307                                         (pwr_diff_limit[2] << 16) |
 308                                         (pwr_diff_limit[1] << 8) |
 309                                         (pwr_diff_limit[0]);
 310                        RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
 311                                ("Customer's limit rf(%c) = 0x%x\n",
 312                                ((rf == 0) ? 'A' : 'B'), customer_limit));
 313                        writeval = customer_limit + ((index < 2) ?
 314                                   powerbase0[rf] : powerbase1[rf]);
 315                        RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
 316                                ("Customer, writeval rf(%c)= 0x%x\n",
 317                                ((rf == 0) ? 'A' : 'B'), writeval));
 318                        break;
 319                default:
 320                        chnlgroup = 0;
 321                        writeval = rtlphy->mcs_txpwrlevel_origoffset
 322                                   [chnlgroup][index +
 323                                   (rf ? 8 : 0)] + ((index < 2) ?
 324                                   powerbase0[rf] : powerbase1[rf]);
 325                        RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
 326                                ("RTK better performance, writeval "
 327                                "rf(%c) = 0x%x\n",
 328                                ((rf == 0) ? 'A' : 'B'), writeval));
 329                        break;
 330                }
 331                *(p_outwriteval + rf) = writeval;
 332        }
 333}
 334
 335static void _rtl92d_write_ofdm_power_reg(struct ieee80211_hw *hw,
 336                                         u8 index, u32 *pvalue)
 337{
 338        struct rtl_priv *rtlpriv = rtl_priv(hw);
 339        struct rtl_phy *rtlphy = &(rtlpriv->phy);
 340        static u16 regoffset_a[6] = {
 341                RTXAGC_A_RATE18_06, RTXAGC_A_RATE54_24,
 342                RTXAGC_A_MCS03_MCS00, RTXAGC_A_MCS07_MCS04,
 343                RTXAGC_A_MCS11_MCS08, RTXAGC_A_MCS15_MCS12
 344        };
 345        static u16 regoffset_b[6] = {
 346                RTXAGC_B_RATE18_06, RTXAGC_B_RATE54_24,
 347                RTXAGC_B_MCS03_MCS00, RTXAGC_B_MCS07_MCS04,
 348                RTXAGC_B_MCS11_MCS08, RTXAGC_B_MCS15_MCS12
 349        };
 350        u8 i, rf, pwr_val[4];
 351        u32 writeval;
 352        u16 regoffset;
 353
 354        for (rf = 0; rf < 2; rf++) {
 355                writeval = pvalue[rf];
 356                for (i = 0; i < 4; i++) {
 357                        pwr_val[i] = (u8) ((writeval & (0x7f <<
 358                                     (i * 8))) >> (i * 8));
 359                        if (pwr_val[i] > RF6052_MAX_TX_PWR)
 360                                pwr_val[i] = RF6052_MAX_TX_PWR;
 361                }
 362                writeval = (pwr_val[3] << 24) | (pwr_val[2] << 16) |
 363                           (pwr_val[1] << 8) | pwr_val[0];
 364                if (rf == 0)
 365                        regoffset = regoffset_a[index];
 366                else
 367                        regoffset = regoffset_b[index];
 368                rtl_set_bbreg(hw, regoffset, BMASKDWORD, writeval);
 369                RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
 370                        ("Set 0x%x = %08x\n", regoffset, writeval));
 371                if (((get_rf_type(rtlphy) == RF_2T2R) &&
 372                    (regoffset == RTXAGC_A_MCS15_MCS12 ||
 373                    regoffset == RTXAGC_B_MCS15_MCS12)) ||
 374                    ((get_rf_type(rtlphy) != RF_2T2R) &&
 375                    (regoffset == RTXAGC_A_MCS07_MCS04 ||
 376                    regoffset == RTXAGC_B_MCS07_MCS04))) {
 377                        writeval = pwr_val[3];
 378                        if (regoffset == RTXAGC_A_MCS15_MCS12 ||
 379                            regoffset == RTXAGC_A_MCS07_MCS04)
 380                                regoffset = 0xc90;
 381                        if (regoffset == RTXAGC_B_MCS15_MCS12 ||
 382                            regoffset == RTXAGC_B_MCS07_MCS04)
 383                                regoffset = 0xc98;
 384                        for (i = 0; i < 3; i++) {
 385                                if (i != 2)
 386                                        writeval = (writeval > 8) ?
 387                                                   (writeval - 8) : 0;
 388                                else
 389                                        writeval = (writeval > 6) ?
 390                                                   (writeval - 6) : 0;
 391                                rtl_write_byte(rtlpriv, (u32) (regoffset + i),
 392                                               (u8) writeval);
 393                        }
 394                }
 395        }
 396}
 397
 398void rtl92d_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
 399                                        u8 *ppowerlevel, u8 channel)
 400{
 401        u32 writeval[2], powerbase0[2], powerbase1[2];
 402        u8 index;
 403
 404        _rtl92d_phy_get_power_base(hw, ppowerlevel, channel,
 405                        &powerbase0[0], &powerbase1[0]);
 406        for (index = 0; index < 6; index++) {
 407                _rtl92d_get_txpower_writeval_by_regulatory(hw,
 408                                channel, index, &powerbase0[0],
 409                                &powerbase1[0], &writeval[0]);
 410                _rtl92d_write_ofdm_power_reg(hw, index, &writeval[0]);
 411        }
 412}
 413
 414bool rtl92d_phy_enable_anotherphy(struct ieee80211_hw *hw, bool bmac0)
 415{
 416        struct rtl_priv *rtlpriv = rtl_priv(hw);
 417        struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
 418        u8 u1btmp;
 419        u8 direct = bmac0 ? BIT(3) | BIT(2) : BIT(3);
 420        u8 mac_reg = bmac0 ? REG_MAC1 : REG_MAC0;
 421        u8 mac_on_bit = bmac0 ? MAC1_ON : MAC0_ON;
 422        bool bresult = true; /* true: need to enable BB/RF power */
 423
 424        rtlhal->during_mac0init_radiob = false;
 425        rtlhal->during_mac1init_radioa = false;
 426        RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("===>\n"));
 427        /* MAC0 Need PHY1 load radio_b.txt . Driver use DBI to write. */
 428        u1btmp = rtl_read_byte(rtlpriv, mac_reg);
 429        if (!(u1btmp & mac_on_bit)) {
 430                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("enable BB & RF\n"));
 431                /* Enable BB and RF power */
 432                rtl92de_write_dword_dbi(hw, REG_SYS_ISO_CTRL,
 433                        rtl92de_read_dword_dbi(hw, REG_SYS_ISO_CTRL, direct) |
 434                                BIT(29) | BIT(16) | BIT(17), direct);
 435        } else {
 436                /* We think if MAC1 is ON,then radio_a.txt
 437                 * and radio_b.txt has been load. */
 438                bresult = false;
 439        }
 440        RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("<===\n"));
 441        return bresult;
 442
 443}
 444
 445void rtl92d_phy_powerdown_anotherphy(struct ieee80211_hw *hw, bool bmac0)
 446{
 447        struct rtl_priv *rtlpriv = rtl_priv(hw);
 448        struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
 449        u8 u1btmp;
 450        u8 direct = bmac0 ? BIT(3) | BIT(2) : BIT(3);
 451        u8 mac_reg = bmac0 ? REG_MAC1 : REG_MAC0;
 452        u8 mac_on_bit = bmac0 ? MAC1_ON : MAC0_ON;
 453
 454        rtlhal->during_mac0init_radiob = false;
 455        rtlhal->during_mac1init_radioa = false;
 456        RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("====>\n"));
 457        /* check MAC0 enable or not again now, if
 458         * enabled, not power down radio A. */
 459        u1btmp = rtl_read_byte(rtlpriv, mac_reg);
 460        if (!(u1btmp & mac_on_bit)) {
 461                RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("power down\n"));
 462                /* power down RF radio A according to YuNan's advice. */
 463                rtl92de_write_dword_dbi(hw, RFPGA0_XA_LSSIPARAMETER,
 464                                        0x00000000, direct);
 465        }
 466        RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("<====\n"));
 467}
 468
 469bool rtl92d_phy_rf6052_config(struct ieee80211_hw *hw)
 470{
 471        struct rtl_priv *rtlpriv = rtl_priv(hw);
 472        struct rtl_phy *rtlphy = &(rtlpriv->phy);
 473        bool rtstatus = true;
 474        struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
 475        u32 u4_regvalue = 0;
 476        u8 rfpath;
 477        struct bb_reg_def *pphyreg;
 478        bool mac1_initradioa_first = false, mac0_initradiob_first = false;
 479        bool need_pwrdown_radioa = false, need_pwrdown_radiob = false;
 480        bool true_bpath = false;
 481
 482        if (rtlphy->rf_type == RF_1T1R)
 483                rtlphy->num_total_rfpath = 1;
 484        else
 485                rtlphy->num_total_rfpath = 2;
 486
 487        /* Single phy mode: use radio_a radio_b config path_A path_B */
 488        /* seperately by MAC0, and MAC1 needn't configure RF; */
 489        /* Dual PHY mode:MAC0 use radio_a config 1st phy path_A, */
 490        /* MAC1 use radio_b config 2nd PHY path_A. */
 491        /* DMDP,MAC0 on G band,MAC1 on A band. */
 492        if (rtlhal->macphymode == DUALMAC_DUALPHY) {
 493                if (rtlhal->current_bandtype == BAND_ON_2_4G &&
 494                    rtlhal->interfaceindex == 0) {
 495                        /* MAC0 needs PHY1 load radio_b.txt.
 496                         * Driver use DBI to write. */
 497                        if (rtl92d_phy_enable_anotherphy(hw, true)) {
 498                                rtlphy->num_total_rfpath = 2;
 499                                mac0_initradiob_first = true;
 500                        } else {
 501                                /* We think if MAC1 is ON,then radio_a.txt and
 502                                 * radio_b.txt has been load. */
 503                                return rtstatus;
 504                        }
 505                } else if (rtlhal->current_bandtype == BAND_ON_5G &&
 506                           rtlhal->interfaceindex == 1) {
 507                        /* MAC1 needs PHY0 load radio_a.txt.
 508                         * Driver use DBI to write. */
 509                        if (rtl92d_phy_enable_anotherphy(hw, false)) {
 510                                rtlphy->num_total_rfpath = 2;
 511                                mac1_initradioa_first = true;
 512                        } else {
 513                                /* We think if MAC0 is ON,then radio_a.txt and
 514                                 * radio_b.txt has been load. */
 515                                return rtstatus;
 516                        }
 517                } else if (rtlhal->interfaceindex == 1) {
 518                        /* MAC0 enabled, only init radia B.   */
 519                        true_bpath = true;
 520                }
 521        }
 522
 523        for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) {
 524                /* Mac1 use PHY0 write */
 525                if (mac1_initradioa_first) {
 526                        if (rfpath == RF90_PATH_A) {
 527                                rtlhal->during_mac1init_radioa = true;
 528                                need_pwrdown_radioa = true;
 529                        } else if (rfpath == RF90_PATH_B) {
 530                                rtlhal->during_mac1init_radioa = false;
 531                                mac1_initradioa_first = false;
 532                                rfpath = RF90_PATH_A;
 533                                true_bpath = true;
 534                                rtlphy->num_total_rfpath = 1;
 535                        }
 536                } else if (mac0_initradiob_first) {
 537                        /* Mac0 use PHY1 write */
 538                        if (rfpath == RF90_PATH_A)
 539                                rtlhal->during_mac0init_radiob = false;
 540                        if (rfpath == RF90_PATH_B) {
 541                                rtlhal->during_mac0init_radiob = true;
 542                                mac0_initradiob_first = false;
 543                                need_pwrdown_radiob = true;
 544                                rfpath = RF90_PATH_A;
 545                                true_bpath = true;
 546                                rtlphy->num_total_rfpath = 1;
 547                        }
 548                }
 549                pphyreg = &rtlphy->phyreg_def[rfpath];
 550                switch (rfpath) {
 551                case RF90_PATH_A:
 552                case RF90_PATH_C:
 553                        u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs,
 554                                                    BRFSI_RFENV);
 555                        break;
 556                case RF90_PATH_B:
 557                case RF90_PATH_D:
 558                        u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs,
 559                                BRFSI_RFENV << 16);
 560                        break;
 561                }
 562                rtl_set_bbreg(hw, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1);
 563                udelay(1);
 564                rtl_set_bbreg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1);
 565                udelay(1);
 566                /* Set bit number of Address and Data for RF register */
 567                /* Set 1 to 4 bits for 8255 */
 568                rtl_set_bbreg(hw, pphyreg->rfhssi_para2,
 569                              B3WIREADDRESSLENGTH, 0x0);
 570                udelay(1);
 571                /* Set 0 to 12  bits for 8255 */
 572                rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0);
 573                udelay(1);
 574                switch (rfpath) {
 575                case RF90_PATH_A:
 576                        if (true_bpath)
 577                                rtstatus = rtl92d_phy_config_rf_with_headerfile(
 578                                                hw, radiob_txt,
 579                                                (enum radio_path)rfpath);
 580                        else
 581                                rtstatus = rtl92d_phy_config_rf_with_headerfile(
 582                                             hw, radioa_txt,
 583                                             (enum radio_path)rfpath);
 584                        break;
 585                case RF90_PATH_B:
 586                        rtstatus =
 587                            rtl92d_phy_config_rf_with_headerfile(hw, radiob_txt,
 588                                                (enum radio_path) rfpath);
 589                        break;
 590                case RF90_PATH_C:
 591                        break;
 592                case RF90_PATH_D:
 593                        break;
 594                }
 595                switch (rfpath) {
 596                case RF90_PATH_A:
 597                case RF90_PATH_C:
 598                        rtl_set_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV,
 599                                      u4_regvalue);
 600                        break;
 601                case RF90_PATH_B:
 602                case RF90_PATH_D:
 603                        rtl_set_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV << 16,
 604                                      u4_regvalue);
 605                        break;
 606                }
 607                if (rtstatus != true) {
 608                        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 609                                ("Radio[%d] Fail!!", rfpath));
 610                        goto phy_rf_cfg_fail;
 611                }
 612
 613        }
 614
 615        /* check MAC0 enable or not again, if enabled,
 616         * not power down radio A. */
 617        /* check MAC1 enable or not again, if enabled,
 618         * not power down radio B. */
 619        if (need_pwrdown_radioa)
 620                rtl92d_phy_powerdown_anotherphy(hw, false);
 621        else if (need_pwrdown_radiob)
 622                rtl92d_phy_powerdown_anotherphy(hw, true);
 623        RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("<---\n"));
 624        return rtstatus;
 625
 626phy_rf_cfg_fail:
 627        return rtstatus;
 628}
 629