📄 ixethaccend.c
字号:
/* buffers left in the pool (may be used by other mux functions) */#define IXETHACC_MBLKS_RESERVED (2 * IXETHACC_MBLKS)/* netjobAdd flow control : no more than 2 or 3 netjobadd pending * in the tnetTask message queue*/#define IXETHACC_NETJOBADD_THRESHOLD 2/* Force more replenish when the number of free mbufs * submitted to the NPE is less than this threshold*/#define IXETHACC_REPL_FAST_THRESHOLD (IXETHACC_MBLKS / 4)#define IXETHACC_REPL_SLOW_THRESHOLD (IXETHACC_MBLKS / 8)#define IXETHACC_REPL_NEARLY_FULL_THRESHOLD ((IXETHACC_MBLKS * 3)/ 4)/* get the size of 1r1w queues so they will never overflow */#define RECBUF_SIZE 256 /* needs to be a power of 2 */#if (1 + IXETHACC_MBLKS + IXETHACC_MBLKS_RESERVED) >= RECBUF_SIZE#undef RECBUF_SIZE#define RECBUF_SIZE 512 #endif#if (1 + IXETHACC_MBLKS + IXETHACC_MBLKS_RESERVED) >= RECBUF_SIZE#undef RECBUF_SIZE#define RECBUF_SIZE 1024 #endif#if (1 + IXETHACC_MBLKS + IXETHACC_MBLKS_RESERVED) >= RECBUF_SIZE#undef RECBUF_SIZE#define RECBUF_SIZE 2048 #endif#if (1 + IXETHACC_MBLKS + IXETHACC_MBLKS_RESERVED) >= RECBUF_SIZE#error "IXETHACC_MBLKS should be less than 1024"#endif#define RECBUF_MASK (RECBUF_SIZE - 1)/* *Private field used by the END driver within the IX_OSAL_MBUF structure * * When transmitting a buffer from the system pool, the buffer header * cannot be used by ethAcc access layer. However, the payload can be * used without copy. The mbuf data pointer is swapped between this mBlk * and an available IX_OSAL_MBUF. The address of the mBLk is stored in an * available IX_OSAL_MBUF field. This field is not used by NPE and is * already in a loaded cache line (for performances)*/#define IXP_DRV_MBUF_PRIV(pIxpBuf) (pIxpBuf)->ix_ne.reserved[7]/* typedefs *//* The definition of the driver control structure */typedef struct end_device{ END_OBJ end; /* The class we inherit from. */ int unit; /* unit number */ int ivec; /* interrupt vector */ int ilevel; /* interrupt level */ char* pShMem; /* real ptr to shared memory */ long flags; /* Our local flags. */ UCHAR enetAddr[6]; /* ethernet address */ CACHE_FUNCS cacheFuncs; /* cache function pointers */ CL_POOL_ID pClPoolId; /* cluster pool */#ifdef IXP_DRV_DEBUG_MBUFS UINT32 tnetReceived; /* packets processed to ipastack */ UINT32 tnetDrop; /* packets dropped by tnet task */ UINT32 tnetJobAddFail; /* netjobadd failed (ring buffer?) */ UINT32 tnetFastReplenish; /* successful fast replenish */ UINT32 tupleGetFail; /* nettupleGet failures */ UINT32 tupleTxAlloc; /* mbufs allocated for TX */ UINT32 errs; /* error counter */#endif IXP_DRV_DEBUG_MBUFS UINT32 netJobAddIn; /* netJobAdd flow control, incremented in qmgr context */ UINT32 netJobAddOut; /* netJobAdd flow control incremented in tnettask context */ IxFastMutex fastReplMutex; /* internal replenish lock */ NET_POOL_ID pTxNetPool; /* pool for transmission */ M_BLK *recBufList[RECBUF_SIZE]; /* internal 1r1w queue */ volatile UINT32 recWr; /* internal queue write pointer */ volatile UINT32 recRd; /* internal queue read pointer */ IX_OSAL_MBUF *replBufList[RECBUF_SIZE]; /* internal 1r1w queue */ volatile UINT32 replWr; /* internal queue write pointer */ volatile UINT32 replRd; /* internal queue read pointer */ IX_OSAL_MBUF *txBufList[RECBUF_SIZE]; /* internal 1r1w queue */ volatile UINT32 txWr; /* internal queue write pointer */ volatile UINT32 txRd; /* internal queue read pointer */ UINT32 rxBufsAlloc; /* The number of cblk/mblk pairs allocated for NPE */ volatile UINT32 rxBufsReplenish; /* The number of mblk sent to NPE */ volatile UINT32 rxBufsRecv; /* The number of mblk returned by NPE */#ifdef IXETHACCEND_FRAG_RECOVERY int ipFragTtl; /* time to live in ip stack */#endif#ifdef INCLUDE_RFC_2233 END_IFDRVCONF endStatsConf; END_IFCOUNTERS endMIBStats; /* updated on the fly */ END_IFCOUNTERS endStatsCounters; /* returned by ioctl */#endif /* INCLUDE_RFC_2233 */} END_DEVICE;/* Definitions for the flags field */#define IxEthAccEnd_PROMISCUOUS 0x1#define IxEthAccEnd_POLLING 0x2/* Status register bits, returned by ixEthAccEndStatusRead() */#define IxEthAccEnd_RINT 0x1 /* Rx interrupt pending */#define IxEthAccEnd_TINT 0x2 /* Tx interrupt pending */#define IxEthAccEnd_RXON 0x4 /* Rx on (enabled) */#define IxEthAccEnd_VALID_INT 0x3 /* Any valid interrupt pending */#define IxEthAccEnd_MIN_FBUF (IX_ETHACC_RX_MBUF_MIN_SIZE) /* min 1st buff sz *//* DEBUG MACROS */#ifdef DEBUG #define LOGMSG(x,a,b,c,d,e,f) \ {\ logMsg (x,a,b,c,d,e,f); \ }#else #define LOGMSG(x,a,b,c,d,e,f)#endif DEBUG#ifdef IXP_DRV_DEBUG #define IXP_DRV_DEBUG_OFF 0x0000 #define IXP_DRV_DEBUG_RX 0x0001 #define IXP_DRV_DEBUG_TX 0x0002 #define IXP_DRV_DEBUG_INT 0x0004 #define IXP_DRV_DEBUG_POLL (IXP_DRV_DEBUG_POLL_RX | IXP_DRV_DEBUG_POLL_TX) #define IXP_DRV_DEBUG_POLL_RX 0x0008 #define IXP_DRV_DEBUG_POLL_TX 0x0010 #define IXP_DRV_DEBUG_LOAD 0x0020 #define IXP_DRV_DEBUG_IOCTL 0x0040 #define IXP_DRV_DEBUG_BUFINIT 0x0080 #define IXP_DRV_DEBUG_ERROR 0x0100 #define IXP_DRV_DEBUG_RX_HANDLING 0x0200 #define IXP_DRV_DEBUG_MIB 0x0400 #define IXP_DRV_DEBUG_TX_HANDLING 0x0800 #define IXP_DRV_DEBUG_POLL_REDIR 0x10000 #define IXP_DRV_DEBUG_LOG_NVRAM 0x20000int IxEthAccEndDebug = IXP_DRV_DEBUG_LOAD | IXP_DRV_DEBUG_ERROR; #define IXP_DRV_LOG(FLG, X0, X1, X2, X3, X4, X5, X6) \ if (IxEthAccEndDebug & FLG) \ logMsg(X0, X1, X2, X3, X4, X5, X6);#else #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, IX_OSAL_MBUF *buffer);LOCAL void ixEthAccEndRxCallback(UINT32 callbackTag, IX_OSAL_MBUF *buffer, IxEthAccPortId portId);LOCAL STATUS ixEthAccEndReplenish(END_DEVICE *pDrvCtrl, IX_OSAL_MBUF *buffer);LOCAL void ixEthAccEndReplenishFast(END_DEVICE *pDrvCtrl);LOCAL void ixEthAccEndReplenishSlow(END_DEVICE *pDrvCtrl);LOCAL void ixEthAccEndTxDoneFree(END_DEVICE *pDrvCtrl, IX_OSAL_MBUF *pIxpBuf);LOCAL void ixEthAccEndTxDoneReplenishFast(END_DEVICE *pDrvCtrl, IX_OSAL_MBUF *pIxpBuf);LOCAL void ixEthAccEndTxDoneCallbackShutdown(UINT32 callbackTag, IX_OSAL_MBUF *buffer);LOCAL void ixEthAccEndRxCallbackShutdown(UINT32 callbackTag, IX_OSAL_MBUF *buffer, IxEthAccPortId portId);LOCAL IX_OSAL_MBUF *ixEthAccEndSwapMblk(END_DEVICE *pDrvCtrl, M_BLK *pMblk);#ifdef INCLUDE_RFC_2233LOCAL STATUS ixEthAccEndMIBStatsDump(END_DEVICE *pDrvCtrl);#endif /*INCLUDE_RFC_2233*/#ifdef IXP_DRV_DEBUG_MBUFSLOCAL void elogHook(M_BLK *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; UINT32 endObjFlags; 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_FRAG_RECOVERY /* Initialize the time-to-live to the default value */ pDrvCtrl->ipFragTtl = IP_FRAG_TTL_DFLT;#endif /* initialise the structure members */ ixOsalFastMutexInit(&(pDrvCtrl->fastReplMutex)); /* Make sure the Intel Ethernet Engines 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_FRAG_RECOVERY dummyAccDrvCtrl.ipFragTtl = IP_FRAG_TTL_DFLT;#endif dummyAccDrvCtrl.end.pNetPool = (NET_POOL_ID)-1; dummyAccDrvCtrl.pTxNetPool = (NET_POOL_ID)-1; ixOsalFastMutexInit(&(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) goto errorExit;#ifdef INCLUDE_RFC_2233 bzero ((char *)&pDrvCtrl->endMIBStats, sizeof(END_IFCOUNTERS)); bzero ((char *)&pDrvCtrl->endStatsCounters, sizeof(END_IFCOUNTERS)); pDrvCtrl->endStatsConf.ifPollInterval = 2*sysClkRateGet(); /* 2 sec poll */ pDrvCtrl->endStatsConf.ifEndObj = &pDrvCtrl->end; pDrvCtrl->endStatsConf.ifWatchdog = NULL; pDrvCtrl->endStatsConf.ifValidCounters = (END_IFINUCASTPKTS_VALID | END_IFINMULTICASTPKTS_VALID | END_IFINBROADCASTPKTS_VALID | END_IFINOCTETS_VALID | END_IFOUTOCTETS_VALID | END_IFOUTUCASTPKTS_VALID | END_IFOUTMULTICASTPKTS_VALID | END_IFOUTBROADCASTPKTS_VALID); /* Initialize MIB-II entries (for RFC 2233 ifXTable) */ pDrvCtrl->end.pMib2Tbl = m2IfAlloc(M2_ifType_ethernet_csmacd, (UINT8*) &pDrvCtrl->enetAddr[0], 6, ETHERMTU, END_SPEED, "ixe", pDrvCtrl->unit); if (pDrvCtrl->end.pMib2Tbl == NULL) { logMsg ("%s%d - MIB-II initializations failed\n", (int)"ixe", pDrvCtrl->unit,0,0,0,0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -