
/*
 * (llc_stk.c) - Implements LLC initialization and deinitialization
 *
 * Copyright (c) 1997 by Procom Technology,Inc.
 *
 * This program can be redistributed or modified under the terms of the 
 * GNU General Public License as published by the Free Software Foundation.
 * This program is distributed without any warranty or implied warranty
 * of merchantability or fitness for a particular purpose.
 *
 * See the GNU General Public License for more details.
 *
 */
 

#define LLC_STK_C

#ifdef MODULE
#include <linux/module.h>
#endif

#include <linux/kernel.h>
#include <linux/skbuff.h>
#include <linux/sched.h>
#include <net/cm_types.h>
#include <net/cm_mm.h>
#include <net/os_if.h>
#include <net/cm_dll.h>
#include <net/cm_frame.h>
#include <net/llc_if.h>
#include <net/llc_sap.h>
#include <net/llc_conn.h>
#include <net/lan_hdrs.h>          /* get size of MAC address */
#include <net/llc_main.h>
#include <net/llc_evnt.h>
#include <net/llc_actn.h>
#include <net/llc_stat.h>
#include <net/llc_glob.h>
#include <net/llc_mac.h>
#include <net/os_if.h>
#include <net/llc_stk.h>
#include <net/llc_dbg.h>

#ifdef LLC_STK_DBG
  #define  DBG_MSG(body) { printk body; }
#else
  #define  DBG_MSG(body)  ;
#endif

#define LLC_INIT_TABLE_SIZE (sizeof(Llc_init_exit_table)/sizeof(init_and_exit_t))

typedef struct
{
	us16	(*init_func) (void);
	us16	(*exit_func) (void);
	us8 *	desc;
} init_and_exit_t;

static init_and_exit_t     Llc_init_exit_table [] = 
{                                          
	{ mm_init,       mm_exit,       "memory management"         },
	{ dll_init,      dll_exit,      "buffer table management"   },
	{ frame_init,    frame_exit,    "frame management"          },
	{ llc_glob_init, llc_glob_exit, "layer configuration"       },
	{ mac_init,      mac_exit,      "MAC interface"             },
	{ llc_lm_init,   llc_lm_exit,   "layer management"          },
	{ llc_init,      llc_exit,      "Layer"                     }
};                                     


void
p8022_proto_init(struct net_proto *pro)
{
	int rc = 1;

	printk(KERN_ERR "\nProcom LLC (version 1.10)\n");
	printk(KERN_ERR "NET3.035: IEEE 802.2 extended support.\n");
	rc = (int) llc_layer_init ();  
	if (!rc) {
		printk(KERN_ERR "\nLLC installation successful.\n");
		register_symtab(&llc_symbols);
	} else {
		printk(KERN_ERR "\nLLC installation NOT successful.\n");
		llc_layer_deinit();
	}

	printk("\n");
	return;
}


void
p8022_proto_done(void)
{
	llc_layer_deinit();
}

/*
 * Function: p8022_proto_init
 *	Tries to complete all LLC initializations.
 *
 * Returns:
 *	0, on success
 *	nonzero, otherwise
 */

us16
llc_layer_init ()
{
	us16	i;
	us16	rc;

	for (i = 0, rc = 0; (i < LLC_INIT_TABLE_SIZE) && !rc; i++) {
		rc = Llc_init_exit_table [i].init_func ();
		#ifdef FDBG
		if (rc) {
			printk(KERN_ERR "llc_layer_init failed in function '%s'\n",
						Llc_init_exit_table [i].desc);
		}
		#endif
		#ifdef TESTING
		mm_inquire ();
		#endif
	}
	return (rc);
}

us16
llc_layer_deinit ()
{
	int	i;
	us16	rc;

	for (rc = 0, i = (LLC_INIT_TABLE_SIZE - 1); (i >= 0) && !rc; i--) {
		rc = Llc_init_exit_table [i].exit_func ();
		#ifdef FDBG
		if (rc) {
			printk(KERN_ERR "llc_layer_deinit failed in function '%s'\n",
					Llc_init_exit_table [i].desc);
		}
		#endif
		#ifdef TESTING
		mm_inquire ();
		#endif
	}
	return (rc);
}


#ifdef MODULE

int
init_module(void)
{
	p8022_proto_init((struct net_proto *)NULL);
	return 0;
}

void
cleanup_module(void)
{
	p8022_proto_done();
}
 
#endif
