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