/*
 * 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/config.h>
#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>


/************************************************************************/
/* 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 */
} FirmwareLevel;

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;

	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);
			return 1;
		}
	}
	return 0;
}

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 termios 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);
	}
	if (r)
		kfree(r);
	if (s)
		kfree(s);
	if (t)
		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 = dev->priv;
	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);

	if (orbuff)
		kfree(orbuff);
	if (osbuff)
		kfree(osbuff);
	if (otbuff)
		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 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) {
		u32 brd = 0;
		struct in_device *in_dev;

		rcu_read_lock();
		in_dev = __in_dev_get(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;
	u32 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(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 = (struct strip *) (dev->priv);

	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 (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 = (struct strip *) (dev->priv);
	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", (struct strip *)(dev->priv), 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							*/

static int strip_receive_room(struct tty_struct *tty)
{
	return 0x10000;		/* We can handle an infinite amount of data. :-) */
}

/*
 * 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->mac.raw = skb->data;

		/* 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 = (struct strip *) (dev->priv);
	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)
{
	static struct net_device_stats stats;
	struct strip *strip_info = (struct strip *) (dev->priv);

	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 = (struct strip *) (dev->priv);

	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 = (struct strip *) (dev->priv);

	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.
	 */
	if (strip_info->rx_buff) {
		kfree(strip_info->rx_buff);
		strip_info->rx_buff = NULL;
	}
	if (strip_info->sx_buff) {
		kfree(strip_info->sx_buff);
		strip_info->sx_buff = NULL;
	}
	if (strip_info->tx_buff) {
		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;
	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,
	.receive_room = strip_receive_room,
	.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_register_ldisc(N_STRIP, NULL)))
		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");
