📄 ixethaccend.c
字号:
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 */ M_BLK *recBufList[RECBUF_SIZE]; /* internal 1r1w queue */ volatile UINT32 recWr; /* internal queue write pointer */ volatile UINT32 recRd; /* internal queue read pointer */ M_BLK *replBufList[RECBUF_SIZE]; /* internal 1r1w queue */ volatile UINT32 replWr; /* internal queue write pointer */ volatile UINT32 replRd; /* 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_CSR_1_1 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 first buffer size *//* 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_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, 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 INCLUDE_RFC_2233LOCAL STATUS ixEthAccEndMIBStatsDump(END_DEVICE *pDrvCtrl);#endif /*INCLUDE_RFC_2233*/#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; 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_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 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_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) 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); goto errorExit; } /* * Set the RFC2233 flag bit in the END object flags field and * install the counter update routines. */ m2IfPktCountRtnInstall(pDrvCtrl->end.pMib2Tbl, m2If8023PacketCount); /* * Make a copy of the data in mib2Tbl struct as well. We do this * mainly for backward compatibility issues. There might be some * code that is referencing the END pointer and doing lookups on * the mib2Tbl, which will cause all sorts of problems. */ bcopy ((char *)&pDrvCtrl->end.pMib2Tbl->m2Data.mibIfTbl, (char *)&pDrvCtrl->end.mib2Tbl, sizeof (M2_INTERFACETBL)); endObjFlags = IFF_NOTRAILERS | IFF_BROADCAST | END_MIB_2233;#else /* INCLUDE_RFC_2233 */ if (END_MIB_INIT (&pDrvCtrl->end, M2_ifType_ethernet_csmacd, &pDrvCtrl->enetAddr[0], 6, ETHERMTU, END_SPEED) == ERROR) goto errorExit; endObjFlags = IFF_NOTRAILERS | IFF_BROADCAST;#endif /* INCLUDE_RFC_2233 */ /* 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 endObjFlags |= IFF_MULTICAST;#endif END_OBJ_READY (&pDrvCtrl->end, endObjFlags); 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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -