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