Deleted Added
full compact
ar5210_attach.c (234873) ar5210_attach.c (235206)
1/*
2 * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
3 * Copyright (c) 2002-2004 Atheros Communications, Inc.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 *
1/*
2 * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
3 * Copyright (c) 2002-2004 Atheros Communications, Inc.
4 *
5 * Permission to use, copy, modify, and/or distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 *
17 * $FreeBSD: head/sys/dev/ath/ath_hal/ar5210/ar5210_attach.c 234873 2012-05-01 14:48:51Z adrian $
17 * $FreeBSD: head/sys/dev/ath/ath_hal/ar5210/ar5210_attach.c 235206 2012-05-09 18:17:01Z adrian $
18 */
19#include "opt_ah.h"
20
21#include "ah.h"
22#include "ah_internal.h"
23#include "ah_devid.h"
24
25#include "ar5210/ar5210.h"
26#include "ar5210/ar5210reg.h"
27#include "ar5210/ar5210phy.h"
28
29#include "ah_eeprom_v1.h"
30
31static HAL_BOOL ar5210GetChannelEdges(struct ath_hal *,
32 uint16_t flags, uint16_t *low, uint16_t *high);
33static HAL_BOOL ar5210GetChipPowerLimits(struct ath_hal *ah,
34 struct ieee80211_channel *chan);
35
36static void ar5210ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore);
37static void ar5210DisablePCIE(struct ath_hal *ah);
38
39static const struct ath_hal_private ar5210hal = {{
40 .ah_magic = AR5210_MAGIC,
41
42 .ah_getRateTable = ar5210GetRateTable,
43 .ah_detach = ar5210Detach,
44
45 /* Reset Functions */
46 .ah_reset = ar5210Reset,
47 .ah_phyDisable = ar5210PhyDisable,
48 .ah_disable = ar5210Disable,
49 .ah_configPCIE = ar5210ConfigPCIE,
50 .ah_disablePCIE = ar5210DisablePCIE,
51 .ah_setPCUConfig = ar5210SetPCUConfig,
52 .ah_perCalibration = ar5210PerCalibration,
53 .ah_perCalibrationN = ar5210PerCalibrationN,
54 .ah_resetCalValid = ar5210ResetCalValid,
55 .ah_setTxPowerLimit = ar5210SetTxPowerLimit,
56 .ah_getChanNoise = ath_hal_getChanNoise,
57
58 /* Transmit functions */
59 .ah_updateTxTrigLevel = ar5210UpdateTxTrigLevel,
60 .ah_setupTxQueue = ar5210SetupTxQueue,
61 .ah_setTxQueueProps = ar5210SetTxQueueProps,
62 .ah_getTxQueueProps = ar5210GetTxQueueProps,
63 .ah_releaseTxQueue = ar5210ReleaseTxQueue,
64 .ah_resetTxQueue = ar5210ResetTxQueue,
65 .ah_getTxDP = ar5210GetTxDP,
66 .ah_setTxDP = ar5210SetTxDP,
67 .ah_numTxPending = ar5210NumTxPending,
68 .ah_startTxDma = ar5210StartTxDma,
69 .ah_stopTxDma = ar5210StopTxDma,
70 .ah_setupTxDesc = ar5210SetupTxDesc,
71 .ah_setupXTxDesc = ar5210SetupXTxDesc,
72 .ah_fillTxDesc = ar5210FillTxDesc,
73 .ah_procTxDesc = ar5210ProcTxDesc,
74 .ah_getTxIntrQueue = ar5210GetTxIntrQueue,
75 .ah_reqTxIntrDesc = ar5210IntrReqTxDesc,
76 .ah_getTxCompletionRates = ar5210GetTxCompletionRates,
77
78 /* RX Functions */
79 .ah_getRxDP = ar5210GetRxDP,
80 .ah_setRxDP = ar5210SetRxDP,
81 .ah_enableReceive = ar5210EnableReceive,
82 .ah_stopDmaReceive = ar5210StopDmaReceive,
83 .ah_startPcuReceive = ar5210StartPcuReceive,
84 .ah_stopPcuReceive = ar5210StopPcuReceive,
85 .ah_setMulticastFilter = ar5210SetMulticastFilter,
86 .ah_setMulticastFilterIndex = ar5210SetMulticastFilterIndex,
87 .ah_clrMulticastFilterIndex = ar5210ClrMulticastFilterIndex,
88 .ah_getRxFilter = ar5210GetRxFilter,
89 .ah_setRxFilter = ar5210SetRxFilter,
90 .ah_setupRxDesc = ar5210SetupRxDesc,
91 .ah_procRxDesc = ar5210ProcRxDesc,
92 .ah_rxMonitor = ar5210RxMonitor,
93 .ah_aniPoll = ar5210AniPoll,
94 .ah_procMibEvent = ar5210MibEvent,
95
96 /* Misc Functions */
97 .ah_getCapability = ar5210GetCapability,
98 .ah_setCapability = ar5210SetCapability,
99 .ah_getDiagState = ar5210GetDiagState,
100 .ah_getMacAddress = ar5210GetMacAddress,
101 .ah_setMacAddress = ar5210SetMacAddress,
102 .ah_getBssIdMask = ar5210GetBssIdMask,
103 .ah_setBssIdMask = ar5210SetBssIdMask,
104 .ah_setRegulatoryDomain = ar5210SetRegulatoryDomain,
105 .ah_setLedState = ar5210SetLedState,
106 .ah_writeAssocid = ar5210WriteAssocid,
107 .ah_gpioCfgInput = ar5210GpioCfgInput,
108 .ah_gpioCfgOutput = ar5210GpioCfgOutput,
109 .ah_gpioGet = ar5210GpioGet,
110 .ah_gpioSet = ar5210GpioSet,
111 .ah_gpioSetIntr = ar5210Gpio0SetIntr,
112 .ah_getTsf32 = ar5210GetTsf32,
113 .ah_getTsf64 = ar5210GetTsf64,
114 .ah_resetTsf = ar5210ResetTsf,
115 .ah_detectCardPresent = ar5210DetectCardPresent,
116 .ah_updateMibCounters = ar5210UpdateMibCounters,
117 .ah_getRfGain = ar5210GetRfgain,
118 .ah_getDefAntenna = ar5210GetDefAntenna,
119 .ah_setDefAntenna = ar5210SetDefAntenna,
120 .ah_getAntennaSwitch = ar5210GetAntennaSwitch,
121 .ah_setAntennaSwitch = ar5210SetAntennaSwitch,
122 .ah_setSifsTime = ar5210SetSifsTime,
123 .ah_getSifsTime = ar5210GetSifsTime,
124 .ah_setSlotTime = ar5210SetSlotTime,
125 .ah_getSlotTime = ar5210GetSlotTime,
126 .ah_setAckTimeout = ar5210SetAckTimeout,
127 .ah_getAckTimeout = ar5210GetAckTimeout,
128 .ah_setAckCTSRate = ar5210SetAckCTSRate,
129 .ah_getAckCTSRate = ar5210GetAckCTSRate,
130 .ah_setCTSTimeout = ar5210SetCTSTimeout,
131 .ah_getCTSTimeout = ar5210GetCTSTimeout,
132 .ah_setDecompMask = ar5210SetDecompMask,
133 .ah_setCoverageClass = ar5210SetCoverageClass,
134 .ah_get11nExtBusy = ar5210Get11nExtBusy,
135 .ah_getMibCycleCounts = ar5210GetMibCycleCounts,
18 */
19#include "opt_ah.h"
20
21#include "ah.h"
22#include "ah_internal.h"
23#include "ah_devid.h"
24
25#include "ar5210/ar5210.h"
26#include "ar5210/ar5210reg.h"
27#include "ar5210/ar5210phy.h"
28
29#include "ah_eeprom_v1.h"
30
31static HAL_BOOL ar5210GetChannelEdges(struct ath_hal *,
32 uint16_t flags, uint16_t *low, uint16_t *high);
33static HAL_BOOL ar5210GetChipPowerLimits(struct ath_hal *ah,
34 struct ieee80211_channel *chan);
35
36static void ar5210ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore);
37static void ar5210DisablePCIE(struct ath_hal *ah);
38
39static const struct ath_hal_private ar5210hal = {{
40 .ah_magic = AR5210_MAGIC,
41
42 .ah_getRateTable = ar5210GetRateTable,
43 .ah_detach = ar5210Detach,
44
45 /* Reset Functions */
46 .ah_reset = ar5210Reset,
47 .ah_phyDisable = ar5210PhyDisable,
48 .ah_disable = ar5210Disable,
49 .ah_configPCIE = ar5210ConfigPCIE,
50 .ah_disablePCIE = ar5210DisablePCIE,
51 .ah_setPCUConfig = ar5210SetPCUConfig,
52 .ah_perCalibration = ar5210PerCalibration,
53 .ah_perCalibrationN = ar5210PerCalibrationN,
54 .ah_resetCalValid = ar5210ResetCalValid,
55 .ah_setTxPowerLimit = ar5210SetTxPowerLimit,
56 .ah_getChanNoise = ath_hal_getChanNoise,
57
58 /* Transmit functions */
59 .ah_updateTxTrigLevel = ar5210UpdateTxTrigLevel,
60 .ah_setupTxQueue = ar5210SetupTxQueue,
61 .ah_setTxQueueProps = ar5210SetTxQueueProps,
62 .ah_getTxQueueProps = ar5210GetTxQueueProps,
63 .ah_releaseTxQueue = ar5210ReleaseTxQueue,
64 .ah_resetTxQueue = ar5210ResetTxQueue,
65 .ah_getTxDP = ar5210GetTxDP,
66 .ah_setTxDP = ar5210SetTxDP,
67 .ah_numTxPending = ar5210NumTxPending,
68 .ah_startTxDma = ar5210StartTxDma,
69 .ah_stopTxDma = ar5210StopTxDma,
70 .ah_setupTxDesc = ar5210SetupTxDesc,
71 .ah_setupXTxDesc = ar5210SetupXTxDesc,
72 .ah_fillTxDesc = ar5210FillTxDesc,
73 .ah_procTxDesc = ar5210ProcTxDesc,
74 .ah_getTxIntrQueue = ar5210GetTxIntrQueue,
75 .ah_reqTxIntrDesc = ar5210IntrReqTxDesc,
76 .ah_getTxCompletionRates = ar5210GetTxCompletionRates,
77
78 /* RX Functions */
79 .ah_getRxDP = ar5210GetRxDP,
80 .ah_setRxDP = ar5210SetRxDP,
81 .ah_enableReceive = ar5210EnableReceive,
82 .ah_stopDmaReceive = ar5210StopDmaReceive,
83 .ah_startPcuReceive = ar5210StartPcuReceive,
84 .ah_stopPcuReceive = ar5210StopPcuReceive,
85 .ah_setMulticastFilter = ar5210SetMulticastFilter,
86 .ah_setMulticastFilterIndex = ar5210SetMulticastFilterIndex,
87 .ah_clrMulticastFilterIndex = ar5210ClrMulticastFilterIndex,
88 .ah_getRxFilter = ar5210GetRxFilter,
89 .ah_setRxFilter = ar5210SetRxFilter,
90 .ah_setupRxDesc = ar5210SetupRxDesc,
91 .ah_procRxDesc = ar5210ProcRxDesc,
92 .ah_rxMonitor = ar5210RxMonitor,
93 .ah_aniPoll = ar5210AniPoll,
94 .ah_procMibEvent = ar5210MibEvent,
95
96 /* Misc Functions */
97 .ah_getCapability = ar5210GetCapability,
98 .ah_setCapability = ar5210SetCapability,
99 .ah_getDiagState = ar5210GetDiagState,
100 .ah_getMacAddress = ar5210GetMacAddress,
101 .ah_setMacAddress = ar5210SetMacAddress,
102 .ah_getBssIdMask = ar5210GetBssIdMask,
103 .ah_setBssIdMask = ar5210SetBssIdMask,
104 .ah_setRegulatoryDomain = ar5210SetRegulatoryDomain,
105 .ah_setLedState = ar5210SetLedState,
106 .ah_writeAssocid = ar5210WriteAssocid,
107 .ah_gpioCfgInput = ar5210GpioCfgInput,
108 .ah_gpioCfgOutput = ar5210GpioCfgOutput,
109 .ah_gpioGet = ar5210GpioGet,
110 .ah_gpioSet = ar5210GpioSet,
111 .ah_gpioSetIntr = ar5210Gpio0SetIntr,
112 .ah_getTsf32 = ar5210GetTsf32,
113 .ah_getTsf64 = ar5210GetTsf64,
114 .ah_resetTsf = ar5210ResetTsf,
115 .ah_detectCardPresent = ar5210DetectCardPresent,
116 .ah_updateMibCounters = ar5210UpdateMibCounters,
117 .ah_getRfGain = ar5210GetRfgain,
118 .ah_getDefAntenna = ar5210GetDefAntenna,
119 .ah_setDefAntenna = ar5210SetDefAntenna,
120 .ah_getAntennaSwitch = ar5210GetAntennaSwitch,
121 .ah_setAntennaSwitch = ar5210SetAntennaSwitch,
122 .ah_setSifsTime = ar5210SetSifsTime,
123 .ah_getSifsTime = ar5210GetSifsTime,
124 .ah_setSlotTime = ar5210SetSlotTime,
125 .ah_getSlotTime = ar5210GetSlotTime,
126 .ah_setAckTimeout = ar5210SetAckTimeout,
127 .ah_getAckTimeout = ar5210GetAckTimeout,
128 .ah_setAckCTSRate = ar5210SetAckCTSRate,
129 .ah_getAckCTSRate = ar5210GetAckCTSRate,
130 .ah_setCTSTimeout = ar5210SetCTSTimeout,
131 .ah_getCTSTimeout = ar5210GetCTSTimeout,
132 .ah_setDecompMask = ar5210SetDecompMask,
133 .ah_setCoverageClass = ar5210SetCoverageClass,
134 .ah_get11nExtBusy = ar5210Get11nExtBusy,
135 .ah_getMibCycleCounts = ar5210GetMibCycleCounts,
136 .ah_enableDfs = ar5210EnableDfs,
137 .ah_getDfsThresh = ar5210GetDfsThresh,
138 /* XXX procRadarEvent */
139 /* XXX isFastClockEnabled */
136
137 /* Key Cache Functions */
138 .ah_getKeyCacheSize = ar5210GetKeyCacheSize,
139 .ah_resetKeyCacheEntry = ar5210ResetKeyCacheEntry,
140 .ah_isKeyCacheEntryValid = ar5210IsKeyCacheEntryValid,
141 .ah_setKeyCacheEntry = ar5210SetKeyCacheEntry,
142 .ah_setKeyCacheEntryMac = ar5210SetKeyCacheEntryMac,
143
144 /* Power Management Functions */
145 .ah_setPowerMode = ar5210SetPowerMode,
146 .ah_getPowerMode = ar5210GetPowerMode,
147
148 /* Beacon Functions */
149 .ah_setBeaconTimers = ar5210SetBeaconTimers,
150 .ah_beaconInit = ar5210BeaconInit,
151 .ah_setStationBeaconTimers = ar5210SetStaBeaconTimers,
152 .ah_resetStationBeaconTimers = ar5210ResetStaBeaconTimers,
153 .ah_getNextTBTT = ar5210GetNextTBTT,
154
155 /* Interrupt Functions */
156 .ah_isInterruptPending = ar5210IsInterruptPending,
157 .ah_getPendingInterrupts = ar5210GetPendingInterrupts,
158 .ah_getInterrupts = ar5210GetInterrupts,
159 .ah_setInterrupts = ar5210SetInterrupts },
160
161 .ah_getChannelEdges = ar5210GetChannelEdges,
162 .ah_getWirelessModes = ar5210GetWirelessModes,
163 .ah_eepromRead = ar5210EepromRead,
164#ifdef AH_SUPPORT_WRITE_EEPROM
165 .ah_eepromWrite = ar5210EepromWrite,
166#endif
167 .ah_getChipPowerLimits = ar5210GetChipPowerLimits,
168};
169
170static HAL_BOOL ar5210FillCapabilityInfo(struct ath_hal *ah);
171
172/*
173 * Attach for an AR5210 part.
174 */
175static struct ath_hal *
176ar5210Attach(uint16_t devid, HAL_SOFTC sc, HAL_BUS_TAG st, HAL_BUS_HANDLE sh,
177 uint16_t *eepromdata, HAL_STATUS *status)
178{
179#define N(a) (sizeof(a)/sizeof(a[0]))
180 struct ath_hal_5210 *ahp;
181 struct ath_hal *ah;
182 uint32_t revid, pcicfg;
183 uint16_t eeval;
184 HAL_STATUS ecode;
185 int i;
186
187 HALDEBUG(AH_NULL, HAL_DEBUG_ATTACH,
188 "%s: devid 0x%x sc %p st %p sh %p\n", __func__, devid,
189 sc, (void*) st, (void*) sh);
190
191 /* NB: memory is returned zero'd */
192 ahp = ath_hal_malloc(sizeof (struct ath_hal_5210));
193 if (ahp == AH_NULL) {
194 HALDEBUG(AH_NULL, HAL_DEBUG_ANY,
195 "%s: no memory for state block\n", __func__);
196 ecode = HAL_ENOMEM;
197 goto bad;
198 }
199 ah = &ahp->ah_priv.h;
200 /* set initial values */
201 OS_MEMCPY(&ahp->ah_priv, &ar5210hal, sizeof(struct ath_hal_private));
202 ah->ah_sc = sc;
203 ah->ah_st = st;
204 ah->ah_sh = sh;
205
206 ah->ah_devid = devid; /* NB: for AH_DEBUG_ALQ */
207 AH_PRIVATE(ah)->ah_devid = devid;
208 AH_PRIVATE(ah)->ah_subvendorid = 0; /* XXX */
209
210 AH_PRIVATE(ah)->ah_powerLimit = AR5210_MAX_RATE_POWER;
211 AH_PRIVATE(ah)->ah_tpScale = HAL_TP_SCALE_MAX; /* no scaling */
212
213 ahp->ah_powerMode = HAL_PM_UNDEFINED;
214 ahp->ah_staId1Defaults = 0;
215 ahp->ah_rssiThr = INIT_RSSI_THR;
216 ahp->ah_sifstime = (u_int) -1;
217 ahp->ah_slottime = (u_int) -1;
218 ahp->ah_acktimeout = (u_int) -1;
219 ahp->ah_ctstimeout = (u_int) -1;
220
221 if (!ar5210ChipReset(ah, AH_NULL)) { /* reset chip */
222 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n",
223 __func__);
224 ecode = HAL_EIO;
225 goto bad;
226 }
227
228 /* Read Revisions from Chips */
229 AH_PRIVATE(ah)->ah_macVersion = 1;
230 AH_PRIVATE(ah)->ah_macRev = OS_REG_READ(ah, AR_SREV) & 0xff;
231 AH_PRIVATE(ah)->ah_phyRev = OS_REG_READ(ah, AR_PHY_CHIPID);
232 AH_PRIVATE(ah)->ah_analog2GhzRev = 0;
233
234 /* Read Radio Chip Rev Extract */
235 OS_REG_WRITE(ah, (AR_PHY_BASE + (0x34 << 2)), 0x00001c16);
236 for (i = 0; i < 4; i++)
237 OS_REG_WRITE(ah, (AR_PHY_BASE + (0x20 << 2)), 0x00010000);
238 revid = (OS_REG_READ(ah, AR_PHY_BASE + (256 << 2)) >> 28) & 0xf;
239
240 /* Chip labelling is 1 greater than revision register for AR5110 */
241 AH_PRIVATE(ah)->ah_analog5GhzRev = ath_hal_reverseBits(revid, 4) + 1;
242
243 /*
244 * Read all the settings from the EEPROM and stash
245 * ones we'll use later.
246 */
247 pcicfg = OS_REG_READ(ah, AR_PCICFG);
248 OS_REG_WRITE(ah, AR_PCICFG, pcicfg | AR_PCICFG_EEPROMSEL);
249 ecode = ath_hal_v1EepromAttach(ah);
250 if (ecode != HAL_OK) {
251 goto eebad;
252 }
253 ecode = ath_hal_eepromGet(ah, AR_EEP_REGDMN_0, &eeval);
254 if (ecode != HAL_OK) {
255 HALDEBUG(ah, HAL_DEBUG_ANY,
256 "%s: cannot read regulatory domain from EEPROM\n",
257 __func__);
258 goto eebad;
259 }
260 AH_PRIVATE(ah)->ah_currentRD = eeval;
261 ecode = ath_hal_eepromGet(ah, AR_EEP_MACADDR, ahp->ah_macaddr);
262 if (ecode != HAL_OK) {
263 HALDEBUG(ah, HAL_DEBUG_ANY,
264 "%s: error getting mac address from EEPROM\n", __func__);
265 goto eebad;
266 }
267 OS_REG_WRITE(ah, AR_PCICFG, pcicfg); /* disable EEPROM access */
268
269 AH_PRIVATE(ah)->ah_getNfAdjust = ar5210GetNfAdjust;
270
271 /*
272 * Got everything we need now to setup the capabilities.
273 */
274 (void) ar5210FillCapabilityInfo(ah);
275
276 HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: return\n", __func__);
277
278 return ah;
279eebad:
280 OS_REG_WRITE(ah, AR_PCICFG, pcicfg); /* disable EEPROM access */
281bad:
282 if (ahp)
283 ath_hal_free(ahp);
284 if (status)
285 *status = ecode;
286 return AH_NULL;
287#undef N
288}
289
290void
291ar5210Detach(struct ath_hal *ah)
292{
293 HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s:\n", __func__);
294
295 HALASSERT(ah != AH_NULL);
296 HALASSERT(ah->ah_magic == AR5210_MAGIC);
297
298 ath_hal_eepromDetach(ah);
299 ath_hal_free(ah);
300}
301
302/*
303 * Store the channel edges for the requested operational mode
304 */
305static HAL_BOOL
306ar5210GetChannelEdges(struct ath_hal *ah,
307 uint16_t flags, uint16_t *low, uint16_t *high)
308{
309 if (flags & IEEE80211_CHAN_5GHZ) {
310 *low = 5120;
311 *high = 5430;
312 return AH_TRUE;
313 } else {
314 return AH_FALSE;
315 }
316}
317
318static HAL_BOOL
319ar5210GetChipPowerLimits(struct ath_hal *ah, struct ieee80211_channel *chan)
320{
321 /* XXX fill in, this is just a placeholder */
322 HALDEBUG(ah, HAL_DEBUG_ATTACH,
323 "%s: no min/max power for %u/0x%x\n",
324 __func__, chan->ic_freq, chan->ic_flags);
325 chan->ic_maxpower = AR5210_MAX_RATE_POWER;
326 chan->ic_minpower = 0;
327 return AH_TRUE;
328}
329
330static void
331ar5210ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore)
332{
333}
334
335static void
336ar5210DisablePCIE(struct ath_hal *ah)
337{
338}
339
340/*
341 * Fill all software cached or static hardware state information.
342 */
343static HAL_BOOL
344ar5210FillCapabilityInfo(struct ath_hal *ah)
345{
346 struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
347 HAL_CAPABILITIES *pCap = &ahpriv->ah_caps;
348
349 pCap->halWirelessModes |= HAL_MODE_11A;
350
351 pCap->halLow5GhzChan = 5120;
352 pCap->halHigh5GhzChan = 5430;
353
354 pCap->halSleepAfterBeaconBroken = AH_TRUE;
355 pCap->halPSPollBroken = AH_FALSE;
356
357 pCap->halTotalQueues = HAL_NUM_TX_QUEUES;
358 pCap->halKeyCacheSize = 64;
359
360 /* XXX not needed */
361 pCap->halChanHalfRate = AH_FALSE;
362 pCap->halChanQuarterRate = AH_FALSE;
363
364 /*
365 * RSSI uses the combined field; some 11n NICs may use
366 * the control chain RSSI.
367 */
368 pCap->halUseCombinedRadarRssi = AH_TRUE;
369
370 if (ath_hal_eepromGetFlag(ah, AR_EEP_RFKILL)) {
371 /*
372 * Setup initial rfsilent settings based on the EEPROM
373 * contents. Pin 0, polarity 0 is fixed; record this
374 * using the EEPROM format found in later parts.
375 */
376 ahpriv->ah_rfsilent = SM(0, AR_EEPROM_RFSILENT_GPIO_SEL)
377 | SM(0, AR_EEPROM_RFSILENT_POLARITY);
378 ahpriv->ah_rfkillEnabled = AH_TRUE;
379 pCap->halRfSilentSupport = AH_TRUE;
380 }
381
382 pCap->halTstampPrecision = 15; /* NB: s/w extended from 13 */
383 pCap->halIntrMask = (HAL_INT_COMMON - HAL_INT_BNR)
384 | HAL_INT_RX
385 | HAL_INT_TX
386 | HAL_INT_FATAL
387 ;
388
389 pCap->hal4kbSplitTransSupport = AH_TRUE;
390 pCap->halHasRxSelfLinkedTail = AH_TRUE;
391
392 ahpriv->ah_rxornIsFatal = AH_TRUE;
393 return AH_TRUE;
394}
395
396static const char*
397ar5210Probe(uint16_t vendorid, uint16_t devid)
398{
399 if (vendorid == ATHEROS_VENDOR_ID &&
400 (devid == AR5210_PROD || devid == AR5210_DEFAULT))
401 return "Atheros 5210";
402 return AH_NULL;
403}
404AH_CHIP(AR5210, ar5210Probe, ar5210Attach);
140
141 /* Key Cache Functions */
142 .ah_getKeyCacheSize = ar5210GetKeyCacheSize,
143 .ah_resetKeyCacheEntry = ar5210ResetKeyCacheEntry,
144 .ah_isKeyCacheEntryValid = ar5210IsKeyCacheEntryValid,
145 .ah_setKeyCacheEntry = ar5210SetKeyCacheEntry,
146 .ah_setKeyCacheEntryMac = ar5210SetKeyCacheEntryMac,
147
148 /* Power Management Functions */
149 .ah_setPowerMode = ar5210SetPowerMode,
150 .ah_getPowerMode = ar5210GetPowerMode,
151
152 /* Beacon Functions */
153 .ah_setBeaconTimers = ar5210SetBeaconTimers,
154 .ah_beaconInit = ar5210BeaconInit,
155 .ah_setStationBeaconTimers = ar5210SetStaBeaconTimers,
156 .ah_resetStationBeaconTimers = ar5210ResetStaBeaconTimers,
157 .ah_getNextTBTT = ar5210GetNextTBTT,
158
159 /* Interrupt Functions */
160 .ah_isInterruptPending = ar5210IsInterruptPending,
161 .ah_getPendingInterrupts = ar5210GetPendingInterrupts,
162 .ah_getInterrupts = ar5210GetInterrupts,
163 .ah_setInterrupts = ar5210SetInterrupts },
164
165 .ah_getChannelEdges = ar5210GetChannelEdges,
166 .ah_getWirelessModes = ar5210GetWirelessModes,
167 .ah_eepromRead = ar5210EepromRead,
168#ifdef AH_SUPPORT_WRITE_EEPROM
169 .ah_eepromWrite = ar5210EepromWrite,
170#endif
171 .ah_getChipPowerLimits = ar5210GetChipPowerLimits,
172};
173
174static HAL_BOOL ar5210FillCapabilityInfo(struct ath_hal *ah);
175
176/*
177 * Attach for an AR5210 part.
178 */
179static struct ath_hal *
180ar5210Attach(uint16_t devid, HAL_SOFTC sc, HAL_BUS_TAG st, HAL_BUS_HANDLE sh,
181 uint16_t *eepromdata, HAL_STATUS *status)
182{
183#define N(a) (sizeof(a)/sizeof(a[0]))
184 struct ath_hal_5210 *ahp;
185 struct ath_hal *ah;
186 uint32_t revid, pcicfg;
187 uint16_t eeval;
188 HAL_STATUS ecode;
189 int i;
190
191 HALDEBUG(AH_NULL, HAL_DEBUG_ATTACH,
192 "%s: devid 0x%x sc %p st %p sh %p\n", __func__, devid,
193 sc, (void*) st, (void*) sh);
194
195 /* NB: memory is returned zero'd */
196 ahp = ath_hal_malloc(sizeof (struct ath_hal_5210));
197 if (ahp == AH_NULL) {
198 HALDEBUG(AH_NULL, HAL_DEBUG_ANY,
199 "%s: no memory for state block\n", __func__);
200 ecode = HAL_ENOMEM;
201 goto bad;
202 }
203 ah = &ahp->ah_priv.h;
204 /* set initial values */
205 OS_MEMCPY(&ahp->ah_priv, &ar5210hal, sizeof(struct ath_hal_private));
206 ah->ah_sc = sc;
207 ah->ah_st = st;
208 ah->ah_sh = sh;
209
210 ah->ah_devid = devid; /* NB: for AH_DEBUG_ALQ */
211 AH_PRIVATE(ah)->ah_devid = devid;
212 AH_PRIVATE(ah)->ah_subvendorid = 0; /* XXX */
213
214 AH_PRIVATE(ah)->ah_powerLimit = AR5210_MAX_RATE_POWER;
215 AH_PRIVATE(ah)->ah_tpScale = HAL_TP_SCALE_MAX; /* no scaling */
216
217 ahp->ah_powerMode = HAL_PM_UNDEFINED;
218 ahp->ah_staId1Defaults = 0;
219 ahp->ah_rssiThr = INIT_RSSI_THR;
220 ahp->ah_sifstime = (u_int) -1;
221 ahp->ah_slottime = (u_int) -1;
222 ahp->ah_acktimeout = (u_int) -1;
223 ahp->ah_ctstimeout = (u_int) -1;
224
225 if (!ar5210ChipReset(ah, AH_NULL)) { /* reset chip */
226 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: chip reset failed\n",
227 __func__);
228 ecode = HAL_EIO;
229 goto bad;
230 }
231
232 /* Read Revisions from Chips */
233 AH_PRIVATE(ah)->ah_macVersion = 1;
234 AH_PRIVATE(ah)->ah_macRev = OS_REG_READ(ah, AR_SREV) & 0xff;
235 AH_PRIVATE(ah)->ah_phyRev = OS_REG_READ(ah, AR_PHY_CHIPID);
236 AH_PRIVATE(ah)->ah_analog2GhzRev = 0;
237
238 /* Read Radio Chip Rev Extract */
239 OS_REG_WRITE(ah, (AR_PHY_BASE + (0x34 << 2)), 0x00001c16);
240 for (i = 0; i < 4; i++)
241 OS_REG_WRITE(ah, (AR_PHY_BASE + (0x20 << 2)), 0x00010000);
242 revid = (OS_REG_READ(ah, AR_PHY_BASE + (256 << 2)) >> 28) & 0xf;
243
244 /* Chip labelling is 1 greater than revision register for AR5110 */
245 AH_PRIVATE(ah)->ah_analog5GhzRev = ath_hal_reverseBits(revid, 4) + 1;
246
247 /*
248 * Read all the settings from the EEPROM and stash
249 * ones we'll use later.
250 */
251 pcicfg = OS_REG_READ(ah, AR_PCICFG);
252 OS_REG_WRITE(ah, AR_PCICFG, pcicfg | AR_PCICFG_EEPROMSEL);
253 ecode = ath_hal_v1EepromAttach(ah);
254 if (ecode != HAL_OK) {
255 goto eebad;
256 }
257 ecode = ath_hal_eepromGet(ah, AR_EEP_REGDMN_0, &eeval);
258 if (ecode != HAL_OK) {
259 HALDEBUG(ah, HAL_DEBUG_ANY,
260 "%s: cannot read regulatory domain from EEPROM\n",
261 __func__);
262 goto eebad;
263 }
264 AH_PRIVATE(ah)->ah_currentRD = eeval;
265 ecode = ath_hal_eepromGet(ah, AR_EEP_MACADDR, ahp->ah_macaddr);
266 if (ecode != HAL_OK) {
267 HALDEBUG(ah, HAL_DEBUG_ANY,
268 "%s: error getting mac address from EEPROM\n", __func__);
269 goto eebad;
270 }
271 OS_REG_WRITE(ah, AR_PCICFG, pcicfg); /* disable EEPROM access */
272
273 AH_PRIVATE(ah)->ah_getNfAdjust = ar5210GetNfAdjust;
274
275 /*
276 * Got everything we need now to setup the capabilities.
277 */
278 (void) ar5210FillCapabilityInfo(ah);
279
280 HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s: return\n", __func__);
281
282 return ah;
283eebad:
284 OS_REG_WRITE(ah, AR_PCICFG, pcicfg); /* disable EEPROM access */
285bad:
286 if (ahp)
287 ath_hal_free(ahp);
288 if (status)
289 *status = ecode;
290 return AH_NULL;
291#undef N
292}
293
294void
295ar5210Detach(struct ath_hal *ah)
296{
297 HALDEBUG(ah, HAL_DEBUG_ATTACH, "%s:\n", __func__);
298
299 HALASSERT(ah != AH_NULL);
300 HALASSERT(ah->ah_magic == AR5210_MAGIC);
301
302 ath_hal_eepromDetach(ah);
303 ath_hal_free(ah);
304}
305
306/*
307 * Store the channel edges for the requested operational mode
308 */
309static HAL_BOOL
310ar5210GetChannelEdges(struct ath_hal *ah,
311 uint16_t flags, uint16_t *low, uint16_t *high)
312{
313 if (flags & IEEE80211_CHAN_5GHZ) {
314 *low = 5120;
315 *high = 5430;
316 return AH_TRUE;
317 } else {
318 return AH_FALSE;
319 }
320}
321
322static HAL_BOOL
323ar5210GetChipPowerLimits(struct ath_hal *ah, struct ieee80211_channel *chan)
324{
325 /* XXX fill in, this is just a placeholder */
326 HALDEBUG(ah, HAL_DEBUG_ATTACH,
327 "%s: no min/max power for %u/0x%x\n",
328 __func__, chan->ic_freq, chan->ic_flags);
329 chan->ic_maxpower = AR5210_MAX_RATE_POWER;
330 chan->ic_minpower = 0;
331 return AH_TRUE;
332}
333
334static void
335ar5210ConfigPCIE(struct ath_hal *ah, HAL_BOOL restore)
336{
337}
338
339static void
340ar5210DisablePCIE(struct ath_hal *ah)
341{
342}
343
344/*
345 * Fill all software cached or static hardware state information.
346 */
347static HAL_BOOL
348ar5210FillCapabilityInfo(struct ath_hal *ah)
349{
350 struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
351 HAL_CAPABILITIES *pCap = &ahpriv->ah_caps;
352
353 pCap->halWirelessModes |= HAL_MODE_11A;
354
355 pCap->halLow5GhzChan = 5120;
356 pCap->halHigh5GhzChan = 5430;
357
358 pCap->halSleepAfterBeaconBroken = AH_TRUE;
359 pCap->halPSPollBroken = AH_FALSE;
360
361 pCap->halTotalQueues = HAL_NUM_TX_QUEUES;
362 pCap->halKeyCacheSize = 64;
363
364 /* XXX not needed */
365 pCap->halChanHalfRate = AH_FALSE;
366 pCap->halChanQuarterRate = AH_FALSE;
367
368 /*
369 * RSSI uses the combined field; some 11n NICs may use
370 * the control chain RSSI.
371 */
372 pCap->halUseCombinedRadarRssi = AH_TRUE;
373
374 if (ath_hal_eepromGetFlag(ah, AR_EEP_RFKILL)) {
375 /*
376 * Setup initial rfsilent settings based on the EEPROM
377 * contents. Pin 0, polarity 0 is fixed; record this
378 * using the EEPROM format found in later parts.
379 */
380 ahpriv->ah_rfsilent = SM(0, AR_EEPROM_RFSILENT_GPIO_SEL)
381 | SM(0, AR_EEPROM_RFSILENT_POLARITY);
382 ahpriv->ah_rfkillEnabled = AH_TRUE;
383 pCap->halRfSilentSupport = AH_TRUE;
384 }
385
386 pCap->halTstampPrecision = 15; /* NB: s/w extended from 13 */
387 pCap->halIntrMask = (HAL_INT_COMMON - HAL_INT_BNR)
388 | HAL_INT_RX
389 | HAL_INT_TX
390 | HAL_INT_FATAL
391 ;
392
393 pCap->hal4kbSplitTransSupport = AH_TRUE;
394 pCap->halHasRxSelfLinkedTail = AH_TRUE;
395
396 ahpriv->ah_rxornIsFatal = AH_TRUE;
397 return AH_TRUE;
398}
399
400static const char*
401ar5210Probe(uint16_t vendorid, uint16_t devid)
402{
403 if (vendorid == ATHEROS_VENDOR_ID &&
404 (devid == AR5210_PROD || devid == AR5210_DEFAULT))
405 return "Atheros 5210";
406 return AH_NULL;
407}
408AH_CHIP(AR5210, ar5210Probe, ar5210Attach);