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->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 } 943 return AH_FALSE; 944 } 945 946 /* 947 * Set the properties of the tx queue with the parameters 948 * from qInfo. 949 */ 950 HAL_BOOL 951 ath_hal_setTxQProps(struct ath_hal *ah, 952 HAL_TX_QUEUE_INFO *qi, const HAL_TXQ_INFO *qInfo) 953 { 954 uint32_t cw; 955 956 if (qi->tqi_type == HAL_TX_QUEUE_INACTIVE) { 957 HALDEBUG(ah, HAL_DEBUG_TXQUEUE, 958 "%s: inactive queue\n", __func__); 959 return AH_FALSE; 960 } 961 /* XXX validate parameters */ 962 qi->tqi_ver = qInfo->tqi_ver; 963 qi->tqi_subtype = qInfo->tqi_subtype; 964 qi->tqi_qflags = qInfo->tqi_qflags; 965 qi->tqi_priority = qInfo->tqi_priority; 966 if (qInfo->tqi_aifs != HAL_TXQ_USEDEFAULT) 967 qi->tqi_aifs = AH_MIN(qInfo->tqi_aifs, 255); 968 else 969 qi->tqi_aifs = INIT_AIFS; 970 if (qInfo->tqi_cwmin != HAL_TXQ_USEDEFAULT) { 971 cw = AH_MIN(qInfo->tqi_cwmin, 1024); 972 /* make sure that the CWmin is of the form (2^n - 1) */ 973 qi->tqi_cwmin = 1; 974 while (qi->tqi_cwmin < cw) 975 qi->tqi_cwmin = (qi->tqi_cwmin << 1) | 1; 976 } else 977 qi->tqi_cwmin = qInfo->tqi_cwmin; 978 if (qInfo->tqi_cwmax != HAL_TXQ_USEDEFAULT) { 979 cw = AH_MIN(qInfo->tqi_cwmax, 1024); 980 /* make sure that the CWmax is of the form (2^n - 1) */ 981 qi->tqi_cwmax = 1; 982 while (qi->tqi_cwmax < cw) 983 qi->tqi_cwmax = (qi->tqi_cwmax << 1) | 1; 984 } else 985 qi->tqi_cwmax = INIT_CWMAX; 986 /* Set retry limit values */ 987 if (qInfo->tqi_shretry != 0) 988 qi->tqi_shretry = AH_MIN(qInfo->tqi_shretry, 15); 989 else 990 qi->tqi_shretry = INIT_SH_RETRY; 991 if (qInfo->tqi_lgretry != 0) 992 qi->tqi_lgretry = AH_MIN(qInfo->tqi_lgretry, 15); 993 else 994 qi->tqi_lgretry = INIT_LG_RETRY; 995 qi->tqi_cbrPeriod = qInfo->tqi_cbrPeriod; 996 qi->tqi_cbrOverflowLimit = qInfo->tqi_cbrOverflowLimit; 997 qi->tqi_burstTime = qInfo->tqi_burstTime; 998 qi->tqi_readyTime = qInfo->tqi_readyTime; 999 1000 switch (qInfo->tqi_subtype) { 1001 case HAL_WME_UPSD: 1002 if (qi->tqi_type == HAL_TX_QUEUE_DATA) 1003 qi->tqi_intFlags = HAL_TXQ_USE_LOCKOUT_BKOFF_DIS; 1004 break; 1005 default: 1006 break; /* NB: silence compiler */ 1007 } 1008 return AH_TRUE; 1009 } 1010 1011 HAL_BOOL 1012 ath_hal_getTxQProps(struct ath_hal *ah, 1013 HAL_TXQ_INFO *qInfo, const HAL_TX_QUEUE_INFO *qi) 1014 { 1015 if (qi->tqi_type == HAL_TX_QUEUE_INACTIVE) { 1016 HALDEBUG(ah, HAL_DEBUG_TXQUEUE, 1017 "%s: inactive queue\n", __func__); 1018 return AH_FALSE; 1019 } 1020 1021 qInfo->tqi_qflags = qi->tqi_qflags; 1022 qInfo->tqi_ver = qi->tqi_ver; 1023 qInfo->tqi_subtype = qi->tqi_subtype; 1024 qInfo->tqi_qflags = qi->tqi_qflags; 1025 qInfo->tqi_priority = qi->tqi_priority; 1026 qInfo->tqi_aifs = qi->tqi_aifs; 1027 qInfo->tqi_cwmin = qi->tqi_cwmin; 1028 qInfo->tqi_cwmax = qi->tqi_cwmax; 1029 qInfo->tqi_shretry = qi->tqi_shretry; 1030 qInfo->tqi_lgretry = qi->tqi_lgretry; 1031 qInfo->tqi_cbrPeriod = qi->tqi_cbrPeriod; 1032 qInfo->tqi_cbrOverflowLimit = qi->tqi_cbrOverflowLimit; 1033 qInfo->tqi_burstTime = qi->tqi_burstTime; 1034 qInfo->tqi_readyTime = qi->tqi_readyTime; 1035 return AH_TRUE; 1036 } 1037 1038 /* 11a Turbo 11b 11g 108g */ 1039 static const int16_t NOISE_FLOOR[] = { -96, -93, -98, -96, -93 }; 1040 1041 /* 1042 * Read the current channel noise floor and return. 1043 * If nf cal hasn't finished, channel noise floor should be 0 1044 * and we return a nominal value based on band and frequency. 1045 * 1046 * NB: This is a private routine used by per-chip code to 1047 * implement the ah_getChanNoise method. 1048 */ 1049 int16_t 1050 ath_hal_getChanNoise(struct ath_hal *ah, const struct ieee80211_channel *chan) 1051 { 1052 HAL_CHANNEL_INTERNAL *ichan; 1053 1054 ichan = ath_hal_checkchannel(ah, chan); 1055 if (ichan == AH_NULL) { 1056 HALDEBUG(ah, HAL_DEBUG_NFCAL, 1057 "%s: invalid channel %u/0x%x; no mapping\n", 1058 __func__, chan->ic_freq, chan->ic_flags); 1059 return 0; 1060 } 1061 if (ichan->rawNoiseFloor == 0) { 1062 WIRELESS_MODE mode = ath_hal_chan2wmode(ah, chan); 1063 1064 HALASSERT(mode < WIRELESS_MODE_MAX); 1065 return NOISE_FLOOR[mode] + ath_hal_getNfAdjust(ah, ichan); 1066 } else 1067 return ichan->rawNoiseFloor + ichan->noiseFloorAdjust; 1068 } 1069 1070 /* 1071 * Fetch the current setup of ctl/ext noise floor values. 1072 * 1073 * If the CHANNEL_MIMO_NF_VALID flag isn't set, the array is simply 1074 * populated with values from NOISE_FLOOR[] + ath_hal_getNfAdjust(). 1075 * 1076 * The caller must supply ctl/ext NF arrays which are at least 1077 * AH_MAX_CHAINS entries long. 1078 */ 1079 int 1080 ath_hal_get_mimo_chan_noise(struct ath_hal *ah, 1081 const struct ieee80211_channel *chan, int16_t *nf_ctl, 1082 int16_t *nf_ext) 1083 { 1084 #ifdef AH_SUPPORT_AR5416 1085 HAL_CHANNEL_INTERNAL *ichan; 1086 int i; 1087 1088 ichan = ath_hal_checkchannel(ah, chan); 1089 if (ichan == AH_NULL) { 1090 HALDEBUG(ah, HAL_DEBUG_NFCAL, 1091 "%s: invalid channel %u/0x%x; no mapping\n", 1092 __func__, chan->ic_freq, chan->ic_flags); 1093 for (i = 0; i < AH_MAX_CHAINS; i++) { 1094 nf_ctl[i] = nf_ext[i] = 0; 1095 } 1096 return 0; 1097 } 1098 1099 /* Return 0 if there's no valid MIMO values (yet) */ 1100 if (! (ichan->privFlags & CHANNEL_MIMO_NF_VALID)) { 1101 for (i = 0; i < AH_MAX_CHAINS; i++) { 1102 nf_ctl[i] = nf_ext[i] = 0; 1103 } 1104 return 0; 1105 } 1106 if (ichan->rawNoiseFloor == 0) { 1107 WIRELESS_MODE mode = ath_hal_chan2wmode(ah, chan); 1108 HALASSERT(mode < WIRELESS_MODE_MAX); 1109 /* 1110 * See the comment below - this could cause issues for 1111 * stations which have a very low RSSI, below the 1112 * 'normalised' NF values in NOISE_FLOOR[]. 1113 */ 1114 for (i = 0; i < AH_MAX_CHAINS; i++) { 1115 nf_ctl[i] = nf_ext[i] = NOISE_FLOOR[mode] + 1116 ath_hal_getNfAdjust(ah, ichan); 1117 } 1118 return 1; 1119 } else { 1120 /* 1121 * The value returned here from a MIMO radio is presumed to be 1122 * "good enough" as a NF calculation. As RSSI values are calculated 1123 * against this, an adjusted NF may be higher than the RSSI value 1124 * returned from a vary weak station, resulting in an obscenely 1125 * high signal strength calculation being returned. 1126 * 1127 * This should be re-evaluated at a later date, along with any 1128 * signal strength calculations which are made. Quite likely the 1129 * RSSI values will need to be adjusted to ensure the calculations 1130 * don't "wrap" when RSSI is less than the "adjusted" NF value. 1131 * ("Adjust" here is via ichan->noiseFloorAdjust.) 1132 */ 1133 for (i = 0; i < AH_MAX_CHAINS; i++) { 1134 nf_ctl[i] = ichan->noiseFloorCtl[i] + ath_hal_getNfAdjust(ah, ichan); 1135 nf_ext[i] = ichan->noiseFloorExt[i] + ath_hal_getNfAdjust(ah, ichan); 1136 } 1137 return 1; 1138 } 1139 #else 1140 return 0; 1141 #endif /* AH_SUPPORT_AR5416 */ 1142 } 1143 1144 /* 1145 * Process all valid raw noise floors into the dBm noise floor values. 1146 * Though our device has no reference for a dBm noise floor, we perform 1147 * a relative minimization of NF's based on the lowest NF found across a 1148 * channel scan. 1149 */ 1150 void 1151 ath_hal_process_noisefloor(struct ath_hal *ah) 1152 { 1153 HAL_CHANNEL_INTERNAL *c; 1154 int16_t correct2, correct5; 1155 int16_t lowest2, lowest5; 1156 int i; 1157 1158 /* 1159 * Find the lowest 2GHz and 5GHz noise floor values after adjusting 1160 * for statistically recorded NF/channel deviation. 1161 */ 1162 correct2 = lowest2 = 0; 1163 correct5 = lowest5 = 0; 1164 for (i = 0; i < AH_PRIVATE(ah)->ah_nchan; i++) { 1165 WIRELESS_MODE mode; 1166 int16_t nf; 1167 1168 c = &AH_PRIVATE(ah)->ah_channels[i]; 1169 if (c->rawNoiseFloor >= 0) 1170 continue; 1171 /* XXX can't identify proper mode */ 1172 mode = IS_CHAN_5GHZ(c) ? WIRELESS_MODE_11a : WIRELESS_MODE_11g; 1173 nf = c->rawNoiseFloor + NOISE_FLOOR[mode] + 1174 ath_hal_getNfAdjust(ah, c); 1175 if (IS_CHAN_5GHZ(c)) { 1176 if (nf < lowest5) { 1177 lowest5 = nf; 1178 correct5 = NOISE_FLOOR[mode] - 1179 (c->rawNoiseFloor + ath_hal_getNfAdjust(ah, c)); 1180 } 1181 } else { 1182 if (nf < lowest2) { 1183 lowest2 = nf; 1184 correct2 = NOISE_FLOOR[mode] - 1185 (c->rawNoiseFloor + ath_hal_getNfAdjust(ah, c)); 1186 } 1187 } 1188 } 1189 1190 /* Correct the channels to reach the expected NF value */ 1191 for (i = 0; i < AH_PRIVATE(ah)->ah_nchan; i++) { 1192 c = &AH_PRIVATE(ah)->ah_channels[i]; 1193 if (c->rawNoiseFloor >= 0) 1194 continue; 1195 /* Apply correction factor */ 1196 c->noiseFloorAdjust = ath_hal_getNfAdjust(ah, c) + 1197 (IS_CHAN_5GHZ(c) ? correct5 : correct2); 1198 HALDEBUG(ah, HAL_DEBUG_NFCAL, "%u raw nf %d adjust %d\n", 1199 c->channel, c->rawNoiseFloor, c->noiseFloorAdjust); 1200 } 1201 } 1202 1203 /* 1204 * INI support routines. 1205 */ 1206 1207 int 1208 ath_hal_ini_write(struct ath_hal *ah, const HAL_INI_ARRAY *ia, 1209 int col, int regWr) 1210 { 1211 int r; 1212 1213 HALASSERT(col < ia->cols); 1214 for (r = 0; r < ia->rows; r++) { 1215 OS_REG_WRITE(ah, HAL_INI_VAL(ia, r, 0), 1216 HAL_INI_VAL(ia, r, col)); 1217 1218 /* Analog shift register delay seems needed for Merlin - PR kern/154220 */ 1219 if (HAL_INI_VAL(ia, r, 0) >= 0x7800 && HAL_INI_VAL(ia, r, 0) < 0x7900) 1220 OS_DELAY(100); 1221 1222 DMA_YIELD(regWr); 1223 } 1224 return regWr; 1225 } 1226 1227 void 1228 ath_hal_ini_bank_setup(uint32_t data[], const HAL_INI_ARRAY *ia, int col) 1229 { 1230 int r; 1231 1232 HALASSERT(col < ia->cols); 1233 for (r = 0; r < ia->rows; r++) 1234 data[r] = HAL_INI_VAL(ia, r, col); 1235 } 1236 1237 int 1238 ath_hal_ini_bank_write(struct ath_hal *ah, const HAL_INI_ARRAY *ia, 1239 const uint32_t data[], int regWr) 1240 { 1241 int r; 1242 1243 for (r = 0; r < ia->rows; r++) { 1244 OS_REG_WRITE(ah, HAL_INI_VAL(ia, r, 0), data[r]); 1245 DMA_YIELD(regWr); 1246 } 1247 return regWr; 1248 } 1249 1250 /* 1251 * These are EEPROM board related routines which should likely live in 1252 * a helper library of some sort. 1253 */ 1254 1255 /************************************************************** 1256 * ath_ee_getLowerUppderIndex 1257 * 1258 * Return indices surrounding the value in sorted integer lists. 1259 * Requirement: the input list must be monotonically increasing 1260 * and populated up to the list size 1261 * Returns: match is set if an index in the array matches exactly 1262 * or a the target is before or after the range of the array. 1263 */ 1264 HAL_BOOL 1265 ath_ee_getLowerUpperIndex(uint8_t target, uint8_t *pList, uint16_t listSize, 1266 uint16_t *indexL, uint16_t *indexR) 1267 { 1268 uint16_t i; 1269 1270 /* 1271 * Check first and last elements for beyond ordered array cases. 1272 */ 1273 if (target <= pList[0]) { 1274 *indexL = *indexR = 0; 1275 return AH_TRUE; 1276 } 1277 if (target >= pList[listSize-1]) { 1278 *indexL = *indexR = (uint16_t)(listSize - 1); 1279 return AH_TRUE; 1280 } 1281 1282 /* look for value being near or between 2 values in list */ 1283 for (i = 0; i < listSize - 1; i++) { 1284 /* 1285 * If value is close to the current value of the list 1286 * then target is not between values, it is one of the values 1287 */ 1288 if (pList[i] == target) { 1289 *indexL = *indexR = i; 1290 return AH_TRUE; 1291 } 1292 /* 1293 * Look for value being between current value and next value 1294 * if so return these 2 values 1295 */ 1296 if (target < pList[i + 1]) { 1297 *indexL = i; 1298 *indexR = (uint16_t)(i + 1); 1299 return AH_FALSE; 1300 } 1301 } 1302 HALASSERT(0); 1303 *indexL = *indexR = 0; 1304 return AH_FALSE; 1305 } 1306 1307 /************************************************************** 1308 * ath_ee_FillVpdTable 1309 * 1310 * Fill the Vpdlist for indices Pmax-Pmin 1311 * Note: pwrMin, pwrMax and Vpdlist are all in dBm * 4 1312 */ 1313 HAL_BOOL 1314 ath_ee_FillVpdTable(uint8_t pwrMin, uint8_t pwrMax, uint8_t *pPwrList, 1315 uint8_t *pVpdList, uint16_t numIntercepts, uint8_t *pRetVpdList) 1316 { 1317 uint16_t i, k; 1318 uint8_t currPwr = pwrMin; 1319 uint16_t idxL, idxR; 1320 1321 HALASSERT(pwrMax > pwrMin); 1322 for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) { 1323 ath_ee_getLowerUpperIndex(currPwr, pPwrList, numIntercepts, 1324 &(idxL), &(idxR)); 1325 if (idxR < 1) 1326 idxR = 1; /* extrapolate below */ 1327 if (idxL == numIntercepts - 1) 1328 idxL = (uint16_t)(numIntercepts - 2); /* extrapolate above */ 1329 if (pPwrList[idxL] == pPwrList[idxR]) 1330 k = pVpdList[idxL]; 1331 else 1332 k = (uint16_t)( ((currPwr - pPwrList[idxL]) * pVpdList[idxR] + (pPwrList[idxR] - currPwr) * pVpdList[idxL]) / 1333 (pPwrList[idxR] - pPwrList[idxL]) ); 1334 HALASSERT(k < 256); 1335 pRetVpdList[i] = (uint8_t)k; 1336 currPwr += 2; /* half dB steps */ 1337 } 1338 1339 return AH_TRUE; 1340 } 1341 1342 /************************************************************************** 1343 * ath_ee_interpolate 1344 * 1345 * Returns signed interpolated or the scaled up interpolated value 1346 */ 1347 int16_t 1348 ath_ee_interpolate(uint16_t target, uint16_t srcLeft, uint16_t srcRight, 1349 int16_t targetLeft, int16_t targetRight) 1350 { 1351 int16_t rv; 1352 1353 if (srcRight == srcLeft) { 1354 rv = targetLeft; 1355 } else { 1356 rv = (int16_t)( ((target - srcLeft) * targetRight + 1357 (srcRight - target) * targetLeft) / (srcRight - srcLeft) ); 1358 } 1359 return rv; 1360 } 1361 1362 /* 1363 * Adjust the TSF. 1364 */ 1365 void 1366 ath_hal_adjusttsf(struct ath_hal *ah, int32_t tsfdelta) 1367 { 1368 /* XXX handle wrap/overflow */ 1369 OS_REG_WRITE(ah, AR_TSF_L32, OS_REG_READ(ah, AR_TSF_L32) + tsfdelta); 1370 } 1371 1372 /* 1373 * Enable or disable CCA. 1374 */ 1375 void 1376 ath_hal_setcca(struct ath_hal *ah, int ena) 1377 { 1378 /* 1379 * NB: fill me in; this is not provided by default because disabling 1380 * CCA in most locales violates regulatory. 1381 */ 1382 } 1383 1384 /* 1385 * Get CCA setting. 1386 */ 1387 int 1388 ath_hal_getcca(struct ath_hal *ah) 1389 { 1390 u_int32_t diag; 1391 if (ath_hal_getcapability(ah, HAL_CAP_DIAG, 0, &diag) != HAL_OK) 1392 return 1; 1393 return ((diag & 0x500000) == 0); 1394 } 1395 1396 /* 1397 * This routine is only needed when supporting EEPROM-in-RAM setups 1398 * (eg embedded SoCs and on-board PCI/PCIe devices.) 1399 */ 1400 /* NB: This is in 16 bit words; not bytes */ 1401 /* XXX This doesn't belong here! */ 1402 #define ATH_DATA_EEPROM_SIZE 2048 1403 1404 HAL_BOOL 1405 ath_hal_EepromDataRead(struct ath_hal *ah, u_int off, uint16_t *data) 1406 { 1407 if (ah->ah_eepromdata == AH_NULL) { 1408 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: no eeprom data!\n", __func__); 1409 return AH_FALSE; 1410 } 1411 if (off > ATH_DATA_EEPROM_SIZE) { 1412 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: offset %x > %x\n", 1413 __func__, off, ATH_DATA_EEPROM_SIZE); 1414 return AH_FALSE; 1415 } 1416 (*data) = ah->ah_eepromdata[off]; 1417 return AH_TRUE; 1418 } 1419 1420 /* 1421 * Do a 2GHz specific MHz->IEEE based on the hardware 1422 * frequency. 1423 * 1424 * This is the unmapped frequency which is programmed into the hardware. 1425 */ 1426 int 1427 ath_hal_mhz2ieee_2ghz(struct ath_hal *ah, int freq) 1428 { 1429 1430 if (freq == 2484) 1431 return 14; 1432 if (freq < 2484) 1433 return ((int) freq - 2407) / 5; 1434 else 1435 return 15 + ((freq - 2512) / 20); 1436 } 1437 1438 /* 1439 * Clear the current survey data. 1440 * 1441 * This should be done during a channel change. 1442 */ 1443 void 1444 ath_hal_survey_clear(struct ath_hal *ah) 1445 { 1446 OS_MEMZERO(&AH_PRIVATE(ah)->ah_chansurvey, 1447 sizeof(AH_PRIVATE(ah)->ah_chansurvey)); 1448 } 1449 1450 /* 1451 * Add a sample to the channel survey. 1452 */ 1453 void 1454 ath_hal_survey_add_sample(struct ath_hal *ah, HAL_SURVEY_SAMPLE *hs) 1455 { 1456 HAL_CHANNEL_SURVEY *cs; 1457 1458 cs = &AH_PRIVATE(ah)->ah_chansurvey; 1459 1460 OS_MEMCPY(&cs->samples[cs->cur_sample], hs, sizeof(*hs)); 1461 cs->samples[cs->cur_sample].seq_num = cs->cur_seq; 1462 cs->cur_sample = (cs->cur_sample + 1) % CHANNEL_SURVEY_SAMPLE_COUNT; 1463 cs->cur_seq++; 1464 } 1465