diff options
Diffstat (limited to 'drivers/net/wireless/rtlwifi/rtl8192se/rf.c')
-rw-r--r-- | drivers/net/wireless/rtlwifi/rtl8192se/rf.c | 546 |
1 files changed, 546 insertions, 0 deletions
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/rf.c b/drivers/net/wireless/rtlwifi/rtl8192se/rf.c new file mode 100644 index 00000000000..1d3a4833039 --- /dev/null +++ b/drivers/net/wireless/rtlwifi/rtl8192se/rf.c | |||
@@ -0,0 +1,546 @@ | |||
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 | #include "../wifi.h" | ||
31 | #include "reg.h" | ||
32 | #include "def.h" | ||
33 | #include "phy.h" | ||
34 | #include "rf.h" | ||
35 | #include "dm.h" | ||
36 | |||
37 | |||
38 | static void _rtl92s_get_powerbase(struct ieee80211_hw *hw, u8 *p_pwrlevel, | ||
39 | u8 chnl, u32 *ofdmbase, u32 *mcsbase, | ||
40 | u8 *p_final_pwridx) | ||
41 | { | ||
42 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
43 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
44 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
45 | u32 pwrbase0, pwrbase1; | ||
46 | u8 legacy_pwrdiff = 0, ht20_pwrdiff = 0; | ||
47 | u8 i, pwrlevel[4]; | ||
48 | |||
49 | for (i = 0; i < 2; i++) | ||
50 | pwrlevel[i] = p_pwrlevel[i]; | ||
51 | |||
52 | /* We only care about the path A for legacy. */ | ||
53 | if (rtlefuse->eeprom_version < 2) { | ||
54 | pwrbase0 = pwrlevel[0] + (rtlefuse->legacy_httxpowerdiff & 0xf); | ||
55 | } else if (rtlefuse->eeprom_version >= 2) { | ||
56 | legacy_pwrdiff = rtlefuse->txpwr_legacyhtdiff | ||
57 | [RF90_PATH_A][chnl - 1]; | ||
58 | |||
59 | /* For legacy OFDM, tx pwr always > HT OFDM pwr. | ||
60 | * We do not care Path B | ||
61 | * legacy OFDM pwr diff. NO BB register | ||
62 | * to notify HW. */ | ||
63 | pwrbase0 = pwrlevel[0] + legacy_pwrdiff; | ||
64 | } | ||
65 | |||
66 | pwrbase0 = (pwrbase0 << 24) | (pwrbase0 << 16) | (pwrbase0 << 8) | | ||
67 | pwrbase0; | ||
68 | *ofdmbase = pwrbase0; | ||
69 | |||
70 | /* MCS rates */ | ||
71 | if (rtlefuse->eeprom_version >= 2) { | ||
72 | /* Check HT20 to HT40 diff */ | ||
73 | if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20) { | ||
74 | for (i = 0; i < 2; i++) { | ||
75 | /* rf-A, rf-B */ | ||
76 | /* HT 20<->40 pwr diff */ | ||
77 | ht20_pwrdiff = rtlefuse->txpwr_ht20diff | ||
78 | [i][chnl - 1]; | ||
79 | |||
80 | if (ht20_pwrdiff < 8) /* 0~+7 */ | ||
81 | pwrlevel[i] += ht20_pwrdiff; | ||
82 | else /* index8-15=-8~-1 */ | ||
83 | pwrlevel[i] -= (16 - ht20_pwrdiff); | ||
84 | } | ||
85 | } | ||
86 | } | ||
87 | |||
88 | /* use index of rf-A */ | ||
89 | pwrbase1 = pwrlevel[0]; | ||
90 | pwrbase1 = (pwrbase1 << 24) | (pwrbase1 << 16) | (pwrbase1 << 8) | | ||
91 | pwrbase1; | ||
92 | *mcsbase = pwrbase1; | ||
93 | |||
94 | /* The following is for Antenna | ||
95 | * diff from Ant-B to Ant-A */ | ||
96 | p_final_pwridx[0] = pwrlevel[0]; | ||
97 | p_final_pwridx[1] = pwrlevel[1]; | ||
98 | |||
99 | switch (rtlefuse->eeprom_regulatory) { | ||
100 | case 3: | ||
101 | /* The following is for calculation | ||
102 | * of the power diff for Ant-B to Ant-A. */ | ||
103 | if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { | ||
104 | p_final_pwridx[0] += rtlefuse->pwrgroup_ht40 | ||
105 | [RF90_PATH_A][ | ||
106 | chnl - 1]; | ||
107 | p_final_pwridx[1] += rtlefuse->pwrgroup_ht40 | ||
108 | [RF90_PATH_B][ | ||
109 | chnl - 1]; | ||
110 | } else { | ||
111 | p_final_pwridx[0] += rtlefuse->pwrgroup_ht20 | ||
112 | [RF90_PATH_A][ | ||
113 | chnl - 1]; | ||
114 | p_final_pwridx[1] += rtlefuse->pwrgroup_ht20 | ||
115 | [RF90_PATH_B][ | ||
116 | chnl - 1]; | ||
117 | } | ||
118 | break; | ||
119 | default: | ||
120 | break; | ||
121 | } | ||
122 | |||
123 | if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { | ||
124 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("40MHz finalpwr_idx " | ||
125 | "(A / B) = 0x%x / 0x%x\n", p_final_pwridx[0], | ||
126 | p_final_pwridx[1])); | ||
127 | } else { | ||
128 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, ("20MHz finalpwr_idx " | ||
129 | "(A / B) = 0x%x / 0x%x\n", p_final_pwridx[0], | ||
130 | p_final_pwridx[1])); | ||
131 | } | ||
132 | } | ||
133 | |||
134 | static void _rtl92s_set_antennadiff(struct ieee80211_hw *hw, | ||
135 | u8 *p_final_pwridx) | ||
136 | { | ||
137 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
138 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
139 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
140 | char ant_pwr_diff = 0; | ||
141 | u32 u4reg_val = 0; | ||
142 | |||
143 | if (rtlphy->rf_type == RF_2T2R) { | ||
144 | ant_pwr_diff = p_final_pwridx[1] - p_final_pwridx[0]; | ||
145 | |||
146 | /* range is from 7~-8, | ||
147 | * index = 0x0~0xf */ | ||
148 | if (ant_pwr_diff > 7) | ||
149 | ant_pwr_diff = 7; | ||
150 | if (ant_pwr_diff < -8) | ||
151 | ant_pwr_diff = -8; | ||
152 | |||
153 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
154 | ("Antenna Diff from RF-B " | ||
155 | "to RF-A = %d (0x%x)\n", ant_pwr_diff, | ||
156 | ant_pwr_diff & 0xf)); | ||
157 | |||
158 | ant_pwr_diff &= 0xf; | ||
159 | } | ||
160 | |||
161 | /* Antenna TX power difference */ | ||
162 | rtlefuse->antenna_txpwdiff[2] = 0;/* RF-D, don't care */ | ||
163 | rtlefuse->antenna_txpwdiff[1] = 0;/* RF-C, don't care */ | ||
164 | rtlefuse->antenna_txpwdiff[0] = (u8)(ant_pwr_diff); /* RF-B */ | ||
165 | |||
166 | u4reg_val = rtlefuse->antenna_txpwdiff[2] << 8 | | ||
167 | rtlefuse->antenna_txpwdiff[1] << 4 | | ||
168 | rtlefuse->antenna_txpwdiff[0]; | ||
169 | |||
170 | rtl_set_bbreg(hw, RFPGA0_TXGAINSTAGE, (BXBTXAGC | BXCTXAGC | BXDTXAGC), | ||
171 | u4reg_val); | ||
172 | |||
173 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
174 | ("Write BCD-Diff(0x%x) = 0x%x\n", | ||
175 | RFPGA0_TXGAINSTAGE, u4reg_val)); | ||
176 | } | ||
177 | |||
178 | static void _rtl92s_get_txpower_writeval_byregulatory(struct ieee80211_hw *hw, | ||
179 | u8 chnl, u8 index, | ||
180 | u32 pwrbase0, | ||
181 | u32 pwrbase1, | ||
182 | u32 *p_outwrite_val) | ||
183 | { | ||
184 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
185 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
186 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
187 | u8 i, chnlgroup, pwrdiff_limit[4]; | ||
188 | u32 writeval, customer_limit; | ||
189 | |||
190 | /* Index 0 & 1= legacy OFDM, 2-5=HT_MCS rate */ | ||
191 | switch (rtlefuse->eeprom_regulatory) { | ||
192 | case 0: | ||
193 | /* Realtek better performance increase power diff | ||
194 | * defined by Realtek for large power */ | ||
195 | chnlgroup = 0; | ||
196 | |||
197 | writeval = rtlphy->mcs_txpwrlevel_origoffset | ||
198 | [chnlgroup][index] + | ||
199 | ((index < 2) ? pwrbase0 : pwrbase1); | ||
200 | |||
201 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
202 | ("RTK better performance, " | ||
203 | "writeval = 0x%x\n", writeval)); | ||
204 | break; | ||
205 | case 1: | ||
206 | /* Realtek regulatory increase power diff defined | ||
207 | * by Realtek for regulatory */ | ||
208 | if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { | ||
209 | writeval = ((index < 2) ? pwrbase0 : pwrbase1); | ||
210 | |||
211 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
212 | ("Realtek regulatory, " | ||
213 | "40MHz, writeval = 0x%x\n", writeval)); | ||
214 | } else { | ||
215 | if (rtlphy->pwrgroup_cnt == 1) | ||
216 | chnlgroup = 0; | ||
217 | |||
218 | if (rtlphy->pwrgroup_cnt >= 3) { | ||
219 | if (chnl <= 3) | ||
220 | chnlgroup = 0; | ||
221 | else if (chnl >= 4 && chnl <= 8) | ||
222 | chnlgroup = 1; | ||
223 | else if (chnl > 8) | ||
224 | chnlgroup = 2; | ||
225 | if (rtlphy->pwrgroup_cnt == 4) | ||
226 | chnlgroup++; | ||
227 | } | ||
228 | |||
229 | writeval = rtlphy->mcs_txpwrlevel_origoffset | ||
230 | [chnlgroup][index] | ||
231 | + ((index < 2) ? | ||
232 | pwrbase0 : pwrbase1); | ||
233 | |||
234 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
235 | ("Realtek regulatory, " | ||
236 | "20MHz, writeval = 0x%x\n", writeval)); | ||
237 | } | ||
238 | break; | ||
239 | case 2: | ||
240 | /* Better regulatory don't increase any power diff */ | ||
241 | writeval = ((index < 2) ? pwrbase0 : pwrbase1); | ||
242 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
243 | ("Better regulatory, " | ||
244 | "writeval = 0x%x\n", writeval)); | ||
245 | break; | ||
246 | case 3: | ||
247 | /* Customer defined power diff. increase power diff | ||
248 | defined by customer. */ | ||
249 | chnlgroup = 0; | ||
250 | |||
251 | if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { | ||
252 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
253 | ("customer's limit, 40MHz = 0x%x\n", | ||
254 | rtlefuse->pwrgroup_ht40 | ||
255 | [RF90_PATH_A][chnl - 1])); | ||
256 | } else { | ||
257 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
258 | ("customer's limit, 20MHz = 0x%x\n", | ||
259 | rtlefuse->pwrgroup_ht20 | ||
260 | [RF90_PATH_A][chnl - 1])); | ||
261 | } | ||
262 | |||
263 | for (i = 0; i < 4; i++) { | ||
264 | pwrdiff_limit[i] = | ||
265 | (u8)((rtlphy->mcs_txpwrlevel_origoffset | ||
266 | [chnlgroup][index] & (0x7f << (i * 8))) | ||
267 | >> (i * 8)); | ||
268 | |||
269 | if (rtlphy->current_chan_bw == | ||
270 | HT_CHANNEL_WIDTH_20_40) { | ||
271 | if (pwrdiff_limit[i] > | ||
272 | rtlefuse->pwrgroup_ht40 | ||
273 | [RF90_PATH_A][chnl - 1]) { | ||
274 | pwrdiff_limit[i] = | ||
275 | rtlefuse->pwrgroup_ht20 | ||
276 | [RF90_PATH_A][chnl - 1]; | ||
277 | } | ||
278 | } else { | ||
279 | if (pwrdiff_limit[i] > | ||
280 | rtlefuse->pwrgroup_ht20 | ||
281 | [RF90_PATH_A][chnl - 1]) { | ||
282 | pwrdiff_limit[i] = | ||
283 | rtlefuse->pwrgroup_ht20 | ||
284 | [RF90_PATH_A][chnl - 1]; | ||
285 | } | ||
286 | } | ||
287 | } | ||
288 | |||
289 | customer_limit = (pwrdiff_limit[3] << 24) | | ||
290 | (pwrdiff_limit[2] << 16) | | ||
291 | (pwrdiff_limit[1] << 8) | | ||
292 | (pwrdiff_limit[0]); | ||
293 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
294 | ("Customer's limit = 0x%x\n", | ||
295 | customer_limit)); | ||
296 | |||
297 | writeval = customer_limit + ((index < 2) ? | ||
298 | pwrbase0 : pwrbase1); | ||
299 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
300 | ("Customer, writeval = " | ||
301 | "0x%x\n", writeval)); | ||
302 | break; | ||
303 | default: | ||
304 | chnlgroup = 0; | ||
305 | writeval = rtlphy->mcs_txpwrlevel_origoffset[chnlgroup][index] + | ||
306 | ((index < 2) ? pwrbase0 : pwrbase1); | ||
307 | RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, | ||
308 | ("RTK better performance, " | ||
309 | "writeval = 0x%x\n", writeval)); | ||
310 | break; | ||
311 | } | ||
312 | |||
313 | if (rtlpriv->dm.dynamic_txhighpower_lvl == TX_HIGH_PWR_LEVEL_LEVEL1) | ||
314 | writeval = 0x10101010; | ||
315 | else if (rtlpriv->dm.dynamic_txhighpower_lvl == | ||
316 | TX_HIGH_PWR_LEVEL_LEVEL2) | ||
317 | writeval = 0x0; | ||
318 | |||
319 | *p_outwrite_val = writeval; | ||
320 | |||
321 | } | ||
322 | |||
323 | static void _rtl92s_write_ofdm_powerreg(struct ieee80211_hw *hw, | ||
324 | u8 index, u32 val) | ||
325 | { | ||
326 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
327 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
328 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
329 | u16 regoffset[6] = {0xe00, 0xe04, 0xe10, 0xe14, 0xe18, 0xe1c}; | ||
330 | u8 i, rfa_pwr[4]; | ||
331 | u8 rfa_lower_bound = 0, rfa_upper_bound = 0, rf_pwr_diff = 0; | ||
332 | u32 writeval = val; | ||
333 | |||
334 | /* If path A and Path B coexist, we must limit Path A tx power. | ||
335 | * Protect Path B pwr over or under flow. We need to calculate | ||
336 | * upper and lower bound of path A tx power. */ | ||
337 | if (rtlphy->rf_type == RF_2T2R) { | ||
338 | rf_pwr_diff = rtlefuse->antenna_txpwdiff[0]; | ||
339 | |||
340 | /* Diff=-8~-1 */ | ||
341 | if (rf_pwr_diff >= 8) { | ||
342 | /* Prevent underflow!! */ | ||
343 | rfa_lower_bound = 0x10 - rf_pwr_diff; | ||
344 | /* if (rf_pwr_diff >= 0) Diff = 0-7 */ | ||
345 | } else { | ||
346 | rfa_upper_bound = RF6052_MAX_TX_PWR - rf_pwr_diff; | ||
347 | } | ||
348 | } | ||
349 | |||
350 | for (i = 0; i < 4; i++) { | ||
351 | rfa_pwr[i] = (u8)((writeval & (0x7f << (i * 8))) >> (i * 8)); | ||
352 | if (rfa_pwr[i] > RF6052_MAX_TX_PWR) | ||
353 | rfa_pwr[i] = RF6052_MAX_TX_PWR; | ||
354 | |||
355 | /* If path A and Path B coexist, we must limit Path A tx power. | ||
356 | * Protect Path B pwr over or under flow. We need to calculate | ||
357 | * upper and lower bound of path A tx power. */ | ||
358 | if (rtlphy->rf_type == RF_2T2R) { | ||
359 | /* Diff=-8~-1 */ | ||
360 | if (rf_pwr_diff >= 8) { | ||
361 | /* Prevent underflow!! */ | ||
362 | if (rfa_pwr[i] < rfa_lower_bound) | ||
363 | rfa_pwr[i] = rfa_lower_bound; | ||
364 | /* Diff = 0-7 */ | ||
365 | } else if (rf_pwr_diff >= 1) { | ||
366 | /* Prevent overflow */ | ||
367 | if (rfa_pwr[i] > rfa_upper_bound) | ||
368 | rfa_pwr[i] = rfa_upper_bound; | ||
369 | } | ||
370 | } | ||
371 | |||
372 | } | ||
373 | |||
374 | writeval = (rfa_pwr[3] << 24) | (rfa_pwr[2] << 16) | (rfa_pwr[1] << 8) | | ||
375 | rfa_pwr[0]; | ||
376 | |||
377 | rtl_set_bbreg(hw, regoffset[index], 0x7f7f7f7f, writeval); | ||
378 | } | ||
379 | |||
380 | void rtl92s_phy_rf6052_set_ofdmtxpower(struct ieee80211_hw *hw, | ||
381 | u8 *p_pwrlevel, u8 chnl) | ||
382 | { | ||
383 | u32 writeval, pwrbase0, pwrbase1; | ||
384 | u8 index = 0; | ||
385 | u8 finalpwr_idx[4]; | ||
386 | |||
387 | _rtl92s_get_powerbase(hw, p_pwrlevel, chnl, &pwrbase0, &pwrbase1, | ||
388 | &finalpwr_idx[0]); | ||
389 | _rtl92s_set_antennadiff(hw, &finalpwr_idx[0]); | ||
390 | |||
391 | for (index = 0; index < 6; index++) { | ||
392 | _rtl92s_get_txpower_writeval_byregulatory(hw, chnl, index, | ||
393 | pwrbase0, pwrbase1, &writeval); | ||
394 | |||
395 | _rtl92s_write_ofdm_powerreg(hw, index, writeval); | ||
396 | } | ||
397 | } | ||
398 | |||
399 | void rtl92s_phy_rf6052_set_ccktxpower(struct ieee80211_hw *hw, u8 pwrlevel) | ||
400 | { | ||
401 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
402 | struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); | ||
403 | struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); | ||
404 | u32 txagc = 0; | ||
405 | bool dont_inc_cck_or_turboscanoff = false; | ||
406 | |||
407 | if (((rtlefuse->eeprom_version >= 2) && | ||
408 | (rtlefuse->txpwr_safetyflag == 1)) || | ||
409 | ((rtlefuse->eeprom_version >= 2) && | ||
410 | (rtlefuse->eeprom_regulatory != 0))) | ||
411 | dont_inc_cck_or_turboscanoff = true; | ||
412 | |||
413 | if (mac->act_scanning == true) { | ||
414 | txagc = 0x3f; | ||
415 | if (dont_inc_cck_or_turboscanoff) | ||
416 | txagc = pwrlevel; | ||
417 | } else { | ||
418 | txagc = pwrlevel; | ||
419 | |||
420 | if (rtlpriv->dm.dynamic_txhighpower_lvl == | ||
421 | TX_HIGH_PWR_LEVEL_LEVEL1) | ||
422 | txagc = 0x10; | ||
423 | else if (rtlpriv->dm.dynamic_txhighpower_lvl == | ||
424 | TX_HIGH_PWR_LEVEL_LEVEL2) | ||
425 | txagc = 0x0; | ||
426 | } | ||
427 | |||
428 | if (txagc > RF6052_MAX_TX_PWR) | ||
429 | txagc = RF6052_MAX_TX_PWR; | ||
430 | |||
431 | rtl_set_bbreg(hw, RTXAGC_CCK_MCS32, BTX_AGCRATECCK, txagc); | ||
432 | |||
433 | } | ||
434 | |||
435 | bool rtl92s_phy_rf6052_config(struct ieee80211_hw *hw) | ||
436 | { | ||
437 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
438 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
439 | u32 u4reg_val = 0; | ||
440 | u8 rfpath; | ||
441 | bool rtstatus = true; | ||
442 | struct bb_reg_def *pphyreg; | ||
443 | |||
444 | /* Initialize RF */ | ||
445 | for (rfpath = 0; rfpath < rtlphy->num_total_rfpath; rfpath++) { | ||
446 | |||
447 | pphyreg = &rtlphy->phyreg_def[rfpath]; | ||
448 | |||
449 | /* Store original RFENV control type */ | ||
450 | switch (rfpath) { | ||
451 | case RF90_PATH_A: | ||
452 | case RF90_PATH_C: | ||
453 | u4reg_val = rtl92s_phy_query_bb_reg(hw, | ||
454 | pphyreg->rfintfs, | ||
455 | BRFSI_RFENV); | ||
456 | break; | ||
457 | case RF90_PATH_B: | ||
458 | case RF90_PATH_D: | ||
459 | u4reg_val = rtl92s_phy_query_bb_reg(hw, | ||
460 | pphyreg->rfintfs, | ||
461 | BRFSI_RFENV << 16); | ||
462 | break; | ||
463 | } | ||
464 | |||
465 | /* Set RF_ENV enable */ | ||
466 | rtl92s_phy_set_bb_reg(hw, pphyreg->rfintfe, | ||
467 | BRFSI_RFENV << 16, 0x1); | ||
468 | |||
469 | /* Set RF_ENV output high */ | ||
470 | rtl92s_phy_set_bb_reg(hw, pphyreg->rfintfo, BRFSI_RFENV, 0x1); | ||
471 | |||
472 | /* Set bit number of Address and Data for RF register */ | ||
473 | rtl92s_phy_set_bb_reg(hw, pphyreg->rfhssi_para2, | ||
474 | B3WIRE_ADDRESSLENGTH, 0x0); | ||
475 | rtl92s_phy_set_bb_reg(hw, pphyreg->rfhssi_para2, | ||
476 | B3WIRE_DATALENGTH, 0x0); | ||
477 | |||
478 | /* Initialize RF fom connfiguration file */ | ||
479 | switch (rfpath) { | ||
480 | case RF90_PATH_A: | ||
481 | rtstatus = rtl92s_phy_config_rf(hw, | ||
482 | (enum radio_path)rfpath); | ||
483 | break; | ||
484 | case RF90_PATH_B: | ||
485 | rtstatus = rtl92s_phy_config_rf(hw, | ||
486 | (enum radio_path)rfpath); | ||
487 | break; | ||
488 | case RF90_PATH_C: | ||
489 | break; | ||
490 | case RF90_PATH_D: | ||
491 | break; | ||
492 | } | ||
493 | |||
494 | /* Restore RFENV control type */ | ||
495 | switch (rfpath) { | ||
496 | case RF90_PATH_A: | ||
497 | case RF90_PATH_C: | ||
498 | rtl92s_phy_set_bb_reg(hw, pphyreg->rfintfs, BRFSI_RFENV, | ||
499 | u4reg_val); | ||
500 | break; | ||
501 | case RF90_PATH_B: | ||
502 | case RF90_PATH_D: | ||
503 | rtl92s_phy_set_bb_reg(hw, pphyreg->rfintfs, | ||
504 | BRFSI_RFENV << 16, | ||
505 | u4reg_val); | ||
506 | break; | ||
507 | } | ||
508 | |||
509 | if (rtstatus != true) { | ||
510 | printk(KERN_ERR "Radio[%d] Fail!!", rfpath); | ||
511 | goto fail; | ||
512 | } | ||
513 | |||
514 | } | ||
515 | |||
516 | return rtstatus; | ||
517 | |||
518 | fail: | ||
519 | return rtstatus; | ||
520 | } | ||
521 | |||
522 | void rtl92s_phy_rf6052_set_bandwidth(struct ieee80211_hw *hw, u8 bandwidth) | ||
523 | { | ||
524 | struct rtl_priv *rtlpriv = rtl_priv(hw); | ||
525 | struct rtl_phy *rtlphy = &(rtlpriv->phy); | ||
526 | |||
527 | switch (bandwidth) { | ||
528 | case HT_CHANNEL_WIDTH_20: | ||
529 | rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] & | ||
530 | 0xfffff3ff) | 0x0400); | ||
531 | rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, | ||
532 | rtlphy->rfreg_chnlval[0]); | ||
533 | break; | ||
534 | case HT_CHANNEL_WIDTH_20_40: | ||
535 | rtlphy->rfreg_chnlval[0] = ((rtlphy->rfreg_chnlval[0] & | ||
536 | 0xfffff3ff)); | ||
537 | rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, | ||
538 | rtlphy->rfreg_chnlval[0]); | ||
539 | break; | ||
540 | default: | ||
541 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, | ||
542 | ("unknown bandwidth: %#X\n", | ||
543 | bandwidth)); | ||
544 | break; | ||
545 | } | ||
546 | } | ||