Skip to content
Snippets Groups Projects
atarilance.c 33.3 KiB
Newer Older
Linus Torvalds's avatar
Linus Torvalds committed
/* 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 General 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/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/module.h>
#include <linux/stddef.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/errno.h>
#include <linux/skbuff.h>
#include <linux/interrupt.h>
#include <linux/init.h>
#include <linux/bitops.h>

#include <asm/setup.h>
#include <asm/irq.h>
#include <asm/atarihw.h>
#include <asm/atariints.h>
#include <asm/io.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_DEBUG
static int lance_debug = LANCE_DEBUG;
#else
static int lance_debug = 1;
#endif
module_param(lance_debug, int, 0);
Linus Torvalds's avatar
Linus Torvalds committed
MODULE_PARM_DESC(lance_debug, "atarilance debug level (0-3)");
MODULE_LICENSE("GPL");

/* 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)

#define TX_TIMEOUT	(HZ/5)
Linus Torvalds's avatar
Linus Torvalds committed

/* 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;
};
Loading
Loading full blame...