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