ar5210_misc.c revision 217684
1132718Skan/* 2132718Skan * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting 3132718Skan * Copyright (c) 2002-2004 Atheros Communications, Inc. 4169689Skan * 5132718Skan * Permission to use, copy, modify, and/or distribute this software for any 6132718Skan * purpose with or without fee is hereby granted, provided that the above 7132718Skan * copyright notice and this permission notice appear in all copies. 8132718Skan * 9132718Skan * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10132718Skan * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11132718Skan * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12132718Skan * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13132718Skan * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14132718Skan * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15132718Skan * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16132718Skan * 17132718Skan * $FreeBSD: head/sys/dev/ath/ath_hal/ar5210/ar5210_misc.c 217684 2011-01-21 05:21:00Z adrian $ 18132718Skan */ 19132718Skan#include "opt_ah.h" 20132718Skan 21169689Skan#include "ah.h" 22169689Skan#include "ah_internal.h" 23132718Skan 24132718Skan#include "ar5210/ar5210.h" 25132718Skan#include "ar5210/ar5210reg.h" 26132718Skan#include "ar5210/ar5210phy.h" 27132718Skan 28169689Skan#include "ah_eeprom_v1.h" 29132718Skan 30132718Skan#define AR_NUM_GPIO 6 /* 6 GPIO bits */ 31132718Skan#define AR_GPIOD_MASK 0x2f /* 6-bit mask */ 32132718Skan 33169689Skanvoid 34169689Skanar5210GetMacAddress(struct ath_hal *ah, uint8_t *mac) 35132718Skan{ 36132718Skan struct ath_hal_5210 *ahp = AH5210(ah); 37132718Skan 38132718Skan OS_MEMCPY(mac, ahp->ah_macaddr, IEEE80211_ADDR_LEN); 39132718Skan} 40132718Skan 41169689SkanHAL_BOOL 42132718Skanar5210SetMacAddress(struct ath_hal *ah, const uint8_t *mac) 43132718Skan{ 44132718Skan struct ath_hal_5210 *ahp = AH5210(ah); 45132718Skan 46132718Skan OS_MEMCPY(ahp->ah_macaddr, mac, IEEE80211_ADDR_LEN); 47132718Skan return AH_TRUE; 48132718Skan} 49132718Skan 50132718Skanvoid 51132718Skanar5210GetBssIdMask(struct ath_hal *ah, uint8_t *mask) 52132718Skan{ 53132718Skan static const uint8_t ones[IEEE80211_ADDR_LEN] = 54132718Skan { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 55132718Skan OS_MEMCPY(mask, ones, IEEE80211_ADDR_LEN); 56132718Skan} 57132718Skan 58132718SkanHAL_BOOL 59132718Skanar5210SetBssIdMask(struct ath_hal *ah, const uint8_t *mask) 60132718Skan{ 61132718Skan return AH_FALSE; 62132718Skan} 63132718Skan 64132718Skan/* 65132718Skan * Read 16 bits of data from the specified EEPROM offset. 66132718Skan */ 67132718SkanHAL_BOOL 68132718Skanar5210EepromRead(struct ath_hal *ah, u_int off, uint16_t *data) 69132718Skan{ 70132718Skan (void) OS_REG_READ(ah, AR_EP_AIR(off)); /* activate read op */ 71132718Skan if (!ath_hal_wait(ah, AR_EP_STA, 72132718Skan AR_EP_STA_RDCMPLT | AR_EP_STA_RDERR, AR_EP_STA_RDCMPLT)) { 73132718Skan HALDEBUG(ah, HAL_DEBUG_ANY, "%s: read failed for entry 0x%x\n", 74132718Skan __func__, AR_EP_AIR(off)); 75132718Skan return AH_FALSE; 76132718Skan } 77132718Skan *data = OS_REG_READ(ah, AR_EP_RDATA) & 0xffff; 78132718Skan return AH_TRUE; 79132718Skan} 80132718Skan 81132718Skan#ifdef AH_SUPPORT_WRITE_EEPROM 82132718Skan/* 83132718Skan * Write 16 bits of data to the specified EEPROM offset. 84132718Skan */ 85132718SkanHAL_BOOL 86132718Skanar5210EepromWrite(struct ath_hal *ah, u_int off, uint16_t data) 87132718Skan{ 88132718Skan return AH_FALSE; 89132718Skan} 90132718Skan#endif /* AH_SUPPORT_WRITE_EEPROM */ 91132718Skan 92132718Skan/* 93132718Skan * Attempt to change the cards operating regulatory domain to the given value 94132718Skan */ 95132718SkanHAL_BOOL 96132718Skanar5210SetRegulatoryDomain(struct ath_hal *ah, 97132718Skan uint16_t regDomain, HAL_STATUS *status) 98132718Skan{ 99132718Skan HAL_STATUS ecode; 100132718Skan 101132718Skan if (AH_PRIVATE(ah)->ah_currentRD == regDomain) { 102132718Skan ecode = HAL_EINVAL; 103132718Skan goto bad; 104132718Skan } 105132718Skan /* 106132718Skan * Check if EEPROM is configured to allow this; must 107132718Skan * be a proper version and the protection bits must 108132718Skan * permit re-writing that segment of the EEPROM. 109132718Skan */ 110132718Skan if (ath_hal_eepromGetFlag(ah, AR_EEP_WRITEPROTECT)) { 111132718Skan ecode = HAL_EEWRITE; 112132718Skan goto bad; 113132718Skan } 114132718Skan ecode = HAL_EIO; /* disallow all writes */ 115132718Skanbad: 116132718Skan if (status) 117132718Skan *status = ecode; 118132718Skan return AH_FALSE; 119132718Skan} 120132718Skan 121132718Skan/* 122132718Skan * Return the wireless modes (a,b,g,t) supported by hardware. 123132718Skan * 124132718Skan * This value is what is actually supported by the hardware 125132718Skan * and is unaffected by regulatory/country code settings. 126132718Skan * 127132718Skan */ 128132718Skanu_int 129132718Skanar5210GetWirelessModes(struct ath_hal *ah) 130132718Skan{ 131132718Skan /* XXX could enable turbo mode but can't do all rates */ 132132718Skan return HAL_MODE_11A; 133132718Skan} 134132718Skan 135169689Skan/* 136132718Skan * Called if RfKill is supported (according to EEPROM). Set the interrupt and 137132718Skan * GPIO values so the ISR and can disable RF on a switch signal 138132718Skan */ 139132718Skanvoid 140169689Skanar5210EnableRfKill(struct ath_hal *ah) 141169689Skan{ 142169689Skan uint16_t rfsilent = AH_PRIVATE(ah)->ah_rfsilent; 143169689Skan int select = MS(rfsilent, AR_EEPROM_RFSILENT_GPIO_SEL); 144132718Skan int polarity = MS(rfsilent, AR_EEPROM_RFSILENT_POLARITY); 145169689Skan 146132718Skan /* 147132718Skan * If radio disable switch connection to GPIO bit 0 is enabled 148132718Skan * program GPIO interrupt. 149132718Skan * If rfkill bit on eeprom is 1, setupeeprommap routine has already 150132718Skan * verified that it is a later version of eeprom, it has a place for 151132718Skan * rfkill bit and it is set to 1, indicating that GPIO bit 0 hardware 152132718Skan * connection is present. 153132718Skan */ 154132718Skan ar5210Gpio0SetIntr(ah, select, (ar5210GpioGet(ah, select) == polarity)); 155132718Skan} 156132718Skan 157132718Skan/* 158132718Skan * Configure GPIO Output lines 159132718Skan */ 160132718SkanHAL_BOOL 161132718Skanar5210GpioCfgOutput(struct ath_hal *ah, uint32_t gpio, HAL_GPIO_MUX_TYPE type) 162132718Skan{ 163132718Skan HALASSERT(gpio < AR_NUM_GPIO); 164132718Skan 165132718Skan OS_REG_WRITE(ah, AR_GPIOCR, 166132718Skan (OS_REG_READ(ah, AR_GPIOCR) &~ AR_GPIOCR_ALL(gpio)) 167132718Skan | AR_GPIOCR_OUT1(gpio)); 168132718Skan 169132718Skan return AH_TRUE; 170132718Skan} 171132718Skan 172132718Skan/* 173132718Skan * Configure GPIO Input lines 174132718Skan */ 175132718SkanHAL_BOOL 176132718Skanar5210GpioCfgInput(struct ath_hal *ah, uint32_t gpio) 177132718Skan{ 178132718Skan HALASSERT(gpio < AR_NUM_GPIO); 179132718Skan 180132718Skan OS_REG_WRITE(ah, AR_GPIOCR, 181132718Skan (OS_REG_READ(ah, AR_GPIOCR) &~ AR_GPIOCR_ALL(gpio)) 182132718Skan | AR_GPIOCR_IN(gpio)); 183132718Skan 184132718Skan return AH_TRUE; 185132718Skan} 186132718Skan 187132718Skan/* 188132718Skan * Once configured for I/O - set output lines 189132718Skan */ 190132718SkanHAL_BOOL 191132718Skanar5210GpioSet(struct ath_hal *ah, uint32_t gpio, uint32_t val) 192132718Skan{ 193132718Skan uint32_t reg; 194132718Skan 195132718Skan HALASSERT(gpio < AR_NUM_GPIO); 196132718Skan 197132718Skan reg = OS_REG_READ(ah, AR_GPIODO); 198132718Skan reg &= ~(1 << gpio); 199132718Skan reg |= (val&1) << gpio; 200132718Skan 201169689Skan OS_REG_WRITE(ah, AR_GPIODO, reg); 202132718Skan return AH_TRUE; 203132718Skan} 204132718Skan 205132718Skan/* 206132718Skan * Once configured for I/O - get input lines 207132718Skan */ 208132718Skanuint32_t 209132718Skanar5210GpioGet(struct ath_hal *ah, uint32_t gpio) 210132718Skan{ 211132718Skan if (gpio < AR_NUM_GPIO) { 212132718Skan uint32_t val = OS_REG_READ(ah, AR_GPIODI); 213132718Skan val = ((val & AR_GPIOD_MASK) >> gpio) & 0x1; 214132718Skan return val; 215132718Skan } else { 216132718Skan return 0xffffffff; 217132718Skan } 218132718Skan} 219132718Skan 220169689Skan/* 221169689Skan * Set the GPIO 0 Interrupt 222169689Skan */ 223169689Skanvoid 224169689Skanar5210Gpio0SetIntr(struct ath_hal *ah, u_int gpio, uint32_t ilevel) 225169689Skan{ 226132718Skan uint32_t val = OS_REG_READ(ah, AR_GPIOCR); 227132718Skan 228132718Skan /* Clear the bits that we will modify. */ 229132718Skan val &= ~(AR_GPIOCR_INT_SEL(gpio) | AR_GPIOCR_INT_SELH | AR_GPIOCR_INT_ENA | 230132718Skan AR_GPIOCR_ALL(gpio)); 231132718Skan 232132718Skan val |= AR_GPIOCR_INT_SEL(gpio) | AR_GPIOCR_INT_ENA; 233132718Skan if (ilevel) 234132718Skan val |= AR_GPIOCR_INT_SELH; 235132718Skan 236132718Skan /* Don't need to change anything for low level interrupt. */ 237132718Skan OS_REG_WRITE(ah, AR_GPIOCR, val); 238132718Skan 239132718Skan /* Change the interrupt mask. */ 240132718Skan ar5210SetInterrupts(ah, AH5210(ah)->ah_maskReg | HAL_INT_GPIO); 241169689Skan} 242132718Skan 243132718Skan/* 244132718Skan * Change the LED blinking pattern to correspond to the connectivity 245132718Skan */ 246132718Skanvoid 247132718Skanar5210SetLedState(struct ath_hal *ah, HAL_LED_STATE state) 248132718Skan{ 249132718Skan uint32_t val; 250132718Skan 251132718Skan val = OS_REG_READ(ah, AR_PCICFG); 252132718Skan switch (state) { 253132718Skan case HAL_LED_INIT: 254132718Skan val &= ~(AR_PCICFG_LED_PEND | AR_PCICFG_LED_ACT); 255132718Skan break; 256132718Skan case HAL_LED_RUN: 257132718Skan /* normal blink when connected */ 258132718Skan val &= ~AR_PCICFG_LED_PEND; 259132718Skan val |= AR_PCICFG_LED_ACT; 260132718Skan break; 261132718Skan default: 262132718Skan val |= AR_PCICFG_LED_PEND; 263132718Skan val &= ~AR_PCICFG_LED_ACT; 264132718Skan break; 265132718Skan } 266132718Skan OS_REG_WRITE(ah, AR_PCICFG, val); 267132718Skan} 268132718Skan 269132718Skan/* 270132718Skan * Return 1 or 2 for the corresponding antenna that is in use 271132718Skan */ 272132718Skanu_int 273132718Skanar5210GetDefAntenna(struct ath_hal *ah) 274132718Skan{ 275169689Skan uint32_t val = OS_REG_READ(ah, AR_STA_ID1); 276132718Skan return (val & AR_STA_ID1_DEFAULT_ANTENNA ? 2 : 1); 277132718Skan} 278132718Skan 279132718Skanvoid 280132718Skanar5210SetDefAntenna(struct ath_hal *ah, u_int antenna) 281132718Skan{ 282132718Skan uint32_t val = OS_REG_READ(ah, AR_STA_ID1); 283132718Skan 284132718Skan if (antenna != (val & AR_STA_ID1_DEFAULT_ANTENNA ? 2 : 1)) { 285169689Skan /* 286169689Skan * Antenna change requested, force a toggle of the default. 287169689Skan */ 288169689Skan OS_REG_WRITE(ah, AR_STA_ID1, val | AR_STA_ID1_DEFAULT_ANTENNA); 289169689Skan } 290169689Skan} 291169689Skan 292169689SkanHAL_ANT_SETTING 293132718Skanar5210GetAntennaSwitch(struct ath_hal *ah) 294132718Skan{ 295132718Skan return HAL_ANT_VARIABLE; 296132718Skan} 297132718Skan 298132718SkanHAL_BOOL 299132718Skanar5210SetAntennaSwitch(struct ath_hal *ah, HAL_ANT_SETTING settings) 300132718Skan{ 301169689Skan /* XXX not sure how to fix antenna */ 302169689Skan return (settings == HAL_ANT_VARIABLE); 303169689Skan} 304169689Skan 305169689Skan/* 306169689Skan * Change association related fields programmed into the hardware. 307132718Skan * Writing a valid BSSID to the hardware effectively enables the hardware 308132718Skan * to synchronize its TSF to the correct beacons and receive frames coming 309132718Skan * from that BSSID. It is called by the SME JOIN operation. 310132718Skan */ 311132718Skanvoid 312169689Skanar5210WriteAssocid(struct ath_hal *ah, const uint8_t *bssid, uint16_t assocId) 313169689Skan{ 314169689Skan struct ath_hal_5210 *ahp = AH5210(ah); 315169689Skan 316169689Skan /* XXX save bssid for possible re-use on reset */ 317169689Skan OS_MEMCPY(ahp->ah_bssid, bssid, IEEE80211_ADDR_LEN); 318169689Skan OS_REG_WRITE(ah, AR_BSS_ID0, LE_READ_4(ahp->ah_bssid)); 319169689Skan OS_REG_WRITE(ah, AR_BSS_ID1, LE_READ_2(ahp->ah_bssid+4) | 320169689Skan ((assocId & 0x3fff)<<AR_BSS_ID1_AID_S)); 321169689Skan if (assocId == 0) 322169689Skan OS_REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_NO_PSPOLL); 323169689Skan else 324169689Skan OS_REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_NO_PSPOLL); 325169689Skan} 326169689Skan 327169689Skan/* 328169689Skan * Get the current hardware tsf for stamlme. 329169689Skan */ 330169689Skanuint64_t 331169689Skanar5210GetTsf64(struct ath_hal *ah) 332169689Skan{ 333169689Skan uint32_t low1, low2, u32; 334169689Skan 335169689Skan /* sync multi-word read */ 336169689Skan low1 = OS_REG_READ(ah, AR_TSF_L32); 337169689Skan u32 = OS_REG_READ(ah, AR_TSF_U32); 338169689Skan low2 = OS_REG_READ(ah, AR_TSF_L32); 339169689Skan if (low2 < low1) { /* roll over */ 340169689Skan /* 341169689Skan * If we are not preempted this will work. If we are 342169689Skan * then we re-reading AR_TSF_U32 does no good as the 343169689Skan * low bits will be meaningless. Likewise reading 344169689Skan * L32, U32, U32, then comparing the last two reads 345169689Skan * to check for rollover doesn't help if preempted--so 346169689Skan * we take this approach as it costs one less PCI 347169689Skan * read which can be noticeable when doing things 348169689Skan * like timestamping packets in monitor mode. 349169689Skan */ 350169689Skan u32++; 351169689Skan } 352132718Skan return (((uint64_t) u32) << 32) | ((uint64_t) low2); 353169689Skan} 354169689Skan 355169689Skan/* 356169689Skan * Get the current hardware tsf for stamlme. 357132718Skan */ 358169689Skanuint32_t 359169689Skanar5210GetTsf32(struct ath_hal *ah) 360169689Skan{ 361169689Skan return OS_REG_READ(ah, AR_TSF_L32); 362169689Skan} 363169689Skan 364169689Skan/* 365169689Skan * Reset the current hardware tsf for stamlme 366169689Skan */ 367169689Skanvoid 368169689Skanar5210ResetTsf(struct ath_hal *ah) 369169689Skan{ 370169689Skan uint32_t val = OS_REG_READ(ah, AR_BEACON); 371169689Skan 372169689Skan OS_REG_WRITE(ah, AR_BEACON, val | AR_BEACON_RESET_TSF); 373169689Skan} 374169689Skan 375169689Skan/* 376169689Skan * Grab a semi-random value from hardware registers - may not 377169689Skan * change often 378169689Skan */ 379169689Skanuint32_t 380169689Skanar5210GetRandomSeed(struct ath_hal *ah) 381169689Skan{ 382169689Skan uint32_t nf; 383169689Skan 384169689Skan nf = (OS_REG_READ(ah, AR_PHY_BASE + (25 << 2)) >> 19) & 0x1ff; 385169689Skan if (nf & 0x100) 386169689Skan nf = 0 - ((nf ^ 0x1ff) + 1); 387169689Skan return (OS_REG_READ(ah, AR_TSF_U32) ^ 388169689Skan OS_REG_READ(ah, AR_TSF_L32) ^ nf); 389169689Skan} 390169689Skan 391169689Skan/* 392169689Skan * Detect if our card is present 393169689Skan */ 394169689SkanHAL_BOOL 395169689Skanar5210DetectCardPresent(struct ath_hal *ah) 396169689Skan{ 397169689Skan /* 398132718Skan * Read the Silicon Revision register and compare that 399132718Skan * to what we read at attach time. If the same, we say 400169689Skan * a card/device is present. 401169689Skan */ 402169689Skan return (AH_PRIVATE(ah)->ah_macRev == (OS_REG_READ(ah, AR_SREV) & 0xff)); 403169689Skan} 404169689Skan 405169689Skan/* 406169689Skan * Update MIB Counters 407169689Skan */ 408169689Skanvoid 409169689Skanar5210UpdateMibCounters(struct ath_hal *ah, HAL_MIB_STATS *stats) 410169689Skan{ 411169689Skan stats->ackrcv_bad += OS_REG_READ(ah, AR_ACK_FAIL); 412169689Skan stats->rts_bad += OS_REG_READ(ah, AR_RTS_FAIL); 413169689Skan stats->fcs_bad += OS_REG_READ(ah, AR_FCS_FAIL); 414169689Skan stats->rts_good += OS_REG_READ(ah, AR_RTS_OK); 415169689Skan stats->beacons += OS_REG_READ(ah, AR_BEACON_CNT); 416169689Skan} 417132718Skan 418132718SkanHAL_BOOL 419132718Skanar5210SetSifsTime(struct ath_hal *ah, u_int us) 420132718Skan{ 421132718Skan struct ath_hal_5210 *ahp = AH5210(ah); 422132718Skan 423132718Skan if (us > ath_hal_mac_usec(ah, 0x7ff)) { 424132718Skan HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad SIFS time %u\n", 425132718Skan __func__, us); 426132718Skan ahp->ah_sifstime = (u_int) -1; /* restore default handling */ 427169689Skan return AH_FALSE; 428169689Skan } else { 429169689Skan /* convert to system clocks */ 430169689Skan OS_REG_RMW_FIELD(ah, AR_IFS0, AR_IFS0_SIFS, 431132718Skan ath_hal_mac_clks(ah, us)); 432132718Skan ahp->ah_sifstime = us; 433169689Skan return AH_TRUE; 434169689Skan } 435169689Skan} 436169689Skan 437169689Skanu_int 438169689Skanar5210GetSifsTime(struct ath_hal *ah) 439169689Skan{ 440132718Skan u_int clks = OS_REG_READ(ah, AR_IFS0) & 0x7ff; 441132718Skan return ath_hal_mac_usec(ah, clks); /* convert from system clocks */ 442132718Skan} 443132718Skan 444132718SkanHAL_BOOL 445132718Skanar5210SetSlotTime(struct ath_hal *ah, u_int us) 446132718Skan{ 447132718Skan struct ath_hal_5210 *ahp = AH5210(ah); 448132718Skan 449132718Skan if (us < HAL_SLOT_TIME_9 || us > ath_hal_mac_usec(ah, 0xffff)) { 450169689Skan HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad slot time %u\n", 451169689Skan __func__, us); 452169689Skan ahp->ah_slottime = (u_int) -1; /* restore default handling */ 453169689Skan return AH_FALSE; 454169689Skan } else { 455169689Skan /* convert to system clocks */ 456169689Skan OS_REG_WRITE(ah, AR_SLOT_TIME, ath_hal_mac_clks(ah, us)); 457169689Skan ahp->ah_slottime = us; 458169689Skan return AH_TRUE; 459169689Skan } 460169689Skan} 461169689Skan 462169689Skanu_int 463169689Skanar5210GetSlotTime(struct ath_hal *ah) 464169689Skan{ 465132718Skan u_int clks = OS_REG_READ(ah, AR_SLOT_TIME) & 0xffff; 466132718Skan return ath_hal_mac_usec(ah, clks); /* convert from system clocks */ 467169689Skan} 468169689Skan 469169689SkanHAL_BOOL 470169689Skanar5210SetAckTimeout(struct ath_hal *ah, u_int us) 471169689Skan{ 472169689Skan struct ath_hal_5210 *ahp = AH5210(ah); 473169689Skan 474169689Skan if (us > ath_hal_mac_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) { 475169689Skan HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad ack timeout %u\n", 476169689Skan __func__, us); 477169689Skan ahp->ah_acktimeout = (u_int) -1; /* restore default handling */ 478169689Skan return AH_FALSE; 479169689Skan } else { 480169689Skan /* convert to system clocks */ 481169689Skan OS_REG_RMW_FIELD(ah, AR_TIME_OUT, 482169689Skan AR_TIME_OUT_ACK, ath_hal_mac_clks(ah, us)); 483169689Skan ahp->ah_acktimeout = us; 484169689Skan return AH_TRUE; 485169689Skan } 486169689Skan} 487169689Skan 488169689Skanu_int 489169689Skanar5210GetAckTimeout(struct ath_hal *ah) 490169689Skan{ 491169689Skan u_int clks = MS(OS_REG_READ(ah, AR_TIME_OUT), AR_TIME_OUT_ACK); 492169689Skan return ath_hal_mac_usec(ah, clks); /* convert from system clocks */ 493169689Skan} 494169689Skan 495169689Skanu_int 496169689Skanar5210GetAckCTSRate(struct ath_hal *ah) 497169689Skan{ 498169689Skan return ((AH5210(ah)->ah_staId1Defaults & AR_STA_ID1_ACKCTS_6MB) == 0); 499169689Skan} 500169689Skan 501169689SkanHAL_BOOL 502169689Skanar5210SetAckCTSRate(struct ath_hal *ah, u_int high) 503169689Skan{ 504169689Skan struct ath_hal_5210 *ahp = AH5210(ah); 505169689Skan 506169689Skan if (high) { 507169689Skan OS_REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_ACKCTS_6MB); 508169689Skan ahp->ah_staId1Defaults &= ~AR_STA_ID1_ACKCTS_6MB; 509169689Skan } else { 510169689Skan OS_REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_ACKCTS_6MB); 511132718Skan ahp->ah_staId1Defaults |= AR_STA_ID1_ACKCTS_6MB; 512132718Skan } 513132718Skan return AH_TRUE; 514132718Skan} 515132718Skan 516132718SkanHAL_BOOL 517132718Skanar5210SetCTSTimeout(struct ath_hal *ah, u_int us) 518132718Skan{ 519169689Skan struct ath_hal_5210 *ahp = AH5210(ah); 520169689Skan 521169689Skan if (us > ath_hal_mac_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) { 522169689Skan HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad cts timeout %u\n", 523169689Skan __func__, us); 524169689Skan ahp->ah_ctstimeout = (u_int) -1; /* restore default handling */ 525169689Skan return AH_FALSE; 526169689Skan } else { 527169689Skan /* convert to system clocks */ 528132718Skan OS_REG_RMW_FIELD(ah, AR_TIME_OUT, 529132718Skan AR_TIME_OUT_CTS, ath_hal_mac_clks(ah, us)); 530132718Skan ahp->ah_ctstimeout = us; 531132718Skan return AH_TRUE; 532169689Skan } 533169689Skan} 534169689Skan 535169689Skanu_int 536132718Skanar5210GetCTSTimeout(struct ath_hal *ah) 537169689Skan{ 538132718Skan u_int clks = MS(OS_REG_READ(ah, AR_TIME_OUT), AR_TIME_OUT_CTS); 539132718Skan return ath_hal_mac_usec(ah, clks); /* convert from system clocks */ 540132718Skan} 541132718Skan 542132718SkanHAL_BOOL 543132718Skanar5210SetDecompMask(struct ath_hal *ah, uint16_t keyidx, int en) 544132718Skan{ 545132718Skan /* nothing to do */ 546132718Skan return AH_TRUE; 547132718Skan} 548132718Skan 549132718Skanvoid 550132718Skanar5210SetCoverageClass(struct ath_hal *ah, uint8_t coverageclass, int now) 551132718Skan{ 552132718Skan} 553132718Skan 554132718Skan/* 555132718Skan * Control Adaptive Noise Immunity Parameters 556132718Skan */ 557132718SkanHAL_BOOL 558132718Skanar5210AniControl(struct ath_hal *ah, HAL_ANI_CMD cmd, int param) 559132718Skan{ 560132718Skan return AH_FALSE; 561132718Skan} 562132718Skan 563132718Skanvoid 564132718Skanar5210RxMonitor(struct ath_hal *ah, const HAL_NODE_STATS *stats, 565132718Skan const struct ieee80211_channel *chan) 566132718Skan{ 567132718Skan} 568132718Skan 569132718Skanvoid 570132718Skanar5210AniPoll(struct ath_hal *ah, const struct ieee80211_channel *chan) 571132718Skan{ 572132718Skan} 573132718Skan 574169689Skanvoid 575132718Skanar5210MibEvent(struct ath_hal *ah, const HAL_NODE_STATS *stats) 576132718Skan{ 577132718Skan} 578169689Skan 579169689Skan#define AR_DIAG_SW_DIS_CRYPTO (AR_DIAG_SW_DIS_ENC | AR_DIAG_SW_DIS_DEC) 580132718Skan 581132718SkanHAL_STATUS 582169689Skanar5210GetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type, 583132718Skan uint32_t capability, uint32_t *result) 584132718Skan{ 585132718Skan 586132718Skan switch (type) { 587169689Skan case HAL_CAP_CIPHER: /* cipher handled in hardware */ 588169689Skan return (capability == HAL_CIPHER_WEP ? HAL_OK : HAL_ENOTSUPP); 589132718Skan default: 590132718Skan return ath_hal_getcapability(ah, type, capability, result); 591169689Skan } 592169689Skan} 593169689Skan 594132718SkanHAL_BOOL 595132718Skanar5210SetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type, 596132718Skan uint32_t capability, uint32_t setting, HAL_STATUS *status) 597132718Skan{ 598132718Skan 599132718Skan switch (type) { 600132718Skan case HAL_CAP_DIAG: /* hardware diagnostic support */ 601132718Skan /* 602132718Skan * NB: could split this up into virtual capabilities, 603132718Skan * (e.g. 1 => ACK, 2 => CTS, etc.) but it hardly 604132718Skan * seems worth the additional complexity. 605132718Skan */ 606132718Skan#ifdef AH_DEBUG 607132718Skan AH_PRIVATE(ah)->ah_diagreg = setting; 608132718Skan#else 609132718Skan AH_PRIVATE(ah)->ah_diagreg = setting & 0x6; /* ACK+CTS */ 610132718Skan#endif 611132718Skan OS_REG_WRITE(ah, AR_DIAG_SW, AH_PRIVATE(ah)->ah_diagreg); 612132718Skan return AH_TRUE; 613132718Skan case HAL_CAP_RXORN_FATAL: /* HAL_INT_RXORN treated as fatal */ 614132718Skan return AH_FALSE; /* NB: disallow */ 615132718Skan default: 616132718Skan return ath_hal_setcapability(ah, type, capability, 617132718Skan setting, status); 618132718Skan } 619132718Skan} 620169689Skan 621169689SkanHAL_BOOL 622169689Skanar5210GetDiagState(struct ath_hal *ah, int request, 623169689Skan const void *args, uint32_t argsize, 624169689Skan void **result, uint32_t *resultsize) 625169689Skan{ 626169689Skan#ifdef AH_PRIVATE_DIAG 627169689Skan uint32_t pcicfg; 628169689Skan HAL_BOOL ok; 629132718Skan 630132718Skan switch (request) { 631132718Skan case HAL_DIAG_EEPROM: 632169689Skan /* XXX */ 633132718Skan break; 634132718Skan case HAL_DIAG_EEREAD: 635132718Skan if (argsize != sizeof(uint16_t)) 636132718Skan return AH_FALSE; 637132718Skan pcicfg = OS_REG_READ(ah, AR_PCICFG); 638169689Skan OS_REG_WRITE(ah, AR_PCICFG, pcicfg | AR_PCICFG_EEPROMSEL); 639169689Skan ok = ath_hal_eepromRead(ah, *(const uint16_t *)args, *result); 640169689Skan OS_REG_WRITE(ah, AR_PCICFG, pcicfg); 641169689Skan if (ok) 642169689Skan *resultsize = sizeof(uint16_t); 643169689Skan return ok; 644169689Skan } 645169689Skan#endif 646169689Skan return ath_hal_getdiagstate(ah, request, 647169689Skan args, argsize, result, resultsize); 648169689Skan} 649169689Skan