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