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