xref: /freebsd/sys/dev/ath/ath_hal/ah.c (revision 10b9d77bf1ccf2f3affafa6261692cb92cf7e992)
1 /*
2  * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
3  * Copyright (c) 2002-2008 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$
18  */
19 #include "opt_ah.h"
20 
21 #include "ah.h"
22 #include "ah_internal.h"
23 #include "ah_devid.h"
24 
25 #include "ar5416/ar5416reg.h"		/* NB: includes ar5212reg.h */
26 
27 /* linker set of registered chips */
28 OS_SET_DECLARE(ah_chips, struct ath_hal_chip);
29 
30 /*
31  * Check the set of registered chips to see if any recognize
32  * the device as one they can support.
33  */
34 const char*
35 ath_hal_probe(uint16_t vendorid, uint16_t devid)
36 {
37 	struct ath_hal_chip * const *pchip;
38 
39 	OS_SET_FOREACH(pchip, ah_chips) {
40 		const char *name = (*pchip)->probe(vendorid, devid);
41 		if (name != AH_NULL)
42 			return name;
43 	}
44 	return AH_NULL;
45 }
46 
47 /*
48  * Attach detects device chip revisions, initializes the hwLayer
49  * function list, reads EEPROM information,
50  * selects reset vectors, and performs a short self test.
51  * Any failures will return an error that should cause a hardware
52  * disable.
53  */
54 struct ath_hal*
55 ath_hal_attach(uint16_t devid, HAL_SOFTC sc,
56 	HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata, HAL_STATUS *error)
57 {
58 	struct ath_hal_chip * const *pchip;
59 
60 	OS_SET_FOREACH(pchip, ah_chips) {
61 		struct ath_hal_chip *chip = *pchip;
62 		struct ath_hal *ah;
63 
64 		/* XXX don't have vendorid, assume atheros one works */
65 		if (chip->probe(ATHEROS_VENDOR_ID, devid) == AH_NULL)
66 			continue;
67 		ah = chip->attach(devid, sc, st, sh, eepromdata, error);
68 		if (ah != AH_NULL) {
69 			/* copy back private state to public area */
70 			ah->ah_devid = AH_PRIVATE(ah)->ah_devid;
71 			ah->ah_subvendorid = AH_PRIVATE(ah)->ah_subvendorid;
72 			ah->ah_macVersion = AH_PRIVATE(ah)->ah_macVersion;
73 			ah->ah_macRev = AH_PRIVATE(ah)->ah_macRev;
74 			ah->ah_phyRev = AH_PRIVATE(ah)->ah_phyRev;
75 			ah->ah_analog5GhzRev = AH_PRIVATE(ah)->ah_analog5GhzRev;
76 			ah->ah_analog2GhzRev = AH_PRIVATE(ah)->ah_analog2GhzRev;
77 			return ah;
78 		}
79 	}
80 	return AH_NULL;
81 }
82 
83 const char *
84 ath_hal_mac_name(struct ath_hal *ah)
85 {
86 	switch (ah->ah_macVersion) {
87 	case AR_SREV_VERSION_CRETE:
88 	case AR_SREV_VERSION_MAUI_1:
89 		return "5210";
90 	case AR_SREV_VERSION_MAUI_2:
91 	case AR_SREV_VERSION_OAHU:
92 		return "5211";
93 	case AR_SREV_VERSION_VENICE:
94 		return "5212";
95 	case AR_SREV_VERSION_GRIFFIN:
96 		return "2413";
97 	case AR_SREV_VERSION_CONDOR:
98 		return "5424";
99 	case AR_SREV_VERSION_EAGLE:
100 		return "5413";
101 	case AR_SREV_VERSION_COBRA:
102 		return "2415";
103 	case AR_SREV_2425:
104 		return "2425";
105 	case AR_SREV_2417:
106 		return "2417";
107 	case AR_XSREV_VERSION_OWL_PCI:
108 		return "5416";
109 	case AR_XSREV_VERSION_OWL_PCIE:
110 		return "5418";
111 	case AR_XSREV_VERSION_SOWL:
112 		return "9160";
113 	case AR_XSREV_VERSION_MERLIN:
114 		return "9280";
115 	case AR_XSREV_VERSION_KITE:
116 		return "9285";
117 	}
118 	return "????";
119 }
120 
121 /*
122  * Return the mask of available modes based on the hardware capabilities.
123  */
124 u_int
125 ath_hal_getwirelessmodes(struct ath_hal*ah)
126 {
127 	return ath_hal_getWirelessModes(ah);
128 }
129 
130 /* linker set of registered RF backends */
131 OS_SET_DECLARE(ah_rfs, struct ath_hal_rf);
132 
133 /*
134  * Check the set of registered RF backends to see if
135  * any recognize the device as one they can support.
136  */
137 struct ath_hal_rf *
138 ath_hal_rfprobe(struct ath_hal *ah, HAL_STATUS *ecode)
139 {
140 	struct ath_hal_rf * const *prf;
141 
142 	OS_SET_FOREACH(prf, ah_rfs) {
143 		struct ath_hal_rf *rf = *prf;
144 		if (rf->probe(ah))
145 			return rf;
146 	}
147 	*ecode = HAL_ENOTSUPP;
148 	return AH_NULL;
149 }
150 
151 const char *
152 ath_hal_rf_name(struct ath_hal *ah)
153 {
154 	switch (ah->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR) {
155 	case 0:			/* 5210 */
156 		return "5110";	/* NB: made up */
157 	case AR_RAD5111_SREV_MAJOR:
158 	case AR_RAD5111_SREV_PROD:
159 		return "5111";
160 	case AR_RAD2111_SREV_MAJOR:
161 		return "2111";
162 	case AR_RAD5112_SREV_MAJOR:
163 	case AR_RAD5112_SREV_2_0:
164 	case AR_RAD5112_SREV_2_1:
165 		return "5112";
166 	case AR_RAD2112_SREV_MAJOR:
167 	case AR_RAD2112_SREV_2_0:
168 	case AR_RAD2112_SREV_2_1:
169 		return "2112";
170 	case AR_RAD2413_SREV_MAJOR:
171 		return "2413";
172 	case AR_RAD5413_SREV_MAJOR:
173 		return "5413";
174 	case AR_RAD2316_SREV_MAJOR:
175 		return "2316";
176 	case AR_RAD2317_SREV_MAJOR:
177 		return "2317";
178 	case AR_RAD5424_SREV_MAJOR:
179 		return "5424";
180 
181 	case AR_RAD5133_SREV_MAJOR:
182 		return "5133";
183 	case AR_RAD2133_SREV_MAJOR:
184 		return "2133";
185 	case AR_RAD5122_SREV_MAJOR:
186 		return "5122";
187 	case AR_RAD2122_SREV_MAJOR:
188 		return "2122";
189 	}
190 	return "????";
191 }
192 
193 /*
194  * Poll the register looking for a specific value.
195  */
196 HAL_BOOL
197 ath_hal_wait(struct ath_hal *ah, u_int reg, uint32_t mask, uint32_t val)
198 {
199 #define	AH_TIMEOUT	1000
200 	return ath_hal_waitfor(ah, reg, mask, val, AH_TIMEOUT);
201 #undef AH_TIMEOUT
202 }
203 
204 HAL_BOOL
205 ath_hal_waitfor(struct ath_hal *ah, u_int reg, uint32_t mask, uint32_t val, uint32_t timeout)
206 {
207 	int i;
208 
209 	for (i = 0; i < timeout; i++) {
210 		if ((OS_REG_READ(ah, reg) & mask) == val)
211 			return AH_TRUE;
212 		OS_DELAY(10);
213 	}
214 	HALDEBUG(ah, HAL_DEBUG_REGIO | HAL_DEBUG_PHYIO,
215 	    "%s: timeout on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n",
216 	    __func__, reg, OS_REG_READ(ah, reg), mask, val);
217 	return AH_FALSE;
218 }
219 
220 /*
221  * Reverse the bits starting at the low bit for a value of
222  * bit_count in size
223  */
224 uint32_t
225 ath_hal_reverseBits(uint32_t val, uint32_t n)
226 {
227 	uint32_t retval;
228 	int i;
229 
230 	for (i = 0, retval = 0; i < n; i++) {
231 		retval = (retval << 1) | (val & 1);
232 		val >>= 1;
233 	}
234 	return retval;
235 }
236 
237 /* 802.11n related timing definitions */
238 
239 #define	OFDM_PLCP_BITS	22
240 #define	HT_L_STF	8
241 #define	HT_L_LTF	8
242 #define	HT_L_SIG	4
243 #define	HT_SIG		8
244 #define	HT_STF		4
245 #define	HT_LTF(n)	((n) * 4)
246 
247 #define	HT_RC_2_MCS(_rc)	((_rc) & 0xf)
248 #define	HT_RC_2_STREAMS(_rc)	((((_rc) & 0x78) >> 3) + 1)
249 #define	IS_HT_RATE(_rc)		( (_rc) & IEEE80211_RATE_MCS)
250 
251 /*
252  * Calculate the duration of a packet whether it is 11n or legacy.
253  */
254 uint32_t
255 ath_hal_pkt_txtime(struct ath_hal *ah, const HAL_RATE_TABLE *rates, uint32_t frameLen,
256     uint16_t rateix, HAL_BOOL isht40, HAL_BOOL shortPreamble)
257 {
258 	uint8_t rc;
259 	int numStreams;
260 
261 	rc = rates->info[rateix].rateCode;
262 
263 	/* Legacy rate? Return the old way */
264 	if (! IS_HT_RATE(rc))
265 		return ath_hal_computetxtime(ah, rates, frameLen, rateix, shortPreamble);
266 
267 	/* 11n frame - extract out the number of spatial streams */
268 	numStreams = HT_RC_2_STREAMS(rc);
269 	KASSERT(numStreams == 1 || numStreams == 2, ("number of spatial streams needs to be 1 or 2: MCS rate 0x%x!", rateix));
270 
271 	return ath_computedur_ht(frameLen, rc, numStreams, isht40, shortPreamble);
272 }
273 
274 /*
275  * Calculate the transmit duration of an 11n frame.
276  * This only works for MCS0->MCS15.
277  */
278 uint32_t
279 ath_computedur_ht(uint32_t frameLen, uint16_t rate, int streams, HAL_BOOL isht40,
280     HAL_BOOL isShortGI)
281 {
282 	static const uint16_t ht20_bps[16] = {
283 	    26, 52, 78, 104, 156, 208, 234, 260,
284 	    52, 104, 156, 208, 312, 416, 468, 520
285 	};
286 	static const uint16_t ht40_bps[16] = {
287 	    54, 108, 162, 216, 324, 432, 486, 540,
288 	    108, 216, 324, 432, 648, 864, 972, 1080,
289 	};
290 	uint32_t bitsPerSymbol, numBits, numSymbols, txTime;
291 
292 	KASSERT(rate & IEEE80211_RATE_MCS, ("not mcs %d", rate));
293 	KASSERT((rate &~ IEEE80211_RATE_MCS) < 16, ("bad mcs 0x%x", rate));
294 
295 	if (isht40)
296 		bitsPerSymbol = ht40_bps[rate & 0xf];
297 	else
298 		bitsPerSymbol = ht20_bps[rate & 0xf];
299 	numBits = OFDM_PLCP_BITS + (frameLen << 3);
300 	numSymbols = howmany(numBits, bitsPerSymbol);
301 	if (isShortGI)
302 		txTime = ((numSymbols * 18) + 4) / 5;   /* 3.6us */
303 	else
304 		txTime = numSymbols * 4;                /* 4us */
305 	return txTime + HT_L_STF + HT_L_LTF +
306 	    HT_L_SIG + HT_SIG + HT_STF + HT_LTF(streams);
307 }
308 
309 /*
310  * Compute the time to transmit a frame of length frameLen bytes
311  * using the specified rate, phy, and short preamble setting.
312  */
313 uint16_t
314 ath_hal_computetxtime(struct ath_hal *ah,
315 	const HAL_RATE_TABLE *rates, uint32_t frameLen, uint16_t rateix,
316 	HAL_BOOL shortPreamble)
317 {
318 	uint32_t bitsPerSymbol, numBits, numSymbols, phyTime, txTime;
319 	uint32_t kbps;
320 
321 	/* Warn if this function is called for 11n rates; it should not be! */
322 	if (IS_HT_RATE(rates->info[rateix].rateCode))
323 		ath_hal_printf(ah, "%s: MCS rate? (index %d; hwrate 0x%x)\n",
324 		    __func__, rateix, rates->info[rateix].rateCode);
325 
326 	kbps = rates->info[rateix].rateKbps;
327 	/*
328 	 * index can be invalid duting dynamic Turbo transitions.
329 	 * XXX
330 	 */
331 	if (kbps == 0)
332 		return 0;
333 	switch (rates->info[rateix].phy) {
334 	case IEEE80211_T_CCK:
335 		phyTime		= CCK_PREAMBLE_BITS + CCK_PLCP_BITS;
336 		if (shortPreamble && rates->info[rateix].shortPreamble)
337 			phyTime >>= 1;
338 		numBits		= frameLen << 3;
339 		txTime		= CCK_SIFS_TIME + phyTime
340 				+ ((numBits * 1000)/kbps);
341 		break;
342 	case IEEE80211_T_OFDM:
343 		bitsPerSymbol	= (kbps * OFDM_SYMBOL_TIME) / 1000;
344 		HALASSERT(bitsPerSymbol != 0);
345 
346 		numBits		= OFDM_PLCP_BITS + (frameLen << 3);
347 		numSymbols	= howmany(numBits, bitsPerSymbol);
348 		txTime		= OFDM_SIFS_TIME
349 				+ OFDM_PREAMBLE_TIME
350 				+ (numSymbols * OFDM_SYMBOL_TIME);
351 		break;
352 	case IEEE80211_T_OFDM_HALF:
353 		bitsPerSymbol	= (kbps * OFDM_HALF_SYMBOL_TIME) / 1000;
354 		HALASSERT(bitsPerSymbol != 0);
355 
356 		numBits		= OFDM_HALF_PLCP_BITS + (frameLen << 3);
357 		numSymbols	= howmany(numBits, bitsPerSymbol);
358 		txTime		= OFDM_HALF_SIFS_TIME
359 				+ OFDM_HALF_PREAMBLE_TIME
360 				+ (numSymbols * OFDM_HALF_SYMBOL_TIME);
361 		break;
362 	case IEEE80211_T_OFDM_QUARTER:
363 		bitsPerSymbol	= (kbps * OFDM_QUARTER_SYMBOL_TIME) / 1000;
364 		HALASSERT(bitsPerSymbol != 0);
365 
366 		numBits		= OFDM_QUARTER_PLCP_BITS + (frameLen << 3);
367 		numSymbols	= howmany(numBits, bitsPerSymbol);
368 		txTime		= OFDM_QUARTER_SIFS_TIME
369 				+ OFDM_QUARTER_PREAMBLE_TIME
370 				+ (numSymbols * OFDM_QUARTER_SYMBOL_TIME);
371 		break;
372 	case IEEE80211_T_TURBO:
373 		bitsPerSymbol	= (kbps * TURBO_SYMBOL_TIME) / 1000;
374 		HALASSERT(bitsPerSymbol != 0);
375 
376 		numBits		= TURBO_PLCP_BITS + (frameLen << 3);
377 		numSymbols	= howmany(numBits, bitsPerSymbol);
378 		txTime		= TURBO_SIFS_TIME
379 				+ TURBO_PREAMBLE_TIME
380 				+ (numSymbols * TURBO_SYMBOL_TIME);
381 		break;
382 	default:
383 		HALDEBUG(ah, HAL_DEBUG_PHYIO,
384 		    "%s: unknown phy %u (rate ix %u)\n",
385 		    __func__, rates->info[rateix].phy, rateix);
386 		txTime = 0;
387 		break;
388 	}
389 	return txTime;
390 }
391 
392 typedef enum {
393 	WIRELESS_MODE_11a   = 0,
394 	WIRELESS_MODE_TURBO = 1,
395 	WIRELESS_MODE_11b   = 2,
396 	WIRELESS_MODE_11g   = 3,
397 	WIRELESS_MODE_108g  = 4,
398 
399 	WIRELESS_MODE_MAX
400 } WIRELESS_MODE;
401 
402 static WIRELESS_MODE
403 ath_hal_chan2wmode(struct ath_hal *ah, const struct ieee80211_channel *chan)
404 {
405 	if (IEEE80211_IS_CHAN_B(chan))
406 		return WIRELESS_MODE_11b;
407 	if (IEEE80211_IS_CHAN_G(chan))
408 		return WIRELESS_MODE_11g;
409 	if (IEEE80211_IS_CHAN_108G(chan))
410 		return WIRELESS_MODE_108g;
411 	if (IEEE80211_IS_CHAN_TURBO(chan))
412 		return WIRELESS_MODE_TURBO;
413 	return WIRELESS_MODE_11a;
414 }
415 
416 /*
417  * Convert between microseconds and core system clocks.
418  */
419                                      /* 11a Turbo  11b  11g  108g */
420 static const uint8_t CLOCK_RATE[]  = { 40,  80,   22,  44,   88  };
421 
422 u_int
423 ath_hal_mac_clks(struct ath_hal *ah, u_int usecs)
424 {
425 	const struct ieee80211_channel *c = AH_PRIVATE(ah)->ah_curchan;
426 	u_int clks;
427 
428 	/* NB: ah_curchan may be null when called attach time */
429 	if (c != AH_NULL) {
430 		clks = usecs * CLOCK_RATE[ath_hal_chan2wmode(ah, c)];
431 		if (IEEE80211_IS_CHAN_HT40(c))
432 			clks <<= 1;
433 	} else
434 		clks = usecs * CLOCK_RATE[WIRELESS_MODE_11b];
435 	return clks;
436 }
437 
438 u_int
439 ath_hal_mac_usec(struct ath_hal *ah, u_int clks)
440 {
441 	const struct ieee80211_channel *c = AH_PRIVATE(ah)->ah_curchan;
442 	u_int usec;
443 
444 	/* NB: ah_curchan may be null when called attach time */
445 	if (c != AH_NULL) {
446 		usec = clks / CLOCK_RATE[ath_hal_chan2wmode(ah, c)];
447 		if (IEEE80211_IS_CHAN_HT40(c))
448 			usec >>= 1;
449 	} else
450 		usec = clks / CLOCK_RATE[WIRELESS_MODE_11b];
451 	return usec;
452 }
453 
454 /*
455  * Setup a h/w rate table's reverse lookup table and
456  * fill in ack durations.  This routine is called for
457  * each rate table returned through the ah_getRateTable
458  * method.  The reverse lookup tables are assumed to be
459  * initialized to zero (or at least the first entry).
460  * We use this as a key that indicates whether or not
461  * we've previously setup the reverse lookup table.
462  *
463  * XXX not reentrant, but shouldn't matter
464  */
465 void
466 ath_hal_setupratetable(struct ath_hal *ah, HAL_RATE_TABLE *rt)
467 {
468 #define	N(a)	(sizeof(a)/sizeof(a[0]))
469 	int i;
470 
471 	if (rt->rateCodeToIndex[0] != 0)	/* already setup */
472 		return;
473 	for (i = 0; i < N(rt->rateCodeToIndex); i++)
474 		rt->rateCodeToIndex[i] = (uint8_t) -1;
475 	for (i = 0; i < rt->rateCount; i++) {
476 		uint8_t code = rt->info[i].rateCode;
477 		uint8_t cix = rt->info[i].controlRate;
478 
479 		HALASSERT(code < N(rt->rateCodeToIndex));
480 		rt->rateCodeToIndex[code] = i;
481 		HALASSERT((code | rt->info[i].shortPreamble) <
482 		    N(rt->rateCodeToIndex));
483 		rt->rateCodeToIndex[code | rt->info[i].shortPreamble] = i;
484 		/*
485 		 * XXX for 11g the control rate to use for 5.5 and 11 Mb/s
486 		 *     depends on whether they are marked as basic rates;
487 		 *     the static tables are setup with an 11b-compatible
488 		 *     2Mb/s rate which will work but is suboptimal
489 		 */
490 		rt->info[i].lpAckDuration = ath_hal_computetxtime(ah, rt,
491 			WLAN_CTRL_FRAME_SIZE, cix, AH_FALSE);
492 		rt->info[i].spAckDuration = ath_hal_computetxtime(ah, rt,
493 			WLAN_CTRL_FRAME_SIZE, cix, AH_TRUE);
494 	}
495 #undef N
496 }
497 
498 HAL_STATUS
499 ath_hal_getcapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
500 	uint32_t capability, uint32_t *result)
501 {
502 	const HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;
503 
504 	switch (type) {
505 	case HAL_CAP_REG_DMN:		/* regulatory domain */
506 		*result = AH_PRIVATE(ah)->ah_currentRD;
507 		return HAL_OK;
508 	case HAL_CAP_CIPHER:		/* cipher handled in hardware */
509 	case HAL_CAP_TKIP_MIC:		/* handle TKIP MIC in hardware */
510 		return HAL_ENOTSUPP;
511 	case HAL_CAP_TKIP_SPLIT:	/* hardware TKIP uses split keys */
512 		return HAL_ENOTSUPP;
513 	case HAL_CAP_PHYCOUNTERS:	/* hardware PHY error counters */
514 		return pCap->halHwPhyCounterSupport ? HAL_OK : HAL_ENXIO;
515 	case HAL_CAP_WME_TKIPMIC:   /* hardware can do TKIP MIC when WMM is turned on */
516 		return HAL_ENOTSUPP;
517 	case HAL_CAP_DIVERSITY:		/* hardware supports fast diversity */
518 		return HAL_ENOTSUPP;
519 	case HAL_CAP_KEYCACHE_SIZE:	/* hardware key cache size */
520 		*result =  pCap->halKeyCacheSize;
521 		return HAL_OK;
522 	case HAL_CAP_NUM_TXQUEUES:	/* number of hardware tx queues */
523 		*result = pCap->halTotalQueues;
524 		return HAL_OK;
525 	case HAL_CAP_VEOL:		/* hardware supports virtual EOL */
526 		return pCap->halVEOLSupport ? HAL_OK : HAL_ENOTSUPP;
527 	case HAL_CAP_PSPOLL:		/* hardware PS-Poll support works */
528 		return pCap->halPSPollBroken ? HAL_ENOTSUPP : HAL_OK;
529 	case HAL_CAP_COMPRESSION:
530 		return pCap->halCompressSupport ? HAL_OK : HAL_ENOTSUPP;
531 	case HAL_CAP_BURST:
532 		return pCap->halBurstSupport ? HAL_OK : HAL_ENOTSUPP;
533 	case HAL_CAP_FASTFRAME:
534 		return pCap->halFastFramesSupport ? HAL_OK : HAL_ENOTSUPP;
535 	case HAL_CAP_DIAG:		/* hardware diagnostic support */
536 		*result = AH_PRIVATE(ah)->ah_diagreg;
537 		return HAL_OK;
538 	case HAL_CAP_TXPOW:		/* global tx power limit  */
539 		switch (capability) {
540 		case 0:			/* facility is supported */
541 			return HAL_OK;
542 		case 1:			/* current limit */
543 			*result = AH_PRIVATE(ah)->ah_powerLimit;
544 			return HAL_OK;
545 		case 2:			/* current max tx power */
546 			*result = AH_PRIVATE(ah)->ah_maxPowerLevel;
547 			return HAL_OK;
548 		case 3:			/* scale factor */
549 			*result = AH_PRIVATE(ah)->ah_tpScale;
550 			return HAL_OK;
551 		}
552 		return HAL_ENOTSUPP;
553 	case HAL_CAP_BSSIDMASK:		/* hardware supports bssid mask */
554 		return pCap->halBssIdMaskSupport ? HAL_OK : HAL_ENOTSUPP;
555 	case HAL_CAP_MCAST_KEYSRCH:	/* multicast frame keycache search */
556 		return pCap->halMcastKeySrchSupport ? HAL_OK : HAL_ENOTSUPP;
557 	case HAL_CAP_TSF_ADJUST:	/* hardware has beacon tsf adjust */
558 		return HAL_ENOTSUPP;
559 	case HAL_CAP_RFSILENT:		/* rfsilent support  */
560 		switch (capability) {
561 		case 0:			/* facility is supported */
562 			return pCap->halRfSilentSupport ? HAL_OK : HAL_ENOTSUPP;
563 		case 1:			/* current setting */
564 			return AH_PRIVATE(ah)->ah_rfkillEnabled ?
565 				HAL_OK : HAL_ENOTSUPP;
566 		case 2:			/* rfsilent config */
567 			*result = AH_PRIVATE(ah)->ah_rfsilent;
568 			return HAL_OK;
569 		}
570 		return HAL_ENOTSUPP;
571 	case HAL_CAP_11D:
572 		return HAL_OK;
573 	case HAL_CAP_RXORN_FATAL:	/* HAL_INT_RXORN treated as fatal  */
574 		return AH_PRIVATE(ah)->ah_rxornIsFatal ? HAL_OK : HAL_ENOTSUPP;
575 	case HAL_CAP_HT:
576 		return pCap->halHTSupport ? HAL_OK : HAL_ENOTSUPP;
577 	case HAL_CAP_TX_CHAINMASK:	/* mask of TX chains supported */
578 		*result = pCap->halTxChainMask;
579 		return HAL_OK;
580 	case HAL_CAP_RX_CHAINMASK:	/* mask of RX chains supported */
581 		*result = pCap->halRxChainMask;
582 		return HAL_OK;
583 	case HAL_CAP_RXTSTAMP_PREC:	/* rx desc tstamp precision (bits) */
584 		*result = pCap->halTstampPrecision;
585 		return HAL_OK;
586 	case HAL_CAP_INTRMASK:		/* mask of supported interrupts */
587 		*result = pCap->halIntrMask;
588 		return HAL_OK;
589 	case HAL_CAP_BSSIDMATCH:	/* hardware has disable bssid match */
590 		return pCap->halBssidMatchSupport ? HAL_OK : HAL_ENOTSUPP;
591 	case HAL_CAP_STREAMS:		/* number of 11n spatial streams */
592 		switch (capability) {
593 		case 0:			/* TX */
594 			*result = pCap->halTxStreams;
595 			return HAL_OK;
596 		case 1:			/* RX */
597 			*result = pCap->halRxStreams;
598 			return HAL_OK;
599 		default:
600 			return HAL_ENOTSUPP;
601 		}
602 	case HAP_CAP_SPLIT_4KB_TRANS:	/* hardware handles descriptors straddling 4k page boundary */
603 		return pCap->hal4kbSplitTransSupport ? HAL_OK : HAL_ENOTSUPP;
604 	default:
605 		return HAL_EINVAL;
606 	}
607 }
608 
609 HAL_BOOL
610 ath_hal_setcapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
611 	uint32_t capability, uint32_t setting, HAL_STATUS *status)
612 {
613 
614 	switch (type) {
615 	case HAL_CAP_TXPOW:
616 		switch (capability) {
617 		case 3:
618 			if (setting <= HAL_TP_SCALE_MIN) {
619 				AH_PRIVATE(ah)->ah_tpScale = setting;
620 				return AH_TRUE;
621 			}
622 			break;
623 		}
624 		break;
625 	case HAL_CAP_RFSILENT:		/* rfsilent support  */
626 		/*
627 		 * NB: allow even if halRfSilentSupport is false
628 		 *     in case the EEPROM is misprogrammed.
629 		 */
630 		switch (capability) {
631 		case 1:			/* current setting */
632 			AH_PRIVATE(ah)->ah_rfkillEnabled = (setting != 0);
633 			return AH_TRUE;
634 		case 2:			/* rfsilent config */
635 			/* XXX better done per-chip for validation? */
636 			AH_PRIVATE(ah)->ah_rfsilent = setting;
637 			return AH_TRUE;
638 		}
639 		break;
640 	case HAL_CAP_REG_DMN:		/* regulatory domain */
641 		AH_PRIVATE(ah)->ah_currentRD = setting;
642 		return AH_TRUE;
643 	case HAL_CAP_RXORN_FATAL:	/* HAL_INT_RXORN treated as fatal  */
644 		AH_PRIVATE(ah)->ah_rxornIsFatal = setting;
645 		return AH_TRUE;
646 	default:
647 		break;
648 	}
649 	if (status)
650 		*status = HAL_EINVAL;
651 	return AH_FALSE;
652 }
653 
654 /*
655  * Common support for getDiagState method.
656  */
657 
658 static u_int
659 ath_hal_getregdump(struct ath_hal *ah, const HAL_REGRANGE *regs,
660 	void *dstbuf, int space)
661 {
662 	uint32_t *dp = dstbuf;
663 	int i;
664 
665 	for (i = 0; space >= 2*sizeof(uint32_t); i++) {
666 		u_int r = regs[i].start;
667 		u_int e = regs[i].end;
668 		*dp++ = (r<<16) | e;
669 		space -= sizeof(uint32_t);
670 		do {
671 			*dp++ = OS_REG_READ(ah, r);
672 			r += sizeof(uint32_t);
673 			space -= sizeof(uint32_t);
674 		} while (r <= e && space >= sizeof(uint32_t));
675 	}
676 	return (char *) dp - (char *) dstbuf;
677 }
678 
679 static void
680 ath_hal_setregs(struct ath_hal *ah, const HAL_REGWRITE *regs, int space)
681 {
682 	while (space >= sizeof(HAL_REGWRITE)) {
683 		OS_REG_WRITE(ah, regs->addr, regs->value);
684 		regs++, space -= sizeof(HAL_REGWRITE);
685 	}
686 }
687 
688 HAL_BOOL
689 ath_hal_getdiagstate(struct ath_hal *ah, int request,
690 	const void *args, uint32_t argsize,
691 	void **result, uint32_t *resultsize)
692 {
693 	switch (request) {
694 	case HAL_DIAG_REVS:
695 		*result = &AH_PRIVATE(ah)->ah_devid;
696 		*resultsize = sizeof(HAL_REVS);
697 		return AH_TRUE;
698 	case HAL_DIAG_REGS:
699 		*resultsize = ath_hal_getregdump(ah, args, *result,*resultsize);
700 		return AH_TRUE;
701 	case HAL_DIAG_SETREGS:
702 		ath_hal_setregs(ah, args, argsize);
703 		*resultsize = 0;
704 		return AH_TRUE;
705 	case HAL_DIAG_FATALERR:
706 		*result = &AH_PRIVATE(ah)->ah_fatalState[0];
707 		*resultsize = sizeof(AH_PRIVATE(ah)->ah_fatalState);
708 		return AH_TRUE;
709 	case HAL_DIAG_EEREAD:
710 		if (argsize != sizeof(uint16_t))
711 			return AH_FALSE;
712 		if (!ath_hal_eepromRead(ah, *(const uint16_t *)args, *result))
713 			return AH_FALSE;
714 		*resultsize = sizeof(uint16_t);
715 		return AH_TRUE;
716 #ifdef AH_PRIVATE_DIAG
717 	case HAL_DIAG_SETKEY: {
718 		const HAL_DIAG_KEYVAL *dk;
719 
720 		if (argsize != sizeof(HAL_DIAG_KEYVAL))
721 			return AH_FALSE;
722 		dk = (const HAL_DIAG_KEYVAL *)args;
723 		return ah->ah_setKeyCacheEntry(ah, dk->dk_keyix,
724 			&dk->dk_keyval, dk->dk_mac, dk->dk_xor);
725 	}
726 	case HAL_DIAG_RESETKEY:
727 		if (argsize != sizeof(uint16_t))
728 			return AH_FALSE;
729 		return ah->ah_resetKeyCacheEntry(ah, *(const uint16_t *)args);
730 #ifdef AH_SUPPORT_WRITE_EEPROM
731 	case HAL_DIAG_EEWRITE: {
732 		const HAL_DIAG_EEVAL *ee;
733 		if (argsize != sizeof(HAL_DIAG_EEVAL))
734 			return AH_FALSE;
735 		ee = (const HAL_DIAG_EEVAL *)args;
736 		return ath_hal_eepromWrite(ah, ee->ee_off, ee->ee_data);
737 	}
738 #endif /* AH_SUPPORT_WRITE_EEPROM */
739 #endif /* AH_PRIVATE_DIAG */
740 	case HAL_DIAG_11NCOMPAT:
741 		if (argsize == 0) {
742 			*resultsize = sizeof(uint32_t);
743 			*((uint32_t *)(*result)) =
744 				AH_PRIVATE(ah)->ah_11nCompat;
745 		} else if (argsize == sizeof(uint32_t)) {
746 			AH_PRIVATE(ah)->ah_11nCompat = *(const uint32_t *)args;
747 		} else
748 			return AH_FALSE;
749 		return AH_TRUE;
750 	}
751 	return AH_FALSE;
752 }
753 
754 /*
755  * Set the properties of the tx queue with the parameters
756  * from qInfo.
757  */
758 HAL_BOOL
759 ath_hal_setTxQProps(struct ath_hal *ah,
760 	HAL_TX_QUEUE_INFO *qi, const HAL_TXQ_INFO *qInfo)
761 {
762 	uint32_t cw;
763 
764 	if (qi->tqi_type == HAL_TX_QUEUE_INACTIVE) {
765 		HALDEBUG(ah, HAL_DEBUG_TXQUEUE,
766 		    "%s: inactive queue\n", __func__);
767 		return AH_FALSE;
768 	}
769 	/* XXX validate parameters */
770 	qi->tqi_ver = qInfo->tqi_ver;
771 	qi->tqi_subtype = qInfo->tqi_subtype;
772 	qi->tqi_qflags = qInfo->tqi_qflags;
773 	qi->tqi_priority = qInfo->tqi_priority;
774 	if (qInfo->tqi_aifs != HAL_TXQ_USEDEFAULT)
775 		qi->tqi_aifs = AH_MIN(qInfo->tqi_aifs, 255);
776 	else
777 		qi->tqi_aifs = INIT_AIFS;
778 	if (qInfo->tqi_cwmin != HAL_TXQ_USEDEFAULT) {
779 		cw = AH_MIN(qInfo->tqi_cwmin, 1024);
780 		/* make sure that the CWmin is of the form (2^n - 1) */
781 		qi->tqi_cwmin = 1;
782 		while (qi->tqi_cwmin < cw)
783 			qi->tqi_cwmin = (qi->tqi_cwmin << 1) | 1;
784 	} else
785 		qi->tqi_cwmin = qInfo->tqi_cwmin;
786 	if (qInfo->tqi_cwmax != HAL_TXQ_USEDEFAULT) {
787 		cw = AH_MIN(qInfo->tqi_cwmax, 1024);
788 		/* make sure that the CWmax is of the form (2^n - 1) */
789 		qi->tqi_cwmax = 1;
790 		while (qi->tqi_cwmax < cw)
791 			qi->tqi_cwmax = (qi->tqi_cwmax << 1) | 1;
792 	} else
793 		qi->tqi_cwmax = INIT_CWMAX;
794 	/* Set retry limit values */
795 	if (qInfo->tqi_shretry != 0)
796 		qi->tqi_shretry = AH_MIN(qInfo->tqi_shretry, 15);
797 	else
798 		qi->tqi_shretry = INIT_SH_RETRY;
799 	if (qInfo->tqi_lgretry != 0)
800 		qi->tqi_lgretry = AH_MIN(qInfo->tqi_lgretry, 15);
801 	else
802 		qi->tqi_lgretry = INIT_LG_RETRY;
803 	qi->tqi_cbrPeriod = qInfo->tqi_cbrPeriod;
804 	qi->tqi_cbrOverflowLimit = qInfo->tqi_cbrOverflowLimit;
805 	qi->tqi_burstTime = qInfo->tqi_burstTime;
806 	qi->tqi_readyTime = qInfo->tqi_readyTime;
807 
808 	switch (qInfo->tqi_subtype) {
809 	case HAL_WME_UPSD:
810 		if (qi->tqi_type == HAL_TX_QUEUE_DATA)
811 			qi->tqi_intFlags = HAL_TXQ_USE_LOCKOUT_BKOFF_DIS;
812 		break;
813 	default:
814 		break;		/* NB: silence compiler */
815 	}
816 	return AH_TRUE;
817 }
818 
819 HAL_BOOL
820 ath_hal_getTxQProps(struct ath_hal *ah,
821 	HAL_TXQ_INFO *qInfo, const HAL_TX_QUEUE_INFO *qi)
822 {
823 	if (qi->tqi_type == HAL_TX_QUEUE_INACTIVE) {
824 		HALDEBUG(ah, HAL_DEBUG_TXQUEUE,
825 		    "%s: inactive queue\n", __func__);
826 		return AH_FALSE;
827 	}
828 
829 	qInfo->tqi_qflags = qi->tqi_qflags;
830 	qInfo->tqi_ver = qi->tqi_ver;
831 	qInfo->tqi_subtype = qi->tqi_subtype;
832 	qInfo->tqi_qflags = qi->tqi_qflags;
833 	qInfo->tqi_priority = qi->tqi_priority;
834 	qInfo->tqi_aifs = qi->tqi_aifs;
835 	qInfo->tqi_cwmin = qi->tqi_cwmin;
836 	qInfo->tqi_cwmax = qi->tqi_cwmax;
837 	qInfo->tqi_shretry = qi->tqi_shretry;
838 	qInfo->tqi_lgretry = qi->tqi_lgretry;
839 	qInfo->tqi_cbrPeriod = qi->tqi_cbrPeriod;
840 	qInfo->tqi_cbrOverflowLimit = qi->tqi_cbrOverflowLimit;
841 	qInfo->tqi_burstTime = qi->tqi_burstTime;
842 	qInfo->tqi_readyTime = qi->tqi_readyTime;
843 	return AH_TRUE;
844 }
845 
846                                      /* 11a Turbo  11b  11g  108g */
847 static const int16_t NOISE_FLOOR[] = { -96, -93,  -98, -96,  -93 };
848 
849 /*
850  * Read the current channel noise floor and return.
851  * If nf cal hasn't finished, channel noise floor should be 0
852  * and we return a nominal value based on band and frequency.
853  *
854  * NB: This is a private routine used by per-chip code to
855  *     implement the ah_getChanNoise method.
856  */
857 int16_t
858 ath_hal_getChanNoise(struct ath_hal *ah, const struct ieee80211_channel *chan)
859 {
860 	HAL_CHANNEL_INTERNAL *ichan;
861 
862 	ichan = ath_hal_checkchannel(ah, chan);
863 	if (ichan == AH_NULL) {
864 		HALDEBUG(ah, HAL_DEBUG_NFCAL,
865 		    "%s: invalid channel %u/0x%x; no mapping\n",
866 		    __func__, chan->ic_freq, chan->ic_flags);
867 		return 0;
868 	}
869 	if (ichan->rawNoiseFloor == 0) {
870 		WIRELESS_MODE mode = ath_hal_chan2wmode(ah, chan);
871 
872 		HALASSERT(mode < WIRELESS_MODE_MAX);
873 		return NOISE_FLOOR[mode] + ath_hal_getNfAdjust(ah, ichan);
874 	} else
875 		return ichan->rawNoiseFloor + ichan->noiseFloorAdjust;
876 }
877 
878 /*
879  * Process all valid raw noise floors into the dBm noise floor values.
880  * Though our device has no reference for a dBm noise floor, we perform
881  * a relative minimization of NF's based on the lowest NF found across a
882  * channel scan.
883  */
884 void
885 ath_hal_process_noisefloor(struct ath_hal *ah)
886 {
887 	HAL_CHANNEL_INTERNAL *c;
888 	int16_t correct2, correct5;
889 	int16_t lowest2, lowest5;
890 	int i;
891 
892 	/*
893 	 * Find the lowest 2GHz and 5GHz noise floor values after adjusting
894 	 * for statistically recorded NF/channel deviation.
895 	 */
896 	correct2 = lowest2 = 0;
897 	correct5 = lowest5 = 0;
898 	for (i = 0; i < AH_PRIVATE(ah)->ah_nchan; i++) {
899 		WIRELESS_MODE mode;
900 		int16_t nf;
901 
902 		c = &AH_PRIVATE(ah)->ah_channels[i];
903 		if (c->rawNoiseFloor >= 0)
904 			continue;
905 		/* XXX can't identify proper mode */
906 		mode = IS_CHAN_5GHZ(c) ? WIRELESS_MODE_11a : WIRELESS_MODE_11g;
907 		nf = c->rawNoiseFloor + NOISE_FLOOR[mode] +
908 			ath_hal_getNfAdjust(ah, c);
909 		if (IS_CHAN_5GHZ(c)) {
910 			if (nf < lowest5) {
911 				lowest5 = nf;
912 				correct5 = NOISE_FLOOR[mode] -
913 				    (c->rawNoiseFloor + ath_hal_getNfAdjust(ah, c));
914 			}
915 		} else {
916 			if (nf < lowest2) {
917 				lowest2 = nf;
918 				correct2 = NOISE_FLOOR[mode] -
919 				    (c->rawNoiseFloor + ath_hal_getNfAdjust(ah, c));
920 			}
921 		}
922 	}
923 
924 	/* Correct the channels to reach the expected NF value */
925 	for (i = 0; i < AH_PRIVATE(ah)->ah_nchan; i++) {
926 		c = &AH_PRIVATE(ah)->ah_channels[i];
927 		if (c->rawNoiseFloor >= 0)
928 			continue;
929 		/* Apply correction factor */
930 		c->noiseFloorAdjust = ath_hal_getNfAdjust(ah, c) +
931 			(IS_CHAN_5GHZ(c) ? correct5 : correct2);
932 		HALDEBUG(ah, HAL_DEBUG_NFCAL, "%u raw nf %d adjust %d\n",
933 		    c->channel, c->rawNoiseFloor, c->noiseFloorAdjust);
934 	}
935 }
936 
937 /*
938  * INI support routines.
939  */
940 
941 int
942 ath_hal_ini_write(struct ath_hal *ah, const HAL_INI_ARRAY *ia,
943 	int col, int regWr)
944 {
945 	int r;
946 
947 	HALASSERT(col < ia->cols);
948 	for (r = 0; r < ia->rows; r++) {
949 		OS_REG_WRITE(ah, HAL_INI_VAL(ia, r, 0),
950 		    HAL_INI_VAL(ia, r, col));
951 
952 		/* Analog shift register delay seems needed for Merlin - PR kern/154220 */
953 		if (HAL_INI_VAL(ia, r, 0) >= 0x7800 && HAL_INI_VAL(ia, r, 0) < 0x78a0)
954 			OS_DELAY(100);
955 
956 		DMA_YIELD(regWr);
957 	}
958 	return regWr;
959 }
960 
961 void
962 ath_hal_ini_bank_setup(uint32_t data[], const HAL_INI_ARRAY *ia, int col)
963 {
964 	int r;
965 
966 	HALASSERT(col < ia->cols);
967 	for (r = 0; r < ia->rows; r++)
968 		data[r] = HAL_INI_VAL(ia, r, col);
969 }
970 
971 int
972 ath_hal_ini_bank_write(struct ath_hal *ah, const HAL_INI_ARRAY *ia,
973 	const uint32_t data[], int regWr)
974 {
975 	int r;
976 
977 	for (r = 0; r < ia->rows; r++) {
978 		OS_REG_WRITE(ah, HAL_INI_VAL(ia, r, 0), data[r]);
979 
980 		/* Analog shift register delay seems needed for Merlin - PR kern/154220 */
981 		/* XXX verify whether any analog radio bank writes will hit up this */
982 		/* XXX since this is a merlin work-around; and merlin doesn't use radio banks */
983 		if (HAL_INI_VAL(ia, r, 0) >= 0x7800 && HAL_INI_VAL(ia, r, 0) < 0x78a0)
984 			OS_DELAY(100);
985 		DMA_YIELD(regWr);
986 	}
987 	return regWr;
988 }
989