diff options
author | Michael Lauer <mickey@vanille-media.de> | 2006-01-22 22:25:42 +0000 |
---|---|---|
committer | OpenEmbedded Project <openembedded-devel@lists.openembedded.org> | 2006-01-22 22:25:42 +0000 |
commit | 9315156b42184f415934d6db0d9ac6dc3f23d139 (patch) | |
tree | 7690b088f28c46ad0934e999afe349f2ac4587cd /packages/linux/files | |
parent | 7349a5c048a4247a9b2c1bcccb0522472047a640 (diff) |
openzaurus-sa: upgrade wireless extension API to V18
Diffstat (limited to 'packages/linux/files')
-rw-r--r-- | packages/linux/files/iw240_we18-5.diff | 421 | ||||
-rw-r--r-- | packages/linux/files/iw249_we16-6.diff | 670 |
2 files changed, 1091 insertions, 0 deletions
diff --git a/packages/linux/files/iw240_we18-5.diff b/packages/linux/files/iw240_we18-5.diff new file mode 100644 index 0000000000..f65987588d --- /dev/null +++ b/packages/linux/files/iw240_we18-5.diff @@ -0,0 +1,421 @@ +diff -u -p linux/include/linux/wireless.we17.h linux/include/linux/wireless.h +--- linux/include/linux/wireless.we17.h 2005-05-20 11:25:49.000000000 -0700 ++++ linux/include/linux/wireless.h 2005-05-20 11:29:05.000000000 -0700 +@@ -1,10 +1,10 @@ + /* + * This file define a set of standard wireless extensions + * +- * Version : 17 21.6.04 ++ * Version : 18 12.3.05 + * + * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com> +- * Copyright (c) 1997-2004 Jean Tourrilhes, All Rights Reserved. ++ * Copyright (c) 1997-2005 Jean Tourrilhes, All Rights Reserved. + */ + + #ifndef _LINUX_WIRELESS_H +@@ -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 17 ++#define WIRELESS_EXT 18 + + /* + * Changes : +@@ -182,6 +182,21 @@ + * - 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 ****************************/ +@@ -256,6 +271,30 @@ + #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 32 ioctl are wireless device private, for 16 commands. +@@ -297,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 + +@@ -432,12 +499,94 @@ + #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. */ +@@ -546,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) +@@ -725,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 */ + }; + + /* +diff -u -p linux/net/core/wireless.we17.c linux/net/core/wireless.c +--- linux/net/core/wireless.we17.c 2005-05-20 11:26:11.000000000 -0700 ++++ linux/net/core/wireless.c 2005-05-20 15:37:09.000000000 -0700 +@@ -2,7 +2,7 @@ + * This file implement the Wireless Extensions APIs. + * + * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com> +- * Copyright (c) 1997-2004 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) + */ +@@ -137,12 +137,12 @@ 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, 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, IW_DESCR_FLAG_NOMAX}, + /* SIOCSIWESSID */ +@@ -185,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)); +@@ -204,6 +223,16 @@ 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)); diff --git a/packages/linux/files/iw249_we16-6.diff b/packages/linux/files/iw249_we16-6.diff new file mode 100644 index 0000000000..0a5aaab954 --- /dev/null +++ b/packages/linux/files/iw249_we16-6.diff @@ -0,0 +1,670 @@ +diff -u -p linux/include/linux/wireless.15.h linux/include/linux/wireless.h +--- linux/include/linux/wireless.15.h 2004-11-05 14:59:33.000000000 -0800 ++++ linux/include/linux/wireless.h 2004-11-05 15:00:42.000000000 -0800 +@@ -1,7 +1,7 @@ + /* + * This file define a set of standard wireless extensions + * +- * Version : 15 12.7.02 ++ * Version : 16 2.4.03 + * + * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com> + * Copyright (c) 1997-2002 Jean Tourrilhes, All Rights Reserved. +@@ -69,6 +69,8 @@ + + /***************************** INCLUDES *****************************/ + ++/* To minimise problems in user space, I might remove those headers ++ * at some point. Jean II */ + #include <linux/types.h> /* for "caddr_t" et al */ + #include <linux/socket.h> /* for "struct sockaddr" et al */ + #include <linux/if.h> /* for IFNAMSIZ and co... */ +@@ -80,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 15 ++#define WIRELESS_EXT 16 + + /* + * Changes : +@@ -163,6 +165,16 @@ + * - Add IW_TXPOW_RANGE for range of Tx Powers + * - Add IWEVREGISTERED & IWEVEXPIRED events for Access Points + * - Add IW_MODE_MONITOR for passive monitor ++ * ++ * V15 to V16 ++ * ---------- ++ * - Increase the number of bitrates in iw_range to 32 (for 802.11g) ++ * - Increase the number of frequencies in iw_range to 32 (for 802.11b+a) ++ * - Reshuffle struct iw_range for increases, add filler ++ * - Increase IW_MAX_AP to 64 for driver returning a lot of addresses ++ * - 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 + */ + + /**************************** CONSTANTS ****************************/ +@@ -196,9 +208,11 @@ + /* SIOCGIWSTATS is strictly used between user space and the kernel, and + * is never passed to the driver (i.e. the driver will never see it). */ + +-/* Mobile IP support (statistics per MAC address) */ ++/* Spy support (statistics per MAC address - used for Mobile IP support) */ + #define SIOCSIWSPY 0x8B10 /* set spy addresses */ + #define SIOCGIWSPY 0x8B11 /* get spy info (quality of link) */ ++#define SIOCSIWTHRSPY 0x8B12 /* set spy threshold (spy event) */ ++#define SIOCGIWTHRSPY 0x8B13 /* get spy threshold */ + + /* Access Point manipulation */ + #define SIOCSIWAP 0x8B14 /* set access point MAC addresses */ +@@ -294,7 +308,7 @@ + #define IW_PRIV_TYPE_FLOAT 0x5000 /* struct iw_freq */ + #define IW_PRIV_TYPE_ADDR 0x6000 /* struct sockaddr */ + +-#define IW_PRIV_SIZE_FIXED 0x0800 /* Variable or fixed nuber of args */ ++#define IW_PRIV_SIZE_FIXED 0x0800 /* Variable or fixed number of args */ + + #define IW_PRIV_SIZE_MASK 0x07FF /* Max number of those args */ + +@@ -306,13 +320,13 @@ + /* ----------------------- OTHER CONSTANTS ----------------------- */ + + /* Maximum frequencies in the range struct */ +-#define IW_MAX_FREQUENCIES 16 ++#define IW_MAX_FREQUENCIES 32 + /* Note : if you have something like 80 frequencies, + * don't increase this constant and don't fill the frequency list. + * The user will be able to set by channel anyway... */ + + /* Maximum bit rates in the range struct */ +-#define IW_MAX_BITRATES 8 ++#define IW_MAX_BITRATES 32 + + /* Maximum tx powers in the range struct */ + #define IW_MAX_TXPOWER 8 +@@ -320,8 +334,7 @@ + * a few of them in the struct iw_range. */ + + /* Maximum of address that you may set with SPY */ +-#define IW_MAX_SPY 8 /* set */ +-#define IW_MAX_GET_SPY 64 /* get */ ++#define IW_MAX_SPY 8 + + /* Maximum of address that you may get in the + list of access points in range */ +@@ -354,7 +367,8 @@ + #define IW_ENCODE_ENABLED 0x0000 /* Encoding enabled */ + #define IW_ENCODE_RESTRICTED 0x4000 /* Refuse non-encoded packets */ + #define IW_ENCODE_OPEN 0x2000 /* Accept non-encoded packets */ +-#define IW_ENCODE_NOKEY 0x0800 /* Key is write only, so not present */ ++#define IW_ENCODE_NOKEY 0x0800 /* Key is write only, so not present */ ++#define IW_ENCODE_TEMP 0x0400 /* Temporary key */ + + /* Power management flags available (along with the value, if any) */ + #define IW_POWER_ON 0x0000 /* No details... */ +@@ -482,6 +496,17 @@ struct iw_missed + __u32 beacon; /* Missed beacons/superframe */ + }; + ++/* ++ * Quality range (for spy threshold) ++ */ ++struct iw_thrspy ++{ ++ struct sockaddr addr; /* Source address (hw/mac) */ ++ struct iw_quality qual; /* Quality of the link */ ++ struct iw_quality low; /* Low threshold */ ++ struct iw_quality high; /* High threshold */ ++}; ++ + /* ------------------------ WIRELESS STATS ------------------------ */ + /* + * Wireless statistics (used for /proc/net/wireless) +@@ -534,7 +559,7 @@ union iwreq_data + struct iw_quality qual; /* Quality part of statistics */ + + struct sockaddr ap_addr; /* Access point address */ +- struct sockaddr addr; /* Destination address (hw) */ ++ struct sockaddr addr; /* Destination address (hw/mac) */ + + struct iw_param param; /* Other small parameters */ + struct iw_point data; /* Other large parameters */ +@@ -582,17 +607,31 @@ struct iw_range + __u32 min_nwid; /* Minimal NWID we are able to set */ + __u32 max_nwid; /* Maximal NWID we are able to set */ + +- /* Frequency */ +- __u16 num_channels; /* Number of channels [0; num - 1] */ +- __u8 num_frequency; /* Number of entry in the list */ +- struct iw_freq freq[IW_MAX_FREQUENCIES]; /* list */ +- /* Note : this frequency list doesn't need to fit channel numbers */ ++ /* 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]; + + /* signal level threshold range */ + __s32 sensitivity; + + /* Quality of link & SNR stuff */ ++ /* Quality range (link, level, noise) ++ * If the quality is absolute, it will be in the range [0 ; max_qual], ++ * if the quality is dBm, it will be in the range [max_qual ; 0]. ++ * Don't forget that we use 8 bit arithmetics... */ + struct iw_quality max_qual; /* Quality of the link */ ++ /* This should contain the average/typical values of the quality ++ * indicator. This should be the threshold between a "good" and ++ * a "bad" link (example : monitor going from green to orange). ++ * Currently, user space apps like quality monitors don't have any ++ * way to calibrate the measurement. With this, they can split ++ * the range between 0 and max_qual in different quality level ++ * (using a geometric subdivision centered on the average). ++ * I expect that people doing the user space apps will feedback ++ * us on which value we need to put in each driver... */ ++ struct iw_quality avg_qual; /* Quality of the link */ + + /* Rates */ + __u8 num_bitrates; /* Number of entries in the list */ +@@ -619,6 +658,8 @@ struct iw_range + __u16 encoding_size[IW_MAX_ENCODING_SIZES]; /* Different token sizes */ + __u8 num_encoding_sizes; /* Number of entry in the list */ + __u8 max_encoding_tokens; /* Max number of tokens */ ++ /* For drivers that need a "login/passwd" form */ ++ __u8 encoding_login_index; /* token index for login token */ + + /* Transmit power */ + __u16 txpower_capa; /* What options are supported */ +@@ -638,18 +679,12 @@ struct iw_range + __s32 min_r_time; /* Minimal retry lifetime */ + __s32 max_r_time; /* Maximal retry lifetime */ + +- /* Average quality of link & SNR */ +- struct iw_quality avg_qual; /* Quality of the link */ +- /* This should contain the average/typical values of the quality +- * indicator. This should be the threshold between a "good" and +- * a "bad" link (example : monitor going from green to orange). +- * Currently, user space apps like quality monitors don't have any +- * way to calibrate the measurement. With this, they can split +- * the range between 0 and max_qual in different quality level +- * (using a geometric subdivision centered on the average). +- * I expect that people doing the user space apps will feedback +- * us on which value we need to put in each driver... +- */ ++ /* Frequency */ ++ __u16 num_channels; /* Number of channels [0; num - 1] */ ++ __u8 num_frequency; /* Number of entry in the list */ ++ 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 */ + }; + + /* +diff -u -p linux/include/net/iw_handler.15.h linux/include/net/iw_handler.h +--- linux/include/net/iw_handler.15.h 2004-11-05 14:59:47.000000000 -0800 ++++ linux/include/net/iw_handler.h 2004-11-05 15:00:42.000000000 -0800 +@@ -1,7 +1,7 @@ + /* + * This file define the new driver API for Wireless Extensions + * +- * Version : 4 21.6.02 ++ * Version : 5 4.12.02 + * + * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com> + * Copyright (c) 2001-2002 Jean Tourrilhes, All Rights Reserved. +@@ -206,7 +206,7 @@ + * will be needed... + * I just plan to increment with each new version. + */ +-#define IW_HANDLER_VERSION 4 ++#define IW_HANDLER_VERSION 5 + + /* + * Changes : +@@ -220,10 +220,18 @@ + * V3 to V4 + * -------- + * - Reshuffle IW_HEADER_TYPE_XXX to map IW_PRIV_TYPE_XXX changes ++ * ++ * V4 to V5 ++ * -------- ++ * - Add new spy support : struct iw_spy_data & prototypes + */ + + /**************************** CONSTANTS ****************************/ + ++/* Enable enhanced spy support. Disable to reduce footprint */ ++#define IW_WIRELESS_SPY ++#define IW_WIRELESS_THRSPY ++ + /* Special error message for the driver to indicate that we + * should do a commit after return from the iw_handler */ + #define EIWCOMMIT EINPROGRESS +@@ -315,6 +323,9 @@ struct iw_handler_def + * We will automatically export that to user space... */ + struct iw_priv_args * private_args; + ++ /* Driver enhanced spy support */ ++ long spy_offset; /* Spy data offset */ ++ + /* In the long term, get_wireless_stats will move from + * 'struct net_device' to here, to minimise bloat. */ + }; +@@ -350,6 +361,33 @@ struct iw_ioctl_description + + /* Need to think of short header translation table. Later. */ + ++/* --------------------- ENHANCED SPY SUPPORT --------------------- */ ++/* ++ * In the old days, the driver was handling spy support all by itself. ++ * Now, the driver can delegate this task to Wireless Extensions. ++ * It needs to include this struct in its private part and use the ++ * standard spy iw_handler. ++ */ ++ ++/* ++ * Instance specific spy data, i.e. addresses spied and quality for them. ++ */ ++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 */ ++}; ++ + /**************************** PROTOTYPES ****************************/ + /* + * Functions part of the Wireless Extensions (defined in net/core/wireless.c). +@@ -376,6 +414,31 @@ extern void wireless_send_event(struct n + /* We may need a function to send a stream of events to user space. + * More on that later... */ + ++/* Standard handler for SIOCSIWSPY */ ++extern int iw_handler_set_spy(struct net_device * dev, ++ struct iw_request_info * info, ++ union iwreq_data * wrqu, ++ char * extra); ++/* Standard handler for SIOCGIWSPY */ ++extern int iw_handler_get_spy(struct net_device * dev, ++ struct iw_request_info * info, ++ union iwreq_data * wrqu, ++ char * extra); ++/* Standard handler for SIOCSIWTHRSPY */ ++extern int iw_handler_set_thrspy(struct net_device * dev, ++ struct iw_request_info *info, ++ union iwreq_data * wrqu, ++ char * extra); ++/* Standard handler for SIOCGIWTHRSPY */ ++extern int iw_handler_get_thrspy(struct net_device * dev, ++ struct iw_request_info *info, ++ union iwreq_data * wrqu, ++ char * extra); ++/* Driver call to update spy records */ ++extern void wireless_spy_update(struct net_device * dev, ++ unsigned char * address, ++ struct iw_quality * wstats); ++ + /************************* INLINE FUNTIONS *************************/ + /* + * Function that are so simple that it's more efficient inlining them +diff -u -p linux/net/core/wireless.15.c linux/net/core/wireless.c +--- linux/net/core/wireless.15.c 2004-11-05 15:00:11.000000000 -0800 ++++ linux/net/core/wireless.c 2004-11-05 15:00:42.000000000 -0800 +@@ -2,7 +2,7 @@ + * This file implement the Wireless Extensions APIs. + * + * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com> +- * Copyright (c) 1997-2002 Jean Tourrilhes, All Rights Reserved. ++ * Copyright (c) 1997-2003 Jean Tourrilhes, All Rights Reserved. + * + * (As all part of the Linux kernel, this file is GPL) + */ +@@ -43,6 +43,11 @@ + * o Turn on WE_STRICT_WRITE by default + kernel warning + * o Fix WE_STRICT_WRITE in ioctl_export_private() (32 => iw_num) + * o Fix off-by-one in test (extra_size <= IFNAMSIZ) ++ * ++ * v6 - 9.01.03 - Jean II ++ * 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 + */ + + /***************************** INCLUDES *****************************/ +@@ -52,6 +57,7 @@ + #include <linux/types.h> /* off_t */ + #include <linux/netdevice.h> /* struct ifreq, dev_get_by_name() */ + #include <linux/rtnetlink.h> /* rtnetlink stuff */ ++#include <linux/if_arp.h> /* ARPHRD_ETHER */ + + #include <linux/wireless.h> /* Pretty obvious */ + #include <net/iw_handler.h> /* New driver API */ +@@ -65,6 +71,7 @@ + /* Debuging stuff */ + #undef WE_IOCTL_DEBUG /* Debug IOCTL API */ + #undef WE_EVENT_DEBUG /* Debug Event dispatcher */ ++#undef WE_SPY_DEBUG /* Debug enhanced spy support */ + + /* Options */ + #define WE_EVENT_NETLINK /* Propagate events using rtnetlink */ +@@ -72,7 +79,7 @@ + + /************************* GLOBAL VARIABLES *************************/ + /* +- * You should not use global variables, because or re-entrancy. ++ * You should not use global variables, because of re-entrancy. + * On our case, it's only const, so it's OK... + */ + /* +@@ -115,11 +122,11 @@ static const struct iw_ioctl_description + /* SIOCSIWSPY */ + { IW_HEADER_TYPE_POINT, 0, sizeof(struct sockaddr), 0, IW_MAX_SPY, 0}, + /* SIOCGIWSPY */ +- { IW_HEADER_TYPE_POINT, 0, (sizeof(struct sockaddr) + sizeof(struct iw_quality)), 0, IW_MAX_GET_SPY, 0}, +- /* -- hole -- */ +- { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0}, +- /* -- hole -- */ +- { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0}, ++ { IW_HEADER_TYPE_POINT, 0, (sizeof(struct sockaddr) + sizeof(struct iw_quality)), 0, IW_MAX_SPY, 0}, ++ /* SIOCSIWTHRSPY */ ++ { IW_HEADER_TYPE_POINT, 0, sizeof(struct iw_thrspy), 1, 1, 0}, ++ /* SIOCGIWTHRSPY */ ++ { IW_HEADER_TYPE_POINT, 0, sizeof(struct iw_thrspy), 1, 1, 0}, + /* SIOCSIWAP */ + { IW_HEADER_TYPE_ADDR, 0, 0, 0, 0, 0}, + /* SIOCGIWAP */ +@@ -377,9 +384,9 @@ int dev_get_wireless_info(char * buffer, + struct net_device * dev; + + size = sprintf(buffer, +- "Inter-| sta-| Quality | Discarded packets | Missed\n" +- " face | tus | link level noise | nwid crypt frag retry misc | beacon\n" +- ); ++ "Inter-| sta-| Quality | Discarded packets | Missed | WE\n" ++ " face | tus | link level noise | nwid crypt frag retry misc | beacon | %d\n", ++ WIRELESS_EXT); + + pos += size; + len += size; +@@ -1024,3 +1031,252 @@ void wireless_send_event(struct net_devi + + return; /* Always success, I guess ;-) */ + } ++ ++/********************** ENHANCED IWSPY SUPPORT **********************/ ++/* ++ * In the old days, the driver was handling spy support all by itself. ++ * Now, the driver can delegate this task to Wireless Extensions. ++ * It needs to use those standard spy iw_handler in struct iw_handler_def, ++ * push data to us via XXX and include struct iw_spy_data in its ++ * private part. ++ * 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 ++ */ ++ ++/*------------------------------------------------------------------*/ ++/* ++ * Standard Wireless Handler : set Spy List ++ */ ++int iw_handler_set_spy(struct net_device * dev, ++ struct iw_request_info * info, ++ union iwreq_data * wrqu, ++ char * extra) ++{ ++#ifdef IW_WIRELESS_SPY ++ struct iw_spy_data * spydata = (dev->priv + ++ dev->wireless_handlers->spy_offset); ++ struct sockaddr * address = (struct sockaddr *) extra; ++ ++ /* 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. */ ++ spydata->spy_number = 0; ++ ++ /* Are there are addresses to copy? */ ++ if(wrqu->data.length > 0) { ++ int i; ++ ++ /* Copy addresses */ ++ for(i = 0; i < wrqu->data.length; i++) ++ memcpy(spydata->spy_address[i], address[i].sa_data, ++ ETH_ALEN); ++ /* Reset stats */ ++ memset(spydata->spy_stat, 0, ++ sizeof(struct iw_quality) * IW_MAX_SPY); ++ ++#ifdef WE_SPY_DEBUG ++ printk(KERN_DEBUG "iw_handler_set_spy() : offset %ld, spydata %p, num %d\n", dev->wireless_handlers->spy_offset, spydata, wrqu->data.length); ++ for (i = 0; i < wrqu->data.length; i++) ++ printk(KERN_DEBUG ++ "%02X:%02X:%02X:%02X:%02X:%02X \n", ++ spydata->spy_address[i][0], ++ spydata->spy_address[i][1], ++ spydata->spy_address[i][2], ++ spydata->spy_address[i][3], ++ spydata->spy_address[i][4], ++ spydata->spy_address[i][5]); ++#endif /* WE_SPY_DEBUG */ ++ } ++ /* Enable addresses */ ++ spydata->spy_number = wrqu->data.length; ++ ++ return 0; ++#else /* IW_WIRELESS_SPY */ ++ return -EOPNOTSUPP; ++#endif /* IW_WIRELESS_SPY */ ++} ++ ++/*------------------------------------------------------------------*/ ++/* ++ * Standard Wireless Handler : get Spy List ++ */ ++int iw_handler_get_spy(struct net_device * dev, ++ struct iw_request_info * info, ++ union iwreq_data * wrqu, ++ char * extra) ++{ ++#ifdef IW_WIRELESS_SPY ++ struct iw_spy_data * spydata = (dev->priv + ++ dev->wireless_handlers->spy_offset); ++ struct sockaddr * address = (struct sockaddr *) extra; ++ int i; ++ ++ wrqu->data.length = spydata->spy_number; ++ ++ /* Copy addresses. */ ++ for(i = 0; i < spydata->spy_number; i++) { ++ memcpy(address[i].sa_data, spydata->spy_address[i], ETH_ALEN); ++ address[i].sa_family = AF_UNIX; ++ } ++ /* Copy stats to the user buffer (just after). */ ++ if(spydata->spy_number > 0) ++ memcpy(extra + (sizeof(struct sockaddr) *spydata->spy_number), ++ spydata->spy_stat, ++ sizeof(struct iw_quality) * spydata->spy_number); ++ /* Reset updated flags. */ ++ 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 */ ++} ++ ++/*------------------------------------------------------------------*/ ++/* ++ * Standard Wireless Handler : set spy threshold ++ */ ++int iw_handler_set_thrspy(struct net_device * dev, ++ struct iw_request_info *info, ++ union iwreq_data * wrqu, ++ char * extra) ++{ ++#ifdef IW_WIRELESS_THRSPY ++ struct iw_spy_data * spydata = (dev->priv + ++ dev->wireless_handlers->spy_offset); ++ struct iw_thrspy * threshold = (struct iw_thrspy *) extra; ++ ++ /* Just do it */ ++ memcpy(&(spydata->spy_thr_low), &(threshold->low), ++ 2 * sizeof(struct iw_quality)); ++ ++ /* Clear flag */ ++ memset(spydata->spy_thr_under, '\0', sizeof(spydata->spy_thr_under)); ++ ++#ifdef WE_SPY_DEBUG ++ printk(KERN_DEBUG "iw_handler_set_thrspy() : low %d ; high %d\n", spydata->spy_thr_low.level, spydata->spy_thr_high.level); ++#endif /* WE_SPY_DEBUG */ ++ ++ return 0; ++#else /* IW_WIRELESS_THRSPY */ ++ return -EOPNOTSUPP; ++#endif /* IW_WIRELESS_THRSPY */ ++} ++ ++/*------------------------------------------------------------------*/ ++/* ++ * Standard Wireless Handler : get spy threshold ++ */ ++int iw_handler_get_thrspy(struct net_device * dev, ++ struct iw_request_info *info, ++ union iwreq_data * wrqu, ++ char * extra) ++{ ++#ifdef IW_WIRELESS_THRSPY ++ struct iw_spy_data * spydata = (dev->priv + ++ dev->wireless_handlers->spy_offset); ++ struct iw_thrspy * threshold = (struct iw_thrspy *) extra; ++ ++ /* 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 ++ */ ++static void iw_send_thrspy_event(struct net_device * dev, ++ struct iw_spy_data * spydata, ++ unsigned char * address, ++ struct iw_quality * wstats) ++{ ++ union iwreq_data wrqu; ++ struct iw_thrspy threshold; ++ ++ /* Init */ ++ wrqu.data.length = 1; ++ wrqu.data.flags = 0; ++ /* Copy address */ ++ memcpy(threshold.addr.sa_data, address, ETH_ALEN); ++ threshold.addr.sa_family = ARPHRD_ETHER; ++ /* Copy stats */ ++ memcpy(&(threshold.qual), wstats, sizeof(struct iw_quality)); ++ /* Copy also thresholds */ ++ memcpy(&(threshold.low), &(spydata->spy_thr_low), ++ 2 * sizeof(struct iw_quality)); ++ ++#ifdef WE_SPY_DEBUG ++ printk(KERN_DEBUG "iw_send_thrspy_event() : address %02X:%02X:%02X:%02X:%02X:%02X, level %d, up = %d\n", ++ threshold.addr.sa_data[0], ++ threshold.addr.sa_data[1], ++ threshold.addr.sa_data[2], ++ threshold.addr.sa_data[3], ++ threshold.addr.sa_data[4], ++ threshold.addr.sa_data[5], threshold.qual.level); ++#endif /* WE_SPY_DEBUG */ ++ ++ /* Send event to user space */ ++ wireless_send_event(dev, SIOCGIWTHRSPY, &wrqu, (char *) &threshold); ++} ++#endif /* IW_WIRELESS_THRSPY */ ++ ++/* ---------------------------------------------------------------- */ ++/* ++ * Call for the driver to update the spy data. ++ * For now, the spy data is a simple array. As the size of the array is ++ * small, this is good enough. If we wanted to support larger number of ++ * spy addresses, we should use something more efficient... ++ */ ++void wireless_spy_update(struct net_device * dev, ++ unsigned char * address, ++ struct iw_quality * wstats) ++{ ++#ifdef IW_WIRELESS_SPY ++ struct iw_spy_data * spydata = (dev->priv + ++ dev->wireless_handlers->spy_offset); ++ int i; ++ int match = -1; ++ ++#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 */ ++ ++ /* Update all records that match */ ++ for(i = 0; i < spydata->spy_number; i++) ++ if(!memcmp(address, spydata->spy_address[i], ETH_ALEN)) { ++ memcpy(&(spydata->spy_stat[i]), wstats, ++ 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 ++ * high threshold. */ ++ if(match >= 0) { ++ if(spydata->spy_thr_under[match]) { ++ if(wstats->level > spydata->spy_thr_high.level) { ++ spydata->spy_thr_under[match] = 0; ++ iw_send_thrspy_event(dev, spydata, ++ address, wstats); ++ } ++ } else { ++ if(wstats->level < spydata->spy_thr_low.level) { ++ spydata->spy_thr_under[match] = 1; ++ iw_send_thrspy_event(dev, spydata, ++ address, wstats); ++ } ++ } ++ } ++#endif /* IW_WIRELESS_THRSPY */ ++#endif /* IW_WIRELESS_SPY */ ++} +diff -u -p linux/net/netsyms.15.c linux/net/netsyms.c +--- linux/net/netsyms.15.c 2004-11-05 15:00:25.000000000 -0800 ++++ linux/net/netsyms.c 2004-11-05 15:01:38.000000000 -0800 +@@ -589,9 +589,13 @@ EXPORT_SYMBOL(net_call_rx_atomic); + EXPORT_SYMBOL(softnet_data); + + #if defined(CONFIG_NET_RADIO) || defined(CONFIG_NET_PCMCIA_RADIO) +-/* Don't include the whole header mess for a single function */ +-extern void wireless_send_event(struct net_device *dev, unsigned int cmd, union iwreq_data *wrqu, char *extra); ++#include <net/iw_handler.h> + EXPORT_SYMBOL(wireless_send_event); ++EXPORT_SYMBOL(iw_handler_set_spy); ++EXPORT_SYMBOL(iw_handler_get_spy); ++EXPORT_SYMBOL(iw_handler_set_thrspy); ++EXPORT_SYMBOL(iw_handler_get_thrspy); ++EXPORT_SYMBOL(wireless_spy_update); + #endif /* CONFIG_NET_RADIO || CONFIG_NET_PCMCIA_RADIO */ + + #endif /* CONFIG_NET */ |