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