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 "rf.h"
33#include "dm.h"
34#include "table.h"
35
36static u32 _rtl92ee_phy_rf_serial_read(struct ieee80211_hw *hw,
37				       enum radio_path rfpath, u32 offset);
38static void _rtl92ee_phy_rf_serial_write(struct ieee80211_hw *hw,
39					 enum radio_path rfpath, u32 offset,
40					 u32 data);
41static u32 _rtl92ee_phy_calculate_bit_shift(u32 bitmask);
42static bool _rtl92ee_phy_bb8192ee_config_parafile(struct ieee80211_hw *hw);
43static bool _rtl92ee_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);
44static bool phy_config_bb_with_hdr_file(struct ieee80211_hw *hw,
45					u8 configtype);
46static bool phy_config_bb_with_pghdrfile(struct ieee80211_hw *hw,
47					 u8 configtype);
48static void phy_init_bb_rf_register_def(struct ieee80211_hw *hw);
49static bool _rtl92ee_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
50					      u32 cmdtableidx, u32 cmdtablesz,
51					      enum swchnlcmd_id cmdid,
52					      u32 para1, u32 para2,
53					      u32 msdelay);
54static bool _rtl92ee_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
55					      u8 channel, u8 *stage,
56					      u8 *step, u32 *delay);
57static long _rtl92ee_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
58					  enum wireless_mode wirelessmode,
59					  u8 txpwridx);
60static void rtl92ee_phy_set_rf_on(struct ieee80211_hw *hw);
61static void rtl92ee_phy_set_io(struct ieee80211_hw *hw);
62
63u32 rtl92ee_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask)
64{
65	struct rtl_priv *rtlpriv = rtl_priv(hw);
66	u32 returnvalue, originalvalue, bitshift;
67
68	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
69		 "regaddr(%#x), bitmask(%#x)\n", regaddr, bitmask);
70	originalvalue = rtl_read_dword(rtlpriv, regaddr);
71	bitshift = _rtl92ee_phy_calculate_bit_shift(bitmask);
72	returnvalue = (originalvalue & bitmask) >> bitshift;
73
74	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
75		 "BBR MASK=0x%x Addr[0x%x]=0x%x\n",
76		  bitmask, regaddr, originalvalue);
77
78	return returnvalue;
79}
80
81void rtl92ee_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr,
82			    u32 bitmask, u32 data)
83{
84	struct rtl_priv *rtlpriv = rtl_priv(hw);
85	u32 originalvalue, bitshift;
86
87	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
88		 "regaddr(%#x), bitmask(%#x), data(%#x)\n",
89		  regaddr, bitmask, data);
90
91	if (bitmask != MASKDWORD) {
92		originalvalue = rtl_read_dword(rtlpriv, regaddr);
93		bitshift = _rtl92ee_phy_calculate_bit_shift(bitmask);
94		data = ((originalvalue & (~bitmask)) | (data << bitshift));
95	}
96
97	rtl_write_dword(rtlpriv, regaddr, data);
98
99	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
100		 "regaddr(%#x), bitmask(%#x), data(%#x)\n",
101		  regaddr, bitmask, data);
102}
103
104u32 rtl92ee_phy_query_rf_reg(struct ieee80211_hw *hw,
105			     enum radio_path rfpath, u32 regaddr, u32 bitmask)
106{
107	struct rtl_priv *rtlpriv = rtl_priv(hw);
108	u32 original_value, readback_value, bitshift;
109	unsigned long flags;
110
111	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
112		 "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
113		  regaddr, rfpath, bitmask);
114
115	spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
116
117	original_value = _rtl92ee_phy_rf_serial_read(hw , rfpath, regaddr);
118	bitshift = _rtl92ee_phy_calculate_bit_shift(bitmask);
119	readback_value = (original_value & bitmask) >> bitshift;
120
121	spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
122
123	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
124		 "regaddr(%#x),rfpath(%#x),bitmask(%#x),original_value(%#x)\n",
125		  regaddr, rfpath, bitmask, original_value);
126
127	return readback_value;
128}
129
130void rtl92ee_phy_set_rf_reg(struct ieee80211_hw *hw,
131			    enum radio_path rfpath,
132			    u32 addr, u32 bitmask, u32 data)
133{
134	struct rtl_priv *rtlpriv = rtl_priv(hw);
135	u32 original_value, bitshift;
136	unsigned long flags;
137
138	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
139		 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
140		  addr, bitmask, data, rfpath);
141
142	spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
143
144	if (bitmask != RFREG_OFFSET_MASK) {
145		original_value = _rtl92ee_phy_rf_serial_read(hw, rfpath, addr);
146		bitshift = _rtl92ee_phy_calculate_bit_shift(bitmask);
147		data = (original_value & (~bitmask)) | (data << bitshift);
148	}
149
150	_rtl92ee_phy_rf_serial_write(hw, rfpath, addr, data);
151
152	spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
153
154	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
155		 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
156		  addr, bitmask, data, rfpath);
157}
158
159static u32 _rtl92ee_phy_rf_serial_read(struct ieee80211_hw *hw,
160				       enum radio_path rfpath, u32 offset)
161{
162	struct rtl_priv *rtlpriv = rtl_priv(hw);
163	struct rtl_phy *rtlphy = &rtlpriv->phy;
164	struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
165	u32 newoffset;
166	u32 tmplong, tmplong2;
167	u8 rfpi_enable = 0;
168	u32 retvalue;
169
170	offset &= 0xff;
171	newoffset = offset;
172	if (RT_CANNOT_IO(hw)) {
173		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "return all one\n");
174		return 0xFFFFFFFF;
175	}
176	tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD);
177	if (rfpath == RF90_PATH_A)
178		tmplong2 = tmplong;
179	else
180		tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD);
181	tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) |
182		   (newoffset << 23) | BLSSIREADEDGE;
183	rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD,
184		      tmplong & (~BLSSIREADEDGE));
185	mdelay(1);
186	rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2);
187	mdelay(2);
188	if (rfpath == RF90_PATH_A)
189		rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1,
190						BIT(8));
191	else if (rfpath == RF90_PATH_B)
192		rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1,
193						BIT(8));
194	if (rfpi_enable)
195		retvalue = rtl_get_bbreg(hw, pphyreg->rf_rbpi,
196					 BLSSIREADBACKDATA);
197	else
198		retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb,
199					 BLSSIREADBACKDATA);
200	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
201		 "RFR-%d Addr[0x%x]=0x%x\n",
202		  rfpath, pphyreg->rf_rb, retvalue);
203	return retvalue;
204}
205
206static void _rtl92ee_phy_rf_serial_write(struct ieee80211_hw *hw,
207					 enum radio_path rfpath, u32 offset,
208					 u32 data)
209{
210	u32 data_and_addr;
211	u32 newoffset;
212	struct rtl_priv *rtlpriv = rtl_priv(hw);
213	struct rtl_phy *rtlphy = &rtlpriv->phy;
214	struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath];
215
216	if (RT_CANNOT_IO(hw)) {
217		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "stop\n");
218		return;
219	}
220	offset &= 0xff;
221	newoffset = offset;
222	data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff;
223	rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr);
224	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
225		 "RFW-%d Addr[0x%x]=0x%x\n", rfpath,
226		 pphyreg->rf3wire_offset, data_and_addr);
227}
228
229static u32 _rtl92ee_phy_calculate_bit_shift(u32 bitmask)
230{
231	u32 i;
232
233	for (i = 0; i <= 31; i++) {
234		if (((bitmask >> i) & 0x1) == 1)
235			break;
236	}
237	return i;
238}
239
240bool rtl92ee_phy_mac_config(struct ieee80211_hw *hw)
241{
242	return _rtl92ee_phy_config_mac_with_headerfile(hw);
243}
244
245bool rtl92ee_phy_bb_config(struct ieee80211_hw *hw)
246{
247	struct rtl_priv *rtlpriv = rtl_priv(hw);
248	bool rtstatus = true;
249	u16 regval;
250	u32 tmp;
251	u8 crystal_cap;
252
253	phy_init_bb_rf_register_def(hw);
254	regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
255	rtl_write_word(rtlpriv, REG_SYS_FUNC_EN,
256		       regval | BIT(13) | BIT(0) | BIT(1));
257
258	rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB);
259	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN,
260		       FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE |
261		       FEN_BB_GLB_RSTN | FEN_BBRSTB);
262
263	rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80);
264
265	tmp = rtl_read_dword(rtlpriv, 0x4c);
266	rtl_write_dword(rtlpriv, 0x4c, tmp | BIT(23));
267
268	rtstatus = _rtl92ee_phy_bb8192ee_config_parafile(hw);
269
270	crystal_cap = rtlpriv->efuse.eeprom_crystalcap & 0x3F;
271	rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000,
272		      (crystal_cap | (crystal_cap << 6)));
273	return rtstatus;
274}
275
276bool rtl92ee_phy_rf_config(struct ieee80211_hw *hw)
277{
278	return rtl92ee_phy_rf6052_config(hw);
279}
280
281static bool _check_condition(struct ieee80211_hw *hw,
282			     const u32  condition)
283{
284	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
285	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
286	u32 _board = rtlefuse->board_type; /*need efuse define*/
287	u32 _interface = rtlhal->interface;
288	u32 _platform = 0x08;/*SupportPlatform */
289	u32 cond = condition;
290
291	if (condition == 0xCDCDCDCD)
292		return true;
293
294	cond = condition & 0xFF;
295	if ((_board != cond) && (cond != 0xFF))
296		return false;
297
298	cond = condition & 0xFF00;
299	cond = cond >> 8;
300	if ((_interface & cond) == 0 && cond != 0x07)
301		return false;
302
303	cond = condition & 0xFF0000;
304	cond = cond >> 16;
305	if ((_platform & cond) == 0 && cond != 0x0F)
306		return false;
307
308	return true;
309}
310
311static void _rtl92ee_config_rf_reg(struct ieee80211_hw *hw, u32 addr, u32 data,
312				   enum radio_path rfpath, u32 regaddr)
313{
314	if (addr == 0xfe || addr == 0xffe) {
315		mdelay(50);
316	} else {
317		rtl_set_rfreg(hw, rfpath, regaddr, RFREG_OFFSET_MASK, data);
318		udelay(1);
319
320		if (addr == 0xb6) {
321			u32 getvalue;
322			u8 count = 0;
323
324			getvalue = rtl_get_rfreg(hw, rfpath, addr, MASKDWORD);
325			udelay(1);
326
327			while ((getvalue >> 8) != (data >> 8)) {
328				count++;
329				rtl_set_rfreg(hw, rfpath, regaddr,
330					      RFREG_OFFSET_MASK, data);
331				udelay(1);
332				getvalue = rtl_get_rfreg(hw, rfpath, addr,
333							 MASKDWORD);
334				if (count > 5)
335					break;
336			}
337		}
338
339		if (addr == 0xb2) {
340			u32 getvalue;
341			u8 count = 0;
342
343			getvalue = rtl_get_rfreg(hw, rfpath, addr, MASKDWORD);
344			udelay(1);
345
346			while (getvalue != data) {
347				count++;
348				rtl_set_rfreg(hw, rfpath, regaddr,
349					      RFREG_OFFSET_MASK, data);
350				udelay(1);
351				rtl_set_rfreg(hw, rfpath, 0x18,
352					      RFREG_OFFSET_MASK, 0x0fc07);
353				udelay(1);
354				getvalue = rtl_get_rfreg(hw, rfpath, addr,
355							 MASKDWORD);
356				if (count > 5)
357					break;
358			}
359		}
360	}
361}
362
363static void _rtl92ee_config_rf_radio_a(struct ieee80211_hw *hw,
364				       u32 addr, u32 data)
365{
366	u32 content = 0x1000; /*RF Content: radio_a_txt*/
367	u32 maskforphyset = (u32)(content & 0xE000);
368
369	_rtl92ee_config_rf_reg(hw, addr, data, RF90_PATH_A,
370			       addr | maskforphyset);
371}
372
373static void _rtl92ee_config_rf_radio_b(struct ieee80211_hw *hw,
374				       u32 addr, u32 data)
375{
376	u32 content = 0x1001; /*RF Content: radio_b_txt*/
377	u32 maskforphyset = (u32)(content & 0xE000);
378
379	_rtl92ee_config_rf_reg(hw, addr, data, RF90_PATH_B,
380			       addr | maskforphyset);
381}
382
383static void _rtl92ee_config_bb_reg(struct ieee80211_hw *hw,
384				   u32 addr, u32 data)
385{
386	if (addr == 0xfe)
387		mdelay(50);
388	else if (addr == 0xfd)
389		mdelay(5);
390	else if (addr == 0xfc)
391		mdelay(1);
392	else if (addr == 0xfb)
393		udelay(50);
394	else if (addr == 0xfa)
395		udelay(5);
396	else if (addr == 0xf9)
397		udelay(1);
398	else
399		rtl_set_bbreg(hw, addr, MASKDWORD , data);
400
401	udelay(1);
402}
403
404static void _rtl92ee_phy_init_tx_power_by_rate(struct ieee80211_hw *hw)
405{
406	struct rtl_priv *rtlpriv = rtl_priv(hw);
407	struct rtl_phy *rtlphy = &rtlpriv->phy;
408
409	u8 band = BAND_ON_2_4G, rf = 0, txnum = 0, sec = 0;
410
411	for (; band <= BAND_ON_5G; ++band)
412		for (; rf < TX_PWR_BY_RATE_NUM_RF; ++rf)
413			for (; txnum < TX_PWR_BY_RATE_NUM_RF; ++txnum)
414				for (; sec < TX_PWR_BY_RATE_NUM_SECTION; ++sec)
415					rtlphy->tx_power_by_rate_offset
416					     [band][rf][txnum][sec] = 0;
417}
418
419static void _rtl92ee_phy_set_txpower_by_rate_base(struct ieee80211_hw *hw,
420						  u8 band, u8 path,
421						  u8 rate_section, u8 txnum,
422						  u8 value)
423{
424	struct rtl_priv *rtlpriv = rtl_priv(hw);
425	struct rtl_phy *rtlphy = &rtlpriv->phy;
426
427	if (path > RF90_PATH_D) {
428		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
429			 "Invalid Rf Path %d\n", path);
430		return;
431	}
432
433	if (band == BAND_ON_2_4G) {
434		switch (rate_section) {
435		case CCK:
436			rtlphy->txpwr_by_rate_base_24g[path][txnum][0] = value;
437			break;
438		case OFDM:
439			rtlphy->txpwr_by_rate_base_24g[path][txnum][1] = value;
440			break;
441		case HT_MCS0_MCS7:
442			rtlphy->txpwr_by_rate_base_24g[path][txnum][2] = value;
443			break;
444		case HT_MCS8_MCS15:
445			rtlphy->txpwr_by_rate_base_24g[path][txnum][3] = value;
446			break;
447		default:
448			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
449				 "Invalid RateSection %d in 2.4G,Rf %d,%dTx\n",
450				  rate_section, path, txnum);
451			break;
452		};
453	} else {
454		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
455			 "Invalid Band %d\n", band);
456	}
457}
458
459static u8 _rtl92ee_phy_get_txpower_by_rate_base(struct ieee80211_hw *hw,
460						u8 band, u8 path, u8 txnum,
461						u8 rate_section)
462{
463	struct rtl_priv *rtlpriv = rtl_priv(hw);
464	struct rtl_phy *rtlphy = &rtlpriv->phy;
465	u8 value = 0;
466
467	if (path > RF90_PATH_D) {
468		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
469			 "Invalid Rf Path %d\n", path);
470		return 0;
471	}
472
473	if (band == BAND_ON_2_4G) {
474		switch (rate_section) {
475		case CCK:
476			value = rtlphy->txpwr_by_rate_base_24g[path][txnum][0];
477			break;
478		case OFDM:
479			value = rtlphy->txpwr_by_rate_base_24g[path][txnum][1];
480			break;
481		case HT_MCS0_MCS7:
482			value = rtlphy->txpwr_by_rate_base_24g[path][txnum][2];
483			break;
484		case HT_MCS8_MCS15:
485			value = rtlphy->txpwr_by_rate_base_24g[path][txnum][3];
486			break;
487		default:
488			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
489				 "Invalid RateSection %d in 2.4G,Rf %d,%dTx\n",
490				  rate_section, path, txnum);
491			break;
492		};
493	} else {
494		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
495			 "Invalid Band %d()\n", band);
496	}
497	return value;
498}
499
500static void _rtl92ee_phy_store_txpower_by_rate_base(struct ieee80211_hw *hw)
501{
502	struct rtl_priv *rtlpriv = rtl_priv(hw);
503	struct rtl_phy *rtlphy = &rtlpriv->phy;
504	u16 raw = 0;
505	u8 base = 0, path = 0;
506
507	for (path = RF90_PATH_A; path <= RF90_PATH_B; ++path) {
508		if (path == RF90_PATH_A) {
509			raw = (u16)(rtlphy->tx_power_by_rate_offset
510				    [BAND_ON_2_4G][path][RF_1TX][3] >> 24) &
511				    0xFF;
512			base = (raw >> 4) * 10 + (raw & 0xF);
513			_rtl92ee_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G,
514							      path, CCK, RF_1TX,
515							      base);
516		} else if (path == RF90_PATH_B) {
517			raw = (u16)(rtlphy->tx_power_by_rate_offset
518				    [BAND_ON_2_4G][path][RF_1TX][3] >> 0) &
519				    0xFF;
520			base = (raw >> 4) * 10 + (raw & 0xF);
521			_rtl92ee_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G,
522							      path, CCK, RF_1TX,
523							      base);
524		}
525		raw = (u16)(rtlphy->tx_power_by_rate_offset
526			    [BAND_ON_2_4G][path][RF_1TX][1] >> 24) & 0xFF;
527		base = (raw >> 4) * 10 + (raw & 0xF);
528		_rtl92ee_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path,
529						      OFDM, RF_1TX, base);
530
531		raw = (u16)(rtlphy->tx_power_by_rate_offset
532			    [BAND_ON_2_4G][path][RF_1TX][5] >> 24) & 0xFF;
533		base = (raw >> 4) * 10 + (raw & 0xF);
534		_rtl92ee_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path,
535						      HT_MCS0_MCS7, RF_1TX,
536						      base);
537
538		raw = (u16)(rtlphy->tx_power_by_rate_offset
539			    [BAND_ON_2_4G][path][RF_2TX][7] >> 24) & 0xFF;
540		base = (raw >> 4) * 10 + (raw & 0xF);
541		_rtl92ee_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path,
542						      HT_MCS8_MCS15, RF_2TX,
543						      base);
544	}
545}
546
547static void _phy_convert_txpower_dbm_to_relative_value(u32 *data, u8 start,
548						       u8 end, u8 base)
549{
550	char i = 0;
551	u8 tmp = 0;
552	u32 temp_data = 0;
553
554	for (i = 3; i >= 0; --i) {
555		if (i >= start && i <= end) {
556			/* Get the exact value */
557			tmp = (u8)(*data >> (i * 8)) & 0xF;
558			tmp += ((u8)((*data >> (i * 8 + 4)) & 0xF)) * 10;
559
560			/* Change the value to a relative value */
561			tmp = (tmp > base) ? tmp - base : base - tmp;
562		} else {
563			tmp = (u8)(*data >> (i * 8)) & 0xFF;
564		}
565		temp_data <<= 8;
566		temp_data |= tmp;
567	}
568	*data = temp_data;
569}
570
571static void phy_convert_txpwr_dbm_to_rel_val(struct ieee80211_hw *hw)
572{
573	struct rtl_priv *rtlpriv = rtl_priv(hw);
574	struct rtl_phy *rtlphy = &rtlpriv->phy;
575	u8 base = 0, rf = 0, band = BAND_ON_2_4G;
576
577	for (rf = RF90_PATH_A; rf <= RF90_PATH_B; ++rf) {
578		if (rf == RF90_PATH_A) {
579			base = _rtl92ee_phy_get_txpower_by_rate_base(hw, band,
580								     rf, RF_1TX,
581								     CCK);
582			_phy_convert_txpower_dbm_to_relative_value(
583				&rtlphy->tx_power_by_rate_offset
584				[band][rf][RF_1TX][2],
585				1, 1, base);
586			_phy_convert_txpower_dbm_to_relative_value(
587				&rtlphy->tx_power_by_rate_offset
588				[band][rf][RF_1TX][3],
589				1, 3, base);
590		} else if (rf == RF90_PATH_B) {
591			base = _rtl92ee_phy_get_txpower_by_rate_base(hw, band,
592								     rf, RF_1TX,
593								     CCK);
594			_phy_convert_txpower_dbm_to_relative_value(
595				&rtlphy->tx_power_by_rate_offset
596				[band][rf][RF_1TX][3],
597				0, 0, base);
598			_phy_convert_txpower_dbm_to_relative_value(
599				&rtlphy->tx_power_by_rate_offset
600				[band][rf][RF_1TX][2],
601				1, 3, base);
602		}
603		base = _rtl92ee_phy_get_txpower_by_rate_base(hw, band, rf,
604							     RF_1TX, OFDM);
605		_phy_convert_txpower_dbm_to_relative_value(
606			&rtlphy->tx_power_by_rate_offset[band][rf][RF_1TX][0],
607			0, 3, base);
608		_phy_convert_txpower_dbm_to_relative_value(
609			&rtlphy->tx_power_by_rate_offset[band][rf][RF_1TX][1],
610			0, 3, base);
611
612		base = _rtl92ee_phy_get_txpower_by_rate_base(hw, band, rf,
613							     RF_1TX,
614							     HT_MCS0_MCS7);
615		_phy_convert_txpower_dbm_to_relative_value(
616			&rtlphy->tx_power_by_rate_offset[band][rf][RF_1TX][4],
617			0, 3, base);
618		_phy_convert_txpower_dbm_to_relative_value(
619			&rtlphy->tx_power_by_rate_offset[band][rf][RF_1TX][5],
620			0, 3, base);
621
622		base = _rtl92ee_phy_get_txpower_by_rate_base(hw, band, rf,
623							     RF_2TX,
624							     HT_MCS8_MCS15);
625		_phy_convert_txpower_dbm_to_relative_value(
626			&rtlphy->tx_power_by_rate_offset[band][rf][RF_2TX][6],
627			0, 3, base);
628
629		_phy_convert_txpower_dbm_to_relative_value(
630			&rtlphy->tx_power_by_rate_offset[band][rf][RF_2TX][7],
631			0, 3, base);
632	}
633
634	RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
635		 "<==phy_convert_txpwr_dbm_to_rel_val()\n");
636}
637
638static void _rtl92ee_phy_txpower_by_rate_configuration(struct ieee80211_hw *hw)
639{
640	_rtl92ee_phy_store_txpower_by_rate_base(hw);
641	phy_convert_txpwr_dbm_to_rel_val(hw);
642}
643
644static bool _rtl92ee_phy_bb8192ee_config_parafile(struct ieee80211_hw *hw)
645{
646	struct rtl_priv *rtlpriv = rtl_priv(hw);
647	struct rtl_phy *rtlphy = &rtlpriv->phy;
648	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
649	bool rtstatus;
650
651	rtstatus = phy_config_bb_with_hdr_file(hw, BASEBAND_CONFIG_PHY_REG);
652	if (!rtstatus) {
653		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!");
654		return false;
655	}
656
657	_rtl92ee_phy_init_tx_power_by_rate(hw);
658	if (!rtlefuse->autoload_failflag) {
659		rtlphy->pwrgroup_cnt = 0;
660		rtstatus =
661		  phy_config_bb_with_pghdrfile(hw, BASEBAND_CONFIG_PHY_REG);
662	}
663	_rtl92ee_phy_txpower_by_rate_configuration(hw);
664	if (!rtstatus) {
665		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!");
666		return false;
667	}
668	rtstatus = phy_config_bb_with_hdr_file(hw, BASEBAND_CONFIG_AGC_TAB);
669	if (!rtstatus) {
670		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n");
671		return false;
672	}
673	rtlphy->cck_high_power = (bool)(rtl_get_bbreg(hw,
674						      RFPGA0_XA_HSSIPARAMETER2,
675						      0x200));
676
677	return true;
678}
679
680static bool _rtl92ee_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
681{
682	struct rtl_priv *rtlpriv = rtl_priv(hw);
683	u32 i;
684	u32 arraylength;
685	u32 *ptrarray;
686
687	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl8192EMACPHY_Array\n");
688	arraylength = RTL8192EE_MAC_ARRAY_LEN;
689	ptrarray = RTL8192EE_MAC_ARRAY;
690	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
691		 "Img:RTL8192EE_MAC_ARRAY LEN %d\n" , arraylength);
692	for (i = 0; i < arraylength; i = i + 2)
693		rtl_write_byte(rtlpriv, ptrarray[i], (u8)ptrarray[i + 1]);
694	return true;
695}
696
697#define READ_NEXT_PAIR(v1, v2, i) \
698	do { \
699		i += 2; \
700		v1 = array[i]; \
701		v2 = array[i+1]; \
702	} while (0)
703
704static bool phy_config_bb_with_hdr_file(struct ieee80211_hw *hw,
705					u8 configtype)
706{
707	int i;
708	u32 *array;
709	u16 len;
710	struct rtl_priv *rtlpriv = rtl_priv(hw);
711	u32 v1 = 0, v2 = 0;
712
713	if (configtype == BASEBAND_CONFIG_PHY_REG) {
714		len = RTL8192EE_PHY_REG_ARRAY_LEN;
715		array = RTL8192EE_PHY_REG_ARRAY;
716
717		for (i = 0; i < len; i = i + 2) {
718			v1 = array[i];
719			v2 = array[i+1];
720			if (v1 < 0xcdcdcdcd) {
721				_rtl92ee_config_bb_reg(hw, v1, v2);
722			} else {/*This line is the start line of branch.*/
723				/* to protect READ_NEXT_PAIR not overrun */
724				if (i >= len - 2)
725					break;
726
727				if (!_check_condition(hw , array[i])) {
728					/*Discard the following pairs*/
729					READ_NEXT_PAIR(v1, v2, i);
730					while (v2 != 0xDEAD &&
731					       v2 != 0xCDEF &&
732					       v2 != 0xCDCD && i < len - 2) {
733						READ_NEXT_PAIR(v1, v2, i);
734					}
735					i -= 2; /* prevent from for-loop += 2*/
736				} else {
737					/* Configure matched pairs and
738					 * skip to end of if-else.
739					 */
740					READ_NEXT_PAIR(v1, v2, i);
741					while (v2 != 0xDEAD &&
742					       v2 != 0xCDEF &&
743					       v2 != 0xCDCD && i < len - 2) {
744						_rtl92ee_config_bb_reg(hw, v1,
745								       v2);
746						READ_NEXT_PAIR(v1, v2, i);
747					}
748
749					while (v2 != 0xDEAD && i < len - 2)
750						READ_NEXT_PAIR(v1, v2, i);
751				}
752			}
753		}
754	} else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
755		len = RTL8192EE_AGC_TAB_ARRAY_LEN;
756		array = RTL8192EE_AGC_TAB_ARRAY;
757
758		for (i = 0; i < len; i = i + 2) {
759			v1 = array[i];
760			v2 = array[i+1];
761			if (v1 < 0xCDCDCDCD) {
762				rtl_set_bbreg(hw, array[i], MASKDWORD,
763					      array[i + 1]);
764				udelay(1);
765				continue;
766		    } else{/*This line is the start line of branch.*/
767			  /* to protect READ_NEXT_PAIR not overrun */
768				if (i >= len - 2)
769					break;
770
771				if (!_check_condition(hw , array[i])) {
772					/*Discard the following pairs*/
773					READ_NEXT_PAIR(v1, v2, i);
774					while (v2 != 0xDEAD &&
775					       v2 != 0xCDEF &&
776					       v2 != 0xCDCD &&
777					       i < len - 2) {
778						READ_NEXT_PAIR(v1, v2, i);
779					}
780					i -= 2; /* prevent from for-loop += 2*/
781				} else {
782					/* Configure matched pairs and
783					 * skip to end of if-else.
784					 */
785					READ_NEXT_PAIR(v1, v2, i);
786					while (v2 != 0xDEAD &&
787					       v2 != 0xCDEF &&
788					       v2 != 0xCDCD &&
789					       i < len - 2) {
790						rtl_set_bbreg(hw,
791							      array[i],
792							      MASKDWORD,
793							      array[i + 1]);
794						udelay(1);
795						READ_NEXT_PAIR(v1 , v2 , i);
796					}
797
798					while (v2 != 0xDEAD &&
799					       i < len - 2) {
800						READ_NEXT_PAIR(v1 , v2 , i);
801					}
802				}
803			}
804			RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
805				 "The agctab_array_table[0] is %x Rtl818EEPHY_REGArray[1] is %x\n",
806				 array[i],
807				 array[i + 1]);
808		}
809	}
810	return true;
811}
812
813static u8 _rtl92ee_get_rate_section_index(u32 regaddr)
814{
815	u8 index = 0;
816
817	switch (regaddr) {
818	case RTXAGC_A_RATE18_06:
819	case RTXAGC_B_RATE18_06:
820		index = 0;
821		break;
822	case RTXAGC_A_RATE54_24:
823	case RTXAGC_B_RATE54_24:
824		index = 1;
825		break;
826	case RTXAGC_A_CCK1_MCS32:
827	case RTXAGC_B_CCK1_55_MCS32:
828		index = 2;
829		break;
830	case RTXAGC_B_CCK11_A_CCK2_11:
831		index = 3;
832		break;
833	case RTXAGC_A_MCS03_MCS00:
834	case RTXAGC_B_MCS03_MCS00:
835		index = 4;
836		break;
837	case RTXAGC_A_MCS07_MCS04:
838	case RTXAGC_B_MCS07_MCS04:
839		index = 5;
840		break;
841	case RTXAGC_A_MCS11_MCS08:
842	case RTXAGC_B_MCS11_MCS08:
843		index = 6;
844		break;
845	case RTXAGC_A_MCS15_MCS12:
846	case RTXAGC_B_MCS15_MCS12:
847		index = 7;
848		break;
849	default:
850		regaddr &= 0xFFF;
851		if (regaddr >= 0xC20 && regaddr <= 0xC4C)
852			index = (u8)((regaddr - 0xC20) / 4);
853		else if (regaddr >= 0xE20 && regaddr <= 0xE4C)
854			index = (u8)((regaddr - 0xE20) / 4);
855		break;
856	};
857	return index;
858}
859
860static void _rtl92ee_store_tx_power_by_rate(struct ieee80211_hw *hw,
861					    enum band_type band,
862					    enum radio_path rfpath,
863					    u32 txnum, u32 regaddr,
864					    u32 bitmask, u32 data)
865{
866	struct rtl_priv *rtlpriv = rtl_priv(hw);
867	struct rtl_phy *rtlphy = &rtlpriv->phy;
868	u8 section = _rtl92ee_get_rate_section_index(regaddr);
869
870	if (band != BAND_ON_2_4G && band != BAND_ON_5G) {
871		RT_TRACE(rtlpriv, FPHY, PHY_TXPWR, "Invalid Band %d\n", band);
872		return;
873	}
874
875	if (rfpath > MAX_RF_PATH - 1) {
876		RT_TRACE(rtlpriv, FPHY, PHY_TXPWR,
877			 "Invalid RfPath %d\n", rfpath);
878		return;
879	}
880	if (txnum > MAX_RF_PATH - 1) {
881		RT_TRACE(rtlpriv, FPHY, PHY_TXPWR, "Invalid TxNum %d\n", txnum);
882		return;
883	}
884
885	rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][section] = data;
886}
887
888static bool phy_config_bb_with_pghdrfile(struct ieee80211_hw *hw,
889					 u8 configtype)
890{
891	struct rtl_priv *rtlpriv = rtl_priv(hw);
892	int i;
893	u32 *phy_regarray_table_pg;
894	u16 phy_regarray_pg_len;
895	u32 v1 = 0, v2 = 0, v3 = 0, v4 = 0, v5 = 0, v6 = 0;
896
897	phy_regarray_pg_len = RTL8192EE_PHY_REG_ARRAY_PG_LEN;
898	phy_regarray_table_pg = RTL8192EE_PHY_REG_ARRAY_PG;
899
900	if (configtype == BASEBAND_CONFIG_PHY_REG) {
901		for (i = 0; i < phy_regarray_pg_len; i = i + 6) {
902			v1 = phy_regarray_table_pg[i];
903			v2 = phy_regarray_table_pg[i+1];
904			v3 = phy_regarray_table_pg[i+2];
905			v4 = phy_regarray_table_pg[i+3];
906			v5 = phy_regarray_table_pg[i+4];
907			v6 = phy_regarray_table_pg[i+5];
908
909			if (v1 < 0xcdcdcdcd) {
910				_rtl92ee_store_tx_power_by_rate(hw, v1, v2, v3,
911								v4, v5, v6);
912				continue;
913			}
914		}
915	} else {
916		RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
917			 "configtype != BaseBand_Config_PHY_REG\n");
918	}
919	return true;
920}
921
922#define READ_NEXT_RF_PAIR(v1, v2, i) \
923	do { \
924		i += 2; \
925		v1 = array[i]; \
926		v2 = array[i+1]; \
927	} while (0)
928
929bool rtl92ee_phy_config_rf_with_headerfile(struct ieee80211_hw  *hw,
930					   enum radio_path rfpath)
931{
932	struct rtl_priv *rtlpriv = rtl_priv(hw);
933	int i;
934	u32 *array;
935	u16 len;
936	u32 v1 = 0, v2 = 0;
937
938	switch (rfpath) {
939	case RF90_PATH_A:
940		len = RTL8192EE_RADIOA_ARRAY_LEN;
941		array = RTL8192EE_RADIOA_ARRAY;
942		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
943			 "Radio_A:RTL8192EE_RADIOA_ARRAY %d\n" , len);
944		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
945		for (i = 0; i < len; i = i + 2) {
946			v1 = array[i];
947			v2 = array[i+1];
948			if (v1 < 0xcdcdcdcd) {
949				_rtl92ee_config_rf_radio_a(hw, v1, v2);
950				continue;
951			} else {/*This line is the start line of branch.*/
952				/* to protect READ_NEXT_PAIR not overrun */
953				if (i >= len - 2)
954					break;
955
956				if (!_check_condition(hw , array[i])) {
957					/*Discard the following pairs*/
958					READ_NEXT_RF_PAIR(v1, v2, i);
959					while (v2 != 0xDEAD &&
960					       v2 != 0xCDEF &&
961					       v2 != 0xCDCD && i < len - 2) {
962						READ_NEXT_RF_PAIR(v1, v2, i);
963					}
964					i -= 2; /* prevent from for-loop += 2*/
965				} else {
966					/* Configure matched pairs and
967					 * skip to end of if-else.
968					 */
969					READ_NEXT_RF_PAIR(v1, v2, i);
970					while (v2 != 0xDEAD &&
971					       v2 != 0xCDEF &&
972					       v2 != 0xCDCD && i < len - 2) {
973						_rtl92ee_config_rf_radio_a(hw,
974									   v1,
975									   v2);
976						READ_NEXT_RF_PAIR(v1, v2, i);
977					}
978
979					while (v2 != 0xDEAD && i < len - 2)
980						READ_NEXT_RF_PAIR(v1, v2, i);
981				}
982			}
983		}
984		break;
985
986	case RF90_PATH_B:
987		len = RTL8192EE_RADIOB_ARRAY_LEN;
988		array = RTL8192EE_RADIOB_ARRAY;
989		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
990			 "Radio_A:RTL8192EE_RADIOB_ARRAY %d\n" , len);
991		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
992		for (i = 0; i < len; i = i + 2) {
993			v1 = array[i];
994			v2 = array[i+1];
995			if (v1 < 0xcdcdcdcd) {
996				_rtl92ee_config_rf_radio_b(hw, v1, v2);
997				continue;
998			} else {/*This line is the start line of branch.*/
999				/* to protect READ_NEXT_PAIR not overrun */
1000				if (i >= len - 2)
1001					break;
1002
1003				if (!_check_condition(hw , array[i])) {
1004					/*Discard the following pairs*/
1005					READ_NEXT_RF_PAIR(v1, v2, i);
1006					while (v2 != 0xDEAD &&
1007					       v2 != 0xCDEF &&
1008					       v2 != 0xCDCD && i < len - 2) {
1009						READ_NEXT_RF_PAIR(v1, v2, i);
1010					}
1011					i -= 2; /* prevent from for-loop += 2*/
1012				} else {
1013					/* Configure matched pairs and
1014					 * skip to end of if-else.
1015					 */
1016					READ_NEXT_RF_PAIR(v1, v2, i);
1017					while (v2 != 0xDEAD &&
1018					       v2 != 0xCDEF &&
1019					       v2 != 0xCDCD && i < len - 2) {
1020						_rtl92ee_config_rf_radio_b(hw,
1021									   v1,
1022									   v2);
1023						READ_NEXT_RF_PAIR(v1, v2, i);
1024					}
1025
1026					while (v2 != 0xDEAD && i < len - 2)
1027						READ_NEXT_RF_PAIR(v1, v2, i);
1028				}
1029			}
1030		}
1031		break;
1032	case RF90_PATH_C:
1033	case RF90_PATH_D:
1034		break;
1035	}
1036	return true;
1037}
1038
1039void rtl92ee_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
1040{
1041	struct rtl_priv *rtlpriv = rtl_priv(hw);
1042	struct rtl_phy *rtlphy = &rtlpriv->phy;
1043
1044	rtlphy->default_initialgain[0] =
1045		(u8)rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
1046	rtlphy->default_initialgain[1] =
1047		(u8)rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
1048	rtlphy->default_initialgain[2] =
1049		(u8)rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
1050	rtlphy->default_initialgain[3] =
1051		(u8)rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
1052
1053	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1054		 "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n",
1055		  rtlphy->default_initialgain[0],
1056		  rtlphy->default_initialgain[1],
1057		  rtlphy->default_initialgain[2],
1058		  rtlphy->default_initialgain[3]);
1059
1060	rtlphy->framesync = (u8)rtl_get_bbreg(hw,
1061					      ROFDM0_RXDETECTOR3, MASKBYTE0);
1062	rtlphy->framesync_c34 = rtl_get_bbreg(hw,
1063					      ROFDM0_RXDETECTOR2, MASKDWORD);
1064
1065	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
1066		 "Default framesync (0x%x) = 0x%x\n",
1067		  ROFDM0_RXDETECTOR3, rtlphy->framesync);
1068}
1069
1070static void phy_init_bb_rf_register_def(struct ieee80211_hw *hw)
1071{
1072	struct rtl_priv *rtlpriv = rtl_priv(hw);
1073	struct rtl_phy *rtlphy = &rtlpriv->phy;
1074
1075	rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW;
1076	rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW;
1077
1078	rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE;
1079	rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE;
1080
1081	rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE;
1082	rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE;
1083
1084	rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset =
1085							RFPGA0_XA_LSSIPARAMETER;
1086	rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset =
1087							RFPGA0_XB_LSSIPARAMETER;
1088
1089	rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2;
1090	rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2;
1091
1092	rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RFPGA0_XA_LSSIREADBACK;
1093	rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RFPGA0_XB_LSSIREADBACK;
1094
1095	rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = TRANSCEIVEA_HSPI_READBACK;
1096	rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = TRANSCEIVEB_HSPI_READBACK;
1097}
1098
1099void rtl92ee_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
1100{
1101	struct rtl_priv *rtlpriv = rtl_priv(hw);
1102	struct rtl_phy *rtlphy = &rtlpriv->phy;
1103	u8 txpwr_level;
1104	long txpwr_dbm;
1105
1106	txpwr_level = rtlphy->cur_cck_txpwridx;
1107	txpwr_dbm = _rtl92ee_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_B,
1108						  txpwr_level);
1109	txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
1110	if (_rtl92ee_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, txpwr_level) >
1111	    txpwr_dbm)
1112		txpwr_dbm = _rtl92ee_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
1113							  txpwr_level);
1114	txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
1115	if (_rtl92ee_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
1116					  txpwr_level) > txpwr_dbm)
1117		txpwr_dbm = _rtl92ee_phy_txpwr_idx_to_dbm(hw,
1118							  WIRELESS_MODE_N_24G,
1119							  txpwr_level);
1120	*powerlevel = txpwr_dbm;
1121}
1122
1123static u8 _rtl92ee_phy_get_ratesection_intxpower_byrate(enum radio_path path,
1124							u8 rate)
1125{
1126	u8 rate_section = 0;
1127
1128	switch (rate) {
1129	case DESC92C_RATE1M:
1130		rate_section = 2;
1131		break;
1132	case DESC92C_RATE2M:
1133	case DESC92C_RATE5_5M:
1134		if (path == RF90_PATH_A)
1135			rate_section = 3;
1136		else if (path == RF90_PATH_B)
1137			rate_section = 2;
1138		break;
1139	case DESC92C_RATE11M:
1140		rate_section = 3;
1141		break;
1142	case DESC92C_RATE6M:
1143	case DESC92C_RATE9M:
1144	case DESC92C_RATE12M:
1145	case DESC92C_RATE18M:
1146		rate_section = 0;
1147		break;
1148	case DESC92C_RATE24M:
1149	case DESC92C_RATE36M:
1150	case DESC92C_RATE48M:
1151	case DESC92C_RATE54M:
1152		rate_section = 1;
1153		break;
1154	case DESC92C_RATEMCS0:
1155	case DESC92C_RATEMCS1:
1156	case DESC92C_RATEMCS2:
1157	case DESC92C_RATEMCS3:
1158		rate_section = 4;
1159		break;
1160	case DESC92C_RATEMCS4:
1161	case DESC92C_RATEMCS5:
1162	case DESC92C_RATEMCS6:
1163	case DESC92C_RATEMCS7:
1164		rate_section = 5;
1165		break;
1166	case DESC92C_RATEMCS8:
1167	case DESC92C_RATEMCS9:
1168	case DESC92C_RATEMCS10:
1169	case DESC92C_RATEMCS11:
1170		rate_section = 6;
1171		break;
1172	case DESC92C_RATEMCS12:
1173	case DESC92C_RATEMCS13:
1174	case DESC92C_RATEMCS14:
1175	case DESC92C_RATEMCS15:
1176		rate_section = 7;
1177		break;
1178	default:
1179		RT_ASSERT(true, "Rate_Section is Illegal\n");
1180		break;
1181	}
1182	return rate_section;
1183}
1184
1185static u8 _rtl92ee_get_txpower_by_rate(struct ieee80211_hw *hw,
1186				       enum band_type band,
1187				       enum radio_path rf, u8 rate)
1188{
1189	struct rtl_priv *rtlpriv = rtl_priv(hw);
1190	struct rtl_phy *rtlphy = &rtlpriv->phy;
1191	u8 shift = 0, sec, tx_num;
1192	char diff = 0;
1193
1194	sec = _rtl92ee_phy_get_ratesection_intxpower_byrate(rf, rate);
1195	tx_num = RF_TX_NUM_NONIMPLEMENT;
1196
1197	if (tx_num == RF_TX_NUM_NONIMPLEMENT) {
1198		if ((rate >= DESC92C_RATEMCS8 && rate <= DESC92C_RATEMCS15))
1199			tx_num = RF_2TX;
1200		else
1201			tx_num = RF_1TX;
1202	}
1203
1204	switch (rate) {
1205	case DESC92C_RATE1M:
1206	case DESC92C_RATE6M:
1207	case DESC92C_RATE24M:
1208	case DESC92C_RATEMCS0:
1209	case DESC92C_RATEMCS4:
1210	case DESC92C_RATEMCS8:
1211	case DESC92C_RATEMCS12:
1212		shift = 0;
1213		break;
1214	case DESC92C_RATE2M:
1215	case DESC92C_RATE9M:
1216	case DESC92C_RATE36M:
1217	case DESC92C_RATEMCS1:
1218	case DESC92C_RATEMCS5:
1219	case DESC92C_RATEMCS9:
1220	case DESC92C_RATEMCS13:
1221		shift = 8;
1222		break;
1223	case DESC92C_RATE5_5M:
1224	case DESC92C_RATE12M:
1225	case DESC92C_RATE48M:
1226	case DESC92C_RATEMCS2:
1227	case DESC92C_RATEMCS6:
1228	case DESC92C_RATEMCS10:
1229	case DESC92C_RATEMCS14:
1230		shift = 16;
1231		break;
1232	case DESC92C_RATE11M:
1233	case DESC92C_RATE18M:
1234	case DESC92C_RATE54M:
1235	case DESC92C_RATEMCS3:
1236	case DESC92C_RATEMCS7:
1237	case DESC92C_RATEMCS11:
1238	case DESC92C_RATEMCS15:
1239		shift = 24;
1240		break;
1241	default:
1242		RT_ASSERT(true, "Rate_Section is Illegal\n");
1243		break;
1244	}
1245
1246	diff = (u8)(rtlphy->tx_power_by_rate_offset[band][rf][tx_num][sec] >>
1247		    shift) & 0xff;
1248
1249	return	diff;
1250}
1251
1252static u8 _rtl92ee_get_txpower_index(struct ieee80211_hw *hw,
1253				     enum radio_path rfpath, u8 rate,
1254				     u8 bw, u8 channel)
1255{
1256	struct rtl_priv *rtlpriv = rtl_priv(hw);
1257	struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
1258	u8 index = (channel - 1);
1259	u8 tx_power = 0;
1260	u8 diff = 0;
1261
1262	if (channel < 1 || channel > 14) {
1263		index = 0;
1264		RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_DMESG,
1265			 "Illegal channel!!\n");
1266	}
1267
1268	if (IS_CCK_RATE(rate))
1269		tx_power = rtlefuse->txpwrlevel_cck[rfpath][index];
1270	else if (DESC92C_RATE6M <= rate)
1271		tx_power = rtlefuse->txpwrlevel_ht40_1s[rfpath][index];
1272
1273	/* OFDM-1T*/
1274	if (DESC92C_RATE6M <= rate && rate <= DESC92C_RATE54M &&
1275	    !IS_CCK_RATE(rate))
1276		tx_power += rtlefuse->txpwr_legacyhtdiff[rfpath][TX_1S];
1277
1278	/* BW20-1S, BW20-2S */
1279	if (bw == HT_CHANNEL_WIDTH_20) {
1280		if (DESC92C_RATEMCS0 <= rate && rate <= DESC92C_RATEMCS15)
1281			tx_power += rtlefuse->txpwr_ht20diff[rfpath][TX_1S];
1282		if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15)
1283			tx_power += rtlefuse->txpwr_ht20diff[rfpath][TX_2S];
1284	} else if (bw == HT_CHANNEL_WIDTH_20_40) {/* BW40-1S, BW40-2S */
1285		if (DESC92C_RATEMCS0 <= rate && rate <= DESC92C_RATEMCS15)
1286			tx_power += rtlefuse->txpwr_ht40diff[rfpath][TX_1S];
1287		if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15)
1288			tx_power += rtlefuse->txpwr_ht40diff[rfpath][TX_2S];
1289	}
1290
1291	if (rtlefuse->eeprom_regulatory != 2)
1292		diff = _rtl92ee_get_txpower_by_rate(hw, BAND_ON_2_4G,
1293						    rfpath, rate);
1294
1295	tx_power += diff;
1296
1297	if (tx_power > MAX_POWER_INDEX)
1298		tx_power = MAX_POWER_INDEX;
1299
1300	return tx_power;
1301}
1302
1303static void _rtl92ee_set_txpower_index(struct ieee80211_hw *hw, u8 pwr_idx,
1304				       enum radio_path rfpath, u8 rate)
1305{
1306	struct rtl_priv *rtlpriv = rtl_priv(hw);
1307
1308	if (rfpath == RF90_PATH_A) {
1309		switch (rate) {
1310		case DESC92C_RATE1M:
1311			rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1,
1312				      pwr_idx);
1313			break;
1314		case DESC92C_RATE2M:
1315			rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE1,
1316				      pwr_idx);
1317			break;
1318		case DESC92C_RATE5_5M:
1319			rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE2,
1320				      pwr_idx);
1321			break;
1322		case DESC92C_RATE11M:
1323			rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE3,
1324				      pwr_idx);
1325			break;
1326		case DESC92C_RATE6M:
1327			rtl_set_bbreg(hw, RTXAGC_A_RATE18_06, MASKBYTE0,
1328				      pwr_idx);
1329			break;
1330		case DESC92C_RATE9M:
1331			rtl_set_bbreg(hw, RTXAGC_A_RATE18_06, MASKBYTE1,
1332				      pwr_idx);
1333			break;
1334		case DESC92C_RATE12M:
1335			rtl_set_bbreg(hw, RTXAGC_A_RATE18_06, MASKBYTE2,
1336				      pwr_idx);
1337			break;
1338		case DESC92C_RATE18M:
1339			rtl_set_bbreg(hw, RTXAGC_A_RATE18_06, MASKBYTE3,
1340				      pwr_idx);
1341			break;
1342		case DESC92C_RATE24M:
1343			rtl_set_bbreg(hw, RTXAGC_A_RATE54_24, MASKBYTE0,
1344				      pwr_idx);
1345			break;
1346		case DESC92C_RATE36M:
1347			rtl_set_bbreg(hw, RTXAGC_A_RATE54_24, MASKBYTE1,
1348				      pwr_idx);
1349			break;
1350		case DESC92C_RATE48M:
1351			rtl_set_bbreg(hw, RTXAGC_A_RATE54_24, MASKBYTE2,
1352				      pwr_idx);
1353			break;
1354		case DESC92C_RATE54M:
1355			rtl_set_bbreg(hw, RTXAGC_A_RATE54_24, MASKBYTE3,
1356				      pwr_idx);
1357			break;
1358		case DESC92C_RATEMCS0:
1359			rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00, MASKBYTE0,
1360				      pwr_idx);
1361			break;
1362		case DESC92C_RATEMCS1:
1363			rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00, MASKBYTE1,
1364				      pwr_idx);
1365			break;
1366		case DESC92C_RATEMCS2:
1367			rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00, MASKBYTE2,
1368				      pwr_idx);
1369			break;
1370		case DESC92C_RATEMCS3:
1371			rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00, MASKBYTE3,
1372				      pwr_idx);
1373			break;
1374		case DESC92C_RATEMCS4:
1375			rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04, MASKBYTE0,
1376				      pwr_idx);
1377			break;
1378		case DESC92C_RATEMCS5:
1379			rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04, MASKBYTE1,
1380				      pwr_idx);
1381			break;
1382		case DESC92C_RATEMCS6:
1383			rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04, MASKBYTE2,
1384				      pwr_idx);
1385			break;
1386		case DESC92C_RATEMCS7:
1387			rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04, MASKBYTE3,
1388				      pwr_idx);
1389			break;
1390		case DESC92C_RATEMCS8:
1391			rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08, MASKBYTE0,
1392				      pwr_idx);
1393			break;
1394		case DESC92C_RATEMCS9:
1395			rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08, MASKBYTE1,
1396				      pwr_idx);
1397			break;
1398		case DESC92C_RATEMCS10:
1399			rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08, MASKBYTE2,
1400				      pwr_idx);
1401			break;
1402		case DESC92C_RATEMCS11:
1403			rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08, MASKBYTE3,
1404				      pwr_idx);
1405			break;
1406		case DESC92C_RATEMCS12:
1407			rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12, MASKBYTE0,
1408				      pwr_idx);
1409			break;
1410		case DESC92C_RATEMCS13:
1411			rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12, MASKBYTE1,
1412				      pwr_idx);
1413			break;
1414		case DESC92C_RATEMCS14:
1415			rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12, MASKBYTE2,
1416				      pwr_idx);
1417			break;
1418		case DESC92C_RATEMCS15:
1419			rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12, MASKBYTE3,
1420				      pwr_idx);
1421			break;
1422		default:
1423			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
1424				 "Invalid Rate!!\n");
1425			break;
1426		}
1427	} else if (rfpath == RF90_PATH_B) {
1428		switch (rate) {
1429		case DESC92C_RATE1M:
1430			rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, MASKBYTE1,
1431				      pwr_idx);
1432			break;
1433		case DESC92C_RATE2M:
1434			rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, MASKBYTE2,
1435				      pwr_idx);
1436			break;
1437		case DESC92C_RATE5_5M:
1438			rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, MASKBYTE3,
1439				      pwr_idx);
1440			break;
1441		case DESC92C_RATE11M:
1442			rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0,
1443				      pwr_idx);
1444			break;
1445		case DESC92C_RATE6M:
1446			rtl_set_bbreg(hw, RTXAGC_B_RATE18_06, MASKBYTE0,
1447				      pwr_idx);
1448			break;
1449		case DESC92C_RATE9M:
1450			rtl_set_bbreg(hw, RTXAGC_B_RATE18_06, MASKBYTE1,
1451				      pwr_idx);
1452			break;
1453		case DESC92C_RATE12M:
1454			rtl_set_bbreg(hw, RTXAGC_B_RATE18_06, MASKBYTE2,
1455				      pwr_idx);
1456			break;
1457		case DESC92C_RATE18M:
1458			rtl_set_bbreg(hw, RTXAGC_B_RATE18_06, MASKBYTE3,
1459				      pwr_idx);
1460			break;
1461		case DESC92C_RATE24M:
1462			rtl_set_bbreg(hw, RTXAGC_B_RATE54_24, MASKBYTE0,
1463				      pwr_idx);
1464			break;
1465		case DESC92C_RATE36M:
1466			rtl_set_bbreg(hw, RTXAGC_B_RATE54_24, MASKBYTE1,
1467				      pwr_idx);
1468			break;
1469		case DESC92C_RATE48M:
1470			rtl_set_bbreg(hw, RTXAGC_B_RATE54_24, MASKBYTE2,
1471				      pwr_idx);
1472			break;
1473		case DESC92C_RATE54M:
1474			rtl_set_bbreg(hw, RTXAGC_B_RATE54_24, MASKBYTE3,
1475				      pwr_idx);
1476			break;
1477		case DESC92C_RATEMCS0:
1478			rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00, MASKBYTE0,
1479				      pwr_idx);
1480			break;
1481		case DESC92C_RATEMCS1:
1482			rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00, MASKBYTE1,
1483				      pwr_idx);
1484			break;
1485		case DESC92C_RATEMCS2:
1486			rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00, MASKBYTE2,
1487				      pwr_idx);
1488			break;
1489		case DESC92C_RATEMCS3:
1490			rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00, MASKBYTE3,
1491				      pwr_idx);
1492			break;
1493		case DESC92C_RATEMCS4:
1494			rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04, MASKBYTE0,
1495				      pwr_idx);
1496			break;
1497		case DESC92C_RATEMCS5:
1498			rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04, MASKBYTE1,
1499				      pwr_idx);
1500			break;
1501		case DESC92C_RATEMCS6:
1502			rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04, MASKBYTE2,
1503				      pwr_idx);
1504			break;
1505		case DESC92C_RATEMCS7:
1506			rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04, MASKBYTE3,
1507				      pwr_idx);
1508			break;
1509		case DESC92C_RATEMCS8:
1510			rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08, MASKBYTE0,
1511				      pwr_idx);
1512			break;
1513		case DESC92C_RATEMCS9:
1514			rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08, MASKBYTE1,
1515				      pwr_idx);
1516			break;
1517		case DESC92C_RATEMCS10:
1518			rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08, MASKBYTE2,
1519				      pwr_idx);
1520			break;
1521		case DESC92C_RATEMCS11:
1522			rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08, MASKBYTE3,
1523				      pwr_idx);
1524			break;
1525		case DESC92C_RATEMCS12:
1526			rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12, MASKBYTE0,
1527				      pwr_idx);
1528			break;
1529		case DESC92C_RATEMCS13:
1530			rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12, MASKBYTE1,
1531				      pwr_idx);
1532			break;
1533		case DESC92C_RATEMCS14:
1534			rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12, MASKBYTE2,
1535				      pwr_idx);
1536			break;
1537		case DESC92C_RATEMCS15:
1538			rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12, MASKBYTE3,
1539				      pwr_idx);
1540			break;
1541		default:
1542			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
1543				 "Invalid Rate!!\n");
1544			break;
1545		}
1546	} else {
1547		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid RFPath!!\n");
1548	}
1549}
1550
1551static void phy_set_txpower_index_by_rate_array(struct ieee80211_hw *hw,
1552						enum radio_path rfpath, u8 bw,
1553						u8 channel, u8 *rates, u8 size)
1554{
1555	u8 i;
1556	u8 power_index;
1557
1558	for (i = 0; i < size; i++) {
1559		power_index = _rtl92ee_get_txpower_index(hw, rfpath, rates[i],
1560							 bw, channel);
1561		_rtl92ee_set_txpower_index(hw, power_index, rfpath, rates[i]);
1562	}
1563}
1564
1565static void phy_set_txpower_index_by_rate_section(struct ieee80211_hw *hw,
1566						  enum radio_path rfpath,
1567						  u8 channel,
1568						  enum rate_section section)
1569{
1570	struct rtl_priv *rtlpriv = rtl_priv(hw);
1571	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
1572	struct rtl_phy *rtlphy = &rtlpriv->phy;
1573
1574	if (section == CCK) {
1575		u8 cck_rates[] = {DESC92C_RATE1M, DESC92C_RATE2M,
1576				  DESC92C_RATE5_5M, DESC92C_RATE11M};
1577		if (rtlhal->current_bandtype == BAND_ON_2_4G)
1578			phy_set_txpower_index_by_rate_array(hw, rfpath,
1579							rtlphy->current_chan_bw,
1580							channel, cck_rates, 4);
1581	} else if (section == OFDM) {
1582		u8 ofdm_rates[] = {DESC92C_RATE6M, DESC92C_RATE9M,
1583				   DESC92C_RATE12M, DESC92C_RATE18M,
1584				   DESC92C_RATE24M, DESC92C_RATE36M,
1585				   DESC92C_RATE48M, DESC92C_RATE54M};
1586		phy_set_txpower_index_by_rate_array(hw, rfpath,
1587						    rtlphy->current_chan_bw,
1588						    channel, ofdm_rates, 8);
1589	} else if (section == HT_MCS0_MCS7) {
1590		u8 ht_rates1t[]  = {DESC92C_RATEMCS0, DESC92C_RATEMCS1,
1591				    DESC92C_RATEMCS2, DESC92C_RATEMCS3,
1592				    DESC92C_RATEMCS4, DESC92C_RATEMCS5,
1593				    DESC92C_RATEMCS6, DESC92C_RATEMCS7};
1594		phy_set_txpower_index_by_rate_array(hw, rfpath,
1595						    rtlphy->current_chan_bw,
1596						    channel, ht_rates1t, 8);
1597	} else if (section == HT_MCS8_MCS15) {
1598		u8 ht_rates2t[]  = {DESC92C_RATEMCS8, DESC92C_RATEMCS9,
1599				    DESC92C_RATEMCS10, DESC92C_RATEMCS11,
1600				    DESC92C_RATEMCS12, DESC92C_RATEMCS13,
1601				    DESC92C_RATEMCS14, DESC92C_RATEMCS15};
1602		phy_set_txpower_index_by_rate_array(hw, rfpath,
1603						    rtlphy->current_chan_bw,
1604						    channel, ht_rates2t, 8);
1605	} else
1606		RT_TRACE(rtlpriv, FPHY, PHY_TXPWR,
1607			 "Invalid RateSection %d\n", section);
1608}
1609
1610void rtl92ee_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
1611{
1612	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1613	struct rtl_phy *rtlphy = &rtl_priv(hw)->phy;
1614	enum radio_path rfpath;
1615
1616	if (!rtlefuse->txpwr_fromeprom)
1617		return;
1618	for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath;
1619	     rfpath++) {
1620		phy_set_txpower_index_by_rate_section(hw, rfpath,
1621						      channel, CCK);
1622		phy_set_txpower_index_by_rate_section(hw, rfpath,
1623						      channel, OFDM);
1624		phy_set_txpower_index_by_rate_section(hw, rfpath,
1625						      channel,
1626						      HT_MCS0_MCS7);
1627
1628		if (rtlphy->num_total_rfpath >= 2)
1629			phy_set_txpower_index_by_rate_section(hw,
1630							      rfpath, channel,
1631							      HT_MCS8_MCS15);
1632	}
1633}
1634
1635static long _rtl92ee_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw,
1636					  enum wireless_mode wirelessmode,
1637					  u8 txpwridx)
1638{
1639	long offset;
1640	long pwrout_dbm;
1641
1642	switch (wirelessmode) {
1643	case WIRELESS_MODE_B:
1644		offset = -7;
1645		break;
1646	case WIRELESS_MODE_G:
1647	case WIRELESS_MODE_N_24G:
1648		offset = -8;
1649		break;
1650	default:
1651		offset = -8;
1652		break;
1653	}
1654	pwrout_dbm = txpwridx / 2 + offset;
1655	return pwrout_dbm;
1656}
1657
1658void rtl92ee_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
1659{
1660	struct rtl_priv *rtlpriv = rtl_priv(hw);
1661	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1662	enum io_type iotype;
1663
1664	if (!is_hal_stop(rtlhal)) {
1665		switch (operation) {
1666		case SCAN_OPT_BACKUP_BAND0:
1667			iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
1668			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1669						      (u8 *)&iotype);
1670
1671			break;
1672		case SCAN_OPT_RESTORE:
1673			iotype = IO_CMD_RESUME_DM_BY_SCAN;
1674			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1675						      (u8 *)&iotype);
1676			break;
1677		default:
1678			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1679				 "Unknown Scan Backup operation.\n");
1680			break;
1681		}
1682	}
1683}
1684
1685void rtl92ee_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
1686{
1687	struct rtl_priv *rtlpriv = rtl_priv(hw);
1688	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1689	struct rtl_phy *rtlphy = &rtlpriv->phy;
1690	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1691	u8 reg_bw_opmode;
1692	u8 reg_prsr_rsc;
1693
1694	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
1695		 "Switch to %s bandwidth\n",
1696		  rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
1697		  "20MHz" : "40MHz");
1698
1699	if (is_hal_stop(rtlhal)) {
1700		rtlphy->set_bwmode_inprogress = false;
1701		return;
1702	}
1703
1704	reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
1705	reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
1706
1707	switch (rtlphy->current_chan_bw) {
1708	case HT_CHANNEL_WIDTH_20:
1709		reg_bw_opmode |= BW_OPMODE_20MHZ;
1710		rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1711		break;
1712	case HT_CHANNEL_WIDTH_20_40:
1713		reg_bw_opmode &= ~BW_OPMODE_20MHZ;
1714		rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1715		reg_prsr_rsc = (reg_prsr_rsc & 0x90) |
1716			       (mac->cur_40_prime_sc << 5);
1717		rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
1718		break;
1719	default:
1720		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1721			 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
1722		break;
1723	}
1724
1725	switch (rtlphy->current_chan_bw) {
1726	case HT_CHANNEL_WIDTH_20:
1727		rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
1728		rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
1729		rtl_set_bbreg(hw, ROFDM0_TXPSEUDONOISEWGT,
1730			      (BIT(31) | BIT(30)), 0);
1731		break;
1732	case HT_CHANNEL_WIDTH_20_40:
1733		rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
1734		rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
1735		rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
1736			      (mac->cur_40_prime_sc >> 1));
1737		rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00,
1738			      mac->cur_40_prime_sc);
1739
1740		rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
1741			      (mac->cur_40_prime_sc ==
1742			       HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
1743		break;
1744	default:
1745		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1746			 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
1747		break;
1748	}
1749	rtl92ee_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
1750	rtlphy->set_bwmode_inprogress = false;
1751	RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, "\n");
1752}
1753
1754void rtl92ee_phy_set_bw_mode(struct ieee80211_hw *hw,
1755			     enum nl80211_channel_type ch_type)
1756{
1757	struct rtl_priv *rtlpriv = rtl_priv(hw);
1758	struct rtl_phy *rtlphy = &rtlpriv->phy;
1759	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1760	u8 tmp_bw = rtlphy->current_chan_bw;
1761
1762	if (rtlphy->set_bwmode_inprogress)
1763		return;
1764	rtlphy->set_bwmode_inprogress = true;
1765	if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1766		rtl92ee_phy_set_bw_mode_callback(hw);
1767	} else {
1768		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1769			 "false driver sleep or unload\n");
1770		rtlphy->set_bwmode_inprogress = false;
1771		rtlphy->current_chan_bw = tmp_bw;
1772	}
1773}
1774
1775void rtl92ee_phy_sw_chnl_callback(struct ieee80211_hw *hw)
1776{
1777	struct rtl_priv *rtlpriv = rtl_priv(hw);
1778	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1779	struct rtl_phy *rtlphy = &rtlpriv->phy;
1780	u32 delay;
1781
1782	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
1783		 "switch to channel%d\n", rtlphy->current_channel);
1784	if (is_hal_stop(rtlhal))
1785		return;
1786	do {
1787		if (!rtlphy->sw_chnl_inprogress)
1788			break;
1789		if (!_rtl92ee_phy_sw_chnl_step_by_step
1790		    (hw, rtlphy->current_channel, &rtlphy->sw_chnl_stage,
1791		     &rtlphy->sw_chnl_step, &delay)) {
1792			if (delay > 0)
1793				mdelay(delay);
1794			else
1795				continue;
1796		} else {
1797			rtlphy->sw_chnl_inprogress = false;
1798		}
1799		break;
1800	} while (true);
1801	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
1802}
1803
1804u8 rtl92ee_phy_sw_chnl(struct ieee80211_hw *hw)
1805{
1806	struct rtl_priv *rtlpriv = rtl_priv(hw);
1807	struct rtl_phy *rtlphy = &rtlpriv->phy;
1808	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1809
1810	if (rtlphy->sw_chnl_inprogress)
1811		return 0;
1812	if (rtlphy->set_bwmode_inprogress)
1813		return 0;
1814	RT_ASSERT((rtlphy->current_channel <= 14),
1815		  "WIRELESS_MODE_G but channel>14");
1816	rtlphy->sw_chnl_inprogress = true;
1817	rtlphy->sw_chnl_stage = 0;
1818	rtlphy->sw_chnl_step = 0;
1819	if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1820		rtl92ee_phy_sw_chnl_callback(hw);
1821		RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
1822			 "sw_chnl_inprogress false schdule workitem current channel %d\n",
1823			 rtlphy->current_channel);
1824		rtlphy->sw_chnl_inprogress = false;
1825	} else {
1826		RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
1827			 "sw_chnl_inprogress false driver sleep or unload\n");
1828		rtlphy->sw_chnl_inprogress = false;
1829	}
1830	return 1;
1831}
1832
1833static bool _rtl92ee_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
1834					      u8 channel, u8 *stage, u8 *step,
1835					      u32 *delay)
1836{
1837	struct rtl_priv *rtlpriv = rtl_priv(hw);
1838	struct rtl_phy *rtlphy = &rtlpriv->phy;
1839	struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];
1840	u32 precommoncmdcnt;
1841	struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];
1842	u32 postcommoncmdcnt;
1843	struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];
1844	u32 rfdependcmdcnt;
1845	struct swchnlcmd *currentcmd = NULL;
1846	u8 rfpath;
1847	u8 num_total_rfpath = rtlphy->num_total_rfpath;
1848
1849	precommoncmdcnt = 0;
1850	_rtl92ee_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
1851					  MAX_PRECMD_CNT,
1852					  CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0);
1853	_rtl92ee_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
1854					  MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
1855
1856	postcommoncmdcnt = 0;
1857
1858	_rtl92ee_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
1859					  MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0);
1860
1861	rfdependcmdcnt = 0;
1862
1863	RT_ASSERT((channel >= 1 && channel <= 14),
1864		  "illegal channel for Zebra: %d\n", channel);
1865
1866	_rtl92ee_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
1867					  MAX_RFDEPENDCMD_CNT,
1868					  CMDID_RF_WRITEREG,
1869					  RF_CHNLBW, channel, 10);
1870
1871	_rtl92ee_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
1872					  MAX_RFDEPENDCMD_CNT, CMDID_END,
1873					  0, 0, 0);
1874
1875	do {
1876		switch (*stage) {
1877		case 0:
1878			currentcmd = &precommoncmd[*step];
1879			break;
1880		case 1:
1881			currentcmd = &rfdependcmd[*step];
1882			break;
1883		case 2:
1884			currentcmd = &postcommoncmd[*step];
1885			break;
1886		default:
1887			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1888				 "Invalid 'stage' = %d, Check it!\n" , *stage);
1889			return true;
1890		}
1891
1892		if (currentcmd->cmdid == CMDID_END) {
1893			if ((*stage) == 2)
1894				return true;
1895			(*stage)++;
1896			(*step) = 0;
1897			continue;
1898		}
1899
1900		switch (currentcmd->cmdid) {
1901		case CMDID_SET_TXPOWEROWER_LEVEL:
1902			rtl92ee_phy_set_txpower_level(hw, channel);
1903			break;
1904		case CMDID_WRITEPORT_ULONG:
1905			rtl_write_dword(rtlpriv, currentcmd->para1,
1906					currentcmd->para2);
1907			break;
1908		case CMDID_WRITEPORT_USHORT:
1909			rtl_write_word(rtlpriv, currentcmd->para1,
1910				       (u16)currentcmd->para2);
1911			break;
1912		case CMDID_WRITEPORT_UCHAR:
1913			rtl_write_byte(rtlpriv, currentcmd->para1,
1914				       (u8)currentcmd->para2);
1915			break;
1916		case CMDID_RF_WRITEREG:
1917			for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
1918				rtlphy->rfreg_chnlval[rfpath] =
1919					((rtlphy->rfreg_chnlval[rfpath] &
1920					  0xfffff00) | currentcmd->para2);
1921
1922				rtl_set_rfreg(hw, (enum radio_path)rfpath,
1923					      currentcmd->para1,
1924					      0x3ff,
1925					      rtlphy->rfreg_chnlval[rfpath]);
1926			}
1927			break;
1928		default:
1929			RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
1930				 "switch case not process\n");
1931			break;
1932		}
1933
1934		break;
1935	} while (true);
1936
1937	(*delay) = currentcmd->msdelay;
1938	(*step)++;
1939	return false;
1940}
1941
1942static bool _rtl92ee_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable,
1943					      u32 cmdtableidx, u32 cmdtablesz,
1944					      enum swchnlcmd_id cmdid,
1945					      u32 para1, u32 para2, u32 msdelay)
1946{
1947	struct swchnlcmd *pcmd;
1948
1949	if (cmdtable == NULL) {
1950		RT_ASSERT(false, "cmdtable cannot be NULL.\n");
1951		return false;
1952	}
1953
1954	if (cmdtableidx >= cmdtablesz)
1955		return false;
1956
1957	pcmd = cmdtable + cmdtableidx;
1958	pcmd->cmdid = cmdid;
1959	pcmd->para1 = para1;
1960	pcmd->para2 = para2;
1961	pcmd->msdelay = msdelay;
1962	return true;
1963}
1964
1965static u8 _rtl92ee_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb)
1966{
1967	u32 reg_eac, reg_e94, reg_e9c;
1968	u8 result = 0x00;
1969	/* path-A IQK setting */
1970	/* PA/PAD controlled by 0x0 */
1971	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1972	rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0x180);
1973	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1974
1975	rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1976	rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1977	rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1978	rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1979
1980	rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82140303);
1981	rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x68160000);
1982
1983	/*LO calibration setting*/
1984	rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x00462911);
1985
1986	/*One shot, path A LOK & IQK*/
1987	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1988	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1989
1990	mdelay(IQK_DELAY_TIME);
1991
1992	reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
1993	reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD);
1994	reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD);
1995
1996	if (!(reg_eac & BIT(28)) &&
1997	    (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1998	    (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1999		result |= 0x01;
2000	else
2001		return result;
2002
2003	return result;
2004}
2005
2006static u8 _rtl92ee_phy_path_b_iqk(struct ieee80211_hw *hw)
2007{
2008	u32 reg_eac, reg_eb4, reg_ebc;
2009	u8 result = 0x00;
2010
2011	/* PA/PAD controlled by 0x0 */
2012	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
2013	rtl_set_rfreg(hw, RF90_PATH_B, 0xdf, RFREG_OFFSET_MASK, 0x180);
2014	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
2015
2016	rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000);
2017	rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
2018
2019	rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
2020	rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
2021	rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x18008c1c);
2022	rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
2023
2024	rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x821403e2);
2025	rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x68160000);
2026
2027	/* LO calibration setting */
2028	rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x00462911);
2029
2030	/*One shot, path B LOK & IQK*/
2031	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xfa000000);
2032	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
2033
2034	mdelay(IQK_DELAY_TIME);
2035
2036	reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
2037	reg_eb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD);
2038	reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD);
2039
2040	if (!(reg_eac & BIT(31)) &&
2041	    (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) &&
2042	    (((reg_ebc & 0x03FF0000) >> 16) != 0x42))
2043		result |= 0x01;
2044	else
2045		return result;
2046
2047	return result;
2048}
2049
2050static u8 _rtl92ee_phy_path_a_rx_iqk(struct ieee80211_hw *hw, bool config_pathb)
2051{
2052	u32 reg_eac, reg_e94, reg_e9c, reg_ea4 , u32temp;
2053	u8 result = 0x00;
2054
2055	/*Get TXIMR Setting*/
2056	/*Modify RX IQK mode table*/
2057	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
2058
2059	rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0);
2060	rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
2061	rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0000f);
2062	rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf117b);
2063
2064	/*PA/PAD control by 0x56, and set = 0x0*/
2065	rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0x980);
2066	rtl_set_rfreg(hw, RF90_PATH_A, 0x56, RFREG_OFFSET_MASK, 0x51000);
2067
2068	/*enter IQK mode*/
2069	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
2070
2071	/*IQK Setting*/
2072	rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
2073	rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
2074
2075	/*path a IQK setting*/
2076	rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
2077	rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
2078	rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
2079	rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
2080
2081	rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160c1f);
2082	rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x68160c1f);
2083
2084	/*LO calibration Setting*/
2085	rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911);
2086
2087	/*one shot,path A LOK & iqk*/
2088	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xfa000000);
2089	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
2090
2091	mdelay(IQK_DELAY_TIME);
2092
2093	/* Check failed */
2094	reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
2095	reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD);
2096	reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD);
2097
2098	if (!(reg_eac & BIT(28)) &&
2099	    (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
2100	    (((reg_e9c & 0x03FF0000) >> 16) != 0x42)) {
2101		result |= 0x01;
2102	} else {
2103		/*	PA/PAD controlled by 0x0 */
2104		rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
2105		rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0x180);
2106		return result;
2107	}
2108
2109	u32temp = 0x80007C00 | (reg_e94 & 0x3FF0000)  |
2110		  ((reg_e9c & 0x3FF0000) >> 16);
2111	rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, u32temp);
2112	/*RX IQK*/
2113	/*Modify RX IQK mode table*/
2114	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
2115
2116	rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0);
2117
2118	rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
2119	rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0000f);
2120	rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7ffa);
2121
2122	/*PA/PAD control by 0x56, and set = 0x0*/
2123	rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0x980);
2124	rtl_set_rfreg(hw, RF90_PATH_A, 0x56, RFREG_OFFSET_MASK, 0x51000);
2125
2126	/*enter IQK mode*/
2127	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
2128
2129	/*IQK Setting*/
2130	rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
2131
2132	/*path a IQK setting*/
2133	rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
2134	rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
2135	rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
2136	rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
2137
2138	rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160c1f);
2139	rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28160c1f);
2140
2141	/*LO calibration Setting*/
2142	rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a891);
2143	/*one shot,path A LOK & iqk*/
2144	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xfa000000);
2145	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
2146
2147	mdelay(IQK_DELAY_TIME);
2148	/*Check failed*/
2149	reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
2150	reg_ea4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2, MASKDWORD);
2151
2152	/*PA/PAD controlled by 0x0*/
2153	/*leave IQK mode*/
2154	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
2155	rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0x180);
2156	/*if Tx is OK, check whether Rx is OK*/
2157	if (!(reg_eac & BIT(27)) &&
2158	    (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) &&
2159	    (((reg_eac & 0x03FF0000) >> 16) != 0x36))
2160		result |= 0x02;
2161
2162	return result;
2163}
2164
2165static u8 _rtl92ee_phy_path_b_rx_iqk(struct ieee80211_hw *hw, bool config_pathb)
2166{
2167	struct rtl_priv *rtlpriv = rtl_priv(hw);
2168	u32 reg_eac, reg_eb4, reg_ebc, reg_ecc, reg_ec4, u32temp;
2169	u8 result = 0x00;
2170
2171	/*Get TXIMR Setting*/
2172	/*Modify RX IQK mode table*/
2173	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
2174
2175	rtl_set_rfreg(hw, RF90_PATH_B, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0);
2176	rtl_set_rfreg(hw, RF90_PATH_B, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
2177	rtl_set_rfreg(hw, RF90_PATH_B, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0000f);
2178	rtl_set_rfreg(hw, RF90_PATH_B, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf117b);
2179
2180	/*PA/PAD all off*/
2181	rtl_set_rfreg(hw, RF90_PATH_B, 0xdf, RFREG_OFFSET_MASK, 0x980);
2182	rtl_set_rfreg(hw, RF90_PATH_B, 0x56, RFREG_OFFSET_MASK, 0x51000);
2183
2184	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
2185
2186	/*IQK Setting*/
2187	rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
2188	rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
2189
2190	/*path a IQK setting*/
2191	rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
2192	rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
2193	rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x18008c1c);
2194	rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
2195
2196	rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82160c1f);
2197	rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x68160c1f);
2198
2199	/*LO calibration Setting*/
2200	rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911);
2201
2202	/*one shot,path A LOK & iqk*/
2203	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xfa000000);
2204	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
2205
2206	mdelay(IQK_DELAY_TIME);
2207
2208	/* Check failed */
2209	reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
2210	reg_eb4 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_B, MASKDWORD);
2211	reg_ebc = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_B, MASKDWORD);
2212
2213	if (!(reg_eac & BIT(31)) &&
2214	    (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) &&
2215	    (((reg_ebc & 0x03FF0000) >> 16) != 0x42)) {
2216		result |= 0x01;
2217	} else {
2218		/*	PA/PAD controlled by 0x0 */
2219		rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
2220		rtl_set_rfreg(hw, RF90_PATH_B, 0xdf, RFREG_OFFSET_MASK, 0x180);
2221		return result;
2222	}
2223
2224	u32temp = 0x80007C00 | (reg_eb4 & 0x3FF0000) |
2225		  ((reg_ebc & 0x3FF0000) >> 16);
2226	rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, u32temp);
2227	/*RX IQK*/
2228	/*Modify RX IQK mode table*/
2229	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
2230	rtl_set_rfreg(hw, RF90_PATH_B, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0);
2231
2232	rtl_set_rfreg(hw, RF90_PATH_B, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
2233	rtl_set_rfreg(hw, RF90_PATH_B, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0000f);
2234	rtl_set_rfreg(hw, RF90_PATH_B, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7ffa);
2235
2236	/*PA/PAD all off*/
2237	rtl_set_rfreg(hw, RF90_PATH_B, 0xdf, RFREG_OFFSET_MASK, 0x980);
2238	rtl_set_rfreg(hw, RF90_PATH_B, 0x56, RFREG_OFFSET_MASK, 0x51000);
2239
2240	/*enter IQK mode*/
2241	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
2242
2243	/*IQK Setting*/
2244	rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
2245
2246	/*path b IQK setting*/
2247	rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
2248	rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
2249	rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
2250	rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x18008c1c);
2251
2252	rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82160c1f);
2253	rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28160c1f);
2254
2255	/*LO calibration Setting*/
2256	rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a891);
2257	/*one shot,path A LOK & iqk*/
2258	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xfa000000);
2259	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
2260
2261	mdelay(IQK_DELAY_TIME);
2262	/*Check failed*/
2263	reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
2264	reg_ec4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_B_2, MASKDWORD);
2265	reg_ecc = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_B_2, MASKDWORD);
2266	/*PA/PAD controlled by 0x0*/
2267	/*leave IQK mode*/
2268	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
2269	rtl_set_rfreg(hw, RF90_PATH_B, 0xdf, RFREG_OFFSET_MASK, 0x180);
2270	/*if Tx is OK, check whether Rx is OK*/
2271	if (!(reg_eac & BIT(30)) &&
2272	    (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) &&
2273	    (((reg_ecc & 0x03FF0000) >> 16) != 0x36))
2274		result |= 0x02;
2275	else
2276		RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD, "Path B Rx IQK fail!!\n");
2277
2278	return result;
2279}
2280
2281static void _rtl92ee_phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw,
2282						bool b_iqk_ok, long result[][8],
2283						u8 final_candidate,
2284						bool btxonly)
2285{
2286	u32 oldval_0, x, tx0_a, reg;
2287	long y, tx0_c;
2288
2289	if (final_candidate == 0xFF) {
2290		return;
2291	} else if (b_iqk_ok) {
2292		oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
2293					  MASKDWORD) >> 22) & 0x3FF;
2294		x = result[final_candidate][0];
2295		if ((x & 0x00000200) != 0)
2296			x = x | 0xFFFFFC00;
2297		tx0_a = (x * oldval_0) >> 8;
2298		rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx0_a);
2299		rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(31),
2300			      ((x * oldval_0 >> 7) & 0x1));
2301		y = result[final_candidate][1];
2302		if ((y & 0x00000200) != 0)
2303			y = y | 0xFFFFFC00;
2304		tx0_c = (y * oldval_0) >> 8;
2305		rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000,
2306			      ((tx0_c & 0x3C0) >> 6));
2307		rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x003F0000,
2308			      (tx0_c & 0x3F));
2309		rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(29),
2310			      ((y * oldval_0 >> 7) & 0x1));
2311
2312		if (btxonly)
2313			return;
2314
2315		reg = result[final_candidate][2];
2316		rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg);
2317
2318		reg = result[final_candidate][3] & 0x3F;
2319		rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg);
2320
2321		reg = (result[final_candidate][3] >> 6) & 0xF;
2322		rtl_set_bbreg(hw, ROFDM0_RXIQEXTANTA, 0xF0000000, reg);
2323	}
2324}
2325
2326static void _rtl92ee_phy_path_b_fill_iqk_matrix(struct ieee80211_hw *hw,
2327						bool b_iqk_ok, long result[][8],
2328						u8 final_candidate,
2329						bool btxonly)
2330{
2331	u32 oldval_1, x, tx1_a, reg;
2332	long y, tx1_c;
2333
2334	if (final_candidate == 0xFF) {
2335		return;
2336	} else if (b_iqk_ok) {
2337		oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
2338					  MASKDWORD) >> 22) & 0x3FF;
2339		x = result[final_candidate][4];
2340		if ((x & 0x00000200) != 0)
2341			x = x | 0xFFFFFC00;
2342		tx1_a = (x * oldval_1) >> 8;
2343		rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx1_a);
2344		rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(27),
2345			      ((x * oldval_1 >> 7) & 0x1));
2346		y = result[final_candidate][5];
2347		if ((y & 0x00000200) != 0)
2348			y = y | 0xFFFFFC00;
2349		tx1_c = (y * oldval_1) >> 8;
2350		rtl_set_bbreg(hw, ROFDM0_XDTXAFE, 0xF0000000,
2351			      ((tx1_c & 0x3C0) >> 6));
2352		rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x003F0000,
2353			      (tx1_c & 0x3F));
2354		rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(25),
2355			      ((y * oldval_1 >> 7) & 0x1));
2356
2357		if (btxonly)
2358			return;
2359
2360		reg = result[final_candidate][6];
2361		rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg);
2362
2363		reg = result[final_candidate][7] & 0x3F;
2364		rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg);
2365
2366		reg = (result[final_candidate][7] >> 6) & 0xF;
2367		rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, 0xF0000000, reg);
2368	}
2369}
2370
2371static void _rtl92ee_phy_save_adda_registers(struct ieee80211_hw *hw,
2372					     u32 *addareg, u32 *addabackup,
2373					     u32 registernum)
2374{
2375	u32 i;
2376
2377	for (i = 0; i < registernum; i++)
2378		addabackup[i] = rtl_get_bbreg(hw, addareg[i], MASKDWORD);
2379}
2380
2381static void _rtl92ee_phy_save_mac_registers(struct ieee80211_hw *hw,
2382					    u32 *macreg, u32 *macbackup)
2383{
2384	struct rtl_priv *rtlpriv = rtl_priv(hw);
2385	u32 i;
2386
2387	for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
2388		macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]);
2389
2390	macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]);
2391}
2392
2393static void _rtl92ee_phy_reload_adda_registers(struct ieee80211_hw *hw,
2394					       u32 *addareg, u32 *addabackup,
2395					       u32 regiesternum)
2396{
2397	u32 i;
2398
2399	for (i = 0; i < regiesternum; i++)
2400		rtl_set_bbreg(hw, addareg[i], MASKDWORD, addabackup[i]);
2401}
2402
2403static void _rtl92ee_phy_reload_mac_registers(struct ieee80211_hw *hw,
2404					      u32 *macreg, u32 *macbackup)
2405{
2406	struct rtl_priv *rtlpriv = rtl_priv(hw);
2407	u32 i;
2408
2409	for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++)
2410		rtl_write_byte(rtlpriv, macreg[i], (u8)macbackup[i]);
2411	rtl_write_dword(rtlpriv, macreg[i], macbackup[i]);
2412}
2413
2414static void _rtl92ee_phy_path_adda_on(struct ieee80211_hw *hw, u32 *addareg,
2415				      bool is_patha_on, bool is2t)
2416{
2417	u32 pathon;
2418	u32 i;
2419
2420	pathon = is_patha_on ? 0x0fc01616 : 0x0fc01616;
2421	if (!is2t) {
2422		pathon = 0x0fc01616;
2423		rtl_set_bbreg(hw, addareg[0], MASKDWORD, 0x0fc01616);
2424	} else {
2425		rtl_set_bbreg(hw, addareg[0], MASKDWORD, pathon);
2426	}
2427
2428	for (i = 1; i < IQK_ADDA_REG_NUM; i++)
2429		rtl_set_bbreg(hw, addareg[i], MASKDWORD, pathon);
2430}
2431
2432static void _rtl92ee_phy_mac_setting_calibration(struct ieee80211_hw *hw,
2433						 u32 *macreg, u32 *macbackup)
2434{
2435	rtl_set_bbreg(hw, 0x520, 0x00ff0000, 0xff);
2436}
2437
2438static void _rtl92ee_phy_path_a_standby(struct ieee80211_hw *hw)
2439{
2440	rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0);
2441	rtl_set_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK, 0x10000);
2442	rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
2443}
2444
2445static bool _rtl92ee_phy_simularity_compare(struct ieee80211_hw *hw,
2446					    long result[][8], u8 c1, u8 c2)
2447{
2448	u32 i, j, diff, simularity_bitmap, bound;
2449
2450	u8 final_candidate[2] = { 0xFF, 0xFF };
2451	bool bresult = true/*, is2t = true*/;
2452	s32 tmp1, tmp2;
2453
2454	bound = 8;
2455
2456	simularity_bitmap = 0;
2457
2458	for (i = 0; i < bound; i++) {
2459		if ((i == 1) || (i == 3) || (i == 5) || (i == 7)) {
2460			if ((result[c1][i] & 0x00000200) != 0)
2461				tmp1 = result[c1][i] | 0xFFFFFC00;
2462			else
2463				tmp1 = result[c1][i];
2464
2465			if ((result[c2][i] & 0x00000200) != 0)
2466				tmp2 = result[c2][i] | 0xFFFFFC00;
2467			else
2468				tmp2 = result[c2][i];
2469		} else {
2470			tmp1 = result[c1][i];
2471			tmp2 = result[c2][i];
2472		}
2473
2474		diff = (tmp1 > tmp2) ? (tmp1 - tmp2) : (tmp2 - tmp1);
2475
2476		if (diff > MAX_TOLERANCE) {
2477			if ((i == 2 || i == 6) && !simularity_bitmap) {
2478				if (result[c1][i] + result[c1][i + 1] == 0)
2479					final_candidate[(i / 4)] = c2;
2480				else if (result[c2][i] + result[c2][i + 1] == 0)
2481					final_candidate[(i / 4)] = c1;
2482				else
2483					simularity_bitmap |= (1 << i);
2484			} else {
2485				simularity_bitmap |= (1 << i);
2486			}
2487		}
2488	}
2489
2490	if (simularity_bitmap == 0) {
2491		for (i = 0; i < (bound / 4); i++) {
2492			if (final_candidate[i] != 0xFF) {
2493				for (j = i * 4; j < (i + 1) * 4 - 2; j++)
2494					result[3][j] =
2495						result[final_candidate[i]][j];
2496				bresult = false;
2497			}
2498		}
2499		return bresult;
2500	}
2501	if (!(simularity_bitmap & 0x03)) {/*path A TX OK*/
2502		for (i = 0; i < 2; i++)
2503			result[3][i] = result[c1][i];
2504	}
2505	if (!(simularity_bitmap & 0x0c)) {/*path A RX OK*/
2506		for (i = 2; i < 4; i++)
2507			result[3][i] = result[c1][i];
2508	}
2509	if (!(simularity_bitmap & 0x30)) {/*path B TX OK*/
2510		for (i = 4; i < 6; i++)
2511			result[3][i] = result[c1][i];
2512	}
2513	if (!(simularity_bitmap & 0xc0)) {/*path B RX OK*/
2514		for (i = 6; i < 8; i++)
2515			result[3][i] = result[c1][i];
2516	}
2517	return false;
2518}
2519
2520static void _rtl92ee_phy_iq_calibrate(struct ieee80211_hw *hw,
2521				      long result[][8], u8 t, bool is2t)
2522{
2523	struct rtl_priv *rtlpriv = rtl_priv(hw);
2524	struct rtl_phy *rtlphy = &rtlpriv->phy;
2525	u32 i;
2526	u8 patha_ok, pathb_ok;
2527	u8 tmp_0xc50 = (u8)rtl_get_bbreg(hw, 0xc50, MASKBYTE0);
2528	u8 tmp_0xc58 = (u8)rtl_get_bbreg(hw, 0xc58, MASKBYTE0);
2529	u32 adda_reg[IQK_ADDA_REG_NUM] = {
2530		0x85c, 0xe6c, 0xe70, 0xe74,
2531		0xe78, 0xe7c, 0xe80, 0xe84,
2532		0xe88, 0xe8c, 0xed0, 0xed4,
2533		0xed8, 0xedc, 0xee0, 0xeec
2534	};
2535	u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
2536		0x522, 0x550, 0x551, 0x040
2537	};
2538	u32 iqk_bb_reg[IQK_BB_REG_NUM] = {
2539		ROFDM0_TRXPATHENABLE, ROFDM0_TRMUXPAR,
2540		RFPGA0_XCD_RFINTERFACESW, 0xb68, 0xb6c,
2541		0x870, 0x860,
2542		0x864, 0x800
2543	};
2544	const u32 retrycount = 2;
2545
2546	if (t == 0) {
2547		_rtl92ee_phy_save_adda_registers(hw, adda_reg,
2548						 rtlphy->adda_backup,
2549						 IQK_ADDA_REG_NUM);
2550		_rtl92ee_phy_save_mac_registers(hw, iqk_mac_reg,
2551						rtlphy->iqk_mac_backup);
2552		_rtl92ee_phy_save_adda_registers(hw, iqk_bb_reg,
2553						 rtlphy->iqk_bb_backup,
2554						 IQK_BB_REG_NUM);
2555	}
2556
2557	_rtl92ee_phy_path_adda_on(hw, adda_reg, true, is2t);
2558
2559	/*BB setting*/
2560	rtl_set_bbreg(hw, RFPGA0_RFMOD, BIT(24), 0x00);
2561	rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKDWORD, 0x03a05600);
2562	rtl_set_bbreg(hw, ROFDM0_TRMUXPAR, MASKDWORD, 0x000800e4);
2563	rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, MASKDWORD, 0x22208200);
2564
2565	rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BIT(10), 0x01);
2566	rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BIT(26), 0x01);
2567	rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, BIT(10), 0x01);
2568	rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, BIT(10), 0x01);
2569
2570	_rtl92ee_phy_mac_setting_calibration(hw, iqk_mac_reg,
2571					     rtlphy->iqk_mac_backup);
2572	/* Page B init*/
2573	/* IQ calibration setting*/
2574	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
2575	rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
2576	rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
2577
2578	for (i = 0 ; i < retrycount ; i++) {
2579		patha_ok = _rtl92ee_phy_path_a_iqk(hw, is2t);
2580
2581		if (patha_ok == 0x01) {
2582			RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
2583				 "Path A Tx IQK Success!!\n");
2584			result[t][0] = (rtl_get_bbreg(hw,
2585						      RTX_POWER_BEFORE_IQK_A,
2586						      MASKDWORD) & 0x3FF0000)
2587						      >> 16;
2588			result[t][1] = (rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A,
2589						      MASKDWORD) & 0x3FF0000)
2590						      >> 16;
2591			break;
2592		}
2593		RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
2594			 "Path A Tx IQK Fail!!, ret = 0x%x\n",
2595			 patha_ok);
2596	}
2597
2598	for (i = 0 ; i < retrycount ; i++) {
2599		patha_ok = _rtl92ee_phy_path_a_rx_iqk(hw, is2t);
2600
2601		if (patha_ok == 0x03) {
2602			RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
2603				 "Path A Rx IQK Success!!\n");
2604			result[t][2] = (rtl_get_bbreg(hw,
2605						      RRX_POWER_BEFORE_IQK_A_2,
2606						      MASKDWORD) & 0x3FF0000)
2607						      >> 16;
2608			result[t][3] = (rtl_get_bbreg(hw,
2609						      RRX_POWER_AFTER_IQK_A_2,
2610						      MASKDWORD) & 0x3FF0000)
2611						      >> 16;
2612			break;
2613		}
2614		RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
2615			 "Path A Rx IQK Fail!!, ret = 0x%x\n",
2616			  patha_ok);
2617	}
2618
2619	if (0x00 == patha_ok)
2620		RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
2621			 "Path A IQK failed!!, ret = 0\n");
2622	if (is2t) {
2623		_rtl92ee_phy_path_a_standby(hw);
2624		/* Turn Path B ADDA on */
2625		_rtl92ee_phy_path_adda_on(hw, adda_reg, false, is2t);
2626
2627		/* IQ calibration setting */
2628		rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
2629		rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
2630		rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
2631
2632		for (i = 0 ; i < retrycount ; i++) {
2633			pathb_ok = _rtl92ee_phy_path_b_iqk(hw);
2634			if (pathb_ok == 0x01) {
2635				RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
2636					 "Path B Tx IQK Success!!\n");
2637				result[t][4] = (rtl_get_bbreg(hw,
2638							RTX_POWER_BEFORE_IQK_B,
2639							MASKDWORD) & 0x3FF0000)
2640							>> 16;
2641				result[t][5] = (rtl_get_bbreg(hw,
2642							RTX_POWER_AFTER_IQK_B,
2643							MASKDWORD) & 0x3FF0000)
2644							>> 16;
2645				break;
2646			}
2647			RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
2648				 "Path B Tx IQK Fail!!, ret = 0x%x\n",
2649				 pathb_ok);
2650		}
2651
2652		for (i = 0 ; i < retrycount ; i++) {
2653			pathb_ok = _rtl92ee_phy_path_b_rx_iqk(hw, is2t);
2654			if (pathb_ok == 0x03) {
2655				RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
2656					 "Path B Rx IQK Success!!\n");
2657				result[t][6] = (rtl_get_bbreg(hw,
2658						       RRX_POWER_BEFORE_IQK_B_2,
2659						       MASKDWORD) & 0x3FF0000)
2660						       >> 16;
2661				result[t][7] = (rtl_get_bbreg(hw,
2662						       RRX_POWER_AFTER_IQK_B_2,
2663						       MASKDWORD) & 0x3FF0000)
2664						       >> 16;
2665				break;
2666			}
2667			RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
2668				 "Path B Rx IQK Fail!!, ret = 0x%x\n",
2669				 pathb_ok);
2670		}
2671
2672		if (0x00 == pathb_ok)
2673			RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
2674				 "Path B IQK failed!!, ret = 0\n");
2675	}
2676	/* Back to BB mode, load original value */
2677	RT_TRACE(rtlpriv, COMP_RF, DBG_LOUD,
2678		 "IQK:Back to BB mode, load original value!\n");
2679	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0);
2680
2681	if (t != 0) {
2682		/* Reload ADDA power saving parameters */
2683		_rtl92ee_phy_reload_adda_registers(hw, adda_reg,
2684						   rtlphy->adda_backup,
2685						   IQK_ADDA_REG_NUM);
2686
2687		/* Reload MAC parameters */
2688		_rtl92ee_phy_reload_mac_registers(hw, iqk_mac_reg,
2689						  rtlphy->iqk_mac_backup);
2690
2691		_rtl92ee_phy_reload_adda_registers(hw, iqk_bb_reg,
2692						   rtlphy->iqk_bb_backup,
2693						   IQK_BB_REG_NUM);
2694
2695		/* Restore RX initial gain */
2696		rtl_set_bbreg(hw, 0xc50, MASKBYTE0, 0x50);
2697		rtl_set_bbreg(hw, 0xc50, MASKBYTE0, tmp_0xc50);
2698		if (is2t) {
2699			rtl_set_bbreg(hw, 0xc50, MASKBYTE0, 0x50);
2700			rtl_set_bbreg(hw, 0xc58, MASKBYTE0, tmp_0xc58);
2701		}
2702
2703		/* load 0xe30 IQC default value */
2704		rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x01008c00);
2705		rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x01008c00);
2706	}
2707}
2708
2709static void _rtl92ee_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
2710{
2711	u8 tmpreg;
2712	u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
2713	struct rtl_priv *rtlpriv = rtl_priv(hw);
2714
2715	tmpreg = rtl_read_byte(rtlpriv, 0xd03);
2716
2717	if ((tmpreg & 0x70) != 0)
2718		rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
2719	else
2720		rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
2721
2722	if ((tmpreg & 0x70) != 0) {
2723		rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS);
2724
2725		if (is2t)
2726			rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00,
2727						  MASK12BITS);
2728
2729		rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS,
2730			      (rf_a_mode & 0x8FFFF) | 0x10000);
2731
2732		if (is2t)
2733			rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
2734				      (rf_b_mode & 0x8FFFF) | 0x10000);
2735	}
2736	lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS);
2737
2738	rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, lc_cal | 0x08000);
2739
2740	mdelay(100);
2741
2742	if ((tmpreg & 0x70) != 0) {
2743		rtl_write_byte(rtlpriv, 0xd03, tmpreg);
2744		rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode);
2745
2746		if (is2t)
2747			rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
2748				      rf_b_mode);
2749	} else {
2750		rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
2751	}
2752}
2753
2754static void _rtl92ee_phy_set_rfpath_switch(struct ieee80211_hw *hw,
2755					   bool bmain, bool is2t)
2756{
2757	struct rtl_priv *rtlpriv = rtl_priv(hw);
2758	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2759	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
2760
2761	RT_TRACE(rtlpriv, COMP_INIT , DBG_LOUD , "\n");
2762
2763	if (is_hal_stop(rtlhal)) {
2764		u8 u1btmp;
2765
2766		u1btmp = rtl_read_byte(rtlpriv, REG_LEDCFG0);
2767		rtl_write_byte(rtlpriv, REG_LEDCFG0, u1btmp | BIT(7));
2768		rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(13), 0x01);
2769	}
2770	if (is2t) {
2771		if (bmain)
2772			rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
2773				      BIT(5) | BIT(6), 0x1);
2774		else
2775			rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
2776				      BIT(5) | BIT(6), 0x2);
2777	} else {
2778		rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BIT(8) | BIT(9), 0);
2779		rtl_set_bbreg(hw, 0x914, MASKLWORD, 0x0201);
2780
2781		/* We use the RF definition of MAIN and AUX,
2782		 * left antenna and right antenna repectively.
2783		 * Default output at AUX.
2784		 */
2785		if (bmain) {
2786			rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE,
2787				      BIT(14) | BIT(13) | BIT(12), 0);
2788			rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
2789				      BIT(5) | BIT(4) | BIT(3), 0);
2790			if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV)
2791				rtl_set_bbreg(hw, RCONFIG_RAM64x16, BIT(31), 0);
2792		} else {
2793			rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE,
2794				      BIT(14) | BIT(13) | BIT(12), 1);
2795			rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
2796				      BIT(5) | BIT(4) | BIT(3), 1);
2797			if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV)
2798				rtl_set_bbreg(hw, RCONFIG_RAM64x16, BIT(31), 1);
2799		}
2800	}
2801}
2802
2803#undef IQK_ADDA_REG_NUM
2804#undef IQK_DELAY_TIME
2805
2806static u8 rtl92ee_get_rightchnlplace_for_iqk(u8 chnl)
2807{
2808	u8 channel_all[59] = {
2809		1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
2810		36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58,
2811		60, 62, 64, 100, 102, 104, 106, 108, 110, 112,
2812		114, 116, 118, 120, 122, 124, 126, 128,	130,
2813		132, 134, 136, 138, 140, 149, 151, 153, 155,
2814		157, 159, 161, 163, 165
2815	};
2816	u8 place = chnl;
2817
2818	if (chnl > 14) {
2819		for (place = 14; place < sizeof(channel_all); place++) {
2820			if (channel_all[place] == chnl)
2821				return place - 13;
2822		}
2823	}
2824
2825	return 0;
2826}
2827
2828void rtl92ee_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
2829{
2830	struct rtl_priv *rtlpriv = rtl_priv(hw);
2831	struct rtl_phy *rtlphy = &rtlpriv->phy;
2832	long result[4][8];
2833	u8 i, final_candidate;
2834	bool b_patha_ok, b_pathb_ok;
2835	long reg_e94, reg_e9c, reg_ea4, reg_eac;
2836	long reg_eb4, reg_ebc, reg_ec4, reg_ecc;
2837	bool is12simular, is13simular, is23simular;
2838	u8 idx;
2839	u32 iqk_bb_reg[IQK_BB_REG_NUM] = {
2840		ROFDM0_XARXIQIMBALANCE,
2841		ROFDM0_XBRXIQIMBALANCE,
2842		ROFDM0_ECCATHRESHOLD,
2843		ROFDM0_AGCRSSITABLE,
2844		ROFDM0_XATXIQIMBALANCE,
2845		ROFDM0_XBTXIQIMBALANCE,
2846		ROFDM0_XCTXAFE,
2847		ROFDM0_XDTXAFE,
2848		ROFDM0_RXIQEXTANTA
2849	};
2850
2851	if (b_recovery) {
2852		_rtl92ee_phy_reload_adda_registers(hw, iqk_bb_reg,
2853						   rtlphy->iqk_bb_backup, 9);
2854		return;
2855	}
2856
2857	for (i = 0; i < 8; i++) {
2858		result[0][i] = 0;
2859		result[1][i] = 0;
2860		result[2][i] = 0;
2861
2862		if ((i == 0) || (i == 2) || (i == 4)  || (i == 6))
2863			result[3][i] = 0x100;
2864		else
2865			result[3][i] = 0;
2866	}
2867	final_candidate = 0xff;
2868	b_patha_ok = false;
2869	b_pathb_ok = false;
2870	is12simular = false;
2871	is23simular = false;
2872	is13simular = false;
2873	for (i = 0; i < 3; i++) {
2874		_rtl92ee_phy_iq_calibrate(hw, result, i, true);
2875		if (i == 1) {
2876			is12simular = _rtl92ee_phy_simularity_compare(hw,
2877								      result,
2878								      0, 1);
2879			if (is12simular) {
2880				final_candidate = 0;
2881				break;
2882			}
2883		}
2884
2885		if (i == 2) {
2886			is13simular = _rtl92ee_phy_simularity_compare(hw,
2887								      result,
2888								      0, 2);
2889			if (is13simular) {
2890				final_candidate = 0;
2891				break;
2892			}
2893			is23simular = _rtl92ee_phy_simularity_compare(hw,
2894								      result,
2895								      1, 2);
2896			if (is23simular)
2897				final_candidate = 1;
2898			else
2899				final_candidate = 3;
2900		}
2901	}
2902
2903	for (i = 0; i < 4; i++) {
2904		reg_e94 = result[i][0];
2905		reg_e9c = result[i][1];
2906		reg_ea4 = result[i][2];
2907		reg_eac = result[i][3];
2908		reg_eb4 = result[i][4];
2909		reg_ebc = result[i][5];
2910		reg_ec4 = result[i][6];
2911		reg_ecc = result[i][7];
2912	}
2913
2914	if (final_candidate != 0xff) {
2915		reg_e94 = result[final_candidate][0];
2916		rtlphy->reg_e94 = reg_e94;
2917		reg_e9c = result[final_candidate][1];
2918		rtlphy->reg_e9c = reg_e9c;
2919		reg_ea4 = result[final_candidate][2];
2920		reg_eac = result[final_candidate][3];
2921		reg_eb4 = result[final_candidate][4];
2922		rtlphy->reg_eb4 = reg_eb4;
2923		reg_ebc = result[final_candidate][5];
2924		rtlphy->reg_ebc = reg_ebc;
2925		reg_ec4 = result[final_candidate][6];
2926		reg_ecc = result[final_candidate][7];
2927		b_patha_ok = true;
2928		b_pathb_ok = true;
2929	} else {
2930		rtlphy->reg_e94 = 0x100;
2931		rtlphy->reg_eb4 = 0x100;
2932		rtlphy->reg_e9c = 0x0;
2933		rtlphy->reg_ebc = 0x0;
2934	}
2935
2936	if (reg_e94 != 0)
2937		_rtl92ee_phy_path_a_fill_iqk_matrix(hw, b_patha_ok, result,
2938						    final_candidate,
2939						    (reg_ea4 == 0));
2940
2941	_rtl92ee_phy_path_b_fill_iqk_matrix(hw, b_pathb_ok, result,
2942					    final_candidate,
2943					    (reg_ec4 == 0));
2944
2945	idx = rtl92ee_get_rightchnlplace_for_iqk(rtlphy->current_channel);
2946
2947	/* To Fix BSOD when final_candidate is 0xff */
2948	if (final_candidate < 4) {
2949		for (i = 0; i < IQK_MATRIX_REG_NUM; i++)
2950			rtlphy->iqk_matrix[idx].value[0][i] =
2951				result[final_candidate][i];
2952
2953		rtlphy->iqk_matrix[idx].iqk_done = true;
2954	}
2955	_rtl92ee_phy_save_adda_registers(hw, iqk_bb_reg,
2956					 rtlphy->iqk_bb_backup, 9);
2957}
2958
2959void rtl92ee_phy_lc_calibrate(struct ieee80211_hw *hw)
2960{
2961	struct rtl_priv *rtlpriv = rtl_priv(hw);
2962	struct rtl_phy *rtlphy = &rtlpriv->phy;
2963	struct rtl_hal *rtlhal = &rtlpriv->rtlhal;
2964	u32 timeout = 2000, timecount = 0;
2965
2966	while (rtlpriv->mac80211.act_scanning && timecount < timeout) {
2967		udelay(50);
2968		timecount += 50;
2969	}
2970
2971	rtlphy->lck_inprogress = true;
2972	RTPRINT(rtlpriv, FINIT, INIT_IQK,
2973		"LCK:Start!!! currentband %x delay %d ms\n",
2974		 rtlhal->current_bandtype, timecount);
2975
2976	_rtl92ee_phy_lc_calibrate(hw, false);
2977
2978	rtlphy->lck_inprogress = false;
2979}
2980
2981void rtl92ee_phy_ap_calibrate(struct ieee80211_hw *hw, char delta)
2982{
2983}
2984
2985void rtl92ee_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
2986{
2987	_rtl92ee_phy_set_rfpath_switch(hw, bmain, false);
2988}
2989
2990bool rtl92ee_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
2991{
2992	struct rtl_priv *rtlpriv = rtl_priv(hw);
2993	struct rtl_phy *rtlphy = &rtlpriv->phy;
2994	bool postprocessing = false;
2995
2996	RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2997		 "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
2998		  iotype, rtlphy->set_io_inprogress);
2999	do {
3000		switch (iotype) {
3001		case IO_CMD_RESUME_DM_BY_SCAN:
3002			RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
3003				 "[IO CMD] Resume DM after scan.\n");
3004			postprocessing = true;
3005			break;
3006		case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
3007			RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
3008				 "[IO CMD] Pause DM before scan.\n");
3009			postprocessing = true;
3010			break;
3011		default:
3012			RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
3013				 "switch case not process\n");
3014			break;
3015		}
3016	} while (false);
3017	if (postprocessing && !rtlphy->set_io_inprogress) {
3018		rtlphy->set_io_inprogress = true;
3019		rtlphy->current_io_type = iotype;
3020	} else {
3021		return false;
3022	}
3023	rtl92ee_phy_set_io(hw);
3024	RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype);
3025	return true;
3026}
3027
3028static void rtl92ee_phy_set_io(struct ieee80211_hw *hw)
3029{
3030	struct rtl_priv *rtlpriv = rtl_priv(hw);
3031	struct rtl_phy *rtlphy = &rtlpriv->phy;
3032	struct dig_t *dm_dig = &rtlpriv->dm_digtable;
3033
3034	RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
3035		 "--->Cmd(%#x), set_io_inprogress(%d)\n",
3036		  rtlphy->current_io_type, rtlphy->set_io_inprogress);
3037	switch (rtlphy->current_io_type) {
3038	case IO_CMD_RESUME_DM_BY_SCAN:
3039		rtl92ee_dm_write_dig(hw, rtlphy->initgain_backup.xaagccore1);
3040		rtl92ee_dm_write_cck_cca_thres(hw, rtlphy->initgain_backup.cca);
3041		RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE , "no set txpower\n");
3042		rtl92ee_phy_set_txpower_level(hw, rtlphy->current_channel);
3043		break;
3044	case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
3045		/* 8192eebt */
3046		rtlphy->initgain_backup.xaagccore1 = dm_dig->cur_igvalue;
3047		rtl92ee_dm_write_dig(hw, 0x17);
3048		rtlphy->initgain_backup.cca = dm_dig->cur_cck_cca_thres;
3049		rtl92ee_dm_write_cck_cca_thres(hw, 0x40);
3050		break;
3051	default:
3052		RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
3053			 "switch case not process\n");
3054		break;
3055	}
3056	rtlphy->set_io_inprogress = false;
3057	RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
3058		 "(%#x)\n", rtlphy->current_io_type);
3059}
3060
3061static void rtl92ee_phy_set_rf_on(struct ieee80211_hw *hw)
3062{
3063	struct rtl_priv *rtlpriv = rtl_priv(hw);
3064
3065	rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
3066	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
3067	/*rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);*/
3068	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
3069	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
3070	rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
3071}
3072
3073static void _rtl92ee_phy_set_rf_sleep(struct ieee80211_hw *hw)
3074{
3075	struct rtl_priv *rtlpriv = rtl_priv(hw);
3076
3077	rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
3078	rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
3079
3080	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
3081	rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
3082}
3083
3084static bool _rtl92ee_phy_set_rf_power_state(struct ieee80211_hw *hw,
3085					    enum rf_pwrstate rfpwr_state)
3086{
3087	struct rtl_priv *rtlpriv = rtl_priv(hw);
3088	struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
3089	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
3090	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
3091	bool bresult = true;
3092	u8 i, queue_id;
3093	struct rtl8192_tx_ring *ring = NULL;
3094
3095	switch (rfpwr_state) {
3096	case ERFON:
3097		if ((ppsc->rfpwr_state == ERFOFF) &&
3098		    RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
3099			bool rtstatus;
3100			u32 initializecount = 0;
3101
3102			do {
3103				initializecount++;
3104				RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
3105					 "IPS Set eRf nic enable\n");
3106				rtstatus = rtl_ps_enable_nic(hw);
3107			} while (!rtstatus && (initializecount < 10));
3108			RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
3109		} else {
3110			RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
3111				 "Set ERFON sleeping:%d ms\n",
3112				  jiffies_to_msecs(jiffies -
3113						   ppsc->last_sleep_jiffies));
3114			ppsc->last_awake_jiffies = jiffies;
3115			rtl92ee_phy_set_rf_on(hw);
3116		}
3117		if (mac->link_state == MAC80211_LINKED)
3118			rtlpriv->cfg->ops->led_control(hw, LED_CTL_LINK);
3119		else
3120			rtlpriv->cfg->ops->led_control(hw, LED_CTL_NO_LINK);
3121		break;
3122	case ERFOFF:
3123		for (queue_id = 0, i = 0;
3124		     queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
3125			ring = &pcipriv->dev.tx_ring[queue_id];
3126			if (queue_id == BEACON_QUEUE ||
3127			    skb_queue_len(&ring->queue) == 0) {
3128				queue_id++;
3129				continue;
3130			} else {
3131				RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
3132					 "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
3133					 (i + 1), queue_id,
3134					 skb_queue_len(&ring->queue));
3135
3136				udelay(10);
3137				i++;
3138			}
3139			if (i >= MAX_DOZE_WAITING_TIMES_9x) {
3140				RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
3141					 "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
3142					  MAX_DOZE_WAITING_TIMES_9x,
3143					  queue_id,
3144					  skb_queue_len(&ring->queue));
3145				break;
3146			}
3147		}
3148
3149		if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
3150			RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
3151				 "IPS Set eRf nic disable\n");
3152			rtl_ps_disable_nic(hw);
3153			RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
3154		} else {
3155			if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
3156				rtlpriv->cfg->ops->led_control(hw,
3157							LED_CTL_NO_LINK);
3158			} else {
3159				rtlpriv->cfg->ops->led_control(hw,
3160							LED_CTL_POWER_OFF);
3161			}
3162		}
3163		break;
3164	case ERFSLEEP:
3165		if (ppsc->rfpwr_state == ERFOFF)
3166			break;
3167		for (queue_id = 0, i = 0;
3168		     queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
3169			ring = &pcipriv->dev.tx_ring[queue_id];
3170			if (skb_queue_len(&ring->queue) == 0) {
3171				queue_id++;
3172				continue;
3173			} else {
3174				RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
3175					 "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
3176					 (i + 1), queue_id,
3177					 skb_queue_len(&ring->queue));
3178				udelay(10);
3179				i++;
3180			}
3181			if (i >= MAX_DOZE_WAITING_TIMES_9x) {
3182				RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
3183					 "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
3184					  MAX_DOZE_WAITING_TIMES_9x,
3185					  queue_id,
3186					  skb_queue_len(&ring->queue));
3187				break;
3188			}
3189		}
3190		RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
3191			 "Set ERFSLEEP awaked:%d ms\n",
3192			  jiffies_to_msecs(jiffies -
3193					   ppsc->last_awake_jiffies));
3194		ppsc->last_sleep_jiffies = jiffies;
3195		_rtl92ee_phy_set_rf_sleep(hw);
3196		break;
3197	default:
3198		RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
3199			 "switch case not process\n");
3200		bresult = false;
3201		break;
3202	}
3203	if (bresult)
3204		ppsc->rfpwr_state = rfpwr_state;
3205	return bresult;
3206}
3207
3208bool rtl92ee_phy_set_rf_power_state(struct ieee80211_hw *hw,
3209				    enum rf_pwrstate rfpwr_state)
3210{
3211	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
3212
3213	bool bresult = false;
3214
3215	if (rfpwr_state == ppsc->rfpwr_state)
3216		return bresult;
3217	bresult = _rtl92ee_phy_set_rf_power_state(hw, rfpwr_state);
3218	return bresult;
3219}
3220