1 /* 2 * Copyright (c) 2002-2009 Sam Leffler, Errno Consulting 3 * Copyright (c) 2002-2008 Atheros Communications, Inc. 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 * 17 * $FreeBSD$ 18 */ 19 #include "opt_ah.h" 20 21 #include "ah.h" 22 #include "ah_internal.h" 23 #include "ah_devid.h" 24 #include "ah_eeprom.h" /* for 5ghz fast clock flag */ 25 26 #include "ar5416/ar5416reg.h" /* NB: includes ar5212reg.h */ 27 #include "ar9003/ar9300_devid.h" 28 29 /* linker set of registered chips */ 30 OS_SET_DECLARE(ah_chips, struct ath_hal_chip); 31 32 /* 33 * Check the set of registered chips to see if any recognize 34 * the device as one they can support. 35 */ 36 const char* 37 ath_hal_probe(uint16_t vendorid, uint16_t devid) 38 { 39 struct ath_hal_chip * const *pchip; 40 41 OS_SET_FOREACH(pchip, ah_chips) { 42 const char *name = (*pchip)->probe(vendorid, devid); 43 if (name != AH_NULL) 44 return name; 45 } 46 return AH_NULL; 47 } 48 49 /* 50 * Attach detects device chip revisions, initializes the hwLayer 51 * function list, reads EEPROM information, 52 * selects reset vectors, and performs a short self test. 53 * Any failures will return an error that should cause a hardware 54 * disable. 55 */ 56 struct ath_hal* 57 ath_hal_attach(uint16_t devid, HAL_SOFTC sc, 58 HAL_BUS_TAG st, HAL_BUS_HANDLE sh, uint16_t *eepromdata, 59 HAL_OPS_CONFIG *ah_config, 60 HAL_STATUS *error) 61 { 62 struct ath_hal_chip * const *pchip; 63 64 OS_SET_FOREACH(pchip, ah_chips) { 65 struct ath_hal_chip *chip = *pchip; 66 struct ath_hal *ah; 67 68 /* XXX don't have vendorid, assume atheros one works */ 69 if (chip->probe(ATHEROS_VENDOR_ID, devid) == AH_NULL) 70 continue; 71 ah = chip->attach(devid, sc, st, sh, eepromdata, ah_config, 72 error); 73 if (ah != AH_NULL) { 74 /* copy back private state to public area */ 75 ah->ah_devid = AH_PRIVATE(ah)->ah_devid; 76 ah->ah_subvendorid = AH_PRIVATE(ah)->ah_subvendorid; 77 ah->ah_macVersion = AH_PRIVATE(ah)->ah_macVersion; 78 ah->ah_macRev = AH_PRIVATE(ah)->ah_macRev; 79 ah->ah_phyRev = AH_PRIVATE(ah)->ah_phyRev; 80 ah->ah_analog5GhzRev = AH_PRIVATE(ah)->ah_analog5GhzRev; 81 ah->ah_analog2GhzRev = AH_PRIVATE(ah)->ah_analog2GhzRev; 82 return ah; 83 } 84 } 85 return AH_NULL; 86 } 87 88 const char * 89 ath_hal_mac_name(struct ath_hal *ah) 90 { 91 switch (ah->ah_macVersion) { 92 case AR_SREV_VERSION_CRETE: 93 case AR_SREV_VERSION_MAUI_1: 94 return "5210"; 95 case AR_SREV_VERSION_MAUI_2: 96 case AR_SREV_VERSION_OAHU: 97 return "5211"; 98 case AR_SREV_VERSION_VENICE: 99 return "5212"; 100 case AR_SREV_VERSION_GRIFFIN: 101 return "2413"; 102 case AR_SREV_VERSION_CONDOR: 103 return "5424"; 104 case AR_SREV_VERSION_EAGLE: 105 return "5413"; 106 case AR_SREV_VERSION_COBRA: 107 return "2415"; 108 case AR_SREV_2425: /* Swan */ 109 return "2425"; 110 case AR_SREV_2417: /* Nala */ 111 return "2417"; 112 case AR_XSREV_VERSION_OWL_PCI: 113 return "5416"; 114 case AR_XSREV_VERSION_OWL_PCIE: 115 return "5418"; 116 case AR_XSREV_VERSION_HOWL: 117 return "9130"; 118 case AR_XSREV_VERSION_SOWL: 119 return "9160"; 120 case AR_XSREV_VERSION_MERLIN: 121 if (AH_PRIVATE(ah)->ah_ispcie) 122 return "9280"; 123 return "9220"; 124 case AR_XSREV_VERSION_KITE: 125 return "9285"; 126 case AR_XSREV_VERSION_KIWI: 127 if (AH_PRIVATE(ah)->ah_ispcie) 128 return "9287"; 129 return "9227"; 130 case AR_SREV_VERSION_AR9380: 131 if (ah->ah_macRev >= AR_SREV_REVISION_AR9580_10) 132 return "9580"; 133 return "9380"; 134 case AR_SREV_VERSION_AR9460: 135 return "9460"; 136 case AR_SREV_VERSION_AR9330: 137 return "9330"; 138 case AR_SREV_VERSION_AR9340: 139 return "9340"; 140 case AR_SREV_VERSION_QCA9550: 141 /* XXX should say QCA, not AR */ 142 return "9550"; 143 case AR_SREV_VERSION_AR9485: 144 return "9485"; 145 case AR_SREV_VERSION_QCA9565: 146 /* XXX should say QCA, not AR */ 147 return "9565"; 148 } 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 switch (request) { 885 case HAL_DIAG_REVS: 886 *result = &AH_PRIVATE(ah)->ah_devid; 887 *resultsize = sizeof(HAL_REVS); 888 return AH_TRUE; 889 case HAL_DIAG_REGS: 890 *resultsize = ath_hal_getregdump(ah, args, *result,*resultsize); 891 return AH_TRUE; 892 case HAL_DIAG_SETREGS: 893 ath_hal_setregs(ah, args, argsize); 894 *resultsize = 0; 895 return AH_TRUE; 896 case HAL_DIAG_FATALERR: 897 *result = &AH_PRIVATE(ah)->ah_fatalState[0]; 898 *resultsize = sizeof(AH_PRIVATE(ah)->ah_fatalState); 899 return AH_TRUE; 900 case HAL_DIAG_EEREAD: 901 if (argsize != sizeof(uint16_t)) 902 return AH_FALSE; 903 if (!ath_hal_eepromRead(ah, *(const uint16_t *)args, *result)) 904 return AH_FALSE; 905 *resultsize = sizeof(uint16_t); 906 return AH_TRUE; 907 #ifdef AH_PRIVATE_DIAG 908 case HAL_DIAG_SETKEY: { 909 const HAL_DIAG_KEYVAL *dk; 910 911 if (argsize != sizeof(HAL_DIAG_KEYVAL)) 912 return AH_FALSE; 913 dk = (const HAL_DIAG_KEYVAL *)args; 914 return ah->ah_setKeyCacheEntry(ah, dk->dk_keyix, 915 &dk->dk_keyval, dk->dk_mac, dk->dk_xor); 916 } 917 case HAL_DIAG_RESETKEY: 918 if (argsize != sizeof(uint16_t)) 919 return AH_FALSE; 920 return ah->ah_resetKeyCacheEntry(ah, *(const uint16_t *)args); 921 #ifdef AH_SUPPORT_WRITE_EEPROM 922 case HAL_DIAG_EEWRITE: { 923 const HAL_DIAG_EEVAL *ee; 924 if (argsize != sizeof(HAL_DIAG_EEVAL)) 925 return AH_FALSE; 926 ee = (const HAL_DIAG_EEVAL *)args; 927 return ath_hal_eepromWrite(ah, ee->ee_off, ee->ee_data); 928 } 929 #endif /* AH_SUPPORT_WRITE_EEPROM */ 930 #endif /* AH_PRIVATE_DIAG */ 931 case HAL_DIAG_11NCOMPAT: 932 if (argsize == 0) { 933 *resultsize = sizeof(uint32_t); 934 *((uint32_t *)(*result)) = 935 AH_PRIVATE(ah)->ah_11nCompat; 936 } else if (argsize == sizeof(uint32_t)) { 937 AH_PRIVATE(ah)->ah_11nCompat = *(const uint32_t *)args; 938 } else 939 return AH_FALSE; 940 return AH_TRUE; 941 } 942 return AH_FALSE; 943 } 944 945 /* 946 * Set the properties of the tx queue with the parameters 947 * from qInfo. 948 */ 949 HAL_BOOL 950 ath_hal_setTxQProps(struct ath_hal *ah, 951 HAL_TX_QUEUE_INFO *qi, const HAL_TXQ_INFO *qInfo) 952 { 953 uint32_t cw; 954 955 if (qi->tqi_type == HAL_TX_QUEUE_INACTIVE) { 956 HALDEBUG(ah, HAL_DEBUG_TXQUEUE, 957 "%s: inactive queue\n", __func__); 958 return AH_FALSE; 959 } 960 /* XXX validate parameters */ 961 qi->tqi_ver = qInfo->tqi_ver; 962 qi->tqi_subtype = qInfo->tqi_subtype; 963 qi->tqi_qflags = qInfo->tqi_qflags; 964 qi->tqi_priority = qInfo->tqi_priority; 965 if (qInfo->tqi_aifs != HAL_TXQ_USEDEFAULT) 966 qi->tqi_aifs = AH_MIN(qInfo->tqi_aifs, 255); 967 else 968 qi->tqi_aifs = INIT_AIFS; 969 if (qInfo->tqi_cwmin != HAL_TXQ_USEDEFAULT) { 970 cw = AH_MIN(qInfo->tqi_cwmin, 1024); 971 /* make sure that the CWmin is of the form (2^n - 1) */ 972 qi->tqi_cwmin = 1; 973 while (qi->tqi_cwmin < cw) 974 qi->tqi_cwmin = (qi->tqi_cwmin << 1) | 1; 975 } else 976 qi->tqi_cwmin = qInfo->tqi_cwmin; 977 if (qInfo->tqi_cwmax != HAL_TXQ_USEDEFAULT) { 978 cw = AH_MIN(qInfo->tqi_cwmax, 1024); 979 /* make sure that the CWmax is of the form (2^n - 1) */ 980 qi->tqi_cwmax = 1; 981 while (qi->tqi_cwmax < cw) 982 qi->tqi_cwmax = (qi->tqi_cwmax << 1) | 1; 983 } else 984 qi->tqi_cwmax = INIT_CWMAX; 985 /* Set retry limit values */ 986 if (qInfo->tqi_shretry != 0) 987 qi->tqi_shretry = AH_MIN(qInfo->tqi_shretry, 15); 988 else 989 qi->tqi_shretry = INIT_SH_RETRY; 990 if (qInfo->tqi_lgretry != 0) 991 qi->tqi_lgretry = AH_MIN(qInfo->tqi_lgretry, 15); 992 else 993 qi->tqi_lgretry = INIT_LG_RETRY; 994 qi->tqi_cbrPeriod = qInfo->tqi_cbrPeriod; 995 qi->tqi_cbrOverflowLimit = qInfo->tqi_cbrOverflowLimit; 996 qi->tqi_burstTime = qInfo->tqi_burstTime; 997 qi->tqi_readyTime = qInfo->tqi_readyTime; 998 999 switch (qInfo->tqi_subtype) { 1000 case HAL_WME_UPSD: 1001 if (qi->tqi_type == HAL_TX_QUEUE_DATA) 1002 qi->tqi_intFlags = HAL_TXQ_USE_LOCKOUT_BKOFF_DIS; 1003 break; 1004 default: 1005 break; /* NB: silence compiler */ 1006 } 1007 return AH_TRUE; 1008 } 1009 1010 HAL_BOOL 1011 ath_hal_getTxQProps(struct ath_hal *ah, 1012 HAL_TXQ_INFO *qInfo, const HAL_TX_QUEUE_INFO *qi) 1013 { 1014 if (qi->tqi_type == HAL_TX_QUEUE_INACTIVE) { 1015 HALDEBUG(ah, HAL_DEBUG_TXQUEUE, 1016 "%s: inactive queue\n", __func__); 1017 return AH_FALSE; 1018 } 1019 1020 qInfo->tqi_qflags = qi->tqi_qflags; 1021 qInfo->tqi_ver = qi->tqi_ver; 1022 qInfo->tqi_subtype = qi->tqi_subtype; 1023 qInfo->tqi_qflags = qi->tqi_qflags; 1024 qInfo->tqi_priority = qi->tqi_priority; 1025 qInfo->tqi_aifs = qi->tqi_aifs; 1026 qInfo->tqi_cwmin = qi->tqi_cwmin; 1027 qInfo->tqi_cwmax = qi->tqi_cwmax; 1028 qInfo->tqi_shretry = qi->tqi_shretry; 1029 qInfo->tqi_lgretry = qi->tqi_lgretry; 1030 qInfo->tqi_cbrPeriod = qi->tqi_cbrPeriod; 1031 qInfo->tqi_cbrOverflowLimit = qi->tqi_cbrOverflowLimit; 1032 qInfo->tqi_burstTime = qi->tqi_burstTime; 1033 qInfo->tqi_readyTime = qi->tqi_readyTime; 1034 return AH_TRUE; 1035 } 1036 1037 /* 11a Turbo 11b 11g 108g */ 1038 static const int16_t NOISE_FLOOR[] = { -96, -93, -98, -96, -93 }; 1039 1040 /* 1041 * Read the current channel noise floor and return. 1042 * If nf cal hasn't finished, channel noise floor should be 0 1043 * and we return a nominal value based on band and frequency. 1044 * 1045 * NB: This is a private routine used by per-chip code to 1046 * implement the ah_getChanNoise method. 1047 */ 1048 int16_t 1049 ath_hal_getChanNoise(struct ath_hal *ah, const struct ieee80211_channel *chan) 1050 { 1051 HAL_CHANNEL_INTERNAL *ichan; 1052 1053 ichan = ath_hal_checkchannel(ah, chan); 1054 if (ichan == AH_NULL) { 1055 HALDEBUG(ah, HAL_DEBUG_NFCAL, 1056 "%s: invalid channel %u/0x%x; no mapping\n", 1057 __func__, chan->ic_freq, chan->ic_flags); 1058 return 0; 1059 } 1060 if (ichan->rawNoiseFloor == 0) { 1061 WIRELESS_MODE mode = ath_hal_chan2wmode(ah, chan); 1062 1063 HALASSERT(mode < WIRELESS_MODE_MAX); 1064 return NOISE_FLOOR[mode] + ath_hal_getNfAdjust(ah, ichan); 1065 } else 1066 return ichan->rawNoiseFloor + ichan->noiseFloorAdjust; 1067 } 1068 1069 /* 1070 * Fetch the current setup of ctl/ext noise floor values. 1071 * 1072 * If the CHANNEL_MIMO_NF_VALID flag isn't set, the array is simply 1073 * populated with values from NOISE_FLOOR[] + ath_hal_getNfAdjust(). 1074 * 1075 * The caller must supply ctl/ext NF arrays which are at least 1076 * AH_MAX_CHAINS entries long. 1077 */ 1078 int 1079 ath_hal_get_mimo_chan_noise(struct ath_hal *ah, 1080 const struct ieee80211_channel *chan, int16_t *nf_ctl, 1081 int16_t *nf_ext) 1082 { 1083 #ifdef AH_SUPPORT_AR5416 1084 HAL_CHANNEL_INTERNAL *ichan; 1085 int i; 1086 1087 ichan = ath_hal_checkchannel(ah, chan); 1088 if (ichan == AH_NULL) { 1089 HALDEBUG(ah, HAL_DEBUG_NFCAL, 1090 "%s: invalid channel %u/0x%x; no mapping\n", 1091 __func__, chan->ic_freq, chan->ic_flags); 1092 for (i = 0; i < AH_MAX_CHAINS; i++) { 1093 nf_ctl[i] = nf_ext[i] = 0; 1094 } 1095 return 0; 1096 } 1097 1098 /* Return 0 if there's no valid MIMO values (yet) */ 1099 if (! (ichan->privFlags & CHANNEL_MIMO_NF_VALID)) { 1100 for (i = 0; i < AH_MAX_CHAINS; i++) { 1101 nf_ctl[i] = nf_ext[i] = 0; 1102 } 1103 return 0; 1104 } 1105 if (ichan->rawNoiseFloor == 0) { 1106 WIRELESS_MODE mode = ath_hal_chan2wmode(ah, chan); 1107 HALASSERT(mode < WIRELESS_MODE_MAX); 1108 /* 1109 * See the comment below - this could cause issues for 1110 * stations which have a very low RSSI, below the 1111 * 'normalised' NF values in NOISE_FLOOR[]. 1112 */ 1113 for (i = 0; i < AH_MAX_CHAINS; i++) { 1114 nf_ctl[i] = nf_ext[i] = NOISE_FLOOR[mode] + 1115 ath_hal_getNfAdjust(ah, ichan); 1116 } 1117 return 1; 1118 } else { 1119 /* 1120 * The value returned here from a MIMO radio is presumed to be 1121 * "good enough" as a NF calculation. As RSSI values are calculated 1122 * against this, an adjusted NF may be higher than the RSSI value 1123 * returned from a vary weak station, resulting in an obscenely 1124 * high signal strength calculation being returned. 1125 * 1126 * This should be re-evaluated at a later date, along with any 1127 * signal strength calculations which are made. Quite likely the 1128 * RSSI values will need to be adjusted to ensure the calculations 1129 * don't "wrap" when RSSI is less than the "adjusted" NF value. 1130 * ("Adjust" here is via ichan->noiseFloorAdjust.) 1131 */ 1132 for (i = 0; i < AH_MAX_CHAINS; i++) { 1133 nf_ctl[i] = ichan->noiseFloorCtl[i] + ath_hal_getNfAdjust(ah, ichan); 1134 nf_ext[i] = ichan->noiseFloorExt[i] + ath_hal_getNfAdjust(ah, ichan); 1135 } 1136 return 1; 1137 } 1138 #else 1139 return 0; 1140 #endif /* AH_SUPPORT_AR5416 */ 1141 } 1142 1143 /* 1144 * Process all valid raw noise floors into the dBm noise floor values. 1145 * Though our device has no reference for a dBm noise floor, we perform 1146 * a relative minimization of NF's based on the lowest NF found across a 1147 * channel scan. 1148 */ 1149 void 1150 ath_hal_process_noisefloor(struct ath_hal *ah) 1151 { 1152 HAL_CHANNEL_INTERNAL *c; 1153 int16_t correct2, correct5; 1154 int16_t lowest2, lowest5; 1155 int i; 1156 1157 /* 1158 * Find the lowest 2GHz and 5GHz noise floor values after adjusting 1159 * for statistically recorded NF/channel deviation. 1160 */ 1161 correct2 = lowest2 = 0; 1162 correct5 = lowest5 = 0; 1163 for (i = 0; i < AH_PRIVATE(ah)->ah_nchan; i++) { 1164 WIRELESS_MODE mode; 1165 int16_t nf; 1166 1167 c = &AH_PRIVATE(ah)->ah_channels[i]; 1168 if (c->rawNoiseFloor >= 0) 1169 continue; 1170 /* XXX can't identify proper mode */ 1171 mode = IS_CHAN_5GHZ(c) ? WIRELESS_MODE_11a : WIRELESS_MODE_11g; 1172 nf = c->rawNoiseFloor + NOISE_FLOOR[mode] + 1173 ath_hal_getNfAdjust(ah, c); 1174 if (IS_CHAN_5GHZ(c)) { 1175 if (nf < lowest5) { 1176 lowest5 = nf; 1177 correct5 = NOISE_FLOOR[mode] - 1178 (c->rawNoiseFloor + ath_hal_getNfAdjust(ah, c)); 1179 } 1180 } else { 1181 if (nf < lowest2) { 1182 lowest2 = nf; 1183 correct2 = NOISE_FLOOR[mode] - 1184 (c->rawNoiseFloor + ath_hal_getNfAdjust(ah, c)); 1185 } 1186 } 1187 } 1188 1189 /* Correct the channels to reach the expected NF value */ 1190 for (i = 0; i < AH_PRIVATE(ah)->ah_nchan; i++) { 1191 c = &AH_PRIVATE(ah)->ah_channels[i]; 1192 if (c->rawNoiseFloor >= 0) 1193 continue; 1194 /* Apply correction factor */ 1195 c->noiseFloorAdjust = ath_hal_getNfAdjust(ah, c) + 1196 (IS_CHAN_5GHZ(c) ? correct5 : correct2); 1197 HALDEBUG(ah, HAL_DEBUG_NFCAL, "%u raw nf %d adjust %d\n", 1198 c->channel, c->rawNoiseFloor, c->noiseFloorAdjust); 1199 } 1200 } 1201 1202 /* 1203 * INI support routines. 1204 */ 1205 1206 int 1207 ath_hal_ini_write(struct ath_hal *ah, const HAL_INI_ARRAY *ia, 1208 int col, int regWr) 1209 { 1210 int r; 1211 1212 HALASSERT(col < ia->cols); 1213 for (r = 0; r < ia->rows; r++) { 1214 OS_REG_WRITE(ah, HAL_INI_VAL(ia, r, 0), 1215 HAL_INI_VAL(ia, r, col)); 1216 1217 /* Analog shift register delay seems needed for Merlin - PR kern/154220 */ 1218 if (HAL_INI_VAL(ia, r, 0) >= 0x7800 && HAL_INI_VAL(ia, r, 0) < 0x7900) 1219 OS_DELAY(100); 1220 1221 DMA_YIELD(regWr); 1222 } 1223 return regWr; 1224 } 1225 1226 void 1227 ath_hal_ini_bank_setup(uint32_t data[], const HAL_INI_ARRAY *ia, int col) 1228 { 1229 int r; 1230 1231 HALASSERT(col < ia->cols); 1232 for (r = 0; r < ia->rows; r++) 1233 data[r] = HAL_INI_VAL(ia, r, col); 1234 } 1235 1236 int 1237 ath_hal_ini_bank_write(struct ath_hal *ah, const HAL_INI_ARRAY *ia, 1238 const uint32_t data[], int regWr) 1239 { 1240 int r; 1241 1242 for (r = 0; r < ia->rows; r++) { 1243 OS_REG_WRITE(ah, HAL_INI_VAL(ia, r, 0), data[r]); 1244 DMA_YIELD(regWr); 1245 } 1246 return regWr; 1247 } 1248 1249 /* 1250 * These are EEPROM board related routines which should likely live in 1251 * a helper library of some sort. 1252 */ 1253 1254 /************************************************************** 1255 * ath_ee_getLowerUppderIndex 1256 * 1257 * Return indices surrounding the value in sorted integer lists. 1258 * Requirement: the input list must be monotonically increasing 1259 * and populated up to the list size 1260 * Returns: match is set if an index in the array matches exactly 1261 * or a the target is before or after the range of the array. 1262 */ 1263 HAL_BOOL 1264 ath_ee_getLowerUpperIndex(uint8_t target, uint8_t *pList, uint16_t listSize, 1265 uint16_t *indexL, uint16_t *indexR) 1266 { 1267 uint16_t i; 1268 1269 /* 1270 * Check first and last elements for beyond ordered array cases. 1271 */ 1272 if (target <= pList[0]) { 1273 *indexL = *indexR = 0; 1274 return AH_TRUE; 1275 } 1276 if (target >= pList[listSize-1]) { 1277 *indexL = *indexR = (uint16_t)(listSize - 1); 1278 return AH_TRUE; 1279 } 1280 1281 /* look for value being near or between 2 values in list */ 1282 for (i = 0; i < listSize - 1; i++) { 1283 /* 1284 * If value is close to the current value of the list 1285 * then target is not between values, it is one of the values 1286 */ 1287 if (pList[i] == target) { 1288 *indexL = *indexR = i; 1289 return AH_TRUE; 1290 } 1291 /* 1292 * Look for value being between current value and next value 1293 * if so return these 2 values 1294 */ 1295 if (target < pList[i + 1]) { 1296 *indexL = i; 1297 *indexR = (uint16_t)(i + 1); 1298 return AH_FALSE; 1299 } 1300 } 1301 HALASSERT(0); 1302 *indexL = *indexR = 0; 1303 return AH_FALSE; 1304 } 1305 1306 /************************************************************** 1307 * ath_ee_FillVpdTable 1308 * 1309 * Fill the Vpdlist for indices Pmax-Pmin 1310 * Note: pwrMin, pwrMax and Vpdlist are all in dBm * 4 1311 */ 1312 HAL_BOOL 1313 ath_ee_FillVpdTable(uint8_t pwrMin, uint8_t pwrMax, uint8_t *pPwrList, 1314 uint8_t *pVpdList, uint16_t numIntercepts, uint8_t *pRetVpdList) 1315 { 1316 uint16_t i, k; 1317 uint8_t currPwr = pwrMin; 1318 uint16_t idxL, idxR; 1319 1320 HALASSERT(pwrMax > pwrMin); 1321 for (i = 0; i <= (pwrMax - pwrMin) / 2; i++) { 1322 ath_ee_getLowerUpperIndex(currPwr, pPwrList, numIntercepts, 1323 &(idxL), &(idxR)); 1324 if (idxR < 1) 1325 idxR = 1; /* extrapolate below */ 1326 if (idxL == numIntercepts - 1) 1327 idxL = (uint16_t)(numIntercepts - 2); /* extrapolate above */ 1328 if (pPwrList[idxL] == pPwrList[idxR]) 1329 k = pVpdList[idxL]; 1330 else 1331 k = (uint16_t)( ((currPwr - pPwrList[idxL]) * pVpdList[idxR] + (pPwrList[idxR] - currPwr) * pVpdList[idxL]) / 1332 (pPwrList[idxR] - pPwrList[idxL]) ); 1333 HALASSERT(k < 256); 1334 pRetVpdList[i] = (uint8_t)k; 1335 currPwr += 2; /* half dB steps */ 1336 } 1337 1338 return AH_TRUE; 1339 } 1340 1341 /************************************************************************** 1342 * ath_ee_interpolate 1343 * 1344 * Returns signed interpolated or the scaled up interpolated value 1345 */ 1346 int16_t 1347 ath_ee_interpolate(uint16_t target, uint16_t srcLeft, uint16_t srcRight, 1348 int16_t targetLeft, int16_t targetRight) 1349 { 1350 int16_t rv; 1351 1352 if (srcRight == srcLeft) { 1353 rv = targetLeft; 1354 } else { 1355 rv = (int16_t)( ((target - srcLeft) * targetRight + 1356 (srcRight - target) * targetLeft) / (srcRight - srcLeft) ); 1357 } 1358 return rv; 1359 } 1360 1361 /* 1362 * Adjust the TSF. 1363 */ 1364 void 1365 ath_hal_adjusttsf(struct ath_hal *ah, int32_t tsfdelta) 1366 { 1367 /* XXX handle wrap/overflow */ 1368 OS_REG_WRITE(ah, AR_TSF_L32, OS_REG_READ(ah, AR_TSF_L32) + tsfdelta); 1369 } 1370 1371 /* 1372 * Enable or disable CCA. 1373 */ 1374 void 1375 ath_hal_setcca(struct ath_hal *ah, int ena) 1376 { 1377 /* 1378 * NB: fill me in; this is not provided by default because disabling 1379 * CCA in most locales violates regulatory. 1380 */ 1381 } 1382 1383 /* 1384 * Get CCA setting. 1385 */ 1386 int 1387 ath_hal_getcca(struct ath_hal *ah) 1388 { 1389 u_int32_t diag; 1390 if (ath_hal_getcapability(ah, HAL_CAP_DIAG, 0, &diag) != HAL_OK) 1391 return 1; 1392 return ((diag & 0x500000) == 0); 1393 } 1394 1395 /* 1396 * This routine is only needed when supporting EEPROM-in-RAM setups 1397 * (eg embedded SoCs and on-board PCI/PCIe devices.) 1398 */ 1399 /* NB: This is in 16 bit words; not bytes */ 1400 /* XXX This doesn't belong here! */ 1401 #define ATH_DATA_EEPROM_SIZE 2048 1402 1403 HAL_BOOL 1404 ath_hal_EepromDataRead(struct ath_hal *ah, u_int off, uint16_t *data) 1405 { 1406 if (ah->ah_eepromdata == AH_NULL) { 1407 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: no eeprom data!\n", __func__); 1408 return AH_FALSE; 1409 } 1410 if (off > ATH_DATA_EEPROM_SIZE) { 1411 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: offset %x > %x\n", 1412 __func__, off, ATH_DATA_EEPROM_SIZE); 1413 return AH_FALSE; 1414 } 1415 (*data) = ah->ah_eepromdata[off]; 1416 return AH_TRUE; 1417 } 1418 1419 /* 1420 * Do a 2GHz specific MHz->IEEE based on the hardware 1421 * frequency. 1422 * 1423 * This is the unmapped frequency which is programmed into the hardware. 1424 */ 1425 int 1426 ath_hal_mhz2ieee_2ghz(struct ath_hal *ah, HAL_CHANNEL_INTERNAL *ichan) 1427 { 1428 1429 if (ichan->channel == 2484) 1430 return 14; 1431 if (ichan->channel < 2484) 1432 return ((int) ichan->channel - 2407) / 5; 1433 else 1434 return 15 + ((ichan->channel - 2512) / 20); 1435 } 1436