PageRenderTime 200ms CodeModel.GetById 31ms app.highlight 139ms RepoModel.GetById 6ms app.codeStats 0ms

/drivers/net/wireless/rtlwifi/rtl8192de/rf.c

https://bitbucket.org/cyanogenmod/android_kernel_asus_tf300t
C | 628 lines | 538 code | 32 blank | 58 comment | 117 complexity | e044773a071c1561309be70b5a3a1c19 MD5 | raw file
Possible License(s): LGPL-2.0, AGPL-1.0, GPL-2.0
  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
 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_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
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_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
335static 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
398void 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
414bool 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
445void 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
469bool 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
626phy_rf_cfg_fail:
627	return rtstatus;
628}