1 /* 2 * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting 3 * Copyright (c) 2002-2008 Atheros Communications, Inc. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 * 17 * $FreeBSD$ 18 */ 19 #include "opt_ah.h" 20 21 #include "ah.h" 22 #include "ah_internal.h" 23 #include "ah_devid.h" 24 25 #include "ar5416/ar5416reg.h" /* NB: includes ar5212reg.h */ 26 27 /* linker set of registered chips */ 28 OS_SET_DECLARE(ah_chips, struct ath_hal_chip); 29 30 /* 31 * Check the set of registered chips to see if any recognize 32 * the device as one they can support. 33 */ 34 const char* 35 ath_hal_probe(uint16_t vendorid, uint16_t devid) 36 { 37 struct ath_hal_chip * const *pchip; 38 39 OS_SET_FOREACH(pchip, ah_chips) { 40 const char *name = (*pchip)->probe(vendorid, devid); 41 if (name != AH_NULL) 42 return name; 43 } 44 return AH_NULL; 45 } 46 47 /* 48 * Attach detects device chip revisions, initializes the hwLayer 49 * function list, reads EEPROM information, 50 * selects reset vectors, and performs a short self test. 51 * Any failures will return an error that should cause a hardware 52 * disable. 53 */ 54 struct ath_hal* 55 ath_hal_attach(uint16_t devid, HAL_SOFTC sc, 56 HAL_BUS_TAG st, HAL_BUS_HANDLE sh, HAL_STATUS *error) 57 { 58 struct ath_hal_chip * const *pchip; 59 60 OS_SET_FOREACH(pchip, ah_chips) { 61 struct ath_hal_chip *chip = *pchip; 62 struct ath_hal *ah; 63 64 /* XXX don't have vendorid, assume atheros one works */ 65 if (chip->probe(ATHEROS_VENDOR_ID, devid) == AH_NULL) 66 continue; 67 ah = chip->attach(devid, sc, st, sh, error); 68 if (ah != AH_NULL) { 69 /* copy back private state to public area */ 70 ah->ah_devid = AH_PRIVATE(ah)->ah_devid; 71 ah->ah_subvendorid = AH_PRIVATE(ah)->ah_subvendorid; 72 ah->ah_macVersion = AH_PRIVATE(ah)->ah_macVersion; 73 ah->ah_macRev = AH_PRIVATE(ah)->ah_macRev; 74 ah->ah_phyRev = AH_PRIVATE(ah)->ah_phyRev; 75 ah->ah_analog5GhzRev = AH_PRIVATE(ah)->ah_analog5GhzRev; 76 ah->ah_analog2GhzRev = AH_PRIVATE(ah)->ah_analog2GhzRev; 77 return ah; 78 } 79 } 80 return AH_NULL; 81 } 82 83 const char * 84 ath_hal_mac_name(struct ath_hal *ah) 85 { 86 switch (ah->ah_macVersion) { 87 case AR_SREV_VERSION_CRETE: 88 case AR_SREV_VERSION_MAUI_1: 89 return "5210"; 90 case AR_SREV_VERSION_MAUI_2: 91 case AR_SREV_VERSION_OAHU: 92 return "5211"; 93 case AR_SREV_VERSION_VENICE: 94 return "5212"; 95 case AR_SREV_VERSION_GRIFFIN: 96 return "2413"; 97 case AR_SREV_VERSION_CONDOR: 98 return "5424"; 99 case AR_SREV_VERSION_EAGLE: 100 return "5413"; 101 case AR_SREV_VERSION_COBRA: 102 return "2415"; 103 case AR_SREV_2425: 104 return "2425"; 105 case AR_SREV_2417: 106 return "2417"; 107 case AR_XSREV_VERSION_OWL_PCI: 108 return "5416"; 109 case AR_XSREV_VERSION_OWL_PCIE: 110 return "5418"; 111 case AR_XSREV_VERSION_SOWL: 112 return "9160"; 113 case AR_XSREV_VERSION_MERLIN: 114 return "9280"; 115 case AR_XSREV_VERSION_KITE: 116 return "9285"; 117 } 118 return "????"; 119 } 120 121 /* 122 * Return the mask of available modes based on the hardware capabilities. 123 */ 124 u_int 125 ath_hal_getwirelessmodes(struct ath_hal*ah) 126 { 127 return ath_hal_getWirelessModes(ah); 128 } 129 130 /* linker set of registered RF backends */ 131 OS_SET_DECLARE(ah_rfs, struct ath_hal_rf); 132 133 /* 134 * Check the set of registered RF backends to see if 135 * any recognize the device as one they can support. 136 */ 137 struct ath_hal_rf * 138 ath_hal_rfprobe(struct ath_hal *ah, HAL_STATUS *ecode) 139 { 140 struct ath_hal_rf * const *prf; 141 142 OS_SET_FOREACH(prf, ah_rfs) { 143 struct ath_hal_rf *rf = *prf; 144 if (rf->probe(ah)) 145 return rf; 146 } 147 *ecode = HAL_ENOTSUPP; 148 return AH_NULL; 149 } 150 151 const char * 152 ath_hal_rf_name(struct ath_hal *ah) 153 { 154 switch (ah->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR) { 155 case 0: /* 5210 */ 156 return "5110"; /* NB: made up */ 157 case AR_RAD5111_SREV_MAJOR: 158 case AR_RAD5111_SREV_PROD: 159 return "5111"; 160 case AR_RAD2111_SREV_MAJOR: 161 return "2111"; 162 case AR_RAD5112_SREV_MAJOR: 163 case AR_RAD5112_SREV_2_0: 164 case AR_RAD5112_SREV_2_1: 165 return "5112"; 166 case AR_RAD2112_SREV_MAJOR: 167 case AR_RAD2112_SREV_2_0: 168 case AR_RAD2112_SREV_2_1: 169 return "2112"; 170 case AR_RAD2413_SREV_MAJOR: 171 return "2413"; 172 case AR_RAD5413_SREV_MAJOR: 173 return "5413"; 174 case AR_RAD2316_SREV_MAJOR: 175 return "2316"; 176 case AR_RAD2317_SREV_MAJOR: 177 return "2317"; 178 case AR_RAD5424_SREV_MAJOR: 179 return "5424"; 180 181 case AR_RAD5133_SREV_MAJOR: 182 return "5133"; 183 case AR_RAD2133_SREV_MAJOR: 184 return "2133"; 185 case AR_RAD5122_SREV_MAJOR: 186 return "5122"; 187 case AR_RAD2122_SREV_MAJOR: 188 return "2122"; 189 } 190 return "????"; 191 } 192 193 /* 194 * Poll the register looking for a specific value. 195 */ 196 HAL_BOOL 197 ath_hal_wait(struct ath_hal *ah, u_int reg, uint32_t mask, uint32_t val) 198 { 199 #define AH_TIMEOUT 1000 200 int i; 201 202 for (i = 0; i < AH_TIMEOUT; i++) { 203 if ((OS_REG_READ(ah, reg) & mask) == val) 204 return AH_TRUE; 205 OS_DELAY(10); 206 } 207 HALDEBUG(ah, HAL_DEBUG_REGIO | HAL_DEBUG_PHYIO, 208 "%s: timeout on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n", 209 __func__, reg, OS_REG_READ(ah, reg), mask, val); 210 return AH_FALSE; 211 #undef AH_TIMEOUT 212 } 213 214 /* 215 * Reverse the bits starting at the low bit for a value of 216 * bit_count in size 217 */ 218 uint32_t 219 ath_hal_reverseBits(uint32_t val, uint32_t n) 220 { 221 uint32_t retval; 222 int i; 223 224 for (i = 0, retval = 0; i < n; i++) { 225 retval = (retval << 1) | (val & 1); 226 val >>= 1; 227 } 228 return retval; 229 } 230 231 /* 232 * Compute the time to transmit a frame of length frameLen bytes 233 * using the specified rate, phy, and short preamble setting. 234 */ 235 uint16_t 236 ath_hal_computetxtime(struct ath_hal *ah, 237 const HAL_RATE_TABLE *rates, uint32_t frameLen, uint16_t rateix, 238 HAL_BOOL shortPreamble) 239 { 240 uint32_t bitsPerSymbol, numBits, numSymbols, phyTime, txTime; 241 uint32_t kbps; 242 243 kbps = rates->info[rateix].rateKbps; 244 /* 245 * index can be invalid duting dynamic Turbo transitions. 246 * XXX 247 */ 248 if (kbps == 0) 249 return 0; 250 switch (rates->info[rateix].phy) { 251 case IEEE80211_T_CCK: 252 phyTime = CCK_PREAMBLE_BITS + CCK_PLCP_BITS; 253 if (shortPreamble && rates->info[rateix].shortPreamble) 254 phyTime >>= 1; 255 numBits = frameLen << 3; 256 txTime = CCK_SIFS_TIME + phyTime 257 + ((numBits * 1000)/kbps); 258 break; 259 case IEEE80211_T_OFDM: 260 bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME) / 1000; 261 HALASSERT(bitsPerSymbol != 0); 262 263 numBits = OFDM_PLCP_BITS + (frameLen << 3); 264 numSymbols = howmany(numBits, bitsPerSymbol); 265 txTime = OFDM_SIFS_TIME 266 + OFDM_PREAMBLE_TIME 267 + (numSymbols * OFDM_SYMBOL_TIME); 268 break; 269 case IEEE80211_T_OFDM_HALF: 270 bitsPerSymbol = (kbps * OFDM_HALF_SYMBOL_TIME) / 1000; 271 HALASSERT(bitsPerSymbol != 0); 272 273 numBits = OFDM_HALF_PLCP_BITS + (frameLen << 3); 274 numSymbols = howmany(numBits, bitsPerSymbol); 275 txTime = OFDM_HALF_SIFS_TIME 276 + OFDM_HALF_PREAMBLE_TIME 277 + (numSymbols * OFDM_HALF_SYMBOL_TIME); 278 break; 279 case IEEE80211_T_OFDM_QUARTER: 280 bitsPerSymbol = (kbps * OFDM_QUARTER_SYMBOL_TIME) / 1000; 281 HALASSERT(bitsPerSymbol != 0); 282 283 numBits = OFDM_QUARTER_PLCP_BITS + (frameLen << 3); 284 numSymbols = howmany(numBits, bitsPerSymbol); 285 txTime = OFDM_QUARTER_SIFS_TIME 286 + OFDM_QUARTER_PREAMBLE_TIME 287 + (numSymbols * OFDM_QUARTER_SYMBOL_TIME); 288 break; 289 case IEEE80211_T_TURBO: 290 /* we still save OFDM rates in kbps - so double them */ 291 bitsPerSymbol = ((kbps << 1) * TURBO_SYMBOL_TIME) / 1000; 292 HALASSERT(bitsPerSymbol != 0); 293 294 numBits = TURBO_PLCP_BITS + (frameLen << 3); 295 numSymbols = howmany(numBits, bitsPerSymbol); 296 txTime = TURBO_SIFS_TIME 297 + TURBO_PREAMBLE_TIME 298 + (numSymbols * TURBO_SYMBOL_TIME); 299 break; 300 default: 301 HALDEBUG(ah, HAL_DEBUG_PHYIO, 302 "%s: unknown phy %u (rate ix %u)\n", 303 __func__, rates->info[rateix].phy, rateix); 304 txTime = 0; 305 break; 306 } 307 return txTime; 308 } 309 310 typedef enum { 311 WIRELESS_MODE_11a = 0, 312 WIRELESS_MODE_TURBO = 1, 313 WIRELESS_MODE_11b = 2, 314 WIRELESS_MODE_11g = 3, 315 WIRELESS_MODE_108g = 4, 316 317 WIRELESS_MODE_MAX 318 } WIRELESS_MODE; 319 320 static WIRELESS_MODE 321 ath_hal_chan2wmode(struct ath_hal *ah, const struct ieee80211_channel *chan) 322 { 323 if (IEEE80211_IS_CHAN_B(chan)) 324 return WIRELESS_MODE_11b; 325 if (IEEE80211_IS_CHAN_G(chan)) 326 return WIRELESS_MODE_11g; 327 if (IEEE80211_IS_CHAN_108G(chan)) 328 return WIRELESS_MODE_108g; 329 if (IEEE80211_IS_CHAN_TURBO(chan)) 330 return WIRELESS_MODE_TURBO; 331 return WIRELESS_MODE_11a; 332 } 333 334 /* 335 * Convert between microseconds and core system clocks. 336 */ 337 /* 11a Turbo 11b 11g 108g */ 338 static const uint8_t CLOCK_RATE[] = { 40, 80, 22, 44, 88 }; 339 340 u_int 341 ath_hal_mac_clks(struct ath_hal *ah, u_int usecs) 342 { 343 const struct ieee80211_channel *c = AH_PRIVATE(ah)->ah_curchan; 344 u_int clks; 345 346 /* NB: ah_curchan may be null when called attach time */ 347 if (c != AH_NULL) { 348 clks = usecs * CLOCK_RATE[ath_hal_chan2wmode(ah, c)]; 349 if (IEEE80211_IS_CHAN_HT40(c)) 350 clks <<= 1; 351 } else 352 clks = usecs * CLOCK_RATE[WIRELESS_MODE_11b]; 353 return clks; 354 } 355 356 u_int 357 ath_hal_mac_usec(struct ath_hal *ah, u_int clks) 358 { 359 const struct ieee80211_channel *c = AH_PRIVATE(ah)->ah_curchan; 360 u_int usec; 361 362 /* NB: ah_curchan may be null when called attach time */ 363 if (c != AH_NULL) { 364 usec = clks / CLOCK_RATE[ath_hal_chan2wmode(ah, c)]; 365 if (IEEE80211_IS_CHAN_HT40(c)) 366 usec >>= 1; 367 } else 368 usec = clks / CLOCK_RATE[WIRELESS_MODE_11b]; 369 return usec; 370 } 371 372 /* 373 * Setup a h/w rate table's reverse lookup table and 374 * fill in ack durations. This routine is called for 375 * each rate table returned through the ah_getRateTable 376 * method. The reverse lookup tables are assumed to be 377 * initialized to zero (or at least the first entry). 378 * We use this as a key that indicates whether or not 379 * we've previously setup the reverse lookup table. 380 * 381 * XXX not reentrant, but shouldn't matter 382 */ 383 void 384 ath_hal_setupratetable(struct ath_hal *ah, HAL_RATE_TABLE *rt) 385 { 386 #define N(a) (sizeof(a)/sizeof(a[0])) 387 int i; 388 389 if (rt->rateCodeToIndex[0] != 0) /* already setup */ 390 return; 391 for (i = 0; i < N(rt->rateCodeToIndex); i++) 392 rt->rateCodeToIndex[i] = (uint8_t) -1; 393 for (i = 0; i < rt->rateCount; i++) { 394 uint8_t code = rt->info[i].rateCode; 395 uint8_t cix = rt->info[i].controlRate; 396 397 HALASSERT(code < N(rt->rateCodeToIndex)); 398 rt->rateCodeToIndex[code] = i; 399 HALASSERT((code | rt->info[i].shortPreamble) < 400 N(rt->rateCodeToIndex)); 401 rt->rateCodeToIndex[code | rt->info[i].shortPreamble] = i; 402 /* 403 * XXX for 11g the control rate to use for 5.5 and 11 Mb/s 404 * depends on whether they are marked as basic rates; 405 * the static tables are setup with an 11b-compatible 406 * 2Mb/s rate which will work but is suboptimal 407 */ 408 rt->info[i].lpAckDuration = ath_hal_computetxtime(ah, rt, 409 WLAN_CTRL_FRAME_SIZE, cix, AH_FALSE); 410 rt->info[i].spAckDuration = ath_hal_computetxtime(ah, rt, 411 WLAN_CTRL_FRAME_SIZE, cix, AH_TRUE); 412 } 413 #undef N 414 } 415 416 HAL_STATUS 417 ath_hal_getcapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type, 418 uint32_t capability, uint32_t *result) 419 { 420 const HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps; 421 422 switch (type) { 423 case HAL_CAP_REG_DMN: /* regulatory domain */ 424 *result = AH_PRIVATE(ah)->ah_currentRD; 425 return HAL_OK; 426 case HAL_CAP_CIPHER: /* cipher handled in hardware */ 427 case HAL_CAP_TKIP_MIC: /* handle TKIP MIC in hardware */ 428 return HAL_ENOTSUPP; 429 case HAL_CAP_TKIP_SPLIT: /* hardware TKIP uses split keys */ 430 return HAL_ENOTSUPP; 431 case HAL_CAP_PHYCOUNTERS: /* hardware PHY error counters */ 432 return pCap->halHwPhyCounterSupport ? HAL_OK : HAL_ENXIO; 433 case HAL_CAP_WME_TKIPMIC: /* hardware can do TKIP MIC when WMM is turned on */ 434 return HAL_ENOTSUPP; 435 case HAL_CAP_DIVERSITY: /* hardware supports fast diversity */ 436 return HAL_ENOTSUPP; 437 case HAL_CAP_KEYCACHE_SIZE: /* hardware key cache size */ 438 *result = pCap->halKeyCacheSize; 439 return HAL_OK; 440 case HAL_CAP_NUM_TXQUEUES: /* number of hardware tx queues */ 441 *result = pCap->halTotalQueues; 442 return HAL_OK; 443 case HAL_CAP_VEOL: /* hardware supports virtual EOL */ 444 return pCap->halVEOLSupport ? HAL_OK : HAL_ENOTSUPP; 445 case HAL_CAP_PSPOLL: /* hardware PS-Poll support works */ 446 return pCap->halPSPollBroken ? HAL_ENOTSUPP : HAL_OK; 447 case HAL_CAP_COMPRESSION: 448 return pCap->halCompressSupport ? HAL_OK : HAL_ENOTSUPP; 449 case HAL_CAP_BURST: 450 return pCap->halBurstSupport ? HAL_OK : HAL_ENOTSUPP; 451 case HAL_CAP_FASTFRAME: 452 return pCap->halFastFramesSupport ? HAL_OK : HAL_ENOTSUPP; 453 case HAL_CAP_DIAG: /* hardware diagnostic support */ 454 *result = AH_PRIVATE(ah)->ah_diagreg; 455 return HAL_OK; 456 case HAL_CAP_TXPOW: /* global tx power limit */ 457 switch (capability) { 458 case 0: /* facility is supported */ 459 return HAL_OK; 460 case 1: /* current limit */ 461 *result = AH_PRIVATE(ah)->ah_powerLimit; 462 return HAL_OK; 463 case 2: /* current max tx power */ 464 *result = AH_PRIVATE(ah)->ah_maxPowerLevel; 465 return HAL_OK; 466 case 3: /* scale factor */ 467 *result = AH_PRIVATE(ah)->ah_tpScale; 468 return HAL_OK; 469 } 470 return HAL_ENOTSUPP; 471 case HAL_CAP_BSSIDMASK: /* hardware supports bssid mask */ 472 return pCap->halBssIdMaskSupport ? HAL_OK : HAL_ENOTSUPP; 473 case HAL_CAP_MCAST_KEYSRCH: /* multicast frame keycache search */ 474 return pCap->halMcastKeySrchSupport ? HAL_OK : HAL_ENOTSUPP; 475 case HAL_CAP_TSF_ADJUST: /* hardware has beacon tsf adjust */ 476 return HAL_ENOTSUPP; 477 case HAL_CAP_RFSILENT: /* rfsilent support */ 478 switch (capability) { 479 case 0: /* facility is supported */ 480 return pCap->halRfSilentSupport ? HAL_OK : HAL_ENOTSUPP; 481 case 1: /* current setting */ 482 return AH_PRIVATE(ah)->ah_rfkillEnabled ? 483 HAL_OK : HAL_ENOTSUPP; 484 case 2: /* rfsilent config */ 485 *result = AH_PRIVATE(ah)->ah_rfsilent; 486 return HAL_OK; 487 } 488 return HAL_ENOTSUPP; 489 case HAL_CAP_11D: 490 return HAL_OK; 491 case HAL_CAP_RXORN_FATAL: /* HAL_INT_RXORN treated as fatal */ 492 return AH_PRIVATE(ah)->ah_rxornIsFatal ? HAL_OK : HAL_ENOTSUPP; 493 case HAL_CAP_HT: 494 return pCap->halHTSupport ? HAL_OK : HAL_ENOTSUPP; 495 case HAL_CAP_TX_CHAINMASK: /* mask of TX chains supported */ 496 *result = pCap->halTxChainMask; 497 return HAL_OK; 498 case HAL_CAP_RX_CHAINMASK: /* mask of RX chains supported */ 499 *result = pCap->halRxChainMask; 500 return HAL_OK; 501 case HAL_CAP_RXTSTAMP_PREC: /* rx desc tstamp precision (bits) */ 502 *result = pCap->halTstampPrecision; 503 return HAL_OK; 504 default: 505 return HAL_EINVAL; 506 } 507 } 508 509 HAL_BOOL 510 ath_hal_setcapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type, 511 uint32_t capability, uint32_t setting, HAL_STATUS *status) 512 { 513 514 switch (type) { 515 case HAL_CAP_TXPOW: 516 switch (capability) { 517 case 3: 518 if (setting <= HAL_TP_SCALE_MIN) { 519 AH_PRIVATE(ah)->ah_tpScale = setting; 520 return AH_TRUE; 521 } 522 break; 523 } 524 break; 525 case HAL_CAP_RFSILENT: /* rfsilent support */ 526 /* 527 * NB: allow even if halRfSilentSupport is false 528 * in case the EEPROM is misprogrammed. 529 */ 530 switch (capability) { 531 case 1: /* current setting */ 532 AH_PRIVATE(ah)->ah_rfkillEnabled = (setting != 0); 533 return AH_TRUE; 534 case 2: /* rfsilent config */ 535 /* XXX better done per-chip for validation? */ 536 AH_PRIVATE(ah)->ah_rfsilent = setting; 537 return AH_TRUE; 538 } 539 break; 540 case HAL_CAP_REG_DMN: /* regulatory domain */ 541 AH_PRIVATE(ah)->ah_currentRD = setting; 542 return AH_TRUE; 543 case HAL_CAP_RXORN_FATAL: /* HAL_INT_RXORN treated as fatal */ 544 AH_PRIVATE(ah)->ah_rxornIsFatal = setting; 545 return AH_TRUE; 546 default: 547 break; 548 } 549 if (status) 550 *status = HAL_EINVAL; 551 return AH_FALSE; 552 } 553 554 /* 555 * Common support for getDiagState method. 556 */ 557 558 static u_int 559 ath_hal_getregdump(struct ath_hal *ah, const HAL_REGRANGE *regs, 560 void *dstbuf, int space) 561 { 562 uint32_t *dp = dstbuf; 563 int i; 564 565 for (i = 0; space >= 2*sizeof(uint32_t); i++) { 566 u_int r = regs[i].start; 567 u_int e = regs[i].end; 568 *dp++ = (r<<16) | e; 569 space -= sizeof(uint32_t); 570 do { 571 *dp++ = OS_REG_READ(ah, r); 572 r += sizeof(uint32_t); 573 space -= sizeof(uint32_t); 574 } while (r <= e && space >= sizeof(uint32_t)); 575 } 576 return (char *) dp - (char *) dstbuf; 577 } 578 579 static void 580 ath_hal_setregs(struct ath_hal *ah, const HAL_REGWRITE *regs, int space) 581 { 582 while (space >= sizeof(HAL_REGWRITE)) { 583 OS_REG_WRITE(ah, regs->addr, regs->value); 584 regs++, space -= sizeof(HAL_REGWRITE); 585 } 586 } 587 588 HAL_BOOL 589 ath_hal_getdiagstate(struct ath_hal *ah, int request, 590 const void *args, uint32_t argsize, 591 void **result, uint32_t *resultsize) 592 { 593 switch (request) { 594 case HAL_DIAG_REVS: 595 *result = &AH_PRIVATE(ah)->ah_devid; 596 *resultsize = sizeof(HAL_REVS); 597 return AH_TRUE; 598 case HAL_DIAG_REGS: 599 *resultsize = ath_hal_getregdump(ah, args, *result,*resultsize); 600 return AH_TRUE; 601 case HAL_DIAG_SETREGS: 602 ath_hal_setregs(ah, args, argsize); 603 *resultsize = 0; 604 return AH_TRUE; 605 case HAL_DIAG_FATALERR: 606 *result = &AH_PRIVATE(ah)->ah_fatalState[0]; 607 *resultsize = sizeof(AH_PRIVATE(ah)->ah_fatalState); 608 return AH_TRUE; 609 case HAL_DIAG_EEREAD: 610 if (argsize != sizeof(uint16_t)) 611 return AH_FALSE; 612 if (!ath_hal_eepromRead(ah, *(const uint16_t *)args, *result)) 613 return AH_FALSE; 614 *resultsize = sizeof(uint16_t); 615 return AH_TRUE; 616 #ifdef AH_PRIVATE_DIAG 617 case HAL_DIAG_SETKEY: { 618 const HAL_DIAG_KEYVAL *dk; 619 620 if (argsize != sizeof(HAL_DIAG_KEYVAL)) 621 return AH_FALSE; 622 dk = (const HAL_DIAG_KEYVAL *)args; 623 return ah->ah_setKeyCacheEntry(ah, dk->dk_keyix, 624 &dk->dk_keyval, dk->dk_mac, dk->dk_xor); 625 } 626 case HAL_DIAG_RESETKEY: 627 if (argsize != sizeof(uint16_t)) 628 return AH_FALSE; 629 return ah->ah_resetKeyCacheEntry(ah, *(const uint16_t *)args); 630 #ifdef AH_SUPPORT_WRITE_EEPROM 631 case HAL_DIAG_EEWRITE: { 632 const HAL_DIAG_EEVAL *ee; 633 if (argsize != sizeof(HAL_DIAG_EEVAL)) 634 return AH_FALSE; 635 ee = (const HAL_DIAG_EEVAL *)args; 636 return ath_hal_eepromWrite(ah, ee->ee_off, ee->ee_data); 637 } 638 #endif /* AH_SUPPORT_WRITE_EEPROM */ 639 #endif /* AH_PRIVATE_DIAG */ 640 case HAL_DIAG_11NCOMPAT: 641 if (argsize == 0) { 642 *resultsize = sizeof(uint32_t); 643 *((uint32_t *)(*result)) = 644 AH_PRIVATE(ah)->ah_11nCompat; 645 } else if (argsize == sizeof(uint32_t)) { 646 AH_PRIVATE(ah)->ah_11nCompat = *(const uint32_t *)args; 647 } else 648 return AH_FALSE; 649 return AH_TRUE; 650 } 651 return AH_FALSE; 652 } 653 654 /* 655 * Set the properties of the tx queue with the parameters 656 * from qInfo. 657 */ 658 HAL_BOOL 659 ath_hal_setTxQProps(struct ath_hal *ah, 660 HAL_TX_QUEUE_INFO *qi, const HAL_TXQ_INFO *qInfo) 661 { 662 uint32_t cw; 663 664 if (qi->tqi_type == HAL_TX_QUEUE_INACTIVE) { 665 HALDEBUG(ah, HAL_DEBUG_TXQUEUE, 666 "%s: inactive queue\n", __func__); 667 return AH_FALSE; 668 } 669 /* XXX validate parameters */ 670 qi->tqi_ver = qInfo->tqi_ver; 671 qi->tqi_subtype = qInfo->tqi_subtype; 672 qi->tqi_qflags = qInfo->tqi_qflags; 673 qi->tqi_priority = qInfo->tqi_priority; 674 if (qInfo->tqi_aifs != HAL_TXQ_USEDEFAULT) 675 qi->tqi_aifs = AH_MIN(qInfo->tqi_aifs, 255); 676 else 677 qi->tqi_aifs = INIT_AIFS; 678 if (qInfo->tqi_cwmin != HAL_TXQ_USEDEFAULT) { 679 cw = AH_MIN(qInfo->tqi_cwmin, 1024); 680 /* make sure that the CWmin is of the form (2^n - 1) */ 681 qi->tqi_cwmin = 1; 682 while (qi->tqi_cwmin < cw) 683 qi->tqi_cwmin = (qi->tqi_cwmin << 1) | 1; 684 } else 685 qi->tqi_cwmin = qInfo->tqi_cwmin; 686 if (qInfo->tqi_cwmax != HAL_TXQ_USEDEFAULT) { 687 cw = AH_MIN(qInfo->tqi_cwmax, 1024); 688 /* make sure that the CWmax is of the form (2^n - 1) */ 689 qi->tqi_cwmax = 1; 690 while (qi->tqi_cwmax < cw) 691 qi->tqi_cwmax = (qi->tqi_cwmax << 1) | 1; 692 } else 693 qi->tqi_cwmax = INIT_CWMAX; 694 /* Set retry limit values */ 695 if (qInfo->tqi_shretry != 0) 696 qi->tqi_shretry = AH_MIN(qInfo->tqi_shretry, 15); 697 else 698 qi->tqi_shretry = INIT_SH_RETRY; 699 if (qInfo->tqi_lgretry != 0) 700 qi->tqi_lgretry = AH_MIN(qInfo->tqi_lgretry, 15); 701 else 702 qi->tqi_lgretry = INIT_LG_RETRY; 703 qi->tqi_cbrPeriod = qInfo->tqi_cbrPeriod; 704 qi->tqi_cbrOverflowLimit = qInfo->tqi_cbrOverflowLimit; 705 qi->tqi_burstTime = qInfo->tqi_burstTime; 706 qi->tqi_readyTime = qInfo->tqi_readyTime; 707 708 switch (qInfo->tqi_subtype) { 709 case HAL_WME_UPSD: 710 if (qi->tqi_type == HAL_TX_QUEUE_DATA) 711 qi->tqi_intFlags = HAL_TXQ_USE_LOCKOUT_BKOFF_DIS; 712 break; 713 default: 714 break; /* NB: silence compiler */ 715 } 716 return AH_TRUE; 717 } 718 719 HAL_BOOL 720 ath_hal_getTxQProps(struct ath_hal *ah, 721 HAL_TXQ_INFO *qInfo, const HAL_TX_QUEUE_INFO *qi) 722 { 723 if (qi->tqi_type == HAL_TX_QUEUE_INACTIVE) { 724 HALDEBUG(ah, HAL_DEBUG_TXQUEUE, 725 "%s: inactive queue\n", __func__); 726 return AH_FALSE; 727 } 728 729 qInfo->tqi_qflags = qi->tqi_qflags; 730 qInfo->tqi_ver = qi->tqi_ver; 731 qInfo->tqi_subtype = qi->tqi_subtype; 732 qInfo->tqi_qflags = qi->tqi_qflags; 733 qInfo->tqi_priority = qi->tqi_priority; 734 qInfo->tqi_aifs = qi->tqi_aifs; 735 qInfo->tqi_cwmin = qi->tqi_cwmin; 736 qInfo->tqi_cwmax = qi->tqi_cwmax; 737 qInfo->tqi_shretry = qi->tqi_shretry; 738 qInfo->tqi_lgretry = qi->tqi_lgretry; 739 qInfo->tqi_cbrPeriod = qi->tqi_cbrPeriod; 740 qInfo->tqi_cbrOverflowLimit = qi->tqi_cbrOverflowLimit; 741 qInfo->tqi_burstTime = qi->tqi_burstTime; 742 qInfo->tqi_readyTime = qi->tqi_readyTime; 743 return AH_TRUE; 744 } 745 746 /* 11a Turbo 11b 11g 108g */ 747 static const int16_t NOISE_FLOOR[] = { -96, -93, -98, -96, -93 }; 748 749 /* 750 * Read the current channel noise floor and return. 751 * If nf cal hasn't finished, channel noise floor should be 0 752 * and we return a nominal value based on band and frequency. 753 * 754 * NB: This is a private routine used by per-chip code to 755 * implement the ah_getChanNoise method. 756 */ 757 int16_t 758 ath_hal_getChanNoise(struct ath_hal *ah, const struct ieee80211_channel *chan) 759 { 760 HAL_CHANNEL_INTERNAL *ichan; 761 762 ichan = ath_hal_checkchannel(ah, chan); 763 if (ichan == AH_NULL) { 764 HALDEBUG(ah, HAL_DEBUG_NFCAL, 765 "%s: invalid channel %u/0x%x; no mapping\n", 766 __func__, chan->ic_freq, chan->ic_flags); 767 return 0; 768 } 769 if (ichan->rawNoiseFloor == 0) { 770 WIRELESS_MODE mode = ath_hal_chan2wmode(ah, chan); 771 772 HALASSERT(mode < WIRELESS_MODE_MAX); 773 return NOISE_FLOOR[mode] + ath_hal_getNfAdjust(ah, ichan); 774 } else 775 return ichan->rawNoiseFloor + ichan->noiseFloorAdjust; 776 } 777 778 /* 779 * Process all valid raw noise floors into the dBm noise floor values. 780 * Though our device has no reference for a dBm noise floor, we perform 781 * a relative minimization of NF's based on the lowest NF found across a 782 * channel scan. 783 */ 784 void 785 ath_hal_process_noisefloor(struct ath_hal *ah) 786 { 787 HAL_CHANNEL_INTERNAL *c; 788 int16_t correct2, correct5; 789 int16_t lowest2, lowest5; 790 int i; 791 792 /* 793 * Find the lowest 2GHz and 5GHz noise floor values after adjusting 794 * for statistically recorded NF/channel deviation. 795 */ 796 correct2 = lowest2 = 0; 797 correct5 = lowest5 = 0; 798 for (i = 0; i < AH_PRIVATE(ah)->ah_nchan; i++) { 799 WIRELESS_MODE mode; 800 int16_t nf; 801 802 c = &AH_PRIVATE(ah)->ah_channels[i]; 803 if (c->rawNoiseFloor >= 0) 804 continue; 805 /* XXX can't identify proper mode */ 806 mode = IS_CHAN_5GHZ(c) ? WIRELESS_MODE_11a : WIRELESS_MODE_11g; 807 nf = c->rawNoiseFloor + NOISE_FLOOR[mode] + 808 ath_hal_getNfAdjust(ah, c); 809 if (IS_CHAN_5GHZ(c)) { 810 if (nf < lowest5) { 811 lowest5 = nf; 812 correct5 = NOISE_FLOOR[mode] - 813 (c->rawNoiseFloor + ath_hal_getNfAdjust(ah, c)); 814 } 815 } else { 816 if (nf < lowest2) { 817 lowest2 = nf; 818 correct2 = NOISE_FLOOR[mode] - 819 (c->rawNoiseFloor + ath_hal_getNfAdjust(ah, c)); 820 } 821 } 822 } 823 824 /* Correct the channels to reach the expected NF value */ 825 for (i = 0; i < AH_PRIVATE(ah)->ah_nchan; i++) { 826 c = &AH_PRIVATE(ah)->ah_channels[i]; 827 if (c->rawNoiseFloor >= 0) 828 continue; 829 /* Apply correction factor */ 830 c->noiseFloorAdjust = ath_hal_getNfAdjust(ah, c) + 831 (IS_CHAN_5GHZ(c) ? correct5 : correct2); 832 HALDEBUG(ah, HAL_DEBUG_NFCAL, "%u raw nf %d adjust %d\n", 833 c->channel, c->rawNoiseFloor, c->noiseFloorAdjust); 834 } 835 } 836 837 /* 838 * INI support routines. 839 */ 840 841 int 842 ath_hal_ini_write(struct ath_hal *ah, const HAL_INI_ARRAY *ia, 843 int col, int regWr) 844 { 845 int r; 846 847 for (r = 0; r < ia->rows; r++) { 848 OS_REG_WRITE(ah, HAL_INI_VAL(ia, r, 0), 849 HAL_INI_VAL(ia, r, col)); 850 DMA_YIELD(regWr); 851 } 852 return regWr; 853 } 854 855 void 856 ath_hal_ini_bank_setup(uint32_t data[], const HAL_INI_ARRAY *ia, int col) 857 { 858 int r; 859 860 for (r = 0; r < ia->rows; r++) 861 data[r] = HAL_INI_VAL(ia, r, col); 862 } 863 864 int 865 ath_hal_ini_bank_write(struct ath_hal *ah, const HAL_INI_ARRAY *ia, 866 const uint32_t data[], int regWr) 867 { 868 int r; 869 870 for (r = 0; r < ia->rows; r++) { 871 OS_REG_WRITE(ah, HAL_INI_VAL(ia, r, 0), data[r]); 872 DMA_YIELD(regWr); 873 } 874 return regWr; 875 } 876