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
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71#ifdef MODULE
72static const char StripVersion[] = "1.3A-STUART.CHESHIRE-MODULAR";
73#else
74static const char StripVersion[] = "1.3A-STUART.CHESHIRE";
75#endif
76
77#define TICKLE_TIMERS 0
78#define EXT_COUNTERS 1
79
80
81
82
83
84#include <linux/kernel.h>
85#include <linux/module.h>
86#include <linux/init.h>
87#include <linux/bitops.h>
88#include <asm/system.h>
89#include <asm/uaccess.h>
90
91# include <linux/ctype.h>
92#include <linux/string.h>
93#include <linux/mm.h>
94#include <linux/interrupt.h>
95#include <linux/in.h>
96#include <linux/tty.h>
97#include <linux/errno.h>
98#include <linux/netdevice.h>
99#include <linux/inetdevice.h>
100#include <linux/etherdevice.h>
101#include <linux/skbuff.h>
102#include <linux/if_arp.h>
103#include <linux/if_strip.h>
104#include <linux/proc_fs.h>
105#include <linux/seq_file.h>
106#include <linux/serial.h>
107#include <linux/serialP.h>
108#include <linux/rcupdate.h>
109#include <net/arp.h>
110#include <net/net_namespace.h>
111
112#include <linux/ip.h>
113#include <linux/tcp.h>
114#include <linux/time.h>
115#include <linux/jiffies.h>
116
117
118
119
120
121
122
123
124
125typedef union {
126 __u8 c[4];
127 __u32 l;
128} MetricomKey;
129
130
131
132
133
134
135typedef union {
136 __u8 b[4];
137 __u32 l;
138} IPaddr;
139
140
141
142
143
144
145typedef struct {
146 __u8 c[24];
147} MetricomAddressString;
148
149
150
151
152
153
154
155#define STRIP_ENCAP_SIZE(X) (32 + (X)*65L/64L)
156
157
158
159
160
161
162
163
164typedef struct {
165 MetricomAddress dst_addr;
166 MetricomAddress src_addr;
167 unsigned short protocol;
168} STRIP_Header;
169
170typedef struct {
171 char c[60];
172} MetricomNode;
173
174#define NODE_TABLE_SIZE 32
175typedef struct {
176 struct timeval timestamp;
177 int num_nodes;
178 MetricomNode node[NODE_TABLE_SIZE];
179} MetricomNodeTable;
180
181enum { FALSE = 0, TRUE = 1 };
182
183
184
185
186typedef struct {
187 char c[50];
188} FirmwareVersion;
189
190
191
192
193typedef struct {
194 char c[18];
195} SerialNumber;
196
197
198
199
200typedef struct {
201 char c[11];
202} BatteryVoltage;
203
204typedef struct {
205 char c[8];
206} char8;
207
208enum {
209 NoStructure = 0,
210 StructuredMessages = 1,
211 ChecksummedMessages = 2
212};
213
214struct strip {
215 int magic;
216
217
218
219
220 unsigned char *rx_buff;
221 unsigned char *sx_buff;
222 int sx_count;
223 int sx_size;
224 unsigned char *tx_buff;
225 unsigned char *tx_head;
226 int tx_left;
227 int tx_size;
228
229
230
231
232
233 unsigned long rx_packets;
234 unsigned long tx_packets;
235 unsigned long rx_errors;
236 unsigned long tx_errors;
237 unsigned long rx_dropped;
238 unsigned long tx_dropped;
239 unsigned long rx_over_errors;
240
241 unsigned long pps_timer;
242 unsigned long rx_pps_count;
243 unsigned long tx_pps_count;
244 unsigned long sx_pps_count;
245 unsigned long rx_average_pps;
246 unsigned long tx_average_pps;
247 unsigned long sx_average_pps;
248
249#ifdef EXT_COUNTERS
250 unsigned long rx_bytes;
251 unsigned long tx_bytes;
252 unsigned long rx_rbytes;
253 unsigned long tx_rbytes;
254 unsigned long rx_sbytes;
255 unsigned long tx_sbytes;
256 unsigned long rx_ebytes;
257 unsigned long tx_ebytes;
258#endif
259
260
261
262
263
264 struct list_head list;
265
266 int discard;
267 int working;
268 int firmware_level;
269 int next_command;
270 unsigned int user_baud;
271 int mtu;
272 long watchdog_doprobe;
273 long watchdog_doreset;
274 long gratuitous_arp;
275 long arp_interval;
276 struct timer_list idle_timer;
277 MetricomAddress true_dev_addr;
278 int manual_dev_addr;
279
280 FirmwareVersion firmware_version;
281 SerialNumber serial_number;
282 BatteryVoltage battery_voltage;
283
284
285
286
287
288 struct tty_struct *tty;
289 struct net_device *dev;
290
291
292
293
294
295 MetricomNodeTable portables;
296 MetricomNodeTable poletops;
297};
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379static const int MaxCommandStringLength = 32;
380static const int CompatibilityCommand = 1;
381
382static const char CommandString0[] = "*&COMMAND*ATS319=7";
383static const char CommandString1[] = "*&COMMAND*ATS305?";
384static const char CommandString2[] = "*&COMMAND*ATS325?";
385static const char CommandString3[] = "*&COMMAND*ATS300?";
386static const char CommandString4[] = "*&COMMAND*ATS311?";
387static const char CommandString5[] = "*&COMMAND*AT~LA";
388typedef struct {
389 const char *string;
390 long length;
391} StringDescriptor;
392
393static const StringDescriptor CommandString[] = {
394 {CommandString0, sizeof(CommandString0) - 1},
395 {CommandString1, sizeof(CommandString1) - 1},
396 {CommandString2, sizeof(CommandString2) - 1},
397 {CommandString3, sizeof(CommandString3) - 1},
398 {CommandString4, sizeof(CommandString4) - 1},
399 {CommandString5, sizeof(CommandString5) - 1}
400};
401
402#define GOT_ALL_RADIO_INFO(S) \
403 ((S)->firmware_version.c[0] && \
404 (S)->battery_voltage.c[0] && \
405 memcmp(&(S)->true_dev_addr, zero_address.c, sizeof(zero_address)))
406
407static const char hextable[16] = "0123456789ABCDEF";
408
409static const MetricomAddress zero_address;
410static const MetricomAddress broadcast_address =
411 { {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} };
412
413static const MetricomKey SIP0Key = { "SIP0" };
414static const MetricomKey ARP0Key = { "ARP0" };
415static const MetricomKey ATR_Key = { "ATR " };
416static const MetricomKey ACK_Key = { "ACK_" };
417static const MetricomKey INF_Key = { "INF_" };
418static const MetricomKey ERR_Key = { "ERR_" };
419
420static const long MaxARPInterval = 60 * HZ;
421
422
423
424
425
426
427
428
429
430static const unsigned short MAX_SEND_MTU = 1152;
431static const unsigned short MAX_RECV_MTU = 1500;
432static const unsigned short DEFAULT_STRIP_MTU = 1152;
433static const int STRIP_MAGIC = 0x5303;
434static const long LongTime = 0x7FFFFFFF;
435
436
437
438
439static LIST_HEAD(strip_list);
440static DEFINE_SPINLOCK(strip_lock);
441
442
443
444
445
446#define has_prefix(T,L,P) (((L) >= sizeof(P)-1) && !strncmp((T), (P), sizeof(P)-1))
447
448
449#define text_equal(T,L,S) (((L) == sizeof(S)-1) && !strncmp((T), (S), sizeof(S)-1))
450
451#define READHEX(X) ((X)>='0' && (X)<='9' ? (X)-'0' : \
452 (X)>='a' && (X)<='f' ? (X)-'a'+10 : \
453 (X)>='A' && (X)<='F' ? (X)-'A'+10 : 0 )
454
455#define READHEX16(X) ((__u16)(READHEX(X)))
456
457#define READDEC(X) ((X)>='0' && (X)<='9' ? (X)-'0' : 0)
458
459#define ARRAY_END(X) (&((X)[ARRAY_SIZE(X)]))
460
461#define JIFFIE_TO_SEC(X) ((X) / HZ)
462
463
464
465
466
467static int arp_query(unsigned char *haddr, u32 paddr,
468 struct net_device *dev)
469{
470 struct neighbour *neighbor_entry;
471 int ret = 0;
472
473 neighbor_entry = neigh_lookup(&arp_tbl, &paddr, dev);
474
475 if (neighbor_entry != NULL) {
476 neighbor_entry->used = jiffies;
477 if (neighbor_entry->nud_state & NUD_VALID) {
478 memcpy(haddr, neighbor_entry->ha, dev->addr_len);
479 ret = 1;
480 }
481 neigh_release(neighbor_entry);
482 }
483 return ret;
484}
485
486static void DumpData(char *msg, struct strip *strip_info, __u8 * ptr,
487 __u8 * end)
488{
489 static const int MAX_DumpData = 80;
490 __u8 pkt_text[MAX_DumpData], *p = pkt_text;
491
492 *p++ = '\"';
493
494 while (ptr < end && p < &pkt_text[MAX_DumpData - 4]) {
495 if (*ptr == '\\') {
496 *p++ = '\\';
497 *p++ = '\\';
498 } else {
499 if (*ptr >= 32 && *ptr <= 126) {
500 *p++ = *ptr;
501 } else {
502 sprintf(p, "\\%02X", *ptr);
503 p += 3;
504 }
505 }
506 ptr++;
507 }
508
509 if (ptr == end)
510 *p++ = '\"';
511 *p++ = 0;
512
513 printk(KERN_INFO "%s: %-13s%s\n", strip_info->dev->name, msg, pkt_text);
514}
515
516
517
518
519
520
521
522
523
524
525
526
527
528typedef enum {
529 Stuff_Diff = 0x00,
530 Stuff_DiffZero = 0x40,
531 Stuff_Same = 0x80,
532 Stuff_Zero = 0xC0,
533 Stuff_NoCode = 0xFF,
534
535 Stuff_CodeMask = 0xC0,
536 Stuff_CountMask = 0x3F,
537 Stuff_MaxCount = 0x3F,
538 Stuff_Magic = 0x0D
539} StuffingCode;
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554#define StuffData_FinishBlock(X) \
555(*code_ptr = (X) ^ Stuff_Magic, code = Stuff_NoCode)
556
557static __u8 *StuffData(__u8 * src, __u32 length, __u8 * dst,
558 __u8 ** code_ptr_ptr)
559{
560 __u8 *end = src + length;
561 __u8 *code_ptr = *code_ptr_ptr;
562 __u8 code = Stuff_NoCode, count = 0;
563
564 if (!length)
565 return (dst);
566
567 if (code_ptr) {
568
569
570
571 code = (*code_ptr ^ Stuff_Magic) & Stuff_CodeMask;
572 count = (*code_ptr ^ Stuff_Magic) & Stuff_CountMask;
573 }
574
575 while (src < end) {
576 switch (code) {
577
578 case Stuff_NoCode:
579
580 code_ptr = dst++;
581 count = 0;
582
583 if (*src == 0) {
584 code = Stuff_Zero;
585 src++;
586 } else {
587 code = Stuff_Same;
588 *dst++ = *src++ ^ Stuff_Magic;
589 }
590
591
592
593 break;
594
595
596 case Stuff_Zero:
597
598 if (*src == 0) {
599 count++;
600 src++;
601 } else {
602 StuffData_FinishBlock(Stuff_Zero + count);
603 }
604 break;
605
606
607 case Stuff_Same:
608
609 if ((*src ^ Stuff_Magic) == code_ptr[1]) {
610 count++;
611 src++;
612 break;
613 }
614
615
616 if (count) {
617 StuffData_FinishBlock(Stuff_Same + count);
618 break;
619 }
620
621 code = Stuff_Diff;
622
623
624
625
626
627
628
629
630
631
632
633 case Stuff_Diff:
634
635 if (*src == 0) {
636 StuffData_FinishBlock(Stuff_DiffZero +
637 count);
638 }
639
640 else if ((*src ^ Stuff_Magic) == dst[-1]
641 && dst[-1] == dst[-2]) {
642
643 code += count - 2;
644
645 if (code == Stuff_Diff + 0) {
646 code = Stuff_Same + 0;
647 }
648 StuffData_FinishBlock(code);
649 code_ptr = dst - 2;
650
651 count = 2;
652 code = Stuff_Same;
653 }
654
655 else {
656 *dst++ = *src ^ Stuff_Magic;
657 count++;
658 }
659 src++;
660 break;
661 }
662 if (count == Stuff_MaxCount) {
663 StuffData_FinishBlock(code + count);
664 }
665 }
666 if (code == Stuff_NoCode) {
667 *code_ptr_ptr = NULL;
668 } else {
669 *code_ptr_ptr = code_ptr;
670 StuffData_FinishBlock(code + count);
671 }
672 return (dst);
673}
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695static __u8 *UnStuffData(__u8 * src, __u8 * end, __u8 * dst,
696 __u32 dst_length)
697{
698 __u8 *dst_end = dst + dst_length;
699
700 if (!src || !end || !dst || !dst_length)
701 return (NULL);
702 while (src < end && dst < dst_end) {
703 int count = (*src ^ Stuff_Magic) & Stuff_CountMask;
704 switch ((*src ^ Stuff_Magic) & Stuff_CodeMask) {
705 case Stuff_Diff:
706 if (src + 1 + count >= end)
707 return (NULL);
708 do {
709 *dst++ = *++src ^ Stuff_Magic;
710 }
711 while (--count >= 0 && dst < dst_end);
712 if (count < 0)
713 src += 1;
714 else {
715 if (count == 0)
716 *src = Stuff_Same ^ Stuff_Magic;
717 else
718 *src =
719 (Stuff_Diff +
720 count) ^ Stuff_Magic;
721 }
722 break;
723 case Stuff_DiffZero:
724 if (src + 1 + count >= end)
725 return (NULL);
726 do {
727 *dst++ = *++src ^ Stuff_Magic;
728 }
729 while (--count >= 0 && dst < dst_end);
730 if (count < 0)
731 *src = Stuff_Zero ^ Stuff_Magic;
732 else
733 *src =
734 (Stuff_DiffZero + count) ^ Stuff_Magic;
735 break;
736 case Stuff_Same:
737 if (src + 1 >= end)
738 return (NULL);
739 do {
740 *dst++ = src[1] ^ Stuff_Magic;
741 }
742 while (--count >= 0 && dst < dst_end);
743 if (count < 0)
744 src += 2;
745 else
746 *src = (Stuff_Same + count) ^ Stuff_Magic;
747 break;
748 case Stuff_Zero:
749 do {
750 *dst++ = 0;
751 }
752 while (--count >= 0 && dst < dst_end);
753 if (count < 0)
754 src += 1;
755 else
756 *src = (Stuff_Zero + count) ^ Stuff_Magic;
757 break;
758 }
759 }
760 if (dst < dst_end)
761 return (NULL);
762 else
763 return (src);
764}
765
766
767
768
769
770
771
772
773static void set_baud(struct tty_struct *tty, speed_t baudrate)
774{
775 struct ktermios old_termios;
776
777 mutex_lock(&tty->termios_mutex);
778 old_termios =*(tty->termios);
779 tty_encode_baud_rate(tty, baudrate, baudrate);
780 tty->ops->set_termios(tty, &old_termios);
781 mutex_unlock(&tty->termios_mutex);
782}
783
784
785
786
787
788#define IS_RADIO_ADDRESS(p) ( \
789 isdigit((p)[0]) && isdigit((p)[1]) && isdigit((p)[2]) && isdigit((p)[3]) && \
790 (p)[4] == '-' && \
791 isdigit((p)[5]) && isdigit((p)[6]) && isdigit((p)[7]) && isdigit((p)[8]) )
792
793static int string_to_radio_address(MetricomAddress * addr, __u8 * p)
794{
795 if (!IS_RADIO_ADDRESS(p))
796 return (1);
797 addr->c[0] = 0;
798 addr->c[1] = 0;
799 addr->c[2] = READHEX(p[0]) << 4 | READHEX(p[1]);
800 addr->c[3] = READHEX(p[2]) << 4 | READHEX(p[3]);
801 addr->c[4] = READHEX(p[5]) << 4 | READHEX(p[6]);
802 addr->c[5] = READHEX(p[7]) << 4 | READHEX(p[8]);
803 return (0);
804}
805
806
807
808
809
810static __u8 *radio_address_to_string(const MetricomAddress * addr,
811 MetricomAddressString * p)
812{
813 sprintf(p->c, "%02X%02X-%02X%02X", addr->c[2], addr->c[3],
814 addr->c[4], addr->c[5]);
815 return (p->c);
816}
817
818
819
820
821
822
823
824static int allocate_buffers(struct strip *strip_info, int mtu)
825{
826 struct net_device *dev = strip_info->dev;
827 int sx_size = max_t(int, STRIP_ENCAP_SIZE(MAX_RECV_MTU), 4096);
828 int tx_size = STRIP_ENCAP_SIZE(mtu) + MaxCommandStringLength;
829 __u8 *r = kmalloc(MAX_RECV_MTU, GFP_ATOMIC);
830 __u8 *s = kmalloc(sx_size, GFP_ATOMIC);
831 __u8 *t = kmalloc(tx_size, GFP_ATOMIC);
832 if (r && s && t) {
833 strip_info->rx_buff = r;
834 strip_info->sx_buff = s;
835 strip_info->tx_buff = t;
836 strip_info->sx_size = sx_size;
837 strip_info->tx_size = tx_size;
838 strip_info->mtu = dev->mtu = mtu;
839 return (1);
840 }
841 kfree(r);
842 kfree(s);
843 kfree(t);
844 return (0);
845}
846
847
848
849
850
851
852static int strip_change_mtu(struct net_device *dev, int new_mtu)
853{
854 struct strip *strip_info = netdev_priv(dev);
855 int old_mtu = strip_info->mtu;
856 unsigned char *orbuff = strip_info->rx_buff;
857 unsigned char *osbuff = strip_info->sx_buff;
858 unsigned char *otbuff = strip_info->tx_buff;
859
860 if (new_mtu > MAX_SEND_MTU) {
861 printk(KERN_ERR
862 "%s: MTU exceeds maximum allowable (%d), MTU change cancelled.\n",
863 strip_info->dev->name, MAX_SEND_MTU);
864 return -EINVAL;
865 }
866
867 spin_lock_bh(&strip_lock);
868 if (!allocate_buffers(strip_info, new_mtu)) {
869 printk(KERN_ERR "%s: unable to grow strip buffers, MTU change cancelled.\n",
870 strip_info->dev->name);
871 spin_unlock_bh(&strip_lock);
872 return -ENOMEM;
873 }
874
875 if (strip_info->sx_count) {
876 if (strip_info->sx_count <= strip_info->sx_size)
877 memcpy(strip_info->sx_buff, osbuff,
878 strip_info->sx_count);
879 else {
880 strip_info->discard = strip_info->sx_count;
881 strip_info->rx_over_errors++;
882 }
883 }
884
885 if (strip_info->tx_left) {
886 if (strip_info->tx_left <= strip_info->tx_size)
887 memcpy(strip_info->tx_buff, strip_info->tx_head,
888 strip_info->tx_left);
889 else {
890 strip_info->tx_left = 0;
891 strip_info->tx_dropped++;
892 }
893 }
894 strip_info->tx_head = strip_info->tx_buff;
895 spin_unlock_bh(&strip_lock);
896
897 printk(KERN_NOTICE "%s: strip MTU changed fom %d to %d.\n",
898 strip_info->dev->name, old_mtu, strip_info->mtu);
899
900 kfree(orbuff);
901 kfree(osbuff);
902 kfree(otbuff);
903 return 0;
904}
905
906static void strip_unlock(struct strip *strip_info)
907{
908
909
910
911 strip_info->idle_timer.expires = jiffies + 1 * HZ;
912 add_timer(&strip_info->idle_timer);
913 netif_wake_queue(strip_info->dev);
914}
915
916
917
918
919
920
921
922
923
924
925
926#ifdef CONFIG_PROC_FS
927static char *time_delta(char buffer[], long time)
928{
929 time -= jiffies;
930 if (time > LongTime / 2)
931 return ("Not scheduled");
932 if (time < 0)
933 time = 0;
934 sprintf(buffer, "%ld seconds", time / HZ);
935 return (buffer);
936}
937
938
939static struct strip *strip_get_idx(loff_t pos)
940{
941 struct strip *str;
942 int i = 0;
943
944 list_for_each_entry_rcu(str, &strip_list, list) {
945 if (pos == i)
946 return str;
947 ++i;
948 }
949 return NULL;
950}
951
952static void *strip_seq_start(struct seq_file *seq, loff_t *pos)
953{
954 rcu_read_lock();
955 return *pos ? strip_get_idx(*pos - 1) : SEQ_START_TOKEN;
956}
957
958static void *strip_seq_next(struct seq_file *seq, void *v, loff_t *pos)
959{
960 struct list_head *l;
961 struct strip *s;
962
963 ++*pos;
964 if (v == SEQ_START_TOKEN)
965 return strip_get_idx(1);
966
967 s = v;
968 l = &s->list;
969 list_for_each_continue_rcu(l, &strip_list) {
970 return list_entry(l, struct strip, list);
971 }
972 return NULL;
973}
974
975static void strip_seq_stop(struct seq_file *seq, void *v)
976{
977 rcu_read_unlock();
978}
979
980static void strip_seq_neighbours(struct seq_file *seq,
981 const MetricomNodeTable * table,
982 const char *title)
983{
984
985
986 struct timeval t;
987
988 do {
989 int i;
990 t = table->timestamp;
991 if (table->num_nodes)
992 seq_printf(seq, "\n %s\n", title);
993 for (i = 0; i < table->num_nodes; i++) {
994 MetricomNode node;
995
996 spin_lock_bh(&strip_lock);
997 node = table->node[i];
998 spin_unlock_bh(&strip_lock);
999 seq_printf(seq, " %s\n", node.c);
1000 }
1001 } while (table->timestamp.tv_sec != t.tv_sec
1002 || table->timestamp.tv_usec != t.tv_usec);
1003}
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015static void strip_seq_status_info(struct seq_file *seq,
1016 const struct strip *strip_info)
1017{
1018 char temp[32];
1019 MetricomAddressString addr_string;
1020
1021
1022
1023 int tx_left = strip_info->tx_left;
1024 unsigned long rx_average_pps = strip_info->rx_average_pps;
1025 unsigned long tx_average_pps = strip_info->tx_average_pps;
1026 unsigned long sx_average_pps = strip_info->sx_average_pps;
1027 int working = strip_info->working;
1028 int firmware_level = strip_info->firmware_level;
1029 long watchdog_doprobe = strip_info->watchdog_doprobe;
1030 long watchdog_doreset = strip_info->watchdog_doreset;
1031 long gratuitous_arp = strip_info->gratuitous_arp;
1032 long arp_interval = strip_info->arp_interval;
1033 FirmwareVersion firmware_version = strip_info->firmware_version;
1034 SerialNumber serial_number = strip_info->serial_number;
1035 BatteryVoltage battery_voltage = strip_info->battery_voltage;
1036 char *if_name = strip_info->dev->name;
1037 MetricomAddress true_dev_addr = strip_info->true_dev_addr;
1038 MetricomAddress dev_dev_addr =
1039 *(MetricomAddress *) strip_info->dev->dev_addr;
1040 int manual_dev_addr = strip_info->manual_dev_addr;
1041#ifdef EXT_COUNTERS
1042 unsigned long rx_bytes = strip_info->rx_bytes;
1043 unsigned long tx_bytes = strip_info->tx_bytes;
1044 unsigned long rx_rbytes = strip_info->rx_rbytes;
1045 unsigned long tx_rbytes = strip_info->tx_rbytes;
1046 unsigned long rx_sbytes = strip_info->rx_sbytes;
1047 unsigned long tx_sbytes = strip_info->tx_sbytes;
1048 unsigned long rx_ebytes = strip_info->rx_ebytes;
1049 unsigned long tx_ebytes = strip_info->tx_ebytes;
1050#endif
1051
1052 seq_printf(seq, "\nInterface name\t\t%s\n", if_name);
1053 seq_printf(seq, " Radio working:\t\t%s\n", working ? "Yes" : "No");
1054 radio_address_to_string(&true_dev_addr, &addr_string);
1055 seq_printf(seq, " Radio address:\t\t%s\n", addr_string.c);
1056 if (manual_dev_addr) {
1057 radio_address_to_string(&dev_dev_addr, &addr_string);
1058 seq_printf(seq, " Device address:\t%s\n", addr_string.c);
1059 }
1060 seq_printf(seq, " Firmware version:\t%s", !working ? "Unknown" :
1061 !firmware_level ? "Should be upgraded" :
1062 firmware_version.c);
1063 if (firmware_level >= ChecksummedMessages)
1064 seq_printf(seq, " (Checksums Enabled)");
1065 seq_printf(seq, "\n");
1066 seq_printf(seq, " Serial number:\t\t%s\n", serial_number.c);
1067 seq_printf(seq, " Battery voltage:\t%s\n", battery_voltage.c);
1068 seq_printf(seq, " Transmit queue (bytes):%d\n", tx_left);
1069 seq_printf(seq, " Receive packet rate: %ld packets per second\n",
1070 rx_average_pps / 8);
1071 seq_printf(seq, " Transmit packet rate: %ld packets per second\n",
1072 tx_average_pps / 8);
1073 seq_printf(seq, " Sent packet rate: %ld packets per second\n",
1074 sx_average_pps / 8);
1075 seq_printf(seq, " Next watchdog probe:\t%s\n",
1076 time_delta(temp, watchdog_doprobe));
1077 seq_printf(seq, " Next watchdog reset:\t%s\n",
1078 time_delta(temp, watchdog_doreset));
1079 seq_printf(seq, " Next gratuitous ARP:\t");
1080
1081 if (!memcmp
1082 (strip_info->dev->dev_addr, zero_address.c,
1083 sizeof(zero_address)))
1084 seq_printf(seq, "Disabled\n");
1085 else {
1086 seq_printf(seq, "%s\n", time_delta(temp, gratuitous_arp));
1087 seq_printf(seq, " Next ARP interval:\t%ld seconds\n",
1088 JIFFIE_TO_SEC(arp_interval));
1089 }
1090
1091 if (working) {
1092#ifdef EXT_COUNTERS
1093 seq_printf(seq, "\n");
1094 seq_printf(seq,
1095 " Total bytes: \trx:\t%lu\ttx:\t%lu\n",
1096 rx_bytes, tx_bytes);
1097 seq_printf(seq,
1098 " thru radio: \trx:\t%lu\ttx:\t%lu\n",
1099 rx_rbytes, tx_rbytes);
1100 seq_printf(seq,
1101 " thru serial port: \trx:\t%lu\ttx:\t%lu\n",
1102 rx_sbytes, tx_sbytes);
1103 seq_printf(seq,
1104 " Total stat/err bytes:\trx:\t%lu\ttx:\t%lu\n",
1105 rx_ebytes, tx_ebytes);
1106#endif
1107 strip_seq_neighbours(seq, &strip_info->poletops,
1108 "Poletops:");
1109 strip_seq_neighbours(seq, &strip_info->portables,
1110 "Portables:");
1111 }
1112}
1113
1114
1115
1116
1117
1118static int strip_seq_show(struct seq_file *seq, void *v)
1119{
1120 if (v == SEQ_START_TOKEN)
1121 seq_printf(seq, "strip_version: %s\n", StripVersion);
1122 else
1123 strip_seq_status_info(seq, (const struct strip *)v);
1124 return 0;
1125}
1126
1127
1128static struct seq_operations strip_seq_ops = {
1129 .start = strip_seq_start,
1130 .next = strip_seq_next,
1131 .stop = strip_seq_stop,
1132 .show = strip_seq_show,
1133};
1134
1135static int strip_seq_open(struct inode *inode, struct file *file)
1136{
1137 return seq_open(file, &strip_seq_ops);
1138}
1139
1140static const struct file_operations strip_seq_fops = {
1141 .owner = THIS_MODULE,
1142 .open = strip_seq_open,
1143 .read = seq_read,
1144 .llseek = seq_lseek,
1145 .release = seq_release,
1146};
1147#endif
1148
1149
1150
1151
1152
1153
1154static void ResetRadio(struct strip *strip_info)
1155{
1156 struct tty_struct *tty = strip_info->tty;
1157 static const char init[] = "ate0q1dt**starmode\r**";
1158 StringDescriptor s = { init, sizeof(init) - 1 };
1159
1160
1161
1162
1163
1164 if (strip_info->working) {
1165 printk(KERN_INFO "%s: No response: Resetting radio.\n",
1166 strip_info->dev->name);
1167 strip_info->firmware_version.c[0] = '\0';
1168 strip_info->serial_number.c[0] = '\0';
1169 strip_info->battery_voltage.c[0] = '\0';
1170 strip_info->portables.num_nodes = 0;
1171 do_gettimeofday(&strip_info->portables.timestamp);
1172 strip_info->poletops.num_nodes = 0;
1173 do_gettimeofday(&strip_info->poletops.timestamp);
1174 }
1175
1176 strip_info->pps_timer = jiffies;
1177 strip_info->rx_pps_count = 0;
1178 strip_info->tx_pps_count = 0;
1179 strip_info->sx_pps_count = 0;
1180 strip_info->rx_average_pps = 0;
1181 strip_info->tx_average_pps = 0;
1182 strip_info->sx_average_pps = 0;
1183
1184
1185 *(MetricomAddress *) & strip_info->true_dev_addr = zero_address;
1186 if (!strip_info->manual_dev_addr)
1187 *(MetricomAddress *) strip_info->dev->dev_addr =
1188 zero_address;
1189 strip_info->working = FALSE;
1190 strip_info->firmware_level = NoStructure;
1191 strip_info->next_command = CompatibilityCommand;
1192 strip_info->watchdog_doprobe = jiffies + 10 * HZ;
1193 strip_info->watchdog_doreset = jiffies + 1 * HZ;
1194
1195
1196 if (strip_info->user_baud > 38400) {
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206 if (strip_info->user_baud == tty_get_baud_rate(tty)) {
1207 static const char b0[] = "ate0q1s304=57600\r";
1208 static const char b1[] = "ate0q1s304=115200\r";
1209 static const StringDescriptor baudstring[2] =
1210 { {b0, sizeof(b0) - 1}
1211 , {b1, sizeof(b1) - 1}
1212 };
1213 set_baud(tty, 19200);
1214 if (strip_info->user_baud == 57600)
1215 s = baudstring[0];
1216 else if (strip_info->user_baud == 115200)
1217 s = baudstring[1];
1218 else
1219 s = baudstring[1];
1220 } else
1221 set_baud(tty, strip_info->user_baud);
1222 }
1223
1224 tty->ops->write(tty, s.string, s.length);
1225#ifdef EXT_COUNTERS
1226 strip_info->tx_ebytes += s.length;
1227#endif
1228}
1229
1230
1231
1232
1233
1234
1235static void strip_write_some_more(struct tty_struct *tty)
1236{
1237 struct strip *strip_info = (struct strip *) tty->disc_data;
1238
1239
1240 if (!strip_info || strip_info->magic != STRIP_MAGIC ||
1241 !netif_running(strip_info->dev))
1242 return;
1243
1244 if (strip_info->tx_left > 0) {
1245 int num_written =
1246 tty->ops->write(tty, strip_info->tx_head,
1247 strip_info->tx_left);
1248 strip_info->tx_left -= num_written;
1249 strip_info->tx_head += num_written;
1250#ifdef EXT_COUNTERS
1251 strip_info->tx_sbytes += num_written;
1252#endif
1253 } else {
1254
1255 tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
1256 strip_unlock(strip_info);
1257 }
1258}
1259
1260static __u8 *add_checksum(__u8 * buffer, __u8 * end)
1261{
1262 __u16 sum = 0;
1263 __u8 *p = buffer;
1264 while (p < end)
1265 sum += *p++;
1266 end[3] = hextable[sum & 0xF];
1267 sum >>= 4;
1268 end[2] = hextable[sum & 0xF];
1269 sum >>= 4;
1270 end[1] = hextable[sum & 0xF];
1271 sum >>= 4;
1272 end[0] = hextable[sum & 0xF];
1273 return (end + 4);
1274}
1275
1276static unsigned char *strip_make_packet(unsigned char *buffer,
1277 struct strip *strip_info,
1278 struct sk_buff *skb)
1279{
1280 __u8 *ptr = buffer;
1281 __u8 *stuffstate = NULL;
1282 STRIP_Header *header = (STRIP_Header *) skb->data;
1283 MetricomAddress haddr = header->dst_addr;
1284 int len = skb->len - sizeof(STRIP_Header);
1285 MetricomKey key;
1286
1287
1288
1289 if (header->protocol == htons(ETH_P_IP))
1290 key = SIP0Key;
1291 else if (header->protocol == htons(ETH_P_ARP))
1292 key = ARP0Key;
1293 else {
1294 printk(KERN_ERR
1295 "%s: strip_make_packet: Unknown packet type 0x%04X\n",
1296 strip_info->dev->name, ntohs(header->protocol));
1297 return (NULL);
1298 }
1299
1300 if (len > strip_info->mtu) {
1301 printk(KERN_ERR
1302 "%s: Dropping oversized transmit packet: %d bytes\n",
1303 strip_info->dev->name, len);
1304 return (NULL);
1305 }
1306
1307
1308
1309
1310
1311 if (!memcmp(haddr.c, strip_info->true_dev_addr.c, sizeof(haddr))) {
1312 printk(KERN_ERR "%s: Dropping packet addressed to self\n",
1313 strip_info->dev->name);
1314 return (NULL);
1315 }
1316
1317
1318
1319
1320
1321 if (haddr.c[0] == 0xFF) {
1322 __be32 brd = 0;
1323 struct in_device *in_dev;
1324
1325 rcu_read_lock();
1326 in_dev = __in_dev_get_rcu(strip_info->dev);
1327 if (in_dev == NULL) {
1328 rcu_read_unlock();
1329 return NULL;
1330 }
1331 if (in_dev->ifa_list)
1332 brd = in_dev->ifa_list->ifa_broadcast;
1333 rcu_read_unlock();
1334
1335
1336 if (!arp_query(haddr.c, brd, strip_info->dev)) {
1337 printk(KERN_ERR
1338 "%s: Unable to send packet (no broadcast hub configured)\n",
1339 strip_info->dev->name);
1340 return (NULL);
1341 }
1342
1343
1344
1345
1346 if (!memcmp
1347 (haddr.c, strip_info->true_dev_addr.c, sizeof(haddr)))
1348 return (NULL);
1349 }
1350
1351 *ptr++ = 0x0D;
1352 *ptr++ = '*';
1353 *ptr++ = hextable[haddr.c[2] >> 4];
1354 *ptr++ = hextable[haddr.c[2] & 0xF];
1355 *ptr++ = hextable[haddr.c[3] >> 4];
1356 *ptr++ = hextable[haddr.c[3] & 0xF];
1357 *ptr++ = '-';
1358 *ptr++ = hextable[haddr.c[4] >> 4];
1359 *ptr++ = hextable[haddr.c[4] & 0xF];
1360 *ptr++ = hextable[haddr.c[5] >> 4];
1361 *ptr++ = hextable[haddr.c[5] & 0xF];
1362 *ptr++ = '*';
1363 *ptr++ = key.c[0];
1364 *ptr++ = key.c[1];
1365 *ptr++ = key.c[2];
1366 *ptr++ = key.c[3];
1367
1368 ptr =
1369 StuffData(skb->data + sizeof(STRIP_Header), len, ptr,
1370 &stuffstate);
1371
1372 if (strip_info->firmware_level >= ChecksummedMessages)
1373 ptr = add_checksum(buffer + 1, ptr);
1374
1375 *ptr++ = 0x0D;
1376 return (ptr);
1377}
1378
1379static void strip_send(struct strip *strip_info, struct sk_buff *skb)
1380{
1381 MetricomAddress haddr;
1382 unsigned char *ptr = strip_info->tx_buff;
1383 int doreset = (long) jiffies - strip_info->watchdog_doreset >= 0;
1384 int doprobe = (long) jiffies - strip_info->watchdog_doprobe >= 0
1385 && !doreset;
1386 __be32 addr, brd;
1387
1388
1389
1390
1391 if (skb) {
1392 char *newptr = strip_make_packet(ptr, strip_info, skb);
1393 strip_info->tx_pps_count++;
1394 if (!newptr)
1395 strip_info->tx_dropped++;
1396 else {
1397 ptr = newptr;
1398 strip_info->sx_pps_count++;
1399 strip_info->tx_packets++;
1400#ifdef EXT_COUNTERS
1401 strip_info->tx_bytes += skb->len;
1402 strip_info->tx_rbytes += ptr - strip_info->tx_buff;
1403#endif
1404
1405
1406 }
1407 }
1408
1409
1410
1411
1412 if (doprobe) {
1413 StringDescriptor ts = CommandString[strip_info->next_command];
1414#if TICKLE_TIMERS
1415 {
1416 struct timeval tv;
1417 do_gettimeofday(&tv);
1418 printk(KERN_INFO "**** Sending tickle string %d at %02d.%06d\n",
1419 strip_info->next_command, tv.tv_sec % 100,
1420 tv.tv_usec);
1421 }
1422#endif
1423 if (ptr == strip_info->tx_buff)
1424 *ptr++ = 0x0D;
1425
1426 *ptr++ = '*';
1427 *ptr++ = '*';
1428
1429
1430 memcpy(ptr, ts.string, ts.length);
1431
1432
1433 if (strip_info->firmware_level < ChecksummedMessages)
1434 ptr += ts.length;
1435 else
1436 ptr = add_checksum(ptr, ptr + ts.length);
1437
1438 *ptr++ = 0x0D;
1439
1440
1441 if (strip_info->firmware_level >= StructuredMessages)
1442 if (++strip_info->next_command >=
1443 ARRAY_SIZE(CommandString))
1444 strip_info->next_command = 0;
1445#ifdef EXT_COUNTERS
1446 strip_info->tx_ebytes += ts.length;
1447#endif
1448 strip_info->watchdog_doprobe = jiffies + 10 * HZ;
1449 strip_info->watchdog_doreset = jiffies + 1 * HZ;
1450
1451 }
1452
1453
1454
1455
1456 strip_info->tx_head = strip_info->tx_buff;
1457 strip_info->tx_left = ptr - strip_info->tx_buff;
1458 strip_info->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
1459
1460
1461
1462
1463 if (strip_info->tx_size - strip_info->tx_left < 20)
1464 printk(KERN_ERR "%s: Sending%5d bytes;%5d bytes free.\n",
1465 strip_info->dev->name, strip_info->tx_left,
1466 strip_info->tx_size - strip_info->tx_left);
1467
1468
1469
1470
1471
1472 if (doreset) {
1473 ResetRadio(strip_info);
1474 return;
1475 }
1476
1477 if (1) {
1478 struct in_device *in_dev;
1479
1480 brd = addr = 0;
1481 rcu_read_lock();
1482 in_dev = __in_dev_get_rcu(strip_info->dev);
1483 if (in_dev) {
1484 if (in_dev->ifa_list) {
1485 brd = in_dev->ifa_list->ifa_broadcast;
1486 addr = in_dev->ifa_list->ifa_local;
1487 }
1488 }
1489 rcu_read_unlock();
1490 }
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507 if (strip_info->working
1508 && (long) jiffies - strip_info->gratuitous_arp >= 0
1509 && memcmp(strip_info->dev->dev_addr, zero_address.c,
1510 sizeof(zero_address))
1511 && arp_query(haddr.c, brd, strip_info->dev)) {
1512
1513
1514 strip_info->gratuitous_arp =
1515 jiffies + strip_info->arp_interval;
1516 strip_info->arp_interval *= 2;
1517 if (strip_info->arp_interval > MaxARPInterval)
1518 strip_info->arp_interval = MaxARPInterval;
1519 if (addr)
1520 arp_send(ARPOP_REPLY, ETH_P_ARP, addr,
1521 strip_info->dev,
1522 addr,
1523 NULL,
1524 strip_info->dev->dev_addr,
1525 strip_info->dev->dev_addr);
1526 }
1527
1528
1529
1530
1531 strip_write_some_more(strip_info->tty);
1532}
1533
1534
1535static int strip_xmit(struct sk_buff *skb, struct net_device *dev)
1536{
1537 struct strip *strip_info = netdev_priv(dev);
1538
1539 if (!netif_running(dev)) {
1540 printk(KERN_ERR "%s: xmit call when iface is down\n",
1541 dev->name);
1542 return (1);
1543 }
1544
1545 netif_stop_queue(dev);
1546
1547 del_timer(&strip_info->idle_timer);
1548
1549
1550 if (time_after(jiffies, strip_info->pps_timer + HZ)) {
1551 unsigned long t = jiffies - strip_info->pps_timer;
1552 unsigned long rx_pps_count = (strip_info->rx_pps_count * HZ * 8 + t / 2) / t;
1553 unsigned long tx_pps_count = (strip_info->tx_pps_count * HZ * 8 + t / 2) / t;
1554 unsigned long sx_pps_count = (strip_info->sx_pps_count * HZ * 8 + t / 2) / t;
1555
1556 strip_info->pps_timer = jiffies;
1557 strip_info->rx_pps_count = 0;
1558 strip_info->tx_pps_count = 0;
1559 strip_info->sx_pps_count = 0;
1560
1561 strip_info->rx_average_pps = (strip_info->rx_average_pps + rx_pps_count + 1) / 2;
1562 strip_info->tx_average_pps = (strip_info->tx_average_pps + tx_pps_count + 1) / 2;
1563 strip_info->sx_average_pps = (strip_info->sx_average_pps + sx_pps_count + 1) / 2;
1564
1565 if (rx_pps_count / 8 >= 10)
1566 printk(KERN_INFO "%s: WARNING: Receiving %ld packets per second.\n",
1567 strip_info->dev->name, rx_pps_count / 8);
1568 if (tx_pps_count / 8 >= 10)
1569 printk(KERN_INFO "%s: WARNING: Tx %ld packets per second.\n",
1570 strip_info->dev->name, tx_pps_count / 8);
1571 if (sx_pps_count / 8 >= 10)
1572 printk(KERN_INFO "%s: WARNING: Sending %ld packets per second.\n",
1573 strip_info->dev->name, sx_pps_count / 8);
1574 }
1575
1576 spin_lock_bh(&strip_lock);
1577
1578 strip_send(strip_info, skb);
1579
1580 spin_unlock_bh(&strip_lock);
1581
1582 if (skb)
1583 dev_kfree_skb(skb);
1584 return 0;
1585}
1586
1587
1588
1589
1590
1591
1592
1593static void strip_IdleTask(unsigned long parameter)
1594{
1595 strip_xmit(NULL, (struct net_device *) parameter);
1596}
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609static int strip_header(struct sk_buff *skb, struct net_device *dev,
1610 unsigned short type, const void *daddr,
1611 const void *saddr, unsigned len)
1612{
1613 struct strip *strip_info = netdev_priv(dev);
1614 STRIP_Header *header = (STRIP_Header *) skb_push(skb, sizeof(STRIP_Header));
1615
1616
1617
1618
1619 header->src_addr = strip_info->true_dev_addr;
1620 header->protocol = htons(type);
1621
1622
1623
1624 if (!daddr)
1625 return (-dev->hard_header_len);
1626
1627 header->dst_addr = *(MetricomAddress *) daddr;
1628 return (dev->hard_header_len);
1629}
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639static int strip_rebuild_header(struct sk_buff *skb)
1640{
1641#ifdef CONFIG_INET
1642 STRIP_Header *header = (STRIP_Header *) skb->data;
1643
1644
1645
1646 return arp_find(header->dst_addr.c, skb) ? 1 : 0;
1647#else
1648 return 0;
1649#endif
1650}
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660static void get_radio_version(struct strip *strip_info, __u8 * ptr, __u8 * end)
1661{
1662 __u8 *p, *value_begin, *value_end;
1663 int len;
1664
1665
1666 p = ptr;
1667 while (p < end && *p != 10)
1668 p++;
1669 if (p >= end)
1670 return;
1671 p++;
1672 value_begin = p;
1673
1674
1675 while (p < end && *p != 10)
1676 p++;
1677 if (p >= end)
1678 return;
1679 value_end = p;
1680 p++;
1681
1682 len = value_end - value_begin;
1683 len = min_t(int, len, sizeof(FirmwareVersion) - 1);
1684 if (strip_info->firmware_version.c[0] == 0)
1685 printk(KERN_INFO "%s: Radio Firmware: %.*s\n",
1686 strip_info->dev->name, len, value_begin);
1687 sprintf(strip_info->firmware_version.c, "%.*s", len, value_begin);
1688
1689
1690 while (p < end && *p != ':')
1691 p++;
1692 if (p >= end)
1693 return;
1694
1695 p += 2;
1696 len = sizeof(SerialNumber) - 1;
1697 if (p + len <= end) {
1698 sprintf(strip_info->serial_number.c, "%.*s", len, p);
1699 } else {
1700 printk(KERN_DEBUG
1701 "STRIP: radio serial number shorter (%zd) than expected (%d)\n",
1702 end - p, len);
1703 }
1704}
1705
1706
1707
1708
1709
1710static void get_radio_voltage(struct strip *strip_info, __u8 * ptr, __u8 * end)
1711{
1712 int len;
1713
1714 len = sizeof(BatteryVoltage) - 1;
1715 if (ptr + len <= end) {
1716 sprintf(strip_info->battery_voltage.c, "%.*s", len, ptr);
1717 } else {
1718 printk(KERN_DEBUG
1719 "STRIP: radio voltage string shorter (%zd) than expected (%d)\n",
1720 end - ptr, len);
1721 }
1722}
1723
1724
1725
1726
1727
1728static void get_radio_neighbours(MetricomNodeTable * table, __u8 * ptr, __u8 * end)
1729{
1730 table->num_nodes = 0;
1731 while (ptr < end && table->num_nodes < NODE_TABLE_SIZE) {
1732 MetricomNode *node = &table->node[table->num_nodes++];
1733 char *dst = node->c, *limit = dst + sizeof(*node) - 1;
1734 while (ptr < end && *ptr <= 32)
1735 ptr++;
1736 while (ptr < end && dst < limit && *ptr != 10)
1737 *dst++ = *ptr++;
1738 *dst++ = 0;
1739 while (ptr < end && ptr[-1] != 10)
1740 ptr++;
1741 }
1742 do_gettimeofday(&table->timestamp);
1743}
1744
1745static int get_radio_address(struct strip *strip_info, __u8 * p)
1746{
1747 MetricomAddress addr;
1748
1749 if (string_to_radio_address(&addr, p))
1750 return (1);
1751
1752
1753 if (memcmp(strip_info->true_dev_addr.c, addr.c, sizeof(addr))) {
1754 MetricomAddressString addr_string;
1755 radio_address_to_string(&addr, &addr_string);
1756 printk(KERN_INFO "%s: Radio address = %s\n",
1757 strip_info->dev->name, addr_string.c);
1758 strip_info->true_dev_addr = addr;
1759 if (!strip_info->manual_dev_addr)
1760 *(MetricomAddress *) strip_info->dev->dev_addr =
1761 addr;
1762
1763 strip_info->gratuitous_arp = jiffies + 15 * HZ;
1764 strip_info->arp_interval = 1 * HZ;
1765 }
1766 return (0);
1767}
1768
1769static int verify_checksum(struct strip *strip_info)
1770{
1771 __u8 *p = strip_info->sx_buff;
1772 __u8 *end = strip_info->sx_buff + strip_info->sx_count - 4;
1773 u_short sum =
1774 (READHEX16(end[0]) << 12) | (READHEX16(end[1]) << 8) |
1775 (READHEX16(end[2]) << 4) | (READHEX16(end[3]));
1776 while (p < end)
1777 sum -= *p++;
1778 if (sum == 0 && strip_info->firmware_level == StructuredMessages) {
1779 strip_info->firmware_level = ChecksummedMessages;
1780 printk(KERN_INFO "%s: Radio provides message checksums\n",
1781 strip_info->dev->name);
1782 }
1783 return (sum == 0);
1784}
1785
1786static void RecvErr(char *msg, struct strip *strip_info)
1787{
1788 __u8 *ptr = strip_info->sx_buff;
1789 __u8 *end = strip_info->sx_buff + strip_info->sx_count;
1790 DumpData(msg, strip_info, ptr, end);
1791 strip_info->rx_errors++;
1792}
1793
1794static void RecvErr_Message(struct strip *strip_info, __u8 * sendername,
1795 const __u8 * msg, u_long len)
1796{
1797 if (has_prefix(msg, len, "001")) {
1798 RecvErr("Error Msg:", strip_info);
1799 printk(KERN_INFO "%s: Radio %s is not in StarMode\n",
1800 strip_info->dev->name, sendername);
1801 }
1802
1803 else if (has_prefix(msg, len, "002")) {
1804
1805 }
1806
1807 else if (has_prefix(msg, len, "003")) {
1808 RecvErr("Error Msg:", strip_info);
1809 printk(KERN_INFO "%s: Destination radio name is unknown\n",
1810 strip_info->dev->name);
1811 }
1812
1813 else if (has_prefix(msg, len, "004")) {
1814 strip_info->watchdog_doreset = jiffies + LongTime;
1815#if TICKLE_TIMERS
1816 {
1817 struct timeval tv;
1818 do_gettimeofday(&tv);
1819 printk(KERN_INFO
1820 "**** Got ERR_004 response at %02d.%06d\n",
1821 tv.tv_sec % 100, tv.tv_usec);
1822 }
1823#endif
1824 if (!strip_info->working) {
1825 strip_info->working = TRUE;
1826 printk(KERN_INFO "%s: Radio now in starmode\n",
1827 strip_info->dev->name);
1828
1829
1830
1831
1832 strip_info->watchdog_doprobe = jiffies;
1833 }
1834 if (strip_info->firmware_level == NoStructure && sendername) {
1835 strip_info->firmware_level = StructuredMessages;
1836 strip_info->next_command = 0;
1837 printk(KERN_INFO
1838 "%s: Radio provides structured messages\n",
1839 strip_info->dev->name);
1840 }
1841 if (strip_info->firmware_level >= StructuredMessages) {
1842
1843
1844
1845
1846
1847 verify_checksum(strip_info);
1848
1849
1850
1851
1852 if (!GOT_ALL_RADIO_INFO(strip_info))
1853 strip_info->watchdog_doprobe = jiffies;
1854 }
1855 }
1856
1857 else if (has_prefix(msg, len, "005"))
1858 RecvErr("Error Msg:", strip_info);
1859
1860 else if (has_prefix(msg, len, "006"))
1861 RecvErr("Error Msg:", strip_info);
1862
1863 else if (has_prefix(msg, len, "007")) {
1864 RecvErr("Error Msg:", strip_info);
1865 printk(KERN_ERR
1866 "%s: Error! Packet size too big for radio.\n",
1867 strip_info->dev->name);
1868 }
1869
1870 else if (has_prefix(msg, len, "008")) {
1871 RecvErr("Error Msg:", strip_info);
1872 printk(KERN_ERR
1873 "%s: Radio name contains illegal character\n",
1874 strip_info->dev->name);
1875 }
1876
1877 else if (has_prefix(msg, len, "009"))
1878 RecvErr("Error Msg:", strip_info);
1879
1880 else if (has_prefix(msg, len, "010"))
1881 RecvErr("Error Msg:", strip_info);
1882
1883 else if (has_prefix(msg, len, "011"))
1884 RecvErr("Error Msg:", strip_info);
1885
1886 else if (has_prefix(msg, len, "012"))
1887 RecvErr("Error Msg:", strip_info);
1888
1889 else
1890 RecvErr("Error Msg:", strip_info);
1891}
1892
1893static void process_AT_response(struct strip *strip_info, __u8 * ptr,
1894 __u8 * end)
1895{
1896 u_long len;
1897 __u8 *p = ptr;
1898 while (p < end && p[-1] != 10)
1899 p++;
1900
1901 len = p - ptr;
1902
1903#if TICKLE_TIMERS
1904 {
1905 struct timeval tv;
1906 do_gettimeofday(&tv);
1907 printk(KERN_INFO "**** Got AT response %.7s at %02d.%06d\n",
1908 ptr, tv.tv_sec % 100, tv.tv_usec);
1909 }
1910#endif
1911
1912 if (has_prefix(ptr, len, "ATS300?"))
1913 get_radio_version(strip_info, p, end);
1914 else if (has_prefix(ptr, len, "ATS305?"))
1915 get_radio_address(strip_info, p);
1916 else if (has_prefix(ptr, len, "ATS311?"))
1917 get_radio_neighbours(&strip_info->poletops, p, end);
1918 else if (has_prefix(ptr, len, "ATS319=7"))
1919 verify_checksum(strip_info);
1920 else if (has_prefix(ptr, len, "ATS325?"))
1921 get_radio_voltage(strip_info, p, end);
1922 else if (has_prefix(ptr, len, "AT~LA"))
1923 get_radio_neighbours(&strip_info->portables, p, end);
1924 else
1925 RecvErr("Unknown AT Response:", strip_info);
1926}
1927
1928static void process_ACK(struct strip *strip_info, __u8 * ptr, __u8 * end)
1929{
1930
1931}
1932
1933static void process_Info(struct strip *strip_info, __u8 * ptr, __u8 * end)
1934{
1935 if (ptr + 16 > end)
1936 RecvErr("Bad Info Msg:", strip_info);
1937}
1938
1939static struct net_device *get_strip_dev(struct strip *strip_info)
1940{
1941
1942
1943
1944 if (strip_info->manual_dev_addr &&
1945 !memcmp(strip_info->dev->dev_addr, zero_address.c,
1946 sizeof(zero_address))
1947 && memcmp(&strip_info->true_dev_addr, zero_address.c,
1948 sizeof(zero_address))) {
1949 struct net_device *dev;
1950 read_lock_bh(&dev_base_lock);
1951 for_each_netdev(&init_net, dev) {
1952 if (dev->type == strip_info->dev->type &&
1953 !memcmp(dev->dev_addr,
1954 &strip_info->true_dev_addr,
1955 sizeof(MetricomAddress))) {
1956 printk(KERN_INFO
1957 "%s: Transferred packet ownership to %s.\n",
1958 strip_info->dev->name, dev->name);
1959 read_unlock_bh(&dev_base_lock);
1960 return (dev);
1961 }
1962 }
1963 read_unlock_bh(&dev_base_lock);
1964 }
1965 return (strip_info->dev);
1966}
1967
1968
1969
1970
1971
1972static void deliver_packet(struct strip *strip_info, STRIP_Header * header,
1973 __u16 packetlen)
1974{
1975 struct sk_buff *skb = dev_alloc_skb(sizeof(STRIP_Header) + packetlen);
1976 if (!skb) {
1977 printk(KERN_ERR "%s: memory squeeze, dropping packet.\n",
1978 strip_info->dev->name);
1979 strip_info->rx_dropped++;
1980 } else {
1981 memcpy(skb_put(skb, sizeof(STRIP_Header)), header,
1982 sizeof(STRIP_Header));
1983 memcpy(skb_put(skb, packetlen), strip_info->rx_buff,
1984 packetlen);
1985 skb->dev = get_strip_dev(strip_info);
1986 skb->protocol = header->protocol;
1987 skb_reset_mac_header(skb);
1988
1989
1990
1991
1992 skb_pull(skb, sizeof(STRIP_Header));
1993
1994
1995 strip_info->rx_packets++;
1996 strip_info->rx_pps_count++;
1997#ifdef EXT_COUNTERS
1998 strip_info->rx_bytes += packetlen;
1999#endif
2000 skb->dev->last_rx = jiffies;
2001 netif_rx(skb);
2002 }
2003}
2004
2005static void process_IP_packet(struct strip *strip_info,
2006 STRIP_Header * header, __u8 * ptr,
2007 __u8 * end)
2008{
2009 __u16 packetlen;
2010
2011
2012 ptr = UnStuffData(ptr, end, strip_info->rx_buff, 4);
2013 if (!ptr) {
2014 RecvErr("IP Packet too short", strip_info);
2015 return;
2016 }
2017
2018 packetlen = ((__u16) strip_info->rx_buff[2] << 8) | strip_info->rx_buff[3];
2019
2020 if (packetlen > MAX_RECV_MTU) {
2021 printk(KERN_INFO "%s: Dropping oversized received IP packet: %d bytes\n",
2022 strip_info->dev->name, packetlen);
2023 strip_info->rx_dropped++;
2024 return;
2025 }
2026
2027
2028
2029
2030 ptr =
2031 UnStuffData(ptr, end, strip_info->rx_buff + 4, packetlen - 4);
2032 if (!ptr) {
2033 RecvErr("IP Packet too short", strip_info);
2034 return;
2035 }
2036
2037 if (ptr < end) {
2038 RecvErr("IP Packet too long", strip_info);
2039 return;
2040 }
2041
2042 header->protocol = htons(ETH_P_IP);
2043
2044 deliver_packet(strip_info, header, packetlen);
2045}
2046
2047static void process_ARP_packet(struct strip *strip_info,
2048 STRIP_Header * header, __u8 * ptr,
2049 __u8 * end)
2050{
2051 __u16 packetlen;
2052 struct arphdr *arphdr = (struct arphdr *) strip_info->rx_buff;
2053
2054
2055 ptr = UnStuffData(ptr, end, strip_info->rx_buff, 8);
2056 if (!ptr) {
2057 RecvErr("ARP Packet too short", strip_info);
2058 return;
2059 }
2060
2061 packetlen = 8 + (arphdr->ar_hln + arphdr->ar_pln) * 2;
2062
2063 if (packetlen > MAX_RECV_MTU) {
2064 printk(KERN_INFO
2065 "%s: Dropping oversized received ARP packet: %d bytes\n",
2066 strip_info->dev->name, packetlen);
2067 strip_info->rx_dropped++;
2068 return;
2069 }
2070
2071
2072
2073
2074
2075
2076 ptr =
2077 UnStuffData(ptr, end, strip_info->rx_buff + 8, packetlen - 8);
2078 if (!ptr) {
2079 RecvErr("ARP Packet too short", strip_info);
2080 return;
2081 }
2082
2083 if (ptr < end) {
2084 RecvErr("ARP Packet too long", strip_info);
2085 return;
2086 }
2087
2088 header->protocol = htons(ETH_P_ARP);
2089
2090 deliver_packet(strip_info, header, packetlen);
2091}
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101static void process_text_message(struct strip *strip_info)
2102{
2103 __u8 *msg = strip_info->sx_buff;
2104 int len = strip_info->sx_count;
2105
2106
2107
2108 if (len == 9 && get_radio_address(strip_info, msg) == 0)
2109 return;
2110
2111 if (text_equal(msg, len, "OK"))
2112 return;
2113 if (text_equal(msg, len, "ERROR"))
2114 return;
2115 if (has_prefix(msg, len, "ate0q1"))
2116 return;
2117
2118
2119
2120 if (has_prefix(msg, len, "ERR_")) {
2121 RecvErr_Message(strip_info, NULL, &msg[4], len - 4);
2122 return;
2123 }
2124
2125 RecvErr("No initial *", strip_info);
2126}
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137static void process_message(struct strip *strip_info)
2138{
2139 STRIP_Header header = { zero_address, zero_address, 0 };
2140 __u8 *ptr = strip_info->sx_buff;
2141 __u8 *end = strip_info->sx_buff + strip_info->sx_count;
2142 __u8 sendername[32], *sptr = sendername;
2143 MetricomKey key;
2144
2145
2146
2147
2148 if (*ptr == '*')
2149 ptr++;
2150 else {
2151 process_text_message(strip_info);
2152 return;
2153 }
2154
2155
2156 while (ptr < end && *ptr != '*'
2157 && sptr < ARRAY_END(sendername) - 1)
2158 *sptr++ = *ptr++;
2159 *sptr = 0;
2160
2161
2162 if (ptr >= end || *ptr != '*') {
2163 RecvErr("No second *", strip_info);
2164 return;
2165 }
2166 ptr++;
2167
2168
2169
2170 if (!strcmp(sendername, "&COMMAND")) {
2171 strip_info->firmware_level = NoStructure;
2172 strip_info->next_command = CompatibilityCommand;
2173 return;
2174 }
2175
2176 if (ptr + 4 > end) {
2177 RecvErr("No proto key", strip_info);
2178 return;
2179 }
2180
2181
2182 key.c[0] = *ptr++;
2183 key.c[1] = *ptr++;
2184 key.c[2] = *ptr++;
2185 key.c[3] = *ptr++;
2186
2187
2188 if (strip_info->firmware_level >= ChecksummedMessages) {
2189 end -= 4;
2190 if (ptr > end) {
2191 RecvErr("Missing Checksum", strip_info);
2192 return;
2193 }
2194 if (!verify_checksum(strip_info)) {
2195 RecvErr("Bad Checksum", strip_info);
2196 return;
2197 }
2198 }
2199
2200
2201
2202
2203
2204
2205
2206
2207 header.dst_addr = strip_info->true_dev_addr;
2208 string_to_radio_address(&header.src_addr, sendername);
2209
2210#ifdef EXT_COUNTERS
2211 if (key.l == SIP0Key.l) {
2212 strip_info->rx_rbytes += (end - ptr);
2213 process_IP_packet(strip_info, &header, ptr, end);
2214 } else if (key.l == ARP0Key.l) {
2215 strip_info->rx_rbytes += (end - ptr);
2216 process_ARP_packet(strip_info, &header, ptr, end);
2217 } else if (key.l == ATR_Key.l) {
2218 strip_info->rx_ebytes += (end - ptr);
2219 process_AT_response(strip_info, ptr, end);
2220 } else if (key.l == ACK_Key.l) {
2221 strip_info->rx_ebytes += (end - ptr);
2222 process_ACK(strip_info, ptr, end);
2223 } else if (key.l == INF_Key.l) {
2224 strip_info->rx_ebytes += (end - ptr);
2225 process_Info(strip_info, ptr, end);
2226 } else if (key.l == ERR_Key.l) {
2227 strip_info->rx_ebytes += (end - ptr);
2228 RecvErr_Message(strip_info, sendername, ptr, end - ptr);
2229 } else
2230 RecvErr("Unrecognized protocol key", strip_info);
2231#else
2232 if (key.l == SIP0Key.l)
2233 process_IP_packet(strip_info, &header, ptr, end);
2234 else if (key.l == ARP0Key.l)
2235 process_ARP_packet(strip_info, &header, ptr, end);
2236 else if (key.l == ATR_Key.l)
2237 process_AT_response(strip_info, ptr, end);
2238 else if (key.l == ACK_Key.l)
2239 process_ACK(strip_info, ptr, end);
2240 else if (key.l == INF_Key.l)
2241 process_Info(strip_info, ptr, end);
2242 else if (key.l == ERR_Key.l)
2243 RecvErr_Message(strip_info, sendername, ptr, end - ptr);
2244 else
2245 RecvErr("Unrecognized protocol key", strip_info);
2246#endif
2247}
2248
2249#define TTYERROR(X) ((X) == TTY_BREAK ? "Break" : \
2250 (X) == TTY_FRAME ? "Framing Error" : \
2251 (X) == TTY_PARITY ? "Parity Error" : \
2252 (X) == TTY_OVERRUN ? "Hardware Overrun" : "Unknown Error")
2253
2254
2255
2256
2257
2258
2259
2260
2261static void strip_receive_buf(struct tty_struct *tty, const unsigned char *cp,
2262 char *fp, int count)
2263{
2264 struct strip *strip_info = (struct strip *) tty->disc_data;
2265 const unsigned char *end = cp + count;
2266
2267 if (!strip_info || strip_info->magic != STRIP_MAGIC
2268 || !netif_running(strip_info->dev))
2269 return;
2270
2271 spin_lock_bh(&strip_lock);
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282#ifdef EXT_COUNTERS
2283 strip_info->rx_sbytes += count;
2284#endif
2285
2286
2287 while (cp < end) {
2288 if (fp && *fp)
2289 printk(KERN_INFO "%s: %s on serial port\n",
2290 strip_info->dev->name, TTYERROR(*fp));
2291 if (fp && *fp++ && !strip_info->discard) {
2292
2293 strip_info->discard = strip_info->sx_count;
2294 strip_info->rx_errors++;
2295 }
2296
2297
2298 if (strip_info->sx_count > 0 || *cp >= ' ') {
2299 if (*cp == 0x0D) {
2300 if (strip_info->sx_count > 3000)
2301 printk(KERN_INFO
2302 "%s: Cut a %d byte packet (%zd bytes remaining)%s\n",
2303 strip_info->dev->name,
2304 strip_info->sx_count,
2305 end - cp - 1,
2306 strip_info->
2307 discard ? " (discarded)" :
2308 "");
2309 if (strip_info->sx_count >
2310 strip_info->sx_size) {
2311 strip_info->rx_over_errors++;
2312 printk(KERN_INFO
2313 "%s: sx_buff overflow (%d bytes total)\n",
2314 strip_info->dev->name,
2315 strip_info->sx_count);
2316 } else if (strip_info->discard)
2317 printk(KERN_INFO
2318 "%s: Discarding bad packet (%d/%d)\n",
2319 strip_info->dev->name,
2320 strip_info->discard,
2321 strip_info->sx_count);
2322 else
2323 process_message(strip_info);
2324 strip_info->discard = 0;
2325 strip_info->sx_count = 0;
2326 } else {
2327
2328 if (strip_info->sx_count <
2329 strip_info->sx_size)
2330 strip_info->sx_buff[strip_info->
2331 sx_count] =
2332 *cp;
2333 strip_info->sx_count++;
2334 }
2335 }
2336 cp++;
2337 }
2338 spin_unlock_bh(&strip_lock);
2339}
2340
2341
2342
2343
2344
2345static int set_mac_address(struct strip *strip_info,
2346 MetricomAddress * addr)
2347{
2348
2349
2350
2351
2352
2353
2354 strip_info->manual_dev_addr =
2355 memcmp(addr->c, broadcast_address.c,
2356 sizeof(broadcast_address));
2357 if (strip_info->manual_dev_addr)
2358 *(MetricomAddress *) strip_info->dev->dev_addr = *addr;
2359 else
2360 *(MetricomAddress *) strip_info->dev->dev_addr =
2361 strip_info->true_dev_addr;
2362 return 0;
2363}
2364
2365static int strip_set_mac_address(struct net_device *dev, void *addr)
2366{
2367 struct strip *strip_info = netdev_priv(dev);
2368 struct sockaddr *sa = addr;
2369 printk(KERN_INFO "%s: strip_set_dev_mac_address called\n", dev->name);
2370 set_mac_address(strip_info, (MetricomAddress *) sa->sa_data);
2371 return 0;
2372}
2373
2374static struct net_device_stats *strip_get_stats(struct net_device *dev)
2375{
2376 struct strip *strip_info = netdev_priv(dev);
2377 static struct net_device_stats stats;
2378
2379 memset(&stats, 0, sizeof(struct net_device_stats));
2380
2381 stats.rx_packets = strip_info->rx_packets;
2382 stats.tx_packets = strip_info->tx_packets;
2383 stats.rx_dropped = strip_info->rx_dropped;
2384 stats.tx_dropped = strip_info->tx_dropped;
2385 stats.tx_errors = strip_info->tx_errors;
2386 stats.rx_errors = strip_info->rx_errors;
2387 stats.rx_over_errors = strip_info->rx_over_errors;
2388 return (&stats);
2389}
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419static int strip_open_low(struct net_device *dev)
2420{
2421 struct strip *strip_info = netdev_priv(dev);
2422
2423 if (strip_info->tty == NULL)
2424 return (-ENODEV);
2425
2426 if (!allocate_buffers(strip_info, dev->mtu))
2427 return (-ENOMEM);
2428
2429 strip_info->sx_count = 0;
2430 strip_info->tx_left = 0;
2431
2432 strip_info->discard = 0;
2433 strip_info->working = FALSE;
2434 strip_info->firmware_level = NoStructure;
2435 strip_info->next_command = CompatibilityCommand;
2436 strip_info->user_baud = tty_get_baud_rate(strip_info->tty);
2437
2438 printk(KERN_INFO "%s: Initializing Radio.\n",
2439 strip_info->dev->name);
2440 ResetRadio(strip_info);
2441 strip_info->idle_timer.expires = jiffies + 1 * HZ;
2442 add_timer(&strip_info->idle_timer);
2443 netif_wake_queue(dev);
2444 return (0);
2445}
2446
2447
2448
2449
2450
2451
2452static int strip_close_low(struct net_device *dev)
2453{
2454 struct strip *strip_info = netdev_priv(dev);
2455
2456 if (strip_info->tty == NULL)
2457 return -EBUSY;
2458 strip_info->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
2459
2460 netif_stop_queue(dev);
2461
2462
2463
2464
2465 kfree(strip_info->rx_buff);
2466 strip_info->rx_buff = NULL;
2467 kfree(strip_info->sx_buff);
2468 strip_info->sx_buff = NULL;
2469 kfree(strip_info->tx_buff);
2470 strip_info->tx_buff = NULL;
2471
2472 del_timer(&strip_info->idle_timer);
2473 return 0;
2474}
2475
2476static const struct header_ops strip_header_ops = {
2477 .create = strip_header,
2478 .rebuild = strip_rebuild_header,
2479};
2480
2481
2482
2483
2484
2485
2486static void strip_dev_setup(struct net_device *dev)
2487{
2488
2489
2490
2491
2492 dev->trans_start = 0;
2493 dev->last_rx = 0;
2494 dev->tx_queue_len = 30;
2495
2496 dev->flags = 0;
2497 dev->mtu = DEFAULT_STRIP_MTU;
2498 dev->type = ARPHRD_METRICOM;
2499 dev->hard_header_len = sizeof(STRIP_Header);
2500
2501
2502
2503
2504 *(MetricomAddress *) & dev->broadcast = broadcast_address;
2505 dev->dev_addr[0] = 0;
2506 dev->addr_len = sizeof(MetricomAddress);
2507
2508
2509
2510
2511
2512 dev->open = strip_open_low;
2513 dev->stop = strip_close_low;
2514 dev->hard_start_xmit = strip_xmit;
2515 dev->header_ops = &strip_header_ops;
2516
2517 dev->set_mac_address = strip_set_mac_address;
2518 dev->get_stats = strip_get_stats;
2519 dev->change_mtu = strip_change_mtu;
2520}
2521
2522
2523
2524
2525
2526static void strip_free(struct strip *strip_info)
2527{
2528 spin_lock_bh(&strip_lock);
2529 list_del_rcu(&strip_info->list);
2530 spin_unlock_bh(&strip_lock);
2531
2532 strip_info->magic = 0;
2533
2534 free_netdev(strip_info->dev);
2535}
2536
2537
2538
2539
2540
2541static struct strip *strip_alloc(void)
2542{
2543 struct list_head *n;
2544 struct net_device *dev;
2545 struct strip *strip_info;
2546
2547 dev = alloc_netdev(sizeof(struct strip), "st%d",
2548 strip_dev_setup);
2549
2550 if (!dev)
2551 return NULL;
2552
2553
2554 strip_info = netdev_priv(dev);
2555 strip_info->dev = dev;
2556
2557 strip_info->magic = STRIP_MAGIC;
2558 strip_info->tty = NULL;
2559
2560 strip_info->gratuitous_arp = jiffies + LongTime;
2561 strip_info->arp_interval = 0;
2562 init_timer(&strip_info->idle_timer);
2563 strip_info->idle_timer.data = (long) dev;
2564 strip_info->idle_timer.function = strip_IdleTask;
2565
2566
2567 spin_lock_bh(&strip_lock);
2568 rescan:
2569
2570
2571
2572
2573
2574 list_for_each(n, &strip_list) {
2575 struct strip *s = hlist_entry(n, struct strip, list);
2576
2577 if (s->dev->base_addr == dev->base_addr) {
2578 ++dev->base_addr;
2579 goto rescan;
2580 }
2581 }
2582
2583 sprintf(dev->name, "st%ld", dev->base_addr);
2584
2585 list_add_tail_rcu(&strip_info->list, &strip_list);
2586 spin_unlock_bh(&strip_lock);
2587
2588 return strip_info;
2589}
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599static int strip_open(struct tty_struct *tty)
2600{
2601 struct strip *strip_info = (struct strip *) tty->disc_data;
2602
2603
2604
2605
2606
2607 if (strip_info && strip_info->magic == STRIP_MAGIC)
2608 return -EEXIST;
2609
2610
2611
2612
2613
2614 if (tty->ops->write == NULL || tty->ops->set_termios == NULL)
2615 return -EOPNOTSUPP;
2616
2617
2618
2619
2620 if ((strip_info = strip_alloc()) == NULL)
2621 return -ENFILE;
2622
2623
2624
2625
2626
2627
2628 if (register_netdev(strip_info->dev) != 0) {
2629 printk(KERN_ERR "strip: register_netdev() failed.\n");
2630 strip_free(strip_info);
2631 return -ENFILE;
2632 }
2633
2634 strip_info->tty = tty;
2635 tty->disc_data = strip_info;
2636 tty->receive_room = 65536;
2637
2638 tty_driver_flush_buffer(tty);
2639
2640
2641
2642
2643
2644 strip_info->dev->type = ARPHRD_METRICOM;
2645
2646
2647
2648
2649
2650 tty->termios->c_iflag |= IGNBRK | IGNPAR;
2651 tty->termios->c_cflag |= CLOCAL;
2652 tty->termios->c_cflag &= ~HUPCL;
2653
2654 printk(KERN_INFO "STRIP: device \"%s\" activated\n",
2655 strip_info->dev->name);
2656
2657
2658
2659
2660 return (strip_info->dev->base_addr);
2661}
2662
2663
2664
2665
2666
2667
2668
2669
2670static void strip_close(struct tty_struct *tty)
2671{
2672 struct strip *strip_info = (struct strip *) tty->disc_data;
2673
2674
2675
2676
2677
2678 if (!strip_info || strip_info->magic != STRIP_MAGIC)
2679 return;
2680
2681 unregister_netdev(strip_info->dev);
2682
2683 tty->disc_data = NULL;
2684 strip_info->tty = NULL;
2685 printk(KERN_INFO "STRIP: device \"%s\" closed down\n",
2686 strip_info->dev->name);
2687 strip_free(strip_info);
2688 tty->disc_data = NULL;
2689}
2690
2691
2692
2693
2694
2695static int strip_ioctl(struct tty_struct *tty, struct file *file,
2696 unsigned int cmd, unsigned long arg)
2697{
2698 struct strip *strip_info = (struct strip *) tty->disc_data;
2699
2700
2701
2702
2703
2704 if (!strip_info || strip_info->magic != STRIP_MAGIC)
2705 return -EINVAL;
2706
2707 switch (cmd) {
2708 case SIOCGIFNAME:
2709 if(copy_to_user((void __user *) arg, strip_info->dev->name, strlen(strip_info->dev->name) + 1))
2710 return -EFAULT;
2711 break;
2712 case SIOCSIFHWADDR:
2713 {
2714 MetricomAddress addr;
2715
2716 if(copy_from_user(&addr, (void __user *) arg, sizeof(MetricomAddress)))
2717 return -EFAULT;
2718 return set_mac_address(strip_info, &addr);
2719 }
2720 default:
2721 return tty_mode_ioctl(tty, file, cmd, arg);
2722 break;
2723 }
2724 return 0;
2725}
2726
2727
2728
2729
2730
2731static struct tty_ldisc_ops strip_ldisc = {
2732 .magic = TTY_LDISC_MAGIC,
2733 .name = "strip",
2734 .owner = THIS_MODULE,
2735 .open = strip_open,
2736 .close = strip_close,
2737 .ioctl = strip_ioctl,
2738 .receive_buf = strip_receive_buf,
2739 .write_wakeup = strip_write_some_more,
2740};
2741
2742
2743
2744
2745
2746
2747
2748static char signon[] __initdata =
2749 KERN_INFO "STRIP: Version %s (unlimited channels)\n";
2750
2751static int __init strip_init_driver(void)
2752{
2753 int status;
2754
2755 printk(signon, StripVersion);
2756
2757
2758
2759
2760
2761 if ((status = tty_register_ldisc(N_STRIP, &strip_ldisc)))
2762 printk(KERN_ERR "STRIP: can't register line discipline (err = %d)\n",
2763 status);
2764
2765
2766
2767
2768 proc_net_fops_create(&init_net, "strip", S_IFREG | S_IRUGO, &strip_seq_fops);
2769
2770 return status;
2771}
2772
2773module_init(strip_init_driver);
2774
2775static const char signoff[] __exitdata =
2776 KERN_INFO "STRIP: Module Unloaded\n";
2777
2778static void __exit strip_exit_driver(void)
2779{
2780 int i;
2781 struct list_head *p,*n;
2782
2783
2784 list_for_each_safe(p, n, &strip_list) {
2785 struct strip *s = list_entry(p, struct strip, list);
2786 strip_free(s);
2787 }
2788
2789
2790 proc_net_remove(&init_net, "strip");
2791
2792 if ((i = tty_unregister_ldisc(N_STRIP)))
2793 printk(KERN_ERR "STRIP: can't unregister line discipline (err = %d)\n", i);
2794
2795 printk(signoff);
2796}
2797
2798module_exit(strip_exit_driver);
2799
2800MODULE_AUTHOR("Stuart Cheshire <cheshire@cs.stanford.edu>");
2801MODULE_DESCRIPTION("Starmode Radio IP (STRIP) Device Driver");
2802MODULE_LICENSE("Dual BSD/GPL");
2803
2804MODULE_SUPPORTED_DEVICE("Starmode Radio IP (STRIP) modem");