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

📄 if_lnpci.c

📁 Tornado 2.0.2 source code!vxworks的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
static STATUS 	lnRecv (DRV_CTRL *pDrvCtrl, ln_rmd *rmd);#ifdef BSD43_DRIVERstatic int 	lnOutput (IDR *ifp, MBUF *m0, SOCK *dst);#elseLOCAL  void 	lnPciStartOutput (DRV_CTRL * 	pDrvCtrl);#endif /* BSD43_DRIVER */static int 	lnIoctl (IDR *ifp, int cmd, caddr_t data);static int 	lnChipReset (DRV_CTRL *pDrvCtrl);static ln_rmd *	lnGetFullRMD (DRV_CTRL *pDrvCtrl);static void 	lnCsrWrite (DRV_CTRL * pDrvCtrl, int reg, ULONG value);static ULONG 	lnCsrRead (DRV_CTRL * pDrvCtrl, int reg);static void 	lnBcrWrite (DRV_CTRL * pDrvCtrl, int reg, ULONG value);static STATUS   lnRestartSetup (DRV_CTRL *pDrvCtrl);static void     lnRestart (DRV_CTRL *pDrvCtrl);#ifdef BSD43_DRIVERstatic BOOL 	convertDestAddr (IDR *pIDR, SOCK *pDestSktAddr,                                 char *pDestEnetAddr, u_short *pPacketType,                                 MBUF *pMbuf);#endif/********************************************************************************* lnPciattach - publish the `lnPci' network interface and initialize the driver and device** 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 lnPciattach    (    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,	/* used if memory pool is NOT malloc()'d */    int		memWidth,	/* byte-width of data (-1 = any width)     */    ULONG    	pciMemBase,	/* memory base as seen from PCI*/    int		spare2		/* not used */    )    {    DRV_CTRL     *pDrvCtrl;    unsigned int sz;           /* temporary size holder */    char         *pTurkey;     /* start of the LANCE memory pool */    /* 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, "lnPci", (FUNCPTR) NULL,                  (FUNCPTR) lnIoctl, (FUNCPTR) lnOutput, (FUNCPTR) lnReset);#else    ether_attach    (                    &pDrvCtrl->idr.ac_if,                    unit,                    "lnPci",                    (FUNCPTR) NULL,                    (FUNCPTR) lnIoctl,                    (FUNCPTR) ether_output,  /* generic output for Ethernet */                    (FUNCPTR) lnReset                    );    pDrvCtrl->idr.ac_if.if_start = (FUNCPTR)lnPciStartOutput;#endif    /* Create the transmit semaphore. */    pDrvCtrl->TxSem = semMCreate    (                                    SEM_Q_PRIORITY |                                    SEM_DELETE_SAFE |                                    SEM_INVERSION_SAFE                                    );    if (pDrvCtrl->TxSem == NULL)        {        printf ("lnPci: error creating transmitter semaphore\n");        return (ERROR);        }    { /***** Establish size of shared memory region we require *****/    if ((int) memAdrs != NONE)  /* specified memory pool */        {        /*         * With a specified memory pool we want to maximize         * lnRsize and lnTsize         */        sz = (memSize - (RMD_SIZ + TMD_SIZ + sizeof (ln_ib)))               / ((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 */    if (lnRsize < 2)        lnRsize = 2;            /* 4 buffers is reasonable min */    if (lnRsize > 7)        lnRsize = 7;            /* 128 buffers is max for chip */    /* limit ring sizes to reasonable values */    if (lnTsize < 2)        lnTsize = 2;            /* 4 buffers is reasonable min */    if (lnTsize > 7)        lnTsize = 7;            /* 128 buffers is max for chip */    /* Add it all up */    sz = (sizeof (ln_ib)) +         ( ((1 << lnRsize) + 1) * RMD_SIZ ) +         (LN_BUFSIZ << lnRsize) +         ( ((1 << lnTsize) + 1) * TMD_SIZ ) +         (LN_BUFSIZ << lnTsize) +         6;                        /* allow for alignment adjustment */    }    { /***** 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 ( "lnPci: not enough memory provided\n" );                return ( ERROR );                }            pTurkey = 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 ( "lnPci: device requires cache coherent memory\n" );                return (ERROR);                }            pTurkey = (char *) cacheDmaMalloc ( sz );            if ((int)pTurkey == NULL)                {                printf ( "lnPci: system memory unavailable\n" );                return (ERROR);                }            /* copy the DMA structure */            pDrvCtrl->cacheFuncs = cacheDmaFuncs;            break;        }    }    /*                        Turkey Carving     *                        --------------     *     *                          LOW MEMORY     *     *             |-------------------------------------|     *             |       The initialization block      |     *             |         (sizeof (ln_ib))            |     *             |-------------------------------------|     *             |         The Rx descriptors          |     *             | (1 << lnRsize) * sizeof (ln_rmd)|     *             |-------------------------------------|     *             |          The receive buffers        |     *             |       (LN_BUFSIZ << lnRsize)        |     *             |-------------------------------------|     *             |         The Tx descriptors          |     *             | (1 << lnTsize) * sizeof (ln_tmd)|     *             |-------------------------------------|     *             |           The transmit buffers      |     *             |       (LN_BUFSIZ << lnTsize)        |     *             |-------------------------------------|     */    /* Save some things */    pDrvCtrl->memBase  = (char *)((ULONG)pTurkey & 0xff000000);    pDrvCtrl->memWidth = memWidth;    pDrvCtrl->bufSize = LN_BUFSIZ;    pDrvCtrl->pciMemBase  = pciMemBase;		/* pci memory base */    if ((int) memAdrs == NONE)        pDrvCtrl->flags |= LS_MEM_ALLOC_FLAG;    { /***** Carve up the turkey *****/    /* First let's clean the whole turkey */    bzero ( (char *) pTurkey, (int) sz );    /* carve out initialization block */    pDrvCtrl->ib = (ln_ib *)pTurkey;    sz = sizeof (ln_ib);                /* size of initialization block */    /* carve out receive message descriptor (RMD) ring structure */    pDrvCtrl->rpo2 = lnRsize;              /* remember for lnConfig */    pDrvCtrl->rsize = (1 << lnRsize);      /* receive ring size */    /* make it 16 byte aligned */    pDrvCtrl->rring = (ln_rmd *) (((int)pDrvCtrl->ib + sz + 0x0f) & ~0x0f);    sz = (1 << lnRsize) * RMD_SIZ;    pDrvCtrl->rmd_ring.r_bufs = (char *)((int)pDrvCtrl->rring + sz);    sz = (LN_BUFSIZ << lnRsize);   /* room for all the receive buffers */    /* carve out transmit message descriptor (TMD) ring structure */    pDrvCtrl->tpo2 = lnTsize;              /* remember for lnConfig */    pDrvCtrl->tsize = (1 << lnTsize);      /* transmit ring size */    pDrvCtrl->tring = (ln_tmd *) (((int)pDrvCtrl->rmd_ring.r_bufs + sz + 0x0f)				  & ~0x0f);    sz = (1 << lnTsize) * TMD_SIZ;    /* carve out transmit buffer space */    pDrvCtrl->tmd_ring.t_bufs = (char *)((int)pDrvCtrl->tring + sz);    }    /* Save some values */    pDrvCtrl->ivec       = ivec;                 /* interrupt vector */    pDrvCtrl->ilevel     = ilevel;               /* interrupt level */    pDrvCtrl->devAdrs    = (LN_DEVICE *)devAdrs; /* LANCE I/O address */    /* Obtain our Ethernet address and save it */    bcopy ((char *) lnEnetAddr, (char *)pDrvCtrl->idr.ac_enaddr, 6);    /***** Device Initializations *****/    if (lnChipReset (pDrvCtrl) == ERROR)	/* reset lance device */    	{        logMsg ("lnPci: Device failed to reset\n", 0,0,0,0,0,0); 	return (ERROR);	}    if (intConnect ((VOIDFUNCPTR *)INUM_TO_IVEC(ivec),lnInt,(int)pDrvCtrl)        == ERROR)        return (ERROR);    if (lnRestartSetup (pDrvCtrl) == ERROR)        return (ERROR);    pDrvCtrl->attached = TRUE;    return (OK);    }/********************************************************************************* lnReset - reset the interface** Mark interface as inactive & reset the chip*/static 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.*/static void lnInt    (    DRV_CTRL  *pDrvCtrl    )    {    ln_tmd         *tmd;    int            *pDindex;    int            *pTindex;    int            *pTsize;    ln_tmd         *pTring;    ULONG	   stat;    /* Read the device status register */    stat = lnCsrRead (pDrvCtrl, 0);    /* If false interrupt, return. */    if ( ! (stat & CSR0_INTR) )        return;    /*     * enable interrupts, clear receive and/or transmit interrupts, and clear     * any errors that may be set.     */    lnCsrWrite (pDrvCtrl, 0, ((stat &            (CSR0_BABL|CSR0_CERR|CSR0_MISS|CSR0_MERR|             CSR0_RINT|CSR0_TINT|CSR0_IDON)) | CSR0_INEA));    /* Check for errors */    if (stat & (CSR0_BABL | CSR0_MISS | CSR0_MERR))        {        ++pDrvCtrl->idr.ac_if.if_ierrors;        /* restart chip on fatal error */        if (stat & CSR0_MERR)        /* memory error */            {            pDrvCtrl->idr.ac_if.if_flags &= ~(IFF_UP | IFF_RUNNING);            (void) netJobAdd (                             (FUNCPTR)lnRestart,                             pDrvCtrl->idr.ac_if.if_unit,                             0,0,0,0                             );            }        }    /* Have netTask handle any input packets */    if ((stat & CSR0_RINT) && (stat & CSR0_RXON))        {        if ( ! (pDrvCtrl->flags & LS_RCV_HANDLING_FLAG) )            {            pDrvCtrl->flags |= LS_RCV_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 & CSR0_TINT))        return;    pDindex = &pDrvCtrl->dindex;    pTindex = &pDrvCtrl->tindex;    pTsize  = &pDrvCtrl->tsize;    pTring  = pDrvCtrl->tring;    while (*pDindex != *pTindex)        {        /* disposal has not caught up */        tmd = pTring + *pDindex;

⌨️ 快捷键说明

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