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