📄 ln97xend.c
字号:
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 + -