1b955f6caSJeff Kirsher /* atarilance.c: Ethernet driver for VME Lance cards on the Atari */ 2b955f6caSJeff Kirsher /* 3b955f6caSJeff Kirsher Written 1995/96 by Roman Hodek (Roman.Hodek@informatik.uni-erlangen.de) 4b955f6caSJeff Kirsher 5b955f6caSJeff Kirsher This software may be used and distributed according to the terms 6b955f6caSJeff Kirsher of the GNU General Public License, incorporated herein by reference. 7b955f6caSJeff Kirsher 8b955f6caSJeff Kirsher This drivers was written with the following sources of reference: 9b955f6caSJeff Kirsher - The driver for the Riebl Lance card by the TU Vienna. 10b955f6caSJeff Kirsher - The modified TUW driver for PAM's VME cards 11b955f6caSJeff Kirsher - The PC-Linux driver for Lance cards (but this is for bus master 12b955f6caSJeff Kirsher cards, not the shared memory ones) 13b955f6caSJeff Kirsher - The Amiga Ariadne driver 14b955f6caSJeff Kirsher 15b955f6caSJeff Kirsher v1.0: (in 1.2.13pl4/0.9.13) 16b955f6caSJeff Kirsher Initial version 17b955f6caSJeff Kirsher v1.1: (in 1.2.13pl5) 18b955f6caSJeff Kirsher more comments 19b955f6caSJeff Kirsher deleted some debugging stuff 20b955f6caSJeff Kirsher optimized register access (keep AREG pointing to CSR0) 21b955f6caSJeff Kirsher following AMD, CSR0_STRT should be set only after IDON is detected 22b955f6caSJeff Kirsher use memcpy() for data transfers, that also employs long word moves 23b955f6caSJeff Kirsher better probe procedure for 24-bit systems 24b955f6caSJeff Kirsher non-VME-RieblCards need extra delays in memcpy 25b955f6caSJeff Kirsher must also do write test, since 0xfxe00000 may hit ROM 26b955f6caSJeff Kirsher use 8/32 tx/rx buffers, which should give better NFS performance; 27b955f6caSJeff Kirsher this is made possible by shifting the last packet buffer after the 28b955f6caSJeff Kirsher RieblCard reserved area 29b955f6caSJeff Kirsher v1.2: (in 1.2.13pl8) 30b955f6caSJeff Kirsher again fixed probing for the Falcon; 0xfe01000 hits phys. 0x00010000 31b955f6caSJeff Kirsher and thus RAM, in case of no Lance found all memory contents have to 32b955f6caSJeff Kirsher be restored! 33b955f6caSJeff Kirsher Now possible to compile as module. 34b955f6caSJeff Kirsher v1.3: 03/30/96 Jes Sorensen, Roman (in 1.3) 35b955f6caSJeff Kirsher Several little 1.3 adaptions 36b955f6caSJeff Kirsher When the lance is stopped it jumps back into little-endian 37b955f6caSJeff Kirsher mode. It is therefore necessary to put it back where it 38b955f6caSJeff Kirsher belongs, in big endian mode, in order to make things work. 39b955f6caSJeff Kirsher This might be the reason why multicast-mode didn't work 40b955f6caSJeff Kirsher before, but I'm not able to test it as I only got an Amiga 41b955f6caSJeff Kirsher (we had similar problems with the A2065 driver). 42b955f6caSJeff Kirsher 43b955f6caSJeff Kirsher */ 44b955f6caSJeff Kirsher 4506324664SKees Cook static const char version[] = "atarilance.c: v1.3 04/04/96 " 46b955f6caSJeff Kirsher "Roman.Hodek@informatik.uni-erlangen.de\n"; 47b955f6caSJeff Kirsher 48b955f6caSJeff Kirsher #include <linux/netdevice.h> 49b955f6caSJeff Kirsher #include <linux/etherdevice.h> 50b955f6caSJeff Kirsher #include <linux/module.h> 51b955f6caSJeff Kirsher #include <linux/stddef.h> 52b955f6caSJeff Kirsher #include <linux/kernel.h> 53b955f6caSJeff Kirsher #include <linux/string.h> 54b955f6caSJeff Kirsher #include <linux/errno.h> 55b955f6caSJeff Kirsher #include <linux/skbuff.h> 56b955f6caSJeff Kirsher #include <linux/interrupt.h> 57b955f6caSJeff Kirsher #include <linux/init.h> 58b955f6caSJeff Kirsher #include <linux/bitops.h> 59b955f6caSJeff Kirsher 60b955f6caSJeff Kirsher #include <asm/setup.h> 61b955f6caSJeff Kirsher #include <asm/irq.h> 62b955f6caSJeff Kirsher #include <asm/atarihw.h> 63b955f6caSJeff Kirsher #include <asm/atariints.h> 64b955f6caSJeff Kirsher #include <asm/io.h> 65b955f6caSJeff Kirsher 66b955f6caSJeff Kirsher /* Debug level: 67b955f6caSJeff Kirsher * 0 = silent, print only serious errors 68b955f6caSJeff Kirsher * 1 = normal, print error messages 69b955f6caSJeff Kirsher * 2 = debug, print debug infos 70b955f6caSJeff Kirsher * 3 = debug, print even more debug infos (packet data) 71b955f6caSJeff Kirsher */ 72b955f6caSJeff Kirsher 73b955f6caSJeff Kirsher #define LANCE_DEBUG 1 74b955f6caSJeff Kirsher 75b955f6caSJeff Kirsher #ifdef LANCE_DEBUG 76b955f6caSJeff Kirsher static int lance_debug = LANCE_DEBUG; 77b955f6caSJeff Kirsher #else 78b955f6caSJeff Kirsher static int lance_debug = 1; 79b955f6caSJeff Kirsher #endif 80b955f6caSJeff Kirsher module_param(lance_debug, int, 0); 81b955f6caSJeff Kirsher MODULE_PARM_DESC(lance_debug, "atarilance debug level (0-3)"); 82b955f6caSJeff Kirsher MODULE_LICENSE("GPL"); 83b955f6caSJeff Kirsher 84b955f6caSJeff Kirsher /* Print debug messages on probing? */ 85b955f6caSJeff Kirsher #undef LANCE_DEBUG_PROBE 86b955f6caSJeff Kirsher 87b955f6caSJeff Kirsher #define DPRINTK(n,a) \ 88b955f6caSJeff Kirsher do { \ 89b955f6caSJeff Kirsher if (lance_debug >= n) \ 90b955f6caSJeff Kirsher printk a; \ 91b955f6caSJeff Kirsher } while( 0 ) 92b955f6caSJeff Kirsher 93b955f6caSJeff Kirsher #ifdef LANCE_DEBUG_PROBE 94b955f6caSJeff Kirsher # define PROBE_PRINT(a) printk a 95b955f6caSJeff Kirsher #else 96b955f6caSJeff Kirsher # define PROBE_PRINT(a) 97b955f6caSJeff Kirsher #endif 98b955f6caSJeff Kirsher 99b955f6caSJeff Kirsher /* These define the number of Rx and Tx buffers as log2. (Only powers 100b955f6caSJeff Kirsher * of two are valid) 101b955f6caSJeff Kirsher * Much more rx buffers (32) are reserved than tx buffers (8), since receiving 102b955f6caSJeff Kirsher * is more time critical then sending and packets may have to remain in the 103b955f6caSJeff Kirsher * board's memory when main memory is low. 104b955f6caSJeff Kirsher */ 105b955f6caSJeff Kirsher 106b955f6caSJeff Kirsher #define TX_LOG_RING_SIZE 3 107b955f6caSJeff Kirsher #define RX_LOG_RING_SIZE 5 108b955f6caSJeff Kirsher 109b955f6caSJeff Kirsher /* These are the derived values */ 110b955f6caSJeff Kirsher 111b955f6caSJeff Kirsher #define TX_RING_SIZE (1 << TX_LOG_RING_SIZE) 112b955f6caSJeff Kirsher #define TX_RING_LEN_BITS (TX_LOG_RING_SIZE << 5) 113b955f6caSJeff Kirsher #define TX_RING_MOD_MASK (TX_RING_SIZE - 1) 114b955f6caSJeff Kirsher 115b955f6caSJeff Kirsher #define RX_RING_SIZE (1 << RX_LOG_RING_SIZE) 116b955f6caSJeff Kirsher #define RX_RING_LEN_BITS (RX_LOG_RING_SIZE << 5) 117b955f6caSJeff Kirsher #define RX_RING_MOD_MASK (RX_RING_SIZE - 1) 118b955f6caSJeff Kirsher 119b955f6caSJeff Kirsher #define TX_TIMEOUT (HZ/5) 120b955f6caSJeff Kirsher 121b955f6caSJeff Kirsher /* The LANCE Rx and Tx ring descriptors. */ 122b955f6caSJeff Kirsher struct lance_rx_head { 123b955f6caSJeff Kirsher unsigned short base; /* Low word of base addr */ 124b955f6caSJeff Kirsher volatile unsigned char flag; 125b955f6caSJeff Kirsher unsigned char base_hi; /* High word of base addr (unused) */ 126b955f6caSJeff Kirsher short buf_length; /* This length is 2s complement! */ 127b955f6caSJeff Kirsher volatile short msg_length; /* This length is "normal". */ 128b955f6caSJeff Kirsher }; 129b955f6caSJeff Kirsher 130b955f6caSJeff Kirsher struct lance_tx_head { 131b955f6caSJeff Kirsher unsigned short base; /* Low word of base addr */ 132b955f6caSJeff Kirsher volatile unsigned char flag; 133b955f6caSJeff Kirsher unsigned char base_hi; /* High word of base addr (unused) */ 134b955f6caSJeff Kirsher short length; /* Length is 2s complement! */ 135b955f6caSJeff Kirsher volatile short misc; 136b955f6caSJeff Kirsher }; 137b955f6caSJeff Kirsher 138b955f6caSJeff Kirsher struct ringdesc { 139b955f6caSJeff Kirsher unsigned short adr_lo; /* Low 16 bits of address */ 140b955f6caSJeff Kirsher unsigned char len; /* Length bits */ 141b955f6caSJeff Kirsher unsigned char adr_hi; /* High 8 bits of address (unused) */ 142b955f6caSJeff Kirsher }; 143b955f6caSJeff Kirsher 144b955f6caSJeff Kirsher /* The LANCE initialization block, described in databook. */ 145b955f6caSJeff Kirsher struct lance_init_block { 146b955f6caSJeff Kirsher unsigned short mode; /* Pre-set mode */ 147b955f6caSJeff Kirsher unsigned char hwaddr[6]; /* Physical ethernet address */ 148b955f6caSJeff Kirsher unsigned filter[2]; /* Multicast filter (unused). */ 149b955f6caSJeff Kirsher /* Receive and transmit ring base, along with length bits. */ 150b955f6caSJeff Kirsher struct ringdesc rx_ring; 151b955f6caSJeff Kirsher struct ringdesc tx_ring; 152b955f6caSJeff Kirsher }; 153b955f6caSJeff Kirsher 154b955f6caSJeff Kirsher /* The whole layout of the Lance shared memory */ 155b955f6caSJeff Kirsher struct lance_memory { 156b955f6caSJeff Kirsher struct lance_init_block init; 157b955f6caSJeff Kirsher struct lance_tx_head tx_head[TX_RING_SIZE]; 158b955f6caSJeff Kirsher struct lance_rx_head rx_head[RX_RING_SIZE]; 159c2dfc7d2SGustavo A. R. Silva char packet_area[]; /* packet data follow after the 160b955f6caSJeff Kirsher * init block and the ring 161b955f6caSJeff Kirsher * descriptors and are located 162b955f6caSJeff Kirsher * at runtime */ 163b955f6caSJeff Kirsher }; 164b955f6caSJeff Kirsher 165b955f6caSJeff Kirsher /* RieblCard specifics: 166b955f6caSJeff Kirsher * The original TOS driver for these cards reserves the area from offset 167b955f6caSJeff Kirsher * 0xee70 to 0xeebb for storing configuration data. Of interest to us is the 168b955f6caSJeff Kirsher * Ethernet address there, and the magic for verifying the data's validity. 169b955f6caSJeff Kirsher * The reserved area isn't touch by packet buffers. Furthermore, offset 0xfffe 170b955f6caSJeff Kirsher * is reserved for the interrupt vector number. 171b955f6caSJeff Kirsher */ 172b955f6caSJeff Kirsher #define RIEBL_RSVD_START 0xee70 173b955f6caSJeff Kirsher #define RIEBL_RSVD_END 0xeec0 174b955f6caSJeff Kirsher #define RIEBL_MAGIC 0x09051990 175b955f6caSJeff Kirsher #define RIEBL_MAGIC_ADDR ((unsigned long *)(((char *)MEM) + 0xee8a)) 176b955f6caSJeff Kirsher #define RIEBL_HWADDR_ADDR ((unsigned char *)(((char *)MEM) + 0xee8e)) 177b955f6caSJeff Kirsher #define RIEBL_IVEC_ADDR ((unsigned short *)(((char *)MEM) + 0xfffe)) 178b955f6caSJeff Kirsher 179b955f6caSJeff Kirsher /* This is a default address for the old RieblCards without a battery 180b955f6caSJeff Kirsher * that have no ethernet address at boot time. 00:00:36:04 is the 181b955f6caSJeff Kirsher * prefix for Riebl cards, the 00:00 at the end is arbitrary. 182b955f6caSJeff Kirsher */ 183b955f6caSJeff Kirsher 184b955f6caSJeff Kirsher static unsigned char OldRieblDefHwaddr[6] = { 185b955f6caSJeff Kirsher 0x00, 0x00, 0x36, 0x04, 0x00, 0x00 186b955f6caSJeff Kirsher }; 187b955f6caSJeff Kirsher 188b955f6caSJeff Kirsher 189b955f6caSJeff Kirsher /* I/O registers of the Lance chip */ 190b955f6caSJeff Kirsher 191b955f6caSJeff Kirsher struct lance_ioreg { 192b955f6caSJeff Kirsher /* base+0x0 */ volatile unsigned short data; 193b955f6caSJeff Kirsher /* base+0x2 */ volatile unsigned short addr; 194b955f6caSJeff Kirsher unsigned char _dummy1[3]; 195b955f6caSJeff Kirsher /* base+0x7 */ volatile unsigned char ivec; 196b955f6caSJeff Kirsher unsigned char _dummy2[5]; 197b955f6caSJeff Kirsher /* base+0xd */ volatile unsigned char eeprom; 198b955f6caSJeff Kirsher unsigned char _dummy3; 199b955f6caSJeff Kirsher /* base+0xf */ volatile unsigned char mem; 200b955f6caSJeff Kirsher }; 201b955f6caSJeff Kirsher 202b955f6caSJeff Kirsher /* Types of boards this driver supports */ 203b955f6caSJeff Kirsher 204b955f6caSJeff Kirsher enum lance_type { 205b955f6caSJeff Kirsher OLD_RIEBL, /* old Riebl card without battery */ 206b955f6caSJeff Kirsher NEW_RIEBL, /* new Riebl card with battery */ 207b955f6caSJeff Kirsher PAM_CARD /* PAM card with EEPROM */ 208b955f6caSJeff Kirsher }; 209b955f6caSJeff Kirsher 210b955f6caSJeff Kirsher static char *lance_names[] = { 211b955f6caSJeff Kirsher "Riebl-Card (without battery)", 212b955f6caSJeff Kirsher "Riebl-Card (with battery)", 213b955f6caSJeff Kirsher "PAM intern card" 214b955f6caSJeff Kirsher }; 215b955f6caSJeff Kirsher 216b955f6caSJeff Kirsher /* The driver's private device structure */ 217b955f6caSJeff Kirsher 218b955f6caSJeff Kirsher struct lance_private { 219b955f6caSJeff Kirsher enum lance_type cardtype; 220b955f6caSJeff Kirsher struct lance_ioreg *iobase; 221b955f6caSJeff Kirsher struct lance_memory *mem; 222b955f6caSJeff Kirsher int cur_rx, cur_tx; /* The next free ring entry */ 223b955f6caSJeff Kirsher int dirty_tx; /* Ring entries to be freed. */ 224b955f6caSJeff Kirsher /* copy function */ 225b955f6caSJeff Kirsher void *(*memcpy_f)( void *, const void *, size_t ); 226b955f6caSJeff Kirsher /* This must be long for set_bit() */ 227b955f6caSJeff Kirsher long tx_full; 228b955f6caSJeff Kirsher spinlock_t devlock; 229b955f6caSJeff Kirsher }; 230b955f6caSJeff Kirsher 231b955f6caSJeff Kirsher /* I/O register access macros */ 232b955f6caSJeff Kirsher 233b955f6caSJeff Kirsher #define MEM lp->mem 234b955f6caSJeff Kirsher #define DREG IO->data 235b955f6caSJeff Kirsher #define AREG IO->addr 236b955f6caSJeff Kirsher #define REGA(a) (*( AREG = (a), &DREG )) 237b955f6caSJeff Kirsher 238b955f6caSJeff Kirsher /* Definitions for packet buffer access: */ 239b955f6caSJeff Kirsher #define PKT_BUF_SZ 1544 240b955f6caSJeff Kirsher /* Get the address of a packet buffer corresponding to a given buffer head */ 241b955f6caSJeff Kirsher #define PKTBUF_ADDR(head) (((unsigned char *)(MEM)) + (head)->base) 242b955f6caSJeff Kirsher 243b955f6caSJeff Kirsher /* Possible memory/IO addresses for probing */ 244b955f6caSJeff Kirsher 245b955f6caSJeff Kirsher static struct lance_addr { 246b955f6caSJeff Kirsher unsigned long memaddr; 247b955f6caSJeff Kirsher unsigned long ioaddr; 248b955f6caSJeff Kirsher int slow_flag; 249b955f6caSJeff Kirsher } lance_addr_list[] = { 250b955f6caSJeff Kirsher { 0xfe010000, 0xfe00fff0, 0 }, /* RieblCard VME in TT */ 251b955f6caSJeff Kirsher { 0xffc10000, 0xffc0fff0, 0 }, /* RieblCard VME in MegaSTE 252b955f6caSJeff Kirsher (highest byte stripped) */ 253b955f6caSJeff Kirsher { 0xffe00000, 0xffff7000, 1 }, /* RieblCard in ST 254b955f6caSJeff Kirsher (highest byte stripped) */ 255b955f6caSJeff Kirsher { 0xffd00000, 0xffff7000, 1 }, /* RieblCard in ST with hw modif. to 256b955f6caSJeff Kirsher avoid conflict with ROM 257b955f6caSJeff Kirsher (highest byte stripped) */ 258b955f6caSJeff Kirsher { 0xffcf0000, 0xffcffff0, 0 }, /* PAMCard VME in TT and MSTE 259b955f6caSJeff Kirsher (highest byte stripped) */ 260b955f6caSJeff Kirsher { 0xfecf0000, 0xfecffff0, 0 }, /* Rhotron's PAMCard VME in TT and MSTE 261b955f6caSJeff Kirsher (highest byte stripped) */ 262b955f6caSJeff Kirsher }; 263b955f6caSJeff Kirsher 264b955f6caSJeff Kirsher #define N_LANCE_ADDR ARRAY_SIZE(lance_addr_list) 265b955f6caSJeff Kirsher 266b955f6caSJeff Kirsher 267b955f6caSJeff Kirsher /* Definitions for the Lance */ 268b955f6caSJeff Kirsher 269b955f6caSJeff Kirsher /* tx_head flags */ 270b955f6caSJeff Kirsher #define TMD1_ENP 0x01 /* end of packet */ 271b955f6caSJeff Kirsher #define TMD1_STP 0x02 /* start of packet */ 272b955f6caSJeff Kirsher #define TMD1_DEF 0x04 /* deferred */ 273b955f6caSJeff Kirsher #define TMD1_ONE 0x08 /* one retry needed */ 274b955f6caSJeff Kirsher #define TMD1_MORE 0x10 /* more than one retry needed */ 275b955f6caSJeff Kirsher #define TMD1_ERR 0x40 /* error summary */ 276b955f6caSJeff Kirsher #define TMD1_OWN 0x80 /* ownership (set: chip owns) */ 277b955f6caSJeff Kirsher 278b955f6caSJeff Kirsher #define TMD1_OWN_CHIP TMD1_OWN 279b955f6caSJeff Kirsher #define TMD1_OWN_HOST 0 280b955f6caSJeff Kirsher 281b955f6caSJeff Kirsher /* tx_head misc field */ 282b955f6caSJeff Kirsher #define TMD3_TDR 0x03FF /* Time Domain Reflectometry counter */ 283b955f6caSJeff Kirsher #define TMD3_RTRY 0x0400 /* failed after 16 retries */ 284b955f6caSJeff Kirsher #define TMD3_LCAR 0x0800 /* carrier lost */ 285b955f6caSJeff Kirsher #define TMD3_LCOL 0x1000 /* late collision */ 286b955f6caSJeff Kirsher #define TMD3_UFLO 0x4000 /* underflow (late memory) */ 287b955f6caSJeff Kirsher #define TMD3_BUFF 0x8000 /* buffering error (no ENP) */ 288b955f6caSJeff Kirsher 289b955f6caSJeff Kirsher /* rx_head flags */ 290b955f6caSJeff Kirsher #define RMD1_ENP 0x01 /* end of packet */ 291b955f6caSJeff Kirsher #define RMD1_STP 0x02 /* start of packet */ 292b955f6caSJeff Kirsher #define RMD1_BUFF 0x04 /* buffer error */ 293b955f6caSJeff Kirsher #define RMD1_CRC 0x08 /* CRC error */ 294b955f6caSJeff Kirsher #define RMD1_OFLO 0x10 /* overflow */ 295b955f6caSJeff Kirsher #define RMD1_FRAM 0x20 /* framing error */ 296b955f6caSJeff Kirsher #define RMD1_ERR 0x40 /* error summary */ 297b955f6caSJeff Kirsher #define RMD1_OWN 0x80 /* ownership (set: ship owns) */ 298b955f6caSJeff Kirsher 299b955f6caSJeff Kirsher #define RMD1_OWN_CHIP RMD1_OWN 300b955f6caSJeff Kirsher #define RMD1_OWN_HOST 0 301b955f6caSJeff Kirsher 302b955f6caSJeff Kirsher /* register names */ 303b955f6caSJeff Kirsher #define CSR0 0 /* mode/status */ 304b955f6caSJeff Kirsher #define CSR1 1 /* init block addr (low) */ 305b955f6caSJeff Kirsher #define CSR2 2 /* init block addr (high) */ 306b955f6caSJeff Kirsher #define CSR3 3 /* misc */ 307b955f6caSJeff Kirsher #define CSR8 8 /* address filter */ 308b955f6caSJeff Kirsher #define CSR15 15 /* promiscuous mode */ 309b955f6caSJeff Kirsher 310b955f6caSJeff Kirsher /* CSR0 */ 311b955f6caSJeff Kirsher /* (R=readable, W=writeable, S=set on write, C=clear on write) */ 312b955f6caSJeff Kirsher #define CSR0_INIT 0x0001 /* initialize (RS) */ 313b955f6caSJeff Kirsher #define CSR0_STRT 0x0002 /* start (RS) */ 314b955f6caSJeff Kirsher #define CSR0_STOP 0x0004 /* stop (RS) */ 315b955f6caSJeff Kirsher #define CSR0_TDMD 0x0008 /* transmit demand (RS) */ 316b955f6caSJeff Kirsher #define CSR0_TXON 0x0010 /* transmitter on (R) */ 317b955f6caSJeff Kirsher #define CSR0_RXON 0x0020 /* receiver on (R) */ 318b955f6caSJeff Kirsher #define CSR0_INEA 0x0040 /* interrupt enable (RW) */ 319b955f6caSJeff Kirsher #define CSR0_INTR 0x0080 /* interrupt active (R) */ 320b955f6caSJeff Kirsher #define CSR0_IDON 0x0100 /* initialization done (RC) */ 321b955f6caSJeff Kirsher #define CSR0_TINT 0x0200 /* transmitter interrupt (RC) */ 322b955f6caSJeff Kirsher #define CSR0_RINT 0x0400 /* receiver interrupt (RC) */ 323b955f6caSJeff Kirsher #define CSR0_MERR 0x0800 /* memory error (RC) */ 324b955f6caSJeff Kirsher #define CSR0_MISS 0x1000 /* missed frame (RC) */ 325b955f6caSJeff Kirsher #define CSR0_CERR 0x2000 /* carrier error (no heartbeat :-) (RC) */ 326b955f6caSJeff Kirsher #define CSR0_BABL 0x4000 /* babble: tx-ed too many bits (RC) */ 327b955f6caSJeff Kirsher #define CSR0_ERR 0x8000 /* error (RC) */ 328b955f6caSJeff Kirsher 329b955f6caSJeff Kirsher /* CSR3 */ 330b955f6caSJeff Kirsher #define CSR3_BCON 0x0001 /* byte control */ 331b955f6caSJeff Kirsher #define CSR3_ACON 0x0002 /* ALE control */ 332b955f6caSJeff Kirsher #define CSR3_BSWP 0x0004 /* byte swap (1=big endian) */ 333b955f6caSJeff Kirsher 334b955f6caSJeff Kirsher 335b955f6caSJeff Kirsher 336b955f6caSJeff Kirsher /***************************** Prototypes *****************************/ 337b955f6caSJeff Kirsher 338b955f6caSJeff Kirsher static unsigned long lance_probe1( struct net_device *dev, struct lance_addr 339b955f6caSJeff Kirsher *init_rec ); 340b955f6caSJeff Kirsher static int lance_open( struct net_device *dev ); 341b955f6caSJeff Kirsher static void lance_init_ring( struct net_device *dev ); 342fe72352eSYueHaibing static netdev_tx_t lance_start_xmit(struct sk_buff *skb, 343fe72352eSYueHaibing struct net_device *dev); 344b955f6caSJeff Kirsher static irqreturn_t lance_interrupt( int irq, void *dev_id ); 345b955f6caSJeff Kirsher static int lance_rx( struct net_device *dev ); 346b955f6caSJeff Kirsher static int lance_close( struct net_device *dev ); 347b955f6caSJeff Kirsher static void set_multicast_list( struct net_device *dev ); 348b955f6caSJeff Kirsher static int lance_set_mac_address( struct net_device *dev, void *addr ); 3490290bd29SMichael S. Tsirkin static void lance_tx_timeout (struct net_device *dev, unsigned int txqueue); 350b955f6caSJeff Kirsher 351b955f6caSJeff Kirsher /************************* End of Prototypes **************************/ 352b955f6caSJeff Kirsher 353b955f6caSJeff Kirsher 354b955f6caSJeff Kirsher 355b955f6caSJeff Kirsher 356b955f6caSJeff Kirsher 357b955f6caSJeff Kirsher static void *slow_memcpy( void *dst, const void *src, size_t len ) 358b955f6caSJeff Kirsher 359b955f6caSJeff Kirsher { char *cto = dst; 360b955f6caSJeff Kirsher const char *cfrom = src; 361b955f6caSJeff Kirsher 362b955f6caSJeff Kirsher while( len-- ) { 363b955f6caSJeff Kirsher *cto++ = *cfrom++; 364b955f6caSJeff Kirsher MFPDELAY(); 365b955f6caSJeff Kirsher } 366b955f6caSJeff Kirsher return dst; 367b955f6caSJeff Kirsher } 368b955f6caSJeff Kirsher 369b955f6caSJeff Kirsher 370*e179d78eSArnd Bergmann struct net_device * __init atarilance_probe(void) 371b955f6caSJeff Kirsher { 372b955f6caSJeff Kirsher int i; 373b955f6caSJeff Kirsher static int found; 374b955f6caSJeff Kirsher struct net_device *dev; 375b955f6caSJeff Kirsher int err = -ENODEV; 376b955f6caSJeff Kirsher 377b955f6caSJeff Kirsher if (!MACH_IS_ATARI || found) 378b955f6caSJeff Kirsher /* Assume there's only one board possible... That seems true, since 379b955f6caSJeff Kirsher * the Riebl/PAM board's address cannot be changed. */ 380b955f6caSJeff Kirsher return ERR_PTR(-ENODEV); 381b955f6caSJeff Kirsher 382b955f6caSJeff Kirsher dev = alloc_etherdev(sizeof(struct lance_private)); 383b955f6caSJeff Kirsher if (!dev) 384b955f6caSJeff Kirsher return ERR_PTR(-ENOMEM); 385b955f6caSJeff Kirsher 386b955f6caSJeff Kirsher for( i = 0; i < N_LANCE_ADDR; ++i ) { 387b955f6caSJeff Kirsher if (lance_probe1( dev, &lance_addr_list[i] )) { 388b955f6caSJeff Kirsher found = 1; 389b955f6caSJeff Kirsher err = register_netdev(dev); 390b955f6caSJeff Kirsher if (!err) 391b955f6caSJeff Kirsher return dev; 392b955f6caSJeff Kirsher free_irq(dev->irq, dev); 393b955f6caSJeff Kirsher break; 394b955f6caSJeff Kirsher } 395b955f6caSJeff Kirsher } 396b955f6caSJeff Kirsher free_netdev(dev); 397b955f6caSJeff Kirsher return ERR_PTR(err); 398b955f6caSJeff Kirsher } 399b955f6caSJeff Kirsher 400b955f6caSJeff Kirsher 401b955f6caSJeff Kirsher /* Derived from hwreg_present() in atari/config.c: */ 402b955f6caSJeff Kirsher 403b955f6caSJeff Kirsher static noinline int __init addr_accessible(volatile void *regp, int wordflag, 404b955f6caSJeff Kirsher int writeflag) 405b955f6caSJeff Kirsher { 406b955f6caSJeff Kirsher int ret; 407b955f6caSJeff Kirsher unsigned long flags; 408b955f6caSJeff Kirsher long *vbr, save_berr; 409b955f6caSJeff Kirsher 410b955f6caSJeff Kirsher local_irq_save(flags); 411b955f6caSJeff Kirsher 412b955f6caSJeff Kirsher __asm__ __volatile__ ( "movec %/vbr,%0" : "=r" (vbr) : ); 413b955f6caSJeff Kirsher save_berr = vbr[2]; 414b955f6caSJeff Kirsher 415b955f6caSJeff Kirsher __asm__ __volatile__ 416b955f6caSJeff Kirsher ( "movel %/sp,%/d1\n\t" 417b955f6caSJeff Kirsher "movel #Lberr,%2@\n\t" 418b955f6caSJeff Kirsher "moveq #0,%0\n\t" 419b955f6caSJeff Kirsher "tstl %3\n\t" 420b955f6caSJeff Kirsher "bne 1f\n\t" 421b955f6caSJeff Kirsher "moveb %1@,%/d0\n\t" 422b955f6caSJeff Kirsher "nop \n\t" 423b955f6caSJeff Kirsher "bra 2f\n" 424b955f6caSJeff Kirsher "1: movew %1@,%/d0\n\t" 425b955f6caSJeff Kirsher "nop \n" 426b955f6caSJeff Kirsher "2: tstl %4\n\t" 427b955f6caSJeff Kirsher "beq 2f\n\t" 428b955f6caSJeff Kirsher "tstl %3\n\t" 429b955f6caSJeff Kirsher "bne 1f\n\t" 430b955f6caSJeff Kirsher "clrb %1@\n\t" 431b955f6caSJeff Kirsher "nop \n\t" 432b955f6caSJeff Kirsher "moveb %/d0,%1@\n\t" 433b955f6caSJeff Kirsher "nop \n\t" 434b955f6caSJeff Kirsher "bra 2f\n" 435b955f6caSJeff Kirsher "1: clrw %1@\n\t" 436b955f6caSJeff Kirsher "nop \n\t" 437b955f6caSJeff Kirsher "movew %/d0,%1@\n\t" 438b955f6caSJeff Kirsher "nop \n" 439b955f6caSJeff Kirsher "2: moveq #1,%0\n" 440b955f6caSJeff Kirsher "Lberr: movel %/d1,%/sp" 441b955f6caSJeff Kirsher : "=&d" (ret) 442b955f6caSJeff Kirsher : "a" (regp), "a" (&vbr[2]), "rm" (wordflag), "rm" (writeflag) 443b955f6caSJeff Kirsher : "d0", "d1", "memory" 444b955f6caSJeff Kirsher ); 445b955f6caSJeff Kirsher 446b955f6caSJeff Kirsher vbr[2] = save_berr; 447b955f6caSJeff Kirsher local_irq_restore(flags); 448b955f6caSJeff Kirsher 449b955f6caSJeff Kirsher return ret; 450b955f6caSJeff Kirsher } 451b955f6caSJeff Kirsher 452b955f6caSJeff Kirsher static const struct net_device_ops lance_netdev_ops = { 453b955f6caSJeff Kirsher .ndo_open = lance_open, 454b955f6caSJeff Kirsher .ndo_stop = lance_close, 455b955f6caSJeff Kirsher .ndo_start_xmit = lance_start_xmit, 456afc4b13dSJiri Pirko .ndo_set_rx_mode = set_multicast_list, 457b955f6caSJeff Kirsher .ndo_set_mac_address = lance_set_mac_address, 458b955f6caSJeff Kirsher .ndo_tx_timeout = lance_tx_timeout, 459b955f6caSJeff Kirsher .ndo_validate_addr = eth_validate_addr, 460b955f6caSJeff Kirsher }; 461b955f6caSJeff Kirsher 462b955f6caSJeff Kirsher static unsigned long __init lance_probe1( struct net_device *dev, 463b955f6caSJeff Kirsher struct lance_addr *init_rec ) 464b955f6caSJeff Kirsher { 465b955f6caSJeff Kirsher volatile unsigned short *memaddr = 466b955f6caSJeff Kirsher (volatile unsigned short *)init_rec->memaddr; 467b955f6caSJeff Kirsher volatile unsigned short *ioaddr = 468b955f6caSJeff Kirsher (volatile unsigned short *)init_rec->ioaddr; 469b955f6caSJeff Kirsher struct lance_private *lp; 470b955f6caSJeff Kirsher struct lance_ioreg *IO; 471b955f6caSJeff Kirsher int i; 472b955f6caSJeff Kirsher static int did_version; 473b955f6caSJeff Kirsher unsigned short save1, save2; 474b955f6caSJeff Kirsher 475b955f6caSJeff Kirsher PROBE_PRINT(( "Probing for Lance card at mem %#lx io %#lx\n", 476b955f6caSJeff Kirsher (long)memaddr, (long)ioaddr )); 477b955f6caSJeff Kirsher 478b955f6caSJeff Kirsher /* Test whether memory readable and writable */ 479b955f6caSJeff Kirsher PROBE_PRINT(( "lance_probe1: testing memory to be accessible\n" )); 480b955f6caSJeff Kirsher if (!addr_accessible( memaddr, 1, 1 )) goto probe_fail; 481b955f6caSJeff Kirsher 482b955f6caSJeff Kirsher /* Written values should come back... */ 483b955f6caSJeff Kirsher PROBE_PRINT(( "lance_probe1: testing memory to be writable (1)\n" )); 484b955f6caSJeff Kirsher save1 = *memaddr; 485b955f6caSJeff Kirsher *memaddr = 0x0001; 486b955f6caSJeff Kirsher if (*memaddr != 0x0001) goto probe_fail; 487b955f6caSJeff Kirsher PROBE_PRINT(( "lance_probe1: testing memory to be writable (2)\n" )); 488b955f6caSJeff Kirsher *memaddr = 0x0000; 489b955f6caSJeff Kirsher if (*memaddr != 0x0000) goto probe_fail; 490b955f6caSJeff Kirsher *memaddr = save1; 491b955f6caSJeff Kirsher 492b955f6caSJeff Kirsher /* First port should be readable and writable */ 493b955f6caSJeff Kirsher PROBE_PRINT(( "lance_probe1: testing ioport to be accessible\n" )); 494b955f6caSJeff Kirsher if (!addr_accessible( ioaddr, 1, 1 )) goto probe_fail; 495b955f6caSJeff Kirsher 496b955f6caSJeff Kirsher /* and written values should be readable */ 497b955f6caSJeff Kirsher PROBE_PRINT(( "lance_probe1: testing ioport to be writeable\n" )); 498b955f6caSJeff Kirsher save2 = ioaddr[1]; 499b955f6caSJeff Kirsher ioaddr[1] = 0x0001; 500b955f6caSJeff Kirsher if (ioaddr[1] != 0x0001) goto probe_fail; 501b955f6caSJeff Kirsher 502b955f6caSJeff Kirsher /* The CSR0_INIT bit should not be readable */ 503b955f6caSJeff Kirsher PROBE_PRINT(( "lance_probe1: testing CSR0 register function (1)\n" )); 504b955f6caSJeff Kirsher save1 = ioaddr[0]; 505b955f6caSJeff Kirsher ioaddr[1] = CSR0; 506b955f6caSJeff Kirsher ioaddr[0] = CSR0_INIT | CSR0_STOP; 507b955f6caSJeff Kirsher if (ioaddr[0] != CSR0_STOP) { 508b955f6caSJeff Kirsher ioaddr[0] = save1; 509b955f6caSJeff Kirsher ioaddr[1] = save2; 510b955f6caSJeff Kirsher goto probe_fail; 511b955f6caSJeff Kirsher } 512b955f6caSJeff Kirsher PROBE_PRINT(( "lance_probe1: testing CSR0 register function (2)\n" )); 513b955f6caSJeff Kirsher ioaddr[0] = CSR0_STOP; 514b955f6caSJeff Kirsher if (ioaddr[0] != CSR0_STOP) { 515b955f6caSJeff Kirsher ioaddr[0] = save1; 516b955f6caSJeff Kirsher ioaddr[1] = save2; 517b955f6caSJeff Kirsher goto probe_fail; 518b955f6caSJeff Kirsher } 519b955f6caSJeff Kirsher 520b955f6caSJeff Kirsher /* Now ok... */ 521b955f6caSJeff Kirsher PROBE_PRINT(( "lance_probe1: Lance card detected\n" )); 522b955f6caSJeff Kirsher goto probe_ok; 523b955f6caSJeff Kirsher 524b955f6caSJeff Kirsher probe_fail: 525b955f6caSJeff Kirsher return 0; 526b955f6caSJeff Kirsher 527b955f6caSJeff Kirsher probe_ok: 528b955f6caSJeff Kirsher lp = netdev_priv(dev); 529b955f6caSJeff Kirsher MEM = (struct lance_memory *)memaddr; 530b955f6caSJeff Kirsher IO = lp->iobase = (struct lance_ioreg *)ioaddr; 531b955f6caSJeff Kirsher dev->base_addr = (unsigned long)ioaddr; /* informational only */ 532b955f6caSJeff Kirsher lp->memcpy_f = init_rec->slow_flag ? slow_memcpy : memcpy; 533b955f6caSJeff Kirsher 534b955f6caSJeff Kirsher REGA( CSR0 ) = CSR0_STOP; 535b955f6caSJeff Kirsher 536b955f6caSJeff Kirsher /* Now test for type: If the eeprom I/O port is readable, it is a 537b955f6caSJeff Kirsher * PAM card */ 538b955f6caSJeff Kirsher if (addr_accessible( &(IO->eeprom), 0, 0 )) { 539b955f6caSJeff Kirsher /* Switch back to Ram */ 540b955f6caSJeff Kirsher i = IO->mem; 541b955f6caSJeff Kirsher lp->cardtype = PAM_CARD; 542b955f6caSJeff Kirsher } 543b955f6caSJeff Kirsher else if (*RIEBL_MAGIC_ADDR == RIEBL_MAGIC) { 544b955f6caSJeff Kirsher lp->cardtype = NEW_RIEBL; 545b955f6caSJeff Kirsher } 546b955f6caSJeff Kirsher else 547b955f6caSJeff Kirsher lp->cardtype = OLD_RIEBL; 548b955f6caSJeff Kirsher 549b955f6caSJeff Kirsher if (lp->cardtype == PAM_CARD || 550b955f6caSJeff Kirsher memaddr == (unsigned short *)0xffe00000) { 551b955f6caSJeff Kirsher /* PAMs card and Riebl on ST use level 5 autovector */ 5528f2bfe5fSGeert Uytterhoeven if (request_irq(IRQ_AUTO_5, lance_interrupt, 0, 553b955f6caSJeff Kirsher "PAM,Riebl-ST Ethernet", dev)) { 554b955f6caSJeff Kirsher printk( "Lance: request for irq %d failed\n", IRQ_AUTO_5 ); 555b955f6caSJeff Kirsher return 0; 556b955f6caSJeff Kirsher } 55744883eb0SGeert Uytterhoeven dev->irq = IRQ_AUTO_5; 558b955f6caSJeff Kirsher } 559b955f6caSJeff Kirsher else { 56044883eb0SGeert Uytterhoeven /* For VME-RieblCards, request a free VME int */ 56144883eb0SGeert Uytterhoeven unsigned int irq = atari_register_vme_int(); 562b955f6caSJeff Kirsher if (!irq) { 563b955f6caSJeff Kirsher printk( "Lance: request for VME interrupt failed\n" ); 564b955f6caSJeff Kirsher return 0; 565b955f6caSJeff Kirsher } 5668f2bfe5fSGeert Uytterhoeven if (request_irq(irq, lance_interrupt, 0, "Riebl-VME Ethernet", 5678f2bfe5fSGeert Uytterhoeven dev)) { 56844883eb0SGeert Uytterhoeven printk( "Lance: request for irq %u failed\n", irq ); 569b955f6caSJeff Kirsher return 0; 570b955f6caSJeff Kirsher } 571b955f6caSJeff Kirsher dev->irq = irq; 572b955f6caSJeff Kirsher } 573b955f6caSJeff Kirsher 574b955f6caSJeff Kirsher printk("%s: %s at io %#lx, mem %#lx, irq %d%s, hwaddr ", 575b955f6caSJeff Kirsher dev->name, lance_names[lp->cardtype], 576b955f6caSJeff Kirsher (unsigned long)ioaddr, 577b955f6caSJeff Kirsher (unsigned long)memaddr, 578b955f6caSJeff Kirsher dev->irq, 579b955f6caSJeff Kirsher init_rec->slow_flag ? " (slow memcpy)" : "" ); 580b955f6caSJeff Kirsher 581b955f6caSJeff Kirsher /* Get the ethernet address */ 582b955f6caSJeff Kirsher switch( lp->cardtype ) { 583b955f6caSJeff Kirsher case OLD_RIEBL: 584b955f6caSJeff Kirsher /* No ethernet address! (Set some default address) */ 585d458cdf7SJoe Perches memcpy(dev->dev_addr, OldRieblDefHwaddr, ETH_ALEN); 586b955f6caSJeff Kirsher break; 587b955f6caSJeff Kirsher case NEW_RIEBL: 588d458cdf7SJoe Perches lp->memcpy_f(dev->dev_addr, RIEBL_HWADDR_ADDR, ETH_ALEN); 589b955f6caSJeff Kirsher break; 590b955f6caSJeff Kirsher case PAM_CARD: 591b955f6caSJeff Kirsher i = IO->eeprom; 592b955f6caSJeff Kirsher for( i = 0; i < 6; ++i ) 593b955f6caSJeff Kirsher dev->dev_addr[i] = 594b955f6caSJeff Kirsher ((((unsigned short *)MEM)[i*2] & 0x0f) << 4) | 595b955f6caSJeff Kirsher ((((unsigned short *)MEM)[i*2+1] & 0x0f)); 596b955f6caSJeff Kirsher i = IO->mem; 597b955f6caSJeff Kirsher break; 598b955f6caSJeff Kirsher } 599b955f6caSJeff Kirsher printk("%pM\n", dev->dev_addr); 600b955f6caSJeff Kirsher if (lp->cardtype == OLD_RIEBL) { 601b955f6caSJeff Kirsher printk( "%s: Warning: This is a default ethernet address!\n", 602b955f6caSJeff Kirsher dev->name ); 603b955f6caSJeff Kirsher printk( " Use \"ifconfig hw ether ...\" to set the address.\n" ); 604b955f6caSJeff Kirsher } 605b955f6caSJeff Kirsher 606b955f6caSJeff Kirsher spin_lock_init(&lp->devlock); 607b955f6caSJeff Kirsher 608b955f6caSJeff Kirsher MEM->init.mode = 0x0000; /* Disable Rx and Tx. */ 609b955f6caSJeff Kirsher for( i = 0; i < 6; i++ ) 610b955f6caSJeff Kirsher MEM->init.hwaddr[i] = dev->dev_addr[i^1]; /* <- 16 bit swap! */ 611b955f6caSJeff Kirsher MEM->init.filter[0] = 0x00000000; 612b955f6caSJeff Kirsher MEM->init.filter[1] = 0x00000000; 613b955f6caSJeff Kirsher MEM->init.rx_ring.adr_lo = offsetof( struct lance_memory, rx_head ); 614b955f6caSJeff Kirsher MEM->init.rx_ring.adr_hi = 0; 615b955f6caSJeff Kirsher MEM->init.rx_ring.len = RX_RING_LEN_BITS; 616b955f6caSJeff Kirsher MEM->init.tx_ring.adr_lo = offsetof( struct lance_memory, tx_head ); 617b955f6caSJeff Kirsher MEM->init.tx_ring.adr_hi = 0; 618b955f6caSJeff Kirsher MEM->init.tx_ring.len = TX_RING_LEN_BITS; 619b955f6caSJeff Kirsher 620b955f6caSJeff Kirsher if (lp->cardtype == PAM_CARD) 621b955f6caSJeff Kirsher IO->ivec = IRQ_SOURCE_TO_VECTOR(dev->irq); 622b955f6caSJeff Kirsher else 623b955f6caSJeff Kirsher *RIEBL_IVEC_ADDR = IRQ_SOURCE_TO_VECTOR(dev->irq); 624b955f6caSJeff Kirsher 625b955f6caSJeff Kirsher if (did_version++ == 0) 626b955f6caSJeff Kirsher DPRINTK( 1, ( version )); 627b955f6caSJeff Kirsher 628b955f6caSJeff Kirsher dev->netdev_ops = &lance_netdev_ops; 629b955f6caSJeff Kirsher 630b955f6caSJeff Kirsher /* XXX MSch */ 631b955f6caSJeff Kirsher dev->watchdog_timeo = TX_TIMEOUT; 632b955f6caSJeff Kirsher 633b955f6caSJeff Kirsher return 1; 634b955f6caSJeff Kirsher } 635b955f6caSJeff Kirsher 636b955f6caSJeff Kirsher 637b955f6caSJeff Kirsher static int lance_open( struct net_device *dev ) 638b955f6caSJeff Kirsher { 639b955f6caSJeff Kirsher struct lance_private *lp = netdev_priv(dev); 640b955f6caSJeff Kirsher struct lance_ioreg *IO = lp->iobase; 641b955f6caSJeff Kirsher int i; 642b955f6caSJeff Kirsher 643b955f6caSJeff Kirsher DPRINTK( 2, ( "%s: lance_open()\n", dev->name )); 644b955f6caSJeff Kirsher 645b955f6caSJeff Kirsher lance_init_ring(dev); 646b955f6caSJeff Kirsher /* Re-initialize the LANCE, and start it when done. */ 647b955f6caSJeff Kirsher 648b955f6caSJeff Kirsher REGA( CSR3 ) = CSR3_BSWP | (lp->cardtype == PAM_CARD ? CSR3_ACON : 0); 649b955f6caSJeff Kirsher REGA( CSR2 ) = 0; 650b955f6caSJeff Kirsher REGA( CSR1 ) = 0; 651b955f6caSJeff Kirsher REGA( CSR0 ) = CSR0_INIT; 652b955f6caSJeff Kirsher /* From now on, AREG is kept to point to CSR0 */ 653b955f6caSJeff Kirsher 654b955f6caSJeff Kirsher i = 1000000; 655b955f6caSJeff Kirsher while (--i > 0) 656b955f6caSJeff Kirsher if (DREG & CSR0_IDON) 657b955f6caSJeff Kirsher break; 658b955f6caSJeff Kirsher if (i <= 0 || (DREG & CSR0_ERR)) { 659b955f6caSJeff Kirsher DPRINTK( 2, ( "lance_open(): opening %s failed, i=%d, csr0=%04x\n", 660b955f6caSJeff Kirsher dev->name, i, DREG )); 661b955f6caSJeff Kirsher DREG = CSR0_STOP; 662b955f6caSJeff Kirsher return -EIO; 663b955f6caSJeff Kirsher } 664b955f6caSJeff Kirsher DREG = CSR0_IDON; 665b955f6caSJeff Kirsher DREG = CSR0_STRT; 666b955f6caSJeff Kirsher DREG = CSR0_INEA; 667b955f6caSJeff Kirsher 668b955f6caSJeff Kirsher netif_start_queue (dev); 669b955f6caSJeff Kirsher 670b955f6caSJeff Kirsher DPRINTK( 2, ( "%s: LANCE is open, csr0 %04x\n", dev->name, DREG )); 671b955f6caSJeff Kirsher 672b955f6caSJeff Kirsher return 0; 673b955f6caSJeff Kirsher } 674b955f6caSJeff Kirsher 675b955f6caSJeff Kirsher 676b955f6caSJeff Kirsher /* Initialize the LANCE Rx and Tx rings. */ 677b955f6caSJeff Kirsher 678b955f6caSJeff Kirsher static void lance_init_ring( struct net_device *dev ) 679b955f6caSJeff Kirsher { 680b955f6caSJeff Kirsher struct lance_private *lp = netdev_priv(dev); 681b955f6caSJeff Kirsher int i; 682b955f6caSJeff Kirsher unsigned offset; 683b955f6caSJeff Kirsher 684b955f6caSJeff Kirsher lp->tx_full = 0; 685b955f6caSJeff Kirsher lp->cur_rx = lp->cur_tx = 0; 686b955f6caSJeff Kirsher lp->dirty_tx = 0; 687b955f6caSJeff Kirsher 688b955f6caSJeff Kirsher offset = offsetof( struct lance_memory, packet_area ); 689b955f6caSJeff Kirsher 690b955f6caSJeff Kirsher /* If the packet buffer at offset 'o' would conflict with the reserved area 691b955f6caSJeff Kirsher * of RieblCards, advance it */ 692b955f6caSJeff Kirsher #define CHECK_OFFSET(o) \ 693b955f6caSJeff Kirsher do { \ 694b955f6caSJeff Kirsher if (lp->cardtype == OLD_RIEBL || lp->cardtype == NEW_RIEBL) { \ 695b955f6caSJeff Kirsher if (((o) < RIEBL_RSVD_START) ? (o)+PKT_BUF_SZ > RIEBL_RSVD_START \ 696b955f6caSJeff Kirsher : (o) < RIEBL_RSVD_END) \ 697b955f6caSJeff Kirsher (o) = RIEBL_RSVD_END; \ 698b955f6caSJeff Kirsher } \ 699b955f6caSJeff Kirsher } while(0) 700b955f6caSJeff Kirsher 701b955f6caSJeff Kirsher for( i = 0; i < TX_RING_SIZE; i++ ) { 702b955f6caSJeff Kirsher CHECK_OFFSET(offset); 703b955f6caSJeff Kirsher MEM->tx_head[i].base = offset; 704b955f6caSJeff Kirsher MEM->tx_head[i].flag = TMD1_OWN_HOST; 705b955f6caSJeff Kirsher MEM->tx_head[i].base_hi = 0; 706b955f6caSJeff Kirsher MEM->tx_head[i].length = 0; 707b955f6caSJeff Kirsher MEM->tx_head[i].misc = 0; 708b955f6caSJeff Kirsher offset += PKT_BUF_SZ; 709b955f6caSJeff Kirsher } 710b955f6caSJeff Kirsher 711b955f6caSJeff Kirsher for( i = 0; i < RX_RING_SIZE; i++ ) { 712b955f6caSJeff Kirsher CHECK_OFFSET(offset); 713b955f6caSJeff Kirsher MEM->rx_head[i].base = offset; 714b955f6caSJeff Kirsher MEM->rx_head[i].flag = TMD1_OWN_CHIP; 715b955f6caSJeff Kirsher MEM->rx_head[i].base_hi = 0; 716b955f6caSJeff Kirsher MEM->rx_head[i].buf_length = -PKT_BUF_SZ; 717b955f6caSJeff Kirsher MEM->rx_head[i].msg_length = 0; 718b955f6caSJeff Kirsher offset += PKT_BUF_SZ; 719b955f6caSJeff Kirsher } 720b955f6caSJeff Kirsher } 721b955f6caSJeff Kirsher 722b955f6caSJeff Kirsher 723b955f6caSJeff Kirsher /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ 724b955f6caSJeff Kirsher 725b955f6caSJeff Kirsher 7260290bd29SMichael S. Tsirkin static void lance_tx_timeout (struct net_device *dev, unsigned int txqueue) 727b955f6caSJeff Kirsher { 728b955f6caSJeff Kirsher struct lance_private *lp = netdev_priv(dev); 729b955f6caSJeff Kirsher struct lance_ioreg *IO = lp->iobase; 730b955f6caSJeff Kirsher 731b955f6caSJeff Kirsher AREG = CSR0; 732b955f6caSJeff Kirsher DPRINTK( 1, ( "%s: transmit timed out, status %04x, resetting.\n", 733b955f6caSJeff Kirsher dev->name, DREG )); 734b955f6caSJeff Kirsher DREG = CSR0_STOP; 735b955f6caSJeff Kirsher /* 736b955f6caSJeff Kirsher * Always set BSWP after a STOP as STOP puts it back into 737b955f6caSJeff Kirsher * little endian mode. 738b955f6caSJeff Kirsher */ 739b955f6caSJeff Kirsher REGA( CSR3 ) = CSR3_BSWP | (lp->cardtype == PAM_CARD ? CSR3_ACON : 0); 740b955f6caSJeff Kirsher dev->stats.tx_errors++; 741b955f6caSJeff Kirsher #ifndef final_version 742b955f6caSJeff Kirsher { int i; 743b955f6caSJeff Kirsher DPRINTK( 2, ( "Ring data: dirty_tx %d cur_tx %d%s cur_rx %d\n", 744b955f6caSJeff Kirsher lp->dirty_tx, lp->cur_tx, 745b955f6caSJeff Kirsher lp->tx_full ? " (full)" : "", 746b955f6caSJeff Kirsher lp->cur_rx )); 747b955f6caSJeff Kirsher for( i = 0 ; i < RX_RING_SIZE; i++ ) 748b955f6caSJeff Kirsher DPRINTK( 2, ( "rx #%d: base=%04x blen=%04x mlen=%04x\n", 749b955f6caSJeff Kirsher i, MEM->rx_head[i].base, 750b955f6caSJeff Kirsher -MEM->rx_head[i].buf_length, 751b955f6caSJeff Kirsher MEM->rx_head[i].msg_length )); 752b955f6caSJeff Kirsher for( i = 0 ; i < TX_RING_SIZE; i++ ) 753b955f6caSJeff Kirsher DPRINTK( 2, ( "tx #%d: base=%04x len=%04x misc=%04x\n", 754b955f6caSJeff Kirsher i, MEM->tx_head[i].base, 755b955f6caSJeff Kirsher -MEM->tx_head[i].length, 756b955f6caSJeff Kirsher MEM->tx_head[i].misc )); 757b955f6caSJeff Kirsher } 758b955f6caSJeff Kirsher #endif 759b955f6caSJeff Kirsher /* XXX MSch: maybe purge/reinit ring here */ 760b955f6caSJeff Kirsher /* lance_restart, essentially */ 761b955f6caSJeff Kirsher lance_init_ring(dev); 762b955f6caSJeff Kirsher REGA( CSR0 ) = CSR0_INEA | CSR0_INIT | CSR0_STRT; 763860e9538SFlorian Westphal netif_trans_update(dev); /* prevent tx timeout */ 764b955f6caSJeff Kirsher netif_wake_queue(dev); 765b955f6caSJeff Kirsher } 766b955f6caSJeff Kirsher 767b955f6caSJeff Kirsher /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX */ 768b955f6caSJeff Kirsher 769fe72352eSYueHaibing static netdev_tx_t 770fe72352eSYueHaibing lance_start_xmit(struct sk_buff *skb, struct net_device *dev) 771b955f6caSJeff Kirsher { 772b955f6caSJeff Kirsher struct lance_private *lp = netdev_priv(dev); 773b955f6caSJeff Kirsher struct lance_ioreg *IO = lp->iobase; 774b955f6caSJeff Kirsher int entry, len; 775b955f6caSJeff Kirsher struct lance_tx_head *head; 776b955f6caSJeff Kirsher unsigned long flags; 777b955f6caSJeff Kirsher 778b955f6caSJeff Kirsher DPRINTK( 2, ( "%s: lance_start_xmit() called, csr0 %4.4x.\n", 779b955f6caSJeff Kirsher dev->name, DREG )); 780b955f6caSJeff Kirsher 781b955f6caSJeff Kirsher 782b955f6caSJeff Kirsher /* The old LANCE chips doesn't automatically pad buffers to min. size. */ 783b955f6caSJeff Kirsher len = skb->len; 784b955f6caSJeff Kirsher if (len < ETH_ZLEN) 785b955f6caSJeff Kirsher len = ETH_ZLEN; 786b955f6caSJeff Kirsher /* PAM-Card has a bug: Can only send packets with even number of bytes! */ 787b955f6caSJeff Kirsher else if (lp->cardtype == PAM_CARD && (len & 1)) 788b955f6caSJeff Kirsher ++len; 789b955f6caSJeff Kirsher 790b955f6caSJeff Kirsher if (len > skb->len) { 791b955f6caSJeff Kirsher if (skb_padto(skb, len)) 792b955f6caSJeff Kirsher return NETDEV_TX_OK; 793b955f6caSJeff Kirsher } 794b955f6caSJeff Kirsher 795b955f6caSJeff Kirsher netif_stop_queue (dev); 796b955f6caSJeff Kirsher 797b955f6caSJeff Kirsher /* Fill in a Tx ring entry */ 798b955f6caSJeff Kirsher if (lance_debug >= 3) { 799b955f6caSJeff Kirsher printk( "%s: TX pkt type 0x%04x from %pM to %pM" 800b955f6caSJeff Kirsher " data at 0x%08x len %d\n", 801b955f6caSJeff Kirsher dev->name, ((u_short *)skb->data)[6], 802b955f6caSJeff Kirsher &skb->data[6], skb->data, 803b955f6caSJeff Kirsher (int)skb->data, (int)skb->len ); 804b955f6caSJeff Kirsher } 805b955f6caSJeff Kirsher 806b955f6caSJeff Kirsher /* We're not prepared for the int until the last flags are set/reset. And 807b955f6caSJeff Kirsher * the int may happen already after setting the OWN_CHIP... */ 808b955f6caSJeff Kirsher spin_lock_irqsave (&lp->devlock, flags); 809b955f6caSJeff Kirsher 810b955f6caSJeff Kirsher /* Mask to ring buffer boundary. */ 811b955f6caSJeff Kirsher entry = lp->cur_tx & TX_RING_MOD_MASK; 812b955f6caSJeff Kirsher head = &(MEM->tx_head[entry]); 813b955f6caSJeff Kirsher 814b955f6caSJeff Kirsher /* Caution: the write order is important here, set the "ownership" bits 815b955f6caSJeff Kirsher * last. 816b955f6caSJeff Kirsher */ 817b955f6caSJeff Kirsher 818b955f6caSJeff Kirsher 819b955f6caSJeff Kirsher head->length = -len; 820b955f6caSJeff Kirsher head->misc = 0; 821b955f6caSJeff Kirsher lp->memcpy_f( PKTBUF_ADDR(head), (void *)skb->data, skb->len ); 822b955f6caSJeff Kirsher head->flag = TMD1_OWN_CHIP | TMD1_ENP | TMD1_STP; 823b955f6caSJeff Kirsher dev->stats.tx_bytes += skb->len; 824b955f6caSJeff Kirsher dev_kfree_skb( skb ); 825b955f6caSJeff Kirsher lp->cur_tx++; 826b955f6caSJeff Kirsher while( lp->cur_tx >= TX_RING_SIZE && lp->dirty_tx >= TX_RING_SIZE ) { 827b955f6caSJeff Kirsher lp->cur_tx -= TX_RING_SIZE; 828b955f6caSJeff Kirsher lp->dirty_tx -= TX_RING_SIZE; 829b955f6caSJeff Kirsher } 830b955f6caSJeff Kirsher 831b955f6caSJeff Kirsher /* Trigger an immediate send poll. */ 832b955f6caSJeff Kirsher DREG = CSR0_INEA | CSR0_TDMD; 833b955f6caSJeff Kirsher 834b955f6caSJeff Kirsher if ((MEM->tx_head[(entry+1) & TX_RING_MOD_MASK].flag & TMD1_OWN) == 835b955f6caSJeff Kirsher TMD1_OWN_HOST) 836b955f6caSJeff Kirsher netif_start_queue (dev); 837b955f6caSJeff Kirsher else 838b955f6caSJeff Kirsher lp->tx_full = 1; 839b955f6caSJeff Kirsher spin_unlock_irqrestore (&lp->devlock, flags); 840b955f6caSJeff Kirsher 841b955f6caSJeff Kirsher return NETDEV_TX_OK; 842b955f6caSJeff Kirsher } 843b955f6caSJeff Kirsher 844b955f6caSJeff Kirsher /* The LANCE interrupt handler. */ 845b955f6caSJeff Kirsher 846b955f6caSJeff Kirsher static irqreturn_t lance_interrupt( int irq, void *dev_id ) 847b955f6caSJeff Kirsher { 848b955f6caSJeff Kirsher struct net_device *dev = dev_id; 849b955f6caSJeff Kirsher struct lance_private *lp; 850b955f6caSJeff Kirsher struct lance_ioreg *IO; 851b955f6caSJeff Kirsher int csr0, boguscnt = 10; 852b955f6caSJeff Kirsher int handled = 0; 853b955f6caSJeff Kirsher 854b955f6caSJeff Kirsher if (dev == NULL) { 855b955f6caSJeff Kirsher DPRINTK( 1, ( "lance_interrupt(): interrupt for unknown device.\n" )); 856b955f6caSJeff Kirsher return IRQ_NONE; 857b955f6caSJeff Kirsher } 858b955f6caSJeff Kirsher 859b955f6caSJeff Kirsher lp = netdev_priv(dev); 860b955f6caSJeff Kirsher IO = lp->iobase; 861b955f6caSJeff Kirsher spin_lock (&lp->devlock); 862b955f6caSJeff Kirsher 863b955f6caSJeff Kirsher AREG = CSR0; 864b955f6caSJeff Kirsher 865b955f6caSJeff Kirsher while( ((csr0 = DREG) & (CSR0_ERR | CSR0_TINT | CSR0_RINT)) && 866b955f6caSJeff Kirsher --boguscnt >= 0) { 867b955f6caSJeff Kirsher handled = 1; 868b955f6caSJeff Kirsher /* Acknowledge all of the current interrupt sources ASAP. */ 869b955f6caSJeff Kirsher DREG = csr0 & ~(CSR0_INIT | CSR0_STRT | CSR0_STOP | 870b955f6caSJeff Kirsher CSR0_TDMD | CSR0_INEA); 871b955f6caSJeff Kirsher 872b955f6caSJeff Kirsher DPRINTK( 2, ( "%s: interrupt csr0=%04x new csr=%04x.\n", 873b955f6caSJeff Kirsher dev->name, csr0, DREG )); 874b955f6caSJeff Kirsher 875b955f6caSJeff Kirsher if (csr0 & CSR0_RINT) /* Rx interrupt */ 876b955f6caSJeff Kirsher lance_rx( dev ); 877b955f6caSJeff Kirsher 878b955f6caSJeff Kirsher if (csr0 & CSR0_TINT) { /* Tx-done interrupt */ 879b955f6caSJeff Kirsher int dirty_tx = lp->dirty_tx; 880b955f6caSJeff Kirsher 881b955f6caSJeff Kirsher while( dirty_tx < lp->cur_tx) { 882b955f6caSJeff Kirsher int entry = dirty_tx & TX_RING_MOD_MASK; 883b955f6caSJeff Kirsher int status = MEM->tx_head[entry].flag; 884b955f6caSJeff Kirsher 885b955f6caSJeff Kirsher if (status & TMD1_OWN_CHIP) 886b955f6caSJeff Kirsher break; /* It still hasn't been Txed */ 887b955f6caSJeff Kirsher 888b955f6caSJeff Kirsher MEM->tx_head[entry].flag = 0; 889b955f6caSJeff Kirsher 890b955f6caSJeff Kirsher if (status & TMD1_ERR) { 891b955f6caSJeff Kirsher /* There was an major error, log it. */ 892b955f6caSJeff Kirsher int err_status = MEM->tx_head[entry].misc; 893b955f6caSJeff Kirsher dev->stats.tx_errors++; 894b955f6caSJeff Kirsher if (err_status & TMD3_RTRY) dev->stats.tx_aborted_errors++; 895b955f6caSJeff Kirsher if (err_status & TMD3_LCAR) dev->stats.tx_carrier_errors++; 896b955f6caSJeff Kirsher if (err_status & TMD3_LCOL) dev->stats.tx_window_errors++; 897b955f6caSJeff Kirsher if (err_status & TMD3_UFLO) { 898b955f6caSJeff Kirsher /* Ackk! On FIFO errors the Tx unit is turned off! */ 899b955f6caSJeff Kirsher dev->stats.tx_fifo_errors++; 900b955f6caSJeff Kirsher /* Remove this verbosity later! */ 901b955f6caSJeff Kirsher DPRINTK( 1, ( "%s: Tx FIFO error! Status %04x\n", 902b955f6caSJeff Kirsher dev->name, csr0 )); 903b955f6caSJeff Kirsher /* Restart the chip. */ 904b955f6caSJeff Kirsher DREG = CSR0_STRT; 905b955f6caSJeff Kirsher } 906b955f6caSJeff Kirsher } else { 907b955f6caSJeff Kirsher if (status & (TMD1_MORE | TMD1_ONE | TMD1_DEF)) 908b955f6caSJeff Kirsher dev->stats.collisions++; 909b955f6caSJeff Kirsher dev->stats.tx_packets++; 910b955f6caSJeff Kirsher } 911b955f6caSJeff Kirsher 912b955f6caSJeff Kirsher /* XXX MSch: free skb?? */ 913b955f6caSJeff Kirsher dirty_tx++; 914b955f6caSJeff Kirsher } 915b955f6caSJeff Kirsher 916b955f6caSJeff Kirsher #ifndef final_version 917b955f6caSJeff Kirsher if (lp->cur_tx - dirty_tx >= TX_RING_SIZE) { 918b955f6caSJeff Kirsher DPRINTK( 0, ( "out-of-sync dirty pointer," 919b955f6caSJeff Kirsher " %d vs. %d, full=%ld.\n", 920b955f6caSJeff Kirsher dirty_tx, lp->cur_tx, lp->tx_full )); 921b955f6caSJeff Kirsher dirty_tx += TX_RING_SIZE; 922b955f6caSJeff Kirsher } 923b955f6caSJeff Kirsher #endif 924b955f6caSJeff Kirsher 925b955f6caSJeff Kirsher if (lp->tx_full && (netif_queue_stopped(dev)) && 926b955f6caSJeff Kirsher dirty_tx > lp->cur_tx - TX_RING_SIZE + 2) { 927b955f6caSJeff Kirsher /* The ring is no longer full, clear tbusy. */ 928b955f6caSJeff Kirsher lp->tx_full = 0; 929b955f6caSJeff Kirsher netif_wake_queue (dev); 930b955f6caSJeff Kirsher } 931b955f6caSJeff Kirsher 932b955f6caSJeff Kirsher lp->dirty_tx = dirty_tx; 933b955f6caSJeff Kirsher } 934b955f6caSJeff Kirsher 935b955f6caSJeff Kirsher /* Log misc errors. */ 936b955f6caSJeff Kirsher if (csr0 & CSR0_BABL) dev->stats.tx_errors++; /* Tx babble. */ 937b955f6caSJeff Kirsher if (csr0 & CSR0_MISS) dev->stats.rx_errors++; /* Missed a Rx frame. */ 938b955f6caSJeff Kirsher if (csr0 & CSR0_MERR) { 939b955f6caSJeff Kirsher DPRINTK( 1, ( "%s: Bus master arbitration failure (?!?), " 940b955f6caSJeff Kirsher "status %04x.\n", dev->name, csr0 )); 941b955f6caSJeff Kirsher /* Restart the chip. */ 942b955f6caSJeff Kirsher DREG = CSR0_STRT; 943b955f6caSJeff Kirsher } 944b955f6caSJeff Kirsher } 945b955f6caSJeff Kirsher 946b955f6caSJeff Kirsher /* Clear any other interrupt, and set interrupt enable. */ 947b955f6caSJeff Kirsher DREG = CSR0_BABL | CSR0_CERR | CSR0_MISS | CSR0_MERR | 948b955f6caSJeff Kirsher CSR0_IDON | CSR0_INEA; 949b955f6caSJeff Kirsher 950b955f6caSJeff Kirsher DPRINTK( 2, ( "%s: exiting interrupt, csr0=%#04x.\n", 951b955f6caSJeff Kirsher dev->name, DREG )); 952b955f6caSJeff Kirsher 953b955f6caSJeff Kirsher spin_unlock (&lp->devlock); 954b955f6caSJeff Kirsher return IRQ_RETVAL(handled); 955b955f6caSJeff Kirsher } 956b955f6caSJeff Kirsher 957b955f6caSJeff Kirsher 958b955f6caSJeff Kirsher static int lance_rx( struct net_device *dev ) 959b955f6caSJeff Kirsher { 960b955f6caSJeff Kirsher struct lance_private *lp = netdev_priv(dev); 961b955f6caSJeff Kirsher int entry = lp->cur_rx & RX_RING_MOD_MASK; 962b955f6caSJeff Kirsher int i; 963b955f6caSJeff Kirsher 964b955f6caSJeff Kirsher DPRINTK( 2, ( "%s: rx int, flag=%04x\n", dev->name, 965b955f6caSJeff Kirsher MEM->rx_head[entry].flag )); 966b955f6caSJeff Kirsher 967b955f6caSJeff Kirsher /* If we own the next entry, it's a new packet. Send it up. */ 968b955f6caSJeff Kirsher while( (MEM->rx_head[entry].flag & RMD1_OWN) == RMD1_OWN_HOST ) { 969b955f6caSJeff Kirsher struct lance_rx_head *head = &(MEM->rx_head[entry]); 970b955f6caSJeff Kirsher int status = head->flag; 971b955f6caSJeff Kirsher 972b955f6caSJeff Kirsher if (status != (RMD1_ENP|RMD1_STP)) { /* There was an error. */ 973b955f6caSJeff Kirsher /* There is a tricky error noted by John Murphy, 974b955f6caSJeff Kirsher <murf@perftech.com> to Russ Nelson: Even with full-sized 975b955f6caSJeff Kirsher buffers it's possible for a jabber packet to use two 976b955f6caSJeff Kirsher buffers, with only the last correctly noting the error. */ 977b955f6caSJeff Kirsher if (status & RMD1_ENP) /* Only count a general error at the */ 978b955f6caSJeff Kirsher dev->stats.rx_errors++; /* end of a packet.*/ 979b955f6caSJeff Kirsher if (status & RMD1_FRAM) dev->stats.rx_frame_errors++; 980b955f6caSJeff Kirsher if (status & RMD1_OFLO) dev->stats.rx_over_errors++; 981b955f6caSJeff Kirsher if (status & RMD1_CRC) dev->stats.rx_crc_errors++; 982b955f6caSJeff Kirsher if (status & RMD1_BUFF) dev->stats.rx_fifo_errors++; 983b955f6caSJeff Kirsher head->flag &= (RMD1_ENP|RMD1_STP); 984b955f6caSJeff Kirsher } else { 985b955f6caSJeff Kirsher /* Malloc up new buffer, compatible with net-3. */ 986b955f6caSJeff Kirsher short pkt_len = head->msg_length & 0xfff; 987b955f6caSJeff Kirsher struct sk_buff *skb; 988b955f6caSJeff Kirsher 989b955f6caSJeff Kirsher if (pkt_len < 60) { 990b955f6caSJeff Kirsher printk( "%s: Runt packet!\n", dev->name ); 991b955f6caSJeff Kirsher dev->stats.rx_errors++; 992b955f6caSJeff Kirsher } 993b955f6caSJeff Kirsher else { 9941d266430SPradeep A Dalvi skb = netdev_alloc_skb(dev, pkt_len + 2); 995b955f6caSJeff Kirsher if (skb == NULL) { 996b955f6caSJeff Kirsher for( i = 0; i < RX_RING_SIZE; i++ ) 997b955f6caSJeff Kirsher if (MEM->rx_head[(entry+i) & RX_RING_MOD_MASK].flag & 998b955f6caSJeff Kirsher RMD1_OWN_CHIP) 999b955f6caSJeff Kirsher break; 1000b955f6caSJeff Kirsher 1001b955f6caSJeff Kirsher if (i > RX_RING_SIZE - 2) { 1002b955f6caSJeff Kirsher dev->stats.rx_dropped++; 1003b955f6caSJeff Kirsher head->flag |= RMD1_OWN_CHIP; 1004b955f6caSJeff Kirsher lp->cur_rx++; 1005b955f6caSJeff Kirsher } 1006b955f6caSJeff Kirsher break; 1007b955f6caSJeff Kirsher } 1008b955f6caSJeff Kirsher 1009b955f6caSJeff Kirsher if (lance_debug >= 3) { 1010b955f6caSJeff Kirsher u_char *data = PKTBUF_ADDR(head); 1011b955f6caSJeff Kirsher 1012b955f6caSJeff Kirsher printk(KERN_DEBUG "%s: RX pkt type 0x%04x from %pM to %pM " 1013b14945acSRasmus Villemoes "data %8ph len %d\n", 1014b955f6caSJeff Kirsher dev->name, ((u_short *)data)[6], 1015b14945acSRasmus Villemoes &data[6], data, &data[15], pkt_len); 1016b955f6caSJeff Kirsher } 1017b955f6caSJeff Kirsher 1018b955f6caSJeff Kirsher skb_reserve( skb, 2 ); /* 16 byte align */ 1019b955f6caSJeff Kirsher skb_put( skb, pkt_len ); /* Make room */ 1020b955f6caSJeff Kirsher lp->memcpy_f( skb->data, PKTBUF_ADDR(head), pkt_len ); 1021b955f6caSJeff Kirsher skb->protocol = eth_type_trans( skb, dev ); 1022b955f6caSJeff Kirsher netif_rx( skb ); 1023b955f6caSJeff Kirsher dev->stats.rx_packets++; 1024b955f6caSJeff Kirsher dev->stats.rx_bytes += pkt_len; 1025b955f6caSJeff Kirsher } 1026b955f6caSJeff Kirsher } 1027b955f6caSJeff Kirsher 1028b955f6caSJeff Kirsher head->flag |= RMD1_OWN_CHIP; 1029b955f6caSJeff Kirsher entry = (++lp->cur_rx) & RX_RING_MOD_MASK; 1030b955f6caSJeff Kirsher } 1031b955f6caSJeff Kirsher lp->cur_rx &= RX_RING_MOD_MASK; 1032b955f6caSJeff Kirsher 1033b955f6caSJeff Kirsher /* From lance.c (Donald Becker): */ 1034b955f6caSJeff Kirsher /* We should check that at least two ring entries are free. If not, 1035b955f6caSJeff Kirsher we should free one and mark stats->rx_dropped++. */ 1036b955f6caSJeff Kirsher 1037b955f6caSJeff Kirsher return 0; 1038b955f6caSJeff Kirsher } 1039b955f6caSJeff Kirsher 1040b955f6caSJeff Kirsher 1041b955f6caSJeff Kirsher static int lance_close( struct net_device *dev ) 1042b955f6caSJeff Kirsher { 1043b955f6caSJeff Kirsher struct lance_private *lp = netdev_priv(dev); 1044b955f6caSJeff Kirsher struct lance_ioreg *IO = lp->iobase; 1045b955f6caSJeff Kirsher 1046b955f6caSJeff Kirsher netif_stop_queue (dev); 1047b955f6caSJeff Kirsher 1048b955f6caSJeff Kirsher AREG = CSR0; 1049b955f6caSJeff Kirsher 1050b955f6caSJeff Kirsher DPRINTK( 2, ( "%s: Shutting down ethercard, status was %2.2x.\n", 1051b955f6caSJeff Kirsher dev->name, DREG )); 1052b955f6caSJeff Kirsher 1053b955f6caSJeff Kirsher /* We stop the LANCE here -- it occasionally polls 1054b955f6caSJeff Kirsher memory if we don't. */ 1055b955f6caSJeff Kirsher DREG = CSR0_STOP; 1056b955f6caSJeff Kirsher 1057b955f6caSJeff Kirsher return 0; 1058b955f6caSJeff Kirsher } 1059b955f6caSJeff Kirsher 1060b955f6caSJeff Kirsher 1061b955f6caSJeff Kirsher /* Set or clear the multicast filter for this adaptor. 1062b955f6caSJeff Kirsher num_addrs == -1 Promiscuous mode, receive all packets 1063b955f6caSJeff Kirsher num_addrs == 0 Normal mode, clear multicast list 1064b955f6caSJeff Kirsher num_addrs > 0 Multicast mode, receive normal and MC packets, and do 1065b955f6caSJeff Kirsher best-effort filtering. 1066b955f6caSJeff Kirsher */ 1067b955f6caSJeff Kirsher 1068b955f6caSJeff Kirsher static void set_multicast_list( struct net_device *dev ) 1069b955f6caSJeff Kirsher { 1070b955f6caSJeff Kirsher struct lance_private *lp = netdev_priv(dev); 1071b955f6caSJeff Kirsher struct lance_ioreg *IO = lp->iobase; 1072b955f6caSJeff Kirsher 1073b955f6caSJeff Kirsher if (netif_running(dev)) 1074b955f6caSJeff Kirsher /* Only possible if board is already started */ 1075b955f6caSJeff Kirsher return; 1076b955f6caSJeff Kirsher 1077b955f6caSJeff Kirsher /* We take the simple way out and always enable promiscuous mode. */ 1078b955f6caSJeff Kirsher DREG = CSR0_STOP; /* Temporarily stop the lance. */ 1079b955f6caSJeff Kirsher 1080b955f6caSJeff Kirsher if (dev->flags & IFF_PROMISC) { 1081b955f6caSJeff Kirsher /* Log any net taps. */ 1082b955f6caSJeff Kirsher DPRINTK( 2, ( "%s: Promiscuous mode enabled.\n", dev->name )); 1083b955f6caSJeff Kirsher REGA( CSR15 ) = 0x8000; /* Set promiscuous mode */ 1084b955f6caSJeff Kirsher } else { 1085b955f6caSJeff Kirsher short multicast_table[4]; 1086b955f6caSJeff Kirsher int num_addrs = netdev_mc_count(dev); 1087b955f6caSJeff Kirsher int i; 1088b955f6caSJeff Kirsher /* We don't use the multicast table, but rely on upper-layer 1089b955f6caSJeff Kirsher * filtering. */ 1090b955f6caSJeff Kirsher memset( multicast_table, (num_addrs == 0) ? 0 : -1, 1091b955f6caSJeff Kirsher sizeof(multicast_table) ); 1092b955f6caSJeff Kirsher for( i = 0; i < 4; i++ ) 1093b955f6caSJeff Kirsher REGA( CSR8+i ) = multicast_table[i]; 1094b955f6caSJeff Kirsher REGA( CSR15 ) = 0; /* Unset promiscuous mode */ 1095b955f6caSJeff Kirsher } 1096b955f6caSJeff Kirsher 1097b955f6caSJeff Kirsher /* 1098b955f6caSJeff Kirsher * Always set BSWP after a STOP as STOP puts it back into 1099b955f6caSJeff Kirsher * little endian mode. 1100b955f6caSJeff Kirsher */ 1101b955f6caSJeff Kirsher REGA( CSR3 ) = CSR3_BSWP | (lp->cardtype == PAM_CARD ? CSR3_ACON : 0); 1102b955f6caSJeff Kirsher 1103b955f6caSJeff Kirsher /* Resume normal operation and reset AREG to CSR0 */ 1104b955f6caSJeff Kirsher REGA( CSR0 ) = CSR0_IDON | CSR0_INEA | CSR0_STRT; 1105b955f6caSJeff Kirsher } 1106b955f6caSJeff Kirsher 1107b955f6caSJeff Kirsher 1108b955f6caSJeff Kirsher /* This is needed for old RieblCards and possible for new RieblCards */ 1109b955f6caSJeff Kirsher 1110b955f6caSJeff Kirsher static int lance_set_mac_address( struct net_device *dev, void *addr ) 1111b955f6caSJeff Kirsher { 1112b955f6caSJeff Kirsher struct lance_private *lp = netdev_priv(dev); 1113b955f6caSJeff Kirsher struct sockaddr *saddr = addr; 1114b955f6caSJeff Kirsher int i; 1115b955f6caSJeff Kirsher 1116b955f6caSJeff Kirsher if (lp->cardtype != OLD_RIEBL && lp->cardtype != NEW_RIEBL) 1117b955f6caSJeff Kirsher return -EOPNOTSUPP; 1118b955f6caSJeff Kirsher 1119b955f6caSJeff Kirsher if (netif_running(dev)) { 1120b955f6caSJeff Kirsher /* Only possible while card isn't started */ 1121b955f6caSJeff Kirsher DPRINTK( 1, ( "%s: hwaddr can be set only while card isn't open.\n", 1122b955f6caSJeff Kirsher dev->name )); 1123b955f6caSJeff Kirsher return -EIO; 1124b955f6caSJeff Kirsher } 1125b955f6caSJeff Kirsher 1126b955f6caSJeff Kirsher memcpy( dev->dev_addr, saddr->sa_data, dev->addr_len ); 1127b955f6caSJeff Kirsher for( i = 0; i < 6; i++ ) 1128b955f6caSJeff Kirsher MEM->init.hwaddr[i] = dev->dev_addr[i^1]; /* <- 16 bit swap! */ 1129b955f6caSJeff Kirsher lp->memcpy_f( RIEBL_HWADDR_ADDR, dev->dev_addr, 6 ); 1130b955f6caSJeff Kirsher /* set also the magic for future sessions */ 1131b955f6caSJeff Kirsher *RIEBL_MAGIC_ADDR = RIEBL_MAGIC; 1132b955f6caSJeff Kirsher 1133b955f6caSJeff Kirsher return 0; 1134b955f6caSJeff Kirsher } 1135b955f6caSJeff Kirsher 1136b955f6caSJeff Kirsher static struct net_device *atarilance_dev; 1137b955f6caSJeff Kirsher 1138b955f6caSJeff Kirsher static int __init atarilance_module_init(void) 1139b955f6caSJeff Kirsher { 1140*e179d78eSArnd Bergmann atarilance_dev = atarilance_probe(); 11418c6ffba0SRusty Russell return PTR_ERR_OR_ZERO(atarilance_dev); 1142b955f6caSJeff Kirsher } 1143b955f6caSJeff Kirsher 1144b955f6caSJeff Kirsher static void __exit atarilance_module_exit(void) 1145b955f6caSJeff Kirsher { 1146b955f6caSJeff Kirsher unregister_netdev(atarilance_dev); 1147b955f6caSJeff Kirsher free_irq(atarilance_dev->irq, atarilance_dev); 1148b955f6caSJeff Kirsher free_netdev(atarilance_dev); 1149b955f6caSJeff Kirsher } 1150b955f6caSJeff Kirsher module_init(atarilance_module_init); 1151b955f6caSJeff Kirsher module_exit(atarilance_module_exit); 1152