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 __acquires(RCU)
954{
955 rcu_read_lock();
956 return *pos ? strip_get_idx(*pos - 1) : SEQ_START_TOKEN;
957}
958
959static void *strip_seq_next(struct seq_file *seq, void *v, loff_t *pos)
960{
961 struct list_head *l;
962 struct strip *s;
963
964 ++*pos;
965 if (v == SEQ_START_TOKEN)
966 return strip_get_idx(1);
967
968 s = v;
969 l = &s->list;
970 list_for_each_continue_rcu(l, &strip_list) {
971 return list_entry(l, struct strip, list);
972 }
973 return NULL;
974}
975
976static void strip_seq_stop(struct seq_file *seq, void *v)
977 __releases(RCU)
978{
979 rcu_read_unlock();
980}
981
982static void strip_seq_neighbours(struct seq_file *seq,
983 const MetricomNodeTable * table,
984 const char *title)
985{
986
987
988 struct timeval t;
989
990 do {
991 int i;
992 t = table->timestamp;
993 if (table->num_nodes)
994 seq_printf(seq, "\n %s\n", title);
995 for (i = 0; i < table->num_nodes; i++) {
996 MetricomNode node;
997
998 spin_lock_bh(&strip_lock);
999 node = table->node[i];
1000 spin_unlock_bh(&strip_lock);
1001 seq_printf(seq, " %s\n", node.c);
1002 }
1003 } while (table->timestamp.tv_sec != t.tv_sec
1004 || table->timestamp.tv_usec != t.tv_usec);
1005}
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017static void strip_seq_status_info(struct seq_file *seq,
1018 const struct strip *strip_info)
1019{
1020 char temp[32];
1021 MetricomAddressString addr_string;
1022
1023
1024
1025 int tx_left = strip_info->tx_left;
1026 unsigned long rx_average_pps = strip_info->rx_average_pps;
1027 unsigned long tx_average_pps = strip_info->tx_average_pps;
1028 unsigned long sx_average_pps = strip_info->sx_average_pps;
1029 int working = strip_info->working;
1030 int firmware_level = strip_info->firmware_level;
1031 long watchdog_doprobe = strip_info->watchdog_doprobe;
1032 long watchdog_doreset = strip_info->watchdog_doreset;
1033 long gratuitous_arp = strip_info->gratuitous_arp;
1034 long arp_interval = strip_info->arp_interval;
1035 FirmwareVersion firmware_version = strip_info->firmware_version;
1036 SerialNumber serial_number = strip_info->serial_number;
1037 BatteryVoltage battery_voltage = strip_info->battery_voltage;
1038 char *if_name = strip_info->dev->name;
1039 MetricomAddress true_dev_addr = strip_info->true_dev_addr;
1040 MetricomAddress dev_dev_addr =
1041 *(MetricomAddress *) strip_info->dev->dev_addr;
1042 int manual_dev_addr = strip_info->manual_dev_addr;
1043#ifdef EXT_COUNTERS
1044 unsigned long rx_bytes = strip_info->rx_bytes;
1045 unsigned long tx_bytes = strip_info->tx_bytes;
1046 unsigned long rx_rbytes = strip_info->rx_rbytes;
1047 unsigned long tx_rbytes = strip_info->tx_rbytes;
1048 unsigned long rx_sbytes = strip_info->rx_sbytes;
1049 unsigned long tx_sbytes = strip_info->tx_sbytes;
1050 unsigned long rx_ebytes = strip_info->rx_ebytes;
1051 unsigned long tx_ebytes = strip_info->tx_ebytes;
1052#endif
1053
1054 seq_printf(seq, "\nInterface name\t\t%s\n", if_name);
1055 seq_printf(seq, " Radio working:\t\t%s\n", working ? "Yes" : "No");
1056 radio_address_to_string(&true_dev_addr, &addr_string);
1057 seq_printf(seq, " Radio address:\t\t%s\n", addr_string.c);
1058 if (manual_dev_addr) {
1059 radio_address_to_string(&dev_dev_addr, &addr_string);
1060 seq_printf(seq, " Device address:\t%s\n", addr_string.c);
1061 }
1062 seq_printf(seq, " Firmware version:\t%s", !working ? "Unknown" :
1063 !firmware_level ? "Should be upgraded" :
1064 firmware_version.c);
1065 if (firmware_level >= ChecksummedMessages)
1066 seq_printf(seq, " (Checksums Enabled)");
1067 seq_printf(seq, "\n");
1068 seq_printf(seq, " Serial number:\t\t%s\n", serial_number.c);
1069 seq_printf(seq, " Battery voltage:\t%s\n", battery_voltage.c);
1070 seq_printf(seq, " Transmit queue (bytes):%d\n", tx_left);
1071 seq_printf(seq, " Receive packet rate: %ld packets per second\n",
1072 rx_average_pps / 8);
1073 seq_printf(seq, " Transmit packet rate: %ld packets per second\n",
1074 tx_average_pps / 8);
1075 seq_printf(seq, " Sent packet rate: %ld packets per second\n",
1076 sx_average_pps / 8);
1077 seq_printf(seq, " Next watchdog probe:\t%s\n",
1078 time_delta(temp, watchdog_doprobe));
1079 seq_printf(seq, " Next watchdog reset:\t%s\n",
1080 time_delta(temp, watchdog_doreset));
1081 seq_printf(seq, " Next gratuitous ARP:\t");
1082
1083 if (!memcmp
1084 (strip_info->dev->dev_addr, zero_address.c,
1085 sizeof(zero_address)))
1086 seq_printf(seq, "Disabled\n");
1087 else {
1088 seq_printf(seq, "%s\n", time_delta(temp, gratuitous_arp));
1089 seq_printf(seq, " Next ARP interval:\t%ld seconds\n",
1090 JIFFIE_TO_SEC(arp_interval));
1091 }
1092
1093 if (working) {
1094#ifdef EXT_COUNTERS
1095 seq_printf(seq, "\n");
1096 seq_printf(seq,
1097 " Total bytes: \trx:\t%lu\ttx:\t%lu\n",
1098 rx_bytes, tx_bytes);
1099 seq_printf(seq,
1100 " thru radio: \trx:\t%lu\ttx:\t%lu\n",
1101 rx_rbytes, tx_rbytes);
1102 seq_printf(seq,
1103 " thru serial port: \trx:\t%lu\ttx:\t%lu\n",
1104 rx_sbytes, tx_sbytes);
1105 seq_printf(seq,
1106 " Total stat/err bytes:\trx:\t%lu\ttx:\t%lu\n",
1107 rx_ebytes, tx_ebytes);
1108#endif
1109 strip_seq_neighbours(seq, &strip_info->poletops,
1110 "Poletops:");
1111 strip_seq_neighbours(seq, &strip_info->portables,
1112 "Portables:");
1113 }
1114}
1115
1116
1117
1118
1119
1120static int strip_seq_show(struct seq_file *seq, void *v)
1121{
1122 if (v == SEQ_START_TOKEN)
1123 seq_printf(seq, "strip_version: %s\n", StripVersion);
1124 else
1125 strip_seq_status_info(seq, (const struct strip *)v);
1126 return 0;
1127}
1128
1129
1130static const struct seq_operations strip_seq_ops = {
1131 .start = strip_seq_start,
1132 .next = strip_seq_next,
1133 .stop = strip_seq_stop,
1134 .show = strip_seq_show,
1135};
1136
1137static int strip_seq_open(struct inode *inode, struct file *file)
1138{
1139 return seq_open(file, &strip_seq_ops);
1140}
1141
1142static const struct file_operations strip_seq_fops = {
1143 .owner = THIS_MODULE,
1144 .open = strip_seq_open,
1145 .read = seq_read,
1146 .llseek = seq_lseek,
1147 .release = seq_release,
1148};
1149#endif
1150
1151
1152
1153
1154
1155
1156static void ResetRadio(struct strip *strip_info)
1157{
1158 struct tty_struct *tty = strip_info->tty;
1159 static const char init[] = "ate0q1dt**starmode\r**";
1160 StringDescriptor s = { init, sizeof(init) - 1 };
1161
1162
1163
1164
1165
1166 if (strip_info->working) {
1167 printk(KERN_INFO "%s: No response: Resetting radio.\n",
1168 strip_info->dev->name);
1169 strip_info->firmware_version.c[0] = '\0';
1170 strip_info->serial_number.c[0] = '\0';
1171 strip_info->battery_voltage.c[0] = '\0';
1172 strip_info->portables.num_nodes = 0;
1173 do_gettimeofday(&strip_info->portables.timestamp);
1174 strip_info->poletops.num_nodes = 0;
1175 do_gettimeofday(&strip_info->poletops.timestamp);
1176 }
1177
1178 strip_info->pps_timer = jiffies;
1179 strip_info->rx_pps_count = 0;
1180 strip_info->tx_pps_count = 0;
1181 strip_info->sx_pps_count = 0;
1182 strip_info->rx_average_pps = 0;
1183 strip_info->tx_average_pps = 0;
1184 strip_info->sx_average_pps = 0;
1185
1186
1187 *(MetricomAddress *) & strip_info->true_dev_addr = zero_address;
1188 if (!strip_info->manual_dev_addr)
1189 *(MetricomAddress *) strip_info->dev->dev_addr =
1190 zero_address;
1191 strip_info->working = FALSE;
1192 strip_info->firmware_level = NoStructure;
1193 strip_info->next_command = CompatibilityCommand;
1194 strip_info->watchdog_doprobe = jiffies + 10 * HZ;
1195 strip_info->watchdog_doreset = jiffies + 1 * HZ;
1196
1197
1198 if (strip_info->user_baud > 38400) {
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208 if (strip_info->user_baud == tty_get_baud_rate(tty)) {
1209 static const char b0[] = "ate0q1s304=57600\r";
1210 static const char b1[] = "ate0q1s304=115200\r";
1211 static const StringDescriptor baudstring[2] =
1212 { {b0, sizeof(b0) - 1}
1213 , {b1, sizeof(b1) - 1}
1214 };
1215 set_baud(tty, 19200);
1216 if (strip_info->user_baud == 57600)
1217 s = baudstring[0];
1218 else if (strip_info->user_baud == 115200)
1219 s = baudstring[1];
1220 else
1221 s = baudstring[1];
1222 } else
1223 set_baud(tty, strip_info->user_baud);
1224 }
1225
1226 tty->ops->write(tty, s.string, s.length);
1227#ifdef EXT_COUNTERS
1228 strip_info->tx_ebytes += s.length;
1229#endif
1230}
1231
1232
1233
1234
1235
1236
1237static void strip_write_some_more(struct tty_struct *tty)
1238{
1239 struct strip *strip_info = tty->disc_data;
1240
1241
1242 if (!strip_info || strip_info->magic != STRIP_MAGIC ||
1243 !netif_running(strip_info->dev))
1244 return;
1245
1246 if (strip_info->tx_left > 0) {
1247 int num_written =
1248 tty->ops->write(tty, strip_info->tx_head,
1249 strip_info->tx_left);
1250 strip_info->tx_left -= num_written;
1251 strip_info->tx_head += num_written;
1252#ifdef EXT_COUNTERS
1253 strip_info->tx_sbytes += num_written;
1254#endif
1255 } else {
1256
1257 clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
1258 strip_unlock(strip_info);
1259 }
1260}
1261
1262static __u8 *add_checksum(__u8 * buffer, __u8 * end)
1263{
1264 __u16 sum = 0;
1265 __u8 *p = buffer;
1266 while (p < end)
1267 sum += *p++;
1268 end[3] = hextable[sum & 0xF];
1269 sum >>= 4;
1270 end[2] = hextable[sum & 0xF];
1271 sum >>= 4;
1272 end[1] = hextable[sum & 0xF];
1273 sum >>= 4;
1274 end[0] = hextable[sum & 0xF];
1275 return (end + 4);
1276}
1277
1278static unsigned char *strip_make_packet(unsigned char *buffer,
1279 struct strip *strip_info,
1280 struct sk_buff *skb)
1281{
1282 __u8 *ptr = buffer;
1283 __u8 *stuffstate = NULL;
1284 STRIP_Header *header = (STRIP_Header *) skb->data;
1285 MetricomAddress haddr = header->dst_addr;
1286 int len = skb->len - sizeof(STRIP_Header);
1287 MetricomKey key;
1288
1289
1290
1291 if (header->protocol == htons(ETH_P_IP))
1292 key = SIP0Key;
1293 else if (header->protocol == htons(ETH_P_ARP))
1294 key = ARP0Key;
1295 else {
1296 printk(KERN_ERR
1297 "%s: strip_make_packet: Unknown packet type 0x%04X\n",
1298 strip_info->dev->name, ntohs(header->protocol));
1299 return (NULL);
1300 }
1301
1302 if (len > strip_info->mtu) {
1303 printk(KERN_ERR
1304 "%s: Dropping oversized transmit packet: %d bytes\n",
1305 strip_info->dev->name, len);
1306 return (NULL);
1307 }
1308
1309
1310
1311
1312
1313 if (!memcmp(haddr.c, strip_info->true_dev_addr.c, sizeof(haddr))) {
1314 printk(KERN_ERR "%s: Dropping packet addressed to self\n",
1315 strip_info->dev->name);
1316 return (NULL);
1317 }
1318
1319
1320
1321
1322
1323 if (haddr.c[0] == 0xFF) {
1324 __be32 brd = 0;
1325 struct in_device *in_dev;
1326
1327 rcu_read_lock();
1328 in_dev = __in_dev_get_rcu(strip_info->dev);
1329 if (in_dev == NULL) {
1330 rcu_read_unlock();
1331 return NULL;
1332 }
1333 if (in_dev->ifa_list)
1334 brd = in_dev->ifa_list->ifa_broadcast;
1335 rcu_read_unlock();
1336
1337
1338 if (!arp_query(haddr.c, brd, strip_info->dev)) {
1339 printk(KERN_ERR
1340 "%s: Unable to send packet (no broadcast hub configured)\n",
1341 strip_info->dev->name);
1342 return (NULL);
1343 }
1344
1345
1346
1347
1348 if (!memcmp
1349 (haddr.c, strip_info->true_dev_addr.c, sizeof(haddr)))
1350 return (NULL);
1351 }
1352
1353 *ptr++ = 0x0D;
1354 *ptr++ = '*';
1355 *ptr++ = hextable[haddr.c[2] >> 4];
1356 *ptr++ = hextable[haddr.c[2] & 0xF];
1357 *ptr++ = hextable[haddr.c[3] >> 4];
1358 *ptr++ = hextable[haddr.c[3] & 0xF];
1359 *ptr++ = '-';
1360 *ptr++ = hextable[haddr.c[4] >> 4];
1361 *ptr++ = hextable[haddr.c[4] & 0xF];
1362 *ptr++ = hextable[haddr.c[5] >> 4];
1363 *ptr++ = hextable[haddr.c[5] & 0xF];
1364 *ptr++ = '*';
1365 *ptr++ = key.c[0];
1366 *ptr++ = key.c[1];
1367 *ptr++ = key.c[2];
1368 *ptr++ = key.c[3];
1369
1370 ptr =
1371 StuffData(skb->data + sizeof(STRIP_Header), len, ptr,
1372 &stuffstate);
1373
1374 if (strip_info->firmware_level >= ChecksummedMessages)
1375 ptr = add_checksum(buffer + 1, ptr);
1376
1377 *ptr++ = 0x0D;
1378 return (ptr);
1379}
1380
1381static void strip_send(struct strip *strip_info, struct sk_buff *skb)
1382{
1383 MetricomAddress haddr;
1384 unsigned char *ptr = strip_info->tx_buff;
1385 int doreset = (long) jiffies - strip_info->watchdog_doreset >= 0;
1386 int doprobe = (long) jiffies - strip_info->watchdog_doprobe >= 0
1387 && !doreset;
1388 __be32 addr, brd;
1389
1390
1391
1392
1393 if (skb) {
1394 char *newptr = strip_make_packet(ptr, strip_info, skb);
1395 strip_info->tx_pps_count++;
1396 if (!newptr)
1397 strip_info->tx_dropped++;
1398 else {
1399 ptr = newptr;
1400 strip_info->sx_pps_count++;
1401 strip_info->tx_packets++;
1402#ifdef EXT_COUNTERS
1403 strip_info->tx_bytes += skb->len;
1404 strip_info->tx_rbytes += ptr - strip_info->tx_buff;
1405#endif
1406
1407
1408 }
1409 }
1410
1411
1412
1413
1414 if (doprobe) {
1415 StringDescriptor ts = CommandString[strip_info->next_command];
1416#if TICKLE_TIMERS
1417 {
1418 struct timeval tv;
1419 do_gettimeofday(&tv);
1420 printk(KERN_INFO "**** Sending tickle string %d at %02d.%06d\n",
1421 strip_info->next_command, tv.tv_sec % 100,
1422 tv.tv_usec);
1423 }
1424#endif
1425 if (ptr == strip_info->tx_buff)
1426 *ptr++ = 0x0D;
1427
1428 *ptr++ = '*';
1429 *ptr++ = '*';
1430
1431
1432 memcpy(ptr, ts.string, ts.length);
1433
1434
1435 if (strip_info->firmware_level < ChecksummedMessages)
1436 ptr += ts.length;
1437 else
1438 ptr = add_checksum(ptr, ptr + ts.length);
1439
1440 *ptr++ = 0x0D;
1441
1442
1443 if (strip_info->firmware_level >= StructuredMessages)
1444 if (++strip_info->next_command >=
1445 ARRAY_SIZE(CommandString))
1446 strip_info->next_command = 0;
1447#ifdef EXT_COUNTERS
1448 strip_info->tx_ebytes += ts.length;
1449#endif
1450 strip_info->watchdog_doprobe = jiffies + 10 * HZ;
1451 strip_info->watchdog_doreset = jiffies + 1 * HZ;
1452
1453 }
1454
1455
1456
1457
1458 strip_info->tx_head = strip_info->tx_buff;
1459 strip_info->tx_left = ptr - strip_info->tx_buff;
1460 set_bit(TTY_DO_WRITE_WAKEUP, &strip_info->tty->flags);
1461
1462
1463
1464 if (strip_info->tx_size - strip_info->tx_left < 20)
1465 printk(KERN_ERR "%s: Sending%5d bytes;%5d bytes free.\n",
1466 strip_info->dev->name, strip_info->tx_left,
1467 strip_info->tx_size - strip_info->tx_left);
1468
1469
1470
1471
1472
1473 if (doreset) {
1474 ResetRadio(strip_info);
1475 return;
1476 }
1477
1478 if (1) {
1479 struct in_device *in_dev;
1480
1481 brd = addr = 0;
1482 rcu_read_lock();
1483 in_dev = __in_dev_get_rcu(strip_info->dev);
1484 if (in_dev) {
1485 if (in_dev->ifa_list) {
1486 brd = in_dev->ifa_list->ifa_broadcast;
1487 addr = in_dev->ifa_list->ifa_local;
1488 }
1489 }
1490 rcu_read_unlock();
1491 }
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508 if (strip_info->working
1509 && (long) jiffies - strip_info->gratuitous_arp >= 0
1510 && memcmp(strip_info->dev->dev_addr, zero_address.c,
1511 sizeof(zero_address))
1512 && arp_query(haddr.c, brd, strip_info->dev)) {
1513
1514
1515 strip_info->gratuitous_arp =
1516 jiffies + strip_info->arp_interval;
1517 strip_info->arp_interval *= 2;
1518 if (strip_info->arp_interval > MaxARPInterval)
1519 strip_info->arp_interval = MaxARPInterval;
1520 if (addr)
1521 arp_send(ARPOP_REPLY, ETH_P_ARP, addr,
1522 strip_info->dev,
1523 addr,
1524 NULL,
1525 strip_info->dev->dev_addr,
1526 strip_info->dev->dev_addr);
1527 }
1528
1529
1530
1531
1532 strip_write_some_more(strip_info->tty);
1533}
1534
1535
1536static netdev_tx_t strip_xmit(struct sk_buff *skb, struct net_device *dev)
1537{
1538 struct strip *strip_info = netdev_priv(dev);
1539
1540 if (!netif_running(dev)) {
1541 printk(KERN_ERR "%s: xmit call when iface is down\n",
1542 dev->name);
1543 return NETDEV_TX_BUSY;
1544 }
1545
1546 netif_stop_queue(dev);
1547
1548 del_timer(&strip_info->idle_timer);
1549
1550
1551 if (time_after(jiffies, strip_info->pps_timer + HZ)) {
1552 unsigned long t = jiffies - strip_info->pps_timer;
1553 unsigned long rx_pps_count =
1554 DIV_ROUND_CLOSEST(strip_info->rx_pps_count*HZ*8, t);
1555 unsigned long tx_pps_count =
1556 DIV_ROUND_CLOSEST(strip_info->tx_pps_count*HZ*8, t);
1557 unsigned long sx_pps_count =
1558 DIV_ROUND_CLOSEST(strip_info->sx_pps_count*HZ*8, t);
1559
1560 strip_info->pps_timer = jiffies;
1561 strip_info->rx_pps_count = 0;
1562 strip_info->tx_pps_count = 0;
1563 strip_info->sx_pps_count = 0;
1564
1565 strip_info->rx_average_pps = (strip_info->rx_average_pps + rx_pps_count + 1) / 2;
1566 strip_info->tx_average_pps = (strip_info->tx_average_pps + tx_pps_count + 1) / 2;
1567 strip_info->sx_average_pps = (strip_info->sx_average_pps + sx_pps_count + 1) / 2;
1568
1569 if (rx_pps_count / 8 >= 10)
1570 printk(KERN_INFO "%s: WARNING: Receiving %ld packets per second.\n",
1571 strip_info->dev->name, rx_pps_count / 8);
1572 if (tx_pps_count / 8 >= 10)
1573 printk(KERN_INFO "%s: WARNING: Tx %ld packets per second.\n",
1574 strip_info->dev->name, tx_pps_count / 8);
1575 if (sx_pps_count / 8 >= 10)
1576 printk(KERN_INFO "%s: WARNING: Sending %ld packets per second.\n",
1577 strip_info->dev->name, sx_pps_count / 8);
1578 }
1579
1580 spin_lock_bh(&strip_lock);
1581
1582 strip_send(strip_info, skb);
1583
1584 spin_unlock_bh(&strip_lock);
1585
1586 if (skb)
1587 dev_kfree_skb(skb);
1588 return NETDEV_TX_OK;
1589}
1590
1591
1592
1593
1594
1595
1596
1597static void strip_IdleTask(unsigned long parameter)
1598{
1599 strip_xmit(NULL, (struct net_device *) parameter);
1600}
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613static int strip_header(struct sk_buff *skb, struct net_device *dev,
1614 unsigned short type, const void *daddr,
1615 const void *saddr, unsigned len)
1616{
1617 struct strip *strip_info = netdev_priv(dev);
1618 STRIP_Header *header = (STRIP_Header *) skb_push(skb, sizeof(STRIP_Header));
1619
1620
1621
1622
1623 header->src_addr = strip_info->true_dev_addr;
1624 header->protocol = htons(type);
1625
1626
1627
1628 if (!daddr)
1629 return (-dev->hard_header_len);
1630
1631 header->dst_addr = *(MetricomAddress *) daddr;
1632 return (dev->hard_header_len);
1633}
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643static int strip_rebuild_header(struct sk_buff *skb)
1644{
1645#ifdef CONFIG_INET
1646 STRIP_Header *header = (STRIP_Header *) skb->data;
1647
1648
1649
1650 return arp_find(header->dst_addr.c, skb) ? 1 : 0;
1651#else
1652 return 0;
1653#endif
1654}
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664static void get_radio_version(struct strip *strip_info, __u8 * ptr, __u8 * end)
1665{
1666 __u8 *p, *value_begin, *value_end;
1667 int len;
1668
1669
1670 p = ptr;
1671 while (p < end && *p != 10)
1672 p++;
1673 if (p >= end)
1674 return;
1675 p++;
1676 value_begin = p;
1677
1678
1679 while (p < end && *p != 10)
1680 p++;
1681 if (p >= end)
1682 return;
1683 value_end = p;
1684 p++;
1685
1686 len = value_end - value_begin;
1687 len = min_t(int, len, sizeof(FirmwareVersion) - 1);
1688 if (strip_info->firmware_version.c[0] == 0)
1689 printk(KERN_INFO "%s: Radio Firmware: %.*s\n",
1690 strip_info->dev->name, len, value_begin);
1691 sprintf(strip_info->firmware_version.c, "%.*s", len, value_begin);
1692
1693
1694 while (p < end && *p != ':')
1695 p++;
1696 if (p >= end)
1697 return;
1698
1699 p += 2;
1700 len = sizeof(SerialNumber) - 1;
1701 if (p + len <= end) {
1702 sprintf(strip_info->serial_number.c, "%.*s", len, p);
1703 } else {
1704 printk(KERN_DEBUG
1705 "STRIP: radio serial number shorter (%zd) than expected (%d)\n",
1706 end - p, len);
1707 }
1708}
1709
1710
1711
1712
1713
1714static void get_radio_voltage(struct strip *strip_info, __u8 * ptr, __u8 * end)
1715{
1716 int len;
1717
1718 len = sizeof(BatteryVoltage) - 1;
1719 if (ptr + len <= end) {
1720 sprintf(strip_info->battery_voltage.c, "%.*s", len, ptr);
1721 } else {
1722 printk(KERN_DEBUG
1723 "STRIP: radio voltage string shorter (%zd) than expected (%d)\n",
1724 end - ptr, len);
1725 }
1726}
1727
1728
1729
1730
1731
1732static void get_radio_neighbours(MetricomNodeTable * table, __u8 * ptr, __u8 * end)
1733{
1734 table->num_nodes = 0;
1735 while (ptr < end && table->num_nodes < NODE_TABLE_SIZE) {
1736 MetricomNode *node = &table->node[table->num_nodes++];
1737 char *dst = node->c, *limit = dst + sizeof(*node) - 1;
1738 while (ptr < end && *ptr <= 32)
1739 ptr++;
1740 while (ptr < end && dst < limit && *ptr != 10)
1741 *dst++ = *ptr++;
1742 *dst++ = 0;
1743 while (ptr < end && ptr[-1] != 10)
1744 ptr++;
1745 }
1746 do_gettimeofday(&table->timestamp);
1747}
1748
1749static int get_radio_address(struct strip *strip_info, __u8 * p)
1750{
1751 MetricomAddress addr;
1752
1753 if (string_to_radio_address(&addr, p))
1754 return (1);
1755
1756
1757 if (memcmp(strip_info->true_dev_addr.c, addr.c, sizeof(addr))) {
1758 MetricomAddressString addr_string;
1759 radio_address_to_string(&addr, &addr_string);
1760 printk(KERN_INFO "%s: Radio address = %s\n",
1761 strip_info->dev->name, addr_string.c);
1762 strip_info->true_dev_addr = addr;
1763 if (!strip_info->manual_dev_addr)
1764 *(MetricomAddress *) strip_info->dev->dev_addr =
1765 addr;
1766
1767 strip_info->gratuitous_arp = jiffies + 15 * HZ;
1768 strip_info->arp_interval = 1 * HZ;
1769 }
1770 return (0);
1771}
1772
1773static int verify_checksum(struct strip *strip_info)
1774{
1775 __u8 *p = strip_info->sx_buff;
1776 __u8 *end = strip_info->sx_buff + strip_info->sx_count - 4;
1777 u_short sum =
1778 (READHEX16(end[0]) << 12) | (READHEX16(end[1]) << 8) |
1779 (READHEX16(end[2]) << 4) | (READHEX16(end[3]));
1780 while (p < end)
1781 sum -= *p++;
1782 if (sum == 0 && strip_info->firmware_level == StructuredMessages) {
1783 strip_info->firmware_level = ChecksummedMessages;
1784 printk(KERN_INFO "%s: Radio provides message checksums\n",
1785 strip_info->dev->name);
1786 }
1787 return (sum == 0);
1788}
1789
1790static void RecvErr(char *msg, struct strip *strip_info)
1791{
1792 __u8 *ptr = strip_info->sx_buff;
1793 __u8 *end = strip_info->sx_buff + strip_info->sx_count;
1794 DumpData(msg, strip_info, ptr, end);
1795 strip_info->rx_errors++;
1796}
1797
1798static void RecvErr_Message(struct strip *strip_info, __u8 * sendername,
1799 const __u8 * msg, u_long len)
1800{
1801 if (has_prefix(msg, len, "001")) {
1802 RecvErr("Error Msg:", strip_info);
1803 printk(KERN_INFO "%s: Radio %s is not in StarMode\n",
1804 strip_info->dev->name, sendername);
1805 }
1806
1807 else if (has_prefix(msg, len, "002")) {
1808
1809 }
1810
1811 else if (has_prefix(msg, len, "003")) {
1812 RecvErr("Error Msg:", strip_info);
1813 printk(KERN_INFO "%s: Destination radio name is unknown\n",
1814 strip_info->dev->name);
1815 }
1816
1817 else if (has_prefix(msg, len, "004")) {
1818 strip_info->watchdog_doreset = jiffies + LongTime;
1819#if TICKLE_TIMERS
1820 {
1821 struct timeval tv;
1822 do_gettimeofday(&tv);
1823 printk(KERN_INFO
1824 "**** Got ERR_004 response at %02d.%06d\n",
1825 tv.tv_sec % 100, tv.tv_usec);
1826 }
1827#endif
1828 if (!strip_info->working) {
1829 strip_info->working = TRUE;
1830 printk(KERN_INFO "%s: Radio now in starmode\n",
1831 strip_info->dev->name);
1832
1833
1834
1835
1836 strip_info->watchdog_doprobe = jiffies;
1837 }
1838 if (strip_info->firmware_level == NoStructure && sendername) {
1839 strip_info->firmware_level = StructuredMessages;
1840 strip_info->next_command = 0;
1841 printk(KERN_INFO
1842 "%s: Radio provides structured messages\n",
1843 strip_info->dev->name);
1844 }
1845 if (strip_info->firmware_level >= StructuredMessages) {
1846
1847
1848
1849
1850
1851 verify_checksum(strip_info);
1852
1853
1854
1855
1856 if (!GOT_ALL_RADIO_INFO(strip_info))
1857 strip_info->watchdog_doprobe = jiffies;
1858 }
1859 }
1860
1861 else if (has_prefix(msg, len, "005"))
1862 RecvErr("Error Msg:", strip_info);
1863
1864 else if (has_prefix(msg, len, "006"))
1865 RecvErr("Error Msg:", strip_info);
1866
1867 else if (has_prefix(msg, len, "007")) {
1868 RecvErr("Error Msg:", strip_info);
1869 printk(KERN_ERR
1870 "%s: Error! Packet size too big for radio.\n",
1871 strip_info->dev->name);
1872 }
1873
1874 else if (has_prefix(msg, len, "008")) {
1875 RecvErr("Error Msg:", strip_info);
1876 printk(KERN_ERR
1877 "%s: Radio name contains illegal character\n",
1878 strip_info->dev->name);
1879 }
1880
1881 else if (has_prefix(msg, len, "009"))
1882 RecvErr("Error Msg:", strip_info);
1883
1884 else if (has_prefix(msg, len, "010"))
1885 RecvErr("Error Msg:", strip_info);
1886
1887 else if (has_prefix(msg, len, "011"))
1888 RecvErr("Error Msg:", strip_info);
1889
1890 else if (has_prefix(msg, len, "012"))
1891 RecvErr("Error Msg:", strip_info);
1892
1893 else
1894 RecvErr("Error Msg:", strip_info);
1895}
1896
1897static void process_AT_response(struct strip *strip_info, __u8 * ptr,
1898 __u8 * end)
1899{
1900 u_long len;
1901 __u8 *p = ptr;
1902 while (p < end && p[-1] != 10)
1903 p++;
1904
1905 len = p - ptr;
1906
1907#if TICKLE_TIMERS
1908 {
1909 struct timeval tv;
1910 do_gettimeofday(&tv);
1911 printk(KERN_INFO "**** Got AT response %.7s at %02d.%06d\n",
1912 ptr, tv.tv_sec % 100, tv.tv_usec);
1913 }
1914#endif
1915
1916 if (has_prefix(ptr, len, "ATS300?"))
1917 get_radio_version(strip_info, p, end);
1918 else if (has_prefix(ptr, len, "ATS305?"))
1919 get_radio_address(strip_info, p);
1920 else if (has_prefix(ptr, len, "ATS311?"))
1921 get_radio_neighbours(&strip_info->poletops, p, end);
1922 else if (has_prefix(ptr, len, "ATS319=7"))
1923 verify_checksum(strip_info);
1924 else if (has_prefix(ptr, len, "ATS325?"))
1925 get_radio_voltage(strip_info, p, end);
1926 else if (has_prefix(ptr, len, "AT~LA"))
1927 get_radio_neighbours(&strip_info->portables, p, end);
1928 else
1929 RecvErr("Unknown AT Response:", strip_info);
1930}
1931
1932static void process_ACK(struct strip *strip_info, __u8 * ptr, __u8 * end)
1933{
1934
1935}
1936
1937static void process_Info(struct strip *strip_info, __u8 * ptr, __u8 * end)
1938{
1939 if (ptr + 16 > end)
1940 RecvErr("Bad Info Msg:", strip_info);
1941}
1942
1943static struct net_device *get_strip_dev(struct strip *strip_info)
1944{
1945
1946
1947
1948 if (strip_info->manual_dev_addr &&
1949 !memcmp(strip_info->dev->dev_addr, zero_address.c,
1950 sizeof(zero_address))
1951 && memcmp(&strip_info->true_dev_addr, zero_address.c,
1952 sizeof(zero_address))) {
1953 struct net_device *dev;
1954 read_lock_bh(&dev_base_lock);
1955 for_each_netdev(&init_net, dev) {
1956 if (dev->type == strip_info->dev->type &&
1957 !memcmp(dev->dev_addr,
1958 &strip_info->true_dev_addr,
1959 sizeof(MetricomAddress))) {
1960 printk(KERN_INFO
1961 "%s: Transferred packet ownership to %s.\n",
1962 strip_info->dev->name, dev->name);
1963 read_unlock_bh(&dev_base_lock);
1964 return (dev);
1965 }
1966 }
1967 read_unlock_bh(&dev_base_lock);
1968 }
1969 return (strip_info->dev);
1970}
1971
1972
1973
1974
1975
1976static void deliver_packet(struct strip *strip_info, STRIP_Header * header,
1977 __u16 packetlen)
1978{
1979 struct sk_buff *skb = dev_alloc_skb(sizeof(STRIP_Header) + packetlen);
1980 if (!skb) {
1981 printk(KERN_ERR "%s: memory squeeze, dropping packet.\n",
1982 strip_info->dev->name);
1983 strip_info->rx_dropped++;
1984 } else {
1985 memcpy(skb_put(skb, sizeof(STRIP_Header)), header,
1986 sizeof(STRIP_Header));
1987 memcpy(skb_put(skb, packetlen), strip_info->rx_buff,
1988 packetlen);
1989 skb->dev = get_strip_dev(strip_info);
1990 skb->protocol = header->protocol;
1991 skb_reset_mac_header(skb);
1992
1993
1994
1995
1996 skb_pull(skb, sizeof(STRIP_Header));
1997
1998
1999 strip_info->rx_packets++;
2000 strip_info->rx_pps_count++;
2001#ifdef EXT_COUNTERS
2002 strip_info->rx_bytes += packetlen;
2003#endif
2004 netif_rx(skb);
2005 }
2006}
2007
2008static void process_IP_packet(struct strip *strip_info,
2009 STRIP_Header * header, __u8 * ptr,
2010 __u8 * end)
2011{
2012 __u16 packetlen;
2013
2014
2015 ptr = UnStuffData(ptr, end, strip_info->rx_buff, 4);
2016 if (!ptr) {
2017 RecvErr("IP Packet too short", strip_info);
2018 return;
2019 }
2020
2021 packetlen = ((__u16) strip_info->rx_buff[2] << 8) | strip_info->rx_buff[3];
2022
2023 if (packetlen > MAX_RECV_MTU) {
2024 printk(KERN_INFO "%s: Dropping oversized received IP packet: %d bytes\n",
2025 strip_info->dev->name, packetlen);
2026 strip_info->rx_dropped++;
2027 return;
2028 }
2029
2030
2031
2032
2033 ptr =
2034 UnStuffData(ptr, end, strip_info->rx_buff + 4, packetlen - 4);
2035 if (!ptr) {
2036 RecvErr("IP Packet too short", strip_info);
2037 return;
2038 }
2039
2040 if (ptr < end) {
2041 RecvErr("IP Packet too long", strip_info);
2042 return;
2043 }
2044
2045 header->protocol = htons(ETH_P_IP);
2046
2047 deliver_packet(strip_info, header, packetlen);
2048}
2049
2050static void process_ARP_packet(struct strip *strip_info,
2051 STRIP_Header * header, __u8 * ptr,
2052 __u8 * end)
2053{
2054 __u16 packetlen;
2055 struct arphdr *arphdr = (struct arphdr *) strip_info->rx_buff;
2056
2057
2058 ptr = UnStuffData(ptr, end, strip_info->rx_buff, 8);
2059 if (!ptr) {
2060 RecvErr("ARP Packet too short", strip_info);
2061 return;
2062 }
2063
2064 packetlen = 8 + (arphdr->ar_hln + arphdr->ar_pln) * 2;
2065
2066 if (packetlen > MAX_RECV_MTU) {
2067 printk(KERN_INFO
2068 "%s: Dropping oversized received ARP packet: %d bytes\n",
2069 strip_info->dev->name, packetlen);
2070 strip_info->rx_dropped++;
2071 return;
2072 }
2073
2074
2075
2076
2077
2078
2079 ptr =
2080 UnStuffData(ptr, end, strip_info->rx_buff + 8, packetlen - 8);
2081 if (!ptr) {
2082 RecvErr("ARP Packet too short", strip_info);
2083 return;
2084 }
2085
2086 if (ptr < end) {
2087 RecvErr("ARP Packet too long", strip_info);
2088 return;
2089 }
2090
2091 header->protocol = htons(ETH_P_ARP);
2092
2093 deliver_packet(strip_info, header, packetlen);
2094}
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104static void process_text_message(struct strip *strip_info)
2105{
2106 __u8 *msg = strip_info->sx_buff;
2107 int len = strip_info->sx_count;
2108
2109
2110
2111 if (len == 9 && get_radio_address(strip_info, msg) == 0)
2112 return;
2113
2114 if (text_equal(msg, len, "OK"))
2115 return;
2116 if (text_equal(msg, len, "ERROR"))
2117 return;
2118 if (has_prefix(msg, len, "ate0q1"))
2119 return;
2120
2121
2122
2123 if (has_prefix(msg, len, "ERR_")) {
2124 RecvErr_Message(strip_info, NULL, &msg[4], len - 4);
2125 return;
2126 }
2127
2128 RecvErr("No initial *", strip_info);
2129}
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140static void process_message(struct strip *strip_info)
2141{
2142 STRIP_Header header = { zero_address, zero_address, 0 };
2143 __u8 *ptr = strip_info->sx_buff;
2144 __u8 *end = strip_info->sx_buff + strip_info->sx_count;
2145 __u8 sendername[32], *sptr = sendername;
2146 MetricomKey key;
2147
2148
2149
2150
2151 if (*ptr == '*')
2152 ptr++;
2153 else {
2154 process_text_message(strip_info);
2155 return;
2156 }
2157
2158
2159 while (ptr < end && *ptr != '*'
2160 && sptr < ARRAY_END(sendername) - 1)
2161 *sptr++ = *ptr++;
2162 *sptr = 0;
2163
2164
2165 if (ptr >= end || *ptr != '*') {
2166 RecvErr("No second *", strip_info);
2167 return;
2168 }
2169 ptr++;
2170
2171
2172
2173 if (!strcmp(sendername, "&COMMAND")) {
2174 strip_info->firmware_level = NoStructure;
2175 strip_info->next_command = CompatibilityCommand;
2176 return;
2177 }
2178
2179 if (ptr + 4 > end) {
2180 RecvErr("No proto key", strip_info);
2181 return;
2182 }
2183
2184
2185 key.c[0] = *ptr++;
2186 key.c[1] = *ptr++;
2187 key.c[2] = *ptr++;
2188 key.c[3] = *ptr++;
2189
2190
2191 if (strip_info->firmware_level >= ChecksummedMessages) {
2192 end -= 4;
2193 if (ptr > end) {
2194 RecvErr("Missing Checksum", strip_info);
2195 return;
2196 }
2197 if (!verify_checksum(strip_info)) {
2198 RecvErr("Bad Checksum", strip_info);
2199 return;
2200 }
2201 }
2202
2203
2204
2205
2206
2207
2208
2209
2210 header.dst_addr = strip_info->true_dev_addr;
2211 string_to_radio_address(&header.src_addr, sendername);
2212
2213#ifdef EXT_COUNTERS
2214 if (key.l == SIP0Key.l) {
2215 strip_info->rx_rbytes += (end - ptr);
2216 process_IP_packet(strip_info, &header, ptr, end);
2217 } else if (key.l == ARP0Key.l) {
2218 strip_info->rx_rbytes += (end - ptr);
2219 process_ARP_packet(strip_info, &header, ptr, end);
2220 } else if (key.l == ATR_Key.l) {
2221 strip_info->rx_ebytes += (end - ptr);
2222 process_AT_response(strip_info, ptr, end);
2223 } else if (key.l == ACK_Key.l) {
2224 strip_info->rx_ebytes += (end - ptr);
2225 process_ACK(strip_info, ptr, end);
2226 } else if (key.l == INF_Key.l) {
2227 strip_info->rx_ebytes += (end - ptr);
2228 process_Info(strip_info, ptr, end);
2229 } else if (key.l == ERR_Key.l) {
2230 strip_info->rx_ebytes += (end - ptr);
2231 RecvErr_Message(strip_info, sendername, ptr, end - ptr);
2232 } else
2233 RecvErr("Unrecognized protocol key", strip_info);
2234#else
2235 if (key.l == SIP0Key.l)
2236 process_IP_packet(strip_info, &header, ptr, end);
2237 else if (key.l == ARP0Key.l)
2238 process_ARP_packet(strip_info, &header, ptr, end);
2239 else if (key.l == ATR_Key.l)
2240 process_AT_response(strip_info, ptr, end);
2241 else if (key.l == ACK_Key.l)
2242 process_ACK(strip_info, ptr, end);
2243 else if (key.l == INF_Key.l)
2244 process_Info(strip_info, ptr, end);
2245 else if (key.l == ERR_Key.l)
2246 RecvErr_Message(strip_info, sendername, ptr, end - ptr);
2247 else
2248 RecvErr("Unrecognized protocol key", strip_info);
2249#endif
2250}
2251
2252#define TTYERROR(X) ((X) == TTY_BREAK ? "Break" : \
2253 (X) == TTY_FRAME ? "Framing Error" : \
2254 (X) == TTY_PARITY ? "Parity Error" : \
2255 (X) == TTY_OVERRUN ? "Hardware Overrun" : "Unknown Error")
2256
2257
2258
2259
2260
2261
2262
2263
2264static void strip_receive_buf(struct tty_struct *tty, const unsigned char *cp,
2265 char *fp, int count)
2266{
2267 struct strip *strip_info = tty->disc_data;
2268 const unsigned char *end = cp + count;
2269
2270 if (!strip_info || strip_info->magic != STRIP_MAGIC
2271 || !netif_running(strip_info->dev))
2272 return;
2273
2274 spin_lock_bh(&strip_lock);
2275#if 0
2276 {
2277 struct timeval tv;
2278 do_gettimeofday(&tv);
2279 printk(KERN_INFO
2280 "**** strip_receive_buf: %3d bytes at %02d.%06d\n",
2281 count, tv.tv_sec % 100, tv.tv_usec);
2282 }
2283#endif
2284
2285#ifdef EXT_COUNTERS
2286 strip_info->rx_sbytes += count;
2287#endif
2288
2289
2290 while (cp < end) {
2291 if (fp && *fp)
2292 printk(KERN_INFO "%s: %s on serial port\n",
2293 strip_info->dev->name, TTYERROR(*fp));
2294 if (fp && *fp++ && !strip_info->discard) {
2295
2296 strip_info->discard = strip_info->sx_count;
2297 strip_info->rx_errors++;
2298 }
2299
2300
2301 if (strip_info->sx_count > 0 || *cp >= ' ') {
2302 if (*cp == 0x0D) {
2303 if (strip_info->sx_count > 3000)
2304 printk(KERN_INFO
2305 "%s: Cut a %d byte packet (%zd bytes remaining)%s\n",
2306 strip_info->dev->name,
2307 strip_info->sx_count,
2308 end - cp - 1,
2309 strip_info->
2310 discard ? " (discarded)" :
2311 "");
2312 if (strip_info->sx_count >
2313 strip_info->sx_size) {
2314 strip_info->rx_over_errors++;
2315 printk(KERN_INFO
2316 "%s: sx_buff overflow (%d bytes total)\n",
2317 strip_info->dev->name,
2318 strip_info->sx_count);
2319 } else if (strip_info->discard)
2320 printk(KERN_INFO
2321 "%s: Discarding bad packet (%d/%d)\n",
2322 strip_info->dev->name,
2323 strip_info->discard,
2324 strip_info->sx_count);
2325 else
2326 process_message(strip_info);
2327 strip_info->discard = 0;
2328 strip_info->sx_count = 0;
2329 } else {
2330
2331 if (strip_info->sx_count <
2332 strip_info->sx_size)
2333 strip_info->sx_buff[strip_info->
2334 sx_count] =
2335 *cp;
2336 strip_info->sx_count++;
2337 }
2338 }
2339 cp++;
2340 }
2341 spin_unlock_bh(&strip_lock);
2342}
2343
2344
2345
2346
2347
2348static int set_mac_address(struct strip *strip_info,
2349 MetricomAddress * addr)
2350{
2351
2352
2353
2354
2355
2356
2357 strip_info->manual_dev_addr =
2358 memcmp(addr->c, broadcast_address.c,
2359 sizeof(broadcast_address));
2360 if (strip_info->manual_dev_addr)
2361 *(MetricomAddress *) strip_info->dev->dev_addr = *addr;
2362 else
2363 *(MetricomAddress *) strip_info->dev->dev_addr =
2364 strip_info->true_dev_addr;
2365 return 0;
2366}
2367
2368static int strip_set_mac_address(struct net_device *dev, void *addr)
2369{
2370 struct strip *strip_info = netdev_priv(dev);
2371 struct sockaddr *sa = addr;
2372 printk(KERN_INFO "%s: strip_set_dev_mac_address called\n", dev->name);
2373 set_mac_address(strip_info, (MetricomAddress *) sa->sa_data);
2374 return 0;
2375}
2376
2377static struct net_device_stats *strip_get_stats(struct net_device *dev)
2378{
2379 struct strip *strip_info = netdev_priv(dev);
2380 static struct net_device_stats stats;
2381
2382 memset(&stats, 0, sizeof(struct net_device_stats));
2383
2384 stats.rx_packets = strip_info->rx_packets;
2385 stats.tx_packets = strip_info->tx_packets;
2386 stats.rx_dropped = strip_info->rx_dropped;
2387 stats.tx_dropped = strip_info->tx_dropped;
2388 stats.tx_errors = strip_info->tx_errors;
2389 stats.rx_errors = strip_info->rx_errors;
2390 stats.rx_over_errors = strip_info->rx_over_errors;
2391 return (&stats);
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
2419
2420
2421
2422static int strip_open_low(struct net_device *dev)
2423{
2424 struct strip *strip_info = netdev_priv(dev);
2425
2426 if (strip_info->tty == NULL)
2427 return (-ENODEV);
2428
2429 if (!allocate_buffers(strip_info, dev->mtu))
2430 return (-ENOMEM);
2431
2432 strip_info->sx_count = 0;
2433 strip_info->tx_left = 0;
2434
2435 strip_info->discard = 0;
2436 strip_info->working = FALSE;
2437 strip_info->firmware_level = NoStructure;
2438 strip_info->next_command = CompatibilityCommand;
2439 strip_info->user_baud = tty_get_baud_rate(strip_info->tty);
2440
2441 printk(KERN_INFO "%s: Initializing Radio.\n",
2442 strip_info->dev->name);
2443 ResetRadio(strip_info);
2444 strip_info->idle_timer.expires = jiffies + 1 * HZ;
2445 add_timer(&strip_info->idle_timer);
2446 netif_wake_queue(dev);
2447 return (0);
2448}
2449
2450
2451
2452
2453
2454
2455static int strip_close_low(struct net_device *dev)
2456{
2457 struct strip *strip_info = netdev_priv(dev);
2458
2459 if (strip_info->tty == NULL)
2460 return -EBUSY;
2461 clear_bit(TTY_DO_WRITE_WAKEUP, &strip_info->tty->flags);
2462 netif_stop_queue(dev);
2463
2464
2465
2466
2467 kfree(strip_info->rx_buff);
2468 strip_info->rx_buff = NULL;
2469 kfree(strip_info->sx_buff);
2470 strip_info->sx_buff = NULL;
2471 kfree(strip_info->tx_buff);
2472 strip_info->tx_buff = NULL;
2473
2474 del_timer(&strip_info->idle_timer);
2475 return 0;
2476}
2477
2478static const struct header_ops strip_header_ops = {
2479 .create = strip_header,
2480 .rebuild = strip_rebuild_header,
2481};
2482
2483
2484static const struct net_device_ops strip_netdev_ops = {
2485 .ndo_open = strip_open_low,
2486 .ndo_stop = strip_close_low,
2487 .ndo_start_xmit = strip_xmit,
2488 .ndo_set_mac_address = strip_set_mac_address,
2489 .ndo_get_stats = strip_get_stats,
2490 .ndo_change_mtu = strip_change_mtu,
2491};
2492
2493
2494
2495
2496
2497
2498static void strip_dev_setup(struct net_device *dev)
2499{
2500
2501
2502
2503
2504 dev->trans_start = 0;
2505 dev->tx_queue_len = 30;
2506
2507 dev->flags = 0;
2508 dev->mtu = DEFAULT_STRIP_MTU;
2509 dev->type = ARPHRD_METRICOM;
2510 dev->hard_header_len = sizeof(STRIP_Header);
2511
2512
2513
2514
2515 *(MetricomAddress *)dev->broadcast = broadcast_address;
2516 dev->dev_addr[0] = 0;
2517 dev->addr_len = sizeof(MetricomAddress);
2518
2519 dev->header_ops = &strip_header_ops,
2520 dev->netdev_ops = &strip_netdev_ops;
2521}
2522
2523
2524
2525
2526
2527static void strip_free(struct strip *strip_info)
2528{
2529 spin_lock_bh(&strip_lock);
2530 list_del_rcu(&strip_info->list);
2531 spin_unlock_bh(&strip_lock);
2532
2533 strip_info->magic = 0;
2534
2535 free_netdev(strip_info->dev);
2536}
2537
2538
2539
2540
2541
2542static struct strip *strip_alloc(void)
2543{
2544 struct list_head *n;
2545 struct net_device *dev;
2546 struct strip *strip_info;
2547
2548 dev = alloc_netdev(sizeof(struct strip), "st%d",
2549 strip_dev_setup);
2550
2551 if (!dev)
2552 return NULL;
2553
2554
2555 strip_info = netdev_priv(dev);
2556 strip_info->dev = dev;
2557
2558 strip_info->magic = STRIP_MAGIC;
2559 strip_info->tty = NULL;
2560
2561 strip_info->gratuitous_arp = jiffies + LongTime;
2562 strip_info->arp_interval = 0;
2563 init_timer(&strip_info->idle_timer);
2564 strip_info->idle_timer.data = (long) dev;
2565 strip_info->idle_timer.function = strip_IdleTask;
2566
2567
2568 spin_lock_bh(&strip_lock);
2569 rescan:
2570
2571
2572
2573
2574
2575 list_for_each(n, &strip_list) {
2576 struct strip *s = hlist_entry(n, struct strip, list);
2577
2578 if (s->dev->base_addr == dev->base_addr) {
2579 ++dev->base_addr;
2580 goto rescan;
2581 }
2582 }
2583
2584 sprintf(dev->name, "st%ld", dev->base_addr);
2585
2586 list_add_tail_rcu(&strip_info->list, &strip_list);
2587 spin_unlock_bh(&strip_lock);
2588
2589 return strip_info;
2590}
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600static int strip_open(struct tty_struct *tty)
2601{
2602 struct strip *strip_info = tty->disc_data;
2603
2604
2605
2606
2607
2608 if (strip_info && strip_info->magic == STRIP_MAGIC)
2609 return -EEXIST;
2610
2611
2612
2613
2614
2615 if (tty->ops->write == NULL || tty->ops->set_termios == NULL)
2616 return -EOPNOTSUPP;
2617
2618
2619
2620
2621 if ((strip_info = strip_alloc()) == NULL)
2622 return -ENFILE;
2623
2624
2625
2626
2627
2628
2629 if (register_netdev(strip_info->dev) != 0) {
2630 printk(KERN_ERR "strip: register_netdev() failed.\n");
2631 strip_free(strip_info);
2632 return -ENFILE;
2633 }
2634
2635 strip_info->tty = tty;
2636 tty->disc_data = strip_info;
2637 tty->receive_room = 65536;
2638
2639 tty_driver_flush_buffer(tty);
2640
2641
2642
2643
2644
2645 strip_info->dev->type = ARPHRD_METRICOM;
2646
2647
2648
2649
2650
2651 tty->termios->c_iflag |= IGNBRK | IGNPAR;
2652 tty->termios->c_cflag |= CLOCAL;
2653 tty->termios->c_cflag &= ~HUPCL;
2654
2655 printk(KERN_INFO "STRIP: device \"%s\" activated\n",
2656 strip_info->dev->name);
2657
2658
2659
2660
2661 return (strip_info->dev->base_addr);
2662}
2663
2664
2665
2666
2667
2668
2669
2670
2671static void strip_close(struct tty_struct *tty)
2672{
2673 struct strip *strip_info = tty->disc_data;
2674
2675
2676
2677
2678
2679 if (!strip_info || strip_info->magic != STRIP_MAGIC)
2680 return;
2681
2682 unregister_netdev(strip_info->dev);
2683
2684 tty->disc_data = NULL;
2685 strip_info->tty = NULL;
2686 printk(KERN_INFO "STRIP: device \"%s\" closed down\n",
2687 strip_info->dev->name);
2688 strip_free(strip_info);
2689 tty->disc_data = NULL;
2690}
2691
2692
2693
2694
2695
2696static int strip_ioctl(struct tty_struct *tty, struct file *file,
2697 unsigned int cmd, unsigned long arg)
2698{
2699 struct strip *strip_info = tty->disc_data;
2700
2701
2702
2703
2704
2705 if (!strip_info || strip_info->magic != STRIP_MAGIC)
2706 return -EINVAL;
2707
2708 switch (cmd) {
2709 case SIOCGIFNAME:
2710 if(copy_to_user((void __user *) arg, strip_info->dev->name, strlen(strip_info->dev->name) + 1))
2711 return -EFAULT;
2712 break;
2713 case SIOCSIFHWADDR:
2714 {
2715 MetricomAddress addr;
2716
2717 if(copy_from_user(&addr, (void __user *) arg, sizeof(MetricomAddress)))
2718 return -EFAULT;
2719 return set_mac_address(strip_info, &addr);
2720 }
2721 default:
2722 return tty_mode_ioctl(tty, file, cmd, arg);
2723 break;
2724 }
2725 return 0;
2726}
2727
2728
2729
2730
2731
2732static struct tty_ldisc_ops strip_ldisc = {
2733 .magic = TTY_LDISC_MAGIC,
2734 .name = "strip",
2735 .owner = THIS_MODULE,
2736 .open = strip_open,
2737 .close = strip_close,
2738 .ioctl = strip_ioctl,
2739 .receive_buf = strip_receive_buf,
2740 .write_wakeup = strip_write_some_more,
2741};
2742
2743
2744
2745
2746
2747
2748
2749static char signon[] __initdata =
2750 KERN_INFO "STRIP: Version %s (unlimited channels)\n";
2751
2752static int __init strip_init_driver(void)
2753{
2754 int status;
2755
2756 printk(signon, StripVersion);
2757
2758
2759
2760
2761
2762 if ((status = tty_register_ldisc(N_STRIP, &strip_ldisc)))
2763 printk(KERN_ERR "STRIP: can't register line discipline (err = %d)\n",
2764 status);
2765
2766
2767
2768
2769 proc_net_fops_create(&init_net, "strip", S_IFREG | S_IRUGO, &strip_seq_fops);
2770
2771 return status;
2772}
2773
2774module_init(strip_init_driver);
2775
2776static const char signoff[] __exitdata =
2777 KERN_INFO "STRIP: Module Unloaded\n";
2778
2779static void __exit strip_exit_driver(void)
2780{
2781 int i;
2782 struct list_head *p,*n;
2783
2784
2785 list_for_each_safe(p, n, &strip_list) {
2786 struct strip *s = list_entry(p, struct strip, list);
2787 strip_free(s);
2788 }
2789
2790
2791 proc_net_remove(&init_net, "strip");
2792
2793 if ((i = tty_unregister_ldisc(N_STRIP)))
2794 printk(KERN_ERR "STRIP: can't unregister line discipline (err = %d)\n", i);
2795
2796 printk(signoff);
2797}
2798
2799module_exit(strip_exit_driver);
2800
2801MODULE_AUTHOR("Stuart Cheshire <cheshire@cs.stanford.edu>");
2802MODULE_DESCRIPTION("Starmode Radio IP (STRIP) Device Driver");
2803MODULE_LICENSE("Dual BSD/GPL");
2804
2805MODULE_SUPPORTED_DEVICE("Starmode Radio IP (STRIP) modem");
2806