提交 0f1c122e 编写于 作者: J Jeff Garzik

Merge branch 'upstream-jgarzik' of git://git.tuxdriver.com/git/wireless-2.6

......@@ -5783,7 +5783,7 @@ static int airo_get_essid(struct net_device *dev,
/* If none, we may want to get the one that was set */
/* Push it out ! */
dwrq->length = status_rid.SSIDlen + 1;
dwrq->length = status_rid.SSIDlen;
dwrq->flags = 1; /* active */
return 0;
......
......@@ -1718,11 +1718,11 @@ static int atmel_get_essid(struct net_device *dev,
if (priv->new_SSID_size != 0) {
memcpy(extra, priv->new_SSID, priv->new_SSID_size);
extra[priv->new_SSID_size] = '\0';
dwrq->length = priv->new_SSID_size + 1;
dwrq->length = priv->new_SSID_size;
} else {
memcpy(extra, priv->SSID, priv->SSID_size);
extra[priv->SSID_size] = '\0';
dwrq->length = priv->SSID_size + 1;
dwrq->length = priv->SSID_size;
}
dwrq->flags = !priv->connect_to_any_BSS; /* active */
......
......@@ -26,11 +26,25 @@ config HOSTAP_FIRMWARE
depends on HOSTAP
---help---
Configure Host AP driver to include support for firmware image
download. Current version supports only downloading to volatile, i.e.,
RAM memory. Flash upgrade is not yet supported.
download. This option by itself only enables downloading to the
volatile memory, i.e. the card RAM. This option is required to
support cards that don't have firmware in flash, such as D-Link
DWL-520 rev E and D-Link DWL-650 rev P.
Firmware image downloading needs user space tool, prism2_srec. It is
available from http://hostap.epitest.fi/.
Firmware image downloading needs a user space tool, prism2_srec.
It is available from http://hostap.epitest.fi/.
config HOSTAP_FIRMWARE_NVRAM
bool "Support for non-volatile firmware download"
depends on HOSTAP_FIRMWARE
---help---
Allow Host AP driver to write firmware images to the non-volatile
card memory, i.e. flash memory that survives power cycling.
Enable this option if you want to be able to change card firmware
permanently.
Firmware image downloading needs a user space tool, prism2_srec.
It is available from http://hostap.epitest.fi/.
config HOSTAP_PLX
tristate "Host AP driver for Prism2/2.5/3 in PLX9052 PCI adaptors"
......
hostap-y := hostap_main.o
hostap-y := hostap_80211_rx.o hostap_80211_tx.o hostap_ap.o hostap_info.o \
hostap_ioctl.o hostap_main.o hostap_proc.o
obj-$(CONFIG_HOSTAP) += hostap.o
obj-$(CONFIG_HOSTAP_CS) += hostap_cs.o
......
#ifndef HOSTAP_H
#define HOSTAP_H
#include <linux/ethtool.h>
#include "hostap_wlan.h"
#include "hostap_ap.h"
static const long freq_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
2447, 2452, 2457, 2462, 2467, 2472, 2484 };
#define FREQ_COUNT (sizeof(freq_list) / sizeof(freq_list[0]))
/* hostap.c */
extern struct proc_dir_entry *hostap_proc;
......@@ -40,6 +49,26 @@ int prism2_update_comms_qual(struct net_device *dev);
int prism2_sta_send_mgmt(local_info_t *local, u8 *dst, u16 stype,
u8 *body, size_t bodylen);
int prism2_sta_deauth(local_info_t *local, u16 reason);
int prism2_wds_add(local_info_t *local, u8 *remote_addr,
int rtnl_locked);
int prism2_wds_del(local_info_t *local, u8 *remote_addr,
int rtnl_locked, int do_not_remove);
/* hostap_ap.c */
int ap_control_add_mac(struct mac_restrictions *mac_restrictions, u8 *mac);
int ap_control_del_mac(struct mac_restrictions *mac_restrictions, u8 *mac);
void ap_control_flush_macs(struct mac_restrictions *mac_restrictions);
int ap_control_kick_mac(struct ap_data *ap, struct net_device *dev, u8 *mac);
void ap_control_kickall(struct ap_data *ap);
void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent,
struct ieee80211_crypt_data ***crypt);
int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[],
struct iw_quality qual[], int buf_size,
int aplist);
int prism2_ap_translate_scan(struct net_device *dev, char *buffer);
int prism2_hostapd(struct ap_data *ap, struct prism2_hostapd_param *param);
/* hostap_proc.c */
......@@ -54,4 +83,12 @@ void hostap_info_init(local_info_t *local);
void hostap_info_process(local_info_t *local, struct sk_buff *skb);
/* hostap_ioctl.c */
extern const struct iw_handler_def hostap_iw_handler_def;
extern struct ethtool_ops prism2_ethtool_ops;
int hostap_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
#endif /* HOSTAP_H */
#ifndef HOSTAP_80211_H
#define HOSTAP_80211_H
#include <linux/types.h>
#include <net/ieee80211_crypt.h>
struct hostap_ieee80211_mgmt {
u16 frame_control;
u16 duration;
......
#include <linux/etherdevice.h>
#include <net/ieee80211_crypt.h>
#include "hostap_80211.h"
#include "hostap.h"
#include "hostap_ap.h"
/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
/* Ethernet-II snap header (RFC1042 for most EtherTypes) */
static unsigned char rfc1042_header[] =
{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
static unsigned char bridge_tunnel_header[] =
{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
/* No encapsulation header if EtherType < 0x600 (=length) */
void hostap_dump_rx_80211(const char *name, struct sk_buff *skb,
struct hostap_80211_rx_status *rx_stats)
......
#include "hostap_80211.h"
#include "hostap_common.h"
#include "hostap_wlan.h"
#include "hostap.h"
#include "hostap_ap.h"
/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
/* Ethernet-II snap header (RFC1042 for most EtherTypes) */
static unsigned char rfc1042_header[] =
{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
static unsigned char bridge_tunnel_header[] =
{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
/* No encapsulation header if EtherType < 0x600 (=length) */
void hostap_dump_tx_80211(const char *name, struct sk_buff *skb)
{
struct ieee80211_hdr_4addr *hdr;
......
......@@ -16,6 +16,14 @@
* (8802.11: 5.5)
*/
#include <linux/proc_fs.h>
#include <linux/delay.h>
#include <linux/random.h>
#include "hostap_wlan.h"
#include "hostap.h"
#include "hostap_ap.h"
static int other_ap_policy[MAX_PARM_DEVICES] = { AP_OTHER_AP_SKIP_ALL,
DEF_INTS };
module_param_array(other_ap_policy, int, NULL, 0444);
......@@ -360,8 +368,7 @@ static int ap_control_proc_read(char *page, char **start, off_t off,
}
static int ap_control_add_mac(struct mac_restrictions *mac_restrictions,
u8 *mac)
int ap_control_add_mac(struct mac_restrictions *mac_restrictions, u8 *mac)
{
struct mac_entry *entry;
......@@ -380,8 +387,7 @@ static int ap_control_add_mac(struct mac_restrictions *mac_restrictions,
}
static int ap_control_del_mac(struct mac_restrictions *mac_restrictions,
u8 *mac)
int ap_control_del_mac(struct mac_restrictions *mac_restrictions, u8 *mac)
{
struct list_head *ptr;
struct mac_entry *entry;
......@@ -433,7 +439,7 @@ static int ap_control_mac_deny(struct mac_restrictions *mac_restrictions,
}
static void ap_control_flush_macs(struct mac_restrictions *mac_restrictions)
void ap_control_flush_macs(struct mac_restrictions *mac_restrictions)
{
struct list_head *ptr, *n;
struct mac_entry *entry;
......@@ -454,8 +460,7 @@ static void ap_control_flush_macs(struct mac_restrictions *mac_restrictions)
}
static int ap_control_kick_mac(struct ap_data *ap, struct net_device *dev,
u8 *mac)
int ap_control_kick_mac(struct ap_data *ap, struct net_device *dev, u8 *mac)
{
struct sta_info *sta;
u16 resp;
......@@ -486,7 +491,7 @@ static int ap_control_kick_mac(struct ap_data *ap, struct net_device *dev,
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
static void ap_control_kickall(struct ap_data *ap)
void ap_control_kickall(struct ap_data *ap)
{
struct list_head *ptr, *n;
struct sta_info *sta;
......@@ -2321,9 +2326,9 @@ static void schedule_packet_send(local_info_t *local, struct sta_info *sta)
}
static int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[],
struct iw_quality qual[], int buf_size,
int aplist)
int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[],
struct iw_quality qual[], int buf_size,
int aplist)
{
struct ap_data *ap = local->ap;
struct list_head *ptr;
......@@ -2363,7 +2368,7 @@ static int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[],
/* Translate our list of Access Points & Stations to a card independant
* format that the Wireless Tools will understand - Jean II */
static int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
{
struct hostap_interface *iface;
local_info_t *local;
......@@ -2608,8 +2613,7 @@ static int prism2_hostapd_sta_clear_stats(struct ap_data *ap,
}
static int prism2_hostapd(struct ap_data *ap,
struct prism2_hostapd_param *param)
int prism2_hostapd(struct ap_data *ap, struct prism2_hostapd_param *param)
{
switch (param->cmd) {
case PRISM2_HOSTAPD_FLUSH:
......@@ -3207,8 +3211,8 @@ void hostap_update_rates(local_info_t *local)
}
static void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent,
struct ieee80211_crypt_data ***crypt)
void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent,
struct ieee80211_crypt_data ***crypt)
{
struct sta_info *sta;
......
#ifndef HOSTAP_AP_H
#define HOSTAP_AP_H
#include "hostap_80211.h"
/* AP data structures for STAs */
/* maximum number of frames to buffer per STA */
......
#ifndef HOSTAP_COMMON_H
#define HOSTAP_COMMON_H
#include <linux/types.h>
#include <linux/if_ether.h>
#define BIT(x) (1 << (x))
#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
......
......@@ -21,15 +21,10 @@
#define PRISM2_DOWNLOAD_SUPPORT
#endif
#ifdef PRISM2_DOWNLOAD_SUPPORT
/* Allow writing firmware images into flash, i.e., to non-volatile storage.
* Before you enable this option, you should make absolutely sure that you are
* using prism2_srec utility that comes with THIS version of the driver!
* In addition, please note that it is possible to kill your card with
* non-volatile download if you are using incorrect image. This feature has not
* been fully tested, so please be careful with it. */
/* #define PRISM2_NON_VOLATILE_DOWNLOAD */
#endif /* PRISM2_DOWNLOAD_SUPPORT */
/* Allow kernel configuration to enable non-volatile download support. */
#ifdef CONFIG_HOSTAP_FIRMWARE_NVRAM
#define PRISM2_NON_VOLATILE_DOWNLOAD
#endif
/* Save low-level I/O for debugging. This should not be enabled in normal use.
*/
......
/* Host AP driver Info Frame processing (part of hostap.o module) */
#include "hostap_wlan.h"
#include "hostap.h"
#include "hostap_ap.h"
/* Called only as a tasklet (software IRQ) */
static void prism2_info_commtallies16(local_info_t *local, unsigned char *buf,
......
/* ioctl() (mostly Linux Wireless Extensions) routines for Host AP driver */
#ifdef in_atomic
/* Get kernel_locked() for in_atomic() */
#include <linux/types.h>
#include <linux/smp_lock.h>
#endif
#include <linux/ethtool.h>
#include <net/ieee80211_crypt.h>
#include "hostap_wlan.h"
#include "hostap.h"
#include "hostap_ap.h"
static struct iw_statistics *hostap_get_wireless_stats(struct net_device *dev)
{
......@@ -3910,7 +3912,7 @@ static void prism2_get_drvinfo(struct net_device *dev,
local->sta_fw_ver & 0xff);
}
static struct ethtool_ops prism2_ethtool_ops = {
struct ethtool_ops prism2_ethtool_ops = {
.get_drvinfo = prism2_get_drvinfo
};
......@@ -3985,7 +3987,7 @@ static const iw_handler prism2_private_handler[] =
(iw_handler) prism2_ioctl_priv_readmif, /* 3 */
};
static const struct iw_handler_def hostap_iw_handler_def =
const struct iw_handler_def hostap_iw_handler_def =
{
.num_standard = sizeof(prism2_handler) / sizeof(iw_handler),
.num_private = sizeof(prism2_private_handler) / sizeof(iw_handler),
......
......@@ -24,6 +24,7 @@
#include <linux/kmod.h>
#include <linux/rtnetlink.h>
#include <linux/wireless.h>
#include <linux/etherdevice.h>
#include <net/iw_handler.h>
#include <net/ieee80211.h>
#include <net/ieee80211_crypt.h>
......@@ -47,57 +48,6 @@ MODULE_VERSION(PRISM2_VERSION);
#define PRISM2_MAX_MTU (PRISM2_MAX_FRAME_SIZE - (6 /* LLC */ + 8 /* WEP */))
/* hostap.c */
static int prism2_wds_add(local_info_t *local, u8 *remote_addr,
int rtnl_locked);
static int prism2_wds_del(local_info_t *local, u8 *remote_addr,
int rtnl_locked, int do_not_remove);
/* hostap_ap.c */
static int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[],
struct iw_quality qual[], int buf_size,
int aplist);
static int prism2_ap_translate_scan(struct net_device *dev, char *buffer);
static int prism2_hostapd(struct ap_data *ap,
struct prism2_hostapd_param *param);
static void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent,
struct ieee80211_crypt_data ***crypt);
static void ap_control_kickall(struct ap_data *ap);
#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
static int ap_control_add_mac(struct mac_restrictions *mac_restrictions,
u8 *mac);
static int ap_control_del_mac(struct mac_restrictions *mac_restrictions,
u8 *mac);
static void ap_control_flush_macs(struct mac_restrictions *mac_restrictions);
static int ap_control_kick_mac(struct ap_data *ap, struct net_device *dev,
u8 *mac);
#endif /* !PRISM2_NO_KERNEL_IEEE80211_MGMT */
static const long freq_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
2447, 2452, 2457, 2462, 2467, 2472, 2484 };
#define FREQ_COUNT (sizeof(freq_list) / sizeof(freq_list[0]))
/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
/* Ethernet-II snap header (RFC1042 for most EtherTypes) */
static unsigned char rfc1042_header[] =
{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
static unsigned char bridge_tunnel_header[] =
{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
/* No encapsulation header if EtherType < 0x600 (=length) */
/* FIX: these could be compiled separately and linked together to hostap.o */
#include "hostap_ap.c"
#include "hostap_info.c"
#include "hostap_ioctl.c"
#include "hostap_proc.c"
#include "hostap_80211_rx.c"
#include "hostap_80211_tx.c"
struct net_device * hostap_add_interface(struct local_info *local,
int type, int rtnl_locked,
const char *prefix,
......@@ -196,8 +146,8 @@ static inline int prism2_wds_special_addr(u8 *addr)
}
static int prism2_wds_add(local_info_t *local, u8 *remote_addr,
int rtnl_locked)
int prism2_wds_add(local_info_t *local, u8 *remote_addr,
int rtnl_locked)
{
struct net_device *dev;
struct list_head *ptr;
......@@ -258,8 +208,8 @@ static int prism2_wds_add(local_info_t *local, u8 *remote_addr,
}
static int prism2_wds_del(local_info_t *local, u8 *remote_addr,
int rtnl_locked, int do_not_remove)
int prism2_wds_del(local_info_t *local, u8 *remote_addr,
int rtnl_locked, int do_not_remove)
{
unsigned long flags;
struct list_head *ptr;
......
/* /proc routines for Host AP driver */
#include <linux/types.h>
#include <linux/proc_fs.h>
#include <net/ieee80211_crypt.h>
#include "hostap_wlan.h"
#include "hostap.h"
#define PROC_LIMIT (PAGE_SIZE - 80)
......
#ifndef HOSTAP_WLAN_H
#define HOSTAP_WLAN_H
#include <linux/wireless.h>
#include <linux/netdevice.h>
#include <net/iw_handler.h>
#include "hostap_config.h"
#include "hostap_common.h"
......
......@@ -5735,70 +5735,6 @@ static struct net_device_stats *ipw2100_stats(struct net_device *dev)
return &priv->ieee->stats;
}
#if WIRELESS_EXT < 18
/* Support for wpa_supplicant before WE-18, deprecated. */
/* following definitions must match definitions in driver_ipw.c */
#define IPW2100_IOCTL_WPA_SUPPLICANT SIOCIWFIRSTPRIV+30
#define IPW2100_CMD_SET_WPA_PARAM 1
#define IPW2100_CMD_SET_WPA_IE 2
#define IPW2100_CMD_SET_ENCRYPTION 3
#define IPW2100_CMD_MLME 4
#define IPW2100_PARAM_WPA_ENABLED 1
#define IPW2100_PARAM_TKIP_COUNTERMEASURES 2
#define IPW2100_PARAM_DROP_UNENCRYPTED 3
#define IPW2100_PARAM_PRIVACY_INVOKED 4
#define IPW2100_PARAM_AUTH_ALGS 5
#define IPW2100_PARAM_IEEE_802_1X 6
#define IPW2100_MLME_STA_DEAUTH 1
#define IPW2100_MLME_STA_DISASSOC 2
#define IPW2100_CRYPT_ERR_UNKNOWN_ALG 2
#define IPW2100_CRYPT_ERR_UNKNOWN_ADDR 3
#define IPW2100_CRYPT_ERR_CRYPT_INIT_FAILED 4
#define IPW2100_CRYPT_ERR_KEY_SET_FAILED 5
#define IPW2100_CRYPT_ERR_TX_KEY_SET_FAILED 6
#define IPW2100_CRYPT_ERR_CARD_CONF_FAILED 7
#define IPW2100_CRYPT_ALG_NAME_LEN 16
struct ipw2100_param {
u32 cmd;
u8 sta_addr[ETH_ALEN];
union {
struct {
u8 name;
u32 value;
} wpa_param;
struct {
u32 len;
u8 reserved[32];
u8 data[0];
} wpa_ie;
struct {
u32 command;
u32 reason_code;
} mlme;
struct {
u8 alg[IPW2100_CRYPT_ALG_NAME_LEN];
u8 set_tx;
u32 err;
u8 idx;
u8 seq[8]; /* sequence counter (set: RX, get: TX) */
u16 key_len;
u8 key[0];
} crypt;
} u;
};
/* end of driver_ipw.c code */
#endif /* WIRELESS_EXT < 18 */
static int ipw2100_wpa_enable(struct ipw2100_priv *priv, int value)
{
/* This is called when wpa_supplicant loads and closes the driver
......@@ -5807,11 +5743,6 @@ static int ipw2100_wpa_enable(struct ipw2100_priv *priv, int value)
return 0;
}
#if WIRELESS_EXT < 18
#define IW_AUTH_ALG_OPEN_SYSTEM 0x1
#define IW_AUTH_ALG_SHARED_KEY 0x2
#endif
static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value)
{
......@@ -5855,360 +5786,6 @@ void ipw2100_wpa_assoc_frame(struct ipw2100_priv *priv,
ipw2100_set_wpa_ie(priv, &frame, 0);
}
#if WIRELESS_EXT < 18
static int ipw2100_wpa_set_param(struct net_device *dev, u8 name, u32 value)
{
struct ipw2100_priv *priv = ieee80211_priv(dev);
struct ieee80211_crypt_data *crypt;
unsigned long flags;
int ret = 0;
switch (name) {
case IPW2100_PARAM_WPA_ENABLED:
ret = ipw2100_wpa_enable(priv, value);
break;
case IPW2100_PARAM_TKIP_COUNTERMEASURES:
crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags)
break;
flags = crypt->ops->get_flags(crypt->priv);
if (value)
flags |= IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
else
flags &= ~IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
crypt->ops->set_flags(flags, crypt->priv);
break;
case IPW2100_PARAM_DROP_UNENCRYPTED:{
/* See IW_AUTH_DROP_UNENCRYPTED handling for details */
struct ieee80211_security sec = {
.flags = SEC_ENABLED,
.enabled = value,
};
priv->ieee->drop_unencrypted = value;
/* We only change SEC_LEVEL for open mode. Others
* are set by ipw_wpa_set_encryption.
*/
if (!value) {
sec.flags |= SEC_LEVEL;
sec.level = SEC_LEVEL_0;
} else {
sec.flags |= SEC_LEVEL;
sec.level = SEC_LEVEL_1;
}
if (priv->ieee->set_security)
priv->ieee->set_security(priv->ieee->dev, &sec);
break;
}
case IPW2100_PARAM_PRIVACY_INVOKED:
priv->ieee->privacy_invoked = value;
break;
case IPW2100_PARAM_AUTH_ALGS:
ret = ipw2100_wpa_set_auth_algs(priv, value);
break;
case IPW2100_PARAM_IEEE_802_1X:
priv->ieee->ieee802_1x = value;
break;
default:
printk(KERN_ERR DRV_NAME ": %s: Unknown WPA param: %d\n",
dev->name, name);
ret = -EOPNOTSUPP;
}
return ret;
}
static int ipw2100_wpa_mlme(struct net_device *dev, int command, int reason)
{
struct ipw2100_priv *priv = ieee80211_priv(dev);
int ret = 0;
switch (command) {
case IPW2100_MLME_STA_DEAUTH:
// silently ignore
break;
case IPW2100_MLME_STA_DISASSOC:
ipw2100_disassociate_bssid(priv);
break;
default:
printk(KERN_ERR DRV_NAME ": %s: Unknown MLME request: %d\n",
dev->name, command);
ret = -EOPNOTSUPP;
}
return ret;
}
static int ipw2100_wpa_set_wpa_ie(struct net_device *dev,
struct ipw2100_param *param, int plen)
{
struct ipw2100_priv *priv = ieee80211_priv(dev);
struct ieee80211_device *ieee = priv->ieee;
u8 *buf;
if (!ieee->wpa_enabled)
return -EOPNOTSUPP;
if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
(param->u.wpa_ie.len && param->u.wpa_ie.data == NULL))
return -EINVAL;
if (param->u.wpa_ie.len) {
buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL);
if (buf == NULL)
return -ENOMEM;
memcpy(buf, param->u.wpa_ie.data, param->u.wpa_ie.len);
kfree(ieee->wpa_ie);
ieee->wpa_ie = buf;
ieee->wpa_ie_len = param->u.wpa_ie.len;
} else {
kfree(ieee->wpa_ie);
ieee->wpa_ie = NULL;
ieee->wpa_ie_len = 0;
}
ipw2100_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len);
return 0;
}
/* implementation borrowed from hostap driver */
static int ipw2100_wpa_set_encryption(struct net_device *dev,
struct ipw2100_param *param,
int param_len)
{
int ret = 0;
struct ipw2100_priv *priv = ieee80211_priv(dev);
struct ieee80211_device *ieee = priv->ieee;
struct ieee80211_crypto_ops *ops;
struct ieee80211_crypt_data **crypt;
struct ieee80211_security sec = {
.flags = 0,
};
param->u.crypt.err = 0;
param->u.crypt.alg[IPW2100_CRYPT_ALG_NAME_LEN - 1] = '\0';
if (param_len !=
(int)((char *)param->u.crypt.key - (char *)param) +
param->u.crypt.key_len) {
IPW_DEBUG_INFO("Len mismatch %d, %d\n", param_len,
param->u.crypt.key_len);
return -EINVAL;
}
if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
if (param->u.crypt.idx >= WEP_KEYS)
return -EINVAL;
crypt = &ieee->crypt[param->u.crypt.idx];
} else {
return -EINVAL;
}
sec.flags |= SEC_ENABLED | SEC_ENCRYPT;
if (strcmp(param->u.crypt.alg, "none") == 0) {
if (crypt) {
sec.enabled = 0;
sec.encrypt = 0;
sec.level = SEC_LEVEL_0;
sec.flags |= SEC_LEVEL;
ieee80211_crypt_delayed_deinit(ieee, crypt);
}
goto done;
}
sec.enabled = 1;
sec.encrypt = 1;
ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
request_module("ieee80211_crypt_wep");
ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
} else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
request_module("ieee80211_crypt_tkip");
ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
} else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
request_module("ieee80211_crypt_ccmp");
ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
}
if (ops == NULL) {
IPW_DEBUG_INFO("%s: unknown crypto alg '%s'\n",
dev->name, param->u.crypt.alg);
param->u.crypt.err = IPW2100_CRYPT_ERR_UNKNOWN_ALG;
ret = -EINVAL;
goto done;
}
if (*crypt == NULL || (*crypt)->ops != ops) {
struct ieee80211_crypt_data *new_crypt;
ieee80211_crypt_delayed_deinit(ieee, crypt);
new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data), GFP_KERNEL);
if (new_crypt == NULL) {
ret = -ENOMEM;
goto done;
}
new_crypt->ops = ops;
if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
new_crypt->priv =
new_crypt->ops->init(param->u.crypt.idx);
if (new_crypt->priv == NULL) {
kfree(new_crypt);
param->u.crypt.err =
IPW2100_CRYPT_ERR_CRYPT_INIT_FAILED;
ret = -EINVAL;
goto done;
}
*crypt = new_crypt;
}
if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key &&
(*crypt)->ops->set_key(param->u.crypt.key,
param->u.crypt.key_len, param->u.crypt.seq,
(*crypt)->priv) < 0) {
IPW_DEBUG_INFO("%s: key setting failed\n", dev->name);
param->u.crypt.err = IPW2100_CRYPT_ERR_KEY_SET_FAILED;
ret = -EINVAL;
goto done;
}
if (param->u.crypt.set_tx) {
ieee->tx_keyidx = param->u.crypt.idx;
sec.active_key = param->u.crypt.idx;
sec.flags |= SEC_ACTIVE_KEY;
}
if (ops->name != NULL) {
if (strcmp(ops->name, "WEP") == 0) {
memcpy(sec.keys[param->u.crypt.idx],
param->u.crypt.key, param->u.crypt.key_len);
sec.key_sizes[param->u.crypt.idx] =
param->u.crypt.key_len;
sec.flags |= (1 << param->u.crypt.idx);
sec.flags |= SEC_LEVEL;
sec.level = SEC_LEVEL_1;
} else if (strcmp(ops->name, "TKIP") == 0) {
sec.flags |= SEC_LEVEL;
sec.level = SEC_LEVEL_2;
} else if (strcmp(ops->name, "CCMP") == 0) {
sec.flags |= SEC_LEVEL;
sec.level = SEC_LEVEL_3;
}
}
done:
if (ieee->set_security)
ieee->set_security(ieee->dev, &sec);
/* Do not reset port if card is in Managed mode since resetting will
* generate new IEEE 802.11 authentication which may end up in looping
* with IEEE 802.1X. If your hardware requires a reset after WEP
* configuration (for example... Prism2), implement the reset_port in
* the callbacks structures used to initialize the 802.11 stack. */
if (ieee->reset_on_keychange &&
ieee->iw_mode != IW_MODE_INFRA &&
ieee->reset_port && ieee->reset_port(dev)) {
IPW_DEBUG_INFO("%s: reset_port failed\n", dev->name);
param->u.crypt.err = IPW2100_CRYPT_ERR_CARD_CONF_FAILED;
return -EINVAL;
}
return ret;
}
static int ipw2100_wpa_supplicant(struct net_device *dev, struct iw_point *p)
{
struct ipw2100_param *param;
int ret = 0;
IPW_DEBUG_IOCTL("wpa_supplicant: len=%d\n", p->length);
if (p->length < sizeof(struct ipw2100_param) || !p->pointer)
return -EINVAL;
param = (struct ipw2100_param *)kmalloc(p->length, GFP_KERNEL);
if (param == NULL)
return -ENOMEM;
if (copy_from_user(param, p->pointer, p->length)) {
kfree(param);
return -EFAULT;
}
switch (param->cmd) {
case IPW2100_CMD_SET_WPA_PARAM:
ret = ipw2100_wpa_set_param(dev, param->u.wpa_param.name,
param->u.wpa_param.value);
break;
case IPW2100_CMD_SET_WPA_IE:
ret = ipw2100_wpa_set_wpa_ie(dev, param, p->length);
break;
case IPW2100_CMD_SET_ENCRYPTION:
ret = ipw2100_wpa_set_encryption(dev, param, p->length);
break;
case IPW2100_CMD_MLME:
ret = ipw2100_wpa_mlme(dev, param->u.mlme.command,
param->u.mlme.reason_code);
break;
default:
printk(KERN_ERR DRV_NAME
": %s: Unknown WPA supplicant request: %d\n", dev->name,
param->cmd);
ret = -EOPNOTSUPP;
}
if (ret == 0 && copy_to_user(p->pointer, param, p->length))
ret = -EFAULT;
kfree(param);
return ret;
}
static int ipw2100_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
{
struct iwreq *wrq = (struct iwreq *)rq;
int ret = -1;
switch (cmd) {
case IPW2100_IOCTL_WPA_SUPPLICANT:
ret = ipw2100_wpa_supplicant(dev, &wrq->u.data);
return ret;
default:
return -EOPNOTSUPP;
}
return -EOPNOTSUPP;
}
#endif /* WIRELESS_EXT < 18 */
static void ipw_ethtool_get_drvinfo(struct net_device *dev,
struct ethtool_drvinfo *info)
{
......@@ -6337,9 +5914,6 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev,
dev->open = ipw2100_open;
dev->stop = ipw2100_close;
dev->init = ipw2100_net_init;
#if WIRELESS_EXT < 18
dev->do_ioctl = ipw2100_ioctl;
#endif
dev->get_stats = ipw2100_stats;
dev->ethtool_ops = &ipw2100_ethtool_ops;
dev->tx_timeout = ipw2100_tx_timeout;
......@@ -7855,7 +7429,6 @@ static int ipw2100_wx_get_power(struct net_device *dev,
return 0;
}
#if WIRELESS_EXT > 17
/*
* WE-18 WPA support
*/
......@@ -8117,7 +7690,6 @@ static int ipw2100_wx_set_mlme(struct net_device *dev,
}
return 0;
}
#endif /* WIRELESS_EXT > 17 */
/*
*
......@@ -8350,11 +7922,7 @@ static iw_handler ipw2100_wx_handlers[] = {
NULL, /* SIOCWIWTHRSPY */
ipw2100_wx_set_wap, /* SIOCSIWAP */
ipw2100_wx_get_wap, /* SIOCGIWAP */
#if WIRELESS_EXT > 17
ipw2100_wx_set_mlme, /* SIOCSIWMLME */
#else
NULL, /* -- hole -- */
#endif
NULL, /* SIOCGIWAPLIST -- deprecated */
ipw2100_wx_set_scan, /* SIOCSIWSCAN */
ipw2100_wx_get_scan, /* SIOCGIWSCAN */
......@@ -8378,7 +7946,6 @@ static iw_handler ipw2100_wx_handlers[] = {
ipw2100_wx_get_encode, /* SIOCGIWENCODE */
ipw2100_wx_set_power, /* SIOCSIWPOWER */
ipw2100_wx_get_power, /* SIOCGIWPOWER */
#if WIRELESS_EXT > 17
NULL, /* -- hole -- */
NULL, /* -- hole -- */
ipw2100_wx_set_genie, /* SIOCSIWGENIE */
......@@ -8388,7 +7955,6 @@ static iw_handler ipw2100_wx_handlers[] = {
ipw2100_wx_set_encodeext, /* SIOCSIWENCODEEXT */
ipw2100_wx_get_encodeext, /* SIOCGIWENCODEEXT */
NULL, /* SIOCSIWPMKSA */
#endif
};
#define IPW2100_PRIV_SET_MONITOR SIOCIWFIRSTPRIV
......
......@@ -8936,14 +8936,12 @@ static int ipw_request_direct_scan(struct ipw_priv *priv, char *essid,
IPW_DEBUG_HC("starting request direct scan!\n");
if (priv->status & (STATUS_SCANNING | STATUS_SCAN_ABORTING)) {
err = wait_event_interruptible(priv->wait_state,
!(priv->
status & (STATUS_SCANNING |
STATUS_SCAN_ABORTING)));
if (err) {
IPW_DEBUG_HC("aborting direct scan");
goto done;
}
/* We should not sleep here; otherwise we will block most
* of the system (for instance, we hold rtnl_lock when we
* get here).
*/
err = -EAGAIN;
goto done;
}
memset(&scan, 0, sizeof(scan));
......
......@@ -748,7 +748,7 @@ prism54_get_essid(struct net_device *ndev, struct iw_request_info *info,
if (essid->length) {
dwrq->flags = 1; /* set ESSID to ON for Wireless Extensions */
/* if it is to big, trunk it */
dwrq->length = min(IW_ESSID_MAX_SIZE, essid->length + 1);
dwrq->length = min(IW_ESSID_MAX_SIZE, essid->length);
} else {
dwrq->flags = 0;
dwrq->length = 0;
......
......@@ -177,7 +177,7 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev)
#endif
newskb->dev = skb->dev;
dev_kfree_skb(skb);
dev_kfree_skb_irq(skb);
skb = newskb;
}
}
......
......@@ -1256,7 +1256,7 @@ static int ray_get_essid(struct net_device *dev,
extra[IW_ESSID_MAX_SIZE] = '\0';
/* Push it out ! */
dwrq->length = strlen(extra) + 1;
dwrq->length = strlen(extra);
dwrq->flags = 1; /* active */
return 0;
......
......@@ -2280,7 +2280,7 @@ static int wavelan_get_essid(struct net_device *dev,
extra[IW_ESSID_MAX_SIZE] = '\0';
/* Set the length */
wrqu->data.length = strlen(extra) + 1;
wrqu->data.length = strlen(extra);
return 0;
}
......
......@@ -25,6 +25,7 @@
#include <linux/types.h>
#include <linux/list.h>
#include <net/ieee80211.h>
#include <asm/atomic.h>
enum {
......
......@@ -327,7 +327,7 @@ struct iw_handler_def
__u16 num_private_args;
/* Array of handlers for standard ioctls
* We will call dev->wireless_handlers->standard[ioctl - SIOCSIWNAME]
* We will call dev->wireless_handlers->standard[ioctl - SIOCSIWCOMMIT]
*/
const iw_handler * standard;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册