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