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