Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
   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 "../core.h"
  30#include "reg.h"
  31#include "def.h"
  32#include "phy.h"
  33#include "../rtl8723com/phy_common.h"
  34#include "rf.h"
  35#include "dm.h"
  36#include "table.h"
  37#include "trx.h"
  38
  39static bool _rtl8723be_phy_bb8723b_config_parafile(struct ieee80211_hw *hw);
  40static bool _rtl8723be_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
  41						       u8 configtype);
  42static bool rtl8723be_phy_sw_chn_step_by_step(struct ieee80211_hw *hw,
  43					      u8 channel, u8 *stage,
  44					      u8 *step, u32 *delay);
  45static bool _rtl8723be_check_condition(struct ieee80211_hw *hw,
  46				       const u32  condition)
  47{
  48	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
  49	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
  50	u32 _board = rtlefuse->board_type; /*need efuse define*/
  51	u32 _interface = rtlhal->interface;
  52	u32 _platform = 0x08;/*SupportPlatform */
  53	u32 cond = condition;
  54
  55	if (condition == 0xCDCDCDCD)
  56		return true;
  57
  58	cond = condition & 0xFF;
  59	if ((_board & cond) == 0 && cond != 0x1F)
  60		return false;
  61
  62	cond = condition & 0xFF00;
  63	cond = cond >> 8;
  64	if ((_interface & cond) == 0 && cond != 0x07)
  65		return false;
  66
  67	cond = condition & 0xFF0000;
  68	cond = cond >> 16;
  69	if ((_platform & cond) == 0 && cond != 0x0F)
  70		return false;
  71	return true;
  72}
  73
  74static bool _rtl8723be_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
  75{
  76	struct rtl_priv *rtlpriv = rtl_priv(hw);
  77	u32 i;
  78	u32 arraylength;
  79	u32 *ptrarray;
  80
  81	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read rtl8723beMACPHY_Array\n");
  82	arraylength = RTL8723BEMAC_1T_ARRAYLEN;
  83	ptrarray = RTL8723BEMAC_1T_ARRAY;
  84	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
  85		 "Img:RTL8723bEMAC_1T_ARRAY LEN %d\n", arraylength);
  86	for (i = 0; i < arraylength; i = i + 2)
  87		rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]);
  88	return true;
  89}
  90
  91static bool _rtl8723be_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
  92						     u8 configtype)
  93{
  94	#define READ_NEXT_PAIR(v1, v2, i) \
  95		do { \
  96			i += 2; \
  97			v1 = array_table[i];\
  98			v2 = array_table[i+1]; \
  99		} while (0)
 100
 101	int i;
 102	u32 *array_table;
 103	u16 arraylen;
 104	struct rtl_priv *rtlpriv = rtl_priv(hw);
 105	u32 v1 = 0, v2 = 0;
 106
 107	if (configtype == BASEBAND_CONFIG_PHY_REG) {
 108		arraylen = RTL8723BEPHY_REG_1TARRAYLEN;
 109		array_table = RTL8723BEPHY_REG_1TARRAY;
 110
 111		for (i = 0; i < arraylen; i = i + 2) {
 112			v1 = array_table[i];
 113			v2 = array_table[i+1];
 114			if (v1 < 0xcdcdcdcd) {
 115				rtl_bb_delay(hw, v1, v2);
 116			} else {/*This line is the start line of branch.*/
 117				if (!_rtl8723be_check_condition(hw, array_table[i])) {
 118					/*Discard the following (offset, data) pairs*/
 119					READ_NEXT_PAIR(v1, v2, i);
 120					while (v2 != 0xDEAD &&
 121					       v2 != 0xCDEF &&
 122					       v2 != 0xCDCD &&
 123					       i < arraylen - 2) {
 124						READ_NEXT_PAIR(v1, v2, i);
 125					}
 126					i -= 2; /* prevent from for-loop += 2*/
 127				/* Configure matched pairs and
 128				 * skip to end of if-else.
 129				 */
 130				} else {
 131					READ_NEXT_PAIR(v1, v2, i);
 132					while (v2 != 0xDEAD &&
 133					       v2 != 0xCDEF &&
 134					       v2 != 0xCDCD &&
 135					       i < arraylen - 2) {
 136						rtl_bb_delay(hw,
 137								    v1, v2);
 138						READ_NEXT_PAIR(v1, v2, i);
 139					}
 140
 141					while (v2 != 0xDEAD && i < arraylen - 2)
 142						READ_NEXT_PAIR(v1, v2, i);
 143				}
 144			}
 145		}
 146	} else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
 147		arraylen = RTL8723BEAGCTAB_1TARRAYLEN;
 148		array_table = RTL8723BEAGCTAB_1TARRAY;
 149
 150		for (i = 0; i < arraylen; i = i + 2) {
 151			v1 = array_table[i];
 152			v2 = array_table[i+1];
 153			if (v1 < 0xCDCDCDCD) {
 154				rtl_set_bbreg(hw, array_table[i],
 155					      MASKDWORD,
 156					      array_table[i + 1]);
 157				udelay(1);
 158				continue;
 159			} else {/*This line is the start line of branch.*/
 160				if (!_rtl8723be_check_condition(hw, array_table[i])) {
 161					/* Discard the following
 162					 * (offset, data) pairs
 163					 */
 164					READ_NEXT_PAIR(v1, v2, i);
 165					while (v2 != 0xDEAD &&
 166					       v2 != 0xCDEF &&
 167					       v2 != 0xCDCD &&
 168					       i < arraylen - 2) {
 169						READ_NEXT_PAIR(v1, v2, i);
 170					}
 171					i -= 2; /* prevent from for-loop += 2*/
 172				/*Configure matched pairs and
 173				 *skip to end of if-else.
 174				 */
 175				} else {
 176					READ_NEXT_PAIR(v1, v2, i);
 177					while (v2 != 0xDEAD &&
 178					       v2 != 0xCDEF &&
 179					       v2 != 0xCDCD &&
 180					       i < arraylen - 2) {
 181						rtl_set_bbreg(hw, array_table[i],
 182							      MASKDWORD,
 183							      array_table[i + 1]);
 184						udelay(1);
 185						READ_NEXT_PAIR(v1, v2, i);
 186					}
 187
 188					while (v2 != 0xDEAD && i < arraylen - 2)
 189						READ_NEXT_PAIR(v1, v2, i);
 190				}
 191			}
 192			RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 193				 "The agctab_array_table[0] is "
 194				  "%x Rtl818EEPHY_REGArray[1] is %x\n",
 195				  array_table[i], array_table[i + 1]);
 196		}
 197	}
 198	return true;
 199}
 200
 201static u8 _rtl8723be_get_rate_section_index(u32 regaddr)
 202{
 203	u8 index = 0;
 204
 205	switch (regaddr) {
 206	case RTXAGC_A_RATE18_06:
 207	case RTXAGC_B_RATE18_06:
 208		index = 0;
 209		break;
 210	case RTXAGC_A_RATE54_24:
 211	case RTXAGC_B_RATE54_24:
 212		index = 1;
 213		break;
 214	case RTXAGC_A_CCK1_MCS32:
 215	case RTXAGC_B_CCK1_55_MCS32:
 216		index = 2;
 217		break;
 218	case RTXAGC_B_CCK11_A_CCK2_11:
 219		index = 3;
 220		break;
 221	case RTXAGC_A_MCS03_MCS00:
 222	case RTXAGC_B_MCS03_MCS00:
 223		index = 4;
 224		break;
 225	case RTXAGC_A_MCS07_MCS04:
 226	case RTXAGC_B_MCS07_MCS04:
 227		index = 5;
 228		break;
 229	case RTXAGC_A_MCS11_MCS08:
 230	case RTXAGC_B_MCS11_MCS08:
 231		index = 6;
 232		break;
 233	case RTXAGC_A_MCS15_MCS12:
 234	case RTXAGC_B_MCS15_MCS12:
 235		index = 7;
 236		break;
 237	default:
 238		regaddr &= 0xFFF;
 239		if (regaddr >= 0xC20 && regaddr <= 0xC4C)
 240			index = (u8) ((regaddr - 0xC20) / 4);
 241		else if (regaddr >= 0xE20 && regaddr <= 0xE4C)
 242			index = (u8) ((regaddr - 0xE20) / 4);
 243		break;
 244	};
 245	return index;
 246}
 247
 248u32 rtl8723be_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
 249			       u32 regaddr, u32 bitmask)
 250{
 251	struct rtl_priv *rtlpriv = rtl_priv(hw);
 252	u32 original_value, readback_value, bitshift;
 253	unsigned long flags;
 254
 255	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
 256		 "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
 257		  regaddr, rfpath, bitmask);
 258
 259	spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
 260
 261	original_value = rtl8723_phy_rf_serial_read(hw, rfpath, regaddr);
 262	bitshift = rtl8723_phy_calculate_bit_shift(bitmask);
 263	readback_value = (original_value & bitmask) >> bitshift;
 264
 265	spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
 266
 267	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
 268		 "regaddr(%#x), rfpath(%#x), "
 269		  "bitmask(%#x), original_value(%#x)\n",
 270		  regaddr, rfpath, bitmask, original_value);
 271
 272	return readback_value;
 273}
 274
 275void rtl8723be_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path path,
 276			      u32 regaddr, u32 bitmask, u32 data)
 277{
 278	struct rtl_priv *rtlpriv = rtl_priv(hw);
 279	u32 original_value, bitshift;
 280	unsigned long flags;
 281
 282	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
 283		 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
 284		  regaddr, bitmask, data, path);
 285
 286	spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
 287
 288	if (bitmask != RFREG_OFFSET_MASK) {
 289			original_value = rtl8723_phy_rf_serial_read(hw, path,
 290								    regaddr);
 291			bitshift = rtl8723_phy_calculate_bit_shift(bitmask);
 292			data = ((original_value & (~bitmask)) |
 293				(data << bitshift));
 294		}
 295
 296	rtl8723_phy_rf_serial_write(hw, path, regaddr, data);
 297
 298	spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
 299
 300	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
 301		 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
 302		  regaddr, bitmask, data, path);
 303}
 304
 305bool rtl8723be_phy_mac_config(struct ieee80211_hw *hw)
 306{
 307	struct rtl_priv *rtlpriv = rtl_priv(hw);
 308	bool rtstatus = _rtl8723be_phy_config_mac_with_headerfile(hw);
 309
 310	rtl_write_byte(rtlpriv, 0x04CA, 0x0B);
 311	return rtstatus;
 312}
 313
 314bool rtl8723be_phy_bb_config(struct ieee80211_hw *hw)
 315{
 316	bool rtstatus = true;
 317	struct rtl_priv *rtlpriv = rtl_priv(hw);
 318	u16 regval;
 319	u8 reg_hwparafile = 1;
 320	u32 tmp;
 321	u8 crystalcap = rtlpriv->efuse.crystalcap;
 322	rtl8723_phy_init_bb_rf_reg_def(hw);
 323	regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
 324	rtl_write_word(rtlpriv, REG_SYS_FUNC_EN,
 325		       regval | BIT(13) | BIT(0) | BIT(1));
 326
 327	rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB);
 328	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN,
 329		       FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE |
 330		       FEN_BB_GLB_RSTN | FEN_BBRSTB);
 331	tmp = rtl_read_dword(rtlpriv, 0x4c);
 332	rtl_write_dword(rtlpriv, 0x4c, tmp | BIT(23));
 333
 334	rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80);
 335
 336	if (reg_hwparafile == 1)
 337		rtstatus = _rtl8723be_phy_bb8723b_config_parafile(hw);
 338
 339	crystalcap = crystalcap & 0x3F;
 340	rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000,
 341		      (crystalcap | crystalcap << 6));
 342
 343	return rtstatus;
 344}
 345
 346bool rtl8723be_phy_rf_config(struct ieee80211_hw *hw)
 347{
 348	return rtl8723be_phy_rf6052_config(hw);
 349}
 350
 351static void _rtl8723be_config_rf_reg(struct ieee80211_hw *hw, u32 addr,
 352				     u32 data, enum radio_path rfpath,
 353				     u32 regaddr)
 354{
 355	if (addr == 0xfe || addr == 0xffe) {
 356		mdelay(50);
 357	} else {
 358		rtl_set_rfreg(hw, rfpath, regaddr, RFREG_OFFSET_MASK, data);
 359		udelay(1);
 360	}
 361}
 362
 363static void _rtl8723be_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	_rtl8723be_config_rf_reg(hw, addr, data, RF90_PATH_A,
 370				 addr | maskforphyset);
 371}
 372
 373static void _rtl8723be_phy_init_tx_power_by_rate(struct ieee80211_hw *hw)
 374{
 375	struct rtl_priv *rtlpriv = rtl_priv(hw);
 376	struct rtl_phy *rtlphy = &(rtlpriv->phy);
 377
 378	u8 band, path, txnum, section;
 379
 380	for (band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band)
 381		for (path = 0; path < TX_PWR_BY_RATE_NUM_RF; ++path)
 382			for (txnum = 0; txnum < TX_PWR_BY_RATE_NUM_RF; ++txnum)
 383				for (section = 0;
 384				     section < TX_PWR_BY_RATE_NUM_SECTION;
 385				     ++section)
 386					rtlphy->tx_power_by_rate_offset[band]
 387						[path][txnum][section] = 0;
 388}
 389
 390static void phy_set_txpwr_by_rate_base(struct ieee80211_hw *hw, u8 band,
 391				       u8 path, u8 rate_section,
 392				       u8 txnum, u8 value)
 393{
 394	struct rtl_priv *rtlpriv = rtl_priv(hw);
 395	struct rtl_phy *rtlphy = &(rtlpriv->phy);
 396
 397	if (path > RF90_PATH_D) {
 398		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 399			 "Invalid Rf Path %d in phy_SetTxPowerByRatBase()\n",
 400			  path);
 401		return;
 402	}
 403
 404	if (band == BAND_ON_2_4G) {
 405		switch (rate_section) {
 406		case CCK:
 407			rtlphy->txpwr_by_rate_base_24g[path][txnum][0] = value;
 408			break;
 409		case OFDM:
 410			rtlphy->txpwr_by_rate_base_24g[path][txnum][1] = value;
 411			break;
 412		case HT_MCS0_MCS7:
 413			rtlphy->txpwr_by_rate_base_24g[path][txnum][2] = value;
 414			break;
 415		case HT_MCS8_MCS15:
 416			rtlphy->txpwr_by_rate_base_24g[path][txnum][3] = value;
 417			break;
 418		default:
 419			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 420				 "Invalid RateSection %d in Band 2.4G, Rf Path"
 421				  " %d, %dTx in PHY_SetTxPowerByRateBase()\n",
 422				  rate_section, path, txnum);
 423			break;
 424		};
 425	} else {
 426		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 427			 "Invalid Band %d in PHY_SetTxPowerByRateBase()\n",
 428			  band);
 429	}
 430}
 431
 432static u8 phy_get_txpwr_by_rate_base(struct ieee80211_hw *hw, u8 band, u8 path,
 433				     u8 txnum, u8 rate_section)
 434{
 435	struct rtl_priv *rtlpriv = rtl_priv(hw);
 436	struct rtl_phy *rtlphy = &(rtlpriv->phy);
 437	u8 value = 0;
 438	if (path > RF90_PATH_D) {
 439		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 440			 "Invalid Rf Path %d in PHY_GetTxPowerByRateBase()\n",
 441			  path);
 442		return 0;
 443	}
 444
 445	if (band == BAND_ON_2_4G) {
 446		switch (rate_section) {
 447		case CCK:
 448			value = rtlphy->txpwr_by_rate_base_24g[path][txnum][0];
 449			break;
 450		case OFDM:
 451			value = rtlphy->txpwr_by_rate_base_24g[path][txnum][1];
 452			break;
 453		case HT_MCS0_MCS7:
 454			value = rtlphy->txpwr_by_rate_base_24g[path][txnum][2];
 455			break;
 456		case HT_MCS8_MCS15:
 457			value = rtlphy->txpwr_by_rate_base_24g[path][txnum][3];
 458			break;
 459		default:
 460			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 461				 "Invalid RateSection %d in Band 2.4G, Rf Path"
 462				  " %d, %dTx in PHY_GetTxPowerByRateBase()\n",
 463				  rate_section, path, txnum);
 464			break;
 465		};
 466	} else {
 467		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 468			 "Invalid Band %d in PHY_GetTxPowerByRateBase()\n",
 469			  band);
 470	}
 471
 472	return value;
 473}
 474
 475static void _rtl8723be_phy_store_txpower_by_rate_base(struct ieee80211_hw *hw)
 476{
 477	struct rtl_priv *rtlpriv = rtl_priv(hw);
 478	struct rtl_phy *rtlphy = &(rtlpriv->phy);
 479	u16 raw_value = 0;
 480	u8 base = 0, path = 0;
 481
 482	for (path = RF90_PATH_A; path <= RF90_PATH_B; ++path) {
 483		if (path == RF90_PATH_A) {
 484			raw_value = (u16) (rtlphy->tx_power_by_rate_offset
 485				[BAND_ON_2_4G][path][RF_1TX][3] >> 24) & 0xFF;
 486			base = (raw_value >> 4) * 10 + (raw_value & 0xF);
 487			phy_set_txpwr_by_rate_base(hw, BAND_ON_2_4G, path, CCK,
 488						   RF_1TX, base);
 489		} else if (path == RF90_PATH_B) {
 490			raw_value = (u16) (rtlphy->tx_power_by_rate_offset
 491				[BAND_ON_2_4G][path][RF_1TX][3] >> 0) & 0xFF;
 492			base = (raw_value >> 4) * 10 + (raw_value & 0xF);
 493			phy_set_txpwr_by_rate_base(hw, BAND_ON_2_4G, path,
 494						   CCK, RF_1TX, base);
 495		}
 496		raw_value = (u16) (rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
 497					  [path][RF_1TX][1] >> 24) & 0xFF;
 498		base = (raw_value >> 4) * 10 + (raw_value & 0xF);
 499		phy_set_txpwr_by_rate_base(hw, BAND_ON_2_4G, path, OFDM, RF_1TX,
 500					   base);
 501
 502		raw_value = (u16) (rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
 503					  [path][RF_1TX][5] >> 24) & 0xFF;
 504		base = (raw_value >> 4) * 10 + (raw_value & 0xF);
 505		phy_set_txpwr_by_rate_base(hw, BAND_ON_2_4G, path, HT_MCS0_MCS7,
 506					   RF_1TX, base);
 507
 508		raw_value = (u16) (rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
 509					  [path][RF_2TX][7] >> 24) & 0xFF;
 510		base = (raw_value >> 4) * 10 + (raw_value & 0xF);
 511		phy_set_txpwr_by_rate_base(hw, BAND_ON_2_4G, path,
 512					   HT_MCS8_MCS15, RF_2TX, base);
 513	}
 514}
 515
 516static void phy_conv_dbm_to_rel(u32 *data, u8 start, u8 end, u8 base_val)
 517{
 518	char i = 0;
 519	u8 temp_value = 0;
 520	u32 temp_data = 0;
 521
 522	for (i = 3; i >= 0; --i) {
 523		if (i >= start && i <= end) {
 524			/* Get the exact value */
 525			temp_value = (u8) (*data >> (i * 8)) & 0xF;
 526			temp_value += ((u8) ((*data >> (i*8 + 4)) & 0xF)) * 10;
 527
 528			/* Change the value to a relative value */
 529			temp_value = (temp_value > base_val) ?
 530				     temp_value - base_val :
 531				     base_val - temp_value;
 532		} else {
 533			temp_value = (u8) (*data >> (i * 8)) & 0xFF;
 534		}
 535		temp_data <<= 8;
 536		temp_data |= temp_value;
 537	}
 538	*data = temp_data;
 539}
 540
 541static void conv_dbm_to_rel(struct ieee80211_hw *hw)
 542{
 543	struct rtl_priv *rtlpriv = rtl_priv(hw);
 544	struct rtl_phy *rtlphy = &(rtlpriv->phy);
 545	u8 base = 0, rfpath = RF90_PATH_A;
 546
 547	base = phy_get_txpwr_by_rate_base(hw, BAND_ON_2_4G, rfpath,
 548					  RF_1TX, CCK);
 549	phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
 550			    [rfpath][RF_1TX][2]), 1, 1, base);
 551	phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
 552			    [rfpath][RF_1TX][3]), 1, 3, base);
 553
 554	base = phy_get_txpwr_by_rate_base(hw, BAND_ON_2_4G, rfpath,
 555					  RF_1TX, OFDM);
 556	phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
 557			    [rfpath][RF_1TX][0]), 0, 3, base);
 558	phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
 559			    [rfpath][RF_1TX][1]), 0, 3, base);
 560
 561	base = phy_get_txpwr_by_rate_base(hw, BAND_ON_2_4G, rfpath,
 562					  RF_1TX, HT_MCS0_MCS7);
 563	phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
 564			    [rfpath][RF_1TX][4]), 0, 3, base);
 565	phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
 566			    [rfpath][RF_1TX][5]), 0, 3, base);
 567
 568	base = phy_get_txpwr_by_rate_base(hw, BAND_ON_2_4G, rfpath,
 569					  RF_2TX, HT_MCS8_MCS15);
 570	phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
 571			    [rfpath][RF_2TX][6]), 0, 3, base);
 572
 573	phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G]
 574			    [rfpath][RF_2TX][7]), 0, 3, base);
 575
 576	RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
 577		 "<=== conv_dbm_to_rel()\n");
 578}
 579
 580static void _rtl8723be_phy_txpower_by_rate_configuration(
 581							struct ieee80211_hw *hw)
 582{
 583	_rtl8723be_phy_store_txpower_by_rate_base(hw);
 584	conv_dbm_to_rel(hw);
 585}
 586
 587static bool _rtl8723be_phy_bb8723b_config_parafile(struct ieee80211_hw *hw)
 588{
 589	struct rtl_priv *rtlpriv = rtl_priv(hw);
 590	struct rtl_phy *rtlphy = &(rtlpriv->phy);
 591	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 592	bool rtstatus;
 593
 594	rtstatus = _rtl8723be_phy_config_bb_with_headerfile(hw,
 595						BASEBAND_CONFIG_PHY_REG);
 596	if (!rtstatus) {
 597		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!");
 598		return false;
 599	}
 600	_rtl8723be_phy_init_tx_power_by_rate(hw);
 601	if (!rtlefuse->autoload_failflag) {
 602		rtlphy->pwrgroup_cnt = 0;
 603		rtstatus = _rtl8723be_phy_config_bb_with_pgheaderfile(hw,
 604						BASEBAND_CONFIG_PHY_REG);
 605	}
 606	_rtl8723be_phy_txpower_by_rate_configuration(hw);
 607	if (!rtstatus) {
 608		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!");
 609		return false;
 610	}
 611	rtstatus = _rtl8723be_phy_config_bb_with_headerfile(hw,
 612						BASEBAND_CONFIG_AGC_TAB);
 613	if (!rtstatus) {
 614		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n");
 615		return false;
 616	}
 617	rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw,
 618						       RFPGA0_XA_HSSIPARAMETER2,
 619						       0x200));
 620	return true;
 621}
 622
 623static void _rtl8723be_store_tx_power_by_rate(struct ieee80211_hw *hw,
 624					      u32 band, u32 rfpath,
 625					      u32 txnum, u32 regaddr,
 626					      u32 bitmask, u32 data)
 627{
 628	struct rtl_priv *rtlpriv = rtl_priv(hw);
 629	struct rtl_phy *rtlphy = &(rtlpriv->phy);
 630	u8 rate_section = _rtl8723be_get_rate_section_index(regaddr);
 631
 632	if (band != BAND_ON_2_4G && band != BAND_ON_5G) {
 633		RT_TRACE(rtlpriv, COMP_POWER, PHY_TXPWR,
 634			 "Invalid Band %d\n", band);
 635		return;
 636	}
 637
 638	if (rfpath > TX_PWR_BY_RATE_NUM_RF) {
 639		RT_TRACE(rtlpriv, COMP_POWER, PHY_TXPWR,
 640			 "Invalid RfPath %d\n", rfpath);
 641		return;
 642	}
 643	if (txnum > TX_PWR_BY_RATE_NUM_RF) {
 644		RT_TRACE(rtlpriv, COMP_POWER, PHY_TXPWR,
 645			 "Invalid TxNum %d\n", txnum);
 646		return;
 647	}
 648	rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section] =
 649									data;
 650}
 651
 652static bool _rtl8723be_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
 653						       u8 configtype)
 654{
 655	struct rtl_priv *rtlpriv = rtl_priv(hw);
 656	int i;
 657	u32 *phy_regarray_table_pg;
 658	u16 phy_regarray_pg_len;
 659	u32 v1 = 0, v2 = 0, v3 = 0, v4 = 0, v5 = 0, v6 = 0;
 660
 661	phy_regarray_pg_len = RTL8723BEPHY_REG_ARRAY_PGLEN;
 662	phy_regarray_table_pg = RTL8723BEPHY_REG_ARRAY_PG;
 663
 664	if (configtype == BASEBAND_CONFIG_PHY_REG) {
 665		for (i = 0; i < phy_regarray_pg_len; i = i + 6) {
 666			v1 = phy_regarray_table_pg[i];
 667			v2 = phy_regarray_table_pg[i+1];
 668			v3 = phy_regarray_table_pg[i+2];
 669			v4 = phy_regarray_table_pg[i+3];
 670			v5 = phy_regarray_table_pg[i+4];
 671			v6 = phy_regarray_table_pg[i+5];
 672
 673			if (v1 < 0xcdcdcdcd) {
 674				if (phy_regarray_table_pg[i] == 0xfe ||
 675				    phy_regarray_table_pg[i] == 0xffe)
 676					mdelay(50);
 677				else
 678					_rtl8723be_store_tx_power_by_rate(hw,
 679							v1, v2, v3, v4, v5, v6);
 680				continue;
 681			} else {
 682				/*don't need the hw_body*/
 683				if (!_rtl8723be_check_condition(hw,
 684						phy_regarray_table_pg[i])) {
 685					i += 2; /* skip the pair of expression*/
 686					v1 = phy_regarray_table_pg[i];
 687					v2 = phy_regarray_table_pg[i+1];
 688					v3 = phy_regarray_table_pg[i+2];
 689					while (v2 != 0xDEAD) {
 690						i += 3;
 691						v1 = phy_regarray_table_pg[i];
 692						v2 = phy_regarray_table_pg[i+1];
 693						v3 = phy_regarray_table_pg[i+2];
 694					}
 695				}
 696			}
 697		}
 698	} else {
 699		RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
 700			 "configtype != BaseBand_Config_PHY_REG\n");
 701	}
 702	return true;
 703}
 704
 705bool rtl8723be_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
 706					     enum radio_path rfpath)
 707{
 708	#define READ_NEXT_RF_PAIR(v1, v2, i) \
 709		do { \
 710			i += 2; \
 711			v1 = radioa_array_table[i]; \
 712			v2 = radioa_array_table[i+1]; \
 713		} while (0)
 714
 715	int i;
 716	bool rtstatus = true;
 717	u32 *radioa_array_table;
 718	u16 radioa_arraylen;
 719	struct rtl_priv *rtlpriv = rtl_priv(hw);
 720	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 721	u32 v1 = 0, v2 = 0;
 722
 723	radioa_arraylen = RTL8723BE_RADIOA_1TARRAYLEN;
 724	radioa_array_table = RTL8723BE_RADIOA_1TARRAY;
 725	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
 726		 "Radio_A:RTL8723BE_RADIOA_1TARRAY %d\n", radioa_arraylen);
 727	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
 728	rtstatus = true;
 729	switch (rfpath) {
 730	case RF90_PATH_A:
 731		for (i = 0; i < radioa_arraylen; i = i + 2) {
 732			v1 = radioa_array_table[i];
 733			v2 = radioa_array_table[i+1];
 734			if (v1 < 0xcdcdcdcd) {
 735				_rtl8723be_config_rf_radio_a(hw, v1, v2);
 736			} else { /*This line is the start line of branch.*/
 737				if (!_rtl8723be_check_condition(hw,
 738						radioa_array_table[i])) {
 739					/* Discard the following
 740					 * (offset, data) pairs
 741					 */
 742					READ_NEXT_RF_PAIR(v1, v2, i);
 743					while (v2 != 0xDEAD &&
 744					       v2 != 0xCDEF &&
 745					       v2 != 0xCDCD &&
 746					       i < radioa_arraylen - 2)
 747						READ_NEXT_RF_PAIR(v1, v2, i);
 748					i -= 2; /* prevent from for-loop += 2*/
 749				} else {
 750					/* Configure matched pairs
 751					 * and skip to end of if-else.
 752					 */
 753					READ_NEXT_RF_PAIR(v1, v2, i);
 754					while (v2 != 0xDEAD &&
 755					       v2 != 0xCDEF &&
 756					       v2 != 0xCDCD &&
 757					       i < radioa_arraylen - 2) {
 758						_rtl8723be_config_rf_radio_a(hw,
 759									v1, v2);
 760						READ_NEXT_RF_PAIR(v1, v2, i);
 761					}
 762
 763					while (v2 != 0xDEAD &&
 764					       i < radioa_arraylen - 2) {
 765						READ_NEXT_RF_PAIR(v1, v2, i);
 766					}
 767				}
 768			}
 769		}
 770
 771		if (rtlhal->oem_id == RT_CID_819X_HP)
 772			_rtl8723be_config_rf_radio_a(hw, 0x52, 0x7E4BD);
 773
 774		break;
 775	case RF90_PATH_B:
 776		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
 777			 "switch case not process\n");
 778		break;
 779	case RF90_PATH_C:
 780		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
 781			 "switch case not process\n");
 782		break;
 783	case RF90_PATH_D:
 784		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
 785			 "switch case not process\n");
 786		break;
 787	}
 788	return true;
 789}
 790
 791void rtl8723be_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
 792{
 793	struct rtl_priv *rtlpriv = rtl_priv(hw);
 794	struct rtl_phy *rtlphy = &(rtlpriv->phy);
 795
 796	rtlphy->default_initialgain[0] =
 797	    (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
 798	rtlphy->default_initialgain[1] =
 799	    (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
 800	rtlphy->default_initialgain[2] =
 801	    (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
 802	rtlphy->default_initialgain[3] =
 803	    (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
 804
 805	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 806		 "Default initial gain (c50 = 0x%x, "
 807		  "c58 = 0x%x, c60 = 0x%x, c68 = 0x%x\n",
 808		  rtlphy->default_initialgain[0],
 809		  rtlphy->default_initialgain[1],
 810		  rtlphy->default_initialgain[2],
 811		  rtlphy->default_initialgain[3]);
 812
 813	rtlphy->framesync = (u8) rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3,
 814					       MASKBYTE0);
 815	rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2,
 816					      MASKDWORD);
 817
 818	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
 819		 "Default framesync (0x%x) = 0x%x\n",
 820		  ROFDM0_RXDETECTOR3, rtlphy->framesync);
 821}
 822
 823void rtl8723be_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
 824{
 825	struct rtl_priv *rtlpriv = rtl_priv(hw);
 826	struct rtl_phy *rtlphy = &(rtlpriv->phy);
 827	u8 txpwr_level;
 828	long txpwr_dbm;
 829
 830	txpwr_level = rtlphy->cur_cck_txpwridx;
 831	txpwr_dbm = rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_B,
 832						 txpwr_level);
 833	txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
 834	if (rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, txpwr_level) >
 835	    txpwr_dbm)
 836		txpwr_dbm =
 837		    rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
 838						 txpwr_level);
 839	txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
 840	if (rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
 841					 txpwr_level) > txpwr_dbm)
 842		txpwr_dbm =
 843		    rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
 844						 txpwr_level);
 845	*powerlevel = txpwr_dbm;
 846}
 847
 848static u8 _rtl8723be_phy_get_ratesection_intxpower_byrate(enum radio_path path,
 849							  u8 rate)
 850{
 851	u8 rate_section = 0;
 852
 853	switch (rate) {
 854	case DESC92C_RATE1M:
 855		rate_section = 2;
 856		break;
 857	case DESC92C_RATE2M:
 858	case DESC92C_RATE5_5M:
 859		if (path == RF90_PATH_A)
 860			rate_section = 3;
 861		else if (path == RF90_PATH_B)
 862			rate_section = 2;
 863		break;
 864	case DESC92C_RATE11M:
 865		rate_section = 3;
 866		break;
 867	case DESC92C_RATE6M:
 868	case DESC92C_RATE9M:
 869	case DESC92C_RATE12M:
 870	case DESC92C_RATE18M:
 871		rate_section = 0;
 872		break;
 873	case DESC92C_RATE24M:
 874	case DESC92C_RATE36M:
 875	case DESC92C_RATE48M:
 876	case DESC92C_RATE54M:
 877		rate_section = 1;
 878		break;
 879	case DESC92C_RATEMCS0:
 880	case DESC92C_RATEMCS1:
 881	case DESC92C_RATEMCS2:
 882	case DESC92C_RATEMCS3:
 883		rate_section = 4;
 884		break;
 885	case DESC92C_RATEMCS4:
 886	case DESC92C_RATEMCS5:
 887	case DESC92C_RATEMCS6:
 888	case DESC92C_RATEMCS7:
 889		rate_section = 5;
 890		break;
 891	case DESC92C_RATEMCS8:
 892	case DESC92C_RATEMCS9:
 893	case DESC92C_RATEMCS10:
 894	case DESC92C_RATEMCS11:
 895		rate_section = 6;
 896		break;
 897	case DESC92C_RATEMCS12:
 898	case DESC92C_RATEMCS13:
 899	case DESC92C_RATEMCS14:
 900	case DESC92C_RATEMCS15:
 901		rate_section = 7;
 902		break;
 903	default:
 904		RT_ASSERT(true, "Rate_Section is Illegal\n");
 905		break;
 906	}
 907	return rate_section;
 908}
 909
 910static u8 _rtl8723be_get_txpower_by_rate(struct ieee80211_hw *hw,
 911					 enum band_type band,
 912					 enum radio_path rfpath, u8 rate)
 913{
 914	struct rtl_priv *rtlpriv = rtl_priv(hw);
 915	struct rtl_phy *rtlphy = &(rtlpriv->phy);
 916	u8 shift = 0, rate_section, tx_num;
 917	char tx_pwr_diff = 0;
 918
 919	rate_section = _rtl8723be_phy_get_ratesection_intxpower_byrate(rfpath,
 920								       rate);
 921	tx_num = RF_TX_NUM_NONIMPLEMENT;
 922
 923	if (tx_num == RF_TX_NUM_NONIMPLEMENT) {
 924		if (rate >= DESC92C_RATEMCS8 && rate <= DESC92C_RATEMCS15)
 925			tx_num = RF_2TX;
 926		else
 927			tx_num = RF_1TX;
 928	}
 929
 930	switch (rate) {
 931	case DESC92C_RATE6M:
 932	case DESC92C_RATE24M:
 933	case DESC92C_RATEMCS0:
 934	case DESC92C_RATEMCS4:
 935	case DESC92C_RATEMCS8:
 936	case DESC92C_RATEMCS12:
 937		shift = 0;
 938		break;
 939	case DESC92C_RATE1M:
 940	case DESC92C_RATE2M:
 941	case DESC92C_RATE9M:
 942	case DESC92C_RATE36M:
 943	case DESC92C_RATEMCS1:
 944	case DESC92C_RATEMCS5:
 945	case DESC92C_RATEMCS9:
 946	case DESC92C_RATEMCS13:
 947		shift = 8;
 948		break;
 949	case DESC92C_RATE5_5M:
 950	case DESC92C_RATE12M:
 951	case DESC92C_RATE48M:
 952	case DESC92C_RATEMCS2:
 953	case DESC92C_RATEMCS6:
 954	case DESC92C_RATEMCS10:
 955	case DESC92C_RATEMCS14:
 956		shift = 16;
 957		break;
 958	case DESC92C_RATE11M:
 959	case DESC92C_RATE18M:
 960	case DESC92C_RATE54M:
 961	case DESC92C_RATEMCS3:
 962	case DESC92C_RATEMCS7:
 963	case DESC92C_RATEMCS11:
 964	case DESC92C_RATEMCS15:
 965		shift = 24;
 966		break;
 967	default:
 968		RT_ASSERT(true, "Rate_Section is Illegal\n");
 969		break;
 970	}
 971	tx_pwr_diff = (u8)(rtlphy->tx_power_by_rate_offset[band][rfpath][tx_num]
 972					  [rate_section] >> shift) & 0xff;
 973
 974	return	tx_pwr_diff;
 975}
 976
 977static u8 _rtl8723be_get_txpower_index(struct ieee80211_hw *hw, u8 path,
 978				       u8 rate, u8 bandwidth, u8 channel)
 979{
 980	struct rtl_priv *rtlpriv = rtl_priv(hw);
 981	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 982	u8 index = (channel - 1);
 983	u8 txpower;
 984	u8 power_diff_byrate = 0;
 985
 986	if (channel > 14 || channel < 1) {
 987		index = 0;
 988		RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
 989			 "Illegal channel!\n");
 990	}
 991	if (RTL8723E_RX_HAL_IS_CCK_RATE(rate))
 992		txpower = rtlefuse->txpwrlevel_cck[path][index];
 993	else if (DESC92C_RATE6M <= rate)
 994		txpower = rtlefuse->txpwrlevel_ht40_1s[path][index];
 995	else
 996		RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
 997			 "invalid rate\n");
 998
 999	if (DESC92C_RATE6M <= rate && rate <= DESC92C_RATE54M &&
1000	    !RTL8723E_RX_HAL_IS_CCK_RATE(rate))
1001		txpower += rtlefuse->txpwr_legacyhtdiff[0][TX_1S];
1002
1003	if (bandwidth == HT_CHANNEL_WIDTH_20) {
1004		if (DESC92C_RATEMCS0 <= rate && rate <= DESC92C_RATEMCS15)
1005			txpower += rtlefuse->txpwr_ht20diff[0][TX_1S];
1006		if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15)
1007			txpower += rtlefuse->txpwr_ht20diff[0][TX_2S];
1008	} else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
1009		if (DESC92C_RATEMCS0 <= rate && rate <= DESC92C_RATEMCS15)
1010			txpower += rtlefuse->txpwr_ht40diff[0][TX_1S];
1011		if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15)
1012			txpower += rtlefuse->txpwr_ht40diff[0][TX_2S];
1013	}
1014	if (rtlefuse->eeprom_regulatory != 2)
1015		power_diff_byrate = _rtl8723be_get_txpower_by_rate(hw,
1016								   BAND_ON_2_4G,
1017								   path, rate);
1018
1019	txpower += power_diff_byrate;
1020
1021	if (txpower > MAX_POWER_INDEX)
1022		txpower = MAX_POWER_INDEX;
1023
1024	return txpower;
1025}
1026
1027static void _rtl8723be_phy_set_txpower_index(struct ieee80211_hw *hw,
1028					     u8 power_index, u8 path, u8 rate)
1029{
1030	struct rtl_priv *rtlpriv = rtl_priv(hw);
1031	if (path == RF90_PATH_A) {
1032		switch (rate) {
1033		case DESC92C_RATE1M:
1034			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_CCK1_MCS32,
1035					       MASKBYTE1, power_index);
1036			break;
1037		case DESC92C_RATE2M:
1038			rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11,
1039					       MASKBYTE1, power_index);
1040			break;
1041		case DESC92C_RATE5_5M:
1042			rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11,
1043					       MASKBYTE2, power_index);
1044			break;
1045		case DESC92C_RATE11M:
1046			rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11,
1047					       MASKBYTE3, power_index);
1048			break;
1049		case DESC92C_RATE6M:
1050			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1051					       MASKBYTE0, power_index);
1052			break;
1053		case DESC92C_RATE9M:
1054			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1055					       MASKBYTE1, power_index);
1056			break;
1057		case DESC92C_RATE12M:
1058			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1059					       MASKBYTE2, power_index);
1060			break;
1061		case DESC92C_RATE18M:
1062			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1063					       MASKBYTE3, power_index);
1064			break;
1065		case DESC92C_RATE24M:
1066			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1067					       MASKBYTE0, power_index);
1068			break;
1069		case DESC92C_RATE36M:
1070			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1071					       MASKBYTE1, power_index);
1072			break;
1073		case DESC92C_RATE48M:
1074			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1075					       MASKBYTE2, power_index);
1076			break;
1077		case DESC92C_RATE54M:
1078			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1079					       MASKBYTE3, power_index);
1080			break;
1081		case DESC92C_RATEMCS0:
1082			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1083					       MASKBYTE0, power_index);
1084			break;
1085		case DESC92C_RATEMCS1:
1086			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1087					       MASKBYTE1, power_index);
1088			break;
1089		case DESC92C_RATEMCS2:
1090			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1091					       MASKBYTE2, power_index);
1092			break;
1093		case DESC92C_RATEMCS3:
1094			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1095					       MASKBYTE3, power_index);
1096			break;
1097		case DESC92C_RATEMCS4:
1098			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1099					       MASKBYTE0, power_index);
1100			break;
1101		case DESC92C_RATEMCS5:
1102			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1103					       MASKBYTE1, power_index);
1104			break;
1105		case DESC92C_RATEMCS6:
1106			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1107					       MASKBYTE2, power_index);
1108			break;
1109		case DESC92C_RATEMCS7:
1110			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1111					       MASKBYTE3, power_index);
1112			break;
1113		case DESC92C_RATEMCS8:
1114			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1115					       MASKBYTE0, power_index);
1116			break;
1117		case DESC92C_RATEMCS9:
1118			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1119					       MASKBYTE1, power_index);
1120			break;
1121		case DESC92C_RATEMCS10:
1122			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1123					       MASKBYTE2, power_index);
1124			break;
1125		case DESC92C_RATEMCS11:
1126			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1127					       MASKBYTE3, power_index);
1128			break;
1129		default:
1130			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
1131				 "Invalid Rate!!\n");
1132			break;
1133		}
1134	} else {
1135		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid RFPath!!\n");
1136	}
1137}
1138
1139void rtl8723be_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
1140{
1141	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1142	u8 cck_rates[]  = {DESC92C_RATE1M, DESC92C_RATE2M,
1143			   DESC92C_RATE5_5M, DESC92C_RATE11M};
1144	u8 ofdm_rates[]  = {DESC92C_RATE6M, DESC92C_RATE9M,
1145			    DESC92C_RATE12M, DESC92C_RATE18M,
1146			    DESC92C_RATE24M, DESC92C_RATE36M,
1147			    DESC92C_RATE48M, DESC92C_RATE54M};
1148	u8 ht_rates_1t[]  = {DESC92C_RATEMCS0, DESC92C_RATEMCS1,
1149			     DESC92C_RATEMCS2, DESC92C_RATEMCS3,
1150			     DESC92C_RATEMCS4, DESC92C_RATEMCS5,
1151			     DESC92C_RATEMCS6, DESC92C_RATEMCS7};
1152	u8 i, size;
1153	u8 power_index;
1154
1155	if (!rtlefuse->txpwr_fromeprom)
1156		return;
1157
1158	size = sizeof(cck_rates) / sizeof(u8);
1159	for (i = 0; i < size; i++) {
1160		power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A,
1161					cck_rates[i],
1162					rtl_priv(hw)->phy.current_chan_bw,
1163					channel);
1164		_rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A,
1165						 cck_rates[i]);
1166	}
1167	size = sizeof(ofdm_rates) / sizeof(u8);
1168	for (i = 0; i < size; i++) {
1169		power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A,
1170					ofdm_rates[i],
1171					rtl_priv(hw)->phy.current_chan_bw,
1172					channel);
1173		_rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A,
1174						 ofdm_rates[i]);
1175	}
1176	size = sizeof(ht_rates_1t) / sizeof(u8);
1177	for (i = 0; i < size; i++) {
1178		power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A,
1179					ht_rates_1t[i],
1180					rtl_priv(hw)->phy.current_chan_bw,
1181					channel);
1182		_rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A,
1183						 ht_rates_1t[i]);
1184	}
1185}
1186
1187void rtl8723be_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
1188{
1189	struct rtl_priv *rtlpriv = rtl_priv(hw);
1190	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1191	enum io_type iotype;
1192
1193	if (!is_hal_stop(rtlhal)) {
1194		switch (operation) {
1195		case SCAN_OPT_BACKUP:
1196			iotype = IO_CMD_PAUSE_DM_BY_SCAN;
1197			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1198						      (u8 *)&iotype);
1199			break;
1200		case SCAN_OPT_RESTORE:
1201			iotype = IO_CMD_RESUME_DM_BY_SCAN;
1202			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1203						      (u8 *)&iotype);
1204			break;
1205		default:
1206			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1207				 "Unknown Scan Backup operation.\n");
1208			break;
1209		}
1210	}
1211}
1212
1213void rtl8723be_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
1214{
1215	struct rtl_priv *rtlpriv = rtl_priv(hw);
1216	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1217	struct rtl_phy *rtlphy = &(rtlpriv->phy);
1218	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1219	u8 reg_bw_opmode;
1220	u8 reg_prsr_rsc;
1221
1222	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
1223		 "Switch to %s bandwidth\n",
1224		 rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
1225		 "20MHz" : "40MHz");
1226
1227	if (is_hal_stop(rtlhal)) {
1228		rtlphy->set_bwmode_inprogress = false;
1229		return;
1230	}
1231
1232	reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
1233	reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
1234
1235	switch (rtlphy->current_chan_bw) {
1236	case HT_CHANNEL_WIDTH_20:
1237		reg_bw_opmode |= BW_OPMODE_20MHZ;
1238		rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1239		break;
1240	case HT_CHANNEL_WIDTH_20_40:
1241		reg_bw_opmode &= ~BW_OPMODE_20MHZ;
1242		rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1243		reg_prsr_rsc = (reg_prsr_rsc & 0x90) |
1244			       (mac->cur_40_prime_sc << 5);
1245		rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
1246		break;
1247	default:
1248		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1249			 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
1250		break;
1251	}
1252
1253	switch (rtlphy->current_chan_bw) {
1254	case HT_CHANNEL_WIDTH_20:
1255		rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
1256		rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
1257		break;
1258	case HT_CHANNEL_WIDTH_20_40:
1259		rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
1260		rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
1261		rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
1262			      (mac->cur_40_prime_sc >> 1));
1263		rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
1264		rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
1265			      (mac->cur_40_prime_sc ==
1266			       HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
1267		break;
1268	default:
1269		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1270			 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
1271		break;
1272	}
1273	rtl8723be_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
1274	rtlphy->set_bwmode_inprogress = false;
1275	RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, "\n");
1276}
1277
1278void rtl8723be_phy_set_bw_mode(struct ieee80211_hw *hw,
1279			    enum nl80211_channel_type ch_type)
1280{
1281	struct rtl_priv *rtlpriv = rtl_priv(hw);
1282	struct rtl_phy *rtlphy = &(rtlpriv->phy);
1283	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1284	u8 tmp_bw = rtlphy->current_chan_bw;
1285
1286	if (rtlphy->set_bwmode_inprogress)
1287		return;
1288	rtlphy->set_bwmode_inprogress = true;
1289	if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1290		rtl8723be_phy_set_bw_mode_callback(hw);
1291	} else {
1292		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1293			 "false driver sleep or unload\n");
1294		rtlphy->set_bwmode_inprogress = false;
1295		rtlphy->current_chan_bw = tmp_bw;
1296	}
1297}
1298
1299void rtl8723be_phy_sw_chnl_callback(struct ieee80211_hw *hw)
1300{
1301	struct rtl_priv *rtlpriv = rtl_priv(hw);
1302	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1303	struct rtl_phy *rtlphy = &(rtlpriv->phy);
1304	u32 delay;
1305
1306	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
1307		 "switch to channel%d\n", rtlphy->current_channel);
1308	if (is_hal_stop(rtlhal))
1309		return;
1310	do {
1311		if (!rtlphy->sw_chnl_inprogress)
1312			break;
1313		if (!rtl8723be_phy_sw_chn_step_by_step(hw,
1314						       rtlphy->current_channel,
1315						       &rtlphy->sw_chnl_stage,
1316						       &rtlphy->sw_chnl_step,
1317						       &delay)) {
1318			if (delay > 0)
1319				mdelay(delay);
1320			else
1321				continue;
1322		} else {
1323			rtlphy->sw_chnl_inprogress = false;
1324		}
1325		break;
1326	} while (true);
1327	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
1328}
1329
1330u8 rtl8723be_phy_sw_chnl(struct ieee80211_hw *hw)
1331{
1332	struct rtl_priv *rtlpriv = rtl_priv(hw);
1333	struct rtl_phy *rtlphy = &(rtlpriv->phy);
1334	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1335
1336	if (rtlphy->sw_chnl_inprogress)
1337		return 0;
1338	if (rtlphy->set_bwmode_inprogress)
1339		return 0;
1340	RT_ASSERT((rtlphy->current_channel <= 14),
1341		  "WIRELESS_MODE_G but channel>14");
1342	rtlphy->sw_chnl_inprogress = true;
1343	rtlphy->sw_chnl_stage = 0;
1344	rtlphy->sw_chnl_step = 0;
1345	if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1346		rtl8723be_phy_sw_chnl_callback(hw);
1347		RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
1348			 "sw_chnl_inprogress false schdule "
1349			  "workitem current channel %d\n",
1350			  rtlphy->current_channel);
1351		rtlphy->sw_chnl_inprogress = false;
1352	} else {
1353		RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
1354			 "sw_chnl_inprogress false driver sleep or"
1355			  " unload\n");
1356		rtlphy->sw_chnl_inprogress = false;
1357	}
1358	return 1;
1359}
1360
1361static bool rtl8723be_phy_sw_chn_step_by_step(struct ieee80211_hw *hw,
1362					      u8 channel, u8 *stage,
1363					      u8 *step, u32 *delay)
1364{
1365	struct rtl_priv *rtlpriv = rtl_priv(hw);
1366	struct rtl_phy *rtlphy = &(rtlpriv->phy);
1367	struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];
1368	u32 precommoncmdcnt;
1369	struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];
1370	u32 postcommoncmdcnt;
1371	struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];
1372	u32 rfdependcmdcnt;
1373	struct swchnlcmd *currentcmd = NULL;
1374	u8 rfpath;
1375	u8 num_total_rfpath = rtlphy->num_total_rfpath;
1376
1377	precommoncmdcnt = 0;
1378	rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
1379					 MAX_PRECMD_CNT,
1380					 CMDID_SET_TXPOWEROWER_LEVEL,
1381					 0, 0, 0);
1382	rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
1383					 MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
1384	postcommoncmdcnt = 0;
1385	rtl8723_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
1386					 MAX_POSTCMD_CNT, CMDID_END,
1387					 0, 0, 0);
1388	rfdependcmdcnt = 0;
1389
1390	RT_ASSERT((channel >= 1 && channel <= 14),
1391		  "illegal channel for Zebra: %d\n", channel);
1392
1393	rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
1394					 MAX_RFDEPENDCMD_CNT,
1395					 CMDID_RF_WRITEREG,
1396					 RF_CHNLBW, channel, 10);
1397
1398	rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
1399					 MAX_RFDEPENDCMD_CNT,
1400					 CMDID_END, 0, 0, 0);
1401
1402	do {
1403		switch (*stage) {
1404		case 0:
1405			currentcmd = &precommoncmd[*step];
1406			break;
1407		case 1:
1408			currentcmd = &rfdependcmd[*step];
1409			break;
1410		case 2:
1411			currentcmd = &postcommoncmd[*step];
1412			break;
1413		}
1414
1415		if (currentcmd->cmdid == CMDID_END) {
1416			if ((*stage) == 2) {
1417				return true;
1418			} else {
1419				(*stage)++;
1420				(*step) = 0;
1421				continue;
1422			}
1423		}
1424
1425		switch (currentcmd->cmdid) {
1426		case CMDID_SET_TXPOWEROWER_LEVEL:
1427			rtl8723be_phy_set_txpower_level(hw, channel);
1428			break;
1429		case CMDID_WRITEPORT_ULONG:
1430			rtl_write_dword(rtlpriv, currentcmd->para1,
1431					currentcmd->para2);
1432			break;
1433		case CMDID_WRITEPORT_USHORT:
1434			rtl_write_word(rtlpriv, currentcmd->para1,
1435				       (u16) currentcmd->para2);
1436			break;
1437		case CMDID_WRITEPORT_UCHAR:
1438			rtl_write_byte(rtlpriv, currentcmd->para1,
1439				       (u8) currentcmd->para2);
1440			break;
1441		case CMDID_RF_WRITEREG:
1442			for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
1443				rtlphy->rfreg_chnlval[rfpath] =
1444				    ((rtlphy->rfreg_chnlval[rfpath] &
1445				      0xfffffc00) | currentcmd->para2);
1446
1447				rtl_set_rfreg(hw, (enum radio_path)rfpath,
1448					      currentcmd->para1,
1449					      RFREG_OFFSET_MASK,
1450					      rtlphy->rfreg_chnlval[rfpath]);
1451			}
1452			break;
1453		default:
1454			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1455				 "switch case not process\n");
1456			break;
1457		}
1458
1459		break;
1460	} while (true);
1461
1462	(*delay) = currentcmd->msdelay;
1463	(*step)++;
1464	return false;
1465}
1466
1467static u8 _rtl8723be_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb)
1468{
1469	u32 reg_eac, reg_e94, reg_e9c, reg_ea4;
1470	u8 result = 0x00;
1471
1472	rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1c);
1473	rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x30008c1c);
1474	rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x8214032a);
1475	rtl_set_bbreg(hw, 0xe3c, MASKDWORD, 0x28160000);
1476
1477	rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x00462911);
1478	rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000);
1479	rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000);
1480
1481	mdelay(IQK_DELAY_TIME);
1482
1483	reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
1484	reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD);
1485	reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD);
1486	reg_ea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD);
1487
1488	if (!(reg_eac & BIT(28)) &&
1489	    (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1490	    (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1491		result |= 0x01;
1492	return result;
1493}
1494
1495static bool phy_similarity_cmp(struct ieee80211_hw *hw, long result[][8],
1496			       u8 c1, u8 c2)
1497{
1498	u32 i, j, diff, simularity_bitmap, bound;
1499	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1500
1501	u8 final_candidate[2] = { 0xFF, 0xFF };
1502	bool bresult = true, is2t = IS_92C_SERIAL(rtlhal->version);
1503
1504	if (is2t)
1505		bound = 8;
1506	else
1507		bound = 4;
1508
1509	simularity_bitmap = 0;
1510
1511	for (i = 0; i < bound; i++) {
1512		diff = (result[c1][i] > result[c2][i]) ?
1513		    (result[c1][i] - result[c2][i]) :
1514		    (result[c2][i] - result[c1][i]);
1515
1516		if (diff > MAX_TOLERANCE) {
1517			if ((i == 2 || i == 6) && !simularity_bitmap) {
1518				if (result[c1][i] + result[c1][i + 1] == 0)
1519					final_candidate[(i / 4)] = c2;
1520				else if (result[c2][i] + result[c2][i + 1] == 0)
1521					final_candidate[(i / 4)] = c1;
1522				else
1523					simularity_bitmap |= (1 << i);
1524			} else {
1525				simularity_bitmap |= (1 << i);
1526			}
1527		}
1528	}
1529
1530	if (simularity_bitmap == 0) {
1531		for (i = 0; i < (bound / 4); i++) {
1532			if (final_candidate[i] != 0xFF) {
1533				for (j = i * 4; j < (i + 1) * 4 - 2; j++)
1534					result[3][j] =
1535						result[final_candidate[i]][j];
1536				bresult = false;
1537			}
1538		}
1539		return bresult;
1540	} else if (!(simularity_bitmap & 0x0F)) {
1541		for (i = 0; i < 4; i++)
1542			result[3][i] = result[c1][i];
1543		return false;
1544	} else if (!(simularity_bitmap & 0xF0) && is2t) {
1545		for (i = 4; i < 8; i++)
1546			result[3][i] = result[c1][i];
1547		return false;
1548	} else {
1549		return false;
1550	}
1551}
1552
1553static void _rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw,
1554					long result[][8], u8 t, bool is2t)
1555{
1556	struct rtl_priv *rtlpriv = rtl_priv(hw);
1557	struct rtl_phy *rtlphy = &(rtlpriv->phy);
1558	u32 i;
1559	u8 patha_ok;
1560	u32 adda_reg[IQK_ADDA_REG_NUM] = {
1561		0x85c, 0xe6c, 0xe70, 0xe74,
1562		0xe78, 0xe7c, 0xe80, 0xe84,
1563		0xe88, 0xe8c, 0xed0, 0xed4,
1564		0xed8, 0xedc, 0xee0, 0xeec
1565	};
1566
1567	u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
1568		0x522, 0x550, 0x551, 0x040
1569	};
1570	u32 iqk_bb_reg[IQK_BB_REG_NUM] = {
1571		ROFDM0_TRXPATHENABLE, ROFDM0_TRMUXPAR,
1572		RFPGA0_XCD_RFINTERFACESW, 0xb68, 0xb6c,
1573		0x870, 0x860,
1574		0x864, 0x800
1575	};
1576	const u32 retrycount = 2;
1577	u32 path_sel_bb, path_sel_rf;
1578	u8 tmp_reg_c50, tmp_reg_c58;
1579
1580	tmp_reg_c50 = rtl_get_bbreg(hw, 0xc50, MASKBYTE0);
1581	tmp_reg_c58 = rtl_get_bbreg(hw, 0xc58, MASKBYTE0);
1582
1583	if (t == 0) {
1584		rtl8723_save_adda_registers(hw, adda_reg,
1585					    rtlphy->adda_backup, 16);
1586		rtl8723_phy_save_mac_registers(hw, iqk_mac_reg,
1587					       rtlphy->iqk_mac_backup);
1588		rtl8723_save_adda_registers(hw, iqk_bb_reg,
1589					    rtlphy->iqk_bb_backup,
1590					    IQK_BB_REG_NUM);
1591	}
1592	rtl8723_phy_path_adda_on(hw, adda_reg, true, is2t);
1593	if (t == 0) {
1594		rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw,
1595						RFPGA0_XA_HSSIPARAMETER1,
1596						BIT(8));
1597	}
1598	if (!rtlphy->rfpi_enable)
1599		rtl8723_phy_pi_mode_switch(hw, true);
1600
1601	path_sel_bb = rtl_get_bbreg(hw, 0x948, MASKDWORD);
1602	path_sel_rf = rtl_get_rfreg(hw, RF90_PATH_A, 0xb0, 0xfffff);
1603
1604	/*BB Setting*/
1605	rtl_set_bbreg(hw, 0x800, BIT(24), 0x00);
1606	rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600);
1607	rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4);
1608	rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000);
1609
1610	rtl_set_bbreg(hw, 0x870, BIT(10), 0x01);
1611	rtl_set_bbreg(hw, 0x870, BIT(26), 0x01);
1612	rtl_set_bbreg(hw, 0x860, BIT(10), 0x00);
1613	rtl_set_bbreg(hw, 0x864, BIT(10), 0x00);
1614
1615	if (is2t)
1616		rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASKDWORD, 0x10000);
1617	rtl8723_phy_mac_setting_calibration(hw, iqk_mac_reg,
1618					    rtlphy->iqk_mac_backup);
1619	rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x0f600000);
1620
1621	rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
1622	rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00);
1623	rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x81004800);
1624	for (i = 0; i < retrycount; i++) {
1625		patha_ok = _rtl8723be_phy_path_a_iqk(hw, is2t);
1626		if (patha_ok == 0x01) {
1627			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1628				 "Path A Tx IQK Success!!\n");
1629			result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) &
1630					0x3FF0000) >> 16;
1631			result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) &
1632					0x3FF0000) >> 16;
1633			break;
1634		}
1635	}
1636
1637	if (0 == patha_ok)
1638		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
1639			 "Path A IQK Success!!\n");
1640	if (is2t) {
1641		rtl8723_phy_path_a_standby(hw);
1642		rtl8723_phy_path_adda_on(hw, adda_reg, false, is2t);
1643	}
1644
1645	rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0);
1646
1647	if (t != 0) {
1648		if (!rtlphy->rfpi_enable)
1649			rtl8723_phy_pi_mode_switch(hw, false);
1650		rtl8723_phy_reload_adda_registers(hw, adda_reg,
1651						  rtlphy->adda_backup, 16);
1652		rtl8723_phy_reload_mac_registers(hw, iqk_mac_reg,
1653						 rtlphy->iqk_mac_backup);
1654		rtl8723_phy_reload_adda_registers(hw, iqk_bb_reg,
1655						  rtlphy->iqk_bb_backup,
1656						  IQK_BB_REG_NUM);
1657
1658		rtl_set_bbreg(hw, 0x948, MASKDWORD, path_sel_bb);
1659		rtl_set_rfreg(hw, RF90_PATH_B, 0xb0, 0xfffff, path_sel_rf);
1660
1661		rtl_set_bbreg(hw, 0xc50, MASKBYTE0, 0x50);
1662		rtl_set_bbreg(hw, 0xc50, MASKBYTE0, tmp_reg_c50);
1663		if (is2t) {
1664			rtl_set_bbreg(hw, 0xc58, MASKBYTE0, 0x50);
1665			rtl_set_bbreg(hw, 0xc58, MASKBYTE0, tmp_reg_c58);
1666		}
1667		rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x01008c00);
1668		rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x01008c00);
1669	}
1670	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "8723be IQK Finish!!\n");
1671}
1672
1673static void _rtl8723be_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
1674{
1675	struct rtl_priv *rtlpriv = rtl_priv(hw);
1676	u8 tmpreg;
1677	u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
1678
1679	tmpreg = rtl_read_byte(rtlpriv, 0xd03);
1680
1681	if ((tmpreg & 0x70) != 0)
1682		rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
1683	else
1684		rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
1685
1686	if ((tmpreg & 0x70) != 0) {
1687		rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS);
1688
1689		if (is2t)
1690			rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00,
1691						  MASK12BITS);
1692
1693		rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS,
1694			      (rf_a_mode & 0x8FFFF) | 0x10000);
1695
1696		if (is2t)
1697			rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
1698				      (rf_b_mode & 0x8FFFF) | 0x10000);
1699	}
1700	lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS);
1701
1702	rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, RFREG_OFFSET_MASK, 0xdfbe0);
1703	rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, 0x8c0a);
1704
1705	mdelay(100);
1706
1707	rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, RFREG_OFFSET_MASK, 0xdffe0);
1708
1709	if ((tmpreg & 0x70) != 0) {
1710		rtl_write_byte(rtlpriv, 0xd03, tmpreg);
1711		rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode);
1712
1713		if (is2t)
1714			rtl_set_rfreg(hw, RF90_PATH_B, 0x00,
1715				      MASK12BITS, rf_b_mode);
1716	} else {
1717		rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
1718	}
1719	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
1720}
1721
1722static void _rtl8723be_phy_set_rfpath_switch(struct ieee80211_hw *hw,
1723					     bool bmain, bool is2t)
1724{
1725	struct rtl_priv *rtlpriv = rtl_priv(hw);
1726	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1727	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1728	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
1729
1730	if (is_hal_stop(rtlhal)) {
1731		u8 u1btmp;
1732		u1btmp = rtl_read_byte(rtlpriv, REG_LEDCFG0);
1733		rtl_write_byte(rtlpriv, REG_LEDCFG0, u1btmp | BIT(7));
1734		rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(13), 0x01);
1735	}
1736	if (is2t) {
1737		if (bmain)
1738			rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1739				      BIT(5) | BIT(6), 0x1);
1740		else
1741			rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1742				      BIT(5) | BIT(6), 0x2);
1743	} else {
1744		rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BIT(8) | BIT(9), 0);
1745		rtl_set_bbreg(hw, 0x914, MASKLWORD, 0x0201);
1746
1747		/* We use the RF definition of MAIN and AUX,
1748		 * left antenna and right antenna repectively.
1749		 * Default output at AUX.
1750		 */
1751		if (bmain) {
1752			rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE,
1753				      BIT(14) | BIT(13) | BIT(12), 0);
1754			rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1755				      BIT(5) | BIT(4) | BIT(3), 0);
1756			if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV)
1757				rtl_set_bbreg(hw, CONFIG_RAM64X16, BIT(31), 0);
1758		} else {
1759			rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE,
1760				      BIT(14) | BIT(13) | BIT(12), 1);
1761			rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1762				      BIT(5) | BIT(4) | BIT(3), 1);
1763			if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV)
1764				rtl_set_bbreg(hw, CONFIG_RAM64X16, BIT(31), 1);
1765		}
1766	}
1767}
1768
1769#undef IQK_ADDA_REG_NUM
1770#undef IQK_DELAY_TIME
1771
1772void rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery)
1773{
1774	struct rtl_priv *rtlpriv = rtl_priv(hw);
1775	struct rtl_phy *rtlphy = &(rtlpriv->phy);
1776	long result[4][8];
1777	u8 i, final_candidate;
1778	bool patha_ok, pathb_ok;
1779	long reg_e94, reg_e9c, reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4,
1780	    reg_ecc, reg_tmp = 0;
1781	bool is12simular, is13simular, is23simular;
1782	u32 iqk_bb_reg[9] = {
1783		ROFDM0_XARXIQIMBALANCE,
1784		ROFDM0_XBRXIQIMBALANCE,
1785		ROFDM0_ECCATHRESHOLD,
1786		ROFDM0_AGCRSSITABLE,
1787		ROFDM0_XATXIQIMBALANCE,
1788		ROFDM0_XBTXIQIMBALANCE,
1789		ROFDM0_XCTXAFE,
1790		ROFDM0_XDTXAFE,
1791		ROFDM0_RXIQEXTANTA
1792	};
1793
1794	if (recovery) {
1795		rtl8723_phy_reload_adda_registers(hw, iqk_bb_reg,
1796						  rtlphy->iqk_bb_backup, 9);
1797		return;
1798	}
1799
1800	for (i = 0; i < 8; i++) {
1801		result[0][i] = 0;
1802		result[1][i] = 0;
1803		result[2][i] = 0;
1804		result[3][i] = 0;
1805	}
1806	final_candidate = 0xff;
1807	patha_ok = false;
1808	pathb_ok = false;
1809	is12simular = false;
1810	is23simular = false;
1811	is13simular = false;
1812	for (i = 0; i < 3; i++) {
1813		if (get_rf_type(rtlphy) == RF_2T2R)
1814			_rtl8723be_phy_iq_calibrate(hw, result, i, true);
1815		else
1816			_rtl8723be_phy_iq_calibrate(hw, result, i, false);
1817		if (i == 1) {
1818			is12simular = phy_similarity_cmp(hw, result, 0, 1);
1819			if (is12simular) {
1820				final_candidate = 0;
1821				break;
1822			}
1823		}
1824		if (i == 2) {
1825			is13simular = phy_similarity_cmp(hw, result, 0, 2);
1826			if (is13simular) {
1827				final_candidate = 0;
1828				break;
1829			}
1830			is23simular = phy_similarity_cmp(hw, result, 1, 2);
1831			if (is23simular) {
1832				final_candidate = 1;
1833			} else {
1834				for (i = 0; i < 8; i++)
1835					reg_tmp += result[3][i];
1836
1837				if (reg_tmp != 0)
1838					final_candidate = 3;
1839				else
1840					final_candidate = 0xFF;
1841			}
1842		}
1843	}
1844	for (i = 0; i < 4; i++) {
1845		reg_e94 = result[i][0];
1846		reg_e9c = result[i][1];
1847		reg_ea4 = result[i][2];
1848		reg_eac = result[i][3];
1849		reg_eb4 = result[i][4];
1850		reg_ebc = result[i][5];
1851		reg_ec4 = result[i][6];
1852		reg_ecc = result[i][7];
1853	}
1854	if (final_candidate != 0xff) {
1855		reg_e94 = result[final_candidate][0];
1856		rtlphy->reg_e94 = reg_e94;
1857		reg_e9c = result[final_candidate][1];
1858		rtlphy->reg_e9c = reg_e9c;
1859		reg_ea4 = result[final_candidate][2];
1860		reg_eac = result[final_candidate][3];
1861		reg_eb4 = result[final_candidate][4];
1862		rtlphy->reg_eb4 = reg_eb4;
1863		reg_ebc = result[final_candidate][5];
1864		rtlphy->reg_ebc = reg_ebc;
1865		reg_ec4 = result[final_candidate][6];
1866		reg_ecc = result[final_candidate][7];
1867		patha_ok = true;
1868		pathb_ok = true;
1869	} else {
1870		rtlphy->reg_e94 = 0x100;
1871		rtlphy->reg_eb4 = 0x100;
1872		rtlphy->reg_e9c = 0x0;
1873		rtlphy->reg_ebc = 0x0;
1874	}
1875	if (reg_e94 != 0) /*&&(reg_ea4 != 0) */
1876		rtl8723_phy_path_a_fill_iqk_matrix(hw, patha_ok, result,
1877						   final_candidate,
1878						   (reg_ea4 == 0));
1879	if (final_candidate != 0xFF) {
1880		for (i = 0; i < IQK_MATRIX_REG_NUM; i++)
1881			rtlphy->iqk_matrix[0].value[0][i] =
1882						result[final_candidate][i];
1883		rtlphy->iqk_matrix[0].iqk_done = true;
1884	}
1885	rtl8723_save_adda_registers(hw, iqk_bb_reg, rtlphy->iqk_bb_backup, 9);
1886}
1887
1888void rtl8723be_phy_lc_calibrate(struct ieee80211_hw *hw)
1889{
1890	struct rtl_priv *rtlpriv = rtl_priv(hw);
1891	struct rtl_phy *rtlphy = &(rtlpriv->phy);
1892	struct rtl_hal *rtlhal = &(rtlpriv->rtlhal);
1893	u32 timeout = 2000, timecount = 0;
1894
1895	while (rtlpriv->mac80211.act_scanning && timecount < timeout) {
1896		udelay(50);
1897		timecount += 50;
1898	}
1899
1900	rtlphy->lck_inprogress = true;
1901	RTPRINT(rtlpriv, FINIT, INIT_EEPROM,
1902		"LCK:Start!!! currentband %x delay %d ms\n",
1903		rtlhal->current_bandtype, timecount);
1904
1905	_rtl8723be_phy_lc_calibrate(hw, false);
1906
1907	rtlphy->lck_inprogress = false;
1908}
1909
1910void rtl23b_phy_ap_calibrate(struct ieee80211_hw *hw, char delta)
1911{
1912	struct rtl_priv *rtlpriv = rtl_priv(hw);
1913	struct rtl_phy *rtlphy = &(rtlpriv->phy);
1914
1915	if (rtlphy->apk_done)
1916		return;
1917
1918	return;
1919}
1920
1921void rtl8723be_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
1922{
1923	_rtl8723be_phy_set_rfpath_switch(hw, bmain, false);
1924}
1925
1926static void rtl8723be_phy_set_io(struct ieee80211_hw *hw)
1927{
1928	struct rtl_priv *rtlpriv = rtl_priv(hw);
1929	struct rtl_phy *rtlphy = &(rtlpriv->phy);
1930
1931	RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1932		 "--->Cmd(%#x), set_io_inprogress(%d)\n",
1933		  rtlphy->current_io_type, rtlphy->set_io_inprogress);
1934	switch (rtlphy->current_io_type) {
1935	case IO_CMD_RESUME_DM_BY_SCAN:
1936		rtlpriv->dm_digtable.cur_igvalue =
1937				 rtlphy->initgain_backup.xaagccore1;
1938		/*rtl92c_dm_write_dig(hw);*/
1939		rtl8723be_phy_set_txpower_level(hw, rtlphy->current_channel);
1940		rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x83);
1941		break;
1942	case IO_CMD_PAUSE_DM_BY_SCAN:
1943		rtlphy->initgain_backup.xaagccore1 =
1944				 rtlpriv->dm_digtable.cur_igvalue;
1945		rtlpriv->dm_digtable.cur_igvalue = 0x17;
1946		rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x40);
1947		break;
1948	default:
1949		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1950			 "switch case not process\n");
1951		break;
1952	}
1953	rtlphy->set_io_inprogress = false;
1954	RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1955		 "(%#x)\n", rtlphy->current_io_type);
1956}
1957
1958bool rtl8723be_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
1959{
1960	struct rtl_priv *rtlpriv = rtl_priv(hw);
1961	struct rtl_phy *rtlphy = &(rtlpriv->phy);
1962	bool postprocessing = false;
1963
1964	RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1965		 "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
1966		  iotype, rtlphy->set_io_inprogress);
1967	do {
1968		switch (iotype) {
1969		case IO_CMD_RESUME_DM_BY_SCAN:
1970			RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1971				 "[IO CMD] Resume DM after scan.\n");
1972			postprocessing = true;
1973			break;
1974		case IO_CMD_PAUSE_DM_BY_SCAN:
1975			RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
1976				 "[IO CMD] Pause DM before scan.\n");
1977			postprocessing = true;
1978			break;
1979		default:
1980			RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
1981				 "switch case not process\n");
1982			break;
1983		}
1984	} while (false);
1985	if (postprocessing && !rtlphy->set_io_inprogress) {
1986		rtlphy->set_io_inprogress = true;
1987		rtlphy->current_io_type = iotype;
1988	} else {
1989		return false;
1990	}
1991	rtl8723be_phy_set_io(hw);
1992	RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype);
1993	return true;
1994}
1995
1996static void rtl8723be_phy_set_rf_on(struct ieee80211_hw *hw)
1997{
1998	struct rtl_priv *rtlpriv = rtl_priv(hw);
1999
2000	rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
2001	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2002	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2003	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2004	rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
2005}
2006
2007static void _rtl8723be_phy_set_rf_sleep(struct ieee80211_hw *hw)
2008{
2009	struct rtl_priv *rtlpriv = rtl_priv(hw);
2010
2011	rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
2012	rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
2013	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2014	rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
2015}
2016
2017static bool _rtl8723be_phy_set_rf_power_state(struct ieee80211_hw *hw,
2018					      enum rf_pwrstate rfpwr_state)
2019{
2020	struct rtl_priv *rtlpriv = rtl_priv(hw);
2021	struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
2022	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2023	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2024	bool bresult = true;
2025	u8 i, queue_id;
2026	struct rtl8192_tx_ring *ring = NULL;
2027
2028	switch (rfpwr_state) {
2029	case ERFON:
2030		if ((ppsc->rfpwr_state == ERFOFF) &&
2031		    RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
2032			bool rtstatus;
2033			u32 initialize_count = 0;
2034			do {
2035				initialize_count++;
2036				RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2037					 "IPS Set eRf nic enable\n");
2038				rtstatus = rtl_ps_enable_nic(hw);
2039			} while (!rtstatus && (initialize_count < 10));
2040				RT_CLEAR_PS_LEVEL(ppsc,
2041						  RT_RF_OFF_LEVL_HALT_NIC);
2042		} else {
2043			RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2044				 "Set ERFON sleeped:%d ms\n",
2045				  jiffies_to_msecs(jiffies -
2046						   ppsc->last_sleep_jiffies));
2047			ppsc->last_awake_jiffies = jiffies;
2048			rtl8723be_phy_set_rf_on(hw);
2049		}
2050		if (mac->link_state == MAC80211_LINKED)
2051			rtlpriv->cfg->ops->led_control(hw, LED_CTL_LINK);
2052		else
2053			rtlpriv->cfg->ops->led_control(hw, LED_CTL_NO_LINK);
2054		break;
2055	case ERFOFF:
2056		for (queue_id = 0, i = 0;
2057		     queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
2058			ring = &pcipriv->dev.tx_ring[queue_id];
2059			if (skb_queue_len(&ring->queue) == 0) {
2060				queue_id++;
2061				continue;
2062			} else {
2063				RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2064					 "eRf Off/Sleep: %d times "
2065					  "TcbBusyQueue[%d] =%d before "
2066					  "doze!\n", (i + 1), queue_id,
2067					  skb_queue_len(&ring->queue));
2068
2069				udelay(10);
2070				i++;
2071			}
2072			if (i >= MAX_DOZE_WAITING_TIMES_9x) {
2073				RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2074					 "\n ERFSLEEP: %d times "
2075					  "TcbBusyQueue[%d] = %d !\n",
2076					  MAX_DOZE_WAITING_TIMES_9x,
2077					  queue_id,
2078					  skb_queue_len(&ring->queue));
2079				break;
2080			}
2081		}
2082
2083		if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
2084			RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2085				 "IPS Set eRf nic disable\n");
2086			rtl_ps_disable_nic(hw);
2087			RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2088		} else {
2089			if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
2090				rtlpriv->cfg->ops->led_control(hw,
2091							       LED_CTL_NO_LINK);
2092			} else {
2093				rtlpriv->cfg->ops->led_control(hw,
2094							     LED_CTL_POWER_OFF);
2095			}
2096		}
2097		break;
2098	case ERFSLEEP:
2099		if (ppsc->rfpwr_state == ERFOFF)
2100			break;
2101		for (queue_id = 0, i = 0;
2102		     queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
2103			ring = &pcipriv->dev.tx_ring[queue_id];
2104			if (skb_queue_len(&ring->queue) == 0) {
2105				queue_id++;
2106				continue;
2107			} else {
2108				RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2109					 "eRf Off/Sleep: %d times "
2110					  "TcbBusyQueue[%d] =%d before "
2111					  "doze!\n", (i + 1), queue_id,
2112					  skb_queue_len(&ring->queue));
2113
2114				udelay(10);
2115				i++;
2116			}
2117			if (i >= MAX_DOZE_WAITING_TIMES_9x) {
2118				RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2119					 "\n ERFSLEEP: %d times "
2120					  "TcbBusyQueue[%d] = %d !\n",
2121					  MAX_DOZE_WAITING_TIMES_9x,
2122					  queue_id,
2123					  skb_queue_len(&ring->queue));
2124				break;
2125			}
2126		}
2127		RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2128			 "Set ERFSLEEP awaked:%d ms\n",
2129			  jiffies_to_msecs(jiffies -
2130					   ppsc->last_awake_jiffies));
2131		ppsc->last_sleep_jiffies = jiffies;
2132		_rtl8723be_phy_set_rf_sleep(hw);
2133		break;
2134	default:
2135		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
2136			 "switch case not process\n");
2137		bresult = false;
2138		break;
2139	}
2140	if (bresult)
2141		ppsc->rfpwr_state = rfpwr_state;
2142	return bresult;
2143}
2144
2145bool rtl8723be_phy_set_rf_power_state(struct ieee80211_hw *hw,
2146				      enum rf_pwrstate rfpwr_state)
2147{
2148	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2149
2150	bool bresult = false;
2151
2152	if (rfpwr_state == ppsc->rfpwr_state)
2153		return bresult;
2154	bresult = _rtl8723be_phy_set_rf_power_state(hw, rfpwr_state);
2155	return bresult;
2156}