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
38void 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
76void 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
149static 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
187static 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
214static 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
330static 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
393void 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
409bool 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
440void 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
464bool 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
621phy_rf_cfg_fail:
622	return rtstatus;
623}
624