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