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