⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ixethaccend.c

📁 INTEL IXP425的VXWORKS BSP
💻 C
📖 第 1 页 / 共 5 页
字号:
* 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;    /* If that port doesn't exist then just return */    if ( ixEthAccPhyAddresses[ pDrvCtrl->unit ] == 0xffffffff )        return OK;    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);    }    /* register callbacks which discard the traffic */    result = ixEthAccPortTxDoneCallbackRegister( pDrvCtrl->unit,                                                 ixEthAccEndTxDoneCallbackShutdown,                                                 (UINT32) pDrvCtrl);    if ( result != IX_ETH_ACC_SUCCESS)        {        IXP_DRV_LOG((IXP_DRV_DEBUG_ERROR | IXP_DRV_DEBUG_LOAD),		    "Error:Registering IxEthAcc Tx Callbacks for shutdown Port[%d]\n",		    pDrvCtrl->unit,2,3,4,5,6);        return(ERROR);        }    result = ixEthAccPortRxCallbackRegister( pDrvCtrl->unit,                                             ixEthAccEndRxCallbackShutdown,                                             (UINT32) pDrvCtrl);        if ( result != IX_ETH_ACC_SUCCESS)        {        IXP_DRV_LOG((IXP_DRV_DEBUG_ERROR | IXP_DRV_DEBUG_LOAD),		    "Error:Registering IxEthAcc Rx Callbacks for shutdown Port[%d]\n",		    pDrvCtrl->unit,2,3,4,5,6);        return(ERROR);        }    /* now, shutdown the hw level */    result = ixdp425EthLibStop(pDrvCtrl->unit);    if ( result != IX_SUCCESS)    {	IXP_DRV_LOG((IXP_DRV_DEBUG_ERROR | IXP_DRV_DEBUG_LOAD),		    "ixdp425EthLibStop Failed Port[%d]\n",		    pDrvCtrl->unit,2,3,4,5,6);	return ERROR;    }        /* Wait aprox 1/2 sec for spin down */    taskDelay(sysClkRateGet()/2);    END_FLAGS_CLR (&pDrvCtrl->end, (IFF_UP | IFF_RUNNING));    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 */){    /* now, shutdown the hw level */    IX_STATUS result = ixdp425EthLibUnload(pDrvCtrl->unit);    if ( result != IX_SUCCESS)    {	logMsg("ixdp425EthLibUnload Failed Port %d\n",	       pDrvCtrl->unit,2,3,4,5,6);	return ERROR;    }        END_OBJECT_UNLOAD (&pDrvCtrl->end);    /* TODO - Free any shared DMA memory */    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){    /* TODO - reset the controller */}#ifdef IXE_ETHACC_POLL_ENABLE/********************************************************************************* ixEthAccEndStatusRead - get current device state/status** RETURNS: status bits.*/LOCAL UINT ixEthAccEndStatusRead(END_DEVICE *pDrvCtrl){    /* TODO - read and return status bits/register */    return(0);}#endif /* IXE_ETHACC_POLL_ENABLE */LOCAL void ixEthAccEndTxDoneCallbackShutdown(UINT32 callbackTag, M_BLK *pMblk){    /* Free the buffer back to the pool */    netMblkClChainFree (pMblk);}/********************************************************************************* ixEthAccEndTxDoneReplenishFast - replenish a mbuf to its pool* Attempt to return a mbuf to its pool. If this is not possible* then the buffer is stored in a fast 1R1W queue which is drained inside * the tnetTask context.** RETURNS: none*/LOCAL __inline__ void ixEthAccEndTxDoneReplenishFast(END_DEVICE *pDrvCtrl,						     M_BLK *pMblk){    /* check on the fly that it is possible to replenish      * and check the buffer can be used for immediate replenish      *  (not chained nor shared)      */#if 0    UINT32 rxBufsActive = pDrvCtrl->rxBufsReplenish - pDrvCtrl->rxBufsRecv;    if (rxBufsActive < pDrvCtrl->rxBufsAlloc)    {	if ((pMblk->pClBlk->clRefCnt == 1) && 	    (pMblk->m_next == NULL))	{	    /* check nobody else is running a replenish at the same time */	    if (ixOsServFastMutexTryLock(&(pDrvCtrl->fastReplMutex)) == IX_SUCCESS)	    {		/* replenish */		if (ixEthAccPortRxFreeReplenish(pDrvCtrl->unit, pMblk) 		    != IX_ETH_ACC_SUCCESS)		{		    pDrvCtrl->rxBufsReplenish++; /* The number of mblk sent to NPE */		    /* release the lock */		    ixOsServFastMutexUnlock(&(pDrvCtrl->fastReplMutex));		    /* done */		    return;		}		/* release the lock */		ixOsServFastMutexUnlock(&(pDrvCtrl->fastReplMutex));	    }	}    }#endif    /* the bufffer cannot yet be used for replenish,      * Free the buffer back to the fast pool      */    pDrvCtrl->replBufList[pDrvCtrl->replWr++ & RECBUF_MASK] = pMblk;    /* pDrvCtrl points to the driver structure which got a     * mbuf to replenish. If this queue is getting overloaded    * it is necessary to wake up the tnetTask    */    if (((pDrvCtrl->replWr - pDrvCtrl->replRd)	 == IXETHACC_REPL_NEARLY_FULL_THRESHOLD) 	&& (pDrvCtrl->netJobAddIn - pDrvCtrl->netJobAddOut	    <= IXETHACC_NETJOBADD_THRESHOLD))    { 	IXP_DRV_LOG ((IXP_DRV_DEBUG_INT | IXP_DRV_DEBUG_RX), 		     "NetJobAdd required for Replenish\n", 1, 2, 3, 4, 5, 6);	if (netJobAdd ((FUNCPTR)ixEthAccEndHandleRcvInt, (int)pDrvCtrl,		   0,0,0,0) == ERROR)            {#ifdef IXP_DRV_DEBUG_MBUFS            pDrvCtrl->tnetJobAddFail++;#endif            DO_EVENT(IXE_EVT_XMT_REPLENISH_NETJOBADDFAIL);            IXP_DRV_LOG ((IXP_DRV_DEBUG_ERROR),                          "NetJobAdd failed for TX Replenish\n",                         1, 2, 3, 4, 5, 6);            }         else            {	    pDrvCtrl->netJobAddIn++;            DO_EVENT(IXE_EVT_XMT_REPLENISH_NETJOBADD);            }     }    return;}LOCAL void ixEthAccEndTxDoneCallback(UINT32 callbackTag, M_BLK *pMblk){    END_DEVICE *pDrvCtrl = (END_DEVICE *)callbackTag;    NET_POOL_ID netPoolId;#ifdef	IXP_DRV_DEBUG    M_BLK *mbufPtr;#endif    DO_EVENT(IXE_EVT_XMT_DONECALLBACK_ENTRY);#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 */#ifdef IXP_DRV_DEBUG_MBUFS    elogHook(pMblk, 5, pDrvCtrl->rxBufsRecv, pDrvCtrl->rxBufsReplenish);#endif    /* attempt to release to the fastreplenish pool      * associated with each driver     */    netPoolId = MBLK_TO_NET_POOL(pMblk);    /* check the current driver */    if (netPoolId == pDrvCtrl->end.pNetPool)    {	ixEthAccEndTxDoneReplenishFast(pDrvCtrl, pMblk);	DO_EVENT(IXE_EVT_XMT_DONECALLBACK_EXIT);	return;    }    else    {	/* check the other ixe driver (safe even if the driver is not 	 * initialized, because the structure is initialized with 	 * a dummy structure) 	 */	pDrvCtrl = ixEthAccpDrvCtrl[1 - pDrvCtrl->unit];	if (netPoolId == pDrvCtrl->end.pNetPool)	{	    ixEthAccEndTxDoneReplenishFast(pDrvCtrl, pMblk);	    DO_EVENT(IXE_EVT_XMT_DONECALLBACK_EXIT);	    return;	}    }    /* this mbuf is from an 'unknown' origin, probably the system pool.     * Free the buffer back to its pool      */    netMblkClChainFree (pMblk);    DO_EVENT(IXE_EVT_XMT_DONECALLBACK_EXIT);}LOCAL void ixEthAccEndRxCallbackShutdown(UINT32 callbackTag, M_BLK *pMblk, IxEthAccPortId portId){    END_DEVICE *pDrvCtrl = (END_DEVICE *)callbackTag;    pDrvCtrl->rxBufsRecv++;    netMblkClChainFree (pMblk);}LOCAL void ixEthAccEndRxCallback(UINT32 callbackTag, M_BLK *pMblk, IxEthAccPortId portId){    END_DEVICE *pDrvCtrl = (END_DEVICE *)callbackTag;    BOOL netJobAddNeeded;    DO_EVENT(IXE_EVT_RCV_CALLBACK_ENTRY);    pDrvCtrl->rxBufsRecv++;    DO_EVENT(IXE_EVT_RCV_CALLBACK_CACHEOPS);    /* Now start a prefetch on the packet header */    PREFETCH(pMblk);    IXP_DRV_LOG ((IXP_DRV_DEBUG_INT | IXP_DRV_DEBUG_RX), 		 "Rx ixe[%d] Callback Hdr: 0x%08X Buff: 0x%08X Size: 0x%08X\n"		 , pDrvCtrl->unit		 , (int)pMblk		 , (int)pMblk->m_data		 , pMblk->m_pkthdr.len		 , 5, 6);    /* 3 possibilities before the queue update     * a - no entry in the queue : need to wake up the tnetTask     * b - between 1 and 120 entries : the tnettask is already running     *     and there is no need for netjobadd     * c - more than 120 entries : impossible by design, there are     *     only 120 mbufs in the rx pool. No check for overflow is     *     necessary.     */    netJobAddNeeded = (pDrvCtrl->recWr == pDrvCtrl->recRd);    /* Store to the top of the 1R1W queue */    pDrvCtrl->recBufList[pDrvCtrl->recWr++ & RECBUF_MASK] = pMblk;    DO_EVENT(IXE_EVT_RCV_CALLBACK_RINGADD);	    /* 4 possibilities after the queue update     * a - no entry in the queue : a ctxt switch occured     *     and the entry is already processed. No need for netjobadd     *     (this may occur when QMgr is running from a task)     * b - 1 entry in the queue : the queue was empty before this cb     *     and a netjobadd is necessary to wake up the tnettask     * c - between 2 and 120 entries : the tnettask is already running     *     and there is no need for netjobadd     * d - more than 120 entries : impossible by design, there are     *     only 120 mbufs in the rx pool. No check for overflow is     *     necessary.     */    /* if there are already NetJobAdd pending, it is unnecesary     * to add more netJobAdd requests (1 netJobAdd will drain all     * the sw queue)     * In case of traffic burst, WRS strongly advice to not     * overflow the tnetTask message queue.     */    netJobAddNeeded = netJobAddNeeded &&	

⌨️ 快捷键说明

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