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