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

📄 if_fe.c

📁 很好的一个嵌入式linux平台下的bootloader
💻 C
📖 第 1 页 / 共 5 页
字号:
/* $Id: if_fe.c,v 1.8 1999/05/13 11:45:22 nigel Exp $ *//* * All Rights Reserved, Copyright (C) Fujitsu Limited 1995 * * This software may be used, modified, copied, distributed, and sold, in * both source and binary form provided that the above copyright, these * terms and the following disclaimer are retained.  The name of the author * and/or the contributor may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND THE CONTRIBUTOR ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR THE CONTRIBUTOR BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */#define FE_VERSION "if_fe.c ver. 0.8a"/* * Device driver for Fujitsu MB86960A/MB86965A based Ethernet cards. * To be used with FreeBSD 2.0 RELEASE. * Contributed by M.S. <seki@sysrap.cs.fujitsu.co.jp> * * This version is intended to be a generic template for various * MB86960A/MB86965A based Ethernet cards.  It currently supports * Fujitsu FMV-180 series (i.e., FMV-181 and FMV-182) and Allied- * Telesis AT1700 series and RE2000 series.  There are some * unnecessary hooks embedded, which are primarily intended to support * other types of Ethernet cards, but the author is not sure whether * they are useful. * * This software is a derivative work of if_ed.c version 1.56 by David * Greenman available as a part of FreeBSD 2.0 RELEASE source distribution. * * The following lines are retained from the original if_ed.c: * * Copyright (C) 1993, David Greenman. This software may be used, modified, *   copied, distributed, and sold, in both source and binary form provided *   that the above copyright and these terms are retained. Under no *   circumstances is the author responsible for the proper functioning *   of this software, nor does the author assume any responsibility *   for damages incurred with its use. */#ifdef PROM#define NFE 1#ifndef INET#define INET#endif#else#include "fe.h"#endif#if NBPFILTER > 0#include "bpfilter.h"#endif#ifdef PROM#include "sys/param.h"#include "sys/systm.h"#include "sys/errno.h"#include "sys/ioctl.h"#include "sys/mbuf.h"#include "sys/socket.h"#include "sys/syslog.h"#include "net/if.h"#include "net/if_dl.h"#include "net/if_types.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#ifdef NS#include "netns/ns.h"#include "netns/ns_if.h"#endif#if NBPFILTER > 0#include "net/bpf.h"#include "net/bpfdesc.h"#endif#include "mips.h"#include "sbd.h"#include "mb86960.h"#include "if_fereg.h"#else /* PROM */#include <sys/param.h>#include <sys/systm.h>#include <sys/errno.h>#include <sys/ioctl.h>#include <sys/mbuf.h>#include <sys/socket.h>#include <sys/syslog.h>#include <sys/devconf.h>#include <net/if.h>#include <net/if_dl.h>#include <net/if_types.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#ifdef NS#include <netns/ns.h>#include <netns/ns_if.h>#endif#if NBPFILTER > 0#include <net/bpf.h>#include <net/bpfdesc.h>#endif#include <machine/clock.h>#include <i386/isa/isa.h>#include <i386/isa/isa_device.h>#include <i386/isa/icu.h>#include <i386/isa/ic/mb86960.h>#include <i386/isa/if_fereg.h>#endif /* PROM */#ifdef __GNUC__#define INLINE inline#else#define INLINE#endif/* * Default settings for fe driver specific options. * They can be set in config file by "options" statements. *//* * Debug control. * 0: No debug at all.  All debug specific codes are stripped off. * 1: Silent.  No debug messages are logged except emergent ones. * 2: Brief.  Lair events and/or important information are logged. * 3: Detailed.  Logs all information which *may* be useful for debugging. * 4: Trace.  All actions in the driver is logged.  Super verbose. */#ifndef FE_DEBUG#define FE_DEBUG	1#endif/* * Delay padding of short transmission packets to minimum Ethernet size. * This may or may not gain performance.  An EXPERIMENTAL option. */#ifndef FE_DELAYED_PADDING#define FE_DELAYED_PADDING 0#endif/* * Transmit just one packet per a "send"command to 86960. * This option is intended for performance test.  An EXPERIMENTAL option. */#ifndef FE_SINGLE_TRANSMISSION#define FE_SINGLE_TRANSMISSION 0#endif#ifndef FE_SYS_BUS_WIDTH#ifdef PROM#define FE_SYS_BUS_WIDTH	8#else#define FE_SYS_BUS_WIDTH	16#endif#endif/* * Device configuration flags. *//* DLCR6 settings.  */#define FE_FLAGS_DLCR6_VALUE	0x007F/* Force DLCR6 override.  */#define FE_FLAGS_OVERRIDE_DLCR6	0x0080/* A cludge for PCMCIA support.  */#define FE_FLAGS_PCMCIA		0x8000/* Shouldn't this be defined somewhere else such as isa_device.h?  */#define NO_IOADDR 0xFFFFFFFF/* Identification of the driver version.  */static char const fe_version [] = FE_VERSION " / " FE_REG_VERSION;/* * Supported hardware (Ethernet card) types * This information is currently used only for debugging */enum fe_type{	/* For cards which are successfully probed but not identified.  */	FE_TYPE_UNKNOWN,	/* Fujitsu FMV-180 series.  */	FE_TYPE_FMV181,	FE_TYPE_FMV182,	/* Allied-Telesis AT1700 series and RE2000 series.  */	FE_TYPE_AT1700,	/* PCMCIA by Fujitsu.  */	FE_TYPE_MBH10302,	FE_TYPE_MBH10304,	/* More can be here.  */};/* * Data type for a multicast address filter on 86960. */struct fe_filter { u_char data [ FE_FILTER_LEN ]; };#ifdef PROM#define FE_FILTER_NOTHING 0,0,0,0,0,0,0,0#define FE_FILTER_ALL 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff#endif/* * Special filter values. */static struct fe_filter const fe_filter_nothing = { FE_FILTER_NOTHING };static struct fe_filter const fe_filter_all     = { FE_FILTER_ALL };/* * fe_softc: per line info and status */struct fe_softc {	/* Used by "common" codes.  */	struct arpcom arpcom;	/* ethernet common */#ifndef PROM	/* Used by config codes.  */	struct kern_devconf kdc;/* Kernel configuration database info.  */#endif	/* Set by probe() and not modified in later phases.  */	enum fe_type type;	/* interface type code */	char * typestr;		/* printable name of the interface.  */#ifdef PROM	u_int addr;		/* MB86960A I/O base address */#else	u_short addr;		/* MB86960A I/O base address */#endif	u_short txb_size;	/* size of TX buffer, in bytes  */	u_char proto_dlcr4;	/* DLCR4 prototype.  */	u_char proto_dlcr5;	/* DLCR5 prototype.  */	u_char proto_dlcr6;	/* DLCR6 prototype.  */	u_char proto_dlcr7;	/* DLCR7 prototype.  */	/* Vendor specific hooks.  */	void ( * init )( struct fe_softc * ); /* Just before fe_init().  */	void ( * stop )( struct fe_softc * ); /* Just after fe_stop().  */#if NBPFILTER > 0	/* For BPF.  */	caddr_t bpf;		/* BPF "magic cookie" */#endif	/* Transmission buffer management.  */	u_short txb_free;	/* free bytes in TX buffer  */	u_char txb_count;	/* number of packets in TX buffer  */	u_char txb_sched;	/* number of scheduled packets  */	u_char txb_padding;	/* number of delayed padding bytes  */	/* Multicast address filter management.  */	u_char filter_change;	/* MARs must be changed ASAP. */	struct fe_filter filter;/* new filter value.  */}       fe_softc[NFE];/* Frequently accessed members in arpcom and kdc.  */#define sc_if		arpcom.ac_if#define sc_unit		arpcom.ac_if.if_unit#define sc_enaddr	arpcom.ac_enaddr#ifndef PROM#define sc_dcstate	kdc.kdc_state#define sc_description	kdc.kdc_description#endif/* * Some entry functions receive a "struct ifnet *" typed pointer as an * argument.  It points to arpcom.ac_if of our softc.  Remember arpcom.ac_if * is located at very first of the fe_softc struct.  So, there is no * difference between "struct fe_softc *" and "struct ifnet *" at the machine * language level.  We just cast to turn a "struct ifnet *" value into "struct * fe_softc * value".  If this were C++, we would need no such cast at all. */#define IFNET2SOFTC(P)	( ( struct fe_softc * )(P) )/* Public entry point.  This is the only functoin which must be external.  */void		feintr		( int );/* Standard driver entry points.  These can be static.  */#ifndef PROMint		fe_probe	( struct isa_device * );int		fe_attach	( struct isa_device * );#endifvoid		fe_init		( int );int		fe_ioctl	( struct ifnet *, int, caddr_t );void		fe_start	( struct ifnet * );void		fe_reset	( int );void		fe_watchdog	( int );/* Local functions.  Order of declaration is confused.  FIXME.  */#ifndef PROMstatic int	fe_probe_fmv	( struct isa_device *, struct fe_softc * );static int	fe_probe_ati	( struct isa_device *, struct fe_softc * );static int	fe_probe_mbh	( struct isa_device *, struct fe_softc * );static void	fe_init_mbh	( struct fe_softc * );#endifstatic int	fe_get_packet	( struct fe_softc *, u_short );static void	fe_stop		( int );static void	fe_tint		( struct fe_softc *, u_char );static void	fe_rint		( struct fe_softc *, u_char );static void	fe_xmit		( struct fe_softc * );static void	fe_write_mbufs	( struct fe_softc *, struct mbuf * );static struct fe_filter		fe_mcaf		( struct fe_softc * );static int	fe_hash		( u_char * );static void	fe_setmode	( struct fe_softc * );static void	fe_loadmar	( struct fe_softc * );static void	fe_setlinkaddr	( struct fe_softc * );#if FE_DEBUG >= 1static void	fe_dump		( int, struct fe_softc *, char * );#endif/* Ethernet constants.  To be defined in if_ehter.h?  FIXME.  */#define ETHER_MIN_LEN	60	/* with header, without CRC. */#define ETHER_MAX_LEN	1514	/* with header, without CRC. */#define ETHER_ADDR_LEN	6	/* number of bytes in an address.  */#define ETHER_TYPE_LEN	2	/* number of bytes in a data type field.  */#define ETHER_HDR_SIZE	14	/* src addr, dst addr, and data type.  */#define ETHER_CRC_LEN	4	/* number of bytes in CRC field.  */#ifndef PROM/* Driver struct used in the config code.  This must be public (external.)  */struct isa_driver fedriver ={	fe_probe,	fe_attach,	"fe",	0		/* Assume we are insensitive.  FIXME.  */};/* Initial value for a kdc struct.  */static struct kern_devconf const fe_kdc_template ={	0, 0, 0,	"fe", 0, { MDDT_ISA, 0, "net" },	isa_generic_externalize, 0, 0, ISA_EXTERNALLEN,	&kdc_isa0,		/* We are an ISA device.  */	0,	DC_UNCONFIGURED,	/* Not yet configured.  */	"Ethernet (fe)",	/* Tentative description (filled in later.)  */	DC_CLS_NETIF		/* We are a network interface.  */};#endif/* * Fe driver specific constants which relate to 86960/86965. * They are here (not in if_fereg.h), since selection of those * values depend on driver design.  I want to keep definitions in * if_fereg.h "clean", so that if someone wrote another driver * for 86960/86965, if_fereg.h were usable unchanged. * * The above statement sounds somothing like it's better to name * it "ic/mb86960.h" but "if_fereg.h"...  Should I do so?  FIXME. *//* Interrupt masks  */#ifndef FE_TMASK#define FE_TMASK ( FE_D0_COLL16 | FE_D0_TXDONE | FE_D0_BUSERR \    		 | FE_D0_JABBER )#endif#ifndef FE_RMASK#define FE_RMASK ( FE_D3_OVRFLO | FE_D3_CRCERR | FE_D3_BUSERR \		 | FE_D3_ALGERR | FE_D3_PKTRDY )#endif/* Maximum number of iterrations for a receive interrupt.  */#define FE_MAX_RECV_COUNT ( ( 65536 - 2048 * 2 ) / 64 )	/* Maximum size of SRAM is 65536,	 * minimum size of transmission buffer in fe is 2x2KB,	 * and minimum amount of received packet including headers	 * added by the chip is 64 bytes.	 * Hence FE_MAX_RECV_COUNT is the upper limit for number	 * of packets in the receive buffer.  *//* * Convenient routines to access contiguous I/O ports. */#ifdef PROMextern void sbdfeoutb (unsigned int base, int offset, u_char v);extern void sbdfeoutsb(unsigned int base, int offset, u_char *addr, int len);extern u_char sbdfeinb(unsigned int base, int offset);extern void sbdfeinsb(unsigned int base, int offset, u_char *addr, int len);extern u_short sbdfeinw(unsigned int base, int offset);extern void sbdfeinsw(unsigned int base, int offset, u_short *addr, int len);extern void sbdfeoutw(unsigned int base, int offset, u_short v);extern void sbdfeoutsw(unsigned int base, int offset, u_short *addr, int len);#define OUTB(base, offset, v) sbdfeoutb (base, offset, v)#define OUTSB(base, offset, addr, len) sbdfeoutsb(base, offset, addr, len)#define INB(base, offset) sbdfeinb(base, offset)#define INSB(base, offset, addr, len) sbdfeinsb(base, offset, addr, len)#define INW(base, offset) sbdfeinw(base, offset)#define INSW(base, offset, addr, len) sbdfeinsw(base, offset, addr, len)#define OUTW(base, offset,  v) sbdfeoutw(base, offset,  v)#define OUTSW(base, offset, addr, len) sbdfeoutsw(base, offset, addr, len)#else#define OUTB(base,offset,v) outb((base)+(offset),(v))#define OUTSB(base,offset,addr,len) outsb((base)+(offset),(addr),(len))#define INB(base,offset) inb((base)+(offset))#define INSB(base,offset,addr,len) insb((base)+(offset),(addr),(len))#define INW(base,offset) inw((base)+(offset))#define INSW(base,offset,addr,len) insw((base)+(offset), (addr), (len))#define OUTW(base,offset,v) outw((base)+(offset), (v))#define OUTSW(base,offset,addr,len) outsw((base)+(offset), (addr), (len))#endifstatic INLINE voidinblk ( unsigned int base, int offset, u_char * mem, int len ){	while ( --len >= 0 ) {		*mem++ = INB( base, offset++ );	}}static INLINE voidoutblk ( unsigned int base, int offset, u_char const * mem, int len ){	while ( --len >= 0 ) {		OUTB( base, offset++, *mem++ );	}}#ifndef PROM/* * Hardware probe routines. *//* How and where to probe; to support automatic I/O address detection.  */struct fe_probe_list{	int ( * probe ) ( struct isa_device *, struct fe_softc * );	u_short const * addresses;};/* Lists of possible addresses.  */static u_short const fe_fmv_addr [] =	{ 0x220, 0x240, 0x260, 0x280, 0x2A0, 0x2C0, 0x300, 0x340, 0 };static u_short const fe_ati_addr [] =	{ 0x240, 0x260, 0x280, 0x2A0, 0x300, 0x320, 0x340, 0x380, 0 };static struct fe_probe_list const fe_probe_list [] ={	{ fe_probe_fmv, fe_fmv_addr },	{ fe_probe_ati, fe_ati_addr },	{ fe_probe_mbh, NULL },  /* PCMCIAs cannot be auto-detected.  */

⌨️ 快捷键说明

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