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

📄 if_dcfast.c

📁 IXP425的BSP代码
💻 C
📖 第 1 页 / 共 5 页
字号:
ULONG	dcCSR0Bmr	= 0;/* locals */LOCAL DRV_CTRL  drvCtrl [MAX_UNITS];	/* array of driver control structs */LOCAL int	dcNumRds  = NUM_RDS;	/* number of ring descriptors */LOCAL int	dcNumTds  = NUM_TDS;	/* number of xmit descriptors */LOCAL int 	dcLPool = DC_L_POOL;/* forward static functions */LOCAL void 	dcReset (int unit);LOCAL void 	dcInt (DRV_CTRL *pDrvCtrl);LOCAL void 	dcHandleRecvInt (DRV_CTRL *pDrvCtrl);LOCAL STATUS 	dcRecv (DRV_CTRL *pDrvCtrl, DC_RDE *rmd);LOCAL int 	dcOutput (IDR *ifp, MBUF *m0, SOCK *dst);LOCAL int 	dcIoctl (IDR *ifp, int cmd, caddr_t data);LOCAL int 	dcChipReset (DRV_CTRL *pDrvCtrl);LOCAL DC_RDE *	dcGetFullRMD (DRV_CTRL *pDrvCtrl);LOCAL void	dcAuiTpInit (ULONG devAdrs);LOCAL void 	dcCsrWrite (ULONG devAdrs, int reg, ULONG value);LOCAL ULONG 	dcCsrRead (ULONG devAdrs, int reg);LOCAL void 	dcRestart (int unit);LOCAL STATUS 	dcEnetAddrGet (ULONG devAdrs, char * enetAdrs, int len);LOCAL STATUS 	dc21140EnetAddrGet (ULONG devAdrs, char * enetAdrs, int len);LOCAL BOOL 	convertDestAddr (IDR * pIDR, SOCK * pDestSktAddr,				 char * pDestEnetAddr, u_short * pPacketType,				 MBUF * pMbuf);LOCAL void 	dcLoanFree (DRV_CTRL *pDrvCtrl, char *pRxBuf, UINT8 *pRef);LOCAL int	dcFltrFrmSetup (DRV_CTRL * pDrvCtrl, char * pPhysAdrsTbl, 				int tblLen);LOCAL int	dcFltrFrmXmit (DRV_CTRL * pDrvCtrl, char * pPhysAdrsTbl,			       int tblLen);#ifdef DC_DEBUGvoid dcCsrShow (ULONG devAdrs);#endif /* DC_DEBUG *//* RCP: Add utilities to read entries in Serial ROM for DEC21140 */USHORT dcReadRom (ULONG devAdrs, UCHAR lineCnt);int dcViewRom (ULONG devAdrs, UCHAR lineCnt, int cnt);/* RCP: Temporary reference of new global symbol */LOCAL STATUS sysLanIntEnable (int Level);/********************************************************************************* dcattach - publish the `dc' network interface.** This routine publishes the `dc' interface by filling in a network interface* record and adding this record to the system list.  This routine also* initializes the driver and the device to the operational state.** The <unit> parameter is used to specify the device unit to initialize.** The <devAdrs> is used to specify the I/O address base of the device.** The <ivec> parameter is used to specify the interrupt vector associated* with the device interrupt.** The <ilevel> parater is used to specify the level of the interrupt which* the device would use.** The <memAdrs> parameter can be used to specify the location of the* memory that will be shared between the driver and the device.  The value* NONE is used to indicate that the driver should obtain the memory.** The <memSize> parameter is valid only if the <memAdrs> parameter is not* set to NONE, in which case <memSize> indicates the size of the* provided memory region.** The <memWidth> parameter sets the memory pool's data port width (in bytes);* if it is NONE, any data width is used.** The <pciMemBase> parameter defines the main memory base as seen from PCI bus.* * The <dcOpMode> parameter defines the mode in which the device should be* operational.** RCP:  Added for DEC21140 Serial ROM** BUGS* To zero out LANCE data structures, this routine uses bzero(), which* ignores the <memWidth> specification and uses any size data access to* write to memory.** RETURNS: OK or ERROR.*/STATUS dcattach    (    int		unit,		/* unit number */    ULONG	devAdrs,	/* LANCE I/O address */    int		ivec,		/* interrupt vector */    int		ilevel,		/* interrupt level */    char *	memAdrs,	/* address of memory pool (-1 = malloc it) */    ULONG	memSize,	/* only used if memory pool is NOT malloc()'d */    int		memWidth,	/* byte-width of data (-1 = any width) */    ULONG	pciMemBase,	/* main memory base as seen from PCI bus */    int		dcOpMode	/* mode of operation */    )    {    DRV_CTRL *		pDrvCtrl;	/* pointer to drvctrl */    unsigned int	sz;		/* temporary size holder */    char *		pShMem;		/* start of the LANCE memory pool */    char *		buf;		/* temp buffer pointer */    void *		pTemp;		/* temp pointer */    DC_RDE *		rmd;		/* pointer to rcv descriptor */    DC_TDE *		tmd;		/* pointer to xmit descriptor */    int			ix;		/* counter *//* RCP: Added temporary value */    ULONG		uTemp;		/* temporary storage */        /* Sanity check the unit number */    if (unit < 0 || unit >= MAX_UNITS)        return (ERROR);    /* Ensure single invocation per system life */    pDrvCtrl = & drvCtrl [unit];    if (pDrvCtrl->attached)        return (OK);    pDrvCtrl->ivec	= ivec;			/* interrupt vector */    pDrvCtrl->ilevel	= ilevel;		/* interrupt level */    pDrvCtrl->devAdrs	= devAdrs;		/* LANCE I/O address */    pDrvCtrl->pciMemBase  = pciMemBase;		/* pci memory base */    pDrvCtrl->memWidth 	= memWidth;		/* memory width */    pDrvCtrl->dcOpMode	= dcOpMode;		/* mode of operation */    /* Publish the interface data record */    ether_attach (		  & pDrvCtrl->idr.ac_if,		  unit,		  "dc",		  (FUNCPTR) NULL,		  (FUNCPTR) dcIoctl,		  (FUNCPTR) dcOutput,		  (FUNCPTR) dcReset		 );    /* Create the transmit semaphore. */    if ((pDrvCtrl->TxSem = semMCreate (SEM_Q_PRIORITY | SEM_DELETE_SAFE |				       SEM_INVERSION_SAFE)) == NULL)        {        printf ("dc: error creating transmitter semaphore\n");        return (ERROR);        }    /* Establish size of shared memory region we require */        if ((int) memAdrs != NONE)  /* specified memory pool */	{	sz  = (memSize - (RMD_SIZ + TMD_SIZ + (dcLPool * DC_BUFSIZ) + 			  FLTR_FRM_SIZE))	      / ((2 * DC_BUFSIZ) + RMD_SIZ + TMD_SIZ);	dcNumRds = max (sz, MIN_RDS);	dcNumTds = max (sz, MIN_TDS);	}    /* add it all up - allow for alignment adjustment */    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 );                }            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;        }    if (intConnect ((VOIDFUNCPTR *)INUM_TO_IVEC(ivec),dcInt,(int)pDrvCtrl)        == 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));    dcCsrWrite (devAdrs, CSR3, ((ULONG)pTemp));	/* recv descriptor */    pTemp = DC_CACHE_VIRT_TO_PHYS (pDrvCtrl->txRing);    pTemp = (void *)(MEM_TO_PCI_PHYS((ULONG)pTemp));    dcCsrWrite (devAdrs, CSR4, ((ULONG)pTemp));	/* xmit descriptor */    /* get the ethernet address *//* RCP: If DEC21140 make an alternate call */    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/* Get the ethernet address for the DEC21140 */    {       if (dc21140EnetAddrGet (devAdrs, (char *) pDrvCtrl->idr.ac_enaddr, 6) 	   != OK)	   logMsg ("dc21140: error reading ethernet rom\n", 0,0,0,0,0,0);    }/* RCP: Check to see if Full Duplex mode set */    if ((pDrvCtrl->dcOpMode & DC_FULLDUPLEX_FLAG) && 	(pDrvCtrl->dcOpMode != NONE))    	dcCsrWrite (devAdrs, CSR6, (dcCsrRead(devAdrs, CSR6) | CSR6_FD));/* RCP: DEC21040 Specific Setup */    if (!DEC21140(pDrvCtrl->dcOpMode))    {        dcAuiTpInit (devAdrs);			/* configure AUI or 10BASE-T *//* RCP: Added initialization of CSR6 to turn off Promiscuous and Multicast */	dcCsrWrite (devAdrs, CSR6, 0x0);    }    else    {/* RCP: DEC21140 Setup - these modes must be set before start Xmitter *//* Default to 10BT */    	uTemp = dcCsrRead(devAdrs, CSR6);        uTemp = uTemp | CSR6_TTM | CSR6_BIT25;/* Now verify the parameters passed to configure the interface further */   	if ((pDrvCtrl->dcOpMode & DC_100_MB_FLAG) &&	    (pDrvCtrl->dcOpMode != NONE))	{/* Hard Coded values from SROM offset to start 100MB testing.  The actual code should   be imbellished to handle the configuration for other possible interfaces other then   100BaseTx.  This information will be stored in the DC21140 Info Leaf of the SROM.   In the case of the DEC520-AA PMC, the starting offset for the DEC21140 Info Leaf   is 0x41.  This location contains some basic capabilities of the interface and the   initial state of CSR12.  Also there is a block count for the total number of interfaces   supported by the interface card.  For testing the default values for the SYM_SCR    (100MBaseTx) port will be used.  The information for this interface starts in offset   0x49. The configuration for Full Duplex starts in offset 0x4D.  Potentially the driver   could be altered to do some autosensing and configuration, but for now arguments will   be passed to the driver to configure it.*/

⌨️ 快捷键说明

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