📄 iolicomend.c
字号:
* All of the device specific parameters are passed in the initString.** This routine can be called in two modes. If it is called with an empty, but* allocated string then it places the name of this device (i.e. oli) into the* initString and returns 0.** If the string is allocated then the routine attempts to perform its load* functionality.** RETURNS: An END object pointer or NULL on error or 0 and the name of the* device if the initString was NULL.*/END_OBJ * iOlicomEndLoad ( char * initString /* String to be parsed by the driver. */ ) { END_DEVICE * pDrvCtrl; END_LOG_MSG (END_DEBUG_LOAD, "Loading oli...\n", 0, 0, 0, 0, 0, 0); if (initString == NULL) { END_LOG_MSG (END_DEBUG_LOAD_FAIL, "initString was null\n", 0, 0, 0, 0, 0, 0); return (NULL); } if (initString[0] == EOS) { memcpy(initString, (char *)DRV_NAME, DRV_NAME_LEN); END_LOG_MSG (END_DEBUG_LOAD_FAIL, "initString[0] was null\n", 0, 0, 0, 0, 0, 0); return (0); } /* allocate the device structure */ pDrvCtrl = (END_DEVICE *)calloc (sizeof (END_DEVICE), 1); if (pDrvCtrl == NULL) { END_LOG_MSG (END_DEBUG_LOAD_FAIL, "%s%d - Failed to allocate control structure\n", DRV_NAME, pDrvCtrl->unit, 0, 0, 0, 0); return (NULL); }#ifdef DEBUG pDbgDrvCtrl = pDrvCtrl;#endif /* parse the init string, filling in the device structure */ if (iOlicomInitParse (pDrvCtrl, initString) == ERROR) { END_LOG_MSG (END_DEBUG_LOAD_FAIL, "%s%d - Failed to parse initialization parameters\n", DRV_NAME, pDrvCtrl->unit, 0, 0, 0, 0); goto errorExit; } /* Sanity check on the unit number */ if (pDrvCtrl->unit < 0) { END_LOG_MSG (END_DEBUG_LOAD_FAIL, "unit number < 0\n", 0, 0, 0, 0, 0, 0); goto errorExit; } /* Check if we are already attached */ if (pDrvCtrl->endObj.attached == TRUE) { END_LOG_MSG (END_DEBUG_LOAD_FAIL, "%s - Already attached\n", DRV_NAME, 0, 0, 0, 0, 0); goto errorExit; } /* endObject Initializations */ if (END_OBJ_INIT (&pDrvCtrl->endObj, (DEV_OBJ*)pDrvCtrl, DRV_NAME, pDrvCtrl->unit, &iOlicomFuncTable, "olicom Enhanced Network Driver") == ERROR) { END_LOG_MSG (END_DEBUG_LOAD_FAIL, "%s%d - Failed to initialize END object\n", DRV_NAME, pDrvCtrl->unit, 0, 0, 0, 0); goto errorExit; } /* * Initialise the PCMCIA side of things. I'm assuming here we have * complete control over the PCMCIA system, this shouldn't really * be done here, rather the whole job should be handled by a * separate PCMCIA sub-system module. * If there is an Olicom card in one of the slots, this will * return TRUE. If no card is found then I just return an error * and this attach() call will fail. A better implementation might * just mark the interface as down, bringing it up when a card * insertion is detected. This will suffice for a first pass though. */ if (iOlicomPcmciaSetup(pDrvCtrl) != OK) { END_LOG_MSG (END_DEBUG_LOAD_FAIL, "%s%d - Failed to initialize the PCMCIA side\n", DRV_NAME, pDrvCtrl->unit, 0, 0, 0, 0); goto errorExit; } /* Initialize MIB-II entries */ if (END_MIB_INIT (&pDrvCtrl->endObj, M2_ifType_ethernet_csmacd, (UINT8*) pDrvCtrl->enetAddr, EADDR_LEN, ETHERMTU, OLI_SPEED) == ERROR) { END_LOG_MSG (END_DEBUG_LOAD_FAIL, "%s%d - MIB-II initializations failed\n", DRV_NAME, pDrvCtrl->unit, 0, 0, 0, 0); goto errorExit; } /* Perform memory allocation/distribution */ if (iOlicomInitMem (pDrvCtrl) == ERROR) { END_LOG_MSG (END_DEBUG_LOAD_FAIL, "initMem() failed\n", 0, 0, 0, 0, 0, 0); goto errorExit; } /* set the flags to indicate readiness */ END_OBJ_READY (&pDrvCtrl->endObj, IFF_NOTRAILERS | IFF_MULTICAST | IFF_BROADCAST); END_LOG_MSG (END_DEBUG_LOAD, "Done loading oli...", 0, 0, 0, 0, 0, 0); /* Successful return */ return (&pDrvCtrl->endObj); /***** Handle error cases *****/errorExit: { iOlicomUnload (pDrvCtrl); taskDelay(120); return (NULL); } }/********************************************************************************* iOlicomInitParse - parse the init string** Parse the input string. Fill in values in the driver control structure.** The initialization string format is:* .CS* "<nisa_base>:<nisa_pcmcia>:<nisa_pcmem>:<intVectA>:<intLevelA>: \* <intVectB>:<intLevelB>:<txBdNum>:<rxBdNum>:<offset>:<pShMem>:<shMemSize>"* .CE** .IP <nisa_base>* Base of NISA space* .IP <ctrlBase>* Base address of Vadem chip* .IP <nisa_pcmem>* Base address of mapped memory space* .IP <intVectA>* Interrupt vector for slot A* .IP <intLevelA>* Interrupt level for slot A* .IP <intVectB>* Interrupt vector for card B* .IP <intLevelB>* Interrupt level for card B* .IP <txBdNum>* number of transmit buffer descriptors; NULL = default* .IP <rxBdNum>* number of receive buffer descriptors; NULL = default* .IP <offset>* Memory offset for alignment.* .IP <pShMem>* Address of memory pool; NONE = malloc it* .IP <shMemSize>* memory pool size* .LP** RETURNS: OK or ERROR for invalid arguments.*/LOCAL STATUS iOlicomInitParse ( END_DEVICE * pDrvCtrl, /* pointer to END_DEVICE structure */ char * initString /* init string */ ) { char * tok; char * holder = NULL; /* Parse the initString */ /* Unit number. */ tok = strtok_r (initString, ":", &holder); if (tok == NULL) return ERROR; pDrvCtrl->unit = atoi (tok); /* Base address of I/O space for card A. */ tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return ERROR; pDrvCtrl->pcmcia.ioBaseA = (char *) strtoul (tok, NULL, 16); /* Base address of Attribute Memory space for card A. */ tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return ERROR; pDrvCtrl->pcmcia.attrBaseA = (char *) strtoul (tok, NULL, 16); /* Base address of Common memory space for card A. */ tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return ERROR; pDrvCtrl->pcmcia.memBaseA = (char *) strtoul (tok, NULL, 16); /* Base address of I/O space for card B. */ tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return ERROR; pDrvCtrl->pcmcia.ioBaseB = (char *) strtoul (tok, NULL, 16); /* Base address of Attribute Memory space for card B. */ tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return ERROR; pDrvCtrl->pcmcia.attrBaseB = (char *) strtoul (tok, NULL, 16); /* Base address of Common memory space for card B. */ tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return ERROR; pDrvCtrl->pcmcia.memBaseB = (char *) strtoul (tok, NULL, 16); /* Base of Vadem controller */ tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return ERROR; pDrvCtrl->pcmcia.ctrlBase = (char *) strtoul (tok, NULL, 16); /* Interrupt vector for slot A. */ tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return ERROR; pDrvCtrl->pcmcia.intVectA = strtoul (tok, NULL, 16); /* Interrupt level for slot A. */ tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return ERROR; pDrvCtrl->pcmcia.intLevelA = strtoul (tok, NULL, 16); /* Interrupt vector for slot B. */ tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return ERROR; pDrvCtrl->pcmcia.intVectB = strtoul (tok, NULL, 16); /* Interrupt level for slot B. */ tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return ERROR; pDrvCtrl->pcmcia.intLevelB = strtoul (tok, NULL, 16); /* number of transmit buf descriptors */ tok = strtok_r(NULL, ":", &holder); if (tok == NULL) return ERROR; pDrvCtrl->txBdNum = strtoul (tok, NULL, 16); /* number of receive buf descriptors */ tok = strtok_r(NULL, ":", &holder); if (tok == NULL) return ERROR; pDrvCtrl->rxBdNum = strtoul (tok, NULL, 16); /* Caller supplied alignment offset. */ tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return ERROR; pDrvCtrl->offset = atoi (tok); /* Address of memory pool. */ tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return ERROR; pDrvCtrl->pShMem = (char *) strtoul (tok, NULL, 16); /* memory pool size. */ tok = strtok_r (NULL, ":", &holder); if (tok == NULL) return ERROR; pDrvCtrl->shMemSize = strtoul (tok, NULL, 16); END_LOG_MSG (END_DEBUG_LOAD, "EndLoad: unit=%d pShMem=0x%X shMemSize=0x%X ctrlBase=0x%X\n", pDrvCtrl->unit, pDrvCtrl->pShMem, pDrvCtrl->shMemSize, pDrvCtrl->pcmcia.ctrlBase, 0, 0); END_LOG_MSG (END_DEBUG_LOAD, "ioBaseA=0x%X attrBaseA=0x%X memBaseA=0x%X\n" "ioBaseB=0x%X attrBaseB=0x%X memBaseB=0x%X\n", (int)pDrvCtrl->pcmcia.ioBaseA, (int)pDrvCtrl->pcmcia.attrBaseA, (int)pDrvCtrl->pcmcia.memBaseA, (int)pDrvCtrl->pcmcia.ioBaseB, (int)pDrvCtrl->pcmcia.attrBaseB, (int)pDrvCtrl->pcmcia.memBaseB); END_LOG_MSG (END_DEBUG_LOAD, "intLevelA=%#x intLevelB %#x txBdNum %#x rxBdNum %#x offset=%#x\n", pDrvCtrl->pcmcia.intLevelA, pDrvCtrl->pcmcia.intLevelB, pDrvCtrl->txBdNum, pDrvCtrl->rxBdNum, pDrvCtrl->offset, 0); END_LOG_MSG (END_DEBUG_LOAD, "Processed all arguments\n", 0, 0, 0, 0, 0, 0); return (OK); }/********************************************************************************* iOlicomInitMem - initialize memory for the chip** Using data in the control structure, setup and initialize the memory* areas needed. If the memory address is not already specified, then allocate* memory.** RETURNS: OK or ERROR.*/LOCAL STATUS iOlicomInitMem ( END_DEVICE * pDrvCtrl /* pointer to END_DEVICE structure */ ) { M_CL_CONFIG oliMclBlkConfig; CL_DESC clDesc; /* cluster description */ void * pBuf; void * pMemBase; int ix; ULONG size; /* Use default number of buffer descriptors if user did not specify */ if (pDrvCtrl->txBdNum == 0) pDrvCtrl->txBdNum = TX_BD_DEFAULT; if (pDrvCtrl->rxBdNum == 0) pDrvCtrl->rxBdNum = RX_BD_DEFAULT; /* must be at least two transmit and receive buffer descriptors */ pDrvCtrl->txBdNum = max (TX_BD_MIN, pDrvCtrl->txBdNum); pDrvCtrl->rxBdNum = max (RX_BD_MIN, pDrvCtrl->rxBdNum); /* Establish a region of 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. */ if ((int) pDrvCtrl->pShMem != NONE) { /* caller provided memory */ size = ((pDrvCtrl->rxBdNum * (OLI_BUFSIZ + RX_BD_SIZ + 8)) + 4 + (pDrvCtrl->txBdNum * (OLI_BUFSIZ + TX_BD_SIZ + 8)) + 4 + (NUM_LOAN * (OLI_BUFSIZ + 8)) + 4); if (pDrvCtrl->shMemSize < size ) /* not enough space */ { END_LOG_MSG (END_DEBUG_LOAD, "%s%d - not enough memory provided\n", DRV_NAME, pDrvCtrl->unit, 0, 0, 0, 0); return ( ERROR ); } pMemBase = pDrvCtrl->pShMem; /* set the beginning of pool */ /* copy null structure */ pDrvCtrl->cacheFuncs = cacheNullFuncs; } else { size = (((pDrvCtrl->rxBdNum + 1) * RX_BD_SIZ) + ((pDrvCtrl->txBdNum + 1) * TX_BD_SIZ)); /* We must allocate memory for buffer descriptors */ pDrvCtrl->pShMem = pMemBase = (char *) malloc (size); if (pMemBase == NULL) { END_LOG_MSG (END_DEBUG_LOAD, "%s%d - system memory unavailable\n", DRV_NAME, pDrvCtrl->unit, 0, 0, 0, 0); return (ERROR); } pDrvCtrl->shMemSize = size; /* copy the DMA structure */ pDrvCtrl->cacheFuncs = cacheNullFuncs; /* Trasmit and receive descriptors allocated by driver */ DRV_FLAGS_SET(OLI_MEMOWN); } /* zero the shared memory */ memset (pMemBase, 0, (int) size); /* carve Tx memory structure */ pDrvCtrl->txBdBase = (TX_BD *) pDrvCtrl->pShMem; /* carve Rx memory structure */ pDrvCtrl->rxBdBase = (RX_BD *) (pDrvCtrl->txBdBase + pDrvCtrl->txBdNum); /* Initialize net buffer pool for tx/rx buffers */ memset ((char *)&oliMclBlkConfig, 0, sizeof(oliMclBlkConfig)); memset ((char *)&clDesc, 0, sizeof(clDesc)); oliMclBlkConfig.mBlkNum = pDrvCtrl->rxBdNum * 4; clDesc.clNum = pDrvCtrl->rxBdNum + pDrvCtrl->txBdNum + NUM_LOAN; oliMclBlkConfig.clBlkNum = clDesc.clNum; /* * mBlk and cluster configuration memory size initialization
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -