]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/net/seeq8005.c
scm: lower SCM_MAX_FD
[net-next-2.6.git] / drivers / net / seeq8005.c
CommitLineData
1da177e4
LT
1/* seeq8005.c: A network driver for linux. */
2/*
3 Based on skeleton.c,
4 Written 1993-94 by Donald Becker.
5 See the skeleton.c file for further copyright information.
6
7 This software may be used and distributed according to the terms
8 of the GNU General Public License, incorporated herein by reference.
9
10 The author may be reached as hamish@zot.apana.org.au
11
12 This file is a network device driver for the SEEQ 8005 chipset and
13 the Linux operating system.
14
15*/
16
17static const char version[] =
18 "seeq8005.c:v1.00 8/07/95 Hamish Coleman (hamish@zot.apana.org.au)\n";
19
20/*
21 Sources:
22 SEEQ 8005 databook
6aa20a22 23
1da177e4
LT
24 Version history:
25 1.00 Public release. cosmetic changes (no warnings now)
26 0.68 Turning per- packet,interrupt debug messages off - testing for release.
27 0.67 timing problems/bad buffer reads seem to be fixed now
28 0.63 *!@$ protocol=eth_type_trans -- now packets flow
29 0.56 Send working
30 0.48 Receive working
31*/
32
33#include <linux/module.h>
34#include <linux/kernel.h>
35#include <linux/types.h>
36#include <linux/fcntl.h>
37#include <linux/interrupt.h>
38#include <linux/ioport.h>
39#include <linux/in.h>
1da177e4
LT
40#include <linux/string.h>
41#include <linux/init.h>
42#include <linux/delay.h>
43#include <linux/errno.h>
44#include <linux/netdevice.h>
45#include <linux/etherdevice.h>
46#include <linux/skbuff.h>
47#include <linux/bitops.h>
ff5688ae 48#include <linux/jiffies.h>
1da177e4
LT
49
50#include <asm/system.h>
51#include <asm/io.h>
52#include <asm/dma.h>
53
54#include "seeq8005.h"
55
56/* First, a few definitions that the brave might change. */
57/* A zero-terminated list of I/O addresses to be probed. */
58static unsigned int seeq8005_portlist[] __initdata =
59 { 0x300, 0x320, 0x340, 0x360, 0};
60
61/* use 0 for production, 1 for verification, >2 for debug */
62#ifndef NET_DEBUG
63#define NET_DEBUG 1
64#endif
65static unsigned int net_debug = NET_DEBUG;
66
67/* Information that need to be kept for each board. */
68struct net_local {
1da177e4
LT
69 unsigned short receive_ptr; /* What address in packet memory do we expect a recv_pkt_header? */
70 long open_time; /* Useless example local info. */
71};
72
73/* The station (ethernet) address prefix, used for IDing the board. */
74#define SA_ADDR0 0x00
75#define SA_ADDR1 0x80
76#define SA_ADDR2 0x4b
77
78/* Index to functions, as function prototypes. */
79
80static int seeq8005_probe1(struct net_device *dev, int ioaddr);
81static int seeq8005_open(struct net_device *dev);
82static void seeq8005_timeout(struct net_device *dev);
61357325
SH
83static netdev_tx_t seeq8005_send_packet(struct sk_buff *skb,
84 struct net_device *dev);
7d12e780 85static irqreturn_t seeq8005_interrupt(int irq, void *dev_id);
1da177e4
LT
86static void seeq8005_rx(struct net_device *dev);
87static int seeq8005_close(struct net_device *dev);
1da177e4
LT
88static void set_multicast_list(struct net_device *dev);
89
90/* Example routines you must write ;->. */
91#define tx_done(dev) (inw(SEEQ_STATUS) & SEEQSTAT_TX_ON)
92static void hardware_send_packet(struct net_device *dev, char *buf, int length);
93extern void seeq8005_init(struct net_device *dev, int startp);
94static inline void wait_for_buffer(struct net_device *dev);
95
6aa20a22 96
1da177e4
LT
97/* Check for a network adaptor of this type, and return '0' iff one exists.
98 If dev->base_addr == 0, probe all likely locations.
99 If dev->base_addr == 1, always return failure.
100 */
101
102static int io = 0x320;
103static int irq = 10;
104
105struct net_device * __init seeq8005_probe(int unit)
106{
107 struct net_device *dev = alloc_etherdev(sizeof(struct net_local));
108 unsigned *port;
109 int err = 0;
110
111 if (!dev)
112 return ERR_PTR(-ENODEV);
113
114 if (unit >= 0) {
115 sprintf(dev->name, "eth%d", unit);
116 netdev_boot_setup_check(dev);
117 io = dev->base_addr;
118 irq = dev->irq;
119 }
120
121 if (io > 0x1ff) { /* Check a single specified location. */
122 err = seeq8005_probe1(dev, io);
123 } else if (io != 0) { /* Don't probe at all. */
124 err = -ENXIO;
125 } else {
126 for (port = seeq8005_portlist; *port; port++) {
127 if (seeq8005_probe1(dev, *port) == 0)
128 break;
129 }
130 if (!*port)
131 err = -ENODEV;
132 }
133 if (err)
134 goto out;
135 err = register_netdev(dev);
136 if (err)
137 goto out1;
138 return dev;
139out1:
140 release_region(dev->base_addr, SEEQ8005_IO_EXTENT);
141out:
142 free_netdev(dev);
143 return ERR_PTR(err);
144}
145
b20417db
SH
146static const struct net_device_ops seeq8005_netdev_ops = {
147 .ndo_open = seeq8005_open,
148 .ndo_stop = seeq8005_close,
149 .ndo_start_xmit = seeq8005_send_packet,
150 .ndo_tx_timeout = seeq8005_timeout,
151 .ndo_set_multicast_list = set_multicast_list,
152 .ndo_change_mtu = eth_change_mtu,
153 .ndo_set_mac_address = eth_mac_addr,
154 .ndo_validate_addr = eth_validate_addr,
155};
156
1da177e4
LT
157/* This is the real probe routine. Linux has a history of friendly device
158 probes on the ISA bus. A good device probes avoids doing writes, and
159 verifies that the correct device exists and functions. */
160
161static int __init seeq8005_probe1(struct net_device *dev, int ioaddr)
162{
163 static unsigned version_printed;
164 int i,j;
165 unsigned char SA_prom[32];
166 int old_cfg1;
167 int old_cfg2;
168 int old_stat;
169 int old_dmaar;
170 int old_rear;
171 int retval;
172
173 if (!request_region(ioaddr, SEEQ8005_IO_EXTENT, "seeq8005"))
174 return -ENODEV;
175
176 if (net_debug>1)
177 printk("seeq8005: probing at 0x%x\n",ioaddr);
178
179 old_stat = inw(SEEQ_STATUS); /* read status register */
180 if (old_stat == 0xffff) {
181 retval = -ENODEV;
182 goto out; /* assume that 0xffff == no device */
183 }
184 if ( (old_stat & 0x1800) != 0x1800 ) { /* assume that unused bits are 1, as my manual says */
185 if (net_debug>1) {
186 printk("seeq8005: reserved stat bits != 0x1800\n");
187 printk(" == 0x%04x\n",old_stat);
188 }
189 retval = -ENODEV;
190 goto out;
191 }
192
193 old_rear = inw(SEEQ_REA);
194 if (old_rear == 0xffff) {
195 outw(0,SEEQ_REA);
196 if (inw(SEEQ_REA) == 0xffff) { /* assume that 0xffff == no device */
197 retval = -ENODEV;
198 goto out;
199 }
200 } else if ((old_rear & 0xff00) != 0xff00) { /* assume that unused bits are 1 */
201 if (net_debug>1) {
202 printk("seeq8005: unused rear bits != 0xff00\n");
203 printk(" == 0x%04x\n",old_rear);
204 }
205 retval = -ENODEV;
206 goto out;
207 }
6aa20a22 208
1da177e4
LT
209 old_cfg2 = inw(SEEQ_CFG2); /* read CFG2 register */
210 old_cfg1 = inw(SEEQ_CFG1);
211 old_dmaar = inw(SEEQ_DMAAR);
6aa20a22 212
1da177e4
LT
213 if (net_debug>4) {
214 printk("seeq8005: stat = 0x%04x\n",old_stat);
215 printk("seeq8005: cfg1 = 0x%04x\n",old_cfg1);
216 printk("seeq8005: cfg2 = 0x%04x\n",old_cfg2);
217 printk("seeq8005: raer = 0x%04x\n",old_rear);
218 printk("seeq8005: dmaar= 0x%04x\n",old_dmaar);
219 }
6aa20a22 220
1da177e4
LT
221 outw( SEEQCMD_FIFO_WRITE | SEEQCMD_SET_ALL_OFF, SEEQ_CMD); /* setup for reading PROM */
222 outw( 0, SEEQ_DMAAR); /* set starting PROM address */
223 outw( SEEQCFG1_BUFFER_PROM, SEEQ_CFG1); /* set buffer to look at PROM */
224
225
226 j=0;
227 for(i=0; i <32; i++) {
228 j+= SA_prom[i] = inw(SEEQ_BUFFER) & 0xff;
229 }
230
231#if 0
232 /* untested because I only have the one card */
233 if ( (j&0xff) != 0 ) { /* checksum appears to be 8bit = 0 */
234 if (net_debug>1) { /* check this before deciding that we have a card */
235 printk("seeq8005: prom sum error\n");
236 }
237 outw( old_stat, SEEQ_STATUS);
238 outw( old_dmaar, SEEQ_DMAAR);
239 outw( old_cfg1, SEEQ_CFG1);
240 retval = -ENODEV;
241 goto out;
242 }
243#endif
244
245 outw( SEEQCFG2_RESET, SEEQ_CFG2); /* reset the card */
246 udelay(5);
247 outw( SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
6aa20a22 248
1da177e4
LT
249 if (net_debug) {
250 printk("seeq8005: prom sum = 0x%08x\n",j);
251 for(j=0; j<32; j+=16) {
252 printk("seeq8005: prom %02x: ",j);
253 for(i=0;i<16;i++) {
254 printk("%02x ",SA_prom[j|i]);
255 }
256 printk(" ");
257 for(i=0;i<16;i++) {
258 if ((SA_prom[j|i]>31)&&(SA_prom[j|i]<127)) {
259 printk("%c", SA_prom[j|i]);
260 } else {
261 printk(" ");
262 }
263 }
264 printk("\n");
265 }
266 }
267
6aa20a22
JG
268#if 0
269 /*
1da177e4 270 * testing the packet buffer memory doesn't work yet
6aa20a22 271 * but all other buffer accesses do
1da177e4
LT
272 * - fixing is not a priority
273 */
274 if (net_debug>1) { /* test packet buffer memory */
275 printk("seeq8005: testing packet buffer ... ");
276 outw( SEEQCFG1_BUFFER_BUFFER, SEEQ_CFG1);
277 outw( SEEQCMD_FIFO_WRITE | SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
278 outw( 0 , SEEQ_DMAAR);
279 for(i=0;i<32768;i++) {
280 outw(0x5a5a, SEEQ_BUFFER);
281 }
282 j=jiffies+HZ;
283 while ( ((inw(SEEQ_STATUS) & SEEQSTAT_FIFO_EMPTY) != SEEQSTAT_FIFO_EMPTY) && time_before(jiffies, j) )
284 mb();
285 outw( 0 , SEEQ_DMAAR);
286 while ( ((inw(SEEQ_STATUS) & SEEQSTAT_WINDOW_INT) != SEEQSTAT_WINDOW_INT) && time_before(jiffies, j+HZ))
287 mb();
288 if ( (inw(SEEQ_STATUS) & SEEQSTAT_WINDOW_INT) == SEEQSTAT_WINDOW_INT)
289 outw( SEEQCMD_WINDOW_INT_ACK | (inw(SEEQ_STATUS)& SEEQCMD_INT_MASK), SEEQ_CMD);
290 outw( SEEQCMD_FIFO_READ | SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
291 j=0;
292 for(i=0;i<32768;i++) {
293 if (inw(SEEQ_BUFFER) != 0x5a5a)
294 j++;
295 }
296 if (j) {
297 printk("%i\n",j);
298 } else {
299 printk("ok.\n");
300 }
301 }
302#endif
303
304 if (net_debug && version_printed++ == 0)
305 printk(version);
306
307 printk("%s: %s found at %#3x, ", dev->name, "seeq8005", ioaddr);
308
309 /* Fill in the 'dev' fields. */
310 dev->base_addr = ioaddr;
311 dev->irq = irq;
312
313 /* Retrieve and print the ethernet address. */
314 for (i = 0; i < 6; i++)
0795af57 315 dev->dev_addr[i] = SA_prom[i+6];
e174961c 316 printk("%pM", dev->dev_addr);
1da177e4
LT
317
318 if (dev->irq == 0xff)
319 ; /* Do nothing: a user-level program will set it. */
320 else if (dev->irq < 2) { /* "Auto-IRQ" */
321 unsigned long cookie = probe_irq_on();
6aa20a22 322
1da177e4
LT
323 outw( SEEQCMD_RX_INT_EN | SEEQCMD_SET_RX_ON | SEEQCMD_SET_RX_OFF, SEEQ_CMD );
324
325 dev->irq = probe_irq_off(cookie);
6aa20a22 326
1da177e4
LT
327 if (net_debug >= 2)
328 printk(" autoirq is %d\n", dev->irq);
329 } else if (dev->irq == 2)
330 /* Fixup for users that don't know that IRQ 2 is really IRQ 9,
6aa20a22 331 * or don't know which one to set.
1da177e4
LT
332 */
333 dev->irq = 9;
334
335#if 0
336 {
a0607fd3 337 int irqval = request_irq(dev->irq, seeq8005_interrupt, 0, "seeq8005", dev);
1da177e4
LT
338 if (irqval) {
339 printk ("%s: unable to get IRQ %d (irqval=%d).\n", dev->name,
340 dev->irq, irqval);
341 retval = -EAGAIN;
342 goto out;
343 }
344 }
345#endif
b20417db 346 dev->netdev_ops = &seeq8005_netdev_ops;
1da177e4 347 dev->watchdog_timeo = HZ/20;
1da177e4
LT
348 dev->flags &= ~IFF_MULTICAST;
349
350 return 0;
351out:
352 release_region(ioaddr, SEEQ8005_IO_EXTENT);
353 return retval;
354}
355
6aa20a22 356
1da177e4
LT
357/* Open/initialize the board. This is called (in the current kernel)
358 sometime after booting when the 'ifconfig' program is run.
359
360 This routine should set everything up anew at each open, even
361 registers that "should" only need to be set once at boot, so that
362 there is non-reboot way to recover if something goes wrong.
363 */
364static int seeq8005_open(struct net_device *dev)
365{
366 struct net_local *lp = netdev_priv(dev);
367
368 {
a0607fd3 369 int irqval = request_irq(dev->irq, seeq8005_interrupt, 0, "seeq8005", dev);
1da177e4
LT
370 if (irqval) {
371 printk ("%s: unable to get IRQ %d (irqval=%d).\n", dev->name,
372 dev->irq, irqval);
373 return -EAGAIN;
374 }
375 }
376
377 /* Reset the hardware here. Don't forget to set the station address. */
378 seeq8005_init(dev, 1);
379
380 lp->open_time = jiffies;
381
382 netif_start_queue(dev);
383 return 0;
384}
385
386static void seeq8005_timeout(struct net_device *dev)
387{
388 int ioaddr = dev->base_addr;
389 printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name,
390 tx_done(dev) ? "IRQ conflict" : "network cable problem");
391 /* Try to restart the adaptor. */
392 seeq8005_init(dev, 1);
1ae5dc34 393 dev->trans_start = jiffies; /* prevent tx timeout */
1da177e4
LT
394 netif_wake_queue(dev);
395}
396
61357325
SH
397static netdev_tx_t seeq8005_send_packet(struct sk_buff *skb,
398 struct net_device *dev)
1da177e4 399{
1da177e4
LT
400 short length = skb->len;
401 unsigned char *buf;
402
403 if (length < ETH_ZLEN) {
5b057c6b 404 if (skb_padto(skb, ETH_ZLEN))
6ed10654 405 return NETDEV_TX_OK;
1da177e4
LT
406 length = ETH_ZLEN;
407 }
408 buf = skb->data;
409
410 /* Block a timer-based transmit from overlapping */
411 netif_stop_queue(dev);
6aa20a22
JG
412
413 hardware_send_packet(dev, buf, length);
09f75cd7 414 dev->stats.tx_bytes += length;
1da177e4
LT
415 dev_kfree_skb (skb);
416 /* You might need to clean up and record Tx statistics here. */
417
6ed10654 418 return NETDEV_TX_OK;
1da177e4 419}
6aa20a22 420
1da177e4
LT
421/*
422 * wait_for_buffer
423 *
424 * This routine waits for the SEEQ chip to assert that the FIFO is ready
425 * by checking for a window interrupt, and then clearing it. This has to
426 * occur in the interrupt handler!
427 */
428inline void wait_for_buffer(struct net_device * dev)
429{
430 int ioaddr = dev->base_addr;
431 unsigned long tmp;
432 int status;
6aa20a22 433
1da177e4
LT
434 tmp = jiffies + HZ;
435 while ( ( ((status=inw(SEEQ_STATUS)) & SEEQSTAT_WINDOW_INT) != SEEQSTAT_WINDOW_INT) && time_before(jiffies, tmp))
436 cpu_relax();
6aa20a22 437
1da177e4
LT
438 if ( (status & SEEQSTAT_WINDOW_INT) == SEEQSTAT_WINDOW_INT)
439 outw( SEEQCMD_WINDOW_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
440}
6aa20a22 441
1da177e4
LT
442/* The typical workload of the driver:
443 Handle the network interface interrupts. */
7d12e780 444static irqreturn_t seeq8005_interrupt(int irq, void *dev_id)
1da177e4
LT
445{
446 struct net_device *dev = dev_id;
447 struct net_local *lp;
448 int ioaddr, status, boguscount = 0;
449 int handled = 0;
450
451 ioaddr = dev->base_addr;
452 lp = netdev_priv(dev);
453
454 status = inw(SEEQ_STATUS);
455 do {
456 if (net_debug >2) {
457 printk("%s: int, status=0x%04x\n",dev->name,status);
458 }
6aa20a22 459
1da177e4
LT
460 if (status & SEEQSTAT_WINDOW_INT) {
461 handled = 1;
462 outw( SEEQCMD_WINDOW_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
463 if (net_debug) {
464 printk("%s: window int!\n",dev->name);
465 }
466 }
467 if (status & SEEQSTAT_TX_INT) {
468 handled = 1;
469 outw( SEEQCMD_TX_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
09f75cd7 470 dev->stats.tx_packets++;
1da177e4
LT
471 netif_wake_queue(dev); /* Inform upper layers. */
472 }
473 if (status & SEEQSTAT_RX_INT) {
474 handled = 1;
475 /* Got a packet(s). */
476 seeq8005_rx(dev);
477 }
478 status = inw(SEEQ_STATUS);
479 } while ( (++boguscount < 10) && (status & SEEQSTAT_ANY_INT)) ;
480
481 if(net_debug>2) {
482 printk("%s: eoi\n",dev->name);
483 }
484 return IRQ_RETVAL(handled);
485}
486
487/* We have a good packet(s), get it/them out of the buffers. */
488static void seeq8005_rx(struct net_device *dev)
489{
490 struct net_local *lp = netdev_priv(dev);
491 int boguscount = 10;
492 int pkt_hdr;
493 int ioaddr = dev->base_addr;
494
495 do {
496 int next_packet;
497 int pkt_len;
498 int i;
499 int status;
500
501 status = inw(SEEQ_STATUS);
502 outw( lp->receive_ptr, SEEQ_DMAAR);
503 outw(SEEQCMD_FIFO_READ | SEEQCMD_RX_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
504 wait_for_buffer(dev);
505 next_packet = ntohs(inw(SEEQ_BUFFER));
506 pkt_hdr = inw(SEEQ_BUFFER);
6aa20a22 507
1da177e4
LT
508 if (net_debug>2) {
509 printk("%s: 0x%04x recv next=0x%04x, hdr=0x%04x\n",dev->name,lp->receive_ptr,next_packet,pkt_hdr);
510 }
6aa20a22 511
1da177e4
LT
512 if ((next_packet == 0) || ((pkt_hdr & SEEQPKTH_CHAIN)==0)) { /* Read all the frames? */
513 return; /* Done for now */
514 }
6aa20a22 515
1da177e4
LT
516 if ((pkt_hdr & SEEQPKTS_DONE)==0)
517 break;
6aa20a22 518
1da177e4
LT
519 if (next_packet < lp->receive_ptr) {
520 pkt_len = (next_packet + 0x10000 - ((DEFAULT_TEA+1)<<8)) - lp->receive_ptr - 4;
521 } else {
522 pkt_len = next_packet - lp->receive_ptr - 4;
523 }
6aa20a22 524
1da177e4
LT
525 if (next_packet < ((DEFAULT_TEA+1)<<8)) { /* is the next_packet address sane? */
526 printk("%s: recv packet ring corrupt, resetting board\n",dev->name);
527 seeq8005_init(dev,1);
528 return;
529 }
6aa20a22 530
1da177e4 531 lp->receive_ptr = next_packet;
6aa20a22 532
1da177e4
LT
533 if (net_debug>2) {
534 printk("%s: recv len=0x%04x\n",dev->name,pkt_len);
535 }
536
537 if (pkt_hdr & SEEQPKTS_ANY_ERROR) { /* There was an error. */
09f75cd7
JG
538 dev->stats.rx_errors++;
539 if (pkt_hdr & SEEQPKTS_SHORT) dev->stats.rx_frame_errors++;
540 if (pkt_hdr & SEEQPKTS_DRIB) dev->stats.rx_frame_errors++;
541 if (pkt_hdr & SEEQPKTS_OVERSIZE) dev->stats.rx_over_errors++;
542 if (pkt_hdr & SEEQPKTS_CRC_ERR) dev->stats.rx_crc_errors++;
1da177e4
LT
543 /* skip over this packet */
544 outw( SEEQCMD_FIFO_WRITE | SEEQCMD_DMA_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
545 outw( (lp->receive_ptr & 0xff00)>>8, SEEQ_REA);
546 } else {
547 /* Malloc up new buffer. */
548 struct sk_buff *skb;
549 unsigned char *buf;
550
551 skb = dev_alloc_skb(pkt_len);
552 if (skb == NULL) {
553 printk("%s: Memory squeeze, dropping packet.\n", dev->name);
09f75cd7 554 dev->stats.rx_dropped++;
1da177e4
LT
555 break;
556 }
1da177e4
LT
557 skb_reserve(skb, 2); /* align data on 16 byte */
558 buf = skb_put(skb,pkt_len);
6aa20a22 559
1da177e4 560 insw(SEEQ_BUFFER, buf, (pkt_len + 1) >> 1);
6aa20a22 561
1da177e4
LT
562 if (net_debug>2) {
563 char * p = buf;
564 printk("%s: recv ",dev->name);
565 for(i=0;i<14;i++) {
566 printk("%02x ",*(p++)&0xff);
567 }
568 printk("\n");
569 }
570
571 skb->protocol=eth_type_trans(skb,dev);
572 netif_rx(skb);
09f75cd7
JG
573 dev->stats.rx_packets++;
574 dev->stats.rx_bytes += pkt_len;
1da177e4
LT
575 }
576 } while ((--boguscount) && (pkt_hdr & SEEQPKTH_CHAIN));
577
578 /* If any worth-while packets have been received, netif_rx()
579 has done a mark_bh(NET_BH) for us and will work on them
580 when we get to the bottom-half routine. */
1da177e4
LT
581}
582
583/* The inverse routine to net_open(). */
584static int seeq8005_close(struct net_device *dev)
585{
586 struct net_local *lp = netdev_priv(dev);
587 int ioaddr = dev->base_addr;
588
589 lp->open_time = 0;
590
591 netif_stop_queue(dev);
6aa20a22 592
1da177e4
LT
593 /* Flush the Tx and disable Rx here. */
594 outw( SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
595
596 free_irq(dev->irq, dev);
597
598 /* Update the statistics here. */
599
600 return 0;
601
602}
603
1da177e4
LT
604/* Set or clear the multicast filter for this adaptor.
605 num_addrs == -1 Promiscuous mode, receive all packets
606 num_addrs == 0 Normal mode, clear multicast list
607 num_addrs > 0 Multicast mode, receive normal and MC packets, and do
608 best-effort filtering.
609 */
610static void set_multicast_list(struct net_device *dev)
611{
612/*
613 * I _could_ do up to 6 addresses here, but won't (yet?)
614 */
615
616#if 0
617 int ioaddr = dev->base_addr;
618/*
619 * hmm, not even sure if my matching works _anyway_ - seem to be receiving
620 * _everything_ . . .
621 */
6aa20a22 622
1da177e4
LT
623 if (num_addrs) { /* Enable promiscuous mode */
624 outw( (inw(SEEQ_CFG1) & ~SEEQCFG1_MATCH_MASK)| SEEQCFG1_MATCH_ALL, SEEQ_CFG1);
625 dev->flags|=IFF_PROMISC;
626 } else { /* Disable promiscuous mode, use normal mode */
627 outw( (inw(SEEQ_CFG1) & ~SEEQCFG1_MATCH_MASK)| SEEQCFG1_MATCH_BROAD, SEEQ_CFG1);
628 }
629#endif
630}
631
632void seeq8005_init(struct net_device *dev, int startp)
633{
634 struct net_local *lp = netdev_priv(dev);
635 int ioaddr = dev->base_addr;
636 int i;
6aa20a22 637
1da177e4
LT
638 outw(SEEQCFG2_RESET, SEEQ_CFG2); /* reset device */
639 udelay(5);
6aa20a22 640
1da177e4
LT
641 outw( SEEQCMD_FIFO_WRITE | SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
642 outw( 0, SEEQ_DMAAR); /* load start address into both low and high byte */
643/* wait_for_buffer(dev); */ /* I think that you only need a wait for memory buffer */
644 outw( SEEQCFG1_BUFFER_MAC0, SEEQ_CFG1);
6aa20a22 645
1da177e4
LT
646 for(i=0;i<6;i++) { /* set Station address */
647 outb(dev->dev_addr[i], SEEQ_BUFFER);
648 udelay(2);
649 }
6aa20a22 650
1da177e4
LT
651 outw( SEEQCFG1_BUFFER_TEA, SEEQ_CFG1); /* set xmit end area pointer to 16K */
652 outb( DEFAULT_TEA, SEEQ_BUFFER); /* this gives us 16K of send buffer and 48K of recv buffer */
6aa20a22 653
1da177e4
LT
654 lp->receive_ptr = (DEFAULT_TEA+1)<<8; /* so we can find our packet_header */
655 outw( lp->receive_ptr, SEEQ_RPR); /* Receive Pointer Register is set to recv buffer memory */
6aa20a22 656
1da177e4
LT
657 outw( 0x00ff, SEEQ_REA); /* Receive Area End */
658
659 if (net_debug>4) {
660 printk("%s: SA0 = ",dev->name);
661
662 outw( SEEQCMD_FIFO_READ | SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
663 outw( 0, SEEQ_DMAAR);
664 outw( SEEQCFG1_BUFFER_MAC0, SEEQ_CFG1);
6aa20a22 665
1da177e4
LT
666 for(i=0;i<6;i++) {
667 printk("%02x ",inb(SEEQ_BUFFER));
668 }
669 printk("\n");
670 }
6aa20a22 671
1da177e4
LT
672 outw( SEEQCFG1_MAC0_EN | SEEQCFG1_MATCH_BROAD | SEEQCFG1_BUFFER_BUFFER, SEEQ_CFG1);
673 outw( SEEQCFG2_AUTO_REA | SEEQCFG2_CTRLO, SEEQ_CFG2);
674 outw( SEEQCMD_SET_RX_ON | SEEQCMD_TX_INT_EN | SEEQCMD_RX_INT_EN, SEEQ_CMD);
675
676 if (net_debug>4) {
677 int old_cfg1;
678 old_cfg1 = inw(SEEQ_CFG1);
679 printk("%s: stat = 0x%04x\n",dev->name,inw(SEEQ_STATUS));
680 printk("%s: cfg1 = 0x%04x\n",dev->name,old_cfg1);
681 printk("%s: cfg2 = 0x%04x\n",dev->name,inw(SEEQ_CFG2));
682 printk("%s: raer = 0x%04x\n",dev->name,inw(SEEQ_REA));
683 printk("%s: dmaar= 0x%04x\n",dev->name,inw(SEEQ_DMAAR));
6aa20a22 684
1da177e4 685 }
6aa20a22 686}
1da177e4
LT
687
688
689static void hardware_send_packet(struct net_device * dev, char *buf, int length)
690{
691 int ioaddr = dev->base_addr;
692 int status = inw(SEEQ_STATUS);
693 int transmit_ptr = 0;
ff5688ae 694 unsigned long tmp;
1da177e4
LT
695
696 if (net_debug>4) {
697 printk("%s: send 0x%04x\n",dev->name,length);
698 }
6aa20a22 699
1da177e4
LT
700 /* Set FIFO to writemode and set packet-buffer address */
701 outw( SEEQCMD_FIFO_WRITE | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
702 outw( transmit_ptr, SEEQ_DMAAR);
6aa20a22 703
1da177e4
LT
704 /* output SEEQ Packet header barfage */
705 outw( htons(length + 4), SEEQ_BUFFER);
706 outw( SEEQPKTH_XMIT | SEEQPKTH_DATA_FOLLOWS | SEEQPKTH_XMIT_INT_EN, SEEQ_BUFFER );
6aa20a22 707
1da177e4
LT
708 /* blat the buffer */
709 outsw( SEEQ_BUFFER, buf, (length +1) >> 1);
710 /* paranoia !! */
711 outw( 0, SEEQ_BUFFER);
712 outw( 0, SEEQ_BUFFER);
6aa20a22 713
1da177e4
LT
714 /* set address of start of transmit chain */
715 outw( transmit_ptr, SEEQ_TPR);
6aa20a22 716
1da177e4
LT
717 /* drain FIFO */
718 tmp = jiffies;
ff5688ae 719 while ( (((status=inw(SEEQ_STATUS)) & SEEQSTAT_FIFO_EMPTY) == 0) && time_before(jiffies, tmp + HZ))
1da177e4 720 mb();
6aa20a22 721
1da177e4
LT
722 /* doit ! */
723 outw( SEEQCMD_WINDOW_INT_ACK | SEEQCMD_SET_TX_ON | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
6aa20a22 724
1da177e4
LT
725}
726
727
728#ifdef MODULE
729
730static struct net_device *dev_seeq;
731MODULE_LICENSE("GPL");
732module_param(io, int, 0);
733module_param(irq, int, 0);
734MODULE_PARM_DESC(io, "SEEQ 8005 I/O base address");
735MODULE_PARM_DESC(irq, "SEEQ 8005 IRQ number");
736
c971ef46 737int __init init_module(void)
1da177e4
LT
738{
739 dev_seeq = seeq8005_probe(-1);
740 if (IS_ERR(dev_seeq))
741 return PTR_ERR(dev_seeq);
742 return 0;
743}
744
afc8eb46 745void __exit cleanup_module(void)
1da177e4
LT
746{
747 unregister_netdev(dev_seeq);
748 release_region(dev_seeq->base_addr, SEEQ8005_IO_EXTENT);
749 free_netdev(dev_seeq);
750}
751
752#endif /* MODULE */