xref: /openbmc/linux/drivers/net/ethernet/realtek/atp.c (revision bb263e18)
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);
154a8fe65b8SJeff Kirsher module_param_array(io, int, NULL, 0);
155a8fe65b8SJeff Kirsher module_param_array(irq, int, 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. */
173a8fe65b8SJeff Kirsher     long last_rx_time;		/* Last Rx, in jiffies, to handle Rx hang. */
174a8fe65b8SJeff Kirsher     int saved_tx_size;
175a8fe65b8SJeff Kirsher     unsigned int tx_unit_busy:1;
176a8fe65b8SJeff Kirsher     unsigned char re_tx,	/* Number of packet retransmissions. */
177a8fe65b8SJeff Kirsher 		addr_mode,		/* Current Rx filter e.g. promiscuous, etc. */
178bb263e18SPaul Bolle 		pac_cnt_in_tx_buf;
179a8fe65b8SJeff Kirsher };
180a8fe65b8SJeff Kirsher 
181a8fe65b8SJeff Kirsher /* This code, written by wwc@super.org, resets the adapter every
182a8fe65b8SJeff Kirsher    TIMED_CHECKER ticks.  This recovers from an unknown error which
183a8fe65b8SJeff Kirsher    hangs the device. */
184a8fe65b8SJeff Kirsher #define TIMED_CHECKER (HZ/4)
185a8fe65b8SJeff Kirsher #ifdef TIMED_CHECKER
186a8fe65b8SJeff Kirsher #include <linux/timer.h>
187a8fe65b8SJeff Kirsher static void atp_timed_checker(unsigned long ignored);
188a8fe65b8SJeff Kirsher #endif
189a8fe65b8SJeff Kirsher 
190a8fe65b8SJeff Kirsher /* Index to functions, as function prototypes. */
191a8fe65b8SJeff Kirsher 
192a8fe65b8SJeff Kirsher static int atp_probe1(long ioaddr);
193a8fe65b8SJeff Kirsher static void get_node_ID(struct net_device *dev);
194a8fe65b8SJeff Kirsher static unsigned short eeprom_op(long ioaddr, unsigned int cmd);
195a8fe65b8SJeff Kirsher static int net_open(struct net_device *dev);
196a8fe65b8SJeff Kirsher static void hardware_init(struct net_device *dev);
197a8fe65b8SJeff Kirsher static void write_packet(long ioaddr, int length, unsigned char *packet, int pad, int mode);
198a8fe65b8SJeff Kirsher static void trigger_send(long ioaddr, int length);
199a8fe65b8SJeff Kirsher static netdev_tx_t atp_send_packet(struct sk_buff *skb,
200a8fe65b8SJeff Kirsher 				   struct net_device *dev);
201a8fe65b8SJeff Kirsher static irqreturn_t atp_interrupt(int irq, void *dev_id);
202a8fe65b8SJeff Kirsher static void net_rx(struct net_device *dev);
203a8fe65b8SJeff Kirsher static void read_block(long ioaddr, int length, unsigned char *buffer, int data_mode);
204a8fe65b8SJeff Kirsher static int net_close(struct net_device *dev);
205a8fe65b8SJeff Kirsher static void set_rx_mode(struct net_device *dev);
206a8fe65b8SJeff Kirsher static void tx_timeout(struct net_device *dev);
207a8fe65b8SJeff Kirsher 
208a8fe65b8SJeff Kirsher 
209a8fe65b8SJeff Kirsher /* A list of all installed ATP devices, for removing the driver module. */
210a8fe65b8SJeff Kirsher static struct net_device *root_atp_dev;
211a8fe65b8SJeff Kirsher 
212a8fe65b8SJeff Kirsher /* Check for a network adapter of this type, and return '0' iff one exists.
213a8fe65b8SJeff Kirsher    If dev->base_addr == 0, probe all likely locations.
214a8fe65b8SJeff Kirsher    If dev->base_addr == 1, always return failure.
215a8fe65b8SJeff Kirsher    If dev->base_addr == 2, allocate space for the device and return success
216a8fe65b8SJeff Kirsher    (detachable devices only).
217a8fe65b8SJeff Kirsher 
218a8fe65b8SJeff Kirsher    FIXME: we should use the parport layer for this
219a8fe65b8SJeff Kirsher    */
220a8fe65b8SJeff Kirsher static int __init atp_init(void)
221a8fe65b8SJeff Kirsher {
222a8fe65b8SJeff Kirsher 	int *port, ports[] = {0x378, 0x278, 0x3bc, 0};
223a8fe65b8SJeff Kirsher 	int base_addr = io[0];
224a8fe65b8SJeff Kirsher 
225a8fe65b8SJeff Kirsher 	if (base_addr > 0x1ff)		/* Check a single specified location. */
226a8fe65b8SJeff Kirsher 		return atp_probe1(base_addr);
227a8fe65b8SJeff Kirsher 	else if (base_addr == 1)	/* Don't probe at all. */
228a8fe65b8SJeff Kirsher 		return -ENXIO;
229a8fe65b8SJeff Kirsher 
230a8fe65b8SJeff Kirsher 	for (port = ports; *port; port++) {
231a8fe65b8SJeff Kirsher 		long ioaddr = *port;
232a8fe65b8SJeff Kirsher 		outb(0x57, ioaddr + PAR_DATA);
233a8fe65b8SJeff Kirsher 		if (inb(ioaddr + PAR_DATA) != 0x57)
234a8fe65b8SJeff Kirsher 			continue;
235a8fe65b8SJeff Kirsher 		if (atp_probe1(ioaddr) == 0)
236a8fe65b8SJeff Kirsher 			return 0;
237a8fe65b8SJeff Kirsher 	}
238a8fe65b8SJeff Kirsher 
239a8fe65b8SJeff Kirsher 	return -ENODEV;
240a8fe65b8SJeff Kirsher }
241a8fe65b8SJeff Kirsher 
242a8fe65b8SJeff Kirsher static const struct net_device_ops atp_netdev_ops = {
243a8fe65b8SJeff Kirsher 	.ndo_open		= net_open,
244a8fe65b8SJeff Kirsher 	.ndo_stop		= net_close,
245a8fe65b8SJeff Kirsher 	.ndo_start_xmit		= atp_send_packet,
246afc4b13dSJiri Pirko 	.ndo_set_rx_mode	= set_rx_mode,
247a8fe65b8SJeff Kirsher 	.ndo_tx_timeout		= tx_timeout,
248a8fe65b8SJeff Kirsher 	.ndo_change_mtu		= eth_change_mtu,
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 
442a8fe65b8SJeff Kirsher 	init_timer(&lp->timer);
443a8fe65b8SJeff Kirsher 	lp->timer.expires = jiffies + TIMED_CHECKER;
444a8fe65b8SJeff Kirsher 	lp->timer.data = (unsigned long)dev;
445a8fe65b8SJeff Kirsher 	lp->timer.function = atp_timed_checker;    /* timer handler */
446a8fe65b8SJeff Kirsher 	add_timer(&lp->timer);
447a8fe65b8SJeff Kirsher 
448a8fe65b8SJeff Kirsher 	netif_start_queue(dev);
449a8fe65b8SJeff Kirsher 	return 0;
450a8fe65b8SJeff Kirsher }
451a8fe65b8SJeff Kirsher 
452a8fe65b8SJeff Kirsher /* This routine resets the hardware.  We initialize everything, assuming that
453a8fe65b8SJeff Kirsher    the hardware may have been temporarily detached. */
454a8fe65b8SJeff Kirsher static void hardware_init(struct net_device *dev)
455a8fe65b8SJeff Kirsher {
456a8fe65b8SJeff Kirsher 	struct net_local *lp = netdev_priv(dev);
457a8fe65b8SJeff Kirsher 	long ioaddr = dev->base_addr;
458a8fe65b8SJeff Kirsher     int i;
459a8fe65b8SJeff Kirsher 
460a8fe65b8SJeff Kirsher 	/* Turn off the printer multiplexer on the 8012. */
461a8fe65b8SJeff Kirsher 	for (i = 0; i < 8; i++)
462a8fe65b8SJeff Kirsher 		outb(mux_8012[i], ioaddr + PAR_DATA);
463a8fe65b8SJeff Kirsher 	write_reg_high(ioaddr, CMR1, CMR1h_RESET);
464a8fe65b8SJeff Kirsher 
465a8fe65b8SJeff Kirsher     for (i = 0; i < 6; i++)
466a8fe65b8SJeff Kirsher 		write_reg_byte(ioaddr, PAR0 + i, dev->dev_addr[i]);
467a8fe65b8SJeff Kirsher 
468a8fe65b8SJeff Kirsher 	write_reg_high(ioaddr, CMR2, lp->addr_mode);
469a8fe65b8SJeff Kirsher 
470a8fe65b8SJeff Kirsher 	if (net_debug > 2) {
471a8fe65b8SJeff Kirsher 		printk(KERN_DEBUG "%s: Reset: current Rx mode %d.\n", dev->name,
472a8fe65b8SJeff Kirsher 			   (read_nibble(ioaddr, CMR2_h) >> 3) & 0x0f);
473a8fe65b8SJeff Kirsher 	}
474a8fe65b8SJeff Kirsher 
475a8fe65b8SJeff Kirsher     write_reg(ioaddr, CMR2, CMR2_IRQOUT);
476a8fe65b8SJeff Kirsher     write_reg_high(ioaddr, CMR1, CMR1h_RxENABLE | CMR1h_TxENABLE);
477a8fe65b8SJeff Kirsher 
478a8fe65b8SJeff Kirsher 	/* Enable the interrupt line from the serial port. */
479a8fe65b8SJeff Kirsher 	outb(Ctrl_SelData + Ctrl_IRQEN, ioaddr + PAR_CONTROL);
480a8fe65b8SJeff Kirsher 
481a8fe65b8SJeff Kirsher 	/* Unmask the interesting interrupts. */
482a8fe65b8SJeff Kirsher     write_reg(ioaddr, IMR, ISR_RxOK | ISR_TxErr | ISR_TxOK);
483a8fe65b8SJeff Kirsher     write_reg_high(ioaddr, IMR, ISRh_RxErr);
484a8fe65b8SJeff Kirsher 
485a8fe65b8SJeff Kirsher 	lp->tx_unit_busy = 0;
486a8fe65b8SJeff Kirsher     lp->pac_cnt_in_tx_buf = 0;
487a8fe65b8SJeff Kirsher 	lp->saved_tx_size = 0;
488a8fe65b8SJeff Kirsher }
489a8fe65b8SJeff Kirsher 
490a8fe65b8SJeff Kirsher static void trigger_send(long ioaddr, int length)
491a8fe65b8SJeff Kirsher {
492a8fe65b8SJeff Kirsher 	write_reg_byte(ioaddr, TxCNT0, length & 0xff);
493a8fe65b8SJeff Kirsher 	write_reg(ioaddr, TxCNT1, length >> 8);
494a8fe65b8SJeff Kirsher 	write_reg(ioaddr, CMR1, CMR1_Xmit);
495a8fe65b8SJeff Kirsher }
496a8fe65b8SJeff Kirsher 
497a8fe65b8SJeff Kirsher static void write_packet(long ioaddr, int length, unsigned char *packet, int pad_len, int data_mode)
498a8fe65b8SJeff Kirsher {
499a8fe65b8SJeff Kirsher     if (length & 1)
500a8fe65b8SJeff Kirsher     {
501a8fe65b8SJeff Kirsher     	length++;
502a8fe65b8SJeff Kirsher     	pad_len++;
503a8fe65b8SJeff Kirsher     }
504a8fe65b8SJeff Kirsher 
505a8fe65b8SJeff Kirsher     outb(EOC+MAR, ioaddr + PAR_DATA);
506a8fe65b8SJeff Kirsher     if ((data_mode & 1) == 0) {
507a8fe65b8SJeff Kirsher 		/* Write the packet out, starting with the write addr. */
508a8fe65b8SJeff Kirsher 		outb(WrAddr+MAR, ioaddr + PAR_DATA);
509a8fe65b8SJeff Kirsher 		do {
510a8fe65b8SJeff Kirsher 			write_byte_mode0(ioaddr, *packet++);
511a8fe65b8SJeff Kirsher 		} while (--length > pad_len) ;
512a8fe65b8SJeff Kirsher 		do {
513a8fe65b8SJeff Kirsher 			write_byte_mode0(ioaddr, 0);
514a8fe65b8SJeff Kirsher 		} while (--length > 0) ;
515a8fe65b8SJeff Kirsher     } else {
516a8fe65b8SJeff Kirsher 		/* Write the packet out in slow mode. */
517a8fe65b8SJeff Kirsher 		unsigned char outbyte = *packet++;
518a8fe65b8SJeff Kirsher 
519a8fe65b8SJeff Kirsher 		outb(Ctrl_LNibWrite + Ctrl_IRQEN, ioaddr + PAR_CONTROL);
520a8fe65b8SJeff Kirsher 		outb(WrAddr+MAR, ioaddr + PAR_DATA);
521a8fe65b8SJeff Kirsher 
522a8fe65b8SJeff Kirsher 		outb((outbyte & 0x0f)|0x40, ioaddr + PAR_DATA);
523a8fe65b8SJeff Kirsher 		outb(outbyte & 0x0f, ioaddr + PAR_DATA);
524a8fe65b8SJeff Kirsher 		outbyte >>= 4;
525a8fe65b8SJeff Kirsher 		outb(outbyte & 0x0f, ioaddr + PAR_DATA);
526a8fe65b8SJeff Kirsher 		outb(Ctrl_HNibWrite + Ctrl_IRQEN, ioaddr + PAR_CONTROL);
527a8fe65b8SJeff Kirsher 		while (--length > pad_len)
528a8fe65b8SJeff Kirsher 			write_byte_mode1(ioaddr, *packet++);
529a8fe65b8SJeff Kirsher 		while (--length > 0)
530a8fe65b8SJeff Kirsher 			write_byte_mode1(ioaddr, 0);
531a8fe65b8SJeff Kirsher     }
532a8fe65b8SJeff Kirsher     /* Terminate the Tx frame.  End of write: ECB. */
533a8fe65b8SJeff Kirsher     outb(0xff, ioaddr + PAR_DATA);
534a8fe65b8SJeff Kirsher     outb(Ctrl_HNibWrite | Ctrl_SelData | Ctrl_IRQEN, ioaddr + PAR_CONTROL);
535a8fe65b8SJeff Kirsher }
536a8fe65b8SJeff Kirsher 
537a8fe65b8SJeff Kirsher static void tx_timeout(struct net_device *dev)
538a8fe65b8SJeff Kirsher {
539a8fe65b8SJeff Kirsher 	long ioaddr = dev->base_addr;
540a8fe65b8SJeff Kirsher 
541a8fe65b8SJeff Kirsher 	printk(KERN_WARNING "%s: Transmit timed out, %s?\n", dev->name,
542a8fe65b8SJeff Kirsher 		   inb(ioaddr + PAR_CONTROL) & 0x10 ? "network cable problem"
543a8fe65b8SJeff Kirsher 		   :  "IRQ conflict");
544a8fe65b8SJeff Kirsher 	dev->stats.tx_errors++;
545a8fe65b8SJeff Kirsher 	/* Try to restart the adapter. */
546a8fe65b8SJeff Kirsher 	hardware_init(dev);
547a8fe65b8SJeff Kirsher 	dev->trans_start = jiffies; /* prevent tx timeout */
548a8fe65b8SJeff Kirsher 	netif_wake_queue(dev);
549a8fe65b8SJeff Kirsher 	dev->stats.tx_errors++;
550a8fe65b8SJeff Kirsher }
551a8fe65b8SJeff Kirsher 
552a8fe65b8SJeff Kirsher static netdev_tx_t atp_send_packet(struct sk_buff *skb,
553a8fe65b8SJeff Kirsher 				   struct net_device *dev)
554a8fe65b8SJeff Kirsher {
555a8fe65b8SJeff Kirsher 	struct net_local *lp = netdev_priv(dev);
556a8fe65b8SJeff Kirsher 	long ioaddr = dev->base_addr;
557a8fe65b8SJeff Kirsher 	int length;
558a8fe65b8SJeff Kirsher 	unsigned long flags;
559a8fe65b8SJeff Kirsher 
560a8fe65b8SJeff Kirsher 	length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
561a8fe65b8SJeff Kirsher 
562a8fe65b8SJeff Kirsher 	netif_stop_queue(dev);
563a8fe65b8SJeff Kirsher 
564a8fe65b8SJeff Kirsher 	/* Disable interrupts by writing 0x00 to the Interrupt Mask Register.
565a8fe65b8SJeff Kirsher 	   This sequence must not be interrupted by an incoming packet. */
566a8fe65b8SJeff Kirsher 
567a8fe65b8SJeff Kirsher 	spin_lock_irqsave(&lp->lock, flags);
568a8fe65b8SJeff Kirsher 	write_reg(ioaddr, IMR, 0);
569a8fe65b8SJeff Kirsher 	write_reg_high(ioaddr, IMR, 0);
570a8fe65b8SJeff Kirsher 	spin_unlock_irqrestore(&lp->lock, flags);
571a8fe65b8SJeff Kirsher 
572a8fe65b8SJeff Kirsher 	write_packet(ioaddr, length, skb->data, length-skb->len, dev->if_port);
573a8fe65b8SJeff Kirsher 
574a8fe65b8SJeff Kirsher 	lp->pac_cnt_in_tx_buf++;
575a8fe65b8SJeff Kirsher 	if (lp->tx_unit_busy == 0) {
576a8fe65b8SJeff Kirsher 		trigger_send(ioaddr, length);
577a8fe65b8SJeff Kirsher 		lp->saved_tx_size = 0; 				/* Redundant */
578a8fe65b8SJeff Kirsher 		lp->re_tx = 0;
579a8fe65b8SJeff Kirsher 		lp->tx_unit_busy = 1;
580a8fe65b8SJeff Kirsher 	} else
581a8fe65b8SJeff Kirsher 		lp->saved_tx_size = length;
582a8fe65b8SJeff Kirsher 	/* Re-enable the LPT interrupts. */
583a8fe65b8SJeff Kirsher 	write_reg(ioaddr, IMR, ISR_RxOK | ISR_TxErr | ISR_TxOK);
584a8fe65b8SJeff Kirsher 	write_reg_high(ioaddr, IMR, ISRh_RxErr);
585a8fe65b8SJeff Kirsher 
586a8fe65b8SJeff Kirsher 	dev_kfree_skb (skb);
587a8fe65b8SJeff Kirsher 	return NETDEV_TX_OK;
588a8fe65b8SJeff Kirsher }
589a8fe65b8SJeff Kirsher 
590a8fe65b8SJeff Kirsher 
591a8fe65b8SJeff Kirsher /* The typical workload of the driver:
592a8fe65b8SJeff Kirsher    Handle the network interface interrupts. */
593a8fe65b8SJeff Kirsher static irqreturn_t atp_interrupt(int irq, void *dev_instance)
594a8fe65b8SJeff Kirsher {
595a8fe65b8SJeff Kirsher 	struct net_device *dev = dev_instance;
596a8fe65b8SJeff Kirsher 	struct net_local *lp;
597a8fe65b8SJeff Kirsher 	long ioaddr;
598a8fe65b8SJeff Kirsher 	static int num_tx_since_rx;
599a8fe65b8SJeff Kirsher 	int boguscount = max_interrupt_work;
600a8fe65b8SJeff Kirsher 	int handled = 0;
601a8fe65b8SJeff Kirsher 
602a8fe65b8SJeff Kirsher 	ioaddr = dev->base_addr;
603a8fe65b8SJeff Kirsher 	lp = netdev_priv(dev);
604a8fe65b8SJeff Kirsher 
605a8fe65b8SJeff Kirsher 	spin_lock(&lp->lock);
606a8fe65b8SJeff Kirsher 
607a8fe65b8SJeff Kirsher 	/* Disable additional spurious interrupts. */
608a8fe65b8SJeff Kirsher 	outb(Ctrl_SelData, ioaddr + PAR_CONTROL);
609a8fe65b8SJeff Kirsher 
610a8fe65b8SJeff Kirsher 	/* The adapter's output is currently the IRQ line, switch it to data. */
611a8fe65b8SJeff Kirsher 	write_reg(ioaddr, CMR2, CMR2_NULL);
612a8fe65b8SJeff Kirsher 	write_reg(ioaddr, IMR, 0);
613a8fe65b8SJeff Kirsher 
614a8fe65b8SJeff Kirsher 	if (net_debug > 5) printk(KERN_DEBUG "%s: In interrupt ", dev->name);
615a8fe65b8SJeff Kirsher     while (--boguscount > 0) {
616a8fe65b8SJeff Kirsher 		int status = read_nibble(ioaddr, ISR);
617a8fe65b8SJeff Kirsher 		if (net_debug > 5) printk("loop status %02x..", status);
618a8fe65b8SJeff Kirsher 
619a8fe65b8SJeff Kirsher 		if (status & (ISR_RxOK<<3)) {
620a8fe65b8SJeff Kirsher 			handled = 1;
621a8fe65b8SJeff Kirsher 			write_reg(ioaddr, ISR, ISR_RxOK); /* Clear the Rx interrupt. */
622a8fe65b8SJeff Kirsher 			do {
623a8fe65b8SJeff Kirsher 				int read_status = read_nibble(ioaddr, CMR1);
624a8fe65b8SJeff Kirsher 				if (net_debug > 6)
625a8fe65b8SJeff Kirsher 					printk("handling Rx packet %02x..", read_status);
626a8fe65b8SJeff Kirsher 				/* We acknowledged the normal Rx interrupt, so if the interrupt
627a8fe65b8SJeff Kirsher 				   is still outstanding we must have a Rx error. */
628a8fe65b8SJeff Kirsher 				if (read_status & (CMR1_IRQ << 3)) { /* Overrun. */
629a8fe65b8SJeff Kirsher 					dev->stats.rx_over_errors++;
630a8fe65b8SJeff Kirsher 					/* Set to no-accept mode long enough to remove a packet. */
631a8fe65b8SJeff Kirsher 					write_reg_high(ioaddr, CMR2, CMR2h_OFF);
632a8fe65b8SJeff Kirsher 					net_rx(dev);
633a8fe65b8SJeff Kirsher 					/* Clear the interrupt and return to normal Rx mode. */
634a8fe65b8SJeff Kirsher 					write_reg_high(ioaddr, ISR, ISRh_RxErr);
635a8fe65b8SJeff Kirsher 					write_reg_high(ioaddr, CMR2, lp->addr_mode);
636a8fe65b8SJeff Kirsher 				} else if ((read_status & (CMR1_BufEnb << 3)) == 0) {
637a8fe65b8SJeff Kirsher 					net_rx(dev);
638a8fe65b8SJeff Kirsher 					num_tx_since_rx = 0;
639a8fe65b8SJeff Kirsher 				} else
640a8fe65b8SJeff Kirsher 					break;
641a8fe65b8SJeff Kirsher 			} while (--boguscount > 0);
642a8fe65b8SJeff Kirsher 		} else if (status & ((ISR_TxErr + ISR_TxOK)<<3)) {
643a8fe65b8SJeff Kirsher 			handled = 1;
644a8fe65b8SJeff Kirsher 			if (net_debug > 6)  printk("handling Tx done..");
645a8fe65b8SJeff Kirsher 			/* Clear the Tx interrupt.  We should check for too many failures
646a8fe65b8SJeff Kirsher 			   and reinitialize the adapter. */
647a8fe65b8SJeff Kirsher 			write_reg(ioaddr, ISR, ISR_TxErr + ISR_TxOK);
648a8fe65b8SJeff Kirsher 			if (status & (ISR_TxErr<<3)) {
649a8fe65b8SJeff Kirsher 				dev->stats.collisions++;
650a8fe65b8SJeff Kirsher 				if (++lp->re_tx > 15) {
651a8fe65b8SJeff Kirsher 					dev->stats.tx_aborted_errors++;
652a8fe65b8SJeff Kirsher 					hardware_init(dev);
653a8fe65b8SJeff Kirsher 					break;
654a8fe65b8SJeff Kirsher 				}
655a8fe65b8SJeff Kirsher 				/* Attempt to retransmit. */
656a8fe65b8SJeff Kirsher 				if (net_debug > 6)  printk("attempting to ReTx");
657a8fe65b8SJeff Kirsher 				write_reg(ioaddr, CMR1, CMR1_ReXmit + CMR1_Xmit);
658a8fe65b8SJeff Kirsher 			} else {
659a8fe65b8SJeff Kirsher 				/* Finish up the transmit. */
660a8fe65b8SJeff Kirsher 				dev->stats.tx_packets++;
661a8fe65b8SJeff Kirsher 				lp->pac_cnt_in_tx_buf--;
662a8fe65b8SJeff Kirsher 				if ( lp->saved_tx_size) {
663a8fe65b8SJeff Kirsher 					trigger_send(ioaddr, lp->saved_tx_size);
664a8fe65b8SJeff Kirsher 					lp->saved_tx_size = 0;
665a8fe65b8SJeff Kirsher 					lp->re_tx = 0;
666a8fe65b8SJeff Kirsher 				} else
667a8fe65b8SJeff Kirsher 					lp->tx_unit_busy = 0;
668a8fe65b8SJeff Kirsher 				netif_wake_queue(dev);	/* Inform upper layers. */
669a8fe65b8SJeff Kirsher 			}
670a8fe65b8SJeff Kirsher 			num_tx_since_rx++;
671a8fe65b8SJeff Kirsher 		} else if (num_tx_since_rx > 8 &&
672a8fe65b8SJeff Kirsher 			   time_after(jiffies, dev->last_rx + HZ)) {
673a8fe65b8SJeff Kirsher 			if (net_debug > 2)
674a8fe65b8SJeff Kirsher 				printk(KERN_DEBUG "%s: Missed packet? No Rx after %d Tx and "
675a8fe65b8SJeff Kirsher 					   "%ld jiffies status %02x  CMR1 %02x.\n", dev->name,
676a8fe65b8SJeff Kirsher 					   num_tx_since_rx, jiffies - dev->last_rx, status,
677a8fe65b8SJeff Kirsher 					   (read_nibble(ioaddr, CMR1) >> 3) & 15);
678a8fe65b8SJeff Kirsher 			dev->stats.rx_missed_errors++;
679a8fe65b8SJeff Kirsher 			hardware_init(dev);
680a8fe65b8SJeff Kirsher 			num_tx_since_rx = 0;
681a8fe65b8SJeff Kirsher 			break;
682a8fe65b8SJeff Kirsher 		} else
683a8fe65b8SJeff Kirsher 			break;
684a8fe65b8SJeff Kirsher     }
685a8fe65b8SJeff Kirsher 
686a8fe65b8SJeff Kirsher 	/* This following code fixes a rare (and very difficult to track down)
687a8fe65b8SJeff Kirsher 	   problem where the adapter forgets its ethernet address. */
688a8fe65b8SJeff Kirsher 	{
689a8fe65b8SJeff Kirsher 		int i;
690a8fe65b8SJeff Kirsher 		for (i = 0; i < 6; i++)
691a8fe65b8SJeff Kirsher 			write_reg_byte(ioaddr, PAR0 + i, dev->dev_addr[i]);
692a8fe65b8SJeff Kirsher #if 0 && defined(TIMED_CHECKER)
693a8fe65b8SJeff Kirsher 		mod_timer(&lp->timer, jiffies + TIMED_CHECKER);
694a8fe65b8SJeff Kirsher #endif
695a8fe65b8SJeff Kirsher 	}
696a8fe65b8SJeff Kirsher 
697a8fe65b8SJeff Kirsher 	/* Tell the adapter that it can go back to using the output line as IRQ. */
698a8fe65b8SJeff Kirsher     write_reg(ioaddr, CMR2, CMR2_IRQOUT);
699a8fe65b8SJeff Kirsher 	/* Enable the physical interrupt line, which is sure to be low until.. */
700a8fe65b8SJeff Kirsher 	outb(Ctrl_SelData + Ctrl_IRQEN, ioaddr + PAR_CONTROL);
701a8fe65b8SJeff Kirsher 	/* .. we enable the interrupt sources. */
702a8fe65b8SJeff Kirsher 	write_reg(ioaddr, IMR, ISR_RxOK | ISR_TxErr | ISR_TxOK);
703a8fe65b8SJeff Kirsher 	write_reg_high(ioaddr, IMR, ISRh_RxErr); 			/* Hmmm, really needed? */
704a8fe65b8SJeff Kirsher 
705a8fe65b8SJeff Kirsher 	spin_unlock(&lp->lock);
706a8fe65b8SJeff Kirsher 
707a8fe65b8SJeff Kirsher 	if (net_debug > 5) printk("exiting interrupt.\n");
708a8fe65b8SJeff Kirsher 	return IRQ_RETVAL(handled);
709a8fe65b8SJeff Kirsher }
710a8fe65b8SJeff Kirsher 
711a8fe65b8SJeff Kirsher #ifdef TIMED_CHECKER
712a8fe65b8SJeff Kirsher /* This following code fixes a rare (and very difficult to track down)
713a8fe65b8SJeff Kirsher    problem where the adapter forgets its ethernet address. */
714a8fe65b8SJeff Kirsher static void atp_timed_checker(unsigned long data)
715a8fe65b8SJeff Kirsher {
716a8fe65b8SJeff Kirsher 	struct net_device *dev = (struct net_device *)data;
717a8fe65b8SJeff Kirsher 	long ioaddr = dev->base_addr;
718a8fe65b8SJeff Kirsher 	struct net_local *lp = netdev_priv(dev);
719a8fe65b8SJeff Kirsher 	int tickssofar = jiffies - lp->last_rx_time;
720a8fe65b8SJeff Kirsher 	int i;
721a8fe65b8SJeff Kirsher 
722a8fe65b8SJeff Kirsher 	spin_lock(&lp->lock);
723a8fe65b8SJeff Kirsher 	if (tickssofar > 2*HZ) {
724a8fe65b8SJeff Kirsher #if 1
725a8fe65b8SJeff Kirsher 		for (i = 0; i < 6; i++)
726a8fe65b8SJeff Kirsher 			write_reg_byte(ioaddr, PAR0 + i, dev->dev_addr[i]);
727a8fe65b8SJeff Kirsher 		lp->last_rx_time = jiffies;
728a8fe65b8SJeff Kirsher #else
729a8fe65b8SJeff Kirsher 		for (i = 0; i < 6; i++)
730a8fe65b8SJeff Kirsher 			if (read_cmd_byte(ioaddr, PAR0 + i) != atp_timed_dev->dev_addr[i])
731a8fe65b8SJeff Kirsher 				{
732a8fe65b8SJeff Kirsher 			struct net_local *lp = netdev_priv(atp_timed_dev);
733a8fe65b8SJeff Kirsher 			write_reg_byte(ioaddr, PAR0 + i, atp_timed_dev->dev_addr[i]);
734a8fe65b8SJeff Kirsher 			if (i == 2)
735a8fe65b8SJeff Kirsher 			  dev->stats.tx_errors++;
736a8fe65b8SJeff Kirsher 			else if (i == 3)
737a8fe65b8SJeff Kirsher 			  dev->stats.tx_dropped++;
738a8fe65b8SJeff Kirsher 			else if (i == 4)
739a8fe65b8SJeff Kirsher 			  dev->stats.collisions++;
740a8fe65b8SJeff Kirsher 			else
741a8fe65b8SJeff Kirsher 			  dev->stats.rx_errors++;
742a8fe65b8SJeff Kirsher 		  }
743a8fe65b8SJeff Kirsher #endif
744a8fe65b8SJeff Kirsher 	}
745a8fe65b8SJeff Kirsher 	spin_unlock(&lp->lock);
746a8fe65b8SJeff Kirsher 	lp->timer.expires = jiffies + TIMED_CHECKER;
747a8fe65b8SJeff Kirsher 	add_timer(&lp->timer);
748a8fe65b8SJeff Kirsher }
749a8fe65b8SJeff Kirsher #endif
750a8fe65b8SJeff Kirsher 
751a8fe65b8SJeff Kirsher /* We have a good packet(s), get it/them out of the buffers. */
752a8fe65b8SJeff Kirsher static void net_rx(struct net_device *dev)
753a8fe65b8SJeff Kirsher {
754a8fe65b8SJeff Kirsher 	struct net_local *lp = netdev_priv(dev);
755a8fe65b8SJeff Kirsher 	long ioaddr = dev->base_addr;
756a8fe65b8SJeff Kirsher 	struct rx_header rx_head;
757a8fe65b8SJeff Kirsher 
758a8fe65b8SJeff Kirsher 	/* Process the received packet. */
759a8fe65b8SJeff Kirsher 	outb(EOC+MAR, ioaddr + PAR_DATA);
760a8fe65b8SJeff Kirsher 	read_block(ioaddr, 8, (unsigned char*)&rx_head, dev->if_port);
761a8fe65b8SJeff Kirsher 	if (net_debug > 5)
762a8fe65b8SJeff Kirsher 		printk(KERN_DEBUG " rx_count %04x %04x %04x %04x..", rx_head.pad,
763a8fe65b8SJeff Kirsher 			   rx_head.rx_count, rx_head.rx_status, rx_head.cur_addr);
764a8fe65b8SJeff Kirsher 	if ((rx_head.rx_status & 0x77) != 0x01) {
765a8fe65b8SJeff Kirsher 		dev->stats.rx_errors++;
766a8fe65b8SJeff Kirsher 		if (rx_head.rx_status & 0x0004) dev->stats.rx_frame_errors++;
767a8fe65b8SJeff Kirsher 		else if (rx_head.rx_status & 0x0002) dev->stats.rx_crc_errors++;
768a8fe65b8SJeff Kirsher 		if (net_debug > 3)
769a8fe65b8SJeff Kirsher 			printk(KERN_DEBUG "%s: Unknown ATP Rx error %04x.\n",
770a8fe65b8SJeff Kirsher 				   dev->name, rx_head.rx_status);
771a8fe65b8SJeff Kirsher 		if  (rx_head.rx_status & 0x0020) {
772a8fe65b8SJeff Kirsher 			dev->stats.rx_fifo_errors++;
773a8fe65b8SJeff Kirsher 			write_reg_high(ioaddr, CMR1, CMR1h_TxENABLE);
774a8fe65b8SJeff Kirsher 			write_reg_high(ioaddr, CMR1, CMR1h_RxENABLE | CMR1h_TxENABLE);
775a8fe65b8SJeff Kirsher 		} else if (rx_head.rx_status & 0x0050)
776a8fe65b8SJeff Kirsher 			hardware_init(dev);
777a8fe65b8SJeff Kirsher 		return;
778a8fe65b8SJeff Kirsher 	} else {
779a8fe65b8SJeff Kirsher 		/* Malloc up new buffer. The "-4" omits the FCS (CRC). */
780a8fe65b8SJeff Kirsher 		int pkt_len = (rx_head.rx_count & 0x7ff) - 4;
781a8fe65b8SJeff Kirsher 		struct sk_buff *skb;
782a8fe65b8SJeff Kirsher 
783dae2e9f4SPradeep A. Dalvi 		skb = netdev_alloc_skb(dev, pkt_len + 2);
784a8fe65b8SJeff Kirsher 		if (skb == NULL) {
785a8fe65b8SJeff Kirsher 			printk(KERN_ERR "%s: Memory squeeze, dropping packet.\n",
786a8fe65b8SJeff Kirsher 				   dev->name);
787a8fe65b8SJeff Kirsher 			dev->stats.rx_dropped++;
788a8fe65b8SJeff Kirsher 			goto done;
789a8fe65b8SJeff Kirsher 		}
790a8fe65b8SJeff Kirsher 
791a8fe65b8SJeff Kirsher 		skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
792a8fe65b8SJeff Kirsher 		read_block(ioaddr, pkt_len, skb_put(skb,pkt_len), dev->if_port);
793a8fe65b8SJeff Kirsher 		skb->protocol = eth_type_trans(skb, dev);
794a8fe65b8SJeff Kirsher 		netif_rx(skb);
795a8fe65b8SJeff Kirsher 		dev->last_rx = jiffies;
796a8fe65b8SJeff Kirsher 		dev->stats.rx_packets++;
797a8fe65b8SJeff Kirsher 		dev->stats.rx_bytes += pkt_len;
798a8fe65b8SJeff Kirsher 	}
799a8fe65b8SJeff Kirsher  done:
800a8fe65b8SJeff Kirsher 	write_reg(ioaddr, CMR1, CMR1_NextPkt);
801a8fe65b8SJeff Kirsher 	lp->last_rx_time = jiffies;
802a8fe65b8SJeff Kirsher }
803a8fe65b8SJeff Kirsher 
804a8fe65b8SJeff Kirsher static void read_block(long ioaddr, int length, unsigned char *p, int data_mode)
805a8fe65b8SJeff Kirsher {
806a8fe65b8SJeff Kirsher 	if (data_mode <= 3) { /* Mode 0 or 1 */
807a8fe65b8SJeff Kirsher 		outb(Ctrl_LNibRead, ioaddr + PAR_CONTROL);
808a8fe65b8SJeff Kirsher 		outb(length == 8  ?  RdAddr | HNib | MAR  :  RdAddr | MAR,
809a8fe65b8SJeff Kirsher 			 ioaddr + PAR_DATA);
810a8fe65b8SJeff Kirsher 		if (data_mode <= 1) { /* Mode 0 or 1 */
811a8fe65b8SJeff Kirsher 			do { *p++ = read_byte_mode0(ioaddr); } while (--length > 0);
812a8fe65b8SJeff Kirsher 		} else { /* Mode 2 or 3 */
813a8fe65b8SJeff Kirsher 			do { *p++ = read_byte_mode2(ioaddr); } while (--length > 0);
814a8fe65b8SJeff Kirsher 		}
815a8fe65b8SJeff Kirsher 	} else if (data_mode <= 5) {
816a8fe65b8SJeff Kirsher 		do { *p++ = read_byte_mode4(ioaddr); } while (--length > 0);
817a8fe65b8SJeff Kirsher 	} else {
818a8fe65b8SJeff Kirsher 		do { *p++ = read_byte_mode6(ioaddr); } while (--length > 0);
819a8fe65b8SJeff Kirsher 	}
820a8fe65b8SJeff Kirsher 
821a8fe65b8SJeff Kirsher 	outb(EOC+HNib+MAR, ioaddr + PAR_DATA);
822a8fe65b8SJeff Kirsher 	outb(Ctrl_SelData, ioaddr + PAR_CONTROL);
823a8fe65b8SJeff Kirsher }
824a8fe65b8SJeff Kirsher 
825a8fe65b8SJeff Kirsher /* The inverse routine to net_open(). */
826a8fe65b8SJeff Kirsher static int
827a8fe65b8SJeff Kirsher net_close(struct net_device *dev)
828a8fe65b8SJeff Kirsher {
829a8fe65b8SJeff Kirsher 	struct net_local *lp = netdev_priv(dev);
830a8fe65b8SJeff Kirsher 	long ioaddr = dev->base_addr;
831a8fe65b8SJeff Kirsher 
832a8fe65b8SJeff Kirsher 	netif_stop_queue(dev);
833a8fe65b8SJeff Kirsher 
834a8fe65b8SJeff Kirsher 	del_timer_sync(&lp->timer);
835a8fe65b8SJeff Kirsher 
836a8fe65b8SJeff Kirsher 	/* Flush the Tx and disable Rx here. */
837a8fe65b8SJeff Kirsher 	lp->addr_mode = CMR2h_OFF;
838a8fe65b8SJeff Kirsher 	write_reg_high(ioaddr, CMR2, CMR2h_OFF);
839a8fe65b8SJeff Kirsher 
840a8fe65b8SJeff Kirsher 	/* Free the IRQ line. */
841a8fe65b8SJeff Kirsher 	outb(0x00, ioaddr + PAR_CONTROL);
842a8fe65b8SJeff Kirsher 	free_irq(dev->irq, dev);
843a8fe65b8SJeff Kirsher 
844a8fe65b8SJeff Kirsher 	/* Reset the ethernet hardware and activate the printer pass-through. */
845a8fe65b8SJeff Kirsher 	write_reg_high(ioaddr, CMR1, CMR1h_RESET | CMR1h_MUX);
846a8fe65b8SJeff Kirsher 	return 0;
847a8fe65b8SJeff Kirsher }
848a8fe65b8SJeff Kirsher 
849a8fe65b8SJeff Kirsher /*
850a8fe65b8SJeff Kirsher  *	Set or clear the multicast filter for this adapter.
851a8fe65b8SJeff Kirsher  */
852a8fe65b8SJeff Kirsher 
853bb263e18SPaul Bolle static void set_rx_mode(struct net_device *dev)
854a8fe65b8SJeff Kirsher {
855a8fe65b8SJeff Kirsher 	struct net_local *lp = netdev_priv(dev);
856a8fe65b8SJeff Kirsher 	long ioaddr = dev->base_addr;
857a8fe65b8SJeff Kirsher 
858a8fe65b8SJeff Kirsher 	if (!netdev_mc_empty(dev) || (dev->flags & (IFF_ALLMULTI|IFF_PROMISC)))
859a8fe65b8SJeff Kirsher 		lp->addr_mode = CMR2h_PROMISC;
860a8fe65b8SJeff Kirsher 	else
861a8fe65b8SJeff Kirsher 		lp->addr_mode = CMR2h_Normal;
862a8fe65b8SJeff Kirsher 	write_reg_high(ioaddr, CMR2, lp->addr_mode);
863a8fe65b8SJeff Kirsher }
864a8fe65b8SJeff Kirsher 
865a8fe65b8SJeff Kirsher static int __init atp_init_module(void) {
866a8fe65b8SJeff Kirsher 	if (debug)					/* Emit version even if no cards detected. */
867a8fe65b8SJeff Kirsher 		printk(KERN_INFO "%s", version);
868a8fe65b8SJeff Kirsher 	return atp_init();
869a8fe65b8SJeff Kirsher }
870a8fe65b8SJeff Kirsher 
871a8fe65b8SJeff Kirsher static void __exit atp_cleanup_module(void) {
872a8fe65b8SJeff Kirsher 	struct net_device *next_dev;
873a8fe65b8SJeff Kirsher 
874a8fe65b8SJeff Kirsher 	while (root_atp_dev) {
875a8fe65b8SJeff Kirsher 		struct net_local *atp_local = netdev_priv(root_atp_dev);
876a8fe65b8SJeff Kirsher 		next_dev = atp_local->next_module;
877a8fe65b8SJeff Kirsher 		unregister_netdev(root_atp_dev);
878a8fe65b8SJeff Kirsher 		/* No need to release_region(), since we never snarf it. */
879a8fe65b8SJeff Kirsher 		free_netdev(root_atp_dev);
880a8fe65b8SJeff Kirsher 		root_atp_dev = next_dev;
881a8fe65b8SJeff Kirsher 	}
882a8fe65b8SJeff Kirsher }
883a8fe65b8SJeff Kirsher 
884a8fe65b8SJeff Kirsher module_init(atp_init_module);
885a8fe65b8SJeff Kirsher module_exit(atp_cleanup_module);
886