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