diff options
author | Luis R. Rodriguez <lrodriguez@atheros.com> | 2009-03-30 22:30:33 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-04-22 16:54:38 -0400 |
commit | 203c4805e91786f9a010bc7945a0fde70c9da28e (patch) | |
tree | 00415276b2fe65713f066ffe07b11ad2d8b6bea8 /drivers/net/wireless/ath/ath5k/reset.c | |
parent | 1878f77e13b9d720b78c4f818b94bfd4a7f596e5 (diff) |
atheros: put atheros wireless drivers into ath/
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath5k/reset.c')
-rw-r--r-- | drivers/net/wireless/ath/ath5k/reset.c | 1346 |
1 files changed, 1346 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath/ath5k/reset.c b/drivers/net/wireless/ath/ath5k/reset.c new file mode 100644 index 000000000000..775fdf78554b --- /dev/null +++ b/drivers/net/wireless/ath/ath5k/reset.c | |||
@@ -0,0 +1,1346 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org> | ||
3 | * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com> | ||
4 | * Copyright (c) 2007-2008 Luis Rodriguez <mcgrof@winlab.rutgers.edu> | ||
5 | * Copyright (c) 2007-2008 Pavel Roskin <proski@gnu.org> | ||
6 | * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com> | ||
7 | * | ||
8 | * Permission to use, copy, modify, and distribute this software for any | ||
9 | * purpose with or without fee is hereby granted, provided that the above | ||
10 | * copyright notice and this permission notice appear in all copies. | ||
11 | * | ||
12 | * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
13 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
14 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
15 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
16 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
17 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
18 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #define _ATH5K_RESET | ||
23 | |||
24 | /*****************************\ | ||
25 | Reset functions and helpers | ||
26 | \*****************************/ | ||
27 | |||
28 | #include <linux/pci.h> /* To determine if a card is pci-e */ | ||
29 | #include <linux/bitops.h> /* For get_bitmask_order */ | ||
30 | #include "ath5k.h" | ||
31 | #include "reg.h" | ||
32 | #include "base.h" | ||
33 | #include "debug.h" | ||
34 | |||
35 | /** | ||
36 | * ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212 | ||
37 | * | ||
38 | * @ah: the &struct ath5k_hw | ||
39 | * @channel: the currently set channel upon reset | ||
40 | * | ||
41 | * Write the delta slope coefficient (used on pilot tracking ?) for OFDM | ||
42 | * operation on the AR5212 upon reset. This is a helper for ath5k_hw_reset(). | ||
43 | * | ||
44 | * Since delta slope is floating point we split it on its exponent and | ||
45 | * mantissa and provide these values on hw. | ||
46 | * | ||
47 | * For more infos i think this patent is related | ||
48 | * http://www.freepatentsonline.com/7184495.html | ||
49 | */ | ||
50 | static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah, | ||
51 | struct ieee80211_channel *channel) | ||
52 | { | ||
53 | /* Get exponent and mantissa and set it */ | ||
54 | u32 coef_scaled, coef_exp, coef_man, | ||
55 | ds_coef_exp, ds_coef_man, clock; | ||
56 | |||
57 | BUG_ON(!(ah->ah_version == AR5K_AR5212) || | ||
58 | !(channel->hw_value & CHANNEL_OFDM)); | ||
59 | |||
60 | /* Get coefficient | ||
61 | * ALGO: coef = (5 * clock * carrier_freq) / 2) | ||
62 | * we scale coef by shifting clock value by 24 for | ||
63 | * better precision since we use integers */ | ||
64 | /* TODO: Half/quarter rate */ | ||
65 | clock = ath5k_hw_htoclock(1, channel->hw_value & CHANNEL_TURBO); | ||
66 | |||
67 | coef_scaled = ((5 * (clock << 24)) / 2) / channel->center_freq; | ||
68 | |||
69 | /* Get exponent | ||
70 | * ALGO: coef_exp = 14 - highest set bit position */ | ||
71 | coef_exp = get_bitmask_order(coef_scaled); | ||
72 | |||
73 | /* Doesn't make sense if it's zero*/ | ||
74 | if (!coef_exp) | ||
75 | return -EINVAL; | ||
76 | |||
77 | /* Note: we've shifted coef_scaled by 24 */ | ||
78 | coef_exp = 14 - (coef_exp - 24); | ||
79 | |||
80 | |||
81 | /* Get mantissa (significant digits) | ||
82 | * ALGO: coef_mant = floor(coef_scaled* 2^coef_exp+0.5) */ | ||
83 | coef_man = coef_scaled + | ||
84 | (1 << (24 - coef_exp - 1)); | ||
85 | |||
86 | /* Calculate delta slope coefficient exponent | ||
87 | * and mantissa (remove scaling) and set them on hw */ | ||
88 | ds_coef_man = coef_man >> (24 - coef_exp); | ||
89 | ds_coef_exp = coef_exp - 16; | ||
90 | |||
91 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3, | ||
92 | AR5K_PHY_TIMING_3_DSC_MAN, ds_coef_man); | ||
93 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3, | ||
94 | AR5K_PHY_TIMING_3_DSC_EXP, ds_coef_exp); | ||
95 | |||
96 | return 0; | ||
97 | } | ||
98 | |||
99 | |||
100 | /* | ||
101 | * index into rates for control rates, we can set it up like this because | ||
102 | * this is only used for AR5212 and we know it supports G mode | ||
103 | */ | ||
104 | static const unsigned int control_rates[] = | ||
105 | { 0, 1, 1, 1, 4, 4, 6, 6, 8, 8, 8, 8 }; | ||
106 | |||
107 | /** | ||
108 | * ath5k_hw_write_rate_duration - fill rate code to duration table | ||
109 | * | ||
110 | * @ah: the &struct ath5k_hw | ||
111 | * @mode: one of enum ath5k_driver_mode | ||
112 | * | ||
113 | * Write the rate code to duration table upon hw reset. This is a helper for | ||
114 | * ath5k_hw_reset(). It seems all this is doing is setting an ACK timeout on | ||
115 | * the hardware, based on current mode, for each rate. The rates which are | ||
116 | * capable of short preamble (802.11b rates 2Mbps, 5.5Mbps, and 11Mbps) have | ||
117 | * different rate code so we write their value twice (one for long preample | ||
118 | * and one for short). | ||
119 | * | ||
120 | * Note: Band doesn't matter here, if we set the values for OFDM it works | ||
121 | * on both a and g modes. So all we have to do is set values for all g rates | ||
122 | * that include all OFDM and CCK rates. If we operate in turbo or xr/half/ | ||
123 | * quarter rate mode, we need to use another set of bitrates (that's why we | ||
124 | * need the mode parameter) but we don't handle these proprietary modes yet. | ||
125 | */ | ||
126 | static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah, | ||
127 | unsigned int mode) | ||
128 | { | ||
129 | struct ath5k_softc *sc = ah->ah_sc; | ||
130 | struct ieee80211_rate *rate; | ||
131 | unsigned int i; | ||
132 | |||
133 | /* Write rate duration table */ | ||
134 | for (i = 0; i < sc->sbands[IEEE80211_BAND_2GHZ].n_bitrates; i++) { | ||
135 | u32 reg; | ||
136 | u16 tx_time; | ||
137 | |||
138 | rate = &sc->sbands[IEEE80211_BAND_2GHZ].bitrates[control_rates[i]]; | ||
139 | |||
140 | /* Set ACK timeout */ | ||
141 | reg = AR5K_RATE_DUR(rate->hw_value); | ||
142 | |||
143 | /* An ACK frame consists of 10 bytes. If you add the FCS, | ||
144 | * which ieee80211_generic_frame_duration() adds, | ||
145 | * its 14 bytes. Note we use the control rate and not the | ||
146 | * actual rate for this rate. See mac80211 tx.c | ||
147 | * ieee80211_duration() for a brief description of | ||
148 | * what rate we should choose to TX ACKs. */ | ||
149 | tx_time = le16_to_cpu(ieee80211_generic_frame_duration(sc->hw, | ||
150 | sc->vif, 10, rate)); | ||
151 | |||
152 | ath5k_hw_reg_write(ah, tx_time, reg); | ||
153 | |||
154 | if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE)) | ||
155 | continue; | ||
156 | |||
157 | /* | ||
158 | * We're not distinguishing short preamble here, | ||
159 | * This is true, all we'll get is a longer value here | ||
160 | * which is not necessarilly bad. We could use | ||
161 | * export ieee80211_frame_duration() but that needs to be | ||
162 | * fixed first to be properly used by mac802111 drivers: | ||
163 | * | ||
164 | * - remove erp stuff and let the routine figure ofdm | ||
165 | * erp rates | ||
166 | * - remove passing argument ieee80211_local as | ||
167 | * drivers don't have access to it | ||
168 | * - move drivers using ieee80211_generic_frame_duration() | ||
169 | * to this | ||
170 | */ | ||
171 | ath5k_hw_reg_write(ah, tx_time, | ||
172 | reg + (AR5K_SET_SHORT_PREAMBLE << 2)); | ||
173 | } | ||
174 | } | ||
175 | |||
176 | /* | ||
177 | * Reset chipset | ||
178 | */ | ||
179 | static int ath5k_hw_nic_reset(struct ath5k_hw *ah, u32 val) | ||
180 | { | ||
181 | int ret; | ||
182 | u32 mask = val ? val : ~0U; | ||
183 | |||
184 | ATH5K_TRACE(ah->ah_sc); | ||
185 | |||
186 | /* Read-and-clear RX Descriptor Pointer*/ | ||
187 | ath5k_hw_reg_read(ah, AR5K_RXDP); | ||
188 | |||
189 | /* | ||
190 | * Reset the device and wait until success | ||
191 | */ | ||
192 | ath5k_hw_reg_write(ah, val, AR5K_RESET_CTL); | ||
193 | |||
194 | /* Wait at least 128 PCI clocks */ | ||
195 | udelay(15); | ||
196 | |||
197 | if (ah->ah_version == AR5K_AR5210) { | ||
198 | val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_DMA | ||
199 | | AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_PHY; | ||
200 | mask &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_DMA | ||
201 | | AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_PHY; | ||
202 | } else { | ||
203 | val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND; | ||
204 | mask &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND; | ||
205 | } | ||
206 | |||
207 | ret = ath5k_hw_register_timeout(ah, AR5K_RESET_CTL, mask, val, false); | ||
208 | |||
209 | /* | ||
210 | * Reset configuration register (for hw byte-swap). Note that this | ||
211 | * is only set for big endian. We do the necessary magic in | ||
212 | * AR5K_INIT_CFG. | ||
213 | */ | ||
214 | if ((val & AR5K_RESET_CTL_PCU) == 0) | ||
215 | ath5k_hw_reg_write(ah, AR5K_INIT_CFG, AR5K_CFG); | ||
216 | |||
217 | return ret; | ||
218 | } | ||
219 | |||
220 | /* | ||
221 | * Sleep control | ||
222 | */ | ||
223 | int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode, | ||
224 | bool set_chip, u16 sleep_duration) | ||
225 | { | ||
226 | unsigned int i; | ||
227 | u32 staid, data; | ||
228 | |||
229 | ATH5K_TRACE(ah->ah_sc); | ||
230 | staid = ath5k_hw_reg_read(ah, AR5K_STA_ID1); | ||
231 | |||
232 | switch (mode) { | ||
233 | case AR5K_PM_AUTO: | ||
234 | staid &= ~AR5K_STA_ID1_DEFAULT_ANTENNA; | ||
235 | /* fallthrough */ | ||
236 | case AR5K_PM_NETWORK_SLEEP: | ||
237 | if (set_chip) | ||
238 | ath5k_hw_reg_write(ah, | ||
239 | AR5K_SLEEP_CTL_SLE_ALLOW | | ||
240 | sleep_duration, | ||
241 | AR5K_SLEEP_CTL); | ||
242 | |||
243 | staid |= AR5K_STA_ID1_PWR_SV; | ||
244 | break; | ||
245 | |||
246 | case AR5K_PM_FULL_SLEEP: | ||
247 | if (set_chip) | ||
248 | ath5k_hw_reg_write(ah, AR5K_SLEEP_CTL_SLE_SLP, | ||
249 | AR5K_SLEEP_CTL); | ||
250 | |||
251 | staid |= AR5K_STA_ID1_PWR_SV; | ||
252 | break; | ||
253 | |||
254 | case AR5K_PM_AWAKE: | ||
255 | |||
256 | staid &= ~AR5K_STA_ID1_PWR_SV; | ||
257 | |||
258 | if (!set_chip) | ||
259 | goto commit; | ||
260 | |||
261 | /* Preserve sleep duration */ | ||
262 | data = ath5k_hw_reg_read(ah, AR5K_SLEEP_CTL); | ||
263 | if (data & 0xffc00000) | ||
264 | data = 0; | ||
265 | else | ||
266 | data = data & 0xfffcffff; | ||
267 | |||
268 | ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL); | ||
269 | udelay(15); | ||
270 | |||
271 | for (i = 50; i > 0; i--) { | ||
272 | /* Check if the chip did wake up */ | ||
273 | if ((ath5k_hw_reg_read(ah, AR5K_PCICFG) & | ||
274 | AR5K_PCICFG_SPWR_DN) == 0) | ||
275 | break; | ||
276 | |||
277 | /* Wait a bit and retry */ | ||
278 | udelay(200); | ||
279 | ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL); | ||
280 | } | ||
281 | |||
282 | /* Fail if the chip didn't wake up */ | ||
283 | if (i <= 0) | ||
284 | return -EIO; | ||
285 | |||
286 | break; | ||
287 | |||
288 | default: | ||
289 | return -EINVAL; | ||
290 | } | ||
291 | |||
292 | commit: | ||
293 | ah->ah_power_mode = mode; | ||
294 | ath5k_hw_reg_write(ah, staid, AR5K_STA_ID1); | ||
295 | |||
296 | return 0; | ||
297 | } | ||
298 | |||
299 | /* | ||
300 | * Bring up MAC + PHY Chips and program PLL | ||
301 | * TODO: Half/Quarter rate support | ||
302 | */ | ||
303 | int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial) | ||
304 | { | ||
305 | struct pci_dev *pdev = ah->ah_sc->pdev; | ||
306 | u32 turbo, mode, clock, bus_flags; | ||
307 | int ret; | ||
308 | |||
309 | turbo = 0; | ||
310 | mode = 0; | ||
311 | clock = 0; | ||
312 | |||
313 | ATH5K_TRACE(ah->ah_sc); | ||
314 | |||
315 | /* Wakeup the device */ | ||
316 | ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0); | ||
317 | if (ret) { | ||
318 | ATH5K_ERR(ah->ah_sc, "failed to wakeup the MAC Chip\n"); | ||
319 | return ret; | ||
320 | } | ||
321 | |||
322 | if (ah->ah_version != AR5K_AR5210) { | ||
323 | /* | ||
324 | * Get channel mode flags | ||
325 | */ | ||
326 | |||
327 | if (ah->ah_radio >= AR5K_RF5112) { | ||
328 | mode = AR5K_PHY_MODE_RAD_RF5112; | ||
329 | clock = AR5K_PHY_PLL_RF5112; | ||
330 | } else { | ||
331 | mode = AR5K_PHY_MODE_RAD_RF5111; /*Zero*/ | ||
332 | clock = AR5K_PHY_PLL_RF5111; /*Zero*/ | ||
333 | } | ||
334 | |||
335 | if (flags & CHANNEL_2GHZ) { | ||
336 | mode |= AR5K_PHY_MODE_FREQ_2GHZ; | ||
337 | clock |= AR5K_PHY_PLL_44MHZ; | ||
338 | |||
339 | if (flags & CHANNEL_CCK) { | ||
340 | mode |= AR5K_PHY_MODE_MOD_CCK; | ||
341 | } else if (flags & CHANNEL_OFDM) { | ||
342 | /* XXX Dynamic OFDM/CCK is not supported by the | ||
343 | * AR5211 so we set MOD_OFDM for plain g (no | ||
344 | * CCK headers) operation. We need to test | ||
345 | * this, 5211 might support ofdm-only g after | ||
346 | * all, there are also initial register values | ||
347 | * in the code for g mode (see initvals.c). */ | ||
348 | if (ah->ah_version == AR5K_AR5211) | ||
349 | mode |= AR5K_PHY_MODE_MOD_OFDM; | ||
350 | else | ||
351 | mode |= AR5K_PHY_MODE_MOD_DYN; | ||
352 | } else { | ||
353 | ATH5K_ERR(ah->ah_sc, | ||
354 | "invalid radio modulation mode\n"); | ||
355 | return -EINVAL; | ||
356 | } | ||
357 | } else if (flags & CHANNEL_5GHZ) { | ||
358 | mode |= AR5K_PHY_MODE_FREQ_5GHZ; | ||
359 | |||
360 | if (ah->ah_radio == AR5K_RF5413) | ||
361 | clock = AR5K_PHY_PLL_40MHZ_5413; | ||
362 | else | ||
363 | clock |= AR5K_PHY_PLL_40MHZ; | ||
364 | |||
365 | if (flags & CHANNEL_OFDM) | ||
366 | mode |= AR5K_PHY_MODE_MOD_OFDM; | ||
367 | else { | ||
368 | ATH5K_ERR(ah->ah_sc, | ||
369 | "invalid radio modulation mode\n"); | ||
370 | return -EINVAL; | ||
371 | } | ||
372 | } else { | ||
373 | ATH5K_ERR(ah->ah_sc, "invalid radio frequency mode\n"); | ||
374 | return -EINVAL; | ||
375 | } | ||
376 | |||
377 | if (flags & CHANNEL_TURBO) | ||
378 | turbo = AR5K_PHY_TURBO_MODE | AR5K_PHY_TURBO_SHORT; | ||
379 | } else { /* Reset the device */ | ||
380 | |||
381 | /* ...enable Atheros turbo mode if requested */ | ||
382 | if (flags & CHANNEL_TURBO) | ||
383 | ath5k_hw_reg_write(ah, AR5K_PHY_TURBO_MODE, | ||
384 | AR5K_PHY_TURBO); | ||
385 | } | ||
386 | |||
387 | /* reseting PCI on PCI-E cards results card to hang | ||
388 | * and always return 0xffff... so we ingore that flag | ||
389 | * for PCI-E cards */ | ||
390 | bus_flags = (pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI; | ||
391 | |||
392 | /* Reset chipset */ | ||
393 | if (ah->ah_version == AR5K_AR5210) { | ||
394 | ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU | | ||
395 | AR5K_RESET_CTL_MAC | AR5K_RESET_CTL_DMA | | ||
396 | AR5K_RESET_CTL_PHY | AR5K_RESET_CTL_PCI); | ||
397 | mdelay(2); | ||
398 | } else { | ||
399 | ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU | | ||
400 | AR5K_RESET_CTL_BASEBAND | bus_flags); | ||
401 | } | ||
402 | if (ret) { | ||
403 | ATH5K_ERR(ah->ah_sc, "failed to reset the MAC Chip\n"); | ||
404 | return -EIO; | ||
405 | } | ||
406 | |||
407 | /* ...wakeup again!*/ | ||
408 | ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0); | ||
409 | if (ret) { | ||
410 | ATH5K_ERR(ah->ah_sc, "failed to resume the MAC Chip\n"); | ||
411 | return ret; | ||
412 | } | ||
413 | |||
414 | /* ...final warm reset */ | ||
415 | if (ath5k_hw_nic_reset(ah, 0)) { | ||
416 | ATH5K_ERR(ah->ah_sc, "failed to warm reset the MAC Chip\n"); | ||
417 | return -EIO; | ||
418 | } | ||
419 | |||
420 | if (ah->ah_version != AR5K_AR5210) { | ||
421 | |||
422 | /* ...update PLL if needed */ | ||
423 | if (ath5k_hw_reg_read(ah, AR5K_PHY_PLL) != clock) { | ||
424 | ath5k_hw_reg_write(ah, clock, AR5K_PHY_PLL); | ||
425 | udelay(300); | ||
426 | } | ||
427 | |||
428 | /* ...set the PHY operating mode */ | ||
429 | ath5k_hw_reg_write(ah, mode, AR5K_PHY_MODE); | ||
430 | ath5k_hw_reg_write(ah, turbo, AR5K_PHY_TURBO); | ||
431 | } | ||
432 | |||
433 | return 0; | ||
434 | } | ||
435 | |||
436 | /* | ||
437 | * If there is an external 32KHz crystal available, use it | ||
438 | * as ref. clock instead of 32/40MHz clock and baseband clocks | ||
439 | * to save power during sleep or restore normal 32/40MHz | ||
440 | * operation. | ||
441 | * | ||
442 | * XXX: When operating on 32KHz certain PHY registers (27 - 31, | ||
443 | * 123 - 127) require delay on access. | ||
444 | */ | ||
445 | static void ath5k_hw_set_sleep_clock(struct ath5k_hw *ah, bool enable) | ||
446 | { | ||
447 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | ||
448 | u32 scal, spending, usec32; | ||
449 | |||
450 | /* Only set 32KHz settings if we have an external | ||
451 | * 32KHz crystal present */ | ||
452 | if ((AR5K_EEPROM_HAS32KHZCRYSTAL(ee->ee_misc1) || | ||
453 | AR5K_EEPROM_HAS32KHZCRYSTAL_OLD(ee->ee_misc1)) && | ||
454 | enable) { | ||
455 | |||
456 | /* 1 usec/cycle */ | ||
457 | AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, 1); | ||
458 | /* Set up tsf increment on each cycle */ | ||
459 | AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 61); | ||
460 | |||
461 | /* Set baseband sleep control registers | ||
462 | * and sleep control rate */ | ||
463 | ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR); | ||
464 | |||
465 | if ((ah->ah_radio == AR5K_RF5112) || | ||
466 | (ah->ah_radio == AR5K_RF5413) || | ||
467 | (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) | ||
468 | spending = 0x14; | ||
469 | else | ||
470 | spending = 0x18; | ||
471 | ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING); | ||
472 | |||
473 | if ((ah->ah_radio == AR5K_RF5112) || | ||
474 | (ah->ah_radio == AR5K_RF5413) || | ||
475 | (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) { | ||
476 | ath5k_hw_reg_write(ah, 0x26, AR5K_PHY_SLMT); | ||
477 | ath5k_hw_reg_write(ah, 0x0d, AR5K_PHY_SCAL); | ||
478 | ath5k_hw_reg_write(ah, 0x07, AR5K_PHY_SCLOCK); | ||
479 | ath5k_hw_reg_write(ah, 0x3f, AR5K_PHY_SDELAY); | ||
480 | AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG, | ||
481 | AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x02); | ||
482 | } else { | ||
483 | ath5k_hw_reg_write(ah, 0x0a, AR5K_PHY_SLMT); | ||
484 | ath5k_hw_reg_write(ah, 0x0c, AR5K_PHY_SCAL); | ||
485 | ath5k_hw_reg_write(ah, 0x03, AR5K_PHY_SCLOCK); | ||
486 | ath5k_hw_reg_write(ah, 0x20, AR5K_PHY_SDELAY); | ||
487 | AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG, | ||
488 | AR5K_PCICFG_SLEEP_CLOCK_RATE, 0x03); | ||
489 | } | ||
490 | |||
491 | /* Enable sleep clock operation */ | ||
492 | AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, | ||
493 | AR5K_PCICFG_SLEEP_CLOCK_EN); | ||
494 | |||
495 | } else { | ||
496 | |||
497 | /* Disable sleep clock operation and | ||
498 | * restore default parameters */ | ||
499 | AR5K_REG_DISABLE_BITS(ah, AR5K_PCICFG, | ||
500 | AR5K_PCICFG_SLEEP_CLOCK_EN); | ||
501 | |||
502 | AR5K_REG_WRITE_BITS(ah, AR5K_PCICFG, | ||
503 | AR5K_PCICFG_SLEEP_CLOCK_RATE, 0); | ||
504 | |||
505 | ath5k_hw_reg_write(ah, 0x1f, AR5K_PHY_SCR); | ||
506 | ath5k_hw_reg_write(ah, AR5K_PHY_SLMT_32MHZ, AR5K_PHY_SLMT); | ||
507 | |||
508 | if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)) | ||
509 | scal = AR5K_PHY_SCAL_32MHZ_2417; | ||
510 | else if (ath5k_eeprom_is_hb63(ah)) | ||
511 | scal = AR5K_PHY_SCAL_32MHZ_HB63; | ||
512 | else | ||
513 | scal = AR5K_PHY_SCAL_32MHZ; | ||
514 | ath5k_hw_reg_write(ah, scal, AR5K_PHY_SCAL); | ||
515 | |||
516 | ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK); | ||
517 | ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY); | ||
518 | |||
519 | if ((ah->ah_radio == AR5K_RF5112) || | ||
520 | (ah->ah_radio == AR5K_RF5413) || | ||
521 | (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) | ||
522 | spending = 0x14; | ||
523 | else | ||
524 | spending = 0x18; | ||
525 | ath5k_hw_reg_write(ah, spending, AR5K_PHY_SPENDING); | ||
526 | |||
527 | if ((ah->ah_radio == AR5K_RF5112) || | ||
528 | (ah->ah_radio == AR5K_RF5413)) | ||
529 | usec32 = 39; | ||
530 | else | ||
531 | usec32 = 31; | ||
532 | AR5K_REG_WRITE_BITS(ah, AR5K_USEC_5211, AR5K_USEC_32, usec32); | ||
533 | |||
534 | AR5K_REG_WRITE_BITS(ah, AR5K_TSF_PARM, AR5K_TSF_PARM_INC, 1); | ||
535 | } | ||
536 | return; | ||
537 | } | ||
538 | |||
539 | static bool ath5k_hw_chan_has_spur_noise(struct ath5k_hw *ah, | ||
540 | struct ieee80211_channel *channel) | ||
541 | { | ||
542 | u8 refclk_freq; | ||
543 | |||
544 | if ((ah->ah_radio == AR5K_RF5112) || | ||
545 | (ah->ah_radio == AR5K_RF5413) || | ||
546 | (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) | ||
547 | refclk_freq = 40; | ||
548 | else | ||
549 | refclk_freq = 32; | ||
550 | |||
551 | if ((channel->center_freq % refclk_freq != 0) && | ||
552 | ((channel->center_freq % refclk_freq < 10) || | ||
553 | (channel->center_freq % refclk_freq > 22))) | ||
554 | return true; | ||
555 | else | ||
556 | return false; | ||
557 | } | ||
558 | |||
559 | /* TODO: Half/Quarter rate */ | ||
560 | static void ath5k_hw_tweak_initval_settings(struct ath5k_hw *ah, | ||
561 | struct ieee80211_channel *channel) | ||
562 | { | ||
563 | if (ah->ah_version == AR5K_AR5212 && | ||
564 | ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) { | ||
565 | |||
566 | /* Setup ADC control */ | ||
567 | ath5k_hw_reg_write(ah, | ||
568 | (AR5K_REG_SM(2, | ||
569 | AR5K_PHY_ADC_CTL_INBUFGAIN_OFF) | | ||
570 | AR5K_REG_SM(2, | ||
571 | AR5K_PHY_ADC_CTL_INBUFGAIN_ON) | | ||
572 | AR5K_PHY_ADC_CTL_PWD_DAC_OFF | | ||
573 | AR5K_PHY_ADC_CTL_PWD_ADC_OFF), | ||
574 | AR5K_PHY_ADC_CTL); | ||
575 | |||
576 | |||
577 | |||
578 | /* Disable barker RSSI threshold */ | ||
579 | AR5K_REG_DISABLE_BITS(ah, AR5K_PHY_DAG_CCK_CTL, | ||
580 | AR5K_PHY_DAG_CCK_CTL_EN_RSSI_THR); | ||
581 | |||
582 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DAG_CCK_CTL, | ||
583 | AR5K_PHY_DAG_CCK_CTL_RSSI_THR, 2); | ||
584 | |||
585 | /* Set the mute mask */ | ||
586 | ath5k_hw_reg_write(ah, 0x0000000f, AR5K_SEQ_MASK); | ||
587 | } | ||
588 | |||
589 | /* Clear PHY_BLUETOOTH to allow RX_CLEAR line debug */ | ||
590 | if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212B) | ||
591 | ath5k_hw_reg_write(ah, 0, AR5K_PHY_BLUETOOTH); | ||
592 | |||
593 | /* Enable DCU double buffering */ | ||
594 | if (ah->ah_phy_revision > AR5K_SREV_PHY_5212B) | ||
595 | AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG, | ||
596 | AR5K_TXCFG_DCU_DBL_BUF_DIS); | ||
597 | |||
598 | /* Set DAC/ADC delays */ | ||
599 | if (ah->ah_version == AR5K_AR5212) { | ||
600 | u32 scal; | ||
601 | if (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4)) | ||
602 | scal = AR5K_PHY_SCAL_32MHZ_2417; | ||
603 | else if (ath5k_eeprom_is_hb63(ah)) | ||
604 | scal = AR5K_PHY_SCAL_32MHZ_HB63; | ||
605 | else | ||
606 | scal = AR5K_PHY_SCAL_32MHZ; | ||
607 | ath5k_hw_reg_write(ah, scal, AR5K_PHY_SCAL); | ||
608 | } | ||
609 | |||
610 | /* Set fast ADC */ | ||
611 | if ((ah->ah_radio == AR5K_RF5413) || | ||
612 | (ah->ah_mac_version == (AR5K_SREV_AR2417 >> 4))) { | ||
613 | u32 fast_adc = true; | ||
614 | |||
615 | if (channel->center_freq == 2462 || | ||
616 | channel->center_freq == 2467) | ||
617 | fast_adc = 0; | ||
618 | |||
619 | /* Only update if needed */ | ||
620 | if (ath5k_hw_reg_read(ah, AR5K_PHY_FAST_ADC) != fast_adc) | ||
621 | ath5k_hw_reg_write(ah, fast_adc, | ||
622 | AR5K_PHY_FAST_ADC); | ||
623 | } | ||
624 | |||
625 | /* Fix for first revision of the RF5112 RF chipset */ | ||
626 | if (ah->ah_radio == AR5K_RF5112 && | ||
627 | ah->ah_radio_5ghz_revision < | ||
628 | AR5K_SREV_RAD_5112A) { | ||
629 | u32 data; | ||
630 | ath5k_hw_reg_write(ah, AR5K_PHY_CCKTXCTL_WORLD, | ||
631 | AR5K_PHY_CCKTXCTL); | ||
632 | if (channel->hw_value & CHANNEL_5GHZ) | ||
633 | data = 0xffb81020; | ||
634 | else | ||
635 | data = 0xffb80d20; | ||
636 | ath5k_hw_reg_write(ah, data, AR5K_PHY_FRAME_CTL); | ||
637 | } | ||
638 | |||
639 | if (ah->ah_mac_srev < AR5K_SREV_AR5211) { | ||
640 | u32 usec_reg; | ||
641 | /* 5311 has different tx/rx latency masks | ||
642 | * from 5211, since we deal 5311 the same | ||
643 | * as 5211 when setting initvals, shift | ||
644 | * values here to their proper locations */ | ||
645 | usec_reg = ath5k_hw_reg_read(ah, AR5K_USEC_5211); | ||
646 | ath5k_hw_reg_write(ah, usec_reg & (AR5K_USEC_1 | | ||
647 | AR5K_USEC_32 | | ||
648 | AR5K_USEC_TX_LATENCY_5211 | | ||
649 | AR5K_REG_SM(29, | ||
650 | AR5K_USEC_RX_LATENCY_5210)), | ||
651 | AR5K_USEC_5211); | ||
652 | /* Clear QCU/DCU clock gating register */ | ||
653 | ath5k_hw_reg_write(ah, 0, AR5K_QCUDCU_CLKGT); | ||
654 | /* Set DAC/ADC delays */ | ||
655 | ath5k_hw_reg_write(ah, 0x08, AR5K_PHY_SCAL); | ||
656 | /* Enable PCU FIFO corruption ECO */ | ||
657 | AR5K_REG_ENABLE_BITS(ah, AR5K_DIAG_SW_5211, | ||
658 | AR5K_DIAG_SW_ECO_ENABLE); | ||
659 | } | ||
660 | } | ||
661 | |||
662 | static void ath5k_hw_commit_eeprom_settings(struct ath5k_hw *ah, | ||
663 | struct ieee80211_channel *channel, u8 *ant, u8 ee_mode) | ||
664 | { | ||
665 | struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom; | ||
666 | s16 cck_ofdm_pwr_delta; | ||
667 | |||
668 | /* Adjust power delta for channel 14 */ | ||
669 | if (channel->center_freq == 2484) | ||
670 | cck_ofdm_pwr_delta = | ||
671 | ((ee->ee_cck_ofdm_power_delta - | ||
672 | ee->ee_scaled_cck_delta) * 2) / 10; | ||
673 | else | ||
674 | cck_ofdm_pwr_delta = | ||
675 | (ee->ee_cck_ofdm_power_delta * 2) / 10; | ||
676 | |||
677 | /* Set CCK to OFDM power delta on tx power | ||
678 | * adjustment register */ | ||
679 | if (ah->ah_phy_revision >= AR5K_SREV_PHY_5212A) { | ||
680 | if (channel->hw_value == CHANNEL_G) | ||
681 | ath5k_hw_reg_write(ah, | ||
682 | AR5K_REG_SM((ee->ee_cck_ofdm_gain_delta * -1), | ||
683 | AR5K_PHY_TX_PWR_ADJ_CCK_GAIN_DELTA) | | ||
684 | AR5K_REG_SM((cck_ofdm_pwr_delta * -1), | ||
685 | AR5K_PHY_TX_PWR_ADJ_CCK_PCDAC_INDEX), | ||
686 | AR5K_PHY_TX_PWR_ADJ); | ||
687 | else | ||
688 | ath5k_hw_reg_write(ah, 0, AR5K_PHY_TX_PWR_ADJ); | ||
689 | } else { | ||
690 | /* For older revs we scale power on sw during tx power | ||
691 | * setup */ | ||
692 | ah->ah_txpower.txp_cck_ofdm_pwr_delta = cck_ofdm_pwr_delta; | ||
693 | ah->ah_txpower.txp_cck_ofdm_gainf_delta = | ||
694 | ee->ee_cck_ofdm_gain_delta; | ||
695 | } | ||
696 | |||
697 | /* Set antenna idle switch table */ | ||
698 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_ANT_CTL, | ||
699 | AR5K_PHY_ANT_CTL_SWTABLE_IDLE, | ||
700 | (ah->ah_antenna[ee_mode][0] | | ||
701 | AR5K_PHY_ANT_CTL_TXRX_EN)); | ||
702 | |||
703 | /* Set antenna switch table */ | ||
704 | ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[0]], | ||
705 | AR5K_PHY_ANT_SWITCH_TABLE_0); | ||
706 | ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[1]], | ||
707 | AR5K_PHY_ANT_SWITCH_TABLE_1); | ||
708 | |||
709 | /* Noise floor threshold */ | ||
710 | ath5k_hw_reg_write(ah, | ||
711 | AR5K_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]), | ||
712 | AR5K_PHY_NFTHRES); | ||
713 | |||
714 | if ((channel->hw_value & CHANNEL_TURBO) && | ||
715 | (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_0)) { | ||
716 | /* Switch settling time (Turbo) */ | ||
717 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING, | ||
718 | AR5K_PHY_SETTLING_SWITCH, | ||
719 | ee->ee_switch_settling_turbo[ee_mode]); | ||
720 | |||
721 | /* Tx/Rx attenuation (Turbo) */ | ||
722 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN, | ||
723 | AR5K_PHY_GAIN_TXRX_ATTEN, | ||
724 | ee->ee_atn_tx_rx_turbo[ee_mode]); | ||
725 | |||
726 | /* ADC/PGA desired size (Turbo) */ | ||
727 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE, | ||
728 | AR5K_PHY_DESIRED_SIZE_ADC, | ||
729 | ee->ee_adc_desired_size_turbo[ee_mode]); | ||
730 | |||
731 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE, | ||
732 | AR5K_PHY_DESIRED_SIZE_PGA, | ||
733 | ee->ee_pga_desired_size_turbo[ee_mode]); | ||
734 | |||
735 | /* Tx/Rx margin (Turbo) */ | ||
736 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ, | ||
737 | AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX, | ||
738 | ee->ee_margin_tx_rx_turbo[ee_mode]); | ||
739 | |||
740 | } else { | ||
741 | /* Switch settling time */ | ||
742 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_SETTLING, | ||
743 | AR5K_PHY_SETTLING_SWITCH, | ||
744 | ee->ee_switch_settling[ee_mode]); | ||
745 | |||
746 | /* Tx/Rx attenuation */ | ||
747 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN, | ||
748 | AR5K_PHY_GAIN_TXRX_ATTEN, | ||
749 | ee->ee_atn_tx_rx[ee_mode]); | ||
750 | |||
751 | /* ADC/PGA desired size */ | ||
752 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE, | ||
753 | AR5K_PHY_DESIRED_SIZE_ADC, | ||
754 | ee->ee_adc_desired_size[ee_mode]); | ||
755 | |||
756 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_DESIRED_SIZE, | ||
757 | AR5K_PHY_DESIRED_SIZE_PGA, | ||
758 | ee->ee_pga_desired_size[ee_mode]); | ||
759 | |||
760 | /* Tx/Rx margin */ | ||
761 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1) | ||
762 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ, | ||
763 | AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX, | ||
764 | ee->ee_margin_tx_rx[ee_mode]); | ||
765 | } | ||
766 | |||
767 | /* XPA delays */ | ||
768 | ath5k_hw_reg_write(ah, | ||
769 | (ee->ee_tx_end2xpa_disable[ee_mode] << 24) | | ||
770 | (ee->ee_tx_end2xpa_disable[ee_mode] << 16) | | ||
771 | (ee->ee_tx_frm2xpa_enable[ee_mode] << 8) | | ||
772 | (ee->ee_tx_frm2xpa_enable[ee_mode]), AR5K_PHY_RF_CTL4); | ||
773 | |||
774 | /* XLNA delay */ | ||
775 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_RF_CTL3, | ||
776 | AR5K_PHY_RF_CTL3_TXE2XLNA_ON, | ||
777 | ee->ee_tx_end2xlna_enable[ee_mode]); | ||
778 | |||
779 | /* Thresh64 (ANI) */ | ||
780 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_NF, | ||
781 | AR5K_PHY_NF_THRESH62, | ||
782 | ee->ee_thr_62[ee_mode]); | ||
783 | |||
784 | |||
785 | /* False detect backoff for channels | ||
786 | * that have spur noise. Write the new | ||
787 | * cyclic power RSSI threshold. */ | ||
788 | if (ath5k_hw_chan_has_spur_noise(ah, channel)) | ||
789 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_OFDM_SELFCORR, | ||
790 | AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1, | ||
791 | AR5K_INIT_CYCRSSI_THR1 + | ||
792 | ee->ee_false_detect[ee_mode]); | ||
793 | else | ||
794 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_OFDM_SELFCORR, | ||
795 | AR5K_PHY_OFDM_SELFCORR_CYPWR_THR1, | ||
796 | AR5K_INIT_CYCRSSI_THR1); | ||
797 | |||
798 | /* I/Q correction | ||
799 | * TODO: Per channel i/q infos ? */ | ||
800 | AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, | ||
801 | AR5K_PHY_IQ_CORR_ENABLE | | ||
802 | (ee->ee_i_cal[ee_mode] << AR5K_PHY_IQ_CORR_Q_I_COFF_S) | | ||
803 | ee->ee_q_cal[ee_mode]); | ||
804 | |||
805 | /* Heavy clipping -disable for now */ | ||
806 | if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_5_1) | ||
807 | ath5k_hw_reg_write(ah, 0, AR5K_PHY_HEAVY_CLIP_ENABLE); | ||
808 | |||
809 | return; | ||
810 | } | ||
811 | |||
812 | /* | ||
813 | * Main reset function | ||
814 | */ | ||
815 | int ath5k_hw_reset(struct ath5k_hw *ah, enum nl80211_iftype op_mode, | ||
816 | struct ieee80211_channel *channel, bool change_channel) | ||
817 | { | ||
818 | u32 s_seq[10], s_ant, s_led[3], staid1_flags, tsf_up, tsf_lo; | ||
819 | u32 phy_tst1; | ||
820 | u8 mode, freq, ee_mode, ant[2]; | ||
821 | int i, ret; | ||
822 | |||
823 | ATH5K_TRACE(ah->ah_sc); | ||
824 | |||
825 | s_ant = 0; | ||
826 | ee_mode = 0; | ||
827 | staid1_flags = 0; | ||
828 | tsf_up = 0; | ||
829 | tsf_lo = 0; | ||
830 | freq = 0; | ||
831 | mode = 0; | ||
832 | |||
833 | /* | ||
834 | * Save some registers before a reset | ||
835 | */ | ||
836 | /*DCU/Antenna selection not available on 5210*/ | ||
837 | if (ah->ah_version != AR5K_AR5210) { | ||
838 | |||
839 | switch (channel->hw_value & CHANNEL_MODES) { | ||
840 | case CHANNEL_A: | ||
841 | mode = AR5K_MODE_11A; | ||
842 | freq = AR5K_INI_RFGAIN_5GHZ; | ||
843 | ee_mode = AR5K_EEPROM_MODE_11A; | ||
844 | break; | ||
845 | case CHANNEL_G: | ||
846 | mode = AR5K_MODE_11G; | ||
847 | freq = AR5K_INI_RFGAIN_2GHZ; | ||
848 | ee_mode = AR5K_EEPROM_MODE_11G; | ||
849 | break; | ||
850 | case CHANNEL_B: | ||
851 | mode = AR5K_MODE_11B; | ||
852 | freq = AR5K_INI_RFGAIN_2GHZ; | ||
853 | ee_mode = AR5K_EEPROM_MODE_11B; | ||
854 | break; | ||
855 | case CHANNEL_T: | ||
856 | mode = AR5K_MODE_11A_TURBO; | ||
857 | freq = AR5K_INI_RFGAIN_5GHZ; | ||
858 | ee_mode = AR5K_EEPROM_MODE_11A; | ||
859 | break; | ||
860 | case CHANNEL_TG: | ||
861 | if (ah->ah_version == AR5K_AR5211) { | ||
862 | ATH5K_ERR(ah->ah_sc, | ||
863 | "TurboG mode not available on 5211"); | ||
864 | return -EINVAL; | ||
865 | } | ||
866 | mode = AR5K_MODE_11G_TURBO; | ||
867 | freq = AR5K_INI_RFGAIN_2GHZ; | ||
868 | ee_mode = AR5K_EEPROM_MODE_11G; | ||
869 | break; | ||
870 | case CHANNEL_XR: | ||
871 | if (ah->ah_version == AR5K_AR5211) { | ||
872 | ATH5K_ERR(ah->ah_sc, | ||
873 | "XR mode not available on 5211"); | ||
874 | return -EINVAL; | ||
875 | } | ||
876 | mode = AR5K_MODE_XR; | ||
877 | freq = AR5K_INI_RFGAIN_5GHZ; | ||
878 | ee_mode = AR5K_EEPROM_MODE_11A; | ||
879 | break; | ||
880 | default: | ||
881 | ATH5K_ERR(ah->ah_sc, | ||
882 | "invalid channel: %d\n", channel->center_freq); | ||
883 | return -EINVAL; | ||
884 | } | ||
885 | |||
886 | if (change_channel) { | ||
887 | /* | ||
888 | * Save frame sequence count | ||
889 | * For revs. after Oahu, only save | ||
890 | * seq num for DCU 0 (Global seq num) | ||
891 | */ | ||
892 | if (ah->ah_mac_srev < AR5K_SREV_AR5211) { | ||
893 | |||
894 | for (i = 0; i < 10; i++) | ||
895 | s_seq[i] = ath5k_hw_reg_read(ah, | ||
896 | AR5K_QUEUE_DCU_SEQNUM(i)); | ||
897 | |||
898 | } else { | ||
899 | s_seq[0] = ath5k_hw_reg_read(ah, | ||
900 | AR5K_QUEUE_DCU_SEQNUM(0)); | ||
901 | } | ||
902 | |||
903 | /* TSF accelerates on AR5211 durring reset | ||
904 | * As a workaround save it here and restore | ||
905 | * it later so that it's back in time after | ||
906 | * reset. This way it'll get re-synced on the | ||
907 | * next beacon without breaking ad-hoc. | ||
908 | * | ||
909 | * On AR5212 TSF is almost preserved across a | ||
910 | * reset so it stays back in time anyway and | ||
911 | * we don't have to save/restore it. | ||
912 | * | ||
913 | * XXX: Since this breaks power saving we have | ||
914 | * to disable power saving until we receive the | ||
915 | * next beacon, so we can resync beacon timers */ | ||
916 | if (ah->ah_version == AR5K_AR5211) { | ||
917 | tsf_up = ath5k_hw_reg_read(ah, AR5K_TSF_U32); | ||
918 | tsf_lo = ath5k_hw_reg_read(ah, AR5K_TSF_L32); | ||
919 | } | ||
920 | } | ||
921 | |||
922 | /* Save default antenna */ | ||
923 | s_ant = ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA); | ||
924 | |||
925 | if (ah->ah_version == AR5K_AR5212) { | ||
926 | /* Restore normal 32/40MHz clock operation | ||
927 | * to avoid register access delay on certain | ||
928 | * PHY registers */ | ||
929 | ath5k_hw_set_sleep_clock(ah, false); | ||
930 | |||
931 | /* Since we are going to write rf buffer | ||
932 | * check if we have any pending gain_F | ||
933 | * optimization settings */ | ||
934 | if (change_channel && ah->ah_rf_banks != NULL) | ||
935 | ath5k_hw_gainf_calibrate(ah); | ||
936 | } | ||
937 | } | ||
938 | |||
939 | /*GPIOs*/ | ||
940 | s_led[0] = ath5k_hw_reg_read(ah, AR5K_PCICFG) & | ||
941 | AR5K_PCICFG_LEDSTATE; | ||
942 | s_led[1] = ath5k_hw_reg_read(ah, AR5K_GPIOCR); | ||
943 | s_led[2] = ath5k_hw_reg_read(ah, AR5K_GPIODO); | ||
944 | |||
945 | /* AR5K_STA_ID1 flags, only preserve antenna | ||
946 | * settings and ack/cts rate mode */ | ||
947 | staid1_flags = ath5k_hw_reg_read(ah, AR5K_STA_ID1) & | ||
948 | (AR5K_STA_ID1_DEFAULT_ANTENNA | | ||
949 | AR5K_STA_ID1_DESC_ANTENNA | | ||
950 | AR5K_STA_ID1_RTS_DEF_ANTENNA | | ||
951 | AR5K_STA_ID1_ACKCTS_6MB | | ||
952 | AR5K_STA_ID1_BASE_RATE_11B | | ||
953 | AR5K_STA_ID1_SELFGEN_DEF_ANT); | ||
954 | |||
955 | /* Wakeup the device */ | ||
956 | ret = ath5k_hw_nic_wakeup(ah, channel->hw_value, false); | ||
957 | if (ret) | ||
958 | return ret; | ||
959 | |||
960 | /* | ||
961 | * Initialize operating mode | ||
962 | */ | ||
963 | ah->ah_op_mode = op_mode; | ||
964 | |||
965 | /* PHY access enable */ | ||
966 | if (ah->ah_mac_srev >= AR5K_SREV_AR5211) | ||
967 | ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0)); | ||
968 | else | ||
969 | ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ | 0x40, | ||
970 | AR5K_PHY(0)); | ||
971 | |||
972 | /* Write initial settings */ | ||
973 | ret = ath5k_hw_write_initvals(ah, mode, change_channel); | ||
974 | if (ret) | ||
975 | return ret; | ||
976 | |||
977 | /* | ||
978 | * 5211/5212 Specific | ||
979 | */ | ||
980 | if (ah->ah_version != AR5K_AR5210) { | ||
981 | |||
982 | /* | ||
983 | * Write initial RF gain settings | ||
984 | * This should work for both 5111/5112 | ||
985 | */ | ||
986 | ret = ath5k_hw_rfgain_init(ah, freq); | ||
987 | if (ret) | ||
988 | return ret; | ||
989 | |||
990 | mdelay(1); | ||
991 | |||
992 | /* | ||
993 | * Tweak initval settings for revised | ||
994 | * chipsets and add some more config | ||
995 | * bits | ||
996 | */ | ||
997 | ath5k_hw_tweak_initval_settings(ah, channel); | ||
998 | |||
999 | /* | ||
1000 | * Set TX power (FIXME) | ||
1001 | */ | ||
1002 | ret = ath5k_hw_txpower(ah, channel, ee_mode, | ||
1003 | AR5K_TUNE_DEFAULT_TXPOWER); | ||
1004 | if (ret) | ||
1005 | return ret; | ||
1006 | |||
1007 | /* Write rate duration table only on AR5212 and if | ||
1008 | * virtual interface has already been brought up | ||
1009 | * XXX: rethink this after new mode changes to | ||
1010 | * mac80211 are integrated */ | ||
1011 | if (ah->ah_version == AR5K_AR5212 && | ||
1012 | ah->ah_sc->vif != NULL) | ||
1013 | ath5k_hw_write_rate_duration(ah, mode); | ||
1014 | |||
1015 | /* | ||
1016 | * Write RF buffer | ||
1017 | */ | ||
1018 | ret = ath5k_hw_rfregs_init(ah, channel, mode); | ||
1019 | if (ret) | ||
1020 | return ret; | ||
1021 | |||
1022 | |||
1023 | /* Write OFDM timings on 5212*/ | ||
1024 | if (ah->ah_version == AR5K_AR5212 && | ||
1025 | channel->hw_value & CHANNEL_OFDM) { | ||
1026 | ret = ath5k_hw_write_ofdm_timings(ah, channel); | ||
1027 | if (ret) | ||
1028 | return ret; | ||
1029 | } | ||
1030 | |||
1031 | /*Enable/disable 802.11b mode on 5111 | ||
1032 | (enable 2111 frequency converter + CCK)*/ | ||
1033 | if (ah->ah_radio == AR5K_RF5111) { | ||
1034 | if (mode == AR5K_MODE_11B) | ||
1035 | AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG, | ||
1036 | AR5K_TXCFG_B_MODE); | ||
1037 | else | ||
1038 | AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG, | ||
1039 | AR5K_TXCFG_B_MODE); | ||
1040 | } | ||
1041 | |||
1042 | /* | ||
1043 | * In case a fixed antenna was set as default | ||
1044 | * write the same settings on both AR5K_PHY_ANT_SWITCH_TABLE | ||
1045 | * registers. | ||
1046 | */ | ||
1047 | if (s_ant != 0) { | ||
1048 | if (s_ant == AR5K_ANT_FIXED_A) /* 1 - Main */ | ||
1049 | ant[0] = ant[1] = AR5K_ANT_FIXED_A; | ||
1050 | else /* 2 - Aux */ | ||
1051 | ant[0] = ant[1] = AR5K_ANT_FIXED_B; | ||
1052 | } else { | ||
1053 | ant[0] = AR5K_ANT_FIXED_A; | ||
1054 | ant[1] = AR5K_ANT_FIXED_B; | ||
1055 | } | ||
1056 | |||
1057 | /* Commit values from EEPROM */ | ||
1058 | ath5k_hw_commit_eeprom_settings(ah, channel, ant, ee_mode); | ||
1059 | |||
1060 | } else { | ||
1061 | /* | ||
1062 | * For 5210 we do all initialization using | ||
1063 | * initvals, so we don't have to modify | ||
1064 | * any settings (5210 also only supports | ||
1065 | * a/aturbo modes) | ||
1066 | */ | ||
1067 | mdelay(1); | ||
1068 | /* Disable phy and wait */ | ||
1069 | ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT); | ||
1070 | mdelay(1); | ||
1071 | } | ||
1072 | |||
1073 | /* | ||
1074 | * Restore saved values | ||
1075 | */ | ||
1076 | |||
1077 | /*DCU/Antenna selection not available on 5210*/ | ||
1078 | if (ah->ah_version != AR5K_AR5210) { | ||
1079 | |||
1080 | if (change_channel) { | ||
1081 | if (ah->ah_mac_srev < AR5K_SREV_AR5211) { | ||
1082 | for (i = 0; i < 10; i++) | ||
1083 | ath5k_hw_reg_write(ah, s_seq[i], | ||
1084 | AR5K_QUEUE_DCU_SEQNUM(i)); | ||
1085 | } else { | ||
1086 | ath5k_hw_reg_write(ah, s_seq[0], | ||
1087 | AR5K_QUEUE_DCU_SEQNUM(0)); | ||
1088 | } | ||
1089 | |||
1090 | |||
1091 | if (ah->ah_version == AR5K_AR5211) { | ||
1092 | ath5k_hw_reg_write(ah, tsf_up, AR5K_TSF_U32); | ||
1093 | ath5k_hw_reg_write(ah, tsf_lo, AR5K_TSF_L32); | ||
1094 | } | ||
1095 | } | ||
1096 | |||
1097 | ath5k_hw_reg_write(ah, s_ant, AR5K_DEFAULT_ANTENNA); | ||
1098 | } | ||
1099 | |||
1100 | /* Ledstate */ | ||
1101 | AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, s_led[0]); | ||
1102 | |||
1103 | /* Gpio settings */ | ||
1104 | ath5k_hw_reg_write(ah, s_led[1], AR5K_GPIOCR); | ||
1105 | ath5k_hw_reg_write(ah, s_led[2], AR5K_GPIODO); | ||
1106 | |||
1107 | /* Restore sta_id flags and preserve our mac address*/ | ||
1108 | ath5k_hw_reg_write(ah, AR5K_LOW_ID(ah->ah_sta_id), | ||
1109 | AR5K_STA_ID0); | ||
1110 | ath5k_hw_reg_write(ah, staid1_flags | AR5K_HIGH_ID(ah->ah_sta_id), | ||
1111 | AR5K_STA_ID1); | ||
1112 | |||
1113 | |||
1114 | /* | ||
1115 | * Configure PCU | ||
1116 | */ | ||
1117 | |||
1118 | /* Restore bssid and bssid mask */ | ||
1119 | /* XXX: add ah->aid once mac80211 gives this to us */ | ||
1120 | ath5k_hw_set_associd(ah, ah->ah_bssid, 0); | ||
1121 | |||
1122 | /* Set PCU config */ | ||
1123 | ath5k_hw_set_opmode(ah); | ||
1124 | |||
1125 | /* Clear any pending interrupts | ||
1126 | * PISR/SISR Not available on 5210 */ | ||
1127 | if (ah->ah_version != AR5K_AR5210) | ||
1128 | ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR); | ||
1129 | |||
1130 | /* Set RSSI/BRSSI thresholds | ||
1131 | * | ||
1132 | * Note: If we decide to set this value | ||
1133 | * dynamicaly, have in mind that when AR5K_RSSI_THR | ||
1134 | * register is read it might return 0x40 if we haven't | ||
1135 | * wrote anything to it plus BMISS RSSI threshold is zeroed. | ||
1136 | * So doing a save/restore procedure here isn't the right | ||
1137 | * choice. Instead store it on ath5k_hw */ | ||
1138 | ath5k_hw_reg_write(ah, (AR5K_TUNE_RSSI_THRES | | ||
1139 | AR5K_TUNE_BMISS_THRES << | ||
1140 | AR5K_RSSI_THR_BMISS_S), | ||
1141 | AR5K_RSSI_THR); | ||
1142 | |||
1143 | /* MIC QoS support */ | ||
1144 | if (ah->ah_mac_srev >= AR5K_SREV_AR2413) { | ||
1145 | ath5k_hw_reg_write(ah, 0x000100aa, AR5K_MIC_QOS_CTL); | ||
1146 | ath5k_hw_reg_write(ah, 0x00003210, AR5K_MIC_QOS_SEL); | ||
1147 | } | ||
1148 | |||
1149 | /* QoS NOACK Policy */ | ||
1150 | if (ah->ah_version == AR5K_AR5212) { | ||
1151 | ath5k_hw_reg_write(ah, | ||
1152 | AR5K_REG_SM(2, AR5K_QOS_NOACK_2BIT_VALUES) | | ||
1153 | AR5K_REG_SM(5, AR5K_QOS_NOACK_BIT_OFFSET) | | ||
1154 | AR5K_REG_SM(0, AR5K_QOS_NOACK_BYTE_OFFSET), | ||
1155 | AR5K_QOS_NOACK); | ||
1156 | } | ||
1157 | |||
1158 | |||
1159 | /* | ||
1160 | * Configure PHY | ||
1161 | */ | ||
1162 | |||
1163 | /* Set channel on PHY */ | ||
1164 | ret = ath5k_hw_channel(ah, channel); | ||
1165 | if (ret) | ||
1166 | return ret; | ||
1167 | |||
1168 | /* | ||
1169 | * Enable the PHY and wait until completion | ||
1170 | * This includes BaseBand and Synthesizer | ||
1171 | * activation. | ||
1172 | */ | ||
1173 | ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT); | ||
1174 | |||
1175 | /* | ||
1176 | * On 5211+ read activation -> rx delay | ||
1177 | * and use it. | ||
1178 | * | ||
1179 | * TODO: Half/quarter rate support | ||
1180 | */ | ||
1181 | if (ah->ah_version != AR5K_AR5210) { | ||
1182 | u32 delay; | ||
1183 | delay = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) & | ||
1184 | AR5K_PHY_RX_DELAY_M; | ||
1185 | delay = (channel->hw_value & CHANNEL_CCK) ? | ||
1186 | ((delay << 2) / 22) : (delay / 10); | ||
1187 | |||
1188 | udelay(100 + (2 * delay)); | ||
1189 | } else { | ||
1190 | mdelay(1); | ||
1191 | } | ||
1192 | |||
1193 | /* | ||
1194 | * Perform ADC test to see if baseband is ready | ||
1195 | * Set tx hold and check adc test register | ||
1196 | */ | ||
1197 | phy_tst1 = ath5k_hw_reg_read(ah, AR5K_PHY_TST1); | ||
1198 | ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1); | ||
1199 | for (i = 0; i <= 20; i++) { | ||
1200 | if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10)) | ||
1201 | break; | ||
1202 | udelay(200); | ||
1203 | } | ||
1204 | ath5k_hw_reg_write(ah, phy_tst1, AR5K_PHY_TST1); | ||
1205 | |||
1206 | /* | ||
1207 | * Start automatic gain control calibration | ||
1208 | * | ||
1209 | * During AGC calibration RX path is re-routed to | ||
1210 | * a power detector so we don't receive anything. | ||
1211 | * | ||
1212 | * This method is used to calibrate some static offsets | ||
1213 | * used together with on-the fly I/Q calibration (the | ||
1214 | * one performed via ath5k_hw_phy_calibrate), that doesn't | ||
1215 | * interrupt rx path. | ||
1216 | * | ||
1217 | * While rx path is re-routed to the power detector we also | ||
1218 | * start a noise floor calibration, to measure the | ||
1219 | * card's noise floor (the noise we measure when we are not | ||
1220 | * transmiting or receiving anything). | ||
1221 | * | ||
1222 | * If we are in a noisy environment AGC calibration may time | ||
1223 | * out and/or noise floor calibration might timeout. | ||
1224 | */ | ||
1225 | AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL, | ||
1226 | AR5K_PHY_AGCCTL_CAL); | ||
1227 | |||
1228 | /* At the same time start I/Q calibration for QAM constellation | ||
1229 | * -no need for CCK- */ | ||
1230 | ah->ah_calibration = false; | ||
1231 | if (!(mode == AR5K_MODE_11B)) { | ||
1232 | ah->ah_calibration = true; | ||
1233 | AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ, | ||
1234 | AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15); | ||
1235 | AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ, | ||
1236 | AR5K_PHY_IQ_RUN); | ||
1237 | } | ||
1238 | |||
1239 | /* Wait for gain calibration to finish (we check for I/Q calibration | ||
1240 | * during ath5k_phy_calibrate) */ | ||
1241 | if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL, | ||
1242 | AR5K_PHY_AGCCTL_CAL, 0, false)) { | ||
1243 | ATH5K_ERR(ah->ah_sc, "gain calibration timeout (%uMHz)\n", | ||
1244 | channel->center_freq); | ||
1245 | } | ||
1246 | |||
1247 | /* | ||
1248 | * If we run NF calibration before AGC, it always times out. | ||
1249 | * Binary HAL starts NF and AGC calibration at the same time | ||
1250 | * and only waits for AGC to finish. Also if AGC or NF cal. | ||
1251 | * times out, reset doesn't fail on binary HAL. I believe | ||
1252 | * that's wrong because since rx path is routed to a detector, | ||
1253 | * if cal. doesn't finish we won't have RX. Sam's HAL for AR5210/5211 | ||
1254 | * enables noise floor calibration after offset calibration and if noise | ||
1255 | * floor calibration fails, reset fails. I believe that's | ||
1256 | * a better approach, we just need to find a polling interval | ||
1257 | * that suits best, even if reset continues we need to make | ||
1258 | * sure that rx path is ready. | ||
1259 | */ | ||
1260 | ath5k_hw_noise_floor_calibration(ah, channel->center_freq); | ||
1261 | |||
1262 | |||
1263 | /* | ||
1264 | * Configure QCUs/DCUs | ||
1265 | */ | ||
1266 | |||
1267 | /* TODO: HW Compression support for data queues */ | ||
1268 | /* TODO: Burst prefetch for data queues */ | ||
1269 | |||
1270 | /* | ||
1271 | * Reset queues and start beacon timers at the end of the reset routine | ||
1272 | * This also sets QCU mask on each DCU for 1:1 qcu to dcu mapping | ||
1273 | * Note: If we want we can assign multiple qcus on one dcu. | ||
1274 | */ | ||
1275 | for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) { | ||
1276 | ret = ath5k_hw_reset_tx_queue(ah, i); | ||
1277 | if (ret) { | ||
1278 | ATH5K_ERR(ah->ah_sc, | ||
1279 | "failed to reset TX queue #%d\n", i); | ||
1280 | return ret; | ||
1281 | } | ||
1282 | } | ||
1283 | |||
1284 | |||
1285 | /* | ||
1286 | * Configure DMA/Interrupts | ||
1287 | */ | ||
1288 | |||
1289 | /* | ||
1290 | * Set Rx/Tx DMA Configuration | ||
1291 | * | ||
1292 | * Set standard DMA size (128). Note that | ||
1293 | * a DMA size of 512 causes rx overruns and tx errors | ||
1294 | * on pci-e cards (tested on 5424 but since rx overruns | ||
1295 | * also occur on 5416/5418 with madwifi we set 128 | ||
1296 | * for all PCI-E cards to be safe). | ||
1297 | * | ||
1298 | * XXX: need to check 5210 for this | ||
1299 | * TODO: Check out tx triger level, it's always 64 on dumps but I | ||
1300 | * guess we can tweak it and see how it goes ;-) | ||
1301 | */ | ||
1302 | if (ah->ah_version != AR5K_AR5210) { | ||
1303 | AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG, | ||
1304 | AR5K_TXCFG_SDMAMR, AR5K_DMASIZE_128B); | ||
1305 | AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG, | ||
1306 | AR5K_RXCFG_SDMAMW, AR5K_DMASIZE_128B); | ||
1307 | } | ||
1308 | |||
1309 | /* Pre-enable interrupts on 5211/5212*/ | ||
1310 | if (ah->ah_version != AR5K_AR5210) | ||
1311 | ath5k_hw_set_imr(ah, ah->ah_imr); | ||
1312 | |||
1313 | /* | ||
1314 | * Setup RFKill interrupt if rfkill flag is set on eeprom. | ||
1315 | * TODO: Use gpio pin and polarity infos from eeprom | ||
1316 | * TODO: Handle this in ath5k_intr because it'll result | ||
1317 | * a nasty interrupt storm. | ||
1318 | */ | ||
1319 | #if 0 | ||
1320 | if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) { | ||
1321 | ath5k_hw_set_gpio_input(ah, 0); | ||
1322 | ah->ah_gpio[0] = ath5k_hw_get_gpio(ah, 0); | ||
1323 | if (ah->ah_gpio[0] == 0) | ||
1324 | ath5k_hw_set_gpio_intr(ah, 0, 1); | ||
1325 | else | ||
1326 | ath5k_hw_set_gpio_intr(ah, 0, 0); | ||
1327 | } | ||
1328 | #endif | ||
1329 | |||
1330 | /* Enable 32KHz clock function for AR5212+ chips | ||
1331 | * Set clocks to 32KHz operation and use an | ||
1332 | * external 32KHz crystal when sleeping if one | ||
1333 | * exists */ | ||
1334 | if (ah->ah_version == AR5K_AR5212) | ||
1335 | ath5k_hw_set_sleep_clock(ah, true); | ||
1336 | |||
1337 | /* | ||
1338 | * Disable beacons and reset the register | ||
1339 | */ | ||
1340 | AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE | | ||
1341 | AR5K_BEACON_RESET_TSF); | ||
1342 | |||
1343 | return 0; | ||
1344 | } | ||
1345 | |||
1346 | #undef _ATH5K_RESET | ||