openzaurus-sa: upgrade wireless extension API to V18
authorMichael Lauer <mickey@vanille-media.de>
Sun, 22 Jan 2006 22:25:42 +0000 (22:25 +0000)
committerOpenEmbedded Project <openembedded-devel@lists.openembedded.org>
Sun, 22 Jan 2006 22:25:42 +0000 (22:25 +0000)
packages/linux/files/iw240_we18-5.diff [new file with mode: 0644]
packages/linux/files/iw249_we16-6.diff [new file with mode: 0644]
packages/linux/openzaurus-sa_2.4.18-rmk7-pxa3-embedix20030509.bb

diff --git a/packages/linux/files/iw240_we18-5.diff b/packages/linux/files/iw240_we18-5.diff
new file mode 100644 (file)
index 0000000..f659875
--- /dev/null
@@ -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 (file)
index 0000000..0a5aaab
--- /dev/null
@@ -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 */
index 2ef84e1..0c3ca93 100644 (file)
@@ -6,7 +6,7 @@ KV = "2.4.18"
 RMKV = "7"
 PXAV = "3"
 SHARPV = "20030509"
-PR = "r22"
+PR = "r23"
 FILESDIR = "${@os.path.dirname(bb.data.getVar('FILE',d,1))}/openzaurus-sa-${KV}-rmk${RMKV}-pxa${PXAV}-embedix${SHARPV}"
 
 SRC_URI = "http://www.openzaurus.org/mirror/linux-sl5500-${SHARPV}-rom3_10.tar.bz2 \
@@ -18,6 +18,9 @@ SRC_URI = "http://www.openzaurus.org/mirror/linux-sl5500-${SHARPV}-rom3_10.tar.b
            file://iw_handlers.w13-5.diff;patch=1 \
            file://iw_handlers.w14-5.diff;patch=1 \
            file://iw240_we15-6.diff;patch=1 \
+           file://iw249_we16-6.diff;patch=1 \
+           file://iw249_we17-13.diff;patch=1 \
+           file://iw240_we18-5.diff;patch=1 \
            file://idecs.patch;patch=1 \
            file://logo.patch;patch=1 \
            file://initsh.patch;patch=1 \
@@ -25,13 +28,11 @@ SRC_URI = "http://www.openzaurus.org/mirror/linux-sl5500-${SHARPV}-rom3_10.tar.b
            file://mkdep.patch;patch=1 \
            file://disable-pcmcia-probe.patch;patch=1 \
            file://linux-2.4.18-list_move.patch;patch=1 \
-          http://www.openswan.org/download/old/openswan-2.2.0-kernel-2.4-klips.patch.gz;patch=1 \
-          file://1764-1.patch;patch=1 \
+           http://www.openswan.org/download/old/openswan-2.2.0-kernel-2.4-klips.patch.gz;patch=1 \
+           file://1764-1.patch;patch=1 \
            file://module_licence.patch;patch=1 \
-          http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/iw249_we16-6.diff;patch=1 \
-          http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/iw249_we17-13.diff;patch=1 \
-          file://ir240_sys_max_tx-2.diff;patch=1 \
-          file://ir241_qos_param-2.diff;patch=1 \
+           file://ir240_sys_max_tx-2.diff;patch=1 \
+           file://ir241_qos_param-2.diff;patch=1 \
            file://defconfig-${MACHINE} \
           "