2 * SPDX-License-Identifier: ISC
4 * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting
5 * Copyright (c) 2002-2008 Atheros Communications, Inc.
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.
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.
24 #include "ah_internal.h"
26 #include "ah_eeprom.h" /* for 5ghz fast clock flag */
28 #include "ar5416/ar5416reg.h" /* NB: includes ar5212reg.h */
29 #include "ar9003/ar9300_devid.h"
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);
36 ath_hal_add_chip(struct ath_hal_chip *ahc)
39 TAILQ_INSERT_TAIL(&ah_chip_list, ahc, node);
44 ath_hal_remove_chip(struct ath_hal_chip *ahc)
47 TAILQ_REMOVE(&ah_chip_list, ahc, node);
52 * Check the set of registered chips to see if any recognize
53 * the device as one they can support.
56 ath_hal_probe(uint16_t vendorid, uint16_t devid)
58 struct ath_hal_chip * const *pchip;
59 struct ath_hal_chip *pc;
62 OS_SET_FOREACH(pchip, ah_chips) {
63 const char *name = (*pchip)->probe(vendorid, devid);
69 TAILQ_FOREACH(pc, &ah_chip_list, node) {
70 const char *name = pc->probe(vendorid, devid);
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
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,
91 struct ath_hal_chip * const *pchip;
92 struct ath_hal_chip *pc;
94 OS_SET_FOREACH(pchip, ah_chips) {
95 struct ath_hal_chip *chip = *pchip;
98 /* XXX don't have vendorid, assume atheros one works */
99 if (chip->probe(ATHEROS_VENDOR_ID, devid) == AH_NULL)
101 ah = chip->attach(devid, sc, st, sh, eepromdata, ah_config,
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;
117 TAILQ_FOREACH(pc, &ah_chip_list, node) {
118 struct ath_hal_chip *chip = pc;
121 /* XXX don't have vendorid, assume atheros one works */
122 if (chip->probe(ATHEROS_VENDOR_ID, devid) == AH_NULL)
124 ah = chip->attach(devid, sc, st, sh, eepromdata, ah_config,
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;
143 ath_hal_mac_name(struct ath_hal *ah)
145 switch (ah->ah_macVersion) {
146 case AR_SREV_VERSION_CRETE:
147 case AR_SREV_VERSION_MAUI_1:
149 case AR_SREV_VERSION_MAUI_2:
150 case AR_SREV_VERSION_OAHU:
152 case AR_SREV_VERSION_VENICE:
154 case AR_SREV_VERSION_GRIFFIN:
156 case AR_SREV_VERSION_CONDOR:
158 case AR_SREV_VERSION_EAGLE:
160 case AR_SREV_VERSION_COBRA:
162 case AR_SREV_2425: /* Swan */
164 case AR_SREV_2417: /* Nala */
166 case AR_XSREV_VERSION_OWL_PCI:
168 case AR_XSREV_VERSION_OWL_PCIE:
170 case AR_XSREV_VERSION_HOWL:
172 case AR_XSREV_VERSION_SOWL:
174 case AR_XSREV_VERSION_MERLIN:
175 if (AH_PRIVATE(ah)->ah_ispcie)
178 case AR_XSREV_VERSION_KITE:
180 case AR_XSREV_VERSION_KIWI:
181 if (AH_PRIVATE(ah)->ah_ispcie)
184 case AR_SREV_VERSION_AR9380:
185 if (ah->ah_macRev >= AR_SREV_REVISION_AR9580_10)
188 case AR_SREV_VERSION_AR9460:
190 case AR_SREV_VERSION_AR9330:
192 case AR_SREV_VERSION_AR9340:
194 case AR_SREV_VERSION_QCA9550:
196 case AR_SREV_VERSION_AR9485:
198 case AR_SREV_VERSION_QCA9565:
200 case AR_SREV_VERSION_QCA9530:
207 * Return the mask of available modes based on the hardware capabilities.
210 ath_hal_getwirelessmodes(struct ath_hal*ah)
212 return ath_hal_getWirelessModes(ah);
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);
220 ath_hal_add_rf(struct ath_hal_rf *arf)
223 TAILQ_INSERT_TAIL(&ah_rf_list, arf, node);
228 ath_hal_remove_rf(struct ath_hal_rf *arf)
231 TAILQ_REMOVE(&ah_rf_list, arf, node);
236 * Check the set of registered RF backends to see if
237 * any recognize the device as one they can support.
240 ath_hal_rfprobe(struct ath_hal *ah, HAL_STATUS *ecode)
242 struct ath_hal_rf * const *prf;
243 struct ath_hal_rf * rf;
245 OS_SET_FOREACH(prf, ah_rfs) {
246 struct ath_hal_rf *rf = *prf;
251 TAILQ_FOREACH(rf, &ah_rf_list, node) {
255 *ecode = HAL_ENOTSUPP;
260 ath_hal_rf_name(struct ath_hal *ah)
262 switch (ah->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR) {
264 return "5110"; /* NB: made up */
265 case AR_RAD5111_SREV_MAJOR:
266 case AR_RAD5111_SREV_PROD:
268 case AR_RAD2111_SREV_MAJOR:
270 case AR_RAD5112_SREV_MAJOR:
271 case AR_RAD5112_SREV_2_0:
272 case AR_RAD5112_SREV_2_1:
274 case AR_RAD2112_SREV_MAJOR:
275 case AR_RAD2112_SREV_2_0:
276 case AR_RAD2112_SREV_2_1:
278 case AR_RAD2413_SREV_MAJOR:
280 case AR_RAD5413_SREV_MAJOR:
282 case AR_RAD2316_SREV_MAJOR:
284 case AR_RAD2317_SREV_MAJOR:
286 case AR_RAD5424_SREV_MAJOR:
289 case AR_RAD5133_SREV_MAJOR:
291 case AR_RAD2133_SREV_MAJOR:
293 case AR_RAD5122_SREV_MAJOR:
295 case AR_RAD2122_SREV_MAJOR:
302 * Poll the register looking for a specific value.
305 ath_hal_wait(struct ath_hal *ah, u_int reg, uint32_t mask, uint32_t val)
307 #define AH_TIMEOUT 5000
308 return ath_hal_waitfor(ah, reg, mask, val, AH_TIMEOUT);
313 ath_hal_waitfor(struct ath_hal *ah, u_int reg, uint32_t mask, uint32_t val, uint32_t timeout)
317 for (i = 0; i < timeout; i++) {
318 if ((OS_REG_READ(ah, reg) & mask) == val)
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);
329 * Reverse the bits starting at the low bit for a value of
333 ath_hal_reverseBits(uint32_t val, uint32_t n)
338 for (i = 0, retval = 0; i < n; i++) {
339 retval = (retval << 1) | (val & 1);
345 /* 802.11n related timing definitions */
347 #define OFDM_PLCP_BITS 22
353 #define HT_LTF(n) ((n) * 4)
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)
360 * Calculate the duration of a packet whether it is 11n or legacy.
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)
370 rc = rates->info[rateix].rateCode;
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);
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!",
383 /* XXX TODO: Add SIFS */
384 return ath_computedur_ht(frameLen, rc, numStreams, isht40,
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
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
402 * Calculate the transmit duration of an 11n frame.
405 ath_computedur_ht(uint32_t frameLen, uint16_t rate, int streams,
406 HAL_BOOL isht40, HAL_BOOL isShortGI)
408 uint32_t bitsPerSymbol, numBits, numSymbols, txTime;
410 KASSERT(rate & IEEE80211_RATE_MCS, ("not mcs %d", rate));
411 KASSERT((rate &~ IEEE80211_RATE_MCS) < 31, ("bad mcs 0x%x", rate));
414 bitsPerSymbol = ht40_bps[HT_RC_2_MCS(rate)];
416 bitsPerSymbol = ht20_bps[HT_RC_2_MCS(rate)];
417 numBits = OFDM_PLCP_BITS + (frameLen << 3);
418 numSymbols = howmany(numBits, bitsPerSymbol);
420 txTime = ((numSymbols * 18) + 4) / 5; /* 3.6us */
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);
428 * Compute the time to transmit a frame of length frameLen bytes
429 * using the specified rate, phy, and short preamble setting.
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)
436 uint32_t bitsPerSymbol, numBits, numSymbols, phyTime, txTime;
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);
444 kbps = rates->info[rateix].rateKbps;
446 * index can be invalid during dynamic Turbo transitions.
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)
456 numBits = frameLen << 3;
458 + ((numBits * 1000)/kbps);
460 txTime += CCK_SIFS_TIME;
462 case IEEE80211_T_OFDM:
463 bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME) / 1000;
464 HALASSERT(bitsPerSymbol != 0);
466 numBits = OFDM_PLCP_BITS + (frameLen << 3);
467 numSymbols = howmany(numBits, bitsPerSymbol);
468 txTime = OFDM_PREAMBLE_TIME
469 + (numSymbols * OFDM_SYMBOL_TIME);
471 txTime += OFDM_SIFS_TIME;
473 case IEEE80211_T_OFDM_HALF:
474 bitsPerSymbol = (kbps * OFDM_HALF_SYMBOL_TIME) / 1000;
475 HALASSERT(bitsPerSymbol != 0);
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);
482 txTime += OFDM_HALF_SIFS_TIME;
484 case IEEE80211_T_OFDM_QUARTER:
485 bitsPerSymbol = (kbps * OFDM_QUARTER_SYMBOL_TIME) / 1000;
486 HALASSERT(bitsPerSymbol != 0);
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);
493 txTime += OFDM_QUARTER_SIFS_TIME;
495 case IEEE80211_T_TURBO:
496 bitsPerSymbol = (kbps * TURBO_SYMBOL_TIME) / 1000;
497 HALASSERT(bitsPerSymbol != 0);
499 numBits = TURBO_PLCP_BITS + (frameLen << 3);
500 numSymbols = howmany(numBits, bitsPerSymbol);
501 txTime = TURBO_PREAMBLE_TIME
502 + (numSymbols * TURBO_SYMBOL_TIME);
504 txTime += TURBO_SIFS_TIME;
507 HALDEBUG(ah, HAL_DEBUG_PHYIO,
508 "%s: unknown phy %u (rate ix %u)\n",
509 __func__, rates->info[rateix].phy, rateix);
517 ath_hal_get_curmode(struct ath_hal *ah, const struct ieee80211_channel *chan)
520 * Pick a default mode at bootup. A channel change is inevitable.
523 return HAL_MODE_11NG_HT20;
525 if (IEEE80211_IS_CHAN_TURBO(chan))
526 return HAL_MODE_TURBO;
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))
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;
547 * XXX For FreeBSD, will this work correctly given the DYN
548 * chan mode (OFDM+CCK dynamic) ? We have pure-G versions DYN-BG..
550 if (IEEE80211_IS_CHAN_G(chan))
552 if (IEEE80211_IS_CHAN_B(chan))
556 return HAL_MODE_11NG_HT20;
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,
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?
575 ath_hal_chan2wmode(struct ath_hal *ah, const struct ieee80211_channel *chan)
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;
589 * Convert between microseconds and core system clocks.
591 /* 11a Turbo 11b 11g 108g */
592 static const uint8_t CLOCK_RATE[] = { 40, 80, 22, 44, 88 };
594 #define CLOCK_FAST_RATE_5GHZ_OFDM 44
597 ath_hal_mac_clks(struct ath_hal *ah, u_int usecs)
599 const struct ieee80211_channel *c = AH_PRIVATE(ah)->ah_curchan;
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))
608 } else if (c != AH_NULL) {
609 clks = usecs * CLOCK_RATE[ath_hal_chan2wmode(ah, c)];
610 if (IEEE80211_IS_CHAN_HT40(c))
613 clks = usecs * CLOCK_RATE[WIRELESS_MODE_11b];
615 /* Compensate for half/quarter rate */
616 if (c != AH_NULL && IEEE80211_IS_CHAN_HALF(c))
618 else if (c != AH_NULL && IEEE80211_IS_CHAN_QUARTER(c))
625 ath_hal_mac_usec(struct ath_hal *ah, u_int clks)
629 psec = ath_hal_mac_psec(ah, clks);
630 return (psec / 1000000);
634 * XXX TODO: half, quarter rates.
637 ath_hal_mac_psec(struct ath_hal *ah, u_int clks)
639 const struct ieee80211_channel *c = AH_PRIVATE(ah)->ah_curchan;
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))
648 } else if (c != AH_NULL) {
649 psec = (clks * 1000000ULL) / CLOCK_RATE[ath_hal_chan2wmode(ah, c)];
650 if (IEEE80211_IS_CHAN_HT40(c))
653 psec = (clks * 1000000ULL) / CLOCK_RATE[WIRELESS_MODE_11b];
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.
666 * XXX not reentrant, but shouldn't matter
669 ath_hal_setupratetable(struct ath_hal *ah, HAL_RATE_TABLE *rt)
671 #define N(a) (sizeof(a)/sizeof(a[0]))
674 if (rt->rateCodeToIndex[0] != 0) /* already setup */
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;
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;
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
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);
702 ath_hal_getcapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
703 uint32_t capability, uint32_t *result)
705 const HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;
708 case HAL_CAP_REG_DMN: /* regulatory domain */
709 *result = AH_PRIVATE(ah)->ah_currentRD;
711 case HAL_CAP_DFS_DMN: /* DFS Domain */
712 *result = AH_PRIVATE(ah)->ah_dfsDomain;
714 case HAL_CAP_CIPHER: /* cipher handled in hardware */
715 case HAL_CAP_TKIP_MIC: /* handle TKIP MIC in hardware */
717 case HAL_CAP_TKIP_SPLIT: /* hardware TKIP uses split keys */
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 */
723 case HAL_CAP_DIVERSITY: /* hardware supports fast diversity */
725 case HAL_CAP_KEYCACHE_SIZE: /* hardware key cache size */
726 *result = pCap->halKeyCacheSize;
728 case HAL_CAP_NUM_TXQUEUES: /* number of hardware tx queues */
729 *result = pCap->halTotalQueues;
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;
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;
744 case HAL_CAP_TXPOW: /* global tx power limit */
745 switch (capability) {
746 case 0: /* facility is supported */
748 case 1: /* current limit */
749 *result = AH_PRIVATE(ah)->ah_powerLimit;
751 case 2: /* current max tx power */
752 *result = AH_PRIVATE(ah)->ah_maxPowerLevel;
754 case 3: /* scale factor */
755 *result = AH_PRIVATE(ah)->ah_tpScale;
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 */
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;
781 return pCap->halHTSupport ? HAL_OK : HAL_ENOTSUPP;
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;
789 case HAL_CAP_RX_CHAINMASK: /* mask of RX chains supported */
790 *result = pCap->halRxChainMask;
792 case HAL_CAP_NUM_GPIO_PINS:
793 *result = pCap->halNumGpioPins;
796 return pCap->halCSTSupport ? HAL_OK : HAL_ENOTSUPP;
797 case HAL_CAP_RTS_AGGR_LIMIT:
798 *result = pCap->halRtsAggrLimit;
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;
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;
824 case HAL_CAP_TXDESCLEN:
825 *result = pCap->halTxDescLen;
827 case HAL_CAP_TXSTATUSLEN:
828 *result = pCap->halTxStatusLen;
830 case HAL_CAP_RXSTATUSLEN:
831 *result = pCap->halRxStatusLen;
833 case HAL_CAP_RXFIFODEPTH:
834 switch (capability) {
835 case HAL_RX_QUEUE_HP:
836 *result = pCap->halRxHpFifoDepth;
838 case HAL_RX_QUEUE_LP:
839 *result = pCap->halRxLpFifoDepth;
844 case HAL_CAP_RXBUFSIZE:
845 case HAL_CAP_NUM_MR_RETRIES:
846 *result = pCap->halNumMRRetries;
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;
857 case HAL_CAP_ANT_DIV_COMB: /* AR9285/AR9485 LNA diversity */
858 return pCap->halAntDivCombSupport ? HAL_OK : HAL_ENOTSUPP;
860 case HAL_CAP_ENHANCED_DFS_SUPPORT:
861 return pCap->halEnhancedDfsSupport ? HAL_OK : HAL_ENOTSUPP;
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;
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) {
874 *result = pCap->halTxStreams;
877 *result = pCap->halRxStreams;
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;
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;
904 ath_hal_setcapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
905 uint32_t capability, uint32_t setting, HAL_STATUS *status)
910 switch (capability) {
912 if (setting <= HAL_TP_SCALE_MIN) {
913 AH_PRIVATE(ah)->ah_tpScale = setting;
919 case HAL_CAP_RFSILENT: /* rfsilent support */
921 * NB: allow even if halRfSilentSupport is false
922 * in case the EEPROM is misprogrammed.
924 switch (capability) {
925 case 1: /* current setting */
926 AH_PRIVATE(ah)->ah_rfkillEnabled = (setting != 0);
928 case 2: /* rfsilent config */
929 /* XXX better done per-chip for validation? */
930 AH_PRIVATE(ah)->ah_rfsilent = setting;
934 case HAL_CAP_REG_DMN: /* regulatory domain */
935 AH_PRIVATE(ah)->ah_currentRD = setting;
937 case HAL_CAP_RXORN_FATAL: /* HAL_INT_RXORN treated as fatal */
938 AH_PRIVATE(ah)->ah_rxornIsFatal = setting;
944 *status = HAL_EINVAL;
949 * Common support for getDiagState method.
953 ath_hal_getregdump(struct ath_hal *ah, const HAL_REGRANGE *regs,
954 void *dstbuf, int space)
956 uint32_t *dp = dstbuf;
959 for (i = 0; space >= 2*sizeof(uint32_t); i++) {
960 uint32_t r = regs[i].start;
961 uint32_t e = regs[i].end;
964 space -= 2*sizeof(uint32_t);
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));
971 return (char *) dp - (char *) dstbuf;
975 ath_hal_setregs(struct ath_hal *ah, const HAL_REGWRITE *regs, int space)
977 while (space >= sizeof(HAL_REGWRITE)) {
978 OS_REG_WRITE(ah, regs->addr, regs->value);
979 regs++, space -= sizeof(HAL_REGWRITE);
984 ath_hal_getdiagstate(struct ath_hal *ah, int request,
985 const void *args, uint32_t argsize,
986 void **result, uint32_t *resultsize)
991 *result = &AH_PRIVATE(ah)->ah_devid;
992 *resultsize = sizeof(HAL_REVS);
995 *resultsize = ath_hal_getregdump(ah, args, *result,*resultsize);
997 case HAL_DIAG_SETREGS:
998 ath_hal_setregs(ah, args, argsize);
1001 case HAL_DIAG_FATALERR:
1002 *result = &AH_PRIVATE(ah)->ah_fatalState[0];
1003 *resultsize = sizeof(AH_PRIVATE(ah)->ah_fatalState);
1005 case HAL_DIAG_EEREAD:
1006 if (argsize != sizeof(uint16_t))
1008 if (!ath_hal_eepromRead(ah, *(const uint16_t *)args, *result))
1010 *resultsize = sizeof(uint16_t);
1012 #ifdef AH_PRIVATE_DIAG
1013 case HAL_DIAG_SETKEY: {
1014 const HAL_DIAG_KEYVAL *dk;
1016 if (argsize != sizeof(HAL_DIAG_KEYVAL))
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);
1022 case HAL_DIAG_RESETKEY:
1023 if (argsize != sizeof(uint16_t))
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))
1031 ee = (const HAL_DIAG_EEVAL *)args;
1032 return ath_hal_eepromWrite(ah, ee->ee_off, ee->ee_data);
1034 #endif /* AH_SUPPORT_WRITE_EEPROM */
1035 #endif /* AH_PRIVATE_DIAG */
1036 case HAL_DIAG_11NCOMPAT:
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;
1046 case HAL_DIAG_CHANSURVEY:
1047 *result = &AH_PRIVATE(ah)->ah_chansurvey;
1048 *resultsize = sizeof(HAL_CHANNEL_SURVEY);
1055 * Set the properties of the tx queue with the parameters
1059 ath_hal_setTxQProps(struct ath_hal *ah,
1060 HAL_TX_QUEUE_INFO *qi, const HAL_TXQ_INFO *qInfo)
1064 if (qi->tqi_type == HAL_TX_QUEUE_INACTIVE) {
1065 HALDEBUG(ah, HAL_DEBUG_TXQUEUE,
1066 "%s: inactive queue\n", __func__);
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);
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) */
1082 while (qi->tqi_cwmin < cw)
1083 qi->tqi_cwmin = (qi->tqi_cwmin << 1) | 1;
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) */
1090 while (qi->tqi_cwmax < cw)
1091 qi->tqi_cwmax = (qi->tqi_cwmax << 1) | 1;
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);
1098 qi->tqi_shretry = INIT_SH_RETRY;
1099 if (qInfo->tqi_lgretry != 0)
1100 qi->tqi_lgretry = AH_MIN(qInfo->tqi_lgretry, 15);
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;
1108 switch (qInfo->tqi_subtype) {
1110 if (qi->tqi_type == HAL_TX_QUEUE_DATA)
1111 qi->tqi_intFlags = HAL_TXQ_USE_LOCKOUT_BKOFF_DIS;
1114 break; /* NB: silence compiler */
1120 ath_hal_getTxQProps(struct ath_hal *ah,
1121 HAL_TXQ_INFO *qInfo, const HAL_TX_QUEUE_INFO *qi)
1123 if (qi->tqi_type == HAL_TX_QUEUE_INACTIVE) {
1124 HALDEBUG(ah, HAL_DEBUG_TXQUEUE,
1125 "%s: inactive queue\n", __func__);
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;
1146 /* 11a Turbo 11b 11g 108g */
1147 static const int16_t NOISE_FLOOR[] = { -96, -93, -98, -96, -93 };
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.
1154 * NB: This is a private routine used by per-chip code to
1155 * implement the ah_getChanNoise method.
1158 ath_hal_getChanNoise(struct ath_hal *ah, const struct ieee80211_channel *chan)
1160 HAL_CHANNEL_INTERNAL *ichan;
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);
1169 if (ichan->rawNoiseFloor == 0) {
1170 WIRELESS_MODE mode = ath_hal_chan2wmode(ah, chan);
1172 HALASSERT(mode < WIRELESS_MODE_MAX);
1173 return NOISE_FLOOR[mode] + ath_hal_getNfAdjust(ah, ichan);
1175 return ichan->rawNoiseFloor + ichan->noiseFloorAdjust;
1179 * Fetch the current setup of ctl/ext noise floor values.
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().
1184 * The caller must supply ctl/ext NF arrays which are at least
1185 * AH_MAX_CHAINS entries long.
1188 ath_hal_get_mimo_chan_noise(struct ath_hal *ah,
1189 const struct ieee80211_channel *chan, int16_t *nf_ctl,
1192 HAL_CHANNEL_INTERNAL *ichan;
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;
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;
1213 if (ichan->rawNoiseFloor == 0) {
1214 WIRELESS_MODE mode = ath_hal_chan2wmode(ah, chan);
1215 HALASSERT(mode < WIRELESS_MODE_MAX);
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[].
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);
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.
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.)
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);
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
1255 ath_hal_process_noisefloor(struct ath_hal *ah)
1257 HAL_CHANNEL_INTERNAL *c;
1258 int16_t correct2, correct5;
1259 int16_t lowest2, lowest5;
1263 * Find the lowest 2GHz and 5GHz noise floor values after adjusting
1264 * for statistically recorded NF/channel deviation.
1266 correct2 = lowest2 = 0;
1267 correct5 = lowest5 = 0;
1268 for (i = 0; i < AH_PRIVATE(ah)->ah_nchan; i++) {
1272 c = &AH_PRIVATE(ah)->ah_channels[i];
1273 if (c->rawNoiseFloor >= 0)
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)) {
1282 correct5 = NOISE_FLOOR[mode] -
1283 (c->rawNoiseFloor + ath_hal_getNfAdjust(ah, c));
1288 correct2 = NOISE_FLOOR[mode] -
1289 (c->rawNoiseFloor + ath_hal_getNfAdjust(ah, c));
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)
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);
1308 * INI support routines.
1312 ath_hal_ini_write(struct ath_hal *ah, const HAL_INI_ARRAY *ia,
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));
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)
1332 ath_hal_ini_bank_setup(uint32_t data[], const HAL_INI_ARRAY *ia, int col)
1336 HALASSERT(col < ia->cols);
1337 for (r = 0; r < ia->rows; r++)
1338 data[r] = HAL_INI_VAL(ia, r, col);
1342 ath_hal_ini_bank_write(struct ath_hal *ah, const HAL_INI_ARRAY *ia,
1343 const uint32_t data[], int regWr)
1347 for (r = 0; r < ia->rows; r++) {
1348 OS_REG_WRITE(ah, HAL_INI_VAL(ia, r, 0), data[r]);
1355 * These are EEPROM board related routines which should likely live in
1356 * a helper library of some sort.
1359 /**************************************************************
1360 * ath_ee_getLowerUppderIndex
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.
1369 ath_ee_getLowerUpperIndex(uint8_t target, uint8_t *pList, uint16_t listSize,
1370 uint16_t *indexL, uint16_t *indexR)
1375 * Check first and last elements for beyond ordered array cases.
1377 if (target <= pList[0]) {
1378 *indexL = *indexR = 0;
1381 if (target >= pList[listSize-1]) {
1382 *indexL = *indexR = (uint16_t)(listSize - 1);
1386 /* look for value being near or between 2 values in list */
1387 for (i = 0; i < listSize - 1; i++) {
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
1392 if (pList[i] == target) {
1393 *indexL = *indexR = i;
1397 * Look for value being between current value and next value
1398 * if so return these 2 values
1400 if (target < pList[i + 1]) {
1402 *indexR = (uint16_t)(i + 1);
1407 *indexL = *indexR = 0;
1411 /**************************************************************
1412 * ath_ee_FillVpdTable
1414 * Fill the Vpdlist for indices Pmax-Pmin
1415 * Note: pwrMin, pwrMax and Vpdlist are all in dBm * 4
1418 ath_ee_FillVpdTable(uint8_t pwrMin, uint8_t pwrMax, uint8_t *pPwrList,
1419 uint8_t *pVpdList, uint16_t numIntercepts, uint8_t *pRetVpdList)
1422 uint8_t currPwr = pwrMin;
1423 uint16_t idxL, idxR;
1425 HALASSERT(pwrMax > pwrMin);
1426 for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) {
1427 ath_ee_getLowerUpperIndex(currPwr, pPwrList, numIntercepts,
1430 idxR = 1; /* extrapolate below */
1431 if (idxL == numIntercepts - 1)
1432 idxL = (uint16_t)(numIntercepts - 2); /* extrapolate above */
1433 if (pPwrList[idxL] == pPwrList[idxR])
1436 k = (uint16_t)( ((currPwr - pPwrList[idxL]) * pVpdList[idxR] + (pPwrList[idxR] - currPwr) * pVpdList[idxL]) /
1437 (pPwrList[idxR] - pPwrList[idxL]) );
1439 pRetVpdList[i] = (uint8_t)k;
1440 currPwr += 2; /* half dB steps */
1446 /**************************************************************************
1447 * ath_ee_interpolate
1449 * Returns signed interpolated or the scaled up interpolated value
1452 ath_ee_interpolate(uint16_t target, uint16_t srcLeft, uint16_t srcRight,
1453 int16_t targetLeft, int16_t targetRight)
1457 if (srcRight == srcLeft) {
1460 rv = (int16_t)( ((target - srcLeft) * targetRight +
1461 (srcRight - target) * targetLeft) / (srcRight - srcLeft) );
1470 ath_hal_adjusttsf(struct ath_hal *ah, int32_t tsfdelta)
1472 /* XXX handle wrap/overflow */
1473 OS_REG_WRITE(ah, AR_TSF_L32, OS_REG_READ(ah, AR_TSF_L32) + tsfdelta);
1477 * Enable or disable CCA.
1480 ath_hal_setcca(struct ath_hal *ah, int ena)
1483 * NB: fill me in; this is not provided by default because disabling
1484 * CCA in most locales violates regulatory.
1491 * XXX TODO: turn this and the above function into methods
1492 * in case there are chipset differences in handling CCA.
1495 ath_hal_getcca(struct ath_hal *ah)
1498 if (ath_hal_getcapability(ah, HAL_CAP_DIAG, 0, &diag) != HAL_OK)
1500 return ((diag & 0x500000) == 0);
1504 * Set the current state of self-generated ACK and RTS/CTS frames.
1506 * For correct DFS operation, the device should not even /ACK/ frames
1507 * that are sent to it during CAC or CSA.
1510 ath_hal_set_dfs_cac_tx_quiet(struct ath_hal *ah, HAL_BOOL ena)
1513 if (ah->ah_setDfsCacTxQuiet == NULL)
1515 ah->ah_setDfsCacTxQuiet(ah, ena);
1519 * This routine is only needed when supporting EEPROM-in-RAM setups
1520 * (eg embedded SoCs and on-board PCI/PCIe devices.)
1522 /* NB: This is in 16 bit words; not bytes */
1523 /* XXX This doesn't belong here! */
1524 #define ATH_DATA_EEPROM_SIZE 2048
1527 ath_hal_EepromDataRead(struct ath_hal *ah, u_int off, uint16_t *data)
1529 if (ah->ah_eepromdata == AH_NULL) {
1530 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: no eeprom data!\n", __func__);
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);
1538 (*data) = ah->ah_eepromdata[off];
1543 * Do a 2GHz specific MHz->IEEE based on the hardware
1546 * This is the unmapped frequency which is programmed into the hardware.
1549 ath_hal_mhz2ieee_2ghz(struct ath_hal *ah, int freq)
1555 return ((int) freq - 2407) / 5;
1557 return 15 + ((freq - 2512) / 20);
1561 * Clear the current survey data.
1563 * This should be done during a channel change.
1566 ath_hal_survey_clear(struct ath_hal *ah)
1569 OS_MEMZERO(&AH_PRIVATE(ah)->ah_chansurvey,
1570 sizeof(AH_PRIVATE(ah)->ah_chansurvey));
1574 * Add a sample to the channel survey.
1577 ath_hal_survey_add_sample(struct ath_hal *ah, HAL_SURVEY_SAMPLE *hs)
1579 HAL_CHANNEL_SURVEY *cs;
1581 cs = &AH_PRIVATE(ah)->ah_chansurvey;
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;