* add p cc
[mascara-docs.git] / i386 / linux / linux-0.99 / drivers / net / at1700.c
blobcfc5922d7d045601fb9face37da560f703498f2e
1 /* at1700.c: A network device driver for the Allied Telesis AT1700.
3 Written 1993 by Donald Becker. This is a alpha test limited release.
4 This version may only be used and distributed according to the terms of the
5 GNU Public License, incorporated herein by reference.
7 The author may be reached as becker@super.org or
8 C/O Supercomputing Research Ctr., 17100 Science Dr., Bowie MD 20715
10 This is a device driver for the Allied Telesis AT1700, which is a
11 straight-foward Fujitsu MB86965 implementation.
14 static char *version =
15 "at1700.c:v0.03 11/16/93 Donald Becker (becker@super.org)\n";
17 #include <linux/config.h>
20 Sources:
21 The Fujitsu MB86695 datasheet.
24 #include <linux/kernel.h>
25 #include <linux/sched.h>
26 #include <linux/types.h>
27 #include <linux/fcntl.h>
28 #include <linux/interrupt.h>
29 #include <linux/ptrace.h>
30 #include <linux/ioport.h>
31 #include <linux/in.h>
32 #include <linux/malloc.h>
33 #include <asm/system.h>
34 #include <asm/bitops.h>
35 #include <asm/io.h>
36 #include <asm/dma.h>
37 #include <errno.h>
38 #include <memory.h>
40 #include "dev.h"
41 #include "eth.h"
42 #include "skbuff.h"
43 #include "arp.h"
45 #ifndef HAVE_AUTOIRQ
46 /* From auto_irq.c, in ioport.h for later versions. */
47 extern void autoirq_setup(int waittime);
48 extern int autoirq_report(int waittime);
49 /* The map from IRQ number (as passed to the interrupt handler) to
50 'struct device'. */
51 extern struct device *irq2dev_map[16];
52 #endif
54 #ifndef HAVE_ALLOC_SKB
55 #define alloc_skb(size, priority) (struct sk_buff *) kmalloc(size,priority)
56 #define kfree_skbmem(addr, size) kfree_s(addr,size);
57 #endif
59 /* use 0 for production, 1 for verification, >2 for debug */
60 #ifndef NET_DEBUG
61 #define NET_DEBUG 2
62 #endif
63 static unsigned int net_debug = NET_DEBUG;
65 typedef unsigned char uchar;
67 /* Information that need to be kept for each board. */
68 struct net_local {
69 struct enet_statistics stats;
70 long open_time; /* Useless example local info. */
71 uint tx_started:1; /* Number of packet on the Tx queue. */
72 uchar tx_queue; /* Number of packet on the Tx queue. */
73 ushort tx_queue_len; /* Current length of the Tx queue. */
77 /* Offsets from the base address. */
78 #define STATUS 0
79 #define TX_STATUS 0
80 #define RX_STATUS 1
81 #define TX_INTR 2 /* Bit-mapped interrupt enable registers. */
82 #define RX_INTR 3
83 #define TX_MODE 4
84 #define RX_MODE 5
85 #define CONFIG_0 6 /* Misc. configuration settings. */
86 #define CONFIG_1 7
87 /* Run-time register bank 2 definitions. */
88 #define DATAPORT 8 /* Word-wide DMA or programmed-I/O dataport. */
89 #define TX_START 10
90 #define MODE13 13
91 #define EEPROM_Ctrl 16
92 #define EEPROM_Data 17
94 /* EEPROM_Ctrl bits. */
95 #define EE_SHIFT_CLK 0x40 /* EEPROM shift clock, in reg. 16. */
96 #define EE_CS 0x20 /* EEPROM chip select, in reg. 16. */
97 #define EE_DATA_WRITE 0x80 /* EEPROM chip data in, in reg. 17. */
98 #define EE_DATA_READ 0x80 /* EEPROM chip data out, in reg. 17. */
100 /* Delay between EEPROM clock transitions. */
101 #define eeprom_delay() do { int _i = 40; while (--_i > 0) { __SLOW_DOWN_IO; }} while (0)
103 /* The EEPROM commands include the alway-set leading bit. */
104 #define EE_WRITE_CMD (5 << 6)
105 #define EE_READ_CMD (6 << 6)
106 #define EE_ERASE_CMD (7 << 6)
109 /* Index to functions, as function prototypes. */
111 extern int at1700_probe(struct device *dev);
113 static int at1700_probe1(struct device *dev, short ioaddr);
114 static int read_eeprom(int ioaddr, int location);
115 static int net_open(struct device *dev);
116 static int net_send_packet(struct sk_buff *skb, struct device *dev);
117 static void net_interrupt(int reg_ptr);
118 static void net_rx(struct device *dev);
119 static int net_close(struct device *dev);
120 static struct enet_statistics *net_get_stats(struct device *dev);
121 #ifdef HAVE_MULTICAST
122 static void set_multicast_list(struct device *dev, int num_addrs, void *addrs);
123 #endif
126 /* Check for a network adaptor of this type, and return '0' iff one exists.
127 If dev->base_addr == 0, probe all likely locations.
128 If dev->base_addr == 1, always return failure.
129 If dev->base_addr == 2, alloate space for the device and return success
130 (detachable devices only).
133 at1700_probe(struct device *dev)
135 short ports[] = {0x300, 0x280, 0x380, 0x320, 0x340, 0x260, 0x2a0, 0x240, 0};
136 short *port, base_addr = dev->base_addr;
138 if (base_addr > 0x1ff) /* Check a single specified location. */
139 return at1700_probe1(dev, base_addr);
140 else if (base_addr > 0) /* Don't probe at all. */
141 return ENXIO;
143 for (port = &ports[0]; *port; port++) {
144 int ioaddr = *port;
145 #ifdef HAVE_PORTRESERVE
146 if (check_region(ioaddr, 32))
147 continue;
148 #endif
149 if (inw(ioaddr) != 0x0000)
150 continue;
151 if (at1700_probe1(dev, ioaddr) == 0)
152 return 0;
155 return ENODEV; /* ENODEV would be more accurate. */
158 int at1700_probe1(struct device *dev, short ioaddr)
160 unsigned short signature[4] = {0x0000, 0xffff, 0x41f6, 0xefb6};
161 unsigned short signature_invalid[4] = {0x0000, 0xffff, 0x00f0, 0x2f00};
162 char irqmap[4] = {3, 4, 5, 9};
163 unsigned short *station_address = (unsigned short *)dev->dev_addr;
164 unsigned int i, irq;
166 /* Resetting the chip doesn't reset the ISA interface, so don't bother.
167 That means we have to be careful with the register values we probe for.
169 for (i = 0; i < 4; i++)
170 if ((inw(ioaddr + 2*i) | signature_invalid[i]) != signature[i]) {
171 if (net_debug > 1)
172 printk("AT1700 signature match failed at %d (%04x vs. %04x)\n",
173 i, inw(ioaddr + 2*i), signature[i]);
174 return -ENODEV;
176 #ifdef HAVE_PORTRESERVE
177 /* Grab the region so that we can find another board if the IRQ request
178 fails. */
179 snarf_region(ioaddr, 32);
180 #endif
182 irq = irqmap[ read_eeprom(ioaddr, 0) >> 14 ];
184 /* Snarf the interrupt vector now. */
185 if (request_irq(irq, &net_interrupt)) {
186 printk ("AT1700 found at %#3x, but it's unusable due to a conflict on"
187 "IRQ %d.\n", ioaddr, irq);
188 return EAGAIN;
191 printk("%s: AT1700 found at %#3x, IRQ %d, address ", dev->name,
192 ioaddr, irq);
194 dev->base_addr = ioaddr;
195 dev->irq = irq;
196 irq2dev_map[irq] = dev;
198 for(i = 0; i < 3; i++) {
199 unsigned short eeprom_val = read_eeprom(ioaddr, 4+i);
200 printk("%04x", eeprom_val);
201 station_address[i] = ntohs(eeprom_val);
204 /* The EEPROM word 12 bit 0x0400 means use regular 100 ohm 10baseT signals,
205 rather than 150 ohm shielded twisted pair compansation.
206 0x0000 == auto-sense the interface
207 0x0800 == use TP interface
208 0x1800 == use coax interface
211 char *porttype[] = {"auto-sense", "10baseT", "auto-sense", "10base2"};
212 ushort setup_value = read_eeprom(ioaddr, 12);
214 dev->if_port = setup_value >> 8;
215 printk(" %s interface (%04x).\n", porttype[(dev->if_port>>3) & 3],
216 setup_value);
219 /* Set the station address in bank zero. */
220 outb(0xe0, ioaddr + 7);
221 for (i = 0; i < 6; i++)
222 outb(dev->dev_addr[i], ioaddr + 8 + i);
224 /* Switch to bank 1 and set the multicast table to accept none. */
225 outb(0xe4, ioaddr + 7);
226 for (i = 0; i < 8; i++)
227 outb(0x00, ioaddr + 8 + i);
229 /* Set the configuration register 0 to 32K 100ns. byte-wide memory, 16 bit
230 bus access, two 4K Tx queues, and disabled Tx and Rx. */
231 outb(0xda, ioaddr + CONFIG_0);
233 /* Switch to bank 2 and lock our I/O address. */
234 outb(0xe8, ioaddr + 7);
235 outb(dev->if_port, MODE13);
237 /* Power-down the chip. Aren't we green! */
238 outb(0x00, ioaddr + CONFIG_1);
240 if (net_debug)
241 printk(version);
243 /* Initialize the device structure. */
244 dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
245 memset(dev->priv, 0, sizeof(struct net_local));
247 dev->open = net_open;
248 dev->stop = net_close;
249 dev->hard_start_xmit = net_send_packet;
250 dev->get_stats = net_get_stats;
251 #ifdef HAVE_MULTICAST
252 dev->set_multicast_list = &set_multicast_list;
253 #endif
255 /* Fill in the fields of the device structure with ethernet-generic values.
256 This should be in a common file instead of per-driver. */
257 for (i = 0; i < DEV_NUMBUFFS; i++)
258 dev->buffs[i] = NULL;
260 dev->hard_header = eth_header;
261 dev->add_arp = eth_add_arp;
262 dev->queue_xmit = dev_queue_xmit;
263 dev->rebuild_header = eth_rebuild_header;
264 dev->type_trans = eth_type_trans;
266 dev->type = ARPHRD_ETHER;
267 dev->hard_header_len = ETH_HLEN;
268 dev->mtu = 1500; /* eth_mtu */
269 dev->addr_len = ETH_ALEN;
270 for (i = 0; i < ETH_ALEN; i++) {
271 dev->broadcast[i]=0xff;
274 /* New-style flags. */
275 dev->flags = IFF_BROADCAST;
276 dev->family = AF_INET;
277 dev->pa_addr = 0;
278 dev->pa_brdaddr = 0;
279 dev->pa_mask = 0;
280 dev->pa_alen = sizeof(unsigned long);
282 return 0;
285 static int read_eeprom(int ioaddr, int location)
287 int i;
288 unsigned short retval = 0;
289 short ee_addr = ioaddr + EEPROM_Ctrl;
290 short ee_daddr = ioaddr + EEPROM_Data;
291 int read_cmd = location | EE_READ_CMD;
292 short ctrl_val = EE_CS;
294 outb(ctrl_val, ee_addr);
296 /* Shift the read command bits out. */
297 for (i = 9; i >= 0; i--) {
298 short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
299 outb(dataval, ee_daddr);
300 outb(EE_CS | EE_SHIFT_CLK, ee_addr); /* EEPROM clock tick. */
301 eeprom_delay();
302 outb(EE_CS, ee_addr); /* Finish EEPROM a clock tick. */
303 eeprom_delay();
305 outb(EE_CS, ee_addr);
307 for (i = 16; i > 0; i--) {
308 outb(EE_CS | EE_SHIFT_CLK, ee_addr);
309 eeprom_delay();
310 retval = (retval << 1) | ((inb(ee_daddr) & EE_DATA_READ) ? 1 : 0);
311 outb(EE_CS, ee_addr);
312 eeprom_delay();
315 /* Terminate the EEPROM access. */
316 ctrl_val &= ~EE_CS;
317 outb(ctrl_val | EE_SHIFT_CLK, ee_addr);
318 eeprom_delay();
319 outb(ctrl_val, ee_addr);
320 eeprom_delay();
321 return retval;
326 static int net_open(struct device *dev)
328 struct net_local *lp = (struct net_local *)dev->priv;
329 int ioaddr = dev->base_addr;
330 int i;
332 /* Powerup the chip, initialize config register 1, and select bank 0. */
333 outb(0xe0, ioaddr + CONFIG_1);
335 /* Set the station address in bank zero. */
336 for (i = 0; i < 6; i++)
337 outb(dev->dev_addr[i], ioaddr + 8 + i);
339 /* Switch to bank 1 and set the multicast table to accept none. */
340 outb(0xe4, ioaddr + 7);
341 for (i = 0; i < 8; i++)
342 outb(0x00, ioaddr + 8 + i);
344 /* Set the configuration register 0 to 32K 100ns. byte-wide memory, 16 bit
345 bus access, and two 4K Tx queues. */
346 outb(0xda, ioaddr + CONFIG_0);
348 /* Same config 0, except enable the Rx and Tx. */
349 outb(0x5a, ioaddr + CONFIG_0);
350 /* Switch to register bank 2 for the run-time registers. */
351 outb(0xe8, ioaddr + CONFIG_1);
353 /* Turn on Rx interrupts, leave Tx interrupts off until packet Tx. */
354 outb(0x00, ioaddr + TX_INTR);
355 outb(0x81, ioaddr + RX_INTR);
357 lp->open_time = jiffies;
359 dev->tbusy = 0;
360 dev->interrupt = 0;
361 dev->start = 1;
363 return 0;
366 static int
367 net_send_packet(struct sk_buff *skb, struct device *dev)
369 struct net_local *lp = (struct net_local *)dev->priv;
370 int ioaddr = dev->base_addr;
372 if (dev->tbusy) {
373 /* If we get here, some higher level has decided we are broken.
374 There should really be a "kick me" function call instead. */
375 int tickssofar = jiffies - dev->trans_start;
376 if (tickssofar < 10)
377 return 1;
378 printk("%s: transmit timed out with status %04x, %s?\n", dev->name,
379 inw(ioaddr + STATUS), inb(ioaddr + TX_STATUS) & 0x80
380 ? "IRQ conflict" : "network cable problem");
381 printk("%s: timeout registers: %04x %04x %04x %04x %04x %04x %04x %04x.\n",
382 dev->name, inw(ioaddr + 0), inw(ioaddr + 2), inw(ioaddr + 4),
383 inw(ioaddr + 6), inw(ioaddr + 8), inw(ioaddr + 10),
384 inw(ioaddr + 12), inw(ioaddr + 14));
385 lp->stats.tx_errors++;
386 /* ToDo: We should try to restart the adaptor... */
387 outw(0xffff, ioaddr + 24);
388 outw(0xffff, ioaddr + TX_STATUS);
389 outw(0xe85a, ioaddr + CONFIG_0);
390 outw(0x8100, ioaddr + TX_INTR);
391 dev->tbusy=0;
392 dev->trans_start = jiffies;
395 /* If some higher layer thinks we've missed an tx-done interrupt
396 we are passed NULL. Caution: dev_tint() handles the cli()/sti()
397 itself. */
398 if (skb == NULL) {
399 dev_tint(dev);
400 return 0;
403 /* For ethernet, fill in the header. This should really be done by a
404 higher level, rather than duplicated for each ethernet adaptor. */
405 if (!skb->arp && dev->rebuild_header(skb->data, dev)) {
406 skb->dev = dev;
407 arp_queue (skb);
408 return 0;
410 skb->arp=1;
412 /* Block a timer-based transmit from overlapping. This could better be
413 done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
414 if (set_bit(0, (void*)&dev->tbusy) != 0)
415 printk("%s: Transmitter access conflict.\n", dev->name);
416 else {
417 short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
418 unsigned char *buf = skb->data;
420 if (net_debug > 4)
421 printk("%s: Transmitting a packet of length %d.\n", dev->name,
422 skb->len);
424 /* Turn off the possible Tx interrupts. */
425 outb(0x00, ioaddr + TX_INTR);
427 outw(length, ioaddr + DATAPORT);
428 outsw(ioaddr + DATAPORT, buf, (length + 1) >> 1);
430 lp->tx_queue++;
431 lp->tx_queue_len += length + 2;
433 if (lp->tx_started == 0) {
434 /* If the Tx is idle, always trigger a transmit. */
435 outb(0x80 | lp->tx_queue, ioaddr + TX_START);
436 lp->tx_queue = 0;
437 lp->tx_queue_len = 0;
438 dev->trans_start = jiffies;
439 lp->tx_started = 1;
440 } else if (lp->tx_queue_len < 4096 - 1502) /* Room for one more packet? */
441 dev->tbusy = 0;
443 /* Turn on Tx interrupts back on. */
444 outb(0x82, ioaddr + TX_INTR);
446 if (skb->free)
447 kfree_skb (skb, FREE_WRITE);
449 return 0;
452 /* The typical workload of the driver:
453 Handle the network interface interrupts. */
454 static void
455 net_interrupt(int reg_ptr)
457 int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2);
458 struct device *dev = (struct device *)(irq2dev_map[irq]);
459 struct net_local *lp;
460 int ioaddr, status;
462 if (dev == NULL) {
463 printk ("at1700_interrupt(): irq %d for unknown device.\n", irq);
464 return;
466 dev->interrupt = 1;
468 ioaddr = dev->base_addr;
469 lp = (struct net_local *)dev->priv;
470 status = inw(ioaddr + TX_STATUS);
471 outw(status, ioaddr + TX_STATUS);
473 if (net_debug > 4)
474 printk("%s: Interrupt with status %04x.\n", dev->name, status);
475 if (status & 0xff00
476 || (inb(ioaddr + RX_MODE) & 0x40) == 0) { /* Got a packet(s). */
477 net_rx(dev);
479 if (status & 0x00ff) {
480 if (status & 0x80) {
481 lp->stats.tx_packets++;
482 if (lp->tx_queue) {
483 outb(0x80 | lp->tx_queue, ioaddr + TX_START);
484 lp->tx_queue = 0;
485 lp->tx_queue_len = 0;
486 dev->trans_start = jiffies;
487 dev->tbusy = 0;
488 mark_bh(INET_BH); /* Inform upper layers. */
489 } else {
490 lp->tx_started = 0;
491 /* Turn on Tx interrupts off. */
492 outb(0x00, ioaddr + TX_INTR);
493 dev->tbusy = 0;
498 return;
501 /* We have a good packet(s), get it/them out of the buffers. */
502 static void
503 net_rx(struct device *dev)
505 struct net_local *lp = (struct net_local *)dev->priv;
506 int ioaddr = dev->base_addr;
507 int boguscount = 5;
509 while ((inb(ioaddr + RX_MODE) & 0x40) == 0) {
510 ushort status = inw(ioaddr + DATAPORT);
512 if (net_debug > 4)
513 printk("%s: Rxing packet mode %02x status %04x.\n",
514 dev->name, inb(ioaddr + RX_MODE), status);
515 #ifndef final_version
516 if (status == 0) {
517 outb(0x05, ioaddr + 14);
518 break;
520 #endif
522 if ((status & 0xF0) != 0x20) { /* There was an error. */
523 lp->stats.rx_errors++;
524 if (status & 0x08) lp->stats.rx_length_errors++;
525 if (status & 0x04) lp->stats.rx_frame_errors++;
526 if (status & 0x02) lp->stats.rx_crc_errors++;
527 if (status & 0x01) lp->stats.rx_over_errors++;
528 } else {
529 ushort pkt_len = inw(ioaddr + DATAPORT);
530 /* Malloc up new buffer. */
531 int sksize = sizeof(struct sk_buff) + pkt_len;
532 struct sk_buff *skb;
534 if (pkt_len > 1550) {
535 printk("%s: The AT1700 claimed a very large packet, size %d.\n",
536 dev->name, pkt_len);
537 outb(0x05, ioaddr + 14);
538 lp->stats.rx_errors++;
539 break;
541 skb = alloc_skb(sksize, GFP_ATOMIC);
542 if (skb == NULL) {
543 printk("%s: Memory squeeze, dropping packet (len %d).\n",
544 dev->name, pkt_len);
545 outb(0x05, ioaddr + 14);
546 lp->stats.rx_dropped++;
547 break;
549 skb->mem_len = sksize;
550 skb->mem_addr = skb;
551 skb->len = pkt_len;
552 skb->dev = dev;
554 /* 'skb->data' points to the start of sk_buff data area. */
555 insw(ioaddr + DATAPORT, skb->data, (pkt_len + 1) >> 1);
557 if (net_debug > 5) {
558 int i;
559 printk("%s: Rxed packet of length %d: ", dev->name, pkt_len);
560 for (i = 0; i < 14; i++)
561 printk(" %02x", skb->data[i]);
562 printk(".\n");
565 #ifdef HAVE_NETIF_RX
566 netif_rx(skb);
567 #else
568 skb->lock = 0;
569 if (dev_rint((unsigned char*)skb, pkt_len, IN_SKBUFF, dev) != 0) {
570 kfree_s(skb, sksize);
571 lp->stats.rx_dropped++;
572 break;
574 #endif
575 lp->stats.rx_packets++;
577 if (--boguscount <= 0)
578 break;
581 /* If any worth-while packets have been received, dev_rint()
582 has done a mark_bh(INET_BH) for us and will work on them
583 when we get to the bottom-half routine. */
585 int i;
586 for (i = 0; i < 20; i++) {
587 if ((inb(ioaddr + RX_MODE) & 0x40) == 0x40)
588 break;
589 outb(0x05, ioaddr + 14);
592 if (net_debug > 5)
593 printk("%s: Exint Rx packet with mode %02x after %d ticks.\n",
594 dev->name, inb(ioaddr + RX_MODE), i);
596 return;
599 /* The inverse routine to net_open(). */
600 static int net_close(struct device *dev)
602 struct net_local *lp = (struct net_local *)dev->priv;
603 int ioaddr = dev->base_addr;
605 lp->open_time = 0;
607 dev->tbusy = 1;
608 dev->start = 0;
610 /* Set configuration register 0 to disable Tx and Rx. */
611 outb(0xda, ioaddr + CONFIG_0);
613 /* Update the statistics -- ToDo. */
615 /* Power-down the chip. Green, green, green! */
616 outb(0x00, ioaddr + CONFIG_1);
618 return 0;
621 /* Get the current statistics. This may be called with the card open or
622 closed. */
623 static struct enet_statistics *
624 net_get_stats(struct device *dev)
626 struct net_local *lp = (struct net_local *)dev->priv;
628 cli();
629 /* ToDo: Update the statistics from the device registers. */
630 sti();
632 return &lp->stats;
635 #ifdef HAVE_MULTICAST
636 /* Set or clear the multicast filter for this adaptor.
637 num_addrs == -1 Promiscuous mode, receive all packets
638 num_addrs == 0 Normal mode, clear multicast list
639 num_addrs > 0 Multicast mode, receive normal and MC packets, and do
640 best-effort filtering.
642 static void
643 set_multicast_list(struct device *dev, int num_addrs, void *addrs)
645 short ioaddr = dev->base_addr;
646 if (num_addrs) {
647 outw(3, ioaddr + RX_MODE); /* Enable promiscuous mode */
648 } else
649 outw(2, ioaddr + RX_MODE); /* Disable promiscuous, use normal mode */
651 #endif
654 * Local variables:
655 * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c at1700.c"
656 * version-control: t
657 * kept-new-versions: 5
658 * tab-width: 4
659 * End: