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

📄 if_ultra.c

📁 Tornado 2.0.2 source code!vxworks的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* if_ultra.c - SMC Elite Ultra Ethernet network interface driver *//* Copyright 1984-1999 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01u,11jan99,aeg  fixed multiple semaphore inits in ultraattach ().01t,29jun98,dat  SPR 21211. fixes to Interrupt loop. 01s,11jun98,hdn  fixed typo in ultraIntr().01r,22apr98,hdn  set FINE16 bit in ultraInit(). 		 added a loop to ack pending interrupts in untraIntr().01q,15jul97,spm  removed driver initialization from ioctl support (SPR #8831)01p,15may97,spm  reverted to bcopy routines for mbufs in BSD 4.401o,07apr97,spm  code cleanup and corrected counter for incoming packets01n,17mar97,spm  upgraded to BSD 4.4 and corrected statistics counters.01m,14jun95,hdn  removed function declarations defined in sysLib.h.01l,01feb95,jdi  doc cleanup.01k,29nov94,hdn  added a semaphore in ultraPut().01j,12nov94,tmk  removed some IMPORTed function decs and included unixLib.h01i,30sep94,hdn  implemented two transmit buffers.		 enabled getting GPOUT and ZWSEN bit of GCR in EEROM.		 deleted while loop in ultraPut().01h,29nov93,hdn  disabled the interrupt in ultraPut().		 removed netJobAdd (ultraPut, ..) in ultraIntr().01g,28nov93,hdn  changed NULTRA to 1.01f,23nov93,hdn  removed cacheInvalidate(). 		 added checking TXP bit before the transmission. 01e,22nov93,hdn  added elcdetach () for the warm start.01d,15nov93,hdn  added support for Thin Ethernet(10Base2, BNC)01c,05nov93,hdn  added cacheFlush() and cacheInvalidate().01b,04nov93,hdn  cleaned up.01a,30oct93,hdn  written.*//*DESCRIPTIONThis module implements the SMC Elite Ultra Ethernet network interface driver.This driver supports single transmission and multiple reception.  TheCurrent register is a write pointer to the ring.  The Bound register is aread pointer from the ring.  This driver gets the Current register at theinterrupt level and sets the Bound register at the task level.  Theinterrupt is never masked at the task level.CONFIGURATIONThe W1 jumper should be set in the position of "Software Configuration".The defined I/O address in config.h must match the one stored in EEROM. The RAM address, the RAM size, and the IRQ level are defined in config.h. IRQ levels 2,3,5,7,10,11,15 are supported.EXTERNAL INTERFACEThe only user-callable routines are ultraattach() and ultraShow():.iP ultraattach() 14publishes the `ultra' interface and initializes the driver and device..iP ultraShow()displays statistics that are collected in the interrupt handler..LP*/#include "vxWorks.h"#include "net/mbuf.h"#include "net/protosw.h"#include "net/unixLib.h"#include "ioctl.h"#include "socket.h"#include "errnoLib.h"#include "net/uio.h"#include "net/if.h"#include "net/route.h"#include "netinet/in.h"#include "netinet/in_systm.h"#include "netinet/ip.h"#include "netinet/ip_var.h"#include "netinet/in_var.h"#include "netinet/if_ether.h"#include "etherLib.h"#include "vme.h"#include "iv.h"#include "iosLib.h"#include "ioLib.h"#include "memLib.h"#include "net/systm.h"#include "net/if_subr.h"#include "sysLib.h"#include "vxLib.h"#include "stdio.h"#include "intLib.h"#include "logLib.h"#include "string.h"#include "netLib.h"#include "stdlib.h"#include "semLib.h"#include "cacheLib.h"#include "drv/netif/if_ultra.h"/* defines */#define	NULTRA	1	/* max number of ULTRA controllers *//* typedefs */typedef struct ifnet IFNET;                 /* real Interface Data Record *//* globals *//* locals */LOCAL ULTRA_SOFTC ultra_softc [NULTRA];LOCAL IRQ_TABLE irqTable [] =     {    { 2, 0x15},    { 2, 0x15},    { 2, 0x15},    { 3, 0x19},    { 3, 0x19},    { 5, 0x1d},    { 5, 0x1d},    { 7, 0x51},    { 7, 0x51},    { 7, 0x51},    {10, 0x55},    {11, 0x59},    {11, 0x59},    {11, 0x59},    {11, 0x59},    {15, 0x5d}    };LOCAL BOOL ultraAttached = FALSE;LOCAL SEMAPHORE  ultraSyncSem;           /* syncronization semaphore *//* forward static functions */       void ultraShow	(int unit, BOOL zap);       void ultradetach (int unit);LOCAL  int  ultrainit	(int unit);LOCAL  void ultrareset	(int unit);LOCAL  int  ultraioctl	(struct ifnet *ifp, int cmd, caddr_t data);#ifdef BSD43_DRIVERLOCAL  int  ultraoutput (struct ifnet *ifp, struct mbuf *m0, struct sockaddr			 *dst);#endifLOCAL  void ultraInit	(int unit);LOCAL  void ultraIntr	(int unit);LOCAL  void ultraGet	(int unit);#ifdef BSD43_DRIVERLOCAL  void ultraPut	(int unit);#elseLOCAL  void ultraPut 	(ULTRA_SOFTC *sc);#endif/********************************************************************************* ultraattach - publish `ultra' interface and initialize device** This routine attaches an `ultra' Ethernet interface to the network if the* device exists.  It makes the interface available by filling in the network* interface record.  The system will initialize the interface when it is ready* to accept packets.** RETURNS: OK or ERROR.** SEE ALSO: ifLib, netShow*/STATUS ultraattach     (    int unit,           /* unit number */    int ioAddr,         /* address of ultra's shared memory */    int ivec,           /* interrupt vector to connect to */    int ilevel,         /* interrupt level */    int memAddr,        /* address of ultra's shared memory */    int memSize,        /* size of ultra's shared memory */    int config		/* 0: RJ45 + AUI(Thick)  1: RJ45 + BNC(Thin) */    )    {    FAST ULTRA_SOFTC *sc = &ultra_softc[unit];    if ((UINT)unit >= NULTRA)	{        errnoSet (S_iosLib_CONTROLLER_NOT_PRESENT);	return (ERROR);	}    sc->ioAddr		= ioAddr;    sc->memAddr		= memAddr;    sc->memSize		= memSize;    sc->intLevel	= irqTable[ilevel].irq;    sc->intVec		= ivec;    sc->config		= config;    sc->transmitPage[0]	= ULTRA_TSTART0;    sc->transmitPage[1]	= ULTRA_TSTART1;    sc->transmitCnt	= 0;    /* synchronization semaphore must be initialized only once */    if (!ultraAttached)	semBInit (&ultraSyncSem, SEM_Q_FIFO, SEM_FULL);    (void) intConnect ((VOIDFUNCPTR *)INUM_TO_IVEC (ivec), 		       (VOIDFUNCPTR)ultraIntr, unit);#ifdef BSD43_DRIVER    ether_attach (&sc->es_if, unit, "ultra", (FUNCPTR)ultrainit, 	  (FUNCPTR)ultraioctl, (FUNCPTR)ultraoutput, (FUNCPTR)ultrareset);#else    ether_attach (                 (IFNET *) & sc->es_ac,                 unit,                 "ultra",                 (FUNCPTR) ultrainit,                 (FUNCPTR) ultraioctl,                 (FUNCPTR) ether_output,    /* generic ether_output */                  (FUNCPTR) ultrareset                 );    sc->es_if.if_start = (FUNCPTR) ultraPut;#endif     ultrainit (unit);    ultraAttached = TRUE;    return (OK);    }/********************************************************************************* ultrareset - reset the interface** RETURNS: N/A*/LOCAL void ultrareset     (    int unit 	/* device unit number */    )    {    FAST ULTRA_SOFTC *sc   = &ultra_softc [unit];    int s = splnet ();    sc->stat.reset++;    sysIntDisablePIC (sc->intLevel);    sc->es_if.if_flags = 0;    splx (s);    }/********************************************************************************* ultrainit - initialize ultra** Restart the link level software on the board and mark the interface up.** RETURNS: 0*/LOCAL int ultrainit     (    int unit 	/* device unit number */    )    {    FAST ULTRA_SOFTC *sc = &ultra_softc[unit];    int s = splnet ();    ultraInit (unit);    sysIntEnablePIC (sc->intLevel);    sc->es_if.if_flags |= IFF_UP|IFF_RUNNING;	/* open for business*/    splx (s);    return (0);    }#ifdef BSD43_DRIVER/********************************************************************************* ultraoutput - ethernet output routine** Encapsulate a packet of type family for the local net.* Use trailer local net encapsulation if enough data in first* packet leaves a multiple of 512 bytes of data in remainder.* If destination is this address or broadcast, send packet to* loop device to kludge around the fact that 3com interfaces can't* talk to themselves.** RETURNS:  OK if successful, otherwise errno.*/LOCAL int ultraoutput     (    struct ifnet *ifp,		/* device structure */    struct mbuf *m0,		/* mbuf containing packet */    struct sockaddr *dst 	/* destination address */    )    {    return (ether_output (ifp, m0, dst, (FUNCPTR)ultraPut,			  &ultra_softc [ifp->if_unit].es_ac));    }#endif/********************************************************************************* ultraioctl - ioctl for interface** RETURNS: OK if successful, otherwise errno.*/LOCAL int ultraioctl     (    FAST struct ifnet *ifp,	/* device structure */    int cmd,			/* ioctl cmd code */    caddr_t data 		/* ioctl argument */    )    {    int status = OK;    int s = splimp();    short flags;    switch (cmd)	{	case SIOCSIFADDR:            ((struct arpcom *)ifp)->ac_ipaddr = IA_SIN (data)->sin_addr;            arpwhohas ((struct arpcom *)ifp, &IA_SIN (data)->sin_addr);	    break;	case SIOCSIFFLAGS:            flags = ifp->if_flags;	    if (ifp->if_flags & IFF_UP)                ifp->if_flags = flags | (IFF_UP | IFF_RUNNING);            else                ifp->if_flags = flags & ~(IFF_UP|IFF_RUNNING);	    break;	default:	    status = EINVAL;	}    splx (s);    return (status);    }/********************************************************************************* ultraIntr - Ethernet interface interrupt** Hand off reading of packets from the interface to task level.** RETURNS: N/A*/LOCAL void ultraIntr     (    int unit 	/* device unit number */    )    {    FAST ULTRA_SOFTC *sc = &ultra_softc[unit];    UCHAR istat;    int   nCnt = 0;    /* Acknowledge interrupt, get Transmit/Receive status */    sc->istat = 0;    do  {        istat = sysInByte (LAN_INTSTAT (sc->ioAddr));        sysOutByte (LAN_INTSTAT (sc->ioAddr), istat);        sc->istat |= istat;        nCnt ++;        }    while (istat != 0);    sc->tstat = sysInByte (LAN_TSTAT (sc->ioAddr));    sc->rstat = sysInByte (LAN_RSTAT (sc->ioAddr));    /* get xxxCount Reg that is cleared after read access */    sc->stat.interrupts++;    sc->stat.collisions += sysInByte (LAN_COLCNT (sc->ioAddr));    sc->stat.aligns += sysInByte (LAN_ALICNT (sc->ioAddr));    sc->stat.crcs += sysInByte (LAN_CRCCNT (sc->ioAddr));    sc->stat.missed += sysInByte (LAN_MPCNT (sc->ioAddr));    if (sc->istat & ISTAT_RXE) /* Receive-error */	{        sc->es_if.if_ierrors++;	sc->stat.rerror++;	if (sc->rstat & RSTAT_OVER)	    sc->stat.overruns++;	if (sc->rstat & RSTAT_DIS)	    sc->stat.disabled++;	if (sc->rstat & RSTAT_DFR)	    sc->stat.deferring++;	}    if (sc->istat & (ISTAT_PRX | ISTAT_OVW)) /* Receive, Overwrite */	{        if (sc->istat & ISTAT_OVW)            {	    sc->stat.overwrite++;            sc->es_if.if_ierrors++;            }        sysOutByte (LAN_CMD (sc->ioAddr), CMD_PS0);        sc->current = sysInByte (LAN_CURR (sc->ioAddr));        sysOutByte (LAN_CMD (sc->ioAddr), 0);	if ((sc->flags & RXING) == 0)	    {            sc->flags |= RXING;	    (void) netJobAdd ((FUNCPTR)ultraGet, unit, 0,0,0,0);	    }	if (sc->rstat & RSTAT_PRX)	    sc->stat.rnoerror++;	}    if (sc->istat & (ISTAT_TXE | ISTAT_PTX)) /* Transmit-error, Transmit */	{	semGive (&ultraSyncSem);#if FALSE  /* BEGIN TEST CODE */	if (sc->es_if.if_snd.ifq_head != NULL)	    {#ifdef BSD43_DRIVER	    netJobAdd ((FUNCPTR) ultraPut, unit, 0,0,0,0);#else	    netJobAdd ((FUNCPTR) ultraPut, (int)sc, 0,0,0,0);#endif	    }#endif /* END TEST CODE */        if (sc->istat & ISTAT_TXE)            {	    sc->stat.terror++;            sc->es_if.if_oerrors++;            sc->es_if.if_opackets--;            }	if (sc->tstat & TSTAT_ABORT)	    {	    sc->stat.aborts++;	    sc->stat.collisions += 16;	    }	if (sc->tstat & TSTAT_UNDER)	    sc->stat.underruns++;	if (sc->tstat & TSTAT_CDH)	    sc->stat.heartbeats++;	if (sc->tstat & TSTAT_OWC)	    sc->stat.outofwindow++;	if (sc->tstat & TSTAT_PTX)	    sc->stat.tnoerror++;	}    }/********************************************************************************* ultraGet - read a packet off the interface** Copy packets from a RING into an mbuf and hand it to the next higher layer.** RETURNS: N/A*/LOCAL void ultraGet     (    int unit	/* device unit number */    )

⌨️ 快捷键说明

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