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