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