⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 el3c90xend.c

📁 3C90X驱动源码
💻 C
📖 第 1 页 / 共 5 页
字号:
#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 + -