/*
 * Copyright 1996 The Board of Trustees of The Leland Stanford
 * Junior University. All Rights Reserved.
 *
 * Permission to use, copy, modify, and distribute this
 * software and its documentation for any purpose and without
 * fee is hereby granted, provided that the above copyright
 * notice appear in all copies.  Stanford University
 * makes no representations about the suitability of this
 * software for any purpose.  It is provided "as is" without
 * express or implied warranty.
 *
 * strip.c	This module implements Starmode Radio IP (STRIP)
 *		for kernel-based devices like TTY.  It interfaces between a
 *		raw TTY, and the kernel's INET protocol layers (via DDI).
 *
 * Version:	@(#)strip.c	1.3	July 1997
 *
 * Author:	Stuart Cheshire <cheshire@cs.stanford.edu>
 *
 * Fixes:	v0.9 12th Feb 1996 (SC)
 *		New byte stuffing (2+6 run-length encoding)
 *		New watchdog timer task
 *		New Protocol key (SIP0)
 *		
 *		v0.9.1 3rd March 1996 (SC)
 *		Changed to dynamic device allocation -- no more compile
 *		time (or boot time) limit on the number of STRIP devices.
 *		
 *		v0.9.2 13th March 1996 (SC)
 *		Uses arp cache lookups (but doesn't send arp packets yet)
 *		
 *		v0.9.3 17th April 1996 (SC)
 *		Fixed bug where STR_ERROR flag was getting set unneccessarily
 *		(causing otherwise good packets to be unneccessarily dropped)
 *		
 *		v0.9.4 27th April 1996 (SC)
 *		First attempt at using "&COMMAND" Starmode AT commands
 *		
 *		v0.9.5 29th May 1996 (SC)
 *		First attempt at sending (unicast) ARP packets
 *		
 *		v0.9.6 5th June 1996 (Elliot)
 *		Put "message level" tags in every "printk" statement
 *		
 *		v0.9.7 13th June 1996 (laik)
 *		Added support for the /proc fs
 *
 *              v0.9.8 July 1996 (Mema)
 *              Added packet logging
 *
 *              v1.0 November 1996 (SC)
 *              Fixed (severe) memory leaks in the /proc fs code
 *              Fixed race conditions in the logging code
 *
 *              v1.1 January 1997 (SC)
 *              Deleted packet logging (use tcpdump instead)
 *              Added support for Metricom Firmware v204 features
 *              (like message checksums)
 *
 *              v1.2 January 1997 (SC)
 *              Put portables list back in
 *
 *              v1.3 July 1997 (SC)
 *              Made STRIP driver set the radio's baud rate automatically.
 *              It is no longer necessarily to manually set the radio's
 *              rate permanently to 115200 -- the driver handles setting
 *              the rate automatically.
 */

#ifdef MODULE
static const char StripVersion[] = "1.3A-STUART.CHESHIRE-MODULAR";
#else
static const char StripVersion[] = "1.3A-STUART.CHESHIRE";
#endif

#define TICKLE_TIMERS 0
#define EXT_COUNTERS 1


/************************************************************************/
/* Header files								*/

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/bitops.h>
#include <asm/system.h>
#include <asm/uaccess.h>

# include <linux/ctype.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/interrupt.h>
#include <linux/in.h>
#include <linux/tty.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
#include <linux/inetdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <linux/if_arp.h>
#include <linux/if_strip.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/serial.h>
#include <linux/serialP.h>
#include <linux/rcupdate.h>
#include <net/arp.h>

#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/time.h>
#include <linux/jiffies.h>

/************************************************************************/
/* Useful structures and definitions					*/

/*
 * A MetricomKey identifies the protocol being carried inside a Metricom
 * Starmode packet.
 */

typedef union {
	__u8 c[4];
	__u32 l;
} MetricomKey;

/*
 * An IP address can be viewed as four bytes in memory (which is what it is) or as
 * a single 32-bit long (which is convenient for assignment, equality testing etc.)
 */

typedef union {
	__u8 b[4];
	__u32 l;
} IPaddr;

/*
 * A MetricomAddressString is used to hold a printable representation of
 * a Metricom address.
 */

typedef struct {
	__u8 c[24];
} MetricomAddressString;

/* Encapsulation can expand packet of size x to 65/64x + 1
 * Sent packet looks like "<CR>*<address>*<key><encaps payload><CR>"
 *                           1 1   1-18  1  4         ?         1
 * eg.                     <CR>*0000-1234*SIP0<encaps payload><CR>
 * We allow 31 bytes for the stars, the key, the address and the <CR>s
 */
#define STRIP_ENCAP_SIZE(X) (32 + (X)*65L/64L)

/*
 * A STRIP_Header is never really sent over the radio, but making a dummy
 * header for internal use within the kernel that looks like an Ethernet
 * header makes certain other software happier. For example, tcpdump
 * already understands Ethernet headers.
 */

typedef struct {
	MetricomAddress dst_addr;	/* Destination address, e.g. "0000-1234"   */
	MetricomAddress src_addr;	/* Source address, e.g. "0000-5678"        */
	unsigned short protocol;	/* The protocol type, using Ethernet codes */
} STRIP_Header;

typedef struct {
	char c[60];
} MetricomNode;

#define NODE_TABLE_SIZE 32
typedef struct {
	struct timeval timestamp;
	int num_nodes;
	MetricomNode node[NODE_TABLE_SIZE];
} MetricomNodeTable;

enum { FALSE = 0, TRUE = 1 };

/*
 * Holds the radio's firmware version.
 */
typedef struct {
	char c[50];
} FirmwareVersion;

/*
 * Holds the radio's serial number.
 */
typedef struct {
	char c[18];
} SerialNumber;

/*
 * Holds the radio's battery voltage.
 */
typedef struct {
	char c[11];
} BatteryVoltage;

typedef struct {
	char c[8];
} char8;

enum {
	NoStructure = 0,	/* Really old firmware */
	StructuredMessages = 1,	/* Parsable AT response msgs */
	ChecksummedMessages = 2	/* Parsable AT response msgs with checksums */
};

struct strip {
	int magic;
	/*
	 * These are pointers to the malloc()ed frame buffers.
	 */

	unsigned char *rx_buff;	/* buffer for received IP packet */
	unsigned char *sx_buff;	/* buffer for received serial data */
	int sx_count;		/* received serial data counter */
	int sx_size;		/* Serial buffer size           */
	unsigned char *tx_buff;	/* transmitter buffer           */
	unsigned char *tx_head;	/* pointer to next byte to XMIT */
	int tx_left;		/* bytes left in XMIT queue     */
	int tx_size;		/* Serial buffer size           */

	/*
	 * STRIP interface statistics.
	 */

	unsigned long rx_packets;	/* inbound frames counter       */
	unsigned long tx_packets;	/* outbound frames counter      */
	unsigned long rx_errors;	/* Parity, etc. errors          */
	unsigned long tx_errors;	/* Planned stuff                */
	unsigned long rx_dropped;	/* No memory for skb            */
	unsigned long tx_dropped;	/* When MTU change              */
	unsigned long rx_over_errors;	/* Frame bigger then STRIP buf. */

	unsigned long pps_timer;	/* Timer to determine pps       */
	unsigned long rx_pps_count;	/* Counter to determine pps     */
	unsigned long tx_pps_count;	/* Counter to determine pps     */
	unsigned long sx_pps_count;	/* Counter to determine pps     */
	unsigned long rx_average_pps;	/* rx packets per second * 8    */
	unsigned long tx_average_pps;	/* tx packets per second * 8    */
	unsigned long sx_average_pps;	/* sent packets per second * 8  */

#ifdef EXT_COUNTERS
	unsigned long rx_bytes;		/* total received bytes */
	unsigned long tx_bytes;		/* total received bytes */
	unsigned long rx_rbytes;	/* bytes thru radio i/f */
	unsigned long tx_rbytes;	/* bytes thru radio i/f */
	unsigned long rx_sbytes;	/* tot bytes thru serial i/f */
	unsigned long tx_sbytes;	/* tot bytes thru serial i/f */
	unsigned long rx_ebytes;	/* tot stat/err bytes */
	unsigned long tx_ebytes;	/* tot stat/err bytes */
#endif

	/*
	 * Internal variables.
	 */

	struct list_head  list;		/* Linked list of devices */

	int discard;			/* Set if serial error          */
	int working;			/* Is radio working correctly?  */
	int firmware_level;		/* Message structuring level    */
	int next_command;		/* Next periodic command        */
	unsigned int user_baud;		/* The user-selected baud rate  */
	int mtu;			/* Our mtu (to spot changes!)   */
	long watchdog_doprobe;		/* Next time to test the radio  */
	long watchdog_doreset;		/* Time to do next reset        */
	long gratuitous_arp;		/* Time to send next ARP refresh */
	long arp_interval;		/* Next ARP interval            */
	struct timer_list idle_timer;	/* For periodic wakeup calls    */
	MetricomAddress true_dev_addr;	/* True address of radio        */
	int manual_dev_addr;		/* Hack: See note below         */

	FirmwareVersion firmware_version;	/* The radio's firmware version */
	SerialNumber serial_number;	/* The radio's serial number    */
	BatteryVoltage battery_voltage;	/* The radio's battery voltage  */

	/*
	 * Other useful structures.
	 */

	struct tty_struct *tty;		/* ptr to TTY structure         */
	struct net_device *dev;		/* Our device structure         */

	/*
	 * Neighbour radio records
	 */

	MetricomNodeTable portables;
	MetricomNodeTable poletops;
};

/*
 * Note: manual_dev_addr hack
 * 
 * It is not possible to change the hardware address of a Metricom radio,
 * or to send packets with a user-specified hardware source address, thus
 * trying to manually set a hardware source address is a questionable
 * thing to do.  However, if the user *does* manually set the hardware
 * source address of a STRIP interface, then the kernel will believe it,
 * and use it in certain places. For example, the hardware address listed
 * by ifconfig will be the manual address, not the true one.
 * (Both addresses are listed in /proc/net/strip.)
 * Also, ARP packets will be sent out giving the user-specified address as
 * the source address, not the real address. This is dangerous, because
 * it means you won't receive any replies -- the ARP replies will go to
 * the specified address, which will be some other radio. The case where
 * this is useful is when that other radio is also connected to the same
 * machine. This allows you to connect a pair of radios to one machine,
 * and to use one exclusively for inbound traffic, and the other
 * exclusively for outbound traffic. Pretty neat, huh?
 * 
 * Here's the full procedure to set this up:
 * 
 * 1. "slattach" two interfaces, e.g. st0 for outgoing packets,
 *    and st1 for incoming packets
 * 
 * 2. "ifconfig" st0 (outbound radio) to have the hardware address
 *    which is the real hardware address of st1 (inbound radio).
 *    Now when it sends out packets, it will masquerade as st1, and
 *    replies will be sent to that radio, which is exactly what we want.
 * 
 * 3. Set the route table entry ("route add default ..." or
 *    "route add -net ...", as appropriate) to send packets via the st0
 *    interface (outbound radio). Do not add any route which sends packets
 *    out via the st1 interface -- that radio is for inbound traffic only.
 * 
 * 4. "ifconfig" st1 (inbound radio) to have hardware address zero.
 *    This tells the STRIP driver to "shut down" that interface and not
 *    send any packets through it. In particular, it stops sending the
 *    periodic gratuitous ARP packets that a STRIP interface normally sends.
 *    Also, when packets arrive on that interface, it will search the
 *    interface list to see if there is another interface who's manual
 *    hardware address matches its own real address (i.e. st0 in this
 *    example) and if so it will transfer ownership of the skbuff to
 *    that interface, so that it looks to the kernel as if the packet
 *    arrived on that interface. This is necessary because when the
 *    kernel sends an ARP packet on st0, it expects to get a reply on
 *    st0, and if it sees the reply come from st1 then it will ignore
 *    it (to be accurate, it puts the entry in the ARP table, but
 *    labelled in such a way that st0 can't use it).
 * 
 * Thanks to Petros Maniatis for coming up with the idea of splitting
 * inbound and outbound traffic between two interfaces, which turned
 * out to be really easy to implement, even if it is a bit of a hack.
 * 
 * Having set a manual address on an interface, you can restore it
 * to automatic operation (where the address is automatically kept
 * consistent with the real address of the radio) by setting a manual
 * address of all ones, e.g. "ifconfig st0 hw strip FFFFFFFFFFFF"
 * This 'turns off' manual override mode for the device address.
 * 
 * Note: The IEEE 802 headers reported in tcpdump will show the *real*
 * radio addresses the packets were sent and received from, so that you
 * can see what is really going on with packets, and which interfaces
 * they are really going through.
 */


/************************************************************************/
/* Constants								*/

/*
 * CommandString1 works on all radios
 * Other CommandStrings are only used with firmware that provides structured responses.
 * 
 * ats319=1 Enables Info message for node additions and deletions
 * ats319=2 Enables Info message for a new best node
 * ats319=4 Enables checksums
 * ats319=8 Enables ACK messages
 */

static const int MaxCommandStringLength = 32;
static const int CompatibilityCommand = 1;

static const char CommandString0[] = "*&COMMAND*ATS319=7";	/* Turn on checksums & info messages */
static const char CommandString1[] = "*&COMMAND*ATS305?";	/* Query radio name */
static const char CommandString2[] = "*&COMMAND*ATS325?";	/* Query battery voltage */
static const char CommandString3[] = "*&COMMAND*ATS300?";	/* Query version information */
static const char CommandString4[] = "*&COMMAND*ATS311?";	/* Query poletop list */
static const char CommandString5[] = "*&COMMAND*AT~LA";		/* Query portables list */
typedef struct {
	const char *string;
	long length;
} StringDescriptor;

static const StringDescriptor CommandString[] = {
	{CommandString0, sizeof(CommandString0) - 1},
	{CommandString1, sizeof(CommandString1) - 1},
	{CommandString2, sizeof(CommandString2) - 1},
	{CommandString3, sizeof(CommandString3) - 1},
	{CommandString4, sizeof(CommandString4) - 1},
	{CommandString5, sizeof(CommandString5) - 1}
};

#define GOT_ALL_RADIO_INFO(S)      \
    ((S)->firmware_version.c[0] && \
     (S)->battery_voltage.c[0]  && \
     memcmp(&(S)->true_dev_addr, zero_address.c, sizeof(zero_address)))

static const char hextable[16] = "0123456789ABCDEF";

static const MetricomAddress zero_address;
static const MetricomAddress broadcast_address =
    { {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} };

static const MetricomKey SIP0Key = { "SIP0" };
static const MetricomKey ARP0Key = { "ARP0" };
static const MetricomKey ATR_Key = { "ATR " };
static const MetricomKey ACK_Key = { "ACK_" };
static const MetricomKey INF_Key = { "INF_" };
static const MetricomKey ERR_Key = { "ERR_" };

static const long MaxARPInterval = 60 * HZ;	/* One minute */

/*
 * Maximum Starmode packet length is 1183 bytes. Allowing 4 bytes for
 * protocol key, 4 bytes for checksum, one byte for CR, and 65/64 expansion
 * for STRIP encoding, that translates to a maximum payload MTU of 1155.
 * Note: A standard NFS 1K data packet is a total of 0x480 (1152) bytes
 * long, including IP header, UDP header, and NFS header. Setting the STRIP
 * MTU to 1152 allows us to send default sized NFS packets without fragmentation.
 */
static const unsigned short MAX_SEND_MTU = 1152;
static const unsigned short MAX_RECV_MTU = 1500;	/* Hoping for Ethernet sized packets in the future! */
static const unsigned short DEFAULT_STRIP_MTU = 1152;
static const int STRIP_MAGIC = 0x5303;
static const long LongTime = 0x7FFFFFFF;

/************************************************************************/
/* Global variables							*/

static LIST_HEAD(strip_list);
static DEFINE_SPINLOCK(strip_lock);

/************************************************************************/
/* Macros								*/

/* Returns TRUE if text T begins with prefix P */
#define has_prefix(T,L,P) (((L) >= sizeof(P)-1) && !strncmp((T), (P), sizeof(P)-1))

/* Returns TRUE if text T of length L is equal to string S */
#define text_equal(T,L,S) (((L) == sizeof(S)-1) && !strncmp((T), (S), sizeof(S)-1))

#define READHEX(X) ((X)>='0' && (X)<='9' ? (X)-'0' :      \
                    (X)>='a' && (X)<='f' ? (X)-'a'+10 :   \
                    (X)>='A' && (X)<='F' ? (X)-'A'+10 : 0 )

#define READHEX16(X) ((__u16)(READHEX(X)))

#define READDEC(X) ((X)>='0' && (X)<='9' ? (X)-'0' : 0)

#define ARRAY_END(X) (&((X)[ARRAY_SIZE(X)]))

#define JIFFIE_TO_SEC(X) ((X) / HZ)


/************************************************************************/
/* Utility routines							*/

static int arp_query(unsigned char *haddr, u32 paddr,
		     struct net_device *dev)
{
	struct neighbour *neighbor_entry;
	int ret = 0;

	neighbor_entry = neigh_lookup(&arp_tbl, &paddr, dev);

	if (neighbor_entry != NULL) {
		neighbor_entry->used = jiffies;
		if (neighbor_entry->nud_state & NUD_VALID) {
			memcpy(haddr, neighbor_entry->ha, dev->addr_len);
			ret = 1;
		}
		neigh_release(neighbor_entry);
	}
	return ret;
}

static void DumpData(char *msg, struct strip *strip_info, __u8 * ptr,
		     __u8 * end)
{
	static const int MAX_DumpData = 80;
	__u8 pkt_text[MAX_DumpData], *p = pkt_text;

	*p++ = '\"';

	while (ptr < end && p < &pkt_text[MAX_DumpData - 4]) {
		if (*ptr == '\\') {
			*p++ = '\\';
			*p++ = '\\';
		} else {
			if (*ptr >= 32 && *ptr <= 126) {
				*p++ = *ptr;
			} else {
				sprintf(p, "\\%02X", *ptr);
				p += 3;
			}
		}
		ptr++;
	}

	if (ptr == end)
		*p++ = '\"';
	*p++ = 0;

	printk(KERN_INFO "%s: %-13s%s\n", strip_info->dev->name, msg, pkt_text);
}


/************************************************************************/
/* Byte stuffing/unstuffing routines					*/

/* Stuffing scheme:
 * 00    Unused (reserved character)
 * 01-3F Run of 2-64 different characters
 * 40-7F Run of 1-64 different characters plus a single zero at the end
 * 80-BF Run of 1-64 of the same character
 * C0-FF Run of 1-64 zeroes (ASCII 0)
 */

typedef enum {
	Stuff_Diff = 0x00,
	Stuff_DiffZero = 0x40,
	Stuff_Same = 0x80,
	Stuff_Zero = 0xC0,
	Stuff_NoCode = 0xFF,	/* Special code, meaning no code selected */

	Stuff_CodeMask = 0xC0,
	Stuff_CountMask = 0x3F,
	Stuff_MaxCount = 0x3F,
	Stuff_Magic = 0x0D	/* The value we are eliminating */
} StuffingCode;

/* StuffData encodes the data starting at "src" for "length" bytes.
 * It writes it to the buffer pointed to by "dst" (which must be at least
 * as long as 1 + 65/64 of the input length). The output may be up to 1.6%
 * larger than the input for pathological input, but will usually be smaller.
 * StuffData returns the new value of the dst pointer as its result.
 * "code_ptr_ptr" points to a "__u8 *" which is used to hold encoding state
 * between calls, allowing an encoded packet to be incrementally built up
 * from small parts. On the first call, the "__u8 *" pointed to should be
 * initialized to NULL; between subsequent calls the calling routine should
 * leave the value alone and simply pass it back unchanged so that the
 * encoder can recover its current state.
 */

#define StuffData_FinishBlock(X) \
(*code_ptr = (X) ^ Stuff_Magic, code = Stuff_NoCode)

static __u8 *StuffData(__u8 * src, __u32 length, __u8 * dst,
		       __u8 ** code_ptr_ptr)
{
	__u8 *end = src + length;
	__u8 *code_ptr = *code_ptr_ptr;
	__u8 code = Stuff_NoCode, count = 0;

	if (!length)
		return (dst);

	if (code_ptr) {
		/*
		 * Recover state from last call, if applicable
		 */
		code = (*code_ptr ^ Stuff_Magic) & Stuff_CodeMask;
		count = (*code_ptr ^ Stuff_Magic) & Stuff_CountMask;
	}

	while (src < end) {
		switch (code) {
			/* Stuff_NoCode: If no current code, select one */
		case Stuff_NoCode:
			/* Record where we're going to put this code */
			code_ptr = dst++;
			count = 0;	/* Reset the count (zero means one instance) */
			/* Tentatively start a new block */
			if (*src == 0) {
				code = Stuff_Zero;
				src++;
			} else {
				code = Stuff_Same;
				*dst++ = *src++ ^ Stuff_Magic;
			}
			/* Note: We optimistically assume run of same -- */
			/* which will be fixed later in Stuff_Same */
			/* if it turns out not to be true. */
			break;

			/* Stuff_Zero: We already have at least one zero encoded */
		case Stuff_Zero:
			/* If another zero, count it, else finish this code block */
			if (*src == 0) {
				count++;
				src++;
			} else {
				StuffData_FinishBlock(Stuff_Zero + count);
			}
			break;

			/* Stuff_Same: We already have at least one byte encoded */
		case Stuff_Same:
			/* If another one the same, count it */
			if ((*src ^ Stuff_Magic) == code_ptr[1]) {
				count++;
				src++;
				break;
			}
			/* else, this byte does not match this block. */
			/* If we already have two or more bytes encoded, finish this code block */
			if (count) {
				StuffData_FinishBlock(Stuff_Same + count);
				break;
			}
			/* else, we only have one so far, so switch to Stuff_Diff code */
			code = Stuff_Diff;
			/* and fall through to Stuff_Diff case below
			 * Note cunning cleverness here: case Stuff_Diff compares 
			 * the current character with the previous two to see if it
			 * has a run of three the same. Won't this be an error if
			 * there aren't two previous characters stored to compare with?
			 * No. Because we know the current character is *not* the same
			 * as the previous one, the first test below will necessarily
			 * fail and the send half of the "if" won't be executed.
			 */

			/* Stuff_Diff: We have at least two *different* bytes encoded */
		case Stuff_Diff:
			/* If this is a zero, must encode a Stuff_DiffZero, and begin a new block */
			if (*src == 0) {
				StuffData_FinishBlock(Stuff_DiffZero +
						      count);
			}
			/* else, if we have three in a row, it is worth starting a Stuff_Same block */
			else if ((*src ^ Stuff_Magic) == dst[-1]
				 && dst[-1] == dst[-2]) {
				/* Back off the last two characters we encoded */
				code += count - 2;
				/* Note: "Stuff_Diff + 0" is an illegal code */
				if (code == Stuff_Diff + 0) {
					code = Stuff_Same + 0;
				}
				StuffData_FinishBlock(code);
				code_ptr = dst - 2;
				/* dst[-1] already holds the correct value */
				count = 2;	/* 2 means three bytes encoded */
				code = Stuff_Same;
			}
			/* else, another different byte, so add it to the block */
			else {
				*dst++ = *src ^ Stuff_Magic;
				count++;
			}
			src++;	/* Consume the byte */
			break;
		}
		if (count == Stuff_MaxCount) {
			StuffData_FinishBlock(code + count);
		}
	}
	if (code == Stuff_NoCode) {
		*code_ptr_ptr = NULL;
	} else {
		*code_ptr_ptr = code_ptr;
		StuffData_FinishBlock(code + count);
	}
	return (dst);
}

/*
 * UnStuffData decodes the data at "src", up to (but not including) "end".
 * It writes the decoded data into the buffer pointed to by "dst", up to a
 * maximum of "dst_length", and returns the new value of "src" so that a
 * follow-on call can read more data, continuing from where the first left off.
 * 
 * There are three types of results:
 * 1. The source data runs out before extracting "dst_length" bytes:
 *    UnStuffData returns NULL to indicate failure.
 * 2. The source data produces exactly "dst_length" bytes:
 *    UnStuffData returns new_src = end to indicate that all bytes were consumed.
 * 3. "dst_length" bytes are extracted, with more remaining.
 *    UnStuffData returns new_src < end to indicate that there are more bytes
 *    to be read.
 * 
 * Note: The decoding may be destructive, in that it may alter the source
 * data in the process of decoding it (this is necessary to allow a follow-on
 * call to resume correctly).
 */

static __u8 *UnStuffData(__u8 * src, __u8 * end, __u8 * dst,
			 __u32 dst_length)
{
	__u8 *dst_end = dst + dst_length;
	/* Sanity check */
	if (!src || !end || !dst || !dst_length)
		return (NULL);
	while (src < end && dst < dst_end) {
		int count = (*src ^ Stuff_Magic) & Stuff_CountMask;
		switch ((*src ^ Stuff_Magic) & Stuff_CodeMask) {
		case Stuff_Diff:
			if (src + 1 + count >= end)
				return (NULL);
			do {
				*dst++ = *++src ^ Stuff_Magic;
			}
			while (--count >= 0 && dst < dst_end);
			if (count < 0)
				src += 1;
			else {
				if (count == 0)
					*src = Stuff_Same ^ Stuff_Magic;
				else
					*src =
					    (Stuff_Diff +
					     count) ^ Stuff_Magic;
			}
			break;
		case Stuff_DiffZero:
			if (src + 1 + count >= end)
				return (NULL);
			do {
				*dst++ = *++src ^ Stuff_Magic;
			}
			while (--count >= 0 && dst < dst_end);
			if (count < 0)
				*src = Stuff_Zero ^ Stuff_Magic;
			else
				*src =
				    (Stuff_DiffZero + count) ^ Stuff_Magic;
			break;
		case Stuff_Same:
			if (src + 1 >= end)
				return (NULL);
			do {
				*dst++ = src[1] ^ Stuff_Magic;
			}
			while (--count >= 0 && dst < dst_end);
			if (count < 0)
				src += 2;
			else
				*src = (Stuff_Same + count) ^ Stuff_Magic;
			break;
		case Stuff_Zero:
			do {
				*dst++ = 0;
			}
			while (--count >= 0 && dst < dst_end);
			if (count < 0)
				src += 1;
			else
				*src = (Stuff_Zero + count) ^ Stuff_Magic;
			break;
		}
	}
	if (dst < dst_end)
		return (NULL);
	else
		return (src);
}


/************************************************************************/
/* General routines for STRIP						*/

/*
 * get_baud returns the current baud rate, as one of the constants defined in
 * termbits.h
 * If the user has issued a baud rate override using the 'setserial' command
 * and the logical current rate is set to 38.4, then the true baud rate
 * currently in effect (57.6 or 115.2) is returned.
 */
static unsigned int get_baud(struct tty_struct *tty)
{
	if (!tty || !tty->termios)
		return (0);
	if ((tty->termios->c_cflag & CBAUD) == B38400 && tty->driver_data) {
		struct async_struct *info =
		    (struct async_struct *) tty->driver_data;
		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
			return (B57600);
		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
			return (B115200);
	}
	return (tty->termios->c_cflag & CBAUD);
}

/*
 * set_baud sets the baud rate to the rate defined by baudcode
 * Note: The rate B38400 should be avoided, because the user may have
 * issued a 'setserial' speed override to map that to a different speed.
 * We could achieve a true rate of 38400 if we needed to by cancelling
 * any user speed override that is in place, but that might annoy the
 * user, so it is simplest to just avoid using 38400.
 */
static void set_baud(struct tty_struct *tty, unsigned int baudcode)
{
	struct ktermios old_termios = *(tty->termios);
	tty->termios->c_cflag &= ~CBAUD;	/* Clear the old baud setting */
	tty->termios->c_cflag |= baudcode;	/* Set the new baud setting */
	tty->driver->set_termios(tty, &old_termios);
}

/*
 * Convert a string to a Metricom Address.
 */

#define IS_RADIO_ADDRESS(p) (                                                 \
  isdigit((p)[0]) && isdigit((p)[1]) && isdigit((p)[2]) && isdigit((p)[3]) && \
  (p)[4] == '-' &&                                                            \
  isdigit((p)[5]) && isdigit((p)[6]) && isdigit((p)[7]) && isdigit((p)[8])    )

static int string_to_radio_address(MetricomAddress * addr, __u8 * p)
{
	if (!IS_RADIO_ADDRESS(p))
		return (1);
	addr->c[0] = 0;
	addr->c[1] = 0;
	addr->c[2] = READHEX(p[0]) << 4 | READHEX(p[1]);
	addr->c[3] = READHEX(p[2]) << 4 | READHEX(p[3]);
	addr->c[4] = READHEX(p[5]) << 4 | READHEX(p[6]);
	addr->c[5] = READHEX(p[7]) << 4 | READHEX(p[8]);
	return (0);
}

/*
 * Convert a Metricom Address to a string.
 */

static __u8 *radio_address_to_string(const MetricomAddress * addr,
				     MetricomAddressString * p)
{
	sprintf(p->c, "%02X%02X-%02X%02X", addr->c[2], addr->c[3],
		addr->c[4], addr->c[5]);
	return (p->c);
}

/*
 * Note: Must make sure sx_size is big enough to receive a stuffed
 * MAX_RECV_MTU packet. Additionally, we also want to ensure that it's
 * big enough to receive a large radio neighbour list (currently 4K).
 */

static int allocate_buffers(struct strip *strip_info, int mtu)
{
	struct net_device *dev = strip_info->dev;
	int sx_size = max_t(int, STRIP_ENCAP_SIZE(MAX_RECV_MTU), 4096);
	int tx_size = STRIP_ENCAP_SIZE(mtu) + MaxCommandStringLength;
	__u8 *r = kmalloc(MAX_RECV_MTU, GFP_ATOMIC);
	__u8 *s = kmalloc(sx_size, GFP_ATOMIC);
	__u8 *t = kmalloc(tx_size, GFP_ATOMIC);
	if (r && s && t) {
		strip_info->rx_buff = r;
		strip_info->sx_buff = s;
		strip_info->tx_buff = t;
		strip_info->sx_size = sx_size;
		strip_info->tx_size = tx_size;
		strip_info->mtu = dev->mtu = mtu;
		return (1);
	}
	kfree(r);
	kfree(s);
	kfree(t);
	return (0);
}

/*
 * MTU has been changed by the IP layer. 
 * We could be in
 * an upcall from the tty driver, or in an ip packet queue.
 */
static int strip_change_mtu(struct net_device *dev, int new_mtu)
{
	struct strip *strip_info = netdev_priv(dev);
	int old_mtu = strip_info->mtu;
	unsigned char *orbuff = strip_info->rx_buff;
	unsigned char *osbuff = strip_info->sx_buff;
	unsigned char *otbuff = strip_info->tx_buff;

	if (new_mtu > MAX_SEND_MTU) {
		printk(KERN_ERR
		       "%s: MTU exceeds maximum allowable (%d), MTU change cancelled.\n",
		       strip_info->dev->name, MAX_SEND_MTU);
		return -EINVAL;
	}

	spin_lock_bh(&strip_lock);
	if (!allocate_buffers(strip_info, new_mtu)) {
		printk(KERN_ERR "%s: unable to grow strip buffers, MTU change cancelled.\n",
		       strip_info->dev->name);
		spin_unlock_bh(&strip_lock);
		return -ENOMEM;
	}

	if (strip_info->sx_count) {
		if (strip_info->sx_count <= strip_info->sx_size)
			memcpy(strip_info->sx_buff, osbuff,
			       strip_info->sx_count);
		else {
			strip_info->discard = strip_info->sx_count;
			strip_info->rx_over_errors++;
		}
	}

	if (strip_info->tx_left) {
		if (strip_info->tx_left <= strip_info->tx_size)
			memcpy(strip_info->tx_buff, strip_info->tx_head,
			       strip_info->tx_left);
		else {
			strip_info->tx_left = 0;
			strip_info->tx_dropped++;
		}
	}
	strip_info->tx_head = strip_info->tx_buff;
	spin_unlock_bh(&strip_lock);

	printk(KERN_NOTICE "%s: strip MTU changed fom %d to %d.\n",
	       strip_info->dev->name, old_mtu, strip_info->mtu);

	kfree(orbuff);
	kfree(osbuff);
	kfree(otbuff);
	return 0;
}

static void strip_unlock(struct strip *strip_info)
{
	/*
	 * Set the timer to go off in one second.
	 */
	strip_info->idle_timer.expires = jiffies + 1 * HZ;
	add_timer(&strip_info->idle_timer);
	netif_wake_queue(strip_info->dev);
}



/*
 * If the time is in the near future, time_delta prints the number of
 * seconds to go into the buffer and returns the address of the buffer.
 * If the time is not in the near future, it returns the address of the
 * string "Not scheduled" The buffer must be long enough to contain the
 * ascii representation of the number plus 9 charactes for the " seconds"
 * and the null character.
 */
#ifdef CONFIG_PROC_FS
static char *time_delta(char buffer[], long time)
{
	time -= jiffies;
	if (time > LongTime / 2)
		return ("Not scheduled");
	if (time < 0)
		time = 0;	/* Don't print negative times */
	sprintf(buffer, "%ld seconds", time / HZ);
	return (buffer);
}

/* get Nth element of the linked list */
static struct strip *strip_get_idx(loff_t pos) 
{
	struct list_head *l;
	int i = 0;

	list_for_each_rcu(l, &strip_list) {
		if (pos == i)
			return list_entry(l, struct strip, list);
		++i;
	}
	return NULL;
}

static void *strip_seq_start(struct seq_file *seq, loff_t *pos)
{
	rcu_read_lock();
	return *pos ? strip_get_idx(*pos - 1) : SEQ_START_TOKEN;
}

static void *strip_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
	struct list_head *l;
	struct strip *s;

	++*pos;
	if (v == SEQ_START_TOKEN)
		return strip_get_idx(1);

	s = v;
	l = &s->list;
	list_for_each_continue_rcu(l, &strip_list) {
		return list_entry(l, struct strip, list);
	}
	return NULL;
}

static void strip_seq_stop(struct seq_file *seq, void *v)
{
	rcu_read_unlock();
}

static void strip_seq_neighbours(struct seq_file *seq,
			   const MetricomNodeTable * table,
			   const char *title)
{
	/* We wrap this in a do/while loop, so if the table changes */
	/* while we're reading it, we just go around and try again. */
	struct timeval t;

	do {
		int i;
		t = table->timestamp;
		if (table->num_nodes)
			seq_printf(seq, "\n %s\n", title);
		for (i = 0; i < table->num_nodes; i++) {
			MetricomNode node;

			spin_lock_bh(&strip_lock);
			node = table->node[i];
			spin_unlock_bh(&strip_lock);
			seq_printf(seq, "  %s\n", node.c);
		}
	} while (table->timestamp.tv_sec != t.tv_sec
		 || table->timestamp.tv_usec != t.tv_usec);
}

/*
 * This function prints radio status information via the seq_file
 * interface.  The interface takes care of buffer size and over
 * run issues. 
 *
 * The buffer in seq_file is PAGESIZE (4K) 
 * so this routine should never print more or it will get truncated.
 * With the maximum of 32 portables and 32 poletops
 * reported, the routine outputs 3107 bytes into the buffer.
 */
static void strip_seq_status_info(struct seq_file *seq, 
				  const struct strip *strip_info)
{
	char temp[32];
	MetricomAddressString addr_string;

	/* First, we must copy all of our data to a safe place, */
	/* in case a serial interrupt comes in and changes it.  */
	int tx_left = strip_info->tx_left;
	unsigned long rx_average_pps = strip_info->rx_average_pps;
	unsigned long tx_average_pps = strip_info->tx_average_pps;
	unsigned long sx_average_pps = strip_info->sx_average_pps;
	int working = strip_info->working;
	int firmware_level = strip_info->firmware_level;
	long watchdog_doprobe = strip_info->watchdog_doprobe;
	long watchdog_doreset = strip_info->watchdog_doreset;
	long gratuitous_arp = strip_info->gratuitous_arp;
	long arp_interval = strip_info->arp_interval;
	FirmwareVersion firmware_version = strip_info->firmware_version;
	SerialNumber serial_number = strip_info->serial_number;
	BatteryVoltage battery_voltage = strip_info->battery_voltage;
	char *if_name = strip_info->dev->name;
	MetricomAddress true_dev_addr = strip_info->true_dev_addr;
	MetricomAddress dev_dev_addr =
	    *(MetricomAddress *) strip_info->dev->dev_addr;
	int manual_dev_addr = strip_info->manual_dev_addr;
#ifdef EXT_COUNTERS
	unsigned long rx_bytes = strip_info->rx_bytes;
	unsigned long tx_bytes = strip_info->tx_bytes;
	unsigned long rx_rbytes = strip_info->rx_rbytes;
	unsigned long tx_rbytes = strip_info->tx_rbytes;
	unsigned long rx_sbytes = strip_info->rx_sbytes;
	unsigned long tx_sbytes = strip_info->tx_sbytes;
	unsigned long rx_ebytes = strip_info->rx_ebytes;
	unsigned long tx_ebytes = strip_info->tx_ebytes;
#endif

	seq_printf(seq, "\nInterface name\t\t%s\n", if_name);
	seq_printf(seq, " Radio working:\t\t%s\n", working ? "Yes" : "No");
	radio_address_to_string(&true_dev_addr, &addr_string);
	seq_printf(seq, " Radio address:\t\t%s\n", addr_string.c);
	if (manual_dev_addr) {
		radio_address_to_string(&dev_dev_addr, &addr_string);
		seq_printf(seq, " Device address:\t%s\n", addr_string.c);
	}
	seq_printf(seq, " Firmware version:\t%s", !working ? "Unknown" :
		     !firmware_level ? "Should be upgraded" :
		     firmware_version.c);
	if (firmware_level >= ChecksummedMessages)
		seq_printf(seq, " (Checksums Enabled)");
	seq_printf(seq, "\n");
	seq_printf(seq, " Serial number:\t\t%s\n", serial_number.c);
	seq_printf(seq, " Battery voltage:\t%s\n", battery_voltage.c);
	seq_printf(seq, " Transmit queue (bytes):%d\n", tx_left);
	seq_printf(seq, " Receive packet rate:   %ld packets per second\n",
		     rx_average_pps / 8);
	seq_printf(seq, " Transmit packet rate:  %ld packets per second\n",
		     tx_average_pps / 8);
	seq_printf(seq, " Sent packet rate:      %ld packets per second\n",
		     sx_average_pps / 8);
	seq_printf(seq, " Next watchdog probe:\t%s\n",
		     time_delta(temp, watchdog_doprobe));
	seq_printf(seq, " Next watchdog reset:\t%s\n",
		     time_delta(temp, watchdog_doreset));
	seq_printf(seq, " Next gratuitous ARP:\t");

	if (!memcmp
	    (strip_info->dev->dev_addr, zero_address.c,
	     sizeof(zero_address)))
		seq_printf(seq, "Disabled\n");
	else {
		seq_printf(seq, "%s\n", time_delta(temp, gratuitous_arp));
		seq_printf(seq, " Next ARP interval:\t%ld seconds\n",
			     JIFFIE_TO_SEC(arp_interval));
	}

	if (working) {
#ifdef EXT_COUNTERS
		seq_printf(seq, "\n");
		seq_printf(seq,
			     " Total bytes:         \trx:\t%lu\ttx:\t%lu\n",
			     rx_bytes, tx_bytes);
		seq_printf(seq,
			     "  thru radio:         \trx:\t%lu\ttx:\t%lu\n",
			     rx_rbytes, tx_rbytes);
		seq_printf(seq,
			     "  thru serial port:   \trx:\t%lu\ttx:\t%lu\n",
			     rx_sbytes, tx_sbytes);
		seq_printf(seq,
			     " Total stat/err bytes:\trx:\t%lu\ttx:\t%lu\n",
			     rx_ebytes, tx_ebytes);
#endif
		strip_seq_neighbours(seq, &strip_info->poletops,
					"Poletops:");
		strip_seq_neighbours(seq, &strip_info->portables,
					"Portables:");
	}
}

/*
 * This function is exports status information from the STRIP driver through
 * the /proc file system.
 */
static int strip_seq_show(struct seq_file *seq, void *v)
{
	if (v == SEQ_START_TOKEN)
		seq_printf(seq, "strip_version: %s\n", StripVersion);
	else
		strip_seq_status_info(seq, (const struct strip *)v);
	return 0;
}


static struct seq_operations strip_seq_ops = {
	.start = strip_seq_start,
	.next  = strip_seq_next,
	.stop  = strip_seq_stop,
	.show  = strip_seq_show,
};

static int strip_seq_open(struct inode *inode, struct file *file)
{
	return seq_open(file, &strip_seq_ops);
}

static const struct file_operations strip_seq_fops = {
	.owner	 = THIS_MODULE,
	.open    = strip_seq_open,
	.read    = seq_read,
	.llseek  = seq_lseek,
	.release = seq_release,
};
#endif



/************************************************************************/
/* Sending routines							*/

static void ResetRadio(struct strip *strip_info)
{
	struct tty_struct *tty = strip_info->tty;
	static const char init[] = "ate0q1dt**starmode\r**";
	StringDescriptor s = { init, sizeof(init) - 1 };

	/* 
	 * If the radio isn't working anymore,
	 * we should clear the old status information.
	 */
	if (strip_info->working) {
		printk(KERN_INFO "%s: No response: Resetting radio.\n",
		       strip_info->dev->name);
		strip_info->firmware_version.c[0] = '\0';
		strip_info->serial_number.c[0] = '\0';
		strip_info->battery_voltage.c[0] = '\0';
		strip_info->portables.num_nodes = 0;
		do_gettimeofday(&strip_info->portables.timestamp);
		strip_info->poletops.num_nodes = 0;
		do_gettimeofday(&strip_info->poletops.timestamp);
	}

	strip_info->pps_timer = jiffies;
	strip_info->rx_pps_count = 0;
	strip_info->tx_pps_count = 0;
	strip_info->sx_pps_count = 0;
	strip_info->rx_average_pps = 0;
	strip_info->tx_average_pps = 0;
	strip_info->sx_average_pps = 0;

	/* Mark radio address as unknown */
	*(MetricomAddress *) & strip_info->true_dev_addr = zero_address;
	if (!strip_info->manual_dev_addr)
		*(MetricomAddress *) strip_info->dev->dev_addr =
		    zero_address;
	strip_info->working = FALSE;
	strip_info->firmware_level = NoStructure;
	strip_info->next_command = CompatibilityCommand;
	strip_info->watchdog_doprobe = jiffies + 10 * HZ;
	strip_info->watchdog_doreset = jiffies + 1 * HZ;

	/* If the user has selected a baud rate above 38.4 see what magic we have to do */
	if (strip_info->user_baud > B38400) {
		/*
		 * Subtle stuff: Pay attention :-)
		 * If the serial port is currently at the user's selected (>38.4) rate,
		 * then we temporarily switch to 19.2 and issue the ATS304 command
		 * to tell the radio to switch to the user's selected rate.
		 * If the serial port is not currently at that rate, that means we just
		 * issued the ATS304 command last time through, so this time we restore
		 * the user's selected rate and issue the normal starmode reset string.
		 */
		if (strip_info->user_baud == get_baud(tty)) {
			static const char b0[] = "ate0q1s304=57600\r";
			static const char b1[] = "ate0q1s304=115200\r";
			static const StringDescriptor baudstring[2] =
			    { {b0, sizeof(b0) - 1}
			, {b1, sizeof(b1) - 1}
			};
			set_baud(tty, B19200);
			if (strip_info->user_baud == B57600)
				s = baudstring[0];
			else if (strip_info->user_baud == B115200)
				s = baudstring[1];
			else
				s = baudstring[1];	/* For now */
		} else
			set_baud(tty, strip_info->user_baud);
	}

	tty->driver->write(tty, s.string, s.length);
#ifdef EXT_COUNTERS
	strip_info->tx_ebytes += s.length;
#endif
}

/*
 * Called by the driver when there's room for more data.  If we have
 * more packets to send, we send them here.
 */

static void strip_write_some_more(struct tty_struct *tty)
{
	struct strip *strip_info = (struct strip *) tty->disc_data;

	/* First make sure we're connected. */
	if (!strip_info || strip_info->magic != STRIP_MAGIC ||
	    !netif_running(strip_info->dev))
		return;

	if (strip_info->tx_left > 0) {
		int num_written =
		    tty->driver->write(tty, strip_info->tx_head,
				      strip_info->tx_left);
		strip_info->tx_left -= num_written;
		strip_info->tx_head += num_written;
#ifdef EXT_COUNTERS
		strip_info->tx_sbytes += num_written;
#endif
	} else {		/* Else start transmission of another packet */

		tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
		strip_unlock(strip_info);
	}
}

static __u8 *add_checksum(__u8 * buffer, __u8 * end)
{
	__u16 sum = 0;
	__u8 *p = buffer;
	while (p < end)
		sum += *p++;
	end[3] = hextable[sum & 0xF];
	sum >>= 4;
	end[2] = hextable[sum & 0xF];
	sum >>= 4;
	end[1] = hextable[sum & 0xF];
	sum >>= 4;
	end[0] = hextable[sum & 0xF];
	return (end + 4);
}

static unsigned char *strip_make_packet(unsigned char *buffer,
					struct strip *strip_info,
					struct sk_buff *skb)
{
	__u8 *ptr = buffer;
	__u8 *stuffstate = NULL;
	STRIP_Header *header = (STRIP_Header *) skb->data;
	MetricomAddress haddr = header->dst_addr;
	int len = skb->len - sizeof(STRIP_Header);
	MetricomKey key;

	/*HexDump("strip_make_packet", strip_info, skb->data, skb->data + skb->len); */

	if (header->protocol == htons(ETH_P_IP))
		key = SIP0Key;
	else if (header->protocol == htons(ETH_P_ARP))
		key = ARP0Key;
	else {
		printk(KERN_ERR
		       "%s: strip_make_packet: Unknown packet type 0x%04X\n",
		       strip_info->dev->name, ntohs(header->protocol));
		return (NULL);
	}

	if (len > strip_info->mtu) {
		printk(KERN_ERR
		       "%s: Dropping oversized transmit packet: %d bytes\n",
		       strip_info->dev->name, len);
		return (NULL);
	}

	/*
	 * If we're sending to ourselves, discard the packet.
	 * (Metricom radios choke if they try to send a packet to their own address.)
	 */
	if (!memcmp(haddr.c, strip_info->true_dev_addr.c, sizeof(haddr))) {
		printk(KERN_ERR "%s: Dropping packet addressed to self\n",
		       strip_info->dev->name);
		return (NULL);
	}

	/*
	 * If this is a broadcast packet, send it to our designated Metricom
	 * 'broadcast hub' radio (First byte of address being 0xFF means broadcast)
	 */
	if (haddr.c[0] == 0xFF) {
		__be32 brd = 0;
		struct in_device *in_dev;

		rcu_read_lock();
		in_dev = __in_dev_get_rcu(strip_info->dev);
		if (in_dev == NULL) {
			rcu_read_unlock();
			return NULL;
		}
		if (in_dev->ifa_list)
			brd = in_dev->ifa_list->ifa_broadcast;
		rcu_read_unlock();

		/* arp_query returns 1 if it succeeds in looking up the address, 0 if it fails */
		if (!arp_query(haddr.c, brd, strip_info->dev)) {
			printk(KERN_ERR
			       "%s: Unable to send packet (no broadcast hub configured)\n",
			       strip_info->dev->name);
			return (NULL);
		}
		/*
		 * If we are the broadcast hub, don't bother sending to ourselves.
		 * (Metricom radios choke if they try to send a packet to their own address.)
		 */
		if (!memcmp
		    (haddr.c, strip_info->true_dev_addr.c, sizeof(haddr)))
			return (NULL);
	}

	*ptr++ = 0x0D;
	*ptr++ = '*';
	*ptr++ = hextable[haddr.c[2] >> 4];
	*ptr++ = hextable[haddr.c[2] & 0xF];
	*ptr++ = hextable[haddr.c[3] >> 4];
	*ptr++ = hextable[haddr.c[3] & 0xF];
	*ptr++ = '-';
	*ptr++ = hextable[haddr.c[4] >> 4];
	*ptr++ = hextable[haddr.c[4] & 0xF];
	*ptr++ = hextable[haddr.c[5] >> 4];
	*ptr++ = hextable[haddr.c[5] & 0xF];
	*ptr++ = '*';
	*ptr++ = key.c[0];
	*ptr++ = key.c[1];
	*ptr++ = key.c[2];
	*ptr++ = key.c[3];

	ptr =
	    StuffData(skb->data + sizeof(STRIP_Header), len, ptr,
		      &stuffstate);

	if (strip_info->firmware_level >= ChecksummedMessages)
		ptr = add_checksum(buffer + 1, ptr);

	*ptr++ = 0x0D;
	return (ptr);
}

static void strip_send(struct strip *strip_info, struct sk_buff *skb)
{
	MetricomAddress haddr;
	unsigned char *ptr = strip_info->tx_buff;
	int doreset = (long) jiffies - strip_info->watchdog_doreset >= 0;
	int doprobe = (long) jiffies - strip_info->watchdog_doprobe >= 0
	    && !doreset;
	__be32 addr, brd;

	/*
	 * 1. If we have a packet, encapsulate it and put it in the buffer
	 */
	if (skb) {
		char *newptr = strip_make_packet(ptr, strip_info, skb);
		strip_info->tx_pps_count++;
		if (!newptr)
			strip_info->tx_dropped++;
		else {
			ptr = newptr;
			strip_info->sx_pps_count++;
			strip_info->tx_packets++;	/* Count another successful packet */
#ifdef EXT_COUNTERS
			strip_info->tx_bytes += skb->len;
			strip_info->tx_rbytes += ptr - strip_info->tx_buff;
#endif
			/*DumpData("Sending:", strip_info, strip_info->tx_buff, ptr); */
			/*HexDump("Sending", strip_info, strip_info->tx_buff, ptr); */
		}
	}

	/*
	 * 2. If it is time for another tickle, tack it on, after the packet
	 */
	if (doprobe) {
		StringDescriptor ts = CommandString[strip_info->next_command];
#if TICKLE_TIMERS
		{
			struct timeval tv;
			do_gettimeofday(&tv);
			printk(KERN_INFO "**** Sending tickle string %d      at %02d.%06d\n",
			       strip_info->next_command, tv.tv_sec % 100,
			       tv.tv_usec);
		}
#endif
		if (ptr == strip_info->tx_buff)
			*ptr++ = 0x0D;

		*ptr++ = '*';	/* First send "**" to provoke an error message */
		*ptr++ = '*';

		/* Then add the command */
		memcpy(ptr, ts.string, ts.length);

		/* Add a checksum ? */
		if (strip_info->firmware_level < ChecksummedMessages)
			ptr += ts.length;
		else
			ptr = add_checksum(ptr, ptr + ts.length);

		*ptr++ = 0x0D;	/* Terminate the command with a <CR> */

		/* Cycle to next periodic command? */
		if (strip_info->firmware_level >= StructuredMessages)
			if (++strip_info->next_command >=
			    ARRAY_SIZE(CommandString))
				strip_info->next_command = 0;
#ifdef EXT_COUNTERS
		strip_info->tx_ebytes += ts.length;
#endif
		strip_info->watchdog_doprobe = jiffies + 10 * HZ;
		strip_info->watchdog_doreset = jiffies + 1 * HZ;
		/*printk(KERN_INFO "%s: Routine radio test.\n", strip_info->dev->name); */
	}

	/*
	 * 3. Set up the strip_info ready to send the data (if any).
	 */
	strip_info->tx_head = strip_info->tx_buff;
	strip_info->tx_left = ptr - strip_info->tx_buff;
	strip_info->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);

	/*
	 * 4. Debugging check to make sure we're not overflowing the buffer.
	 */
	if (strip_info->tx_size - strip_info->tx_left < 20)
		printk(KERN_ERR "%s: Sending%5d bytes;%5d bytes free.\n",
		       strip_info->dev->name, strip_info->tx_left,
		       strip_info->tx_size - strip_info->tx_left);

	/*
	 * 5. If watchdog has expired, reset the radio. Note: if there's data waiting in
	 * the buffer, strip_write_some_more will send it after the reset has finished
	 */
	if (doreset) {
		ResetRadio(strip_info);
		return;
	}

	if (1) {
		struct in_device *in_dev;

		brd = addr = 0;
		rcu_read_lock();
		in_dev = __in_dev_get_rcu(strip_info->dev);
		if (in_dev) {
			if (in_dev->ifa_list) {
				brd = in_dev->ifa_list->ifa_broadcast;
				addr = in_dev->ifa_list->ifa_local;
			}
		}
		rcu_read_unlock();
	}


	/*
	 * 6. If it is time for a periodic ARP, queue one up to be sent.
	 * We only do this if:
	 *  1. The radio is working
	 *  2. It's time to send another periodic ARP
	 *  3. We really know what our address is (and it is not manually set to zero)
	 *  4. We have a designated broadcast address configured
	 * If we queue up an ARP packet when we don't have a designated broadcast
	 * address configured, then the packet will just have to be discarded in
	 * strip_make_packet. This is not fatal, but it causes misleading information
	 * to be displayed in tcpdump. tcpdump will report that periodic APRs are
	 * being sent, when in fact they are not, because they are all being dropped
	 * in the strip_make_packet routine.
	 */
	if (strip_info->working
	    && (long) jiffies - strip_info->gratuitous_arp >= 0
	    && memcmp(strip_info->dev->dev_addr, zero_address.c,
		      sizeof(zero_address))
	    && arp_query(haddr.c, brd, strip_info->dev)) {
		/*printk(KERN_INFO "%s: Sending gratuitous ARP with interval %ld\n",
		   strip_info->dev->name, strip_info->arp_interval / HZ); */
		strip_info->gratuitous_arp =
		    jiffies + strip_info->arp_interval;
		strip_info->arp_interval *= 2;
		if (strip_info->arp_interval > MaxARPInterval)
			strip_info->arp_interval = MaxARPInterval;
		if (addr)
			arp_send(ARPOP_REPLY, ETH_P_ARP, addr,	/* Target address of ARP packet is our address */
				 strip_info->dev,	/* Device to send packet on */
				 addr,	/* Source IP address this ARP packet comes from */
				 NULL,	/* Destination HW address is NULL (broadcast it) */
				 strip_info->dev->dev_addr,	/* Source HW address is our HW address */
				 strip_info->dev->dev_addr);	/* Target HW address is our HW address (redundant) */
	}

	/*
	 * 7. All ready. Start the transmission
	 */
	strip_write_some_more(strip_info->tty);
}

/* Encapsulate a datagram and kick it into a TTY queue. */
static int strip_xmit(struct sk_buff *skb, struct net_device *dev)
{
	struct strip *strip_info = netdev_priv(dev);

	if (!netif_running(dev)) {
		printk(KERN_ERR "%s: xmit call when iface is down\n",
		       dev->name);
		return (1);
	}

	netif_stop_queue(dev);

	del_timer(&strip_info->idle_timer);


	if (time_after(jiffies, strip_info->pps_timer + HZ)) {
		unsigned long t = jiffies - strip_info->pps_timer;
		unsigned long rx_pps_count = (strip_info->rx_pps_count * HZ * 8 + t / 2) / t;
		unsigned long tx_pps_count = (strip_info->tx_pps_count * HZ * 8 + t / 2) / t;
		unsigned long sx_pps_count = (strip_info->sx_pps_count * HZ * 8 + t / 2) / t;

		strip_info->pps_timer = jiffies;
		strip_info->rx_pps_count = 0;
		strip_info->tx_pps_count = 0;
		strip_info->sx_pps_count = 0;

		strip_info->rx_average_pps = (strip_info->rx_average_pps + rx_pps_count + 1) / 2;
		strip_info->tx_average_pps = (strip_info->tx_average_pps + tx_pps_count + 1) / 2;
		strip_info->sx_average_pps = (strip_info->sx_average_pps + sx_pps_count + 1) / 2;

		if (rx_pps_count / 8 >= 10)
			printk(KERN_INFO "%s: WARNING: Receiving %ld packets per second.\n",
			       strip_info->dev->name, rx_pps_count / 8);
		if (tx_pps_count / 8 >= 10)
			printk(KERN_INFO "%s: WARNING: Tx        %ld packets per second.\n",
			       strip_info->dev->name, tx_pps_count / 8);
		if (sx_pps_count / 8 >= 10)
			printk(KERN_INFO "%s: WARNING: Sending   %ld packets per second.\n",
			       strip_info->dev->name, sx_pps_count / 8);
	}

	spin_lock_bh(&strip_lock);

	strip_send(strip_info, skb);

	spin_unlock_bh(&strip_lock);

	if (skb)
		dev_kfree_skb(skb);
	return 0;
}

/*
 * IdleTask periodically calls strip_xmit, so even when we have no IP packets
 * to send for an extended period of time, the watchdog processing still gets
 * done to ensure that the radio stays in Starmode
 */

static void strip_IdleTask(unsigned long parameter)
{
	strip_xmit(NULL, (struct net_device *) parameter);
}

/*
 * Create the MAC header for an arbitrary protocol layer
 *
 * saddr!=NULL        means use this specific address (n/a for Metricom)
 * saddr==NULL        means use default device source address
 * daddr!=NULL        means use this destination address
 * daddr==NULL        means leave destination address alone
 *                 (e.g. unresolved arp -- kernel will call
 *                 rebuild_header later to fill in the address)
 */

static int strip_header(struct sk_buff *skb, struct net_device *dev,
			unsigned short type, void *daddr, void *saddr,
			unsigned len)
{
	struct strip *strip_info = netdev_priv(dev);
	STRIP_Header *header = (STRIP_Header *) skb_push(skb, sizeof(STRIP_Header));

	/*printk(KERN_INFO "%s: strip_header 0x%04X %s\n", dev->name, type,
	   type == ETH_P_IP ? "IP" : type == ETH_P_ARP ? "ARP" : ""); */

	header->src_addr = strip_info->true_dev_addr;
	header->protocol = htons(type);

	/*HexDump("strip_header", netdev_priv(dev), skb->data, skb->data + skb->len); */

	if (!daddr)
		return (-dev->hard_header_len);

	header->dst_addr = *(MetricomAddress *) daddr;
	return (dev->hard_header_len);
}

/*
 * Rebuild the MAC header. This is called after an ARP
 * (or in future other address resolution) has completed on this
 * sk_buff. We now let ARP fill in the other fields.
 * I think this should return zero if packet is ready to send,
 * or non-zero if it needs more time to do an address lookup
 */

static int strip_rebuild_header(struct sk_buff *skb)
{
#ifdef CONFIG_INET
	STRIP_Header *header = (STRIP_Header *) skb->data;

	/* Arp find returns zero if if knows the address, */
	/* or if it doesn't know the address it sends an ARP packet and returns non-zero */
	return arp_find(header->dst_addr.c, skb) ? 1 : 0;
#else
	return 0;
#endif
}


/************************************************************************/
/* Receiving routines							*/

/*
 * This function parses the response to the ATS300? command,
 * extracting the radio version and serial number.
 */
static void get_radio_version(struct strip *strip_info, __u8 * ptr, __u8 * end)
{
	__u8 *p, *value_begin, *value_end;
	int len;

	/* Determine the beginning of the second line of the payload */
	p = ptr;
	while (p < end && *p != 10)
		p++;
	if (p >= end)
		return;
	p++;
	value_begin = p;

	/* Determine the end of line */
	while (p < end && *p != 10)
		p++;
	if (p >= end)
		return;
	value_end = p;
	p++;

	len = value_end - value_begin;
	len = min_t(int, len, sizeof(FirmwareVersion) - 1);
	if (strip_info->firmware_version.c[0] == 0)
		printk(KERN_INFO "%s: Radio Firmware: %.*s\n",
		       strip_info->dev->name, len, value_begin);
	sprintf(strip_info->firmware_version.c, "%.*s", len, value_begin);

	/* Look for the first colon */
	while (p < end && *p != ':')
		p++;
	if (p >= end)
		return;
	/* Skip over the space */
	p += 2;
	len = sizeof(SerialNumber) - 1;
	if (p + len <= end) {
		sprintf(strip_info->serial_number.c, "%.*s", len, p);
	} else {
		printk(KERN_DEBUG
		       "STRIP: radio serial number shorter (%zd) than expected (%d)\n",
		       end - p, len);
	}
}

/*
 * This function parses the response to the ATS325? command,
 * extracting the radio battery voltage.
 */
static void get_radio_voltage(struct strip *strip_info, __u8 * ptr, __u8 * end)
{
	int len;

	len = sizeof(BatteryVoltage) - 1;
	if (ptr + len <= end) {
		sprintf(strip_info->battery_voltage.c, "%.*s", len, ptr);
	} else {
		printk(KERN_DEBUG
		       "STRIP: radio voltage string shorter (%zd) than expected (%d)\n",
		       end - ptr, len);
	}
}

/*
 * This function parses the responses to the AT~LA and ATS311 commands,
 * which list the radio's neighbours.
 */
static void get_radio_neighbours(MetricomNodeTable * table, __u8 * ptr, __u8 * end)
{
	table->num_nodes = 0;
	while (ptr < end && table->num_nodes < NODE_TABLE_SIZE) {
		MetricomNode *node = &table->node[table->num_nodes++];
		char *dst = node->c, *limit = dst + sizeof(*node) - 1;
		while (ptr < end && *ptr <= 32)
			ptr++;
		while (ptr < end && dst < limit && *ptr != 10)
			*dst++ = *ptr++;
		*dst++ = 0;
		while (ptr < end && ptr[-1] != 10)
			ptr++;
	}
	do_gettimeofday(&table->timestamp);
}

static int get_radio_address(struct strip *strip_info, __u8 * p)
{
	MetricomAddress addr;

	if (string_to_radio_address(&addr, p))
		return (1);

	/* See if our radio address has changed */
	if (memcmp(strip_info->true_dev_addr.c, addr.c, sizeof(addr))) {
		MetricomAddressString addr_string;
		radio_address_to_string(&addr, &addr_string);
		printk(KERN_INFO "%s: Radio address = %s\n",
		       strip_info->dev->name, addr_string.c);
		strip_info->true_dev_addr = addr;
		if (!strip_info->manual_dev_addr)
			*(MetricomAddress *) strip_info->dev->dev_addr =
			    addr;
		/* Give the radio a few seconds to get its head straight, then send an arp */
		strip_info->gratuitous_arp = jiffies + 15 * HZ;
		strip_info->arp_interval = 1 * HZ;
	}
	return (0);
}

static int verify_checksum(struct strip *strip_info)
{
	__u8 *p = strip_info->sx_buff;
	__u8 *end = strip_info->sx_buff + strip_info->sx_count - 4;
	u_short sum =
	    (READHEX16(end[0]) << 12) | (READHEX16(end[1]) << 8) |
	    (READHEX16(end[2]) << 4) | (READHEX16(end[3]));
	while (p < end)
		sum -= *p++;
	if (sum == 0 && strip_info->firmware_level == StructuredMessages) {
		strip_info->firmware_level = ChecksummedMessages;
		printk(KERN_INFO "%s: Radio provides message checksums\n",
		       strip_info->dev->name);
	}
	return (sum == 0);
}

static void RecvErr(char *msg, struct strip *strip_info)
{
	__u8 *ptr = strip_info->sx_buff;
	__u8 *end = strip_info->sx_buff + strip_info->sx_count;
	DumpData(msg, strip_info, ptr, end);
	strip_info->rx_errors++;
}

static void RecvErr_Message(struct strip *strip_info, __u8 * sendername,
			    const __u8 * msg, u_long len)
{
	if (has_prefix(msg, len, "001")) {	/* Not in StarMode! */
		RecvErr("Error Msg:", strip_info);
		printk(KERN_INFO "%s: Radio %s is not in StarMode\n",
		       strip_info->dev->name, sendername);
	}

	else if (has_prefix(msg, len, "002")) {	/* Remap handle */
		/* We ignore "Remap handle" messages for now */
	}

	else if (has_prefix(msg, len, "003")) {	/* Can't resolve name */
		RecvErr("Error Msg:", strip_info);
		printk(KERN_INFO "%s: Destination radio name is unknown\n",
		       strip_info->dev->name);
	}

	else if (has_prefix(msg, len, "004")) {	/* Name too small or missing */
		strip_info->watchdog_doreset = jiffies + LongTime;
#if TICKLE_TIMERS
		{
			struct timeval tv;
			do_gettimeofday(&tv);
			printk(KERN_INFO
			       "**** Got ERR_004 response         at %02d.%06d\n",
			       tv.tv_sec % 100, tv.tv_usec);
		}
#endif
		if (!strip_info->working) {
			strip_info->working = TRUE;
			printk(KERN_INFO "%s: Radio now in starmode\n",
			       strip_info->dev->name);
			/*
			 * If the radio has just entered a working state, we should do our first
			 * probe ASAP, so that we find out our radio address etc. without delay.
			 */
			strip_info->watchdog_doprobe = jiffies;
		}
		if (strip_info->firmware_level == NoStructure && sendername) {
			strip_info->firmware_level = StructuredMessages;
			strip_info->next_command = 0;	/* Try to enable checksums ASAP */
			printk(KERN_INFO
			       "%s: Radio provides structured messages\n",
			       strip_info->dev->name);
		}
		if (strip_info->firmware_level >= StructuredMessages) {
			/*
			 * If this message has a valid checksum on the end, then the call to verify_checksum
			 * will elevate the firmware_level to ChecksummedMessages for us. (The actual return
			 * code from verify_checksum is ignored here.)
			 */
			verify_checksum(strip_info);
			/*
			 * If the radio has structured messages but we don't yet have all our information about it,
			 * we should do probes without delay, until we have gathered all the information
			 */
			if (!GOT_ALL_RADIO_INFO(strip_info))
				strip_info->watchdog_doprobe = jiffies;
		}
	}

	else if (has_prefix(msg, len, "005"))	/* Bad count specification */
		RecvErr("Error Msg:", strip_info);

	else if (has_prefix(msg, len, "006"))	/* Header too big */
		RecvErr("Error Msg:", strip_info);

	else if (has_prefix(msg, len, "007")) {	/* Body too big */
		RecvErr("Error Msg:", strip_info);
		printk(KERN_ERR
		       "%s: Error! Packet size too big for radio.\n",
		       strip_info->dev->name);
	}

	else if (has_prefix(msg, len, "008")) {	/* Bad character in name */
		RecvErr("Error Msg:", strip_info);
		printk(KERN_ERR
		       "%s: Radio name contains illegal character\n",
		       strip_info->dev->name);
	}

	else if (has_prefix(msg, len, "009"))	/* No count or line terminator */
		RecvErr("Error Msg:", strip_info);

	else if (has_prefix(msg, len, "010"))	/* Invalid checksum */
		RecvErr("Error Msg:", strip_info);

	else if (has_prefix(msg, len, "011"))	/* Checksum didn't match */
		RecvErr("Error Msg:", strip_info);

	else if (has_prefix(msg, len, "012"))	/* Failed to transmit packet */
		RecvErr("Error Msg:", strip_info);

	else
		RecvErr("Error Msg:", strip_info);
}

static void process_AT_response(struct strip *strip_info, __u8 * ptr,
				__u8 * end)
{
	u_long len;
	__u8 *p = ptr;
	while (p < end && p[-1] != 10)
		p++;		/* Skip past first newline character */
	/* Now ptr points to the AT command, and p points to the text of the response. */
	len = p - ptr;

#if TICKLE_TIMERS
	{
		struct timeval tv;
		do_gettimeofday(&tv);
		printk(KERN_INFO "**** Got AT response %.7s      at %02d.%06d\n",
		       ptr, tv.tv_sec % 100, tv.tv_usec);
	}
#endif

	if (has_prefix(ptr, len, "ATS300?"))
		get_radio_version(strip_info, p, end);
	else if (has_prefix(ptr, len, "ATS305?"))
		get_radio_address(strip_info, p);
	else if (has_prefix(ptr, len, "ATS311?"))
		get_radio_neighbours(&strip_info->poletops, p, end);
	else if (has_prefix(ptr, len, "ATS319=7"))
		verify_checksum(strip_info);
	else if (has_prefix(ptr, len, "ATS325?"))
		get_radio_voltage(strip_info, p, end);
	else if (has_prefix(ptr, len, "AT~LA"))
		get_radio_neighbours(&strip_info->portables, p, end);
	else
		RecvErr("Unknown AT Response:", strip_info);
}

static void process_ACK(struct strip *strip_info, __u8 * ptr, __u8 * end)
{
	/* Currently we don't do anything with ACKs from the radio */
}

static void process_Info(struct strip *strip_info, __u8 * ptr, __u8 * end)
{
	if (ptr + 16 > end)
		RecvErr("Bad Info Msg:", strip_info);
}

static struct net_device *get_strip_dev(struct strip *strip_info)
{
	/* If our hardware address is *manually set* to zero, and we know our */
	/* real radio hardware address, try to find another strip device that has been */
	/* manually set to that address that we can 'transfer ownership' of this packet to  */
	if (strip_info->manual_dev_addr &&
	    !memcmp(strip_info->dev->dev_addr, zero_address.c,
		    sizeof(zero_address))
	    && memcmp(&strip_info->true_dev_addr, zero_address.c,
		      sizeof(zero_address))) {
		struct net_device *dev;
		read_lock_bh(&dev_base_lock);
		dev = dev_base;
		while (dev) {
			if (dev->type == strip_info->dev->type &&
			    !memcmp(dev->dev_addr,
				    &strip_info->true_dev_addr,
				    sizeof(MetricomAddress))) {
				printk(KERN_INFO
				       "%s: Transferred packet ownership to %s.\n",
				       strip_info->dev->name, dev->name);
				read_unlock_bh(&dev_base_lock);
				return (dev);
			}
			dev = dev->next;
		}
		read_unlock_bh(&dev_base_lock);
	}
	return (strip_info->dev);
}

/*
 * Send one completely decapsulated datagram to the next layer.
 */

static void deliver_packet(struct strip *strip_info, STRIP_Header * header,
			   __u16 packetlen)
{
	struct sk_buff *skb = dev_alloc_skb(sizeof(STRIP_Header) + packetlen);
	if (!skb) {
		printk(KERN_ERR "%s: memory squeeze, dropping packet.\n",
		       strip_info->dev->name);
		strip_info->rx_dropped++;
	} else {
		memcpy(skb_put(skb, sizeof(STRIP_Header)), header,
		       sizeof(STRIP_Header));
		memcpy(skb_put(skb, packetlen), strip_info->rx_buff,
		       packetlen);
		skb->dev = get_strip_dev(strip_info);
		skb->protocol = header->protocol;
		skb_reset_mac_header(skb);

		/* Having put a fake header on the front of the sk_buff for the */
		/* benefit of tools like tcpdump, skb_pull now 'consumes' that  */
		/* fake header before we hand the packet up to the next layer.  */
		skb_pull(skb, sizeof(STRIP_Header));

		/* Finally, hand the packet up to the next layer (e.g. IP or ARP, etc.) */
		strip_info->rx_packets++;
		strip_info->rx_pps_count++;
#ifdef EXT_COUNTERS
		strip_info->rx_bytes += packetlen;
#endif
		skb->dev->last_rx = jiffies;
		netif_rx(skb);
	}
}

static void process_IP_packet(struct strip *strip_info,
			      STRIP_Header * header, __u8 * ptr,
			      __u8 * end)
{
	__u16 packetlen;

	/* Decode start of the IP packet header */
	ptr = UnStuffData(ptr, end, strip_info->rx_buff, 4);
	if (!ptr) {
		RecvErr("IP Packet too short", strip_info);
		return;
	}

	packetlen = ((__u16) strip_info->rx_buff[2] << 8) | strip_info->rx_buff[3];

	if (packetlen > MAX_RECV_MTU) {
		printk(KERN_INFO "%s: Dropping oversized received IP packet: %d bytes\n",
		       strip_info->dev->name, packetlen);
		strip_info->rx_dropped++;
		return;
	}

	/*printk(KERN_INFO "%s: Got %d byte IP packet\n", strip_info->dev->name, packetlen); */

	/* Decode remainder of the IP packet */
	ptr =
	    UnStuffData(ptr, end, strip_info->rx_buff + 4, packetlen - 4);
	if (!ptr) {
		RecvErr("IP Packet too short", strip_info);
		return;
	}

	if (ptr < end) {
		RecvErr("IP Packet too long", strip_info);
		return;
	}

	header->protocol = htons(ETH_P_IP);

	deliver_packet(strip_info, header, packetlen);
}

static void process_ARP_packet(struct strip *strip_info,
			       STRIP_Header * header, __u8 * ptr,
			       __u8 * end)
{
	__u16 packetlen;
	struct arphdr *arphdr = (struct arphdr *) strip_info->rx_buff;

	/* Decode start of the ARP packet */
	ptr = UnStuffData(ptr, end, strip_info->rx_buff, 8);
	if (!ptr) {
		RecvErr("ARP Packet too short", strip_info);
		return;
	}

	packetlen = 8 + (arphdr->ar_hln + arphdr->ar_pln) * 2;

	if (packetlen > MAX_RECV_MTU) {
		printk(KERN_INFO
		       "%s: Dropping oversized received ARP packet: %d bytes\n",
		       strip_info->dev->name, packetlen);
		strip_info->rx_dropped++;
		return;
	}

	/*printk(KERN_INFO "%s: Got %d byte ARP %s\n",
	   strip_info->dev->name, packetlen,
	   ntohs(arphdr->ar_op) == ARPOP_REQUEST ? "request" : "reply"); */

	/* Decode remainder of the ARP packet */
	ptr =
	    UnStuffData(ptr, end, strip_info->rx_buff + 8, packetlen - 8);
	if (!ptr) {
		RecvErr("ARP Packet too short", strip_info);
		return;
	}

	if (ptr < end) {
		RecvErr("ARP Packet too long", strip_info);
		return;
	}

	header->protocol = htons(ETH_P_ARP);

	deliver_packet(strip_info, header, packetlen);
}

/*
 * process_text_message processes a <CR>-terminated block of data received
 * from the radio that doesn't begin with a '*' character. All normal
 * Starmode communication messages with the radio begin with a '*',
 * so any text that does not indicates a serial port error, a radio that
 * is in Hayes command mode instead of Starmode, or a radio with really
 * old firmware that doesn't frame its Starmode responses properly.
 */
static void process_text_message(struct strip *strip_info)
{
	__u8 *msg = strip_info->sx_buff;
	int len = strip_info->sx_count;

	/* Check for anything that looks like it might be our radio name */
	/* (This is here for backwards compatibility with old firmware)  */
	if (len == 9 && get_radio_address(strip_info, msg) == 0)
		return;

	if (text_equal(msg, len, "OK"))
		return;		/* Ignore 'OK' responses from prior commands */
	if (text_equal(msg, len, "ERROR"))
		return;		/* Ignore 'ERROR' messages */
	if (has_prefix(msg, len, "ate0q1"))
		return;		/* Ignore character echo back from the radio */

	/* Catch other error messages */
	/* (This is here for backwards compatibility with old firmware) */
	if (has_prefix(msg, len, "ERR_")) {
		RecvErr_Message(strip_info, NULL, &msg[4], len - 4);
		return;
	}

	RecvErr("No initial *", strip_info);
}

/*
 * process_message processes a <CR>-terminated block of data received
 * from the radio. If the radio is not in Starmode or has old firmware,
 * it may be a line of text in response to an AT command. Ideally, with
 * a current radio that's properly in Starmode, all data received should
 * be properly framed and checksummed radio message blocks, containing
 * either a starmode packet, or a other communication from the radio
 * firmware, like "INF_" Info messages and &COMMAND responses.
 */
static void process_message(struct strip *strip_info)
{
	STRIP_Header header = { zero_address, zero_address, 0 };
	__u8 *ptr = strip_info->sx_buff;
	__u8 *end = strip_info->sx_buff + strip_info->sx_count;
	__u8 sendername[32], *sptr = sendername;
	MetricomKey key;

	/*HexDump("Receiving", strip_info, ptr, end); */

	/* Check for start of address marker, and then skip over it */
	if (*ptr == '*')
		ptr++;
	else {
		process_text_message(strip_info);
		return;
	}

	/* Copy out the return address */
	while (ptr < end && *ptr != '*'
	       && sptr < ARRAY_END(sendername) - 1)
		*sptr++ = *ptr++;
	*sptr = 0;		/* Null terminate the sender name */

	/* Check for end of address marker, and skip over it */
	if (ptr >= end || *ptr != '*') {
		RecvErr("No second *", strip_info);
		return;
	}
	ptr++;			/* Skip the second '*' */

	/* If the sender name is "&COMMAND", ignore this 'packet'       */
	/* (This is here for backwards compatibility with old firmware) */
	if (!strcmp(sendername, "&COMMAND")) {
		strip_info->firmware_level = NoStructure;
		strip_info->next_command = CompatibilityCommand;
		return;
	}

	if (ptr + 4 > end) {
		RecvErr("No proto key", strip_info);
		return;
	}

	/* Get the protocol key out of the buffer */
	key.c[0] = *ptr++;
	key.c[1] = *ptr++;
	key.c[2] = *ptr++;
	key.c[3] = *ptr++;

	/* If we're using checksums, verify the checksum at the end of the packet */
	if (strip_info->firmware_level >= ChecksummedMessages) {
		end -= 4;	/* Chop the last four bytes off the packet (they're the checksum) */
		if (ptr > end) {
			RecvErr("Missing Checksum", strip_info);
			return;
		}
		if (!verify_checksum(strip_info)) {
			RecvErr("Bad Checksum", strip_info);
			return;
		}
	}

	/*printk(KERN_INFO "%s: Got packet from \"%s\".\n", strip_info->dev->name, sendername); */

	/*
	 * Fill in (pseudo) source and destination addresses in the packet.
	 * We assume that the destination address was our address (the radio does not
	 * tell us this). If the radio supplies a source address, then we use it.
	 */
	header.dst_addr = strip_info->true_dev_addr;
	string_to_radio_address(&header.src_addr, sendername);

#ifdef EXT_COUNTERS
	if (key.l == SIP0Key.l) {
		strip_info->rx_rbytes += (end - ptr);
		process_IP_packet(strip_info, &header, ptr, end);
	} else if (key.l == ARP0Key.l) {
		strip_info->rx_rbytes += (end - ptr);
		process_ARP_packet(strip_info, &header, ptr, end);
	} else if (key.l == ATR_Key.l) {
		strip_info->rx_ebytes += (end - ptr);
		process_AT_response(strip_info, ptr, end);
	} else if (key.l == ACK_Key.l) {
		strip_info->rx_ebytes += (end - ptr);
		process_ACK(strip_info, ptr, end);
	} else if (key.l == INF_Key.l) {
		strip_info->rx_ebytes += (end - ptr);
		process_Info(strip_info, ptr, end);
	} else if (key.l == ERR_Key.l) {
		strip_info->rx_ebytes += (end - ptr);
		RecvErr_Message(strip_info, sendername, ptr, end - ptr);
	} else
		RecvErr("Unrecognized protocol key", strip_info);
#else
	if (key.l == SIP0Key.l)
		process_IP_packet(strip_info, &header, ptr, end);
	else if (key.l == ARP0Key.l)
		process_ARP_packet(strip_info, &header, ptr, end);
	else if (key.l == ATR_Key.l)
		process_AT_response(strip_info, ptr, end);
	else if (key.l == ACK_Key.l)
		process_ACK(strip_info, ptr, end);
	else if (key.l == INF_Key.l)
		process_Info(strip_info, ptr, end);
	else if (key.l == ERR_Key.l)
		RecvErr_Message(strip_info, sendername, ptr, end - ptr);
	else
		RecvErr("Unrecognized protocol key", strip_info);
#endif
}

#define TTYERROR(X) ((X) == TTY_BREAK   ? "Break"            : \
                     (X) == TTY_FRAME   ? "Framing Error"    : \
                     (X) == TTY_PARITY  ? "Parity Error"     : \
                     (X) == TTY_OVERRUN ? "Hardware Overrun" : "Unknown Error")

/*
 * Handle the 'receiver data ready' interrupt.
 * This function is called by the 'tty_io' module in the kernel when
 * a block of STRIP data has been received, which can now be decapsulated
 * and sent on to some IP layer for further processing.
 */

static void strip_receive_buf(struct tty_struct *tty, const unsigned char *cp,
		  char *fp, int count)
{
	struct strip *strip_info = (struct strip *) tty->disc_data;
	const unsigned char *end = cp + count;

	if (!strip_info || strip_info->magic != STRIP_MAGIC
	    || !netif_running(strip_info->dev))
		return;

	spin_lock_bh(&strip_lock);
#if 0
	{
		struct timeval tv;
		do_gettimeofday(&tv);
		printk(KERN_INFO
		       "**** strip_receive_buf: %3d bytes at %02d.%06d\n",
		       count, tv.tv_sec % 100, tv.tv_usec);
	}
#endif

#ifdef EXT_COUNTERS
	strip_info->rx_sbytes += count;
#endif

	/* Read the characters out of the buffer */
	while (cp < end) {
		if (fp && *fp)
			printk(KERN_INFO "%s: %s on serial port\n",
			       strip_info->dev->name, TTYERROR(*fp));
		if (fp && *fp++ && !strip_info->discard) {	/* If there's a serial error, record it */
			/* If we have some characters in the buffer, discard them */
			strip_info->discard = strip_info->sx_count;
			strip_info->rx_errors++;
		}

		/* Leading control characters (CR, NL, Tab, etc.) are ignored */
		if (strip_info->sx_count > 0 || *cp >= ' ') {
			if (*cp == 0x0D) {	/* If end of packet, decide what to do with it */
				if (strip_info->sx_count > 3000)
					printk(KERN_INFO
					       "%s: Cut a %d byte packet (%zd bytes remaining)%s\n",
					       strip_info->dev->name,
					       strip_info->sx_count,
					       end - cp - 1,
					       strip_info->
					       discard ? " (discarded)" :
					       "");
				if (strip_info->sx_count >
				    strip_info->sx_size) {
					strip_info->rx_over_errors++;
					printk(KERN_INFO
					       "%s: sx_buff overflow (%d bytes total)\n",
					       strip_info->dev->name,
					       strip_info->sx_count);
				} else if (strip_info->discard)
					printk(KERN_INFO
					       "%s: Discarding bad packet (%d/%d)\n",
					       strip_info->dev->name,
					       strip_info->discard,
					       strip_info->sx_count);
				else
					process_message(strip_info);
				strip_info->discard = 0;
				strip_info->sx_count = 0;
			} else {
				/* Make sure we have space in the buffer */
				if (strip_info->sx_count <
				    strip_info->sx_size)
					strip_info->sx_buff[strip_info->
							    sx_count] =
					    *cp;
				strip_info->sx_count++;
			}
		}
		cp++;
	}
	spin_unlock_bh(&strip_lock);
}


/************************************************************************/
/* General control routines						*/

static int set_mac_address(struct strip *strip_info,
			   MetricomAddress * addr)
{
	/*
	 * We're using a manually specified address if the address is set
	 * to anything other than all ones. Setting the address to all ones
	 * disables manual mode and goes back to automatic address determination
	 * (tracking the true address that the radio has).
	 */
	strip_info->manual_dev_addr =
	    memcmp(addr->c, broadcast_address.c,
		   sizeof(broadcast_address));
	if (strip_info->manual_dev_addr)
		*(MetricomAddress *) strip_info->dev->dev_addr = *addr;
	else
		*(MetricomAddress *) strip_info->dev->dev_addr =
		    strip_info->true_dev_addr;
	return 0;
}

static int strip_set_mac_address(struct net_device *dev, void *addr)
{
	struct strip *strip_info = netdev_priv(dev);
	struct sockaddr *sa = addr;
	printk(KERN_INFO "%s: strip_set_dev_mac_address called\n", dev->name);
	set_mac_address(strip_info, (MetricomAddress *) sa->sa_data);
	return 0;
}

static struct net_device_stats *strip_get_stats(struct net_device *dev)
{
	struct strip *strip_info = netdev_priv(dev);
	static struct net_device_stats stats;

	memset(&stats, 0, sizeof(struct net_device_stats));

	stats.rx_packets = strip_info->rx_packets;
	stats.tx_packets = strip_info->tx_packets;
	stats.rx_dropped = strip_info->rx_dropped;
	stats.tx_dropped = strip_info->tx_dropped;
	stats.tx_errors = strip_info->tx_errors;
	stats.rx_errors = strip_info->rx_errors;
	stats.rx_over_errors = strip_info->rx_over_errors;
	return (&stats);
}


/************************************************************************/
/* Opening and closing							*/

/*
 * Here's the order things happen:
 * When the user runs "slattach -p strip ..."
 *  1. The TTY module calls strip_open;;
 *  2. strip_open calls strip_alloc
 *  3.                  strip_alloc calls register_netdev
 *  4.                  register_netdev calls strip_dev_init
 *  5. then strip_open finishes setting up the strip_info
 *
 * When the user runs "ifconfig st<x> up address netmask ..."
 *  6. strip_open_low gets called
 *
 * When the user runs "ifconfig st<x> down"
 *  7. strip_close_low gets called
 *
 * When the user kills the slattach process
 *  8. strip_close gets called
 *  9. strip_close calls dev_close
 * 10. if the device is still up, then dev_close calls strip_close_low
 * 11. strip_close calls strip_free
 */

/* Open the low-level part of the STRIP channel. Easy! */

static int strip_open_low(struct net_device *dev)
{
	struct strip *strip_info = netdev_priv(dev);

	if (strip_info->tty == NULL)
		return (-ENODEV);

	if (!allocate_buffers(strip_info, dev->mtu))
		return (-ENOMEM);

	strip_info->sx_count = 0;
	strip_info->tx_left = 0;

	strip_info->discard = 0;
	strip_info->working = FALSE;
	strip_info->firmware_level = NoStructure;
	strip_info->next_command = CompatibilityCommand;
	strip_info->user_baud = get_baud(strip_info->tty);

	printk(KERN_INFO "%s: Initializing Radio.\n",
	       strip_info->dev->name);
	ResetRadio(strip_info);
	strip_info->idle_timer.expires = jiffies + 1 * HZ;
	add_timer(&strip_info->idle_timer);
	netif_wake_queue(dev);
	return (0);
}


/*
 * Close the low-level part of the STRIP channel. Easy!
 */

static int strip_close_low(struct net_device *dev)
{
	struct strip *strip_info = netdev_priv(dev);

	if (strip_info->tty == NULL)
		return -EBUSY;
	strip_info->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);

	netif_stop_queue(dev);

	/*
	 * Free all STRIP frame buffers.
	 */
	kfree(strip_info->rx_buff);
	strip_info->rx_buff = NULL;
	kfree(strip_info->sx_buff);
	strip_info->sx_buff = NULL;
	kfree(strip_info->tx_buff);
	strip_info->tx_buff = NULL;

	del_timer(&strip_info->idle_timer);
	return 0;
}

/*
 * This routine is called by DDI when the
 * (dynamically assigned) device is registered
 */

static void strip_dev_setup(struct net_device *dev)
{
	/*
	 * Finish setting up the DEVICE info.
	 */

	SET_MODULE_OWNER(dev);

	dev->trans_start = 0;
	dev->last_rx = 0;
	dev->tx_queue_len = 30;	/* Drop after 30 frames queued */

	dev->flags = 0;
	dev->mtu = DEFAULT_STRIP_MTU;
	dev->type = ARPHRD_METRICOM;	/* dtang */
	dev->hard_header_len = sizeof(STRIP_Header);
	/*
	 *  dev->priv             Already holds a pointer to our struct strip
	 */

	*(MetricomAddress *) & dev->broadcast = broadcast_address;
	dev->dev_addr[0] = 0;
	dev->addr_len = sizeof(MetricomAddress);

	/*
	 * Pointers to interface service routines.
	 */

	dev->open = strip_open_low;
	dev->stop = strip_close_low;
	dev->hard_start_xmit = strip_xmit;
	dev->hard_header = strip_header;
	dev->rebuild_header = strip_rebuild_header;
	dev->set_mac_address = strip_set_mac_address;
	dev->get_stats = strip_get_stats;
	dev->change_mtu = strip_change_mtu;
}

/*
 * Free a STRIP channel.
 */

static void strip_free(struct strip *strip_info)
{
	spin_lock_bh(&strip_lock);
	list_del_rcu(&strip_info->list);
	spin_unlock_bh(&strip_lock);

	strip_info->magic = 0;

	free_netdev(strip_info->dev);
}


/*
 * Allocate a new free STRIP channel
 */
static struct strip *strip_alloc(void)
{
	struct list_head *n;
	struct net_device *dev;
	struct strip *strip_info;

	dev = alloc_netdev(sizeof(struct strip), "st%d",
			   strip_dev_setup);

	if (!dev)
		return NULL;	/* If no more memory, return */


	strip_info = dev->priv;
	strip_info->dev = dev;

	strip_info->magic = STRIP_MAGIC;
	strip_info->tty = NULL;

	strip_info->gratuitous_arp = jiffies + LongTime;
	strip_info->arp_interval = 0;
	init_timer(&strip_info->idle_timer);
	strip_info->idle_timer.data = (long) dev;
	strip_info->idle_timer.function = strip_IdleTask;


	spin_lock_bh(&strip_lock);
 rescan:
	/*
	 * Search the list to find where to put our new entry
	 * (and in the process decide what channel number it is
	 * going to be)
	 */
	list_for_each(n, &strip_list) {
		struct strip *s = hlist_entry(n, struct strip, list);

		if (s->dev->base_addr == dev->base_addr) {
			++dev->base_addr;
			goto rescan;
		}
	}

	sprintf(dev->name, "st%ld", dev->base_addr);

	list_add_tail_rcu(&strip_info->list, &strip_list);
	spin_unlock_bh(&strip_lock);

	return strip_info;
}

/*
 * Open the high-level part of the STRIP channel.
 * This function is called by the TTY module when the
 * STRIP line discipline is called for.  Because we are
 * sure the tty line exists, we only have to link it to
 * a free STRIP channel...
 */

static int strip_open(struct tty_struct *tty)
{
	struct strip *strip_info = (struct strip *) tty->disc_data;

	/*
	 * First make sure we're not already connected.
	 */

	if (strip_info && strip_info->magic == STRIP_MAGIC)
		return -EEXIST;

	/*
	 * OK.  Find a free STRIP channel to use.
	 */
	if ((strip_info = strip_alloc()) == NULL)
		return -ENFILE;

	/*
	 * Register our newly created device so it can be ifconfig'd
	 * strip_dev_init() will be called as a side-effect
	 */

	if (register_netdev(strip_info->dev) != 0) {
		printk(KERN_ERR "strip: register_netdev() failed.\n");
		strip_free(strip_info);
		return -ENFILE;
	}

	strip_info->tty = tty;
	tty->disc_data = strip_info;
	tty->receive_room = 65536;

	if (tty->driver->flush_buffer)
		tty->driver->flush_buffer(tty);

	/*
	 * Restore default settings
	 */

	strip_info->dev->type = ARPHRD_METRICOM;	/* dtang */

	/*
	 * Set tty options
	 */

	tty->termios->c_iflag |= IGNBRK | IGNPAR;	/* Ignore breaks and parity errors. */
	tty->termios->c_cflag |= CLOCAL;	/* Ignore modem control signals. */
	tty->termios->c_cflag &= ~HUPCL;	/* Don't close on hup */

	printk(KERN_INFO "STRIP: device \"%s\" activated\n",
	       strip_info->dev->name);

	/*
	 * Done.  We have linked the TTY line to a channel.
	 */
	return (strip_info->dev->base_addr);
}

/*
 * Close down a STRIP channel.
 * This means flushing out any pending queues, and then restoring the
 * TTY line discipline to what it was before it got hooked to STRIP
 * (which usually is TTY again).
 */

static void strip_close(struct tty_struct *tty)
{
	struct strip *strip_info = (struct strip *) tty->disc_data;

	/*
	 * First make sure we're connected.
	 */

	if (!strip_info || strip_info->magic != STRIP_MAGIC)
		return;

	unregister_netdev(strip_info->dev);

	tty->disc_data = NULL;
	strip_info->tty = NULL;
	printk(KERN_INFO "STRIP: device \"%s\" closed down\n",
	       strip_info->dev->name);
	strip_free(strip_info);
	tty->disc_data = NULL;
}


/************************************************************************/
/* Perform I/O control calls on an active STRIP channel.		*/

static int strip_ioctl(struct tty_struct *tty, struct file *file,
		       unsigned int cmd, unsigned long arg)
{
	struct strip *strip_info = (struct strip *) tty->disc_data;

	/*
	 * First make sure we're connected.
	 */

	if (!strip_info || strip_info->magic != STRIP_MAGIC)
		return -EINVAL;

	switch (cmd) {
	case SIOCGIFNAME:
		if(copy_to_user((void __user *) arg, strip_info->dev->name, strlen(strip_info->dev->name) + 1))
			return -EFAULT;
		break;
	case SIOCSIFHWADDR:
	{
		MetricomAddress addr;
		//printk(KERN_INFO "%s: SIOCSIFHWADDR\n", strip_info->dev->name);
		if(copy_from_user(&addr, (void __user *) arg, sizeof(MetricomAddress)))
			return -EFAULT;
		return set_mac_address(strip_info, &addr);
	}
	/*
	 * Allow stty to read, but not set, the serial port
	 */

	case TCGETS:
	case TCGETA:
		return n_tty_ioctl(tty, file, cmd, arg);
		break;
	default:
		return -ENOIOCTLCMD;
		break;
	}
	return 0;
}


/************************************************************************/
/* Initialization							*/

static struct tty_ldisc strip_ldisc = {
	.magic = TTY_LDISC_MAGIC,
	.name = "strip",
	.owner = THIS_MODULE,
	.open = strip_open,
	.close = strip_close,
	.ioctl = strip_ioctl,
	.receive_buf = strip_receive_buf,
	.write_wakeup = strip_write_some_more,
};

/*
 * Initialize the STRIP driver.
 * This routine is called at boot time, to bootstrap the multi-channel
 * STRIP driver
 */

static char signon[] __initdata =
    KERN_INFO "STRIP: Version %s (unlimited channels)\n";

static int __init strip_init_driver(void)
{
	int status;

	printk(signon, StripVersion);

	
	/*
	 * Fill in our line protocol discipline, and register it
	 */
	if ((status = tty_register_ldisc(N_STRIP, &strip_ldisc)))
		printk(KERN_ERR "STRIP: can't register line discipline (err = %d)\n",
		       status);

	/*
	 * Register the status file with /proc
	 */
	proc_net_fops_create("strip", S_IFREG | S_IRUGO, &strip_seq_fops);

	return status;
}

module_init(strip_init_driver);

static const char signoff[] __exitdata =
    KERN_INFO "STRIP: Module Unloaded\n";

static void __exit strip_exit_driver(void)
{
	int i;
	struct list_head *p,*n;

	/* module ref count rules assure that all entries are unregistered */
	list_for_each_safe(p, n, &strip_list) {
		struct strip *s = list_entry(p, struct strip, list);
		strip_free(s);
	}

	/* Unregister with the /proc/net file here. */
	proc_net_remove("strip");

	if ((i = tty_unregister_ldisc(N_STRIP)))
		printk(KERN_ERR "STRIP: can't unregister line discipline (err = %d)\n", i);

	printk(signoff);
}

module_exit(strip_exit_driver);

MODULE_AUTHOR("Stuart Cheshire <cheshire@cs.stanford.edu>");
MODULE_DESCRIPTION("Starmode Radio IP (STRIP) Device Driver");
MODULE_LICENSE("Dual BSD/GPL");

MODULE_SUPPORTED_DEVICE("Starmode Radio IP (STRIP) modem");
