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 }
624