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