Home | History | Annotate | Line # | Download | only in dist
ah.c revision 1.2.18.1
      1       1.1     alc /*
      2       1.1     alc  * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
      3       1.1     alc  * Copyright (c) 2002-2008 Atheros Communications, Inc.
      4       1.1     alc  *
      5       1.1     alc  * Permission to use, copy, modify, and/or distribute this software for any
      6       1.1     alc  * purpose with or without fee is hereby granted, provided that the above
      7       1.1     alc  * copyright notice and this permission notice appear in all copies.
      8       1.1     alc  *
      9       1.1     alc  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     10       1.1     alc  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     11       1.1     alc  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     12       1.1     alc  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     13       1.1     alc  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     14       1.1     alc  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     15       1.1     alc  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     16       1.1     alc  *
     17  1.2.18.1  jruoho  * $Id: ah.c,v 1.2.18.1 2011/06/06 09:09:16 jruoho Exp $
     18       1.1     alc  */
     19       1.1     alc #include "opt_ah.h"
     20       1.1     alc 
     21       1.1     alc #include "ah.h"
     22       1.1     alc #include "ah_internal.h"
     23       1.1     alc #include "ah_devid.h"
     24       1.1     alc 
     25       1.1     alc /* linker set of registered chips */
     26       1.1     alc OS_SET_DECLARE(ah_chips, struct ath_hal_chip);
     27       1.1     alc 
     28       1.1     alc /*
     29       1.1     alc  * Check the set of registered chips to see if any recognize
     30       1.1     alc  * the device as one they can support.
     31       1.1     alc  */
     32       1.1     alc const char*
     33       1.1     alc ath_hal_probe(uint16_t vendorid, uint16_t devid)
     34       1.1     alc {
     35       1.2     alc 	struct ath_hal_chip * const *pchip;
     36       1.1     alc 
     37       1.1     alc 	OS_SET_FOREACH(pchip, ah_chips) {
     38       1.1     alc 		const char *name = (*pchip)->probe(vendorid, devid);
     39       1.1     alc 		if (name != AH_NULL)
     40       1.1     alc 			return name;
     41       1.1     alc 	}
     42       1.1     alc 	return AH_NULL;
     43       1.1     alc }
     44       1.1     alc 
     45       1.1     alc /*
     46       1.1     alc  * Attach detects device chip revisions, initializes the hwLayer
     47       1.1     alc  * function list, reads EEPROM information,
     48       1.1     alc  * selects reset vectors, and performs a short self test.
     49       1.1     alc  * Any failures will return an error that should cause a hardware
     50       1.1     alc  * disable.
     51       1.1     alc  */
     52       1.1     alc struct ath_hal*
     53       1.1     alc ath_hal_attach(uint16_t devid, HAL_SOFTC sc,
     54       1.1     alc 	HAL_BUS_TAG st, HAL_BUS_HANDLE sh, HAL_STATUS *error)
     55       1.1     alc {
     56       1.2     alc 	struct ath_hal_chip * const *pchip;
     57       1.1     alc 
     58       1.1     alc 	OS_SET_FOREACH(pchip, ah_chips) {
     59       1.1     alc 		struct ath_hal_chip *chip = *pchip;
     60       1.1     alc 		struct ath_hal *ah;
     61       1.1     alc 
     62       1.1     alc 		/* XXX don't have vendorid, assume atheros one works */
     63       1.1     alc 		if (chip->probe(ATHEROS_VENDOR_ID, devid) == AH_NULL)
     64       1.1     alc 			continue;
     65       1.1     alc 		ah = chip->attach(devid, sc, st, sh, error);
     66       1.1     alc 		if (ah != AH_NULL) {
     67       1.1     alc 			/* copy back private state to public area */
     68       1.1     alc 			ah->ah_devid = AH_PRIVATE(ah)->ah_devid;
     69       1.1     alc 			ah->ah_subvendorid = AH_PRIVATE(ah)->ah_subvendorid;
     70       1.1     alc 			ah->ah_macVersion = AH_PRIVATE(ah)->ah_macVersion;
     71       1.1     alc 			ah->ah_macRev = AH_PRIVATE(ah)->ah_macRev;
     72       1.1     alc 			ah->ah_phyRev = AH_PRIVATE(ah)->ah_phyRev;
     73       1.1     alc 			ah->ah_analog5GhzRev = AH_PRIVATE(ah)->ah_analog5GhzRev;
     74       1.1     alc 			ah->ah_analog2GhzRev = AH_PRIVATE(ah)->ah_analog2GhzRev;
     75       1.1     alc 			return ah;
     76       1.1     alc 		}
     77       1.1     alc 	}
     78       1.1     alc 	return AH_NULL;
     79       1.1     alc }
     80       1.1     alc 
     81       1.1     alc /* linker set of registered RF backends */
     82       1.1     alc OS_SET_DECLARE(ah_rfs, struct ath_hal_rf);
     83       1.1     alc 
     84       1.1     alc /*
     85       1.1     alc  * Check the set of registered RF backends to see if
     86       1.1     alc  * any recognize the device as one they can support.
     87       1.1     alc  */
     88       1.1     alc struct ath_hal_rf *
     89       1.1     alc ath_hal_rfprobe(struct ath_hal *ah, HAL_STATUS *ecode)
     90       1.1     alc {
     91       1.2     alc #ifdef AH_HAS_RF
     92       1.2     alc 	struct ath_hal_rf * const *prf;
     93       1.1     alc 
     94       1.1     alc 	OS_SET_FOREACH(prf, ah_rfs) {
     95       1.1     alc 		struct ath_hal_rf *rf = *prf;
     96       1.1     alc 		if (rf->probe(ah))
     97       1.1     alc 			return rf;
     98       1.1     alc 	}
     99       1.1     alc 	*ecode = HAL_ENOTSUPP;
    100       1.2     alc #endif
    101       1.1     alc 	return AH_NULL;
    102       1.1     alc }
    103       1.1     alc 
    104       1.1     alc /*
    105       1.1     alc  * Poll the register looking for a specific value.
    106       1.1     alc  */
    107       1.1     alc HAL_BOOL
    108       1.1     alc ath_hal_wait(struct ath_hal *ah, u_int reg, uint32_t mask, uint32_t val)
    109       1.1     alc {
    110       1.1     alc #define	AH_TIMEOUT	1000
    111       1.1     alc 	int i;
    112       1.1     alc 
    113       1.1     alc 	for (i = 0; i < AH_TIMEOUT; i++) {
    114       1.1     alc 		if ((OS_REG_READ(ah, reg) & mask) == val)
    115       1.1     alc 			return AH_TRUE;
    116       1.1     alc 		OS_DELAY(10);
    117       1.1     alc 	}
    118       1.1     alc 	HALDEBUG(ah, HAL_DEBUG_REGIO | HAL_DEBUG_PHYIO,
    119       1.1     alc 	    "%s: timeout on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n",
    120       1.1     alc 	    __func__, reg, OS_REG_READ(ah, reg), mask, val);
    121       1.1     alc 	return AH_FALSE;
    122       1.1     alc #undef AH_TIMEOUT
    123       1.1     alc }
    124       1.1     alc 
    125       1.1     alc /*
    126       1.1     alc  * Reverse the bits starting at the low bit for a value of
    127       1.1     alc  * bit_count in size
    128       1.1     alc  */
    129       1.1     alc uint32_t
    130       1.1     alc ath_hal_reverseBits(uint32_t val, uint32_t n)
    131       1.1     alc {
    132       1.1     alc 	uint32_t retval;
    133       1.1     alc 	int i;
    134       1.1     alc 
    135       1.1     alc 	for (i = 0, retval = 0; i < n; i++) {
    136       1.1     alc 		retval = (retval << 1) | (val & 1);
    137       1.1     alc 		val >>= 1;
    138       1.1     alc 	}
    139       1.1     alc 	return retval;
    140       1.1     alc }
    141       1.1     alc 
    142       1.1     alc /*
    143       1.1     alc  * Compute the time to transmit a frame of length frameLen bytes
    144       1.1     alc  * using the specified rate, phy, and short preamble setting.
    145       1.1     alc  */
    146       1.1     alc uint16_t
    147       1.1     alc ath_hal_computetxtime(struct ath_hal *ah,
    148       1.1     alc 	const HAL_RATE_TABLE *rates, uint32_t frameLen, uint16_t rateix,
    149       1.1     alc 	HAL_BOOL shortPreamble)
    150       1.1     alc {
    151       1.1     alc 	uint32_t bitsPerSymbol, numBits, numSymbols, phyTime, txTime;
    152       1.1     alc 	uint32_t kbps;
    153       1.1     alc 
    154       1.1     alc 	kbps = rates->info[rateix].rateKbps;
    155       1.1     alc 	/*
    156       1.1     alc 	 * index can be invalid duting dynamic Turbo transitions.
    157       1.1     alc 	 */
    158       1.1     alc 	if(kbps == 0) return 0;
    159       1.1     alc 	switch (rates->info[rateix].phy) {
    160       1.1     alc 
    161       1.1     alc 	case IEEE80211_T_CCK:
    162       1.1     alc #define CCK_SIFS_TIME        10
    163       1.1     alc #define CCK_PREAMBLE_BITS   144
    164       1.1     alc #define CCK_PLCP_BITS        48
    165       1.1     alc 		phyTime		= CCK_PREAMBLE_BITS + CCK_PLCP_BITS;
    166       1.1     alc 		if (shortPreamble && rates->info[rateix].shortPreamble)
    167       1.1     alc 			phyTime >>= 1;
    168       1.1     alc 		numBits		= frameLen << 3;
    169       1.1     alc 		txTime		= CCK_SIFS_TIME + phyTime
    170       1.1     alc 				+ ((numBits * 1000)/kbps);
    171       1.1     alc 		break;
    172       1.1     alc #undef CCK_SIFS_TIME
    173       1.1     alc #undef CCK_PREAMBLE_BITS
    174       1.1     alc #undef CCK_PLCP_BITS
    175       1.1     alc 
    176       1.1     alc 	case IEEE80211_T_OFDM:
    177       1.1     alc #define OFDM_SIFS_TIME        16
    178       1.1     alc #define OFDM_PREAMBLE_TIME    20
    179       1.1     alc #define OFDM_PLCP_BITS        22
    180       1.1     alc #define OFDM_SYMBOL_TIME       4
    181       1.1     alc 
    182       1.1     alc #define OFDM_SIFS_TIME_HALF	32
    183       1.1     alc #define OFDM_PREAMBLE_TIME_HALF	40
    184       1.1     alc #define OFDM_PLCP_BITS_HALF	22
    185       1.1     alc #define OFDM_SYMBOL_TIME_HALF	8
    186       1.1     alc 
    187       1.1     alc #define OFDM_SIFS_TIME_QUARTER 		64
    188       1.1     alc #define OFDM_PREAMBLE_TIME_QUARTER	80
    189       1.1     alc #define OFDM_PLCP_BITS_QUARTER		22
    190       1.1     alc #define OFDM_SYMBOL_TIME_QUARTER	16
    191       1.1     alc 
    192       1.1     alc 		if (AH_PRIVATE(ah)->ah_curchan &&
    193       1.1     alc 			IS_CHAN_QUARTER_RATE(AH_PRIVATE(ah)->ah_curchan)) {
    194       1.1     alc 			bitsPerSymbol	= (kbps * OFDM_SYMBOL_TIME_QUARTER) / 1000;
    195       1.1     alc 			HALASSERT(bitsPerSymbol != 0);
    196       1.1     alc 
    197       1.1     alc 			numBits		= OFDM_PLCP_BITS + (frameLen << 3);
    198       1.1     alc 			numSymbols	= howmany(numBits, bitsPerSymbol);
    199       1.1     alc 			txTime		= OFDM_SIFS_TIME_QUARTER
    200       1.1     alc 						+ OFDM_PREAMBLE_TIME_QUARTER
    201       1.1     alc 					+ (numSymbols * OFDM_SYMBOL_TIME_QUARTER);
    202       1.1     alc 		} else if (AH_PRIVATE(ah)->ah_curchan &&
    203       1.1     alc 				IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan)) {
    204       1.1     alc 			bitsPerSymbol	= (kbps * OFDM_SYMBOL_TIME_HALF) / 1000;
    205       1.1     alc 			HALASSERT(bitsPerSymbol != 0);
    206       1.1     alc 
    207       1.1     alc 			numBits		= OFDM_PLCP_BITS + (frameLen << 3);
    208       1.1     alc 			numSymbols	= howmany(numBits, bitsPerSymbol);
    209       1.1     alc 			txTime		= OFDM_SIFS_TIME_HALF +
    210       1.1     alc 						OFDM_PREAMBLE_TIME_HALF
    211       1.1     alc 					+ (numSymbols * OFDM_SYMBOL_TIME_HALF);
    212       1.1     alc 		} else { /* full rate channel */
    213       1.1     alc 			bitsPerSymbol	= (kbps * OFDM_SYMBOL_TIME) / 1000;
    214       1.1     alc 			HALASSERT(bitsPerSymbol != 0);
    215       1.1     alc 
    216       1.1     alc 			numBits		= OFDM_PLCP_BITS + (frameLen << 3);
    217       1.1     alc 			numSymbols	= howmany(numBits, bitsPerSymbol);
    218       1.1     alc 			txTime		= OFDM_SIFS_TIME + OFDM_PREAMBLE_TIME
    219       1.1     alc 					+ (numSymbols * OFDM_SYMBOL_TIME);
    220       1.1     alc 		}
    221       1.1     alc 		break;
    222       1.1     alc 
    223       1.1     alc #undef OFDM_SIFS_TIME
    224       1.1     alc #undef OFDM_PREAMBLE_TIME
    225       1.1     alc #undef OFDM_PLCP_BITS
    226       1.1     alc #undef OFDM_SYMBOL_TIME
    227       1.1     alc 
    228       1.1     alc 	case IEEE80211_T_TURBO:
    229       1.1     alc #define TURBO_SIFS_TIME         8
    230       1.1     alc #define TURBO_PREAMBLE_TIME    14
    231       1.1     alc #define TURBO_PLCP_BITS        22
    232       1.1     alc #define TURBO_SYMBOL_TIME       4
    233       1.1     alc 		/* we still save OFDM rates in kbps - so double them */
    234       1.1     alc 		bitsPerSymbol = ((kbps << 1) * TURBO_SYMBOL_TIME) / 1000;
    235       1.1     alc 		HALASSERT(bitsPerSymbol != 0);
    236       1.1     alc 
    237       1.1     alc 		numBits       = TURBO_PLCP_BITS + (frameLen << 3);
    238       1.1     alc 		numSymbols    = howmany(numBits, bitsPerSymbol);
    239       1.1     alc 		txTime        = TURBO_SIFS_TIME + TURBO_PREAMBLE_TIME
    240       1.1     alc 			      + (numSymbols * TURBO_SYMBOL_TIME);
    241       1.1     alc 		break;
    242       1.1     alc #undef TURBO_SIFS_TIME
    243       1.1     alc #undef TURBO_PREAMBLE_TIME
    244       1.1     alc #undef TURBO_PLCP_BITS
    245       1.1     alc #undef TURBO_SYMBOL_TIME
    246       1.1     alc 
    247       1.1     alc 	default:
    248       1.1     alc 		HALDEBUG(ah, HAL_DEBUG_PHYIO,
    249       1.1     alc 		    "%s: unknown phy %u (rate ix %u)\n",
    250       1.1     alc 		    __func__, rates->info[rateix].phy, rateix);
    251       1.1     alc 		txTime = 0;
    252       1.1     alc 		break;
    253       1.1     alc 	}
    254       1.1     alc 	return txTime;
    255       1.1     alc }
    256       1.1     alc 
    257       1.1     alc static __inline int
    258       1.1     alc mapgsm(u_int freq, u_int flags)
    259       1.1     alc {
    260       1.1     alc 	freq *= 10;
    261       1.1     alc 	if (flags & CHANNEL_QUARTER)
    262       1.1     alc 		freq += 5;
    263       1.1     alc 	else if (flags & CHANNEL_HALF)
    264       1.1     alc 		freq += 10;
    265       1.1     alc 	else
    266       1.1     alc 		freq += 20;
    267       1.1     alc 	return (freq - 24220) / 5;
    268       1.1     alc }
    269       1.1     alc 
    270       1.1     alc static __inline int
    271       1.1     alc mappsb(u_int freq, u_int flags)
    272       1.1     alc {
    273       1.1     alc 	return ((freq * 10) + (((freq % 5) == 2) ? 5 : 0) - 49400) / 5;
    274       1.1     alc }
    275       1.1     alc 
    276       1.1     alc /*
    277       1.1     alc  * Convert GHz frequency to IEEE channel number.
    278       1.1     alc  */
    279       1.1     alc int
    280       1.1     alc ath_hal_mhz2ieee(struct ath_hal *ah, u_int freq, u_int flags)
    281       1.1     alc {
    282       1.1     alc 	if (flags & CHANNEL_2GHZ) {	/* 2GHz band */
    283       1.1     alc 		if (freq == 2484)
    284       1.1     alc 			return 14;
    285       1.1     alc 		if (freq < 2484) {
    286       1.1     alc 			if (ath_hal_isgsmsku(ah))
    287       1.1     alc 				return mapgsm(freq, flags);
    288       1.1     alc 			return ((int)freq - 2407) / 5;
    289       1.1     alc 		} else
    290       1.1     alc 			return 15 + ((freq - 2512) / 20);
    291       1.1     alc 	} else if (flags & CHANNEL_5GHZ) {/* 5Ghz band */
    292       1.1     alc 		if (ath_hal_ispublicsafetysku(ah) &&
    293       1.1     alc 		    IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) {
    294       1.1     alc 			return mappsb(freq, flags);
    295       1.1     alc 		} else if ((flags & CHANNEL_A) && (freq <= 5000)) {
    296       1.1     alc 			return (freq - 4000) / 5;
    297       1.1     alc 		} else {
    298       1.1     alc 			return (freq - 5000) / 5;
    299       1.1     alc 		}
    300       1.1     alc 	} else {			/* either, guess */
    301       1.1     alc 		if (freq == 2484)
    302       1.1     alc 			return 14;
    303       1.1     alc 		if (freq < 2484) {
    304       1.1     alc 			if (ath_hal_isgsmsku(ah))
    305       1.1     alc 				return mapgsm(freq, flags);
    306       1.1     alc 			return ((int)freq - 2407) / 5;
    307       1.1     alc 		}
    308       1.1     alc 		if (freq < 5000) {
    309       1.1     alc 			if (ath_hal_ispublicsafetysku(ah) &&
    310       1.1     alc 			    IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) {
    311       1.1     alc 				return mappsb(freq, flags);
    312       1.1     alc 			} else if (freq > 4900) {
    313       1.1     alc 				return (freq - 4000) / 5;
    314       1.1     alc 			} else {
    315       1.1     alc 				return 15 + ((freq - 2512) / 20);
    316       1.1     alc 			}
    317       1.1     alc 		}
    318       1.1     alc 		return (freq - 5000) / 5;
    319       1.1     alc 	}
    320       1.1     alc }
    321       1.1     alc 
    322       1.1     alc typedef enum {
    323       1.1     alc 	WIRELESS_MODE_11a   = 0,
    324       1.1     alc 	WIRELESS_MODE_TURBO = 1,
    325       1.1     alc 	WIRELESS_MODE_11b   = 2,
    326       1.1     alc 	WIRELESS_MODE_11g   = 3,
    327       1.1     alc 	WIRELESS_MODE_108g  = 4,
    328       1.1     alc 
    329       1.1     alc 	WIRELESS_MODE_MAX
    330       1.1     alc } WIRELESS_MODE;
    331       1.1     alc 
    332       1.1     alc static WIRELESS_MODE
    333       1.1     alc ath_hal_chan2wmode(struct ath_hal *ah, const HAL_CHANNEL *chan)
    334       1.1     alc {
    335       1.1     alc 	if (IS_CHAN_CCK(chan))
    336       1.1     alc 		return WIRELESS_MODE_11b;
    337       1.1     alc 	if (IS_CHAN_G(chan))
    338       1.1     alc 		return WIRELESS_MODE_11g;
    339       1.1     alc 	if (IS_CHAN_108G(chan))
    340       1.1     alc 		return WIRELESS_MODE_108g;
    341       1.1     alc 	if (IS_CHAN_TURBO(chan))
    342       1.1     alc 		return WIRELESS_MODE_TURBO;
    343       1.1     alc 	return WIRELESS_MODE_11a;
    344       1.1     alc }
    345       1.1     alc 
    346       1.1     alc /*
    347       1.1     alc  * Convert between microseconds and core system clocks.
    348       1.1     alc  */
    349       1.1     alc                                      /* 11a Turbo  11b  11g  108g */
    350       1.1     alc static const uint8_t CLOCK_RATE[]  = { 40,  80,   22,  44,   88  };
    351       1.1     alc 
    352       1.1     alc u_int
    353       1.1     alc ath_hal_mac_clks(struct ath_hal *ah, u_int usecs)
    354       1.1     alc {
    355       1.1     alc 	const HAL_CHANNEL *c = (const HAL_CHANNEL *) AH_PRIVATE(ah)->ah_curchan;
    356       1.1     alc 	u_int clks;
    357       1.1     alc 
    358       1.1     alc 	/* NB: ah_curchan may be null when called attach time */
    359       1.1     alc 	if (c != AH_NULL) {
    360       1.1     alc 		clks = usecs * CLOCK_RATE[ath_hal_chan2wmode(ah, c)];
    361       1.1     alc 		if (IS_CHAN_HT40(c))
    362       1.1     alc 			clks <<= 1;
    363       1.1     alc 		else if (IS_CHAN_HALF_RATE(c))
    364       1.1     alc 			clks >>= 1;
    365       1.1     alc 		else if (IS_CHAN_QUARTER_RATE(c))
    366       1.1     alc 			clks >>= 2;
    367       1.1     alc 	} else
    368       1.1     alc 		clks = usecs * CLOCK_RATE[WIRELESS_MODE_11b];
    369       1.1     alc 	return clks;
    370       1.1     alc }
    371       1.1     alc 
    372       1.1     alc u_int
    373       1.1     alc ath_hal_mac_usec(struct ath_hal *ah, u_int clks)
    374       1.1     alc {
    375       1.1     alc 	const HAL_CHANNEL *c = (const HAL_CHANNEL *) AH_PRIVATE(ah)->ah_curchan;
    376       1.1     alc 	u_int usec;
    377       1.1     alc 
    378       1.1     alc 	/* NB: ah_curchan may be null when called attach time */
    379       1.1     alc 	if (c != AH_NULL) {
    380       1.1     alc 		usec = clks / CLOCK_RATE[ath_hal_chan2wmode(ah, c)];
    381       1.1     alc 		if (IS_CHAN_HT40(c))
    382       1.1     alc 			usec >>= 1;
    383       1.1     alc 		else if (IS_CHAN_HALF_RATE(c))
    384       1.1     alc 			usec <<= 1;
    385       1.1     alc 		else if (IS_CHAN_QUARTER_RATE(c))
    386       1.1     alc 			usec <<= 2;
    387       1.1     alc 	} else
    388       1.1     alc 		usec = clks / CLOCK_RATE[WIRELESS_MODE_11b];
    389       1.1     alc 	return usec;
    390       1.1     alc }
    391       1.1     alc 
    392       1.1     alc /*
    393       1.1     alc  * Setup a h/w rate table's reverse lookup table and
    394       1.1     alc  * fill in ack durations.  This routine is called for
    395       1.1     alc  * each rate table returned through the ah_getRateTable
    396       1.1     alc  * method.  The reverse lookup tables are assumed to be
    397       1.1     alc  * initialized to zero (or at least the first entry).
    398       1.1     alc  * We use this as a key that indicates whether or not
    399       1.1     alc  * we've previously setup the reverse lookup table.
    400       1.1     alc  *
    401       1.1     alc  * XXX not reentrant, but shouldn't matter
    402       1.1     alc  */
    403       1.1     alc void
    404       1.1     alc ath_hal_setupratetable(struct ath_hal *ah, HAL_RATE_TABLE *rt)
    405       1.1     alc {
    406       1.1     alc #define	N(a)	(sizeof(a)/sizeof(a[0]))
    407       1.1     alc 	int i;
    408       1.1     alc 
    409       1.1     alc 	if (rt->rateCodeToIndex[0] != 0)	/* already setup */
    410       1.1     alc 		return;
    411       1.1     alc 	for (i = 0; i < N(rt->rateCodeToIndex); i++)
    412       1.1     alc 		rt->rateCodeToIndex[i] = (uint8_t) -1;
    413       1.1     alc 	for (i = 0; i < rt->rateCount; i++) {
    414       1.1     alc 		uint8_t code = rt->info[i].rateCode;
    415       1.1     alc 		uint8_t cix = rt->info[i].controlRate;
    416       1.1     alc 
    417       1.1     alc 		HALASSERT(code < N(rt->rateCodeToIndex));
    418       1.1     alc 		rt->rateCodeToIndex[code] = i;
    419       1.1     alc 		HALASSERT((code | rt->info[i].shortPreamble) <
    420       1.1     alc 		    N(rt->rateCodeToIndex));
    421       1.1     alc 		rt->rateCodeToIndex[code | rt->info[i].shortPreamble] = i;
    422       1.1     alc 		/*
    423       1.1     alc 		 * XXX for 11g the control rate to use for 5.5 and 11 Mb/s
    424       1.1     alc 		 *     depends on whether they are marked as basic rates;
    425       1.1     alc 		 *     the static tables are setup with an 11b-compatible
    426       1.1     alc 		 *     2Mb/s rate which will work but is suboptimal
    427       1.1     alc 		 */
    428       1.1     alc 		rt->info[i].lpAckDuration = ath_hal_computetxtime(ah, rt,
    429       1.1     alc 			WLAN_CTRL_FRAME_SIZE, cix, AH_FALSE);
    430       1.1     alc 		rt->info[i].spAckDuration = ath_hal_computetxtime(ah, rt,
    431       1.1     alc 			WLAN_CTRL_FRAME_SIZE, cix, AH_TRUE);
    432       1.1     alc 	}
    433       1.1     alc #undef N
    434       1.1     alc }
    435       1.1     alc 
    436       1.1     alc HAL_STATUS
    437       1.1     alc ath_hal_getcapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
    438       1.1     alc 	uint32_t capability, uint32_t *result)
    439       1.1     alc {
    440       1.1     alc 	const HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;
    441       1.1     alc 
    442       1.1     alc 	switch (type) {
    443       1.1     alc 	case HAL_CAP_REG_DMN:		/* regulatory domain */
    444       1.1     alc 		*result = AH_PRIVATE(ah)->ah_currentRD;
    445       1.1     alc 		return HAL_OK;
    446       1.1     alc 	case HAL_CAP_CIPHER:		/* cipher handled in hardware */
    447       1.1     alc 	case HAL_CAP_TKIP_MIC:		/* handle TKIP MIC in hardware */
    448       1.1     alc 		return HAL_ENOTSUPP;
    449       1.1     alc 	case HAL_CAP_TKIP_SPLIT:	/* hardware TKIP uses split keys */
    450       1.1     alc 		return HAL_ENOTSUPP;
    451       1.1     alc 	case HAL_CAP_PHYCOUNTERS:	/* hardware PHY error counters */
    452       1.1     alc 		return pCap->halHwPhyCounterSupport ? HAL_OK : HAL_ENXIO;
    453       1.1     alc 	case HAL_CAP_WME_TKIPMIC:   /* hardware can do TKIP MIC when WMM is turned on */
    454       1.1     alc 		return HAL_ENOTSUPP;
    455       1.1     alc 	case HAL_CAP_DIVERSITY:		/* hardware supports fast diversity */
    456       1.1     alc 		return HAL_ENOTSUPP;
    457       1.1     alc 	case HAL_CAP_KEYCACHE_SIZE:	/* hardware key cache size */
    458       1.1     alc 		*result =  pCap->halKeyCacheSize;
    459       1.1     alc 		return HAL_OK;
    460       1.1     alc 	case HAL_CAP_NUM_TXQUEUES:	/* number of hardware tx queues */
    461       1.1     alc 		*result = pCap->halTotalQueues;
    462       1.1     alc 		return HAL_OK;
    463       1.1     alc 	case HAL_CAP_VEOL:		/* hardware supports virtual EOL */
    464       1.1     alc 		return pCap->halVEOLSupport ? HAL_OK : HAL_ENOTSUPP;
    465       1.1     alc 	case HAL_CAP_PSPOLL:		/* hardware PS-Poll support works */
    466       1.1     alc 		return pCap->halPSPollBroken ? HAL_ENOTSUPP : HAL_OK;
    467       1.1     alc 	case HAL_CAP_COMPRESSION:
    468       1.1     alc 		return pCap->halCompressSupport ? HAL_OK : HAL_ENOTSUPP;
    469       1.1     alc 	case HAL_CAP_BURST:
    470       1.1     alc 		return pCap->halBurstSupport ? HAL_OK : HAL_ENOTSUPP;
    471       1.1     alc 	case HAL_CAP_FASTFRAME:
    472       1.1     alc 		return pCap->halFastFramesSupport ? HAL_OK : HAL_ENOTSUPP;
    473       1.1     alc 	case HAL_CAP_DIAG:		/* hardware diagnostic support */
    474       1.1     alc 		*result = AH_PRIVATE(ah)->ah_diagreg;
    475       1.1     alc 		return HAL_OK;
    476       1.1     alc 	case HAL_CAP_TXPOW:		/* global tx power limit  */
    477       1.1     alc 		switch (capability) {
    478       1.1     alc 		case 0:			/* facility is supported */
    479       1.1     alc 			return HAL_OK;
    480       1.1     alc 		case 1:			/* current limit */
    481       1.1     alc 			*result = AH_PRIVATE(ah)->ah_powerLimit;
    482       1.1     alc 			return HAL_OK;
    483       1.1     alc 		case 2:			/* current max tx power */
    484       1.1     alc 			*result = AH_PRIVATE(ah)->ah_maxPowerLevel;
    485       1.1     alc 			return HAL_OK;
    486       1.1     alc 		case 3:			/* scale factor */
    487       1.1     alc 			*result = AH_PRIVATE(ah)->ah_tpScale;
    488       1.1     alc 			return HAL_OK;
    489       1.1     alc 		}
    490       1.1     alc 		return HAL_ENOTSUPP;
    491       1.1     alc 	case HAL_CAP_BSSIDMASK:		/* hardware supports bssid mask */
    492       1.1     alc 		return pCap->halBssIdMaskSupport ? HAL_OK : HAL_ENOTSUPP;
    493       1.1     alc 	case HAL_CAP_MCAST_KEYSRCH:	/* multicast frame keycache search */
    494       1.1     alc 		return pCap->halMcastKeySrchSupport ? HAL_OK : HAL_ENOTSUPP;
    495       1.1     alc 	case HAL_CAP_TSF_ADJUST:	/* hardware has beacon tsf adjust */
    496       1.1     alc 		return HAL_ENOTSUPP;
    497       1.1     alc 	case HAL_CAP_RFSILENT:		/* rfsilent support  */
    498       1.1     alc 		switch (capability) {
    499       1.1     alc 		case 0:			/* facility is supported */
    500       1.1     alc 			return pCap->halRfSilentSupport ? HAL_OK : HAL_ENOTSUPP;
    501       1.1     alc 		case 1:			/* current setting */
    502       1.1     alc 			return AH_PRIVATE(ah)->ah_rfkillEnabled ?
    503       1.1     alc 				HAL_OK : HAL_ENOTSUPP;
    504       1.1     alc 		case 2:			/* rfsilent config */
    505       1.1     alc 			*result = AH_PRIVATE(ah)->ah_rfsilent;
    506       1.1     alc 			return HAL_OK;
    507       1.1     alc 		}
    508       1.1     alc 		return HAL_ENOTSUPP;
    509       1.1     alc 	case HAL_CAP_11D:
    510       1.1     alc #ifdef AH_SUPPORT_11D
    511       1.1     alc 		return HAL_OK;
    512       1.1     alc #else
    513       1.1     alc 		return HAL_ENOTSUPP;
    514       1.1     alc #endif
    515       1.1     alc 	case HAL_CAP_RXORN_FATAL:	/* HAL_INT_RXORN treated as fatal  */
    516       1.1     alc 		return AH_PRIVATE(ah)->ah_rxornIsFatal ? HAL_OK : HAL_ENOTSUPP;
    517       1.1     alc 	case HAL_CAP_HT:
    518       1.1     alc 		return pCap->halHTSupport ? HAL_OK : HAL_ENOTSUPP;
    519       1.1     alc 	case HAL_CAP_TX_CHAINMASK:	/* mask of TX chains supported */
    520       1.1     alc 		*result = pCap->halTxChainMask;
    521       1.1     alc 		return HAL_OK;
    522       1.1     alc 	case HAL_CAP_RX_CHAINMASK:	/* mask of RX chains supported */
    523       1.1     alc 		*result = pCap->halRxChainMask;
    524       1.1     alc 		return HAL_OK;
    525       1.1     alc 	case HAL_CAP_RXTSTAMP_PREC:	/* rx desc tstamp precision (bits) */
    526       1.1     alc 		*result = pCap->halTstampPrecision;
    527       1.1     alc 		return HAL_OK;
    528  1.2.18.1  jruoho 	case HAL_CAP_INTRMASK:		/* mask of supported interrupts */
    529  1.2.18.1  jruoho 		*result = pCap->halIntrMask;
    530  1.2.18.1  jruoho 		return HAL_OK;
    531  1.2.18.1  jruoho 	case HAL_CAP_BSSIDMATCH:	/* hardware has disable bssid match */
    532  1.2.18.1  jruoho 		return pCap->halBssidMatchSupport ? HAL_OK : HAL_ENOTSUPP;
    533       1.1     alc 	default:
    534       1.1     alc 		return HAL_EINVAL;
    535       1.1     alc 	}
    536       1.1     alc }
    537       1.1     alc 
    538       1.1     alc HAL_BOOL
    539       1.1     alc ath_hal_setcapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
    540       1.1     alc 	uint32_t capability, uint32_t setting, HAL_STATUS *status)
    541       1.1     alc {
    542       1.1     alc 
    543       1.1     alc 	switch (type) {
    544       1.1     alc 	case HAL_CAP_TXPOW:
    545       1.1     alc 		switch (capability) {
    546       1.1     alc 		case 3:
    547       1.1     alc 			if (setting <= HAL_TP_SCALE_MIN) {
    548       1.1     alc 				AH_PRIVATE(ah)->ah_tpScale = setting;
    549       1.1     alc 				return AH_TRUE;
    550       1.1     alc 			}
    551       1.1     alc 			break;
    552       1.1     alc 		}
    553       1.1     alc 		break;
    554       1.1     alc 	case HAL_CAP_RFSILENT:		/* rfsilent support  */
    555       1.1     alc 		/*
    556       1.1     alc 		 * NB: allow even if halRfSilentSupport is false
    557       1.1     alc 		 *     in case the EEPROM is misprogrammed.
    558       1.1     alc 		 */
    559       1.1     alc 		switch (capability) {
    560       1.1     alc 		case 1:			/* current setting */
    561       1.1     alc 			AH_PRIVATE(ah)->ah_rfkillEnabled = (setting != 0);
    562       1.1     alc 			return AH_TRUE;
    563       1.1     alc 		case 2:			/* rfsilent config */
    564       1.1     alc 			/* XXX better done per-chip for validation? */
    565       1.1     alc 			AH_PRIVATE(ah)->ah_rfsilent = setting;
    566       1.1     alc 			return AH_TRUE;
    567       1.1     alc 		}
    568       1.1     alc 		break;
    569       1.1     alc 	case HAL_CAP_REG_DMN:		/* regulatory domain */
    570       1.1     alc 		AH_PRIVATE(ah)->ah_currentRD = setting;
    571       1.1     alc 		return AH_TRUE;
    572       1.1     alc 	case HAL_CAP_RXORN_FATAL:	/* HAL_INT_RXORN treated as fatal  */
    573       1.1     alc 		AH_PRIVATE(ah)->ah_rxornIsFatal = setting;
    574       1.1     alc 		return AH_TRUE;
    575       1.1     alc 	default:
    576       1.1     alc 		break;
    577       1.1     alc 	}
    578       1.1     alc 	if (status)
    579       1.1     alc 		*status = HAL_EINVAL;
    580       1.1     alc 	return AH_FALSE;
    581       1.1     alc }
    582       1.1     alc 
    583       1.1     alc /*
    584       1.1     alc  * Common support for getDiagState method.
    585       1.1     alc  */
    586       1.1     alc 
    587       1.1     alc static u_int
    588       1.1     alc ath_hal_getregdump(struct ath_hal *ah, const HAL_REGRANGE *regs,
    589       1.1     alc 	void *dstbuf, int space)
    590       1.1     alc {
    591       1.1     alc 	uint32_t *dp = dstbuf;
    592       1.1     alc 	int i;
    593       1.1     alc 
    594       1.1     alc 	for (i = 0; space >= 2*sizeof(uint32_t); i++) {
    595       1.1     alc 		u_int r = regs[i].start;
    596       1.1     alc 		u_int e = regs[i].end;
    597       1.1     alc 		*dp++ = (r<<16) | e;
    598       1.1     alc 		space -= sizeof(uint32_t);
    599       1.1     alc 		do {
    600       1.1     alc 			*dp++ = OS_REG_READ(ah, r);
    601       1.1     alc 			r += sizeof(uint32_t);
    602       1.1     alc 			space -= sizeof(uint32_t);
    603       1.1     alc 		} while (r <= e && space >= sizeof(uint32_t));
    604       1.1     alc 	}
    605       1.1     alc 	return (char *) dp - (char *) dstbuf;
    606       1.1     alc }
    607       1.1     alc 
    608       1.1     alc HAL_BOOL
    609       1.1     alc ath_hal_getdiagstate(struct ath_hal *ah, int request,
    610       1.1     alc 	const void *args, uint32_t argsize,
    611       1.1     alc 	void **result, uint32_t *resultsize)
    612       1.1     alc {
    613       1.1     alc 	switch (request) {
    614       1.1     alc 	case HAL_DIAG_REVS:
    615       1.1     alc 		*result = &AH_PRIVATE(ah)->ah_devid;
    616       1.1     alc 		*resultsize = sizeof(HAL_REVS);
    617       1.1     alc 		return AH_TRUE;
    618       1.1     alc 	case HAL_DIAG_REGS:
    619       1.1     alc 		*resultsize = ath_hal_getregdump(ah, args, *result,*resultsize);
    620       1.1     alc 		return AH_TRUE;
    621       1.1     alc 	case HAL_DIAG_FATALERR:
    622       1.1     alc 		*result = &AH_PRIVATE(ah)->ah_fatalState[0];
    623       1.1     alc 		*resultsize = sizeof(AH_PRIVATE(ah)->ah_fatalState);
    624       1.1     alc 		return AH_TRUE;
    625       1.1     alc 	case HAL_DIAG_EEREAD:
    626       1.1     alc 		if (argsize != sizeof(uint16_t))
    627       1.1     alc 			return AH_FALSE;
    628       1.1     alc 		if (!ath_hal_eepromRead(ah, *(const uint16_t *)args, *result))
    629       1.1     alc 			return AH_FALSE;
    630       1.1     alc 		*resultsize = sizeof(uint16_t);
    631       1.1     alc 		return AH_TRUE;
    632       1.1     alc #ifdef AH_PRIVATE_DIAG
    633       1.1     alc 	case HAL_DIAG_SETKEY: {
    634       1.1     alc 		const HAL_DIAG_KEYVAL *dk;
    635       1.1     alc 
    636       1.1     alc 		if (argsize != sizeof(HAL_DIAG_KEYVAL))
    637       1.1     alc 			return AH_FALSE;
    638       1.1     alc 		dk = (const HAL_DIAG_KEYVAL *)args;
    639       1.1     alc 		return ah->ah_setKeyCacheEntry(ah, dk->dk_keyix,
    640       1.1     alc 			&dk->dk_keyval, dk->dk_mac, dk->dk_xor);
    641       1.1     alc 	}
    642       1.1     alc 	case HAL_DIAG_RESETKEY:
    643       1.1     alc 		if (argsize != sizeof(uint16_t))
    644       1.1     alc 			return AH_FALSE;
    645       1.1     alc 		return ah->ah_resetKeyCacheEntry(ah, *(const uint16_t *)args);
    646       1.1     alc #ifdef AH_SUPPORT_WRITE_EEPROM
    647       1.1     alc 	case HAL_DIAG_EEWRITE: {
    648       1.1     alc 		const HAL_DIAG_EEVAL *ee;
    649       1.1     alc 		if (argsize != sizeof(HAL_DIAG_EEVAL))
    650       1.1     alc 			return AH_FALSE;
    651       1.1     alc 		ee = (const HAL_DIAG_EEVAL *)args;
    652       1.1     alc 		return ath_hal_eepromWrite(ah, ee->ee_off, ee->ee_data);
    653       1.1     alc 	}
    654       1.1     alc #endif /* AH_SUPPORT_WRITE_EEPROM */
    655       1.1     alc #endif /* AH_PRIVATE_DIAG */
    656       1.1     alc 	case HAL_DIAG_11NCOMPAT:
    657       1.1     alc 		if (argsize == 0) {
    658       1.1     alc 			*resultsize = sizeof(uint32_t);
    659       1.1     alc 			*((uint32_t *)(*result)) =
    660       1.1     alc 				AH_PRIVATE(ah)->ah_11nCompat;
    661       1.1     alc 		} else if (argsize == sizeof(uint32_t)) {
    662       1.1     alc 			AH_PRIVATE(ah)->ah_11nCompat = *(const uint32_t *)args;
    663       1.1     alc 		} else
    664       1.1     alc 			return AH_FALSE;
    665       1.1     alc 		return AH_TRUE;
    666       1.1     alc 	}
    667       1.1     alc 	return AH_FALSE;
    668       1.1     alc }
    669       1.1     alc 
    670       1.1     alc /*
    671       1.1     alc  * Set the properties of the tx queue with the parameters
    672       1.1     alc  * from qInfo.
    673       1.1     alc  */
    674       1.1     alc HAL_BOOL
    675       1.1     alc ath_hal_setTxQProps(struct ath_hal *ah,
    676       1.1     alc 	HAL_TX_QUEUE_INFO *qi, const HAL_TXQ_INFO *qInfo)
    677       1.1     alc {
    678       1.1     alc 	uint32_t cw;
    679       1.1     alc 
    680       1.1     alc 	if (qi->tqi_type == HAL_TX_QUEUE_INACTIVE) {
    681       1.1     alc 		HALDEBUG(ah, HAL_DEBUG_TXQUEUE,
    682       1.1     alc 		    "%s: inactive queue\n", __func__);
    683       1.1     alc 		return AH_FALSE;
    684       1.1     alc 	}
    685       1.1     alc 	/* XXX validate parameters */
    686       1.1     alc 	qi->tqi_ver = qInfo->tqi_ver;
    687       1.1     alc 	qi->tqi_subtype = qInfo->tqi_subtype;
    688       1.1     alc 	qi->tqi_qflags = qInfo->tqi_qflags;
    689       1.1     alc 	qi->tqi_priority = qInfo->tqi_priority;
    690       1.1     alc 	if (qInfo->tqi_aifs != HAL_TXQ_USEDEFAULT)
    691       1.1     alc 		qi->tqi_aifs = AH_MIN(qInfo->tqi_aifs, 255);
    692       1.1     alc 	else
    693       1.1     alc 		qi->tqi_aifs = INIT_AIFS;
    694       1.1     alc 	if (qInfo->tqi_cwmin != HAL_TXQ_USEDEFAULT) {
    695       1.1     alc 		cw = AH_MIN(qInfo->tqi_cwmin, 1024);
    696       1.1     alc 		/* make sure that the CWmin is of the form (2^n - 1) */
    697       1.1     alc 		qi->tqi_cwmin = 1;
    698       1.1     alc 		while (qi->tqi_cwmin < cw)
    699       1.1     alc 			qi->tqi_cwmin = (qi->tqi_cwmin << 1) | 1;
    700       1.1     alc 	} else
    701       1.1     alc 		qi->tqi_cwmin = qInfo->tqi_cwmin;
    702       1.1     alc 	if (qInfo->tqi_cwmax != HAL_TXQ_USEDEFAULT) {
    703       1.1     alc 		cw = AH_MIN(qInfo->tqi_cwmax, 1024);
    704       1.1     alc 		/* make sure that the CWmax is of the form (2^n - 1) */
    705       1.1     alc 		qi->tqi_cwmax = 1;
    706       1.1     alc 		while (qi->tqi_cwmax < cw)
    707       1.1     alc 			qi->tqi_cwmax = (qi->tqi_cwmax << 1) | 1;
    708       1.1     alc 	} else
    709       1.1     alc 		qi->tqi_cwmax = INIT_CWMAX;
    710       1.1     alc 	/* Set retry limit values */
    711       1.1     alc 	if (qInfo->tqi_shretry != 0)
    712       1.1     alc 		qi->tqi_shretry = AH_MIN(qInfo->tqi_shretry, 15);
    713       1.1     alc 	else
    714       1.1     alc 		qi->tqi_shretry = INIT_SH_RETRY;
    715       1.1     alc 	if (qInfo->tqi_lgretry != 0)
    716       1.1     alc 		qi->tqi_lgretry = AH_MIN(qInfo->tqi_lgretry, 15);
    717       1.1     alc 	else
    718       1.1     alc 		qi->tqi_lgretry = INIT_LG_RETRY;
    719       1.1     alc 	qi->tqi_cbrPeriod = qInfo->tqi_cbrPeriod;
    720       1.1     alc 	qi->tqi_cbrOverflowLimit = qInfo->tqi_cbrOverflowLimit;
    721       1.1     alc 	qi->tqi_burstTime = qInfo->tqi_burstTime;
    722       1.1     alc 	qi->tqi_readyTime = qInfo->tqi_readyTime;
    723       1.1     alc 
    724       1.1     alc 	switch (qInfo->tqi_subtype) {
    725       1.1     alc 	case HAL_WME_UPSD:
    726       1.1     alc 		if (qi->tqi_type == HAL_TX_QUEUE_DATA)
    727       1.1     alc 			qi->tqi_intFlags = HAL_TXQ_USE_LOCKOUT_BKOFF_DIS;
    728       1.1     alc 		break;
    729       1.1     alc 	default:
    730       1.1     alc 		break;		/* NB: silence compiler */
    731       1.1     alc 	}
    732       1.1     alc 	return AH_TRUE;
    733       1.1     alc }
    734       1.1     alc 
    735       1.1     alc HAL_BOOL
    736       1.1     alc ath_hal_getTxQProps(struct ath_hal *ah,
    737       1.1     alc 	HAL_TXQ_INFO *qInfo, const HAL_TX_QUEUE_INFO *qi)
    738       1.1     alc {
    739       1.1     alc 	if (qi->tqi_type == HAL_TX_QUEUE_INACTIVE) {
    740       1.1     alc 		HALDEBUG(ah, HAL_DEBUG_TXQUEUE,
    741       1.1     alc 		    "%s: inactive queue\n", __func__);
    742       1.1     alc 		return AH_FALSE;
    743       1.1     alc 	}
    744       1.1     alc 
    745       1.1     alc 	qInfo->tqi_qflags = qi->tqi_qflags;
    746       1.1     alc 	qInfo->tqi_ver = qi->tqi_ver;
    747       1.1     alc 	qInfo->tqi_subtype = qi->tqi_subtype;
    748       1.1     alc 	qInfo->tqi_qflags = qi->tqi_qflags;
    749       1.1     alc 	qInfo->tqi_priority = qi->tqi_priority;
    750       1.1     alc 	qInfo->tqi_aifs = qi->tqi_aifs;
    751       1.1     alc 	qInfo->tqi_cwmin = qi->tqi_cwmin;
    752       1.1     alc 	qInfo->tqi_cwmax = qi->tqi_cwmax;
    753       1.1     alc 	qInfo->tqi_shretry = qi->tqi_shretry;
    754       1.1     alc 	qInfo->tqi_lgretry = qi->tqi_lgretry;
    755       1.1     alc 	qInfo->tqi_cbrPeriod = qi->tqi_cbrPeriod;
    756       1.1     alc 	qInfo->tqi_cbrOverflowLimit = qi->tqi_cbrOverflowLimit;
    757       1.1     alc 	qInfo->tqi_burstTime = qi->tqi_burstTime;
    758       1.1     alc 	qInfo->tqi_readyTime = qi->tqi_readyTime;
    759       1.1     alc 	return AH_TRUE;
    760       1.1     alc }
    761       1.1     alc 
    762       1.1     alc                                      /* 11a Turbo  11b  11g  108g */
    763       1.1     alc static const int16_t NOISE_FLOOR[] = { -96, -93,  -98, -96,  -93 };
    764       1.1     alc 
    765       1.1     alc /*
    766       1.1     alc  * Read the current channel noise floor and return.
    767       1.1     alc  * If nf cal hasn't finished, channel noise floor should be 0
    768       1.1     alc  * and we return a nominal value based on band and frequency.
    769       1.1     alc  *
    770       1.1     alc  * NB: This is a private routine used by per-chip code to
    771       1.1     alc  *     implement the ah_getChanNoise method.
    772       1.1     alc  */
    773       1.1     alc int16_t
    774       1.1     alc ath_hal_getChanNoise(struct ath_hal *ah, HAL_CHANNEL *chan)
    775       1.1     alc {
    776       1.1     alc 	HAL_CHANNEL_INTERNAL *ichan;
    777       1.1     alc 
    778       1.1     alc 	ichan = ath_hal_checkchannel(ah, chan);
    779       1.1     alc 	if (ichan == AH_NULL) {
    780       1.1     alc 		HALDEBUG(ah, HAL_DEBUG_NFCAL,
    781       1.1     alc 		    "%s: invalid channel %u/0x%x; no mapping\n",
    782       1.1     alc 		    __func__, chan->channel, chan->channelFlags);
    783       1.1     alc 		return 0;
    784       1.1     alc 	}
    785       1.1     alc 	if (ichan->rawNoiseFloor == 0) {
    786       1.1     alc 		WIRELESS_MODE mode = ath_hal_chan2wmode(ah, chan);
    787       1.1     alc 
    788       1.1     alc 		HALASSERT(mode < WIRELESS_MODE_MAX);
    789       1.1     alc 		return NOISE_FLOOR[mode] + ath_hal_getNfAdjust(ah, ichan);
    790       1.1     alc 	} else
    791       1.1     alc 		return ichan->rawNoiseFloor + ichan->noiseFloorAdjust;
    792       1.1     alc }
    793       1.1     alc 
    794       1.1     alc /*
    795       1.1     alc  * Process all valid raw noise floors into the dBm noise floor values.
    796       1.1     alc  * Though our device has no reference for a dBm noise floor, we perform
    797       1.1     alc  * a relative minimization of NF's based on the lowest NF found across a
    798       1.1     alc  * channel scan.
    799       1.1     alc  */
    800       1.1     alc void
    801       1.1     alc ath_hal_process_noisefloor(struct ath_hal *ah)
    802       1.1     alc {
    803       1.1     alc 	HAL_CHANNEL_INTERNAL *c;
    804       1.1     alc 	int16_t correct2, correct5;
    805       1.1     alc 	int16_t lowest2, lowest5;
    806       1.1     alc 	int i;
    807       1.1     alc 
    808       1.1     alc 	/*
    809       1.1     alc 	 * Find the lowest 2GHz and 5GHz noise floor values after adjusting
    810       1.1     alc 	 * for statistically recorded NF/channel deviation.
    811       1.1     alc 	 */
    812       1.1     alc 	correct2 = lowest2 = 0;
    813       1.1     alc 	correct5 = lowest5 = 0;
    814       1.1     alc 	for (i = 0; i < AH_PRIVATE(ah)->ah_nchan; i++) {
    815       1.1     alc 		WIRELESS_MODE mode;
    816       1.1     alc 		int16_t nf;
    817       1.1     alc 
    818       1.1     alc 		c = &AH_PRIVATE(ah)->ah_channels[i];
    819       1.1     alc 		if (c->rawNoiseFloor >= 0)
    820       1.1     alc 			continue;
    821       1.1     alc 		mode = ath_hal_chan2wmode(ah, (HAL_CHANNEL *) c);
    822       1.1     alc 		HALASSERT(mode < WIRELESS_MODE_MAX);
    823       1.1     alc 		nf = c->rawNoiseFloor + NOISE_FLOOR[mode] +
    824       1.1     alc 			ath_hal_getNfAdjust(ah, c);
    825       1.1     alc 		if (IS_CHAN_5GHZ(c)) {
    826       1.1     alc 			if (nf < lowest5) {
    827       1.1     alc 				lowest5 = nf;
    828       1.1     alc 				correct5 = NOISE_FLOOR[mode] -
    829       1.1     alc 				    (c->rawNoiseFloor + ath_hal_getNfAdjust(ah, c));
    830       1.1     alc 			}
    831       1.1     alc 		} else {
    832       1.1     alc 			if (nf < lowest2) {
    833       1.1     alc 				lowest2 = nf;
    834       1.1     alc 				correct2 = NOISE_FLOOR[mode] -
    835       1.1     alc 				    (c->rawNoiseFloor + ath_hal_getNfAdjust(ah, c));
    836       1.1     alc 			}
    837       1.1     alc 		}
    838       1.1     alc 	}
    839       1.1     alc 
    840       1.1     alc 	/* Correct the channels to reach the expected NF value */
    841       1.1     alc 	for (i = 0; i < AH_PRIVATE(ah)->ah_nchan; i++) {
    842       1.1     alc 		c = &AH_PRIVATE(ah)->ah_channels[i];
    843       1.1     alc 		if (c->rawNoiseFloor >= 0)
    844       1.1     alc 			continue;
    845       1.1     alc 		/* Apply correction factor */
    846       1.1     alc 		c->noiseFloorAdjust = ath_hal_getNfAdjust(ah, c) +
    847       1.1     alc 			(IS_CHAN_5GHZ(c) ? correct5 : correct2);
    848       1.1     alc 		HALDEBUG(ah, HAL_DEBUG_NFCAL, "%u/0x%x raw nf %d adjust %d\n",
    849       1.1     alc 		    c->channel, c->channelFlags, c->rawNoiseFloor,
    850       1.1     alc 		    c->noiseFloorAdjust);
    851       1.1     alc 	}
    852       1.1     alc }
    853       1.1     alc 
    854       1.1     alc /*
    855       1.1     alc  * INI support routines.
    856       1.1     alc  */
    857       1.1     alc 
    858       1.1     alc int
    859       1.1     alc ath_hal_ini_write(struct ath_hal *ah, const HAL_INI_ARRAY *ia,
    860       1.1     alc 	int col, int regWr)
    861       1.1     alc {
    862       1.1     alc 	int r;
    863       1.1     alc 
    864       1.1     alc 	for (r = 0; r < ia->rows; r++) {
    865       1.1     alc 		OS_REG_WRITE(ah, HAL_INI_VAL(ia, r, 0),
    866       1.1     alc 		    HAL_INI_VAL(ia, r, col));
    867       1.1     alc 		DMA_YIELD(regWr);
    868       1.1     alc 	}
    869       1.1     alc 	return regWr;
    870       1.1     alc }
    871       1.1     alc 
    872       1.1     alc void
    873       1.1     alc ath_hal_ini_bank_setup(uint32_t data[], const HAL_INI_ARRAY *ia, int col)
    874       1.1     alc {
    875       1.1     alc 	int r;
    876       1.1     alc 
    877       1.1     alc 	for (r = 0; r < ia->rows; r++)
    878       1.1     alc 		data[r] = HAL_INI_VAL(ia, r, col);
    879       1.1     alc }
    880       1.1     alc 
    881       1.1     alc int
    882       1.1     alc ath_hal_ini_bank_write(struct ath_hal *ah, const HAL_INI_ARRAY *ia,
    883       1.1     alc 	const uint32_t data[], int regWr)
    884       1.1     alc {
    885       1.1     alc 	int r;
    886       1.1     alc 
    887       1.1     alc 	for (r = 0; r < ia->rows; r++) {
    888       1.1     alc 		OS_REG_WRITE(ah, HAL_INI_VAL(ia, r, 0), data[r]);
    889       1.1     alc 		DMA_YIELD(regWr);
    890       1.1     alc 	}
    891       1.1     alc 	return regWr;
    892       1.1     alc }
    893