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