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/slab.h>
41#include <linux/string.h>
42#include <linux/init.h>
43#include <linux/delay.h>
44#include <linux/errno.h>
45#include <linux/netdevice.h>
46#include <linux/etherdevice.h>
47#include <linux/skbuff.h>
48#include <linux/bitops.h>
49#include <linux/jiffies.h>
50
51#include <asm/system.h>
52#include <asm/io.h>
53#include <asm/dma.h>
54
55#include "seeq8005.h"
56
57
58
59static unsigned int seeq8005_portlist[] __initdata =
60 { 0x300, 0x320, 0x340, 0x360, 0};
61
62
63#ifndef NET_DEBUG
64#define NET_DEBUG 1
65#endif
66static unsigned int net_debug = NET_DEBUG;
67
68
69struct net_local {
70 unsigned short receive_ptr;
71 long open_time;
72};
73
74
75#define SA_ADDR0 0x00
76#define SA_ADDR1 0x80
77#define SA_ADDR2 0x4b
78
79
80
81static int seeq8005_probe1(struct net_device *dev, int ioaddr);
82static int seeq8005_open(struct net_device *dev);
83static void seeq8005_timeout(struct net_device *dev);
84static int seeq8005_send_packet(struct sk_buff *skb, 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
146
147
148
149
150static int __init seeq8005_probe1(struct net_device *dev, int ioaddr)
151{
152 static unsigned version_printed;
153 int i,j;
154 unsigned char SA_prom[32];
155 int old_cfg1;
156 int old_cfg2;
157 int old_stat;
158 int old_dmaar;
159 int old_rear;
160 int retval;
161 DECLARE_MAC_BUF(mac);
162
163 if (!request_region(ioaddr, SEEQ8005_IO_EXTENT, "seeq8005"))
164 return -ENODEV;
165
166 if (net_debug>1)
167 printk("seeq8005: probing at 0x%x\n",ioaddr);
168
169 old_stat = inw(SEEQ_STATUS);
170 if (old_stat == 0xffff) {
171 retval = -ENODEV;
172 goto out;
173 }
174 if ( (old_stat & 0x1800) != 0x1800 ) {
175 if (net_debug>1) {
176 printk("seeq8005: reserved stat bits != 0x1800\n");
177 printk(" == 0x%04x\n",old_stat);
178 }
179 retval = -ENODEV;
180 goto out;
181 }
182
183 old_rear = inw(SEEQ_REA);
184 if (old_rear == 0xffff) {
185 outw(0,SEEQ_REA);
186 if (inw(SEEQ_REA) == 0xffff) {
187 retval = -ENODEV;
188 goto out;
189 }
190 } else if ((old_rear & 0xff00) != 0xff00) {
191 if (net_debug>1) {
192 printk("seeq8005: unused rear bits != 0xff00\n");
193 printk(" == 0x%04x\n",old_rear);
194 }
195 retval = -ENODEV;
196 goto out;
197 }
198
199 old_cfg2 = inw(SEEQ_CFG2);
200 old_cfg1 = inw(SEEQ_CFG1);
201 old_dmaar = inw(SEEQ_DMAAR);
202
203 if (net_debug>4) {
204 printk("seeq8005: stat = 0x%04x\n",old_stat);
205 printk("seeq8005: cfg1 = 0x%04x\n",old_cfg1);
206 printk("seeq8005: cfg2 = 0x%04x\n",old_cfg2);
207 printk("seeq8005: raer = 0x%04x\n",old_rear);
208 printk("seeq8005: dmaar= 0x%04x\n",old_dmaar);
209 }
210
211 outw( SEEQCMD_FIFO_WRITE | SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
212 outw( 0, SEEQ_DMAAR);
213 outw( SEEQCFG1_BUFFER_PROM, SEEQ_CFG1);
214
215
216 j=0;
217 for(i=0; i <32; i++) {
218 j+= SA_prom[i] = inw(SEEQ_BUFFER) & 0xff;
219 }
220
221#if 0
222
223 if ( (j&0xff) != 0 ) {
224 if (net_debug>1) {
225 printk("seeq8005: prom sum error\n");
226 }
227 outw( old_stat, SEEQ_STATUS);
228 outw( old_dmaar, SEEQ_DMAAR);
229 outw( old_cfg1, SEEQ_CFG1);
230 retval = -ENODEV;
231 goto out;
232 }
233#endif
234
235 outw( SEEQCFG2_RESET, SEEQ_CFG2);
236 udelay(5);
237 outw( SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
238
239 if (net_debug) {
240 printk("seeq8005: prom sum = 0x%08x\n",j);
241 for(j=0; j<32; j+=16) {
242 printk("seeq8005: prom %02x: ",j);
243 for(i=0;i<16;i++) {
244 printk("%02x ",SA_prom[j|i]);
245 }
246 printk(" ");
247 for(i=0;i<16;i++) {
248 if ((SA_prom[j|i]>31)&&(SA_prom[j|i]<127)) {
249 printk("%c", SA_prom[j|i]);
250 } else {
251 printk(" ");
252 }
253 }
254 printk("\n");
255 }
256 }
257
258#if 0
259
260
261
262
263
264 if (net_debug>1) {
265 printk("seeq8005: testing packet buffer ... ");
266 outw( SEEQCFG1_BUFFER_BUFFER, SEEQ_CFG1);
267 outw( SEEQCMD_FIFO_WRITE | SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
268 outw( 0 , SEEQ_DMAAR);
269 for(i=0;i<32768;i++) {
270 outw(0x5a5a, SEEQ_BUFFER);
271 }
272 j=jiffies+HZ;
273 while ( ((inw(SEEQ_STATUS) & SEEQSTAT_FIFO_EMPTY) != SEEQSTAT_FIFO_EMPTY) && time_before(jiffies, j) )
274 mb();
275 outw( 0 , SEEQ_DMAAR);
276 while ( ((inw(SEEQ_STATUS) & SEEQSTAT_WINDOW_INT) != SEEQSTAT_WINDOW_INT) && time_before(jiffies, j+HZ))
277 mb();
278 if ( (inw(SEEQ_STATUS) & SEEQSTAT_WINDOW_INT) == SEEQSTAT_WINDOW_INT)
279 outw( SEEQCMD_WINDOW_INT_ACK | (inw(SEEQ_STATUS)& SEEQCMD_INT_MASK), SEEQ_CMD);
280 outw( SEEQCMD_FIFO_READ | SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
281 j=0;
282 for(i=0;i<32768;i++) {
283 if (inw(SEEQ_BUFFER) != 0x5a5a)
284 j++;
285 }
286 if (j) {
287 printk("%i\n",j);
288 } else {
289 printk("ok.\n");
290 }
291 }
292#endif
293
294 if (net_debug && version_printed++ == 0)
295 printk(version);
296
297 printk("%s: %s found at %#3x, ", dev->name, "seeq8005", ioaddr);
298
299
300 dev->base_addr = ioaddr;
301 dev->irq = irq;
302
303
304 for (i = 0; i < 6; i++)
305 dev->dev_addr[i] = SA_prom[i+6];
306 printk("%s", print_mac(mac, dev->dev_addr));
307
308 if (dev->irq == 0xff)
309 ;
310 else if (dev->irq < 2) {
311 unsigned long cookie = probe_irq_on();
312
313 outw( SEEQCMD_RX_INT_EN | SEEQCMD_SET_RX_ON | SEEQCMD_SET_RX_OFF, SEEQ_CMD );
314
315 dev->irq = probe_irq_off(cookie);
316
317 if (net_debug >= 2)
318 printk(" autoirq is %d\n", dev->irq);
319 } else if (dev->irq == 2)
320
321
322
323 dev->irq = 9;
324
325#if 0
326 {
327 int irqval = request_irq(dev->irq, &seeq8005_interrupt, 0, "seeq8005", dev);
328 if (irqval) {
329 printk ("%s: unable to get IRQ %d (irqval=%d).\n", dev->name,
330 dev->irq, irqval);
331 retval = -EAGAIN;
332 goto out;
333 }
334 }
335#endif
336 dev->open = seeq8005_open;
337 dev->stop = seeq8005_close;
338 dev->hard_start_xmit = seeq8005_send_packet;
339 dev->tx_timeout = seeq8005_timeout;
340 dev->watchdog_timeo = HZ/20;
341 dev->set_multicast_list = set_multicast_list;
342 dev->flags &= ~IFF_MULTICAST;
343
344 return 0;
345out:
346 release_region(ioaddr, SEEQ8005_IO_EXTENT);
347 return retval;
348}
349
350
351
352
353
354
355
356
357
358static int seeq8005_open(struct net_device *dev)
359{
360 struct net_local *lp = netdev_priv(dev);
361
362 {
363 int irqval = request_irq(dev->irq, &seeq8005_interrupt, 0, "seeq8005", dev);
364 if (irqval) {
365 printk ("%s: unable to get IRQ %d (irqval=%d).\n", dev->name,
366 dev->irq, irqval);
367 return -EAGAIN;
368 }
369 }
370
371
372 seeq8005_init(dev, 1);
373
374 lp->open_time = jiffies;
375
376 netif_start_queue(dev);
377 return 0;
378}
379
380static void seeq8005_timeout(struct net_device *dev)
381{
382 int ioaddr = dev->base_addr;
383 printk(KERN_WARNING "%s: transmit timed out, %s?\n", dev->name,
384 tx_done(dev) ? "IRQ conflict" : "network cable problem");
385
386 seeq8005_init(dev, 1);
387 dev->trans_start = jiffies;
388 netif_wake_queue(dev);
389}
390
391static int seeq8005_send_packet(struct sk_buff *skb, struct net_device *dev)
392{
393 short length = skb->len;
394 unsigned char *buf;
395
396 if (length < ETH_ZLEN) {
397 if (skb_padto(skb, ETH_ZLEN))
398 return 0;
399 length = ETH_ZLEN;
400 }
401 buf = skb->data;
402
403
404 netif_stop_queue(dev);
405
406 hardware_send_packet(dev, buf, length);
407 dev->trans_start = jiffies;
408 dev->stats.tx_bytes += length;
409 dev_kfree_skb (skb);
410
411
412 return 0;
413}
414
415
416
417
418
419
420
421
422inline void wait_for_buffer(struct net_device * dev)
423{
424 int ioaddr = dev->base_addr;
425 unsigned long tmp;
426 int status;
427
428 tmp = jiffies + HZ;
429 while ( ( ((status=inw(SEEQ_STATUS)) & SEEQSTAT_WINDOW_INT) != SEEQSTAT_WINDOW_INT) && time_before(jiffies, tmp))
430 cpu_relax();
431
432 if ( (status & SEEQSTAT_WINDOW_INT) == SEEQSTAT_WINDOW_INT)
433 outw( SEEQCMD_WINDOW_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
434}
435
436
437
438static irqreturn_t seeq8005_interrupt(int irq, void *dev_id)
439{
440 struct net_device *dev = dev_id;
441 struct net_local *lp;
442 int ioaddr, status, boguscount = 0;
443 int handled = 0;
444
445 ioaddr = dev->base_addr;
446 lp = netdev_priv(dev);
447
448 status = inw(SEEQ_STATUS);
449 do {
450 if (net_debug >2) {
451 printk("%s: int, status=0x%04x\n",dev->name,status);
452 }
453
454 if (status & SEEQSTAT_WINDOW_INT) {
455 handled = 1;
456 outw( SEEQCMD_WINDOW_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
457 if (net_debug) {
458 printk("%s: window int!\n",dev->name);
459 }
460 }
461 if (status & SEEQSTAT_TX_INT) {
462 handled = 1;
463 outw( SEEQCMD_TX_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
464 dev->stats.tx_packets++;
465 netif_wake_queue(dev);
466 }
467 if (status & SEEQSTAT_RX_INT) {
468 handled = 1;
469
470 seeq8005_rx(dev);
471 }
472 status = inw(SEEQ_STATUS);
473 } while ( (++boguscount < 10) && (status & SEEQSTAT_ANY_INT)) ;
474
475 if(net_debug>2) {
476 printk("%s: eoi\n",dev->name);
477 }
478 return IRQ_RETVAL(handled);
479}
480
481
482static void seeq8005_rx(struct net_device *dev)
483{
484 struct net_local *lp = netdev_priv(dev);
485 int boguscount = 10;
486 int pkt_hdr;
487 int ioaddr = dev->base_addr;
488
489 do {
490 int next_packet;
491 int pkt_len;
492 int i;
493 int status;
494
495 status = inw(SEEQ_STATUS);
496 outw( lp->receive_ptr, SEEQ_DMAAR);
497 outw(SEEQCMD_FIFO_READ | SEEQCMD_RX_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
498 wait_for_buffer(dev);
499 next_packet = ntohs(inw(SEEQ_BUFFER));
500 pkt_hdr = inw(SEEQ_BUFFER);
501
502 if (net_debug>2) {
503 printk("%s: 0x%04x recv next=0x%04x, hdr=0x%04x\n",dev->name,lp->receive_ptr,next_packet,pkt_hdr);
504 }
505
506 if ((next_packet == 0) || ((pkt_hdr & SEEQPKTH_CHAIN)==0)) {
507 return;
508 }
509
510 if ((pkt_hdr & SEEQPKTS_DONE)==0)
511 break;
512
513 if (next_packet < lp->receive_ptr) {
514 pkt_len = (next_packet + 0x10000 - ((DEFAULT_TEA+1)<<8)) - lp->receive_ptr - 4;
515 } else {
516 pkt_len = next_packet - lp->receive_ptr - 4;
517 }
518
519 if (next_packet < ((DEFAULT_TEA+1)<<8)) {
520 printk("%s: recv packet ring corrupt, resetting board\n",dev->name);
521 seeq8005_init(dev,1);
522 return;
523 }
524
525 lp->receive_ptr = next_packet;
526
527 if (net_debug>2) {
528 printk("%s: recv len=0x%04x\n",dev->name,pkt_len);
529 }
530
531 if (pkt_hdr & SEEQPKTS_ANY_ERROR) {
532 dev->stats.rx_errors++;
533 if (pkt_hdr & SEEQPKTS_SHORT) dev->stats.rx_frame_errors++;
534 if (pkt_hdr & SEEQPKTS_DRIB) dev->stats.rx_frame_errors++;
535 if (pkt_hdr & SEEQPKTS_OVERSIZE) dev->stats.rx_over_errors++;
536 if (pkt_hdr & SEEQPKTS_CRC_ERR) dev->stats.rx_crc_errors++;
537
538 outw( SEEQCMD_FIFO_WRITE | SEEQCMD_DMA_INT_ACK | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
539 outw( (lp->receive_ptr & 0xff00)>>8, SEEQ_REA);
540 } else {
541
542 struct sk_buff *skb;
543 unsigned char *buf;
544
545 skb = dev_alloc_skb(pkt_len);
546 if (skb == NULL) {
547 printk("%s: Memory squeeze, dropping packet.\n", dev->name);
548 dev->stats.rx_dropped++;
549 break;
550 }
551 skb_reserve(skb, 2);
552 buf = skb_put(skb,pkt_len);
553
554 insw(SEEQ_BUFFER, buf, (pkt_len + 1) >> 1);
555
556 if (net_debug>2) {
557 char * p = buf;
558 printk("%s: recv ",dev->name);
559 for(i=0;i<14;i++) {
560 printk("%02x ",*(p++)&0xff);
561 }
562 printk("\n");
563 }
564
565 skb->protocol=eth_type_trans(skb,dev);
566 netif_rx(skb);
567 dev->last_rx = jiffies;
568 dev->stats.rx_packets++;
569 dev->stats.rx_bytes += pkt_len;
570 }
571 } while ((--boguscount) && (pkt_hdr & SEEQPKTH_CHAIN));
572
573
574
575
576 return;
577}
578
579
580static int seeq8005_close(struct net_device *dev)
581{
582 struct net_local *lp = netdev_priv(dev);
583 int ioaddr = dev->base_addr;
584
585 lp->open_time = 0;
586
587 netif_stop_queue(dev);
588
589
590 outw( SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
591
592 free_irq(dev->irq, dev);
593
594
595
596 return 0;
597
598}
599
600
601
602
603
604
605
606static void set_multicast_list(struct net_device *dev)
607{
608
609
610
611
612#if 0
613 int ioaddr = dev->base_addr;
614
615
616
617
618
619 if (num_addrs) {
620 outw( (inw(SEEQ_CFG1) & ~SEEQCFG1_MATCH_MASK)| SEEQCFG1_MATCH_ALL, SEEQ_CFG1);
621 dev->flags|=IFF_PROMISC;
622 } else {
623 outw( (inw(SEEQ_CFG1) & ~SEEQCFG1_MATCH_MASK)| SEEQCFG1_MATCH_BROAD, SEEQ_CFG1);
624 }
625#endif
626}
627
628void seeq8005_init(struct net_device *dev, int startp)
629{
630 struct net_local *lp = netdev_priv(dev);
631 int ioaddr = dev->base_addr;
632 int i;
633
634 outw(SEEQCFG2_RESET, SEEQ_CFG2);
635 udelay(5);
636
637 outw( SEEQCMD_FIFO_WRITE | SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
638 outw( 0, SEEQ_DMAAR);
639
640 outw( SEEQCFG1_BUFFER_MAC0, SEEQ_CFG1);
641
642 for(i=0;i<6;i++) {
643 outb(dev->dev_addr[i], SEEQ_BUFFER);
644 udelay(2);
645 }
646
647 outw( SEEQCFG1_BUFFER_TEA, SEEQ_CFG1);
648 outb( DEFAULT_TEA, SEEQ_BUFFER);
649
650 lp->receive_ptr = (DEFAULT_TEA+1)<<8;
651 outw( lp->receive_ptr, SEEQ_RPR);
652
653 outw( 0x00ff, SEEQ_REA);
654
655 if (net_debug>4) {
656 printk("%s: SA0 = ",dev->name);
657
658 outw( SEEQCMD_FIFO_READ | SEEQCMD_SET_ALL_OFF, SEEQ_CMD);
659 outw( 0, SEEQ_DMAAR);
660 outw( SEEQCFG1_BUFFER_MAC0, SEEQ_CFG1);
661
662 for(i=0;i<6;i++) {
663 printk("%02x ",inb(SEEQ_BUFFER));
664 }
665 printk("\n");
666 }
667
668 outw( SEEQCFG1_MAC0_EN | SEEQCFG1_MATCH_BROAD | SEEQCFG1_BUFFER_BUFFER, SEEQ_CFG1);
669 outw( SEEQCFG2_AUTO_REA | SEEQCFG2_CTRLO, SEEQ_CFG2);
670 outw( SEEQCMD_SET_RX_ON | SEEQCMD_TX_INT_EN | SEEQCMD_RX_INT_EN, SEEQ_CMD);
671
672 if (net_debug>4) {
673 int old_cfg1;
674 old_cfg1 = inw(SEEQ_CFG1);
675 printk("%s: stat = 0x%04x\n",dev->name,inw(SEEQ_STATUS));
676 printk("%s: cfg1 = 0x%04x\n",dev->name,old_cfg1);
677 printk("%s: cfg2 = 0x%04x\n",dev->name,inw(SEEQ_CFG2));
678 printk("%s: raer = 0x%04x\n",dev->name,inw(SEEQ_REA));
679 printk("%s: dmaar= 0x%04x\n",dev->name,inw(SEEQ_DMAAR));
680
681 }
682}
683
684
685static void hardware_send_packet(struct net_device * dev, char *buf, int length)
686{
687 int ioaddr = dev->base_addr;
688 int status = inw(SEEQ_STATUS);
689 int transmit_ptr = 0;
690 unsigned long tmp;
691
692 if (net_debug>4) {
693 printk("%s: send 0x%04x\n",dev->name,length);
694 }
695
696
697 outw( SEEQCMD_FIFO_WRITE | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
698 outw( transmit_ptr, SEEQ_DMAAR);
699
700
701 outw( htons(length + 4), SEEQ_BUFFER);
702 outw( SEEQPKTH_XMIT | SEEQPKTH_DATA_FOLLOWS | SEEQPKTH_XMIT_INT_EN, SEEQ_BUFFER );
703
704
705 outsw( SEEQ_BUFFER, buf, (length +1) >> 1);
706
707 outw( 0, SEEQ_BUFFER);
708 outw( 0, SEEQ_BUFFER);
709
710
711 outw( transmit_ptr, SEEQ_TPR);
712
713
714 tmp = jiffies;
715 while ( (((status=inw(SEEQ_STATUS)) & SEEQSTAT_FIFO_EMPTY) == 0) && time_before(jiffies, tmp + HZ))
716 mb();
717
718
719 outw( SEEQCMD_WINDOW_INT_ACK | SEEQCMD_SET_TX_ON | (status & SEEQCMD_INT_MASK), SEEQ_CMD);
720
721}
722
723
724#ifdef MODULE
725
726static struct net_device *dev_seeq;
727MODULE_LICENSE("GPL");
728module_param(io, int, 0);
729module_param(irq, int, 0);
730MODULE_PARM_DESC(io, "SEEQ 8005 I/O base address");
731MODULE_PARM_DESC(irq, "SEEQ 8005 IRQ number");
732
733int __init init_module(void)
734{
735 dev_seeq = seeq8005_probe(-1);
736 if (IS_ERR(dev_seeq))
737 return PTR_ERR(dev_seeq);
738 return 0;
739}
740
741void __exit cleanup_module(void)
742{
743 unregister_netdev(dev_seeq);
744 release_region(dev_seeq->base_addr, SEEQ8005_IO_EXTENT);
745 free_netdev(dev_seeq);
746}
747
748#endif
749
750
751
752
753
754
755
756
757
758