/* * * This is the DMA RX interrupt handler function * * It gets the interrupt status from the hardware, acknowledges it, and if any * error happens, it resets the hardware. Otherwise, if a completion interrupt * presents, then it calls the callback function. * * @param Callback is a pointer to RX channel of the DMA engine. * * @return None. * * @note None. * ******************************************************************************/ static void RxIntrHandler(void *Callback) { XAxiDma *AxiDmaPtr = (XAxiDma *) Callback; XAxiDma_BdRing *RxRingPtr = XAxiDma_GetRxIndexRing(AxiDmaPtr, 0); u32 IrqStatus; int TimeOut; /* Read pending interrupts */ IrqStatus = XAxiDma_BdRingGetIrq(RxRingPtr); /* Acknowledge pending interrupts */ XAxiDma_BdRingAckIrq(RxRingPtr, IrqStatus); /* * If no interrupt is asserted, we do not do anything */ if (!(IrqStatus & XAXIDMA_IRQ_ALL_MASK)) { return; } /* * If error interrupt is asserted, raise error flag, reset the * hardware to recover from the error, and return with no further * processing. */ if ((IrqStatus & XAXIDMA_IRQ_ERROR_MASK)) { Error = 1; /* Reset could fail and hang * NEED a way to handle this or do not call it?? */ XAxiDma_Reset(&AxiDma); TimeOut = RESET_TIMEOUT_COUNTER; while (TimeOut) { if(XAxiDma_ResetIsDone(&AxiDma)) { break; } TimeOut -= 1; } return; } /* * If completion interrupt is asserted, call RX call back function * to handle the processed BDs and then raise the according flag. */ if ((IrqStatus & (XAXIDMA_IRQ_DELAY_MASK | XAXIDMA_IRQ_IOC_MASK))) { RxCallBack(AxiDmaPtr); } }
/* * * This is the DMA TX Interrupt handler function. * * It gets the interrupt status from the hardware, acknowledges it, and if any * error happens, it resets the hardware. Otherwise, if a completion interrupt * presents, then it calls the callback function. * * @param Callback is a pointer to TX channel of the DMA engine. * * @return None. * * @note None. * ******************************************************************************/ static void TxIntrHandler(void *Callback) { XAxiDma_BdRing *TxRingPtr = (XAxiDma_BdRing *) Callback; u32 IrqStatus; int TimeOut; /* Read pending interrupts */ IrqStatus = XAxiDma_BdRingGetIrq(TxRingPtr); /* Acknowledge pending interrupts */ XAxiDma_BdRingAckIrq(TxRingPtr, IrqStatus); /* If no interrupt is asserted, we do not do anything */ if (!(IrqStatus & XAXIDMA_IRQ_ALL_MASK)) { return; } /* * If error interrupt is asserted, raise error flag, reset the * hardware to recover from the error, and return with no further * processing. */ if ((IrqStatus & XAXIDMA_IRQ_ERROR_MASK)) { XAxiDma_BdRingDumpRegs(TxRingPtr); Error = 1; /* * Reset should never fail for transmit channel */ XAxiDma_Reset(&AxiDma); TimeOut = RESET_TIMEOUT_COUNTER; while (TimeOut) { if (XAxiDma_ResetIsDone(&AxiDma)) { break; } TimeOut -= 1; } return; } /* * If Transmit done interrupt is asserted, call TX call back function * to handle the processed BDs and raise the according flag */ if ((IrqStatus & (XAXIDMA_IRQ_DELAY_MASK | XAXIDMA_IRQ_IOC_MASK))) { TxCallBack(TxRingPtr); } }
void RxIntrHandler(void *Callback){ XAxiDma_BdRing *RxRingPtr = (XAxiDma_BdRing *) Callback; u32 IrqStatus; XIntc_Stop(Intc_ptr); IrqStatus = XAxiDma_BdRingGetIrq(RxRingPtr); XAxiDma_BdRingAckIrq(RxRingPtr, IrqStatus); if ((IrqStatus & (XAXIDMA_IRQ_DELAY_MASK | XAXIDMA_IRQ_IOC_MASK))) { wlan_poll_eth(); } XIntc_Start(Intc_ptr, XIN_REAL_MODE); return; }