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

📄 if_elt.c

📁 Tornado 2.0.2 source code!vxworks的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* if_elt.c - 3Com 3C509 Ethernet network interface driver *//* Copyright 1993-1998 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01o,24sep98,dat  SPR 21261, discard packets only when complete.01n,15jul97,spm  changed ioctl handler: added ARP request to SIOCSIFADDR and                  cleaned up SIOCSIFFLAGS01m,17mar97,hdn  added codes to load values in EEPROM to the address config		 register and resource config register. 01m,07apr97,spm  code cleanup, corrected statistics, and upgraded to BSD 4.401l,06mar96,hdn  supported PCMCIA EtherLink III card.01k,14jun95,hdn  removed function declarations defined in sysLib.h.01j,01feb95,jdi  doc cleanup.01i,12nov94,tmk  removed some IMPORTed function decs and included unixLib.h01h,28wed94,hdn  fixed a bug for RX incomplete packet.		 cleaned up, eltFailure(), eltRxDrain(), eltTxCleanup().01g,10apr94,hdn  made warm start work by clearing the interrupt latch bit.01f,20feb94,bcs  add attachment (connector) type selection in eltattach(),                 relegate receive-in-net-task to compile-time selection01e,07feb94,bcs  fix excessive transmit (and/or receive) net job queuing,                 add counters (as "ELT_TIMING") for netJobAdd() calls,                 remove rxInNetTask argument to eltattach(), update comments01d,23jan94,bcs  call eltTxCleanup() and eltStatFlush() from interrupt handler,                 remove receive threshold (not obviously helping), add                 receive and interrupt timing statistics, fix comments01c,16jan94,bcs  eliminated receive task (didn't help enough), consolidated                 packet receive routine into eltRxDrain, simplified transmit                 to handle only one packet at a time but 10% slower01b,30dec93,bcs  fixed adapter failure int. handling, broke up attach routine                 added statistics capture01a,10dec93,bcs  written*//*DESCRIPTIONThis module implements the 3Com 3C509 network adapter driver.The 3C509 (EtherLink\(rg III) is not well-suited for use in real-time systems.Its meager on-board buffering (4K total; 2K transmit, 2K receive) forces thehost processor to service the board at a high priority.  3Com makes a virtueof this necessity by adding fancy lookahead support and adding the label"Parallel Tasking" to the outside of the box.  Using 3Com's drivers, this boardwill look good in benchmarks that measure raw link speed.The board is greatly simplified by using the host CPU as a DMA controller.BOARD LAYOUTThis device is soft-configured by a DOS-hosted program supplied by themanufacturer.  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.  Thus, in the global interfacestructure, the function pointer to the initialization routine is NULL.There are two user-callable routines:.iP eltattach() 14publishes the `elt' interface and initializes the driver and device..iP eltShow()displays statistics that are collected in the interrupt handler..LPSee the manual entries for these routines for more detail.SYSTEM RESOURCE USAGE    - one mutual exclusion semaphore    - one interrupt vector    - 16 bytes in the uninitialized data section (bss)    - 180 bytes (plus overhead) of malloc'ed memory per unit    - 1530 bytes (plus overhead) of malloc'ed memory per frame buffer,        minimum 5 frame buffers.SHORTCUTSThe EISA and MCA versions of the board are not supported.Attachment selection assumes the board is in power-on reset state; a warmrestart will not clear the old attachment selection out of the hardware,and certain new selections may not clear it either.  For example, if RJ45was selected, the system is warm-booted, and AUI is selected, the RJ45connector is still functional.Attachment type selection is not validated against the board's capabilities,even though there is a register that describes which connectors exist.The loaned buffer cluster type is MC_EI; no new type is defined yet.Although it seems possible to put the transmitter into a non-functioningstate, it is not obvious either how to do this or how to detect the resultingstate.  There is therefore no transmit watchdog timer.No use is made of the tuning features of the board; it is possible thatproper dynamic tuning would reduce or eliminate the receive overrunsthat occur when receiving under task control (instead of in the ISR).TUNING HINTSMore receive buffers (than the default 20) could help by allowing moreloaning in cases of massive reception; four per receiving TCP connection plusfour extras should be considered a minimum.INTERNALA driver implementation for this board faces two conflicting networkinterface design goals:  (1) minimizing the time spent at interrupt level,and (2) servicing the board's input without dropping packets.  Thisimplementation can be switched at run-time to meet either goal.Received data is drained from the board's FIFO in the interrupt handler.Many common TCP/IP occurrences, such as filling a 4K TCP window orfragmenting a 4K packet, can cause data to arrive faster than it can bedrained at the task level.  This causes receive overruns and if the datastream continues for very long, the resulting retries may cause the transmitterto give up completely.One possible compromise has been tried and discarded: to receive at thetask level in a high-priority task.  It turns out that the worst-casetask-switching latency is too great to prevent the board from overrunningits receive FIFO often enough to be unacceptable.  Another possible compromiseis to add code to switch between task-level and interrupt-level receptionas necessary depending on the packet arrival rate.  Yet another possibilityis to use the receive threshold feature of the board to receive a packetin chunks rather than all-or-nothing could make the interrupt-level receptionmore palatable in some applications; the threshold would be advanced by perhaps200 bytes per interrupt until the whole packet has been read.The timing measurements represent an attempt to understand why the receiverperformance is what it is, both interrupt-level and task-level.  The mostimportant statistics are "timer overflows" and "max rx latency", whereoverflow is a latency greater than 255 timer ticks.  "Timer invalids" arenot in themselves bad; it means that another interrupt (presumably transmit)occurred before the receiver was serviced and caused the timer to be reset(this is a hardware feature).SEE ALSO: ifLib*/#define ELT_TIMING                          /* Compiles rx timing measurement */#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/unixLib.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 "sys/times.h"#include "net/if_subr.h"#include "drv/netif/if_elt.h"/* defines */#undef ELT_DEBUG                             /* Compiles debug output */#define MAX_UNITS		4	/* maximum units to support */#define DEF_NUM_RX_FRAMES	20	/* default number of rx buffers */#define MIN_NUM_RX_FRAMES	4	/* number we reserve from loaning */#define PARTIAL_TRANSFER_MASK   0xfffe  /* when pulling partial frames out */                                        /* of receive FIFO, transfer even */                                        /* words only *//* 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)*/#define ELT_PRODUCTID_3C589	0x9058	/* product ID for PCMCIA 3C589 *//* globals */ELT_CTRL * pEltCtrl [MAX_UNITS];/* locals *//* forward function declarations */LOCAL void	eltBoardInit	(int unit);LOCAL STATUS	eltMemoryInit	(int unit);LOCAL void	eltReset	(int unit);LOCAL int	eltIoctl	(IDR * pIDR, int cmd, caddr_t data);#ifdef BSD43_DRIVERLOCAL int	eltOutput	(IDR * pIDR, MBUF * pMbuf, SOCK * pDestAddr);LOCAL void	eltTxOutputStart (int unit);#elseLOCAL void	eltTxOutputStart (ELT_CTRL * pDrvCtrl);#endifLOCAL void	eltInt		(ELT_CTRL * pDrvCtrl);LOCAL void	eltTxFlush	(ELT_CTRL * pDrvCtrl, BOOL netJob);LOCAL void	eltRxDeliver	(ELT_CTRL * pDrvCtrl);LOCAL void	eltLoanFree	(ELT_CTRL * pDrvCtrl, ELT_FRAME * pFrame);LOCAL void	eltRxFree	(ELT_CTRL * pDrvCtrl, ELT_FRAME * pFrame);LOCAL void	eltStatFlush	(ELT_CTRL * pDrvCtrl);LOCAL void	eltIntMaskSet	(ELT_CTRL * pDrvCtrl, int maskBits);LOCAL void	eltIntDisable	(ELT_CTRL * pDrvCtrl);LOCAL void	eltIntEnable	(ELT_CTRL * pDrvCtrl);LOCAL void	eltRxStart	(ELT_CTRL * pDrvCtrl);LOCAL void	eltTxStart	(ELT_CTRL * pDrvCtrl);LOCAL STATUS	eltActivate	(ELT_CTRL * pDrvCtrl);LOCAL void	eltIdCommand	(int idPort);LOCAL UINT16	eltIdEepromRead	(int address);LOCAL int	eltEepromRead	(int port, int offset);/********************************************************************************* eltEepromRead - read one 16-bit adapter EEPROM register.** RETURNS: Value from an offset of the EEPROM.*/LOCAL int eltEepromRead    (    int port,    int offset    )    {    int ix;    sysOutWord (port + EEPROM_CONTROL, 0x80 + offset);    /* wait 162 us minimum */    for (ix = 0; ix < 300; ix++)	sysDelay ();        return (sysInWord (port + EEPROM_DATA));    }/********************************************************************************* eltattach - publish the `elt' interface and initialize the driver and device** The routine publishes the `elt' 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 eltattach    (    int         unit,                   /* unit number */    int         port,                   /* base I/O address */    int         ivec,                   /* interrupt vector number */    int         intLevel,               /* interrupt level */    int         nRxFrames,              /* # of receive frames (0=default) */    int         attachment,             /* Ethernet connector to use */    char	*ifName			/* interface name */    )    {    ELT_CTRL *  pDrvCtrl;    int productID;    short *p;    /* Sanity check the unit number */    if (unit < 0 || unit >= MAX_UNITS)        return (ERROR);    /* allocate this unit's control structure the first time attach is called */    if (pEltCtrl [unit] == NULL)        {        pEltCtrl [unit] = malloc (sizeof (ELT_CTRL));        if (pEltCtrl [unit] == NULL)            return (ERROR);        bzero ( (char *) pEltCtrl [unit], sizeof (ELT_CTRL));        }    /* Ensure single invocation per system life */    pDrvCtrl = pEltCtrl [unit];    if (pDrvCtrl->attached)        return (OK);    /* it would be a good idea to validate these parameters.... */    pDrvCtrl->intLevel	= intLevel;	/* PC IRQ number */    pDrvCtrl->ivec	= ivec;		/* interrupt vector */    /* Determine which attachment 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 */    pDrvCtrl->port = port;    productID = eltEepromRead (pDrvCtrl->port, EE_A_PRODUCT_ID);    if (productID == ELT_PRODUCTID_3C589)	{        p = (short *)pDrvCtrl->idr.ac_enaddr;	*p++ = htons (eltEepromRead (port, EE_A_OEM_NODE_0));	*p++ = htons (eltEepromRead (port, EE_A_OEM_NODE_1));	*p++ = htons (eltEepromRead (port, EE_A_OEM_NODE_2));	sysOutWord (port + ELT_COMMAND, SELECT_WINDOW | WIN_CONFIG);	sysOutWord (port + ADDRESS_CONFIG, eltEepromRead (port, EE_A_ADDRESS));	sysOutWord (port + RESOURCE_CONFIG, eltEepromRead (port,EE_A_RESOURCE));	}    else        if (eltActivate (pDrvCtrl) != OK)            return (ERROR);    eltBoardInit (unit);    /* Determine number of Rx descriptors to use */    pDrvCtrl->nRxFrames = nRxFrames ? nRxFrames : DEF_NUM_RX_FRAMES;    /* Publish the interface record */    if (strncmp (ifName, "pcmcia", 6) != 0)	ifName = "elt";#ifdef BSD43_DRIVER    ether_attach    ( (IFNET *) & pDrvCtrl->idr, unit, ifName, (FUNCPTR) NULL,                    (FUNCPTR) eltIoctl, (FUNCPTR) eltOutput, (FUNCPTR) eltReset                    );#else    ether_attach    (                     (IFNET *) & pDrvCtrl->idr,                     unit,                     ifName,                     (FUNCPTR) NULL,                    (FUNCPTR) eltIoctl,                     (FUNCPTR) ether_output,                     (FUNCPTR) eltReset                    );    pDrvCtrl->idr.ac_if.if_start = (FUNCPTR)eltTxOutputStart;#endif    if (eltMemoryInit (unit) != OK)        return (ERROR);    /* keep operating registers in window except in critical sections */    sysOutWord (port + ELT_COMMAND, SELECT_WINDOW | WIN_OPERATING);    /* Connect the interrupt handler */    if (intConnect ( (VOIDFUNCPTR *)INUM_TO_IVEC (pDrvCtrl->ivec),                    eltInt, (int)pDrvCtrl) == ERROR)        return (ERROR);    sysIntEnablePIC (intLevel);    eltIntEnable (pDrvCtrl);    /* Set our flag */    pDrvCtrl->attached = TRUE;    /* Set status flags in IDR */    pDrvCtrl->idr.ac_if.if_flags |= (IFF_UP | IFF_RUNNING | IFF_NOTRAILERS);    /* Successful return */    return (OK);    }/*******************************************************************************

⌨️ 快捷键说明

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