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, uint16_t *eepromdata, 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, eepromdata, 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 return ath_hal_waitfor(ah, reg, mask, val, AH_TIMEOUT); 201 #undef AH_TIMEOUT 202 } 203 204 HAL_BOOL 205 ath_hal_waitfor(struct ath_hal *ah, u_int reg, uint32_t mask, uint32_t val, uint32_t timeout) 206 { 207 int i; 208 209 for (i = 0; i < timeout; i++) { 210 if ((OS_REG_READ(ah, reg) & mask) == val) 211 return AH_TRUE; 212 OS_DELAY(10); 213 } 214 HALDEBUG(ah, HAL_DEBUG_REGIO | HAL_DEBUG_PHYIO, 215 "%s: timeout on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n", 216 __func__, reg, OS_REG_READ(ah, reg), mask, val); 217 return AH_FALSE; 218 } 219 220 /* 221 * Reverse the bits starting at the low bit for a value of 222 * bit_count in size 223 */ 224 uint32_t 225 ath_hal_reverseBits(uint32_t val, uint32_t n) 226 { 227 uint32_t retval; 228 int i; 229 230 for (i = 0, retval = 0; i < n; i++) { 231 retval = (retval << 1) | (val & 1); 232 val >>= 1; 233 } 234 return retval; 235 } 236 237 /* 802.11n related timing definitions */ 238 239 #define OFDM_PLCP_BITS 22 240 #define HT_L_STF 8 241 #define HT_L_LTF 8 242 #define HT_L_SIG 4 243 #define HT_SIG 8 244 #define HT_STF 4 245 #define HT_LTF(n) ((n) * 4) 246 247 #define HT_RC_2_MCS(_rc) ((_rc) & 0xf) 248 #define HT_RC_2_STREAMS(_rc) ((((_rc) & 0x78) >> 3) + 1) 249 #define IS_HT_RATE(_rc) ( (_rc) & IEEE80211_RATE_MCS) 250 251 /* 252 * Calculate the duration of a packet whether it is 11n or legacy. 253 */ 254 uint32_t 255 ath_hal_pkt_txtime(struct ath_hal *ah, const HAL_RATE_TABLE *rates, uint32_t frameLen, 256 uint16_t rateix, HAL_BOOL isht40, HAL_BOOL shortPreamble) 257 { 258 uint8_t rc; 259 int numStreams; 260 261 rc = rates->info[rateix].rateCode; 262 263 /* Legacy rate? Return the old way */ 264 if (! IS_HT_RATE(rc)) 265 return ath_hal_computetxtime(ah, rates, frameLen, rateix, shortPreamble); 266 267 /* 11n frame - extract out the number of spatial streams */ 268 numStreams = HT_RC_2_STREAMS(rc); 269 KASSERT(numStreams == 1 || numStreams == 2, ("number of spatial streams needs to be 1 or 2: MCS rate 0x%x!", rateix)); 270 271 return ath_computedur_ht(frameLen, rc, numStreams, isht40, shortPreamble); 272 } 273 274 /* 275 * Calculate the transmit duration of an 11n frame. 276 * This only works for MCS0->MCS15. 277 */ 278 uint32_t 279 ath_computedur_ht(uint32_t frameLen, uint16_t rate, int streams, HAL_BOOL isht40, 280 HAL_BOOL isShortGI) 281 { 282 static const uint16_t ht20_bps[16] = { 283 26, 52, 78, 104, 156, 208, 234, 260, 284 52, 104, 156, 208, 312, 416, 468, 520 285 }; 286 static const uint16_t ht40_bps[16] = { 287 54, 108, 162, 216, 324, 432, 486, 540, 288 108, 216, 324, 432, 648, 864, 972, 1080, 289 }; 290 uint32_t bitsPerSymbol, numBits, numSymbols, txTime; 291 292 KASSERT(rate & IEEE80211_RATE_MCS, ("not mcs %d", rate)); 293 KASSERT((rate &~ IEEE80211_RATE_MCS) < 16, ("bad mcs 0x%x", rate)); 294 295 if (isht40) 296 bitsPerSymbol = ht40_bps[rate & 0xf]; 297 else 298 bitsPerSymbol = ht20_bps[rate & 0xf]; 299 numBits = OFDM_PLCP_BITS + (frameLen << 3); 300 numSymbols = howmany(numBits, bitsPerSymbol); 301 if (isShortGI) 302 txTime = ((numSymbols * 18) + 4) / 5; /* 3.6us */ 303 else 304 txTime = numSymbols * 4; /* 4us */ 305 return txTime + HT_L_STF + HT_L_LTF + 306 HT_L_SIG + HT_SIG + HT_STF + HT_LTF(streams); 307 } 308 309 /* 310 * Compute the time to transmit a frame of length frameLen bytes 311 * using the specified rate, phy, and short preamble setting. 312 */ 313 uint16_t 314 ath_hal_computetxtime(struct ath_hal *ah, 315 const HAL_RATE_TABLE *rates, uint32_t frameLen, uint16_t rateix, 316 HAL_BOOL shortPreamble) 317 { 318 uint32_t bitsPerSymbol, numBits, numSymbols, phyTime, txTime; 319 uint32_t kbps; 320 321 /* Warn if this function is called for 11n rates; it should not be! */ 322 if (IS_HT_RATE(rates->info[rateix].rateCode)) 323 ath_hal_printf(ah, "%s: MCS rate? (index %d; hwrate 0x%x)\n", 324 __func__, rateix, rates->info[rateix].rateCode); 325 326 kbps = rates->info[rateix].rateKbps; 327 /* 328 * index can be invalid duting dynamic Turbo transitions. 329 * XXX 330 */ 331 if (kbps == 0) 332 return 0; 333 switch (rates->info[rateix].phy) { 334 case IEEE80211_T_CCK: 335 phyTime = CCK_PREAMBLE_BITS + CCK_PLCP_BITS; 336 if (shortPreamble && rates->info[rateix].shortPreamble) 337 phyTime >>= 1; 338 numBits = frameLen << 3; 339 txTime = CCK_SIFS_TIME + phyTime 340 + ((numBits * 1000)/kbps); 341 break; 342 case IEEE80211_T_OFDM: 343 bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME) / 1000; 344 HALASSERT(bitsPerSymbol != 0); 345 346 numBits = OFDM_PLCP_BITS + (frameLen << 3); 347 numSymbols = howmany(numBits, bitsPerSymbol); 348 txTime = OFDM_SIFS_TIME 349 + OFDM_PREAMBLE_TIME 350 + (numSymbols * OFDM_SYMBOL_TIME); 351 break; 352 case IEEE80211_T_OFDM_HALF: 353 bitsPerSymbol = (kbps * OFDM_HALF_SYMBOL_TIME) / 1000; 354 HALASSERT(bitsPerSymbol != 0); 355 356 numBits = OFDM_HALF_PLCP_BITS + (frameLen << 3); 357 numSymbols = howmany(numBits, bitsPerSymbol); 358 txTime = OFDM_HALF_SIFS_TIME 359 + OFDM_HALF_PREAMBLE_TIME 360 + (numSymbols * OFDM_HALF_SYMBOL_TIME); 361 break; 362 case IEEE80211_T_OFDM_QUARTER: 363 bitsPerSymbol = (kbps * OFDM_QUARTER_SYMBOL_TIME) / 1000; 364 HALASSERT(bitsPerSymbol != 0); 365 366 numBits = OFDM_QUARTER_PLCP_BITS + (frameLen << 3); 367 numSymbols = howmany(numBits, bitsPerSymbol); 368 txTime = OFDM_QUARTER_SIFS_TIME 369 + OFDM_QUARTER_PREAMBLE_TIME 370 + (numSymbols * OFDM_QUARTER_SYMBOL_TIME); 371 break; 372 case IEEE80211_T_TURBO: 373 bitsPerSymbol = (kbps * TURBO_SYMBOL_TIME) / 1000; 374 HALASSERT(bitsPerSymbol != 0); 375 376 numBits = TURBO_PLCP_BITS + (frameLen << 3); 377 numSymbols = howmany(numBits, bitsPerSymbol); 378 txTime = TURBO_SIFS_TIME 379 + TURBO_PREAMBLE_TIME 380 + (numSymbols * TURBO_SYMBOL_TIME); 381 break; 382 default: 383 HALDEBUG(ah, HAL_DEBUG_PHYIO, 384 "%s: unknown phy %u (rate ix %u)\n", 385 __func__, rates->info[rateix].phy, rateix); 386 txTime = 0; 387 break; 388 } 389 return txTime; 390 } 391 392 typedef enum { 393 WIRELESS_MODE_11a = 0, 394 WIRELESS_MODE_TURBO = 1, 395 WIRELESS_MODE_11b = 2, 396 WIRELESS_MODE_11g = 3, 397 WIRELESS_MODE_108g = 4, 398 399 WIRELESS_MODE_MAX 400 } WIRELESS_MODE; 401 402 static WIRELESS_MODE 403 ath_hal_chan2wmode(struct ath_hal *ah, const struct ieee80211_channel *chan) 404 { 405 if (IEEE80211_IS_CHAN_B(chan)) 406 return WIRELESS_MODE_11b; 407 if (IEEE80211_IS_CHAN_G(chan)) 408 return WIRELESS_MODE_11g; 409 if (IEEE80211_IS_CHAN_108G(chan)) 410 return WIRELESS_MODE_108g; 411 if (IEEE80211_IS_CHAN_TURBO(chan)) 412 return WIRELESS_MODE_TURBO; 413 return WIRELESS_MODE_11a; 414 } 415 416 /* 417 * Convert between microseconds and core system clocks. 418 */ 419 /* 11a Turbo 11b 11g 108g */ 420 static const uint8_t CLOCK_RATE[] = { 40, 80, 22, 44, 88 }; 421 422 u_int 423 ath_hal_mac_clks(struct ath_hal *ah, u_int usecs) 424 { 425 const struct ieee80211_channel *c = AH_PRIVATE(ah)->ah_curchan; 426 u_int clks; 427 428 /* NB: ah_curchan may be null when called attach time */ 429 if (c != AH_NULL) { 430 clks = usecs * CLOCK_RATE[ath_hal_chan2wmode(ah, c)]; 431 if (IEEE80211_IS_CHAN_HT40(c)) 432 clks <<= 1; 433 } else 434 clks = usecs * CLOCK_RATE[WIRELESS_MODE_11b]; 435 return clks; 436 } 437 438 u_int 439 ath_hal_mac_usec(struct ath_hal *ah, u_int clks) 440 { 441 const struct ieee80211_channel *c = AH_PRIVATE(ah)->ah_curchan; 442 u_int usec; 443 444 /* NB: ah_curchan may be null when called attach time */ 445 if (c != AH_NULL) { 446 usec = clks / CLOCK_RATE[ath_hal_chan2wmode(ah, c)]; 447 if (IEEE80211_IS_CHAN_HT40(c)) 448 usec >>= 1; 449 } else 450 usec = clks / CLOCK_RATE[WIRELESS_MODE_11b]; 451 return usec; 452 } 453 454 /* 455 * Setup a h/w rate table's reverse lookup table and 456 * fill in ack durations. This routine is called for 457 * each rate table returned through the ah_getRateTable 458 * method. The reverse lookup tables are assumed to be 459 * initialized to zero (or at least the first entry). 460 * We use this as a key that indicates whether or not 461 * we've previously setup the reverse lookup table. 462 * 463 * XXX not reentrant, but shouldn't matter 464 */ 465 void 466 ath_hal_setupratetable(struct ath_hal *ah, HAL_RATE_TABLE *rt) 467 { 468 #define N(a) (sizeof(a)/sizeof(a[0])) 469 int i; 470 471 if (rt->rateCodeToIndex[0] != 0) /* already setup */ 472 return; 473 for (i = 0; i < N(rt->rateCodeToIndex); i++) 474 rt->rateCodeToIndex[i] = (uint8_t) -1; 475 for (i = 0; i < rt->rateCount; i++) { 476 uint8_t code = rt->info[i].rateCode; 477 uint8_t cix = rt->info[i].controlRate; 478 479 HALASSERT(code < N(rt->rateCodeToIndex)); 480 rt->rateCodeToIndex[code] = i; 481 HALASSERT((code | rt->info[i].shortPreamble) < 482 N(rt->rateCodeToIndex)); 483 rt->rateCodeToIndex[code | rt->info[i].shortPreamble] = i; 484 /* 485 * XXX for 11g the control rate to use for 5.5 and 11 Mb/s 486 * depends on whether they are marked as basic rates; 487 * the static tables are setup with an 11b-compatible 488 * 2Mb/s rate which will work but is suboptimal 489 */ 490 rt->info[i].lpAckDuration = ath_hal_computetxtime(ah, rt, 491 WLAN_CTRL_FRAME_SIZE, cix, AH_FALSE); 492 rt->info[i].spAckDuration = ath_hal_computetxtime(ah, rt, 493 WLAN_CTRL_FRAME_SIZE, cix, AH_TRUE); 494 } 495 #undef N 496 } 497 498 HAL_STATUS 499 ath_hal_getcapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type, 500 uint32_t capability, uint32_t *result) 501 { 502 const HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps; 503 504 switch (type) { 505 case HAL_CAP_REG_DMN: /* regulatory domain */ 506 *result = AH_PRIVATE(ah)->ah_currentRD; 507 return HAL_OK; 508 case HAL_CAP_CIPHER: /* cipher handled in hardware */ 509 case HAL_CAP_TKIP_MIC: /* handle TKIP MIC in hardware */ 510 return HAL_ENOTSUPP; 511 case HAL_CAP_TKIP_SPLIT: /* hardware TKIP uses split keys */ 512 return HAL_ENOTSUPP; 513 case HAL_CAP_PHYCOUNTERS: /* hardware PHY error counters */ 514 return pCap->halHwPhyCounterSupport ? HAL_OK : HAL_ENXIO; 515 case HAL_CAP_WME_TKIPMIC: /* hardware can do TKIP MIC when WMM is turned on */ 516 return HAL_ENOTSUPP; 517 case HAL_CAP_DIVERSITY: /* hardware supports fast diversity */ 518 return HAL_ENOTSUPP; 519 case HAL_CAP_KEYCACHE_SIZE: /* hardware key cache size */ 520 *result = pCap->halKeyCacheSize; 521 return HAL_OK; 522 case HAL_CAP_NUM_TXQUEUES: /* number of hardware tx queues */ 523 *result = pCap->halTotalQueues; 524 return HAL_OK; 525 case HAL_CAP_VEOL: /* hardware supports virtual EOL */ 526 return pCap->halVEOLSupport ? HAL_OK : HAL_ENOTSUPP; 527 case HAL_CAP_PSPOLL: /* hardware PS-Poll support works */ 528 return pCap->halPSPollBroken ? HAL_ENOTSUPP : HAL_OK; 529 case HAL_CAP_COMPRESSION: 530 return pCap->halCompressSupport ? HAL_OK : HAL_ENOTSUPP; 531 case HAL_CAP_BURST: 532 return pCap->halBurstSupport ? HAL_OK : HAL_ENOTSUPP; 533 case HAL_CAP_FASTFRAME: 534 return pCap->halFastFramesSupport ? HAL_OK : HAL_ENOTSUPP; 535 case HAL_CAP_DIAG: /* hardware diagnostic support */ 536 *result = AH_PRIVATE(ah)->ah_diagreg; 537 return HAL_OK; 538 case HAL_CAP_TXPOW: /* global tx power limit */ 539 switch (capability) { 540 case 0: /* facility is supported */ 541 return HAL_OK; 542 case 1: /* current limit */ 543 *result = AH_PRIVATE(ah)->ah_powerLimit; 544 return HAL_OK; 545 case 2: /* current max tx power */ 546 *result = AH_PRIVATE(ah)->ah_maxPowerLevel; 547 return HAL_OK; 548 case 3: /* scale factor */ 549 *result = AH_PRIVATE(ah)->ah_tpScale; 550 return HAL_OK; 551 } 552 return HAL_ENOTSUPP; 553 case HAL_CAP_BSSIDMASK: /* hardware supports bssid mask */ 554 return pCap->halBssIdMaskSupport ? HAL_OK : HAL_ENOTSUPP; 555 case HAL_CAP_MCAST_KEYSRCH: /* multicast frame keycache search */ 556 return pCap->halMcastKeySrchSupport ? HAL_OK : HAL_ENOTSUPP; 557 case HAL_CAP_TSF_ADJUST: /* hardware has beacon tsf adjust */ 558 return HAL_ENOTSUPP; 559 case HAL_CAP_RFSILENT: /* rfsilent support */ 560 switch (capability) { 561 case 0: /* facility is supported */ 562 return pCap->halRfSilentSupport ? HAL_OK : HAL_ENOTSUPP; 563 case 1: /* current setting */ 564 return AH_PRIVATE(ah)->ah_rfkillEnabled ? 565 HAL_OK : HAL_ENOTSUPP; 566 case 2: /* rfsilent config */ 567 *result = AH_PRIVATE(ah)->ah_rfsilent; 568 return HAL_OK; 569 } 570 return HAL_ENOTSUPP; 571 case HAL_CAP_11D: 572 return HAL_OK; 573 case HAL_CAP_RXORN_FATAL: /* HAL_INT_RXORN treated as fatal */ 574 return AH_PRIVATE(ah)->ah_rxornIsFatal ? HAL_OK : HAL_ENOTSUPP; 575 case HAL_CAP_HT: 576 return pCap->halHTSupport ? HAL_OK : HAL_ENOTSUPP; 577 case HAL_CAP_TX_CHAINMASK: /* mask of TX chains supported */ 578 *result = pCap->halTxChainMask; 579 return HAL_OK; 580 case HAL_CAP_RX_CHAINMASK: /* mask of RX chains supported */ 581 *result = pCap->halRxChainMask; 582 return HAL_OK; 583 case HAL_CAP_RXTSTAMP_PREC: /* rx desc tstamp precision (bits) */ 584 *result = pCap->halTstampPrecision; 585 return HAL_OK; 586 case HAL_CAP_INTRMASK: /* mask of supported interrupts */ 587 *result = pCap->halIntrMask; 588 return HAL_OK; 589 case HAL_CAP_BSSIDMATCH: /* hardware has disable bssid match */ 590 return pCap->halBssidMatchSupport ? HAL_OK : HAL_ENOTSUPP; 591 case HAL_CAP_STREAMS: /* number of 11n spatial streams */ 592 switch (capability) { 593 case 0: /* TX */ 594 *result = pCap->halTxStreams; 595 return HAL_OK; 596 case 1: /* RX */ 597 *result = pCap->halRxStreams; 598 return HAL_OK; 599 default: 600 return HAL_ENOTSUPP; 601 } 602 case HAP_CAP_SPLIT_4KB_TRANS: /* hardware handles descriptors straddling 4k page boundary */ 603 return pCap->hal4kbSplitTransSupport ? HAL_OK : HAL_ENOTSUPP; 604 default: 605 return HAL_EINVAL; 606 } 607 } 608 609 HAL_BOOL 610 ath_hal_setcapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type, 611 uint32_t capability, uint32_t setting, HAL_STATUS *status) 612 { 613 614 switch (type) { 615 case HAL_CAP_TXPOW: 616 switch (capability) { 617 case 3: 618 if (setting <= HAL_TP_SCALE_MIN) { 619 AH_PRIVATE(ah)->ah_tpScale = setting; 620 return AH_TRUE; 621 } 622 break; 623 } 624 break; 625 case HAL_CAP_RFSILENT: /* rfsilent support */ 626 /* 627 * NB: allow even if halRfSilentSupport is false 628 * in case the EEPROM is misprogrammed. 629 */ 630 switch (capability) { 631 case 1: /* current setting */ 632 AH_PRIVATE(ah)->ah_rfkillEnabled = (setting != 0); 633 return AH_TRUE; 634 case 2: /* rfsilent config */ 635 /* XXX better done per-chip for validation? */ 636 AH_PRIVATE(ah)->ah_rfsilent = setting; 637 return AH_TRUE; 638 } 639 break; 640 case HAL_CAP_REG_DMN: /* regulatory domain */ 641 AH_PRIVATE(ah)->ah_currentRD = setting; 642 return AH_TRUE; 643 case HAL_CAP_RXORN_FATAL: /* HAL_INT_RXORN treated as fatal */ 644 AH_PRIVATE(ah)->ah_rxornIsFatal = setting; 645 return AH_TRUE; 646 default: 647 break; 648 } 649 if (status) 650 *status = HAL_EINVAL; 651 return AH_FALSE; 652 } 653 654 /* 655 * Common support for getDiagState method. 656 */ 657 658 static u_int 659 ath_hal_getregdump(struct ath_hal *ah, const HAL_REGRANGE *regs, 660 void *dstbuf, int space) 661 { 662 uint32_t *dp = dstbuf; 663 int i; 664 665 for (i = 0; space >= 2*sizeof(uint32_t); i++) { 666 u_int r = regs[i].start; 667 u_int e = regs[i].end; 668 *dp++ = (r<<16) | e; 669 space -= sizeof(uint32_t); 670 do { 671 *dp++ = OS_REG_READ(ah, r); 672 r += sizeof(uint32_t); 673 space -= sizeof(uint32_t); 674 } while (r <= e && space >= sizeof(uint32_t)); 675 } 676 return (char *) dp - (char *) dstbuf; 677 } 678 679 static void 680 ath_hal_setregs(struct ath_hal *ah, const HAL_REGWRITE *regs, int space) 681 { 682 while (space >= sizeof(HAL_REGWRITE)) { 683 OS_REG_WRITE(ah, regs->addr, regs->value); 684 regs++, space -= sizeof(HAL_REGWRITE); 685 } 686 } 687 688 HAL_BOOL 689 ath_hal_getdiagstate(struct ath_hal *ah, int request, 690 const void *args, uint32_t argsize, 691 void **result, uint32_t *resultsize) 692 { 693 switch (request) { 694 case HAL_DIAG_REVS: 695 *result = &AH_PRIVATE(ah)->ah_devid; 696 *resultsize = sizeof(HAL_REVS); 697 return AH_TRUE; 698 case HAL_DIAG_REGS: 699 *resultsize = ath_hal_getregdump(ah, args, *result,*resultsize); 700 return AH_TRUE; 701 case HAL_DIAG_SETREGS: 702 ath_hal_setregs(ah, args, argsize); 703 *resultsize = 0; 704 return AH_TRUE; 705 case HAL_DIAG_FATALERR: 706 *result = &AH_PRIVATE(ah)->ah_fatalState[0]; 707 *resultsize = sizeof(AH_PRIVATE(ah)->ah_fatalState); 708 return AH_TRUE; 709 case HAL_DIAG_EEREAD: 710 if (argsize != sizeof(uint16_t)) 711 return AH_FALSE; 712 if (!ath_hal_eepromRead(ah, *(const uint16_t *)args, *result)) 713 return AH_FALSE; 714 *resultsize = sizeof(uint16_t); 715 return AH_TRUE; 716 #ifdef AH_PRIVATE_DIAG 717 case HAL_DIAG_SETKEY: { 718 const HAL_DIAG_KEYVAL *dk; 719 720 if (argsize != sizeof(HAL_DIAG_KEYVAL)) 721 return AH_FALSE; 722 dk = (const HAL_DIAG_KEYVAL *)args; 723 return ah->ah_setKeyCacheEntry(ah, dk->dk_keyix, 724 &dk->dk_keyval, dk->dk_mac, dk->dk_xor); 725 } 726 case HAL_DIAG_RESETKEY: 727 if (argsize != sizeof(uint16_t)) 728 return AH_FALSE; 729 return ah->ah_resetKeyCacheEntry(ah, *(const uint16_t *)args); 730 #ifdef AH_SUPPORT_WRITE_EEPROM 731 case HAL_DIAG_EEWRITE: { 732 const HAL_DIAG_EEVAL *ee; 733 if (argsize != sizeof(HAL_DIAG_EEVAL)) 734 return AH_FALSE; 735 ee = (const HAL_DIAG_EEVAL *)args; 736 return ath_hal_eepromWrite(ah, ee->ee_off, ee->ee_data); 737 } 738 #endif /* AH_SUPPORT_WRITE_EEPROM */ 739 #endif /* AH_PRIVATE_DIAG */ 740 case HAL_DIAG_11NCOMPAT: 741 if (argsize == 0) { 742 *resultsize = sizeof(uint32_t); 743 *((uint32_t *)(*result)) = 744 AH_PRIVATE(ah)->ah_11nCompat; 745 } else if (argsize == sizeof(uint32_t)) { 746 AH_PRIVATE(ah)->ah_11nCompat = *(const uint32_t *)args; 747 } else 748 return AH_FALSE; 749 return AH_TRUE; 750 } 751 return AH_FALSE; 752 } 753 754 /* 755 * Set the properties of the tx queue with the parameters 756 * from qInfo. 757 */ 758 HAL_BOOL 759 ath_hal_setTxQProps(struct ath_hal *ah, 760 HAL_TX_QUEUE_INFO *qi, const HAL_TXQ_INFO *qInfo) 761 { 762 uint32_t cw; 763 764 if (qi->tqi_type == HAL_TX_QUEUE_INACTIVE) { 765 HALDEBUG(ah, HAL_DEBUG_TXQUEUE, 766 "%s: inactive queue\n", __func__); 767 return AH_FALSE; 768 } 769 /* XXX validate parameters */ 770 qi->tqi_ver = qInfo->tqi_ver; 771 qi->tqi_subtype = qInfo->tqi_subtype; 772 qi->tqi_qflags = qInfo->tqi_qflags; 773 qi->tqi_priority = qInfo->tqi_priority; 774 if (qInfo->tqi_aifs != HAL_TXQ_USEDEFAULT) 775 qi->tqi_aifs = AH_MIN(qInfo->tqi_aifs, 255); 776 else 777 qi->tqi_aifs = INIT_AIFS; 778 if (qInfo->tqi_cwmin != HAL_TXQ_USEDEFAULT) { 779 cw = AH_MIN(qInfo->tqi_cwmin, 1024); 780 /* make sure that the CWmin is of the form (2^n - 1) */ 781 qi->tqi_cwmin = 1; 782 while (qi->tqi_cwmin < cw) 783 qi->tqi_cwmin = (qi->tqi_cwmin << 1) | 1; 784 } else 785 qi->tqi_cwmin = qInfo->tqi_cwmin; 786 if (qInfo->tqi_cwmax != HAL_TXQ_USEDEFAULT) { 787 cw = AH_MIN(qInfo->tqi_cwmax, 1024); 788 /* make sure that the CWmax is of the form (2^n - 1) */ 789 qi->tqi_cwmax = 1; 790 while (qi->tqi_cwmax < cw) 791 qi->tqi_cwmax = (qi->tqi_cwmax << 1) | 1; 792 } else 793 qi->tqi_cwmax = INIT_CWMAX; 794 /* Set retry limit values */ 795 if (qInfo->tqi_shretry != 0) 796 qi->tqi_shretry = AH_MIN(qInfo->tqi_shretry, 15); 797 else 798 qi->tqi_shretry = INIT_SH_RETRY; 799 if (qInfo->tqi_lgretry != 0) 800 qi->tqi_lgretry = AH_MIN(qInfo->tqi_lgretry, 15); 801 else 802 qi->tqi_lgretry = INIT_LG_RETRY; 803 qi->tqi_cbrPeriod = qInfo->tqi_cbrPeriod; 804 qi->tqi_cbrOverflowLimit = qInfo->tqi_cbrOverflowLimit; 805 qi->tqi_burstTime = qInfo->tqi_burstTime; 806 qi->tqi_readyTime = qInfo->tqi_readyTime; 807 808 switch (qInfo->tqi_subtype) { 809 case HAL_WME_UPSD: 810 if (qi->tqi_type == HAL_TX_QUEUE_DATA) 811 qi->tqi_intFlags = HAL_TXQ_USE_LOCKOUT_BKOFF_DIS; 812 break; 813 default: 814 break; /* NB: silence compiler */ 815 } 816 return AH_TRUE; 817 } 818 819 HAL_BOOL 820 ath_hal_getTxQProps(struct ath_hal *ah, 821 HAL_TXQ_INFO *qInfo, const HAL_TX_QUEUE_INFO *qi) 822 { 823 if (qi->tqi_type == HAL_TX_QUEUE_INACTIVE) { 824 HALDEBUG(ah, HAL_DEBUG_TXQUEUE, 825 "%s: inactive queue\n", __func__); 826 return AH_FALSE; 827 } 828 829 qInfo->tqi_qflags = qi->tqi_qflags; 830 qInfo->tqi_ver = qi->tqi_ver; 831 qInfo->tqi_subtype = qi->tqi_subtype; 832 qInfo->tqi_qflags = qi->tqi_qflags; 833 qInfo->tqi_priority = qi->tqi_priority; 834 qInfo->tqi_aifs = qi->tqi_aifs; 835 qInfo->tqi_cwmin = qi->tqi_cwmin; 836 qInfo->tqi_cwmax = qi->tqi_cwmax; 837 qInfo->tqi_shretry = qi->tqi_shretry; 838 qInfo->tqi_lgretry = qi->tqi_lgretry; 839 qInfo->tqi_cbrPeriod = qi->tqi_cbrPeriod; 840 qInfo->tqi_cbrOverflowLimit = qi->tqi_cbrOverflowLimit; 841 qInfo->tqi_burstTime = qi->tqi_burstTime; 842 qInfo->tqi_readyTime = qi->tqi_readyTime; 843 return AH_TRUE; 844 } 845 846 /* 11a Turbo 11b 11g 108g */ 847 static const int16_t NOISE_FLOOR[] = { -96, -93, -98, -96, -93 }; 848 849 /* 850 * Read the current channel noise floor and return. 851 * If nf cal hasn't finished, channel noise floor should be 0 852 * and we return a nominal value based on band and frequency. 853 * 854 * NB: This is a private routine used by per-chip code to 855 * implement the ah_getChanNoise method. 856 */ 857 int16_t 858 ath_hal_getChanNoise(struct ath_hal *ah, const struct ieee80211_channel *chan) 859 { 860 HAL_CHANNEL_INTERNAL *ichan; 861 862 ichan = ath_hal_checkchannel(ah, chan); 863 if (ichan == AH_NULL) { 864 HALDEBUG(ah, HAL_DEBUG_NFCAL, 865 "%s: invalid channel %u/0x%x; no mapping\n", 866 __func__, chan->ic_freq, chan->ic_flags); 867 return 0; 868 } 869 if (ichan->rawNoiseFloor == 0) { 870 WIRELESS_MODE mode = ath_hal_chan2wmode(ah, chan); 871 872 HALASSERT(mode < WIRELESS_MODE_MAX); 873 return NOISE_FLOOR[mode] + ath_hal_getNfAdjust(ah, ichan); 874 } else 875 return ichan->rawNoiseFloor + ichan->noiseFloorAdjust; 876 } 877 878 /* 879 * Process all valid raw noise floors into the dBm noise floor values. 880 * Though our device has no reference for a dBm noise floor, we perform 881 * a relative minimization of NF's based on the lowest NF found across a 882 * channel scan. 883 */ 884 void 885 ath_hal_process_noisefloor(struct ath_hal *ah) 886 { 887 HAL_CHANNEL_INTERNAL *c; 888 int16_t correct2, correct5; 889 int16_t lowest2, lowest5; 890 int i; 891 892 /* 893 * Find the lowest 2GHz and 5GHz noise floor values after adjusting 894 * for statistically recorded NF/channel deviation. 895 */ 896 correct2 = lowest2 = 0; 897 correct5 = lowest5 = 0; 898 for (i = 0; i < AH_PRIVATE(ah)->ah_nchan; i++) { 899 WIRELESS_MODE mode; 900 int16_t nf; 901 902 c = &AH_PRIVATE(ah)->ah_channels[i]; 903 if (c->rawNoiseFloor >= 0) 904 continue; 905 /* XXX can't identify proper mode */ 906 mode = IS_CHAN_5GHZ(c) ? WIRELESS_MODE_11a : WIRELESS_MODE_11g; 907 nf = c->rawNoiseFloor + NOISE_FLOOR[mode] + 908 ath_hal_getNfAdjust(ah, c); 909 if (IS_CHAN_5GHZ(c)) { 910 if (nf < lowest5) { 911 lowest5 = nf; 912 correct5 = NOISE_FLOOR[mode] - 913 (c->rawNoiseFloor + ath_hal_getNfAdjust(ah, c)); 914 } 915 } else { 916 if (nf < lowest2) { 917 lowest2 = nf; 918 correct2 = NOISE_FLOOR[mode] - 919 (c->rawNoiseFloor + ath_hal_getNfAdjust(ah, c)); 920 } 921 } 922 } 923 924 /* Correct the channels to reach the expected NF value */ 925 for (i = 0; i < AH_PRIVATE(ah)->ah_nchan; i++) { 926 c = &AH_PRIVATE(ah)->ah_channels[i]; 927 if (c->rawNoiseFloor >= 0) 928 continue; 929 /* Apply correction factor */ 930 c->noiseFloorAdjust = ath_hal_getNfAdjust(ah, c) + 931 (IS_CHAN_5GHZ(c) ? correct5 : correct2); 932 HALDEBUG(ah, HAL_DEBUG_NFCAL, "%u raw nf %d adjust %d\n", 933 c->channel, c->rawNoiseFloor, c->noiseFloorAdjust); 934 } 935 } 936 937 /* 938 * INI support routines. 939 */ 940 941 int 942 ath_hal_ini_write(struct ath_hal *ah, const HAL_INI_ARRAY *ia, 943 int col, int regWr) 944 { 945 int r; 946 947 HALASSERT(col < ia->cols); 948 for (r = 0; r < ia->rows; r++) { 949 OS_REG_WRITE(ah, HAL_INI_VAL(ia, r, 0), 950 HAL_INI_VAL(ia, r, col)); 951 952 /* Analog shift register delay seems needed for Merlin - PR kern/154220 */ 953 if (HAL_INI_VAL(ia, r, 0) >= 0x7800 && HAL_INI_VAL(ia, r, 0) < 0x78a0) 954 OS_DELAY(100); 955 956 DMA_YIELD(regWr); 957 } 958 return regWr; 959 } 960 961 void 962 ath_hal_ini_bank_setup(uint32_t data[], const HAL_INI_ARRAY *ia, int col) 963 { 964 int r; 965 966 HALASSERT(col < ia->cols); 967 for (r = 0; r < ia->rows; r++) 968 data[r] = HAL_INI_VAL(ia, r, col); 969 } 970 971 int 972 ath_hal_ini_bank_write(struct ath_hal *ah, const HAL_INI_ARRAY *ia, 973 const uint32_t data[], int regWr) 974 { 975 int r; 976 977 for (r = 0; r < ia->rows; r++) { 978 OS_REG_WRITE(ah, HAL_INI_VAL(ia, r, 0), data[r]); 979 980 /* Analog shift register delay seems needed for Merlin - PR kern/154220 */ 981 /* XXX verify whether any analog radio bank writes will hit up this */ 982 /* XXX since this is a merlin work-around; and merlin doesn't use radio banks */ 983 if (HAL_INI_VAL(ia, r, 0) >= 0x7800 && HAL_INI_VAL(ia, r, 0) < 0x78a0) 984 OS_DELAY(100); 985 DMA_YIELD(regWr); 986 } 987 return regWr; 988 } 989