ixethaccend.c

来自「ixEthAccEnd END network interface driver」· C语言 代码 · 共 1,681 行 · 第 1/4 页

C
1,681
字号
    /* Upper layer must provide a valid buffer. */    if ((pMblk->mBlkHdr.mLen < len) || (!(pMblk->mBlkHdr.mFlags & M_EXT)))        {        IXP_DRV_LOG (IXP_DRV_DEBUG_POLL_RX, "PRX bad mblk\n", 1, 2, 3, 4, 5, 6);        return(EAGAIN);        }    END_ERR_ADD (&pDrvCtrl->end, MIB2_IN_UCAST, +1);    bcopy (pPacket, pMblk->m_data, len);    pMblk->mBlkHdr.mFlags |= M_PKTHDR;  /* set the packet header */    pMblk->mBlkHdr.mLen = len;      /* set the data len */    pMblk->mBlkPktHdr.len = len;    /* set the total len */    IXP_DRV_LOG (IXP_DRV_DEBUG_POLL_RX, "ixEthAccEndPollRcv OK\n", 1, 2, 3, 4, 5, 6);    IXP_DRV_LOG (IXP_DRV_DEBUG_POLL_RX, "ixEthAccEndPollRcv OK\n", 1, 2, 3, 4, 5, 6);    return(OK);#else    return(ERROR);#endif /* IXE_ETHACC_POLL_ENABLE */}/********************************************************************************* ixEthAccEndPollSend - routine to send a packet in polled mode.** This routine is called by a user to try and send a packet on the* device.** RETURNS: OK upon success.  EAGAIN if device is busy.*/LOCAL STATUS ixEthAccEndPollSend(END_DEVICE*     pDrvCtrl,   /* device to be polled */M_BLK_ID    pMblk   /* packet to send */){#ifdef IXE_ETHACC_POLL_ENABLE    int         len;    u_short stat;    IXP_DRV_LOG (IXP_DRV_DEBUG_POLL_TX, "ixEthAccEndPollSend\n", 1, 2, 3, 4, 5, 6);    stat = ixEthAccEndStatusRead (pDrvCtrl);    /* dummy code */    if ((stat & IxEthAccEnd_TINT) == 0)        return((STATUS) EAGAIN);    len = max (ETHERSMALL, pMblk->m_len);    /* Bump the statistic counter. */    END_ERR_ADD (&pDrvCtrl->end, MIB2_OUT_UCAST, +1);    /* Free the data if it was accepted by device */    netMblkClFree (pMblk);    IXP_DRV_LOG (IXP_DRV_DEBUG_POLL_TX, "leaving ixEthAccEndPollSend\n", 1, 2, 3, 4, 5, 6);    return(OK);#else    return(ERROR);#endif  /* IXE_ETHACC_POLL_ENABLE */}/******************************************************************************* ixEthAccEndMCastAdd - add a multicast address for the device** This routine adds a multicast address to whatever the driver* is already listening for.  It then resets the address filter.** RETURNS: OK or ERROR.*/LOCAL STATUS ixEthAccEndMCastAdd(END_DEVICE *pDrvCtrl,       /* device pointer */char* pAddress  /* new address to add */){    int error;    if ((error = etherMultiAdd (&pDrvCtrl->end.multiList,                                pAddress)) == ENETRESET)    ixEthAccEndConfig (pDrvCtrl);    return(OK);}/******************************************************************************* ixEthAccEndMCastDel - delete a multicast address for the device** This routine removes a multicast address from whatever the driver* is listening for.  It then resets the address filter.** RETURNS: OK or ERROR.*/LOCAL STATUS ixEthAccEndMCastDel(END_DEVICE *pDrvCtrl,       /* device pointer */char* pAddress      /* address to be deleted */){    int error;    if ((error = etherMultiDel (&pDrvCtrl->end.multiList,                                (char *)pAddress)) == ENETRESET)    ixEthAccEndConfig (pDrvCtrl);    return(OK);}/******************************************************************************* ixEthAccEndMCastGet - get the multicast address list for the device** This routine gets the multicast list of whatever the driver* is already listening for.** RETURNS: OK or ERROR.*/LOCAL STATUS ixEthAccEndMCastGet(END_DEVICE *pDrvCtrl,           /* device pointer */MULTI_TABLE* pTable     /* address table to be filled in */){    return(etherMultiGet (&pDrvCtrl->end.multiList, pTable));}/********************************************************************************* ixEthAccEndStop - stop the device** This function calls BSP functions to disconnect interrupts and stop* the device from operating in interrupt mode.** RETURNS: OK or ERROR.*/LOCAL STATUS ixEthAccEndStop(END_DEVICE *pDrvCtrl    /* device to be stopped */){    STATUS result = OK;    ixEthAccShutdown = TRUE;    /* If that port doesn't exist then just return */    if ( ixEthAccPhyAddresses[ pDrvCtrl->unit ] == 0xffffffff )        return OK;#ifdef PORT_FLUSH_EXISTS    /* Flush all buffers back to stack */    ixEthAccTxPortFlush ( pDrvCtrl->unit );    ixEthAccRxPortFlush ( pDrvCtrl->unit );    /* Wait aprox 1/2 sec for flush */    taskDelay(sysClkRateGet()/2);#endif /* PORT_FLUSH_EXISTS */    /* Shut down the port */    ixEthAccPortDisable ( pDrvCtrl->unit );    /* Wait aprox 1/2 sec for spin down */    taskDelay(sysClkRateGet()/2);    END_FLAGS_CLR (&pDrvCtrl->end, (IFF_UP | IFF_RUNNING));    SYS_INT_DISCONNECT (pDrvCtrl, IxEthAccEndInt, (int)pDrvCtrl, &result);    if (result == ERROR)        {        IXP_DRV_LOG (IXP_DRV_DEBUG_ERROR, "ixEthAccEndStop: Could not disconnect interrupt!\n",                 1, 2, 3, 4, 5, 6);        }    return(result);}/******************************************************************************** ixEthAccEndUnload - unload a driver from the system** This function first brings down the device, and then frees any* stuff that was allocated by the driver in the load function.** RETURNS: OK or ERROR.*/LOCAL STATUS ixEthAccEndUnload(END_DEVICE* pDrvCtrl    /* device to be unloaded */){    END_OBJECT_UNLOAD (&pDrvCtrl->end);    return(OK);}/********************************************************************************* ixEthAccEndPollStart - start polled mode operations** RETURNS: OK or ERROR.*/LOCAL STATUS ixEthAccEndPollStart(END_DEVICE * pDrvCtrl   /* device to be polled */){    int         oldLevel;    oldLevel = intLock ();          /* disable ints during update */    pDrvCtrl->flags |= IxEthAccEnd_POLLING;    intUnlock (oldLevel);   /* now IxEthAccEndInt won't get confused */    IXP_DRV_LOG (IXP_DRV_DEBUG_POLL, "STARTED\n", 1, 2, 3, 4, 5, 6);    ixEthAccEndConfig (pDrvCtrl);   /* reconfigure device */    return(OK);}/********************************************************************************* ixEthAccEndPollStop - stop polled mode operations** This function terminates polled mode operation.  The device returns to* interrupt mode.** The device interrupts are enabled, the current mode flag is switched* to indicate interrupt mode and the device is then reconfigured for* interrupt operation.** RETURNS: OK or ERROR.*/LOCAL STATUS ixEthAccEndPollStop(END_DEVICE * pDrvCtrl   /* device to be polled */){    int         oldLevel;    oldLevel = intLock ();  /* disable ints during register updates */    pDrvCtrl->flags &= ~IxEthAccEnd_POLLING;    intUnlock (oldLevel);    ixEthAccEndConfig (pDrvCtrl);    IXP_DRV_LOG (IXP_DRV_DEBUG_POLL, "STOPPED\n", 1, 2, 3, 4, 5, 6);    return(OK);}/********************************************************************************* ixEthAccEndReset - reset device** RETURNS: N/A.*/LOCAL void ixEthAccEndReset(END_DEVICE *pDrvCtrl){}#ifdef IXE_ETHACC_POLL_ENABLE/********************************************************************************* ixEthAccEndStatusRead - get current device state/status** RETURNS: status bits.*/LOCAL UINT ixEthAccEndStatusRead(END_DEVICE *pDrvCtrl){    return(0);}#endif /* IXE_ETHACC_POLL_ENABLE */LOCAL void ixEthAccEndTxDoneCallback(UINT32 callbackTag, M_BLK *pMblk){#ifdef	IXP_DRV_DEBUG    END_DEVICE *pDrvCtrl = (END_DEVICE *)callbackTag;    M_BLK *mbufPtr;#endif    /* If we are shutting down then just dump the buffer */    if ( ixEthAccShutdown )        return;#ifdef	IXP_DRV_DEBUG    for ( mbufPtr = pMblk; mbufPtr; mbufPtr = mbufPtr->m_next )        {        IXP_DRV_LOG (IXP_DRV_DEBUG_INT, "Tx ixe[%d] Callback Hdr: 0x%08X Buff: 0x%08X Size: 0x%08X\n"                 , pDrvCtrl->unit                 , (int)mbufPtr                 , (int)mbufPtr->m_data                 , mbufPtr->m_pkthdr.len                 , 5, 6);        }#endif /* IXP_DRV_DEBUG */    /* Free the buffer back to the pool */    netMblkClChainFree (pMblk);}LOCAL void ixEthAccEndRxCallback(UINT32 callbackTag, M_BLK *pMblk){    int         oldLevel;    IX_ETH_ACC_REC_BUF *pBufList;    END_DEVICE *pDrvCtrl = (END_DEVICE *)callbackTag;    /* If we are shutting down then just dump the buffer */    if ( ixEthAccShutdown )        return;    /* Expunge buffer header from cache. The data will be done later */#ifdef IXE_CACHED_BUFFERS_ENABLE    IXP425_END_CACHE_INVALIDATE (pMblk, sizeof(M_BLK));#endif /* IXE_CACHED_BUFFERS_ENABLE */    /* Pass buffer off to Task level processing */    if ( pDrvCtrl->rxHandling == 0 )        {        oldLevel = intLock ();  /* protect IxEthAccEndInt */        /* Point to the top of the list */        pDrvCtrl->recNext = pDrvCtrl->recBufList;        pBufList = pDrvCtrl->recNext;        /* set the buffer */        pBufList->ix_rec_buf = pMblk;        /* Bump the next available pointer */        pDrvCtrl->recNext = pBufList->ix_rec_next;        /* Say we're handling */        pDrvCtrl->rxHandling = 1;                intUnlock (oldLevel);        netJobAdd ((FUNCPTR)ixEthAccEndHandleRcvInt, (int)pDrvCtrl,                   (int)pBufList,0,0,0);         }    else        {        oldLevel = intLock ();  /* protect IxEthAccEndInt */        /* Point to the next block */        pBufList = pDrvCtrl->recNext;        /* Check for list overflow */        if (pBufList->ix_rec_buf)            {            intUnlock (oldLevel);            /* Drop the packet */            netMblkFree (pDrvCtrl->end.pNetPool, pMblk);#if 1            logMsg ("ixe[%d] Rx Callback: Buffer: 0x%08X - rxHandling over-run. Packet Dropped\n"                    ,pDrvCtrl->unit, (int)pMblk, 3, 4, 5, 6);#endif            }        else            {            pDrvCtrl->rxHandling++;            /* Instrumentation */            if ( pDrvCtrl->rxHandling > pDrvCtrl->rxMaxHandling )                pDrvCtrl->rxMaxHandling = pDrvCtrl->rxHandling;            /* Don't do the netJobAdd - Do a low overhead buffer add */            pBufList->ix_rec_buf = pMblk;            pDrvCtrl->recNext = pBufList->ix_rec_next;            intUnlock (oldLevel);            IXP_DRV_LOG (IXP_DRV_DEBUG_RX_HANDLING                     , "Rx Callback Unit[%d] : Buffer: 0x%08X %4d %4d Bytes rxHandling: %d\n"                     , pDrvCtrl->unit, (int)pMblk, pMblk->m_pkthdr.len                     , pMblk->m_len, pDrvCtrl->rxHandling, 6);            }        }}   #endif /* INCLUDE_IXETHACCEND */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?