diff options
author | Larry Finger <Larry.Finger@lwfinger.net> | 2011-02-19 17:29:12 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2011-02-21 15:39:57 -0500 |
commit | 4295cd254af3181873c7ad15969421d3cb852cf9 (patch) | |
tree | 7b3e83ba68264d17b90ca94dd3afe93c1e348c08 /drivers/net/wireless/rtlwifi | |
parent | e97b775d9bce1d7b51df5bf470ba9c529d93dc66 (diff) |
rtlwifi: Move common parts of rtl8192ce/phy.c
Move common routines from rtlwifi/rtl8192ce/phy.c and .../rtl8192cu/phy.c
into rtlwifi/rtl8192c/phy_common.c.
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rtlwifi')
-rw-r--r-- | drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c | 2049 | ||||
-rw-r--r-- | drivers/net/wireless/rtlwifi/rtl8192ce/phy.c | 2019 |
2 files changed, 2050 insertions, 2018 deletions
diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c new file mode 100644 index 000000000000..3728abc4df59 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192c/phy_common.c | |||
@@ -0,0 +1,2049 @@ | |||
1 | /****************************************************************************** | ||
2 | * | ||
3 | * Copyright(c) 2009-2010 Realtek Corporation. | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify it | ||
6 | * under the terms of version 2 of the GNU General Public License as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
12 | * more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License along with | ||
15 | * this program; if not, write to the Free Software Foundation, Inc., | ||
16 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA | ||
17 | * | ||
18 | * The full GNU General Public License is included in this distribution in the | ||
19 | * file called LICENSE. | ||
20 | * | ||
21 | * Contact Information: | ||
22 | * wlanfae <wlanfae@realtek.com> | ||
23 | * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, | ||
24 | * Hsinchu 300, Taiwan. | ||
25 | * | ||
26 | * Larry Finger <Larry.Finger@lwfinger.net> | ||
27 | * | ||
28 | *****************************************************************************/ | ||
29 | |||
30 | /* Define macro to shorten lines */ | ||
31 | #define MCS_TXPWR mcs_txpwrlevel_origoffset | ||
32 | |||
33 | static u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, | ||
34 | enum radio_path rfpath, u32 offset); | ||
35 | static void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, | ||
36 | enum radio_path rfpath, u32 offset, | ||
37 | u32 data); | ||
38 | static u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, | ||
39 | enum radio_path rfpath, u32 offset); | ||
40 | static void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, | ||
41 | enum radio_path rfpath, u32 offset, | ||
42 | u32 data); | ||
43 | static u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask); | ||
44 | static bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw); | ||
45 | static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); | ||
46 | static bool _rtl92c_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, | ||
47 | u8 configtype); | ||
48 | static bool _rtl92c_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, | ||
49 | u8 configtype); | ||
50 | static void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw); | ||
51 | static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, | ||
52 | u32 cmdtableidx, u32 cmdtablesz, | ||
53 | enum swchnlcmd_id cmdid, u32 para1, | ||
54 | u32 para2, u32 msdelay); | ||
55 | static bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, | ||
56 | u8 channel, u8 *stage, u8 *step, | ||
57 | u32 *delay); | ||
58 | static u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw, | ||
59 | enum wireless_mode wirelessmode, | ||
60 | long power_indbm); | ||
61 | static bool _rtl92c_phy_config_rf_external_pa(struct ieee80211_hw *hw, | ||
62 | enum radio_path rfpath); | ||
63 | static long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, | ||
64 | enum wireless_mode wirelessmode, | ||
65 | u8 txpwridx); | ||
66 | static void _rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t); | ||
67 | |||
68 | u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) | ||
69 | { | ||
70 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
71 | u32 returnvalue, originalvalue, bitshift; | ||
72 | |||
73 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " | ||
74 | "bitmask(%#x)\n", regaddr, | ||
75 | bitmask)); | ||
76 | originalvalue = rtl_read_dword(rtlpriv, regaddr); | ||
77 | bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); | ||
78 | returnvalue = (originalvalue & bitmask) >> bitshift; | ||
79 | |||
80 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("BBR MASK=0x%x " | ||
81 | "Addr[0x%x]=0x%x\n", bitmask, | ||
82 | regaddr, originalvalue)); | ||
83 | |||
84 | return returnvalue; | ||
85 | |||
86 | } | ||
87 | |||
88 | void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, | ||
89 | u32 regaddr, u32 bitmask, u32 data) | ||
90 | { | ||
91 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
92 | u32 originalvalue, bitshift; | ||
93 | |||
94 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," | ||
95 | " data(%#x)\n", regaddr, bitmask, | ||
96 | data)); | ||
97 | |||
98 | if (bitmask != MASKDWORD) { | ||
99 | originalvalue = rtl_read_dword(rtlpriv, regaddr); | ||
100 | bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); | ||
101 | data = ((originalvalue & (~bitmask)) | (data << bitshift)); | ||
102 | } | ||
103 | |||
104 | rtl_write_dword(rtlpriv, regaddr, data); | ||
105 | |||
106 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," | ||
107 | " data(%#x)\n", regaddr, bitmask, | ||
108 | data)); | ||
109 | |||
110 | } | ||
111 | |||
112 | static u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, | ||
113 | enum radio_path rfpath, u32 offset) | ||
114 | { | ||
115 | RT_ASSERT(false, ("deprecated!\n")); | ||
116 | return 0; | ||
117 | } | ||
118 | |||
119 | static void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, | ||
120 | enum radio_path rfpath, u32 offset, | ||
121 | u32 data) | ||
122 | { | ||
123 | RT_ASSERT(false, ("deprecated!\n")); | ||
124 | } | ||
125 | |||
126 | static u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, | ||
127 | enum radio_path rfpath, u32 offset) | ||
128 | { | ||
129 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
130 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
131 | struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; | ||
132 | u32 newoffset; | ||
133 | u32 tmplong, tmplong2; | ||
134 | u8 rfpi_enable = 0; | ||
135 | u32 retvalue; | ||
136 | |||
137 | offset &= 0x3f; | ||
138 | newoffset = offset; | ||
139 | if (RT_CANNOT_IO(hw)) { | ||
140 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("return all one\n")); | ||
141 | return 0xFFFFFFFF; | ||
142 | } | ||
143 | tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD); | ||
144 | if (rfpath == RF90_PATH_A) | ||
145 | tmplong2 = tmplong; | ||
146 | else | ||
147 | tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD); | ||
148 | tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) | | ||
149 | (newoffset << 23) | BLSSIREADEDGE; | ||
150 | rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, | ||
151 | tmplong & (~BLSSIREADEDGE)); | ||
152 | mdelay(1); | ||
153 | rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2); | ||
154 | mdelay(1); | ||
155 | rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, | ||
156 | tmplong | BLSSIREADEDGE); | ||
157 | mdelay(1); | ||
158 | if (rfpath == RF90_PATH_A) | ||
159 | rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1, | ||
160 | BIT(8)); | ||
161 | else if (rfpath == RF90_PATH_B) | ||
162 | rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1, | ||
163 | BIT(8)); | ||
164 | if (rfpi_enable) | ||
165 | retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readbackpi, | ||
166 | BLSSIREADBACKDATA); | ||
167 | else | ||
168 | retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback, | ||
169 | BLSSIREADBACKDATA); | ||
170 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFR-%d Addr[0x%x]=0x%x\n", | ||
171 | rfpath, pphyreg->rflssi_readback, | ||
172 | retvalue)); | ||
173 | return retvalue; | ||
174 | } | ||
175 | |||
176 | static void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, | ||
177 | enum radio_path rfpath, u32 offset, | ||
178 | u32 data) | ||
179 | { | ||
180 | u32 data_and_addr; | ||
181 | u32 newoffset; | ||
182 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
183 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
184 | struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; | ||
185 | |||
186 | if (RT_CANNOT_IO(hw)) { | ||
187 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("stop\n")); | ||
188 | return; | ||
189 | } | ||
190 | offset &= 0x3f; | ||
191 | newoffset = offset; | ||
192 | data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff; | ||
193 | rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr); | ||
194 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFW-%d Addr[0x%x]=0x%x\n", | ||
195 | rfpath, pphyreg->rf3wire_offset, | ||
196 | data_and_addr)); | ||
197 | } | ||
198 | |||
199 | static u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask) | ||
200 | { | ||
201 | u32 i; | ||
202 | |||
203 | for (i = 0; i <= 31; i++) { | ||
204 | if (((bitmask >> i) & 0x1) == 1) | ||
205 | break; | ||
206 | } | ||
207 | return i; | ||
208 | } | ||
209 | |||
210 | static void _rtl92c_phy_bb_config_1t(struct ieee80211_hw *hw) | ||
211 | { | ||
212 | rtl_set_bbreg(hw, RFPGA0_TXINFO, 0x3, 0x2); | ||
213 | rtl_set_bbreg(hw, RFPGA1_TXINFO, 0x300033, 0x200022); | ||
214 | rtl_set_bbreg(hw, RCCK0_AFESETTING, MASKBYTE3, 0x45); | ||
215 | rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x23); | ||
216 | rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, 0x30, 0x1); | ||
217 | rtl_set_bbreg(hw, 0xe74, 0x0c000000, 0x2); | ||
218 | rtl_set_bbreg(hw, 0xe78, 0x0c000000, 0x2); | ||
219 | rtl_set_bbreg(hw, 0xe7c, 0x0c000000, 0x2); | ||
220 | rtl_set_bbreg(hw, 0xe80, 0x0c000000, 0x2); | ||
221 | rtl_set_bbreg(hw, 0xe88, 0x0c000000, 0x2); | ||
222 | } | ||
223 | bool rtl92c_phy_rf_config(struct ieee80211_hw *hw) | ||
224 | { | ||
225 | return rtl92c_phy_rf6052_config(hw); | ||
226 | } | ||
227 | |||
228 | static bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw) | ||
229 | { | ||
230 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
231 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
232 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
233 | bool rtstatus; | ||
234 | |||
235 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("==>\n")); | ||
236 | rtstatus = _rtl92c_phy_config_bb_with_headerfile(hw, | ||
237 | BASEBAND_CONFIG_PHY_REG); | ||
238 | if (rtstatus != true) { | ||
239 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Write BB Reg Fail!!")); | ||
240 | return false; | ||
241 | } | ||
242 | if (rtlphy->rf_type == RF_1T2R) { | ||
243 | _rtl92c_phy_bb_config_1t(hw); | ||
244 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Config to 1T!!\n")); | ||
245 | } | ||
246 | if (rtlefuse->autoload_failflag == false) { | ||
247 | rtlphy->pwrgroup_cnt = 0; | ||
248 | rtstatus = _rtl92c_phy_config_bb_with_pgheaderfile(hw, | ||
249 | BASEBAND_CONFIG_PHY_REG); | ||
250 | } | ||
251 | if (rtstatus != true) { | ||
252 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("BB_PG Reg Fail!!")); | ||
253 | return false; | ||
254 | } | ||
255 | rtstatus = _rtl92c_phy_config_bb_with_headerfile(hw, | ||
256 | BASEBAND_CONFIG_AGC_TAB); | ||
257 | if (rtstatus != true) { | ||
258 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("AGC Table Fail\n")); | ||
259 | return false; | ||
260 | } | ||
261 | rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw, | ||
262 | RFPGA0_XA_HSSIPARAMETER2, | ||
263 | 0x200)); | ||
264 | return true; | ||
265 | } | ||
266 | |||
267 | |||
268 | void rtl92c_phy_config_bb_external_pa(struct ieee80211_hw *hw) | ||
269 | { | ||
270 | } | ||
271 | |||
272 | static void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw, | ||
273 | u32 regaddr, u32 bitmask, | ||
274 | u32 data) | ||
275 | { | ||
276 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
277 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
278 | |||
279 | if (regaddr == RTXAGC_A_RATE18_06) { | ||
280 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][0] = data; | ||
281 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
282 | ("MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n", | ||
283 | rtlphy->pwrgroup_cnt, | ||
284 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][0])); | ||
285 | } | ||
286 | if (regaddr == RTXAGC_A_RATE54_24) { | ||
287 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][1] = data; | ||
288 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
289 | ("MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n", | ||
290 | rtlphy->pwrgroup_cnt, | ||
291 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][1])); | ||
292 | } | ||
293 | if (regaddr == RTXAGC_A_CCK1_MCS32) { | ||
294 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][6] = data; | ||
295 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
296 | ("MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n", | ||
297 | rtlphy->pwrgroup_cnt, | ||
298 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][6])); | ||
299 | } | ||
300 | if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) { | ||
301 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][7] = data; | ||
302 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
303 | ("MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n", | ||
304 | rtlphy->pwrgroup_cnt, | ||
305 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][7])); | ||
306 | } | ||
307 | if (regaddr == RTXAGC_A_MCS03_MCS00) { | ||
308 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][2] = data; | ||
309 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
310 | ("MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n", | ||
311 | rtlphy->pwrgroup_cnt, | ||
312 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][2])); | ||
313 | } | ||
314 | if (regaddr == RTXAGC_A_MCS07_MCS04) { | ||
315 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][3] = data; | ||
316 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
317 | ("MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n", | ||
318 | rtlphy->pwrgroup_cnt, | ||
319 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][3])); | ||
320 | } | ||
321 | if (regaddr == RTXAGC_A_MCS11_MCS08) { | ||
322 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][4] = data; | ||
323 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
324 | ("MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n", | ||
325 | rtlphy->pwrgroup_cnt, | ||
326 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][4])); | ||
327 | } | ||
328 | if (regaddr == RTXAGC_A_MCS15_MCS12) { | ||
329 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][5] = data; | ||
330 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
331 | ("MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n", | ||
332 | rtlphy->pwrgroup_cnt, | ||
333 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][5])); | ||
334 | } | ||
335 | if (regaddr == RTXAGC_B_RATE18_06) { | ||
336 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][8] = data; | ||
337 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
338 | ("MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n", | ||
339 | rtlphy->pwrgroup_cnt, | ||
340 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][8])); | ||
341 | } | ||
342 | if (regaddr == RTXAGC_B_RATE54_24) { | ||
343 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9] = data; | ||
344 | |||
345 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
346 | ("MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n", | ||
347 | rtlphy->pwrgroup_cnt, | ||
348 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9])); | ||
349 | } | ||
350 | |||
351 | if (regaddr == RTXAGC_B_CCK1_55_MCS32) { | ||
352 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14] = data; | ||
353 | |||
354 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
355 | ("MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n", | ||
356 | rtlphy->pwrgroup_cnt, | ||
357 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14])); | ||
358 | } | ||
359 | |||
360 | if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) { | ||
361 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15] = data; | ||
362 | |||
363 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
364 | ("MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n", | ||
365 | rtlphy->pwrgroup_cnt, | ||
366 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15])); | ||
367 | } | ||
368 | |||
369 | if (regaddr == RTXAGC_B_MCS03_MCS00) { | ||
370 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10] = data; | ||
371 | |||
372 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
373 | ("MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n", | ||
374 | rtlphy->pwrgroup_cnt, | ||
375 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10])); | ||
376 | } | ||
377 | |||
378 | if (regaddr == RTXAGC_B_MCS07_MCS04) { | ||
379 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11] = data; | ||
380 | |||
381 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
382 | ("MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n", | ||
383 | rtlphy->pwrgroup_cnt, | ||
384 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11])); | ||
385 | } | ||
386 | |||
387 | if (regaddr == RTXAGC_B_MCS11_MCS08) { | ||
388 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12] = data; | ||
389 | |||
390 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
391 | ("MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n", | ||
392 | rtlphy->pwrgroup_cnt, | ||
393 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12])); | ||
394 | } | ||
395 | |||
396 | if (regaddr == RTXAGC_B_MCS15_MCS12) { | ||
397 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][13] = data; | ||
398 | |||
399 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
400 | ("MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n", | ||
401 | rtlphy->pwrgroup_cnt, | ||
402 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][13])); | ||
403 | |||
404 | rtlphy->pwrgroup_cnt++; | ||
405 | } | ||
406 | } | ||
407 | |||
408 | static bool _rtl92c_phy_config_rf_external_pa(struct ieee80211_hw *hw, | ||
409 | enum radio_path rfpath) | ||
410 | { | ||
411 | return true; | ||
412 | } | ||
413 | |||
414 | void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) | ||
415 | { | ||
416 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
417 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
418 | |||
419 | rtlphy->default_initialgain[0] = | ||
420 | (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0); | ||
421 | rtlphy->default_initialgain[1] = | ||
422 | (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0); | ||
423 | rtlphy->default_initialgain[2] = | ||
424 | (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0); | ||
425 | rtlphy->default_initialgain[3] = | ||
426 | (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0); | ||
427 | |||
428 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
429 | ("Default initial gain (c50=0x%x, " | ||
430 | "c58=0x%x, c60=0x%x, c68=0x%x\n", | ||
431 | rtlphy->default_initialgain[0], | ||
432 | rtlphy->default_initialgain[1], | ||
433 | rtlphy->default_initialgain[2], | ||
434 | rtlphy->default_initialgain[3])); | ||
435 | |||
436 | rtlphy->framesync = (u8) rtl_get_bbreg(hw, | ||
437 | ROFDM0_RXDETECTOR3, MASKBYTE0); | ||
438 | rtlphy->framesync_c34 = rtl_get_bbreg(hw, | ||
439 | ROFDM0_RXDETECTOR2, MASKDWORD); | ||
440 | |||
441 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
442 | ("Default framesync (0x%x) = 0x%x\n", | ||
443 | ROFDM0_RXDETECTOR3, rtlphy->framesync)); | ||
444 | } | ||
445 | |||
446 | static void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) | ||
447 | { | ||
448 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
449 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
450 | |||
451 | rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW; | ||
452 | rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW; | ||
453 | rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW; | ||
454 | rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW; | ||
455 | |||
456 | rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB; | ||
457 | rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB; | ||
458 | rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB; | ||
459 | rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB; | ||
460 | |||
461 | rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE; | ||
462 | rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE; | ||
463 | |||
464 | rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE; | ||
465 | rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE; | ||
466 | |||
467 | rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = | ||
468 | RFPGA0_XA_LSSIPARAMETER; | ||
469 | rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = | ||
470 | RFPGA0_XB_LSSIPARAMETER; | ||
471 | |||
472 | rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = rFPGA0_XAB_RFPARAMETER; | ||
473 | rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = rFPGA0_XAB_RFPARAMETER; | ||
474 | rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = rFPGA0_XCD_RFPARAMETER; | ||
475 | rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = rFPGA0_XCD_RFPARAMETER; | ||
476 | |||
477 | rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE; | ||
478 | rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE; | ||
479 | rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE; | ||
480 | rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE; | ||
481 | |||
482 | rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1; | ||
483 | rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1; | ||
484 | |||
485 | rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2; | ||
486 | rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2; | ||
487 | |||
488 | rtlphy->phyreg_def[RF90_PATH_A].rfswitch_control = | ||
489 | RFPGA0_XAB_SWITCHCONTROL; | ||
490 | rtlphy->phyreg_def[RF90_PATH_B].rfswitch_control = | ||
491 | RFPGA0_XAB_SWITCHCONTROL; | ||
492 | rtlphy->phyreg_def[RF90_PATH_C].rfswitch_control = | ||
493 | RFPGA0_XCD_SWITCHCONTROL; | ||
494 | rtlphy->phyreg_def[RF90_PATH_D].rfswitch_control = | ||
495 | RFPGA0_XCD_SWITCHCONTROL; | ||
496 | |||
497 | rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1; | ||
498 | rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1; | ||
499 | rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1; | ||
500 | rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1; | ||
501 | |||
502 | rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2; | ||
503 | rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2; | ||
504 | rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2; | ||
505 | rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2; | ||
506 | |||
507 | rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbalance = | ||
508 | ROFDM0_XARXIQIMBALANCE; | ||
509 | rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbalance = | ||
510 | ROFDM0_XBRXIQIMBALANCE; | ||
511 | rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbalance = | ||
512 | ROFDM0_XCRXIQIMBANLANCE; | ||
513 | rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbalance = | ||
514 | ROFDM0_XDRXIQIMBALANCE; | ||
515 | |||
516 | rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE; | ||
517 | rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE; | ||
518 | rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE; | ||
519 | rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE; | ||
520 | |||
521 | rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbalance = | ||
522 | ROFDM0_XATXIQIMBALANCE; | ||
523 | rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbalance = | ||
524 | ROFDM0_XBTXIQIMBALANCE; | ||
525 | rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbalance = | ||
526 | ROFDM0_XCTXIQIMBALANCE; | ||
527 | rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbalance = | ||
528 | ROFDM0_XDTXIQIMBALANCE; | ||
529 | |||
530 | rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE; | ||
531 | rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE; | ||
532 | rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE; | ||
533 | rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE; | ||
534 | |||
535 | rtlphy->phyreg_def[RF90_PATH_A].rflssi_readback = | ||
536 | RFPGA0_XA_LSSIREADBACK; | ||
537 | rtlphy->phyreg_def[RF90_PATH_B].rflssi_readback = | ||
538 | RFPGA0_XB_LSSIREADBACK; | ||
539 | rtlphy->phyreg_def[RF90_PATH_C].rflssi_readback = | ||
540 | RFPGA0_XC_LSSIREADBACK; | ||
541 | rtlphy->phyreg_def[RF90_PATH_D].rflssi_readback = | ||
542 | RFPGA0_XD_LSSIREADBACK; | ||
543 | |||
544 | rtlphy->phyreg_def[RF90_PATH_A].rflssi_readbackpi = | ||
545 | TRANSCEIVEA_HSPI_READBACK; | ||
546 | rtlphy->phyreg_def[RF90_PATH_B].rflssi_readbackpi = | ||
547 | TRANSCEIVEB_HSPI_READBACK; | ||
548 | |||
549 | } | ||
550 | |||
551 | void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel) | ||
552 | { | ||
553 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
554 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
555 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
556 | u8 txpwr_level; | ||
557 | long txpwr_dbm; | ||
558 | |||
559 | txpwr_level = rtlphy->cur_cck_txpwridx; | ||
560 | txpwr_dbm = _rtl92c_phy_txpwr_idx_to_dbm(hw, | ||
561 | WIRELESS_MODE_B, txpwr_level); | ||
562 | txpwr_level = rtlphy->cur_ofdm24g_txpwridx + | ||
563 | rtlefuse->legacy_ht_txpowerdiff; | ||
564 | if (_rtl92c_phy_txpwr_idx_to_dbm(hw, | ||
565 | WIRELESS_MODE_G, | ||
566 | txpwr_level) > txpwr_dbm) | ||
567 | txpwr_dbm = | ||
568 | _rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, | ||
569 | txpwr_level); | ||
570 | txpwr_level = rtlphy->cur_ofdm24g_txpwridx; | ||
571 | if (_rtl92c_phy_txpwr_idx_to_dbm(hw, | ||
572 | WIRELESS_MODE_N_24G, | ||
573 | txpwr_level) > txpwr_dbm) | ||
574 | txpwr_dbm = | ||
575 | _rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G, | ||
576 | txpwr_level); | ||
577 | *powerlevel = txpwr_dbm; | ||
578 | } | ||
579 | |||
580 | static void _rtl92c_get_txpower_index(struct ieee80211_hw *hw, u8 channel, | ||
581 | u8 *cckpowerlevel, u8 *ofdmpowerlevel) | ||
582 | { | ||
583 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
584 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
585 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
586 | u8 index = (channel - 1); | ||
587 | |||
588 | cckpowerlevel[RF90_PATH_A] = | ||
589 | rtlefuse->txpwrlevel_cck[RF90_PATH_A][index]; | ||
590 | cckpowerlevel[RF90_PATH_B] = | ||
591 | rtlefuse->txpwrlevel_cck[RF90_PATH_B][index]; | ||
592 | if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_1T1R) { | ||
593 | ofdmpowerlevel[RF90_PATH_A] = | ||
594 | rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index]; | ||
595 | ofdmpowerlevel[RF90_PATH_B] = | ||
596 | rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index]; | ||
597 | } else if (get_rf_type(rtlphy) == RF_2T2R) { | ||
598 | ofdmpowerlevel[RF90_PATH_A] = | ||
599 | rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_A][index]; | ||
600 | ofdmpowerlevel[RF90_PATH_B] = | ||
601 | rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_B][index]; | ||
602 | } | ||
603 | } | ||
604 | |||
605 | static void _rtl92c_ccxpower_index_check(struct ieee80211_hw *hw, | ||
606 | u8 channel, u8 *cckpowerlevel, | ||
607 | u8 *ofdmpowerlevel) | ||
608 | { | ||
609 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
610 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
611 | |||
612 | rtlphy->cur_cck_txpwridx = cckpowerlevel[0]; | ||
613 | rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0]; | ||
614 | } | ||
615 | |||
616 | void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel) | ||
617 | { | ||
618 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
619 | u8 cckpowerlevel[2], ofdmpowerlevel[2]; | ||
620 | |||
621 | if (rtlefuse->txpwr_fromeprom == false) | ||
622 | return; | ||
623 | _rtl92c_get_txpower_index(hw, channel, | ||
624 | &cckpowerlevel[0], &ofdmpowerlevel[0]); | ||
625 | _rtl92c_ccxpower_index_check(hw, | ||
626 | channel, &cckpowerlevel[0], | ||
627 | &ofdmpowerlevel[0]); | ||
628 | rtl92c_phy_rf6052_set_cck_txpower(hw, &cckpowerlevel[0]); | ||
629 | rtl92c_phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0], channel); | ||
630 | } | ||
631 | |||
632 | bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm) | ||
633 | { | ||
634 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
635 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
636 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
637 | u8 idx; | ||
638 | u8 rf_path; | ||
639 | |||
640 | u8 ccktxpwridx = _rtl92c_phy_dbm_to_txpwr_Idx(hw, | ||
641 | WIRELESS_MODE_B, | ||
642 | power_indbm); | ||
643 | u8 ofdmtxpwridx = _rtl92c_phy_dbm_to_txpwr_Idx(hw, | ||
644 | WIRELESS_MODE_N_24G, | ||
645 | power_indbm); | ||
646 | if (ofdmtxpwridx - rtlefuse->legacy_ht_txpowerdiff > 0) | ||
647 | ofdmtxpwridx -= rtlefuse->legacy_ht_txpowerdiff; | ||
648 | else | ||
649 | ofdmtxpwridx = 0; | ||
650 | RT_TRACE(rtlpriv, COMP_TXAGC, DBG_TRACE, | ||
651 | ("%lx dBm, ccktxpwridx = %d, ofdmtxpwridx = %d\n", | ||
652 | power_indbm, ccktxpwridx, ofdmtxpwridx)); | ||
653 | for (idx = 0; idx < 14; idx++) { | ||
654 | for (rf_path = 0; rf_path < 2; rf_path++) { | ||
655 | rtlefuse->txpwrlevel_cck[rf_path][idx] = ccktxpwridx; | ||
656 | rtlefuse->txpwrlevel_ht40_1s[rf_path][idx] = | ||
657 | ofdmtxpwridx; | ||
658 | rtlefuse->txpwrlevel_ht40_2s[rf_path][idx] = | ||
659 | ofdmtxpwridx; | ||
660 | } | ||
661 | } | ||
662 | rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); | ||
663 | return true; | ||
664 | } | ||
665 | |||
666 | void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw, u16 beaconinterval) | ||
667 | { | ||
668 | } | ||
669 | |||
670 | static u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw, | ||
671 | enum wireless_mode wirelessmode, | ||
672 | long power_indbm) | ||
673 | { | ||
674 | u8 txpwridx; | ||
675 | long offset; | ||
676 | |||
677 | switch (wirelessmode) { | ||
678 | case WIRELESS_MODE_B: | ||
679 | offset = -7; | ||
680 | break; | ||
681 | case WIRELESS_MODE_G: | ||
682 | case WIRELESS_MODE_N_24G: | ||
683 | offset = -8; | ||
684 | break; | ||
685 | default: | ||
686 | offset = -8; | ||
687 | break; | ||
688 | } | ||
689 | |||
690 | if ((power_indbm - offset) > 0) | ||
691 | txpwridx = (u8) ((power_indbm - offset) * 2); | ||
692 | else | ||
693 | txpwridx = 0; | ||
694 | |||
695 | if (txpwridx > MAX_TXPWR_IDX_NMODE_92S) | ||
696 | txpwridx = MAX_TXPWR_IDX_NMODE_92S; | ||
697 | |||
698 | return txpwridx; | ||
699 | } | ||
700 | |||
701 | static long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, | ||
702 | enum wireless_mode wirelessmode, | ||
703 | u8 txpwridx) | ||
704 | { | ||
705 | long offset; | ||
706 | long pwrout_dbm; | ||
707 | |||
708 | switch (wirelessmode) { | ||
709 | case WIRELESS_MODE_B: | ||
710 | offset = -7; | ||
711 | break; | ||
712 | case WIRELESS_MODE_G: | ||
713 | case WIRELESS_MODE_N_24G: | ||
714 | offset = -8; | ||
715 | break; | ||
716 | default: | ||
717 | offset = -8; | ||
718 | break; | ||
719 | } | ||
720 | pwrout_dbm = txpwridx / 2 + offset; | ||
721 | return pwrout_dbm; | ||
722 | } | ||
723 | |||
724 | void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) | ||
725 | { | ||
726 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
727 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
728 | enum io_type iotype; | ||
729 | |||
730 | if (!is_hal_stop(rtlhal)) { | ||
731 | switch (operation) { | ||
732 | case SCAN_OPT_BACKUP: | ||
733 | iotype = IO_CMD_PAUSE_DM_BY_SCAN; | ||
734 | rtlpriv->cfg->ops->set_hw_reg(hw, | ||
735 | HW_VAR_IO_CMD, | ||
736 | (u8 *)&iotype); | ||
737 | |||
738 | break; | ||
739 | case SCAN_OPT_RESTORE: | ||
740 | iotype = IO_CMD_RESUME_DM_BY_SCAN; | ||
741 | rtlpriv->cfg->ops->set_hw_reg(hw, | ||
742 | HW_VAR_IO_CMD, | ||
743 | (u8 *)&iotype); | ||
744 | break; | ||
745 | default: | ||
746 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
747 | ("Unknown Scan Backup operation.\n")); | ||
748 | break; | ||
749 | } | ||
750 | } | ||
751 | } | ||
752 | |||
753 | void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw, | ||
754 | enum nl80211_channel_type ch_type) | ||
755 | { | ||
756 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
757 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
758 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
759 | u8 tmp_bw = rtlphy->current_chan_bw; | ||
760 | |||
761 | if (rtlphy->set_bwmode_inprogress) | ||
762 | return; | ||
763 | rtlphy->set_bwmode_inprogress = true; | ||
764 | if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) | ||
765 | rtl92c_phy_set_bw_mode_callback(hw); | ||
766 | else { | ||
767 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, | ||
768 | ("FALSE driver sleep or unload\n")); | ||
769 | rtlphy->set_bwmode_inprogress = false; | ||
770 | rtlphy->current_chan_bw = tmp_bw; | ||
771 | } | ||
772 | } | ||
773 | |||
774 | void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw) | ||
775 | { | ||
776 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
777 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
778 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
779 | u32 delay; | ||
780 | |||
781 | RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, | ||
782 | ("switch to channel%d\n", rtlphy->current_channel)); | ||
783 | if (is_hal_stop(rtlhal)) | ||
784 | return; | ||
785 | do { | ||
786 | if (!rtlphy->sw_chnl_inprogress) | ||
787 | break; | ||
788 | if (!_rtl92c_phy_sw_chnl_step_by_step | ||
789 | (hw, rtlphy->current_channel, &rtlphy->sw_chnl_stage, | ||
790 | &rtlphy->sw_chnl_step, &delay)) { | ||
791 | if (delay > 0) | ||
792 | mdelay(delay); | ||
793 | else | ||
794 | continue; | ||
795 | } else | ||
796 | rtlphy->sw_chnl_inprogress = false; | ||
797 | break; | ||
798 | } while (true); | ||
799 | RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); | ||
800 | } | ||
801 | |||
802 | u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw) | ||
803 | { | ||
804 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
805 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
806 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
807 | |||
808 | if (rtlphy->sw_chnl_inprogress) | ||
809 | return 0; | ||
810 | if (rtlphy->set_bwmode_inprogress) | ||
811 | return 0; | ||
812 | RT_ASSERT((rtlphy->current_channel <= 14), | ||
813 | ("WIRELESS_MODE_G but channel>14")); | ||
814 | rtlphy->sw_chnl_inprogress = true; | ||
815 | rtlphy->sw_chnl_stage = 0; | ||
816 | rtlphy->sw_chnl_step = 0; | ||
817 | if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { | ||
818 | rtl92c_phy_sw_chnl_callback(hw); | ||
819 | RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, | ||
820 | ("sw_chnl_inprogress false schdule workitem\n")); | ||
821 | rtlphy->sw_chnl_inprogress = false; | ||
822 | } else { | ||
823 | RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, | ||
824 | ("sw_chnl_inprogress false driver sleep or" | ||
825 | " unload\n")); | ||
826 | rtlphy->sw_chnl_inprogress = false; | ||
827 | } | ||
828 | return 1; | ||
829 | } | ||
830 | |||
831 | static bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, | ||
832 | u8 channel, u8 *stage, u8 *step, | ||
833 | u32 *delay) | ||
834 | { | ||
835 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
836 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
837 | struct swchnlcmd precommoncmd[MAX_PRECMD_CNT]; | ||
838 | u32 precommoncmdcnt; | ||
839 | struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT]; | ||
840 | u32 postcommoncmdcnt; | ||
841 | struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT]; | ||
842 | u32 rfdependcmdcnt; | ||
843 | struct swchnlcmd *currentcmd = NULL; | ||
844 | u8 rfpath; | ||
845 | u8 num_total_rfpath = rtlphy->num_total_rfpath; | ||
846 | |||
847 | precommoncmdcnt = 0; | ||
848 | _rtl92c_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, | ||
849 | MAX_PRECMD_CNT, | ||
850 | CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0); | ||
851 | _rtl92c_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, | ||
852 | MAX_PRECMD_CNT, CMDID_END, 0, 0, 0); | ||
853 | |||
854 | postcommoncmdcnt = 0; | ||
855 | |||
856 | _rtl92c_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++, | ||
857 | MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0); | ||
858 | |||
859 | rfdependcmdcnt = 0; | ||
860 | |||
861 | RT_ASSERT((channel >= 1 && channel <= 14), | ||
862 | ("illegal channel for Zebra: %d\n", channel)); | ||
863 | |||
864 | _rtl92c_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, | ||
865 | MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG, | ||
866 | RF_CHNLBW, channel, 10); | ||
867 | |||
868 | _rtl92c_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, | ||
869 | MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0, | ||
870 | 0); | ||
871 | |||
872 | do { | ||
873 | switch (*stage) { | ||
874 | case 0: | ||
875 | currentcmd = &precommoncmd[*step]; | ||
876 | break; | ||
877 | case 1: | ||
878 | currentcmd = &rfdependcmd[*step]; | ||
879 | break; | ||
880 | case 2: | ||
881 | currentcmd = &postcommoncmd[*step]; | ||
882 | break; | ||
883 | } | ||
884 | |||
885 | if (currentcmd->cmdid == CMDID_END) { | ||
886 | if ((*stage) == 2) { | ||
887 | return true; | ||
888 | } else { | ||
889 | (*stage)++; | ||
890 | (*step) = 0; | ||
891 | continue; | ||
892 | } | ||
893 | } | ||
894 | |||
895 | switch (currentcmd->cmdid) { | ||
896 | case CMDID_SET_TXPOWEROWER_LEVEL: | ||
897 | rtl92c_phy_set_txpower_level(hw, channel); | ||
898 | break; | ||
899 | case CMDID_WRITEPORT_ULONG: | ||
900 | rtl_write_dword(rtlpriv, currentcmd->para1, | ||
901 | currentcmd->para2); | ||
902 | break; | ||
903 | case CMDID_WRITEPORT_USHORT: | ||
904 | rtl_write_word(rtlpriv, currentcmd->para1, | ||
905 | (u16) currentcmd->para2); | ||
906 | break; | ||
907 | case CMDID_WRITEPORT_UCHAR: | ||
908 | rtl_write_byte(rtlpriv, currentcmd->para1, | ||
909 | (u8) currentcmd->para2); | ||
910 | break; | ||
911 | case CMDID_RF_WRITEREG: | ||
912 | for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) { | ||
913 | rtlphy->rfreg_chnlval[rfpath] = | ||
914 | ((rtlphy->rfreg_chnlval[rfpath] & | ||
915 | 0xfffffc00) | currentcmd->para2); | ||
916 | |||
917 | rtl_set_rfreg(hw, (enum radio_path)rfpath, | ||
918 | currentcmd->para1, | ||
919 | RFREG_OFFSET_MASK, | ||
920 | rtlphy->rfreg_chnlval[rfpath]); | ||
921 | } | ||
922 | break; | ||
923 | default: | ||
924 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
925 | ("switch case not process\n")); | ||
926 | break; | ||
927 | } | ||
928 | |||
929 | break; | ||
930 | } while (true); | ||
931 | |||
932 | (*delay) = currentcmd->msdelay; | ||
933 | (*step)++; | ||
934 | return false; | ||
935 | } | ||
936 | |||
937 | static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, | ||
938 | u32 cmdtableidx, u32 cmdtablesz, | ||
939 | enum swchnlcmd_id cmdid, | ||
940 | u32 para1, u32 para2, u32 msdelay) | ||
941 | { | ||
942 | struct swchnlcmd *pcmd; | ||
943 | |||
944 | if (cmdtable == NULL) { | ||
945 | RT_ASSERT(false, ("cmdtable cannot be NULL.\n")); | ||
946 | return false; | ||
947 | } | ||
948 | |||
949 | if (cmdtableidx >= cmdtablesz) | ||
950 | return false; | ||
951 | |||
952 | pcmd = cmdtable + cmdtableidx; | ||
953 | pcmd->cmdid = cmdid; | ||
954 | pcmd->para1 = para1; | ||
955 | pcmd->para2 = para2; | ||
956 | pcmd->msdelay = msdelay; | ||
957 | return true; | ||
958 | } | ||
959 | |||
960 | bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, u32 rfpath) | ||
961 | { | ||
962 | return true; | ||
963 | } | ||
964 | |||
965 | static u8 _rtl92c_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb) | ||
966 | { | ||
967 | u32 reg_eac, reg_e94, reg_e9c, reg_ea4; | ||
968 | u8 result = 0x00; | ||
969 | |||
970 | rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1f); | ||
971 | rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x10008c1f); | ||
972 | rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x82140102); | ||
973 | rtl_set_bbreg(hw, 0xe3c, MASKDWORD, | ||
974 | config_pathb ? 0x28160202 : 0x28160502); | ||
975 | |||
976 | if (config_pathb) { | ||
977 | rtl_set_bbreg(hw, 0xe50, MASKDWORD, 0x10008c22); | ||
978 | rtl_set_bbreg(hw, 0xe54, MASKDWORD, 0x10008c22); | ||
979 | rtl_set_bbreg(hw, 0xe58, MASKDWORD, 0x82140102); | ||
980 | rtl_set_bbreg(hw, 0xe5c, MASKDWORD, 0x28160202); | ||
981 | } | ||
982 | |||
983 | rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x001028d1); | ||
984 | rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000); | ||
985 | rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000); | ||
986 | |||
987 | mdelay(IQK_DELAY_TIME); | ||
988 | |||
989 | reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); | ||
990 | reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD); | ||
991 | reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD); | ||
992 | reg_ea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD); | ||
993 | |||
994 | if (!(reg_eac & BIT(28)) && | ||
995 | (((reg_e94 & 0x03FF0000) >> 16) != 0x142) && | ||
996 | (((reg_e9c & 0x03FF0000) >> 16) != 0x42)) | ||
997 | result |= 0x01; | ||
998 | else | ||
999 | return result; | ||
1000 | |||
1001 | if (!(reg_eac & BIT(27)) && | ||
1002 | (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) && | ||
1003 | (((reg_eac & 0x03FF0000) >> 16) != 0x36)) | ||
1004 | result |= 0x02; | ||
1005 | return result; | ||
1006 | } | ||
1007 | |||
1008 | static u8 _rtl92c_phy_path_b_iqk(struct ieee80211_hw *hw) | ||
1009 | { | ||
1010 | u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc; | ||
1011 | u8 result = 0x00; | ||
1012 | |||
1013 | rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000002); | ||
1014 | rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000000); | ||
1015 | mdelay(IQK_DELAY_TIME); | ||
1016 | reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); | ||
1017 | reg_eb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD); | ||
1018 | reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD); | ||
1019 | reg_ec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD); | ||
1020 | reg_ecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD); | ||
1021 | if (!(reg_eac & BIT(31)) && | ||
1022 | (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) && | ||
1023 | (((reg_ebc & 0x03FF0000) >> 16) != 0x42)) | ||
1024 | result |= 0x01; | ||
1025 | else | ||
1026 | return result; | ||
1027 | |||
1028 | if (!(reg_eac & BIT(30)) && | ||
1029 | (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) && | ||
1030 | (((reg_ecc & 0x03FF0000) >> 16) != 0x36)) | ||
1031 | result |= 0x02; | ||
1032 | return result; | ||
1033 | } | ||
1034 | |||
1035 | static void _rtl92c_phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw, | ||
1036 | bool iqk_ok, long result[][8], | ||
1037 | u8 final_candidate, bool btxonly) | ||
1038 | { | ||
1039 | u32 oldval_0, x, tx0_a, reg; | ||
1040 | long y, tx0_c; | ||
1041 | |||
1042 | if (final_candidate == 0xFF) | ||
1043 | return; | ||
1044 | else if (iqk_ok) { | ||
1045 | oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, | ||
1046 | MASKDWORD) >> 22) & 0x3FF; | ||
1047 | x = result[final_candidate][0]; | ||
1048 | if ((x & 0x00000200) != 0) | ||
1049 | x = x | 0xFFFFFC00; | ||
1050 | tx0_a = (x * oldval_0) >> 8; | ||
1051 | rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx0_a); | ||
1052 | rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(31), | ||
1053 | ((x * oldval_0 >> 7) & 0x1)); | ||
1054 | y = result[final_candidate][1]; | ||
1055 | if ((y & 0x00000200) != 0) | ||
1056 | y = y | 0xFFFFFC00; | ||
1057 | tx0_c = (y * oldval_0) >> 8; | ||
1058 | rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000, | ||
1059 | ((tx0_c & 0x3C0) >> 6)); | ||
1060 | rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x003F0000, | ||
1061 | (tx0_c & 0x3F)); | ||
1062 | rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(29), | ||
1063 | ((y * oldval_0 >> 7) & 0x1)); | ||
1064 | if (btxonly) | ||
1065 | return; | ||
1066 | reg = result[final_candidate][2]; | ||
1067 | rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg); | ||
1068 | reg = result[final_candidate][3] & 0x3F; | ||
1069 | rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg); | ||
1070 | reg = (result[final_candidate][3] >> 6) & 0xF; | ||
1071 | rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg); | ||
1072 | } | ||
1073 | } | ||
1074 | |||
1075 | static void _rtl92c_phy_path_b_fill_iqk_matrix(struct ieee80211_hw *hw, | ||
1076 | bool iqk_ok, long result[][8], | ||
1077 | u8 final_candidate, bool btxonly) | ||
1078 | { | ||
1079 | u32 oldval_1, x, tx1_a, reg; | ||
1080 | long y, tx1_c; | ||
1081 | |||
1082 | if (final_candidate == 0xFF) | ||
1083 | return; | ||
1084 | else if (iqk_ok) { | ||
1085 | oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, | ||
1086 | MASKDWORD) >> 22) & 0x3FF; | ||
1087 | x = result[final_candidate][4]; | ||
1088 | if ((x & 0x00000200) != 0) | ||
1089 | x = x | 0xFFFFFC00; | ||
1090 | tx1_a = (x * oldval_1) >> 8; | ||
1091 | rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x3FF, tx1_a); | ||
1092 | rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(27), | ||
1093 | ((x * oldval_1 >> 7) & 0x1)); | ||
1094 | y = result[final_candidate][5]; | ||
1095 | if ((y & 0x00000200) != 0) | ||
1096 | y = y | 0xFFFFFC00; | ||
1097 | tx1_c = (y * oldval_1) >> 8; | ||
1098 | rtl_set_bbreg(hw, ROFDM0_XDTXAFE, 0xF0000000, | ||
1099 | ((tx1_c & 0x3C0) >> 6)); | ||
1100 | rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x003F0000, | ||
1101 | (tx1_c & 0x3F)); | ||
1102 | rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(25), | ||
1103 | ((y * oldval_1 >> 7) & 0x1)); | ||
1104 | if (btxonly) | ||
1105 | return; | ||
1106 | reg = result[final_candidate][6]; | ||
1107 | rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg); | ||
1108 | reg = result[final_candidate][7] & 0x3F; | ||
1109 | rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg); | ||
1110 | reg = (result[final_candidate][7] >> 6) & 0xF; | ||
1111 | rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, 0x0000F000, reg); | ||
1112 | } | ||
1113 | } | ||
1114 | |||
1115 | static void _rtl92c_phy_save_adda_registers(struct ieee80211_hw *hw, | ||
1116 | u32 *addareg, u32 *addabackup, | ||
1117 | u32 registernum) | ||
1118 | { | ||
1119 | u32 i; | ||
1120 | |||
1121 | for (i = 0; i < registernum; i++) | ||
1122 | addabackup[i] = rtl_get_bbreg(hw, addareg[i], MASKDWORD); | ||
1123 | } | ||
1124 | |||
1125 | static void _rtl92c_phy_save_mac_registers(struct ieee80211_hw *hw, | ||
1126 | u32 *macreg, u32 *macbackup) | ||
1127 | { | ||
1128 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1129 | u32 i; | ||
1130 | |||
1131 | for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) | ||
1132 | macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]); | ||
1133 | macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]); | ||
1134 | } | ||
1135 | |||
1136 | static void _rtl92c_phy_reload_adda_registers(struct ieee80211_hw *hw, | ||
1137 | u32 *addareg, u32 *addabackup, | ||
1138 | u32 regiesternum) | ||
1139 | { | ||
1140 | u32 i; | ||
1141 | |||
1142 | for (i = 0; i < regiesternum; i++) | ||
1143 | rtl_set_bbreg(hw, addareg[i], MASKDWORD, addabackup[i]); | ||
1144 | } | ||
1145 | |||
1146 | static void _rtl92c_phy_reload_mac_registers(struct ieee80211_hw *hw, | ||
1147 | u32 *macreg, u32 *macbackup) | ||
1148 | { | ||
1149 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1150 | u32 i; | ||
1151 | |||
1152 | for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) | ||
1153 | rtl_write_byte(rtlpriv, macreg[i], (u8) macbackup[i]); | ||
1154 | rtl_write_dword(rtlpriv, macreg[i], macbackup[i]); | ||
1155 | } | ||
1156 | |||
1157 | static void _rtl92c_phy_path_adda_on(struct ieee80211_hw *hw, | ||
1158 | u32 *addareg, bool is_patha_on, bool is2t) | ||
1159 | { | ||
1160 | u32 pathOn; | ||
1161 | u32 i; | ||
1162 | |||
1163 | pathOn = is_patha_on ? 0x04db25a4 : 0x0b1b25a4; | ||
1164 | if (false == is2t) { | ||
1165 | pathOn = 0x0bdb25a0; | ||
1166 | rtl_set_bbreg(hw, addareg[0], MASKDWORD, 0x0b1b25a0); | ||
1167 | } else { | ||
1168 | rtl_set_bbreg(hw, addareg[0], MASKDWORD, pathOn); | ||
1169 | } | ||
1170 | |||
1171 | for (i = 1; i < IQK_ADDA_REG_NUM; i++) | ||
1172 | rtl_set_bbreg(hw, addareg[i], MASKDWORD, pathOn); | ||
1173 | } | ||
1174 | |||
1175 | static void _rtl92c_phy_mac_setting_calibration(struct ieee80211_hw *hw, | ||
1176 | u32 *macreg, u32 *macbackup) | ||
1177 | { | ||
1178 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1179 | u32 i; | ||
1180 | |||
1181 | rtl_write_byte(rtlpriv, macreg[0], 0x3F); | ||
1182 | |||
1183 | for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++) | ||
1184 | rtl_write_byte(rtlpriv, macreg[i], | ||
1185 | (u8) (macbackup[i] & (~BIT(3)))); | ||
1186 | rtl_write_byte(rtlpriv, macreg[i], (u8) (macbackup[i] & (~BIT(5)))); | ||
1187 | } | ||
1188 | |||
1189 | static void _rtl92c_phy_path_a_standby(struct ieee80211_hw *hw) | ||
1190 | { | ||
1191 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0); | ||
1192 | rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000); | ||
1193 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); | ||
1194 | } | ||
1195 | |||
1196 | static void _rtl92c_phy_pi_mode_switch(struct ieee80211_hw *hw, bool pi_mode) | ||
1197 | { | ||
1198 | u32 mode; | ||
1199 | |||
1200 | mode = pi_mode ? 0x01000100 : 0x01000000; | ||
1201 | rtl_set_bbreg(hw, 0x820, MASKDWORD, mode); | ||
1202 | rtl_set_bbreg(hw, 0x828, MASKDWORD, mode); | ||
1203 | } | ||
1204 | |||
1205 | static bool _rtl92c_phy_simularity_compare(struct ieee80211_hw *hw, | ||
1206 | long result[][8], u8 c1, u8 c2) | ||
1207 | { | ||
1208 | u32 i, j, diff, simularity_bitmap, bound; | ||
1209 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1210 | |||
1211 | u8 final_candidate[2] = { 0xFF, 0xFF }; | ||
1212 | bool bresult = true, is2t = IS_92C_SERIAL(rtlhal->version); | ||
1213 | |||
1214 | if (is2t) | ||
1215 | bound = 8; | ||
1216 | else | ||
1217 | bound = 4; | ||
1218 | |||
1219 | simularity_bitmap = 0; | ||
1220 | |||
1221 | for (i = 0; i < bound; i++) { | ||
1222 | diff = (result[c1][i] > result[c2][i]) ? | ||
1223 | (result[c1][i] - result[c2][i]) : | ||
1224 | (result[c2][i] - result[c1][i]); | ||
1225 | |||
1226 | if (diff > MAX_TOLERANCE) { | ||
1227 | if ((i == 2 || i == 6) && !simularity_bitmap) { | ||
1228 | if (result[c1][i] + result[c1][i + 1] == 0) | ||
1229 | final_candidate[(i / 4)] = c2; | ||
1230 | else if (result[c2][i] + result[c2][i + 1] == 0) | ||
1231 | final_candidate[(i / 4)] = c1; | ||
1232 | else | ||
1233 | simularity_bitmap = simularity_bitmap | | ||
1234 | (1 << i); | ||
1235 | } else | ||
1236 | simularity_bitmap = | ||
1237 | simularity_bitmap | (1 << i); | ||
1238 | } | ||
1239 | } | ||
1240 | |||
1241 | if (simularity_bitmap == 0) { | ||
1242 | for (i = 0; i < (bound / 4); i++) { | ||
1243 | if (final_candidate[i] != 0xFF) { | ||
1244 | for (j = i * 4; j < (i + 1) * 4 - 2; j++) | ||
1245 | result[3][j] = | ||
1246 | result[final_candidate[i]][j]; | ||
1247 | bresult = false; | ||
1248 | } | ||
1249 | } | ||
1250 | return bresult; | ||
1251 | } else if (!(simularity_bitmap & 0x0F)) { | ||
1252 | for (i = 0; i < 4; i++) | ||
1253 | result[3][i] = result[c1][i]; | ||
1254 | return false; | ||
1255 | } else if (!(simularity_bitmap & 0xF0) && is2t) { | ||
1256 | for (i = 4; i < 8; i++) | ||
1257 | result[3][i] = result[c1][i]; | ||
1258 | return false; | ||
1259 | } else { | ||
1260 | return false; | ||
1261 | } | ||
1262 | |||
1263 | } | ||
1264 | |||
1265 | static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, | ||
1266 | long result[][8], u8 t, bool is2t) | ||
1267 | { | ||
1268 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1269 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1270 | u32 i; | ||
1271 | u8 patha_ok, pathb_ok; | ||
1272 | u32 adda_reg[IQK_ADDA_REG_NUM] = { | ||
1273 | 0x85c, 0xe6c, 0xe70, 0xe74, | ||
1274 | 0xe78, 0xe7c, 0xe80, 0xe84, | ||
1275 | 0xe88, 0xe8c, 0xed0, 0xed4, | ||
1276 | 0xed8, 0xedc, 0xee0, 0xeec | ||
1277 | }; | ||
1278 | |||
1279 | u32 iqk_mac_reg[IQK_MAC_REG_NUM] = { | ||
1280 | 0x522, 0x550, 0x551, 0x040 | ||
1281 | }; | ||
1282 | |||
1283 | const u32 retrycount = 2; | ||
1284 | |||
1285 | u32 bbvalue; | ||
1286 | |||
1287 | if (t == 0) { | ||
1288 | bbvalue = rtl_get_bbreg(hw, 0x800, MASKDWORD); | ||
1289 | |||
1290 | _rtl92c_phy_save_adda_registers(hw, adda_reg, | ||
1291 | rtlphy->adda_backup, 16); | ||
1292 | _rtl92c_phy_save_mac_registers(hw, iqk_mac_reg, | ||
1293 | rtlphy->iqk_mac_backup); | ||
1294 | } | ||
1295 | _rtl92c_phy_path_adda_on(hw, adda_reg, true, is2t); | ||
1296 | if (t == 0) { | ||
1297 | rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw, | ||
1298 | RFPGA0_XA_HSSIPARAMETER1, | ||
1299 | BIT(8)); | ||
1300 | } | ||
1301 | if (!rtlphy->rfpi_enable) | ||
1302 | _rtl92c_phy_pi_mode_switch(hw, true); | ||
1303 | if (t == 0) { | ||
1304 | rtlphy->reg_c04 = rtl_get_bbreg(hw, 0xc04, MASKDWORD); | ||
1305 | rtlphy->reg_c08 = rtl_get_bbreg(hw, 0xc08, MASKDWORD); | ||
1306 | rtlphy->reg_874 = rtl_get_bbreg(hw, 0x874, MASKDWORD); | ||
1307 | } | ||
1308 | rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600); | ||
1309 | rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4); | ||
1310 | rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000); | ||
1311 | if (is2t) { | ||
1312 | rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000); | ||
1313 | rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000); | ||
1314 | } | ||
1315 | _rtl92c_phy_mac_setting_calibration(hw, iqk_mac_reg, | ||
1316 | rtlphy->iqk_mac_backup); | ||
1317 | rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x00080000); | ||
1318 | if (is2t) | ||
1319 | rtl_set_bbreg(hw, 0xb6c, MASKDWORD, 0x00080000); | ||
1320 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); | ||
1321 | rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00); | ||
1322 | rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x01004800); | ||
1323 | for (i = 0; i < retrycount; i++) { | ||
1324 | patha_ok = _rtl92c_phy_path_a_iqk(hw, is2t); | ||
1325 | if (patha_ok == 0x03) { | ||
1326 | result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) & | ||
1327 | 0x3FF0000) >> 16; | ||
1328 | result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & | ||
1329 | 0x3FF0000) >> 16; | ||
1330 | result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) & | ||
1331 | 0x3FF0000) >> 16; | ||
1332 | result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) & | ||
1333 | 0x3FF0000) >> 16; | ||
1334 | break; | ||
1335 | } else if (i == (retrycount - 1) && patha_ok == 0x01) | ||
1336 | result[t][0] = (rtl_get_bbreg(hw, 0xe94, | ||
1337 | MASKDWORD) & 0x3FF0000) >> | ||
1338 | 16; | ||
1339 | result[t][1] = | ||
1340 | (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & 0x3FF0000) >> 16; | ||
1341 | |||
1342 | } | ||
1343 | |||
1344 | if (is2t) { | ||
1345 | _rtl92c_phy_path_a_standby(hw); | ||
1346 | _rtl92c_phy_path_adda_on(hw, adda_reg, false, is2t); | ||
1347 | for (i = 0; i < retrycount; i++) { | ||
1348 | pathb_ok = _rtl92c_phy_path_b_iqk(hw); | ||
1349 | if (pathb_ok == 0x03) { | ||
1350 | result[t][4] = (rtl_get_bbreg(hw, | ||
1351 | 0xeb4, | ||
1352 | MASKDWORD) & | ||
1353 | 0x3FF0000) >> 16; | ||
1354 | result[t][5] = | ||
1355 | (rtl_get_bbreg(hw, 0xebc, MASKDWORD) & | ||
1356 | 0x3FF0000) >> 16; | ||
1357 | result[t][6] = | ||
1358 | (rtl_get_bbreg(hw, 0xec4, MASKDWORD) & | ||
1359 | 0x3FF0000) >> 16; | ||
1360 | result[t][7] = | ||
1361 | (rtl_get_bbreg(hw, 0xecc, MASKDWORD) & | ||
1362 | 0x3FF0000) >> 16; | ||
1363 | break; | ||
1364 | } else if (i == (retrycount - 1) && pathb_ok == 0x01) { | ||
1365 | result[t][4] = (rtl_get_bbreg(hw, | ||
1366 | 0xeb4, | ||
1367 | MASKDWORD) & | ||
1368 | 0x3FF0000) >> 16; | ||
1369 | } | ||
1370 | result[t][5] = (rtl_get_bbreg(hw, 0xebc, MASKDWORD) & | ||
1371 | 0x3FF0000) >> 16; | ||
1372 | } | ||
1373 | } | ||
1374 | rtl_set_bbreg(hw, 0xc04, MASKDWORD, rtlphy->reg_c04); | ||
1375 | rtl_set_bbreg(hw, 0x874, MASKDWORD, rtlphy->reg_874); | ||
1376 | rtl_set_bbreg(hw, 0xc08, MASKDWORD, rtlphy->reg_c08); | ||
1377 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0); | ||
1378 | rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3); | ||
1379 | if (is2t) | ||
1380 | rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3); | ||
1381 | if (t != 0) { | ||
1382 | if (!rtlphy->rfpi_enable) | ||
1383 | _rtl92c_phy_pi_mode_switch(hw, false); | ||
1384 | _rtl92c_phy_reload_adda_registers(hw, adda_reg, | ||
1385 | rtlphy->adda_backup, 16); | ||
1386 | _rtl92c_phy_reload_mac_registers(hw, iqk_mac_reg, | ||
1387 | rtlphy->iqk_mac_backup); | ||
1388 | } | ||
1389 | } | ||
1390 | |||
1391 | static void _rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, | ||
1392 | char delta, bool is2t) | ||
1393 | { | ||
1394 | /* This routine is deliberately dummied out for later fixes */ | ||
1395 | #if 0 | ||
1396 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1397 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1398 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
1399 | |||
1400 | u32 reg_d[PATH_NUM]; | ||
1401 | u32 tmpreg, index, offset, path, i, pathbound = PATH_NUM, apkbound; | ||
1402 | |||
1403 | u32 bb_backup[APK_BB_REG_NUM]; | ||
1404 | u32 bb_reg[APK_BB_REG_NUM] = { | ||
1405 | 0x904, 0xc04, 0x800, 0xc08, 0x874 | ||
1406 | }; | ||
1407 | u32 bb_ap_mode[APK_BB_REG_NUM] = { | ||
1408 | 0x00000020, 0x00a05430, 0x02040000, | ||
1409 | 0x000800e4, 0x00204000 | ||
1410 | }; | ||
1411 | u32 bb_normal_ap_mode[APK_BB_REG_NUM] = { | ||
1412 | 0x00000020, 0x00a05430, 0x02040000, | ||
1413 | 0x000800e4, 0x22204000 | ||
1414 | }; | ||
1415 | |||
1416 | u32 afe_backup[APK_AFE_REG_NUM]; | ||
1417 | u32 afe_reg[APK_AFE_REG_NUM] = { | ||
1418 | 0x85c, 0xe6c, 0xe70, 0xe74, 0xe78, | ||
1419 | 0xe7c, 0xe80, 0xe84, 0xe88, 0xe8c, | ||
1420 | 0xed0, 0xed4, 0xed8, 0xedc, 0xee0, | ||
1421 | 0xeec | ||
1422 | }; | ||
1423 | |||
1424 | u32 mac_backup[IQK_MAC_REG_NUM]; | ||
1425 | u32 mac_reg[IQK_MAC_REG_NUM] = { | ||
1426 | 0x522, 0x550, 0x551, 0x040 | ||
1427 | }; | ||
1428 | |||
1429 | u32 apk_rf_init_value[PATH_NUM][APK_BB_REG_NUM] = { | ||
1430 | {0x0852c, 0x1852c, 0x5852c, 0x1852c, 0x5852c}, | ||
1431 | {0x2852e, 0x0852e, 0x3852e, 0x0852e, 0x0852e} | ||
1432 | }; | ||
1433 | |||
1434 | u32 apk_normal_rf_init_value[PATH_NUM][APK_BB_REG_NUM] = { | ||
1435 | {0x0852c, 0x0a52c, 0x3a52c, 0x5a52c, 0x5a52c}, | ||
1436 | {0x0852c, 0x0a52c, 0x5a52c, 0x5a52c, 0x5a52c} | ||
1437 | }; | ||
1438 | |||
1439 | u32 apk_rf_value_0[PATH_NUM][APK_BB_REG_NUM] = { | ||
1440 | {0x52019, 0x52014, 0x52013, 0x5200f, 0x5208d}, | ||
1441 | {0x5201a, 0x52019, 0x52016, 0x52033, 0x52050} | ||
1442 | }; | ||
1443 | |||
1444 | u32 apk_normal_rf_value_0[PATH_NUM][APK_BB_REG_NUM] = { | ||
1445 | {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a}, | ||
1446 | {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a} | ||
1447 | }; | ||
1448 | |||
1449 | u32 afe_on_off[PATH_NUM] = { | ||
1450 | 0x04db25a4, 0x0b1b25a4 | ||
1451 | }; | ||
1452 | |||
1453 | u32 apk_offset[PATH_NUM] = { 0xb68, 0xb6c }; | ||
1454 | |||
1455 | u32 apk_normal_offset[PATH_NUM] = { 0xb28, 0xb98 }; | ||
1456 | |||
1457 | u32 apk_value[PATH_NUM] = { 0x92fc0000, 0x12fc0000 }; | ||
1458 | |||
1459 | u32 apk_normal_value[PATH_NUM] = { 0x92680000, 0x12680000 }; | ||
1460 | |||
1461 | const char apk_delta_mapping[APK_BB_REG_NUM][13] = { | ||
1462 | {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6}, | ||
1463 | {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6}, | ||
1464 | {-6, -4, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6}, | ||
1465 | {-1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6}, | ||
1466 | {-11, -9, -7, -5, -3, -1, 0, 0, 0, 0, 0, 0, 0} | ||
1467 | }; | ||
1468 | |||
1469 | const u32 apk_normal_setting_value_1[13] = { | ||
1470 | 0x01017018, 0xf7ed8f84, 0x1b1a1816, 0x2522201e, 0x322e2b28, | ||
1471 | 0x433f3a36, 0x5b544e49, 0x7b726a62, 0xa69a8f84, 0xdfcfc0b3, | ||
1472 | 0x12680000, 0x00880000, 0x00880000 | ||
1473 | }; | ||
1474 | |||
1475 | const u32 apk_normal_setting_value_2[16] = { | ||
1476 | 0x01c7021d, 0x01670183, 0x01000123, 0x00bf00e2, 0x008d00a3, | ||
1477 | 0x0068007b, 0x004d0059, 0x003a0042, 0x002b0031, 0x001f0025, | ||
1478 | 0x0017001b, 0x00110014, 0x000c000f, 0x0009000b, 0x00070008, | ||
1479 | 0x00050006 | ||
1480 | }; | ||
1481 | |||
1482 | const u32 apk_result[PATH_NUM][APK_BB_REG_NUM]; | ||
1483 | |||
1484 | long bb_offset, delta_v, delta_offset; | ||
1485 | |||
1486 | if (!is2t) | ||
1487 | pathbound = 1; | ||
1488 | |||
1489 | for (index = 0; index < PATH_NUM; index++) { | ||
1490 | apk_offset[index] = apk_normal_offset[index]; | ||
1491 | apk_value[index] = apk_normal_value[index]; | ||
1492 | afe_on_off[index] = 0x6fdb25a4; | ||
1493 | } | ||
1494 | |||
1495 | for (index = 0; index < APK_BB_REG_NUM; index++) { | ||
1496 | for (path = 0; path < pathbound; path++) { | ||
1497 | apk_rf_init_value[path][index] = | ||
1498 | apk_normal_rf_init_value[path][index]; | ||
1499 | apk_rf_value_0[path][index] = | ||
1500 | apk_normal_rf_value_0[path][index]; | ||
1501 | } | ||
1502 | bb_ap_mode[index] = bb_normal_ap_mode[index]; | ||
1503 | |||
1504 | apkbound = 6; | ||
1505 | } | ||
1506 | |||
1507 | for (index = 0; index < APK_BB_REG_NUM; index++) { | ||
1508 | if (index == 0) | ||
1509 | continue; | ||
1510 | bb_backup[index] = rtl_get_bbreg(hw, bb_reg[index], MASKDWORD); | ||
1511 | } | ||
1512 | |||
1513 | _rtl92c_phy_save_mac_registers(hw, mac_reg, mac_backup); | ||
1514 | |||
1515 | _rtl92c_phy_save_adda_registers(hw, afe_reg, afe_backup, 16); | ||
1516 | |||
1517 | for (path = 0; path < pathbound; path++) { | ||
1518 | if (path == RF90_PATH_A) { | ||
1519 | offset = 0xb00; | ||
1520 | for (index = 0; index < 11; index++) { | ||
1521 | rtl_set_bbreg(hw, offset, MASKDWORD, | ||
1522 | apk_normal_setting_value_1 | ||
1523 | [index]); | ||
1524 | |||
1525 | offset += 0x04; | ||
1526 | } | ||
1527 | |||
1528 | rtl_set_bbreg(hw, 0xb98, MASKDWORD, 0x12680000); | ||
1529 | |||
1530 | offset = 0xb68; | ||
1531 | for (; index < 13; index++) { | ||
1532 | rtl_set_bbreg(hw, offset, MASKDWORD, | ||
1533 | apk_normal_setting_value_1 | ||
1534 | [index]); | ||
1535 | |||
1536 | offset += 0x04; | ||
1537 | } | ||
1538 | |||
1539 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x40000000); | ||
1540 | |||
1541 | offset = 0xb00; | ||
1542 | for (index = 0; index < 16; index++) { | ||
1543 | rtl_set_bbreg(hw, offset, MASKDWORD, | ||
1544 | apk_normal_setting_value_2 | ||
1545 | [index]); | ||
1546 | |||
1547 | offset += 0x04; | ||
1548 | } | ||
1549 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000); | ||
1550 | } else if (path == RF90_PATH_B) { | ||
1551 | offset = 0xb70; | ||
1552 | for (index = 0; index < 10; index++) { | ||
1553 | rtl_set_bbreg(hw, offset, MASKDWORD, | ||
1554 | apk_normal_setting_value_1 | ||
1555 | [index]); | ||
1556 | |||
1557 | offset += 0x04; | ||
1558 | } | ||
1559 | rtl_set_bbreg(hw, 0xb28, MASKDWORD, 0x12680000); | ||
1560 | rtl_set_bbreg(hw, 0xb98, MASKDWORD, 0x12680000); | ||
1561 | |||
1562 | offset = 0xb68; | ||
1563 | index = 11; | ||
1564 | for (; index < 13; index++) { | ||
1565 | rtl_set_bbreg(hw, offset, MASKDWORD, | ||
1566 | apk_normal_setting_value_1 | ||
1567 | [index]); | ||
1568 | |||
1569 | offset += 0x04; | ||
1570 | } | ||
1571 | |||
1572 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x40000000); | ||
1573 | |||
1574 | offset = 0xb60; | ||
1575 | for (index = 0; index < 16; index++) { | ||
1576 | rtl_set_bbreg(hw, offset, MASKDWORD, | ||
1577 | apk_normal_setting_value_2 | ||
1578 | [index]); | ||
1579 | |||
1580 | offset += 0x04; | ||
1581 | } | ||
1582 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000); | ||
1583 | } | ||
1584 | |||
1585 | reg_d[path] = rtl_get_rfreg(hw, (enum radio_path)path, | ||
1586 | 0xd, MASKDWORD); | ||
1587 | |||
1588 | for (index = 0; index < APK_AFE_REG_NUM; index++) | ||
1589 | rtl_set_bbreg(hw, afe_reg[index], MASKDWORD, | ||
1590 | afe_on_off[path]); | ||
1591 | |||
1592 | if (path == RF90_PATH_A) { | ||
1593 | for (index = 0; index < APK_BB_REG_NUM; index++) { | ||
1594 | if (index == 0) | ||
1595 | continue; | ||
1596 | rtl_set_bbreg(hw, bb_reg[index], MASKDWORD, | ||
1597 | bb_ap_mode[index]); | ||
1598 | } | ||
1599 | } | ||
1600 | |||
1601 | _rtl92c_phy_mac_setting_calibration(hw, mac_reg, mac_backup); | ||
1602 | |||
1603 | if (path == 0) { | ||
1604 | rtl_set_rfreg(hw, RF90_PATH_B, 0x0, MASKDWORD, 0x10000); | ||
1605 | } else { | ||
1606 | rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASKDWORD, | ||
1607 | 0x10000); | ||
1608 | rtl_set_rfreg(hw, RF90_PATH_A, 0x10, MASKDWORD, | ||
1609 | 0x1000f); | ||
1610 | rtl_set_rfreg(hw, RF90_PATH_A, 0x11, MASKDWORD, | ||
1611 | 0x20103); | ||
1612 | } | ||
1613 | |||
1614 | delta_offset = ((delta + 14) / 2); | ||
1615 | if (delta_offset < 0) | ||
1616 | delta_offset = 0; | ||
1617 | else if (delta_offset > 12) | ||
1618 | delta_offset = 12; | ||
1619 | |||
1620 | for (index = 0; index < APK_BB_REG_NUM; index++) { | ||
1621 | if (index != 1) | ||
1622 | continue; | ||
1623 | |||
1624 | tmpreg = apk_rf_init_value[path][index]; | ||
1625 | |||
1626 | if (!rtlefuse->apk_thermalmeterignore) { | ||
1627 | bb_offset = (tmpreg & 0xF0000) >> 16; | ||
1628 | |||
1629 | if (!(tmpreg & BIT(15))) | ||
1630 | bb_offset = -bb_offset; | ||
1631 | |||
1632 | delta_v = | ||
1633 | apk_delta_mapping[index][delta_offset]; | ||
1634 | |||
1635 | bb_offset += delta_v; | ||
1636 | |||
1637 | if (bb_offset < 0) { | ||
1638 | tmpreg = tmpreg & (~BIT(15)); | ||
1639 | bb_offset = -bb_offset; | ||
1640 | } else { | ||
1641 | tmpreg = tmpreg | BIT(15); | ||
1642 | } | ||
1643 | |||
1644 | tmpreg = | ||
1645 | (tmpreg & 0xFFF0FFFF) | (bb_offset << 16); | ||
1646 | } | ||
1647 | |||
1648 | rtl_set_rfreg(hw, (enum radio_path)path, 0xc, | ||
1649 | MASKDWORD, 0x8992e); | ||
1650 | rtl_set_rfreg(hw, (enum radio_path)path, 0x0, | ||
1651 | MASKDWORD, apk_rf_value_0[path][index]); | ||
1652 | rtl_set_rfreg(hw, (enum radio_path)path, 0xd, | ||
1653 | MASKDWORD, tmpreg); | ||
1654 | |||
1655 | i = 0; | ||
1656 | do { | ||
1657 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80000000); | ||
1658 | rtl_set_bbreg(hw, apk_offset[path], | ||
1659 | MASKDWORD, apk_value[0]); | ||
1660 | RTPRINT(rtlpriv, FINIT, INIT_IQK, | ||
1661 | ("PHY_APCalibrate() offset 0x%x " | ||
1662 | "value 0x%x\n", | ||
1663 | apk_offset[path], | ||
1664 | rtl_get_bbreg(hw, apk_offset[path], | ||
1665 | MASKDWORD))); | ||
1666 | |||
1667 | mdelay(3); | ||
1668 | |||
1669 | rtl_set_bbreg(hw, apk_offset[path], | ||
1670 | MASKDWORD, apk_value[1]); | ||
1671 | RTPRINT(rtlpriv, FINIT, INIT_IQK, | ||
1672 | ("PHY_APCalibrate() offset 0x%x " | ||
1673 | "value 0x%x\n", | ||
1674 | apk_offset[path], | ||
1675 | rtl_get_bbreg(hw, apk_offset[path], | ||
1676 | MASKDWORD))); | ||
1677 | |||
1678 | mdelay(20); | ||
1679 | |||
1680 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000); | ||
1681 | |||
1682 | if (path == RF90_PATH_A) | ||
1683 | tmpreg = rtl_get_bbreg(hw, 0xbd8, | ||
1684 | 0x03E00000); | ||
1685 | else | ||
1686 | tmpreg = rtl_get_bbreg(hw, 0xbd8, | ||
1687 | 0xF8000000); | ||
1688 | |||
1689 | RTPRINT(rtlpriv, FINIT, INIT_IQK, | ||
1690 | ("PHY_APCalibrate() offset " | ||
1691 | "0xbd8[25:21] %x\n", tmpreg)); | ||
1692 | |||
1693 | i++; | ||
1694 | |||
1695 | } while (tmpreg > apkbound && i < 4); | ||
1696 | |||
1697 | apk_result[path][index] = tmpreg; | ||
1698 | } | ||
1699 | } | ||
1700 | |||
1701 | _rtl92c_phy_reload_mac_registers(hw, mac_reg, mac_backup); | ||
1702 | |||
1703 | for (index = 0; index < APK_BB_REG_NUM; index++) { | ||
1704 | if (index == 0) | ||
1705 | continue; | ||
1706 | rtl_set_bbreg(hw, bb_reg[index], MASKDWORD, bb_backup[index]); | ||
1707 | } | ||
1708 | |||
1709 | _rtl92c_phy_reload_adda_registers(hw, afe_reg, afe_backup, 16); | ||
1710 | |||
1711 | for (path = 0; path < pathbound; path++) { | ||
1712 | rtl_set_rfreg(hw, (enum radio_path)path, 0xd, | ||
1713 | MASKDWORD, reg_d[path]); | ||
1714 | |||
1715 | if (path == RF90_PATH_B) { | ||
1716 | rtl_set_rfreg(hw, RF90_PATH_A, 0x10, MASKDWORD, | ||
1717 | 0x1000f); | ||
1718 | rtl_set_rfreg(hw, RF90_PATH_A, 0x11, MASKDWORD, | ||
1719 | 0x20101); | ||
1720 | } | ||
1721 | |||
1722 | if (apk_result[path][1] > 6) | ||
1723 | apk_result[path][1] = 6; | ||
1724 | } | ||
1725 | |||
1726 | for (path = 0; path < pathbound; path++) { | ||
1727 | rtl_set_rfreg(hw, (enum radio_path)path, 0x3, MASKDWORD, | ||
1728 | ((apk_result[path][1] << 15) | | ||
1729 | (apk_result[path][1] << 10) | | ||
1730 | (apk_result[path][1] << 5) | | ||
1731 | apk_result[path][1])); | ||
1732 | |||
1733 | if (path == RF90_PATH_A) | ||
1734 | rtl_set_rfreg(hw, (enum radio_path)path, 0x4, MASKDWORD, | ||
1735 | ((apk_result[path][1] << 15) | | ||
1736 | (apk_result[path][1] << 10) | | ||
1737 | (0x00 << 5) | 0x05)); | ||
1738 | else | ||
1739 | rtl_set_rfreg(hw, (enum radio_path)path, 0x4, MASKDWORD, | ||
1740 | ((apk_result[path][1] << 15) | | ||
1741 | (apk_result[path][1] << 10) | | ||
1742 | (0x02 << 5) | 0x05)); | ||
1743 | |||
1744 | rtl_set_rfreg(hw, (enum radio_path)path, 0xe, MASKDWORD, | ||
1745 | ((0x08 << 15) | (0x08 << 10) | (0x08 << 5) | | ||
1746 | 0x08)); | ||
1747 | |||
1748 | } | ||
1749 | |||
1750 | rtlphy->apk_done = true; | ||
1751 | #endif | ||
1752 | } | ||
1753 | |||
1754 | static void _rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, | ||
1755 | bool bmain, bool is2t) | ||
1756 | { | ||
1757 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1758 | |||
1759 | if (is_hal_stop(rtlhal)) { | ||
1760 | rtl_set_bbreg(hw, REG_LEDCFG0, BIT(23), 0x01); | ||
1761 | rtl_set_bbreg(hw, rFPGA0_XAB_RFPARAMETER, BIT(13), 0x01); | ||
1762 | } | ||
1763 | if (is2t) { | ||
1764 | if (bmain) | ||
1765 | rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, | ||
1766 | BIT(5) | BIT(6), 0x1); | ||
1767 | else | ||
1768 | rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, | ||
1769 | BIT(5) | BIT(6), 0x2); | ||
1770 | } else { | ||
1771 | if (bmain) | ||
1772 | rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x2); | ||
1773 | else | ||
1774 | rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x1); | ||
1775 | |||
1776 | } | ||
1777 | } | ||
1778 | |||
1779 | #undef IQK_ADDA_REG_NUM | ||
1780 | #undef IQK_DELAY_TIME | ||
1781 | |||
1782 | void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery) | ||
1783 | { | ||
1784 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1785 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1786 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1787 | |||
1788 | long result[4][8]; | ||
1789 | u8 i, final_candidate; | ||
1790 | bool patha_ok, pathb_ok; | ||
1791 | long reg_e94, reg_e9c, reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4, | ||
1792 | reg_ecc, reg_tmp = 0; | ||
1793 | bool is12simular, is13simular, is23simular; | ||
1794 | bool start_conttx = false, singletone = false; | ||
1795 | u32 iqk_bb_reg[10] = { | ||
1796 | ROFDM0_XARXIQIMBALANCE, | ||
1797 | ROFDM0_XBRXIQIMBALANCE, | ||
1798 | ROFDM0_ECCATHRESHOLD, | ||
1799 | ROFDM0_AGCRSSITABLE, | ||
1800 | ROFDM0_XATXIQIMBALANCE, | ||
1801 | ROFDM0_XBTXIQIMBALANCE, | ||
1802 | ROFDM0_XCTXIQIMBALANCE, | ||
1803 | ROFDM0_XCTXAFE, | ||
1804 | ROFDM0_XDTXAFE, | ||
1805 | ROFDM0_RXIQEXTANTA | ||
1806 | }; | ||
1807 | |||
1808 | if (recovery) { | ||
1809 | _rtl92c_phy_reload_adda_registers(hw, | ||
1810 | iqk_bb_reg, | ||
1811 | rtlphy->iqk_bb_backup, 10); | ||
1812 | return; | ||
1813 | } | ||
1814 | if (start_conttx || singletone) | ||
1815 | return; | ||
1816 | for (i = 0; i < 8; i++) { | ||
1817 | result[0][i] = 0; | ||
1818 | result[1][i] = 0; | ||
1819 | result[2][i] = 0; | ||
1820 | result[3][i] = 0; | ||
1821 | } | ||
1822 | final_candidate = 0xff; | ||
1823 | patha_ok = false; | ||
1824 | pathb_ok = false; | ||
1825 | is12simular = false; | ||
1826 | is23simular = false; | ||
1827 | is13simular = false; | ||
1828 | for (i = 0; i < 3; i++) { | ||
1829 | if (IS_92C_SERIAL(rtlhal->version)) | ||
1830 | _rtl92c_phy_iq_calibrate(hw, result, i, true); | ||
1831 | else | ||
1832 | _rtl92c_phy_iq_calibrate(hw, result, i, false); | ||
1833 | if (i == 1) { | ||
1834 | is12simular = _rtl92c_phy_simularity_compare(hw, | ||
1835 | result, 0, | ||
1836 | 1); | ||
1837 | if (is12simular) { | ||
1838 | final_candidate = 0; | ||
1839 | break; | ||
1840 | } | ||
1841 | } | ||
1842 | if (i == 2) { | ||
1843 | is13simular = _rtl92c_phy_simularity_compare(hw, | ||
1844 | result, 0, | ||
1845 | 2); | ||
1846 | if (is13simular) { | ||
1847 | final_candidate = 0; | ||
1848 | break; | ||
1849 | } | ||
1850 | is23simular = _rtl92c_phy_simularity_compare(hw, | ||
1851 | result, 1, | ||
1852 | 2); | ||
1853 | if (is23simular) | ||
1854 | final_candidate = 1; | ||
1855 | else { | ||
1856 | for (i = 0; i < 8; i++) | ||
1857 | reg_tmp += result[3][i]; | ||
1858 | |||
1859 | if (reg_tmp != 0) | ||
1860 | final_candidate = 3; | ||
1861 | else | ||
1862 | final_candidate = 0xFF; | ||
1863 | } | ||
1864 | } | ||
1865 | } | ||
1866 | for (i = 0; i < 4; i++) { | ||
1867 | reg_e94 = result[i][0]; | ||
1868 | reg_e9c = result[i][1]; | ||
1869 | reg_ea4 = result[i][2]; | ||
1870 | reg_eac = result[i][3]; | ||
1871 | reg_eb4 = result[i][4]; | ||
1872 | reg_ebc = result[i][5]; | ||
1873 | reg_ec4 = result[i][6]; | ||
1874 | reg_ecc = result[i][7]; | ||
1875 | } | ||
1876 | if (final_candidate != 0xff) { | ||
1877 | rtlphy->reg_e94 = reg_e94 = result[final_candidate][0]; | ||
1878 | rtlphy->reg_e9c = reg_e9c = result[final_candidate][1]; | ||
1879 | reg_ea4 = result[final_candidate][2]; | ||
1880 | reg_eac = result[final_candidate][3]; | ||
1881 | rtlphy->reg_eb4 = reg_eb4 = result[final_candidate][4]; | ||
1882 | rtlphy->reg_ebc = reg_ebc = result[final_candidate][5]; | ||
1883 | reg_ec4 = result[final_candidate][6]; | ||
1884 | reg_ecc = result[final_candidate][7]; | ||
1885 | patha_ok = pathb_ok = true; | ||
1886 | } else { | ||
1887 | rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100; | ||
1888 | rtlphy->reg_e9c = rtlphy->reg_ebc = 0x0; | ||
1889 | } | ||
1890 | if (reg_e94 != 0) /*&&(reg_ea4 != 0) */ | ||
1891 | _rtl92c_phy_path_a_fill_iqk_matrix(hw, patha_ok, result, | ||
1892 | final_candidate, | ||
1893 | (reg_ea4 == 0)); | ||
1894 | if (IS_92C_SERIAL(rtlhal->version)) { | ||
1895 | if (reg_eb4 != 0) /*&&(reg_ec4 != 0) */ | ||
1896 | _rtl92c_phy_path_b_fill_iqk_matrix(hw, pathb_ok, | ||
1897 | result, | ||
1898 | final_candidate, | ||
1899 | (reg_ec4 == 0)); | ||
1900 | } | ||
1901 | _rtl92c_phy_save_adda_registers(hw, iqk_bb_reg, | ||
1902 | rtlphy->iqk_bb_backup, 10); | ||
1903 | } | ||
1904 | |||
1905 | void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw) | ||
1906 | { | ||
1907 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1908 | bool start_conttx = false, singletone = false; | ||
1909 | |||
1910 | if (start_conttx || singletone) | ||
1911 | return; | ||
1912 | if (IS_92C_SERIAL(rtlhal->version)) | ||
1913 | _rtl92c_phy_lc_calibrate(hw, true); | ||
1914 | else | ||
1915 | _rtl92c_phy_lc_calibrate(hw, false); | ||
1916 | } | ||
1917 | |||
1918 | void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta) | ||
1919 | { | ||
1920 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1921 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1922 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1923 | |||
1924 | if (rtlphy->apk_done) | ||
1925 | return; | ||
1926 | if (IS_92C_SERIAL(rtlhal->version)) | ||
1927 | _rtl92c_phy_ap_calibrate(hw, delta, true); | ||
1928 | else | ||
1929 | _rtl92c_phy_ap_calibrate(hw, delta, false); | ||
1930 | } | ||
1931 | |||
1932 | void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain) | ||
1933 | { | ||
1934 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1935 | |||
1936 | if (IS_92C_SERIAL(rtlhal->version)) | ||
1937 | _rtl92c_phy_set_rfpath_switch(hw, bmain, true); | ||
1938 | else | ||
1939 | _rtl92c_phy_set_rfpath_switch(hw, bmain, false); | ||
1940 | } | ||
1941 | |||
1942 | bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) | ||
1943 | { | ||
1944 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1945 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1946 | bool postprocessing = false; | ||
1947 | |||
1948 | RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, | ||
1949 | ("-->IO Cmd(%#x), set_io_inprogress(%d)\n", | ||
1950 | iotype, rtlphy->set_io_inprogress)); | ||
1951 | do { | ||
1952 | switch (iotype) { | ||
1953 | case IO_CMD_RESUME_DM_BY_SCAN: | ||
1954 | RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, | ||
1955 | ("[IO CMD] Resume DM after scan.\n")); | ||
1956 | postprocessing = true; | ||
1957 | break; | ||
1958 | case IO_CMD_PAUSE_DM_BY_SCAN: | ||
1959 | RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, | ||
1960 | ("[IO CMD] Pause DM before scan.\n")); | ||
1961 | postprocessing = true; | ||
1962 | break; | ||
1963 | default: | ||
1964 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
1965 | ("switch case not process\n")); | ||
1966 | break; | ||
1967 | } | ||
1968 | } while (false); | ||
1969 | if (postprocessing && !rtlphy->set_io_inprogress) { | ||
1970 | rtlphy->set_io_inprogress = true; | ||
1971 | rtlphy->current_io_type = iotype; | ||
1972 | } else { | ||
1973 | return false; | ||
1974 | } | ||
1975 | rtl92c_phy_set_io(hw); | ||
1976 | RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, ("<--IO Type(%#x)\n", iotype)); | ||
1977 | return true; | ||
1978 | } | ||
1979 | |||
1980 | void rtl92c_phy_set_io(struct ieee80211_hw *hw) | ||
1981 | { | ||
1982 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1983 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1984 | |||
1985 | RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, | ||
1986 | ("--->Cmd(%#x), set_io_inprogress(%d)\n", | ||
1987 | rtlphy->current_io_type, rtlphy->set_io_inprogress)); | ||
1988 | switch (rtlphy->current_io_type) { | ||
1989 | case IO_CMD_RESUME_DM_BY_SCAN: | ||
1990 | dm_digtable.cur_igvalue = rtlphy->initgain_backup.xaagccore1; | ||
1991 | rtl92c_dm_write_dig(hw); | ||
1992 | rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); | ||
1993 | break; | ||
1994 | case IO_CMD_PAUSE_DM_BY_SCAN: | ||
1995 | rtlphy->initgain_backup.xaagccore1 = dm_digtable.cur_igvalue; | ||
1996 | dm_digtable.cur_igvalue = 0x17; | ||
1997 | rtl92c_dm_write_dig(hw); | ||
1998 | break; | ||
1999 | default: | ||
2000 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
2001 | ("switch case not process\n")); | ||
2002 | break; | ||
2003 | } | ||
2004 | rtlphy->set_io_inprogress = false; | ||
2005 | RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, | ||
2006 | ("<---(%#x)\n", rtlphy->current_io_type)); | ||
2007 | } | ||
2008 | |||
2009 | void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw) | ||
2010 | { | ||
2011 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
2012 | |||
2013 | rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b); | ||
2014 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); | ||
2015 | rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00); | ||
2016 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); | ||
2017 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); | ||
2018 | rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); | ||
2019 | } | ||
2020 | |||
2021 | static void _rtl92ce_phy_set_rf_sleep(struct ieee80211_hw *hw) | ||
2022 | { | ||
2023 | u32 u4b_tmp; | ||
2024 | u8 delay = 5; | ||
2025 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
2026 | |||
2027 | rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); | ||
2028 | rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); | ||
2029 | rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); | ||
2030 | u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK); | ||
2031 | while (u4b_tmp != 0 && delay > 0) { | ||
2032 | rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0); | ||
2033 | rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); | ||
2034 | rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); | ||
2035 | u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK); | ||
2036 | delay--; | ||
2037 | } | ||
2038 | if (delay == 0) { | ||
2039 | rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00); | ||
2040 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); | ||
2041 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); | ||
2042 | rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); | ||
2043 | RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, | ||
2044 | ("Switch RF timeout !!!.\n")); | ||
2045 | return; | ||
2046 | } | ||
2047 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); | ||
2048 | rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22); | ||
2049 | } | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c index 4b256d0bebcc..191106033b3c 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8192ce/phy.c | |||
@@ -37,85 +37,7 @@ | |||
37 | #include "dm.h" | 37 | #include "dm.h" |
38 | #include "table.h" | 38 | #include "table.h" |
39 | 39 | ||
40 | /* Define macro to shorten lines */ | 40 | #include "../rtl8192c/phy_common.c" |
41 | #define MCS_TXPWR mcs_txpwrlevel_origoffset | ||
42 | |||
43 | static u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, | ||
44 | enum radio_path rfpath, u32 offset); | ||
45 | static void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, | ||
46 | enum radio_path rfpath, u32 offset, | ||
47 | u32 data); | ||
48 | static u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, | ||
49 | enum radio_path rfpath, u32 offset); | ||
50 | static void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, | ||
51 | enum radio_path rfpath, u32 offset, | ||
52 | u32 data); | ||
53 | static u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask); | ||
54 | static bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw); | ||
55 | static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); | ||
56 | static bool _rtl92c_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, | ||
57 | u8 configtype); | ||
58 | static bool _rtl92c_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, | ||
59 | u8 configtype); | ||
60 | static void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw); | ||
61 | static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, | ||
62 | u32 cmdtableidx, u32 cmdtablesz, | ||
63 | enum swchnlcmd_id cmdid, u32 para1, | ||
64 | u32 para2, u32 msdelay); | ||
65 | static bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, | ||
66 | u8 channel, u8 *stage, u8 *step, | ||
67 | u32 *delay); | ||
68 | static u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw, | ||
69 | enum wireless_mode wirelessmode, | ||
70 | long power_indbm); | ||
71 | static bool _rtl92c_phy_config_rf_external_pa(struct ieee80211_hw *hw, | ||
72 | enum radio_path rfpath); | ||
73 | static long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, | ||
74 | enum wireless_mode wirelessmode, | ||
75 | u8 txpwridx); | ||
76 | u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) | ||
77 | { | ||
78 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
79 | u32 returnvalue, originalvalue, bitshift; | ||
80 | |||
81 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), " | ||
82 | "bitmask(%#x)\n", regaddr, | ||
83 | bitmask)); | ||
84 | originalvalue = rtl_read_dword(rtlpriv, regaddr); | ||
85 | bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); | ||
86 | returnvalue = (originalvalue & bitmask) >> bitshift; | ||
87 | |||
88 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("BBR MASK=0x%x " | ||
89 | "Addr[0x%x]=0x%x\n", bitmask, | ||
90 | regaddr, originalvalue)); | ||
91 | |||
92 | return returnvalue; | ||
93 | |||
94 | } | ||
95 | |||
96 | void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, | ||
97 | u32 regaddr, u32 bitmask, u32 data) | ||
98 | { | ||
99 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
100 | u32 originalvalue, bitshift; | ||
101 | |||
102 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," | ||
103 | " data(%#x)\n", regaddr, bitmask, | ||
104 | data)); | ||
105 | |||
106 | if (bitmask != MASKDWORD) { | ||
107 | originalvalue = rtl_read_dword(rtlpriv, regaddr); | ||
108 | bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); | ||
109 | data = ((originalvalue & (~bitmask)) | (data << bitshift)); | ||
110 | } | ||
111 | |||
112 | rtl_write_dword(rtlpriv, regaddr, data); | ||
113 | |||
114 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("regaddr(%#x), bitmask(%#x)," | ||
115 | " data(%#x)\n", regaddr, bitmask, | ||
116 | data)); | ||
117 | |||
118 | } | ||
119 | 41 | ||
120 | u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, | 42 | u32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, |
121 | enum radio_path rfpath, u32 regaddr, u32 bitmask) | 43 | enum radio_path rfpath, u32 regaddr, u32 bitmask) |
@@ -200,118 +122,6 @@ void rtl92c_phy_set_rf_reg(struct ieee80211_hw *hw, | |||
200 | bitmask, data, rfpath)); | 122 | bitmask, data, rfpath)); |
201 | } | 123 | } |
202 | 124 | ||
203 | static u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, | ||
204 | enum radio_path rfpath, u32 offset) | ||
205 | { | ||
206 | RT_ASSERT(false, ("deprecated!\n")); | ||
207 | return 0; | ||
208 | } | ||
209 | |||
210 | static void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, | ||
211 | enum radio_path rfpath, u32 offset, | ||
212 | u32 data) | ||
213 | { | ||
214 | RT_ASSERT(false, ("deprecated!\n")); | ||
215 | } | ||
216 | |||
217 | static u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, | ||
218 | enum radio_path rfpath, u32 offset) | ||
219 | { | ||
220 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
221 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
222 | struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; | ||
223 | u32 newoffset; | ||
224 | u32 tmplong, tmplong2; | ||
225 | u8 rfpi_enable = 0; | ||
226 | u32 retvalue; | ||
227 | |||
228 | offset &= 0x3f; | ||
229 | newoffset = offset; | ||
230 | if (RT_CANNOT_IO(hw)) { | ||
231 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("return all one\n")); | ||
232 | return 0xFFFFFFFF; | ||
233 | } | ||
234 | tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD); | ||
235 | if (rfpath == RF90_PATH_A) | ||
236 | tmplong2 = tmplong; | ||
237 | else | ||
238 | tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD); | ||
239 | tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) | | ||
240 | (newoffset << 23) | BLSSIREADEDGE; | ||
241 | rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, | ||
242 | tmplong & (~BLSSIREADEDGE)); | ||
243 | mdelay(1); | ||
244 | rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2); | ||
245 | mdelay(1); | ||
246 | rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, | ||
247 | tmplong | BLSSIREADEDGE); | ||
248 | mdelay(1); | ||
249 | if (rfpath == RF90_PATH_A) | ||
250 | rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1, | ||
251 | BIT(8)); | ||
252 | else if (rfpath == RF90_PATH_B) | ||
253 | rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1, | ||
254 | BIT(8)); | ||
255 | if (rfpi_enable) | ||
256 | retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readbackpi, | ||
257 | BLSSIREADBACKDATA); | ||
258 | else | ||
259 | retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback, | ||
260 | BLSSIREADBACKDATA); | ||
261 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFR-%d Addr[0x%x]=0x%x\n", | ||
262 | rfpath, pphyreg->rflssi_readback, | ||
263 | retvalue)); | ||
264 | return retvalue; | ||
265 | } | ||
266 | |||
267 | static void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, | ||
268 | enum radio_path rfpath, u32 offset, | ||
269 | u32 data) | ||
270 | { | ||
271 | u32 data_and_addr; | ||
272 | u32 newoffset; | ||
273 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
274 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
275 | struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; | ||
276 | |||
277 | if (RT_CANNOT_IO(hw)) { | ||
278 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("stop\n")); | ||
279 | return; | ||
280 | } | ||
281 | offset &= 0x3f; | ||
282 | newoffset = offset; | ||
283 | data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff; | ||
284 | rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr); | ||
285 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, ("RFW-%d Addr[0x%x]=0x%x\n", | ||
286 | rfpath, pphyreg->rf3wire_offset, | ||
287 | data_and_addr)); | ||
288 | } | ||
289 | |||
290 | static u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask) | ||
291 | { | ||
292 | u32 i; | ||
293 | |||
294 | for (i = 0; i <= 31; i++) { | ||
295 | if (((bitmask >> i) & 0x1) == 1) | ||
296 | break; | ||
297 | } | ||
298 | return i; | ||
299 | } | ||
300 | |||
301 | static void _rtl92c_phy_bb_config_1t(struct ieee80211_hw *hw) | ||
302 | { | ||
303 | rtl_set_bbreg(hw, RFPGA0_TXINFO, 0x3, 0x2); | ||
304 | rtl_set_bbreg(hw, RFPGA1_TXINFO, 0x300033, 0x200022); | ||
305 | rtl_set_bbreg(hw, RCCK0_AFESETTING, MASKBYTE3, 0x45); | ||
306 | rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x23); | ||
307 | rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, 0x30, 0x1); | ||
308 | rtl_set_bbreg(hw, 0xe74, 0x0c000000, 0x2); | ||
309 | rtl_set_bbreg(hw, 0xe78, 0x0c000000, 0x2); | ||
310 | rtl_set_bbreg(hw, 0xe7c, 0x0c000000, 0x2); | ||
311 | rtl_set_bbreg(hw, 0xe80, 0x0c000000, 0x2); | ||
312 | rtl_set_bbreg(hw, 0xe88, 0x0c000000, 0x2); | ||
313 | } | ||
314 | |||
315 | bool rtl92c_phy_mac_config(struct ieee80211_hw *hw) | 125 | bool rtl92c_phy_mac_config(struct ieee80211_hw *hw) |
316 | { | 126 | { |
317 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 127 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
@@ -350,50 +160,6 @@ bool rtl92c_phy_bb_config(struct ieee80211_hw *hw) | |||
350 | return rtstatus; | 160 | return rtstatus; |
351 | } | 161 | } |
352 | 162 | ||
353 | bool rtl92c_phy_rf_config(struct ieee80211_hw *hw) | ||
354 | { | ||
355 | return rtl92c_phy_rf6052_config(hw); | ||
356 | } | ||
357 | |||
358 | static bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw) | ||
359 | { | ||
360 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
361 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
362 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
363 | bool rtstatus; | ||
364 | |||
365 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("==>\n")); | ||
366 | rtstatus = _rtl92c_phy_config_bb_with_headerfile(hw, | ||
367 | BASEBAND_CONFIG_PHY_REG); | ||
368 | if (rtstatus != true) { | ||
369 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Write BB Reg Fail!!")); | ||
370 | return false; | ||
371 | } | ||
372 | if (rtlphy->rf_type == RF_1T2R) { | ||
373 | _rtl92c_phy_bb_config_1t(hw); | ||
374 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, ("Config to 1T!!\n")); | ||
375 | } | ||
376 | if (rtlefuse->autoload_failflag == false) { | ||
377 | rtlphy->pwrgroup_cnt = 0; | ||
378 | rtstatus = _rtl92c_phy_config_bb_with_pgheaderfile(hw, | ||
379 | BASEBAND_CONFIG_PHY_REG); | ||
380 | } | ||
381 | if (rtstatus != true) { | ||
382 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("BB_PG Reg Fail!!")); | ||
383 | return false; | ||
384 | } | ||
385 | rtstatus = _rtl92c_phy_config_bb_with_headerfile(hw, | ||
386 | BASEBAND_CONFIG_AGC_TAB); | ||
387 | if (rtstatus != true) { | ||
388 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("AGC Table Fail\n")); | ||
389 | return false; | ||
390 | } | ||
391 | rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw, | ||
392 | RFPGA0_XA_HSSIPARAMETER2, | ||
393 | 0x200)); | ||
394 | return true; | ||
395 | } | ||
396 | |||
397 | static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) | 163 | static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) |
398 | { | 164 | { |
399 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 165 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
@@ -411,10 +177,6 @@ static bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) | |||
411 | return true; | 177 | return true; |
412 | } | 178 | } |
413 | 179 | ||
414 | void rtl92c_phy_config_bb_external_pa(struct ieee80211_hw *hw) | ||
415 | { | ||
416 | } | ||
417 | |||
418 | static bool _rtl92c_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, | 180 | static bool _rtl92c_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, |
419 | u8 configtype) | 181 | u8 configtype) |
420 | { | 182 | { |
@@ -475,142 +237,6 @@ static bool _rtl92c_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, | |||
475 | return true; | 237 | return true; |
476 | } | 238 | } |
477 | 239 | ||
478 | static void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw, | ||
479 | u32 regaddr, u32 bitmask, | ||
480 | u32 data) | ||
481 | { | ||
482 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
483 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
484 | |||
485 | if (regaddr == RTXAGC_A_RATE18_06) { | ||
486 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][0] = data; | ||
487 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
488 | ("MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n", | ||
489 | rtlphy->pwrgroup_cnt, | ||
490 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][0])); | ||
491 | } | ||
492 | if (regaddr == RTXAGC_A_RATE54_24) { | ||
493 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][1] = data; | ||
494 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
495 | ("MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n", | ||
496 | rtlphy->pwrgroup_cnt, | ||
497 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][1])); | ||
498 | } | ||
499 | if (regaddr == RTXAGC_A_CCK1_MCS32) { | ||
500 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][6] = data; | ||
501 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
502 | ("MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n", | ||
503 | rtlphy->pwrgroup_cnt, | ||
504 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][6])); | ||
505 | } | ||
506 | if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) { | ||
507 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][7] = data; | ||
508 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
509 | ("MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n", | ||
510 | rtlphy->pwrgroup_cnt, | ||
511 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][7])); | ||
512 | } | ||
513 | if (regaddr == RTXAGC_A_MCS03_MCS00) { | ||
514 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][2] = data; | ||
515 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
516 | ("MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n", | ||
517 | rtlphy->pwrgroup_cnt, | ||
518 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][2])); | ||
519 | } | ||
520 | if (regaddr == RTXAGC_A_MCS07_MCS04) { | ||
521 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][3] = data; | ||
522 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
523 | ("MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n", | ||
524 | rtlphy->pwrgroup_cnt, | ||
525 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][3])); | ||
526 | } | ||
527 | if (regaddr == RTXAGC_A_MCS11_MCS08) { | ||
528 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][4] = data; | ||
529 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
530 | ("MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n", | ||
531 | rtlphy->pwrgroup_cnt, | ||
532 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][4])); | ||
533 | } | ||
534 | if (regaddr == RTXAGC_A_MCS15_MCS12) { | ||
535 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][5] = data; | ||
536 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
537 | ("MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n", | ||
538 | rtlphy->pwrgroup_cnt, | ||
539 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][5])); | ||
540 | } | ||
541 | if (regaddr == RTXAGC_B_RATE18_06) { | ||
542 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][8] = data; | ||
543 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
544 | ("MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n", | ||
545 | rtlphy->pwrgroup_cnt, | ||
546 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][8])); | ||
547 | } | ||
548 | if (regaddr == RTXAGC_B_RATE54_24) { | ||
549 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9] = data; | ||
550 | |||
551 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
552 | ("MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n", | ||
553 | rtlphy->pwrgroup_cnt, | ||
554 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][9])); | ||
555 | } | ||
556 | |||
557 | if (regaddr == RTXAGC_B_CCK1_55_MCS32) { | ||
558 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14] = data; | ||
559 | |||
560 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
561 | ("MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n", | ||
562 | rtlphy->pwrgroup_cnt, | ||
563 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][14])); | ||
564 | } | ||
565 | |||
566 | if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) { | ||
567 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15] = data; | ||
568 | |||
569 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
570 | ("MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n", | ||
571 | rtlphy->pwrgroup_cnt, | ||
572 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][15])); | ||
573 | } | ||
574 | |||
575 | if (regaddr == RTXAGC_B_MCS03_MCS00) { | ||
576 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10] = data; | ||
577 | |||
578 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
579 | ("MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n", | ||
580 | rtlphy->pwrgroup_cnt, | ||
581 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][10])); | ||
582 | } | ||
583 | |||
584 | if (regaddr == RTXAGC_B_MCS07_MCS04) { | ||
585 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11] = data; | ||
586 | |||
587 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
588 | ("MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n", | ||
589 | rtlphy->pwrgroup_cnt, | ||
590 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][11])); | ||
591 | } | ||
592 | |||
593 | if (regaddr == RTXAGC_B_MCS11_MCS08) { | ||
594 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12] = data; | ||
595 | |||
596 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
597 | ("MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n", | ||
598 | rtlphy->pwrgroup_cnt, | ||
599 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][12])); | ||
600 | } | ||
601 | |||
602 | if (regaddr == RTXAGC_B_MCS15_MCS12) { | ||
603 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][13] = data; | ||
604 | |||
605 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
606 | ("MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n", | ||
607 | rtlphy->pwrgroup_cnt, | ||
608 | rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][13])); | ||
609 | |||
610 | rtlphy->pwrgroup_cnt++; | ||
611 | } | ||
612 | } | ||
613 | |||
614 | static bool _rtl92c_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, | 240 | static bool _rtl92c_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, |
615 | u8 configtype) | 241 | u8 configtype) |
616 | { | 242 | { |
@@ -650,12 +276,6 @@ static bool _rtl92c_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, | |||
650 | return true; | 276 | return true; |
651 | } | 277 | } |
652 | 278 | ||
653 | static bool _rtl92c_phy_config_rf_external_pa(struct ieee80211_hw *hw, | ||
654 | enum radio_path rfpath) | ||
655 | { | ||
656 | return true; | ||
657 | } | ||
658 | |||
659 | bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, | 279 | bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, |
660 | enum radio_path rfpath) | 280 | enum radio_path rfpath) |
661 | { | 281 | { |
@@ -747,345 +367,6 @@ bool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, | |||
747 | return true; | 367 | return true; |
748 | } | 368 | } |
749 | 369 | ||
750 | void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) | ||
751 | { | ||
752 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
753 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
754 | |||
755 | rtlphy->default_initialgain[0] = | ||
756 | (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0); | ||
757 | rtlphy->default_initialgain[1] = | ||
758 | (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0); | ||
759 | rtlphy->default_initialgain[2] = | ||
760 | (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0); | ||
761 | rtlphy->default_initialgain[3] = | ||
762 | (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0); | ||
763 | |||
764 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
765 | ("Default initial gain (c50=0x%x, " | ||
766 | "c58=0x%x, c60=0x%x, c68=0x%x\n", | ||
767 | rtlphy->default_initialgain[0], | ||
768 | rtlphy->default_initialgain[1], | ||
769 | rtlphy->default_initialgain[2], | ||
770 | rtlphy->default_initialgain[3])); | ||
771 | |||
772 | rtlphy->framesync = (u8) rtl_get_bbreg(hw, | ||
773 | ROFDM0_RXDETECTOR3, MASKBYTE0); | ||
774 | rtlphy->framesync_c34 = rtl_get_bbreg(hw, | ||
775 | ROFDM0_RXDETECTOR2, MASKDWORD); | ||
776 | |||
777 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | ||
778 | ("Default framesync (0x%x) = 0x%x\n", | ||
779 | ROFDM0_RXDETECTOR3, rtlphy->framesync)); | ||
780 | } | ||
781 | |||
782 | static void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) | ||
783 | { | ||
784 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
785 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
786 | |||
787 | rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW; | ||
788 | rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW; | ||
789 | rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW; | ||
790 | rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW; | ||
791 | |||
792 | rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB; | ||
793 | rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB; | ||
794 | rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB; | ||
795 | rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB; | ||
796 | |||
797 | rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE; | ||
798 | rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE; | ||
799 | |||
800 | rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE; | ||
801 | rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE; | ||
802 | |||
803 | rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = | ||
804 | RFPGA0_XA_LSSIPARAMETER; | ||
805 | rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = | ||
806 | RFPGA0_XB_LSSIPARAMETER; | ||
807 | |||
808 | rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = rFPGA0_XAB_RFPARAMETER; | ||
809 | rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = rFPGA0_XAB_RFPARAMETER; | ||
810 | rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = rFPGA0_XCD_RFPARAMETER; | ||
811 | rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = rFPGA0_XCD_RFPARAMETER; | ||
812 | |||
813 | rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE; | ||
814 | rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE; | ||
815 | rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE; | ||
816 | rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE; | ||
817 | |||
818 | rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1; | ||
819 | rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1; | ||
820 | |||
821 | rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2; | ||
822 | rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2; | ||
823 | |||
824 | rtlphy->phyreg_def[RF90_PATH_A].rfswitch_control = | ||
825 | RFPGA0_XAB_SWITCHCONTROL; | ||
826 | rtlphy->phyreg_def[RF90_PATH_B].rfswitch_control = | ||
827 | RFPGA0_XAB_SWITCHCONTROL; | ||
828 | rtlphy->phyreg_def[RF90_PATH_C].rfswitch_control = | ||
829 | RFPGA0_XCD_SWITCHCONTROL; | ||
830 | rtlphy->phyreg_def[RF90_PATH_D].rfswitch_control = | ||
831 | RFPGA0_XCD_SWITCHCONTROL; | ||
832 | |||
833 | rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1; | ||
834 | rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1; | ||
835 | rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1; | ||
836 | rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1; | ||
837 | |||
838 | rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2; | ||
839 | rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2; | ||
840 | rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2; | ||
841 | rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2; | ||
842 | |||
843 | rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbalance = | ||
844 | ROFDM0_XARXIQIMBALANCE; | ||
845 | rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbalance = | ||
846 | ROFDM0_XBRXIQIMBALANCE; | ||
847 | rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbalance = | ||
848 | ROFDM0_XCRXIQIMBANLANCE; | ||
849 | rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbalance = | ||
850 | ROFDM0_XDRXIQIMBALANCE; | ||
851 | |||
852 | rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE; | ||
853 | rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE; | ||
854 | rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE; | ||
855 | rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE; | ||
856 | |||
857 | rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbalance = | ||
858 | ROFDM0_XATXIQIMBALANCE; | ||
859 | rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbalance = | ||
860 | ROFDM0_XBTXIQIMBALANCE; | ||
861 | rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbalance = | ||
862 | ROFDM0_XCTXIQIMBALANCE; | ||
863 | rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbalance = | ||
864 | ROFDM0_XDTXIQIMBALANCE; | ||
865 | |||
866 | rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE; | ||
867 | rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE; | ||
868 | rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE; | ||
869 | rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE; | ||
870 | |||
871 | rtlphy->phyreg_def[RF90_PATH_A].rflssi_readback = | ||
872 | RFPGA0_XA_LSSIREADBACK; | ||
873 | rtlphy->phyreg_def[RF90_PATH_B].rflssi_readback = | ||
874 | RFPGA0_XB_LSSIREADBACK; | ||
875 | rtlphy->phyreg_def[RF90_PATH_C].rflssi_readback = | ||
876 | RFPGA0_XC_LSSIREADBACK; | ||
877 | rtlphy->phyreg_def[RF90_PATH_D].rflssi_readback = | ||
878 | RFPGA0_XD_LSSIREADBACK; | ||
879 | |||
880 | rtlphy->phyreg_def[RF90_PATH_A].rflssi_readbackpi = | ||
881 | TRANSCEIVEA_HSPI_READBACK; | ||
882 | rtlphy->phyreg_def[RF90_PATH_B].rflssi_readbackpi = | ||
883 | TRANSCEIVEB_HSPI_READBACK; | ||
884 | |||
885 | } | ||
886 | |||
887 | void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel) | ||
888 | { | ||
889 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
890 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
891 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
892 | u8 txpwr_level; | ||
893 | long txpwr_dbm; | ||
894 | |||
895 | txpwr_level = rtlphy->cur_cck_txpwridx; | ||
896 | txpwr_dbm = _rtl92c_phy_txpwr_idx_to_dbm(hw, | ||
897 | WIRELESS_MODE_B, txpwr_level); | ||
898 | txpwr_level = rtlphy->cur_ofdm24g_txpwridx + | ||
899 | rtlefuse->legacy_ht_txpowerdiff; | ||
900 | if (_rtl92c_phy_txpwr_idx_to_dbm(hw, | ||
901 | WIRELESS_MODE_G, | ||
902 | txpwr_level) > txpwr_dbm) | ||
903 | txpwr_dbm = | ||
904 | _rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, | ||
905 | txpwr_level); | ||
906 | txpwr_level = rtlphy->cur_ofdm24g_txpwridx; | ||
907 | if (_rtl92c_phy_txpwr_idx_to_dbm(hw, | ||
908 | WIRELESS_MODE_N_24G, | ||
909 | txpwr_level) > txpwr_dbm) | ||
910 | txpwr_dbm = | ||
911 | _rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G, | ||
912 | txpwr_level); | ||
913 | *powerlevel = txpwr_dbm; | ||
914 | } | ||
915 | |||
916 | static void _rtl92c_get_txpower_index(struct ieee80211_hw *hw, u8 channel, | ||
917 | u8 *cckpowerlevel, u8 *ofdmpowerlevel) | ||
918 | { | ||
919 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
920 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
921 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
922 | u8 index = (channel - 1); | ||
923 | |||
924 | cckpowerlevel[RF90_PATH_A] = | ||
925 | rtlefuse->txpwrlevel_cck[RF90_PATH_A][index]; | ||
926 | cckpowerlevel[RF90_PATH_B] = | ||
927 | rtlefuse->txpwrlevel_cck[RF90_PATH_B][index]; | ||
928 | if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_1T1R) { | ||
929 | ofdmpowerlevel[RF90_PATH_A] = | ||
930 | rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index]; | ||
931 | ofdmpowerlevel[RF90_PATH_B] = | ||
932 | rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index]; | ||
933 | } else if (get_rf_type(rtlphy) == RF_2T2R) { | ||
934 | ofdmpowerlevel[RF90_PATH_A] = | ||
935 | rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_A][index]; | ||
936 | ofdmpowerlevel[RF90_PATH_B] = | ||
937 | rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_B][index]; | ||
938 | } | ||
939 | } | ||
940 | |||
941 | static void _rtl92c_ccxpower_index_check(struct ieee80211_hw *hw, | ||
942 | u8 channel, u8 *cckpowerlevel, | ||
943 | u8 *ofdmpowerlevel) | ||
944 | { | ||
945 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
946 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
947 | |||
948 | rtlphy->cur_cck_txpwridx = cckpowerlevel[0]; | ||
949 | rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0]; | ||
950 | } | ||
951 | |||
952 | void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel) | ||
953 | { | ||
954 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
955 | u8 cckpowerlevel[2], ofdmpowerlevel[2]; | ||
956 | |||
957 | if (rtlefuse->txpwr_fromeprom == false) | ||
958 | return; | ||
959 | _rtl92c_get_txpower_index(hw, channel, | ||
960 | &cckpowerlevel[0], &ofdmpowerlevel[0]); | ||
961 | _rtl92c_ccxpower_index_check(hw, | ||
962 | channel, &cckpowerlevel[0], | ||
963 | &ofdmpowerlevel[0]); | ||
964 | rtl92c_phy_rf6052_set_cck_txpower(hw, &cckpowerlevel[0]); | ||
965 | rtl92c_phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0], channel); | ||
966 | } | ||
967 | |||
968 | bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm) | ||
969 | { | ||
970 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
971 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
972 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
973 | u8 idx; | ||
974 | u8 rf_path; | ||
975 | |||
976 | u8 ccktxpwridx = _rtl92c_phy_dbm_to_txpwr_Idx(hw, | ||
977 | WIRELESS_MODE_B, | ||
978 | power_indbm); | ||
979 | u8 ofdmtxpwridx = _rtl92c_phy_dbm_to_txpwr_Idx(hw, | ||
980 | WIRELESS_MODE_N_24G, | ||
981 | power_indbm); | ||
982 | if (ofdmtxpwridx - rtlefuse->legacy_ht_txpowerdiff > 0) | ||
983 | ofdmtxpwridx -= rtlefuse->legacy_ht_txpowerdiff; | ||
984 | else | ||
985 | ofdmtxpwridx = 0; | ||
986 | RT_TRACE(rtlpriv, COMP_TXAGC, DBG_TRACE, | ||
987 | ("%lx dBm, ccktxpwridx = %d, ofdmtxpwridx = %d\n", | ||
988 | power_indbm, ccktxpwridx, ofdmtxpwridx)); | ||
989 | for (idx = 0; idx < 14; idx++) { | ||
990 | for (rf_path = 0; rf_path < 2; rf_path++) { | ||
991 | rtlefuse->txpwrlevel_cck[rf_path][idx] = ccktxpwridx; | ||
992 | rtlefuse->txpwrlevel_ht40_1s[rf_path][idx] = | ||
993 | ofdmtxpwridx; | ||
994 | rtlefuse->txpwrlevel_ht40_2s[rf_path][idx] = | ||
995 | ofdmtxpwridx; | ||
996 | } | ||
997 | } | ||
998 | rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); | ||
999 | return true; | ||
1000 | } | ||
1001 | |||
1002 | void rtl92c_phy_set_beacon_hw_reg(struct ieee80211_hw *hw, u16 beaconinterval) | ||
1003 | { | ||
1004 | } | ||
1005 | |||
1006 | static u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw, | ||
1007 | enum wireless_mode wirelessmode, | ||
1008 | long power_indbm) | ||
1009 | { | ||
1010 | u8 txpwridx; | ||
1011 | long offset; | ||
1012 | |||
1013 | switch (wirelessmode) { | ||
1014 | case WIRELESS_MODE_B: | ||
1015 | offset = -7; | ||
1016 | break; | ||
1017 | case WIRELESS_MODE_G: | ||
1018 | case WIRELESS_MODE_N_24G: | ||
1019 | offset = -8; | ||
1020 | break; | ||
1021 | default: | ||
1022 | offset = -8; | ||
1023 | break; | ||
1024 | } | ||
1025 | |||
1026 | if ((power_indbm - offset) > 0) | ||
1027 | txpwridx = (u8) ((power_indbm - offset) * 2); | ||
1028 | else | ||
1029 | txpwridx = 0; | ||
1030 | |||
1031 | if (txpwridx > MAX_TXPWR_IDX_NMODE_92S) | ||
1032 | txpwridx = MAX_TXPWR_IDX_NMODE_92S; | ||
1033 | |||
1034 | return txpwridx; | ||
1035 | } | ||
1036 | |||
1037 | static long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, | ||
1038 | enum wireless_mode wirelessmode, | ||
1039 | u8 txpwridx) | ||
1040 | { | ||
1041 | long offset; | ||
1042 | long pwrout_dbm; | ||
1043 | |||
1044 | switch (wirelessmode) { | ||
1045 | case WIRELESS_MODE_B: | ||
1046 | offset = -7; | ||
1047 | break; | ||
1048 | case WIRELESS_MODE_G: | ||
1049 | case WIRELESS_MODE_N_24G: | ||
1050 | offset = -8; | ||
1051 | break; | ||
1052 | default: | ||
1053 | offset = -8; | ||
1054 | break; | ||
1055 | } | ||
1056 | pwrout_dbm = txpwridx / 2 + offset; | ||
1057 | return pwrout_dbm; | ||
1058 | } | ||
1059 | |||
1060 | void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) | ||
1061 | { | ||
1062 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1063 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1064 | enum io_type iotype; | ||
1065 | |||
1066 | if (!is_hal_stop(rtlhal)) { | ||
1067 | switch (operation) { | ||
1068 | case SCAN_OPT_BACKUP: | ||
1069 | iotype = IO_CMD_PAUSE_DM_BY_SCAN; | ||
1070 | rtlpriv->cfg->ops->set_hw_reg(hw, | ||
1071 | HW_VAR_IO_CMD, | ||
1072 | (u8 *)&iotype); | ||
1073 | |||
1074 | break; | ||
1075 | case SCAN_OPT_RESTORE: | ||
1076 | iotype = IO_CMD_RESUME_DM_BY_SCAN; | ||
1077 | rtlpriv->cfg->ops->set_hw_reg(hw, | ||
1078 | HW_VAR_IO_CMD, | ||
1079 | (u8 *)&iotype); | ||
1080 | break; | ||
1081 | default: | ||
1082 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
1083 | ("Unknown Scan Backup operation.\n")); | ||
1084 | break; | ||
1085 | } | ||
1086 | } | ||
1087 | } | ||
1088 | |||
1089 | void rtl92c_phy_set_bw_mode_callback(struct ieee80211_hw *hw) | 370 | void rtl92c_phy_set_bw_mode_callback(struct ieee80211_hw *hw) |
1090 | { | 371 | { |
1091 | struct rtl_priv *rtlpriv = rtl_priv(hw); | 372 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
@@ -1154,644 +435,6 @@ void rtl92c_phy_set_bw_mode_callback(struct ieee80211_hw *hw) | |||
1154 | RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); | 435 | RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); |
1155 | } | 436 | } |
1156 | 437 | ||
1157 | void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw, | ||
1158 | enum nl80211_channel_type ch_type) | ||
1159 | { | ||
1160 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1161 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1162 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1163 | u8 tmp_bw = rtlphy->current_chan_bw; | ||
1164 | |||
1165 | if (rtlphy->set_bwmode_inprogress) | ||
1166 | return; | ||
1167 | rtlphy->set_bwmode_inprogress = true; | ||
1168 | if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) | ||
1169 | rtl92c_phy_set_bw_mode_callback(hw); | ||
1170 | else { | ||
1171 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, | ||
1172 | ("FALSE driver sleep or unload\n")); | ||
1173 | rtlphy->set_bwmode_inprogress = false; | ||
1174 | rtlphy->current_chan_bw = tmp_bw; | ||
1175 | } | ||
1176 | } | ||
1177 | |||
1178 | void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw) | ||
1179 | { | ||
1180 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1181 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1182 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1183 | u32 delay; | ||
1184 | |||
1185 | RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, | ||
1186 | ("switch to channel%d\n", rtlphy->current_channel)); | ||
1187 | if (is_hal_stop(rtlhal)) | ||
1188 | return; | ||
1189 | do { | ||
1190 | if (!rtlphy->sw_chnl_inprogress) | ||
1191 | break; | ||
1192 | if (!_rtl92c_phy_sw_chnl_step_by_step | ||
1193 | (hw, rtlphy->current_channel, &rtlphy->sw_chnl_stage, | ||
1194 | &rtlphy->sw_chnl_step, &delay)) { | ||
1195 | if (delay > 0) | ||
1196 | mdelay(delay); | ||
1197 | else | ||
1198 | continue; | ||
1199 | } else | ||
1200 | rtlphy->sw_chnl_inprogress = false; | ||
1201 | break; | ||
1202 | } while (true); | ||
1203 | RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, ("<==\n")); | ||
1204 | } | ||
1205 | |||
1206 | u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw) | ||
1207 | { | ||
1208 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1209 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1210 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1211 | |||
1212 | if (rtlphy->sw_chnl_inprogress) | ||
1213 | return 0; | ||
1214 | if (rtlphy->set_bwmode_inprogress) | ||
1215 | return 0; | ||
1216 | RT_ASSERT((rtlphy->current_channel <= 14), | ||
1217 | ("WIRELESS_MODE_G but channel>14")); | ||
1218 | rtlphy->sw_chnl_inprogress = true; | ||
1219 | rtlphy->sw_chnl_stage = 0; | ||
1220 | rtlphy->sw_chnl_step = 0; | ||
1221 | if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { | ||
1222 | rtl92c_phy_sw_chnl_callback(hw); | ||
1223 | RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, | ||
1224 | ("sw_chnl_inprogress false schdule workitem\n")); | ||
1225 | rtlphy->sw_chnl_inprogress = false; | ||
1226 | } else { | ||
1227 | RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, | ||
1228 | ("sw_chnl_inprogress false driver sleep or" | ||
1229 | " unload\n")); | ||
1230 | rtlphy->sw_chnl_inprogress = false; | ||
1231 | } | ||
1232 | return 1; | ||
1233 | } | ||
1234 | |||
1235 | static bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, | ||
1236 | u8 channel, u8 *stage, u8 *step, | ||
1237 | u32 *delay) | ||
1238 | { | ||
1239 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1240 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1241 | struct swchnlcmd precommoncmd[MAX_PRECMD_CNT]; | ||
1242 | u32 precommoncmdcnt; | ||
1243 | struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT]; | ||
1244 | u32 postcommoncmdcnt; | ||
1245 | struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT]; | ||
1246 | u32 rfdependcmdcnt; | ||
1247 | struct swchnlcmd *currentcmd = NULL; | ||
1248 | u8 rfpath; | ||
1249 | u8 num_total_rfpath = rtlphy->num_total_rfpath; | ||
1250 | |||
1251 | precommoncmdcnt = 0; | ||
1252 | _rtl92c_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, | ||
1253 | MAX_PRECMD_CNT, | ||
1254 | CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0); | ||
1255 | _rtl92c_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, | ||
1256 | MAX_PRECMD_CNT, CMDID_END, 0, 0, 0); | ||
1257 | |||
1258 | postcommoncmdcnt = 0; | ||
1259 | |||
1260 | _rtl92c_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++, | ||
1261 | MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0); | ||
1262 | |||
1263 | rfdependcmdcnt = 0; | ||
1264 | |||
1265 | RT_ASSERT((channel >= 1 && channel <= 14), | ||
1266 | ("illegal channel for Zebra: %d\n", channel)); | ||
1267 | |||
1268 | _rtl92c_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, | ||
1269 | MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG, | ||
1270 | RF_CHNLBW, channel, 10); | ||
1271 | |||
1272 | _rtl92c_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, | ||
1273 | MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0, | ||
1274 | 0); | ||
1275 | |||
1276 | do { | ||
1277 | switch (*stage) { | ||
1278 | case 0: | ||
1279 | currentcmd = &precommoncmd[*step]; | ||
1280 | break; | ||
1281 | case 1: | ||
1282 | currentcmd = &rfdependcmd[*step]; | ||
1283 | break; | ||
1284 | case 2: | ||
1285 | currentcmd = &postcommoncmd[*step]; | ||
1286 | break; | ||
1287 | } | ||
1288 | |||
1289 | if (currentcmd->cmdid == CMDID_END) { | ||
1290 | if ((*stage) == 2) { | ||
1291 | return true; | ||
1292 | } else { | ||
1293 | (*stage)++; | ||
1294 | (*step) = 0; | ||
1295 | continue; | ||
1296 | } | ||
1297 | } | ||
1298 | |||
1299 | switch (currentcmd->cmdid) { | ||
1300 | case CMDID_SET_TXPOWEROWER_LEVEL: | ||
1301 | rtl92c_phy_set_txpower_level(hw, channel); | ||
1302 | break; | ||
1303 | case CMDID_WRITEPORT_ULONG: | ||
1304 | rtl_write_dword(rtlpriv, currentcmd->para1, | ||
1305 | currentcmd->para2); | ||
1306 | break; | ||
1307 | case CMDID_WRITEPORT_USHORT: | ||
1308 | rtl_write_word(rtlpriv, currentcmd->para1, | ||
1309 | (u16) currentcmd->para2); | ||
1310 | break; | ||
1311 | case CMDID_WRITEPORT_UCHAR: | ||
1312 | rtl_write_byte(rtlpriv, currentcmd->para1, | ||
1313 | (u8) currentcmd->para2); | ||
1314 | break; | ||
1315 | case CMDID_RF_WRITEREG: | ||
1316 | for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) { | ||
1317 | rtlphy->rfreg_chnlval[rfpath] = | ||
1318 | ((rtlphy->rfreg_chnlval[rfpath] & | ||
1319 | 0xfffffc00) | currentcmd->para2); | ||
1320 | |||
1321 | rtl_set_rfreg(hw, (enum radio_path)rfpath, | ||
1322 | currentcmd->para1, | ||
1323 | RFREG_OFFSET_MASK, | ||
1324 | rtlphy->rfreg_chnlval[rfpath]); | ||
1325 | } | ||
1326 | break; | ||
1327 | default: | ||
1328 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
1329 | ("switch case not process\n")); | ||
1330 | break; | ||
1331 | } | ||
1332 | |||
1333 | break; | ||
1334 | } while (true); | ||
1335 | |||
1336 | (*delay) = currentcmd->msdelay; | ||
1337 | (*step)++; | ||
1338 | return false; | ||
1339 | } | ||
1340 | |||
1341 | static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, | ||
1342 | u32 cmdtableidx, u32 cmdtablesz, | ||
1343 | enum swchnlcmd_id cmdid, | ||
1344 | u32 para1, u32 para2, u32 msdelay) | ||
1345 | { | ||
1346 | struct swchnlcmd *pcmd; | ||
1347 | |||
1348 | if (cmdtable == NULL) { | ||
1349 | RT_ASSERT(false, ("cmdtable cannot be NULL.\n")); | ||
1350 | return false; | ||
1351 | } | ||
1352 | |||
1353 | if (cmdtableidx >= cmdtablesz) | ||
1354 | return false; | ||
1355 | |||
1356 | pcmd = cmdtable + cmdtableidx; | ||
1357 | pcmd->cmdid = cmdid; | ||
1358 | pcmd->para1 = para1; | ||
1359 | pcmd->para2 = para2; | ||
1360 | pcmd->msdelay = msdelay; | ||
1361 | return true; | ||
1362 | } | ||
1363 | |||
1364 | bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, u32 rfpath) | ||
1365 | { | ||
1366 | return true; | ||
1367 | } | ||
1368 | |||
1369 | static u8 _rtl92c_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb) | ||
1370 | { | ||
1371 | u32 reg_eac, reg_e94, reg_e9c, reg_ea4; | ||
1372 | u8 result = 0x00; | ||
1373 | |||
1374 | rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1f); | ||
1375 | rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x10008c1f); | ||
1376 | rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x82140102); | ||
1377 | rtl_set_bbreg(hw, 0xe3c, MASKDWORD, | ||
1378 | config_pathb ? 0x28160202 : 0x28160502); | ||
1379 | |||
1380 | if (config_pathb) { | ||
1381 | rtl_set_bbreg(hw, 0xe50, MASKDWORD, 0x10008c22); | ||
1382 | rtl_set_bbreg(hw, 0xe54, MASKDWORD, 0x10008c22); | ||
1383 | rtl_set_bbreg(hw, 0xe58, MASKDWORD, 0x82140102); | ||
1384 | rtl_set_bbreg(hw, 0xe5c, MASKDWORD, 0x28160202); | ||
1385 | } | ||
1386 | |||
1387 | rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x001028d1); | ||
1388 | rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000); | ||
1389 | rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000); | ||
1390 | |||
1391 | mdelay(IQK_DELAY_TIME); | ||
1392 | |||
1393 | reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); | ||
1394 | reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD); | ||
1395 | reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD); | ||
1396 | reg_ea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD); | ||
1397 | |||
1398 | if (!(reg_eac & BIT(28)) && | ||
1399 | (((reg_e94 & 0x03FF0000) >> 16) != 0x142) && | ||
1400 | (((reg_e9c & 0x03FF0000) >> 16) != 0x42)) | ||
1401 | result |= 0x01; | ||
1402 | else | ||
1403 | return result; | ||
1404 | |||
1405 | if (!(reg_eac & BIT(27)) && | ||
1406 | (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) && | ||
1407 | (((reg_eac & 0x03FF0000) >> 16) != 0x36)) | ||
1408 | result |= 0x02; | ||
1409 | return result; | ||
1410 | } | ||
1411 | |||
1412 | static u8 _rtl92c_phy_path_b_iqk(struct ieee80211_hw *hw) | ||
1413 | { | ||
1414 | u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc; | ||
1415 | u8 result = 0x00; | ||
1416 | |||
1417 | rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000002); | ||
1418 | rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000000); | ||
1419 | mdelay(IQK_DELAY_TIME); | ||
1420 | reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); | ||
1421 | reg_eb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD); | ||
1422 | reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD); | ||
1423 | reg_ec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD); | ||
1424 | reg_ecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD); | ||
1425 | if (!(reg_eac & BIT(31)) && | ||
1426 | (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) && | ||
1427 | (((reg_ebc & 0x03FF0000) >> 16) != 0x42)) | ||
1428 | result |= 0x01; | ||
1429 | else | ||
1430 | return result; | ||
1431 | |||
1432 | if (!(reg_eac & BIT(30)) && | ||
1433 | (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) && | ||
1434 | (((reg_ecc & 0x03FF0000) >> 16) != 0x36)) | ||
1435 | result |= 0x02; | ||
1436 | return result; | ||
1437 | } | ||
1438 | |||
1439 | static void _rtl92c_phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw, | ||
1440 | bool iqk_ok, long result[][8], | ||
1441 | u8 final_candidate, bool btxonly) | ||
1442 | { | ||
1443 | u32 oldval_0, x, tx0_a, reg; | ||
1444 | long y, tx0_c; | ||
1445 | |||
1446 | if (final_candidate == 0xFF) | ||
1447 | return; | ||
1448 | else if (iqk_ok) { | ||
1449 | oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, | ||
1450 | MASKDWORD) >> 22) & 0x3FF; | ||
1451 | x = result[final_candidate][0]; | ||
1452 | if ((x & 0x00000200) != 0) | ||
1453 | x = x | 0xFFFFFC00; | ||
1454 | tx0_a = (x * oldval_0) >> 8; | ||
1455 | rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx0_a); | ||
1456 | rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(31), | ||
1457 | ((x * oldval_0 >> 7) & 0x1)); | ||
1458 | y = result[final_candidate][1]; | ||
1459 | if ((y & 0x00000200) != 0) | ||
1460 | y = y | 0xFFFFFC00; | ||
1461 | tx0_c = (y * oldval_0) >> 8; | ||
1462 | rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000, | ||
1463 | ((tx0_c & 0x3C0) >> 6)); | ||
1464 | rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x003F0000, | ||
1465 | (tx0_c & 0x3F)); | ||
1466 | rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(29), | ||
1467 | ((y * oldval_0 >> 7) & 0x1)); | ||
1468 | if (btxonly) | ||
1469 | return; | ||
1470 | reg = result[final_candidate][2]; | ||
1471 | rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg); | ||
1472 | reg = result[final_candidate][3] & 0x3F; | ||
1473 | rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg); | ||
1474 | reg = (result[final_candidate][3] >> 6) & 0xF; | ||
1475 | rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg); | ||
1476 | } | ||
1477 | } | ||
1478 | |||
1479 | static void _rtl92c_phy_path_b_fill_iqk_matrix(struct ieee80211_hw *hw, | ||
1480 | bool iqk_ok, long result[][8], | ||
1481 | u8 final_candidate, bool btxonly) | ||
1482 | { | ||
1483 | u32 oldval_1, x, tx1_a, reg; | ||
1484 | long y, tx1_c; | ||
1485 | |||
1486 | if (final_candidate == 0xFF) | ||
1487 | return; | ||
1488 | else if (iqk_ok) { | ||
1489 | oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, | ||
1490 | MASKDWORD) >> 22) & 0x3FF; | ||
1491 | x = result[final_candidate][4]; | ||
1492 | if ((x & 0x00000200) != 0) | ||
1493 | x = x | 0xFFFFFC00; | ||
1494 | tx1_a = (x * oldval_1) >> 8; | ||
1495 | rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x3FF, tx1_a); | ||
1496 | rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(27), | ||
1497 | ((x * oldval_1 >> 7) & 0x1)); | ||
1498 | y = result[final_candidate][5]; | ||
1499 | if ((y & 0x00000200) != 0) | ||
1500 | y = y | 0xFFFFFC00; | ||
1501 | tx1_c = (y * oldval_1) >> 8; | ||
1502 | rtl_set_bbreg(hw, ROFDM0_XDTXAFE, 0xF0000000, | ||
1503 | ((tx1_c & 0x3C0) >> 6)); | ||
1504 | rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x003F0000, | ||
1505 | (tx1_c & 0x3F)); | ||
1506 | rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(25), | ||
1507 | ((y * oldval_1 >> 7) & 0x1)); | ||
1508 | if (btxonly) | ||
1509 | return; | ||
1510 | reg = result[final_candidate][6]; | ||
1511 | rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg); | ||
1512 | reg = result[final_candidate][7] & 0x3F; | ||
1513 | rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg); | ||
1514 | reg = (result[final_candidate][7] >> 6) & 0xF; | ||
1515 | rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, 0x0000F000, reg); | ||
1516 | } | ||
1517 | } | ||
1518 | |||
1519 | static void _rtl92c_phy_save_adda_registers(struct ieee80211_hw *hw, | ||
1520 | u32 *addareg, u32 *addabackup, | ||
1521 | u32 registernum) | ||
1522 | { | ||
1523 | u32 i; | ||
1524 | |||
1525 | for (i = 0; i < registernum; i++) | ||
1526 | addabackup[i] = rtl_get_bbreg(hw, addareg[i], MASKDWORD); | ||
1527 | } | ||
1528 | |||
1529 | static void _rtl92c_phy_save_mac_registers(struct ieee80211_hw *hw, | ||
1530 | u32 *macreg, u32 *macbackup) | ||
1531 | { | ||
1532 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1533 | u32 i; | ||
1534 | |||
1535 | for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) | ||
1536 | macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]); | ||
1537 | macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]); | ||
1538 | } | ||
1539 | |||
1540 | static void _rtl92c_phy_reload_adda_registers(struct ieee80211_hw *hw, | ||
1541 | u32 *addareg, u32 *addabackup, | ||
1542 | u32 regiesternum) | ||
1543 | { | ||
1544 | u32 i; | ||
1545 | |||
1546 | for (i = 0; i < regiesternum; i++) | ||
1547 | rtl_set_bbreg(hw, addareg[i], MASKDWORD, addabackup[i]); | ||
1548 | } | ||
1549 | |||
1550 | static void _rtl92c_phy_reload_mac_registers(struct ieee80211_hw *hw, | ||
1551 | u32 *macreg, u32 *macbackup) | ||
1552 | { | ||
1553 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1554 | u32 i; | ||
1555 | |||
1556 | for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) | ||
1557 | rtl_write_byte(rtlpriv, macreg[i], (u8) macbackup[i]); | ||
1558 | rtl_write_dword(rtlpriv, macreg[i], macbackup[i]); | ||
1559 | } | ||
1560 | |||
1561 | static void _rtl92c_phy_path_adda_on(struct ieee80211_hw *hw, | ||
1562 | u32 *addareg, bool is_patha_on, bool is2t) | ||
1563 | { | ||
1564 | u32 pathOn; | ||
1565 | u32 i; | ||
1566 | |||
1567 | pathOn = is_patha_on ? 0x04db25a4 : 0x0b1b25a4; | ||
1568 | if (false == is2t) { | ||
1569 | pathOn = 0x0bdb25a0; | ||
1570 | rtl_set_bbreg(hw, addareg[0], MASKDWORD, 0x0b1b25a0); | ||
1571 | } else { | ||
1572 | rtl_set_bbreg(hw, addareg[0], MASKDWORD, pathOn); | ||
1573 | } | ||
1574 | |||
1575 | for (i = 1; i < IQK_ADDA_REG_NUM; i++) | ||
1576 | rtl_set_bbreg(hw, addareg[i], MASKDWORD, pathOn); | ||
1577 | } | ||
1578 | |||
1579 | static void _rtl92c_phy_mac_setting_calibration(struct ieee80211_hw *hw, | ||
1580 | u32 *macreg, u32 *macbackup) | ||
1581 | { | ||
1582 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1583 | u32 i; | ||
1584 | |||
1585 | rtl_write_byte(rtlpriv, macreg[0], 0x3F); | ||
1586 | |||
1587 | for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++) | ||
1588 | rtl_write_byte(rtlpriv, macreg[i], | ||
1589 | (u8) (macbackup[i] & (~BIT(3)))); | ||
1590 | rtl_write_byte(rtlpriv, macreg[i], (u8) (macbackup[i] & (~BIT(5)))); | ||
1591 | } | ||
1592 | |||
1593 | static void _rtl92c_phy_path_a_standby(struct ieee80211_hw *hw) | ||
1594 | { | ||
1595 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0); | ||
1596 | rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000); | ||
1597 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); | ||
1598 | } | ||
1599 | |||
1600 | static void _rtl92c_phy_pi_mode_switch(struct ieee80211_hw *hw, bool pi_mode) | ||
1601 | { | ||
1602 | u32 mode; | ||
1603 | |||
1604 | mode = pi_mode ? 0x01000100 : 0x01000000; | ||
1605 | rtl_set_bbreg(hw, 0x820, MASKDWORD, mode); | ||
1606 | rtl_set_bbreg(hw, 0x828, MASKDWORD, mode); | ||
1607 | } | ||
1608 | |||
1609 | static bool _rtl92c_phy_simularity_compare(struct ieee80211_hw *hw, | ||
1610 | long result[][8], u8 c1, u8 c2) | ||
1611 | { | ||
1612 | u32 i, j, diff, simularity_bitmap, bound; | ||
1613 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
1614 | |||
1615 | u8 final_candidate[2] = { 0xFF, 0xFF }; | ||
1616 | bool bresult = true, is2t = IS_92C_SERIAL(rtlhal->version); | ||
1617 | |||
1618 | if (is2t) | ||
1619 | bound = 8; | ||
1620 | else | ||
1621 | bound = 4; | ||
1622 | |||
1623 | simularity_bitmap = 0; | ||
1624 | |||
1625 | for (i = 0; i < bound; i++) { | ||
1626 | diff = (result[c1][i] > result[c2][i]) ? | ||
1627 | (result[c1][i] - result[c2][i]) : | ||
1628 | (result[c2][i] - result[c1][i]); | ||
1629 | |||
1630 | if (diff > MAX_TOLERANCE) { | ||
1631 | if ((i == 2 || i == 6) && !simularity_bitmap) { | ||
1632 | if (result[c1][i] + result[c1][i + 1] == 0) | ||
1633 | final_candidate[(i / 4)] = c2; | ||
1634 | else if (result[c2][i] + result[c2][i + 1] == 0) | ||
1635 | final_candidate[(i / 4)] = c1; | ||
1636 | else | ||
1637 | simularity_bitmap = simularity_bitmap | | ||
1638 | (1 << i); | ||
1639 | } else | ||
1640 | simularity_bitmap = | ||
1641 | simularity_bitmap | (1 << i); | ||
1642 | } | ||
1643 | } | ||
1644 | |||
1645 | if (simularity_bitmap == 0) { | ||
1646 | for (i = 0; i < (bound / 4); i++) { | ||
1647 | if (final_candidate[i] != 0xFF) { | ||
1648 | for (j = i * 4; j < (i + 1) * 4 - 2; j++) | ||
1649 | result[3][j] = | ||
1650 | result[final_candidate[i]][j]; | ||
1651 | bresult = false; | ||
1652 | } | ||
1653 | } | ||
1654 | return bresult; | ||
1655 | } else if (!(simularity_bitmap & 0x0F)) { | ||
1656 | for (i = 0; i < 4; i++) | ||
1657 | result[3][i] = result[c1][i]; | ||
1658 | return false; | ||
1659 | } else if (!(simularity_bitmap & 0xF0) && is2t) { | ||
1660 | for (i = 4; i < 8; i++) | ||
1661 | result[3][i] = result[c1][i]; | ||
1662 | return false; | ||
1663 | } else { | ||
1664 | return false; | ||
1665 | } | ||
1666 | |||
1667 | } | ||
1668 | |||
1669 | static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, | ||
1670 | long result[][8], u8 t, bool is2t) | ||
1671 | { | ||
1672 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1673 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1674 | u32 i; | ||
1675 | u8 patha_ok, pathb_ok; | ||
1676 | u32 adda_reg[IQK_ADDA_REG_NUM] = { | ||
1677 | 0x85c, 0xe6c, 0xe70, 0xe74, | ||
1678 | 0xe78, 0xe7c, 0xe80, 0xe84, | ||
1679 | 0xe88, 0xe8c, 0xed0, 0xed4, | ||
1680 | 0xed8, 0xedc, 0xee0, 0xeec | ||
1681 | }; | ||
1682 | |||
1683 | u32 iqk_mac_reg[IQK_MAC_REG_NUM] = { | ||
1684 | 0x522, 0x550, 0x551, 0x040 | ||
1685 | }; | ||
1686 | |||
1687 | const u32 retrycount = 2; | ||
1688 | |||
1689 | u32 bbvalue; | ||
1690 | |||
1691 | if (t == 0) { | ||
1692 | bbvalue = rtl_get_bbreg(hw, 0x800, MASKDWORD); | ||
1693 | |||
1694 | _rtl92c_phy_save_adda_registers(hw, adda_reg, | ||
1695 | rtlphy->adda_backup, 16); | ||
1696 | _rtl92c_phy_save_mac_registers(hw, iqk_mac_reg, | ||
1697 | rtlphy->iqk_mac_backup); | ||
1698 | } | ||
1699 | _rtl92c_phy_path_adda_on(hw, adda_reg, true, is2t); | ||
1700 | if (t == 0) { | ||
1701 | rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw, | ||
1702 | RFPGA0_XA_HSSIPARAMETER1, | ||
1703 | BIT(8)); | ||
1704 | } | ||
1705 | if (!rtlphy->rfpi_enable) | ||
1706 | _rtl92c_phy_pi_mode_switch(hw, true); | ||
1707 | if (t == 0) { | ||
1708 | rtlphy->reg_c04 = rtl_get_bbreg(hw, 0xc04, MASKDWORD); | ||
1709 | rtlphy->reg_c08 = rtl_get_bbreg(hw, 0xc08, MASKDWORD); | ||
1710 | rtlphy->reg_874 = rtl_get_bbreg(hw, 0x874, MASKDWORD); | ||
1711 | } | ||
1712 | rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600); | ||
1713 | rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4); | ||
1714 | rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000); | ||
1715 | if (is2t) { | ||
1716 | rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000); | ||
1717 | rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000); | ||
1718 | } | ||
1719 | _rtl92c_phy_mac_setting_calibration(hw, iqk_mac_reg, | ||
1720 | rtlphy->iqk_mac_backup); | ||
1721 | rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x00080000); | ||
1722 | if (is2t) | ||
1723 | rtl_set_bbreg(hw, 0xb6c, MASKDWORD, 0x00080000); | ||
1724 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); | ||
1725 | rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00); | ||
1726 | rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x01004800); | ||
1727 | for (i = 0; i < retrycount; i++) { | ||
1728 | patha_ok = _rtl92c_phy_path_a_iqk(hw, is2t); | ||
1729 | if (patha_ok == 0x03) { | ||
1730 | result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) & | ||
1731 | 0x3FF0000) >> 16; | ||
1732 | result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & | ||
1733 | 0x3FF0000) >> 16; | ||
1734 | result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) & | ||
1735 | 0x3FF0000) >> 16; | ||
1736 | result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) & | ||
1737 | 0x3FF0000) >> 16; | ||
1738 | break; | ||
1739 | } else if (i == (retrycount - 1) && patha_ok == 0x01) | ||
1740 | result[t][0] = (rtl_get_bbreg(hw, 0xe94, | ||
1741 | MASKDWORD) & 0x3FF0000) >> | ||
1742 | 16; | ||
1743 | result[t][1] = | ||
1744 | (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & 0x3FF0000) >> 16; | ||
1745 | |||
1746 | } | ||
1747 | |||
1748 | if (is2t) { | ||
1749 | _rtl92c_phy_path_a_standby(hw); | ||
1750 | _rtl92c_phy_path_adda_on(hw, adda_reg, false, is2t); | ||
1751 | for (i = 0; i < retrycount; i++) { | ||
1752 | pathb_ok = _rtl92c_phy_path_b_iqk(hw); | ||
1753 | if (pathb_ok == 0x03) { | ||
1754 | result[t][4] = (rtl_get_bbreg(hw, | ||
1755 | 0xeb4, | ||
1756 | MASKDWORD) & | ||
1757 | 0x3FF0000) >> 16; | ||
1758 | result[t][5] = | ||
1759 | (rtl_get_bbreg(hw, 0xebc, MASKDWORD) & | ||
1760 | 0x3FF0000) >> 16; | ||
1761 | result[t][6] = | ||
1762 | (rtl_get_bbreg(hw, 0xec4, MASKDWORD) & | ||
1763 | 0x3FF0000) >> 16; | ||
1764 | result[t][7] = | ||
1765 | (rtl_get_bbreg(hw, 0xecc, MASKDWORD) & | ||
1766 | 0x3FF0000) >> 16; | ||
1767 | break; | ||
1768 | } else if (i == (retrycount - 1) && pathb_ok == 0x01) { | ||
1769 | result[t][4] = (rtl_get_bbreg(hw, | ||
1770 | 0xeb4, | ||
1771 | MASKDWORD) & | ||
1772 | 0x3FF0000) >> 16; | ||
1773 | } | ||
1774 | result[t][5] = (rtl_get_bbreg(hw, 0xebc, MASKDWORD) & | ||
1775 | 0x3FF0000) >> 16; | ||
1776 | } | ||
1777 | } | ||
1778 | rtl_set_bbreg(hw, 0xc04, MASKDWORD, rtlphy->reg_c04); | ||
1779 | rtl_set_bbreg(hw, 0x874, MASKDWORD, rtlphy->reg_874); | ||
1780 | rtl_set_bbreg(hw, 0xc08, MASKDWORD, rtlphy->reg_c08); | ||
1781 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0); | ||
1782 | rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3); | ||
1783 | if (is2t) | ||
1784 | rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3); | ||
1785 | if (t != 0) { | ||
1786 | if (!rtlphy->rfpi_enable) | ||
1787 | _rtl92c_phy_pi_mode_switch(hw, false); | ||
1788 | _rtl92c_phy_reload_adda_registers(hw, adda_reg, | ||
1789 | rtlphy->adda_backup, 16); | ||
1790 | _rtl92c_phy_reload_mac_registers(hw, iqk_mac_reg, | ||
1791 | rtlphy->iqk_mac_backup); | ||
1792 | } | ||
1793 | } | ||
1794 | |||
1795 | static void _rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) | 438 | static void _rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) |
1796 | { | 439 | { |
1797 | u8 tmpreg; | 440 | u8 tmpreg; |
@@ -1837,666 +480,6 @@ static void _rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) | |||
1837 | } | 480 | } |
1838 | } | 481 | } |
1839 | 482 | ||
1840 | static void _rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, | ||
1841 | char delta, bool is2t) | ||
1842 | { | ||
1843 | /* This routine is deliberately dummied out for later fixes */ | ||
1844 | #if 0 | ||
1845 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
1846 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
1847 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
1848 | |||
1849 | u32 reg_d[PATH_NUM]; | ||
1850 | u32 tmpreg, index, offset, path, i, pathbound = PATH_NUM, apkbound; | ||
1851 | |||
1852 | u32 bb_backup[APK_BB_REG_NUM]; | ||
1853 | u32 bb_reg[APK_BB_REG_NUM] = { | ||
1854 | 0x904, 0xc04, 0x800, 0xc08, 0x874 | ||
1855 | }; | ||
1856 | u32 bb_ap_mode[APK_BB_REG_NUM] = { | ||
1857 | 0x00000020, 0x00a05430, 0x02040000, | ||
1858 | 0x000800e4, 0x00204000 | ||
1859 | }; | ||
1860 | u32 bb_normal_ap_mode[APK_BB_REG_NUM] = { | ||
1861 | 0x00000020, 0x00a05430, 0x02040000, | ||
1862 | 0x000800e4, 0x22204000 | ||
1863 | }; | ||
1864 | |||
1865 | u32 afe_backup[APK_AFE_REG_NUM]; | ||
1866 | u32 afe_reg[APK_AFE_REG_NUM] = { | ||
1867 | 0x85c, 0xe6c, 0xe70, 0xe74, 0xe78, | ||
1868 | 0xe7c, 0xe80, 0xe84, 0xe88, 0xe8c, | ||
1869 | 0xed0, 0xed4, 0xed8, 0xedc, 0xee0, | ||
1870 | 0xeec | ||
1871 | }; | ||
1872 | |||
1873 | u32 mac_backup[IQK_MAC_REG_NUM]; | ||
1874 | u32 mac_reg[IQK_MAC_REG_NUM] = { | ||
1875 | 0x522, 0x550, 0x551, 0x040 | ||
1876 | }; | ||
1877 | |||
1878 | u32 apk_rf_init_value[PATH_NUM][APK_BB_REG_NUM] = { | ||
1879 | {0x0852c, 0x1852c, 0x5852c, 0x1852c, 0x5852c}, | ||
1880 | {0x2852e, 0x0852e, 0x3852e, 0x0852e, 0x0852e} | ||
1881 | }; | ||
1882 | |||
1883 | u32 apk_normal_rf_init_value[PATH_NUM][APK_BB_REG_NUM] = { | ||
1884 | {0x0852c, 0x0a52c, 0x3a52c, 0x5a52c, 0x5a52c}, | ||
1885 | {0x0852c, 0x0a52c, 0x5a52c, 0x5a52c, 0x5a52c} | ||
1886 | }; | ||
1887 | |||
1888 | u32 apk_rf_value_0[PATH_NUM][APK_BB_REG_NUM] = { | ||
1889 | {0x52019, 0x52014, 0x52013, 0x5200f, 0x5208d}, | ||
1890 | {0x5201a, 0x52019, 0x52016, 0x52033, 0x52050} | ||
1891 | }; | ||
1892 | |||
1893 | u32 apk_normal_rf_value_0[PATH_NUM][APK_BB_REG_NUM] = { | ||
1894 | {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a}, | ||
1895 | {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a} | ||
1896 | }; | ||
1897 | |||
1898 | u32 afe_on_off[PATH_NUM] = { | ||
1899 | 0x04db25a4, 0x0b1b25a4 | ||
1900 | }; | ||
1901 | |||
1902 | u32 apk_offset[PATH_NUM] = { 0xb68, 0xb6c }; | ||
1903 | |||
1904 | u32 apk_normal_offset[PATH_NUM] = { 0xb28, 0xb98 }; | ||
1905 | |||
1906 | u32 apk_value[PATH_NUM] = { 0x92fc0000, 0x12fc0000 }; | ||
1907 | |||
1908 | u32 apk_normal_value[PATH_NUM] = { 0x92680000, 0x12680000 }; | ||
1909 | |||
1910 | const char apk_delta_mapping[APK_BB_REG_NUM][13] = { | ||
1911 | {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6}, | ||
1912 | {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6}, | ||
1913 | {-6, -4, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6}, | ||
1914 | {-1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6}, | ||
1915 | {-11, -9, -7, -5, -3, -1, 0, 0, 0, 0, 0, 0, 0} | ||
1916 | }; | ||
1917 | |||
1918 | const u32 apk_normal_setting_value_1[13] = { | ||
1919 | 0x01017018, 0xf7ed8f84, 0x1b1a1816, 0x2522201e, 0x322e2b28, | ||
1920 | 0x433f3a36, 0x5b544e49, 0x7b726a62, 0xa69a8f84, 0xdfcfc0b3, | ||
1921 | 0x12680000, 0x00880000, 0x00880000 | ||
1922 | }; | ||
1923 | |||
1924 | const u32 apk_normal_setting_value_2[16] = { | ||
1925 | 0x01c7021d, 0x01670183, 0x01000123, 0x00bf00e2, 0x008d00a3, | ||
1926 | 0x0068007b, 0x004d0059, 0x003a0042, 0x002b0031, 0x001f0025, | ||
1927 | 0x0017001b, 0x00110014, 0x000c000f, 0x0009000b, 0x00070008, | ||
1928 | 0x00050006 | ||
1929 | }; | ||
1930 | |||
1931 | const u32 apk_result[PATH_NUM][APK_BB_REG_NUM]; | ||
1932 | |||
1933 | long bb_offset, delta_v, delta_offset; | ||
1934 | |||
1935 | if (!is2t) | ||
1936 | pathbound = 1; | ||
1937 | |||
1938 | for (index = 0; index < PATH_NUM; index++) { | ||
1939 | apk_offset[index] = apk_normal_offset[index]; | ||
1940 | apk_value[index] = apk_normal_value[index]; | ||
1941 | afe_on_off[index] = 0x6fdb25a4; | ||
1942 | } | ||
1943 | |||
1944 | for (index = 0; index < APK_BB_REG_NUM; index++) { | ||
1945 | for (path = 0; path < pathbound; path++) { | ||
1946 | apk_rf_init_value[path][index] = | ||
1947 | apk_normal_rf_init_value[path][index]; | ||
1948 | apk_rf_value_0[path][index] = | ||
1949 | apk_normal_rf_value_0[path][index]; | ||
1950 | } | ||
1951 | bb_ap_mode[index] = bb_normal_ap_mode[index]; | ||
1952 | |||
1953 | apkbound = 6; | ||
1954 | } | ||
1955 | |||
1956 | for (index = 0; index < APK_BB_REG_NUM; index++) { | ||
1957 | if (index == 0) | ||
1958 | continue; | ||
1959 | bb_backup[index] = rtl_get_bbreg(hw, bb_reg[index], MASKDWORD); | ||
1960 | } | ||
1961 | |||
1962 | _rtl92c_phy_save_mac_registers(hw, mac_reg, mac_backup); | ||
1963 | |||
1964 | _rtl92c_phy_save_adda_registers(hw, afe_reg, afe_backup, 16); | ||
1965 | |||
1966 | for (path = 0; path < pathbound; path++) { | ||
1967 | if (path == RF90_PATH_A) { | ||
1968 | offset = 0xb00; | ||
1969 | for (index = 0; index < 11; index++) { | ||
1970 | rtl_set_bbreg(hw, offset, MASKDWORD, | ||
1971 | apk_normal_setting_value_1 | ||
1972 | [index]); | ||
1973 | |||
1974 | offset += 0x04; | ||
1975 | } | ||
1976 | |||
1977 | rtl_set_bbreg(hw, 0xb98, MASKDWORD, 0x12680000); | ||
1978 | |||
1979 | offset = 0xb68; | ||
1980 | for (; index < 13; index++) { | ||
1981 | rtl_set_bbreg(hw, offset, MASKDWORD, | ||
1982 | apk_normal_setting_value_1 | ||
1983 | [index]); | ||
1984 | |||
1985 | offset += 0x04; | ||
1986 | } | ||
1987 | |||
1988 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x40000000); | ||
1989 | |||
1990 | offset = 0xb00; | ||
1991 | for (index = 0; index < 16; index++) { | ||
1992 | rtl_set_bbreg(hw, offset, MASKDWORD, | ||
1993 | apk_normal_setting_value_2 | ||
1994 | [index]); | ||
1995 | |||
1996 | offset += 0x04; | ||
1997 | } | ||
1998 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000); | ||
1999 | } else if (path == RF90_PATH_B) { | ||
2000 | offset = 0xb70; | ||
2001 | for (index = 0; index < 10; index++) { | ||
2002 | rtl_set_bbreg(hw, offset, MASKDWORD, | ||
2003 | apk_normal_setting_value_1 | ||
2004 | [index]); | ||
2005 | |||
2006 | offset += 0x04; | ||
2007 | } | ||
2008 | rtl_set_bbreg(hw, 0xb28, MASKDWORD, 0x12680000); | ||
2009 | rtl_set_bbreg(hw, 0xb98, MASKDWORD, 0x12680000); | ||
2010 | |||
2011 | offset = 0xb68; | ||
2012 | index = 11; | ||
2013 | for (; index < 13; index++) { | ||
2014 | rtl_set_bbreg(hw, offset, MASKDWORD, | ||
2015 | apk_normal_setting_value_1 | ||
2016 | [index]); | ||
2017 | |||
2018 | offset += 0x04; | ||
2019 | } | ||
2020 | |||
2021 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x40000000); | ||
2022 | |||
2023 | offset = 0xb60; | ||
2024 | for (index = 0; index < 16; index++) { | ||
2025 | rtl_set_bbreg(hw, offset, MASKDWORD, | ||
2026 | apk_normal_setting_value_2 | ||
2027 | [index]); | ||
2028 | |||
2029 | offset += 0x04; | ||
2030 | } | ||
2031 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000); | ||
2032 | } | ||
2033 | |||
2034 | reg_d[path] = rtl_get_rfreg(hw, (enum radio_path)path, | ||
2035 | 0xd, MASKDWORD); | ||
2036 | |||
2037 | for (index = 0; index < APK_AFE_REG_NUM; index++) | ||
2038 | rtl_set_bbreg(hw, afe_reg[index], MASKDWORD, | ||
2039 | afe_on_off[path]); | ||
2040 | |||
2041 | if (path == RF90_PATH_A) { | ||
2042 | for (index = 0; index < APK_BB_REG_NUM; index++) { | ||
2043 | if (index == 0) | ||
2044 | continue; | ||
2045 | rtl_set_bbreg(hw, bb_reg[index], MASKDWORD, | ||
2046 | bb_ap_mode[index]); | ||
2047 | } | ||
2048 | } | ||
2049 | |||
2050 | _rtl92c_phy_mac_setting_calibration(hw, mac_reg, mac_backup); | ||
2051 | |||
2052 | if (path == 0) { | ||
2053 | rtl_set_rfreg(hw, RF90_PATH_B, 0x0, MASKDWORD, 0x10000); | ||
2054 | } else { | ||
2055 | rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASKDWORD, | ||
2056 | 0x10000); | ||
2057 | rtl_set_rfreg(hw, RF90_PATH_A, 0x10, MASKDWORD, | ||
2058 | 0x1000f); | ||
2059 | rtl_set_rfreg(hw, RF90_PATH_A, 0x11, MASKDWORD, | ||
2060 | 0x20103); | ||
2061 | } | ||
2062 | |||
2063 | delta_offset = ((delta + 14) / 2); | ||
2064 | if (delta_offset < 0) | ||
2065 | delta_offset = 0; | ||
2066 | else if (delta_offset > 12) | ||
2067 | delta_offset = 12; | ||
2068 | |||
2069 | for (index = 0; index < APK_BB_REG_NUM; index++) { | ||
2070 | if (index != 1) | ||
2071 | continue; | ||
2072 | |||
2073 | tmpreg = apk_rf_init_value[path][index]; | ||
2074 | |||
2075 | if (!rtlefuse->b_apk_thermalmeterignore) { | ||
2076 | bb_offset = (tmpreg & 0xF0000) >> 16; | ||
2077 | |||
2078 | if (!(tmpreg & BIT(15))) | ||
2079 | bb_offset = -bb_offset; | ||
2080 | |||
2081 | delta_v = | ||
2082 | apk_delta_mapping[index][delta_offset]; | ||
2083 | |||
2084 | bb_offset += delta_v; | ||
2085 | |||
2086 | if (bb_offset < 0) { | ||
2087 | tmpreg = tmpreg & (~BIT(15)); | ||
2088 | bb_offset = -bb_offset; | ||
2089 | } else { | ||
2090 | tmpreg = tmpreg | BIT(15); | ||
2091 | } | ||
2092 | |||
2093 | tmpreg = | ||
2094 | (tmpreg & 0xFFF0FFFF) | (bb_offset << 16); | ||
2095 | } | ||
2096 | |||
2097 | rtl_set_rfreg(hw, (enum radio_path)path, 0xc, | ||
2098 | MASKDWORD, 0x8992e); | ||
2099 | rtl_set_rfreg(hw, (enum radio_path)path, 0x0, | ||
2100 | MASKDWORD, apk_rf_value_0[path][index]); | ||
2101 | rtl_set_rfreg(hw, (enum radio_path)path, 0xd, | ||
2102 | MASKDWORD, tmpreg); | ||
2103 | |||
2104 | i = 0; | ||
2105 | do { | ||
2106 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80000000); | ||
2107 | rtl_set_bbreg(hw, apk_offset[path], | ||
2108 | MASKDWORD, apk_value[0]); | ||
2109 | RTPRINT(rtlpriv, FINIT, INIT_IQK, | ||
2110 | ("PHY_APCalibrate() offset 0x%x " | ||
2111 | "value 0x%x\n", | ||
2112 | apk_offset[path], | ||
2113 | rtl_get_bbreg(hw, apk_offset[path], | ||
2114 | MASKDWORD))); | ||
2115 | |||
2116 | mdelay(3); | ||
2117 | |||
2118 | rtl_set_bbreg(hw, apk_offset[path], | ||
2119 | MASKDWORD, apk_value[1]); | ||
2120 | RTPRINT(rtlpriv, FINIT, INIT_IQK, | ||
2121 | ("PHY_APCalibrate() offset 0x%x " | ||
2122 | "value 0x%x\n", | ||
2123 | apk_offset[path], | ||
2124 | rtl_get_bbreg(hw, apk_offset[path], | ||
2125 | MASKDWORD))); | ||
2126 | |||
2127 | mdelay(20); | ||
2128 | |||
2129 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000); | ||
2130 | |||
2131 | if (path == RF90_PATH_A) | ||
2132 | tmpreg = rtl_get_bbreg(hw, 0xbd8, | ||
2133 | 0x03E00000); | ||
2134 | else | ||
2135 | tmpreg = rtl_get_bbreg(hw, 0xbd8, | ||
2136 | 0xF8000000); | ||
2137 | |||
2138 | RTPRINT(rtlpriv, FINIT, INIT_IQK, | ||
2139 | ("PHY_APCalibrate() offset " | ||
2140 | "0xbd8[25:21] %x\n", tmpreg)); | ||
2141 | |||
2142 | i++; | ||
2143 | |||
2144 | } while (tmpreg > apkbound && i < 4); | ||
2145 | |||
2146 | apk_result[path][index] = tmpreg; | ||
2147 | } | ||
2148 | } | ||
2149 | |||
2150 | _rtl92c_phy_reload_mac_registers(hw, mac_reg, mac_backup); | ||
2151 | |||
2152 | for (index = 0; index < APK_BB_REG_NUM; index++) { | ||
2153 | if (index == 0) | ||
2154 | continue; | ||
2155 | rtl_set_bbreg(hw, bb_reg[index], MASKDWORD, bb_backup[index]); | ||
2156 | } | ||
2157 | |||
2158 | _rtl92c_phy_reload_adda_registers(hw, afe_reg, afe_backup, 16); | ||
2159 | |||
2160 | for (path = 0; path < pathbound; path++) { | ||
2161 | rtl_set_rfreg(hw, (enum radio_path)path, 0xd, | ||
2162 | MASKDWORD, reg_d[path]); | ||
2163 | |||
2164 | if (path == RF90_PATH_B) { | ||
2165 | rtl_set_rfreg(hw, RF90_PATH_A, 0x10, MASKDWORD, | ||
2166 | 0x1000f); | ||
2167 | rtl_set_rfreg(hw, RF90_PATH_A, 0x11, MASKDWORD, | ||
2168 | 0x20101); | ||
2169 | } | ||
2170 | |||
2171 | if (apk_result[path][1] > 6) | ||
2172 | apk_result[path][1] = 6; | ||
2173 | } | ||
2174 | |||
2175 | for (path = 0; path < pathbound; path++) { | ||
2176 | rtl_set_rfreg(hw, (enum radio_path)path, 0x3, MASKDWORD, | ||
2177 | ((apk_result[path][1] << 15) | | ||
2178 | (apk_result[path][1] << 10) | | ||
2179 | (apk_result[path][1] << 5) | | ||
2180 | apk_result[path][1])); | ||
2181 | |||
2182 | if (path == RF90_PATH_A) | ||
2183 | rtl_set_rfreg(hw, (enum radio_path)path, 0x4, MASKDWORD, | ||
2184 | ((apk_result[path][1] << 15) | | ||
2185 | (apk_result[path][1] << 10) | | ||
2186 | (0x00 << 5) | 0x05)); | ||
2187 | else | ||
2188 | rtl_set_rfreg(hw, (enum radio_path)path, 0x4, MASKDWORD, | ||
2189 | ((apk_result[path][1] << 15) | | ||
2190 | (apk_result[path][1] << 10) | | ||
2191 | (0x02 << 5) | 0x05)); | ||
2192 | |||
2193 | rtl_set_rfreg(hw, (enum radio_path)path, 0xe, MASKDWORD, | ||
2194 | ((0x08 << 15) | (0x08 << 10) | (0x08 << 5) | | ||
2195 | 0x08)); | ||
2196 | |||
2197 | } | ||
2198 | |||
2199 | rtlphy->b_apk_done = true; | ||
2200 | #endif | ||
2201 | } | ||
2202 | |||
2203 | static void _rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, | ||
2204 | bool bmain, bool is2t) | ||
2205 | { | ||
2206 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
2207 | |||
2208 | if (is_hal_stop(rtlhal)) { | ||
2209 | rtl_set_bbreg(hw, REG_LEDCFG0, BIT(23), 0x01); | ||
2210 | rtl_set_bbreg(hw, rFPGA0_XAB_RFPARAMETER, BIT(13), 0x01); | ||
2211 | } | ||
2212 | if (is2t) { | ||
2213 | if (bmain) | ||
2214 | rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, | ||
2215 | BIT(5) | BIT(6), 0x1); | ||
2216 | else | ||
2217 | rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, | ||
2218 | BIT(5) | BIT(6), 0x2); | ||
2219 | } else { | ||
2220 | if (bmain) | ||
2221 | rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x2); | ||
2222 | else | ||
2223 | rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x1); | ||
2224 | |||
2225 | } | ||
2226 | } | ||
2227 | |||
2228 | #undef IQK_ADDA_REG_NUM | ||
2229 | #undef IQK_DELAY_TIME | ||
2230 | |||
2231 | void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery) | ||
2232 | { | ||
2233 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
2234 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
2235 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
2236 | |||
2237 | long result[4][8]; | ||
2238 | u8 i, final_candidate; | ||
2239 | bool b_patha_ok, b_pathb_ok; | ||
2240 | long reg_e94, reg_e9c, reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4, | ||
2241 | reg_ecc, reg_tmp = 0; | ||
2242 | bool is12simular, is13simular, is23simular; | ||
2243 | bool b_start_conttx = false, b_singletone = false; | ||
2244 | u32 iqk_bb_reg[10] = { | ||
2245 | ROFDM0_XARXIQIMBALANCE, | ||
2246 | ROFDM0_XBRXIQIMBALANCE, | ||
2247 | ROFDM0_ECCATHRESHOLD, | ||
2248 | ROFDM0_AGCRSSITABLE, | ||
2249 | ROFDM0_XATXIQIMBALANCE, | ||
2250 | ROFDM0_XBTXIQIMBALANCE, | ||
2251 | ROFDM0_XCTXIQIMBALANCE, | ||
2252 | ROFDM0_XCTXAFE, | ||
2253 | ROFDM0_XDTXAFE, | ||
2254 | ROFDM0_RXIQEXTANTA | ||
2255 | }; | ||
2256 | |||
2257 | if (b_recovery) { | ||
2258 | _rtl92c_phy_reload_adda_registers(hw, | ||
2259 | iqk_bb_reg, | ||
2260 | rtlphy->iqk_bb_backup, 10); | ||
2261 | return; | ||
2262 | } | ||
2263 | if (b_start_conttx || b_singletone) | ||
2264 | return; | ||
2265 | for (i = 0; i < 8; i++) { | ||
2266 | result[0][i] = 0; | ||
2267 | result[1][i] = 0; | ||
2268 | result[2][i] = 0; | ||
2269 | result[3][i] = 0; | ||
2270 | } | ||
2271 | final_candidate = 0xff; | ||
2272 | b_patha_ok = false; | ||
2273 | b_pathb_ok = false; | ||
2274 | is12simular = false; | ||
2275 | is23simular = false; | ||
2276 | is13simular = false; | ||
2277 | for (i = 0; i < 3; i++) { | ||
2278 | if (IS_92C_SERIAL(rtlhal->version)) | ||
2279 | _rtl92c_phy_iq_calibrate(hw, result, i, true); | ||
2280 | else | ||
2281 | _rtl92c_phy_iq_calibrate(hw, result, i, false); | ||
2282 | if (i == 1) { | ||
2283 | is12simular = _rtl92c_phy_simularity_compare(hw, | ||
2284 | result, 0, | ||
2285 | 1); | ||
2286 | if (is12simular) { | ||
2287 | final_candidate = 0; | ||
2288 | break; | ||
2289 | } | ||
2290 | } | ||
2291 | if (i == 2) { | ||
2292 | is13simular = _rtl92c_phy_simularity_compare(hw, | ||
2293 | result, 0, | ||
2294 | 2); | ||
2295 | if (is13simular) { | ||
2296 | final_candidate = 0; | ||
2297 | break; | ||
2298 | } | ||
2299 | is23simular = _rtl92c_phy_simularity_compare(hw, | ||
2300 | result, 1, | ||
2301 | 2); | ||
2302 | if (is23simular) | ||
2303 | final_candidate = 1; | ||
2304 | else { | ||
2305 | for (i = 0; i < 8; i++) | ||
2306 | reg_tmp += result[3][i]; | ||
2307 | |||
2308 | if (reg_tmp != 0) | ||
2309 | final_candidate = 3; | ||
2310 | else | ||
2311 | final_candidate = 0xFF; | ||
2312 | } | ||
2313 | } | ||
2314 | } | ||
2315 | for (i = 0; i < 4; i++) { | ||
2316 | reg_e94 = result[i][0]; | ||
2317 | reg_e9c = result[i][1]; | ||
2318 | reg_ea4 = result[i][2]; | ||
2319 | reg_eac = result[i][3]; | ||
2320 | reg_eb4 = result[i][4]; | ||
2321 | reg_ebc = result[i][5]; | ||
2322 | reg_ec4 = result[i][6]; | ||
2323 | reg_ecc = result[i][7]; | ||
2324 | } | ||
2325 | if (final_candidate != 0xff) { | ||
2326 | rtlphy->reg_e94 = reg_e94 = result[final_candidate][0]; | ||
2327 | rtlphy->reg_e9c = reg_e9c = result[final_candidate][1]; | ||
2328 | reg_ea4 = result[final_candidate][2]; | ||
2329 | reg_eac = result[final_candidate][3]; | ||
2330 | rtlphy->reg_eb4 = reg_eb4 = result[final_candidate][4]; | ||
2331 | rtlphy->reg_ebc = reg_ebc = result[final_candidate][5]; | ||
2332 | reg_ec4 = result[final_candidate][6]; | ||
2333 | reg_ecc = result[final_candidate][7]; | ||
2334 | b_patha_ok = b_pathb_ok = true; | ||
2335 | } else { | ||
2336 | rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100; | ||
2337 | rtlphy->reg_e9c = rtlphy->reg_ebc = 0x0; | ||
2338 | } | ||
2339 | if (reg_e94 != 0) /*&&(reg_ea4 != 0) */ | ||
2340 | _rtl92c_phy_path_a_fill_iqk_matrix(hw, b_patha_ok, result, | ||
2341 | final_candidate, | ||
2342 | (reg_ea4 == 0)); | ||
2343 | if (IS_92C_SERIAL(rtlhal->version)) { | ||
2344 | if (reg_eb4 != 0) /*&&(reg_ec4 != 0) */ | ||
2345 | _rtl92c_phy_path_b_fill_iqk_matrix(hw, b_pathb_ok, | ||
2346 | result, | ||
2347 | final_candidate, | ||
2348 | (reg_ec4 == 0)); | ||
2349 | } | ||
2350 | _rtl92c_phy_save_adda_registers(hw, iqk_bb_reg, | ||
2351 | rtlphy->iqk_bb_backup, 10); | ||
2352 | } | ||
2353 | |||
2354 | void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw) | ||
2355 | { | ||
2356 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
2357 | bool b_start_conttx = false, b_singletone = false; | ||
2358 | |||
2359 | if (b_start_conttx || b_singletone) | ||
2360 | return; | ||
2361 | if (IS_92C_SERIAL(rtlhal->version)) | ||
2362 | _rtl92c_phy_lc_calibrate(hw, true); | ||
2363 | else | ||
2364 | _rtl92c_phy_lc_calibrate(hw, false); | ||
2365 | } | ||
2366 | |||
2367 | void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta) | ||
2368 | { | ||
2369 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
2370 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
2371 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
2372 | |||
2373 | if (rtlphy->apk_done) | ||
2374 | return; | ||
2375 | if (IS_92C_SERIAL(rtlhal->version)) | ||
2376 | _rtl92c_phy_ap_calibrate(hw, delta, true); | ||
2377 | else | ||
2378 | _rtl92c_phy_ap_calibrate(hw, delta, false); | ||
2379 | } | ||
2380 | |||
2381 | void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain) | ||
2382 | { | ||
2383 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | ||
2384 | |||
2385 | if (IS_92C_SERIAL(rtlhal->version)) | ||
2386 | _rtl92c_phy_set_rfpath_switch(hw, bmain, true); | ||
2387 | else | ||
2388 | _rtl92c_phy_set_rfpath_switch(hw, bmain, false); | ||
2389 | } | ||
2390 | |||
2391 | bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) | ||
2392 | { | ||
2393 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
2394 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
2395 | bool b_postprocessing = false; | ||
2396 | |||
2397 | RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, | ||
2398 | ("-->IO Cmd(%#x), set_io_inprogress(%d)\n", | ||
2399 | iotype, rtlphy->set_io_inprogress)); | ||
2400 | do { | ||
2401 | switch (iotype) { | ||
2402 | case IO_CMD_RESUME_DM_BY_SCAN: | ||
2403 | RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, | ||
2404 | ("[IO CMD] Resume DM after scan.\n")); | ||
2405 | b_postprocessing = true; | ||
2406 | break; | ||
2407 | case IO_CMD_PAUSE_DM_BY_SCAN: | ||
2408 | RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, | ||
2409 | ("[IO CMD] Pause DM before scan.\n")); | ||
2410 | b_postprocessing = true; | ||
2411 | break; | ||
2412 | default: | ||
2413 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
2414 | ("switch case not process\n")); | ||
2415 | break; | ||
2416 | } | ||
2417 | } while (false); | ||
2418 | if (b_postprocessing && !rtlphy->set_io_inprogress) { | ||
2419 | rtlphy->set_io_inprogress = true; | ||
2420 | rtlphy->current_io_type = iotype; | ||
2421 | } else { | ||
2422 | return false; | ||
2423 | } | ||
2424 | rtl92c_phy_set_io(hw); | ||
2425 | RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, ("<--IO Type(%#x)\n", iotype)); | ||
2426 | return true; | ||
2427 | } | ||
2428 | |||
2429 | void rtl92c_phy_set_io(struct ieee80211_hw *hw) | ||
2430 | { | ||
2431 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
2432 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
2433 | |||
2434 | RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, | ||
2435 | ("--->Cmd(%#x), set_io_inprogress(%d)\n", | ||
2436 | rtlphy->current_io_type, rtlphy->set_io_inprogress)); | ||
2437 | switch (rtlphy->current_io_type) { | ||
2438 | case IO_CMD_RESUME_DM_BY_SCAN: | ||
2439 | dm_digtable.cur_igvalue = rtlphy->initgain_backup.xaagccore1; | ||
2440 | rtl92c_dm_write_dig(hw); | ||
2441 | rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); | ||
2442 | break; | ||
2443 | case IO_CMD_PAUSE_DM_BY_SCAN: | ||
2444 | rtlphy->initgain_backup.xaagccore1 = dm_digtable.cur_igvalue; | ||
2445 | dm_digtable.cur_igvalue = 0x17; | ||
2446 | rtl92c_dm_write_dig(hw); | ||
2447 | break; | ||
2448 | default: | ||
2449 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
2450 | ("switch case not process\n")); | ||
2451 | break; | ||
2452 | } | ||
2453 | rtlphy->set_io_inprogress = false; | ||
2454 | RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, | ||
2455 | ("<---(%#x)\n", rtlphy->current_io_type)); | ||
2456 | } | ||
2457 | |||
2458 | void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw) | ||
2459 | { | ||
2460 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
2461 | |||
2462 | rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b); | ||
2463 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); | ||
2464 | rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00); | ||
2465 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); | ||
2466 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); | ||
2467 | rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); | ||
2468 | } | ||
2469 | |||
2470 | static void _rtl92ce_phy_set_rf_sleep(struct ieee80211_hw *hw) | ||
2471 | { | ||
2472 | u32 u4b_tmp; | ||
2473 | u8 delay = 5; | ||
2474 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
2475 | |||
2476 | rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); | ||
2477 | rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); | ||
2478 | rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); | ||
2479 | u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK); | ||
2480 | while (u4b_tmp != 0 && delay > 0) { | ||
2481 | rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0); | ||
2482 | rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); | ||
2483 | rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); | ||
2484 | u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK); | ||
2485 | delay--; | ||
2486 | } | ||
2487 | if (delay == 0) { | ||
2488 | rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00); | ||
2489 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); | ||
2490 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); | ||
2491 | rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); | ||
2492 | RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, | ||
2493 | ("Switch RF timeout !!!.\n")); | ||
2494 | return; | ||
2495 | } | ||
2496 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); | ||
2497 | rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22); | ||
2498 | } | ||
2499 | |||
2500 | static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, | 483 | static bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, |
2501 | enum rf_pwrstate rfpwr_state) | 484 | enum rf_pwrstate rfpwr_state) |
2502 | { | 485 | { |