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