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

📄 elt3c509end.c

📁 Tornado 2.0.2 source code!vxworks的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
                }            if ((statusTx & (TX_S_JABBER | TX_S_UNDERRUN)) != 0)                {                /* Must reset transmitter; this clears the tx FIFO */                SYS_OUT_WORD (pDrvCtrl, port + ELT3C509_COMMAND, TX_RESET);                }            }        if (needTxStart)                            /* check flag */            elt3c509TxStart (pDrvCtrl);        if (pDrvCtrl->txBlocked)            {            pDrvCtrl->txBlocked = FALSE;            /* restart the transmit flow */            netJobAdd ((FUNCPTR) muxTxRestart, (int) &pDrvCtrl->endObj, 0, 0,                       0, 0);#ifdef ELT_TIMING            if ((int)++pDrvCtrl->elt3c509Stat.taskQTxOuts >                 (int)pDrvCtrl->elt3c509Stat.maxTxTaskQ)                pDrvCtrl->elt3c509Stat.maxTxTaskQ =                    pDrvCtrl->elt3c509Stat.taskQTxOuts;#endif /* ELT_TIMING */            }        }    /* Handle update statistics interrupt */    if ((status & UPDATE_STATS) != 0)        elt3c509StatFlush (pDrvCtrl);    /* mask and ack the events we've just handled or queued handlers for */    SYS_OUT_WORD (pDrvCtrl, pDrvCtrl->port + ELT3C509_COMMAND,                  MASK_STATUS | pDrvCtrl->intMask);    SYS_OUT_WORD (pDrvCtrl, pDrvCtrl->port + ELT3C509_COMMAND,                  ACK_INTERRUPT | status);    sysBusIntAck (pDrvCtrl->intLevel);    }/********************************************************************************* elt3c509HandlePktsRcv - task level interrupt service for input packets** This routine is called at task level indirectly by the interrupt* service routine to do any message received processing.** RETURNS: N/A.*/LOCAL void elt3c509HandlePktsRcv    (    ELT3C509_DEVICE * pDrvCtrl	/* interrupting device */    )    {    M_BLK_ID 		pMblk;		/* pointer to the mBlk */    CL_BLK_ID		pClBlk;		/* pointer to the clBlk */    char *		pCluster;	/* pointer to the cluster */    int    		port;		/* IO port to read */    STATUS      	result = OK;    /* Tracks result of Cluster Alloc */    port = pDrvCtrl->port;        /* loop for more frames */    while (TRUE)        {        /* get a cluster */        pCluster = netClusterGet (pDrvCtrl->endObj.pNetPool,                                  pDrvCtrl->pClPoolId);        if (pCluster == NULL)            {            ENDLOGMSG (("Cannot loan!\n", 1, 2, 3, 4, 5, 6));            ++pDrvCtrl->elt3c509Stat.rxnobuffers;            END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);	    result = ERROR;            break;            }        /* get a cluster block */        if ((pClBlk = netClBlkGet (pDrvCtrl->endObj.pNetPool, M_DONTWAIT)) ==            NULL)            {            netClFree (pDrvCtrl->endObj.pNetPool, pCluster);            ENDLOGMSG (("Out of Cluster Blocks!\n", 1, 2, 3, 4, 5, 6));            END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);	    result = ERROR;            break;            }            /* get an mBlk */        if ((pMblk = mBlkGet (pDrvCtrl->endObj.pNetPool, M_DONTWAIT, MT_DATA))            == NULL)            {            netClBlkFree (pDrvCtrl->endObj.pNetPool, pClBlk);             netClFree (pDrvCtrl->endObj.pNetPool, pCluster);            ENDLOGMSG (("Out of M Blocks!\n", 1, 2, 3, 4, 5, 6));            END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);	    result = ERROR;            break;            }        /* Join the cluster to the MBlock */        netClBlkJoin (pClBlk, pCluster, ELT3C509_BUFSIZ, NULL, 0, 0, 0);        netMblkClJoin (pMblk, pClBlk);                if (elt3c509PollRcv ((void *)pDrvCtrl, pMblk) == OK)            {            END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_UCAST, +1);            ENDLOGMSG (("Calling upper layer's recv rtn\n", 1, 2, 3, 4, 5, 6));            /* Call the upper layer's receive routine. */            END_RCV_RTN_CALL (&pDrvCtrl->endObj, pMblk);            }        else            {            ENDLOGMSG (("EAGAIN\n", 1, 2, 3, 4, 5, 6));            netMblkClFree (pMblk);	    result = ERROR;            break;            }        }        /* Discard the packet in the FIFO here of there was an error */    if (result == ERROR)	{	/* discard packet */        SYS_OUT_WORD (pDrvCtrl, port + ELT3C509_COMMAND, RX_DISCARD);	}	    	/* enable the recv interrupt */    elt3c509IntMaskSet (pDrvCtrl, (RX_COMPLETE | RX_EARLY));    }/********************************************************************************* elt3c509PollRcv - 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: EGAIN or OK*/LOCAL STATUS elt3c509PollRcv    (    void  * 	pEnd,		/* device pointer */    M_BLK_ID 	pMblk		/* pointer to the mBlk chain */    )    {    UINT16 		statusRx;    UINT16 		statusRxNew;    UINT16 		length;    int    		port;    int			ix = 0;    int	     		status = OK;    ELT3C509_DEVICE * 	pDrvCtrl;    VOID_TO_DRVCTRL (pEnd, pDrvCtrl);    port = pDrvCtrl->port;        SYS_IN_WORD (pDrvCtrl, port + RX_STATUS, statusRx);        if (statusRx & RX_S_INCOMPLETE)		/* incomplete */        {        if (statusRx == RX_S_INCOMPLETE)	/* no bytes available */            {            ENDLOGMSG (("no more packets\n", 1, 2, 3, 4, 5, 6));            return (EAGAIN);            }        while (ix < 10000)            {            SYS_IN_WORD (pDrvCtrl, port + RX_STATUS, statusRxNew);            if (statusRx == statusRxNew)                {                break;                }            else                {                statusRx = statusRxNew;                ix++;                }            }                if (statusRx & RX_S_INCOMPLETE)            {            END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);            ENDLOGMSG (("status quo\n", 1, 2, 3, 4, 5, 6));            status = EAGAIN;            goto PollRcvErrHandle;            }        }    /* Check for errors in completed packet */    if (statusRx & RX_S_ERROR)        {        switch (statusRx & RX_S_CODE_MASK)            {            case RX_S_OVERRUN:	/* handled by statistics registers */                break;            case RX_S_RUNT:                ++pDrvCtrl->elt3c509Stat.shortPacket;                break;            case RX_S_ALIGN:                ++pDrvCtrl->elt3c509Stat.aligns;                break;            case RX_S_CRC:                ++pDrvCtrl->elt3c509Stat.crcs;                break;            case RX_S_OVERSIZE:                ++pDrvCtrl->elt3c509Stat.badPacket;                break;            default:		/* no other codes are defined */                break;	            }        END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);        ENDLOGMSG (("recv error\n", 1, 2, 3, 4, 5, 6));        status = EAGAIN;        goto PollRcvErrHandle;        }    /* length of the buffer in the FIFO */    length = statusRx & RX_S_CNT_MASK;    /* discard packet if received frame is bigger than MAX_FRAME_SIZE */    if (length > MAX_FRAME_SIZE)        {        ENDLOGMSG (("pktlen>MAX_FRAME_SIZE\n", 1, 2, 3, 4, 5, 6));        END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);        status = EAGAIN;        goto PollRcvErrHandle;        }    /* if given mBlk does not have enough space */    if ((!(pMblk->mBlkHdr.mFlags & M_EXT)) || (pMblk->pClBlk->clSize < length))	{        ENDLOGMSG (("PRX bad mblk len:%d flags:%d\n", pMblk->mBlkHdr.mLen,                   pMblk->mBlkHdr.mFlags, 3, 4, 5, 6));        END_ERR_ADD (&pDrvCtrl->endObj, MIB2_IN_ERRS, +1);        status = EAGAIN;        goto PollRcvErrHandle;	}    /* read the packet from the FIFO into the cluster */        SYS_IN_WORD_STRING (pDrvCtrl, port + DATA_REGISTER, 			(short *) pMblk->mBlkHdr.mData, (length + 1) / 2);    /* update the mBlk fields */    pMblk->mBlkHdr.mLen   = length;    pMblk->mBlkHdr.mFlags |= M_PKTHDR;    pMblk->mBlkPktHdr.len = length;    status = OK;        PollRcvErrHandle:    	{	/* discard packet */        SYS_OUT_WORD (pDrvCtrl, port + ELT3C509_COMMAND, RX_DISCARD);        /* wait for command to finish */        statusRxNew = ERROR;        while ((statusRxNew & COMMAND_IN_PROGRESS) != 0)            {            SYS_IN_WORD (pDrvCtrl, port + ELT3C509_STATUS, statusRxNew);            }        }    return (status);    }/******************************************************************************** elt3c509Config - reconfigure the interface under us.** Reconfigure the interface setting promiscuous mode, and changing the* multicast interface list.** RETURNS: N/A.*/LOCAL void elt3c509Config    (    ELT3C509_DEVICE * pDrvCtrl	/* device to be re-configured */    )    {    /* Set promiscuous mode if it's asked for. */    if (END_FLAGS_GET (&pDrvCtrl->endObj) & IFF_PROMISC)	{	ENDLOGMSG (("Setting promiscuous mode on!\n", 1, 2, 3, 4, 5, 6));        pDrvCtrl->rxFilter |= RX_F_PROMISCUOUS;        SYS_OUT_WORD(pDrvCtrl, pDrvCtrl->port + ELT3C509_COMMAND,                     SET_RX_FILTER | pDrvCtrl->rxFilter);	}    else	{	ENDLOGMSG (("Setting promiscuous mode off!\n", 1, 2, 3, 4, 5, 6));        pDrvCtrl->rxFilter &= ~RX_F_PROMISCUOUS;        SYS_OUT_WORD (pDrvCtrl, pDrvCtrl->port + ELT3C509_COMMAND,                      SET_RX_FILTER | pDrvCtrl->rxFilter);	}    /* Set up address filter for multicasting.      * Multicast bit is set if the address list has one or more entries     * Multicasting is disabled if the address list is empty     */    if (END_MULTI_LST_CNT (&pDrvCtrl->endObj) > 0 ||             (END_FLAGS_GET (&pDrvCtrl->endObj) & IFF_MULTICAST))	{	ENDLOGMSG (("Setting multicast mode on!\n", 1, 2, 3, 4, 5, 6));        pDrvCtrl->rxFilter |= RX_F_MULTICAST;        SYS_OUT_WORD (pDrvCtrl, pDrvCtrl->port + ELT3C509_COMMAND,                      SET_RX_FILTER | pDrvCtrl->rxFilter);	}    else	{	ENDLOGMSG (("Setting multcast mode off!\n", 1, 2, 3, 4, 5, 6));        pDrvCtrl->rxFilter &= ~RX_F_MULTICAST;        SYS_OUT_WORD (pDrvCtrl, pDrvCtrl->port + ELT3C509_COMMAND,                      SET_RX_FILTER | pDrvCtrl->rxFilter);	}    return;    }/********************************************************************************* elt3c509PollSend - 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 elt3c509PollSend    (    void  * 	pEnd,	        /* device pointer */    M_BLK_ID 	pMblk		/* packet to send */    )    {    int			len;    int *		pLenMask;    char *		pBuf;    ELT3C509_DEVICE * 	pDrvCtrl;    UINT16		txStatus;    VOID_TO_DRVCTRL (pEnd, pDrvCtrl);    SYS_IN_WORD (pDrvCtrl, pDrvCtrl->port + TX_FREE_BYTES, txStatus);    if (txStatus >= TX_IDLE_COUNT)        {        pBuf = pDrvCtrl->pTxCluster; 	/* pointer to the transmit cluster */        pLenMask = (UINT32 *)pBuf;                /* allow space for the preamble the trasmit buffer is 1520 */        pBuf += sizeof(UINT32);        len = netMblkToBufCopy(pMblk, pBuf, NULL);        len = max(len, ETHERSMALL);		/* set the packet size */        *pLenMask = len | TX_F_INTERRUPT;	/* set the preamble */        len = (len + TX_F_PREAMBLE_SIZE + 3) & TX_F_DWORD_MASK;        /* place a transmit request */        SYS_OUT_WORD_STRING (pDrvCtrl, pDrvCtrl->port + DATA_REGISTER, 				(short *)pLenMask, len / 2);        /* read the tranmsit status */        SYS_IN_BYTE (pDrvCtrl, pDrvCtrl->port + TX_STATUS, txStatus);        /* wait until tramit is complete */        while (!(txStatus & TX_S_COMPLETE))            {            SYS_IN_BYTE (pDrvCtrl, pDrvCtrl->port + TX_STATUS, txStatus);            }	/* clear old status */        SYS_OUT_BYTE (pDrvCtrl, pDrvCtrl->port + TX_STATUS, 0);        }    else        {        ENDLOGMSG(("Error in Send, not enough TxFreeBytes\n",1,2,3,4,5,6));        return (EAGAIN);        }        /* Bump the statistic counter. */    END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_UCAST, +1);    ENDLOGMSG (("Poll Send complete\n",1,2,3,4,5,6));    return (OK);    }/********************************************************************************* elt3c509PollStart - start polled mode operations** This function starts polled mode operation.** The device interrupts are disabled, the current mode flag is switched* to indicate Polled mode and the device is reconfigured.** RETURNS: OK or ERROR.*/LOCAL STATUS elt3c509PollStart    (    ELT3C509_DEVICE * pDrvCtrl	/* device to be polled */    )    {    int         oldLevel;        oldLevel = intLock ();          /* disable ints during update */

⌨️ 快捷键说明

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