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