1 1.1 alc /* 2 1.1 alc * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting 3 1.1 alc * Copyright (c) 2002-2006 Atheros Communications, Inc. 4 1.1 alc * 5 1.1 alc * Permission to use, copy, modify, and/or distribute this software for any 6 1.1 alc * purpose with or without fee is hereby granted, provided that the above 7 1.1 alc * copyright notice and this permission notice appear in all copies. 8 1.1 alc * 9 1.1 alc * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 1.1 alc * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 1.1 alc * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 1.1 alc * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 1.1 alc * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 1.1 alc * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 1.1 alc * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 1.1 alc * 17 1.2 cegger * $Id: ar5211_misc.c,v 1.2 2011/03/07 11:25:42 cegger Exp $ 18 1.1 alc */ 19 1.1 alc #include "opt_ah.h" 20 1.1 alc 21 1.1 alc #include "ah.h" 22 1.1 alc #include "ah_internal.h" 23 1.1 alc 24 1.1 alc #include "ar5211/ar5211.h" 25 1.1 alc #include "ar5211/ar5211reg.h" 26 1.1 alc #include "ar5211/ar5211phy.h" 27 1.1 alc 28 1.1 alc #include "ah_eeprom_v3.h" 29 1.1 alc 30 1.1 alc #define AR_NUM_GPIO 6 /* 6 GPIO bits */ 31 1.1 alc #define AR_GPIOD_MASK 0x2f /* 6-bit mask */ 32 1.1 alc 33 1.1 alc void 34 1.1 alc ar5211GetMacAddress(struct ath_hal *ah, uint8_t *mac) 35 1.1 alc { 36 1.1 alc struct ath_hal_5211 *ahp = AH5211(ah); 37 1.1 alc 38 1.1 alc OS_MEMCPY(mac, ahp->ah_macaddr, IEEE80211_ADDR_LEN); 39 1.1 alc } 40 1.1 alc 41 1.1 alc HAL_BOOL 42 1.1 alc ar5211SetMacAddress(struct ath_hal *ah, const uint8_t *mac) 43 1.1 alc { 44 1.1 alc struct ath_hal_5211 *ahp = AH5211(ah); 45 1.1 alc 46 1.1 alc OS_MEMCPY(ahp->ah_macaddr, mac, IEEE80211_ADDR_LEN); 47 1.1 alc return AH_TRUE; 48 1.1 alc } 49 1.1 alc 50 1.1 alc void 51 1.1 alc ar5211GetBssIdMask(struct ath_hal *ah, uint8_t *mask) 52 1.1 alc { 53 1.1 alc static const uint8_t ones[IEEE80211_ADDR_LEN] = 54 1.1 alc { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 55 1.1 alc OS_MEMCPY(mask, ones, IEEE80211_ADDR_LEN); 56 1.1 alc } 57 1.1 alc 58 1.1 alc HAL_BOOL 59 1.1 alc ar5211SetBssIdMask(struct ath_hal *ah, const uint8_t *mask) 60 1.1 alc { 61 1.1 alc return AH_FALSE; 62 1.1 alc } 63 1.1 alc 64 1.1 alc /* 65 1.1 alc * Read 16 bits of data from the specified EEPROM offset. 66 1.1 alc */ 67 1.1 alc HAL_BOOL 68 1.1 alc ar5211EepromRead(struct ath_hal *ah, u_int off, uint16_t *data) 69 1.1 alc { 70 1.1 alc OS_REG_WRITE(ah, AR_EEPROM_ADDR, off); 71 1.1 alc OS_REG_WRITE(ah, AR_EEPROM_CMD, AR_EEPROM_CMD_READ); 72 1.1 alc 73 1.1 alc if (!ath_hal_wait(ah, AR_EEPROM_STS, 74 1.1 alc AR_EEPROM_STS_READ_COMPLETE | AR_EEPROM_STS_READ_ERROR, 75 1.1 alc AR_EEPROM_STS_READ_COMPLETE)) { 76 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, 77 1.1 alc "%s: read failed for entry 0x%x\n", __func__, off); 78 1.1 alc return AH_FALSE; 79 1.1 alc } 80 1.1 alc *data = OS_REG_READ(ah, AR_EEPROM_DATA) & 0xffff; 81 1.1 alc return AH_TRUE; 82 1.1 alc } 83 1.1 alc 84 1.1 alc #ifdef AH_SUPPORT_WRITE_EEPROM 85 1.1 alc /* 86 1.1 alc * Write 16 bits of data to the specified EEPROM offset. 87 1.1 alc */ 88 1.1 alc HAL_BOOL 89 1.1 alc ar5211EepromWrite(struct ath_hal *ah, u_int off, uint16_t data) 90 1.1 alc { 91 1.1 alc return AH_FALSE; 92 1.1 alc } 93 1.1 alc #endif /* AH_SUPPORT_WRITE_EEPROM */ 94 1.1 alc 95 1.1 alc /* 96 1.1 alc * Attempt to change the cards operating regulatory domain to the given value 97 1.1 alc */ 98 1.1 alc HAL_BOOL 99 1.1 alc ar5211SetRegulatoryDomain(struct ath_hal *ah, 100 1.1 alc uint16_t regDomain, HAL_STATUS *status) 101 1.1 alc { 102 1.1 alc HAL_STATUS ecode; 103 1.1 alc 104 1.1 alc if (AH_PRIVATE(ah)->ah_currentRD == regDomain) { 105 1.1 alc ecode = HAL_EINVAL; 106 1.1 alc goto bad; 107 1.1 alc } 108 1.1 alc /* 109 1.1 alc * Check if EEPROM is configured to allow this; must 110 1.1 alc * be a proper version and the protection bits must 111 1.1 alc * permit re-writing that segment of the EEPROM. 112 1.1 alc */ 113 1.1 alc if (ath_hal_eepromGetFlag(ah, AR_EEP_WRITEPROTECT)) { 114 1.1 alc ecode = HAL_EEWRITE; 115 1.1 alc goto bad; 116 1.1 alc } 117 1.1 alc #ifdef AH_SUPPORT_WRITE_REGDOMAIN 118 1.1 alc if (ar5211EepromWrite(ah, AR_EEPROM_REG_DOMAIN, regDomain)) { 119 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, 120 1.1 alc "%s: set regulatory domain to %u (0x%x)\n", 121 1.1 alc __func__, regDomain, regDomain); 122 1.1 alc AH_PRIVATE(ah)->ah_currentRD = regDomain; 123 1.1 alc return AH_TRUE; 124 1.1 alc } 125 1.1 alc #endif 126 1.1 alc ecode = HAL_EIO; 127 1.1 alc bad: 128 1.1 alc if (status) 129 1.1 alc *status = ecode; 130 1.1 alc return AH_FALSE; 131 1.1 alc } 132 1.1 alc 133 1.1 alc /* 134 1.1 alc * Return the wireless modes (a,b,g,t) supported by hardware. 135 1.1 alc * 136 1.1 alc * This value is what is actually supported by the hardware 137 1.1 alc * and is unaffected by regulatory/country code settings. 138 1.1 alc * 139 1.1 alc */ 140 1.1 alc u_int 141 1.1 alc ar5211GetWirelessModes(struct ath_hal *ah) 142 1.1 alc { 143 1.1 alc u_int mode = 0; 144 1.1 alc 145 1.1 alc if (ath_hal_eepromGetFlag(ah, AR_EEP_AMODE)) { 146 1.1 alc mode = HAL_MODE_11A; 147 1.1 alc if (!ath_hal_eepromGetFlag(ah, AR_EEP_TURBO5DISABLE)) 148 1.1 alc mode |= HAL_MODE_TURBO | HAL_MODE_108A; 149 1.1 alc } 150 1.1 alc if (ath_hal_eepromGetFlag(ah, AR_EEP_BMODE)) 151 1.1 alc mode |= HAL_MODE_11B; 152 1.1 alc return mode; 153 1.1 alc } 154 1.1 alc 155 1.1 alc #if 0 156 1.1 alc HAL_BOOL 157 1.1 alc ar5211GetTurboDisable(struct ath_hal *ah) 158 1.1 alc { 159 1.1 alc return (AH5211(ah)->ah_turboDisable != 0); 160 1.1 alc } 161 1.1 alc #endif 162 1.1 alc 163 1.1 alc /* 164 1.1 alc * Called if RfKill is supported (according to EEPROM). Set the interrupt and 165 1.1 alc * GPIO values so the ISR and can disable RF on a switch signal 166 1.1 alc */ 167 1.1 alc void 168 1.1 alc ar5211EnableRfKill(struct ath_hal *ah) 169 1.1 alc { 170 1.1 alc uint16_t rfsilent = AH_PRIVATE(ah)->ah_rfsilent; 171 1.1 alc int select = MS(rfsilent, AR_EEPROM_RFSILENT_GPIO_SEL); 172 1.1 alc int polarity = MS(rfsilent, AR_EEPROM_RFSILENT_POLARITY); 173 1.1 alc 174 1.1 alc /* 175 1.1 alc * Configure the desired GPIO port for input 176 1.1 alc * and enable baseband rf silence. 177 1.1 alc */ 178 1.1 alc ar5211GpioCfgInput(ah, select); 179 1.1 alc OS_REG_SET_BIT(ah, AR_PHY_BASE, 0x00002000); 180 1.1 alc /* 181 1.1 alc * If radio disable switch connection to GPIO bit x is enabled 182 1.1 alc * program GPIO interrupt. 183 1.1 alc * If rfkill bit on eeprom is 1, setupeeprommap routine has already 184 1.1 alc * verified that it is a later version of eeprom, it has a place for 185 1.1 alc * rfkill bit and it is set to 1, indicating that GPIO bit x hardware 186 1.1 alc * connection is present. 187 1.1 alc */ 188 1.1 alc ar5211GpioSetIntr(ah, select, (ar5211GpioGet(ah, select) != polarity)); 189 1.1 alc } 190 1.1 alc 191 1.1 alc /* 192 1.1 alc * Configure GPIO Output lines 193 1.1 alc */ 194 1.1 alc HAL_BOOL 195 1.2 cegger ar5211GpioCfgOutput(struct ath_hal *ah, uint32_t gpio, HAL_GPIO_MUX_TYPE type) 196 1.1 alc { 197 1.1 alc uint32_t reg; 198 1.1 alc 199 1.1 alc HALASSERT(gpio < AR_NUM_GPIO); 200 1.1 alc 201 1.1 alc reg = OS_REG_READ(ah, AR_GPIOCR); 202 1.1 alc reg &= ~(AR_GPIOCR_0_CR_A << (gpio * AR_GPIOCR_CR_SHIFT)); 203 1.1 alc reg |= AR_GPIOCR_0_CR_A << (gpio * AR_GPIOCR_CR_SHIFT); 204 1.1 alc 205 1.1 alc OS_REG_WRITE(ah, AR_GPIOCR, reg); 206 1.1 alc return AH_TRUE; 207 1.1 alc } 208 1.1 alc 209 1.1 alc /* 210 1.1 alc * Configure GPIO Input lines 211 1.1 alc */ 212 1.1 alc HAL_BOOL 213 1.1 alc ar5211GpioCfgInput(struct ath_hal *ah, uint32_t gpio) 214 1.1 alc { 215 1.1 alc uint32_t reg; 216 1.1 alc 217 1.1 alc HALASSERT(gpio < AR_NUM_GPIO); 218 1.1 alc 219 1.1 alc reg = OS_REG_READ(ah, AR_GPIOCR); 220 1.1 alc reg &= ~(AR_GPIOCR_0_CR_A << (gpio * AR_GPIOCR_CR_SHIFT)); 221 1.1 alc reg |= AR_GPIOCR_0_CR_N << (gpio * AR_GPIOCR_CR_SHIFT); 222 1.1 alc 223 1.1 alc OS_REG_WRITE(ah, AR_GPIOCR, reg); 224 1.1 alc return AH_TRUE; 225 1.1 alc } 226 1.1 alc 227 1.1 alc /* 228 1.1 alc * Once configured for I/O - set output lines 229 1.1 alc */ 230 1.1 alc HAL_BOOL 231 1.1 alc ar5211GpioSet(struct ath_hal *ah, uint32_t gpio, uint32_t val) 232 1.1 alc { 233 1.1 alc uint32_t reg; 234 1.1 alc 235 1.1 alc HALASSERT(gpio < AR_NUM_GPIO); 236 1.1 alc 237 1.1 alc reg = OS_REG_READ(ah, AR_GPIODO); 238 1.1 alc reg &= ~(1 << gpio); 239 1.1 alc reg |= (val&1) << gpio; 240 1.1 alc 241 1.1 alc OS_REG_WRITE(ah, AR_GPIODO, reg); 242 1.1 alc return AH_TRUE; 243 1.1 alc } 244 1.1 alc 245 1.1 alc /* 246 1.1 alc * Once configured for I/O - get input lines 247 1.1 alc */ 248 1.1 alc uint32_t 249 1.1 alc ar5211GpioGet(struct ath_hal *ah, uint32_t gpio) 250 1.1 alc { 251 1.1 alc if (gpio < AR_NUM_GPIO) { 252 1.1 alc uint32_t val = OS_REG_READ(ah, AR_GPIODI); 253 1.1 alc val = ((val & AR_GPIOD_MASK) >> gpio) & 0x1; 254 1.1 alc return val; 255 1.1 alc } else { 256 1.1 alc return 0xffffffff; 257 1.1 alc } 258 1.1 alc } 259 1.1 alc 260 1.1 alc /* 261 1.1 alc * Set the GPIO 0 Interrupt (gpio is ignored) 262 1.1 alc */ 263 1.1 alc void 264 1.1 alc ar5211GpioSetIntr(struct ath_hal *ah, u_int gpio, uint32_t ilevel) 265 1.1 alc { 266 1.1 alc uint32_t val = OS_REG_READ(ah, AR_GPIOCR); 267 1.1 alc 268 1.1 alc /* Clear the bits that we will modify. */ 269 1.1 alc val &= ~(AR_GPIOCR_INT_SEL0 | AR_GPIOCR_INT_SELH | AR_GPIOCR_INT_ENA | 270 1.1 alc AR_GPIOCR_0_CR_A); 271 1.1 alc 272 1.1 alc val |= AR_GPIOCR_INT_SEL0 | AR_GPIOCR_INT_ENA; 273 1.1 alc if (ilevel) 274 1.1 alc val |= AR_GPIOCR_INT_SELH; 275 1.1 alc 276 1.1 alc /* Don't need to change anything for low level interrupt. */ 277 1.1 alc OS_REG_WRITE(ah, AR_GPIOCR, val); 278 1.1 alc 279 1.1 alc /* Change the interrupt mask. */ 280 1.1 alc ar5211SetInterrupts(ah, AH5211(ah)->ah_maskReg | HAL_INT_GPIO); 281 1.1 alc } 282 1.1 alc 283 1.1 alc /* 284 1.1 alc * Change the LED blinking pattern to correspond to the connectivity 285 1.1 alc */ 286 1.1 alc void 287 1.1 alc ar5211SetLedState(struct ath_hal *ah, HAL_LED_STATE state) 288 1.1 alc { 289 1.1 alc static const uint32_t ledbits[8] = { 290 1.1 alc AR_PCICFG_LEDCTL_NONE|AR_PCICFG_LEDMODE_PROP, /* HAL_LED_INIT */ 291 1.1 alc AR_PCICFG_LEDCTL_PEND|AR_PCICFG_LEDMODE_PROP, /* HAL_LED_SCAN */ 292 1.1 alc AR_PCICFG_LEDCTL_PEND|AR_PCICFG_LEDMODE_PROP, /* HAL_LED_AUTH */ 293 1.1 alc AR_PCICFG_LEDCTL_ASSOC|AR_PCICFG_LEDMODE_PROP,/* HAL_LED_ASSOC*/ 294 1.1 alc AR_PCICFG_LEDCTL_ASSOC|AR_PCICFG_LEDMODE_PROP,/* HAL_LED_RUN */ 295 1.1 alc AR_PCICFG_LEDCTL_NONE|AR_PCICFG_LEDMODE_RAND, 296 1.1 alc AR_PCICFG_LEDCTL_NONE|AR_PCICFG_LEDMODE_RAND, 297 1.1 alc AR_PCICFG_LEDCTL_NONE|AR_PCICFG_LEDMODE_RAND, 298 1.1 alc }; 299 1.1 alc OS_REG_WRITE(ah, AR_PCICFG, 300 1.1 alc (OS_REG_READ(ah, AR_PCICFG) &~ 301 1.1 alc (AR_PCICFG_LEDCTL | AR_PCICFG_LEDMODE)) 302 1.1 alc | ledbits[state & 0x7] 303 1.1 alc ); 304 1.1 alc } 305 1.1 alc 306 1.1 alc /* 307 1.1 alc * Change association related fields programmed into the hardware. 308 1.1 alc * Writing a valid BSSID to the hardware effectively enables the hardware 309 1.1 alc * to synchronize its TSF to the correct beacons and receive frames coming 310 1.1 alc * from that BSSID. It is called by the SME JOIN operation. 311 1.1 alc */ 312 1.1 alc void 313 1.1 alc ar5211WriteAssocid(struct ath_hal *ah, const uint8_t *bssid, uint16_t assocId) 314 1.1 alc { 315 1.1 alc struct ath_hal_5211 *ahp = AH5211(ah); 316 1.1 alc 317 1.1 alc /* XXX save bssid for possible re-use on reset */ 318 1.1 alc OS_MEMCPY(ahp->ah_bssid, bssid, IEEE80211_ADDR_LEN); 319 1.1 alc OS_REG_WRITE(ah, AR_BSS_ID0, LE_READ_4(ahp->ah_bssid)); 320 1.1 alc OS_REG_WRITE(ah, AR_BSS_ID1, LE_READ_2(ahp->ah_bssid+4) | 321 1.1 alc ((assocId & 0x3fff)<<AR_BSS_ID1_AID_S)); 322 1.1 alc } 323 1.1 alc 324 1.1 alc /* 325 1.1 alc * Get the current hardware tsf for stamlme. 326 1.1 alc */ 327 1.1 alc uint64_t 328 1.1 alc ar5211GetTsf64(struct ath_hal *ah) 329 1.1 alc { 330 1.1 alc uint32_t low1, low2, u32; 331 1.1 alc 332 1.1 alc /* sync multi-word read */ 333 1.1 alc low1 = OS_REG_READ(ah, AR_TSF_L32); 334 1.1 alc u32 = OS_REG_READ(ah, AR_TSF_U32); 335 1.1 alc low2 = OS_REG_READ(ah, AR_TSF_L32); 336 1.1 alc if (low2 < low1) { /* roll over */ 337 1.1 alc /* 338 1.1 alc * If we are not preempted this will work. If we are 339 1.1 alc * then we re-reading AR_TSF_U32 does no good as the 340 1.1 alc * low bits will be meaningless. Likewise reading 341 1.1 alc * L32, U32, U32, then comparing the last two reads 342 1.1 alc * to check for rollover doesn't help if preempted--so 343 1.1 alc * we take this approach as it costs one less PCI 344 1.1 alc * read which can be noticeable when doing things 345 1.1 alc * like timestamping packets in monitor mode. 346 1.1 alc */ 347 1.1 alc u32++; 348 1.1 alc } 349 1.1 alc return (((uint64_t) u32) << 32) | ((uint64_t) low2); 350 1.1 alc } 351 1.1 alc 352 1.1 alc /* 353 1.1 alc * Get the current hardware tsf for stamlme. 354 1.1 alc */ 355 1.1 alc uint32_t 356 1.1 alc ar5211GetTsf32(struct ath_hal *ah) 357 1.1 alc { 358 1.1 alc return OS_REG_READ(ah, AR_TSF_L32); 359 1.1 alc } 360 1.1 alc 361 1.1 alc /* 362 1.1 alc * Reset the current hardware tsf for stamlme 363 1.1 alc */ 364 1.1 alc void 365 1.1 alc ar5211ResetTsf(struct ath_hal *ah) 366 1.1 alc { 367 1.1 alc uint32_t val = OS_REG_READ(ah, AR_BEACON); 368 1.1 alc 369 1.1 alc OS_REG_WRITE(ah, AR_BEACON, val | AR_BEACON_RESET_TSF); 370 1.1 alc } 371 1.1 alc 372 1.1 alc /* 373 1.1 alc * Grab a semi-random value from hardware registers - may not 374 1.1 alc * change often 375 1.1 alc */ 376 1.1 alc uint32_t 377 1.1 alc ar5211GetRandomSeed(struct ath_hal *ah) 378 1.1 alc { 379 1.1 alc uint32_t nf; 380 1.1 alc 381 1.1 alc nf = (OS_REG_READ(ah, AR_PHY(25)) >> 19) & 0x1ff; 382 1.1 alc if (nf & 0x100) 383 1.1 alc nf = 0 - ((nf ^ 0x1ff) + 1); 384 1.1 alc return (OS_REG_READ(ah, AR_TSF_U32) ^ 385 1.1 alc OS_REG_READ(ah, AR_TSF_L32) ^ nf); 386 1.1 alc } 387 1.1 alc 388 1.1 alc /* 389 1.1 alc * Detect if our card is present 390 1.1 alc */ 391 1.1 alc HAL_BOOL 392 1.1 alc ar5211DetectCardPresent(struct ath_hal *ah) 393 1.1 alc { 394 1.1 alc uint16_t macVersion, macRev; 395 1.1 alc uint32_t v; 396 1.1 alc 397 1.1 alc /* 398 1.1 alc * Read the Silicon Revision register and compare that 399 1.1 alc * to what we read at attach time. If the same, we say 400 1.1 alc * a card/device is present. 401 1.1 alc */ 402 1.1 alc v = OS_REG_READ(ah, AR_SREV) & AR_SREV_ID_M; 403 1.1 alc macVersion = v >> AR_SREV_ID_S; 404 1.1 alc macRev = v & AR_SREV_REVISION_M; 405 1.1 alc return (AH_PRIVATE(ah)->ah_macVersion == macVersion && 406 1.1 alc AH_PRIVATE(ah)->ah_macRev == macRev); 407 1.1 alc } 408 1.1 alc 409 1.1 alc /* 410 1.1 alc * Update MIB Counters 411 1.1 alc */ 412 1.1 alc void 413 1.1 alc ar5211UpdateMibCounters(struct ath_hal *ah, HAL_MIB_STATS *stats) 414 1.1 alc { 415 1.1 alc stats->ackrcv_bad += OS_REG_READ(ah, AR_ACK_FAIL); 416 1.1 alc stats->rts_bad += OS_REG_READ(ah, AR_RTS_FAIL); 417 1.1 alc stats->fcs_bad += OS_REG_READ(ah, AR_FCS_FAIL); 418 1.1 alc stats->rts_good += OS_REG_READ(ah, AR_RTS_OK); 419 1.1 alc stats->beacons += OS_REG_READ(ah, AR_BEACON_CNT); 420 1.1 alc } 421 1.1 alc 422 1.1 alc HAL_BOOL 423 1.1 alc ar5211SetSifsTime(struct ath_hal *ah, u_int us) 424 1.1 alc { 425 1.1 alc struct ath_hal_5211 *ahp = AH5211(ah); 426 1.1 alc 427 1.1 alc if (us > ath_hal_mac_usec(ah, 0xffff)) { 428 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad SIFS time %u\n", 429 1.1 alc __func__, us); 430 1.1 alc ahp->ah_sifstime = (u_int) -1; /* restore default handling */ 431 1.1 alc return AH_FALSE; 432 1.1 alc } else { 433 1.1 alc /* convert to system clocks */ 434 1.1 alc OS_REG_WRITE(ah, AR_D_GBL_IFS_SIFS, ath_hal_mac_clks(ah, us)); 435 1.1 alc ahp->ah_slottime = us; 436 1.1 alc return AH_TRUE; 437 1.1 alc } 438 1.1 alc } 439 1.1 alc 440 1.1 alc u_int 441 1.1 alc ar5211GetSifsTime(struct ath_hal *ah) 442 1.1 alc { 443 1.1 alc u_int clks = OS_REG_READ(ah, AR_D_GBL_IFS_SIFS) & 0xffff; 444 1.1 alc return ath_hal_mac_usec(ah, clks); /* convert from system clocks */ 445 1.1 alc } 446 1.1 alc 447 1.1 alc HAL_BOOL 448 1.1 alc ar5211SetSlotTime(struct ath_hal *ah, u_int us) 449 1.1 alc { 450 1.1 alc struct ath_hal_5211 *ahp = AH5211(ah); 451 1.1 alc 452 1.1 alc if (us < HAL_SLOT_TIME_9 || us > ath_hal_mac_usec(ah, 0xffff)) { 453 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad slot time %u\n", 454 1.1 alc __func__, us); 455 1.1 alc ahp->ah_slottime = us; /* restore default handling */ 456 1.1 alc return AH_FALSE; 457 1.1 alc } else { 458 1.1 alc /* convert to system clocks */ 459 1.1 alc OS_REG_WRITE(ah, AR_D_GBL_IFS_SLOT, ath_hal_mac_clks(ah, us)); 460 1.1 alc ahp->ah_slottime = us; 461 1.1 alc return AH_TRUE; 462 1.1 alc } 463 1.1 alc } 464 1.1 alc 465 1.1 alc u_int 466 1.1 alc ar5211GetSlotTime(struct ath_hal *ah) 467 1.1 alc { 468 1.1 alc u_int clks = OS_REG_READ(ah, AR_D_GBL_IFS_SLOT) & 0xffff; 469 1.1 alc return ath_hal_mac_usec(ah, clks); /* convert from system clocks */ 470 1.1 alc } 471 1.1 alc 472 1.1 alc HAL_BOOL 473 1.1 alc ar5211SetAckTimeout(struct ath_hal *ah, u_int us) 474 1.1 alc { 475 1.1 alc struct ath_hal_5211 *ahp = AH5211(ah); 476 1.1 alc 477 1.1 alc if (us > ath_hal_mac_usec(ah, MS(0xffffffff, AR_TIME_OUT_ACK))) { 478 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad ack timeout %u\n", 479 1.1 alc __func__, us); 480 1.1 alc ahp->ah_acktimeout = (u_int) -1; /* restore default handling */ 481 1.1 alc return AH_FALSE; 482 1.1 alc } else { 483 1.1 alc /* convert to system clocks */ 484 1.1 alc OS_REG_RMW_FIELD(ah, AR_TIME_OUT, 485 1.1 alc AR_TIME_OUT_ACK, ath_hal_mac_clks(ah, us)); 486 1.1 alc ahp->ah_acktimeout = us; 487 1.1 alc return AH_TRUE; 488 1.1 alc } 489 1.1 alc } 490 1.1 alc 491 1.1 alc u_int 492 1.1 alc ar5211GetAckTimeout(struct ath_hal *ah) 493 1.1 alc { 494 1.1 alc u_int clks = MS(OS_REG_READ(ah, AR_TIME_OUT), AR_TIME_OUT_ACK); 495 1.1 alc return ath_hal_mac_usec(ah, clks); /* convert from system clocks */ 496 1.1 alc } 497 1.1 alc 498 1.1 alc u_int 499 1.1 alc ar5211GetAckCTSRate(struct ath_hal *ah) 500 1.1 alc { 501 1.1 alc return ((AH5211(ah)->ah_staId1Defaults & AR_STA_ID1_ACKCTS_6MB) == 0); 502 1.1 alc } 503 1.1 alc 504 1.1 alc HAL_BOOL 505 1.1 alc ar5211SetAckCTSRate(struct ath_hal *ah, u_int high) 506 1.1 alc { 507 1.1 alc struct ath_hal_5211 *ahp = AH5211(ah); 508 1.1 alc 509 1.1 alc if (high) { 510 1.1 alc OS_REG_CLR_BIT(ah, AR_STA_ID1, AR_STA_ID1_ACKCTS_6MB); 511 1.1 alc ahp->ah_staId1Defaults &= ~AR_STA_ID1_ACKCTS_6MB; 512 1.1 alc } else { 513 1.1 alc OS_REG_SET_BIT(ah, AR_STA_ID1, AR_STA_ID1_ACKCTS_6MB); 514 1.1 alc ahp->ah_staId1Defaults |= AR_STA_ID1_ACKCTS_6MB; 515 1.1 alc } 516 1.1 alc return AH_TRUE; 517 1.1 alc } 518 1.1 alc 519 1.1 alc HAL_BOOL 520 1.1 alc ar5211SetCTSTimeout(struct ath_hal *ah, u_int us) 521 1.1 alc { 522 1.1 alc struct ath_hal_5211 *ahp = AH5211(ah); 523 1.1 alc 524 1.1 alc if (us > ath_hal_mac_usec(ah, MS(0xffffffff, AR_TIME_OUT_CTS))) { 525 1.1 alc HALDEBUG(ah, HAL_DEBUG_ANY, "%s: bad cts timeout %u\n", 526 1.1 alc __func__, us); 527 1.1 alc ahp->ah_ctstimeout = (u_int) -1; /* restore default handling */ 528 1.1 alc return AH_FALSE; 529 1.1 alc } else { 530 1.1 alc /* convert to system clocks */ 531 1.1 alc OS_REG_RMW_FIELD(ah, AR_TIME_OUT, 532 1.1 alc AR_TIME_OUT_CTS, ath_hal_mac_clks(ah, us)); 533 1.1 alc ahp->ah_ctstimeout = us; 534 1.1 alc return AH_TRUE; 535 1.1 alc } 536 1.1 alc } 537 1.1 alc 538 1.1 alc u_int 539 1.1 alc ar5211GetCTSTimeout(struct ath_hal *ah) 540 1.1 alc { 541 1.1 alc u_int clks = MS(OS_REG_READ(ah, AR_TIME_OUT), AR_TIME_OUT_CTS); 542 1.1 alc return ath_hal_mac_usec(ah, clks); /* convert from system clocks */ 543 1.1 alc } 544 1.1 alc 545 1.1 alc HAL_BOOL 546 1.1 alc ar5211SetDecompMask(struct ath_hal *ah, uint16_t keyidx, int en) 547 1.1 alc { 548 1.1 alc /* nothing to do */ 549 1.1 alc return AH_TRUE; 550 1.1 alc } 551 1.1 alc 552 1.1 alc void 553 1.1 alc ar5211SetCoverageClass(struct ath_hal *ah, uint8_t coverageclass, int now) 554 1.1 alc { 555 1.1 alc } 556 1.1 alc 557 1.1 alc /* 558 1.1 alc * Control Adaptive Noise Immunity Parameters 559 1.1 alc */ 560 1.1 alc HAL_BOOL 561 1.1 alc ar5211AniControl(struct ath_hal *ah, HAL_ANI_CMD cmd, int param) 562 1.1 alc { 563 1.1 alc return AH_FALSE; 564 1.1 alc } 565 1.1 alc 566 1.1 alc void 567 1.1 alc ar5211AniPoll(struct ath_hal *ah, const HAL_NODE_STATS *stats, HAL_CHANNEL *chan) 568 1.1 alc { 569 1.1 alc } 570 1.1 alc 571 1.1 alc void 572 1.1 alc ar5211MibEvent(struct ath_hal *ah, const HAL_NODE_STATS *stats) 573 1.1 alc { 574 1.1 alc } 575 1.1 alc 576 1.1 alc /* 577 1.1 alc * Get the rssi of frame curently being received. 578 1.1 alc */ 579 1.1 alc uint32_t 580 1.1 alc ar5211GetCurRssi(struct ath_hal *ah) 581 1.1 alc { 582 1.1 alc return (OS_REG_READ(ah, AR_PHY_CURRENT_RSSI) & 0xff); 583 1.1 alc } 584 1.1 alc 585 1.1 alc u_int 586 1.1 alc ar5211GetDefAntenna(struct ath_hal *ah) 587 1.1 alc { 588 1.1 alc return (OS_REG_READ(ah, AR_DEF_ANTENNA) & 0x7); 589 1.1 alc } 590 1.1 alc 591 1.1 alc void 592 1.1 alc ar5211SetDefAntenna(struct ath_hal *ah, u_int antenna) 593 1.1 alc { 594 1.1 alc OS_REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7)); 595 1.1 alc } 596 1.1 alc 597 1.1 alc HAL_ANT_SETTING 598 1.1 alc ar5211GetAntennaSwitch(struct ath_hal *ah) 599 1.1 alc { 600 1.1 alc return AH5211(ah)->ah_diversityControl; 601 1.1 alc } 602 1.1 alc 603 1.1 alc HAL_BOOL 604 1.1 alc ar5211SetAntennaSwitch(struct ath_hal *ah, HAL_ANT_SETTING settings) 605 1.1 alc { 606 1.1 alc const HAL_CHANNEL *chan = 607 1.1 alc (const HAL_CHANNEL *) AH_PRIVATE(ah)->ah_curchan; 608 1.1 alc 609 1.1 alc if (chan == AH_NULL) { 610 1.1 alc AH5211(ah)->ah_diversityControl = settings; 611 1.1 alc return AH_TRUE; 612 1.1 alc } 613 1.1 alc return ar5211SetAntennaSwitchInternal(ah, settings, chan); 614 1.1 alc } 615 1.1 alc 616 1.1 alc HAL_STATUS 617 1.1 alc ar5211GetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type, 618 1.1 alc uint32_t capability, uint32_t *result) 619 1.1 alc { 620 1.1 alc 621 1.1 alc switch (type) { 622 1.1 alc case HAL_CAP_CIPHER: /* cipher handled in hardware */ 623 1.1 alc switch (capability) { 624 1.1 alc case HAL_CIPHER_AES_OCB: 625 1.1 alc case HAL_CIPHER_WEP: 626 1.1 alc case HAL_CIPHER_CLR: 627 1.1 alc return HAL_OK; 628 1.1 alc default: 629 1.1 alc return HAL_ENOTSUPP; 630 1.1 alc } 631 1.1 alc default: 632 1.1 alc return ath_hal_getcapability(ah, type, capability, result); 633 1.1 alc } 634 1.1 alc } 635 1.1 alc 636 1.1 alc HAL_BOOL 637 1.1 alc ar5211SetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type, 638 1.1 alc uint32_t capability, uint32_t setting, HAL_STATUS *status) 639 1.1 alc { 640 1.1 alc switch (type) { 641 1.1 alc case HAL_CAP_DIAG: /* hardware diagnostic support */ 642 1.1 alc /* 643 1.1 alc * NB: could split this up into virtual capabilities, 644 1.1 alc * (e.g. 1 => ACK, 2 => CTS, etc.) but it hardly 645 1.1 alc * seems worth the additional complexity. 646 1.1 alc */ 647 1.1 alc #ifdef AH_DEBUG 648 1.1 alc AH_PRIVATE(ah)->ah_diagreg = setting; 649 1.1 alc #else 650 1.1 alc AH_PRIVATE(ah)->ah_diagreg = setting & 0x6; /* ACK+CTS */ 651 1.1 alc #endif 652 1.1 alc OS_REG_WRITE(ah, AR_DIAG_SW, AH_PRIVATE(ah)->ah_diagreg); 653 1.1 alc return AH_TRUE; 654 1.1 alc default: 655 1.1 alc return ath_hal_setcapability(ah, type, capability, 656 1.1 alc setting, status); 657 1.1 alc } 658 1.1 alc } 659 1.1 alc 660 1.1 alc HAL_BOOL 661 1.1 alc ar5211GetDiagState(struct ath_hal *ah, int request, 662 1.1 alc const void *args, uint32_t argsize, 663 1.1 alc void **result, uint32_t *resultsize) 664 1.1 alc { 665 1.1 alc struct ath_hal_5211 *ahp = AH5211(ah); 666 1.1 alc 667 1.1 alc (void) ahp; 668 1.1 alc if (ath_hal_getdiagstate(ah, request, args, argsize, result, resultsize)) 669 1.1 alc return AH_TRUE; 670 1.1 alc switch (request) { 671 1.1 alc case HAL_DIAG_EEPROM: 672 1.1 alc return ath_hal_eepromDiag(ah, request, 673 1.1 alc args, argsize, result, resultsize); 674 1.1 alc case HAL_DIAG_RFGAIN: 675 1.1 alc *result = &ahp->ah_gainValues; 676 1.1 alc *resultsize = sizeof(GAIN_VALUES); 677 1.1 alc return AH_TRUE; 678 1.1 alc case HAL_DIAG_RFGAIN_CURSTEP: 679 1.1 alc *result = __DECONST(void *, ahp->ah_gainValues.currStep); 680 1.1 alc *resultsize = (*result == AH_NULL) ? 681 1.1 alc 0 : sizeof(GAIN_OPTIMIZATION_STEP); 682 1.1 alc return AH_TRUE; 683 1.1 alc } 684 1.1 alc return AH_FALSE; 685 1.1 alc } 686