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

📄 if_ln.c

📁 Tornado 2.0.2 source code!vxworks的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
#ifdef __STDC__LOCAL void lnReset (int unit);LOCAL void lnInt (DRV_CTRL *pDrvCtrl);LOCAL void lnHandleRecvInt (DRV_CTRL *pDrvCtrl);LOCAL STATUS lnRecv (DRV_CTRL *pDrvCtrl);#ifdef BSD43_DRIVERLOCAL int lnOutput (IDR *ifp, MBUF *m0, SOCK *dst);#elseLOCAL void lnStartOutput (DRV_CTRL *	pDrvCtrl);#endif /* BSD43_DRIVER */LOCAL int lnIoctl (IDR *ifp, int cmd, caddr_t data);LOCAL void lnChipReset (DRV_CTRL *pDrvCtrl);LOCAL BOOL lnGetFullRMD (DRV_CTRL *pDrvCtrl);LOCAL u_short lnCsr0Read (DRV_CTRL * pDrvCtrl);LOCAL void lnCsr0Write (DRV_CTRL * pDrvCtrl, u_short value);LOCAL void lnCsrWrite (DRV_CTRL * pDrvCtrl, int reg, u_short value);LOCAL void lnRestart (int unit);LOCAL void lnRestartSetup (DRV_CTRL * pDrvCtrl);#ifdef BSD43_DRIVERLOCAL BOOL convertDestAddr (IDR *pIDR, SOCK *pDestSktAddr, char *pDestEnetAddr,			     u_short *pPacketType, MBUF *pMbuf);#endif /* BSD43_DRIVER */LOCAL void lnLoanFree (DRV_CTRL *pDrvCtrl, char *pRxBuf, UINT8 *pRef);#else	/* __STDC__ */LOCAL void lnReset ();LOCAL void lnInt ();LOCAL void lnHandleRecvInt ();LOCAL STATUS lnRecv ();#ifdef BSD43_DRIVERLOCAL int lnOutput ();#elseLOCAL void lnStartOutput ();#endif /* BSD43_DRIVER */LOCAL int lnIoctl ();LOCAL void lnChipReset ();LOCAL BOOL lnGetFullRMD ();LOCAL u_short lnCsr0Read ();LOCAL void lnCsr0Write ();LOCAL void lnCsrWrite ();LOCAL void lnRestart ();LOCAL BOOL convertDestAddr ();LOCAL void lnLoanFree ();#endif	/*  __STDC__ *//********************************************************************************* lnattach - publish the `ln' network interface and initialize driver structures** This routine publishes the `ln' 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 <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.** 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 lnattach    (    int       unit,		/* unit number */    char     *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)     */    int       spare,		/* not used */    int       spare2		/* not used */    )    {    DRV_CTRL     *pDrvCtrl;    char         *pShMem;	/* start of the LANCE memory pool */    char         *buf;    ln_rmd       *rmd;    unsigned int sz;    int          ix;    /* 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);    /* publish the interface data record */#ifdef BSD43_DRIVER    ether_attach (& pDrvCtrl->idr.ac_if, unit, "ln", (FUNCPTR) NULL,                  (FUNCPTR) lnIoctl, (FUNCPTR) lnOutput, (FUNCPTR) lnReset);#else    /* Publish the interface record */    ether_attach    (                    (IFNET *) & pDrvCtrl->idr,                    unit,                    "ln",                    (FUNCPTR) NULL,                    (FUNCPTR) lnIoctl,                    (FUNCPTR) ether_output, /* generic ether_output */                    (FUNCPTR) lnReset                    );    pDrvCtrl->idr.ac_if.if_start = (FUNCPTR)lnStartOutput;#endif    /* create the transmit semaphore. */    if ((pDrvCtrl->TxSem = semMCreate (SEM_Q_PRIORITY | SEM_DELETE_SAFE |	SEM_INVERSION_SAFE)) == NULL)        {        printf ("ln: error creating transmitter semaphore\n");        return (ERROR);        }    /* establish size of shared memory region we require */    if ((int) memAdrs != NONE)  /* specified memory pool */        {        /* we want to maximize lnRsize and lnTsize */        sz = (memSize - (RMD_SIZ + TMD_SIZ + (lnLPool * LN_BUFSIZ) +	     IB_SIZ)) / ((2 * LN_BUFSIZ) + RMD_SIZ + TMD_SIZ);        sz >>= 1;		/* adjust for roundoff */        for (lnRsize = 0; sz != 0; lnRsize++, sz >>= 1)            ;        lnTsize = lnRsize;	/* lnTsize = lnRsize for convenience */        }    /* limit ring sizes to reasonable values */    lnRsize = max (lnRsize, 2);		/* 4 Rx buffers is reasonable min */    lnRsize = min (lnRsize, 7);		/* 128 Rx buffers is max for chip */    lnTsize = max (lnTsize, 2);		/* 4 Tx buffers is reasonable min */    lnTsize = min (lnTsize, 7);		/* 128 Tx buffers is max for chip */    lnLPool = min (lnLPool, LN_L_POOL);	/* L_POOL is max for Rx loaner pool */    /* add it all up - allow extra bytes for alignment adjustments */    sz = (((1 << lnRsize) + 1) * RMD_SIZ ) + (LN_BUFSIZ << lnRsize) +	 (((1 << lnTsize) + 1) * TMD_SIZ ) + (LN_BUFSIZ << lnTsize) +	 (LN_BUFSIZ * lnLPool) + IB_SIZ + 24;    /* 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 ( "ln: 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 ( "ln: device requires cache coherent memory\n" );                return (ERROR);                }            pShMem = (char *) cacheDmaMalloc (sz);            if ((int) pShMem == NULL)                {                printf ( "ln: system memory unavailable\n" );                return (ERROR);                }            /* copy the DMA structure */            pDrvCtrl->cacheFuncs = cacheDmaFuncs;            break;        }    /* Align pool on 4 byte boundary - uses up to 8 bytes of excess memory. */    pShMem = (char *) ( ( (int)pShMem + 3) & ~3);    /* save some things */    pDrvCtrl->flags    = 0;			/* initialize the LANCE flags */    pDrvCtrl->memWidth = memWidth;    pDrvCtrl->ivec     = ivec;                  /* interrupt vector */    pDrvCtrl->ilevel   = ilevel;                /* interrupt level */    pDrvCtrl->devAdrs  = (LN_DEVICE *) devAdrs; /* LANCE I/O address */    pDrvCtrl->pMemPool = pShMem;                /* start of memory pool */    /* obtain our Ethernet address and save it */    bcopy ((char *) lnEnetAddr, (char *) pDrvCtrl->idr.ac_enaddr, 6);    /*     *                        MEMORY MAPPING     *     *                          low memory     *     *             |-------------------------------------|     *             |       The initialization block      |     *             |              (IB_SIZ)               |     *             |-------------------------------------|     *             |         The Rx descriptors          |     *             |   ((1 << lnRsize) + 1) * RMD_SIZ    |     *             |-------------------------------------|     *             |          The receive buffers        |     *             |       (LN_BUFSIZ << lnRsize)        |     *             |-------------------------------------|     *             |         The Rx loaner pool          |     *             |        (LN_BUFSIZ * lnLPool)        |     *             |-------------------------------------|     *             |         The Tx descriptors          |     *             |    ((1 << lnTsize) + 1)* TMD_SIZ    |     *             |-------------------------------------|     *             |        The transmit buffers         |     *             |       (LN_BUFSIZ << lnTsize)        |     *             |-------------------------------------|     */    /* first let's clear memory */    bzero ((char *) pShMem, (int) sz); /* XXX deal with memWidth */    /* carve Rx memory structure */    pDrvCtrl->rring     = (ln_rmd *) ((int)pShMem + IB_SIZ);    pDrvCtrl->rringLen  = lnRsize;    pDrvCtrl->rringSize = 1 << lnRsize;    pDrvCtrl->rmdIndex	= 0;    /* setup Rx buffer descriptors */    rmd = pDrvCtrl->rring;    /*      * Set the Rx buffer misaligned so that the ether header will align the     * IP header on a 4 byte boundary.      */    buf = ( (char *) (rmd + (pDrvCtrl->rringSize +1))) + 2;    /* Skip over the receive buffer pool to the Rx loaner pool. */    buf += LN_BUFSIZ << lnRsize;    /* setup Rx loaner pool */    pDrvCtrl->nLoanRx = lnLPool;    for (ix = 0; ix < lnLPool; ix++)	{        pDrvCtrl->lPool[ix] = buf + (ix * LN_BUFSIZ);        pDrvCtrl->refCnt[ix] = 0;        pDrvCtrl->pRefCnt[ix] = & pDrvCtrl->refCnt[ix];	}    /* carve Tx memory structure */    /* Note: +2 offset aligns IP header on 4 byte boundary. */         pDrvCtrl->tring     = (ln_tmd *)(buf + (ix * LN_BUFSIZ) + 2);    pDrvCtrl->tringLen  = lnTsize;    pDrvCtrl->tringSize = 1 << lnTsize;    pDrvCtrl->tmdIndex	= 0;    pDrvCtrl->tmdIndexC	= 0;    lnChipReset (pDrvCtrl);                           /* reset LANCE */     if (intConnect ((VOIDFUNCPTR *) INUM_TO_IVEC (ivec), lnInt, (int) pDrvCtrl)        == ERROR)        return (ERROR);    lnRestartSetup (pDrvCtrl);    pDrvCtrl->attached = TRUE;			/* Set our flag */    return (OK);    }/********************************************************************************* lnReset - reset the interface** Mark interface as inactive & reset the chip*/LOCAL void lnReset    (    int unit    )    {    DRV_CTRL *pDrvCtrl = & drvCtrl [unit];    pDrvCtrl->idr.ac_if.if_flags = 0;    lnChipReset (pDrvCtrl);		/* reset LANCE */    }/********************************************************************************* lnInt - handle controller interrupt** This routine is called at interrupt level in response to an interrupt from* the controller.*/LOCAL void lnInt    (    DRV_CTRL  *pDrvCtrl    )    {    ln_tmd	*tmd;    u_short	stat;    int 	i;    stat = lnCsr0Read (pDrvCtrl);	/* Read the device status register */    if (!(stat & lncsr_INTR))		/* If false interrupt, return. */        return;    /*     * Enable interrupts, clear receive and/or transmit interrupts, and clear     * any errors that may be set.     */    lnCsr0Write (pDrvCtrl, ((stat & (lncsr_BABL | lncsr_CERR | lncsr_MISS |	lncsr_MERR | lncsr_RINT | lncsr_TINT | lncsr_IDON)) | lncsr_INEA));    /* Check for errors */    if (stat & (lncsr_BABL | lncsr_MISS | lncsr_MERR))        {        ++pDrvCtrl->idr.ac_if.if_ierrors;        if (stat & lncsr_MERR)		/* restart chip on memory error */            {            logMsg ("lnInt: memory error detected\n",0, 0, 0, 0, 0, 0);            pDrvCtrl->idr.ac_if.if_flags &= ~(IFF_UP | IFF_RUNNING);            (void) netJobAdd ((FUNCPTR) lnRestart, pDrvCtrl->idr.ac_if.if_unit,                              0,0,0,0);            }        }    /* schedule netTask to handle any Rx packets */    if ((stat & lncsr_RINT) && (stat & lncsr_RXON) &&	!(pDrvCtrl->flags & LN_RX_HANDLING_FLAG))	{        pDrvCtrl->flags |= LN_RX_HANDLING_FLAG;        (void) netJobAdd ((FUNCPTR)lnHandleRecvInt, (int)pDrvCtrl, 0,0,0,0);        }     /*     * Did LANCE update any of the TMD's?     * If not then don't bother continuing with transmitter stuff     */      if (!(stat & lncsr_TINT))        {        /* Flush the write pipe */        CACHE_PIPE_FLUSH ();        /* allow interrupt line to go inactive */        i = 3;        while (i-- && (lnCsr0Read (pDrvCtrl) & lncsr_INTR))           ;        return;

⌨️ 快捷键说明

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