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