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 #include "ah_eeprom.h" /* for 5ghz fast clock flag */ 25 26 #include "ar5416/ar5416reg.h" /* NB: includes ar5212reg.h */ 27 #include "ar9003/ar9300_devid.h" 28 29 /* linker set of registered chips */ 30 OS_SET_DECLARE(ah_chips, struct ath_hal_chip); 31 TAILQ_HEAD(, ath_hal_chip) ah_chip_list = TAILQ_HEAD_INITIALIZER(ah_chip_list); 32 33 int 34 ath_hal_add_chip(struct ath_hal_chip *ahc) 35 { 36 37 TAILQ_INSERT_TAIL(&ah_chip_list, ahc, node); 38 return (0); 39 } 40 41 int 42 ath_hal_remove_chip(struct ath_hal_chip *ahc) 43 { 44 45 TAILQ_REMOVE(&ah_chip_list, ahc, node); 46 return (0); 47 } 48 49 /* 50 * Check the set of registered chips to see if any recognize 51 * the device as one they can support. 52 */ 53 const char* 54 ath_hal_probe(uint16_t vendorid, uint16_t devid) 55 { 56 struct ath_hal_chip * const *pchip; 57 struct ath_hal_chip *pc; 58 59 /* Linker set */ 60 OS_SET_FOREACH(pchip, ah_chips) { 61 const char *name = (*pchip)->probe(vendorid, devid); 62 if (name != AH_NULL) 63 return name; 64 } 65 66 /* List */ 67 TAILQ_FOREACH(pc, &ah_chip_list, node) { 68 const char *name = pc->probe(vendorid, devid); 69 if (name != AH_NULL) 70 return name; 71 } 72 73 return AH_NULL; 74 } 75 76 /* 77 * Attach detects device chip revisions, initializes the hwLayer 78 * function list, reads EEPROM information, 79 * selects reset vectors, and performs a short self test. 80 * Any failures will return an error that should cause a hardware 81 * disable. 82 */ 83 struct ath_hal* 84 ath_hal_attach(uint16_t devid, HAL_SOFTC sc, 85 HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata, 86 HAL_OPS_CONFIG *ah_config, 87 HAL_STATUS *error) 88 { 89 struct ath_hal_chip * const *pchip; 90 struct ath_hal_chip *pc; 91 92 OS_SET_FOREACH(pchip, ah_chips) { 93 struct ath_hal_chip *chip = *pchip; 94 struct ath_hal *ah; 95 96 /* XXX don't have vendorid, assume atheros one works */ 97 if (chip->probe(ATHEROS_VENDOR_ID, devid) == AH_NULL) 98 continue; 99 ah = chip->attach(devid, sc, st, sh, eepromdata, ah_config, 100 error); 101 if (ah != AH_NULL) { 102 /* copy back private state to public area */ 103 ah->ah_devid = AH_PRIVATE(ah)->ah_devid; 104 ah->ah_subvendorid = AH_PRIVATE(ah)->ah_subvendorid; 105 ah->ah_macVersion = AH_PRIVATE(ah)->ah_macVersion; 106 ah->ah_macRev = AH_PRIVATE(ah)->ah_macRev; 107 ah->ah_phyRev = AH_PRIVATE(ah)->ah_phyRev; 108 ah->ah_analog5GhzRev = AH_PRIVATE(ah)->ah_analog5GhzRev; 109 ah->ah_analog2GhzRev = AH_PRIVATE(ah)->ah_analog2GhzRev; 110 return ah; 111 } 112 } 113 114 /* List */ 115 TAILQ_FOREACH(pc, &ah_chip_list, node) { 116 struct ath_hal_chip *chip = pc; 117 struct ath_hal *ah; 118 119 /* XXX don't have vendorid, assume atheros one works */ 120 if (chip->probe(ATHEROS_VENDOR_ID, devid) == AH_NULL) 121 continue; 122 ah = chip->attach(devid, sc, st, sh, eepromdata, ah_config, 123 error); 124 if (ah != AH_NULL) { 125 /* copy back private state to public area */ 126 ah->ah_devid = AH_PRIVATE(ah)->ah_devid; 127 ah->ah_subvendorid = AH_PRIVATE(ah)->ah_subvendorid; 128 ah->ah_macVersion = AH_PRIVATE(ah)->ah_macVersion; 129 ah->ah_macRev = AH_PRIVATE(ah)->ah_macRev; 130 ah->ah_phyRev = AH_PRIVATE(ah)->ah_phyRev; 131 ah->ah_analog5GhzRev = AH_PRIVATE(ah)->ah_analog5GhzRev; 132 ah->ah_analog2GhzRev = AH_PRIVATE(ah)->ah_analog2GhzRev; 133 return ah; 134 } 135 } 136 137 return AH_NULL; 138 } 139 140 const char * 141 ath_hal_mac_name(struct ath_hal *ah) 142 { 143 switch (ah->ah_macVersion) { 144 case AR_SREV_VERSION_CRETE: 145 case AR_SREV_VERSION_MAUI_1: 146 return "AR5210"; 147 case AR_SREV_VERSION_MAUI_2: 148 case AR_SREV_VERSION_OAHU: 149 return "AR5211"; 150 case AR_SREV_VERSION_VENICE: 151 return "AR5212"; 152 case AR_SREV_VERSION_GRIFFIN: 153 return "AR2413"; 154 case AR_SREV_VERSION_CONDOR: 155 return "AR5424"; 156 case AR_SREV_VERSION_EAGLE: 157 return "AR5413"; 158 case AR_SREV_VERSION_COBRA: 159 return "AR2415"; 160 case AR_SREV_2425: /* Swan */ 161 return "AR2425"; 162 case AR_SREV_2417: /* Nala */ 163 return "AR2417"; 164 case AR_XSREV_VERSION_OWL_PCI: 165 return "AR5416"; 166 case AR_XSREV_VERSION_OWL_PCIE: 167 return "AR5418"; 168 case AR_XSREV_VERSION_HOWL: 169 return "AR9130"; 170 case AR_XSREV_VERSION_SOWL: 171 return "AR9160"; 172 case AR_XSREV_VERSION_MERLIN: 173 if (AH_PRIVATE(ah)->ah_ispcie) 174 return "AR9280"; 175 return "AR9220"; 176 case AR_XSREV_VERSION_KITE: 177 return "AR9285"; 178 case AR_XSREV_VERSION_KIWI: 179 if (AH_PRIVATE(ah)->ah_ispcie) 180 return "AR9287"; 181 return "AR9227"; 182 case AR_SREV_VERSION_AR9380: 183 if (ah->ah_macRev >= AR_SREV_REVISION_AR9580_10) 184 return "AR9580"; 185 return "AR9380"; 186 case AR_SREV_VERSION_AR9460: 187 return "AR9460"; 188 case AR_SREV_VERSION_AR9330: 189 return "AR9330"; 190 case AR_SREV_VERSION_AR9340: 191 return "AR9340"; 192 case AR_SREV_VERSION_QCA9550: 193 return "QCA9550"; 194 case AR_SREV_VERSION_AR9485: 195 return "AR9485"; 196 case AR_SREV_VERSION_QCA9565: 197 return "QCA9565"; 198 case AR_SREV_VERSION_QCA9530: 199 return "QCA9530"; 200 } 201 return "????"; 202 } 203 204 /* 205 * Return the mask of available modes based on the hardware capabilities. 206 */ 207 u_int 208 ath_hal_getwirelessmodes(struct ath_hal*ah) 209 { 210 return ath_hal_getWirelessModes(ah); 211 } 212 213 /* linker set of registered RF backends */ 214 OS_SET_DECLARE(ah_rfs, struct ath_hal_rf); 215 TAILQ_HEAD(, ath_hal_rf) ah_rf_list = TAILQ_HEAD_INITIALIZER(ah_rf_list); 216 217 int 218 ath_hal_add_rf(struct ath_hal_rf *arf) 219 { 220 221 TAILQ_INSERT_TAIL(&ah_rf_list, arf, node); 222 return (0); 223 } 224 225 int 226 ath_hal_remove_rf(struct ath_hal_rf *arf) 227 { 228 229 TAILQ_REMOVE(&ah_rf_list, arf, node); 230 return (0); 231 } 232 233 /* 234 * Check the set of registered RF backends to see if 235 * any recognize the device as one they can support. 236 */ 237 struct ath_hal_rf * 238 ath_hal_rfprobe(struct ath_hal *ah, HAL_STATUS *ecode) 239 { 240 struct ath_hal_rf * const *prf; 241 struct ath_hal_rf * rf; 242 243 OS_SET_FOREACH(prf, ah_rfs) { 244 struct ath_hal_rf *rf = *prf; 245 if (rf->probe(ah)) 246 return rf; 247 } 248 249 TAILQ_FOREACH(rf, &ah_rf_list, node) { 250 if (rf->probe(ah)) 251 return rf; 252 } 253 *ecode = HAL_ENOTSUPP; 254 return AH_NULL; 255 } 256 257 const char * 258 ath_hal_rf_name(struct ath_hal *ah) 259 { 260 switch (ah->ah_analog5GhzRev & AR_RADIO_SREV_MAJOR) { 261 case 0: /* 5210 */ 262 return "5110"; /* NB: made up */ 263 case AR_RAD5111_SREV_MAJOR: 264 case AR_RAD5111_SREV_PROD: 265 return "5111"; 266 case AR_RAD2111_SREV_MAJOR: 267 return "2111"; 268 case AR_RAD5112_SREV_MAJOR: 269 case AR_RAD5112_SREV_2_0: 270 case AR_RAD5112_SREV_2_1: 271 return "5112"; 272 case AR_RAD2112_SREV_MAJOR: 273 case AR_RAD2112_SREV_2_0: 274 case AR_RAD2112_SREV_2_1: 275 return "2112"; 276 case AR_RAD2413_SREV_MAJOR: 277 return "2413"; 278 case AR_RAD5413_SREV_MAJOR: 279 return "5413"; 280 case AR_RAD2316_SREV_MAJOR: 281 return "2316"; 282 case AR_RAD2317_SREV_MAJOR: 283 return "2317"; 284 case AR_RAD5424_SREV_MAJOR: 285 return "5424"; 286 287 case AR_RAD5133_SREV_MAJOR: 288 return "5133"; 289 case AR_RAD2133_SREV_MAJOR: 290 return "2133"; 291 case AR_RAD5122_SREV_MAJOR: 292 return "5122"; 293 case AR_RAD2122_SREV_MAJOR: 294 return "2122"; 295 } 296 return "????"; 297 } 298 299 /* 300 * Poll the register looking for a specific value. 301 */ 302 HAL_BOOL 303 ath_hal_wait(struct ath_hal *ah, u_int reg, uint32_t mask, uint32_t val) 304 { 305 #define AH_TIMEOUT 5000 306 return ath_hal_waitfor(ah, reg, mask, val, AH_TIMEOUT); 307 #undef AH_TIMEOUT 308 } 309 310 HAL_BOOL 311 ath_hal_waitfor(struct ath_hal *ah, u_int reg, uint32_t mask, uint32_t val, uint32_t timeout) 312 { 313 int i; 314 315 for (i = 0; i < timeout; i++) { 316 if ((OS_REG_READ(ah, reg) & mask) == val) 317 return AH_TRUE; 318 OS_DELAY(10); 319 } 320 HALDEBUG(ah, HAL_DEBUG_REGIO | HAL_DEBUG_PHYIO, 321 "%s: timeout on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n", 322 __func__, reg, OS_REG_READ(ah, reg), mask, val); 323 return AH_FALSE; 324 } 325 326 /* 327 * Reverse the bits starting at the low bit for a value of 328 * bit_count in size 329 */ 330 uint32_t 331 ath_hal_reverseBits(uint32_t val, uint32_t n) 332 { 333 uint32_t retval; 334 int i; 335 336 for (i = 0, retval = 0; i < n; i++) { 337 retval = (retval << 1) | (val & 1); 338 val >>= 1; 339 } 340 return retval; 341 } 342 343 /* 802.11n related timing definitions */ 344 345 #define OFDM_PLCP_BITS 22 346 #define HT_L_STF 8 347 #define HT_L_LTF 8 348 #define HT_L_SIG 4 349 #define HT_SIG 8 350 #define HT_STF 4 351 #define HT_LTF(n) ((n) * 4) 352 353 #define HT_RC_2_MCS(_rc) ((_rc) & 0x1f) 354 #define HT_RC_2_STREAMS(_rc) ((((_rc) & 0x78) >> 3) + 1) 355 #define IS_HT_RATE(_rc) ( (_rc) & IEEE80211_RATE_MCS) 356 357 /* 358 * Calculate the duration of a packet whether it is 11n or legacy. 359 */ 360 uint32_t 361 ath_hal_pkt_txtime(struct ath_hal *ah, const HAL_RATE_TABLE *rates, uint32_t frameLen, 362 uint16_t rateix, HAL_BOOL isht40, HAL_BOOL shortPreamble, 363 HAL_BOOL includeSifs) 364 { 365 uint8_t rc; 366 int numStreams; 367 368 rc = rates->info[rateix].rateCode; 369 370 /* Legacy rate? Return the old way */ 371 if (! IS_HT_RATE(rc)) 372 return ath_hal_computetxtime(ah, rates, frameLen, rateix, 373 shortPreamble, includeSifs); 374 375 /* 11n frame - extract out the number of spatial streams */ 376 numStreams = HT_RC_2_STREAMS(rc); 377 KASSERT(numStreams > 0 && numStreams <= 4, 378 ("number of spatial streams needs to be 1..3: MCS rate 0x%x!", 379 rateix)); 380 381 /* XXX TODO: Add SIFS */ 382 return ath_computedur_ht(frameLen, rc, numStreams, isht40, 383 shortPreamble); 384 } 385 386 static const uint16_t ht20_bps[32] = { 387 26, 52, 78, 104, 156, 208, 234, 260, 388 52, 104, 156, 208, 312, 416, 468, 520, 389 78, 156, 234, 312, 468, 624, 702, 780, 390 104, 208, 312, 416, 624, 832, 936, 1040 391 }; 392 static const uint16_t ht40_bps[32] = { 393 54, 108, 162, 216, 324, 432, 486, 540, 394 108, 216, 324, 432, 648, 864, 972, 1080, 395 162, 324, 486, 648, 972, 1296, 1458, 1620, 396 216, 432, 648, 864, 1296, 1728, 1944, 2160 397 }; 398 399 /* 400 * Calculate the transmit duration of an 11n frame. 401 */ 402 uint32_t 403 ath_computedur_ht(uint32_t frameLen, uint16_t rate, int streams, 404 HAL_BOOL isht40, HAL_BOOL isShortGI) 405 { 406 uint32_t bitsPerSymbol, numBits, numSymbols, txTime; 407 408 KASSERT(rate & IEEE80211_RATE_MCS, ("not mcs %d", rate)); 409 KASSERT((rate &~ IEEE80211_RATE_MCS) < 31, ("bad mcs 0x%x", rate)); 410 411 if (isht40) 412 bitsPerSymbol = ht40_bps[HT_RC_2_MCS(rate)]; 413 else 414 bitsPerSymbol = ht20_bps[HT_RC_2_MCS(rate)]; 415 numBits = OFDM_PLCP_BITS + (frameLen << 3); 416 numSymbols = howmany(numBits, bitsPerSymbol); 417 if (isShortGI) 418 txTime = ((numSymbols * 18) + 4) / 5; /* 3.6us */ 419 else 420 txTime = numSymbols * 4; /* 4us */ 421 return txTime + HT_L_STF + HT_L_LTF + 422 HT_L_SIG + HT_SIG + HT_STF + HT_LTF(streams); 423 } 424 425 /* 426 * Compute the time to transmit a frame of length frameLen bytes 427 * using the specified rate, phy, and short preamble setting. 428 */ 429 uint16_t 430 ath_hal_computetxtime(struct ath_hal *ah, 431 const HAL_RATE_TABLE *rates, uint32_t frameLen, uint16_t rateix, 432 HAL_BOOL shortPreamble, HAL_BOOL includeSifs) 433 { 434 uint32_t bitsPerSymbol, numBits, numSymbols, phyTime, txTime; 435 uint32_t kbps; 436 437 /* Warn if this function is called for 11n rates; it should not be! */ 438 if (IS_HT_RATE(rates->info[rateix].rateCode)) 439 ath_hal_printf(ah, "%s: MCS rate? (index %d; hwrate 0x%x)\n", 440 __func__, rateix, rates->info[rateix].rateCode); 441 442 kbps = rates->info[rateix].rateKbps; 443 /* 444 * index can be invalid during dynamic Turbo transitions. 445 * XXX 446 */ 447 if (kbps == 0) 448 return 0; 449 switch (rates->info[rateix].phy) { 450 case IEEE80211_T_CCK: 451 phyTime = CCK_PREAMBLE_BITS + CCK_PLCP_BITS; 452 if (shortPreamble && rates->info[rateix].shortPreamble) 453 phyTime >>= 1; 454 numBits = frameLen << 3; 455 txTime = phyTime 456 + ((numBits * 1000)/kbps); 457 if (includeSifs) 458 txTime += CCK_SIFS_TIME; 459 break; 460 case IEEE80211_T_OFDM: 461 bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME) / 1000; 462 HALASSERT(bitsPerSymbol != 0); 463 464 numBits = OFDM_PLCP_BITS + (frameLen << 3); 465 numSymbols = howmany(numBits, bitsPerSymbol); 466 txTime = OFDM_PREAMBLE_TIME 467 + (numSymbols * OFDM_SYMBOL_TIME); 468 if (includeSifs) 469 txTime += OFDM_SIFS_TIME; 470 break; 471 case IEEE80211_T_OFDM_HALF: 472 bitsPerSymbol = (kbps * OFDM_HALF_SYMBOL_TIME) / 1000; 473 HALASSERT(bitsPerSymbol != 0); 474 475 numBits = OFDM_HALF_PLCP_BITS + (frameLen << 3); 476 numSymbols = howmany(numBits, bitsPerSymbol); 477 txTime = OFDM_HALF_PREAMBLE_TIME 478 + (numSymbols * OFDM_HALF_SYMBOL_TIME); 479 if (includeSifs) 480 txTime += OFDM_HALF_SIFS_TIME; 481 break; 482 case IEEE80211_T_OFDM_QUARTER: 483 bitsPerSymbol = (kbps * OFDM_QUARTER_SYMBOL_TIME) / 1000; 484 HALASSERT(bitsPerSymbol != 0); 485 486 numBits = OFDM_QUARTER_PLCP_BITS + (frameLen << 3); 487 numSymbols = howmany(numBits, bitsPerSymbol); 488 txTime = OFDM_QUARTER_PREAMBLE_TIME 489 + (numSymbols * OFDM_QUARTER_SYMBOL_TIME); 490 if (includeSifs) 491 txTime += OFDM_QUARTER_SIFS_TIME; 492 break; 493 case IEEE80211_T_TURBO: 494 bitsPerSymbol = (kbps * TURBO_SYMBOL_TIME) / 1000; 495 HALASSERT(bitsPerSymbol != 0); 496 497 numBits = TURBO_PLCP_BITS + (frameLen << 3); 498 numSymbols = howmany(numBits, bitsPerSymbol); 499 txTime = TURBO_PREAMBLE_TIME 500 + (numSymbols * TURBO_SYMBOL_TIME); 501 if (includeSifs) 502 txTime += TURBO_SIFS_TIME; 503 break; 504 default: 505 HALDEBUG(ah, HAL_DEBUG_PHYIO, 506 "%s: unknown phy %u (rate ix %u)\n", 507 __func__, rates->info[rateix].phy, rateix); 508 txTime = 0; 509 break; 510 } 511 return txTime; 512 } 513 514 int 515 ath_hal_get_curmode(struct ath_hal *ah, const struct ieee80211_channel *chan) 516 { 517 /* 518 * Pick a default mode at bootup. A channel change is inevitable. 519 */ 520 if (!chan) 521 return HAL_MODE_11NG_HT20; 522 523 if (IEEE80211_IS_CHAN_TURBO(chan)) 524 return HAL_MODE_TURBO; 525 526 /* check for NA_HT before plain A, since IS_CHAN_A includes NA_HT */ 527 if (IEEE80211_IS_CHAN_5GHZ(chan) && IEEE80211_IS_CHAN_HT20(chan)) 528 return HAL_MODE_11NA_HT20; 529 if (IEEE80211_IS_CHAN_5GHZ(chan) && IEEE80211_IS_CHAN_HT40U(chan)) 530 return HAL_MODE_11NA_HT40PLUS; 531 if (IEEE80211_IS_CHAN_5GHZ(chan) && IEEE80211_IS_CHAN_HT40D(chan)) 532 return HAL_MODE_11NA_HT40MINUS; 533 if (IEEE80211_IS_CHAN_A(chan)) 534 return HAL_MODE_11A; 535 536 /* check for NG_HT before plain G, since IS_CHAN_G includes NG_HT */ 537 if (IEEE80211_IS_CHAN_2GHZ(chan) && IEEE80211_IS_CHAN_HT20(chan)) 538 return HAL_MODE_11NG_HT20; 539 if (IEEE80211_IS_CHAN_2GHZ(chan) && IEEE80211_IS_CHAN_HT40U(chan)) 540 return HAL_MODE_11NG_HT40PLUS; 541 if (IEEE80211_IS_CHAN_2GHZ(chan) && IEEE80211_IS_CHAN_HT40D(chan)) 542 return HAL_MODE_11NG_HT40MINUS; 543 544 /* 545 * XXX For FreeBSD, will this work correctly given the DYN 546 * chan mode (OFDM+CCK dynamic) ? We have pure-G versions DYN-BG.. 547 */ 548 if (IEEE80211_IS_CHAN_G(chan)) 549 return HAL_MODE_11G; 550 if (IEEE80211_IS_CHAN_B(chan)) 551 return HAL_MODE_11B; 552 553 HALASSERT(0); 554 return HAL_MODE_11NG_HT20; 555 } 556 557 558 typedef enum { 559 WIRELESS_MODE_11a = 0, 560 WIRELESS_MODE_TURBO = 1, 561 WIRELESS_MODE_11b = 2, 562 WIRELESS_MODE_11g = 3, 563 WIRELESS_MODE_108g = 4, 564 565 WIRELESS_MODE_MAX 566 } WIRELESS_MODE; 567 568 /* 569 * XXX TODO: for some (?) chips, an 11b mode still runs at 11bg. 570 * Maybe AR5211 has separate 11b and 11g only modes, so 11b is 22MHz 571 * and 11g is 44MHz, but AR5416 and later run 11b in 11bg mode, right? 572 */ 573 static WIRELESS_MODE 574 ath_hal_chan2wmode(struct ath_hal *ah, const struct ieee80211_channel *chan) 575 { 576 if (IEEE80211_IS_CHAN_B(chan)) 577 return WIRELESS_MODE_11b; 578 if (IEEE80211_IS_CHAN_G(chan)) 579 return WIRELESS_MODE_11g; 580 if (IEEE80211_IS_CHAN_108G(chan)) 581 return WIRELESS_MODE_108g; 582 if (IEEE80211_IS_CHAN_TURBO(chan)) 583 return WIRELESS_MODE_TURBO; 584 return WIRELESS_MODE_11a; 585 } 586 587 /* 588 * Convert between microseconds and core system clocks. 589 */ 590 /* 11a Turbo 11b 11g 108g */ 591 static const uint8_t CLOCK_RATE[] = { 40, 80, 22, 44, 88 }; 592 593 #define CLOCK_FAST_RATE_5GHZ_OFDM 44 594 595 u_int 596 ath_hal_mac_clks(struct ath_hal *ah, u_int usecs) 597 { 598 const struct ieee80211_channel *c = AH_PRIVATE(ah)->ah_curchan; 599 u_int clks; 600 601 /* NB: ah_curchan may be null when called attach time */ 602 /* XXX merlin and later specific workaround - 5ghz fast clock is 44 */ 603 if (c != AH_NULL && IS_5GHZ_FAST_CLOCK_EN(ah, c)) { 604 clks = usecs * CLOCK_FAST_RATE_5GHZ_OFDM; 605 if (IEEE80211_IS_CHAN_HT40(c)) 606 clks <<= 1; 607 } else if (c != AH_NULL) { 608 clks = usecs * CLOCK_RATE[ath_hal_chan2wmode(ah, c)]; 609 if (IEEE80211_IS_CHAN_HT40(c)) 610 clks <<= 1; 611 } else 612 clks = usecs * CLOCK_RATE[WIRELESS_MODE_11b]; 613 614 /* Compensate for half/quarter rate */ 615 if (c != AH_NULL && IEEE80211_IS_CHAN_HALF(c)) 616 clks = clks / 2; 617 else if (c != AH_NULL && IEEE80211_IS_CHAN_QUARTER(c)) 618 clks = clks / 4; 619 620 return clks; 621 } 622 623 u_int 624 ath_hal_mac_usec(struct ath_hal *ah, u_int clks) 625 { 626 uint64_t psec; 627 628 psec = ath_hal_mac_psec(ah, clks); 629 return (psec / 1000000); 630 } 631 632 /* 633 * XXX TODO: half, quarter rates. 634 */ 635 uint64_t 636 ath_hal_mac_psec(struct ath_hal *ah, u_int clks) 637 { 638 const struct ieee80211_channel *c = AH_PRIVATE(ah)->ah_curchan; 639 uint64_t psec; 640 641 /* NB: ah_curchan may be null when called attach time */ 642 /* XXX merlin and later specific workaround - 5ghz fast clock is 44 */ 643 if (c != AH_NULL && IS_5GHZ_FAST_CLOCK_EN(ah, c)) { 644 psec = (clks * 1000000ULL) / CLOCK_FAST_RATE_5GHZ_OFDM; 645 if (IEEE80211_IS_CHAN_HT40(c)) 646 psec >>= 1; 647 } else if (c != AH_NULL) { 648 psec = (clks * 1000000ULL) / CLOCK_RATE[ath_hal_chan2wmode(ah, c)]; 649 if (IEEE80211_IS_CHAN_HT40(c)) 650 psec >>= 1; 651 } else 652 psec = (clks * 1000000ULL) / CLOCK_RATE[WIRELESS_MODE_11b]; 653 return psec; 654 } 655 656 /* 657 * Setup a h/w rate table's reverse lookup table and 658 * fill in ack durations. This routine is called for 659 * each rate table returned through the ah_getRateTable 660 * method. The reverse lookup tables are assumed to be 661 * initialized to zero (or at least the first entry). 662 * We use this as a key that indicates whether or not 663 * we've previously setup the reverse lookup table. 664 * 665 * XXX not reentrant, but shouldn't matter 666 */ 667 void 668 ath_hal_setupratetable(struct ath_hal *ah, HAL_RATE_TABLE *rt) 669 { 670 #define N(a) (sizeof(a)/sizeof(a[0])) 671 int i; 672 673 if (rt->rateCodeToIndex[0] != 0) /* already setup */ 674 return; 675 for (i = 0; i < N(rt->rateCodeToIndex); i++) 676 rt->rateCodeToIndex[i] = (uint8_t) -1; 677 for (i = 0; i < rt->rateCount; i++) { 678 uint8_t code = rt->info[i].rateCode; 679 uint8_t cix = rt->info[i].controlRate; 680 681 HALASSERT(code < N(rt->rateCodeToIndex)); 682 rt->rateCodeToIndex[code] = i; 683 HALASSERT((code | rt->info[i].shortPreamble) < 684 N(rt->rateCodeToIndex)); 685 rt->rateCodeToIndex[code | rt->info[i].shortPreamble] = i; 686 /* 687 * XXX for 11g the control rate to use for 5.5 and 11 Mb/s 688 * depends on whether they are marked as basic rates; 689 * the static tables are setup with an 11b-compatible 690 * 2Mb/s rate which will work but is suboptimal 691 */ 692 rt->info[i].lpAckDuration = ath_hal_computetxtime(ah, rt, 693 WLAN_CTRL_FRAME_SIZE, cix, AH_FALSE, AH_TRUE); 694 rt->info[i].spAckDuration = ath_hal_computetxtime(ah, rt, 695 WLAN_CTRL_FRAME_SIZE, cix, AH_TRUE, AH_TRUE); 696 } 697 #undef N 698 } 699 700 HAL_STATUS 701 ath_hal_getcapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type, 702 uint32_t capability, uint32_t *result) 703 { 704 const HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps; 705 706 switch (type) { 707 case HAL_CAP_REG_DMN: /* regulatory domain */ 708 *result = AH_PRIVATE(ah)->ah_currentRD; 709 return HAL_OK; 710 case HAL_CAP_DFS_DMN: /* DFS Domain */ 711 *result = AH_PRIVATE(ah)->ah_dfsDomain; 712 return HAL_OK; 713 case HAL_CAP_CIPHER: /* cipher handled in hardware */ 714 case HAL_CAP_TKIP_MIC: /* handle TKIP MIC in hardware */ 715 return HAL_ENOTSUPP; 716 case HAL_CAP_TKIP_SPLIT: /* hardware TKIP uses split keys */ 717 return HAL_ENOTSUPP; 718 case HAL_CAP_PHYCOUNTERS: /* hardware PHY error counters */ 719 return pCap->halHwPhyCounterSupport ? HAL_OK : HAL_ENXIO; 720 case HAL_CAP_WME_TKIPMIC: /* hardware can do TKIP MIC when WMM is turned on */ 721 return HAL_ENOTSUPP; 722 case HAL_CAP_DIVERSITY: /* hardware supports fast diversity */ 723 return HAL_ENOTSUPP; 724 case HAL_CAP_KEYCACHE_SIZE: /* hardware key cache size */ 725 *result = pCap->halKeyCacheSize; 726 return HAL_OK; 727 case HAL_CAP_NUM_TXQUEUES: /* number of hardware tx queues */ 728 *result = pCap->halTotalQueues; 729 return HAL_OK; 730 case HAL_CAP_VEOL: /* hardware supports virtual EOL */ 731 return pCap->halVEOLSupport ? HAL_OK : HAL_ENOTSUPP; 732 case HAL_CAP_PSPOLL: /* hardware PS-Poll support works */ 733 return pCap->halPSPollBroken ? HAL_ENOTSUPP : HAL_OK; 734 case HAL_CAP_COMPRESSION: 735 return pCap->halCompressSupport ? HAL_OK : HAL_ENOTSUPP; 736 case HAL_CAP_BURST: 737 return pCap->halBurstSupport ? HAL_OK : HAL_ENOTSUPP; 738 case HAL_CAP_FASTFRAME: 739 return pCap->halFastFramesSupport ? HAL_OK : HAL_ENOTSUPP; 740 case HAL_CAP_DIAG: /* hardware diagnostic support */ 741 *result = AH_PRIVATE(ah)->ah_diagreg; 742 return HAL_OK; 743 case HAL_CAP_TXPOW: /* global tx power limit */ 744 switch (capability) { 745 case 0: /* facility is supported */ 746 return HAL_OK; 747 case 1: /* current limit */ 748 *result = AH_PRIVATE(ah)->ah_powerLimit; 749 return HAL_OK; 750 case 2: /* current max tx power */ 751 *result = AH_PRIVATE(ah)->ah_maxPowerLevel; 752 return HAL_OK; 753 case 3: /* scale factor */ 754 *result = AH_PRIVATE(ah)->ah_tpScale; 755 return HAL_OK; 756 } 757 return HAL_ENOTSUPP; 758 case HAL_CAP_BSSIDMASK: /* hardware supports bssid mask */ 759 return pCap->halBssIdMaskSupport ? HAL_OK : HAL_ENOTSUPP; 760 case HAL_CAP_MCAST_KEYSRCH: /* multicast frame keycache search */ 761 return pCap->halMcastKeySrchSupport ? HAL_OK : HAL_ENOTSUPP; 762 case HAL_CAP_TSF_ADJUST: /* hardware has beacon tsf adjust */ 763 return HAL_ENOTSUPP; 764 case HAL_CAP_RFSILENT: /* rfsilent support */ 765 switch (capability) { 766 case 0: /* facility is supported */ 767 return pCap->halRfSilentSupport ? HAL_OK : HAL_ENOTSUPP; 768 case 1: /* current setting */ 769 return AH_PRIVATE(ah)->ah_rfkillEnabled ? 770 HAL_OK : HAL_ENOTSUPP; 771 case 2: /* rfsilent config */ 772 *result = AH_PRIVATE(ah)->ah_rfsilent; 773 return HAL_OK; 774 } 775 return HAL_ENOTSUPP; 776 case HAL_CAP_11D: 777 return HAL_OK; 778 779 case HAL_CAP_HT: 780 return pCap->halHTSupport ? HAL_OK : HAL_ENOTSUPP; 781 case HAL_CAP_GTXTO: 782 return pCap->halGTTSupport ? HAL_OK : HAL_ENOTSUPP; 783 case HAL_CAP_FAST_CC: 784 return pCap->halFastCCSupport ? HAL_OK : HAL_ENOTSUPP; 785 case HAL_CAP_TX_CHAINMASK: /* mask of TX chains supported */ 786 *result = pCap->halTxChainMask; 787 return HAL_OK; 788 case HAL_CAP_RX_CHAINMASK: /* mask of RX chains supported */ 789 *result = pCap->halRxChainMask; 790 return HAL_OK; 791 case HAL_CAP_NUM_GPIO_PINS: 792 *result = pCap->halNumGpioPins; 793 return HAL_OK; 794 case HAL_CAP_CST: 795 return pCap->halCSTSupport ? HAL_OK : HAL_ENOTSUPP; 796 case HAL_CAP_RTS_AGGR_LIMIT: 797 *result = pCap->halRtsAggrLimit; 798 return HAL_OK; 799 case HAL_CAP_4ADDR_AGGR: 800 return pCap->hal4AddrAggrSupport ? HAL_OK : HAL_ENOTSUPP; 801 case HAL_CAP_EXT_CHAN_DFS: 802 return pCap->halExtChanDfsSupport ? HAL_OK : HAL_ENOTSUPP; 803 case HAL_CAP_RX_STBC: 804 return pCap->halRxStbcSupport ? HAL_OK : HAL_ENOTSUPP; 805 case HAL_CAP_TX_STBC: 806 return pCap->halTxStbcSupport ? HAL_OK : HAL_ENOTSUPP; 807 case HAL_CAP_COMBINED_RADAR_RSSI: 808 return pCap->halUseCombinedRadarRssi ? HAL_OK : HAL_ENOTSUPP; 809 case HAL_CAP_AUTO_SLEEP: 810 return pCap->halAutoSleepSupport ? HAL_OK : HAL_ENOTSUPP; 811 case HAL_CAP_MBSSID_AGGR_SUPPORT: 812 return pCap->halMbssidAggrSupport ? HAL_OK : HAL_ENOTSUPP; 813 case HAL_CAP_SPLIT_4KB_TRANS: /* hardware handles descriptors straddling 4k page boundary */ 814 return pCap->hal4kbSplitTransSupport ? HAL_OK : HAL_ENOTSUPP; 815 case HAL_CAP_REG_FLAG: 816 *result = AH_PRIVATE(ah)->ah_currentRDext; 817 return HAL_OK; 818 case HAL_CAP_ENHANCED_DMA_SUPPORT: 819 return pCap->halEnhancedDmaSupport ? HAL_OK : HAL_ENOTSUPP; 820 case HAL_CAP_NUM_TXMAPS: 821 *result = pCap->halNumTxMaps; 822 return HAL_OK; 823 case HAL_CAP_TXDESCLEN: 824 *result = pCap->halTxDescLen; 825 return HAL_OK; 826 case HAL_CAP_TXSTATUSLEN: 827 *result = pCap->halTxStatusLen; 828 return HAL_OK; 829 case HAL_CAP_RXSTATUSLEN: 830 *result = pCap->halRxStatusLen; 831 return HAL_OK; 832 case HAL_CAP_RXFIFODEPTH: 833 switch (capability) { 834 case HAL_RX_QUEUE_HP: 835 *result = pCap->halRxHpFifoDepth; 836 return HAL_OK; 837 case HAL_RX_QUEUE_LP: 838 *result = pCap->halRxLpFifoDepth; 839 return HAL_OK; 840 default: 841 return HAL_ENOTSUPP; 842 } 843 case HAL_CAP_RXBUFSIZE: 844 case HAL_CAP_NUM_MR_RETRIES: 845 *result = pCap->halNumMRRetries; 846 return HAL_OK; 847 case HAL_CAP_BT_COEX: 848 return pCap->halBtCoexSupport ? HAL_OK : HAL_ENOTSUPP; 849 case HAL_CAP_SPECTRAL_SCAN: 850 return pCap->halSpectralScanSupport ? HAL_OK : HAL_ENOTSUPP; 851 case HAL_CAP_HT20_SGI: 852 return pCap->halHTSGI20Support ? HAL_OK : HAL_ENOTSUPP; 853 case HAL_CAP_RXTSTAMP_PREC: /* rx desc tstamp precision (bits) */ 854 *result = pCap->halRxTstampPrecision; 855 return HAL_OK; 856 case HAL_CAP_ANT_DIV_COMB: /* AR9285/AR9485 LNA diversity */ 857 return pCap->halAntDivCombSupport ? HAL_OK : HAL_ENOTSUPP; 858 859 case HAL_CAP_ENHANCED_DFS_SUPPORT: 860 return pCap->halEnhancedDfsSupport ? HAL_OK : HAL_ENOTSUPP; 861 862 /* FreeBSD-specific entries for now */ 863 case HAL_CAP_RXORN_FATAL: /* HAL_INT_RXORN treated as fatal */ 864 return AH_PRIVATE(ah)->ah_rxornIsFatal ? HAL_OK : HAL_ENOTSUPP; 865 case HAL_CAP_INTRMASK: /* mask of supported interrupts */ 866 *result = pCap->halIntrMask; 867 return HAL_OK; 868 case HAL_CAP_BSSIDMATCH: /* hardware has disable bssid match */ 869 return pCap->halBssidMatchSupport ? HAL_OK : HAL_ENOTSUPP; 870 case HAL_CAP_STREAMS: /* number of 11n spatial streams */ 871 switch (capability) { 872 case 0: /* TX */ 873 *result = pCap->halTxStreams; 874 return HAL_OK; 875 case 1: /* RX */ 876 *result = pCap->halRxStreams; 877 return HAL_OK; 878 default: 879 return HAL_ENOTSUPP; 880 } 881 case HAL_CAP_RXDESC_SELFLINK: /* hardware supports self-linked final RX descriptors correctly */ 882 return pCap->halHasRxSelfLinkedTail ? HAL_OK : HAL_ENOTSUPP; 883 case HAL_CAP_BB_READ_WAR: /* Baseband read WAR */ 884 return pCap->halHasBBReadWar? HAL_OK : HAL_ENOTSUPP; 885 case HAL_CAP_SERIALISE_WAR: /* PCI register serialisation */ 886 return pCap->halSerialiseRegWar ? HAL_OK : HAL_ENOTSUPP; 887 case HAL_CAP_MFP: /* Management frame protection setting */ 888 *result = pCap->halMfpSupport; 889 return HAL_OK; 890 case HAL_CAP_RX_LNA_MIXING: /* Hardware uses an RX LNA mixer to map 2 antennas to a 1 stream receiver */ 891 return pCap->halRxUsingLnaMixing ? HAL_OK : HAL_ENOTSUPP; 892 case HAL_CAP_DO_MYBEACON: /* Hardware supports filtering my-beacons */ 893 return pCap->halRxDoMyBeacon ? HAL_OK : HAL_ENOTSUPP; 894 case HAL_CAP_TXTSTAMP_PREC: /* tx desc tstamp precision (bits) */ 895 *result = pCap->halTxTstampPrecision; 896 return HAL_OK; 897 default: 898 return HAL_EINVAL; 899 } 900 } 901 902 HAL_BOOL 903 ath_hal_setcapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type, 904 uint32_t capability, uint32_t setting, HAL_STATUS *status) 905 { 906 907 switch (type) { 908 case HAL_CAP_TXPOW: 909 switch (capability) { 910 case 3: 911 if (setting <= HAL_TP_SCALE_MIN) { 912 AH_PRIVATE(ah)->ah_tpScale = setting; 913 return AH_TRUE; 914 } 915 break; 916 } 917 break; 918 case HAL_CAP_RFSILENT: /* rfsilent support */ 919 /* 920 * NB: allow even if halRfSilentSupport is false 921 * in case the EEPROM is misprogrammed. 922 */ 923 switch (capability) { 924 case 1: /* current setting */ 925 AH_PRIVATE(ah)->ah_rfkillEnabled = (setting != 0); 926 return AH_TRUE; 927 case 2: /* rfsilent config */ 928 /* XXX better done per-chip for validation? */ 929 AH_PRIVATE(ah)->ah_rfsilent = setting; 930 return AH_TRUE; 931 } 932 break; 933 case HAL_CAP_REG_DMN: /* regulatory domain */ 934 AH_PRIVATE(ah)->ah_currentRD = setting; 935 return AH_TRUE; 936 case HAL_CAP_RXORN_FATAL: /* HAL_INT_RXORN treated as fatal */ 937 AH_PRIVATE(ah)->ah_rxornIsFatal = setting; 938 return AH_TRUE; 939 default: 940 break; 941 } 942 if (status) 943 *status = HAL_EINVAL; 944 return AH_FALSE; 945 } 946 947 /* 948 * Common support for getDiagState method. 949 */ 950 951 static u_int 952 ath_hal_getregdump(struct ath_hal *ah, const HAL_REGRANGE *regs, 953 void *dstbuf, int space) 954 { 955 uint32_t *dp = dstbuf; 956 int i; 957 958 for (i = 0; space >= 2*sizeof(uint32_t); i++) { 959 uint32_t r = regs[i].start; 960 uint32_t e = regs[i].end; 961 *dp++ = r; 962 *dp++ = e; 963 space -= 2*sizeof(uint32_t); 964 do { 965 *dp++ = OS_REG_READ(ah, r); 966 r += sizeof(uint32_t); 967 space -= sizeof(uint32_t); 968 } while (r <= e && space >= sizeof(uint32_t)); 969 } 970 return (char *) dp - (char *) dstbuf; 971 } 972 973 static void 974 ath_hal_setregs(struct ath_hal *ah, const HAL_REGWRITE *regs, int space) 975 { 976 while (space >= sizeof(HAL_REGWRITE)) { 977 OS_REG_WRITE(ah, regs->addr, regs->value); 978 regs++, space -= sizeof(HAL_REGWRITE); 979 } 980 } 981 982 HAL_BOOL 983 ath_hal_getdiagstate(struct ath_hal *ah, int request, 984 const void *args, uint32_t argsize, 985 void **result, uint32_t *resultsize) 986 { 987 988 switch (request) { 989 case HAL_DIAG_REVS: 990 *result = &AH_PRIVATE(ah)->ah_devid; 991 *resultsize = sizeof(HAL_REVS); 992 return AH_TRUE; 993 case HAL_DIAG_REGS: 994 *resultsize = ath_hal_getregdump(ah, args, *result,*resultsize); 995 return AH_TRUE; 996 case HAL_DIAG_SETREGS: 997 ath_hal_setregs(ah, args, argsize); 998 *resultsize = 0; 999 return AH_TRUE; 1000 case HAL_DIAG_FATALERR: 1001 *result = &AH_PRIVATE(ah)->ah_fatalState[0]; 1002 *resultsize = sizeof(AH_PRIVATE(ah)->ah_fatalState); 1003 return AH_TRUE; 1004 case HAL_DIAG_EEREAD: 1005 if (argsize != sizeof(uint16_t)) 1006 return AH_FALSE; 1007 if (!ath_hal_eepromRead(ah, *(const uint16_t *)args, *result)) 1008 return AH_FALSE; 1009 *resultsize = sizeof(uint16_t); 1010 return AH_TRUE; 1011 #ifdef AH_PRIVATE_DIAG 1012 case HAL_DIAG_SETKEY: { 1013 const HAL_DIAG_KEYVAL *dk; 1014 1015 if (argsize != sizeof(HAL_DIAG_KEYVAL)) 1016 return AH_FALSE; 1017 dk = (const HAL_DIAG_KEYVAL *)args; 1018 return ah->ah_setKeyCacheEntry(ah, dk->dk_keyix, 1019 &dk->dk_keyval, dk->dk_mac, dk->dk_xor); 1020 } 1021 case HAL_DIAG_RESETKEY: 1022 if (argsize != sizeof(uint16_t)) 1023 return AH_FALSE; 1024 return ah->ah_resetKeyCacheEntry(ah, *(const uint16_t *)args); 1025 #ifdef AH_SUPPORT_WRITE_EEPROM 1026 case HAL_DIAG_EEWRITE: { 1027 const HAL_DIAG_EEVAL *ee; 1028 if (argsize != sizeof(HAL_DIAG_EEVAL)) 1029 return AH_FALSE; 1030 ee = (const HAL_DIAG_EEVAL *)args; 1031 return ath_hal_eepromWrite(ah, ee->ee_off, ee->ee_data); 1032 } 1033 #endif /* AH_SUPPORT_WRITE_EEPROM */ 1034 #endif /* AH_PRIVATE_DIAG */ 1035 case HAL_DIAG_11NCOMPAT: 1036 if (argsize == 0) { 1037 *resultsize = sizeof(uint32_t); 1038 *((uint32_t *)(*result)) = 1039 AH_PRIVATE(ah)->ah_11nCompat; 1040 } else if (argsize == sizeof(uint32_t)) { 1041 AH_PRIVATE(ah)->ah_11nCompat = *(const uint32_t *)args; 1042 } else 1043 return AH_FALSE; 1044 return AH_TRUE; 1045 case HAL_DIAG_CHANSURVEY: 1046 *result = &AH_PRIVATE(ah)->ah_chansurvey; 1047 *resultsize = sizeof(HAL_CHANNEL_SURVEY); 1048 return AH_TRUE; 1049 } 1050 return AH_FALSE; 1051 } 1052 1053 /* 1054 * Set the properties of the tx queue with the parameters 1055 * from qInfo. 1056 */ 1057 HAL_BOOL 1058 ath_hal_setTxQProps(struct ath_hal *ah, 1059 HAL_TX_QUEUE_INFO *qi, const HAL_TXQ_INFO *qInfo) 1060 { 1061 uint32_t cw; 1062 1063 if (qi->tqi_type == HAL_TX_QUEUE_INACTIVE) { 1064 HALDEBUG(ah, HAL_DEBUG_TXQUEUE, 1065 "%s: inactive queue\n", __func__); 1066 return AH_FALSE; 1067 } 1068 /* XXX validate parameters */ 1069 qi->tqi_ver = qInfo->tqi_ver; 1070 qi->tqi_subtype = qInfo->tqi_subtype; 1071 qi->tqi_qflags = qInfo->tqi_qflags; 1072 qi->tqi_priority = qInfo->tqi_priority; 1073 if (qInfo->tqi_aifs != HAL_TXQ_USEDEFAULT) 1074 qi->tqi_aifs = AH_MIN(qInfo->tqi_aifs, 255); 1075 else 1076 qi->tqi_aifs = INIT_AIFS; 1077 if (qInfo->tqi_cwmin != HAL_TXQ_USEDEFAULT) { 1078 cw = AH_MIN(qInfo->tqi_cwmin, 1024); 1079 /* make sure that the CWmin is of the form (2^n - 1) */ 1080 qi->tqi_cwmin = 1; 1081 while (qi->tqi_cwmin < cw) 1082 qi->tqi_cwmin = (qi->tqi_cwmin << 1) | 1; 1083 } else 1084 qi->tqi_cwmin = qInfo->tqi_cwmin; 1085 if (qInfo->tqi_cwmax != HAL_TXQ_USEDEFAULT) { 1086 cw = AH_MIN(qInfo->tqi_cwmax, 1024); 1087 /* make sure that the CWmax is of the form (2^n - 1) */ 1088 qi->tqi_cwmax = 1; 1089 while (qi->tqi_cwmax < cw) 1090 qi->tqi_cwmax = (qi->tqi_cwmax << 1) | 1; 1091 } else 1092 qi->tqi_cwmax = INIT_CWMAX; 1093 /* Set retry limit values */ 1094 if (qInfo->tqi_shretry != 0) 1095 qi->tqi_shretry = AH_MIN(qInfo->tqi_shretry, 15); 1096 else 1097 qi->tqi_shretry = INIT_SH_RETRY; 1098 if (qInfo->tqi_lgretry != 0) 1099 qi->tqi_lgretry = AH_MIN(qInfo->tqi_lgretry, 15); 1100 else 1101 qi->tqi_lgretry = INIT_LG_RETRY; 1102 qi->tqi_cbrPeriod = qInfo->tqi_cbrPeriod; 1103 qi->tqi_cbrOverflowLimit = qInfo->tqi_cbrOverflowLimit; 1104 qi->tqi_burstTime = qInfo->tqi_burstTime; 1105 qi->tqi_readyTime = qInfo->tqi_readyTime; 1106 1107 switch (qInfo->tqi_subtype) { 1108 case HAL_WME_UPSD: 1109 if (qi->tqi_type == HAL_TX_QUEUE_DATA) 1110 qi->tqi_intFlags = HAL_TXQ_USE_LOCKOUT_BKOFF_DIS; 1111 break; 1112 default: 1113 break; /* NB: silence compiler */ 1114 } 1115 return AH_TRUE; 1116 } 1117 1118 HAL_BOOL 1119 ath_hal_getTxQProps(struct ath_hal *ah, 1120 HAL_TXQ_INFO *qInfo, const HAL_TX_QUEUE_INFO *qi) 1121 { 1122 if (qi->tqi_type == HAL_TX_QUEUE_INACTIVE) { 1123 HALDEBUG(ah, HAL_DEBUG_TXQUEUE, 1124 "%s: inactive queue\n", __func__); 1125 return AH_FALSE; 1126 } 1127 1128 qInfo->tqi_qflags = qi->tqi_qflags; 1129 qInfo->tqi_ver = qi->tqi_ver; 1130 qInfo->tqi_subtype = qi->tqi_subtype; 1131 qInfo->tqi_qflags = qi->tqi_qflags; 1132 qInfo->tqi_priority = qi->tqi_priority; 1133 qInfo->tqi_aifs = qi->tqi_aifs; 1134 qInfo->tqi_cwmin = qi->tqi_cwmin; 1135 qInfo->tqi_cwmax = qi->tqi_cwmax; 1136 qInfo->tqi_shretry = qi->tqi_shretry; 1137 qInfo->tqi_lgretry = qi->tqi_lgretry; 1138 qInfo->tqi_cbrPeriod = qi->tqi_cbrPeriod; 1139 qInfo->tqi_cbrOverflowLimit = qi->tqi_cbrOverflowLimit; 1140 qInfo->tqi_burstTime = qi->tqi_burstTime; 1141 qInfo->tqi_readyTime = qi->tqi_readyTime; 1142 return AH_TRUE; 1143 } 1144 1145 /* 11a Turbo 11b 11g 108g */ 1146 static const int16_t NOISE_FLOOR[] = { -96, -93, -98, -96, -93 }; 1147 1148 /* 1149 * Read the current channel noise floor and return. 1150 * If nf cal hasn't finished, channel noise floor should be 0 1151 * and we return a nominal value based on band and frequency. 1152 * 1153 * NB: This is a private routine used by per-chip code to 1154 * implement the ah_getChanNoise method. 1155 */ 1156 int16_t 1157 ath_hal_getChanNoise(struct ath_hal *ah, const struct ieee80211_channel *chan) 1158 { 1159 HAL_CHANNEL_INTERNAL *ichan; 1160 1161 ichan = ath_hal_checkchannel(ah, chan); 1162 if (ichan == AH_NULL) { 1163 HALDEBUG(ah, HAL_DEBUG_NFCAL, 1164 "%s: invalid channel %u/0x%x; no mapping\n", 1165 __func__, chan->ic_freq, chan->ic_flags); 1166 return 0; 1167 } 1168 if (ichan->rawNoiseFloor == 0) { 1169 WIRELESS_MODE mode = ath_hal_chan2wmode(ah, chan); 1170 1171 HALASSERT(mode < WIRELESS_MODE_MAX); 1172 return NOISE_FLOOR[mode] + ath_hal_getNfAdjust(ah, ichan); 1173 } else 1174 return ichan->rawNoiseFloor + ichan->noiseFloorAdjust; 1175 } 1176 1177 /* 1178 * Fetch the current setup of ctl/ext noise floor values. 1179 * 1180 * If the CHANNEL_MIMO_NF_VALID flag isn't set, the array is simply 1181 * populated with values from NOISE_FLOOR[] + ath_hal_getNfAdjust(). 1182 * 1183 * The caller must supply ctl/ext NF arrays which are at least 1184 * AH_MAX_CHAINS entries long. 1185 */ 1186 int 1187 ath_hal_get_mimo_chan_noise(struct ath_hal *ah, 1188 const struct ieee80211_channel *chan, int16_t *nf_ctl, 1189 int16_t *nf_ext) 1190 { 1191 HAL_CHANNEL_INTERNAL *ichan; 1192 int i; 1193 1194 ichan = ath_hal_checkchannel(ah, chan); 1195 if (ichan == AH_NULL) { 1196 HALDEBUG(ah, HAL_DEBUG_NFCAL, 1197 "%s: invalid channel %u/0x%x; no mapping\n", 1198 __func__, chan->ic_freq, chan->ic_flags); 1199 for (i = 0; i < AH_MAX_CHAINS; i++) { 1200 nf_ctl[i] = nf_ext[i] = 0; 1201 } 1202 return 0; 1203 } 1204 1205 /* Return 0 if there's no valid MIMO values (yet) */ 1206 if (! (ichan->privFlags & CHANNEL_MIMO_NF_VALID)) { 1207 for (i = 0; i < AH_MAX_CHAINS; i++) { 1208 nf_ctl[i] = nf_ext[i] = 0; 1209 } 1210 return 0; 1211 } 1212 if (ichan->rawNoiseFloor == 0) { 1213 WIRELESS_MODE mode = ath_hal_chan2wmode(ah, chan); 1214 HALASSERT(mode < WIRELESS_MODE_MAX); 1215 /* 1216 * See the comment below - this could cause issues for 1217 * stations which have a very low RSSI, below the 1218 * 'normalised' NF values in NOISE_FLOOR[]. 1219 */ 1220 for (i = 0; i < AH_MAX_CHAINS; i++) { 1221 nf_ctl[i] = nf_ext[i] = NOISE_FLOOR[mode] + 1222 ath_hal_getNfAdjust(ah, ichan); 1223 } 1224 return 1; 1225 } else { 1226 /* 1227 * The value returned here from a MIMO radio is presumed to be 1228 * "good enough" as a NF calculation. As RSSI values are calculated 1229 * against this, an adjusted NF may be higher than the RSSI value 1230 * returned from a vary weak station, resulting in an obscenely 1231 * high signal strength calculation being returned. 1232 * 1233 * This should be re-evaluated at a later date, along with any 1234 * signal strength calculations which are made. Quite likely the 1235 * RSSI values will need to be adjusted to ensure the calculations 1236 * don't "wrap" when RSSI is less than the "adjusted" NF value. 1237 * ("Adjust" here is via ichan->noiseFloorAdjust.) 1238 */ 1239 for (i = 0; i < AH_MAX_CHAINS; i++) { 1240 nf_ctl[i] = ichan->noiseFloorCtl[i] + ath_hal_getNfAdjust(ah, ichan); 1241 nf_ext[i] = ichan->noiseFloorExt[i] + ath_hal_getNfAdjust(ah, ichan); 1242 } 1243 return 1; 1244 } 1245 } 1246 1247 /* 1248 * Process all valid raw noise floors into the dBm noise floor values. 1249 * Though our device has no reference for a dBm noise floor, we perform 1250 * a relative minimization of NF's based on the lowest NF found across a 1251 * channel scan. 1252 */ 1253 void 1254 ath_hal_process_noisefloor(struct ath_hal *ah) 1255 { 1256 HAL_CHANNEL_INTERNAL *c; 1257 int16_t correct2, correct5; 1258 int16_t lowest2, lowest5; 1259 int i; 1260 1261 /* 1262 * Find the lowest 2GHz and 5GHz noise floor values after adjusting 1263 * for statistically recorded NF/channel deviation. 1264 */ 1265 correct2 = lowest2 = 0; 1266 correct5 = lowest5 = 0; 1267 for (i = 0; i < AH_PRIVATE(ah)->ah_nchan; i++) { 1268 WIRELESS_MODE mode; 1269 int16_t nf; 1270 1271 c = &AH_PRIVATE(ah)->ah_channels[i]; 1272 if (c->rawNoiseFloor >= 0) 1273 continue; 1274 /* XXX can't identify proper mode */ 1275 mode = IS_CHAN_5GHZ(c) ? WIRELESS_MODE_11a : WIRELESS_MODE_11g; 1276 nf = c->rawNoiseFloor + NOISE_FLOOR[mode] + 1277 ath_hal_getNfAdjust(ah, c); 1278 if (IS_CHAN_5GHZ(c)) { 1279 if (nf < lowest5) { 1280 lowest5 = nf; 1281 correct5 = NOISE_FLOOR[mode] - 1282 (c->rawNoiseFloor + ath_hal_getNfAdjust(ah, c)); 1283 } 1284 } else { 1285 if (nf < lowest2) { 1286 lowest2 = nf; 1287 correct2 = NOISE_FLOOR[mode] - 1288 (c->rawNoiseFloor + ath_hal_getNfAdjust(ah, c)); 1289 } 1290 } 1291 } 1292 1293 /* Correct the channels to reach the expected NF value */ 1294 for (i = 0; i < AH_PRIVATE(ah)->ah_nchan; i++) { 1295 c = &AH_PRIVATE(ah)->ah_channels[i]; 1296 if (c->rawNoiseFloor >= 0) 1297 continue; 1298 /* Apply correction factor */ 1299 c->noiseFloorAdjust = ath_hal_getNfAdjust(ah, c) + 1300 (IS_CHAN_5GHZ(c) ? correct5 : correct2); 1301 HALDEBUG(ah, HAL_DEBUG_NFCAL, "%u raw nf %d adjust %d\n", 1302 c->channel, c->rawNoiseFloor, c->noiseFloorAdjust); 1303 } 1304 } 1305 1306 /* 1307 * INI support routines. 1308 */ 1309 1310 int 1311 ath_hal_ini_write(struct ath_hal *ah, const HAL_INI_ARRAY *ia, 1312 int col, int regWr) 1313 { 1314 int r; 1315 1316 HALASSERT(col < ia->cols); 1317 for (r = 0; r < ia->rows; r++) { 1318 OS_REG_WRITE(ah, HAL_INI_VAL(ia, r, 0), 1319 HAL_INI_VAL(ia, r, col)); 1320 1321 /* Analog shift register delay seems needed for Merlin - PR kern/154220 */ 1322 if (HAL_INI_VAL(ia, r, 0) >= 0x7800 && HAL_INI_VAL(ia, r, 0) < 0x7900) 1323 OS_DELAY(100); 1324 1325 DMA_YIELD(regWr); 1326 } 1327 return regWr; 1328 } 1329 1330 void 1331 ath_hal_ini_bank_setup(uint32_t data[], const HAL_INI_ARRAY *ia, int col) 1332 { 1333 int r; 1334 1335 HALASSERT(col < ia->cols); 1336 for (r = 0; r < ia->rows; r++) 1337 data[r] = HAL_INI_VAL(ia, r, col); 1338 } 1339 1340 int 1341 ath_hal_ini_bank_write(struct ath_hal *ah, const HAL_INI_ARRAY *ia, 1342 const uint32_t data[], int regWr) 1343 { 1344 int r; 1345 1346 for (r = 0; r < ia->rows; r++) { 1347 OS_REG_WRITE(ah, HAL_INI_VAL(ia, r, 0), data[r]); 1348 DMA_YIELD(regWr); 1349 } 1350 return regWr; 1351 } 1352 1353 /* 1354 * These are EEPROM board related routines which should likely live in 1355 * a helper library of some sort. 1356 */ 1357 1358 /************************************************************** 1359 * ath_ee_getLowerUppderIndex 1360 * 1361 * Return indices surrounding the value in sorted integer lists. 1362 * Requirement: the input list must be monotonically increasing 1363 * and populated up to the list size 1364 * Returns: match is set if an index in the array matches exactly 1365 * or a the target is before or after the range of the array. 1366 */ 1367 HAL_BOOL 1368 ath_ee_getLowerUpperIndex(uint8_t target, uint8_t *pList, uint16_t listSize, 1369 uint16_t *indexL, uint16_t *indexR) 1370 { 1371 uint16_t i; 1372 1373 /* 1374 * Check first and last elements for beyond ordered array cases. 1375 */ 1376 if (target <= pList[0]) { 1377 *indexL = *indexR = 0; 1378 return AH_TRUE; 1379 } 1380 if (target >= pList[listSize-1]) { 1381 *indexL = *indexR = (uint16_t)(listSize - 1); 1382 return AH_TRUE; 1383 } 1384 1385 /* look for value being near or between 2 values in list */ 1386 for (i = 0; i < listSize - 1; i++) { 1387 /* 1388 * If value is close to the current value of the list 1389 * then target is not between values, it is one of the values 1390 */ 1391 if (pList[i] == target) { 1392 *indexL = *indexR = i; 1393 return AH_TRUE; 1394 } 1395 /* 1396 * Look for value being between current value and next value 1397 * if so return these 2 values 1398 */ 1399 if (target < pList[i + 1]) { 1400 *indexL = i; 1401 *indexR = (uint16_t)(i + 1); 1402 return AH_FALSE; 1403 } 1404 } 1405 HALASSERT(0); 1406 *indexL = *indexR = 0; 1407 return AH_FALSE; 1408 } 1409 1410 /************************************************************** 1411 * ath_ee_FillVpdTable 1412 * 1413 * Fill the Vpdlist for indices Pmax-Pmin 1414 * Note: pwrMin, pwrMax and Vpdlist are all in dBm * 4 1415 */ 1416 HAL_BOOL 1417 ath_ee_FillVpdTable(uint8_t pwrMin, uint8_t pwrMax, uint8_t *pPwrList, 1418 uint8_t *pVpdList, uint16_t numIntercepts, uint8_t *pRetVpdList) 1419 { 1420 uint16_t i, k; 1421 uint8_t currPwr = pwrMin; 1422 uint16_t idxL, idxR; 1423 1424 HALASSERT(pwrMax > pwrMin); 1425 for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) { 1426 ath_ee_getLowerUpperIndex(currPwr, pPwrList, numIntercepts, 1427 &(idxL), &(idxR)); 1428 if (idxR < 1) 1429 idxR = 1; /* extrapolate below */ 1430 if (idxL == numIntercepts - 1) 1431 idxL = (uint16_t)(numIntercepts - 2); /* extrapolate above */ 1432 if (pPwrList[idxL] == pPwrList[idxR]) 1433 k = pVpdList[idxL]; 1434 else 1435 k = (uint16_t)( ((currPwr - pPwrList[idxL]) * pVpdList[idxR] + (pPwrList[idxR] - currPwr) * pVpdList[idxL]) / 1436 (pPwrList[idxR] - pPwrList[idxL]) ); 1437 HALASSERT(k < 256); 1438 pRetVpdList[i] = (uint8_t)k; 1439 currPwr += 2; /* half dB steps */ 1440 } 1441 1442 return AH_TRUE; 1443 } 1444 1445 /************************************************************************** 1446 * ath_ee_interpolate 1447 * 1448 * Returns signed interpolated or the scaled up interpolated value 1449 */ 1450 int16_t 1451 ath_ee_interpolate(uint16_t target, uint16_t srcLeft, uint16_t srcRight, 1452 int16_t targetLeft, int16_t targetRight) 1453 { 1454 int16_t rv; 1455 1456 if (srcRight == srcLeft) { 1457 rv = targetLeft; 1458 } else { 1459 rv = (int16_t)( ((target - srcLeft) * targetRight + 1460 (srcRight - target) * targetLeft) / (srcRight - srcLeft) ); 1461 } 1462 return rv; 1463 } 1464 1465 /* 1466 * Adjust the TSF. 1467 */ 1468 void 1469 ath_hal_adjusttsf(struct ath_hal *ah, int32_t tsfdelta) 1470 { 1471 /* XXX handle wrap/overflow */ 1472 OS_REG_WRITE(ah, AR_TSF_L32, OS_REG_READ(ah, AR_TSF_L32) + tsfdelta); 1473 } 1474 1475 /* 1476 * Enable or disable CCA. 1477 */ 1478 void 1479 ath_hal_setcca(struct ath_hal *ah, int ena) 1480 { 1481 /* 1482 * NB: fill me in; this is not provided by default because disabling 1483 * CCA in most locales violates regulatory. 1484 */ 1485 } 1486 1487 /* 1488 * Get CCA setting. 1489 * 1490 * XXX TODO: turn this and the above function into methods 1491 * in case there are chipset differences in handling CCA. 1492 */ 1493 int 1494 ath_hal_getcca(struct ath_hal *ah) 1495 { 1496 u_int32_t diag; 1497 if (ath_hal_getcapability(ah, HAL_CAP_DIAG, 0, &diag) != HAL_OK) 1498 return 1; 1499 return ((diag & 0x500000) == 0); 1500 } 1501 1502 /* 1503 * Set the current state of self-generated ACK and RTS/CTS frames. 1504 * 1505 * For correct DFS operation, the device should not even /ACK/ frames 1506 * that are sent to it during CAC or CSA. 1507 */ 1508 void 1509 ath_hal_set_dfs_cac_tx_quiet(struct ath_hal *ah, HAL_BOOL ena) 1510 { 1511 1512 if (ah->ah_setDfsCacTxQuiet == NULL) 1513 return; 1514 ah->ah_setDfsCacTxQuiet(ah, ena); 1515 } 1516 1517 /* 1518 * This routine is only needed when supporting EEPROM-in-RAM setups 1519 * (eg embedded SoCs and on-board PCI/PCIe devices.) 1520 */ 1521 /* NB: This is in 16 bit words; not bytes */ 1522 /* XXX This doesn't belong here! */ 1523 #define ATH_DATA_EEPROM_SIZE 2048 1524 1525 HAL_BOOL 1526 ath_hal_EepromDataRead(struct ath_hal *ah, u_int off, uint16_t *data) 1527 { 1528 if (ah->ah_eepromdata == AH_NULL) { 1529 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: no eeprom data!\n", __func__); 1530 return AH_FALSE; 1531 } 1532 if (off > ATH_DATA_EEPROM_SIZE) { 1533 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: offset %x > %x\n", 1534 __func__, off, ATH_DATA_EEPROM_SIZE); 1535 return AH_FALSE; 1536 } 1537 (*data) = ah->ah_eepromdata[off]; 1538 return AH_TRUE; 1539 } 1540 1541 /* 1542 * Do a 2GHz specific MHz->IEEE based on the hardware 1543 * frequency. 1544 * 1545 * This is the unmapped frequency which is programmed into the hardware. 1546 */ 1547 int 1548 ath_hal_mhz2ieee_2ghz(struct ath_hal *ah, int freq) 1549 { 1550 1551 if (freq == 2484) 1552 return 14; 1553 if (freq < 2484) 1554 return ((int) freq - 2407) / 5; 1555 else 1556 return 15 + ((freq - 2512) / 20); 1557 } 1558 1559 /* 1560 * Clear the current survey data. 1561 * 1562 * This should be done during a channel change. 1563 */ 1564 void 1565 ath_hal_survey_clear(struct ath_hal *ah) 1566 { 1567 1568 OS_MEMZERO(&AH_PRIVATE(ah)->ah_chansurvey, 1569 sizeof(AH_PRIVATE(ah)->ah_chansurvey)); 1570 } 1571 1572 /* 1573 * Add a sample to the channel survey. 1574 */ 1575 void 1576 ath_hal_survey_add_sample(struct ath_hal *ah, HAL_SURVEY_SAMPLE *hs) 1577 { 1578 HAL_CHANNEL_SURVEY *cs; 1579 1580 cs = &AH_PRIVATE(ah)->ah_chansurvey; 1581 1582 OS_MEMCPY(&cs->samples[cs->cur_sample], hs, sizeof(*hs)); 1583 cs->samples[cs->cur_sample].seq_num = cs->cur_seq; 1584 cs->cur_sample = (cs->cur_sample + 1) % CHANNEL_SURVEY_SAMPLE_COUNT; 1585 cs->cur_seq++; 1586 } 1587