/*********************************************************************
 *
 * Filename:      irlan_common.c
 * Version:       0.9
 * Description:   IrDA LAN Access Protocol Implementation
 * Status:        Experimental.
 * Author:        Dag Brattli <dagb@cs.uit.no>
 * Created at:    Sun Aug 31 20:14:37 1997
 * Modified at:   Sun Dec 26 21:53:10 1999
 * Modified by:   Dag Brattli <dagb@cs.uit.no>
 *
 *     Copyright (c) 1997, 1999 Dag Brattli <dagb@cs.uit.no>,
 *     All Rights Reserved.
 *
 *     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.
 *
 *     Neither Dag Brattli nor University of Tromsø admit liability nor
 *     provide warranty for any of this software. This material is
 *     provided "AS-IS" and at no charge.
 *
 ********************************************************************/

#include <linux/module.h>

#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/gfp.h>
#include <linux/init.h>
#include <linux/errno.h>
#include <linux/proc_fs.h>
#include <linux/sched.h>
#include <linux/seq_file.h>
#include <linux/random.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/rtnetlink.h>
#include <linux/moduleparam.h>
#include <linux/bitops.h>

#include <asm/byteorder.h>

#include <net/irda/irda.h>
#include <net/irda/irttp.h>
#include <net/irda/irlmp.h>
#include <net/irda/iriap.h>
#include <net/irda/timer.h>

#include <net/irda/irlan_common.h>
#include <net/irda/irlan_client.h>
#include <net/irda/irlan_provider.h>
#include <net/irda/irlan_eth.h>
#include <net/irda/irlan_filter.h>


/* extern char sysctl_devname[]; */

/*
 *  Master structure
 */
static LIST_HEAD(irlans);

static void *ckey;
static void *skey;

/* Module parameters */
static bool eth;   /* Use "eth" or "irlan" name for devices */
static int access = ACCESS_PEER; /* PEER, DIRECT or HOSTED */

#ifdef CONFIG_PROC_FS
static const char *const irlan_access[] = {
	"UNKNOWN",
	"DIRECT",
	"PEER",
	"HOSTED"
};

static const char *const irlan_media[] = {
	"UNKNOWN",
	"802.3",
	"802.5"
};

extern struct proc_dir_entry *proc_irda;

static int irlan_seq_open(struct inode *inode, struct file *file);

static const struct file_operations irlan_fops = {
	.owner	 = THIS_MODULE,
	.open    = irlan_seq_open,
	.read    = seq_read,
	.llseek  = seq_lseek,
	.release = seq_release,
};

extern struct proc_dir_entry *proc_irda;
#endif /* CONFIG_PROC_FS */

static struct irlan_cb __init *irlan_open(__u32 saddr, __u32 daddr);
static void __irlan_close(struct irlan_cb *self);
static int __irlan_insert_param(struct sk_buff *skb, char *param, int type,
				__u8 value_byte, __u16 value_short,
				__u8 *value_array, __u16 value_len);
static void irlan_open_unicast_addr(struct irlan_cb *self);
static void irlan_get_unicast_addr(struct irlan_cb *self);
void irlan_close_tsaps(struct irlan_cb *self);

/*
 * Function irlan_init (void)
 *
 *    Initialize IrLAN layer
 *
 */
static int __init irlan_init(void)
{
	struct irlan_cb *new;
	__u16 hints;

#ifdef CONFIG_PROC_FS
	{ struct proc_dir_entry *proc;
	proc = proc_create("irlan", 0, proc_irda, &irlan_fops);
	if (!proc) {
		printk(KERN_ERR "irlan_init: can't create /proc entry!\n");
		return -ENODEV;
	}
	}
#endif /* CONFIG_PROC_FS */

	hints = irlmp_service_to_hint(S_LAN);

	/* Register with IrLMP as a client */
	ckey = irlmp_register_client(hints, &irlan_client_discovery_indication,
				     NULL, NULL);
	if (!ckey)
		goto err_ckey;

	/* Register with IrLMP as a service */
	skey = irlmp_register_service(hints);
	if (!skey)
		goto err_skey;

	/* Start the master IrLAN instance (the only one for now) */
	new = irlan_open(DEV_ADDR_ANY, DEV_ADDR_ANY);
	if (!new)
		goto err_open;

	/* The master will only open its (listen) control TSAP */
	irlan_provider_open_ctrl_tsap(new);

	/* Do some fast discovery! */
	irlmp_discovery_request(DISCOVERY_DEFAULT_SLOTS);

	return 0;

err_open:
	irlmp_unregister_service(skey);
err_skey:
	irlmp_unregister_client(ckey);
err_ckey:
#ifdef CONFIG_PROC_FS
	remove_proc_entry("irlan", proc_irda);
#endif /* CONFIG_PROC_FS */

	return -ENOMEM;
}

static void __exit irlan_cleanup(void)
{
	struct irlan_cb *self, *next;

	irlmp_unregister_client(ckey);
	irlmp_unregister_service(skey);

#ifdef CONFIG_PROC_FS
	remove_proc_entry("irlan", proc_irda);
#endif /* CONFIG_PROC_FS */

	/* Cleanup any leftover network devices */
	rtnl_lock();
	list_for_each_entry_safe(self, next, &irlans, dev_list) {
		__irlan_close(self);
	}
	rtnl_unlock();
}

/*
 * Function irlan_open (void)
 *
 *    Open new instance of a client/provider, we should only register the
 *    network device if this instance is ment for a particular client/provider
 */
static struct irlan_cb __init *irlan_open(__u32 saddr, __u32 daddr)
{
	struct net_device *dev;
	struct irlan_cb *self;

	/* Create network device with irlan */
	dev = alloc_irlandev(eth ? "eth%d" : "irlan%d");
	if (!dev)
		return NULL;

	self = netdev_priv(dev);
	self->dev = dev;

	/*
	 *  Initialize local device structure
	 */
	self->magic = IRLAN_MAGIC;
	self->saddr = saddr;
	self->daddr = daddr;

	/* Provider access can only be PEER, DIRECT, or HOSTED */
	self->provider.access_type = access;
	if (access == ACCESS_DIRECT) {
		/*
		 * Since we are emulating an IrLAN sever we will have to
		 * give ourself an ethernet address!
		 */
		dev->dev_addr[0] = 0x40;
		dev->dev_addr[1] = 0x00;
		dev->dev_addr[2] = 0x00;
		dev->dev_addr[3] = 0x00;
		get_random_bytes(dev->dev_addr+4, 1);
		get_random_bytes(dev->dev_addr+5, 1);
	}

	self->media = MEDIA_802_3;
	self->disconnect_reason = LM_USER_REQUEST;
	init_timer(&self->watchdog_timer);
	init_timer(&self->client.kick_timer);
	init_waitqueue_head(&self->open_wait);

	skb_queue_head_init(&self->client.txq);

	irlan_next_client_state(self, IRLAN_IDLE);
	irlan_next_provider_state(self, IRLAN_IDLE);

	if (register_netdev(dev)) {
		pr_debug("%s(), register_netdev() failed!\n",
			 __func__);
		self = NULL;
		free_netdev(dev);
	} else {
		rtnl_lock();
		list_add_rcu(&self->dev_list, &irlans);
		rtnl_unlock();
	}

	return self;
}
/*
 * Function __irlan_close (self)
 *
 *    This function closes and deallocates the IrLAN client instances. Be
 *    aware that other functions which calls client_close() must
 *    remove self from irlans list first.
 */
static void __irlan_close(struct irlan_cb *self)
{
	ASSERT_RTNL();
	IRDA_ASSERT(self != NULL, return;);
	IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);

	del_timer_sync(&self->watchdog_timer);
	del_timer_sync(&self->client.kick_timer);

	/* Close all open connections and remove TSAPs */
	irlan_close_tsaps(self);

	if (self->client.iriap)
		iriap_close(self->client.iriap);

	/* Remove frames queued on the control channel */
	skb_queue_purge(&self->client.txq);

	/* Unregister and free self via destructor */
	unregister_netdevice(self->dev);
}

/* Find any instance of irlan, used for client discovery wakeup */
struct irlan_cb *irlan_get_any(void)
{
	struct irlan_cb *self;

	list_for_each_entry_rcu(self, &irlans, dev_list) {
		return self;
	}
	return NULL;
}

/*
 * Function irlan_connect_indication (instance, sap, qos, max_sdu_size, skb)
 *
 *    Here we receive the connect indication for the data channel
 *
 */
static void irlan_connect_indication(void *instance, void *sap,
				     struct qos_info *qos,
				     __u32 max_sdu_size,
				     __u8 max_header_size,
				     struct sk_buff *skb)
{
	struct irlan_cb *self;
	struct tsap_cb *tsap;

	self = instance;
	tsap = sap;

	IRDA_ASSERT(self != NULL, return;);
	IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
	IRDA_ASSERT(tsap == self->tsap_data,return;);

	self->max_sdu_size = max_sdu_size;
	self->max_header_size = max_header_size;

	pr_debug("%s: We are now connected!\n", __func__);

	del_timer(&self->watchdog_timer);

	/* If you want to pass the skb to *both* state machines, you will
	 * need to skb_clone() it, so that you don't free it twice.
	 * As the state machines don't need it, git rid of it here...
	 * Jean II */
	if (skb)
		dev_kfree_skb(skb);

	irlan_do_provider_event(self, IRLAN_DATA_CONNECT_INDICATION, NULL);
	irlan_do_client_event(self, IRLAN_DATA_CONNECT_INDICATION, NULL);

	if (self->provider.access_type == ACCESS_PEER) {
		/*
		 * Data channel is open, so we are now allowed to
		 * configure the remote filter
		 */
		irlan_get_unicast_addr(self);
		irlan_open_unicast_addr(self);
	}
	/* Ready to transfer Ethernet frames (at last) */
	netif_start_queue(self->dev); /* Clear reason */
}

static void irlan_connect_confirm(void *instance, void *sap,
				  struct qos_info *qos,
				  __u32 max_sdu_size,
				  __u8 max_header_size,
				  struct sk_buff *skb)
{
	struct irlan_cb *self;

	self = instance;

	IRDA_ASSERT(self != NULL, return;);
	IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);

	self->max_sdu_size = max_sdu_size;
	self->max_header_size = max_header_size;

	/* TODO: we could set the MTU depending on the max_sdu_size */

	pr_debug("%s: We are now connected!\n", __func__);
	del_timer(&self->watchdog_timer);

	/*
	 * Data channel is open, so we are now allowed to configure the remote
	 * filter
	 */
	irlan_get_unicast_addr(self);
	irlan_open_unicast_addr(self);

	/* Open broadcast and multicast filter by default */
	irlan_set_broadcast_filter(self, TRUE);
	irlan_set_multicast_filter(self, TRUE);

	/* Ready to transfer Ethernet frames */
	netif_start_queue(self->dev);
	self->disconnect_reason = 0; /* Clear reason */
	wake_up_interruptible(&self->open_wait);
}

/*
 * Function irlan_client_disconnect_indication (handle)
 *
 *    Callback function for the IrTTP layer. Indicates a disconnection of
 *    the specified connection (handle)
 */
static void irlan_disconnect_indication(void *instance,
					void *sap, LM_REASON reason,
					struct sk_buff *userdata)
{
	struct irlan_cb *self;
	struct tsap_cb *tsap;

	pr_debug("%s(), reason=%d\n", __func__ , reason);

	self = instance;
	tsap = sap;

	IRDA_ASSERT(self != NULL, return;);
	IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);
	IRDA_ASSERT(tsap != NULL, return;);
	IRDA_ASSERT(tsap->magic == TTP_TSAP_MAGIC, return;);

	IRDA_ASSERT(tsap == self->tsap_data, return;);

	pr_debug("IrLAN, data channel disconnected by peer!\n");

	/* Save reason so we know if we should try to reconnect or not */
	self->disconnect_reason = reason;

	switch (reason) {
	case LM_USER_REQUEST: /* User request */
		pr_debug("%s(), User requested\n", __func__);
		break;
	case LM_LAP_DISCONNECT: /* Unexpected IrLAP disconnect */
		pr_debug("%s(), Unexpected IrLAP disconnect\n", __func__);
		break;
	case LM_CONNECT_FAILURE: /* Failed to establish IrLAP connection */
		pr_debug("%s(), IrLAP connect failed\n", __func__);
		break;
	case LM_LAP_RESET:  /* IrLAP reset */
		pr_debug("%s(), IrLAP reset\n", __func__);
		break;
	case LM_INIT_DISCONNECT:
		pr_debug("%s(), IrLMP connect failed\n", __func__);
		break;
	default:
		net_err_ratelimited("%s(), Unknown disconnect reason\n",
				    __func__);
		break;
	}

	/* If you want to pass the skb to *both* state machines, you will
	 * need to skb_clone() it, so that you don't free it twice.
	 * As the state machines don't need it, git rid of it here...
	 * Jean II */
	if (userdata)
		dev_kfree_skb(userdata);

	irlan_do_client_event(self, IRLAN_LMP_DISCONNECT, NULL);
	irlan_do_provider_event(self, IRLAN_LMP_DISCONNECT, NULL);

	wake_up_interruptible(&self->open_wait);
}

void irlan_open_data_tsap(struct irlan_cb *self)
{
	struct tsap_cb *tsap;
	notify_t notify;

	IRDA_ASSERT(self != NULL, return;);
	IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);

	/* Check if already open */
	if (self->tsap_data)
		return;

	irda_notify_init(&notify);

	notify.data_indication       = irlan_eth_receive;
	notify.udata_indication      = irlan_eth_receive;
	notify.connect_indication    = irlan_connect_indication;
	notify.connect_confirm       = irlan_connect_confirm;
	notify.flow_indication       = irlan_eth_flow_indication;
	notify.disconnect_indication = irlan_disconnect_indication;
	notify.instance              = self;
	strlcpy(notify.name, "IrLAN data", sizeof(notify.name));

	tsap = irttp_open_tsap(LSAP_ANY, DEFAULT_INITIAL_CREDIT, &notify);
	if (!tsap) {
		pr_debug("%s(), Got no tsap!\n", __func__);
		return;
	}
	self->tsap_data = tsap;

	/*
	 *  This is the data TSAP selector which we will pass to the client
	 *  when the client ask for it.
	 */
	self->stsap_sel_data = self->tsap_data->stsap_sel;
}

void irlan_close_tsaps(struct irlan_cb *self)
{
	IRDA_ASSERT(self != NULL, return;);
	IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);

	/* Disconnect and close all open TSAP connections */
	if (self->tsap_data) {
		irttp_disconnect_request(self->tsap_data, NULL, P_NORMAL);
		irttp_close_tsap(self->tsap_data);
		self->tsap_data = NULL;
	}
	if (self->client.tsap_ctrl) {
		irttp_disconnect_request(self->client.tsap_ctrl, NULL,
					 P_NORMAL);
		irttp_close_tsap(self->client.tsap_ctrl);
		self->client.tsap_ctrl = NULL;
	}
	if (self->provider.tsap_ctrl) {
		irttp_disconnect_request(self->provider.tsap_ctrl, NULL,
					 P_NORMAL);
		irttp_close_tsap(self->provider.tsap_ctrl);
		self->provider.tsap_ctrl = NULL;
	}
	self->disconnect_reason = LM_USER_REQUEST;
}

/*
 * Function irlan_ias_register (self, tsap_sel)
 *
 *    Register with LM-IAS
 *
 */
void irlan_ias_register(struct irlan_cb *self, __u8 tsap_sel)
{
	struct ias_object *obj;
	struct ias_value *new_value;

	IRDA_ASSERT(self != NULL, return;);
	IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);

	/*
	 * Check if object has already been registered by a previous provider.
	 * If that is the case, we just change the value of the attribute
	 */
	if (!irias_find_object("IrLAN")) {
		obj = irias_new_object("IrLAN", IAS_IRLAN_ID);
		irias_add_integer_attrib(obj, "IrDA:TinyTP:LsapSel", tsap_sel,
					 IAS_KERNEL_ATTR);
		irias_insert_object(obj);
	} else {
		new_value = irias_new_integer_value(tsap_sel);
		irias_object_change_attribute("IrLAN", "IrDA:TinyTP:LsapSel",
					      new_value);
	}

	/* Register PnP object only if not registered before */
	if (!irias_find_object("PnP")) {
		obj = irias_new_object("PnP", IAS_PNP_ID);
#if 0
		irias_add_string_attrib(obj, "Name", sysctl_devname,
					IAS_KERNEL_ATTR);
#else
		irias_add_string_attrib(obj, "Name", "Linux", IAS_KERNEL_ATTR);
#endif
		irias_add_string_attrib(obj, "DeviceID", "HWP19F0",
					IAS_KERNEL_ATTR);
		irias_add_integer_attrib(obj, "CompCnt", 1, IAS_KERNEL_ATTR);
		if (self->provider.access_type == ACCESS_PEER)
			irias_add_string_attrib(obj, "Comp#01", "PNP8389",
						IAS_KERNEL_ATTR);
		else
			irias_add_string_attrib(obj, "Comp#01", "PNP8294",
						IAS_KERNEL_ATTR);

		irias_add_string_attrib(obj, "Manufacturer",
					"Linux-IrDA Project", IAS_KERNEL_ATTR);
		irias_insert_object(obj);
	}
}

/*
 * Function irlan_run_ctrl_tx_queue (self)
 *
 *    Try to send the next command in the control transmit queue
 *
 */
int irlan_run_ctrl_tx_queue(struct irlan_cb *self)
{
	struct sk_buff *skb;

	if (irda_lock(&self->client.tx_busy) == FALSE)
		return -EBUSY;

	skb = skb_dequeue(&self->client.txq);
	if (!skb) {
		self->client.tx_busy = FALSE;
		return 0;
	}

	/* Check that it's really possible to send commands */
	if ((self->client.tsap_ctrl == NULL) ||
	    (self->client.state == IRLAN_IDLE))
	{
		self->client.tx_busy = FALSE;
		dev_kfree_skb(skb);
		return -1;
	}
	pr_debug("%s(), sending ...\n", __func__);

	return irttp_data_request(self->client.tsap_ctrl, skb);
}

/*
 * Function irlan_ctrl_data_request (self, skb)
 *
 *    This function makes sure that commands on the control channel is being
 *    sent in a command/response fashion
 */
static void irlan_ctrl_data_request(struct irlan_cb *self, struct sk_buff *skb)
{
	/* Queue command */
	skb_queue_tail(&self->client.txq, skb);

	/* Try to send command */
	irlan_run_ctrl_tx_queue(self);
}

/*
 * Function irlan_get_provider_info (self)
 *
 *    Send Get Provider Information command to peer IrLAN layer
 *
 */
void irlan_get_provider_info(struct irlan_cb *self)
{
	struct sk_buff *skb;
	__u8 *frame;

	IRDA_ASSERT(self != NULL, return;);
	IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);

	skb = alloc_skb(IRLAN_MAX_HEADER + IRLAN_CMD_HEADER,
			GFP_ATOMIC);
	if (!skb)
		return;

	/* Reserve space for TTP, LMP, and LAP header */
	skb_reserve(skb, self->client.max_header_size);
	skb_put(skb, 2);

	frame = skb->data;

	frame[0] = CMD_GET_PROVIDER_INFO;
	frame[1] = 0x00;                 /* Zero parameters */

	irlan_ctrl_data_request(self, skb);
}

/*
 * Function irlan_open_data_channel (self)
 *
 *    Send an Open Data Command to provider
 *
 */
void irlan_open_data_channel(struct irlan_cb *self)
{
	struct sk_buff *skb;
	__u8 *frame;

	IRDA_ASSERT(self != NULL, return;);
	IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);

	skb = alloc_skb(IRLAN_MAX_HEADER + IRLAN_CMD_HEADER +
			IRLAN_STRING_PARAMETER_LEN("MEDIA", "802.3") +
			IRLAN_STRING_PARAMETER_LEN("ACCESS_TYPE", "DIRECT"),
			GFP_ATOMIC);
	if (!skb)
		return;

	skb_reserve(skb, self->client.max_header_size);
	skb_put(skb, 2);

	frame = skb->data;

	/* Build frame */
	frame[0] = CMD_OPEN_DATA_CHANNEL;
	frame[1] = 0x02; /* Two parameters */

	irlan_insert_string_param(skb, "MEDIA", "802.3");
	irlan_insert_string_param(skb, "ACCESS_TYPE", "DIRECT");
	/* irlan_insert_string_param(skb, "MODE", "UNRELIABLE"); */

/* 	self->use_udata = TRUE; */

	irlan_ctrl_data_request(self, skb);
}

void irlan_close_data_channel(struct irlan_cb *self)
{
	struct sk_buff *skb;
	__u8 *frame;

	IRDA_ASSERT(self != NULL, return;);
	IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);

	/* Check if the TSAP is still there */
	if (self->client.tsap_ctrl == NULL)
		return;

	skb = alloc_skb(IRLAN_MAX_HEADER + IRLAN_CMD_HEADER +
			IRLAN_BYTE_PARAMETER_LEN("DATA_CHAN"),
			GFP_ATOMIC);
	if (!skb)
		return;

	skb_reserve(skb, self->client.max_header_size);
	skb_put(skb, 2);

	frame = skb->data;

	/* Build frame */
	frame[0] = CMD_CLOSE_DATA_CHAN;
	frame[1] = 0x01; /* One parameter */

	irlan_insert_byte_param(skb, "DATA_CHAN", self->dtsap_sel_data);

	irlan_ctrl_data_request(self, skb);
}

/*
 * Function irlan_open_unicast_addr (self)
 *
 *    Make IrLAN provider accept ethernet frames addressed to the unicast
 *    address.
 *
 */
static void irlan_open_unicast_addr(struct irlan_cb *self)
{
	struct sk_buff *skb;
	__u8 *frame;

	IRDA_ASSERT(self != NULL, return;);
	IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);

	skb = alloc_skb(IRLAN_MAX_HEADER + IRLAN_CMD_HEADER +
			IRLAN_BYTE_PARAMETER_LEN("DATA_CHAN") +
			IRLAN_STRING_PARAMETER_LEN("FILTER_TYPE", "DIRECTED") +
			IRLAN_STRING_PARAMETER_LEN("FILTER_MODE", "FILTER"),
			GFP_ATOMIC);
	if (!skb)
		return;

	/* Reserve space for TTP, LMP, and LAP header */
	skb_reserve(skb, self->max_header_size);
	skb_put(skb, 2);

	frame = skb->data;

	frame[0] = CMD_FILTER_OPERATION;
	frame[1] = 0x03;                 /* Three parameters */
	irlan_insert_byte_param(skb, "DATA_CHAN" , self->dtsap_sel_data);
	irlan_insert_string_param(skb, "FILTER_TYPE", "DIRECTED");
	irlan_insert_string_param(skb, "FILTER_MODE", "FILTER");

	irlan_ctrl_data_request(self, skb);
}

/*
 * Function irlan_set_broadcast_filter (self, status)
 *
 *    Make IrLAN provider accept ethernet frames addressed to the broadcast
 *    address. Be careful with the use of this one, since there may be a lot
 *    of broadcast traffic out there. We can still function without this
 *    one but then _we_ have to initiate all communication with other
 *    hosts, since ARP request for this host will not be answered.
 */
void irlan_set_broadcast_filter(struct irlan_cb *self, int status)
{
	struct sk_buff *skb;
	__u8 *frame;

	IRDA_ASSERT(self != NULL, return;);
	IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);

	skb = alloc_skb(IRLAN_MAX_HEADER + IRLAN_CMD_HEADER +
			IRLAN_BYTE_PARAMETER_LEN("DATA_CHAN") +
			IRLAN_STRING_PARAMETER_LEN("FILTER_TYPE", "BROADCAST") +
			/* We may waste one byte here...*/
			IRLAN_STRING_PARAMETER_LEN("FILTER_MODE", "FILTER"),
			GFP_ATOMIC);
	if (!skb)
		return;

	/* Reserve space for TTP, LMP, and LAP header */
	skb_reserve(skb, self->client.max_header_size);
	skb_put(skb, 2);

	frame = skb->data;

	frame[0] = CMD_FILTER_OPERATION;
	frame[1] = 0x03;                 /* Three parameters */
	irlan_insert_byte_param(skb, "DATA_CHAN", self->dtsap_sel_data);
	irlan_insert_string_param(skb, "FILTER_TYPE", "BROADCAST");
	if (status)
		irlan_insert_string_param(skb, "FILTER_MODE", "FILTER");
	else
		irlan_insert_string_param(skb, "FILTER_MODE", "NONE");

	irlan_ctrl_data_request(self, skb);
}

/*
 * Function irlan_set_multicast_filter (self, status)
 *
 *    Make IrLAN provider accept ethernet frames addressed to the multicast
 *    address.
 *
 */
void irlan_set_multicast_filter(struct irlan_cb *self, int status)
{
	struct sk_buff *skb;
	__u8 *frame;

	IRDA_ASSERT(self != NULL, return;);
	IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);

	skb = alloc_skb(IRLAN_MAX_HEADER + IRLAN_CMD_HEADER +
			IRLAN_BYTE_PARAMETER_LEN("DATA_CHAN") +
			IRLAN_STRING_PARAMETER_LEN("FILTER_TYPE", "MULTICAST") +
			/* We may waste one byte here...*/
			IRLAN_STRING_PARAMETER_LEN("FILTER_MODE", "NONE"),
			GFP_ATOMIC);
	if (!skb)
		return;

	/* Reserve space for TTP, LMP, and LAP header */
	skb_reserve(skb, self->client.max_header_size);
	skb_put(skb, 2);

	frame = skb->data;

	frame[0] = CMD_FILTER_OPERATION;
	frame[1] = 0x03;                 /* Three parameters */
	irlan_insert_byte_param(skb, "DATA_CHAN", self->dtsap_sel_data);
	irlan_insert_string_param(skb, "FILTER_TYPE", "MULTICAST");
	if (status)
		irlan_insert_string_param(skb, "FILTER_MODE", "ALL");
	else
		irlan_insert_string_param(skb, "FILTER_MODE", "NONE");

	irlan_ctrl_data_request(self, skb);
}

/*
 * Function irlan_get_unicast_addr (self)
 *
 *    Retrieves the unicast address from the IrLAN provider. This address
 *    will be inserted into the devices structure, so the ethernet layer
 *    can construct its packets.
 *
 */
static void irlan_get_unicast_addr(struct irlan_cb *self)
{
	struct sk_buff *skb;
	__u8 *frame;

	IRDA_ASSERT(self != NULL, return;);
	IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);

	skb = alloc_skb(IRLAN_MAX_HEADER + IRLAN_CMD_HEADER +
			IRLAN_BYTE_PARAMETER_LEN("DATA_CHAN") +
			IRLAN_STRING_PARAMETER_LEN("FILTER_TYPE", "DIRECTED") +
			IRLAN_STRING_PARAMETER_LEN("FILTER_OPERATION",
						   "DYNAMIC"),
			GFP_ATOMIC);
	if (!skb)
		return;

	/* Reserve space for TTP, LMP, and LAP header */
	skb_reserve(skb, self->client.max_header_size);
	skb_put(skb, 2);

	frame = skb->data;

	frame[0] = CMD_FILTER_OPERATION;
	frame[1] = 0x03;                 /* Three parameters */
	irlan_insert_byte_param(skb, "DATA_CHAN", self->dtsap_sel_data);
	irlan_insert_string_param(skb, "FILTER_TYPE", "DIRECTED");
	irlan_insert_string_param(skb, "FILTER_OPERATION", "DYNAMIC");

	irlan_ctrl_data_request(self, skb);
}

/*
 * Function irlan_get_media_char (self)
 *
 *
 *
 */
void irlan_get_media_char(struct irlan_cb *self)
{
	struct sk_buff *skb;
	__u8 *frame;

	IRDA_ASSERT(self != NULL, return;);
	IRDA_ASSERT(self->magic == IRLAN_MAGIC, return;);

	skb = alloc_skb(IRLAN_MAX_HEADER + IRLAN_CMD_HEADER +
			IRLAN_STRING_PARAMETER_LEN("MEDIA", "802.3"),
			GFP_ATOMIC);

	if (!skb)
		return;

	/* Reserve space for TTP, LMP, and LAP header */
	skb_reserve(skb, self->client.max_header_size);
	skb_put(skb, 2);

	frame = skb->data;

	/* Build frame */
	frame[0] = CMD_GET_MEDIA_CHAR;
	frame[1] = 0x01; /* One parameter */

	irlan_insert_string_param(skb, "MEDIA", "802.3");
	irlan_ctrl_data_request(self, skb);
}

/*
 * Function insert_byte_param (skb, param, value)
 *
 *    Insert byte parameter into frame
 *
 */
int irlan_insert_byte_param(struct sk_buff *skb, char *param, __u8 value)
{
	return __irlan_insert_param(skb, param, IRLAN_BYTE, value, 0, NULL, 0);
}

int irlan_insert_short_param(struct sk_buff *skb, char *param, __u16 value)
{
	return __irlan_insert_param(skb, param, IRLAN_SHORT, 0, value, NULL, 0);
}

/*
 * Function insert_string (skb, param, value)
 *
 *    Insert string parameter into frame
 *
 */
int irlan_insert_string_param(struct sk_buff *skb, char *param, char *string)
{
	int string_len = strlen(string);

	return __irlan_insert_param(skb, param, IRLAN_ARRAY, 0, 0, string,
				    string_len);
}

/*
 * Function insert_array_param(skb, param, value, len_value)
 *
 *    Insert array parameter into frame
 *
 */
int irlan_insert_array_param(struct sk_buff *skb, char *name, __u8 *array,
			     __u16 array_len)
{
	return __irlan_insert_param(skb, name, IRLAN_ARRAY, 0, 0, array,
				    array_len);
}

/*
 * Function insert_param (skb, param, value, byte)
 *
 *    Insert parameter at end of buffer, structure of a parameter is:
 *
 *    -----------------------------------------------------------------------
 *    | Name Length[1] | Param Name[1..255] | Val Length[2] | Value[0..1016]|
 *    -----------------------------------------------------------------------
 */
static int __irlan_insert_param(struct sk_buff *skb, char *param, int type,
				__u8 value_byte, __u16 value_short,
				__u8 *value_array, __u16 value_len)
{
	__u8 *frame;
	__u8 param_len;
	__le16 tmp_le; /* Temporary value in little endian format */
	int n=0;

	if (skb == NULL) {
		pr_debug("%s(), Got NULL skb\n", __func__);
		return 0;
	}

	param_len = strlen(param);
	switch (type) {
	case IRLAN_BYTE:
		value_len = 1;
		break;
	case IRLAN_SHORT:
		value_len = 2;
		break;
	case IRLAN_ARRAY:
		IRDA_ASSERT(value_array != NULL, return 0;);
		IRDA_ASSERT(value_len > 0, return 0;);
		break;
	default:
		pr_debug("%s(), Unknown parameter type!\n", __func__);
		return 0;
	}

	/* Insert at end of sk-buffer */
	frame = skb_tail_pointer(skb);

	/* Make space for data */
	if (skb_tailroom(skb) < (param_len+value_len+3)) {
		pr_debug("%s(), No more space at end of skb\n", __func__);
		return 0;
	}
	skb_put(skb, param_len+value_len+3);

	/* Insert parameter length */
	frame[n++] = param_len;

	/* Insert parameter */
	memcpy(frame+n, param, param_len); n += param_len;

	/* Insert value length (2 byte little endian format, LSB first) */
	tmp_le = cpu_to_le16(value_len);
	memcpy(frame+n, &tmp_le, 2); n += 2; /* To avoid alignment problems */

	/* Insert value */
	switch (type) {
	case IRLAN_BYTE:
		frame[n++] = value_byte;
		break;
	case IRLAN_SHORT:
		tmp_le = cpu_to_le16(value_short);
		memcpy(frame+n, &tmp_le, 2); n += 2;
		break;
	case IRLAN_ARRAY:
		memcpy(frame+n, value_array, value_len); n+=value_len;
		break;
	default:
		break;
	}
	IRDA_ASSERT(n == (param_len+value_len+3), return 0;);

	return param_len+value_len+3;
}

/*
 * Function irlan_extract_param (buf, name, value, len)
 *
 *    Extracts a single parameter name/value pair from buffer and updates
 *    the buffer pointer to point to the next name/value pair.
 */
int irlan_extract_param(__u8 *buf, char *name, char *value, __u16 *len)
{
	__u8 name_len;
	__u16 val_len;
	int n=0;

	/* get length of parameter name (1 byte) */
	name_len = buf[n++];

	if (name_len > 254) {
		pr_debug("%s(), name_len > 254\n", __func__);
		return -RSP_INVALID_COMMAND_FORMAT;
	}

	/* get parameter name */
	memcpy(name, buf+n, name_len);
	name[name_len] = '\0';
	n+=name_len;

	/*
	 *  Get length of parameter value (2 bytes in little endian
	 *  format)
	 */
	memcpy(&val_len, buf+n, 2); /* To avoid alignment problems */
	le16_to_cpus(&val_len); n+=2;

	if (val_len >= 1016) {
		pr_debug("%s(), parameter length to long\n", __func__);
		return -RSP_INVALID_COMMAND_FORMAT;
	}
	*len = val_len;

	/* get parameter value */
	memcpy(value, buf+n, val_len);
	value[val_len] = '\0';
	n+=val_len;

	pr_debug("Parameter: %s ", name);
	pr_debug("Value: %s\n", value);

	return n;
}

#ifdef CONFIG_PROC_FS

/*
 * Start of reading /proc entries.
 * Return entry at pos,
 *	or start_token to indicate print header line
 *	or NULL if end of file
 */
static void *irlan_seq_start(struct seq_file *seq, loff_t *pos)
{
	rcu_read_lock();
	return seq_list_start_head(&irlans, *pos);
}

/* Return entry after v, and increment pos */
static void *irlan_seq_next(struct seq_file *seq, void *v, loff_t *pos)
{
	return seq_list_next(v, &irlans, pos);
}

/* End of reading /proc file */
static void irlan_seq_stop(struct seq_file *seq, void *v)
{
	rcu_read_unlock();
}


/*
 * Show one entry in /proc file.
 */
static int irlan_seq_show(struct seq_file *seq, void *v)
{
	if (v == &irlans)
		seq_puts(seq, "IrLAN instances:\n");
	else {
		struct irlan_cb *self = list_entry(v, struct irlan_cb, dev_list);

		IRDA_ASSERT(self != NULL, return -1;);
		IRDA_ASSERT(self->magic == IRLAN_MAGIC, return -1;);

		seq_printf(seq,"ifname: %s,\n",
			       self->dev->name);
		seq_printf(seq,"client state: %s, ",
			       irlan_state[ self->client.state]);
		seq_printf(seq,"provider state: %s,\n",
			       irlan_state[ self->provider.state]);
		seq_printf(seq,"saddr: %#08x, ",
			       self->saddr);
		seq_printf(seq,"daddr: %#08x\n",
			       self->daddr);
		seq_printf(seq,"version: %d.%d,\n",
			       self->version[1], self->version[0]);
		seq_printf(seq,"access type: %s\n",
			       irlan_access[self->client.access_type]);
		seq_printf(seq,"media: %s\n",
			       irlan_media[self->media]);

		seq_printf(seq,"local filter:\n");
		seq_printf(seq,"remote filter: ");
		irlan_print_filter(seq, self->client.filter_type);
		seq_printf(seq,"tx busy: %s\n",
			       netif_queue_stopped(self->dev) ? "TRUE" : "FALSE");

		seq_putc(seq,'\n');
	}
	return 0;
}

static const struct seq_operations irlan_seq_ops = {
	.start = irlan_seq_start,
	.next  = irlan_seq_next,
	.stop  = irlan_seq_stop,
	.show  = irlan_seq_show,
};

static int irlan_seq_open(struct inode *inode, struct file *file)
{
	return seq_open(file, &irlan_seq_ops);
}
#endif

MODULE_AUTHOR("Dag Brattli <dagb@cs.uit.no>");
MODULE_DESCRIPTION("The Linux IrDA LAN protocol");
MODULE_LICENSE("GPL");

module_param(eth, bool, 0);
MODULE_PARM_DESC(eth, "Name devices ethX (0) or irlanX (1)");
module_param(access, int, 0);
MODULE_PARM_DESC(access, "Access type DIRECT=1, PEER=2, HOSTED=3");

module_init(irlan_init);
module_exit(irlan_cleanup);

