[go: nahoru, domu]

1/******************************************************************************
2 *
3 * Copyright(c) 2009-2014  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 "../pci.h"
28#include "../ps.h"
29#include "reg.h"
30#include "def.h"
31#include "phy.h"
32#include "../rtl8723com/phy_common.h"
33#include "rf.h"
34#include "dm.h"
35#include "../rtl8723com/dm_common.h"
36#include "table.h"
37#include "trx.h"
38
39static bool _rtl8723be_phy_bb8723b_config_parafile(struct ieee80211_hw *hw);
40static bool _rtl8723be_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);
41static bool _rtl8723be_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
42						     u8 configtype);
43static bool _rtl8723be_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
44						       u8 configtype);
45static bool _rtl8723be_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
46						u8 channel, u8 *stage,
47						u8 *step, u32 *delay);
48
49static void rtl8723be_phy_set_rf_on(struct ieee80211_hw *hw);
50static void rtl8723be_phy_set_io(struct ieee80211_hw *hw);
51
52u32 rtl8723be_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
53			       u32 regaddr, u32 bitmask)
54{
55	struct rtl_priv *rtlpriv = rtl_priv(hw);
56	u32 original_value, readback_value, bitshift;
57	unsigned long flags;
58
59	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
60		 "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
61		  regaddr, rfpath, bitmask);
62
63	spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
64
65	original_value = rtl8723_phy_rf_serial_read(hw, rfpath, regaddr);
66	bitshift = rtl8723_phy_calculate_bit_shift(bitmask);
67	readback_value = (original_value & bitmask) >> bitshift;
68
69	spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
70
71	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
72		 "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n",
73		 regaddr, rfpath, bitmask, original_value);
74
75	return readback_value;
76}
77
78void rtl8723be_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path path,
79			      u32 regaddr, u32 bitmask, u32 data)
80{
81	struct rtl_priv *rtlpriv = rtl_priv(hw);
82	u32 original_value, bitshift;
83	unsigned long flags;
84
85	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
86		 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
87		  regaddr, bitmask, data, path);
88
89	spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
90
91	if (bitmask != RFREG_OFFSET_MASK) {
92			original_value = rtl8723_phy_rf_serial_read(hw, path,
93								    regaddr);
94			bitshift = rtl8723_phy_calculate_bit_shift(bitmask);
95			data = ((original_value & (~bitmask)) |
96				(data << bitshift));
97		}
98
99	rtl8723_phy_rf_serial_write(hw, path, regaddr, data);
100
101	spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
102
103	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
104		 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
105		  regaddr, bitmask, data, path);
106
107}
108
109bool rtl8723be_phy_mac_config(struct ieee80211_hw *hw)
110{
111	struct rtl_priv *rtlpriv = rtl_priv(hw);
112	bool rtstatus = _rtl8723be_phy_config_mac_with_headerfile(hw);
113
114	rtl_write_byte(rtlpriv, 0x04CA, 0x0B);
115	return rtstatus;
116}
117
118bool rtl8723be_phy_bb_config(struct ieee80211_hw *hw)
119{
120	bool rtstatus = true;
121	struct rtl_priv *rtlpriv = rtl_priv(hw);
122	u16 regval;
123	u8 b_reg_hwparafile = 1;
124	u32 tmp;
125	u8 crystalcap = rtlpriv->efuse.crystalcap;
126	rtl8723_phy_init_bb_rf_reg_def(hw);
127	regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
128	rtl_write_word(rtlpriv, REG_SYS_FUNC_EN,
129		       regval | BIT(13) | BIT(0) | BIT(1));
130
131	rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB);
132	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN,
133		       FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE |
134		       FEN_BB_GLB_RSTN | FEN_BBRSTB);
135	tmp = rtl_read_dword(rtlpriv, 0x4c);
136	rtl_write_dword(rtlpriv, 0x4c, tmp | BIT(23));
137
138	rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80);
139
140	if (b_reg_hwparafile == 1)
141		rtstatus = _rtl8723be_phy_bb8723b_config_parafile(hw);
142
143	crystalcap = crystalcap & 0x3F;
144	rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000,
145		      (crystalcap | crystalcap << 6));
146
147	return rtstatus;
148}
149
150bool rtl8723be_phy_rf_config(struct ieee80211_hw *hw)
151{
152	return rtl8723be_phy_rf6052_config(hw);
153}
154
155static bool _rtl8723be_check_condition(struct ieee80211_hw *hw,
156				       const u32  condition)
157{
158	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
159	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
160	u32 _board = rtlefuse->board_type; /*need efuse define*/
161	u32 _interface = rtlhal->interface;
162	u32 _platform = 0x08;/*SupportPlatform */
163	u32 cond = condition;
164
165	if (condition == 0xCDCDCDCD)
166		return true;
167
168	cond = condition & 0xFF;
169	if ((_board & cond) == 0 && cond != 0x1F)
170		return false;
171
172	cond = condition & 0xFF00;
173	cond = cond >> 8;
174	if ((_interface & cond) == 0 && cond != 0x07)
175		return false;
176
177	cond = condition & 0xFF0000;
178	cond = cond >> 16;
179	if ((_platform & cond) == 0 && cond != 0x0F)
180		return false;
181	return true;
182}
183
184static void _rtl8723be_config_rf_reg(struct ieee80211_hw *hw, u32 addr,
185				     u32 data, enum radio_path rfpath,
186				     u32 regaddr)
187{
188	if (addr == 0xfe || addr == 0xffe) {
189		/* In order not to disturb BT music
190		 *	when wifi init.(1ant NIC only)
191		 */
192		mdelay(50);
193	} else {
194		rtl_set_rfreg(hw, rfpath, regaddr, RFREG_OFFSET_MASK, data);
195		udelay(1);
196	}
197}
198static void _rtl8723be_config_rf_radio_a(struct ieee80211_hw *hw,
199					 u32 addr, u32 data)
200{
201	u32 content = 0x1000; /*RF Content: radio_a_txt*/
202	u32 maskforphyset = (u32)(content & 0xE000);
203
204	_rtl8723be_config_rf_reg(hw, addr, data, RF90_PATH_A,
205				 addr | maskforphyset);
206
207}
208
209static void _rtl8723be_phy_init_tx_power_by_rate(struct ieee80211_hw *hw)
210{
211	struct rtl_priv *rtlpriv = rtl_priv(hw);
212	struct rtl_phy *rtlphy = &rtlpriv->phy;
213
214	u8 band, path, txnum, section;
215
216	for (band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band)
217		for (path = 0; path < TX_PWR_BY_RATE_NUM_RF; ++path)
218			for (txnum = 0; txnum < TX_PWR_BY_RATE_NUM_RF; ++txnum)
219				for (section = 0;
220				     section < TX_PWR_BY_RATE_NUM_SECTION;
221				     ++section)
222					rtlphy->tx_power_by_rate_offset
223					  [band][path][txnum][section] = 0;
224}
225
226static void _rtl8723be_config_bb_reg(struct ieee80211_hw *hw,
227				     u32 addr, u32 data)
228{
229	if (addr == 0xfe) {
230		mdelay(50);
231	} else if (addr == 0xfd) {
232		mdelay(5);
233	} else if (addr == 0xfc) {
234		mdelay(1);
235	} else if (addr == 0xfb) {
236		udelay(50);
237	} else if (addr == 0xfa) {
238		udelay(5);
239	} else if (addr == 0xf9) {
240		udelay(1);
241	} else {
242		rtl_set_bbreg(hw, addr, MASKDWORD, data);
243		udelay(1);
244	}
245}
246
247static void _rtl8723be_phy_set_txpower_by_rate_base(struct ieee80211_hw *hw,
248						    u8 band,
249						    u8 path, u8 rate_section,
250						    u8 txnum, u8 value)
251{
252	struct rtl_priv *rtlpriv = rtl_priv(hw);
253	struct rtl_phy *rtlphy = &rtlpriv->phy;
254
255	if (path > RF90_PATH_D) {
256		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
257			 "Invalid Rf Path %d in phy_SetTxPowerByRatBase()\n",
258			  path);
259		return;
260	}
261
262	if (band == BAND_ON_2_4G) {
263		switch (rate_section) {
264		case CCK:
265			rtlphy->txpwr_by_rate_base_24g[path][txnum][0] = value;
266			break;
267		case OFDM:
268			rtlphy->txpwr_by_rate_base_24g[path][txnum][1] = value;
269			break;
270		case HT_MCS0_MCS7:
271			rtlphy->txpwr_by_rate_base_24g[path][txnum][2] = value;
272			break;
273		case HT_MCS8_MCS15:
274			rtlphy->txpwr_by_rate_base_24g[path][txnum][3] = value;
275			break;
276		default:
277			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
278				 "Invalid RateSection %d in Band 2.4G, Rf Path %d, %dTx in PHY_SetTxPowerByRateBase()\n",
279				 rate_section, path, txnum);
280			break;
281		};
282	} else {
283		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
284			 "Invalid Band %d in PHY_SetTxPowerByRateBase()\n",
285			 band);
286	}
287
288}
289
290static u8 _rtl8723be_phy_get_txpower_by_rate_base(struct ieee80211_hw *hw,
291						  u8 band, u8 path, u8 txnum,
292						  u8 rate_section)
293{
294	struct rtl_priv *rtlpriv = rtl_priv(hw);
295	struct rtl_phy *rtlphy = &rtlpriv->phy;
296	u8 value = 0;
297	if (path > RF90_PATH_D) {
298		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
299			 "Invalid Rf Path %d in PHY_GetTxPowerByRateBase()\n",
300			  path);
301		return 0;
302	}
303
304	if (band == BAND_ON_2_4G) {
305		switch (rate_section) {
306		case CCK:
307			value = rtlphy->txpwr_by_rate_base_24g[path][txnum][0];
308			break;
309		case OFDM:
310			value = rtlphy->txpwr_by_rate_base_24g[path][txnum][1];
311			break;
312		case HT_MCS0_MCS7:
313			value = rtlphy->txpwr_by_rate_base_24g[path][txnum][2];
314			break;
315		case HT_MCS8_MCS15:
316			value = rtlphy->txpwr_by_rate_base_24g[path][txnum][3];
317			break;
318		default:
319			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
320				 "Invalid RateSection %d in Band 2.4G, Rf Path %d, %dTx in PHY_GetTxPowerByRateBase()\n",
321				 rate_section, path, txnum);
322			break;
323		};
324	} else {
325		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
326			 "Invalid Band %d in PHY_GetTxPowerByRateBase()\n",
327			 band);
328	}
329
330	return value;
331}
332
333static void _rtl8723be_phy_store_txpower_by_rate_base(struct ieee80211_hw *hw)
334{
335	struct rtl_priv *rtlpriv = rtl_priv(hw);
336	struct rtl_phy *rtlphy = &rtlpriv->phy;
337	u16 rawvalue = 0;
338	u8 base = 0, path = 0;
339
340	for (path = RF90_PATH_A; path <= RF90_PATH_B; ++path) {
341		if (path == RF90_PATH_A) {
342			rawvalue = (u16)(rtlphy->tx_power_by_rate_offset
343				[BAND_ON_2_4G][path][RF_1TX][3] >> 24) & 0xFF;
344			base = (rawvalue >> 4) * 10 + (rawvalue & 0xF);
345			_rtl8723be_phy_set_txpower_by_rate_base(hw,
346				BAND_ON_2_4G, path, CCK, RF_1TX, base);
347		} else if (path == RF90_PATH_B) {
348			rawvalue = (u16)(rtlphy->tx_power_by_rate_offset
349				[BAND_ON_2_4G][path][RF_1TX][3] >> 0) & 0xFF;
350			base = (rawvalue >> 4) * 10 + (rawvalue & 0xF);
351			_rtl8723be_phy_set_txpower_by_rate_base(hw,
352								BAND_ON_2_4G,
353								path, CCK,
354								RF_1TX, base);
355		}
356		rawvalue = (u16)(rtlphy->tx_power_by_rate_offset
357				[BAND_ON_2_4G][path][RF_1TX][1] >> 24) & 0xFF;
358		base = (rawvalue >> 4) * 10 + (rawvalue & 0xF);
359		_rtl8723be_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G,
360							path, OFDM, RF_1TX,
361							base);
362
363		rawvalue = (u16)(rtlphy->tx_power_by_rate_offset
364				[BAND_ON_2_4G][path][RF_1TX][5] >> 24) & 0xFF;
365		base = (rawvalue >> 4) * 10 + (rawvalue & 0xF);
366		_rtl8723be_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G,
367							path, HT_MCS0_MCS7,
368							RF_1TX, base);
369
370		rawvalue = (u16)(rtlphy->tx_power_by_rate_offset
371				[BAND_ON_2_4G][path][RF_2TX][7] >> 24) & 0xFF;
372		base = (rawvalue >> 4) * 10 + (rawvalue & 0xF);
373		_rtl8723be_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G,
374							path, HT_MCS8_MCS15,
375							RF_2TX, base);
376	}
377}
378
379static void _phy_convert_txpower_dbm_to_relative_value(u32 *data, u8 start,
380						u8 end, u8 base_val)
381{
382	char i = 0;
383	u8 temp_value = 0;
384	u32 temp_data = 0;
385
386	for (i = 3; i >= 0; --i) {
387		if (i >= start && i <= end) {
388			/* Get the exact value */
389			temp_value = (u8)(*data >> (i * 8)) & 0xF;
390			temp_value += ((u8)((*data >> (i*8 + 4)) & 0xF)) * 10;
391
392			/* Change the value to a relative value */
393			temp_value = (temp_value > base_val) ?
394				     temp_value - base_val :
395				     base_val - temp_value;
396		} else {
397			temp_value = (u8)(*data >> (i * 8)) & 0xFF;
398		}
399		temp_data <<= 8;
400		temp_data |= temp_value;
401	}
402	*data = temp_data;
403}
404
405static void _rtl8723be_phy_convert_txpower_dbm_to_relative_value(
406							struct ieee80211_hw *hw)
407{
408	struct rtl_priv *rtlpriv = rtl_priv(hw);
409	struct rtl_phy *rtlphy = &rtlpriv->phy;
410	u8 base = 0, rfpath = RF90_PATH_A;
411
412	base = _rtl8723be_phy_get_txpower_by_rate_base(hw,
413			BAND_ON_2_4G, rfpath, RF_1TX, CCK);
414	_phy_convert_txpower_dbm_to_relative_value(
415	    &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][2],
416	    1, 1, base);
417	_phy_convert_txpower_dbm_to_relative_value(
418	    &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][3],
419	    1, 3, base);
420
421	base = _rtl8723be_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfpath,
422						       RF_1TX, OFDM);
423	_phy_convert_txpower_dbm_to_relative_value(
424	    &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][0],
425	    0, 3, base);
426	_phy_convert_txpower_dbm_to_relative_value(
427	    &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][1],
428	    0, 3, base);
429
430	base = _rtl8723be_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G,
431						rfpath, RF_1TX, HT_MCS0_MCS7);
432	_phy_convert_txpower_dbm_to_relative_value(
433	    &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][4],
434	    0, 3, base);
435	_phy_convert_txpower_dbm_to_relative_value(
436	    &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][5],
437	    0, 3, base);
438
439	base = _rtl8723be_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G,
440						       rfpath, RF_2TX,
441						       HT_MCS8_MCS15);
442	_phy_convert_txpower_dbm_to_relative_value(
443	    &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_2TX][6],
444	    0, 3, base);
445
446	_phy_convert_txpower_dbm_to_relative_value(
447	    &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_2TX][7],
448	    0, 3, base);
449
450	RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
451	    "<===_rtl8723be_phy_convert_txpower_dbm_to_relative_value()\n");
452}
453
454static void phy_txpower_by_rate_config(struct ieee80211_hw *hw)
455{
456	_rtl8723be_phy_store_txpower_by_rate_base(hw);
457	_rtl8723be_phy_convert_txpower_dbm_to_relative_value(hw);
458}
459
460static bool _rtl8723be_phy_bb8723b_config_parafile(struct ieee80211_hw *hw)
461{
462	struct rtl_priv *rtlpriv = rtl_priv(hw);
463	struct rtl_phy *rtlphy = &rtlpriv->phy;
464	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
465	bool rtstatus;
466
467	rtstatus = _rtl8723be_phy_config_bb_with_headerfile(hw,
468						BASEBAND_CONFIG_PHY_REG);
469	if (!rtstatus) {
470		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!");
471		return false;
472	}
473	_rtl8723be_phy_init_tx_power_by_rate(hw);
474	if (!rtlefuse->autoload_failflag) {
475		rtlphy->pwrgroup_cnt = 0;
476		rtstatus = _rtl8723be_phy_config_bb_with_pgheaderfile(hw,
477						BASEBAND_CONFIG_PHY_REG);
478	}
479	phy_txpower_by_rate_config(hw);
480	if (!rtstatus) {
481		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!");
482		return false;
483	}
484	rtstatus = _rtl8723be_phy_config_bb_with_headerfile(hw,
485						BASEBAND_CONFIG_AGC_TAB);
486	if (!rtstatus) {
487		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n");
488		return false;
489	}
490	rtlphy->cck_high_power = (bool)(rtl_get_bbreg(hw,
491						      RFPGA0_XA_HSSIPARAMETER2,
492						      0x200));
493	return true;
494}
495
496static bool _rtl8723be_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
497{
498	struct rtl_priv *rtlpriv = rtl_priv(hw);
499	u32 i;
500	u32 arraylength;
501	u32 *ptrarray;
502
503	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read rtl8723beMACPHY_Array\n");
504	arraylength = RTL8723BEMAC_1T_ARRAYLEN;
505	ptrarray = RTL8723BEMAC_1T_ARRAY;
506	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
507		 "Img:RTL8723bEMAC_1T_ARRAY LEN %d\n", arraylength);
508	for (i = 0; i < arraylength; i = i + 2)
509		rtl_write_byte(rtlpriv, ptrarray[i], (u8)ptrarray[i + 1]);
510	return true;
511}
512
513static bool _rtl8723be_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
514						     u8 configtype)
515{
516	#define READ_NEXT_PAIR(v1, v2, i) \
517		do { \
518			i += 2; \
519			v1 = array_table[i];\
520			v2 = array_table[i+1]; \
521		} while (0)
522
523	int i;
524	u32 *array_table;
525	u16 arraylen;
526	struct rtl_priv *rtlpriv = rtl_priv(hw);
527	u32 v1 = 0, v2 = 0;
528
529	if (configtype == BASEBAND_CONFIG_PHY_REG) {
530		arraylen = RTL8723BEPHY_REG_1TARRAYLEN;
531		array_table = RTL8723BEPHY_REG_1TARRAY;
532
533		for (i = 0; i < arraylen; i = i + 2) {
534			v1 = array_table[i];
535			v2 = array_table[i+1];
536			if (v1 < 0xcdcdcdcd) {
537				_rtl8723be_config_bb_reg(hw, v1, v2);
538			} else {/*This line is the start line of branch.*/
539				/* to protect READ_NEXT_PAIR not overrun */
540				if (i >= arraylen - 2)
541					break;
542
543				if (!_rtl8723be_check_condition(hw,
544						array_table[i])) {
545					/*Discard the following
546					 *(offset, data) pairs
547					 */
548					READ_NEXT_PAIR(v1, v2, i);
549					while (v2 != 0xDEAD &&
550					       v2 != 0xCDEF &&
551					       v2 != 0xCDCD &&
552					       i < arraylen - 2) {
553						READ_NEXT_PAIR(v1, v2, i);
554					}
555					i -= 2; /* prevent from for-loop += 2*/
556				/*Configure matched pairs and
557				 *skip to end of if-else.
558				 */
559				} else {
560					READ_NEXT_PAIR(v1, v2, i);
561					while (v2 != 0xDEAD &&
562					       v2 != 0xCDEF &&
563					       v2 != 0xCDCD &&
564					       i < arraylen - 2) {
565						_rtl8723be_config_bb_reg(hw,
566								    v1, v2);
567						READ_NEXT_PAIR(v1, v2, i);
568					}
569
570					while (v2 != 0xDEAD && i < arraylen - 2)
571						READ_NEXT_PAIR(v1, v2, i);
572				}
573			}
574		}
575	} else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
576		arraylen = RTL8723BEAGCTAB_1TARRAYLEN;
577		array_table = RTL8723BEAGCTAB_1TARRAY;
578
579		for (i = 0; i < arraylen; i = i + 2) {
580			v1 = array_table[i];
581			v2 = array_table[i+1];
582			if (v1 < 0xCDCDCDCD) {
583				rtl_set_bbreg(hw, array_table[i],
584					      MASKDWORD,
585					      array_table[i + 1]);
586				udelay(1);
587				continue;
588			} else {/*This line is the start line of branch.*/
589				/* to protect READ_NEXT_PAIR not overrun */
590				if (i >= arraylen - 2)
591					break;
592
593				if (!_rtl8723be_check_condition(hw,
594					array_table[i])) {
595					/*Discard the following
596					 *(offset, data) pairs
597					 */
598					READ_NEXT_PAIR(v1, v2, i);
599					while (v2 != 0xDEAD &&
600					       v2 != 0xCDEF &&
601					       v2 != 0xCDCD &&
602					       i < arraylen - 2) {
603						READ_NEXT_PAIR(v1, v2, i);
604					}
605					i -= 2; /* prevent from for-loop += 2*/
606				/*Configure matched pairs and
607				 *skip to end of if-else.
608				 */
609				} else {
610					READ_NEXT_PAIR(v1, v2, i);
611					while (v2 != 0xDEAD &&
612					       v2 != 0xCDEF &&
613					       v2 != 0xCDCD &&
614					       i < arraylen - 2) {
615						rtl_set_bbreg(hw, array_table[i],
616							      MASKDWORD,
617							      array_table[i + 1]);
618						udelay(1);
619						READ_NEXT_PAIR(v1, v2, i);
620					}
621
622					while (v2 != 0xDEAD && i < arraylen - 2)
623						READ_NEXT_PAIR(v1, v2, i);
624				}
625			}
626			RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
627				 "The agctab_array_table[0] is %x Rtl818EEPHY_REGArray[1] is %x\n",
628				 array_table[i], array_table[i + 1]);
629		}
630	}
631	return true;
632}
633
634static u8 _rtl8723be_get_rate_section_index(u32 regaddr)
635{
636	u8 index = 0;
637
638	switch (regaddr) {
639	case RTXAGC_A_RATE18_06:
640		index = 0;
641	break;
642	case RTXAGC_A_RATE54_24:
643		index = 1;
644	break;
645	case RTXAGC_A_CCK1_MCS32:
646		index = 2;
647	break;
648	case RTXAGC_B_CCK11_A_CCK2_11:
649		index = 3;
650	break;
651	case RTXAGC_A_MCS03_MCS00:
652		index = 4;
653	break;
654	case RTXAGC_A_MCS07_MCS04:
655		index = 5;
656	break;
657	case RTXAGC_A_MCS11_MCS08:
658		index = 6;
659	break;
660	case RTXAGC_A_MCS15_MCS12:
661		index = 7;
662	break;
663	case RTXAGC_B_RATE18_06:
664		index = 0;
665	break;
666	case RTXAGC_B_RATE54_24:
667		index = 1;
668	break;
669	case RTXAGC_B_CCK1_55_MCS32:
670		index = 2;
671	break;
672	case RTXAGC_B_MCS03_MCS00:
673		index = 4;
674	break;
675	case RTXAGC_B_MCS07_MCS04:
676		index = 5;
677	break;
678	case RTXAGC_B_MCS11_MCS08:
679		index = 6;
680	break;
681	case RTXAGC_B_MCS15_MCS12:
682		index = 7;
683	break;
684	default:
685		regaddr &= 0xFFF;
686		if (regaddr >= 0xC20 && regaddr <= 0xC4C)
687			index = (u8)((regaddr - 0xC20) / 4);
688		else if (regaddr >= 0xE20 && regaddr <= 0xE4C)
689			index = (u8)((regaddr - 0xE20) / 4);
690		break;
691	};
692	return index;
693}
694
695static void _rtl8723be_store_tx_power_by_rate(struct ieee80211_hw *hw,
696					      u32 band, u32 rfpath,
697					      u32 txnum, u32 regaddr,
698					      u32 bitmask, u32 data)
699{
700	struct rtl_priv *rtlpriv = rtl_priv(hw);
701	struct rtl_phy *rtlphy = &rtlpriv->phy;
702	u8 rate_section = _rtl8723be_get_rate_section_index(regaddr);
703
704	if (band != BAND_ON_2_4G && band != BAND_ON_5G) {
705		RT_TRACE(rtlpriv, FPHY, PHY_TXPWR, "Invalid Band %d\n", band);
706		return;
707	}
708	if (rfpath > MAX_RF_PATH - 1) {
709		RT_TRACE(rtlpriv, FPHY, PHY_TXPWR,
710			 "Invalid RfPath %d\n", rfpath);
711		return;
712	}
713	if (txnum > MAX_RF_PATH - 1) {
714		RT_TRACE(rtlpriv, FPHY, PHY_TXPWR, "Invalid TxNum %d\n", txnum);
715		return;
716	}
717
718	rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section] =
719									data;
720
721}
722
723static bool _rtl8723be_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
724						       u8 configtype)
725{
726	struct rtl_priv *rtlpriv = rtl_priv(hw);
727	int i;
728	u32 *phy_regarray_table_pg;
729	u16 phy_regarray_pg_len;
730	u32 v1 = 0, v2 = 0, v3 = 0, v4 = 0, v5 = 0, v6 = 0;
731
732	phy_regarray_pg_len = RTL8723BEPHY_REG_ARRAY_PGLEN;
733	phy_regarray_table_pg = RTL8723BEPHY_REG_ARRAY_PG;
734
735	if (configtype == BASEBAND_CONFIG_PHY_REG) {
736		for (i = 0; i < phy_regarray_pg_len; i = i + 6) {
737			v1 = phy_regarray_table_pg[i];
738			v2 = phy_regarray_table_pg[i+1];
739			v3 = phy_regarray_table_pg[i+2];
740			v4 = phy_regarray_table_pg[i+3];
741			v5 = phy_regarray_table_pg[i+4];
742			v6 = phy_regarray_table_pg[i+5];
743
744			if (v1 < 0xcdcdcdcd) {
745				if (phy_regarray_table_pg[i] == 0xfe ||
746				    phy_regarray_table_pg[i] == 0xffe)
747					mdelay(50);
748				else
749					_rtl8723be_store_tx_power_by_rate(hw,
750							v1, v2, v3, v4, v5, v6);
751				continue;
752			}
753		}
754	} else {
755		RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
756			 "configtype != BaseBand_Config_PHY_REG\n");
757	}
758	return true;
759}
760
761bool rtl8723be_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
762					     enum radio_path rfpath)
763{
764	#define READ_NEXT_RF_PAIR(v1, v2, i) \
765		do { \
766			i += 2; \
767			v1 = radioa_array_table[i]; \
768			v2 = radioa_array_table[i+1]; \
769		} while (0)
770
771	int i;
772	bool rtstatus = true;
773	u32 *radioa_array_table;
774	u16 radioa_arraylen;
775	struct rtl_priv *rtlpriv = rtl_priv(hw);
776	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
777	u32 v1 = 0, v2 = 0;
778
779	radioa_arraylen = RTL8723BE_RADIOA_1TARRAYLEN;
780	radioa_array_table = RTL8723BE_RADIOA_1TARRAY;
781	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
782		 "Radio_A:RTL8723BE_RADIOA_1TARRAY %d\n", radioa_arraylen);
783	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
784	rtstatus = true;
785	switch (rfpath) {
786	case RF90_PATH_A:
787		for (i = 0; i < radioa_arraylen; i = i + 2) {
788			v1 = radioa_array_table[i];
789			v2 = radioa_array_table[i+1];
790			if (v1 < 0xcdcdcdcd) {
791				_rtl8723be_config_rf_radio_a(hw, v1, v2);
792			} else {/*This line is the start line of branch.*/
793				/* to protect READ_NEXT_PAIR not overrun */
794				if (i >= radioa_arraylen - 2)
795					break;
796
797				if (!_rtl8723be_check_condition(hw,
798						radioa_array_table[i])) {
799					/*Discard the following
800					 *(offset, data) pairs
801					 */
802					READ_NEXT_RF_PAIR(v1, v2, i);
803					while (v2 != 0xDEAD &&
804					       v2 != 0xCDEF &&
805					       v2 != 0xCDCD &&
806					       i < radioa_arraylen - 2) {
807						READ_NEXT_RF_PAIR(v1, v2, i);
808					}
809					i -= 2; /* prevent from for-loop += 2*/
810				} else {
811					/*Configure matched pairs
812					 *and skip to end of if-else.
813					 */
814					READ_NEXT_RF_PAIR(v1, v2, i);
815					while (v2 != 0xDEAD &&
816					       v2 != 0xCDEF &&
817					       v2 != 0xCDCD &&
818					       i < radioa_arraylen - 2) {
819						_rtl8723be_config_rf_radio_a(hw,
820									v1, v2);
821						READ_NEXT_RF_PAIR(v1, v2, i);
822					}
823
824					while (v2 != 0xDEAD &&
825					       i < radioa_arraylen - 2) {
826						READ_NEXT_RF_PAIR(v1, v2, i);
827					}
828				}
829			}
830		}
831
832		if (rtlhal->oem_id == RT_CID_819X_HP)
833			_rtl8723be_config_rf_radio_a(hw, 0x52, 0x7E4BD);
834		break;
835	case RF90_PATH_B:
836	case RF90_PATH_C:
837		break;
838	case RF90_PATH_D:
839		RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
840			 "switch case not process\n");
841		break;
842	}
843	return true;
844}
845
846void rtl8723be_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
847{
848	struct rtl_priv *rtlpriv = rtl_priv(hw);
849	struct rtl_phy *rtlphy = &rtlpriv->phy;
850
851	rtlphy->default_initialgain[0] =
852	    (u8)rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
853	rtlphy->default_initialgain[1] =
854	    (u8)rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
855	rtlphy->default_initialgain[2] =
856	    (u8)rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
857	rtlphy->default_initialgain[3] =
858	    (u8)rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
859
860	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
861		 "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n",
862		 rtlphy->default_initialgain[0],
863		 rtlphy->default_initialgain[1],
864		 rtlphy->default_initialgain[2],
865		 rtlphy->default_initialgain[3]);
866
867	rtlphy->framesync = (u8)rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3,
868					       MASKBYTE0);
869	rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2,
870					      MASKDWORD);
871
872	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
873		 "Default framesync (0x%x) = 0x%x\n",
874		  ROFDM0_RXDETECTOR3, rtlphy->framesync);
875}
876
877void rtl8723be_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
878{
879	struct rtl_priv *rtlpriv = rtl_priv(hw);
880	struct rtl_phy *rtlphy = &rtlpriv->phy;
881	u8 txpwr_level;
882	long txpwr_dbm;
883
884	txpwr_level = rtlphy->cur_cck_txpwridx;
885	txpwr_dbm = rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_B,
886						 txpwr_level);
887	txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
888	if (rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, txpwr_level) >
889	    txpwr_dbm)
890		txpwr_dbm =
891		    rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
892						 txpwr_level);
893	txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
894	if (rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
895					 txpwr_level) > txpwr_dbm)
896		txpwr_dbm =
897		    rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
898						 txpwr_level);
899	*powerlevel = txpwr_dbm;
900}
901
902static u8 _rtl8723be_phy_get_ratesection_intxpower_byrate(enum radio_path path,
903							  u8 rate)
904{
905	u8 rate_section = 0;
906
907	switch (rate) {
908	case DESC92C_RATE1M:
909		rate_section = 2;
910		break;
911
912	case DESC92C_RATE2M:
913	case DESC92C_RATE5_5M:
914		if (path == RF90_PATH_A)
915			rate_section = 3;
916		else if (path == RF90_PATH_B)
917			rate_section = 2;
918		break;
919
920	case DESC92C_RATE11M:
921		rate_section = 3;
922		break;
923
924	case DESC92C_RATE6M:
925	case DESC92C_RATE9M:
926	case DESC92C_RATE12M:
927	case DESC92C_RATE18M:
928		rate_section = 0;
929		break;
930
931	case DESC92C_RATE24M:
932	case DESC92C_RATE36M:
933	case DESC92C_RATE48M:
934	case DESC92C_RATE54M:
935		rate_section = 1;
936		break;
937
938	case DESC92C_RATEMCS0:
939	case DESC92C_RATEMCS1:
940	case DESC92C_RATEMCS2:
941	case DESC92C_RATEMCS3:
942		rate_section = 4;
943		break;
944
945	case DESC92C_RATEMCS4:
946	case DESC92C_RATEMCS5:
947	case DESC92C_RATEMCS6:
948	case DESC92C_RATEMCS7:
949		rate_section = 5;
950		break;
951
952	case DESC92C_RATEMCS8:
953	case DESC92C_RATEMCS9:
954	case DESC92C_RATEMCS10:
955	case DESC92C_RATEMCS11:
956		rate_section = 6;
957		break;
958
959	case DESC92C_RATEMCS12:
960	case DESC92C_RATEMCS13:
961	case DESC92C_RATEMCS14:
962	case DESC92C_RATEMCS15:
963		rate_section = 7;
964		break;
965
966	default:
967		RT_ASSERT(true, "Rate_Section is Illegal\n");
968		break;
969	}
970
971	return rate_section;
972}
973
974static u8 _rtl8723be_get_txpower_by_rate(struct ieee80211_hw *hw,
975					 enum band_type band,
976					 enum radio_path rfpath, u8 rate)
977{
978	struct rtl_priv *rtlpriv = rtl_priv(hw);
979	struct rtl_phy *rtlphy = &rtlpriv->phy;
980	u8 shift = 0, rate_section, tx_num;
981	char tx_pwr_diff = 0;
982
983	rate_section = _rtl8723be_phy_get_ratesection_intxpower_byrate(rfpath,
984								       rate);
985	tx_num = RF_TX_NUM_NONIMPLEMENT;
986
987	if (tx_num == RF_TX_NUM_NONIMPLEMENT) {
988		if (rate >= DESC92C_RATEMCS8 && rate <= DESC92C_RATEMCS15)
989			tx_num = RF_2TX;
990		else
991			tx_num = RF_1TX;
992	}
993
994	switch (rate) {
995	case DESC92C_RATE6M:
996	case DESC92C_RATE24M:
997	case DESC92C_RATEMCS0:
998	case DESC92C_RATEMCS4:
999	case DESC92C_RATEMCS8:
1000	case DESC92C_RATEMCS12:
1001		shift = 0;
1002		break;
1003	case DESC92C_RATE1M:
1004	case DESC92C_RATE2M:
1005	case DESC92C_RATE9M:
1006	case DESC92C_RATE36M:
1007	case DESC92C_RATEMCS1:
1008	case DESC92C_RATEMCS5:
1009	case DESC92C_RATEMCS9:
1010	case DESC92C_RATEMCS13:
1011		shift = 8;
1012		break;
1013	case DESC92C_RATE5_5M:
1014	case DESC92C_RATE12M:
1015	case DESC92C_RATE48M:
1016	case DESC92C_RATEMCS2:
1017	case DESC92C_RATEMCS6:
1018	case DESC92C_RATEMCS10:
1019	case DESC92C_RATEMCS14:
1020		shift = 16;
1021		break;
1022	case DESC92C_RATE11M:
1023	case DESC92C_RATE18M:
1024	case DESC92C_RATE54M:
1025	case DESC92C_RATEMCS3:
1026	case DESC92C_RATEMCS7:
1027	case DESC92C_RATEMCS11:
1028	case DESC92C_RATEMCS15:
1029		shift = 24;
1030		break;
1031	default:
1032		RT_ASSERT(true, "Rate_Section is Illegal\n");
1033		break;
1034	}
1035	tx_pwr_diff = (u8)(rtlphy->tx_power_by_rate_offset[band][rfpath][tx_num]
1036					  [rate_section] >> shift) & 0xff;
1037
1038	return	tx_pwr_diff;
1039}
1040
1041static u8 _rtl8723be_get_txpower_index(struct ieee80211_hw *hw, u8 path,
1042				       u8 rate, u8 bandwidth, u8 channel)
1043{
1044	struct rtl_priv *rtlpriv = rtl_priv(hw);
1045	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1046	u8 index = (channel - 1);
1047	u8 txpower;
1048	u8 power_diff_byrate = 0;
1049
1050	if (channel > 14 || channel < 1) {
1051		index = 0;
1052		RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1053			 "Illegal channel!\n");
1054	}
1055	if (RX_HAL_IS_CCK_RATE(rate))
1056		txpower = rtlefuse->txpwrlevel_cck[path][index];
1057	else if (DESC92C_RATE6M <= rate)
1058		txpower = rtlefuse->txpwrlevel_ht40_1s[path][index];
1059	else
1060		RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1061			 "invalid rate\n");
1062
1063	if (DESC92C_RATE6M <= rate && rate <= DESC92C_RATE54M &&
1064	    !RX_HAL_IS_CCK_RATE(rate))
1065		txpower += rtlefuse->txpwr_legacyhtdiff[0][TX_1S];
1066
1067	if (bandwidth == HT_CHANNEL_WIDTH_20) {
1068		if (DESC92C_RATEMCS0 <= rate && rate <= DESC92C_RATEMCS15)
1069			txpower += rtlefuse->txpwr_ht20diff[0][TX_1S];
1070		if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15)
1071			txpower += rtlefuse->txpwr_ht20diff[0][TX_2S];
1072	} else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
1073		if (DESC92C_RATEMCS0 <= rate && rate <= DESC92C_RATEMCS15)
1074			txpower += rtlefuse->txpwr_ht40diff[0][TX_1S];
1075		if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15)
1076			txpower += rtlefuse->txpwr_ht40diff[0][TX_2S];
1077	}
1078
1079	if (rtlefuse->eeprom_regulatory != 2)
1080		power_diff_byrate = _rtl8723be_get_txpower_by_rate(hw,
1081								   BAND_ON_2_4G,
1082								   path, rate);
1083
1084	txpower += power_diff_byrate;
1085
1086	if (txpower > MAX_POWER_INDEX)
1087		txpower = MAX_POWER_INDEX;
1088
1089	return txpower;
1090}
1091
1092static void _rtl8723be_phy_set_txpower_index(struct ieee80211_hw *hw,
1093					     u8 power_index, u8 path, u8 rate)
1094{
1095	struct rtl_priv *rtlpriv = rtl_priv(hw);
1096	if (path == RF90_PATH_A) {
1097		switch (rate) {
1098		case DESC92C_RATE1M:
1099			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_CCK1_MCS32,
1100					       MASKBYTE1, power_index);
1101			break;
1102		case DESC92C_RATE2M:
1103			rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11,
1104					       MASKBYTE1, power_index);
1105			break;
1106		case DESC92C_RATE5_5M:
1107			rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11,
1108					       MASKBYTE2, power_index);
1109			break;
1110		case DESC92C_RATE11M:
1111			rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11,
1112					       MASKBYTE3, power_index);
1113			break;
1114
1115		case DESC92C_RATE6M:
1116			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1117					       MASKBYTE0, power_index);
1118			break;
1119		case DESC92C_RATE9M:
1120			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1121					       MASKBYTE1, power_index);
1122			break;
1123		case DESC92C_RATE12M:
1124			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1125					       MASKBYTE2, power_index);
1126			break;
1127		case DESC92C_RATE18M:
1128			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1129					       MASKBYTE3, power_index);
1130			break;
1131
1132		case DESC92C_RATE24M:
1133			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1134					       MASKBYTE0, power_index);
1135			break;
1136		case DESC92C_RATE36M:
1137			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1138					       MASKBYTE1, power_index);
1139			break;
1140		case DESC92C_RATE48M:
1141			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1142					       MASKBYTE2, power_index);
1143			break;
1144		case DESC92C_RATE54M:
1145			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1146					       MASKBYTE3, power_index);
1147			break;
1148
1149		case DESC92C_RATEMCS0:
1150			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1151					       MASKBYTE0, power_index);
1152			break;
1153		case DESC92C_RATEMCS1:
1154			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1155					       MASKBYTE1, power_index);
1156			break;
1157		case DESC92C_RATEMCS2:
1158			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1159					       MASKBYTE2, power_index);
1160			break;
1161		case DESC92C_RATEMCS3:
1162			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1163					       MASKBYTE3, power_index);
1164			break;
1165
1166		case DESC92C_RATEMCS4:
1167			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1168					       MASKBYTE0, power_index);
1169			break;
1170		case DESC92C_RATEMCS5:
1171			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1172					       MASKBYTE1, power_index);
1173			break;
1174		case DESC92C_RATEMCS6:
1175			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1176					       MASKBYTE2, power_index);
1177			break;
1178		case DESC92C_RATEMCS7:
1179			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1180					       MASKBYTE3, power_index);
1181			break;
1182
1183		case DESC92C_RATEMCS8:
1184			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1185					       MASKBYTE0, power_index);
1186			break;
1187		case DESC92C_RATEMCS9:
1188			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1189					       MASKBYTE1, power_index);
1190			break;
1191		case DESC92C_RATEMCS10:
1192			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1193					       MASKBYTE2, power_index);
1194			break;
1195		case DESC92C_RATEMCS11:
1196			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1197					       MASKBYTE3, power_index);
1198			break;
1199
1200		default:
1201			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid Rate!!\n");
1202			break;
1203		}
1204	} else {
1205		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid RFPath!!\n");
1206	}
1207}
1208
1209void rtl8723be_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
1210{
1211	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1212	u8 cck_rates[]  = {DESC92C_RATE1M, DESC92C_RATE2M,
1213			   DESC92C_RATE5_5M, DESC92C_RATE11M};
1214	u8 ofdm_rates[]  = {DESC92C_RATE6M, DESC92C_RATE9M,
1215			    DESC92C_RATE12M, DESC92C_RATE18M,
1216			    DESC92C_RATE24M, DESC92C_RATE36M,
1217			    DESC92C_RATE48M, DESC92C_RATE54M};
1218	u8 ht_rates_1t[]  = {DESC92C_RATEMCS0, DESC92C_RATEMCS1,
1219			     DESC92C_RATEMCS2, DESC92C_RATEMCS3,
1220			     DESC92C_RATEMCS4, DESC92C_RATEMCS5,
1221			     DESC92C_RATEMCS6, DESC92C_RATEMCS7};
1222	u8 i, size;
1223	u8 power_index;
1224
1225	if (!rtlefuse->txpwr_fromeprom)
1226		return;
1227
1228	size = sizeof(cck_rates) / sizeof(u8);
1229	for (i = 0; i < size; i++) {
1230		power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A,
1231					cck_rates[i],
1232					rtl_priv(hw)->phy.current_chan_bw,
1233					channel);
1234		_rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A,
1235						 cck_rates[i]);
1236	}
1237	size = sizeof(ofdm_rates) / sizeof(u8);
1238	for (i = 0; i < size; i++) {
1239		power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A,
1240					ofdm_rates[i],
1241					rtl_priv(hw)->phy.current_chan_bw,
1242					channel);
1243		_rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A,
1244						 ofdm_rates[i]);
1245	}
1246	size = sizeof(ht_rates_1t) / sizeof(u8);
1247	for (i = 0; i < size; i++) {
1248		power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A,
1249					ht_rates_1t[i],
1250					rtl_priv(hw)->phy.current_chan_bw,
1251					channel);
1252		_rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A,
1253						 ht_rates_1t[i]);
1254	}
1255}
1256
1257void rtl8723be_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
1258{
1259	struct rtl_priv *rtlpriv = rtl_priv(hw);
1260	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1261	enum io_type iotype;
1262
1263	if (!is_hal_stop(rtlhal)) {
1264		switch (operation) {
1265		case SCAN_OPT_BACKUP_BAND0:
1266			iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
1267			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1268						      (u8 *)&iotype);
1269
1270			break;
1271		case SCAN_OPT_RESTORE:
1272			iotype = IO_CMD_RESUME_DM_BY_SCAN;
1273			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1274						      (u8 *)&iotype);
1275			break;
1276		default:
1277			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1278				 "Unknown Scan Backup operation.\n");
1279			break;
1280		}
1281	}
1282}
1283
1284void rtl8723be_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
1285{
1286	struct rtl_priv *rtlpriv = rtl_priv(hw);
1287	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1288	struct rtl_phy *rtlphy = &rtlpriv->phy;
1289	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1290	u8 reg_bw_opmode;
1291	u8 reg_prsr_rsc;
1292
1293	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
1294		 "Switch to %s bandwidth\n",
1295		  rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
1296		  "20MHz" : "40MHz");
1297
1298	if (is_hal_stop(rtlhal)) {
1299		rtlphy->set_bwmode_inprogress = false;
1300		return;
1301	}
1302
1303	reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
1304	reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
1305
1306	switch (rtlphy->current_chan_bw) {
1307	case HT_CHANNEL_WIDTH_20:
1308		reg_bw_opmode |= BW_OPMODE_20MHZ;
1309		rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1310		break;
1311	case HT_CHANNEL_WIDTH_20_40:
1312		reg_bw_opmode &= ~BW_OPMODE_20MHZ;
1313		rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1314		reg_prsr_rsc = (reg_prsr_rsc & 0x90) |
1315			       (mac->cur_40_prime_sc << 5);
1316		rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
1317		break;
1318	default:
1319		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1320			 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
1321		break;
1322	}
1323
1324	switch (rtlphy->current_chan_bw) {
1325	case HT_CHANNEL_WIDTH_20:
1326		rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
1327		rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
1328	/*	rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1);*/
1329		break;
1330	case HT_CHANNEL_WIDTH_20_40:
1331		rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
1332		rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
1333
1334		rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
1335			      (mac->cur_40_prime_sc >> 1));
1336		rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
1337		/*rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0);*/
1338
1339		rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
1340			      (mac->cur_40_prime_sc ==
1341			       HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
1342		break;
1343	default:
1344		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1345			 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
1346		break;
1347	}
1348	rtl8723be_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
1349	rtlphy->set_bwmode_inprogress = false;
1350	RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, "\n");
1351}
1352
1353void rtl8723be_phy_set_bw_mode(struct ieee80211_hw *hw,
1354			    enum nl80211_channel_type ch_type)
1355{
1356	struct rtl_priv *rtlpriv = rtl_priv(hw);
1357	struct rtl_phy *rtlphy = &rtlpriv->phy;
1358	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1359	u8 tmp_bw = rtlphy->current_chan_bw;
1360
1361	if (rtlphy->set_bwmode_inprogress)
1362		return;
1363	rtlphy->set_bwmode_inprogress = true;
1364	if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1365		rtl8723be_phy_set_bw_mode_callback(hw);
1366	} else {
1367		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1368			 "false driver sleep or unload\n");
1369		rtlphy->set_bwmode_inprogress = false;
1370		rtlphy->current_chan_bw = tmp_bw;
1371	}
1372}
1373
1374void rtl8723be_phy_sw_chnl_callback(struct ieee80211_hw *hw)
1375{
1376	struct rtl_priv *rtlpriv = rtl_priv(hw);
1377	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1378	struct rtl_phy *rtlphy = &rtlpriv->phy;
1379	u32 delay;
1380
1381	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
1382		 "switch to channel%d\n", rtlphy->current_channel);
1383	if (is_hal_stop(rtlhal))
1384		return;
1385	do {
1386		if (!rtlphy->sw_chnl_inprogress)
1387			break;
1388		if (!_rtl8723be_phy_sw_chnl_step_by_step(hw,
1389							 rtlphy->current_channel,
1390							 &rtlphy->sw_chnl_stage,
1391							 &rtlphy->sw_chnl_step,
1392							 &delay)) {
1393			if (delay > 0)
1394				mdelay(delay);
1395			else
1396				continue;
1397		} else {
1398			rtlphy->sw_chnl_inprogress = false;
1399		}
1400		break;
1401	} while (true);
1402	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
1403}
1404
1405u8 rtl8723be_phy_sw_chnl(struct ieee80211_hw *hw)
1406{
1407	struct rtl_priv *rtlpriv = rtl_priv(hw);
1408	struct rtl_phy *rtlphy = &rtlpriv->phy;
1409	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1410
1411	if (rtlphy->sw_chnl_inprogress)
1412		return 0;
1413	if (rtlphy->set_bwmode_inprogress)
1414		return 0;
1415	RT_ASSERT((rtlphy->current_channel <= 14),
1416		  "WIRELESS_MODE_G but channel>14");
1417	rtlphy->sw_chnl_inprogress = true;
1418	rtlphy->sw_chnl_stage = 0;
1419	rtlphy->sw_chnl_step = 0;
1420	if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1421		rtl8723be_phy_sw_chnl_callback(hw);
1422		RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
1423			 "sw_chnl_inprogress false schdule workitem current channel %d\n",
1424			 rtlphy->current_channel);
1425		rtlphy->sw_chnl_inprogress = false;
1426	} else {
1427		RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
1428			 "sw_chnl_inprogress false driver sleep or unload\n");
1429		rtlphy->sw_chnl_inprogress = false;
1430	}
1431	return 1;
1432}
1433
1434static bool _rtl8723be_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
1435						u8 channel, u8 *stage,
1436						u8 *step, u32 *delay)
1437{
1438	struct rtl_priv *rtlpriv = rtl_priv(hw);
1439	struct rtl_phy *rtlphy = &rtlpriv->phy;
1440	struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];
1441	u32 precommoncmdcnt;
1442	struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];
1443	u32 postcommoncmdcnt;
1444	struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];
1445	u32 rfdependcmdcnt;
1446	struct swchnlcmd *currentcmd = NULL;
1447	u8 rfpath;
1448	u8 num_total_rfpath = rtlphy->num_total_rfpath;
1449
1450	precommoncmdcnt = 0;
1451	rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
1452					 MAX_PRECMD_CNT,
1453					 CMDID_SET_TXPOWEROWER_LEVEL,
1454					 0, 0, 0);
1455	rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
1456					 MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
1457
1458	postcommoncmdcnt = 0;
1459
1460	rtl8723_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
1461					 MAX_POSTCMD_CNT, CMDID_END,
1462					    0, 0, 0);
1463
1464	rfdependcmdcnt = 0;
1465
1466	RT_ASSERT((channel >= 1 && channel <= 14),
1467		  "illegal channel for Zebra: %d\n", channel);
1468
1469	rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
1470					 MAX_RFDEPENDCMD_CNT,
1471					 CMDID_RF_WRITEREG,
1472					 RF_CHNLBW, channel, 10);
1473
1474	rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
1475					 MAX_RFDEPENDCMD_CNT,
1476					    CMDID_END, 0, 0, 0);
1477
1478	do {
1479		switch (*stage) {
1480		case 0:
1481			currentcmd = &precommoncmd[*step];
1482			break;
1483		case 1:
1484			currentcmd = &rfdependcmd[*step];
1485			break;
1486		case 2:
1487			currentcmd = &postcommoncmd[*step];
1488			break;
1489		default:
1490			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1491				 "Invalid 'stage' = %d, Check it!\n", *stage);
1492			return true;
1493		}
1494
1495		if (currentcmd->cmdid == CMDID_END) {
1496			if ((*stage) == 2) {
1497				return true;
1498			} else {
1499				(*stage)++;
1500				(*step) = 0;
1501				continue;
1502			}
1503		}
1504
1505		switch (currentcmd->cmdid) {
1506		case CMDID_SET_TXPOWEROWER_LEVEL:
1507			rtl8723be_phy_set_txpower_level(hw, channel);
1508			break;
1509		case CMDID_WRITEPORT_ULONG:
1510			rtl_write_dword(rtlpriv, currentcmd->para1,
1511					currentcmd->para2);
1512			break;
1513		case CMDID_WRITEPORT_USHORT:
1514			rtl_write_word(rtlpriv, currentcmd->para1,
1515				       (u16)currentcmd->para2);
1516			break;
1517		case CMDID_WRITEPORT_UCHAR:
1518			rtl_write_byte(rtlpriv, currentcmd->para1,
1519				       (u8)currentcmd->para2);
1520			break;
1521		case CMDID_RF_WRITEREG:
1522			for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
1523				rtlphy->rfreg_chnlval[rfpath] =
1524				    ((rtlphy->rfreg_chnlval[rfpath] &
1525				      0xfffffc00) | currentcmd->para2);
1526
1527				rtl_set_rfreg(hw, (enum radio_path)rfpath,
1528					      currentcmd->para1,
1529					      RFREG_OFFSET_MASK,
1530					      rtlphy->rfreg_chnlval[rfpath]);
1531			}
1532			break;
1533		default:
1534			RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
1535				 "switch case not process\n");
1536			break;
1537		}
1538
1539		break;
1540	} while (true);
1541
1542	(*delay) = currentcmd->msdelay;
1543	(*step)++;
1544	return false;
1545}
1546
1547static u8 _rtl8723be_phy_path_a_iqk(struct ieee80211_hw *hw)
1548{
1549	u32 reg_eac, reg_e94, reg_e9c, tmp;
1550	u8 result = 0x00;
1551
1552	/* leave IQK mode */
1553	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1554	/* switch to path A */
1555	rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000000);
1556	/* enable path A PA in TXIQK mode */
1557	rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0);
1558	rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x20000);
1559	rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0003f);
1560	rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xc7f87);
1561
1562	/* 1. TX IQK */
1563	/* path-A IQK setting */
1564	/* IQK setting */
1565	rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
1566	rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1567	/* path-A IQK setting */
1568	rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1569	rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1570	rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1571	rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1572
1573	rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x821403ea);
1574	rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28160000);
1575	rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1576	rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1577	/* LO calibration setting */
1578	rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x00462911);
1579	/* enter IQK mode */
1580	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1581
1582	/* One shot, path A LOK & IQK */
1583	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1584	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1585
1586	mdelay(IQK_DELAY_TIME);
1587
1588	/* leave IQK mode */
1589	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1590
1591	/* Check failed */
1592	reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
1593	reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD);
1594	reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD);
1595
1596	if (!(reg_eac & BIT(28)) &&
1597	    (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1598	    (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1599		result |= 0x01;
1600	else /* if Tx not OK, ignore Rx */
1601		return result;
1602
1603	/* Allen 20131125 */
1604	tmp = (reg_e9c & 0x03FF0000) >> 16;
1605	if ((tmp & 0x200) > 0)
1606		tmp = 0x400 - tmp;
1607
1608	if (!(reg_eac & BIT(28)) &&
1609	    (((reg_e94 & 0x03FF0000) >> 16) < 0x110) &&
1610	    (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) &&
1611	    (tmp < 0xf))
1612		result |= 0x01;
1613	else /* if Tx not OK, ignore Rx */
1614		return result;
1615
1616	return result;
1617}
1618
1619/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
1620static u8 _rtl8723be_phy_path_a_rx_iqk(struct ieee80211_hw *hw)
1621{
1622	u32 reg_eac, reg_e94, reg_e9c, reg_ea4, u32tmp, tmp;
1623	u8 result = 0x00;
1624
1625	/* leave IQK mode */
1626	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1627
1628	/* switch to path A */
1629	rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000000);
1630
1631	/* 1 Get TXIMR setting */
1632	/* modify RXIQK mode table */
1633	rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x1);
1634	rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
1635	rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f);
1636	/* LNA2 off, PA on for Dcut */
1637	rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7fb7);
1638	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1639
1640	/* IQK setting */
1641	rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
1642	rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1643
1644	/* path-A IQK setting */
1645	rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1646	rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1647	rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1648	rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1649
1650	rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160ff0);
1651	rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28110000);
1652	rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1653	rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1654
1655	/* LO calibration setting */
1656	rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911);
1657
1658	/* enter IQK mode */
1659	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1660
1661	/* One shot, path A LOK & IQK */
1662	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1663	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1664
1665	mdelay(IQK_DELAY_TIME);
1666
1667	/* leave IQK mode */
1668	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1669
1670	/* Check failed */
1671	reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1672	reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD);
1673	reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD);
1674
1675	if (!(reg_eac & BIT(28)) &&
1676	    (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1677	    (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1678		result |= 0x01;
1679	else /* if Tx not OK, ignore Rx */
1680		return result;
1681
1682	/* Allen 20131125 */
1683	tmp = (reg_e9c & 0x03FF0000) >> 16;
1684	if ((tmp & 0x200) > 0)
1685		tmp = 0x400 - tmp;
1686
1687	if (!(reg_eac & BIT(28)) &&
1688	    (((reg_e94 & 0x03FF0000) >> 16) < 0x110) &&
1689	    (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) &&
1690	    (tmp < 0xf))
1691		result |= 0x01;
1692	else /* if Tx not OK, ignore Rx */
1693		return result;
1694
1695	u32tmp = 0x80007C00 | (reg_e94 & 0x3FF0000) |
1696		 ((reg_e9c & 0x3FF0000) >> 16);
1697	rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, u32tmp);
1698
1699	/* 1 RX IQK */
1700	/* modify RXIQK mode table */
1701	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1702	rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x1);
1703	rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
1704	rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f);
1705	/* LAN2 on, PA off for Dcut */
1706	rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7d77);
1707
1708	/* PA, PAD setting */
1709	rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0xf80);
1710	rtl_set_rfreg(hw, RF90_PATH_A, 0x55, RFREG_OFFSET_MASK, 0x4021f);
1711
1712	/* IQK setting */
1713	rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1714
1715	/* path-A IQK setting */
1716	rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1717	rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1718	rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1719	rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1720
1721	rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82110000);
1722	rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x2816001f);
1723	rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1724	rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1725
1726	/* LO calibration setting */
1727	rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a8d1);
1728
1729	/* enter IQK mode */
1730	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1731
1732	/* One shot, path A LOK & IQK */
1733	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1734	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1735
1736	mdelay(IQK_DELAY_TIME);
1737
1738	/* leave IQK mode */
1739	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1740
1741	/* Check failed */
1742	reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1743	reg_ea4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2, MASKDWORD);
1744
1745	/* leave IQK mode */
1746	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1747	rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0x780);
1748
1749	/* Allen 20131125 */
1750	tmp = (reg_eac & 0x03FF0000) >> 16;
1751		if ((tmp & 0x200) > 0)
1752			tmp = 0x400 - tmp;
1753	/* if Tx is OK, check whether Rx is OK */
1754	if (!(reg_eac & BIT(27)) &&
1755	    (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) &&
1756	    (((reg_eac & 0x03FF0000) >> 16) != 0x36))
1757		result |= 0x02;
1758	else if (!(reg_eac & BIT(27)) &&
1759		 (((reg_ea4 & 0x03FF0000) >> 16) < 0x110) &&
1760		 (((reg_ea4 & 0x03FF0000) >> 16) > 0xf0) &&
1761		 (tmp < 0xf))
1762		result |= 0x02;
1763
1764	return result;
1765}
1766
1767static u8 _rtl8723be_phy_path_b_iqk(struct ieee80211_hw *hw)
1768{
1769	u32 reg_eac, reg_e94, reg_e9c, tmp;
1770	u8 result = 0x00;
1771
1772	/* leave IQK mode */
1773	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1774	/* switch to path B */
1775	rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000280);
1776
1777	/* enable path B PA in TXIQK mode */
1778	rtl_set_rfreg(hw, RF90_PATH_A, 0xed, RFREG_OFFSET_MASK, 0x00020);
1779	rtl_set_rfreg(hw, RF90_PATH_A, 0x43, RFREG_OFFSET_MASK, 0x40fc1);
1780
1781	/* 1 Tx IQK */
1782	/* IQK setting */
1783	rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
1784	rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1785	/* path-A IQK setting */
1786	rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1787	rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1788	rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1789	rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1790
1791	rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x821403ea);
1792	rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28110000);
1793	rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1794	rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1795
1796	/* LO calibration setting */
1797	rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x00462911);
1798
1799	/* enter IQK mode */
1800	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1801
1802	/* One shot, path B LOK & IQK */
1803	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1804	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1805
1806	mdelay(IQK_DELAY_TIME);
1807
1808	/* leave IQK mode */
1809	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1810
1811	/* Check failed */
1812	reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1813	reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD);
1814	reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD);
1815
1816	if (!(reg_eac & BIT(28)) &&
1817	    (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1818	    (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1819		result |= 0x01;
1820	else
1821		return result;
1822
1823	/* Allen 20131125 */
1824	tmp = (reg_e9c & 0x03FF0000) >> 16;
1825	if ((tmp & 0x200) > 0)
1826		tmp = 0x400 - tmp;
1827
1828	if (!(reg_eac & BIT(28)) &&
1829	    (((reg_e94 & 0x03FF0000) >> 16) < 0x110) &&
1830	    (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) &&
1831	    (tmp < 0xf))
1832		result |= 0x01;
1833	else
1834		return result;
1835
1836	return result;
1837}
1838
1839/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
1840static u8 _rtl8723be_phy_path_b_rx_iqk(struct ieee80211_hw *hw)
1841{
1842	u32 reg_e94, reg_e9c, reg_ea4, reg_eac, u32tmp, tmp;
1843	u8 result = 0x00;
1844
1845	/* leave IQK mode */
1846	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1847	/* switch to path B */
1848	rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000280);
1849
1850	/* 1 Get TXIMR setting */
1851	/* modify RXIQK mode table */
1852	rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0);
1853	rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
1854	rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f);
1855	rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7ff7);
1856
1857	/* open PA S1 & SMIXER */
1858	rtl_set_rfreg(hw, RF90_PATH_A, 0xed, RFREG_OFFSET_MASK, 0x00020);
1859	rtl_set_rfreg(hw, RF90_PATH_A, 0x43, RFREG_OFFSET_MASK, 0x60fed);
1860
1861	/* IQK setting */
1862	rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
1863	rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1864
1865	/* path-B IQK setting */
1866	rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1867	rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1868	rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1869	rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1870
1871	rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160ff0);
1872	rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28110000);
1873	rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1874	rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1875
1876	/* LO calibration setting */
1877	rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911);
1878	/* enter IQK mode */
1879	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1880
1881	/* One shot, path B TXIQK @ RXIQK */
1882	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1883	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1884
1885	mdelay(IQK_DELAY_TIME);
1886
1887	/* leave IQK mode */
1888	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1889	/* Check failed */
1890	reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1891	reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD);
1892	reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD);
1893
1894	if (!(reg_eac & BIT(28)) &&
1895	    (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1896	    (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1897		result |= 0x01;
1898	else	/* if Tx not OK, ignore Rx */
1899		return result;
1900
1901	/* Allen 20131125 */
1902	tmp = (reg_e9c & 0x03FF0000) >> 16;
1903	if ((tmp & 0x200) > 0)
1904		tmp = 0x400 - tmp;
1905
1906	if (!(reg_eac & BIT(28)) &&
1907	    (((reg_e94 & 0x03FF0000) >> 16) < 0x110) &&
1908	    (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) &&
1909	    (tmp < 0xf))
1910		result |= 0x01;
1911	else
1912		return result;
1913
1914	u32tmp = 0x80007C00 | (reg_e94 & 0x3FF0000)  |
1915		 ((reg_e9c & 0x3FF0000) >> 16);
1916	rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, u32tmp);
1917
1918	/* 1 RX IQK */
1919
1920	/* <20121009, Kordan> RF Mode = 3 */
1921	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1922	rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x1);
1923	rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
1924	rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f);
1925	rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7d77);
1926	rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x0);
1927
1928	/* open PA S1 & close SMIXER */
1929	rtl_set_rfreg(hw, RF90_PATH_A, 0xed, RFREG_OFFSET_MASK, 0x00020);
1930	rtl_set_rfreg(hw, RF90_PATH_A, 0x43, RFREG_OFFSET_MASK, 0x60fbd);
1931
1932	/* IQK setting */
1933	rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1934
1935	/* path-B IQK setting */
1936	rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1937	rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1938	rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1939	rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1940
1941	rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82110000);
1942	rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x2816001f);
1943	rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1944	rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1945
1946	/* LO calibration setting */
1947	rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a8d1);
1948	/* enter IQK mode */
1949	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1950
1951	/* One shot, path B LOK & IQK */
1952	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1953	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1954
1955	mdelay(IQK_DELAY_TIME);
1956
1957	/* leave IQK mode */
1958	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1959	/* Check failed */
1960	reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1961	reg_ea4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2, MASKDWORD);
1962
1963	/* Allen 20131125 */
1964	tmp = (reg_eac & 0x03FF0000) >> 16;
1965	if ((tmp & 0x200) > 0)
1966		tmp = 0x400 - tmp;
1967
1968	/* if Tx is OK, check whether Rx is OK */
1969	if (!(reg_eac & BIT(27)) &&
1970	    (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) &&
1971	    (((reg_eac & 0x03FF0000) >> 16) != 0x36))
1972		result |= 0x02;
1973	else if (!(reg_eac & BIT(27)) &&
1974		 (((reg_ea4 & 0x03FF0000) >> 16) < 0x110) &&
1975		 (((reg_ea4 & 0x03FF0000) >> 16) > 0xf0) &&
1976		 (tmp < 0xf))
1977		result |= 0x02;
1978	else
1979		return result;
1980
1981	return result;
1982}
1983
1984static void _rtl8723be_phy_path_b_fill_iqk_matrix(struct ieee80211_hw *hw,
1985						  bool b_iqk_ok,
1986						  long result[][8],
1987						  u8 final_candidate,
1988						  bool btxonly)
1989{
1990	u32 oldval_1, x, tx1_a, reg;
1991	long y, tx1_c;
1992
1993	if (final_candidate == 0xFF) {
1994		return;
1995	} else if (b_iqk_ok) {
1996		oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE,
1997					  MASKDWORD) >> 22) & 0x3FF;
1998		x = result[final_candidate][4];
1999		if ((x & 0x00000200) != 0)
2000			x = x | 0xFFFFFC00;
2001		tx1_a = (x * oldval_1) >> 8;
2002		rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x3FF, tx1_a);
2003		rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(27),
2004			      ((x * oldval_1 >> 7) & 0x1));
2005		y = result[final_candidate][5];
2006		if ((y & 0x00000200) != 0)
2007			y = y | 0xFFFFFC00;
2008		tx1_c = (y * oldval_1) >> 8;
2009		rtl_set_bbreg(hw, ROFDM0_XDTXAFE, 0xF0000000,
2010			      ((tx1_c & 0x3C0) >> 6));
2011		rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x003F0000,
2012			      (tx1_c & 0x3F));
2013		rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(25),
2014			      ((y * oldval_1 >> 7) & 0x1));
2015		if (btxonly)
2016			return;
2017		reg = result[final_candidate][6];
2018		rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg);
2019		reg = result[final_candidate][7] & 0x3F;
2020		rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg);
2021		reg = (result[final_candidate][7] >> 6) & 0xF;
2022		/* rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg); */
2023	}
2024}
2025
2026static bool _rtl8723be_phy_simularity_compare(struct ieee80211_hw *hw,
2027					      long result[][8], u8 c1, u8 c2)
2028{
2029	u32 i, j, diff, simularity_bitmap, bound = 0;
2030
2031	u8 final_candidate[2] = {0xFF, 0xFF}; /* for path A and path B */
2032	bool bresult = true; /* is2t = true*/
2033	s32 tmp1 = 0, tmp2 = 0;
2034
2035	bound = 8;
2036
2037	simularity_bitmap = 0;
2038
2039	for (i = 0; i < bound; i++) {
2040		if ((i == 1) || (i == 3) || (i == 5) || (i == 7)) {
2041			if ((result[c1][i] & 0x00000200) != 0)
2042				tmp1 = result[c1][i] | 0xFFFFFC00;
2043			else
2044				tmp1 = result[c1][i];
2045
2046			if ((result[c2][i] & 0x00000200) != 0)
2047				tmp2 = result[c2][i] | 0xFFFFFC00;
2048			else
2049				tmp2 = result[c2][i];
2050		} else {
2051			tmp1 = result[c1][i];
2052			tmp2 = result[c2][i];
2053		}
2054
2055		diff = (tmp1 > tmp2) ? (tmp1 - tmp2) : (tmp2 - tmp1);
2056
2057		if (diff > MAX_TOLERANCE) {
2058			if ((i == 2 || i == 6) && !simularity_bitmap) {
2059				if (result[c1][i] + result[c1][i + 1] == 0)
2060					final_candidate[(i / 4)] = c2;
2061				else if (result[c2][i] + result[c2][i + 1] == 0)
2062					final_candidate[(i / 4)] = c1;
2063				else
2064					simularity_bitmap |= (1 << i);
2065			} else
2066				simularity_bitmap |= (1 << i);
2067		}
2068	}
2069
2070	if (simularity_bitmap == 0) {
2071		for (i = 0; i < (bound / 4); i++) {
2072			if (final_candidate[i] != 0xFF) {
2073				for (j = i * 4; j < (i + 1) * 4 - 2; j++)
2074					result[3][j] =
2075						result[final_candidate[i]][j];
2076				bresult = false;
2077			}
2078		}
2079		return bresult;
2080	} else {
2081		if (!(simularity_bitmap & 0x03)) { /* path A TX OK */
2082			for (i = 0; i < 2; i++)
2083				result[3][i] = result[c1][i];
2084		}
2085		if (!(simularity_bitmap & 0x0c)) { /* path A RX OK */
2086			for (i = 2; i < 4; i++)
2087				result[3][i] = result[c1][i];
2088		}
2089		if (!(simularity_bitmap & 0x30)) { /* path B TX OK */
2090			for (i = 4; i < 6; i++)
2091				result[3][i] = result[c1][i];
2092		}
2093		if (!(simularity_bitmap & 0xc0)) { /* path B RX OK */
2094			for (i = 6; i < 8; i++)
2095				result[3][i] = result[c1][i];
2096		}
2097		return false;
2098	}
2099}
2100
2101static void _rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw,
2102					long result[][8], u8 t, bool is2t)
2103{
2104	struct rtl_priv *rtlpriv = rtl_priv(hw);
2105	struct rtl_phy *rtlphy = &rtlpriv->phy;
2106	u32 i;
2107	u8 patha_ok, pathb_ok;
2108	u32 adda_reg[IQK_ADDA_REG_NUM] = {
2109		0x85c, 0xe6c, 0xe70, 0xe74,
2110		0xe78, 0xe7c, 0xe80, 0xe84,
2111		0xe88, 0xe8c, 0xed0, 0xed4,
2112		0xed8, 0xedc, 0xee0, 0xeec
2113	};
2114
2115	u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
2116		0x522, 0x550, 0x551, 0x040
2117	};
2118	u32 iqk_bb_reg[IQK_BB_REG_NUM] = {
2119		ROFDM0_TRXPATHENABLE, ROFDM0_TRMUXPAR,
2120		RFPGA0_XCD_RFINTERFACESW, 0xb68, 0xb6c,
2121		0x870, 0x860,
2122		0x864, 0xa04
2123	};
2124	const u32 retrycount = 2;
2125
2126	u32 path_sel_bb;/* path_sel_rf */
2127
2128	u8 tmp_reg_c50, tmp_reg_c58;
2129
2130	tmp_reg_c50 = rtl_get_bbreg(hw, 0xc50, MASKBYTE0);
2131	tmp_reg_c58 = rtl_get_bbreg(hw, 0xc58, MASKBYTE0);
2132
2133	if (t == 0) {
2134		rtl8723_save_adda_registers(hw, adda_reg,
2135					    rtlphy->adda_backup, 16);
2136		rtl8723_phy_save_mac_registers(hw, iqk_mac_reg,
2137					       rtlphy->iqk_mac_backup);
2138		rtl8723_save_adda_registers(hw, iqk_bb_reg,
2139					    rtlphy->iqk_bb_backup,
2140					    IQK_BB_REG_NUM);
2141	}
2142	rtl8723_phy_path_adda_on(hw, adda_reg, true, is2t);
2143	if (t == 0) {
2144		rtlphy->rfpi_enable = (u8)rtl_get_bbreg(hw,
2145						RFPGA0_XA_HSSIPARAMETER1,
2146						BIT(8));
2147	}
2148
2149	path_sel_bb = rtl_get_bbreg(hw, 0x948, MASKDWORD);
2150
2151	rtl8723_phy_mac_setting_calibration(hw, iqk_mac_reg,
2152					    rtlphy->iqk_mac_backup);
2153	/*BB Setting*/
2154	rtl_set_bbreg(hw, 0xa04, 0x0f000000, 0xf);
2155	rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600);
2156	rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4);
2157	rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000);
2158
2159	/* path A TX IQK */
2160	for (i = 0; i < retrycount; i++) {
2161		patha_ok = _rtl8723be_phy_path_a_iqk(hw);
2162		if (patha_ok == 0x01) {
2163			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2164				"Path A Tx IQK Success!!\n");
2165			result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) &
2166					0x3FF0000) >> 16;
2167			result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) &
2168					0x3FF0000) >> 16;
2169			break;
2170		} else {
2171			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2172				 "Path A Tx IQK Fail!!\n");
2173		}
2174	}
2175	/* path A RX IQK */
2176	for (i = 0; i < retrycount; i++) {
2177		patha_ok = _rtl8723be_phy_path_a_rx_iqk(hw);
2178		if (patha_ok == 0x03) {
2179			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2180				 "Path A Rx IQK Success!!\n");
2181			result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) &
2182					0x3FF0000) >> 16;
2183			result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) &
2184					0x3FF0000) >> 16;
2185			break;
2186		}
2187		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2188			 "Path A Rx IQK Fail!!\n");
2189	}
2190
2191	if (0x00 == patha_ok)
2192		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Path A IQK Fail!!\n");
2193
2194	if (is2t) {
2195		/* path B TX IQK */
2196		for (i = 0; i < retrycount; i++) {
2197			pathb_ok = _rtl8723be_phy_path_b_iqk(hw);
2198			if (pathb_ok == 0x01) {
2199				RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2200					 "Path B Tx IQK Success!!\n");
2201				result[t][4] = (rtl_get_bbreg(hw, 0xe94,
2202							      MASKDWORD) &
2203							      0x3FF0000) >> 16;
2204				result[t][5] = (rtl_get_bbreg(hw, 0xe9c,
2205							      MASKDWORD) &
2206							      0x3FF0000) >> 16;
2207				break;
2208			}
2209			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2210				 "Path B Tx IQK Fail!!\n");
2211		}
2212		/* path B RX IQK */
2213		for (i = 0; i < retrycount; i++) {
2214			pathb_ok = _rtl8723be_phy_path_b_rx_iqk(hw);
2215			if (pathb_ok == 0x03) {
2216				RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2217					 "Path B Rx IQK Success!!\n");
2218				result[t][6] = (rtl_get_bbreg(hw, 0xea4,
2219							      MASKDWORD) &
2220							      0x3FF0000) >> 16;
2221				result[t][7] = (rtl_get_bbreg(hw, 0xeac,
2222							      MASKDWORD) &
2223							      0x3FF0000) >> 16;
2224				break;
2225			}
2226			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2227				 "Path B Rx IQK Fail!!\n");
2228		}
2229	}
2230
2231	/* Back to BB mode, load original value */
2232	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0);
2233
2234	if (t != 0) {
2235		rtl8723_phy_reload_adda_registers(hw, adda_reg,
2236						  rtlphy->adda_backup, 16);
2237		rtl8723_phy_reload_mac_registers(hw, iqk_mac_reg,
2238						 rtlphy->iqk_mac_backup);
2239		rtl8723_phy_reload_adda_registers(hw, iqk_bb_reg,
2240						  rtlphy->iqk_bb_backup,
2241						  IQK_BB_REG_NUM);
2242
2243		rtl_set_bbreg(hw, 0x948, MASKDWORD, path_sel_bb);
2244		/*rtl_set_rfreg(hw, RF90_PATH_B, 0xb0, 0xfffff, path_sel_rf);*/
2245
2246		rtl_set_bbreg(hw, 0xc50, MASKBYTE0, 0x50);
2247		rtl_set_bbreg(hw, 0xc50, MASKBYTE0, tmp_reg_c50);
2248		if (is2t) {
2249			rtl_set_bbreg(hw, 0xc58, MASKBYTE0, 0x50);
2250			rtl_set_bbreg(hw, 0xc58, MASKBYTE0, tmp_reg_c58);
2251		}
2252		rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x01008c00);
2253		rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x01008c00);
2254	}
2255	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "8723be IQK Finish!!\n");
2256}
2257
2258static u8 _get_right_chnl_place_for_iqk(u8 chnl)
2259{
2260	u8 channel_all[TARGET_CHNL_NUM_2G_5G] = {
2261			1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
2262			13, 14, 36, 38, 40, 42, 44, 46,
2263			48, 50, 52, 54, 56, 58, 60, 62, 64,
2264			100, 102, 104, 106, 108, 110,
2265			112, 114, 116, 118, 120, 122,
2266			124, 126, 128, 130, 132, 134, 136,
2267			138, 140, 149, 151, 153, 155, 157,
2268			159, 161, 163, 165};
2269	u8 place = chnl;
2270
2271	if (chnl > 14) {
2272		for (place = 14; place < sizeof(channel_all); place++) {
2273			if (channel_all[place] == chnl)
2274				return place - 13;
2275		}
2276	}
2277	return 0;
2278}
2279
2280static void _rtl8723be_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
2281{
2282	u8 tmpreg;
2283	u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
2284	struct rtl_priv *rtlpriv = rtl_priv(hw);
2285
2286	tmpreg = rtl_read_byte(rtlpriv, 0xd03);
2287
2288	if ((tmpreg & 0x70) != 0)
2289		rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
2290	else
2291		rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
2292
2293	if ((tmpreg & 0x70) != 0) {
2294		rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS);
2295
2296		if (is2t)
2297			rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00,
2298						  MASK12BITS);
2299
2300		rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS,
2301			      (rf_a_mode & 0x8FFFF) | 0x10000);
2302
2303		if (is2t)
2304			rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
2305				      (rf_b_mode & 0x8FFFF) | 0x10000);
2306	}
2307	lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS);
2308
2309	rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, RFREG_OFFSET_MASK, 0xdfbe0);
2310	rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, 0x8c0a);
2311
2312	/* In order not to disturb BT music when wifi init.(1ant NIC only) */
2313	/*mdelay(100);*/
2314	/* In order not to disturb BT music when wifi init.(1ant NIC only) */
2315	mdelay(50);
2316
2317	rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, RFREG_OFFSET_MASK, 0xdffe0);
2318
2319	if ((tmpreg & 0x70) != 0) {
2320		rtl_write_byte(rtlpriv, 0xd03, tmpreg);
2321		rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode);
2322
2323		if (is2t)
2324			rtl_set_rfreg(hw, RF90_PATH_B, 0x00,
2325				      MASK12BITS, rf_b_mode);
2326	} else {
2327		rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
2328	}
2329RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
2330
2331}
2332
2333static void _rtl8723be_phy_set_rfpath_switch(struct ieee80211_hw *hw,
2334					     bool bmain, bool is2t)
2335{
2336	struct rtl_priv *rtlpriv = rtl_priv(hw);
2337	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
2338
2339	if (bmain) /* left antenna */
2340		rtl_set_bbreg(hw, 0x92C, MASKDWORD, 0x1);
2341	else
2342		rtl_set_bbreg(hw, 0x92C, MASKDWORD, 0x2);
2343}
2344
2345#undef IQK_ADDA_REG_NUM
2346#undef IQK_DELAY_TIME
2347/* IQK is merge from Merge Temp */
2348void rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
2349{
2350	struct rtl_priv *rtlpriv = rtl_priv(hw);
2351	struct rtl_phy *rtlphy = &rtlpriv->phy;
2352	long result[4][8];
2353	u8 i, final_candidate, idx;
2354	bool b_patha_ok, b_pathb_ok;
2355	long reg_e94, reg_e9c, reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4;
2356	long reg_ecc, reg_tmp = 0;
2357	bool is12simular, is13simular, is23simular;
2358	u32 iqk_bb_reg[9] = {
2359		ROFDM0_XARXIQIMBALANCE,
2360		ROFDM0_XBRXIQIMBALANCE,
2361		ROFDM0_ECCATHRESHOLD,
2362		ROFDM0_AGCRSSITABLE,
2363		ROFDM0_XATXIQIMBALANCE,
2364		ROFDM0_XBTXIQIMBALANCE,
2365		ROFDM0_XCTXAFE,
2366		ROFDM0_XDTXAFE,
2367		ROFDM0_RXIQEXTANTA
2368	};
2369	u32 path_sel_bb = 0; /* path_sel_rf = 0 */
2370
2371	if (rtlphy->lck_inprogress)
2372		return;
2373
2374	spin_lock(&rtlpriv->locks.iqk_lock);
2375	rtlphy->lck_inprogress = true;
2376	spin_unlock(&rtlpriv->locks.iqk_lock);
2377
2378	if (b_recovery) {
2379		rtl8723_phy_reload_adda_registers(hw, iqk_bb_reg,
2380						  rtlphy->iqk_bb_backup, 9);
2381		return;
2382	}
2383	/* Save RF Path */
2384	path_sel_bb = rtl_get_bbreg(hw, 0x948, MASKDWORD);
2385	/* path_sel_rf = rtl_get_rfreg(hw, RF90_PATH_A, 0xb0, 0xfffff); */
2386
2387	for (i = 0; i < 8; i++) {
2388		result[0][i] = 0;
2389		result[1][i] = 0;
2390		result[2][i] = 0;
2391		result[3][i] = 0;
2392	}
2393	final_candidate = 0xff;
2394	b_patha_ok = false;
2395	b_pathb_ok = false;
2396	is12simular = false;
2397	is23simular = false;
2398	is13simular = false;
2399	for (i = 0; i < 3; i++) {
2400		_rtl8723be_phy_iq_calibrate(hw, result, i, true);
2401		if (i == 1) {
2402			is12simular = _rtl8723be_phy_simularity_compare(hw,
2403									result,
2404									0, 1);
2405			if (is12simular) {
2406				final_candidate = 0;
2407				break;
2408			}
2409		}
2410		if (i == 2) {
2411			is13simular = _rtl8723be_phy_simularity_compare(hw,
2412									result,
2413									0, 2);
2414			if (is13simular) {
2415				final_candidate = 0;
2416				break;
2417			}
2418			is23simular = _rtl8723be_phy_simularity_compare(hw,
2419									result,
2420									1, 2);
2421			if (is23simular) {
2422				final_candidate = 1;
2423			} else {
2424				for (i = 0; i < 8; i++)
2425					reg_tmp += result[3][i];
2426
2427				if (reg_tmp != 0)
2428					final_candidate = 3;
2429				else
2430					final_candidate = 0xFF;
2431			}
2432		}
2433	}
2434	for (i = 0; i < 4; i++) {
2435		reg_e94 = result[i][0];
2436		reg_e9c = result[i][1];
2437		reg_ea4 = result[i][2];
2438		reg_eac = result[i][3];
2439		reg_eb4 = result[i][4];
2440		reg_ebc = result[i][5];
2441		reg_ec4 = result[i][6];
2442		reg_ecc = result[i][7];
2443	}
2444	if (final_candidate != 0xff) {
2445		reg_e94 = result[final_candidate][0];
2446		rtlphy->reg_e94 = reg_e94;
2447		reg_e9c = result[final_candidate][1];
2448		rtlphy->reg_e9c = reg_e9c;
2449		reg_ea4 = result[final_candidate][2];
2450		reg_eac = result[final_candidate][3];
2451		reg_eb4 = result[final_candidate][4];
2452		rtlphy->reg_eb4 = reg_eb4;
2453		reg_ebc = result[final_candidate][5];
2454		rtlphy->reg_ebc = reg_ebc;
2455		reg_ec4 = result[final_candidate][6];
2456		reg_ecc = result[final_candidate][7];
2457		b_patha_ok = true;
2458		b_pathb_ok = true;
2459	} else {
2460		rtlphy->reg_e94 = 0x100;
2461		rtlphy->reg_eb4 = 0x100;
2462		rtlphy->reg_e9c = 0x0;
2463		rtlphy->reg_ebc = 0x0;
2464	}
2465	if (reg_e94 != 0)
2466		rtl8723_phy_path_a_fill_iqk_matrix(hw, b_patha_ok, result,
2467						   final_candidate,
2468						   (reg_ea4 == 0));
2469	if (reg_eb4 != 0)
2470		_rtl8723be_phy_path_b_fill_iqk_matrix(hw, b_pathb_ok, result,
2471						      final_candidate,
2472						      (reg_ec4 == 0));
2473
2474	idx = _get_right_chnl_place_for_iqk(rtlphy->current_channel);
2475
2476	if (final_candidate < 4) {
2477		for (i = 0; i < IQK_MATRIX_REG_NUM; i++)
2478			rtlphy->iqk_matrix[idx].value[0][i] =
2479						result[final_candidate][i];
2480		rtlphy->iqk_matrix[idx].iqk_done = true;
2481
2482	}
2483	rtl8723_save_adda_registers(hw, iqk_bb_reg,
2484				    rtlphy->iqk_bb_backup, 9);
2485
2486	rtl_set_bbreg(hw, 0x948, MASKDWORD, path_sel_bb);
2487	/* rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, 0xfffff, path_sel_rf); */
2488
2489	spin_lock(&rtlpriv->locks.iqk_lock);
2490	rtlphy->lck_inprogress = false;
2491	spin_unlock(&rtlpriv->locks.iqk_lock);
2492}
2493
2494void rtl8723be_phy_lc_calibrate(struct ieee80211_hw *hw)
2495{
2496	struct rtl_priv *rtlpriv = rtl_priv(hw);
2497	struct rtl_phy *rtlphy = &rtlpriv->phy;
2498	struct rtl_hal *rtlhal = &rtlpriv->rtlhal;
2499	u32 timeout = 2000, timecount = 0;
2500
2501	while (rtlpriv->mac80211.act_scanning && timecount < timeout) {
2502		udelay(50);
2503		timecount += 50;
2504	}
2505
2506	rtlphy->lck_inprogress = true;
2507	RTPRINT(rtlpriv, FINIT, INIT_IQK,
2508		"LCK:Start!!! currentband %x delay %d ms\n",
2509		 rtlhal->current_bandtype, timecount);
2510
2511	_rtl8723be_phy_lc_calibrate(hw, false);
2512
2513	rtlphy->lck_inprogress = false;
2514}
2515
2516void rtl8723be_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
2517{
2518	_rtl8723be_phy_set_rfpath_switch(hw, bmain, true);
2519}
2520
2521bool rtl8723be_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
2522{
2523	struct rtl_priv *rtlpriv = rtl_priv(hw);
2524	struct rtl_phy *rtlphy = &rtlpriv->phy;
2525	bool b_postprocessing = false;
2526
2527	RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2528		 "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
2529		  iotype, rtlphy->set_io_inprogress);
2530	do {
2531		switch (iotype) {
2532		case IO_CMD_RESUME_DM_BY_SCAN:
2533			RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2534				 "[IO CMD] Resume DM after scan.\n");
2535			b_postprocessing = true;
2536			break;
2537		case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
2538			RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2539				 "[IO CMD] Pause DM before scan.\n");
2540			b_postprocessing = true;
2541			break;
2542		default:
2543			RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
2544				 "switch case not process\n");
2545			break;
2546		}
2547	} while (false);
2548	if (b_postprocessing && !rtlphy->set_io_inprogress) {
2549		rtlphy->set_io_inprogress = true;
2550		rtlphy->current_io_type = iotype;
2551	} else {
2552		return false;
2553	}
2554	rtl8723be_phy_set_io(hw);
2555	RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype);
2556	return true;
2557}
2558
2559static void rtl8723be_phy_set_io(struct ieee80211_hw *hw)
2560{
2561	struct rtl_priv *rtlpriv = rtl_priv(hw);
2562	struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
2563	struct rtl_phy *rtlphy = &rtlpriv->phy;
2564
2565	RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2566		 "--->Cmd(%#x), set_io_inprogress(%d)\n",
2567		  rtlphy->current_io_type, rtlphy->set_io_inprogress);
2568	switch (rtlphy->current_io_type) {
2569	case IO_CMD_RESUME_DM_BY_SCAN:
2570		dm_digtable->cur_igvalue = rtlphy->initgain_backup.xaagccore1;
2571		/*rtl92c_dm_write_dig(hw);*/
2572		rtl8723be_phy_set_txpower_level(hw, rtlphy->current_channel);
2573		rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x83);
2574		break;
2575	case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
2576		rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue;
2577		dm_digtable->cur_igvalue = 0x17;
2578		rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x40);
2579		break;
2580	default:
2581		RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
2582			 "switch case not process\n");
2583		break;
2584	}
2585	rtlphy->set_io_inprogress = false;
2586	RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2587		 "(%#x)\n", rtlphy->current_io_type);
2588}
2589
2590static void rtl8723be_phy_set_rf_on(struct ieee80211_hw *hw)
2591{
2592	struct rtl_priv *rtlpriv = rtl_priv(hw);
2593
2594	rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
2595	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2596	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2597	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2598	rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
2599}
2600
2601static void _rtl8723be_phy_set_rf_sleep(struct ieee80211_hw *hw)
2602{
2603	struct rtl_priv *rtlpriv = rtl_priv(hw);
2604
2605	rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
2606	rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
2607	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2608	rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
2609}
2610
2611static bool _rtl8723be_phy_set_rf_power_state(struct ieee80211_hw *hw,
2612					      enum rf_pwrstate rfpwr_state)
2613{
2614	struct rtl_priv *rtlpriv = rtl_priv(hw);
2615	struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
2616	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2617	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2618	bool bresult = true;
2619	u8 i, queue_id;
2620	struct rtl8192_tx_ring *ring = NULL;
2621
2622	switch (rfpwr_state) {
2623	case ERFON:
2624		if ((ppsc->rfpwr_state == ERFOFF) &&
2625		     RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
2626			bool rtstatus;
2627			u32 initializecount = 0;
2628			do {
2629				initializecount++;
2630				RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2631					 "IPS Set eRf nic enable\n");
2632				rtstatus = rtl_ps_enable_nic(hw);
2633			} while (!rtstatus && (initializecount < 10));
2634				RT_CLEAR_PS_LEVEL(ppsc,
2635						  RT_RF_OFF_LEVL_HALT_NIC);
2636		} else {
2637			RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2638				 "Set ERFON sleeped:%d ms\n",
2639				  jiffies_to_msecs(jiffies -
2640						   ppsc->last_sleep_jiffies));
2641			ppsc->last_awake_jiffies = jiffies;
2642			rtl8723be_phy_set_rf_on(hw);
2643		}
2644		if (mac->link_state == MAC80211_LINKED)
2645			rtlpriv->cfg->ops->led_control(hw, LED_CTL_LINK);
2646		else
2647			rtlpriv->cfg->ops->led_control(hw, LED_CTL_NO_LINK);
2648
2649		break;
2650
2651	case ERFOFF:
2652		for (queue_id = 0, i = 0;
2653		     queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
2654			ring = &pcipriv->dev.tx_ring[queue_id];
2655			/* Don't check BEACON Q.
2656			 * BEACON Q is always not empty,
2657			 * because '_rtl8723be_cmd_send_packet'
2658			 */
2659			if (queue_id == BEACON_QUEUE ||
2660			    skb_queue_len(&ring->queue) == 0) {
2661				queue_id++;
2662				continue;
2663			} else {
2664				RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2665					 "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
2666					 (i + 1), queue_id,
2667					 skb_queue_len(&ring->queue));
2668
2669				udelay(10);
2670				i++;
2671			}
2672			if (i >= MAX_DOZE_WAITING_TIMES_9x) {
2673				RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2674					 "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
2675					  MAX_DOZE_WAITING_TIMES_9x,
2676					  queue_id,
2677					  skb_queue_len(&ring->queue));
2678				break;
2679			}
2680		}
2681
2682		if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
2683			RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2684				 "IPS Set eRf nic disable\n");
2685			rtl_ps_disable_nic(hw);
2686			RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2687		} else {
2688			if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
2689				rtlpriv->cfg->ops->led_control(hw,
2690							       LED_CTL_NO_LINK);
2691			} else {
2692				rtlpriv->cfg->ops->led_control(hw,
2693							     LED_CTL_POWER_OFF);
2694			}
2695		}
2696		break;
2697
2698	case ERFSLEEP:
2699		if (ppsc->rfpwr_state == ERFOFF)
2700			break;
2701		for (queue_id = 0, i = 0;
2702		     queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
2703			ring = &pcipriv->dev.tx_ring[queue_id];
2704			if (skb_queue_len(&ring->queue) == 0) {
2705				queue_id++;
2706				continue;
2707			} else {
2708				RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2709					 "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
2710					 (i + 1), queue_id,
2711					 skb_queue_len(&ring->queue));
2712
2713				udelay(10);
2714				i++;
2715			}
2716			if (i >= MAX_DOZE_WAITING_TIMES_9x) {
2717				RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2718					 "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
2719					 MAX_DOZE_WAITING_TIMES_9x,
2720					 queue_id,
2721					 skb_queue_len(&ring->queue));
2722				break;
2723			}
2724		}
2725		RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2726			 "Set ERFSLEEP awaked:%d ms\n",
2727			  jiffies_to_msecs(jiffies -
2728					   ppsc->last_awake_jiffies));
2729		ppsc->last_sleep_jiffies = jiffies;
2730		_rtl8723be_phy_set_rf_sleep(hw);
2731		break;
2732
2733	default:
2734		RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
2735			 "switch case not process\n");
2736		bresult = false;
2737		break;
2738	}
2739	if (bresult)
2740		ppsc->rfpwr_state = rfpwr_state;
2741	return bresult;
2742}
2743
2744bool rtl8723be_phy_set_rf_power_state(struct ieee80211_hw *hw,
2745				      enum rf_pwrstate rfpwr_state)
2746{
2747	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2748
2749	bool bresult = false;
2750
2751	if (rfpwr_state == ppsc->rfpwr_state)
2752		return bresult;
2753	bresult = _rtl8723be_phy_set_rf_power_state(hw, rfpwr_state);
2754	return bresult;
2755}
2756