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