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