1 1.1 alc /* 2 1.1 alc * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting 3 1.1 alc * Copyright (c) 2002-2008 Atheros Communications, Inc. 4 1.1 alc * 5 1.1 alc * Permission to use, copy, modify, and/or distribute this software for any 6 1.1 alc * purpose with or without fee is hereby granted, provided that the above 7 1.1 alc * copyright notice and this permission notice appear in all copies. 8 1.1 alc * 9 1.1 alc * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 1.1 alc * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 1.1 alc * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 1.1 alc * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 1.1 alc * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 1.1 alc * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 1.1 alc * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 1.1 alc * 17 1.3 cegger * $Id: ah.c,v 1.3 2011/03/07 11:25:42 cegger Exp $ 18 1.1 alc */ 19 1.1 alc #include "opt_ah.h" 20 1.1 alc 21 1.1 alc #include "ah.h" 22 1.1 alc #include "ah_internal.h" 23 1.1 alc #include "ah_devid.h" 24 1.1 alc 25 1.1 alc /* linker set of registered chips */ 26 1.1 alc OS_SET_DECLARE(ah_chips, struct ath_hal_chip); 27 1.1 alc 28 1.1 alc /* 29 1.1 alc * Check the set of registered chips to see if any recognize 30 1.1 alc * the device as one they can support. 31 1.1 alc */ 32 1.1 alc const char* 33 1.1 alc ath_hal_probe(uint16_t vendorid, uint16_t devid) 34 1.1 alc { 35 1.2 alc struct ath_hal_chip * const *pchip; 36 1.1 alc 37 1.1 alc OS_SET_FOREACH(pchip, ah_chips) { 38 1.1 alc const char *name = (*pchip)->probe(vendorid, devid); 39 1.1 alc if (name != AH_NULL) 40 1.1 alc return name; 41 1.1 alc } 42 1.1 alc return AH_NULL; 43 1.1 alc } 44 1.1 alc 45 1.1 alc /* 46 1.1 alc * Attach detects device chip revisions, initializes the hwLayer 47 1.1 alc * function list, reads EEPROM information, 48 1.1 alc * selects reset vectors, and performs a short self test. 49 1.1 alc * Any failures will return an error that should cause a hardware 50 1.1 alc * disable. 51 1.1 alc */ 52 1.1 alc struct ath_hal* 53 1.1 alc ath_hal_attach(uint16_t devid, HAL_SOFTC sc, 54 1.1 alc HAL_BUS_TAG st, HAL_BUS_HANDLE sh, HAL_STATUS *error) 55 1.1 alc { 56 1.2 alc struct ath_hal_chip * const *pchip; 57 1.1 alc 58 1.1 alc OS_SET_FOREACH(pchip, ah_chips) { 59 1.1 alc struct ath_hal_chip *chip = *pchip; 60 1.1 alc struct ath_hal *ah; 61 1.1 alc 62 1.1 alc /* XXX don't have vendorid, assume atheros one works */ 63 1.1 alc if (chip->probe(ATHEROS_VENDOR_ID, devid) == AH_NULL) 64 1.1 alc continue; 65 1.1 alc ah = chip->attach(devid, sc, st, sh, error); 66 1.1 alc if (ah != AH_NULL) { 67 1.1 alc /* copy back private state to public area */ 68 1.1 alc ah->ah_devid = AH_PRIVATE(ah)->ah_devid; 69 1.1 alc ah->ah_subvendorid = AH_PRIVATE(ah)->ah_subvendorid; 70 1.1 alc ah->ah_macVersion = AH_PRIVATE(ah)->ah_macVersion; 71 1.1 alc ah->ah_macRev = AH_PRIVATE(ah)->ah_macRev; 72 1.1 alc ah->ah_phyRev = AH_PRIVATE(ah)->ah_phyRev; 73 1.1 alc ah->ah_analog5GhzRev = AH_PRIVATE(ah)->ah_analog5GhzRev; 74 1.1 alc ah->ah_analog2GhzRev = AH_PRIVATE(ah)->ah_analog2GhzRev; 75 1.1 alc return ah; 76 1.1 alc } 77 1.1 alc } 78 1.1 alc return AH_NULL; 79 1.1 alc } 80 1.1 alc 81 1.1 alc /* linker set of registered RF backends */ 82 1.1 alc OS_SET_DECLARE(ah_rfs, struct ath_hal_rf); 83 1.1 alc 84 1.1 alc /* 85 1.1 alc * Check the set of registered RF backends to see if 86 1.1 alc * any recognize the device as one they can support. 87 1.1 alc */ 88 1.1 alc struct ath_hal_rf * 89 1.1 alc ath_hal_rfprobe(struct ath_hal *ah, HAL_STATUS *ecode) 90 1.1 alc { 91 1.2 alc #ifdef AH_HAS_RF 92 1.2 alc struct ath_hal_rf * const *prf; 93 1.1 alc 94 1.1 alc OS_SET_FOREACH(prf, ah_rfs) { 95 1.1 alc struct ath_hal_rf *rf = *prf; 96 1.1 alc if (rf->probe(ah)) 97 1.1 alc return rf; 98 1.1 alc } 99 1.1 alc *ecode = HAL_ENOTSUPP; 100 1.2 alc #endif 101 1.1 alc return AH_NULL; 102 1.1 alc } 103 1.1 alc 104 1.1 alc /* 105 1.1 alc * Poll the register looking for a specific value. 106 1.1 alc */ 107 1.1 alc HAL_BOOL 108 1.1 alc ath_hal_wait(struct ath_hal *ah, u_int reg, uint32_t mask, uint32_t val) 109 1.1 alc { 110 1.1 alc #define AH_TIMEOUT 1000 111 1.1 alc int i; 112 1.1 alc 113 1.1 alc for (i = 0; i < AH_TIMEOUT; i++) { 114 1.1 alc if ((OS_REG_READ(ah, reg) & mask) == val) 115 1.1 alc return AH_TRUE; 116 1.1 alc OS_DELAY(10); 117 1.1 alc } 118 1.1 alc HALDEBUG(ah, HAL_DEBUG_REGIO | HAL_DEBUG_PHYIO, 119 1.1 alc "%s: timeout on reg 0x%x: 0x%08x & 0x%08x != 0x%08x\n", 120 1.1 alc __func__, reg, OS_REG_READ(ah, reg), mask, val); 121 1.1 alc return AH_FALSE; 122 1.1 alc #undef AH_TIMEOUT 123 1.1 alc } 124 1.1 alc 125 1.1 alc /* 126 1.1 alc * Reverse the bits starting at the low bit for a value of 127 1.1 alc * bit_count in size 128 1.1 alc */ 129 1.1 alc uint32_t 130 1.1 alc ath_hal_reverseBits(uint32_t val, uint32_t n) 131 1.1 alc { 132 1.1 alc uint32_t retval; 133 1.1 alc int i; 134 1.1 alc 135 1.1 alc for (i = 0, retval = 0; i < n; i++) { 136 1.1 alc retval = (retval << 1) | (val & 1); 137 1.1 alc val >>= 1; 138 1.1 alc } 139 1.1 alc return retval; 140 1.1 alc } 141 1.1 alc 142 1.1 alc /* 143 1.1 alc * Compute the time to transmit a frame of length frameLen bytes 144 1.1 alc * using the specified rate, phy, and short preamble setting. 145 1.1 alc */ 146 1.1 alc uint16_t 147 1.1 alc ath_hal_computetxtime(struct ath_hal *ah, 148 1.1 alc const HAL_RATE_TABLE *rates, uint32_t frameLen, uint16_t rateix, 149 1.1 alc HAL_BOOL shortPreamble) 150 1.1 alc { 151 1.1 alc uint32_t bitsPerSymbol, numBits, numSymbols, phyTime, txTime; 152 1.1 alc uint32_t kbps; 153 1.1 alc 154 1.1 alc kbps = rates->info[rateix].rateKbps; 155 1.1 alc /* 156 1.1 alc * index can be invalid duting dynamic Turbo transitions. 157 1.1 alc */ 158 1.1 alc if(kbps == 0) return 0; 159 1.1 alc switch (rates->info[rateix].phy) { 160 1.1 alc 161 1.1 alc case IEEE80211_T_CCK: 162 1.1 alc #define CCK_SIFS_TIME 10 163 1.1 alc #define CCK_PREAMBLE_BITS 144 164 1.1 alc #define CCK_PLCP_BITS 48 165 1.1 alc phyTime = CCK_PREAMBLE_BITS + CCK_PLCP_BITS; 166 1.1 alc if (shortPreamble && rates->info[rateix].shortPreamble) 167 1.1 alc phyTime >>= 1; 168 1.1 alc numBits = frameLen << 3; 169 1.1 alc txTime = CCK_SIFS_TIME + phyTime 170 1.1 alc + ((numBits * 1000)/kbps); 171 1.1 alc break; 172 1.1 alc #undef CCK_SIFS_TIME 173 1.1 alc #undef CCK_PREAMBLE_BITS 174 1.1 alc #undef CCK_PLCP_BITS 175 1.1 alc 176 1.1 alc case IEEE80211_T_OFDM: 177 1.1 alc #define OFDM_SIFS_TIME 16 178 1.1 alc #define OFDM_PREAMBLE_TIME 20 179 1.1 alc #define OFDM_PLCP_BITS 22 180 1.1 alc #define OFDM_SYMBOL_TIME 4 181 1.1 alc 182 1.1 alc #define OFDM_SIFS_TIME_HALF 32 183 1.1 alc #define OFDM_PREAMBLE_TIME_HALF 40 184 1.1 alc #define OFDM_PLCP_BITS_HALF 22 185 1.1 alc #define OFDM_SYMBOL_TIME_HALF 8 186 1.1 alc 187 1.1 alc #define OFDM_SIFS_TIME_QUARTER 64 188 1.1 alc #define OFDM_PREAMBLE_TIME_QUARTER 80 189 1.1 alc #define OFDM_PLCP_BITS_QUARTER 22 190 1.1 alc #define OFDM_SYMBOL_TIME_QUARTER 16 191 1.1 alc 192 1.1 alc if (AH_PRIVATE(ah)->ah_curchan && 193 1.1 alc IS_CHAN_QUARTER_RATE(AH_PRIVATE(ah)->ah_curchan)) { 194 1.1 alc bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME_QUARTER) / 1000; 195 1.1 alc HALASSERT(bitsPerSymbol != 0); 196 1.1 alc 197 1.1 alc numBits = OFDM_PLCP_BITS + (frameLen << 3); 198 1.1 alc numSymbols = howmany(numBits, bitsPerSymbol); 199 1.1 alc txTime = OFDM_SIFS_TIME_QUARTER 200 1.1 alc + OFDM_PREAMBLE_TIME_QUARTER 201 1.1 alc + (numSymbols * OFDM_SYMBOL_TIME_QUARTER); 202 1.1 alc } else if (AH_PRIVATE(ah)->ah_curchan && 203 1.1 alc IS_CHAN_HALF_RATE(AH_PRIVATE(ah)->ah_curchan)) { 204 1.1 alc bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME_HALF) / 1000; 205 1.1 alc HALASSERT(bitsPerSymbol != 0); 206 1.1 alc 207 1.1 alc numBits = OFDM_PLCP_BITS + (frameLen << 3); 208 1.1 alc numSymbols = howmany(numBits, bitsPerSymbol); 209 1.1 alc txTime = OFDM_SIFS_TIME_HALF + 210 1.1 alc OFDM_PREAMBLE_TIME_HALF 211 1.1 alc + (numSymbols * OFDM_SYMBOL_TIME_HALF); 212 1.1 alc } else { /* full rate channel */ 213 1.1 alc bitsPerSymbol = (kbps * OFDM_SYMBOL_TIME) / 1000; 214 1.1 alc HALASSERT(bitsPerSymbol != 0); 215 1.1 alc 216 1.1 alc numBits = OFDM_PLCP_BITS + (frameLen << 3); 217 1.1 alc numSymbols = howmany(numBits, bitsPerSymbol); 218 1.1 alc txTime = OFDM_SIFS_TIME + OFDM_PREAMBLE_TIME 219 1.1 alc + (numSymbols * OFDM_SYMBOL_TIME); 220 1.1 alc } 221 1.1 alc break; 222 1.1 alc 223 1.1 alc #undef OFDM_SIFS_TIME 224 1.1 alc #undef OFDM_PREAMBLE_TIME 225 1.1 alc #undef OFDM_PLCP_BITS 226 1.1 alc #undef OFDM_SYMBOL_TIME 227 1.1 alc 228 1.1 alc case IEEE80211_T_TURBO: 229 1.1 alc #define TURBO_SIFS_TIME 8 230 1.1 alc #define TURBO_PREAMBLE_TIME 14 231 1.1 alc #define TURBO_PLCP_BITS 22 232 1.1 alc #define TURBO_SYMBOL_TIME 4 233 1.1 alc /* we still save OFDM rates in kbps - so double them */ 234 1.1 alc bitsPerSymbol = ((kbps << 1) * TURBO_SYMBOL_TIME) / 1000; 235 1.1 alc HALASSERT(bitsPerSymbol != 0); 236 1.1 alc 237 1.1 alc numBits = TURBO_PLCP_BITS + (frameLen << 3); 238 1.1 alc numSymbols = howmany(numBits, bitsPerSymbol); 239 1.1 alc txTime = TURBO_SIFS_TIME + TURBO_PREAMBLE_TIME 240 1.1 alc + (numSymbols * TURBO_SYMBOL_TIME); 241 1.1 alc break; 242 1.1 alc #undef TURBO_SIFS_TIME 243 1.1 alc #undef TURBO_PREAMBLE_TIME 244 1.1 alc #undef TURBO_PLCP_BITS 245 1.1 alc #undef TURBO_SYMBOL_TIME 246 1.1 alc 247 1.1 alc default: 248 1.1 alc HALDEBUG(ah, HAL_DEBUG_PHYIO, 249 1.1 alc "%s: unknown phy %u (rate ix %u)\n", 250 1.1 alc __func__, rates->info[rateix].phy, rateix); 251 1.1 alc txTime = 0; 252 1.1 alc break; 253 1.1 alc } 254 1.1 alc return txTime; 255 1.1 alc } 256 1.1 alc 257 1.1 alc static __inline int 258 1.1 alc mapgsm(u_int freq, u_int flags) 259 1.1 alc { 260 1.1 alc freq *= 10; 261 1.1 alc if (flags & CHANNEL_QUARTER) 262 1.1 alc freq += 5; 263 1.1 alc else if (flags & CHANNEL_HALF) 264 1.1 alc freq += 10; 265 1.1 alc else 266 1.1 alc freq += 20; 267 1.1 alc return (freq - 24220) / 5; 268 1.1 alc } 269 1.1 alc 270 1.1 alc static __inline int 271 1.1 alc mappsb(u_int freq, u_int flags) 272 1.1 alc { 273 1.1 alc return ((freq * 10) + (((freq % 5) == 2) ? 5 : 0) - 49400) / 5; 274 1.1 alc } 275 1.1 alc 276 1.1 alc /* 277 1.1 alc * Convert GHz frequency to IEEE channel number. 278 1.1 alc */ 279 1.1 alc int 280 1.1 alc ath_hal_mhz2ieee(struct ath_hal *ah, u_int freq, u_int flags) 281 1.1 alc { 282 1.1 alc if (flags & CHANNEL_2GHZ) { /* 2GHz band */ 283 1.1 alc if (freq == 2484) 284 1.1 alc return 14; 285 1.1 alc if (freq < 2484) { 286 1.1 alc if (ath_hal_isgsmsku(ah)) 287 1.1 alc return mapgsm(freq, flags); 288 1.1 alc return ((int)freq - 2407) / 5; 289 1.1 alc } else 290 1.1 alc return 15 + ((freq - 2512) / 20); 291 1.1 alc } else if (flags & CHANNEL_5GHZ) {/* 5Ghz band */ 292 1.1 alc if (ath_hal_ispublicsafetysku(ah) && 293 1.1 alc IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) { 294 1.1 alc return mappsb(freq, flags); 295 1.1 alc } else if ((flags & CHANNEL_A) && (freq <= 5000)) { 296 1.1 alc return (freq - 4000) / 5; 297 1.1 alc } else { 298 1.1 alc return (freq - 5000) / 5; 299 1.1 alc } 300 1.1 alc } else { /* either, guess */ 301 1.1 alc if (freq == 2484) 302 1.1 alc return 14; 303 1.1 alc if (freq < 2484) { 304 1.1 alc if (ath_hal_isgsmsku(ah)) 305 1.1 alc return mapgsm(freq, flags); 306 1.1 alc return ((int)freq - 2407) / 5; 307 1.1 alc } 308 1.1 alc if (freq < 5000) { 309 1.1 alc if (ath_hal_ispublicsafetysku(ah) && 310 1.1 alc IS_CHAN_IN_PUBLIC_SAFETY_BAND(freq)) { 311 1.1 alc return mappsb(freq, flags); 312 1.1 alc } else if (freq > 4900) { 313 1.1 alc return (freq - 4000) / 5; 314 1.1 alc } else { 315 1.1 alc return 15 + ((freq - 2512) / 20); 316 1.1 alc } 317 1.1 alc } 318 1.1 alc return (freq - 5000) / 5; 319 1.1 alc } 320 1.1 alc } 321 1.1 alc 322 1.1 alc typedef enum { 323 1.1 alc WIRELESS_MODE_11a = 0, 324 1.1 alc WIRELESS_MODE_TURBO = 1, 325 1.1 alc WIRELESS_MODE_11b = 2, 326 1.1 alc WIRELESS_MODE_11g = 3, 327 1.1 alc WIRELESS_MODE_108g = 4, 328 1.1 alc 329 1.1 alc WIRELESS_MODE_MAX 330 1.1 alc } WIRELESS_MODE; 331 1.1 alc 332 1.1 alc static WIRELESS_MODE 333 1.1 alc ath_hal_chan2wmode(struct ath_hal *ah, const HAL_CHANNEL *chan) 334 1.1 alc { 335 1.1 alc if (IS_CHAN_CCK(chan)) 336 1.1 alc return WIRELESS_MODE_11b; 337 1.1 alc if (IS_CHAN_G(chan)) 338 1.1 alc return WIRELESS_MODE_11g; 339 1.1 alc if (IS_CHAN_108G(chan)) 340 1.1 alc return WIRELESS_MODE_108g; 341 1.1 alc if (IS_CHAN_TURBO(chan)) 342 1.1 alc return WIRELESS_MODE_TURBO; 343 1.1 alc return WIRELESS_MODE_11a; 344 1.1 alc } 345 1.1 alc 346 1.1 alc /* 347 1.1 alc * Convert between microseconds and core system clocks. 348 1.1 alc */ 349 1.1 alc /* 11a Turbo 11b 11g 108g */ 350 1.1 alc static const uint8_t CLOCK_RATE[] = { 40, 80, 22, 44, 88 }; 351 1.1 alc 352 1.1 alc u_int 353 1.1 alc ath_hal_mac_clks(struct ath_hal *ah, u_int usecs) 354 1.1 alc { 355 1.1 alc const HAL_CHANNEL *c = (const HAL_CHANNEL *) AH_PRIVATE(ah)->ah_curchan; 356 1.1 alc u_int clks; 357 1.1 alc 358 1.1 alc /* NB: ah_curchan may be null when called attach time */ 359 1.1 alc if (c != AH_NULL) { 360 1.1 alc clks = usecs * CLOCK_RATE[ath_hal_chan2wmode(ah, c)]; 361 1.1 alc if (IS_CHAN_HT40(c)) 362 1.1 alc clks <<= 1; 363 1.1 alc else if (IS_CHAN_HALF_RATE(c)) 364 1.1 alc clks >>= 1; 365 1.1 alc else if (IS_CHAN_QUARTER_RATE(c)) 366 1.1 alc clks >>= 2; 367 1.1 alc } else 368 1.1 alc clks = usecs * CLOCK_RATE[WIRELESS_MODE_11b]; 369 1.1 alc return clks; 370 1.1 alc } 371 1.1 alc 372 1.1 alc u_int 373 1.1 alc ath_hal_mac_usec(struct ath_hal *ah, u_int clks) 374 1.1 alc { 375 1.1 alc const HAL_CHANNEL *c = (const HAL_CHANNEL *) AH_PRIVATE(ah)->ah_curchan; 376 1.1 alc u_int usec; 377 1.1 alc 378 1.1 alc /* NB: ah_curchan may be null when called attach time */ 379 1.1 alc if (c != AH_NULL) { 380 1.1 alc usec = clks / CLOCK_RATE[ath_hal_chan2wmode(ah, c)]; 381 1.1 alc if (IS_CHAN_HT40(c)) 382 1.1 alc usec >>= 1; 383 1.1 alc else if (IS_CHAN_HALF_RATE(c)) 384 1.1 alc usec <<= 1; 385 1.1 alc else if (IS_CHAN_QUARTER_RATE(c)) 386 1.1 alc usec <<= 2; 387 1.1 alc } else 388 1.1 alc usec = clks / CLOCK_RATE[WIRELESS_MODE_11b]; 389 1.1 alc return usec; 390 1.1 alc } 391 1.1 alc 392 1.1 alc /* 393 1.1 alc * Setup a h/w rate table's reverse lookup table and 394 1.1 alc * fill in ack durations. This routine is called for 395 1.1 alc * each rate table returned through the ah_getRateTable 396 1.1 alc * method. The reverse lookup tables are assumed to be 397 1.1 alc * initialized to zero (or at least the first entry). 398 1.1 alc * We use this as a key that indicates whether or not 399 1.1 alc * we've previously setup the reverse lookup table. 400 1.1 alc * 401 1.1 alc * XXX not reentrant, but shouldn't matter 402 1.1 alc */ 403 1.1 alc void 404 1.1 alc ath_hal_setupratetable(struct ath_hal *ah, HAL_RATE_TABLE *rt) 405 1.1 alc { 406 1.1 alc #define N(a) (sizeof(a)/sizeof(a[0])) 407 1.1 alc int i; 408 1.1 alc 409 1.1 alc if (rt->rateCodeToIndex[0] != 0) /* already setup */ 410 1.1 alc return; 411 1.1 alc for (i = 0; i < N(rt->rateCodeToIndex); i++) 412 1.1 alc rt->rateCodeToIndex[i] = (uint8_t) -1; 413 1.1 alc for (i = 0; i < rt->rateCount; i++) { 414 1.1 alc uint8_t code = rt->info[i].rateCode; 415 1.1 alc uint8_t cix = rt->info[i].controlRate; 416 1.1 alc 417 1.1 alc HALASSERT(code < N(rt->rateCodeToIndex)); 418 1.1 alc rt->rateCodeToIndex[code] = i; 419 1.1 alc HALASSERT((code | rt->info[i].shortPreamble) < 420 1.1 alc N(rt->rateCodeToIndex)); 421 1.1 alc rt->rateCodeToIndex[code | rt->info[i].shortPreamble] = i; 422 1.1 alc /* 423 1.1 alc * XXX for 11g the control rate to use for 5.5 and 11 Mb/s 424 1.1 alc * depends on whether they are marked as basic rates; 425 1.1 alc * the static tables are setup with an 11b-compatible 426 1.1 alc * 2Mb/s rate which will work but is suboptimal 427 1.1 alc */ 428 1.1 alc rt->info[i].lpAckDuration = ath_hal_computetxtime(ah, rt, 429 1.1 alc WLAN_CTRL_FRAME_SIZE, cix, AH_FALSE); 430 1.1 alc rt->info[i].spAckDuration = ath_hal_computetxtime(ah, rt, 431 1.1 alc WLAN_CTRL_FRAME_SIZE, cix, AH_TRUE); 432 1.1 alc } 433 1.1 alc #undef N 434 1.1 alc } 435 1.1 alc 436 1.1 alc HAL_STATUS 437 1.1 alc ath_hal_getcapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type, 438 1.1 alc uint32_t capability, uint32_t *result) 439 1.1 alc { 440 1.1 alc const HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps; 441 1.1 alc 442 1.1 alc switch (type) { 443 1.1 alc case HAL_CAP_REG_DMN: /* regulatory domain */ 444 1.1 alc *result = AH_PRIVATE(ah)->ah_currentRD; 445 1.1 alc return HAL_OK; 446 1.1 alc case HAL_CAP_CIPHER: /* cipher handled in hardware */ 447 1.1 alc case HAL_CAP_TKIP_MIC: /* handle TKIP MIC in hardware */ 448 1.1 alc return HAL_ENOTSUPP; 449 1.1 alc case HAL_CAP_TKIP_SPLIT: /* hardware TKIP uses split keys */ 450 1.1 alc return HAL_ENOTSUPP; 451 1.1 alc case HAL_CAP_PHYCOUNTERS: /* hardware PHY error counters */ 452 1.1 alc return pCap->halHwPhyCounterSupport ? HAL_OK : HAL_ENXIO; 453 1.1 alc case HAL_CAP_WME_TKIPMIC: /* hardware can do TKIP MIC when WMM is turned on */ 454 1.1 alc return HAL_ENOTSUPP; 455 1.1 alc case HAL_CAP_DIVERSITY: /* hardware supports fast diversity */ 456 1.1 alc return HAL_ENOTSUPP; 457 1.1 alc case HAL_CAP_KEYCACHE_SIZE: /* hardware key cache size */ 458 1.1 alc *result = pCap->halKeyCacheSize; 459 1.1 alc return HAL_OK; 460 1.1 alc case HAL_CAP_NUM_TXQUEUES: /* number of hardware tx queues */ 461 1.1 alc *result = pCap->halTotalQueues; 462 1.1 alc return HAL_OK; 463 1.1 alc case HAL_CAP_VEOL: /* hardware supports virtual EOL */ 464 1.1 alc return pCap->halVEOLSupport ? HAL_OK : HAL_ENOTSUPP; 465 1.1 alc case HAL_CAP_PSPOLL: /* hardware PS-Poll support works */ 466 1.1 alc return pCap->halPSPollBroken ? HAL_ENOTSUPP : HAL_OK; 467 1.1 alc case HAL_CAP_COMPRESSION: 468 1.1 alc return pCap->halCompressSupport ? HAL_OK : HAL_ENOTSUPP; 469 1.1 alc case HAL_CAP_BURST: 470 1.1 alc return pCap->halBurstSupport ? HAL_OK : HAL_ENOTSUPP; 471 1.1 alc case HAL_CAP_FASTFRAME: 472 1.1 alc return pCap->halFastFramesSupport ? HAL_OK : HAL_ENOTSUPP; 473 1.1 alc case HAL_CAP_DIAG: /* hardware diagnostic support */ 474 1.1 alc *result = AH_PRIVATE(ah)->ah_diagreg; 475 1.1 alc return HAL_OK; 476 1.1 alc case HAL_CAP_TXPOW: /* global tx power limit */ 477 1.1 alc switch (capability) { 478 1.1 alc case 0: /* facility is supported */ 479 1.1 alc return HAL_OK; 480 1.1 alc case 1: /* current limit */ 481 1.1 alc *result = AH_PRIVATE(ah)->ah_powerLimit; 482 1.1 alc return HAL_OK; 483 1.1 alc case 2: /* current max tx power */ 484 1.1 alc *result = AH_PRIVATE(ah)->ah_maxPowerLevel; 485 1.1 alc return HAL_OK; 486 1.1 alc case 3: /* scale factor */ 487 1.1 alc *result = AH_PRIVATE(ah)->ah_tpScale; 488 1.1 alc return HAL_OK; 489 1.1 alc } 490 1.1 alc return HAL_ENOTSUPP; 491 1.1 alc case HAL_CAP_BSSIDMASK: /* hardware supports bssid mask */ 492 1.1 alc return pCap->halBssIdMaskSupport ? HAL_OK : HAL_ENOTSUPP; 493 1.1 alc case HAL_CAP_MCAST_KEYSRCH: /* multicast frame keycache search */ 494 1.1 alc return pCap->halMcastKeySrchSupport ? HAL_OK : HAL_ENOTSUPP; 495 1.1 alc case HAL_CAP_TSF_ADJUST: /* hardware has beacon tsf adjust */ 496 1.1 alc return HAL_ENOTSUPP; 497 1.1 alc case HAL_CAP_RFSILENT: /* rfsilent support */ 498 1.1 alc switch (capability) { 499 1.1 alc case 0: /* facility is supported */ 500 1.1 alc return pCap->halRfSilentSupport ? HAL_OK : HAL_ENOTSUPP; 501 1.1 alc case 1: /* current setting */ 502 1.1 alc return AH_PRIVATE(ah)->ah_rfkillEnabled ? 503 1.1 alc HAL_OK : HAL_ENOTSUPP; 504 1.1 alc case 2: /* rfsilent config */ 505 1.1 alc *result = AH_PRIVATE(ah)->ah_rfsilent; 506 1.1 alc return HAL_OK; 507 1.1 alc } 508 1.1 alc return HAL_ENOTSUPP; 509 1.1 alc case HAL_CAP_11D: 510 1.1 alc #ifdef AH_SUPPORT_11D 511 1.1 alc return HAL_OK; 512 1.1 alc #else 513 1.1 alc return HAL_ENOTSUPP; 514 1.1 alc #endif 515 1.1 alc case HAL_CAP_RXORN_FATAL: /* HAL_INT_RXORN treated as fatal */ 516 1.1 alc return AH_PRIVATE(ah)->ah_rxornIsFatal ? HAL_OK : HAL_ENOTSUPP; 517 1.1 alc case HAL_CAP_HT: 518 1.1 alc return pCap->halHTSupport ? HAL_OK : HAL_ENOTSUPP; 519 1.1 alc case HAL_CAP_TX_CHAINMASK: /* mask of TX chains supported */ 520 1.1 alc *result = pCap->halTxChainMask; 521 1.1 alc return HAL_OK; 522 1.1 alc case HAL_CAP_RX_CHAINMASK: /* mask of RX chains supported */ 523 1.1 alc *result = pCap->halRxChainMask; 524 1.1 alc return HAL_OK; 525 1.1 alc case HAL_CAP_RXTSTAMP_PREC: /* rx desc tstamp precision (bits) */ 526 1.1 alc *result = pCap->halTstampPrecision; 527 1.1 alc return HAL_OK; 528 1.3 cegger case HAL_CAP_INTRMASK: /* mask of supported interrupts */ 529 1.3 cegger *result = pCap->halIntrMask; 530 1.3 cegger return HAL_OK; 531 1.3 cegger case HAL_CAP_BSSIDMATCH: /* hardware has disable bssid match */ 532 1.3 cegger return pCap->halBssidMatchSupport ? HAL_OK : HAL_ENOTSUPP; 533 1.1 alc default: 534 1.1 alc return HAL_EINVAL; 535 1.1 alc } 536 1.1 alc } 537 1.1 alc 538 1.1 alc HAL_BOOL 539 1.1 alc ath_hal_setcapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type, 540 1.1 alc uint32_t capability, uint32_t setting, HAL_STATUS *status) 541 1.1 alc { 542 1.1 alc 543 1.1 alc switch (type) { 544 1.1 alc case HAL_CAP_TXPOW: 545 1.1 alc switch (capability) { 546 1.1 alc case 3: 547 1.1 alc if (setting <= HAL_TP_SCALE_MIN) { 548 1.1 alc AH_PRIVATE(ah)->ah_tpScale = setting; 549 1.1 alc return AH_TRUE; 550 1.1 alc } 551 1.1 alc break; 552 1.1 alc } 553 1.1 alc break; 554 1.1 alc case HAL_CAP_RFSILENT: /* rfsilent support */ 555 1.1 alc /* 556 1.1 alc * NB: allow even if halRfSilentSupport is false 557 1.1 alc * in case the EEPROM is misprogrammed. 558 1.1 alc */ 559 1.1 alc switch (capability) { 560 1.1 alc case 1: /* current setting */ 561 1.1 alc AH_PRIVATE(ah)->ah_rfkillEnabled = (setting != 0); 562 1.1 alc return AH_TRUE; 563 1.1 alc case 2: /* rfsilent config */ 564 1.1 alc /* XXX better done per-chip for validation? */ 565 1.1 alc AH_PRIVATE(ah)->ah_rfsilent = setting; 566 1.1 alc return AH_TRUE; 567 1.1 alc } 568 1.1 alc break; 569 1.1 alc case HAL_CAP_REG_DMN: /* regulatory domain */ 570 1.1 alc AH_PRIVATE(ah)->ah_currentRD = setting; 571 1.1 alc return AH_TRUE; 572 1.1 alc case HAL_CAP_RXORN_FATAL: /* HAL_INT_RXORN treated as fatal */ 573 1.1 alc AH_PRIVATE(ah)->ah_rxornIsFatal = setting; 574 1.1 alc return AH_TRUE; 575 1.1 alc default: 576 1.1 alc break; 577 1.1 alc } 578 1.1 alc if (status) 579 1.1 alc *status = HAL_EINVAL; 580 1.1 alc return AH_FALSE; 581 1.1 alc } 582 1.1 alc 583 1.1 alc /* 584 1.1 alc * Common support for getDiagState method. 585 1.1 alc */ 586 1.1 alc 587 1.1 alc static u_int 588 1.1 alc ath_hal_getregdump(struct ath_hal *ah, const HAL_REGRANGE *regs, 589 1.1 alc void *dstbuf, int space) 590 1.1 alc { 591 1.1 alc uint32_t *dp = dstbuf; 592 1.1 alc int i; 593 1.1 alc 594 1.1 alc for (i = 0; space >= 2*sizeof(uint32_t); i++) { 595 1.1 alc u_int r = regs[i].start; 596 1.1 alc u_int e = regs[i].end; 597 1.1 alc *dp++ = (r<<16) | e; 598 1.1 alc space -= sizeof(uint32_t); 599 1.1 alc do { 600 1.1 alc *dp++ = OS_REG_READ(ah, r); 601 1.1 alc r += sizeof(uint32_t); 602 1.1 alc space -= sizeof(uint32_t); 603 1.1 alc } while (r <= e && space >= sizeof(uint32_t)); 604 1.1 alc } 605 1.1 alc return (char *) dp - (char *) dstbuf; 606 1.1 alc } 607 1.1 alc 608 1.1 alc HAL_BOOL 609 1.1 alc ath_hal_getdiagstate(struct ath_hal *ah, int request, 610 1.1 alc const void *args, uint32_t argsize, 611 1.1 alc void **result, uint32_t *resultsize) 612 1.1 alc { 613 1.1 alc switch (request) { 614 1.1 alc case HAL_DIAG_REVS: 615 1.1 alc *result = &AH_PRIVATE(ah)->ah_devid; 616 1.1 alc *resultsize = sizeof(HAL_REVS); 617 1.1 alc return AH_TRUE; 618 1.1 alc case HAL_DIAG_REGS: 619 1.1 alc *resultsize = ath_hal_getregdump(ah, args, *result,*resultsize); 620 1.1 alc return AH_TRUE; 621 1.1 alc case HAL_DIAG_FATALERR: 622 1.1 alc *result = &AH_PRIVATE(ah)->ah_fatalState[0]; 623 1.1 alc *resultsize = sizeof(AH_PRIVATE(ah)->ah_fatalState); 624 1.1 alc return AH_TRUE; 625 1.1 alc case HAL_DIAG_EEREAD: 626 1.1 alc if (argsize != sizeof(uint16_t)) 627 1.1 alc return AH_FALSE; 628 1.1 alc if (!ath_hal_eepromRead(ah, *(const uint16_t *)args, *result)) 629 1.1 alc return AH_FALSE; 630 1.1 alc *resultsize = sizeof(uint16_t); 631 1.1 alc return AH_TRUE; 632 1.1 alc #ifdef AH_PRIVATE_DIAG 633 1.1 alc case HAL_DIAG_SETKEY: { 634 1.1 alc const HAL_DIAG_KEYVAL *dk; 635 1.1 alc 636 1.1 alc if (argsize != sizeof(HAL_DIAG_KEYVAL)) 637 1.1 alc return AH_FALSE; 638 1.1 alc dk = (const HAL_DIAG_KEYVAL *)args; 639 1.1 alc return ah->ah_setKeyCacheEntry(ah, dk->dk_keyix, 640 1.1 alc &dk->dk_keyval, dk->dk_mac, dk->dk_xor); 641 1.1 alc } 642 1.1 alc case HAL_DIAG_RESETKEY: 643 1.1 alc if (argsize != sizeof(uint16_t)) 644 1.1 alc return AH_FALSE; 645 1.1 alc return ah->ah_resetKeyCacheEntry(ah, *(const uint16_t *)args); 646 1.1 alc #ifdef AH_SUPPORT_WRITE_EEPROM 647 1.1 alc case HAL_DIAG_EEWRITE: { 648 1.1 alc const HAL_DIAG_EEVAL *ee; 649 1.1 alc if (argsize != sizeof(HAL_DIAG_EEVAL)) 650 1.1 alc return AH_FALSE; 651 1.1 alc ee = (const HAL_DIAG_EEVAL *)args; 652 1.1 alc return ath_hal_eepromWrite(ah, ee->ee_off, ee->ee_data); 653 1.1 alc } 654 1.1 alc #endif /* AH_SUPPORT_WRITE_EEPROM */ 655 1.1 alc #endif /* AH_PRIVATE_DIAG */ 656 1.1 alc case HAL_DIAG_11NCOMPAT: 657 1.1 alc if (argsize == 0) { 658 1.1 alc *resultsize = sizeof(uint32_t); 659 1.1 alc *((uint32_t *)(*result)) = 660 1.1 alc AH_PRIVATE(ah)->ah_11nCompat; 661 1.1 alc } else if (argsize == sizeof(uint32_t)) { 662 1.1 alc AH_PRIVATE(ah)->ah_11nCompat = *(const uint32_t *)args; 663 1.1 alc } else 664 1.1 alc return AH_FALSE; 665 1.1 alc return AH_TRUE; 666 1.1 alc } 667 1.1 alc return AH_FALSE; 668 1.1 alc } 669 1.1 alc 670 1.1 alc /* 671 1.1 alc * Set the properties of the tx queue with the parameters 672 1.1 alc * from qInfo. 673 1.1 alc */ 674 1.1 alc HAL_BOOL 675 1.1 alc ath_hal_setTxQProps(struct ath_hal *ah, 676 1.1 alc HAL_TX_QUEUE_INFO *qi, const HAL_TXQ_INFO *qInfo) 677 1.1 alc { 678 1.1 alc uint32_t cw; 679 1.1 alc 680 1.1 alc if (qi->tqi_type == HAL_TX_QUEUE_INACTIVE) { 681 1.1 alc HALDEBUG(ah, HAL_DEBUG_TXQUEUE, 682 1.1 alc "%s: inactive queue\n", __func__); 683 1.1 alc return AH_FALSE; 684 1.1 alc } 685 1.1 alc /* XXX validate parameters */ 686 1.1 alc qi->tqi_ver = qInfo->tqi_ver; 687 1.1 alc qi->tqi_subtype = qInfo->tqi_subtype; 688 1.1 alc qi->tqi_qflags = qInfo->tqi_qflags; 689 1.1 alc qi->tqi_priority = qInfo->tqi_priority; 690 1.1 alc if (qInfo->tqi_aifs != HAL_TXQ_USEDEFAULT) 691 1.1 alc qi->tqi_aifs = AH_MIN(qInfo->tqi_aifs, 255); 692 1.1 alc else 693 1.1 alc qi->tqi_aifs = INIT_AIFS; 694 1.1 alc if (qInfo->tqi_cwmin != HAL_TXQ_USEDEFAULT) { 695 1.1 alc cw = AH_MIN(qInfo->tqi_cwmin, 1024); 696 1.1 alc /* make sure that the CWmin is of the form (2^n - 1) */ 697 1.1 alc qi->tqi_cwmin = 1; 698 1.1 alc while (qi->tqi_cwmin < cw) 699 1.1 alc qi->tqi_cwmin = (qi->tqi_cwmin << 1) | 1; 700 1.1 alc } else 701 1.1 alc qi->tqi_cwmin = qInfo->tqi_cwmin; 702 1.1 alc if (qInfo->tqi_cwmax != HAL_TXQ_USEDEFAULT) { 703 1.1 alc cw = AH_MIN(qInfo->tqi_cwmax, 1024); 704 1.1 alc /* make sure that the CWmax is of the form (2^n - 1) */ 705 1.1 alc qi->tqi_cwmax = 1; 706 1.1 alc while (qi->tqi_cwmax < cw) 707 1.1 alc qi->tqi_cwmax = (qi->tqi_cwmax << 1) | 1; 708 1.1 alc } else 709 1.1 alc qi->tqi_cwmax = INIT_CWMAX; 710 1.1 alc /* Set retry limit values */ 711 1.1 alc if (qInfo->tqi_shretry != 0) 712 1.1 alc qi->tqi_shretry = AH_MIN(qInfo->tqi_shretry, 15); 713 1.1 alc else 714 1.1 alc qi->tqi_shretry = INIT_SH_RETRY; 715 1.1 alc if (qInfo->tqi_lgretry != 0) 716 1.1 alc qi->tqi_lgretry = AH_MIN(qInfo->tqi_lgretry, 15); 717 1.1 alc else 718 1.1 alc qi->tqi_lgretry = INIT_LG_RETRY; 719 1.1 alc qi->tqi_cbrPeriod = qInfo->tqi_cbrPeriod; 720 1.1 alc qi->tqi_cbrOverflowLimit = qInfo->tqi_cbrOverflowLimit; 721 1.1 alc qi->tqi_burstTime = qInfo->tqi_burstTime; 722 1.1 alc qi->tqi_readyTime = qInfo->tqi_readyTime; 723 1.1 alc 724 1.1 alc switch (qInfo->tqi_subtype) { 725 1.1 alc case HAL_WME_UPSD: 726 1.1 alc if (qi->tqi_type == HAL_TX_QUEUE_DATA) 727 1.1 alc qi->tqi_intFlags = HAL_TXQ_USE_LOCKOUT_BKOFF_DIS; 728 1.1 alc break; 729 1.1 alc default: 730 1.1 alc break; /* NB: silence compiler */ 731 1.1 alc } 732 1.1 alc return AH_TRUE; 733 1.1 alc } 734 1.1 alc 735 1.1 alc HAL_BOOL 736 1.1 alc ath_hal_getTxQProps(struct ath_hal *ah, 737 1.1 alc HAL_TXQ_INFO *qInfo, const HAL_TX_QUEUE_INFO *qi) 738 1.1 alc { 739 1.1 alc if (qi->tqi_type == HAL_TX_QUEUE_INACTIVE) { 740 1.1 alc HALDEBUG(ah, HAL_DEBUG_TXQUEUE, 741 1.1 alc "%s: inactive queue\n", __func__); 742 1.1 alc return AH_FALSE; 743 1.1 alc } 744 1.1 alc 745 1.1 alc qInfo->tqi_qflags = qi->tqi_qflags; 746 1.1 alc qInfo->tqi_ver = qi->tqi_ver; 747 1.1 alc qInfo->tqi_subtype = qi->tqi_subtype; 748 1.1 alc qInfo->tqi_qflags = qi->tqi_qflags; 749 1.1 alc qInfo->tqi_priority = qi->tqi_priority; 750 1.1 alc qInfo->tqi_aifs = qi->tqi_aifs; 751 1.1 alc qInfo->tqi_cwmin = qi->tqi_cwmin; 752 1.1 alc qInfo->tqi_cwmax = qi->tqi_cwmax; 753 1.1 alc qInfo->tqi_shretry = qi->tqi_shretry; 754 1.1 alc qInfo->tqi_lgretry = qi->tqi_lgretry; 755 1.1 alc qInfo->tqi_cbrPeriod = qi->tqi_cbrPeriod; 756 1.1 alc qInfo->tqi_cbrOverflowLimit = qi->tqi_cbrOverflowLimit; 757 1.1 alc qInfo->tqi_burstTime = qi->tqi_burstTime; 758 1.1 alc qInfo->tqi_readyTime = qi->tqi_readyTime; 759 1.1 alc return AH_TRUE; 760 1.1 alc } 761 1.1 alc 762 1.1 alc /* 11a Turbo 11b 11g 108g */ 763 1.1 alc static const int16_t NOISE_FLOOR[] = { -96, -93, -98, -96, -93 }; 764 1.1 alc 765 1.1 alc /* 766 1.1 alc * Read the current channel noise floor and return. 767 1.1 alc * If nf cal hasn't finished, channel noise floor should be 0 768 1.1 alc * and we return a nominal value based on band and frequency. 769 1.1 alc * 770 1.1 alc * NB: This is a private routine used by per-chip code to 771 1.1 alc * implement the ah_getChanNoise method. 772 1.1 alc */ 773 1.1 alc int16_t 774 1.1 alc ath_hal_getChanNoise(struct ath_hal *ah, HAL_CHANNEL *chan) 775 1.1 alc { 776 1.1 alc HAL_CHANNEL_INTERNAL *ichan; 777 1.1 alc 778 1.1 alc ichan = ath_hal_checkchannel(ah, chan); 779 1.1 alc if (ichan == AH_NULL) { 780 1.1 alc HALDEBUG(ah, HAL_DEBUG_NFCAL, 781 1.1 alc "%s: invalid channel %u/0x%x; no mapping\n", 782 1.1 alc __func__, chan->channel, chan->channelFlags); 783 1.1 alc return 0; 784 1.1 alc } 785 1.1 alc if (ichan->rawNoiseFloor == 0) { 786 1.1 alc WIRELESS_MODE mode = ath_hal_chan2wmode(ah, chan); 787 1.1 alc 788 1.1 alc HALASSERT(mode < WIRELESS_MODE_MAX); 789 1.1 alc return NOISE_FLOOR[mode] + ath_hal_getNfAdjust(ah, ichan); 790 1.1 alc } else 791 1.1 alc return ichan->rawNoiseFloor + ichan->noiseFloorAdjust; 792 1.1 alc } 793 1.1 alc 794 1.1 alc /* 795 1.1 alc * Process all valid raw noise floors into the dBm noise floor values. 796 1.1 alc * Though our device has no reference for a dBm noise floor, we perform 797 1.1 alc * a relative minimization of NF's based on the lowest NF found across a 798 1.1 alc * channel scan. 799 1.1 alc */ 800 1.1 alc void 801 1.1 alc ath_hal_process_noisefloor(struct ath_hal *ah) 802 1.1 alc { 803 1.1 alc HAL_CHANNEL_INTERNAL *c; 804 1.1 alc int16_t correct2, correct5; 805 1.1 alc int16_t lowest2, lowest5; 806 1.1 alc int i; 807 1.1 alc 808 1.1 alc /* 809 1.1 alc * Find the lowest 2GHz and 5GHz noise floor values after adjusting 810 1.1 alc * for statistically recorded NF/channel deviation. 811 1.1 alc */ 812 1.1 alc correct2 = lowest2 = 0; 813 1.1 alc correct5 = lowest5 = 0; 814 1.1 alc for (i = 0; i < AH_PRIVATE(ah)->ah_nchan; i++) { 815 1.1 alc WIRELESS_MODE mode; 816 1.1 alc int16_t nf; 817 1.1 alc 818 1.1 alc c = &AH_PRIVATE(ah)->ah_channels[i]; 819 1.1 alc if (c->rawNoiseFloor >= 0) 820 1.1 alc continue; 821 1.1 alc mode = ath_hal_chan2wmode(ah, (HAL_CHANNEL *) c); 822 1.1 alc HALASSERT(mode < WIRELESS_MODE_MAX); 823 1.1 alc nf = c->rawNoiseFloor + NOISE_FLOOR[mode] + 824 1.1 alc ath_hal_getNfAdjust(ah, c); 825 1.1 alc if (IS_CHAN_5GHZ(c)) { 826 1.1 alc if (nf < lowest5) { 827 1.1 alc lowest5 = nf; 828 1.1 alc correct5 = NOISE_FLOOR[mode] - 829 1.1 alc (c->rawNoiseFloor + ath_hal_getNfAdjust(ah, c)); 830 1.1 alc } 831 1.1 alc } else { 832 1.1 alc if (nf < lowest2) { 833 1.1 alc lowest2 = nf; 834 1.1 alc correct2 = NOISE_FLOOR[mode] - 835 1.1 alc (c->rawNoiseFloor + ath_hal_getNfAdjust(ah, c)); 836 1.1 alc } 837 1.1 alc } 838 1.1 alc } 839 1.1 alc 840 1.1 alc /* Correct the channels to reach the expected NF value */ 841 1.1 alc for (i = 0; i < AH_PRIVATE(ah)->ah_nchan; i++) { 842 1.1 alc c = &AH_PRIVATE(ah)->ah_channels[i]; 843 1.1 alc if (c->rawNoiseFloor >= 0) 844 1.1 alc continue; 845 1.1 alc /* Apply correction factor */ 846 1.1 alc c->noiseFloorAdjust = ath_hal_getNfAdjust(ah, c) + 847 1.1 alc (IS_CHAN_5GHZ(c) ? correct5 : correct2); 848 1.1 alc HALDEBUG(ah, HAL_DEBUG_NFCAL, "%u/0x%x raw nf %d adjust %d\n", 849 1.1 alc c->channel, c->channelFlags, c->rawNoiseFloor, 850 1.1 alc c->noiseFloorAdjust); 851 1.1 alc } 852 1.1 alc } 853 1.1 alc 854 1.1 alc /* 855 1.1 alc * INI support routines. 856 1.1 alc */ 857 1.1 alc 858 1.1 alc int 859 1.1 alc ath_hal_ini_write(struct ath_hal *ah, const HAL_INI_ARRAY *ia, 860 1.1 alc int col, int regWr) 861 1.1 alc { 862 1.1 alc int r; 863 1.1 alc 864 1.1 alc for (r = 0; r < ia->rows; r++) { 865 1.1 alc OS_REG_WRITE(ah, HAL_INI_VAL(ia, r, 0), 866 1.1 alc HAL_INI_VAL(ia, r, col)); 867 1.1 alc DMA_YIELD(regWr); 868 1.1 alc } 869 1.1 alc return regWr; 870 1.1 alc } 871 1.1 alc 872 1.1 alc void 873 1.1 alc ath_hal_ini_bank_setup(uint32_t data[], const HAL_INI_ARRAY *ia, int col) 874 1.1 alc { 875 1.1 alc int r; 876 1.1 alc 877 1.1 alc for (r = 0; r < ia->rows; r++) 878 1.1 alc data[r] = HAL_INI_VAL(ia, r, col); 879 1.1 alc } 880 1.1 alc 881 1.1 alc int 882 1.1 alc ath_hal_ini_bank_write(struct ath_hal *ah, const HAL_INI_ARRAY *ia, 883 1.1 alc const uint32_t data[], int regWr) 884 1.1 alc { 885 1.1 alc int r; 886 1.1 alc 887 1.1 alc for (r = 0; r < ia->rows; r++) { 888 1.1 alc OS_REG_WRITE(ah, HAL_INI_VAL(ia, r, 0), data[r]); 889 1.1 alc DMA_YIELD(regWr); 890 1.1 alc } 891 1.1 alc return regWr; 892 1.1 alc } 893