📄 mbcend.c
字号:
* The string contains the target specific parameters like this:** "unit:memAddr:ivec:txBdNum:rxBdNum:dmaParms:bufBase:offset"* * RETURNS: An END object pointer or NULL on error.*/END_OBJ* mbcEndLoad ( char * initString /* String to be parsed by the driver. */ ) { MBC_DEVICE * pDrvCtrl; if (initString == NULL) return (NULL); if (initString[0] == 0) { bcopy ((char *)DEV_NAME, initString, DEV_NAME_LEN); return (NULL); } DRV_LOG (DRV_DEBUG_LOAD, "Loading mbc...\n", 1, 2, 3, 4, 5, 6); /* allocate the device structure */ pDrvCtrl = (MBC_DEVICE *) calloc (sizeof (MBC_DEVICE), 1); if (pDrvCtrl == NULL) goto errorExit; /* parse the init string, filling in the device structure */ if (mbcParse (pDrvCtrl, initString) == ERROR) goto errorExit; /* Ask the BSP to provide the ethernet address. */ SYS_ENET_ADDR_GET (&pDrvCtrl->enetAddr); /* Allocate a watchdog timer */ pDrvCtrl->wdId = wdCreate (); if (pDrvCtrl->wdId == NULL) goto errorExit; /* initialize the END and MIB2 parts of the structure */ /* * The M2 element must come from m2Lib.h * This mbcis set up for a DIX type ethernet device. */ if (END_OBJ_INIT (&pDrvCtrl->end, (DEV_OBJ *)pDrvCtrl, DEV_NAME, pDrvCtrl->unit, &mbcFuncTable, "END mbcDriver.") == ERROR) goto errorExit; if (END_MIB_INIT (&pDrvCtrl->end, M2_ifType_ethernet_csmacd, &pDrvCtrl->enetAddr[0], 6, ETHERMTU, MBC_SPEED) == ERROR) goto errorExit; /* Perform memory allocation/distribution */ if (mbcMemInit (pDrvCtrl) == ERROR) goto errorExit; /* reset and reconfigure the device */ mbcReset (pDrvCtrl); mbcInit (pDrvCtrl); mbcConfig (pDrvCtrl); /* set the flags to indicate readiness */ END_OBJ_READY (&pDrvCtrl->end, IFF_UP | IFF_RUNNING | IFF_NOTRAILERS | IFF_BROADCAST | IFF_MULTICAST); DRV_LOG (DRV_DEBUG_RX, "%s%d: mbcEndLoad: offset=%d\n", (int) DEV_NAME, pDrvCtrl->unit, pDrvCtrl->offset, 0, 0, 0); return (&pDrvCtrl->end);errorExit: if (pDrvCtrl != NULL) { if (pDrvCtrl->wdId) wdDelete (pDrvCtrl->wdId); free ((char *)pDrvCtrl); } return (NULL); }/******************************************************************************** mbcParse - parse the init string** Parse the input string. Fill in values in the driver control structure.** The initialization string format is:* .CS* "unit:memAddr:ivec:txBdNum:rxBdNum:dmaParms:bufBase:offset"* .CE** .IP <unit>* Device unit number, a small integer.* .IP <memAddr>* ethernet module base address.* .IP <ivec>* Interrupt vector number (used with sysIntConnect)* .IP <txBdNum>* transmit buffer descriptor* .IP <rxBdNum>* receive buffer descriptor* .IP <dmaParms>* dma parameters* .IP <bufBase>* address of memory pool* .IP <offset>* packet data offset * .LP** RETURNS: OK or ERROR for invalid arguments.*/STATUS mbcParse ( MBC_DEVICE * pDrvCtrl, /* device pointer */ char * initString /* information string */ ) { char * tok; char * pHolder = NULL; /* Parse the initString */ /* Unit number. */ tok = strtok_r (initString, ":", &pHolder); if (tok == NULL) return (ERROR); pDrvCtrl->unit = strtoul (tok, NULL, 16); /* ethernet module base address */ tok = strtok_r (NULL, ":", &pHolder); if (tok == NULL) return (ERROR); pDrvCtrl->memAddr = (void *) strtoul (tok, NULL, 16); /* Interrupt vector. */ tok = strtok_r (NULL, ":", &pHolder); if (tok == NULL) return (ERROR); pDrvCtrl->ivec = strtoul (tok, NULL, 16); /* number of transmit buffer descriptors */ tok = strtok_r (NULL, ":", &pHolder); if (tok == NULL) return (ERROR); pDrvCtrl->txBdNum = strtoul (tok, NULL, 16); /* number of receive buffer descriptors */ tok = strtok_r (NULL, ":", &pHolder); if (tok == NULL) return (ERROR); pDrvCtrl->rxBdNum = strtoul (tok, NULL, 16); /* DMA parameters */ tok = strtok_r (NULL, ":", &pHolder); if (tok == NULL) return (ERROR); pDrvCtrl->dmaParms = strtoul (tok, NULL, 16); /* address of memory pool; NONE = malloc it */ tok = strtok_r (NULL, ":", &pHolder); if (tok == NULL) return (ERROR); pDrvCtrl->bufBase = (void *) strtoul (tok, NULL, 16); /* packet data offset */ tok = strtok_r (NULL, ":", &pHolder); if (tok == NULL) return (ERROR); pDrvCtrl->offset = strtoul (tok, NULL, 16); return (OK); }/******************************************************************************** mbcMemInit - initialize memory for the chip** Allocates and initializes the memory pools for the mbc device.** RETURNS: OK or ERROR.*/STATUS mbcMemInit ( MBC_DEVICE * pDrvCtrl /* device to be initialized */ ) { MBC_BD * pBd; int counter; int bdSize; int txBdMax; int rxBdMax; M_CL_CONFIG mbcMclBlkConfig; CL_DESC mbcClDesc; /* Setup the netPool */ if ((pDrvCtrl->end.pNetPool = malloc (sizeof(NET_POOL))) == NULL) return (ERROR); /* Use default values if the parameters are NULL */ if (pDrvCtrl->txBdNum == 0) pDrvCtrl->txBdNum = TX_BD_DEFAULT; if (pDrvCtrl->rxBdNum == 0) pDrvCtrl->rxBdNum = RX_BD_DEFAULT; /* Use the default minimum value if the given value is smaller */ pDrvCtrl->txBdNum = max (TX_BD_MIN, pDrvCtrl->txBdNum); pDrvCtrl->rxBdNum = max (RX_BD_MIN, pDrvCtrl->rxBdNum); /* Ensure that txBdNum, and rxBdNum are within range */ if (pDrvCtrl->txBdNum > 64) pDrvCtrl->txBdNum = 64; for (bdSize = MBC_EDMA_BDS_8; bdSize <= MBC_EDMA_BDS_64; bdSize++) { txBdMax = 1 << (bdSize + 3); /* set txBdMax to (8, 16, 32, 64) */ rxBdMax = MBC_BD_MAX - txBdMax; if (pDrvCtrl->txBdNum <= txBdMax) { if (pDrvCtrl->rxBdNum > rxBdMax) pDrvCtrl->rxBdNum = rxBdMax; break; } } /* fill in the driver control parameters */ pDrvCtrl->bdSize = bdSize; pDrvCtrl->txBdBase = (MBC_BD *) ((int) pDrvCtrl->memAddr + MBC_EBD); pDrvCtrl->rxBdBase = (MBC_BD *) ((int) pDrvCtrl->memAddr + MBC_EBD + sizeof (MBC_BD) * (1 << (bdSize + 3))); pDrvCtrl->txBdNext = 0; pDrvCtrl->rxBdNext = 0; pDrvCtrl->resetCounter = 0; DRV_LOG (DRV_DEBUG_LOAD, "%s%d: rxBdNum=%d txBdNum=%d rxBdBase=%x txBdBase=%x\n", (int) DEV_NAME, pDrvCtrl->unit, pDrvCtrl->rxBdNum, pDrvCtrl->txBdNum, (int) pDrvCtrl->rxBdBase, (int) pDrvCtrl->txBdBase); mbcClDesc.clNum = 4 * (pDrvCtrl->rxBdNum + pDrvCtrl->txBdNum); mbcClDesc.clSize = MEM_ROUND_UP (MBC_BUFSIZ + pDrvCtrl->offset); mbcClDesc.memSize = (mbcClDesc.clNum * (mbcClDesc.clSize + 4)) + 4; /* Calculate the total memory for all the M-Blks and CL-Blks. */ mbcMclBlkConfig.mBlkNum = mbcClDesc.clNum; mbcMclBlkConfig.clBlkNum = mbcClDesc.clNum; mbcMclBlkConfig.memSize = (mbcMclBlkConfig.mBlkNum * (MSIZE + sizeof (long))) + (mbcMclBlkConfig.clBlkNum * (CL_BLK_SZ + sizeof(long))); mbcMclBlkConfig.memArea = (char *) memalign (sizeof(long), mbcMclBlkConfig.memSize); if (mbcMclBlkConfig.memArea == NULL) { free (pDrvCtrl->end.pNetPool); return (ERROR); } /* Allocate the memory for the clusters from cache safe memory. */ if (pDrvCtrl->bufBase == NULL) { /* Get our own memory */ pDrvCtrl->cacheFuncs = cacheDmaFuncs; pDrvCtrl->bufBase = (char *) cacheDmaMalloc (mbcClDesc.memSize); pDrvCtrl->flags |= MBC_MEM_ALLOC_FLAG; if (pDrvCtrl->bufBase == NULL) { DRV_LOG (DRV_DEBUG_LOAD | DRV_DEBUG_ERROR, "%s%d: system memory unavailable (%d bytes)\n", (int) DEV_NAME, pDrvCtrl->unit, mbcClDesc.memSize, 4, 5, 6); free (pDrvCtrl->end.pNetPool); free (mbcMclBlkConfig.memArea); return (ERROR); } } else { /* Caller provided memory */ pDrvCtrl->cacheFuncs = cacheNullFuncs; } mbcClDesc.memArea = pDrvCtrl->bufBase; /* Initialize the memory pool. */ if (netPoolInit(pDrvCtrl->end.pNetPool, &mbcMclBlkConfig, &mbcClDesc, 1, NULL) == ERROR) { DRV_LOG (DRV_DEBUG_LOAD | DRV_DEBUG_ERROR, "Could not init buffering\n", 1, 2, 3, 4, 5, 6); free (pDrvCtrl->end.pNetPool); free (mbcMclBlkConfig.memArea); if (pDrvCtrl->flags & MBC_MEM_ALLOC_FLAG) cacheDmaFree (pDrvCtrl->bufBase); return (ERROR); } /* * If you need clusters to store received packets into then get them * here ahead of time. */ pDrvCtrl->pClPoolId = netClPoolIdGet (pDrvCtrl->end.pNetPool, MBC_BUFSIZ, FALSE); if (pDrvCtrl->pClPoolId == NULL) { free (pDrvCtrl->end.pNetPool); free (mbcMclBlkConfig.memArea); if (pDrvCtrl->flags & MBC_MEM_ALLOC_FLAG) cacheDmaFree (pDrvCtrl->bufBase); return (ERROR); } /* take the device out of reset state */ SYS_OUT_SHORT (pDrvCtrl, MBC_ECNTL, MBC_ECNTL_RES_OFF); /* set up transmit buffer descriptors, setting 'wrap' bit on last */ pDrvCtrl->txBdNext = 0; pDrvCtrl->txClNext = 0; pBd = pDrvCtrl->txBdBase; for (counter = pDrvCtrl->txBdNum; counter; counter--, pBd++) { pBd->statusMode = (MBC_TXBD_I | MBC_TXBD_L | MBC_TXBD_TC); pBd->dataPointer = NULL; } pBd--; pBd->statusMode |= MBC_TXBD_W; /* set up the receive buffer descriptors, setting 'wrap' bit on last */ pDrvCtrl->rxBdNext = 0; pBd = pDrvCtrl->rxBdBase; for (counter = pDrvCtrl->rxBdNum; counter; counter--, pBd++) { pBd->statusMode = MBC_RXBD_I; pBd->dataPointer = NULL; } pBd--; pBd->statusMode |= MBC_RXBD_W; DRV_LOG (DRV_DEBUG_LOAD, "%s%d: Memory setup complete\n", (int) DEV_NAME, pDrvCtrl->unit, 3, 4, 5, 6); return (OK); }/******************************************************************************** mbcInit - initialize the MBC network device* * Mbc initializes registers, and enables interrupts.** The complement of this routine is mbcReset(). Once a unit is reset by* mbcReset(), it may be re-initialized to a running state by this routine.** RETURNS: OK or ERROR.** SEE ALSO: mbcIoctl(), mbcReset()**/LOCAL STATUS mbcInit ( MBC_DEVICE * pDrvCtrl ) { UINT16 regValue; MBC_BD * pBd; int counter; DRV_LOG (DRV_DEBUG_LOAD, "%s%d: mbcInit\n", (int) DEV_NAME, pDrvCtrl->unit, 3, 4, 5, 6); /* take the device out of reset state */ SYS_OUT_SHORT (pDrvCtrl, MBC_ECNTL, MBC_ECNTL_RES_OFF); /* * set up transmit buffer descriptors, setting 'wrap' bit on last. * clean up any transmit buffers left behind. */ pDrvCtrl->txBdNext = 0; pDrvCtrl->txClNext = 0; pBd = pDrvCtrl->txBdBase; for (counter = pDrvCtrl->txBdNum; counter; counter--, pBd++) { if ((pBd->dataPointer != NULL) && (pDrvCtrl->freeRtn[counter] != NULL)) pDrvCtrl->freeRtn[counter] (pDrvCtrl->freeData[counter].arg1, pDrvCtrl->freeData[counter].arg2); pDrvCtrl->freeRtn[counter] = NULL; pDrvCtrl->freeData[counter].arg1 = NULL; pDrvCtrl->freeData[counter].arg2 = NULL; pBd->dataPointer = NULL; pBd->statusMode = (MBC_TXBD_I | MBC_TXBD_L | MBC_TXBD_TC); } pBd--; pBd->statusMode |= MBC_TXBD_W; /* * set up the receive buffer descriptors, setting 'wrap' bit on last. * Free up any old receive clusters left behind. */ pDrvCtrl->rxBdNext = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -