]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/net/wireless/realtek/rtlwifi/rtl8192de/rf.c
Merge branch 'linus' of git://git.kernel.org/pub/scm/linux/kernel/git/herbert/crypto-2.6
[karo-tx-linux.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  * 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
38 void 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
76 void 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, MASKBYTE1, 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, MASKBYTE0, 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
149 static 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
187 static 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
214 static 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
330 static 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, MASKDWORD, 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
393 void 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
409 bool 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
440 void 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
464 bool 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
621 phy_rf_cfg_fail:
622         return rtstatus;
623 }