📄 ixethaccend.c
字号:
#define IXP_DRV_LOG(FLG, X0, X1, X2, X3, X4, X5, X6)#endif IXP_DRV_DEBUG/* forward static functions */LOCAL void ixEthAccEndReset (END_DEVICE *pDrvCtrl);LOCAL void ixEthAccEndHandleRcvInt (END_DEVICE *pDrvCtrl);LOCAL void ixEthAccEndConfig (END_DEVICE *pDrvCtrl);#ifdef IXE_ETHACC_POLL_ENABLELOCAL UINT ixEthAccEndStatusRead (END_DEVICE *pDrvCtrl);#endif IXE_ETHACC_POLL_ENABLE/* END Specific interfaces. *//* This is the only externally visible interface. */END_OBJ* ixEthAccEndLoad (char* initString, void* unUsed);LOCAL STATUS ixEthAccEndStart (END_OBJ* pDrvCtrl);LOCAL STATUS ixEthAccEndStop (END_DEVICE* pDrvCtrl);LOCAL STATUS ixEthAccEndIoctl (END_DEVICE * pDrvCtrl, int cmd, caddr_t data);LOCAL STATUS ixEthAccEndUnload (END_DEVICE* pDrvCtrl);LOCAL STATUS ixEthAccEndSend (END_DEVICE* pDrvCtrl, M_BLK_ID pBuf);LOCAL STATUS ixEthAccEndMCastAdd (END_DEVICE* pDrvCtrl, char* pAddress);LOCAL STATUS ixEthAccEndMCastDel (END_DEVICE* pDrvCtrl, char* pAddress);LOCAL STATUS ixEthAccEndMCastGet (END_DEVICE* pDrvCtrl, MULTI_TABLE* pTable);LOCAL STATUS ixEthAccEndPollStart (END_DEVICE* pDrvCtrl);LOCAL STATUS ixEthAccEndPollStop (END_DEVICE* pDrvCtrl);LOCAL STATUS ixEthAccEndPollSend (END_DEVICE* pDrvCtrl, M_BLK_ID pBuf);LOCAL STATUS ixEthAccEndPollRcv (END_DEVICE* pDrvCtrl, M_BLK_ID pBuf);LOCAL void ixEthAccEndAddrFilterSet(END_DEVICE *pDrvCtrl);LOCAL STATUS ixEthAccEndParse ();LOCAL STATUS ixEthAccEndMemInit ();LOCAL void ixEthAccEndTxDoneCallback(UINT32 callbackTag, M_BLK *buffer);LOCAL void ixEthAccEndRxCallback(UINT32 callbackTag, M_BLK *buffer, IxEthAccPortId portId);LOCAL STATUS ixEthAccEndReplenish(END_DEVICE *pDrvCtrl, M_BLK *buffer);LOCAL void ixEthAccEndReplenishFast(END_DEVICE *pDrvCtrl);LOCAL void ixEthAccEndReplenishSlow(END_DEVICE *pDrvCtrl);LOCAL void ixEthAccEndTxDoneReplenishFast(END_DEVICE *pDrvCtrl, M_BLK *buffer);LOCAL void ixEthAccEndTxDoneCallbackShutdown(UINT32 callbackTag, M_BLK *buffer);LOCAL void ixEthAccEndRxCallbackShutdown(UINT32 callbackTag, M_BLK *buffer, IxEthAccPortId portId);#ifdef IXP_DRV_DEBUG_MBUFSLOCAL void elogHook(IX_MBUF *pMblk, int flag, unsigned int repl, unsigned int recv);#endif IXP_DRV_DEBUG_MBUFS/* * Declare our function table. This is static across all driver * instances. */LOCAL NET_FUNCS ixEthAccEndFuncTable ={ (FUNCPTR) ixEthAccEndStart, /* Function to start the device. */ (FUNCPTR) ixEthAccEndStop, /* Function to stop the device. */ (FUNCPTR) ixEthAccEndUnload, /* Unloading function for the driver. */ (FUNCPTR) ixEthAccEndIoctl, /* Ioctl function for the driver. */ (FUNCPTR) ixEthAccEndSend, /* Send function for the driver. */ (FUNCPTR) ixEthAccEndMCastAdd, /* Multicast add function for the */ /* driver. */ (FUNCPTR) ixEthAccEndMCastDel, /* Multicast delete function for */ /* the driver. */ (FUNCPTR) ixEthAccEndMCastGet, /* Multicast retrieve function for */ /* the driver. */ (FUNCPTR) ixEthAccEndPollSend, /* Polling send function */ (FUNCPTR) ixEthAccEndPollRcv, /* Polling receive function */ endEtherAddressForm, /* put address info into a NET_BUFFER */ endEtherPacketDataGet, /* get pointer to data in NET_BUFFER */ endEtherPacketAddrGet /* Get packet addresses. */};/* Structure to handle ixe0 and ixe. It is initialized * with a dummy driver to limit checks against NULL in the datapath */LOCAL END_DEVICE dummyAccDrvCtrl;END_DEVICE *ixEthAccpDrvCtrl[2] = { &dummyAccDrvCtrl, &dummyAccDrvCtrl };/********************************************************************************* ixEthAccEndLoad - initialize the driver and device** This routine initializes the driver and the device to the operational state.* All of the device specific parameters are passed in the initString.** The string contains the target specific parameters like this:** "register addr:int vector:int level:shmem addr:shmem size:shmem width"** RETURNS: An END object pointer or NULL on error.*/END_OBJ* ixEthAccEndLoad(char* initString, /* String to be parsed by the driver. */void* unUsed){ END_DEVICE *pDrvCtrl; if (initString == NULL) { IXP_DRV_LOG (IXP_DRV_DEBUG_LOAD, "Failed to load IXP425 Ethernet END, null init string was given\n",0,0,0,0,0,0); return NULL; } 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; if (pDrvCtrl->unit >= 2) goto errorExit;#ifdef IXETHACCEND_CSR_1_1 /* Initialize the time-to-live to the default value */ pDrvCtrl->ipFragTtl = IP_FRAG_TTL_DFLT;#endif /* initialise the structure members */ ixOsServFastMutexInit(&(pDrvCtrl->fastReplMutex)); /* 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; } /* initialised members from the default structure */#ifdef IXETHACCEND_CSR_1_1 dummyAccDrvCtrl.ipFragTtl = IP_FRAG_TTL_DFLT;#endif dummyAccDrvCtrl.end.pNetPool = (NET_POOL_ID)-1; ixOsServFastMutexInit(&(dummyAccDrvCtrl.fastReplMutex)); } /* Enable the eth port */ if ( ixdp425EthLibLoad(pDrvCtrl->unit) != IX_SUCCESS ) { logMsg("ixdp425EthLibLoad Failed\n",1,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); /* Capture pDrvCtrl */ ixEthAccpDrvCtrl[pDrvCtrl->unit] = pDrvCtrl; return(&pDrvCtrl->end); errorExit: if (pDrvCtrl != NULL) { 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.*/LOCAL 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.*/LOCAL STATUS ixEthAccEndMemInit(END_DEVICE * pDrvCtrl /* device to be initialized */){ if (IX_MBUF_POOL_INIT(&(pDrvCtrl->end.pNetPool), IXETHACC_MBLKS + IXETHACC_MBLKS_RESERVED, IX_ETHACC_RX_MBUF_MIN_SIZE + ALIGN_MLEN, "End pool") != IX_SUCCESS) { 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); /* The number of cblk/mblk pairs allocated for NPE */ pDrvCtrl->rxBufsAlloc = IXETHACC_MBLKS; 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 IXP_DRV_DEBUG return OK;}/********************************************************************************* Return buffers to the Intel Ethernet Engine */LOCAL __inline__ STATUS ixEthAccEndReplenish(END_DEVICE *pDrvCtrl, /* interrupting device */M_BLK *pMblk){ if (ixOsServFastMutexTryLock(&(pDrvCtrl->fastReplMutex)) == IX_SUCCESS) { if (ixEthAccPortRxFreeReplenish(pDrvCtrl->unit, pMblk) == IX_ETH_ACC_SUCCESS) { pDrvCtrl->rxBufsReplenish++; /* The number of mblk sent to NPE */ ixOsServFastMutexUnlock(&(pDrvCtrl->fastReplMutex)); IXP_DRV_LOG (IXP_DRV_DEBUG_RX, "ixEthAccEndRepl: replenished mbuf %8.8x\n", (UINT32)pMblk, 2, 3, 4, 5, 6); } else {#ifdef IXP_DRV_DEBUG_MBUFS pDrvCtrl->errs++;#endif ixOsServFastMutexUnlock(&(pDrvCtrl->fastReplMutex)); /* Free buffer back to its pool */ netMblkClChainFree (pMblk); IXP_DRV_LOG(IXP_DRV_DEBUG_RX,"Error:replenish Port[%d]\n", pDrvCtrl->unit,2,3,4,5,6); return ERROR; /* unable to replenish */ } } else { /* replenish is already running at this time * Free buffer back to its pool */ netMblkClChainFree (pMblk); } return OK;}/********************************************************************************* Return buffers from the fast pool to the Intel Ethernet Engine */LOCAL void ixEthAccEndReplenishFast(END_DEVICE *pDrvCtrl /* interrupting device */){ M_BLK_ID pMblk; int oldLevel; UINT32 rxBufsActive; /* drain all buffers from the fast path pool */ while (pDrvCtrl->replRd < pDrvCtrl->replWr) { pMblk = pDrvCtrl->replBufList[pDrvCtrl->replRd++ & RECBUF_MASK]; IXP_DRV_LOG (IXP_DRV_DEBUG_RX, "ixEthAccEndRepl fast: received mbuf %8.8x\n", (UINT32)pMblk, 2, 3, 4, 5, 6); /* check the mblk is ready for replenish */ oldLevel = intLock (); /* protect the mbuf structure */ if(pMblk->pClBlk->clRefCnt != 1 || pMblk->m_next != NULL) { /* this mblk may be shared by other components, * or is chained to an other mbuf, so release * it to the pool. */ intUnlock (oldLevel); netMblkClChainFree (pMblk); continue; } intUnlock (oldLevel); rxBufsActive = pDrvCtrl->rxBufsReplenish - pDrvCtrl->rxBufsRecv; if (rxBufsActive >= pDrvCtrl->rxBufsAlloc) { netMblkClChainFree (pMblk); continue; } /* increment stats about fast replenish */#ifdef IXP_DRV_DEBUG_MBUFS pDrvCtrl->tnetFastReplenish++;#endif#ifdef IXE_CACHED_RX_BUFFERS_ENABLE /* * Mblk header is invalidated in ethAcc component. * We need only invalidate up to the contents of the use * of this buffer. */ DO_EVENT(IXE_EVT_RCV_REPLENISH_LOOP_CACHEOPS); IXP425_END_CACHE_INVALIDATE(pMblk->m_data, pMblk->m_len);#endif /* Force Quad align for Ip packet headers */ pMblk->m_data = ALIGN_MDATA(pMblk->pClBlk->clNode.pClBuf); pMblk->m_len = IX_ETHACC_RX_MBUF_MIN_SIZE; pMblk->mBlkPktHdr.len = IX_ETHACC_RX_MBUF_MIN_SIZE;#ifdef IXP_DRV_DEBUG_MBUFS elogHook(pMblk, 2, pDrvCtrl->rxBufsRecv,pDrvCtrl->rxBufsReplenish);#endif if (ixEthAccEndReplenish(pDrvCtrl, pMblk) != OK) { IXP_DRV_LOG(IXP_DRV_DEBUG_ERROR,"Error:replenish Port[%d]\n", pDrvCtrl->unit,2,3,4,5,6); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -