diff options
Diffstat (limited to 'recipes/linux/files/iw249_we16-6.diff')
-rw-r--r-- | recipes/linux/files/iw249_we16-6.diff | 670 |
1 files changed, 670 insertions, 0 deletions
diff --git a/recipes/linux/files/iw249_we16-6.diff b/recipes/linux/files/iw249_we16-6.diff new file mode 100644 index 0000000000..0a5aaab954 --- /dev/null +++ b/recipes/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 */ |