Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) /* sun3lance.c: Ethernet driver for SUN3 Lance chip */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)   Sun3 Lance ethernet driver, by Sam Creasey (sammy@users.qual.net).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)   This driver is a part of the linux kernel, and is thus distributed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)   under the GNU General Public License.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)   The values used in LANCE_OBIO and LANCE_IRQ seem to be empirically
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)   true for the correct IRQ and address of the lance registers.  They
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10)   have not been widely tested, however.  What we probably need is a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11)   "proper" way to search for a device in the sun3's prom, but, alas,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12)   linux has no such thing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14)   This driver is largely based on atarilance.c, by Roman Hodek.  Other
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15)   sources of inspiration were the NetBSD sun3 am7990 driver, and the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)   linux sparc lance driver (sunlance.c).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)   There are more assumptions made throughout this driver, it almost
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)   certainly still needs work, but it does work at least for RARP/BOOTP and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)   mounting the root NFS filesystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) static const char version[] =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) "sun3lance.c: v1.2 1/12/2001  Sam Creasey (sammy@sammy.net)\n";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #include <linux/stddef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) #include <linux/string.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) #include <linux/ioport.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) #include <linux/etherdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) #include <linux/pgtable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) #include <asm/cacheflush.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) #include <asm/setup.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) #include <asm/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) #include <asm/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) #include <asm/dvma.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) #include <asm/idprom.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) #include <asm/machines.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) #ifdef CONFIG_SUN3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) #include <asm/sun3mmu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) #include <asm/sun3xprom.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) /* sun3/60 addr/irq for the lance chip.  If your sun is different,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57)    change this. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) #define LANCE_OBIO 0x120000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) #define LANCE_IRQ IRQ_AUTO_3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) /* Debug level:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62)  *  0 = silent, print only serious errors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63)  *  1 = normal, print error messages
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64)  *  2 = debug, print debug infos
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65)  *  3 = debug, print even more debug infos (packet data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) #define	LANCE_DEBUG	0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) #ifdef LANCE_DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) static int lance_debug = LANCE_DEBUG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) static int lance_debug = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) module_param(lance_debug, int, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) MODULE_PARM_DESC(lance_debug, "SUN3 Lance debug level (0-3)");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) #define	DPRINTK(n,a) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	do {  \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 		if (lance_debug >= n)  \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 			printk a; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	} while( 0 )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) /* we're only using 32k of memory, so we use 4 TX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87)    buffers and 16 RX buffers.  These values are expressed as log2. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) #define TX_LOG_RING_SIZE			3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) #define RX_LOG_RING_SIZE			5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) /* These are the derived values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) #define TX_RING_SIZE			(1 << TX_LOG_RING_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) #define TX_RING_LEN_BITS		(TX_LOG_RING_SIZE << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) #define	TX_RING_MOD_MASK		(TX_RING_SIZE - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) #define RX_RING_SIZE			(1 << RX_LOG_RING_SIZE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) #define RX_RING_LEN_BITS		(RX_LOG_RING_SIZE << 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) #define	RX_RING_MOD_MASK		(RX_RING_SIZE - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) /* Definitions for packet buffer access: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) #define PKT_BUF_SZ		1544
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) /* Get the address of a packet buffer corresponding to a given buffer head */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) #define	PKTBUF_ADDR(head)	(void *)((unsigned long)(MEM) | (head)->base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) /* The LANCE Rx and Tx ring descriptors. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) struct lance_rx_head {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	unsigned short	base;		/* Low word of base addr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	volatile unsigned char	flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	unsigned char  base_hi;	/* High word of base addr (unused) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	short buf_length;	/* This length is 2s complement! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	volatile short msg_length;	/* This length is "normal". */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) struct lance_tx_head {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	unsigned short base;		/* Low word of base addr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 	volatile unsigned char	flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	unsigned char base_hi;	/* High word of base addr (unused) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	short length;		/* Length is 2s complement! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	volatile short misc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) /* The LANCE initialization block, described in databook. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) struct lance_init_block {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 	unsigned short	mode;		/* Pre-set mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	unsigned char	hwaddr[6];	/* Physical ethernet address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	unsigned int    filter[2];	/* Multicast filter (unused). */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 	/* Receive and transmit ring base, along with length bits. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	unsigned short rdra;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	unsigned short rlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	unsigned short tdra;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	unsigned short tlen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	unsigned short pad[4]; /* is thie needed? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) /* The whole layout of the Lance shared memory */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) struct lance_memory {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	struct lance_init_block	init;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	struct lance_tx_head	tx_head[TX_RING_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	struct lance_rx_head	rx_head[RX_RING_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 	char   rx_data[RX_RING_SIZE][PKT_BUF_SZ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	char   tx_data[TX_RING_SIZE][PKT_BUF_SZ];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) /* The driver's private device structure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) struct lance_private {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	volatile unsigned short	*iobase;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 	struct lance_memory	*mem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)      	int new_rx, new_tx;	/* The next free ring entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	int old_tx, old_rx;     /* ring entry to be processed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) /* These two must be longs for set_bit() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	long	    tx_full;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 	long	    lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /* I/O register access macros */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) #define	MEM	lp->mem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) #define	DREG	lp->iobase[0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) #define	AREG	lp->iobase[1]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) #define	REGA(a)	(*( AREG = (a), &DREG ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) /* Definitions for the Lance */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) /* tx_head flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) #define TMD1_ENP		0x01	/* end of packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) #define TMD1_STP		0x02	/* start of packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) #define TMD1_DEF		0x04	/* deferred */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) #define TMD1_ONE		0x08	/* one retry needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) #define TMD1_MORE		0x10	/* more than one retry needed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) #define TMD1_ERR		0x40	/* error summary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) #define TMD1_OWN 		0x80	/* ownership (set: chip owns) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) #define TMD1_OWN_CHIP	TMD1_OWN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) #define TMD1_OWN_HOST	0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) /* tx_head misc field */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) #define TMD3_TDR		0x03FF	/* Time Domain Reflectometry counter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) #define TMD3_RTRY		0x0400	/* failed after 16 retries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) #define TMD3_LCAR		0x0800	/* carrier lost */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) #define TMD3_LCOL		0x1000	/* late collision */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) #define TMD3_UFLO		0x4000	/* underflow (late memory) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) #define TMD3_BUFF		0x8000	/* buffering error (no ENP) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) /* rx_head flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) #define RMD1_ENP		0x01	/* end of packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) #define RMD1_STP		0x02	/* start of packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) #define RMD1_BUFF		0x04	/* buffer error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) #define RMD1_CRC		0x08	/* CRC error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) #define RMD1_OFLO		0x10	/* overflow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) #define RMD1_FRAM		0x20	/* framing error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) #define RMD1_ERR		0x40	/* error summary */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) #define RMD1_OWN 		0x80	/* ownership (set: ship owns) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) #define RMD1_OWN_CHIP	RMD1_OWN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) #define RMD1_OWN_HOST	0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) /* register names */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) #define CSR0	0		/* mode/status */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) #define CSR1	1		/* init block addr (low) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) #define CSR2	2		/* init block addr (high) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) #define CSR3	3		/* misc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) #define CSR8	8	  	/* address filter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) #define CSR15	15		/* promiscuous mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) /* CSR0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) /* (R=readable, W=writeable, S=set on write, C=clear on write) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) #define CSR0_INIT	0x0001		/* initialize (RS) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) #define CSR0_STRT	0x0002		/* start (RS) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) #define CSR0_STOP	0x0004		/* stop (RS) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) #define CSR0_TDMD	0x0008		/* transmit demand (RS) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) #define CSR0_TXON	0x0010		/* transmitter on (R) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) #define CSR0_RXON	0x0020		/* receiver on (R) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) #define CSR0_INEA	0x0040		/* interrupt enable (RW) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) #define CSR0_INTR	0x0080		/* interrupt active (R) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) #define CSR0_IDON	0x0100		/* initialization done (RC) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) #define CSR0_TINT	0x0200		/* transmitter interrupt (RC) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) #define CSR0_RINT	0x0400		/* receiver interrupt (RC) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) #define CSR0_MERR	0x0800		/* memory error (RC) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) #define CSR0_MISS	0x1000		/* missed frame (RC) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) #define CSR0_CERR	0x2000		/* carrier error (no heartbeat :-) (RC) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) #define CSR0_BABL	0x4000		/* babble: tx-ed too many bits (RC) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) #define CSR0_ERR	0x8000		/* error (RC) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) /* CSR3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) #define CSR3_BCON	0x0001		/* byte control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) #define CSR3_ACON	0x0002		/* ALE control */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) #define CSR3_BSWP	0x0004		/* byte swap (1=big endian) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) /***************************** Prototypes *****************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static int lance_probe( struct net_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) static int lance_open( struct net_device *dev );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) static void lance_init_ring( struct net_device *dev );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) static netdev_tx_t lance_start_xmit(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 				    struct net_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) static irqreturn_t lance_interrupt( int irq, void *dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) static int lance_rx( struct net_device *dev );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) static int lance_close( struct net_device *dev );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) static void set_multicast_list( struct net_device *dev );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) /************************* End of Prototypes **************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) struct net_device * __init sun3lance_probe(int unit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) 	struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) 	static int found;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) 	int err = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 	if (!MACH_IS_SUN3 && !MACH_IS_SUN3X)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 		return ERR_PTR(-ENODEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	/* check that this machine has an onboard lance */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 	switch(idprom->id_machtype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 	case SM_SUN3|SM_3_50:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	case SM_SUN3|SM_3_60:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	case SM_SUN3X|SM_3_80:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 		/* these machines have lance */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 		return ERR_PTR(-ENODEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) 	if (found)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 		return ERR_PTR(-ENODEV);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 	dev = alloc_etherdev(sizeof(struct lance_private));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) 	if (!dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 		return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 	if (unit >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 		sprintf(dev->name, "eth%d", unit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 		netdev_boot_setup_check(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 	if (!lance_probe(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 	err = register_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 		goto out1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	found = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	return dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) out1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) #ifdef CONFIG_SUN3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	iounmap((void __iomem *)dev->base_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	free_netdev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	return ERR_PTR(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) static const struct net_device_ops lance_netdev_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 	.ndo_open		= lance_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	.ndo_stop		= lance_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 	.ndo_start_xmit		= lance_start_xmit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	.ndo_set_rx_mode	= set_multicast_list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 	.ndo_set_mac_address	= NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 	.ndo_validate_addr	= eth_validate_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) static int __init lance_probe( struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 	unsigned long ioaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	struct lance_private	*lp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	int 			i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) 	static int 		did_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 	volatile unsigned short *ioaddr_probe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) 	unsigned short tmp1, tmp2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) #ifdef CONFIG_SUN3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) 	ioaddr = (unsigned long)ioremap(LANCE_OBIO, PAGE_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 	if (!ioaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	ioaddr = SUN3X_LANCE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) 	/* test to see if there's really a lance here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) 	/* (CSRO_INIT shouldn't be readable) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) 	ioaddr_probe = (volatile unsigned short *)ioaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) 	tmp1 = ioaddr_probe[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) 	tmp2 = ioaddr_probe[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) 	ioaddr_probe[1] = CSR0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) 	ioaddr_probe[0] = CSR0_INIT | CSR0_STOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) 	if(ioaddr_probe[0] != CSR0_STOP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) 		ioaddr_probe[0] = tmp1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) 		ioaddr_probe[1] = tmp2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) #ifdef CONFIG_SUN3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) 		iounmap((void __iomem *)ioaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) 	lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) 	/* XXX - leak? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) 	MEM = dvma_malloc_align(sizeof(struct lance_memory), 0x10000);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) 	if (MEM == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) #ifdef CONFIG_SUN3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) 		iounmap((void __iomem *)ioaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) 		printk(KERN_WARNING "SUN3 Lance couldn't allocate DVMA memory\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 	lp->iobase = (volatile unsigned short *)ioaddr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) 	dev->base_addr = (unsigned long)ioaddr; /* informational only */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 	REGA(CSR0) = CSR0_STOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) 	if (request_irq(LANCE_IRQ, lance_interrupt, 0, "SUN3 Lance", dev) < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) #ifdef CONFIG_SUN3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) 		iounmap((void __iomem *)ioaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) 		dvma_free((void *)MEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) 		printk(KERN_WARNING "SUN3 Lance unable to allocate IRQ\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) 	dev->irq = (unsigned short)LANCE_IRQ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) 	printk("%s: SUN3 Lance at io %#lx, mem %#lx, irq %d, hwaddr ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) 		   dev->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) 		   (unsigned long)ioaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) 		   (unsigned long)MEM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) 		   dev->irq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) 	/* copy in the ethernet address from the prom */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) 	for(i = 0; i < 6 ; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) 	     dev->dev_addr[i] = idprom->id_ethaddr[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) 	/* tell the card it's ether address, bytes swapped */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) 	MEM->init.hwaddr[0] = dev->dev_addr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 	MEM->init.hwaddr[1] = dev->dev_addr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) 	MEM->init.hwaddr[2] = dev->dev_addr[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) 	MEM->init.hwaddr[3] = dev->dev_addr[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) 	MEM->init.hwaddr[4] = dev->dev_addr[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) 	MEM->init.hwaddr[5] = dev->dev_addr[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) 	printk("%pM\n", dev->dev_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) 	MEM->init.mode = 0x0000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) 	MEM->init.filter[0] = 0x00000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) 	MEM->init.filter[1] = 0x00000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) 	MEM->init.rdra = dvma_vtob(MEM->rx_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 	MEM->init.rlen    = (RX_LOG_RING_SIZE << 13) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) 		(dvma_vtob(MEM->rx_head) >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) 	MEM->init.tdra = dvma_vtob(MEM->tx_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) 	MEM->init.tlen    = (TX_LOG_RING_SIZE << 13) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) 		(dvma_vtob(MEM->tx_head) >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) 	DPRINTK(2, ("initaddr: %08lx rx_ring: %08lx tx_ring: %08lx\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) 	       dvma_vtob(&(MEM->init)), dvma_vtob(MEM->rx_head),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) 	       (dvma_vtob(MEM->tx_head))));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) 	if (did_version++ == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) 		printk( version );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) 	dev->netdev_ops = &lance_netdev_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) //	KLUDGE -- REMOVE ME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) 	set_bit(__LINK_STATE_PRESENT, &dev->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) static int lance_open( struct net_device *dev )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) 	struct lance_private *lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) 	DPRINTK( 2, ( "%s: lance_open()\n", dev->name ));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) 	REGA(CSR0) = CSR0_STOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) 	lance_init_ring(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) 	/* From now on, AREG is kept to point to CSR0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) 	REGA(CSR0) = CSR0_INIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) 	i = 1000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) 	while (--i > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) 		if (DREG & CSR0_IDON)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) 	if (i <= 0 || (DREG & CSR0_ERR)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) 		DPRINTK( 2, ( "lance_open(): opening %s failed, i=%d, csr0=%04x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) 					  dev->name, i, DREG ));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) 		DREG = CSR0_STOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) 		return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) 	DREG = CSR0_IDON | CSR0_STRT | CSR0_INEA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) 	netif_start_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) 	DPRINTK( 2, ( "%s: LANCE is open, csr0 %04x\n", dev->name, DREG ));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) /* Initialize the LANCE Rx and Tx rings. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) static void lance_init_ring( struct net_device *dev )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) 	struct lance_private *lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) 	lp->lock = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 	lp->tx_full = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) 	lp->new_rx = lp->new_tx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) 	lp->old_rx = lp->old_tx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) 	for( i = 0; i < TX_RING_SIZE; i++ ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) 		MEM->tx_head[i].base = dvma_vtob(MEM->tx_data[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) 		MEM->tx_head[i].flag = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)  		MEM->tx_head[i].base_hi =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) 			(dvma_vtob(MEM->tx_data[i])) >>16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) 		MEM->tx_head[i].length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) 		MEM->tx_head[i].misc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) 	for( i = 0; i < RX_RING_SIZE; i++ ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) 		MEM->rx_head[i].base = dvma_vtob(MEM->rx_data[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) 		MEM->rx_head[i].flag = RMD1_OWN_CHIP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) 		MEM->rx_head[i].base_hi =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) 			(dvma_vtob(MEM->rx_data[i])) >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 		MEM->rx_head[i].buf_length = -PKT_BUF_SZ | 0xf000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) 		MEM->rx_head[i].msg_length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) 	/* tell the card it's ether address, bytes swapped */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) 	MEM->init.hwaddr[0] = dev->dev_addr[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) 	MEM->init.hwaddr[1] = dev->dev_addr[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) 	MEM->init.hwaddr[2] = dev->dev_addr[3];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) 	MEM->init.hwaddr[3] = dev->dev_addr[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) 	MEM->init.hwaddr[4] = dev->dev_addr[5];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) 	MEM->init.hwaddr[5] = dev->dev_addr[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) 	MEM->init.mode = 0x0000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) 	MEM->init.filter[0] = 0x00000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) 	MEM->init.filter[1] = 0x00000000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) 	MEM->init.rdra = dvma_vtob(MEM->rx_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) 	MEM->init.rlen    = (RX_LOG_RING_SIZE << 13) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) 		(dvma_vtob(MEM->rx_head) >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) 	MEM->init.tdra = dvma_vtob(MEM->tx_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) 	MEM->init.tlen    = (TX_LOG_RING_SIZE << 13) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) 		(dvma_vtob(MEM->tx_head) >> 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) 	/* tell the lance the address of its init block */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) 	REGA(CSR1) = dvma_vtob(&(MEM->init));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) 	REGA(CSR2) = dvma_vtob(&(MEM->init)) >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) #ifdef CONFIG_SUN3X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) 	REGA(CSR3) = CSR3_BSWP | CSR3_ACON | CSR3_BCON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) 	REGA(CSR3) = CSR3_BSWP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) static netdev_tx_t
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) lance_start_xmit(struct sk_buff *skb, struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) 	struct lance_private *lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) 	int entry, len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) 	struct lance_tx_head *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) 	DPRINTK( 1, ( "%s: transmit start.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) 		      dev->name));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) 	/* Transmitter timeout, serious problems. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) 	if (netif_queue_stopped(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) 		int tickssofar = jiffies - dev_trans_start(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) 		if (tickssofar < HZ/5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) 			return NETDEV_TX_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) 		DPRINTK( 1, ( "%s: transmit timed out, status %04x, resetting.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) 					  dev->name, DREG ));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) 		DREG = CSR0_STOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) 		 * Always set BSWP after a STOP as STOP puts it back into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) 		 * little endian mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) 		REGA(CSR3) = CSR3_BSWP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) 		dev->stats.tx_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) 		if(lance_debug >= 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) 			int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) 			printk("Ring data: old_tx %d new_tx %d%s new_rx %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) 			       lp->old_tx, lp->new_tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) 			       lp->tx_full ? " (full)" : "",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) 			       lp->new_rx );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) 			for( i = 0 ; i < RX_RING_SIZE; i++ )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) 				printk( "rx #%d: base=%04x blen=%04x mlen=%04x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) 					i, MEM->rx_head[i].base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) 					-MEM->rx_head[i].buf_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) 					MEM->rx_head[i].msg_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) 			for( i = 0 ; i < TX_RING_SIZE; i++ )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) 				printk("tx #%d: base=%04x len=%04x misc=%04x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) 				       i, MEM->tx_head[i].base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) 				       -MEM->tx_head[i].length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) 				       MEM->tx_head[i].misc );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) 		lance_init_ring(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) 		REGA( CSR0 ) = CSR0_INEA | CSR0_INIT | CSR0_STRT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) 		netif_start_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) 		return NETDEV_TX_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) 	/* Block a timer-based transmit from overlapping.  This could better be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) 	   done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) 	/* Block a timer-based transmit from overlapping with us by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) 	   stopping the queue for a bit... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) 	netif_stop_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) 	if (test_and_set_bit( 0, (void*)&lp->lock ) != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) 		printk( "%s: tx queue lock!.\n", dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) 		/* don't clear dev->tbusy flag. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) 		return NETDEV_TX_BUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) 	AREG = CSR0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584)   	DPRINTK( 2, ( "%s: lance_start_xmit() called, csr0 %4.4x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)   				  dev->name, DREG ));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) #ifdef CONFIG_SUN3X
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) 	/* this weirdness doesn't appear on sun3... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) 	if(!(DREG & CSR0_INIT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) 		DPRINTK( 1, ("INIT not set, reinitializing...\n"));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) 		REGA( CSR0 ) = CSR0_STOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) 		lance_init_ring(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) 		REGA( CSR0 ) = CSR0_INIT | CSR0_STRT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) 	/* Fill in a Tx ring entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) 	if (lance_debug >= 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) 		printk( "%s: TX pkt %d type 0x%04x"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) 			" from %s to %s"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) 			" data at 0x%08x len %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) 			dev->name, lp->new_tx, ((u_short *)skb->data)[6],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 			DEV_ADDR(&skb->data[6]), DEV_ADDR(skb->data),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) 			(int)skb->data, (int)skb->len );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) 	/* We're not prepared for the int until the last flags are set/reset.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) 	 * And the int may happen already after setting the OWN_CHIP... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) 	local_irq_save(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) 	/* Mask to ring buffer boundary. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) 	entry = lp->new_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) 	head  = &(MEM->tx_head[entry]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) 	/* Caution: the write order is important here, set the "ownership" bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) 	 * last.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) 	/* the sun3's lance needs it's buffer padded to the minimum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) 	   size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) 	len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) //	head->length = -len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) 	head->length = (-len) | 0xf000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) 	head->misc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) 	skb_copy_from_linear_data(skb, PKTBUF_ADDR(head), skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) 	if (len != skb->len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) 		memset(PKTBUF_ADDR(head) + skb->len, 0, len-skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) 	head->flag = TMD1_OWN_CHIP | TMD1_ENP | TMD1_STP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) 	lp->new_tx = (lp->new_tx + 1) & TX_RING_MOD_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) 	dev->stats.tx_bytes += skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) 	/* Trigger an immediate send poll. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) 	REGA(CSR0) = CSR0_INEA | CSR0_TDMD | CSR0_STRT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) 	AREG = CSR0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)   	DPRINTK( 2, ( "%s: lance_start_xmit() exiting, csr0 %4.4x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)   				  dev->name, DREG ));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) 	dev_kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) 	lp->lock = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) 	if ((MEM->tx_head[(entry+1) & TX_RING_MOD_MASK].flag & TMD1_OWN) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) 	    TMD1_OWN_HOST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) 		netif_start_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) 	local_irq_restore(flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) 	return NETDEV_TX_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) /* The LANCE interrupt handler. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) static irqreturn_t lance_interrupt( int irq, void *dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) 	struct net_device *dev = dev_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) 	struct lance_private *lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) 	int csr0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)  still_more:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) 	flush_cache_all();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) 	AREG = CSR0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) 	csr0 = DREG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) 	/* ack interrupts */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) 	DREG = csr0 & (CSR0_TINT | CSR0_RINT | CSR0_IDON);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) 	/* clear errors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) 	if(csr0 & CSR0_ERR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) 		DREG = CSR0_BABL | CSR0_MERR | CSR0_CERR | CSR0_MISS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) 	DPRINTK( 2, ( "%s: interrupt  csr0=%04x new csr=%04x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) 		      dev->name, csr0, DREG ));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) 	if (csr0 & CSR0_TINT) {			/* Tx-done interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) 		int old_tx = lp->old_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) //		if(lance_debug >= 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) //			int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) //			printk("%s: tx int\n", dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) //
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) //			for(i = 0; i < TX_RING_SIZE; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) //				printk("ring %d flag=%04x\n", i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) //				       MEM->tx_head[i].flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) //		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) 		while( old_tx != lp->new_tx) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) 			struct lance_tx_head *head = &(MEM->tx_head[old_tx]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) 			DPRINTK(3, ("on tx_ring %d\n", old_tx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) 			if (head->flag & TMD1_OWN_CHIP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) 				break; /* It still hasn't been Txed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) 			if (head->flag & TMD1_ERR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) 				int status = head->misc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) 				dev->stats.tx_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) 				if (status & TMD3_RTRY) dev->stats.tx_aborted_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) 				if (status & TMD3_LCAR) dev->stats.tx_carrier_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) 				if (status & TMD3_LCOL) dev->stats.tx_window_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) 				if (status & (TMD3_UFLO | TMD3_BUFF)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) 					dev->stats.tx_fifo_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) 					printk("%s: Tx FIFO error\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) 					       dev->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) 					REGA(CSR0) = CSR0_STOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) 					REGA(CSR3) = CSR3_BSWP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) 					lance_init_ring(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) 					REGA(CSR0) = CSR0_STRT | CSR0_INEA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) 					return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) 			} else if(head->flag & (TMD1_ENP | TMD1_STP)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) 				head->flag &= ~(TMD1_ENP | TMD1_STP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) 				if(head->flag & (TMD1_ONE | TMD1_MORE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) 					dev->stats.collisions++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) 				dev->stats.tx_packets++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) 				DPRINTK(3, ("cleared tx ring %d\n", old_tx));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) 			old_tx = (old_tx +1) & TX_RING_MOD_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) 		lp->old_tx = old_tx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) 	if (netif_queue_stopped(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) 		/* The ring is no longer full, clear tbusy. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) 		netif_start_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) 		netif_wake_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) 	if (csr0 & CSR0_RINT)			/* Rx interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) 		lance_rx( dev );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) 	/* Log misc errors. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) 	if (csr0 & CSR0_BABL) dev->stats.tx_errors++; /* Tx babble. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) 	if (csr0 & CSR0_MISS) dev->stats.rx_errors++; /* Missed a Rx frame. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) 	if (csr0 & CSR0_MERR) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) 		DPRINTK( 1, ( "%s: Bus master arbitration failure (?!?), "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) 			      "status %04x.\n", dev->name, csr0 ));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) 		/* Restart the chip. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) 		REGA(CSR0) = CSR0_STOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) 		REGA(CSR3) = CSR3_BSWP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) 		lance_init_ring(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) 		REGA(CSR0) = CSR0_STRT | CSR0_INEA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)     /* Clear any other interrupt, and set interrupt enable. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) //	DREG = CSR0_BABL | CSR0_CERR | CSR0_MISS | CSR0_MERR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) //		   CSR0_IDON | CSR0_INEA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) 	REGA(CSR0) = CSR0_INEA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) 	if(DREG & (CSR0_RINT | CSR0_TINT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) 	     DPRINTK(2, ("restarting interrupt, csr0=%#04x\n", DREG));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) 	     goto still_more;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) 	DPRINTK( 2, ( "%s: exiting interrupt, csr0=%#04x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) 				  dev->name, DREG ));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) 	return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) /* get packet, toss into skbuff */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) static int lance_rx( struct net_device *dev )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) 	struct lance_private *lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) 	int entry = lp->new_rx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) 	/* If we own the next entry, it's a new packet. Send it up. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) 	while( (MEM->rx_head[entry].flag & RMD1_OWN) == RMD1_OWN_HOST ) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) 		struct lance_rx_head *head = &(MEM->rx_head[entry]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) 		int status = head->flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) 		if (status != (RMD1_ENP|RMD1_STP)) {  /* There was an error. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) 			/* There is a tricky error noted by John Murphy,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) 			   <murf@perftech.com> to Russ Nelson: Even with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) 			   full-sized buffers it's possible for a jabber packet to use two
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) 			   buffers, with only the last correctly noting the error. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) 			if (status & RMD1_ENP)	/* Only count a general error at the */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) 				dev->stats.rx_errors++; /* end of a packet.*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) 			if (status & RMD1_FRAM) dev->stats.rx_frame_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) 			if (status & RMD1_OFLO) dev->stats.rx_over_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) 			if (status & RMD1_CRC) dev->stats.rx_crc_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) 			if (status & RMD1_BUFF) dev->stats.rx_fifo_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) 			head->flag &= (RMD1_ENP|RMD1_STP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) 			/* Malloc up new buffer, compatible with net-3. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) //			short pkt_len = head->msg_length;// & 0xfff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) 			short pkt_len = (head->msg_length & 0xfff) - 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) 			struct sk_buff *skb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) 			if (pkt_len < 60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) 				printk( "%s: Runt packet!\n", dev->name );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) 				dev->stats.rx_errors++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) 			else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) 				skb = netdev_alloc_skb(dev, pkt_len + 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) 				if (skb == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) 					dev->stats.rx_dropped++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) 					head->msg_length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) 					head->flag |= RMD1_OWN_CHIP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) 					lp->new_rx = (lp->new_rx+1) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) 					     RX_RING_MOD_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) #if 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) 				if (lance_debug >= 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) 					u_char *data = PKTBUF_ADDR(head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) 					printk("%s: RX pkt %d type 0x%04x"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) 					       " from %pM to %pM",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) 					       dev->name, lp->new_tx, ((u_short *)data)[6],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) 					       &data[6], data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) 					printk(" data %02x %02x %02x %02x %02x %02x %02x %02x "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) 					       "len %d at %08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) 					       data[15], data[16], data[17], data[18],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) 					       data[19], data[20], data[21], data[22],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) 					       pkt_len, data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) 				if (lance_debug >= 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) 					u_char *data = PKTBUF_ADDR(head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) 					printk( "%s: RX pkt %d type 0x%04x len %d\n ", dev->name, entry, ((u_short *)data)[6], pkt_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) 				skb_reserve( skb, 2 );	/* 16 byte align */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) 				skb_put( skb, pkt_len );	/* Make room */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) 				skb_copy_to_linear_data(skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) 						 PKTBUF_ADDR(head),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) 						 pkt_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) 				skb->protocol = eth_type_trans( skb, dev );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) 				netif_rx( skb );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) 				dev->stats.rx_packets++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) 				dev->stats.rx_bytes += pkt_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) //		head->buf_length = -PKT_BUF_SZ | 0xf000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) 		head->msg_length = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) 		head->flag = RMD1_OWN_CHIP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) 		entry = lp->new_rx = (lp->new_rx +1) & RX_RING_MOD_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) 	/* From lance.c (Donald Becker): */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) 	/* We should check that at least two ring entries are free.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) 	   If not, we should free one and mark stats->rx_dropped++. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) static int lance_close( struct net_device *dev )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) 	struct lance_private *lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) 	netif_stop_queue(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) 	AREG = CSR0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) 	DPRINTK( 2, ( "%s: Shutting down ethercard, status was %2.2x.\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) 				  dev->name, DREG ));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) 	/* We stop the LANCE here -- it occasionally polls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) 	   memory if we don't. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) 	DREG = CSR0_STOP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) /* Set or clear the multicast filter for this adaptor.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881)    num_addrs == -1		Promiscuous mode, receive all packets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882)    num_addrs == 0		Normal mode, clear multicast list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883)    num_addrs > 0		Multicast mode, receive normal and MC packets, and do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) 						best-effort filtering.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) /* completely untested on a sun3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) static void set_multicast_list( struct net_device *dev )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) 	struct lance_private *lp = netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) 	if(netif_queue_stopped(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) 		/* Only possible if board is already started */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) 	/* We take the simple way out and always enable promiscuous mode. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) 	DREG = CSR0_STOP; /* Temporarily stop the lance. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) 	if (dev->flags & IFF_PROMISC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) 		/* Log any net taps. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) 		DPRINTK( 3, ( "%s: Promiscuous mode enabled.\n", dev->name ));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) 		REGA( CSR15 ) = 0x8000; /* Set promiscuous mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) 		short multicast_table[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) 		int num_addrs = netdev_mc_count(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) 		int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) 		/* We don't use the multicast table, but rely on upper-layer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) 		 * filtering. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) 		memset( multicast_table, (num_addrs == 0) ? 0 : -1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) 				sizeof(multicast_table) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) 		for( i = 0; i < 4; i++ )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) 			REGA( CSR8+i ) = multicast_table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) 		REGA( CSR15 ) = 0; /* Unset promiscuous mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) 	 * Always set BSWP after a STOP as STOP puts it back into
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) 	 * little endian mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) 	REGA( CSR3 ) = CSR3_BSWP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) 	/* Resume normal operation and reset AREG to CSR0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) 	REGA( CSR0 ) = CSR0_IDON | CSR0_INEA | CSR0_STRT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) #ifdef MODULE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) static struct net_device *sun3lance_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) int __init init_module(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) 	sun3lance_dev = sun3lance_probe(-1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) 	return PTR_ERR_OR_ZERO(sun3lance_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) void __exit cleanup_module(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) 	unregister_netdev(sun3lance_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) #ifdef CONFIG_SUN3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) 	iounmap((void __iomem *)sun3lance_dev->base_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) 	free_netdev(sun3lance_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) #endif /* MODULE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947)