http://gimel.esc.cam.ac.uk/james/rpld/src/rpld-1.7.tar.gz
authorMichael Brown <mcb30@dolphin.home>
Mon, 10 Mar 2008 23:56:41 +0000 (23:56 +0000)
committerMichael Brown <mcb30@dolphin.home>
Mon, 10 Mar 2008 23:56:41 +0000 (23:56 +0000)
25 files changed:
INSTALL
Makefile
README
ana.c
client.c
config.c
doc/rpld.8
kernel/README [new file with mode: 0644]
kernel/linux.2.2.llc.patch [new file with mode: 0644]
linux-nit.c [new file with mode: 0644]
linux-old-nit.c [moved from linux-ps.c with 64% similarity]
linux-ps.h [deleted file]
llc-linux.c [new file with mode: 0644]
llc-nit.c [new file with mode: 0644]
llc.c [deleted file]
llc.h
nit.h [new file with mode: 0644]
project.h
protocol.c
protocol.c.orig [deleted file]
prototypes.h
rpl.c
rpld.c
rpld.c.orig [deleted file]
rpld.man

diff --git a/INSTALL b/INSTALL
index e39ccd1..fad0eb9 100644 (file)
--- a/INSTALL
+++ b/INSTALL
@@ -12,10 +12,23 @@ Compilation:
        Linux 2.0.x (*)
        Linux 2.1.x (*)
        Linux 2.2.x
+       Linux 2.3.x
+       Linux 2.4.0-prex
 
 (*)    You will get a console message saying "can't find module net-pf-17"
        which you can ignore.
 
+       rpld ships by default with a resonably efficent driver for 2.2 and
+       above. It also comes with old drivers for 2.0 and 2.1, and a driver
+       for kernels with native llc support. The non native drivers consist
+       of a nit (which listens for packets on the network) and llc-nit.c
+       which implements an LLC 802.2 layer. If you want to change from the
+       default, you need to edit the makefile an recompile.
+       
+       A native llc support patche for linux 2.2 kernels can be found
+       in kernel, for 2.3 and 2.4 use the linux-sna package available
+       from www.linux-sna.org.
+
        To compile rpld, you MUST DO "make depend" and then "make".
        To compile the utilities/patches/fixes for the ever burgeoning list of
        network cards type "make nics", you will need a recent version of the
@@ -28,4 +41,11 @@ Installation:
 
        run rpld somewhere in your init scripts.
 
+Trouble shooting:
+       
+       You can try running ana (in this directory). The synopis is
+       ana [interface name]
+       even if the output makes no sense to you it will help people
+       who understand more to quickly find the problem.
+
 
index c4b0c90..7ef6d91 100644 (file)
--- a/Makefile
+++ b/Makefile
 #  */
 
 #
-# $Id: Makefile,v 1.19 2000/07/29 23:25:59 root Exp root $
+# $Id: Makefile,v 1.23 2000/09/26 03:46:20 root Exp $
 #
 # $Log: Makefile,v $
-# Revision 1.19  2000/07/29 23:25:59  root
+# Revision 1.23  2000/09/26 03:46:20  root
 # #
 #
-# Revision 1.18  2000/07/23 19:07:49  root
+# Revision 1.22  2000/09/26 02:32:47  root
 # #
 #
-# Revision 1.17  2000/07/17 11:59:46  root
+# Revision 1.21  2000/09/26 02:31:39  root
 # #
 #
-# Revision 1.16  2000/07/17 10:43:34  root
+# Revision 1.20  2000/09/26 01:03:22  root
 # #
 #
-# Revision 1.15  2000/07/16 14:22:07  root
-# #
-#
-# Revision 1.14  2000/07/16 14:05:30  root
-# #
-#
-# Revision 1.13  2000/07/16 13:18:12  root
-# #
-#
-# Revision 1.1  2000/07/16 13:16:42  root
-# #
-#
-# Revision 1.14  1999/09/15 13:46:58  root
-# #
-#
-# Revision 1.13  1999/09/15 00:36:29  root
-# #
-#
-# Revision 1.12  1999/09/14 21:45:17  root
-# #
-#
-# Revision 1.11  1999/09/14 21:38:41  root
-# #
-#
-# Revision 1.10  1999/09/14 21:36:03  root
-# #
-#
-# Revision 1.9  1999/09/14 21:32:13  root
-# #
 #
-# Revision 1.8  1999/09/14 21:26:00  root
-# #
-#
-# Revision 1.7  1999/09/14 21:16:25  root
-# #
-#
-# Revision 1.6  1999/09/14 21:14:38  root
-# #
-#
-# Revision 1.5  1999/09/14 21:13:14  root
-# #
-#
-# Revision 1.4  1999/09/14 17:18:27  root
-# #
+
 #
-# Revision 1.3  1999/09/14 17:12:39  root
-# #
+
+# Important you need to choose a driver for rpld
+# there are two sorts of driver for rpld:
+#   nit: easy to write and dirty
+#        these drivers send a copy of
+#        every (LLC) packet transmitted
+#        or received to rpld, and greatly
+#        increase CPU load.
 #
-# Revision 1.2  1999/09/14 16:17:16  root
-# #
+#   llc: these are for systems which have
+#        native LLC support, the kernel
+#        takes care of the LLC layer and
+#        passes decoded data down to rpld  
 #
-# Revision 1.1  1999/09/13 12:36:20  root
-# #
+
+# Available NIT drivers: choose from
+#  linux-nit.c:          For modern kerenels, attempts to persuade the
+#                kernel to send rpld only 802.2 frames thus 
+#                greatly reducing system load. However some
+#                bad voodo magic is required to get it to
+#                send properly.
 #
+#  linux-old-nit.c:  For older kernels and those with problems.
+#                    this is the simplest possible form of driver
+#                    it receives every frame tranmitted of received
+#                    from the host and places a large extra load on
+#                    busy machines.
+#                    
+#  llc-nit.c implements the LLC 802.2 layer ontop of the raw packet (nit)
+#  layer and is needed in all cases
 #
+#  Newer driver
+NIT=linux-nit.c
+#  Older driver
+#NIT=linux-old-nit.c
 
-#
+DRIVER=llc-nit.c ${NIT}
+
+# Native LLC drivers, to use these you require a kernel with native
+# llc support, for linux 2.2 you can use the patches in ./kernel
+# for linux 2.3 and 2.4 you can use the LLC stack that comes as 
+# part of the linux-sna package available at www.linux-sna.org 
+# 
+# To use this driver comment out the DRIVER line above and
+# uncomment this one
+# DRIVER=llc-linux.c
 
 DEFINES=
 
@@ -99,8 +91,9 @@ DESTDIR=/usr
 # Stuff
 CC      = gcc
 INCLUDES = 
-CFLAGS   = -O  ${INCLUDES} ${DEFINES}
-LIBS     =
+OPT     = -O
+CFLAGS   = ${OPT} ${INCLUDES} ${DEFINES}
+LIBS     = 
 LDFLAGS  =
 
 # Where to find yacc and lex
@@ -112,7 +105,7 @@ INSTALL=install
 
 ################# NO USER SERVICABLE PARTS BELOW HERE
 
-VERSION=1.6
+VERSION=1.7
 
 COFLAGS = -l
 
@@ -123,9 +116,7 @@ include .depend
 do-it-all: all
        @echo " " Now type make install to install rpld
        @echo " " or make nics to assemble the adapter utilities
-#      @echo " " or make capture to capture RPL traffic
-#      @echo " " or make replay to analyse captured RPL traffic
-#      @echo " " or make realtime to capture and analyse RPL traffic
+       @echo " " or make realtime to capture and analyse RPL traffic
 
 else
 do-it-all: depend
@@ -153,10 +144,11 @@ MAN5=   ${MANROOT}5
 MAN5EXT=5
 MAN5SRC=man
 
-PROTOSRC = protocol.c linux-ps.c rpld.c util.c rpl.c llc.c client.c config.c
-HSRCS=rpl.h project.h rpl.h linux-ps.h llc.h client.h 
 
-CSRCS=${PROTOSRC} 
+PROTOSRC = protocol.c rpld.c util.c rpl.c client.c config.c 
+HSRCS=rpl.h project.h rpl.h llc.h client.h  nit.h
+
+CSRCS=${PROTOSRC} ${DRIVER}
 
 YSRCS=rpld_conf.y
 LSRCS=rpld_conf.lex
@@ -164,7 +156,7 @@ MANSRCS=rpld.man rpld.conf.man
 
 ALLSRCS=${CSRCS}
 
-RCSCFILES=${CSRCS} ${HSRCS}
+RCSCFILES=${CSRCS} ${HSRCS} linux-nit.c linux-old-nit.c llc-linux.c
 RCSFILES=${RCSCFILES} ${YSRCS} ${LSRCS} ${MANSRCS} ana.c
 
 
@@ -209,13 +201,13 @@ install-docs: doc
        ${INSTALL} -c -o ${MANOWN} -g ${MANGRP} -m ${MANMODE} rpld.${MAN8EXT} ${MAN8}/rpld.${MAN8EXT}
        ${INSTALL} -c -o ${MANOWN} -g ${MANGRP} -m ${MANMODE} rpld.conf.${MAN5EXT} ${MAN5}/rpld.conf.${MAN5EXT}
 
-#ana:ana.c
+ana:ana.c linux-old-nit.c
 
-#realtime: ana
-#      tcpdump -l -x -s 2048 ether[14]=0xfc and ether[15]=0xfc | ana
+realtime: ana
+       ./ana
 
-capture: 
-       tcpdump -x -s 2048 ether[14]=0xfc and ether[15]=0xfc -w capture.dat
+#capture: 
+#      tcpdump -x -s 2048 ether[14]=0xfc and ether[15]=0xfc -w capture.dat
 
 #replay: ana capture.dat
 #      tcpdump -x -r capture.dat | ana
@@ -240,7 +232,9 @@ clean: nodep
 
 proto: ${PROTOSRCS} ${HSRCS} ${LSRCS:%.lex=%.tab.h}
        echo -n > ${PROTOH}
-       for i in ${PROTOSRC}; do cproto -e -v $$i | grep -v inline >> ${PROTOH}  ; done
+       echo -n > ${PROTOH}.tmp
+       for i in ${PROTOSRC}; do cproto -e -v $$i | grep -v inline >> ${PROTOH}.tmp  ; done
+       /bin/mv -f ${PROTOH}.tmp ${PROTOH}
 
 
 
@@ -290,3 +284,4 @@ yguff:${YGUFF}
 
 config.o: rpld_conf.tab.h
 
+# DO NOT DELETE
diff --git a/README b/README
index 7849e65..5781f32 100644 (file)
--- a/README
+++ b/README
@@ -49,14 +49,11 @@ You can dump all RPL packets on your network using tcpdump:
   # tcpdump -x -s 2048 ether[14]=0xfc and ether[15]=0xfc
 
 Also included in the distribution is a program called ana, ana is a horrid
-piece of kludgey C code which will read the output of tcpdump and decode RPL
-packets. The Makefile has some targets which may be helpful. Type "make
-realtime" to capture and decode packets in real time (NB: a feature of ana is
-that the most recently received packet will not be printed until other packet
-arrives).  Alternatively you can do "make capture" and "make replay" to
-analyze packets off-line. We reverse engineered the protocol so it's very
-likely we've not implemented a whole bunch of stuff. If you have problems send
-us your capture.dat files.
+piece of kludgey C code which will try to parse RPL packets [it's not the
+same parser that rpld uses it's the one I wrote first]. We reverse engineered 
+the protocol so it's very likely we've not implemented a whole bunch of stuff. 
+If you have problems send us your capture files. Also you may want to enable
+promisc mode and or allmulti mode before running ana.
 
 The authors can be contacted at <james@fishsoup.dhs.org> and
                                 <chris@ex-parrot.com>
diff --git a/ana.c b/ana.c
index f23a2ca..9ffe224 100644 (file)
--- a/ana.c
+++ b/ana.c
@@ -1,10 +1,16 @@
 #include <stdio.h>
 #include <strings.h>
 
-static char *rcsid = "$Id: ana.c,v 1.3 2000/07/16 13:18:10 root Exp $";
+static char *rcsid = "$Id: ana.c,v 1.5 2000/09/26 03:48:23 root Exp $";
 
 /* 
  * $Log: ana.c,v $
+ * Revision 1.5  2000/09/26 03:48:23  root
+ * #
+ *
+ * Revision 1.4  2000/09/26 03:44:29  root
+ * #
+ *
  * Revision 1.3  2000/07/16 13:18:10  root
  * #
  *
@@ -25,63 +31,14 @@ static char *rcsid = "$Id: ana.c,v 1.3 2000/07/16 13:18:10 root Exp $";
  *
  */
 
+#include <sys/time.h>
+#include "nit.h"
 
+#define ETH_ALEN 6
 unsigned char pbuf[4096];
 int plen;
-char buf[1024];
-
-get_packet ()
-{
-  char *ptr, *pptr;
-
-  plen = 0;
-
-  while (!feof (stdin) && *buf == '\t')
-    {
-      fgets (buf, sizeof (buf) - 1, stdin);
-    }
-  while (!feof (stdin) && *buf != '\t')
-    {
-      buf[strlen (buf) - 1] = 0;
-      puts (buf);
-      fgets (buf, sizeof (buf) - 1, stdin);
-    }
-  if (feof (stdin))
-    return;
-
-  sscanf (buf, "%x", &plen);
-
-  pptr = pbuf;
-
-
-  while (!feof (stdin) && *buf == '\t')
-    {
-      ptr = buf;
-
-      while (!isxdigit (*ptr))
-        ptr++;
-      while (*ptr)
-        {
-          char hex[3];
-
-          bcopy (ptr, hex, 3);
-          hex[2] = 0;
-          ptr++;
-          ptr++;
-
-          sscanf (hex, "%x", pptr);
-          pptr++;
-
-          while (*ptr && !isxdigit (*ptr))
-            ptr++;
-        }
 
 
-      fgets (buf, sizeof (buf) - 1, stdin);
-    }
-
-}
-
 int
 pull_short (unsigned char *c)
 {
@@ -223,46 +180,85 @@ ana_frag (unsigned char *pp, int pl)
 
 
 
-main ()
+int
+main (int argc, char *argv[])
 {
   int i, s;
   char *pptr;
-  *buf = '\t';
+  struct nit *n;
+  struct timeval tv;
+
 
+  if (argc == 2)
+    {
+      n = nit_open (argv[1]);
+    }
+  else
+    {
+      n = nit_open (NULL);
+    }
+
+  if (!n)
+    {
+      printf ("Failed to open network device\n");
+    }
   while (!feof (stdin))
     {
-      get_packet ();
+      unsigned char from[ETH_ALEN];
 
-      pptr = pbuf;
-      pptr += 2;                /*Length */
-      plen -= 2;
+      plen = nit_recv (n, pbuf, sizeof (pbuf), from, NULL);
+      gettimeofday (&tv, NULL);
 
-      printf ("  Pack Type:");
-      switch (pull_short (pptr))
+      if (
+          (pbuf[0] == 0xfc) || (pbuf[1] == 0xfc) ||
+          (pbuf[0] == 0xf8) || (pbuf[1] == 0xf8) ||
+          (pbuf[0] == 0xf4) || (pbuf[1] == 0xf4))
         {
-        case 0x1:
-          printf (" FIND:");
-          break;
-        case 0x2:
-          printf (" FOUND:");
-          break;
-        case 0x10:
-          printf (" SEND.FILE.REQUEST:");
-          break;
-        case 0x20:
-          printf (" FILE.DATA.RESPONSE:");
-          break;
-        default:
-          printf (" 0x%04x ?:", pull_short (pptr));
-        }
-      printf (" Length=%d\n", plen);
-      pptr += 2;
-      plen -= 2;
-
-      s = ana_frag (pptr, plen);
 
-
-      printf ("\n\n");
+          printf ("%d.%06d  From %02x:%02x:%02x:%02x:%02x:%02x \n",
+                  (int) tv.tv_sec,
+                  (int) tv.tv_usec,
+                  from[0], from[1], from[2], from[3], from[4], from[5]);
+          printf (" Ssap %02x Dsap %02x Cmd %02x Length %d(%d)\n",
+                  pbuf[0],
+                  pbuf[1], pbuf[2], plen, ntohs (*(short *) &pbuf[3]));
+
+
+          pptr = pbuf;
+          pptr += 5;            /*Length */
+          plen -= 5;
+
+          printf ("  ");
+          dump_hex (pptr, plen);
+          printf ("\n");
+
+          printf ("  Pack Type:");
+          switch (pull_short (pptr))
+            {
+            case 0x1:
+              printf (" FIND:");
+              break;
+            case 0x2:
+              printf (" FOUND:");
+              break;
+            case 0x10:
+              printf (" SEND.FILE.REQUEST:");
+              break;
+            case 0x20:
+              printf (" FILE.DATA.RESPONSE:");
+              break;
+            default:
+              printf (" 0x%04x ?:", pull_short (pptr));
+            }
+          printf (" Length=%d\n", plen);
+          pptr += 2;
+          plen -= 2;
+
+          s = ana_frag (pptr, plen);
+
+
+          printf ("\n\n");
+        }
     }
 
   exit (0);
index b79d79e..9b56b4c 100644 (file)
--- a/client.c
+++ b/client.c
 
 
 static char rcsid[] =
-  "$Id: client.c,v 1.21 2000/07/29 23:25:58 root Exp root $";
+  "$Id: client.c,v 1.29 2000/09/26 04:06:07 root Exp root $";
 
 /*
  * $Log: client.c,v $
+ * Revision 1.29  2000/09/26 04:06:07  root
+ * #
+ *
+ * Revision 1.28  2000/09/26 03:48:23  root
+ * #
+ *
+ * Revision 1.27  2000/09/26 02:32:46  root
+ * #
+ *
+ * Revision 1.26  2000/09/26 02:31:38  root
+ * #
+ *
+ * Revision 1.25  2000/09/26 01:41:22  root
+ * #
+ *
+ * Revision 1.24  2000/09/26 01:41:20  root
+ * #
+ *
+ * Revision 1.23  2000/09/26 01:39:17  root
+ * #
+ *
+ * Revision 1.22  2000/09/26 01:03:19  root
+ * #
+ *
  * Revision 1.21  2000/07/29 23:25:58  root
  * #
  *
@@ -371,7 +395,7 @@ clients_check_status ()
 
 }
 
-client_dispatch (struct nit *n)
+client_dispatch (struct llcdrv *lld)
 {
   struct client *c = clients;
 
@@ -379,7 +403,7 @@ client_dispatch (struct nit *n)
     {
       if ((c->state == ST_FILEDATA) && (!c->nospew))
         {
-          file_data_frame (n, c);
+          file_data_frame (lld, c);
         }
       c = c->next;
 
index cb9965c..526bbd4 100644 (file)
--- a/config.c
+++ b/config.c
 
 
 static char rcsid[] =
-  "$Id: config.c,v 1.14 2000/07/29 23:25:58 root Exp root $";
+  "$Id: config.c,v 1.22 2000/09/26 04:06:07 root Exp root $";
 
 /*
  * $Log: config.c,v $
+ * Revision 1.22  2000/09/26 04:06:07  root
+ * #
+ *
+ * Revision 1.21  2000/09/26 03:48:23  root
+ * #
+ *
+ * Revision 1.20  2000/09/26 03:44:29  root
+ * #
+ *
+ * Revision 1.19  2000/09/26 02:32:46  root
+ * #
+ *
+ * Revision 1.18  2000/09/26 01:42:24  root
+ * #
+ *
+ * Revision 1.17  2000/09/26 01:41:22  root
+ * #
+ *
+ * Revision 1.16  2000/09/26 01:41:08  root
+ * #
+ *
+ * Revision 1.15  2000/09/26 01:39:17  root
+ * #
+ *
  * Revision 1.14  2000/07/29 23:25:58  root
  * #
  *
@@ -142,15 +166,15 @@ do_linux_kernel (struct client *c, struct clfile *f)
 
 
 void
-parse_config ()
+parse_config (char *filename)
 {
   FILE *file;
 
-  file = fopen (CONFIG_FILE, "r");
+  file = fopen (filename, "r");
 
   if (!file)
     {
-      fprintf (stderr, "Cannot open config file %s\n", CONFIG_FILE);
+      fprintf (stderr, "Cannot open config file %s\n", filename);
       exit (1);
     }
 
index 4daeb14..adfae69 100644 (file)
@@ -5,11 +5,32 @@ NAME
      rpld - an RPL/RIPL remote boot server
 
 SYNOPSIS
-     rpld
+     rpld [-f] [-C configfile] [-i iface] [-s sap] [-h]
 
 WARRANTY
      rpld DOES NOT come with ANY WARRANTY, NOT even an IMPLIED WARRANTY.
 
+OPTIONS
+     -f              this flag causes rpld to run in the foreground, and not
+                     to fork and run as a daemon.
+
+     -C configfile   causes rpld to read configfile rather than the default
+                     configuration file.
+
+     -i iface        causes rpld to bind to network interface iface rather
+                     than the default. Because of the limitations of the LLC
+                     802.2 protocol rpld can only bind to one interface.
+
+     -s sap          changes the SAP number that rpld binds to. The IBM stan-
+                     dard says this should be 0xf8 but most network cards seem
+                     to use 0xfc and some even use 0xf4. You can specify the
+                     sap as either a hex number with a leading 0x or a decimal
+                     one. Beware of specificing a SAP number which is used for
+                     system control packets on a machine with native llc sup-
+                     port.
+
+     -h              causes rpld to print a brief help message.
+
 DESCRIPTION
      rpld will net-boot IBM style RPL boot ROMs. Communication between the
      client and the server is done in LLC-1 ui/C frames with the source and
@@ -35,11 +56,13 @@ DESCRIPTION
 
 BUGS
        Solenopsis invicta Burens
-       rpld (probably) doesn't support the new bzImage format correctly.
+       rpld doesn't support the new bzImage format correctly.
        rpld doesn't reload the first 512 octets of Linux kernels automatical-
        ly.
        There is no way to make rpld re-read its configuration file.
        When concurrently serving multiple clients rpld will choose the pacing
+
+
        value of the slowest one.
        Partial ethernet addresses should be specified in bits not bytes.
        rpld needs to meet more network adapters.
@@ -47,6 +70,8 @@ BUGS
 NOTES
      IBM is a trademark of IBM Corp.
 
+     and the makefile in the distribution for more information.
+
 FILES
      /usr/sbin/rpld
      /etc/rpld.conf
@@ -62,4 +87,4 @@ AUTHORS AND COPYRIGHT
      (c) 1999,2000 James McKenzie, and Christopher Lightfoot. All rights re-
      served.
 
- Linux                           Jun 16, 2000                                1
+ Linux                           Jun 16, 2000                                2
diff --git a/kernel/README b/kernel/README
new file mode 100644 (file)
index 0000000..b5fb2f5
--- /dev/null
@@ -0,0 +1,12 @@
+NO WARRANTY NO WARRANTY NO WARRANTY
+This may trash your disk, blow up your toaster and kill your dog.
+
+The patch in this directory adds native support for llc 802.2 sockets
+into linux 2.2 kernels. It's cobbled together from an old linux-sna
+release and much debugging. The patch changes the size of struct skb
+so if for whatever reason (eg you use pcmcia) your network drivers
+are not in the kernel tree, your machine will crash badly if you
+forget to recompile them after applying this patch.
+
+This isn't really meant to be supported code, but hey you can
+reach me on <james@fishsoup.dhs.org>
diff --git a/kernel/linux.2.2.llc.patch b/kernel/linux.2.2.llc.patch
new file mode 100644 (file)
index 0000000..b05ef3c
--- /dev/null
@@ -0,0 +1,14128 @@
+# 
+# /*************************************************
+# *     rpld - an IBM style RIPL server            *
+# *************************************************/
+# 
+# /* Copyright (c) 1999,2000, James McKenzie.
+#  *                      All rights reserved
+#  * Copyright (c) 1998,2000, Christopher Lightfoot.
+#  *                      All rights reserved
+#  *
+#  * By using this file, you agree to the terms and conditions set
+#  * forth in the LICENCE file which can be found at the top level of
+#  * the rpld distribution.
+#  *
+#  * IBM is a trademark of IBM corp.
+#  *
+#  */
+#                          NO WARRANTY
+# 
+# BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+# FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+# OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+# PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+# OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+# TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+# PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+# REPAIR OR CORRECTION.
+#
+# this patch is hacked together from an old release of the linux-sna
+# patches and some extensive bugfixes by me.
+#
+
+diff -uNr linux/Documentation/networking/llc.txt linux-llc/Documentation/networking/llc.txt
+--- linux/Documentation/networking/llc.txt     Thu Jan  1 01:00:00 1970
++++ linux-llc/Documentation/networking/llc.txt Mon Sep 25 06:47:02 2000
+@@ -0,0 +1,80 @@
++llc.txt: Documentation for the Linux IEEE 802.2 and Linux LLC UI layers.
++         Written by: Jay Schulist <jschlst@turbolinux.com>
++
++LLC User Interface Notes:
++
++LLC Class 1 socket types:
++      - SOCK_DGRAM
++LLC Class 2 socket types:
++      - SOCK_STREAM
++
++Besides normal data transfer, the user can send a test request 
++from either socket type. just set the sllc_test to 1 in the sockaddr_llc
++structure.
++
++struct sockaddr_llc {
++      sa_family_t     sllc_family;
++
++      unsigned char   sllc_dmac[14];
++      unsigned char   sllc_dsap;
++      unsigned char   sllc_smac[14];
++      unsigned char   sllc_ssap;
++      unsigned char   sllc_test;
++};
++
++
++IEEE 802.2 Layer Notes:
++Initialization/LLC load:
++1). LLC scans for LLC interfaces in the IFF_UP state. For each interface
++    found a independent Station Component (SC) is created. *
++2). We register a device notifier to alert us of devices going up and/or
++    down. We then either add or delete a SC for the appropriate device. *
++
++* Required for protocol compliance.
++
++Operation:
++
++LLC commands are executed by the llc_queue_cmd() call unless otherwise
++noted. The following commands are available depending on the llc class type.
++([] = only available by this command)
++
++Class One:
++- LLC_STATE_SAP_ACTIVATION_REQUEST    [register_8022_client()]
++- LLC_STATE_SAP_DEACTIVATION_REQUEST  [unregister_8022_client()]
++
++- LLC_STATE_XID_REQUEST
++
++- LLC_STATE_TEST_REQUEST              [dl->datalink_header()]
++                                      [dev_queue_xmit() or llc_queue_xmit()]
++- LLC_STATE_UNITDATA_REQUEST          [dl->datalink_header()]
++                                      [dev_queue_xmit() or llc_queue_xmit()]
++
++Class Two:
++- LLC_STATE_CONNECT_REQUEST           [llc_connect()]
++- LLC_STATE_CONNECT_RESPONSE          [llc_connect()]
++- LLC_STATE_DISCONNECT_REQUEST                [llc_disconnect()]
++- LLC_STATE_DISCONNECT_RESPONSE               [llc_disconnect()]
++- LLC_STATE_RESET_REQUEST             [llc_reset()]
++- LLC_STATE_RESET_RESPONSE            [llc_reset()]
++
++- LLC_STATE_DATA_REQUEST              [dl->datalink_header()]
++                                      [llc_queue_xmit()]
++
++Check linux/net/llc/af_llc.c for a great reference on how to connect your
++networking layer into the llc layer, it is great fun and worth a try.
++
++
++- Transmit and Receive Processor paths
++
++Receive:
++- llc_rcv
++  - llc_find_client
++  - llc_decode_pdu
++  - llc_demux_pdu
++    - llc_process_pdu_type2
++
++Transmit
++- llc_datalink_header
++  - llc_demux_cmd
++    - llc_process_cmd_type2
++      - llc_build_pdu
+diff -uNr linux/MAINTAINERS linux-llc/MAINTAINERS
+--- linux/MAINTAINERS  Fri Jun 23 10:57:58 2000
++++ linux-llc/MAINTAINERS      Mon Sep 25 06:47:02 2000
+@@ -533,6 +533,13 @@
+ W:    http://linux.msede.com/lvm
+ S:    Maintained
++LLC NETWORK LAYER
++P:    Jay Schulist
++M:    jschlst@turbolinux.com
++W:    http://www.linux-sna.org
++L:    linux-sna@tubrolinux.com
++S:    Maintained
++
+ MAESTRO PCI SOUND DRIVER
+ P:    Zach Brown
+ M:    zab@redhat.com
+diff -uNr linux/include/linux/llc.h linux-llc/include/linux/llc.h
+--- linux/include/linux/llc.h  Thu Jan  1 01:00:00 1970
++++ linux-llc/include/linux/llc.h      Mon Sep 25 06:47:02 2000
+@@ -0,0 +1,109 @@
++/*
++ * IEEE 802.2 for Linux, data structures and indicators.
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License
++ * as published by the Free Software Foundation; either version
++ * 2 of the License, or (at your option) any later version.
++ *
++ * None of the authors or maintainers or their employers admit
++ * liability nor provide warranty for any of this software.
++ * This material is provided "as is" and at no charge.
++ */
++
++#ifndef __LINUX_LLC_H
++#define __LINUX_LLC_H
++
++#ifdef __KERNEL__
++
++struct llc_msg_head
++{
++      struct llc_msg *next;
++      struct llc_msg *prev;
++      unsigned long qlen;
++};
++
++struct llc_msg
++{
++      struct llc_msg *next;
++      struct llc_msg *prev;
++
++      struct llc_msg_head *list;
++      struct llc_pinfo *llc;
++
++      unsigned char cmd;
++      unsigned char rsp;
++
++      struct sk_buff *skb;
++};
++#endif
++
++struct sockaddr_llc {
++        sa_family_t     sllc_family;
++        unsigned char   sllc_dmac[14];
++        unsigned char   sllc_dsap;
++        unsigned char   sllc_smac[14];
++        unsigned char   sllc_ssap;
++      unsigned char   sllc_test;
++};
++
++#define LLC_IOCTL_RETRY                       0x01    /* Max retrans attempts. */
++#define LLC_IOCTL_SIZE                        0x02    /* Max PDU size. */
++#define LLC_IOCTL_WINDOW              0x03    /* Max PDU window size. */
++#define LLC_IOCTL_ACK_TIMER_EXPIRE    0x04
++#define LLC_IOCTL_P_TIMER_EXPIRE      0x05
++#define LLC_IOCTL_REJ_TIMER_EXPIRE    0x06
++#define LLC_IOCTL_BUSY_TIMER_EXPIRE   0x07
++#define LLC_IOCTL_SSAP                        0x08
++#define LLC_IOCTL_CLASS                       0x09
++
++#define LLC_MAX_RETRY                 100
++#define       LLC_MAX_SIZE                    sizeof(int)
++#define LLC_MAX_WINDOW                        50
++#define LLC_MAX_ACK_TIMER_EXPIRE      60 * HZ
++#define LLC_MAX_P_TIMER_EXPIRE                60 * HZ
++#define LLC_MAX_REJ_TIMER_EXPIRE      60 * HZ
++#define LLC_MAX_BUSY_TIMER_EXPIRE     60 * HZ
++
++struct llc_data
++{
++      unsigned char   ssap;
++};
++
++/* LLC socket operations. */
++#define LLC_REG_SAP_CLIENT    0xAA            /* Reg. LLC UI client w/ LLC */
++#define LLC_SET_SAP_CLASS     0xBB            /* Set class (LLC1 or LLC2) */
++#define LLC_QUE_MSG           0xCC            /* UI SAP Event Indication. */
++
++/* LLC types. */
++#define LLC_SAP_CLASS_1               0x01
++#define LLC_SAP_CLASS_2         0x02
++
++/* Linux LLC header sizes. */
++#define LLC_TYPE1_SIZE          3       /* 3 bytes. */
++#define LLC_TYPE2_SIZE          4       /* 4 bytes. */
++
++/* LLC SAP types. */
++#define LLC_SAP_NULL  0x00            /* NULL SAP.                    */
++#define LLC_SAP_LLC   0x02            /* LLC Sublayer Managment.      */
++#define LLC_SAP_SNA   0x04            /* SNA Path Control.            */
++#define LLC_SAP_PNM   0x0E            /* Proway Network Managment.    */      
++#define LLC_SAP_IP    0x06            /* TCP/IP.                      */
++#define LLC_SAP_BSPAN 0x42            /* Bridge Spanning Tree Proto   */
++#define LLC_SAP_MMS   0x4E            /* Manufacturing Message Srv.   */
++#define LLC_SAP_8208  0x7E            /* ISO 8208                     */
++#define LLC_SAP_3COM  0x80            /* 3COM.                        */
++#define LLC_SAP_PRO   0x8E            /* Proway Active Station List   */
++#define LLC_SAP_SNAP  0xAA            /* SNAP.                        */
++#define LLC_SAP_BANYAN        0xBC            /* Banyan.                      */
++#define LLC_SAP_IPX   0xE0            /* IPX/SPX.                     */
++#define LLC_SAP_NETBIOS       0xF0            /* NetBIOS.                     */
++#define LLC_SAP_LANMGR        0xF4            /* LanManager.                  */
++#define LLC_SAP_IMPL  0xF8            /* IMPL                         */
++#define LLC_SAP_DISC  0xFC            /* Discovery                    */
++#define LLC_SAP_OSI   0xFE            /* OSI Network Layers.          */
++#define LLC_SAP_LAR   0xDC            /* LAN Address Resolution       */
++#define LLC_SAP_RM    0xD4            /* Resource Management          */
++#define LLC_SAP_GLOBAL        0xFF            /* Global SAP.                  */
++
++#endif /* __LINUX_LLC_H */
+diff -uNr linux/include/linux/skbuff.h linux-llc/include/linux/skbuff.h
+--- linux/include/linux/skbuff.h       Fri Jun 23 11:12:47 2000
++++ linux-llc/include/linux/skbuff.h   Mon Sep 25 07:16:54 2000
+@@ -36,6 +36,7 @@
+                                          for using debugging */
+ };
++
+ struct sk_buff {
+       struct sk_buff  * next;                 /* Next buffer in list                          */
+       struct sk_buff  * prev;                 /* Previous buffer in list                      */
+@@ -66,7 +67,14 @@
+               unsigned char   *raw;
+       } nh;
+   
+-      /* Link layer header */
++      /* Link layer header, ie. 802.2 */
++        union
++        {
++                struct llchdr   *llc;
++                unsigned char   *raw;
++        } link;
++
++      /* Mac/Hardware header. */
+       union 
+       {       
+               struct ethhdr   *ethernet;
+@@ -76,6 +84,10 @@
+       struct  dst_entry *dst;
+       char            cb[48];  
++
++      /* LLC layer. */
++      unsigned int llc_cmd;
++      struct packet_type *pt;
+       unsigned int    len;                    /* Length of actual data                        */
+       unsigned int    csum;                   /* Checksum                                     */
+diff -uNr linux/include/linux/socket.h linux-llc/include/linux/socket.h
+--- linux/include/linux/socket.h       Fri Jun 23 11:12:46 2000
++++ linux-llc/include/linux/socket.h   Mon Sep 25 06:47:02 2000
+@@ -155,6 +155,7 @@
+ #define AF_ATMSVC     20      /* ATM SVCs                     */
+ #define AF_SNA                22      /* Linux SNA Project (nutters!) */
+ #define AF_IRDA               23      /* IRDA sockets                 */
++#define AF_LLC          30      /* LLC Class One and Two.       */
+ #define AF_MAX                32      /* For now.. */
+ /* Protocol families, same as address families. */
+@@ -183,6 +184,7 @@
+ #define PF_ATMSVC     AF_ATMSVC
+ #define PF_SNA                AF_SNA
+ #define PF_IRDA               AF_IRDA
++#define PF_LLC                AF_LLC
+ #define PF_MAX                AF_MAX
+@@ -235,6 +237,7 @@
+ #define SOL_ATM               264     /* ATM layer (cell level) */
+ #define SOL_AAL               265     /* ATM Adaption Layer (packet level) */
+ #define SOL_IRDA        266
++#define SOL_LLC               277     /* LLC User Interface SAPs */
+ /* IPX options */
+ #define IPX_TYPE      1
+diff -uNr linux/include/linux/sysctl.h linux-llc/include/linux/sysctl.h
+--- linux/include/linux/sysctl.h       Wed Jun  7 22:26:44 2000
++++ linux-llc/include/linux/sysctl.h   Mon Sep 25 06:50:30 2000
+@@ -143,7 +143,8 @@
+       NET_X25=13,
+       NET_TR=14,
+       NET_DECNET=15,
+-      NET_ECONET=16
++      NET_ECONET=16,
++      NET_LLC=17
+ };
+ /* /proc/sys/bus/isa */
+@@ -171,7 +172,17 @@
+ /* /proc/sys/net/ethernet */
+-/* /proc/sys/net/802 */
++/* /proc/sys/net/llc */
++enum {
++        NET_LLC_MAX_RETRY=1,
++        NET_LLC_MAX_SIZE=2,
++        NET_LLC_MAX_WINDOW=3,
++        NET_LLC_ACK_TIMER_EXPIRE=4,
++        NET_LLC_P_TIMER_EXPIRE=5,
++        NET_LLC_REJ_TIMER_EXPIRE=6,
++        NET_LLC_BUSY_TIMER_EXPIRE=7,
++      NET_LLC_DEBUG=8
++};
+ /* /proc/sys/net/unix */
+diff -uNr linux/include/net/datalink.h linux-llc/include/net/datalink.h
+--- linux/include/net/datalink.h       Tue Oct 24 13:26:07 1995
++++ linux-llc/include/net/datalink.h   Mon Sep 25 07:21:02 2000
+@@ -2,15 +2,24 @@
+ #define _NET_INET_DATALINK_H_
+ struct datalink_proto {
+-      unsigned short  type_len;
+-      unsigned char   type[8];
+-      const char      *string_name;
+-      unsigned short  header_length;
+-      int     (*rcvfunc)(struct sk_buff *, struct device *, 
+-                              struct packet_type *);
+-      void    (*datalink_header)(struct datalink_proto *, struct sk_buff *,
+-                                      unsigned char *);
+-      struct datalink_proto   *next;
++        unsigned short  type_len;
++        unsigned char   type[8];
++        const char      *string_name;
++
++        union {
++                struct llc_pinfo *llc;
++        } ll_pinfo;
++
++      struct llc_sc_info *llc_sc;
++      struct sock *sock;
++
++        unsigned short  header_length;
++
++        int     (*rcvfunc)(struct sk_buff *, struct device *,
++                                struct packet_type *);
++        void    (*datalink_header)(struct datalink_proto *, struct sk_buff *,
++                                        unsigned char *);
++        struct datalink_proto   *next;
+ };
+ #endif
+diff -uNr linux/include/net/llc.h linux-llc/include/net/llc.h
+--- linux/include/net/llc.h    Wed Dec 10 17:45:16 1997
++++ linux-llc/include/net/llc.h        Mon Sep 25 07:25:33 2000
+@@ -1,135 +1,1538 @@
+ #include <linux/skbuff.h>
+-#define LLC_MODULE
+-
+-typedef struct llc_struct llc;
+-typedef struct llc_struct *llcptr;
+-
+ /*
+- *    LLC private data area structure.
++ * IEEE 802.2 for Linux, data structures and indicators.
+  */
+-struct llc_struct
+-{ 
+-      char eye[4];                    /* To recognize llc area in dump */
+-      int retry_count;                /* LLC link state variables */
+-      unsigned char name[9];          /* name of this llc instance */
+-      unsigned char s_flag;
+-      unsigned char p_flag;
+-      unsigned char f_flag;
+-      unsigned char data_flag;
+-      unsigned char cause_flag;
+-      unsigned char vs;               /* Send state variable */
+-      unsigned char vr;               /* Receive state variable */
+-      unsigned char remote_busy;
+-      unsigned char state;            /* Current state of type2 llc procedure */
+-      int n1;                         /* Maximum number of bytes in I pdu 7.8.2 */
+-      int n2;                         /* Naximum number of retransmissions 7.8.2 */
+-      unsigned char k;                /* Transmit window size 7.8.4, tw in IBM doc*/ 
+-      unsigned char rw;               /* Receive window size */
+-      struct 
+-      {                               
+-              /*
+-               *      FRMR_RSP info field structure: 5.4.2.3.5 p55
+-               */
+-
+-              unsigned char cntl1;
+-              unsigned char cntl2;
+-              unsigned char vs;
+-              unsigned char vr_cr;
+-              unsigned char xxyz;
+-      } frmr_info_fld;
+-
+-      /*
+-       *      Timers in 7.8.1 page 78 
+-       */
+-
+-#define P_TIMER         0
+-#define REJ_TIMER       1
+-#define ACK_TIMER       2 
+-#define BUSY_TIMER      3
+-      unsigned long timer_expire_time[4];     
+-      unsigned char timer_state[4];   /* The state of each timer */
+-#define TIMER_IDLE      0
+-#define TIMER_RUNNING   1
+-#define TIMER_EXPIRED   2
+-      unsigned long timer_interval[4]; 
+-      struct timer_list tl[4];
+-
+-      /* 
+-       *      Client entry point, called by the LLC.
+-       */
+-       
+-      void    (*llc_event)(struct llc_struct *);
+-      
+-      /*
+-       *      Mux and Demux variables
+-       */
+-       
+-      char * client_data;             /* Pointer to clients context */
+-      unsigned char local_sap;
+-      unsigned char remote_sap ;
+-      char remote_mac[MAX_ADDR_LEN];  /* MAC address of remote session partner */ 
+-      struct device *dev;             /* Device we are attached to */
+-                   
+-      unsigned char llc_mode;         /* See doc 7.1 on p70 */
+-#define MODE_ADM 1
+-#define MODE_ABM 2
+-
+-      int llc_callbacks;              /* Pending callbacks */
+-#define LLC_CONN_INDICATION   1       /* We have to ensure the names don't */
+-#define LLC_CONN_CONFIRM      2       /* mix up with the 802 state table */
+-#define LLC_DATA_INDIC                4
+-#define LLC_DISC_INDICATION   8
+-#define LLC_RESET_INDIC_LOC   16
+-#define LLC_RESET_INDIC_REM   32
+-#define LLC_RST_CONFIRM               64
+-#define LLC_FRMR_RECV         128
+-#define LLC_FRMR_SENT         256
+-#define LLC_REMOTE_BUSY               512
+-#define LLC_REMOTE_NOTBUSY    1024
+-#define LLC_TEST_INDICATION   2048
+-#define LLC_XID_INDICATION    4096
+-#define LLC_UI_DATA           8192
+-
+-      struct sk_buff *inc_skb;        /* Saved data buffer for indications */
+-      
+-      struct sk_buff_head rtq;        /* Retransmit queue */
+-      struct sk_buff_head atq;        /* Await transit queue */
+-      
+-      unsigned char xid_count;
++#ifndef __NET_LLC_H
++#define __NET_LLC_H
++
++#include <linux/skbuff.h>
++#include <linux/llc.h>
++
++#define LLC_SC_SAP            0x12    /* Linux Specific SC SAP. */
++
++#define LLC_MSG_QUEUE_SIZE    20
++
++/* LLC timer indicators. */
++#define LLC_P_TIMER           0
++#define LLC_REJ_TIMER         1
++#define LLC_ACK_TIMER         2
++#define LLC_BUSY_TIMER        3
++#define LLC_TIMER_IDLE        0
++#define LLC_TIMER_RUNNING     1
++#define LLC_TIMER_EXPIRED     2
++
++/* LLC operational modes. */
++#define LLC_MODE_ADM          1
++#define LLC_MODE_ABM          2
++
++typedef struct
++{
++      unsigned pdu_type:1;    /* PDU type field. */
++      unsigned ns:7;          /* Send sequence #, network-order. */
++      unsigned pf:1;          /* Poll/Final command/response bit. */
++      unsigned nr:7;          /* Receive sequence #, network-order. */
++} llc_ictrl;
++
++typedef struct
++{
++      unsigned pdu_type:2;    /* PDU type field. */
++      unsigned cmd:2;         /* Supervisory command. */
++      unsigned __pad:4;       /* Zero'd out padding. */
++      unsigned pf:1;          /* Poll/Final command/response bit. */
++      unsigned nr:7;          /* Receive sequence #, network-order. */
++} llc_sctrl;
++
++typedef struct
++{
++      unsigned pdu_type:2;    /* PDU type field. */
++      unsigned mod1:2;        /* Modifer bits, field one. */
++      unsigned pf:1;          /* Poll/Final command/response bit. */
++      unsigned mod2:3;        /* Modifier bits, field two. */
++} llc_uctrl;
++
++typedef struct
++{
++      unsigned f1:1;
++      unsigned f2:1;
++      unsigned f3:6;
++} llc_bits;
++
++/* LLC data link header. */
++typedef struct
++{
++      __u8    dsap:8; /* Destination Service Access Point. */
++      __u8    ssap:8; /* Source Service Access Point. */
++
++      union {
++              llc_bits bits __attribute__ ((packed));
++              /* I PDU control bit fields. */
++              llc_ictrl ictrl __attribute__ ((packed));
++              /* S PDU control bit fields. */
++              llc_sctrl sctrl __attribute__ ((packed));
++              /* U PDU control bit fields. */
++              llc_uctrl uctrl __attribute__ ((packed));
++              __u8 ctrl __attribute__ ((packed));
++      } ctrl;
++} llchdr;
++
++typedef struct
++{
++      __u16   ctrl;
++      unsigned __pad1:1;
++      unsigned vs:7;
++      unsigned cr:1;
++      unsigned vr:7;
++      unsigned wxyz:4;
++      unsigned v:4;
++} llc_frmr;
++
++typedef struct
++{
++      __u8    format;         /* 10000001, IEEE Basic Format. */
++      unsigned class:5;       /* LLC Type/Class. */
++      unsigned __pad:4;
++      unsigned window:7;      /* Recieve window size (k). */
++} llc_xid;
++
++typedef struct
++{
++      unsigned vs:7;
++      unsigned vr:7;
++} llc_seq;
++
++/* LLC SC information */
++struct llc_sc_info
++{
++      struct llc_sc_info *next;
++      struct llc_sc_info *prev;
++
++      struct datalink_proto *llc_sap_list;
++      struct device *dev;
++
++      int state;
++};
++
++/* LLC SAP information per socket. */
++struct llc_pinfo 
++{
++      int event;              /* Current event on the link. */
++      int state;              /* Current state of the link. LLC 1 */
++      int state2;             /* Current state of the link. LLC 2 */
++
++      int build;              /* Current PDU to be built. */
++      __u8 build_pf:1;        /* PF to use when Building PDU. */
++      int build_dsap;         /* DSAP to use when Building PDU. */
++
++      __u8 dmac[14];          /* XXX??? Destination Mac. may not stay */
++
++      __u8 dsap;
++      __u8 ssap;
++
++      int class;              /* LLC communication class. */
+-      struct llc_struct *nextllc;     /* ptr to next llc struct in proto chain */
++      int s_flag;             /* Supervisory function bit. */
++      int p_flag;             /* Poll function bit. */
++      int f_flag;             /* Final function bit. */
++      int data_flag;          /* Number of toss'd PDUs due to a local busy. */
++      int remote_busy;        /* Indicates if the DSAP is busy. */
++
++      llc_seq seq;            /* Tx/Rx sequence numbers */
++
++#ifdef NOT
++      __u8 vs;                /* Send state variable. (Tx sequence #) */
++      __u8 vr;                /* Receive state variable. (Rx sequence #) */
++#endif
++
++      int retry_count;        /* Number of retransmits/retrys. */
++      int window_count;       /* Number of outstanding I PDUs. */
++      int xid_r_count;        /* Number of XID responses. */
++
++      int max_retry;          /* Maximm number of transmissions, N2. */
++      int max_size;           /* Maximum number of octets in an I PDU, N1. */
++      int max_window;         /* Maximum number of outstanding I PDUs, k. */
++
++      struct sk_buff_head rx_queue;
++
++      int tx_queue_depth;
++      struct sk_buff_head tx_queue;
++
++      int retransmitting;
++      int retx_queue_depth;
++      struct sk_buff_head retx_queue;
++
++      struct datalink_proto *dl;
++
++      int (*rcvfunc)(int rsp, struct sk_buff *);
++
++      int ack_expire;                 /* Ack time-out value. */
++      struct timer_list ack_timer;    /* Acknowledgment timer. */
++      int p_expire;                   /* P time-out value. */
++      struct timer_list p_timer;      /* P-bit timer. */
++      int rej_expire;                 /* Reject time-out value. */
++      struct timer_list rej_timer;    /* Reject timer. */
++      int busy_expire;                /* Busy time-out value. */
++      struct timer_list busy_timer;   /* Busy timer. */
+ };
+-#define ADD_TO_RTQ(skb) skb_queue_tail(&lp->rtq,skb)
+-#define ADD_TO_ATQ(skb) skb_queue_tail(&lp->atq,skb)
++#define LLC_PDU_RSP           0x01
++#define LLC_P_FLAG            1
++#define LLC_F_FLAG            1
++#define LLC_X_FLAG            0
++
++#define LLC_XID_SIZE          3
++#define LLC_FRMR_SIZE         5
++
++/* LLC timer time-outs, these are linux specific (not to spec). */
++#define LLC_ACK_TIMER_EXPIRE  3 * HZ;
++#define LLC_P_TIMER_EXPIRE    3 * HZ;
++#define LLC_REJ_TIMER_EXPIRE  10 * HZ;
++#define LLC_BUSY_TIMER_EXPIRE 15 * HZ;
++
++/* LLC maximum counts, these are linux specific (not to spec). */
++#define LLC_RETRY             10
++#define LLC_SIZE              65535   /* Should hold us for a while ;) */
++#define LLC_WINDOW            15
++
++/* LLC PDU types. */
++#define LLC_I_CMD                     0x00
++#define LLC_I_RSP                     0x01
++#define LLC_RR_CMD                    0x02
++#define LLC_RR_RSP                    0x03
++#define LLC_ACK_CMD                   LLC_RR_CMD
++#define LLC_ACK_RSP                   LLC_RR_RSP
++#define LLC_RNR_CMD                   0x04
++#define LLC_RNR_RSP                   0x05
++#define LLC_REJ_CMD                   0x06
++#define LLC_REJ_RSP                   0x07
++#define LLC_FRMR_RSP                  0x08
++#define LLC_UI_CMD                    0x09
++#define LLC_TEST_CMD                  0x0A
++#define LLC_TEST_RSP                  0x0B
++#define LLC_DISC_CMD                  0x0C
++#define LLC_UA_RSP                    0x0D
++#define LLC_DM_RSP                    0x0E
++#define LLC_XID_CMD                   0x0F
++#define LLC_XID_RSP                   0x10
++#define LLC_SABME_CMD                 0x11
++
++/* LLC Control Byte Assignments. */
++#define LLC_CTRL_I_CMD                        0x00
++#define LLC_CTRL_I_RSP                        LLC_CTRL_I_CMD
++#define LLC_CTRL_RR_CMD                       0x01
++#define LLC_CTRL_RR_RSP                       LLC_CTRL_RR_CMD
++#define LLC_CTRL_RNR_CMD              0x05
++#define LLC_CTRL_RNR_RSP              LLC_CTRL_RNR_CMD
++#define LLC_CTRL_REJ_CMD              0x09
++#define LLC_CTRL_REJ_RSP              LLC_CTRL_REJ_CMD
++#define LLC_CTRL_DISC_CMD             0x43
++#define LLC_CTRL_SABME_CMD            0x7F
++#define LLC_CTRL_UA_RSP                       0x63
++#define LLC_CTRL_DM_RSP                       0x0F
++#define LLC_CTRL_FRMR_RSP             0x87
++#define LLC_CTRL_UI_CMD                       0x03
++#define LLC_CTRL_XID_CMD              0xBF
++#define LLC_CTRL_XID_RSP              LLC_CTRL_XID_CMD
++#define LLC_CTRL_TEST_CMD             0xF3            /* Was 0xE3 */
++#define LLC_CTRL_TEST_RSP             LLC_CTRL_TEST_CMD
++
++/* LLC connection states, Type 1 and Type 2. */
++#define LLC_STATE_DISCONNECTED                0x00
++#define LLC_STATE_DISCONNECTING               0x01
++#define LLC_STATE_RESETTING           0x02
++#define LLC_STATE_FRMR_TX             0x03
++#define LLC_STATE_FRMR_RX             0x04
++#define LLC_STATE_CONNECTING          0x05
++#define LLC_STATE_CONNECTED           0x06
++#define LLC_STATE_CHKPOINT            0x07
++#define LLC_STATE_LOCAL_BUSY          0x08    /* User and Buffer. */
++#define LLC_STATE_REMOTE_BUSY         0x09
++#define LLC_STATE_REJECTION           0x0A
++#define LLC_STATE_CLEARING            0x0B
++#define LLC_STATE_DYNWINDOW           0x0C
++
++/* Message/Command action words. */
++#define ENABLE_W_DUP_ADDR_CHK LLC_STATE_ENABLE_W_DUPLICATE_ADDRESS_CHK
++#define ENABLE                        LLC_STATE_ENABLE_WOUT_DUPLICATE_ADDRESS_CHK
++
++#define LLC_R_XID_C_INDICATION                        0x01
++#define LLC_R_XID_R_INDICATION                        0x02
++#define LLC_R_TEST_C_INDICATION                       0x03
++#define LLC_R_TEST_R_INDICATION                       0x04
++
++
++
++#define LLC_STATE_SEND_XID_R_DATA             0x9F    /* Linux specific. */
++
++/* Linux LLC states for the Linux LLC state machine. 
++ * - IEEE 802.2-1989 state naratives are provided for the enjoyment
++ *   of the reader.
++ */
++
++/* Linux LLC Type 1 states. */
++#define LLC_STATE_DOWN                        0x90    /* DOWN_STATE. The station
++                                               * component is powered off,
++                                               * not initialized, and/or
++                                               * disabled from operating in
++                                               * the local area network.
++                                               */
++#define LLC_STATE_DUPLICATE_ADDRESS_CHK       0x91    /* DUPLICATE_ADDRESS_CHECK_STATE
++                                               * The station component is in
++                                               * the process of checking for
++                                               * duplicate MAC addresses on
++                                               * the LAN. The main purpose of
++                                               * this state shall be to allow
++                                               * the LLC station component to
++                                               * verify that this station's
++                                               * MAC address is unique on the
++                                               * LAN. The station component
++                                               * shall send XID command PDUs
++                                               * with identical MAC DA and SA
++                                               * addresses, and shall wait for
++                                               * a possible XID Response PDU
++                                               * indicating the existance of
++                                               * other stations with identical
++                                               * MAC link addresses.
++                                               */
++#define LLC_STATE_UP                  0x92    /* UP_STATE. The station 
++                                               * component is enabled, powered
++                                               * on, initialized, and 
++                                               * operating in the local area
++                                               * network. The LLC shall allow
++                                               * SAPs to exchange LLC PDUs on
++                                               * the medium.
++                                               */
++#define LLC_STATE_ENABLE_W_DUPLICATE_ADDRESS_CHK 0x93
++                                              /* ENABLE_WITH_DUPLICATE_
++                                               * ADDRESS_CHECK. Station
++                                               * component user has 
++                                               * initialized/enabled the
++                                               * station equipment, and has
++                                               * requested that the LLC check
++                                               * for MAC service access point
++                                               * address duplications before
++                                               * participating in data link
++                                               * communications.
++                                               */
++#define LLC_STATE_ENABLE_WOUT_DUPLICATE_ADDRESS_CHK 0x94
++                                              /* ENABLE_WITHOUT_DUPLICATE_
++                                               * ADDRESS_CHECK. Station
++                                               * component user has
++                                               * initialized/enabled the
++                                               * station equipment, but
++                                               * duplicate MAC service access
++                                               * point address checking by the
++                                               * LLC is not supported/desired.
++                                               */
++#define LLC_STATE_ACK_TIMER_EXPIRED_AND_RETRY_COUNT_OK 0x95
++                                              /* ACK_TIMER_EXPIRED_AND_RETRY_
++                                               * COUNT<MAXIMUM_RETRY.
++                                               * Acknowledgment timer has
++                                               * expired and retry count is
++                                               * less than maximum retry 
++                                               * limit.
++                                               */
++#define LLC_STATE_ACK_TIMER_EXPIRED_AND_RETRY_COUNT_MAX 0x96
++                                              /* ACK_TIMER_EXPIRED_AND_RETRY_
++                                               * COUNT=MAXIMUM_RETRY.
++                                               * Acknowledgment timer has
++                                               * expired and retry count is
++                                               * equal to the maximum retry
++                                               * limit.
++                                               */
++#define LLC_STATE_RECEIVE_NULL_DSAP_XID_C 0x97        /* RECEIVE_NULL_DSAP_XID_C. An
++                                               * XID command PDU with the
++                                               * NULL DSAP address has been
++                                               * received.
++                                               */
++#define LLC_STATE_RECEIVE_NULL_DSAP_XID_R 0x98
++                                              /* RECEIVE_NULL_DSAP_XID_R_AND_
++                                               * XID_R_COUNT=0. A single XID
++                                               * response PDU with the null
++                                               * DSAP address has been 
++                                               * received.
++                                               */
++#define LLC_STATE_RECEIVE_NULL_DSAP_XID_R_AND_XID_R_CNT_1 0x99
++                                              /* RECEIVE_NULL_DSAP_XID_R_AND_
++                                               * XID_R_COUNT=1. A second XID
++                                               * response PDU with the null
++                                               * DSAP address have been
++                                               * received.
++                                               */
++#define LLC_STATE_RECEIVE_NULL_DSAP_TEST_C 0x9A       /* RECEIVE_NULL_DSAP_TEST_C. A
++                                               * TEST command PDU with the
++                                               * null DSAP address has been
++                                               * received.
++                                               */
++#define LLC_STATE_DISABLE_REQUEST     0x9B    /* DISABLE_REQUEST. Station user
++                                               * has requested that the
++                                               * equipment be disabled from
++                                               * operating on the medium.
++                                               */
++#define LLC_STATE_XID_R_COUNT_0               0x9F    /* XID_R_COUNT:=0. Initialize
++                                               * the XID response PDU counter.
++                                               */
++#define LLC_STATE_XID_R_COUNT_PLUS_1  0xA0    /* XID_R_COUNT:=XID_R_COUNT+1.
++                                               * Increment the XID response
++                                               * PDU counter.
++                                               */
++#define LLC_STATE_SEND_NULL_DSAP_XID_C        0xA1    /* SEND_NULL_DSAP_XID_C. The LLC
++                                               * shall send an XID command PDU
++                                               * with null SSAP and null DSAP
++                                               * addresses and with identical
++                                               * MAC DA and SA addresses.
++                                               */
++#define LLC_STATE_SEND_XID_R          0xA2    /* SEND_XID_R. The LLC shall 
++                                               * send an XID response PDU,
++                                               * using the SSAP address of the
++                                               * XID command PDU as the DSAP
++                                               * address of the response PDU,
++                                               * and using a null SSAP 
++                                               * address.
++                                               */
++#define LLC_STATE_SEND_TEST_R         0xA3    /* SEND_TEST_R. The LLC shall
++                                               * send a TEST response PDU,
++                                               * using the SSAP address of the
++                                               * TEST command PDU as the DSAP
++                                               * address of the response PDU,
++                                               * and using a null SSAP 
++                                               * address.
++                                               */
++#define LLC_STATE_RPT_STATION_UP      0xA4    /* REPORT_STATUS(STATION_UP).
++                                               * LLC entity is now 
++                                               * operational.
++                                               */
++#define LLC_STATE_RPT_STATION_DOWN    0xA5    /* REPORT_STATUS(STATION_DOWN).
++                                               * The LLC entity is now
++                                               * non-operational.
++                                               */
++#define LLC_STATE_RPT_DUPLOCATE_ADDRESS_FOUND 0xA6
++                                              /* REPORT_STATUS(DUPLICATE_
++                                               * ADDRESS_FOUNT). LLC entity 
++                                               * has detected another LLC
++                                               * entity on the LAN with a MAC
++                                               * service access point address
++                                               * identical to its own.
++                                               */
++#define LLC_STATE_INACTIVE            0xA7    /* INACTIVE_STATE. LLC SAP
++                                               * component is not active,
++                                               * functioning, or operational.
++                                               * No PDUs are accepted and/or
++                                               * sent.
++                                               */
++#define LLC_STATE_ACTIVE              0xA8    /* ACTIVE_STATE. LLC SAP
++                                               * component is active, 
++                                               * functioning, and operational.
++                                               * PDUs are received and sent.
++                                               */
++#define LLC_STATE_SAP_ACTIVATION_REQUEST 0xA9 /* SAP_ACTIVATION_REQUEST. The
++                                               * SAP user has requested that
++                                               * the particular LLC SAP
++                                               * component be activated and
++                                               * begin logical data link
++                                               * operation of the Type 1
++                                               * services.
++                                               */
++#define LLC_STATE_SAP_DEACTIVATION_REQUEST 0xAA       /* SAP_DEACTIVATION_REQUEST. The
++                                               * SAP user has requested that
++                                               * the particular LLC SAP
++                                               * component be deactivated and
++                                               * no longer allow to operate on
++                                               * the logical data link.
++                                               */
++#define LLC_STATE_XID_REQUEST         0xAB    /* XID_REQUEST. The SAP user has
++                                               * requested that the LLC SAP
++                                               * component send an XID
++                                               * command PDU to one or more
++                                               * remote SAPs.
++                                               */
++#define LLC_STATE_TEST_REQUEST                0xAC    /* TEST_REQUEST. The SAP user 
++                                               * has requested that the LLC
++                                               * SAP component send a TEST
++                                               * command PDU to one or more
++                                               * remote SAPs.
++                                               */
++#define LLC_STATE_RECEIVE_UI          0xAD    /* RECEIVE_UI. The local SAP
++                                               * component has received a UI
++                                               * PDU from a remote SAP.
++                                               */
++#define LLC_STATE_UNITDATA_REQUEST    0xAE    /* UNITDATA_REQUEST. The SAP
++                                               * user has requested that a
++                                               * data unit be passed to a
++                                               * remote LLC SAP, via a UI PDU.
++                                               */
++#define LLC_STATE_RECEIVE_XID_C               0xAF    /* RECEIVE_XID_C. The local SAP
++                                               * component has received an XID
++                                               * command PDU from a remote 
++                                               * SAP.
++                                               */
++#define LLC_STATE_RECEIVE_XID_R               0xB0    /* RECEIVE_XID_R. The local SAP
++                                               * component has received an XID
++                                               * response PDU from a remote 
++                                               * SAP.
++                                               */
++#define LLC_STATE_RECEIVE_TEST_C      0xB1    /* RECEIVE_TEST_C. The local SAP
++                                               * component has received a TEST
++                                               * command PDU from the remote
++                                               * SAP.
++                                               */
++#define LLC_STATE_RECEIVE_TEST_R      0xB2    /* RECEIVE_TEST_R. The local SAP
++                                               * component has received a TEST
++                                               * response PDU from the remote
++                                               * SAP.
++                                               */
++#define LLC_STATE_UNITDATA_INDICATION 0xB3    /* UNITDATA_INDICATION. LLC SAP
++                                               * component has received a UI
++                                               * PDU from a remote SAP. The
++                                               * service data unit is given to
++                                               * the SAP user.
++                                               */
++#define LLC_STATE_SEND_UI             0xB4    /* SEND_UI. A UI PDU is sent to
++                                               * one or more remote SAPs in
++                                               * response to a user request to
++                                               * send a service data unit.
++                                               */
++#define LLC_STATE_SEND_XID_C          0xB5    /* SEND_XID_C. LLC SAP component
++                                               * shall send an XID command PDU
++                                               * to remote SAPs in response to
++                                               * a SAP user request to 
++                                               * identify other SAPs.
++                                               */
++#define LLC_STATE_SEND_TEST_C         0xB7    /* SEND_TEST_C. LLC SAP 
++                                               * component shall send a TEST
++                                               * command PDU in response to
++                                               * a SAP user request to test
++                                               * a remote SAP.
++                                               */
++#define LLC_STATE_RPT_SAP_ACTIVE      0xB9    /* REPORT_STATUS(SAP_ACTIVE).
++                                               * The SAP_ACTIVATION_REQUEST
++                                               * has been successfully
++                                               * processed and the component
++                                               * is now operational.
++                                               */
++#define LLC_STATE_RPT_SAP_INACTIVE    0xBA    /* REPORT_STATUS(SAP_INACTIVE).
++                                               * The SAP_DEACTIVATION_REQUEST
++                                               * has been successfully
++                                               * processed and the component
++                                               * is now deactivated.
++                                               */
++#define LLC_STATE_XID_INDICATION      0xBB    /* XID_INDICATION. LLC SAP
++                                               * component has received an XID
++                                               * response PDU from a remote
++                                               * SAP. An indication of this
++                                               * event is passed to the SAP
++                                               * user, and may also return the
++                                               * XID information field.
++                                               */
++#define LLC_STATE_TEST_INDICATION     0xBC    /* TEST_INDICATION. LLC SAP
++                                               * component has received a
++                                               * TEST response PDU from a
++                                               * remote SAP. An indication of
++                                               * this event is passed to the
++                                               * SAP user, and may also return
++                                               * the TEST information field.
++                                               */
++
++/* Linux LLC Type 2 states. */
++#define LLC_STATE_ADM                 0x00    /* ADM. The connection component
++                                               * is in the asynchronous
++                                               * disconnected mode. It can
++                                               * accept an SABME PDU from a
++                                               * remote LLC SSAP or, at the
++                                               * request of the service access
++                                               * point user, can initiate an
++                                               * SABME PDU transmission to a
++                                               * remote LLC DSAP, to establish
++                                               * a data link connection. It
++                                               * also responds to a DISC
++                                               * command PDU and to any 
++                                               * command PDU with the P bit
++                                               * set to "1".
++                                               */
++#define LLC_STATE_SETUP                       0x01    /* SETUP. The connection 
++                                               * component has transmitted an
++                                               * SABME command PDU to a remote
++                                               * LLC DSAP and is waiting for
++                                               * a reply.
++                                               */
++#define LLC_STATE_NORMAL              0x02    /* NORMAL. A data link 
++                                               * connection exists between the
++                                               * local LLC service access 
++                                               * point and the remote LLC
++                                               * service access point. Sending
++                                               * and reception of information
++                                               * and supervisory PDUs can be
++                                               * performed.
++                                               */
++#define LLC_STATE_BUSY                        0x03    /* BUSY. A data link connection
++                                               * exists between the local LLC
++                                               * service access point and the
++                                               * remote LLC service access
++                                               * point. I PDUs may be sent.
++                                               * Local conditions make it 
++                                               * likely that the information
++                                               * field of received I PDUs will
++                                               * be ignored. Supervisory PDUs
++                                               * may be both sent and received
++                                               */
++#define LLC_STATE_REJECT              0x04    /* REJECT. A data link 
++                                               * connection exists between the
++                                               * local LLC service access 
++                                               * point and the remote LLC
++                                               * service point The remote
++                                               * connection component has
++                                               * requested that the remote
++                                               * connection component resend
++                                               * a specified I PDU that the
++                                               * local connection component
++                                               * has detected as being out
++                                               * of sequence. Both I PDUs and
++                                               * supervisory PDUs may be
++                                               * sent and received.
++                                               */
++#define LLC_STATE_AWAIT                       0x05    /* AWAIT. A data link connection
++                                               * exists between the local LLC
++                                               * service access point and the
++                                               * remote LLC service access
++                                               * point. The local LLC is
++                                               * performing a timer recovery
++                                               * operation and has sent a
++                                               * command PDU with the P bit
++                                               * set to "1", and is awaiting
++                                               * an acknowledgment from the
++                                               * remote LLC. I PDUs may be
++                                               * received but not sent.
++                                               * Supervisory PDUs may be both
++                                               * sent and received.
++                                               */
++#define LLC_STATE_AWAIT_BUSY          0x06    /* AWAIT_BUSY. A data link
++                                               * connection exists between the
++                                               * local LLC service access
++                                               * point and the remote LLC
++                                               * service access point. The 
++                                               * local LLC is performing a
++                                               * timer recovery operation and
++                                               * has sent a command PDU with 
++                                               * the P bit set to "1", and is
++                                               * awaiting an acknowledgment
++                                               * from the remote LLC. I PDUs
++                                               * may not be sent. Local
++                                               * conditions make it likely
++                                               * that the information field of
++                                               * received I PDUs will be 
++                                               * ignored. Supervisory PDUs may
++                                               * be both sent and received.
++                                               */
++#define LLC_STATE_AWAIT_REJECT                0x07    /* AWAIT_REJECT. A data link
++                                               * connection exists between the
++                                               * local LLC service access
++                                               * point and the remote LLC
++                                               * service access point. The
++                                               * local connection component
++                                               * has requested that the remote
++                                               * connection component
++                                               * re-transmit a specified I PDU
++                                               * that the local connection
++                                               * component has detected as
++                                               * being out of sequence. Before
++                                               * the local LLC entered this
++                                               * state it was performing a
++                                               * timer recovery operation and
++                                               * had sent a command PDU with
++                                               * the P bit set to "1", and is
++                                               * still awaiting an 
++                                               * acknowledgment from the 
++                                               * remote LLC. I PDUs may be
++                                               * received but not transmitted.
++                                               * Supervisory PDUs may be both
++                                               * transmitted and received.
++                                               */
++#define LLC_STATE_D_CONN              0x08    /* D_CONN. At the request of the
++                                               * service access point user, 
++                                               * the local LLC has sent a DISC
++                                               * command PDU to the remote LLC
++                                               * DSAP and it waiting for a
++                                               * reply.
++                                               */
++#define LLC_STATE_RESET                       0x09    /* RESET. As a result of a 
++                                               * service access point user
++                                               * request or the receipt of a
++                                               * FRMR response PDU, the local
++                                               * connection component has sent
++                                               * an SABME command PDU to the
++                                               * remote LLC DSAP to reset the
++                                               * data link connection and is
++                                               * waiting for a reply.
++                                               */
++#define LLC_STATE_ERROR                       0x0A    /* ERROR. The local connection
++                                               * component has detected an
++                                               * error in a received PDU and
++                                               * has sent a FRMR response PDU.
++                                               * It is waiting for a reply
++                                               * from the remote connection
++                                               * component.
++                                               */
++#define LLC_STATE_CONN                        0x0B    /* CONN. The local connection
++                                               * component has received an
++                                               * SABME PDU from a remote LLC
++                                               * SSAP, and it is waiting for
++                                               * the local user to accept or
++                                               * refuse the connection.
++                                               */
++#define LLC_STATE_RESET_CHECK         0x0C    /* RESET_CHECK. The local
++                                               * connection component is 
++                                               * waiting for the local user to
++                                               * accept or refuse a remote
++                                               * reset request.
++                                               */
++#define LLC_STATE_RESET_WAIT          0x0D    /* RESET_WAIT. The local 
++                                               * connection component is 
++                                               * waiting for the local user to
++                                               * indicate a RESET_REQUEST or a
++                                               * DISCONNECT_REQUEST.
++                                               */
++#define LLC_STATE_CONNECT_REQUEST     0x10    /* CONNECT_REQUEST. The user has
++                                               * requested that a data link
++                                               * connection be established 
++                                               * with a remote LLC DSAP.
++                                               */
++#define LLC_STATE_CONNECT_RESPONSE    0x11    /* CONNECT_RESPONSE. The user
++                                               * has accepted the data link
++                                               * connection.
++                                               */
++#define LLC_STATE_DATA_REQUEST                0x12    /* DATA_REQUEST. The user has
++                                               * requested that a data unit
++                                               * be sent to the remote LLC
++                                               * DSAP.
++                                               */
++#define LLC_STATE_DISCONNECT_REQUEST  0x13    /* DISCONNECT_REQUEST. The user
++                                               * has requested that the data
++                                               * link connection with the
++                                               * remote LLC DSAP be 
++                                               * terminated.
++                                               */
++#define LLC_STATE_RESET_REQUEST               0x14    /* RESET_REQUEST. The user has
++                                               * requested that the data link
++                                               * connection with the remote
++                                               * LLC DSAP be reset.
++                                               */
++#define LLC_STATE_RESET_RESPONSE      0x15    /* RESET_RESPONSE. The user has
++                                               * accepted the reset of the 
++                                               * data link connection.
++                                               */
++#define LLC_STATE_LOCAL_BUSY_DETECTED 0x16    /* LOCAL_BUSY_DETECTED. The
++                                               * local station has entered a
++                                               * busy condition and may not
++                                               * be able to accept I PDUs from
++                                               * the remote LLC SSAP.
++                                               */
++#define LLC_STATE_LOCAL_BUSY_CLEARED  0x17    /* LOCAL_BUSY_CLEARED. The local
++                                               * station busy condition has
++                                               * ended and the station can
++                                               * accept I PDUs from the remote
++                                               * LLC SSAP.
++                                               */
++#define LLC_STATE_RECEIVE_BAD_PDU     0x18    /* RECEIVE_BAD_PDU. The remote
++                                               * SSAP has sent to the local
++                                               * DSAP a command or response
++                                               * PDU which is not implemented,
++                                               * or has an information field
++                                               * when not permitted, or is an
++                                               * I PDU with an information
++                                               * field length greater than can
++                                               * be accommodated by the local
++                                               * LLC.
++                                               */
++#define LLC_STATE_RECEIVE_DISC_CMD    0x19    /* RECEIVE_DISC_CMD(P=X). The
++                                               * remote SSAP has sent a DISC
++                                               * command PDU with the P bit
++                                               * set to "X" addressed to the
++                                               * local DSAP.
++                                               */
++#define LLC_STATE_RECEIVE_DM_RSP      0x1A    /* RECEIVE_DM_RSP(F=X). The
++                                               * remote SSAP has sent a DM
++                                               * response PDU with the F bit
++                                               * set to "X" addressed to the
++                                               * local DSAP.
++                                               */
++#define LLC_STATE_RECEIVE_FRMR_RSP    0x1B    /* RECEIVE_FRMR_RSP(F=X). The
++                                               * remote SSAP has sent a
++                                               * FRMR response PDU with the F
++                                               * bit set to "X" addressed to
++                                               * the local DSAP.
++                                               */
++#define LLC_STATE_RECEIVE_I_CMD               0x1C    /* RECEIVE_I_CMD(P=X). The 
++                                               * remote SSAP has sent a I
++                                               * command PDU with the P bit 
++                                               * set to "X" addressed to the
++                                               * local DSAP. Both the N(R) and
++                                               * N(S) fields are valid and the
++                                               * N(S) value is the expected
++                                               * sequence number.
++                                               */
++#define LLC_STATE_RECEIVE_I_CMD_W_UNEXPECTED_SEQ 0x1D
++                                              /* RECEIVE_I_CMD(P=X)_WITH_
++                                               * UNEXPECTED_N(S). The remote
++                                               * SSAP has sent an I command
++                                               * PDU with the P bit set to
++                                               * "X" addressed to the local
++                                               * DSAP. The N(S) field of the
++                                               * command does not contain the
++                                               * expected sequence number but
++                                               * is within the windows size.
++                                               * The N(R) field is valid.
++                                               */
++#define LLC_STATE_RECEIVE_I_CMD_W_INVALID_SEQ 0x1E
++                                              /* RECEIVE_I_CMD(P=X)_WITH_
++                                               * INVALID_N(S). The remote SSAP
++                                               * has sent an I command PDU 
++                                               * with the P bit set to "X"
++                                               * addressed to the local DSAP.
++                                               * The N(S) field of the command
++                                               * is invalid. The N(R) field is
++                                               * valid.
++                                               */
++#define LLC_STATE_RECEIVE_I_RSP               0x1F    /* RECEIVE_I_RSP(F=X). The 
++                                               * remote SSAP has sent a I
++                                               * response PDU with the F bit
++                                               * set to "X" addressed to the
++                                               * local DSAP. Both the N(R) and
++                                               * N(S) fields are valid and the
++                                               * N(S) value is the expected
++                                               * sequence number.
++                                               */
++#define LLC_STATE_RECEIVE_I_RSP_W_UNEXPECTED_SEQ 0x20
++                                              /* RECEIVE_I_RSP(F=X)_WITH_
++                                               * UNEXPECTED_N(S). The remote
++                                               * SSAP has sent an I response
++                                               * PDU with the F bit set to "X"
++                                               * addressed to the local DSAP.
++                                               * The N(S) field of the command
++                                               * does not contain the expected
++                                               * sequence number but is within
++                                               * the window size.
++                                               */
++#define LLC_STATE_RECEIVE_I_RSP_W_INVALID_SEQ 0x21
++                                              /* RECEIVE_I_RSP(F=X)_WITH_
++                                               * INVALID_N(S). The remote SSAP
++                                               * has sent an I response PDU
++                                               * with the F bit set to "X"
++                                               * addressed to the local DSAP.
++                                               * The N(S) field of the 
++                                               * response is invalid. The N(R)
++                                               * field is valid.
++                                               */
++#define LLC_STATE_RECEIVE_REJ_CMD     0x22    /* RECEIVE_REJ_CMD(P=X). The
++                                               * remote SSAP has sent a REJ
++                                               * command PDU with the P bit 
++                                               * set to "X" addressed to the
++                                               * local DSAP.
++                                               */
++#define LLC_STATE_RECEIVE_REJ_RSP     0x23    /* RECEIVE_REJ_RSP(F=X). The
++                                               * remote SSAP has sent a REJ
++                                               * response PDU with the F bit
++                                               * set to "X" addressed to the
++                                               * local DSAP.
++                                               */
++#define LLC_STATE_RECEIVE_RNR_CMD     0x24    /* RECEIVE_RNR_CMD(P=X). The
++                                               * remote SSAP has sent a REJ
++                                               * response PDU with the P bit
++                                               * set to "X" addressed to the
++                                               * local DSAP.
++                                               */
++#define LLC_STATE_RECEIVE_RNR_RSP     0x25    /* RECEIVE_RNR_RSP(F=X). The
++                                               * remote SSAP has sent a RNR
++                                               * response PDU with the F bit
++                                               * set to "X" addressed to the
++                                               * local DSAP.
++                                               */
++#define LLC_STATE_RECEIVE_RR_CMD      0x26    /* RECEIVE_RR_CMD(P=X). The
++                                               * remote SSAP has sent a RNR
++                                               * command PDU with the F bit
++                                               * set to "X" addressed to the
++                                               * local DSAP.
++                                               */
++#define LLC_STATE_RECEIVE_RR_RSP      0x27    /* RECEIVE_RR_RSP(F=X). The
++                                               * remote SSAP has sent a RR
++                                               * response PDU with the F bit
++                                               * set to "X" addressed to the
++                                               * local DSAP.
++                                               */
++#define LLC_STATE_RECEIVE_SABME_CMD   0x28    /* RECEIVE_SABME_CMD(P=X). The
++                                               * remote SSAP has sent an SABME
++                                               * command PDU with the P bit
++                                               * set to "X" addressed to the
++                                               * local DSAP.
++                                               */
++#define LLC_STATE_RECEIVE_UA_RSP      0x29    /* RECEIVE_UA_RSP(F=X). The
++                                               * remote SSAP has sent a UA
++                                               * response PDU with the F bit
++                                               * set to "X" addressed to the
++                                               * local DSAP.
++                                               */
++#define LLC_STATE_RECEIVE_XXX_CMD     0x2A    /* RECEIVE_XXX_CMD(F=X). The
++                                               * remote SSAP has sent a Type 2
++                                               * command PDU with the P bit
++                                               * set to "X" addressed to the
++                                               * local DSAP. The command is
++                                               * any command not specificly
++                                               * listed for that state.
++                                               */
++#define LLC_STATE_RECEIVE_XXX_RSP     0x2B    /* RECEIVE_XXX_RSP(F=X). The
++                                               * remote SSAP has sent a Type 2
++                                               * response PDU with the F bit
++                                               * set to "X" addressed to the
++                                               * local DSAP. The response is
++                                               * any response not specifically
++                                               * listed for that state.
++                                               */
++#define LLC_STATE_RECEIVE_XXX_YYY     0x2C    /* RECEIVE_XXX_YYY. The remote
++                                               * SSAP has sent a Type 2 PDU
++                                               * addressed to the local DSAP.
++                                               * The PDU is any command or
++                                               * response not specificly 
++                                               * listed for that state.
++                                               */
++#define LLC_STATE_RECEIVE_ZZZ_CMD_W_INVALID_SEQ       0x2D
++                                              /* RECEIVE_ZZZ_CMD(P=X)_WITH_
++                                               * INVALID_N(R). The remote
++                                               * SSAP has sent an I, RR, RNR,
++                                               * or REJ command PDU with the
++                                               * P bit set to "X" addressed to
++                                               * the local DSAP. The N(R) 
++                                               * field of the command is 
++                                               * invalid.
++                                               */
++#define LLC_STATE_RECEIVE_ZZZ_RSP_W_INVALID_SEQ       0x2E
++                                              /* RECEIVE_ZZZ_RSP(F=X)_WITH_
++                                               * INVALID_N(R). The remote SSAP
++                                               * has sent an I, RR, RNR, or
++                                               * REJ command PDU with the F 
++                                               * bit set to "X" addressed to 
++                                               * the local DSAP. The N(R) 
++                                               * field of the response is
++                                               * invalid.
++                                               */
++#define LLC_STATE_P_TIMER_EXPIRED     0x2F    /* P_TIMER_EXPIRED. The P/F 
++                                               * cycle timer has expired.
++                                               */
++#define LLC_STATE_ACK_TIMER_EXPIRED   0x30    /* ACK_TIMER_EXPIRED. The
++                                               * acknowledgment timer has
++                                               * expired.
++                                               */
++#define LLC_STATE_REJ_TIMER_EXPIRED   0x31    /* REJ_TIMER_EXPIRED. The "sent
++                                               * REJ" timer has expired.
++                                               */
++#define LLC_STATE_BUSY_TIMER_EXPIRED  0x32    /* BUSY_TIMER_EXPIRED. The
++                                               * remote-busy timer has expired
++                                               * In the state transition table
++                                               * some of the above events are
++                                               * qualified by the following
++                                               * conditions. The event is
++                                               * recognized only when the
++                                               * condition is true.
++                                               */
++#define LLC_STATE_P_FLAG_1            0x37    /* P_FLAG=1. P_FLAG has a value
++                                               * of one when a command with 
++                                               * the P bit set to "1" has been
++                                               * sent and a response with the
++                                               * F bit set to "1" is expected.
++                                               */
++#define LLC_STATE_P_FLAG_F            0x38    /* P_FLAG=F. P_FLAG has a value
++                                               * equal to the F bit in the
++                                               * response PDU received.
++                                               */
++#define LLC_STATE_REMOTE_BUSY_1               0x39    /* REMOTE_BUSY=1. When
++                                               * REMOTE_BUSY has a value of
++                                               * one, an RNR PDU has been
++                                               * received from the remote
++                                               * connection commponent to
++                                               * indicate that I PDUs should
++                                               * not be sent. DATA_REQUEST
++                                               * events are not recognized
++                                               * until this flag is reset to
++                                               * zero.
++                                               */
++#define LLC_STATE_RETRY_COUNT_OK      0x3B    /* RETRY_COUNT<N2. The number of
++                                               * retries is less than the
++                                               * maximum number of retries.
++                                               */
++#define LLC_STATE_RETRY_COUNT_MAX     0x3C    /* RETRY_COUNT>=N2. The number
++                                               * of retries has reached the
++                                               * maximum number permissible.
++                                               */
++#define LLC_STATE_INIT_PF_CYCLE               0x3F    /* INITIATE_P/F_CYCLE. The local
++                                               * LLC wants to initiate a P/F
++                                               * cycle. (This is only required
++                                               * if the local LLC is not
++                                               * generating other command PDUs
++                                               * for some reason.
++                                               */
++#define LLC_STATE_CLEAR_REMOTE_BUSY   0x40    /* CLEAR_REMOTE_BUSY. If
++                                               * REMOTE_BUSY has a value of
++                                               * one, then set REMOTE_BUSY to
++                                               * zero to indicate the remote
++                                               * LLC is now able to accept I
++                                               * PDUs, stop the BUSY_TIMER,
++                                               * inform the user by issuing
++                                               * REPORT_STATUS(
++                                               * REMOTE_NOT_BUSY) and, 
++                                               * provided the local LLC is in
++                                               * the NORMAL, REJECT, or BUSY
++                                               * state, start the (re)sending
++                                               * of any I PDUs that were 
++                                               * waiting for the remote busy
++                                               * to be cleared.
++                                               */
++#define LLC_STATE_CONNECT_INDICATION  0x41    /* CONNECT_INDICATION. Inform
++                                               * the user that a connection
++                                               * has been requested by a
++                                               * remote LLC SSAP.
++                                               */
++#define LLC_STATE_CONNECT_CONFIRM     0x42    /* CONENCT_CONFIRM. The
++                                               * connection service component
++                                               * indicates that the remote
++                                               * network entity has accepted
++                                               * the connection.
++                                               */
++#define LLC_STATE_DATA_INDICATION     0x43    /* DATA_INDICATION. The 
++                                               * connection service component
++                                               * passes the data unit from the
++                                               * received I PDU to the user.
++                                               */
++#define LLC_STATE_DISCONNECT_INDICATION       0x44    /* DISCONNECT_INDICATION. Inform
++                                               * the user that the remote
++                                               * network entity has initiated
++                                               * disconnection of the data 
++                                               * link connection.
++                                               */
++#define LLC_STATE_REMOTE_RESET_INDICATION 0x45        /* REMOTE_RESET_INDICATION. The
++                                               * remote network entity or
++                                               * remote peer has initiated a
++                                               * reset of the data link
++                                               * connection.
++                                               */
++#define LLC_STATE_LOCAL_RESET_INDICATION 0x46 /* LOCAL_RESET_INDICATION. The
++                                               * local LLC has determined that
++                                               * the data link connection is
++                                               * in need of reinitialization.
++                                               */
++#define LLC_STATE_RESET_CONFIRM               0x47    /* RESET_CONFIRM. The connection
++                                               * service component indicated
++                                               * that the remote network
++                                               * entity has accepted the
++                                               * reset.
++                                               */
++#define LLC_STATE_RPT_FRMR_RECEIVED   0x48    /* REPORT_STATUS. FRMR_RECEIVED.
++                                               * The local connection service
++                                               * component has received a FRMR
++                                               * response PDU.
++                                               */
++#define LLC_STATE_RPT_FRMR_SENT               0x49    /* REPORT_STATUS. FRMR_SENT. The
++                                               * local connection service
++                                               * component has received an
++                                               * invalid PDU, and has sent a
++                                               * FRMR response PDU.
++                                               */
++#define LLC_STATE_RPT_REMOTE_BUSY     0x4A    /* REPORT_STATUS. REMOTE_BUSY.
++                                               * The remote LLC DSAP is busy.
++                                               * The local connection service
++                                               * component will not accept a
++                                               * DATA_REQUEST.
++                                               */
++#define LLC_STATE_RPT_REMOTE_NOT_BUSY 0x4B    /* REPORT_STATUS. 
++                                               * REMOTE_NOT_BUSY. The remote
++                                               * LLC DSAP is no longer busy.
++                                               * The local connection service
++                                               * component will now accept a
++                                               * DATA_REQUEST.
++                                               */
++#define LLC_STATE_IF_F_1_CLEAR_REMOTE_BUSY 0x4C       /* IF_F=1_CLEAR_REMOTE_BUSY. If
++                                               * the I PDU is a response with
++                                               * the F bit set to "1" in
++                                               * response to a command PDU 
++                                               * with the P bit set to "1",
++                                               * then perform the 
++                                               * CLEAR_REMOTE_BUSY action.
++                                               */
++#define LLC_STATE_IF_DATA_FLAG_2_STOP_REJ_TIMER 0x4D /* 
++                                               * IF_DATA_FLAG=2_STOP_REJ_TIMER
++                                               * If DATA_FLAG has a value of
++                                               * two, indicating that a REJ
++                                               * PDU has been sent, stop the
++                                               * "sent REJ" timer.
++                                               */
++#define LLC_STATE_SEND_DISC_CMD               0x4E    /* SEND_DISC_CMD(P=X). Transmit
++                                               * a DISC command PDU with the
++                                               * P bit set to "X" to the 
++                                               * remote LLC DSAP.
++                                               */
++#define LLC_STATE_SEND_DM_RSP         0x4F    /* SEND_DM_RSP(F=X). Send a DM
++                                               * response PDU with the F bit
++                                               * set to "X" to the remote LLC
++                                               * DSAP.
++                                               */
++#define LLC_STATE_SEND_FRMR_RSP               0x50    /* SEND_FRMR_RSP(F=X). Send a
++                                               * FRMR response PDU with the F
++                                               * bit set to "X" to the remote
++                                               * LLC DSAP.
++                                               */
++#define LLC_STATE_RESEND_FRMR_RSP_0   0x51    /* RE-SEND_FRMR_RSP(F=0). Send
++                                               * the same FRMR response PDU
++                                               * with the same information
++                                               * field as sent earlier to the
++                                               * remote LLC DSAP. Set the F
++                                               * bit to "0".
++                                               */
++#define LLC_STATE_RESEND_FRMR_RSP_P   0x52    /* RE-SEND_FRMR_RSP(F=P). Send
++                                               * the same FRMR response PDU
++                                               * with the same information
++                                               * field as sent earlier to the
++                                               * remote LLC DSAP. Set the F
++                                               * bit equal to the P bit of the
++                                               * received command PDU.
++                                               */
++#define LLC_STATE_SEND_I_CMD          0x53    /* SEND_I_CMD(P=1). Send an I
++                                               * command PDU with the P bit
++                                               * set to "1" to the remote LLC
++                                               * DSAP with the data unit
++                                               * supplied by the user with the
++                                               * DATA_REQUEST. Before 
++                                               * transmission, copy the 
++                                               * current values of the send
++                                               * state variable V(S) and the
++                                               * receive state variable V(R)
++                                               * into the N(S) and N(R)
++                                               * fields, respectively, of the
++                                               * I PDU and increment (modulo 
++                                               * 128) the send state variable
++                                               * V(S).
++                                               */
++#define LLC_STATE_RESEND_I_CMD                0x54    /* RE-SEND_I_CMD(P=1). Start
++                                               * resending all the 
++                                               * unacknowledged I PDUs for 
++                                               * this data link connection
++                                               * begining with the N(R) given
++                                               * in the received PDU. Send the
++                                               * first as a command with the P
++                                               * bit set to "1". If the queue
++                                               * contains more than one I PDU,
++                                               * the balance must be sent as
++                                               * commands with the P bit set
++                                               * to "0", or as response with
++                                               * the F bit set to "0".
++                                               */
++#define LLC_STATE_RESEND_I_CMD_OR_SEND_RR 0x55        /* RE-SEND_I_CMD(P=I)_OR_SEND_RR
++                                               * Start resending all the
++                                               * unacknowledged I PDUs for
++                                                 * this data link connection
++                                                 * begining with the N(R) given
++                                                 * in the received PDU. Send the                                                 * first as a command with the P                                                 * bit set to "1". If the queue
++                                                 * contains more than one I PDU,                                                 * the balance must be sent as
++                                                 * commands with the P bit set
++                                                 * to "0", or as response with
++                                                 * the F bit set to "0". It is
++                                               * permissable to send a RR
++                                               * command PDU with the P bit
++                                               * set to "0", or as a response
++                                               * with the F bit set to "0". If
++                                               * no I PDU is ready to send, a                                                  * RR command PDU with the P bit
++                                               * set to "1" must be sent to
++                                               * the remote LLC DSAP.
++                                               */
++#define LLC_STATE_SEND_I_XXX          0x56    /* SEND_I_XXX(X=0). Send either
++                                               * an I response PDU with the
++                                               * F bit set to "0" or an I
++                                               * command PDU with the P bit
++                                               * set to "0" to the remote LLC
++                                               * DSAP with the data unit
++                                               * supplied by the user with the
++                                               * DATA_REQUEST. Before 
++                                               * transmission, copy the
++                                               * current values of the send
++                                               * state variable V(S) and the
++                                               * receive state variable V(R)
++                                               * into the N(S) and N(R) fields
++                                               * respectively, of the I PDU
++                                               * and increment (modulo 128)
++                                               * the send state variable V(S).
++                                               */
++#define LLC_STATE_RESEND_I_XXX                0x57    /* RE-SEND_I_XXX(X=0). Start
++                                               * resending all the 
++                                               * unacknowledged I PDUs for
++                                               * this data link connection
++                                               * begining with the N(R) given
++                                               * in the received PDU. They
++                                               * must be sent as either 
++                                               * commands with the P bit set 
++                                               * to "0" or as responses with 
++                                               * the F bit set to "0".
++                                               */
++#define LLC_STATE_RESEND_I_XXX_OR_SEND_RR 0x58        /* RE-SEND_I_XXX(X=0)_OR_SEND_RR
++                                               * Start resending all the
++                                                 * unacknowledged I PDUs for
++                                                 * this data link connection
++                                                 * begining with the N(R) given
++                                                 * in the received PDU. They
++                                                 * must be sent as either
++                                                 * commands with the P bit set
++                                                 * to "0" or as responses with
++                                                 * the F bit set to "0". It is
++                                               * permissable to send either
++                                               * a RR response PDU with the
++                                               * F bit set to "0" or a RR
++                                               * command PDU with the P bit
++                                               * set to "0" to the remote
++                                               * LLC DSAP before starting the
++                                               * resending of the I PDUs. If
++                                               * no I PDU is ready to send,
++                                               * either an RR response PDU
++                                               * with the F bit set to "0" or
++                                               * an RR command PDU with the P
++                                               * bit set to "0" must be sent
++                                               * to the remote LLC DSAP.
++                                               */
++#define LLC_STATE_RESEND_I_RSP                0x59    /* RE-SEND_I_RSP(F=1). Start
++                                               * resending all the
++                                               * unacknowledged I PDUs for
++                                               * this data link connection
++                                               * begining with the N(R) given
++                                               * in the received PDU. Send the
++                                               * first as a response with the
++                                               * F bit set to "1". If the
++                                               * queue contains more than one
++                                               * I PDU, the balance must be
++                                               * transmitted as commands with
++                                               * the P bit set to "0" or as
++                                               * responses with the F bit set
++                                               * to "0".
++                                               */
++#define LLC_STATE_SEND_REJ_CMD                0x5A    /* SEND_REJ_CMD(P=1). Send a REJ
++                                               * command PDU with the P bit
++                                               * set to "1" to the remote LLC
++                                               * DSAP.
++                                               */
++#define LLC_STATE_SEND_REJ_RSP                0x5B    /* SEND_REJ_RSP(F=1). Send a REJ
++                                               * response PDU with the F bit
++                                               * set to "1" to the remote LLC
++                                               * DSAP.
++                                               */
++#define LLC_STATE_SEND_REJ_XXX                0x5C    /* SEND_REJ_XXX(X=0). Send
++                                               * either a REJ response PDU
++                                               * with the F bit set to "0" or
++                                               * a REJ command PDU with the P
++                                               * bit set to "0" to the remote
++                                               * LLC DSAP.
++                                               */
++#define LLC_STATE_SEND_RNR_CMD                0x5D    /* SEND_RNR_CMD(P=1). Send a RNR
++                                               * command PDU with the P bit
++                                               * set to "1" to the remote LLC
++                                               * DSAP.
++                                               */
++#define LLC_STATE_SEND_RNR_RSP                0x5E    /* SEND_RNR_RSP(F=I). Send a RNR
++                                               * response PDU with the F bit
++                                               * set to "1"  to the remote LLC
++                                               * DSAP.
++                                               */
++#define LLC_STATE_SEND_RNR_XXX                0x5F    /* SEND_RNR_XXX(X=0). Send
++                                               * either a RNR response PDU 
++                                               * with the F bit set to "0" or
++                                               * a RNR command PDU with the P
++                                               * bit set to "0" to the remote
++                                               * LLC DSAP.
++                                               */
++#define LLC_STATE_SET_REMOTE_BUSY     0x60    /* SET_REMOTE_BUSY. If 
++                                               * REMOTE_BUSY is zero, then set
++                                               * REMOTE_BUSY to one to 
++                                               * indicate the remote LLC is in
++                                               * the busy state and is no able
++                                               * to accept I PDUs, start the
++                                               * BUSY timer, inform the 
++                                               * sublayer management function
++                                               * by using REPORT_STATUS(
++                                               * REMOTE_BUSY) and stop any
++                                               * (re)sending of I PDUs that is
++                                               * in progess.
++                                               */
++#define LLC_STATE_OPTIONAL_SEND_RNR_XXX       0x61    /* OPTIONAL_SEND_RNR_XXX(X=0).
++                                               * It is permissible to send a
++                                               * RNR command PDU with the P
++                                               * bit set to "0" or a RNR
++                                               * response PDU with the
++                                               * F bit set to "0" to the 
++                                               * remote LLC DSAP in case the
++                                               * remote LLC did no receive the
++                                               * first RNR sent when the busy
++                                               * state was entered.
++                                               */
++#define LLC_STATE_SEND_RR_CMD         0x62    /* SEND_RR_CMD(P=1). Send a RR
++                                               * command PDU with the P bit
++                                               * set to "1" to the remote LLC
++                                               * DSAP.
++                                               */
++#define LLC_STATE_SEND_ACKNOWLEDGE_CMD        0x63    /* SEND_ACKNOWLEDGE_CMD(P=1).
++                                               * Under all conditions it is
++                                               * permissible to send a RR
++                                               * command PDU with the P bit
++                                               * set to "1" to the remote LLC
++                                               * DSAP. If no I PDU is ready to
++                                               * send, the RR command PDU with
++                                               * the P bit set to "1" must be
++                                               * sent to the remote LLC DSAP.
++                                               * (This RR PDU may be delayed
++                                               * by a time bounded by the
++                                               * ACK_TIMER value, to wait for
++                                               * the generation of an I PDU.)
++                                               * However, if an I PDU is ready
++                                               * send, and can be modified to
++                                               * a command with the P bit set
++                                               * to "1", then the RR command
++                                               * PDU does not need to be sent.
++                                               */
++#define LLC_STATE_SEND_RR_RSP         0x64    /* SEND_RR_RSP(F=I). Send a RR
++                                               * response PDU with the F bit
++                                               * set to "1" to the remote LLC
++                                               * DSAP.
++                                               */
++#define LLC_STATE_SEND_ACKNOWLEDGE_RSP        0x65    /* SEND_ACKNOWLEDGE_RSP(F=I).
++                                               * Under all conditions it is
++                                               * permissible to send a RR 
++                                               * response PDU with the F bit
++                                               * set to "1" to the remote LLC
++                                               * DSAP. If no I PDU is ready to
++                                               * send, the RR response PDU 
++                                               * with the F bit set to "1" 
++                                               * must be sent to the remote
++                                               * LLC DSAP. However, if an I 
++                                               * PDU is ready to send, and can
++                                               * be modified to a response 
++                                               * with the F bit set to "1," 
++                                               * then the RR response PDU does
++                                               * not need to be sent.
++                                               */
++#define LLC_STATE_SEND_RR_XXX         0x66    /* SEND_RR_XXX(X=0). Send either
++                                               * a RR response PDU with the F
++                                               * bit set to "0" or a RR 
++                                               * command PDU with the P bit
++                                               * set to "0" to the remote LLC
++                                               * DSAP.
++                                               */
++#define LLC_STATE_SEND_ACKNOWLEDGE_XXX        0x67    /* SEND_ACKNOWLEDGE_XXX(X=0).
++                                               * Under all conditions it is
++                                               * permissible to send either a
++                                               * RR response PDU with the F
++                                               * bit set to "0" or a RR 
++                                               * command PDU with the P bit
++                                               * set to "0" to the remote LLC
++                                               * DSAP. If no I PDU is ready to
++                                               * send, either an RR response
++                                               * with the F bit set to "0" or
++                                               * an RR command PDU with the P
++                                               * bit set to "0" must be sent 
++                                               * to the remote LLC DSAP. (This
++                                               * RR PDU may be delayed, by a
++                                               * time bounded by the ACK_TIMER
++                                               * value, to wait for the
++                                               * generation of an I PDU.)
++                                               * However, if an I PDU is ready
++                                               * to send, then the RR PDU does
++                                               * not need to be sent.
++                                               */
++#define LLC_STATE_SEND_SABME_CMD      0x68    /* SEND_SABME_CMD(P=X). Send a
++                                               * SABME command PDU with the P
++                                               * bit set to "X" to the remote
++                                               * LLC DSAP.
++                                               */
++#define LLC_STATE_SEND_UA_RSP         0x69    /* SEND_UA_RSP(F=X). Send a UA
++                                               * response PDU with the F bit
++                                               * set to "X" to the remote LLC
++                                               * DSAP.
++                                               */
++#define LLC_STATE_S_FLAG_0            0x6A    /* S_FLAG:=0. Set S_FLAG to zero
++                                               * to indicate that a SABME PDU
++                                               * has not been received from
++                                               * the remote LLC while the
++                                               * local connection service
++                                               * component is in the RESET,
++                                               * SETUP, or RESET_WAIT state.
++                                               */
++#define LLC_STATE_S_FLAG_1            0x6B    /* S_FLAG:=1. Set S_FLAG to one
++                                               * to indicate that a SABME PDU
++                                               * has been received from the
++                                               * remote LLC while the local
++                                               * connection service component
++                                               * is in the RESET, SETUP, or
++                                               * RESET_WAIT state.
++                                               */
++#define LLC_STATE_START_P_TIMER               0x6C    /* START_P_TIMER. Start the P/F
++                                               * cycle timer from zero; if the
++                                               * P_FLAG is zero, initialize
++                                               * RETRY_COUNT to zero, and set
++                                               * P_FLAG to one.
++                                               */
++#define LLC_STATE_START_ACK_TIMER     0x6D    /* START_ACK_TIMER. Start the
++                                               * acknowledgment timer from
++                                               * zero.
++                                               */
++#define LLC_STATE_START_REJ_TIMER     0x6E    /* START_REJ_TIMER. Start the
++                                               * "sent REJ" timer from zero.
++                                               */
++#define LLC_STATE_START_ACK_TIMER_IF_NOT_RUNNING 0x6F
++                                              /* START_ACK_TIMER_IF_NOT_
++                                               * RUNNING. If the 
++                                               * acknowledgment timer is not
++                                               * currently running, then start
++                                               * the acknowledgment timer from
++                                               * zero.
++                                               */
++#define LLC_STATE_STOP_ACK_TIMER      0x6F    /* STOP_ACK_TIMER. Stop the
++                                               * acknowledgment timer.
++                                               */
++#define LLC_STATE_STOP_P_TIMER                0x70    /* STOP_P_TIMER. Stop the P/F
++                                               * cycle timer and set P_FLAG
++                                               * to zero.
++                                               */
++#define LLC_STATE_STOP_REJ_TIMER      0x71    /* STOP_REJ_TIMER. Stop the
++                                               * "sent REJ" timer.
++                                               */
++#define LLC_STATE_STOP_ALL_TIMERS     0x72    /* STOP_ALL_TIMERS. Stop the
++                                               * P/F cycle timer, the "sent
++                                               * REJ" timer, the remote-busy
++                                               * timer, and the acknowledgment
++                                               * timer.
++                                               */
++#define LLC_STATE_STOP_OTHER_TIMERS   0x73    /* STOP_OTHER_TIMERS. Stop the
++                                               * P/F cycle timer, the "sent
++                                               * REJ" timer, and the remote-
++                                               * busy timer.
++                                               */
++#define LLC_STATE_UPDATE_SEQ_RECEIVED 0x74    /* UPDATE_N(R)_RECEIVED. If the
++                                               * N(R) of the received PDU
++                                               * acknowledges the receipt of
++                                               * one or more previously
++                                               * unacknowledged I PDUs, update
++                                               * the local record of 
++                                               * N(R)_RECEIVED, set 
++                                               * RETRY_COUNT to zero, and stop
++                                               * the acknowledgment timer. If
++                                               * unacknowledged I PDUs still
++                                               * exist, start the 
++                                               * acknowledgment timer if it
++                                               * was stopped.
++                                               */
++#define LLC_STATE_UPDATE_P_FLAG               0x75    /* UPDATE_P_FLAG. If the 
++                                               * received PDU was a response
++                                               * with the F bit set to "1",
++                                               * set the P_FLAG to zero and
++                                               * stop the P/F cycle timer.
++                                               */
++#define LLC_STATE_DATA_FLAG_0         0x76    /* DATA_FLAG:=0. Set the 
++                                               * DATA_FLAG to zero to indicate
++                                               * that the data units from
++                                               * received I PDUs were not
++                                               * discarded during a local busy
++                                               * period.
++                                               */
++#define LLC_STATE_DATA_FLAG_1         0x77    /* DATA_FLAG:=1. Set the 
++                                               * DATA_FLAG to one to indicate
++                                               * that the data units from
++                                               * receieved I PDUs were 
++                                               * discarded during a local busy
++                                               * period.
++                                               */
++#define LLC_STATE_DATA_FLAG_2         0x78    /* DATA_FLAG:=2. Set the
++                                               * DATA_FLAG to two to record
++                                               * that the BUSY state was 
++                                               * entered with a REJ PDU
++                                               * outstanding.
++                                               */
++#define LLC_STATE_DATA_FLAG_0_THEN_DATA_FLAG_1 0x79
++                                              /* DATA_FLAG=0_THEN_DATA_FLAG:=1
++                                               * If the DATA_FLAG had been
++                                               * zero, indicating that no data
++                                               * units had been discarded, set
++                                               * it to one to indicate that
++                                               * data units have now been
++                                               * discarded.
++                                               */
++#define LLC_STATE_P_FLAG_0            0x7A    /* P_FLAG:=0. Initialize the
++                                               * P_FLAG to zero. This 
++                                               * indicates that the reception
++                                               * of a response PDU with the F
++                                               * bit set to "1" is not 
++                                               * expected.
++                                               */
++#define LLC_STATE_P_FLAG_P            0x7B    /* P_FLAG:=P. Set the P_FLAG to
++                                               * the value of the P bit in the
++                                               * command PDU being sent.
++                                               */
++#define LLC_STATE_REMOTE_BUSY_0               0x7C    /* REMOTE_BUSY:=0. Set 
++                                               * REMOTE_BUSY to zero to 
++                                               * indicate that the remote LLC
++                                               * is avle to accept I PDUs.
++                                               */
++#define LLC_STATE_RETRY_COUNT_0               0x7D    /* RETRY_COUNT:=0. Initialize
++                                               * RETRY_COUNT to zero.
++                                               */
++#define LLC_STATE_RETRY_COUNT_PLUS_1  0x7E    /* RETRY_COUNT:=RETRY_COUNT+1.
++                                               * Increment RETRY_COUNT by one.
++                                               */
++#define LLC_STATE_RECEIVE_SEQ_0               0x7F    /* V(R):=0. Initialize the 
++                                               * receive state variable. This
++                                               * is the expected sequence
++                                               * number of the next I PDU
++                                               * received.
++                                               */
++#define LLC_STATE_RECEIVE_SEQ_PLUS_1  0x80    /* V(R):=V(R)+1. Increment
++                                               * (modulo 128) the receive
++                                               * state variable. This is the
++                                               * expected sequence number of 
++                                               * the next I PDU received.
++                                               */
++#define LLC_STATE_SEND_SEQ_0          0x81    /* V(S):=0. Initialize the send
++                                               * state variable. This is the
++                                               * sequence number of the next
++                                               * I PDU to be sent.
++                                               */
++#define LLC_STATE_SEND_SEQ_TO_RECEIVE_PDU 0x82        /* V(S):=N(R). Reset the send
++                                               * state variable to the value
++                                               * specified by the N(R) field
++                                               * of the PDU just received.
++                                               */
++#define LLC_STATE_F_FLAG_P            0x83    /* F_FLAG:=P. Set the F_FLAG to
++                                               * the value of the P bit
++                                               * received. This is the value
++                                               * of the F bit to be sent in
++                                               * UA or DM PDUs.
++                                               */
++#define LLC_STATE_SEND_I_RSP          0x84
++#define LLC_STATE_DISCONNECT_RESPONSE 0x85
++#define LLC_STATE_SEND_RR_RESPONSE    0x86
++#define LLC_STATE_SEND_RR_REQUEST     0x87
++#define LLC_STATE_SEND_REJ_REQUEST    0x88
++#define LLC_STATE_SEND_REJ_RESPONSE   0x89
++#define LLC_STATE_SEND_RNR_REQUEST    0x8A
++#define LLC_STATE_SEND_RNR_RESPONSE   0x8B
++#define LLC_STATE_SEND_DM_RESPONSE    0x8C
++#define LLC_STATE_SEND_UA_RESPONSE    0x8D
++#define LLC_STATE_SEND_NULL_DSAP_TEST_R       0x8E
+-void          llc_cancel_timers(llcptr lp);
+-int           llc_decode_frametype(frameptr fr);
+-llcptr                llc_find(void);
+-int           llc_free_acknowledged_skbs(llcptr lp, unsigned char ack);
+-void          llc_handle_xid_indication( char *chsp, short int ll, char *xid_data);
+-void          llc_interpret_pseudo_code(llcptr lp, int pc_label, struct sk_buff *skb, char type);
+-void          llc_add_to_queue(struct sk_buff *skb, struct sk_buff **f, struct sk_buff **b);
+-void          llc_process_otype2_frame(llcptr lp, struct sk_buff *skb, char type);
+-struct sk_buff *llc_pull_from_atq(llcptr lp); 
+-int           llc_resend_ipdu(llcptr lp, unsigned char ack_nr, unsigned char type, char p);
+-void          llc_sendpdu(llcptr lp, char type, char pf, int data_len, char *pdu_data);
+-void          llc_sendipdu(llcptr lp, char type, char pf, struct sk_buff *skb);
+-void          llc_start_timer(llcptr lp, int t);
+-void          llc_stop_timer(llcptr lp, int t);
+-void          llc_timer_expired(llcptr lp, int t);
+-int           llc_validate_seq_nos(llcptr lp, frameptr fr);
+-
+-int           llc_data_request(llcptr lp, struct sk_buff *skb);
+-void          llc_unit_data_request(llcptr lp, int ll, char * data);
+-void          llc_disconnect_request(llcptr lp);
+-void          llc_connect_request(llcptr lp);
+-void          llc_xid_request(llcptr lp, char opt, int data_len, char *pdu_data);
+-void          llc_test_request(llcptr lp, int data_len, char *pdu_data);
+-
+-int           register_cl2llc_client(llcptr llc, const char *device, void (*ops)(llcptr), u8 *rmac, u8 ssap, u8 dsap);
+-void          unregister_cl2llc_client(llcptr lp);
+-int           llc_mac_data_indicate(llcptr lp, struct sk_buff *skb );
++extern int llc_queue_xmit(struct sk_buff *skb);
++extern struct datalink_proto *register_8022_client(unsigned char type,
++        int (*rcvfunc)(struct sk_buff*,struct device*,struct packet_type*),
++        int (*msgrcvfunc)(int rsp, struct sk_buff *));
++extern void unregister_8022_client(unsigned char type);
++extern int llc_connect(struct datalink_proto *dl, struct device *dev,
++        __u8 *dmac, __u8 dsap, int rsp);
++extern int llc_reset(struct datalink_proto *dl, struct device *dev,
++        __u8 *dmac, __u8 dsap, int rsp);
++extern int llc_disconnect(struct datalink_proto *dl, struct device *dev,
++        __u8 *dmac, __u8 dsap, int rsp);
++extern int llc_decode_pdu(llchdr *llc);
++extern int llc_data(__u8 ssap, __u8 dsap, __u8 *dmac,
++        struct sk_buff *skb, struct device *dev);
++extern int llc_test(__u8 ssap, __u8 dsap, __u8 *dmac,
++        struct sk_buff *skb, struct device *dev);
++#endif /* __NET_LLC_H */
+diff -uNr linux/include/net/llc_frame.h linux-llc/include/net/llc_frame.h
+--- linux/include/net/llc_frame.h      Thu Dec 12 14:54:21 1996
++++ linux-llc/include/net/llc_frame.h  Thu Jan  1 01:00:00 1970
+@@ -1,98 +0,0 @@
+-/* if_ether.h needed for definition of ETH_DATA_LEN and ETH_ALEN
+- */
+-#include "linux/if_ether.h"
+-
+-/* frame layout based on par3.2 "LLC PDU format"
+- */
+-typedef union {                       /* pdu layout from pages 40 & 44 */
+-    struct {                  /* general header, all pdu types */
+-      unsigned dsap : 8;      /* dest service access point */
+-      unsigned ssap : 8;      /* source service access point */
+-      unsigned f1 : 1;        /* I- U- or S- format id bits */
+-      unsigned f2 : 1;
+-      unsigned : 6;
+-      unsigned : 8;
+-   } pdu_hdr;
+-   struct {
+-        char dummy1[2];       /* dsap + ssap */
+-      char byte1;
+-      char byte2;
+-   } pdu_cntl;                        /* unformatted control bytes */
+-   struct {                   /* header of an Information pdu */
+-      unsigned char dummy2[2];
+-      unsigned : 1;
+-      unsigned ns : 7;
+-      unsigned i_pflag : 1;   /* poll/final bit */
+-      unsigned nr : 7;        /* N(R)  */     
+-      unsigned char is_info[ ETH_DATA_LEN ];
+-   }  i_hdr;
+-   struct {                   /* header of a Supervisory pdu */
+-      unsigned char dummy3[2];
+-      unsigned : 2;
+-      unsigned ss : 2;        /* supervisory function bits */
+-      unsigned : 4;
+-      unsigned s_pflag : 1;   /* poll/final bit  */
+-      unsigned nr : 7;        /* N(R)  */
+-   } s_hdr;
+-
+-/* when accessing the P/F bit or the N(R) field there's no need to distinguish
+-   I pdus from S pdus i_pflag and s_pflag / i_nr and s_nr map to the same
+-   physical location.
+- */ 
+-   struct {                   /* header of an Unnumbered pdu */
+-      unsigned char dummy4[2];
+-      unsigned : 2;
+-      unsigned mm1 : 2;       /* modifier function part1 */
+-      unsigned u_pflag : 1;    /* P/F for U- pdus */
+-      unsigned mm2 : 3;       /* modifier function part2 */
+-      unsigned char u_info[ ETH_DATA_LEN-1];
+-   } u_hdr;
+-   struct {                   /* mm field in an Unnumbered pdu */
+-      unsigned char dummy5[2];
+-      unsigned : 2;
+-      unsigned mm : 6;        /* must be masked to get ridd of P/F !  */
+-   } u_mm;
+-       
+-} frame_type, *frameptr;
+-
+-/* frame format test macros: */
+-
+-#define IS_UFRAME( fr ) ( ( (fr)->pdu_hdr.f1) & ( (fr)->pdu_hdr.f2) )
+-
+-#define IS_IFRAME( fr ) ( !( (fr)->pdu_hdr.f1) )
+-
+-#define IS_SFRAME( fr ) ( ( (fr)->pdu_hdr.f1) & !( (fr)->pdu_hdr.f2) )
+-
+-#define IS_RSP( fr ) ( fr->pdu_hdr.ssap & 0x01 )
+-
+-
+-/* The transition table, the _encode tables and some tests in the
+-   source code depend on the numeric order of these values.
+-   Think twice before changing.
+- */
+-
+-/* frame names for TYPE 2 operation: */
+-#define I_CMD         0
+-#define RR_CMD                1
+-#define RNR_CMD               2
+-#define REJ_CMD               3
+-#define DISC_CMD      4
+-#define SABME_CMD     5
+-#define I_RSP         6
+-#define RR_RSP                7
+-#define RNR_RSP               8
+-#define REJ_RSP               9
+-#define UA_RSP                10
+-#define DM_RSP                11
+-#define FRMR_RSP      12
+-
+-/* junk frame name: */
+-#define BAD_FRAME     13
+-#define NO_FRAME      13
+-
+-/* frame names for TYPE 1 operation: */
+-#define UI_CMD                14
+-#define XID_CMD               15
+-#define TEST_CMD      16
+-#define XID_RSP               17
+-#define TEST_RSP      18
+diff -uNr linux/include/net/llc_name.h linux-llc/include/net/llc_name.h
+--- linux/include/net/llc_name.h       Thu Dec 12 14:54:21 1996
++++ linux-llc/include/net/llc_name.h   Thu Jan  1 01:00:00 1970
+@@ -1,7 +0,0 @@
+-char *frame_names[] =
+-    {"I_CMD","RR_CMD","RNR_CMD","REJ_CMD","DISC_CMD",
+-    "SABME_CMD","I_RSP","RR_RSP","RNR_RSP","REJ_RSP",
+-    "UA_RSP","DM_RSP","FRMR_RSP","BAD_FRAME","UI_CMD",
+-    "XID_CMD","TEST_CMD","XID_RSP","TEST_RSP"
+-};
+- 
+diff -uNr linux/include/net/llc_state.h linux-llc/include/net/llc_state.h
+--- linux/include/net/llc_state.h      Thu Dec 12 14:54:21 1996
++++ linux-llc/include/net/llc_state.h  Thu Jan  1 01:00:00 1970
+@@ -1,4 +0,0 @@
+-char *state_names[] = { 
+-      "ADM","CONN","RESET_WAIT","RESET_CHECK","SETUP",
+-      "RESET","D_CONN","ERROR","NORMAL"
+-};
+diff -uNr linux/include/net/llccall.h linux-llc/include/net/llccall.h
+--- linux/include/net/llccall.h        Thu Dec 12 14:54:21 1996
++++ linux-llc/include/net/llccall.h    Mon Sep 25 06:47:02 2000
+@@ -1,3 +1,2 @@
+ /* Separate to keep compilation of protocols.c simpler */
+-extern void llc_init(struct net_proto *pro);
+-
++extern void llc_proto_init(struct net_proto *);
+diff -uNr linux/include/net/p8022.h linux-llc/include/net/p8022.h
+--- linux/include/net/p8022.h  Mon Mar 25 06:58:22 1996
++++ linux-llc/include/net/p8022.h      Thu Jan  1 01:00:00 1970
+@@ -1,7 +0,0 @@
+-#ifndef _NET_P8022_H
+-#define _NET_P8022_H
+-
+-extern struct datalink_proto *register_8022_client(unsigned char type, int (*rcvfunc)(struct sk_buff *, struct device *, struct packet_type *));
+-extern void unregister_8022_client(unsigned char type);
+-
+-#endif
+diff -uNr linux/include/net/p8023.h linux-llc/include/net/p8023.h
+--- linux/include/net/p8023.h  Thu Jan  1 01:00:00 1970
++++ linux-llc/include/net/p8023.h      Mon Sep 25 06:47:27 2000
+@@ -0,0 +1,2 @@
++extern struct datalink_proto *make_8023_client(void);
++extern void destroy_8023_client(struct datalink_proto *);
+diff -uNr linux/include/net/sock.h linux-llc/include/net/sock.h
+--- linux/include/net/sock.h   Fri Jun 23 11:13:52 2000
++++ linux-llc/include/net/sock.h       Mon Sep 25 07:21:08 2000
+@@ -461,6 +461,11 @@
+       struct sk_filter        *filter;
+ #endif /* CONFIG_FILTER */
++#if defined(CONFIG_LLC_UI) || defined(CONFIG_LLC_UI_MODULE)
++        __u8                    sap;
++        struct datalink_proto   *llc_proto;
++#endif
++
+       /* This is where all the private (optional) areas that don't
+        * overlap will eventually live. 
+        */
+diff -uNr linux/net/802/Makefile linux-llc/net/802/Makefile
+--- linux/net/802/Makefile     Thu Aug 26 01:29:53 1999
++++ linux-llc/net/802/Makefile Thu Jan  1 01:00:00 1970
+@@ -1,60 +0,0 @@
+-#
+-# Makefile for the Linux 802.x protocol layers.
+-#
+-# Note! Dependencies are done automagically by 'make dep', which also
+-# removes any old dependencies. DON'T put your own dependencies here
+-# unless it's something special (ie not a .c file).
+-#
+-# Note 2! The CFLAGS definition is now in the main makefile...
+-
+-O_TARGET := 802.o
+-O_OBJS          = p8023.o
+-
+-ifeq ($(CONFIG_SYSCTL),y)
+-O_OBJS += sysctl_net_802.o
+-endif
+-
+-ifeq ($(CONFIG_LLC),y)
+-SUB_DIRS += transit
+-O_OBJS += llc_sendpdu.o llc_utility.o cl2llc.o
+-OX_OBJS += llc_macinit.o
+-SNAP = y
+-endif
+-
+-ifdef CONFIG_TR
+-O_OBJS += tr.o
+-      SNAP=y
+-endif
+-
+-ifdef CONFIG_NET_FC
+-O_OBJS += fc.o
+-endif
+-
+-ifdef CONFIG_FDDI
+-O_OBJS += fddi.o
+-endif
+-
+-ifdef CONFIG_HIPPI
+-O_OBJS += hippi.o
+-endif
+-
+-ifdef CONFIG_IPX
+-      SNAP=y
+-endif
+-
+-ifdef CONFIG_ATALK
+-      SNAP=y
+-endif
+-
+-ifeq ($(SNAP),y)
+-OX_OBJS += p8022.o psnap.o
+-endif
+-
+-
+-include $(TOPDIR)/Rules.make
+-
+-cl2llc.c: cl2llc.pre
+-      sed -f ./pseudo/opcd2num.sed cl2llc.pre >cl2llc.c
+-
+-tar:
+-              tar -cvf /dev/f1 .
+diff -uNr linux/net/802/TODO linux-llc/net/802/TODO
+--- linux/net/802/TODO Thu Dec 12 14:54:22 1996
++++ linux-llc/net/802/TODO     Thu Jan  1 01:00:00 1970
+@@ -1,29 +0,0 @@
+-Remaining Problems:
+-
+-1. Serialization of access to variables in the llc structure
+-by mac_data_indicate(), timer expired functions, and data_request() .
+-There is not serialization of any kind right now.
+-While testing, I have not seen any problems that stem from this lack of
+-serialization, but it wories me...
+-
+-2. The code is currently able to handle one connection only,
+-there is more work in register_cl2llc_client() to make a chain
+-of llc structures and in mac_data_indicate() to find back
+-the llc structure addressed by an incomming frame.
+-According to IEEE, connections are identified by (remote mac + local mac
+-+ dsap + ssap). dsap and ssap do not seem important: existing applications
+-always use the same dsap/ssap. Its probably sufficient to index on 
+-the remote mac only. 
+- 
+-3. There is no test to see if the transmit window is full in data_request()
+-as described in the doc p73, "7.5.1 Sending I PDUs" 3th alinea.
+-The pdus presented to data_request() could probably go on the 
+-awaiting-transmit-queue (atq). The real difficulty is coding a test
+-to see if the transmit window is used up and to send the queue
+-when space in the window becomes available.
+-As I have no network layer that can generate a continous flow of pdus it is
+-difficult to simulate a remote busy condition and hence to test the code
+-to handle it.
+- 
+-4. A simple flow control algorithm, steering the size of the transmit
+-window would be nice to have.
+diff -uNr linux/net/802/cl2llc.c linux-llc/net/802/cl2llc.c
+--- linux/net/802/cl2llc.c     Sat Nov 29 18:41:10 1997
++++ linux-llc/net/802/cl2llc.c Thu Jan  1 01:00:00 1970
+@@ -1,615 +0,0 @@
+-/*
+- * NET                An implementation of the IEEE 802.2 LLC protocol for the
+- *            LINUX operating system.  LLC is implemented as a set of 
+- *            state machines and callbacks for higher networking layers.
+- *
+- *            Class 2 llc algorithm.
+- *            Pseudocode interpreter, transition table lookup,
+- *                    data_request & indicate primitives...
+- *
+- *            Code for initialization, termination, registration and 
+- *            MAC layer glue.
+- *
+- *            Copyright Tim Alpaerts, 
+- *                    <Tim_Alpaerts@toyota-motor-europe.com>
+- *
+- *            This program is free software; you can redistribute it and/or
+- *            modify it under the terms of the GNU General Public License
+- *            as published by the Free Software Foundation; either version
+- *            2 of the License, or (at your option) any later version.
+- *
+- *    Changes
+- *            Alan Cox        :       Chainsawed into Linux format
+- *                                    Modified to use llc_ names
+- *                                    Changed callbacks
+- *
+- *    This file must be processed by sed before it can be compiled.
+- */
+-
+-#include <linux/types.h>
+-#include <linux/kernel.h>
+-#include <linux/malloc.h>
+-#include <linux/netdevice.h>
+-#include <linux/skbuff.h>
+-#include <net/p8022.h>
+-#include <linux/proc_fs.h>
+-#include <linux/stat.h>
+-#include <asm/byteorder.h>
+-
+-#include "pseudo/pseudocode.h"
+-#include "transit/pdutr.h"
+-#include "transit/timertr.h"
+-#include <net/llc_frame.h>
+-#include <net/llc.h>
+-
+-/*
+- *    Data_request() is called by the client to present a data unit
+- *    to the llc for transmission.
+- *    In the future this function should also check if the transmit window
+- *    allows the sending of another pdu, and if not put the skb on the atq
+- *    for deferred sending.
+- */
+-
+-int llc_data_request(llcptr lp, struct sk_buff *skb)
+-{
+-      if (skb_headroom(skb) < (lp->dev->hard_header_len +4)){
+-              printk("cl2llc: data_request() not enough headroom in skb\n");
+-              return -1;
+-      };
+-
+-      skb_push(skb, 4);
+-
+-      if ((lp->state != NORMAL) && (lp->state != BUSY) && (lp->state != REJECT))
+-      {
+-              printk("cl2llc: data_request() while no llc connection\n"); 
+-              return -1;  
+-      }
+-
+-      if (lp->remote_busy)
+-      {     /* if the remote llc is BUSY, */
+-              ADD_TO_ATQ(skb);      /* save skb in the await transmit queue */
+-              return 0;
+-      }                           
+-      else
+-      {
+-              /*
+-               *      Else proceed with xmit 
+-               */
+-
+-              switch(lp->state)
+-              {
+-                      case NORMAL:
+-                              if(lp->p_flag)
+-                                      llc_interpret_pseudo_code(lp, NORMAL2, skb, NO_FRAME);
+-                              else
+-                                      llc_interpret_pseudo_code(lp, NORMAL1, skb, NO_FRAME);
+-                              break;
+-                      case BUSY:
+-                              if (lp->p_flag)
+-                                      llc_interpret_pseudo_code(lp, BUSY2, skb, NO_FRAME);
+-                              else
+-                                      llc_interpret_pseudo_code(lp, BUSY1, skb, NO_FRAME);
+-                              break;
+-                      case REJECT:
+-                              if (lp->p_flag)
+-                                      llc_interpret_pseudo_code(lp, REJECT2, skb, NO_FRAME);
+-                              else
+-                                      llc_interpret_pseudo_code(lp, REJECT1, skb, NO_FRAME);
+-                              break;
+-                      default:
+-              }
+-              if(lp->llc_callbacks)
+-              {
+-                      lp->llc_event(lp);
+-                      lp->llc_callbacks=0;
+-              }
+-              return 0;  
+-      }              
+-}
+-
+-
+-
+-/* 
+- *    Disconnect_request() requests that the llc to terminate a connection
+- */
+-
+-void disconnect_request(llcptr lp)
+-{
+-      if ((lp->state == NORMAL) ||
+-              (lp->state == BUSY) ||
+-              (lp->state == REJECT) ||
+-              (lp->state == AWAIT) ||
+-              (lp->state == AWAIT_BUSY) ||
+-              (lp->state == AWAIT_REJECT))
+-      {
+-              lp->state = D_CONN;
+-              llc_interpret_pseudo_code(lp, SH1, NULL, NO_FRAME);
+-              if(lp->llc_callbacks)
+-              {
+-                      lp->llc_event(lp);
+-                      lp->llc_callbacks=0;
+-              }
+-              /*
+-               *      lp may be invalid after the callback
+-               */
+-      }
+-}
+-
+-
+-/*
+- *    Connect_request() requests that the llc to start a connection
+- */
+-
+-void connect_request(llcptr lp)
+-{
+-      if (lp->state == ADM)
+-      {
+-              lp->state = SETUP;
+-              llc_interpret_pseudo_code(lp, ADM1, NULL, NO_FRAME);
+-              if(lp->llc_callbacks)
+-              {
+-                      lp->llc_event(lp);
+-                      lp->llc_callbacks=0;
+-              }
+-              /*
+-               *      lp may be invalid after the callback
+-               */
+-      }
+-}
+-
+-
+-/*
+- *    Interpret_pseudo_code() executes the actions in the connection component
+- *    state transition table. Table 4 in document on p88.
+- *
+- *    If this function is called to handle an incomming pdu, skb will point
+- *    to the buffer with the pdu and type will contain the decoded pdu type.
+- *
+- *    If called by data_request skb points to an skb that was skb_alloc-ed by 
+- *    the llc client to hold the information unit to be transmitted, there is
+- *    no valid type in this case.  
+- *
+- *    If called because a timer expired no skb is passed, and there is no 
+- *    type.
+- */
+-
+-void llc_interpret_pseudo_code(llcptr lp, int pc_label, struct sk_buff *skb, 
+-              char type)
+-{    
+-      short int pc;   /* program counter in pseudo code array */ 
+-      char p_flag_received;
+-      frameptr fr;
+-      int resend_count;   /* number of pdus resend by llc_resend_ipdu() */
+-      int ack_count;      /* number of pdus acknowledged */
+-      struct sk_buff *skb2;
+-
+-      if (skb != NULL) 
+-      {
+-              fr = (frameptr) skb->data;
+-      }
+-      else
+-              fr = NULL;
+-
+-      pc = pseudo_code_idx[pc_label];
+-      while(pseudo_code[pc])
+-      {
+-              switch(pseudo_code[pc])
+-              {
+-                      case 9:
+-                              if ((type != I_CMD) || (fr->i_hdr.i_pflag == 0))
+-                                      break;
+-                      case 1:
+-                              lp->remote_busy = 0;
+-                              llc_stop_timer(lp, BUSY_TIMER);
+-                              if ((lp->state == NORMAL) ||
+-                                      (lp->state == REJECT) ||
+-                                      (lp->state == BUSY))
+-                              {
+-                                      skb2 = llc_pull_from_atq(lp);
+-                                      if (skb2 != NULL) 
+-                                              llc_start_timer(lp, ACK_TIMER);
+-                                      while (skb2 != NULL)
+-                                      {
+-                                              llc_sendipdu( lp, I_CMD, 0, skb2);
+-                                              skb2 = llc_pull_from_atq(lp);
+-                                      }
+-                              }          
+-                              break;
+-                      case 2:
+-                              lp->state = NORMAL;  /* needed to eliminate connect_response() */
+-                              lp->llc_mode = MODE_ABM;
+-                              lp->llc_callbacks|=LLC_CONN_INDICATION;
+-                              break;
+-                      case 3:
+-                              lp->llc_mode = MODE_ABM;
+-                              lp->llc_callbacks|=LLC_CONN_CONFIRM;
+-                              break;
+-                      case 4:
+-                              skb_pull(skb, 4);
+-                              lp->inc_skb=skb;
+-                              lp->llc_callbacks|=LLC_DATA_INDIC;
+-                              break;
+-                      case 5:
+-                              lp->llc_mode = MODE_ADM;
+-                              lp->llc_callbacks|=LLC_DISC_INDICATION;
+-                              break;
+-                      case 70:
+-                              lp->llc_callbacks|=LLC_RESET_INDIC_LOC;
+-                              break;
+-                      case 71:
+-                              lp->llc_callbacks|=LLC_RESET_INDIC_REM;
+-                              break;
+-                      case 7:
+-                              lp->llc_callbacks|=LLC_RST_CONFIRM;
+-                              break;
+-                      case 66:
+-                              lp->llc_callbacks|=LLC_FRMR_RECV;
+-                              break;
+-                      case 67:
+-                              lp->llc_callbacks|=LLC_FRMR_SENT;
+-                              break;
+-                      case 68:
+-                              lp->llc_callbacks|=LLC_REMOTE_BUSY;
+-                              break;
+-                      case 69:
+-                              lp->llc_callbacks|=LLC_REMOTE_NOTBUSY;
+-                              break;
+-                      case 11:
+-                              llc_sendpdu(lp, DISC_CMD, lp->f_flag, 0, NULL);
+-                              break;
+-                      case 12:
+-                              llc_sendpdu(lp, DM_RSP, 0, 0, NULL);
+-                              break;
+-                      case 13:                        
+-                              lp->frmr_info_fld.cntl1 = fr->pdu_cntl.byte1;
+-                              lp->frmr_info_fld.cntl2 = fr->pdu_cntl.byte2;
+-                              lp->frmr_info_fld.vs = lp->vs;
+-                              lp->frmr_info_fld.vr_cr = lp->vr;
+-                              llc_sendpdu(lp, FRMR_RSP, 0, 5, (char *) &lp->frmr_info_fld);
+-                              break;
+-                      case 14:
+-                              llc_sendpdu(lp, FRMR_RSP, 0, 5, (char *) &lp->frmr_info_fld);
+-                              break;
+-                      case 15:
+-                              llc_sendpdu(lp, FRMR_RSP, lp->p_flag,
+-                                      5, (char *) &lp->frmr_info_fld);
+-                              break;
+-                      case 16:
+-                              llc_sendipdu(lp, I_CMD, 1, skb);   
+-                              break;
+-                      case 17:
+-                              resend_count = llc_resend_ipdu(lp, fr->i_hdr.nr, I_CMD, 1);
+-                              break;
+-                      case 18:
+-                              resend_count = llc_resend_ipdu(lp, fr->i_hdr.nr, I_CMD, 1);
+-                              if (resend_count == 0) 
+-                              {
+-                                      llc_sendpdu(lp, RR_CMD, 1, 0, NULL);
+-                              }    
+-                              break;
+-                      case 19:
+-                              llc_sendipdu(lp, I_CMD, 0, skb);   
+-                              break;
+-                      case 20:
+-                              resend_count = llc_resend_ipdu(lp, fr->i_hdr.nr, I_CMD, 0);
+-                              break;
+-                      case 21:
+-                              resend_count = llc_resend_ipdu(lp, fr->i_hdr.nr, I_CMD, 0);
+-                              if (resend_count == 0) 
+-                              {
+-                                      llc_sendpdu(lp, RR_CMD, 0, 0, NULL);
+-                              }    
+-                              break;
+-                      case 22:
+-                              resend_count = llc_resend_ipdu(lp, fr->i_hdr.nr, I_RSP, 1);
+-                              break;
+-                      case 23:
+-                              llc_sendpdu(lp, REJ_CMD, 1, 0, NULL);
+-                              break;
+-                      case 24:
+-                              llc_sendpdu(lp, REJ_RSP, 1, 0, NULL);
+-                              break;
+-                      case 25:
+-                              if (IS_RSP(fr))
+-                                      llc_sendpdu(lp, REJ_CMD, 0, 0, NULL);
+-                              else
+-                                      llc_sendpdu(lp, REJ_RSP, 0, 0, NULL);
+-                              break;
+-                      case 26:
+-                              llc_sendpdu(lp, RNR_CMD, 1, 0, NULL);
+-                              break;
+-                      case 27:
+-                              llc_sendpdu(lp, RNR_RSP, 1, 0, NULL);
+-                              break;
+-                      case 28:
+-                              if (IS_RSP(fr))
+-                                      llc_sendpdu(lp, RNR_CMD, 0, 0, NULL);
+-                              else
+-                                      llc_sendpdu(lp, RNR_RSP, 0, 0, NULL);
+-                              break;
+-                      case 29:
+-                              if (lp->remote_busy == 0)
+-                              {
+-                                      lp->remote_busy = 1;
+-                                      llc_start_timer(lp, BUSY_TIMER);
+-                                      lp->llc_callbacks|=LLC_REMOTE_BUSY;
+-                              }
+-                              else if (lp->timer_state[BUSY_TIMER] == TIMER_IDLE)
+-                              {
+-                                      llc_start_timer(lp, BUSY_TIMER);
+-                              }
+-                              break;
+-                      case 30:
+-                              if (IS_RSP(fr)) 
+-                                      llc_sendpdu(lp, RNR_CMD, 0, 0, NULL);
+-                              else
+-                                      llc_sendpdu(lp, RNR_RSP, 0, 0, NULL);
+-                              break;
+-                      case 31:
+-                              llc_sendpdu(lp, RR_CMD, 1, 0, NULL);
+-                              break;
+-                      case 32:
+-                              llc_sendpdu(lp, RR_CMD, 1, 0, NULL);
+-                              break;
+-                      case 33:
+-                              llc_sendpdu(lp, RR_RSP, 1, 0, NULL);
+-                              break;
+-                      case 34:
+-                              llc_sendpdu(lp, RR_RSP, 1, 0, NULL);
+-                              break;
+-                      case 35:
+-                              llc_sendpdu(lp, RR_RSP, 0, 0, NULL);
+-                              break;
+-                      case 36:
+-                              if (IS_RSP(fr)) 
+-                                      llc_sendpdu(lp, RR_CMD, 0, 0, NULL);
+-                              else
+-                                      llc_sendpdu(lp, RR_RSP, 0, 0, NULL);
+-                              break;
+-                      case 37:
+-                              llc_sendpdu(lp, SABME_CMD, 0, 0, NULL);
+-                              lp->f_flag = 0;
+-                              break;
+-                      case 38:
+-                              llc_sendpdu(lp, UA_RSP, lp->f_flag, 0, NULL);
+-                              break;
+-                      case 39:
+-                              lp->s_flag = 0;
+-                              break;
+-                      case 40:
+-                              lp->s_flag = 1;
+-                              break;
+-                      case 41:
+-                              if(lp->timer_state[P_TIMER] == TIMER_RUNNING)
+-                                      llc_stop_timer(lp, P_TIMER);
+-                              llc_start_timer(lp, P_TIMER);
+-                              if (lp->p_flag == 0)
+-                              {
+-                                      lp->retry_count = 0;
+-                                      lp->p_flag = 1;
+-                              }
+-                              break;
+-                      case 44:
+-                              if (lp->timer_state[ACK_TIMER] == TIMER_IDLE)
+-                                      llc_start_timer(lp, ACK_TIMER);
+-                              break;
+-                      case 42:
+-                              llc_start_timer(lp, ACK_TIMER);
+-                              break;
+-                      case 43:
+-                              llc_start_timer(lp, REJ_TIMER);
+-                              break;
+-                      case 45:
+-                              llc_stop_timer(lp, ACK_TIMER);
+-                              break;
+-                      case 46:
+-                              llc_stop_timer(lp, ACK_TIMER);
+-                              lp->p_flag = 0;
+-                              break;
+-                      case 10:
+-                              if (lp->data_flag == 2)
+-                                      llc_stop_timer(lp, REJ_TIMER);
+-                              break;
+-                      case 47:
+-                              llc_stop_timer(lp, REJ_TIMER);
+-                              break;
+-                      case 48:
+-                              llc_stop_timer(lp, ACK_TIMER);
+-                              llc_stop_timer(lp, P_TIMER);
+-                              llc_stop_timer(lp, REJ_TIMER);
+-                              llc_stop_timer(lp, BUSY_TIMER);
+-                              break;
+-                      case 49:
+-                              llc_stop_timer(lp, P_TIMER);
+-                              llc_stop_timer(lp, REJ_TIMER);
+-                              llc_stop_timer(lp, BUSY_TIMER);
+-                              break;
+-                      case 50:             
+-                              ack_count = llc_free_acknowledged_skbs(lp,
+-                                      (unsigned char) fr->s_hdr.nr);
+-                              if (ack_count > 0)
+-                              {
+-                                      lp->retry_count = 0;
+-                                      llc_stop_timer(lp, ACK_TIMER);  
+-                                      if (skb_peek(&lp->rtq) != NULL)
+-                                      {
+-                                              /*
+-                                               *      Re-transmit queue not empty 
+-                                               */
+-                                              llc_start_timer(lp, ACK_TIMER);  
+-                                      }
+-                              }        
+-                              break;
+-                      case 51:
+-                              if (IS_UFRAME(fr)) 
+-                                      p_flag_received = fr->u_hdr.u_pflag;
+-                              else
+-                                      p_flag_received = fr->i_hdr.i_pflag;
+-                              if ((fr->pdu_hdr.ssap & 0x01) && (p_flag_received))
+-                              {
+-                                      lp->p_flag = 0;
+-                                      llc_stop_timer(lp, P_TIMER);  
+-                              }
+-                              break;
+-                      case 52:
+-                              lp->data_flag = 2;
+-                              break;
+-                      case 53:
+-                              lp->data_flag = 0;
+-                              break;
+-                      case 54:
+-                              lp->data_flag = 1;
+-                              break;
+-                      case 55:
+-                              if (lp->data_flag == 0)
+-                                      lp->data_flag = 1;
+-                              break;
+-                      case 56:
+-                              lp->p_flag = 0;
+-                              break;
+-                      case 57:
+-                              lp->p_flag = lp->f_flag;
+-                              break;
+-                      case 58:
+-                              lp->remote_busy = 0;
+-                              break;
+-                      case 59:
+-                              lp->retry_count = 0;
+-                              break;
+-                      case 60:
+-                              lp->retry_count++;
+-                              break;
+-                      case 61:
+-                              lp->vr = 0;
+-                              break;
+-                      case 62:
+-                              lp->vr++;
+-                              break;
+-                      case 63:
+-                              lp->vs = 0;
+-                              break;
+-                      case 64:
+-                              lp->vs = fr->i_hdr.nr;
+-                              break;
+-                      case 65:
+-                              if (IS_UFRAME(fr)) 
+-                                      lp->f_flag = fr->u_hdr.u_pflag;
+-                              else
+-                                      lp->f_flag = fr->i_hdr.i_pflag;
+-                              break;
+-                      default:
+-              }
+-              pc++;   
+-      }
+-}
+-
+-
+-/*
+- *    Process_otype2_frame will handle incoming frames
+- *    for 802.2 Type 2 Procedure.
+- */
+-
+-void llc_process_otype2_frame(llcptr lp, struct sk_buff *skb, char type)
+-{
+-      int idx;                /*      index in transition table */
+-      int pc_label;           /*      action to perform, from tr tbl */
+-      int validation;         /*      result of validate_seq_nos */
+-      int p_flag_received;    /*      p_flag in received frame */
+-      frameptr fr;
+-
+-      fr = (frameptr) skb->data;
+-
+-      if (IS_UFRAME(fr))
+-              p_flag_received = fr->u_hdr.u_pflag;
+-      else
+-              p_flag_received = fr->i_hdr.i_pflag;
+-
+-      switch(lp->state)
+-      {
+-              /*      Compute index in transition table: */
+-              case ADM:
+-                      idx = type;
+-                      idx = (idx << 1) + p_flag_received;
+-                      break;
+-              case CONN:
+-              case RESET_WAIT:
+-              case RESET_CHECK:
+-              case ERROR:
+-                      idx = type;
+-                      break;
+-              case SETUP:
+-              case RESET:
+-              case D_CONN:
+-                      idx = type;
+-                      idx = (idx << 1) + lp->p_flag;
+-                      break;
+-              case NORMAL:
+-              case BUSY:
+-              case REJECT:
+-              case AWAIT:
+-              case AWAIT_BUSY:
+-              case AWAIT_REJECT:
+-                      validation = llc_validate_seq_nos(lp, fr);
+-                      if (validation > 3) 
+-                              type = BAD_FRAME;
+-                      idx = type;
+-                      idx = (idx << 1);
+-                      if (validation & 1) 
+-                              idx = idx +1;
+-                      idx = (idx << 1) + p_flag_received;
+-                      idx = (idx << 1) + lp->p_flag;
+-              default:
+-                      printk("llc_proc: bad state\n");
+-                      return;
+-      }
+-      idx = (idx << 1) + pdutr_offset[lp->state];
+-      lp->state = pdutr_entry[idx +1]; 
+-      pc_label = pdutr_entry[idx];
+-      if (pc_label != 0)
+-      { 
+-              llc_interpret_pseudo_code(lp, pc_label, skb, type);
+-              if(lp->llc_callbacks)
+-              {
+-                      lp->llc_event(lp);
+-                      lp->llc_callbacks=0;
+-              }
+-              /*
+-               *      lp may no longer be valid after this point. Be
+-               *      careful what is added!
+-               */
+-      }
+-}
+-
+-
+-void llc_timer_expired(llcptr lp, int t)
+-{
+-      int idx;                /* index in transition table    */
+-      int pc_label;           /* action to perform, from tr tbl */
+-
+-      lp->timer_state[t] = TIMER_EXPIRED;
+-      idx = lp->state;            /* Compute index in transition table: */
+-      idx = (idx << 2) + t;
+-      idx = idx << 1;
+-      if (lp->retry_count >= lp->n2) 
+-              idx = idx + 1;
+-      idx = (idx << 1) + lp->s_flag;
+-      idx = (idx << 1) + lp->p_flag;
+-      idx = idx << 1;             /* 2 bytes per entry: action & newstate */
+-
+-      pc_label = timertr_entry[idx];
+-      if (pc_label != 0)
+-      {
+-              llc_interpret_pseudo_code(lp, pc_label, NULL, NO_FRAME);
+-              lp->state = timertr_entry[idx +1];
+-      }
+-      lp->timer_state[t] = TIMER_IDLE;
+-      if(lp->llc_callbacks)
+-      {
+-              lp->llc_event(lp);
+-              lp->llc_callbacks=0;
+-      }
+-      /*
+-       *      And lp may have vanished in the event callback
+-       */
+-}
+-
+diff -uNr linux/net/802/cl2llc.pre linux-llc/net/802/cl2llc.pre
+--- linux/net/802/cl2llc.pre   Sat Nov 29 18:41:10 1997
++++ linux-llc/net/802/cl2llc.pre       Thu Jan  1 01:00:00 1970
+@@ -1,615 +0,0 @@
+-/*
+- * NET                An implementation of the IEEE 802.2 LLC protocol for the
+- *            LINUX operating system.  LLC is implemented as a set of 
+- *            state machines and callbacks for higher networking layers.
+- *
+- *            Class 2 llc algorithm.
+- *            Pseudocode interpreter, transition table lookup,
+- *                    data_request & indicate primitives...
+- *
+- *            Code for initialization, termination, registration and 
+- *            MAC layer glue.
+- *
+- *            Copyright Tim Alpaerts, 
+- *                    <Tim_Alpaerts@toyota-motor-europe.com>
+- *
+- *            This program is free software; you can redistribute it and/or
+- *            modify it under the terms of the GNU General Public License
+- *            as published by the Free Software Foundation; either version
+- *            2 of the License, or (at your option) any later version.
+- *
+- *    Changes
+- *            Alan Cox        :       Chainsawed into Linux format
+- *                                    Modified to use llc_ names
+- *                                    Changed callbacks
+- *
+- *    This file must be processed by sed before it can be compiled.
+- */
+-
+-#include <linux/types.h>
+-#include <linux/kernel.h>
+-#include <linux/malloc.h>
+-#include <linux/netdevice.h>
+-#include <linux/skbuff.h>
+-#include <net/p8022.h>
+-#include <linux/proc_fs.h>
+-#include <linux/stat.h>
+-#include <asm/byteorder.h>
+-
+-#include "pseudo/pseudocode.h"
+-#include "transit/pdutr.h"
+-#include "transit/timertr.h"
+-#include <net/llc_frame.h>
+-#include <net/llc.h>
+-
+-/*
+- *    Data_request() is called by the client to present a data unit
+- *    to the llc for transmission.
+- *    In the future this function should also check if the transmit window
+- *    allows the sending of another pdu, and if not put the skb on the atq
+- *    for deferred sending.
+- */
+-
+-int llc_data_request(llcptr lp, struct sk_buff *skb)
+-{
+-      if (skb_headroom(skb) < (lp->dev->hard_header_len +4)){
+-              printk("cl2llc: data_request() not enough headroom in skb\n");
+-              return -1;
+-      };
+-
+-      skb_push(skb, 4);
+-
+-      if ((lp->state != NORMAL) && (lp->state != BUSY) && (lp->state != REJECT))
+-      {
+-              printk("cl2llc: data_request() while no llc connection\n"); 
+-              return -1;  
+-      }
+-
+-      if (lp->remote_busy)
+-      {     /* if the remote llc is BUSY, */
+-              ADD_TO_ATQ(skb);      /* save skb in the await transmit queue */
+-              return 0;
+-      }                           
+-      else
+-      {
+-              /*
+-               *      Else proceed with xmit 
+-               */
+-
+-              switch(lp->state)
+-              {
+-                      case NORMAL:
+-                              if(lp->p_flag)
+-                                      llc_interpret_pseudo_code(lp, NORMAL2, skb, NO_FRAME);
+-                              else
+-                                      llc_interpret_pseudo_code(lp, NORMAL1, skb, NO_FRAME);
+-                              break;
+-                      case BUSY:
+-                              if (lp->p_flag)
+-                                      llc_interpret_pseudo_code(lp, BUSY2, skb, NO_FRAME);
+-                              else
+-                                      llc_interpret_pseudo_code(lp, BUSY1, skb, NO_FRAME);
+-                              break;
+-                      case REJECT:
+-                              if (lp->p_flag)
+-                                      llc_interpret_pseudo_code(lp, REJECT2, skb, NO_FRAME);
+-                              else
+-                                      llc_interpret_pseudo_code(lp, REJECT1, skb, NO_FRAME);
+-                              break;
+-                      default:
+-              }
+-              if(lp->llc_callbacks)
+-              {
+-                      lp->llc_event(lp);
+-                      lp->llc_callbacks=0;
+-              }
+-              return 0;  
+-      }              
+-}
+-
+-
+-
+-/* 
+- *    Disconnect_request() requests that the llc to terminate a connection
+- */
+-
+-void disconnect_request(llcptr lp)
+-{
+-      if ((lp->state == NORMAL) ||
+-              (lp->state == BUSY) ||
+-              (lp->state == REJECT) ||
+-              (lp->state == AWAIT) ||
+-              (lp->state == AWAIT_BUSY) ||
+-              (lp->state == AWAIT_REJECT))
+-      {
+-              lp->state = D_CONN;
+-              llc_interpret_pseudo_code(lp, SH1, NULL, NO_FRAME);
+-              if(lp->llc_callbacks)
+-              {
+-                      lp->llc_event(lp);
+-                      lp->llc_callbacks=0;
+-              }
+-              /*
+-               *      lp may be invalid after the callback
+-               */
+-      }
+-}
+-
+-
+-/*
+- *    Connect_request() requests that the llc to start a connection
+- */
+-
+-void connect_request(llcptr lp)
+-{
+-      if (lp->state == ADM)
+-      {
+-              lp->state = SETUP;
+-              llc_interpret_pseudo_code(lp, ADM1, NULL, NO_FRAME);
+-              if(lp->llc_callbacks)
+-              {
+-                      lp->llc_event(lp);
+-                      lp->llc_callbacks=0;
+-              }
+-              /*
+-               *      lp may be invalid after the callback
+-               */
+-      }
+-}
+-
+-
+-/*
+- *    Interpret_pseudo_code() executes the actions in the connection component
+- *    state transition table. Table 4 in document on p88.
+- *
+- *    If this function is called to handle an incomming pdu, skb will point
+- *    to the buffer with the pdu and type will contain the decoded pdu type.
+- *
+- *    If called by data_request skb points to an skb that was skb_alloc-ed by 
+- *    the llc client to hold the information unit to be transmitted, there is
+- *    no valid type in this case.  
+- *
+- *    If called because a timer expired no skb is passed, and there is no 
+- *    type.
+- */
+-
+-void llc_interpret_pseudo_code(llcptr lp, int pc_label, struct sk_buff *skb, 
+-              char type)
+-{    
+-      short int pc;   /* program counter in pseudo code array */ 
+-      char p_flag_received;
+-      frameptr fr;
+-      int resend_count;   /* number of pdus resend by llc_resend_ipdu() */
+-      int ack_count;      /* number of pdus acknowledged */
+-      struct sk_buff *skb2;
+-
+-      if (skb != NULL) 
+-      {
+-              fr = (frameptr) skb->data;
+-      }
+-      else
+-              fr = NULL;
+-
+-      pc = pseudo_code_idx[pc_label];
+-      while(pseudo_code[pc])
+-      {
+-              switch(pseudo_code[pc])
+-              {
+-                      case IF_F=1_CLEAR_REMOTE_BUSY:
+-                              if ((type != I_CMD) || (fr->i_hdr.i_pflag == 0))
+-                                      break;
+-                      case CLEAR_REMOTE_BUSY:
+-                              lp->remote_busy = 0;
+-                              llc_stop_timer(lp, BUSY_TIMER);
+-                              if ((lp->state == NORMAL) ||
+-                                      (lp->state == REJECT) ||
+-                                      (lp->state == BUSY))
+-                              {
+-                                      skb2 = llc_pull_from_atq(lp);
+-                                      if (skb2 != NULL) 
+-                                              llc_start_timer(lp, ACK_TIMER);
+-                                      while (skb2 != NULL)
+-                                      {
+-                                              llc_sendipdu( lp, I_CMD, 0, skb2);
+-                                              skb2 = llc_pull_from_atq(lp);
+-                                      }
+-                              }          
+-                              break;
+-                      case CONNECT_INDICATION:
+-                              lp->state = NORMAL;  /* needed to eliminate connect_response() */
+-                              lp->llc_mode = MODE_ABM;
+-                              lp->llc_callbacks|=LLC_CONN_INDICATION;
+-                              break;
+-                      case CONNECT_CONFIRM:
+-                              lp->llc_mode = MODE_ABM;
+-                              lp->llc_callbacks|=LLC_CONN_CONFIRM;
+-                              break;
+-                      case DATA_INDICATION:
+-                              skb_pull(skb, 4);
+-                              lp->inc_skb=skb;
+-                              lp->llc_callbacks|=LLC_DATA_INDIC;
+-                              break;
+-                      case DISCONNECT_INDICATION:
+-                              lp->llc_mode = MODE_ADM;
+-                              lp->llc_callbacks|=LLC_DISC_INDICATION;
+-                              break;
+-                      case RESET_INDICATION(LOCAL):
+-                              lp->llc_callbacks|=LLC_RESET_INDIC_LOC;
+-                              break;
+-                      case RESET_INDICATION(REMOTE):
+-                              lp->llc_callbacks|=LLC_RESET_INDIC_REM;
+-                              break;
+-                      case RESET_CONFIRM:
+-                              lp->llc_callbacks|=LLC_RST_CONFIRM;
+-                              break;
+-                      case REPORT_STATUS(FRMR_RECEIVED):
+-                              lp->llc_callbacks|=LLC_FRMR_RECV;
+-                              break;
+-                      case REPORT_STATUS(FRMR_SENT):
+-                              lp->llc_callbacks|=LLC_FRMR_SENT;
+-                              break;
+-                      case REPORT_STATUS(REMOTE_BUSY):
+-                              lp->llc_callbacks|=LLC_REMOTE_BUSY;
+-                              break;
+-                      case REPORT_STATUS(REMOTE_NOT_BUSY):
+-                              lp->llc_callbacks|=LLC_REMOTE_NOTBUSY;
+-                              break;
+-                      case SEND_DISC_CMD(P=X):
+-                              llc_sendpdu(lp, DISC_CMD, lp->f_flag, 0, NULL);
+-                              break;
+-                      case SEND_DM_RSP(F=X):
+-                              llc_sendpdu(lp, DM_RSP, 0, 0, NULL);
+-                              break;
+-                      case SEND_FRMR_RSP(F=X):                        
+-                              lp->frmr_info_fld.cntl1 = fr->pdu_cntl.byte1;
+-                              lp->frmr_info_fld.cntl2 = fr->pdu_cntl.byte2;
+-                              lp->frmr_info_fld.vs = lp->vs;
+-                              lp->frmr_info_fld.vr_cr = lp->vr;
+-                              llc_sendpdu(lp, FRMR_RSP, 0, 5, (char *) &lp->frmr_info_fld);
+-                              break;
+-                      case RE-SEND_FRMR_RSP(F=0):
+-                              llc_sendpdu(lp, FRMR_RSP, 0, 5, (char *) &lp->frmr_info_fld);
+-                              break;
+-                      case RE-SEND_FRMR_RSP(F=P):
+-                              llc_sendpdu(lp, FRMR_RSP, lp->p_flag,
+-                                      5, (char *) &lp->frmr_info_fld);
+-                              break;
+-                      case SEND_I_CMD(P=1):
+-                              llc_sendipdu(lp, I_CMD, 1, skb);   
+-                              break;
+-                      case RE-SEND_I_CMD(P=1):
+-                              resend_count = llc_resend_ipdu(lp, fr->i_hdr.nr, I_CMD, 1);
+-                              break;
+-                      case RE-SEND_I_CMD(P=1)_OR_SEND_RR:
+-                              resend_count = llc_resend_ipdu(lp, fr->i_hdr.nr, I_CMD, 1);
+-                              if (resend_count == 0) 
+-                              {
+-                                      llc_sendpdu(lp, RR_CMD, 1, 0, NULL);
+-                              }    
+-                              break;
+-                      case SEND_I_XXX(X=0):
+-                              llc_sendipdu(lp, I_CMD, 0, skb);   
+-                              break;
+-                      case RE-SEND_I_XXX(X=0):
+-                              resend_count = llc_resend_ipdu(lp, fr->i_hdr.nr, I_CMD, 0);
+-                              break;
+-                      case RE-SEND_I_XXX(X=0)_OR_SEND_RR:
+-                              resend_count = llc_resend_ipdu(lp, fr->i_hdr.nr, I_CMD, 0);
+-                              if (resend_count == 0) 
+-                              {
+-                                      llc_sendpdu(lp, RR_CMD, 0, 0, NULL);
+-                              }    
+-                              break;
+-                      case RE-SEND_I_RSP(F=1):
+-                              resend_count = llc_resend_ipdu(lp, fr->i_hdr.nr, I_RSP, 1);
+-                              break;
+-                      case SEND_REJ_CMD(P=1):
+-                              llc_sendpdu(lp, REJ_CMD, 1, 0, NULL);
+-                              break;
+-                      case SEND_REJ_RSP(F=1):
+-                              llc_sendpdu(lp, REJ_RSP, 1, 0, NULL);
+-                              break;
+-                      case SEND_REJ_XXX(X=0):
+-                              if (IS_RSP(fr))
+-                                      llc_sendpdu(lp, REJ_CMD, 0, 0, NULL);
+-                              else
+-                                      llc_sendpdu(lp, REJ_RSP, 0, 0, NULL);
+-                              break;
+-                      case SEND_RNR_CMD(F=1):
+-                              llc_sendpdu(lp, RNR_CMD, 1, 0, NULL);
+-                              break;
+-                      case SEND_RNR_RSP(F=1):
+-                              llc_sendpdu(lp, RNR_RSP, 1, 0, NULL);
+-                              break;
+-                      case SEND_RNR_XXX(X=0):
+-                              if (IS_RSP(fr))
+-                                      llc_sendpdu(lp, RNR_CMD, 0, 0, NULL);
+-                              else
+-                                      llc_sendpdu(lp, RNR_RSP, 0, 0, NULL);
+-                              break;
+-                      case SET_REMOTE_BUSY:
+-                              if (lp->remote_busy == 0)
+-                              {
+-                                      lp->remote_busy = 1;
+-                                      llc_start_timer(lp, BUSY_TIMER);
+-                                      lp->llc_callbacks|=LLC_REMOTE_BUSY;
+-                              }
+-                              else if (lp->timer_state[BUSY_TIMER] == TIMER_IDLE)
+-                              {
+-                                      llc_start_timer(lp, BUSY_TIMER);
+-                              }
+-                              break;
+-                      case OPTIONAL_SEND_RNR_XXX(X=0):
+-                              if (IS_RSP(fr)) 
+-                                      llc_sendpdu(lp, RNR_CMD, 0, 0, NULL);
+-                              else
+-                                      llc_sendpdu(lp, RNR_RSP, 0, 0, NULL);
+-                              break;
+-                      case SEND_RR_CMD(P=1):
+-                              llc_sendpdu(lp, RR_CMD, 1, 0, NULL);
+-                              break;
+-                      case SEND_ACKNOWLEDGE_CMD(P=1):
+-                              llc_sendpdu(lp, RR_CMD, 1, 0, NULL);
+-                              break;
+-                      case SEND_RR_RSP(F=1):
+-                              llc_sendpdu(lp, RR_RSP, 1, 0, NULL);
+-                              break;
+-                      case SEND_ACKNOWLEDGE_RSP(F=1):
+-                              llc_sendpdu(lp, RR_RSP, 1, 0, NULL);
+-                              break;
+-                      case SEND_RR_XXX(X=0):
+-                              llc_sendpdu(lp, RR_RSP, 0, 0, NULL);
+-                              break;
+-                      case SEND_ACKNOWLEDGE_XXX(X=0):
+-                              if (IS_RSP(fr)) 
+-                                      llc_sendpdu(lp, RR_CMD, 0, 0, NULL);
+-                              else
+-                                      llc_sendpdu(lp, RR_RSP, 0, 0, NULL);
+-                              break;
+-                      case SEND_SABME_CMD(P=X):
+-                              llc_sendpdu(lp, SABME_CMD, 0, 0, NULL);
+-                              lp->f_flag = 0;
+-                              break;
+-                      case SEND_UA_RSP(F=X):
+-                              llc_sendpdu(lp, UA_RSP, lp->f_flag, 0, NULL);
+-                              break;
+-                      case S_FLAG:=0:
+-                              lp->s_flag = 0;
+-                              break;
+-                      case S_FLAG:=1:
+-                              lp->s_flag = 1;
+-                              break;
+-                      case START_P_TIMER:
+-                              if(lp->timer_state[P_TIMER] == TIMER_RUNNING)
+-                                      llc_stop_timer(lp, P_TIMER);
+-                              llc_start_timer(lp, P_TIMER);
+-                              if (lp->p_flag == 0)
+-                              {
+-                                      lp->retry_count = 0;
+-                                      lp->p_flag = 1;
+-                              }
+-                              break;
+-                      case START_ACK_TIMER_IF_NOT_RUNNING:
+-                              if (lp->timer_state[ACK_TIMER] == TIMER_IDLE)
+-                                      llc_start_timer(lp, ACK_TIMER);
+-                              break;
+-                      case START_ACK_TIMER:
+-                              llc_start_timer(lp, ACK_TIMER);
+-                              break;
+-                      case START_REJ_TIMER:
+-                              llc_start_timer(lp, REJ_TIMER);
+-                              break;
+-                      case STOP_ACK_TIMER:
+-                              llc_stop_timer(lp, ACK_TIMER);
+-                              break;
+-                      case STOP_P_TIMER:
+-                              llc_stop_timer(lp, ACK_TIMER);
+-                              lp->p_flag = 0;
+-                              break;
+-                      case IF_DATA_FLAG=2_STOP_REJ_TIMER:
+-                              if (lp->data_flag == 2)
+-                                      llc_stop_timer(lp, REJ_TIMER);
+-                              break;
+-                      case STOP_REJ_TIMER:
+-                              llc_stop_timer(lp, REJ_TIMER);
+-                              break;
+-                      case STOP_ALL_TIMERS:
+-                              llc_stop_timer(lp, ACK_TIMER);
+-                              llc_stop_timer(lp, P_TIMER);
+-                              llc_stop_timer(lp, REJ_TIMER);
+-                              llc_stop_timer(lp, BUSY_TIMER);
+-                              break;
+-                      case STOP_OTHER_TIMERS:
+-                              llc_stop_timer(lp, P_TIMER);
+-                              llc_stop_timer(lp, REJ_TIMER);
+-                              llc_stop_timer(lp, BUSY_TIMER);
+-                              break;
+-                      case UPDATE_N(R)_RECEIVED:             
+-                              ack_count = llc_free_acknowledged_skbs(lp,
+-                                      (unsigned char) fr->s_hdr.nr);
+-                              if (ack_count > 0)
+-                              {
+-                                      lp->retry_count = 0;
+-                                      llc_stop_timer(lp, ACK_TIMER);  
+-                                      if (skb_peek(&lp->rtq) != NULL)
+-                                      {
+-                                              /*
+-                                               *      Re-transmit queue not empty 
+-                                               */
+-                                              llc_start_timer(lp, ACK_TIMER);  
+-                                      }
+-                              }        
+-                              break;
+-                      case UPDATE_P_FLAG:
+-                              if (IS_UFRAME(fr)) 
+-                                      p_flag_received = fr->u_hdr.u_pflag;
+-                              else
+-                                      p_flag_received = fr->i_hdr.i_pflag;
+-                              if ((fr->pdu_hdr.ssap & 0x01) && (p_flag_received))
+-                              {
+-                                      lp->p_flag = 0;
+-                                      llc_stop_timer(lp, P_TIMER);  
+-                              }
+-                              break;
+-                      case DATA_FLAG:=2:
+-                              lp->data_flag = 2;
+-                              break;
+-                      case DATA_FLAG:=0:
+-                              lp->data_flag = 0;
+-                              break;
+-                      case DATA_FLAG:=1:
+-                              lp->data_flag = 1;
+-                              break;
+-                      case IF_DATA_FLAG_=0_THEN_DATA_FLAG:=1:
+-                              if (lp->data_flag == 0)
+-                                      lp->data_flag = 1;
+-                              break;
+-                      case P_FLAG:=0:
+-                              lp->p_flag = 0;
+-                              break;
+-                      case P_FLAG:=P:
+-                              lp->p_flag = lp->f_flag;
+-                              break;
+-                      case REMOTE_BUSY:=0:
+-                              lp->remote_busy = 0;
+-                              break;
+-                      case RETRY_COUNT:=0:
+-                              lp->retry_count = 0;
+-                              break;
+-                      case RETRY_COUNT:=RETRY_COUNT+1:
+-                              lp->retry_count++;
+-                              break;
+-                      case V(R):=0:
+-                              lp->vr = 0;
+-                              break;
+-                      case V(R):=V(R)+1:
+-                              lp->vr++;
+-                              break;
+-                      case V(S):=0:
+-                              lp->vs = 0;
+-                              break;
+-                      case V(S):=N(R):
+-                              lp->vs = fr->i_hdr.nr;
+-                              break;
+-                      case F_FLAG:=P:
+-                              if (IS_UFRAME(fr)) 
+-                                      lp->f_flag = fr->u_hdr.u_pflag;
+-                              else
+-                                      lp->f_flag = fr->i_hdr.i_pflag;
+-                              break;
+-                      default:
+-              }
+-              pc++;   
+-      }
+-}
+-
+-
+-/*
+- *    Process_otype2_frame will handle incoming frames
+- *    for 802.2 Type 2 Procedure.
+- */
+-
+-void llc_process_otype2_frame(llcptr lp, struct sk_buff *skb, char type)
+-{
+-      int idx;                /*      index in transition table */
+-      int pc_label;           /*      action to perform, from tr tbl */
+-      int validation;         /*      result of validate_seq_nos */
+-      int p_flag_received;    /*      p_flag in received frame */
+-      frameptr fr;
+-
+-      fr = (frameptr) skb->data;
+-
+-      if (IS_UFRAME(fr))
+-              p_flag_received = fr->u_hdr.u_pflag;
+-      else
+-              p_flag_received = fr->i_hdr.i_pflag;
+-
+-      switch(lp->state)
+-      {
+-              /*      Compute index in transition table: */
+-              case ADM:
+-                      idx = type;
+-                      idx = (idx << 1) + p_flag_received;
+-                      break;
+-              case CONN:
+-              case RESET_WAIT:
+-              case RESET_CHECK:
+-              case ERROR:
+-                      idx = type;
+-                      break;
+-              case SETUP:
+-              case RESET:
+-              case D_CONN:
+-                      idx = type;
+-                      idx = (idx << 1) + lp->p_flag;
+-                      break;
+-              case NORMAL:
+-              case BUSY:
+-              case REJECT:
+-              case AWAIT:
+-              case AWAIT_BUSY:
+-              case AWAIT_REJECT:
+-                      validation = llc_validate_seq_nos(lp, fr);
+-                      if (validation > 3) 
+-                              type = BAD_FRAME;
+-                      idx = type;
+-                      idx = (idx << 1);
+-                      if (validation & 1) 
+-                              idx = idx +1;
+-                      idx = (idx << 1) + p_flag_received;
+-                      idx = (idx << 1) + lp->p_flag;
+-              default:
+-                      printk("llc_proc: bad state\n");
+-                      return;
+-      }
+-      idx = (idx << 1) + pdutr_offset[lp->state];
+-      lp->state = pdutr_entry[idx +1]; 
+-      pc_label = pdutr_entry[idx];
+-      if (pc_label != NOP)
+-      { 
+-              llc_interpret_pseudo_code(lp, pc_label, skb, type);
+-              if(lp->llc_callbacks)
+-              {
+-                      lp->llc_event(lp);
+-                      lp->llc_callbacks=0;
+-              }
+-              /*
+-               *      lp may no longer be valid after this point. Be
+-               *      careful what is added!
+-               */
+-      }
+-}
+-
+-
+-void llc_timer_expired(llcptr lp, int t)
+-{
+-      int idx;                /* index in transition table    */
+-      int pc_label;           /* action to perform, from tr tbl */
+-
+-      lp->timer_state[t] = TIMER_EXPIRED;
+-      idx = lp->state;            /* Compute index in transition table: */
+-      idx = (idx << 2) + t;
+-      idx = idx << 1;
+-      if (lp->retry_count >= lp->n2) 
+-              idx = idx + 1;
+-      idx = (idx << 1) + lp->s_flag;
+-      idx = (idx << 1) + lp->p_flag;
+-      idx = idx << 1;             /* 2 bytes per entry: action & newstate */
+-
+-      pc_label = timertr_entry[idx];
+-      if (pc_label != NOP)
+-      {
+-              llc_interpret_pseudo_code(lp, pc_label, NULL, NO_FRAME);
+-              lp->state = timertr_entry[idx +1];
+-      }
+-      lp->timer_state[t] = TIMER_IDLE;
+-      if(lp->llc_callbacks)
+-      {
+-              lp->llc_event(lp);
+-              lp->llc_callbacks=0;
+-      }
+-      /*
+-       *      And lp may have vanished in the event callback
+-       */
+-}
+-
+diff -uNr linux/net/802/fc.c linux-llc/net/802/fc.c
+--- linux/net/802/fc.c Tue Jan  4 18:12:26 2000
++++ linux-llc/net/802/fc.c     Thu Jan  1 01:00:00 1970
+@@ -1,99 +0,0 @@
+-/*
+- * NET3:      Fibre Channel device handling subroutines
+- * 
+- *            This program is free software; you can redistribute it and/or
+- *            modify it under the terms of the GNU General Public License
+- *            as published by the Free Software Foundation; either version
+- *            2 of the License, or (at your option) any later version.
+- *
+- *            Vineet Abraham <vma@iol.unh.edu>
+- *            v 1.0 03/22/99
+- */
+-
+-#include <asm/uaccess.h>
+-#include <asm/system.h>
+-#include <linux/config.h>
+-#include <linux/types.h>
+-#include <linux/kernel.h>
+-#include <linux/sched.h>
+-#include <linux/string.h>
+-#include <linux/mm.h>
+-#include <linux/socket.h>
+-#include <linux/in.h>
+-#include <linux/inet.h>
+-#include <linux/netdevice.h>
+-#include <linux/fcdevice.h>
+-#include <linux/skbuff.h>
+-#include <linux/errno.h>
+-#include <linux/string.h>
+-#include <linux/timer.h>
+-#include <linux/net.h>
+-#include <linux/proc_fs.h>
+-#include <linux/init.h>
+-#include <net/arp.h>
+-
+-/*
+- *    Put the headers on a Fibre Channel packet. 
+- */
+- 
+-int fc_header(struct sk_buff *skb, struct device *dev, unsigned short type,
+-              void *daddr, void *saddr, unsigned len) 
+-{
+-      struct fch_hdr *fch;
+-      int hdr_len;
+-
+-      /* 
+-       * Add the 802.2 SNAP header if IP as the IPv4 code calls  
+-       * dev->hard_header directly.
+-       */
+-      if (type == ETH_P_IP || type == ETH_P_ARP)
+-      {
+-              struct fcllc *fcllc=(struct fcllc *)(fch+1);
+-
+-              hdr_len = sizeof(struct fch_hdr) + sizeof(struct fcllc);
+-              fch = (struct fch_hdr *)skb_push(skb, hdr_len);
+-              fcllc = (struct fcllc *)(fch+1);
+-              fcllc->dsap = fcllc->ssap = EXTENDED_SAP;
+-              fcllc->llc = UI_CMD;
+-              fcllc->protid[0] = fcllc->protid[1] = fcllc->protid[2] = 0x00;
+-              fcllc->ethertype = htons(type);
+-      }
+-      else
+-      {
+-              hdr_len = sizeof(struct fch_hdr);
+-              fch = (struct fch_hdr *)skb_push(skb, hdr_len); 
+-      }
+-
+-      if(saddr)
+-              memcpy(fch->saddr,saddr,dev->addr_len);
+-      else
+-              memcpy(fch->saddr,dev->dev_addr,dev->addr_len);
+-
+-      if(daddr) 
+-      {
+-              memcpy(fch->daddr,daddr,dev->addr_len);
+-              return(hdr_len);
+-      }
+-      return -hdr_len;
+-}
+-      
+-/*
+- *    A neighbour discovery of some species (eg arp) has completed. We
+- *    can now send the packet.
+- */
+- 
+-int fc_rebuild_header(struct sk_buff *skb) 
+-{
+-      struct fch_hdr *fch=(struct fch_hdr *)skb->data;
+-      struct fcllc *fcllc=(struct fcllc *)(skb->data+sizeof(struct fch_hdr));
+-      if(fcllc->ethertype != htons(ETH_P_IP)) {
+-              printk("fc_rebuild_header: Don't know how to resolve type %04X addresses ?\n",(unsigned int)htons(fcllc->ethertype));
+-              return 0;
+-      }
+-#ifdef CONFIG_INET
+-      return arp_find(fch->daddr, skb);
+-#else
+-      return 0; /* Cannot happen because of ETH_P_IP test */
+-#endif        
+-}
+-      
+diff -uNr linux/net/802/fddi.c linux-llc/net/802/fddi.c
+--- linux/net/802/fddi.c       Sun Nov 15 17:52:28 1998
++++ linux-llc/net/802/fddi.c   Thu Jan  1 01:00:00 1970
+@@ -1,165 +0,0 @@
+-/*
+- * INET               An implementation of the TCP/IP protocol suite for the LINUX
+- *            operating system.  INET is implemented using the BSD Socket
+- *            interface as the means of communication with the user level.
+- *
+- *            FDDI-type device handling.
+- *
+- * Version:   @(#)fddi.c      1.0.0   08/12/96
+- *
+- * Authors:   Lawrence V. Stefani, <stefani@lkg.dec.com>
+- *
+- *            fddi.c is based on previous eth.c and tr.c work by
+- *                    Ross Biro, <bir7@leland.Stanford.Edu>
+- *                    Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
+- *                    Mark Evans, <evansmp@uhura.aston.ac.uk>
+- *                    Florian La Roche, <rzsfl@rz.uni-sb.de>
+- *                    Alan Cox, <gw4pts@gw4pts.ampr.org>
+- * 
+- *            This program is free software; you can redistribute it and/or
+- *            modify it under the terms of the GNU General Public License
+- *            as published by the Free Software Foundation; either version
+- *            2 of the License, or (at your option) any later version.
+- *
+- *    Changes
+- *            Alan Cox        :       New arp/rebuild header
+- */
+- 
+-#include <linux/config.h>
+-#include <asm/segment.h>
+-#include <asm/system.h>
+-#include <linux/types.h>
+-#include <linux/kernel.h>
+-#include <linux/sched.h>
+-#include <linux/string.h>
+-#include <linux/mm.h>
+-#include <linux/socket.h>
+-#include <linux/in.h>
+-#include <linux/inet.h>
+-#include <linux/netdevice.h>
+-#include <linux/fddidevice.h>
+-#include <linux/if_ether.h>
+-#include <linux/skbuff.h>
+-#include <linux/errno.h>
+-#include <net/arp.h>
+-#include <net/sock.h>
+-
+-/*
+- * Create the FDDI MAC header for an arbitrary protocol layer
+- *
+- * saddr=NULL means use device source address
+- * daddr=NULL means leave destination address (eg unresolved arp)
+- */
+-
+-int fddi_header(struct sk_buff        *skb, struct device *dev, unsigned short type,
+-              void *daddr, void *saddr, unsigned len)
+-{
+-      int hl = FDDI_K_SNAP_HLEN;
+-      struct fddihdr *fddi;
+-      
+-      if(type != ETH_P_IP && type != ETH_P_ARP)
+-              hl=FDDI_K_8022_HLEN-3;
+-      fddi = (struct fddihdr *)skb_push(skb, hl);
+-      fddi->fc                         = FDDI_FC_K_ASYNC_LLC_DEF;
+-      if(type == ETH_P_IP || type == ETH_P_ARP)
+-      {
+-              fddi->hdr.llc_snap.dsap          = FDDI_EXTENDED_SAP;
+-              fddi->hdr.llc_snap.ssap          = FDDI_EXTENDED_SAP;
+-              fddi->hdr.llc_snap.ctrl          = FDDI_UI_CMD;
+-              fddi->hdr.llc_snap.oui[0]        = 0x00;
+-              fddi->hdr.llc_snap.oui[1]        = 0x00;
+-              fddi->hdr.llc_snap.oui[2]        = 0x00;
+-              fddi->hdr.llc_snap.ethertype     = htons(type);
+-      }
+-
+-      /* Set the source and destination hardware addresses */
+-       
+-      if (saddr != NULL)
+-              memcpy(fddi->saddr, saddr, dev->addr_len);
+-      else
+-              memcpy(fddi->saddr, dev->dev_addr, dev->addr_len);
+-
+-      if (daddr != NULL)
+-      {
+-              memcpy(fddi->daddr, daddr, dev->addr_len);
+-              return(hl);
+-      }
+-
+-      return(-hl);
+-}
+-
+-
+-/*
+- * Rebuild the FDDI 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.
+- */
+- 
+-int fddi_rebuild_header(struct sk_buff        *skb)
+-{
+-      struct fddihdr *fddi = (struct fddihdr *)skb->data;
+-
+-#ifdef CONFIG_INET
+-      if (fddi->hdr.llc_snap.ethertype == __constant_htons(ETH_P_IP))
+-              /* Try to get ARP to resolve the header and fill destination address */
+-              return arp_find(fddi->daddr, skb);
+-      else
+-#endif        
+-      {
+-              printk("%s: Don't know how to resolve type %02X addresses.\n",
+-                     skb->dev->name, htons(fddi->hdr.llc_snap.ethertype));
+-              return(0);
+-      }
+-}
+-
+-
+-/*
+- * Determine the packet's protocol ID and fill in skb fields.
+- * This routine is called before an incoming packet is passed
+- * up.  It's used to fill in specific skb fields and to set
+- * the proper pointer to the start of packet data (skb->data).
+- */
+- 
+-unsigned short fddi_type_trans(struct sk_buff *skb, struct device *dev)
+-{
+-      struct fddihdr *fddi = (struct fddihdr *)skb->data;
+-      unsigned short type;
+-      
+-      /*
+-       * Set mac.raw field to point to FC byte, set data field to point
+-       * to start of packet data.  Assume 802.2 SNAP frames for now.
+-       */
+-
+-      skb->mac.raw = skb->data;       /* point to frame control (FC) */
+-      
+-      if(fddi->hdr.llc_8022_1.dsap==0xe0)
+-      {
+-              skb_pull(skb, FDDI_K_8022_HLEN-3);
+-              type = __constant_htons(ETH_P_802_2);
+-      }
+-      else
+-      {
+-              skb_pull(skb, FDDI_K_SNAP_HLEN);                /* adjust for 21 byte header */
+-              type=fddi->hdr.llc_snap.ethertype;
+-      }
+-      
+-      /* Set packet type based on destination address and flag settings */
+-                      
+-      if (*fddi->daddr & 0x01)
+-      {
+-              if (memcmp(fddi->daddr, dev->broadcast, FDDI_K_ALEN) == 0)
+-                      skb->pkt_type = PACKET_BROADCAST;
+-              else
+-                      skb->pkt_type = PACKET_MULTICAST;
+-      }
+-      
+-      else if (dev->flags & IFF_PROMISC)
+-      {
+-              if (memcmp(fddi->daddr, dev->dev_addr, FDDI_K_ALEN))
+-                      skb->pkt_type = PACKET_OTHERHOST;
+-      }
+-
+-      /* Assume 802.2 SNAP frames, for now */
+-
+-      return(type);
+-}
+diff -uNr linux/net/802/hippi.c linux-llc/net/802/hippi.c
+--- linux/net/802/hippi.c      Wed Oct  7 19:13:49 1998
++++ linux-llc/net/802/hippi.c  Thu Jan  1 01:00:00 1970
+@@ -1,154 +0,0 @@
+-/*
+- * INET               An implementation of the TCP/IP protocol suite for the LINUX
+- *            operating system.  INET is implemented using the  BSD Socket
+- *            interface as the means of communication with the user level.
+- *
+- *            HIPPI-type device handling.
+- *
+- * Version:   @(#)hippi.c     1.0.0   05/29/97
+- *
+- * Authors:   Ross Biro, <bir7@leland.Stanford.Edu>
+- *            Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
+- *            Mark Evans, <evansmp@uhura.aston.ac.uk>
+- *            Florian  La Roche, <rzsfl@rz.uni-sb.de>
+- *            Alan Cox, <gw4pts@gw4pts.ampr.org>
+- *            Jes Sorensen, <Jes.Sorensen@cern.ch>
+- *
+- *            This program is free software; you can redistribute it and/or
+- *            modify it under the terms of the GNU General Public License
+- *            as published by the Free Software Foundation; either version
+- *            2 of the License, or (at your option) any later version.
+- */
+-
+-#include <linux/types.h>
+-#include <linux/kernel.h>
+-#include <linux/sched.h>
+-#include <linux/string.h>
+-#include <linux/mm.h>
+-#include <linux/socket.h>
+-#include <linux/in.h>
+-#include <linux/inet.h>
+-#include <linux/netdevice.h>
+-#include <linux/hippidevice.h>
+-#include <linux/skbuff.h>
+-#include <linux/errno.h>
+-#include <net/arp.h>
+-#include <net/sock.h>
+-#include <asm/uaccess.h>
+-#include <asm/checksum.h>
+-#include <asm/segment.h>
+-#include <asm/system.h>
+-
+-/*
+- * hippi_net_init()
+- *
+- * Do nothing, this is just to pursuade the stupid linker to behave.
+- */
+-
+-void hippi_net_init(void)
+-{
+-      return;
+-}
+-
+-/*
+- * Create the HIPPI MAC header for an arbitrary protocol layer 
+- *
+- * saddr=NULL means use device source address
+- * daddr=NULL means leave destination address (eg unresolved arp)
+- */
+-
+-int hippi_header(struct sk_buff *skb, struct device *dev,
+-               unsigned short type, void *daddr, void *saddr,
+-               unsigned len)
+-{
+-      struct hippi_hdr *hip = (struct hippi_hdr *)skb_push(skb, HIPPI_HLEN);
+-
+-      if (!len){
+-              len = skb->len - HIPPI_HLEN;
+-              printk("hippi_header(): length not supplied\n");
+-      }
+-
+-      /*
+-       * Due to the stupidity of the little endian byte-order we
+-       * have to set the fp field this way.
+-       */
+-      hip->fp.fixed           = __constant_htonl(0x04800018);
+-      hip->fp.d2_size         = htonl(len + 8);
+-      hip->le.fc              = 0;
+-      hip->le.double_wide     = 0;    /* only HIPPI 800 for the time being */
+-      hip->le.message_type    = 0;    /* Data PDU */
+-
+-      hip->le.dest_addr_type  = 2;    /* 12 bit SC address */
+-      hip->le.src_addr_type   = 2;    /* 12 bit SC address */
+-
+-      memcpy(hip->le.src_switch_addr, dev->dev_addr + 3, 3);
+-      memset(&hip->le.reserved, 0, 16);
+-
+-      hip->snap.dsap          = HIPPI_EXTENDED_SAP;
+-      hip->snap.ssap          = HIPPI_EXTENDED_SAP;
+-      hip->snap.ctrl          = HIPPI_UI_CMD;
+-      hip->snap.oui[0]        = 0x00;
+-      hip->snap.oui[1]        = 0x00;
+-      hip->snap.oui[2]        = 0x00;
+-      hip->snap.ethertype     = htons(type);
+-
+-      if (daddr)
+-      {
+-              memcpy(hip->le.dest_switch_addr, daddr + 3, 3);
+-              memcpy(&skb->private.ifield, daddr + 2, 4);
+-              return HIPPI_HLEN;
+-      }
+-      return -HIPPI_HLEN;
+-}
+-
+-
+-/*
+- * Rebuild the HIPPI MAC header. This is called after an ARP has
+- * completed on this sk_buff. We now let ARP fill in the other fields.
+- */
+-
+-int hippi_rebuild_header(struct sk_buff *skb)
+-{
+-      struct hippi_hdr *hip = (struct hippi_hdr *)skb->data;
+-
+-      /*
+-       * Only IP is currently supported
+-       */
+-       
+-      if(hip->snap.ethertype != __constant_htons(ETH_P_IP)) 
+-      {
+-              printk(KERN_DEBUG "%s: unable to resolve type %X addresses.\n",skb->dev->name,ntohs(hip->snap.ethertype));
+-              return 0;
+-      }
+-
+-      /*
+-       * We don't support dynamic ARP on HIPPI, but we use the ARP
+-       * static ARP tables to hold the I-FIELDs.
+-       */
+-      return arp_find(hip->le.daddr, skb);
+-}
+-
+-
+-/*
+- *    Determine the packet's protocol ID.
+- */
+- 
+-unsigned short hippi_type_trans(struct sk_buff *skb, struct device *dev)
+-{
+-      struct hippi_hdr *hip;
+-      
+-      hip = (struct hippi_hdr *) skb->data;
+-
+-      /*
+-       * This is actually wrong ... question is if we really should
+-       * set the raw address here.
+-       */
+-       skb->mac.raw = skb->data;
+-       skb_pull(skb, HIPPI_HLEN);
+-
+-      /*
+-       * No fancy promisc stuff here now.
+-       */
+-
+-      return hip->snap.ethertype;
+-}
+diff -uNr linux/net/802/llc_macinit.c linux-llc/net/802/llc_macinit.c
+--- linux/net/802/llc_macinit.c        Sat Feb 21 02:28:23 1998
++++ linux-llc/net/802/llc_macinit.c    Thu Jan  1 01:00:00 1970
+@@ -1,224 +0,0 @@
+-/*
+- * NET                An implementation of the IEEE 802.2 LLC protocol for the
+- *            LINUX operating system.  LLC is implemented as a set of
+- *            state machines and callbacks for higher networking layers.
+- *
+- *            Code for initialization, termination, registration and
+- *            MAC layer glue.
+- *
+- *            Written by Tim Alpaerts, Tim_Alpaerts@toyota-motor-europe.com
+- *
+- *            This program is free software; you can redistribute it and/or
+- *            modify it under the terms of the GNU General Public License
+- *            as published by the Free Software Foundation; either version
+- *            2 of the License, or (at your option) any later version.
+- *
+- *    Changes
+- *            Alan Cox        :       Chainsawed to Linux format
+- *                                    Added llc_ to names
+- *                                    Started restructuring handlers
+- */
+-
+-#include <linux/module.h>
+-#include <linux/version.h>
+-#include <linux/kernel.h>
+-#include <linux/malloc.h>
+-#include <linux/unistd.h>
+-#include <linux/netdevice.h>
+-#include <linux/init.h>
+-#include <net/p8022.h>
+-
+-#include <asm/byteorder.h>
+-
+-#include <net/llc_frame.h>
+-#include <net/llc.h>
+-
+-/*
+- *    All incoming frames pass thru mac_data_indicate().
+- *    On entry the llc structure related to the frame is passed as parameter. 
+- *    The received sk_buffs with pdus other than I_CMD and I_RSP
+- *    are freed by mac_data_indicate() after processing,
+- *    the I pdu buffers are freed by the cl2llc client when it no longer needs
+- *    the skb.
+-*/
+-
+-int llc_mac_data_indicate(llcptr lp, struct sk_buff *skb)
+-{
+-      int ll;                 /* logical length == 802.3 length field */
+-      unsigned char p_flag;
+-      unsigned char type;
+-      frameptr fr;
+-      int free=1;
+-
+-      lp->inc_skb=NULL;
+-      
+-      /*
+-       *      Truncate buffer to true 802.3 length
+-       *      [FIXME: move to 802.2 demux]
+-       */
+-
+-      ll = *(skb->data -2) * 256 + *(skb->data -1);
+-      skb_trim( skb, ll );
+-
+-      fr = (frameptr) skb->data;
+-      type = llc_decode_frametype( fr );
+-
+-
+-      if (type <= FRMR_RSP)
+-      {
+-              /*
+-               *      PDU is of the type 2 set
+-               */
+-              if ((lp->llc_mode == MODE_ABM)||(type == SABME_CMD))
+-                      llc_process_otype2_frame(lp, skb, type);
+-
+-      }
+-      else
+-      {
+-              /*
+-               *      PDU belongs to type 1 set
+-               */
+-              p_flag = fr->u_hdr.u_pflag;
+-              switch(type)
+-              {
+-                      case TEST_CMD:
+-                              llc_sendpdu(lp, TEST_RSP, 0,ll -3,
+-                                      fr->u_hdr.u_info);
+-                              break;
+-                      case TEST_RSP:
+-                              lp->llc_callbacks|=LLC_TEST_INDICATION;
+-                              lp->inc_skb=skb;
+-                              free=0;
+-                              break;
+-                      case XID_CMD:
+-                              /*
+-                               *      Basic format XID is handled by LLC itself
+-                               *      Doc 5.4.1.1.2 p 48/49
+-                               */
+-
+-                              if ((ll == 6)&&(fr->u_hdr.u_info[0] == 0x81))
+-                              {
+-                                      lp->k = fr->u_hdr.u_info[2];
+-                                      llc_sendpdu(lp, XID_RSP,
+-                                              fr->u_hdr.u_pflag, ll -3,
+-                                              fr->u_hdr.u_info);
+-                              }
+-                              break;
+-
+-                      case XID_RSP:
+-                              if( ll == 6 && fr->u_hdr.u_info[0] == 0x81 )
+-                              {
+-                                      lp->k = fr->u_hdr.u_info[2];
+-                              }
+-                              lp->llc_callbacks|=LLC_XID_INDICATION;
+-                              lp->inc_skb=skb;
+-                              free=0;
+-                              break;
+-
+-                      case UI_CMD:
+-                              lp->llc_callbacks|=LLC_UI_DATA;
+-                              skb_pull(skb,3);
+-                              lp->inc_skb=skb;
+-                              free=0;
+-                              break;
+-
+-                      default:
+-                              /*
+-                               *      All other type 1 pdus ignored for now
+-                               */
+-              }
+-      }
+-
+-      if (free&&(!(IS_IFRAME(fr))))
+-      {
+-              /*
+-               *      No auto free for I pdus
+-               */
+-              skb->sk = NULL;
+-              kfree_skb(skb);
+-      }
+-
+-      if(lp->llc_callbacks)
+-      {
+-              if ( lp->llc_event != NULL ) lp->llc_event(lp);
+-              lp->llc_callbacks=0;
+-      }
+-      return 0;
+-}
+-
+-
+-/*
+- *    Create an LLC client. As it is the job of the caller to clean up
+- *    LLC's on device down, the device list must be locked before this call.
+- */
+-
+-int register_cl2llc_client(llcptr lp, const char *device, void (*event)(llcptr), u8 *rmac, u8 ssap, u8 dsap)
+-{
+-      char eye_init[] = "LLC\0";
+-
+-      memset(lp, 0, sizeof(*lp));
+-      lp->dev = dev_get(device);
+-      if(lp->dev == NULL)
+-              return -ENODEV;
+-      memcpy(lp->eye, eye_init, sizeof(lp->eye));
+-      lp->rw = 1;
+-      lp->k = 127;
+-      lp->n1 = 1490;
+-      lp->n2 = 10;
+-      lp->timer_interval[P_TIMER] = HZ;    /* 1 sec */
+-      lp->timer_interval[REJ_TIMER] = HZ/8;
+-      lp->timer_interval[ACK_TIMER] = HZ/8;
+-      lp->timer_interval[BUSY_TIMER] = HZ*2;
+-      lp->local_sap = ssap;
+-      lp->llc_event = event;
+-      memcpy(lp->remote_mac, rmac, sizeof(lp->remote_mac));
+-      lp->state = 0;
+-      lp->llc_mode = MODE_ADM;
+-      lp->remote_sap = dsap;
+-      skb_queue_head_init(&lp->atq);
+-      skb_queue_head_init(&lp->rtq);
+-      MOD_INC_USE_COUNT;
+-      return 0;
+-}
+-
+-
+-void unregister_cl2llc_client(llcptr lp)
+-{
+-      llc_cancel_timers(lp);
+-      MOD_DEC_USE_COUNT;
+-      kfree(lp);
+-}
+-
+-
+-EXPORT_SYMBOL(register_cl2llc_client);
+-EXPORT_SYMBOL(unregister_cl2llc_client);
+-EXPORT_SYMBOL(llc_data_request);
+-EXPORT_SYMBOL(llc_unit_data_request);
+-EXPORT_SYMBOL(llc_test_request);
+-EXPORT_SYMBOL(llc_xid_request);
+-EXPORT_SYMBOL(llc_mac_data_indicate);
+-EXPORT_SYMBOL(llc_cancel_timers);
+-
+-#define ALL_TYPES_8022 0
+-
+-__initfunc(void llc_init(struct net_proto *proto))
+-{
+-      printk(KERN_NOTICE "IEEE 802.2 LLC for Linux 2.1 (c) 1996 Tim Alpaerts\n");
+-      return;
+-}
+-
+-#ifdef MODULE
+-
+-
+-int init_module(void)
+-{
+-      llc_init(NULL);
+-      return 0;
+-}
+-
+-void cleanup_module(void)
+-{
+-
+-}
+-
+-#endif
+diff -uNr linux/net/802/llc_sendpdu.c linux-llc/net/802/llc_sendpdu.c
+--- linux/net/802/llc_sendpdu.c        Tue Feb 10 21:07:49 1998
++++ linux-llc/net/802/llc_sendpdu.c    Thu Jan  1 01:00:00 1970
+@@ -1,357 +0,0 @@
+-/*
+- * NET                An implementation of the IEEE 802.2 LLC protocol for the
+- *            LINUX operating system.  LLC is implemented as a set of 
+- *            state machines and callbacks for higher networking layers.
+- *
+- *            llc_sendpdu(), llc_sendipdu(), resend() + queue handling code
+- *
+- *            Written by Tim Alpaerts, Tim_Alpaerts@toyota-motor-europe.com
+- *
+- *            This program is free software; you can redistribute it and/or
+- *            modify it under the terms of the GNU General Public License
+- *            as published by the Free Software Foundation; either version
+- *            2 of the License, or (at your option) any later version.
+- *
+- *    Changes
+- *            Alan Cox        :       Chainsawed into Linux format, style
+- *                                    Added llc_ to function names
+- */
+-
+-#include <linux/types.h>
+-#include <linux/kernel.h>
+-#include <linux/malloc.h>
+-#include <linux/netdevice.h>
+-#include <linux/skbuff.h>
+-#include <net/p8022.h>
+-#include <linux/stat.h>
+-#include <asm/byteorder.h>
+-#include <net/llc_frame.h>
+-#include <net/llc.h>
+-
+-static unsigned char cntl_byte_encode[] = 
+-{
+-      0x00,   /* I_CMD */
+-      0x01,   /* RR_CMD */
+-      0x05,   /* RNR_CMD */
+-      0x09,   /* REJ_CMD */
+-      0x43,   /* DISC_CMD */
+-      0x7F,   /* SABME_CMD */
+-      0x00,   /* I_RSP */
+-      0x01,   /* RR_RSP */
+-      0x05,   /* RNR_RSP */
+-      0x09,   /* REJ_RSP */
+-      0x63,   /* UA_RSP */
+-      0x0F,   /* DM_RSP */
+-      0x87,   /* FRMR_RSP */
+-      0xFF,   /* BAD_FRAME */
+-      0x03,   /* UI_CMD */
+-      0xBF,   /* XID_CMD */
+-      0xE3,   /* TEST_CMD */
+-      0xBF,   /* XID_RSP */
+-      0xE3    /* TEST_RSP */
+-};
+-
+-static unsigned char fr_length_encode[] = 
+-{
+-      0x04,   /* I_CMD */
+-      0x04,   /* RR_CMD */
+-      0x04,   /* RNR_CMD */
+-      0x04,   /* REJ_CMD */
+-      0x03,   /* DISC_CMD */
+-      0x03,   /* SABME_CMD */
+-      0x04,   /* I_RSP */
+-      0x04,   /* RR_RSP */
+-      0x04,   /* RNR_RSP */
+-      0x04,   /* REJ_RSP */
+-      0x03,   /* UA_RSP */
+-      0x03,   /* DM_RSP */
+-      0x03,   /* FRMR_RSP */
+-      0x00,   /* BAD_FRAME */
+-      0x03,   /* UI_CMD */
+-      0x03,   /* XID_CMD */
+-      0x03,   /* TEST_CMD */
+-      0x03,   /* XID_RSP */
+-      0x03    /* TEST_RSP */
+-};
+-
+-static unsigned char cr_bit_encode[] = {
+-      0x00,   /* I_CMD */
+-      0x00,   /* RR_CMD */
+-      0x00,   /* RNR_CMD */
+-      0x00,   /* REJ_CMD */
+-      0x00,   /* DISC_CMD */
+-      0x00,   /* SABME_CMD */
+-      0x01,   /* I_RSP */
+-      0x01,   /* RR_RSP */
+-      0x01,   /* RNR_RSP */
+-      0x01,   /* REJ_RSP */
+-      0x01,   /* UA_RSP */
+-      0x01,   /* DM_RSP */
+-      0x01,   /* FRMR_RSP */
+-      0x00,   /* BAD_FRAME */
+-      0x00,   /* UI_CMD */
+-      0x00,   /* XID_CMD */
+-      0x00,   /* TEST_CMD */
+-      0x01,   /* XID_RSP */
+-      0x01    /* TEST_RSP */
+-};
+-
+-/*
+- *    Sendpdu() constructs an output frame in a new skb and
+- *    gives it to the MAC layer for transmision.
+- *    This function is not used to send I pdus.
+- *    No queues are updated here, nothing is saved for retransmission.
+- *
+- *    Parameter pf controls both the poll/final bit and dsap
+- *    fields in the output pdu. 
+- *    The dsap trick was needed to implement XID_CMD send with
+- *    zero dsap field as described in doc 6.6 item 1 of enum.  
+- */
+-
+-void llc_sendpdu(llcptr lp, char type, char pf, int data_len, char *pdu_data)
+-{
+-      frameptr fr;                /* ptr to output pdu buffer */
+-      unsigned short int fl;      /* frame length == 802.3 "length" value */
+-      struct sk_buff *skb;
+-
+-      fl = data_len + fr_length_encode[(int)type];
+-      skb = alloc_skb(16 + fl, GFP_ATOMIC); 
+-      if (skb != NULL)
+-      {
+-              skb->dev = lp->dev;     
+-              skb_reserve(skb, 16);
+-              fr = (frameptr) skb_put(skb, fl);
+-              memset(fr, 0, fl);
+-                /*
+-                 *    Construct 802.2 header 
+-                 */
+-              if (pf & 0x02) 
+-                      fr->pdu_hdr.dsap = 0;
+-              else
+-                      fr->pdu_hdr.dsap = lp->remote_sap;
+-              fr->pdu_hdr.ssap = lp->local_sap + cr_bit_encode[(int)type];
+-              fr->pdu_cntl.byte1 = cntl_byte_encode[(int)type];
+-              /* 
+-               *      Fill in pflag and seq nbrs: 
+-               */
+-              if (IS_SFRAME(fr)) 
+-              {
+-                      /* case S-frames */
+-                      if (pf & 0x01) 
+-                              fr->i_hdr.i_pflag = 1;
+-                      fr->i_hdr.nr = lp->vr;
+-              }
+-              else
+-              {
+-                      /* case U frames */ 
+-                      if (pf & 0x01) 
+-                              fr->u_hdr.u_pflag = 1;
+-              }
+-                       
+-              if (data_len > 0) 
+-              {                       /* append data if any  */ 
+-                      if (IS_UFRAME(fr)) 
+-                      {
+-                              memcpy(fr->u_hdr.u_info, pdu_data, data_len);
+-                      }
+-                      else 
+-                      {
+-                              memcpy(fr->i_hdr.is_info, pdu_data, data_len);
+-                      }
+-              }
+-              lp->dev->hard_header(skb, lp->dev, ETH_P_802_3,
+-                       lp->remote_mac, NULL, fl);
+-              skb->dev=lp->dev;
+-              dev_queue_xmit(skb);
+-      }
+-      else
+-              printk(KERN_DEBUG "cl2llc: skb_alloc() in llc_sendpdu() failed\n");     
+-}
+-
+-void llc_xid_request(llcptr lp, char opt, int ll, char * data)
+-{
+-      llc_sendpdu(lp, XID_CMD, opt, ll, data); 
+-}
+-
+-void llc_test_request(llcptr lp, int ll, char * data)
+-{
+-      llc_sendpdu(lp, TEST_CMD, 0, ll, data); 
+-}
+-
+-void llc_unit_data_request(llcptr lp, int ll, char * data)
+-{
+-      llc_sendpdu(lp, UI_CMD, 0, ll, data); 
+-}
+-
+-
+-/*
+- *    llc_sendipdu() Completes an I pdu in an existing skb and gives it
+- *    to the MAC layer for transmision.
+- *    Parameter "type" must be either I_CMD or I_RSP.
+- *    The skb is not freed after xmit, it is kept in case a retransmission
+- *    is requested. If needed it can be picked up again from the rtq.
+- */
+-
+-void llc_sendipdu(llcptr lp, char type, char pf, struct sk_buff *skb)
+-{
+-      frameptr fr;                /* ptr to output pdu buffer */
+-      struct sk_buff *tmp;
+-      
+-      fr = (frameptr) skb->data;
+-
+-      fr->pdu_hdr.dsap = lp->remote_sap;
+-      fr->pdu_hdr.ssap = lp->local_sap + cr_bit_encode[(int)type];
+-      fr->pdu_cntl.byte1 = cntl_byte_encode[(int)type];
+-                      
+-      if (pf)
+-              fr->i_hdr.i_pflag = 1; /* p/f and seq numbers */  
+-      fr->i_hdr.nr = lp->vr;
+-      fr->i_hdr.ns = lp->vs;
+-      lp->vs++;
+-      if (lp->vs > 127) 
+-              lp->vs = 0;
+-      lp->dev->hard_header(skb, lp->dev, ETH_P_802_3,
+-              lp->remote_mac, NULL, skb->len);
+-      ADD_TO_RTQ(skb);                /* add skb to the retransmit queue */
+-      tmp=skb_clone(skb, GFP_ATOMIC);
+-      if(tmp!=NULL)
+-      {
+-              tmp->dev=lp->dev;
+-              dev_queue_xmit(tmp);
+-      }
+-}
+-
+-
+-/*
+- *    Resend_ipdu() will resend the pdus in the retransmit queue (rtq)
+- *    the return value is the number of pdus resend.
+- *    ack_nr is N(R) of 1st pdu to resent.
+- *    Type is I_CMD or I_RSP for 1st pdu resent.
+- *    p is p/f flag 0 or 1 for 1st pdu resent.
+- *    All subsequent pdus will be sent as I_CMDs with p/f set to 0
+- */ 
+-
+-int llc_resend_ipdu(llcptr lp, unsigned char ack_nr, unsigned char type, char p)
+-{
+-      struct sk_buff *skb,*tmp;
+-      int resend_count;
+-      frameptr fr;
+-      unsigned long flags;
+-      
+-
+-      resend_count = 0;
+-      
+-      save_flags(flags);
+-      cli();
+-      
+-      skb = skb_peek(&lp->rtq);
+-
+-      while(skb && skb != (struct sk_buff *)&lp->rtq)
+-      {
+-              fr = (frameptr) (skb->data + lp->dev->hard_header_len);
+-              if (resend_count == 0) 
+-              {
+-                      /* 
+-                       *      Resending 1st pdu: 
+-                       */
+-
+-                      if (p) 
+-                              fr->i_hdr.i_pflag = 1;
+-                      else
+-                              fr->i_hdr.i_pflag = 0;
+-            
+-                      if (type == I_CMD)           
+-                              fr->pdu_hdr.ssap = fr->pdu_hdr.ssap & 0xfe;
+-                      else
+-                              fr->pdu_hdr.ssap = fr->pdu_hdr.ssap | 0x01;
+-              }
+-              else
+-              {
+-                      /*
+-                       *      Resending pdu 2...n 
+-                       */
+-
+-                      fr->pdu_hdr.ssap = fr->pdu_hdr.ssap & 0xfe;
+-                      fr->i_hdr.i_pflag = 0;
+-              }
+-              fr->i_hdr.nr = lp->vr;
+-              fr->i_hdr.ns = lp->vs;
+-              lp->vs++;
+-              if (lp->vs > 127) 
+-                      lp->vs = 0;
+-              tmp=skb_clone(skb, GFP_ATOMIC);
+-              if(tmp!=NULL)
+-              {
+-                      tmp->dev = lp->dev;
+-                      dev_queue_xmit(skb);
+-              }
+-              resend_count++;
+-              skb = skb->next;
+-      }
+-      restore_flags(flags);
+-      return resend_count;
+-}
+-
+-/* ************** internal queue management code ****************** */
+-
+-
+-/*
+- *    Remove one skb from the front of the awaiting transmit queue
+- *    (this is the skb longest on the queue) and return a pointer to 
+- *    that skb. 
+- */ 
+-
+-struct sk_buff *llc_pull_from_atq(llcptr lp) 
+-{
+-      return skb_dequeue(&lp->atq);
+-}
+- 
+-/*
+- *    Free_acknowledged_skbs(), remove from retransmit queue (rtq)
+- *    and free all skbs with an N(S) chronologicaly before 'pdu_ack'.
+- *    The return value is the number of pdus acknowledged.
+- */
+- 
+-int llc_free_acknowledged_skbs(llcptr lp, unsigned char pdu_ack)
+-{
+-      struct sk_buff *pp;
+-      frameptr fr; 
+-      int ack_count;
+-      unsigned char ack;      /* N(S) of most recently ack'ed pdu */
+-      unsigned char ns_save; 
+-      unsigned long flags;
+-
+-      if (pdu_ack > 0) 
+-              ack = pdu_ack -1;
+-      else 
+-              ack = 127;
+-
+-      ack_count = 0;
+-
+-      save_flags(flags);
+-      cli();
+-
+-      pp = skb_dequeue(&lp->rtq); 
+-      while (pp != NULL)
+-      {
+-              /* 
+-               *      Locate skb with N(S) == ack 
+-               */
+-
+-              /*
+-               *      BUG: FIXME - use skb->h.*
+-               */
+-              fr = (frameptr) (pp->data + lp->dev->hard_header_len);
+-              ns_save = fr->i_hdr.ns;
+-
+-              kfree_skb(pp);
+-              ack_count++;
+-
+-              if (ns_save == ack) 
+-                      break;  
+-              pp = skb_dequeue(&lp->rtq);
+-      }
+-      restore_flags(flags);
+-      return ack_count; 
+-}
+-
+diff -uNr linux/net/802/llc_utility.c linux-llc/net/802/llc_utility.c
+--- linux/net/802/llc_utility.c        Thu Dec 12 14:54:22 1996
++++ linux-llc/net/802/llc_utility.c    Thu Jan  1 01:00:00 1970
+@@ -1,253 +0,0 @@
+-/*
+- * NET                An implementation of the IEEE 802.2 LLC protocol for the
+- *            LINUX operating system.  LLC is implemented as a set of 
+- *            state machines and callbacks for higher networking layers.
+- *
+- *            Small utilities, Linux timer handling.
+- *
+- *            Written by Tim Alpaerts, Tim_Alpaerts@toyota-motor-europe.com
+- *
+- *            This program is free software; you can redistribute it and/or
+- *            modify it under the terms of the GNU General Public License
+- *            as published by the Free Software Foundation; either version
+- *            2 of the License, or (at your option) any later version.
+- *
+- *    Changes
+- *            Alan Cox        :       Chainsawed into Linux form.
+- *                                    Added llc_ function name prefixes.
+- *                                    Fixed bug in stop/start timer.
+- *                                    Added llc_cancel_timers for closing
+- *                                            down an llc
+- */
+-
+-#include <linux/types.h>
+-#include <linux/kernel.h>
+-#include <linux/netdevice.h>
+-#include <linux/skbuff.h>
+-#include <linux/proc_fs.h>
+-#include <linux/stat.h>
+-#include <net/llc_frame.h>
+-#include <net/llc.h>
+-
+-int llc_decode_frametype(frameptr fr)
+-{
+-      if (IS_UFRAME(fr)) 
+-      {      /* unnumbered cmd/rsp */
+-              switch(fr->u_mm.mm & 0x3B)
+-              {
+-                      case 0x1B:
+-                          return(SABME_CMD);
+-                          break;
+-                      case 0x10:
+-                          return(DISC_CMD);
+-                          break;
+-                      case 0x18:
+-                          return(UA_RSP);
+-                          break;
+-                      case 0x03:
+-                          return(DM_RSP);
+-                          break;
+-                      case 0x21:
+-                          return(FRMR_RSP);
+-                          break;
+-                      case 0x00:
+-                          return(UI_CMD);
+-                          break;
+-                      case 0x2B:
+-                          if (IS_RSP(fr)) 
+-                              return(XID_RSP);
+-                          else
+-                              return(XID_CMD);
+-                          break;
+-                      case 0x38:
+-                          if (IS_RSP(fr))
+-                              return(TEST_RSP);
+-                          else
+-                              return(TEST_CMD);
+-                          break;
+-                      default:
+-                          return(BAD_FRAME);
+-              }
+-      }
+-      else if (IS_SFRAME(fr))
+-      {  /* supervisory cmd/rsp */
+-              switch(fr->s_hdr.ss)
+-              {
+-                      case 0x00:
+-                          if (IS_RSP(fr)) 
+-                              return(RR_RSP);
+-                          else
+-                              return(RR_CMD);
+-                          break;
+-                      case 0x02:
+-                          if (IS_RSP(fr))
+-                              return(REJ_RSP);
+-                          else
+-                              return(REJ_CMD);
+-                          break;
+-                      case 0x01:
+-                          if (IS_RSP(fr))
+-                              return(RNR_RSP);
+-                          else
+-                              return(RNR_CMD);
+-                          break;
+-                      default:
+-                          return(BAD_FRAME);
+-              }
+-      }
+-      else
+-      {                         /* information xfer */
+-              if (IS_RSP(fr)) 
+-                      return(I_RSP);
+-              else    
+-                      return(I_CMD);
+-      }
+-}
+-
+-
+-/*
+- *    Validate_seq_nos will check N(S) and N(R) to see if they are
+- *    invalid or unexpected.
+- *    "unexpected" is explained on p44 Send State Variable.
+- *    The return value is:
+- *            4 * invalid N(R) +
+- *            2 * invalid N(S) +
+- *            1 * unexpected N(S)
+- */
+-
+-int llc_validate_seq_nos(llcptr lp, frameptr fr)
+-{
+-      int res;
+-     
+-      /*
+-       *      A U-frame is always good 
+-       */
+-
+-      if (IS_UFRAME(fr)) 
+-              return(0);      
+-
+-      /*
+-       *      For S- and I-frames check N(R): 
+-       */
+-
+-      if (fr->i_hdr.nr == lp->vs) 
+-      {       /* if N(R) = V(S)  */
+-              res = 0;                        /* N(R) is good */
+-      }
+-      else
+-      {                               /* lp->k = transmit window size */
+-              if (lp->vs >= lp->k) 
+-              {       /* if window not wrapped around 127 */
+-                      if ((fr->i_hdr.nr < lp->vs) &&
+-                              (fr->i_hdr.nr > (lp->vs - lp->k)))
+-                              res = 0;
+-                      else 
+-                              res = 4;                /* N(R) invalid */
+-              }
+-              else
+-              {       /* window wraps around 127 */
+-                      if ((fr->i_hdr.nr < lp->vs) ||
+-                              (fr->i_hdr.nr > (128 + lp->vs - lp->k))) 
+-                              res = 0;
+-                      else
+-                              res = 4;                /* N(R) invalid */
+-              }
+-      }
+-
+-      /*
+-       *      For an I-frame, must check N(S) also:  
+-       */
+-
+-      if (IS_IFRAME(fr)) 
+-      {
+-              if (fr->i_hdr.ns == lp->vr) 
+-                      return res;   /* N(S) good */
+-              if (lp->vr >= lp->rw) 
+-              {
+-                      /* if receive window not wrapped */
+-
+-                      if ((fr->i_hdr.ns < lp->vr) &&
+-                              (fr->i_hdr.ns > (lp->vr - lp->k)))
+-                              res = res +1;           /* N(S) unexpected */
+-                      else  
+-                              res = res +2;         /* N(S) invalid */            
+-              }
+-              else
+-              {
+-                      /* Window wraps around 127 */
+-
+-                      if ((fr->i_hdr.ns < lp->vr) ||
+-                              (fr->i_hdr.ns > (128 + lp->vr - lp->k)))
+-                              res = res +1;           /* N(S) unexpected */
+-                      else
+-                              res = res +2;         /* N(S) invalid */            
+-              }
+-      }                                       
+-      return(res);
+-}
+-
+-/* **************** timer management routines ********************* */
+-
+-static void llc_p_timer_expired(unsigned long ulp)
+-{
+-      llc_timer_expired((llcptr) ulp, P_TIMER);
+-}
+-
+-static void llc_rej_timer_expired(unsigned long ulp)
+-{
+-      llc_timer_expired((llcptr) ulp, REJ_TIMER);
+-}
+-
+-static void llc_ack_timer_expired(unsigned long ulp)
+-{
+-      llc_timer_expired((llcptr) ulp, ACK_TIMER);
+-} 
+-
+-static void llc_busy_timer_expired(unsigned long ulp)
+-{
+-      llc_timer_expired((llcptr) ulp, BUSY_TIMER);
+-}
+-
+-/* exp_fcn is an array holding the 4 entry points of the
+-   timer expiry routines above.
+-   It is required to keep start_timer() generic.
+-   Thank you cdecl.
+- */
+-
+-static void (* exp_fcn[])(unsigned long) = 
+-{
+-      llc_p_timer_expired,
+-      llc_rej_timer_expired,
+-      llc_ack_timer_expired,
+-      llc_busy_timer_expired
+-};   
+-
+-void llc_start_timer(llcptr lp, int t)
+-{
+-      if (lp->timer_state[t] == TIMER_IDLE)
+-      {
+-              lp->tl[t].expires = jiffies + lp->timer_interval[t];
+-              lp->tl[t].data = (unsigned long) lp;
+-              lp->tl[t].function = exp_fcn[t];
+-              add_timer(&lp->tl[t]);
+-              lp->timer_state[t] = TIMER_RUNNING;
+-      }
+-}
+-
+-void llc_stop_timer(llcptr lp, int t)
+-{
+-      if (lp->timer_state[t] == TIMER_RUNNING)
+-      {
+-              del_timer(&lp->tl[t]);
+-              lp->timer_state[t] = TIMER_IDLE;
+-      }
+-}
+-
+-void llc_cancel_timers(llcptr lp)
+-{
+-      llc_stop_timer(lp, P_TIMER);
+-      llc_stop_timer(lp, REJ_TIMER);
+-      llc_stop_timer(lp, ACK_TIMER);
+-      llc_stop_timer(lp, BUSY_TIMER);
+-}
+-
+diff -uNr linux/net/802/p8022.c linux-llc/net/802/p8022.c
+--- linux/net/802/p8022.c      Thu May 21 02:55:16 1998
++++ linux-llc/net/802/p8022.c  Thu Jan  1 01:00:00 1970
+@@ -1,141 +0,0 @@
+-/*
+- *    NET3:   Support for 802.2 demultiplexing off Ethernet (Token ring
+- *            is kept separate see p8022tr.c)
+- *            This program is free software; you can redistribute it and/or
+- *            modify it under the terms of the GNU General Public License
+- *            as published by the Free Software Foundation; either version
+- *            2 of the License, or (at your option) any later version.
+- *
+- *            Demultiplex 802.2 encoded protocols. We match the entry by the
+- *            SSAP/DSAP pair and then deliver to the registered datalink that
+- *            matches. The control byte is ignored and handling of such items
+- *            is up to the routine passed the frame.
+- *
+- *            Unlike the 802.3 datalink we have a list of 802.2 entries as there
+- *            are multiple protocols to demux. The list is currently short (3 or
+- *            4 entries at most). The current demux assumes this.
+- */
+-
+-#include <linux/module.h>
+-#include <linux/netdevice.h>
+-#include <linux/skbuff.h>
+-#include <net/datalink.h>
+-#include <linux/mm.h>
+-#include <linux/in.h>
+-#include <linux/init.h>
+-#include <net/p8022.h>
+-
+-static struct datalink_proto *p8022_list = NULL;
+-
+-/*
+- *    We don't handle the loopback SAP stuff, the extended
+- *    802.2 command set, multicast SAP identifiers and non UI
+- *    frames. We have the absolute minimum needed for IPX,
+- *    IP and Appletalk phase 2. See the llc_* routines for
+- *    support libraries if your protocol needs these.
+- */
+-
+-static struct datalink_proto *find_8022_client(unsigned char type)
+-{
+-      struct datalink_proto   *proto;
+-
+-      for (proto = p8022_list;
+-              ((proto != NULL) && (*(proto->type) != type));
+-              proto = proto->next)
+-              ;
+-
+-      return proto;
+-}
+-
+-int p8022_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
+-{
+-      struct datalink_proto   *proto;
+-
+-      proto = find_8022_client(*(skb->h.raw));
+-      if (proto != NULL) 
+-      {
+-              skb->h.raw += 3;
+-              skb->nh.raw += 3;
+-              skb_pull(skb,3);
+-              return proto->rcvfunc(skb, dev, pt);
+-      }
+-
+-      skb->sk = NULL;
+-      kfree_skb(skb);
+-      return 0;
+-}
+-
+-static void p8022_datalink_header(struct datalink_proto *dl,
+-              struct sk_buff *skb, unsigned char *dest_node)
+-{
+-      struct device   *dev = skb->dev;
+-      unsigned char   *rawp;
+-
+-      rawp = skb_push(skb,3);
+-      *rawp++ = dl->type[0];
+-      *rawp++ = dl->type[0];
+-      *rawp = 0x03;   /* UI */
+-      dev->hard_header(skb, dev, ETH_P_802_3, dest_node, NULL, skb->len);
+-}
+-
+-static struct packet_type p8022_packet_type =
+-{
+-      0,      /* MUTTER ntohs(ETH_P_8022),*/
+-      NULL,           /* All devices */
+-      p8022_rcv,
+-      NULL,
+-      NULL,
+-};
+-
+-EXPORT_SYMBOL(register_8022_client);
+-EXPORT_SYMBOL(unregister_8022_client);
+-
+-__initfunc(void p8022_proto_init(struct net_proto *pro))
+-{
+-      p8022_packet_type.type=htons(ETH_P_802_2);
+-      dev_add_pack(&p8022_packet_type);
+-}
+-
+-struct datalink_proto *register_8022_client(unsigned char type, int (*rcvfunc)(struct sk_buff *, struct device *, struct packet_type *))
+-{
+-      struct datalink_proto   *proto;
+-
+-      if (find_8022_client(type) != NULL)
+-              return NULL;
+-
+-      proto = (struct datalink_proto *) kmalloc(sizeof(*proto), GFP_ATOMIC);
+-      if (proto != NULL) {
+-              proto->type[0] = type;
+-              proto->type_len = 1;
+-              proto->rcvfunc = rcvfunc;
+-              proto->header_length = 3;
+-              proto->datalink_header = p8022_datalink_header;
+-              proto->string_name = "802.2";
+-              proto->next = p8022_list;
+-              p8022_list = proto;
+-      }
+-
+-      return proto;
+-}
+-
+-void unregister_8022_client(unsigned char type)
+-{
+-      struct datalink_proto *tmp, **clients = &p8022_list;
+-      unsigned long flags;
+-
+-      save_flags(flags);
+-      cli();
+-
+-      while ((tmp = *clients) != NULL)
+-      {
+-              if (tmp->type[0] == type) {
+-                      *clients = tmp->next;
+-                      kfree_s(tmp, sizeof(struct datalink_proto));
+-                      break;
+-              } else {
+-                      clients = &tmp->next;
+-              }
+-      }
+-
+-      restore_flags(flags);
+-}
+diff -uNr linux/net/802/p8023.c linux-llc/net/802/p8023.c
+--- linux/net/802/p8023.c      Thu Jan  2 13:13:27 1997
++++ linux-llc/net/802/p8023.c  Thu Jan  1 01:00:00 1970
+@@ -1,62 +0,0 @@
+-/*
+- *    NET3:   802.3 data link hooks used for IPX 802.3
+- *
+- *    This program is free software; you can redistribute it and/or
+- *    modify it under the terms of the GNU General Public License
+- *    as published by the Free Software Foundation; either version
+- *    2 of the License, or (at your option) any later version.
+- *
+- *    802.3 isn't really a protocol data link layer. Some old IPX stuff
+- *    uses it however. Note that there is only one 802.3 protocol layer
+- *    in the system. We don't currently support different protocols
+- *    running raw 802.3 on different devices. Thankfully nobody else
+- *    has done anything like the old IPX.
+- */
+- 
+-#include <linux/netdevice.h>
+-#include <linux/skbuff.h>
+-#include <net/datalink.h>
+-#include <linux/mm.h>
+-#include <linux/in.h>
+-
+-/*
+- *    Place an 802.3 header on a packet. The driver will do the mac
+- *    addresses, we just need to give it the buffer length.
+- */
+- 
+-static void p8023_datalink_header(struct datalink_proto *dl, 
+-              struct sk_buff *skb, unsigned char *dest_node)
+-{
+-      struct device   *dev = skb->dev;
+-      dev->hard_header(skb, dev, ETH_P_802_3, dest_node, NULL, skb->len);
+-}
+-
+-/*
+- *    Create an 802.3 client. Note there can be only one 802.3 client
+- */
+- 
+-struct datalink_proto *make_8023_client(void)
+-{
+-      struct datalink_proto   *proto;
+-
+-      proto = (struct datalink_proto *) kmalloc(sizeof(*proto), GFP_ATOMIC);
+-      if (proto != NULL) 
+-      {
+-              proto->type_len = 0;
+-              proto->header_length = 0;
+-              proto->datalink_header = p8023_datalink_header;
+-              proto->string_name = "802.3";
+-      }
+-      return proto;
+-}
+-
+-/*
+- *    Destroy the 802.3 client.
+- */
+- 
+-void destroy_8023_client(struct datalink_proto *dl)
+-{
+-      if (dl)
+-              kfree_s(dl,sizeof(struct datalink_proto));
+-}
+-
+diff -uNr linux/net/802/pseudo/Makefile linux-llc/net/802/pseudo/Makefile
+--- linux/net/802/pseudo/Makefile      Thu Dec 12 14:54:22 1996
++++ linux-llc/net/802/pseudo/Makefile  Thu Jan  1 01:00:00 1970
+@@ -1,13 +0,0 @@
+-all:  pseudocode.h actionnm.h
+-
+-clean:
+-      touch pseudocode.h actionnm.h
+-      rm pseudocode.h actionnm.h
+-
+-pseudocode.h: pseudocode opcd2num.sed compile.awk
+-      sed -f opcd2num.sed pseudocode |  awk -f compile.awk >pseudocode.h
+-
+-actionnm.h: pseudocode.h actionnm.awk
+-      awk -f actionnm.awk pseudocode.h>actionnm.h
+-
+-      
+diff -uNr linux/net/802/pseudo/actionnm.awk linux-llc/net/802/pseudo/actionnm.awk
+--- linux/net/802/pseudo/actionnm.awk  Thu Dec 12 14:54:22 1996
++++ linux-llc/net/802/pseudo/actionnm.awk      Thu Jan  1 01:00:00 1970
+@@ -1,27 +0,0 @@
+-# usage: awk -f actionnm.awk pseudocode.h
+-#
+-BEGIN { "date" | getline
+-      today = $0
+-      printf("\n/* this file generated on %s  */\n", today )
+-      printf("\nstatic char *action_names[] = { \n    " )
+-      opl = 0
+-}
+-
+-/^#define/ {                  
+-      if ( opl > 3 ) {
+-          printf("\n    ")
+-          opl = 0
+-      }
+-      opl = opl +1
+-      t = sprintf("\"%s\"", $2 )
+-      printf("%-15s ,", t )
+-#     printf("%-10s", $2 )
+-}
+-
+-END {         
+-      if ( opl > 3 ) {
+-          printf("\n    ")
+-      }
+-      printf("\t  0\n};\n\n")
+-}
+-
+diff -uNr linux/net/802/pseudo/actionnm.h linux-llc/net/802/pseudo/actionnm.h
+--- linux/net/802/pseudo/actionnm.h    Thu Dec 12 14:54:22 1996
++++ linux-llc/net/802/pseudo/actionnm.h        Thu Jan  1 01:00:00 1970
+@@ -1,51 +0,0 @@
+-
+-/* this file generated on Thu Oct 24 11:42:37 GMT 1996  */
+-
+-static char *action_names[] = { 
+-    "NOP"           ,"ADM1"          ,"ADM2"          ,"ADM3"          ,
+-    "ADM4"          ,"ADM5"          ,"CONN2"         ,"CONN3"         ,
+-    "CONN4"         ,"CONN5"         ,"RESWAIT1"      ,"RESWAIT2"      ,
+-    "RESWAIT3"      ,"RESWAIT4"      ,"RESWAIT5"      ,"RESWAIT6"      ,
+-    "RESWAIT7"      ,"RESWAIT8"      ,"RESCHK1"       ,"RESCHK2"       ,
+-    "RESCHK3"       ,"RESCHK4"       ,"RESCHK5"       ,"RESCHK6"       ,
+-    "SETUP1"        ,"SETUP2"        ,"SETUP3"        ,"SETUP4"        ,
+-    "SETUP5"        ,"SETUP6"        ,"SETUP7"        ,"SETUP8"        ,
+-    "RESET1"        ,"RESET2"        ,"RESET3"        ,"RESET4"        ,
+-    "RESET5"        ,"RESET6"        ,"RESET7"        ,"RESET8"        ,
+-    "D_CONN1"       ,"D_CONN2"       ,"D_CONN3"       ,"D_CONN4"       ,
+-    "D_CONN5"       ,"D_CONN6"       ,"D_CONN7"       ,"ERR1"          ,
+-    "ERR2"          ,"ERR3"          ,"ERR4"          ,"ERR5"          ,
+-    "ERR6"          ,"ERR7"          ,"ERR8"          ,"SH1"           ,
+-    "SH2"           ,"SH3"           ,"SH4"           ,"SH5"           ,
+-    "SH6"           ,"SH7"           ,"SH8"           ,"SH9"           ,
+-    "SH10"          ,"SH11"          ,"NORMAL1"       ,"NORMAL2"       ,
+-    "NORMAL3"       ,"NORMAL4"       ,"NORMAL5"       ,"NORMAL6"       ,
+-    "NORMAL7"       ,"NORMAL8A"      ,"NORMAL8B"      ,"NORMAL9"       ,
+-    "NORMAL10"      ,"NORMAL11"      ,"NORMAL12"      ,"NORMAL13"      ,
+-    "NORMAL14"      ,"NORMAL15"      ,"NORMAL16"      ,"NORMAL17"      ,
+-    "NORMAL18"      ,"NORMAL19"      ,"NORMAL20"      ,"BUSY1"         ,
+-    "BUSY2"         ,"BUSY3"         ,"BUSY4"         ,"BUSY5"         ,
+-    "BUSY6"         ,"BUSY7"         ,"BUSY8"         ,"BUSY9"         ,
+-    "BUSY10"        ,"BUSY11"        ,"BUSY12"        ,"BUSY13"        ,
+-    "BUSY14"        ,"BUSY15"        ,"BUSY16"        ,"BUSY17"        ,
+-    "BUSY18"        ,"BUSY19"        ,"BUSY20"        ,"BUSY21"        ,
+-    "BUSY22"        ,"BUSY23"        ,"BUSY24"        ,"BUSY25"        ,
+-    "BUSY26"        ,"REJECT1"       ,"REJECT2"       ,"REJECT3"       ,
+-    "REJECT4"       ,"REJECT5"       ,"REJECT6"       ,"REJECT7"       ,
+-    "REJECT8"       ,"REJECT9"       ,"REJECT10"      ,"REJECT11"      ,
+-    "REJECT12"      ,"REJECT13"      ,"REJECT14"      ,"REJECT15"      ,
+-    "REJECT16"      ,"REJECT17"      ,"REJECT18"      ,"REJECT19"      ,
+-    "REJECT20"      ,"AWAIT1"        ,"AWAIT2"        ,"AWAIT3"        ,
+-    "AWAIT4"        ,"AWAIT5"        ,"AWAIT6"        ,"AWAIT7"        ,
+-    "AWAIT8"        ,"AWAIT9"        ,"AWAIT10"       ,"AWAIT11"       ,
+-    "AWAIT12"       ,"AWAIT13"       ,"AWAIT14"       ,"AWAIT_BUSY1"   ,
+-    "AWAIT_BUSY2"   ,"AWAIT_BUSY3"   ,"AWAIT_BUSY4"   ,"AWAIT_BUSY5"   ,
+-    "AWAIT_BUSY6"   ,"AWAIT_BUSY7"   ,"AWAIT_BUSY8"   ,"AWAIT_BUSY9"   ,
+-    "AWAIT_BUSY10"  ,"AWAIT_BUSY11"  ,"AWAIT_BUSY12"  ,"AWAIT_BUSY13"  ,
+-    "AWAIT_BUSY14"  ,"AWAIT_BUSY15"  ,"AWAIT_BUSY16"  ,"AWAIT_REJECT1" ,
+-    "AWAIT_REJECT2" ,"AWAIT_REJECT3" ,"AWAIT_REJECT4" ,"AWAIT_REJECT5" ,
+-    "AWAIT_REJECT6" ,"AWAIT_REJECT7" ,"AWAIT_REJECT8" ,"AWAIT_REJECT9" ,
+-    "AWAIT_REJECT10" ,"AWAIT_REJECT11" ,"AWAIT_REJECT12" ,"AWAIT_REJECT13" ,
+-        0
+-};
+-
+diff -uNr linux/net/802/pseudo/compile.awk linux-llc/net/802/pseudo/compile.awk
+--- linux/net/802/pseudo/compile.awk   Thu Dec 12 14:54:22 1996
++++ linux-llc/net/802/pseudo/compile.awk       Thu Jan  1 01:00:00 1970
+@@ -1,57 +0,0 @@
+-# usage: cat pseudocode | sed -f act2num | awk -f compile.awk
+-#
+-#
+-BEGIN { "date" | getline
+-      today = $0
+-      printf("\n/* this file generated on %s  */\n", today )
+-      printf("\nstatic char pseudo_code [ ] = { \n" )
+-      opl = 0                 # op codes on the current line
+-
+-      opc = 0                 # opcode counter
+-      fpi = 0                 # fill pointer for idx array
+-}
+-
+-/^;/ { }                      # line starting with semicolon is comment 
+-
+-/^[A-Z]/ {                    # start of a new action 
+-      emit( 0 )
+-      idx[ ++fpi ] = opc
+-      name[ fpi ] = $1 
+-      emit( $2 )
+-}
+-
+-/^[\t ]/ { 
+-        emit( $1 )
+-}
+-
+-END {         
+-      if ( opl > 8 ) {
+-          printf("\n")
+-      }
+-      printf("\t  0\n};\n\n")
+-      printf("static short int pseudo_code_idx [ ] ={\n")
+-      opl = 0
+-      emit( 0 )
+-      for( ii = 1; ii <= fpi; ii++ )
+-         e