ar5210_misc.c revision 185377
1185377Ssam/*
2185377Ssam * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
3185377Ssam * Copyright (c) 2002-2004 Atheros Communications, Inc.
4185377Ssam *
5185377Ssam * Permission to use, copy, modify, and/or distribute this software for any
6185377Ssam * purpose with or without fee is hereby granted, provided that the above
7185377Ssam * copyright notice and this permission notice appear in all copies.
8185377Ssam *
9185377Ssam * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10185377Ssam * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11185377Ssam * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12185377Ssam * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13185377Ssam * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14185377Ssam * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15185377Ssam * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16185377Ssam *
17185377Ssam * $Id: ar5210_misc.c,v 1.4 2008/11/10 04:08:02 sam Exp $
18185377Ssam */
19185377Ssam#include "opt_ah.h"
20185377Ssam
21185377Ssam#ifdef AH_SUPPORT_AR5210
22185377Ssam
23185377Ssam#include "ah.h"
24185377Ssam#include "ah_internal.h"
25185377Ssam
26185377Ssam#include "ar5210/ar5210.h"
27185377Ssam#include "ar5210/ar5210reg.h"
28185377Ssam#include "ar5210/ar5210phy.h"
29185377Ssam
30185377Ssam#define	AR_NUM_GPIO	6		/* 6 GPIO bits */
31185377Ssam#define	AR_GPIOD_MASK	0x2f		/* 6-bit mask */
32185377Ssam
33185377Ssamvoid
34185377Ssamar5210GetMacAddress(struct ath_hal *ah, uint8_t *mac)
35185377Ssam{
36185377Ssam	struct ath_hal_5210 *ahp = AH5210(ah);
37185377Ssam
38185377Ssam	OS_MEMCPY(mac, ahp->ah_macaddr, IEEE80211_ADDR_LEN);
39185377Ssam}
40185377Ssam
41185377SsamHAL_BOOL
42185377Ssamar5210SetMacAddress(struct ath_hal *ah, const uint8_t *mac)
43185377Ssam{
44185377Ssam	struct ath_hal_5210 *ahp = AH5210(ah);
45185377Ssam
46185377Ssam	OS_MEMCPY(ahp->ah_macaddr, mac, IEEE80211_ADDR_LEN);
47185377Ssam	return AH_TRUE;
48185377Ssam}
49185377Ssam
50185377Ssamvoid
51185377Ssamar5210GetBssIdMask(struct ath_hal *ah, uint8_t *mask)
52185377Ssam{
53185377Ssam	static const uint8_t ones[IEEE80211_ADDR_LEN] =
54185377Ssam		{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
55185377Ssam	OS_MEMCPY(mask, ones, IEEE80211_ADDR_LEN);
56185377Ssam}
57185377Ssam
58185377SsamHAL_BOOL
59185377Ssamar5210SetBssIdMask(struct ath_hal *ah, const uint8_t *mask)
60185377Ssam{
61185377Ssam	return AH_FALSE;
62185377Ssam}
63185377Ssam
64185377Ssam/*
65185377Ssam * Read 16 bits of data from the specified EEPROM offset.
66185377Ssam */
67185377SsamHAL_BOOL
68185377Ssamar5210EepromRead(struct ath_hal *ah, u_int off, uint16_t *data)
69185377Ssam{
70185377Ssam	(void) OS_REG_READ(ah, AR_EP_AIR(off));	/* activate read op */
71185377Ssam	if (!ath_hal_wait(ah, AR_EP_STA,
72185377Ssam	    AR_EP_STA_RDCMPLT | AR_EP_STA_RDERR, AR_EP_STA_RDCMPLT)) {
73185377Ssam		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: read failed for entry 0x%x\n",
74185377Ssam		    __func__, AR_EP_AIR(off));
75185377Ssam		return AH_FALSE;
76185377Ssam	}
77185377Ssam	*data = OS_REG_READ(ah, AR_EP_RDATA) & 0xffff;
78185377Ssam	return AH_TRUE;
79185377Ssam}
80185377Ssam
81185377Ssam/*
82185377Ssam * Return the wireless modes (a,b,g,t) supported by hardware.
83185377Ssam *
84185377Ssam * This value is what is actually supported by the hardware
85185377Ssam * and is unaffected by regulatory/country code settings.
86185377Ssam *
87185377Ssam */
88185377Ssamu_int
89185377Ssamar5210GetWirelessModes(struct ath_hal *ah)
90185377Ssam{
91185377Ssam	/* XXX could enable turbo mode but can't do all rates */
92185377Ssam	return HAL_MODE_11A;
93185377Ssam}
94185377Ssam
95185377Ssam/*
96185377Ssam * Called if RfKill is supported (according to EEPROM).  Set the interrupt and
97185377Ssam * GPIO values so the ISR and can disable RF on a switch signal
98185377Ssam */
99185377Ssamvoid
100185377Ssamar5210EnableRfKill(struct ath_hal *ah)
101185377Ssam{
102185377Ssam	uint16_t rfsilent = AH_PRIVATE(ah)->ah_rfsilent;
103185377Ssam	int select = MS(rfsilent, AR_EEPROM_RFSILENT_GPIO_SEL);
104185377Ssam	int polarity = MS(rfsilent, AR_EEPROM_RFSILENT_POLARITY);
105185377Ssam
106185377Ssam	/*
107185377Ssam	 * If radio disable switch connection to GPIO bit 0 is enabled
108185377Ssam	 * program GPIO interrupt.
109185377Ssam	 * If rfkill bit on eeprom is 1, setupeeprommap routine has already
110185377Ssam	 * verified that it is a later version of eeprom, it has a place for
111185377Ssam	 * rfkill bit and it is set to 1, indicating that GPIO bit 0 hardware
112185377Ssam	 * connection is present.
113185377Ssam	 */
114185377Ssam	ar5210Gpio0SetIntr(ah, select, (ar5210GpioGet(ah, select) == polarity));
115185377Ssam}
116185377Ssam
117185377Ssam/*
118185377Ssam * Configure GPIO Output lines
119185377Ssam */
120185377SsamHAL_BOOL
121185377Ssamar5210GpioCfgOutput(struct ath_hal *ah, uint32_t gpio)
122185377Ssam{
123185377Ssam	HALASSERT(gpio < AR_NUM_GPIO);
124185377Ssam
125185377Ssam	OS_REG_WRITE(ah, AR_GPIOCR,
126185377Ssam		  (OS_REG_READ(ah, AR_GPIOCR) &~ AR_GPIOCR_ALL(gpio))
127185377Ssam		| AR_GPIOCR_OUT1(gpio));
128185377Ssam
129185377Ssam	return AH_TRUE;
130185377Ssam}
131185377Ssam
132185377Ssam/*
133185377Ssam * Configure GPIO Input lines
134185377Ssam */
135185377SsamHAL_BOOL
136185377Ssamar5210GpioCfgInput(struct ath_hal *ah, uint32_t gpio)
137185377Ssam{
138185377Ssam	HALASSERT(gpio < AR_NUM_GPIO);
139185377Ssam
140185377Ssam	OS_REG_WRITE(ah, AR_GPIOCR,
141185377Ssam		  (OS_REG_READ(ah, AR_GPIOCR) &~ AR_GPIOCR_ALL(gpio))
142185377Ssam		| AR_GPIOCR_IN(gpio));
143185377Ssam
144185377Ssam	return AH_TRUE;
145185377Ssam}
146185377Ssam
147185377Ssam/*
148185377Ssam * Once configured for I/O - set output lines
149185377Ssam */
150185377SsamHAL_BOOL
151185377Ssamar5210GpioSet(struct ath_hal *ah, uint32_t gpio, uint32_t val)
152185377Ssam{
153185377Ssam	uint32_t reg;
154185377Ssam
155185377Ssam	HALASSERT(gpio < AR_NUM_GPIO);
156185377Ssam
157185377Ssam	reg =  OS_REG_READ(ah, AR_GPIODO);
158185377Ssam	reg &= ~(1 << gpio);
159185377Ssam	reg |= (val&1) << gpio;
160185377Ssam
161185377Ssam	OS_REG_WRITE(ah, AR_GPIODO, reg);
162185377Ssam	return AH_TRUE;
163185377Ssam}
164185377Ssam
165185377Ssam/*
166185377Ssam * Once configured for I/O - get input lines
167185377Ssam */
168185377Ssamuint32_t
169185377Ssamar5210GpioGet(struct ath_hal *ah, uint32_t gpio)
170185377Ssam{
171185377Ssam	if (gpio < AR_NUM_GPIO) {
172185377Ssam		uint32_t val = OS_REG_READ(ah, AR_GPIODI);
173185377Ssam		val = ((val & AR_GPIOD_MASK) >> gpio) & 0x1;
174185377Ssam		return val;
175185377Ssam	} else  {
176185377Ssam		return 0xffffffff;
177185377Ssam	}
178185377Ssam}
179185377Ssam
180185377Ssam/*
181185377Ssam * Set the GPIO 0 Interrupt
182185377Ssam */
183185377Ssamvoid
184185377Ssamar5210Gpio0SetIntr(struct ath_hal *ah, u_int gpio, uint32_t ilevel)
185185377Ssam{
186185377Ssam	uint32_t val = OS_REG_READ(ah, AR_GPIOCR);
187185377Ssam
188185377Ssam	/* Clear the bits that we will modify. */
189185377Ssam	val &= ~(AR_GPIOCR_INT_SEL(gpio) | AR_GPIOCR_INT_SELH | AR_GPIOCR_INT_ENA |
190185377Ssam			AR_GPIOCR_ALL(gpio));
191185377Ssam
192185377Ssam	val |= AR_GPIOCR_INT_SEL(gpio) | AR_GPIOCR_INT_ENA;
193185377Ssam	if (ilevel)
194185377Ssam		val |= AR_GPIOCR_INT_SELH;
195185377Ssam
196185377Ssam	/* Don't need to change anything for low level interrupt. */
197185377Ssam	OS_REG_WRITE(ah, AR_GPIOCR, val);
198185377Ssam
199185377Ssam	/* Change the interrupt mask. */
200185377Ssam	ar5210SetInterrupts(ah, AH5210(ah)->ah_maskReg | HAL_INT_GPIO);
201185377Ssam}
202185377Ssam
203185377Ssam/*
204185377Ssam * Change the LED blinking pattern to correspond to the connectivity
205185377Ssam */
206185377Ssamvoid
207185377Ssamar5210SetLedState(struct ath_hal *ah, HAL_LED_STATE state)
208185377Ssam{
209185377Ssam	uint32_t val;
210185377Ssam
211185377Ssam	val = OS_REG_READ(ah, AR_PCICFG);
212185377Ssam	switch (state) {
213185377Ssam	case HAL_LED_INIT:
214185377Ssam		val &= ~(AR_PCICFG_LED_PEND | AR_PCICFG_LED_ACT);
215185377Ssam		break;
216185377Ssam	case HAL_LED_RUN:
217185377Ssam		/* normal blink when connected */
218185377Ssam		val &= ~AR_PCICFG_LED_PEND;
219185377Ssam		val |= AR_PCICFG_LED_ACT;
220185377Ssam		break;
221185377Ssam	default:
222185377Ssam		val |= AR_PCICFG_LED_PEND;
223185377Ssam		val &= ~AR_PCICFG_LED_ACT;
224185377Ssam		break;
225185377Ssam	}
226185377Ssam	OS_REG_WRITE(ah, AR_PCICFG, val);
227185377Ssam}
228185377Ssam
229185377Ssam/*
230185377Ssam * Return 1 or 2 for the corresponding antenna that is in use
231185377Ssam */
232185377Ssamu_int
233185377Ssamar5210GetDefAntenna(struct ath_hal *ah)
234185377Ssam{
235185377Ssam	uint32_t val = OS_REG_READ(ah, AR_STA_ID1);
236185377Ssam	return (val & AR_STA_ID1_DEFAULT_ANTENNA ?  2 : 1);
237185377Ssam}
238185377Ssam
239185377Ssamvoid
240185377Ssamar5210SetDefAntenna(struct ath_hal *ah, u_int antenna)
241185377Ssam{
242185377Ssam	uint32_t val = OS_REG_READ(ah, AR_STA_ID1);
243185377Ssam
244185377Ssam	if (antenna != (val & AR_STA_ID1_DEFAULT_ANTENNA ?  2 : 1)) {
245185377Ssam		/*
246185377Ssam		 * Antenna change requested, force a toggle of the default.
247185377Ssam		 */
248185377Ssam		OS_REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_DEFAULT_ANTENNA);
249185377Ssam	}
250185377Ssam}
251185377Ssam
252185377SsamHAL_ANT_SETTING
253185377Ssamar5210GetAntennaSwitch(struct ath_hal *ah)
254185377Ssam{
255185377Ssam	return HAL_ANT_VARIABLE;
256185377Ssam}
257185377Ssam
258185377SsamHAL_BOOL
259185377Ssamar5210SetAntennaSwitch(struct ath_hal *ah, HAL_ANT_SETTING settings)
260185377Ssam{
261185377Ssam	/* XXX not sure how to fix antenna */
262185377Ssam	return (settings == HAL_ANT_VARIABLE);
263185377Ssam}
264185377Ssam
265185377Ssam/*
266185377Ssam * Change association related fields programmed into the hardware.
267185377Ssam * Writing a valid BSSID to the hardware effectively enables the hardware
268185377Ssam * to synchronize its TSF to the correct beacons and receive frames coming
269185377Ssam * from that BSSID. It is called by the SME JOIN operation.
270185377Ssam */
271185377Ssamvoid
272185377Ssamar5210WriteAssocid(struct ath_hal *ah, const uint8_t *bssid, uint16_t assocId)
273185377Ssam{
274185377Ssam	struct ath_hal_5210 *ahp = AH5210(ah);
275185377Ssam
276185377Ssam	/* XXX save bssid for possible re-use on reset */
277185377Ssam	OS_MEMCPY(ahp->ah_bssid, bssid, IEEE80211_ADDR_LEN);
278185377Ssam	OS_REG_WRITE(ah, AR_BSS_ID0, LE_READ_4(ahp->ah_bssid));
279185377Ssam	OS_REG_WRITE(ah, AR_BSS_ID1, LE_READ_2(ahp->ah_bssid+4) |
280185377Ssam				     ((assocId & 0x3fff)<<AR_BSS_ID1_AID_S));
281185377Ssam	if (assocId == 0)
282185377Ssam		OS_REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_NO_PSPOLL);
283185377Ssam	else
284185377Ssam		OS_REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_NO_PSPOLL);
285185377Ssam}
286185377Ssam
287185377Ssam/*
288185377Ssam * Get the current hardware tsf for stamlme.
289185377Ssam */
290185377Ssamuint64_t
291185377Ssamar5210GetTsf64(struct ath_hal *ah)
292185377Ssam{
293185377Ssam	uint32_t low1, low2, u32;
294185377Ssam
295185377Ssam	/* sync multi-word read */
296185377Ssam	low1 = OS_REG_READ(ah, AR_TSF_L32);
297185377Ssam	u32 = OS_REG_READ(ah, AR_TSF_U32);
298185377Ssam	low2 = OS_REG_READ(ah, AR_TSF_L32);
299185377Ssam	if (low2 < low1) {	/* roll over */
300185377Ssam		/*
301185377Ssam		 * If we are not preempted this will work.  If we are
302185377Ssam		 * then we re-reading AR_TSF_U32 does no good as the
303185377Ssam		 * low bits will be meaningless.  Likewise reading
304185377Ssam		 * L32, U32, U32, then comparing the last two reads
305185377Ssam		 * to check for rollover
306185377Ssam		 * doesn't help if preempted--so we take this approach
307185377Ssam		 * as it costs one less PCI read which can be noticeable
308185377Ssam		 * when doing things like timestamping packets in
309185377Ssam		 * monitor mode.
310185377Ssam		 */
311185377Ssam		u32++;
312185377Ssam	}
313185377Ssam	return (((uint64_t) u32) << 32) | ((uint64_t) low2);
314185377Ssam}
315185377Ssam
316185377Ssam/*
317185377Ssam * Get the current hardware tsf for stamlme.
318185377Ssam */
319185377Ssamuint32_t
320185377Ssamar5210GetTsf32(struct ath_hal *ah)
321185377Ssam{
322185377Ssam	return OS_REG_READ(ah, AR_TSF_L32);
323185377Ssam}
324185377Ssam
325185377Ssam/*
326185377Ssam * Reset the current hardware tsf for stamlme
327185377Ssam */
328185377Ssamvoid
329185377Ssamar5210ResetTsf(struct ath_hal *ah)
330185377Ssam{
331185377Ssam	uint32_t val = OS_REG_READ(ah, AR_BEACON);
332185377Ssam
333185377Ssam	OS_REG_WRITE(ah, AR_BEACON, val | AR_BEACON_RESET_TSF);
334185377Ssam}
335185377Ssam
336185377Ssam/*
337185377Ssam * Grab a semi-random value from hardware registers - may not
338185377Ssam * change often
339185377Ssam */
340185377Ssamuint32_t
341185377Ssamar5210GetRandomSeed(struct ath_hal *ah)
342185377Ssam{
343185377Ssam	uint32_t nf;
344185377Ssam
345185377Ssam	nf = (OS_REG_READ(ah, AR_PHY_BASE + (25 << 2)) >> 19) & 0x1ff;
346185377Ssam	if (nf & 0x100)
347185377Ssam		nf = 0 - ((nf ^ 0x1ff) + 1);
348185377Ssam	return (OS_REG_READ(ah, AR_TSF_U32) ^
349185377Ssam		OS_REG_READ(ah, AR_TSF_L32) ^ nf);
350185377Ssam}
351185377Ssam
352185377Ssam/*
353185377Ssam * Detect if our card is present
354185377Ssam */
355185377SsamHAL_BOOL
356185377Ssamar5210DetectCardPresent(struct ath_hal *ah)
357185377Ssam{
358185377Ssam	/*
359185377Ssam	 * Read the Silicon Revision register and compare that
360185377Ssam	 * to what we read at attach time.  If the same, we say
361185377Ssam	 * a card/device is present.
362185377Ssam	 */
363185377Ssam	return (AH_PRIVATE(ah)->ah_macRev == (OS_REG_READ(ah, AR_SREV) & 0xff));
364185377Ssam}
365185377Ssam
366185377Ssam/*
367185377Ssam * Update MIB Counters
368185377Ssam */
369185377Ssamvoid
370185377Ssamar5210UpdateMibCounters(struct ath_hal *ah, HAL_MIB_STATS *stats)
371185377Ssam{
372185377Ssam	stats->ackrcv_bad += OS_REG_READ(ah, AR_ACK_FAIL);
373185377Ssam	stats->rts_bad	  += OS_REG_READ(ah, AR_RTS_FAIL);
374185377Ssam	stats->fcs_bad	  += OS_REG_READ(ah, AR_FCS_FAIL);
375185377Ssam	stats->rts_good	  += OS_REG_READ(ah, AR_RTS_OK);
376185377Ssam	stats->beacons	  += OS_REG_READ(ah, AR_BEACON_CNT);
377185377Ssam}
378185377Ssam
379185377SsamHAL_BOOL
380185377Ssamar5210SetSifsTime(struct ath_hal *ah, u_int us)
381185377Ssam{
382185377Ssam	struct ath_hal_5210 *ahp = AH5210(ah);
383185377Ssam
384185377Ssam	if (us > ath_hal_mac_usec(ah, 0x7ff)) {
385185377Ssam		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad SIFS time %u\n",
386185377Ssam		    __func__, us);
387185377Ssam		ahp->ah_sifstime = (u_int) -1;	/* restore default handling */
388185377Ssam		return AH_FALSE;
389185377Ssam	} else {
390185377Ssam		/* convert to system clocks */
391185377Ssam		OS_REG_RMW_FIELD(ah, AR_IFS0, AR_IFS0_SIFS,
392185377Ssam		    ath_hal_mac_clks(ah, us));
393185377Ssam		ahp->ah_sifstime = us;
394185377Ssam		return AH_TRUE;
395185377Ssam	}
396185377Ssam}
397185377Ssam
398185377Ssamu_int
399185377Ssamar5210GetSifsTime(struct ath_hal *ah)
400185377Ssam{
401185377Ssam	u_int clks = OS_REG_READ(ah, AR_IFS0) & 0x7ff;
402185377Ssam	return ath_hal_mac_usec(ah, clks);	/* convert from system clocks */
403185377Ssam}
404185377Ssam
405185377SsamHAL_BOOL
406185377Ssamar5210SetSlotTime(struct ath_hal *ah, u_int us)
407185377Ssam{
408185377Ssam	struct ath_hal_5210 *ahp = AH5210(ah);
409185377Ssam
410185377Ssam	if (us < HAL_SLOT_TIME_9 || us > ath_hal_mac_usec(ah, 0xffff)) {
411185377Ssam		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad slot time %u\n",
412185377Ssam		    __func__, us);
413185377Ssam		ahp->ah_slottime = (u_int) -1;	/* restore default handling */
414185377Ssam		return AH_FALSE;
415185377Ssam	} else {
416185377Ssam		/* convert to system clocks */
417185377Ssam		OS_REG_WRITE(ah, AR_SLOT_TIME, ath_hal_mac_clks(ah, us));
418185377Ssam		ahp->ah_slottime = us;
419185377Ssam		return AH_TRUE;
420185377Ssam	}
421185377Ssam}
422185377Ssam
423185377Ssamu_int
424185377Ssamar5210GetSlotTime(struct ath_hal *ah)
425185377Ssam{
426185377Ssam	u_int clks = OS_REG_READ(ah, AR_SLOT_TIME) & 0xffff;
427185377Ssam	return ath_hal_mac_usec(ah, clks);	/* convert from system clocks */
428185377Ssam}
429185377Ssam
430185377SsamHAL_BOOL
431185377Ssamar5210SetAckTimeout(struct ath_hal *ah, u_int us)
432185377Ssam{
433185377Ssam	struct ath_hal_5210 *ahp = AH5210(ah);
434185377Ssam
435185377Ssam	if (us > ath_hal_mac_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) {
436185377Ssam		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad ack timeout %u\n",
437185377Ssam		    __func__, us);
438185377Ssam		ahp->ah_acktimeout = (u_int) -1; /* restore default handling */
439185377Ssam		return AH_FALSE;
440185377Ssam	} else {
441185377Ssam		/* convert to system clocks */
442185377Ssam		OS_REG_RMW_FIELD(ah, AR_TIME_OUT,
443185377Ssam			AR_TIME_OUT_ACK, ath_hal_mac_clks(ah, us));
444185377Ssam		ahp->ah_acktimeout = us;
445185377Ssam		return AH_TRUE;
446185377Ssam	}
447185377Ssam}
448185377Ssam
449185377Ssamu_int
450185377Ssamar5210GetAckTimeout(struct ath_hal *ah)
451185377Ssam{
452185377Ssam	u_int clks = MS(OS_REG_READ(ah, AR_TIME_OUT), AR_TIME_OUT_ACK);
453185377Ssam	return ath_hal_mac_usec(ah, clks);	/* convert from system clocks */
454185377Ssam}
455185377Ssam
456185377Ssamu_int
457185377Ssamar5210GetAckCTSRate(struct ath_hal *ah)
458185377Ssam{
459185377Ssam	return ((AH5210(ah)->ah_staId1Defaults & AR_STA_ID1_ACKCTS_6MB) == 0);
460185377Ssam}
461185377Ssam
462185377SsamHAL_BOOL
463185377Ssamar5210SetAckCTSRate(struct ath_hal *ah, u_int high)
464185377Ssam{
465185377Ssam	struct ath_hal_5210 *ahp = AH5210(ah);
466185377Ssam
467185377Ssam	if (high) {
468185377Ssam		OS_REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_ACKCTS_6MB);
469185377Ssam		ahp->ah_staId1Defaults &= ~AR_STA_ID1_ACKCTS_6MB;
470185377Ssam	} else {
471185377Ssam		OS_REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_ACKCTS_6MB);
472185377Ssam		ahp->ah_staId1Defaults |= AR_STA_ID1_ACKCTS_6MB;
473185377Ssam	}
474185377Ssam	return AH_TRUE;
475185377Ssam}
476185377Ssam
477185377SsamHAL_BOOL
478185377Ssamar5210SetCTSTimeout(struct ath_hal *ah, u_int us)
479185377Ssam{
480185377Ssam	struct ath_hal_5210 *ahp = AH5210(ah);
481185377Ssam
482185377Ssam	if (us > ath_hal_mac_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) {
483185377Ssam		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad cts timeout %u\n",
484185377Ssam		    __func__, us);
485185377Ssam		ahp->ah_ctstimeout = (u_int) -1; /* restore default handling */
486185377Ssam		return AH_FALSE;
487185377Ssam	} else {
488185377Ssam		/* convert to system clocks */
489185377Ssam		OS_REG_RMW_FIELD(ah, AR_TIME_OUT,
490185377Ssam			AR_TIME_OUT_CTS, ath_hal_mac_clks(ah, us));
491185377Ssam		ahp->ah_ctstimeout = us;
492185377Ssam		return AH_TRUE;
493185377Ssam	}
494185377Ssam}
495185377Ssam
496185377Ssamu_int
497185377Ssamar5210GetCTSTimeout(struct ath_hal *ah)
498185377Ssam{
499185377Ssam	u_int clks = MS(OS_REG_READ(ah, AR_TIME_OUT), AR_TIME_OUT_CTS);
500185377Ssam	return ath_hal_mac_usec(ah, clks);	/* convert from system clocks */
501185377Ssam}
502185377Ssam
503185377SsamHAL_BOOL
504185377Ssamar5210SetDecompMask(struct ath_hal *ah, uint16_t keyidx, int en)
505185377Ssam{
506185377Ssam	/* nothing to do */
507185377Ssam        return AH_TRUE;
508185377Ssam}
509185377Ssam
510185377Ssamvoid
511185377Ssamar5210SetCoverageClass(struct ath_hal *ah, uint8_t coverageclass, int now)
512185377Ssam{
513185377Ssam}
514185377Ssam
515185377Ssam/*
516185377Ssam * Control Adaptive Noise Immunity Parameters
517185377Ssam */
518185377SsamHAL_BOOL
519185377Ssamar5210AniControl(struct ath_hal *ah, HAL_ANI_CMD cmd, int param)
520185377Ssam{
521185377Ssam	return AH_FALSE;
522185377Ssam}
523185377Ssam
524185377Ssamvoid
525185377Ssamar5210AniPoll(struct ath_hal *ah, const HAL_NODE_STATS *stats, HAL_CHANNEL *chan)
526185377Ssam{
527185377Ssam}
528185377Ssam
529185377Ssamvoid
530185377Ssamar5210MibEvent(struct ath_hal *ah, const HAL_NODE_STATS *stats)
531185377Ssam{
532185377Ssam}
533185377Ssam
534185377Ssam#define	AR_DIAG_SW_DIS_CRYPTO	(AR_DIAG_SW_DIS_ENC | AR_DIAG_SW_DIS_DEC)
535185377Ssam
536185377SsamHAL_STATUS
537185377Ssamar5210GetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
538185377Ssam	uint32_t capability, uint32_t *result)
539185377Ssam{
540185377Ssam
541185377Ssam	switch (type) {
542185377Ssam	case HAL_CAP_CIPHER:		/* cipher handled in hardware */
543185377Ssam		return (capability == HAL_CIPHER_WEP ? HAL_OK : HAL_ENOTSUPP);
544185377Ssam	default:
545185377Ssam		return ath_hal_getcapability(ah, type, capability, result);
546185377Ssam	}
547185377Ssam}
548185377Ssam
549185377SsamHAL_BOOL
550185377Ssamar5210SetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
551185377Ssam	uint32_t capability, uint32_t setting, HAL_STATUS *status)
552185377Ssam{
553185377Ssam
554185377Ssam	switch (type) {
555185377Ssam	case HAL_CAP_DIAG:		/* hardware diagnostic support */
556185377Ssam		/*
557185377Ssam		 * NB: could split this up into virtual capabilities,
558185377Ssam		 *     (e.g. 1 => ACK, 2 => CTS, etc.) but it hardly
559185377Ssam		 *     seems worth the additional complexity.
560185377Ssam		 */
561185377Ssam#ifdef AH_DEBUG
562185377Ssam		AH_PRIVATE(ah)->ah_diagreg = setting;
563185377Ssam#else
564185377Ssam		AH_PRIVATE(ah)->ah_diagreg = setting & 0x6;	/* ACK+CTS */
565185377Ssam#endif
566185377Ssam		OS_REG_WRITE(ah, AR_DIAG_SW, AH_PRIVATE(ah)->ah_diagreg);
567185377Ssam		return AH_TRUE;
568185377Ssam	case HAL_CAP_RXORN_FATAL:	/* HAL_INT_RXORN treated as fatal  */
569185377Ssam		return AH_FALSE;	/* NB: disallow */
570185377Ssam	default:
571185377Ssam		return ath_hal_setcapability(ah, type, capability,
572185377Ssam			setting, status);
573185377Ssam	}
574185377Ssam}
575185377Ssam
576185377SsamHAL_BOOL
577185377Ssamar5210GetDiagState(struct ath_hal *ah, int request,
578185377Ssam	const void *args, uint32_t argsize,
579185377Ssam	void **result, uint32_t *resultsize)
580185377Ssam{
581185377Ssam#ifdef AH_PRIVATE_DIAG
582185377Ssam	uint32_t pcicfg;
583185377Ssam	HAL_BOOL ok;
584185377Ssam
585185377Ssam	switch (request) {
586185377Ssam	case HAL_DIAG_EEPROM:
587185377Ssam		/* XXX */
588185377Ssam		break;
589185377Ssam	case HAL_DIAG_EEREAD:
590185377Ssam		if (argsize != sizeof(uint16_t))
591185377Ssam			return AH_FALSE;
592185377Ssam		pcicfg = OS_REG_READ(ah, AR_PCICFG);
593185377Ssam		OS_REG_WRITE(ah, AR_PCICFG, pcicfg | AR_PCICFG_EEPROMSEL);
594185377Ssam		ok = ath_hal_eepromRead(ah, *(const uint16_t *)args, *result);
595185377Ssam		OS_REG_WRITE(ah, AR_PCICFG, pcicfg);
596185377Ssam		if (ok)
597185377Ssam			*resultsize = sizeof(uint16_t);
598185377Ssam		return ok;
599185377Ssam	}
600185377Ssam#endif
601185377Ssam	return ath_hal_getdiagstate(ah, request,
602185377Ssam		args, argsize, result, resultsize);
603185377Ssam}
604185377Ssam#endif /* AH_SUPPORT_AR5210 */
605