Commit | Line | Data |
---|---|---|
4295cd25 LF |
1 | /****************************************************************************** |
2 | * | |
fc616856 | 3 | * Copyright(c) 2009-2012 Realtek Corporation. |
4295cd25 LF |
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 | ||
1472d3a8 LF |
30 | #include "../wifi.h" |
31 | #include "../rtl8192ce/reg.h" | |
32 | #include "../rtl8192ce/def.h" | |
33 | #include "dm_common.h" | |
9f087a92 | 34 | #include "fw_common.h" |
1472d3a8 | 35 | #include "phy_common.h" |
9f087a92 | 36 | #include <linux/export.h> |
1472d3a8 | 37 | |
4295cd25 LF |
38 | u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) |
39 | { | |
40 | struct rtl_priv *rtlpriv = rtl_priv(hw); | |
41 | u32 returnvalue, originalvalue, bitshift; | |
42 | ||
f30d7507 JP |
43 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n", |
44 | regaddr, bitmask); | |
4295cd25 LF |
45 | originalvalue = rtl_read_dword(rtlpriv, regaddr); |
46 | bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); | |
47 | returnvalue = (originalvalue & bitmask) >> bitshift; | |
48 | ||
f30d7507 JP |
49 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, |
50 | "BBR MASK=0x%x Addr[0x%x]=0x%x\n", | |
51 | bitmask, regaddr, originalvalue); | |
4295cd25 LF |
52 | |
53 | return returnvalue; | |
4295cd25 | 54 | } |
1472d3a8 | 55 | EXPORT_SYMBOL(rtl92c_phy_query_bb_reg); |
4295cd25 LF |
56 | |
57 | void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, | |
58 | u32 regaddr, u32 bitmask, u32 data) | |
59 | { | |
60 | struct rtl_priv *rtlpriv = rtl_priv(hw); | |
61 | u32 originalvalue, bitshift; | |
62 | ||
f30d7507 JP |
63 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, |
64 | "regaddr(%#x), bitmask(%#x), data(%#x)\n", | |
65 | regaddr, bitmask, data); | |
4295cd25 LF |
66 | |
67 | if (bitmask != MASKDWORD) { | |
68 | originalvalue = rtl_read_dword(rtlpriv, regaddr); | |
69 | bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); | |
70 | data = ((originalvalue & (~bitmask)) | (data << bitshift)); | |
71 | } | |
72 | ||
73 | rtl_write_dword(rtlpriv, regaddr, data); | |
74 | ||
f30d7507 JP |
75 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, |
76 | "regaddr(%#x), bitmask(%#x), data(%#x)\n", | |
77 | regaddr, bitmask, data); | |
4295cd25 | 78 | } |
1472d3a8 | 79 | EXPORT_SYMBOL(rtl92c_phy_set_bb_reg); |
4295cd25 | 80 | |
76c34f91 | 81 | u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, |
d3bb1429 | 82 | enum radio_path rfpath, u32 offset) |
4295cd25 | 83 | { |
9d833ed7 | 84 | RT_ASSERT(false, "deprecated!\n"); |
4295cd25 LF |
85 | return 0; |
86 | } | |
1472d3a8 | 87 | EXPORT_SYMBOL(_rtl92c_phy_fw_rf_serial_read); |
4295cd25 | 88 | |
76c34f91 | 89 | void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, |
d3bb1429 LF |
90 | enum radio_path rfpath, u32 offset, |
91 | u32 data) | |
4295cd25 | 92 | { |
9d833ed7 | 93 | RT_ASSERT(false, "deprecated!\n"); |
4295cd25 | 94 | } |
1472d3a8 | 95 | EXPORT_SYMBOL(_rtl92c_phy_fw_rf_serial_write); |
4295cd25 | 96 | |
76c34f91 | 97 | u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, |
d3bb1429 | 98 | enum radio_path rfpath, u32 offset) |
4295cd25 LF |
99 | { |
100 | struct rtl_priv *rtlpriv = rtl_priv(hw); | |
101 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | |
102 | struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; | |
103 | u32 newoffset; | |
104 | u32 tmplong, tmplong2; | |
105 | u8 rfpi_enable = 0; | |
106 | u32 retvalue; | |
107 | ||
108 | offset &= 0x3f; | |
109 | newoffset = offset; | |
110 | if (RT_CANNOT_IO(hw)) { | |
f30d7507 | 111 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "return all one\n"); |
4295cd25 LF |
112 | return 0xFFFFFFFF; |
113 | } | |
114 | tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD); | |
115 | if (rfpath == RF90_PATH_A) | |
116 | tmplong2 = tmplong; | |
117 | else | |
118 | tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD); | |
119 | tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) | | |
120 | (newoffset << 23) | BLSSIREADEDGE; | |
121 | rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, | |
122 | tmplong & (~BLSSIREADEDGE)); | |
123 | mdelay(1); | |
124 | rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2); | |
125 | mdelay(1); | |
126 | rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, | |
127 | tmplong | BLSSIREADEDGE); | |
128 | mdelay(1); | |
129 | if (rfpath == RF90_PATH_A) | |
9f087a92 | 130 | rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1, |
4295cd25 LF |
131 | BIT(8)); |
132 | else if (rfpath == RF90_PATH_B) | |
9f087a92 | 133 | rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1, |
4295cd25 LF |
134 | BIT(8)); |
135 | if (rfpi_enable) | |
da17fcff | 136 | retvalue = rtl_get_bbreg(hw, pphyreg->rf_rbpi, |
4295cd25 LF |
137 | BLSSIREADBACKDATA); |
138 | else | |
da17fcff | 139 | retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb, |
4295cd25 | 140 | BLSSIREADBACKDATA); |
f30d7507 | 141 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x]=0x%x\n", |
9f087a92 LF |
142 | rfpath, pphyreg->rf_rb, |
143 | retvalue); | |
4295cd25 LF |
144 | return retvalue; |
145 | } | |
1472d3a8 | 146 | EXPORT_SYMBOL(_rtl92c_phy_rf_serial_read); |
4295cd25 | 147 | |
76c34f91 | 148 | void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, |
d3bb1429 LF |
149 | enum radio_path rfpath, u32 offset, |
150 | u32 data) | |
4295cd25 LF |
151 | { |
152 | u32 data_and_addr; | |
153 | u32 newoffset; | |
154 | struct rtl_priv *rtlpriv = rtl_priv(hw); | |
155 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | |
156 | struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; | |
157 | ||
158 | if (RT_CANNOT_IO(hw)) { | |
f30d7507 | 159 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "stop\n"); |
4295cd25 LF |
160 | return; |
161 | } | |
162 | offset &= 0x3f; | |
163 | newoffset = offset; | |
164 | data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff; | |
165 | rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr); | |
f30d7507 | 166 | RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFW-%d Addr[0x%x]=0x%x\n", |
9f087a92 LF |
167 | rfpath, pphyreg->rf3wire_offset, |
168 | data_and_addr); | |
4295cd25 | 169 | } |
1472d3a8 | 170 | EXPORT_SYMBOL(_rtl92c_phy_rf_serial_write); |
4295cd25 | 171 | |
1472d3a8 | 172 | u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask) |
4295cd25 LF |
173 | { |
174 | u32 i; | |
175 | ||
176 | for (i = 0; i <= 31; i++) { | |
9f087a92 | 177 | if (((bitmask >> i) & 0x1) == 1) |
4295cd25 LF |
178 | break; |
179 | } | |
180 | return i; | |
181 | } | |
1472d3a8 | 182 | EXPORT_SYMBOL(_rtl92c_phy_calculate_bit_shift); |
4295cd25 LF |
183 | |
184 | static void _rtl92c_phy_bb_config_1t(struct ieee80211_hw *hw) | |
185 | { | |
186 | rtl_set_bbreg(hw, RFPGA0_TXINFO, 0x3, 0x2); | |
187 | rtl_set_bbreg(hw, RFPGA1_TXINFO, 0x300033, 0x200022); | |
188 | rtl_set_bbreg(hw, RCCK0_AFESETTING, MASKBYTE3, 0x45); | |
189 | rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x23); | |
190 | rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, 0x30, 0x1); | |
191 | rtl_set_bbreg(hw, 0xe74, 0x0c000000, 0x2); | |
192 | rtl_set_bbreg(hw, 0xe78, 0x0c000000, 0x2); | |
193 | rtl_set_bbreg(hw, 0xe7c, 0x0c000000, 0x2); | |
194 | rtl_set_bbreg(hw, 0xe80, 0x0c000000, 0x2); | |
195 | rtl_set_bbreg(hw, 0xe88, 0x0c000000, 0x2); | |
196 | } | |
c07ccff3 | 197 | |
4295cd25 LF |
198 | bool rtl92c_phy_rf_config(struct ieee80211_hw *hw) |
199 | { | |
1472d3a8 LF |
200 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
201 | ||
202 | return rtlpriv->cfg->ops->phy_rf6052_config(hw); | |
4295cd25 | 203 | } |
1472d3a8 | 204 | EXPORT_SYMBOL(rtl92c_phy_rf_config); |
4295cd25 | 205 | |
76c34f91 | 206 | bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw) |
4295cd25 LF |
207 | { |
208 | struct rtl_priv *rtlpriv = rtl_priv(hw); | |
209 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | |
210 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | |
211 | bool rtstatus; | |
212 | ||
1472d3a8 | 213 | rtstatus = rtlpriv->cfg->ops->config_bb_with_headerfile(hw, |
4295cd25 | 214 | BASEBAND_CONFIG_PHY_REG); |
23677ce3 | 215 | if (!rtstatus) { |
9f087a92 | 216 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!"); |
4295cd25 LF |
217 | return false; |
218 | } | |
219 | if (rtlphy->rf_type == RF_1T2R) { | |
220 | _rtl92c_phy_bb_config_1t(hw); | |
f30d7507 | 221 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Config to 1T!!\n"); |
4295cd25 LF |
222 | } |
223 | if (rtlefuse->autoload_failflag == false) { | |
224 | rtlphy->pwrgroup_cnt = 0; | |
1472d3a8 | 225 | rtstatus = rtlpriv->cfg->ops->config_bb_with_pgheaderfile(hw, |
4295cd25 LF |
226 | BASEBAND_CONFIG_PHY_REG); |
227 | } | |
23677ce3 | 228 | if (!rtstatus) { |
9f087a92 | 229 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!"); |
4295cd25 LF |
230 | return false; |
231 | } | |
1472d3a8 | 232 | rtstatus = rtlpriv->cfg->ops->config_bb_with_headerfile(hw, |
4295cd25 | 233 | BASEBAND_CONFIG_AGC_TAB); |
23677ce3 | 234 | if (!rtstatus) { |
f30d7507 | 235 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n"); |
4295cd25 LF |
236 | return false; |
237 | } | |
9f087a92 LF |
238 | rtlphy->cck_high_power = |
239 | (bool)(rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, 0x200)); | |
c07ccff3 | 240 | |
4295cd25 LF |
241 | return true; |
242 | } | |
9f087a92 | 243 | |
1472d3a8 | 244 | EXPORT_SYMBOL(_rtl92c_phy_bb8192c_config_parafile); |
4295cd25 | 245 | |
1472d3a8 | 246 | void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw, |
d3bb1429 LF |
247 | u32 regaddr, u32 bitmask, |
248 | u32 data) | |
4295cd25 LF |
249 | { |
250 | struct rtl_priv *rtlpriv = rtl_priv(hw); | |
251 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | |
252 | ||
9f087a92 LF |
253 | if (regaddr == RTXAGC_A_RATE18_06) { |
254 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][0] = | |
255 | data; | |
256 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | |
257 | "MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n", | |
258 | rtlphy->pwrgroup_cnt, | |
259 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> | |
260 | pwrgroup_cnt][0]); | |
261 | } | |
262 | if (regaddr == RTXAGC_A_RATE54_24) { | |
263 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][1] = | |
264 | data; | |
265 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | |
266 | "MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n", | |
267 | rtlphy->pwrgroup_cnt, | |
268 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> | |
269 | pwrgroup_cnt][1]); | |
270 | } | |
271 | if (regaddr == RTXAGC_A_CCK1_MCS32) { | |
272 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][6] = | |
273 | data; | |
274 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | |
275 | "MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n", | |
276 | rtlphy->pwrgroup_cnt, | |
277 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> | |
278 | pwrgroup_cnt][6]); | |
279 | } | |
280 | if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) { | |
281 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][7] = | |
282 | data; | |
283 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | |
284 | "MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n", | |
285 | rtlphy->pwrgroup_cnt, | |
286 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> | |
287 | pwrgroup_cnt][7]); | |
288 | } | |
289 | if (regaddr == RTXAGC_A_MCS03_MCS00) { | |
290 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][2] = | |
291 | data; | |
292 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | |
293 | "MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n", | |
294 | rtlphy->pwrgroup_cnt, | |
295 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> | |
296 | pwrgroup_cnt][2]); | |
297 | } | |
298 | if (regaddr == RTXAGC_A_MCS07_MCS04) { | |
299 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][3] = | |
300 | data; | |
301 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | |
302 | "MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n", | |
303 | rtlphy->pwrgroup_cnt, | |
304 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> | |
305 | pwrgroup_cnt][3]); | |
306 | } | |
307 | if (regaddr == RTXAGC_A_MCS11_MCS08) { | |
308 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][4] = | |
309 | data; | |
310 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | |
311 | "MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n", | |
312 | rtlphy->pwrgroup_cnt, | |
313 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> | |
314 | pwrgroup_cnt][4]); | |
315 | } | |
316 | if (regaddr == RTXAGC_A_MCS15_MCS12) { | |
317 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][5] = | |
318 | data; | |
319 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | |
320 | "MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n", | |
321 | rtlphy->pwrgroup_cnt, | |
322 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> | |
323 | pwrgroup_cnt][5]); | |
324 | } | |
325 | if (regaddr == RTXAGC_B_RATE18_06) { | |
326 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][8] = | |
327 | data; | |
328 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | |
329 | "MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n", | |
330 | rtlphy->pwrgroup_cnt, | |
331 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> | |
332 | pwrgroup_cnt][8]); | |
333 | } | |
334 | if (regaddr == RTXAGC_B_RATE54_24) { | |
335 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][9] = | |
336 | data; | |
337 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | |
338 | "MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n", | |
339 | rtlphy->pwrgroup_cnt, | |
340 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> | |
341 | pwrgroup_cnt][9]); | |
342 | } | |
343 | if (regaddr == RTXAGC_B_CCK1_55_MCS32) { | |
344 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][14] = | |
345 | data; | |
346 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | |
347 | "MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n", | |
348 | rtlphy->pwrgroup_cnt, | |
349 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> | |
350 | pwrgroup_cnt][14]); | |
351 | } | |
352 | if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) { | |
353 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][15] = | |
354 | data; | |
355 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | |
356 | "MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n", | |
357 | rtlphy->pwrgroup_cnt, | |
358 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> | |
359 | pwrgroup_cnt][15]); | |
360 | } | |
361 | if (regaddr == RTXAGC_B_MCS03_MCS00) { | |
362 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][10] = | |
363 | data; | |
364 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | |
365 | "MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n", | |
366 | rtlphy->pwrgroup_cnt, | |
367 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> | |
368 | pwrgroup_cnt][10]); | |
369 | } | |
370 | if (regaddr == RTXAGC_B_MCS07_MCS04) { | |
371 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][11] = | |
372 | data; | |
373 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | |
374 | "MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n", | |
375 | rtlphy->pwrgroup_cnt, | |
376 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> | |
377 | pwrgroup_cnt][11]); | |
378 | } | |
379 | if (regaddr == RTXAGC_B_MCS11_MCS08) { | |
380 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][12] = | |
381 | data; | |
382 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | |
383 | "MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n", | |
384 | rtlphy->pwrgroup_cnt, | |
385 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> | |
386 | pwrgroup_cnt][12]); | |
387 | } | |
388 | if (regaddr == RTXAGC_B_MCS15_MCS12) { | |
389 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][13] = | |
390 | data; | |
391 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | |
392 | "MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n", | |
393 | rtlphy->pwrgroup_cnt, | |
394 | rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> | |
395 | pwrgroup_cnt][13]); | |
4295cd25 LF |
396 | |
397 | rtlphy->pwrgroup_cnt++; | |
9f087a92 | 398 | } |
4295cd25 | 399 | } |
1472d3a8 | 400 | EXPORT_SYMBOL(_rtl92c_store_pwrIndex_diffrate_offset); |
4295cd25 LF |
401 | |
402 | void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) | |
403 | { | |
404 | struct rtl_priv *rtlpriv = rtl_priv(hw); | |
405 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | |
406 | ||
407 | rtlphy->default_initialgain[0] = | |
9f087a92 | 408 | (u8)rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0); |
4295cd25 | 409 | rtlphy->default_initialgain[1] = |
9f087a92 | 410 | (u8)rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0); |
4295cd25 | 411 | rtlphy->default_initialgain[2] = |
9f087a92 | 412 | (u8)rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0); |
4295cd25 | 413 | rtlphy->default_initialgain[3] = |
9f087a92 | 414 | (u8)rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0); |
4295cd25 LF |
415 | |
416 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | |
f30d7507 | 417 | "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n", |
9f087a92 LF |
418 | rtlphy->default_initialgain[0], |
419 | rtlphy->default_initialgain[1], | |
420 | rtlphy->default_initialgain[2], | |
421 | rtlphy->default_initialgain[3]); | |
4295cd25 | 422 | |
9f087a92 | 423 | rtlphy->framesync = (u8)rtl_get_bbreg(hw, |
4295cd25 LF |
424 | ROFDM0_RXDETECTOR3, MASKBYTE0); |
425 | rtlphy->framesync_c34 = rtl_get_bbreg(hw, | |
426 | ROFDM0_RXDETECTOR2, MASKDWORD); | |
427 | ||
428 | RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, | |
f30d7507 | 429 | "Default framesync (0x%x) = 0x%x\n", |
9f087a92 | 430 | ROFDM0_RXDETECTOR3, rtlphy->framesync); |
4295cd25 LF |
431 | } |
432 | ||
1472d3a8 | 433 | void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) |
4295cd25 LF |
434 | { |
435 | struct rtl_priv *rtlpriv = rtl_priv(hw); | |
436 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | |
437 | ||
438 | rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW; | |
439 | rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW; | |
440 | rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW; | |
441 | rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW; | |
442 | ||
443 | rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB; | |
444 | rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB; | |
445 | rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB; | |
446 | rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB; | |
447 | ||
448 | rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE; | |
449 | rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE; | |
450 | ||
451 | rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE; | |
452 | rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE; | |
453 | ||
454 | rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = | |
455 | RFPGA0_XA_LSSIPARAMETER; | |
456 | rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = | |
457 | RFPGA0_XB_LSSIPARAMETER; | |
458 | ||
459 | rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = rFPGA0_XAB_RFPARAMETER; | |
460 | rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = rFPGA0_XAB_RFPARAMETER; | |
461 | rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = rFPGA0_XCD_RFPARAMETER; | |
462 | rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = rFPGA0_XCD_RFPARAMETER; | |
463 | ||
464 | rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE; | |
465 | rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE; | |
466 | rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE; | |
467 | rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE; | |
468 | ||
469 | rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1; | |
470 | rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1; | |
471 | ||
472 | rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2; | |
473 | rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2; | |
474 | ||
da17fcff LF |
475 | rtlphy->phyreg_def[RF90_PATH_A].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL; |
476 | rtlphy->phyreg_def[RF90_PATH_B].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL; | |
477 | rtlphy->phyreg_def[RF90_PATH_C].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL; | |
478 | rtlphy->phyreg_def[RF90_PATH_D].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL; | |
4295cd25 LF |
479 | |
480 | rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1; | |
481 | rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1; | |
482 | rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1; | |
483 | rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1; | |
484 | ||
485 | rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2; | |
486 | rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2; | |
487 | rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2; | |
488 | rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2; | |
489 | ||
da17fcff LF |
490 | rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbal = ROFDM0_XARXIQIMBALANCE; |
491 | rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbal = ROFDM0_XBRXIQIMBALANCE; | |
492 | rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbal = ROFDM0_XCRXIQIMBANLANCE; | |
493 | rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbal = ROFDM0_XDRXIQIMBALANCE; | |
4295cd25 LF |
494 | |
495 | rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE; | |
496 | rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE; | |
497 | rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE; | |
498 | rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE; | |
499 | ||
da17fcff LF |
500 | rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbal = ROFDM0_XATXIQIMBALANCE; |
501 | rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbal = ROFDM0_XBTXIQIMBALANCE; | |
502 | rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbal = ROFDM0_XCTXIQIMBALANCE; | |
503 | rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbal = ROFDM0_XDTXIQIMBALANCE; | |
4295cd25 LF |
504 | |
505 | rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE; | |
506 | rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE; | |
507 | rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE; | |
508 | rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE; | |
509 | ||
da17fcff LF |
510 | rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RFPGA0_XA_LSSIREADBACK; |
511 | rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RFPGA0_XB_LSSIREADBACK; | |
512 | rtlphy->phyreg_def[RF90_PATH_C].rf_rb = RFPGA0_XC_LSSIREADBACK; | |
513 | rtlphy->phyreg_def[RF90_PATH_D].rf_rb = RFPGA0_XD_LSSIREADBACK; | |
514 | ||
515 | rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = TRANSCEIVEA_HSPI_READBACK; | |
516 | rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = TRANSCEIVEB_HSPI_READBACK; | |
4295cd25 LF |
517 | |
518 | } | |
1472d3a8 | 519 | EXPORT_SYMBOL(_rtl92c_phy_init_bb_rf_register_definition); |
4295cd25 LF |
520 | |
521 | void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel) | |
522 | { | |
523 | struct rtl_priv *rtlpriv = rtl_priv(hw); | |
524 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | |
525 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | |
526 | u8 txpwr_level; | |
527 | long txpwr_dbm; | |
528 | ||
529 | txpwr_level = rtlphy->cur_cck_txpwridx; | |
9f087a92 LF |
530 | txpwr_dbm = _rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_B, |
531 | txpwr_level); | |
4295cd25 LF |
532 | txpwr_level = rtlphy->cur_ofdm24g_txpwridx + |
533 | rtlefuse->legacy_ht_txpowerdiff; | |
9f087a92 | 534 | if (_rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, |
4295cd25 LF |
535 | txpwr_level) > txpwr_dbm) |
536 | txpwr_dbm = | |
537 | _rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, | |
538 | txpwr_level); | |
539 | txpwr_level = rtlphy->cur_ofdm24g_txpwridx; | |
9f087a92 | 540 | if (_rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G, |
4295cd25 LF |
541 | txpwr_level) > txpwr_dbm) |
542 | txpwr_dbm = | |
543 | _rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G, | |
544 | txpwr_level); | |
545 | *powerlevel = txpwr_dbm; | |
546 | } | |
547 | ||
548 | static void _rtl92c_get_txpower_index(struct ieee80211_hw *hw, u8 channel, | |
549 | u8 *cckpowerlevel, u8 *ofdmpowerlevel) | |
550 | { | |
551 | struct rtl_priv *rtlpriv = rtl_priv(hw); | |
552 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | |
553 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | |
554 | u8 index = (channel - 1); | |
555 | ||
556 | cckpowerlevel[RF90_PATH_A] = | |
557 | rtlefuse->txpwrlevel_cck[RF90_PATH_A][index]; | |
558 | cckpowerlevel[RF90_PATH_B] = | |
559 | rtlefuse->txpwrlevel_cck[RF90_PATH_B][index]; | |
560 | if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_1T1R) { | |
561 | ofdmpowerlevel[RF90_PATH_A] = | |
562 | rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index]; | |
563 | ofdmpowerlevel[RF90_PATH_B] = | |
564 | rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index]; | |
565 | } else if (get_rf_type(rtlphy) == RF_2T2R) { | |
566 | ofdmpowerlevel[RF90_PATH_A] = | |
567 | rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_A][index]; | |
568 | ofdmpowerlevel[RF90_PATH_B] = | |
569 | rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_B][index]; | |
570 | } | |
571 | } | |
572 | ||
573 | static void _rtl92c_ccxpower_index_check(struct ieee80211_hw *hw, | |
574 | u8 channel, u8 *cckpowerlevel, | |
575 | u8 *ofdmpowerlevel) | |
576 | { | |
577 | struct rtl_priv *rtlpriv = rtl_priv(hw); | |
578 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | |
579 | ||
580 | rtlphy->cur_cck_txpwridx = cckpowerlevel[0]; | |
581 | rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0]; | |
582 | } | |
583 | ||
584 | void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel) | |
585 | { | |
1472d3a8 | 586 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
9f087a92 | 587 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); |
4295cd25 LF |
588 | u8 cckpowerlevel[2], ofdmpowerlevel[2]; |
589 | ||
23677ce3 | 590 | if (!rtlefuse->txpwr_fromeprom) |
4295cd25 LF |
591 | return; |
592 | _rtl92c_get_txpower_index(hw, channel, | |
593 | &cckpowerlevel[0], &ofdmpowerlevel[0]); | |
9f087a92 | 594 | _rtl92c_ccxpower_index_check(hw, channel, &cckpowerlevel[0], |
4295cd25 | 595 | &ofdmpowerlevel[0]); |
1472d3a8 LF |
596 | rtlpriv->cfg->ops->phy_rf6052_set_cck_txpower(hw, &cckpowerlevel[0]); |
597 | rtlpriv->cfg->ops->phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0], | |
598 | channel); | |
4295cd25 | 599 | } |
1472d3a8 | 600 | EXPORT_SYMBOL(rtl92c_phy_set_txpower_level); |
4295cd25 LF |
601 | |
602 | bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm) | |
603 | { | |
604 | struct rtl_priv *rtlpriv = rtl_priv(hw); | |
605 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | |
606 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | |
607 | u8 idx; | |
608 | u8 rf_path; | |
9f087a92 | 609 | u8 ccktxpwridx = _rtl92c_phy_dbm_to_txpwr_idx(hw, WIRELESS_MODE_B, |
4295cd25 | 610 | power_indbm); |
9f087a92 | 611 | u8 ofdmtxpwridx = _rtl92c_phy_dbm_to_txpwr_idx(hw, WIRELESS_MODE_N_24G, |
4295cd25 LF |
612 | power_indbm); |
613 | if (ofdmtxpwridx - rtlefuse->legacy_ht_txpowerdiff > 0) | |
614 | ofdmtxpwridx -= rtlefuse->legacy_ht_txpowerdiff; | |
615 | else | |
616 | ofdmtxpwridx = 0; | |
617 | RT_TRACE(rtlpriv, COMP_TXAGC, DBG_TRACE, | |
f30d7507 | 618 | "%lx dBm, ccktxpwridx = %d, ofdmtxpwridx = %d\n", |
9f087a92 | 619 | power_indbm, ccktxpwridx, ofdmtxpwridx); |
4295cd25 LF |
620 | for (idx = 0; idx < 14; idx++) { |
621 | for (rf_path = 0; rf_path < 2; rf_path++) { | |
622 | rtlefuse->txpwrlevel_cck[rf_path][idx] = ccktxpwridx; | |
623 | rtlefuse->txpwrlevel_ht40_1s[rf_path][idx] = | |
624 | ofdmtxpwridx; | |
625 | rtlefuse->txpwrlevel_ht40_2s[rf_path][idx] = | |
626 | ofdmtxpwridx; | |
627 | } | |
628 | } | |
629 | rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); | |
630 | return true; | |
631 | } | |
1472d3a8 | 632 | EXPORT_SYMBOL(rtl92c_phy_update_txpower_dbm); |
4295cd25 | 633 | |
9f087a92 | 634 | u8 _rtl92c_phy_dbm_to_txpwr_idx(struct ieee80211_hw *hw, |
41cae2d0 JB |
635 | enum wireless_mode wirelessmode, |
636 | long power_indbm) | |
4295cd25 LF |
637 | { |
638 | u8 txpwridx; | |
639 | long offset; | |
640 | ||
641 | switch (wirelessmode) { | |
642 | case WIRELESS_MODE_B: | |
643 | offset = -7; | |
644 | break; | |
645 | case WIRELESS_MODE_G: | |
646 | case WIRELESS_MODE_N_24G: | |
647 | offset = -8; | |
648 | break; | |
649 | default: | |
650 | offset = -8; | |
651 | break; | |
652 | } | |
653 | ||
654 | if ((power_indbm - offset) > 0) | |
9f087a92 | 655 | txpwridx = (u8)((power_indbm - offset) * 2); |
4295cd25 LF |
656 | else |
657 | txpwridx = 0; | |
658 | ||
659 | if (txpwridx > MAX_TXPWR_IDX_NMODE_92S) | |
660 | txpwridx = MAX_TXPWR_IDX_NMODE_92S; | |
661 | ||
662 | return txpwridx; | |
663 | } | |
9f087a92 | 664 | EXPORT_SYMBOL(_rtl92c_phy_dbm_to_txpwr_idx); |
4295cd25 | 665 | |
41cae2d0 JB |
666 | long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, |
667 | enum wireless_mode wirelessmode, | |
668 | u8 txpwridx) | |
4295cd25 LF |
669 | { |
670 | long offset; | |
671 | long pwrout_dbm; | |
672 | ||
673 | switch (wirelessmode) { | |
674 | case WIRELESS_MODE_B: | |
675 | offset = -7; | |
676 | break; | |
677 | case WIRELESS_MODE_G: | |
678 | case WIRELESS_MODE_N_24G: | |
679 | offset = -8; | |
680 | break; | |
681 | default: | |
682 | offset = -8; | |
683 | break; | |
684 | } | |
685 | pwrout_dbm = txpwridx / 2 + offset; | |
686 | return pwrout_dbm; | |
687 | } | |
1472d3a8 | 688 | EXPORT_SYMBOL(_rtl92c_phy_txpwr_idx_to_dbm); |
4295cd25 | 689 | |
4295cd25 LF |
690 | void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw, |
691 | enum nl80211_channel_type ch_type) | |
692 | { | |
693 | struct rtl_priv *rtlpriv = rtl_priv(hw); | |
694 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | |
695 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | |
696 | u8 tmp_bw = rtlphy->current_chan_bw; | |
697 | ||
698 | if (rtlphy->set_bwmode_inprogress) | |
699 | return; | |
700 | rtlphy->set_bwmode_inprogress = true; | |
c07ccff3 | 701 | if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { |
099fb8ab | 702 | rtlpriv->cfg->ops->phy_set_bw_mode_callback(hw); |
c07ccff3 | 703 | } else { |
4295cd25 | 704 | RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, |
9f087a92 | 705 | "false driver sleep or unload\n"); |
4295cd25 LF |
706 | rtlphy->set_bwmode_inprogress = false; |
707 | rtlphy->current_chan_bw = tmp_bw; | |
708 | } | |
709 | } | |
1472d3a8 | 710 | EXPORT_SYMBOL(rtl92c_phy_set_bw_mode); |
4295cd25 LF |
711 | |
712 | void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw) | |
713 | { | |
714 | struct rtl_priv *rtlpriv = rtl_priv(hw); | |
715 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | |
716 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | |
717 | u32 delay; | |
718 | ||
719 | RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, | |
f30d7507 | 720 | "switch to channel%d\n", rtlphy->current_channel); |
4295cd25 LF |
721 | if (is_hal_stop(rtlhal)) |
722 | return; | |
723 | do { | |
724 | if (!rtlphy->sw_chnl_inprogress) | |
725 | break; | |
726 | if (!_rtl92c_phy_sw_chnl_step_by_step | |
727 | (hw, rtlphy->current_channel, &rtlphy->sw_chnl_stage, | |
728 | &rtlphy->sw_chnl_step, &delay)) { | |
729 | if (delay > 0) | |
730 | mdelay(delay); | |
731 | else | |
732 | continue; | |
c07ccff3 | 733 | } else { |
4295cd25 | 734 | rtlphy->sw_chnl_inprogress = false; |
c07ccff3 | 735 | } |
4295cd25 LF |
736 | break; |
737 | } while (true); | |
9f087a92 | 738 | RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n"); |
4295cd25 | 739 | } |
1472d3a8 | 740 | EXPORT_SYMBOL(rtl92c_phy_sw_chnl_callback); |
4295cd25 LF |
741 | |
742 | u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw) | |
743 | { | |
744 | struct rtl_priv *rtlpriv = rtl_priv(hw); | |
745 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | |
746 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | |
747 | ||
748 | if (rtlphy->sw_chnl_inprogress) | |
749 | return 0; | |
750 | if (rtlphy->set_bwmode_inprogress) | |
751 | return 0; | |
752 | RT_ASSERT((rtlphy->current_channel <= 14), | |
9f087a92 | 753 | "WIRELESS_MODE_G but channel>14"); |
4295cd25 LF |
754 | rtlphy->sw_chnl_inprogress = true; |
755 | rtlphy->sw_chnl_stage = 0; | |
756 | rtlphy->sw_chnl_step = 0; | |
757 | if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { | |
758 | rtl92c_phy_sw_chnl_callback(hw); | |
759 | RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, | |
9f087a92 | 760 | "sw_chnl_inprogress false schdule workitem\n"); |
4295cd25 LF |
761 | rtlphy->sw_chnl_inprogress = false; |
762 | } else { | |
763 | RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, | |
f30d7507 | 764 | "sw_chnl_inprogress false driver sleep or unload\n"); |
4295cd25 LF |
765 | rtlphy->sw_chnl_inprogress = false; |
766 | } | |
767 | return 1; | |
768 | } | |
1472d3a8 | 769 | EXPORT_SYMBOL(rtl92c_phy_sw_chnl); |
4295cd25 | 770 | |
9f087a92 | 771 | static void _rtl92c_phy_sw_rf_seting(struct ieee80211_hw *hw, u8 channel) |
0bd899e7 LF |
772 | { |
773 | struct rtl_priv *rtlpriv = rtl_priv(hw); | |
774 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | |
775 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | |
9f087a92 LF |
776 | if (IS_81XXC_VENDOR_UMC_B_CUT(rtlhal->version)) { |
777 | if (channel == 6 && | |
778 | rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) { | |
779 | rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, | |
780 | MASKDWORD, 0x00255); | |
781 | } else { | |
782 | u32 backuprf0x1A = | |
783 | (u32)rtl_get_rfreg(hw, RF90_PATH_A, RF_RX_G1, | |
784 | RFREG_OFFSET_MASK); | |
0bd899e7 | 785 | rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD, |
9f087a92 | 786 | backuprf0x1A); |
0bd899e7 LF |
787 | } |
788 | } | |
789 | } | |
790 | ||
c07ccff3 C |
791 | static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, |
792 | u32 cmdtableidx, u32 cmdtablesz, | |
793 | enum swchnlcmd_id cmdid, | |
794 | u32 para1, u32 para2, u32 msdelay) | |
795 | { | |
796 | struct swchnlcmd *pcmd; | |
797 | ||
798 | if (cmdtable == NULL) { | |
9f087a92 | 799 | RT_ASSERT(false, "cmdtable cannot be NULL.\n"); |
c07ccff3 C |
800 | return false; |
801 | } | |
802 | ||
803 | if (cmdtableidx >= cmdtablesz) | |
804 | return false; | |
805 | ||
806 | pcmd = cmdtable + cmdtableidx; | |
807 | pcmd->cmdid = cmdid; | |
808 | pcmd->para1 = para1; | |
809 | pcmd->para2 = para2; | |
810 | pcmd->msdelay = msdelay; | |
811 | return true; | |
812 | } | |
813 | ||
814 | bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, | |
815 | u8 channel, u8 *stage, u8 *step, | |
816 | u32 *delay) | |
4295cd25 LF |
817 | { |
818 | struct rtl_priv *rtlpriv = rtl_priv(hw); | |
819 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | |
820 | struct swchnlcmd precommoncmd[MAX_PRECMD_CNT]; | |
821 | u32 precommoncmdcnt; | |
822 | struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT]; | |
823 | u32 postcommoncmdcnt; | |
824 | struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT]; | |
825 | u32 rfdependcmdcnt; | |
826 | struct swchnlcmd *currentcmd = NULL; | |
827 | u8 rfpath; | |
828 | u8 num_total_rfpath = rtlphy->num_total_rfpath; | |
829 | ||
830 | precommoncmdcnt = 0; | |
831 | _rtl92c_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, | |
832 | MAX_PRECMD_CNT, | |
833 | CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0); | |
834 | _rtl92c_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, | |
835 | MAX_PRECMD_CNT, CMDID_END, 0, 0, 0); | |
836 | ||
837 | postcommoncmdcnt = 0; | |
838 | ||
839 | _rtl92c_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++, | |
840 | MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0); | |
841 | ||
842 | rfdependcmdcnt = 0; | |
843 | ||
844 | RT_ASSERT((channel >= 1 && channel <= 14), | |
9f087a92 | 845 | "illegal channel for Zebra: %d\n", channel); |
4295cd25 LF |
846 | |
847 | _rtl92c_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, | |
848 | MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG, | |
849 | RF_CHNLBW, channel, 10); | |
850 | ||
851 | _rtl92c_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, | |
852 | MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0, | |
853 | 0); | |
854 | ||
855 | do { | |
856 | switch (*stage) { | |
857 | case 0: | |
858 | currentcmd = &precommoncmd[*step]; | |
859 | break; | |
860 | case 1: | |
861 | currentcmd = &rfdependcmd[*step]; | |
862 | break; | |
863 | case 2: | |
864 | currentcmd = &postcommoncmd[*step]; | |
865 | break; | |
9f087a92 LF |
866 | default: |
867 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | |
868 | "Invalid 'stage' = %d, Check it!\n", *stage); | |
869 | return true; | |
4295cd25 LF |
870 | } |
871 | ||
872 | if (currentcmd->cmdid == CMDID_END) { | |
873 | if ((*stage) == 2) { | |
874 | return true; | |
875 | } else { | |
876 | (*stage)++; | |
877 | (*step) = 0; | |
878 | continue; | |
879 | } | |
880 | } | |
881 | ||
882 | switch (currentcmd->cmdid) { | |
883 | case CMDID_SET_TXPOWEROWER_LEVEL: | |
884 | rtl92c_phy_set_txpower_level(hw, channel); | |
885 | break; | |
886 | case CMDID_WRITEPORT_ULONG: | |
887 | rtl_write_dword(rtlpriv, currentcmd->para1, | |
888 | currentcmd->para2); | |
889 | break; | |
890 | case CMDID_WRITEPORT_USHORT: | |
891 | rtl_write_word(rtlpriv, currentcmd->para1, | |
892 | (u16) currentcmd->para2); | |
893 | break; | |
894 | case CMDID_WRITEPORT_UCHAR: | |
895 | rtl_write_byte(rtlpriv, currentcmd->para1, | |
9f087a92 | 896 | (u8)currentcmd->para2); |
4295cd25 LF |
897 | break; |
898 | case CMDID_RF_WRITEREG: | |
899 | for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) { | |
900 | rtlphy->rfreg_chnlval[rfpath] = | |
901 | ((rtlphy->rfreg_chnlval[rfpath] & | |
902 | 0xfffffc00) | currentcmd->para2); | |
903 | ||
904 | rtl_set_rfreg(hw, (enum radio_path)rfpath, | |
905 | currentcmd->para1, | |
906 | RFREG_OFFSET_MASK, | |
907 | rtlphy->rfreg_chnlval[rfpath]); | |
908 | } | |
9f087a92 | 909 | _rtl92c_phy_sw_rf_seting(hw, channel); |
4295cd25 LF |
910 | break; |
911 | default: | |
9f087a92 LF |
912 | RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, |
913 | "switch case not process\n"); | |
4295cd25 LF |
914 | break; |
915 | } | |
916 | ||
917 | break; | |
918 | } while (true); | |
919 | ||
920 | (*delay) = currentcmd->msdelay; | |
921 | (*step)++; | |
922 | return false; | |
923 | } | |
924 | ||
4295cd25 LF |
925 | bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, u32 rfpath) |
926 | { | |
927 | return true; | |
928 | } | |
1472d3a8 | 929 | EXPORT_SYMBOL(rtl8192_phy_check_is_legal_rfpath); |
4295cd25 LF |
930 | |
931 | static u8 _rtl92c_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb) | |
932 | { | |
933 | u32 reg_eac, reg_e94, reg_e9c, reg_ea4; | |
934 | u8 result = 0x00; | |
935 | ||
936 | rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1f); | |
937 | rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x10008c1f); | |
938 | rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x82140102); | |
939 | rtl_set_bbreg(hw, 0xe3c, MASKDWORD, | |
940 | config_pathb ? 0x28160202 : 0x28160502); | |
941 | ||
942 | if (config_pathb) { | |
943 | rtl_set_bbreg(hw, 0xe50, MASKDWORD, 0x10008c22); | |
944 | rtl_set_bbreg(hw, 0xe54, MASKDWORD, 0x10008c22); | |
945 | rtl_set_bbreg(hw, 0xe58, MASKDWORD, 0x82140102); | |
946 | rtl_set_bbreg(hw, 0xe5c, MASKDWORD, 0x28160202); | |
947 | } | |
948 | ||
949 | rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x001028d1); | |
950 | rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000); | |
951 | rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000); | |
952 | ||
953 | mdelay(IQK_DELAY_TIME); | |
954 | ||
955 | reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); | |
956 | reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD); | |
957 | reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD); | |
958 | reg_ea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD); | |
959 | ||
960 | if (!(reg_eac & BIT(28)) && | |
961 | (((reg_e94 & 0x03FF0000) >> 16) != 0x142) && | |
962 | (((reg_e9c & 0x03FF0000) >> 16) != 0x42)) | |
963 | result |= 0x01; | |
964 | else | |
965 | return result; | |
966 | ||
967 | if (!(reg_eac & BIT(27)) && | |
968 | (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) && | |
969 | (((reg_eac & 0x03FF0000) >> 16) != 0x36)) | |
970 | result |= 0x02; | |
971 | return result; | |
972 | } | |
973 | ||
974 | static u8 _rtl92c_phy_path_b_iqk(struct ieee80211_hw *hw) | |
975 | { | |
976 | u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc; | |
977 | u8 result = 0x00; | |
978 | ||
979 | rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000002); | |
980 | rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000000); | |
981 | mdelay(IQK_DELAY_TIME); | |
982 | reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); | |
983 | reg_eb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD); | |
984 | reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD); | |
985 | reg_ec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD); | |
986 | reg_ecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD); | |
c07ccff3 | 987 | |
4295cd25 LF |
988 | if (!(reg_eac & BIT(31)) && |
989 | (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) && | |
990 | (((reg_ebc & 0x03FF0000) >> 16) != 0x42)) | |
991 | result |= 0x01; | |
992 | else | |
993 | return result; | |
4295cd25 LF |
994 | if (!(reg_eac & BIT(30)) && |
995 | (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) && | |
996 | (((reg_ecc & 0x03FF0000) >> 16) != 0x36)) | |
997 | result |= 0x02; | |
998 | return result; | |
999 | } | |
1000 | ||
1001 | static void _rtl92c_phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw, | |
9f087a92 | 1002 | bool b_iqk_ok, long result[][8], |
4295cd25 LF |
1003 | u8 final_candidate, bool btxonly) |
1004 | { | |
1005 | u32 oldval_0, x, tx0_a, reg; | |
1006 | long y, tx0_c; | |
1007 | ||
c07ccff3 | 1008 | if (final_candidate == 0xFF) { |
4295cd25 | 1009 | return; |
9f087a92 | 1010 | } else if (b_iqk_ok) { |
4295cd25 LF |
1011 | oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, |
1012 | MASKDWORD) >> 22) & 0x3FF; | |
1013 | x = result[final_candidate][0]; | |
1014 | if ((x & 0x00000200) != 0) | |
1015 | x = x | 0xFFFFFC00; | |
1016 | tx0_a = (x * oldval_0) >> 8; | |
1017 | rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx0_a); | |
1018 | rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(31), | |
1019 | ((x * oldval_0 >> 7) & 0x1)); | |
1020 | y = result[final_candidate][1]; | |
1021 | if ((y & 0x00000200) != 0) | |
1022 | y = y | 0xFFFFFC00; | |
1023 | tx0_c = (y * oldval_0) >> 8; | |
1024 | rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000, | |
1025 | ((tx0_c & 0x3C0) >> 6)); | |
1026 | rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x003F0000, | |
1027 | (tx0_c & 0x3F)); | |
1028 | rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(29), | |
1029 | ((y * oldval_0 >> 7) & 0x1)); | |
1030 | if (btxonly) | |
1031 | return; | |
1032 | reg = result[final_candidate][2]; | |
1033 | rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg); | |
1034 | reg = result[final_candidate][3] & 0x3F; | |
1035 | rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg); | |
1036 | reg = (result[final_candidate][3] >> 6) & 0xF; | |
1037 | rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg); | |
1038 | } | |
1039 | } | |
1040 | ||
1041 | static void _rtl92c_phy_path_b_fill_iqk_matrix(struct ieee80211_hw *hw, | |
9f087a92 | 1042 | bool b_iqk_ok, long result[][8], |
4295cd25 LF |
1043 | u8 final_candidate, bool btxonly) |
1044 | { | |
1045 | u32 oldval_1, x, tx1_a, reg; | |
1046 | long y, tx1_c; | |
1047 | ||
c07ccff3 | 1048 | if (final_candidate == 0xFF) { |
4295cd25 | 1049 | return; |
9f087a92 | 1050 | } else if (b_iqk_ok) { |
4295cd25 LF |
1051 | oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, |
1052 | MASKDWORD) >> 22) & 0x3FF; | |
1053 | x = result[final_candidate][4]; | |
1054 | if ((x & 0x00000200) != 0) | |
1055 | x = x | 0xFFFFFC00; | |
1056 | tx1_a = (x * oldval_1) >> 8; | |
1057 | rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x3FF, tx1_a); | |
1058 | rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(27), | |
1059 | ((x * oldval_1 >> 7) & 0x1)); | |
1060 | y = result[final_candidate][5]; | |
1061 | if ((y & 0x00000200) != 0) | |
1062 | y = y | 0xFFFFFC00; | |
1063 | tx1_c = (y * oldval_1) >> 8; | |
1064 | rtl_set_bbreg(hw, ROFDM0_XDTXAFE, 0xF0000000, | |
1065 | ((tx1_c & 0x3C0) >> 6)); | |
1066 | rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x003F0000, | |
1067 | (tx1_c & 0x3F)); | |
1068 | rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(25), | |
1069 | ((y * oldval_1 >> 7) & 0x1)); | |
1070 | if (btxonly) | |
1071 | return; | |
1072 | reg = result[final_candidate][6]; | |
1073 | rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg); | |
1074 | reg = result[final_candidate][7] & 0x3F; | |
1075 | rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg); | |
1076 | reg = (result[final_candidate][7] >> 6) & 0xF; | |
1077 | rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, 0x0000F000, reg); | |
1078 | } | |
1079 | } | |
1080 | ||
1081 | static void _rtl92c_phy_save_adda_registers(struct ieee80211_hw *hw, | |
1082 | u32 *addareg, u32 *addabackup, | |
1083 | u32 registernum) | |
1084 | { | |
1085 | u32 i; | |
1086 | ||
1087 | for (i = 0; i < registernum; i++) | |
1088 | addabackup[i] = rtl_get_bbreg(hw, addareg[i], MASKDWORD); | |
1089 | } | |
1090 | ||
1091 | static void _rtl92c_phy_save_mac_registers(struct ieee80211_hw *hw, | |
1092 | u32 *macreg, u32 *macbackup) | |
1093 | { | |
1094 | struct rtl_priv *rtlpriv = rtl_priv(hw); | |
1095 | u32 i; | |
1096 | ||
1097 | for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) | |
1098 | macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]); | |
1099 | macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]); | |
1100 | } | |
1101 | ||
1102 | static void _rtl92c_phy_reload_adda_registers(struct ieee80211_hw *hw, | |
1103 | u32 *addareg, u32 *addabackup, | |
1104 | u32 regiesternum) | |
1105 | { | |
1106 | u32 i; | |
1107 | ||
1108 | for (i = 0; i < regiesternum; i++) | |
1109 | rtl_set_bbreg(hw, addareg[i], MASKDWORD, addabackup[i]); | |
1110 | } | |
1111 | ||
1112 | static void _rtl92c_phy_reload_mac_registers(struct ieee80211_hw *hw, | |
1113 | u32 *macreg, u32 *macbackup) | |
1114 | { | |
1115 | struct rtl_priv *rtlpriv = rtl_priv(hw); | |
1116 | u32 i; | |
1117 | ||
1118 | for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) | |
9f087a92 | 1119 | rtl_write_byte(rtlpriv, macreg[i], (u8)macbackup[i]); |
4295cd25 LF |
1120 | rtl_write_dword(rtlpriv, macreg[i], macbackup[i]); |
1121 | } | |
1122 | ||
1123 | static void _rtl92c_phy_path_adda_on(struct ieee80211_hw *hw, | |
1124 | u32 *addareg, bool is_patha_on, bool is2t) | |
1125 | { | |
1126 | u32 pathOn; | |
1127 | u32 i; | |
1128 | ||
1129 | pathOn = is_patha_on ? 0x04db25a4 : 0x0b1b25a4; | |
1130 | if (false == is2t) { | |
1131 | pathOn = 0x0bdb25a0; | |
1132 | rtl_set_bbreg(hw, addareg[0], MASKDWORD, 0x0b1b25a0); | |
1133 | } else { | |
1134 | rtl_set_bbreg(hw, addareg[0], MASKDWORD, pathOn); | |
1135 | } | |
1136 | ||
1137 | for (i = 1; i < IQK_ADDA_REG_NUM; i++) | |
1138 | rtl_set_bbreg(hw, addareg[i], MASKDWORD, pathOn); | |
1139 | } | |
1140 | ||
1141 | static void _rtl92c_phy_mac_setting_calibration(struct ieee80211_hw *hw, | |
1142 | u32 *macreg, u32 *macbackup) | |
1143 | { | |
1144 | struct rtl_priv *rtlpriv = rtl_priv(hw); | |
9f087a92 | 1145 | u32 i = 0; |
4295cd25 | 1146 | |
9f087a92 | 1147 | rtl_write_byte(rtlpriv, macreg[i], 0x3F); |
4295cd25 LF |
1148 | |
1149 | for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++) | |
1150 | rtl_write_byte(rtlpriv, macreg[i], | |
9f087a92 LF |
1151 | (u8)(macbackup[i] & (~BIT(3)))); |
1152 | rtl_write_byte(rtlpriv, macreg[i], (u8)(macbackup[i] & (~BIT(5)))); | |
4295cd25 LF |
1153 | } |
1154 | ||
1155 | static void _rtl92c_phy_path_a_standby(struct ieee80211_hw *hw) | |
1156 | { | |
1157 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0); | |
1158 | rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000); | |
1159 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); | |
1160 | } | |
1161 | ||
1162 | static void _rtl92c_phy_pi_mode_switch(struct ieee80211_hw *hw, bool pi_mode) | |
1163 | { | |
1164 | u32 mode; | |
1165 | ||
1166 | mode = pi_mode ? 0x01000100 : 0x01000000; | |
1167 | rtl_set_bbreg(hw, 0x820, MASKDWORD, mode); | |
1168 | rtl_set_bbreg(hw, 0x828, MASKDWORD, mode); | |
1169 | } | |
1170 | ||
1171 | static bool _rtl92c_phy_simularity_compare(struct ieee80211_hw *hw, | |
1172 | long result[][8], u8 c1, u8 c2) | |
1173 | { | |
1174 | u32 i, j, diff, simularity_bitmap, bound; | |
1175 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | |
1176 | ||
1177 | u8 final_candidate[2] = { 0xFF, 0xFF }; | |
1178 | bool bresult = true, is2t = IS_92C_SERIAL(rtlhal->version); | |
1179 | ||
1180 | if (is2t) | |
1181 | bound = 8; | |
1182 | else | |
1183 | bound = 4; | |
1184 | ||
1185 | simularity_bitmap = 0; | |
1186 | ||
1187 | for (i = 0; i < bound; i++) { | |
1188 | diff = (result[c1][i] > result[c2][i]) ? | |
1189 | (result[c1][i] - result[c2][i]) : | |
1190 | (result[c2][i] - result[c1][i]); | |
1191 | ||
1192 | if (diff > MAX_TOLERANCE) { | |
1193 | if ((i == 2 || i == 6) && !simularity_bitmap) { | |
1194 | if (result[c1][i] + result[c1][i + 1] == 0) | |
1195 | final_candidate[(i / 4)] = c2; | |
1196 | else if (result[c2][i] + result[c2][i + 1] == 0) | |
1197 | final_candidate[(i / 4)] = c1; | |
1198 | else | |
1199 | simularity_bitmap = simularity_bitmap | | |
1200 | (1 << i); | |
1201 | } else | |
1202 | simularity_bitmap = | |
1203 | simularity_bitmap | (1 << i); | |
1204 | } | |
1205 | } | |
1206 | ||
1207 | if (simularity_bitmap == 0) { | |
1208 | for (i = 0; i < (bound / 4); i++) { | |
1209 | if (final_candidate[i] != 0xFF) { | |
1210 | for (j = i * 4; j < (i + 1) * 4 - 2; j++) | |
1211 | result[3][j] = | |
1212 | result[final_candidate[i]][j]; | |
1213 | bresult = false; | |
1214 | } | |
1215 | } | |
1216 | return bresult; | |
1217 | } else if (!(simularity_bitmap & 0x0F)) { | |
1218 | for (i = 0; i < 4; i++) | |
1219 | result[3][i] = result[c1][i]; | |
1220 | return false; | |
1221 | } else if (!(simularity_bitmap & 0xF0) && is2t) { | |
1222 | for (i = 4; i < 8; i++) | |
1223 | result[3][i] = result[c1][i]; | |
1224 | return false; | |
1225 | } else { | |
1226 | return false; | |
1227 | } | |
4295cd25 LF |
1228 | } |
1229 | ||
1230 | static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, | |
1231 | long result[][8], u8 t, bool is2t) | |
1232 | { | |
1233 | struct rtl_priv *rtlpriv = rtl_priv(hw); | |
1234 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | |
1235 | u32 i; | |
1236 | u8 patha_ok, pathb_ok; | |
1237 | u32 adda_reg[IQK_ADDA_REG_NUM] = { | |
1238 | 0x85c, 0xe6c, 0xe70, 0xe74, | |
1239 | 0xe78, 0xe7c, 0xe80, 0xe84, | |
1240 | 0xe88, 0xe8c, 0xed0, 0xed4, | |
1241 | 0xed8, 0xedc, 0xee0, 0xeec | |
1242 | }; | |
4295cd25 LF |
1243 | u32 iqk_mac_reg[IQK_MAC_REG_NUM] = { |
1244 | 0x522, 0x550, 0x551, 0x040 | |
1245 | }; | |
4295cd25 | 1246 | const u32 retrycount = 2; |
9f087a92 | 1247 | u32 bbvalue; |
4295cd25 | 1248 | |
4295cd25 | 1249 | if (t == 0) { |
9f087a92 | 1250 | bbvalue = rtl_get_bbreg(hw, 0x800, MASKDWORD); |
4295cd25 LF |
1251 | |
1252 | _rtl92c_phy_save_adda_registers(hw, adda_reg, | |
1253 | rtlphy->adda_backup, 16); | |
1254 | _rtl92c_phy_save_mac_registers(hw, iqk_mac_reg, | |
1255 | rtlphy->iqk_mac_backup); | |
1256 | } | |
1257 | _rtl92c_phy_path_adda_on(hw, adda_reg, true, is2t); | |
1258 | if (t == 0) { | |
9f087a92 LF |
1259 | rtlphy->rfpi_enable = |
1260 | (u8)rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1, | |
1261 | BIT(8)); | |
4295cd25 | 1262 | } |
c07ccff3 | 1263 | |
4295cd25 LF |
1264 | if (!rtlphy->rfpi_enable) |
1265 | _rtl92c_phy_pi_mode_switch(hw, true); | |
9f087a92 LF |
1266 | if (t == 0) { |
1267 | rtlphy->reg_c04 = rtl_get_bbreg(hw, 0xc04, MASKDWORD); | |
1268 | rtlphy->reg_c08 = rtl_get_bbreg(hw, 0xc08, MASKDWORD); | |
1269 | rtlphy->reg_874 = rtl_get_bbreg(hw, 0x874, MASKDWORD); | |
1270 | } | |
4295cd25 LF |
1271 | rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600); |
1272 | rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4); | |
1273 | rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000); | |
1274 | if (is2t) { | |
1275 | rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000); | |
1276 | rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000); | |
1277 | } | |
1278 | _rtl92c_phy_mac_setting_calibration(hw, iqk_mac_reg, | |
1279 | rtlphy->iqk_mac_backup); | |
1280 | rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x00080000); | |
1281 | if (is2t) | |
1282 | rtl_set_bbreg(hw, 0xb6c, MASKDWORD, 0x00080000); | |
1283 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); | |
1284 | rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00); | |
1285 | rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x01004800); | |
1286 | for (i = 0; i < retrycount; i++) { | |
1287 | patha_ok = _rtl92c_phy_path_a_iqk(hw, is2t); | |
1288 | if (patha_ok == 0x03) { | |
1289 | result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) & | |
1290 | 0x3FF0000) >> 16; | |
1291 | result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & | |
1292 | 0x3FF0000) >> 16; | |
1293 | result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) & | |
1294 | 0x3FF0000) >> 16; | |
1295 | result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) & | |
1296 | 0x3FF0000) >> 16; | |
1297 | break; | |
1298 | } else if (i == (retrycount - 1) && patha_ok == 0x01) | |
c07ccff3 | 1299 | |
4295cd25 LF |
1300 | result[t][0] = (rtl_get_bbreg(hw, 0xe94, |
1301 | MASKDWORD) & 0x3FF0000) >> | |
c07ccff3 | 1302 | 16; |
4295cd25 LF |
1303 | result[t][1] = |
1304 | (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & 0x3FF0000) >> 16; | |
1305 | ||
1306 | } | |
1307 | ||
1308 | if (is2t) { | |
1309 | _rtl92c_phy_path_a_standby(hw); | |
1310 | _rtl92c_phy_path_adda_on(hw, adda_reg, false, is2t); | |
1311 | for (i = 0; i < retrycount; i++) { | |
1312 | pathb_ok = _rtl92c_phy_path_b_iqk(hw); | |
1313 | if (pathb_ok == 0x03) { | |
1314 | result[t][4] = (rtl_get_bbreg(hw, | |
9f087a92 LF |
1315 | 0xeb4, |
1316 | MASKDWORD) & | |
4295cd25 LF |
1317 | 0x3FF0000) >> 16; |
1318 | result[t][5] = | |
1319 | (rtl_get_bbreg(hw, 0xebc, MASKDWORD) & | |
1320 | 0x3FF0000) >> 16; | |
1321 | result[t][6] = | |
1322 | (rtl_get_bbreg(hw, 0xec4, MASKDWORD) & | |
1323 | 0x3FF0000) >> 16; | |
1324 | result[t][7] = | |
1325 | (rtl_get_bbreg(hw, 0xecc, MASKDWORD) & | |
1326 | 0x3FF0000) >> 16; | |
1327 | break; | |
1328 | } else if (i == (retrycount - 1) && pathb_ok == 0x01) { | |
1329 | result[t][4] = (rtl_get_bbreg(hw, | |
9f087a92 LF |
1330 | 0xeb4, |
1331 | MASKDWORD) & | |
4295cd25 LF |
1332 | 0x3FF0000) >> 16; |
1333 | } | |
1334 | result[t][5] = (rtl_get_bbreg(hw, 0xebc, MASKDWORD) & | |
1335 | 0x3FF0000) >> 16; | |
1336 | } | |
1337 | } | |
9f087a92 LF |
1338 | rtl_set_bbreg(hw, 0xc04, MASKDWORD, rtlphy->reg_c04); |
1339 | rtl_set_bbreg(hw, 0x874, MASKDWORD, rtlphy->reg_874); | |
1340 | rtl_set_bbreg(hw, 0xc08, MASKDWORD, rtlphy->reg_c08); | |
4295cd25 | 1341 | rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0); |
9f087a92 LF |
1342 | rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3); |
1343 | if (is2t) | |
1344 | rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3); | |
4295cd25 LF |
1345 | if (t != 0) { |
1346 | if (!rtlphy->rfpi_enable) | |
1347 | _rtl92c_phy_pi_mode_switch(hw, false); | |
1348 | _rtl92c_phy_reload_adda_registers(hw, adda_reg, | |
1349 | rtlphy->adda_backup, 16); | |
1350 | _rtl92c_phy_reload_mac_registers(hw, iqk_mac_reg, | |
1351 | rtlphy->iqk_mac_backup); | |
1352 | } | |
1353 | } | |
1354 | ||
1355 | static void _rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, | |
1356 | char delta, bool is2t) | |
1357 | { | |
4295cd25 LF |
1358 | } |
1359 | ||
1360 | static void _rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, | |
1361 | bool bmain, bool is2t) | |
1362 | { | |
1363 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | |
1364 | ||
1365 | if (is_hal_stop(rtlhal)) { | |
1366 | rtl_set_bbreg(hw, REG_LEDCFG0, BIT(23), 0x01); | |
1367 | rtl_set_bbreg(hw, rFPGA0_XAB_RFPARAMETER, BIT(13), 0x01); | |
1368 | } | |
1369 | if (is2t) { | |
1370 | if (bmain) | |
1371 | rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, | |
1372 | BIT(5) | BIT(6), 0x1); | |
1373 | else | |
1374 | rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, | |
1375 | BIT(5) | BIT(6), 0x2); | |
1376 | } else { | |
1377 | if (bmain) | |
1378 | rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x2); | |
1379 | else | |
1380 | rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x1); | |
4295cd25 LF |
1381 | } |
1382 | } | |
1383 | ||
1384 | #undef IQK_ADDA_REG_NUM | |
1385 | #undef IQK_DELAY_TIME | |
1386 | ||
9f087a92 | 1387 | void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery) |
4295cd25 LF |
1388 | { |
1389 | struct rtl_priv *rtlpriv = rtl_priv(hw); | |
1390 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | |
1391 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | |
1392 | ||
1393 | long result[4][8]; | |
1394 | u8 i, final_candidate; | |
9f087a92 LF |
1395 | bool b_patha_ok, b_pathb_ok; |
1396 | long reg_e94, reg_e9c, reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4, | |
1397 | reg_ecc, reg_tmp = 0; | |
4295cd25 | 1398 | bool is12simular, is13simular, is23simular; |
4295cd25 LF |
1399 | u32 iqk_bb_reg[10] = { |
1400 | ROFDM0_XARXIQIMBALANCE, | |
1401 | ROFDM0_XBRXIQIMBALANCE, | |
1402 | ROFDM0_ECCATHRESHOLD, | |
1403 | ROFDM0_AGCRSSITABLE, | |
1404 | ROFDM0_XATXIQIMBALANCE, | |
1405 | ROFDM0_XBTXIQIMBALANCE, | |
1406 | ROFDM0_XCTXIQIMBALANCE, | |
1407 | ROFDM0_XCTXAFE, | |
1408 | ROFDM0_XDTXAFE, | |
1409 | ROFDM0_RXIQEXTANTA | |
1410 | }; | |
1411 | ||
9f087a92 | 1412 | if (b_recovery) { |
4295cd25 LF |
1413 | _rtl92c_phy_reload_adda_registers(hw, |
1414 | iqk_bb_reg, | |
1415 | rtlphy->iqk_bb_backup, 10); | |
1416 | return; | |
1417 | } | |
4295cd25 LF |
1418 | for (i = 0; i < 8; i++) { |
1419 | result[0][i] = 0; | |
1420 | result[1][i] = 0; | |
1421 | result[2][i] = 0; | |
1422 | result[3][i] = 0; | |
1423 | } | |
1424 | final_candidate = 0xff; | |
9f087a92 LF |
1425 | b_patha_ok = false; |
1426 | b_pathb_ok = false; | |
4295cd25 LF |
1427 | is12simular = false; |
1428 | is23simular = false; | |
1429 | is13simular = false; | |
1430 | for (i = 0; i < 3; i++) { | |
1431 | if (IS_92C_SERIAL(rtlhal->version)) | |
1432 | _rtl92c_phy_iq_calibrate(hw, result, i, true); | |
1433 | else | |
1434 | _rtl92c_phy_iq_calibrate(hw, result, i, false); | |
1435 | if (i == 1) { | |
1436 | is12simular = _rtl92c_phy_simularity_compare(hw, | |
1437 | result, 0, | |
1438 | 1); | |
1439 | if (is12simular) { | |
1440 | final_candidate = 0; | |
1441 | break; | |
1442 | } | |
1443 | } | |
1444 | if (i == 2) { | |
1445 | is13simular = _rtl92c_phy_simularity_compare(hw, | |
1446 | result, 0, | |
1447 | 2); | |
1448 | if (is13simular) { | |
1449 | final_candidate = 0; | |
1450 | break; | |
1451 | } | |
1452 | is23simular = _rtl92c_phy_simularity_compare(hw, | |
1453 | result, 1, | |
1454 | 2); | |
1455 | if (is23simular) | |
1456 | final_candidate = 1; | |
1457 | else { | |
1458 | for (i = 0; i < 8; i++) | |
1459 | reg_tmp += result[3][i]; | |
1460 | ||
1461 | if (reg_tmp != 0) | |
1462 | final_candidate = 3; | |
1463 | else | |
1464 | final_candidate = 0xFF; | |
1465 | } | |
1466 | } | |
1467 | } | |
1468 | for (i = 0; i < 4; i++) { | |
1469 | reg_e94 = result[i][0]; | |
1470 | reg_e9c = result[i][1]; | |
1471 | reg_ea4 = result[i][2]; | |
9f087a92 | 1472 | reg_eac = result[i][3]; |
4295cd25 LF |
1473 | reg_eb4 = result[i][4]; |
1474 | reg_ebc = result[i][5]; | |
1475 | reg_ec4 = result[i][6]; | |
9f087a92 | 1476 | reg_ecc = result[i][7]; |
4295cd25 LF |
1477 | } |
1478 | if (final_candidate != 0xff) { | |
1479 | rtlphy->reg_e94 = reg_e94 = result[final_candidate][0]; | |
1480 | rtlphy->reg_e9c = reg_e9c = result[final_candidate][1]; | |
1481 | reg_ea4 = result[final_candidate][2]; | |
9f087a92 | 1482 | reg_eac = result[final_candidate][3]; |
4295cd25 LF |
1483 | rtlphy->reg_eb4 = reg_eb4 = result[final_candidate][4]; |
1484 | rtlphy->reg_ebc = reg_ebc = result[final_candidate][5]; | |
1485 | reg_ec4 = result[final_candidate][6]; | |
9f087a92 LF |
1486 | reg_ecc = result[final_candidate][7]; |
1487 | b_patha_ok = true; | |
1488 | b_pathb_ok = true; | |
4295cd25 LF |
1489 | } else { |
1490 | rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100; | |
1491 | rtlphy->reg_e9c = rtlphy->reg_ebc = 0x0; | |
1492 | } | |
1493 | if (reg_e94 != 0) /*&&(reg_ea4 != 0) */ | |
9f087a92 | 1494 | _rtl92c_phy_path_a_fill_iqk_matrix(hw, b_patha_ok, result, |
4295cd25 LF |
1495 | final_candidate, |
1496 | (reg_ea4 == 0)); | |
1497 | if (IS_92C_SERIAL(rtlhal->version)) { | |
1498 | if (reg_eb4 != 0) /*&&(reg_ec4 != 0) */ | |
9f087a92 | 1499 | _rtl92c_phy_path_b_fill_iqk_matrix(hw, b_pathb_ok, |
4295cd25 LF |
1500 | result, |
1501 | final_candidate, | |
1502 | (reg_ec4 == 0)); | |
1503 | } | |
1504 | _rtl92c_phy_save_adda_registers(hw, iqk_bb_reg, | |
1505 | rtlphy->iqk_bb_backup, 10); | |
1506 | } | |
1472d3a8 | 1507 | EXPORT_SYMBOL(rtl92c_phy_iq_calibrate); |
4295cd25 LF |
1508 | |
1509 | void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw) | |
1510 | { | |
1472d3a8 | 1511 | struct rtl_priv *rtlpriv = rtl_priv(hw); |
4295cd25 | 1512 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); |
4295cd25 | 1513 | |
4295cd25 | 1514 | if (IS_92C_SERIAL(rtlhal->version)) |
1472d3a8 | 1515 | rtlpriv->cfg->ops->phy_lc_calibrate(hw, true); |
4295cd25 | 1516 | else |
1472d3a8 | 1517 | rtlpriv->cfg->ops->phy_lc_calibrate(hw, false); |
4295cd25 | 1518 | } |
1472d3a8 | 1519 | EXPORT_SYMBOL(rtl92c_phy_lc_calibrate); |
4295cd25 LF |
1520 | |
1521 | void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta) | |
1522 | { | |
1523 | struct rtl_priv *rtlpriv = rtl_priv(hw); | |
1524 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | |
1525 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | |
1526 | ||
1527 | if (rtlphy->apk_done) | |
1528 | return; | |
1529 | if (IS_92C_SERIAL(rtlhal->version)) | |
1530 | _rtl92c_phy_ap_calibrate(hw, delta, true); | |
1531 | else | |
1532 | _rtl92c_phy_ap_calibrate(hw, delta, false); | |
1533 | } | |
1472d3a8 | 1534 | EXPORT_SYMBOL(rtl92c_phy_ap_calibrate); |
4295cd25 LF |
1535 | |
1536 | void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain) | |
1537 | { | |
1538 | struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); | |
1539 | ||
1540 | if (IS_92C_SERIAL(rtlhal->version)) | |
1541 | _rtl92c_phy_set_rfpath_switch(hw, bmain, true); | |
1542 | else | |
1543 | _rtl92c_phy_set_rfpath_switch(hw, bmain, false); | |
1544 | } | |
1472d3a8 | 1545 | EXPORT_SYMBOL(rtl92c_phy_set_rfpath_switch); |
4295cd25 LF |
1546 | |
1547 | bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) | |
1548 | { | |
1549 | struct rtl_priv *rtlpriv = rtl_priv(hw); | |
1550 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | |
1551 | bool postprocessing = false; | |
1552 | ||
1553 | RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, | |
f30d7507 | 1554 | "-->IO Cmd(%#x), set_io_inprogress(%d)\n", |
9f087a92 | 1555 | iotype, rtlphy->set_io_inprogress); |
4295cd25 LF |
1556 | do { |
1557 | switch (iotype) { | |
1558 | case IO_CMD_RESUME_DM_BY_SCAN: | |
1559 | RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, | |
9f087a92 | 1560 | "[IO CMD] Resume DM after scan.\n"); |
4295cd25 LF |
1561 | postprocessing = true; |
1562 | break; | |
9f087a92 | 1563 | case IO_CMD_PAUSE_BAND0_DM_BY_SCAN: |
4295cd25 | 1564 | RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, |
9f087a92 | 1565 | "[IO CMD] Pause DM before scan.\n"); |
4295cd25 LF |
1566 | postprocessing = true; |
1567 | break; | |
1568 | default: | |
9f087a92 LF |
1569 | RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, |
1570 | "switch case not process\n"); | |
4295cd25 LF |
1571 | break; |
1572 | } | |
1573 | } while (false); | |
1574 | if (postprocessing && !rtlphy->set_io_inprogress) { | |
1575 | rtlphy->set_io_inprogress = true; | |
1576 | rtlphy->current_io_type = iotype; | |
1577 | } else { | |
1578 | return false; | |
1579 | } | |
1580 | rtl92c_phy_set_io(hw); | |
9f087a92 | 1581 | RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype); |
4295cd25 LF |
1582 | return true; |
1583 | } | |
1472d3a8 | 1584 | EXPORT_SYMBOL(rtl92c_phy_set_io_cmd); |
4295cd25 LF |
1585 | |
1586 | void rtl92c_phy_set_io(struct ieee80211_hw *hw) | |
1587 | { | |
1588 | struct rtl_priv *rtlpriv = rtl_priv(hw); | |
1589 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | |
9f087a92 | 1590 | struct dig_t *dm_digtable = &rtlpriv->dm_digtable; |
4295cd25 LF |
1591 | |
1592 | RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, | |
f30d7507 | 1593 | "--->Cmd(%#x), set_io_inprogress(%d)\n", |
9f087a92 | 1594 | rtlphy->current_io_type, rtlphy->set_io_inprogress); |
4295cd25 LF |
1595 | switch (rtlphy->current_io_type) { |
1596 | case IO_CMD_RESUME_DM_BY_SCAN: | |
9f087a92 | 1597 | dm_digtable->cur_igvalue = rtlphy->initgain_backup.xaagccore1; |
4295cd25 LF |
1598 | rtl92c_dm_write_dig(hw); |
1599 | rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); | |
1600 | break; | |
9f087a92 LF |
1601 | case IO_CMD_PAUSE_BAND0_DM_BY_SCAN: |
1602 | rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue; | |
1603 | dm_digtable->cur_igvalue = 0x17; | |
4295cd25 LF |
1604 | rtl92c_dm_write_dig(hw); |
1605 | break; | |
1606 | default: | |
9f087a92 LF |
1607 | RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, |
1608 | "switch case not process\n"); | |
4295cd25 LF |
1609 | break; |
1610 | } | |
1611 | rtlphy->set_io_inprogress = false; | |
9f087a92 LF |
1612 | RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, |
1613 | "(%#x)\n", rtlphy->current_io_type); | |
4295cd25 | 1614 | } |
1472d3a8 | 1615 | EXPORT_SYMBOL(rtl92c_phy_set_io); |
4295cd25 LF |
1616 | |
1617 | void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw) | |
1618 | { | |
1619 | struct rtl_priv *rtlpriv = rtl_priv(hw); | |
1620 | ||
1621 | rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b); | |
1622 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); | |
1623 | rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00); | |
1624 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); | |
1625 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); | |
1626 | rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); | |
1627 | } | |
1472d3a8 | 1628 | EXPORT_SYMBOL(rtl92ce_phy_set_rf_on); |
4295cd25 | 1629 | |
1472d3a8 | 1630 | void _rtl92c_phy_set_rf_sleep(struct ieee80211_hw *hw) |
4295cd25 LF |
1631 | { |
1632 | u32 u4b_tmp; | |
1633 | u8 delay = 5; | |
1634 | struct rtl_priv *rtlpriv = rtl_priv(hw); | |
1635 | ||
1636 | rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); | |
1637 | rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); | |
1638 | rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); | |
1639 | u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK); | |
1640 | while (u4b_tmp != 0 && delay > 0) { | |
1641 | rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0); | |
1642 | rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); | |
1643 | rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); | |
1644 | u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK); | |
1645 | delay--; | |
1646 | } | |
1647 | if (delay == 0) { | |
1648 | rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00); | |
1649 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); | |
1650 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); | |
1651 | rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); | |
1652 | RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, | |
9f087a92 | 1653 | "Switch RF timeout !!!.\n"); |
4295cd25 LF |
1654 | return; |
1655 | } | |
1656 | rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); | |
1657 | rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22); | |
1658 | } | |
1472d3a8 | 1659 | EXPORT_SYMBOL(_rtl92c_phy_set_rf_sleep); |