📄 sh7615end.c
字号:
*/END_OBJ* sh7615EndLoad ( char * initString /* String to be parsed by the driver. */ ) { DRV_CTRL * pDrvCtrl; DRV_LOG (DRV_DEBUG_LOAD, "Loading sh7615End...\n", 1, 2, 3, 4, 5, 6); if (initString == NULL) return (NULL); if (initString[0] == EOS) { bcopy((char *)SH7615END_DEV_NAME, initString, SH7615END_DEV_NAME_LEN); return (0); } /* Allocate a control structure for this device */ pDrvCtrl = (DRV_CTRL *)calloc (sizeof (DRV_CTRL), 1); if (pDrvCtrl == NULL) { printf ("%s - Failed to allocate control structure\n", SH7615END_DEV_NAME ); return (NULL); } /* parse the init string, filling in the device structure */ if (sh7615EndParse (pDrvCtrl, initString) == ERROR) goto errorExit; /* Ask the BSP to provide the ethernet address. */ sh7615EnetAddrGet (pDrvCtrl, (char*) &(pDrvCtrl->enetAddr)); DRV_LOG (DRV_DEBUG_LOAD, "ENET Addr: %x:%x:%x:%x:%x:%x \n", pDrvCtrl->enetAddr[0], pDrvCtrl->enetAddr[1], pDrvCtrl->enetAddr[2], pDrvCtrl->enetAddr[3], pDrvCtrl->enetAddr[4], pDrvCtrl->enetAddr[5]); /* initialize some flags */ pDrvCtrl->loaded = TRUE; /* initialize the END and MIB2 parts of the structure */ /* * The M2 element must come from m2Lib.h * This sh7615End is set up for a DIX type ethernet device. */ if (END_OBJ_INIT (&pDrvCtrl->end, (DEV_OBJ *)pDrvCtrl, SH7615END_DEV_NAME, pDrvCtrl->unit, &sh7615EndFuncTable, "Hitachi SH7615 Enhanced Network Driver.") == ERROR || END_MIB_INIT (&pDrvCtrl->end, M2_ifType_ethernet_csmacd, &pDrvCtrl->enetAddr[0], 6, ETHERMTU, SH7615END_SPEED) == ERROR) goto errorExit; pDrvCtrl->flags = 0; /* Perform memory allocation/distribution */ if (sh7615EndMemInit (pDrvCtrl) == ERROR) goto errorExit; /* set the End flags to indicate readiness */ END_OBJ_READY (&pDrvCtrl->end, (IFF_NOTRAILERS | IFF_MULTICAST | IFF_BROADCAST)); DRV_LOG (DRV_DEBUG_LOAD, "Done loading sh7615end...", 1, 2, 3, 4, 5, 6);#ifdef DRV_DEBUG pShEnd = pDrvCtrl;#endif return (&pDrvCtrl->end);errorExit: sh7615EndUnload (pDrvCtrl); free ((char *)pDrvCtrl); return NULL; }/******************************************************************************** sh7615EndUnload - unload a driver from the system** This function first brings down the device, and then frees any* stuff that was allocated by the driver in the load function.** RETURNS: OK or ERROR.*/LOCAL STATUS sh7615EndUnload ( DRV_CTRL* pDrvCtrl /* device to be unloaded */ ) { DRV_LOG (DRV_DEBUG_LOAD, "EndUnload\n", 0, 0, 0, 0, 0, 0); if (pDrvCtrl == NULL) return (ERROR); pDrvCtrl->loaded = FALSE; END_OBJECT_UNLOAD (&pDrvCtrl->end); /* free allocated shared memory */ if (pDrvCtrl->memBase != NULL) cacheDmaFree (pDrvCtrl->memBase); /* free allocated memory if necessary */ if ((pDrvCtrl->pMBlkArea) != NULL) free (pDrvCtrl->pMBlkArea); /* REVISIT - what about clusters? */ cfree ((char *) pDrvCtrl); return (OK); }/********************************************************************************* sh7615EndParse - parse the init string** Parse the input string. Fill in values in the driver control structure.** The muxLib.o module automatically prepends the unit number to the user's* initialization string from the BSP (configNet.h).*** RETURNS: OK or ERROR for invalid arguments.*/LOCAL STATUS sh7615EndParse ( DRV_CTRL * pDrvCtrl, /* device pointer */ char * initString /* information string */ ) { char* tok; char* pHolder = NULL; /* Parse the initString */ /* Unit number. (from muxLib.o) */ tok = strtok_r (initString, ":", &pHolder); if (tok == NULL) return ERROR; pDrvCtrl->unit = atoi (tok); /* Get various driver configuration values */ tok = strtok_r (NULL, ":", &pHolder); if (tok == NULL) return ERROR; pDrvCtrl->ivec = atoi (tok); tok = strtok_r (NULL, ":", &pHolder); if (tok == NULL) return ERROR; pDrvCtrl->ilevel = atoi (tok); tok = strtok_r (NULL, ":", &pHolder); if (tok == NULL) return ERROR; pDrvCtrl->numTds = strtoul (tok, NULL, 16); tok = strtok_r (NULL, ":", &pHolder); if (tok == NULL) return ERROR; pDrvCtrl->numRds = strtoul (tok, NULL, 16); /* PHY options (phyDefMode) currently not used */ tok = strtok_r (NULL, ":", &pHolder); if (tok == NULL) return ERROR; tok = strtok_r (NULL, ":", &pHolder); if (tok == NULL) return ERROR; pDrvCtrl->userFlags = strtoul (tok, NULL, 16); /* Use default values for invalid settings */ if (!pDrvCtrl->numTds || pDrvCtrl->numTds <= 2) { DRV_FLAGS_SET (SH7615END_INV_TBD_NUM); pDrvCtrl->numTds = SH7615END_TBD_DEF_NUM; } if (!pDrvCtrl->numRds || pDrvCtrl->numRds <= 2) { DRV_FLAGS_SET (SH7615END_INV_RBD_NUM); pDrvCtrl->numRds = SH7615END_RBD_DEF_NUM; } DRV_LOG (DRV_DEBUG_LOAD, "Processed all arugments\n", 1, 2, 3, 4, 5, 6); return OK; }/********************************************************************************* sh7615EndMemInit - initialize memory for the chip** This routine sets up memory required by the driver. It is highly specific * to the device.** RETURNS: OK or ERROR.*/LOCAL STATUS sh7615EndMemInit ( DRV_CTRL * pDrvCtrl /* device to be initialized */ ) { SH7615_RD * pRxD; SH7615_TD * pTxD; char * pBuf; int ix; int sz; M_CL_CONFIG mclBlkConfig = {0, 0, NULL, 0}; /* cluster blocks configuration */ CL_DESC clDesc = {SH7615END_BUFSIZ, 0, NULL, 0}; /* cluster blocks config table */ /* Establish size of shared memory region we require */ DRV_LOG (DRV_DEBUG_LOAD, "MemInit \n", 0, 0, 0, 0, 0, 0); /* Establish a region of shared memory - allow for 16 byte align */ sz = (((pDrvCtrl->numRds + 1) * SH7615END_RBD_SZ) + ((pDrvCtrl->numTds + 1) * SH7615END_TBD_SZ)); /* this driver can't handle write incoherent caches */ if (!CACHE_DMA_IS_WRITE_COHERENT ()) { DRV_LOG (DRV_DEBUG_LOAD, "sh7615EndMemInit: shared memory not cache coherent\n", 1, 2, 3, 4, 5, 6); return (ERROR); } /* cacheDmaMalloc returns CACHE_ALIGN_SIZE aligned and rounded * non-cacheable buffer. So, there is no need to flush and invalidate * descriptor buffers in this driver. */ pDrvCtrl->memBase = (char *) cacheDmaMalloc (sz); if (pDrvCtrl->memBase == NULL) { DRV_LOG (DRV_DEBUG_LOAD, "%s%d - system memory unavailable\n", (int)SH7615END_DEV_NAME, pDrvCtrl->unit, 3, 4, 5, 6); return (ERROR); } pDrvCtrl->memSize = sz; /* zero the shared memory */ bzero (pDrvCtrl->memBase, (int) pDrvCtrl->memSize); /* ensure 16 byte alignment - device requirement */ pDrvCtrl->rxRing = (SH7615_RD *) NET_TO_SH7615END_BUF (pDrvCtrl->memBase); /* carve Tx memory structure */ pDrvCtrl->txRing = (SH7615_TD *) (pDrvCtrl->rxRing + pDrvCtrl->numRds); /* Initialize net buffer pool for tx/rx buffers */ clDesc.clNum = pDrvCtrl->numRds + pDrvCtrl->numTds + NUM_LOAN; mclBlkConfig.mBlkNum = pDrvCtrl->numRds * 4; mclBlkConfig.clBlkNum = clDesc.clNum; mclBlkConfig.memSize = mclBlkConfig.mBlkNum * (MSIZE + sizeof (long)) + mclBlkConfig.clBlkNum * (CL_BLK_SZ + sizeof(long)); mclBlkConfig.memArea = (char *) memalign (MBLK_ALIGNMENT, mclBlkConfig.memSize); if (mclBlkConfig.memArea == NULL) return (ERROR); /* store the pointer to the mBlock area */ pDrvCtrl->pMBlkArea = mclBlkConfig.memArea; pDrvCtrl->mBlkSize = mclBlkConfig.memSize; /* Calculate the memory size of all the clusters. */ clDesc.clSize = SH7615END_BUFSIZ; clDesc.memSize = clDesc.clNum * (clDesc.clSize + sizeof(int)); clDesc.memArea = (char *) memalign (CL_ALIGNMENT, clDesc.memSize); if (clDesc.memArea == NULL) { DRV_LOG (DRV_DEBUG_LOAD, "system memory unavailable\n", 1, 2, 3, 4, 5, 6); return (ERROR); } /* store the pointer to the clBlock area - for show purposes */ pDrvCtrl->pClBlkArea = clDesc.memArea; pDrvCtrl->clBlkSize = clDesc.memSize; /* Allocate and initialize the memory pool. */ if ((pDrvCtrl->end.pNetPool = malloc (sizeof(NET_POOL))) == NULL) return (ERROR); if (netPoolInit(pDrvCtrl->end.pNetPool, &mclBlkConfig, &clDesc, 1, NULL) == ERROR) { DRV_LOG (DRV_DEBUG_LOAD, "Could not initialize net pools\n", 1, 2, 3, 4, 5, 6); return (ERROR); } /* Save the cluster pool id */ pDrvCtrl->pClPoolId = netClPoolIdGet (pDrvCtrl->end.pNetPool, SH7615END_BUFSIZ, FALSE); if (pDrvCtrl->pClPoolId == NULL) return (ERROR);#ifdef DRV_DEBUG sh7615NetPoolId = pDrvCtrl->end.pNetPool; sh7615ClPool = pDrvCtrl->pClPoolId;#endif /* Clear all indices */ pDrvCtrl->rxIndex=0; pDrvCtrl->txIndex=0; pDrvCtrl->txDiIndex=0; pDrvCtrl->txCleaning = FALSE; pDrvCtrl->rxHandling = FALSE; pDrvCtrl->txBlocked = FALSE; /* Setup the receive ring */ pRxD = pDrvCtrl->rxRing; for (ix = 0; ix < pDrvCtrl->numRds; ix++, pRxD++) { pBuf = NET_BUF_ALLOC(); if (pBuf == NULL) { pDrvCtrl->lastError.errCode = END_ERR_NO_BUF; muxError (&pDrvCtrl->end, &pDrvCtrl->lastError); DRV_LOG (DRV_DEBUG_LOAD, "Could not get a buffer\n", 1, 2, 3, 4, 5, 6); return (ERROR); } pRxD->rDesc0 = RD0_OWN; /* chip owns the buffer */ pRxD->rDesc1 = SH7615END_BUFSIZ << 16; /* max frame size */ pRxD->rDesc2 = NET_TO_SH7615END_BUF (pBuf); /* buffer address */ pRxD->rDesc3 = (UINT32) pBuf; /* The real cluster address */ if (ix == (pDrvCtrl->numRds - 1)) /* if its is last one */ pRxD->rDesc0 |= RD0_RDL; /* end of receive ring */ } /* Setup the transmit ring */ pTxD = pDrvCtrl->txRing; for (ix = 0; ix < pDrvCtrl->numTds; ix++, pTxD++) { /* empty -- no buffers at this time -- owner is host */ pTxD->tDesc0 = 0; pTxD->tDesc1 = 0; pTxD->tDesc2 = 0; pTxD->tDesc3 = 0; if (ix == (pDrvCtrl->numTds - 1)) /* if its is last one */ pTxD->tDesc0 |= TD0_TDL; /* end of transmit ring */ } DRV_LOG (DRV_DEBUG_LOAD, "Memory setup complete\n", 1, 2, 3, 4, 5, 6); return OK; }/***************************************************************************** sh7615EndRestart - restart the device** Restarts the device after cleaning up the transmit and receive queues. This* routine should be called only after sh7615EndStop().** RETURNS: OK or ERROR*/LOCAL void sh7615EndRestart ( DRV_CTRL *pDrvCtrl ) { SH7615_TD *pTxD = pDrvCtrl->txRing; FREE_BUF *pFreeBuf = pDrvCtrl->freeBuf; SH7615_RD *pRxD; int count; DRV_LOG (DRV_DEBUG_LOAD, "%s%d - restarting device.\n", (int)SH7615END_DEV_NAME, pDrvCtrl->unit, 0, 0, 0, 0); /* cleanup the tx and rx queues */ sh7615EndTxRingClean (pDrvCtrl); while ((pRxD = sh7615EndRxDGet (pDrvCtrl)) != NULL) sh7615EndRecv (pDrvCtrl, pRxD); /* drop rest of the queued tx packets */ for (count=pDrvCtrl->numTds; count > 0; count--, pTxD++, pFreeBuf++) { /* Free buffers */ if (pFreeBuf->pClBuf != NULL) { NET_BUF_FREE(pFreeBuf->pClBuf); pFreeBuf->pClBuf = NULL; } /* These never had the chance to be sent */ if (pTxD->tDesc0 & TD0_OWN) { END_OBJ *pEndObj = &pDrvCtrl->end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -