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

📄 atarilance.c

📁 powerpc内核mpc8241linux系统下net驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/* atarilance.c: Ethernet driver for VME Lance cards on the Atari *//*	Written 1995/96 by Roman Hodek (Roman.Hodek@informatik.uni-erlangen.de)	This software may be used and distributed according to the terms	of the GNU Public License, incorporated herein by reference.	This drivers was written with the following sources of reference:	 - The driver for the Riebl Lance card by the TU Vienna.	 - The modified TUW driver for PAM's VME cards	 - The PC-Linux driver for Lance cards (but this is for bus master       cards, not the shared memory ones)	 - The Amiga Ariadne driver	v1.0: (in 1.2.13pl4/0.9.13)	      Initial version	v1.1: (in 1.2.13pl5)	      more comments		  deleted some debugging stuff		  optimized register access (keep AREG pointing to CSR0)		  following AMD, CSR0_STRT should be set only after IDON is detected		  use memcpy() for data transfers, that also employs long word moves		  better probe procedure for 24-bit systems          non-VME-RieblCards need extra delays in memcpy		  must also do write test, since 0xfxe00000 may hit ROM		  use 8/32 tx/rx buffers, which should give better NFS performance;		    this is made possible by shifting the last packet buffer after the		    RieblCard reserved area    v1.2: (in 1.2.13pl8)	      again fixed probing for the Falcon; 0xfe01000 hits phys. 0x00010000		  and thus RAM, in case of no Lance found all memory contents have to		  be restored!		  Now possible to compile as module.	v1.3: 03/30/96 Jes Sorensen, Roman (in 1.3)	      Several little 1.3 adaptions		  When the lance is stopped it jumps back into little-endian		  mode. It is therefore necessary to put it back where it		  belongs, in big endian mode, in order to make things work.		  This might be the reason why multicast-mode didn't work		  before, but I'm not able to test it as I only got an Amiga		  (we had similar problems with the A2065 driver).*/static char *version = "atarilance.c: v1.3 04/04/96 "					   "Roman.Hodek@informatik.uni-erlangen.de\n";#include <linux/module.h>#include <linux/stddef.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/string.h>#include <linux/ptrace.h>#include <linux/errno.h>#include <linux/malloc.h>#include <linux/interrupt.h>#include <linux/init.h>#include <asm/setup.h>#include <asm/irq.h>#include <asm/atarihw.h>#include <asm/atariints.h>#include <asm/bitops.h>#include <asm/io.h>#include <linux/netdevice.h>#include <linux/etherdevice.h>#include <linux/skbuff.h>/* Debug level: *  0 = silent, print only serious errors *  1 = normal, print error messages *  2 = debug, print debug infos *  3 = debug, print even more debug infos (packet data) */#define	LANCE_DEBUG	1#ifdef LANCE_DEBUGstatic int lance_debug = LANCE_DEBUG;#elsestatic int lance_debug = 1;#endifMODULE_PARM(lance_debug, "i");/* Print debug messages on probing? */#undef LANCE_DEBUG_PROBE#define	DPRINTK(n,a)							\	do {										\		if (lance_debug >= n)					\			printk a;							\	} while( 0 )#ifdef LANCE_DEBUG_PROBE# define PROBE_PRINT(a)	printk a#else# define PROBE_PRINT(a)#endif/* These define the number of Rx and Tx buffers as log2. (Only powers * of two are valid) * Much more rx buffers (32) are reserved than tx buffers (8), since receiving * is more time critical then sending and packets may have to remain in the * board's memory when main memory is low. */#define TX_LOG_RING_SIZE			3#define RX_LOG_RING_SIZE			5/* These are the derived values */#define TX_RING_SIZE			(1 << TX_LOG_RING_SIZE)#define TX_RING_LEN_BITS		(TX_LOG_RING_SIZE << 5)#define	TX_RING_MOD_MASK		(TX_RING_SIZE - 1)#define RX_RING_SIZE			(1 << RX_LOG_RING_SIZE)#define RX_RING_LEN_BITS		(RX_LOG_RING_SIZE << 5)#define	RX_RING_MOD_MASK		(RX_RING_SIZE - 1)/* The LANCE Rx and Tx ring descriptors. */struct lance_rx_head {	unsigned short			base;		/* Low word of base addr */	volatile unsigned char	flag;	unsigned char			base_hi;	/* High word of base addr (unused) */	short					buf_length;	/* This length is 2s complement! */	volatile short			msg_length;	/* This length is "normal". */};struct lance_tx_head {	unsigned short			base;		/* Low word of base addr */	volatile unsigned char	flag;	unsigned char			base_hi;	/* High word of base addr (unused) */	short					length;		/* Length is 2s complement! */	volatile short			misc;};struct ringdesc {	unsigned short	adr_lo;		/* Low 16 bits of address */	unsigned char	len;		/* Length bits */	unsigned char	adr_hi;		/* High 8 bits of address (unused) */};/* The LANCE initialization block, described in databook. */struct lance_init_block {	unsigned short	mode;		/* Pre-set mode */	unsigned char	hwaddr[6];	/* Physical ethernet address */	unsigned		filter[2];	/* Multicast filter (unused). */	/* Receive and transmit ring base, along with length bits. */	struct ringdesc	rx_ring;	struct ringdesc	tx_ring;};/* The whole layout of the Lance shared memory */struct lance_memory {	struct lance_init_block	init;	struct lance_tx_head	tx_head[TX_RING_SIZE];	struct lance_rx_head	rx_head[RX_RING_SIZE];	char					packet_area[0];	/* packet data follow after the											 * init block and the ring											 * descriptors and are located											 * at runtime */};/* RieblCard specifics: * The original TOS driver for these cards reserves the area from offset * 0xee70 to 0xeebb for storing configuration data. Of interest to us is the * Ethernet address there, and the magic for verifying the data's validity. * The reserved area isn't touch by packet buffers. Furthermore, offset 0xfffe * is reserved for the interrupt vector number. */#define	RIEBL_RSVD_START	0xee70#define	RIEBL_RSVD_END		0xeec0#define RIEBL_MAGIC			0x09051990#define RIEBL_MAGIC_ADDR	((unsigned long *)(((char *)MEM) + 0xee8a))#define RIEBL_HWADDR_ADDR	((unsigned char *)(((char *)MEM) + 0xee8e))#define RIEBL_IVEC_ADDR		((unsigned short *)(((char *)MEM) + 0xfffe))/* This is a default address for the old RieblCards without a battery * that have no ethernet address at boot time. 00:00:36:04 is the * prefix for Riebl cards, the 00:00 at the end is arbitrary. */static unsigned char OldRieblDefHwaddr[6] = {	0x00, 0x00, 0x36, 0x04, 0x00, 0x00};/* I/O registers of the Lance chip */struct lance_ioreg {/* base+0x0 */	volatile unsigned short	data;/* base+0x2 */	volatile unsigned short	addr;				unsigned char			_dummy1[3];/* base+0x7 */	volatile unsigned char	ivec;				unsigned char			_dummy2[5];/* base+0xd */	volatile unsigned char	eeprom;				unsigned char			_dummy3;/* base+0xf */	volatile unsigned char	mem;};/* Types of boards this driver supports */enum lance_type {	OLD_RIEBL,		/* old Riebl card without battery */	NEW_RIEBL,		/* new Riebl card with battery */	PAM_CARD		/* PAM card with EEPROM */};static char *lance_names[] = {	"Riebl-Card (without battery)",	"Riebl-Card (with battery)",	"PAM intern card"};/* The driver's private device structure */struct lance_private {	enum lance_type		cardtype;	struct lance_ioreg	*iobase;	struct lance_memory	*mem;	int					cur_rx, cur_tx;	/* The next free ring entry */	int					dirty_tx;		/* Ring entries to be freed. */						/* copy function */	void				*(*memcpy_f)( void *, const void *, size_t );	struct net_device_stats stats;/* These two must be ints for set_bit() */	int					tx_full;	int					lock;};/* I/O register access macros */#define	MEM		lp->mem#define	DREG	IO->data#define	AREG	IO->addr#define	REGA(a)	( AREG = (a), DREG )/* Definitions for packet buffer access: */#define PKT_BUF_SZ		1544/* Get the address of a packet buffer corresponding to a given buffer head */#define	PKTBUF_ADDR(head)	(((unsigned char *)(MEM)) + (head)->base)/* Possible memory/IO addresses for probing */struct lance_addr {	unsigned long	memaddr;	unsigned long	ioaddr;	int				slow_flag;} lance_addr_list[] = {	{ 0xfe010000, 0xfe00fff0, 0 },	/* RieblCard VME in TT */	{ 0xffc10000, 0xffc0fff0, 0 },	/* RieblCard VME in MegaSTE									   (highest byte stripped) */	{ 0xffe00000, 0xffff7000, 1 },	/* RieblCard in ST									   (highest byte stripped) */	{ 0xffd00000, 0xffff7000, 1 },	/* RieblCard in ST with hw modif. to									   avoid conflict with ROM									   (highest byte stripped) */	{ 0xffcf0000, 0xffcffff0, 0 },	/* PAMCard VME in TT and MSTE									   (highest byte stripped) */	{ 0xfecf0000, 0xfecffff0, 0 },	/* Rhotron's PAMCard VME in TT and MSTE									   (highest byte stripped) */};#define	N_LANCE_ADDR	(sizeof(lance_addr_list)/sizeof(*lance_addr_list))/* Definitions for the Lance *//* tx_head flags */#define TMD1_ENP		0x01	/* end of packet */#define TMD1_STP		0x02	/* start of packet */#define TMD1_DEF		0x04	/* deferred */#define TMD1_ONE		0x08	/* one retry needed */#define TMD1_MORE		0x10	/* more than one retry needed */#define TMD1_ERR		0x40	/* error summary */#define TMD1_OWN 		0x80	/* ownership (set: chip owns) */#define TMD1_OWN_CHIP	TMD1_OWN#define TMD1_OWN_HOST	0/* tx_head misc field */#define TMD3_TDR		0x03FF	/* Time Domain Reflectometry counter */#define TMD3_RTRY		0x0400	/* failed after 16 retries */#define TMD3_LCAR		0x0800	/* carrier lost */#define TMD3_LCOL		0x1000	/* late collision */#define TMD3_UFLO		0x4000	/* underflow (late memory) */#define TMD3_BUFF		0x8000	/* buffering error (no ENP) *//* rx_head flags */#define RMD1_ENP		0x01	/* end of packet */#define RMD1_STP		0x02	/* start of packet */#define RMD1_BUFF		0x04	/* buffer error */#define RMD1_CRC		0x08	/* CRC error */#define RMD1_OFLO		0x10	/* overflow */#define RMD1_FRAM		0x20	/* framing error */#define RMD1_ERR		0x40	/* error summary */#define RMD1_OWN 		0x80	/* ownership (set: ship owns) */#define RMD1_OWN_CHIP	RMD1_OWN#define RMD1_OWN_HOST	0/* register names */#define CSR0	0		/* mode/status */#define CSR1	1		/* init block addr (low) */#define CSR2	2		/* init block addr (high) */#define CSR3	3		/* misc */#define CSR8	8	  	/* address filter */#define CSR15	15		/* promiscuous mode *//* CSR0 *//* (R=readable, W=writeable, S=set on write, C=clear on write) */#define CSR0_INIT	0x0001		/* initialize (RS) */#define CSR0_STRT	0x0002		/* start (RS) */#define CSR0_STOP	0x0004		/* stop (RS) */#define CSR0_TDMD	0x0008		/* transmit demand (RS) */#define CSR0_TXON	0x0010		/* transmitter on (R) */#define CSR0_RXON	0x0020		/* receiver on (R) */#define CSR0_INEA	0x0040		/* interrupt enable (RW) */#define CSR0_INTR	0x0080		/* interrupt active (R) */#define CSR0_IDON	0x0100		/* initialization done (RC) */#define CSR0_TINT	0x0200		/* transmitter interrupt (RC) */#define CSR0_RINT	0x0400		/* receiver interrupt (RC) */#define CSR0_MERR	0x0800		/* memory error (RC) */#define CSR0_MISS	0x1000		/* missed frame (RC) */#define CSR0_CERR	0x2000		/* carrier error (no heartbeat :-) (RC) */#define CSR0_BABL	0x4000		/* babble: tx-ed too many bits (RC) */#define CSR0_ERR	0x8000		/* error (RC) *//* CSR3 */#define CSR3_BCON	0x0001		/* byte control */#define CSR3_ACON	0x0002		/* ALE control */#define CSR3_BSWP	0x0004		/* byte swap (1=big endian) *//***************************** Prototypes *****************************/static int addr_accessible( volatile void *regp, int wordflag, int                            writeflag );static unsigned long lance_probe1( struct device *dev, struct lance_addr                                   *init_rec );static int lance_open( struct device *dev );static void lance_init_ring( struct device *dev );static int lance_start_xmit( struct sk_buff *skb, struct device *dev );static void lance_interrupt( int irq, void *dev_id, struct pt_regs *fp );static int lance_rx( struct device *dev );static int lance_close( struct device *dev );static struct net_device_stats *lance_get_stats( struct device *dev );static void set_multicast_list( struct device *dev );static int lance_set_mac_address( struct device *dev, void *addr );/************************* End of Prototypes **************************/void *slow_memcpy( void *dst, const void *src, size_t len ){	char *cto = dst;	const char *cfrom = src;	while( len-- ) {		*cto++ = *cfrom++;		MFPDELAY();	}	return( dst );}__initfunc(int atarilance_probe( struct device *dev )){	int i;	static int found = 0;	if (!MACH_IS_ATARI || found)		/* Assume there's only one board possible... That seems true, since		 * the Riebl/PAM board's address cannot be changed. */		return( ENODEV );	for( i = 0; i < N_LANCE_ADDR; ++i ) {		if (lance_probe1( dev, &lance_addr_list[i] )) {			found = 1;			return( 0 );		}	}	return( ENODEV );}/* Derived from hwreg_present() in atari/config.c: */__initfunc(static int addr_accessible( volatile void *regp, int wordflag, int writeflag )){	int		ret;

⌨️ 快捷键说明

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