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
877static u8 _rtl8723be_phy_get_ratesection_intxpower_byrate(enum radio_path path,
878							  u8 rate)
879{
880	u8 rate_section = 0;
881
882	switch (rate) {
883	case DESC92C_RATE1M:
884		rate_section = 2;
885		break;
886
887	case DESC92C_RATE2M:
888	case DESC92C_RATE5_5M:
889		if (path == RF90_PATH_A)
890			rate_section = 3;
891		else if (path == RF90_PATH_B)
892			rate_section = 2;
893		break;
894
895	case DESC92C_RATE11M:
896		rate_section = 3;
897		break;
898
899	case DESC92C_RATE6M:
900	case DESC92C_RATE9M:
901	case DESC92C_RATE12M:
902	case DESC92C_RATE18M:
903		rate_section = 0;
904		break;
905
906	case DESC92C_RATE24M:
907	case DESC92C_RATE36M:
908	case DESC92C_RATE48M:
909	case DESC92C_RATE54M:
910		rate_section = 1;
911		break;
912
913	case DESC92C_RATEMCS0:
914	case DESC92C_RATEMCS1:
915	case DESC92C_RATEMCS2:
916	case DESC92C_RATEMCS3:
917		rate_section = 4;
918		break;
919
920	case DESC92C_RATEMCS4:
921	case DESC92C_RATEMCS5:
922	case DESC92C_RATEMCS6:
923	case DESC92C_RATEMCS7:
924		rate_section = 5;
925		break;
926
927	case DESC92C_RATEMCS8:
928	case DESC92C_RATEMCS9:
929	case DESC92C_RATEMCS10:
930	case DESC92C_RATEMCS11:
931		rate_section = 6;
932		break;
933
934	case DESC92C_RATEMCS12:
935	case DESC92C_RATEMCS13:
936	case DESC92C_RATEMCS14:
937	case DESC92C_RATEMCS15:
938		rate_section = 7;
939		break;
940
941	default:
942		RT_ASSERT(true, "Rate_Section is Illegal\n");
943		break;
944	}
945
946	return rate_section;
947}
948
949static u8 _rtl8723be_get_txpower_by_rate(struct ieee80211_hw *hw,
950					 enum band_type band,
951					 enum radio_path rfpath, u8 rate)
952{
953	struct rtl_priv *rtlpriv = rtl_priv(hw);
954	struct rtl_phy *rtlphy = &rtlpriv->phy;
955	u8 shift = 0, rate_section, tx_num;
956	char tx_pwr_diff = 0;
957
958	rate_section = _rtl8723be_phy_get_ratesection_intxpower_byrate(rfpath,
959								       rate);
960	tx_num = RF_TX_NUM_NONIMPLEMENT;
961
962	if (tx_num == RF_TX_NUM_NONIMPLEMENT) {
963		if (rate >= DESC92C_RATEMCS8 && rate <= DESC92C_RATEMCS15)
964			tx_num = RF_2TX;
965		else
966			tx_num = RF_1TX;
967	}
968
969	switch (rate) {
970	case DESC92C_RATE6M:
971	case DESC92C_RATE24M:
972	case DESC92C_RATEMCS0:
973	case DESC92C_RATEMCS4:
974	case DESC92C_RATEMCS8:
975	case DESC92C_RATEMCS12:
976		shift = 0;
977		break;
978	case DESC92C_RATE1M:
979	case DESC92C_RATE2M:
980	case DESC92C_RATE9M:
981	case DESC92C_RATE36M:
982	case DESC92C_RATEMCS1:
983	case DESC92C_RATEMCS5:
984	case DESC92C_RATEMCS9:
985	case DESC92C_RATEMCS13:
986		shift = 8;
987		break;
988	case DESC92C_RATE5_5M:
989	case DESC92C_RATE12M:
990	case DESC92C_RATE48M:
991	case DESC92C_RATEMCS2:
992	case DESC92C_RATEMCS6:
993	case DESC92C_RATEMCS10:
994	case DESC92C_RATEMCS14:
995		shift = 16;
996		break;
997	case DESC92C_RATE11M:
998	case DESC92C_RATE18M:
999	case DESC92C_RATE54M:
1000	case DESC92C_RATEMCS3:
1001	case DESC92C_RATEMCS7:
1002	case DESC92C_RATEMCS11:
1003	case DESC92C_RATEMCS15:
1004		shift = 24;
1005		break;
1006	default:
1007		RT_ASSERT(true, "Rate_Section is Illegal\n");
1008		break;
1009	}
1010	tx_pwr_diff = (u8)(rtlphy->tx_power_by_rate_offset[band][rfpath][tx_num]
1011					  [rate_section] >> shift) & 0xff;
1012
1013	return	tx_pwr_diff;
1014}
1015
1016static u8 _rtl8723be_get_txpower_index(struct ieee80211_hw *hw, u8 path,
1017				       u8 rate, u8 bandwidth, u8 channel)
1018{
1019	struct rtl_priv *rtlpriv = rtl_priv(hw);
1020	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1021	u8 index = (channel - 1);
1022	u8 txpower;
1023	u8 power_diff_byrate = 0;
1024
1025	if (channel > 14 || channel < 1) {
1026		index = 0;
1027		RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1028			 "Illegal channel!\n");
1029	}
1030	if (RX_HAL_IS_CCK_RATE(rate))
1031		txpower = rtlefuse->txpwrlevel_cck[path][index];
1032	else if (DESC92C_RATE6M <= rate)
1033		txpower = rtlefuse->txpwrlevel_ht40_1s[path][index];
1034	else
1035		RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1036			 "invalid rate\n");
1037
1038	if (DESC92C_RATE6M <= rate && rate <= DESC92C_RATE54M &&
1039	    !RX_HAL_IS_CCK_RATE(rate))
1040		txpower += rtlefuse->txpwr_legacyhtdiff[0][TX_1S];
1041
1042	if (bandwidth == HT_CHANNEL_WIDTH_20) {
1043		if (DESC92C_RATEMCS0 <= rate && rate <= DESC92C_RATEMCS15)
1044			txpower += rtlefuse->txpwr_ht20diff[0][TX_1S];
1045		if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15)
1046			txpower += rtlefuse->txpwr_ht20diff[0][TX_2S];
1047	} else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
1048		if (DESC92C_RATEMCS0 <= rate && rate <= DESC92C_RATEMCS15)
1049			txpower += rtlefuse->txpwr_ht40diff[0][TX_1S];
1050		if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15)
1051			txpower += rtlefuse->txpwr_ht40diff[0][TX_2S];
1052	}
1053
1054	if (rtlefuse->eeprom_regulatory != 2)
1055		power_diff_byrate = _rtl8723be_get_txpower_by_rate(hw,
1056								   BAND_ON_2_4G,
1057								   path, rate);
1058
1059	txpower += power_diff_byrate;
1060
1061	if (txpower > MAX_POWER_INDEX)
1062		txpower = MAX_POWER_INDEX;
1063
1064	return txpower;
1065}
1066
1067static void _rtl8723be_phy_set_txpower_index(struct ieee80211_hw *hw,
1068					     u8 power_index, u8 path, u8 rate)
1069{
1070	struct rtl_priv *rtlpriv = rtl_priv(hw);
1071	if (path == RF90_PATH_A) {
1072		switch (rate) {
1073		case DESC92C_RATE1M:
1074			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_CCK1_MCS32,
1075					       MASKBYTE1, power_index);
1076			break;
1077		case DESC92C_RATE2M:
1078			rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11,
1079					       MASKBYTE1, power_index);
1080			break;
1081		case DESC92C_RATE5_5M:
1082			rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11,
1083					       MASKBYTE2, power_index);
1084			break;
1085		case DESC92C_RATE11M:
1086			rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11,
1087					       MASKBYTE3, power_index);
1088			break;
1089
1090		case DESC92C_RATE6M:
1091			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1092					       MASKBYTE0, power_index);
1093			break;
1094		case DESC92C_RATE9M:
1095			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1096					       MASKBYTE1, power_index);
1097			break;
1098		case DESC92C_RATE12M:
1099			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1100					       MASKBYTE2, power_index);
1101			break;
1102		case DESC92C_RATE18M:
1103			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1104					       MASKBYTE3, power_index);
1105			break;
1106
1107		case DESC92C_RATE24M:
1108			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1109					       MASKBYTE0, power_index);
1110			break;
1111		case DESC92C_RATE36M:
1112			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1113					       MASKBYTE1, power_index);
1114			break;
1115		case DESC92C_RATE48M:
1116			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1117					       MASKBYTE2, power_index);
1118			break;
1119		case DESC92C_RATE54M:
1120			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1121					       MASKBYTE3, power_index);
1122			break;
1123
1124		case DESC92C_RATEMCS0:
1125			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1126					       MASKBYTE0, power_index);
1127			break;
1128		case DESC92C_RATEMCS1:
1129			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1130					       MASKBYTE1, power_index);
1131			break;
1132		case DESC92C_RATEMCS2:
1133			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1134					       MASKBYTE2, power_index);
1135			break;
1136		case DESC92C_RATEMCS3:
1137			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1138					       MASKBYTE3, power_index);
1139			break;
1140
1141		case DESC92C_RATEMCS4:
1142			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1143					       MASKBYTE0, power_index);
1144			break;
1145		case DESC92C_RATEMCS5:
1146			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1147					       MASKBYTE1, power_index);
1148			break;
1149		case DESC92C_RATEMCS6:
1150			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1151					       MASKBYTE2, power_index);
1152			break;
1153		case DESC92C_RATEMCS7:
1154			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1155					       MASKBYTE3, power_index);
1156			break;
1157
1158		case DESC92C_RATEMCS8:
1159			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1160					       MASKBYTE0, power_index);
1161			break;
1162		case DESC92C_RATEMCS9:
1163			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1164					       MASKBYTE1, power_index);
1165			break;
1166		case DESC92C_RATEMCS10:
1167			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1168					       MASKBYTE2, power_index);
1169			break;
1170		case DESC92C_RATEMCS11:
1171			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1172					       MASKBYTE3, power_index);
1173			break;
1174
1175		default:
1176			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid Rate!!\n");
1177			break;
1178		}
1179	} else {
1180		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid RFPath!!\n");
1181	}
1182}
1183
1184void rtl8723be_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
1185{
1186	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1187	u8 cck_rates[]  = {DESC92C_RATE1M, DESC92C_RATE2M,
1188			   DESC92C_RATE5_5M, DESC92C_RATE11M};
1189	u8 ofdm_rates[]  = {DESC92C_RATE6M, DESC92C_RATE9M,
1190			    DESC92C_RATE12M, DESC92C_RATE18M,
1191			    DESC92C_RATE24M, DESC92C_RATE36M,
1192			    DESC92C_RATE48M, DESC92C_RATE54M};
1193	u8 ht_rates_1t[]  = {DESC92C_RATEMCS0, DESC92C_RATEMCS1,
1194			     DESC92C_RATEMCS2, DESC92C_RATEMCS3,
1195			     DESC92C_RATEMCS4, DESC92C_RATEMCS5,
1196			     DESC92C_RATEMCS6, DESC92C_RATEMCS7};
1197	u8 i, size;
1198	u8 power_index;
1199
1200	if (!rtlefuse->txpwr_fromeprom)
1201		return;
1202
1203	size = sizeof(cck_rates) / sizeof(u8);
1204	for (i = 0; i < size; i++) {
1205		power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A,
1206					cck_rates[i],
1207					rtl_priv(hw)->phy.current_chan_bw,
1208					channel);
1209		_rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A,
1210						 cck_rates[i]);
1211	}
1212	size = sizeof(ofdm_rates) / sizeof(u8);
1213	for (i = 0; i < size; i++) {
1214		power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A,
1215					ofdm_rates[i],
1216					rtl_priv(hw)->phy.current_chan_bw,
1217					channel);
1218		_rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A,
1219						 ofdm_rates[i]);
1220	}
1221	size = sizeof(ht_rates_1t) / sizeof(u8);
1222	for (i = 0; i < size; i++) {
1223		power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A,
1224					ht_rates_1t[i],
1225					rtl_priv(hw)->phy.current_chan_bw,
1226					channel);
1227		_rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A,
1228						 ht_rates_1t[i]);
1229	}
1230}
1231
1232void rtl8723be_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
1233{
1234	struct rtl_priv *rtlpriv = rtl_priv(hw);
1235	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1236	enum io_type iotype;
1237
1238	if (!is_hal_stop(rtlhal)) {
1239		switch (operation) {
1240		case SCAN_OPT_BACKUP_BAND0:
1241			iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
1242			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1243						      (u8 *)&iotype);
1244
1245			break;
1246		case SCAN_OPT_RESTORE:
1247			iotype = IO_CMD_RESUME_DM_BY_SCAN;
1248			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1249						      (u8 *)&iotype);
1250			break;
1251		default:
1252			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1253				 "Unknown Scan Backup operation.\n");
1254			break;
1255		}
1256	}
1257}
1258
1259void rtl8723be_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
1260{
1261	struct rtl_priv *rtlpriv = rtl_priv(hw);
1262	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1263	struct rtl_phy *rtlphy = &rtlpriv->phy;
1264	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1265	u8 reg_bw_opmode;
1266	u8 reg_prsr_rsc;
1267
1268	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
1269		 "Switch to %s bandwidth\n",
1270		  rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
1271		  "20MHz" : "40MHz");
1272
1273	if (is_hal_stop(rtlhal)) {
1274		rtlphy->set_bwmode_inprogress = false;
1275		return;
1276	}
1277
1278	reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
1279	reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
1280
1281	switch (rtlphy->current_chan_bw) {
1282	case HT_CHANNEL_WIDTH_20:
1283		reg_bw_opmode |= BW_OPMODE_20MHZ;
1284		rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1285		break;
1286	case HT_CHANNEL_WIDTH_20_40:
1287		reg_bw_opmode &= ~BW_OPMODE_20MHZ;
1288		rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1289		reg_prsr_rsc = (reg_prsr_rsc & 0x90) |
1290			       (mac->cur_40_prime_sc << 5);
1291		rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
1292		break;
1293	default:
1294		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1295			 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
1296		break;
1297	}
1298
1299	switch (rtlphy->current_chan_bw) {
1300	case HT_CHANNEL_WIDTH_20:
1301		rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
1302		rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
1303	/*	rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1);*/
1304		break;
1305	case HT_CHANNEL_WIDTH_20_40:
1306		rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
1307		rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
1308
1309		rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
1310			      (mac->cur_40_prime_sc >> 1));
1311		rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
1312		/*rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0);*/
1313
1314		rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
1315			      (mac->cur_40_prime_sc ==
1316			       HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
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	rtl8723be_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
1324	rtlphy->set_bwmode_inprogress = false;
1325	RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, "\n");
1326}
1327
1328void rtl8723be_phy_set_bw_mode(struct ieee80211_hw *hw,
1329			    enum nl80211_channel_type ch_type)
1330{
1331	struct rtl_priv *rtlpriv = rtl_priv(hw);
1332	struct rtl_phy *rtlphy = &rtlpriv->phy;
1333	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1334	u8 tmp_bw = rtlphy->current_chan_bw;
1335
1336	if (rtlphy->set_bwmode_inprogress)
1337		return;
1338	rtlphy->set_bwmode_inprogress = true;
1339	if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1340		rtl8723be_phy_set_bw_mode_callback(hw);
1341	} else {
1342		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1343			 "false driver sleep or unload\n");
1344		rtlphy->set_bwmode_inprogress = false;
1345		rtlphy->current_chan_bw = tmp_bw;
1346	}
1347}
1348
1349void rtl8723be_phy_sw_chnl_callback(struct ieee80211_hw *hw)
1350{
1351	struct rtl_priv *rtlpriv = rtl_priv(hw);
1352	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1353	struct rtl_phy *rtlphy = &rtlpriv->phy;
1354	u32 delay;
1355
1356	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
1357		 "switch to channel%d\n", rtlphy->current_channel);
1358	if (is_hal_stop(rtlhal))
1359		return;
1360	do {
1361		if (!rtlphy->sw_chnl_inprogress)
1362			break;
1363		if (!_rtl8723be_phy_sw_chnl_step_by_step(hw,
1364							 rtlphy->current_channel,
1365							 &rtlphy->sw_chnl_stage,
1366							 &rtlphy->sw_chnl_step,
1367							 &delay)) {
1368			if (delay > 0)
1369				mdelay(delay);
1370			else
1371				continue;
1372		} else {
1373			rtlphy->sw_chnl_inprogress = false;
1374		}
1375		break;
1376	} while (true);
1377	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
1378}
1379
1380u8 rtl8723be_phy_sw_chnl(struct ieee80211_hw *hw)
1381{
1382	struct rtl_priv *rtlpriv = rtl_priv(hw);
1383	struct rtl_phy *rtlphy = &rtlpriv->phy;
1384	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1385
1386	if (rtlphy->sw_chnl_inprogress)
1387		return 0;
1388	if (rtlphy->set_bwmode_inprogress)
1389		return 0;
1390	RT_ASSERT((rtlphy->current_channel <= 14),
1391		  "WIRELESS_MODE_G but channel>14");
1392	rtlphy->sw_chnl_inprogress = true;
1393	rtlphy->sw_chnl_stage = 0;
1394	rtlphy->sw_chnl_step = 0;
1395	if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1396		rtl8723be_phy_sw_chnl_callback(hw);
1397		RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
1398			 "sw_chnl_inprogress false schdule workitem current channel %d\n",
1399			 rtlphy->current_channel);
1400		rtlphy->sw_chnl_inprogress = false;
1401	} else {
1402		RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
1403			 "sw_chnl_inprogress false driver sleep or unload\n");
1404		rtlphy->sw_chnl_inprogress = false;
1405	}
1406	return 1;
1407}
1408
1409static bool _rtl8723be_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
1410						u8 channel, u8 *stage,
1411						u8 *step, u32 *delay)
1412{
1413	struct rtl_priv *rtlpriv = rtl_priv(hw);
1414	struct rtl_phy *rtlphy = &rtlpriv->phy;
1415	struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];
1416	u32 precommoncmdcnt;
1417	struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];
1418	u32 postcommoncmdcnt;
1419	struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];
1420	u32 rfdependcmdcnt;
1421	struct swchnlcmd *currentcmd = NULL;
1422	u8 rfpath;
1423	u8 num_total_rfpath = rtlphy->num_total_rfpath;
1424
1425	precommoncmdcnt = 0;
1426	rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
1427					 MAX_PRECMD_CNT,
1428					 CMDID_SET_TXPOWEROWER_LEVEL,
1429					 0, 0, 0);
1430	rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
1431					 MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
1432
1433	postcommoncmdcnt = 0;
1434
1435	rtl8723_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
1436					 MAX_POSTCMD_CNT, CMDID_END,
1437					    0, 0, 0);
1438
1439	rfdependcmdcnt = 0;
1440
1441	RT_ASSERT((channel >= 1 && channel <= 14),
1442		  "illegal channel for Zebra: %d\n", channel);
1443
1444	rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
1445					 MAX_RFDEPENDCMD_CNT,
1446					 CMDID_RF_WRITEREG,
1447					 RF_CHNLBW, channel, 10);
1448
1449	rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
1450					 MAX_RFDEPENDCMD_CNT,
1451					    CMDID_END, 0, 0, 0);
1452
1453	do {
1454		switch (*stage) {
1455		case 0:
1456			currentcmd = &precommoncmd[*step];
1457			break;
1458		case 1:
1459			currentcmd = &rfdependcmd[*step];
1460			break;
1461		case 2:
1462			currentcmd = &postcommoncmd[*step];
1463			break;
1464		default:
1465			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1466				 "Invalid 'stage' = %d, Check it!\n", *stage);
1467			return true;
1468		}
1469
1470		if (currentcmd->cmdid == CMDID_END) {
1471			if ((*stage) == 2) {
1472				return true;
1473			} else {
1474				(*stage)++;
1475				(*step) = 0;
1476				continue;
1477			}
1478		}
1479
1480		switch (currentcmd->cmdid) {
1481		case CMDID_SET_TXPOWEROWER_LEVEL:
1482			rtl8723be_phy_set_txpower_level(hw, channel);
1483			break;
1484		case CMDID_WRITEPORT_ULONG:
1485			rtl_write_dword(rtlpriv, currentcmd->para1,
1486					currentcmd->para2);
1487			break;
1488		case CMDID_WRITEPORT_USHORT:
1489			rtl_write_word(rtlpriv, currentcmd->para1,
1490				       (u16)currentcmd->para2);
1491			break;
1492		case CMDID_WRITEPORT_UCHAR:
1493			rtl_write_byte(rtlpriv, currentcmd->para1,
1494				       (u8)currentcmd->para2);
1495			break;
1496		case CMDID_RF_WRITEREG:
1497			for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
1498				rtlphy->rfreg_chnlval[rfpath] =
1499				    ((rtlphy->rfreg_chnlval[rfpath] &
1500				      0xfffffc00) | currentcmd->para2);
1501
1502				rtl_set_rfreg(hw, (enum radio_path)rfpath,
1503					      currentcmd->para1,
1504					      RFREG_OFFSET_MASK,
1505					      rtlphy->rfreg_chnlval[rfpath]);
1506			}
1507			break;
1508		default:
1509			RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
1510				 "switch case not process\n");
1511			break;
1512		}
1513
1514		break;
1515	} while (true);
1516
1517	(*delay) = currentcmd->msdelay;
1518	(*step)++;
1519	return false;
1520}
1521
1522static u8 _rtl8723be_phy_path_a_iqk(struct ieee80211_hw *hw)
1523{
1524	u32 reg_eac, reg_e94, reg_e9c, tmp;
1525	u8 result = 0x00;
1526
1527	/* leave IQK mode */
1528	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1529	/* switch to path A */
1530	rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000000);
1531	/* enable path A PA in TXIQK mode */
1532	rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0);
1533	rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x20000);
1534	rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0003f);
1535	rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xc7f87);
1536
1537	/* 1. TX IQK */
1538	/* path-A IQK setting */
1539	/* IQK setting */
1540	rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
1541	rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1542	/* path-A IQK setting */
1543	rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1544	rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1545	rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1546	rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1547
1548	rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x821403ea);
1549	rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28160000);
1550	rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1551	rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1552	/* LO calibration setting */
1553	rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x00462911);
1554	/* enter IQK mode */
1555	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1556
1557	/* One shot, path A LOK & IQK */
1558	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1559	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1560
1561	mdelay(IQK_DELAY_TIME);
1562
1563	/* leave IQK mode */
1564	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1565
1566	/* Check failed */
1567	reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
1568	reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD);
1569	reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD);
1570
1571	if (!(reg_eac & BIT(28)) &&
1572	    (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1573	    (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1574		result |= 0x01;
1575	else /* if Tx not OK, ignore Rx */
1576		return result;
1577
1578	/* Allen 20131125 */
1579	tmp = (reg_e9c & 0x03FF0000) >> 16;
1580	if ((tmp & 0x200) > 0)
1581		tmp = 0x400 - tmp;
1582
1583	if (!(reg_eac & BIT(28)) &&
1584	    (((reg_e94 & 0x03FF0000) >> 16) < 0x110) &&
1585	    (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) &&
1586	    (tmp < 0xf))
1587		result |= 0x01;
1588	else /* if Tx not OK, ignore Rx */
1589		return result;
1590
1591	return result;
1592}
1593
1594/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
1595static u8 _rtl8723be_phy_path_a_rx_iqk(struct ieee80211_hw *hw)
1596{
1597	u32 reg_eac, reg_e94, reg_e9c, reg_ea4, u32tmp, tmp;
1598	u8 result = 0x00;
1599
1600	/* leave IQK mode */
1601	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1602
1603	/* switch to path A */
1604	rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000000);
1605
1606	/* 1 Get TXIMR setting */
1607	/* modify RXIQK mode table */
1608	rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x1);
1609	rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
1610	rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f);
1611	/* LNA2 off, PA on for Dcut */
1612	rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7fb7);
1613	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1614
1615	/* IQK setting */
1616	rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
1617	rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1618
1619	/* path-A IQK setting */
1620	rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1621	rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1622	rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1623	rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1624
1625	rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160ff0);
1626	rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28110000);
1627	rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1628	rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1629
1630	/* LO calibration setting */
1631	rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911);
1632
1633	/* enter IQK mode */
1634	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1635
1636	/* One shot, path A LOK & IQK */
1637	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1638	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1639
1640	mdelay(IQK_DELAY_TIME);
1641
1642	/* leave IQK mode */
1643	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1644
1645	/* Check failed */
1646	reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1647	reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD);
1648	reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD);
1649
1650	if (!(reg_eac & BIT(28)) &&
1651	    (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1652	    (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1653		result |= 0x01;
1654	else /* if Tx not OK, ignore Rx */
1655		return result;
1656
1657	/* Allen 20131125 */
1658	tmp = (reg_e9c & 0x03FF0000) >> 16;
1659	if ((tmp & 0x200) > 0)
1660		tmp = 0x400 - tmp;
1661
1662	if (!(reg_eac & BIT(28)) &&
1663	    (((reg_e94 & 0x03FF0000) >> 16) < 0x110) &&
1664	    (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) &&
1665	    (tmp < 0xf))
1666		result |= 0x01;
1667	else /* if Tx not OK, ignore Rx */
1668		return result;
1669
1670	u32tmp = 0x80007C00 | (reg_e94 & 0x3FF0000) |
1671		 ((reg_e9c & 0x3FF0000) >> 16);
1672	rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, u32tmp);
1673
1674	/* 1 RX IQK */
1675	/* modify RXIQK mode table */
1676	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1677	rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x1);
1678	rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
1679	rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f);
1680	/* LAN2 on, PA off for Dcut */
1681	rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7d77);
1682
1683	/* PA, PAD setting */
1684	rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0xf80);
1685	rtl_set_rfreg(hw, RF90_PATH_A, 0x55, RFREG_OFFSET_MASK, 0x4021f);
1686
1687	/* IQK setting */
1688	rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1689
1690	/* path-A IQK setting */
1691	rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1692	rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1693	rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1694	rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1695
1696	rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82110000);
1697	rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x2816001f);
1698	rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1699	rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1700
1701	/* LO calibration setting */
1702	rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a8d1);
1703
1704	/* enter IQK mode */
1705	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1706
1707	/* One shot, path A LOK & IQK */
1708	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1709	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1710
1711	mdelay(IQK_DELAY_TIME);
1712
1713	/* leave IQK mode */
1714	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1715
1716	/* Check failed */
1717	reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1718	reg_ea4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2, MASKDWORD);
1719
1720	/* leave IQK mode */
1721	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1722	rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0x780);
1723
1724	/* Allen 20131125 */
1725	tmp = (reg_eac & 0x03FF0000) >> 16;
1726		if ((tmp & 0x200) > 0)
1727			tmp = 0x400 - tmp;
1728	/* if Tx is OK, check whether Rx is OK */
1729	if (!(reg_eac & BIT(27)) &&
1730	    (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) &&
1731	    (((reg_eac & 0x03FF0000) >> 16) != 0x36))
1732		result |= 0x02;
1733	else if (!(reg_eac & BIT(27)) &&
1734		 (((reg_ea4 & 0x03FF0000) >> 16) < 0x110) &&
1735		 (((reg_ea4 & 0x03FF0000) >> 16) > 0xf0) &&
1736		 (tmp < 0xf))
1737		result |= 0x02;
1738
1739	return result;
1740}
1741
1742static u8 _rtl8723be_phy_path_b_iqk(struct ieee80211_hw *hw)
1743{
1744	u32 reg_eac, reg_e94, reg_e9c, tmp;
1745	u8 result = 0x00;
1746
1747	/* leave IQK mode */
1748	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1749	/* switch to path B */
1750	rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000280);
1751
1752	/* enable path B PA in TXIQK mode */
1753	rtl_set_rfreg(hw, RF90_PATH_A, 0xed, RFREG_OFFSET_MASK, 0x00020);
1754	rtl_set_rfreg(hw, RF90_PATH_A, 0x43, RFREG_OFFSET_MASK, 0x40fc1);
1755
1756	/* 1 Tx IQK */
1757	/* IQK setting */
1758	rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
1759	rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1760	/* path-A IQK setting */
1761	rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1762	rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1763	rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1764	rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1765
1766	rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x821403ea);
1767	rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28110000);
1768	rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1769	rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1770
1771	/* LO calibration setting */
1772	rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x00462911);
1773
1774	/* enter IQK mode */
1775	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1776
1777	/* One shot, path B LOK & IQK */
1778	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1779	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1780
1781	mdelay(IQK_DELAY_TIME);
1782
1783	/* leave IQK mode */
1784	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1785
1786	/* Check failed */
1787	reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1788	reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD);
1789	reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD);
1790
1791	if (!(reg_eac & BIT(28)) &&
1792	    (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1793	    (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1794		result |= 0x01;
1795	else
1796		return result;
1797
1798	/* Allen 20131125 */
1799	tmp = (reg_e9c & 0x03FF0000) >> 16;
1800	if ((tmp & 0x200) > 0)
1801		tmp = 0x400 - tmp;
1802
1803	if (!(reg_eac & BIT(28)) &&
1804	    (((reg_e94 & 0x03FF0000) >> 16) < 0x110) &&
1805	    (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) &&
1806	    (tmp < 0xf))
1807		result |= 0x01;
1808	else
1809		return result;
1810
1811	return result;
1812}
1813
1814/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
1815static u8 _rtl8723be_phy_path_b_rx_iqk(struct ieee80211_hw *hw)
1816{
1817	u32 reg_e94, reg_e9c, reg_ea4, reg_eac, u32tmp, tmp;
1818	u8 result = 0x00;
1819
1820	/* leave IQK mode */
1821	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1822	/* switch to path B */
1823	rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000280);
1824
1825	/* 1 Get TXIMR setting */
1826	/* modify RXIQK mode table */
1827	rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0);
1828	rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
1829	rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f);
1830	rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7ff7);
1831
1832	/* open PA S1 & SMIXER */
1833	rtl_set_rfreg(hw, RF90_PATH_A, 0xed, RFREG_OFFSET_MASK, 0x00020);
1834	rtl_set_rfreg(hw, RF90_PATH_A, 0x43, RFREG_OFFSET_MASK, 0x60fed);
1835
1836	/* IQK setting */
1837	rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
1838	rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1839
1840	/* path-B IQK setting */
1841	rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1842	rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1843	rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1844	rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1845
1846	rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160ff0);
1847	rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28110000);
1848	rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1849	rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1850
1851	/* LO calibration setting */
1852	rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911);
1853	/* enter IQK mode */
1854	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1855
1856	/* One shot, path B TXIQK @ RXIQK */
1857	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1858	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1859
1860	mdelay(IQK_DELAY_TIME);
1861
1862	/* leave IQK mode */
1863	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1864	/* Check failed */
1865	reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1866	reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD);
1867	reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD);
1868
1869	if (!(reg_eac & BIT(28)) &&
1870	    (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1871	    (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1872		result |= 0x01;
1873	else	/* if Tx not OK, ignore Rx */
1874		return result;
1875
1876	/* Allen 20131125 */
1877	tmp = (reg_e9c & 0x03FF0000) >> 16;
1878	if ((tmp & 0x200) > 0)
1879		tmp = 0x400 - tmp;
1880
1881	if (!(reg_eac & BIT(28)) &&
1882	    (((reg_e94 & 0x03FF0000) >> 16) < 0x110) &&
1883	    (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) &&
1884	    (tmp < 0xf))
1885		result |= 0x01;
1886	else
1887		return result;
1888
1889	u32tmp = 0x80007C00 | (reg_e94 & 0x3FF0000)  |
1890		 ((reg_e9c & 0x3FF0000) >> 16);
1891	rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, u32tmp);
1892
1893	/* 1 RX IQK */
1894
1895	/* <20121009, Kordan> RF Mode = 3 */
1896	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1897	rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x1);
1898	rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
1899	rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f);
1900	rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7d77);
1901	rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x0);
1902
1903	/* open PA S1 & close SMIXER */
1904	rtl_set_rfreg(hw, RF90_PATH_A, 0xed, RFREG_OFFSET_MASK, 0x00020);
1905	rtl_set_rfreg(hw, RF90_PATH_A, 0x43, RFREG_OFFSET_MASK, 0x60fbd);
1906
1907	/* IQK setting */
1908	rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1909
1910	/* path-B IQK setting */
1911	rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1912	rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1913	rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1914	rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1915
1916	rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82110000);
1917	rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x2816001f);
1918	rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1919	rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1920
1921	/* LO calibration setting */
1922	rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a8d1);
1923	/* enter IQK mode */
1924	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1925
1926	/* One shot, path B LOK & IQK */
1927	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1928	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1929
1930	mdelay(IQK_DELAY_TIME);
1931
1932	/* leave IQK mode */
1933	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1934	/* Check failed */
1935	reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1936	reg_ea4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2, MASKDWORD);
1937
1938	/* Allen 20131125 */
1939	tmp = (reg_eac & 0x03FF0000) >> 16;
1940	if ((tmp & 0x200) > 0)
1941		tmp = 0x400 - tmp;
1942
1943	/* if Tx is OK, check whether Rx is OK */
1944	if (!(reg_eac & BIT(27)) &&
1945	    (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) &&
1946	    (((reg_eac & 0x03FF0000) >> 16) != 0x36))
1947		result |= 0x02;
1948	else if (!(reg_eac & BIT(27)) &&
1949		 (((reg_ea4 & 0x03FF0000) >> 16) < 0x110) &&
1950		 (((reg_ea4 & 0x03FF0000) >> 16) > 0xf0) &&
1951		 (tmp < 0xf))
1952		result |= 0x02;
1953	else
1954		return result;
1955
1956	return result;
1957}
1958
1959static void _rtl8723be_phy_path_b_fill_iqk_matrix(struct ieee80211_hw *hw,
1960						  bool b_iqk_ok,
1961						  long result[][8],
1962						  u8 final_candidate,
1963						  bool btxonly)
1964{
1965	u32 oldval_1, x, tx1_a, reg;
1966	long y, tx1_c;
1967
1968	if (final_candidate == 0xFF) {
1969		return;
1970	} else if (b_iqk_ok) {
1971		oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE,
1972					  MASKDWORD) >> 22) & 0x3FF;
1973		x = result[final_candidate][4];
1974		if ((x & 0x00000200) != 0)
1975			x = x | 0xFFFFFC00;
1976		tx1_a = (x * oldval_1) >> 8;
1977		rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x3FF, tx1_a);
1978		rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(27),
1979			      ((x * oldval_1 >> 7) & 0x1));
1980		y = result[final_candidate][5];
1981		if ((y & 0x00000200) != 0)
1982			y = y | 0xFFFFFC00;
1983		tx1_c = (y * oldval_1) >> 8;
1984		rtl_set_bbreg(hw, ROFDM0_XDTXAFE, 0xF0000000,
1985			      ((tx1_c & 0x3C0) >> 6));
1986		rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x003F0000,
1987			      (tx1_c & 0x3F));
1988		rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(25),
1989			      ((y * oldval_1 >> 7) & 0x1));
1990		if (btxonly)
1991			return;
1992		reg = result[final_candidate][6];
1993		rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg);
1994		reg = result[final_candidate][7] & 0x3F;
1995		rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg);
1996		reg = (result[final_candidate][7] >> 6) & 0xF;
1997		/* rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg); */
1998	}
1999}
2000
2001static bool _rtl8723be_phy_simularity_compare(struct ieee80211_hw *hw,
2002					      long result[][8], u8 c1, u8 c2)
2003{
2004	u32 i, j, diff, simularity_bitmap, bound = 0;
2005
2006	u8 final_candidate[2] = {0xFF, 0xFF}; /* for path A and path B */
2007	bool bresult = true; /* is2t = true*/
2008	s32 tmp1 = 0, tmp2 = 0;
2009
2010	bound = 8;
2011
2012	simularity_bitmap = 0;
2013
2014	for (i = 0; i < bound; i++) {
2015		if ((i == 1) || (i == 3) || (i == 5) || (i == 7)) {
2016			if ((result[c1][i] & 0x00000200) != 0)
2017				tmp1 = result[c1][i] | 0xFFFFFC00;
2018			else
2019				tmp1 = result[c1][i];
2020
2021			if ((result[c2][i] & 0x00000200) != 0)
2022				tmp2 = result[c2][i] | 0xFFFFFC00;
2023			else
2024				tmp2 = result[c2][i];
2025		} else {
2026			tmp1 = result[c1][i];
2027			tmp2 = result[c2][i];
2028		}
2029
2030		diff = (tmp1 > tmp2) ? (tmp1 - tmp2) : (tmp2 - tmp1);
2031
2032		if (diff > MAX_TOLERANCE) {
2033			if ((i == 2 || i == 6) && !simularity_bitmap) {
2034				if (result[c1][i] + result[c1][i + 1] == 0)
2035					final_candidate[(i / 4)] = c2;
2036				else if (result[c2][i] + result[c2][i + 1] == 0)
2037					final_candidate[(i / 4)] = c1;
2038				else
2039					simularity_bitmap |= (1 << i);
2040			} else
2041				simularity_bitmap |= (1 << i);
2042		}
2043	}
2044
2045	if (simularity_bitmap == 0) {
2046		for (i = 0; i < (bound / 4); i++) {
2047			if (final_candidate[i] != 0xFF) {
2048				for (j = i * 4; j < (i + 1) * 4 - 2; j++)
2049					result[3][j] =
2050						result[final_candidate[i]][j];
2051				bresult = false;
2052			}
2053		}
2054		return bresult;
2055	} else {
2056		if (!(simularity_bitmap & 0x03)) { /* path A TX OK */
2057			for (i = 0; i < 2; i++)
2058				result[3][i] = result[c1][i];
2059		}
2060		if (!(simularity_bitmap & 0x0c)) { /* path A RX OK */
2061			for (i = 2; i < 4; i++)
2062				result[3][i] = result[c1][i];
2063		}
2064		if (!(simularity_bitmap & 0x30)) { /* path B TX OK */
2065			for (i = 4; i < 6; i++)
2066				result[3][i] = result[c1][i];
2067		}
2068		if (!(simularity_bitmap & 0xc0)) { /* path B RX OK */
2069			for (i = 6; i < 8; i++)
2070				result[3][i] = result[c1][i];
2071		}
2072		return false;
2073	}
2074}
2075
2076static void _rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw,
2077					long result[][8], u8 t, bool is2t)
2078{
2079	struct rtl_priv *rtlpriv = rtl_priv(hw);
2080	struct rtl_phy *rtlphy = &rtlpriv->phy;
2081	u32 i;
2082	u8 patha_ok, pathb_ok;
2083	u32 adda_reg[IQK_ADDA_REG_NUM] = {
2084		0x85c, 0xe6c, 0xe70, 0xe74,
2085		0xe78, 0xe7c, 0xe80, 0xe84,
2086		0xe88, 0xe8c, 0xed0, 0xed4,
2087		0xed8, 0xedc, 0xee0, 0xeec
2088	};
2089
2090	u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
2091		0x522, 0x550, 0x551, 0x040
2092	};
2093	u32 iqk_bb_reg[IQK_BB_REG_NUM] = {
2094		ROFDM0_TRXPATHENABLE, ROFDM0_TRMUXPAR,
2095		RFPGA0_XCD_RFINTERFACESW, 0xb68, 0xb6c,
2096		0x870, 0x860,
2097		0x864, 0xa04
2098	};
2099	const u32 retrycount = 2;
2100
2101	u32 path_sel_bb;/* path_sel_rf */
2102
2103	u8 tmp_reg_c50, tmp_reg_c58;
2104
2105	tmp_reg_c50 = rtl_get_bbreg(hw, 0xc50, MASKBYTE0);
2106	tmp_reg_c58 = rtl_get_bbreg(hw, 0xc58, MASKBYTE0);
2107
2108	if (t == 0) {
2109		rtl8723_save_adda_registers(hw, adda_reg,
2110					    rtlphy->adda_backup, 16);
2111		rtl8723_phy_save_mac_registers(hw, iqk_mac_reg,
2112					       rtlphy->iqk_mac_backup);
2113		rtl8723_save_adda_registers(hw, iqk_bb_reg,
2114					    rtlphy->iqk_bb_backup,
2115					    IQK_BB_REG_NUM);
2116	}
2117	rtl8723_phy_path_adda_on(hw, adda_reg, true, is2t);
2118	if (t == 0) {
2119		rtlphy->rfpi_enable = (u8)rtl_get_bbreg(hw,
2120						RFPGA0_XA_HSSIPARAMETER1,
2121						BIT(8));
2122	}
2123
2124	path_sel_bb = rtl_get_bbreg(hw, 0x948, MASKDWORD);
2125
2126	rtl8723_phy_mac_setting_calibration(hw, iqk_mac_reg,
2127					    rtlphy->iqk_mac_backup);
2128	/*BB Setting*/
2129	rtl_set_bbreg(hw, 0xa04, 0x0f000000, 0xf);
2130	rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600);
2131	rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4);
2132	rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000);
2133
2134	/* path A TX IQK */
2135	for (i = 0; i < retrycount; i++) {
2136		patha_ok = _rtl8723be_phy_path_a_iqk(hw);
2137		if (patha_ok == 0x01) {
2138			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2139				"Path A Tx IQK Success!!\n");
2140			result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) &
2141					0x3FF0000) >> 16;
2142			result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) &
2143					0x3FF0000) >> 16;
2144			break;
2145		} else {
2146			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2147				 "Path A Tx IQK Fail!!\n");
2148		}
2149	}
2150	/* path A RX IQK */
2151	for (i = 0; i < retrycount; i++) {
2152		patha_ok = _rtl8723be_phy_path_a_rx_iqk(hw);
2153		if (patha_ok == 0x03) {
2154			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2155				 "Path A Rx IQK Success!!\n");
2156			result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) &
2157					0x3FF0000) >> 16;
2158			result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) &
2159					0x3FF0000) >> 16;
2160			break;
2161		}
2162		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2163			 "Path A Rx IQK Fail!!\n");
2164	}
2165
2166	if (0x00 == patha_ok)
2167		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Path A IQK Fail!!\n");
2168
2169	if (is2t) {
2170		/* path B TX IQK */
2171		for (i = 0; i < retrycount; i++) {
2172			pathb_ok = _rtl8723be_phy_path_b_iqk(hw);
2173			if (pathb_ok == 0x01) {
2174				RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2175					 "Path B Tx IQK Success!!\n");
2176				result[t][4] = (rtl_get_bbreg(hw, 0xe94,
2177							      MASKDWORD) &
2178							      0x3FF0000) >> 16;
2179				result[t][5] = (rtl_get_bbreg(hw, 0xe9c,
2180							      MASKDWORD) &
2181							      0x3FF0000) >> 16;
2182				break;
2183			}
2184			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2185				 "Path B Tx IQK Fail!!\n");
2186		}
2187		/* path B RX IQK */
2188		for (i = 0; i < retrycount; i++) {
2189			pathb_ok = _rtl8723be_phy_path_b_rx_iqk(hw);
2190			if (pathb_ok == 0x03) {
2191				RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2192					 "Path B Rx IQK Success!!\n");
2193				result[t][6] = (rtl_get_bbreg(hw, 0xea4,
2194							      MASKDWORD) &
2195							      0x3FF0000) >> 16;
2196				result[t][7] = (rtl_get_bbreg(hw, 0xeac,
2197							      MASKDWORD) &
2198							      0x3FF0000) >> 16;
2199				break;
2200			}
2201			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2202				 "Path B Rx IQK Fail!!\n");
2203		}
2204	}
2205
2206	/* Back to BB mode, load original value */
2207	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0);
2208
2209	if (t != 0) {
2210		rtl8723_phy_reload_adda_registers(hw, adda_reg,
2211						  rtlphy->adda_backup, 16);
2212		rtl8723_phy_reload_mac_registers(hw, iqk_mac_reg,
2213						 rtlphy->iqk_mac_backup);
2214		rtl8723_phy_reload_adda_registers(hw, iqk_bb_reg,
2215						  rtlphy->iqk_bb_backup,
2216						  IQK_BB_REG_NUM);
2217
2218		rtl_set_bbreg(hw, 0x948, MASKDWORD, path_sel_bb);
2219		/*rtl_set_rfreg(hw, RF90_PATH_B, 0xb0, 0xfffff, path_sel_rf);*/
2220
2221		rtl_set_bbreg(hw, 0xc50, MASKBYTE0, 0x50);
2222		rtl_set_bbreg(hw, 0xc50, MASKBYTE0, tmp_reg_c50);
2223		if (is2t) {
2224			rtl_set_bbreg(hw, 0xc58, MASKBYTE0, 0x50);
2225			rtl_set_bbreg(hw, 0xc58, MASKBYTE0, tmp_reg_c58);
2226		}
2227		rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x01008c00);
2228		rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x01008c00);
2229	}
2230	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "8723be IQK Finish!!\n");
2231}
2232
2233static u8 _get_right_chnl_place_for_iqk(u8 chnl)
2234{
2235	u8 channel_all[TARGET_CHNL_NUM_2G_5G] = {
2236			1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
2237			13, 14, 36, 38, 40, 42, 44, 46,
2238			48, 50, 52, 54, 56, 58, 60, 62, 64,
2239			100, 102, 104, 106, 108, 110,
2240			112, 114, 116, 118, 120, 122,
2241			124, 126, 128, 130, 132, 134, 136,
2242			138, 140, 149, 151, 153, 155, 157,
2243			159, 161, 163, 165};
2244	u8 place = chnl;
2245
2246	if (chnl > 14) {
2247		for (place = 14; place < sizeof(channel_all); place++) {
2248			if (channel_all[place] == chnl)
2249				return place - 13;
2250		}
2251	}
2252	return 0;
2253}
2254
2255static void _rtl8723be_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
2256{
2257	u8 tmpreg;
2258	u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
2259	struct rtl_priv *rtlpriv = rtl_priv(hw);
2260
2261	tmpreg = rtl_read_byte(rtlpriv, 0xd03);
2262
2263	if ((tmpreg & 0x70) != 0)
2264		rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
2265	else
2266		rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
2267
2268	if ((tmpreg & 0x70) != 0) {
2269		rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS);
2270
2271		if (is2t)
2272			rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00,
2273						  MASK12BITS);
2274
2275		rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS,
2276			      (rf_a_mode & 0x8FFFF) | 0x10000);
2277
2278		if (is2t)
2279			rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
2280				      (rf_b_mode & 0x8FFFF) | 0x10000);
2281	}
2282	lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS);
2283
2284	rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, RFREG_OFFSET_MASK, 0xdfbe0);
2285	rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, 0x8c0a);
2286
2287	/* In order not to disturb BT music when wifi init.(1ant NIC only) */
2288	/*mdelay(100);*/
2289	/* In order not to disturb BT music when wifi init.(1ant NIC only) */
2290	mdelay(50);
2291
2292	rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, RFREG_OFFSET_MASK, 0xdffe0);
2293
2294	if ((tmpreg & 0x70) != 0) {
2295		rtl_write_byte(rtlpriv, 0xd03, tmpreg);
2296		rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode);
2297
2298		if (is2t)
2299			rtl_set_rfreg(hw, RF90_PATH_B, 0x00,
2300				      MASK12BITS, rf_b_mode);
2301	} else {
2302		rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
2303	}
2304RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
2305
2306}
2307
2308static void _rtl8723be_phy_set_rfpath_switch(struct ieee80211_hw *hw,
2309					     bool bmain, bool is2t)
2310{
2311	struct rtl_priv *rtlpriv = rtl_priv(hw);
2312	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
2313
2314	if (bmain) /* left antenna */
2315		rtl_set_bbreg(hw, 0x92C, MASKDWORD, 0x1);
2316	else
2317		rtl_set_bbreg(hw, 0x92C, MASKDWORD, 0x2);
2318}
2319
2320#undef IQK_ADDA_REG_NUM
2321#undef IQK_DELAY_TIME
2322/* IQK is merge from Merge Temp */
2323void rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
2324{
2325	struct rtl_priv *rtlpriv = rtl_priv(hw);
2326	struct rtl_phy *rtlphy = &rtlpriv->phy;
2327	long result[4][8];
2328	u8 i, final_candidate, idx;
2329	bool b_patha_ok, b_pathb_ok;
2330	long reg_e94, reg_e9c, reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4;
2331	long reg_ecc, reg_tmp = 0;
2332	bool is12simular, is13simular, is23simular;
2333	u32 iqk_bb_reg[9] = {
2334		ROFDM0_XARXIQIMBALANCE,
2335		ROFDM0_XBRXIQIMBALANCE,
2336		ROFDM0_ECCATHRESHOLD,
2337		ROFDM0_AGCRSSITABLE,
2338		ROFDM0_XATXIQIMBALANCE,
2339		ROFDM0_XBTXIQIMBALANCE,
2340		ROFDM0_XCTXAFE,
2341		ROFDM0_XDTXAFE,
2342		ROFDM0_RXIQEXTANTA
2343	};
2344	u32 path_sel_bb = 0; /* path_sel_rf = 0 */
2345
2346	if (rtlphy->lck_inprogress)
2347		return;
2348
2349	spin_lock(&rtlpriv->locks.iqk_lock);
2350	rtlphy->lck_inprogress = true;
2351	spin_unlock(&rtlpriv->locks.iqk_lock);
2352
2353	if (b_recovery) {
2354		rtl8723_phy_reload_adda_registers(hw, iqk_bb_reg,
2355						  rtlphy->iqk_bb_backup, 9);
2356		return;
2357	}
2358	/* Save RF Path */
2359	path_sel_bb = rtl_get_bbreg(hw, 0x948, MASKDWORD);
2360	/* path_sel_rf = rtl_get_rfreg(hw, RF90_PATH_A, 0xb0, 0xfffff); */
2361
2362	for (i = 0; i < 8; i++) {
2363		result[0][i] = 0;
2364		result[1][i] = 0;
2365		result[2][i] = 0;
2366		result[3][i] = 0;
2367	}
2368	final_candidate = 0xff;
2369	b_patha_ok = false;
2370	b_pathb_ok = false;
2371	is12simular = false;
2372	is23simular = false;
2373	is13simular = false;
2374	for (i = 0; i < 3; i++) {
2375		_rtl8723be_phy_iq_calibrate(hw, result, i, true);
2376		if (i == 1) {
2377			is12simular = _rtl8723be_phy_simularity_compare(hw,
2378									result,
2379									0, 1);
2380			if (is12simular) {
2381				final_candidate = 0;
2382				break;
2383			}
2384		}
2385		if (i == 2) {
2386			is13simular = _rtl8723be_phy_simularity_compare(hw,
2387									result,
2388									0, 2);
2389			if (is13simular) {
2390				final_candidate = 0;
2391				break;
2392			}
2393			is23simular = _rtl8723be_phy_simularity_compare(hw,
2394									result,
2395									1, 2);
2396			if (is23simular) {
2397				final_candidate = 1;
2398			} else {
2399				for (i = 0; i < 8; i++)
2400					reg_tmp += result[3][i];
2401
2402				if (reg_tmp != 0)
2403					final_candidate = 3;
2404				else
2405					final_candidate = 0xFF;
2406			}
2407		}
2408	}
2409	for (i = 0; i < 4; i++) {
2410		reg_e94 = result[i][0];
2411		reg_e9c = result[i][1];
2412		reg_ea4 = result[i][2];
2413		reg_eac = result[i][3];
2414		reg_eb4 = result[i][4];
2415		reg_ebc = result[i][5];
2416		reg_ec4 = result[i][6];
2417		reg_ecc = result[i][7];
2418	}
2419	if (final_candidate != 0xff) {
2420		reg_e94 = result[final_candidate][0];
2421		rtlphy->reg_e94 = reg_e94;
2422		reg_e9c = result[final_candidate][1];
2423		rtlphy->reg_e9c = reg_e9c;
2424		reg_ea4 = result[final_candidate][2];
2425		reg_eac = result[final_candidate][3];
2426		reg_eb4 = result[final_candidate][4];
2427		rtlphy->reg_eb4 = reg_eb4;
2428		reg_ebc = result[final_candidate][5];
2429		rtlphy->reg_ebc = reg_ebc;
2430		reg_ec4 = result[final_candidate][6];
2431		reg_ecc = result[final_candidate][7];
2432		b_patha_ok = true;
2433		b_pathb_ok = true;
2434	} else {
2435		rtlphy->reg_e94 = 0x100;
2436		rtlphy->reg_eb4 = 0x100;
2437		rtlphy->reg_e9c = 0x0;
2438		rtlphy->reg_ebc = 0x0;
2439	}
2440	if (reg_e94 != 0)
2441		rtl8723_phy_path_a_fill_iqk_matrix(hw, b_patha_ok, result,
2442						   final_candidate,
2443						   (reg_ea4 == 0));
2444	if (reg_eb4 != 0)
2445		_rtl8723be_phy_path_b_fill_iqk_matrix(hw, b_pathb_ok, result,
2446						      final_candidate,
2447						      (reg_ec4 == 0));
2448
2449	idx = _get_right_chnl_place_for_iqk(rtlphy->current_channel);
2450
2451	if (final_candidate < 4) {
2452		for (i = 0; i < IQK_MATRIX_REG_NUM; i++)
2453			rtlphy->iqk_matrix[idx].value[0][i] =
2454						result[final_candidate][i];
2455		rtlphy->iqk_matrix[idx].iqk_done = true;
2456
2457	}
2458	rtl8723_save_adda_registers(hw, iqk_bb_reg,
2459				    rtlphy->iqk_bb_backup, 9);
2460
2461	rtl_set_bbreg(hw, 0x948, MASKDWORD, path_sel_bb);
2462	/* rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, 0xfffff, path_sel_rf); */
2463
2464	spin_lock(&rtlpriv->locks.iqk_lock);
2465	rtlphy->lck_inprogress = false;
2466	spin_unlock(&rtlpriv->locks.iqk_lock);
2467}
2468
2469void rtl8723be_phy_lc_calibrate(struct ieee80211_hw *hw)
2470{
2471	struct rtl_priv *rtlpriv = rtl_priv(hw);
2472	struct rtl_phy *rtlphy = &rtlpriv->phy;
2473	struct rtl_hal *rtlhal = &rtlpriv->rtlhal;
2474	u32 timeout = 2000, timecount = 0;
2475
2476	while (rtlpriv->mac80211.act_scanning && timecount < timeout) {
2477		udelay(50);
2478		timecount += 50;
2479	}
2480
2481	rtlphy->lck_inprogress = true;
2482	RTPRINT(rtlpriv, FINIT, INIT_IQK,
2483		"LCK:Start!!! currentband %x delay %d ms\n",
2484		 rtlhal->current_bandtype, timecount);
2485
2486	_rtl8723be_phy_lc_calibrate(hw, false);
2487
2488	rtlphy->lck_inprogress = false;
2489}
2490
2491void rtl8723be_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
2492{
2493	_rtl8723be_phy_set_rfpath_switch(hw, bmain, true);
2494}
2495
2496bool rtl8723be_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
2497{
2498	struct rtl_priv *rtlpriv = rtl_priv(hw);
2499	struct rtl_phy *rtlphy = &rtlpriv->phy;
2500	bool b_postprocessing = false;
2501
2502	RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2503		 "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
2504		  iotype, rtlphy->set_io_inprogress);
2505	do {
2506		switch (iotype) {
2507		case IO_CMD_RESUME_DM_BY_SCAN:
2508			RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2509				 "[IO CMD] Resume DM after scan.\n");
2510			b_postprocessing = true;
2511			break;
2512		case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
2513			RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2514				 "[IO CMD] Pause DM before scan.\n");
2515			b_postprocessing = true;
2516			break;
2517		default:
2518			RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
2519				 "switch case not process\n");
2520			break;
2521		}
2522	} while (false);
2523	if (b_postprocessing && !rtlphy->set_io_inprogress) {
2524		rtlphy->set_io_inprogress = true;
2525		rtlphy->current_io_type = iotype;
2526	} else {
2527		return false;
2528	}
2529	rtl8723be_phy_set_io(hw);
2530	RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype);
2531	return true;
2532}
2533
2534static void rtl8723be_phy_set_io(struct ieee80211_hw *hw)
2535{
2536	struct rtl_priv *rtlpriv = rtl_priv(hw);
2537	struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
2538	struct rtl_phy *rtlphy = &rtlpriv->phy;
2539
2540	RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2541		 "--->Cmd(%#x), set_io_inprogress(%d)\n",
2542		  rtlphy->current_io_type, rtlphy->set_io_inprogress);
2543	switch (rtlphy->current_io_type) {
2544	case IO_CMD_RESUME_DM_BY_SCAN:
2545		dm_digtable->cur_igvalue = rtlphy->initgain_backup.xaagccore1;
2546		/*rtl92c_dm_write_dig(hw);*/
2547		rtl8723be_phy_set_txpower_level(hw, rtlphy->current_channel);
2548		rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x83);
2549		break;
2550	case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
2551		rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue;
2552		dm_digtable->cur_igvalue = 0x17;
2553		rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x40);
2554		break;
2555	default:
2556		RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
2557			 "switch case not process\n");
2558		break;
2559	}
2560	rtlphy->set_io_inprogress = false;
2561	RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2562		 "(%#x)\n", rtlphy->current_io_type);
2563}
2564
2565static void rtl8723be_phy_set_rf_on(struct ieee80211_hw *hw)
2566{
2567	struct rtl_priv *rtlpriv = rtl_priv(hw);
2568
2569	rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
2570	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2571	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2572	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2573	rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
2574}
2575
2576static void _rtl8723be_phy_set_rf_sleep(struct ieee80211_hw *hw)
2577{
2578	struct rtl_priv *rtlpriv = rtl_priv(hw);
2579
2580	rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
2581	rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
2582	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2583	rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
2584}
2585
2586static bool _rtl8723be_phy_set_rf_power_state(struct ieee80211_hw *hw,
2587					      enum rf_pwrstate rfpwr_state)
2588{
2589	struct rtl_priv *rtlpriv = rtl_priv(hw);
2590	struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
2591	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2592	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2593	bool bresult = true;
2594	u8 i, queue_id;
2595	struct rtl8192_tx_ring *ring = NULL;
2596
2597	switch (rfpwr_state) {
2598	case ERFON:
2599		if ((ppsc->rfpwr_state == ERFOFF) &&
2600		     RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
2601			bool rtstatus;
2602			u32 initializecount = 0;
2603			do {
2604				initializecount++;
2605				RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2606					 "IPS Set eRf nic enable\n");
2607				rtstatus = rtl_ps_enable_nic(hw);
2608			} while (!rtstatus && (initializecount < 10));
2609				RT_CLEAR_PS_LEVEL(ppsc,
2610						  RT_RF_OFF_LEVL_HALT_NIC);
2611		} else {
2612			RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2613				 "Set ERFON sleeped:%d ms\n",
2614				  jiffies_to_msecs(jiffies -
2615						   ppsc->last_sleep_jiffies));
2616			ppsc->last_awake_jiffies = jiffies;
2617			rtl8723be_phy_set_rf_on(hw);
2618		}
2619		if (mac->link_state == MAC80211_LINKED)
2620			rtlpriv->cfg->ops->led_control(hw, LED_CTL_LINK);
2621		else
2622			rtlpriv->cfg->ops->led_control(hw, LED_CTL_NO_LINK);
2623
2624		break;
2625
2626	case ERFOFF:
2627		for (queue_id = 0, i = 0;
2628		     queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
2629			ring = &pcipriv->dev.tx_ring[queue_id];
2630			/* Don't check BEACON Q.
2631			 * BEACON Q is always not empty,
2632			 * because '_rtl8723be_cmd_send_packet'
2633			 */
2634			if (queue_id == BEACON_QUEUE ||
2635			    skb_queue_len(&ring->queue) == 0) {
2636				queue_id++;
2637				continue;
2638			} else {
2639				RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2640					 "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
2641					 (i + 1), queue_id,
2642					 skb_queue_len(&ring->queue));
2643
2644				udelay(10);
2645				i++;
2646			}
2647			if (i >= MAX_DOZE_WAITING_TIMES_9x) {
2648				RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2649					 "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
2650					  MAX_DOZE_WAITING_TIMES_9x,
2651					  queue_id,
2652					  skb_queue_len(&ring->queue));
2653				break;
2654			}
2655		}
2656
2657		if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
2658			RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2659				 "IPS Set eRf nic disable\n");
2660			rtl_ps_disable_nic(hw);
2661			RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2662		} else {
2663			if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
2664				rtlpriv->cfg->ops->led_control(hw,
2665							       LED_CTL_NO_LINK);
2666			} else {
2667				rtlpriv->cfg->ops->led_control(hw,
2668							     LED_CTL_POWER_OFF);
2669			}
2670		}
2671		break;
2672
2673	case ERFSLEEP:
2674		if (ppsc->rfpwr_state == ERFOFF)
2675			break;
2676		for (queue_id = 0, i = 0;
2677		     queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
2678			ring = &pcipriv->dev.tx_ring[queue_id];
2679			if (skb_queue_len(&ring->queue) == 0) {
2680				queue_id++;
2681				continue;
2682			} else {
2683				RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2684					 "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
2685					 (i + 1), queue_id,
2686					 skb_queue_len(&ring->queue));
2687
2688				udelay(10);
2689				i++;
2690			}
2691			if (i >= MAX_DOZE_WAITING_TIMES_9x) {
2692				RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2693					 "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
2694					 MAX_DOZE_WAITING_TIMES_9x,
2695					 queue_id,
2696					 skb_queue_len(&ring->queue));
2697				break;
2698			}
2699		}
2700		RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2701			 "Set ERFSLEEP awaked:%d ms\n",
2702			  jiffies_to_msecs(jiffies -
2703					   ppsc->last_awake_jiffies));
2704		ppsc->last_sleep_jiffies = jiffies;
2705		_rtl8723be_phy_set_rf_sleep(hw);
2706		break;
2707
2708	default:
2709		RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
2710			 "switch case not process\n");
2711		bresult = false;
2712		break;
2713	}
2714	if (bresult)
2715		ppsc->rfpwr_state = rfpwr_state;
2716	return bresult;
2717}
2718
2719bool rtl8723be_phy_set_rf_power_state(struct ieee80211_hw *hw,
2720				      enum rf_pwrstate rfpwr_state)
2721{
2722	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2723
2724	bool bresult = false;
2725
2726	if (rfpwr_state == ppsc->rfpwr_state)
2727		return bresult;
2728	bresult = _rtl8723be_phy_set_rf_power_state(hw, rfpwr_state);
2729	return bresult;
2730}
2731