10c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger/******************************************************************************
20c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger *
39003a4aba4b040be265ce8ed51f6fe437d369453Larry Finger * Copyright(c) 2009-2012  Realtek Corporation.
40c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger *
50c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger * This program is free software; you can redistribute it and/or modify it
60c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger * under the terms of version 2 of the GNU General Public License as
70c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger * published by the Free Software Foundation.
80c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger *
90c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger * This program is distributed in the hope that it will be useful, but WITHOUT
100c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
110c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
120c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger * more details.
130c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger *
140c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger * You should have received a copy of the GNU General Public License along with
150c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger * this program; if not, write to the Free Software Foundation, Inc.,
160c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
170c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger *
180c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger * The full GNU General Public License is included in this distribution in the
190c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger * file called LICENSE.
200c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger *
210c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger * Contact Information:
220c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger * wlanfae <wlanfae@realtek.com>
230c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
240c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger * Hsinchu 300, Taiwan.
250c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger *
260c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger * Larry Finger <Larry.Finger@lwfinger.net>
270c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger *
280c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger *****************************************************************************/
290c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger
300c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger#include "../wifi.h"
310c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger#include "../pci.h"
320c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger#include "../ps.h"
3325b13dbc38a74b76da5746d75867e306b70035bdLarry Finger#include "../core.h"
345c405b5c3e435fd332058c59ee58eaa1ac9c513aJohn W. Linville#include "reg.h"
355c405b5c3e435fd332058c59ee58eaa1ac9c513aJohn W. Linville#include "def.h"
361472d3a87586eb7529d1d85f7c888055650b7208Larry Finger#include "hw.h"
375c405b5c3e435fd332058c59ee58eaa1ac9c513aJohn W. Linville#include "phy.h"
389f087a924427c01190b205f0051be00808c99828Larry Finger#include "../rtl8192c/phy_common.h"
395c405b5c3e435fd332058c59ee58eaa1ac9c513aJohn W. Linville#include "rf.h"
405c405b5c3e435fd332058c59ee58eaa1ac9c513aJohn W. Linville#include "dm.h"
419f087a924427c01190b205f0051be00808c99828Larry Finger#include "../rtl8192c/dm_common.h"
429f087a924427c01190b205f0051be00808c99828Larry Finger#include "../rtl8192c/fw_common.h"
435c405b5c3e435fd332058c59ee58eaa1ac9c513aJohn W. Linville#include "table.h"
440c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger
45e0b5a5078675f58736787982af811244eeb98081Chaoming_Listatic bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);
46e0b5a5078675f58736787982af811244eeb98081Chaoming_Li
47e0b5a5078675f58736787982af811244eeb98081Chaoming_Liu32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw,
480c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger			    enum radio_path rfpath, u32 regaddr, u32 bitmask)
490c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger{
500c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	struct rtl_priv *rtlpriv = rtl_priv(hw);
510c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	u32 original_value, readback_value, bitshift;
520c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	struct rtl_phy *rtlphy = &(rtlpriv->phy);
530c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger
54f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
55f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches		 "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
56f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches		 regaddr, rfpath, bitmask);
570c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger
58312d5479dcfaca2b8aa451201b5388fdb8c8684aMike McCormack	spin_lock(&rtlpriv->locks.rf_lock);
590c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger
600c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	if (rtlphy->rf_mode != RF_OP_BY_FW) {
610c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		original_value = _rtl92c_phy_rf_serial_read(hw,
620c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger							    rfpath, regaddr);
630c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	} else {
640c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		original_value = _rtl92c_phy_fw_rf_serial_read(hw,
650c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger							       rfpath, regaddr);
660c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	}
670c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger
680c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
690c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	readback_value = (original_value & bitmask) >> bitshift;
700c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger
71312d5479dcfaca2b8aa451201b5388fdb8c8684aMike McCormack	spin_unlock(&rtlpriv->locks.rf_lock);
720c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger
730c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
74f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches		 "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n",
75f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches		 regaddr, rfpath, bitmask, original_value);
760c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger
770c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	return readback_value;
780c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger}
790c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger
80e0b5a5078675f58736787982af811244eeb98081Chaoming_Libool rtl92c_phy_mac_config(struct ieee80211_hw *hw)
81e0b5a5078675f58736787982af811244eeb98081Chaoming_Li{
82e0b5a5078675f58736787982af811244eeb98081Chaoming_Li	struct rtl_priv *rtlpriv = rtl_priv(hw);
83e0b5a5078675f58736787982af811244eeb98081Chaoming_Li	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
84e0b5a5078675f58736787982af811244eeb98081Chaoming_Li	bool is92c = IS_92C_SERIAL(rtlhal->version);
85e0b5a5078675f58736787982af811244eeb98081Chaoming_Li	bool rtstatus = _rtl92c_phy_config_mac_with_headerfile(hw);
86e0b5a5078675f58736787982af811244eeb98081Chaoming_Li
87e0b5a5078675f58736787982af811244eeb98081Chaoming_Li	if (is92c)
88e0b5a5078675f58736787982af811244eeb98081Chaoming_Li		rtl_write_byte(rtlpriv, 0x14, 0x71);
890bd899e76476e0134f7289a003090165adea2611Larry Finger	else
900bd899e76476e0134f7289a003090165adea2611Larry Finger		rtl_write_byte(rtlpriv, 0x04CA, 0x0A);
91e0b5a5078675f58736787982af811244eeb98081Chaoming_Li	return rtstatus;
92e0b5a5078675f58736787982af811244eeb98081Chaoming_Li}
93e0b5a5078675f58736787982af811244eeb98081Chaoming_Li
94e0b5a5078675f58736787982af811244eeb98081Chaoming_Libool rtl92c_phy_bb_config(struct ieee80211_hw *hw)
95e0b5a5078675f58736787982af811244eeb98081Chaoming_Li{
96e0b5a5078675f58736787982af811244eeb98081Chaoming_Li	bool rtstatus = true;
97e0b5a5078675f58736787982af811244eeb98081Chaoming_Li	struct rtl_priv *rtlpriv = rtl_priv(hw);
98e0b5a5078675f58736787982af811244eeb98081Chaoming_Li	u16 regval;
99e0b5a5078675f58736787982af811244eeb98081Chaoming_Li	u32 regvaldw;
100e0b5a5078675f58736787982af811244eeb98081Chaoming_Li	u8 reg_hwparafile = 1;
101e0b5a5078675f58736787982af811244eeb98081Chaoming_Li
102e0b5a5078675f58736787982af811244eeb98081Chaoming_Li	_rtl92c_phy_init_bb_rf_register_definition(hw);
103e0b5a5078675f58736787982af811244eeb98081Chaoming_Li	regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
104e0b5a5078675f58736787982af811244eeb98081Chaoming_Li	rtl_write_word(rtlpriv, REG_SYS_FUNC_EN,
105e0b5a5078675f58736787982af811244eeb98081Chaoming_Li		       regval | BIT(13) | BIT(0) | BIT(1));
106e0b5a5078675f58736787982af811244eeb98081Chaoming_Li	rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x83);
107e0b5a5078675f58736787982af811244eeb98081Chaoming_Li	rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL + 1, 0xdb);
108e0b5a5078675f58736787982af811244eeb98081Chaoming_Li	rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB);
109e0b5a5078675f58736787982af811244eeb98081Chaoming_Li	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN,
110e0b5a5078675f58736787982af811244eeb98081Chaoming_Li		       FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE |
111e0b5a5078675f58736787982af811244eeb98081Chaoming_Li		       FEN_BB_GLB_RSTn | FEN_BBRSTB);
112e0b5a5078675f58736787982af811244eeb98081Chaoming_Li	rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80);
113e0b5a5078675f58736787982af811244eeb98081Chaoming_Li	regvaldw = rtl_read_dword(rtlpriv, REG_LEDCFG0);
114e0b5a5078675f58736787982af811244eeb98081Chaoming_Li	rtl_write_dword(rtlpriv, REG_LEDCFG0, regvaldw | BIT(23));
115e0b5a5078675f58736787982af811244eeb98081Chaoming_Li	if (reg_hwparafile == 1)
116e0b5a5078675f58736787982af811244eeb98081Chaoming_Li		rtstatus = _rtl92c_phy_bb8192c_config_parafile(hw);
117e0b5a5078675f58736787982af811244eeb98081Chaoming_Li	return rtstatus;
118e0b5a5078675f58736787982af811244eeb98081Chaoming_Li}
119e0b5a5078675f58736787982af811244eeb98081Chaoming_Li
1201472d3a87586eb7529d1d85f7c888055650b7208Larry Fingervoid rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw,
121e0b5a5078675f58736787982af811244eeb98081Chaoming_Li			    enum radio_path rfpath,
122e0b5a5078675f58736787982af811244eeb98081Chaoming_Li			    u32 regaddr, u32 bitmask, u32 data)
1230c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger{
1240c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	struct rtl_priv *rtlpriv = rtl_priv(hw);
1250c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	struct rtl_phy *rtlphy = &(rtlpriv->phy);
1260c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	u32 original_value, bitshift;
1270c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger
1280c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
129f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches		 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
130f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches		 regaddr, bitmask, data, rfpath);
1310c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger
132312d5479dcfaca2b8aa451201b5388fdb8c8684aMike McCormack	spin_lock(&rtlpriv->locks.rf_lock);
1330c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger
1340c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	if (rtlphy->rf_mode != RF_OP_BY_FW) {
1350c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		if (bitmask != RFREG_OFFSET_MASK) {
1360c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger			original_value = _rtl92c_phy_rf_serial_read(hw,
1370c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger								    rfpath,
1380c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger								    regaddr);
1390c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger			bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
1400c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger			data =
1410c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger			    ((original_value & (~bitmask)) |
1420c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger			     (data << bitshift));
1430c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		}
1440c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger
1450c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		_rtl92c_phy_rf_serial_write(hw, rfpath, regaddr, data);
1460c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	} else {
1470c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		if (bitmask != RFREG_OFFSET_MASK) {
1480c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger			original_value = _rtl92c_phy_fw_rf_serial_read(hw,
1490c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger								       rfpath,
1500c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger								       regaddr);
1510c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger			bitshift = _rtl92c_phy_calculate_bit_shift(bitmask);
1520c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger			data =
1530c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger			    ((original_value & (~bitmask)) |
1540c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger			     (data << bitshift));
1550c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		}
1560c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		_rtl92c_phy_fw_rf_serial_write(hw, rfpath, regaddr, data);
1570c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	}
1580c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger
159312d5479dcfaca2b8aa451201b5388fdb8c8684aMike McCormack	spin_unlock(&rtlpriv->locks.rf_lock);
1600c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger
161f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
162f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches		 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
163f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches		 regaddr, bitmask, data, rfpath);
1640c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger}
1650c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger
166e0b5a5078675f58736787982af811244eeb98081Chaoming_Listatic bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
1670c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger{
1680c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	struct rtl_priv *rtlpriv = rtl_priv(hw);
1690c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	u32 i;
1700c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	u32 arraylength;
1710c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	u32 *ptrarray;
1720c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger
173f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl819XMACPHY_Array\n");
1740c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	arraylength = MAC_2T_ARRAYLENGTH;
1750c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	ptrarray = RTL8192CEMAC_2T_ARRAY;
176f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Img:RTL8192CEMAC_2T_ARRAY\n");
1770c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	for (i = 0; i < arraylength; i = i + 2)
1780c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]);
1790c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	return true;
1800c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger}
1810c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger
1821472d3a87586eb7529d1d85f7c888055650b7208Larry Fingerbool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
183e0b5a5078675f58736787982af811244eeb98081Chaoming_Li					    u8 configtype)
1840c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger{
1850c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	int i;
1860c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	u32 *phy_regarray_table;
1870c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	u32 *agctab_array_table;
1880c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	u16 phy_reg_arraylen, agctab_arraylen;
1890c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	struct rtl_priv *rtlpriv = rtl_priv(hw);
1900c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1910c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger
1920c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	if (IS_92C_SERIAL(rtlhal->version)) {
1930c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		agctab_arraylen = AGCTAB_2TARRAYLENGTH;
1940c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		agctab_array_table = RTL8192CEAGCTAB_2TARRAY;
1950c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		phy_reg_arraylen = PHY_REG_2TARRAY_LENGTH;
1960c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		phy_regarray_table = RTL8192CEPHY_REG_2TARRAY;
1970c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	} else {
1980c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		agctab_arraylen = AGCTAB_1TARRAYLENGTH;
1990c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		agctab_array_table = RTL8192CEAGCTAB_1TARRAY;
2000c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		phy_reg_arraylen = PHY_REG_1TARRAY_LENGTH;
2010c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		phy_regarray_table = RTL8192CEPHY_REG_1TARRAY;
2020c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	}
2030c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	if (configtype == BASEBAND_CONFIG_PHY_REG) {
2040c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		for (i = 0; i < phy_reg_arraylen; i = i + 2) {
20525b13dbc38a74b76da5746d75867e306b70035bdLarry Finger			rtl_addr_delay(phy_regarray_table[i]);
2060c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger			rtl_set_bbreg(hw, phy_regarray_table[i], MASKDWORD,
2070c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger				      phy_regarray_table[i + 1]);
2080c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger			udelay(1);
2090c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger			RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
210f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches				 "The phy_regarray_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n",
211f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches				 phy_regarray_table[i],
212f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches				 phy_regarray_table[i + 1]);
2130c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		}
2140c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	} else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
2150c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		for (i = 0; i < agctab_arraylen; i = i + 2) {
2160c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger			rtl_set_bbreg(hw, agctab_array_table[i], MASKDWORD,
2170c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger				      agctab_array_table[i + 1]);
2180c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger			udelay(1);
2190c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger			RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
220f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches				 "The agctab_array_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n",
221f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches				 agctab_array_table[i],
222f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches				 agctab_array_table[i + 1]);
2230c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		}
2240c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	}
2250c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	return true;
2260c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger}
2270c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger
2281472d3a87586eb7529d1d85f7c888055650b7208Larry Fingerbool _rtl92ce_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
229e0b5a5078675f58736787982af811244eeb98081Chaoming_Li					      u8 configtype)
2300c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger{
2310c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	struct rtl_priv *rtlpriv = rtl_priv(hw);
2320c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	int i;
2330c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	u32 *phy_regarray_table_pg;
2340c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	u16 phy_regarray_pg_len;
2350c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger
2360c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	phy_regarray_pg_len = PHY_REG_ARRAY_PGLENGTH;
2370c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	phy_regarray_table_pg = RTL8192CEPHY_REG_ARRAY_PG;
2380c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger
2390c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	if (configtype == BASEBAND_CONFIG_PHY_REG) {
2400c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		for (i = 0; i < phy_regarray_pg_len; i = i + 3) {
24125b13dbc38a74b76da5746d75867e306b70035bdLarry Finger			rtl_addr_delay(phy_regarray_table_pg[i]);
2420c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger
2430c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger			_rtl92c_store_pwrIndex_diffrate_offset(hw,
2440c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger					       phy_regarray_table_pg[i],
2450c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger					       phy_regarray_table_pg[i + 1],
2460c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger					       phy_regarray_table_pg[i + 2]);
2470c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		}
2480c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	} else {
2490c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger
2500c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
251f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches			 "configtype != BaseBand_Config_PHY_REG\n");
2520c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	}
2530c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	return true;
2540c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger}
2550c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger
256e0b5a5078675f58736787982af811244eeb98081Chaoming_Libool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
2570c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger					  enum radio_path rfpath)
2580c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger{
2590c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger
2600c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	int i;
2610c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	u32 *radioa_array_table;
2620c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	u32 *radiob_array_table;
2630c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	u16 radioa_arraylen, radiob_arraylen;
2640c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	struct rtl_priv *rtlpriv = rtl_priv(hw);
2650c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
2660c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger
2670c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	if (IS_92C_SERIAL(rtlhal->version)) {
2680c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		radioa_arraylen = RADIOA_2TARRAYLENGTH;
2690c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		radioa_array_table = RTL8192CERADIOA_2TARRAY;
2700c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		radiob_arraylen = RADIOB_2TARRAYLENGTH;
2710c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		radiob_array_table = RTL8192CE_RADIOB_2TARRAY;
2720c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
273f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches			 "Radio_A:RTL8192CERADIOA_2TARRAY\n");
2740c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
275f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches			 "Radio_B:RTL8192CE_RADIOB_2TARRAY\n");
2760c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	} else {
2770c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		radioa_arraylen = RADIOA_1TARRAYLENGTH;
2780c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		radioa_array_table = RTL8192CE_RADIOA_1TARRAY;
2790c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		radiob_arraylen = RADIOB_1TARRAYLENGTH;
2800c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		radiob_array_table = RTL8192CE_RADIOB_1TARRAY;
2810c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
282f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches			 "Radio_A:RTL8192CE_RADIOA_1TARRAY\n");
2830c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
284f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches			 "Radio_B:RTL8192CE_RADIOB_1TARRAY\n");
2850c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	}
286f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Radio No %x\n", rfpath);
2870c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	switch (rfpath) {
2880c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	case RF90_PATH_A:
2890c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		for (i = 0; i < radioa_arraylen; i = i + 2) {
29025b13dbc38a74b76da5746d75867e306b70035bdLarry Finger			rtl_rfreg_delay(hw, rfpath, radioa_array_table[i],
29125b13dbc38a74b76da5746d75867e306b70035bdLarry Finger					RFREG_OFFSET_MASK,
29225b13dbc38a74b76da5746d75867e306b70035bdLarry Finger					radioa_array_table[i + 1]);
2930c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		}
2940c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		break;
2950c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	case RF90_PATH_B:
2960c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		for (i = 0; i < radiob_arraylen; i = i + 2) {
29725b13dbc38a74b76da5746d75867e306b70035bdLarry Finger			rtl_rfreg_delay(hw, rfpath, radiob_array_table[i],
29825b13dbc38a74b76da5746d75867e306b70035bdLarry Finger					RFREG_OFFSET_MASK,
29925b13dbc38a74b76da5746d75867e306b70035bdLarry Finger					radiob_array_table[i + 1]);
3000c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		}
3010c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		break;
3020c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	case RF90_PATH_C:
3030c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
304f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches			 "switch case not processed\n");
3050c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		break;
3060c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	case RF90_PATH_D:
3070c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
308f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches			 "switch case not processed\n");
3090c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		break;
31025b13dbc38a74b76da5746d75867e306b70035bdLarry Finger	default:
31125b13dbc38a74b76da5746d75867e306b70035bdLarry Finger		break;
3120c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	}
3130c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	return true;
3140c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger}
3150c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger
316099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Fingervoid rtl92ce_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
317099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger{
318099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger	struct rtl_priv *rtlpriv = rtl_priv(hw);
319099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
320099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger	struct rtl_phy *rtlphy = &(rtlpriv->phy);
321099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
322099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger	u8 reg_bw_opmode;
323099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger	u8 reg_prsr_rsc;
324099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger
325f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n",
326f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches		 rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
327f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches		 "20MHz" : "40MHz");
328099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger
329099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger	if (is_hal_stop(rtlhal)) {
330099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger		rtlphy->set_bwmode_inprogress = false;
331099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger		return;
332099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger	}
333099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger
334099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger	reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
335099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger	reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
336099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger
337099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger	switch (rtlphy->current_chan_bw) {
338099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger	case HT_CHANNEL_WIDTH_20:
339099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger		reg_bw_opmode |= BW_OPMODE_20MHZ;
340099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger		rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
341099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger		break;
342099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger	case HT_CHANNEL_WIDTH_20_40:
343099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger		reg_bw_opmode &= ~BW_OPMODE_20MHZ;
344099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger		rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
345099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger		reg_prsr_rsc =
346099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger		    (reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5);
347099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger		rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
348099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger		break;
349099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger	default:
350099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
351f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches			 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
352099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger		break;
353099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger	}
354099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger
355099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger	switch (rtlphy->current_chan_bw) {
356099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger	case HT_CHANNEL_WIDTH_20:
357099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger		rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
358099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger		rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
359099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger		rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1);
360099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger		break;
361099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger	case HT_CHANNEL_WIDTH_20_40:
362099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger		rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
363099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger		rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
364099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger
365099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger		rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
366099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger			      (mac->cur_40_prime_sc >> 1));
367099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger		rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
368099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger		rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0);
369099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger
370099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger		rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
371099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger			      (mac->cur_40_prime_sc ==
372099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger			       HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
373099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger		break;
374099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger	default:
375099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
376f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches			 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw);
377099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger		break;
378099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger	}
379099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger	rtl92ce_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
380099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger	rtlphy->set_bwmode_inprogress = false;
381f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n");
382099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger}
383099fb8ab1e57e5d609ac686cc0ab6d1835a79155Larry Finger
3841472d3a87586eb7529d1d85f7c888055650b7208Larry Fingervoid _rtl92ce_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
3850c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger{
3864295cd254af3181873c7ad15969421d3cb852cf9Larry Finger	u8 tmpreg;
3874295cd254af3181873c7ad15969421d3cb852cf9Larry Finger	u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
3880c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	struct rtl_priv *rtlpriv = rtl_priv(hw);
3890c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger
3904295cd254af3181873c7ad15969421d3cb852cf9Larry Finger	tmpreg = rtl_read_byte(rtlpriv, 0xd03);
3910c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger
3924295cd254af3181873c7ad15969421d3cb852cf9Larry Finger	if ((tmpreg & 0x70) != 0)
3934295cd254af3181873c7ad15969421d3cb852cf9Larry Finger		rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
3944295cd254af3181873c7ad15969421d3cb852cf9Larry Finger	else
3954295cd254af3181873c7ad15969421d3cb852cf9Larry Finger		rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
3960c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger
3974295cd254af3181873c7ad15969421d3cb852cf9Larry Finger	if ((tmpreg & 0x70) != 0) {
3984295cd254af3181873c7ad15969421d3cb852cf9Larry Finger		rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS);
3990c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger
4000c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		if (is2t)
4010c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger			rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00,
4020c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger						  MASK12BITS);
4030c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger
4040c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS,
4050c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger			      (rf_a_mode & 0x8FFFF) | 0x10000);
4060c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger
4070c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		if (is2t)
4080c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger			rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
4090c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger				      (rf_b_mode & 0x8FFFF) | 0x10000);
4100c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	}
4110c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS);
4120c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger
4130c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, lc_cal | 0x08000);
4140c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger
4150c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	mdelay(100);
4160c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger
4170c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	if ((tmpreg & 0x70) != 0) {
4180c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		rtl_write_byte(rtlpriv, 0xd03, tmpreg);
4190c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode);
4200c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger
4210c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		if (is2t)
4220c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger			rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
4230c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger				      rf_b_mode);
4240c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	} else {
4250c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
4260c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	}
4270c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger}
4280c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger
429e0b5a5078675f58736787982af811244eeb98081Chaoming_Listatic void _rtl92ce_phy_set_rf_sleep(struct ieee80211_hw *hw)
430e0b5a5078675f58736787982af811244eeb98081Chaoming_Li{
431e0b5a5078675f58736787982af811244eeb98081Chaoming_Li	u32 u4b_tmp;
432e0b5a5078675f58736787982af811244eeb98081Chaoming_Li	u8 delay = 5;
433e0b5a5078675f58736787982af811244eeb98081Chaoming_Li	struct rtl_priv *rtlpriv = rtl_priv(hw);
434e0b5a5078675f58736787982af811244eeb98081Chaoming_Li
435e0b5a5078675f58736787982af811244eeb98081Chaoming_Li	rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
436e0b5a5078675f58736787982af811244eeb98081Chaoming_Li	rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
437e0b5a5078675f58736787982af811244eeb98081Chaoming_Li	rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
438e0b5a5078675f58736787982af811244eeb98081Chaoming_Li	u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
439e0b5a5078675f58736787982af811244eeb98081Chaoming_Li	while (u4b_tmp != 0 && delay > 0) {
440e0b5a5078675f58736787982af811244eeb98081Chaoming_Li		rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0);
441e0b5a5078675f58736787982af811244eeb98081Chaoming_Li		rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
442e0b5a5078675f58736787982af811244eeb98081Chaoming_Li		rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
443e0b5a5078675f58736787982af811244eeb98081Chaoming_Li		u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
444e0b5a5078675f58736787982af811244eeb98081Chaoming_Li		delay--;
445e0b5a5078675f58736787982af811244eeb98081Chaoming_Li	}
446e0b5a5078675f58736787982af811244eeb98081Chaoming_Li	if (delay == 0) {
447e0b5a5078675f58736787982af811244eeb98081Chaoming_Li		rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);
448e0b5a5078675f58736787982af811244eeb98081Chaoming_Li		rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
449e0b5a5078675f58736787982af811244eeb98081Chaoming_Li		rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
450e0b5a5078675f58736787982af811244eeb98081Chaoming_Li		rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
451e0b5a5078675f58736787982af811244eeb98081Chaoming_Li		RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
452f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches			 "Switch RF timeout !!!\n");
453e0b5a5078675f58736787982af811244eeb98081Chaoming_Li		return;
454e0b5a5078675f58736787982af811244eeb98081Chaoming_Li	}
455e0b5a5078675f58736787982af811244eeb98081Chaoming_Li	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
456e0b5a5078675f58736787982af811244eeb98081Chaoming_Li	rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
457e0b5a5078675f58736787982af811244eeb98081Chaoming_Li}
458e0b5a5078675f58736787982af811244eeb98081Chaoming_Li
4590c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Fingerstatic bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw,
4600c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger					    enum rf_pwrstate rfpwr_state)
4610c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger{
4620c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	struct rtl_priv *rtlpriv = rtl_priv(hw);
4630c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
4640c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
4650c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
4660c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	bool bresult = true;
4670c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	u8 i, queue_id;
4680c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	struct rtl8192_tx_ring *ring = NULL;
4690c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger
4700c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	switch (rfpwr_state) {
4710c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	case ERFON:{
4720c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger			if ((ppsc->rfpwr_state == ERFOFF) &&
4730c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger			    RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
4740c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger				bool rtstatus;
4750c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger				u32 InitializeCount = 0;
4760c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger				do {
4770c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger					InitializeCount++;
4780c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger					RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
479f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches						 "IPS Set eRf nic enable\n");
4800c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger					rtstatus = rtl_ps_enable_nic(hw);
48123677ce3172fcb93522a1df077d21019e73ee1e3Joe Perches				} while (!rtstatus && (InitializeCount < 10));
4820c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger				RT_CLEAR_PS_LEVEL(ppsc,
4830c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger						  RT_RF_OFF_LEVL_HALT_NIC);
4840c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger			} else {
4850c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger				RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
486f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches					 "Set ERFON sleeped:%d ms\n",
487f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches					 jiffies_to_msecs(jiffies -
488f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches							  ppsc->
489f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches							  last_sleep_jiffies));
4900c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger				ppsc->last_awake_jiffies = jiffies;
4910c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger				rtl92ce_phy_set_rf_on(hw);
4920c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger			}
4930c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger			if (mac->link_state == MAC80211_LINKED) {
4940c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger				rtlpriv->cfg->ops->led_control(hw,
4950c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger							       LED_CTL_LINK);
4960c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger			} else {
4970c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger				rtlpriv->cfg->ops->led_control(hw,
4980c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger							       LED_CTL_NO_LINK);
4990c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger			}
5000c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger			break;
5010c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		}
5020c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	case ERFOFF:{
5030c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger			if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
5040c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger				RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
505f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches					 "IPS Set eRf nic disable\n");
5060c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger				rtl_ps_disable_nic(hw);
5070c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger				RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
5080c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger			} else {
5090c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger				if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
5100c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger					rtlpriv->cfg->ops->led_control(hw,
5110c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger							       LED_CTL_NO_LINK);
5120c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger				} else {
5130c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger					rtlpriv->cfg->ops->led_control(hw,
5140c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger							     LED_CTL_POWER_OFF);
5150c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger				}
5160c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger			}
5170c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger			break;
5180c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		}
5190c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	case ERFSLEEP:{
5200c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger			if (ppsc->rfpwr_state == ERFOFF)
52191ddff8a3b9cc7ac2252aca138220939cf6cc2cfPhilipp Dreimann				return false;
5220c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger			for (queue_id = 0, i = 0;
5230c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger			     queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
5240c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger				ring = &pcipriv->dev.tx_ring[queue_id];
5250c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger				if (skb_queue_len(&ring->queue) == 0) {
5260c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger					queue_id++;
5270c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger					continue;
5280c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger				} else {
5290c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger					RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
530f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches						 "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
531f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches						 i + 1, queue_id,
532f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches						 skb_queue_len(&ring->queue));
533e0b5a5078675f58736787982af811244eeb98081Chaoming_Li
5340c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger					udelay(10);
5350c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger					i++;
5360c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger				}
5370c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger				if (i >= MAX_DOZE_WAITING_TIMES_9x) {
5380c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger					RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
539f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches						 "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
540f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches						 MAX_DOZE_WAITING_TIMES_9x,
541f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches						 queue_id,
542f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches						 skb_queue_len(&ring->queue));
5430c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger					break;
5440c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger				}
5450c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger			}
5460c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger			RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
547f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches				 "Set ERFSLEEP awaked:%d ms\n",
548f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches				 jiffies_to_msecs(jiffies -
549f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches						  ppsc->last_awake_jiffies));
5500c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger			ppsc->last_sleep_jiffies = jiffies;
551e0b5a5078675f58736787982af811244eeb98081Chaoming_Li			_rtl92ce_phy_set_rf_sleep(hw);
5520c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger			break;
5530c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		}
5540c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	default:
5550c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
556f30d7507a8116e2099a9135c873411db8c0a3dc6Joe Perches			 "switch case not processed\n");
5570c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		bresult = false;
5580c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		break;
5590c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	}
5600c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	if (bresult)
5610c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		ppsc->rfpwr_state = rfpwr_state;
5620c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	return bresult;
5630c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger}
5640c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger
565e0b5a5078675f58736787982af811244eeb98081Chaoming_Libool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw,
5660c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger				   enum rf_pwrstate rfpwr_state)
5670c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger{
5680c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
569e0b5a5078675f58736787982af811244eeb98081Chaoming_Li
5700c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	bool bresult = false;
5710c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger
5720c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	if (rfpwr_state == ppsc->rfpwr_state)
5730c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger		return bresult;
5740c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	bresult = _rtl92ce_phy_set_rf_power_state(hw, rfpwr_state);
5750c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger	return bresult;
5760c8173385e549f95cd80c3fff5aab87b4f881d8dLarry Finger}
577