FreeBSD kernel ATH device code
ar5416_misc.c
Go to the documentation of this file.
1/*-
2 * SPDX-License-Identifier: ISC
3 *
4 * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting
5 * Copyright (c) 2002-2008 Atheros Communications, Inc.
6 *
7 * Permission to use, copy, modify, and/or distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 *
19 * $FreeBSD$
20 */
21#include "opt_ah.h"
22
23#include "ah.h"
24#include "ah_internal.h"
25#include "ah_devid.h"
26#include "ah_desc.h" /* NB: for HAL_PHYERR* */
27
28#include "ar5416/ar5416.h"
29#include "ar5416/ar5416reg.h"
30#include "ar5416/ar5416phy.h"
31
32#include "ah_eeprom_v14.h" /* for owl_get_ntxchains() */
33
34/*
35 * Return the wireless modes (a,b,g,n,t) supported by hardware.
36 *
37 * This value is what is actually supported by the hardware
38 * and is unaffected by regulatory/country code settings.
39 *
40 */
41u_int
43{
44 u_int mode;
45 struct ath_hal_private *ahpriv = AH_PRIVATE(ah);
46 HAL_CAPABILITIES *pCap = &ahpriv->ah_caps;
47
48 mode = ar5212GetWirelessModes(ah);
49
50 /* Only enable HT modes if the NIC supports HT */
51 if (pCap->halHTSupport == AH_TRUE && (mode & HAL_MODE_11A))
52 mode |= HAL_MODE_11NA_HT20
55 ;
56 if (pCap->halHTSupport == AH_TRUE && (mode & HAL_MODE_11G))
57 mode |= HAL_MODE_11NG_HT20
60 ;
61 return mode;
62}
63
64/*
65 * Change the LED blinking pattern to correspond to the connectivity
66 */
67void
69{
70 static const uint32_t ledbits[8] = {
71 AR_MAC_LED_ASSOC_NONE, /* HAL_LED_INIT */
72 AR_MAC_LED_ASSOC_PEND, /* HAL_LED_SCAN */
73 AR_MAC_LED_ASSOC_PEND, /* HAL_LED_AUTH */
74 AR_MAC_LED_ASSOC_ACTIVE, /* HAL_LED_ASSOC*/
75 AR_MAC_LED_ASSOC_ACTIVE, /* HAL_LED_RUN */
79 };
80
81 if (AR_SREV_HOWL(ah))
82 return;
83
84 /*
85 * Set the blink operating mode.
86 */
88 AR_MAC_LED_ASSOC, ledbits[state & 0x7]);
89
90 /* XXX Blink slow mode? */
91 /* XXX Blink threshold? */
92 /* XXX Blink sleep hystersis? */
93
94 /*
95 * Set the LED blink configuration to be proportional
96 * to the current TX and RX filter bytes. (Ie, RX'ed
97 * frames that don't match the filter are ignored.)
98 * This means that higher TX/RX throughput will result
99 * in the blink rate increasing.
100 */
103}
104
105/*
106 * Get the current hardware tsf for stamlme
107 */
108uint64_t
110{
111 uint32_t low1, low2, u32;
112
113 /* sync multi-word read */
114 low1 = OS_REG_READ(ah, AR_TSF_L32);
115 u32 = OS_REG_READ(ah, AR_TSF_U32);
116 low2 = OS_REG_READ(ah, AR_TSF_L32);
117 if (low2 < low1) { /* roll over */
118 /*
119 * If we are not preempted this will work. If we are
120 * then we re-reading AR_TSF_U32 does no good as the
121 * low bits will be meaningless. Likewise reading
122 * L32, U32, U32, then comparing the last two reads
123 * to check for rollover doesn't help if preempted--so
124 * we take this approach as it costs one less PCI read
125 * which can be noticeable when doing things like
126 * timestamping packets in monitor mode.
127 */
128 u32++;
129 }
130 return (((uint64_t) u32) << 32) | ((uint64_t) low2);
131}
132
133/*
134 * Update the TSF.
135 *
136 * The full TSF is only updated once the upper 32 bits have
137 * been written. Writing only the lower 32 bits of the TSF
138 * will not actually correctly update the TSF.
139 *
140 * The #if 0'ed code is to check whether the previous TSF
141 * reset or write has completed before writing to the
142 * TSF. Strictly speaking, it should be also checked before
143 * reading the TSF as the write/reset may not have completed.
144 */
145void
146ar5416SetTsf64(struct ath_hal *ah, uint64_t tsf64)
147{
148 /* XXX check if this is correct! */
149#if 0
150 int i;
151 uint32_t v;
152
153 for (i = 0; i < 10; i++) {
154 v = OS_REG_READ(ah, AR_SLP32_MODE);
155 if ((v & AR_SLP32_TSF_WRITE_STATUS) == 0)
156 break;
157 OS_DELAY(10);
158 }
159 if (i == 10)
160 ath_hal_printf(ah, "%s: couldn't slew things right!\n", __func__);
161#endif
162
163 OS_REG_WRITE(ah, AR_TSF_L32, tsf64 & 0xffffffff);
164 OS_REG_WRITE(ah, AR_TSF_U32, (tsf64 >> 32) & 0xffffffff);
165}
166
167/*
168 * Reset the current hardware tsf for stamlme.
169 */
170void
172{
173 uint32_t v;
174 int i;
175
176 for (i = 0; i < 10; i++) {
177 v = OS_REG_READ(ah, AR_SLP32_MODE);
178 if ((v & AR_SLP32_TSF_WRITE_STATUS) == 0)
179 break;
180 OS_DELAY(10);
181 }
183}
184
185uint32_t
187{
188 if (AR_SREV_OWL(ah))
189 return (OS_REG_READ(ah, AR_PHY_CURRENT_RSSI) & 0xff);
190 return (OS_REG_READ(ah, AR9130_PHY_CURRENT_RSSI) & 0xff);
191}
192
195{
196 return AH_TRUE;
197}
198
199/* Setup decompression for given key index */
201ar5416SetDecompMask(struct ath_hal *ah, uint16_t keyidx, int en)
202{
203 return AH_TRUE;
204}
205
206/* Setup coverage class */
207void
208ar5416SetCoverageClass(struct ath_hal *ah, uint8_t coverageclass, int now)
209{
210
211 ar5212SetCoverageClass(ah, coverageclass, now);
212}
213
214/*
215 * Return the busy for rx_frame, rx_clear, and tx_frame
216 */
219{
220 struct ath_hal_5416 *ahp = AH5416(ah);
221 u_int32_t good = AH_TRUE;
222
223 /* XXX freeze/unfreeze mib counters */
224 uint32_t rc = OS_REG_READ(ah, AR_RCCNT);
225 uint32_t ec = OS_REG_READ(ah, AR_EXTRCCNT);
226 uint32_t rf = OS_REG_READ(ah, AR_RFCNT);
227 uint32_t tf = OS_REG_READ(ah, AR_TFCNT);
228 uint32_t cc = OS_REG_READ(ah, AR_CCCNT); /* read cycles last */
229
230 if (ahp->ah_cycleCount == 0 || ahp->ah_cycleCount > cc) {
231 /*
232 * Cycle counter wrap (or initial call); it's not possible
233 * to accurately calculate a value because the registers
234 * right shift rather than wrap--so punt and return 0.
235 */
237 "%s: cycle counter wrap. ExtBusy = 0\n", __func__);
238 good = AH_FALSE;
239 } else {
240 hsample->cycle_count = cc - ahp->ah_cycleCount;
241 hsample->chan_busy = rc - ahp->ah_ctlBusy;
242 hsample->ext_chan_busy = ec - ahp->ah_extBusy;
243 hsample->rx_busy = rf - ahp->ah_rxBusy;
244 hsample->tx_busy = tf - ahp->ah_txBusy;
245 }
246
247 /*
248 * Keep a copy of the MIB results so the next sample has something
249 * to work from.
250 */
251 ahp->ah_cycleCount = cc;
252 ahp->ah_rxBusy = rf;
253 ahp->ah_ctlBusy = rc;
254 ahp->ah_txBusy = tf;
255 ahp->ah_extBusy = ec;
256
257 return (good);
258}
259
260/*
261 * Setup the TX/RX chainmasks - this needs to be done before a call
262 * to the reset method as it doesn't update the hardware.
263 */
264void
265ar5416SetChainMasks(struct ath_hal *ah, uint32_t tx_chainmask,
266 uint32_t rx_chainmask)
267{
268 HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;
269
270 AH5416(ah)->ah_tx_chainmask = tx_chainmask & pCap->halTxChainMask;
271 AH5416(ah)->ah_rx_chainmask = rx_chainmask & pCap->halRxChainMask;
272}
273
274/*
275 * Return approximation of extension channel busy over an time interval
276 * 0% (clear) -> 100% (busy)
277 *
278 * XXX TODO: update this to correctly sample all the counters,
279 * rather than a subset of it.
280 */
281uint32_t
283{
284 struct ath_hal_5416 *ahp = AH5416(ah);
285 uint32_t busy; /* percentage */
286 uint32_t cycleCount, ctlBusy, extBusy;
287
288 ctlBusy = OS_REG_READ(ah, AR_RCCNT);
289 extBusy = OS_REG_READ(ah, AR_EXTRCCNT);
290 cycleCount = OS_REG_READ(ah, AR_CCCNT);
291
292 if (ahp->ah_cycleCount == 0 || ahp->ah_cycleCount > cycleCount) {
293 /*
294 * Cycle counter wrap (or initial call); it's not possible
295 * to accurately calculate a value because the registers
296 * right shift rather than wrap--so punt and return 0.
297 */
298 busy = 0;
299 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: cycle counter wrap. ExtBusy = 0\n",
300 __func__);
301
302 } else {
303 uint32_t cycleDelta = cycleCount - ahp->ah_cycleCount;
304 uint32_t ctlBusyDelta = ctlBusy - ahp->ah_ctlBusy;
305 uint32_t extBusyDelta = extBusy - ahp->ah_extBusy;
306 uint32_t ctlClearDelta = 0;
307
308 /* Compute control channel rxclear.
309 * The cycle delta may be less than the control channel delta.
310 * This could be solved by freezing the timers (or an atomic read,
311 * if one was available). Checking for the condition should be
312 * sufficient.
313 */
314 if (cycleDelta > ctlBusyDelta) {
315 ctlClearDelta = cycleDelta - ctlBusyDelta;
316 }
317
318 /* Compute ratio of extension channel busy to control channel clear
319 * as an approximation to extension channel cleanliness.
320 *
321 * According to the hardware folks, ext rxclear is undefined
322 * if the ctrl rxclear is de-asserted (i.e. busy)
323 */
324 if (ctlClearDelta) {
325 busy = (extBusyDelta * 100) / ctlClearDelta;
326 } else {
327 busy = 100;
328 }
329 if (busy > 100) {
330 busy = 100;
331 }
332#if 0
333 HALDEBUG(ah, HAL_DEBUG_ANY, "%s: cycleDelta 0x%x, ctlBusyDelta 0x%x, "
334 "extBusyDelta 0x%x, ctlClearDelta 0x%x, "
335 "busy %d\n",
336 __func__, cycleDelta, ctlBusyDelta, extBusyDelta, ctlClearDelta, busy);
337#endif
338 }
339
340 ahp->ah_cycleCount = cycleCount;
341 ahp->ah_ctlBusy = ctlBusy;
342 ahp->ah_extBusy = extBusy;
343
344 return busy;
345}
346
347/*
348 * Configure 20/40 operation
349 *
350 * 20/40 = joint rx clear (control and extension)
351 * 20 = rx clear (control)
352 *
353 * - NOTE: must stop MAC (tx) and requeue 40 MHz packets as 20 MHz when changing
354 * from 20/40 => 20 only
355 */
356void
358{
359 uint32_t macmode;
360
361 /* Configure MAC for 20/40 operation */
362 if (mode == HAL_HT_MACMODE_2040) {
363 macmode = AR_2040_JOINED_RX_CLEAR;
364 } else {
365 macmode = 0;
366 }
367 OS_REG_WRITE(ah, AR_2040_MODE, macmode);
368}
369
370/*
371 * Get Rx clear (control/extension channel)
372 *
373 * Returns active low (busy) for ctrl/ext channel
374 * Owl 2.0
375 */
378{
379 HAL_HT_RXCLEAR rxclear = 0;
380 uint32_t val;
381
382 val = OS_REG_READ(ah, AR_DIAG_SW);
383
384 /* control channel */
385 if (val & AR_DIAG_RXCLEAR_CTL_LOW) {
386 rxclear |= HAL_RX_CLEAR_CTL_LOW;
387 }
388 /* extension channel */
389 if (val & AR_DIAG_RXCLEAR_EXT_LOW) {
390 rxclear |= HAL_RX_CLEAR_EXT_LOW;
391 }
392 return rxclear;
393}
394
395/*
396 * Set Rx clear (control/extension channel)
397 *
398 * Useful for forcing the channel to appear busy for
399 * debugging/diagnostics
400 * Owl 2.0
401 */
402void
404{
405 /* control channel */
406 if (rxclear & HAL_RX_CLEAR_CTL_LOW) {
408 } else {
410 }
411 /* extension channel */
412 if (rxclear & HAL_RX_CLEAR_EXT_LOW) {
414 } else {
416 }
417}
418
419/* XXX shouldn't be here! */
420#define TU_TO_USEC(_tu) ((_tu) << 10)
421
423ar5416SetQuiet(struct ath_hal *ah, uint32_t period, uint32_t duration,
424 uint32_t nextStart, HAL_QUIET_FLAG flag)
425{
426 uint32_t period_us = TU_TO_USEC(period); /* convert to us unit */
427 uint32_t nextStart_us = TU_TO_USEC(nextStart); /* convert to us unit */
428 if (flag & HAL_QUIET_ENABLE) {
429 if ((!nextStart) || (flag & HAL_QUIET_ADD_CURRENT_TSF)) {
430 /* Add the nextStart offset to the current TSF */
431 nextStart_us += OS_REG_READ(ah, AR_TSF_L32);
432 }
433 if (flag & HAL_QUIET_ADD_SWBA_RESP_TIME) {
434 nextStart_us += ah->ah_config.ah_sw_beacon_response_time;
435 }
438 OS_REG_WRITE(ah, AR_QUIET_PERIOD, period_us);
439 OS_REG_WRITE(ah, AR_NEXT_QUIET, nextStart_us);
441 } else {
443 }
444 return HAL_OK;
445}
446#undef TU_TO_USEC
447
450 uint32_t capability, uint32_t *result)
451{
452 switch (type) {
453 case HAL_CAP_BB_HANG:
454 switch (capability) {
455 case HAL_BB_HANG_RIFS:
456 return (AR_SREV_HOWL(ah) || AR_SREV_SOWL(ah)) ? HAL_OK : HAL_ENOTSUPP;
457 case HAL_BB_HANG_DFS:
458 return (AR_SREV_HOWL(ah) || AR_SREV_SOWL(ah)) ? HAL_OK : HAL_ENOTSUPP;
460 return AR_SREV_MERLIN(ah) ? HAL_OK : HAL_ENOTSUPP;
461 }
462 break;
463 case HAL_CAP_MAC_HANG:
464 return ((ah->ah_macVersion == AR_XSREV_VERSION_OWL_PCI) ||
466 AR_SREV_HOWL(ah) || AR_SREV_SOWL(ah)) ?
468 case HAL_CAP_DIVERSITY: /* disable classic fast diversity */
469 return HAL_ENXIO;
471 if (capability == 0)
472 return (HAL_OK);
473 if (capability != 1)
474 return (HAL_ENOTSUPP);
475 (*result) =
476 !! (AH5212(ah)->ah_miscMode & AR_PCU_TXOP_TBTT_LIMIT_ENA);
477 return (HAL_OK);
478 default:
479 break;
480 }
481 return ar5212GetCapability(ah, type, capability, result);
482}
483
486 u_int32_t capability, u_int32_t setting, HAL_STATUS *status)
487{
488 HAL_CAPABILITIES *pCap = &AH_PRIVATE(ah)->ah_caps;
489
490 switch (type) {
492 setting &= ath_hal_eepromGet(ah, AR_EEP_RXMASK, NULL);
493 pCap->halRxChainMask = setting;
494 if (owl_get_ntxchains(setting) > 2)
495 pCap->halRxStreams = 2;
496 else
497 pCap->halRxStreams = 1;
498 return AH_TRUE;
500 setting &= ath_hal_eepromGet(ah, AR_EEP_TXMASK, NULL);
501 pCap->halTxChainMask = setting;
502 if (owl_get_ntxchains(setting) > 2)
503 pCap->halTxStreams = 2;
504 else
505 pCap->halTxStreams = 1;
506 return AH_TRUE;
508 if (capability != 1)
509 return AH_FALSE;
510 if (setting) {
511 AH5212(ah)->ah_miscMode
515 } else {
516 AH5212(ah)->ah_miscMode
517 &= ~AR_PCU_TXOP_TBTT_LIMIT_ENA;
520 }
521 return AH_TRUE;
522 default:
523 break;
524 }
525 return ar5212SetCapability(ah, type, capability, setting, status);
526}
527
528static int ar5416DetectMacHang(struct ath_hal *ah);
529static int ar5416DetectBBHang(struct ath_hal *ah);
530
532ar5416GetDiagState(struct ath_hal *ah, int request,
533 const void *args, uint32_t argsize,
534 void **result, uint32_t *resultsize)
535{
536 struct ath_hal_5416 *ahp = AH5416(ah);
537 int hangs;
538
539 if (ath_hal_getdiagstate(ah, request, args, argsize, result, resultsize))
540 return AH_TRUE;
541 switch (request) {
542 case HAL_DIAG_EEPROM:
543 return ath_hal_eepromDiag(ah, request,
544 args, argsize, result, resultsize);
546 if (argsize != sizeof(int))
547 return AH_FALSE;
548 hangs = *(const int *) args;
549 ahp->ah_hangs = 0;
550 if (hangs & HAL_BB_HANGS)
551 ahp->ah_hangs |= ar5416DetectBBHang(ah);
552 /* NB: if BB is hung MAC will be hung too so skip check */
553 if (ahp->ah_hangs == 0 && (hangs & HAL_MAC_HANGS))
554 ahp->ah_hangs |= ar5416DetectMacHang(ah);
555 *result = &ahp->ah_hangs;
556 *resultsize = sizeof(ahp->ah_hangs);
557 return AH_TRUE;
558 }
559 return ar5212GetDiagState(ah, request,
560 args, argsize, result, resultsize);
561}
562
564ar5416SetRifsDelay(struct ath_hal *ah, const struct ieee80211_channel *chan,
565 HAL_BOOL enable)
566{
567 uint32_t val;
568 HAL_BOOL is_chan_2g = AH_FALSE;
569 HAL_BOOL is_ht40 = AH_FALSE;
570
571 if (chan)
572 is_chan_2g = IEEE80211_IS_CHAN_2GHZ(chan);
573
574 if (chan)
575 is_ht40 = IEEE80211_IS_CHAN_HT40(chan);
576
577 /* Only support disabling RIFS delay for now */
578 HALASSERT(enable == AH_FALSE);
579
580 if (enable == AH_TRUE)
581 return AH_FALSE;
582
583 /* Change RIFS init delay to 0 */
585 val &= ~AR_PHY_RIFS_INIT_DELAY;
587
588 /*
589 * For Owl, RIFS RX parameters are controlled differently;
590 * it isn't enabled in the inivals by default.
591 *
592 * For Sowl/Howl, RIFS RX is enabled in the inivals by default;
593 * the following code sets them back to non-RIFS values.
594 *
595 * For > Sowl/Howl, RIFS RX can be left on by default and so
596 * this function shouldn't be called.
597 */
598 if ((! AR_SREV_SOWL(ah)) && (! AR_SREV_HOWL(ah)))
599 return AH_TRUE;
600
601 /* Reset search delay to default values */
602 if (is_chan_2g)
603 if (is_ht40)
605 else
607 else
608 if (is_ht40)
610 else
612
613 return AH_TRUE;
614}
615
616static HAL_BOOL
618 const hal_mac_hang_check_t *check)
619{
620 int found_states;
621
622 found_states = 0;
623 if (check->states & dcu_chain_state) {
624 int i;
625
626 for (i = 0; i < 6; i++) {
627 if (((regs->dma_dbg_4 >> (5*i)) & 0x1f) ==
628 check->dcu_chain_state)
629 found_states |= dcu_chain_state;
630 }
631 for (i = 0; i < 4; i++) {
632 if (((regs->dma_dbg_5 >> (5*i)) & 0x1f) ==
633 check->dcu_chain_state)
634 found_states |= dcu_chain_state;
635 }
636 }
637 if (check->states & dcu_complete_state) {
638 if ((regs->dma_dbg_6 & 0x3) == check->dcu_complete_state)
639 found_states |= dcu_complete_state;
640 }
641 if (check->states & qcu_stitch_state) {
642 if (((regs->dma_dbg_3 >> 18) & 0xf) == check->qcu_stitch_state)
643 found_states |= qcu_stitch_state;
644 }
645 if (check->states & qcu_fetch_state) {
646 if (((regs->dma_dbg_3 >> 22) & 0xf) == check->qcu_fetch_state)
647 found_states |= qcu_fetch_state;
648 }
649 if (check->states & qcu_complete_state) {
650 if (((regs->dma_dbg_3 >> 26) & 0x7) == check->qcu_complete_state)
651 found_states |= qcu_complete_state;
652 }
653 return (found_states == check->states);
654}
655
656#define NUM_STATUS_READS 50
657
658static int
660{
661 static const hal_mac_hang_check_t hang_sig1 = {
662 .dcu_chain_state = 0x6,
663 .dcu_complete_state = 0x1,
664 .states = dcu_chain_state
666 };
667 static const hal_mac_hang_check_t hang_sig2 = {
668 .qcu_stitch_state = 0x9,
669 .qcu_fetch_state = 0x8,
670 .qcu_complete_state = 0x4,
671 .states = qcu_stitch_state
674 };
675 mac_dbg_regs_t mac_dbg;
676 int i;
677
678 mac_dbg.dma_dbg_3 = OS_REG_READ(ah, AR_DMADBG_3);
679 mac_dbg.dma_dbg_4 = OS_REG_READ(ah, AR_DMADBG_4);
680 mac_dbg.dma_dbg_5 = OS_REG_READ(ah, AR_DMADBG_5);
681 mac_dbg.dma_dbg_6 = OS_REG_READ(ah, AR_DMADBG_6);
682 for (i = 1; i <= NUM_STATUS_READS; i++) {
683 if (mac_dbg.dma_dbg_3 != OS_REG_READ(ah, AR_DMADBG_3) ||
684 mac_dbg.dma_dbg_4 != OS_REG_READ(ah, AR_DMADBG_4) ||
685 mac_dbg.dma_dbg_5 != OS_REG_READ(ah, AR_DMADBG_5) ||
686 mac_dbg.dma_dbg_6 != OS_REG_READ(ah, AR_DMADBG_6))
687 return 0;
688 }
689
690 if (ar5416CompareDbgHang(ah, &mac_dbg, &hang_sig1))
691 return HAL_MAC_HANG_SIG1;
692 if (ar5416CompareDbgHang(ah, &mac_dbg, &hang_sig2))
693 return HAL_MAC_HANG_SIG2;
694
695 HALDEBUG(ah, HAL_DEBUG_HANG, "%s Found an unknown MAC hang signature "
696 "DMADBG_3=0x%x DMADBG_4=0x%x DMADBG_5=0x%x DMADBG_6=0x%x\n",
697 __func__, mac_dbg.dma_dbg_3, mac_dbg.dma_dbg_4, mac_dbg.dma_dbg_5,
698 mac_dbg.dma_dbg_6);
699
700 return 0;
701}
702
703/*
704 * Determine if the baseband using the Observation Bus Register
705 */
706static int
708{
709#define N(a) (sizeof(a)/sizeof(a[0]))
710 /*
711 * Check the PCU Observation Bus 1 register (0x806c)
712 * NUM_STATUS_READS times
713 *
714 * 4 known BB hang signatures -
715 * [1] bits 8,9,11 are 0. State machine state (bits 25-31) is 0x1E
716 * [2] bits 8,9 are 1, bit 11 is 0. State machine state
717 * (bits 25-31) is 0x52
718 * [3] bits 8,9 are 1, bit 11 is 0. State machine state
719 * (bits 25-31) is 0x18
720 * [4] bit 10 is 1, bit 11 is 0. WEP state (bits 12-17) is 0x2,
721 * Rx State (bits 20-24) is 0x7.
722 */
723 static const struct {
724 uint32_t val;
725 uint32_t mask;
726 int code;
727 } hang_list[] = {
728 /* Reg Value Reg Mask Hang Code XXX */
729 { 0x1E000000, 0x7E000B00, HAL_BB_HANG_DFS },
730 { 0x52000B00, 0x7E000B00, HAL_BB_HANG_RIFS },
731 { 0x18000B00, 0x7E000B00, HAL_BB_HANG_RX_CLEAR },
732 { 0x00702400, 0x7E7FFFEF, HAL_BB_HANG_RX_CLEAR }
733 };
734 uint32_t hang_sig;
735 int i;
736
737 hang_sig = OS_REG_READ(ah, AR_OBSERV_1);
738 for (i = 1; i <= NUM_STATUS_READS; i++) {
739 if (hang_sig != OS_REG_READ(ah, AR_OBSERV_1))
740 return 0;
741 }
742 for (i = 0; i < N(hang_list); i++)
743 if ((hang_sig & hang_list[i].mask) == hang_list[i].val) {
745 "%s BB hang, signature 0x%x, code 0x%x\n",
746 __func__, hang_sig, hang_list[i].code);
747 return hang_list[i].code;
748 }
749
750 HALDEBUG(ah, HAL_DEBUG_HANG, "%s Found an unknown BB hang signature! "
751 "<0x806c>=0x%x\n", __func__, hang_sig);
752
753 return 0;
754#undef N
755}
756#undef NUM_STATUS_READS
HAL_STATUS
Definition: ah.h:71
@ HAL_ENOTSUPP
Definition: ah.h:85
@ HAL_ENXIO
Definition: ah.h:73
@ HAL_OK
Definition: ah.h:72
@ HAL_MODE_11NG_HT40PLUS
Definition: ah.h:674
@ HAL_MODE_11NG_HT40MINUS
Definition: ah.h:675
@ HAL_MODE_11NA_HT40MINUS
Definition: ah.h:677
@ HAL_MODE_11NA_HT40PLUS
Definition: ah.h:676
@ HAL_MODE_11NA_HT20
Definition: ah.h:673
@ HAL_MODE_11G
Definition: ah.h:664
@ HAL_MODE_11NG_HT20
Definition: ah.h:672
@ HAL_MODE_11A
Definition: ah.h:657
HAL_CAPABILITY_TYPE
Definition: ah.h:98
@ HAL_CAP_DIVERSITY
Definition: ah.h:104
@ HAL_CAP_BB_HANG
Definition: ah.h:206
@ HAL_CAP_RX_CHAINMASK
Definition: ah.h:132
@ HAL_CAP_MAC_HANG
Definition: ah.h:162
@ HAL_CAP_ENFORCE_TXOP
Definition: ah.h:213
@ HAL_CAP_TX_CHAINMASK
Definition: ah.h:131
HAL_ANT_SETTING
Definition: ah.h:758
HAL_HT_RXCLEAR
Definition: ah.h:742
@ HAL_RX_CLEAR_EXT_LOW
Definition: ah.h:744
@ HAL_RX_CLEAR_CTL_LOW
Definition: ah.h:743
HAL_HT_MACMODE
Definition: ah.h:727
@ HAL_HT_MACMODE_2040
Definition: ah.h:729
HAL_QUIET_FLAG
Definition: ah.h:1090
@ HAL_QUIET_ENABLE
Definition: ah.h:1092
@ HAL_QUIET_ADD_CURRENT_TSF
Definition: ah.h:1093
@ HAL_QUIET_ADD_SWBA_RESP_TIME
Definition: ah.h:1094
HAL_BOOL
Definition: ah.h:93
@ AH_FALSE
Definition: ah.h:94
@ AH_TRUE
Definition: ah.h:95
HAL_LED_STATE
Definition: ah.h:227
@ HAL_DEBUG_ANY
Definition: ah_debug.h:62
@ HAL_DEBUG_HANG
Definition: ah_debug.h:51
@ HAL_DIAG_CHECK_HANGS
Definition: ah_diagcodes.h:65
@ HAL_DIAG_EEPROM
Definition: ah_diagcodes.h:41
@ AR_EEP_RXMASK
Definition: ah_eeprom.h:96
@ AR_EEP_TXMASK
Definition: ah_eeprom.h:95
#define owl_get_ntxchains(_txchainmask)
Definition: ah_eeprom_v14.h:34
#define OS_REG_SET_BIT(_a, _r, _f)
Definition: ah_internal.h:594
#define SM(_v, _f)
Definition: ah_internal.h:587
@ dcu_chain_state
Definition: ah_internal.h:769
@ qcu_stitch_state
Definition: ah_internal.h:774
@ qcu_complete_state
Definition: ah_internal.h:776
@ dcu_complete_state
Definition: ah_internal.h:770
@ qcu_fetch_state
Definition: ah_internal.h:775
#define ath_hal_eepromGet(_ah, _param, _val)
Definition: ah_internal.h:486
#define OS_REG_CLR_BIT(_a, _r, _f)
Definition: ah_internal.h:596
#define AH_PRIVATE(_ah)
Definition: ah_internal.h:442
#define OS_REG_RMW_FIELD(_a, _r, _f, _v)
Definition: ah_internal.h:591
@ HAL_BB_HANG_RX_CLEAR
Definition: ah_internal.h:794
@ HAL_BB_HANGS
Definition: ah_internal.h:801
@ HAL_MAC_HANG_SIG2
Definition: ah_internal.h:798
@ HAL_BB_HANG_RIFS
Definition: ah_internal.h:793
@ HAL_MAC_HANGS
Definition: ah_internal.h:805
@ HAL_MAC_HANG_SIG1
Definition: ah_internal.h:797
@ HAL_BB_HANG_DFS
Definition: ah_internal.h:792
#define ath_hal_eepromDiag(_ah, _request, _a, _asize, _r, _rsize)
Definition: ah_internal.h:494
#define HALASSERT(_x)
Definition: ah_internal.h:683
#define HALDEBUG(_ah, __m,...)
Definition: ah_internal.h:658
void ath_hal_printf(struct ath_hal *, const char *,...)
Definition: ah_osdep.c:80
#define OS_DELAY(_n)
Definition: ah_osdep.h:69
#define OS_REG_WRITE(_ah, _reg, _val)
Definition: ah_osdep.h:139
#define OS_REG_READ(_ah, _reg)
Definition: ah_osdep.h:140
#define AR_TSF_U32
Definition: ar5210reg.h:97
#define AR_RFCNT
Definition: ar5210reg.h:53
#define AR_TSF_L32
Definition: ar5210reg.h:96
#define AR_DIAG_SW
Definition: ar5210reg.h:95
#define AR_PHY_CURRENT_RSSI
Definition: ar5211phy.h:87
HAL_BOOL ar5212SetCapability(struct ath_hal *, HAL_CAPABILITY_TYPE, uint32_t, uint32_t, HAL_STATUS *)
Definition: ar5212_misc.c:932
#define AH5212(_ah)
Definition: ar5212.h:354
void ar5212SetCoverageClass(struct ath_hal *, uint8_t, int)
Definition: ar5212_misc.c:589
u_int ar5212GetWirelessModes(struct ath_hal *ah)
Definition: ar5212_misc.c:115
HAL_STATUS ar5212GetCapability(struct ath_hal *, HAL_CAPABILITY_TYPE, uint32_t, uint32_t *)
Definition: ar5212_misc.c:795
HAL_BOOL ar5212GetDiagState(struct ath_hal *ah, int request, const void *args, uint32_t argsize, void **result, uint32_t *resultsize)
Definition: ar5212_misc.c:1052
#define AR_QUIET2
Definition: ar5212reg.h:309
#define AR_DMADBG_5
Definition: ar5212reg.h:72
#define AR_QUIET1
Definition: ar5212reg.h:302
#define AR_RCCNT
Definition: ar5212reg.h:299
#define AR_TFCNT
Definition: ar5212reg.h:297
#define AR_QUIET2_QUIET_DUR
Definition: ar5212reg.h:313
#define AR_DMADBG_6
Definition: ar5212reg.h:73
#define AR_MISC_MODE
Definition: ar5212reg.h:321
#define AR_OBSERV_1
Definition: ar5212reg.h:281
#define AR_CCCNT
Definition: ar5212reg.h:300
#define AR_QUIET1_QUIET_ACK_CTS_ENABLE
Definition: ar5212reg.h:306
#define AR_DMADBG_4
Definition: ar5212reg.h:71
#define AR_DMADBG_3
Definition: ar5212reg.h:70
#define AH5416(_ah)
Definition: ar5416.h:162
void ar5416ResetTsf(struct ath_hal *ah)
Definition: ar5416_misc.c:171
#define NUM_STATUS_READS
Definition: ar5416_misc.c:656
u_int ar5416GetWirelessModes(struct ath_hal *ah)
Definition: ar5416_misc.c:42
HAL_HT_RXCLEAR ar5416Get11nRxClear(struct ath_hal *ah)
Definition: ar5416_misc.c:377
uint64_t ar5416GetTsf64(struct ath_hal *ah)
Definition: ar5416_misc.c:109
static HAL_BOOL ar5416CompareDbgHang(struct ath_hal *ah, const mac_dbg_regs_t *regs, const hal_mac_hang_check_t *check)
Definition: ar5416_misc.c:617
HAL_STATUS ar5416GetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type, uint32_t capability, uint32_t *result)
Definition: ar5416_misc.c:449
void ar5416SetTsf64(struct ath_hal *ah, uint64_t tsf64)
Definition: ar5416_misc.c:146
HAL_BOOL ar5416GetMibCycleCounts(struct ath_hal *ah, HAL_SURVEY_SAMPLE *hsample)
Definition: ar5416_misc.c:218
uint32_t ar5416GetCurRssi(struct ath_hal *ah)
Definition: ar5416_misc.c:186
void ar5416Set11nMac2040(struct ath_hal *ah, HAL_HT_MACMODE mode)
Definition: ar5416_misc.c:357
void ar5416SetLedState(struct ath_hal *ah, HAL_LED_STATE state)
Definition: ar5416_misc.c:68
void ar5416SetChainMasks(struct ath_hal *ah, uint32_t tx_chainmask, uint32_t rx_chainmask)
Definition: ar5416_misc.c:265
static int ar5416DetectBBHang(struct ath_hal *ah)
Definition: ar5416_misc.c:707
HAL_BOOL ar5416SetCapability(struct ath_hal *ah, HAL_CAPABILITY_TYPE type, u_int32_t capability, u_int32_t setting, HAL_STATUS *status)
Definition: ar5416_misc.c:485
HAL_BOOL ar5416SetAntennaSwitch(struct ath_hal *ah, HAL_ANT_SETTING settings)
Definition: ar5416_misc.c:194
HAL_BOOL ar5416GetDiagState(struct ath_hal *ah, int request, const void *args, uint32_t argsize, void **result, uint32_t *resultsize)
Definition: ar5416_misc.c:532
HAL_BOOL ar5416SetDecompMask(struct ath_hal *ah, uint16_t keyidx, int en)
Definition: ar5416_misc.c:201
uint32_t ar5416Get11nExtBusy(struct ath_hal *ah)
Definition: ar5416_misc.c:282
void ar5416SetCoverageClass(struct ath_hal *ah, uint8_t coverageclass, int now)
Definition: ar5416_misc.c:208
HAL_STATUS ar5416SetQuiet(struct ath_hal *ah, uint32_t period, uint32_t duration, uint32_t nextStart, HAL_QUIET_FLAG flag)
Definition: ar5416_misc.c:423
HAL_BOOL ar5416SetRifsDelay(struct ath_hal *ah, const struct ieee80211_channel *chan, HAL_BOOL enable)
Definition: ar5416_misc.c:564
static int ar5416DetectMacHang(struct ath_hal *ah)
Definition: ar5416_misc.c:659
#define N(a)
#define TU_TO_USEC(_tu)
Definition: ar5416_misc.c:420
void ar5416Set11nRxClear(struct ath_hal *ah, HAL_HT_RXCLEAR rxclear)
Definition: ar5416_misc.c:403
#define AR_2040_MODE
Definition: ar5416phy.h:129
#define AR9130_PHY_CURRENT_RSSI
Definition: ar5416phy.h:231
#define AR_PHY_SEARCH_START_DELAY
Definition: ar5416phy.h:186
#define AR_2040_JOINED_RX_CLEAR
Definition: ar5416phy.h:130
#define AR_PHY_HEAVY_CLIP_FACTOR_RIFS
Definition: ar5416phy.h:207
#define AR_EXTRCCNT
Definition: ar5416reg.h:182
#define AR_DIAG_RXCLEAR_CTL_LOW
Definition: ar5416reg.h:302
#define AR_SREV_SOWL(_ah)
Definition: ar5416reg.h:725
#define AR_NEXT_QUIET
Definition: ar5416reg.h:164
#define AR_TIMER_MODE
Definition: ar5416reg.h:174
#define AR_MAC_LED_ASSOC_ACTIVE
Definition: ar5416reg.h:261
#define AR_DIAG_RXCLEAR_EXT_LOW
Definition: ar5416reg.h:303
#define AR_MAC_LED_ASSOC_PEND
Definition: ar5416reg.h:262
#define AR_PCU_TXOP_TBTT_LIMIT_ENA
Definition: ar5416reg.h:517
#define AR_RESET_TSF
Definition: ar5416reg.h:134
#define AR_MAC_LED
Definition: ar5416reg.h:35
#define AR_TIMER_MODE_QUIET
Definition: ar5416reg.h:504
#define AR_MAC_LED_MODE
Definition: ar5416reg.h:251
#define AR_RESET_TSF_ONCE
Definition: ar5416reg.h:307
#define AR_SREV_OWL(_ah)
Definition: ar5416reg.h:702
#define AR_MAC_LED_MODE_PROP
Definition: ar5416reg.h:253
#define AR_SLP32_MODE
Definition: ar5416reg.h:175
#define AR_SREV_HOWL(_ah)
Definition: ar5416reg.h:718
#define AR_XSREV_VERSION_OWL_PCIE
Definition: ar5416reg.h:669
#define AR_XSREV_VERSION_OWL_PCI
Definition: ar5416reg.h:668
#define AR_SLP32_TSF_WRITE_STATUS
Definition: ar5416reg.h:489
#define AR_SREV_MERLIN(_ah)
Definition: ar5416reg.h:737
#define AR_QUIET_PERIOD
Definition: ar5416reg.h:172
#define AR_MAC_LED_ASSOC
Definition: ar5416reg.h:259
#define AR_MAC_LED_ASSOC_NONE
Definition: ar5416reg.h:260
#define ath_hal_getdiagstate(_ah, _id, _indata, _insize, _outdata, _outsize)
Definition: if_athvar.h:1165
uint8_t halRxStreams
Definition: ah_internal.h:310
uint32_t halHTSupport
Definition: ah_internal.h:245
uint8_t halTxStreams
Definition: ah_internal.h:309
uint8_t halTxChainMask
Definition: ah_internal.h:303
uint8_t halRxChainMask
Definition: ah_internal.h:304
int ah_sw_beacon_response_time
Definition: ah.h:1160
uint32_t rx_busy
Definition: ah.h:940
uint32_t ext_chan_busy
Definition: ah.h:942
uint32_t tx_busy
Definition: ah.h:939
uint32_t cycle_count
Definition: ah.h:943
uint32_t chan_busy
Definition: ah.h:941
uint32_t ah_txBusy
Definition: ar5416.h:120
int ah_hangs
Definition: ar5416.h:111
uint32_t ah_rxBusy
Definition: ar5416.h:119
uint32_t ah_extBusy
Definition: ar5416.h:118
uint32_t ah_ctlBusy
Definition: ar5416.h:117
uint32_t ah_cycleCount
Definition: ar5416.h:116
HAL_CAPABILITIES ah_caps
Definition: ah_internal.h:402
Definition: ah.h:1219
uint32_t ah_macVersion
Definition: ah.h:1228
HAL_OPS_CONFIG ah_config
Definition: ah.h:1243
uint8_t dcu_complete_state
Definition: ah_internal.h:782
uint8_t qcu_complete_state
Definition: ah_internal.h:788
uint32_t dma_dbg_6
Definition: ah_internal.h:765
uint32_t dma_dbg_5
Definition: ah_internal.h:764
uint32_t dma_dbg_3
Definition: ah_internal.h:762
uint32_t dma_dbg_4
Definition: ah_internal.h:763