/** * \brief GMAC Interrupt handler * \param pGmacd Pointer to GMAC Driver instance. */ void GMACD_Handler(sGmacd *pGmacd ) { Gmac *pHw = pGmacd->pHw; uint32_t isr; uint32_t rsr; /* Interrupt Status Register is cleared on read */ while ((isr = GMAC_GetItStatus(pHw)) != 0) { /* RX packet */ if (isr & GMAC_INT_RX_BITS) { /* Clear status */ rsr = GMAC_GetRxStatus(pHw); GMAC_ClearRxStatus(pHw, rsr); /* Invoke callback */ if (pGmacd->fRxCb) pGmacd->fRxCb(rsr); } /* TX error */ if (isr & GMAC_INT_TX_ERR_BITS) { GMACD_TxErrorHandler(pGmacd); break; } /* TX packet */ if (isr & GMAC_IER_TCOMP) GMACD_TxCompleteHandler(pGmacd); if (isr & GMAC_IER_HRESP) { TRACE_ERROR("HRESP\n\r"); } } }
/** * \brief GMAC Interrupt handler * \param pGmacd Pointer to GMAC Driver instance. */ void GMACD_Handler(sGmacd *pGmacd, gmacQueList_t queIdx) { Gmac *pHw = pGmacd->pHw; uint32_t isr; uint32_t rsr; /* Interrupt Status Register is cleared on read */ while ( (isr = GMAC_GetItStatus(pHw, queIdx)) !=0) { /* Sync Frame Received - PTP */ if(0u != (isr & GMAC_ISR_SFR)) { rsr = GMAC_ISR_SFR; memory_barrier(); /* Invoke callbacks */ if (pGmacd->queueList[queIdx].fRxCb) { pGmacd->queueList[queIdx].fRxCb(rsr); } else { } } else { } /* Peer Delay Request Frame Received - PTP */ if (0u != (isr & GMAC_ISR_PDRQFR) ) { rsr = GMAC_ISR_PDRQFR; memory_barrier(); /* Invoke callbacks */ if (pGmacd->queueList[queIdx].fRxCb) { pGmacd->queueList[queIdx].fRxCb(rsr); } else { } } else { } /* Peer Delay Response Frame Received - PTP */ if (0u != (isr & GMAC_ISR_PDRSFR) ) { rsr = GMAC_ISR_PDRSFR; memory_barrier(); /* Invoke callbacks */ if (pGmacd->queueList[queIdx].fRxCb) { pGmacd->queueList[queIdx].fRxCb(rsr); } else { } } else { } if( 0u != (isr & GMAC_ISR_TSU)) { /* Invoke call back with flag set to TSU comparison interrupt */ rsr = GMAC_ISR_TSU; memory_barrier(); /* Invoke callbacks */ if (pGmacd->queueList[queIdx].fRxCb) { pGmacd->queueList[queIdx].fRxCb(rsr); } else { } } else { } /* RX packet */ if (isr & GMAC_INT_RX_BITS) { /* Clear status */ rsr = GMAC_GetRxStatus(pHw); GMAC_ClearRxStatus(pHw, rsr); /* Invoke callback */ if (pGmacd->queueList[queIdx].fRxCb) pGmacd->queueList[queIdx].fRxCb(rsr); } /* TX error */ if (isr & GMAC_INT_TX_ERR_BITS) { GMACD_TxErrorHandler(pGmacd, queIdx); break; } #ifndef PTP_1588_TX_DISABLE /* Transmit of SYNC / PDELAY_REQ / PDELAY_RSP */ if(0u != (isr & isrMasks[gPtpMsgTxQue[ptpTxQueReadIdx]])) { /* Invoke callback */ /* Check if it is possible for multiple messages to be triggered within a single isr. If so, a loop may be needed to validate the top of the queue with the actual interrupt that has been triggered */ /* while(0u != (isr & (GMAC_IMR_SFT | GMAC_IMR_PDRQFT | GMAC_IMR_PDRSFT))) { */ if (pGmacd->queueList[queIdx].fTxPtpEvtCb) { switch (gPtpMsgTxQue[ptpTxQueReadIdx]) { case SYNC_MSG_TYPE: pGmacd->queueList[queIdx].fTxPtpEvtCb (gPtpMsgTxQue[ptpTxQueReadIdx], GMAC_GetTxEvtFrameSec(pHw), GMAC_GetTxEvtFrameNsec(pHw), gPtpMsgTxSeqId[ptpTxQueReadIdx]); isr &= GMAC_IMR_SFT; break; case PDELAY_REQ_TYPE: pGmacd->queueList[queIdx].fTxPtpEvtCb (gPtpMsgTxQue[ptpTxQueReadIdx], GMAC_GetTxPeerEvtFrameSec(pHw), GMAC_GetTxPeerEvtFrameNsec(pHw), gPtpMsgTxSeqId[ptpTxQueReadIdx]); isr &= GMAC_IMR_PDRQFT; break; case PDELAY_RESP_TYPE: pGmacd->queueList[queIdx].fTxPtpEvtCb (gPtpMsgTxQue[ptpTxQueReadIdx], GMAC_GetTxPeerEvtFrameSec(pHw), GMAC_GetTxPeerEvtFrameNsec(pHw), gPtpMsgTxSeqId[ptpTxQueReadIdx]); isr &= GMAC_IMR_PDRSFT; break; default: /* Only for Peer messages & sync messages */ break; }; } else { } ptpTxQueReadIdx++; ptpTxQueReadIdx &= (EFRS_BUFFER_LEN-1); } else { /* if(0u != (isr & isrMasks[gPtpMsgTxQue[ptpTxQueReadIdx]])) */ } #endif /* #ifndef PTP_1588_TX_DISABLE */ /* TX packet */ if (isr & GMAC_IER_TCOMP) GMACD_TxCompleteHandler(pGmacd, queIdx); if (isr & GMAC_IER_HRESP) { TRACE_ERROR("HRESP\n\r"); } } }
/** * \brief GMAC Interrupt handler * \param pGmacd Pointer to GMAC Driver instance. */ void GMACD_Handler(sGmacd *pGmacd ) { Gmac *pHw = pGmacd->pHw; sGmacTxDescriptor *pTxTd; fGmacdTransferCallback *pTxCb = NULL; uint32_t isr; uint32_t rsr; uint32_t tsr; uint32_t rxStatusFlag; uint32_t txStatusFlag; isr = GMAC_GetItStatus(pHw); rsr = GMAC_GetRxStatus(pHw); tsr = GMAC_GetTxStatus(pHw); isr &= ~(GMAC_GetItMask(pHw)| 0xF8030300); /* RX packet */ if ((isr & GMAC_ISR_RCOMP) || (rsr & GMAC_RSR_REC)) { asm("nop"); rxStatusFlag = GMAC_RSR_REC; /* Frame received */ /* Check OVR */ if (rsr & GMAC_RSR_RXOVR) { rxStatusFlag |= GMAC_RSR_RXOVR; } /* Check BNA */ if (rsr & GMAC_RSR_BNA) { rxStatusFlag |= GMAC_RSR_BNA; } /* Check HNO */ if (rsr & GMAC_RSR_HNO) { rxStatusFlag |= GMAC_RSR_HNO; } /* Clear status */ GMAC_ClearRxStatus(pHw, rxStatusFlag); /* Invoke callbacks */ if (pGmacd->fRxCb) { pGmacd->fRxCb(rxStatusFlag); } } /* TX packet */ if ((isr & GMAC_ISR_TCOMP) || (tsr & GMAC_TSR_TXCOMP)) { asm("nop"); txStatusFlag = GMAC_TSR_TXCOMP; /* A frame transmitted Check RLE */ if (tsr & GMAC_TSR_RLE) { /* Status RLE & Number of discarded buffers */ txStatusFlag = GMAC_TSR_RLE | GCIRC_CNT(pGmacd->wTxHead, pGmacd->wTxTail, pGmacd->wTxListSize); pTxCb = &pGmacd->fTxCbList[pGmacd->wTxTail]; GMACD_ResetTx(pGmacd); TRACE_INFO("Tx RLE!!\n\r"); GMAC_TransmitEnable(pHw, 1); } /* Check COL */ if (tsr & GMAC_TSR_COL) { txStatusFlag |= GMAC_TSR_COL; } /* Check TFC */ if (tsr & GMAC_TSR_TFC) { txStatusFlag |= GMAC_TSR_TFC; } /* Check UND */ if (tsr & GMAC_TSR_UND) { txStatusFlag |= GMAC_TSR_UND; } /* Check HRESP */ if (tsr & GMAC_TSR_HRESP) { txStatusFlag |= GMAC_TSR_HRESP; } /* Check LCO */ if (tsr & GMAC_TSR_LCO) { txStatusFlag |= GMAC_TSR_LCO; } /* Clear status */ GMAC_ClearTxStatus(pHw, txStatusFlag); if (!GCIRC_EMPTY(pGmacd->wTxHead, pGmacd->wTxTail)) { /* Check the buffers */ do { pTxTd = &pGmacd->pTxD[pGmacd->wTxTail]; pTxCb = &pGmacd->fTxCbList[pGmacd->wTxTail]; /* Exit if buffer has not been sent yet */ if ((pTxTd->status.val & (uint32_t)GMAC_TX_USED_BIT) == 0) { break; } /* Notify upper layer that a packet has been sent */ if (*pTxCb) { (*pTxCb)(txStatusFlag); } GCIRC_INC( pGmacd->wTxTail, pGmacd->wTxListSize ); } while (GCIRC_CNT(pGmacd->wTxHead, pGmacd->wTxTail, pGmacd->wTxListSize)); } if (tsr & GMAC_TSR_RLE) { /* Notify upper layer RLE */ if (*pTxCb) { (*pTxCb)(txStatusFlag); } } /* If a wakeup has been scheduled, notify upper layer that it can send other packets, send will be successfull. */ if((GCIRC_SPACE(pGmacd->wTxHead, pGmacd->wTxTail, pGmacd->wTxListSize) >= pGmacd->bWakeupThreshold) && pGmacd->fWakupCb) { pGmacd->fWakupCb(); } } /* PAUSE Frame */ if (isr & GMAC_ISR_PFNZ) TRACE_INFO("Pause!\n\r"); if (isr & GMAC_ISR_PTZ) TRACE_INFO("Pause TO!\n\r"); }