|
|
1.1 root 1: /* at1700.c: A network device driver for the Allied Telesis AT1700.
2:
3: Written 1993-98 by Donald Becker.
4:
5: Copyright 1993 United States Government as represented by the
6: Director, National Security Agency.
7:
8: This software may be used and distributed according to the terms
9: of the GNU Public License, incorporated herein by reference.
10:
11: The author may be reached as [email protected], or C/O
12: Center of Excellence in Space Data and Information Sciences
13: Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
14:
15: This is a device driver for the Allied Telesis AT1700, which is a
16: straight-forward Fujitsu MB86965 implementation.
17:
18: Sources:
19: The Fujitsu MB86965 datasheet.
20:
21: After the initial version of this driver was written Gerry Sawkins of
22: ATI provided their EEPROM configuration code header file.
23: Thanks to NIIBE Yutaka <[email protected]> for bug fixes.
24:
25: Bugs:
26: The MB86965 has a design flaw that makes all probes unreliable. Not
27: only is it difficult to detect, it also moves around in I/O space in
28: response to inb()s from other device probes!
29: */
30:
31: static const char *version =
32: "at1700.c:v1.15 4/7/98 Donald Becker ([email protected])\n";
33:
34: #include <linux/module.h>
35:
36: #include <linux/kernel.h>
37: #include <linux/sched.h>
38: #include <linux/types.h>
39: #include <linux/fcntl.h>
40: #include <linux/interrupt.h>
41: #include <linux/ptrace.h>
42: #include <linux/ioport.h>
43: #include <linux/in.h>
44: #include <linux/malloc.h>
45: #include <linux/string.h>
46: #include <asm/system.h>
47: #include <asm/bitops.h>
48: #include <asm/io.h>
49: #include <asm/dma.h>
50: #include <linux/errno.h>
51:
52: #include <linux/netdevice.h>
53: #include <linux/etherdevice.h>
54: #include <linux/skbuff.h>
55:
56: /* Tunable parameters. */
57:
58: /* When to switch from the 64-entry multicast filter to Rx-all-multicast. */
59: #define MC_FILTERBREAK 64
60:
61: /* These unusual address orders are used to verify the CONFIG register. */
62: static int at1700_probe_list[] =
63: {0x260, 0x280, 0x2a0, 0x240, 0x340, 0x320, 0x380, 0x300, 0};
64: static int fmv18x_probe_list[] =
65: {0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x300, 0x340, 0};
66:
67:
68: /* use 0 for production, 1 for verification, >2 for debug */
69: #ifndef NET_DEBUG
70: #define NET_DEBUG 1
71: #endif
72: static unsigned int net_debug = NET_DEBUG;
73:
74: typedef unsigned char uchar;
75:
76: /* Information that need to be kept for each board. */
77: struct net_local {
78: struct enet_statistics stats;
79: unsigned char mc_filter[8];
80: uint jumpered:1; /* Set iff the board has jumper config. */
81: uint tx_started:1; /* Packets are on the Tx queue. */
82: uint invalid_irq:1;
83: uchar tx_queue; /* Number of packet on the Tx queue. */
84: ushort tx_queue_len; /* Current length of the Tx queue. */
85: };
86:
87:
88: /* Offsets from the base address. */
89: #define STATUS 0
90: #define TX_STATUS 0
91: #define RX_STATUS 1
92: #define TX_INTR 2 /* Bit-mapped interrupt enable registers. */
93: #define RX_INTR 3
94: #define TX_MODE 4
95: #define RX_MODE 5
96: #define CONFIG_0 6 /* Misc. configuration settings. */
97: #define CONFIG_1 7
98: /* Run-time register bank 2 definitions. */
99: #define DATAPORT 8 /* Word-wide DMA or programmed-I/O dataport. */
100: #define TX_START 10
101: #define MODE13 13
102: /* Configuration registers only on the '865A/B chips. */
103: #define EEPROM_Ctrl 16
104: #define EEPROM_Data 17
105: #define IOCONFIG 18 /* Either read the jumper, or move the I/O. */
106: #define IOCONFIG1 19
107: #define SAPROM 20 /* The station address PROM, if no EEPROM. */
108: #define RESET 31 /* Write to reset some parts of the chip. */
109: #define AT1700_IO_EXTENT 32
110: /* Index to functions, as function prototypes. */
111:
112: extern int at1700_probe(struct device *dev);
113:
114: static int at1700_probe1(struct device *dev, int ioaddr);
115: static int read_eeprom(int ioaddr, int location);
116: static int net_open(struct device *dev);
117: static int net_send_packet(struct sk_buff *skb, struct device *dev);
118: static void net_interrupt(int irq, void *dev_id, struct pt_regs *regs);
119: static void net_rx(struct device *dev);
120: static int net_close(struct device *dev);
121: static struct enet_statistics *net_get_stats(struct device *dev);
122: static void set_rx_mode(struct device *dev);
123:
124:
125: /* Check for a network adaptor of this type, and return '0' iff one exists.
126: If dev->base_addr == 0, probe all likely locations.
127: If dev->base_addr == 1, always return failure.
128: If dev->base_addr == 2, allocate space for the device and return success
129: (detachable devices only).
130: */
131: #ifdef HAVE_DEVLIST
132: /* Support for a alternate probe manager, which will eliminate the
133: boilerplate below. */
134: struct netdev_entry at1700_drv =
135: {"at1700", at1700_probe1, AT1700_IO_EXTENT, at1700_probe_list};
136: #else
137: int
138: at1700_probe(struct device *dev)
139: {
140: int i;
141: int base_addr = dev ? dev->base_addr : 0;
142:
143: if (base_addr > 0x1ff) /* Check a single specified location. */
144: return at1700_probe1(dev, base_addr);
145: else if (base_addr != 0) /* Don't probe at all. */
146: return ENXIO;
147:
148: for (i = 0; at1700_probe_list[i]; i++) {
149: int ioaddr = at1700_probe_list[i];
150: if (check_region(ioaddr, AT1700_IO_EXTENT))
151: continue;
152: if (at1700_probe1(dev, ioaddr) == 0)
153: return 0;
154: }
155:
156: return ENODEV;
157: }
158: #endif
159:
160: /* The Fujitsu datasheet suggests that the NIC be probed for by checking its
161: "signature", the default bit pattern after a reset. This *doesn't* work --
162: there is no way to reset the bus interface without a complete power-cycle!
163:
164: It turns out that ATI came to the same conclusion I did: the only thing
165: that can be done is checking a few bits and then diving right into an
166: EEPROM read. */
167:
168: int at1700_probe1(struct device *dev, int ioaddr)
169: {
170: char fmv_irqmap[4] = {3, 7, 10, 15};
171: char at1700_irqmap[8] = {3, 4, 5, 9, 10, 11, 14, 15};
172: unsigned int i, irq, is_fmv18x = 0, is_at1700 = 0;
173:
174: /* Resetting the chip doesn't reset the ISA interface, so don't bother.
175: That means we have to be careful with the register values we probe for.
176: */
177: #ifdef notdef
178: printk("at1700 probe at %#x, eeprom is %4.4x %4.4x %4.4x ctrl %4.4x.\n",
179: ioaddr, read_eeprom(ioaddr, 4), read_eeprom(ioaddr, 5),
180: read_eeprom(ioaddr, 6), inw(ioaddr + EEPROM_Ctrl));
181: #endif
182: /* We must check for the EEPROM-config boards first, else accessing
183: IOCONFIG0 will move the board! */
184: if (at1700_probe_list[inb(ioaddr + IOCONFIG1) & 0x07] == ioaddr
185: && read_eeprom(ioaddr, 4) == 0x0000
186: && (read_eeprom(ioaddr, 5) & 0xff00) == 0xF400)
187: is_at1700 = 1;
188: else if (fmv18x_probe_list[inb(ioaddr + IOCONFIG) & 0x07] == ioaddr
189: && inb(ioaddr + SAPROM ) == 0x00
190: && inb(ioaddr + SAPROM + 1) == 0x00
191: && inb(ioaddr + SAPROM + 2) == 0x0e)
192: is_fmv18x = 1;
193: else
194: return -ENODEV;
195:
196: /* Reset the internal state machines. */
197: outb(0, ioaddr + RESET);
198:
199: /* Allocate a new 'dev' if needed. */
200: if (dev == NULL)
201: dev = init_etherdev(0, sizeof(struct net_local));
202:
203: if (is_at1700)
204: irq = at1700_irqmap[(read_eeprom(ioaddr, 12)&0x04)
205: | (read_eeprom(ioaddr, 0)>>14)];
206: else
207: irq = fmv_irqmap[(inb(ioaddr + IOCONFIG)>>6) & 0x03];
208:
209: /* Grab the region so that we can find another board if the IRQ request
210: fails. */
211: request_region(ioaddr, AT1700_IO_EXTENT, dev->name);
212:
213: printk("%s: AT1700 found at %#3x, IRQ %d, address ", dev->name,
214: ioaddr, irq);
215:
216: dev->base_addr = ioaddr;
217: dev->irq = irq;
218:
219: for(i = 0; i < 3; i++) {
220: unsigned short eeprom_val = read_eeprom(ioaddr, 4+i);
221: printk("%04x", eeprom_val);
222: ((unsigned short *)dev->dev_addr)[i] = ntohs(eeprom_val);
223: }
224:
225: /* The EEPROM word 12 bit 0x0400 means use regular 100 ohm 10baseT signals,
226: rather than 150 ohm shielded twisted pair compensation.
227: 0x0000 == auto-sense the interface
228: 0x0800 == use TP interface
229: 0x1800 == use coax interface
230: */
231: {
232: const char *porttype[] = {"auto-sense", "10baseT", "auto-sense", "10base2"};
233: ushort setup_value = read_eeprom(ioaddr, 12);
234:
235: dev->if_port = setup_value >> 8;
236: printk(" %s interface.\n", porttype[(dev->if_port>>3) & 3]);
237: }
238:
239: /* Set the station address in bank zero. */
240: outb(0xe0, ioaddr + CONFIG_1);
241: for (i = 0; i < 6; i++)
242: outb(dev->dev_addr[i], ioaddr + 8 + i);
243:
244: /* Switch to bank 1 and set the multicast table to accept none. */
245: outb(0xe4, ioaddr + CONFIG_1);
246: for (i = 0; i < 8; i++)
247: outb(0x00, ioaddr + 8 + i);
248:
249: /* Set the configuration register 0 to 32K 100ns. byte-wide memory, 16 bit
250: bus access, two 4K Tx queues, and disabled Tx and Rx. */
251: outb(0xda, ioaddr + CONFIG_0);
252:
253: /* Switch to bank 2 and lock our I/O address. */
254: outb(0xe8, ioaddr + CONFIG_1);
255: outb(dev->if_port, MODE13);
256:
257: /* Power-down the chip. Aren't we green! */
258: outb(0x00, ioaddr + CONFIG_1);
259:
260: if (net_debug)
261: printk(version);
262:
263: /* Initialize the device structure. */
264: dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
265: if (dev->priv == NULL)
266: return -ENOMEM;
267: memset(dev->priv, 0, sizeof(struct net_local));
268:
269: dev->open = net_open;
270: dev->stop = net_close;
271: dev->hard_start_xmit = net_send_packet;
272: dev->get_stats = net_get_stats;
273: dev->set_multicast_list = &set_rx_mode;
274:
275: /* Fill in the fields of 'dev' with ethernet-generic values. */
276: ether_setup(dev);
277:
278: {
279: struct net_local *lp = (struct net_local *)dev->priv;
280: lp->jumpered = is_fmv18x;
281: /* Snarf the interrupt vector now. */
282: if (request_irq(irq, &net_interrupt, 0, dev->name, dev)) {
283: printk (" AT1700 at %#3x is unusable due to a conflict on"
284: "IRQ %d.\n", ioaddr, irq);
285: lp->invalid_irq = 1;
286: return 0;
287: }
288: }
289:
290: return 0;
291: }
292:
293:
294: /* EEPROM_Ctrl bits. */
295: #define EE_SHIFT_CLK 0x40 /* EEPROM shift clock, in reg. 16. */
296: #define EE_CS 0x20 /* EEPROM chip select, in reg. 16. */
297: #define EE_DATA_WRITE 0x80 /* EEPROM chip data in, in reg. 17. */
298: #define EE_DATA_READ 0x80 /* EEPROM chip data out, in reg. 17. */
299:
300: /* Delay between EEPROM clock transitions. */
301: #define eeprom_delay() do {} while (0);
302:
303: /* The EEPROM commands include the alway-set leading bit. */
304: #define EE_WRITE_CMD (5 << 6)
305: #define EE_READ_CMD (6 << 6)
306: #define EE_ERASE_CMD (7 << 6)
307:
308: static int read_eeprom(int ioaddr, int location)
309: {
310: int i;
311: unsigned short retval = 0;
312: int ee_addr = ioaddr + EEPROM_Ctrl;
313: int ee_daddr = ioaddr + EEPROM_Data;
314: int read_cmd = location | EE_READ_CMD;
315:
316: /* Shift the read command bits out. */
317: for (i = 9; i >= 0; i--) {
318: short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
319: outb(EE_CS, ee_addr);
320: outb(dataval, ee_daddr);
321: eeprom_delay();
322: outb(EE_CS | EE_SHIFT_CLK, ee_addr); /* EEPROM clock tick. */
323: eeprom_delay();
324: }
325: outb(EE_DATA_WRITE, ee_daddr);
326: for (i = 16; i > 0; i--) {
327: outb(EE_CS, ee_addr);
328: eeprom_delay();
329: outb(EE_CS | EE_SHIFT_CLK, ee_addr);
330: eeprom_delay();
331: retval = (retval << 1) | ((inb(ee_daddr) & EE_DATA_READ) ? 1 : 0);
332: }
333:
334: /* Terminate the EEPROM access. */
335: outb(EE_CS, ee_addr);
336: eeprom_delay();
337: outb(EE_SHIFT_CLK, ee_addr);
338: outb(0, ee_addr);
339: return retval;
340: }
341:
342:
343:
344: static int net_open(struct device *dev)
345: {
346: struct net_local *lp = (struct net_local *)dev->priv;
347: int ioaddr = dev->base_addr;
348: int i;
349:
350: /* Powerup the chip, initialize config register 1, and select bank 0. */
351: outb(0xe0, ioaddr + CONFIG_1);
352:
353: /* Set the station address in bank zero. */
354: for (i = 0; i < 6; i++)
355: outb(dev->dev_addr[i], ioaddr + 8 + i);
356:
357: /* Switch to bank 1 and set the multicast table to accept none. */
358: outb(0xe4, ioaddr + CONFIG_1);
359: for (i = 0; i < 8; i++)
360: outb(0x00, ioaddr + 8 + i);
361:
362: /* Set the configuration register 0 to 32K 100ns. byte-wide memory, 16 bit
363: bus access, and two 4K Tx queues. */
364: outb(0xda, ioaddr + CONFIG_0);
365:
366: /* Switch to register bank 2, enable the Rx and Tx. */
367: outw(0xe85a, ioaddr + CONFIG_0);
368:
369: lp->tx_started = 0;
370: lp->tx_queue = 0;
371: lp->tx_queue_len = 0;
372:
373: /* Turn on Rx interrupts, leave Tx interrupts off until packet Tx. */
374: outb(0x00, ioaddr + TX_INTR);
375: outb(0x81, ioaddr + RX_INTR);
376:
377: dev->tbusy = 0;
378: dev->interrupt = 0;
379: dev->start = 1;
380:
381: MOD_INC_USE_COUNT;
382:
383: return 0;
384: }
385:
386: static int
387: net_send_packet(struct sk_buff *skb, struct device *dev)
388: {
389: struct net_local *lp = (struct net_local *)dev->priv;
390: int ioaddr = dev->base_addr;
391:
392: if (dev->tbusy) {
393: /* If we get here, some higher level has decided we are broken.
394: There should really be a "kick me" function call instead. */
395: int tickssofar = jiffies - dev->trans_start;
396: if (tickssofar < 10)
397: return 1;
398: printk("%s: transmit timed out with status %04x, %s?\n", dev->name,
399: inw(ioaddr + STATUS), inb(ioaddr + TX_STATUS) & 0x80
400: ? "IRQ conflict" : "network cable problem");
401: printk("%s: timeout registers: %04x %04x %04x %04x %04x %04x %04x %04x.\n",
402: dev->name, inw(ioaddr + 0), inw(ioaddr + 2), inw(ioaddr + 4),
403: inw(ioaddr + 6), inw(ioaddr + 8), inw(ioaddr + 10),
404: inw(ioaddr + 12), inw(ioaddr + 14));
405: lp->stats.tx_errors++;
406: /* ToDo: We should try to restart the adaptor... */
407: outw(0xffff, ioaddr + 24);
408: outw(0xffff, ioaddr + TX_STATUS);
409: outw(0xe85a, ioaddr + CONFIG_0);
410: outw(0x8100, ioaddr + TX_INTR);
411: dev->tbusy=0;
412: dev->trans_start = jiffies;
413: lp->tx_started = 0;
414: lp->tx_queue = 0;
415: lp->tx_queue_len = 0;
416: }
417:
418: /* If some higher layer thinks we've missed an tx-done interrupt
419: we are passed NULL. Caution: dev_tint() handles the cli()/sti()
420: itself. */
421: if (skb == NULL) {
422: dev_tint(dev);
423: return 0;
424: }
425:
426: /* Block a timer-based transmit from overlapping. This could better be
427: done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
428: if (set_bit(0, (void*)&dev->tbusy) != 0)
429: printk("%s: Transmitter access conflict.\n", dev->name);
430: else {
431: short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
432: unsigned char *buf = skb->data;
433:
434: /* Turn off the possible Tx interrupts. */
435: outb(0x00, ioaddr + TX_INTR);
436:
437: outw(length, ioaddr + DATAPORT);
438: outsw(ioaddr + DATAPORT, buf, (length + 1) >> 1);
439:
440: lp->tx_queue++;
441: lp->tx_queue_len += length + 2;
442:
443: if (lp->tx_started == 0) {
444: /* If the Tx is idle, always trigger a transmit. */
445: outb(0x80 | lp->tx_queue, ioaddr + TX_START);
446: lp->tx_queue = 0;
447: lp->tx_queue_len = 0;
448: dev->trans_start = jiffies;
449: lp->tx_started = 1;
450: dev->tbusy = 0;
451: } else if (lp->tx_queue_len < 4096 - 1502)
452: /* Yes, there is room for one more packet. */
453: dev->tbusy = 0;
454:
455: /* Turn on Tx interrupts back on. */
456: outb(0x82, ioaddr + TX_INTR);
457: }
458: dev_kfree_skb (skb, FREE_WRITE);
459:
460: return 0;
461: }
462:
463: /* The typical workload of the driver:
464: Handle the network interface interrupts. */
465: static void
466: net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
467: {
468: struct device *dev = dev_id;
469: struct net_local *lp;
470: int ioaddr, status;
471:
472: if (dev == NULL) {
473: printk ("at1700_interrupt(): irq %d for unknown device.\n", irq);
474: return;
475: }
476: dev->interrupt = 1;
477:
478: ioaddr = dev->base_addr;
479: lp = (struct net_local *)dev->priv;
480: status = inw(ioaddr + TX_STATUS);
481: outw(status, ioaddr + TX_STATUS);
482:
483: if (net_debug > 4)
484: printk("%s: Interrupt with status %04x.\n", dev->name, status);
485: if (status & 0xff00
486: || (inb(ioaddr + RX_MODE) & 0x40) == 0) { /* Got a packet(s). */
487: net_rx(dev);
488: }
489: if (status & 0x00ff) {
490: if (status & 0x80) {
491: lp->stats.tx_packets++;
492: if (lp->tx_queue) {
493: outb(0x80 | lp->tx_queue, ioaddr + TX_START);
494: lp->tx_queue = 0;
495: lp->tx_queue_len = 0;
496: dev->trans_start = jiffies;
497: dev->tbusy = 0;
498: mark_bh(NET_BH); /* Inform upper layers. */
499: } else {
500: lp->tx_started = 0;
501: /* Turn on Tx interrupts off. */
502: outb(0x00, ioaddr + TX_INTR);
503: dev->tbusy = 0;
504: mark_bh(NET_BH); /* Inform upper layers. */
505: }
506: }
507: }
508:
509: dev->interrupt = 0;
510: return;
511: }
512:
513: /* We have a good packet(s), get it/them out of the buffers. */
514: static void
515: net_rx(struct device *dev)
516: {
517: struct net_local *lp = (struct net_local *)dev->priv;
518: int ioaddr = dev->base_addr;
519: int boguscount = 5;
520:
521: while ((inb(ioaddr + RX_MODE) & 0x40) == 0) {
522: ushort status = inw(ioaddr + DATAPORT);
523: ushort pkt_len = inw(ioaddr + DATAPORT);
524:
525: if (net_debug > 4)
526: printk("%s: Rxing packet mode %02x status %04x.\n",
527: dev->name, inb(ioaddr + RX_MODE), status);
528: #ifndef final_version
529: if (status == 0) {
530: outb(0x05, ioaddr + 14);
531: break;
532: }
533: #endif
534:
535: if ((status & 0xF0) != 0x20) { /* There was an error. */
536: lp->stats.rx_errors++;
537: if (status & 0x08) lp->stats.rx_length_errors++;
538: if (status & 0x04) lp->stats.rx_frame_errors++;
539: if (status & 0x02) lp->stats.rx_crc_errors++;
540: if (status & 0x01) lp->stats.rx_over_errors++;
541: } else {
542: /* Malloc up new buffer. */
543: struct sk_buff *skb;
544:
545: if (pkt_len > 1550) {
546: printk("%s: The AT1700 claimed a very large packet, size %d.\n",
547: dev->name, pkt_len);
548: /* Prime the FIFO and then flush the packet. */
549: inw(ioaddr + DATAPORT); inw(ioaddr + DATAPORT);
550: outb(0x05, ioaddr + 14);
551: lp->stats.rx_errors++;
552: break;
553: }
554: skb = dev_alloc_skb(pkt_len+3);
555: if (skb == NULL) {
556: printk("%s: Memory squeeze, dropping packet (len %d).\n",
557: dev->name, pkt_len);
558: /* Prime the FIFO and then flush the packet. */
559: inw(ioaddr + DATAPORT); inw(ioaddr + DATAPORT);
560: outb(0x05, ioaddr + 14);
561: lp->stats.rx_dropped++;
562: break;
563: }
564: skb->dev = dev;
565: skb_reserve(skb,2);
566:
567: insw(ioaddr + DATAPORT, skb_put(skb,pkt_len), (pkt_len + 1) >> 1);
568: skb->protocol=eth_type_trans(skb, dev);
569: netif_rx(skb);
570: lp->stats.rx_packets++;
571: }
572: if (--boguscount <= 0)
573: break;
574: }
575:
576: /* If any worth-while packets have been received, dev_rint()
577: has done a mark_bh(NET_BH) for us and will work on them
578: when we get to the bottom-half routine. */
579: {
580: int i;
581: for (i = 0; i < 20; i++) {
582: if ((inb(ioaddr + RX_MODE) & 0x40) == 0x40)
583: break;
584: inw(ioaddr + DATAPORT); /* dummy status read */
585: outb(0x05, ioaddr + 14);
586: }
587:
588: if (net_debug > 5)
589: printk("%s: Exint Rx packet with mode %02x after %d ticks.\n",
590: dev->name, inb(ioaddr + RX_MODE), i);
591: }
592: return;
593: }
594:
595: /* The inverse routine to net_open(). */
596: static int net_close(struct device *dev)
597: {
1.1.1.2 ! root 598: #if 0
1.1 root 599: struct net_local *lp = (struct net_local *)dev->priv;
1.1.1.2 ! root 600: #endif
1.1 root 601: int ioaddr = dev->base_addr;
602:
603: dev->tbusy = 1;
604: dev->start = 0;
605:
606: /* Set configuration register 0 to disable Tx and Rx. */
607: outb(0xda, ioaddr + CONFIG_0);
608:
609: /* No statistic counters on the chip to update. */
610:
611: #if 0
612: /* Disable the IRQ on boards where it is feasible. */
613: if (lp->jumpered) {
614: outb(0x00, ioaddr + IOCONFIG1);
615: free_irq(dev->irq, dev);
616: }
617: #endif
618:
619: /* Power-down the chip. Green, green, green! */
620: outb(0x00, ioaddr + CONFIG_1);
621:
622: MOD_DEC_USE_COUNT;
623:
624: return 0;
625: }
626:
627: /* Get the current statistics.
628: This may be called with the card open or closed.
629: There are no on-chip counters, so this function is trivial.
630: */
631: static struct enet_statistics *
632: net_get_stats(struct device *dev)
633: {
634: struct net_local *lp = (struct net_local *)dev->priv;
635: return &lp->stats;
636: }
637:
638: /*
639: Set the multicast/promiscuous mode for this adaptor.
640: */
641:
642: /* The little-endian AUTODIN II ethernet CRC calculation.
643: N.B. Do not use for bulk data, use a table-based routine instead.
644: This is common code and should be moved to net/core/crc.c */
645: static unsigned const ethernet_polynomial_le = 0xedb88320U;
646: static inline unsigned ether_crc_le(int length, unsigned char *data)
647: {
648: unsigned int crc = 0xffffffff; /* Initial value. */
649: while(--length >= 0) {
650: unsigned char current_octet = *data++;
651: int bit;
652: for (bit = 8; --bit >= 0; current_octet >>= 1) {
653: if ((crc ^ current_octet) & 1) {
654: crc >>= 1;
655: crc ^= ethernet_polynomial_le;
656: } else
657: crc >>= 1;
658: }
659: }
660: return crc;
661: }
662:
663: static void
664: set_rx_mode(struct device *dev)
665: {
666: int ioaddr = dev->base_addr;
667: struct net_local *lp = (struct net_local *)dev->priv;
668: unsigned char mc_filter[8]; /* Multicast hash filter */
669: long flags;
670: int i;
671:
672: if (dev->flags & IFF_PROMISC) {
673: /* Unconditionally log net taps. */
674: printk("%s: Promiscuous mode enabled.\n", dev->name);
675: memset(mc_filter, 0xff, sizeof(mc_filter));
676: outb(3, ioaddr + RX_MODE); /* Enable promiscuous mode */
677: } else if (dev->mc_count > MC_FILTERBREAK
678: || (dev->flags & IFF_ALLMULTI)) {
679: /* Too many to filter perfectly -- accept all multicasts. */
680: memset(mc_filter, 0xff, sizeof(mc_filter));
681: outb(2, ioaddr + RX_MODE); /* Use normal mode. */
682: } else if (dev->mc_count == 0) {
683: memset(mc_filter, 0x00, sizeof(mc_filter));
684: outb(1, ioaddr + RX_MODE); /* Ignore almost all multicasts. */
685: } else {
686: struct dev_mc_list *mclist;
687: int i;
688:
689: memset(mc_filter, 0, sizeof(mc_filter));
690: for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
691: i++, mclist = mclist->next)
692: set_bit(ether_crc_le(ETH_ALEN, mclist->dmi_addr) >> 26,
693: mc_filter);
694: }
695:
696: save_flags(flags);
697: cli();
698: if (memcmp(mc_filter, lp->mc_filter, sizeof(mc_filter))) {
699: int saved_bank = inw(ioaddr + CONFIG_0);
700: /* Switch to bank 1 and set the multicast table. */
701: outw((saved_bank & ~0x0C00) | 0x0480, ioaddr + CONFIG_0);
702: for (i = 0; i < 8; i++)
703: outb(mc_filter[i], ioaddr + 8 + i);
704: memcpy(lp->mc_filter, mc_filter, sizeof(mc_filter));
705: outw(saved_bank, ioaddr + CONFIG_0);
706: }
707: restore_flags(flags);
708: return;
709: }
710:
711: #ifdef MODULE
712: static char devicename[9] = { 0, };
713: static struct device dev_at1700 = {
714: devicename, /* device name is inserted by linux/drivers/net/net_init.c */
715: 0, 0, 0, 0,
716: 0, 0,
717: 0, 0, 0, NULL, at1700_probe };
718:
719: static int io = 0x260;
720: static int irq = 0;
721:
722: int init_module(void)
723: {
724: if (io == 0)
725: printk("at1700: You should not use auto-probing with insmod!\n");
726: dev_at1700.base_addr = io;
727: dev_at1700.irq = irq;
728: if (register_netdev(&dev_at1700) != 0) {
729: printk("at1700: register_netdev() returned non-zero.\n");
730: return -EIO;
731: }
732: return 0;
733: }
734:
735: void
736: cleanup_module(void)
737: {
738: unregister_netdev(&dev_at1700);
739: kfree(dev_at1700.priv);
740: dev_at1700.priv = NULL;
741:
742: /* If we don't do this, we can't re-insmod it later. */
743: free_irq(dev_at1700.irq, NULL);
744: release_region(dev_at1700.base_addr, AT1700_IO_EXTENT);
745: }
746: #endif /* MODULE */
747:
748: /*
749: * Local variables:
750: * compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c at1700.c"
751: * alt-compile-command: "gcc -DMODVERSIONS -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c at1700.c"
752: * tab-width: 4
753: * c-basic-offset: 4
754: * c-indent-level: 4
755: * End:
756: */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.