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