a_uint32_t ar5416NumTxPending(struct ath_hal *ah, a_uint32_t q) { a_uint32_t npend; HALASSERT(q < AH_PRIVATE(ah)->ah_caps.halTotalQueues); HALASSERT(AH5416(ah)->ah_txq[q].tqi_type != HAL_TX_QUEUE_INACTIVE); npend = OS_REG_READ(ah, AR_QSTS(q)) & AR_Q_STS_PEND_FR_CNT; if (npend == 0) { /* * Pending frame count (PFC) can momentarily go to zero * while TXE remains asserted. In other words a PFC of * zero is not sufficient to say that the queue has stopped. */ if (OS_REG_READ(ah, AR_Q_TXE) & (1 << q)) npend = 1; } #ifdef DEBUG if (npend && (AH5416(ah)->ah_txq[q].tqi_type == HAL_TX_QUEUE_CAB)) { if (OS_REG_READ(ah, AR_Q_RDYTIMESHDN) & (1 << q)) { isrPrintf("RTSD on CAB queue\n"); /* Clear the ReadyTime shutdown status bits */ OS_REG_WRITE(ah, AR_Q_RDYTIMESHDN, 1 << q); } } #endif return npend; }
HAL_INT_TYPE ar5212GetInterrupts(WLAN_DEV_INFO *pDev, HAL_INT_TYPE *pUnmaskedValue, A_UINT32 *pDescQueueBitMask) { A_UINT32 isr, isrS2 = 0, maskedIsr; HAL_INT_TYPE ints = 0, maskedInts = 0; *pDescQueueBitMask = 0; isr = readPlatformReg(pDev, MAC_ISR); if (isr == 0xffffffff) { return HAL_INT_NOCARD; } maskedIsr = isr & pDev->MaskReg; ASSERT(maskedIsr); /* Mask out non-common interrupts. These will be added in below. */ maskedInts = maskedIsr & HAL_INT_COMMON; if ( #ifdef PCI_INTERFACE (maskedIsr & MAC_ISR_HIUERR) || #endif (maskedIsr & MAC_ISR_BCNMISC)) { isrS2 = readPlatformReg(pDev, MAC_ISR_S2); } #ifdef PCI_INTERFACE if (maskedIsr & MAC_ISR_HIUERR) { if (isrS2 & MAC_ISR_S2_MCABT) { isrPrintf("hwGetInterrupts: Bus Master Cycle Abort Error!\n"); } if (isrS2 & MAC_ISR_S2_SSERR) { isrPrintf("hwGetInterrupts: Bus Signalled System Error!\n"); } if (isrS2 & MAC_ISR_S2_DPERR) { isrPrintf("hwGetInterrupts: Bus Parity Error!\n"); } maskedInts |= HAL_INT_FATAL; } #endif if (maskedIsr & (MAC_ISR_RXOK | MAC_ISR_RXERR)) { maskedInts |= HAL_INT_RX; } if (maskedIsr & (MAC_ISR_TXOK | MAC_ISR_TXERR)) { maskedInts |= HAL_INT_TX; } if (maskedIsr & MAC_ISR_TXDESC) { maskedInts |= HAL_INT_TXDESC; } if ((maskedIsr & MAC_ISR_BCNMISC) && (isrS2 & MAC_ISR_S2_DTIM)) { maskedInts |= HAL_INT_DTIM; } if (maskedIsr & MAC_ISR_RXCHIRP) { maskedInts |= HAL_INT_RXCHIRP; } /* * Receive Overuns happen quite frequently in Venice/Hainan based MAC * when compression and fastframes are enabled as reported in * bug 9208. Since the bug report also concludes that RXORN is * not fatal anymore, software now uses it as information and * carries on with its normal operation without doing a chip reset */ #if 0 /* Receive overrun is usually non-fatal on Oahu/Spirit. * * BUT early silicon had a bug which causes the rx to fail and the chip * must be reset. * * AND even AR531X v3.1 and AR5211 v4.2 silicon seems to have a problem * with RXORN which hangs the receive path and requires a chip reset * to proceed (see bug 3996). So for now, we force a hardware reset in * all cases. */ if (isr & MAC_ISR_RXORN) { isrPrintf("hwGetInterrupts: Receive FIFO Overrun Error!\n"); maskedInts |= HAL_INT_FATAL; } #endif /* * Now we take care of the unmasked interrupts. We need to return certain * unmasked interrupts or we'll "lose" them after reading the ISR register. */ ints = isr & HAL_INT_COMMON; if (isr & (MAC_ISR_RXOK | MAC_ISR_RXERR)) { ints |= HAL_INT_RX; } if (isr & (MAC_ISR_TXOK | MAC_ISR_TXERR)) { ints |= HAL_INT_TX; } if (isr & MAC_ISR_TXDESC) { ints |= HAL_INT_TXDESC; *pDescQueueBitMask = A_REG_RD_FIELD(pDev, MAC_ISR_S0, QCU_TXDESC); /* * Disable the interrupt caused by the queue by writing ones * to the secondary ISR. This avoids the race condition * mentioned below. */ A_REG_WR_FIELD(pDev, MAC_ISR_S0, QCU_TXDESC, *pDescQueueBitMask); /* * This avoids a race condition where a new TXDESC interrupt * could come in between reading the ISR and clearing the interrupt * via the primary ISR. We therefore clear the interrupt via * the secondary, which avoids this race. */ isr = isr & ~MAC_ISR_TXDESC; } /* * Clear the interrupts we've read by writing back ones in these locations * to the primary ISR, TXDESC excepted (see above). */ writePlatformReg(pDev, MAC_ISR, isr); /* Flush the write to the Register */ (void)readPlatformReg(pDev, MAC_ISR); #if AR_PB32 sysPciIntrAck(); #endif /* Return the unmasked value. */ *pUnmaskedValue = ints; /* Return the masked value. */ return maskedInts; }