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

📄 elt3c509end.c

📁 操作系统vxworks平台下end设备的驱动程序,支持多种芯片,支持多种cpu
💻 C
📖 第 1 页 / 共 5 页
字号:
    /* Handle adapter failure first in case other conditions mask it */    if ((status & ADAPTER_FAILURE) != 0)        {        SYS_OUT_WORD (pDrvCtrl, port + ELT3C509_COMMAND,                      SELECT_WINDOW | WIN_DIAGNOSTIC);        SYS_IN_WORD (pDrvCtrl, port + FIFO_DIAGNOSTIC, statusDiag);        SYS_OUT_WORD (pDrvCtrl, port + ELT3C509_COMMAND,                      SELECT_WINDOW | WIN_OPERATING);        if ((statusDiag & FD_TX_OVERRUN) != 0)            {            ++pDrvCtrl->elt3c509Stat.txoverruns;            SYS_OUT_WORD (pDrvCtrl, port + ELT3C509_COMMAND, TX_RESET);            elt3c509TxStart (pDrvCtrl);            }        if ((status & FD_RX_UNDERRUN) != 0)            {            ++pDrvCtrl->elt3c509Stat.rxunderruns;            SYS_OUT_WORD (pDrvCtrl, port + ELT3C509_COMMAND, RX_RESET);            elt3c509RxStart (pDrvCtrl);            }        }    if (status & (RX_COMPLETE | RX_EARLY))        {        if ((status & RX_EARLY) != 0)            ++pDrvCtrl->elt3c509Stat.rxearly;        if (netJobAdd ((FUNCPTR)elt3c509HandlePktsRcv, (int) pDrvCtrl,                       0, 0, 0, 0) == OK)            {            pDrvCtrl->intMask &= ~(RX_COMPLETE | RX_EARLY);                #ifdef ELT_TIMING            if((int)++pDrvCtrl->elt3c509Stat.taskQRxOuts >               (int)pDrvCtrl->elt3c509Stat.maxRxTaskQ)                {                pDrvCtrl->elt3c509Stat.maxRxTaskQ =                    pDrvCtrl->elt3c509Stat.taskQRxOuts;                }#endif /* ELT_TIMING */            }        else            logMsg ("elt: netJobAdd (elt3c509HandlePktsRcv) failed\n",                    0, 0, 0, 0, 0, 0);        }        /* Handle transmitter interrupts */    if ((status & TX_COMPLETE) != 0)        {        SYS_IN_BYTE (pDrvCtrl, port+TX_STATUS, statusTx);        if ((statusTx & TX_S_COMPLETE) != 0)            {            SYS_OUT_BYTE (pDrvCtrl,port + TX_STATUS, 0); /* clear old status */            /*             * other errors are tabulated by reading the statistics registers             */            if ((statusTx & TX_S_MAX_COLL) != 0)                END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_ERRS, +16);            if ((statusTx & TX_S_JABBER) != 0)                END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_ERRS, +1);            if ((statusTx & (TX_S_JABBER | TX_S_MAX_COLL | TX_S_UNDERRUN))                != 0)                {                needTxStart = TRUE;                 /* restart transmitter */                /* packet not sent */                END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_ERRS, +1);                END_ERR_ADD (&pDrvCtrl->endObj, MIB2_OUT_UCAST, -1);                }            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

⌨️ 快捷键说明

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