Beispiel #1
0
/**
 * Return current load of TX.
 * \param pGmacd   Pointer to GMAC Driver instance.
 */
uint32_t GMACD_TxLoad(sGmacd *pGmacd)
{
    uint16_t head = pGmacd->wTxHead;
    uint16_t tail = pGmacd->wTxTail;
    return GCIRC_CNT(head, tail, pGmacd->wTxListSize);
}
Beispiel #2
0
/**
 * Return current load of TX.
 * \param pGmacd   Pointer to GMAC Driver instance.
 */
uint32_t GMACD_TxLoad(sGmacd *pGmacd, gmacQueList_t queIdx)
{
    uint16_t head = pGmacd->queueList[queIdx].wTxHead;
    uint16_t tail = pGmacd->queueList[queIdx].wTxTail;
    return GCIRC_CNT(head, tail, pGmacd->queueList[queIdx].wTxListSize);
}
Beispiel #3
0
/**
 *  \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");
}