1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36static const char *version =
37"cops.c:v0.04 6/7/98 Jay Schulist <jschlst@samba.org>\n";
38
39
40
41
42
43
44
45
46
47
48
49
50
51#include <linux/module.h>
52#include <linux/kernel.h>
53#include <linux/types.h>
54#include <linux/fcntl.h>
55#include <linux/interrupt.h>
56#include <linux/ptrace.h>
57#include <linux/ioport.h>
58#include <linux/in.h>
59#include <linux/slab.h>
60#include <linux/string.h>
61#include <linux/errno.h>
62#include <linux/init.h>
63#include <linux/netdevice.h>
64#include <linux/etherdevice.h>
65#include <linux/skbuff.h>
66#include <linux/if_arp.h>
67#include <linux/if_ltalk.h>
68#include <linux/delay.h>
69#include <linux/atalk.h>
70#include <linux/spinlock.h>
71#include <linux/bitops.h>
72#include <linux/jiffies.h>
73
74#include <asm/system.h>
75#include <asm/io.h>
76#include <asm/dma.h>
77
78#include "cops.h"
79#include "cops_ltdrv.h"
80#include "cops_ffdrv.h"
81
82
83
84
85
86
87static const char *cardname = "cops";
88
89#ifdef CONFIG_COPS_DAYNA
90static int board_type = DAYNA;
91#else
92static int board_type = TANGENT;
93#endif
94
95static int io = 0x240;
96static int irq = 5;
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145static unsigned int ports[] = {
146 0x240, 0x340, 0x200, 0x210, 0x220, 0x230, 0x260,
147 0x2A0, 0x300, 0x310, 0x320, 0x330, 0x350, 0x360,
148 0
149};
150
151
152
153
154
155static int cops_irqlist[] = {
156 5, 4, 3, 0
157};
158
159static struct timer_list cops_timer;
160
161
162#ifndef COPS_DEBUG
163#define COPS_DEBUG 1
164#endif
165static unsigned int cops_debug = COPS_DEBUG;
166
167
168#define COPS_IO_EXTENT 8
169
170
171
172struct cops_local
173{
174 int board;
175 int nodeid;
176 unsigned char node_acquire;
177 struct atalk_addr node_addr;
178 spinlock_t lock;
179};
180
181
182static int cops_probe1 (struct net_device *dev, int ioaddr);
183static int cops_irq (int ioaddr, int board);
184
185static int cops_open (struct net_device *dev);
186static int cops_jumpstart (struct net_device *dev);
187static void cops_reset (struct net_device *dev, int sleep);
188static void cops_load (struct net_device *dev);
189static int cops_nodeid (struct net_device *dev, int nodeid);
190
191static irqreturn_t cops_interrupt (int irq, void *dev_id);
192static void cops_poll (unsigned long ltdev);
193static void cops_timeout(struct net_device *dev);
194static void cops_rx (struct net_device *dev);
195static netdev_tx_t cops_send_packet (struct sk_buff *skb,
196 struct net_device *dev);
197static void set_multicast_list (struct net_device *dev);
198static int cops_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
199static int cops_close (struct net_device *dev);
200
201static void cleanup_card(struct net_device *dev)
202{
203 if (dev->irq)
204 free_irq(dev->irq, dev);
205 release_region(dev->base_addr, COPS_IO_EXTENT);
206}
207
208
209
210
211
212
213
214struct net_device * __init cops_probe(int unit)
215{
216 struct net_device *dev;
217 unsigned *port;
218 int base_addr;
219 int err = 0;
220
221 dev = alloc_ltalkdev(sizeof(struct cops_local));
222 if (!dev)
223 return ERR_PTR(-ENOMEM);
224
225 if (unit >= 0) {
226 sprintf(dev->name, "lt%d", unit);
227 netdev_boot_setup_check(dev);
228 irq = dev->irq;
229 base_addr = dev->base_addr;
230 } else {
231 base_addr = dev->base_addr = io;
232 }
233
234 if (base_addr > 0x1ff) {
235 err = cops_probe1(dev, base_addr);
236 } else if (base_addr != 0) {
237 err = -ENXIO;
238 } else {
239
240
241
242
243
244 for (port = ports; *port && cops_probe1(dev, *port) < 0; port++)
245 ;
246 if (!*port)
247 err = -ENODEV;
248 }
249 if (err)
250 goto out;
251 err = register_netdev(dev);
252 if (err)
253 goto out1;
254 return dev;
255out1:
256 cleanup_card(dev);
257out:
258 free_netdev(dev);
259 return ERR_PTR(err);
260}
261
262static const struct net_device_ops cops_netdev_ops = {
263 .ndo_open = cops_open,
264 .ndo_stop = cops_close,
265 .ndo_start_xmit = cops_send_packet,
266 .ndo_tx_timeout = cops_timeout,
267 .ndo_do_ioctl = cops_ioctl,
268 .ndo_set_multicast_list = set_multicast_list,
269};
270
271
272
273
274
275
276static int __init cops_probe1(struct net_device *dev, int ioaddr)
277{
278 struct cops_local *lp;
279 static unsigned version_printed;
280 int board = board_type;
281 int retval;
282
283 if(cops_debug && version_printed++ == 0)
284 printk("%s", version);
285
286
287 if (!request_region(ioaddr, COPS_IO_EXTENT, dev->name))
288 return -EBUSY;
289
290
291
292
293
294
295
296
297 dev->irq = irq;
298 switch (dev->irq)
299 {
300 case 0:
301
302 dev->irq = cops_irq(ioaddr, board);
303 if (dev->irq)
304 break;
305
306 case 1:
307 retval = -EINVAL;
308 goto err_out;
309
310
311
312
313 case 2:
314 dev->irq = 9;
315 break;
316
317
318
319
320
321 case 0xff:
322 dev->irq = 0;
323 break;
324
325 default:
326 break;
327 }
328
329
330 if (dev->irq) {
331 retval = request_irq(dev->irq, &cops_interrupt, 0, dev->name, dev);
332 if (retval)
333 goto err_out;
334 }
335
336 dev->base_addr = ioaddr;
337
338 lp = netdev_priv(dev);
339 spin_lock_init(&lp->lock);
340
341
342 lp->board = board;
343
344 dev->netdev_ops = &cops_netdev_ops;
345 dev->watchdog_timeo = HZ * 2;
346
347
348
349 if(board==DAYNA)
350 printk("%s: %s at %#3x, using IRQ %d, in Dayna mode.\n",
351 dev->name, cardname, ioaddr, dev->irq);
352 if(board==TANGENT) {
353 if(dev->irq)
354 printk("%s: %s at %#3x, IRQ %d, in Tangent mode\n",
355 dev->name, cardname, ioaddr, dev->irq);
356 else
357 printk("%s: %s at %#3x, using polled IO, in Tangent mode.\n",
358 dev->name, cardname, ioaddr);
359
360 }
361 return 0;
362
363err_out:
364 release_region(ioaddr, COPS_IO_EXTENT);
365 return retval;
366}
367
368static int __init cops_irq (int ioaddr, int board)
369{
370
371
372
373
374
375
376 int irqaddr=0;
377 int i, x, status;
378
379 if(board==DAYNA)
380 {
381 outb(0, ioaddr+DAYNA_RESET);
382 inb(ioaddr+DAYNA_RESET);
383 mdelay(333);
384 }
385 if(board==TANGENT)
386 {
387 inb(ioaddr);
388 outb(0, ioaddr);
389 outb(0, ioaddr+TANG_RESET);
390 }
391
392 for(i=0; cops_irqlist[i] !=0; i++)
393 {
394 irqaddr = cops_irqlist[i];
395 for(x = 0xFFFF; x>0; x --)
396 {
397 if(board==DAYNA)
398 {
399 status = (inb(ioaddr+DAYNA_CARD_STATUS)&3);
400 if(status == 1)
401 return irqaddr;
402 }
403 if(board==TANGENT)
404 {
405 if((inb(ioaddr+TANG_CARD_STATUS)& TANG_TX_READY) !=0)
406 return irqaddr;
407 }
408 }
409 }
410 return 0;
411}
412
413
414
415
416
417static int cops_open(struct net_device *dev)
418{
419 struct cops_local *lp = netdev_priv(dev);
420
421 if(dev->irq==0)
422 {
423
424
425
426
427 if(lp->board==TANGENT)
428 {
429 init_timer(&cops_timer);
430 cops_timer.function = cops_poll;
431 cops_timer.data = (unsigned long)dev;
432 cops_timer.expires = jiffies + HZ/20;
433 add_timer(&cops_timer);
434 }
435 else
436 {
437 printk(KERN_WARNING "%s: No irq line set\n", dev->name);
438 return -EAGAIN;
439 }
440 }
441
442 cops_jumpstart(dev);
443
444 netif_start_queue(dev);
445 return 0;
446}
447
448
449
450
451static int cops_jumpstart(struct net_device *dev)
452{
453 struct cops_local *lp = netdev_priv(dev);
454
455
456
457
458
459 cops_reset(dev,1);
460 cops_load(dev);
461
462
463
464
465
466
467
468 if(lp->nodeid == 1)
469 cops_nodeid(dev,lp->node_acquire);
470
471 return 0;
472}
473
474static void tangent_wait_reset(int ioaddr)
475{
476 int timeout=0;
477
478 while(timeout++ < 5 && (inb(ioaddr+TANG_CARD_STATUS)&TANG_TX_READY)==0)
479 mdelay(1);
480}
481
482
483
484
485static void cops_reset(struct net_device *dev, int sleep)
486{
487 struct cops_local *lp = netdev_priv(dev);
488 int ioaddr=dev->base_addr;
489
490 if(lp->board==TANGENT)
491 {
492 inb(ioaddr);
493 outb(0,ioaddr);
494 outb(0, ioaddr+TANG_RESET);
495
496 tangent_wait_reset(ioaddr);
497 outb(0, ioaddr+TANG_CLEAR_INT);
498 }
499 if(lp->board==DAYNA)
500 {
501 outb(0, ioaddr+DAYNA_RESET);
502 inb(ioaddr+DAYNA_RESET);
503 if (sleep)
504 msleep(333);
505 else
506 mdelay(333);
507 }
508
509 netif_wake_queue(dev);
510}
511
512static void cops_load (struct net_device *dev)
513{
514 struct ifreq ifr;
515 struct ltfirmware *ltf= (struct ltfirmware *)&ifr.ifr_ifru;
516 struct cops_local *lp = netdev_priv(dev);
517 int ioaddr=dev->base_addr;
518 int length, i = 0;
519
520 strcpy(ifr.ifr_name,"lt0");
521
522
523#ifdef CONFIG_COPS_DAYNA
524 if(lp->board==DAYNA)
525 {
526 ltf->length=sizeof(ffdrv_code);
527 ltf->data=ffdrv_code;
528 }
529 else
530#endif
531#ifdef CONFIG_COPS_TANGENT
532 if(lp->board==TANGENT)
533 {
534 ltf->length=sizeof(ltdrv_code);
535 ltf->data=ltdrv_code;
536 }
537 else
538#endif
539 {
540 printk(KERN_INFO "%s; unsupported board type.\n", dev->name);
541 return;
542 }
543
544
545 if(lp->board==DAYNA && ltf->length!=5983)
546 {
547 printk(KERN_WARNING "%s: Firmware is not length of FFDRV.BIN.\n", dev->name);
548 return;
549 }
550 if(lp->board==TANGENT && ltf->length!=2501)
551 {
552 printk(KERN_WARNING "%s: Firmware is not length of DRVCODE.BIN.\n", dev->name);
553 return;
554 }
555
556 if(lp->board==DAYNA)
557 {
558
559
560
561
562 while(++i<65536)
563 {
564 if((inb(ioaddr+DAYNA_CARD_STATUS)&3)==1)
565 break;
566 }
567
568 if(i==65536)
569 return;
570 }
571
572
573
574
575 i=0;
576 length = ltf->length;
577 while(length--)
578 {
579 outb(ltf->data[i], ioaddr);
580 i++;
581 }
582
583 if(cops_debug > 1)
584 printk("%s: Uploaded firmware - %d bytes of %d bytes.\n",
585 dev->name, i, ltf->length);
586
587 if(lp->board==DAYNA)
588 outb(1, ioaddr+DAYNA_INT_CARD);
589 else
590 inb(ioaddr);
591
592 if(lp->board==TANGENT)
593 {
594 tangent_wait_reset(ioaddr);
595 inb(ioaddr);
596 }
597
598 return;
599}
600
601
602
603
604
605
606
607static int cops_nodeid (struct net_device *dev, int nodeid)
608{
609 struct cops_local *lp = netdev_priv(dev);
610 int ioaddr = dev->base_addr;
611
612 if(lp->board == DAYNA)
613 {
614
615 while((inb(ioaddr+DAYNA_CARD_STATUS)&DAYNA_TX_READY)==0)
616 {
617 outb(0, ioaddr+COPS_CLEAR_INT);
618 if((inb(ioaddr+DAYNA_CARD_STATUS)&0x03)==DAYNA_RX_REQUEST)
619 cops_rx(dev);
620 schedule();
621 }
622
623 outb(2, ioaddr);
624 outb(0, ioaddr);
625 outb(LAP_INIT, ioaddr);
626 outb(nodeid, ioaddr);
627 }
628
629 if(lp->board == TANGENT)
630 {
631
632 while(inb(ioaddr+TANG_CARD_STATUS)&TANG_RX_READY)
633 {
634 outb(0, ioaddr+COPS_CLEAR_INT);
635 cops_rx(dev);
636 schedule();
637 }
638
639
640 if(nodeid == 0)
641 nodeid = jiffies&0xFF;
642 outb(2, ioaddr);
643 outb(0, ioaddr);
644 outb(LAP_INIT, ioaddr);
645 outb(nodeid, ioaddr);
646 outb(0xFF, ioaddr);
647 }
648
649 lp->node_acquire=0;
650 while(lp->node_acquire==0)
651 {
652 outb(0, ioaddr+COPS_CLEAR_INT);
653
654 if(lp->board == DAYNA)
655 {
656 if((inb(ioaddr+DAYNA_CARD_STATUS)&0x03)==DAYNA_RX_REQUEST)
657 cops_rx(dev);
658 }
659 if(lp->board == TANGENT)
660 {
661 if(inb(ioaddr+TANG_CARD_STATUS)&TANG_RX_READY)
662 cops_rx(dev);
663 }
664 schedule();
665 }
666
667 if(cops_debug > 1)
668 printk(KERN_DEBUG "%s: Node ID %d has been acquired.\n",
669 dev->name, lp->node_acquire);
670
671 lp->nodeid=1;
672
673 return 0;
674}
675
676
677
678
679
680static void cops_poll(unsigned long ltdev)
681{
682 int ioaddr, status;
683 int boguscount = 0;
684
685 struct net_device *dev = (struct net_device *)ltdev;
686
687 del_timer(&cops_timer);
688
689 if(dev == NULL)
690 return;
691
692 ioaddr = dev->base_addr;
693 do {
694 status=inb(ioaddr+TANG_CARD_STATUS);
695 if(status & TANG_RX_READY)
696 cops_rx(dev);
697 if(status & TANG_TX_READY)
698 netif_wake_queue(dev);
699 status = inb(ioaddr+TANG_CARD_STATUS);
700 } while((++boguscount < 20) && (status&(TANG_RX_READY|TANG_TX_READY)));
701
702
703 cops_timer.expires = jiffies + HZ/20;
704 add_timer(&cops_timer);
705
706 return;
707}
708
709
710
711
712
713static irqreturn_t cops_interrupt(int irq, void *dev_id)
714{
715 struct net_device *dev = dev_id;
716 struct cops_local *lp;
717 int ioaddr, status;
718 int boguscount = 0;
719
720 ioaddr = dev->base_addr;
721 lp = netdev_priv(dev);
722
723 if(lp->board==DAYNA)
724 {
725 do {
726 outb(0, ioaddr + COPS_CLEAR_INT);
727 status=inb(ioaddr+DAYNA_CARD_STATUS);
728 if((status&0x03)==DAYNA_RX_REQUEST)
729 cops_rx(dev);
730 netif_wake_queue(dev);
731 } while(++boguscount < 20);
732 }
733 else
734 {
735 do {
736 status=inb(ioaddr+TANG_CARD_STATUS);
737 if(status & TANG_RX_READY)
738 cops_rx(dev);
739 if(status & TANG_TX_READY)
740 netif_wake_queue(dev);
741 status=inb(ioaddr+TANG_CARD_STATUS);
742 } while((++boguscount < 20) && (status&(TANG_RX_READY|TANG_TX_READY)));
743 }
744
745 return IRQ_HANDLED;
746}
747
748
749
750
751static void cops_rx(struct net_device *dev)
752{
753 int pkt_len = 0;
754 int rsp_type = 0;
755 struct sk_buff *skb = NULL;
756 struct cops_local *lp = netdev_priv(dev);
757 int ioaddr = dev->base_addr;
758 int boguscount = 0;
759 unsigned long flags;
760
761
762 spin_lock_irqsave(&lp->lock, flags);
763
764 if(lp->board==DAYNA)
765 {
766 outb(0, ioaddr);
767 outb(0, ioaddr);
768 outb(DATA_READ, ioaddr);
769
770
771 while(++boguscount<1000000)
772 {
773 barrier();
774 if((inb(ioaddr+DAYNA_CARD_STATUS)&0x03)==DAYNA_RX_READY)
775 break;
776 }
777
778 if(boguscount==1000000)
779 {
780 printk(KERN_WARNING "%s: DMA timed out.\n",dev->name);
781 spin_unlock_irqrestore(&lp->lock, flags);
782 return;
783 }
784 }
785
786
787 if(lp->board==DAYNA)
788 pkt_len = inb(ioaddr) & 0xFF;
789 else
790 pkt_len = inb(ioaddr) & 0x00FF;
791 pkt_len |= (inb(ioaddr) << 8);
792
793 rsp_type=inb(ioaddr);
794
795
796 skb = dev_alloc_skb(pkt_len);
797 if(skb == NULL)
798 {
799 printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n",
800 dev->name);
801 dev->stats.rx_dropped++;
802 while(pkt_len--)
803 inb(ioaddr);
804 spin_unlock_irqrestore(&lp->lock, flags);
805 return;
806 }
807 skb->dev = dev;
808 skb_put(skb, pkt_len);
809 skb->protocol = htons(ETH_P_LOCALTALK);
810
811 insb(ioaddr, skb->data, pkt_len);
812
813 if(lp->board==DAYNA)
814 outb(1, ioaddr+DAYNA_INT_CARD);
815
816 spin_unlock_irqrestore(&lp->lock, flags);
817
818
819 if(pkt_len < 0 || pkt_len > MAX_LLAP_SIZE)
820 {
821 printk(KERN_WARNING "%s: Bad packet length of %d bytes.\n",
822 dev->name, pkt_len);
823 dev->stats.tx_errors++;
824 dev_kfree_skb_any(skb);
825 return;
826 }
827
828
829 if(rsp_type == LAP_INIT_RSP)
830 {
831 lp->node_acquire = skb->data[0];
832 dev_kfree_skb_any(skb);
833 return;
834 }
835
836
837 if(rsp_type != LAP_RESPONSE)
838 {
839 printk(KERN_WARNING "%s: Bad packet type %d.\n", dev->name, rsp_type);
840 dev->stats.tx_errors++;
841 dev_kfree_skb_any(skb);
842 return;
843 }
844
845 skb_reset_mac_header(skb);
846 skb_pull(skb,3);
847 skb_reset_transport_header(skb);
848
849
850 dev->stats.rx_packets++;
851 dev->stats.rx_bytes += skb->len;
852
853
854 netif_rx(skb);
855}
856
857static void cops_timeout(struct net_device *dev)
858{
859 struct cops_local *lp = netdev_priv(dev);
860 int ioaddr = dev->base_addr;
861
862 dev->stats.tx_errors++;
863 if(lp->board==TANGENT)
864 {
865 if((inb(ioaddr+TANG_CARD_STATUS)&TANG_TX_READY)==0)
866 printk(KERN_WARNING "%s: No TX complete interrupt.\n", dev->name);
867 }
868 printk(KERN_WARNING "%s: Transmit timed out.\n", dev->name);
869 cops_jumpstart(dev);
870 dev->trans_start = jiffies;
871 netif_wake_queue(dev);
872}
873
874
875
876
877
878
879static netdev_tx_t cops_send_packet(struct sk_buff *skb,
880 struct net_device *dev)
881{
882 struct cops_local *lp = netdev_priv(dev);
883 int ioaddr = dev->base_addr;
884 unsigned long flags;
885
886
887
888
889
890 netif_stop_queue(dev);
891
892 spin_lock_irqsave(&lp->lock, flags);
893 if(lp->board == DAYNA)
894 while((inb(ioaddr+DAYNA_CARD_STATUS)&DAYNA_TX_READY)==0)
895 cpu_relax();
896 if(lp->board == TANGENT)
897 while((inb(ioaddr+TANG_CARD_STATUS)&TANG_TX_READY)==0)
898 cpu_relax();
899
900
901 outb(skb->len, ioaddr);
902 if(lp->board == DAYNA)
903 outb(skb->len >> 8, ioaddr);
904 else
905 outb((skb->len >> 8)&0x0FF, ioaddr);
906
907
908 outb(LAP_WRITE, ioaddr);
909
910 if(lp->board == DAYNA)
911 while((inb(ioaddr+DAYNA_CARD_STATUS)&DAYNA_TX_READY)==0);
912
913 outsb(ioaddr, skb->data, skb->len);
914
915 if(lp->board==DAYNA)
916 outb(1, ioaddr+DAYNA_INT_CARD);
917
918 spin_unlock_irqrestore(&lp->lock, flags);
919
920
921 dev->stats.tx_packets++;
922 dev->stats.tx_bytes += skb->len;
923 dev->trans_start = jiffies;
924 dev_kfree_skb (skb);
925 return NETDEV_TX_OK;
926}
927
928
929
930
931
932static void set_multicast_list(struct net_device *dev)
933{
934 if(cops_debug >= 3)
935 printk("%s: set_multicast_list executed\n", dev->name);
936}
937
938
939
940
941
942static int cops_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
943{
944 struct cops_local *lp = netdev_priv(dev);
945 struct sockaddr_at *sa = (struct sockaddr_at *)&ifr->ifr_addr;
946 struct atalk_addr *aa = (struct atalk_addr *)&lp->node_addr;
947
948 switch(cmd)
949 {
950 case SIOCSIFADDR:
951
952 cops_nodeid(dev, sa->sat_addr.s_node);
953 aa->s_net = sa->sat_addr.s_net;
954 aa->s_node = lp->node_acquire;
955
956
957 dev->broadcast[0] = 0xFF;
958
959
960 dev->dev_addr[0] = aa->s_node;
961 dev->addr_len = 1;
962 return 0;
963
964 case SIOCGIFADDR:
965 sa->sat_addr.s_net = aa->s_net;
966 sa->sat_addr.s_node = aa->s_node;
967 return 0;
968
969 default:
970 return -EOPNOTSUPP;
971 }
972}
973
974
975
976
977
978static int cops_close(struct net_device *dev)
979{
980 struct cops_local *lp = netdev_priv(dev);
981
982
983
984 if(lp->board==TANGENT && dev->irq==0)
985 del_timer(&cops_timer);
986
987 netif_stop_queue(dev);
988 return 0;
989}
990
991
992#ifdef MODULE
993static struct net_device *cops_dev;
994
995MODULE_LICENSE("GPL");
996module_param(io, int, 0);
997module_param(irq, int, 0);
998module_param(board_type, int, 0);
999
1000static int __init cops_module_init(void)
1001{
1002 if (io == 0)
1003 printk(KERN_WARNING "%s: You shouldn't autoprobe with insmod\n",
1004 cardname);
1005 cops_dev = cops_probe(-1);
1006 if (IS_ERR(cops_dev))
1007 return PTR_ERR(cops_dev);
1008 return 0;
1009}
1010
1011static void __exit cops_module_exit(void)
1012{
1013 unregister_netdev(cops_dev);
1014 cleanup_card(cops_dev);
1015 free_netdev(cops_dev);
1016}
1017module_init(cops_module_init);
1018module_exit(cops_module_exit);
1019#endif
1020