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

📄 if_eex.c

📁 Tornado 2.0.2 source code!vxworks的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* if_eex.c - Intel EtherExpress 16 network interface driver *//* Copyright 1989-1997 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01k,15jul97,spm  added ARP request to SIOCSIFADDR ioctl handler01j,07apr97,spm  corrected statistics counter for incoming packets01i,17mar97,spm  upgraded to BSD 4.4 and corrected statistics counters.01h,14jun95,hdn  removed function declarations defined in sysLib.h.01g,01feb95,jdi  doc cleanup.01f,17jan95,jag  only send connector select command if NOT auto-detect01e,12nov94,tmk  removed some IMPORTed function decs and included unixLib.h01d,20feb94,bcs  add attachment type selection, stub for auto-detect01c,13dec93,bcs  rearranged initialization, fixed comments01b,04dec93,bcs  made functional, added AL_LOC compile-time option01a,28nov93,bcs  derived from if_ei.c (rev. 03c,15jan93)*//*DESCRIPTIONThis module implements the Intel EtherExpress 16 PC network interface carddriver.  It is specific to that board as used in PC 386/486 hosts.This driver is written using the device's I/O registers exclusively.SIMPLIFYING ASSUMPTIONSThis module assumes a little-endian host (80x86); thus, no endianadjustments are needed to manipulate the 82586 data structures (little-endian).The on-board memory is assumed to be sufficient; thus, no provision is madefor additional buffering in system memory.The "frame descriptor" and "buffer descriptor" structures can be boundinto permanent pairs by pointing each FD at a "chain" of one BD of MTU size.The 82586 receive algorithm fills exactly one BD for each FD; it looks tothe NEXT FD in line for the next BD.The transmit and receive descriptor lists are permanently linked intocircular queues partitioned into sublists designated by the EEX_LISTheaders in the driver control structure.  Empty partitions have NULL pointerfields.  EL bits are set as needed to tell the 82586 where a partition ends.The lists are managed in strict FIFO fashion; thus the link fields are nevermodified, just ignored if a descriptor is at the end of a list partition.BOARD LAYOUTThis device is soft-configured.  No jumpering diagram is required.EXTERNAL INTERFACEThis driver provides the standard external interface with the followingexceptions.  All initialization is performed within the attach routine andthere is no separate initialization routine.  Therefore, in the global interfacestructure, the function pointer to the init() routine is NULL.There is one user-callable routine, eexattach().  For details on usage,see the manual entry for this routine.EXTERNAL SUPPORT REQUIREMENTSNone.SYSTEM RESOURCE USAGE    - one mutual exclusion semaphore    - one interrupt vector    - one watchdog timer.    - 8 bytes in the initialized data section (data)    - 912 bytes in the uninitialized data section (bss)The data and bss sections are quoted for the MC68020 architecture and may varyfor other architectures.  The code size (text) will vary widely betweenarchitectures, and is thus not quoted here.The device contains on-board buffer memory; no system memory is requiredfor buffering.TUNING HINTSThe only adjustable parameter is the number of TFDs to create in adapter buffermemory.  The total number of TFDs and RFDs is 21, given full-frame bufferingand the sizes of the auxiliary structures.  eexattach() requires at leastMIN_NUM_RFDS RFDs to exist.  More than ten TFDs is not sensiblein typical circumstances.SEE ALSO: ifLib*/#include "vxWorks.h"#include "wdLib.h"#include "iv.h"#include "vme.h"#include "net/mbuf.h"#include "net/protosw.h"#include "socket.h"#include "ioctl.h"#include "errno.h"#include "memLib.h"#include "intLib.h"#include "net/if.h"#include "net/route.h"#include "iosLib.h"#include "errnoLib.h"#include "cacheLib.h"#include "logLib.h"#include "netLib.h"#include "stdio.h"#include "stdlib.h"#include "sysLib.h"#ifdef  INET#include "netinet/in.h"#include "netinet/in_systm.h"#include "netinet/in_var.h"#include "netinet/ip.h"#include "netinet/if_ether.h"#endif  /* INET */#include "etherLib.h"#include "net/systm.h"#include "net/unixLib.h"#include "sys/times.h"#include "drv/netif/if_eex.h"#include "net/if_subr.h"/***** LOCAL DEFINITIONS *****/#undef EEX_DEBUG                             /* Compiles debug output */#undef EEX_DEBUG1  /* dhe 10/24/94 */#define MAX_UNITS       4                   /* maximum units to support */#define DEF_NUM_TFDS    8                   /* default number of TFDs */#define MIN_NUM_RFDS    4                   /* minimum number of RFDs */#define MAX_IRQ         15              /* Highest PC IRQ number */#define EEX_MEMSIZE     0x8000          /* Size of EtherExpress memory */                                        /* Production units are 32K */#define SCP_OFFSET      0xfff6          /* At top of 64K address space */                                        /* (aliased in a 32K board) */#define ISCP_OFFSET     0x0000          /* EtherExpress convention */#define SCB_OFFSET      0x0008          /* EtherExpress convention */                                        /* Supported by hardware feature */#define CFD_OFFSET      ( SCB_OFFSET + sizeof (SCB) )#define TFD_OFFSET      ( CFD_OFFSET + sizeof (CFD) )/* These should be in a common file but which one? *//* Ethernet attachment type selections */#define ATTACHMENT_DEFAULT      0       /* use card as configured */#define ATTACHMENT_AUI          1       /* AUI  (thick, DIX, DB-15) */#define ATTACHMENT_BNC          2       /* BNC  (thin, 10BASE-2) */#define ATTACHMENT_RJ45         3       /* RJ-45 (twisted pair, TPE, 10BASE-T)*//* Typedefs for external structures that are not typedef'd in their .h files */typedef struct mbuf MBUF;typedef struct arpcom IDR;                  /* Interface Data Record wrapper */typedef struct ifnet IFNET;                 /* real Interface Data Record */typedef struct sockaddr SOCK;/* The definition of our linked list management structure */typedef struct eex_list                     /* EEX_LIST - 82586 queue head */    {    volatile EEX_SHORTLINK  head;       /* header of list */    volatile EEX_SHORTLINK  tail;       /* tail of list */    } EEX_LIST;/* Macro to follow TFRAME and RFRAME (TFD/RFD) lists */#define SUCC_FD(fd)     ( \                sysOutWord (pDrvCtrl->port + RDPTR, (fd) + RF_LINK), \                sysInWord (pDrvCtrl->port + DXREG) )/* The definition of the driver control structure */typedef struct drv_ctrl    {    IDR                 idr;        /* interface data record */    BOOL                attached;   /* indicates attach() called */    CFD                 *pCfd;      /* Scratch CFD to copy to board mem.*/    EEX_SHORTLINK       rfdBase;    /* RFD pool starts here */    EEX_SHORTLINK       lastFd;     /* last RFD dhe 10/26/94 */    volatile EEX_LIST   rxQueue;    /* receive queue */    volatile EEX_SHORTLINK freeRfd; /* first free receive frame */    volatile EEX_LIST   tfdQueue;   /* free transmit frame descriptors */    volatile EEX_LIST   txQueue;    /* to be sent queue */    volatile EEX_LIST   cblQueue;   /* actual chip transmit queue */    volatile EEX_LIST   cleanQueue; /* queue of TFDs to cleanup */    volatile BOOL       rcvHandling;/* flag, indicates netTask active */    volatile BOOL       txCleaning; /* flag, indicates netTask active */    volatile BOOL       txIdle;     /* flag, indicates idle transmitter */    int                 nTFDs;      /* how many TFDs to create */    int                 nRFDs;      /* how many RFDs to create */    int                 port;       /* base I/O port */    int                 ivec;       /* interrupt vector */    int                 intLevel;   /* interrupt number */    int                 irqCode;    /* encoded value written to IRQ port */    int                 attachment; /* connector type: BNC, AUI, or TPE */    UINT16              setup;      /* base, boot ROM, I/O, AUI/BNC, IRQ */    UINT16              tpeBit;     /* bit 0 = 1 && setup AUI bit = 0 for TPE */    MEM_SETUP           memSetup;   /* everything to set up memory mapping */    WDOG_ID             wid;        /* watchdog timer for transmit */    long                transLocks; /* count for transmit lockup failures */    } DRV_CTRL;#define DRV_CTRL_SIZ  sizeof(DRV_CTRL)/***** GLOBALS *****//***** LOCALS *****//* The array of driver control structs */LOCAL DRV_CTRL drvCtrl [MAX_UNITS];/* Encoded IRQ selection numbers for EtherExpress 16 IRQ Control port * Entries correspond to PC IRQ numbers 0-15.  A zero entry means the * corresponding IRQ cannot be used by the board; a non-zero entry is * the value needed in the board's interrupt control register to program * the board for the corresponding IRQ. */LOCAL int irqTable [MAX_IRQ + 1] =    {    0, 0, 1, 2, 3, 4, 0, 0, 0, 1, 5, 6, 0, 0, 0, 0    };/* following are used only in netTask() context so can be common */LOCAL CFD       Cfd;                    /* expedient for code porting */                                        /* build commands here then copy */                                        /* to board memory */LOCAL char      buffer [FRAME_SIZE];    /* Copy frames through here *//* forward function declarations */static void eexReset (int unit);static int eexIoctl (IDR *pIDR, int cmd, caddr_t data);#ifdef BSD43_DRIVERstatic int eexOutput (IDR *pIDR, MBUF *pMbuf, SOCK *pDestAddr);static void eexTxStartup (int unit);#elsestatic void eexTxStartup (DRV_CTRL *pDrvCtrl);#endifstatic void eexInt (DRV_CTRL *pDrvCtrl);static void eexTxCleanQ (DRV_CTRL *pDrvCtrl);static void eexHandleRecvInt (DRV_CTRL *pDrvCtrl);static STATUS eexReceive (DRV_CTRL *pDrvCtrl, EEX_SHORTLINK rfdOffset);static void eexDiag (int unit);static void eexConfig (int unit);static void eexIASetup (int unit);static void eexRxStartup (DRV_CTRL *pDrvCtrl);static void eexAction (int unit, UINT16 action);static STATUS eexCommand (DRV_CTRL *pDrvCtrl, UINT16 cmd);static void eexTxQPut (DRV_CTRL *pDrvCtrl, EEX_SHORTLINK tfdOffset);static void eexTxQFlush (DRV_CTRL *pDrvCtrl);static void eexRxQPut (DRV_CTRL *pDrvCtrl, EEX_SHORTLINK rfdOffset);static EEX_SHORTLINK eexRxQGet (DRV_CTRL *pDrvCtrl);static BOOL eexRxQFull (DRV_CTRL *pDrvCtrl);static void eexQInit (EEX_LIST *pHead);static EEX_SHORTLINK eexQGet (DRV_CTRL *pDrvCtrl, EEX_LIST *pQueue);static void eexQPut (DRV_CTRL *pDrvCtrl, EEX_LIST *pQueue, EEX_SHORTLINK pNode);static STATUS eexDeviceStart (int unit);static void eexWatchDog(int unit);static STATUS eexEnetAddrGet (DRV_CTRL *pDrvCtrl, char addr[]);static STATUS eex586Init (int unit);static void   eex586IntAck (int unit);static void   eex586IntEnable (int unit);static void   eex586IntDisable (int unit);static void   eex586SetReset (int unit);static void   eex586ClearReset (int unit);static void   eex586ChanAtn (DRV_CTRL *pDrvCtrl);static UINT16 eexReadEEPROM (DRV_CTRL *pDRvCtrl, UINT16 address);static void eexOutBitsEEPROM (int port, int count, UINT16 bits);static UINT16 eexInBitsEEPROM (int port, int count);static void   eexDelayEEPROM (void);static void DUMMY (){}/********************************************************************************* eexattach - publish the `eex' network interface and initialize the driver and device** The routine publishes the `eex' interface by filling in a network interface* record and adding this record to the system list.  This routine also* initializes the driver and the device to the operational state.** RETURNS: OK or ERROR.** SEE ALSO: ifLib*/STATUS eexattach    (    int         unit,                   /* unit number */    int         port,                   /* base I/O address */    int         ivec,                   /* interrupt vector number */    int         ilevel,                 /* interrupt level */    int         nTfds,                  /* # of transmit frames (0=default) */    int         attachment              /* 0=default, 1=AUI, 2=BNC, 3=TPE */    )    {    DRV_CTRL    *pDrvCtrl;    long        size;                   /* temporary size holder */    /* Sanity check the unit number */    if (unit < 0 || unit >= MAX_UNITS)        return (ERROR);    /* Ensure single invocation per system life */    pDrvCtrl = & drvCtrl [unit];#ifdef EEX_DEBUG /* dhe 10/20/94 */    logMsg ("eex: eeattach: pDrvCtrl=%x\n", pDrvCtrl, 0, 0, 0, 0, 0);#endif    if (pDrvCtrl->attached)        return (OK);    /* Check interrupt number for sanity and usability */    if (ilevel < 0 || ilevel > MAX_IRQ)        return (ERROR);    pDrvCtrl->intLevel = ilevel;    pDrvCtrl->irqCode = irqTable [ilevel];    if (pDrvCtrl->irqCode == 0)        return (ERROR);    /* Determine number of Tx and Rx descriptors to use */    pDrvCtrl->nTFDs = (nTfds != 0) ? nTfds : DEF_NUM_TFDS;    /* Determine which connector is desired */    switch (attachment)        {        case ATTACHMENT_DEFAULT:        case ATTACHMENT_AUI:        case ATTACHMENT_BNC:        case ATTACHMENT_RJ45:            pDrvCtrl->attachment = attachment;            break;        default:            return (ERROR);             /* unknown value */        }    /* Find and activate the adapter */    /* Publish the interface record */#ifdef BSD43_DRIVER    ether_attach    ( (IFNET *) & pDrvCtrl->idr, unit, "eex", (FUNCPTR) NULL,                     (FUNCPTR) eexIoctl, (FUNCPTR) eexOutput,                     (FUNCPTR) eexReset);#else    ether_attach    (                    (IFNET *) & pDrvCtrl->idr,                    unit,                    "eex",                    (FUNCPTR) NULL,                    (FUNCPTR) eexIoctl,                    (FUNCPTR) ether_output,                    (FUNCPTR) eexReset                    );    pDrvCtrl->idr.ac_if.if_start = (FUNCPTR)eexTxStartup;#endif    /* Calculate the total size of 82586 memory pool.     * Evaluate as a long so it can force nRFDs negative if way too many     * TFDs were asked for.     */    size =            sizeof (SCP) +            sizeof (ISCP) +            sizeof (SCB) +            sizeof (CFD) +                      /* synch'ed command frame */            (sizeof (TFRAME) * pDrvCtrl->nTFDs);   /* pool of transmit frames */    pDrvCtrl->nRFDs = ( (long)EEX_MEMSIZE - size ) / sizeof (RFRAME);#ifdef EEX_DEBUG /* dhe 10/20/94 */    logMsg ("eex: eeattach: nRFDS=%x\n", pDrvCtrl->nRFDs, 0, 0, 0, 0, 0);#endif    if (pDrvCtrl->nRFDs < MIN_NUM_RFDS)        return (ERROR);    /* Save other passed-in parameters */    pDrvCtrl->port = port;                      /* base I/O address */    pDrvCtrl->ivec = ivec;                      /* interrupt vector */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -