xref: /openbmc/linux/drivers/net/ethernet/realtek/atp.c (revision 923ca6f6)
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    */
atp_init(void)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 
atp_probe1(long ioaddr)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. */
get_node_ID(struct net_device * dev)368a8fe65b8SJeff Kirsher static void __init get_node_ID(struct net_device *dev)
369a8fe65b8SJeff Kirsher {
370a8fe65b8SJeff Kirsher 	long ioaddr = dev->base_addr;
371*923ca6f6SJakub Kicinski 	__be16 addr[ETH_ALEN / 2];
372a8fe65b8SJeff Kirsher 	int sa_offset = 0;
373a8fe65b8SJeff Kirsher 	int i;
374a8fe65b8SJeff Kirsher 
375a8fe65b8SJeff Kirsher 	write_reg(ioaddr, CMR2, CMR2_EEPROM);	  /* Point to the EEPROM control registers. */
376a8fe65b8SJeff Kirsher 
377a8fe65b8SJeff Kirsher 	/* Some adapters have the station address at offset 15 instead of offset
378a8fe65b8SJeff Kirsher 	   zero.  Check for it, and fix it if needed. */
379a8fe65b8SJeff Kirsher 	if (eeprom_op(ioaddr, EE_READ(0)) == 0xffff)
380a8fe65b8SJeff Kirsher 		sa_offset = 15;
381a8fe65b8SJeff Kirsher 
382a8fe65b8SJeff Kirsher 	for (i = 0; i < 3; i++)
383*923ca6f6SJakub Kicinski 		addr[i] =
384a8fe65b8SJeff Kirsher 			cpu_to_be16(eeprom_op(ioaddr, EE_READ(sa_offset + i)));
385*923ca6f6SJakub Kicinski 	eth_hw_addr_set(dev, (u8 *)addr);
386a8fe65b8SJeff Kirsher 
387a8fe65b8SJeff Kirsher 	write_reg(ioaddr, CMR2, CMR2_NULL);
388a8fe65b8SJeff Kirsher }
389a8fe65b8SJeff Kirsher 
390a8fe65b8SJeff Kirsher /*
391a8fe65b8SJeff Kirsher   An EEPROM read command starts by shifting out 0x60+address, and then
392a8fe65b8SJeff Kirsher   shifting in the serial data. See the NatSemi databook for details.
393a8fe65b8SJeff Kirsher  *		   ________________
394a8fe65b8SJeff Kirsher  * CS : __|
395a8fe65b8SJeff Kirsher  *			   ___	   ___
396a8fe65b8SJeff Kirsher  * CLK: ______|	  |___|	  |
397a8fe65b8SJeff Kirsher  *		 __ _______ _______
398a8fe65b8SJeff Kirsher  * DI :	 __X_______X_______X
399a8fe65b8SJeff Kirsher  * DO :	 _________X_______X
400a8fe65b8SJeff Kirsher  */
401a8fe65b8SJeff Kirsher 
eeprom_op(long ioaddr,u32 cmd)402a8fe65b8SJeff Kirsher static unsigned short __init eeprom_op(long ioaddr, u32 cmd)
403a8fe65b8SJeff Kirsher {
404a8fe65b8SJeff Kirsher 	unsigned eedata_out = 0;
405a8fe65b8SJeff Kirsher 	int num_bits = EE_CMD_SIZE;
406a8fe65b8SJeff Kirsher 
407a8fe65b8SJeff Kirsher 	while (--num_bits >= 0) {
408a8fe65b8SJeff Kirsher 		char outval = (cmd & (1<<num_bits)) ? EE_DATA_WRITE : 0;
409a8fe65b8SJeff Kirsher 		write_reg_high(ioaddr, PROM_CMD, outval | EE_CLK_LOW);
410a8fe65b8SJeff Kirsher 		write_reg_high(ioaddr, PROM_CMD, outval | EE_CLK_HIGH);
411a8fe65b8SJeff Kirsher 		eedata_out <<= 1;
412a8fe65b8SJeff Kirsher 		if (read_nibble(ioaddr, PROM_DATA) & EE_DATA_READ)
413a8fe65b8SJeff Kirsher 			eedata_out++;
414a8fe65b8SJeff Kirsher 	}
415a8fe65b8SJeff Kirsher 	write_reg_high(ioaddr, PROM_CMD, EE_CLK_LOW & ~EE_CS);
416a8fe65b8SJeff Kirsher 	return eedata_out;
417a8fe65b8SJeff Kirsher }
418a8fe65b8SJeff Kirsher 
419a8fe65b8SJeff Kirsher 
420a8fe65b8SJeff Kirsher /* Open/initialize the board.  This is called (in the current kernel)
421a8fe65b8SJeff Kirsher    sometime after booting when the 'ifconfig' program is run.
422a8fe65b8SJeff Kirsher 
423a8fe65b8SJeff Kirsher    This routine sets everything up anew at each open, even
424a8fe65b8SJeff Kirsher    registers that "should" only need to be set once at boot, so that
425a8fe65b8SJeff Kirsher    there is non-reboot way to recover if something goes wrong.
426a8fe65b8SJeff Kirsher 
427a8fe65b8SJeff Kirsher    This is an attachable device: if there is no private entry then it wasn't
428a8fe65b8SJeff Kirsher    probed for at boot-time, and we need to probe for it again.
429a8fe65b8SJeff Kirsher    */
net_open(struct net_device * dev)430a8fe65b8SJeff Kirsher static int net_open(struct net_device *dev)
431a8fe65b8SJeff Kirsher {
432a8fe65b8SJeff Kirsher 	struct net_local *lp = netdev_priv(dev);
433a8fe65b8SJeff Kirsher 	int ret;
434a8fe65b8SJeff Kirsher 
435a8fe65b8SJeff Kirsher 	/* The interrupt line is turned off (tri-stated) when the device isn't in
436a8fe65b8SJeff Kirsher 	   use.  That's especially important for "attached" interfaces where the
437a8fe65b8SJeff Kirsher 	   port or interrupt may be shared. */
438a8fe65b8SJeff Kirsher 	ret = request_irq(dev->irq, atp_interrupt, 0, dev->name, dev);
439a8fe65b8SJeff Kirsher 	if (ret)
440a8fe65b8SJeff Kirsher 		return ret;
441a8fe65b8SJeff Kirsher 
442a8fe65b8SJeff Kirsher 	hardware_init(dev);
443a8fe65b8SJeff Kirsher 
4449de36ccfSKees Cook 	lp->dev = dev;
4459de36ccfSKees Cook 	timer_setup(&lp->timer, atp_timed_checker, 0);
446a8fe65b8SJeff Kirsher 	lp->timer.expires = jiffies + TIMED_CHECKER;
447a8fe65b8SJeff Kirsher 	add_timer(&lp->timer);
448a8fe65b8SJeff Kirsher 
449a8fe65b8SJeff Kirsher 	netif_start_queue(dev);
450a8fe65b8SJeff Kirsher 	return 0;
451a8fe65b8SJeff Kirsher }
452a8fe65b8SJeff Kirsher 
453a8fe65b8SJeff Kirsher /* This routine resets the hardware.  We initialize everything, assuming that
454a8fe65b8SJeff Kirsher    the hardware may have been temporarily detached. */
hardware_init(struct net_device * dev)455a8fe65b8SJeff Kirsher static void hardware_init(struct net_device *dev)
456a8fe65b8SJeff Kirsher {
457a8fe65b8SJeff Kirsher 	struct net_local *lp = netdev_priv(dev);
458a8fe65b8SJeff Kirsher 	long ioaddr = dev->base_addr;
459a8fe65b8SJeff Kirsher 	int i;
460a8fe65b8SJeff Kirsher 
461a8fe65b8SJeff Kirsher 	/* Turn off the printer multiplexer on the 8012. */
462a8fe65b8SJeff Kirsher 	for (i = 0; i < 8; i++)
463a8fe65b8SJeff Kirsher 		outb(mux_8012[i], ioaddr + PAR_DATA);
464a8fe65b8SJeff Kirsher 	write_reg_high(ioaddr, CMR1, CMR1h_RESET);
465a8fe65b8SJeff Kirsher 
466a8fe65b8SJeff Kirsher 	for (i = 0; i < 6; i++)
467a8fe65b8SJeff Kirsher 		write_reg_byte(ioaddr, PAR0 + i, dev->dev_addr[i]);
468a8fe65b8SJeff Kirsher 
469a8fe65b8SJeff Kirsher 	write_reg_high(ioaddr, CMR2, lp->addr_mode);
470a8fe65b8SJeff Kirsher 
471a8fe65b8SJeff Kirsher 	if (net_debug > 2) {
472a8fe65b8SJeff Kirsher 		printk(KERN_DEBUG "%s: Reset: current Rx mode %d.\n", dev->name,
473a8fe65b8SJeff Kirsher 			   (read_nibble(ioaddr, CMR2_h) >> 3) & 0x0f);
474a8fe65b8SJeff Kirsher 	}
475a8fe65b8SJeff Kirsher 
476a8fe65b8SJeff Kirsher 	write_reg(ioaddr, CMR2, CMR2_IRQOUT);
477a8fe65b8SJeff Kirsher 	write_reg_high(ioaddr, CMR1, CMR1h_RxENABLE | CMR1h_TxENABLE);
478a8fe65b8SJeff Kirsher 
479a8fe65b8SJeff Kirsher 	/* Enable the interrupt line from the serial port. */
480a8fe65b8SJeff Kirsher 	outb(Ctrl_SelData + Ctrl_IRQEN, ioaddr + PAR_CONTROL);
481a8fe65b8SJeff Kirsher 
482a8fe65b8SJeff Kirsher 	/* Unmask the interesting interrupts. */
483a8fe65b8SJeff Kirsher 	write_reg(ioaddr, IMR, ISR_RxOK | ISR_TxErr | ISR_TxOK);
484a8fe65b8SJeff Kirsher 	write_reg_high(ioaddr, IMR, ISRh_RxErr);
485a8fe65b8SJeff Kirsher 
486a8fe65b8SJeff Kirsher 	lp->tx_unit_busy = 0;
487a8fe65b8SJeff Kirsher 	lp->pac_cnt_in_tx_buf = 0;
488a8fe65b8SJeff Kirsher 	lp->saved_tx_size = 0;
489a8fe65b8SJeff Kirsher }
490a8fe65b8SJeff Kirsher 
trigger_send(long ioaddr,int length)491a8fe65b8SJeff Kirsher static void trigger_send(long ioaddr, int length)
492a8fe65b8SJeff Kirsher {
493a8fe65b8SJeff Kirsher 	write_reg_byte(ioaddr, TxCNT0, length & 0xff);
494a8fe65b8SJeff Kirsher 	write_reg(ioaddr, TxCNT1, length >> 8);
495a8fe65b8SJeff Kirsher 	write_reg(ioaddr, CMR1, CMR1_Xmit);
496a8fe65b8SJeff Kirsher }
497a8fe65b8SJeff Kirsher 
write_packet(long ioaddr,int length,unsigned char * packet,int pad_len,int data_mode)498a8fe65b8SJeff Kirsher static void write_packet(long ioaddr, int length, unsigned char *packet, int pad_len, int data_mode)
499a8fe65b8SJeff Kirsher {
500a8fe65b8SJeff Kirsher     if (length & 1)
501a8fe65b8SJeff Kirsher     {
502a8fe65b8SJeff Kirsher 	length++;
503a8fe65b8SJeff Kirsher 	pad_len++;
504a8fe65b8SJeff Kirsher     }
505a8fe65b8SJeff Kirsher 
506a8fe65b8SJeff Kirsher     outb(EOC+MAR, ioaddr + PAR_DATA);
507a8fe65b8SJeff Kirsher     if ((data_mode & 1) == 0) {
508a8fe65b8SJeff Kirsher 		/* Write the packet out, starting with the write addr. */
509a8fe65b8SJeff Kirsher 		outb(WrAddr+MAR, ioaddr + PAR_DATA);
510a8fe65b8SJeff Kirsher 		do {
511a8fe65b8SJeff Kirsher 			write_byte_mode0(ioaddr, *packet++);
512a8fe65b8SJeff Kirsher 		} while (--length > pad_len) ;
513a8fe65b8SJeff Kirsher 		do {
514a8fe65b8SJeff Kirsher 			write_byte_mode0(ioaddr, 0);
515a8fe65b8SJeff Kirsher 		} while (--length > 0) ;
516a8fe65b8SJeff Kirsher     } else {
517a8fe65b8SJeff Kirsher 		/* Write the packet out in slow mode. */
518a8fe65b8SJeff Kirsher 		unsigned char outbyte = *packet++;
519a8fe65b8SJeff Kirsher 
520a8fe65b8SJeff Kirsher 		outb(Ctrl_LNibWrite + Ctrl_IRQEN, ioaddr + PAR_CONTROL);
521a8fe65b8SJeff Kirsher 		outb(WrAddr+MAR, ioaddr + PAR_DATA);
522a8fe65b8SJeff Kirsher 
523a8fe65b8SJeff Kirsher 		outb((outbyte & 0x0f)|0x40, ioaddr + PAR_DATA);
524a8fe65b8SJeff Kirsher 		outb(outbyte & 0x0f, ioaddr + PAR_DATA);
525a8fe65b8SJeff Kirsher 		outbyte >>= 4;
526a8fe65b8SJeff Kirsher 		outb(outbyte & 0x0f, ioaddr + PAR_DATA);
527a8fe65b8SJeff Kirsher 		outb(Ctrl_HNibWrite + Ctrl_IRQEN, ioaddr + PAR_CONTROL);
528a8fe65b8SJeff Kirsher 		while (--length > pad_len)
529a8fe65b8SJeff Kirsher 			write_byte_mode1(ioaddr, *packet++);
530a8fe65b8SJeff Kirsher 		while (--length > 0)
531a8fe65b8SJeff Kirsher 			write_byte_mode1(ioaddr, 0);
532a8fe65b8SJeff Kirsher     }
533a8fe65b8SJeff Kirsher     /* Terminate the Tx frame.  End of write: ECB. */
534a8fe65b8SJeff Kirsher     outb(0xff, ioaddr + PAR_DATA);
535a8fe65b8SJeff Kirsher     outb(Ctrl_HNibWrite | Ctrl_SelData | Ctrl_IRQEN, ioaddr + PAR_CONTROL);
536a8fe65b8SJeff Kirsher }
537a8fe65b8SJeff Kirsher 
tx_timeout(struct net_device * dev,unsigned int txqueue)5380290bd29SMichael S. Tsirkin static void tx_timeout(struct net_device *dev, unsigned int txqueue)
539a8fe65b8SJeff Kirsher {
540a8fe65b8SJeff Kirsher 	long ioaddr = dev->base_addr;
541a8fe65b8SJeff Kirsher 
542a8fe65b8SJeff Kirsher 	printk(KERN_WARNING "%s: Transmit timed out, %s?\n", dev->name,
543a8fe65b8SJeff Kirsher 		   inb(ioaddr + PAR_CONTROL) & 0x10 ? "network cable problem"
544a8fe65b8SJeff Kirsher 		   :  "IRQ conflict");
545a8fe65b8SJeff Kirsher 	dev->stats.tx_errors++;
546a8fe65b8SJeff Kirsher 	/* Try to restart the adapter. */
547a8fe65b8SJeff Kirsher 	hardware_init(dev);
548860e9538SFlorian Westphal 	netif_trans_update(dev); /* prevent tx timeout */
549a8fe65b8SJeff Kirsher 	netif_wake_queue(dev);
550a8fe65b8SJeff Kirsher 	dev->stats.tx_errors++;
551a8fe65b8SJeff Kirsher }
552a8fe65b8SJeff Kirsher 
atp_send_packet(struct sk_buff * skb,struct net_device * dev)553a8fe65b8SJeff Kirsher static netdev_tx_t atp_send_packet(struct sk_buff *skb,
554a8fe65b8SJeff Kirsher 				   struct net_device *dev)
555a8fe65b8SJeff Kirsher {
556a8fe65b8SJeff Kirsher 	struct net_local *lp = netdev_priv(dev);
557a8fe65b8SJeff Kirsher 	long ioaddr = dev->base_addr;
558a8fe65b8SJeff Kirsher 	int length;
559a8fe65b8SJeff Kirsher 	unsigned long flags;
560a8fe65b8SJeff Kirsher 
561a8fe65b8SJeff Kirsher 	length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
562a8fe65b8SJeff Kirsher 
563a8fe65b8SJeff Kirsher 	netif_stop_queue(dev);
564a8fe65b8SJeff Kirsher 
565a8fe65b8SJeff Kirsher 	/* Disable interrupts by writing 0x00 to the Interrupt Mask Register.
566a8fe65b8SJeff Kirsher 	   This sequence must not be interrupted by an incoming packet. */
567a8fe65b8SJeff Kirsher 
568a8fe65b8SJeff Kirsher 	spin_lock_irqsave(&lp->lock, flags);
569a8fe65b8SJeff Kirsher 	write_reg(ioaddr, IMR, 0);
570a8fe65b8SJeff Kirsher 	write_reg_high(ioaddr, IMR, 0);
571a8fe65b8SJeff Kirsher 	spin_unlock_irqrestore(&lp->lock, flags);
572a8fe65b8SJeff Kirsher 
573a8fe65b8SJeff Kirsher 	write_packet(ioaddr, length, skb->data, length-skb->len, dev->if_port);
574a8fe65b8SJeff Kirsher 
575a8fe65b8SJeff Kirsher 	lp->pac_cnt_in_tx_buf++;
576a8fe65b8SJeff Kirsher 	if (lp->tx_unit_busy == 0) {
577a8fe65b8SJeff Kirsher 		trigger_send(ioaddr, length);
578a8fe65b8SJeff Kirsher 		lp->saved_tx_size = 0; 				/* Redundant */
579a8fe65b8SJeff Kirsher 		lp->re_tx = 0;
580a8fe65b8SJeff Kirsher 		lp->tx_unit_busy = 1;
581a8fe65b8SJeff Kirsher 	} else
582a8fe65b8SJeff Kirsher 		lp->saved_tx_size = length;
583a8fe65b8SJeff Kirsher 	/* Re-enable the LPT interrupts. */
584a8fe65b8SJeff Kirsher 	write_reg(ioaddr, IMR, ISR_RxOK | ISR_TxErr | ISR_TxOK);
585a8fe65b8SJeff Kirsher 	write_reg_high(ioaddr, IMR, ISRh_RxErr);
586a8fe65b8SJeff Kirsher 
587a8fe65b8SJeff Kirsher 	dev_kfree_skb (skb);
588a8fe65b8SJeff Kirsher 	return NETDEV_TX_OK;
589a8fe65b8SJeff Kirsher }
590a8fe65b8SJeff Kirsher 
591a8fe65b8SJeff Kirsher 
592a8fe65b8SJeff Kirsher /* The typical workload of the driver:
593a8fe65b8SJeff Kirsher    Handle the network interface interrupts. */
atp_interrupt(int irq,void * dev_instance)594a8fe65b8SJeff Kirsher static irqreturn_t atp_interrupt(int irq, void *dev_instance)
595a8fe65b8SJeff Kirsher {
596a8fe65b8SJeff Kirsher 	struct net_device *dev = dev_instance;
597a8fe65b8SJeff Kirsher 	struct net_local *lp;
598a8fe65b8SJeff Kirsher 	long ioaddr;
599a8fe65b8SJeff Kirsher 	static int num_tx_since_rx;
600a8fe65b8SJeff Kirsher 	int boguscount = max_interrupt_work;
601a8fe65b8SJeff Kirsher 	int handled = 0;
602a8fe65b8SJeff Kirsher 
603a8fe65b8SJeff Kirsher 	ioaddr = dev->base_addr;
604a8fe65b8SJeff Kirsher 	lp = netdev_priv(dev);
605a8fe65b8SJeff Kirsher 
606a8fe65b8SJeff Kirsher 	spin_lock(&lp->lock);
607a8fe65b8SJeff Kirsher 
608a8fe65b8SJeff Kirsher 	/* Disable additional spurious interrupts. */
609a8fe65b8SJeff Kirsher 	outb(Ctrl_SelData, ioaddr + PAR_CONTROL);
610a8fe65b8SJeff Kirsher 
611a8fe65b8SJeff Kirsher 	/* The adapter's output is currently the IRQ line, switch it to data. */
612a8fe65b8SJeff Kirsher 	write_reg(ioaddr, CMR2, CMR2_NULL);
613a8fe65b8SJeff Kirsher 	write_reg(ioaddr, IMR, 0);
614a8fe65b8SJeff Kirsher 
615eedfb223SColin Ian King 	if (net_debug > 5)
616eedfb223SColin Ian King 		printk(KERN_DEBUG "%s: In interrupt ", dev->name);
617a8fe65b8SJeff Kirsher 	while (--boguscount > 0) {
618a8fe65b8SJeff Kirsher 		int status = read_nibble(ioaddr, ISR);
619eedfb223SColin Ian King 		if (net_debug > 5)
620eedfb223SColin Ian King 			printk("loop status %02x..", status);
621a8fe65b8SJeff Kirsher 
622a8fe65b8SJeff Kirsher 		if (status & (ISR_RxOK<<3)) {
623a8fe65b8SJeff Kirsher 			handled = 1;
624a8fe65b8SJeff Kirsher 			write_reg(ioaddr, ISR, ISR_RxOK); /* Clear the Rx interrupt. */
625a8fe65b8SJeff Kirsher 			do {
626a8fe65b8SJeff Kirsher 				int read_status = read_nibble(ioaddr, CMR1);
627a8fe65b8SJeff Kirsher 				if (net_debug > 6)
628a8fe65b8SJeff Kirsher 					printk("handling Rx packet %02x..", read_status);
629a8fe65b8SJeff Kirsher 				/* We acknowledged the normal Rx interrupt, so if the interrupt
630a8fe65b8SJeff Kirsher 				   is still outstanding we must have a Rx error. */
631a8fe65b8SJeff Kirsher 				if (read_status & (CMR1_IRQ << 3)) { /* Overrun. */
632a8fe65b8SJeff Kirsher 					dev->stats.rx_over_errors++;
633a8fe65b8SJeff Kirsher 					/* Set to no-accept mode long enough to remove a packet. */
634a8fe65b8SJeff Kirsher 					write_reg_high(ioaddr, CMR2, CMR2h_OFF);
635a8fe65b8SJeff Kirsher 					net_rx(dev);
636a8fe65b8SJeff Kirsher 					/* Clear the interrupt and return to normal Rx mode. */
637a8fe65b8SJeff Kirsher 					write_reg_high(ioaddr, ISR, ISRh_RxErr);
638a8fe65b8SJeff Kirsher 					write_reg_high(ioaddr, CMR2, lp->addr_mode);
639a8fe65b8SJeff Kirsher 				} else if ((read_status & (CMR1_BufEnb << 3)) == 0) {
640a8fe65b8SJeff Kirsher 					net_rx(dev);
641a8fe65b8SJeff Kirsher 					num_tx_since_rx = 0;
642a8fe65b8SJeff Kirsher 				} else
643a8fe65b8SJeff Kirsher 					break;
644a8fe65b8SJeff Kirsher 			} while (--boguscount > 0);
645a8fe65b8SJeff Kirsher 		} else if (status & ((ISR_TxErr + ISR_TxOK)<<3)) {
646a8fe65b8SJeff Kirsher 			handled = 1;
647eedfb223SColin Ian King 			if (net_debug > 6)
648eedfb223SColin Ian King 				printk("handling Tx done..");
649a8fe65b8SJeff Kirsher 			/* Clear the Tx interrupt.  We should check for too many failures
650a8fe65b8SJeff Kirsher 			   and reinitialize the adapter. */
651a8fe65b8SJeff Kirsher 			write_reg(ioaddr, ISR, ISR_TxErr + ISR_TxOK);
652a8fe65b8SJeff Kirsher 			if (status & (ISR_TxErr<<3)) {
653a8fe65b8SJeff Kirsher 				dev->stats.collisions++;
654a8fe65b8SJeff Kirsher 				if (++lp->re_tx > 15) {
655a8fe65b8SJeff Kirsher 					dev->stats.tx_aborted_errors++;
656a8fe65b8SJeff Kirsher 					hardware_init(dev);
657a8fe65b8SJeff Kirsher 					break;
658a8fe65b8SJeff Kirsher 				}
659a8fe65b8SJeff Kirsher 				/* Attempt to retransmit. */
660a8fe65b8SJeff Kirsher 				if (net_debug > 6)  printk("attempting to ReTx");
661a8fe65b8SJeff Kirsher 				write_reg(ioaddr, CMR1, CMR1_ReXmit + CMR1_Xmit);
662a8fe65b8SJeff Kirsher 			} else {
663a8fe65b8SJeff Kirsher 				/* Finish up the transmit. */
664a8fe65b8SJeff Kirsher 				dev->stats.tx_packets++;
665a8fe65b8SJeff Kirsher 				lp->pac_cnt_in_tx_buf--;
666a8fe65b8SJeff Kirsher 				if ( lp->saved_tx_size) {
667a8fe65b8SJeff Kirsher 					trigger_send(ioaddr, lp->saved_tx_size);
668a8fe65b8SJeff Kirsher 					lp->saved_tx_size = 0;
669a8fe65b8SJeff Kirsher 					lp->re_tx = 0;
670a8fe65b8SJeff Kirsher 				} else
671a8fe65b8SJeff Kirsher 					lp->tx_unit_busy = 0;
672a8fe65b8SJeff Kirsher 				netif_wake_queue(dev);	/* Inform upper layers. */
673a8fe65b8SJeff Kirsher 			}
674a8fe65b8SJeff Kirsher 			num_tx_since_rx++;
675a8fe65b8SJeff Kirsher 		} else if (num_tx_since_rx > 8 &&
6764a7c9726STobias Klauser 			   time_after(jiffies, lp->last_rx_time + HZ)) {
677a8fe65b8SJeff Kirsher 			if (net_debug > 2)
678a8fe65b8SJeff Kirsher 				printk(KERN_DEBUG "%s: Missed packet? No Rx after %d Tx and "
679a8fe65b8SJeff Kirsher 					   "%ld jiffies status %02x  CMR1 %02x.\n", dev->name,
6804a7c9726STobias Klauser 					   num_tx_since_rx, jiffies - lp->last_rx_time, status,
681a8fe65b8SJeff Kirsher 					   (read_nibble(ioaddr, CMR1) >> 3) & 15);
682a8fe65b8SJeff Kirsher 			dev->stats.rx_missed_errors++;
683a8fe65b8SJeff Kirsher 			hardware_init(dev);
684a8fe65b8SJeff Kirsher 			num_tx_since_rx = 0;
685a8fe65b8SJeff Kirsher 			break;
686a8fe65b8SJeff Kirsher 		} else
687a8fe65b8SJeff Kirsher 			break;
688a8fe65b8SJeff Kirsher 	}
689a8fe65b8SJeff Kirsher 
690a8fe65b8SJeff Kirsher 	/* This following code fixes a rare (and very difficult to track down)
691a8fe65b8SJeff Kirsher 	   problem where the adapter forgets its ethernet address. */
692a8fe65b8SJeff Kirsher 	{
693a8fe65b8SJeff Kirsher 		int i;
694a8fe65b8SJeff Kirsher 		for (i = 0; i < 6; i++)
695a8fe65b8SJeff Kirsher 			write_reg_byte(ioaddr, PAR0 + i, dev->dev_addr[i]);
696a8fe65b8SJeff Kirsher #if 0 && defined(TIMED_CHECKER)
697a8fe65b8SJeff Kirsher 		mod_timer(&lp->timer, jiffies + TIMED_CHECKER);
698a8fe65b8SJeff Kirsher #endif
699a8fe65b8SJeff Kirsher 	}
700a8fe65b8SJeff Kirsher 
701a8fe65b8SJeff Kirsher 	/* Tell the adapter that it can go back to using the output line as IRQ. */
702a8fe65b8SJeff Kirsher 	write_reg(ioaddr, CMR2, CMR2_IRQOUT);
703a8fe65b8SJeff Kirsher 	/* Enable the physical interrupt line, which is sure to be low until.. */
704a8fe65b8SJeff Kirsher 	outb(Ctrl_SelData + Ctrl_IRQEN, ioaddr + PAR_CONTROL);
705a8fe65b8SJeff Kirsher 	/* .. we enable the interrupt sources. */
706a8fe65b8SJeff Kirsher 	write_reg(ioaddr, IMR, ISR_RxOK | ISR_TxErr | ISR_TxOK);
707a8fe65b8SJeff Kirsher 	write_reg_high(ioaddr, IMR, ISRh_RxErr); 			/* Hmmm, really needed? */
708a8fe65b8SJeff Kirsher 
709a8fe65b8SJeff Kirsher 	spin_unlock(&lp->lock);
710a8fe65b8SJeff Kirsher 
711a8fe65b8SJeff Kirsher 	if (net_debug > 5) printk("exiting interrupt.\n");
712a8fe65b8SJeff Kirsher 	return IRQ_RETVAL(handled);
713a8fe65b8SJeff Kirsher }
714a8fe65b8SJeff Kirsher 
715a8fe65b8SJeff Kirsher #ifdef TIMED_CHECKER
716a8fe65b8SJeff Kirsher /* This following code fixes a rare (and very difficult to track down)
717a8fe65b8SJeff Kirsher    problem where the adapter forgets its ethernet address. */
atp_timed_checker(struct timer_list * t)7189de36ccfSKees Cook static void atp_timed_checker(struct timer_list *t)
719a8fe65b8SJeff Kirsher {
7209de36ccfSKees Cook 	struct net_local *lp = from_timer(lp, t, timer);
7219de36ccfSKees Cook 	struct net_device *dev = lp->dev;
722a8fe65b8SJeff Kirsher 	long ioaddr = dev->base_addr;
723a8fe65b8SJeff Kirsher 	int tickssofar = jiffies - lp->last_rx_time;
724a8fe65b8SJeff Kirsher 	int i;
725a8fe65b8SJeff Kirsher 
726a8fe65b8SJeff Kirsher 	spin_lock(&lp->lock);
727a8fe65b8SJeff Kirsher 	if (tickssofar > 2*HZ) {
728a8fe65b8SJeff Kirsher #if 1
729a8fe65b8SJeff Kirsher 		for (i = 0; i < 6; i++)
730a8fe65b8SJeff Kirsher 			write_reg_byte(ioaddr, PAR0 + i, dev->dev_addr[i]);
731a8fe65b8SJeff Kirsher 		lp->last_rx_time = jiffies;
732a8fe65b8SJeff Kirsher #else
733a8fe65b8SJeff Kirsher 		for (i = 0; i < 6; i++)
734a8fe65b8SJeff Kirsher 			if (read_cmd_byte(ioaddr, PAR0 + i) != atp_timed_dev->dev_addr[i])
735a8fe65b8SJeff Kirsher 				{
736a8fe65b8SJeff Kirsher 			struct net_local *lp = netdev_priv(atp_timed_dev);
737a8fe65b8SJeff Kirsher 			write_reg_byte(ioaddr, PAR0 + i, atp_timed_dev->dev_addr[i]);
738a8fe65b8SJeff Kirsher 			if (i == 2)
739a8fe65b8SJeff Kirsher 			  dev->stats.tx_errors++;
740a8fe65b8SJeff Kirsher 			else if (i == 3)
741a8fe65b8SJeff Kirsher 			  dev->stats.tx_dropped++;
742a8fe65b8SJeff Kirsher 			else if (i == 4)
743a8fe65b8SJeff Kirsher 			  dev->stats.collisions++;
744a8fe65b8SJeff Kirsher 			else
745a8fe65b8SJeff Kirsher 			  dev->stats.rx_errors++;
746a8fe65b8SJeff Kirsher 		  }
747a8fe65b8SJeff Kirsher #endif
748a8fe65b8SJeff Kirsher 	}
749a8fe65b8SJeff Kirsher 	spin_unlock(&lp->lock);
750a8fe65b8SJeff Kirsher 	lp->timer.expires = jiffies + TIMED_CHECKER;
751a8fe65b8SJeff Kirsher 	add_timer(&lp->timer);
752a8fe65b8SJeff Kirsher }
753a8fe65b8SJeff Kirsher #endif
754a8fe65b8SJeff Kirsher 
755a8fe65b8SJeff Kirsher /* We have a good packet(s), get it/them out of the buffers. */
net_rx(struct net_device * dev)756a8fe65b8SJeff Kirsher static void net_rx(struct net_device *dev)
757a8fe65b8SJeff Kirsher {
758a8fe65b8SJeff Kirsher 	struct net_local *lp = netdev_priv(dev);
759a8fe65b8SJeff Kirsher 	long ioaddr = dev->base_addr;
760a8fe65b8SJeff Kirsher 	struct rx_header rx_head;
761a8fe65b8SJeff Kirsher 
762a8fe65b8SJeff Kirsher 	/* Process the received packet. */
763a8fe65b8SJeff Kirsher 	outb(EOC+MAR, ioaddr + PAR_DATA);
764a8fe65b8SJeff Kirsher 	read_block(ioaddr, 8, (unsigned char*)&rx_head, dev->if_port);
765a8fe65b8SJeff Kirsher 	if (net_debug > 5)
766a8fe65b8SJeff Kirsher 		printk(KERN_DEBUG " rx_count %04x %04x %04x %04x..", rx_head.pad,
767a8fe65b8SJeff Kirsher 			   rx_head.rx_count, rx_head.rx_status, rx_head.cur_addr);
768a8fe65b8SJeff Kirsher 	if ((rx_head.rx_status & 0x77) != 0x01) {
769a8fe65b8SJeff Kirsher 		dev->stats.rx_errors++;
770a8fe65b8SJeff Kirsher 		if (rx_head.rx_status & 0x0004) dev->stats.rx_frame_errors++;
771a8fe65b8SJeff Kirsher 		else if (rx_head.rx_status & 0x0002) dev->stats.rx_crc_errors++;
772a8fe65b8SJeff Kirsher 		if (net_debug > 3)
773a8fe65b8SJeff Kirsher 			printk(KERN_DEBUG "%s: Unknown ATP Rx error %04x.\n",
774a8fe65b8SJeff Kirsher 				   dev->name, rx_head.rx_status);
775a8fe65b8SJeff Kirsher 		if  (rx_head.rx_status & 0x0020) {
776a8fe65b8SJeff Kirsher 			dev->stats.rx_fifo_errors++;
777a8fe65b8SJeff Kirsher 			write_reg_high(ioaddr, CMR1, CMR1h_TxENABLE);
778a8fe65b8SJeff Kirsher 			write_reg_high(ioaddr, CMR1, CMR1h_RxENABLE | CMR1h_TxENABLE);
779a8fe65b8SJeff Kirsher 		} else if (rx_head.rx_status & 0x0050)
780a8fe65b8SJeff Kirsher 			hardware_init(dev);
781a8fe65b8SJeff Kirsher 		return;
782a8fe65b8SJeff Kirsher 	} else {
783a8fe65b8SJeff Kirsher 		/* Malloc up new buffer. The "-4" omits the FCS (CRC). */
784a8fe65b8SJeff Kirsher 		int pkt_len = (rx_head.rx_count & 0x7ff) - 4;
785a8fe65b8SJeff Kirsher 		struct sk_buff *skb;
786a8fe65b8SJeff Kirsher 
787dae2e9f4SPradeep A. Dalvi 		skb = netdev_alloc_skb(dev, pkt_len + 2);
788a8fe65b8SJeff Kirsher 		if (skb == NULL) {
789a8fe65b8SJeff Kirsher 			dev->stats.rx_dropped++;
790a8fe65b8SJeff Kirsher 			goto done;
791a8fe65b8SJeff Kirsher 		}
792a8fe65b8SJeff Kirsher 
793a8fe65b8SJeff Kirsher 		skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
794a8fe65b8SJeff Kirsher 		read_block(ioaddr, pkt_len, skb_put(skb,pkt_len), dev->if_port);
795a8fe65b8SJeff Kirsher 		skb->protocol = eth_type_trans(skb, dev);
796a8fe65b8SJeff Kirsher 		netif_rx(skb);
797a8fe65b8SJeff Kirsher 		dev->stats.rx_packets++;
798a8fe65b8SJeff Kirsher 		dev->stats.rx_bytes += pkt_len;
799a8fe65b8SJeff Kirsher 	}
800a8fe65b8SJeff Kirsher  done:
801a8fe65b8SJeff Kirsher 	write_reg(ioaddr, CMR1, CMR1_NextPkt);
802a8fe65b8SJeff Kirsher 	lp->last_rx_time = jiffies;
803a8fe65b8SJeff Kirsher }
804a8fe65b8SJeff Kirsher 
read_block(long ioaddr,int length,unsigned char * p,int data_mode)805a8fe65b8SJeff Kirsher static void read_block(long ioaddr, int length, unsigned char *p, int data_mode)
806a8fe65b8SJeff Kirsher {
807a8fe65b8SJeff Kirsher 	if (data_mode <= 3) { /* Mode 0 or 1 */
808a8fe65b8SJeff Kirsher 		outb(Ctrl_LNibRead, ioaddr + PAR_CONTROL);
809a8fe65b8SJeff Kirsher 		outb(length == 8  ?  RdAddr | HNib | MAR  :  RdAddr | MAR,
810a8fe65b8SJeff Kirsher 			 ioaddr + PAR_DATA);
811a8fe65b8SJeff Kirsher 		if (data_mode <= 1) { /* Mode 0 or 1 */
812a8fe65b8SJeff Kirsher 			do { *p++ = read_byte_mode0(ioaddr); } while (--length > 0);
813a8fe65b8SJeff Kirsher 		} else { /* Mode 2 or 3 */
814a8fe65b8SJeff Kirsher 			do { *p++ = read_byte_mode2(ioaddr); } while (--length > 0);
815a8fe65b8SJeff Kirsher 		}
816a8fe65b8SJeff Kirsher 	} else if (data_mode <= 5) {
817a8fe65b8SJeff Kirsher 		do { *p++ = read_byte_mode4(ioaddr); } while (--length > 0);
818a8fe65b8SJeff Kirsher 	} else {
819a8fe65b8SJeff Kirsher 		do { *p++ = read_byte_mode6(ioaddr); } while (--length > 0);
820a8fe65b8SJeff Kirsher 	}
821a8fe65b8SJeff Kirsher 
822a8fe65b8SJeff Kirsher 	outb(EOC+HNib+MAR, ioaddr + PAR_DATA);
823a8fe65b8SJeff Kirsher 	outb(Ctrl_SelData, ioaddr + PAR_CONTROL);
824a8fe65b8SJeff Kirsher }
825a8fe65b8SJeff Kirsher 
826a8fe65b8SJeff Kirsher /* The inverse routine to net_open(). */
827a8fe65b8SJeff Kirsher static int
net_close(struct net_device * dev)828a8fe65b8SJeff Kirsher net_close(struct net_device *dev)
829a8fe65b8SJeff Kirsher {
830a8fe65b8SJeff Kirsher 	struct net_local *lp = netdev_priv(dev);
831a8fe65b8SJeff Kirsher 	long ioaddr = dev->base_addr;
832a8fe65b8SJeff Kirsher 
833a8fe65b8SJeff Kirsher 	netif_stop_queue(dev);
834a8fe65b8SJeff Kirsher 
835a8fe65b8SJeff Kirsher 	del_timer_sync(&lp->timer);
836a8fe65b8SJeff Kirsher 
837a8fe65b8SJeff Kirsher 	/* Flush the Tx and disable Rx here. */
838a8fe65b8SJeff Kirsher 	lp->addr_mode = CMR2h_OFF;
839a8fe65b8SJeff Kirsher 	write_reg_high(ioaddr, CMR2, CMR2h_OFF);
840a8fe65b8SJeff Kirsher 
841a8fe65b8SJeff Kirsher 	/* Free the IRQ line. */
842a8fe65b8SJeff Kirsher 	outb(0x00, ioaddr + PAR_CONTROL);
843a8fe65b8SJeff Kirsher 	free_irq(dev->irq, dev);
844a8fe65b8SJeff Kirsher 
845a8fe65b8SJeff Kirsher 	/* Reset the ethernet hardware and activate the printer pass-through. */
846a8fe65b8SJeff Kirsher 	write_reg_high(ioaddr, CMR1, CMR1h_RESET | CMR1h_MUX);
847a8fe65b8SJeff Kirsher 	return 0;
848a8fe65b8SJeff Kirsher }
849a8fe65b8SJeff Kirsher 
850a8fe65b8SJeff Kirsher /*
851a8fe65b8SJeff Kirsher  *	Set or clear the multicast filter for this adapter.
852a8fe65b8SJeff Kirsher  */
853a8fe65b8SJeff Kirsher 
set_rx_mode(struct net_device * dev)854bb263e18SPaul Bolle static void set_rx_mode(struct net_device *dev)
855a8fe65b8SJeff Kirsher {
856a8fe65b8SJeff Kirsher 	struct net_local *lp = netdev_priv(dev);
857a8fe65b8SJeff Kirsher 	long ioaddr = dev->base_addr;
858a8fe65b8SJeff Kirsher 
859a8fe65b8SJeff Kirsher 	if (!netdev_mc_empty(dev) || (dev->flags & (IFF_ALLMULTI|IFF_PROMISC)))
860a8fe65b8SJeff Kirsher 		lp->addr_mode = CMR2h_PROMISC;
861a8fe65b8SJeff Kirsher 	else
862a8fe65b8SJeff Kirsher 		lp->addr_mode = CMR2h_Normal;
863a8fe65b8SJeff Kirsher 	write_reg_high(ioaddr, CMR2, lp->addr_mode);
864a8fe65b8SJeff Kirsher }
865a8fe65b8SJeff Kirsher 
atp_init_module(void)866a8fe65b8SJeff Kirsher static int __init atp_init_module(void) {
867a8fe65b8SJeff Kirsher 	if (debug)					/* Emit version even if no cards detected. */
868a8fe65b8SJeff Kirsher 		printk(KERN_INFO "%s", version);
869a8fe65b8SJeff Kirsher 	return atp_init();
870a8fe65b8SJeff Kirsher }
871a8fe65b8SJeff Kirsher 
atp_cleanup_module(void)872a8fe65b8SJeff Kirsher static void __exit atp_cleanup_module(void) {
873a8fe65b8SJeff Kirsher 	struct net_device *next_dev;
874a8fe65b8SJeff Kirsher 
875a8fe65b8SJeff Kirsher 	while (root_atp_dev) {
876a8fe65b8SJeff Kirsher 		struct net_local *atp_local = netdev_priv(root_atp_dev);
877a8fe65b8SJeff Kirsher 		next_dev = atp_local->next_module;
878a8fe65b8SJeff Kirsher 		unregister_netdev(root_atp_dev);
879a8fe65b8SJeff Kirsher 		/* No need to release_region(), since we never snarf it. */
880a8fe65b8SJeff Kirsher 		free_netdev(root_atp_dev);
881a8fe65b8SJeff Kirsher 		root_atp_dev = next_dev;
882a8fe65b8SJeff Kirsher 	}
883a8fe65b8SJeff Kirsher }
884a8fe65b8SJeff Kirsher 
885a8fe65b8SJeff Kirsher module_init(atp_init_module);
886a8fe65b8SJeff Kirsher module_exit(atp_cleanup_module);
887