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 duting 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->halTstampPrecision; 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_LONG_RXDESC_TSF: /* 32 bit TSF in RX descriptor? */ 782 return pCap->halHasLongRxDescTsf ? HAL_OK : HAL_ENOTSUPP; 783 case HAL_CAP_BB_READ_WAR: /* Baseband read WAR */ 784 return pCap->halHasBBReadWar? HAL_OK : HAL_ENOTSUPP; 785 case HAL_CAP_SERIALISE_WAR: /* PCI register serialisation */ 786 return pCap->halSerialiseRegWar ? HAL_OK : HAL_ENOTSUPP; 787 case HAL_CAP_MFP: /* Management frame protection setting */ 788 *result = pCap->halMfpSupport; 789 return HAL_OK; 790 case HAL_CAP_RX_LNA_MIXING: /* Hardware uses an RX LNA mixer to map 2 antennas to a 1 stream receiver */ 791 return pCap->halRxUsingLnaMixing ? HAL_OK : HAL_ENOTSUPP; 792 case HAL_CAP_DO_MYBEACON: /* Hardware supports filtering my-beacons */ 793 return pCap->halRxDoMyBeacon ? HAL_OK : HAL_ENOTSUPP; 794 default: 795 return HAL_EINVAL; 796 } 797 } 798 799 HAL_BOOL 800 ath_hal_setcapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type, 801 uint32_t capability, uint32_t setting, HAL_STATUS *status) 802 { 803 804 switch (type) { 805 case HAL_CAP_TXPOW: 806 switch (capability) { 807 case 3: 808 if (setting <= HAL_TP_SCALE_MIN) { 809 AH_PRIVATE(ah)->ah_tpScale = setting; 810 return AH_TRUE; 811 } 812 break; 813 } 814 break; 815 case HAL_CAP_RFSILENT: /* rfsilent support */ 816 /* 817 * NB: allow even if halRfSilentSupport is false 818 * in case the EEPROM is misprogrammed. 819 */ 820 switch (capability) { 821 case 1: /* current setting */ 822 AH_PRIVATE(ah)->ah_rfkillEnabled = (setting != 0); 823 return AH_TRUE; 824 case 2: /* rfsilent config */ 825 /* XXX better done per-chip for validation? */ 826 AH_PRIVATE(ah)->ah_rfsilent = setting; 827 return AH_TRUE; 828 } 829 break; 830 case HAL_CAP_REG_DMN: /* regulatory domain */ 831 AH_PRIVATE(ah)->ah_currentRD = setting; 832 return AH_TRUE; 833 case HAL_CAP_RXORN_FATAL: /* HAL_INT_RXORN treated as fatal */ 834 AH_PRIVATE(ah)->ah_rxornIsFatal = setting; 835 return AH_TRUE; 836 default: 837 break; 838 } 839 if (status) 840 *status = HAL_EINVAL; 841 return AH_FALSE; 842 } 843 844 /* 845 * Common support for getDiagState method. 846 */ 847 848 static u_int 849 ath_hal_getregdump(struct ath_hal *ah, const HAL_REGRANGE *regs, 850 void *dstbuf, int space) 851 { 852 uint32_t *dp = dstbuf; 853 int i; 854 855 for (i = 0; space >= 2*sizeof(uint32_t); i++) { 856 uint32_t r = regs[i].start; 857 uint32_t e = regs[i].end; 858 *dp++ = r; 859 *dp++ = e; 860 space -= 2*sizeof(uint32_t); 861 do { 862 *dp++ = OS_REG_READ(ah, r); 863 r += sizeof(uint32_t); 864 space -= sizeof(uint32_t); 865 } while (r <= e && space >= sizeof(uint32_t)); 866 } 867 return (char *) dp - (char *) dstbuf; 868 } 869 870 static void 871 ath_hal_setregs(struct ath_hal *ah, const HAL_REGWRITE *regs, int space) 872 { 873 while (space >= sizeof(HAL_REGWRITE)) { 874 OS_REG_WRITE(ah, regs->addr, regs->value); 875 regs++, space -= sizeof(HAL_REGWRITE); 876 } 877 } 878 879 HAL_BOOL 880 ath_hal_getdiagstate(struct ath_hal *ah, int request, 881 const void *args, uint32_t argsize, 882 void **result, uint32_t *resultsize) 883 { 884 885 switch (request) { 886 case HAL_DIAG_REVS: 887 *result = &AH_PRIVATE(ah)->ah_devid; 888 *resultsize = sizeof(HAL_REVS); 889 return AH_TRUE; 890 case HAL_DIAG_REGS: 891 *resultsize = ath_hal_getregdump(ah, args, *result,*resultsize); 892 return AH_TRUE; 893 case HAL_DIAG_SETREGS: 894 ath_hal_setregs(ah, args, argsize); 895 *resultsize = 0; 896 return AH_TRUE; 897 case HAL_DIAG_FATALERR: 898 *result = &AH_PRIVATE(ah)->ah_fatalState[0]; 899 *resultsize = sizeof(AH_PRIVATE(ah)->ah_fatalState); 900 return AH_TRUE; 901 case HAL_DIAG_EEREAD: 902 if (argsize != sizeof(uint16_t)) 903 return AH_FALSE; 904 if (!ath_hal_eepromRead(ah, *(const uint16_t *)args, *result)) 905 return AH_FALSE; 906 *resultsize = sizeof(uint16_t); 907 return AH_TRUE; 908 #ifdef AH_PRIVATE_DIAG 909 case HAL_DIAG_SETKEY: { 910 const HAL_DIAG_KEYVAL *dk; 911 912 if (argsize != sizeof(HAL_DIAG_KEYVAL)) 913 return AH_FALSE; 914 dk = (const HAL_DIAG_KEYVAL *)args; 915 return ah->ah_setKeyCacheEntry(ah, dk->dk_keyix, 916 &dk->dk_keyval, dk->dk_mac, dk->dk_xor); 917 } 918 case HAL_DIAG_RESETKEY: 919 if (argsize != sizeof(uint16_t)) 920 return AH_FALSE; 921 return ah->ah_resetKeyCacheEntry(ah, *(const uint16_t *)args); 922 #ifdef AH_SUPPORT_WRITE_EEPROM 923 case HAL_DIAG_EEWRITE: { 924 const HAL_DIAG_EEVAL *ee; 925 if (argsize != sizeof(HAL_DIAG_EEVAL)) 926 return AH_FALSE; 927 ee = (const HAL_DIAG_EEVAL *)args; 928 return ath_hal_eepromWrite(ah, ee->ee_off, ee->ee_data); 929 } 930 #endif /* AH_SUPPORT_WRITE_EEPROM */ 931 #endif /* AH_PRIVATE_DIAG */ 932 case HAL_DIAG_11NCOMPAT: 933 if (argsize == 0) { 934 *resultsize = sizeof(uint32_t); 935 *((uint32_t *)(*result)) = 936 AH_PRIVATE(ah)->ah_11nCompat; 937 } else if (argsize == sizeof(uint32_t)) { 938 AH_PRIVATE(ah)->ah_11nCompat = *(const uint32_t *)args; 939 } else 940 return AH_FALSE; 941 return AH_TRUE; 942 case HAL_DIAG_CHANSURVEY: 943 *result = &AH_PRIVATE(ah)->ah_chansurvey; 944 *resultsize = sizeof(HAL_CHANNEL_SURVEY); 945 return AH_TRUE; 946 } 947 return AH_FALSE; 948 } 949 950 /* 951 * Set the properties of the tx queue with the parameters 952 * from qInfo. 953 */ 954 HAL_BOOL 955 ath_hal_setTxQProps(struct ath_hal *ah, 956 HAL_TX_QUEUE_INFO *qi, const HAL_TXQ_INFO *qInfo) 957 { 958 uint32_t cw; 959 960 if (qi->tqi_type == HAL_TX_QUEUE_INACTIVE) { 961 HALDEBUG(ah, HAL_DEBUG_TXQUEUE, 962 "%s: inactive queue\n", __func__); 963 return AH_FALSE; 964 } 965 /* XXX validate parameters */ 966 qi->tqi_ver = qInfo->tqi_ver; 967 qi->tqi_subtype = qInfo->tqi_subtype; 968 qi->tqi_qflags = qInfo->tqi_qflags; 969 qi->tqi_priority = qInfo->tqi_priority; 970 if (qInfo->tqi_aifs != HAL_TXQ_USEDEFAULT) 971 qi->tqi_aifs = AH_MIN(qInfo->tqi_aifs, 255); 972 else 973 qi->tqi_aifs = INIT_AIFS; 974 if (qInfo->tqi_cwmin != HAL_TXQ_USEDEFAULT) { 975 cw = AH_MIN(qInfo->tqi_cwmin, 1024); 976 /* make sure that the CWmin is of the form (2^n - 1) */ 977 qi->tqi_cwmin = 1; 978 while (qi->tqi_cwmin < cw) 979 qi->tqi_cwmin = (qi->tqi_cwmin << 1) | 1; 980 } else 981 qi->tqi_cwmin = qInfo->tqi_cwmin; 982 if (qInfo->tqi_cwmax != HAL_TXQ_USEDEFAULT) { 983 cw = AH_MIN(qInfo->tqi_cwmax, 1024); 984 /* make sure that the CWmax is of the form (2^n - 1) */ 985 qi->tqi_cwmax = 1; 986 while (qi->tqi_cwmax < cw) 987 qi->tqi_cwmax = (qi->tqi_cwmax << 1) | 1; 988 } else 989 qi->tqi_cwmax = INIT_CWMAX; 990 /* Set retry limit values */ 991 if (qInfo->tqi_shretry != 0) 992 qi->tqi_shretry = AH_MIN(qInfo->tqi_shretry, 15); 993 else 994 qi->tqi_shretry = INIT_SH_RETRY; 995 if (qInfo->tqi_lgretry != 0) 996 qi->tqi_lgretry = AH_MIN(qInfo->tqi_lgretry, 15); 997 else 998 qi->tqi_lgretry = INIT_LG_RETRY; 999 qi->tqi_cbrPeriod = qInfo->tqi_cbrPeriod; 1000 qi->tqi_cbrOverflowLimit = qInfo->tqi_cbrOverflowLimit; 1001 qi->tqi_burstTime = qInfo->tqi_burstTime; 1002 qi->tqi_readyTime = qInfo->tqi_readyTime; 1003 1004 switch (qInfo->tqi_subtype) { 1005 case HAL_WME_UPSD: 1006 if (qi->tqi_type == HAL_TX_QUEUE_DATA) 1007 qi->tqi_intFlags = HAL_TXQ_USE_LOCKOUT_BKOFF_DIS; 1008 break; 1009 default: 1010 break; /* NB: silence compiler */ 1011 } 1012 return AH_TRUE; 1013 } 1014 1015 HAL_BOOL 1016 ath_hal_getTxQProps(struct ath_hal *ah, 1017 HAL_TXQ_INFO *qInfo, const HAL_TX_QUEUE_INFO *qi) 1018 { 1019 if (qi->tqi_type == HAL_TX_QUEUE_INACTIVE) { 1020 HALDEBUG(ah, HAL_DEBUG_TXQUEUE, 1021 "%s: inactive queue\n", __func__); 1022 return AH_FALSE; 1023 } 1024 1025 qInfo->tqi_qflags = qi->tqi_qflags; 1026 qInfo->tqi_ver = qi->tqi_ver; 1027 qInfo->tqi_subtype = qi->tqi_subtype; 1028 qInfo->tqi_qflags = qi->tqi_qflags; 1029 qInfo->tqi_priority = qi->tqi_priority; 1030 qInfo->tqi_aifs = qi->tqi_aifs; 1031 qInfo->tqi_cwmin = qi->tqi_cwmin; 1032 qInfo->tqi_cwmax = qi->tqi_cwmax; 1033 qInfo->tqi_shretry = qi->tqi_shretry; 1034 qInfo->tqi_lgretry = qi->tqi_lgretry; 1035 qInfo->tqi_cbrPeriod = qi->tqi_cbrPeriod; 1036 qInfo->tqi_cbrOverflowLimit = qi->tqi_cbrOverflowLimit; 1037 qInfo->tqi_burstTime = qi->tqi_burstTime; 1038 qInfo->tqi_readyTime = qi->tqi_readyTime; 1039 return AH_TRUE; 1040 } 1041 1042 /* 11a Turbo 11b 11g 108g */ 1043 static const int16_t NOISE_FLOOR[] = { -96, -93, -98, -96, -93 }; 1044 1045 /* 1046 * Read the current channel noise floor and return. 1047 * If nf cal hasn't finished, channel noise floor should be 0 1048 * and we return a nominal value based on band and frequency. 1049 * 1050 * NB: This is a private routine used by per-chip code to 1051 * implement the ah_getChanNoise method. 1052 */ 1053 int16_t 1054 ath_hal_getChanNoise(struct ath_hal *ah, const struct ieee80211_channel *chan) 1055 { 1056 HAL_CHANNEL_INTERNAL *ichan; 1057 1058 ichan = ath_hal_checkchannel(ah, chan); 1059 if (ichan == AH_NULL) { 1060 HALDEBUG(ah, HAL_DEBUG_NFCAL, 1061 "%s: invalid channel %u/0x%x; no mapping\n", 1062 __func__, chan->ic_freq, chan->ic_flags); 1063 return 0; 1064 } 1065 if (ichan->rawNoiseFloor == 0) { 1066 WIRELESS_MODE mode = ath_hal_chan2wmode(ah, chan); 1067 1068 HALASSERT(mode < WIRELESS_MODE_MAX); 1069 return NOISE_FLOOR[mode] + ath_hal_getNfAdjust(ah, ichan); 1070 } else 1071 return ichan->rawNoiseFloor + ichan->noiseFloorAdjust; 1072 } 1073 1074 /* 1075 * Fetch the current setup of ctl/ext noise floor values. 1076 * 1077 * If the CHANNEL_MIMO_NF_VALID flag isn't set, the array is simply 1078 * populated with values from NOISE_FLOOR[] + ath_hal_getNfAdjust(). 1079 * 1080 * The caller must supply ctl/ext NF arrays which are at least 1081 * AH_MAX_CHAINS entries long. 1082 */ 1083 int 1084 ath_hal_get_mimo_chan_noise(struct ath_hal *ah, 1085 const struct ieee80211_channel *chan, int16_t *nf_ctl, 1086 int16_t *nf_ext) 1087 { 1088 #ifdef AH_SUPPORT_AR5416 1089 HAL_CHANNEL_INTERNAL *ichan; 1090 int i; 1091 1092 ichan = ath_hal_checkchannel(ah, chan); 1093 if (ichan == AH_NULL) { 1094 HALDEBUG(ah, HAL_DEBUG_NFCAL, 1095 "%s: invalid channel %u/0x%x; no mapping\n", 1096 __func__, chan->ic_freq, chan->ic_flags); 1097 for (i = 0; i < AH_MAX_CHAINS; i++) { 1098 nf_ctl[i] = nf_ext[i] = 0; 1099 } 1100 return 0; 1101 } 1102 1103 /* Return 0 if there's no valid MIMO values (yet) */ 1104 if (! (ichan->privFlags & CHANNEL_MIMO_NF_VALID)) { 1105 for (i = 0; i < AH_MAX_CHAINS; i++) { 1106 nf_ctl[i] = nf_ext[i] = 0; 1107 } 1108 return 0; 1109 } 1110 if (ichan->rawNoiseFloor == 0) { 1111 WIRELESS_MODE mode = ath_hal_chan2wmode(ah, chan); 1112 HALASSERT(mode < WIRELESS_MODE_MAX); 1113 /* 1114 * See the comment below - this could cause issues for 1115 * stations which have a very low RSSI, below the 1116 * 'normalised' NF values in NOISE_FLOOR[]. 1117 */ 1118 for (i = 0; i < AH_MAX_CHAINS; i++) { 1119 nf_ctl[i] = nf_ext[i] = NOISE_FLOOR[mode] + 1120 ath_hal_getNfAdjust(ah, ichan); 1121 } 1122 return 1; 1123 } else { 1124 /* 1125 * The value returned here from a MIMO radio is presumed to be 1126 * "good enough" as a NF calculation. As RSSI values are calculated 1127 * against this, an adjusted NF may be higher than the RSSI value 1128 * returned from a vary weak station, resulting in an obscenely 1129 * high signal strength calculation being returned. 1130 * 1131 * This should be re-evaluated at a later date, along with any 1132 * signal strength calculations which are made. Quite likely the 1133 * RSSI values will need to be adjusted to ensure the calculations 1134 * don't "wrap" when RSSI is less than the "adjusted" NF value. 1135 * ("Adjust" here is via ichan->noiseFloorAdjust.) 1136 */ 1137 for (i = 0; i < AH_MAX_CHAINS; i++) { 1138 nf_ctl[i] = ichan->noiseFloorCtl[i] + ath_hal_getNfAdjust(ah, ichan); 1139 nf_ext[i] = ichan->noiseFloorExt[i] + ath_hal_getNfAdjust(ah, ichan); 1140 } 1141 return 1; 1142 } 1143 #else 1144 return 0; 1145 #endif /* AH_SUPPORT_AR5416 */ 1146 } 1147 1148 /* 1149 * Process all valid raw noise floors into the dBm noise floor values. 1150 * Though our device has no reference for a dBm noise floor, we perform 1151 * a relative minimization of NF's based on the lowest NF found across a 1152 * channel scan. 1153 */ 1154 void 1155 ath_hal_process_noisefloor(struct ath_hal *ah) 1156 { 1157 HAL_CHANNEL_INTERNAL *c; 1158 int16_t correct2, correct5; 1159 int16_t lowest2, lowest5; 1160 int i; 1161 1162 /* 1163 * Find the lowest 2GHz and 5GHz noise floor values after adjusting 1164 * for statistically recorded NF/channel deviation. 1165 */ 1166 correct2 = lowest2 = 0; 1167 correct5 = lowest5 = 0; 1168 for (i = 0; i < AH_PRIVATE(ah)->ah_nchan; i++) { 1169 WIRELESS_MODE mode; 1170 int16_t nf; 1171 1172 c = &AH_PRIVATE(ah)->ah_channels[i]; 1173 if (c->rawNoiseFloor >= 0) 1174 continue; 1175 /* XXX can't identify proper mode */ 1176 mode = IS_CHAN_5GHZ(c) ? WIRELESS_MODE_11a : WIRELESS_MODE_11g; 1177 nf = c->rawNoiseFloor + NOISE_FLOOR[mode] + 1178 ath_hal_getNfAdjust(ah, c); 1179 if (IS_CHAN_5GHZ(c)) { 1180 if (nf < lowest5) { 1181 lowest5 = nf; 1182 correct5 = NOISE_FLOOR[mode] - 1183 (c->rawNoiseFloor + ath_hal_getNfAdjust(ah, c)); 1184 } 1185 } else { 1186 if (nf < lowest2) { 1187 lowest2 = nf; 1188 correct2 = NOISE_FLOOR[mode] - 1189 (c->rawNoiseFloor + ath_hal_getNfAdjust(ah, c)); 1190 } 1191 } 1192 } 1193 1194 /* Correct the channels to reach the expected NF value */ 1195 for (i = 0; i < AH_PRIVATE(ah)->ah_nchan; i++) { 1196 c = &AH_PRIVATE(ah)->ah_channels[i]; 1197 if (c->rawNoiseFloor >= 0) 1198 continue; 1199 /* Apply correction factor */ 1200 c->noiseFloorAdjust = ath_hal_getNfAdjust(ah, c) + 1201 (IS_CHAN_5GHZ(c) ? correct5 : correct2); 1202 HALDEBUG(ah, HAL_DEBUG_NFCAL, "%u raw nf %d adjust %d\n", 1203 c->channel, c->rawNoiseFloor, c->noiseFloorAdjust); 1204 } 1205 } 1206 1207 /* 1208 * INI support routines. 1209 */ 1210 1211 int 1212 ath_hal_ini_write(struct ath_hal *ah, const HAL_INI_ARRAY *ia, 1213 int col, int regWr) 1214 { 1215 int r; 1216 1217 HALASSERT(col < ia->cols); 1218 for (r = 0; r < ia->rows; r++) { 1219 OS_REG_WRITE(ah, HAL_INI_VAL(ia, r, 0), 1220 HAL_INI_VAL(ia, r, col)); 1221 1222 /* Analog shift register delay seems needed for Merlin - PR kern/154220 */ 1223 if (HAL_INI_VAL(ia, r, 0) >= 0x7800 && HAL_INI_VAL(ia, r, 0) < 0x7900) 1224 OS_DELAY(100); 1225 1226 DMA_YIELD(regWr); 1227 } 1228 return regWr; 1229 } 1230 1231 void 1232 ath_hal_ini_bank_setup(uint32_t data[], const HAL_INI_ARRAY *ia, int col) 1233 { 1234 int r; 1235 1236 HALASSERT(col < ia->cols); 1237 for (r = 0; r < ia->rows; r++) 1238 data[r] = HAL_INI_VAL(ia, r, col); 1239 } 1240 1241 int 1242 ath_hal_ini_bank_write(struct ath_hal *ah, const HAL_INI_ARRAY *ia, 1243 const uint32_t data[], int regWr) 1244 { 1245 int r; 1246 1247 for (r = 0; r < ia->rows; r++) { 1248 OS_REG_WRITE(ah, HAL_INI_VAL(ia, r, 0), data[r]); 1249 DMA_YIELD(regWr); 1250 } 1251 return regWr; 1252 } 1253 1254 /* 1255 * These are EEPROM board related routines which should likely live in 1256 * a helper library of some sort. 1257 */ 1258 1259 /************************************************************** 1260 * ath_ee_getLowerUppderIndex 1261 * 1262 * Return indices surrounding the value in sorted integer lists. 1263 * Requirement: the input list must be monotonically increasing 1264 * and populated up to the list size 1265 * Returns: match is set if an index in the array matches exactly 1266 * or a the target is before or after the range of the array. 1267 */ 1268 HAL_BOOL 1269 ath_ee_getLowerUpperIndex(uint8_t target, uint8_t *pList, uint16_t listSize, 1270 uint16_t *indexL, uint16_t *indexR) 1271 { 1272 uint16_t i; 1273 1274 /* 1275 * Check first and last elements for beyond ordered array cases. 1276 */ 1277 if (target <= pList[0]) { 1278 *indexL = *indexR = 0; 1279 return AH_TRUE; 1280 } 1281 if (target >= pList[listSize-1]) { 1282 *indexL = *indexR = (uint16_t)(listSize - 1); 1283 return AH_TRUE; 1284 } 1285 1286 /* look for value being near or between 2 values in list */ 1287 for (i = 0; i < listSize - 1; i++) { 1288 /* 1289 * If value is close to the current value of the list 1290 * then target is not between values, it is one of the values 1291 */ 1292 if (pList[i] == target) { 1293 *indexL = *indexR = i; 1294 return AH_TRUE; 1295 } 1296 /* 1297 * Look for value being between current value and next value 1298 * if so return these 2 values 1299 */ 1300 if (target < pList[i + 1]) { 1301 *indexL = i; 1302 *indexR = (uint16_t)(i + 1); 1303 return AH_FALSE; 1304 } 1305 } 1306 HALASSERT(0); 1307 *indexL = *indexR = 0; 1308 return AH_FALSE; 1309 } 1310 1311 /************************************************************** 1312 * ath_ee_FillVpdTable 1313 * 1314 * Fill the Vpdlist for indices Pmax-Pmin 1315 * Note: pwrMin, pwrMax and Vpdlist are all in dBm * 4 1316 */ 1317 HAL_BOOL 1318 ath_ee_FillVpdTable(uint8_t pwrMin, uint8_t pwrMax, uint8_t *pPwrList, 1319 uint8_t *pVpdList, uint16_t numIntercepts, uint8_t *pRetVpdList) 1320 { 1321 uint16_t i, k; 1322 uint8_t currPwr = pwrMin; 1323 uint16_t idxL, idxR; 1324 1325 HALASSERT(pwrMax > pwrMin); 1326 for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) { 1327 ath_ee_getLowerUpperIndex(currPwr, pPwrList, numIntercepts, 1328 &(idxL), &(idxR)); 1329 if (idxR < 1) 1330 idxR = 1; /* extrapolate below */ 1331 if (idxL == numIntercepts - 1) 1332 idxL = (uint16_t)(numIntercepts - 2); /* extrapolate above */ 1333 if (pPwrList[idxL] == pPwrList[idxR]) 1334 k = pVpdList[idxL]; 1335 else 1336 k = (uint16_t)( ((currPwr - pPwrList[idxL]) * pVpdList[idxR] + (pPwrList[idxR] - currPwr) * pVpdList[idxL]) / 1337 (pPwrList[idxR] - pPwrList[idxL]) ); 1338 HALASSERT(k < 256); 1339 pRetVpdList[i] = (uint8_t)k; 1340 currPwr += 2; /* half dB steps */ 1341 } 1342 1343 return AH_TRUE; 1344 } 1345 1346 /************************************************************************** 1347 * ath_ee_interpolate 1348 * 1349 * Returns signed interpolated or the scaled up interpolated value 1350 */ 1351 int16_t 1352 ath_ee_interpolate(uint16_t target, uint16_t srcLeft, uint16_t srcRight, 1353 int16_t targetLeft, int16_t targetRight) 1354 { 1355 int16_t rv; 1356 1357 if (srcRight == srcLeft) { 1358 rv = targetLeft; 1359 } else { 1360 rv = (int16_t)( ((target - srcLeft) * targetRight + 1361 (srcRight - target) * targetLeft) / (srcRight - srcLeft) ); 1362 } 1363 return rv; 1364 } 1365 1366 /* 1367 * Adjust the TSF. 1368 */ 1369 void 1370 ath_hal_adjusttsf(struct ath_hal *ah, int32_t tsfdelta) 1371 { 1372 /* XXX handle wrap/overflow */ 1373 OS_REG_WRITE(ah, AR_TSF_L32, OS_REG_READ(ah, AR_TSF_L32) + tsfdelta); 1374 } 1375 1376 /* 1377 * Enable or disable CCA. 1378 */ 1379 void 1380 ath_hal_setcca(struct ath_hal *ah, int ena) 1381 { 1382 /* 1383 * NB: fill me in; this is not provided by default because disabling 1384 * CCA in most locales violates regulatory. 1385 */ 1386 } 1387 1388 /* 1389 * Get CCA setting. 1390 */ 1391 int 1392 ath_hal_getcca(struct ath_hal *ah) 1393 { 1394 u_int32_t diag; 1395 if (ath_hal_getcapability(ah, HAL_CAP_DIAG, 0, &diag) != HAL_OK) 1396 return 1; 1397 return ((diag & 0x500000) == 0); 1398 } 1399 1400 /* 1401 * This routine is only needed when supporting EEPROM-in-RAM setups 1402 * (eg embedded SoCs and on-board PCI/PCIe devices.) 1403 */ 1404 /* NB: This is in 16 bit words; not bytes */ 1405 /* XXX This doesn't belong here! */ 1406 #define ATH_DATA_EEPROM_SIZE 2048 1407 1408 HAL_BOOL 1409 ath_hal_EepromDataRead(struct ath_hal *ah, u_int off, uint16_t *data) 1410 { 1411 if (ah->ah_eepromdata == AH_NULL) { 1412 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: no eeprom data!\n", __func__); 1413 return AH_FALSE; 1414 } 1415 if (off > ATH_DATA_EEPROM_SIZE) { 1416 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: offset %x > %x\n", 1417 __func__, off, ATH_DATA_EEPROM_SIZE); 1418 return AH_FALSE; 1419 } 1420 (*data) = ah->ah_eepromdata[off]; 1421 return AH_TRUE; 1422 } 1423 1424 /* 1425 * Do a 2GHz specific MHz->IEEE based on the hardware 1426 * frequency. 1427 * 1428 * This is the unmapped frequency which is programmed into the hardware. 1429 */ 1430 int 1431 ath_hal_mhz2ieee_2ghz(struct ath_hal *ah, int freq) 1432 { 1433 1434 if (freq == 2484) 1435 return 14; 1436 if (freq < 2484) 1437 return ((int) freq - 2407) / 5; 1438 else 1439 return 15 + ((freq - 2512) / 20); 1440 } 1441 1442 /* 1443 * Clear the current survey data. 1444 * 1445 * This should be done during a channel change. 1446 */ 1447 void 1448 ath_hal_survey_clear(struct ath_hal *ah) 1449 { 1450 1451 OS_MEMZERO(&AH_PRIVATE(ah)->ah_chansurvey, 1452 sizeof(AH_PRIVATE(ah)->ah_chansurvey)); 1453 } 1454 1455 /* 1456 * Add a sample to the channel survey. 1457 */ 1458 void 1459 ath_hal_survey_add_sample(struct ath_hal *ah, HAL_SURVEY_SAMPLE *hs) 1460 { 1461 HAL_CHANNEL_SURVEY *cs; 1462 1463 cs = &AH_PRIVATE(ah)->ah_chansurvey; 1464 1465 OS_MEMCPY(&cs->samples[cs->cur_sample], hs, sizeof(*hs)); 1466 cs->samples[cs->cur_sample].seq_num = cs->cur_seq; 1467 cs->cur_sample = (cs->cur_sample + 1) % CHANNEL_SURVEY_SAMPLE_COUNT; 1468 cs->cur_seq++; 1469 } 1470