xref: /freebsd/sys/dev/ath/ath_hal/ah.c (revision 1f474190)
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 typedef enum {
560 	WIRELESS_MODE_11a   = 0,
561 	WIRELESS_MODE_TURBO = 1,
562 	WIRELESS_MODE_11b   = 2,
563 	WIRELESS_MODE_11g   = 3,
564 	WIRELESS_MODE_108g  = 4,
565 
566 	WIRELESS_MODE_MAX
567 } WIRELESS_MODE;
568 
569 /*
570  * XXX TODO: for some (?) chips, an 11b mode still runs at 11bg.
571  * Maybe AR5211 has separate 11b and 11g only modes, so 11b is 22MHz
572  * and 11g is 44MHz, but AR5416 and later run 11b in 11bg mode, right?
573  */
574 static WIRELESS_MODE
575 ath_hal_chan2wmode(struct ath_hal *ah, const struct ieee80211_channel *chan)
576 {
577 	if (IEEE80211_IS_CHAN_B(chan))
578 		return WIRELESS_MODE_11b;
579 	if (IEEE80211_IS_CHAN_G(chan))
580 		return WIRELESS_MODE_11g;
581 	if (IEEE80211_IS_CHAN_108G(chan))
582 		return WIRELESS_MODE_108g;
583 	if (IEEE80211_IS_CHAN_TURBO(chan))
584 		return WIRELESS_MODE_TURBO;
585 	return WIRELESS_MODE_11a;
586 }
587 
588 /*
589  * Convert between microseconds and core system clocks.
590  */
591                                      /* 11a Turbo  11b  11g  108g */
592 static const uint8_t CLOCK_RATE[]  = { 40,  80,   22,  44,   88  };
593 
594 #define	CLOCK_FAST_RATE_5GHZ_OFDM	44
595 
596 u_int
597 ath_hal_mac_clks(struct ath_hal *ah, u_int usecs)
598 {
599 	const struct ieee80211_channel *c = AH_PRIVATE(ah)->ah_curchan;
600 	u_int clks;
601 
602 	/* NB: ah_curchan may be null when called attach time */
603 	/* XXX merlin and later specific workaround - 5ghz fast clock is 44 */
604 	if (c != AH_NULL && IS_5GHZ_FAST_CLOCK_EN(ah, c)) {
605 		clks = usecs * CLOCK_FAST_RATE_5GHZ_OFDM;
606 		if (IEEE80211_IS_CHAN_HT40(c))
607 			clks <<= 1;
608 	} else if (c != AH_NULL) {
609 		clks = usecs * CLOCK_RATE[ath_hal_chan2wmode(ah, c)];
610 		if (IEEE80211_IS_CHAN_HT40(c))
611 			clks <<= 1;
612 	} else
613 		clks = usecs * CLOCK_RATE[WIRELESS_MODE_11b];
614 
615 	/* Compensate for half/quarter rate */
616 	if (c != AH_NULL && IEEE80211_IS_CHAN_HALF(c))
617 		clks = clks / 2;
618 	else if (c != AH_NULL && IEEE80211_IS_CHAN_QUARTER(c))
619 		clks = clks / 4;
620 
621 	return clks;
622 }
623 
624 u_int
625 ath_hal_mac_usec(struct ath_hal *ah, u_int clks)
626 {
627 	uint64_t psec;
628 
629 	psec = ath_hal_mac_psec(ah, clks);
630 	return (psec / 1000000);
631 }
632 
633 /*
634  * XXX TODO: half, quarter rates.
635  */
636 uint64_t
637 ath_hal_mac_psec(struct ath_hal *ah, u_int clks)
638 {
639 	const struct ieee80211_channel *c = AH_PRIVATE(ah)->ah_curchan;
640 	uint64_t psec;
641 
642 	/* NB: ah_curchan may be null when called attach time */
643 	/* XXX merlin and later specific workaround - 5ghz fast clock is 44 */
644 	if (c != AH_NULL && IS_5GHZ_FAST_CLOCK_EN(ah, c)) {
645 		psec = (clks * 1000000ULL) / CLOCK_FAST_RATE_5GHZ_OFDM;
646 		if (IEEE80211_IS_CHAN_HT40(c))
647 			psec >>= 1;
648 	} else if (c != AH_NULL) {
649 		psec = (clks * 1000000ULL) / CLOCK_RATE[ath_hal_chan2wmode(ah, c)];
650 		if (IEEE80211_IS_CHAN_HT40(c))
651 			psec >>= 1;
652 	} else
653 		psec = (clks * 1000000ULL) / CLOCK_RATE[WIRELESS_MODE_11b];
654 	return psec;
655 }
656 
657 /*
658  * Setup a h/w rate table's reverse lookup table and
659  * fill in ack durations.  This routine is called for
660  * each rate table returned through the ah_getRateTable
661  * method.  The reverse lookup tables are assumed to be
662  * initialized to zero (or at least the first entry).
663  * We use this as a key that indicates whether or not
664  * we've previously setup the reverse lookup table.
665  *
666  * XXX not reentrant, but shouldn't matter
667  */
668 void
669 ath_hal_setupratetable(struct ath_hal *ah, HAL_RATE_TABLE *rt)
670 {
671 #define	N(a)	(sizeof(a)/sizeof(a[0]))
672 	int i;
673 
674 	if (rt->rateCodeToIndex[0] != 0)	/* already setup */
675 		return;
676 	for (i = 0; i < N(rt->rateCodeToIndex); i++)
677 		rt->rateCodeToIndex[i] = (uint8_t) -1;
678 	for (i = 0; i < rt->rateCount; i++) {
679 		uint8_t code = rt->info[i].rateCode;
680 		uint8_t cix = rt->info[i].controlRate;
681 
682 		HALASSERT(code < N(rt->rateCodeToIndex));
683 		rt->rateCodeToIndex[code] = i;
684 		HALASSERT((code | rt->info[i].shortPreamble) <
685 		    N(rt->rateCodeToIndex));
686 		rt->rateCodeToIndex[code | rt->info[i].shortPreamble] = i;
687 		/*
688 		 * XXX for 11g the control rate to use for 5.5 and 11 Mb/s
689 		 *     depends on whether they are marked as basic rates;
690 		 *     the static tables are setup with an 11b-compatible
691 		 *     2Mb/s rate which will work but is suboptimal
692 		 */
693 		rt->info[i].lpAckDuration = ath_hal_computetxtime(ah, rt,
694 			WLAN_CTRL_FRAME_SIZE, cix, AH_FALSE, AH_TRUE);
695 		rt->info[i].spAckDuration = ath_hal_computetxtime(ah, rt,
696 			WLAN_CTRL_FRAME_SIZE, cix, AH_TRUE, AH_TRUE);
697 	}
698 #undef N
699 }
700 
701 HAL_STATUS
702 ath_hal_getcapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
703 	uint32_t capability, uint32_t *result)
704 {
705 	const HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;
706 
707 	switch (type) {
708 	case HAL_CAP_REG_DMN:		/* regulatory domain */
709 		*result = AH_PRIVATE(ah)->ah_currentRD;
710 		return HAL_OK;
711 	case HAL_CAP_DFS_DMN:		/* DFS Domain */
712 		*result = AH_PRIVATE(ah)->ah_dfsDomain;
713 		return HAL_OK;
714 	case HAL_CAP_CIPHER:		/* cipher handled in hardware */
715 	case HAL_CAP_TKIP_MIC:		/* handle TKIP MIC in hardware */
716 		return HAL_ENOTSUPP;
717 	case HAL_CAP_TKIP_SPLIT:	/* hardware TKIP uses split keys */
718 		return HAL_ENOTSUPP;
719 	case HAL_CAP_PHYCOUNTERS:	/* hardware PHY error counters */
720 		return pCap->halHwPhyCounterSupport ? HAL_OK : HAL_ENXIO;
721 	case HAL_CAP_WME_TKIPMIC:   /* hardware can do TKIP MIC when WMM is turned on */
722 		return HAL_ENOTSUPP;
723 	case HAL_CAP_DIVERSITY:		/* hardware supports fast diversity */
724 		return HAL_ENOTSUPP;
725 	case HAL_CAP_KEYCACHE_SIZE:	/* hardware key cache size */
726 		*result =  pCap->halKeyCacheSize;
727 		return HAL_OK;
728 	case HAL_CAP_NUM_TXQUEUES:	/* number of hardware tx queues */
729 		*result = pCap->halTotalQueues;
730 		return HAL_OK;
731 	case HAL_CAP_VEOL:		/* hardware supports virtual EOL */
732 		return pCap->halVEOLSupport ? HAL_OK : HAL_ENOTSUPP;
733 	case HAL_CAP_PSPOLL:		/* hardware PS-Poll support works */
734 		return pCap->halPSPollBroken ? HAL_ENOTSUPP : HAL_OK;
735 	case HAL_CAP_COMPRESSION:
736 		return pCap->halCompressSupport ? HAL_OK : HAL_ENOTSUPP;
737 	case HAL_CAP_BURST:
738 		return pCap->halBurstSupport ? HAL_OK : HAL_ENOTSUPP;
739 	case HAL_CAP_FASTFRAME:
740 		return pCap->halFastFramesSupport ? HAL_OK : HAL_ENOTSUPP;
741 	case HAL_CAP_DIAG:		/* hardware diagnostic support */
742 		*result = AH_PRIVATE(ah)->ah_diagreg;
743 		return HAL_OK;
744 	case HAL_CAP_TXPOW:		/* global tx power limit  */
745 		switch (capability) {
746 		case 0:			/* facility is supported */
747 			return HAL_OK;
748 		case 1:			/* current limit */
749 			*result = AH_PRIVATE(ah)->ah_powerLimit;
750 			return HAL_OK;
751 		case 2:			/* current max tx power */
752 			*result = AH_PRIVATE(ah)->ah_maxPowerLevel;
753 			return HAL_OK;
754 		case 3:			/* scale factor */
755 			*result = AH_PRIVATE(ah)->ah_tpScale;
756 			return HAL_OK;
757 		}
758 		return HAL_ENOTSUPP;
759 	case HAL_CAP_BSSIDMASK:		/* hardware supports bssid mask */
760 		return pCap->halBssIdMaskSupport ? HAL_OK : HAL_ENOTSUPP;
761 	case HAL_CAP_MCAST_KEYSRCH:	/* multicast frame keycache search */
762 		return pCap->halMcastKeySrchSupport ? HAL_OK : HAL_ENOTSUPP;
763 	case HAL_CAP_TSF_ADJUST:	/* hardware has beacon tsf adjust */
764 		return HAL_ENOTSUPP;
765 	case HAL_CAP_RFSILENT:		/* rfsilent support  */
766 		switch (capability) {
767 		case 0:			/* facility is supported */
768 			return pCap->halRfSilentSupport ? HAL_OK : HAL_ENOTSUPP;
769 		case 1:			/* current setting */
770 			return AH_PRIVATE(ah)->ah_rfkillEnabled ?
771 				HAL_OK : HAL_ENOTSUPP;
772 		case 2:			/* rfsilent config */
773 			*result = AH_PRIVATE(ah)->ah_rfsilent;
774 			return HAL_OK;
775 		}
776 		return HAL_ENOTSUPP;
777 	case HAL_CAP_11D:
778 		return HAL_OK;
779 
780 	case HAL_CAP_HT:
781 		return pCap->halHTSupport ? HAL_OK : HAL_ENOTSUPP;
782 	case HAL_CAP_GTXTO:
783 		return pCap->halGTTSupport ? HAL_OK : HAL_ENOTSUPP;
784 	case HAL_CAP_FAST_CC:
785 		return pCap->halFastCCSupport ? HAL_OK : HAL_ENOTSUPP;
786 	case HAL_CAP_TX_CHAINMASK:	/* mask of TX chains supported */
787 		*result = pCap->halTxChainMask;
788 		return HAL_OK;
789 	case HAL_CAP_RX_CHAINMASK:	/* mask of RX chains supported */
790 		*result = pCap->halRxChainMask;
791 		return HAL_OK;
792 	case HAL_CAP_NUM_GPIO_PINS:
793 		*result = pCap->halNumGpioPins;
794 		return HAL_OK;
795 	case HAL_CAP_CST:
796 		return pCap->halCSTSupport ? HAL_OK : HAL_ENOTSUPP;
797 	case HAL_CAP_RTS_AGGR_LIMIT:
798 		*result = pCap->halRtsAggrLimit;
799 		return HAL_OK;
800 	case HAL_CAP_4ADDR_AGGR:
801 		return pCap->hal4AddrAggrSupport ? HAL_OK : HAL_ENOTSUPP;
802 	case HAL_CAP_EXT_CHAN_DFS:
803 		return pCap->halExtChanDfsSupport ? HAL_OK : HAL_ENOTSUPP;
804 	case HAL_CAP_RX_STBC:
805 		return pCap->halRxStbcSupport ? HAL_OK : HAL_ENOTSUPP;
806 	case HAL_CAP_TX_STBC:
807 		return pCap->halTxStbcSupport ? HAL_OK : HAL_ENOTSUPP;
808 	case HAL_CAP_COMBINED_RADAR_RSSI:
809 		return pCap->halUseCombinedRadarRssi ? HAL_OK : HAL_ENOTSUPP;
810 	case HAL_CAP_AUTO_SLEEP:
811 		return pCap->halAutoSleepSupport ? HAL_OK : HAL_ENOTSUPP;
812 	case HAL_CAP_MBSSID_AGGR_SUPPORT:
813 		return pCap->halMbssidAggrSupport ? HAL_OK : HAL_ENOTSUPP;
814 	case HAL_CAP_SPLIT_4KB_TRANS:	/* hardware handles descriptors straddling 4k page boundary */
815 		return pCap->hal4kbSplitTransSupport ? HAL_OK : HAL_ENOTSUPP;
816 	case HAL_CAP_REG_FLAG:
817 		*result = AH_PRIVATE(ah)->ah_currentRDext;
818 		return HAL_OK;
819 	case HAL_CAP_ENHANCED_DMA_SUPPORT:
820 		return pCap->halEnhancedDmaSupport ? HAL_OK : HAL_ENOTSUPP;
821 	case HAL_CAP_NUM_TXMAPS:
822 		*result = pCap->halNumTxMaps;
823 		return HAL_OK;
824 	case HAL_CAP_TXDESCLEN:
825 		*result = pCap->halTxDescLen;
826 		return HAL_OK;
827 	case HAL_CAP_TXSTATUSLEN:
828 		*result = pCap->halTxStatusLen;
829 		return HAL_OK;
830 	case HAL_CAP_RXSTATUSLEN:
831 		*result = pCap->halRxStatusLen;
832 		return HAL_OK;
833 	case HAL_CAP_RXFIFODEPTH:
834 		switch (capability) {
835 		case HAL_RX_QUEUE_HP:
836 			*result = pCap->halRxHpFifoDepth;
837 			return HAL_OK;
838 		case HAL_RX_QUEUE_LP:
839 			*result = pCap->halRxLpFifoDepth;
840 			return HAL_OK;
841 		default:
842 			return HAL_ENOTSUPP;
843 	}
844 	case HAL_CAP_RXBUFSIZE:
845 	case HAL_CAP_NUM_MR_RETRIES:
846 		*result = pCap->halNumMRRetries;
847 		return HAL_OK;
848 	case HAL_CAP_BT_COEX:
849 		return pCap->halBtCoexSupport ? HAL_OK : HAL_ENOTSUPP;
850 	case HAL_CAP_SPECTRAL_SCAN:
851 		return pCap->halSpectralScanSupport ? HAL_OK : HAL_ENOTSUPP;
852 	case HAL_CAP_HT20_SGI:
853 		return pCap->halHTSGI20Support ? HAL_OK : HAL_ENOTSUPP;
854 	case HAL_CAP_RXTSTAMP_PREC:	/* rx desc tstamp precision (bits) */
855 		*result = pCap->halRxTstampPrecision;
856 		return HAL_OK;
857 	case HAL_CAP_ANT_DIV_COMB:	/* AR9285/AR9485 LNA diversity */
858 		return pCap->halAntDivCombSupport ? HAL_OK  : HAL_ENOTSUPP;
859 
860 	case HAL_CAP_ENHANCED_DFS_SUPPORT:
861 		return pCap->halEnhancedDfsSupport ? HAL_OK : HAL_ENOTSUPP;
862 
863 	/* FreeBSD-specific entries for now */
864 	case HAL_CAP_RXORN_FATAL:	/* HAL_INT_RXORN treated as fatal  */
865 		return AH_PRIVATE(ah)->ah_rxornIsFatal ? HAL_OK : HAL_ENOTSUPP;
866 	case HAL_CAP_INTRMASK:		/* mask of supported interrupts */
867 		*result = pCap->halIntrMask;
868 		return HAL_OK;
869 	case HAL_CAP_BSSIDMATCH:	/* hardware has disable bssid match */
870 		return pCap->halBssidMatchSupport ? HAL_OK : HAL_ENOTSUPP;
871 	case HAL_CAP_STREAMS:		/* number of 11n spatial streams */
872 		switch (capability) {
873 		case 0:			/* TX */
874 			*result = pCap->halTxStreams;
875 			return HAL_OK;
876 		case 1:			/* RX */
877 			*result = pCap->halRxStreams;
878 			return HAL_OK;
879 		default:
880 			return HAL_ENOTSUPP;
881 		}
882 	case HAL_CAP_RXDESC_SELFLINK:	/* hardware supports self-linked final RX descriptors correctly */
883 		return pCap->halHasRxSelfLinkedTail ? HAL_OK : HAL_ENOTSUPP;
884 	case HAL_CAP_BB_READ_WAR:		/* Baseband read WAR */
885 		return pCap->halHasBBReadWar? HAL_OK : HAL_ENOTSUPP;
886 	case HAL_CAP_SERIALISE_WAR:		/* PCI register serialisation */
887 		return pCap->halSerialiseRegWar ? HAL_OK : HAL_ENOTSUPP;
888 	case HAL_CAP_MFP:			/* Management frame protection setting */
889 		*result = pCap->halMfpSupport;
890 		return HAL_OK;
891 	case HAL_CAP_RX_LNA_MIXING:	/* Hardware uses an RX LNA mixer to map 2 antennas to a 1 stream receiver */
892 		return pCap->halRxUsingLnaMixing ? HAL_OK : HAL_ENOTSUPP;
893 	case HAL_CAP_DO_MYBEACON:	/* Hardware supports filtering my-beacons */
894 		return pCap->halRxDoMyBeacon ? HAL_OK : HAL_ENOTSUPP;
895 	case HAL_CAP_TXTSTAMP_PREC:	/* tx desc tstamp precision (bits) */
896 		*result = pCap->halTxTstampPrecision;
897 		return HAL_OK;
898 	default:
899 		return HAL_EINVAL;
900 	}
901 }
902 
903 HAL_BOOL
904 ath_hal_setcapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
905 	uint32_t capability, uint32_t setting, HAL_STATUS *status)
906 {
907 
908 	switch (type) {
909 	case HAL_CAP_TXPOW:
910 		switch (capability) {
911 		case 3:
912 			if (setting <= HAL_TP_SCALE_MIN) {
913 				AH_PRIVATE(ah)->ah_tpScale = setting;
914 				return AH_TRUE;
915 			}
916 			break;
917 		}
918 		break;
919 	case HAL_CAP_RFSILENT:		/* rfsilent support  */
920 		/*
921 		 * NB: allow even if halRfSilentSupport is false
922 		 *     in case the EEPROM is misprogrammed.
923 		 */
924 		switch (capability) {
925 		case 1:			/* current setting */
926 			AH_PRIVATE(ah)->ah_rfkillEnabled = (setting != 0);
927 			return AH_TRUE;
928 		case 2:			/* rfsilent config */
929 			/* XXX better done per-chip for validation? */
930 			AH_PRIVATE(ah)->ah_rfsilent = setting;
931 			return AH_TRUE;
932 		}
933 		break;
934 	case HAL_CAP_REG_DMN:		/* regulatory domain */
935 		AH_PRIVATE(ah)->ah_currentRD = setting;
936 		return AH_TRUE;
937 	case HAL_CAP_RXORN_FATAL:	/* HAL_INT_RXORN treated as fatal  */
938 		AH_PRIVATE(ah)->ah_rxornIsFatal = setting;
939 		return AH_TRUE;
940 	default:
941 		break;
942 	}
943 	if (status)
944 		*status = HAL_EINVAL;
945 	return AH_FALSE;
946 }
947 
948 /*
949  * Common support for getDiagState method.
950  */
951 
952 static u_int
953 ath_hal_getregdump(struct ath_hal *ah, const HAL_REGRANGE *regs,
954 	void *dstbuf, int space)
955 {
956 	uint32_t *dp = dstbuf;
957 	int i;
958 
959 	for (i = 0; space >= 2*sizeof(uint32_t); i++) {
960 		uint32_t r = regs[i].start;
961 		uint32_t e = regs[i].end;
962 		*dp++ = r;
963 		*dp++ = e;
964 		space -= 2*sizeof(uint32_t);
965 		do {
966 			*dp++ = OS_REG_READ(ah, r);
967 			r += sizeof(uint32_t);
968 			space -= sizeof(uint32_t);
969 		} while (r <= e && space >= sizeof(uint32_t));
970 	}
971 	return (char *) dp - (char *) dstbuf;
972 }
973 
974 static void
975 ath_hal_setregs(struct ath_hal *ah, const HAL_REGWRITE *regs, int space)
976 {
977 	while (space >= sizeof(HAL_REGWRITE)) {
978 		OS_REG_WRITE(ah, regs->addr, regs->value);
979 		regs++, space -= sizeof(HAL_REGWRITE);
980 	}
981 }
982 
983 HAL_BOOL
984 ath_hal_getdiagstate(struct ath_hal *ah, int request,
985 	const void *args, uint32_t argsize,
986 	void **result, uint32_t *resultsize)
987 {
988 
989 	switch (request) {
990 	case HAL_DIAG_REVS:
991 		*result = &AH_PRIVATE(ah)->ah_devid;
992 		*resultsize = sizeof(HAL_REVS);
993 		return AH_TRUE;
994 	case HAL_DIAG_REGS:
995 		*resultsize = ath_hal_getregdump(ah, args, *result,*resultsize);
996 		return AH_TRUE;
997 	case HAL_DIAG_SETREGS:
998 		ath_hal_setregs(ah, args, argsize);
999 		*resultsize = 0;
1000 		return AH_TRUE;
1001 	case HAL_DIAG_FATALERR:
1002 		*result = &AH_PRIVATE(ah)->ah_fatalState[0];
1003 		*resultsize = sizeof(AH_PRIVATE(ah)->ah_fatalState);
1004 		return AH_TRUE;
1005 	case HAL_DIAG_EEREAD:
1006 		if (argsize != sizeof(uint16_t))
1007 			return AH_FALSE;
1008 		if (!ath_hal_eepromRead(ah, *(const uint16_t *)args, *result))
1009 			return AH_FALSE;
1010 		*resultsize = sizeof(uint16_t);
1011 		return AH_TRUE;
1012 #ifdef AH_PRIVATE_DIAG
1013 	case HAL_DIAG_SETKEY: {
1014 		const HAL_DIAG_KEYVAL *dk;
1015 
1016 		if (argsize != sizeof(HAL_DIAG_KEYVAL))
1017 			return AH_FALSE;
1018 		dk = (const HAL_DIAG_KEYVAL *)args;
1019 		return ah->ah_setKeyCacheEntry(ah, dk->dk_keyix,
1020 			&dk->dk_keyval, dk->dk_mac, dk->dk_xor);
1021 	}
1022 	case HAL_DIAG_RESETKEY:
1023 		if (argsize != sizeof(uint16_t))
1024 			return AH_FALSE;
1025 		return ah->ah_resetKeyCacheEntry(ah, *(const uint16_t *)args);
1026 #ifdef AH_SUPPORT_WRITE_EEPROM
1027 	case HAL_DIAG_EEWRITE: {
1028 		const HAL_DIAG_EEVAL *ee;
1029 		if (argsize != sizeof(HAL_DIAG_EEVAL))
1030 			return AH_FALSE;
1031 		ee = (const HAL_DIAG_EEVAL *)args;
1032 		return ath_hal_eepromWrite(ah, ee->ee_off, ee->ee_data);
1033 	}
1034 #endif /* AH_SUPPORT_WRITE_EEPROM */
1035 #endif /* AH_PRIVATE_DIAG */
1036 	case HAL_DIAG_11NCOMPAT:
1037 		if (argsize == 0) {
1038 			*resultsize = sizeof(uint32_t);
1039 			*((uint32_t *)(*result)) =
1040 				AH_PRIVATE(ah)->ah_11nCompat;
1041 		} else if (argsize == sizeof(uint32_t)) {
1042 			AH_PRIVATE(ah)->ah_11nCompat = *(const uint32_t *)args;
1043 		} else
1044 			return AH_FALSE;
1045 		return AH_TRUE;
1046 	case HAL_DIAG_CHANSURVEY:
1047 		*result = &AH_PRIVATE(ah)->ah_chansurvey;
1048 		*resultsize = sizeof(HAL_CHANNEL_SURVEY);
1049 		return AH_TRUE;
1050 	}
1051 	return AH_FALSE;
1052 }
1053 
1054 /*
1055  * Set the properties of the tx queue with the parameters
1056  * from qInfo.
1057  */
1058 HAL_BOOL
1059 ath_hal_setTxQProps(struct ath_hal *ah,
1060 	HAL_TX_QUEUE_INFO *qi, const HAL_TXQ_INFO *qInfo)
1061 {
1062 	uint32_t cw;
1063 
1064 	if (qi->tqi_type == HAL_TX_QUEUE_INACTIVE) {
1065 		HALDEBUG(ah, HAL_DEBUG_TXQUEUE,
1066 		    "%s: inactive queue\n", __func__);
1067 		return AH_FALSE;
1068 	}
1069 	/* XXX validate parameters */
1070 	qi->tqi_ver = qInfo->tqi_ver;
1071 	qi->tqi_subtype = qInfo->tqi_subtype;
1072 	qi->tqi_qflags = qInfo->tqi_qflags;
1073 	qi->tqi_priority = qInfo->tqi_priority;
1074 	if (qInfo->tqi_aifs != HAL_TXQ_USEDEFAULT)
1075 		qi->tqi_aifs = AH_MIN(qInfo->tqi_aifs, 255);
1076 	else
1077 		qi->tqi_aifs = INIT_AIFS;
1078 	if (qInfo->tqi_cwmin != HAL_TXQ_USEDEFAULT) {
1079 		cw = AH_MIN(qInfo->tqi_cwmin, 1024);
1080 		/* make sure that the CWmin is of the form (2^n - 1) */
1081 		qi->tqi_cwmin = 1;
1082 		while (qi->tqi_cwmin < cw)
1083 			qi->tqi_cwmin = (qi->tqi_cwmin << 1) | 1;
1084 	} else
1085 		qi->tqi_cwmin = qInfo->tqi_cwmin;
1086 	if (qInfo->tqi_cwmax != HAL_TXQ_USEDEFAULT) {
1087 		cw = AH_MIN(qInfo->tqi_cwmax, 1024);
1088 		/* make sure that the CWmax is of the form (2^n - 1) */
1089 		qi->tqi_cwmax = 1;
1090 		while (qi->tqi_cwmax < cw)
1091 			qi->tqi_cwmax = (qi->tqi_cwmax << 1) | 1;
1092 	} else
1093 		qi->tqi_cwmax = INIT_CWMAX;
1094 	/* Set retry limit values */
1095 	if (qInfo->tqi_shretry != 0)
1096 		qi->tqi_shretry = AH_MIN(qInfo->tqi_shretry, 15);
1097 	else
1098 		qi->tqi_shretry = INIT_SH_RETRY;
1099 	if (qInfo->tqi_lgretry != 0)
1100 		qi->tqi_lgretry = AH_MIN(qInfo->tqi_lgretry, 15);
1101 	else
1102 		qi->tqi_lgretry = INIT_LG_RETRY;
1103 	qi->tqi_cbrPeriod = qInfo->tqi_cbrPeriod;
1104 	qi->tqi_cbrOverflowLimit = qInfo->tqi_cbrOverflowLimit;
1105 	qi->tqi_burstTime = qInfo->tqi_burstTime;
1106 	qi->tqi_readyTime = qInfo->tqi_readyTime;
1107 
1108 	switch (qInfo->tqi_subtype) {
1109 	case HAL_WME_UPSD:
1110 		if (qi->tqi_type == HAL_TX_QUEUE_DATA)
1111 			qi->tqi_intFlags = HAL_TXQ_USE_LOCKOUT_BKOFF_DIS;
1112 		break;
1113 	default:
1114 		break;		/* NB: silence compiler */
1115 	}
1116 	return AH_TRUE;
1117 }
1118 
1119 HAL_BOOL
1120 ath_hal_getTxQProps(struct ath_hal *ah,
1121 	HAL_TXQ_INFO *qInfo, const HAL_TX_QUEUE_INFO *qi)
1122 {
1123 	if (qi->tqi_type == HAL_TX_QUEUE_INACTIVE) {
1124 		HALDEBUG(ah, HAL_DEBUG_TXQUEUE,
1125 		    "%s: inactive queue\n", __func__);
1126 		return AH_FALSE;
1127 	}
1128 
1129 	qInfo->tqi_ver = qi->tqi_ver;
1130 	qInfo->tqi_subtype = qi->tqi_subtype;
1131 	qInfo->tqi_qflags = qi->tqi_qflags;
1132 	qInfo->tqi_priority = qi->tqi_priority;
1133 	qInfo->tqi_aifs = qi->tqi_aifs;
1134 	qInfo->tqi_cwmin = qi->tqi_cwmin;
1135 	qInfo->tqi_cwmax = qi->tqi_cwmax;
1136 	qInfo->tqi_shretry = qi->tqi_shretry;
1137 	qInfo->tqi_lgretry = qi->tqi_lgretry;
1138 	qInfo->tqi_cbrPeriod = qi->tqi_cbrPeriod;
1139 	qInfo->tqi_cbrOverflowLimit = qi->tqi_cbrOverflowLimit;
1140 	qInfo->tqi_burstTime = qi->tqi_burstTime;
1141 	qInfo->tqi_readyTime = qi->tqi_readyTime;
1142 	qInfo->tqi_compBuf = qi->tqi_physCompBuf;
1143 	return AH_TRUE;
1144 }
1145 
1146                                      /* 11a Turbo  11b  11g  108g */
1147 static const int16_t NOISE_FLOOR[] = { -96, -93,  -98, -96,  -93 };
1148 
1149 /*
1150  * Read the current channel noise floor and return.
1151  * If nf cal hasn't finished, channel noise floor should be 0
1152  * and we return a nominal value based on band and frequency.
1153  *
1154  * NB: This is a private routine used by per-chip code to
1155  *     implement the ah_getChanNoise method.
1156  */
1157 int16_t
1158 ath_hal_getChanNoise(struct ath_hal *ah, const struct ieee80211_channel *chan)
1159 {
1160 	HAL_CHANNEL_INTERNAL *ichan;
1161 
1162 	ichan = ath_hal_checkchannel(ah, chan);
1163 	if (ichan == AH_NULL) {
1164 		HALDEBUG(ah, HAL_DEBUG_NFCAL,
1165 		    "%s: invalid channel %u/0x%x; no mapping\n",
1166 		    __func__, chan->ic_freq, chan->ic_flags);
1167 		return 0;
1168 	}
1169 	if (ichan->rawNoiseFloor == 0) {
1170 		WIRELESS_MODE mode = ath_hal_chan2wmode(ah, chan);
1171 
1172 		HALASSERT(mode < WIRELESS_MODE_MAX);
1173 		return NOISE_FLOOR[mode] + ath_hal_getNfAdjust(ah, ichan);
1174 	} else
1175 		return ichan->rawNoiseFloor + ichan->noiseFloorAdjust;
1176 }
1177 
1178 /*
1179  * Fetch the current setup of ctl/ext noise floor values.
1180  *
1181  * If the CHANNEL_MIMO_NF_VALID flag isn't set, the array is simply
1182  * populated with values from NOISE_FLOOR[] + ath_hal_getNfAdjust().
1183  *
1184  * The caller must supply ctl/ext NF arrays which are at least
1185  * AH_MAX_CHAINS entries long.
1186  */
1187 int
1188 ath_hal_get_mimo_chan_noise(struct ath_hal *ah,
1189     const struct ieee80211_channel *chan, int16_t *nf_ctl,
1190     int16_t *nf_ext)
1191 {
1192 	HAL_CHANNEL_INTERNAL *ichan;
1193 	int i;
1194 
1195 	ichan = ath_hal_checkchannel(ah, chan);
1196 	if (ichan == AH_NULL) {
1197 		HALDEBUG(ah, HAL_DEBUG_NFCAL,
1198 		    "%s: invalid channel %u/0x%x; no mapping\n",
1199 		    __func__, chan->ic_freq, chan->ic_flags);
1200 		for (i = 0; i < AH_MAX_CHAINS; i++) {
1201 			nf_ctl[i] = nf_ext[i] = 0;
1202 		}
1203 		return 0;
1204 	}
1205 
1206 	/* Return 0 if there's no valid MIMO values (yet) */
1207 	if (! (ichan->privFlags & CHANNEL_MIMO_NF_VALID)) {
1208 		for (i = 0; i < AH_MAX_CHAINS; i++) {
1209 			nf_ctl[i] = nf_ext[i] = 0;
1210 		}
1211 		return 0;
1212 	}
1213 	if (ichan->rawNoiseFloor == 0) {
1214 		WIRELESS_MODE mode = ath_hal_chan2wmode(ah, chan);
1215 		HALASSERT(mode < WIRELESS_MODE_MAX);
1216 		/*
1217 		 * See the comment below - this could cause issues for
1218 		 * stations which have a very low RSSI, below the
1219 		 * 'normalised' NF values in NOISE_FLOOR[].
1220 		 */
1221 		for (i = 0; i < AH_MAX_CHAINS; i++) {
1222 			nf_ctl[i] = nf_ext[i] = NOISE_FLOOR[mode] +
1223 			    ath_hal_getNfAdjust(ah, ichan);
1224 		}
1225 		return 1;
1226 	} else {
1227 		/*
1228 		 * The value returned here from a MIMO radio is presumed to be
1229 		 * "good enough" as a NF calculation. As RSSI values are calculated
1230 		 * against this, an adjusted NF may be higher than the RSSI value
1231 		 * returned from a vary weak station, resulting in an obscenely
1232 		 * high signal strength calculation being returned.
1233 		 *
1234 		 * This should be re-evaluated at a later date, along with any
1235 		 * signal strength calculations which are made. Quite likely the
1236 		 * RSSI values will need to be adjusted to ensure the calculations
1237 		 * don't "wrap" when RSSI is less than the "adjusted" NF value.
1238 		 * ("Adjust" here is via ichan->noiseFloorAdjust.)
1239 		 */
1240 		for (i = 0; i < AH_MAX_CHAINS; i++) {
1241 			nf_ctl[i] = ichan->noiseFloorCtl[i] + ath_hal_getNfAdjust(ah, ichan);
1242 			nf_ext[i] = ichan->noiseFloorExt[i] + ath_hal_getNfAdjust(ah, ichan);
1243 		}
1244 		return 1;
1245 	}
1246 }
1247 
1248 /*
1249  * Process all valid raw noise floors into the dBm noise floor values.
1250  * Though our device has no reference for a dBm noise floor, we perform
1251  * a relative minimization of NF's based on the lowest NF found across a
1252  * channel scan.
1253  */
1254 void
1255 ath_hal_process_noisefloor(struct ath_hal *ah)
1256 {
1257 	HAL_CHANNEL_INTERNAL *c;
1258 	int16_t correct2, correct5;
1259 	int16_t lowest2, lowest5;
1260 	int i;
1261 
1262 	/*
1263 	 * Find the lowest 2GHz and 5GHz noise floor values after adjusting
1264 	 * for statistically recorded NF/channel deviation.
1265 	 */
1266 	correct2 = lowest2 = 0;
1267 	correct5 = lowest5 = 0;
1268 	for (i = 0; i < AH_PRIVATE(ah)->ah_nchan; i++) {
1269 		WIRELESS_MODE mode;
1270 		int16_t nf;
1271 
1272 		c = &AH_PRIVATE(ah)->ah_channels[i];
1273 		if (c->rawNoiseFloor >= 0)
1274 			continue;
1275 		/* XXX can't identify proper mode */
1276 		mode = IS_CHAN_5GHZ(c) ? WIRELESS_MODE_11a : WIRELESS_MODE_11g;
1277 		nf = c->rawNoiseFloor + NOISE_FLOOR[mode] +
1278 			ath_hal_getNfAdjust(ah, c);
1279 		if (IS_CHAN_5GHZ(c)) {
1280 			if (nf < lowest5) {
1281 				lowest5 = nf;
1282 				correct5 = NOISE_FLOOR[mode] -
1283 				    (c->rawNoiseFloor + ath_hal_getNfAdjust(ah, c));
1284 			}
1285 		} else {
1286 			if (nf < lowest2) {
1287 				lowest2 = nf;
1288 				correct2 = NOISE_FLOOR[mode] -
1289 				    (c->rawNoiseFloor + ath_hal_getNfAdjust(ah, c));
1290 			}
1291 		}
1292 	}
1293 
1294 	/* Correct the channels to reach the expected NF value */
1295 	for (i = 0; i < AH_PRIVATE(ah)->ah_nchan; i++) {
1296 		c = &AH_PRIVATE(ah)->ah_channels[i];
1297 		if (c->rawNoiseFloor >= 0)
1298 			continue;
1299 		/* Apply correction factor */
1300 		c->noiseFloorAdjust = ath_hal_getNfAdjust(ah, c) +
1301 			(IS_CHAN_5GHZ(c) ? correct5 : correct2);
1302 		HALDEBUG(ah, HAL_DEBUG_NFCAL, "%u raw nf %d adjust %d\n",
1303 		    c->channel, c->rawNoiseFloor, c->noiseFloorAdjust);
1304 	}
1305 }
1306 
1307 /*
1308  * INI support routines.
1309  */
1310 
1311 int
1312 ath_hal_ini_write(struct ath_hal *ah, const HAL_INI_ARRAY *ia,
1313 	int col, int regWr)
1314 {
1315 	int r;
1316 
1317 	HALASSERT(col < ia->cols);
1318 	for (r = 0; r < ia->rows; r++) {
1319 		OS_REG_WRITE(ah, HAL_INI_VAL(ia, r, 0),
1320 		    HAL_INI_VAL(ia, r, col));
1321 
1322 		/* Analog shift register delay seems needed for Merlin - PR kern/154220 */
1323 		if (HAL_INI_VAL(ia, r, 0) >= 0x7800 && HAL_INI_VAL(ia, r, 0) < 0x7900)
1324 			OS_DELAY(100);
1325 
1326 		DMA_YIELD(regWr);
1327 	}
1328 	return regWr;
1329 }
1330 
1331 void
1332 ath_hal_ini_bank_setup(uint32_t data[], const HAL_INI_ARRAY *ia, int col)
1333 {
1334 	int r;
1335 
1336 	HALASSERT(col < ia->cols);
1337 	for (r = 0; r < ia->rows; r++)
1338 		data[r] = HAL_INI_VAL(ia, r, col);
1339 }
1340 
1341 int
1342 ath_hal_ini_bank_write(struct ath_hal *ah, const HAL_INI_ARRAY *ia,
1343 	const uint32_t data[], int regWr)
1344 {
1345 	int r;
1346 
1347 	for (r = 0; r < ia->rows; r++) {
1348 		OS_REG_WRITE(ah, HAL_INI_VAL(ia, r, 0), data[r]);
1349 		DMA_YIELD(regWr);
1350 	}
1351 	return regWr;
1352 }
1353 
1354 /*
1355  * These are EEPROM board related routines which should likely live in
1356  * a helper library of some sort.
1357  */
1358 
1359 /**************************************************************
1360  * ath_ee_getLowerUppderIndex
1361  *
1362  * Return indices surrounding the value in sorted integer lists.
1363  * Requirement: the input list must be monotonically increasing
1364  *     and populated up to the list size
1365  * Returns: match is set if an index in the array matches exactly
1366  *     or a the target is before or after the range of the array.
1367  */
1368 HAL_BOOL
1369 ath_ee_getLowerUpperIndex(uint8_t target, uint8_t *pList, uint16_t listSize,
1370                    uint16_t *indexL, uint16_t *indexR)
1371 {
1372     uint16_t i;
1373 
1374     /*
1375      * Check first and last elements for beyond ordered array cases.
1376      */
1377     if (target <= pList[0]) {
1378         *indexL = *indexR = 0;
1379         return AH_TRUE;
1380     }
1381     if (target >= pList[listSize-1]) {
1382         *indexL = *indexR = (uint16_t)(listSize - 1);
1383         return AH_TRUE;
1384     }
1385 
1386     /* look for value being near or between 2 values in list */
1387     for (i = 0; i < listSize - 1; i++) {
1388         /*
1389          * If value is close to the current value of the list
1390          * then target is not between values, it is one of the values
1391          */
1392         if (pList[i] == target) {
1393             *indexL = *indexR = i;
1394             return AH_TRUE;
1395         }
1396         /*
1397          * Look for value being between current value and next value
1398          * if so return these 2 values
1399          */
1400         if (target < pList[i + 1]) {
1401             *indexL = i;
1402             *indexR = (uint16_t)(i + 1);
1403             return AH_FALSE;
1404         }
1405     }
1406     HALASSERT(0);
1407     *indexL = *indexR = 0;
1408     return AH_FALSE;
1409 }
1410 
1411 /**************************************************************
1412  * ath_ee_FillVpdTable
1413  *
1414  * Fill the Vpdlist for indices Pmax-Pmin
1415  * Note: pwrMin, pwrMax and Vpdlist are all in dBm * 4
1416  */
1417 HAL_BOOL
1418 ath_ee_FillVpdTable(uint8_t pwrMin, uint8_t pwrMax, uint8_t *pPwrList,
1419                    uint8_t *pVpdList, uint16_t numIntercepts, uint8_t *pRetVpdList)
1420 {
1421     uint16_t  i, k;
1422     uint8_t   currPwr = pwrMin;
1423     uint16_t  idxL, idxR;
1424 
1425     HALASSERT(pwrMax > pwrMin);
1426     for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) {
1427         ath_ee_getLowerUpperIndex(currPwr, pPwrList, numIntercepts,
1428                            &(idxL), &(idxR));
1429         if (idxR < 1)
1430             idxR = 1;           /* extrapolate below */
1431         if (idxL == numIntercepts - 1)
1432             idxL = (uint16_t)(numIntercepts - 2);   /* extrapolate above */
1433         if (pPwrList[idxL] == pPwrList[idxR])
1434             k = pVpdList[idxL];
1435         else
1436             k = (uint16_t)( ((currPwr - pPwrList[idxL]) * pVpdList[idxR] + (pPwrList[idxR] - currPwr) * pVpdList[idxL]) /
1437                   (pPwrList[idxR] - pPwrList[idxL]) );
1438         HALASSERT(k < 256);
1439         pRetVpdList[i] = (uint8_t)k;
1440         currPwr += 2;               /* half dB steps */
1441     }
1442 
1443     return AH_TRUE;
1444 }
1445 
1446 /**************************************************************************
1447  * ath_ee_interpolate
1448  *
1449  * Returns signed interpolated or the scaled up interpolated value
1450  */
1451 int16_t
1452 ath_ee_interpolate(uint16_t target, uint16_t srcLeft, uint16_t srcRight,
1453             int16_t targetLeft, int16_t targetRight)
1454 {
1455     int16_t rv;
1456 
1457     if (srcRight == srcLeft) {
1458         rv = targetLeft;
1459     } else {
1460         rv = (int16_t)( ((target - srcLeft) * targetRight +
1461               (srcRight - target) * targetLeft) / (srcRight - srcLeft) );
1462     }
1463     return rv;
1464 }
1465 
1466 /*
1467  * Adjust the TSF.
1468  */
1469 void
1470 ath_hal_adjusttsf(struct ath_hal *ah, int32_t tsfdelta)
1471 {
1472 	/* XXX handle wrap/overflow */
1473 	OS_REG_WRITE(ah, AR_TSF_L32, OS_REG_READ(ah, AR_TSF_L32) + tsfdelta);
1474 }
1475 
1476 /*
1477  * Enable or disable CCA.
1478  */
1479 void
1480 ath_hal_setcca(struct ath_hal *ah, int ena)
1481 {
1482 	/*
1483 	 * NB: fill me in; this is not provided by default because disabling
1484 	 *     CCA in most locales violates regulatory.
1485 	 */
1486 }
1487 
1488 /*
1489  * Get CCA setting.
1490  *
1491  * XXX TODO: turn this and the above function into methods
1492  * in case there are chipset differences in handling CCA.
1493  */
1494 int
1495 ath_hal_getcca(struct ath_hal *ah)
1496 {
1497 	u_int32_t diag;
1498 	if (ath_hal_getcapability(ah, HAL_CAP_DIAG, 0, &diag) != HAL_OK)
1499 		return 1;
1500 	return ((diag & 0x500000) == 0);
1501 }
1502 
1503 /*
1504  * Set the current state of self-generated ACK and RTS/CTS frames.
1505  *
1506  * For correct DFS operation, the device should not even /ACK/ frames
1507  * that are sent to it during CAC or CSA.
1508  */
1509 void
1510 ath_hal_set_dfs_cac_tx_quiet(struct ath_hal *ah, HAL_BOOL ena)
1511 {
1512 
1513 	if (ah->ah_setDfsCacTxQuiet == NULL)
1514 		return;
1515 	ah->ah_setDfsCacTxQuiet(ah, ena);
1516 }
1517 
1518 /*
1519  * This routine is only needed when supporting EEPROM-in-RAM setups
1520  * (eg embedded SoCs and on-board PCI/PCIe devices.)
1521  */
1522 /* NB: This is in 16 bit words; not bytes */
1523 /* XXX This doesn't belong here!  */
1524 #define ATH_DATA_EEPROM_SIZE    2048
1525 
1526 HAL_BOOL
1527 ath_hal_EepromDataRead(struct ath_hal *ah, u_int off, uint16_t *data)
1528 {
1529 	if (ah->ah_eepromdata == AH_NULL) {
1530 		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: no eeprom data!\n", __func__);
1531 		return AH_FALSE;
1532 	}
1533 	if (off > ATH_DATA_EEPROM_SIZE) {
1534 		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: offset %x > %x\n",
1535 		    __func__, off, ATH_DATA_EEPROM_SIZE);
1536 		return AH_FALSE;
1537 	}
1538 	(*data) = ah->ah_eepromdata[off];
1539 	return AH_TRUE;
1540 }
1541 
1542 /*
1543  * Do a 2GHz specific MHz->IEEE based on the hardware
1544  * frequency.
1545  *
1546  * This is the unmapped frequency which is programmed into the hardware.
1547  */
1548 int
1549 ath_hal_mhz2ieee_2ghz(struct ath_hal *ah, int freq)
1550 {
1551 
1552 	if (freq == 2484)
1553 		return 14;
1554 	if (freq < 2484)
1555 		return ((int) freq - 2407) / 5;
1556 	else
1557 		return 15 + ((freq - 2512) / 20);
1558 }
1559 
1560 /*
1561  * Clear the current survey data.
1562  *
1563  * This should be done during a channel change.
1564  */
1565 void
1566 ath_hal_survey_clear(struct ath_hal *ah)
1567 {
1568 
1569 	OS_MEMZERO(&AH_PRIVATE(ah)->ah_chansurvey,
1570 	    sizeof(AH_PRIVATE(ah)->ah_chansurvey));
1571 }
1572 
1573 /*
1574  * Add a sample to the channel survey.
1575  */
1576 void
1577 ath_hal_survey_add_sample(struct ath_hal *ah, HAL_SURVEY_SAMPLE *hs)
1578 {
1579 	HAL_CHANNEL_SURVEY *cs;
1580 
1581 	cs = &AH_PRIVATE(ah)->ah_chansurvey;
1582 
1583 	OS_MEMCPY(&cs->samples[cs->cur_sample], hs, sizeof(*hs));
1584 	cs->samples[cs->cur_sample].seq_num = cs->cur_seq;
1585 	cs->cur_sample = (cs->cur_sample + 1) % CHANNEL_SURVEY_SAMPLE_COUNT;
1586 	cs->cur_seq++;
1587 }
1588