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

📄 if_dc.c

📁 Tornado 2.0.2 source code!vxworks的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
    sz = ((dcNumRds + 1) * RMD_SIZ) + (dcNumRds * DC_BUFSIZ) +	 ((dcNumTds + 1) * TMD_SIZ) + (dcNumTds * DC_BUFSIZ) + 	 (DC_BUFSIZ * dcLPool) + FLTR_FRM_SIZE;    /* Establish a region of shared memory */    /*     * OK. We now know how much shared memory we need.  If the caller     * provides a specific memory region, we check to see if the provided     * region is large enough for our needs.  If the caller did not     * provide a specific region, then we attempt to allocate the memory     * from the system, using the cache aware allocation system call.     */    switch ((int) memAdrs)        {        default :       /* caller provided memory */            if (memSize < sz)     /* not enough space */                {                printf ("dc: not enough memory provided\n");                return (ERROR);                }            else                dcNumRds += (memSize - sz) / (DC_BUFSIZ + TMD_SIZ);            pShMem = memAdrs;             /* set the beginning of pool */            /* assume pool is cache coherent, copy null structure */            pDrvCtrl->cacheFuncs = cacheNullFuncs;            break;        case NONE :     /* get our own memory */            /*	     * Because the structures that are shared between the device             * and the driver may share cache lines, the possibility exists             * that the driver could flush a cache line for a structure and             * wipe out an asynchronous change by the device to a neighboring             * structure. Therefore, this driver cannot operate with memory             * that is not write coherent.  We check for the availability of             * such memory here, and abort if the system did not give us what             * we need.             */            if (!CACHE_DMA_IS_WRITE_COHERENT ())                {                printf ("dc: device requires cache coherent memory\n");                return (ERROR);                }            pShMem = (char *) cacheDmaMalloc (sz);            if ((int)pShMem == NULL)                {                printf ("dc: system memory unavailable\n");                return (ERROR);                }            /* copy the DMA structure */            pDrvCtrl->cacheFuncs = cacheDmaFuncs;            break;        }    SYS_INT_CONNECT(pDrvCtrl, dcInt, pDrvCtrl, &retVal);    if (retVal == ERROR)        return (ERROR);    /*           Turkey Carving     *           --------------     *     *             LOW MEMORY     * |-------------------------------------|     * |         The Rx descriptors          |     * | (dcNumRds * sizeof (DC_RDE))        |     * |-------------------------------------|     * |          The receive buffers        |     * |       (DC_BUFSIZ * dcNumRds)        |     * |-------------------------------------|     * |         The Rx loaner pool          |     * |        (DC_BUFSIZ * dcLPool)        |     * |-------------------------------------|     * |         The Tx descriptors          |     * | (dcNumTds *  sizeof (DC_TDE))       |     * |-------------------------------------|     * |           The transmit buffers      |     * |       (DC_BUFSIZ * dcNumTds)        |     * |-------------------------------------|     * |           Setup Filter Frame        |     * |           (FLTR_FRM_SIZE)           |     * |-------------------------------------|     */    /* zero the shared memory */    bzero ( (char *) pShMem, (int) sz );    /* carve Rx memory structure */    pDrvCtrl->rxRing = (DC_RDE *) (((int)pShMem + 0x03) & ~0x03); /* wd align */    pDrvCtrl->dcNumRds = dcNumRds;		/* receive ring size */    pDrvCtrl->rxIndex = 0;    /* Set up the Rx descriptors */    rmd = pDrvCtrl->rxRing;                      /* receive ring */    buf = (char *)(rmd + pDrvCtrl->dcNumRds);    for (ix = 0; ix < pDrvCtrl->dcNumRds; ix++, rmd++, buf += DC_BUFSIZ)        {        pTemp = DC_CACHE_VIRT_TO_PHYS (buf);	/* convert to PCI  phys addr */	pTemp = (void *)(MEM_TO_PCI_PHYS((ULONG)pTemp));	rmd->rDesc2 = PCISWAP((ULONG)pTemp);	/* buffer address 1 */	rmd->rDesc3 = 0;			/* no second buffer */	/* buffer size */	rmd->rDesc1 = PCISWAP(RDESC1_RBS1_VAL(DC_BUFSIZ) | 			      RDESC1_RBS2_VAL(0));	if (ix == (pDrvCtrl->dcNumRds - 1))	/* if its is last one */    	    rmd->rDesc1 |= PCISWAP(RDESC1_RER);	/* end of receive ring */	rmd->rDesc0 = PCISWAP(RDESC0_OWN);	/* give ownership to lance */        }    /* setup Rx loaner pool */    pDrvCtrl->nLoanRx = dcLPool;    for (ix = 0; ix < dcLPool; ix++, buf += DC_BUFSIZ)	{        pDrvCtrl->lPool[ix] = buf;        pDrvCtrl->refCnt[ix] = 0;        pDrvCtrl->pRefCnt[ix] = & pDrvCtrl->refCnt[ix];	}    /* carve Tx memory structure */    pDrvCtrl->txRing = (DC_TDE *) (((int)buf + 0x03) & ~0x03); /* word align */    pDrvCtrl->dcNumTds = dcNumTds;	/* transmit ring size */    pDrvCtrl->txIndex = 0;    pDrvCtrl->txDiIndex = 0;    /* Setup the Tx descriptors */    tmd = pDrvCtrl->txRing;                 /* transmit ring */    buf = (char *)(tmd + pDrvCtrl->dcNumTds);    for (ix = 0; ix < pDrvCtrl->dcNumTds; ix++, tmd++, buf += DC_BUFSIZ)        {        pTemp = DC_CACHE_VIRT_TO_PHYS (buf);	/* convert to PCI phys addr */	pTemp = (void *)(MEM_TO_PCI_PHYS((ULONG)pTemp));	tmd->tDesc2 = PCISWAP((ULONG)pTemp);	/* buffer address 1 */	tmd->tDesc3 = 0;			/* no second buffer */	tmd->tDesc1 = PCISWAP((TDESC1_TBS1_PUT(0) |			       TDESC1_TBS2_PUT(0) |			       TDESC1_IC	  | 	/* intrpt on xmit */			       TDESC1_LS          |	/* last segment */			       TDESC1_FS));		/* first segment */	if (ix == (pDrvCtrl->dcNumTds - 1))	/* if its is last one */	    tmd->tDesc1 |= PCISWAP(TDESC1_TER);	/* end of Xmit ring */	tmd->tDesc0 = 0 ;			/* clear status */        }    /* carve Setup Filter Frame buffer */        pDrvCtrl->pFltrFrm = (ULONG *)(((int)buf + 0x03) & ~0x03); /* word align */    buf += FLTR_FRM_SIZE;    /* Flush the write pipe */    CACHE_PIPE_FLUSH ();    /* Device Initialization */    dcChipReset (pDrvCtrl);			/* reset the chip */    pTemp = DC_CACHE_VIRT_TO_PHYS (pDrvCtrl->rxRing);    pTemp = (void *)(MEM_TO_PCI_PHYS((ULONG)pTemp));    DC_CSR_WRITE (devAdrs, CSR3, ((ULONG)pTemp));	/* recv descriptor */    pTemp = DC_CACHE_VIRT_TO_PHYS (pDrvCtrl->txRing);    pTemp = (void *)(MEM_TO_PCI_PHYS((ULONG)pTemp));    DC_CSR_WRITE (devAdrs, CSR4, ((ULONG)pTemp));	/* xmit descriptor */    /* get the ethernet address */    if (!DEC21140(pDrvCtrl->dcOpMode))    	{        if (dcEnetAddrGet (devAdrs, (char *) pDrvCtrl->idr.ac_enaddr, 6) != OK)	    logMsg ("dc: error reading ethernet rom\n", 0,0,0,0,0,0);    	}    else    	{        if (dc21140EnetAddrGet (devAdrs, (char *) pDrvCtrl->idr.ac_enaddr, 6) 	    != OK)	    logMsg ("dc21140: error reading ethernet rom\n", 0,0,0,0,0,0);    	}    if (!DEC21140(pDrvCtrl->dcOpMode))    	{        dc21040AuiTpInit (devAdrs);		/* configure AUI or 10BASE-T */	DC_CSR_WRITE (devAdrs, CSR6, 0x0);        pDrvCtrl->dcMediaBlocks.DontSwitch = 1;    	}    else    	{	DC_CSR_WRITE (devAdrs, CSR6, 0x0);        dc21140AuiMiiInit (pDrvCtrl, devAdrs, uTemp);    	}    if ((pDrvCtrl->dcOpMode & DC_FULLDUPLEX_FLAG) && 	(pDrvCtrl->dcOpMode != NONE))        DC_CSR_UPDATE (devAdrs, CSR6, CSR6_FD);    /* clear the status register */    DC_CSR_WRITE (devAdrs, CSR5, 0xffffffff);    /* set the operating mode to start Xmitter only */    DC_CSR_UPDATE (devAdrs, CSR6, (CSR6_ST | CSR6_BIT25));    if ((pDrvCtrl->dcOpMode & DC_ILOOPB_FLAG) &&	(pDrvCtrl->dcOpMode != NONE))        DC_CSR_UPDATE (devAdrs, CSR6, CSR6_OM_ILB);    else if ((pDrvCtrl->dcOpMode & DC_ELOOPB_FLAG) &&             (pDrvCtrl->dcOpMode != NONE))        DC_CSR_UPDATE (devAdrs, CSR6, CSR6_OM_ELB);    /* Xmit a Filter Setup Frame */    dcFltrFrmXmit (pDrvCtrl, (char *) pDrvCtrl->idr.ac_enaddr, 1);    /* start the receiver with multicast and promiscuous mode, if needed */    DC_CSR_UPDATE (devAdrs, CSR6,                   (CSR6_SR |                     ((pDrvCtrl->dcOpMode & DC_MULTICAST_FLAG) ? CSR6_PM: 0) |                    ((pDrvCtrl->dcOpMode & DC_PROMISCUOUS_FLAG) ? CSR6_PR: 0)));    /* set up the interrupts */    if (!DEC21140(pDrvCtrl->dcOpMode))    	DC_CSR_WRITE (devAdrs, CSR7, (			       CSR7_NIM |	/* normal interrupt mask */			       CSR7_AIM |	/* abnormal interrupt mask */			       CSR7_SEM |	/* system error mask */			       CSR7_RIM |	/* rcv  interrupt mask */			       CSR7_RUM	|	/* rcv buff unavailable mask */			       CSR7_TUM 	/* xmit buff unavailble mask */			       ));    else    	DC_CSR_WRITE (devAdrs, CSR7, (			       CSR7_NIM |	/* normal interrupt mask */			       CSR7_AIM |	/* abnormal interrupt mask */			       CSR7_SEM |	/* system error mask */			       CSR7_RIM |	/* rcv  interrupt mask */			       CSR7_RUM	|	/* rcv buff unavailable mask */			       CSR7_TUM 	/* xmit buff unavailble mask */			       ));    SYS_INT_ENABLE (pDrvCtrl);    pDrvCtrl->idr.ac_if.if_flags |= ((IFF_UP | IFF_RUNNING | IFF_NOTRAILERS) |                        ((dcOpMode & DC_PROMISCUOUS_FLAG) ? IFF_PROMISC : 0) |                        ((dcOpMode & DC_MULTICAST_FLAG) ? IFF_ALLMULTI : 0));    /* Set our flag */    pDrvCtrl->attached = TRUE;    pDrvCtrl->txFlushScheduled = FALSE;    return (OK);    }/********************************************************************************* dcReset - reset the interface** Mark interface as inactive & reset the chip*/LOCAL void dcReset    (    int unit    )    {    DRV_CTRL *pDrvCtrl = & drvCtrl [unit];    pDrvCtrl->idr.ac_if.if_flags = 0;    dcChipReset (pDrvCtrl);                           /* reset device */    }/********************************************************************************* dcInt - handle controller interrupt** This routine is called at interrupt level in response to an interrupt from* the controller.*/LOCAL void dcInt    (    DRV_CTRL *	pDrvCtrl	/* pointer to device control struct */    )    {    ULONG	stat;		/* status register */    ULONG	devAdrs;	/* device address */    devAdrs = pDrvCtrl->devAdrs;    /* Read the device status register */    stat = DC_CSR_READ (devAdrs, CSR5);    /* clear the interrupts */    DC_CSR_WRITE (devAdrs, CSR5, stat);    stat &= DC_CSR_READ (devAdrs, CSR7);    /* If false interrupt, return. */    if ( ! (stat & (CSR5_NIS | CSR5_AIS)) )         return;    /* Check for system error */    if (stat & CSR5_SE)        {        ++pDrvCtrl->idr.ac_if.if_ierrors;            /* restart chip on fatal error */        pDrvCtrl->idr.ac_if.if_flags &= ~(IFF_UP | IFF_RUNNING);            netJobAdd ((FUNCPTR)dcRestart, pDrvCtrl->idr.ac_if.if_unit, 0,0,0,0);        }        /* Have netTask handle any input packets */    if (stat & (CSR5_RI | CSR5_RU))        {        DC_INT_DISABLE (devAdrs, CSR7_RIM);        netJobAdd ((FUNCPTR)dcHandleRecvInt, (int)pDrvCtrl, 0, 0, 0, 0);        }    if ((stat & CSR5_TU) && pDrvCtrl->idr.ac_if.if_snd.ifq_len &&        (! pDrvCtrl->txFlushScheduled))        {        pDrvCtrl->txFlushScheduled = TRUE;        netJobAdd ((FUNCPTR) dcTxFlush, (int) pDrvCtrl, 0, 0, 0, 0);        }    return;    }/********************************************************************************* dcHandleRecvInt - 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.*/LOCAL void dcHandleRecvInt    (    DRV_CTRL *	pDrvCtrl	/* pointer to device control struct */    )    {    DC_RDE *	rmd;		/* pointer to Rx ring descriptor */    while ((rmd = dcGetFullRMD (pDrvCtrl)) != NULL)        dcRecv (pDrvCtrl, rmd);    DC_INT_ENABLE (pDrvCtrl->devAdrs, CSR7_RIM);    while ((rmd = dcGetFullRMD (pDrvCtrl)) != NULL)        dcRecv (pDrvCtrl, rmd);#ifdef DC_DEBUG    pDrvCtrl->errStats.rxMissed += (DC_CSR_READ (pDrvCtrl->devAdrs, CSR8) &                                    (CSR8_MFO | CSR8_MFC_MSK));#endif /* DC_DEBUG */    return;    }/********************************************************************************* dcTxRingClean - cleans up the transmit ring** This routine is called at task level in the context of dcOutput() or* tNetTask by dcTxFlush() to collect statistics, and mark "free" all* descriptors consumed by the device.*/LOCAL void dcTxRingClean    (    DRV_CTRL *pDrvCtrl    )    {    DC_TDE *    tmd;            /* pointer to Xmit ring descriptor */    while (pDrvCtrl->txDiIndex != pDrvCtrl->txIndex)        {        /* disposal has not caught up */        tmd = pDrvCtrl->txRing + pDrvCtrl->txDiIndex;        /* if the buffer is still owned by device, don't touch it */        DC_CACHE_INVALIDATE (tmd, TMD_SIZ);

⌨️ 快捷键说明

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