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