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