1a8fe65b8SJeff Kirsher /* atp.c: Attached (pocket) ethernet adapter driver for linux. */ 2a8fe65b8SJeff Kirsher /* 3a8fe65b8SJeff Kirsher This is a driver for commonly OEM pocket (parallel port) 4a8fe65b8SJeff Kirsher ethernet adapters based on the Realtek RTL8002 and RTL8012 chips. 5a8fe65b8SJeff Kirsher 6a8fe65b8SJeff Kirsher Written 1993-2000 by Donald Becker. 7a8fe65b8SJeff Kirsher 8a8fe65b8SJeff Kirsher This software may be used and distributed according to the terms of 9a8fe65b8SJeff Kirsher the GNU General Public License (GPL), incorporated herein by reference. 10a8fe65b8SJeff Kirsher Drivers based on or derived from this code fall under the GPL and must 11a8fe65b8SJeff Kirsher retain the authorship, copyright and license notice. This file is not 12a8fe65b8SJeff Kirsher a complete program and may only be used when the entire operating 13a8fe65b8SJeff Kirsher system is licensed under the GPL. 14a8fe65b8SJeff Kirsher 15a8fe65b8SJeff Kirsher Copyright 1993 United States Government as represented by the Director, 16a8fe65b8SJeff Kirsher National Security Agency. Copyright 1994-2000 retained by the original 17a8fe65b8SJeff Kirsher author, Donald Becker. The timer-based reset code was supplied in 1995 18a8fe65b8SJeff Kirsher by Bill Carlson, wwc@super.org. 19a8fe65b8SJeff Kirsher 20a8fe65b8SJeff Kirsher The author may be reached as becker@scyld.com, or C/O 21a8fe65b8SJeff Kirsher Scyld Computing Corporation 22a8fe65b8SJeff Kirsher 410 Severn Ave., Suite 210 23a8fe65b8SJeff Kirsher Annapolis MD 21403 24a8fe65b8SJeff Kirsher 25a8fe65b8SJeff Kirsher Support information and updates available at 26a8fe65b8SJeff Kirsher http://www.scyld.com/network/atp.html 27a8fe65b8SJeff Kirsher 28a8fe65b8SJeff Kirsher 29a8fe65b8SJeff Kirsher Modular support/softnet added by Alan Cox. 30a8fe65b8SJeff Kirsher _bit abuse fixed up by Alan Cox 31a8fe65b8SJeff Kirsher 32a8fe65b8SJeff Kirsher */ 33a8fe65b8SJeff Kirsher 34a8fe65b8SJeff Kirsher static const char version[] = 35a8fe65b8SJeff Kirsher "atp.c:v1.09=ac 2002/10/01 Donald Becker <becker@scyld.com>\n"; 36a8fe65b8SJeff Kirsher 37a8fe65b8SJeff Kirsher /* The user-configurable values. 38a8fe65b8SJeff Kirsher These may be modified when a driver module is loaded.*/ 39a8fe65b8SJeff Kirsher 40a8fe65b8SJeff Kirsher static int debug = 1; /* 1 normal messages, 0 quiet .. 7 verbose. */ 41a8fe65b8SJeff Kirsher #define net_debug debug 42a8fe65b8SJeff Kirsher 43a8fe65b8SJeff Kirsher /* Maximum events (Rx packets, etc.) to handle at each interrupt. */ 44a8fe65b8SJeff Kirsher static int max_interrupt_work = 15; 45a8fe65b8SJeff Kirsher 46a8fe65b8SJeff Kirsher #define NUM_UNITS 2 47a8fe65b8SJeff Kirsher /* The standard set of ISA module parameters. */ 48a8fe65b8SJeff Kirsher static int io[NUM_UNITS]; 49a8fe65b8SJeff Kirsher static int irq[NUM_UNITS]; 50a8fe65b8SJeff Kirsher static int xcvr[NUM_UNITS]; /* The data transfer mode. */ 51a8fe65b8SJeff Kirsher 52a8fe65b8SJeff Kirsher /* Operational parameters that are set at compile time. */ 53a8fe65b8SJeff Kirsher 54a8fe65b8SJeff Kirsher /* Time in jiffies before concluding the transmitter is hung. */ 55a8fe65b8SJeff Kirsher #define TX_TIMEOUT (400*HZ/1000) 56a8fe65b8SJeff Kirsher 57a8fe65b8SJeff Kirsher /* 58a8fe65b8SJeff Kirsher This file is a device driver for the RealTek (aka AT-Lan-Tec) pocket 59a8fe65b8SJeff Kirsher ethernet adapter. This is a common low-cost OEM pocket ethernet 60a8fe65b8SJeff Kirsher adapter, sold under many names. 61a8fe65b8SJeff Kirsher 62a8fe65b8SJeff Kirsher Sources: 63a8fe65b8SJeff Kirsher This driver was written from the packet driver assembly code provided by 64a8fe65b8SJeff Kirsher Vincent Bono of AT-Lan-Tec. Ever try to figure out how a complicated 65a8fe65b8SJeff Kirsher device works just from the assembly code? It ain't pretty. The following 66a8fe65b8SJeff Kirsher description is written based on guesses and writing lots of special-purpose 67a8fe65b8SJeff Kirsher code to test my theorized operation. 68a8fe65b8SJeff Kirsher 69a8fe65b8SJeff Kirsher In 1997 Realtek made available the documentation for the second generation 70a8fe65b8SJeff Kirsher RTL8012 chip, which has lead to several driver improvements. 71a8fe65b8SJeff Kirsher http://www.realtek.com.tw/ 72a8fe65b8SJeff Kirsher 73a8fe65b8SJeff Kirsher Theory of Operation 74a8fe65b8SJeff Kirsher 75a8fe65b8SJeff Kirsher The RTL8002 adapter seems to be built around a custom spin of the SEEQ 76a8fe65b8SJeff Kirsher controller core. It probably has a 16K or 64K internal packet buffer, of 77a8fe65b8SJeff Kirsher which the first 4K is devoted to transmit and the rest to receive. 78a8fe65b8SJeff Kirsher The controller maintains the queue of received packet and the packet buffer 79a8fe65b8SJeff Kirsher access pointer internally, with only 'reset to beginning' and 'skip to next 80a8fe65b8SJeff Kirsher packet' commands visible. The transmit packet queue holds two (or more?) 81a8fe65b8SJeff Kirsher packets: both 'retransmit this packet' (due to collision) and 'transmit next 82a8fe65b8SJeff Kirsher packet' commands must be started by hand. 83a8fe65b8SJeff Kirsher 84a8fe65b8SJeff Kirsher The station address is stored in a standard bit-serial EEPROM which must be 85a8fe65b8SJeff Kirsher read (ughh) by the device driver. (Provisions have been made for 86a8fe65b8SJeff Kirsher substituting a 74S288 PROM, but I haven't gotten reports of any models 87a8fe65b8SJeff Kirsher using it.) Unlike built-in devices, a pocket adapter can temporarily lose 88a8fe65b8SJeff Kirsher power without indication to the device driver. The major effect is that 89a8fe65b8SJeff Kirsher the station address, receive filter (promiscuous, etc.) and transceiver 90a8fe65b8SJeff Kirsher must be reset. 91a8fe65b8SJeff Kirsher 92a8fe65b8SJeff Kirsher The controller itself has 16 registers, some of which use only the lower 93a8fe65b8SJeff Kirsher bits. The registers are read and written 4 bits at a time. The four bit 94a8fe65b8SJeff Kirsher register address is presented on the data lines along with a few additional 95a8fe65b8SJeff Kirsher timing and control bits. The data is then read from status port or written 96a8fe65b8SJeff Kirsher to the data port. 97a8fe65b8SJeff Kirsher 98a8fe65b8SJeff Kirsher Correction: the controller has two banks of 16 registers. The second 99a8fe65b8SJeff Kirsher bank contains only the multicast filter table (now used) and the EEPROM 100a8fe65b8SJeff Kirsher access registers. 101a8fe65b8SJeff Kirsher 102a8fe65b8SJeff Kirsher Since the bulk data transfer of the actual packets through the slow 103a8fe65b8SJeff Kirsher parallel port dominates the driver's running time, four distinct data 104a8fe65b8SJeff Kirsher (non-register) transfer modes are provided by the adapter, two in each 105a8fe65b8SJeff Kirsher direction. In the first mode timing for the nibble transfers is 106a8fe65b8SJeff Kirsher provided through the data port. In the second mode the same timing is 107a8fe65b8SJeff Kirsher provided through the control port. In either case the data is read from 108a8fe65b8SJeff Kirsher the status port and written to the data port, just as it is accessing 109a8fe65b8SJeff Kirsher registers. 110a8fe65b8SJeff Kirsher 111a8fe65b8SJeff Kirsher In addition to the basic data transfer methods, several more are modes are 112a8fe65b8SJeff Kirsher created by adding some delay by doing multiple reads of the data to allow 113a8fe65b8SJeff Kirsher it to stabilize. This delay seems to be needed on most machines. 114a8fe65b8SJeff Kirsher 115a8fe65b8SJeff Kirsher The data transfer mode is stored in the 'dev->if_port' field. Its default 116a8fe65b8SJeff Kirsher value is '4'. It may be overridden at boot-time using the third parameter 117a8fe65b8SJeff Kirsher to the "ether=..." initialization. 118a8fe65b8SJeff Kirsher 119a8fe65b8SJeff Kirsher The header file <atp.h> provides inline functions that encapsulate the 120a8fe65b8SJeff Kirsher register and data access methods. These functions are hand-tuned to 121a8fe65b8SJeff Kirsher generate reasonable object code. This header file also documents my 122a8fe65b8SJeff Kirsher interpretations of the device registers. 123a8fe65b8SJeff Kirsher */ 124a8fe65b8SJeff Kirsher 125a8fe65b8SJeff Kirsher #include <linux/kernel.h> 126a8fe65b8SJeff Kirsher #include <linux/module.h> 127a8fe65b8SJeff Kirsher #include <linux/types.h> 128a8fe65b8SJeff Kirsher #include <linux/fcntl.h> 129a8fe65b8SJeff Kirsher #include <linux/interrupt.h> 130a8fe65b8SJeff Kirsher #include <linux/ioport.h> 131a8fe65b8SJeff Kirsher #include <linux/in.h> 132a8fe65b8SJeff Kirsher #include <linux/string.h> 133a8fe65b8SJeff Kirsher #include <linux/errno.h> 134a8fe65b8SJeff Kirsher #include <linux/init.h> 135a8fe65b8SJeff Kirsher #include <linux/crc32.h> 136a8fe65b8SJeff Kirsher #include <linux/netdevice.h> 137a8fe65b8SJeff Kirsher #include <linux/etherdevice.h> 138a8fe65b8SJeff Kirsher #include <linux/skbuff.h> 139a8fe65b8SJeff Kirsher #include <linux/spinlock.h> 140a8fe65b8SJeff Kirsher #include <linux/delay.h> 141a8fe65b8SJeff Kirsher #include <linux/bitops.h> 142a8fe65b8SJeff Kirsher 143a8fe65b8SJeff Kirsher #include <asm/system.h> 144a8fe65b8SJeff Kirsher #include <asm/io.h> 145a8fe65b8SJeff Kirsher #include <asm/dma.h> 146a8fe65b8SJeff Kirsher 147a8fe65b8SJeff Kirsher #include "atp.h" 148a8fe65b8SJeff Kirsher 149a8fe65b8SJeff Kirsher MODULE_AUTHOR("Donald Becker <becker@scyld.com>"); 150a8fe65b8SJeff Kirsher MODULE_DESCRIPTION("RealTek RTL8002/8012 parallel port Ethernet driver"); 151a8fe65b8SJeff Kirsher MODULE_LICENSE("GPL"); 152a8fe65b8SJeff Kirsher 153a8fe65b8SJeff Kirsher module_param(max_interrupt_work, int, 0); 154a8fe65b8SJeff Kirsher module_param(debug, int, 0); 155a8fe65b8SJeff Kirsher module_param_array(io, int, NULL, 0); 156a8fe65b8SJeff Kirsher module_param_array(irq, int, NULL, 0); 157a8fe65b8SJeff Kirsher module_param_array(xcvr, int, NULL, 0); 158a8fe65b8SJeff Kirsher MODULE_PARM_DESC(max_interrupt_work, "ATP maximum events handled per interrupt"); 159a8fe65b8SJeff Kirsher MODULE_PARM_DESC(debug, "ATP debug level (0-7)"); 160a8fe65b8SJeff Kirsher MODULE_PARM_DESC(io, "ATP I/O base address(es)"); 161a8fe65b8SJeff Kirsher MODULE_PARM_DESC(irq, "ATP IRQ number(s)"); 162a8fe65b8SJeff Kirsher MODULE_PARM_DESC(xcvr, "ATP transceiver(s) (0=internal, 1=external)"); 163a8fe65b8SJeff Kirsher 164a8fe65b8SJeff Kirsher /* The number of low I/O ports used by the ethercard. */ 165a8fe65b8SJeff Kirsher #define ETHERCARD_TOTAL_SIZE 3 166a8fe65b8SJeff Kirsher 167a8fe65b8SJeff Kirsher /* Sequence to switch an 8012 from printer mux to ethernet mode. */ 168a8fe65b8SJeff Kirsher static char mux_8012[] = { 0xff, 0xf7, 0xff, 0xfb, 0xf3, 0xfb, 0xff, 0xf7,}; 169a8fe65b8SJeff Kirsher 170a8fe65b8SJeff Kirsher struct net_local { 171a8fe65b8SJeff Kirsher spinlock_t lock; 172a8fe65b8SJeff Kirsher struct net_device *next_module; 173a8fe65b8SJeff Kirsher struct timer_list timer; /* Media selection timer. */ 174a8fe65b8SJeff Kirsher long last_rx_time; /* Last Rx, in jiffies, to handle Rx hang. */ 175a8fe65b8SJeff Kirsher int saved_tx_size; 176a8fe65b8SJeff Kirsher unsigned int tx_unit_busy:1; 177a8fe65b8SJeff Kirsher unsigned char re_tx, /* Number of packet retransmissions. */ 178a8fe65b8SJeff Kirsher addr_mode, /* Current Rx filter e.g. promiscuous, etc. */ 179a8fe65b8SJeff Kirsher pac_cnt_in_tx_buf, 180a8fe65b8SJeff Kirsher chip_type; 181a8fe65b8SJeff Kirsher }; 182a8fe65b8SJeff Kirsher 183a8fe65b8SJeff Kirsher /* This code, written by wwc@super.org, resets the adapter every 184a8fe65b8SJeff Kirsher TIMED_CHECKER ticks. This recovers from an unknown error which 185a8fe65b8SJeff Kirsher hangs the device. */ 186a8fe65b8SJeff Kirsher #define TIMED_CHECKER (HZ/4) 187a8fe65b8SJeff Kirsher #ifdef TIMED_CHECKER 188a8fe65b8SJeff Kirsher #include <linux/timer.h> 189a8fe65b8SJeff Kirsher static void atp_timed_checker(unsigned long ignored); 190a8fe65b8SJeff Kirsher #endif 191a8fe65b8SJeff Kirsher 192a8fe65b8SJeff Kirsher /* Index to functions, as function prototypes. */ 193a8fe65b8SJeff Kirsher 194a8fe65b8SJeff Kirsher static int atp_probe1(long ioaddr); 195a8fe65b8SJeff Kirsher static void get_node_ID(struct net_device *dev); 196a8fe65b8SJeff Kirsher static unsigned short eeprom_op(long ioaddr, unsigned int cmd); 197a8fe65b8SJeff Kirsher static int net_open(struct net_device *dev); 198a8fe65b8SJeff Kirsher static void hardware_init(struct net_device *dev); 199a8fe65b8SJeff Kirsher static void write_packet(long ioaddr, int length, unsigned char *packet, int pad, int mode); 200a8fe65b8SJeff Kirsher static void trigger_send(long ioaddr, int length); 201a8fe65b8SJeff Kirsher static netdev_tx_t atp_send_packet(struct sk_buff *skb, 202a8fe65b8SJeff Kirsher struct net_device *dev); 203a8fe65b8SJeff Kirsher static irqreturn_t atp_interrupt(int irq, void *dev_id); 204a8fe65b8SJeff Kirsher static void net_rx(struct net_device *dev); 205a8fe65b8SJeff Kirsher static void read_block(long ioaddr, int length, unsigned char *buffer, int data_mode); 206a8fe65b8SJeff Kirsher static int net_close(struct net_device *dev); 207a8fe65b8SJeff Kirsher static void set_rx_mode(struct net_device *dev); 208a8fe65b8SJeff Kirsher static void tx_timeout(struct net_device *dev); 209a8fe65b8SJeff Kirsher 210a8fe65b8SJeff Kirsher 211a8fe65b8SJeff Kirsher /* A list of all installed ATP devices, for removing the driver module. */ 212a8fe65b8SJeff Kirsher static struct net_device *root_atp_dev; 213a8fe65b8SJeff Kirsher 214a8fe65b8SJeff Kirsher /* Check for a network adapter of this type, and return '0' iff one exists. 215a8fe65b8SJeff Kirsher If dev->base_addr == 0, probe all likely locations. 216a8fe65b8SJeff Kirsher If dev->base_addr == 1, always return failure. 217a8fe65b8SJeff Kirsher If dev->base_addr == 2, allocate space for the device and return success 218a8fe65b8SJeff Kirsher (detachable devices only). 219a8fe65b8SJeff Kirsher 220a8fe65b8SJeff Kirsher FIXME: we should use the parport layer for this 221a8fe65b8SJeff Kirsher */ 222a8fe65b8SJeff Kirsher static int __init atp_init(void) 223a8fe65b8SJeff Kirsher { 224a8fe65b8SJeff Kirsher int *port, ports[] = {0x378, 0x278, 0x3bc, 0}; 225a8fe65b8SJeff Kirsher int base_addr = io[0]; 226a8fe65b8SJeff Kirsher 227a8fe65b8SJeff Kirsher if (base_addr > 0x1ff) /* Check a single specified location. */ 228a8fe65b8SJeff Kirsher return atp_probe1(base_addr); 229a8fe65b8SJeff Kirsher else if (base_addr == 1) /* Don't probe at all. */ 230a8fe65b8SJeff Kirsher return -ENXIO; 231a8fe65b8SJeff Kirsher 232a8fe65b8SJeff Kirsher for (port = ports; *port; port++) { 233a8fe65b8SJeff Kirsher long ioaddr = *port; 234a8fe65b8SJeff Kirsher outb(0x57, ioaddr + PAR_DATA); 235a8fe65b8SJeff Kirsher if (inb(ioaddr + PAR_DATA) != 0x57) 236a8fe65b8SJeff Kirsher continue; 237a8fe65b8SJeff Kirsher if (atp_probe1(ioaddr) == 0) 238a8fe65b8SJeff Kirsher return 0; 239a8fe65b8SJeff Kirsher } 240a8fe65b8SJeff Kirsher 241a8fe65b8SJeff Kirsher return -ENODEV; 242a8fe65b8SJeff Kirsher } 243a8fe65b8SJeff Kirsher 244a8fe65b8SJeff Kirsher static const struct net_device_ops atp_netdev_ops = { 245a8fe65b8SJeff Kirsher .ndo_open = net_open, 246a8fe65b8SJeff Kirsher .ndo_stop = net_close, 247a8fe65b8SJeff Kirsher .ndo_start_xmit = atp_send_packet, 248a8fe65b8SJeff Kirsher .ndo_set_multicast_list = set_rx_mode, 249a8fe65b8SJeff Kirsher .ndo_tx_timeout = tx_timeout, 250a8fe65b8SJeff Kirsher .ndo_change_mtu = eth_change_mtu, 251a8fe65b8SJeff Kirsher .ndo_set_mac_address = eth_mac_addr, 252a8fe65b8SJeff Kirsher .ndo_validate_addr = eth_validate_addr, 253a8fe65b8SJeff Kirsher }; 254a8fe65b8SJeff Kirsher 255a8fe65b8SJeff Kirsher static int __init atp_probe1(long ioaddr) 256a8fe65b8SJeff Kirsher { 257a8fe65b8SJeff Kirsher struct net_device *dev = NULL; 258a8fe65b8SJeff Kirsher struct net_local *lp; 259a8fe65b8SJeff Kirsher int saved_ctrl_reg, status, i; 260a8fe65b8SJeff Kirsher int res; 261a8fe65b8SJeff Kirsher 262a8fe65b8SJeff Kirsher outb(0xff, ioaddr + PAR_DATA); 263a8fe65b8SJeff Kirsher /* Save the original value of the Control register, in case we guessed 264a8fe65b8SJeff Kirsher wrong. */ 265a8fe65b8SJeff Kirsher saved_ctrl_reg = inb(ioaddr + PAR_CONTROL); 266a8fe65b8SJeff Kirsher if (net_debug > 3) 267a8fe65b8SJeff Kirsher printk("atp: Control register was %#2.2x.\n", saved_ctrl_reg); 268a8fe65b8SJeff Kirsher /* IRQEN=0, SLCTB=high INITB=high, AUTOFDB=high, STBB=high. */ 269a8fe65b8SJeff Kirsher outb(0x04, ioaddr + PAR_CONTROL); 270a8fe65b8SJeff Kirsher #ifndef final_version 271a8fe65b8SJeff Kirsher if (net_debug > 3) { 272a8fe65b8SJeff Kirsher /* Turn off the printer multiplexer on the 8012. */ 273a8fe65b8SJeff Kirsher for (i = 0; i < 8; i++) 274a8fe65b8SJeff Kirsher outb(mux_8012[i], ioaddr + PAR_DATA); 275a8fe65b8SJeff Kirsher write_reg(ioaddr, MODSEL, 0x00); 276a8fe65b8SJeff Kirsher printk("atp: Registers are "); 277a8fe65b8SJeff Kirsher for (i = 0; i < 32; i++) 278a8fe65b8SJeff Kirsher printk(" %2.2x", read_nibble(ioaddr, i)); 279a8fe65b8SJeff Kirsher printk(".\n"); 280a8fe65b8SJeff Kirsher } 281a8fe65b8SJeff Kirsher #endif 282a8fe65b8SJeff Kirsher /* Turn off the printer multiplexer on the 8012. */ 283a8fe65b8SJeff Kirsher for (i = 0; i < 8; i++) 284a8fe65b8SJeff Kirsher outb(mux_8012[i], ioaddr + PAR_DATA); 285a8fe65b8SJeff Kirsher write_reg_high(ioaddr, CMR1, CMR1h_RESET); 286a8fe65b8SJeff Kirsher /* udelay() here? */ 287a8fe65b8SJeff Kirsher status = read_nibble(ioaddr, CMR1); 288a8fe65b8SJeff Kirsher 289a8fe65b8SJeff Kirsher if (net_debug > 3) { 290a8fe65b8SJeff Kirsher printk(KERN_DEBUG "atp: Status nibble was %#2.2x..", status); 291a8fe65b8SJeff Kirsher for (i = 0; i < 32; i++) 292a8fe65b8SJeff Kirsher printk(" %2.2x", read_nibble(ioaddr, i)); 293a8fe65b8SJeff Kirsher printk("\n"); 294a8fe65b8SJeff Kirsher } 295a8fe65b8SJeff Kirsher 296a8fe65b8SJeff Kirsher if ((status & 0x78) != 0x08) { 297a8fe65b8SJeff Kirsher /* The pocket adapter probe failed, restore the control register. */ 298a8fe65b8SJeff Kirsher outb(saved_ctrl_reg, ioaddr + PAR_CONTROL); 299a8fe65b8SJeff Kirsher return -ENODEV; 300a8fe65b8SJeff Kirsher } 301a8fe65b8SJeff Kirsher status = read_nibble(ioaddr, CMR2_h); 302a8fe65b8SJeff Kirsher if ((status & 0x78) != 0x10) { 303a8fe65b8SJeff Kirsher outb(saved_ctrl_reg, ioaddr + PAR_CONTROL); 304a8fe65b8SJeff Kirsher return -ENODEV; 305a8fe65b8SJeff Kirsher } 306a8fe65b8SJeff Kirsher 307a8fe65b8SJeff Kirsher dev = alloc_etherdev(sizeof(struct net_local)); 308a8fe65b8SJeff Kirsher if (!dev) 309a8fe65b8SJeff Kirsher return -ENOMEM; 310a8fe65b8SJeff Kirsher 311a8fe65b8SJeff Kirsher /* Find the IRQ used by triggering an interrupt. */ 312a8fe65b8SJeff Kirsher write_reg_byte(ioaddr, CMR2, 0x01); /* No accept mode, IRQ out. */ 313a8fe65b8SJeff Kirsher write_reg_high(ioaddr, CMR1, CMR1h_RxENABLE | CMR1h_TxENABLE); /* Enable Tx and Rx. */ 314a8fe65b8SJeff Kirsher 315a8fe65b8SJeff Kirsher /* Omit autoIRQ routine for now. Use "table lookup" instead. Uhgggh. */ 316a8fe65b8SJeff Kirsher if (irq[0]) 317a8fe65b8SJeff Kirsher dev->irq = irq[0]; 318a8fe65b8SJeff Kirsher else if (ioaddr == 0x378) 319a8fe65b8SJeff Kirsher dev->irq = 7; 320a8fe65b8SJeff Kirsher else 321a8fe65b8SJeff Kirsher dev->irq = 5; 322a8fe65b8SJeff Kirsher write_reg_high(ioaddr, CMR1, CMR1h_TxRxOFF); /* Disable Tx and Rx units. */ 323a8fe65b8SJeff Kirsher write_reg(ioaddr, CMR2, CMR2_NULL); 324a8fe65b8SJeff Kirsher 325a8fe65b8SJeff Kirsher dev->base_addr = ioaddr; 326a8fe65b8SJeff Kirsher 327a8fe65b8SJeff Kirsher /* Read the station address PROM. */ 328a8fe65b8SJeff Kirsher get_node_ID(dev); 329a8fe65b8SJeff Kirsher 330a8fe65b8SJeff Kirsher #ifndef MODULE 331a8fe65b8SJeff Kirsher if (net_debug) 332a8fe65b8SJeff Kirsher printk(KERN_INFO "%s", version); 333a8fe65b8SJeff Kirsher #endif 334a8fe65b8SJeff Kirsher 335a8fe65b8SJeff Kirsher printk(KERN_NOTICE "%s: Pocket adapter found at %#3lx, IRQ %d, " 336a8fe65b8SJeff Kirsher "SAPROM %pM.\n", 337a8fe65b8SJeff Kirsher dev->name, dev->base_addr, dev->irq, dev->dev_addr); 338a8fe65b8SJeff Kirsher 339a8fe65b8SJeff Kirsher /* Reset the ethernet hardware and activate the printer pass-through. */ 340a8fe65b8SJeff Kirsher write_reg_high(ioaddr, CMR1, CMR1h_RESET | CMR1h_MUX); 341a8fe65b8SJeff Kirsher 342a8fe65b8SJeff Kirsher lp = netdev_priv(dev); 343a8fe65b8SJeff Kirsher lp->chip_type = RTL8002; 344a8fe65b8SJeff Kirsher lp->addr_mode = CMR2h_Normal; 345a8fe65b8SJeff Kirsher spin_lock_init(&lp->lock); 346a8fe65b8SJeff Kirsher 347a8fe65b8SJeff Kirsher /* For the ATP adapter the "if_port" is really the data transfer mode. */ 348a8fe65b8SJeff Kirsher if (xcvr[0]) 349a8fe65b8SJeff Kirsher dev->if_port = xcvr[0]; 350a8fe65b8SJeff Kirsher else 351a8fe65b8SJeff Kirsher dev->if_port = (dev->mem_start & 0xf) ? (dev->mem_start & 0x7) : 4; 352a8fe65b8SJeff Kirsher if (dev->mem_end & 0xf) 353a8fe65b8SJeff Kirsher net_debug = dev->mem_end & 7; 354a8fe65b8SJeff Kirsher 355a8fe65b8SJeff Kirsher dev->netdev_ops = &atp_netdev_ops; 356a8fe65b8SJeff Kirsher dev->watchdog_timeo = TX_TIMEOUT; 357a8fe65b8SJeff Kirsher 358a8fe65b8SJeff Kirsher res = register_netdev(dev); 359a8fe65b8SJeff Kirsher if (res) { 360a8fe65b8SJeff Kirsher free_netdev(dev); 361a8fe65b8SJeff Kirsher return res; 362a8fe65b8SJeff Kirsher } 363a8fe65b8SJeff Kirsher 364a8fe65b8SJeff Kirsher lp->next_module = root_atp_dev; 365a8fe65b8SJeff Kirsher root_atp_dev = dev; 366a8fe65b8SJeff Kirsher 367a8fe65b8SJeff Kirsher return 0; 368a8fe65b8SJeff Kirsher } 369a8fe65b8SJeff Kirsher 370a8fe65b8SJeff Kirsher /* Read the station address PROM, usually a word-wide EEPROM. */ 371a8fe65b8SJeff Kirsher static void __init get_node_ID(struct net_device *dev) 372a8fe65b8SJeff Kirsher { 373a8fe65b8SJeff Kirsher long ioaddr = dev->base_addr; 374a8fe65b8SJeff Kirsher int sa_offset = 0; 375a8fe65b8SJeff Kirsher int i; 376a8fe65b8SJeff Kirsher 377a8fe65b8SJeff Kirsher write_reg(ioaddr, CMR2, CMR2_EEPROM); /* Point to the EEPROM control registers. */ 378a8fe65b8SJeff Kirsher 379a8fe65b8SJeff Kirsher /* Some adapters have the station address at offset 15 instead of offset 380a8fe65b8SJeff Kirsher zero. Check for it, and fix it if needed. */ 381a8fe65b8SJeff Kirsher if (eeprom_op(ioaddr, EE_READ(0)) == 0xffff) 382a8fe65b8SJeff Kirsher sa_offset = 15; 383a8fe65b8SJeff Kirsher 384a8fe65b8SJeff Kirsher for (i = 0; i < 3; i++) 385a8fe65b8SJeff Kirsher ((__be16 *)dev->dev_addr)[i] = 386a8fe65b8SJeff Kirsher cpu_to_be16(eeprom_op(ioaddr, EE_READ(sa_offset + i))); 387a8fe65b8SJeff Kirsher 388a8fe65b8SJeff Kirsher write_reg(ioaddr, CMR2, CMR2_NULL); 389a8fe65b8SJeff Kirsher } 390a8fe65b8SJeff Kirsher 391a8fe65b8SJeff Kirsher /* 392a8fe65b8SJeff Kirsher An EEPROM read command starts by shifting out 0x60+address, and then 393a8fe65b8SJeff Kirsher shifting in the serial data. See the NatSemi databook for details. 394a8fe65b8SJeff Kirsher * ________________ 395a8fe65b8SJeff Kirsher * CS : __| 396a8fe65b8SJeff Kirsher * ___ ___ 397a8fe65b8SJeff Kirsher * CLK: ______| |___| | 398a8fe65b8SJeff Kirsher * __ _______ _______ 399a8fe65b8SJeff Kirsher * DI : __X_______X_______X 400a8fe65b8SJeff Kirsher * DO : _________X_______X 401a8fe65b8SJeff Kirsher */ 402a8fe65b8SJeff Kirsher 403a8fe65b8SJeff Kirsher static unsigned short __init eeprom_op(long ioaddr, u32 cmd) 404a8fe65b8SJeff Kirsher { 405a8fe65b8SJeff Kirsher unsigned eedata_out = 0; 406a8fe65b8SJeff Kirsher int num_bits = EE_CMD_SIZE; 407a8fe65b8SJeff Kirsher 408a8fe65b8SJeff Kirsher while (--num_bits >= 0) { 409a8fe65b8SJeff Kirsher char outval = (cmd & (1<<num_bits)) ? EE_DATA_WRITE : 0; 410a8fe65b8SJeff Kirsher write_reg_high(ioaddr, PROM_CMD, outval | EE_CLK_LOW); 411a8fe65b8SJeff Kirsher write_reg_high(ioaddr, PROM_CMD, outval | EE_CLK_HIGH); 412a8fe65b8SJeff Kirsher eedata_out <<= 1; 413a8fe65b8SJeff Kirsher if (read_nibble(ioaddr, PROM_DATA) & EE_DATA_READ) 414a8fe65b8SJeff Kirsher eedata_out++; 415a8fe65b8SJeff Kirsher } 416a8fe65b8SJeff Kirsher write_reg_high(ioaddr, PROM_CMD, EE_CLK_LOW & ~EE_CS); 417a8fe65b8SJeff Kirsher return eedata_out; 418a8fe65b8SJeff Kirsher } 419a8fe65b8SJeff Kirsher 420a8fe65b8SJeff Kirsher 421a8fe65b8SJeff Kirsher /* Open/initialize the board. This is called (in the current kernel) 422a8fe65b8SJeff Kirsher sometime after booting when the 'ifconfig' program is run. 423a8fe65b8SJeff Kirsher 424a8fe65b8SJeff Kirsher This routine sets everything up anew at each open, even 425a8fe65b8SJeff Kirsher registers that "should" only need to be set once at boot, so that 426a8fe65b8SJeff Kirsher there is non-reboot way to recover if something goes wrong. 427a8fe65b8SJeff Kirsher 428a8fe65b8SJeff Kirsher This is an attachable device: if there is no private entry then it wasn't 429a8fe65b8SJeff Kirsher probed for at boot-time, and we need to probe for it again. 430a8fe65b8SJeff Kirsher */ 431a8fe65b8SJeff Kirsher static int net_open(struct net_device *dev) 432a8fe65b8SJeff Kirsher { 433a8fe65b8SJeff Kirsher struct net_local *lp = netdev_priv(dev); 434a8fe65b8SJeff Kirsher int ret; 435a8fe65b8SJeff Kirsher 436a8fe65b8SJeff Kirsher /* The interrupt line is turned off (tri-stated) when the device isn't in 437a8fe65b8SJeff Kirsher use. That's especially important for "attached" interfaces where the 438a8fe65b8SJeff Kirsher port or interrupt may be shared. */ 439a8fe65b8SJeff Kirsher ret = request_irq(dev->irq, atp_interrupt, 0, dev->name, dev); 440a8fe65b8SJeff Kirsher if (ret) 441a8fe65b8SJeff Kirsher return ret; 442a8fe65b8SJeff Kirsher 443a8fe65b8SJeff Kirsher hardware_init(dev); 444a8fe65b8SJeff Kirsher 445a8fe65b8SJeff Kirsher init_timer(&lp->timer); 446a8fe65b8SJeff Kirsher lp->timer.expires = jiffies + TIMED_CHECKER; 447a8fe65b8SJeff Kirsher lp->timer.data = (unsigned long)dev; 448a8fe65b8SJeff Kirsher lp->timer.function = atp_timed_checker; /* timer handler */ 449a8fe65b8SJeff Kirsher add_timer(&lp->timer); 450a8fe65b8SJeff Kirsher 451a8fe65b8SJeff Kirsher netif_start_queue(dev); 452a8fe65b8SJeff Kirsher return 0; 453a8fe65b8SJeff Kirsher } 454a8fe65b8SJeff Kirsher 455a8fe65b8SJeff Kirsher /* This routine resets the hardware. We initialize everything, assuming that 456a8fe65b8SJeff Kirsher the hardware may have been temporarily detached. */ 457a8fe65b8SJeff Kirsher static void hardware_init(struct net_device *dev) 458a8fe65b8SJeff Kirsher { 459a8fe65b8SJeff Kirsher struct net_local *lp = netdev_priv(dev); 460a8fe65b8SJeff Kirsher long ioaddr = dev->base_addr; 461a8fe65b8SJeff Kirsher int i; 462a8fe65b8SJeff Kirsher 463a8fe65b8SJeff Kirsher /* Turn off the printer multiplexer on the 8012. */ 464a8fe65b8SJeff Kirsher for (i = 0; i < 8; i++) 465a8fe65b8SJeff Kirsher outb(mux_8012[i], ioaddr + PAR_DATA); 466a8fe65b8SJeff Kirsher write_reg_high(ioaddr, CMR1, CMR1h_RESET); 467a8fe65b8SJeff Kirsher 468a8fe65b8SJeff Kirsher for (i = 0; i < 6; i++) 469a8fe65b8SJeff Kirsher write_reg_byte(ioaddr, PAR0 + i, dev->dev_addr[i]); 470a8fe65b8SJeff Kirsher 471a8fe65b8SJeff Kirsher write_reg_high(ioaddr, CMR2, lp->addr_mode); 472a8fe65b8SJeff Kirsher 473a8fe65b8SJeff Kirsher if (net_debug > 2) { 474a8fe65b8SJeff Kirsher printk(KERN_DEBUG "%s: Reset: current Rx mode %d.\n", dev->name, 475a8fe65b8SJeff Kirsher (read_nibble(ioaddr, CMR2_h) >> 3) & 0x0f); 476a8fe65b8SJeff Kirsher } 477a8fe65b8SJeff Kirsher 478a8fe65b8SJeff Kirsher write_reg(ioaddr, CMR2, CMR2_IRQOUT); 479a8fe65b8SJeff Kirsher write_reg_high(ioaddr, CMR1, CMR1h_RxENABLE | CMR1h_TxENABLE); 480a8fe65b8SJeff Kirsher 481a8fe65b8SJeff Kirsher /* Enable the interrupt line from the serial port. */ 482a8fe65b8SJeff Kirsher outb(Ctrl_SelData + Ctrl_IRQEN, ioaddr + PAR_CONTROL); 483a8fe65b8SJeff Kirsher 484a8fe65b8SJeff Kirsher /* Unmask the interesting interrupts. */ 485a8fe65b8SJeff Kirsher write_reg(ioaddr, IMR, ISR_RxOK | ISR_TxErr | ISR_TxOK); 486a8fe65b8SJeff Kirsher write_reg_high(ioaddr, IMR, ISRh_RxErr); 487a8fe65b8SJeff Kirsher 488a8fe65b8SJeff Kirsher lp->tx_unit_busy = 0; 489a8fe65b8SJeff Kirsher lp->pac_cnt_in_tx_buf = 0; 490a8fe65b8SJeff Kirsher lp->saved_tx_size = 0; 491a8fe65b8SJeff Kirsher } 492a8fe65b8SJeff Kirsher 493a8fe65b8SJeff Kirsher static void trigger_send(long ioaddr, int length) 494a8fe65b8SJeff Kirsher { 495a8fe65b8SJeff Kirsher write_reg_byte(ioaddr, TxCNT0, length & 0xff); 496a8fe65b8SJeff Kirsher write_reg(ioaddr, TxCNT1, length >> 8); 497a8fe65b8SJeff Kirsher write_reg(ioaddr, CMR1, CMR1_Xmit); 498a8fe65b8SJeff Kirsher } 499a8fe65b8SJeff Kirsher 500a8fe65b8SJeff Kirsher static void write_packet(long ioaddr, int length, unsigned char *packet, int pad_len, int data_mode) 501a8fe65b8SJeff Kirsher { 502a8fe65b8SJeff Kirsher if (length & 1) 503a8fe65b8SJeff Kirsher { 504a8fe65b8SJeff Kirsher length++; 505a8fe65b8SJeff Kirsher pad_len++; 506a8fe65b8SJeff Kirsher } 507a8fe65b8SJeff Kirsher 508a8fe65b8SJeff Kirsher outb(EOC+MAR, ioaddr + PAR_DATA); 509a8fe65b8SJeff Kirsher if ((data_mode & 1) == 0) { 510a8fe65b8SJeff Kirsher /* Write the packet out, starting with the write addr. */ 511a8fe65b8SJeff Kirsher outb(WrAddr+MAR, ioaddr + PAR_DATA); 512a8fe65b8SJeff Kirsher do { 513a8fe65b8SJeff Kirsher write_byte_mode0(ioaddr, *packet++); 514a8fe65b8SJeff Kirsher } while (--length > pad_len) ; 515a8fe65b8SJeff Kirsher do { 516a8fe65b8SJeff Kirsher write_byte_mode0(ioaddr, 0); 517a8fe65b8SJeff Kirsher } while (--length > 0) ; 518a8fe65b8SJeff Kirsher } else { 519a8fe65b8SJeff Kirsher /* Write the packet out in slow mode. */ 520a8fe65b8SJeff Kirsher unsigned char outbyte = *packet++; 521a8fe65b8SJeff Kirsher 522a8fe65b8SJeff Kirsher outb(Ctrl_LNibWrite + Ctrl_IRQEN, ioaddr + PAR_CONTROL); 523a8fe65b8SJeff Kirsher outb(WrAddr+MAR, ioaddr + PAR_DATA); 524a8fe65b8SJeff Kirsher 525a8fe65b8SJeff Kirsher outb((outbyte & 0x0f)|0x40, ioaddr + PAR_DATA); 526a8fe65b8SJeff Kirsher outb(outbyte & 0x0f, ioaddr + PAR_DATA); 527a8fe65b8SJeff Kirsher outbyte >>= 4; 528a8fe65b8SJeff Kirsher outb(outbyte & 0x0f, ioaddr + PAR_DATA); 529a8fe65b8SJeff Kirsher outb(Ctrl_HNibWrite + Ctrl_IRQEN, ioaddr + PAR_CONTROL); 530a8fe65b8SJeff Kirsher while (--length > pad_len) 531a8fe65b8SJeff Kirsher write_byte_mode1(ioaddr, *packet++); 532a8fe65b8SJeff Kirsher while (--length > 0) 533a8fe65b8SJeff Kirsher write_byte_mode1(ioaddr, 0); 534a8fe65b8SJeff Kirsher } 535a8fe65b8SJeff Kirsher /* Terminate the Tx frame. End of write: ECB. */ 536a8fe65b8SJeff Kirsher outb(0xff, ioaddr + PAR_DATA); 537a8fe65b8SJeff Kirsher outb(Ctrl_HNibWrite | Ctrl_SelData | Ctrl_IRQEN, ioaddr + PAR_CONTROL); 538a8fe65b8SJeff Kirsher } 539a8fe65b8SJeff Kirsher 540a8fe65b8SJeff Kirsher static void tx_timeout(struct net_device *dev) 541a8fe65b8SJeff Kirsher { 542a8fe65b8SJeff Kirsher long ioaddr = dev->base_addr; 543a8fe65b8SJeff Kirsher 544a8fe65b8SJeff Kirsher printk(KERN_WARNING "%s: Transmit timed out, %s?\n", dev->name, 545a8fe65b8SJeff Kirsher inb(ioaddr + PAR_CONTROL) & 0x10 ? "network cable problem" 546a8fe65b8SJeff Kirsher : "IRQ conflict"); 547a8fe65b8SJeff Kirsher dev->stats.tx_errors++; 548a8fe65b8SJeff Kirsher /* Try to restart the adapter. */ 549a8fe65b8SJeff Kirsher hardware_init(dev); 550a8fe65b8SJeff Kirsher dev->trans_start = jiffies; /* prevent tx timeout */ 551a8fe65b8SJeff Kirsher netif_wake_queue(dev); 552a8fe65b8SJeff Kirsher dev->stats.tx_errors++; 553a8fe65b8SJeff Kirsher } 554a8fe65b8SJeff Kirsher 555a8fe65b8SJeff Kirsher static netdev_tx_t atp_send_packet(struct sk_buff *skb, 556a8fe65b8SJeff Kirsher struct net_device *dev) 557a8fe65b8SJeff Kirsher { 558a8fe65b8SJeff Kirsher struct net_local *lp = netdev_priv(dev); 559a8fe65b8SJeff Kirsher long ioaddr = dev->base_addr; 560a8fe65b8SJeff Kirsher int length; 561a8fe65b8SJeff Kirsher unsigned long flags; 562a8fe65b8SJeff Kirsher 563a8fe65b8SJeff Kirsher length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; 564a8fe65b8SJeff Kirsher 565a8fe65b8SJeff Kirsher netif_stop_queue(dev); 566a8fe65b8SJeff Kirsher 567a8fe65b8SJeff Kirsher /* Disable interrupts by writing 0x00 to the Interrupt Mask Register. 568a8fe65b8SJeff Kirsher This sequence must not be interrupted by an incoming packet. */ 569a8fe65b8SJeff Kirsher 570a8fe65b8SJeff Kirsher spin_lock_irqsave(&lp->lock, flags); 571a8fe65b8SJeff Kirsher write_reg(ioaddr, IMR, 0); 572a8fe65b8SJeff Kirsher write_reg_high(ioaddr, IMR, 0); 573a8fe65b8SJeff Kirsher spin_unlock_irqrestore(&lp->lock, flags); 574a8fe65b8SJeff Kirsher 575a8fe65b8SJeff Kirsher write_packet(ioaddr, length, skb->data, length-skb->len, dev->if_port); 576a8fe65b8SJeff Kirsher 577a8fe65b8SJeff Kirsher lp->pac_cnt_in_tx_buf++; 578a8fe65b8SJeff Kirsher if (lp->tx_unit_busy == 0) { 579a8fe65b8SJeff Kirsher trigger_send(ioaddr, length); 580a8fe65b8SJeff Kirsher lp->saved_tx_size = 0; /* Redundant */ 581a8fe65b8SJeff Kirsher lp->re_tx = 0; 582a8fe65b8SJeff Kirsher lp->tx_unit_busy = 1; 583a8fe65b8SJeff Kirsher } else 584a8fe65b8SJeff Kirsher lp->saved_tx_size = length; 585a8fe65b8SJeff Kirsher /* Re-enable the LPT interrupts. */ 586a8fe65b8SJeff Kirsher write_reg(ioaddr, IMR, ISR_RxOK | ISR_TxErr | ISR_TxOK); 587a8fe65b8SJeff Kirsher write_reg_high(ioaddr, IMR, ISRh_RxErr); 588a8fe65b8SJeff Kirsher 589a8fe65b8SJeff Kirsher dev_kfree_skb (skb); 590a8fe65b8SJeff Kirsher return NETDEV_TX_OK; 591a8fe65b8SJeff Kirsher } 592a8fe65b8SJeff Kirsher 593a8fe65b8SJeff Kirsher 594a8fe65b8SJeff Kirsher /* The typical workload of the driver: 595a8fe65b8SJeff Kirsher Handle the network interface interrupts. */ 596a8fe65b8SJeff Kirsher static irqreturn_t atp_interrupt(int irq, void *dev_instance) 597a8fe65b8SJeff Kirsher { 598a8fe65b8SJeff Kirsher struct net_device *dev = dev_instance; 599a8fe65b8SJeff Kirsher struct net_local *lp; 600a8fe65b8SJeff Kirsher long ioaddr; 601a8fe65b8SJeff Kirsher static int num_tx_since_rx; 602a8fe65b8SJeff Kirsher int boguscount = max_interrupt_work; 603a8fe65b8SJeff Kirsher int handled = 0; 604a8fe65b8SJeff Kirsher 605a8fe65b8SJeff Kirsher ioaddr = dev->base_addr; 606a8fe65b8SJeff Kirsher lp = netdev_priv(dev); 607a8fe65b8SJeff Kirsher 608a8fe65b8SJeff Kirsher spin_lock(&lp->lock); 609a8fe65b8SJeff Kirsher 610a8fe65b8SJeff Kirsher /* Disable additional spurious interrupts. */ 611a8fe65b8SJeff Kirsher outb(Ctrl_SelData, ioaddr + PAR_CONTROL); 612a8fe65b8SJeff Kirsher 613a8fe65b8SJeff Kirsher /* The adapter's output is currently the IRQ line, switch it to data. */ 614a8fe65b8SJeff Kirsher write_reg(ioaddr, CMR2, CMR2_NULL); 615a8fe65b8SJeff Kirsher write_reg(ioaddr, IMR, 0); 616a8fe65b8SJeff Kirsher 617a8fe65b8SJeff Kirsher if (net_debug > 5) printk(KERN_DEBUG "%s: In interrupt ", dev->name); 618a8fe65b8SJeff Kirsher while (--boguscount > 0) { 619a8fe65b8SJeff Kirsher int status = read_nibble(ioaddr, ISR); 620a8fe65b8SJeff Kirsher if (net_debug > 5) printk("loop status %02x..", status); 621a8fe65b8SJeff Kirsher 622a8fe65b8SJeff Kirsher if (status & (ISR_RxOK<<3)) { 623a8fe65b8SJeff Kirsher handled = 1; 624a8fe65b8SJeff Kirsher write_reg(ioaddr, ISR, ISR_RxOK); /* Clear the Rx interrupt. */ 625a8fe65b8SJeff Kirsher do { 626a8fe65b8SJeff Kirsher int read_status = read_nibble(ioaddr, CMR1); 627a8fe65b8SJeff Kirsher if (net_debug > 6) 628a8fe65b8SJeff Kirsher printk("handling Rx packet %02x..", read_status); 629a8fe65b8SJeff Kirsher /* We acknowledged the normal Rx interrupt, so if the interrupt 630a8fe65b8SJeff Kirsher is still outstanding we must have a Rx error. */ 631a8fe65b8SJeff Kirsher if (read_status & (CMR1_IRQ << 3)) { /* Overrun. */ 632a8fe65b8SJeff Kirsher dev->stats.rx_over_errors++; 633a8fe65b8SJeff Kirsher /* Set to no-accept mode long enough to remove a packet. */ 634a8fe65b8SJeff Kirsher write_reg_high(ioaddr, CMR2, CMR2h_OFF); 635a8fe65b8SJeff Kirsher net_rx(dev); 636a8fe65b8SJeff Kirsher /* Clear the interrupt and return to normal Rx mode. */ 637a8fe65b8SJeff Kirsher write_reg_high(ioaddr, ISR, ISRh_RxErr); 638a8fe65b8SJeff Kirsher write_reg_high(ioaddr, CMR2, lp->addr_mode); 639a8fe65b8SJeff Kirsher } else if ((read_status & (CMR1_BufEnb << 3)) == 0) { 640a8fe65b8SJeff Kirsher net_rx(dev); 641a8fe65b8SJeff Kirsher num_tx_since_rx = 0; 642a8fe65b8SJeff Kirsher } else 643a8fe65b8SJeff Kirsher break; 644a8fe65b8SJeff Kirsher } while (--boguscount > 0); 645a8fe65b8SJeff Kirsher } else if (status & ((ISR_TxErr + ISR_TxOK)<<3)) { 646a8fe65b8SJeff Kirsher handled = 1; 647a8fe65b8SJeff Kirsher if (net_debug > 6) printk("handling Tx done.."); 648a8fe65b8SJeff Kirsher /* Clear the Tx interrupt. We should check for too many failures 649a8fe65b8SJeff Kirsher and reinitialize the adapter. */ 650a8fe65b8SJeff Kirsher write_reg(ioaddr, ISR, ISR_TxErr + ISR_TxOK); 651a8fe65b8SJeff Kirsher if (status & (ISR_TxErr<<3)) { 652a8fe65b8SJeff Kirsher dev->stats.collisions++; 653a8fe65b8SJeff Kirsher if (++lp->re_tx > 15) { 654a8fe65b8SJeff Kirsher dev->stats.tx_aborted_errors++; 655a8fe65b8SJeff Kirsher hardware_init(dev); 656a8fe65b8SJeff Kirsher break; 657a8fe65b8SJeff Kirsher } 658a8fe65b8SJeff Kirsher /* Attempt to retransmit. */ 659a8fe65b8SJeff Kirsher if (net_debug > 6) printk("attempting to ReTx"); 660a8fe65b8SJeff Kirsher write_reg(ioaddr, CMR1, CMR1_ReXmit + CMR1_Xmit); 661a8fe65b8SJeff Kirsher } else { 662a8fe65b8SJeff Kirsher /* Finish up the transmit. */ 663a8fe65b8SJeff Kirsher dev->stats.tx_packets++; 664a8fe65b8SJeff Kirsher lp->pac_cnt_in_tx_buf--; 665a8fe65b8SJeff Kirsher if ( lp->saved_tx_size) { 666a8fe65b8SJeff Kirsher trigger_send(ioaddr, lp->saved_tx_size); 667a8fe65b8SJeff Kirsher lp->saved_tx_size = 0; 668a8fe65b8SJeff Kirsher lp->re_tx = 0; 669a8fe65b8SJeff Kirsher } else 670a8fe65b8SJeff Kirsher lp->tx_unit_busy = 0; 671a8fe65b8SJeff Kirsher netif_wake_queue(dev); /* Inform upper layers. */ 672a8fe65b8SJeff Kirsher } 673a8fe65b8SJeff Kirsher num_tx_since_rx++; 674a8fe65b8SJeff Kirsher } else if (num_tx_since_rx > 8 && 675a8fe65b8SJeff Kirsher time_after(jiffies, dev->last_rx + HZ)) { 676a8fe65b8SJeff Kirsher if (net_debug > 2) 677a8fe65b8SJeff Kirsher printk(KERN_DEBUG "%s: Missed packet? No Rx after %d Tx and " 678a8fe65b8SJeff Kirsher "%ld jiffies status %02x CMR1 %02x.\n", dev->name, 679a8fe65b8SJeff Kirsher num_tx_since_rx, jiffies - dev->last_rx, status, 680a8fe65b8SJeff Kirsher (read_nibble(ioaddr, CMR1) >> 3) & 15); 681a8fe65b8SJeff Kirsher dev->stats.rx_missed_errors++; 682a8fe65b8SJeff Kirsher hardware_init(dev); 683a8fe65b8SJeff Kirsher num_tx_since_rx = 0; 684a8fe65b8SJeff Kirsher break; 685a8fe65b8SJeff Kirsher } else 686a8fe65b8SJeff Kirsher break; 687a8fe65b8SJeff Kirsher } 688a8fe65b8SJeff Kirsher 689a8fe65b8SJeff Kirsher /* This following code fixes a rare (and very difficult to track down) 690a8fe65b8SJeff Kirsher problem where the adapter forgets its ethernet address. */ 691a8fe65b8SJeff Kirsher { 692a8fe65b8SJeff Kirsher int i; 693a8fe65b8SJeff Kirsher for (i = 0; i < 6; i++) 694a8fe65b8SJeff Kirsher write_reg_byte(ioaddr, PAR0 + i, dev->dev_addr[i]); 695a8fe65b8SJeff Kirsher #if 0 && defined(TIMED_CHECKER) 696a8fe65b8SJeff Kirsher mod_timer(&lp->timer, jiffies + TIMED_CHECKER); 697a8fe65b8SJeff Kirsher #endif 698a8fe65b8SJeff Kirsher } 699a8fe65b8SJeff Kirsher 700a8fe65b8SJeff Kirsher /* Tell the adapter that it can go back to using the output line as IRQ. */ 701a8fe65b8SJeff Kirsher write_reg(ioaddr, CMR2, CMR2_IRQOUT); 702a8fe65b8SJeff Kirsher /* Enable the physical interrupt line, which is sure to be low until.. */ 703a8fe65b8SJeff Kirsher outb(Ctrl_SelData + Ctrl_IRQEN, ioaddr + PAR_CONTROL); 704a8fe65b8SJeff Kirsher /* .. we enable the interrupt sources. */ 705a8fe65b8SJeff Kirsher write_reg(ioaddr, IMR, ISR_RxOK | ISR_TxErr | ISR_TxOK); 706a8fe65b8SJeff Kirsher write_reg_high(ioaddr, IMR, ISRh_RxErr); /* Hmmm, really needed? */ 707a8fe65b8SJeff Kirsher 708a8fe65b8SJeff Kirsher spin_unlock(&lp->lock); 709a8fe65b8SJeff Kirsher 710a8fe65b8SJeff Kirsher if (net_debug > 5) printk("exiting interrupt.\n"); 711a8fe65b8SJeff Kirsher return IRQ_RETVAL(handled); 712a8fe65b8SJeff Kirsher } 713a8fe65b8SJeff Kirsher 714a8fe65b8SJeff Kirsher #ifdef TIMED_CHECKER 715a8fe65b8SJeff Kirsher /* This following code fixes a rare (and very difficult to track down) 716a8fe65b8SJeff Kirsher problem where the adapter forgets its ethernet address. */ 717a8fe65b8SJeff Kirsher static void atp_timed_checker(unsigned long data) 718a8fe65b8SJeff Kirsher { 719a8fe65b8SJeff Kirsher struct net_device *dev = (struct net_device *)data; 720a8fe65b8SJeff Kirsher long ioaddr = dev->base_addr; 721a8fe65b8SJeff Kirsher struct net_local *lp = netdev_priv(dev); 722a8fe65b8SJeff Kirsher int tickssofar = jiffies - lp->last_rx_time; 723a8fe65b8SJeff Kirsher int i; 724a8fe65b8SJeff Kirsher 725a8fe65b8SJeff Kirsher spin_lock(&lp->lock); 726a8fe65b8SJeff Kirsher if (tickssofar > 2*HZ) { 727a8fe65b8SJeff Kirsher #if 1 728a8fe65b8SJeff Kirsher for (i = 0; i < 6; i++) 729a8fe65b8SJeff Kirsher write_reg_byte(ioaddr, PAR0 + i, dev->dev_addr[i]); 730a8fe65b8SJeff Kirsher lp->last_rx_time = jiffies; 731a8fe65b8SJeff Kirsher #else 732a8fe65b8SJeff Kirsher for (i = 0; i < 6; i++) 733a8fe65b8SJeff Kirsher if (read_cmd_byte(ioaddr, PAR0 + i) != atp_timed_dev->dev_addr[i]) 734a8fe65b8SJeff Kirsher { 735a8fe65b8SJeff Kirsher struct net_local *lp = netdev_priv(atp_timed_dev); 736a8fe65b8SJeff Kirsher write_reg_byte(ioaddr, PAR0 + i, atp_timed_dev->dev_addr[i]); 737a8fe65b8SJeff Kirsher if (i == 2) 738a8fe65b8SJeff Kirsher dev->stats.tx_errors++; 739a8fe65b8SJeff Kirsher else if (i == 3) 740a8fe65b8SJeff Kirsher dev->stats.tx_dropped++; 741a8fe65b8SJeff Kirsher else if (i == 4) 742a8fe65b8SJeff Kirsher dev->stats.collisions++; 743a8fe65b8SJeff Kirsher else 744a8fe65b8SJeff Kirsher dev->stats.rx_errors++; 745a8fe65b8SJeff Kirsher } 746a8fe65b8SJeff Kirsher #endif 747a8fe65b8SJeff Kirsher } 748a8fe65b8SJeff Kirsher spin_unlock(&lp->lock); 749a8fe65b8SJeff Kirsher lp->timer.expires = jiffies + TIMED_CHECKER; 750a8fe65b8SJeff Kirsher add_timer(&lp->timer); 751a8fe65b8SJeff Kirsher } 752a8fe65b8SJeff Kirsher #endif 753a8fe65b8SJeff Kirsher 754a8fe65b8SJeff Kirsher /* We have a good packet(s), get it/them out of the buffers. */ 755a8fe65b8SJeff Kirsher static void net_rx(struct net_device *dev) 756a8fe65b8SJeff Kirsher { 757a8fe65b8SJeff Kirsher struct net_local *lp = netdev_priv(dev); 758a8fe65b8SJeff Kirsher long ioaddr = dev->base_addr; 759a8fe65b8SJeff Kirsher struct rx_header rx_head; 760a8fe65b8SJeff Kirsher 761a8fe65b8SJeff Kirsher /* Process the received packet. */ 762a8fe65b8SJeff Kirsher outb(EOC+MAR, ioaddr + PAR_DATA); 763a8fe65b8SJeff Kirsher read_block(ioaddr, 8, (unsigned char*)&rx_head, dev->if_port); 764a8fe65b8SJeff Kirsher if (net_debug > 5) 765a8fe65b8SJeff Kirsher printk(KERN_DEBUG " rx_count %04x %04x %04x %04x..", rx_head.pad, 766a8fe65b8SJeff Kirsher rx_head.rx_count, rx_head.rx_status, rx_head.cur_addr); 767a8fe65b8SJeff Kirsher if ((rx_head.rx_status & 0x77) != 0x01) { 768a8fe65b8SJeff Kirsher dev->stats.rx_errors++; 769a8fe65b8SJeff Kirsher if (rx_head.rx_status & 0x0004) dev->stats.rx_frame_errors++; 770a8fe65b8SJeff Kirsher else if (rx_head.rx_status & 0x0002) dev->stats.rx_crc_errors++; 771a8fe65b8SJeff Kirsher if (net_debug > 3) 772a8fe65b8SJeff Kirsher printk(KERN_DEBUG "%s: Unknown ATP Rx error %04x.\n", 773a8fe65b8SJeff Kirsher dev->name, rx_head.rx_status); 774a8fe65b8SJeff Kirsher if (rx_head.rx_status & 0x0020) { 775a8fe65b8SJeff Kirsher dev->stats.rx_fifo_errors++; 776a8fe65b8SJeff Kirsher write_reg_high(ioaddr, CMR1, CMR1h_TxENABLE); 777a8fe65b8SJeff Kirsher write_reg_high(ioaddr, CMR1, CMR1h_RxENABLE | CMR1h_TxENABLE); 778a8fe65b8SJeff Kirsher } else if (rx_head.rx_status & 0x0050) 779a8fe65b8SJeff Kirsher hardware_init(dev); 780a8fe65b8SJeff Kirsher return; 781a8fe65b8SJeff Kirsher } else { 782a8fe65b8SJeff Kirsher /* Malloc up new buffer. The "-4" omits the FCS (CRC). */ 783a8fe65b8SJeff Kirsher int pkt_len = (rx_head.rx_count & 0x7ff) - 4; 784a8fe65b8SJeff Kirsher struct sk_buff *skb; 785a8fe65b8SJeff Kirsher 786a8fe65b8SJeff Kirsher skb = dev_alloc_skb(pkt_len + 2); 787a8fe65b8SJeff Kirsher if (skb == NULL) { 788a8fe65b8SJeff Kirsher printk(KERN_ERR "%s: Memory squeeze, dropping packet.\n", 789a8fe65b8SJeff Kirsher dev->name); 790a8fe65b8SJeff Kirsher dev->stats.rx_dropped++; 791a8fe65b8SJeff Kirsher goto done; 792a8fe65b8SJeff Kirsher } 793a8fe65b8SJeff Kirsher 794a8fe65b8SJeff Kirsher skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */ 795a8fe65b8SJeff Kirsher read_block(ioaddr, pkt_len, skb_put(skb,pkt_len), dev->if_port); 796a8fe65b8SJeff Kirsher skb->protocol = eth_type_trans(skb, dev); 797a8fe65b8SJeff Kirsher netif_rx(skb); 798a8fe65b8SJeff Kirsher dev->last_rx = jiffies; 799a8fe65b8SJeff Kirsher dev->stats.rx_packets++; 800a8fe65b8SJeff Kirsher dev->stats.rx_bytes += pkt_len; 801a8fe65b8SJeff Kirsher } 802a8fe65b8SJeff Kirsher done: 803a8fe65b8SJeff Kirsher write_reg(ioaddr, CMR1, CMR1_NextPkt); 804a8fe65b8SJeff Kirsher lp->last_rx_time = jiffies; 805a8fe65b8SJeff Kirsher } 806a8fe65b8SJeff Kirsher 807a8fe65b8SJeff Kirsher static void read_block(long ioaddr, int length, unsigned char *p, int data_mode) 808a8fe65b8SJeff Kirsher { 809a8fe65b8SJeff Kirsher if (data_mode <= 3) { /* Mode 0 or 1 */ 810a8fe65b8SJeff Kirsher outb(Ctrl_LNibRead, ioaddr + PAR_CONTROL); 811a8fe65b8SJeff Kirsher outb(length == 8 ? RdAddr | HNib | MAR : RdAddr | MAR, 812a8fe65b8SJeff Kirsher ioaddr + PAR_DATA); 813a8fe65b8SJeff Kirsher if (data_mode <= 1) { /* Mode 0 or 1 */ 814a8fe65b8SJeff Kirsher do { *p++ = read_byte_mode0(ioaddr); } while (--length > 0); 815a8fe65b8SJeff Kirsher } else { /* Mode 2 or 3 */ 816a8fe65b8SJeff Kirsher do { *p++ = read_byte_mode2(ioaddr); } while (--length > 0); 817a8fe65b8SJeff Kirsher } 818a8fe65b8SJeff Kirsher } else if (data_mode <= 5) { 819a8fe65b8SJeff Kirsher do { *p++ = read_byte_mode4(ioaddr); } while (--length > 0); 820a8fe65b8SJeff Kirsher } else { 821a8fe65b8SJeff Kirsher do { *p++ = read_byte_mode6(ioaddr); } while (--length > 0); 822a8fe65b8SJeff Kirsher } 823a8fe65b8SJeff Kirsher 824a8fe65b8SJeff Kirsher outb(EOC+HNib+MAR, ioaddr + PAR_DATA); 825a8fe65b8SJeff Kirsher outb(Ctrl_SelData, ioaddr + PAR_CONTROL); 826a8fe65b8SJeff Kirsher } 827a8fe65b8SJeff Kirsher 828a8fe65b8SJeff Kirsher /* The inverse routine to net_open(). */ 829a8fe65b8SJeff Kirsher static int 830a8fe65b8SJeff Kirsher net_close(struct net_device *dev) 831a8fe65b8SJeff Kirsher { 832a8fe65b8SJeff Kirsher struct net_local *lp = netdev_priv(dev); 833a8fe65b8SJeff Kirsher long ioaddr = dev->base_addr; 834a8fe65b8SJeff Kirsher 835a8fe65b8SJeff Kirsher netif_stop_queue(dev); 836a8fe65b8SJeff Kirsher 837a8fe65b8SJeff Kirsher del_timer_sync(&lp->timer); 838a8fe65b8SJeff Kirsher 839a8fe65b8SJeff Kirsher /* Flush the Tx and disable Rx here. */ 840a8fe65b8SJeff Kirsher lp->addr_mode = CMR2h_OFF; 841a8fe65b8SJeff Kirsher write_reg_high(ioaddr, CMR2, CMR2h_OFF); 842a8fe65b8SJeff Kirsher 843a8fe65b8SJeff Kirsher /* Free the IRQ line. */ 844a8fe65b8SJeff Kirsher outb(0x00, ioaddr + PAR_CONTROL); 845a8fe65b8SJeff Kirsher free_irq(dev->irq, dev); 846a8fe65b8SJeff Kirsher 847a8fe65b8SJeff Kirsher /* Reset the ethernet hardware and activate the printer pass-through. */ 848a8fe65b8SJeff Kirsher write_reg_high(ioaddr, CMR1, CMR1h_RESET | CMR1h_MUX); 849a8fe65b8SJeff Kirsher return 0; 850a8fe65b8SJeff Kirsher } 851a8fe65b8SJeff Kirsher 852a8fe65b8SJeff Kirsher /* 853a8fe65b8SJeff Kirsher * Set or clear the multicast filter for this adapter. 854a8fe65b8SJeff Kirsher */ 855a8fe65b8SJeff Kirsher 856a8fe65b8SJeff Kirsher static void set_rx_mode_8002(struct net_device *dev) 857a8fe65b8SJeff Kirsher { 858a8fe65b8SJeff Kirsher struct net_local *lp = netdev_priv(dev); 859a8fe65b8SJeff Kirsher long ioaddr = dev->base_addr; 860a8fe65b8SJeff Kirsher 861a8fe65b8SJeff Kirsher if (!netdev_mc_empty(dev) || (dev->flags & (IFF_ALLMULTI|IFF_PROMISC))) 862a8fe65b8SJeff Kirsher lp->addr_mode = CMR2h_PROMISC; 863a8fe65b8SJeff Kirsher else 864a8fe65b8SJeff Kirsher lp->addr_mode = CMR2h_Normal; 865a8fe65b8SJeff Kirsher write_reg_high(ioaddr, CMR2, lp->addr_mode); 866a8fe65b8SJeff Kirsher } 867a8fe65b8SJeff Kirsher 868a8fe65b8SJeff Kirsher static void set_rx_mode_8012(struct net_device *dev) 869a8fe65b8SJeff Kirsher { 870a8fe65b8SJeff Kirsher struct net_local *lp = netdev_priv(dev); 871a8fe65b8SJeff Kirsher long ioaddr = dev->base_addr; 872a8fe65b8SJeff Kirsher unsigned char new_mode, mc_filter[8]; /* Multicast hash filter */ 873a8fe65b8SJeff Kirsher int i; 874a8fe65b8SJeff Kirsher 875a8fe65b8SJeff Kirsher if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */ 876a8fe65b8SJeff Kirsher new_mode = CMR2h_PROMISC; 877a8fe65b8SJeff Kirsher } else if ((netdev_mc_count(dev) > 1000) || 878a8fe65b8SJeff Kirsher (dev->flags & IFF_ALLMULTI)) { 879a8fe65b8SJeff Kirsher /* Too many to filter perfectly -- accept all multicasts. */ 880a8fe65b8SJeff Kirsher memset(mc_filter, 0xff, sizeof(mc_filter)); 881a8fe65b8SJeff Kirsher new_mode = CMR2h_Normal; 882a8fe65b8SJeff Kirsher } else { 883a8fe65b8SJeff Kirsher struct netdev_hw_addr *ha; 884a8fe65b8SJeff Kirsher 885a8fe65b8SJeff Kirsher memset(mc_filter, 0, sizeof(mc_filter)); 886a8fe65b8SJeff Kirsher netdev_for_each_mc_addr(ha, dev) { 887a8fe65b8SJeff Kirsher int filterbit = ether_crc_le(ETH_ALEN, ha->addr) & 0x3f; 888a8fe65b8SJeff Kirsher mc_filter[filterbit >> 5] |= 1 << (filterbit & 31); 889a8fe65b8SJeff Kirsher } 890a8fe65b8SJeff Kirsher new_mode = CMR2h_Normal; 891a8fe65b8SJeff Kirsher } 892a8fe65b8SJeff Kirsher lp->addr_mode = new_mode; 893a8fe65b8SJeff Kirsher write_reg(ioaddr, CMR2, CMR2_IRQOUT | 0x04); /* Switch to page 1. */ 894a8fe65b8SJeff Kirsher for (i = 0; i < 8; i++) 895a8fe65b8SJeff Kirsher write_reg_byte(ioaddr, i, mc_filter[i]); 896a8fe65b8SJeff Kirsher if (net_debug > 2 || 1) { 897a8fe65b8SJeff Kirsher lp->addr_mode = 1; 898a8fe65b8SJeff Kirsher printk(KERN_DEBUG "%s: Mode %d, setting multicast filter to", 899a8fe65b8SJeff Kirsher dev->name, lp->addr_mode); 900a8fe65b8SJeff Kirsher for (i = 0; i < 8; i++) 901a8fe65b8SJeff Kirsher printk(" %2.2x", mc_filter[i]); 902a8fe65b8SJeff Kirsher printk(".\n"); 903a8fe65b8SJeff Kirsher } 904a8fe65b8SJeff Kirsher 905a8fe65b8SJeff Kirsher write_reg_high(ioaddr, CMR2, lp->addr_mode); 906a8fe65b8SJeff Kirsher write_reg(ioaddr, CMR2, CMR2_IRQOUT); /* Switch back to page 0 */ 907a8fe65b8SJeff Kirsher } 908a8fe65b8SJeff Kirsher 909a8fe65b8SJeff Kirsher static void set_rx_mode(struct net_device *dev) 910a8fe65b8SJeff Kirsher { 911a8fe65b8SJeff Kirsher struct net_local *lp = netdev_priv(dev); 912a8fe65b8SJeff Kirsher 913a8fe65b8SJeff Kirsher if (lp->chip_type == RTL8002) 914a8fe65b8SJeff Kirsher return set_rx_mode_8002(dev); 915a8fe65b8SJeff Kirsher else 916a8fe65b8SJeff Kirsher return set_rx_mode_8012(dev); 917a8fe65b8SJeff Kirsher } 918a8fe65b8SJeff Kirsher 919a8fe65b8SJeff Kirsher 920a8fe65b8SJeff Kirsher static int __init atp_init_module(void) { 921a8fe65b8SJeff Kirsher if (debug) /* Emit version even if no cards detected. */ 922a8fe65b8SJeff Kirsher printk(KERN_INFO "%s", version); 923a8fe65b8SJeff Kirsher return atp_init(); 924a8fe65b8SJeff Kirsher } 925a8fe65b8SJeff Kirsher 926a8fe65b8SJeff Kirsher static void __exit atp_cleanup_module(void) { 927a8fe65b8SJeff Kirsher struct net_device *next_dev; 928a8fe65b8SJeff Kirsher 929a8fe65b8SJeff Kirsher while (root_atp_dev) { 930a8fe65b8SJeff Kirsher struct net_local *atp_local = netdev_priv(root_atp_dev); 931a8fe65b8SJeff Kirsher next_dev = atp_local->next_module; 932a8fe65b8SJeff Kirsher unregister_netdev(root_atp_dev); 933a8fe65b8SJeff Kirsher /* No need to release_region(), since we never snarf it. */ 934a8fe65b8SJeff Kirsher free_netdev(root_atp_dev); 935a8fe65b8SJeff Kirsher root_atp_dev = next_dev; 936a8fe65b8SJeff Kirsher } 937a8fe65b8SJeff Kirsher } 938a8fe65b8SJeff Kirsher 939a8fe65b8SJeff Kirsher module_init(atp_init_module); 940a8fe65b8SJeff Kirsher module_exit(atp_cleanup_module); 941