1 /******************************************************************************
2  *
3  * Copyright(c) 2009-2010  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 
rtl92d_phy_rf6052_set_bandwidth(struct ieee80211_hw * hw,u8 bandwidth)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 
rtl92d_phy_rf6052_set_cck_txpower(struct ieee80211_hw * hw,u8 * ppowerlevel)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_txpwrlevel_origoffset[0][6]) +
110 			    (rtlphy->mcs_txpwrlevel_origoffset[0][7] << 8);
111 			tx_agc[RF90_PATH_A] += tmpval;
112 			tmpval = (rtlphy->mcs_txpwrlevel_origoffset[0][14]) +
113 			    (rtlphy->mcs_txpwrlevel_origoffset[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, BMASKBYTE1, tmpval);
129 	RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
130 		("CCK PWR 1M (rf-A) = 0x%x (reg 0x%x)\n", tmpval,
131 		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", tmpval,
136 		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, BMASKBYTE0, tmpval);
139 	RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
140 		("CCK PWR 11M (rf-B) = 0x%x (reg 0x%x)\n", tmpval,
141 		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", tmpval,
146 		RTXAGC_B_CCK1_55_MCS32));
147 }
148 
_rtl92d_phy_get_power_base(struct ieee80211_hw * hw,u8 * ppowerlevel,u8 channel,u32 * ofdmbase,u32 * mcsbase)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 
_rtl92d_phy_get_chnlgroup_bypg(u8 chnlindex)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 
_rtl92d_get_txpower_writeval_by_regulatory(struct ieee80211_hw * hw,u8 channel,u8 index,u32 * powerbase0,u32 * powerbase1,u32 * p_outwriteval)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_txpwrlevel_origoffset
231 					[chnlgroup][index +
232 					(rf ? 8 : 0)] + ((index < 2) ?
233 					powerbase0[rf] :
234 					powerbase1[rf]);
235 			RTPRINT(rtlpriv, FPHY, PHY_TXPWR, ("RTK better "
236 				"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_txpwrlevel_origoffset
251 						[chnlgroup][index +
252 						(rf ? 8 : 0)] + ((index < 2) ?
253 						powerbase0[rf] :
254 						powerbase1[rf]);
255 				RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
256 					("Realtek regulatory, "
257 					"20MHz, writeval(%c) = 0x%x\n",
258 					((rf == 0) ? 'A' : 'B'),
259 					writeval));
260 			}
261 			break;
262 		case 2:
263 			writeval = ((index < 2) ? powerbase0[rf] :
264 				   powerbase1[rf]);
265 			RTPRINT(rtlpriv, FPHY, PHY_TXPWR, ("Better regulatory, "
266 				"writeval(%c) = 0x%x\n",
267 				((rf == 0) ? 'A' : 'B'), writeval));
268 			break;
269 		case 3:
270 			chnlgroup = 0;
271 			if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
272 				RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
273 					("customer's limit, 40MHz rf(%c) = "
274 					"0x%x\n", ((rf == 0) ? 'A' : 'B'),
275 					rtlefuse->pwrgroup_ht40[rf]
276 					[channel - 1]));
277 			} else {
278 				RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
279 					("customer's limit, 20MHz rf(%c) = "
280 					"0x%x\n", ((rf == 0) ? 'A' : 'B'),
281 					rtlefuse->pwrgroup_ht20[rf]
282 					[channel - 1]));
283 			}
284 			for (i = 0; i < 4; i++) {
285 				pwr_diff_limit[i] =
286 					(u8)((rtlphy->mcs_txpwrlevel_origoffset
287 					[chnlgroup][index + (rf ? 8 : 0)] &
288 					(0x7f << (i * 8))) >> (i * 8));
289 				if (rtlphy->current_chan_bw ==
290 				    HT_CHANNEL_WIDTH_20_40) {
291 					if (pwr_diff_limit[i] >
292 					    rtlefuse->pwrgroup_ht40[rf]
293 					   [channel - 1])
294 						pwr_diff_limit[i] =
295 							rtlefuse->pwrgroup_ht40
296 							[rf][channel - 1];
297 				} else {
298 					if (pwr_diff_limit[i] >
299 					    rtlefuse->pwrgroup_ht20[rf][
300 						channel - 1])
301 						pwr_diff_limit[i] =
302 						   rtlefuse->pwrgroup_ht20[rf]
303 						   [channel - 1];
304 				}
305 			}
306 			customer_limit = (pwr_diff_limit[3] << 24) |
307 					 (pwr_diff_limit[2] << 16) |
308 					 (pwr_diff_limit[1] << 8) |
309 					 (pwr_diff_limit[0]);
310 			RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
311 				("Customer's limit rf(%c) = 0x%x\n",
312 				((rf == 0) ? 'A' : 'B'), customer_limit));
313 			writeval = customer_limit + ((index < 2) ?
314 				   powerbase0[rf] : powerbase1[rf]);
315 			RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
316 				("Customer, writeval rf(%c)= 0x%x\n",
317 				((rf == 0) ? 'A' : 'B'), writeval));
318 			break;
319 		default:
320 			chnlgroup = 0;
321 			writeval = rtlphy->mcs_txpwrlevel_origoffset
322 				   [chnlgroup][index +
323 				   (rf ? 8 : 0)] + ((index < 2) ?
324 				   powerbase0[rf] : powerbase1[rf]);
325 			RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
326 				("RTK better performance, writeval "
327 				"rf(%c) = 0x%x\n",
328 				((rf == 0) ? 'A' : 'B'), writeval));
329 			break;
330 		}
331 		*(p_outwriteval + rf) = writeval;
332 	}
333 }
334 
_rtl92d_write_ofdm_power_reg(struct ieee80211_hw * hw,u8 index,u32 * pvalue)335 static void _rtl92d_write_ofdm_power_reg(struct ieee80211_hw *hw,
336 					 u8 index, u32 *pvalue)
337 {
338 	struct rtl_priv *rtlpriv = rtl_priv(hw);
339 	struct rtl_phy *rtlphy = &(rtlpriv->phy);
340 	static u16 regoffset_a[6] = {
341 		RTXAGC_A_RATE18_06, RTXAGC_A_RATE54_24,
342 		RTXAGC_A_MCS03_MCS00, RTXAGC_A_MCS07_MCS04,
343 		RTXAGC_A_MCS11_MCS08, RTXAGC_A_MCS15_MCS12
344 	};
345 	static u16 regoffset_b[6] = {
346 		RTXAGC_B_RATE18_06, RTXAGC_B_RATE54_24,
347 		RTXAGC_B_MCS03_MCS00, RTXAGC_B_MCS07_MCS04,
348 		RTXAGC_B_MCS11_MCS08, RTXAGC_B_MCS15_MCS12
349 	};
350 	u8 i, rf, pwr_val[4];
351 	u32 writeval;
352 	u16 regoffset;
353 
354 	for (rf = 0; rf < 2; rf++) {
355 		writeval = pvalue[rf];
356 		for (i = 0; i < 4; i++) {
357 			pwr_val[i] = (u8) ((writeval & (0x7f <<
358 				     (i * 8))) >> (i * 8));
359 			if (pwr_val[i] > RF6052_MAX_TX_PWR)
360 				pwr_val[i] = RF6052_MAX_TX_PWR;
361 		}
362 		writeval = (pwr_val[3] << 24) | (pwr_val[2] << 16) |
363 			   (pwr_val[1] << 8) | pwr_val[0];
364 		if (rf == 0)
365 			regoffset = regoffset_a[index];
366 		else
367 			regoffset = regoffset_b[index];
368 		rtl_set_bbreg(hw, regoffset, BMASKDWORD, writeval);
369 		RTPRINT(rtlpriv, FPHY, PHY_TXPWR,
370 			("Set 0x%x = %08x\n", regoffset, writeval));
371 		if (((get_rf_type(rtlphy) == RF_2T2R) &&
372 		    (regoffset == RTXAGC_A_MCS15_MCS12 ||
373 		    regoffset == RTXAGC_B_MCS15_MCS12)) ||
374 		    ((get_rf_type(rtlphy) != RF_2T2R) &&
375 		    (regoffset == RTXAGC_A_MCS07_MCS04 ||
376 		    regoffset == RTXAGC_B_MCS07_MCS04))) {
377 			writeval = pwr_val[3];
378 			if (regoffset == RTXAGC_A_MCS15_MCS12 ||
379 			    regoffset == RTXAGC_A_MCS07_MCS04)
380 				regoffset = 0xc90;
381 			if (regoffset == RTXAGC_B_MCS15_MCS12 ||
382 			    regoffset == RTXAGC_B_MCS07_MCS04)
383 				regoffset = 0xc98;
384 			for (i = 0; i < 3; i++) {
385 				if (i != 2)
386 					writeval = (writeval > 8) ?
387 						   (writeval - 8) : 0;
388 				else
389 					writeval = (writeval > 6) ?
390 						   (writeval - 6) : 0;
391 				rtl_write_byte(rtlpriv, (u32) (regoffset + i),
392 					       (u8) writeval);
393 			}
394 		}
395 	}
396 }
397 
rtl92d_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw * hw,u8 * ppowerlevel,u8 channel)398 void rtl92d_phy_rf6052_set_ofdm_txpower(struct ieee80211_hw *hw,
399 					u8 *ppowerlevel, u8 channel)
400 {
401 	u32 writeval[2], powerbase0[2], powerbase1[2];
402 	u8 index;
403 
404 	_rtl92d_phy_get_power_base(hw, ppowerlevel, channel,
405 			&powerbase0[0],	&powerbase1[0]);
406 	for (index = 0; index < 6; index++) {
407 		_rtl92d_get_txpower_writeval_by_regulatory(hw,
408 				channel, index,	&powerbase0[0],
409 				&powerbase1[0],	&writeval[0]);
410 		_rtl92d_write_ofdm_power_reg(hw, index, &writeval[0]);
411 	}
412 }
413 
rtl92d_phy_enable_anotherphy(struct ieee80211_hw * hw,bool bmac0)414 bool rtl92d_phy_enable_anotherphy(struct ieee80211_hw *hw, bool bmac0)
415 {
416 	struct rtl_priv *rtlpriv = rtl_priv(hw);
417 	struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
418 	u8 u1btmp;
419 	u8 direct = bmac0 ? BIT(3) | BIT(2) : BIT(3);
420 	u8 mac_reg = bmac0 ? REG_MAC1 : REG_MAC0;
421 	u8 mac_on_bit = bmac0 ? MAC1_ON : MAC0_ON;
422 	bool bresult = true; /* true: need to enable BB/RF power */
423 
424 	rtlhal->during_mac0init_radiob = false;
425 	rtlhal->during_mac1init_radioa = false;
426 	RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("===>\n"));
427 	/* MAC0 Need PHY1 load radio_b.txt . Driver use DBI to write. */
428 	u1btmp = rtl_read_byte(rtlpriv, mac_reg);
429 	if (!(u1btmp & mac_on_bit)) {
430 		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("enable BB & RF\n"));
431 		/* Enable BB and RF power */
432 		rtl92de_write_dword_dbi(hw, REG_SYS_ISO_CTRL,
433 			rtl92de_read_dword_dbi(hw, REG_SYS_ISO_CTRL, direct) |
434 				BIT(29) | BIT(16) | BIT(17), direct);
435 	} else {
436 		/* We think if MAC1 is ON,then radio_a.txt
437 		 * and radio_b.txt has been load. */
438 		bresult = false;
439 	}
440 	RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("<===\n"));
441 	return bresult;
442 
443 }
444 
rtl92d_phy_powerdown_anotherphy(struct ieee80211_hw * hw,bool bmac0)445 void rtl92d_phy_powerdown_anotherphy(struct ieee80211_hw *hw, bool bmac0)
446 {
447 	struct rtl_priv *rtlpriv = rtl_priv(hw);
448 	struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
449 	u8 u1btmp;
450 	u8 direct = bmac0 ? BIT(3) | BIT(2) : BIT(3);
451 	u8 mac_reg = bmac0 ? REG_MAC1 : REG_MAC0;
452 	u8 mac_on_bit = bmac0 ? MAC1_ON : MAC0_ON;
453 
454 	rtlhal->during_mac0init_radiob = false;
455 	rtlhal->during_mac1init_radioa = false;
456 	RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("====>\n"));
457 	/* check MAC0 enable or not again now, if
458 	 * enabled, not power down radio A. */
459 	u1btmp = rtl_read_byte(rtlpriv, mac_reg);
460 	if (!(u1btmp & mac_on_bit)) {
461 		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, ("power down\n"));
462 		/* power down RF radio A according to YuNan's advice. */
463 		rtl92de_write_dword_dbi(hw, RFPGA0_XA_LSSIPARAMETER,
464 					0x00000000, direct);
465 	}
466 	RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, ("<====\n"));
467 }
468 
rtl92d_phy_rf6052_config(struct ieee80211_hw * hw)469 bool rtl92d_phy_rf6052_config(struct ieee80211_hw *hw)
470 {
471 	struct rtl_priv *rtlpriv = rtl_priv(hw);
472 	struct rtl_phy *rtlphy = &(rtlpriv->phy);
473 	bool rtstatus = true;
474 	struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
475 	u32 u4_regvalue = 0;
476 	u8 rfpath;
477 	struct bb_reg_def *pphyreg;
478 	bool mac1_initradioa_first = false, mac0_initradiob_first = false;
479 	bool need_pwrdown_radioa = false, need_pwrdown_radiob = false;
480 	bool true_bpath = false;
481 
482 	if (rtlphy->rf_type == RF_1T1R)
483 		rtlphy->num_total_rfpath = 1;
484 	else
485 		rtlphy->num_total_rfpath = 2;
486 
487 	/* Single phy mode: use radio_a radio_b config path_A path_B */
488 	/* seperately by MAC0, and MAC1 needn't configure RF; */
489 	/* Dual PHY mode:MAC0 use radio_a config 1st phy path_A, */
490 	/* MAC1 use radio_b config 2nd PHY path_A. */
491 	/* DMDP,MAC0 on G band,MAC1 on A band. */
492 	if (rtlhal->macphymode == DUALMAC_DUALPHY) {
493 		if (rtlhal->current_bandtype == BAND_ON_2_4G &&
494 		    rtlhal->interfaceindex == 0) {
495 			/* MAC0 needs PHY1 load radio_b.txt.
496 			 * Driver use DBI to write. */
497 			if (rtl92d_phy_enable_anotherphy(hw, true)) {
498 				rtlphy->num_total_rfpath = 2;
499 				mac0_initradiob_first = true;
500 			} else {
501 				/* We think if MAC1 is ON,then radio_a.txt and
502 				 * radio_b.txt has been load. */
503 				return rtstatus;
504 			}
505 		} else if (rtlhal->current_bandtype == BAND_ON_5G &&
506 			   rtlhal->interfaceindex == 1) {
507 			/* MAC1 needs PHY0 load radio_a.txt.
508 			 * Driver use DBI to write. */
509 			if (rtl92d_phy_enable_anotherphy(hw, false)) {
510 				rtlphy->num_total_rfpath = 2;
511 				mac1_initradioa_first = true;
512 			} else {
513 				/* We think if MAC0 is ON,then radio_a.txt and
514 				 * radio_b.txt has been load. */
515 				return rtstatus;
516 			}
517 		} else if (rtlhal->interfaceindex == 1) {
518 			/* MAC0 enabled, only init radia B.   */
519 			true_bpath = true;
520 		}
521 	}
522 
523 	for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) {
524 		/* Mac1 use PHY0 write */
525 		if (mac1_initradioa_first) {
526 			if (rfpath == RF90_PATH_A) {
527 				rtlhal->during_mac1init_radioa = true;
528 				need_pwrdown_radioa = true;
529 			} else if (rfpath == RF90_PATH_B) {
530 				rtlhal->during_mac1init_radioa = false;
531 				mac1_initradioa_first = false;
532 				rfpath = RF90_PATH_A;
533 				true_bpath = true;
534 				rtlphy->num_total_rfpath = 1;
535 			}
536 		} else if (mac0_initradiob_first) {
537 			/* Mac0 use PHY1 write */
538 			if (rfpath == RF90_PATH_A)
539 				rtlhal->during_mac0init_radiob = false;
540 			if (rfpath == RF90_PATH_B) {
541 				rtlhal->during_mac0init_radiob = true;
542 				mac0_initradiob_first = false;
543 				need_pwrdown_radiob = true;
544 				rfpath = RF90_PATH_A;
545 				true_bpath = true;
546 				rtlphy->num_total_rfpath = 1;
547 			}
548 		}
549 		pphyreg = &rtlphy->phyreg_def[rfpath];
550 		switch (rfpath) {
551 		case RF90_PATH_A:
552 		case RF90_PATH_C:
553 			u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs,
554 						    BRFSI_RFENV);
555 			break;
556 		case RF90_PATH_B:
557 		case RF90_PATH_D:
558 			u4_regvalue = rtl_get_bbreg(hw, pphyreg->rfintfs,
559 				BRFSI_RFENV << 16);
560 			break;
561 		}
562 		rtl_set_bbreg(hw, pphyreg->rfintfe, BRFSI_RFENV << 16, 0x1);
563 		udelay(1);
564 		rtl_set_bbreg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1);
565 		udelay(1);
566 		/* Set bit number of Address and Data for RF register */
567 		/* Set 1 to 4 bits for 8255 */
568 		rtl_set_bbreg(hw, pphyreg->rfhssi_para2,
569 			      B3WIREADDRESSLENGTH, 0x0);
570 		udelay(1);
571 		/* Set 0 to 12  bits for 8255 */
572 		rtl_set_bbreg(hw, pphyreg->rfhssi_para2, B3WIREDATALENGTH, 0x0);
573 		udelay(1);
574 		switch (rfpath) {
575 		case RF90_PATH_A:
576 			if (true_bpath)
577 				rtstatus = rtl92d_phy_config_rf_with_headerfile(
578 						hw, radiob_txt,
579 						(enum radio_path)rfpath);
580 			else
581 				rtstatus = rtl92d_phy_config_rf_with_headerfile(
582 					     hw, radioa_txt,
583 					     (enum radio_path)rfpath);
584 			break;
585 		case RF90_PATH_B:
586 			rtstatus =
587 			    rtl92d_phy_config_rf_with_headerfile(hw, radiob_txt,
588 						(enum radio_path) rfpath);
589 			break;
590 		case RF90_PATH_C:
591 			break;
592 		case RF90_PATH_D:
593 			break;
594 		}
595 		switch (rfpath) {
596 		case RF90_PATH_A:
597 		case RF90_PATH_C:
598 			rtl_set_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV,
599 				      u4_regvalue);
600 			break;
601 		case RF90_PATH_B:
602 		case RF90_PATH_D:
603 			rtl_set_bbreg(hw, pphyreg->rfintfs, BRFSI_RFENV << 16,
604 				      u4_regvalue);
605 			break;
606 		}
607 		if (rtstatus != true) {
608 			RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
609 				("Radio[%d] Fail!!", rfpath));
610 			goto phy_rf_cfg_fail;
611 		}
612 
613 	}
614 
615 	/* check MAC0 enable or not again, if enabled,
616 	 * not power down radio A. */
617 	/* check MAC1 enable or not again, if enabled,
618 	 * not power down radio B. */
619 	if (need_pwrdown_radioa)
620 		rtl92d_phy_powerdown_anotherphy(hw, false);
621 	else if (need_pwrdown_radiob)
622 		rtl92d_phy_powerdown_anotherphy(hw, true);
623 	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("<---\n"));
624 	return rtstatus;
625 
626 phy_rf_cfg_fail:
627 	return rtstatus;
628 }
629