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

📄 if_esmc.c

📁 Tornado 2.0.2 source code!vxworks的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
    sc->interrupt++;    bank = sysInWord (ioaddr + ESMC_BANK_SELECT);	/* save bank */    ESMC_SWITCH_BANK (2);    mask = sysInByte (ioaddr + ESMC_INT_MASK);		/* save mask */    while ((status = sysInByte (ioaddr + ESMC_INT_STAT) & mask) && (timeout--))	{	if (status & ESMC_INT_RCV)			/* RX done */	    {            sc->intRcv++;	    if (sc->mode == RX_MODE_INTERRUPT)		/* RX in int */		{		esmcGetInt (unit);	        if ((sc->flags & ESMC_RXING) == 0)		    {		    sc->flags |= ESMC_RXING;		    (void) netJobAdd ((FUNCPTR)esmcGetTask, unit, 0, 0, 0, 0);		    }		}	    else if ((sc->flags & ESMC_RXING) == 0)	/* RX in task */		{		sc->flags |= ESMC_RXING;		(void) netJobAdd ((FUNCPTR)esmcGet, unit, 0, 0, 0, 0);		}	    }		if (status & ESMC_INT_TX)			/* TX error */	    {            sc->es_if.if_oerrors++;            sc->es_if.if_opackets--;            sc->intTx++;    	    pointerSave = sysInWord (ioaddr + ESMC_PTR); /* save pointer */	    packetSave  = sysInByte (ioaddr + ESMC_PNR); /* save packet */	    packetFail  = sysInWord (ioaddr + ESMC_FIFO) & 0x7f;	    sysOutByte (ioaddr + ESMC_PNR, packetFail);	    sysOutWord (ioaddr + ESMC_PTR, ESMC_PTR_AUTOINC | ESMC_PTR_READ);	    statusTx = sysInWord (ioaddr + ESMC_DATA_1);	    if (statusTx & ESMC_TS_LOST_CARR)		sc->lostCarr++;	    if (statusTx & ESMC_TS_LATCOL)		sc->es_if.if_collisions++;	    	    sysOutWord (ioaddr + ESMC_MMU, ESMC_MMU_TX_RELEASE); /* release */	    sysOutByte (ioaddr + ESMC_INT_ACK, ESMC_INT_TX);	 /* int ack */	    ESMC_SWITCH_BANK (0);	    sysOutWord (ioaddr + ESMC_TCR, 			sysInWord (ioaddr + ESMC_TCR) | ESMC_TCR_TXEN);	    ESMC_SWITCH_BANK (2);	    sysOutByte (ioaddr + ESMC_PNR, packetSave);	 /* restore packet */            sysOutWord (ioaddr + ESMC_PTR, pointerSave); /* restore pointer */	    }	if (status & ESMC_INT_TX_EMPTY)			/* TX done */	    {            sc->intTxempty++;	    sysOutByte (ioaddr + ESMC_INT_ACK, ESMC_INT_TX_EMPTY); /* int ack */	    ESMC_SWITCH_BANK (0);	    statusCard = sysInWord (ioaddr + ESMC_COUNTER);    	    ESMC_SWITCH_BANK (2);	    sc->es_if.if_collisions += statusCard & 0x0f;	    statusCard >>= 4;	    sc->es_if.if_collisions += statusCard & 0x0f;	    mask &= ~ESMC_INT_TX_EMPTY;	    if (sc->es_if.if_snd.ifq_head != NULL)#ifdef BSD43_DRIVER		(void) netJobAdd ((FUNCPTR)esmcPut, unit, 0, 0, 0, 0);#else		(void) netJobAdd ((FUNCPTR)esmcPut, (int)sc, 0, 0, 0, 0);#endif	    }		if (status & ESMC_INT_ALLOC)			/* ALLOC done */	    {            sc->intAlloc++;	    mask &= ~ESMC_INT_ALLOC;	    semGive (&sc->esmcSyncSem);	    }	if (status & ESMC_INT_RX_OVRN)			/* RX over run */	    {            sc->es_if.if_ierrors++;            sc->intOverrun++;            sysOutByte (ioaddr + ESMC_INT_ACK, ESMC_INT_RX_OVRN); /* int ack */	    if (sc->mode == RX_MODE_INTERRUPT)		/* RX in int */		{		esmcGetInt (unit);	        if ((sc->flags & ESMC_RXING) == 0)		    {		    sc->flags |= ESMC_RXING;		    (void) netJobAdd ((FUNCPTR)esmcGetTask, unit, 0, 0, 0, 0);		    }		}	    else if ((sc->flags & ESMC_RXING) == 0)	/* RX in task */		{		sc->flags |= ESMC_RXING;		(void) netJobAdd ((FUNCPTR)esmcGet, unit, 0, 0, 0, 0);		}	    }		if (status & ESMC_INT_EPH)			/* EPH */            sc->intEph++;	if (status & ESMC_INT_ERCV)			/* early receive */            sc->intErcv++;	}        sysOutByte (ioaddr + ESMC_INT_MASK, mask);		/* restore the mask */    ESMC_SWITCH_BANK (bank);				/* restore the bank */    return;    }/********************************************************************************* esmcGet - read a packet off the interface(Task Level: netTask)** Copy packets from a RING into an mbuf and hand it to the next higher layer.** RETURNS: N/A*/LOCAL void esmcGet     (    int unit    )    {    FAST ESMC_SOFTC *sc = &esmc_softc[unit];    FAST int ioaddr     = sc->ioAddr;    FAST struct ether_header *eh;    FAST struct mbuf *m;    int off;    int len;    u_short packetNo;    u_short statusRx;    u_char * pData;    u_char mask;    ESMC_SWITCH_BANK (2);    mask = sysInByte (ioaddr + ESMC_INT_MASK);		/* save mask */unlucky:    while (((packetNo = sysInWord (ioaddr + ESMC_FIFO)) & ESMC_FP_RXEMPTY) == 0)	{        sysOutByte (ioaddr + ESMC_INT_MASK, 0);		/* lock INT */	sysOutWord (ioaddr + ESMC_PTR, 		    ESMC_PTR_READ | ESMC_PTR_RCV | ESMC_PTR_AUTOINC);	statusRx = sysInWord (ioaddr + ESMC_DATA_1);	/* status */	len	 = sysInWord (ioaddr + ESMC_DATA_1);	/* byte count */	len	 = (len & 0x07ff) - 6;			/* subtract extra */	if (statusRx & ESMC_RS_ERROR_MASK)	    {	    ++sc->es_if.if_ierrors;	    while (sysInWord (ioaddr + ESMC_MMU) & 0x0001) /* check busy bit */		;	    sysOutWord (ioaddr + ESMC_MMU, ESMC_MMU_RX_RELEASE); /* release */            sysOutByte (ioaddr + ESMC_INT_MASK, mask);	/* unlock INT */	    }	else	    {#if	ESMC_USE_LONG	    sysInLongString (ioaddr + ESMC_DATA_1, (long *)sc->pBuft, len >> 2);	    if (len & 0x02)	        *(short *)&sc->pBuft[len & ~0x03] = 		                              sysInWord (ioaddr + ESMC_DATA_1);	    *(short *)&sc->pBuft[len & ~0x01] = 		                              sysInWord (ioaddr + ESMC_DATA_1);#else	    sysInWordString (ioaddr + ESMC_DATA_1, (short *)sc->pBuft,		             (len>>1) + 1);#endif	/* ESMC_USE_LONG */	    if (statusRx & ESMC_RS_ODDFRM)		len++;	    while (sysInWord (ioaddr + ESMC_MMU) & 0x0001) /* check busy bit */		;	    sysOutWord (ioaddr + ESMC_MMU, ESMC_MMU_RX_RELEASE); /* release */            sysOutByte (ioaddr + ESMC_INT_MASK, mask);	/* unlock INT */#ifdef ESMC_DEBUG	    {	    int ix;	    int iy;	    printf ("packet=0x%x, status=0x%x, len=%d\n", 		    (packetNo >> 8) & 0x1f, statusRx, len);	    for (iy = 0; iy < 8; iy++)	        {                for (ix = 0; ix < 16; ix++)	            printf ("%2.2x ", (u_char)sc->pBuft[iy * 16 + ix]);	        printf ("\n");	        }	    }#endif	/* ESMC_DEBUG */            sc->es_if.if_ipackets++;        /* bump statistic */	    eh = (struct ether_header *)(sc->pBuft);            /* call input hook if any */            if ((etherInputHookRtn != NULL) &&	        (* etherInputHookRtn) (&sc->es_if, (char *) eh, len))	        {	        continue;	        }            if (len >= SIZEOF_ETHERHEADER)                len -= SIZEOF_ETHERHEADER;            else                {                sc->es_if.if_ierrors++;         /* bump error statistic */	        continue;                }            pData = ((unsigned char *) eh) + SIZEOF_ETHERHEADER;#ifdef BSD43_DRIVER            check_trailer (eh, pData, &len, &off, &sc->es_if);            /* copy data from the ring buffer to mbuf a long-word at a time */            m = bcopy_to_mbufs (pData, len, off, (struct ifnet *)&sc->es_if, 2);            if (m == NULL)                {                sc->es_if.if_ierrors++;        /* bump error statistic */	        continue;                }            do_protocol_with_type (eh->ether_type, m, &sc->es_ac, len);#else            /* copy data from the ring buffer to mbuf */            m = bcopy_to_mbufs (pData, len, off, (struct ifnet *)&sc->es_if, 2);            if (m == NULL)                {                sc->es_if.if_ierrors++;        /* bump error statistic */	        continue;                }            do_protocol (eh, m, &sc->es_ac, len);#endif	    }        }    sc->flags &= ~ESMC_RXING;    /* go back if we got an interrupt and a new packet */    if ((sysInByte (ioaddr + ESMC_INT_STAT) & (ESMC_INT_RCV | ESMC_INT_RX_OVRN))	 || (((sysInWord (ioaddr + ESMC_FIFO)) & ESMC_FP_RXEMPTY) == 0))	goto unlucky;    }/********************************************************************************* esmcGetInt - read a packet off the interface(Interrupt Level)** Copy packets from a RING into an mbuf and hand it to the next higher layer.** RETURNS: N/A*/LOCAL void esmcGetInt     (    int unit    )    {    FAST ESMC_SOFTC *sc = &esmc_softc[unit];    FAST int ioaddr     = sc->ioAddr;    int len;    int bufLen;    u_short statusRx;    u_short packetNo;    if ((sc->pIn > sc->pOut) && ((sc->pEnd - sc->pIn) < ESMC_BUFSIZE))	sc->pIn = sc->pStart;    if (((sc->pOut > sc->pIn) && ((sc->pOut - sc->pIn) < ESMC_BUFSIZE)) ||        (sc->packetLen[sc->indexIn] != 0))	return;    while (((packetNo = sysInWord (ioaddr + ESMC_FIFO)) & ESMC_FP_RXEMPTY) == 0)	{	sysOutWord (ioaddr + ESMC_PTR, 		    ESMC_PTR_READ | ESMC_PTR_RCV | ESMC_PTR_AUTOINC);	statusRx = sysInWord (ioaddr + ESMC_DATA_1);	/* status */	len	 = sysInWord (ioaddr + ESMC_DATA_1);	/* byte count */	len	 = (len & 0x07ff) - 6;			/* subtract extra */	if (statusRx & ESMC_RS_ERROR_MASK)	    {	    ++sc->es_if.if_ierrors;	    while (sysInWord (ioaddr + ESMC_MMU) & 0x0001) /* check busy bit */		;	    sysOutWord (ioaddr + ESMC_MMU, ESMC_MMU_RX_RELEASE); /* release */	    }	else	    {#if	ESMC_USE_LONG	    sysInLongString (ioaddr + ESMC_DATA_1, (long *)sc->pIn, len >> 2);	    if (len & 0x02)	        *(short *)&sc->pIn[len & ~0x03] = 					      sysInWord (ioaddr + ESMC_DATA_1);	    *(short *)&sc->pIn[len & ~0x01] = sysInWord (ioaddr + ESMC_DATA_1);#else	    sysInWordString (ioaddr + ESMC_DATA_1, (short *)sc->pIn, 			     (len>>1) + 1);#endif	/* ESMC_USE_LONG */	    if (statusRx & ESMC_RS_ODDFRM)		len++;	    while (sysInWord (ioaddr + ESMC_MMU) & 0x0001) /* check busy bit */		;	    sysOutWord (ioaddr + ESMC_MMU, ESMC_MMU_RX_RELEASE); /* release */	    if (len & 0x01)				/* buffer length */		bufLen = len + 1;	    else		bufLen = len + 2;	    sc->packetAddr[sc->indexIn] = sc->pIn;	/* packet address */	    sc->packetLen[sc->indexIn] = len;		/* packet length */	    sc->pIn += bufLen;				/* increment */	    sc->indexIn = (sc->indexIn + 1) % sc->nIndex;            if ((sc->pIn > sc->pOut) && ((sc->pEnd - sc->pIn) < ESMC_BUFSIZE))	        sc->pIn = sc->pStart;			/* wrap around */            if (((sc->pOut > sc->pIn) && ((sc->pOut - sc->pIn) < ESMC_BUFSIZE))		|| (sc->packetLen[sc->indexIn] != 0))	/* no space */	        break;	    }        }    }/********************************************************************************* esmcGetTask - read a packet off the interface(Task Level)** Copy packets from a RING into an mbuf and hand it to the next higher layer.** RETURNS: N/A*/LOCAL void esmcGetTask     (    int unit    )    {    FAST ESMC_SOFTC *sc = &esmc_softc[unit];    FAST struct ether_header *eh;    FAST struct mbuf *m;    int off;    int len;    int bufLen;    u_char * pData;    while ((len = sc->packetLen[sc->indexOut]) != 0)	{	eh = (struct ether_header *)(sc->packetAddr[sc->indexOut]);        sc->es_if.if_ipackets++;        /* bump statistic */        /* call input hook if any */        if ((etherInputHookRtn != NULL) &&	    (* etherInputHookRtn) (&sc->es_if, (char *) eh, len))	    continue;        if (len >= SIZEOF_ETHERHEADER)            len -= SIZEOF_ETHERHEADER;        else            {            sc->es_if.if_ierrors++;         /* bump error statistic */	    continue;            }

⌨️ 快捷键说明

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