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