aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS4
-rw-r--r--drivers/net/wireless/Kconfig24
-rw-r--r--drivers/net/wireless/Makefile1
-rw-r--r--drivers/net/wireless/strip.c2804
4 files changed, 2833 insertions, 0 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index f92707fee59..ec0c9c914f1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3908,6 +3908,10 @@ P: Ion Badulescu
3908M: ionut@cs.columbia.edu 3908M: ionut@cs.columbia.edu
3909S: Maintained 3909S: Maintained
3910 3910
3911STARMODE RADIO IP (STRIP) PROTOCOL DRIVER
3912W: http://mosquitonet.Stanford.EDU/strip.html
3913S: Unsupported ?
3914
3911STRADIS MPEG-2 DECODER DRIVER 3915STRADIS MPEG-2 DECODER DRIVER
3912P: Nathan Laredo 3916P: Nathan Laredo
3913M: laredo@gnu.org 3917M: laredo@gnu.org
diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig
index d5b006f5b86..91fc2c765d9 100644
--- a/drivers/net/wireless/Kconfig
+++ b/drivers/net/wireless/Kconfig
@@ -14,6 +14,30 @@ config WLAN_PRE80211
14 This option does not affect the kernel build, it only 14 This option does not affect the kernel build, it only
15 lets you choose drivers. 15 lets you choose drivers.
16 16
17config STRIP
18 tristate "STRIP (Metricom starmode radio IP)"
19 depends on INET && WLAN_PRE80211
20 select WIRELESS_EXT
21 ---help---
22 Say Y if you have a Metricom radio and intend to use Starmode Radio
23 IP. STRIP is a radio protocol developed for the MosquitoNet project
24 (on the WWW at <http://mosquitonet.stanford.edu/>) to send Internet
25 traffic using Metricom radios. Metricom radios are small, battery
26 powered, 100kbit/sec packet radio transceivers, about the size and
27 weight of a cellular telephone. (You may also have heard them called
28 "Metricom modems" but we avoid the term "modem" because it misleads
29 many people into thinking that you can plug a Metricom modem into a
30 phone line and use it as a modem.)
31
32 You can use STRIP on any Linux machine with a serial port, although
33 it is obviously most useful for people with laptop computers. If you
34 think you might get a Metricom radio in the future, there is no harm
35 in saying Y to STRIP now, except that it makes the kernel a bit
36 bigger.
37
38 To compile this as a module, choose M here: the module will be
39 called strip.
40
17config ARLAN 41config ARLAN
18 tristate "Aironet Arlan 655 & IC2200 DS support" 42 tristate "Aironet Arlan 655 & IC2200 DS support"
19 depends on ISA && !64BIT && WLAN_PRE80211 43 depends on ISA && !64BIT && WLAN_PRE80211
diff --git a/drivers/net/wireless/Makefile b/drivers/net/wireless/Makefile
index 2668934abbf..54a4f6f1db6 100644
--- a/drivers/net/wireless/Makefile
+++ b/drivers/net/wireless/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_IPW2100) += ipw2100.o
6 6
7obj-$(CONFIG_IPW2200) += ipw2200.o 7obj-$(CONFIG_IPW2200) += ipw2200.o
8 8
9obj-$(CONFIG_STRIP) += strip.o
9obj-$(CONFIG_ARLAN) += arlan.o 10obj-$(CONFIG_ARLAN) += arlan.o
10 11
11arlan-objs := arlan-main.o arlan-proc.o 12arlan-objs := arlan-main.o arlan-proc.o
diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c
new file mode 100644
index 00000000000..883af891ebf
--- /dev/null
+++ b/drivers/net/wireless/strip.c
@@ -0,0 +1,2804 @@
1/*
2 * Copyright 1996 The Board of Trustees of The Leland Stanford
3 * Junior University. All Rights Reserved.
4 *
5 * Permission to use, copy, modify, and distribute this
6 * software and its documentation for any purpose and without
7 * fee is hereby granted, provided that the above copyright
8 * notice appear in all copies. Stanford University
9 * makes no representations about the suitability of this
10 * software for any purpose. It is provided "as is" without
11 * express or implied warranty.
12 *
13 * strip.c This module implements Starmode Radio IP (STRIP)
14 * for kernel-based devices like TTY. It interfaces between a
15 * raw TTY, and the kernel's INET protocol layers (via DDI).
16 *
17 * Version: @(#)strip.c 1.3 July 1997
18 *
19 * Author: Stuart Cheshire <cheshire@cs.stanford.edu>
20 *
21 * Fixes: v0.9 12th Feb 1996 (SC)
22 * New byte stuffing (2+6 run-length encoding)
23 * New watchdog timer task
24 * New Protocol key (SIP0)
25 *
26 * v0.9.1 3rd March 1996 (SC)
27 * Changed to dynamic device allocation -- no more compile
28 * time (or boot time) limit on the number of STRIP devices.
29 *
30 * v0.9.2 13th March 1996 (SC)
31 * Uses arp cache lookups (but doesn't send arp packets yet)
32 *
33 * v0.9.3 17th April 1996 (SC)
34 * Fixed bug where STR_ERROR flag was getting set unneccessarily
35 * (causing otherwise good packets to be unneccessarily dropped)
36 *
37 * v0.9.4 27th April 1996 (SC)
38 * First attempt at using "&COMMAND" Starmode AT commands
39 *
40 * v0.9.5 29th May 1996 (SC)
41 * First attempt at sending (unicast) ARP packets
42 *
43 * v0.9.6 5th June 1996 (Elliot)
44 * Put "message level" tags in every "printk" statement
45 *
46 * v0.9.7 13th June 1996 (laik)
47 * Added support for the /proc fs
48 *
49 * v0.9.8 July 1996 (Mema)
50 * Added packet logging
51 *
52 * v1.0 November 1996 (SC)
53 * Fixed (severe) memory leaks in the /proc fs code
54 * Fixed race conditions in the logging code
55 *
56 * v1.1 January 1997 (SC)
57 * Deleted packet logging (use tcpdump instead)
58 * Added support for Metricom Firmware v204 features
59 * (like message checksums)
60 *
61 * v1.2 January 1997 (SC)
62 * Put portables list back in
63 *
64 * v1.3 July 1997 (SC)
65 * Made STRIP driver set the radio's baud rate automatically.
66 * It is no longer necessarily to manually set the radio's
67 * rate permanently to 115200 -- the driver handles setting
68 * the rate automatically.
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/* Header files */
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/* Useful structures and definitions */
119
120/*
121 * A MetricomKey identifies the protocol being carried inside a Metricom
122 * Starmode packet.
123 */
124
125typedef union {
126 __u8 c[4];
127 __u32 l;
128} MetricomKey;
129
130/*
131 * An IP address can be viewed as four bytes in memory (which is what it is) or as
132 * a single 32-bit long (which is convenient for assignment, equality testing etc.)
133 */
134
135typedef union {
136 __u8 b[4];
137 __u32 l;
138} IPaddr;
139
140/*
141 * A MetricomAddressString is used to hold a printable representation of
142 * a Metricom address.
143 */
144
145typedef struct {
146 __u8 c[24];
147} MetricomAddressString;
148
149/* Encapsulation can expand packet of size x to 65/64x + 1
150 * Sent packet looks like "<CR>*<address>*<key><encaps payload><CR>"
151 * 1 1 1-18 1 4 ? 1
152 * eg. <CR>*0000-1234*SIP0<encaps payload><CR>
153 * We allow 31 bytes for the stars, the key, the address and the <CR>s
154 */
155#define STRIP_ENCAP_SIZE(X) (32 + (X)*65L/64L)
156
157/*
158 * A STRIP_Header is never really sent over the radio, but making a dummy
159 * header for internal use within the kernel that looks like an Ethernet
160 * header makes certain other software happier. For example, tcpdump
161 * already understands Ethernet headers.
162 */
163
164typedef struct {
165 MetricomAddress dst_addr; /* Destination address, e.g. "0000-1234" */
166 MetricomAddress src_addr; /* Source address, e.g. "0000-5678" */
167 unsigned short protocol; /* The protocol type, using Ethernet codes */
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 * Holds the radio's firmware version.
185 */
186typedef struct {
187 char c[50];
188} FirmwareVersion;
189
190/*
191 * Holds the radio's serial number.
192 */
193typedef struct {
194 char c[18];
195} SerialNumber;
196
197/*
198 * Holds the radio's battery voltage.
199 */
200typedef struct {
201 char c[11];
202} BatteryVoltage;
203
204typedef struct {
205 char c[8];
206} char8;
207
208enum {
209 NoStructure = 0, /* Really old firmware */
210 StructuredMessages = 1, /* Parsable AT response msgs */
211 ChecksummedMessages = 2 /* Parsable AT response msgs with checksums */
212};
213
214struct strip {
215 int magic;
216 /*
217 * These are pointers to the malloc()ed frame buffers.
218 */
219
220 unsigned char *rx_buff; /* buffer for received IP packet */
221 unsigned char *sx_buff; /* buffer for received serial data */
222 int sx_count; /* received serial data counter */
223 int sx_size; /* Serial buffer size */
224 unsigned char *tx_buff; /* transmitter buffer */
225 unsigned char *tx_head; /* pointer to next byte to XMIT */
226 int tx_left; /* bytes left in XMIT queue */
227 int tx_size; /* Serial buffer size */
228
229 /*
230 * STRIP interface statistics.
231 */
232
233 unsigned long rx_packets; /* inbound frames counter */
234 unsigned long tx_packets; /* outbound frames counter */
235 unsigned long rx_errors; /* Parity, etc. errors */
236 unsigned long tx_errors; /* Planned stuff */
237 unsigned long rx_dropped; /* No memory for skb */
238 unsigned long tx_dropped; /* When MTU change */
239 unsigned long rx_over_errors; /* Frame bigger then STRIP buf. */
240
241 unsigned long pps_timer; /* Timer to determine pps */
242 unsigned long rx_pps_count; /* Counter to determine pps */
243 unsigned long tx_pps_count; /* Counter to determine pps */
244 unsigned long sx_pps_count; /* Counter to determine pps */
245 unsigned long rx_average_pps; /* rx packets per second * 8 */
246 unsigned long tx_average_pps; /* tx packets per second * 8 */
247 unsigned long sx_average_pps; /* sent packets per second * 8 */
248
249#ifdef EXT_COUNTERS
250 unsigned long rx_bytes; /* total received bytes */
251 unsigned long tx_bytes; /* total received bytes */
252 unsigned long rx_rbytes; /* bytes thru radio i/f */
253 unsigned long tx_rbytes; /* bytes thru radio i/f */
254 unsigned long rx_sbytes; /* tot bytes thru serial i/f */
255 unsigned long tx_sbytes; /* tot bytes thru serial i/f */
256 unsigned long rx_ebytes; /* tot stat/err bytes */
257 unsigned long tx_ebytes; /* tot stat/err bytes */
258#endif
259
260 /*
261 * Internal variables.
262 */
263
264 struct list_head list; /* Linked list of devices */
265
266 int discard; /* Set if serial error */
267 int working; /* Is radio working correctly? */
268 int firmware_level; /* Message structuring level */
269 int next_command; /* Next periodic command */
270 unsigned int user_baud; /* The user-selected baud rate */
271 int mtu; /* Our mtu (to spot changes!) */
272 long watchdog_doprobe; /* Next time to test the radio */
273 long watchdog_doreset; /* Time to do next reset */
274 long gratuitous_arp; /* Time to send next ARP refresh */
275 long arp_interval; /* Next ARP interval */
276 struct timer_list idle_timer; /* For periodic wakeup calls */
277 MetricomAddress true_dev_addr; /* True address of radio */
278 int manual_dev_addr; /* Hack: See note below */
279
280 FirmwareVersion firmware_version; /* The radio's firmware version */
281 SerialNumber serial_number; /* The radio's serial number */
282 BatteryVoltage battery_voltage; /* The radio's battery voltage */
283
284 /*
285 * Other useful structures.
286 */
287
288 struct tty_struct *tty; /* ptr to TTY structure */
289 struct net_device *dev; /* Our device structure */
290
291 /*
292 * Neighbour radio records
293 */
294
295 MetricomNodeTable portables;
296 MetricomNodeTable poletops;
297};
298
299/*
300 * Note: manual_dev_addr hack
301 *
302 * It is not possible to change the hardware address of a Metricom radio,
303 * or to send packets with a user-specified hardware source address, thus
304 * trying to manually set a hardware source address is a questionable
305 * thing to do. However, if the user *does* manually set the hardware
306 * source address of a STRIP interface, then the kernel will believe it,
307 * and use it in certain places. For example, the hardware address listed
308 * by ifconfig will be the manual address, not the true one.
309 * (Both addresses are listed in /proc/net/strip.)
310 * Also, ARP packets will be sent out giving the user-specified address as
311 * the source address, not the real address. This is dangerous, because
312 * it means you won't receive any replies -- the ARP replies will go to
313 * the specified address, which will be some other radio. The case where
314 * this is useful is when that other radio is also connected to the same
315 * machine. This allows you to connect a pair of radios to one machine,
316 * and to use one exclusively for inbound traffic, and the other
317 * exclusively for outbound traffic. Pretty neat, huh?
318 *
319 * Here's the full procedure to set this up:
320 *
321 * 1. "slattach" two interfaces, e.g. st0 for outgoing packets,
322 * and st1 for incoming packets
323 *
324 * 2. "ifconfig" st0 (outbound radio) to have the hardware address
325 * which is the real hardware address of st1 (inbound radio).
326 * Now when it sends out packets, it will masquerade as st1, and
327 * replies will be sent to that radio, which is exactly what we want.
328 *
329 * 3. Set the route table entry ("route add default ..." or
330 * "route add -net ...", as appropriate) to send packets via the st0
331 * interface (outbound radio). Do not add any route which sends packets
332 * out via the st1 interface -- that radio is for inbound traffic only.
333 *
334 * 4. "ifconfig" st1 (inbound radio) to have hardware address zero.
335 * This tells the STRIP driver to "shut down" that interface and not
336 * send any packets through it. In particular, it stops sending the
337 * periodic gratuitous ARP packets that a STRIP interface normally sends.
338 * Also, when packets arrive on that interface, it will search the
339 * interface list to see if there is another interface who's manual
340 * hardware address matches its own real address (i.e. st0 in this
341 * example) and if so it will transfer ownership of the skbuff to
342 * that interface, so that it looks to the kernel as if the packet
343 * arrived on that interface. This is necessary because when the
344 * kernel sends an ARP packet on st0, it expects to get a reply on
345 * st0, and if it sees the reply come from st1 then it will ignore
346 * it (to be accurate, it puts the entry in the ARP table, but
347 * labelled in such a way that st0 can't use it).
348 *
349 * Thanks to Petros Maniatis for coming up with the idea of splitting
350 * inbound and outbound traffic between two interfaces, which turned
351 * out to be really easy to implement, even if it is a bit of a hack.
352 *
353 * Having set a manual address on an interface, you can restore it
354 * to automatic operation (where the address is automatically kept
355 * consistent with the real address of the radio) by setting a manual
356 * address of all ones, e.g. "ifconfig st0 hw strip FFFFFFFFFFFF"
357 * This 'turns off' manual override mode for the device address.
358 *
359 * Note: The IEEE 802 headers reported in tcpdump will show the *real*
360 * radio addresses the packets were sent and received from, so that you
361 * can see what is really going on with packets, and which interfaces
362 * they are really going through.
363 */
364
365
366/************************************************************************/
367/* Constants */
368
369/*
370 * CommandString1 works on all radios
371 * Other CommandStrings are only used with firmware that provides structured responses.
372 *
373 * ats319=1 Enables Info message for node additions and deletions
374 * ats319=2 Enables Info message for a new best node
375 * ats319=4 Enables checksums
376 * ats319=8 Enables ACK messages
377 */
378
379static const int MaxCommandStringLength = 32;
380static const int CompatibilityCommand = 1;
381
382static const char CommandString0[] = "*&COMMAND*ATS319=7"; /* Turn on checksums & info messages */
383static const char CommandString1[] = "*&COMMAND*ATS305?"; /* Query radio name */
384static const char CommandString2[] = "*&COMMAND*ATS325?"; /* Query battery voltage */
385static const char CommandString3[] = "*&COMMAND*ATS300?"; /* Query version information */
386static const char CommandString4[] = "*&COMMAND*ATS311?"; /* Query poletop list */
387static const char CommandString5[] = "*&COMMAND*AT~LA"; /* Query portables list */
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; /* One minute */
421
422/*
423 * Maximum Starmode packet length is 1183 bytes. Allowing 4 bytes for
424 * protocol key, 4 bytes for checksum, one byte for CR, and 65/64 expansion
425 * for STRIP encoding, that translates to a maximum payload MTU of 1155.
426 * Note: A standard NFS 1K data packet is a total of 0x480 (1152) bytes
427 * long, including IP header, UDP header, and NFS header. Setting the STRIP
428 * MTU to 1152 allows us to send default sized NFS packets without fragmentation.
429 */
430static const unsigned short MAX_SEND_MTU = 1152;
431static const unsigned short MAX_RECV_MTU = 1500; /* Hoping for Ethernet sized packets in the future! */
432static const unsigned short DEFAULT_STRIP_MTU = 1152;
433static const int STRIP_MAGIC = 0x5303;
434static const long LongTime = 0x7FFFFFFF;
435
436/************************************************************************/
437/* Global variables */
438
439static LIST_HEAD(strip_list);
440static DEFINE_SPINLOCK(strip_lock);
441
442/************************************************************************/
443/* Macros */
444
445/* Returns TRUE if text T begins with prefix P */
446#define has_prefix(T,L,P) (((L) >= sizeof(P)-1) && !strncmp((T), (P), sizeof(P)-1))
447
448/* Returns TRUE if text T of length L is equal to string S */
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/* Utility routines */
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/* Byte stuffing/unstuffing routines */
519
520/* Stuffing scheme:
521 * 00 Unused (reserved character)
522 * 01-3F Run of 2-64 different characters
523 * 40-7F Run of 1-64 different characters plus a single zero at the end
524 * 80-BF Run of 1-64 of the same character
525 * C0-FF Run of 1-64 zeroes (ASCII 0)
526 */
527
528typedef enum {
529 Stuff_Diff = 0x00,
530 Stuff_DiffZero = 0x40,
531 Stuff_Same = 0x80,
532 Stuff_Zero = 0xC0,
533 Stuff_NoCode = 0xFF, /* Special code, meaning no code selected */
534
535 Stuff_CodeMask = 0xC0,
536 Stuff_CountMask = 0x3F,
537 Stuff_MaxCount = 0x3F,
538 Stuff_Magic = 0x0D /* The value we are eliminating */
539} StuffingCode;
540
541/* StuffData encodes the data starting at "src" for "length" bytes.
542 * It writes it to the buffer pointed to by "dst" (which must be at least
543 * as long as 1 + 65/64 of the input length). The output may be up to 1.6%
544 * larger than the input for pathological input, but will usually be smaller.
545 * StuffData returns the new value of the dst pointer as its result.
546 * "code_ptr_ptr" points to a "__u8 *" which is used to hold encoding state
547 * between calls, allowing an encoded packet to be incrementally built up
548 * from small parts. On the first call, the "__u8 *" pointed to should be
549 * initialized to NULL; between subsequent calls the calling routine should
550 * leave the value alone and simply pass it back unchanged so that the
551 * encoder can recover its current state.
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 * Recover state from last call, if applicable
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 /* Stuff_NoCode: If no current code, select one */
578 case Stuff_NoCode:
579 /* Record where we're going to put this code */
580 code_ptr = dst++;
581 count = 0; /* Reset the count (zero means one instance) */
582 /* Tentatively start a new block */
583 if (*src == 0) {
584 code = Stuff_Zero;
585 src++;
586 } else {
587 code = Stuff_Same;
588 *dst++ = *src++ ^ Stuff_Magic;
589 }
590 /* Note: We optimistically assume run of same -- */
591 /* which will be fixed later in Stuff_Same */
592 /* if it turns out not to be true. */
593 break;
594
595 /* Stuff_Zero: We already have at least one zero encoded */
596 case Stuff_Zero:
597 /* If another zero, count it, else finish this code block */
598 if (*src == 0) {
599 count++;
600 src++;
601 } else {
602 StuffData_FinishBlock(Stuff_Zero + count);
603 }
604 break;
605
606 /* Stuff_Same: We already have at least one byte encoded */
607 case Stuff_Same:
608 /* If another one the same, count it */
609 if ((*src ^ Stuff_Magic) == code_ptr[1]) {
610 count++;
611 src++;
612 break;
613 }
614 /* else, this byte does not match this block. */
615 /* If we already have two or more bytes encoded, finish this code block */
616 if (count) {
617 StuffData_FinishBlock(Stuff_Same + count);
618 break;
619 }
620 /* else, we only have one so far, so switch to Stuff_Diff code */
621 code = Stuff_Diff;
622 /* and fall through to Stuff_Diff case below
623 * Note cunning cleverness here: case Stuff_Diff compares
624 * the current character with the previous two to see if it
625 * has a run of three the same. Won't this be an error if
626 * there aren't two previous characters stored to compare with?
627 * No. Because we know the current character is *not* the same
628 * as the previous one, the first test below will necessarily
629 * fail and the send half of the "if" won't be executed.
630 */
631
632 /* Stuff_Diff: We have at least two *different* bytes encoded */
633 case Stuff_Diff:
634 /* If this is a zero, must encode a Stuff_DiffZero, and begin a new block */
635 if (*src == 0) {
636 StuffData_FinishBlock(Stuff_DiffZero +
637 count);
638 }
639 /* else, if we have three in a row, it is worth starting a Stuff_Same block */
640 else if ((*src ^ Stuff_Magic) == dst[-1]
641 && dst[-1] == dst[-2]) {
642 /* Back off the last two characters we encoded */
643 code += count - 2;
644 /* Note: "Stuff_Diff + 0" is an illegal code */
645 if (code == Stuff_Diff + 0) {
646 code = Stuff_Same + 0;
647 }
648 StuffData_FinishBlock(code);
649 code_ptr = dst - 2;
650 /* dst[-1] already holds the correct value */
651 count = 2; /* 2 means three bytes encoded */
652 code = Stuff_Same;
653 }
654 /* else, another different byte, so add it to the block */
655 else {
656 *dst++ = *src ^ Stuff_Magic;
657 count++;
658 }
659 src++; /* Consume the byte */
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 * UnStuffData decodes the data at "src", up to (but not including) "end".
677 * It writes the decoded data into the buffer pointed to by "dst", up to a
678 * maximum of "dst_length", and returns the new value of "src" so that a
679 * follow-on call can read more data, continuing from where the first left off.
680 *
681 * There are three types of results:
682 * 1. The source data runs out before extracting "dst_length" bytes:
683 * UnStuffData returns NULL to indicate failure.
684 * 2. The source data produces exactly "dst_length" bytes:
685 * UnStuffData returns new_src = end to indicate that all bytes were consumed.
686 * 3. "dst_length" bytes are extracted, with more remaining.
687 * UnStuffData returns new_src < end to indicate that there are more bytes
688 * to be read.
689 *
690 * Note: The decoding may be destructive, in that it may alter the source
691 * data in the process of decoding it (this is necessary to allow a follow-on
692 * call to resume correctly).
693 */
694
695static __u8 *UnStuffData(__u8 * src, __u8 * end, __u8 * dst,
696 __u32 dst_length)
697{
698 __u8 *dst_end = dst + dst_length;
699 /* Sanity check */
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/* General routines for STRIP */
769
770/*
771 * set_baud sets the baud rate to the rate defined by baudcode
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 * Convert a string to a Metricom Address.
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 * Convert a Metricom Address to a string.
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 * Note: Must make sure sx_size is big enough to receive a stuffed
820 * MAX_RECV_MTU packet. Additionally, we also want to ensure that it's
821 * big enough to receive a large radio neighbour list (currently 4K).
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 * MTU has been changed by the IP layer.
849 * We could be in
850 * an upcall from the tty driver, or in an ip packet queue.
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 * Set the timer to go off in one second.
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 * If the time is in the near future, time_delta prints the number of
920 * seconds to go into the buffer and returns the address of the buffer.
921 * If the time is not in the near future, it returns the address of the
922 * string "Not scheduled" The buffer must be long enough to contain the
923 * ascii representation of the number plus 9 charactes for the " seconds"
924 * and the null character.
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; /* Don't print negative times */
934 sprintf(buffer, "%ld seconds", time / HZ);
935 return (buffer);
936}
937
938/* get Nth element of the linked list */
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 /* We wrap this in a do/while loop, so if the table changes */
985 /* while we're reading it, we just go around and try again. */
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 * This function prints radio status information via the seq_file
1007 * interface. The interface takes care of buffer size and over
1008 * run issues.
1009 *
1010 * The buffer in seq_file is PAGESIZE (4K)
1011 * so this routine should never print more or it will get truncated.
1012 * With the maximum of 32 portables and 32 poletops
1013 * reported, the routine outputs 3107 bytes into the buffer.
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 /* First, we must copy all of our data to a safe place, */
1022 /* in case a serial interrupt comes in and changes it. */
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 * This function is exports status information from the STRIP driver through
1116 * the /proc file system.
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/* Sending routines */
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 * If the radio isn't working anymore,
1162 * we should clear the old status information.
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 /* Mark radio address as unknown */
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 /* If the user has selected a baud rate above 38.4 see what magic we have to do */
1196 if (strip_info->user_baud > 38400) {
1197 /*
1198 * Subtle stuff: Pay attention :-)
1199 * If the serial port is currently at the user's selected (>38.4) rate,
1200 * then we temporarily switch to 19.2 and issue the ATS304 command
1201 * to tell the radio to switch to the user's selected rate.
1202 * If the serial port is not currently at that rate, that means we just
1203 * issued the ATS304 command last time through, so this time we restore
1204 * the user's selected rate and issue the normal starmode reset string.
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]; /* For now */
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 * Called by the driver when there's room for more data. If we have
1232 * more packets to send, we send them here.
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 /* First make sure we're connected. */
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 { /* Else start transmission of another packet */
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 /*HexDump("strip_make_packet", strip_info, skb->data, skb->data + skb->len); */
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 * If we're sending to ourselves, discard the packet.
1309 * (Metricom radios choke if they try to send a packet to their own address.)
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 * If this is a broadcast packet, send it to our designated Metricom
1319 * 'broadcast hub' radio (First byte of address being 0xFF means broadcast)
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 /* arp_query returns 1 if it succeeds in looking up the address, 0 if it fails */
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 * If we are the broadcast hub, don't bother sending to ourselves.
1344 * (Metricom radios choke if they try to send a packet to their own address.)
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 * 1. If we have a packet, encapsulate it and put it in the buffer
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++; /* Count another successful packet */
1400#ifdef EXT_COUNTERS
1401 strip_info->tx_bytes += skb->len;
1402 strip_info->tx_rbytes += ptr - strip_info->tx_buff;
1403#endif
1404 /*DumpData("Sending:", strip_info, strip_info->tx_buff, ptr); */
1405 /*HexDump("Sending", strip_info, strip_info->tx_buff, ptr); */
1406 }
1407 }
1408
1409 /*
1410 * 2. If it is time for another tickle, tack it on, after the packet
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++ = '*'; /* First send "**" to provoke an error message */
1427 *ptr++ = '*';
1428
1429 /* Then add the command */
1430 memcpy(ptr, ts.string, ts.length);
1431
1432 /* Add a checksum ? */
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; /* Terminate the command with a <CR> */
1439
1440 /* Cycle to next periodic command? */
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 /*printk(KERN_INFO "%s: Routine radio test.\n", strip_info->dev->name); */
1451 }
1452
1453 /*
1454 * 3. Set up the strip_info ready to send the data (if any).
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 * 4. Debugging check to make sure we're not overflowing the buffer.
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 * 5. If watchdog has expired, reset the radio. Note: if there's data waiting in
1470 * the buffer, strip_write_some_more will send it after the reset has finished
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 * 6. If it is time for a periodic ARP, queue one up to be sent.
1495 * We only do this if:
1496 * 1. The radio is working
1497 * 2. It's time to send another periodic ARP
1498 * 3. We really know what our address is (and it is not manually set to zero)
1499 * 4. We have a designated broadcast address configured
1500 * If we queue up an ARP packet when we don't have a designated broadcast
1501 * address configured, then the packet will just have to be discarded in
1502 * strip_make_packet. This is not fatal, but it causes misleading information
1503 * to be displayed in tcpdump. tcpdump will report that periodic APRs are
1504 * being sent, when in fact they are not, because they are all being dropped
1505 * in the strip_make_packet routine.
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 /*printk(KERN_INFO "%s: Sending gratuitous ARP with interval %ld\n",
1513 strip_info->dev->name, strip_info->arp_interval / HZ); */
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, /* Target address of ARP packet is our address */
1521 strip_info->dev, /* Device to send packet on */
1522 addr, /* Source IP address this ARP packet comes from */
1523 NULL, /* Destination HW address is NULL (broadcast it) */
1524 strip_info->dev->dev_addr, /* Source HW address is our HW address */
1525 strip_info->dev->dev_addr); /* Target HW address is our HW address (redundant) */
1526 }
1527
1528 /*
1529 * 7. All ready. Start the transmission
1530 */
1531 strip_write_some_more(strip_info->tty);
1532}
1533
1534/* Encapsulate a datagram and kick it into a TTY queue. */
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 * IdleTask periodically calls strip_xmit, so even when we have no IP packets
1589 * to send for an extended period of time, the watchdog processing still gets
1590 * done to ensure that the radio stays in Starmode
1591 */
1592
1593static void strip_IdleTask(unsigned long parameter)
1594{
1595 strip_xmit(NULL, (struct net_device *) parameter);
1596}
1597
1598/*
1599 * Create the MAC header for an arbitrary protocol layer
1600 *
1601 * saddr!=NULL means use this specific address (n/a for Metricom)
1602 * saddr==NULL means use default device source address
1603 * daddr!=NULL means use this destination address
1604 * daddr==NULL means leave destination address alone
1605 * (e.g. unresolved arp -- kernel will call
1606 * rebuild_header later to fill in the address)
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 /*printk(KERN_INFO "%s: strip_header 0x%04X %s\n", dev->name, type,
1617 type == ETH_P_IP ? "IP" : type == ETH_P_ARP ? "ARP" : ""); */
1618
1619 header->src_addr = strip_info->true_dev_addr;
1620 header->protocol = htons(type);
1621
1622 /*HexDump("strip_header", netdev_priv(dev), skb->data, skb->data + skb->len); */
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 * Rebuild the MAC header. This is called after an ARP
1633 * (or in future other address resolution) has completed on this
1634 * sk_buff. We now let ARP fill in the other fields.
1635 * I think this should return zero if packet is ready to send,
1636 * or non-zero if it needs more time to do an address lookup
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 /* Arp find returns zero if if knows the address, */
1645 /* or if it doesn't know the address it sends an ARP packet and returns non-zero */
1646 return arp_find(header->dst_addr.c, skb) ? 1 : 0;
1647#else
1648 return 0;
1649#endif
1650}
1651
1652
1653/************************************************************************/
1654/* Receiving routines */
1655
1656/*
1657 * This function parses the response to the ATS300? command,
1658 * extracting the radio version and serial number.
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 /* Determine the beginning of the second line of the payload */
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 /* Determine the end of line */
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 /* Look for the first colon */
1690 while (p < end && *p != ':')
1691 p++;
1692 if (p >= end)
1693 return;
1694 /* Skip over the space */
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 * This function parses the response to the ATS325? command,
1708 * extracting the radio battery voltage.
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 * This function parses the responses to the AT~LA and ATS311 commands,
1726 * which list the radio's neighbours.
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 /* See if our radio address has changed */
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 /* Give the radio a few seconds to get its head straight, then send an arp */
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")) { /* Not in StarMode! */
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")) { /* Remap handle */
1804 /* We ignore "Remap handle" messages for now */
1805 }
1806
1807 else if (has_prefix(msg, len, "003")) { /* Can't resolve name */
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")) { /* Name too small or missing */
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 * If the radio has just entered a working state, we should do our first
1830 * probe ASAP, so that we find out our radio address etc. without delay.
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; /* Try to enable checksums ASAP */
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 * If this message has a valid checksum on the end, then the call to verify_checksum
1844 * will elevate the firmware_level to ChecksummedMessages for us. (The actual return
1845 * code from verify_checksum is ignored here.)
1846 */
1847 verify_checksum(strip_info);
1848 /*
1849 * If the radio has structured messages but we don't yet have all our information about it,
1850 * we should do probes without delay, until we have gathered all the information
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")) /* Bad count specification */
1858 RecvErr("Error Msg:", strip_info);
1859
1860 else if (has_prefix(msg, len, "006")) /* Header too big */
1861 RecvErr("Error Msg:", strip_info);
1862
1863 else if (has_prefix(msg, len, "007")) { /* Body too big */
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")) { /* Bad character in name */
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")) /* No count or line terminator */
1878 RecvErr("Error Msg:", strip_info);
1879
1880 else if (has_prefix(msg, len, "010")) /* Invalid checksum */
1881 RecvErr("Error Msg:", strip_info);
1882
1883 else if (has_prefix(msg, len, "011")) /* Checksum didn't match */
1884 RecvErr("Error Msg:", strip_info);
1885
1886 else if (has_prefix(msg, len, "012")) /* Failed to transmit packet */
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++; /* Skip past first newline character */
1900 /* Now ptr points to the AT command, and p points to the text of the response. */
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 /* Currently we don't do anything with ACKs from the radio */
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 /* If our hardware address is *manually set* to zero, and we know our */
1942 /* real radio hardware address, try to find another strip device that has been */
1943 /* manually set to that address that we can 'transfer ownership' of this packet to */
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 * Send one completely decapsulated datagram to the next layer.
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 /* Having put a fake header on the front of the sk_buff for the */
1990 /* benefit of tools like tcpdump, skb_pull now 'consumes' that */
1991 /* fake header before we hand the packet up to the next layer. */
1992 skb_pull(skb, sizeof(STRIP_Header));
1993
1994 /* Finally, hand the packet up to the next layer (e.g. IP or ARP, etc.) */
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 /* Decode start of the IP packet header */
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 /*printk(KERN_INFO "%s: Got %d byte IP packet\n", strip_info->dev->name, packetlen); */
2028
2029 /* Decode remainder of the IP packet */
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 /* Decode start of the ARP packet */
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 /*printk(KERN_INFO "%s: Got %d byte ARP %s\n",
2072 strip_info->dev->name, packetlen,
2073 ntohs(arphdr->ar_op) == ARPOP_REQUEST ? "request" : "reply"); */
2074
2075 /* Decode remainder of the ARP packet */
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 * process_text_message processes a <CR>-terminated block of data received
2095 * from the radio that doesn't begin with a '*' character. All normal
2096 * Starmode communication messages with the radio begin with a '*',
2097 * so any text that does not indicates a serial port error, a radio that
2098 * is in Hayes command mode instead of Starmode, or a radio with really
2099 * old firmware that doesn't frame its Starmode responses properly.
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 /* Check for anything that looks like it might be our radio name */
2107 /* (This is here for backwards compatibility with old firmware) */
2108 if (len == 9 && get_radio_address(strip_info, msg) == 0)
2109 return;
2110
2111 if (text_equal(msg, len, "OK"))
2112 return; /* Ignore 'OK' responses from prior commands */
2113 if (text_equal(msg, len, "ERROR"))
2114 return; /* Ignore 'ERROR' messages */
2115 if (has_prefix(msg, len, "ate0q1"))
2116 return; /* Ignore character echo back from the radio */
2117
2118 /* Catch other error messages */
2119 /* (This is here for backwards compatibility with old firmware) */
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 * process_message processes a <CR>-terminated block of data received
2130 * from the radio. If the radio is not in Starmode or has old firmware,
2131 * it may be a line of text in response to an AT command. Ideally, with
2132 * a current radio that's properly in Starmode, all data received should
2133 * be properly framed and checksummed radio message blocks, containing
2134 * either a starmode packet, or a other communication from the radio
2135 * firmware, like "INF_" Info messages and &COMMAND responses.
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 /*HexDump("Receiving", strip_info, ptr, end); */
2146
2147 /* Check for start of address marker, and then skip over it */
2148 if (*ptr == '*')
2149 ptr++;
2150 else {
2151 process_text_message(strip_info);
2152 return;
2153 }
2154
2155 /* Copy out the return address */
2156 while (ptr < end && *ptr != '*'
2157 && sptr < ARRAY_END(sendername) - 1)
2158 *sptr++ = *ptr++;
2159 *sptr = 0; /* Null terminate the sender name */
2160
2161 /* Check for end of address marker, and skip over it */
2162 if (ptr >= end || *ptr != '*') {
2163 RecvErr("No second *", strip_info);
2164 return;
2165 }
2166 ptr++; /* Skip the second '*' */
2167
2168 /* If the sender name is "&COMMAND", ignore this 'packet' */
2169 /* (This is here for backwards compatibility with old firmware) */
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 /* Get the protocol key out of the buffer */
2182 key.c[0] = *ptr++;
2183 key.c[1] = *ptr++;
2184 key.c[2] = *ptr++;
2185 key.c[3] = *ptr++;
2186
2187 /* If we're using checksums, verify the checksum at the end of the packet */
2188 if (strip_info->firmware_level >= ChecksummedMessages) {
2189 end -= 4; /* Chop the last four bytes off the packet (they're the checksum) */
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 /*printk(KERN_INFO "%s: Got packet from \"%s\".\n", strip_info->dev->name, sendername); */
2201
2202 /*
2203 * Fill in (pseudo) source and destination addresses in the packet.
2204 * We assume that the destination address was our address (the radio does not
2205 * tell us this). If the radio supplies a source address, then we use it.
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 * Handle the 'receiver data ready' interrupt.
2256 * This function is called by the 'tty_io' module in the kernel when
2257 * a block of STRIP data has been received, which can now be decapsulated
2258 * and sent on to some IP layer for further processing.
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#if 0
2273 {
2274 struct timeval tv;
2275 do_gettimeofday(&tv);
2276 printk(KERN_INFO
2277 "**** strip_receive_buf: %3d bytes at %02d.%06d\n",
2278 count, tv.tv_sec % 100, tv.tv_usec);
2279 }
2280#endif
2281
2282#ifdef EXT_COUNTERS
2283 strip_info->rx_sbytes += count;
2284#endif
2285
2286 /* Read the characters out of the buffer */
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) { /* If there's a serial error, record it */
2292 /* If we have some characters in the buffer, discard them */
2293 strip_info->discard = strip_info->sx_count;
2294 strip_info->rx_errors++;
2295 }
2296
2297 /* Leading control characters (CR, NL, Tab, etc.) are ignored */
2298 if (strip_info->sx_count > 0 || *cp >= ' ') {
2299 if (*cp == 0x0D) { /* If end of packet, decide what to do with it */
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 /* Make sure we have space in the buffer */
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/* General control routines */
2344
2345static int set_mac_address(struct strip *strip_info,
2346 MetricomAddress * addr)
2347{
2348 /*
2349 * We're using a manually specified address if the address is set
2350 * to anything other than all ones. Setting the address to all ones
2351 * disables manual mode and goes back to automatic address determination
2352 * (tracking the true address that the radio has).
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/* Opening and closing */
2394
2395/*
2396 * Here's the order things happen:
2397 * When the user runs "slattach -p strip ..."
2398 * 1. The TTY module calls strip_open;;
2399 * 2. strip_open calls strip_alloc
2400 * 3. strip_alloc calls register_netdev
2401 * 4. register_netdev calls strip_dev_init
2402 * 5. then strip_open finishes setting up the strip_info
2403 *
2404 * When the user runs "ifconfig st<x> up address netmask ..."
2405 * 6. strip_open_low gets called
2406 *
2407 * When the user runs "ifconfig st<x> down"
2408 * 7. strip_close_low gets called
2409 *
2410 * When the user kills the slattach process
2411 * 8. strip_close gets called
2412 * 9. strip_close calls dev_close
2413 * 10. if the device is still up, then dev_close calls strip_close_low
2414 * 11. strip_close calls strip_free
2415 */
2416
2417/* Open the low-level part of the STRIP channel. Easy! */
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 * Close the low-level part of the STRIP channel. Easy!
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 * Free all STRIP frame buffers.
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 * This routine is called by DDI when the
2483 * (dynamically assigned) device is registered
2484 */
2485
2486static void strip_dev_setup(struct net_device *dev)
2487{
2488 /*
2489 * Finish setting up the DEVICE info.
2490 */
2491
2492 dev->trans_start = 0;
2493 dev->last_rx = 0;
2494 dev->tx_queue_len = 30; /* Drop after 30 frames queued */
2495
2496 dev->flags = 0;
2497 dev->mtu = DEFAULT_STRIP_MTU;
2498 dev->type = ARPHRD_METRICOM; /* dtang */
2499 dev->hard_header_len = sizeof(STRIP_Header);
2500 /*
2501 * dev->priv Already holds a pointer to our struct strip
2502 */
2503
2504 *(MetricomAddress *) & dev->broadcast = broadcast_address;
2505 dev->dev_addr[0] = 0;
2506 dev->addr_len = sizeof(MetricomAddress);
2507
2508 /*
2509 * Pointers to interface service routines.
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 * Free a STRIP channel.
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 * Allocate a new free STRIP channel
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; /* If no more memory, return */
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 * Search the list to find where to put our new entry
2571 * (and in the process decide what channel number it is
2572 * going to be)
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 * Open the high-level part of the STRIP channel.
2593 * This function is called by the TTY module when the
2594 * STRIP line discipline is called for. Because we are
2595 * sure the tty line exists, we only have to link it to
2596 * a free STRIP channel...
2597 */
2598
2599static int strip_open(struct tty_struct *tty)
2600{
2601 struct strip *strip_info = (struct strip *) tty->disc_data;
2602
2603 /*
2604 * First make sure we're not already connected.
2605 */
2606
2607 if (strip_info && strip_info->magic == STRIP_MAGIC)
2608 return -EEXIST;
2609
2610 /*
2611 * We need a write method.
2612 */
2613
2614 if (tty->ops->write == NULL || tty->ops->set_termios == NULL)
2615 return -EOPNOTSUPP;
2616
2617 /*
2618 * OK. Find a free STRIP channel to use.
2619 */
2620 if ((strip_info = strip_alloc()) == NULL)
2621 return -ENFILE;
2622
2623 /*
2624 * Register our newly created device so it can be ifconfig'd
2625 * strip_dev_init() will be called as a side-effect
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 * Restore default settings
2642 */
2643
2644 strip_info->dev->type = ARPHRD_METRICOM; /* dtang */
2645
2646 /*
2647 * Set tty options
2648 */
2649
2650 tty->termios->c_iflag |= IGNBRK | IGNPAR; /* Ignore breaks and parity errors. */
2651 tty->termios->c_cflag |= CLOCAL; /* Ignore modem control signals. */
2652 tty->termios->c_cflag &= ~HUPCL; /* Don't close on hup */
2653
2654 printk(KERN_INFO "STRIP: device \"%s\" activated\n",
2655 strip_info->dev->name);
2656
2657 /*
2658 * Done. We have linked the TTY line to a channel.
2659 */
2660 return (strip_info->dev->base_addr);
2661}
2662
2663/*
2664 * Close down a STRIP channel.
2665 * This means flushing out any pending queues, and then restoring the
2666 * TTY line discipline to what it was before it got hooked to STRIP
2667 * (which usually is TTY again).
2668 */
2669
2670static void strip_close(struct tty_struct *tty)
2671{
2672 struct strip *strip_info = (struct strip *) tty->disc_data;
2673
2674 /*
2675 * First make sure we're connected.
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/* Perform I/O control calls on an active STRIP channel. */
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 * First make sure we're connected.
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 //printk(KERN_INFO "%s: SIOCSIFHWADDR\n", strip_info->dev->name);
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/* Initialization */
2730
2731static struct tty_ldisc 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 * Initialize the STRIP driver.
2744 * This routine is called at boot time, to bootstrap the multi-channel
2745 * STRIP driver
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 * Fill in our line protocol discipline, and register it
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 * Register the status file with /proc
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 /* module ref count rules assure that all entries are unregistered */
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 /* Unregister with the /proc/net file here. */
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");