1190747Snwhitehorn/* 2190747Snwhitehorn * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting 3190747Snwhitehorn * Copyright (c) 2002-2006 Atheros Communications, Inc. 4190747Snwhitehorn * 5190747Snwhitehorn * Permission to use, copy, modify, and/or distribute this software for any 6190747Snwhitehorn * purpose with or without fee is hereby granted, provided that the above 7190747Snwhitehorn * copyright notice and this permission notice appear in all copies. 8190747Snwhitehorn * 9190747Snwhitehorn * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10190747Snwhitehorn * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11190747Snwhitehorn * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12190747Snwhitehorn * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13190747Snwhitehorn * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14190747Snwhitehorn * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15190747Snwhitehorn * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16190747Snwhitehorn * 17190747Snwhitehorn * $FreeBSD$ 18190747Snwhitehorn */ 19190747Snwhitehorn#include "opt_ah.h" 20190747Snwhitehorn 21190747Snwhitehorn#include "ah.h" 22190747Snwhitehorn#include "ah_internal.h" 23190747Snwhitehorn 24190747Snwhitehorn#include "ar5211/ar5211.h" 25190747Snwhitehorn#include "ar5211/ar5211reg.h" 26190747Snwhitehorn#include "ar5211/ar5211phy.h" 27190747Snwhitehorn 28190747Snwhitehorn#include "ah_eeprom_v3.h" 29190747Snwhitehorn 30190747Snwhitehorn#define AR_NUM_GPIO 6 /* 6 GPIO bits */ 31190747Snwhitehorn#define AR_GPIOD_MASK 0x2f /* 6-bit mask */ 32190747Snwhitehorn 33190747Snwhitehornvoid 34190747Snwhitehornar5211GetMacAddress(struct ath_hal *ah, uint8_t *mac) 35190747Snwhitehorn{ 36190747Snwhitehorn struct ath_hal_5211 *ahp = AH5211(ah); 37190747Snwhitehorn 38190747Snwhitehorn OS_MEMCPY(mac, ahp->ah_macaddr, IEEE80211_ADDR_LEN); 39190747Snwhitehorn} 40190747Snwhitehorn 41190747SnwhitehornHAL_BOOL 42190747Snwhitehornar5211SetMacAddress(struct ath_hal *ah, const uint8_t *mac) 43190747Snwhitehorn{ 44190747Snwhitehorn struct ath_hal_5211 *ahp = AH5211(ah); 45190747Snwhitehorn 46190747Snwhitehorn OS_MEMCPY(ahp->ah_macaddr, mac, IEEE80211_ADDR_LEN); 47190747Snwhitehorn return AH_TRUE; 48190747Snwhitehorn} 49190747Snwhitehorn 50190747Snwhitehornvoid 51190747Snwhitehornar5211GetBssIdMask(struct ath_hal *ah, uint8_t *mask) 52190747Snwhitehorn{ 53190747Snwhitehorn static const uint8_t ones[IEEE80211_ADDR_LEN] = 54190747Snwhitehorn { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 55190747Snwhitehorn OS_MEMCPY(mask, ones, IEEE80211_ADDR_LEN); 56190747Snwhitehorn} 57190747Snwhitehorn 58190747SnwhitehornHAL_BOOL 59190747Snwhitehornar5211SetBssIdMask(struct ath_hal *ah, const uint8_t *mask) 60190747Snwhitehorn{ 61190747Snwhitehorn return AH_FALSE; 62190747Snwhitehorn} 63190747Snwhitehorn 64190747Snwhitehorn/* 65190747Snwhitehorn * Read 16 bits of data from the specified EEPROM offset. 66190747Snwhitehorn */ 67190747SnwhitehornHAL_BOOL 68209803Snwhitehornar5211EepromRead(struct ath_hal *ah, u_int off, uint16_t *data) 69190747Snwhitehorn{ 70190747Snwhitehorn OS_REG_WRITE(ah, AR_EEPROM_ADDR, off); 71190747Snwhitehorn OS_REG_WRITE(ah, AR_EEPROM_CMD, AR_EEPROM_CMD_READ); 72209803Snwhitehorn 73209803Snwhitehorn if (!ath_hal_wait(ah, AR_EEPROM_STS, 74190747Snwhitehorn AR_EEPROM_STS_READ_COMPLETE | AR_EEPROM_STS_READ_ERROR, 75209803Snwhitehorn AR_EEPROM_STS_READ_COMPLETE)) { 76190747Snwhitehorn HALDEBUG(ah, HAL_DEBUG_ANY, 77190747Snwhitehorn "%s: read failed for entry 0x%x\n", __func__, off); 78190747Snwhitehorn return AH_FALSE; 79190747Snwhitehorn } 80190747Snwhitehorn *data = OS_REG_READ(ah, AR_EEPROM_DATA) & 0xffff; 81208614Sraj return AH_TRUE; 82190747Snwhitehorn} 83190747Snwhitehorn 84190747Snwhitehorn#ifdef AH_SUPPORT_WRITE_EEPROM 85190747Snwhitehorn/* 86190747Snwhitehorn * Write 16 bits of data to the specified EEPROM offset. 87190747Snwhitehorn */ 88190747SnwhitehornHAL_BOOL 89190747Snwhitehornar5211EepromWrite(struct ath_hal *ah, u_int off, uint16_t data) 90190747Snwhitehorn{ 91190747Snwhitehorn return AH_FALSE; 92190747Snwhitehorn} 93194025Savg#endif /* AH_SUPPORT_WRITE_EEPROM */ 94194025Savg 95190747Snwhitehorn/* 96190747Snwhitehorn * Attempt to change the cards operating regulatory domain to the given value 97190747Snwhitehorn */ 98190747SnwhitehornHAL_BOOL 99190747Snwhitehornar5211SetRegulatoryDomain(struct ath_hal *ah, 100190747Snwhitehorn uint16_t regDomain, HAL_STATUS *status) 101190747Snwhitehorn{ 102209801Snwhitehorn HAL_STATUS ecode; 103209803Snwhitehorn 104209803Snwhitehorn if (AH_PRIVATE(ah)->ah_currentRD == regDomain) { 105190747Snwhitehorn ecode = HAL_EINVAL; 106190747Snwhitehorn goto bad; 107190747Snwhitehorn } 108190747Snwhitehorn /* 109190747Snwhitehorn * Check if EEPROM is configured to allow this; must 110190747Snwhitehorn * be a proper version and the protection bits must 111190747Snwhitehorn * permit re-writing that segment of the EEPROM. 112190747Snwhitehorn */ 113190747Snwhitehorn if (ath_hal_eepromGetFlag(ah, AR_EEP_WRITEPROTECT)) { 114190747Snwhitehorn ecode = HAL_EEWRITE; 115190747Snwhitehorn goto bad; 116190747Snwhitehorn } 117190747Snwhitehorn#ifdef AH_SUPPORT_WRITE_REGDOMAIN 118190747Snwhitehorn if (ar5211EepromWrite(ah, AR_EEPROM_REG_DOMAIN, regDomain)) { 119190747Snwhitehorn HALDEBUG(ah, HAL_DEBUG_ANY, 120190747Snwhitehorn "%s: set regulatory domain to %u (0x%x)\n", 121190747Snwhitehorn __func__, regDomain, regDomain); 122190747Snwhitehorn AH_PRIVATE(ah)->ah_currentRD = regDomain; 123190747Snwhitehorn return AH_TRUE; 124190747Snwhitehorn } 125190747Snwhitehorn#endif 126190747Snwhitehorn ecode = HAL_EIO; 127190747Snwhitehornbad: 128190747Snwhitehorn if (status) 129190747Snwhitehorn *status = ecode; 130190747Snwhitehorn return AH_FALSE; 131190747Snwhitehorn} 132190747Snwhitehorn 133209803Snwhitehorn/* 134190747Snwhitehorn * Return the wireless modes (a,b,g,t) supported by hardware. 135190747Snwhitehorn * 136190747Snwhitehorn * This value is what is actually supported by the hardware 137190747Snwhitehorn * and is unaffected by regulatory/country code settings. 138190747Snwhitehorn * 139190747Snwhitehorn */ 140190747Snwhitehornu_int 141190747Snwhitehornar5211GetWirelessModes(struct ath_hal *ah) 142190747Snwhitehorn{ 143190747Snwhitehorn u_int mode = 0; 144190747Snwhitehorn 145190747Snwhitehorn if (ath_hal_eepromGetFlag(ah, AR_EEP_AMODE)) { 146190747Snwhitehorn mode = HAL_MODE_11A; 147190747Snwhitehorn if (!ath_hal_eepromGetFlag(ah, AR_EEP_TURBO5DISABLE)) 148190747Snwhitehorn mode |= HAL_MODE_TURBO | HAL_MODE_108A; 149190747Snwhitehorn } 150190747Snwhitehorn if (ath_hal_eepromGetFlag(ah, AR_EEP_BMODE)) 151190747Snwhitehorn mode |= HAL_MODE_11B; 152190747Snwhitehorn return mode; 153190747Snwhitehorn} 154209803Snwhitehorn 155209803Snwhitehorn#if 0 156209803SnwhitehornHAL_BOOL 157209803Snwhitehornar5211GetTurboDisable(struct ath_hal *ah) 158209803Snwhitehorn{ 159209803Snwhitehorn return (AH5211(ah)->ah_turboDisable != 0); 160209803Snwhitehorn} 161190747Snwhitehorn#endif 162190747Snwhitehorn 163190747Snwhitehorn/* 164190747Snwhitehorn * Called if RfKill is supported (according to EEPROM). Set the interrupt and 165190747Snwhitehorn * GPIO values so the ISR and can disable RF on a switch signal 166190747Snwhitehorn */ 167190747Snwhitehornvoid 168190747Snwhitehornar5211EnableRfKill(struct ath_hal *ah) 169190747Snwhitehorn{ 170190747Snwhitehorn uint16_t rfsilent = AH_PRIVATE(ah)->ah_rfsilent; 171209803Snwhitehorn int select = MS(rfsilent, AR_EEPROM_RFSILENT_GPIO_SEL); 172209803Snwhitehorn int polarity = MS(rfsilent, AR_EEPROM_RFSILENT_POLARITY); 173209803Snwhitehorn 174190747Snwhitehorn /* 175190747Snwhitehorn * Configure the desired GPIO port for input 176190747Snwhitehorn * and enable baseband rf silence. 177190747Snwhitehorn */ 178190747Snwhitehorn ar5211GpioCfgInput(ah, select); 179190747Snwhitehorn OS_REG_SET_BIT(ah, AR_PHY_BASE, 0x00002000); 180209803Snwhitehorn /* 181190747Snwhitehorn * If radio disable switch connection to GPIO bit x is enabled 182190747Snwhitehorn * program GPIO interrupt. 183190747Snwhitehorn * If rfkill bit on eeprom is 1, setupeeprommap routine has already 184190747Snwhitehorn * verified that it is a later version of eeprom, it has a place for 185190747Snwhitehorn * rfkill bit and it is set to 1, indicating that GPIO bit x hardware 186190747Snwhitehorn * connection is present. 187190747Snwhitehorn */ 188190747Snwhitehorn ar5211GpioSetIntr(ah, select, (ar5211GpioGet(ah, select) != polarity)); 189190747Snwhitehorn} 190190747Snwhitehorn 191190747Snwhitehorn/* 192190747Snwhitehorn * Configure GPIO Output lines 193190747Snwhitehorn */ 194190747SnwhitehornHAL_BOOL 195190747Snwhitehornar5211GpioCfgOutput(struct ath_hal *ah, uint32_t gpio, HAL_GPIO_MUX_TYPE type) 196190747Snwhitehorn{ 197190747Snwhitehorn uint32_t reg; 198190747Snwhitehorn 199190747Snwhitehorn HALASSERT(gpio < AR_NUM_GPIO); 200190747Snwhitehorn 201190747Snwhitehorn reg = OS_REG_READ(ah, AR_GPIOCR); 202190747Snwhitehorn reg &= ~(AR_GPIOCR_0_CR_A << (gpio * AR_GPIOCR_CR_SHIFT)); 203190747Snwhitehorn reg |= AR_GPIOCR_0_CR_A << (gpio * AR_GPIOCR_CR_SHIFT); 204190747Snwhitehorn 205190747Snwhitehorn OS_REG_WRITE(ah, AR_GPIOCR, reg); 206190747Snwhitehorn return AH_TRUE; 207190747Snwhitehorn} 208190747Snwhitehorn 209190747Snwhitehorn/* 210190747Snwhitehorn * Configure GPIO Input lines 211190747Snwhitehorn */ 212190747SnwhitehornHAL_BOOL 213190747Snwhitehornar5211GpioCfgInput(struct ath_hal *ah, uint32_t gpio) 214190747Snwhitehorn{ 215209803Snwhitehorn uint32_t reg; 216190747Snwhitehorn 217190747Snwhitehorn HALASSERT(gpio < AR_NUM_GPIO); 218190747Snwhitehorn 219209803Snwhitehorn reg = OS_REG_READ(ah, AR_GPIOCR); 220209803Snwhitehorn reg &= ~(AR_GPIOCR_0_CR_A << (gpio * AR_GPIOCR_CR_SHIFT)); 221209803Snwhitehorn reg |= AR_GPIOCR_0_CR_N << (gpio * AR_GPIOCR_CR_SHIFT); 222209803Snwhitehorn 223209803Snwhitehorn OS_REG_WRITE(ah, AR_GPIOCR, reg); 224209803Snwhitehorn return AH_TRUE; 225209803Snwhitehorn} 226209803Snwhitehorn 227190747Snwhitehorn/* 228190747Snwhitehorn * Once configured for I/O - set output lines 229190747Snwhitehorn */ 230190747SnwhitehornHAL_BOOL 231190747Snwhitehornar5211GpioSet(struct ath_hal *ah, uint32_t gpio, uint32_t val) 232190747Snwhitehorn{ 233209803Snwhitehorn uint32_t reg; 234190747Snwhitehorn 235190747Snwhitehorn HALASSERT(gpio < AR_NUM_GPIO); 236190747Snwhitehorn 237190747Snwhitehorn reg = OS_REG_READ(ah, AR_GPIODO); 238190747Snwhitehorn reg &= ~(1 << gpio); 239209803Snwhitehorn reg |= (val&1) << gpio; 240209803Snwhitehorn 241209803Snwhitehorn OS_REG_WRITE(ah, AR_GPIODO, reg); 242209803Snwhitehorn return AH_TRUE; 243209803Snwhitehorn} 244190747Snwhitehorn 245209803Snwhitehorn/* 246190747Snwhitehorn * Once configured for I/O - get input lines 247190747Snwhitehorn */ 248190747Snwhitehornuint32_t 249190747Snwhitehornar5211GpioGet(struct ath_hal *ah, uint32_t gpio) 250190747Snwhitehorn{ 251209803Snwhitehorn if (gpio < AR_NUM_GPIO) { 252190747Snwhitehorn uint32_t val = OS_REG_READ(ah, AR_GPIODI); 253209803Snwhitehorn val = ((val & AR_GPIOD_MASK) >> gpio) & 0x1; 254209803Snwhitehorn return val; 255209803Snwhitehorn } else { 256190747Snwhitehorn return 0xffffffff; 257190747Snwhitehorn } 258190747Snwhitehorn} 259190747Snwhitehorn 260190747Snwhitehorn/* 261190747Snwhitehorn * Set the GPIO 0 Interrupt (gpio is ignored) 262209803Snwhitehorn */ 263190747Snwhitehornvoid 264190747Snwhitehornar5211GpioSetIntr(struct ath_hal *ah, u_int gpio, uint32_t ilevel) 265190747Snwhitehorn{ 266190747Snwhitehorn uint32_t val = OS_REG_READ(ah, AR_GPIOCR); 267190747Snwhitehorn 268190747Snwhitehorn /* Clear the bits that we will modify. */ 269190747Snwhitehorn val &= ~(AR_GPIOCR_INT_SEL0 | AR_GPIOCR_INT_SELH | AR_GPIOCR_INT_ENA | 270190747Snwhitehorn AR_GPIOCR_0_CR_A); 271190747Snwhitehorn 272190747Snwhitehorn val |= AR_GPIOCR_INT_SEL0 | AR_GPIOCR_INT_ENA; 273190747Snwhitehorn if (ilevel) 274209803Snwhitehorn val |= AR_GPIOCR_INT_SELH; 275190747Snwhitehorn 276190747Snwhitehorn /* Don't need to change anything for low level interrupt. */ 277190747Snwhitehorn OS_REG_WRITE(ah, AR_GPIOCR, val); 278190747Snwhitehorn 279190747Snwhitehorn /* Change the interrupt mask. */ 280190747Snwhitehorn ar5211SetInterrupts(ah, AH5211(ah)->ah_maskReg | HAL_INT_GPIO); 281190747Snwhitehorn} 282190747Snwhitehorn 283190747Snwhitehorn/* 284190747Snwhitehorn * Change the LED blinking pattern to correspond to the connectivity 285190747Snwhitehorn */ 286190747Snwhitehornvoid 287190747Snwhitehornar5211SetLedState(struct ath_hal *ah, HAL_LED_STATE state) 288190747Snwhitehorn{ 289190747Snwhitehorn static const uint32_t ledbits[8] = { 290208614Sraj AR_PCICFG_LEDCTL_NONE|AR_PCICFG_LEDMODE_PROP, /* HAL_LED_INIT */ 291190747Snwhitehorn AR_PCICFG_LEDCTL_PEND|AR_PCICFG_LEDMODE_PROP, /* HAL_LED_SCAN */ 292190747Snwhitehorn AR_PCICFG_LEDCTL_PEND|AR_PCICFG_LEDMODE_PROP, /* HAL_LED_AUTH */ 293190747Snwhitehorn AR_PCICFG_LEDCTL_ASSOC|AR_PCICFG_LEDMODE_PROP,/* HAL_LED_ASSOC*/ 294190747Snwhitehorn AR_PCICFG_LEDCTL_ASSOC|AR_PCICFG_LEDMODE_PROP,/* HAL_LED_RUN */ 295190747Snwhitehorn AR_PCICFG_LEDCTL_NONE|AR_PCICFG_LEDMODE_RAND, 296190747Snwhitehorn AR_PCICFG_LEDCTL_NONE|AR_PCICFG_LEDMODE_RAND, 297208614Sraj AR_PCICFG_LEDCTL_NONE|AR_PCICFG_LEDMODE_RAND, 298190747Snwhitehorn }; 299190747Snwhitehorn OS_REG_WRITE(ah, AR_PCICFG, 300190747Snwhitehorn (OS_REG_READ(ah, AR_PCICFG) &~ 301190747Snwhitehorn (AR_PCICFG_LEDCTL | AR_PCICFG_LEDMODE)) 302190747Snwhitehorn | ledbits[state & 0x7] 303190747Snwhitehorn ); 304190747Snwhitehorn} 305190747Snwhitehorn 306190747Snwhitehorn/* 307190747Snwhitehorn * Change association related fields programmed into the hardware. 308209803Snwhitehorn * Writing a valid BSSID to the hardware effectively enables the hardware 309205496Snwhitehorn * to synchronize its TSF to the correct beacons and receive frames coming 310190747Snwhitehorn * from that BSSID. It is called by the SME JOIN operation. 311190747Snwhitehorn */ 312190747Snwhitehornvoid 313190747Snwhitehornar5211WriteAssocid(struct ath_hal *ah, const uint8_t *bssid, uint16_t assocId) 314190747Snwhitehorn{ 315209803Snwhitehorn struct ath_hal_5211 *ahp = AH5211(ah); 316190747Snwhitehorn 317209803Snwhitehorn /* XXX save bssid for possible re-use on reset */ 318209803Snwhitehorn OS_MEMCPY(ahp->ah_bssid, bssid, IEEE80211_ADDR_LEN); 319209803Snwhitehorn OS_REG_WRITE(ah, AR_BSS_ID0, LE_READ_4(ahp->ah_bssid)); 320209803Snwhitehorn OS_REG_WRITE(ah, AR_BSS_ID1, LE_READ_2(ahp->ah_bssid+4) | 321190747Snwhitehorn ((assocId & 0x3fff)<<AR_BSS_ID1_AID_S)); 322190747Snwhitehorn} 323190747Snwhitehorn 324209803Snwhitehorn/* 325209803Snwhitehorn * Get the current hardware tsf for stamlme. 326190747Snwhitehorn */ 327190747Snwhitehornuint64_t 328190747Snwhitehornar5211GetTsf64(struct ath_hal *ah) 329209803Snwhitehorn{ 330190747Snwhitehorn uint32_t low1, low2, u32; 331190747Snwhitehorn 332190747Snwhitehorn /* sync multi-word read */ 333190747Snwhitehorn low1 = OS_REG_READ(ah, AR_TSF_L32); 334190747Snwhitehorn u32 = OS_REG_READ(ah, AR_TSF_U32); 335190747Snwhitehorn low2 = OS_REG_READ(ah, AR_TSF_L32); 336190747Snwhitehorn if (low2 < low1) { /* roll over */ 337190747Snwhitehorn /* 338190747Snwhitehorn * If we are not preempted this will work. If we are 339190747Snwhitehorn * then we re-reading AR_TSF_U32 does no good as the 340190747Snwhitehorn * low bits will be meaningless. Likewise reading 341190747Snwhitehorn * L32, U32, U32, then comparing the last two reads 342209803Snwhitehorn * to check for rollover doesn't help if preempted--so 343205496Snwhitehorn * we take this approach as it costs one less PCI 344190747Snwhitehorn * read which can be noticeable when doing things 345190747Snwhitehorn * like timestamping packets in monitor mode. 346190747Snwhitehorn */ 347190747Snwhitehorn u32++; 348190747Snwhitehorn } 349209803Snwhitehorn return (((uint64_t) u32) << 32) | ((uint64_t) low2); 350190747Snwhitehorn} 351209803Snwhitehorn 352209803Snwhitehorn/* 353209803Snwhitehorn * Get the current hardware tsf for stamlme. 354209803Snwhitehorn */ 355190747Snwhitehornuint32_t 356209803Snwhitehornar5211GetTsf32(struct ath_hal *ah) 357209803Snwhitehorn{ 358209803Snwhitehorn return OS_REG_READ(ah, AR_TSF_L32); 359209803Snwhitehorn} 360190747Snwhitehorn 361209803Snwhitehorn/* 362209803Snwhitehorn * Reset the current hardware tsf for stamlme 363209803Snwhitehorn */ 364190747Snwhitehornvoid 365190747Snwhitehornar5211ResetTsf(struct ath_hal *ah) 366190747Snwhitehorn{ 367190747Snwhitehorn uint32_t val = OS_REG_READ(ah, AR_BEACON); 368190747Snwhitehorn 369190747Snwhitehorn OS_REG_WRITE(ah, AR_BEACON, val | AR_BEACON_RESET_TSF); 370190747Snwhitehorn} 371209803Snwhitehorn 372205496Snwhitehorn/* 373190747Snwhitehorn * Grab a semi-random value from hardware registers - may not 374190747Snwhitehorn * change often 375190747Snwhitehorn */ 376190747Snwhitehornuint32_t 377190747Snwhitehornar5211GetRandomSeed(struct ath_hal *ah) 378209803Snwhitehorn{ 379190747Snwhitehorn uint32_t nf; 380209803Snwhitehorn 381209803Snwhitehorn nf = (OS_REG_READ(ah, AR_PHY(25)) >> 19) & 0x1ff; 382209803Snwhitehorn if (nf & 0x100) 383209803Snwhitehorn nf = 0 - ((nf ^ 0x1ff) + 1); 384190747Snwhitehorn return (OS_REG_READ(ah, AR_TSF_U32) ^ 385209803Snwhitehorn OS_REG_READ(ah, AR_TSF_L32) ^ nf); 386209803Snwhitehorn} 387209803Snwhitehorn 388209803Snwhitehorn/* 389190747Snwhitehorn * Detect if our card is present 390209803Snwhitehorn */ 391209803SnwhitehornHAL_BOOL 392209803Snwhitehornar5211DetectCardPresent(struct ath_hal *ah) 393190747Snwhitehorn{ 394190747Snwhitehorn uint16_t macVersion, macRev; 395190747Snwhitehorn uint32_t v; 396190747Snwhitehorn 397190747Snwhitehorn /* 398190747Snwhitehorn * Read the Silicon Revision register and compare that 399190747Snwhitehorn * to what we read at attach time. If the same, we say 400209803Snwhitehorn * a card/device is present. 401205496Snwhitehorn */ 402190747Snwhitehorn v = OS_REG_READ(ah, AR_SREV) & AR_SREV_ID_M; 403190747Snwhitehorn macVersion = v >> AR_SREV_ID_S; 404190747Snwhitehorn macRev = v & AR_SREV_REVISION_M; 405190747Snwhitehorn return (AH_PRIVATE(ah)->ah_macVersion == macVersion && 406190747Snwhitehorn AH_PRIVATE(ah)->ah_macRev == macRev); 407209803Snwhitehorn} 408190747Snwhitehorn 409209803Snwhitehorn/* 410209803Snwhitehorn * Update MIB Counters 411209803Snwhitehorn */ 412209803Snwhitehornvoid 413190747Snwhitehornar5211UpdateMibCounters(struct ath_hal *ah, HAL_MIB_STATS *stats) 414209803Snwhitehorn{ 415209803Snwhitehorn stats->ackrcv_bad += OS_REG_READ(ah, AR_ACK_FAIL); 416209803Snwhitehorn stats->rts_bad += OS_REG_READ(ah, AR_RTS_FAIL); 417209803Snwhitehorn stats->fcs_bad += OS_REG_READ(ah, AR_FCS_FAIL); 418190747Snwhitehorn stats->rts_good += OS_REG_READ(ah, AR_RTS_OK); 419209803Snwhitehorn stats->beacons += OS_REG_READ(ah, AR_BEACON_CNT); 420209803Snwhitehorn} 421209803Snwhitehorn 422190747SnwhitehornHAL_BOOL 423190747Snwhitehornar5211SetSifsTime(struct ath_hal *ah, u_int us) 424190747Snwhitehorn{ 425190747Snwhitehorn struct ath_hal_5211 *ahp = AH5211(ah); 426190747Snwhitehorn 427190747Snwhitehorn if (us > ath_hal_mac_usec(ah, 0xffff)) { 428190747Snwhitehorn HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad SIFS time %u\n", 429209803Snwhitehorn __func__, us); 430205496Snwhitehorn ahp->ah_sifstime = (u_int) -1; /* restore default handling */ 431190747Snwhitehorn return AH_FALSE; 432190747Snwhitehorn } else { 433190747Snwhitehorn /* convert to system clocks */ 434190747Snwhitehorn OS_REG_WRITE(ah, AR_D_GBL_IFS_SIFS, ath_hal_mac_clks(ah, us)); 435190747Snwhitehorn ahp->ah_slottime = us; 436209803Snwhitehorn return AH_TRUE; 437190747Snwhitehorn } 438209803Snwhitehorn} 439209803Snwhitehorn 440209803Snwhitehornu_int 441209803Snwhitehornar5211GetSifsTime(struct ath_hal *ah) 442190747Snwhitehorn{ 443209803Snwhitehorn u_int clks = OS_REG_READ(ah, AR_D_GBL_IFS_SIFS) & 0xffff; 444209803Snwhitehorn return ath_hal_mac_usec(ah, clks); /* convert from system clocks */ 445209803Snwhitehorn} 446209803Snwhitehorn 447190747SnwhitehornHAL_BOOL 448209803Snwhitehornar5211SetSlotTime(struct ath_hal *ah, u_int us) 449209803Snwhitehorn{ 450209803Snwhitehorn struct ath_hal_5211 *ahp = AH5211(ah); 451190747Snwhitehorn 452190747Snwhitehorn if (us < HAL_SLOT_TIME_9 || us > ath_hal_mac_usec(ah, 0xffff)) { 453190747Snwhitehorn HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad slot time %u\n", 454190747Snwhitehorn __func__, us); 455190747Snwhitehorn ahp->ah_slottime = us; /* restore default handling */ 456190747Snwhitehorn return AH_FALSE; 457190747Snwhitehorn } else { 458209803Snwhitehorn /* convert to system clocks */ 459205496Snwhitehorn OS_REG_WRITE(ah, AR_D_GBL_IFS_SLOT, ath_hal_mac_clks(ah, us)); 460190747Snwhitehorn ahp->ah_slottime = us; 461190747Snwhitehorn return AH_TRUE; 462190747Snwhitehorn } 463190747Snwhitehorn} 464190747Snwhitehorn 465209803Snwhitehornu_int 466209803Snwhitehornar5211GetSlotTime(struct ath_hal *ah) 467190747Snwhitehorn{ 468209803Snwhitehorn u_int clks = OS_REG_READ(ah, AR_D_GBL_IFS_SLOT) & 0xffff; 469209803Snwhitehorn return ath_hal_mac_usec(ah, clks); /* convert from system clocks */ 470209803Snwhitehorn} 471209803Snwhitehorn 472190747SnwhitehornHAL_BOOL 473190747Snwhitehornar5211SetAckTimeout(struct ath_hal *ah, u_int us) 474190747Snwhitehorn{ 475190747Snwhitehorn struct ath_hal_5211 *ahp = AH5211(ah); 476209803Snwhitehorn 477209803Snwhitehorn if (us > ath_hal_mac_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) { 478190747Snwhitehorn HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad ack timeout %u\n", 479190747Snwhitehorn __func__, us); 480190747Snwhitehorn ahp->ah_acktimeout = (u_int) -1; /* restore default handling */ 481209803Snwhitehorn return AH_FALSE; 482190747Snwhitehorn } else { 483190747Snwhitehorn /* convert to system clocks */ 484190747Snwhitehorn OS_REG_RMW_FIELD(ah, AR_TIME_OUT, 485190747Snwhitehorn AR_TIME_OUT_ACK, ath_hal_mac_clks(ah, us)); 486190747Snwhitehorn ahp->ah_acktimeout = us; 487190747Snwhitehorn return AH_TRUE; 488190747Snwhitehorn } 489190747Snwhitehorn} 490190747Snwhitehorn 491209803Snwhitehornu_int 492205496Snwhitehornar5211GetAckTimeout(struct ath_hal *ah) 493190747Snwhitehorn{ 494190747Snwhitehorn u_int clks = MS(OS_REG_READ(ah, AR_TIME_OUT), AR_TIME_OUT_ACK); 495190747Snwhitehorn return ath_hal_mac_usec(ah, clks); /* convert from system clocks */ 496190747Snwhitehorn} 497190747Snwhitehorn 498190747Snwhitehornu_int 499190747Snwhitehornar5211GetAckCTSRate(struct ath_hal *ah) 500209803Snwhitehorn{ 501209803Snwhitehorn return ((AH5211(ah)->ah_staId1Defaults & AR_STA_ID1_ACKCTS_6MB) == 0); 502190747Snwhitehorn} 503209803Snwhitehorn 504209803SnwhitehornHAL_BOOL 505209803Snwhitehornar5211SetAckCTSRate(struct ath_hal *ah, u_int high) 506209803Snwhitehorn{ 507190747Snwhitehorn struct ath_hal_5211 *ahp = AH5211(ah); 508190747Snwhitehorn 509190747Snwhitehorn if (high) { 510190747Snwhitehorn OS_REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_ACKCTS_6MB); 511190747Snwhitehorn ahp->ah_staId1Defaults &= ~AR_STA_ID1_ACKCTS_6MB; 512190747Snwhitehorn } else { 513209803Snwhitehorn OS_REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_ACKCTS_6MB); 514209803Snwhitehorn ahp->ah_staId1Defaults |= AR_STA_ID1_ACKCTS_6MB; 515209803Snwhitehorn } 516190747Snwhitehorn return AH_TRUE; 517190747Snwhitehorn} 518190747Snwhitehorn 519209803SnwhitehornHAL_BOOL 520190747Snwhitehornar5211SetCTSTimeout(struct ath_hal *ah, u_int us) 521190747Snwhitehorn{ 522190747Snwhitehorn struct ath_hal_5211 *ahp = AH5211(ah); 523190747Snwhitehorn 524190747Snwhitehorn if (us > ath_hal_mac_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) { 525190747Snwhitehorn HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad cts timeout %u\n", 526190747Snwhitehorn __func__, us); 527190747Snwhitehorn ahp->ah_ctstimeout = (u_int) -1; /* restore default handling */ 528190747Snwhitehorn return AH_FALSE; 529190747Snwhitehorn } else { 530190747Snwhitehorn /* convert to system clocks */ 531209803Snwhitehorn OS_REG_RMW_FIELD(ah, AR_TIME_OUT, 532205496Snwhitehorn AR_TIME_OUT_CTS, ath_hal_mac_clks(ah, us)); 533190747Snwhitehorn ahp->ah_ctstimeout = us; 534190747Snwhitehorn return AH_TRUE; 535190747Snwhitehorn } 536190747Snwhitehorn} 537190747Snwhitehorn 538190747Snwhitehornu_int 539190747Snwhitehornar5211GetCTSTimeout(struct ath_hal *ah) 540209803Snwhitehorn{ 541190747Snwhitehorn u_int clks = MS(OS_REG_READ(ah, AR_TIME_OUT), AR_TIME_OUT_CTS); 542209803Snwhitehorn return ath_hal_mac_usec(ah, clks); /* convert from system clocks */ 543209803Snwhitehorn} 544209803Snwhitehorn 545209803SnwhitehornHAL_BOOL 546190747Snwhitehornar5211SetDecompMask(struct ath_hal *ah, uint16_t keyidx, int en) 547190747Snwhitehorn{ 548190747Snwhitehorn /* nothing to do */ 549190747Snwhitehorn return AH_TRUE; 550190747Snwhitehorn} 551209803Snwhitehorn 552209803Snwhitehornvoid 553209803Snwhitehornar5211SetCoverageClass(struct ath_hal *ah, uint8_t coverageclass, int now) 554190747Snwhitehorn{ 555190747Snwhitehorn} 556190747Snwhitehorn 557209803Snwhitehorn/* 558190747Snwhitehorn * Control Adaptive Noise Immunity Parameters 559190747Snwhitehorn */ 560190747SnwhitehornHAL_BOOL 561190747Snwhitehornar5211AniControl(struct ath_hal *ah, HAL_ANI_CMD cmd, int param) 562190747Snwhitehorn{ 563190747Snwhitehorn return AH_FALSE; 564190747Snwhitehorn} 565190747Snwhitehorn 566190747Snwhitehornvoid 567194025Savgar5211AniPoll(struct ath_hal *ah, const struct ieee80211_channel *chan) 568194025Savg{ 569190747Snwhitehorn} 570209803Snwhitehorn 571205496Snwhitehornvoid 572190747Snwhitehornar5211RxMonitor(struct ath_hal *ah, const HAL_NODE_STATS *stats, 573190747Snwhitehorn const struct ieee80211_channel *chan) 574190747Snwhitehorn{ 575190747Snwhitehorn} 576190747Snwhitehorn 577190747Snwhitehornvoid 578190747Snwhitehornar5211MibEvent(struct ath_hal *ah, const HAL_NODE_STATS *stats) 579190747Snwhitehorn{ 580209803Snwhitehorn} 581190747Snwhitehorn 582209803Snwhitehorn/* 583209803Snwhitehorn * Get the rssi of frame curently being received. 584209803Snwhitehorn */ 585209803Snwhitehornuint32_t 586190747Snwhitehornar5211GetCurRssi(struct ath_hal *ah) 587190747Snwhitehorn{ 588190747Snwhitehorn return (OS_REG_READ(ah, AR_PHY_CURRENT_RSSI) & 0xff); 589190747Snwhitehorn} 590190747Snwhitehorn 591190747Snwhitehornu_int 592209803Snwhitehornar5211GetDefAntenna(struct ath_hal *ah) 593209803Snwhitehorn{ 594209803Snwhitehorn return (OS_REG_READ(ah, AR_DEF_ANTENNA) & 0x7); 595190747Snwhitehorn} 596190747Snwhitehorn 597190747Snwhitehornvoid 598209803Snwhitehornar5211SetDefAntenna(struct ath_hal *ah, u_int antenna) 599190747Snwhitehorn{ 600190747Snwhitehorn OS_REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7)); 601190747Snwhitehorn} 602190747Snwhitehorn 603190747SnwhitehornHAL_ANT_SETTING 604190747Snwhitehornar5211GetAntennaSwitch(struct ath_hal *ah) 605190747Snwhitehorn{ 606190747Snwhitehorn return AH5211(ah)->ah_diversityControl; 607209803Snwhitehorn} 608205496Snwhitehorn 609190747SnwhitehornHAL_BOOL 610190747Snwhitehornar5211SetAntennaSwitch(struct ath_hal *ah, HAL_ANT_SETTING settings) 611190747Snwhitehorn{ 612190747Snwhitehorn const struct ieee80211_channel *chan = AH_PRIVATE(ah)->ah_curchan; 613190747Snwhitehorn 614190747Snwhitehorn if (chan == AH_NULL) { 615209803Snwhitehorn AH5211(ah)->ah_diversityControl = settings; 616209803Snwhitehorn return AH_TRUE; 617190747Snwhitehorn } 618209803Snwhitehorn return ar5211SetAntennaSwitchInternal(ah, settings, chan); 619209803Snwhitehorn} 620209803Snwhitehorn 621209803SnwhitehornHAL_STATUS 622190747Snwhitehornar5211GetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type, 623190747Snwhitehorn uint32_t capability, uint32_t *result) 624190747Snwhitehorn{ 625190747Snwhitehorn 626190747Snwhitehorn switch (type) { 627209803Snwhitehorn case HAL_CAP_CIPHER: /* cipher handled in hardware */ 628209803Snwhitehorn switch (capability) { 629209803Snwhitehorn case HAL_CIPHER_AES_OCB: 630190747Snwhitehorn case HAL_CIPHER_WEP: 631190747Snwhitehorn case HAL_CIPHER_CLR: 632190747Snwhitehorn return HAL_OK; 633209803Snwhitehorn default: 634190747Snwhitehorn return HAL_ENOTSUPP; 635190747Snwhitehorn } 636190747Snwhitehorn default: 637190747Snwhitehorn return ath_hal_getcapability(ah, type, capability, result); 638190747Snwhitehorn } 639190747Snwhitehorn} 640190747Snwhitehorn 641190747SnwhitehornHAL_BOOL 642190747Snwhitehornar5211SetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type, 643190747Snwhitehorn uint32_t capability, uint32_t setting, HAL_STATUS *status) 644209803Snwhitehorn{ 645205496Snwhitehorn switch (type) { 646190747Snwhitehorn case HAL_CAP_DIAG: /* hardware diagnostic support */ 647190747Snwhitehorn /* 648190747Snwhitehorn * NB: could split this up into virtual capabilities, 649190747Snwhitehorn * (e.g. 1 => ACK, 2 => CTS, etc.) but it hardly 650190747Snwhitehorn * seems worth the additional complexity. 651209803Snwhitehorn */ 652190747Snwhitehorn#ifdef AH_DEBUG 653209803Snwhitehorn AH_PRIVATE(ah)->ah_diagreg = setting; 654209803Snwhitehorn#else 655209803Snwhitehorn AH_PRIVATE(ah)->ah_diagreg = setting & 0x6; /* ACK+CTS */ 656209803Snwhitehorn#endif 657190747Snwhitehorn OS_REG_WRITE(ah, AR_DIAG_SW, AH_PRIVATE(ah)->ah_diagreg); 658190747Snwhitehorn return AH_TRUE; 659190747Snwhitehorn default: 660209803Snwhitehorn return ath_hal_setcapability(ah, type, capability, 661209803Snwhitehorn setting, status); 662209803Snwhitehorn } 663190747Snwhitehorn} 664190747Snwhitehorn 665190747SnwhitehornHAL_BOOL 666209803Snwhitehornar5211GetDiagState(struct ath_hal *ah, int request, 667190747Snwhitehorn const void *args, uint32_t argsize, 668190747Snwhitehorn void **result, uint32_t *resultsize) 669190747Snwhitehorn{ 670190747Snwhitehorn struct ath_hal_5211 *ahp = AH5211(ah); 671190747Snwhitehorn 672190747Snwhitehorn (void) ahp; 673190747Snwhitehorn if (ath_hal_getdiagstate(ah, request, args, argsize, result, resultsize)) 674190747Snwhitehorn return AH_TRUE; 675209803Snwhitehorn switch (request) { 676205496Snwhitehorn case HAL_DIAG_EEPROM: 677190747Snwhitehorn return ath_hal_eepromDiag(ah, request, 678190747Snwhitehorn args, argsize, result, resultsize); 679190747Snwhitehorn case HAL_DIAG_RFGAIN: 680190747Snwhitehorn *result = &ahp->ah_gainValues; 681190747Snwhitehorn *resultsize = sizeof(GAIN_VALUES); 682190747Snwhitehorn return AH_TRUE; 683209803Snwhitehorn case HAL_DIAG_RFGAIN_CURSTEP: 684209803Snwhitehorn *result = __DECONST(void *, ahp->ah_gainValues.currStep); 685190747Snwhitehorn *resultsize = (*result == AH_NULL) ? 686209803Snwhitehorn 0 : sizeof(GAIN_OPTIMIZATION_STEP); 687209803Snwhitehorn return AH_TRUE; 688209803Snwhitehorn } 689209803Snwhitehorn return AH_FALSE; 690190747Snwhitehorn} 691190747Snwhitehorn