1185377Ssam/*
2187831Ssam * Copyright (c) 2002-2009 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 *
17187831Ssam * $FreeBSD$
18185377Ssam */
19185377Ssam#include "opt_ah.h"
20185377Ssam
21185377Ssam#include "ah.h"
22185377Ssam#include "ah_internal.h"
23185406Ssam#include "ah_devid.h"
24185377Ssam
25185377Ssam#include "ar5210/ar5210.h"
26185377Ssam#include "ar5210/ar5210reg.h"
27185377Ssam#include "ar5210/ar5210phy.h"
28185377Ssam
29185380Ssam#include "ah_eeprom_v1.h"
30185380Ssam
31185377Ssamstatic	HAL_BOOL ar5210GetChannelEdges(struct ath_hal *,
32185377Ssam		uint16_t flags, uint16_t *low, uint16_t *high);
33185377Ssamstatic	HAL_BOOL ar5210GetChipPowerLimits(struct ath_hal *ah,
34187831Ssam		struct ieee80211_channel *chan);
35185377Ssam
36235972Sadrianstatic void ar5210ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore,
37235972Sadrian		HAL_BOOL power_on);
38188979Ssamstatic void ar5210DisablePCIE(struct ath_hal *ah);
39188979Ssam
40185377Ssamstatic const struct ath_hal_private ar5210hal = {{
41185377Ssam	.ah_magic			= AR5210_MAGIC,
42185377Ssam
43185377Ssam	.ah_getRateTable		= ar5210GetRateTable,
44185377Ssam	.ah_detach			= ar5210Detach,
45185377Ssam
46185377Ssam	/* Reset Functions */
47185377Ssam	.ah_reset			= ar5210Reset,
48185377Ssam	.ah_phyDisable			= ar5210PhyDisable,
49185377Ssam	.ah_disable			= ar5210Disable,
50188979Ssam	.ah_configPCIE			= ar5210ConfigPCIE,
51188979Ssam	.ah_disablePCIE			= ar5210DisablePCIE,
52185377Ssam	.ah_setPCUConfig		= ar5210SetPCUConfig,
53185377Ssam	.ah_perCalibration		= ar5210PerCalibration,
54185380Ssam	.ah_perCalibrationN		= ar5210PerCalibrationN,
55185380Ssam	.ah_resetCalValid		= ar5210ResetCalValid,
56185377Ssam	.ah_setTxPowerLimit		= ar5210SetTxPowerLimit,
57185377Ssam	.ah_getChanNoise		= ath_hal_getChanNoise,
58185377Ssam
59185377Ssam	/* Transmit functions */
60185377Ssam	.ah_updateTxTrigLevel		= ar5210UpdateTxTrigLevel,
61185377Ssam	.ah_setupTxQueue		= ar5210SetupTxQueue,
62185377Ssam	.ah_setTxQueueProps             = ar5210SetTxQueueProps,
63185377Ssam	.ah_getTxQueueProps             = ar5210GetTxQueueProps,
64185377Ssam	.ah_releaseTxQueue		= ar5210ReleaseTxQueue,
65185377Ssam	.ah_resetTxQueue		= ar5210ResetTxQueue,
66185377Ssam	.ah_getTxDP			= ar5210GetTxDP,
67185377Ssam	.ah_setTxDP			= ar5210SetTxDP,
68185377Ssam	.ah_numTxPending		= ar5210NumTxPending,
69185377Ssam	.ah_startTxDma			= ar5210StartTxDma,
70185377Ssam	.ah_stopTxDma			= ar5210StopTxDma,
71185377Ssam	.ah_setupTxDesc			= ar5210SetupTxDesc,
72185377Ssam	.ah_setupXTxDesc		= ar5210SetupXTxDesc,
73185377Ssam	.ah_fillTxDesc			= ar5210FillTxDesc,
74185377Ssam	.ah_procTxDesc			= ar5210ProcTxDesc,
75185377Ssam	.ah_getTxIntrQueue		= ar5210GetTxIntrQueue,
76185377Ssam	.ah_reqTxIntrDesc 		= ar5210IntrReqTxDesc,
77217621Sadrian	.ah_getTxCompletionRates	= ar5210GetTxCompletionRates,
78238607Sadrian	.ah_setTxDescLink		= ar5210SetTxDescLink,
79238607Sadrian	.ah_getTxDescLink		= ar5210GetTxDescLink,
80238607Sadrian	.ah_getTxDescLinkPtr		= ar5210GetTxDescLinkPtr,
81185377Ssam
82185377Ssam	/* RX Functions */
83185377Ssam	.ah_getRxDP			= ar5210GetRxDP,
84185377Ssam	.ah_setRxDP			= ar5210SetRxDP,
85185377Ssam	.ah_enableReceive		= ar5210EnableReceive,
86185377Ssam	.ah_stopDmaReceive		= ar5210StopDmaReceive,
87185377Ssam	.ah_startPcuReceive		= ar5210StartPcuReceive,
88185377Ssam	.ah_stopPcuReceive		= ar5210StopPcuReceive,
89185377Ssam	.ah_setMulticastFilter		= ar5210SetMulticastFilter,
90185377Ssam	.ah_setMulticastFilterIndex	= ar5210SetMulticastFilterIndex,
91185377Ssam	.ah_clrMulticastFilterIndex	= ar5210ClrMulticastFilterIndex,
92185377Ssam	.ah_getRxFilter			= ar5210GetRxFilter,
93185377Ssam	.ah_setRxFilter			= ar5210SetRxFilter,
94185377Ssam	.ah_setupRxDesc			= ar5210SetupRxDesc,
95185377Ssam	.ah_procRxDesc			= ar5210ProcRxDesc,
96217684Sadrian	.ah_rxMonitor			= ar5210RxMonitor,
97217684Sadrian	.ah_aniPoll			= ar5210AniPoll,
98185377Ssam	.ah_procMibEvent		= ar5210MibEvent,
99185377Ssam
100185377Ssam	/* Misc Functions */
101185377Ssam	.ah_getCapability		= ar5210GetCapability,
102185377Ssam	.ah_setCapability		= ar5210SetCapability,
103185377Ssam	.ah_getDiagState		= ar5210GetDiagState,
104185377Ssam	.ah_getMacAddress		= ar5210GetMacAddress,
105185377Ssam	.ah_setMacAddress		= ar5210SetMacAddress,
106185377Ssam	.ah_getBssIdMask		= ar5210GetBssIdMask,
107185377Ssam	.ah_setBssIdMask		= ar5210SetBssIdMask,
108185380Ssam	.ah_setRegulatoryDomain		= ar5210SetRegulatoryDomain,
109185377Ssam	.ah_setLedState			= ar5210SetLedState,
110185377Ssam	.ah_writeAssocid		= ar5210WriteAssocid,
111185377Ssam	.ah_gpioCfgInput		= ar5210GpioCfgInput,
112185377Ssam	.ah_gpioCfgOutput		= ar5210GpioCfgOutput,
113185377Ssam	.ah_gpioGet			= ar5210GpioGet,
114185377Ssam	.ah_gpioSet			= ar5210GpioSet,
115185377Ssam	.ah_gpioSetIntr			= ar5210Gpio0SetIntr,
116185377Ssam	.ah_getTsf32			= ar5210GetTsf32,
117185377Ssam	.ah_getTsf64			= ar5210GetTsf64,
118185377Ssam	.ah_resetTsf			= ar5210ResetTsf,
119185377Ssam	.ah_detectCardPresent		= ar5210DetectCardPresent,
120185377Ssam	.ah_updateMibCounters		= ar5210UpdateMibCounters,
121185377Ssam	.ah_getRfGain			= ar5210GetRfgain,
122185377Ssam	.ah_getDefAntenna		= ar5210GetDefAntenna,
123185377Ssam	.ah_setDefAntenna		= ar5210SetDefAntenna,
124185377Ssam	.ah_getAntennaSwitch		= ar5210GetAntennaSwitch,
125185377Ssam	.ah_setAntennaSwitch		= ar5210SetAntennaSwitch,
126185377Ssam	.ah_setSifsTime			= ar5210SetSifsTime,
127185377Ssam	.ah_getSifsTime			= ar5210GetSifsTime,
128185377Ssam	.ah_setSlotTime			= ar5210SetSlotTime,
129185377Ssam	.ah_getSlotTime			= ar5210GetSlotTime,
130185377Ssam	.ah_setAckTimeout		= ar5210SetAckTimeout,
131185377Ssam	.ah_getAckTimeout		= ar5210GetAckTimeout,
132185377Ssam	.ah_setAckCTSRate		= ar5210SetAckCTSRate,
133185377Ssam	.ah_getAckCTSRate		= ar5210GetAckCTSRate,
134185377Ssam	.ah_setCTSTimeout		= ar5210SetCTSTimeout,
135185377Ssam	.ah_getCTSTimeout		= ar5210GetCTSTimeout,
136234873Sadrian	.ah_setDecompMask		= ar5210SetDecompMask,
137234873Sadrian	.ah_setCoverageClass		= ar5210SetCoverageClass,
138234873Sadrian	.ah_get11nExtBusy		= ar5210Get11nExtBusy,
139234873Sadrian	.ah_getMibCycleCounts		= ar5210GetMibCycleCounts,
140247286Sadrian	.ah_setChainMasks		= ar5210SetChainMasks,
141235206Sadrian	.ah_enableDfs			= ar5210EnableDfs,
142235206Sadrian	.ah_getDfsThresh		= ar5210GetDfsThresh,
143235206Sadrian	/* XXX procRadarEvent */
144235206Sadrian	/* XXX isFastClockEnabled */
145185377Ssam
146185377Ssam	/* Key Cache Functions */
147185377Ssam	.ah_getKeyCacheSize		= ar5210GetKeyCacheSize,
148185377Ssam	.ah_resetKeyCacheEntry		= ar5210ResetKeyCacheEntry,
149185377Ssam	.ah_isKeyCacheEntryValid	= ar5210IsKeyCacheEntryValid,
150185377Ssam	.ah_setKeyCacheEntry		= ar5210SetKeyCacheEntry,
151185377Ssam	.ah_setKeyCacheEntryMac		= ar5210SetKeyCacheEntryMac,
152185377Ssam
153185377Ssam	/* Power Management Functions */
154185377Ssam	.ah_setPowerMode		= ar5210SetPowerMode,
155185377Ssam	.ah_getPowerMode		= ar5210GetPowerMode,
156185377Ssam
157185377Ssam	/* Beacon Functions */
158185377Ssam	.ah_setBeaconTimers		= ar5210SetBeaconTimers,
159185377Ssam	.ah_beaconInit			= ar5210BeaconInit,
160185377Ssam	.ah_setStationBeaconTimers	= ar5210SetStaBeaconTimers,
161185377Ssam	.ah_resetStationBeaconTimers	= ar5210ResetStaBeaconTimers,
162225444Sadrian	.ah_getNextTBTT			= ar5210GetNextTBTT,
163185377Ssam
164185377Ssam	/* Interrupt Functions */
165185377Ssam	.ah_isInterruptPending		= ar5210IsInterruptPending,
166185377Ssam	.ah_getPendingInterrupts	= ar5210GetPendingInterrupts,
167185377Ssam	.ah_getInterrupts		= ar5210GetInterrupts,
168185377Ssam	.ah_setInterrupts		= ar5210SetInterrupts },
169185377Ssam
170185377Ssam	.ah_getChannelEdges		= ar5210GetChannelEdges,
171185377Ssam	.ah_getWirelessModes		= ar5210GetWirelessModes,
172185377Ssam	.ah_eepromRead			= ar5210EepromRead,
173185377Ssam#ifdef AH_SUPPORT_WRITE_EEPROM
174185377Ssam	.ah_eepromWrite			= ar5210EepromWrite,
175185377Ssam#endif
176185377Ssam	.ah_getChipPowerLimits		= ar5210GetChipPowerLimits,
177185377Ssam};
178185377Ssam
179185377Ssamstatic HAL_BOOL ar5210FillCapabilityInfo(struct ath_hal *ah);
180185377Ssam
181185377Ssam/*
182185377Ssam * Attach for an AR5210 part.
183185377Ssam */
184185406Ssamstatic struct ath_hal *
185185406Ssamar5210Attach(uint16_t devid, HAL_SOFTC sc, HAL_BUS_TAG st, HAL_BUS_HANDLE sh,
186217624Sadrian	uint16_t *eepromdata, HAL_STATUS *status)
187185377Ssam{
188185377Ssam#define	N(a)	(sizeof(a)/sizeof(a[0]))
189185377Ssam	struct ath_hal_5210 *ahp;
190185377Ssam	struct ath_hal *ah;
191185380Ssam	uint32_t revid, pcicfg;
192185380Ssam	uint16_t eeval;
193185377Ssam	HAL_STATUS ecode;
194185380Ssam	int i;
195185377Ssam
196225883Sadrian	HALDEBUG(AH_NULL, HAL_DEBUG_ATTACH,
197185377Ssam	    "%s: devid 0x%x sc %p st %p sh %p\n", __func__, devid,
198185377Ssam	    sc, (void*) st, (void*) sh);
199185377Ssam
200185377Ssam	/* NB: memory is returned zero'd */
201185377Ssam	ahp = ath_hal_malloc(sizeof (struct ath_hal_5210));
202185377Ssam	if (ahp == AH_NULL) {
203225883Sadrian		HALDEBUG(AH_NULL, HAL_DEBUG_ANY,
204185377Ssam		    "%s: no memory for state block\n", __func__);
205185377Ssam		ecode = HAL_ENOMEM;
206185377Ssam		goto bad;
207185377Ssam	}
208185377Ssam	ah = &ahp->ah_priv.h;
209185377Ssam	/* set initial values */
210185377Ssam	OS_MEMCPY(&ahp->ah_priv, &ar5210hal, sizeof(struct ath_hal_private));
211185377Ssam	ah->ah_sc = sc;
212185377Ssam	ah->ah_st = st;
213185377Ssam	ah->ah_sh = sh;
214185377Ssam
215185377Ssam	ah->ah_devid = devid;			/* NB: for AH_DEBUG_ALQ */
216185377Ssam	AH_PRIVATE(ah)->ah_devid = devid;
217185377Ssam	AH_PRIVATE(ah)->ah_subvendorid = 0;	/* XXX */
218185377Ssam
219185380Ssam	AH_PRIVATE(ah)->ah_powerLimit = AR5210_MAX_RATE_POWER;
220185377Ssam	AH_PRIVATE(ah)->ah_tpScale = HAL_TP_SCALE_MAX;	/* no scaling */
221185377Ssam
222185377Ssam	ahp->ah_powerMode = HAL_PM_UNDEFINED;
223185377Ssam	ahp->ah_staId1Defaults = 0;
224185377Ssam	ahp->ah_rssiThr = INIT_RSSI_THR;
225185377Ssam	ahp->ah_sifstime = (u_int) -1;
226185377Ssam	ahp->ah_slottime = (u_int) -1;
227185377Ssam	ahp->ah_acktimeout = (u_int) -1;
228185377Ssam	ahp->ah_ctstimeout = (u_int) -1;
229185377Ssam
230185377Ssam	if (!ar5210ChipReset(ah, AH_NULL)) {	/* reset chip */
231185377Ssam		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n",
232185377Ssam		    __func__);
233185377Ssam		ecode = HAL_EIO;
234185377Ssam		goto bad;
235185377Ssam	}
236185377Ssam
237185377Ssam	/* Read Revisions from Chips */
238185377Ssam	AH_PRIVATE(ah)->ah_macVersion = 1;
239185377Ssam	AH_PRIVATE(ah)->ah_macRev = OS_REG_READ(ah, AR_SREV) & 0xff;
240185377Ssam	AH_PRIVATE(ah)->ah_phyRev = OS_REG_READ(ah, AR_PHY_CHIPID);
241185377Ssam	AH_PRIVATE(ah)->ah_analog2GhzRev = 0;
242185377Ssam
243185377Ssam	/* Read Radio Chip Rev Extract */
244185377Ssam	OS_REG_WRITE(ah, (AR_PHY_BASE + (0x34 << 2)), 0x00001c16);
245185377Ssam	for (i = 0; i < 4; i++)
246185377Ssam		OS_REG_WRITE(ah, (AR_PHY_BASE + (0x20 << 2)), 0x00010000);
247185377Ssam	revid = (OS_REG_READ(ah, AR_PHY_BASE + (256 << 2)) >> 28) & 0xf;
248185377Ssam
249185377Ssam	/* Chip labelling is 1 greater than revision register for AR5110 */
250185377Ssam	AH_PRIVATE(ah)->ah_analog5GhzRev = ath_hal_reverseBits(revid, 4) + 1;
251185377Ssam
252185377Ssam	/*
253185377Ssam	 * Read all the settings from the EEPROM and stash
254185380Ssam	 * ones we'll use later.
255185377Ssam	 */
256185377Ssam	pcicfg = OS_REG_READ(ah, AR_PCICFG);
257185377Ssam	OS_REG_WRITE(ah, AR_PCICFG, pcicfg | AR_PCICFG_EEPROMSEL);
258185380Ssam	ecode = ath_hal_v1EepromAttach(ah);
259185380Ssam	if (ecode != HAL_OK) {
260185377Ssam		goto eebad;
261185377Ssam	}
262185380Ssam	ecode = ath_hal_eepromGet(ah, AR_EEP_REGDMN_0, &eeval);
263185380Ssam	if (ecode != HAL_OK) {
264185377Ssam		HALDEBUG(ah, HAL_DEBUG_ANY,
265185380Ssam		    "%s: cannot read regulatory domain from EEPROM\n",
266185377Ssam		    __func__);
267185377Ssam		goto eebad;
268185380Ssam        }
269185380Ssam	AH_PRIVATE(ah)->ah_currentRD = eeval;
270185380Ssam	ecode = ath_hal_eepromGet(ah, AR_EEP_MACADDR, ahp->ah_macaddr);
271185380Ssam	if (ecode != HAL_OK) {
272185377Ssam		HALDEBUG(ah, HAL_DEBUG_ANY,
273185380Ssam		    "%s: error getting mac address from EEPROM\n", __func__);
274185377Ssam		goto eebad;
275185380Ssam        }
276185380Ssam	OS_REG_WRITE(ah, AR_PCICFG, pcicfg);	/* disable EEPROM access */
277185377Ssam
278185377Ssam	AH_PRIVATE(ah)->ah_getNfAdjust = ar5210GetNfAdjust;
279185377Ssam
280185377Ssam	/*
281185377Ssam	 * Got everything we need now to setup the capabilities.
282185377Ssam	 */
283185377Ssam	(void) ar5210FillCapabilityInfo(ah);
284185377Ssam
285185377Ssam	HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: return\n", __func__);
286185377Ssam
287185377Ssam	return ah;
288185377Ssameebad:
289185377Ssam	OS_REG_WRITE(ah, AR_PCICFG, pcicfg);	/* disable EEPROM access */
290185377Ssambad:
291185377Ssam	if (ahp)
292185377Ssam		ath_hal_free(ahp);
293185377Ssam	if (status)
294185377Ssam		*status = ecode;
295185377Ssam	return AH_NULL;
296185377Ssam#undef N
297185377Ssam}
298185377Ssam
299185377Ssamvoid
300185377Ssamar5210Detach(struct ath_hal *ah)
301185377Ssam{
302185377Ssam	HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s:\n", __func__);
303185377Ssam
304185377Ssam	HALASSERT(ah != AH_NULL);
305185377Ssam	HALASSERT(ah->ah_magic == AR5210_MAGIC);
306185377Ssam
307185380Ssam	ath_hal_eepromDetach(ah);
308185377Ssam	ath_hal_free(ah);
309185377Ssam}
310185377Ssam
311185377Ssam/*
312185377Ssam * Store the channel edges for the requested operational mode
313185377Ssam */
314185377Ssamstatic HAL_BOOL
315185377Ssamar5210GetChannelEdges(struct ath_hal *ah,
316185377Ssam	uint16_t flags, uint16_t *low, uint16_t *high)
317185377Ssam{
318187831Ssam	if (flags & IEEE80211_CHAN_5GHZ) {
319185377Ssam		*low = 5120;
320185377Ssam		*high = 5430;
321185377Ssam		return AH_TRUE;
322185377Ssam	} else {
323185377Ssam		return AH_FALSE;
324185377Ssam	}
325185377Ssam}
326185377Ssam
327185377Ssamstatic HAL_BOOL
328187831Ssamar5210GetChipPowerLimits(struct ath_hal *ah, struct ieee80211_channel *chan)
329185377Ssam{
330185377Ssam	/* XXX fill in, this is just a placeholder */
331187831Ssam	HALDEBUG(ah, HAL_DEBUG_ATTACH,
332187831Ssam	    "%s: no min/max power for %u/0x%x\n",
333187831Ssam	    __func__, chan->ic_freq, chan->ic_flags);
334187831Ssam	chan->ic_maxpower = AR5210_MAX_RATE_POWER;
335187831Ssam	chan->ic_minpower = 0;
336185377Ssam	return AH_TRUE;
337185377Ssam}
338185377Ssam
339188979Ssamstatic void
340235972Sadrianar5210ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore, HAL_BOOL power_off)
341188979Ssam{
342188979Ssam}
343188979Ssam
344188979Ssamstatic void
345188979Ssamar5210DisablePCIE(struct ath_hal *ah)
346188979Ssam{
347188979Ssam}
348188979Ssam
349185377Ssam/*
350185377Ssam * Fill all software cached or static hardware state information.
351185377Ssam */
352185377Ssamstatic HAL_BOOL
353185377Ssamar5210FillCapabilityInfo(struct ath_hal *ah)
354185377Ssam{
355185377Ssam	struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
356185377Ssam	HAL_CAPABILITIES *pCap = &ahpriv->ah_caps;
357185377Ssam
358185377Ssam	pCap->halWirelessModes |= HAL_MODE_11A;
359185377Ssam
360185377Ssam	pCap->halLow5GhzChan = 5120;
361185377Ssam	pCap->halHigh5GhzChan = 5430;
362185377Ssam
363185377Ssam	pCap->halSleepAfterBeaconBroken = AH_TRUE;
364185377Ssam	pCap->halPSPollBroken = AH_FALSE;
365238858Sadrian	pCap->halNumMRRetries = 1;		/* No hardware MRR support */
366239643Sadrian	pCap->halNumTxMaps = 1;			/* Single TX ptr per descr */
367185377Ssam
368185377Ssam	pCap->halTotalQueues = HAL_NUM_TX_QUEUES;
369185377Ssam	pCap->halKeyCacheSize = 64;
370185377Ssam
371185377Ssam	/* XXX not needed */
372185377Ssam	pCap->halChanHalfRate = AH_FALSE;
373185377Ssam	pCap->halChanQuarterRate = AH_FALSE;
374185377Ssam
375230791Sadrian	/*
376230791Sadrian	 * RSSI uses the combined field; some 11n NICs may use
377230791Sadrian	 * the control chain RSSI.
378230791Sadrian	 */
379230791Sadrian	pCap->halUseCombinedRadarRssi = AH_TRUE;
380230791Sadrian
381185380Ssam	if (ath_hal_eepromGetFlag(ah, AR_EEP_RFKILL)) {
382185377Ssam		/*
383185377Ssam		 * Setup initial rfsilent settings based on the EEPROM
384185377Ssam		 * contents.  Pin 0, polarity 0 is fixed; record this
385185377Ssam		 * using the EEPROM format found in later parts.
386185377Ssam		 */
387185377Ssam		ahpriv->ah_rfsilent = SM(0, AR_EEPROM_RFSILENT_GPIO_SEL)
388185377Ssam				    | SM(0, AR_EEPROM_RFSILENT_POLARITY);
389185377Ssam		ahpriv->ah_rfkillEnabled = AH_TRUE;
390185377Ssam		pCap->halRfSilentSupport = AH_TRUE;
391185377Ssam	}
392185377Ssam
393185377Ssam	pCap->halTstampPrecision = 15;		/* NB: s/w extended from 13 */
394192397Ssam	pCap->halIntrMask = (HAL_INT_COMMON - HAL_INT_BNR)
395192396Ssam			| HAL_INT_RX
396192396Ssam			| HAL_INT_TX
397192396Ssam			| HAL_INT_FATAL
398192396Ssam			;
399185377Ssam
400218436Sadrian	pCap->hal4kbSplitTransSupport = AH_TRUE;
401220324Sadrian	pCap->halHasRxSelfLinkedTail = AH_TRUE;
402218436Sadrian
403185377Ssam	ahpriv->ah_rxornIsFatal = AH_TRUE;
404185377Ssam	return AH_TRUE;
405185377Ssam}
406185406Ssam
407185406Ssamstatic const char*
408185406Ssamar5210Probe(uint16_t vendorid, uint16_t devid)
409185406Ssam{
410185406Ssam	if (vendorid == ATHEROS_VENDOR_ID &&
411185406Ssam	    (devid == AR5210_PROD || devid == AR5210_DEFAULT))
412185406Ssam		return "Atheros 5210";
413185406Ssam	return AH_NULL;
414185406Ssam}
415185418SsamAH_CHIP(AR5210, ar5210Probe, ar5210Attach);
416