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