aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath5k/reset.c
diff options
context:
space:
mode:
authorNick Kossifidis <mick@madwifi.org>2008-08-29 15:45:39 -0400
committerJohn W. Linville <linville@tuxdriver.com>2008-09-05 16:15:24 -0400
commitc6e387a214f4b2c4bd48020409e366c133385d98 (patch)
tree11fd58fd71e113a62d05f6f191771ca3d7d544f0 /drivers/net/wireless/ath5k/reset.c
parentfa9abe050d0a018b888fce61a4353afab17b0860 (diff)
ath5k: HW code cleanup
* No code changes... * Split hw.c to multiple files for better maintenance and add some documentation on each file code is going to grow soon (eeprom.c for example is going to get much stuff currently developed on ath_info) so it's better this way. * Rename following functions to maintain naming scheme: ah_setup_xtx_desc -> ah_setup_mrr_tx_desc (Because xtx doesn't say much, it's actually a multi-rate-retry tx descriptor) ath5k_hw_put_tx/rx_buf - > ath5k_hw_set_tx/rxdp ath5k_hw_get_tx/rx_buf -> ath5k_hw_get_tx/rxdp (We don't put any "buf" we set descriptor pointers on hw) ath5k_hw_tx_start -> ath5k_hw_start_tx_dma ath5k_hw_start_rx -> ath5k_hw_start_rx_dma ath5k_hw_stop_pcu_recv -> ath5k_hw_stop_rx_pcu (It's easier this way to identify them, we also have ath5k_hw_start_rx_pcu which completes the set) ath5k_hw_set_intr -> ath5k_hw_set_imr (As in get_isr we set imr here, not "intr") * Move ath5k_hw_setup_rx_desc on ah->ah_setup_rx_desc so we can include support for different rx descriptors in the future * Further cleanups so that checkpatch doesn't complain (only some > 80 col warnings for eeprom.h and reg.h as usual due to comments) Tested on 5211 and 5213 cards and works ok. Changes-licensed-under: ISC Signed-off-by: Nick Kossifidis <mickflemm@gmail.com> Acked-by: Luis R. Rodriguez <lrodriguez@atheros.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath5k/reset.c')
-rw-r--r--drivers/net/wireless/ath5k/reset.c925
1 files changed, 925 insertions, 0 deletions
diff --git a/drivers/net/wireless/ath5k/reset.c b/drivers/net/wireless/ath5k/reset.c
new file mode 100644
index 000000000000..d260fba0180f
--- /dev/null
+++ b/drivers/net/wireless/ath5k/reset.c
@@ -0,0 +1,925 @@
1/*
2 * Copyright (c) 2004-2008 Reyk Floeter <reyk@openbsd.org>
3 * Copyright (c) 2006-2008 Nick Kossifidis <mickflemm@gmail.com>
4 * Copyright (c) 2007-2008 Luis Rodriguez <mcgrof@winlab.rutgers.edu>
5 * Copyright (c) 2007-2008 Pavel Roskin <proski@gnu.org>
6 * Copyright (c) 2007-2008 Jiri Slaby <jirislaby@gmail.com>
7 *
8 * Permission to use, copy, modify, and distribute this software for any
9 * purpose with or without fee is hereby granted, provided that the above
10 * copyright notice and this permission notice appear in all copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 *
20 */
21
22#define _ATH5K_RESET
23
24/*****************************\
25 Reset functions and helpers
26\*****************************/
27
28#include <linux/pci.h>
29#include "ath5k.h"
30#include "reg.h"
31#include "base.h"
32#include "debug.h"
33
34/**
35 * ath5k_hw_write_ofdm_timings - set OFDM timings on AR5212
36 *
37 * @ah: the &struct ath5k_hw
38 * @channel: the currently set channel upon reset
39 *
40 * Write the OFDM timings for the AR5212 upon reset. This is a helper for
41 * ath5k_hw_reset(). This seems to tune the PLL a specified frequency
42 * depending on the bandwidth of the channel.
43 *
44 */
45static inline int ath5k_hw_write_ofdm_timings(struct ath5k_hw *ah,
46 struct ieee80211_channel *channel)
47{
48 /* Get exponent and mantissa and set it */
49 u32 coef_scaled, coef_exp, coef_man,
50 ds_coef_exp, ds_coef_man, clock;
51
52 if (!(ah->ah_version == AR5K_AR5212) ||
53 !(channel->hw_value & CHANNEL_OFDM))
54 BUG();
55
56 /* Seems there are two PLLs, one for baseband sampling and one
57 * for tuning. Tuning basebands are 40 MHz or 80MHz when in
58 * turbo. */
59 clock = channel->hw_value & CHANNEL_TURBO ? 80 : 40;
60 coef_scaled = ((5 * (clock << 24)) / 2) /
61 channel->center_freq;
62
63 for (coef_exp = 31; coef_exp > 0; coef_exp--)
64 if ((coef_scaled >> coef_exp) & 0x1)
65 break;
66
67 if (!coef_exp)
68 return -EINVAL;
69
70 coef_exp = 14 - (coef_exp - 24);
71 coef_man = coef_scaled +
72 (1 << (24 - coef_exp - 1));
73 ds_coef_man = coef_man >> (24 - coef_exp);
74 ds_coef_exp = coef_exp - 16;
75
76 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
77 AR5K_PHY_TIMING_3_DSC_MAN, ds_coef_man);
78 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_TIMING_3,
79 AR5K_PHY_TIMING_3_DSC_EXP, ds_coef_exp);
80
81 return 0;
82}
83
84
85/*
86 * index into rates for control rates, we can set it up like this because
87 * this is only used for AR5212 and we know it supports G mode
88 */
89static int control_rates[] =
90 { 0, 1, 1, 1, 4, 4, 6, 6, 8, 8, 8, 8 };
91
92/**
93 * ath5k_hw_write_rate_duration - set rate duration during hw resets
94 *
95 * @ah: the &struct ath5k_hw
96 * @mode: one of enum ath5k_driver_mode
97 *
98 * Write the rate duration table upon hw reset. This is a helper for
99 * ath5k_hw_reset(). It seems all this is doing is setting an ACK timeout for
100 * the hardware for the current mode for each rate. The rates which are capable
101 * of short preamble (802.11b rates 2Mbps, 5.5Mbps, and 11Mbps) have another
102 * register for the short preamble ACK timeout calculation.
103 */
104static inline void ath5k_hw_write_rate_duration(struct ath5k_hw *ah,
105 unsigned int mode)
106{
107 struct ath5k_softc *sc = ah->ah_sc;
108 struct ieee80211_rate *rate;
109 unsigned int i;
110
111 /* Write rate duration table */
112 for (i = 0; i < sc->sbands[IEEE80211_BAND_2GHZ].n_bitrates; i++) {
113 u32 reg;
114 u16 tx_time;
115
116 rate = &sc->sbands[IEEE80211_BAND_2GHZ].bitrates[control_rates[i]];
117
118 /* Set ACK timeout */
119 reg = AR5K_RATE_DUR(rate->hw_value);
120
121 /* An ACK frame consists of 10 bytes. If you add the FCS,
122 * which ieee80211_generic_frame_duration() adds,
123 * its 14 bytes. Note we use the control rate and not the
124 * actual rate for this rate. See mac80211 tx.c
125 * ieee80211_duration() for a brief description of
126 * what rate we should choose to TX ACKs. */
127 tx_time = le16_to_cpu(ieee80211_generic_frame_duration(sc->hw,
128 sc->vif, 10, rate));
129
130 ath5k_hw_reg_write(ah, tx_time, reg);
131
132 if (!(rate->flags & IEEE80211_RATE_SHORT_PREAMBLE))
133 continue;
134
135 /*
136 * We're not distinguishing short preamble here,
137 * This is true, all we'll get is a longer value here
138 * which is not necessarilly bad. We could use
139 * export ieee80211_frame_duration() but that needs to be
140 * fixed first to be properly used by mac802111 drivers:
141 *
142 * - remove erp stuff and let the routine figure ofdm
143 * erp rates
144 * - remove passing argument ieee80211_local as
145 * drivers don't have access to it
146 * - move drivers using ieee80211_generic_frame_duration()
147 * to this
148 */
149 ath5k_hw_reg_write(ah, tx_time,
150 reg + (AR5K_SET_SHORT_PREAMBLE << 2));
151 }
152}
153
154/*
155 * Reset chipset
156 */
157static int ath5k_hw_nic_reset(struct ath5k_hw *ah, u32 val)
158{
159 int ret;
160 u32 mask = val ? val : ~0U;
161
162 ATH5K_TRACE(ah->ah_sc);
163
164 /* Read-and-clear RX Descriptor Pointer*/
165 ath5k_hw_reg_read(ah, AR5K_RXDP);
166
167 /*
168 * Reset the device and wait until success
169 */
170 ath5k_hw_reg_write(ah, val, AR5K_RESET_CTL);
171
172 /* Wait at least 128 PCI clocks */
173 udelay(15);
174
175 if (ah->ah_version == AR5K_AR5210) {
176 val &= AR5K_RESET_CTL_CHIP;
177 mask &= AR5K_RESET_CTL_CHIP;
178 } else {
179 val &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND;
180 mask &= AR5K_RESET_CTL_PCU | AR5K_RESET_CTL_BASEBAND;
181 }
182
183 ret = ath5k_hw_register_timeout(ah, AR5K_RESET_CTL, mask, val, false);
184
185 /*
186 * Reset configuration register (for hw byte-swap). Note that this
187 * is only set for big endian. We do the necessary magic in
188 * AR5K_INIT_CFG.
189 */
190 if ((val & AR5K_RESET_CTL_PCU) == 0)
191 ath5k_hw_reg_write(ah, AR5K_INIT_CFG, AR5K_CFG);
192
193 return ret;
194}
195
196/*
197 * Sleep control
198 */
199int ath5k_hw_set_power(struct ath5k_hw *ah, enum ath5k_power_mode mode,
200 bool set_chip, u16 sleep_duration)
201{
202 unsigned int i;
203 u32 staid, data;
204
205 ATH5K_TRACE(ah->ah_sc);
206 staid = ath5k_hw_reg_read(ah, AR5K_STA_ID1);
207
208 switch (mode) {
209 case AR5K_PM_AUTO:
210 staid &= ~AR5K_STA_ID1_DEFAULT_ANTENNA;
211 /* fallthrough */
212 case AR5K_PM_NETWORK_SLEEP:
213 if (set_chip)
214 ath5k_hw_reg_write(ah,
215 AR5K_SLEEP_CTL_SLE_ALLOW |
216 sleep_duration,
217 AR5K_SLEEP_CTL);
218
219 staid |= AR5K_STA_ID1_PWR_SV;
220 break;
221
222 case AR5K_PM_FULL_SLEEP:
223 if (set_chip)
224 ath5k_hw_reg_write(ah, AR5K_SLEEP_CTL_SLE_SLP,
225 AR5K_SLEEP_CTL);
226
227 staid |= AR5K_STA_ID1_PWR_SV;
228 break;
229
230 case AR5K_PM_AWAKE:
231
232 staid &= ~AR5K_STA_ID1_PWR_SV;
233
234 if (!set_chip)
235 goto commit;
236
237 /* Preserve sleep duration */
238 data = ath5k_hw_reg_read(ah, AR5K_SLEEP_CTL);
239 if (data & 0xffc00000)
240 data = 0;
241 else
242 data = data & 0xfffcffff;
243
244 ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL);
245 udelay(15);
246
247 for (i = 50; i > 0; i--) {
248 /* Check if the chip did wake up */
249 if ((ath5k_hw_reg_read(ah, AR5K_PCICFG) &
250 AR5K_PCICFG_SPWR_DN) == 0)
251 break;
252
253 /* Wait a bit and retry */
254 udelay(200);
255 ath5k_hw_reg_write(ah, data, AR5K_SLEEP_CTL);
256 }
257
258 /* Fail if the chip didn't wake up */
259 if (i <= 0)
260 return -EIO;
261
262 break;
263
264 default:
265 return -EINVAL;
266 }
267
268commit:
269 ah->ah_power_mode = mode;
270 ath5k_hw_reg_write(ah, staid, AR5K_STA_ID1);
271
272 return 0;
273}
274
275/*
276 * Bring up MAC + PHY Chips
277 */
278int ath5k_hw_nic_wakeup(struct ath5k_hw *ah, int flags, bool initial)
279{
280 struct pci_dev *pdev = ah->ah_sc->pdev;
281 u32 turbo, mode, clock, bus_flags;
282 int ret;
283
284 turbo = 0;
285 mode = 0;
286 clock = 0;
287
288 ATH5K_TRACE(ah->ah_sc);
289
290 /* Wakeup the device */
291 ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
292 if (ret) {
293 ATH5K_ERR(ah->ah_sc, "failed to wakeup the MAC Chip\n");
294 return ret;
295 }
296
297 if (ah->ah_version != AR5K_AR5210) {
298 /*
299 * Get channel mode flags
300 */
301
302 if (ah->ah_radio >= AR5K_RF5112) {
303 mode = AR5K_PHY_MODE_RAD_RF5112;
304 clock = AR5K_PHY_PLL_RF5112;
305 } else {
306 mode = AR5K_PHY_MODE_RAD_RF5111; /*Zero*/
307 clock = AR5K_PHY_PLL_RF5111; /*Zero*/
308 }
309
310 if (flags & CHANNEL_2GHZ) {
311 mode |= AR5K_PHY_MODE_FREQ_2GHZ;
312 clock |= AR5K_PHY_PLL_44MHZ;
313
314 if (flags & CHANNEL_CCK) {
315 mode |= AR5K_PHY_MODE_MOD_CCK;
316 } else if (flags & CHANNEL_OFDM) {
317 /* XXX Dynamic OFDM/CCK is not supported by the
318 * AR5211 so we set MOD_OFDM for plain g (no
319 * CCK headers) operation. We need to test
320 * this, 5211 might support ofdm-only g after
321 * all, there are also initial register values
322 * in the code for g mode (see initvals.c). */
323 if (ah->ah_version == AR5K_AR5211)
324 mode |= AR5K_PHY_MODE_MOD_OFDM;
325 else
326 mode |= AR5K_PHY_MODE_MOD_DYN;
327 } else {
328 ATH5K_ERR(ah->ah_sc,
329 "invalid radio modulation mode\n");
330 return -EINVAL;
331 }
332 } else if (flags & CHANNEL_5GHZ) {
333 mode |= AR5K_PHY_MODE_FREQ_5GHZ;
334 clock |= AR5K_PHY_PLL_40MHZ;
335
336 if (flags & CHANNEL_OFDM)
337 mode |= AR5K_PHY_MODE_MOD_OFDM;
338 else {
339 ATH5K_ERR(ah->ah_sc,
340 "invalid radio modulation mode\n");
341 return -EINVAL;
342 }
343 } else {
344 ATH5K_ERR(ah->ah_sc, "invalid radio frequency mode\n");
345 return -EINVAL;
346 }
347
348 if (flags & CHANNEL_TURBO)
349 turbo = AR5K_PHY_TURBO_MODE | AR5K_PHY_TURBO_SHORT;
350 } else { /* Reset the device */
351
352 /* ...enable Atheros turbo mode if requested */
353 if (flags & CHANNEL_TURBO)
354 ath5k_hw_reg_write(ah, AR5K_PHY_TURBO_MODE,
355 AR5K_PHY_TURBO);
356 }
357
358 /* reseting PCI on PCI-E cards results card to hang
359 * and always return 0xffff... so we ingore that flag
360 * for PCI-E cards */
361 bus_flags = (pdev->is_pcie) ? 0 : AR5K_RESET_CTL_PCI;
362
363 /* Reset chipset */
364 ret = ath5k_hw_nic_reset(ah, AR5K_RESET_CTL_PCU |
365 AR5K_RESET_CTL_BASEBAND | bus_flags);
366 if (ret) {
367 ATH5K_ERR(ah->ah_sc, "failed to reset the MAC Chip\n");
368 return -EIO;
369 }
370
371 if (ah->ah_version == AR5K_AR5210)
372 udelay(2300);
373
374 /* ...wakeup again!*/
375 ret = ath5k_hw_set_power(ah, AR5K_PM_AWAKE, true, 0);
376 if (ret) {
377 ATH5K_ERR(ah->ah_sc, "failed to resume the MAC Chip\n");
378 return ret;
379 }
380
381 /* ...final warm reset */
382 if (ath5k_hw_nic_reset(ah, 0)) {
383 ATH5K_ERR(ah->ah_sc, "failed to warm reset the MAC Chip\n");
384 return -EIO;
385 }
386
387 if (ah->ah_version != AR5K_AR5210) {
388 /* ...set the PHY operating mode */
389 ath5k_hw_reg_write(ah, clock, AR5K_PHY_PLL);
390 udelay(300);
391
392 ath5k_hw_reg_write(ah, mode, AR5K_PHY_MODE);
393 ath5k_hw_reg_write(ah, turbo, AR5K_PHY_TURBO);
394 }
395
396 return 0;
397}
398
399/*
400 * Main reset function
401 */
402int ath5k_hw_reset(struct ath5k_hw *ah, enum ieee80211_if_types op_mode,
403 struct ieee80211_channel *channel, bool change_channel)
404{
405 struct ath5k_eeprom_info *ee = &ah->ah_capabilities.cap_eeprom;
406 struct pci_dev *pdev = ah->ah_sc->pdev;
407 u32 data, s_seq, s_ant, s_led[3], dma_size;
408 unsigned int i, mode, freq, ee_mode, ant[2];
409 int ret;
410
411 ATH5K_TRACE(ah->ah_sc);
412
413 s_seq = 0;
414 s_ant = 0;
415 ee_mode = 0;
416 freq = 0;
417 mode = 0;
418
419 /*
420 * Save some registers before a reset
421 */
422 /*DCU/Antenna selection not available on 5210*/
423 if (ah->ah_version != AR5K_AR5210) {
424 if (change_channel) {
425 /* Seq number for queue 0 -do this for all queues ? */
426 s_seq = ath5k_hw_reg_read(ah,
427 AR5K_QUEUE_DFS_SEQNUM(0));
428 /*Default antenna*/
429 s_ant = ath5k_hw_reg_read(ah, AR5K_DEFAULT_ANTENNA);
430 }
431 }
432
433 /*GPIOs*/
434 s_led[0] = ath5k_hw_reg_read(ah, AR5K_PCICFG) & AR5K_PCICFG_LEDSTATE;
435 s_led[1] = ath5k_hw_reg_read(ah, AR5K_GPIOCR);
436 s_led[2] = ath5k_hw_reg_read(ah, AR5K_GPIODO);
437
438 if (change_channel && ah->ah_rf_banks != NULL)
439 ath5k_hw_get_rf_gain(ah);
440
441
442 /*Wakeup the device*/
443 ret = ath5k_hw_nic_wakeup(ah, channel->hw_value, false);
444 if (ret)
445 return ret;
446
447 /*
448 * Initialize operating mode
449 */
450 ah->ah_op_mode = op_mode;
451
452 /*
453 * 5111/5112 Settings
454 * 5210 only comes with RF5110
455 */
456 if (ah->ah_version != AR5K_AR5210) {
457 if (ah->ah_radio != AR5K_RF5111 &&
458 ah->ah_radio != AR5K_RF5112 &&
459 ah->ah_radio != AR5K_RF5413 &&
460 ah->ah_radio != AR5K_RF2413 &&
461 ah->ah_radio != AR5K_RF2425) {
462 ATH5K_ERR(ah->ah_sc,
463 "invalid phy radio: %u\n", ah->ah_radio);
464 return -EINVAL;
465 }
466
467 switch (channel->hw_value & CHANNEL_MODES) {
468 case CHANNEL_A:
469 mode = AR5K_MODE_11A;
470 freq = AR5K_INI_RFGAIN_5GHZ;
471 ee_mode = AR5K_EEPROM_MODE_11A;
472 break;
473 case CHANNEL_G:
474 mode = AR5K_MODE_11G;
475 freq = AR5K_INI_RFGAIN_2GHZ;
476 ee_mode = AR5K_EEPROM_MODE_11G;
477 break;
478 case CHANNEL_B:
479 mode = AR5K_MODE_11B;
480 freq = AR5K_INI_RFGAIN_2GHZ;
481 ee_mode = AR5K_EEPROM_MODE_11B;
482 break;
483 case CHANNEL_T:
484 mode = AR5K_MODE_11A_TURBO;
485 freq = AR5K_INI_RFGAIN_5GHZ;
486 ee_mode = AR5K_EEPROM_MODE_11A;
487 break;
488 /*Is this ok on 5211 too ?*/
489 case CHANNEL_TG:
490 mode = AR5K_MODE_11G_TURBO;
491 freq = AR5K_INI_RFGAIN_2GHZ;
492 ee_mode = AR5K_EEPROM_MODE_11G;
493 break;
494 case CHANNEL_XR:
495 if (ah->ah_version == AR5K_AR5211) {
496 ATH5K_ERR(ah->ah_sc,
497 "XR mode not available on 5211");
498 return -EINVAL;
499 }
500 mode = AR5K_MODE_XR;
501 freq = AR5K_INI_RFGAIN_5GHZ;
502 ee_mode = AR5K_EEPROM_MODE_11A;
503 break;
504 default:
505 ATH5K_ERR(ah->ah_sc,
506 "invalid channel: %d\n", channel->center_freq);
507 return -EINVAL;
508 }
509
510 /* PHY access enable */
511 ath5k_hw_reg_write(ah, AR5K_PHY_SHIFT_5GHZ, AR5K_PHY(0));
512
513 }
514
515 ret = ath5k_hw_write_initvals(ah, mode, change_channel);
516 if (ret)
517 return ret;
518
519 /*
520 * 5211/5212 Specific
521 */
522 if (ah->ah_version != AR5K_AR5210) {
523 /*
524 * Write initial RF gain settings
525 * This should work for both 5111/5112
526 */
527 ret = ath5k_hw_rfgain(ah, freq);
528 if (ret)
529 return ret;
530
531 mdelay(1);
532
533 /*
534 * Write some more initial register settings
535 */
536 if (ah->ah_version == AR5K_AR5212) {
537 ath5k_hw_reg_write(ah, 0x0002a002, 0x982c);
538
539 if (channel->hw_value == CHANNEL_G)
540 if (ah->ah_mac_srev < AR5K_SREV_VER_AR2413)
541 ath5k_hw_reg_write(ah, 0x00f80d80,
542 0x994c);
543 else if (ah->ah_mac_srev < AR5K_SREV_VER_AR2424)
544 ath5k_hw_reg_write(ah, 0x00380140,
545 0x994c);
546 else if (ah->ah_mac_srev < AR5K_SREV_VER_AR2425)
547 ath5k_hw_reg_write(ah, 0x00fc0ec0,
548 0x994c);
549 else /* 2425 */
550 ath5k_hw_reg_write(ah, 0x00fc0fc0,
551 0x994c);
552 else
553 ath5k_hw_reg_write(ah, 0x00000000, 0x994c);
554
555 /* Some bits are disabled here, we know nothing about
556 * register 0xa228 yet, most of the times this ends up
557 * with a value 0x9b5 -haven't seen any dump with
558 * a different value- */
559 /* Got this from decompiling binary HAL */
560 data = ath5k_hw_reg_read(ah, 0xa228);
561 data &= 0xfffffdff;
562 ath5k_hw_reg_write(ah, data, 0xa228);
563
564 data = ath5k_hw_reg_read(ah, 0xa228);
565 data &= 0xfffe03ff;
566 ath5k_hw_reg_write(ah, data, 0xa228);
567 data = 0;
568
569 /* Just write 0x9b5 ? */
570 /* ath5k_hw_reg_write(ah, 0x000009b5, 0xa228); */
571 ath5k_hw_reg_write(ah, 0x0000000f, AR5K_SEQ_MASK);
572 ath5k_hw_reg_write(ah, 0x00000000, 0xa254);
573 ath5k_hw_reg_write(ah, 0x0000000e, AR5K_PHY_SCAL);
574 }
575
576 /* Fix for first revision of the RF5112 RF chipset */
577 if (ah->ah_radio >= AR5K_RF5112 &&
578 ah->ah_radio_5ghz_revision <
579 AR5K_SREV_RAD_5112A) {
580 ath5k_hw_reg_write(ah, AR5K_PHY_CCKTXCTL_WORLD,
581 AR5K_PHY_CCKTXCTL);
582 if (channel->hw_value & CHANNEL_5GHZ)
583 data = 0xffb81020;
584 else
585 data = 0xffb80d20;
586 ath5k_hw_reg_write(ah, data, AR5K_PHY_FRAME_CTL);
587 data = 0;
588 }
589
590 /*
591 * Set TX power (FIXME)
592 */
593 ret = ath5k_hw_txpower(ah, channel, AR5K_TUNE_DEFAULT_TXPOWER);
594 if (ret)
595 return ret;
596
597 /* Write rate duration table only on AR5212 and if
598 * virtual interface has already been brought up
599 * XXX: rethink this after new mode changes to
600 * mac80211 are integrated */
601 if (ah->ah_version == AR5K_AR5212 &&
602 ah->ah_sc->vif != NULL)
603 ath5k_hw_write_rate_duration(ah, mode);
604
605 /*
606 * Write RF registers
607 */
608 ret = ath5k_hw_rfregs(ah, channel, mode);
609 if (ret)
610 return ret;
611
612 /*
613 * Configure additional registers
614 */
615
616 /* Write OFDM timings on 5212*/
617 if (ah->ah_version == AR5K_AR5212 &&
618 channel->hw_value & CHANNEL_OFDM) {
619 ret = ath5k_hw_write_ofdm_timings(ah, channel);
620 if (ret)
621 return ret;
622 }
623
624 /*Enable/disable 802.11b mode on 5111
625 (enable 2111 frequency converter + CCK)*/
626 if (ah->ah_radio == AR5K_RF5111) {
627 if (mode == AR5K_MODE_11B)
628 AR5K_REG_ENABLE_BITS(ah, AR5K_TXCFG,
629 AR5K_TXCFG_B_MODE);
630 else
631 AR5K_REG_DISABLE_BITS(ah, AR5K_TXCFG,
632 AR5K_TXCFG_B_MODE);
633 }
634
635 /*
636 * Set channel and calibrate the PHY
637 */
638 ret = ath5k_hw_channel(ah, channel);
639 if (ret)
640 return ret;
641
642 /* Set antenna mode */
643 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_ANT_CTL,
644 ah->ah_antenna[ee_mode][0], 0xfffffc06);
645
646 /*
647 * In case a fixed antenna was set as default
648 * write the same settings on both AR5K_PHY_ANT_SWITCH_TABLE
649 * registers.
650 */
651 if (s_ant != 0) {
652 if (s_ant == AR5K_ANT_FIXED_A) /* 1 - Main */
653 ant[0] = ant[1] = AR5K_ANT_FIXED_A;
654 else /* 2 - Aux */
655 ant[0] = ant[1] = AR5K_ANT_FIXED_B;
656 } else {
657 ant[0] = AR5K_ANT_FIXED_A;
658 ant[1] = AR5K_ANT_FIXED_B;
659 }
660
661 ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[0]],
662 AR5K_PHY_ANT_SWITCH_TABLE_0);
663 ath5k_hw_reg_write(ah, ah->ah_antenna[ee_mode][ant[1]],
664 AR5K_PHY_ANT_SWITCH_TABLE_1);
665
666 /* Commit values from EEPROM */
667 if (ah->ah_radio == AR5K_RF5111)
668 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_FRAME_CTL,
669 AR5K_PHY_FRAME_CTL_TX_CLIP, ee->ee_tx_clip);
670
671 ath5k_hw_reg_write(ah,
672 AR5K_PHY_NF_SVAL(ee->ee_noise_floor_thr[ee_mode]),
673 AR5K_PHY_NFTHRES);
674
675 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_SETTLING,
676 (ee->ee_switch_settling[ee_mode] << 7) & 0x3f80,
677 0xffffc07f);
678 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_GAIN,
679 (ee->ee_ant_tx_rx[ee_mode] << 12) & 0x3f000,
680 0xfffc0fff);
681 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_DESIRED_SIZE,
682 (ee->ee_adc_desired_size[ee_mode] & 0x00ff) |
683 ((ee->ee_pga_desired_size[ee_mode] << 8) & 0xff00),
684 0xffff0000);
685
686 ath5k_hw_reg_write(ah,
687 (ee->ee_tx_end2xpa_disable[ee_mode] << 24) |
688 (ee->ee_tx_end2xpa_disable[ee_mode] << 16) |
689 (ee->ee_tx_frm2xpa_enable[ee_mode] << 8) |
690 (ee->ee_tx_frm2xpa_enable[ee_mode]), AR5K_PHY_RF_CTL4);
691
692 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_RF_CTL3,
693 ee->ee_tx_end2xlna_enable[ee_mode] << 8, 0xffff00ff);
694 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_NF,
695 (ee->ee_thr_62[ee_mode] << 12) & 0x7f000, 0xfff80fff);
696 AR5K_REG_MASKED_BITS(ah, AR5K_PHY_OFDM_SELFCORR, 4, 0xffffff01);
697
698 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
699 AR5K_PHY_IQ_CORR_ENABLE |
700 (ee->ee_i_cal[ee_mode] << AR5K_PHY_IQ_CORR_Q_I_COFF_S) |
701 ee->ee_q_cal[ee_mode]);
702
703 if (ah->ah_ee_version >= AR5K_EEPROM_VERSION_4_1)
704 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_GAIN_2GHZ,
705 AR5K_PHY_GAIN_2GHZ_MARGIN_TXRX,
706 ee->ee_margin_tx_rx[ee_mode]);
707
708 } else {
709 mdelay(1);
710 /* Disable phy and wait */
711 ath5k_hw_reg_write(ah, AR5K_PHY_ACT_DISABLE, AR5K_PHY_ACT);
712 mdelay(1);
713 }
714
715 /*
716 * Restore saved values
717 */
718 /*DCU/Antenna selection not available on 5210*/
719 if (ah->ah_version != AR5K_AR5210) {
720 ath5k_hw_reg_write(ah, s_seq, AR5K_QUEUE_DFS_SEQNUM(0));
721 ath5k_hw_reg_write(ah, s_ant, AR5K_DEFAULT_ANTENNA);
722 }
723 AR5K_REG_ENABLE_BITS(ah, AR5K_PCICFG, s_led[0]);
724 ath5k_hw_reg_write(ah, s_led[1], AR5K_GPIOCR);
725 ath5k_hw_reg_write(ah, s_led[2], AR5K_GPIODO);
726
727 /*
728 * Misc
729 */
730 /* XXX: add ah->aid once mac80211 gives this to us */
731 ath5k_hw_set_associd(ah, ah->ah_bssid, 0);
732
733 ath5k_hw_set_opmode(ah);
734 /*PISR/SISR Not available on 5210*/
735 if (ah->ah_version != AR5K_AR5210) {
736 ath5k_hw_reg_write(ah, 0xffffffff, AR5K_PISR);
737 /* If we later allow tuning for this, store into sc structure */
738 data = AR5K_TUNE_RSSI_THRES |
739 AR5K_TUNE_BMISS_THRES << AR5K_RSSI_THR_BMISS_S;
740 ath5k_hw_reg_write(ah, data, AR5K_RSSI_THR);
741 }
742
743 /*
744 * Set Rx/Tx DMA Configuration
745 *
746 * Set maximum DMA size (512) except for PCI-E cards since
747 * it causes rx overruns and tx errors (tested on 5424 but since
748 * rx overruns also occur on 5416/5418 with madwifi we set 128
749 * for all PCI-E cards to be safe).
750 *
751 * In dumps this is 128 for allchips.
752 *
753 * XXX: need to check 5210 for this
754 * TODO: Check out tx triger level, it's always 64 on dumps but I
755 * guess we can tweak it and see how it goes ;-)
756 */
757 dma_size = (pdev->is_pcie) ? AR5K_DMASIZE_128B : AR5K_DMASIZE_512B;
758 if (ah->ah_version != AR5K_AR5210) {
759 AR5K_REG_WRITE_BITS(ah, AR5K_TXCFG,
760 AR5K_TXCFG_SDMAMR, dma_size);
761 AR5K_REG_WRITE_BITS(ah, AR5K_RXCFG,
762 AR5K_RXCFG_SDMAMW, dma_size);
763 }
764
765 /*
766 * Enable the PHY and wait until completion
767 */
768 ath5k_hw_reg_write(ah, AR5K_PHY_ACT_ENABLE, AR5K_PHY_ACT);
769
770 /*
771 * On 5211+ read activation -> rx delay
772 * and use it.
773 */
774 if (ah->ah_version != AR5K_AR5210) {
775 data = ath5k_hw_reg_read(ah, AR5K_PHY_RX_DELAY) &
776 AR5K_PHY_RX_DELAY_M;
777 data = (channel->hw_value & CHANNEL_CCK) ?
778 ((data << 2) / 22) : (data / 10);
779
780 udelay(100 + (2 * data));
781 data = 0;
782 } else {
783 mdelay(1);
784 }
785
786 /*
787 * Perform ADC test (?)
788 */
789 data = ath5k_hw_reg_read(ah, AR5K_PHY_TST1);
790 ath5k_hw_reg_write(ah, AR5K_PHY_TST1_TXHOLD, AR5K_PHY_TST1);
791 for (i = 0; i <= 20; i++) {
792 if (!(ath5k_hw_reg_read(ah, AR5K_PHY_ADC_TEST) & 0x10))
793 break;
794 udelay(200);
795 }
796 ath5k_hw_reg_write(ah, data, AR5K_PHY_TST1);
797 data = 0;
798
799 /*
800 * Start automatic gain calibration
801 *
802 * During AGC calibration RX path is re-routed to
803 * a signal detector so we don't receive anything.
804 *
805 * This method is used to calibrate some static offsets
806 * used together with on-the fly I/Q calibration (the
807 * one performed via ath5k_hw_phy_calibrate), that doesn't
808 * interrupt rx path.
809 *
810 * If we are in a noisy environment AGC calibration may time
811 * out.
812 */
813 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_AGCCTL,
814 AR5K_PHY_AGCCTL_CAL);
815
816 /* At the same time start I/Q calibration for QAM constellation
817 * -no need for CCK- */
818 ah->ah_calibration = false;
819 if (!(mode == AR5K_MODE_11B)) {
820 ah->ah_calibration = true;
821 AR5K_REG_WRITE_BITS(ah, AR5K_PHY_IQ,
822 AR5K_PHY_IQ_CAL_NUM_LOG_MAX, 15);
823 AR5K_REG_ENABLE_BITS(ah, AR5K_PHY_IQ,
824 AR5K_PHY_IQ_RUN);
825 }
826
827 /* Wait for gain calibration to finish (we check for I/Q calibration
828 * during ath5k_phy_calibrate) */
829 if (ath5k_hw_register_timeout(ah, AR5K_PHY_AGCCTL,
830 AR5K_PHY_AGCCTL_CAL, 0, false)) {
831 ATH5K_ERR(ah->ah_sc, "gain calibration timeout (%uMHz)\n",
832 channel->center_freq);
833 return -EAGAIN;
834 }
835
836 /*
837 * Start noise floor calibration
838 *
839 * If we run NF calibration before AGC, it always times out.
840 * Binary HAL starts NF and AGC calibration at the same time
841 * and only waits for AGC to finish. I believe that's wrong because
842 * during NF calibration, rx path is also routed to a detector, so if
843 * it doesn't finish we won't have RX.
844 *
845 * XXX: Find an interval that's OK for all cards...
846 */
847 ret = ath5k_hw_noise_floor_calibration(ah, channel->center_freq);
848 if (ret)
849 return ret;
850
851 /*
852 * Reset queues and start beacon timers at the end of the reset routine
853 */
854 for (i = 0; i < ah->ah_capabilities.cap_queues.q_tx_num; i++) {
855 /*No QCU on 5210*/
856 if (ah->ah_version != AR5K_AR5210)
857 AR5K_REG_WRITE_Q(ah, AR5K_QUEUE_QCUMASK(i), i);
858
859 ret = ath5k_hw_reset_tx_queue(ah, i);
860 if (ret) {
861 ATH5K_ERR(ah->ah_sc,
862 "failed to reset TX queue #%d\n", i);
863 return ret;
864 }
865 }
866
867 /* Pre-enable interrupts on 5211/5212*/
868 if (ah->ah_version != AR5K_AR5210)
869 ath5k_hw_set_imr(ah, AR5K_INT_RX | AR5K_INT_TX |
870 AR5K_INT_FATAL);
871
872 /*
873 * Set RF kill flags if supported by the device (read from the EEPROM)
874 * Disable gpio_intr for now since it results system hang.
875 * TODO: Handle this in ath5k_intr
876 */
877#if 0
878 if (AR5K_EEPROM_HDR_RFKILL(ah->ah_capabilities.cap_eeprom.ee_header)) {
879 ath5k_hw_set_gpio_input(ah, 0);
880 ah->ah_gpio[0] = ath5k_hw_get_gpio(ah, 0);
881 if (ah->ah_gpio[0] == 0)
882 ath5k_hw_set_gpio_intr(ah, 0, 1);
883 else
884 ath5k_hw_set_gpio_intr(ah, 0, 0);
885 }
886#endif
887
888 /*
889 * Set the 32MHz reference clock on 5212 phy clock sleep register
890 *
891 * TODO: Find out how to switch to external 32Khz clock to save power
892 */
893 if (ah->ah_version == AR5K_AR5212) {
894 ath5k_hw_reg_write(ah, AR5K_PHY_SCR_32MHZ, AR5K_PHY_SCR);
895 ath5k_hw_reg_write(ah, AR5K_PHY_SLMT_32MHZ, AR5K_PHY_SLMT);
896 ath5k_hw_reg_write(ah, AR5K_PHY_SCAL_32MHZ, AR5K_PHY_SCAL);
897 ath5k_hw_reg_write(ah, AR5K_PHY_SCLOCK_32MHZ, AR5K_PHY_SCLOCK);
898 ath5k_hw_reg_write(ah, AR5K_PHY_SDELAY_32MHZ, AR5K_PHY_SDELAY);
899 ath5k_hw_reg_write(ah, ah->ah_phy_spending, AR5K_PHY_SPENDING);
900
901 data = ath5k_hw_reg_read(ah, AR5K_USEC_5211) & 0xffffc07f ;
902 data |= (ah->ah_phy_spending == AR5K_PHY_SPENDING_18) ?
903 0x00000f80 : 0x00001380 ;
904 ath5k_hw_reg_write(ah, data, AR5K_USEC_5211);
905 data = 0;
906 }
907
908 if (ah->ah_version == AR5K_AR5212) {
909 ath5k_hw_reg_write(ah, 0x000100aa, 0x8118);
910 ath5k_hw_reg_write(ah, 0x00003210, 0x811c);
911 ath5k_hw_reg_write(ah, 0x00000052, 0x8108);
912 if (ah->ah_mac_srev >= AR5K_SREV_VER_AR2413)
913 ath5k_hw_reg_write(ah, 0x00000004, 0x8120);
914 }
915
916 /*
917 * Disable beacons and reset the register
918 */
919 AR5K_REG_DISABLE_BITS(ah, AR5K_BEACON, AR5K_BEACON_ENABLE |
920 AR5K_BEACON_RESET_TSF);
921
922 return 0;
923}
924
925#undef _ATH5K_RESET