📄 el3c90xend.c
字号:
}#endif /* SYS_DELAY *//* A shortcut for getting the hardware address from the MIB II stuff. */#ifdef INCLUDE_RFC_1213/* Old RFC 1213 mib2 interface */#define END_HADDR(pEnd) \ ((pEnd)->mib2Tbl.ifPhysAddress.phyAddress)#define END_HADDR_LEN(pEnd) \ ((pEnd)->mib2Tbl.ifPhysAddress.addrLength)#else/* New RFC 2233 mib2 interface */#define END_HADDR(pEnd) \ ((pEnd)->pMib2Tbl->m2Data.mibIfTbl.ifPhysAddress.phyAddress)#define END_HADDR_LEN(pEnd) \ ((pEnd)->pMib2Tbl->m2Data.mibIfTbl.ifPhysAddress.addrLength)#endif /* INCLUDE_RFC_1213 */#define END_FLAGS_ISSET(pEnd, setBits) \ ((pEnd)->flags & (setBits))#define VOID_TO_DRVCTRL(pVoid,pDrvCtrl) ((pDrvCtrl)=(EL3C90X_DEVICE *)(pVoid))/* externs */IMPORT int endMultiLstCnt (END_OBJ *);IMPORT void sysDelay(); /* x86 bSP implements around 720 ns delay *//* DEBUG MACROS */#ifdef DRV_DEBUG /* if debugging driver */int el3c90xDebug = DRV_DEBUG_LOAD| DRV_DEBUG_INT | DRV_DEBUG_TX;NET_POOL * pElXlPool;#define DRV_LOG(FLG, X0, X1, X2, X3, X4, X5, X6) \ if (el3c90xDebug & FLG) \ logMsg((char *)X0, (int)X1, (int)X2, (int)X3, (int)X4, \ (int)X5, (int)X6);#define ENDLOGMSG(x) \ if (el3c90xDebug) \ { \ logMsg x; \ }#define DRV_PRINT(FLG,X) \ if (el3c90xDebug & FLG) printf X;#else /*DRV_DEBUG*/#define DRV_LOG(DBG_SW, X0, X1, X2, X3, X4, X5, X6)#define DRV_PRINT(DBG_SW,X)#define ENDLOGMSG(x)#endif /*DRV_DEBUG*/FUNCPTR el3c90xIntConnectRtn = intConnect;/* * Various supported PHY vendors/types and their names. Note that * this driver will work with pretty much any MII-compliant PHY, * so failure to positively identify the chip is not a fatal error. */LOCAL EL_DEV_TYPE el3c90xPhyTbl[ ] = { { TI_PHY_VENDORID, TI_PHY_10BT, "<TI ThunderLAN 10BT (internal)>" }, { TI_PHY_VENDORID, TI_PHY_100VGPMI, "<TI TNETE211 100VG Any-LAN>" }, { NS_PHY_VENDORID, NS_PHY_83840A, "<National Semiconductor DP83840A>"}, { LEVEL1_PHY_VENDORID, LEVEL1_PHY_LXT970, "<Level 1 LXT970>" }, { INTEL_PHY_VENDORID, INTEL_PHY_82555, "<Intel 82555>" }, { SEEQ_PHY_VENDORID, SEEQ_PHY_80220, "<SEEQ 80220>" }, { 0, 0, "<MII-compliant physical interface>" } };LOCAL STATUS el3c90xStart (void * pEnd);LOCAL STATUS el3c90xStop (void * pEnd);LOCAL STATUS el3c90xUnload (void * pEnd);LOCAL int el3c90xIoctl (void * pEnd, int cmd, caddr_t data);LOCAL STATUS el3c90xSend (void * pEnd, M_BLK_ID pMblk);LOCAL STATUS el3c90xMCastAdd (void * pEnd, char * pAddress);LOCAL STATUS el3c90xMCastDel (void * pEnd, char * pAddress);LOCAL STATUS el3c90xMCastGet (void * pEnd, MULTI_TABLE * pTable);LOCAL STATUS el3c90xPollSend (void * pEnd, M_BLK_ID pMblk);LOCAL STATUS el3c90xPollRcv (void * pEnd, M_BLK_ID pMblk);LOCAL void el3c90xInit (EL3C90X_DEVICE *);LOCAL STATUS el3c90xMemInit (EL3C90X_DEVICE * pDrvCtrl);LOCAL void el3c90xDevStop (EL3C90X_DEVICE *);LOCAL void el3c90xReset (EL3C90X_DEVICE *);LOCAL void el3c90xIntEnable (EL3C90X_DEVICE * pDrvCtrl);LOCAL void el3c90xIntDisable (EL3C90X_DEVICE * pDrvCtrl);LOCAL STATUS el3c90xPollStart(EL3C90X_DEVICE * pDrvCtrl);LOCAL STATUS el3c90xPollStop (EL3C90X_DEVICE * pDrvCtrl);LOCAL int el3c90xUpdInit (EL3C90X_DEVICE *);LOCAL int el3c90xDndInit (EL3C90X_DEVICE *);LOCAL UINT8 el3c90xHashGet (char *);LOCAL void el3c90xFilterSet (EL3C90X_DEVICE *);LOCAL void el3c90xHashFilterSet (EL3C90X_DEVICE *);LOCAL void el3c90xMcastConfig (EL3C90X_DEVICE * pDrvCtrl);LOCAL int el3c90xUpdFill (EL3C90X_DEVICE *, EL_SIMPLE_DESC_CHAIN *);LOCAL STATUS el3c90xDndMblkPack (EL3C90X_DEVICE *, EL_DESC_CHAIN *, M_BLK_ID);LOCAL int el3c90xDndSet (EL3C90X_DEVICE *, EL_DESC_CHAIN *, M_BLK * );LOCAL STATUS el3c90xDndFree (EL3C90X_DEVICE *, EL_DESC_CHAIN *);LOCAL STATUS el3c90xDndEnqueue (EL3C90X_DEVICE *, EL_DESC_CHAIN *);LOCAL EL_DESC_CHAIN * el3c90xDndGet (EL3C90X_DEVICE * pDrvCtrl);LOCAL EL_DESC_CHAIN * el3c90xTxDequeue (EL3C90X_DEVICE * pDrvCtrl);LOCAL M_BLK_ID el3c90xNextPktFetch (EL3C90X_DEVICE *, EL_SIMPLE_DESC_CHAIN *);LOCAL EL_SIMPLE_DESC_CHAIN * el3c90xNextUpdFetch (EL3C90X_DEVICE * pDrvCtrl);LOCAL STATUS el3c90xRxUnStall (EL3C90X_DEVICE * pDrvCtrl);LOCAL void el3c90xRxKick (EL3C90X_DEVICE * pDrvCtrl);LOCAL void el3c90xIntrRx (EL3C90X_DEVICE * pDrvCtrl);LOCAL void el3c90xIntrTx (EL3C90X_DEVICE * pDrvCtrl);LOCAL void el3c90xIntrErr (EL3C90X_DEVICE * pDrvCtrl, UINT8 txstat);LOCAL void el3c90xStatUpdate (EL3C90X_DEVICE *);LOCAL void el3c90xInt (EL3C90X_DEVICE * pDrvCtrl);LOCAL void el3c90xMiiSync (EL3C90X_DEVICE *);LOCAL void el3c90xMiiSend (EL3C90X_DEVICE *, UINT32, int);LOCAL int el3c90xMiiRegRead (EL3C90X_DEVICE *, EL_MII_FRAME *);LOCAL int el3c90xMiiRegWrite (EL3C90X_DEVICE *, EL_MII_FRAME *);LOCAL UINT16 el3c90xPhyRegRead (EL3C90X_DEVICE *, int);LOCAL void el3c90xPhyRegWrite (EL3C90X_DEVICE *, int, int);LOCAL void el3c90xAutoNegTx (EL3C90X_DEVICE *);LOCAL void el3c90xMiiAutoNeg (EL3C90X_DEVICE *);LOCAL int el3c90xMiiModeGet (EL3C90X_DEVICE *);LOCAL void el3c90xMediaSet (EL3C90X_DEVICE *, int);LOCAL void el3c90xMediaCheck (EL3C90X_DEVICE *);LOCAL int el3c90xMediaConfig (EL3C90X_DEVICE * pDrvCtrl);LOCAL int el3c90xEprmWait (EL3C90X_DEVICE *);LOCAL int el3c90xEprmRead (EL3C90X_DEVICE *, caddr_t, int, int, int);LOCAL void el3c90xWait (EL3C90X_DEVICE *);LOCAL void el3c90xIntrSet (EL3C90X_DEVICE * pDrvCtrl, UINT16 flag);LOCAL void el3c90xIntrClr (EL3C90X_DEVICE * pDrvCtrl, UINT16 flag);LOCAL UCHAR el3c90xCsrReadByte (EL3C90X_DEVICE *, USHORT, int);LOCAL USHORT el3c90xCsrReadWord (EL3C90X_DEVICE *, USHORT, int);LOCAL ULONG el3c90xCsrReadLong (EL3C90X_DEVICE *, USHORT, int);LOCAL void el3c90xCsrWriteByte (EL3C90X_DEVICE *, USHORT, UCHAR, int);LOCAL void el3c90xCsrWriteWord (EL3C90X_DEVICE *, USHORT, USHORT, int);LOCAL void el3c90xCsrWriteLong (EL3C90X_DEVICE *, USHORT, ULONG, int);/* * Declare our function table. This is static across all driver * instances. */LOCAL NET_FUNCS el3c90xFuncTable = { (FUNCPTR) el3c90xStart, /* Function to start the device. */ (FUNCPTR) el3c90xStop, /* Function to stop the device. */ (FUNCPTR) el3c90xUnload, /* Unloading function for the driver. */ (FUNCPTR) el3c90xIoctl, /* Ioctl function for the driver. */ (FUNCPTR) el3c90xSend, /* Send function for the driver. */ (FUNCPTR) el3c90xMCastAdd, /* Multicast address add function for the */ /* driver. */ (FUNCPTR) el3c90xMCastDel, /* Multicast address delete function for */ /* the driver. */ (FUNCPTR) el3c90xMCastGet, /* Multicast table retrieve function for */ /* the driver. */ (FUNCPTR) el3c90xPollSend, /* Polling send function for the driver. */ (FUNCPTR) el3c90xPollRcv, /* Polling receive function for the driver. */ endEtherAddressForm, /* Put address info into a packet. */ (FUNCPTR) endEtherPacketDataGet,/* Get a pointer to packet data. */ (FUNCPTR) endEtherPacketAddrGet /* Get packet addresses. */ };/******************************************************************************** el3c90xEndLoad - 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 <initString>, which* expects a string of the following format:** <unit>:<devMemAddr>:<devIoAddr>:<pciMemBase:<vecnum>:<intLvl>:<memAdrs>* :<memSize>:<memWidth>:<flags>:<buffMultiplier>** This routine can be called in two modes. If it is called with an empty but* allocated string, it places the name of this device (that is, "elPci") into * the <initString> and returns 0.** If the string is allocated and not empty, the routine attempts to load* the driver using the values specified in the string.** RETURNS: An END object pointer, or NULL on error, or 0 and the name of the* device if the <initString> was NULL.*/END_OBJ * el3c90xEndLoad ( char * initString /* String to be parsed by the driver. */ ) { EL3C90X_DEVICE * pDrvCtrl = NULL; int speed; DRV_LOG (DRV_DEBUG_LOAD, "Loading elPci...\n", 1, 2, 3, 4, 5, 6); if (initString == NULL) return (NULL); if (initString [0] == 0) { bcopy ((char *)EL3C90X_DEV_NAME, initString, EL3C90X_DEV_NAME_LEN); return (0); } if ((pDrvCtrl = (EL3C90X_DEVICE *)calloc (sizeof (EL3C90X_DEVICE), 1)) == NULL) return (NULL); /* parse the init string, filling in the device structure */ if (el3c90xInitParse (pDrvCtrl, initString) == ERROR) goto endLoadFail; /* initialize the END and MIB2 parts of the structure */ if (END_OBJ_INIT (&pDrvCtrl->endObj, (DEV_OBJ *)pDrvCtrl, EL3C90X_DEV_NAME, pDrvCtrl->unit, &el3c90xFuncTable, "3COM 3c90X Fast Etherlink Endhanced Network Driver.") == ERROR) { goto endLoadFail; } /* Reset the adapter. */ el3c90xReset(pDrvCtrl); /* get station address from the EEPROM */ if (el3c90xEprmRead(pDrvCtrl, &pDrvCtrl->enetAddr[0], EL_EE_OEM_ADR0, 3, 1) != OK) { DRV_LOG (DRV_DEBUG_LOAD, "elPci%d: failed to read station address\n", pDrvCtrl->unit, 2, 3, 4, 5, 6); goto endLoadFail; } /* Perform memory allocation */ if (el3c90xMemInit (pDrvCtrl) == ERROR) goto endLoadFail; DRV_LOG (DRV_DEBUG_LOAD, "Malloc done ...\n", 1, 2, 3, 4, 5, 6); /* * Figure out the card type. 3c905B adapters have the * 'supportsNoTxLength' bit set in the capabilities * word in the EEPROM. */ el3c90xEprmRead(pDrvCtrl, (caddr_t)&pDrvCtrl->devCaps, EL_EE_CAPS, 1, 0); if (pDrvCtrl->devCaps & EL_CAPS_NO_TXLENGTH) pDrvCtrl->devType = EL_TYPE_905B; else pDrvCtrl->devType = EL_TYPE_90X; speed = el3c90xMediaConfig (pDrvCtrl); #ifdef INCLUDE_RFC_1213 /* Old RFC 1213 mib2 interface */ if (END_MIB_INIT (&pDrvCtrl->endObj, M2_ifType_ethernet_csmacd, &pDrvCtrl->enetAddr[0], 6, ETHERMTU, speed) == ERROR) goto endLoadFail; /* set the flags to indicate readiness */ END_OBJ_READY (&pDrvCtrl->endObj, IFF_NOTRAILERS | IFF_BROADCAST | IFF_MULTICAST | IFF_SIMPLEX);#else /* New RFC 2233 mib2 interface */ /* Initialize MIB-II entries (for RFC 2233 ifXTable) */ pDrvCtrl->endObj.pMib2Tbl = m2IfAlloc(M2_ifType_ethernet_csmacd, (UINT8*) &pDrvCtrl->enetAddr[0], 6, ETHERMTU, speed, EL3C90X_DEV_NAME, pDrvCtrl->unit); if (pDrvCtrl->endObj.pMib2Tbl == NULL) { printf ("%s%d - MIB-II initializations failed\n", EL3C90X_DEV_NAME, pDrvCtrl->unit); goto endLoadFail; } /* * Set the RFC2233 flag bit in the END object flags field and * install the counter update routines. */ pDrvCtrl->endObj.flags |= END_MIB_2233; m2IfPktCountRtnInstall(pDrvCtrl->endObj.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 might be referencing the END pointer and might * possibly do lookups on the mib2Tbl, which will cause all sorts * of problems. */ bcopy ((char *)&pDrvCtrl->endObj.pMib2Tbl->m2Data.mibIfTbl, (char *)&pDrvCtrl->endObj.mib2Tbl, sizeof (M2_INTERFACETBL)); /* set the flags to indicate readiness */ END_OBJ_READY (&pDrvCtrl->endObj, IFF_NOTRAILERS | IFF_BROADCAST | IFF_MULTICAST | IFF_SIMPLEX | END_MIB_2233);#endif /* INCLUDE_RFC_1213 */ DRV_LOG (DRV_DEBUG_LOAD, "Done loading elPci...\n", 1, 2, 3, 4, 5, 6); return (&pDrvCtrl->endObj); endLoadFail: { if (pDrvCtrl != NULL) free ((char *)pDrvCtrl); } return ((END_OBJ *)NULL); }/********************************************************************************* el3c90xInitParse - parse the initialization string** Parse the input string. This routine is called from el3c90xEndLoad() which* intializes some values in the driver control structure with the values* passed in the intialization string.** The initialization string format is:* <unit>:<devMemAddr>:<devIoAddr>:<pciMemBase:<vecNum>:<intLvl>:<memAdrs>* :<memSize>:<memWidth>:<flags>:<buffMultiplier>** .IP <unit>* Device unit number, a small integer.* .IP <devMemAddr>* Device register base memory address* .IP <devIoAddr>* Device register base IO address* .IP <pciMemBase>* Base address of PCI memory space* .IP <vecNum>* Interrupt vector number.* .IP <intLvl>* Interrupt level.* .IP <memAdrs>* Memory pool address or NONE.* .IP <memSize>* Memory pool size or zero.* .IP <memWidth>* Memory system size, 1, 2, or 4 bytes (optional).* .IP <flags>* Device specific flags, for future use.* .IP <buffMultiplier>* Buffer Multiplier or NONE. If NONE is specified, it defaults to 2** RETURNS: OK, or ERROR if any arguments are invalid.*/STATUS el3c90xInitParse ( EL3C90X_DEVICE * pDrvCtrl, /* pointer to the control structure */ char * initString /* initialization string */ ) { char* tok; char* pHolder = NULL; UINT32 devMemAddr; UINT32 devIoAddr; DRV_LOG (DRV_DEBUG_LOAD, "Parse starting ...\n", 1, 2, 3, 4, 5, 6); /* Parse the initString */ /* Unit number. */ tok = strtok_r (initString, ":", &pHolder); if (tok == NULL) return ERROR; pDrvCtrl->unit = atoi (tok); DRV_LOG (DRV_DEBUG_LOAD, "Unit : %d ...\n", pDrvCtrl->unit, 2, 3, 4, 5, 6); /* devAdrs address. */ tok = strtok_r (NULL, ":", &pHolder); if (tok == NULL) return ERROR; devMemAddr = (UINT32) strtoul (tok, NULL, 16); DRV_LOG (DRV_DEBUG_LOAD, "devMemAddr : 0x%X ...\n", devMemAddr, 2, 3, 4, 5, 6); /* devIoAddrs address */ tok = strtok_r (NULL, ":", &pHolder);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -