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

📄 ixethaccend.c

📁 INTEL IXP425的VXWORKS BSP
💻 C
📖 第 1 页 / 共 5 页
字号:
	/* 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;#ifndef IXE_CACHED_RX_BUFFERS_ENABLE    pMblk = swapMblk(pDrvCtrl, pMblk);#endif    if (pMblk == NULL)        return ERROR;    if (pMblk->m_next)    {	/* Calculate total size of chained buffer */	for ( mbufPtr = pMblk; mbufPtr; mbufPtr = mbufPtr->m_next )            {            /* Force outbound packets to 60 bytes minimum */            if ( mbufPtr->m_pkthdr.len && mbufPtr->m_pkthdr.len < 60 )                {                bzero (mbufPtr->m_data + mbufPtr->m_pkthdr.len,                       (int) 60 - mbufPtr->m_pkthdr.len);                mbufPtr->m_pkthdr.len = 60;                }	    tmLen += mbufPtr->m_len;            }	if ( pMblk->m_pkthdr.len != tmLen )	{	    pMblk->m_pkthdr.len = tmLen;        }   	/* 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        /* Xmit 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)) ;	/* update the length */	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    }    /*     * 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);        rtnStatus = ERROR;        }        else        { 	    /* Bump the statistics counters. */	    if ( bumpFlag != 0 )		END_ERR_ADD (&pDrvCtrl->end, MIB2_OUT_UCAST, +1);        }    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:            *(int *)data = END_FLAGS_GET(&pDrvCtrl->end);            break;        case EIOCPOLLSTART: /* Begin polled operation */            ixEthAccEndPollStart (pDrvCtrl);            break;        case EIOCPOLLSTOP:  /* End polled operation */            ixEthAccEndPollStop (pDrvCtrl);            break;        case EIOCGMIB2:     /* return MIB information */            if (data == NULL)                return(EINVAL);            bcopy((char *)&pDrvCtrl->end.mib2Tbl, (char *)data,                  sizeof(pDrvCtrl->end.mib2Tbl));            break;        case EIOCGFBUF:     /* return minimum First Buffer for chaining */            if (data == NULL)                return(EINVAL);            *(int *)data = IxEthAccEnd_MIN_FBUF;            break;        default:            error = EINVAL;        }    return(error);}/******************************************************************************** ixEthAccEndConfig - reconfigure the interface under us.** Reconfigure the interface setting promiscuous mode, and changing the* multicast interface list.** RETURNS: N/A.*/LOCAL void ixEthAccEndConfig(END_DEVICE *pDrvCtrl    /* device to be re-configured */){    /* Set promiscuous mode if it's asked for. */    if (END_FLAGS_GET(&pDrvCtrl->end) & IFF_PROMISC)        {        IXP_DRV_LOG ((IXP_DRV_DEBUG_IOCTL | IXP_DRV_DEBUG_LOAD), "Port [%d]: Setting promiscuous mode on!\n",		     pDrvCtrl->unit, 2, 3, 4, 5, 6);        ixEthAccPortPromiscuousModeSet(pDrvCtrl->unit);        } else        {        IXP_DRV_LOG ((IXP_DRV_DEBUG_IOCTL | IXP_DRV_DEBUG_LOAD), "Port [%d]: Setting promiscuous mode off!\n",		     pDrvCtrl->unit, 2, 3, 4, 5, 6);        ixEthAccPortPromiscuousModeClear(pDrvCtrl->unit);        }    /* Set up address filter for multicasting. */    if (END_MULTI_LST_CNT(&pDrvCtrl->end) > 0)        {        ixEthAccEndAddrFilterSet (pDrvCtrl);        }    return;}/******************************************************************************** ixEthAccEndAddrFilterSet - set the address filter for multicast addresses** This routine goes through all of the multicast addresses on the list* of addresses (added with the endAddrAdd() routine) and sets the* device's filter correctly.** RETURNS: N/A.*/LOCAL void ixEthAccEndAddrFilterSet(END_DEVICE *pDrvCtrl    /* device to be updated */){    ETHER_MULTI* pCurr;    pCurr = END_MULTI_LST_FIRST (&pDrvCtrl->end);    while (pCurr != NULL)    {        pCurr = END_MULTI_LST_NEXT(pCurr);    }}/********************************************************************************* ixEthAccEndPollRcv - routine to receive a packet in polled mode.** This routine is called by a user to try and get a packet from the* device.** RETURNS: OK upon success.  EAGAIN is returned when no packet is available.*/LOCAL STATUS ixEthAccEndPollRcv(END_DEVICE * pDrvCtrl,  /* device to be polled */M_BLK_ID      pMblk     /* ptr to buffer */){#ifdef IXE_ETHACC_POLL_ENABLE    u_short stat;    char* pPacket;    int len;    IXP_DRV_LOG (IXP_DRV_DEBUG_POLL_RX, "ixEthAccEndPollRcv\n", 1, 2, 3, 4, 5, 6);    stat = ixEthAccEndStatusRead (pDrvCtrl);    if (!(stat & IxEthAccEnd_RINT))        {        IXP_DRV_LOG (IXP_DRV_DEBUG_POLL_RX, "ixEthAccEndPollRcv no data\n", 1,                 2, 3, 4, 5, 6);        return(EAGAIN);        }    /* Get packet and  length from device buffer/descriptor */    pPacket = NULL; /* DUMMY CODE */    len = 64;       /* DUMMY CODE */    /* 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 */    netMblkClChainFree (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);}/******************************************************************************

⌨️ 快捷键说明

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