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