This source file includes following definitions.
- DisableInterrupts
- RestoreInterrupts
- StuffData
- UnStuffData
- strip_changedmtu
- strip_unlock
- ResetRadio
- strip_write_some_more
- strip_stuff
- strip_send
- strip_xmit
- strip_IdleTask
- strip_receive_room
- strip_bump
- RecvErr
- RecvErr_Message
- process_packet
- strip_receive_buf
- strip_header
- strip_rebuild_header
- strip_set_dev_mac_address
- strip_get_stats
- strip_open_low
- strip_close_low
- strip_dev_init
- strip_free
- strip_alloc
- strip_open
- strip_close
- strip_ioctl
- strip_init_ctrl_dev
- init_module
- cleanup_module
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 #include <linux/config.h>
36 #ifdef MODULE
37 #include <linux/module.h>
38 #include <linux/version.h>
39 #endif
40
41 #include <asm/system.h>
42 #include <asm/segment.h>
43 #include <asm/bitops.h>
44 #include <linux/string.h>
45 #include <linux/mm.h>
46 #include <linux/interrupt.h>
47 #include <linux/in.h>
48 #include <linux/tty.h>
49 #include <linux/errno.h>
50 #include <linux/netdevice.h>
51 #include <linux/etherdevice.h>
52 #include <linux/skbuff.h>
53 #include <linux/if_arp.h>
54 #include <linux/if_strip.h>
55 #include <net/arp.h>
56 #ifdef CONFIG_INET
57 #include <linux/ip.h>
58 #include <linux/tcp.h>
59 #endif
60
61 #ifdef MODULE
62 #define STRIP_VERSION "0.9.1-STUART.CHESHIRE-MODULAR"
63 #else
64 #define STRIP_VERSION "0.9.1-STUART.CHESHIRE"
65 #endif
66
67 #define STRIP_MTU 1024
68 #define STRIP_MAGIC 0x5303
69
70
71
72
73
74 enum
75 {
76 STR_INUSE = 0,
77 STR_ESCAPE,
78 STR_ERROR
79 }
80 STRIP_FLAGS;
81
82 struct strip
83 {
84 int magic;
85
86
87
88
89
90
91
92
93 unsigned char *rx_buff;
94 unsigned char *sx_buff;
95 int sx_count;
96 unsigned char *tx_buff;
97 unsigned char *tx_head;
98 int tx_left;
99
100
101
102
103
104 unsigned long rx_packets;
105 unsigned long tx_packets;
106 unsigned long rx_errors;
107 unsigned long tx_errors;
108 unsigned long rx_dropped;
109 unsigned long tx_dropped;
110 unsigned long rx_over_errors;
111
112
113
114
115
116 struct strip *next;
117 struct strip **referrer;
118 unsigned char flags;
119 int mtu;
120 int buffsize;
121 long watchdog_doprobe;
122 long watchdog_doreset;
123 struct timer_list idle_timer;
124
125 struct tty_struct *tty;
126 char if_name[8];
127 struct device dev;
128 };
129
130
131
132 typedef unsigned long InterruptStatus;
133
134 extern __inline__ InterruptStatus DisableInterrupts(void)
135 {
136 InterruptStatus x;
137 save_flags(x);
138 cli();
139 return(x);
140 }
141
142 extern __inline__ void RestoreInterrupts(InterruptStatus x)
143 {
144 restore_flags(x);
145 }
146
147
148
149
150 typedef struct {
151 __u8 c[32];
152 } RadioName;
153
154 typedef struct {
155 __u8 c[ 4];
156 } MetricomKey;
157
158 typedef union {
159 __u8 b[ 4];
160 __u32 l;
161 } IPaddr;
162
163 static const MetricomKey ProtocolKey =
164 {
165 {
166 "SIP0"
167 }
168 };
169
170 enum
171 {
172 FALSE = 0,
173 TRUE = 1
174 };
175
176 #define LONG_TIME 0x7FFFFFFF
177
178 typedef struct
179 {
180 RadioName name;
181 MetricomKey key;
182 } STRIP_Header;
183
184 typedef struct
185 {
186 STRIP_Header h;
187 __u8 data[4];
188 } STRIP_Packet;
189
190
191
192
193
194
195 #define STRIP_ENCAP_SIZE(X) (sizeof(STRIP_Header) + (X)*65L/64L + 2)
196
197
198
199
200
201
202 static struct strip *struct_strip_list = NULL;
203
204
205
206
207
208
209
210
211
212
213
214
215 typedef enum
216 {
217 Stuff_Diff = 0x00,
218 Stuff_DiffZero = 0x40,
219 Stuff_Same = 0x80,
220 Stuff_Zero = 0xC0,
221 Stuff_NoCode = 0xFF,
222
223 Stuff_CodeMask = 0xC0,
224 Stuff_CountMask = 0x3F,
225 Stuff_MaxCount = 0x3F,
226 Stuff_Magic = 0x0D
227 } StuffingCode;
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242 #define StuffData_FinishBlock(X) \
243 (*code_ptr = (X) ^ Stuff_Magic, code = Stuff_NoCode)
244
245 static __u8 *StuffData(__u8 *src, __u32 length, __u8 *dst, __u8 **code_ptr_ptr)
246 {
247 __u8 *end = src + length;
248 __u8 *code_ptr = *code_ptr_ptr;
249 __u8 code = Stuff_NoCode, count = 0;
250
251 if (!length)
252 return(dst);
253
254 if (code_ptr)
255 {
256
257
258
259 code = (*code_ptr ^ Stuff_Magic) & Stuff_CodeMask;
260 count = (*code_ptr ^ Stuff_Magic) & Stuff_CountMask;
261 }
262
263 while (src < end)
264 {
265 switch (code)
266 {
267
268 case Stuff_NoCode:
269
270 code_ptr = dst++;
271 count = 0;
272
273 if (*src == 0)
274 {
275 code = Stuff_Zero;
276 src++;
277 }
278 else
279 {
280 code = Stuff_Same;
281 *dst++ = *src++ ^ Stuff_Magic;
282 }
283
284
285
286 break;
287
288
289 case Stuff_Zero:
290
291 if (*src == 0)
292 {
293 count++;
294 src++;
295 }
296 else
297 {
298 StuffData_FinishBlock(Stuff_Zero + count);
299 }
300 break;
301
302
303 case Stuff_Same:
304
305 if ((*src ^ Stuff_Magic) == code_ptr[1])
306 {
307 count++;
308 src++;
309 break;
310 }
311
312
313
314 if (count)
315 {
316 StuffData_FinishBlock(Stuff_Same + count);
317 break;
318 }
319
320
321 code = Stuff_Diff;
322
323
324 case Stuff_Diff:
325
326
327 if (*src == 0)
328 {
329 StuffData_FinishBlock(Stuff_DiffZero + count);
330 }
331
332
333 else if ((*src ^ Stuff_Magic)==dst[-1] && dst[-1]==dst[-2])
334 {
335
336 code += count-2;
337
338 if (code == Stuff_Diff + 0)
339 {
340 code = Stuff_Same + 0;
341 }
342 StuffData_FinishBlock(code);
343 code_ptr = dst-2;
344
345 count = 2;
346 code = Stuff_Same;
347 }
348
349 else
350 {
351 *dst++ = *src ^ Stuff_Magic;
352 count++;
353 }
354 src++;
355 break;
356 }
357 if (count == Stuff_MaxCount)
358 {
359 StuffData_FinishBlock(code + count);
360 }
361 }
362 if (code == Stuff_NoCode)
363 {
364 *code_ptr_ptr = NULL;
365 }
366 else
367 {
368 *code_ptr_ptr = code_ptr;
369 StuffData_FinishBlock(code + count);
370 }
371 return(dst);
372 }
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392 static __u8 *UnStuffData(__u8 *src, __u8 *end, __u8 *dst, __u32 dst_length)
393 {
394 __u8 *dst_end = dst + dst_length;
395
396 if (!src || !end || !dst || !dst_length)
397 return(NULL);
398 while (src < end && dst < dst_end)
399 {
400 int count = (*src ^ Stuff_Magic) & Stuff_CountMask;
401 switch ((*src ^ Stuff_Magic) & Stuff_CodeMask)
402 {
403 case Stuff_Diff:
404 if (src+1+count >= end)
405 return(NULL);
406 do
407 {
408 *dst++ = *++src ^ Stuff_Magic;
409 }
410 while(--count >= 0 && dst < dst_end);
411 if (count < 0)
412 src += 1;
413 else
414 {
415 if (count == 0)
416 *src = Stuff_Same ^ Stuff_Magic;
417 else
418 *src = (Stuff_Diff + count) ^ Stuff_Magic;
419 }
420 break;
421 case Stuff_DiffZero:
422 if (src+1+count >= end)
423 return(NULL);
424 do
425 {
426 *dst++ = *++src ^ Stuff_Magic;
427 }
428 while(--count >= 0 && dst < dst_end);
429 if (count < 0)
430 *src = Stuff_Zero ^ Stuff_Magic;
431 else
432 *src = (Stuff_DiffZero + count) ^ Stuff_Magic;
433 break;
434 case Stuff_Same:
435 if (src+1 >= end)
436 return(NULL);
437 do
438 {
439 *dst++ = src[1] ^ Stuff_Magic;
440 }
441 while(--count >= 0 && dst < dst_end);
442 if (count < 0)
443 src += 2;
444 else
445 *src = (Stuff_Same + count) ^ Stuff_Magic;
446 break;
447 case Stuff_Zero:
448 do
449 {
450 *dst++ = 0;
451 }
452 while(--count >= 0 && dst < dst_end);
453 if (count < 0)
454 src += 1;
455 else
456 *src = (Stuff_Zero + count) ^ Stuff_Magic;
457 break;
458 }
459 }
460 if (dst < dst_end)
461 return(NULL);
462 else
463 return(src);
464 }
465
466
467
468
469
470
471
472
473
474 static void strip_changedmtu(struct strip *strip_info)
475 {
476 struct device *dev = &strip_info->dev;
477 unsigned char *tbuff, *rbuff, *sbuff, *otbuff, *orbuff, *osbuff;
478 int len;
479 InterruptStatus intstat;
480
481 len = STRIP_ENCAP_SIZE(dev->mtu);
482 if (len < STRIP_ENCAP_SIZE(576))
483 len = STRIP_ENCAP_SIZE(576);
484
485 tbuff = (unsigned char *) kmalloc (len + 4, GFP_ATOMIC);
486 rbuff = (unsigned char *) kmalloc (len + 4, GFP_ATOMIC);
487 sbuff = (unsigned char *) kmalloc (len + 4, GFP_ATOMIC);
488 if (!tbuff || !rbuff || !sbuff)
489 {
490 printk("%s: unable to grow strip buffers, MTU change cancelled.\n",
491 strip_info->dev.name);
492 dev->mtu = strip_info->mtu;
493 if (tbuff)
494 kfree(tbuff);
495 if (rbuff)
496 kfree(rbuff);
497 if (sbuff)
498 kfree(sbuff);
499 return;
500 }
501
502 intstat = DisableInterrupts();
503 otbuff = strip_info->tx_buff; strip_info->tx_buff = tbuff;
504 orbuff = strip_info->rx_buff; strip_info->rx_buff = rbuff;
505 osbuff = strip_info->sx_buff; strip_info->sx_buff = sbuff;
506 if (strip_info->tx_left)
507 {
508 if (strip_info->tx_left <= len)
509 memcpy(strip_info->tx_buff, strip_info->tx_head, strip_info->tx_left);
510 else
511 {
512 strip_info->tx_left = 0;
513 strip_info->tx_dropped++;
514 }
515 }
516 strip_info->tx_head = strip_info->tx_buff;
517
518 if (strip_info->sx_count)
519 {
520 if (strip_info->sx_count <= len)
521 memcpy(strip_info->sx_buff, osbuff, strip_info->sx_count);
522 else
523 {
524 strip_info->sx_count = 0;
525 strip_info->rx_over_errors++;
526 set_bit(STR_ERROR, &strip_info->flags);
527 }
528 }
529
530 strip_info->mtu = STRIP_ENCAP_SIZE(dev->mtu);
531 strip_info->buffsize = len;
532
533 RestoreInterrupts(intstat);
534
535 if (otbuff != NULL)
536 kfree(otbuff);
537 if (orbuff != NULL)
538 kfree(orbuff);
539 if (osbuff != NULL)
540 kfree(osbuff);
541 }
542
543 static void strip_unlock(struct strip *strip_info)
544 {
545 strip_info->idle_timer.expires = jiffies + 2 * HZ;
546 add_timer(&strip_info->idle_timer);
547 if (!clear_bit(0, (void *)&strip_info->dev.tbusy))
548 printk("%s: trying to unlock already unlocked device!\n",
549 strip_info->dev.name);
550 }
551
552
553
554
555 static void ResetRadio(struct strip *strip_info)
556 {
557 static const char InitString[] = "ate0dt**starmode\r**";
558 strip_info->watchdog_doprobe = jiffies + 10 * HZ;
559 strip_info->watchdog_doreset = jiffies + 1 * HZ;
560 strip_info->tty->driver.write(strip_info->tty, 0,
561 (char *)InitString, sizeof(InitString)-1);
562 }
563
564
565
566
567
568
569 static void strip_write_some_more(struct tty_struct *tty)
570 {
571 InterruptStatus intstat;
572 int num_written;
573 struct strip *strip_info = (struct strip *) tty->disc_data;
574
575
576 if (!strip_info || strip_info->magic != STRIP_MAGIC || !strip_info->dev.start)
577 return;
578
579 if (strip_info->tx_left > 0)
580 {
581
582
583
584
585 intstat = DisableInterrupts();
586 num_written = tty->driver.write(tty, 0, strip_info->tx_head, strip_info->tx_left);
587 strip_info->tx_left -= num_written;
588 strip_info->tx_head += num_written;
589 RestoreInterrupts(intstat);
590 }
591 else
592 {
593 tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
594 strip_unlock(strip_info);
595 mark_bh(NET_BH);
596 }
597 }
598
599
600
601
602 static unsigned char *strip_stuff(unsigned char *ptr, struct strip *strip_info, struct sk_buff *skb)
603 {
604 __u8 *start;
605 __u8 *stuffstate = NULL;
606 unsigned char *icp = skb->data;
607 int len = skb->len;
608 MetricomAddress haddr;
609
610 if (len > strip_info->mtu) {
611 printk("%s: Dropping oversized transmit packet!\n", strip_info->dev.name);
612 strip_info->tx_dropped++;
613 return(NULL);
614 }
615
616 if (!arp_query(haddr.c, skb->raddr, &strip_info->dev)) {
617 IPaddr a,b,c;
618 a.l = skb->raddr;
619 b.l = skb->saddr;
620 c.l = skb->daddr;
621 printk("%s: Unknown dest %d.%d.%d.%d s=%d.%d.%d.%d d=%d.%d.%d.%d\n",
622 strip_info->dev.name,
623 a.b[0], a.b[1], a.b[2], a.b[3],
624 b.b[0], b.b[1], b.b[2], b.b[3],
625 c.b[0], c.b[1], c.b[2], c.b[3]);
626 strip_info->tx_dropped++;
627 return(NULL);
628 }
629
630 *ptr++ = '*';
631 ptr[3] = '0' + haddr.s[0] % 10; haddr.s[0] /= 10;
632 ptr[2] = '0' + haddr.s[0] % 10; haddr.s[0] /= 10;
633 ptr[1] = '0' + haddr.s[0] % 10; haddr.s[0] /= 10;
634 ptr[0] = '0' + haddr.s[0] % 10;
635 ptr+=4;
636 *ptr++ = '-';
637 ptr[3] = '0' + haddr.s[1] % 10; haddr.s[1] /= 10;
638 ptr[2] = '0' + haddr.s[1] % 10; haddr.s[1] /= 10;
639 ptr[1] = '0' + haddr.s[1] % 10; haddr.s[1] /= 10;
640 ptr[0] = '0' + haddr.s[1] % 10;
641 ptr+=4;
642 *ptr++ = '*';
643 *ptr++ = ProtocolKey.c[0];
644 *ptr++ = ProtocolKey.c[1];
645 *ptr++ = ProtocolKey.c[2];
646 *ptr++ = ProtocolKey.c[3];
647
648 start = ptr;
649 ptr = StuffData(icp, len, ptr, &stuffstate);
650
651 *ptr++ = 0x0D;
652 return(ptr);
653 }
654
655
656 static void strip_send(struct strip *strip_info, struct sk_buff *skb)
657 {
658 unsigned char *ptr;
659
660
661 if (strip_info->mtu != STRIP_ENCAP_SIZE(strip_info->dev.mtu))
662 strip_changedmtu(strip_info);
663
664 ptr = strip_info->tx_buff;
665
666
667 if (skb) {
668 ptr = strip_stuff(ptr, strip_info, skb);
669
670 if (!ptr) { strip_unlock(strip_info); return; }
671 strip_info->tx_packets++;
672 }
673
674
675 strip_info->tx_head = strip_info->tx_buff;
676 strip_info->tx_left = ptr - strip_info->tx_buff;
677 strip_info->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
678
679
680 if ((long)jiffies - strip_info->watchdog_doreset >= 0) {
681 printk("%s: No response: Resetting radio.\n", strip_info->dev.name);
682 ResetRadio(strip_info);
683
684
685 return;
686 }
687
688
689
690
691 if ((long)jiffies - strip_info->watchdog_doprobe >= 0) {
692
693 *ptr++ = '*';
694 *ptr++ = '*';
695 strip_info->tx_left += 2;
696 strip_info->watchdog_doprobe = jiffies + 10 * HZ;
697 strip_info->watchdog_doreset = jiffies + 1 * HZ;
698 }
699
700
701 strip_write_some_more(strip_info->tty);
702 }
703
704
705 static int strip_xmit(struct sk_buff *skb, struct device *dev)
706 {
707 struct strip *strip_info = (struct strip *)(dev->priv);
708
709 if (!dev->start) {
710 printk("%s: xmit call when iface is down\n", dev->name);
711 return(1);
712 }
713 if (set_bit(0, (void *) &strip_info->dev.tbusy)) return(1);
714 del_timer(&strip_info->idle_timer);
715 strip_send(strip_info, skb);
716 if (skb) dev_kfree_skb(skb, FREE_WRITE);
717 return(0);
718 }
719
720
721
722
723
724 static void strip_IdleTask(unsigned long parameter)
725 {
726 strip_xmit(NULL, (struct device *)parameter);
727 }
728
729
730
731
732 static int strip_receive_room(struct tty_struct *tty)
733 {
734 return 65536;
735 }
736
737
738
739 static void strip_bump(struct strip *strip_info, __u16 packetlen)
740 {
741 int count = sizeof(STRIP_Header) + packetlen;
742 struct sk_buff *skb = dev_alloc_skb(count);
743 if (skb == NULL)
744 {
745 printk("%s: memory squeeze, dropping packet.\n",
746 strip_info->dev.name);
747 strip_info->rx_dropped++;
748 return;
749 }
750 skb->dev = &strip_info->dev;
751 memcpy(skb_put(skb, count), strip_info->rx_buff, count);
752 skb->mac.raw=skb->data;
753 skb->protocol = htons(ETH_P_IP);
754 netif_rx(skb);
755 strip_info->rx_packets++;
756 }
757
758 static void RecvErr(char *msg, struct strip *strip_info)
759 {
760 static const int MAX_RecvErr = 80;
761 __u8 *ptr = strip_info->sx_buff;
762 __u8 *end = strip_info->sx_buff + strip_info->sx_count;
763 __u8 pkt_text[MAX_RecvErr], *p = pkt_text;
764 *p++ = '\"';
765 while (ptr<end && p < &pkt_text[MAX_RecvErr-4])
766 {
767 if (*ptr == '\\')
768 {
769 *p++ = '\\';
770 *p++ = '\\';
771 }
772 else
773 {
774 if (*ptr >= 32 && *ptr <= 126)
775 *p++ = *ptr;
776 else
777 {
778 sprintf(p, "\\%02X", *ptr);
779 p+= 3;
780 }
781 }
782 ptr++;
783 }
784 if (ptr == end)
785 *p++ = '\"';
786 *p++ = 0;
787 printk("%-13s%s\n", msg, pkt_text);
788 set_bit(STR_ERROR, &strip_info->flags);
789 strip_info->rx_errors++;
790 }
791
792 static void RecvErr_Message(struct strip *strip_info, __u8 *sendername, __u8 *msg)
793 {
794 static const char ERR_001[] = "ERR_001 Not in StarMode!";
795 static const char ERR_002[] = "ERR_002 Remap handle";
796 static const char ERR_003[] = "ERR_003 Can't resolve name";
797 static const char ERR_004[] = "ERR_004 Name too small or missing";
798 static const char ERR_007[] = "ERR_007 Body too big";
799 static const char ERR_008[] = "ERR_008 Bad character in name";
800
801 if (!strncmp(msg, ERR_001, sizeof(ERR_001)-1))
802 printk("Radio %s is not in StarMode\n", sendername);
803 else if (!strncmp(msg, ERR_002, sizeof(ERR_002)-1))
804 {
805 #ifdef notyet
806 int handle;
807 __u8 newname[64];
808 sscanf(msg, "ERR_002 Remap handle &%d to name %s", &handle, newname);
809 printk("Radio name %s is handle %d\n", newname, handle);
810 #endif
811 }
812 else if (!strncmp(msg, ERR_003, sizeof(ERR_003)-1))
813 printk("Radio name <unspecified> is unknown (\"Can't resolve name\" error)\n");
814 else if (!strncmp(msg, ERR_004, sizeof(ERR_004)-1))
815 strip_info->watchdog_doreset = jiffies + LONG_TIME;
816 else if (!strncmp(msg, ERR_007, sizeof(ERR_007)-1))
817 {
818
819
820
821
822 printk("Error! Packet size <unspecified> is too big for radio.");
823 strip_info->watchdog_doreset = jiffies;
824 }
825 else if (!strncmp(msg, ERR_008, sizeof(ERR_008)-1))
826 printk("Name <unspecified> contains illegal character\n");
827 else
828 RecvErr("Error Msg:", strip_info);
829 }
830
831 static void process_packet(struct strip *strip_info)
832 {
833 __u8 *ptr = strip_info->sx_buff;
834 __u8 *end = strip_info->sx_buff + strip_info->sx_count;
835 __u8 *name, *name_end;
836 __u16 packetlen;
837
838
839 if (strip_info->sx_count == 0) return;
840
841
842 if (strip_info->sx_count == 2 && ptr[0] == 'O' && ptr[1] == 'K') {
843 printk("%s: Radio is back in AT command mode: Will Reset\n",
844 strip_info->dev.name);
845 strip_info->watchdog_doreset = jiffies;
846 return;
847 }
848
849
850 if (*ptr != '*') {
851
852 if (ptr[0] == 'E' && ptr[1] == 'R' && ptr[2] == 'R' && ptr[3] == '_')
853 RecvErr_Message(strip_info, NULL, strip_info->sx_buff);
854 else RecvErr("No initial *", strip_info);
855 return;
856 }
857 ptr++;
858
859
860 name = ptr;
861 while (ptr < end && *ptr != '*') ptr++;
862
863
864 if (ptr == end) {
865 RecvErr("No second *", strip_info);
866 return;
867 }
868 name_end = ptr++;
869
870
871 if (ptr[0] != ProtocolKey.c[0] ||
872 ptr[1] != ProtocolKey.c[1] ||
873 ptr[2] != ProtocolKey.c[2] ||
874 ptr[3] != ProtocolKey.c[3]) {
875 if (ptr[0] == 'E' && ptr[1] == 'R' && ptr[2] == 'R' && ptr[3] == '_') { *name_end = 0; RecvErr_Message(strip_info, name, ptr); }
876 else RecvErr("Unrecognized protocol key", strip_info);
877 return;
878 }
879 ptr += 4;
880
881
882 ptr = UnStuffData(ptr, end, strip_info->rx_buff, 4);
883 if (!ptr) {
884 RecvErr("Runt packet", strip_info);
885 return;
886 }
887
888 packetlen = ((__u16)strip_info->rx_buff[2] << 8) | strip_info->rx_buff[3];
889
890
891
892
893
894
895 ptr = UnStuffData(ptr, end, strip_info->rx_buff+4, packetlen-4);
896 if (!ptr) {
897 RecvErr("Runt packet", strip_info);
898 return;
899 }
900 strip_bump(strip_info, packetlen);
901
902
903
904
905
906
907
908
909
910
911
912 }
913
914
915
916
917
918
919
920 static void
921 strip_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count)
922 {
923
924 struct strip *strip_info = (struct strip *) tty->disc_data;
925 const unsigned char *end = cp + count;
926
927 if (!strip_info || strip_info->magic != STRIP_MAGIC || !strip_info->dev.start)
928 return;
929
930
931 if (strip_info->mtu != STRIP_ENCAP_SIZE(strip_info->dev.mtu))
932 strip_changedmtu(strip_info);
933
934
935
936
937
938 while (cp < end) {
939 if (fp && *fp++) {
940 if (!set_bit(STR_ERROR, &strip_info->flags)) strip_info->rx_errors++;
941 }
942 else if (*cp == 0x0D) {
943
944
945 if (!clear_bit(STR_ERROR, &strip_info->flags))
946 process_packet(strip_info);
947 strip_info->sx_count = 0;
948 }
949 else if (!test_bit(STR_ERROR, &strip_info->flags) &&
950 (strip_info->sx_count > 0 || *cp != 0x0A))
951 {
952
953 if (strip_info->sx_count < strip_info->buffsize)
954 strip_info->sx_buff[strip_info->sx_count++] = *cp;
955 else
956 {
957 set_bit(STR_ERROR, &strip_info->flags);
958 strip_info->rx_over_errors++;
959 }
960 }
961 cp++;
962 }
963 }
964
965
966
967
968
969
970
971
972
973
974
975 static int strip_header(struct sk_buff *skb, struct device *dev,
976 unsigned short type, void *daddr, void *saddr, unsigned len)
977 {
978 return(-dev->hard_header_len);
979 }
980
981
982
983
984
985
986
987
988
989
990 static int strip_rebuild_header(void *buff, struct device *dev,
991 unsigned long dst, struct sk_buff *skb)
992 {
993
994
995 #ifdef CONFIG_INET
996
997
998
999
1000 return(0);
1001 #else
1002 return(0);
1003 #endif
1004 }
1005
1006 static int strip_set_dev_mac_address(struct device *dev, void *addr)
1007 {
1008 memcpy(dev->dev_addr, addr, 7);
1009 return 0;
1010 }
1011
1012 static struct enet_statistics *strip_get_stats(struct device *dev)
1013 {
1014 static struct enet_statistics stats;
1015 struct strip *strip_info = (struct strip *)(dev->priv);
1016
1017 memset(&stats, 0, sizeof(struct enet_statistics));
1018
1019 stats.rx_packets = strip_info->rx_packets;
1020 stats.tx_packets = strip_info->tx_packets;
1021 stats.rx_dropped = strip_info->rx_dropped;
1022 stats.tx_dropped = strip_info->tx_dropped;
1023 stats.tx_errors = strip_info->tx_errors;
1024 stats.rx_errors = strip_info->rx_errors;
1025 stats.rx_over_errors = strip_info->rx_over_errors;
1026 return(&stats);
1027 }
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056 static int strip_open_low(struct device *dev)
1057 {
1058 struct strip *strip_info = (struct strip *)(dev->priv);
1059 unsigned long len;
1060
1061 if (strip_info->tty == NULL)
1062 return(-ENODEV);
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072 len = STRIP_ENCAP_SIZE(dev->mtu);
1073 if (len < STRIP_ENCAP_SIZE(576))
1074 len = STRIP_ENCAP_SIZE(576);
1075 strip_info->rx_buff = (unsigned char *) kmalloc(len + 4, GFP_KERNEL);
1076 if (strip_info->rx_buff == NULL)
1077 goto norbuff;
1078 strip_info->sx_buff = (unsigned char *) kmalloc(len + 4, GFP_KERNEL);
1079 if (strip_info->sx_buff == NULL)
1080 goto nosbuff;
1081 strip_info->tx_buff = (unsigned char *) kmalloc(len + 4, GFP_KERNEL);
1082 if (strip_info->tx_buff == NULL)
1083 goto notbuff;
1084
1085 strip_info->flags &= (1 << STR_INUSE);
1086 strip_info->mtu = STRIP_ENCAP_SIZE(dev->mtu);
1087 strip_info->buffsize = len;
1088 strip_info->sx_count = 0;
1089 strip_info->tx_left = 0;
1090
1091
1092
1093
1094
1095 if (dev->pa_addr == 0)
1096 dev->pa_addr=ntohl(0xC0A80001);
1097 dev->tbusy = 0;
1098 dev->start = 1;
1099
1100 printk("%s: Initializing Radio.\n", strip_info->dev.name);
1101 ResetRadio(strip_info);
1102 strip_info->idle_timer.expires = jiffies + 2 * HZ;
1103 add_timer(&strip_info->idle_timer);
1104 return(0);
1105
1106 notbuff:
1107 kfree(strip_info->sx_buff);
1108 nosbuff:
1109 kfree(strip_info->rx_buff);
1110 norbuff:
1111 return(-ENOMEM);
1112 }
1113
1114
1115
1116
1117
1118
1119 static int strip_close_low(struct device *dev)
1120 {
1121 struct strip *strip_info = (struct strip *)(dev->priv);
1122
1123 if (strip_info->tty == NULL)
1124 return -EBUSY;
1125 strip_info->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
1126 dev->tbusy = 1;
1127 dev->start = 0;
1128
1129
1130
1131
1132 if (strip_info->rx_buff)
1133 {
1134 kfree(strip_info->rx_buff);
1135 strip_info->rx_buff = NULL;
1136 }
1137 if (strip_info->sx_buff)
1138 {
1139 kfree(strip_info->sx_buff);
1140 strip_info->sx_buff = NULL;
1141 }
1142 if (strip_info->tx_buff)
1143 {
1144 kfree(strip_info->tx_buff);
1145 strip_info->tx_buff = NULL;
1146 }
1147 del_timer(&strip_info->idle_timer);
1148 return 0;
1149 }
1150
1151
1152
1153
1154
1155
1156 static int strip_dev_init(struct device *dev)
1157 {
1158 int i;
1159
1160
1161
1162
1163
1164 dev->trans_start = 0;
1165 dev->last_rx = 0;
1166 dev->tx_queue_len = 30;
1167
1168 dev->flags = 0;
1169 dev->family = AF_INET;
1170 dev->metric = 0;
1171 dev->mtu = STRIP_MTU;
1172 dev->type = ARPHRD_METRICOM;
1173 dev->hard_header_len = 8;
1174
1175
1176
1177
1178 dev->broadcast[0] = 0;
1179 dev->dev_addr[0] = 0;
1180 dev->addr_len = sizeof(MetricomAddress);
1181 dev->pa_addr = 0;
1182 dev->pa_brdaddr = 0;
1183 dev->pa_mask = 0;
1184 dev->pa_alen = sizeof(unsigned long);
1185
1186
1187
1188
1189
1190 for (i = 0; i < DEV_NUMBUFFS; i++)
1191 skb_queue_head_init(&dev->buffs[i]);
1192
1193
1194
1195
1196
1197 dev->open = strip_open_low;
1198 dev->stop = strip_close_low;
1199 dev->hard_start_xmit = strip_xmit;
1200 dev->hard_header = strip_header;
1201 dev->rebuild_header = strip_rebuild_header;
1202
1203
1204 dev->set_mac_address = strip_set_dev_mac_address;
1205
1206
1207 dev->get_stats = strip_get_stats;
1208 return 0;
1209 }
1210
1211
1212
1213
1214
1215 static void strip_free(struct strip *strip_info)
1216 {
1217 *(strip_info->referrer) = strip_info->next;
1218 if (strip_info->next)
1219 strip_info->next->referrer = strip_info->referrer;
1220 strip_info->magic = 0;
1221 kfree(strip_info);
1222 }
1223
1224
1225
1226
1227
1228 static struct strip *strip_alloc(void)
1229 {
1230 int channel_id = 0;
1231 struct strip **s = &struct_strip_list;
1232 struct strip *strip_info = (struct strip *)
1233 kmalloc(sizeof(struct strip), GFP_KERNEL);
1234
1235 if (!strip_info)
1236 return(NULL);
1237
1238
1239
1240
1241
1242 memset(strip_info, 0, sizeof(struct strip));
1243
1244
1245
1246
1247
1248
1249
1250 while (*s && (*s)->dev.base_addr == channel_id)
1251 {
1252 channel_id++;
1253 s = &(*s)->next;
1254 }
1255
1256
1257
1258
1259
1260 strip_info->next = *s;
1261 if (*s)
1262 (*s)->referrer = &strip_info->next;
1263 strip_info->referrer = s;
1264 *s = strip_info;
1265
1266 set_bit(STR_INUSE, &strip_info->flags);
1267 strip_info->magic = STRIP_MAGIC;
1268 strip_info->tty = NULL;
1269
1270 init_timer(&strip_info->idle_timer);
1271 strip_info->idle_timer.data = (long)&strip_info->dev;
1272 strip_info->idle_timer.function = strip_IdleTask;
1273
1274 sprintf(strip_info->if_name, "st%d", channel_id);
1275 strip_info->dev.name = strip_info->if_name;
1276 strip_info->dev.base_addr = channel_id;
1277 strip_info->dev.priv = (void*)strip_info;
1278 strip_info->dev.next = NULL;
1279 strip_info->dev.init = strip_dev_init;
1280
1281 return(strip_info);
1282 }
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292 static int strip_open(struct tty_struct *tty)
1293 {
1294 struct strip *strip_info = (struct strip *) tty->disc_data;
1295
1296
1297
1298
1299
1300 if (strip_info && strip_info->magic == STRIP_MAGIC)
1301 return -EEXIST;
1302
1303
1304
1305
1306
1307 if ((strip_info = strip_alloc()) == NULL)
1308 return -ENFILE;
1309
1310
1311
1312
1313
1314
1315 if (register_netdev(&strip_info->dev) != 0)
1316 {
1317 printk("strip: register_netdev() failed.\n");
1318 strip_free(strip_info);
1319 return -ENFILE;
1320 }
1321
1322 strip_info->tty = tty;
1323 tty->disc_data = strip_info;
1324 if (tty->driver.flush_buffer)
1325 tty->driver.flush_buffer(tty);
1326 if (tty->ldisc.flush_buffer)
1327 tty->ldisc.flush_buffer(tty);
1328
1329
1330
1331
1332
1333 strip_info->dev.type = ARPHRD_METRICOM;
1334
1335
1336
1337
1338
1339 tty->termios->c_iflag |= IGNBRK |IGNPAR;
1340 tty->termios->c_cflag |= CLOCAL;
1341 tty->termios->c_cflag &= ~HUPCL;
1342
1343 #ifdef MODULE
1344 MOD_INC_USE_COUNT;
1345 #endif
1346
1347
1348
1349 return(strip_info->dev.base_addr);
1350 }
1351
1352
1353
1354
1355
1356
1357
1358 static void strip_close(struct tty_struct *tty)
1359 {
1360 struct strip *strip_info = (struct strip *) tty->disc_data;
1361
1362
1363
1364
1365
1366 if (!strip_info || strip_info->magic != STRIP_MAGIC)
1367 return;
1368
1369 dev_close(&strip_info->dev);
1370 unregister_netdev(&strip_info->dev);
1371
1372 tty->disc_data = 0;
1373 strip_info->tty = NULL;
1374 strip_free(strip_info);
1375 tty->disc_data = NULL;
1376 #ifdef MODULE
1377 MOD_DEC_USE_COUNT;
1378 #endif
1379 }
1380
1381
1382
1383
1384
1385 static int strip_ioctl(struct tty_struct *tty, struct file *file,
1386 unsigned int cmd, unsigned long arg)
1387 {
1388 struct strip *strip_info = (struct strip *) tty->disc_data;
1389 int err;
1390
1391
1392
1393
1394
1395 if (!strip_info || strip_info->magic != STRIP_MAGIC)
1396 return -EINVAL;
1397
1398 switch(cmd)
1399 {
1400 case SIOCGIFNAME:
1401 err = verify_area(VERIFY_WRITE, (void*)arg, 16);
1402 if (err)
1403 return -err;
1404 memcpy_tofs((void*)arg, strip_info->dev.name,
1405 strlen(strip_info->dev.name) + 1);
1406 return 0;
1407
1408 case SIOCSIFHWADDR:
1409 return -EINVAL;
1410
1411
1412
1413
1414
1415 case TCGETS:
1416 case TCGETA:
1417 return n_tty_ioctl(tty, (struct file *) file, cmd,
1418 (unsigned long) arg);
1419
1420 default:
1421 return -ENOIOCTLCMD;
1422 }
1423 }
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434 #ifdef MODULE
1435 static
1436 #endif
1437 int strip_init_ctrl_dev(struct device *dummy)
1438 {
1439 static struct tty_ldisc strip_ldisc;
1440 int status;
1441 printk("STRIP: version %s (unlimited channels)\n", STRIP_VERSION);
1442
1443
1444
1445
1446
1447 memset(&strip_ldisc, 0, sizeof(strip_ldisc));
1448 strip_ldisc.magic = TTY_LDISC_MAGIC;
1449 strip_ldisc.flags = 0;
1450 strip_ldisc.open = strip_open;
1451 strip_ldisc.close = strip_close;
1452 strip_ldisc.read = NULL;
1453 strip_ldisc.write = NULL;
1454 strip_ldisc.ioctl = strip_ioctl;
1455 strip_ldisc.select = NULL;
1456 strip_ldisc.receive_buf = strip_receive_buf;
1457 strip_ldisc.receive_room = strip_receive_room;
1458 strip_ldisc.write_wakeup = strip_write_some_more;
1459 status = tty_register_ldisc(N_STRIP, &strip_ldisc);
1460 if (status != 0)
1461 {
1462 printk("STRIP: can't register line discipline (err = %d)\n", status);
1463 }
1464
1465 #ifdef MODULE
1466 return status;
1467 #else
1468
1469
1470
1471 return ENODEV;
1472 #endif
1473 }
1474
1475
1476
1477
1478 #ifdef MODULE
1479
1480 int init_module(void)
1481 {
1482 return strip_init_ctrl_dev(0);
1483 }
1484
1485 void cleanup_module(void)
1486 {
1487 int i;
1488 while (struct_strip_list)
1489 strip_free(struct_strip_list);
1490
1491 if ((i = tty_register_ldisc(N_STRIP, NULL)))
1492 printk("STRIP: can't unregister line discipline (err = %d)\n", i);
1493 }
1494 #endif