📄 el3c90xend.c
字号:
#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*//* * 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] == NULL) { 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); 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); 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** holder = 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, ":", holder); 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, ":", holder); 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, ":", holder); if (tok == NULL) return ERROR; devIoAddr = (UINT32) strtoul (tok, NULL, 16); DRV_LOG (DRV_DEBUG_LOAD, "devIoAddr : 0x%X ...\n", devIoAddr, 2, 3, 4, 5, 6); /* always use memory mapped IO if provided, else use io map */ if ((devMemAddr == NONE) && (devIoAddr == NONE)) { DRV_LOG (DRV_DEBUG_LOAD, "No memory or IO base specified ...\n", 1, 2, 3, 4, 5, 6); return (ERROR); } else if (devMemAddr != NONE) { pDrvCtrl->devAdrs = devMemAddr; pDrvCtrl->flags |= EL_MODE_MEM_IO_MAP; } else { pDrvCtrl->devAdrs = devIoAddr; } /* PCI memory base address as seen from the CPU */ tok = strtok_r (NULL, ":", holder); if (tok == NULL) return ERROR; pDrvCtrl->pciMemBase = strtoul (tok, NULL, 16); DRV_LOG (DRV_DEBUG_LOAD, "Pci : 0x%X ...\n", pDrvCtrl->pciMemBase, 2, 3, 4, 5, 6); /* Interrupt vector. */ tok = strtok_r (NULL, ":", holder); if (tok == NULL) return ERROR; pDrvCtrl->ivec = atoi (tok); DRV_LOG (DRV_DEBUG_LOAD, "ivec : 0x%X ...\n", pDrvCtrl->ivec, 2, 3, 4, 5, 6); /* Interrupt level. */ tok = strtok_r (NULL, ":", holder); if (tok == NULL) return ERROR; pDrvCtrl->intLevel = atoi (tok); DRV_LOG (DRV_DEBUG_LOAD, "ilevel : 0x%X ...\n", pDrvCtrl->intLevel, 2, 3, 4, 5, 6); /* Caller supplied memory address. */ tok = strtok_r (NULL, ":", holder); if (tok == NULL) return ERROR; pDrvCtrl->memAdrs = (char *)strtoul (tok, NULL, 16); DRV_LOG (DRV_DEBUG_LOAD, "memAdrs : 0x%X ...\n", (int)pDrvCtrl->memAdrs, 2, 3, 4, 5, 6); /* Caller supplied memory size. */ tok = strtok_r (NULL, ":", holder); if (tok == NULL) return ERROR; pDrvCtrl->memSize = strtoul (tok, NULL, 16); DRV_LOG (DRV_DEBUG_LOAD, "memSize : 0x%X ...\n", pDrvCtrl->memSize, 2, 3, 4, 5, 6); /* Caller supplied memory width. */ tok = strtok_r (NULL, ":", holder); if (tok == NULL) return ERROR; pDrvCtrl->memWidth = atoi (tok); DRV_LOG (DRV_DEBUG_LOAD, "memWidth : 0x%X ...\n", pDrvCtrl->memWidth, 2, 3, 4, 5, 6); /* caller supplied flags */ tok = strtok_r (NULL, ":", holder); if (tok == NULL) return ERROR; pDrvCtrl->flags |= strtoul (tok, NULL, 16); DRV_LOG (DRV_DEBUG_LOAD, "flags : 0x%X ...\n", pDrvCtrl->flags, 2, 3, 4, 5, 6); /* buffer multiplier */ tok = strtok_r (NULL, ":", holder); if (tok == NULL) return ERROR; pDrvCtrl->bufMtplr |= strtoul (tok, NULL, 16); DRV_LOG (DRV_DEBUG_LOAD, "bufMultiplier : 0x%X ...\n", pDrvCtrl->bufMtplr, 2, 3, 4, 5, 6); return OK; }/********************************************************************************* el3c90xStart - start the device** This function calls BSP functions to connect interrupts and start the* device running in interrupt mode.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -