/*********************************************************************
*
* Filename: irlap.c
* Version: 1.0
* Description: IrLAP implementation for Linux
* Status: Stable
* Author: Dag Brattli <dagb@cs.uit.no>
* Created at: Mon Aug 4 20:40:53 1997
* Modified at: Tue Dec 14 09:26:44 1999
* Modified by: Dag Brattli <dagb@cs.uit.no>
*
* Copyright (c) 1998-1999 Dag Brattli, All Rights Reserved.
* Copyright (c) 2000-2003 Jean Tourrilhes <jt@hpl.hp.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.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see <http://www.gnu.org/licenses/>.
*
********************************************************************/
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/skbuff.h>
#include <linux/delay.h>
#include <linux/proc_fs.h>
#include <linux/init.h>
#include <linux/random.h>
#include <linux/module.h>
#include <linux/seq_file.h>
#include <net/irda/irda.h>
#include <net/irda/irda_device.h>
#include <net/irda/irqueue.h>
#include <net/irda/irlmp.h>
#include <net/irda/irlmp_frame.h>
#include <net/irda/irlap_frame.h>
#include <net/irda/irlap.h>
#include <net/irda/timer.h>
#include <net/irda/qos.h>
static hashbin_t *irlap = NULL;
int sysctl_slot_timeout = SLOT_TIMEOUT * 1000 / HZ;
/* This is the delay of missed pf period before generating an event
* to the application. The spec mandate 3 seconds, but in some cases
* it's way too long. - Jean II */
int sysctl_warn_noreply_time = 3;
extern void irlap_queue_xmit(struct irlap_cb *self, struct sk_buff *skb);
static void __irlap_close(struct irlap_cb *self);
static void irlap_init_qos_capabilities(struct irlap_cb *self,
struct qos_info *qos_user);
static const char *const lap_reasons[] __maybe_unused = {
"ERROR, NOT USED",
"LAP_DISC_INDICATION",
"LAP_NO_RESPONSE",
"LAP_RESET_INDICATION",
"LAP_FOUND_NONE",
"LAP_MEDIA_BUSY",
"LAP_PRIMARY_CONFLICT",
"ERROR, NOT USED",
};
int __init irlap_init(void)
{
/* Check if the compiler did its job properly.
* May happen on some ARM configuration, check with Russell King. */
IRDA_ASSERT(sizeof(struct xid_frame) == 14, ;);
IRDA_ASSERT(sizeof(struct test_frame) == 10, ;);
IRDA_ASSERT(sizeof(struct ua_frame) == 10, ;);
IRDA_ASSERT(sizeof(struct snrm_frame) == 11, ;);
/* Allocate master array */
irlap = hashbin_new(HB_LOCK);
if (irlap == NULL) {
net_err_ratelimited("%s: can't allocate irlap hashbin!\n",
__func__);
return -ENOMEM;
}
return 0;
}
void irlap_cleanup(void)
{
IRDA_ASSERT(irlap != NULL, return;);
hashbin_delete(irlap, (FREE_FUNC) __irlap_close);
}
/*
* Function irlap_open (driver)
*
* Initialize IrLAP layer
*
*/
struct irlap_cb *irlap_open(struct net_device *dev, struct qos_info *qos,
const char *hw_name)
{
struct irlap_cb *self;
/* Initialize the irlap structure. */
self = kzalloc(sizeof(struct irlap_cb), GFP_KERNEL);
if (self == NULL)
return NULL;
self->magic = LAP_MAGIC;
/* Make a binding between the layers */
self->netdev = dev;
self->qos_dev = qos;
/* Copy hardware name */
if(hw