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
24FILE_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 */
40static 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 */
85static 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 */
142static 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 */
164static 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 */
206static 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 */
248int 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 */
290int 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
422static 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 */
443static 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
545static 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 */
698int 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
1177