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