Home | History | Annotate | Line # | Download | only in ar5212
      1 /*
      2  * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
      3  * Copyright (c) 2002-2008 Atheros Communications, Inc.
      4  *
      5  * Permission to use, copy, modify, and/or distribute this software for any
      6  * purpose with or without fee is hereby granted, provided that the above
      7  * copyright notice and this permission notice appear in all copies.
      8  *
      9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
     10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
     11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
     12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
     13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
     14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
     15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
     16  *
     17  * $Id: ar5212_misc.c,v 1.3 2012/02/12 13:48:45 wiz Exp $
     18  */
     19 #include "opt_ah.h"
     20 
     21 #include "ah.h"
     22 #include "ah_internal.h"
     23 #include "ah_devid.h"
     24 #ifdef AH_DEBUG
     25 #include "ah_desc.h"			/* NB: for HAL_PHYERR* */
     26 #endif
     27 
     28 #include "ar5212/ar5212.h"
     29 #include "ar5212/ar5212reg.h"
     30 #include "ar5212/ar5212phy.h"
     31 
     32 #include "ah_eeprom_v3.h"
     33 
     34 #define	AR_NUM_GPIO	6		/* 6 GPIO pins */
     35 #define	AR_GPIOD_MASK	0x0000002F	/* GPIO data reg r/w mask */
     36 
     37 extern void ar5212SetRateDurationTable(struct ath_hal *, HAL_CHANNEL *);
     38 
     39 void
     40 ar5212GetMacAddress(struct ath_hal *ah, uint8_t *mac)
     41 {
     42 	struct ath_hal_5212 *ahp = AH5212(ah);
     43 
     44 	OS_MEMCPY(mac, ahp->ah_macaddr, IEEE80211_ADDR_LEN);
     45 }
     46 
     47 HAL_BOOL
     48 ar5212SetMacAddress(struct ath_hal *ah, const uint8_t *mac)
     49 {
     50 	struct ath_hal_5212 *ahp = AH5212(ah);
     51 
     52 	OS_MEMCPY(ahp->ah_macaddr, mac, IEEE80211_ADDR_LEN);
     53 	return AH_TRUE;
     54 }
     55 
     56 void
     57 ar5212GetBssIdMask(struct ath_hal *ah, uint8_t *mask)
     58 {
     59 	struct ath_hal_5212 *ahp = AH5212(ah);
     60 
     61 	OS_MEMCPY(mask, ahp->ah_bssidmask, IEEE80211_ADDR_LEN);
     62 }
     63 
     64 HAL_BOOL
     65 ar5212SetBssIdMask(struct ath_hal *ah, const uint8_t *mask)
     66 {
     67 	struct ath_hal_5212 *ahp = AH5212(ah);
     68 
     69 	/* save it since it must be rewritten on reset */
     70 	OS_MEMCPY(ahp->ah_bssidmask, mask, IEEE80211_ADDR_LEN);
     71 
     72 	OS_REG_WRITE(ah, AR_BSSMSKL, LE_READ_4(ahp->ah_bssidmask));
     73 	OS_REG_WRITE(ah, AR_BSSMSKU, LE_READ_2(ahp->ah_bssidmask + 4));
     74 	return AH_TRUE;
     75 }
     76 
     77 /*
     78  * Attempt to change the cards operating regulatory domain to the given value
     79  */
     80 HAL_BOOL
     81 ar5212SetRegulatoryDomain(struct ath_hal *ah,
     82 	uint16_t regDomain, HAL_STATUS *status)
     83 {
     84 	HAL_STATUS ecode;
     85 
     86 	if (AH_PRIVATE(ah)->ah_currentRD == regDomain) {
     87 		ecode = HAL_EINVAL;
     88 		goto bad;
     89 	}
     90 	if (ath_hal_eepromGetFlag(ah, AR_EEP_WRITEPROTECT)) {
     91 		ecode = HAL_EEWRITE;
     92 		goto bad;
     93 	}
     94 #ifdef AH_SUPPORT_WRITE_REGDOMAIN
     95 	if (ath_hal_eepromWrite(ah, AR_EEPROM_REG_DOMAIN, regDomain)) {
     96 		HALDEBUG(ah, HAL_DEBUG_ANY,
     97 		    "%s: set regulatory domain to %u (0x%x)\n",
     98 		    __func__, regDomain, regDomain);
     99 		AH_PRIVATE(ah)->ah_currentRD = regDomain;
    100 		return AH_TRUE;
    101 	}
    102 #endif
    103 	ecode = HAL_EIO;
    104 bad:
    105 	if (status)
    106 		*status = ecode;
    107 	return AH_FALSE;
    108 }
    109 
    110 /*
    111  * Return the wireless modes (a,b,g,t) supported by hardware.
    112  *
    113  * This value is what is actually supported by the hardware
    114  * and is unaffected by regulatory/country code settings.
    115  */
    116 u_int
    117 ar5212GetWirelessModes(struct ath_hal *ah)
    118 {
    119 	u_int mode = 0;
    120 
    121 	if (ath_hal_eepromGetFlag(ah, AR_EEP_AMODE)) {
    122 		mode = HAL_MODE_11A;
    123 		if (!ath_hal_eepromGetFlag(ah, AR_EEP_TURBO5DISABLE))
    124 			mode |= HAL_MODE_TURBO | HAL_MODE_108A;
    125 		if (AH_PRIVATE(ah)->ah_caps.halChanHalfRate)
    126 			mode |= HAL_MODE_11A_HALF_RATE;
    127 		if (AH_PRIVATE(ah)->ah_caps.halChanQuarterRate)
    128 			mode |= HAL_MODE_11A_QUARTER_RATE;
    129 	}
    130 	if (ath_hal_eepromGetFlag(ah, AR_EEP_BMODE))
    131 		mode |= HAL_MODE_11B;
    132 	if (ath_hal_eepromGetFlag(ah, AR_EEP_GMODE) &&
    133 	    AH_PRIVATE(ah)->ah_subvendorid != AR_SUBVENDOR_ID_NOG) {
    134 		mode |= HAL_MODE_11G;
    135 		if (!ath_hal_eepromGetFlag(ah, AR_EEP_TURBO2DISABLE))
    136 			mode |= HAL_MODE_108G;
    137 		if (AH_PRIVATE(ah)->ah_caps.halChanHalfRate)
    138 			mode |= HAL_MODE_11G_HALF_RATE;
    139 		if (AH_PRIVATE(ah)->ah_caps.halChanQuarterRate)
    140 			mode |= HAL_MODE_11G_QUARTER_RATE;
    141 	}
    142 	return mode;
    143 }
    144 
    145 /*
    146  * Set the interrupt and GPIO values so the ISR can disable RF
    147  * on a switch signal.  Assumes GPIO port and interrupt polarity
    148  * are set prior to call.
    149  */
    150 void
    151 ar5212EnableRfKill(struct ath_hal *ah)
    152 {
    153 	uint16_t rfsilent = AH_PRIVATE(ah)->ah_rfsilent;
    154 	int select = MS(rfsilent, AR_EEPROM_RFSILENT_GPIO_SEL);
    155 	int polarity = MS(rfsilent, AR_EEPROM_RFSILENT_POLARITY);
    156 
    157 	/*
    158 	 * Configure the desired GPIO port for input
    159 	 * and enable baseband rf silence.
    160 	 */
    161 	ath_hal_gpioCfgInput(ah, select);
    162 	OS_REG_SET_BIT(ah, AR_PHY(0), 0x00002000);
    163 	/*
    164 	 * If radio disable switch connection to GPIO bit x is enabled
    165 	 * program GPIO interrupt.
    166 	 * If rfkill bit on eeprom is 1, setupeeprommap routine has already
    167 	 * verified that it is a later version of eeprom, it has a place for
    168 	 * rfkill bit and it is set to 1, indicating that GPIO bit x hardware
    169 	 * connection is present.
    170 	 */
    171 	ath_hal_gpioSetIntr(ah, select,
    172 	    (ath_hal_gpioGet(ah, select) == polarity ? !polarity : polarity));
    173 }
    174 
    175 /*
    176  * Change the LED blinking pattern to correspond to the connectivity
    177  */
    178 void
    179 ar5212SetLedState(struct ath_hal *ah, HAL_LED_STATE state)
    180 {
    181 	static const uint32_t ledbits[8] = {
    182 		AR_PCICFG_LEDCTL_NONE,	/* HAL_LED_INIT */
    183 		AR_PCICFG_LEDCTL_PEND,	/* HAL_LED_SCAN */
    184 		AR_PCICFG_LEDCTL_PEND,	/* HAL_LED_AUTH */
    185 		AR_PCICFG_LEDCTL_ASSOC,	/* HAL_LED_ASSOC*/
    186 		AR_PCICFG_LEDCTL_ASSOC,	/* HAL_LED_RUN */
    187 		AR_PCICFG_LEDCTL_NONE,
    188 		AR_PCICFG_LEDCTL_NONE,
    189 		AR_PCICFG_LEDCTL_NONE,
    190 	};
    191 	uint32_t bits;
    192 
    193 	bits = OS_REG_READ(ah, AR_PCICFG);
    194 	if (IS_2417(ah)) {
    195 		/*
    196 		 * Enable LED for Nala. There is a bit marked reserved
    197 		 * that must be set and we also turn on the power led.
    198 		 * Because we mark s/w LED control setting the control
    199 		 * status bits below is meangless (the driver must flash
    200 		 * the LED(s) using the GPIO lines).
    201 		 */
    202 		bits = (bits &~ AR_PCICFG_LEDMODE)
    203 		     | SM(AR_PCICFG_LEDMODE_POWON, AR_PCICFG_LEDMODE)
    204 #if 0
    205 		     | SM(AR_PCICFG_LEDMODE_NETON, AR_PCICFG_LEDMODE)
    206 #endif
    207 		     | 0x08000000;
    208 	}
    209 	bits = (bits &~ AR_PCICFG_LEDCTL)
    210 	     | SM(ledbits[state & 0x7], AR_PCICFG_LEDCTL);
    211 	OS_REG_WRITE(ah, AR_PCICFG, bits);
    212 }
    213 
    214 /*
    215  * Change association related fields programmed into the hardware.
    216  * Writing a valid BSSID to the hardware effectively enables the hardware
    217  * to synchronize its TSF to the correct beacons and receive frames coming
    218  * from that BSSID. It is called by the SME JOIN operation.
    219  */
    220 void
    221 ar5212WriteAssocid(struct ath_hal *ah, const uint8_t *bssid, uint16_t assocId)
    222 {
    223 	struct ath_hal_5212 *ahp = AH5212(ah);
    224 
    225 	/* XXX save bssid for possible re-use on reset */
    226 	OS_MEMCPY(ahp->ah_bssid, bssid, IEEE80211_ADDR_LEN);
    227 	OS_REG_WRITE(ah, AR_BSS_ID0, LE_READ_4(ahp->ah_bssid));
    228 	OS_REG_WRITE(ah, AR_BSS_ID1, LE_READ_2(ahp->ah_bssid+4) |
    229 				     ((assocId & 0x3fff)<<AR_BSS_ID1_AID_S));
    230 }
    231 
    232 /*
    233  * Get the current hardware tsf for stamlme
    234  */
    235 uint64_t
    236 ar5212GetTsf64(struct ath_hal *ah)
    237 {
    238 	uint32_t low1, low2, u32;
    239 
    240 	/* sync multi-word read */
    241 	low1 = OS_REG_READ(ah, AR_TSF_L32);
    242 	u32 = OS_REG_READ(ah, AR_TSF_U32);
    243 	low2 = OS_REG_READ(ah, AR_TSF_L32);
    244 	if (low2 < low1) {	/* roll over */
    245 		/*
    246 		 * If we are not preempted this will work.  If we are
    247 		 * then we re-reading AR_TSF_U32 does no good as the
    248 		 * low bits will be meaningless.  Likewise reading
    249 		 * L32, U32, U32, then comparing the last two reads
    250 		 * to check for rollover doesn't help if preempted--so
    251 		 * we take this approach as it costs one less PCI read
    252 		 * which can be noticeable when doing things like
    253 		 * timestamping packets in monitor mode.
    254 		 */
    255 		u32++;
    256 	}
    257 	return (((uint64_t) u32) << 32) | ((uint64_t) low2);
    258 }
    259 
    260 /*
    261  * Get the current hardware tsf for stamlme
    262  */
    263 uint32_t
    264 ar5212GetTsf32(struct ath_hal *ah)
    265 {
    266 	return OS_REG_READ(ah, AR_TSF_L32);
    267 }
    268 
    269 /*
    270  * Reset the current hardware tsf for stamlme.
    271  */
    272 void
    273 ar5212ResetTsf(struct ath_hal *ah)
    274 {
    275 
    276 	uint32_t val = OS_REG_READ(ah, AR_BEACON);
    277 
    278 	OS_REG_WRITE(ah, AR_BEACON, val | AR_BEACON_RESET_TSF);
    279 	/*
    280 	 * When resetting the TSF, write twice to the
    281 	 * corresponding register; each write to the RESET_TSF bit toggles
    282 	 * the internal signal to cause a reset of the TSF - but if the signal
    283 	 * is left high, it will reset the TSF on the next chip reset also!
    284 	 * writing the bit an even number of times fixes this issue
    285 	 */
    286 	OS_REG_WRITE(ah, AR_BEACON, val | AR_BEACON_RESET_TSF);
    287 }
    288 
    289 /*
    290  * Set or clear hardware basic rate bit
    291  * Set hardware basic rate set if basic rate is found
    292  * and basic rate is equal or less than 2Mbps
    293  */
    294 void
    295 ar5212SetBasicRate(struct ath_hal *ah, HAL_RATE_SET *rs)
    296 {
    297 	HAL_CHANNEL_INTERNAL *chan = AH_PRIVATE(ah)->ah_curchan;
    298 	uint32_t reg;
    299 	uint8_t xset;
    300 	int i;
    301 
    302 	if (chan == AH_NULL || !IS_CHAN_CCK(chan))
    303 		return;
    304 	xset = 0;
    305 	for (i = 0; i < rs->rs_count; i++) {
    306 		uint8_t rset = rs->rs_rates[i];
    307 		/* Basic rate defined? */
    308 		if ((rset & 0x80) && (rset &= 0x7f) >= xset)
    309 			xset = rset;
    310 	}
    311 	/*
    312 	 * Set the h/w bit to reflect whether or not the basic
    313 	 * rate is found to be equal or less than 2Mbps.
    314 	 */
    315 	reg = OS_REG_READ(ah, AR_STA_ID1);
    316 	if (xset && xset/2 <= 2)
    317 		OS_REG_WRITE(ah, AR_STA_ID1, reg | AR_STA_ID1_BASE_RATE_11B);
    318 	else
    319 		OS_REG_WRITE(ah, AR_STA_ID1, reg &~ AR_STA_ID1_BASE_RATE_11B);
    320 }
    321 
    322 /*
    323  * Grab a semi-random value from hardware registers - may not
    324  * change often
    325  */
    326 uint32_t
    327 ar5212GetRandomSeed(struct ath_hal *ah)
    328 {
    329 	uint32_t nf;
    330 
    331 	nf = (OS_REG_READ(ah, AR_PHY(25)) >> 19) & 0x1ff;
    332 	if (nf & 0x100)
    333 		nf = 0 - ((nf ^ 0x1ff) + 1);
    334 	return (OS_REG_READ(ah, AR_TSF_U32) ^
    335 		OS_REG_READ(ah, AR_TSF_L32) ^ nf);
    336 }
    337 
    338 /*
    339  * Detect if our card is present
    340  */
    341 HAL_BOOL
    342 ar5212DetectCardPresent(struct ath_hal *ah)
    343 {
    344 	uint16_t macVersion, macRev;
    345 	uint32_t v;
    346 
    347 	/*
    348 	 * Read the Silicon Revision register and compare that
    349 	 * to what we read at attach time.  If the same, we say
    350 	 * a card/device is present.
    351 	 */
    352 	v = OS_REG_READ(ah, AR_SREV) & AR_SREV_ID;
    353 	macVersion = v >> AR_SREV_ID_S;
    354 	macRev = v & AR_SREV_REVISION;
    355 	return (AH_PRIVATE(ah)->ah_macVersion == macVersion &&
    356 		AH_PRIVATE(ah)->ah_macRev == macRev);
    357 }
    358 
    359 void
    360 ar5212EnableMibCounters(struct ath_hal *ah)
    361 {
    362 	/* NB: this just resets the mib counter machinery */
    363 	OS_REG_WRITE(ah, AR_MIBC,
    364 	    ~(AR_MIBC_COW | AR_MIBC_FMC | AR_MIBC_CMC | AR_MIBC_MCS) & 0x0f);
    365 }
    366 
    367 void
    368 ar5212DisableMibCounters(struct ath_hal *ah)
    369 {
    370 	OS_REG_WRITE(ah, AR_MIBC,  AR_MIBC | AR_MIBC_CMC);
    371 }
    372 
    373 /*
    374  * Update MIB Counters
    375  */
    376 void
    377 ar5212UpdateMibCounters(struct ath_hal *ah, HAL_MIB_STATS* stats)
    378 {
    379 	stats->ackrcv_bad += OS_REG_READ(ah, AR_ACK_FAIL);
    380 	stats->rts_bad	  += OS_REG_READ(ah, AR_RTS_FAIL);
    381 	stats->fcs_bad	  += OS_REG_READ(ah, AR_FCS_FAIL);
    382 	stats->rts_good	  += OS_REG_READ(ah, AR_RTS_OK);
    383 	stats->beacons	  += OS_REG_READ(ah, AR_BEACON_CNT);
    384 }
    385 
    386 /*
    387  * Detect if the HW supports spreading a CCK signal on channel 14
    388  */
    389 HAL_BOOL
    390 ar5212IsJapanChannelSpreadSupported(struct ath_hal *ah)
    391 {
    392 	return AH_TRUE;
    393 }
    394 
    395 /*
    396  * Get the rssi of frame curently being received.
    397  */
    398 uint32_t
    399 ar5212GetCurRssi(struct ath_hal *ah)
    400 {
    401 	return (OS_REG_READ(ah, AR_PHY_CURRENT_RSSI) & 0xff);
    402 }
    403 
    404 u_int
    405 ar5212GetDefAntenna(struct ath_hal *ah)
    406 {
    407 	return (OS_REG_READ(ah, AR_DEF_ANTENNA) & 0x7);
    408 }
    409 
    410 void
    411 ar5212SetDefAntenna(struct ath_hal *ah, u_int antenna)
    412 {
    413 	OS_REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7));
    414 }
    415 
    416 HAL_ANT_SETTING
    417 ar5212GetAntennaSwitch(struct ath_hal *ah)
    418 {
    419 	return AH5212(ah)->ah_antControl;
    420 }
    421 
    422 HAL_BOOL
    423 ar5212SetAntennaSwitch(struct ath_hal *ah, HAL_ANT_SETTING setting)
    424 {
    425 	struct ath_hal_5212 *ahp = AH5212(ah);
    426 	const HAL_CHANNEL_INTERNAL *ichan = AH_PRIVATE(ah)->ah_curchan;
    427 
    428 	if (!ahp->ah_phyPowerOn || ichan == AH_NULL) {
    429 		/* PHY powered off, just stash settings */
    430 		ahp->ah_antControl = setting;
    431 		ahp->ah_diversity = (setting == HAL_ANT_VARIABLE);
    432 		return AH_TRUE;
    433 	}
    434 	return ar5212SetAntennaSwitchInternal(ah, setting, ichan);
    435 }
    436 
    437 HAL_BOOL
    438 ar5212IsSleepAfterBeaconBroken(struct ath_hal *ah)
    439 {
    440 	return AH_TRUE;
    441 }
    442 
    443 HAL_BOOL
    444 ar5212SetSifsTime(struct ath_hal *ah, u_int us)
    445 {
    446 	struct ath_hal_5212 *ahp = AH5212(ah);
    447 
    448 	if (us > ath_hal_mac_usec(ah, 0xffff)) {
    449 		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad SIFS time %u\n",
    450 		    __func__, us);
    451 		ahp->ah_sifstime = (u_int) -1;	/* restore default handling */
    452 		return AH_FALSE;
    453 	} else {
    454 		/* convert to system clocks */
    455 		OS_REG_WRITE(ah, AR_D_GBL_IFS_SIFS, ath_hal_mac_clks(ah, us-2));
    456 		ahp->ah_slottime = us;
    457 		return AH_TRUE;
    458 	}
    459 }
    460 
    461 u_int
    462 ar5212GetSifsTime(struct ath_hal *ah)
    463 {
    464 	u_int clks = OS_REG_READ(ah, AR_D_GBL_IFS_SIFS) & 0xffff;
    465 	return ath_hal_mac_usec(ah, clks)+2;	/* convert from system clocks */
    466 }
    467 
    468 HAL_BOOL
    469 ar5212SetSlotTime(struct ath_hal *ah, u_int us)
    470 {
    471 	struct ath_hal_5212 *ahp = AH5212(ah);
    472 
    473 	if (us < HAL_SLOT_TIME_6 || us > ath_hal_mac_usec(ah, 0xffff)) {
    474 		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad slot time %u\n",
    475 		    __func__, us);
    476 		ahp->ah_slottime = (u_int) -1;	/* restore default handling */
    477 		return AH_FALSE;
    478 	} else {
    479 		/* convert to system clocks */
    480 		OS_REG_WRITE(ah, AR_D_GBL_IFS_SLOT, ath_hal_mac_clks(ah, us));
    481 		ahp->ah_slottime = us;
    482 		return AH_TRUE;
    483 	}
    484 }
    485 
    486 u_int
    487 ar5212GetSlotTime(struct ath_hal *ah)
    488 {
    489 	u_int clks = OS_REG_READ(ah, AR_D_GBL_IFS_SLOT) & 0xffff;
    490 	return ath_hal_mac_usec(ah, clks);	/* convert from system clocks */
    491 }
    492 
    493 HAL_BOOL
    494 ar5212SetAckTimeout(struct ath_hal *ah, u_int us)
    495 {
    496 	struct ath_hal_5212 *ahp = AH5212(ah);
    497 
    498 	if (us > ath_hal_mac_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) {
    499 		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad ack timeout %u\n",
    500 		    __func__, us);
    501 		ahp->ah_acktimeout = (u_int) -1; /* restore default handling */
    502 		return AH_FALSE;
    503 	} else {
    504 		/* convert to system clocks */
    505 		OS_REG_RMW_FIELD(ah, AR_TIME_OUT,
    506 			AR_TIME_OUT_ACK, ath_hal_mac_clks(ah, us));
    507 		ahp->ah_acktimeout = us;
    508 		return AH_TRUE;
    509 	}
    510 }
    511 
    512 u_int
    513 ar5212GetAckTimeout(struct ath_hal *ah)
    514 {
    515 	u_int clks = MS(OS_REG_READ(ah, AR_TIME_OUT), AR_TIME_OUT_ACK);
    516 	return ath_hal_mac_usec(ah, clks);	/* convert from system clocks */
    517 }
    518 
    519 u_int
    520 ar5212GetAckCTSRate(struct ath_hal *ah)
    521 {
    522 	return ((AH5212(ah)->ah_staId1Defaults & AR_STA_ID1_ACKCTS_6MB) == 0);
    523 }
    524 
    525 HAL_BOOL
    526 ar5212SetAckCTSRate(struct ath_hal *ah, u_int high)
    527 {
    528 	struct ath_hal_5212 *ahp = AH5212(ah);
    529 
    530 	if (high) {
    531 		OS_REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_ACKCTS_6MB);
    532 		ahp->ah_staId1Defaults &= ~AR_STA_ID1_ACKCTS_6MB;
    533 	} else {
    534 		OS_REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_ACKCTS_6MB);
    535 		ahp->ah_staId1Defaults |= AR_STA_ID1_ACKCTS_6MB;
    536 	}
    537 	return AH_TRUE;
    538 }
    539 
    540 HAL_BOOL
    541 ar5212SetCTSTimeout(struct ath_hal *ah, u_int us)
    542 {
    543 	struct ath_hal_5212 *ahp = AH5212(ah);
    544 
    545 	if (us > ath_hal_mac_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) {
    546 		HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad cts timeout %u\n",
    547 		    __func__, us);
    548 		ahp->ah_ctstimeout = (u_int) -1; /* restore default handling */
    549 		return AH_FALSE;
    550 	} else {
    551 		/* convert to system clocks */
    552 		OS_REG_RMW_FIELD(ah, AR_TIME_OUT,
    553 			AR_TIME_OUT_CTS, ath_hal_mac_clks(ah, us));
    554 		ahp->ah_ctstimeout = us;
    555 		return AH_TRUE;
    556 	}
    557 }
    558 
    559 u_int
    560 ar5212GetCTSTimeout(struct ath_hal *ah)
    561 {
    562 	u_int clks = MS(OS_REG_READ(ah, AR_TIME_OUT), AR_TIME_OUT_CTS);
    563 	return ath_hal_mac_usec(ah, clks);	/* convert from system clocks */
    564 }
    565 
    566 /* Setup decompression for given key index */
    567 HAL_BOOL
    568 ar5212SetDecompMask(struct ath_hal *ah, uint16_t keyidx, int en)
    569 {
    570 	struct ath_hal_5212 *ahp = AH5212(ah);
    571 
    572         if (keyidx >= HAL_DECOMP_MASK_SIZE)
    573                 return AH_FALSE;
    574         OS_REG_WRITE(ah, AR_DCM_A, keyidx);
    575         OS_REG_WRITE(ah, AR_DCM_D, en ? AR_DCM_D_EN : 0);
    576         ahp->ah_decompMask[keyidx] = en;
    577 
    578         return AH_TRUE;
    579 }
    580 
    581 /* Setup coverage class */
    582 void
    583 ar5212SetCoverageClass(struct ath_hal *ah, uint8_t coverageclass, int now)
    584 {
    585 	uint32_t slot, timeout, eifs;
    586 	u_int clkRate;
    587 
    588 	AH_PRIVATE(ah)->ah_coverageClass = coverageclass;
    589 
    590 	if (now) {
    591 		if (AH_PRIVATE(ah)->ah_coverageClass == 0)
    592 			return;
    593 
    594 		/* Don't apply coverage class to non A channels */
    595 		if (!IS_CHAN_A(AH_PRIVATE(ah)->ah_curchan))
    596 			return;
    597 
    598 		/* Get core clock rate */
    599 		clkRate = ath_hal_mac_clks(ah, 1);
    600 
    601 		/* Compute EIFS */
    602 		slot = coverageclass * 3 * clkRate;
    603 		eifs = coverageclass * 6 * clkRate;
    604 		if (IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan)) {
    605 			slot += IFS_SLOT_HALF_RATE;
    606 			eifs += IFS_EIFS_HALF_RATE;
    607 		} else if (IS_CHAN_QUARTER_RATE(AH_PRIVATE(ah)->ah_curchan)) {
    608 			slot += IFS_SLOT_QUARTER_RATE;
    609 			eifs += IFS_EIFS_QUARTER_RATE;
    610 		} else { /* full rate */
    611 			slot += IFS_SLOT_FULL_RATE;
    612 			eifs += IFS_EIFS_FULL_RATE;
    613 		}
    614 
    615 		/*
    616 		 * Add additional time for air propagation for ACK and CTS
    617 		 * timeouts. This value is in core clocks.
    618   		 */
    619 		timeout = ACK_CTS_TIMEOUT_11A + (coverageclass * 3 * clkRate);
    620 
    621 		/*
    622 		 * Write the values: slot, eifs, ack/cts timeouts.
    623 		 */
    624 		OS_REG_WRITE(ah, AR_D_GBL_IFS_SLOT, slot);
    625 		OS_REG_WRITE(ah, AR_D_GBL_IFS_EIFS, eifs);
    626 		OS_REG_WRITE(ah, AR_TIME_OUT,
    627 			  SM(timeout, AR_TIME_OUT_CTS)
    628 			| SM(timeout, AR_TIME_OUT_ACK));
    629 	}
    630 }
    631 
    632 void
    633 ar5212SetPCUConfig(struct ath_hal *ah)
    634 {
    635 	ar5212SetOperatingMode(ah, AH_PRIVATE(ah)->ah_opmode);
    636 }
    637 
    638 /*
    639  * Return whether an external 32KHz crystal should be used
    640  * to reduce power consumption when sleeping.  We do so if
    641  * the crystal is present (obtained from EEPROM) and if we
    642  * are not running as an AP and are configured to use it.
    643  */
    644 HAL_BOOL
    645 ar5212Use32KHzclock(struct ath_hal *ah, HAL_OPMODE opmode)
    646 {
    647 	if (opmode != HAL_M_HOSTAP) {
    648 		struct ath_hal_5212 *ahp = AH5212(ah);
    649 		return ath_hal_eepromGetFlag(ah, AR_EEP_32KHZCRYSTAL) &&
    650 		       (ahp->ah_enable32kHzClock == USE_32KHZ ||
    651 		        ahp->ah_enable32kHzClock == AUTO_32KHZ);
    652 	} else
    653 		return AH_FALSE;
    654 }
    655 
    656 /*
    657  * If 32KHz clock exists, use it to lower power consumption during sleep
    658  *
    659  * Note: If clock is set to 32 KHz, delays on accessing certain
    660  *       baseband registers (27-31, 124-127) are required.
    661  */
    662 void
    663 ar5212SetupClock(struct ath_hal *ah, HAL_OPMODE opmode)
    664 {
    665 	if (ar5212Use32KHzclock(ah, opmode)) {
    666 		/*
    667 		 * Enable clocks to be turned OFF in BB during sleep
    668 		 * and also enable turning OFF 32MHz/40MHz Refclk
    669 		 * from A2.
    670 		 */
    671 		OS_REG_WRITE(ah, AR_PHY_SLEEP_CTR_CONTROL, 0x1f);
    672 		OS_REG_WRITE(ah, AR_PHY_REFCLKPD,
    673 		    IS_RAD5112_ANY(ah) || IS_5413(ah) ? 0x14 : 0x18);
    674 		OS_REG_RMW_FIELD(ah, AR_USEC, AR_USEC_USEC32, 1);
    675 		OS_REG_WRITE(ah, AR_TSF_PARM, 61);  /* 32 KHz TSF incr */
    676 		OS_REG_RMW_FIELD(ah, AR_PCICFG, AR_PCICFG_SCLK_SEL, 1);
    677 
    678 		if (IS_2413(ah) || IS_5413(ah) || IS_2417(ah)) {
    679 			OS_REG_WRITE(ah, AR_PHY_SLEEP_CTR_LIMIT,   0x26);
    680 			OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL,        0x0d);
    681 			OS_REG_WRITE(ah, AR_PHY_M_SLEEP,           0x07);
    682 			OS_REG_WRITE(ah, AR_PHY_REFCLKDLY,         0x3f);
    683 			/* # Set sleep clock rate to 32 KHz. */
    684 			OS_REG_RMW_FIELD(ah, AR_PCICFG, AR_PCICFG_SCLK_RATE_IND, 0x2);
    685 		} else {
    686 			OS_REG_WRITE(ah, AR_PHY_SLEEP_CTR_LIMIT,   0x0a);
    687 			OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL,        0x0c);
    688 			OS_REG_WRITE(ah, AR_PHY_M_SLEEP,           0x03);
    689 			OS_REG_WRITE(ah, AR_PHY_REFCLKDLY,         0x20);
    690 			OS_REG_RMW_FIELD(ah, AR_PCICFG, AR_PCICFG_SCLK_RATE_IND, 0x3);
    691 		}
    692 	} else {
    693 		OS_REG_RMW_FIELD(ah, AR_PCICFG, AR_PCICFG_SCLK_RATE_IND, 0x0);
    694 		OS_REG_RMW_FIELD(ah, AR_PCICFG, AR_PCICFG_SCLK_SEL, 0);
    695 
    696 		OS_REG_WRITE(ah, AR_TSF_PARM, 1);	/* 32MHz TSF inc */
    697 
    698 		OS_REG_WRITE(ah, AR_PHY_SLEEP_CTR_CONTROL, 0x1f);
    699 		OS_REG_WRITE(ah, AR_PHY_SLEEP_CTR_LIMIT,   0x7f);
    700 
    701 		if (IS_2417(ah))
    702 			OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x0a);
    703 		else if (IS_HB63(ah))
    704 			OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x32);
    705 		else
    706 			OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL, 0x0e);
    707 		OS_REG_WRITE(ah, AR_PHY_M_SLEEP,           0x0c);
    708 		OS_REG_WRITE(ah, AR_PHY_REFCLKDLY,         0xff);
    709 		OS_REG_WRITE(ah, AR_PHY_REFCLKPD,
    710 		    IS_RAD5112_ANY(ah) || IS_5413(ah) || IS_2417(ah) ? 0x14 : 0x18);
    711 		OS_REG_RMW_FIELD(ah, AR_USEC, AR_USEC_USEC32,
    712 		    IS_RAD5112_ANY(ah) || IS_5413(ah) ? 39 : 31);
    713 	}
    714 }
    715 
    716 /*
    717  * If 32KHz clock exists, turn it off and turn back on the 32Mhz
    718  */
    719 void
    720 ar5212RestoreClock(struct ath_hal *ah, HAL_OPMODE opmode)
    721 {
    722 	if (ar5212Use32KHzclock(ah, opmode)) {
    723 		/* # Set sleep clock rate back to 32 MHz. */
    724 		OS_REG_RMW_FIELD(ah, AR_PCICFG, AR_PCICFG_SCLK_RATE_IND, 0);
    725 		OS_REG_RMW_FIELD(ah, AR_PCICFG, AR_PCICFG_SCLK_SEL, 0);
    726 
    727 		OS_REG_WRITE(ah, AR_TSF_PARM, 1);	/* 32 MHz TSF incr */
    728 		OS_REG_RMW_FIELD(ah, AR_USEC, AR_USEC_USEC32,
    729 		    IS_RAD5112_ANY(ah) || IS_5413(ah) ? 39 : 31);
    730 
    731 		/*
    732 		 * Restore BB registers to power-on defaults
    733 		 */
    734 		OS_REG_WRITE(ah, AR_PHY_SLEEP_CTR_CONTROL, 0x1f);
    735 		OS_REG_WRITE(ah, AR_PHY_SLEEP_CTR_LIMIT,   0x7f);
    736 		OS_REG_WRITE(ah, AR_PHY_SLEEP_SCAL,        0x0e);
    737 		OS_REG_WRITE(ah, AR_PHY_M_SLEEP,           0x0c);
    738 		OS_REG_WRITE(ah, AR_PHY_REFCLKDLY,         0xff);
    739 		OS_REG_WRITE(ah, AR_PHY_REFCLKPD,
    740 		    IS_RAD5112_ANY(ah) || IS_5413(ah) ?  0x14 : 0x18);
    741 	}
    742 }
    743 
    744 /*
    745  * Adjust NF based on statistical values for 5GHz frequencies.
    746  * Default method: this may be overridden by the rf backend.
    747  */
    748 int16_t
    749 ar5212GetNfAdjust(struct ath_hal *ah, const HAL_CHANNEL_INTERNAL *c)
    750 {
    751 	static const struct {
    752 		uint16_t freqLow;
    753 		int16_t	  adjust;
    754 	} adjustDef[] = {
    755 		{ 5790,	11 },	/* NB: ordered high -> low */
    756 		{ 5730, 10 },
    757 		{ 5690,  9 },
    758 		{ 5660,  8 },
    759 		{ 5610,  7 },
    760 		{ 5530,  5 },
    761 		{ 5450,  4 },
    762 		{ 5379,  2 },
    763 		{ 5209,  0 },
    764 		{ 3000,  1 },
    765 		{    0,  0 },
    766 	};
    767 	int i;
    768 
    769 	for (i = 0; c->channel <= adjustDef[i].freqLow; i++)
    770 		;
    771 	return adjustDef[i].adjust;
    772 }
    773 
    774 HAL_STATUS
    775 ar5212GetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
    776 	uint32_t capability, uint32_t *result)
    777 {
    778 #define	MACVERSION(ah)	AH_PRIVATE(ah)->ah_macVersion
    779 	struct ath_hal_5212 *ahp = AH5212(ah);
    780 	const HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;
    781 	const struct ar5212AniState *ani;
    782 
    783 	switch (type) {
    784 	case HAL_CAP_CIPHER:		/* cipher handled in hardware */
    785 		switch (capability) {
    786 		case HAL_CIPHER_AES_CCM:
    787 			return pCap->halCipherAesCcmSupport ?
    788 				HAL_OK : HAL_ENOTSUPP;
    789 		case HAL_CIPHER_AES_OCB:
    790 		case HAL_CIPHER_TKIP:
    791 		case HAL_CIPHER_WEP:
    792 		case HAL_CIPHER_MIC:
    793 		case HAL_CIPHER_CLR:
    794 			return HAL_OK;
    795 		default:
    796 			return HAL_ENOTSUPP;
    797 		}
    798 	case HAL_CAP_TKIP_MIC:		/* handle TKIP MIC in hardware */
    799 		switch (capability) {
    800 		case 0:			/* hardware capability */
    801 			return HAL_OK;
    802 		case 1:
    803 			return (ahp->ah_staId1Defaults &
    804 			    AR_STA_ID1_CRPT_MIC_ENABLE) ?  HAL_OK : HAL_ENXIO;
    805 		}
    806 		return HAL_EINVAL;
    807 	case HAL_CAP_TKIP_SPLIT:	/* hardware TKIP uses split keys */
    808 		switch (capability) {
    809 		case 0:			/* hardware capability */
    810 			return pCap->halTkipMicTxRxKeySupport ?
    811 				HAL_ENXIO : HAL_OK;
    812 		case 1:			/* current setting */
    813 			return (ahp->ah_miscMode &
    814 			    AR_MISC_MODE_MIC_NEW_LOC_ENABLE) ? HAL_ENXIO : HAL_OK;
    815 		}
    816 		return HAL_EINVAL;
    817 	case HAL_CAP_WME_TKIPMIC:	/* hardware can do TKIP MIC w/ WMM */
    818 		/* XXX move to capability bit */
    819 		return MACVERSION(ah) > AR_SREV_VERSION_VENICE ||
    820 		    (MACVERSION(ah) == AR_SREV_VERSION_VENICE &&
    821 		     AH_PRIVATE(ah)->ah_macRev >= 8) ? HAL_OK : HAL_ENOTSUPP;
    822 	case HAL_CAP_DIVERSITY:		/* hardware supports fast diversity */
    823 		switch (capability) {
    824 		case 0:			/* hardware capability */
    825 			return HAL_OK;
    826 		case 1:			/* current setting */
    827 			return ahp->ah_diversity ? HAL_OK : HAL_ENXIO;
    828 		}
    829 		return HAL_EINVAL;
    830 	case HAL_CAP_DIAG:
    831 		*result = AH_PRIVATE(ah)->ah_diagreg;
    832 		return HAL_OK;
    833 	case HAL_CAP_TPC:
    834 		switch (capability) {
    835 		case 0:			/* hardware capability */
    836 			return HAL_OK;
    837 		case 1:
    838 			return ahp->ah_tpcEnabled ? HAL_OK : HAL_ENXIO;
    839 		}
    840 		return HAL_OK;
    841 	case HAL_CAP_PHYDIAG:		/* radar pulse detection capability */
    842 		switch (capability) {
    843 		case HAL_CAP_RADAR:
    844 			return ath_hal_eepromGetFlag(ah, AR_EEP_AMODE) ?
    845 			    HAL_OK: HAL_ENXIO;
    846 		case HAL_CAP_AR:
    847 			return (ath_hal_eepromGetFlag(ah, AR_EEP_GMODE) ||
    848 			    ath_hal_eepromGetFlag(ah, AR_EEP_BMODE)) ?
    849 			       HAL_OK: HAL_ENXIO;
    850 		}
    851 		return HAL_ENXIO;
    852 	case HAL_CAP_MCAST_KEYSRCH:	/* multicast frame keycache search */
    853 		switch (capability) {
    854 		case 0:			/* hardware capability */
    855 			return HAL_OK;
    856 		case 1:
    857 			return (ahp->ah_staId1Defaults &
    858 			    AR_STA_ID1_MCAST_KSRCH) ? HAL_OK : HAL_ENXIO;
    859 		}
    860 		return HAL_EINVAL;
    861 	case HAL_CAP_TSF_ADJUST:	/* hardware has beacon tsf adjust */
    862 		switch (capability) {
    863 		case 0:			/* hardware capability */
    864 			return pCap->halTsfAddSupport ? HAL_OK : HAL_ENOTSUPP;
    865 		case 1:
    866 			return (ahp->ah_miscMode & AR_MISC_MODE_TX_ADD_TSF) ?
    867 				HAL_OK : HAL_ENXIO;
    868 		}
    869 		return HAL_EINVAL;
    870 	case HAL_CAP_TPC_ACK:
    871 		*result = MS(ahp->ah_macTPC, AR_TPC_ACK);
    872 		return HAL_OK;
    873 	case HAL_CAP_TPC_CTS:
    874 		*result = MS(ahp->ah_macTPC, AR_TPC_CTS);
    875 		return HAL_OK;
    876 	case HAL_CAP_INTMIT:		/* interference mitigation */
    877 		switch (capability) {
    878 		case 0:			/* hardware capability */
    879 			return HAL_OK;
    880 		case 1:
    881 			return (ahp->ah_procPhyErr & HAL_ANI_ENA) ?
    882 				HAL_OK : HAL_ENXIO;
    883 		case 2:			/* HAL_ANI_NOISE_IMMUNITY_LEVEL */
    884 		case 3:			/* HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION */
    885 		case 4:			/* HAL_ANI_CCK_WEAK_SIGNAL_THR */
    886 		case 5:			/* HAL_ANI_FIRSTEP_LEVEL */
    887 		case 6:			/* HAL_ANI_SPUR_IMMUNITY_LEVEL */
    888 			ani = ar5212AniGetCurrentState(ah);
    889 			if (ani == AH_NULL)
    890 				return HAL_ENXIO;
    891 			switch (capability) {
    892 			case 2:	*result = ani->noiseImmunityLevel; break;
    893 			case 3: *result = !ani->ofdmWeakSigDetectOff; break;
    894 			case 4: *result = ani->cckWeakSigThreshold; break;
    895 			case 5: *result = ani->firstepLevel; break;
    896 			case 6: *result = ani->spurImmunityLevel; break;
    897 			}
    898 			return HAL_OK;
    899 		}
    900 		return HAL_EINVAL;
    901 	default:
    902 		return ath_hal_getcapability(ah, type, capability, result);
    903 	}
    904 #undef MACVERSION
    905 }
    906 
    907 HAL_BOOL
    908 ar5212SetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type,
    909 	uint32_t capability, uint32_t setting, HAL_STATUS *status)
    910 {
    911 #define	N(a)	(sizeof(a)/sizeof(a[0]))
    912 	struct ath_hal_5212 *ahp = AH5212(ah);
    913 	const HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;
    914 	uint32_t v;
    915 
    916 	switch (type) {
    917 	case HAL_CAP_TKIP_MIC:		/* handle TKIP MIC in hardware */
    918 		if (setting)
    919 			ahp->ah_staId1Defaults |= AR_STA_ID1_CRPT_MIC_ENABLE;
    920 		else
    921 			ahp->ah_staId1Defaults &= ~AR_STA_ID1_CRPT_MIC_ENABLE;
    922 		return AH_TRUE;
    923 	case HAL_CAP_TKIP_SPLIT:	/* hardware TKIP uses split keys */
    924 		if (!pCap->halTkipMicTxRxKeySupport)
    925 			return AH_FALSE;
    926 		/* NB: true =>'s use split key cache layout */
    927 		if (setting)
    928 			ahp->ah_miscMode &= ~AR_MISC_MODE_MIC_NEW_LOC_ENABLE;
    929 		else
    930 			ahp->ah_miscMode |= AR_MISC_MODE_MIC_NEW_LOC_ENABLE;
    931 		/* NB: write here so keys can be setup w/o a reset */
    932 		OS_REG_WRITE(ah, AR_MISC_MODE, ahp->ah_miscMode);
    933 		return AH_TRUE;
    934 	case HAL_CAP_DIVERSITY:
    935 		if (ahp->ah_phyPowerOn) {
    936 			v = OS_REG_READ(ah, AR_PHY_CCK_DETECT);
    937 			if (setting)
    938 				v |= AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
    939 			else
    940 				v &= ~AR_PHY_CCK_DETECT_BB_ENABLE_ANT_FAST_DIV;
    941 			OS_REG_WRITE(ah, AR_PHY_CCK_DETECT, v);
    942 		}
    943 		ahp->ah_diversity = (setting != 0);
    944 		return AH_TRUE;
    945 	case HAL_CAP_DIAG:		/* hardware diagnostic support */
    946 		/*
    947 		 * NB: could split this up into virtual capabilities,
    948 		 *     (e.g. 1 => ACK, 2 => CTS, etc.) but it hardly
    949 		 *     seems worth the additional complexity.
    950 		 */
    951 		AH_PRIVATE(ah)->ah_diagreg = setting;
    952 		OS_REG_WRITE(ah, AR_DIAG_SW, AH_PRIVATE(ah)->ah_diagreg);
    953 		return AH_TRUE;
    954 	case HAL_CAP_TPC:
    955 		ahp->ah_tpcEnabled = (setting != 0);
    956 		return AH_TRUE;
    957 	case HAL_CAP_MCAST_KEYSRCH:	/* multicast frame keycache search */
    958 		if (setting)
    959 			ahp->ah_staId1Defaults |= AR_STA_ID1_MCAST_KSRCH;
    960 		else
    961 			ahp->ah_staId1Defaults &= ~AR_STA_ID1_MCAST_KSRCH;
    962 		return AH_TRUE;
    963 	case HAL_CAP_TPC_ACK:
    964 	case HAL_CAP_TPC_CTS:
    965 		setting += ahp->ah_txPowerIndexOffset;
    966 		if (setting > 63)
    967 			setting = 63;
    968 		if (type == HAL_CAP_TPC_ACK) {
    969 			ahp->ah_macTPC &= AR_TPC_ACK;
    970 			ahp->ah_macTPC |= MS(setting, AR_TPC_ACK);
    971 		} else {
    972 			ahp->ah_macTPC &= AR_TPC_CTS;
    973 			ahp->ah_macTPC |= MS(setting, AR_TPC_CTS);
    974 		}
    975 		OS_REG_WRITE(ah, AR_TPC, ahp->ah_macTPC);
    976 		return AH_TRUE;
    977 	case HAL_CAP_INTMIT: {		/* interference mitigation */
    978 		static const HAL_ANI_CMD cmds[] = {
    979 			HAL_ANI_PRESENT,
    980 			HAL_ANI_MODE,
    981 			HAL_ANI_NOISE_IMMUNITY_LEVEL,
    982 			HAL_ANI_OFDM_WEAK_SIGNAL_DETECTION,
    983 			HAL_ANI_CCK_WEAK_SIGNAL_THR,
    984 			HAL_ANI_FIRSTEP_LEVEL,
    985 			HAL_ANI_SPUR_IMMUNITY_LEVEL,
    986 		};
    987 		return capability < N(cmds) ?
    988 			ar5212AniControl(ah, cmds[capability], setting) :
    989 			AH_FALSE;
    990 	}
    991 	case HAL_CAP_TSF_ADJUST:	/* hardware has beacon tsf adjust */
    992 		if (pCap->halTsfAddSupport) {
    993 			if (setting)
    994 				ahp->ah_miscMode |= AR_MISC_MODE_TX_ADD_TSF;
    995 			else
    996 				ahp->ah_miscMode &= ~AR_MISC_MODE_TX_ADD_TSF;
    997 			return AH_TRUE;
    998 		}
    999 		/* fall thru... */
   1000 	default:
   1001 		return ath_hal_setcapability(ah, type, capability,
   1002 				setting, status);
   1003 	}
   1004 #undef N
   1005 }
   1006 
   1007 HAL_BOOL
   1008 ar5212GetDiagState(struct ath_hal *ah, int request,
   1009 	const void *args, uint32_t argsize,
   1010 	void **result, uint32_t *resultsize)
   1011 {
   1012 	struct ath_hal_5212 *ahp = AH5212(ah);
   1013 
   1014 	(void) ahp;
   1015 	if (ath_hal_getdiagstate(ah, request, args, argsize, result, resultsize))
   1016 		return AH_TRUE;
   1017 	switch (request) {
   1018 	case HAL_DIAG_EEPROM:
   1019 	case HAL_DIAG_EEPROM_EXP_11A:
   1020 	case HAL_DIAG_EEPROM_EXP_11B:
   1021 	case HAL_DIAG_EEPROM_EXP_11G:
   1022 	case HAL_DIAG_RFGAIN:
   1023 		return ath_hal_eepromDiag(ah, request,
   1024 		    args, argsize, result, resultsize);
   1025 	case HAL_DIAG_RFGAIN_CURSTEP:
   1026 		*result = __DECONST(void *, ahp->ah_gainValues.currStep);
   1027 		*resultsize = (*result == AH_NULL) ?
   1028 			0 : sizeof(GAIN_OPTIMIZATION_STEP);
   1029 		return AH_TRUE;
   1030 	case HAL_DIAG_PCDAC:
   1031 		*result = ahp->ah_pcdacTable;
   1032 		*resultsize = ahp->ah_pcdacTableSize;
   1033 		return AH_TRUE;
   1034 	case HAL_DIAG_TXRATES:
   1035 		*result = &ahp->ah_ratesArray[0];
   1036 		*resultsize = sizeof(ahp->ah_ratesArray);
   1037 		return AH_TRUE;
   1038 	case HAL_DIAG_ANI_CURRENT:
   1039 		*result = ar5212AniGetCurrentState(ah);
   1040 		*resultsize = (*result == AH_NULL) ?
   1041 			0 : sizeof(struct ar5212AniState);
   1042 		return AH_TRUE;
   1043 	case HAL_DIAG_ANI_STATS:
   1044 		*result = ar5212AniGetCurrentStats(ah);
   1045 		*resultsize = (*result == AH_NULL) ?
   1046 			0 : sizeof(struct ar5212Stats);
   1047 		return AH_TRUE;
   1048 	case HAL_DIAG_ANI_CMD:
   1049 		if (argsize != 2*sizeof(uint32_t))
   1050 			return AH_FALSE;
   1051 		ar5212AniControl(ah, ((const uint32_t *)args)[0],
   1052 			((const uint32_t *)args)[1]);
   1053 		return AH_TRUE;
   1054 	case HAL_DIAG_ANI_PARAMS:
   1055 		/*
   1056 		 * NB: We assume struct ar5212AniParams is identical
   1057 		 * to HAL_ANI_PARAMS; if they diverge then we'll need
   1058 		 * to handle it here
   1059 		 */
   1060 		if (argsize == 0 && args == AH_NULL) {
   1061 			struct ar5212AniState *aniState =
   1062 			    ar5212AniGetCurrentState(ah);
   1063 			if (aniState == AH_NULL)
   1064 				return AH_FALSE;
   1065 			*result = __DECONST(void *, aniState->params);
   1066 			*resultsize = sizeof(struct ar5212AniParams);
   1067 			return AH_TRUE;
   1068 		} else {
   1069 			if (argsize != sizeof(struct ar5212AniParams))
   1070 				return AH_FALSE;
   1071 			return ar5212AniSetParams(ah, args, args);
   1072 		}
   1073 	}
   1074 	return AH_FALSE;
   1075 }
   1076 
   1077 /*
   1078  * Check whether there's an in-progress NF completion.
   1079  *
   1080  * Returns AH_TRUE if there's a in-progress NF calibration, AH_FALSE
   1081  * otherwise.
   1082  */
   1083 HAL_BOOL
   1084 ar5212IsNFCalInProgress(struct ath_hal *ah)
   1085 {
   1086 	if (OS_REG_READ(ah, AR_PHY_AGC_CONTROL) & AR_PHY_AGC_CONTROL_NF)
   1087 		return AH_TRUE;
   1088 	return AH_FALSE;
   1089 }
   1090 
   1091 /*
   1092  * Wait for an in-progress NF calibration to complete.
   1093  *
   1094  * The completion function waits "i" times 10uS.
   1095  * It returns AH_TRUE if the NF calibration completed (or was never
   1096  * in progress); AH_FALSE if it was still in progress after "i" checks.
   1097  */
   1098 HAL_BOOL
   1099 ar5212WaitNFCalComplete(struct ath_hal *ah, int i)
   1100 {
   1101 	int j;
   1102 
   1103 	if (i <= 0)
   1104 		i = 1;	/* it should run at least once */
   1105 	for (j = 0; j < i; i++) {
   1106 		if (! ar5212IsNFCalInProgress(ah))
   1107 			return AH_TRUE;
   1108 		OS_DELAY(10);
   1109 	}
   1110 	return AH_FALSE;
   1111 }
   1112