xref: /openbmc/linux/drivers/net/ethernet/realtek/atp.c (revision 9de36ccf)
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/io.h>
144a8fe65b8SJeff Kirsher #include <asm/dma.h>
145a8fe65b8SJeff Kirsher 
146a8fe65b8SJeff Kirsher #include "atp.h"
147a8fe65b8SJeff Kirsher 
148a8fe65b8SJeff Kirsher MODULE_AUTHOR("Donald Becker <becker@scyld.com>");
149a8fe65b8SJeff Kirsher MODULE_DESCRIPTION("RealTek RTL8002/8012 parallel port Ethernet driver");
150a8fe65b8SJeff Kirsher MODULE_LICENSE("GPL");
151a8fe65b8SJeff Kirsher 
152a8fe65b8SJeff Kirsher module_param(max_interrupt_work, int, 0);
153a8fe65b8SJeff Kirsher module_param(debug, int, 0);
154df298408SDavid Howells module_param_hw_array(io, int, ioport, NULL, 0);
155df298408SDavid Howells module_param_hw_array(irq, int, irq, NULL, 0);
156a8fe65b8SJeff Kirsher module_param_array(xcvr, int, NULL, 0);
157a8fe65b8SJeff Kirsher MODULE_PARM_DESC(max_interrupt_work, "ATP maximum events handled per interrupt");
158a8fe65b8SJeff Kirsher MODULE_PARM_DESC(debug, "ATP debug level (0-7)");
159a8fe65b8SJeff Kirsher MODULE_PARM_DESC(io, "ATP I/O base address(es)");
160a8fe65b8SJeff Kirsher MODULE_PARM_DESC(irq, "ATP IRQ number(s)");
161a8fe65b8SJeff Kirsher MODULE_PARM_DESC(xcvr, "ATP transceiver(s) (0=internal, 1=external)");
162a8fe65b8SJeff Kirsher 
163a8fe65b8SJeff Kirsher /* The number of low I/O ports used by the ethercard. */
164a8fe65b8SJeff Kirsher #define ETHERCARD_TOTAL_SIZE	3
165a8fe65b8SJeff Kirsher 
166a8fe65b8SJeff Kirsher /* Sequence to switch an 8012 from printer mux to ethernet mode. */
167a8fe65b8SJeff Kirsher static char mux_8012[] = { 0xff, 0xf7, 0xff, 0xfb, 0xf3, 0xfb, 0xff, 0xf7,};
168a8fe65b8SJeff Kirsher 
169a8fe65b8SJeff Kirsher struct net_local {
170a8fe65b8SJeff Kirsher     spinlock_t lock;
171a8fe65b8SJeff Kirsher     struct net_device *next_module;
172a8fe65b8SJeff Kirsher     struct timer_list timer;	/* Media selection timer. */
1739de36ccfSKees Cook     struct net_device *dev;	/* Timer dev. */
1744a7c9726STobias Klauser     unsigned 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. */
179bb263e18SPaul Bolle 		pac_cnt_in_tx_buf;
180a8fe65b8SJeff Kirsher };
181a8fe65b8SJeff Kirsher 
182a8fe65b8SJeff Kirsher /* This code, written by wwc@super.org, resets the adapter every
183a8fe65b8SJeff Kirsher    TIMED_CHECKER ticks.  This recovers from an unknown error which
184a8fe65b8SJeff Kirsher    hangs the device. */
185a8fe65b8SJeff Kirsher #define TIMED_CHECKER (HZ/4)
186a8fe65b8SJeff Kirsher #ifdef TIMED_CHECKER
187a8fe65b8SJeff Kirsher #include <linux/timer.h>
1889de36ccfSKees Cook static void atp_timed_checker(struct timer_list *t);
189a8fe65b8SJeff Kirsher #endif
190a8fe65b8SJeff Kirsher 
191a8fe65b8SJeff Kirsher /* Index to functions, as function prototypes. */
192a8fe65b8SJeff Kirsher 
193a8fe65b8SJeff Kirsher static int atp_probe1(long ioaddr);
194a8fe65b8SJeff Kirsher static void get_node_ID(struct net_device *dev);
195a8fe65b8SJeff Kirsher static unsigned short eeprom_op(long ioaddr, unsigned int cmd);
196a8fe65b8SJeff Kirsher static int net_open(struct net_device *dev);
197a8fe65b8SJeff Kirsher static void hardware_init(struct net_device *dev);
198a8fe65b8SJeff Kirsher static void write_packet(long ioaddr, int length, unsigned char *packet, int pad, int mode);
199a8fe65b8SJeff Kirsher static void trigger_send(long ioaddr, int length);
200a8fe65b8SJeff Kirsher static netdev_tx_t atp_send_packet(struct sk_buff *skb,
201a8fe65b8SJeff Kirsher 				   struct net_device *dev);
202a8fe65b8SJeff Kirsher static irqreturn_t atp_interrupt(int irq, void *dev_id);
203a8fe65b8SJeff Kirsher static void net_rx(struct net_device *dev);
204a8fe65b8SJeff Kirsher static void read_block(long ioaddr, int length, unsigned char *buffer, int data_mode);
205a8fe65b8SJeff Kirsher static int net_close(struct net_device *dev);
206a8fe65b8SJeff Kirsher static void set_rx_mode(struct net_device *dev);
207a8fe65b8SJeff Kirsher static void tx_timeout(struct net_device *dev);
208a8fe65b8SJeff Kirsher 
209a8fe65b8SJeff Kirsher 
210a8fe65b8SJeff Kirsher /* A list of all installed ATP devices, for removing the driver module. */
211a8fe65b8SJeff Kirsher static struct net_device *root_atp_dev;
212a8fe65b8SJeff Kirsher 
213a8fe65b8SJeff Kirsher /* Check for a network adapter of this type, and return '0' iff one exists.
214a8fe65b8SJeff Kirsher    If dev->base_addr == 0, probe all likely locations.
215a8fe65b8SJeff Kirsher    If dev->base_addr == 1, always return failure.
216a8fe65b8SJeff Kirsher    If dev->base_addr == 2, allocate space for the device and return success
217a8fe65b8SJeff Kirsher    (detachable devices only).
218a8fe65b8SJeff Kirsher 
219a8fe65b8SJeff Kirsher    FIXME: we should use the parport layer for this
220a8fe65b8SJeff Kirsher    */
221a8fe65b8SJeff Kirsher static int __init atp_init(void)
222a8fe65b8SJeff Kirsher {
223a8fe65b8SJeff Kirsher 	int *port, ports[] = {0x378, 0x278, 0x3bc, 0};
224a8fe65b8SJeff Kirsher 	int base_addr = io[0];
225a8fe65b8SJeff Kirsher 
226a8fe65b8SJeff Kirsher 	if (base_addr > 0x1ff)		/* Check a single specified location. */
227a8fe65b8SJeff Kirsher 		return atp_probe1(base_addr);
228a8fe65b8SJeff Kirsher 	else if (base_addr == 1)	/* Don't probe at all. */
229a8fe65b8SJeff Kirsher 		return -ENXIO;
230a8fe65b8SJeff Kirsher 
231a8fe65b8SJeff Kirsher 	for (port = ports; *port; port++) {
232a8fe65b8SJeff Kirsher 		long ioaddr = *port;
233a8fe65b8SJeff Kirsher 		outb(0x57, ioaddr + PAR_DATA);
234a8fe65b8SJeff Kirsher 		if (inb(ioaddr + PAR_DATA) != 0x57)
235a8fe65b8SJeff Kirsher 			continue;
236a8fe65b8SJeff Kirsher 		if (atp_probe1(ioaddr) == 0)
237a8fe65b8SJeff Kirsher 			return 0;
238a8fe65b8SJeff Kirsher 	}
239a8fe65b8SJeff Kirsher 
240a8fe65b8SJeff Kirsher 	return -ENODEV;
241a8fe65b8SJeff Kirsher }
242a8fe65b8SJeff Kirsher 
243a8fe65b8SJeff Kirsher static const struct net_device_ops atp_netdev_ops = {
244a8fe65b8SJeff Kirsher 	.ndo_open		= net_open,
245a8fe65b8SJeff Kirsher 	.ndo_stop		= net_close,
246a8fe65b8SJeff Kirsher 	.ndo_start_xmit		= atp_send_packet,
247afc4b13dSJiri Pirko 	.ndo_set_rx_mode	= set_rx_mode,
248a8fe65b8SJeff Kirsher 	.ndo_tx_timeout		= tx_timeout,
249a8fe65b8SJeff Kirsher 	.ndo_set_mac_address 	= eth_mac_addr,
250a8fe65b8SJeff Kirsher 	.ndo_validate_addr	= eth_validate_addr,
251a8fe65b8SJeff Kirsher };
252a8fe65b8SJeff Kirsher 
253a8fe65b8SJeff Kirsher static int __init atp_probe1(long ioaddr)
254a8fe65b8SJeff Kirsher {
255a8fe65b8SJeff Kirsher 	struct net_device *dev = NULL;
256a8fe65b8SJeff Kirsher 	struct net_local *lp;
257a8fe65b8SJeff Kirsher 	int saved_ctrl_reg, status, i;
258a8fe65b8SJeff Kirsher 	int res;
259a8fe65b8SJeff Kirsher 
260a8fe65b8SJeff Kirsher 	outb(0xff, ioaddr + PAR_DATA);
261a8fe65b8SJeff Kirsher 	/* Save the original value of the Control register, in case we guessed
262a8fe65b8SJeff Kirsher 	   wrong. */
263a8fe65b8SJeff Kirsher 	saved_ctrl_reg = inb(ioaddr + PAR_CONTROL);
264a8fe65b8SJeff Kirsher 	if (net_debug > 3)
265a8fe65b8SJeff Kirsher 		printk("atp: Control register was %#2.2x.\n", saved_ctrl_reg);
266a8fe65b8SJeff Kirsher 	/* IRQEN=0, SLCTB=high INITB=high, AUTOFDB=high, STBB=high. */
267a8fe65b8SJeff Kirsher 	outb(0x04, ioaddr + PAR_CONTROL);
268a8fe65b8SJeff Kirsher #ifndef final_version
269a8fe65b8SJeff Kirsher 	if (net_debug > 3) {
270a8fe65b8SJeff Kirsher 		/* Turn off the printer multiplexer on the 8012. */
271a8fe65b8SJeff Kirsher 		for (i = 0; i < 8; i++)
272a8fe65b8SJeff Kirsher 			outb(mux_8012[i], ioaddr + PAR_DATA);
273a8fe65b8SJeff Kirsher 		write_reg(ioaddr, MODSEL, 0x00);
274a8fe65b8SJeff Kirsher 		printk("atp: Registers are ");
275a8fe65b8SJeff Kirsher 		for (i = 0; i < 32; i++)
276a8fe65b8SJeff Kirsher 			printk(" %2.2x", read_nibble(ioaddr, i));
277a8fe65b8SJeff Kirsher 		printk(".\n");
278a8fe65b8SJeff Kirsher 	}
279a8fe65b8SJeff Kirsher #endif
280a8fe65b8SJeff Kirsher 	/* Turn off the printer multiplexer on the 8012. */
281a8fe65b8SJeff Kirsher 	for (i = 0; i < 8; i++)
282a8fe65b8SJeff Kirsher 		outb(mux_8012[i], ioaddr + PAR_DATA);
283a8fe65b8SJeff Kirsher 	write_reg_high(ioaddr, CMR1, CMR1h_RESET);
284a8fe65b8SJeff Kirsher 	/* udelay() here? */
285a8fe65b8SJeff Kirsher 	status = read_nibble(ioaddr, CMR1);
286a8fe65b8SJeff Kirsher 
287a8fe65b8SJeff Kirsher 	if (net_debug > 3) {
288a8fe65b8SJeff Kirsher 		printk(KERN_DEBUG "atp: Status nibble was %#2.2x..", status);
289a8fe65b8SJeff Kirsher 		for (i = 0; i < 32; i++)
290a8fe65b8SJeff Kirsher 			printk(" %2.2x", read_nibble(ioaddr, i));
291a8fe65b8SJeff Kirsher 		printk("\n");
292a8fe65b8SJeff Kirsher 	}
293a8fe65b8SJeff Kirsher 
294a8fe65b8SJeff Kirsher 	if ((status & 0x78) != 0x08) {
295a8fe65b8SJeff Kirsher 		/* The pocket adapter probe failed, restore the control register. */
296a8fe65b8SJeff Kirsher 		outb(saved_ctrl_reg, ioaddr + PAR_CONTROL);
297a8fe65b8SJeff Kirsher 		return -ENODEV;
298a8fe65b8SJeff Kirsher 	}
299a8fe65b8SJeff Kirsher 	status = read_nibble(ioaddr, CMR2_h);
300a8fe65b8SJeff Kirsher 	if ((status & 0x78) != 0x10) {
301a8fe65b8SJeff Kirsher 		outb(saved_ctrl_reg, ioaddr + PAR_CONTROL);
302a8fe65b8SJeff Kirsher 		return -ENODEV;
303a8fe65b8SJeff Kirsher 	}
304a8fe65b8SJeff Kirsher 
305a8fe65b8SJeff Kirsher 	dev = alloc_etherdev(sizeof(struct net_local));
306a8fe65b8SJeff Kirsher 	if (!dev)
307a8fe65b8SJeff Kirsher 		return -ENOMEM;
308a8fe65b8SJeff Kirsher 
309a8fe65b8SJeff Kirsher 	/* Find the IRQ used by triggering an interrupt. */
310a8fe65b8SJeff Kirsher 	write_reg_byte(ioaddr, CMR2, 0x01);			/* No accept mode, IRQ out. */
311a8fe65b8SJeff Kirsher 	write_reg_high(ioaddr, CMR1, CMR1h_RxENABLE | CMR1h_TxENABLE);	/* Enable Tx and Rx. */
312a8fe65b8SJeff Kirsher 
313a8fe65b8SJeff Kirsher 	/* Omit autoIRQ routine for now. Use "table lookup" instead.  Uhgggh. */
314a8fe65b8SJeff Kirsher 	if (irq[0])
315a8fe65b8SJeff Kirsher 		dev->irq = irq[0];
316a8fe65b8SJeff Kirsher 	else if (ioaddr == 0x378)
317a8fe65b8SJeff Kirsher 		dev->irq = 7;
318a8fe65b8SJeff Kirsher 	else
319a8fe65b8SJeff Kirsher 		dev->irq = 5;
320a8fe65b8SJeff Kirsher 	write_reg_high(ioaddr, CMR1, CMR1h_TxRxOFF); /* Disable Tx and Rx units. */
321a8fe65b8SJeff Kirsher 	write_reg(ioaddr, CMR2, CMR2_NULL);
322a8fe65b8SJeff Kirsher 
323a8fe65b8SJeff Kirsher 	dev->base_addr = ioaddr;
324a8fe65b8SJeff Kirsher 
325a8fe65b8SJeff Kirsher 	/* Read the station address PROM.  */
326a8fe65b8SJeff Kirsher 	get_node_ID(dev);
327a8fe65b8SJeff Kirsher 
328a8fe65b8SJeff Kirsher #ifndef MODULE
329a8fe65b8SJeff Kirsher 	if (net_debug)
330a8fe65b8SJeff Kirsher 		printk(KERN_INFO "%s", version);
331a8fe65b8SJeff Kirsher #endif
332a8fe65b8SJeff Kirsher 
333a8fe65b8SJeff Kirsher 	printk(KERN_NOTICE "%s: Pocket adapter found at %#3lx, IRQ %d, "
334a8fe65b8SJeff Kirsher 	       "SAPROM %pM.\n",
335a8fe65b8SJeff Kirsher 	       dev->name, dev->base_addr, dev->irq, dev->dev_addr);
336a8fe65b8SJeff Kirsher 
337a8fe65b8SJeff Kirsher 	/* Reset the ethernet hardware and activate the printer pass-through. */
338a8fe65b8SJeff Kirsher 	write_reg_high(ioaddr, CMR1, CMR1h_RESET | CMR1h_MUX);
339a8fe65b8SJeff Kirsher 
340a8fe65b8SJeff Kirsher 	lp = netdev_priv(dev);
341a8fe65b8SJeff Kirsher 	lp->addr_mode = CMR2h_Normal;
342a8fe65b8SJeff Kirsher 	spin_lock_init(&lp->lock);
343a8fe65b8SJeff Kirsher 
344a8fe65b8SJeff Kirsher 	/* For the ATP adapter the "if_port" is really the data transfer mode. */
345a8fe65b8SJeff Kirsher 	if (xcvr[0])
346a8fe65b8SJeff Kirsher 		dev->if_port = xcvr[0];
347a8fe65b8SJeff Kirsher 	else
348a8fe65b8SJeff Kirsher 		dev->if_port = (dev->mem_start & 0xf) ? (dev->mem_start & 0x7) : 4;
349a8fe65b8SJeff Kirsher 	if (dev->mem_end & 0xf)
350a8fe65b8SJeff Kirsher 		net_debug = dev->mem_end & 7;
351a8fe65b8SJeff Kirsher 
352a8fe65b8SJeff Kirsher 	dev->netdev_ops 	= &atp_netdev_ops;
353a8fe65b8SJeff Kirsher 	dev->watchdog_timeo	= TX_TIMEOUT;
354a8fe65b8SJeff Kirsher 
355a8fe65b8SJeff Kirsher 	res = register_netdev(dev);
356a8fe65b8SJeff Kirsher 	if (res) {
357a8fe65b8SJeff Kirsher 		free_netdev(dev);
358a8fe65b8SJeff Kirsher 		return res;
359a8fe65b8SJeff Kirsher 	}
360a8fe65b8SJeff Kirsher 
361a8fe65b8SJeff Kirsher 	lp->next_module = root_atp_dev;
362a8fe65b8SJeff Kirsher 	root_atp_dev = dev;
363a8fe65b8SJeff Kirsher 
364a8fe65b8SJeff Kirsher 	return 0;
365a8fe65b8SJeff Kirsher }
366a8fe65b8SJeff Kirsher 
367a8fe65b8SJeff Kirsher /* Read the station address PROM, usually a word-wide EEPROM. */
368a8fe65b8SJeff Kirsher static void __init get_node_ID(struct net_device *dev)
369a8fe65b8SJeff Kirsher {
370a8fe65b8SJeff Kirsher 	long ioaddr = dev->base_addr;
371a8fe65b8SJeff Kirsher 	int sa_offset = 0;
372a8fe65b8SJeff Kirsher 	int i;
373a8fe65b8SJeff Kirsher 
374a8fe65b8SJeff Kirsher 	write_reg(ioaddr, CMR2, CMR2_EEPROM);	  /* Point to the EEPROM control registers. */
375a8fe65b8SJeff Kirsher 
376a8fe65b8SJeff Kirsher 	/* Some adapters have the station address at offset 15 instead of offset
377a8fe65b8SJeff Kirsher 	   zero.  Check for it, and fix it if needed. */
378a8fe65b8SJeff Kirsher 	if (eeprom_op(ioaddr, EE_READ(0)) == 0xffff)
379a8fe65b8SJeff Kirsher 		sa_offset = 15;
380a8fe65b8SJeff Kirsher 
381a8fe65b8SJeff Kirsher 	for (i = 0; i < 3; i++)
382a8fe65b8SJeff Kirsher 		((__be16 *)dev->dev_addr)[i] =
383a8fe65b8SJeff Kirsher 			cpu_to_be16(eeprom_op(ioaddr, EE_READ(sa_offset + i)));
384a8fe65b8SJeff Kirsher 
385a8fe65b8SJeff Kirsher 	write_reg(ioaddr, CMR2, CMR2_NULL);
386a8fe65b8SJeff Kirsher }
387a8fe65b8SJeff Kirsher 
388a8fe65b8SJeff Kirsher /*
389a8fe65b8SJeff Kirsher   An EEPROM read command starts by shifting out 0x60+address, and then
390a8fe65b8SJeff Kirsher   shifting in the serial data. See the NatSemi databook for details.
391a8fe65b8SJeff Kirsher  *		   ________________
392a8fe65b8SJeff Kirsher  * CS : __|
393a8fe65b8SJeff Kirsher  *			   ___	   ___
394a8fe65b8SJeff Kirsher  * CLK: ______|	  |___|	  |
395a8fe65b8SJeff Kirsher  *		 __ _______ _______
396a8fe65b8SJeff Kirsher  * DI :	 __X_______X_______X
397a8fe65b8SJeff Kirsher  * DO :	 _________X_______X
398a8fe65b8SJeff Kirsher  */
399a8fe65b8SJeff Kirsher 
400a8fe65b8SJeff Kirsher static unsigned short __init eeprom_op(long ioaddr, u32 cmd)
401a8fe65b8SJeff Kirsher {
402a8fe65b8SJeff Kirsher 	unsigned eedata_out = 0;
403a8fe65b8SJeff Kirsher 	int num_bits = EE_CMD_SIZE;
404a8fe65b8SJeff Kirsher 
405a8fe65b8SJeff Kirsher 	while (--num_bits >= 0) {
406a8fe65b8SJeff Kirsher 		char outval = (cmd & (1<<num_bits)) ? EE_DATA_WRITE : 0;
407a8fe65b8SJeff Kirsher 		write_reg_high(ioaddr, PROM_CMD, outval | EE_CLK_LOW);
408a8fe65b8SJeff Kirsher 		write_reg_high(ioaddr, PROM_CMD, outval | EE_CLK_HIGH);
409a8fe65b8SJeff Kirsher 		eedata_out <<= 1;
410a8fe65b8SJeff Kirsher 		if (read_nibble(ioaddr, PROM_DATA) & EE_DATA_READ)
411a8fe65b8SJeff Kirsher 			eedata_out++;
412a8fe65b8SJeff Kirsher 	}
413a8fe65b8SJeff Kirsher 	write_reg_high(ioaddr, PROM_CMD, EE_CLK_LOW & ~EE_CS);
414a8fe65b8SJeff Kirsher 	return eedata_out;
415a8fe65b8SJeff Kirsher }
416a8fe65b8SJeff Kirsher 
417a8fe65b8SJeff Kirsher 
418a8fe65b8SJeff Kirsher /* Open/initialize the board.  This is called (in the current kernel)
419a8fe65b8SJeff Kirsher    sometime after booting when the 'ifconfig' program is run.
420a8fe65b8SJeff Kirsher 
421a8fe65b8SJeff Kirsher    This routine sets everything up anew at each open, even
422a8fe65b8SJeff Kirsher    registers that "should" only need to be set once at boot, so that
423a8fe65b8SJeff Kirsher    there is non-reboot way to recover if something goes wrong.
424a8fe65b8SJeff Kirsher 
425a8fe65b8SJeff Kirsher    This is an attachable device: if there is no private entry then it wasn't
426a8fe65b8SJeff Kirsher    probed for at boot-time, and we need to probe for it again.
427a8fe65b8SJeff Kirsher    */
428a8fe65b8SJeff Kirsher static int net_open(struct net_device *dev)
429a8fe65b8SJeff Kirsher {
430a8fe65b8SJeff Kirsher 	struct net_local *lp = netdev_priv(dev);
431a8fe65b8SJeff Kirsher 	int ret;
432a8fe65b8SJeff Kirsher 
433a8fe65b8SJeff Kirsher 	/* The interrupt line is turned off (tri-stated) when the device isn't in
434a8fe65b8SJeff Kirsher 	   use.  That's especially important for "attached" interfaces where the
435a8fe65b8SJeff Kirsher 	   port or interrupt may be shared. */
436a8fe65b8SJeff Kirsher 	ret = request_irq(dev->irq, atp_interrupt, 0, dev->name, dev);
437a8fe65b8SJeff Kirsher 	if (ret)
438a8fe65b8SJeff Kirsher 		return ret;
439a8fe65b8SJeff Kirsher 
440a8fe65b8SJeff Kirsher 	hardware_init(dev);
441a8fe65b8SJeff Kirsher 
4429de36ccfSKees Cook 	lp->dev = dev;
4439de36ccfSKees Cook 	timer_setup(&lp->timer, atp_timed_checker, 0);
444a8fe65b8SJeff Kirsher 	lp->timer.expires = jiffies + TIMED_CHECKER;
445a8fe65b8SJeff Kirsher 	add_timer(&lp->timer);
446a8fe65b8SJeff Kirsher 
447a8fe65b8SJeff Kirsher 	netif_start_queue(dev);
448a8fe65b8SJeff Kirsher 	return 0;
449a8fe65b8SJeff Kirsher }
450a8fe65b8SJeff Kirsher 
451a8fe65b8SJeff Kirsher /* This routine resets the hardware.  We initialize everything, assuming that
452a8fe65b8SJeff Kirsher    the hardware may have been temporarily detached. */
453a8fe65b8SJeff Kirsher static void hardware_init(struct net_device *dev)
454a8fe65b8SJeff Kirsher {
455a8fe65b8SJeff Kirsher 	struct net_local *lp = netdev_priv(dev);
456a8fe65b8SJeff Kirsher 	long ioaddr = dev->base_addr;
457a8fe65b8SJeff Kirsher     int i;
458a8fe65b8SJeff Kirsher 
459a8fe65b8SJeff Kirsher 	/* Turn off the printer multiplexer on the 8012. */
460a8fe65b8SJeff Kirsher 	for (i = 0; i < 8; i++)
461a8fe65b8SJeff Kirsher 		outb(mux_8012[i], ioaddr + PAR_DATA);
462a8fe65b8SJeff Kirsher 	write_reg_high(ioaddr, CMR1, CMR1h_RESET);
463a8fe65b8SJeff Kirsher 
464a8fe65b8SJeff Kirsher     for (i = 0; i < 6; i++)
465a8fe65b8SJeff Kirsher 		write_reg_byte(ioaddr, PAR0 + i, dev->dev_addr[i]);
466a8fe65b8SJeff Kirsher 
467a8fe65b8SJeff Kirsher 	write_reg_high(ioaddr, CMR2, lp->addr_mode);
468a8fe65b8SJeff Kirsher 
469a8fe65b8SJeff Kirsher 	if (net_debug > 2) {
470a8fe65b8SJeff Kirsher 		printk(KERN_DEBUG "%s: Reset: current Rx mode %d.\n", dev->name,
471a8fe65b8SJeff Kirsher 			   (read_nibble(ioaddr, CMR2_h) >> 3) & 0x0f);
472a8fe65b8SJeff Kirsher 	}
473a8fe65b8SJeff Kirsher 
474a8fe65b8SJeff Kirsher     write_reg(ioaddr, CMR2, CMR2_IRQOUT);
475a8fe65b8SJeff Kirsher     write_reg_high(ioaddr, CMR1, CMR1h_RxENABLE | CMR1h_TxENABLE);
476a8fe65b8SJeff Kirsher 
477a8fe65b8SJeff Kirsher 	/* Enable the interrupt line from the serial port. */
478a8fe65b8SJeff Kirsher 	outb(Ctrl_SelData + Ctrl_IRQEN, ioaddr + PAR_CONTROL);
479a8fe65b8SJeff Kirsher 
480a8fe65b8SJeff Kirsher 	/* Unmask the interesting interrupts. */
481a8fe65b8SJeff Kirsher     write_reg(ioaddr, IMR, ISR_RxOK | ISR_TxErr | ISR_TxOK);
482a8fe65b8SJeff Kirsher     write_reg_high(ioaddr, IMR, ISRh_RxErr);
483a8fe65b8SJeff Kirsher 
484a8fe65b8SJeff Kirsher 	lp->tx_unit_busy = 0;
485a8fe65b8SJeff Kirsher     lp->pac_cnt_in_tx_buf = 0;
486a8fe65b8SJeff Kirsher 	lp->saved_tx_size = 0;
487a8fe65b8SJeff Kirsher }
488a8fe65b8SJeff Kirsher 
489a8fe65b8SJeff Kirsher static void trigger_send(long ioaddr, int length)
490a8fe65b8SJeff Kirsher {
491a8fe65b8SJeff Kirsher 	write_reg_byte(ioaddr, TxCNT0, length & 0xff);
492a8fe65b8SJeff Kirsher 	write_reg(ioaddr, TxCNT1, length >> 8);
493a8fe65b8SJeff Kirsher 	write_reg(ioaddr, CMR1, CMR1_Xmit);
494a8fe65b8SJeff Kirsher }
495a8fe65b8SJeff Kirsher 
496a8fe65b8SJeff Kirsher static void write_packet(long ioaddr, int length, unsigned char *packet, int pad_len, int data_mode)
497a8fe65b8SJeff Kirsher {
498a8fe65b8SJeff Kirsher     if (length & 1)
499a8fe65b8SJeff Kirsher     {
500a8fe65b8SJeff Kirsher     	length++;
501a8fe65b8SJeff Kirsher     	pad_len++;
502a8fe65b8SJeff Kirsher     }
503a8fe65b8SJeff Kirsher 
504a8fe65b8SJeff Kirsher     outb(EOC+MAR, ioaddr + PAR_DATA);
505a8fe65b8SJeff Kirsher     if ((data_mode & 1) == 0) {
506a8fe65b8SJeff Kirsher 		/* Write the packet out, starting with the write addr. */
507a8fe65b8SJeff Kirsher 		outb(WrAddr+MAR, ioaddr + PAR_DATA);
508a8fe65b8SJeff Kirsher 		do {
509a8fe65b8SJeff Kirsher 			write_byte_mode0(ioaddr, *packet++);
510a8fe65b8SJeff Kirsher 		} while (--length > pad_len) ;
511a8fe65b8SJeff Kirsher 		do {
512a8fe65b8SJeff Kirsher 			write_byte_mode0(ioaddr, 0);
513a8fe65b8SJeff Kirsher 		} while (--length > 0) ;
514a8fe65b8SJeff Kirsher     } else {
515a8fe65b8SJeff Kirsher 		/* Write the packet out in slow mode. */
516a8fe65b8SJeff Kirsher 		unsigned char outbyte = *packet++;
517a8fe65b8SJeff Kirsher 
518a8fe65b8SJeff Kirsher 		outb(Ctrl_LNibWrite + Ctrl_IRQEN, ioaddr + PAR_CONTROL);
519a8fe65b8SJeff Kirsher 		outb(WrAddr+MAR, ioaddr + PAR_DATA);
520a8fe65b8SJeff Kirsher 
521a8fe65b8SJeff Kirsher 		outb((outbyte & 0x0f)|0x40, ioaddr + PAR_DATA);
522a8fe65b8SJeff Kirsher 		outb(outbyte & 0x0f, ioaddr + PAR_DATA);
523a8fe65b8SJeff Kirsher 		outbyte >>= 4;
524a8fe65b8SJeff Kirsher 		outb(outbyte & 0x0f, ioaddr + PAR_DATA);
525a8fe65b8SJeff Kirsher 		outb(Ctrl_HNibWrite + Ctrl_IRQEN, ioaddr + PAR_CONTROL);
526a8fe65b8SJeff Kirsher 		while (--length > pad_len)
527a8fe65b8SJeff Kirsher 			write_byte_mode1(ioaddr, *packet++);
528a8fe65b8SJeff Kirsher 		while (--length > 0)
529a8fe65b8SJeff Kirsher 			write_byte_mode1(ioaddr, 0);
530a8fe65b8SJeff Kirsher     }
531a8fe65b8SJeff Kirsher     /* Terminate the Tx frame.  End of write: ECB. */
532a8fe65b8SJeff Kirsher     outb(0xff, ioaddr + PAR_DATA);
533a8fe65b8SJeff Kirsher     outb(Ctrl_HNibWrite | Ctrl_SelData | Ctrl_IRQEN, ioaddr + PAR_CONTROL);
534a8fe65b8SJeff Kirsher }
535a8fe65b8SJeff Kirsher 
536a8fe65b8SJeff Kirsher static void tx_timeout(struct net_device *dev)
537a8fe65b8SJeff Kirsher {
538a8fe65b8SJeff Kirsher 	long ioaddr = dev->base_addr;
539a8fe65b8SJeff Kirsher 
540a8fe65b8SJeff Kirsher 	printk(KERN_WARNING "%s: Transmit timed out, %s?\n", dev->name,
541a8fe65b8SJeff Kirsher 		   inb(ioaddr + PAR_CONTROL) & 0x10 ? "network cable problem"
542a8fe65b8SJeff Kirsher 		   :  "IRQ conflict");
543a8fe65b8SJeff Kirsher 	dev->stats.tx_errors++;
544a8fe65b8SJeff Kirsher 	/* Try to restart the adapter. */
545a8fe65b8SJeff Kirsher 	hardware_init(dev);
546860e9538SFlorian Westphal 	netif_trans_update(dev); /* prevent tx timeout */
547a8fe65b8SJeff Kirsher 	netif_wake_queue(dev);
548a8fe65b8SJeff Kirsher 	dev->stats.tx_errors++;
549a8fe65b8SJeff Kirsher }
550a8fe65b8SJeff Kirsher 
551a8fe65b8SJeff Kirsher static netdev_tx_t atp_send_packet(struct sk_buff *skb,
552a8fe65b8SJeff Kirsher 				   struct net_device *dev)
553a8fe65b8SJeff Kirsher {
554a8fe65b8SJeff Kirsher 	struct net_local *lp = netdev_priv(dev);
555a8fe65b8SJeff Kirsher 	long ioaddr = dev->base_addr;
556a8fe65b8SJeff Kirsher 	int length;
557a8fe65b8SJeff Kirsher 	unsigned long flags;
558a8fe65b8SJeff Kirsher 
559a8fe65b8SJeff Kirsher 	length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
560a8fe65b8SJeff Kirsher 
561a8fe65b8SJeff Kirsher 	netif_stop_queue(dev);
562a8fe65b8SJeff Kirsher 
563a8fe65b8SJeff Kirsher 	/* Disable interrupts by writing 0x00 to the Interrupt Mask Register.
564a8fe65b8SJeff Kirsher 	   This sequence must not be interrupted by an incoming packet. */
565a8fe65b8SJeff Kirsher 
566a8fe65b8SJeff Kirsher 	spin_lock_irqsave(&lp->lock, flags);
567a8fe65b8SJeff Kirsher 	write_reg(ioaddr, IMR, 0);
568a8fe65b8SJeff Kirsher 	write_reg_high(ioaddr, IMR, 0);
569a8fe65b8SJeff Kirsher 	spin_unlock_irqrestore(&lp->lock, flags);
570a8fe65b8SJeff Kirsher 
571a8fe65b8SJeff Kirsher 	write_packet(ioaddr, length, skb->data, length-skb->len, dev->if_port);
572a8fe65b8SJeff Kirsher 
573a8fe65b8SJeff Kirsher 	lp->pac_cnt_in_tx_buf++;
574a8fe65b8SJeff Kirsher 	if (lp->tx_unit_busy == 0) {
575a8fe65b8SJeff Kirsher 		trigger_send(ioaddr, length);
576a8fe65b8SJeff Kirsher 		lp->saved_tx_size = 0; 				/* Redundant */
577a8fe65b8SJeff Kirsher 		lp->re_tx = 0;
578a8fe65b8SJeff Kirsher 		lp->tx_unit_busy = 1;
579a8fe65b8SJeff Kirsher 	} else
580a8fe65b8SJeff Kirsher 		lp->saved_tx_size = length;
581a8fe65b8SJeff Kirsher 	/* Re-enable the LPT interrupts. */
582a8fe65b8SJeff Kirsher 	write_reg(ioaddr, IMR, ISR_RxOK | ISR_TxErr | ISR_TxOK);
583a8fe65b8SJeff Kirsher 	write_reg_high(ioaddr, IMR, ISRh_RxErr);
584a8fe65b8SJeff Kirsher 
585a8fe65b8SJeff Kirsher 	dev_kfree_skb (skb);
586a8fe65b8SJeff Kirsher 	return NETDEV_TX_OK;
587a8fe65b8SJeff Kirsher }
588a8fe65b8SJeff Kirsher 
589a8fe65b8SJeff Kirsher 
590a8fe65b8SJeff Kirsher /* The typical workload of the driver:
591a8fe65b8SJeff Kirsher    Handle the network interface interrupts. */
592a8fe65b8SJeff Kirsher static irqreturn_t atp_interrupt(int irq, void *dev_instance)
593a8fe65b8SJeff Kirsher {
594a8fe65b8SJeff Kirsher 	struct net_device *dev = dev_instance;
595a8fe65b8SJeff Kirsher 	struct net_local *lp;
596a8fe65b8SJeff Kirsher 	long ioaddr;
597a8fe65b8SJeff Kirsher 	static int num_tx_since_rx;
598a8fe65b8SJeff Kirsher 	int boguscount = max_interrupt_work;
599a8fe65b8SJeff Kirsher 	int handled = 0;
600a8fe65b8SJeff Kirsher 
601a8fe65b8SJeff Kirsher 	ioaddr = dev->base_addr;
602a8fe65b8SJeff Kirsher 	lp = netdev_priv(dev);
603a8fe65b8SJeff Kirsher 
604a8fe65b8SJeff Kirsher 	spin_lock(&lp->lock);
605a8fe65b8SJeff Kirsher 
606a8fe65b8SJeff Kirsher 	/* Disable additional spurious interrupts. */
607a8fe65b8SJeff Kirsher 	outb(Ctrl_SelData, ioaddr + PAR_CONTROL);
608a8fe65b8SJeff Kirsher 
609a8fe65b8SJeff Kirsher 	/* The adapter's output is currently the IRQ line, switch it to data. */
610a8fe65b8SJeff Kirsher 	write_reg(ioaddr, CMR2, CMR2_NULL);
611a8fe65b8SJeff Kirsher 	write_reg(ioaddr, IMR, 0);
612a8fe65b8SJeff Kirsher 
613a8fe65b8SJeff Kirsher 	if (net_debug > 5) printk(KERN_DEBUG "%s: In interrupt ", dev->name);
614a8fe65b8SJeff Kirsher     while (--boguscount > 0) {
615a8fe65b8SJeff Kirsher 		int status = read_nibble(ioaddr, ISR);
616a8fe65b8SJeff Kirsher 		if (net_debug > 5) printk("loop status %02x..", status);
617a8fe65b8SJeff Kirsher 
618a8fe65b8SJeff Kirsher 		if (status & (ISR_RxOK<<3)) {
619a8fe65b8SJeff Kirsher 			handled = 1;
620a8fe65b8SJeff Kirsher 			write_reg(ioaddr, ISR, ISR_RxOK); /* Clear the Rx interrupt. */
621a8fe65b8SJeff Kirsher 			do {
622a8fe65b8SJeff Kirsher 				int read_status = read_nibble(ioaddr, CMR1);
623a8fe65b8SJeff Kirsher 				if (net_debug > 6)
624a8fe65b8SJeff Kirsher 					printk("handling Rx packet %02x..", read_status);
625a8fe65b8SJeff Kirsher 				/* We acknowledged the normal Rx interrupt, so if the interrupt
626a8fe65b8SJeff Kirsher 				   is still outstanding we must have a Rx error. */
627a8fe65b8SJeff Kirsher 				if (read_status & (CMR1_IRQ << 3)) { /* Overrun. */
628a8fe65b8SJeff Kirsher 					dev->stats.rx_over_errors++;
629a8fe65b8SJeff Kirsher 					/* Set to no-accept mode long enough to remove a packet. */
630a8fe65b8SJeff Kirsher 					write_reg_high(ioaddr, CMR2, CMR2h_OFF);
631a8fe65b8SJeff Kirsher 					net_rx(dev);
632a8fe65b8SJeff Kirsher 					/* Clear the interrupt and return to normal Rx mode. */
633a8fe65b8SJeff Kirsher 					write_reg_high(ioaddr, ISR, ISRh_RxErr);
634a8fe65b8SJeff Kirsher 					write_reg_high(ioaddr, CMR2, lp->addr_mode);
635a8fe65b8SJeff Kirsher 				} else if ((read_status & (CMR1_BufEnb << 3)) == 0) {
636a8fe65b8SJeff Kirsher 					net_rx(dev);
637a8fe65b8SJeff Kirsher 					num_tx_since_rx = 0;
638a8fe65b8SJeff Kirsher 				} else
639a8fe65b8SJeff Kirsher 					break;
640a8fe65b8SJeff Kirsher 			} while (--boguscount > 0);
641a8fe65b8SJeff Kirsher 		} else if (status & ((ISR_TxErr + ISR_TxOK)<<3)) {
642a8fe65b8SJeff Kirsher 			handled = 1;
643a8fe65b8SJeff Kirsher 			if (net_debug > 6)  printk("handling Tx done..");
644a8fe65b8SJeff Kirsher 			/* Clear the Tx interrupt.  We should check for too many failures
645a8fe65b8SJeff Kirsher 			   and reinitialize the adapter. */
646a8fe65b8SJeff Kirsher 			write_reg(ioaddr, ISR, ISR_TxErr + ISR_TxOK);
647a8fe65b8SJeff Kirsher 			if (status & (ISR_TxErr<<3)) {
648a8fe65b8SJeff Kirsher 				dev->stats.collisions++;
649a8fe65b8SJeff Kirsher 				if (++lp->re_tx > 15) {
650a8fe65b8SJeff Kirsher 					dev->stats.tx_aborted_errors++;
651a8fe65b8SJeff Kirsher 					hardware_init(dev);
652a8fe65b8SJeff Kirsher 					break;
653a8fe65b8SJeff Kirsher 				}
654a8fe65b8SJeff Kirsher 				/* Attempt to retransmit. */
655a8fe65b8SJeff Kirsher 				if (net_debug > 6)  printk("attempting to ReTx");
656a8fe65b8SJeff Kirsher 				write_reg(ioaddr, CMR1, CMR1_ReXmit + CMR1_Xmit);
657a8fe65b8SJeff Kirsher 			} else {
658a8fe65b8SJeff Kirsher 				/* Finish up the transmit. */
659a8fe65b8SJeff Kirsher 				dev->stats.tx_packets++;
660a8fe65b8SJeff Kirsher 				lp->pac_cnt_in_tx_buf--;
661a8fe65b8SJeff Kirsher 				if ( lp->saved_tx_size) {
662a8fe65b8SJeff Kirsher 					trigger_send(ioaddr, lp->saved_tx_size);
663a8fe65b8SJeff Kirsher 					lp->saved_tx_size = 0;
664a8fe65b8SJeff Kirsher 					lp->re_tx = 0;
665a8fe65b8SJeff Kirsher 				} else
666a8fe65b8SJeff Kirsher 					lp->tx_unit_busy = 0;
667a8fe65b8SJeff Kirsher 				netif_wake_queue(dev);	/* Inform upper layers. */
668a8fe65b8SJeff Kirsher 			}
669a8fe65b8SJeff Kirsher 			num_tx_since_rx++;
670a8fe65b8SJeff Kirsher 		} else if (num_tx_since_rx > 8 &&
6714a7c9726STobias Klauser 			   time_after(jiffies, lp->last_rx_time + HZ)) {
672a8fe65b8SJeff Kirsher 			if (net_debug > 2)
673a8fe65b8SJeff Kirsher 				printk(KERN_DEBUG "%s: Missed packet? No Rx after %d Tx and "
674a8fe65b8SJeff Kirsher 					   "%ld jiffies status %02x  CMR1 %02x.\n", dev->name,
6754a7c9726STobias Klauser 					   num_tx_since_rx, jiffies - lp->last_rx_time, status,
676a8fe65b8SJeff Kirsher 					   (read_nibble(ioaddr, CMR1) >> 3) & 15);
677a8fe65b8SJeff Kirsher 			dev->stats.rx_missed_errors++;
678a8fe65b8SJeff Kirsher 			hardware_init(dev);
679a8fe65b8SJeff Kirsher 			num_tx_since_rx = 0;
680a8fe65b8SJeff Kirsher 			break;
681a8fe65b8SJeff Kirsher 		} else
682a8fe65b8SJeff Kirsher 			break;
683a8fe65b8SJeff Kirsher     }
684a8fe65b8SJeff Kirsher 
685a8fe65b8SJeff Kirsher 	/* This following code fixes a rare (and very difficult to track down)
686a8fe65b8SJeff Kirsher 	   problem where the adapter forgets its ethernet address. */
687a8fe65b8SJeff Kirsher 	{
688a8fe65b8SJeff Kirsher 		int i;
689a8fe65b8SJeff Kirsher 		for (i = 0; i < 6; i++)
690a8fe65b8SJeff Kirsher 			write_reg_byte(ioaddr, PAR0 + i, dev->dev_addr[i]);
691a8fe65b8SJeff Kirsher #if 0 && defined(TIMED_CHECKER)
692a8fe65b8SJeff Kirsher 		mod_timer(&lp->timer, jiffies + TIMED_CHECKER);
693a8fe65b8SJeff Kirsher #endif
694a8fe65b8SJeff Kirsher 	}
695a8fe65b8SJeff Kirsher 
696a8fe65b8SJeff Kirsher 	/* Tell the adapter that it can go back to using the output line as IRQ. */
697a8fe65b8SJeff Kirsher     write_reg(ioaddr, CMR2, CMR2_IRQOUT);
698a8fe65b8SJeff Kirsher 	/* Enable the physical interrupt line, which is sure to be low until.. */
699a8fe65b8SJeff Kirsher 	outb(Ctrl_SelData + Ctrl_IRQEN, ioaddr + PAR_CONTROL);
700a8fe65b8SJeff Kirsher 	/* .. we enable the interrupt sources. */
701a8fe65b8SJeff Kirsher 	write_reg(ioaddr, IMR, ISR_RxOK | ISR_TxErr | ISR_TxOK);
702a8fe65b8SJeff Kirsher 	write_reg_high(ioaddr, IMR, ISRh_RxErr); 			/* Hmmm, really needed? */
703a8fe65b8SJeff Kirsher 
704a8fe65b8SJeff Kirsher 	spin_unlock(&lp->lock);
705a8fe65b8SJeff Kirsher 
706a8fe65b8SJeff Kirsher 	if (net_debug > 5) printk("exiting interrupt.\n");
707a8fe65b8SJeff Kirsher 	return IRQ_RETVAL(handled);
708a8fe65b8SJeff Kirsher }
709a8fe65b8SJeff Kirsher 
710a8fe65b8SJeff Kirsher #ifdef TIMED_CHECKER
711a8fe65b8SJeff Kirsher /* This following code fixes a rare (and very difficult to track down)
712a8fe65b8SJeff Kirsher    problem where the adapter forgets its ethernet address. */
7139de36ccfSKees Cook static void atp_timed_checker(struct timer_list *t)
714a8fe65b8SJeff Kirsher {
7159de36ccfSKees Cook 	struct net_local *lp = from_timer(lp, t, timer);
7169de36ccfSKees Cook 	struct net_device *dev = lp->dev;
717a8fe65b8SJeff Kirsher 	long ioaddr = dev->base_addr;
718a8fe65b8SJeff Kirsher 	int tickssofar = jiffies - lp->last_rx_time;
719a8fe65b8SJeff Kirsher 	int i;
720a8fe65b8SJeff Kirsher 
721a8fe65b8SJeff Kirsher 	spin_lock(&lp->lock);
722a8fe65b8SJeff Kirsher 	if (tickssofar > 2*HZ) {
723a8fe65b8SJeff Kirsher #if 1
724a8fe65b8SJeff Kirsher 		for (i = 0; i < 6; i++)
725a8fe65b8SJeff Kirsher 			write_reg_byte(ioaddr, PAR0 + i, dev->dev_addr[i]);
726a8fe65b8SJeff Kirsher 		lp->last_rx_time = jiffies;
727a8fe65b8SJeff Kirsher #else
728a8fe65b8SJeff Kirsher 		for (i = 0; i < 6; i++)
729a8fe65b8SJeff Kirsher 			if (read_cmd_byte(ioaddr, PAR0 + i) != atp_timed_dev->dev_addr[i])
730a8fe65b8SJeff Kirsher 				{
731a8fe65b8SJeff Kirsher 			struct net_local *lp = netdev_priv(atp_timed_dev);
732a8fe65b8SJeff Kirsher 			write_reg_byte(ioaddr, PAR0 + i, atp_timed_dev->dev_addr[i]);
733a8fe65b8SJeff Kirsher 			if (i == 2)
734a8fe65b8SJeff Kirsher 			  dev->stats.tx_errors++;
735a8fe65b8SJeff Kirsher 			else if (i == 3)
736a8fe65b8SJeff Kirsher 			  dev->stats.tx_dropped++;
737a8fe65b8SJeff Kirsher 			else if (i == 4)
738a8fe65b8SJeff Kirsher 			  dev->stats.collisions++;
739a8fe65b8SJeff Kirsher 			else
740a8fe65b8SJeff Kirsher 			  dev->stats.rx_errors++;
741a8fe65b8SJeff Kirsher 		  }
742a8fe65b8SJeff Kirsher #endif
743a8fe65b8SJeff Kirsher 	}
744a8fe65b8SJeff Kirsher 	spin_unlock(&lp->lock);
745a8fe65b8SJeff Kirsher 	lp->timer.expires = jiffies + TIMED_CHECKER;
746a8fe65b8SJeff Kirsher 	add_timer(&lp->timer);
747a8fe65b8SJeff Kirsher }
748a8fe65b8SJeff Kirsher #endif
749a8fe65b8SJeff Kirsher 
750a8fe65b8SJeff Kirsher /* We have a good packet(s), get it/them out of the buffers. */
751a8fe65b8SJeff Kirsher static void net_rx(struct net_device *dev)
752a8fe65b8SJeff Kirsher {
753a8fe65b8SJeff Kirsher 	struct net_local *lp = netdev_priv(dev);
754a8fe65b8SJeff Kirsher 	long ioaddr = dev->base_addr;
755a8fe65b8SJeff Kirsher 	struct rx_header rx_head;
756a8fe65b8SJeff Kirsher 
757a8fe65b8SJeff Kirsher 	/* Process the received packet. */
758a8fe65b8SJeff Kirsher 	outb(EOC+MAR, ioaddr + PAR_DATA);
759a8fe65b8SJeff Kirsher 	read_block(ioaddr, 8, (unsigned char*)&rx_head, dev->if_port);
760a8fe65b8SJeff Kirsher 	if (net_debug > 5)
761a8fe65b8SJeff Kirsher 		printk(KERN_DEBUG " rx_count %04x %04x %04x %04x..", rx_head.pad,
762a8fe65b8SJeff Kirsher 			   rx_head.rx_count, rx_head.rx_status, rx_head.cur_addr);
763a8fe65b8SJeff Kirsher 	if ((rx_head.rx_status & 0x77) != 0x01) {
764a8fe65b8SJeff Kirsher 		dev->stats.rx_errors++;
765a8fe65b8SJeff Kirsher 		if (rx_head.rx_status & 0x0004) dev->stats.rx_frame_errors++;
766a8fe65b8SJeff Kirsher 		else if (rx_head.rx_status & 0x0002) dev->stats.rx_crc_errors++;
767a8fe65b8SJeff Kirsher 		if (net_debug > 3)
768a8fe65b8SJeff Kirsher 			printk(KERN_DEBUG "%s: Unknown ATP Rx error %04x.\n",
769a8fe65b8SJeff Kirsher 				   dev->name, rx_head.rx_status);
770a8fe65b8SJeff Kirsher 		if  (rx_head.rx_status & 0x0020) {
771a8fe65b8SJeff Kirsher 			dev->stats.rx_fifo_errors++;
772a8fe65b8SJeff Kirsher 			write_reg_high(ioaddr, CMR1, CMR1h_TxENABLE);
773a8fe65b8SJeff Kirsher 			write_reg_high(ioaddr, CMR1, CMR1h_RxENABLE | CMR1h_TxENABLE);
774a8fe65b8SJeff Kirsher 		} else if (rx_head.rx_status & 0x0050)
775a8fe65b8SJeff Kirsher 			hardware_init(dev);
776a8fe65b8SJeff Kirsher 		return;
777a8fe65b8SJeff Kirsher 	} else {
778a8fe65b8SJeff Kirsher 		/* Malloc up new buffer. The "-4" omits the FCS (CRC). */
779a8fe65b8SJeff Kirsher 		int pkt_len = (rx_head.rx_count & 0x7ff) - 4;
780a8fe65b8SJeff Kirsher 		struct sk_buff *skb;
781a8fe65b8SJeff Kirsher 
782dae2e9f4SPradeep A. Dalvi 		skb = netdev_alloc_skb(dev, pkt_len + 2);
783a8fe65b8SJeff Kirsher 		if (skb == NULL) {
784a8fe65b8SJeff Kirsher 			dev->stats.rx_dropped++;
785a8fe65b8SJeff Kirsher 			goto done;
786a8fe65b8SJeff Kirsher 		}
787a8fe65b8SJeff Kirsher 
788a8fe65b8SJeff Kirsher 		skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
789a8fe65b8SJeff Kirsher 		read_block(ioaddr, pkt_len, skb_put(skb,pkt_len), dev->if_port);
790a8fe65b8SJeff Kirsher 		skb->protocol = eth_type_trans(skb, dev);
791a8fe65b8SJeff Kirsher 		netif_rx(skb);
792a8fe65b8SJeff Kirsher 		dev->stats.rx_packets++;
793a8fe65b8SJeff Kirsher 		dev->stats.rx_bytes += pkt_len;
794a8fe65b8SJeff Kirsher 	}
795a8fe65b8SJeff Kirsher  done:
796a8fe65b8SJeff Kirsher 	write_reg(ioaddr, CMR1, CMR1_NextPkt);
797a8fe65b8SJeff Kirsher 	lp->last_rx_time = jiffies;
798a8fe65b8SJeff Kirsher }
799a8fe65b8SJeff Kirsher 
800a8fe65b8SJeff Kirsher static void read_block(long ioaddr, int length, unsigned char *p, int data_mode)
801a8fe65b8SJeff Kirsher {
802a8fe65b8SJeff Kirsher 	if (data_mode <= 3) { /* Mode 0 or 1 */
803a8fe65b8SJeff Kirsher 		outb(Ctrl_LNibRead, ioaddr + PAR_CONTROL);
804a8fe65b8SJeff Kirsher 		outb(length == 8  ?  RdAddr | HNib | MAR  :  RdAddr | MAR,
805a8fe65b8SJeff Kirsher 			 ioaddr + PAR_DATA);
806a8fe65b8SJeff Kirsher 		if (data_mode <= 1) { /* Mode 0 or 1 */
807a8fe65b8SJeff Kirsher 			do { *p++ = read_byte_mode0(ioaddr); } while (--length > 0);
808a8fe65b8SJeff Kirsher 		} else { /* Mode 2 or 3 */
809a8fe65b8SJeff Kirsher 			do { *p++ = read_byte_mode2(ioaddr); } while (--length > 0);
810a8fe65b8SJeff Kirsher 		}
811a8fe65b8SJeff Kirsher 	} else if (data_mode <= 5) {
812a8fe65b8SJeff Kirsher 		do { *p++ = read_byte_mode4(ioaddr); } while (--length > 0);
813a8fe65b8SJeff Kirsher 	} else {
814a8fe65b8SJeff Kirsher 		do { *p++ = read_byte_mode6(ioaddr); } while (--length > 0);
815a8fe65b8SJeff Kirsher 	}
816a8fe65b8SJeff Kirsher 
817a8fe65b8SJeff Kirsher 	outb(EOC+HNib+MAR, ioaddr + PAR_DATA);
818a8fe65b8SJeff Kirsher 	outb(Ctrl_SelData, ioaddr + PAR_CONTROL);
819a8fe65b8SJeff Kirsher }
820a8fe65b8SJeff Kirsher 
821a8fe65b8SJeff Kirsher /* The inverse routine to net_open(). */
822a8fe65b8SJeff Kirsher static int
823a8fe65b8SJeff Kirsher net_close(struct net_device *dev)
824a8fe65b8SJeff Kirsher {
825a8fe65b8SJeff Kirsher 	struct net_local *lp = netdev_priv(dev);
826a8fe65b8SJeff Kirsher 	long ioaddr = dev->base_addr;
827a8fe65b8SJeff Kirsher 
828a8fe65b8SJeff Kirsher 	netif_stop_queue(dev);
829a8fe65b8SJeff Kirsher 
830a8fe65b8SJeff Kirsher 	del_timer_sync(&lp->timer);
831a8fe65b8SJeff Kirsher 
832a8fe65b8SJeff Kirsher 	/* Flush the Tx and disable Rx here. */
833a8fe65b8SJeff Kirsher 	lp->addr_mode = CMR2h_OFF;
834a8fe65b8SJeff Kirsher 	write_reg_high(ioaddr, CMR2, CMR2h_OFF);
835a8fe65b8SJeff Kirsher 
836a8fe65b8SJeff Kirsher 	/* Free the IRQ line. */
837a8fe65b8SJeff Kirsher 	outb(0x00, ioaddr + PAR_CONTROL);
838a8fe65b8SJeff Kirsher 	free_irq(dev->irq, dev);
839a8fe65b8SJeff Kirsher 
840a8fe65b8SJeff Kirsher 	/* Reset the ethernet hardware and activate the printer pass-through. */
841a8fe65b8SJeff Kirsher 	write_reg_high(ioaddr, CMR1, CMR1h_RESET | CMR1h_MUX);
842a8fe65b8SJeff Kirsher 	return 0;
843a8fe65b8SJeff Kirsher }
844a8fe65b8SJeff Kirsher 
845a8fe65b8SJeff Kirsher /*
846a8fe65b8SJeff Kirsher  *	Set or clear the multicast filter for this adapter.
847a8fe65b8SJeff Kirsher  */
848a8fe65b8SJeff Kirsher 
849bb263e18SPaul Bolle static void set_rx_mode(struct net_device *dev)
850a8fe65b8SJeff Kirsher {
851a8fe65b8SJeff Kirsher 	struct net_local *lp = netdev_priv(dev);
852a8fe65b8SJeff Kirsher 	long ioaddr = dev->base_addr;
853a8fe65b8SJeff Kirsher 
854a8fe65b8SJeff Kirsher 	if (!netdev_mc_empty(dev) || (dev->flags & (IFF_ALLMULTI|IFF_PROMISC)))
855a8fe65b8SJeff Kirsher 		lp->addr_mode = CMR2h_PROMISC;
856a8fe65b8SJeff Kirsher 	else
857a8fe65b8SJeff Kirsher 		lp->addr_mode = CMR2h_Normal;
858a8fe65b8SJeff Kirsher 	write_reg_high(ioaddr, CMR2, lp->addr_mode);
859a8fe65b8SJeff Kirsher }
860a8fe65b8SJeff Kirsher 
861a8fe65b8SJeff Kirsher static int __init atp_init_module(void) {
862a8fe65b8SJeff Kirsher 	if (debug)					/* Emit version even if no cards detected. */
863a8fe65b8SJeff Kirsher 		printk(KERN_INFO "%s", version);
864a8fe65b8SJeff Kirsher 	return atp_init();
865a8fe65b8SJeff Kirsher }
866a8fe65b8SJeff Kirsher 
867a8fe65b8SJeff Kirsher static void __exit atp_cleanup_module(void) {
868a8fe65b8SJeff Kirsher 	struct net_device *next_dev;
869a8fe65b8SJeff Kirsher 
870a8fe65b8SJeff Kirsher 	while (root_atp_dev) {
871a8fe65b8SJeff Kirsher 		struct net_local *atp_local = netdev_priv(root_atp_dev);
872a8fe65b8SJeff Kirsher 		next_dev = atp_local->next_module;
873a8fe65b8SJeff Kirsher 		unregister_netdev(root_atp_dev);
874a8fe65b8SJeff Kirsher 		/* No need to release_region(), since we never snarf it. */
875a8fe65b8SJeff Kirsher 		free_netdev(root_atp_dev);
876a8fe65b8SJeff Kirsher 		root_atp_dev = next_dev;
877a8fe65b8SJeff Kirsher 	}
878a8fe65b8SJeff Kirsher }
879a8fe65b8SJeff Kirsher 
880a8fe65b8SJeff Kirsher module_init(atp_init_module);
881a8fe65b8SJeff Kirsher module_exit(atp_cleanup_module);
882