xref: /openbmc/linux/drivers/net/ethernet/realtek/atp.c (revision 0290bd29)
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);
2070290bd29SMichael S. Tsirkin static void tx_timeout(struct net_device *dev, unsigned int txqueue);
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 
5360290bd29SMichael S. Tsirkin static void tx_timeout(struct net_device *dev, unsigned int txqueue)
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 
613eedfb223SColin Ian King 	if (net_debug > 5)
614eedfb223SColin Ian King 		printk(KERN_DEBUG "%s: In interrupt ", dev->name);
615a8fe65b8SJeff Kirsher 	while (--boguscount > 0) {
616a8fe65b8SJeff Kirsher 		int status = read_nibble(ioaddr, ISR);
617eedfb223SColin Ian King 		if (net_debug > 5)
618eedfb223SColin Ian King 			printk("loop status %02x..", status);
619a8fe65b8SJeff Kirsher 
620a8fe65b8SJeff Kirsher 		if (status & (ISR_RxOK<<3)) {
621a8fe65b8SJeff Kirsher 			handled = 1;
622a8fe65b8SJeff Kirsher 			write_reg(ioaddr, ISR, ISR_RxOK); /* Clear the Rx interrupt. */
623a8fe65b8SJeff Kirsher 			do {
624a8fe65b8SJeff Kirsher 				int read_status = read_nibble(ioaddr, CMR1);
625a8fe65b8SJeff Kirsher 				if (net_debug > 6)
626a8fe65b8SJeff Kirsher 					printk("handling Rx packet %02x..", read_status);
627a8fe65b8SJeff Kirsher 				/* We acknowledged the normal Rx interrupt, so if the interrupt
628a8fe65b8SJeff Kirsher 				   is still outstanding we must have a Rx error. */
629a8fe65b8SJeff Kirsher 				if (read_status & (CMR1_IRQ << 3)) { /* Overrun. */
630a8fe65b8SJeff Kirsher 					dev->stats.rx_over_errors++;
631a8fe65b8SJeff Kirsher 					/* Set to no-accept mode long enough to remove a packet. */
632a8fe65b8SJeff Kirsher 					write_reg_high(ioaddr, CMR2, CMR2h_OFF);
633a8fe65b8SJeff Kirsher 					net_rx(dev);
634a8fe65b8SJeff Kirsher 					/* Clear the interrupt and return to normal Rx mode. */
635a8fe65b8SJeff Kirsher 					write_reg_high(ioaddr, ISR, ISRh_RxErr);
636a8fe65b8SJeff Kirsher 					write_reg_high(ioaddr, CMR2, lp->addr_mode);
637a8fe65b8SJeff Kirsher 				} else if ((read_status & (CMR1_BufEnb << 3)) == 0) {
638a8fe65b8SJeff Kirsher 					net_rx(dev);
639a8fe65b8SJeff Kirsher 					num_tx_since_rx = 0;
640a8fe65b8SJeff Kirsher 				} else
641a8fe65b8SJeff Kirsher 					break;
642a8fe65b8SJeff Kirsher 			} while (--boguscount > 0);
643a8fe65b8SJeff Kirsher 		} else if (status & ((ISR_TxErr + ISR_TxOK)<<3)) {
644a8fe65b8SJeff Kirsher 			handled = 1;
645eedfb223SColin Ian King 			if (net_debug > 6)
646eedfb223SColin Ian King 				printk("handling Tx done..");
647a8fe65b8SJeff Kirsher 			/* Clear the Tx interrupt.  We should check for too many failures
648a8fe65b8SJeff Kirsher 			   and reinitialize the adapter. */
649a8fe65b8SJeff Kirsher 			write_reg(ioaddr, ISR, ISR_TxErr + ISR_TxOK);
650a8fe65b8SJeff Kirsher 			if (status & (ISR_TxErr<<3)) {
651a8fe65b8SJeff Kirsher 				dev->stats.collisions++;
652a8fe65b8SJeff Kirsher 				if (++lp->re_tx > 15) {
653a8fe65b8SJeff Kirsher 					dev->stats.tx_aborted_errors++;
654a8fe65b8SJeff Kirsher 					hardware_init(dev);
655a8fe65b8SJeff Kirsher 					break;
656a8fe65b8SJeff Kirsher 				}
657a8fe65b8SJeff Kirsher 				/* Attempt to retransmit. */
658a8fe65b8SJeff Kirsher 				if (net_debug > 6)  printk("attempting to ReTx");
659a8fe65b8SJeff Kirsher 				write_reg(ioaddr, CMR1, CMR1_ReXmit + CMR1_Xmit);
660a8fe65b8SJeff Kirsher 			} else {
661a8fe65b8SJeff Kirsher 				/* Finish up the transmit. */
662a8fe65b8SJeff Kirsher 				dev->stats.tx_packets++;
663a8fe65b8SJeff Kirsher 				lp->pac_cnt_in_tx_buf--;
664a8fe65b8SJeff Kirsher 				if ( lp->saved_tx_size) {
665a8fe65b8SJeff Kirsher 					trigger_send(ioaddr, lp->saved_tx_size);
666a8fe65b8SJeff Kirsher 					lp->saved_tx_size = 0;
667a8fe65b8SJeff Kirsher 					lp->re_tx = 0;
668a8fe65b8SJeff Kirsher 				} else
669a8fe65b8SJeff Kirsher 					lp->tx_unit_busy = 0;
670a8fe65b8SJeff Kirsher 				netif_wake_queue(dev);	/* Inform upper layers. */
671a8fe65b8SJeff Kirsher 			}
672a8fe65b8SJeff Kirsher 			num_tx_since_rx++;
673a8fe65b8SJeff Kirsher 		} else if (num_tx_since_rx > 8 &&
6744a7c9726STobias Klauser 			   time_after(jiffies, lp->last_rx_time + HZ)) {
675a8fe65b8SJeff Kirsher 			if (net_debug > 2)
676a8fe65b8SJeff Kirsher 				printk(KERN_DEBUG "%s: Missed packet? No Rx after %d Tx and "
677a8fe65b8SJeff Kirsher 					   "%ld jiffies status %02x  CMR1 %02x.\n", dev->name,
6784a7c9726STobias Klauser 					   num_tx_since_rx, jiffies - lp->last_rx_time, status,
679a8fe65b8SJeff Kirsher 					   (read_nibble(ioaddr, CMR1) >> 3) & 15);
680a8fe65b8SJeff Kirsher 			dev->stats.rx_missed_errors++;
681a8fe65b8SJeff Kirsher 			hardware_init(dev);
682a8fe65b8SJeff Kirsher 			num_tx_since_rx = 0;
683a8fe65b8SJeff Kirsher 			break;
684a8fe65b8SJeff Kirsher 		} else
685a8fe65b8SJeff Kirsher 			break;
686a8fe65b8SJeff Kirsher 	}
687a8fe65b8SJeff Kirsher 
688a8fe65b8SJeff Kirsher 	/* This following code fixes a rare (and very difficult to track down)
689a8fe65b8SJeff Kirsher 	   problem where the adapter forgets its ethernet address. */
690a8fe65b8SJeff Kirsher 	{
691a8fe65b8SJeff Kirsher 		int i;
692a8fe65b8SJeff Kirsher 		for (i = 0; i < 6; i++)
693a8fe65b8SJeff Kirsher 			write_reg_byte(ioaddr, PAR0 + i, dev->dev_addr[i]);
694a8fe65b8SJeff Kirsher #if 0 && defined(TIMED_CHECKER)
695a8fe65b8SJeff Kirsher 		mod_timer(&lp->timer, jiffies + TIMED_CHECKER);
696a8fe65b8SJeff Kirsher #endif
697a8fe65b8SJeff Kirsher 	}
698a8fe65b8SJeff Kirsher 
699a8fe65b8SJeff Kirsher 	/* Tell the adapter that it can go back to using the output line as IRQ. */
700a8fe65b8SJeff Kirsher 	write_reg(ioaddr, CMR2, CMR2_IRQOUT);
701a8fe65b8SJeff Kirsher 	/* Enable the physical interrupt line, which is sure to be low until.. */
702a8fe65b8SJeff Kirsher 	outb(Ctrl_SelData + Ctrl_IRQEN, ioaddr + PAR_CONTROL);
703a8fe65b8SJeff Kirsher 	/* .. we enable the interrupt sources. */
704a8fe65b8SJeff Kirsher 	write_reg(ioaddr, IMR, ISR_RxOK | ISR_TxErr | ISR_TxOK);
705a8fe65b8SJeff Kirsher 	write_reg_high(ioaddr, IMR, ISRh_RxErr); 			/* Hmmm, really needed? */
706a8fe65b8SJeff Kirsher 
707a8fe65b8SJeff Kirsher 	spin_unlock(&lp->lock);
708a8fe65b8SJeff Kirsher 
709a8fe65b8SJeff Kirsher 	if (net_debug > 5) printk("exiting interrupt.\n");
710a8fe65b8SJeff Kirsher 	return IRQ_RETVAL(handled);
711a8fe65b8SJeff Kirsher }
712a8fe65b8SJeff Kirsher 
713a8fe65b8SJeff Kirsher #ifdef TIMED_CHECKER
714a8fe65b8SJeff Kirsher /* This following code fixes a rare (and very difficult to track down)
715a8fe65b8SJeff Kirsher    problem where the adapter forgets its ethernet address. */
7169de36ccfSKees Cook static void atp_timed_checker(struct timer_list *t)
717a8fe65b8SJeff Kirsher {
7189de36ccfSKees Cook 	struct net_local *lp = from_timer(lp, t, timer);
7199de36ccfSKees Cook 	struct net_device *dev = lp->dev;
720a8fe65b8SJeff Kirsher 	long ioaddr = dev->base_addr;
721a8fe65b8SJeff Kirsher 	int tickssofar = jiffies - lp->last_rx_time;
722a8fe65b8SJeff Kirsher 	int i;
723a8fe65b8SJeff Kirsher 
724a8fe65b8SJeff Kirsher 	spin_lock(&lp->lock);
725a8fe65b8SJeff Kirsher 	if (tickssofar > 2*HZ) {
726a8fe65b8SJeff Kirsher #if 1
727a8fe65b8SJeff Kirsher 		for (i = 0; i < 6; i++)
728a8fe65b8SJeff Kirsher 			write_reg_byte(ioaddr, PAR0 + i, dev->dev_addr[i]);
729a8fe65b8SJeff Kirsher 		lp->last_rx_time = jiffies;
730a8fe65b8SJeff Kirsher #else
731a8fe65b8SJeff Kirsher 		for (i = 0; i < 6; i++)
732a8fe65b8SJeff Kirsher 			if (read_cmd_byte(ioaddr, PAR0 + i) != atp_timed_dev->dev_addr[i])
733a8fe65b8SJeff Kirsher 				{
734a8fe65b8SJeff Kirsher 			struct net_local *lp = netdev_priv(atp_timed_dev);
735a8fe65b8SJeff Kirsher 			write_reg_byte(ioaddr, PAR0 + i, atp_timed_dev->dev_addr[i]);
736a8fe65b8SJeff Kirsher 			if (i == 2)
737a8fe65b8SJeff Kirsher 			  dev->stats.tx_errors++;
738a8fe65b8SJeff Kirsher 			else if (i == 3)
739a8fe65b8SJeff Kirsher 			  dev->stats.tx_dropped++;
740a8fe65b8SJeff Kirsher 			else if (i == 4)
741a8fe65b8SJeff Kirsher 			  dev->stats.collisions++;
742a8fe65b8SJeff Kirsher 			else
743a8fe65b8SJeff Kirsher 			  dev->stats.rx_errors++;
744a8fe65b8SJeff Kirsher 		  }
745a8fe65b8SJeff Kirsher #endif
746a8fe65b8SJeff Kirsher 	}
747a8fe65b8SJeff Kirsher 	spin_unlock(&lp->lock);
748a8fe65b8SJeff Kirsher 	lp->timer.expires = jiffies + TIMED_CHECKER;
749a8fe65b8SJeff Kirsher 	add_timer(&lp->timer);
750a8fe65b8SJeff Kirsher }
751a8fe65b8SJeff Kirsher #endif
752a8fe65b8SJeff Kirsher 
753a8fe65b8SJeff Kirsher /* We have a good packet(s), get it/them out of the buffers. */
754a8fe65b8SJeff Kirsher static void net_rx(struct net_device *dev)
755a8fe65b8SJeff Kirsher {
756a8fe65b8SJeff Kirsher 	struct net_local *lp = netdev_priv(dev);
757a8fe65b8SJeff Kirsher 	long ioaddr = dev->base_addr;
758a8fe65b8SJeff Kirsher 	struct rx_header rx_head;
759a8fe65b8SJeff Kirsher 
760a8fe65b8SJeff Kirsher 	/* Process the received packet. */
761a8fe65b8SJeff Kirsher 	outb(EOC+MAR, ioaddr + PAR_DATA);
762a8fe65b8SJeff Kirsher 	read_block(ioaddr, 8, (unsigned char*)&rx_head, dev->if_port);
763a8fe65b8SJeff Kirsher 	if (net_debug > 5)
764a8fe65b8SJeff Kirsher 		printk(KERN_DEBUG " rx_count %04x %04x %04x %04x..", rx_head.pad,
765a8fe65b8SJeff Kirsher 			   rx_head.rx_count, rx_head.rx_status, rx_head.cur_addr);
766a8fe65b8SJeff Kirsher 	if ((rx_head.rx_status & 0x77) != 0x01) {
767a8fe65b8SJeff Kirsher 		dev->stats.rx_errors++;
768a8fe65b8SJeff Kirsher 		if (rx_head.rx_status & 0x0004) dev->stats.rx_frame_errors++;
769a8fe65b8SJeff Kirsher 		else if (rx_head.rx_status & 0x0002) dev->stats.rx_crc_errors++;
770a8fe65b8SJeff Kirsher 		if (net_debug > 3)
771a8fe65b8SJeff Kirsher 			printk(KERN_DEBUG "%s: Unknown ATP Rx error %04x.\n",
772a8fe65b8SJeff Kirsher 				   dev->name, rx_head.rx_status);
773a8fe65b8SJeff Kirsher 		if  (rx_head.rx_status & 0x0020) {
774a8fe65b8SJeff Kirsher 			dev->stats.rx_fifo_errors++;
775a8fe65b8SJeff Kirsher 			write_reg_high(ioaddr, CMR1, CMR1h_TxENABLE);
776a8fe65b8SJeff Kirsher 			write_reg_high(ioaddr, CMR1, CMR1h_RxENABLE | CMR1h_TxENABLE);
777a8fe65b8SJeff Kirsher 		} else if (rx_head.rx_status & 0x0050)
778a8fe65b8SJeff Kirsher 			hardware_init(dev);
779a8fe65b8SJeff Kirsher 		return;
780a8fe65b8SJeff Kirsher 	} else {
781a8fe65b8SJeff Kirsher 		/* Malloc up new buffer. The "-4" omits the FCS (CRC). */
782a8fe65b8SJeff Kirsher 		int pkt_len = (rx_head.rx_count & 0x7ff) - 4;
783a8fe65b8SJeff Kirsher 		struct sk_buff *skb;
784a8fe65b8SJeff Kirsher 
785dae2e9f4SPradeep A. Dalvi 		skb = netdev_alloc_skb(dev, pkt_len + 2);
786a8fe65b8SJeff Kirsher 		if (skb == NULL) {
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->stats.rx_packets++;
796a8fe65b8SJeff Kirsher 		dev->stats.rx_bytes += pkt_len;
797a8fe65b8SJeff Kirsher 	}
798a8fe65b8SJeff Kirsher  done:
799a8fe65b8SJeff Kirsher 	write_reg(ioaddr, CMR1, CMR1_NextPkt);
800a8fe65b8SJeff Kirsher 	lp->last_rx_time = jiffies;
801a8fe65b8SJeff Kirsher }
802a8fe65b8SJeff Kirsher 
803a8fe65b8SJeff Kirsher static void read_block(long ioaddr, int length, unsigned char *p, int data_mode)
804a8fe65b8SJeff Kirsher {
805a8fe65b8SJeff Kirsher 	if (data_mode <= 3) { /* Mode 0 or 1 */
806a8fe65b8SJeff Kirsher 		outb(Ctrl_LNibRead, ioaddr + PAR_CONTROL);
807a8fe65b8SJeff Kirsher 		outb(length == 8  ?  RdAddr | HNib | MAR  :  RdAddr | MAR,
808a8fe65b8SJeff Kirsher 			 ioaddr + PAR_DATA);
809a8fe65b8SJeff Kirsher 		if (data_mode <= 1) { /* Mode 0 or 1 */
810a8fe65b8SJeff Kirsher 			do { *p++ = read_byte_mode0(ioaddr); } while (--length > 0);
811a8fe65b8SJeff Kirsher 		} else { /* Mode 2 or 3 */
812a8fe65b8SJeff Kirsher 			do { *p++ = read_byte_mode2(ioaddr); } while (--length > 0);
813a8fe65b8SJeff Kirsher 		}
814a8fe65b8SJeff Kirsher 	} else if (data_mode <= 5) {
815a8fe65b8SJeff Kirsher 		do { *p++ = read_byte_mode4(ioaddr); } while (--length > 0);
816a8fe65b8SJeff Kirsher 	} else {
817a8fe65b8SJeff Kirsher 		do { *p++ = read_byte_mode6(ioaddr); } while (--length > 0);
818a8fe65b8SJeff Kirsher 	}
819a8fe65b8SJeff Kirsher 
820a8fe65b8SJeff Kirsher 	outb(EOC+HNib+MAR, ioaddr + PAR_DATA);
821a8fe65b8SJeff Kirsher 	outb(Ctrl_SelData, ioaddr + PAR_CONTROL);
822a8fe65b8SJeff Kirsher }
823a8fe65b8SJeff Kirsher 
824a8fe65b8SJeff Kirsher /* The inverse routine to net_open(). */
825a8fe65b8SJeff Kirsher static int
826a8fe65b8SJeff Kirsher net_close(struct net_device *dev)
827a8fe65b8SJeff Kirsher {
828a8fe65b8SJeff Kirsher 	struct net_local *lp = netdev_priv(dev);
829a8fe65b8SJeff Kirsher 	long ioaddr = dev->base_addr;
830a8fe65b8SJeff Kirsher 
831a8fe65b8SJeff Kirsher 	netif_stop_queue(dev);
832a8fe65b8SJeff Kirsher 
833a8fe65b8SJeff Kirsher 	del_timer_sync(&lp->timer);
834a8fe65b8SJeff Kirsher 
835a8fe65b8SJeff Kirsher 	/* Flush the Tx and disable Rx here. */
836a8fe65b8SJeff Kirsher 	lp->addr_mode = CMR2h_OFF;
837a8fe65b8SJeff Kirsher 	write_reg_high(ioaddr, CMR2, CMR2h_OFF);
838a8fe65b8SJeff Kirsher 
839a8fe65b8SJeff Kirsher 	/* Free the IRQ line. */
840a8fe65b8SJeff Kirsher 	outb(0x00, ioaddr + PAR_CONTROL);
841a8fe65b8SJeff Kirsher 	free_irq(dev->irq, dev);
842a8fe65b8SJeff Kirsher 
843a8fe65b8SJeff Kirsher 	/* Reset the ethernet hardware and activate the printer pass-through. */
844a8fe65b8SJeff Kirsher 	write_reg_high(ioaddr, CMR1, CMR1h_RESET | CMR1h_MUX);
845a8fe65b8SJeff Kirsher 	return 0;
846a8fe65b8SJeff Kirsher }
847a8fe65b8SJeff Kirsher 
848a8fe65b8SJeff Kirsher /*
849a8fe65b8SJeff Kirsher  *	Set or clear the multicast filter for this adapter.
850a8fe65b8SJeff Kirsher  */
851a8fe65b8SJeff Kirsher 
852bb263e18SPaul Bolle static void set_rx_mode(struct net_device *dev)
853a8fe65b8SJeff Kirsher {
854a8fe65b8SJeff Kirsher 	struct net_local *lp = netdev_priv(dev);
855a8fe65b8SJeff Kirsher 	long ioaddr = dev->base_addr;
856a8fe65b8SJeff Kirsher 
857a8fe65b8SJeff Kirsher 	if (!netdev_mc_empty(dev) || (dev->flags & (IFF_ALLMULTI|IFF_PROMISC)))
858a8fe65b8SJeff Kirsher 		lp->addr_mode = CMR2h_PROMISC;
859a8fe65b8SJeff Kirsher 	else
860a8fe65b8SJeff Kirsher 		lp->addr_mode = CMR2h_Normal;
861a8fe65b8SJeff Kirsher 	write_reg_high(ioaddr, CMR2, lp->addr_mode);
862a8fe65b8SJeff Kirsher }
863a8fe65b8SJeff Kirsher 
864a8fe65b8SJeff Kirsher static int __init atp_init_module(void) {
865a8fe65b8SJeff Kirsher 	if (debug)					/* Emit version even if no cards detected. */
866a8fe65b8SJeff Kirsher 		printk(KERN_INFO "%s", version);
867a8fe65b8SJeff Kirsher 	return atp_init();
868a8fe65b8SJeff Kirsher }
869a8fe65b8SJeff Kirsher 
870a8fe65b8SJeff Kirsher static void __exit atp_cleanup_module(void) {
871a8fe65b8SJeff Kirsher 	struct net_device *next_dev;
872a8fe65b8SJeff Kirsher 
873a8fe65b8SJeff Kirsher 	while (root_atp_dev) {
874a8fe65b8SJeff Kirsher 		struct net_local *atp_local = netdev_priv(root_atp_dev);
875a8fe65b8SJeff Kirsher 		next_dev = atp_local->next_module;
876a8fe65b8SJeff Kirsher 		unregister_netdev(root_atp_dev);
877a8fe65b8SJeff Kirsher 		/* No need to release_region(), since we never snarf it. */
878a8fe65b8SJeff Kirsher 		free_netdev(root_atp_dev);
879a8fe65b8SJeff Kirsher 		root_atp_dev = next_dev;
880a8fe65b8SJeff Kirsher 	}
881a8fe65b8SJeff Kirsher }
882a8fe65b8SJeff Kirsher 
883a8fe65b8SJeff Kirsher module_init(atp_init_module);
884a8fe65b8SJeff Kirsher module_exit(atp_cleanup_module);
885