diff options
Diffstat (limited to 'target/linux/generic-2.4/patches/100-wireless-extension.patch')
-rw-r--r-- | target/linux/generic-2.4/patches/100-wireless-extension.patch | 1116 |
1 files changed, 0 insertions, 1116 deletions
diff --git a/target/linux/generic-2.4/patches/100-wireless-extension.patch b/target/linux/generic-2.4/patches/100-wireless-extension.patch deleted file mode 100644 index a4eee2d87..000000000 --- a/target/linux/generic-2.4/patches/100-wireless-extension.patch +++ /dev/null @@ -1,1116 +0,0 @@ ---- a/include/linux/netdevice.h -+++ b/include/linux/netdevice.h -@@ -295,7 +295,9 @@ struct net_device - - /* List of functions to handle Wireless Extensions (instead of ioctl). - * See <net/iw_handler.h> for details. Jean II */ -- struct iw_handler_def * wireless_handlers; -+ const struct iw_handler_def * wireless_handlers; -+ /* Instance data managed by the core of Wireless Extensions. */ -+ struct iw_public_data * wireless_data; - - struct ethtool_ops *ethtool_ops; - ---- a/include/linux/wireless.h -+++ b/include/linux/wireless.h -@@ -1,10 +1,10 @@ - /* - * This file define a set of standard wireless extensions - * -- * Version : 16 2.4.03 -+ * Version : 18 12.3.05 - * - * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com> -- * Copyright (c) 1997-2002 Jean Tourrilhes, All Rights Reserved. -+ * Copyright (c) 1997-2005 Jean Tourrilhes, All Rights Reserved. - */ - - #ifndef _LINUX_WIRELESS_H -@@ -47,12 +47,12 @@ - * # include/net/iw_handler.h - * - * Note as well that /proc/net/wireless implementation has now moved in : -- * # include/linux/wireless.c -+ * # net/core/wireless.c - * - * Wireless Events (2002 -> onward) : - * -------------------------------- - * Events are defined at the end of this file, and implemented in : -- * # include/linux/wireless.c -+ * # net/core/wireless.c - * - * Other comments : - * -------------- -@@ -82,7 +82,7 @@ - * (there is some stuff that will be added in the future...) - * I just plan to increment with each new version. - */ --#define WIRELESS_EXT 16 -+#define WIRELESS_EXT 18 - - /* - * Changes : -@@ -175,6 +175,28 @@ - * - Remove IW_MAX_GET_SPY because conflict with enhanced spy support - * - Add SIOCSIWTHRSPY/SIOCGIWTHRSPY and "struct iw_thrspy" - * - Add IW_ENCODE_TEMP and iw_range->encoding_login_index -+ * -+ * V16 to V17 -+ * ---------- -+ * - Add flags to frequency -> auto/fixed -+ * - Document (struct iw_quality *)->updated, add new flags (INVALID) -+ * - Wireless Event capability in struct iw_range -+ * - Add support for relative TxPower (yick !) -+ * -+ * V17 to V18 (From Jouni Malinen <jkmaline@cc.hut.fi>) -+ * ---------- -+ * - Add support for WPA/WPA2 -+ * - Add extended encoding configuration (SIOCSIWENCODEEXT and -+ * SIOCGIWENCODEEXT) -+ * - Add SIOCSIWGENIE/SIOCGIWGENIE -+ * - Add SIOCSIWMLME -+ * - Add SIOCSIWPMKSA -+ * - Add struct iw_range bit field for supported encoding capabilities -+ * - Add optional scan request parameters for SIOCSIWSCAN -+ * - Add SIOCSIWAUTH/SIOCGIWAUTH for setting authentication and WPA -+ * related parameters (extensible up to 4096 parameter values) -+ * - Add wireless events: IWEVGENIE, IWEVMICHAELMICFAILURE, -+ * IWEVASSOCREQIE, IWEVASSOCRESPIE, IWEVPMKIDCAND - */ - - /**************************** CONSTANTS ****************************/ -@@ -249,9 +271,33 @@ - #define SIOCSIWPOWER 0x8B2C /* set Power Management settings */ - #define SIOCGIWPOWER 0x8B2D /* get Power Management settings */ - -+/* WPA : Generic IEEE 802.11 informatiom element (e.g., for WPA/RSN/WMM). -+ * This ioctl uses struct iw_point and data buffer that includes IE id and len -+ * fields. More than one IE may be included in the request. Setting the generic -+ * IE to empty buffer (len=0) removes the generic IE from the driver. Drivers -+ * are allowed to generate their own WPA/RSN IEs, but in these cases, drivers -+ * are required to report the used IE as a wireless event, e.g., when -+ * associating with an AP. */ -+#define SIOCSIWGENIE 0x8B30 /* set generic IE */ -+#define SIOCGIWGENIE 0x8B31 /* get generic IE */ -+ -+/* WPA : IEEE 802.11 MLME requests */ -+#define SIOCSIWMLME 0x8B16 /* request MLME operation; uses -+ * struct iw_mlme */ -+/* WPA : Authentication mode parameters */ -+#define SIOCSIWAUTH 0x8B32 /* set authentication mode params */ -+#define SIOCGIWAUTH 0x8B33 /* get authentication mode params */ -+ -+/* WPA : Extended version of encoding configuration */ -+#define SIOCSIWENCODEEXT 0x8B34 /* set encoding token & mode */ -+#define SIOCGIWENCODEEXT 0x8B35 /* get encoding token & mode */ -+ -+/* WPA2 : PMKSA cache management */ -+#define SIOCSIWPMKSA 0x8B36 /* PMKSA cache operation */ -+ - /* -------------------- DEV PRIVATE IOCTL LIST -------------------- */ - --/* These 16 ioctl are wireless device private. -+/* These 32 ioctl are wireless device private, for 16 commands. - * Each driver is free to use them for whatever purpose it chooses, - * however the driver *must* export the description of those ioctls - * with SIOCGIWPRIV and *must* use arguments as defined below. -@@ -266,8 +312,8 @@ - * We now have 32 commands, so a bit more space ;-). - * Also, all 'odd' commands are only usable by root and don't return the - * content of ifr/iwr to user (but you are not obliged to use the set/get -- * convention, just use every other two command). -- * And I repeat : you are not obliged to use them with iwspy, but you -+ * convention, just use every other two command). More details in iwpriv.c. -+ * And I repeat : you are not forced to use them with iwpriv, but you - * must be compliant with it. - */ - -@@ -290,6 +336,34 @@ - #define IWEVCUSTOM 0x8C02 /* Driver specific ascii string */ - #define IWEVREGISTERED 0x8C03 /* Discovered a new node (AP mode) */ - #define IWEVEXPIRED 0x8C04 /* Expired a node (AP mode) */ -+#define IWEVGENIE 0x8C05 /* Generic IE (WPA, RSN, WMM, ..) -+ * (scan results); This includes id and -+ * length fields. One IWEVGENIE may -+ * contain more than one IE. Scan -+ * results may contain one or more -+ * IWEVGENIE events. */ -+#define IWEVMICHAELMICFAILURE 0x8C06 /* Michael MIC failure -+ * (struct iw_michaelmicfailure) -+ */ -+#define IWEVASSOCREQIE 0x8C07 /* IEs used in (Re)Association Request. -+ * The data includes id and length -+ * fields and may contain more than one -+ * IE. This event is required in -+ * Managed mode if the driver -+ * generates its own WPA/RSN IE. This -+ * should be sent just before -+ * IWEVREGISTERED event for the -+ * association. */ -+#define IWEVASSOCRESPIE 0x8C08 /* IEs used in (Re)Association -+ * Response. The data includes id and -+ * length fields and may contain more -+ * than one IE. This may be sent -+ * between IWEVASSOCREQIE and -+ * IWEVREGISTERED events for the -+ * association. */ -+#define IWEVPMKIDCAND 0x8C09 /* PMKID candidate for RSN -+ * pre-authentication -+ * (struct iw_pmkid_cand) */ - - #define IWEVFIRST 0x8C00 - -@@ -352,6 +426,18 @@ - #define IW_MODE_SECOND 5 /* Secondary master/repeater (backup) */ - #define IW_MODE_MONITOR 6 /* Passive monitor (listen only) */ - -+/* Statistics flags (bitmask in updated) */ -+#define IW_QUAL_QUAL_UPDATED 0x1 /* Value was updated since last read */ -+#define IW_QUAL_LEVEL_UPDATED 0x2 -+#define IW_QUAL_NOISE_UPDATED 0x4 -+#define IW_QUAL_QUAL_INVALID 0x10 /* Driver doesn't provide value */ -+#define IW_QUAL_LEVEL_INVALID 0x20 -+#define IW_QUAL_NOISE_INVALID 0x40 -+ -+/* Frequency flags */ -+#define IW_FREQ_AUTO 0x00 /* Let the driver decides */ -+#define IW_FREQ_FIXED 0x01 /* Force a specific value */ -+ - /* Maximum number of size of encoding token available - * they are listed in the range structure */ - #define IW_MAX_ENCODING_SIZES 8 -@@ -390,6 +476,7 @@ - #define IW_TXPOW_TYPE 0x00FF /* Type of value */ - #define IW_TXPOW_DBM 0x0000 /* Value is in dBm */ - #define IW_TXPOW_MWATT 0x0001 /* Value is in mW */ -+#define IW_TXPOW_RELATIVE 0x0002 /* Value is in arbitrary units */ - #define IW_TXPOW_RANGE 0x1000 /* Range of value between min/max */ - - /* Retry limits and lifetime flags available */ -@@ -412,12 +499,113 @@ - #define IW_SCAN_THIS_MODE 0x0020 /* Scan only this Mode */ - #define IW_SCAN_ALL_RATE 0x0040 /* Scan all Bit-Rates */ - #define IW_SCAN_THIS_RATE 0x0080 /* Scan only this Bit-Rate */ -+/* struct iw_scan_req scan_type */ -+#define IW_SCAN_TYPE_ACTIVE 0 -+#define IW_SCAN_TYPE_PASSIVE 1 - /* Maximum size of returned data */ - #define IW_SCAN_MAX_DATA 4096 /* In bytes */ - - /* Max number of char in custom event - use multiple of them if needed */ - #define IW_CUSTOM_MAX 256 /* In bytes */ - -+/* Generic information element */ -+#define IW_GENERIC_IE_MAX 1024 -+ -+/* MLME requests (SIOCSIWMLME / struct iw_mlme) */ -+#define IW_MLME_DEAUTH 0 -+#define IW_MLME_DISASSOC 1 -+ -+/* SIOCSIWAUTH/SIOCGIWAUTH struct iw_param flags */ -+#define IW_AUTH_INDEX 0x0FFF -+#define IW_AUTH_FLAGS 0xF000 -+/* SIOCSIWAUTH/SIOCGIWAUTH parameters (0 .. 4095) -+ * (IW_AUTH_INDEX mask in struct iw_param flags; this is the index of the -+ * parameter that is being set/get to; value will be read/written to -+ * struct iw_param value field) */ -+#define IW_AUTH_WPA_VERSION 0 -+#define IW_AUTH_CIPHER_PAIRWISE 1 -+#define IW_AUTH_CIPHER_GROUP 2 -+#define IW_AUTH_KEY_MGMT 3 -+#define IW_AUTH_TKIP_COUNTERMEASURES 4 -+#define IW_AUTH_DROP_UNENCRYPTED 5 -+#define IW_AUTH_80211_AUTH_ALG 6 -+#define IW_AUTH_WPA_ENABLED 7 -+#define IW_AUTH_RX_UNENCRYPTED_EAPOL 8 -+#define IW_AUTH_ROAMING_CONTROL 9 -+#define IW_AUTH_PRIVACY_INVOKED 10 -+ -+/* IW_AUTH_WPA_VERSION values (bit field) */ -+#define IW_AUTH_WPA_VERSION_DISABLED 0x00000001 -+#define IW_AUTH_WPA_VERSION_WPA 0x00000002 -+#define IW_AUTH_WPA_VERSION_WPA2 0x00000004 -+ -+/* IW_AUTH_PAIRWISE_CIPHER and IW_AUTH_GROUP_CIPHER values (bit field) */ -+#define IW_AUTH_CIPHER_NONE 0x00000001 -+#define IW_AUTH_CIPHER_WEP40 0x00000002 -+#define IW_AUTH_CIPHER_TKIP 0x00000004 -+#define IW_AUTH_CIPHER_CCMP 0x00000008 -+#define IW_AUTH_CIPHER_WEP104 0x00000010 -+ -+/* IW_AUTH_KEY_MGMT values (bit field) */ -+#define IW_AUTH_KEY_MGMT_802_1X 1 -+#define IW_AUTH_KEY_MGMT_PSK 2 -+ -+/* IW_AUTH_80211_AUTH_ALG values (bit field) */ -+#define IW_AUTH_ALG_OPEN_SYSTEM 0x00000001 -+#define IW_AUTH_ALG_SHARED_KEY 0x00000002 -+#define IW_AUTH_ALG_LEAP 0x00000004 -+ -+/* IW_AUTH_ROAMING_CONTROL values */ -+#define IW_AUTH_ROAMING_ENABLE 0 /* driver/firmware based roaming */ -+#define IW_AUTH_ROAMING_DISABLE 1 /* user space program used for roaming -+ * control */ -+ -+/* SIOCSIWENCODEEXT definitions */ -+#define IW_ENCODE_SEQ_MAX_SIZE 8 -+/* struct iw_encode_ext ->alg */ -+#define IW_ENCODE_ALG_NONE 0 -+#define IW_ENCODE_ALG_WEP 1 -+#define IW_ENCODE_ALG_TKIP 2 -+#define IW_ENCODE_ALG_CCMP 3 -+/* struct iw_encode_ext ->ext_flags */ -+#define IW_ENCODE_EXT_TX_SEQ_VALID 0x00000001 -+#define IW_ENCODE_EXT_RX_SEQ_VALID 0x00000002 -+#define IW_ENCODE_EXT_GROUP_KEY 0x00000004 -+#define IW_ENCODE_EXT_SET_TX_KEY 0x00000008 -+ -+/* IWEVMICHAELMICFAILURE : struct iw_michaelmicfailure ->flags */ -+#define IW_MICFAILURE_KEY_ID 0x00000003 /* Key ID 0..3 */ -+#define IW_MICFAILURE_GROUP 0x00000004 -+#define IW_MICFAILURE_PAIRWISE 0x00000008 -+#define IW_MICFAILURE_STAKEY 0x00000010 -+#define IW_MICFAILURE_COUNT 0x00000060 /* 1 or 2 (0 = count not supported) -+ */ -+ -+/* Bit field values for enc_capa in struct iw_range */ -+#define IW_ENC_CAPA_WPA 0x00000001 -+#define IW_ENC_CAPA_WPA2 0x00000002 -+#define IW_ENC_CAPA_CIPHER_TKIP 0x00000004 -+#define IW_ENC_CAPA_CIPHER_CCMP 0x00000008 -+ -+/* Event capability macros - in (struct iw_range *)->event_capa -+ * Because we have more than 32 possible events, we use an array of -+ * 32 bit bitmasks. Note : 32 bits = 0x20 = 2^5. */ -+#define IW_EVENT_CAPA_BASE(cmd) ((cmd >= SIOCIWFIRSTPRIV) ? \ -+ (cmd - SIOCIWFIRSTPRIV + 0x60) : \ -+ (cmd - SIOCSIWCOMMIT)) -+#define IW_EVENT_CAPA_INDEX(cmd) (IW_EVENT_CAPA_BASE(cmd) >> 5) -+#define IW_EVENT_CAPA_MASK(cmd) (1 << (IW_EVENT_CAPA_BASE(cmd) & 0x1F)) -+/* Event capability constants - event autogenerated by the kernel -+ * This list is valid for most 802.11 devices, customise as needed... */ -+#define IW_EVENT_CAPA_K_0 (IW_EVENT_CAPA_MASK(0x8B04) | \ -+ IW_EVENT_CAPA_MASK(0x8B06) | \ -+ IW_EVENT_CAPA_MASK(0x8B1A)) -+#define IW_EVENT_CAPA_K_1 (IW_EVENT_CAPA_MASK(0x8B2A)) -+/* "Easy" macro to set events in iw_range (less efficient) */ -+#define IW_EVENT_CAPA_SET(event_capa, cmd) (event_capa[IW_EVENT_CAPA_INDEX(cmd)] |= IW_EVENT_CAPA_MASK(cmd)) -+#define IW_EVENT_CAPA_SET_KERNEL(event_capa) {event_capa[0] |= IW_EVENT_CAPA_K_0; event_capa[1] |= IW_EVENT_CAPA_K_1; } -+ -+ - /****************************** TYPES ******************************/ - - /* --------------------------- SUBTYPES --------------------------- */ -@@ -456,7 +644,7 @@ struct iw_freq - __s32 m; /* Mantissa */ - __s16 e; /* Exponent */ - __u8 i; /* List index (when in range struct) */ -- __u8 pad; /* Unused - just for alignement */ -+ __u8 flags; /* Flags (fixed/auto) */ - }; - - /* -@@ -507,6 +695,132 @@ struct iw_thrspy - struct iw_quality high; /* High threshold */ - }; - -+/* -+ * Optional data for scan request -+ * -+ * Note: these optional parameters are controlling parameters for the -+ * scanning behavior, these do not apply to getting scan results -+ * (SIOCGIWSCAN). Drivers are expected to keep a local BSS table and -+ * provide a merged results with all BSSes even if the previous scan -+ * request limited scanning to a subset, e.g., by specifying an SSID. -+ * Especially, scan results are required to include an entry for the -+ * current BSS if the driver is in Managed mode and associated with an AP. -+ */ -+struct iw_scan_req -+{ -+ __u8 scan_type; /* IW_SCAN_TYPE_{ACTIVE,PASSIVE} */ -+ __u8 essid_len; -+ __u8 num_channels; /* num entries in channel_list; -+ * 0 = scan all allowed channels */ -+ __u8 flags; /* reserved as padding; use zero, this may -+ * be used in the future for adding flags -+ * to request different scan behavior */ -+ struct sockaddr bssid; /* ff:ff:ff:ff:ff:ff for broadcast BSSID or -+ * individual address of a specific BSS */ -+ -+ /* -+ * Use this ESSID if IW_SCAN_THIS_ESSID flag is used instead of using -+ * the current ESSID. This allows scan requests for specific ESSID -+ * without having to change the current ESSID and potentially breaking -+ * the current association. -+ */ -+ __u8 essid[IW_ESSID_MAX_SIZE]; -+ -+ /* -+ * Optional parameters for changing the default scanning behavior. -+ * These are based on the MLME-SCAN.request from IEEE Std 802.11. -+ * TU is 1.024 ms. If these are set to 0, driver is expected to use -+ * reasonable default values. min_channel_time defines the time that -+ * will be used to wait for the first reply on each channel. If no -+ * replies are received, next channel will be scanned after this. If -+ * replies are received, total time waited on the channel is defined by -+ * max_channel_time. -+ */ -+ __u32 min_channel_time; /* in TU */ -+ __u32 max_channel_time; /* in TU */ -+ -+ struct iw_freq channel_list[IW_MAX_FREQUENCIES]; -+}; -+ -+/* ------------------------- WPA SUPPORT ------------------------- */ -+ -+/* -+ * Extended data structure for get/set encoding (this is used with -+ * SIOCSIWENCODEEXT/SIOCGIWENCODEEXT. struct iw_point and IW_ENCODE_* -+ * flags are used in the same way as with SIOCSIWENCODE/SIOCGIWENCODE and -+ * only the data contents changes (key data -> this structure, including -+ * key data). -+ * -+ * If the new key is the first group key, it will be set as the default -+ * TX key. Otherwise, default TX key index is only changed if -+ * IW_ENCODE_EXT_SET_TX_KEY flag is set. -+ * -+ * Key will be changed with SIOCSIWENCODEEXT in all cases except for -+ * special "change TX key index" operation which is indicated by setting -+ * key_len = 0 and ext_flags |= IW_ENCODE_EXT_SET_TX_KEY. -+ * -+ * tx_seq/rx_seq are only used when respective -+ * IW_ENCODE_EXT_{TX,RX}_SEQ_VALID flag is set in ext_flags. Normal -+ * TKIP/CCMP operation is to set RX seq with SIOCSIWENCODEEXT and start -+ * TX seq from zero whenever key is changed. SIOCGIWENCODEEXT is normally -+ * used only by an Authenticator (AP or an IBSS station) to get the -+ * current TX sequence number. Using TX_SEQ_VALID for SIOCSIWENCODEEXT and -+ * RX_SEQ_VALID for SIOCGIWENCODEEXT are optional, but can be useful for -+ * debugging/testing. -+ */ -+struct iw_encode_ext -+{ -+ __u32 ext_flags; /* IW_ENCODE_EXT_* */ -+ __u8 tx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /* LSB first */ -+ __u8 rx_seq[IW_ENCODE_SEQ_MAX_SIZE]; /* LSB first */ -+ struct sockaddr addr; /* ff:ff:ff:ff:ff:ff for broadcast/multicast -+ * (group) keys or unicast address for -+ * individual keys */ -+ __u16 alg; /* IW_ENCODE_ALG_* */ -+ __u16 key_len; -+ __u8 key[0]; -+}; -+ -+/* SIOCSIWMLME data */ -+struct iw_mlme -+{ -+ __u16 cmd; /* IW_MLME_* */ -+ __u16 reason_code; -+ struct sockaddr addr; -+}; -+ -+/* SIOCSIWPMKSA data */ -+#define IW_PMKSA_ADD 1 -+#define IW_PMKSA_REMOVE 2 -+#define IW_PMKSA_FLUSH 3 -+ -+#define IW_PMKID_LEN 16 -+ -+struct iw_pmksa -+{ -+ __u32 cmd; /* IW_PMKSA_* */ -+ struct sockaddr bssid; -+ __u8 pmkid[IW_PMKID_LEN]; -+}; -+ -+/* IWEVMICHAELMICFAILURE data */ -+struct iw_michaelmicfailure -+{ -+ __u32 flags; -+ struct sockaddr src_addr; -+ __u8 tsc[IW_ENCODE_SEQ_MAX_SIZE]; /* LSB first */ -+}; -+ -+/* IWEVPMKIDCAND data */ -+#define IW_PMKID_CAND_PREAUTH 0x00000001 /* RNS pre-authentication enabled */ -+struct iw_pmkid_cand -+{ -+ __u32 flags; /* IW_PMKID_CAND_* */ -+ __u32 index; /* the smaller the index, the higher the -+ * priority */ -+ struct sockaddr bssid; -+}; -+ - /* ------------------------ WIRELESS STATS ------------------------ */ - /* - * Wireless statistics (used for /proc/net/wireless) -@@ -610,11 +924,12 @@ struct iw_range - /* Old Frequency (backward compat - moved lower ) */ - __u16 old_num_channels; - __u8 old_num_frequency; -- /* Filler to keep "version" at the same offset */ -- __s32 old_freq[6]; -+ -+ /* Wireless event capability bitmasks */ -+ __u32 event_capa[6]; - - /* signal level threshold range */ -- __s32 sensitivity; -+ __s32 sensitivity; - - /* Quality of link & SNR stuff */ - /* Quality range (link, level, noise) -@@ -685,6 +1000,8 @@ struct iw_range - struct iw_freq freq[IW_MAX_FREQUENCIES]; /* list */ - /* Note : this frequency list doesn't need to fit channel numbers, - * because each entry contain its channel index */ -+ -+ __u32 enc_capa; /* IW_ENC_CAPA_* bit field */ - }; - - /* ---- a/include/net/iw_handler.h -+++ b/include/net/iw_handler.h -@@ -1,10 +1,10 @@ - /* - * This file define the new driver API for Wireless Extensions - * -- * Version : 5 4.12.02 -+ * Version : 6 21.6.04 - * - * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com> -- * Copyright (c) 2001-2002 Jean Tourrilhes, All Rights Reserved. -+ * Copyright (c) 2001-2004 Jean Tourrilhes, All Rights Reserved. - */ - - #ifndef _IW_HANDLER_H -@@ -206,7 +206,7 @@ - * will be needed... - * I just plan to increment with each new version. - */ --#define IW_HANDLER_VERSION 5 -+#define IW_HANDLER_VERSION 6 - - /* - * Changes : -@@ -224,11 +224,18 @@ - * V4 to V5 - * -------- - * - Add new spy support : struct iw_spy_data & prototypes -+ * -+ * V5 to V6 -+ * -------- -+ * - Change the way we get to spy_data method for added safety -+ * - Remove spy #ifdef, they are always on -> cleaner code -+ * - Add IW_DESCR_FLAG_NOMAX flag for very large requests -+ * - Start migrating get_wireless_stats to struct iw_handler_def - */ - - /**************************** CONSTANTS ****************************/ - --/* Enable enhanced spy support. Disable to reduce footprint */ -+/* Enhanced spy support available */ - #define IW_WIRELESS_SPY - #define IW_WIRELESS_THRSPY - -@@ -258,6 +265,7 @@ - #define IW_DESCR_FLAG_EVENT 0x0002 /* Generate an event on SET */ - #define IW_DESCR_FLAG_RESTRICT 0x0004 /* GET : request is ROOT only */ - /* SET : Omit payload from generated iwevent */ -+#define IW_DESCR_FLAG_NOMAX 0x0008 /* GET : no limit on request size */ - /* Driver level flags */ - #define IW_DESCR_FLAG_WAIT 0x0100 /* Wait for driver event */ - -@@ -311,23 +319,25 @@ struct iw_handler_def - /* Array of handlers for standard ioctls - * We will call dev->wireless_handlers->standard[ioctl - SIOCSIWNAME] - */ -- iw_handler * standard; -+ const iw_handler * standard; - - /* Array of handlers for private ioctls - * Will call dev->wireless_handlers->private[ioctl - SIOCIWFIRSTPRIV] - */ -- iw_handler * private; -+ const iw_handler * private; - - /* Arguments of private handler. This one is just a list, so you - * can put it in any order you want and should not leave holes... - * We will automatically export that to user space... */ -- struct iw_priv_args * private_args; -+ const struct iw_priv_args * private_args; - -- /* Driver enhanced spy support */ -- long spy_offset; /* Spy data offset */ -+ /* This field will be *removed* in the next version of WE */ -+ long spy_offset; /* DO NOT USE */ - -- /* In the long term, get_wireless_stats will move from -- * 'struct net_device' to here, to minimise bloat. */ -+ /* New location of get_wireless_stats, to de-bloat struct net_device. -+ * The old pointer in struct net_device will be gradually phased -+ * out, and drivers are encouraged to use this one... */ -+ struct iw_statistics* (*get_wireless_stats)(struct net_device *dev); - }; - - /* ---------------------- IOCTL DESCRIPTION ---------------------- */ -@@ -374,18 +384,29 @@ struct iw_ioctl_description - */ - struct iw_spy_data - { --#ifdef IW_WIRELESS_SPY - /* --- Standard spy support --- */ - int spy_number; - u_char spy_address[IW_MAX_SPY][ETH_ALEN]; - struct iw_quality spy_stat[IW_MAX_SPY]; --#ifdef IW_WIRELESS_THRSPY - /* --- Enhanced spy support (event) */ - struct iw_quality spy_thr_low; /* Low threshold */ - struct iw_quality spy_thr_high; /* High threshold */ - u_char spy_thr_under[IW_MAX_SPY]; --#endif /* IW_WIRELESS_THRSPY */ --#endif /* IW_WIRELESS_SPY */ -+}; -+ -+/* --------------------- DEVICE WIRELESS DATA --------------------- */ -+/* -+ * This is all the wireless data specific to a device instance that -+ * is managed by the core of Wireless Extensions. -+ * We only keep pointer to those structures, so that a driver is free -+ * to share them between instances. -+ * This structure should be initialised before registering the device. -+ * Access to this data follow the same rules as any other struct net_device -+ * data (i.e. valid as long as struct net_device exist, same locking rules). -+ */ -+struct iw_public_data { -+ /* Driver enhanced spy support */ -+ struct iw_spy_data * spy_data; - }; - - /**************************** PROTOTYPES ****************************/ ---- a/net/core/dev.c -+++ b/net/core/dev.c -@@ -2426,7 +2426,7 @@ int dev_ioctl(unsigned int cmd, void *ar - /* Follow me in net/core/wireless.c */ - ret = wireless_process_ioctl(&ifr, cmd); - rtnl_unlock(); -- if (!ret && IW_IS_GET(cmd) && -+ if (IW_IS_GET(cmd) && - copy_to_user(arg, &ifr, sizeof(struct ifreq))) - return -EFAULT; - return ret; ---- a/net/core/wireless.c -+++ b/net/core/wireless.c -@@ -2,7 +2,7 @@ - * This file implement the Wireless Extensions APIs. - * - * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com> -- * Copyright (c) 1997-2003 Jean Tourrilhes, All Rights Reserved. -+ * Copyright (c) 1997-2005 Jean Tourrilhes, All Rights Reserved. - * - * (As all part of the Linux kernel, this file is GPL) - */ -@@ -48,6 +48,16 @@ - * o Add common spy support : iw_handler_set_spy(), wireless_spy_update() - * o Add enhanced spy support : iw_handler_set_thrspy() and event. - * o Add WIRELESS_EXT version display in /proc/net/wireless -+ * -+ * v6 - 18.06.04 - Jean II -+ * o Change get_spydata() method for added safety -+ * o Remove spy #ifdef, they are always on -> cleaner code -+ * o Allow any size GET request if user specifies length > max -+ * and if request has IW_DESCR_FLAG_NOMAX flag or is SIOCGIWPRIV -+ * o Start migrating get_wireless_stats to struct iw_handler_def -+ * o Add wmb() in iw_handler_set_spy() for non-coherent archs/cpus -+ * Based on patch from Pavel Roskin <proski@gnu.org> : -+ * o Fix kernel data leak to user space in private handler handling - */ - - /***************************** INCLUDES *****************************/ -@@ -64,11 +74,7 @@ - - /**************************** CONSTANTS ****************************/ - --/* Enough lenience, let's make sure things are proper... */ --#define WE_STRICT_WRITE /* Check write buffer size */ --/* I'll probably drop both the define and kernel message in the next version */ -- --/* Debuging stuff */ -+/* Debugging stuff */ - #undef WE_IOCTL_DEBUG /* Debug IOCTL API */ - #undef WE_EVENT_DEBUG /* Debug Event dispatcher */ - #undef WE_SPY_DEBUG /* Debug enhanced spy support */ -@@ -131,14 +137,14 @@ static const struct iw_ioctl_description - { IW_HEADER_TYPE_ADDR, 0, 0, 0, 0, 0}, - /* SIOCGIWAP */ - { IW_HEADER_TYPE_ADDR, 0, 0, 0, 0, IW_DESCR_FLAG_DUMP}, -- /* -- hole -- */ -- { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0}, -+ /* SIOCSIWMLME */ -+ { IW_HEADER_TYPE_POINT, 0, 1, sizeof(struct iw_mlme), sizeof(struct iw_mlme), 0}, - /* SIOCGIWAPLIST */ -- { IW_HEADER_TYPE_POINT, 0, (sizeof(struct sockaddr) + sizeof(struct iw_quality)), 0, IW_MAX_AP, 0}, -+ { IW_HEADER_TYPE_POINT, 0, (sizeof(struct sockaddr) + sizeof(struct iw_quality)), 0, IW_MAX_AP, IW_DESCR_FLAG_NOMAX}, - /* SIOCSIWSCAN */ -- { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0}, -+ { IW_HEADER_TYPE_POINT, 0, 1, 0, sizeof(struct iw_scan_req), 0}, - /* SIOCGIWSCAN */ -- { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_SCAN_MAX_DATA, 0}, -+ { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_SCAN_MAX_DATA, IW_DESCR_FLAG_NOMAX}, - /* SIOCSIWESSID */ - { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_ESSID_MAX_SIZE + 1, IW_DESCR_FLAG_EVENT}, - /* SIOCGIWESSID */ -@@ -179,6 +185,25 @@ static const struct iw_ioctl_description - { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0}, - /* SIOCGIWPOWER */ - { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0}, -+ /* -- hole -- */ -+ { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0}, -+ /* -- hole -- */ -+ { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0}, -+ /* SIOCSIWGENIE */ -+ { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_GENERIC_IE_MAX, 0}, -+ /* SIOCGIWGENIE */ -+ { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_GENERIC_IE_MAX, 0}, -+ /* SIOCSIWAUTH */ -+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0}, -+ /* SIOCGIWAUTH */ -+ { IW_HEADER_TYPE_PARAM, 0, 0, 0, 0, 0}, -+ /* SIOCSIWENCODEEXT */ -+ { IW_HEADER_TYPE_POINT, 0, 1, sizeof(struct iw_encode_ext), sizeof(struct iw_encode_ext) + IW_ENCODING_TOKEN_MAX, 0}, -+ /* SIOCGIWENCODEEXT */ -+ { IW_HEADER_TYPE_POINT, 0, 1, sizeof(struct iw_encode_ext), sizeof(struct iw_encode_ext) + IW_ENCODING_TOKEN_MAX, 0}, -+ /* SIOCSIWPMKSA */ -+ { IW_HEADER_TYPE_POINT, 0, 1, sizeof(struct iw_pmksa), sizeof(struct iw_pmksa), 0}, -+ /* -- hole -- */ - }; - static const int standard_ioctl_num = (sizeof(standard_ioctl) / - sizeof(struct iw_ioctl_description)); -@@ -198,12 +223,22 @@ static const struct iw_ioctl_description - { IW_HEADER_TYPE_ADDR, 0, 0, 0, 0, 0}, - /* IWEVEXPIRED */ - { IW_HEADER_TYPE_ADDR, 0, 0, 0, 0, 0}, -+ /* IWEVGENIE */ -+ { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_GENERIC_IE_MAX, 0}, -+ /* IWEVMICHAELMICFAILURE */ -+ { IW_HEADER_TYPE_POINT, 0, 1, 0, sizeof(struct iw_michaelmicfailure), 0}, -+ /* IWEVASSOCREQIE */ -+ { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_GENERIC_IE_MAX, 0}, -+ /* IWEVASSOCRESPIE */ -+ { IW_HEADER_TYPE_POINT, 0, 1, 0, IW_GENERIC_IE_MAX, 0}, -+ /* IWEVPMKIDCAND */ -+ { IW_HEADER_TYPE_POINT, 0, 1, 0, sizeof(struct iw_pmkid_cand), 0}, - }; - static const int standard_event_num = (sizeof(standard_event) / - sizeof(struct iw_ioctl_description)); - - /* Size (in bytes) of the various private data types */ --static const char priv_type_size[] = { -+static const char iw_priv_type_size[] = { - 0, /* IW_PRIV_TYPE_NONE */ - 1, /* IW_PRIV_TYPE_BYTE */ - 1, /* IW_PRIV_TYPE_CHAR */ -@@ -270,12 +305,15 @@ static inline iw_handler get_handler(str - */ - static inline struct iw_statistics *get_wireless_stats(struct net_device *dev) - { -+ /* New location */ -+ if((dev->wireless_handlers != NULL) && -+ (dev->wireless_handlers->get_wireless_stats != NULL)) -+ return dev->wireless_handlers->get_wireless_stats(dev); -+ -+ /* Old location, will be phased out in next WE */ - return (dev->get_wireless_stats ? - dev->get_wireless_stats(dev) : - (struct iw_statistics *) NULL); -- /* In the future, get_wireless_stats may move from 'struct net_device' -- * to 'struct iw_handler_def', to de-bloat struct net_device. -- * Definitely worse a thought... */ - } - - /* ---------------------------------------------------------------- */ -@@ -310,14 +348,32 @@ static inline int call_commit_handler(st - - /* ---------------------------------------------------------------- */ - /* -- * Number of private arguments -+ * Calculate size of private arguments - */ - static inline int get_priv_size(__u16 args) - { - int num = args & IW_PRIV_SIZE_MASK; - int type = (args & IW_PRIV_TYPE_MASK) >> 12; - -- return num * priv_type_size[type]; -+ return num * iw_priv_type_size[type]; -+} -+ -+/* ---------------------------------------------------------------- */ -+/* -+ * Re-calculate the size of private arguments -+ */ -+static inline int adjust_priv_size(__u16 args, -+ union iwreq_data * wrqu) -+{ -+ int num = wrqu->data.length; -+ int max = args & IW_PRIV_SIZE_MASK; -+ int type = (args & IW_PRIV_TYPE_MASK) >> 12; -+ -+ /* Make sure the driver doesn't goof up */ -+ if (max < num) -+ num = max; -+ -+ return num * iw_priv_type_size[type]; - } - - -@@ -350,11 +406,14 @@ static inline int sprintf_wireless_stats - dev->name, - stats->status, - stats->qual.qual, -- stats->qual.updated & 1 ? '.' : ' ', -+ stats->qual.updated & IW_QUAL_QUAL_UPDATED -+ ? '.' : ' ', - ((__u8) stats->qual.level), -- stats->qual.updated & 2 ? '.' : ' ', -+ stats->qual.updated & IW_QUAL_LEVEL_UPDATED -+ ? '.' : ' ', - ((__u8) stats->qual.noise), -- stats->qual.updated & 4 ? '.' : ' ', -+ stats->qual.updated & IW_QUAL_NOISE_UPDATED -+ ? '.' : ' ', - stats->discard.nwid, - stats->discard.code, - stats->discard.fragment, -@@ -470,13 +529,15 @@ static inline int ioctl_export_private(s - /* Check NULL pointer */ - if(iwr->u.data.pointer == NULL) - return -EFAULT; --#ifdef WE_STRICT_WRITE -+ - /* Check if there is enough buffer up there */ - if(iwr->u.data.length < dev->wireless_handlers->num_private_args) { -- printk(KERN_ERR "%s (WE) : Buffer for request SIOCGIWPRIV too small (%d<%d)\n", dev->name, iwr->u.data.length, dev->wireless_handlers->num_private_args); -+ /* User space can't know in advance how large the buffer -+ * needs to be. Give it a hint, so that we can support -+ * any size buffer we want somewhat efficiently... */ -+ iwr->u.data.length = dev->wireless_handlers->num_private_args; - return -E2BIG; - } --#endif /* WE_STRICT_WRITE */ - - /* Set the number of available ioctls. */ - iwr->u.data.length = dev->wireless_handlers->num_private_args; -@@ -505,7 +566,6 @@ static inline int ioctl_standard_call(st - const struct iw_ioctl_description * descr; - struct iw_request_info info; - int ret = -EINVAL; -- int user_size = 0; - - /* Get the description of the IOCTL */ - if((cmd - SIOCIWFIRST) >= standard_ioctl_num) -@@ -536,8 +596,14 @@ static inline int ioctl_standard_call(st - #endif /* WE_SET_EVENT */ - } else { - char * extra; -+ int extra_size; -+ int user_length = 0; - int err; - -+ /* Calculate space needed by arguments. Always allocate -+ * for max space. Easier, and won't last long... */ -+ extra_size = descr->max_tokens * descr->token_size; -+ - /* Check what user space is giving us */ - if(IW_IS_SET(cmd)) { - /* Check NULL pointer */ -@@ -554,18 +620,33 @@ static inline int ioctl_standard_call(st - if(iwr->u.data.pointer == NULL) - return -EFAULT; - /* Save user space buffer size for checking */ -- user_size = iwr->u.data.length; -+ user_length = iwr->u.data.length; -+ -+ /* Don't check if user_length > max to allow forward -+ * compatibility. The test user_length < min is -+ * implied by the test at the end. */ -+ -+ /* Support for very large requests */ -+ if((descr->flags & IW_DESCR_FLAG_NOMAX) && -+ (user_length > descr->max_tokens)) { -+ /* Allow userspace to GET more than max so -+ * we can support any size GET requests. -+ * There is still a limit : -ENOMEM. */ -+ extra_size = user_length * descr->token_size; -+ /* Note : user_length is originally a __u16, -+ * and token_size is controlled by us, -+ * so extra_size won't get negative and -+ * won't overflow... */ -+ } - } - - #ifdef WE_IOCTL_DEBUG - printk(KERN_DEBUG "%s (WE) : Malloc %d bytes\n", -- dev->name, descr->max_tokens * descr->token_size); -+ dev->name, extra_size); - #endif /* WE_IOCTL_DEBUG */ - -- /* Always allocate for max space. Easier, and won't last -- * long... */ -- extra = kmalloc(descr->max_tokens * descr->token_size, -- GFP_KERNEL); -+ /* Create the kernel buffer */ -+ extra = kmalloc(extra_size, GFP_KERNEL); - if (extra == NULL) { - return -ENOMEM; - } -@@ -591,14 +672,11 @@ static inline int ioctl_standard_call(st - - /* If we have something to return to the user */ - if (!ret && IW_IS_GET(cmd)) { --#ifdef WE_STRICT_WRITE - /* Check if there is enough buffer up there */ -- if(user_size < iwr->u.data.length) { -- printk(KERN_ERR "%s (WE) : Buffer for request %04X too small (%d<%d)\n", dev->name, cmd, user_size, iwr->u.data.length); -+ if(user_length < iwr->u.data.length) { - kfree(extra); - return -E2BIG; - } --#endif /* WE_STRICT_WRITE */ - - err = copy_to_user(iwr->u.data.pointer, extra, - iwr->u.data.length * -@@ -661,7 +739,7 @@ static inline int ioctl_private_call(str - iw_handler handler) - { - struct iwreq * iwr = (struct iwreq *) ifr; -- struct iw_priv_args * descr = NULL; -+ const struct iw_priv_args * descr = NULL; - struct iw_request_info info; - int extra_size = 0; - int i; -@@ -701,7 +779,7 @@ static inline int ioctl_private_call(str - ((extra_size + offset) <= IFNAMSIZ)) - extra_size = 0; - } else { -- /* Size of set arguments */ -+ /* Size of get arguments */ - extra_size = get_priv_size(descr->get_args); - - /* Does it fits in iwr ? */ -@@ -771,6 +849,14 @@ static inline int ioctl_private_call(str - - /* If we have something to return to the user */ - if (!ret && IW_IS_GET(cmd)) { -+ -+ /* Adjust for the actual length if it's variable, -+ * avoid leaking kernel bits outside. */ -+ if (!(descr->get_args & IW_PRIV_SIZE_FIXED)) { -+ extra_size = adjust_priv_size(descr->get_args, -+ &(iwr->u)); -+ } -+ - err = copy_to_user(iwr->u.data.pointer, extra, - extra_size); - if (err) -@@ -1043,9 +1129,25 @@ void wireless_send_event(struct net_devi - * One of the main advantage of centralising spy support here is that - * it becomes much easier to improve and extend it without having to touch - * the drivers. One example is the addition of the Spy-Threshold events. -- * Note : IW_WIRELESS_SPY is defined in iw_handler.h - */ - -+/* ---------------------------------------------------------------- */ -+/* -+ * Return the pointer to the spy data in the driver. -+ * Because this is called on the Rx path via wireless_spy_update(), -+ * we want it to be efficient... -+ */ -+static inline struct iw_spy_data * get_spydata(struct net_device *dev) -+{ -+ /* This is the new way */ -+ if(dev->wireless_data) -+ return(dev->wireless_data->spy_data); -+ -+ /* This is the old way. Doesn't work for multi-headed drivers. -+ * It will be removed in the next version of WE. */ -+ return (dev->priv + dev->wireless_handlers->spy_offset); -+} -+ - /*------------------------------------------------------------------*/ - /* - * Standard Wireless Handler : set Spy List -@@ -1055,16 +1157,26 @@ int iw_handler_set_spy(struct net_device - union iwreq_data * wrqu, - char * extra) - { --#ifdef IW_WIRELESS_SPY -- struct iw_spy_data * spydata = (dev->priv + -- dev->wireless_handlers->spy_offset); -+ struct iw_spy_data * spydata = get_spydata(dev); - struct sockaddr * address = (struct sockaddr *) extra; - -+ /* Make sure driver is not buggy or using the old API */ -+ if(!spydata) -+ return -EOPNOTSUPP; -+ - /* Disable spy collection while we copy the addresses. -- * As we don't disable interrupts, we need to do this to avoid races. -- * As we are the only writer, this is good enough. */ -+ * While we copy addresses, any call to wireless_spy_update() -+ * will NOP. This is OK, as anyway the addresses are changing. */ - spydata->spy_number = 0; - -+ /* We want to operate without locking, because wireless_spy_update() -+ * most likely will happen in the interrupt handler, and therefore -+ * have its own locking constraints and needs performance. -+ * The rtnl_lock() make sure we don't race with the other iw_handlers. -+ * This make sure wireless_spy_update() "see" that the spy list -+ * is temporarily disabled. */ -+ wmb(); -+ - /* Are there are addresses to copy? */ - if(wrqu->data.length > 0) { - int i; -@@ -1090,13 +1202,14 @@ int iw_handler_set_spy(struct net_device - spydata->spy_address[i][5]); - #endif /* WE_SPY_DEBUG */ - } -+ -+ /* Make sure above is updated before re-enabling */ -+ wmb(); -+ - /* Enable addresses */ - spydata->spy_number = wrqu->data.length; - - return 0; --#else /* IW_WIRELESS_SPY */ -- return -EOPNOTSUPP; --#endif /* IW_WIRELESS_SPY */ - } - - /*------------------------------------------------------------------*/ -@@ -1108,12 +1221,14 @@ int iw_handler_get_spy(struct net_device - union iwreq_data * wrqu, - char * extra) - { --#ifdef IW_WIRELESS_SPY -- struct iw_spy_data * spydata = (dev->priv + -- dev->wireless_handlers->spy_offset); -+ struct iw_spy_data * spydata = get_spydata(dev); - struct sockaddr * address = (struct sockaddr *) extra; - int i; - -+ /* Make sure driver is not buggy or using the old API */ -+ if(!spydata) -+ return -EOPNOTSUPP; -+ - wrqu->data.length = spydata->spy_number; - - /* Copy addresses. */ -@@ -1130,9 +1245,6 @@ int iw_handler_get_spy(struct net_device - for(i = 0; i < spydata->spy_number; i++) - spydata->spy_stat[i].updated = 0; - return 0; --#else /* IW_WIRELESS_SPY */ -- return -EOPNOTSUPP; --#endif /* IW_WIRELESS_SPY */ - } - - /*------------------------------------------------------------------*/ -@@ -1144,11 +1256,13 @@ int iw_handler_set_thrspy(struct net_dev - union iwreq_data * wrqu, - char * extra) - { --#ifdef IW_WIRELESS_THRSPY -- struct iw_spy_data * spydata = (dev->priv + -- dev->wireless_handlers->spy_offset); -+ struct iw_spy_data * spydata = get_spydata(dev); - struct iw_thrspy * threshold = (struct iw_thrspy *) extra; - -+ /* Make sure driver is not buggy or using the old API */ -+ if(!spydata) -+ return -EOPNOTSUPP; -+ - /* Just do it */ - memcpy(&(spydata->spy_thr_low), &(threshold->low), - 2 * sizeof(struct iw_quality)); -@@ -1161,9 +1275,6 @@ int iw_handler_set_thrspy(struct net_dev - #endif /* WE_SPY_DEBUG */ - - return 0; --#else /* IW_WIRELESS_THRSPY */ -- return -EOPNOTSUPP; --#endif /* IW_WIRELESS_THRSPY */ - } - - /*------------------------------------------------------------------*/ -@@ -1175,22 +1286,20 @@ int iw_handler_get_thrspy(struct net_dev - union iwreq_data * wrqu, - char * extra) - { --#ifdef IW_WIRELESS_THRSPY -- struct iw_spy_data * spydata = (dev->priv + -- dev->wireless_handlers->spy_offset); -+ struct iw_spy_data * spydata = get_spydata(dev); - struct iw_thrspy * threshold = (struct iw_thrspy *) extra; - -+ /* Make sure driver is not buggy or using the old API */ -+ if(!spydata) -+ return -EOPNOTSUPP; -+ - /* Just do it */ - memcpy(&(threshold->low), &(spydata->spy_thr_low), - 2 * sizeof(struct iw_quality)); - - return 0; --#else /* IW_WIRELESS_THRSPY */ -- return -EOPNOTSUPP; --#endif /* IW_WIRELESS_THRSPY */ - } - --#ifdef IW_WIRELESS_THRSPY - /*------------------------------------------------------------------*/ - /* - * Prepare and send a Spy Threshold event -@@ -1228,7 +1337,6 @@ static void iw_send_thrspy_event(struct - /* Send event to user space */ - wireless_send_event(dev, SIOCGIWTHRSPY, &wrqu, (char *) &threshold); - } --#endif /* IW_WIRELESS_THRSPY */ - - /* ---------------------------------------------------------------- */ - /* -@@ -1241,12 +1349,14 @@ void wireless_spy_update(struct net_devi - unsigned char * address, - struct iw_quality * wstats) - { --#ifdef IW_WIRELESS_SPY -- struct iw_spy_data * spydata = (dev->priv + -- dev->wireless_handlers->spy_offset); -+ struct iw_spy_data * spydata = get_spydata(dev); - int i; - int match = -1; - -+ /* Make sure driver is not buggy or using the old API */ -+ if(!spydata) -+ return; -+ - #ifdef WE_SPY_DEBUG - printk(KERN_DEBUG "wireless_spy_update() : offset %ld, spydata %p, address %02X:%02X:%02X:%02X:%02X:%02X\n", dev->wireless_handlers->spy_offset, spydata, address[0], address[1], address[2], address[3], address[4], address[5]); - #endif /* WE_SPY_DEBUG */ -@@ -1258,7 +1368,7 @@ void wireless_spy_update(struct net_devi - sizeof(struct iw_quality)); - match = i; - } --#ifdef IW_WIRELESS_THRSPY -+ - /* Generate an event if we cross the spy threshold. - * To avoid event storms, we have a simple hysteresis : we generate - * event only when we go under the low threshold or above the -@@ -1278,6 +1388,4 @@ void wireless_spy_update(struct net_devi - } - } - } --#endif /* IW_WIRELESS_THRSPY */ --#endif /* IW_WIRELESS_SPY */ - } |