1
2
3
4
5
6
7
8
9
10
11
12
13
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
22
23
24
25
26
27
28
29
30
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>
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>
48#include <linux/jiffies.h>
49
50#include <asm/system.h>
51#include <asm/io.h>
52#include <asm/dma.h>
53
54#include "seeq8005.h"
55
56
57
58static unsigned int seeq8005_portlist[] __initdata =
59 { 0x300, 0x320, 0x340, 0x360, 0};
60
61
62#ifndef NET_DEBUG
63#define NET_DEBUG 1
64#endif
65static unsigned int net_debug = NET_DEBUG;
66
67
68struct net_local {
69 unsigned short receive_ptr;
70 long open_time;
71};
72
73
74#define SA_ADDR0 0x00
75#define SA_ADDR1 0x80
76#define SA_ADDR2 0x4b
77
78
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);
83static netdev_tx_t seeq8005_send_packet(struct sk_buff *skb,
84 struct net_device *dev);
85static irqreturn_t seeq8005_interrupt(int irq, void *dev_id);
86static void seeq8005_rx(struct net_device *dev);
87static int seeq8005_close(struct net_device *dev);
88static void set_multicast_list(struct net_device *dev);
89
90
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
96
97
98
99
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) {
122 err = seeq8005_probe1(dev, io);
123 } else if (io != 0) {
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
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
157
158
159
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);
180 if (old_stat == 0xffff) {
181 retval = -ENODEV;
182 goto out;
183 }
184 if ( (old_stat & 0x1800) != 0x1800 ) {
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) {
197 retval = -ENODEV;
198 goto out;
199 }
200 } else if ((old_rear & 0xff00) != 0xff00) {
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 }
208
209 old_cfg2 = inw(SEEQ_CFG2);
210 old_cfg1 = inw(SEEQ_CFG1);
211 old_dmaar = inw(SEEQ_DMAAR);
212
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 }
220
221 outw( SEEQCMD_FIFO_WRITE | SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
222 outw( 0, SEEQ_DMAAR);
223 outw( SEEQCFG1_BUFFER_PROM, SEEQ_CFG1);
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
233 if ( (j&0xff) != 0 ) {
234 if (net_debug>1) {
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);
246 udelay(5);
247 outw( SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
248
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
268#if 0
269
270
271
272
273
274 if (net_debug>1) {
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
310 dev->base_addr = ioaddr;
311 dev->irq = irq;
312
313
314 for (i = 0; i < 6; i++)
315 dev->dev_addr[i] = SA_prom[i+6];
316 printk("%pM", dev->dev_addr);
317
318 if (dev->irq == 0xff)
319 ;
320 else if (dev->irq < 2) {
321 unsigned long cookie = probe_irq_on();
322
323 outw( SEEQCMD_RX_INT_EN | SEEQCMD_SET_RX_ON | SEEQCMD_SET_RX_OFF, SEEQ_CMD );
324
325 dev->irq = probe_irq_off(cookie);
326
327 if (net_debug >= 2)
328 printk(" autoirq is %d\n", dev->irq);
329 } else if (dev->irq == 2)
330
331
332
333 dev->irq = 9;
334
335#if 0
336 {
337 int irqval = request_irq(dev->irq, seeq8005_interrupt, 0, "seeq8005", dev);
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
346 dev->netdev_ops = &seeq8005_netdev_ops;
347 dev->watchdog_timeo = HZ/20;
348 dev->flags &= ~IFF_MULTICAST;
349
350 return 0;
351out:
352 release_region(ioaddr, SEEQ8005_IO_EXTENT);
353 return retval;
354}
355
356
357
358
359
360
361
362
363
364static int seeq8005_open(struct net_device *dev)
365{
366 struct net_local *lp = netdev_priv(dev);
367
368 {
369 int irqval = request_irq(dev->irq, seeq8005_interrupt, 0, "seeq8005", dev);
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
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
392 seeq8005_init(dev, 1);
393 dev->trans_start = jiffies;
394 netif_wake_queue(dev);
395}
396
397static netdev_tx_t seeq8005_send_packet(struct sk_buff *skb,
398 struct net_device *dev)
399{
400 short length = skb->len;
401 unsigned char *buf;
402
403 if (length < ETH_ZLEN) {
404 if (skb_padto(skb, ETH_ZLEN))
405 return NETDEV_TX_OK;
406 length = ETH_ZLEN;
407 }
408 buf = skb->data;
409
410
411 netif_stop_queue(dev);
412
413 hardware_send_packet(dev, buf, length);
414 dev->stats.tx_bytes += length;
415 dev_kfree_skb (skb);
416
417
418 return NETDEV_TX_OK;
419}
420
421
422
423
424
425
426
427
428inline void wait_for_buffer(struct net_device * dev)
429{
430 int ioaddr = dev->base_addr;
431 unsigned long tmp;
432 int status;
433
434 tmp = jiffies + HZ;
435 while ( ( ((status=inw(SEEQ_STATUS)) & SEEQSTAT_WINDOW_INT) != SEEQSTAT_WINDOW_INT) && time_before(jiffies, tmp))
436 cpu_relax();
437
438 if ( (status & SEEQSTAT_WINDOW_INT) == SEEQSTAT_WINDOW_INT)
439 outw( SEEQCMD_WINDOW_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
440}
441
442
443
444static irqreturn_t seeq8005_interrupt(int irq, void *dev_id)
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 }
459
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);
470 dev->stats.tx_packets++;
471 netif_wake_queue(dev);
472 }
473 if (status & SEEQSTAT_RX_INT) {
474 handled = 1;
475
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
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);
507
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 }
511
512 if ((next_packet == 0) || ((pkt_hdr & SEEQPKTH_CHAIN)==0)) {
513 return;
514 }
515
516 if ((pkt_hdr & SEEQPKTS_DONE)==0)
517 break;
518
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 }
524
525 if (next_packet < ((DEFAULT_TEA+1)<<8)) {
526 printk("%s: recv packet ring corrupt, resetting board\n",dev->name);
527 seeq8005_init(dev,1);
528 return;
529 }
530
531 lp->receive_ptr = next_packet;
532
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) {
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++;
543
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
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);
554 dev->stats.rx_dropped++;
555 break;
556 }
557 skb_reserve(skb, 2);
558 buf = skb_put(skb,pkt_len);
559
560 insw(SEEQ_BUFFER, buf, (pkt_len + 1) >> 1);
561
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);
573 dev->stats.rx_packets++;
574 dev->stats.rx_bytes += pkt_len;
575 }
576 } while ((--boguscount) && (pkt_hdr & SEEQPKTH_CHAIN));
577
578
579
580
581}
582
583
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);
592
593
594 outw( SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
595
596 free_irq(dev->irq, dev);
597
598
599
600 return 0;
601
602}
603
604
605
606
607
608
609
610static void set_multicast_list(struct net_device *dev)
611{
612
613
614
615
616#if 0
617 int ioaddr = dev->base_addr;
618
619
620
621
622
623 if (num_addrs) {
624 outw( (inw(SEEQ_CFG1) & ~SEEQCFG1_MATCH_MASK)| SEEQCFG1_MATCH_ALL, SEEQ_CFG1);
625 dev->flags|=IFF_PROMISC;
626 } else {
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;
637
638 outw(SEEQCFG2_RESET, SEEQ_CFG2);
639 udelay(5);
640
641 outw( SEEQCMD_FIFO_WRITE | SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
642 outw( 0, SEEQ_DMAAR);
643
644 outw( SEEQCFG1_BUFFER_MAC0, SEEQ_CFG1);
645
646 for(i=0;i<6;i++) {
647 outb(dev->dev_addr[i], SEEQ_BUFFER);
648 udelay(2);
649 }
650
651 outw( SEEQCFG1_BUFFER_TEA, SEEQ_CFG1);
652 outb( DEFAULT_TEA, SEEQ_BUFFER);
653
654 lp->receive_ptr = (DEFAULT_TEA+1)<<8;
655 outw( lp->receive_ptr, SEEQ_RPR);
656
657 outw( 0x00ff, SEEQ_REA);
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);
665
666 for(i=0;i<6;i++) {
667 printk("%02x ",inb(SEEQ_BUFFER));
668 }
669 printk("\n");
670 }
671
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));
684
685 }
686}
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;
694 unsigned long tmp;
695
696 if (net_debug>4) {
697 printk("%s: send 0x%04x\n",dev->name,length);
698 }
699
700
701 outw( SEEQCMD_FIFO_WRITE | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
702 outw( transmit_ptr, SEEQ_DMAAR);
703
704
705 outw( htons(length + 4), SEEQ_BUFFER);
706 outw( SEEQPKTH_XMIT | SEEQPKTH_DATA_FOLLOWS | SEEQPKTH_XMIT_INT_EN, SEEQ_BUFFER );
707
708
709 outsw( SEEQ_BUFFER, buf, (length +1) >> 1);
710
711 outw( 0, SEEQ_BUFFER);
712 outw( 0, SEEQ_BUFFER);
713
714
715 outw( transmit_ptr, SEEQ_TPR);
716
717
718 tmp = jiffies;
719 while ( (((status=inw(SEEQ_STATUS)) & SEEQSTAT_FIFO_EMPTY) == 0) && time_before(jiffies, tmp + HZ))
720 mb();
721
722
723 outw( SEEQCMD_WINDOW_INT_ACK | SEEQCMD_SET_TX_ON | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
724
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
737int __init init_module(void)
738{
739 dev_seeq = seeq8005_probe(-1);
740 if (IS_ERR(dev_seeq))
741 return PTR_ERR(dev_seeq);
742 return 0;
743}
744
745void __exit cleanup_module(void)
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
753