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;
158
159
160#ifndef COPS_DEBUG
161#define COPS_DEBUG 1
162#endif
163static unsigned int cops_debug = COPS_DEBUG;
164
165
166#define COPS_IO_EXTENT 8
167
168
169
170struct cops_local
171{
172 int board;
173 int nodeid;
174 unsigned char node_acquire;
175 struct atalk_addr node_addr;
176 spinlock_t lock;
177};
178
179
180static int cops_probe1 (struct net_device *dev, int ioaddr);
181static int cops_irq (int ioaddr, int board);
182
183static int cops_open (struct net_device *dev);
184static int cops_jumpstart (struct net_device *dev);
185static void cops_reset (struct net_device *dev, int sleep);
186static void cops_load (struct net_device *dev);
187static int cops_nodeid (struct net_device *dev, int nodeid);
188
189static irqreturn_t cops_interrupt (int irq, void *dev_id);
190static void cops_poll (unsigned long ltdev);
191static void cops_timeout(struct net_device *dev);
192static void cops_rx (struct net_device *dev);
193static netdev_tx_t cops_send_packet (struct sk_buff *skb,
194 struct net_device *dev);
195static void set_multicast_list (struct net_device *dev);
196static int cops_ioctl (struct net_device *dev, struct ifreq *rq, int cmd);
197static int cops_close (struct net_device *dev);
198
199static void cleanup_card(struct net_device *dev)
200{
201 if (dev->irq)
202 free_irq(dev->irq, dev);
203 release_region(dev->base_addr, COPS_IO_EXTENT);
204}
205
206
207
208
209
210
211
212struct net_device * __init cops_probe(int unit)
213{
214 struct net_device *dev;
215 unsigned *port;
216 int base_addr;
217 int err = 0;
218
219 dev = alloc_ltalkdev(sizeof(struct cops_local));
220 if (!dev)
221 return ERR_PTR(-ENOMEM);
222
223 if (unit >= 0) {
224 sprintf(dev->name, "lt%d", unit);
225 netdev_boot_setup_check(dev);
226 irq = dev->irq;
227 base_addr = dev->base_addr;
228 } else {
229 base_addr = dev->base_addr = io;
230 }
231
232 if (base_addr > 0x1ff) {
233 err = cops_probe1(dev, base_addr);
234 } else if (base_addr != 0) {
235 err = -ENXIO;
236 } else {
237
238
239
240
241
242 for (port = ports; *port && cops_probe1(dev, *port) < 0; port++)
243 ;
244 if (!*port)
245 err = -ENODEV;
246 }
247 if (err)
248 goto out;
249 err = register_netdev(dev);
250 if (err)
251 goto out1;
252 return dev;
253out1:
254 cleanup_card(dev);
255out:
256 free_netdev(dev);
257 return ERR_PTR(err);
258}
259
260static const struct net_device_ops cops_netdev_ops = {
261 .ndo_open = cops_open,
262 .ndo_stop = cops_close,
263 .ndo_start_xmit = cops_send_packet,
264 .ndo_tx_timeout = cops_timeout,
265 .ndo_do_ioctl = cops_ioctl,
266 .ndo_set_rx_mode = set_multicast_list,
267};
268
269
270
271
272
273
274static int __init cops_probe1(struct net_device *dev, int ioaddr)
275{
276 struct cops_local *lp;
277 static unsigned version_printed;
278 int board = board_type;
279 int retval;
280
281 if(cops_debug && version_printed++ == 0)
282 printk("%s", version);
283
284
285 if (!request_region(ioaddr, COPS_IO_EXTENT, dev->name))
286 return -EBUSY;
287
288
289
290
291
292
293
294
295 dev->irq = irq;
296 switch (dev->irq)
297 {
298 case 0:
299
300 dev->irq = cops_irq(ioaddr, board);
301 if (dev->irq)
302 break;
303
304 case 1:
305 retval = -EINVAL;
306 goto err_out;
307
308
309
310
311 case 2:
312 dev->irq = 9;
313 break;
314
315
316
317
318
319 case 0xff:
320 dev->irq = 0;
321 break;
322
323 default:
324 break;
325 }
326
327
328 if (dev->irq) {
329 retval = request_irq(dev->irq, cops_interrupt, 0, dev->name, dev);
330 if (retval)
331 goto err_out;
332 }
333
334 dev->base_addr = ioaddr;
335
336 lp = netdev_priv(dev);
337 spin_lock_init(&lp->lock);
338
339
340 lp->board = board;
341
342 dev->netdev_ops = &cops_netdev_ops;
343 dev->watchdog_timeo = HZ * 2;
344
345
346
347 if(board==DAYNA)
348 printk("%s: %s at %#3x, using IRQ %d, in Dayna mode.\n",
349 dev->name, cardname, ioaddr, dev->irq);
350 if(board==TANGENT) {
351 if(dev->irq)
352 printk("%s: %s at %#3x, IRQ %d, in Tangent mode\n",
353 dev->name, cardname, ioaddr, dev->irq);
354 else
355 printk("%s: %s at %#3x, using polled IO, in Tangent mode.\n",
356 dev->name, cardname, ioaddr);
357
358 }
359 return 0;
360
361err_out:
362 release_region(ioaddr, COPS_IO_EXTENT);
363 return retval;
364}
365
366static int __init cops_irq (int ioaddr, int board)
367{
368
369
370
371
372
373
374 int irqaddr=0;
375 int i, x, status;
376
377 if(board==DAYNA)
378 {
379 outb(0, ioaddr+DAYNA_RESET);
380 inb(ioaddr+DAYNA_RESET);
381 mdelay(333);
382 }
383 if(board==TANGENT)
384 {
385 inb(ioaddr);
386 outb(0, ioaddr);
387 outb(0, ioaddr+TANG_RESET);
388 }
389
390 for(i=0; cops_irqlist[i] !=0; i++)
391 {
392 irqaddr = cops_irqlist[i];
393 for(x = 0xFFFF; x>0; x --)
394 {
395 if(board==DAYNA)
396 {
397 status = (inb(ioaddr+DAYNA_CARD_STATUS)&3);
398 if(status == 1)
399 return irqaddr;
400 }
401 if(board==TANGENT)
402 {
403 if((inb(ioaddr+TANG_CARD_STATUS)& TANG_TX_READY) !=0)
404 return irqaddr;
405 }
406 }
407 }
408 return 0;
409}
410
411
412
413
414
415static int cops_open(struct net_device *dev)
416{
417 struct cops_local *lp = netdev_priv(dev);
418
419 if(dev->irq==0)
420 {
421
422
423
424
425 if(lp->board==TANGENT)
426 {
427 init_timer(&cops_timer);
428 cops_timer.function = cops_poll;
429 cops_timer.data = (unsigned long)dev;
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(unsigned long ltdev)
677{
678 int ioaddr, status;
679 int boguscount = 0;
680
681 struct net_device *dev = (struct net_device *)ltdev;
682
683 del_timer(&cops_timer);
684
685 if(dev == NULL)
686 return;
687
688 ioaddr = dev->base_addr;
689 do {
690 status=inb(ioaddr+TANG_CARD_STATUS);
691 if(status & TANG_RX_READY)
692 cops_rx(dev);
693 if(status & TANG_TX_READY)
694 netif_wake_queue(dev);
695 status = inb(ioaddr+TANG_CARD_STATUS);
696 } while((++boguscount < 20) && (status&(TANG_RX_READY|TANG_TX_READY)));
697
698
699 cops_timer.expires = jiffies + HZ/20;
700 add_timer(&cops_timer);
701}
702
703
704
705
706
707static irqreturn_t cops_interrupt(int irq, void *dev_id)
708{
709 struct net_device *dev = dev_id;
710 struct cops_local *lp;
711 int ioaddr, status;
712 int boguscount = 0;
713
714 ioaddr = dev->base_addr;
715 lp = netdev_priv(dev);
716
717 if(lp->board==DAYNA)
718 {
719 do {
720 outb(0, ioaddr + COPS_CLEAR_INT);
721 status=inb(ioaddr+DAYNA_CARD_STATUS);
722 if((status&0x03)==DAYNA_RX_REQUEST)
723 cops_rx(dev);
724 netif_wake_queue(dev);
725 } while(++boguscount < 20);
726 }
727 else
728 {
729 do {
730 status=inb(ioaddr+TANG_CARD_STATUS);
731 if(status & TANG_RX_READY)
732 cops_rx(dev);
733 if(status & TANG_TX_READY)
734 netif_wake_queue(dev);
735 status=inb(ioaddr+TANG_CARD_STATUS);
736 } while((++boguscount < 20) && (status&(TANG_RX_READY|TANG_TX_READY)));
737 }
738
739 return IRQ_HANDLED;
740}
741
742
743
744
745static void cops_rx(struct net_device *dev)
746{
747 int pkt_len = 0;
748 int rsp_type = 0;
749 struct sk_buff *skb = NULL;
750 struct cops_local *lp = netdev_priv(dev);
751 int ioaddr = dev->base_addr;
752 int boguscount = 0;
753 unsigned long flags;
754
755
756 spin_lock_irqsave(&lp->lock, flags);
757
758 if(lp->board==DAYNA)
759 {
760 outb(0, ioaddr);
761 outb(0, ioaddr);
762 outb(DATA_READ, ioaddr);
763
764
765 while(++boguscount<1000000)
766 {
767 barrier();
768 if((inb(ioaddr+DAYNA_CARD_STATUS)&0x03)==DAYNA_RX_READY)
769 break;
770 }
771
772 if(boguscount==1000000)
773 {
774 printk(KERN_WARNING "%s: DMA timed out.\n",dev->name);
775 spin_unlock_irqrestore(&lp->lock, flags);
776 return;
777 }
778 }
779
780
781 if(lp->board==DAYNA)
782 pkt_len = inb(ioaddr) & 0xFF;
783 else
784 pkt_len = inb(ioaddr) & 0x00FF;
785 pkt_len |= (inb(ioaddr) << 8);
786
787 rsp_type=inb(ioaddr);
788
789
790 skb = dev_alloc_skb(pkt_len);
791 if(skb == NULL)
792 {
793 printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n",
794 dev->name);
795 dev->stats.rx_dropped++;
796 while(pkt_len--)
797 inb(ioaddr);
798 spin_unlock_irqrestore(&lp->lock, flags);
799 return;
800 }
801 skb->dev = dev;
802 skb_put(skb, pkt_len);
803 skb->protocol = htons(ETH_P_LOCALTALK);
804
805 insb(ioaddr, skb->data, pkt_len);
806
807 if(lp->board==DAYNA)
808 outb(1, ioaddr+DAYNA_INT_CARD);
809
810 spin_unlock_irqrestore(&lp->lock, flags);
811
812
813 if(pkt_len < 0 || pkt_len > MAX_LLAP_SIZE)
814 {
815 printk(KERN_WARNING "%s: Bad packet length of %d bytes.\n",
816 dev->name, pkt_len);
817 dev->stats.tx_errors++;
818 dev_kfree_skb_any(skb);
819 return;
820 }
821
822
823 if(rsp_type == LAP_INIT_RSP)
824 {
825 lp->node_acquire = skb->data[0];
826 dev_kfree_skb_any(skb);
827 return;
828 }
829
830
831 if(rsp_type != LAP_RESPONSE)
832 {
833 printk(KERN_WARNING "%s: Bad packet type %d.\n", dev->name, rsp_type);
834 dev->stats.tx_errors++;
835 dev_kfree_skb_any(skb);
836 return;
837 }
838
839 skb_reset_mac_header(skb);
840 skb_pull(skb,3);
841 skb_reset_transport_header(skb);
842
843
844 dev->stats.rx_packets++;
845 dev->stats.rx_bytes += skb->len;
846
847
848 netif_rx(skb);
849}
850
851static void cops_timeout(struct net_device *dev)
852{
853 struct cops_local *lp = netdev_priv(dev);
854 int ioaddr = dev->base_addr;
855
856 dev->stats.tx_errors++;
857 if(lp->board==TANGENT)
858 {
859 if((inb(ioaddr+TANG_CARD_STATUS)&TANG_TX_READY)==0)
860 printk(KERN_WARNING "%s: No TX complete interrupt.\n", dev->name);
861 }
862 printk(KERN_WARNING "%s: Transmit timed out.\n", dev->name);
863 cops_jumpstart(dev);
864 netif_trans_update(dev);
865 netif_wake_queue(dev);
866}
867
868
869
870
871
872
873static netdev_tx_t cops_send_packet(struct sk_buff *skb,
874 struct net_device *dev)
875{
876 struct cops_local *lp = netdev_priv(dev);
877 int ioaddr = dev->base_addr;
878 unsigned long flags;
879
880
881
882
883
884 netif_stop_queue(dev);
885
886 spin_lock_irqsave(&lp->lock, flags);
887 if(lp->board == DAYNA)
888 while((inb(ioaddr+DAYNA_CARD_STATUS)&DAYNA_TX_READY)==0)
889 cpu_relax();
890 if(lp->board == TANGENT)
891 while((inb(ioaddr+TANG_CARD_STATUS)&TANG_TX_READY)==0)
892 cpu_relax();
893
894
895 outb(skb->len, ioaddr);
896 if(lp->board == DAYNA)
897 outb(skb->len >> 8, ioaddr);
898 else
899 outb((skb->len >> 8)&0x0FF, ioaddr);
900
901
902 outb(LAP_WRITE, ioaddr);
903
904 if(lp->board == DAYNA)
905 while((inb(ioaddr+DAYNA_CARD_STATUS)&DAYNA_TX_READY)==0);
906
907 outsb(ioaddr, skb->data, skb->len);
908
909 if(lp->board==DAYNA)
910 outb(1, ioaddr+DAYNA_INT_CARD);
911
912 spin_unlock_irqrestore(&lp->lock, flags);
913
914
915 dev->stats.tx_packets++;
916 dev->stats.tx_bytes += skb->len;
917 dev_kfree_skb (skb);
918 return NETDEV_TX_OK;
919}
920
921
922
923
924
925static void set_multicast_list(struct net_device *dev)
926{
927 if(cops_debug >= 3)
928 printk("%s: set_multicast_list executed\n", dev->name);
929}
930
931
932
933
934
935static int cops_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
936{
937 struct cops_local *lp = netdev_priv(dev);
938 struct sockaddr_at *sa = (struct sockaddr_at *)&ifr->ifr_addr;
939 struct atalk_addr *aa = &lp->node_addr;
940
941 switch(cmd)
942 {
943 case SIOCSIFADDR:
944
945 cops_nodeid(dev, sa->sat_addr.s_node);
946 aa->s_net = sa->sat_addr.s_net;
947 aa->s_node = lp->node_acquire;
948
949
950 dev->broadcast[0] = 0xFF;
951
952
953 dev->dev_addr[0] = aa->s_node;
954 dev->addr_len = 1;
955 return 0;
956
957 case SIOCGIFADDR:
958 sa->sat_addr.s_net = aa->s_net;
959 sa->sat_addr.s_node = aa->s_node;
960 return 0;
961
962 default:
963 return -EOPNOTSUPP;
964 }
965}
966
967
968
969
970
971static int cops_close(struct net_device *dev)
972{
973 struct cops_local *lp = netdev_priv(dev);
974
975
976
977 if(lp->board==TANGENT && dev->irq==0)
978 del_timer(&cops_timer);
979
980 netif_stop_queue(dev);
981 return 0;
982}
983
984
985#ifdef MODULE
986static struct net_device *cops_dev;
987
988MODULE_LICENSE("GPL");
989module_param(io, int, 0);
990module_param(irq, int, 0);
991module_param(board_type, int, 0);
992
993static int __init cops_module_init(void)
994{
995 if (io == 0)
996 printk(KERN_WARNING "%s: You shouldn't autoprobe with insmod\n",
997 cardname);
998 cops_dev = cops_probe(-1);
999 return PTR_ERR_OR_ZERO(cops_dev);
1000}
1001
1002static void __exit cops_module_exit(void)
1003{
1004 unregister_netdev(cops_dev);
1005 cleanup_card(cops_dev);
1006 free_netdev(cops_dev);
1007}
1008module_init(cops_module_init);
1009module_exit(cops_module_exit);
1010#endif
1011