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: releng/12.0/sys/dev/ath/ath_hal/ar5211/ar5211_misc.c 326695 2017-12-08 15:57:29Z pfg $ 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 35void 36ar5211GetMacAddress(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 43HAL_BOOL 44ar5211SetMacAddress(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 52void 53ar5211GetBssIdMask(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 60HAL_BOOL 61ar5211SetBssIdMask(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 */ 69HAL_BOOL 70ar5211EepromRead(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 */ 90HAL_BOOL 91ar5211EepromWrite(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 */ 100HAL_BOOL 101ar5211SetRegulatoryDomain(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; 129bad: 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 */ 142u_int 143ar5211GetWirelessModes(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 158HAL_BOOL 159ar5211GetTurboDisable(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 */ 169void 170ar5211EnableRfKill(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 */ 196HAL_BOOL 197ar5211GpioCfgOutput(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 */ 214HAL_BOOL 215ar5211GpioCfgInput(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 */ 232HAL_BOOL 233ar5211GpioSet(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 */ 250uint32_t 251ar5211GpioGet(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 */ 265void 266ar5211GpioSetIntr(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 */ 288void 289ar5211SetLedState(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 */ 314void 315ar5211WriteAssocid(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 */ 329uint64_t 330ar5211GetTsf64(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 */ 357uint32_t 358ar5211GetTsf32(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 */ 366void 367ar5211ResetTsf(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 */ 378uint32_t 379ar5211GetRandomSeed(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 */ 393HAL_BOOL 394ar5211DetectCardPresent(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 */ 414void 415ar5211UpdateMibCounters(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 424HAL_BOOL 425ar5211SetSifsTime(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 442u_int 443ar5211GetSifsTime(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 449HAL_BOOL 450ar5211SetSlotTime(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 467u_int 468ar5211GetSlotTime(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 474HAL_BOOL 475ar5211SetAckTimeout(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 493u_int 494ar5211GetAckTimeout(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 500u_int 501ar5211GetAckCTSRate(struct ath_hal *ah) 502{ 503 return ((AH5211(ah)->ah_staId1Defaults & AR_STA_ID1_ACKCTS_6MB) == 0); 504} 505 506HAL_BOOL 507ar5211SetAckCTSRate(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 521HAL_BOOL 522ar5211SetCTSTimeout(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 540u_int 541ar5211GetCTSTimeout(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 547HAL_BOOL 548ar5211SetDecompMask(struct ath_hal *ah, uint16_t keyidx, int en) 549{ 550 /* nothing to do */ 551 return AH_TRUE; 552} 553 554void 555ar5211SetCoverageClass(struct ath_hal *ah, uint8_t coverageclass, int now) 556{ 557} 558 559HAL_STATUS 560ar5211SetQuiet(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 */ 569HAL_BOOL 570ar5211AniControl(struct ath_hal *ah, HAL_ANI_CMD cmd, int param) 571{ 572 return AH_FALSE; 573} 574 575void 576ar5211AniPoll(struct ath_hal *ah, const struct ieee80211_channel *chan) 577{ 578} 579 580void 581ar5211RxMonitor(struct ath_hal *ah, const HAL_NODE_STATS *stats, 582 const struct ieee80211_channel *chan) 583{ 584} 585 586void 587ar5211MibEvent(struct ath_hal *ah, const HAL_NODE_STATS *stats) 588{ 589} 590 591/* 592 * Get the rssi of frame curently being received. 593 */ 594uint32_t 595ar5211GetCurRssi(struct ath_hal *ah) 596{ 597 return (OS_REG_READ(ah, AR_PHY_CURRENT_RSSI) & 0xff); 598} 599 600u_int 601ar5211GetDefAntenna(struct ath_hal *ah) 602{ 603 return (OS_REG_READ(ah, AR_DEF_ANTENNA) & 0x7); 604} 605 606void 607ar5211SetDefAntenna(struct ath_hal *ah, u_int antenna) 608{ 609 OS_REG_WRITE(ah, AR_DEF_ANTENNA, (antenna & 0x7)); 610} 611 612HAL_ANT_SETTING 613ar5211GetAntennaSwitch(struct ath_hal *ah) 614{ 615 return AH5211(ah)->ah_diversityControl; 616} 617 618HAL_BOOL 619ar5211SetAntennaSwitch(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 630HAL_STATUS 631ar5211GetCapability(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 650HAL_BOOL 651ar5211SetCapability(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 674HAL_BOOL 675ar5211GetDiagState(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 */ 705uint32_t 706ar5211Get11nExtBusy(struct ath_hal *ah) 707{ 708 return (0); 709} 710 711/* 712 * There's no channel survey support for the AR5211. 713 */ 714HAL_BOOL 715ar5211GetMibCycleCounts(struct ath_hal *ah, HAL_SURVEY_SAMPLE *hsample) 716{ 717 718 return (AH_FALSE); 719} 720 721void 722ar5211SetChainMasks(struct ath_hal *ah, uint32_t txchainmask, 723 uint32_t rxchainmask) 724{ 725} 726 727void 728ar5211EnableDfs(struct ath_hal *ah, HAL_PHYERR_PARAM *pe) 729{ 730} 731 732void 733ar5211GetDfsThresh(struct ath_hal *ah, HAL_PHYERR_PARAM *pe) 734{ 735} 736