ixethaccend.c
来自「ixEthAccEnd END network interface driver」· C语言 代码 · 共 1,681 行 · 第 1/4 页
C
1,681 行
IXP_DRV_LOG (IXP_DRV_DEBUG_LOAD, "Loading IxEthAccEnd...\n", 1, 2, 3, 4, 5, 6); /* VxWorks needs the device name on the first call */ if (initString[0] == '\0') { bcopy("ixe", initString, 4); IXP_DRV_LOG (IXP_DRV_DEBUG_LOAD,"Returning the ixp425 Ethernet device name string..\n",0,0,0,0,0,0); return(END_OBJ *) OK; } /* allocate the device structure */ pDrvCtrl = (END_DEVICE *)calloc (sizeof (END_DEVICE), 1); if (pDrvCtrl == NULL) goto errorExit; /* parse the init string, filling in the device structure */ if (ixEthAccEndParse (pDrvCtrl, initString) == ERROR) goto errorExit; /* Capture pDrvCtrl */ ixEthAccpDrvCtrl[pDrvCtrl->unit] = pDrvCtrl; /* Point to the top of the list */ pDrvCtrl->recNext = pDrvCtrl->recBufList; /* Link the buffers */ for ( index = 0, rBufList = pDrvCtrl->recBufList; index < MAX_IX_ETH_ACC_REC_BUF; index++) { rBufList++; pDrvCtrl->recBufList[index].ix_rec_next = rBufList; } pDrvCtrl->recBufList[MAX_IX_ETH_ACC_REC_BUF - 1].ix_rec_next = pDrvCtrl->recBufList; /* Make sure the Intel Ethernet Engine's are initialized */ if ( !ixdp425EthLibInitialised ) if ( ixdp425EthLibInit() != IX_SUCCESS ) { logMsg("ixdp425EthLibInit Failed\n",1,2,3,4,5,6); goto errorExit; } /* Init the eth port */ if ( ixdp425EthPhysInit(pDrvCtrl->unit) != IX_SUCCESS ) { logMsg("ixdp425EthPhysInit( %d ) Failed\n", pDrvCtrl->unit,2,3,4,5,6); goto errorExit; } /* Ask the BSP to provide the ethernet address. */ /* This comes after ixdp425EthPhysInit */ SYS_ENET_ADDR_GET(pDrvCtrl); /* initialize the END and MIB2 parts of the structure */ /* * The M2 element must come from m2Lib.h * This IxEthAccEnd is set up for a DIX type ethernet device. */ if (END_OBJ_INIT (&pDrvCtrl->end, (DEV_OBJ *)pDrvCtrl, "ixe", pDrvCtrl->unit, &ixEthAccEndFuncTable, "END IXP425 IxEthAccEnd Driver.") == ERROR || END_MIB_INIT (&pDrvCtrl->end, M2_ifType_ethernet_csmacd, &pDrvCtrl->enetAddr[0], 6, ETHERMTU, END_SPEED) == ERROR) goto errorExit; /* Perform memory allocation/distribution */ if (ixEthAccEndMemInit (pDrvCtrl) == ERROR) goto errorExit; /* reset and reconfigure the device */ ixEthAccEndReset (pDrvCtrl); ixEthAccEndConfig (pDrvCtrl); /* set the flags to indicate readiness */#ifdef IXEETHACC_MULTICAST_ENABLE END_OBJ_READY (&pDrvCtrl->end, IFF_UP | IFF_RUNNING | IFF_NOTRAILERS | IFF_BROADCAST | IFF_MULTICAST);#else END_OBJ_READY (&pDrvCtrl->end, IFF_UP | IFF_RUNNING | IFF_NOTRAILERS | IFF_BROADCAST);#endif IXP_DRV_LOG (IXP_DRV_DEBUG_LOAD, "Done loading IxEthAccEnd...", 1, 2, 3, 4, 5, 6); return(&pDrvCtrl->end); errorExit: if (pDrvCtrl != NULL) { if ( pDrvCtrl->recBufList != NULL ) free ( pDrvCtrl->recBufList ); free ((char *)pDrvCtrl); } logMsg("IxEthAccEndLoad Failed\n", 1, 2, 3, 4, 5, 6); return NULL;}/********************************************************************************* ixEthAccEndParse - 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).** .IP <unit>* Device unit number, a small integer.* .IP <vecNum>* Interrupt vector number (used with sysIntConnect)* .IP <intLvl>* Interrupt level* .LP** RETURNS: OK or ERROR for invalid arguments.*/STATUS ixEthAccEndParse(END_DEVICE * 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); IXP_DRV_LOG (IXP_DRV_DEBUG_LOAD, "Parsed unit number %d\n",pDrvCtrl->unit , 2, 3, 4, 5, 6); /* Interrupt vector. */#if 0 tok = strtok_r (NULL, ":", &pHolder); if (tok == NULL) return ERROR; pDrvCtrl->ivec = atoi (tok); /* Interrupt level. */ tok = strtok_r (NULL, ":", &pHolder); if (tok == NULL) return ERROR; pDrvCtrl->ilevel = atoi (tok);#else pDrvCtrl->ivec = 0; pDrvCtrl->ilevel = 0;#endif IXP_DRV_LOG (IXP_DRV_DEBUG_LOAD, "Processed all arguments\n", 1, 2, 3, 4, 5, 6); return OK;}/********************************************************************************* ixEthAccEndMemInit - initialize memory for the chip** This routine is highly specific to the device.** RETURNS: OK or ERROR.*/STATUS ixEthAccEndMemInit(END_DEVICE * pDrvCtrl /* device to be initialized */){ IxEthAccStatus result; M_CL_CONFIG IxEthAccEndMclBlkConfig; /* network mbuf configuration table */ int count; int IxEthAccEndClDescTblNumEnt = (NELEMENTS(IxEthAccEndClDescTbl)); /* * This is how we would set up and END ETHERMTU + IXP_EH_SIZE using netBufLib(1). * This code is pretty generic. */ if ((pDrvCtrl->end.pNetPool = malloc (sizeof(NET_POOL))) == NULL) return(ERROR); IxEthAccEndMclBlkConfig.mBlkNum = IXETHACC_MBLKS; /* Number of allocated mBlks per IxEth */ IxEthAccEndClDescTbl[0].clNum = IXETHACC_CLSTS; /* Number of allocated cLists per IxEth */ IxEthAccEndMclBlkConfig.clBlkNum = IxEthAccEndClDescTbl[0].clNum; /* Calculate the total memory for all the M-Blks and CL-Blks. */ IxEthAccEndMclBlkConfig.memSize = (IxEthAccEndMclBlkConfig.mBlkNum * (MSIZE + sizeof (long))) + (IxEthAccEndMclBlkConfig.clBlkNum * (CL_BLK_SZ + sizeof(long)));#ifdef IXE_CACHED_BUFFERS_ENABLE IxEthAccEndMclBlkConfig.memArea = (char *) memalign ( _CACHE_ALIGN_SIZE, IxEthAccEndMclBlkConfig.memSize );#else /* Allocate the memory for the buffers from cache safe memory. */ IxEthAccEndMclBlkConfig.memArea = (char *) cacheDmaMalloc ( IxEthAccEndMclBlkConfig.memSize);#endif /* IXE_CACHED_BUFFERS_ENABLE */ if (IxEthAccEndMclBlkConfig.memArea == NULL) { IXP_DRV_LOG (IXP_DRV_DEBUG_LOAD, "system memory unavailable\n", 1, 2, 3, 4, 5, 6); return(ERROR); } /* Calculate the memory size of all the clusters. */ IxEthAccEndClDescTbl[0].memSize = (IxEthAccEndClDescTbl[0].clNum * (IxEthAccEndClDescTbl[0].clSize + 8)) + sizeof(int);#ifdef IXE_CACHED_BUFFERS_ENABLE IxEthAccEndClDescTbl[0].memArea = (char *) memalign ( _CACHE_ALIGN_SIZE, IxEthAccEndClDescTbl[0].memSize );#else /* Allocate the memory for the clusters from cache safe memory. */ IxEthAccEndClDescTbl[0].memArea = (char *) cacheDmaMalloc (IxEthAccEndClDescTbl[0].memSize);#endif /* IXE_CACHED_BUFFERS_ENABLE */ if (IxEthAccEndClDescTbl[0].memArea == NULL) { IXP_DRV_LOG (IXP_DRV_DEBUG_LOAD, "system memory unavailable\n", 1, 2, 3, 4, 5, 6); return(ERROR); } IXP_DRV_LOG (IXP_DRV_DEBUG_LOAD, "\nIxEthAccEndClDescTbl[0].memArea : start:0x%08X End:0x%08X\n", (int)IxEthAccEndClDescTbl[0].memArea, (int)IxEthAccEndClDescTbl[0].memArea + IxEthAccEndClDescTbl[0].memSize, 3, 4, 5, 6); /* Initialize the memory pool. */ if (netPoolInit(pDrvCtrl->end.pNetPool, &IxEthAccEndMclBlkConfig, &IxEthAccEndClDescTbl[0], IxEthAccEndClDescTblNumEnt, NULL) == ERROR) { IXP_DRV_LOG (IXP_DRV_DEBUG_LOAD, "Could not init buffering\n", 1, 2, 3, 4, 5, 6); return(ERROR); } /* * If you need clusters to store received packets into then get them * here ahead of time. */ if ((pDrvCtrl->pClPoolId = netClPoolIdGet (pDrvCtrl->end.pNetPool, IX_ETHACC_RX_MBUF_MIN_SIZE, FALSE)) == NULL) return(ERROR); IXP_DRV_LOG (IXP_DRV_DEBUG_LOAD , "Loading Rx buffers: Unit: %d , num buffs: [%d] NetPooId: 0x%08X ClPoolId: 0x%08X\n" ,pDrvCtrl->unit,IxEthAccEndClDescTbl[0].clNum , (int)pDrvCtrl->end.pNetPool, (int)pDrvCtrl->pClPoolId, 5, 6); /* Provision the NPE with receive buffers */ /* The number of cblk/mblk pairs allocated for NPE */ pDrvCtrl->rxBufsAlloc = (IxEthAccEndClDescTbl[0].clNum - 8); for ( count = 0; count < pDrvCtrl->rxBufsAlloc ; count++ ) { M_BLK_ID pMblk; if ((pMblk = netTupleGet(pDrvCtrl->end.pNetPool, IX_ETHACC_RX_MBUF_MIN_SIZE, M_DONTWAIT, MT_HEADER, FALSE )) == NULL) { IXP_DRV_LOG (IXP_DRV_DEBUG_LOAD, "Could not get a buffer [%d]\n", count, 2, 3, 4, 5, 6); return(ERROR); } IXP_DRV_LOG (IXP_DRV_DEBUG_BUFINIT, "Rx Buff unit[%d]: mBlk: 0x%08X Buff: 0x%08X\n", pDrvCtrl->unit, (int)pMblk, (int)pMblk->m_data, 4, 5, 6);#ifdef IXE_CACHED_BUFFERS_ENABLE /* Flush the buffer */ IXP425_END_CACHE_FLUSH(pMblk->m_data, IX_ETHACC_RX_MBUF_MIN_SIZE);#endif /* IXE_CACHED_BUFFERS_ENABLE */ /* Force Quad align for Ip packet */ pMblk->m_data += 2; pMblk->m_len = IX_ETHACC_RX_MBUF_MIN_SIZE; pMblk->m_next = NULL;#ifdef IXE_CACHED_BUFFERS_ENABLE /* Flush the header */ IXP425_END_CACHE_FLUSH(pMblk,sizeof(M_BLK));#endif /* IXE_CACHED_BUFFERS_ENABLE */ result = ixEthAccPortRxFreeReplenish ( pDrvCtrl->unit, pMblk); if ( result != IX_ETH_ACC_SUCCESS) { /* Free buffer back */ netMblkClChainFree (pMblk); IXP_DRV_LOG(IXP_DRV_DEBUG_LOAD,"Error:Registering IxEthAcc Rx Callbacks Port[%d]\n",pDrvCtrl->unit,2,3,4,5,6); return(ERROR); } } pDrvCtrl->rxBufsActive = count; /* The number of cblk/mblk pairs allocated for NPE */ IXP_DRV_LOG (IXP_DRV_DEBUG_LOAD, "Memory setup complete\n", 1, 2, 3, 4, 5, 6);#ifdef IXP_DRV_DEBUG /* allow log messages to print */ taskDelay(240);#endif return OK;}/********************************************************************************* ixEthAccEndStart - start the device** This function calls BSP functions to connect interrupts and start the* device running in interrupt mode.** RETURNS: OK or ERROR**/LOCAL STATUS ixEthAccEndStart(END_OBJ * pDrv /* device ID */){ IxEthAccStatus result; END_DEVICE *pDrvCtrl = (END_DEVICE *)pDrv; /* * Register Tx Done Callback */ IXP_DRV_LOG(IXP_DRV_DEBUG_LOAD,"Registering IxEthAcc Callbacks Port[%d]\n",pDrvCtrl->unit,2,3,4,5,6); result = ixEthAccPortTxDoneCallbackRegister( pDrvCtrl->unit, ixEthAccEndTxDoneCallback, (UINT32) pDrv); if ( result != IX_ETH_ACC_SUCCESS) { IXP_DRV_LOG(IXP_DRV_DEBUG_LOAD,"Error:Registering IxEthAcc Tx Callbacks Port[%d]\n",pDrvCtrl->unit,2,3,4,5,6); return(ERROR); } /* * Now register Rx Done Callback */ result = ixEthAccPortRxCallbackRegister( pDrvCtrl->unit, (IxEthAccPortRxCallback) ixEthAccEndRxCallback, (UINT32) pDrv); if ( result != IX_ETH_ACC_SUCCESS) { IXP_DRV_LOG(IXP_DRV_DEBUG_LOAD,"Error:Registering IxEthAcc Rx Callbacks Port[%d]\n",pDrvCtrl->unit,2,3,4,5,6); return(ERROR); } IXP_DRV_LOG(IXP_DRV_DEBUG_LOAD,"Enable IxEthAcc Port[%d]\n",pDrvCtrl->unit,2,3,4,5,6); result = ixEthAccPortEnable(pDrvCtrl->unit); if ( result != IX_ETH_ACC_SUCCESS) { IXP_DRV_LOG(IXP_DRV_DEBUG_LOAD,"Error:Enabling IxEthAcc Port[%d]\n",pDrvCtrl->unit,2,3,4,5,6); return(ERROR); } END_FLAGS_SET (&pDrvCtrl->end, (IFF_UP | IFF_RUNNING)); return(OK);}/********************************************************************************* ixEthAccEndPacketGet - get next received message** Get next received message. Returns NULL if none are* ready.** RETURNS: ptr to next packet, or NULL if none ready.*/char* ixEthAccEndPacketGet(
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?