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