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