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

📄 ixethaccend.c

📁 ixp425 bsp for vxworks
💻 C
📖 第 1 页 / 共 5 页
字号:
	/* queue not empty, get a mbuf */	pMblk = pDrvCtrl->recBufList[pDrvCtrl->recRd++ & RECBUF_MASK];        IXP_DRV_LOG (IXP_DRV_DEBUG_RX, 		     "ixEthAccEndRcvInt: received mbuf %8.8x\n",		     (UINT32)pMblk, 2, 3, 4, 5, 6);        DO_EVENT(IXE_EVT_RCV_RECEIVE_LOOP_CACHEOPS);#ifdef IXE_CACHED_RX_BUFFERS_ENABLE	/*	 * We need only invalidate up to the contents of the use	 * of this buffer. But because 	 * - the buffers are invalidated during replenish 	 * - the buffers are aligned on cache line boundaries if the 	 *   cache is enabled, 	 * it is not necessary to invalidate the cache.	 */	/* 	   IXP425_END_CACHE_INVALIDATE(pMblk->m_data, pMblk->m_len);	*/#endif#ifdef IXP_DRV_DEBUG_MBUFS	elogHook(pMblk, 3, pDrvCtrl->rxBufsRecv, pDrvCtrl->rxBufsReplenish);#endif         pMblk->mBlkHdr.mFlags |= M_PKTHDR;        /* No chained MBUF's on receive side, and NPE set the pktlen field	 * pMblk->mBlkPktHdr.len = pMblk->m_len;	 * pMblk->m_next = 0;	 */	rxBufsActive = pDrvCtrl->rxBufsReplenish - pDrvCtrl->rxBufsRecv;	if (rxBufsActive < IXETHACC_REPL_FAST_THRESHOLD)	{	    /* replenish as much as possible */	    ixEthAccEndReplenishFast(pDrvCtrl);	    rxBufsActive = pDrvCtrl->rxBufsReplenish - pDrvCtrl->rxBufsRecv;	}	if (rxBufsActive < IXETHACC_REPL_SLOW_THRESHOLD)	{	    /* replenish as much as possible */	    ixEthAccEndReplenishSlow(pDrvCtrl);	    rxBufsActive = pDrvCtrl->rxBufsReplenish - pDrvCtrl->rxBufsRecv;	}	        /* Now start a prefetch on the packet payload 	 * This will bring to memory the MAC addresses 	 * and a part of the IP header.	 */        PREFETCH(pMblk->m_data) ;	if (rxBufsActive < 2)	{	    /* The number of cblk/mblk pairs owned by NPE 	     * is gone low. This mbuf will be used for replenish.	     * If we don't replenish, rx events will not take	     * place and traffic is blocked (because replenish	     * is done from RX	     */	    netMblkClChainFree (pMblk);	    #ifdef IXP_DRV_DEBUG_MBUFS	    pDrvCtrl->tnetDrop++;#endif#ifdef IXETHACCEND_CSR_1_1	    /* update the ip ttl for this interface */	    ixEthAccEnd_ip_ttl_update(pDrvCtrl);	    /* recover ttl-expired mbufs from the stack  */	    ixEthAccEnd_ip_ttl_mbuf_release(pDrvCtrl->ipFragTtl, 					    pDrvCtrl->end.pNetPool);#endif	}	else	{        /* up-date statistics */        if (pMblk->mBlkHdr.mFlags & M_MCAST)            {            END_INC_IN_MCAST(pMblk->mBlkHdr.mData,pMblk->mBlkPktHdr.len);            }        else if (pMblk->mBlkHdr.mFlags & M_BCAST)            {            END_INC_IN_BCAST(pMblk->mBlkHdr.mData,pMblk->mBlkPktHdr.len);            }        else            {            END_INC_IN_UCAST(pMblk->mBlkHdr.mData,pMblk->mBlkPktHdr.len);            }#ifdef IXETHACCEND_CSR_1_1	    /* update the ip ttl for this interface */	    ixEthAccEnd_ip_ttl_update(pDrvCtrl);#endif#ifdef IXP_DRV_DEBUG_MBUFS	    pDrvCtrl->tnetReceived++;#endif	    IXP_DRV_LOG (IXP_DRV_DEBUG_RX, 		     "ixEthAccEndRcvInt: mbuf %8.8x sent to stack\n",		     (UINT32)pMblk, 2, 3, 4, 5, 6);	    /* Call the upper layer's receive routine. */   	    END_RCV_RTN_CALL(&pDrvCtrl->end, pMblk);	}    }    /* replenish all buffers */    ixEthAccEndReplenishSlow(pDrvCtrl);    DO_EVENT(IXE_EVT_RCV_HANDLE_EXIT);}/********************************************************************************* swapMblk: the driver send routine** This routine is used to replace a mbuf chain with mbuf appropriate * for transmission (they need to be aligned, or in uncached memory)***/#ifndef IXE_CACHED_RX_BUFFERS_ENABLEstatic M_BLK *swapMblk(END_DEVICE *pDrvCtrl, M_BLK *pMblk){    M_BLK *newMblk;    if (pMblk == NULL)    {	return NULL;    }    /* check if the mbuf if from the driver pool */    if ((MBLK_TO_NET_POOL(pMblk) == pDrvCtrl->end.pNetPool)	|| (MBLK_TO_NET_POOL(pMblk) == ixEthAccpDrvCtrl[1 - pDrvCtrl->unit]->end.pNetPool))    {	/* use current mbuf because it belongs to the driver pools */	if (pMblk->m_next == NULL)	{	    /* check for unchained (happy day scenario) */	    return pMblk;	    	}	else	{	    pMblk->m_next = swapMblk(pDrvCtrl, pMblk->m_next);	    return pMblk;	}    }    /* Check if mbuf header and payload is aligned */    if (((UINT32)pMblk & (IX_XSCALE_CACHE_LINE_SIZE - 1)) == 0 	&& ((UINT32)(pMblk->m_data) & (IX_XSCALE_CACHE_LINE_SIZE - 1)) <= 3)    {	/* use current mbuf, because it is correctly aligned */	pMblk->m_next = swapMblk(pDrvCtrl, pMblk->m_next);	return pMblk;    }    /* the cache operations over mbufs will destroy     * the information in adjacent mbuf.     * The solution is to get a new mbuf with correct alignement     */#ifdef IXP_DRV_DEBUG_MBUFS    pDrvCtrl->tupleTxAlloc++;#endif    newMblk = netTupleGet(pDrvCtrl->end.pNetPool,			  pMblk->m_len,			  M_DONTWAIT,			  MT_HEADER,			  FALSE );    if (newMblk != NULL)    {	M_BLK *next = pMblk->m_next;	/* duplicate the mbuf */	memcpy(newMblk->m_data, pMblk->m_data, pMblk->m_len);	newMblk->m_len = pMblk->m_len;	/* process the next nblk */	if (next == NULL)	{	    /* free the current mblk */	    netMblkClChainFree(pMblk);	    newMblk->m_next = NULL;	}	else	{	    /* free the current mblk */	    pMblk->m_next = 0;	    netMblkClChainFree(pMblk);	    newMblk->m_next = swapMblk(pDrvCtrl, next);	}	return newMblk;    }    else    {	/* drop the remaining of the chain */	netMblkClChainFree(pMblk);	return NULL;    }}#endif/********************************************************************************* ixEthAccEndSend - the driver send routine** This routine takes a M_BLK_ID sends off the data in the M_BLK_ID.* The buffer must already have the addressing information properly installed* in it.  This is done by a higher layer.** RETURNS: OK, ERROR, or END_ERR_BLOCK.*/LOCAL STATUS ixEthAccEndSend(END_DEVICE * pDrvCtrl,  /* device ptr */M_BLK_ID     pMblk      /* data to send */){    int      tmLen = 0;    M_BLK   *mbufPtr;    STATUS   rtnStatus = OK;    char     bumpFlag;    char     mFlags = 0;    char    *mData;#ifdef INCLUDE_IXETHACC_64BYTES_PADDING     M_BLK *lastMbuf;#endif#ifndef IXE_CACHED_RX_BUFFERS_ENABLE    pMblk = swapMblk(pDrvCtrl, pMblk);#endif    if (pMblk == NULL)        return ERROR;    if (pMblk->m_next)    {	/* remember a flag to increment the stats counters */ 	bumpFlag = pMblk->mBlkHdr.mData[0] & (UINT8) 0x01 ;	#ifdef IXP_DRV_DEBUG_MBUFS	elogHook(pMblk, 4, pDrvCtrl->rxBufsRecv,pDrvCtrl->rxBufsReplenish);#endif        /* calculate the frame size (sum of chained mbufs) */	for ( mbufPtr = pMblk; mbufPtr; mbufPtr = mbufPtr->m_next )        {#ifdef INCLUDE_IXETHACC_64BYTES_PADDING 	    /* remember the last mbuf where padding may be necessary */	    lastMbuf = mbufPtr;#endif	    tmLen += mbufPtr->m_len;        }	pMblk->m_pkthdr.len = tmLen;#ifdef INCLUDE_IXETHACC_64BYTES_PADDING 	/* Add padding at the end of the mbuf 	 * this is normally done by the ixp silicon.	 * (unless the hardware Padding/FCS generation is disabled)	 */	if (pMblk->m_pkthdr.len < 64)	{            /* add trailing bytes in last mbuf */	    char *mDataPtr = &(lastMbuf->m_data[lastMbuf->m_len]);	    char *mClBufPtr = &(lastMbuf->pClBlk->clNode.pClBuf[lastMbuf->pClBlk->clSize]);	    while((pMblk->m_pkthdr.len < 64)		  && (mDataPtr < mClBufPtr))	    {		*mDataPtr++ = 0;		lastMbuf->m_len += 1;		pMblk->m_pkthdr.len += 1;	    }	}#endif        /* blocks and buffers come from cached memory */	for ( mbufPtr = pMblk; mbufPtr; mbufPtr = mbufPtr->m_next )        {	    IXP425_END_CACHE_FLUSH(mbufPtr->m_data, mbufPtr->m_len);#ifdef IXE_CACHED_RX_BUFFERS_ENABLE	    /* the access component flush the mbuf header */#else	    IXP425_END_CACHE_FLUSH(mbufPtr, sizeof(M_BLK));#endif        }    }    else    {#ifdef INCLUDE_IXETHACC_64BYTES_PADDING 	/* Add padding at the end of the mbuf 	 * this is normally done by the ixp silicon.	 * (unless the harware Padding/FCS generation is disabled)	 */	if (pMblk->m_len < 64)	{	    char *mDataPtr = &(pMblk->m_data[pMblk->m_len]);	    char *mClBufPtr = &(pMblk->pClBlk->clNode.pClBuf[pMblk->pClBlk->clSize]);	    while((pMblk->m_len < 64)		  && (mDataPtr < mClBufPtr))	    {		*mDataPtr++ = 0;		pMblk->m_len += 1;	    }	}#endif#ifdef IXP_DRV_DEBUG_MBUFS	elogHook(pMblk, 4, pDrvCtrl->rxBufsRecv,pDrvCtrl->rxBufsReplenish);#endif	/* remember a flag to increment the stats counters */ 	bumpFlag = (pMblk->m_data[0] & ((UINT8)0x01)) ;        mFlags = pMblk->m_flags;	/* update the length */	tmLen = pMblk->m_pkthdr.len = pMblk->m_len;	/* Xmit blocks and buffers can come from cached memory */        IXP425_END_CACHE_FLUSH(pMblk->m_data, pMblk->m_len);#ifdef IXE_CACHED_RX_BUFFERS_ENABLE	/* the access component flush the mbuf header */#else	IXP425_END_CACHE_FLUSH(pMblk, sizeof(M_BLK));#endif    }    /* Little endian target swaps bytes so save the pointer for MIB statistics */    mData = pMblk->mBlkHdr.mData;    /*     * Obtain exclusive access to transmitter.  This is necessary because     * we might have more than one stack transmitting at once.     */    if (!(pDrvCtrl->flags & IxEthAccEnd_POLLING))        {        END_TX_SEM_TAKE (&pDrvCtrl->end, WAIT_FOREVER);        }    /* place a transmit request */    if ( ixEthAccPortTxFrameSubmit(pDrvCtrl->unit, pMblk, IX_ETH_ACC_TX_DEFAULT_PRIORITY) != IX_ETH_ACC_SUCCESS )        {        IXP_DRV_LOG (IXP_DRV_DEBUG_ERROR, 		     "Error Tx Send Unit[%d] : Buffer:08x%08X\n",                     pDrvCtrl->unit, (int)pMblk, 3, 4, 5, 6);#ifdef IXP_DRV_DEBUG_MBUFS	pDrvCtrl->errs++;#endif	netMblkClChainFree (pMblk);        /* update mib stats */        END_INC_OUT_DISCARDS();        rtnStatus = ERROR;        }    else        {         /* WARNING: in the little endian BSP, the mBlkHdr has been endian-swapped */        /* Bump the statistics counters. */        if ( (mFlags & M_MCAST) != 0 )            {            END_INC_OUT_MCAST (mData, tmLen);            }        else if ( (mFlags & M_BCAST) != 0 )            {            END_INC_OUT_BCAST (mData, tmLen);            }        else            {            END_INC_OUT_UCAST (mData, tmLen);            }        }    if (!(pDrvCtrl->flags & IxEthAccEnd_POLLING))        {        END_TX_SEM_GIVE (&pDrvCtrl->end);        }    DO_EVENT(IXE_EVT_XMT_SEND_EXIT);    return(rtnStatus);}/********************************************************************************* ixEthAccEndIoctl - the driver I/O control routine** Process an ioctl request.** RETURNS: A command specific response, usually OK or ERROR.*/LOCAL STATUS ixEthAccEndIoctl(END_DEVICE * pDrvCtrl,  /* device receiving command */int cmd,            /* ioctl command code */caddr_t data        /* command argument */){    int error = 0;    long value;    IXP_DRV_LOG (IXP_DRV_DEBUG_IOCTL, 		 "ixe: Ioctl:unit[%d]:CMD:0x%08X\n", 		 pDrvCtrl->unit, cmd, 3, 4, 5, 6);    switch ((UINT)cmd)        {        case EIOCSADDR:            if (data == NULL)                return(EINVAL);            bcopy ((char *)data, (char *)END_HADDR(&pDrvCtrl->end),                   END_HADDR_LEN(&pDrvCtrl->end));            break;        case EIOCGADDR:            if (data == NULL)                return(EINVAL);            bcopy ((char *)END_HADDR(&pDrvCtrl->end), (char *)data,                   END_HADDR_LEN(&pDrvCtrl->end));            break;        case EIOCSFLAGS:            value = (long)data;            if (value < 0)                {                value = -(--value);                END_FLAGS_CLR (&pDrvCtrl->end, value);                } else                {                END_FLAGS_SET (&pDrvCtrl->end, value);                }            ixEthAccEndConfig (pDrvCtrl);            break;        case EIOCGFLAGS:

⌨️ 快捷键说明

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