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