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

📄 if_dc.c

📁 Tornado 2.0.2 source code!vxworks的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
        if (tmd->tDesc0 & PCISWAP(TDESC0_OWN))            break;        /* now bump the tmd disposal index pointer around the ring */        pDrvCtrl->txDiIndex = (pDrvCtrl->txDiIndex + 1) % pDrvCtrl->dcNumTds;        pDrvCtrl->txCount--;#ifdef DC_DEBUG        {        UINT		tdesc0 = PCISWAP(tmd->tDesc0);        DC_STATS *	pErrStats = &pDrvCtrl->errStats;        if (tdesc0 & TDESC0_TO)            pErrStats->txJbrTmo++;        if (tdesc0 & TDESC0_LO)            pErrStats->txLostCarrier++;        if (tdesc0 & TDESC0_NC)            pErrStats->txNoCarrier++;        if (tdesc0 & TDESC0_LC)            pErrStats->txLateCollision++;        if (tdesc0 & TDESC0_HF)            pErrStats->txHeartBeatFail++;        if (tdesc0 & TDESC0_LF)            pErrStats->txLinkFail++;        if (tdesc0 & TDESC0_UF)            pErrStats->txUnderflow++;        if (tdesc0 & TDESC0_DE)            pErrStats->txDeferred++;        }#endif /* DC_DEBUG */        /*         * TDESC0_ES is an "OR" of LC, NC, UF, EC.         * here for error conditions.         */        if (tmd->tDesc0 & PCISWAP(TDESC0_ES)) 	    {            /* check for no carrier */#if 0  /* HELP */            if ((tmd->tDesc0 & PCISWAP(TDESC0_NC | TDESC0_LO | TDESC0_LF)) &&                (pDrvCtrl->dcMediaBlocks.DontSwitch == 0)) 		{		dcSelectMedia (pDrvCtrl);		return;		}            pDrvCtrl->dcMediaBlocks.DontSwitch = 1;#endif            pDrvCtrl->idr.ac_if.if_oerrors++;     /* output error */            pDrvCtrl->idr.ac_if.if_opackets--;            /*	     * If error was due to excess collisions, bump the collision             * counter.             */            if (tmd->tDesc0 & PCISWAP(TDESC0_EC)) 		pDrvCtrl->idr.ac_if.if_collisions += 16;	    /* bump the collision counter if late collision */	    if (tmd->tDesc0 & PCISWAP(TDESC0_LC)) 		pDrvCtrl->idr.ac_if.if_collisions++;	    /* check for no carrier */#if 0 /* HELP */	    if (tmd->tDesc0 & PCISWAP(TDESC0_NC | TDESC0_LO | TDESC0_LF)) 		{		logMsg ("dc%d: no carrier\n",			pDrvCtrl->idr.ac_if.if_unit, 0,0,0,0,0);		dcSelectMedia (pDrvCtrl);		}#endif            /*	     * Restart chip on fatal errors.             * The following code handles the situation where the transmitter             * shuts down due to an underflow error.  This is a situation that             * will occur if the DMA cannot keep up with the transmitter.             * It will occur if the device is being held off from DMA access             * for too long or due to significant memory latency.  DRAM             * refresh or slow memory could influence this.  Many             * implementation use a dedicated device buffer.  This can be             * static RAM to eliminate refresh conflicts; or dual-port RAM             * so that the device can have free run of this memory during its             * DMA transfers.             */            if (tmd->tDesc0 & PCISWAP(TDESC0_UF))                {                pDrvCtrl->idr.ac_if.if_flags &= ~(IFF_UP | IFF_RUNNING);                netJobAdd ((FUNCPTR)dcRestart, pDrvCtrl->idr.ac_if.if_unit,                           0,0,0,0 );                return;                }            }	tmd->tDesc0 = 0;	/* clear all error & stat stuff */        }    /* Flush the write pipe */    CACHE_PIPE_FLUSH ();    }/********************************************************************************* dcGetFullRMD - get next received message RMD** Returns ptr to next Rx desc to process, or NULL if none ready.*/LOCAL DC_RDE * dcGetFullRMD    (    DRV_CTRL *	pDrvCtrl	/* pointer to device control struct */    )    {    DC_RDE *	rmd;		/* pointer to Rx ring descriptor */    /* Refuse to do anything if flags are down */    if  (        (pDrvCtrl->idr.ac_if.if_flags & (IFF_UP | IFF_RUNNING) ) !=        (IFF_UP | IFF_RUNNING)        )        return ((DC_RDE *) NULL);    rmd = pDrvCtrl->rxRing + pDrvCtrl->rxIndex;       /* form ptr to Rx desc */    DC_CACHE_INVALIDATE (rmd, RMD_SIZ);    if ((rmd->rDesc0 & PCISWAP(RDESC0_OWN)) == 0)        return (rmd);    else        return ((DC_RDE *) NULL);    }/********************************************************************************* dcRecv - process the next incoming packet**/LOCAL STATUS dcRecv    (    DRV_CTRL *	pDrvCtrl,	/* pointer to device control struct */    DC_RDE *	rmd		/* pointer to Rx ring descriptor */    )    {    ENET_HDR *	pEnetHdr;	/* pointer to ethernet header */    MBUF *	pMbuf = NULL;	/* pointer to mbuf */    u_long	pPhys;    UCHAR *	pData;		/* pointer to data */    int		len;		/* length */    USHORT	ether_type;	/* ether packet type */#ifdef DC_DEBUG    UINT32	rdesc0;		/* desc0 status word */#endif /* DC_DEBUG */#ifdef DC_DEBUG    rdesc0 = rmd->rDesc0;    if (rdesc0 & PCISWAP(0x40000000))        pDrvCtrl->errStats.rxFiltrErr++;        if (rdesc0 & PCISWAP(0x00004000))        pDrvCtrl->errStats.rxDescErr++;            if  (rdesc0 & PCISWAP(RDESC0_RF))        pDrvCtrl->errStats.rxRuntFrm++;    if  (rdesc0 & PCISWAP(RDESC0_TL))        pDrvCtrl->errStats.rxTooLong++;    if  (rdesc0 & PCISWAP(RDESC0_CS))        pDrvCtrl->errStats.rxCollision++;    if  (rdesc0 & PCISWAP(0x00000008))        pDrvCtrl->errStats.rxMiiErr++;    if  (rdesc0 & PCISWAP(RDESC0_DB))        pDrvCtrl->errStats.rxDribbleBit++;    if  (rdesc0 & PCISWAP(RDESC0_CE))        pDrvCtrl->errStats.rxCrcErr++;#endif /* DC_DEBUG */    /* Discard if we have errors */    if  (rmd->rDesc0 & PCISWAP(RDESC0_ES))        {        ++pDrvCtrl->idr.ac_if.if_ierrors;       /* bump error stat */        goto cleanRXD;        }    /* Process clean packets */    ++pDrvCtrl->idr.ac_if.if_ipackets;		/* bump statistic */    len = RDESC0_FL_GET(PCISWAP(rmd->rDesc0));	/* frame length */    len -= 4; 	/* Frame length includes CRC in it so subtract it */    /* Get pointer to packet */    pEnetHdr = DC_CACHE_PHYS_TO_VIRT(PCI_TO_MEM_PHYS(PCISWAP(rmd->rDesc2)));    DC_CACHE_INVALIDATE (pEnetHdr, len);   /* make the packet data coherent */    /* call input hook if any */    if ((etherInputHookRtn == NULL) || ((*etherInputHookRtn)       (& pDrvCtrl->idr.ac_if, (char *) pEnetHdr, len)) == 0)        {        /* Adjust length to size of data only */        len -= SIZEOF_ETHERHEADER;        /* Get pointer to packet data */        pData = ((u_char *) pEnetHdr) + SIZEOF_ETHERHEADER;        ether_type = ntohs ( pEnetHdr->type );        /* OK to loan out buffer ? -> build an mbuf cluster */    	if ((pDrvCtrl->nLoanRx > 0) && (USE_CLUSTER (len))	    && (pMbuf = BUILD_CLUSTER (pDrvCtrl, pEnetHdr, pData, len)))	    {            pPhys = (u_long) DC_CACHE_VIRT_TO_PHYS(MEM_TO_PCI_PHYS(		    (pDrvCtrl->lPool[--pDrvCtrl->nLoanRx])));	    rmd->rDesc2 = PCISWAP(pPhys);	    }        else            {            if ((pMbuf = bcopy_to_mbufs (pData, len, 0, & pDrvCtrl->idr.ac_if,                pDrvCtrl->memWidth)) == NULL)		{                ++pDrvCtrl->idr.ac_if.if_ierrors;	/* bump error stat */                goto cleanRXD;		}            }        /* send on up... */        do_protocol_with_type (ether_type, pMbuf, &pDrvCtrl->idr, len);        }    /* Done with descriptor, clean up and give it to the device. */cleanRXD:    /* clear status bits and give ownership to device */    rmd->rDesc0 = PCISWAP(RDESC0_OWN);    /* Flush the write pipe */    CACHE_PIPE_FLUSH ();    /* Advance our management index */    pDrvCtrl->rxIndex = (pDrvCtrl->rxIndex + 1) % pDrvCtrl->dcNumRds;    return (OK);    }#ifdef BSD43_DRIVER/********************************************************************************* dcOutput - driver output routine** This routine is called by the stack to transmit an mbuf.* This routine is called by the stack to transmit an mbuf.*/LOCAL int dcOutput    (    IDR  *	pIDR,		/* pointer to interface data record */    MBUF *	pMbuf,		/* pointer to mbuf */    SOCK *	pDest		/* pointer to destination sock */    )    {    int 	unit = ((IFNET *)pIDR)->if_unit;    DRV_CTRL *	pDrvCtrl = &drvCtrl[unit];    int		errorVal;    errorVal =  ether_output ((IFNET *)pIDR, pMbuf, pDest,                               (FUNCPTR) dcStartOutput, pIDR);    if ((errorVal == ENOBUFS) && !pDrvCtrl->txFlushScheduled)        {#ifdef DC_DEBUG        pDrvCtrl->errStats.txDropped++;#endif /* DC_DEBUG */        dcTxFlush (pDrvCtrl);        }        return (errorVal);    }#endif /* BSD43_DRIVER *//********************************************************************************* dcTxFlush - flush enqueued transmit buffers**/LOCAL void dcTxFlush    (    DRV_CTRL *	pDrvCtrl    )    {    int		retry;    int		delayCount;#ifdef DC_DEBUG    pDrvCtrl->errStats.txFlushCalled++;    if (pDrvCtrl->idr.ac_if.if_snd.ifq_len)        pDrvCtrl->errStats.txFlushNeeded++;#endif /* DC_DEBUG */    retry = DC_FLUSH_RETRIES;    while (pDrvCtrl->idr.ac_if.if_snd.ifq_len && retry)        {        dcTxRingClean (pDrvCtrl);        if (DC_TD_INDEX_NEXT(pDrvCtrl) != pDrvCtrl->txDiIndex)            DC_START_OUTPUT (pDrvCtrl);        else            {            for (delayCount=1000; delayCount--;)                ;            retry--;            }        }#ifdef DC_DEBUG    if (pDrvCtrl->idr.ac_if.if_snd.ifq_len == 0)        pDrvCtrl->errStats.txFlushDone++;#endif /* DC_DEBUG */    pDrvCtrl->txFlushScheduled = FALSE;    }    /********************************************************************************* dcStartOutput - send transmit buffers**/LOCAL void dcStartOutput    (#   ifdef BSD43_DRIVER    int unit#   else    DRV_CTRL *	pDrvCtrl#   endif /* BSD43_DRIVER */    )    {#   ifdef BSD43_DRIVER        DRV_CTRL *	pDrvCtrl = &drvCtrl[unit];#   endif /* BSD43_DRIVER */        DC_TDE *	pTxD;    MBUF *	pMbuf;    char * 	pTxdBuf;    int		bufLen;    int		retries;#ifdef DC_DEBUG    pDrvCtrl->errStats.txQsizeCur=pDrvCtrl->idr.ac_if.if_snd.ifq_len;#endif /* DC_DEBUG */    retries = MAX_TX_RETRIES;    while (pDrvCtrl->idr.ac_if.if_snd.ifq_len && retries)        {        pTxD = pDrvCtrl->txRing + pDrvCtrl->txIndex;        if  (((pTxD->tDesc0 & PCISWAP(TDESC0_OWN)) != 0) ||             (DC_TD_INDEX_NEXT (pDrvCtrl) == pDrvCtrl->txDiIndex))            {            dcTxRingClean (pDrvCtrl);#ifdef DC_DEBUG            pDrvCtrl->errStats.txRetries++;#endif /* DC_DEBUG */            retries--;            continue;            }        retries = MAX_TX_RETRIES;                /* Get pointer to transmit buffer */        pTxdBuf = (char *)DC_CACHE_PHYS_TO_VIRT(PCI_TO_MEM_PHYS(        			PCISWAP(pTxD->tDesc2)));        IF_DEQUEUE (&pDrvCtrl->idr.ac_if.if_snd, pMbuf);        /* copy stuff */        bcopy_from_mbufs (pTxdBuf, pMbuf, bufLen, pDrvCtrl->memWidth);        pTxD->tDesc0  = 0;		/* clear buffer error status */        pTxD->tDesc1 &= PCISWAP (~TDESC1_TBS1_MSK);        pTxD->tDesc1 |= PCISWAP (TDESC1_TBS1_PUT(max (ETHERSMALL, bufLen)));        pTxD->tDesc0  = PCISWAP (TDESC0_OWN);  /* give ownership to device */        CACHE_PIPE_FLUSH ();		/* Flush the write pipe */        /* Advance our management index */        pDrvCtrl->txIndex = DC_TD_INDEX_NEXT (pDrvCtrl);

⌨️ 快捷键说明

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