1250003Sadrian/*
2250003Sadrian * Copyright (c) 2013 Qualcomm Atheros, Inc.
3250003Sadrian *
4250003Sadrian * Permission to use, copy, modify, and/or distribute this software for any
5250003Sadrian * purpose with or without fee is hereby granted, provided that the above
6250003Sadrian * copyright notice and this permission notice appear in all copies.
7250003Sadrian *
8250003Sadrian * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
9250003Sadrian * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10250003Sadrian * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
11250003Sadrian * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12250003Sadrian * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
13250003Sadrian * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14250003Sadrian * PERFORMANCE OF THIS SOFTWARE.
15250003Sadrian */
16250003Sadrian
17250003Sadrian#include "opt_ah.h"
18250003Sadrian
19250003Sadrian#include "ah.h"
20250003Sadrian#include "ah_internal.h"
21250003Sadrian
22250003Sadrian#include "ar9300/ar9300.h"
23250003Sadrian#include "ar9300/ar9300reg.h"
24250003Sadrian#include "ar9300/ar9300phy.h"
25250003Sadrian
26250003Sadrian/*
27250003Sadrian * Checks to see if an interrupt is pending on our NIC
28250003Sadrian *
29250003Sadrian * Returns: TRUE    if an interrupt is pending
30250003Sadrian *          FALSE   if not
31250003Sadrian */
32250003SadrianHAL_BOOL
33250003Sadrianar9300_is_interrupt_pending(struct ath_hal *ah)
34250003Sadrian{
35250003Sadrian    u_int32_t sync_en_def = AR9300_INTR_SYNC_DEFAULT;
36250003Sadrian    u_int32_t host_isr;
37250003Sadrian
38250003Sadrian    /*
39250003Sadrian     * Some platforms trigger our ISR before applying power to
40250003Sadrian     * the card, so make sure.
41250003Sadrian     */
42250003Sadrian    host_isr = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_ASYNC_CAUSE));
43250003Sadrian    if ((host_isr & AR_INTR_ASYNC_USED) && (host_isr != AR_INTR_SPURIOUS)) {
44250003Sadrian        return AH_TRUE;
45250003Sadrian    }
46250003Sadrian
47250003Sadrian    host_isr = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_CAUSE));
48250003Sadrian    if (AR_SREV_POSEIDON(ah)) {
49250003Sadrian        sync_en_def = AR9300_INTR_SYNC_DEF_NO_HOST1_PERR;
50250003Sadrian    }
51250003Sadrian    else if (AR_SREV_WASP(ah)) {
52250003Sadrian        sync_en_def = AR9340_INTR_SYNC_DEFAULT;
53250003Sadrian    }
54250003Sadrian
55250003Sadrian    if ((host_isr & (sync_en_def | AR_INTR_SYNC_MASK_GPIO)) &&
56250003Sadrian        (host_isr != AR_INTR_SPURIOUS)) {
57250003Sadrian        return AH_TRUE;
58250003Sadrian    }
59250003Sadrian
60250003Sadrian    return AH_FALSE;
61250003Sadrian}
62250003Sadrian
63250003Sadrian/*
64250003Sadrian * Reads the Interrupt Status Register value from the NIC, thus deasserting
65250003Sadrian * the interrupt line, and returns both the masked and unmasked mapped ISR
66250003Sadrian * values.  The value returned is mapped to abstract the hw-specific bit
67250003Sadrian * locations in the Interrupt Status Register.
68250003Sadrian *
69250003Sadrian * Returns: A hardware-abstracted bitmap of all non-masked-out
70250003Sadrian *          interrupts pending, as well as an unmasked value
71250003Sadrian */
72250003Sadrian#define MAP_ISR_S2_HAL_CST          6 /* Carrier sense timeout */
73250003Sadrian#define MAP_ISR_S2_HAL_GTT          6 /* Global transmit timeout */
74250003Sadrian#define MAP_ISR_S2_HAL_TIM          3 /* TIM */
75250003Sadrian#define MAP_ISR_S2_HAL_CABEND       0 /* CABEND */
76250003Sadrian#define MAP_ISR_S2_HAL_DTIMSYNC     7 /* DTIMSYNC */
77250003Sadrian#define MAP_ISR_S2_HAL_DTIM         7 /* DTIM */
78250003Sadrian#define MAP_ISR_S2_HAL_TSFOOR       4 /* Rx TSF out of range */
79250003Sadrian#define MAP_ISR_S2_HAL_BBPANIC      6 /* Panic watchdog IRQ from BB */
80250003SadrianHAL_BOOL
81250003Sadrianar9300_get_pending_interrupts(
82250003Sadrian    struct ath_hal *ah,
83250003Sadrian    HAL_INT *masked,
84250003Sadrian    HAL_INT_TYPE type,
85250003Sadrian    u_int8_t msi,
86250003Sadrian    HAL_BOOL nortc)
87250003Sadrian{
88250003Sadrian    struct ath_hal_9300 *ahp = AH9300(ah);
89250003Sadrian    HAL_BOOL  ret_val = AH_TRUE;
90250003Sadrian    u_int32_t isr = 0;
91250003Sadrian    u_int32_t mask2 = 0;
92250003Sadrian    u_int32_t sync_cause = 0;
93250003Sadrian    u_int32_t async_cause;
94250003Sadrian    u_int32_t msi_pend_addr_mask = 0;
95250003Sadrian    u_int32_t sync_en_def = AR9300_INTR_SYNC_DEFAULT;
96250003Sadrian    HAL_CAPABILITIES *p_cap = &AH_PRIVATE(ah)->ah_caps;
97250003Sadrian
98250003Sadrian    *masked = 0;
99250003Sadrian
100250003Sadrian    if (!nortc) {
101250003Sadrian        if (HAL_INT_MSI == type) {
102250003Sadrian            if (msi == HAL_MSIVEC_RXHP) {
103250003Sadrian                OS_REG_WRITE(ah, AR_ISR, AR_ISR_HP_RXOK);
104250003Sadrian                *masked = HAL_INT_RXHP;
105250003Sadrian                goto end;
106250003Sadrian            } else if (msi == HAL_MSIVEC_RXLP) {
107250003Sadrian                OS_REG_WRITE(ah, AR_ISR,
108250003Sadrian                    (AR_ISR_LP_RXOK | AR_ISR_RXMINTR | AR_ISR_RXINTM));
109250003Sadrian                *masked = HAL_INT_RXLP;
110250003Sadrian                goto end;
111250003Sadrian            } else if (msi == HAL_MSIVEC_TX) {
112250003Sadrian                OS_REG_WRITE(ah, AR_ISR, AR_ISR_TXOK);
113250003Sadrian                *masked = HAL_INT_TX;
114250003Sadrian                goto end;
115250003Sadrian            } else if (msi == HAL_MSIVEC_MISC) {
116250003Sadrian                /*
117250003Sadrian                 * For the misc MSI event fall through and determine the cause.
118250003Sadrian                 */
119250003Sadrian            }
120250003Sadrian        }
121250003Sadrian    }
122250003Sadrian
123250003Sadrian    /* Make sure mac interrupt is pending in async interrupt cause register */
124250003Sadrian    async_cause = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_ASYNC_CAUSE));
125250003Sadrian    if (async_cause & AR_INTR_ASYNC_USED) {
126250003Sadrian        /*
127250003Sadrian         * RTC may not be on since it runs on a slow 32khz clock
128250003Sadrian         * so check its status to be sure
129250003Sadrian         */
130250003Sadrian        if (!nortc &&
131250003Sadrian            (OS_REG_READ(ah, AR_RTC_STATUS) & AR_RTC_STATUS_M) ==
132250003Sadrian             AR_RTC_STATUS_ON)
133250003Sadrian        {
134250003Sadrian            isr = OS_REG_READ(ah, AR_ISR);
135250003Sadrian        }
136250003Sadrian    }
137250003Sadrian
138250003Sadrian    if (AR_SREV_POSEIDON(ah)) {
139250003Sadrian        sync_en_def = AR9300_INTR_SYNC_DEF_NO_HOST1_PERR;
140250003Sadrian    }
141250003Sadrian    else if (AR_SREV_WASP(ah)) {
142250003Sadrian        sync_en_def = AR9340_INTR_SYNC_DEFAULT;
143250003Sadrian    }
144250003Sadrian
145269146Sadrian    /* Store away the async and sync cause registers */
146269146Sadrian    /* XXX Do this before the filtering done below */
147269146Sadrian#ifdef	AH_INTERRUPT_DEBUGGING
148269146Sadrian	ah->ah_intrstate[0] = OS_REG_READ(ah, AR_ISR);
149269146Sadrian	ah->ah_intrstate[1] = OS_REG_READ(ah, AR_ISR_S0);
150269146Sadrian	ah->ah_intrstate[2] = OS_REG_READ(ah, AR_ISR_S1);
151269146Sadrian	ah->ah_intrstate[3] = OS_REG_READ(ah, AR_ISR_S2);
152269146Sadrian	ah->ah_intrstate[4] = OS_REG_READ(ah, AR_ISR_S3);
153269146Sadrian	ah->ah_intrstate[5] = OS_REG_READ(ah, AR_ISR_S4);
154269146Sadrian	ah->ah_intrstate[6] = OS_REG_READ(ah, AR_ISR_S5);
155269146Sadrian
156269146Sadrian	/* XXX double reading? */
157269146Sadrian	ah->ah_syncstate = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_CAUSE));
158269146Sadrian#endif
159269146Sadrian
160250003Sadrian    sync_cause =
161250003Sadrian        OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_CAUSE)) &
162250003Sadrian        (sync_en_def | AR_INTR_SYNC_MASK_GPIO);
163250003Sadrian
164250003Sadrian    if (!isr && !sync_cause && !async_cause) {
165250003Sadrian        ret_val = AH_FALSE;
166250003Sadrian        goto end;
167250003Sadrian    }
168250003Sadrian
169250008Sadrian    HALDEBUG(ah, HAL_DEBUG_INTERRUPT,
170250008Sadrian        "%s: isr=0x%x, sync_cause=0x%x, async_cause=0x%x\n",
171250008Sadrian	__func__,
172250008Sadrian	isr,
173250008Sadrian	sync_cause,
174250008Sadrian	async_cause);
175250008Sadrian
176250003Sadrian    if (isr) {
177250003Sadrian        if (isr & AR_ISR_BCNMISC) {
178250003Sadrian            u_int32_t isr2;
179250003Sadrian            isr2 = OS_REG_READ(ah, AR_ISR_S2);
180250003Sadrian
181250003Sadrian            /* Translate ISR bits to HAL values */
182250003Sadrian            mask2 |= ((isr2 & AR_ISR_S2_TIM) >> MAP_ISR_S2_HAL_TIM);
183250003Sadrian            mask2 |= ((isr2 & AR_ISR_S2_DTIM) >> MAP_ISR_S2_HAL_DTIM);
184250003Sadrian            mask2 |= ((isr2 & AR_ISR_S2_DTIMSYNC) >> MAP_ISR_S2_HAL_DTIMSYNC);
185250003Sadrian            mask2 |= ((isr2 & AR_ISR_S2_CABEND) >> MAP_ISR_S2_HAL_CABEND);
186250003Sadrian            mask2 |= ((isr2 & AR_ISR_S2_GTT) << MAP_ISR_S2_HAL_GTT);
187250003Sadrian            mask2 |= ((isr2 & AR_ISR_S2_CST) << MAP_ISR_S2_HAL_CST);
188250003Sadrian            mask2 |= ((isr2 & AR_ISR_S2_TSFOOR) >> MAP_ISR_S2_HAL_TSFOOR);
189250003Sadrian            mask2 |= ((isr2 & AR_ISR_S2_BBPANIC) >> MAP_ISR_S2_HAL_BBPANIC);
190250003Sadrian
191250008Sadrian            if (!p_cap->halIsrRacSupport) {
192250003Sadrian                /*
193250003Sadrian                 * EV61133 (missing interrupts due to ISR_RAC):
194250003Sadrian                 * If not using ISR_RAC, clear interrupts by writing to ISR_S2.
195250003Sadrian                 * This avoids a race condition where a new BCNMISC interrupt
196250003Sadrian                 * could come in between reading the ISR and clearing the
197250003Sadrian                 * interrupt via the primary ISR.  We therefore clear the
198250003Sadrian                 * interrupt via the secondary, which avoids this race.
199250003Sadrian                 */
200250003Sadrian                OS_REG_WRITE(ah, AR_ISR_S2, isr2);
201250003Sadrian                isr &= ~AR_ISR_BCNMISC;
202250003Sadrian            }
203250003Sadrian        }
204250003Sadrian
205250003Sadrian        /* Use AR_ISR_RAC only if chip supports it.
206250003Sadrian         * See EV61133 (missing interrupts due to ISR_RAC)
207250003Sadrian         */
208250008Sadrian        if (p_cap->halIsrRacSupport) {
209250003Sadrian            isr = OS_REG_READ(ah, AR_ISR_RAC);
210250003Sadrian        }
211250003Sadrian        if (isr == 0xffffffff) {
212250003Sadrian            *masked = 0;
213250003Sadrian            ret_val = AH_FALSE;
214250003Sadrian            goto end;
215250003Sadrian        }
216250003Sadrian
217250003Sadrian        *masked = isr & HAL_INT_COMMON;
218250003Sadrian
219250003Sadrian        /*
220250003Sadrian         * When interrupt mitigation is switched on, we fake a normal RX or TX
221250003Sadrian         * interrupt when we received a mitigated interrupt. This way, the upper
222250003Sadrian         * layer do not need to know about feature.
223250003Sadrian         */
224250003Sadrian        if (ahp->ah_intr_mitigation_rx) {
225250003Sadrian            /* Only Rx interrupt mitigation. No Tx intr. mitigation. */
226250003Sadrian            if (isr & (AR_ISR_RXMINTR | AR_ISR_RXINTM)) {
227250003Sadrian                *masked |= HAL_INT_RXLP;
228250003Sadrian            }
229250003Sadrian        }
230250003Sadrian        if (ahp->ah_intr_mitigation_tx) {
231250003Sadrian            if (isr & (AR_ISR_TXMINTR | AR_ISR_TXINTM)) {
232250003Sadrian                *masked |= HAL_INT_TX;
233250003Sadrian            }
234250003Sadrian        }
235250003Sadrian
236250003Sadrian        if (isr & (AR_ISR_LP_RXOK | AR_ISR_RXERR)) {
237250003Sadrian            *masked |= HAL_INT_RXLP;
238250003Sadrian        }
239250003Sadrian        if (isr & AR_ISR_HP_RXOK) {
240250003Sadrian            *masked |= HAL_INT_RXHP;
241250003Sadrian        }
242250003Sadrian        if (isr & (AR_ISR_TXOK | AR_ISR_TXERR | AR_ISR_TXEOL)) {
243250003Sadrian            *masked |= HAL_INT_TX;
244250003Sadrian
245250008Sadrian            if (!p_cap->halIsrRacSupport) {
246250003Sadrian                u_int32_t s0, s1;
247250003Sadrian                /*
248250003Sadrian                 * EV61133 (missing interrupts due to ISR_RAC):
249250003Sadrian                 * If not using ISR_RAC, clear interrupts by writing to
250250003Sadrian                 * ISR_S0/S1.
251250003Sadrian                 * This avoids a race condition where a new interrupt
252250003Sadrian                 * could come in between reading the ISR and clearing the
253250003Sadrian                 * interrupt via the primary ISR.  We therefore clear the
254250003Sadrian                 * interrupt via the secondary, which avoids this race.
255250003Sadrian                 */
256250003Sadrian                s0 = OS_REG_READ(ah, AR_ISR_S0);
257250003Sadrian                OS_REG_WRITE(ah, AR_ISR_S0, s0);
258250003Sadrian                s1 = OS_REG_READ(ah, AR_ISR_S1);
259250003Sadrian                OS_REG_WRITE(ah, AR_ISR_S1, s1);
260250003Sadrian
261250003Sadrian                isr &= ~(AR_ISR_TXOK | AR_ISR_TXERR | AR_ISR_TXEOL);
262250003Sadrian            }
263250003Sadrian        }
264250003Sadrian
265250003Sadrian        /*
266250003Sadrian         * Do not treat receive overflows as fatal for owl.
267250003Sadrian         */
268250003Sadrian        if (isr & AR_ISR_RXORN) {
269250003Sadrian#if __PKT_SERIOUS_ERRORS__
270250003Sadrian            HALDEBUG(ah, HAL_DEBUG_INTERRUPT,
271250003Sadrian                "%s: receive FIFO overrun interrupt\n", __func__);
272250003Sadrian#endif
273250003Sadrian        }
274250003Sadrian
275250003Sadrian#if 0
276250003Sadrian        /* XXX Verify if this is fixed for Osprey */
277250008Sadrian        if (!p_cap->halAutoSleepSupport) {
278250003Sadrian            u_int32_t isr5 = OS_REG_READ(ah, AR_ISR_S5_S);
279250003Sadrian            if (isr5 & AR_ISR_S5_TIM_TIMER) {
280250003Sadrian                *masked |= HAL_INT_TIM_TIMER;
281250003Sadrian            }
282250003Sadrian        }
283250003Sadrian#endif
284250003Sadrian        if (isr & AR_ISR_GENTMR) {
285250003Sadrian            u_int32_t s5;
286250003Sadrian
287250008Sadrian            if (p_cap->halIsrRacSupport) {
288250003Sadrian                /* Use secondary shadow registers if using ISR_RAC */
289250003Sadrian                s5 = OS_REG_READ(ah, AR_ISR_S5_S);
290250003Sadrian            } else {
291250003Sadrian                s5 = OS_REG_READ(ah, AR_ISR_S5);
292250003Sadrian            }
293250003Sadrian            if (isr & AR_ISR_GENTMR) {
294250003Sadrian
295250003Sadrian                HALDEBUG(ah, HAL_DEBUG_INTERRUPT,
296250003Sadrian                    "%s: GENTIMER, ISR_RAC=0x%x ISR_S2_S=0x%x\n", __func__,
297250003Sadrian                    isr, s5);
298250003Sadrian                ahp->ah_intr_gen_timer_trigger =
299250003Sadrian                    MS(s5, AR_ISR_S5_GENTIMER_TRIG);
300250003Sadrian                ahp->ah_intr_gen_timer_thresh =
301250003Sadrian                    MS(s5, AR_ISR_S5_GENTIMER_THRESH);
302250003Sadrian                if (ahp->ah_intr_gen_timer_trigger) {
303250003Sadrian                    *masked |= HAL_INT_GENTIMER;
304250003Sadrian                }
305250003Sadrian            }
306250008Sadrian            if (!p_cap->halIsrRacSupport) {
307250003Sadrian                /*
308250003Sadrian                 * EV61133 (missing interrupts due to ISR_RAC):
309250003Sadrian                 * If not using ISR_RAC, clear interrupts by writing to ISR_S5.
310250003Sadrian                 * This avoids a race condition where a new interrupt
311250003Sadrian                 * could come in between reading the ISR and clearing the
312250003Sadrian                 * interrupt via the primary ISR.  We therefore clear the
313250003Sadrian                 * interrupt via the secondary, which avoids this race.
314250003Sadrian                 */
315250003Sadrian                OS_REG_WRITE(ah, AR_ISR_S5, s5);
316250003Sadrian                isr &= ~AR_ISR_GENTMR;
317250003Sadrian            }
318250003Sadrian        }
319250003Sadrian
320250003Sadrian        *masked |= mask2;
321250003Sadrian
322250008Sadrian        if (!p_cap->halIsrRacSupport) {
323250003Sadrian            /*
324250003Sadrian             * EV61133 (missing interrupts due to ISR_RAC):
325250003Sadrian             * If not using ISR_RAC, clear the interrupts we've read by
326250003Sadrian             * writing back ones in these locations to the primary ISR
327250003Sadrian             * (except for interrupts that have a secondary isr register -
328250003Sadrian             * see above).
329250003Sadrian             */
330250003Sadrian            OS_REG_WRITE(ah, AR_ISR, isr);
331250003Sadrian
332250003Sadrian            /* Flush prior write */
333250003Sadrian            (void) OS_REG_READ(ah, AR_ISR);
334250003Sadrian        }
335250003Sadrian
336250003Sadrian#ifdef AH_SUPPORT_AR9300
337250003Sadrian        if (*masked & HAL_INT_BBPANIC) {
338250003Sadrian            ar9300_handle_bb_panic(ah);
339250003Sadrian        }
340250003Sadrian#endif
341250003Sadrian    }
342250003Sadrian
343250003Sadrian    if (async_cause) {
344250003Sadrian        if (nortc) {
345250003Sadrian            OS_REG_WRITE(ah,
346250003Sadrian                AR_HOSTIF_REG(ah, AR_INTR_ASYNC_CAUSE_CLR), async_cause);
347250003Sadrian            /* Flush prior write */
348250003Sadrian            (void) OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_ASYNC_CAUSE_CLR));
349250003Sadrian        } else {
350250003Sadrian#ifdef ATH_GPIO_USE_ASYNC_CAUSE
351250003Sadrian            if (async_cause & AR_INTR_ASYNC_CAUSE_GPIO) {
352250003Sadrian                ahp->ah_gpio_cause = (async_cause & AR_INTR_ASYNC_CAUSE_GPIO) >>
353250003Sadrian                                     AR_INTR_ASYNC_ENABLE_GPIO_S;
354250003Sadrian                *masked |= HAL_INT_GPIO;
355250003Sadrian            }
356250003Sadrian#endif
357250003Sadrian        }
358250003Sadrian
359250003Sadrian#if ATH_SUPPORT_MCI
360250003Sadrian        if ((async_cause & AR_INTR_ASYNC_CAUSE_MCI) &&
361250008Sadrian            p_cap->halMciSupport)
362250003Sadrian        {
363250003Sadrian            u_int32_t int_raw, int_rx_msg;
364250003Sadrian
365250003Sadrian            int_rx_msg = OS_REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_RAW);
366250003Sadrian            int_raw = OS_REG_READ(ah, AR_MCI_INTERRUPT_RAW);
367250003Sadrian
368250003Sadrian            if ((int_raw == 0xdeadbeef) || (int_rx_msg == 0xdeadbeef))
369250003Sadrian            {
370250003Sadrian                HALDEBUG(ah, HAL_DEBUG_BT_COEX,
371250003Sadrian                    "(MCI) Get 0xdeadbeef during MCI int processing"
372250003Sadrian                    "new int_raw=0x%08x, new rx_msg_raw=0x%08x, "
373250003Sadrian                    "int_raw=0x%08x, rx_msg_raw=0x%08x\n",
374250003Sadrian                    int_raw, int_rx_msg, ahp->ah_mci_int_raw,
375250003Sadrian                    ahp->ah_mci_int_rx_msg);
376250003Sadrian            }
377250003Sadrian            else {
378250003Sadrian                if (ahp->ah_mci_int_raw || ahp->ah_mci_int_rx_msg) {
379250003Sadrian                    ahp->ah_mci_int_rx_msg |= int_rx_msg;
380250003Sadrian                    ahp->ah_mci_int_raw |= int_raw;
381250003Sadrian                }
382250003Sadrian                else {
383250003Sadrian                    ahp->ah_mci_int_rx_msg = int_rx_msg;
384250003Sadrian                    ahp->ah_mci_int_raw = int_raw;
385250003Sadrian                }
386250003Sadrian
387250003Sadrian                *masked |= HAL_INT_MCI;
388250003Sadrian                ahp->ah_mci_rx_status = OS_REG_READ(ah, AR_MCI_RX_STATUS);
389250003Sadrian                if (int_rx_msg & AR_MCI_INTERRUPT_RX_MSG_CONT_INFO) {
390250003Sadrian                    ahp->ah_mci_cont_status =
391250003Sadrian                                    OS_REG_READ(ah, AR_MCI_CONT_STATUS);
392301091Sadrian                    HALDEBUG(ah, HAL_DEBUG_BT_COEX,
393301091Sadrian                        "(MCI) cont_status=0x%08x\n", ahp->ah_mci_cont_status);
394250003Sadrian                }
395250003Sadrian                OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
396250003Sadrian                    int_rx_msg);
397250003Sadrian                OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, int_raw);
398250003Sadrian
399250003Sadrian                HALDEBUG(ah, HAL_DEBUG_INTERRUPT, "%s:AR_INTR_SYNC_MCI\n", __func__);
400250003Sadrian            }
401250003Sadrian        }
402250003Sadrian#endif
403250003Sadrian    }
404250003Sadrian
405250003Sadrian    if (sync_cause) {
406250003Sadrian        int host1_fatal, host1_perr, radm_cpl_timeout, local_timeout;
407250003Sadrian
408250003Sadrian        host1_fatal = AR_SREV_WASP(ah) ?
409250003Sadrian            AR9340_INTR_SYNC_HOST1_FATAL : AR9300_INTR_SYNC_HOST1_FATAL;
410250003Sadrian        host1_perr = AR_SREV_WASP(ah) ?
411250003Sadrian            AR9340_INTR_SYNC_HOST1_PERR : AR9300_INTR_SYNC_HOST1_PERR;
412250003Sadrian        radm_cpl_timeout = AR_SREV_WASP(ah) ?
413250003Sadrian            0x0 : AR9300_INTR_SYNC_RADM_CPL_TIMEOUT;
414250003Sadrian        local_timeout = AR_SREV_WASP(ah) ?
415250003Sadrian            AR9340_INTR_SYNC_LOCAL_TIMEOUT : AR9300_INTR_SYNC_LOCAL_TIMEOUT;
416250003Sadrian
417250003Sadrian        if (sync_cause & host1_fatal) {
418250003Sadrian#if __PKT_SERIOUS_ERRORS__
419250003Sadrian            HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
420250003Sadrian                "%s: received PCI FATAL interrupt\n", __func__);
421250003Sadrian#endif
422250003Sadrian           *masked |= HAL_INT_FATAL; /* Set FATAL INT flag here;*/
423250003Sadrian        }
424250003Sadrian        if (sync_cause & host1_perr) {
425250003Sadrian#if __PKT_SERIOUS_ERRORS__
426250003Sadrian            HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
427250003Sadrian                "%s: received PCI PERR interrupt\n", __func__);
428250003Sadrian#endif
429250003Sadrian        }
430250003Sadrian
431250003Sadrian        if (sync_cause & radm_cpl_timeout) {
432250003Sadrian            HALDEBUG(ah, HAL_DEBUG_INTERRUPT,
433250003Sadrian                "%s: AR_INTR_SYNC_RADM_CPL_TIMEOUT\n",
434250003Sadrian                __func__);
435250003Sadrian
436250003Sadrian            OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_RC), AR_RC_HOSTIF);
437250003Sadrian            OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_RC), 0);
438250003Sadrian            *masked |= HAL_INT_FATAL;
439250003Sadrian        }
440250003Sadrian        if (sync_cause & local_timeout) {
441250003Sadrian            HALDEBUG(ah, HAL_DEBUG_INTERRUPT,
442250003Sadrian                "%s: AR_INTR_SYNC_LOCAL_TIMEOUT\n",
443250003Sadrian                __func__);
444250003Sadrian        }
445250003Sadrian
446250003Sadrian#ifndef ATH_GPIO_USE_ASYNC_CAUSE
447250003Sadrian        if (sync_cause & AR_INTR_SYNC_MASK_GPIO) {
448250003Sadrian            ahp->ah_gpio_cause = (sync_cause & AR_INTR_SYNC_MASK_GPIO) >>
449250003Sadrian                                 AR_INTR_SYNC_ENABLE_GPIO_S;
450250003Sadrian            *masked |= HAL_INT_GPIO;
451250003Sadrian            HALDEBUG(ah, HAL_DEBUG_INTERRUPT,
452250003Sadrian                "%s: AR_INTR_SYNC_GPIO\n", __func__);
453250003Sadrian        }
454250003Sadrian#endif
455250003Sadrian
456250003Sadrian        OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_CAUSE_CLR), sync_cause);
457250003Sadrian        /* Flush prior write */
458250003Sadrian        (void) OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_CAUSE_CLR));
459250003Sadrian    }
460250003Sadrian
461250003Sadrianend:
462250003Sadrian    if (HAL_INT_MSI == type) {
463250003Sadrian        /*
464250003Sadrian         * WAR for Bug EV#75887
465250003Sadrian         * In normal case, SW read HOST_INTF_PCIE_MSI (0x40A4) and write
466250003Sadrian         * into ah_msi_reg.  Then use value of ah_msi_reg to set bit#25
467250003Sadrian         * when want to enable HW write the cfg_msi_pending.
468250003Sadrian         * Sometimes, driver get MSI interrupt before read 0x40a4 and
469250003Sadrian         * ah_msi_reg is initialization value (0x0).
470250003Sadrian         * We don't know why "MSI interrupt earlier than driver read" now...
471250003Sadrian         */
472250003Sadrian        if (!ahp->ah_msi_reg) {
473250003Sadrian            ahp->ah_msi_reg = OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_PCIE_MSI));
474250003Sadrian        }
475250003Sadrian        if (AR_SREV_POSEIDON(ah)) {
476250003Sadrian            msi_pend_addr_mask = AR_PCIE_MSI_HW_INT_PENDING_ADDR_MSI_64;
477250003Sadrian        } else {
478250003Sadrian            msi_pend_addr_mask = AR_PCIE_MSI_HW_INT_PENDING_ADDR;
479250003Sadrian        }
480250003Sadrian        OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_PCIE_MSI),
481250003Sadrian            ((ahp->ah_msi_reg | AR_PCIE_MSI_ENABLE) & msi_pend_addr_mask));
482250003Sadrian
483250003Sadrian    }
484250003Sadrian
485250003Sadrian    return ret_val;
486250003Sadrian}
487250003Sadrian
488250003SadrianHAL_INT
489250003Sadrianar9300_get_interrupts(struct ath_hal *ah)
490250003Sadrian{
491250003Sadrian    return AH9300(ah)->ah_mask_reg;
492250003Sadrian}
493250003Sadrian
494250003Sadrian/*
495250003Sadrian * Atomically enables NIC interrupts.  Interrupts are passed in
496250003Sadrian * via the enumerated bitmask in ints.
497250003Sadrian */
498250003SadrianHAL_INT
499250003Sadrianar9300_set_interrupts(struct ath_hal *ah, HAL_INT ints, HAL_BOOL nortc)
500250003Sadrian{
501250003Sadrian    struct ath_hal_9300 *ahp = AH9300(ah);
502250003Sadrian    u_int32_t omask = ahp->ah_mask_reg;
503250003Sadrian    u_int32_t mask, mask2, msi_mask = 0;
504250003Sadrian    u_int32_t msi_pend_addr_mask = 0;
505250003Sadrian    u_int32_t sync_en_def = AR9300_INTR_SYNC_DEFAULT;
506250003Sadrian    HAL_CAPABILITIES *p_cap = &AH_PRIVATE(ah)->ah_caps;
507250003Sadrian
508250003Sadrian    HALDEBUG(ah, HAL_DEBUG_INTERRUPT,
509250003Sadrian        "%s: 0x%x => 0x%x\n", __func__, omask, ints);
510250003Sadrian
511250003Sadrian    if (omask & HAL_INT_GLOBAL) {
512250003Sadrian        HALDEBUG(ah, HAL_DEBUG_INTERRUPT, "%s: disable IER\n", __func__);
513250003Sadrian
514250008Sadrian        if (ah->ah_config.ath_hal_enable_msi) {
515250003Sadrian            OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_PRIO_ASYNC_ENABLE), 0);
516250003Sadrian            /* flush write to HW */
517250003Sadrian            (void)OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_PRIO_ASYNC_ENABLE));
518250003Sadrian        }
519250003Sadrian
520250003Sadrian        if (!nortc) {
521250003Sadrian            OS_REG_WRITE(ah, AR_IER, AR_IER_DISABLE);
522250003Sadrian            (void) OS_REG_READ(ah, AR_IER);   /* flush write to HW */
523250003Sadrian        }
524250003Sadrian
525250003Sadrian        OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_ENABLE), 0);
526250003Sadrian        /* flush write to HW */
527250003Sadrian        (void) OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_ENABLE));
528250003Sadrian        OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_ASYNC_ENABLE), 0);
529250003Sadrian        /* flush write to HW */
530250003Sadrian        (void) OS_REG_READ(ah, AR_HOSTIF_REG(ah, AR_INTR_ASYNC_ENABLE));
531250003Sadrian    }
532250003Sadrian
533250003Sadrian    if (!nortc) {
534250003Sadrian        /* reference count for global IER */
535250003Sadrian        if (ints & HAL_INT_GLOBAL) {
536250003Sadrian#ifdef AH_DEBUG
537250003Sadrian            HALDEBUG(ah, HAL_DEBUG_INTERRUPT,
538250003Sadrian                "%s: Request HAL_INT_GLOBAL ENABLED\n", __func__);
539250008Sadrian#if 0
540250003Sadrian            if (OS_ATOMIC_READ(&ahp->ah_ier_ref_count) == 0) {
541250003Sadrian                HALDEBUG(ah, HAL_DEBUG_UNMASKABLE,
542250003Sadrian                    "%s: WARNING: ah_ier_ref_count is 0 "
543250003Sadrian                    "and attempting to enable IER\n",
544250003Sadrian                    __func__);
545250003Sadrian            }
546250003Sadrian#endif
547250008Sadrian#endif
548250008Sadrian#if 0
549250003Sadrian            if (OS_ATOMIC_READ(&ahp->ah_ier_ref_count) > 0) {
550250003Sadrian                OS_ATOMIC_DEC(&ahp->ah_ier_ref_count);
551250003Sadrian            }
552250008Sadrian#endif
553250003Sadrian        } else {
554250003Sadrian            HALDEBUG(ah, HAL_DEBUG_INTERRUPT,
555250003Sadrian                "%s: Request HAL_INT_GLOBAL DISABLED\n", __func__);
556250003Sadrian            OS_ATOMIC_INC(&ahp->ah_ier_ref_count);
557250003Sadrian        }
558250003Sadrian        HALDEBUG(ah, HAL_DEBUG_INTERRUPT,
559250003Sadrian            "%s: ah_ier_ref_count = %d\n", __func__, ahp->ah_ier_ref_count);
560250003Sadrian
561250003Sadrian        mask = ints & HAL_INT_COMMON;
562250003Sadrian        mask2 = 0;
563250003Sadrian        msi_mask = 0;
564250003Sadrian
565250003Sadrian        if (ints & HAL_INT_TX) {
566250003Sadrian            if (ahp->ah_intr_mitigation_tx) {
567250003Sadrian                mask |= AR_IMR_TXMINTR | AR_IMR_TXINTM;
568250003Sadrian            } else if (ahp->ah_tx_ok_interrupt_mask) {
569250003Sadrian                mask |= AR_IMR_TXOK;
570250003Sadrian            }
571250003Sadrian            msi_mask |= AR_INTR_PRIO_TX;
572250003Sadrian            if (ahp->ah_tx_err_interrupt_mask) {
573250003Sadrian                mask |= AR_IMR_TXERR;
574250003Sadrian            }
575250003Sadrian            if (ahp->ah_tx_eol_interrupt_mask) {
576250003Sadrian                mask |= AR_IMR_TXEOL;
577250003Sadrian            }
578250003Sadrian        }
579250003Sadrian        if (ints & HAL_INT_RX) {
580250003Sadrian            mask |= AR_IMR_RXERR | AR_IMR_RXOK_HP;
581250003Sadrian            if (ahp->ah_intr_mitigation_rx) {
582250003Sadrian                mask &= ~(AR_IMR_RXOK_LP);
583250003Sadrian                mask |=  AR_IMR_RXMINTR | AR_IMR_RXINTM;
584250003Sadrian            } else {
585250003Sadrian                mask |= AR_IMR_RXOK_LP;
586250003Sadrian            }
587250003Sadrian            msi_mask |= AR_INTR_PRIO_RXLP | AR_INTR_PRIO_RXHP;
588250008Sadrian            if (! p_cap->halAutoSleepSupport) {
589250003Sadrian                mask |= AR_IMR_GENTMR;
590250003Sadrian            }
591250003Sadrian        }
592250003Sadrian
593250003Sadrian        if (ints & (HAL_INT_BMISC)) {
594250003Sadrian            mask |= AR_IMR_BCNMISC;
595250003Sadrian            if (ints & HAL_INT_TIM) {
596250003Sadrian                mask2 |= AR_IMR_S2_TIM;
597250003Sadrian            }
598250003Sadrian            if (ints & HAL_INT_DTIM) {
599250003Sadrian                mask2 |= AR_IMR_S2_DTIM;
600250003Sadrian            }
601250003Sadrian            if (ints & HAL_INT_DTIMSYNC) {
602250003Sadrian                mask2 |= AR_IMR_S2_DTIMSYNC;
603250003Sadrian            }
604250003Sadrian            if (ints & HAL_INT_CABEND) {
605250003Sadrian                mask2 |= (AR_IMR_S2_CABEND);
606250003Sadrian            }
607250003Sadrian            if (ints & HAL_INT_TSFOOR) {
608250003Sadrian                mask2 |= AR_IMR_S2_TSFOOR;
609250003Sadrian            }
610250003Sadrian        }
611250003Sadrian
612250003Sadrian        if (ints & (HAL_INT_GTT | HAL_INT_CST)) {
613250003Sadrian            mask |= AR_IMR_BCNMISC;
614250003Sadrian            if (ints & HAL_INT_GTT) {
615250003Sadrian                mask2 |= AR_IMR_S2_GTT;
616250003Sadrian            }
617250003Sadrian            if (ints & HAL_INT_CST) {
618250003Sadrian                mask2 |= AR_IMR_S2_CST;
619250003Sadrian            }
620250003Sadrian        }
621250003Sadrian
622250003Sadrian        if (ints & HAL_INT_BBPANIC) {
623250003Sadrian            /* EV92527 - MAC secondary interrupt must enable AR_IMR_BCNMISC */
624250003Sadrian            mask |= AR_IMR_BCNMISC;
625250003Sadrian            mask2 |= AR_IMR_S2_BBPANIC;
626250003Sadrian        }
627250003Sadrian
628250003Sadrian        if (ints & HAL_INT_GENTIMER) {
629250003Sadrian            HALDEBUG(ah, HAL_DEBUG_INTERRUPT,
630250003Sadrian                "%s: enabling gen timer\n", __func__);
631250003Sadrian            mask |= AR_IMR_GENTMR;
632250003Sadrian        }
633250003Sadrian
634250003Sadrian        /* Write the new IMR and store off our SW copy. */
635250003Sadrian        HALDEBUG(ah, HAL_DEBUG_INTERRUPT, "%s: new IMR 0x%x\n", __func__, mask);
636250003Sadrian        OS_REG_WRITE(ah, AR_IMR, mask);
637250003Sadrian        ahp->ah_mask2Reg &= ~(AR_IMR_S2_TIM |
638250003Sadrian                        AR_IMR_S2_DTIM |
639250003Sadrian                        AR_IMR_S2_DTIMSYNC |
640250003Sadrian                        AR_IMR_S2_CABEND |
641250003Sadrian                        AR_IMR_S2_CABTO  |
642250003Sadrian                        AR_IMR_S2_TSFOOR |
643250003Sadrian                        AR_IMR_S2_GTT |
644250003Sadrian                        AR_IMR_S2_CST |
645250003Sadrian                        AR_IMR_S2_BBPANIC);
646250003Sadrian        ahp->ah_mask2Reg |= mask2;
647250003Sadrian        OS_REG_WRITE(ah, AR_IMR_S2, ahp->ah_mask2Reg );
648250003Sadrian        ahp->ah_mask_reg = ints;
649250003Sadrian
650250008Sadrian        if (! p_cap->halAutoSleepSupport) {
651250003Sadrian            if (ints & HAL_INT_TIM_TIMER) {
652250003Sadrian                OS_REG_SET_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
653250003Sadrian            }
654250003Sadrian            else {
655250003Sadrian                OS_REG_CLR_BIT(ah, AR_IMR_S5, AR_IMR_S5_TIM_TIMER);
656250003Sadrian            }
657250003Sadrian        }
658250003Sadrian    }
659250003Sadrian
660250003Sadrian    /* Re-enable interrupts if they were enabled before. */
661250003Sadrian#if HAL_INTR_REFCOUNT_DISABLE
662250003Sadrian    if ((ints & HAL_INT_GLOBAL)) {
663250003Sadrian#else
664250003Sadrian    if ((ints & HAL_INT_GLOBAL) && (OS_ATOMIC_READ(&ahp->ah_ier_ref_count) == 0)) {
665250003Sadrian#endif
666250003Sadrian        HALDEBUG(ah, HAL_DEBUG_INTERRUPT, "%s: enable IER\n", __func__);
667250003Sadrian
668250003Sadrian        if (!nortc) {
669250003Sadrian            OS_REG_WRITE(ah, AR_IER, AR_IER_ENABLE);
670250003Sadrian        }
671250003Sadrian
672250003Sadrian        mask = AR_INTR_MAC_IRQ;
673250003Sadrian#ifdef ATH_GPIO_USE_ASYNC_CAUSE
674250003Sadrian        if (ints & HAL_INT_GPIO) {
675250003Sadrian            if (ahp->ah_gpio_mask) {
676250003Sadrian                mask |= SM(ahp->ah_gpio_mask, AR_INTR_ASYNC_MASK_GPIO);
677250003Sadrian            }
678250003Sadrian        }
679250003Sadrian#endif
680250003Sadrian
681250003Sadrian#if ATH_SUPPORT_MCI
682250003Sadrian        if (ints & HAL_INT_MCI) {
683250003Sadrian            mask |= AR_INTR_ASYNC_MASK_MCI;
684250003Sadrian        }
685250003Sadrian#endif
686250003Sadrian
687250003Sadrian        OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_ASYNC_ENABLE), mask);
688250003Sadrian        OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_ASYNC_MASK), mask);
689250003Sadrian
690250008Sadrian        if (ah->ah_config.ath_hal_enable_msi) {
691250003Sadrian            OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_PRIO_ASYNC_ENABLE),
692250003Sadrian                msi_mask);
693250003Sadrian            OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_PRIO_ASYNC_MASK),
694250003Sadrian                msi_mask);
695250003Sadrian            if (AR_SREV_POSEIDON(ah)) {
696250003Sadrian                msi_pend_addr_mask = AR_PCIE_MSI_HW_INT_PENDING_ADDR_MSI_64;
697250003Sadrian            } else {
698250003Sadrian                msi_pend_addr_mask = AR_PCIE_MSI_HW_INT_PENDING_ADDR;
699250003Sadrian            }
700250003Sadrian            OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_PCIE_MSI),
701250003Sadrian                ((ahp->ah_msi_reg | AR_PCIE_MSI_ENABLE) & msi_pend_addr_mask));
702250003Sadrian        }
703250003Sadrian
704250003Sadrian        /*
705250003Sadrian         * debug - enable to see all synchronous interrupts status
706250003Sadrian         * Enable synchronous GPIO interrupts as well, since some async
707250003Sadrian         * GPIO interrupts don't wake the chip up.
708250003Sadrian         */
709250003Sadrian        mask = 0;
710250003Sadrian#ifndef ATH_GPIO_USE_ASYNC_CAUSE
711250003Sadrian        if (ints & HAL_INT_GPIO) {
712250003Sadrian            mask |= SM(ahp->ah_gpio_mask, AR_INTR_SYNC_MASK_GPIO);
713250003Sadrian        }
714250003Sadrian#endif
715250003Sadrian        if (AR_SREV_POSEIDON(ah)) {
716250003Sadrian            sync_en_def = AR9300_INTR_SYNC_DEF_NO_HOST1_PERR;
717250003Sadrian        }
718250003Sadrian        else if (AR_SREV_WASP(ah)) {
719250003Sadrian            sync_en_def = AR9340_INTR_SYNC_DEFAULT;
720250003Sadrian        }
721250003Sadrian
722250003Sadrian        OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_ENABLE),
723250003Sadrian            (sync_en_def | mask));
724250003Sadrian        OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_INTR_SYNC_MASK),
725250003Sadrian            (sync_en_def | mask));
726250003Sadrian
727250003Sadrian        HALDEBUG(ah,  HAL_DEBUG_INTERRUPT,
728250003Sadrian            "AR_IMR 0x%x IER 0x%x\n",
729250003Sadrian            OS_REG_READ(ah, AR_IMR), OS_REG_READ(ah, AR_IER));
730250003Sadrian    }
731250003Sadrian
732250003Sadrian    return omask;
733250003Sadrian}
734250003Sadrian
735250003Sadrianvoid
736250003Sadrianar9300_set_intr_mitigation_timer(
737250003Sadrian    struct ath_hal* ah,
738250003Sadrian    HAL_INT_MITIGATION reg,
739250003Sadrian    u_int32_t value)
740250003Sadrian{
741250003Sadrian#ifdef AR5416_INT_MITIGATION
742250003Sadrian    switch (reg) {
743250003Sadrian    case HAL_INT_THRESHOLD:
744250003Sadrian        OS_REG_WRITE(ah, AR_MIRT, 0);
745250003Sadrian        break;
746250003Sadrian    case HAL_INT_RX_LASTPKT:
747250003Sadrian        OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_LAST, value);
748250003Sadrian        break;
749250003Sadrian    case HAL_INT_RX_FIRSTPKT:
750250003Sadrian        OS_REG_RMW_FIELD(ah, AR_RIMT, AR_RIMT_FIRST, value);
751250003Sadrian        break;
752250003Sadrian    case HAL_INT_TX_LASTPKT:
753250003Sadrian        OS_REG_RMW_FIELD(ah, AR_TIMT, AR_TIMT_LAST, value);
754250003Sadrian        break;
755250003Sadrian    case HAL_INT_TX_FIRSTPKT:
756250003Sadrian        OS_REG_RMW_FIELD(ah, AR_TIMT, AR_TIMT_FIRST, value);
757250003Sadrian        break;
758250003Sadrian    default:
759250003Sadrian        break;
760250003Sadrian    }
761250003Sadrian#endif
762250003Sadrian}
763250003Sadrian
764250003Sadrianu_int32_t
765250003Sadrianar9300_get_intr_mitigation_timer(struct ath_hal* ah, HAL_INT_MITIGATION reg)
766250003Sadrian{
767250003Sadrian    u_int32_t val = 0;
768250003Sadrian#ifdef AR5416_INT_MITIGATION
769250003Sadrian    switch (reg) {
770250003Sadrian    case HAL_INT_THRESHOLD:
771250003Sadrian        val = OS_REG_READ(ah, AR_MIRT);
772250003Sadrian        break;
773250003Sadrian    case HAL_INT_RX_LASTPKT:
774250003Sadrian        val = OS_REG_READ(ah, AR_RIMT) & 0xFFFF;
775250003Sadrian        break;
776250003Sadrian    case HAL_INT_RX_FIRSTPKT:
777250003Sadrian        val = OS_REG_READ(ah, AR_RIMT) >> 16;
778250003Sadrian        break;
779250003Sadrian    case HAL_INT_TX_LASTPKT:
780250003Sadrian        val = OS_REG_READ(ah, AR_TIMT) & 0xFFFF;
781250003Sadrian        break;
782250003Sadrian    case HAL_INT_TX_FIRSTPKT:
783250003Sadrian        val = OS_REG_READ(ah, AR_TIMT) >> 16;
784250003Sadrian        break;
785250003Sadrian    default:
786250003Sadrian        break;
787250003Sadrian    }
788250003Sadrian#endif
789250003Sadrian    return val;
790250003Sadrian}
791