xref: /freebsd/sys/dev/ath/ath_hal/ah.c (revision d9f0ce31900a48d1a2bfc1c8c86f79d1e831451a)
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 #include "ah_eeprom.h"			/* for 5ghz fast clock flag */
25 
26 #include "ar5416/ar5416reg.h"		/* NB: includes ar5212reg.h */
27 #include "ar9003/ar9300_devid.h"
28 
29 /* linker set of registered chips */
30 OS_SET_DECLARE(ah_chips, struct ath_hal_chip);
31 
32 /*
33  * Check the set of registered chips to see if any recognize
34  * the device as one they can support.
35  */
36 const char*
37 ath_hal_probe(uint16_t vendorid, uint16_t devid)
38 {
39 	struct ath_hal_chip * const *pchip;
40 
41 	OS_SET_FOREACH(pchip, ah_chips) {
42 		const char *name = (*pchip)->probe(vendorid, devid);
43 		if (name != AH_NULL)
44 			return name;
45 	}
46 	return AH_NULL;
47 }
48 
49 /*
50  * Attach detects device chip revisions, initializes the hwLayer
51  * function list, reads EEPROM information,
52  * selects reset vectors, and performs a short self test.
53  * Any failures will return an error that should cause a hardware
54  * disable.
55  */
56 struct ath_hal*
57 ath_hal_attach(uint16_t devid, HAL_SOFTC sc,
58 	HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata,
59 	HAL_OPS_CONFIG *ah_config,
60 	HAL_STATUS *error)
61 {
62 	struct ath_hal_chip * const *pchip;
63 
64 	OS_SET_FOREACH(pchip, ah_chips) {
65 		struct ath_hal_chip *chip = *pchip;
66 		struct ath_hal *ah;
67 
68 		/* XXX don't have vendorid, assume atheros one works */
69 		if (chip->probe(ATHEROS_VENDOR_ID, devid) == AH_NULL)
70 			continue;
71 		ah = chip->attach(devid, sc, st, sh, eepromdata, ah_config,
72 		    error);
73 		if (ah != AH_NULL) {
74 			/* copy back private state to public area */
75 			ah->ah_devid = AH_PRIVATE(ah)->ah_devid;
76 			ah->ah_subvendorid = AH_PRIVATE(ah)->ah_subvendorid;
77 			ah->ah_macVersion = AH_PRIVATE(ah)->ah_macVersion;
78 			ah->ah_macRev = AH_PRIVATE(ah)->ah_macRev;
79 			ah->ah_phyRev = AH_PRIVATE(ah)->ah_phyRev;
80 			ah->ah_analog5GhzRev = AH_PRIVATE(ah)->ah_analog5GhzRev;
81 			ah->ah_analog2GhzRev = AH_PRIVATE(ah)->ah_analog2GhzRev;
82 			return ah;
83 		}
84 	}
85 	return AH_NULL;
86 }
87 
88 const char *
89 ath_hal_mac_name(struct ath_hal *ah)
90 {
91 	switch (ah->ah_macVersion) {
92 	case AR_SREV_VERSION_CRETE:
93 	case AR_SREV_VERSION_MAUI_1:
94 		return "AR5210";
95 	case AR_SREV_VERSION_MAUI_2:
96 	case AR_SREV_VERSION_OAHU:
97 		return "AR5211";
98 	case AR_SREV_VERSION_VENICE:
99 		return "AR5212";
100 	case AR_SREV_VERSION_GRIFFIN:
101 		return "AR2413";
102 	case AR_SREV_VERSION_CONDOR:
103 		return "AR5424";
104 	case AR_SREV_VERSION_EAGLE:
105 		return "AR5413";
106 	case AR_SREV_VERSION_COBRA:
107 		return "AR2415";
108 	case AR_SREV_2425:	/* Swan */
109 		return "AR2425";
110 	case AR_SREV_2417:	/* Nala */
111 		return "AR2417";
112 	case AR_XSREV_VERSION_OWL_PCI:
113 		return "AR5416";
114 	case AR_XSREV_VERSION_OWL_PCIE:
115 		return "AR5418";
116 	case AR_XSREV_VERSION_HOWL:
117 		return "AR9130";
118 	case AR_XSREV_VERSION_SOWL:
119 		return "AR9160";
120 	case AR_XSREV_VERSION_MERLIN:
121 		if (AH_PRIVATE(ah)->ah_ispcie)
122 			return "AR9280";
123 		return "AR9220";
124 	case AR_XSREV_VERSION_KITE:
125 		return "AR9285";
126 	case AR_XSREV_VERSION_KIWI:
127 		if (AH_PRIVATE(ah)->ah_ispcie)
128 			return "AR9287";
129 		return "AR9227";
130 	case AR_SREV_VERSION_AR9380:
131 		if (ah->ah_macRev >= AR_SREV_REVISION_AR9580_10)
132 			return "AR9580";
133 		return "AR9380";
134 	case AR_SREV_VERSION_AR9460:
135 		return "AR9460";
136 	case AR_SREV_VERSION_AR9330:
137 		return "AR9330";
138 	case AR_SREV_VERSION_AR9340:
139 		return "AR9340";
140 	case AR_SREV_VERSION_QCA9550:
141 		return "QCA9550";
142 	case AR_SREV_VERSION_AR9485:
143 		return "AR9485";
144 	case AR_SREV_VERSION_QCA9565:
145 		return "QCA9565";
146 	case AR_SREV_VERSION_QCA9530:
147 		return "QCA9530";
148 	}
149 	return "????";
150 }
151 
152 /*
153  * Return the mask of available modes based on the hardware capabilities.
154  */
155 u_int
156 ath_hal_getwirelessmodes(struct ath_hal*ah)
157 {
158 	return ath_hal_getWirelessModes(ah);
159 }
160 
161 /* linker set of registered RF backends */
162 OS_SET_DECLARE(ah_rfs, struct ath_hal_rf);
163 
164 /*
165  * Check the set of registered RF backends to see if
166  * any recognize the device as one they can support.
167  */
168 struct ath_hal_rf *
169 ath_hal_rfprobe(struct ath_hal *ah, HAL_STATUS *ecode)
170 {
171 	struct ath_hal_rf * const *prf;
172 
173 	OS_SET_FOREACH(prf, ah_rfs) {
174 		struct ath_hal_rf *rf = *prf;
175 		if (rf->probe(ah))
176 			return rf;
177 	}
178 	*ecode = HAL_ENOTSUPP;
179 	return AH_NULL;
180 }
181 
182 const char *
183 ath_hal_rf_name(struct ath_hal *ah)
184 {
185 	switch (ah->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR) {
186 	case 0:			/* 5210 */
187 		return "5110";	/* NB: made up */
188 	case AR_RAD5111_SREV_MAJOR:
189 	case AR_RAD5111_SREV_PROD:
190 		return "5111";
191 	case AR_RAD2111_SREV_MAJOR:
192 		return "2111";
193 	case AR_RAD5112_SREV_MAJOR:
194 	case AR_RAD5112_SREV_2_0:
195 	case AR_RAD5112_SREV_2_1:
196 		return "5112";
197 	case AR_RAD2112_SREV_MAJOR:
198 	case AR_RAD2112_SREV_2_0:
199 	case AR_RAD2112_SREV_2_1:
200 		return "2112";
201 	case AR_RAD2413_SREV_MAJOR:
202 		return "2413";
203 	case AR_RAD5413_SREV_MAJOR:
204 		return "5413";
205 	case AR_RAD2316_SREV_MAJOR:
206 		return "2316";
207 	case AR_RAD2317_SREV_MAJOR:
208 		return "2317";
209 	case AR_RAD5424_SREV_MAJOR:
210 		return "5424";
211 
212 	case AR_RAD5133_SREV_MAJOR:
213 		return "5133";
214 	case AR_RAD2133_SREV_MAJOR:
215 		return "2133";
216 	case AR_RAD5122_SREV_MAJOR:
217 		return "5122";
218 	case AR_RAD2122_SREV_MAJOR:
219 		return "2122";
220 	}
221 	return "????";
222 }
223 
224 /*
225  * Poll the register looking for a specific value.
226  */
227 HAL_BOOL
228 ath_hal_wait(struct ath_hal *ah, u_int reg, uint32_t mask, uint32_t val)
229 {
230 #define	AH_TIMEOUT	1000
231 	return ath_hal_waitfor(ah, reg, mask, val, AH_TIMEOUT);
232 #undef AH_TIMEOUT
233 }
234 
235 HAL_BOOL
236 ath_hal_waitfor(struct ath_hal *ah, u_int reg, uint32_t mask, uint32_t val, uint32_t timeout)
237 {
238 	int i;
239 
240 	for (i = 0; i < timeout; i++) {
241 		if ((OS_REG_READ(ah, reg) & mask) == val)
242 			return AH_TRUE;
243 		OS_DELAY(10);
244 	}
245 	HALDEBUG(ah, HAL_DEBUG_REGIO | HAL_DEBUG_PHYIO,
246 	    "%s: timeout on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n",
247 	    __func__, reg, OS_REG_READ(ah, reg), mask, val);
248 	return AH_FALSE;
249 }
250 
251 /*
252  * Reverse the bits starting at the low bit for a value of
253  * bit_count in size
254  */
255 uint32_t
256 ath_hal_reverseBits(uint32_t val, uint32_t n)
257 {
258 	uint32_t retval;
259 	int i;
260 
261 	for (i = 0, retval = 0; i < n; i++) {
262 		retval = (retval << 1) | (val & 1);
263 		val >>= 1;
264 	}
265 	return retval;
266 }
267 
268 /* 802.11n related timing definitions */
269 
270 #define	OFDM_PLCP_BITS	22
271 #define	HT_L_STF	8
272 #define	HT_L_LTF	8
273 #define	HT_L_SIG	4
274 #define	HT_SIG		8
275 #define	HT_STF		4
276 #define	HT_LTF(n)	((n) * 4)
277 
278 #define	HT_RC_2_MCS(_rc)	((_rc) & 0xf)
279 #define	HT_RC_2_STREAMS(_rc)	((((_rc) & 0x78) >> 3) + 1)
280 #define	IS_HT_RATE(_rc)		( (_rc) & IEEE80211_RATE_MCS)
281 
282 /*
283  * Calculate the duration of a packet whether it is 11n or legacy.
284  */
285 uint32_t
286 ath_hal_pkt_txtime(struct ath_hal *ah, const HAL_RATE_TABLE *rates, uint32_t frameLen,
287     uint16_t rateix, HAL_BOOL isht40, HAL_BOOL shortPreamble)
288 {
289 	uint8_t rc;
290 	int numStreams;
291 
292 	rc = rates->info[rateix].rateCode;
293 
294 	/* Legacy rate? Return the old way */
295 	if (! IS_HT_RATE(rc))
296 		return ath_hal_computetxtime(ah, rates, frameLen, rateix, shortPreamble);
297 
298 	/* 11n frame - extract out the number of spatial streams */
299 	numStreams = HT_RC_2_STREAMS(rc);
300 	KASSERT(numStreams > 0 && numStreams <= 4,
301 	    ("number of spatial streams needs to be 1..3: MCS rate 0x%x!",
302 	    rateix));
303 
304 	return ath_computedur_ht(frameLen, rc, numStreams, isht40, shortPreamble);
305 }
306 
307 static const uint16_t ht20_bps[32] = {
308     26, 52, 78, 104, 156, 208, 234, 260,
309     52, 104, 156, 208, 312, 416, 468, 520,
310     78, 156, 234, 312, 468, 624, 702, 780,
311     104, 208, 312, 416, 624, 832, 936, 1040
312 };
313 static const uint16_t ht40_bps[32] = {
314     54, 108, 162, 216, 324, 432, 486, 540,
315     108, 216, 324, 432, 648, 864, 972, 1080,
316     162, 324, 486, 648, 972, 1296, 1458, 1620,
317     216, 432, 648, 864, 1296, 1728, 1944, 2160
318 };
319 
320 /*
321  * Calculate the transmit duration of an 11n frame.
322  */
323 uint32_t
324 ath_computedur_ht(uint32_t frameLen, uint16_t rate, int streams,
325     HAL_BOOL isht40, HAL_BOOL isShortGI)
326 {
327 	uint32_t bitsPerSymbol, numBits, numSymbols, txTime;
328 
329 	KASSERT(rate & IEEE80211_RATE_MCS, ("not mcs %d", rate));
330 	KASSERT((rate &~ IEEE80211_RATE_MCS) < 31, ("bad mcs 0x%x", rate));
331 
332 	if (isht40)
333 		bitsPerSymbol = ht40_bps[rate & 0x1f];
334 	else
335 		bitsPerSymbol = ht20_bps[rate & 0x1f];
336 	numBits = OFDM_PLCP_BITS + (frameLen << 3);
337 	numSymbols = howmany(numBits, bitsPerSymbol);
338 	if (isShortGI)
339 		txTime = ((numSymbols * 18) + 4) / 5;   /* 3.6us */
340 	else
341 		txTime = numSymbols * 4;                /* 4us */
342 	return txTime + HT_L_STF + HT_L_LTF +
343 	    HT_L_SIG + HT_SIG + HT_STF + HT_LTF(streams);
344 }
345 
346 /*
347  * Compute the time to transmit a frame of length frameLen bytes
348  * using the specified rate, phy, and short preamble setting.
349  */
350 uint16_t
351 ath_hal_computetxtime(struct ath_hal *ah,
352 	const HAL_RATE_TABLE *rates, uint32_t frameLen, uint16_t rateix,
353 	HAL_BOOL shortPreamble)
354 {
355 	uint32_t bitsPerSymbol, numBits, numSymbols, phyTime, txTime;
356 	uint32_t kbps;
357 
358 	/* Warn if this function is called for 11n rates; it should not be! */
359 	if (IS_HT_RATE(rates->info[rateix].rateCode))
360 		ath_hal_printf(ah, "%s: MCS rate? (index %d; hwrate 0x%x)\n",
361 		    __func__, rateix, rates->info[rateix].rateCode);
362 
363 	kbps = rates->info[rateix].rateKbps;
364 	/*
365 	 * index can be invalid duting dynamic Turbo transitions.
366 	 * XXX
367 	 */
368 	if (kbps == 0)
369 		return 0;
370 	switch (rates->info[rateix].phy) {
371 	case IEEE80211_T_CCK:
372 		phyTime		= CCK_PREAMBLE_BITS + CCK_PLCP_BITS;
373 		if (shortPreamble && rates->info[rateix].shortPreamble)
374 			phyTime >>= 1;
375 		numBits		= frameLen << 3;
376 		txTime		= CCK_SIFS_TIME + phyTime
377 				+ ((numBits * 1000)/kbps);
378 		break;
379 	case IEEE80211_T_OFDM:
380 		bitsPerSymbol	= (kbps * OFDM_SYMBOL_TIME) / 1000;
381 		HALASSERT(bitsPerSymbol != 0);
382 
383 		numBits		= OFDM_PLCP_BITS + (frameLen << 3);
384 		numSymbols	= howmany(numBits, bitsPerSymbol);
385 		txTime		= OFDM_SIFS_TIME
386 				+ OFDM_PREAMBLE_TIME
387 				+ (numSymbols * OFDM_SYMBOL_TIME);
388 		break;
389 	case IEEE80211_T_OFDM_HALF:
390 		bitsPerSymbol	= (kbps * OFDM_HALF_SYMBOL_TIME) / 1000;
391 		HALASSERT(bitsPerSymbol != 0);
392 
393 		numBits		= OFDM_HALF_PLCP_BITS + (frameLen << 3);
394 		numSymbols	= howmany(numBits, bitsPerSymbol);
395 		txTime		= OFDM_HALF_SIFS_TIME
396 				+ OFDM_HALF_PREAMBLE_TIME
397 				+ (numSymbols * OFDM_HALF_SYMBOL_TIME);
398 		break;
399 	case IEEE80211_T_OFDM_QUARTER:
400 		bitsPerSymbol	= (kbps * OFDM_QUARTER_SYMBOL_TIME) / 1000;
401 		HALASSERT(bitsPerSymbol != 0);
402 
403 		numBits		= OFDM_QUARTER_PLCP_BITS + (frameLen << 3);
404 		numSymbols	= howmany(numBits, bitsPerSymbol);
405 		txTime		= OFDM_QUARTER_SIFS_TIME
406 				+ OFDM_QUARTER_PREAMBLE_TIME
407 				+ (numSymbols * OFDM_QUARTER_SYMBOL_TIME);
408 		break;
409 	case IEEE80211_T_TURBO:
410 		bitsPerSymbol	= (kbps * TURBO_SYMBOL_TIME) / 1000;
411 		HALASSERT(bitsPerSymbol != 0);
412 
413 		numBits		= TURBO_PLCP_BITS + (frameLen << 3);
414 		numSymbols	= howmany(numBits, bitsPerSymbol);
415 		txTime		= TURBO_SIFS_TIME
416 				+ TURBO_PREAMBLE_TIME
417 				+ (numSymbols * TURBO_SYMBOL_TIME);
418 		break;
419 	default:
420 		HALDEBUG(ah, HAL_DEBUG_PHYIO,
421 		    "%s: unknown phy %u (rate ix %u)\n",
422 		    __func__, rates->info[rateix].phy, rateix);
423 		txTime = 0;
424 		break;
425 	}
426 	return txTime;
427 }
428 
429 int
430 ath_hal_get_curmode(struct ath_hal *ah, const struct ieee80211_channel *chan)
431 {
432 	/*
433 	 * Pick a default mode at bootup. A channel change is inevitable.
434 	 */
435 	if (!chan)
436 		return HAL_MODE_11NG_HT20;
437 
438 	if (IEEE80211_IS_CHAN_TURBO(chan))
439 		return HAL_MODE_TURBO;
440 
441 	/* check for NA_HT before plain A, since IS_CHAN_A includes NA_HT */
442 	if (IEEE80211_IS_CHAN_5GHZ(chan) && IEEE80211_IS_CHAN_HT20(chan))
443 		return HAL_MODE_11NA_HT20;
444 	if (IEEE80211_IS_CHAN_5GHZ(chan) && IEEE80211_IS_CHAN_HT40U(chan))
445 		return HAL_MODE_11NA_HT40PLUS;
446 	if (IEEE80211_IS_CHAN_5GHZ(chan) && IEEE80211_IS_CHAN_HT40D(chan))
447 		return HAL_MODE_11NA_HT40MINUS;
448 	if (IEEE80211_IS_CHAN_A(chan))
449 		return HAL_MODE_11A;
450 
451 	/* check for NG_HT before plain G, since IS_CHAN_G includes NG_HT */
452 	if (IEEE80211_IS_CHAN_2GHZ(chan) && IEEE80211_IS_CHAN_HT20(chan))
453 		return HAL_MODE_11NG_HT20;
454 	if (IEEE80211_IS_CHAN_2GHZ(chan) && IEEE80211_IS_CHAN_HT40U(chan))
455 		return HAL_MODE_11NG_HT40PLUS;
456 	if (IEEE80211_IS_CHAN_2GHZ(chan) && IEEE80211_IS_CHAN_HT40D(chan))
457 		return HAL_MODE_11NG_HT40MINUS;
458 
459 	/*
460 	 * XXX For FreeBSD, will this work correctly given the DYN
461 	 * chan mode (OFDM+CCK dynamic) ? We have pure-G versions DYN-BG..
462 	 */
463 	if (IEEE80211_IS_CHAN_G(chan))
464 		return HAL_MODE_11G;
465 	if (IEEE80211_IS_CHAN_B(chan))
466 		return HAL_MODE_11B;
467 
468 	HALASSERT(0);
469 	return HAL_MODE_11NG_HT20;
470 }
471 
472 
473 typedef enum {
474 	WIRELESS_MODE_11a   = 0,
475 	WIRELESS_MODE_TURBO = 1,
476 	WIRELESS_MODE_11b   = 2,
477 	WIRELESS_MODE_11g   = 3,
478 	WIRELESS_MODE_108g  = 4,
479 
480 	WIRELESS_MODE_MAX
481 } WIRELESS_MODE;
482 
483 static WIRELESS_MODE
484 ath_hal_chan2wmode(struct ath_hal *ah, const struct ieee80211_channel *chan)
485 {
486 	if (IEEE80211_IS_CHAN_B(chan))
487 		return WIRELESS_MODE_11b;
488 	if (IEEE80211_IS_CHAN_G(chan))
489 		return WIRELESS_MODE_11g;
490 	if (IEEE80211_IS_CHAN_108G(chan))
491 		return WIRELESS_MODE_108g;
492 	if (IEEE80211_IS_CHAN_TURBO(chan))
493 		return WIRELESS_MODE_TURBO;
494 	return WIRELESS_MODE_11a;
495 }
496 
497 /*
498  * Convert between microseconds and core system clocks.
499  */
500                                      /* 11a Turbo  11b  11g  108g */
501 static const uint8_t CLOCK_RATE[]  = { 40,  80,   22,  44,   88  };
502 
503 #define	CLOCK_FAST_RATE_5GHZ_OFDM	44
504 
505 u_int
506 ath_hal_mac_clks(struct ath_hal *ah, u_int usecs)
507 {
508 	const struct ieee80211_channel *c = AH_PRIVATE(ah)->ah_curchan;
509 	u_int clks;
510 
511 	/* NB: ah_curchan may be null when called attach time */
512 	/* XXX merlin and later specific workaround - 5ghz fast clock is 44 */
513 	if (c != AH_NULL && IS_5GHZ_FAST_CLOCK_EN(ah, c)) {
514 		clks = usecs * CLOCK_FAST_RATE_5GHZ_OFDM;
515 		if (IEEE80211_IS_CHAN_HT40(c))
516 			clks <<= 1;
517 	} else if (c != AH_NULL) {
518 		clks = usecs * CLOCK_RATE[ath_hal_chan2wmode(ah, c)];
519 		if (IEEE80211_IS_CHAN_HT40(c))
520 			clks <<= 1;
521 	} else
522 		clks = usecs * CLOCK_RATE[WIRELESS_MODE_11b];
523 
524 	/* Compensate for half/quarter rate */
525 	if (c != AH_NULL && IEEE80211_IS_CHAN_HALF(c))
526 		clks = clks / 2;
527 	else if (c != AH_NULL && IEEE80211_IS_CHAN_QUARTER(c))
528 		clks = clks / 4;
529 
530 	return clks;
531 }
532 
533 u_int
534 ath_hal_mac_usec(struct ath_hal *ah, u_int clks)
535 {
536 	const struct ieee80211_channel *c = AH_PRIVATE(ah)->ah_curchan;
537 	u_int usec;
538 
539 	/* NB: ah_curchan may be null when called attach time */
540 	/* XXX merlin and later specific workaround - 5ghz fast clock is 44 */
541 	if (c != AH_NULL && IS_5GHZ_FAST_CLOCK_EN(ah, c)) {
542 		usec = clks / CLOCK_FAST_RATE_5GHZ_OFDM;
543 		if (IEEE80211_IS_CHAN_HT40(c))
544 			usec >>= 1;
545 	} else if (c != AH_NULL) {
546 		usec = clks / CLOCK_RATE[ath_hal_chan2wmode(ah, c)];
547 		if (IEEE80211_IS_CHAN_HT40(c))
548 			usec >>= 1;
549 	} else
550 		usec = clks / CLOCK_RATE[WIRELESS_MODE_11b];
551 	return usec;
552 }
553 
554 /*
555  * Setup a h/w rate table's reverse lookup table and
556  * fill in ack durations.  This routine is called for
557  * each rate table returned through the ah_getRateTable
558  * method.  The reverse lookup tables are assumed to be
559  * initialized to zero (or at least the first entry).
560  * We use this as a key that indicates whether or not
561  * we've previously setup the reverse lookup table.
562  *
563  * XXX not reentrant, but shouldn't matter
564  */
565 void
566 ath_hal_setupratetable(struct ath_hal *ah, HAL_RATE_TABLE *rt)
567 {
568 #define	N(a)	(sizeof(a)/sizeof(a[0]))
569 	int i;
570 
571 	if (rt->rateCodeToIndex[0] != 0)	/* already setup */
572 		return;
573 	for (i = 0; i < N(rt->rateCodeToIndex); i++)
574 		rt->rateCodeToIndex[i] = (uint8_t) -1;
575 	for (i = 0; i < rt->rateCount; i++) {
576 		uint8_t code = rt->info[i].rateCode;
577 		uint8_t cix = rt->info[i].controlRate;
578 
579 		HALASSERT(code < N(rt->rateCodeToIndex));
580 		rt->rateCodeToIndex[code] = i;
581 		HALASSERT((code | rt->info[i].shortPreamble) <
582 		    N(rt->rateCodeToIndex));
583 		rt->rateCodeToIndex[code | rt->info[i].shortPreamble] = i;
584 		/*
585 		 * XXX for 11g the control rate to use for 5.5 and 11 Mb/s
586 		 *     depends on whether they are marked as basic rates;
587 		 *     the static tables are setup with an 11b-compatible
588 		 *     2Mb/s rate which will work but is suboptimal
589 		 */
590 		rt->info[i].lpAckDuration = ath_hal_computetxtime(ah, rt,
591 			WLAN_CTRL_FRAME_SIZE, cix, AH_FALSE);
592 		rt->info[i].spAckDuration = ath_hal_computetxtime(ah, rt,
593 			WLAN_CTRL_FRAME_SIZE, cix, AH_TRUE);
594 	}
595 #undef N
596 }
597 
598 HAL_STATUS
599 ath_hal_getcapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
600 	uint32_t capability, uint32_t *result)
601 {
602 	const HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;
603 
604 	switch (type) {
605 	case HAL_CAP_REG_DMN:		/* regulatory domain */
606 		*result = AH_PRIVATE(ah)->ah_currentRD;
607 		return HAL_OK;
608 	case HAL_CAP_DFS_DMN:		/* DFS Domain */
609 		*result = AH_PRIVATE(ah)->ah_dfsDomain;
610 		return HAL_OK;
611 	case HAL_CAP_CIPHER:		/* cipher handled in hardware */
612 	case HAL_CAP_TKIP_MIC:		/* handle TKIP MIC in hardware */
613 		return HAL_ENOTSUPP;
614 	case HAL_CAP_TKIP_SPLIT:	/* hardware TKIP uses split keys */
615 		return HAL_ENOTSUPP;
616 	case HAL_CAP_PHYCOUNTERS:	/* hardware PHY error counters */
617 		return pCap->halHwPhyCounterSupport ? HAL_OK : HAL_ENXIO;
618 	case HAL_CAP_WME_TKIPMIC:   /* hardware can do TKIP MIC when WMM is turned on */
619 		return HAL_ENOTSUPP;
620 	case HAL_CAP_DIVERSITY:		/* hardware supports fast diversity */
621 		return HAL_ENOTSUPP;
622 	case HAL_CAP_KEYCACHE_SIZE:	/* hardware key cache size */
623 		*result =  pCap->halKeyCacheSize;
624 		return HAL_OK;
625 	case HAL_CAP_NUM_TXQUEUES:	/* number of hardware tx queues */
626 		*result = pCap->halTotalQueues;
627 		return HAL_OK;
628 	case HAL_CAP_VEOL:		/* hardware supports virtual EOL */
629 		return pCap->halVEOLSupport ? HAL_OK : HAL_ENOTSUPP;
630 	case HAL_CAP_PSPOLL:		/* hardware PS-Poll support works */
631 		return pCap->halPSPollBroken ? HAL_ENOTSUPP : HAL_OK;
632 	case HAL_CAP_COMPRESSION:
633 		return pCap->halCompressSupport ? HAL_OK : HAL_ENOTSUPP;
634 	case HAL_CAP_BURST:
635 		return pCap->halBurstSupport ? HAL_OK : HAL_ENOTSUPP;
636 	case HAL_CAP_FASTFRAME:
637 		return pCap->halFastFramesSupport ? HAL_OK : HAL_ENOTSUPP;
638 	case HAL_CAP_DIAG:		/* hardware diagnostic support */
639 		*result = AH_PRIVATE(ah)->ah_diagreg;
640 		return HAL_OK;
641 	case HAL_CAP_TXPOW:		/* global tx power limit  */
642 		switch (capability) {
643 		case 0:			/* facility is supported */
644 			return HAL_OK;
645 		case 1:			/* current limit */
646 			*result = AH_PRIVATE(ah)->ah_powerLimit;
647 			return HAL_OK;
648 		case 2:			/* current max tx power */
649 			*result = AH_PRIVATE(ah)->ah_maxPowerLevel;
650 			return HAL_OK;
651 		case 3:			/* scale factor */
652 			*result = AH_PRIVATE(ah)->ah_tpScale;
653 			return HAL_OK;
654 		}
655 		return HAL_ENOTSUPP;
656 	case HAL_CAP_BSSIDMASK:		/* hardware supports bssid mask */
657 		return pCap->halBssIdMaskSupport ? HAL_OK : HAL_ENOTSUPP;
658 	case HAL_CAP_MCAST_KEYSRCH:	/* multicast frame keycache search */
659 		return pCap->halMcastKeySrchSupport ? HAL_OK : HAL_ENOTSUPP;
660 	case HAL_CAP_TSF_ADJUST:	/* hardware has beacon tsf adjust */
661 		return HAL_ENOTSUPP;
662 	case HAL_CAP_RFSILENT:		/* rfsilent support  */
663 		switch (capability) {
664 		case 0:			/* facility is supported */
665 			return pCap->halRfSilentSupport ? HAL_OK : HAL_ENOTSUPP;
666 		case 1:			/* current setting */
667 			return AH_PRIVATE(ah)->ah_rfkillEnabled ?
668 				HAL_OK : HAL_ENOTSUPP;
669 		case 2:			/* rfsilent config */
670 			*result = AH_PRIVATE(ah)->ah_rfsilent;
671 			return HAL_OK;
672 		}
673 		return HAL_ENOTSUPP;
674 	case HAL_CAP_11D:
675 		return HAL_OK;
676 
677 	case HAL_CAP_HT:
678 		return pCap->halHTSupport ? HAL_OK : HAL_ENOTSUPP;
679 	case HAL_CAP_GTXTO:
680 		return pCap->halGTTSupport ? HAL_OK : HAL_ENOTSUPP;
681 	case HAL_CAP_FAST_CC:
682 		return pCap->halFastCCSupport ? HAL_OK : HAL_ENOTSUPP;
683 	case HAL_CAP_TX_CHAINMASK:	/* mask of TX chains supported */
684 		*result = pCap->halTxChainMask;
685 		return HAL_OK;
686 	case HAL_CAP_RX_CHAINMASK:	/* mask of RX chains supported */
687 		*result = pCap->halRxChainMask;
688 		return HAL_OK;
689 	case HAL_CAP_NUM_GPIO_PINS:
690 		*result = pCap->halNumGpioPins;
691 		return HAL_OK;
692 	case HAL_CAP_CST:
693 		return pCap->halCSTSupport ? HAL_OK : HAL_ENOTSUPP;
694 	case HAL_CAP_RTS_AGGR_LIMIT:
695 		*result = pCap->halRtsAggrLimit;
696 		return HAL_OK;
697 	case HAL_CAP_4ADDR_AGGR:
698 		return pCap->hal4AddrAggrSupport ? HAL_OK : HAL_ENOTSUPP;
699 	case HAL_CAP_EXT_CHAN_DFS:
700 		return pCap->halExtChanDfsSupport ? HAL_OK : HAL_ENOTSUPP;
701 	case HAL_CAP_RX_STBC:
702 		return pCap->halRxStbcSupport ? HAL_OK : HAL_ENOTSUPP;
703 	case HAL_CAP_TX_STBC:
704 		return pCap->halTxStbcSupport ? HAL_OK : HAL_ENOTSUPP;
705 	case HAL_CAP_COMBINED_RADAR_RSSI:
706 		return pCap->halUseCombinedRadarRssi ? HAL_OK : HAL_ENOTSUPP;
707 	case HAL_CAP_AUTO_SLEEP:
708 		return pCap->halAutoSleepSupport ? HAL_OK : HAL_ENOTSUPP;
709 	case HAL_CAP_MBSSID_AGGR_SUPPORT:
710 		return pCap->halMbssidAggrSupport ? HAL_OK : HAL_ENOTSUPP;
711 	case HAL_CAP_SPLIT_4KB_TRANS:	/* hardware handles descriptors straddling 4k page boundary */
712 		return pCap->hal4kbSplitTransSupport ? HAL_OK : HAL_ENOTSUPP;
713 	case HAL_CAP_REG_FLAG:
714 		*result = AH_PRIVATE(ah)->ah_currentRDext;
715 		return HAL_OK;
716 	case HAL_CAP_ENHANCED_DMA_SUPPORT:
717 		return pCap->halEnhancedDmaSupport ? HAL_OK : HAL_ENOTSUPP;
718 	case HAL_CAP_NUM_TXMAPS:
719 		*result = pCap->halNumTxMaps;
720 		return HAL_OK;
721 	case HAL_CAP_TXDESCLEN:
722 		*result = pCap->halTxDescLen;
723 		return HAL_OK;
724 	case HAL_CAP_TXSTATUSLEN:
725 		*result = pCap->halTxStatusLen;
726 		return HAL_OK;
727 	case HAL_CAP_RXSTATUSLEN:
728 		*result = pCap->halRxStatusLen;
729 		return HAL_OK;
730 	case HAL_CAP_RXFIFODEPTH:
731 		switch (capability) {
732 		case HAL_RX_QUEUE_HP:
733 			*result = pCap->halRxHpFifoDepth;
734 			return HAL_OK;
735 		case HAL_RX_QUEUE_LP:
736 			*result = pCap->halRxLpFifoDepth;
737 			return HAL_OK;
738 		default:
739 			return HAL_ENOTSUPP;
740 	}
741 	case HAL_CAP_RXBUFSIZE:
742 	case HAL_CAP_NUM_MR_RETRIES:
743 		*result = pCap->halNumMRRetries;
744 		return HAL_OK;
745 	case HAL_CAP_BT_COEX:
746 		return pCap->halBtCoexSupport ? HAL_OK : HAL_ENOTSUPP;
747 	case HAL_CAP_SPECTRAL_SCAN:
748 		return pCap->halSpectralScanSupport ? HAL_OK : HAL_ENOTSUPP;
749 	case HAL_CAP_HT20_SGI:
750 		return pCap->halHTSGI20Support ? HAL_OK : HAL_ENOTSUPP;
751 	case HAL_CAP_RXTSTAMP_PREC:	/* rx desc tstamp precision (bits) */
752 		*result = pCap->halTstampPrecision;
753 		return HAL_OK;
754 	case HAL_CAP_ANT_DIV_COMB:	/* AR9285/AR9485 LNA diversity */
755 		return pCap->halAntDivCombSupport ? HAL_OK  : HAL_ENOTSUPP;
756 
757 	case HAL_CAP_ENHANCED_DFS_SUPPORT:
758 		return pCap->halEnhancedDfsSupport ? HAL_OK : HAL_ENOTSUPP;
759 
760 	/* FreeBSD-specific entries for now */
761 	case HAL_CAP_RXORN_FATAL:	/* HAL_INT_RXORN treated as fatal  */
762 		return AH_PRIVATE(ah)->ah_rxornIsFatal ? HAL_OK : HAL_ENOTSUPP;
763 	case HAL_CAP_INTRMASK:		/* mask of supported interrupts */
764 		*result = pCap->halIntrMask;
765 		return HAL_OK;
766 	case HAL_CAP_BSSIDMATCH:	/* hardware has disable bssid match */
767 		return pCap->halBssidMatchSupport ? HAL_OK : HAL_ENOTSUPP;
768 	case HAL_CAP_STREAMS:		/* number of 11n spatial streams */
769 		switch (capability) {
770 		case 0:			/* TX */
771 			*result = pCap->halTxStreams;
772 			return HAL_OK;
773 		case 1:			/* RX */
774 			*result = pCap->halRxStreams;
775 			return HAL_OK;
776 		default:
777 			return HAL_ENOTSUPP;
778 		}
779 	case HAL_CAP_RXDESC_SELFLINK:	/* hardware supports self-linked final RX descriptors correctly */
780 		return pCap->halHasRxSelfLinkedTail ? HAL_OK : HAL_ENOTSUPP;
781 	case HAL_CAP_LONG_RXDESC_TSF:		/* 32 bit TSF in RX descriptor? */
782 		return pCap->halHasLongRxDescTsf ? HAL_OK : HAL_ENOTSUPP;
783 	case HAL_CAP_BB_READ_WAR:		/* Baseband read WAR */
784 		return pCap->halHasBBReadWar? HAL_OK : HAL_ENOTSUPP;
785 	case HAL_CAP_SERIALISE_WAR:		/* PCI register serialisation */
786 		return pCap->halSerialiseRegWar ? HAL_OK : HAL_ENOTSUPP;
787 	case HAL_CAP_MFP:			/* Management frame protection setting */
788 		*result = pCap->halMfpSupport;
789 		return HAL_OK;
790 	case HAL_CAP_RX_LNA_MIXING:	/* Hardware uses an RX LNA mixer to map 2 antennas to a 1 stream receiver */
791 		return pCap->halRxUsingLnaMixing ? HAL_OK : HAL_ENOTSUPP;
792 	case HAL_CAP_DO_MYBEACON:	/* Hardware supports filtering my-beacons */
793 		return pCap->halRxDoMyBeacon ? HAL_OK : HAL_ENOTSUPP;
794 	default:
795 		return HAL_EINVAL;
796 	}
797 }
798 
799 HAL_BOOL
800 ath_hal_setcapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
801 	uint32_t capability, uint32_t setting, HAL_STATUS *status)
802 {
803 
804 	switch (type) {
805 	case HAL_CAP_TXPOW:
806 		switch (capability) {
807 		case 3:
808 			if (setting <= HAL_TP_SCALE_MIN) {
809 				AH_PRIVATE(ah)->ah_tpScale = setting;
810 				return AH_TRUE;
811 			}
812 			break;
813 		}
814 		break;
815 	case HAL_CAP_RFSILENT:		/* rfsilent support  */
816 		/*
817 		 * NB: allow even if halRfSilentSupport is false
818 		 *     in case the EEPROM is misprogrammed.
819 		 */
820 		switch (capability) {
821 		case 1:			/* current setting */
822 			AH_PRIVATE(ah)->ah_rfkillEnabled = (setting != 0);
823 			return AH_TRUE;
824 		case 2:			/* rfsilent config */
825 			/* XXX better done per-chip for validation? */
826 			AH_PRIVATE(ah)->ah_rfsilent = setting;
827 			return AH_TRUE;
828 		}
829 		break;
830 	case HAL_CAP_REG_DMN:		/* regulatory domain */
831 		AH_PRIVATE(ah)->ah_currentRD = setting;
832 		return AH_TRUE;
833 	case HAL_CAP_RXORN_FATAL:	/* HAL_INT_RXORN treated as fatal  */
834 		AH_PRIVATE(ah)->ah_rxornIsFatal = setting;
835 		return AH_TRUE;
836 	default:
837 		break;
838 	}
839 	if (status)
840 		*status = HAL_EINVAL;
841 	return AH_FALSE;
842 }
843 
844 /*
845  * Common support for getDiagState method.
846  */
847 
848 static u_int
849 ath_hal_getregdump(struct ath_hal *ah, const HAL_REGRANGE *regs,
850 	void *dstbuf, int space)
851 {
852 	uint32_t *dp = dstbuf;
853 	int i;
854 
855 	for (i = 0; space >= 2*sizeof(uint32_t); i++) {
856 		uint32_t r = regs[i].start;
857 		uint32_t e = regs[i].end;
858 		*dp++ = r;
859 		*dp++ = e;
860 		space -= 2*sizeof(uint32_t);
861 		do {
862 			*dp++ = OS_REG_READ(ah, r);
863 			r += sizeof(uint32_t);
864 			space -= sizeof(uint32_t);
865 		} while (r <= e && space >= sizeof(uint32_t));
866 	}
867 	return (char *) dp - (char *) dstbuf;
868 }
869 
870 static void
871 ath_hal_setregs(struct ath_hal *ah, const HAL_REGWRITE *regs, int space)
872 {
873 	while (space >= sizeof(HAL_REGWRITE)) {
874 		OS_REG_WRITE(ah, regs->addr, regs->value);
875 		regs++, space -= sizeof(HAL_REGWRITE);
876 	}
877 }
878 
879 HAL_BOOL
880 ath_hal_getdiagstate(struct ath_hal *ah, int request,
881 	const void *args, uint32_t argsize,
882 	void **result, uint32_t *resultsize)
883 {
884 
885 	switch (request) {
886 	case HAL_DIAG_REVS:
887 		*result = &AH_PRIVATE(ah)->ah_devid;
888 		*resultsize = sizeof(HAL_REVS);
889 		return AH_TRUE;
890 	case HAL_DIAG_REGS:
891 		*resultsize = ath_hal_getregdump(ah, args, *result,*resultsize);
892 		return AH_TRUE;
893 	case HAL_DIAG_SETREGS:
894 		ath_hal_setregs(ah, args, argsize);
895 		*resultsize = 0;
896 		return AH_TRUE;
897 	case HAL_DIAG_FATALERR:
898 		*result = &AH_PRIVATE(ah)->ah_fatalState[0];
899 		*resultsize = sizeof(AH_PRIVATE(ah)->ah_fatalState);
900 		return AH_TRUE;
901 	case HAL_DIAG_EEREAD:
902 		if (argsize != sizeof(uint16_t))
903 			return AH_FALSE;
904 		if (!ath_hal_eepromRead(ah, *(const uint16_t *)args, *result))
905 			return AH_FALSE;
906 		*resultsize = sizeof(uint16_t);
907 		return AH_TRUE;
908 #ifdef AH_PRIVATE_DIAG
909 	case HAL_DIAG_SETKEY: {
910 		const HAL_DIAG_KEYVAL *dk;
911 
912 		if (argsize != sizeof(HAL_DIAG_KEYVAL))
913 			return AH_FALSE;
914 		dk = (const HAL_DIAG_KEYVAL *)args;
915 		return ah->ah_setKeyCacheEntry(ah, dk->dk_keyix,
916 			&dk->dk_keyval, dk->dk_mac, dk->dk_xor);
917 	}
918 	case HAL_DIAG_RESETKEY:
919 		if (argsize != sizeof(uint16_t))
920 			return AH_FALSE;
921 		return ah->ah_resetKeyCacheEntry(ah, *(const uint16_t *)args);
922 #ifdef AH_SUPPORT_WRITE_EEPROM
923 	case HAL_DIAG_EEWRITE: {
924 		const HAL_DIAG_EEVAL *ee;
925 		if (argsize != sizeof(HAL_DIAG_EEVAL))
926 			return AH_FALSE;
927 		ee = (const HAL_DIAG_EEVAL *)args;
928 		return ath_hal_eepromWrite(ah, ee->ee_off, ee->ee_data);
929 	}
930 #endif /* AH_SUPPORT_WRITE_EEPROM */
931 #endif /* AH_PRIVATE_DIAG */
932 	case HAL_DIAG_11NCOMPAT:
933 		if (argsize == 0) {
934 			*resultsize = sizeof(uint32_t);
935 			*((uint32_t *)(*result)) =
936 				AH_PRIVATE(ah)->ah_11nCompat;
937 		} else if (argsize == sizeof(uint32_t)) {
938 			AH_PRIVATE(ah)->ah_11nCompat = *(const uint32_t *)args;
939 		} else
940 			return AH_FALSE;
941 		return AH_TRUE;
942 	case HAL_DIAG_CHANSURVEY:
943 		*result = &AH_PRIVATE(ah)->ah_chansurvey;
944 		*resultsize = sizeof(HAL_CHANNEL_SURVEY);
945 		return AH_TRUE;
946 	}
947 	return AH_FALSE;
948 }
949 
950 /*
951  * Set the properties of the tx queue with the parameters
952  * from qInfo.
953  */
954 HAL_BOOL
955 ath_hal_setTxQProps(struct ath_hal *ah,
956 	HAL_TX_QUEUE_INFO *qi, const HAL_TXQ_INFO *qInfo)
957 {
958 	uint32_t cw;
959 
960 	if (qi->tqi_type == HAL_TX_QUEUE_INACTIVE) {
961 		HALDEBUG(ah, HAL_DEBUG_TXQUEUE,
962 		    "%s: inactive queue\n", __func__);
963 		return AH_FALSE;
964 	}
965 	/* XXX validate parameters */
966 	qi->tqi_ver = qInfo->tqi_ver;
967 	qi->tqi_subtype = qInfo->tqi_subtype;
968 	qi->tqi_qflags = qInfo->tqi_qflags;
969 	qi->tqi_priority = qInfo->tqi_priority;
970 	if (qInfo->tqi_aifs != HAL_TXQ_USEDEFAULT)
971 		qi->tqi_aifs = AH_MIN(qInfo->tqi_aifs, 255);
972 	else
973 		qi->tqi_aifs = INIT_AIFS;
974 	if (qInfo->tqi_cwmin != HAL_TXQ_USEDEFAULT) {
975 		cw = AH_MIN(qInfo->tqi_cwmin, 1024);
976 		/* make sure that the CWmin is of the form (2^n - 1) */
977 		qi->tqi_cwmin = 1;
978 		while (qi->tqi_cwmin < cw)
979 			qi->tqi_cwmin = (qi->tqi_cwmin << 1) | 1;
980 	} else
981 		qi->tqi_cwmin = qInfo->tqi_cwmin;
982 	if (qInfo->tqi_cwmax != HAL_TXQ_USEDEFAULT) {
983 		cw = AH_MIN(qInfo->tqi_cwmax, 1024);
984 		/* make sure that the CWmax is of the form (2^n - 1) */
985 		qi->tqi_cwmax = 1;
986 		while (qi->tqi_cwmax < cw)
987 			qi->tqi_cwmax = (qi->tqi_cwmax << 1) | 1;
988 	} else
989 		qi->tqi_cwmax = INIT_CWMAX;
990 	/* Set retry limit values */
991 	if (qInfo->tqi_shretry != 0)
992 		qi->tqi_shretry = AH_MIN(qInfo->tqi_shretry, 15);
993 	else
994 		qi->tqi_shretry = INIT_SH_RETRY;
995 	if (qInfo->tqi_lgretry != 0)
996 		qi->tqi_lgretry = AH_MIN(qInfo->tqi_lgretry, 15);
997 	else
998 		qi->tqi_lgretry = INIT_LG_RETRY;
999 	qi->tqi_cbrPeriod = qInfo->tqi_cbrPeriod;
1000 	qi->tqi_cbrOverflowLimit = qInfo->tqi_cbrOverflowLimit;
1001 	qi->tqi_burstTime = qInfo->tqi_burstTime;
1002 	qi->tqi_readyTime = qInfo->tqi_readyTime;
1003 
1004 	switch (qInfo->tqi_subtype) {
1005 	case HAL_WME_UPSD:
1006 		if (qi->tqi_type == HAL_TX_QUEUE_DATA)
1007 			qi->tqi_intFlags = HAL_TXQ_USE_LOCKOUT_BKOFF_DIS;
1008 		break;
1009 	default:
1010 		break;		/* NB: silence compiler */
1011 	}
1012 	return AH_TRUE;
1013 }
1014 
1015 HAL_BOOL
1016 ath_hal_getTxQProps(struct ath_hal *ah,
1017 	HAL_TXQ_INFO *qInfo, const HAL_TX_QUEUE_INFO *qi)
1018 {
1019 	if (qi->tqi_type == HAL_TX_QUEUE_INACTIVE) {
1020 		HALDEBUG(ah, HAL_DEBUG_TXQUEUE,
1021 		    "%s: inactive queue\n", __func__);
1022 		return AH_FALSE;
1023 	}
1024 
1025 	qInfo->tqi_qflags = qi->tqi_qflags;
1026 	qInfo->tqi_ver = qi->tqi_ver;
1027 	qInfo->tqi_subtype = qi->tqi_subtype;
1028 	qInfo->tqi_qflags = qi->tqi_qflags;
1029 	qInfo->tqi_priority = qi->tqi_priority;
1030 	qInfo->tqi_aifs = qi->tqi_aifs;
1031 	qInfo->tqi_cwmin = qi->tqi_cwmin;
1032 	qInfo->tqi_cwmax = qi->tqi_cwmax;
1033 	qInfo->tqi_shretry = qi->tqi_shretry;
1034 	qInfo->tqi_lgretry = qi->tqi_lgretry;
1035 	qInfo->tqi_cbrPeriod = qi->tqi_cbrPeriod;
1036 	qInfo->tqi_cbrOverflowLimit = qi->tqi_cbrOverflowLimit;
1037 	qInfo->tqi_burstTime = qi->tqi_burstTime;
1038 	qInfo->tqi_readyTime = qi->tqi_readyTime;
1039 	return AH_TRUE;
1040 }
1041 
1042                                      /* 11a Turbo  11b  11g  108g */
1043 static const int16_t NOISE_FLOOR[] = { -96, -93,  -98, -96,  -93 };
1044 
1045 /*
1046  * Read the current channel noise floor and return.
1047  * If nf cal hasn't finished, channel noise floor should be 0
1048  * and we return a nominal value based on band and frequency.
1049  *
1050  * NB: This is a private routine used by per-chip code to
1051  *     implement the ah_getChanNoise method.
1052  */
1053 int16_t
1054 ath_hal_getChanNoise(struct ath_hal *ah, const struct ieee80211_channel *chan)
1055 {
1056 	HAL_CHANNEL_INTERNAL *ichan;
1057 
1058 	ichan = ath_hal_checkchannel(ah, chan);
1059 	if (ichan == AH_NULL) {
1060 		HALDEBUG(ah, HAL_DEBUG_NFCAL,
1061 		    "%s: invalid channel %u/0x%x; no mapping\n",
1062 		    __func__, chan->ic_freq, chan->ic_flags);
1063 		return 0;
1064 	}
1065 	if (ichan->rawNoiseFloor == 0) {
1066 		WIRELESS_MODE mode = ath_hal_chan2wmode(ah, chan);
1067 
1068 		HALASSERT(mode < WIRELESS_MODE_MAX);
1069 		return NOISE_FLOOR[mode] + ath_hal_getNfAdjust(ah, ichan);
1070 	} else
1071 		return ichan->rawNoiseFloor + ichan->noiseFloorAdjust;
1072 }
1073 
1074 /*
1075  * Fetch the current setup of ctl/ext noise floor values.
1076  *
1077  * If the CHANNEL_MIMO_NF_VALID flag isn't set, the array is simply
1078  * populated with values from NOISE_FLOOR[] + ath_hal_getNfAdjust().
1079  *
1080  * The caller must supply ctl/ext NF arrays which are at least
1081  * AH_MAX_CHAINS entries long.
1082  */
1083 int
1084 ath_hal_get_mimo_chan_noise(struct ath_hal *ah,
1085     const struct ieee80211_channel *chan, int16_t *nf_ctl,
1086     int16_t *nf_ext)
1087 {
1088 #ifdef	AH_SUPPORT_AR5416
1089 	HAL_CHANNEL_INTERNAL *ichan;
1090 	int i;
1091 
1092 	ichan = ath_hal_checkchannel(ah, chan);
1093 	if (ichan == AH_NULL) {
1094 		HALDEBUG(ah, HAL_DEBUG_NFCAL,
1095 		    "%s: invalid channel %u/0x%x; no mapping\n",
1096 		    __func__, chan->ic_freq, chan->ic_flags);
1097 		for (i = 0; i < AH_MAX_CHAINS; i++) {
1098 			nf_ctl[i] = nf_ext[i] = 0;
1099 		}
1100 		return 0;
1101 	}
1102 
1103 	/* Return 0 if there's no valid MIMO values (yet) */
1104 	if (! (ichan->privFlags & CHANNEL_MIMO_NF_VALID)) {
1105 		for (i = 0; i < AH_MAX_CHAINS; i++) {
1106 			nf_ctl[i] = nf_ext[i] = 0;
1107 		}
1108 		return 0;
1109 	}
1110 	if (ichan->rawNoiseFloor == 0) {
1111 		WIRELESS_MODE mode = ath_hal_chan2wmode(ah, chan);
1112 		HALASSERT(mode < WIRELESS_MODE_MAX);
1113 		/*
1114 		 * See the comment below - this could cause issues for
1115 		 * stations which have a very low RSSI, below the
1116 		 * 'normalised' NF values in NOISE_FLOOR[].
1117 		 */
1118 		for (i = 0; i < AH_MAX_CHAINS; i++) {
1119 			nf_ctl[i] = nf_ext[i] = NOISE_FLOOR[mode] +
1120 			    ath_hal_getNfAdjust(ah, ichan);
1121 		}
1122 		return 1;
1123 	} else {
1124 		/*
1125 		 * The value returned here from a MIMO radio is presumed to be
1126 		 * "good enough" as a NF calculation. As RSSI values are calculated
1127 		 * against this, an adjusted NF may be higher than the RSSI value
1128 		 * returned from a vary weak station, resulting in an obscenely
1129 		 * high signal strength calculation being returned.
1130 		 *
1131 		 * This should be re-evaluated at a later date, along with any
1132 		 * signal strength calculations which are made. Quite likely the
1133 		 * RSSI values will need to be adjusted to ensure the calculations
1134 		 * don't "wrap" when RSSI is less than the "adjusted" NF value.
1135 		 * ("Adjust" here is via ichan->noiseFloorAdjust.)
1136 		 */
1137 		for (i = 0; i < AH_MAX_CHAINS; i++) {
1138 			nf_ctl[i] = ichan->noiseFloorCtl[i] + ath_hal_getNfAdjust(ah, ichan);
1139 			nf_ext[i] = ichan->noiseFloorExt[i] + ath_hal_getNfAdjust(ah, ichan);
1140 		}
1141 		return 1;
1142 	}
1143 #else
1144 	return 0;
1145 #endif	/* AH_SUPPORT_AR5416 */
1146 }
1147 
1148 /*
1149  * Process all valid raw noise floors into the dBm noise floor values.
1150  * Though our device has no reference for a dBm noise floor, we perform
1151  * a relative minimization of NF's based on the lowest NF found across a
1152  * channel scan.
1153  */
1154 void
1155 ath_hal_process_noisefloor(struct ath_hal *ah)
1156 {
1157 	HAL_CHANNEL_INTERNAL *c;
1158 	int16_t correct2, correct5;
1159 	int16_t lowest2, lowest5;
1160 	int i;
1161 
1162 	/*
1163 	 * Find the lowest 2GHz and 5GHz noise floor values after adjusting
1164 	 * for statistically recorded NF/channel deviation.
1165 	 */
1166 	correct2 = lowest2 = 0;
1167 	correct5 = lowest5 = 0;
1168 	for (i = 0; i < AH_PRIVATE(ah)->ah_nchan; i++) {
1169 		WIRELESS_MODE mode;
1170 		int16_t nf;
1171 
1172 		c = &AH_PRIVATE(ah)->ah_channels[i];
1173 		if (c->rawNoiseFloor >= 0)
1174 			continue;
1175 		/* XXX can't identify proper mode */
1176 		mode = IS_CHAN_5GHZ(c) ? WIRELESS_MODE_11a : WIRELESS_MODE_11g;
1177 		nf = c->rawNoiseFloor + NOISE_FLOOR[mode] +
1178 			ath_hal_getNfAdjust(ah, c);
1179 		if (IS_CHAN_5GHZ(c)) {
1180 			if (nf < lowest5) {
1181 				lowest5 = nf;
1182 				correct5 = NOISE_FLOOR[mode] -
1183 				    (c->rawNoiseFloor + ath_hal_getNfAdjust(ah, c));
1184 			}
1185 		} else {
1186 			if (nf < lowest2) {
1187 				lowest2 = nf;
1188 				correct2 = NOISE_FLOOR[mode] -
1189 				    (c->rawNoiseFloor + ath_hal_getNfAdjust(ah, c));
1190 			}
1191 		}
1192 	}
1193 
1194 	/* Correct the channels to reach the expected NF value */
1195 	for (i = 0; i < AH_PRIVATE(ah)->ah_nchan; i++) {
1196 		c = &AH_PRIVATE(ah)->ah_channels[i];
1197 		if (c->rawNoiseFloor >= 0)
1198 			continue;
1199 		/* Apply correction factor */
1200 		c->noiseFloorAdjust = ath_hal_getNfAdjust(ah, c) +
1201 			(IS_CHAN_5GHZ(c) ? correct5 : correct2);
1202 		HALDEBUG(ah, HAL_DEBUG_NFCAL, "%u raw nf %d adjust %d\n",
1203 		    c->channel, c->rawNoiseFloor, c->noiseFloorAdjust);
1204 	}
1205 }
1206 
1207 /*
1208  * INI support routines.
1209  */
1210 
1211 int
1212 ath_hal_ini_write(struct ath_hal *ah, const HAL_INI_ARRAY *ia,
1213 	int col, int regWr)
1214 {
1215 	int r;
1216 
1217 	HALASSERT(col < ia->cols);
1218 	for (r = 0; r < ia->rows; r++) {
1219 		OS_REG_WRITE(ah, HAL_INI_VAL(ia, r, 0),
1220 		    HAL_INI_VAL(ia, r, col));
1221 
1222 		/* Analog shift register delay seems needed for Merlin - PR kern/154220 */
1223 		if (HAL_INI_VAL(ia, r, 0) >= 0x7800 && HAL_INI_VAL(ia, r, 0) < 0x7900)
1224 			OS_DELAY(100);
1225 
1226 		DMA_YIELD(regWr);
1227 	}
1228 	return regWr;
1229 }
1230 
1231 void
1232 ath_hal_ini_bank_setup(uint32_t data[], const HAL_INI_ARRAY *ia, int col)
1233 {
1234 	int r;
1235 
1236 	HALASSERT(col < ia->cols);
1237 	for (r = 0; r < ia->rows; r++)
1238 		data[r] = HAL_INI_VAL(ia, r, col);
1239 }
1240 
1241 int
1242 ath_hal_ini_bank_write(struct ath_hal *ah, const HAL_INI_ARRAY *ia,
1243 	const uint32_t data[], int regWr)
1244 {
1245 	int r;
1246 
1247 	for (r = 0; r < ia->rows; r++) {
1248 		OS_REG_WRITE(ah, HAL_INI_VAL(ia, r, 0), data[r]);
1249 		DMA_YIELD(regWr);
1250 	}
1251 	return regWr;
1252 }
1253 
1254 /*
1255  * These are EEPROM board related routines which should likely live in
1256  * a helper library of some sort.
1257  */
1258 
1259 /**************************************************************
1260  * ath_ee_getLowerUppderIndex
1261  *
1262  * Return indices surrounding the value in sorted integer lists.
1263  * Requirement: the input list must be monotonically increasing
1264  *     and populated up to the list size
1265  * Returns: match is set if an index in the array matches exactly
1266  *     or a the target is before or after the range of the array.
1267  */
1268 HAL_BOOL
1269 ath_ee_getLowerUpperIndex(uint8_t target, uint8_t *pList, uint16_t listSize,
1270                    uint16_t *indexL, uint16_t *indexR)
1271 {
1272     uint16_t i;
1273 
1274     /*
1275      * Check first and last elements for beyond ordered array cases.
1276      */
1277     if (target <= pList[0]) {
1278         *indexL = *indexR = 0;
1279         return AH_TRUE;
1280     }
1281     if (target >= pList[listSize-1]) {
1282         *indexL = *indexR = (uint16_t)(listSize - 1);
1283         return AH_TRUE;
1284     }
1285 
1286     /* look for value being near or between 2 values in list */
1287     for (i = 0; i < listSize - 1; i++) {
1288         /*
1289          * If value is close to the current value of the list
1290          * then target is not between values, it is one of the values
1291          */
1292         if (pList[i] == target) {
1293             *indexL = *indexR = i;
1294             return AH_TRUE;
1295         }
1296         /*
1297          * Look for value being between current value and next value
1298          * if so return these 2 values
1299          */
1300         if (target < pList[i + 1]) {
1301             *indexL = i;
1302             *indexR = (uint16_t)(i + 1);
1303             return AH_FALSE;
1304         }
1305     }
1306     HALASSERT(0);
1307     *indexL = *indexR = 0;
1308     return AH_FALSE;
1309 }
1310 
1311 /**************************************************************
1312  * ath_ee_FillVpdTable
1313  *
1314  * Fill the Vpdlist for indices Pmax-Pmin
1315  * Note: pwrMin, pwrMax and Vpdlist are all in dBm * 4
1316  */
1317 HAL_BOOL
1318 ath_ee_FillVpdTable(uint8_t pwrMin, uint8_t pwrMax, uint8_t *pPwrList,
1319                    uint8_t *pVpdList, uint16_t numIntercepts, uint8_t *pRetVpdList)
1320 {
1321     uint16_t  i, k;
1322     uint8_t   currPwr = pwrMin;
1323     uint16_t  idxL, idxR;
1324 
1325     HALASSERT(pwrMax > pwrMin);
1326     for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) {
1327         ath_ee_getLowerUpperIndex(currPwr, pPwrList, numIntercepts,
1328                            &(idxL), &(idxR));
1329         if (idxR < 1)
1330             idxR = 1;           /* extrapolate below */
1331         if (idxL == numIntercepts - 1)
1332             idxL = (uint16_t)(numIntercepts - 2);   /* extrapolate above */
1333         if (pPwrList[idxL] == pPwrList[idxR])
1334             k = pVpdList[idxL];
1335         else
1336             k = (uint16_t)( ((currPwr - pPwrList[idxL]) * pVpdList[idxR] + (pPwrList[idxR] - currPwr) * pVpdList[idxL]) /
1337                   (pPwrList[idxR] - pPwrList[idxL]) );
1338         HALASSERT(k < 256);
1339         pRetVpdList[i] = (uint8_t)k;
1340         currPwr += 2;               /* half dB steps */
1341     }
1342 
1343     return AH_TRUE;
1344 }
1345 
1346 /**************************************************************************
1347  * ath_ee_interpolate
1348  *
1349  * Returns signed interpolated or the scaled up interpolated value
1350  */
1351 int16_t
1352 ath_ee_interpolate(uint16_t target, uint16_t srcLeft, uint16_t srcRight,
1353             int16_t targetLeft, int16_t targetRight)
1354 {
1355     int16_t rv;
1356 
1357     if (srcRight == srcLeft) {
1358         rv = targetLeft;
1359     } else {
1360         rv = (int16_t)( ((target - srcLeft) * targetRight +
1361               (srcRight - target) * targetLeft) / (srcRight - srcLeft) );
1362     }
1363     return rv;
1364 }
1365 
1366 /*
1367  * Adjust the TSF.
1368  */
1369 void
1370 ath_hal_adjusttsf(struct ath_hal *ah, int32_t tsfdelta)
1371 {
1372 	/* XXX handle wrap/overflow */
1373 	OS_REG_WRITE(ah, AR_TSF_L32, OS_REG_READ(ah, AR_TSF_L32) + tsfdelta);
1374 }
1375 
1376 /*
1377  * Enable or disable CCA.
1378  */
1379 void
1380 ath_hal_setcca(struct ath_hal *ah, int ena)
1381 {
1382 	/*
1383 	 * NB: fill me in; this is not provided by default because disabling
1384 	 *     CCA in most locales violates regulatory.
1385 	 */
1386 }
1387 
1388 /*
1389  * Get CCA setting.
1390  */
1391 int
1392 ath_hal_getcca(struct ath_hal *ah)
1393 {
1394 	u_int32_t diag;
1395 	if (ath_hal_getcapability(ah, HAL_CAP_DIAG, 0, &diag) != HAL_OK)
1396 		return 1;
1397 	return ((diag & 0x500000) == 0);
1398 }
1399 
1400 /*
1401  * This routine is only needed when supporting EEPROM-in-RAM setups
1402  * (eg embedded SoCs and on-board PCI/PCIe devices.)
1403  */
1404 /* NB: This is in 16 bit words; not bytes */
1405 /* XXX This doesn't belong here!  */
1406 #define ATH_DATA_EEPROM_SIZE    2048
1407 
1408 HAL_BOOL
1409 ath_hal_EepromDataRead(struct ath_hal *ah, u_int off, uint16_t *data)
1410 {
1411 	if (ah->ah_eepromdata == AH_NULL) {
1412 		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: no eeprom data!\n", __func__);
1413 		return AH_FALSE;
1414 	}
1415 	if (off > ATH_DATA_EEPROM_SIZE) {
1416 		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: offset %x > %x\n",
1417 		    __func__, off, ATH_DATA_EEPROM_SIZE);
1418 		return AH_FALSE;
1419 	}
1420 	(*data) = ah->ah_eepromdata[off];
1421 	return AH_TRUE;
1422 }
1423 
1424 /*
1425  * Do a 2GHz specific MHz->IEEE based on the hardware
1426  * frequency.
1427  *
1428  * This is the unmapped frequency which is programmed into the hardware.
1429  */
1430 int
1431 ath_hal_mhz2ieee_2ghz(struct ath_hal *ah, int freq)
1432 {
1433 
1434 	if (freq == 2484)
1435 		return 14;
1436 	if (freq < 2484)
1437 		return ((int) freq - 2407) / 5;
1438 	else
1439 		return 15 + ((freq - 2512) / 20);
1440 }
1441 
1442 /*
1443  * Clear the current survey data.
1444  *
1445  * This should be done during a channel change.
1446  */
1447 void
1448 ath_hal_survey_clear(struct ath_hal *ah)
1449 {
1450 
1451 	OS_MEMZERO(&AH_PRIVATE(ah)->ah_chansurvey,
1452 	    sizeof(AH_PRIVATE(ah)->ah_chansurvey));
1453 }
1454 
1455 /*
1456  * Add a sample to the channel survey.
1457  */
1458 void
1459 ath_hal_survey_add_sample(struct ath_hal *ah, HAL_SURVEY_SAMPLE *hs)
1460 {
1461 	HAL_CHANNEL_SURVEY *cs;
1462 
1463 	cs = &AH_PRIVATE(ah)->ah_chansurvey;
1464 
1465 	OS_MEMCPY(&cs->samples[cs->cur_sample], hs, sizeof(*hs));
1466 	cs->samples[cs->cur_sample].seq_num = cs->cur_seq;
1467 	cs->cur_sample = (cs->cur_sample + 1) % CHANNEL_SURVEY_SAMPLE_COUNT;
1468 	cs->cur_seq++;
1469 }
1470