brintos

brintos / linux-shallow public Read only

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