GNU Linux-libre 4.14.266-gnu1
[releases.git] / drivers / net / wireless / realtek / rtlwifi / rtl8192de / rf.c
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 }