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

📄 ln97xend.c

📁 操作系统vxworks平台下end设备的驱动程序,支持多种芯片,支持多种cpu
💻 C
📖 第 1 页 / 共 5 页
字号:
    devMemAddr = (UINT32) strtoul (tok, NULL, 16);    DRV_LOG (DRV_DEBUG_LOAD, "devMemAddr : 0x%X ...\n", devMemAddr,             2, 3, 4, 5, 6);    /* Intel IO space address base */    if ((tok = strtok_r (NULL, ":", &pHolder)) == NULL)        return ERROR;    devIoAddr = (UINT32) strtoul (tok, NULL, 16);    DRV_LOG (DRV_DEBUG_LOAD, "devIoAddr : 0x%X ...\n", devIoAddr,             2, 3, 4, 5, 6);    /* always use memory mapped IO if provided, else use IO map */        if ((devMemAddr == NONE) && (devIoAddr == NONE))        {        return (ERROR);        }    else if (devMemAddr != NONE)        {        pDrvCtrl->devAdrs = devMemAddr;        pDrvCtrl->flags  |= LS_MODE_MEM_IO_MAP;        }    else        {        pDrvCtrl->devAdrs = devIoAddr;        }    /* PCI memory base address as seen from the CPU */        if ((tok = strtok_r (NULL, ":", &pHolder)) == NULL)        return ERROR;    pDrvCtrl->pciMemBase = strtoul (tok, NULL, 16);    DRV_LOG (DRV_DEBUG_LOAD, "Pci : 0x%X ...\n", pDrvCtrl->pciMemBase,             2, 3, 4, 5, 6);    /* interrupt vector */    if ((tok = strtok_r (NULL, ":", &pHolder)) == NULL)        return ERROR;    pDrvCtrl->inum = atoi (tok);    DRV_LOG (DRV_DEBUG_LOAD, "inum : 0x%X ...\n", pDrvCtrl->inum,             2, 3, 4, 5, 6);    /* interrupt level */    if ((tok = strtok_r (NULL, ":", &pHolder)) == NULL)        return ERROR;    pDrvCtrl->ilevel = atoi (tok);    DRV_LOG (DRV_DEBUG_LOAD, "ilevel : 0x%X ...\n", pDrvCtrl->ilevel,             2, 3, 4, 5, 6);    /* caller supplied memory address */    if ((tok = strtok_r (NULL, ":", &pHolder)) == NULL)        return ERROR;    pDrvCtrl->memAdrs = (char *)strtoul (tok, NULL, 16);    DRV_LOG (DRV_DEBUG_LOAD, "memAdrs : 0x%X ...\n", (int)pDrvCtrl->memAdrs,             2, 3, 4, 5, 6);    /* caller supplied memory size */    if ((tok = strtok_r (NULL, ":", &pHolder)) == NULL)        return ERROR;    pDrvCtrl->memSize = strtoul (tok, NULL, 16);    DRV_LOG (DRV_DEBUG_LOAD, "memSize : 0x%X ...\n", pDrvCtrl->memSize,             2, 3, 4, 5, 6);    /* caller supplied memory width */    if ((tok = strtok_r (NULL, ":", &pHolder)) == NULL)        return ERROR;    pDrvCtrl->memWidth = atoi (tok);    DRV_LOG (DRV_DEBUG_LOAD, "memWidth : 0x%X ...\n", pDrvCtrl->memWidth,             2, 3, 4, 5, 6);    /* CSR3B value */    if ((tok = strtok_r (NULL, ":", &pHolder)) == NULL)        return ERROR;    pDrvCtrl->csr3B = strtoul (tok, NULL, 16);    DRV_LOG (DRV_DEBUG_LOAD, "CSR3b : 0x%X ...\n", pDrvCtrl->csr3B,             2, 3, 4, 5, 6);    /* caller supplied alignment offset */    if ((tok = strtok_r (NULL, ":", &pHolder)) == NULL)        return ERROR;    pDrvCtrl->offset = atoi (tok);    DRV_LOG (DRV_DEBUG_LOAD, "Offset : 0x%X ...\n", pDrvCtrl->offset,             2, 3, 4, 5, 6);    /* caller supplied flags */    if ((tok = strtok_r (NULL, ":", &pHolder)) == NULL)        return ERROR;    pDrvCtrl->flags |= strtoul (tok, NULL, 16);    DRV_LOG (DRV_DEBUG_LOAD, "flags : 0x%X ...\n", pDrvCtrl->flags,             2, 3, 4, 5, 6);    /* custom device description string */    if ((tok = strtok_r (NULL, ":", &pHolder)) != NULL)        {        pDescription = *((char **)(strtoul (tok, NULL, 16)));        }    return OK;    }/********************************************************************************* ln97xMemInit - initialize memory for Lance chip** Using data in the control structure, setup and initialize the memory* areas needed.  If the memory address is not already specified, then allocate* cache safe memory.** RETURNS: OK or ERROR.*/LOCAL STATUS ln97xMemInit    (    LN_97X_DRV_CTRL * pDrvCtrl  /* device to be initialized */    )    {    UINT32            sz;       /* temporary size holder */    int               ix;    volatile LN_RMD * pRmd;    char *            pTempBuf;    /* Remember register addresses */    pDrvCtrl->pRdp   = LN_97X_RDP;    pDrvCtrl->pRap   = LN_97X_RAP;    pDrvCtrl->pReset = LN_97X_RST;    pDrvCtrl->pBdp   = LN_97X_BDP;    /***** Establish size of shared memory region we require *****/    if ((int) pDrvCtrl->memAdrs != NONE)  /* specified memory pool */        {        /*         * With a specified memory pool we want to maximize         * lnRsize and lnTsize         */        sz = (pDrvCtrl->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 */    lnRsize = max (lnRsize, LN_RMD_MIN); /* 4 Rx buffers is reasonable min */    lnRsize = min (lnRsize, LN_RMD_MAX); /* 512 Rx buffers is max for chip */    lnTsize = max (lnTsize, LN_TMD_MIN); /* 4 Tx buffers is reasonable min */    lnTsize = min (lnTsize, LN_TMD_MAX); /* 512 Tx buffers is max for chip */    /* Add it all up */    sz = (((1 << lnRsize) + 1) * RMD_SIZ) +         (((1 << lnTsize) + 1) * TMD_SIZ) + IB_SIZ + 0x10;    /***** 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) pDrvCtrl->memAdrs)        {	default :       /* caller provided memory */	    if (pDrvCtrl->memSize < sz)     /* not enough space */		{		DRV_LOG (DRV_DEBUG_LOAD, "ln97x: not enough memory provided\n"			 "ln97x: need %ul got %d\n",			 sz, pDrvCtrl->memSize, 3, 4, 5, 6);		return (ERROR);                }	    /* set the beginning of pool */	    pDrvCtrl->pShMem = pDrvCtrl->memAdrs;	    /* 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 ( "ln97x: device requires cache coherent memory\n" );		return (ERROR);		}	    pDrvCtrl->pShMem = (char *) cacheDmaMalloc (sz);	    if (pDrvCtrl->pShMem == NULL)		{		printf ( "ln97x: 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 Tx descriptors          |     *             | (1 << lnTsize) * sizeof (LN_TMD)    |     *             |-------------------------------------|     */    /* Save some things */    pDrvCtrl->memBase = (char *)((UINT32) pDrvCtrl->pShMem & 0xff000000);    if ((int) pDrvCtrl->memAdrs == NONE)        pDrvCtrl->flags |= LS_MEM_ALLOC_FLAG;    /* first let's clear memory */    bzero ((char *) pDrvCtrl->pShMem, (int) sz);    /* initialize a 16-byte aligned RMD ring base address */    pDrvCtrl->pRring    = (LN_RMD *) ((int) pDrvCtrl->pShMem + IB_SIZ);    pDrvCtrl->pRring    = (LN_RMD *) (((int) pDrvCtrl->pRring + 0xf) & ~0xf);    pDrvCtrl->rringLen  = lnRsize;    pDrvCtrl->rringSize = 1 << lnRsize;    pDrvCtrl->rmdIndex  = 0;    /* initialize a 16-byte aligned TMD ring base address */    pDrvCtrl->pTring = (LN_TMD *) ((int) pDrvCtrl->pShMem + IB_SIZ +                       ((1 << lnRsize) + 1) * RMD_SIZ + 0xf);    pDrvCtrl->pTring = (LN_TMD *) (((int) pDrvCtrl->pTring + 0xf) & ~0xf);    pDrvCtrl->tringLen  = lnTsize;    pDrvCtrl->tringSize = 1 << lnTsize;    pDrvCtrl->tmdIndex  = 0;    pDrvCtrl->tmdIndexC = 0;    /* allocate pool structure for mblks, clBlk, and clusters */    if ((pDrvCtrl->endObj.pNetPool = malloc (sizeof (NET_POOL))) == NULL)	return (ERROR);        pDrvCtrl->clDesc.clNum    = pDrvCtrl->rringSize * 2;    pDrvCtrl->mClCfg.clBlkNum = pDrvCtrl->clDesc.clNum;    pDrvCtrl->mClCfg.mBlkNum  = pDrvCtrl->mClCfg.clBlkNum * 2;    /* total memory size for mBlks and clBlks */        pDrvCtrl->mClCfg.memSize =        (pDrvCtrl->mClCfg.mBlkNum  * (MSIZE + sizeof (long))) +        (pDrvCtrl->mClCfg.clBlkNum * (CL_BLK_SZ + sizeof (long)));    /* total memory for mBlks and clBlks */    if ((pDrvCtrl->mClCfg.memArea = (char *) memalign        (sizeof (long), pDrvCtrl->mClCfg.memSize)) == NULL)        {        return (ERROR);        }    /* total memory size for all clusters */    pDrvCtrl->clDesc.clSize  = LN_BUFSIZ;    pDrvCtrl->clDesc.memSize =        (pDrvCtrl->clDesc.clNum * (pDrvCtrl->clDesc.clSize + 8)) + sizeof (int);    /* Do we hand over our own memory? */    if (pDrvCtrl->memAdrs != (char *) NONE)        {        pDrvCtrl->clDesc.memArea =            (char *)(pDrvCtrl->pTring + pDrvCtrl->tringSize);        }    else        {        pDrvCtrl->clDesc.memArea = cacheDmaMalloc (pDrvCtrl->clDesc.memSize);                    if (pDrvCtrl->clDesc.memArea == NULL)            {            return (ERROR);            }        }    /* initialize the device net pool */        if (netPoolInit (pDrvCtrl->endObj.pNetPool, &pDrvCtrl->mClCfg,                     &pDrvCtrl->clDesc, 1, NULL) == ERROR)        {        return (ERROR);        }        /* Store the cluster pool ID as others need it later. */    pDrvCtrl->pClPoolId = clPoolIdGet (pDrvCtrl->endObj.pNetPool,                                       LN_BUFSIZ, FALSE);    pRmd = pDrvCtrl->pRring;    for (ix = 0; ix < pDrvCtrl->rringSize; ++ix, ++pRmd)        {        if ((pTempBuf = netClusterGet            (pDrvCtrl->endObj.pNetPool, pDrvCtrl->pClPoolId)) == NULL)            {            return (ERROR);            }        pTempBuf += pDrvCtrl->offset;        rmdBuffAddrSet (pDrvCtrl, pRmd, pTempBuf);        }    return OK;    }/********************************************************************************* ln97xStart - start the device** This function calls BSP functions to connect interrupts and start the* device running in interrupt mode.** RETURNS: OK or ERROR if the interrupt handler could not be connected.*/LOCAL STATUS ln97xStart    (    LN_97X_DRV_CTRL * pDrvCtrl  /* device to be initialized */    )    {    STATUS        result = ERROR;    pDrvCtrl->txCleaning = FALSE;    pDrvCtrl->txBlocked  = FALSE;    result = (* ln97xIntConnect)((VOIDFUNCPTR *) INUM_TO_IVEC(pDrvCtrl->inum),                                 ln97xInt, (int)(pDrvCtrl));    if (result == OK)        {        /* mark the interface as up */        END_FLAGS_SET (&pDrvCtrl->endObj, (IFF_UP | IFF_RUNNING));        (* ln97xIntEnable) (pDrvCtrl->ilevel);        /* Enable interrupts on the device-side */        csrWrite (pDrvCtrl, CSR(0), CSR0_INEA);        DRV_LOG (DRV_DEBUG_LOAD, "interrupt enabled.\n", 0, 0, 0, 0, 0, 0);        }    return (result);    }/********************************************************************************* ln97xHandleError - handle controller interrupt errors** This routine performs task level error handling for controller errors* detected in interrupt context.** RETURNS: N/A.*/

⌨️ 快捷键说明

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