/*
* Host AP (software wireless LAN access point) driver for
* Intersil Prism2/2.5/3 - hostap.o module, common routines
*
* Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
* <j@w1.fi>
* Copyright (c) 2002-2005, Jouni Malinen <j@w1.fi>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation. See README and COPYING for
* more details.
*/
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/proc_fs.h>
#include <linux/if_arp.h>
#include <linux/delay.h>
#include <linux/random.h>
#include <linux/workqueue.h>
#include <linux/kmod.h>
#include <linux/rtnetlink.h>
#include <linux/wireless.h>
#include <linux/etherdevice.h>
#include <net/net_namespace.h>
#include <net/iw_handler.h>
#include <net/lib80211.h>
#include <asm/uaccess.h>
#include "hostap_wlan.h"
#include "hostap_80211.h"
#include "hostap_ap.h"
#include "hostap.h"
MODULE_AUTHOR("Jouni Malinen");
MODULE_DESCRIPTION("Host AP common routines");
MODULE_LICENSE("GPL");
#define TX_TIMEOUT (2 * HZ)
#define PRISM2_MAX_FRAME_SIZE 2304
#define PRISM2_MIN_MTU 256
/* FIX: */
#define PRISM2_MAX_MTU (PRISM2_MAX_FRAME_SIZE - (6 /* LLC */ + 8 /* WEP */))
struct net_device * hostap_add_interface(struct local_info *local,
int type, int rtnl_locked,
const char *prefix,
const char *name)
{
struct net_device *dev, *mdev;
struct hostap_interface *iface;
int ret;
dev = alloc_etherdev(sizeof(struct hostap_interface));
if (dev == NULL)
return NULL;
iface = netdev_priv(dev);
iface->dev = dev;
iface->local = local;
iface->type = type;
list_add(&iface->list, &local->hostap_interfaces);
mdev = local->dev;
memcpy(dev->dev_addr, mdev->dev_addr, ETH_ALEN);
dev->base_addr = mdev->base_addr;
dev->irq = mdev->irq;
dev->mem_start = mdev->mem_start;
dev->mem_end = mdev->mem_end;
hostap_setup_dev(dev, local, type);
dev->destructor = free_netdev;
sprintf(dev->name, "%s%s", prefix, name);
if (!rtnl_locked)
rtnl_lock();
SET_NETDEV_DEV(dev, mdev->dev.parent);
ret = register_netdevice(dev);
if (!rtnl_locked)
rtnl_unlock();
if (ret < 0) {
printk(KERN_WARNING "%s: failed to add new netdevice!\n",
dev->name);
free_netdev(dev);
return NULL;
}
printk(KERN_DEBUG "%s: registered netdevice %s\n",
mdev->name, dev->name);
return dev;
}
void hostap_remove_interface(struct net_device *dev, int rtnl_locked,
int remove_from_list)
{
struct hostap_interface *iface;
if (!dev)
return;
iface = netdev_priv(dev);
if (remove_from_list) {
list_del(&iface->list);
}
if (dev == iface->local->ddev)
iface->local->ddev = NULL;
else if (dev == iface->local->apdev)
iface->local->apdev = NULL;
else if (dev == iface->local->stadev)
iface->local->stadev = NULL;
if (rtnl_locked)
unregister_netdevice(dev);
else