1 diff -u -p linux/include/linux/wireless.15.h linux/include/linux/wireless.h
2 --- linux/include/linux/wireless.15.h 2004-11-05 14:59:33.000000000 -0800
3 +++ linux/include/linux/wireless.h 2004-11-05 15:00:42.000000000 -0800
6 * This file define a set of standard wireless extensions
8 - * Version : 15 12.7.02
9 + * Version : 16 2.4.03
11 * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
12 * Copyright (c) 1997-2002 Jean Tourrilhes, All Rights Reserved.
15 /***************************** INCLUDES *****************************/
17 +/* To minimise problems in user space, I might remove those headers
18 + * at some point. Jean II */
19 #include <linux/types.h> /* for "caddr_t" et al */
20 #include <linux/socket.h> /* for "struct sockaddr" et al */
21 #include <linux/if.h> /* for IFNAMSIZ and co... */
23 * (there is some stuff that will be added in the future...)
24 * I just plan to increment with each new version.
26 -#define WIRELESS_EXT 15
27 +#define WIRELESS_EXT 16
32 * - Add IW_TXPOW_RANGE for range of Tx Powers
33 * - Add IWEVREGISTERED & IWEVEXPIRED events for Access Points
34 * - Add IW_MODE_MONITOR for passive monitor
38 + * - Increase the number of bitrates in iw_range to 32 (for 802.11g)
39 + * - Increase the number of frequencies in iw_range to 32 (for 802.11b+a)
40 + * - Reshuffle struct iw_range for increases, add filler
41 + * - Increase IW_MAX_AP to 64 for driver returning a lot of addresses
42 + * - Remove IW_MAX_GET_SPY because conflict with enhanced spy support
43 + * - Add SIOCSIWTHRSPY/SIOCGIWTHRSPY and "struct iw_thrspy"
44 + * - Add IW_ENCODE_TEMP and iw_range->encoding_login_index
47 /**************************** CONSTANTS ****************************/
49 /* SIOCGIWSTATS is strictly used between user space and the kernel, and
50 * is never passed to the driver (i.e. the driver will never see it). */
52 -/* Mobile IP support (statistics per MAC address) */
53 +/* Spy support (statistics per MAC address - used for Mobile IP support) */
54 #define SIOCSIWSPY 0x8B10 /* set spy addresses */
55 #define SIOCGIWSPY 0x8B11 /* get spy info (quality of link) */
56 +#define SIOCSIWTHRSPY 0x8B12 /* set spy threshold (spy event) */
57 +#define SIOCGIWTHRSPY 0x8B13 /* get spy threshold */
59 /* Access Point manipulation */
60 #define SIOCSIWAP 0x8B14 /* set access point MAC addresses */
62 #define IW_PRIV_TYPE_FLOAT 0x5000 /* struct iw_freq */
63 #define IW_PRIV_TYPE_ADDR 0x6000 /* struct sockaddr */
65 -#define IW_PRIV_SIZE_FIXED 0x0800 /* Variable or fixed nuber of args */
66 +#define IW_PRIV_SIZE_FIXED 0x0800 /* Variable or fixed number of args */
68 #define IW_PRIV_SIZE_MASK 0x07FF /* Max number of those args */
71 /* ----------------------- OTHER CONSTANTS ----------------------- */
73 /* Maximum frequencies in the range struct */
74 -#define IW_MAX_FREQUENCIES 16
75 +#define IW_MAX_FREQUENCIES 32
76 /* Note : if you have something like 80 frequencies,
77 * don't increase this constant and don't fill the frequency list.
78 * The user will be able to set by channel anyway... */
80 /* Maximum bit rates in the range struct */
81 -#define IW_MAX_BITRATES 8
82 +#define IW_MAX_BITRATES 32
84 /* Maximum tx powers in the range struct */
85 #define IW_MAX_TXPOWER 8
87 * a few of them in the struct iw_range. */
89 /* Maximum of address that you may set with SPY */
90 -#define IW_MAX_SPY 8 /* set */
91 -#define IW_MAX_GET_SPY 64 /* get */
94 /* Maximum of address that you may get in the
95 list of access points in range */
97 #define IW_ENCODE_ENABLED 0x0000 /* Encoding enabled */
98 #define IW_ENCODE_RESTRICTED 0x4000 /* Refuse non-encoded packets */
99 #define IW_ENCODE_OPEN 0x2000 /* Accept non-encoded packets */
100 -#define IW_ENCODE_NOKEY 0x0800 /* Key is write only, so not present */
101 +#define IW_ENCODE_NOKEY 0x0800 /* Key is write only, so not present */
102 +#define IW_ENCODE_TEMP 0x0400 /* Temporary key */
104 /* Power management flags available (along with the value, if any) */
105 #define IW_POWER_ON 0x0000 /* No details... */
106 @@ -482,6 +496,17 @@ struct iw_missed
107 __u32 beacon; /* Missed beacons/superframe */
111 + * Quality range (for spy threshold)
115 + struct sockaddr addr; /* Source address (hw/mac) */
116 + struct iw_quality qual; /* Quality of the link */
117 + struct iw_quality low; /* Low threshold */
118 + struct iw_quality high; /* High threshold */
121 /* ------------------------ WIRELESS STATS ------------------------ */
123 * Wireless statistics (used for /proc/net/wireless)
124 @@ -534,7 +559,7 @@ union iwreq_data
125 struct iw_quality qual; /* Quality part of statistics */
127 struct sockaddr ap_addr; /* Access point address */
128 - struct sockaddr addr; /* Destination address (hw) */
129 + struct sockaddr addr; /* Destination address (hw/mac) */
131 struct iw_param param; /* Other small parameters */
132 struct iw_point data; /* Other large parameters */
133 @@ -582,17 +607,31 @@ struct iw_range
134 __u32 min_nwid; /* Minimal NWID we are able to set */
135 __u32 max_nwid; /* Maximal NWID we are able to set */
138 - __u16 num_channels; /* Number of channels [0; num - 1] */
139 - __u8 num_frequency; /* Number of entry in the list */
140 - struct iw_freq freq[IW_MAX_FREQUENCIES]; /* list */
141 - /* Note : this frequency list doesn't need to fit channel numbers */
142 + /* Old Frequency (backward compat - moved lower ) */
143 + __u16 old_num_channels;
144 + __u8 old_num_frequency;
145 + /* Filler to keep "version" at the same offset */
148 /* signal level threshold range */
151 /* Quality of link & SNR stuff */
152 + /* Quality range (link, level, noise)
153 + * If the quality is absolute, it will be in the range [0 ; max_qual],
154 + * if the quality is dBm, it will be in the range [max_qual ; 0].
155 + * Don't forget that we use 8 bit arithmetics... */
156 struct iw_quality max_qual; /* Quality of the link */
157 + /* This should contain the average/typical values of the quality
158 + * indicator. This should be the threshold between a "good" and
159 + * a "bad" link (example : monitor going from green to orange).
160 + * Currently, user space apps like quality monitors don't have any
161 + * way to calibrate the measurement. With this, they can split
162 + * the range between 0 and max_qual in different quality level
163 + * (using a geometric subdivision centered on the average).
164 + * I expect that people doing the user space apps will feedback
165 + * us on which value we need to put in each driver... */
166 + struct iw_quality avg_qual; /* Quality of the link */
169 __u8 num_bitrates; /* Number of entries in the list */
170 @@ -619,6 +658,8 @@ struct iw_range
171 __u16 encoding_size[IW_MAX_ENCODING_SIZES]; /* Different token sizes */
172 __u8 num_encoding_sizes; /* Number of entry in the list */
173 __u8 max_encoding_tokens; /* Max number of tokens */
174 + /* For drivers that need a "login/passwd" form */
175 + __u8 encoding_login_index; /* token index for login token */
178 __u16 txpower_capa; /* What options are supported */
179 @@ -638,18 +679,12 @@ struct iw_range
180 __s32 min_r_time; /* Minimal retry lifetime */
181 __s32 max_r_time; /* Maximal retry lifetime */
183 - /* Average quality of link & SNR */
184 - struct iw_quality avg_qual; /* Quality of the link */
185 - /* This should contain the average/typical values of the quality
186 - * indicator. This should be the threshold between a "good" and
187 - * a "bad" link (example : monitor going from green to orange).
188 - * Currently, user space apps like quality monitors don't have any
189 - * way to calibrate the measurement. With this, they can split
190 - * the range between 0 and max_qual in different quality level
191 - * (using a geometric subdivision centered on the average).
192 - * I expect that people doing the user space apps will feedback
193 - * us on which value we need to put in each driver...
196 + __u16 num_channels; /* Number of channels [0; num - 1] */
197 + __u8 num_frequency; /* Number of entry in the list */
198 + struct iw_freq freq[IW_MAX_FREQUENCIES]; /* list */
199 + /* Note : this frequency list doesn't need to fit channel numbers,
200 + * because each entry contain its channel index */
204 diff -u -p linux/include/net/iw_handler.15.h linux/include/net/iw_handler.h
205 --- linux/include/net/iw_handler.15.h 2004-11-05 14:59:47.000000000 -0800
206 +++ linux/include/net/iw_handler.h 2004-11-05 15:00:42.000000000 -0800
209 * This file define the new driver API for Wireless Extensions
211 - * Version : 4 21.6.02
212 + * Version : 5 4.12.02
214 * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
215 * Copyright (c) 2001-2002 Jean Tourrilhes, All Rights Reserved.
218 * I just plan to increment with each new version.
220 -#define IW_HANDLER_VERSION 4
221 +#define IW_HANDLER_VERSION 5
225 @@ -220,10 +220,18 @@
228 * - Reshuffle IW_HEADER_TYPE_XXX to map IW_PRIV_TYPE_XXX changes
232 + * - Add new spy support : struct iw_spy_data & prototypes
235 /**************************** CONSTANTS ****************************/
237 +/* Enable enhanced spy support. Disable to reduce footprint */
238 +#define IW_WIRELESS_SPY
239 +#define IW_WIRELESS_THRSPY
241 /* Special error message for the driver to indicate that we
242 * should do a commit after return from the iw_handler */
243 #define EIWCOMMIT EINPROGRESS
244 @@ -315,6 +323,9 @@ struct iw_handler_def
245 * We will automatically export that to user space... */
246 struct iw_priv_args * private_args;
248 + /* Driver enhanced spy support */
249 + long spy_offset; /* Spy data offset */
251 /* In the long term, get_wireless_stats will move from
252 * 'struct net_device' to here, to minimise bloat. */
254 @@ -350,6 +361,33 @@ struct iw_ioctl_description
256 /* Need to think of short header translation table. Later. */
258 +/* --------------------- ENHANCED SPY SUPPORT --------------------- */
260 + * In the old days, the driver was handling spy support all by itself.
261 + * Now, the driver can delegate this task to Wireless Extensions.
262 + * It needs to include this struct in its private part and use the
263 + * standard spy iw_handler.
267 + * Instance specific spy data, i.e. addresses spied and quality for them.
271 +#ifdef IW_WIRELESS_SPY
272 + /* --- Standard spy support --- */
274 + u_char spy_address[IW_MAX_SPY][ETH_ALEN];
275 + struct iw_quality spy_stat[IW_MAX_SPY];
276 +#ifdef IW_WIRELESS_THRSPY
277 + /* --- Enhanced spy support (event) */
278 + struct iw_quality spy_thr_low; /* Low threshold */
279 + struct iw_quality spy_thr_high; /* High threshold */
280 + u_char spy_thr_under[IW_MAX_SPY];
281 +#endif /* IW_WIRELESS_THRSPY */
282 +#endif /* IW_WIRELESS_SPY */
285 /**************************** PROTOTYPES ****************************/
287 * Functions part of the Wireless Extensions (defined in net/core/wireless.c).
288 @@ -376,6 +414,31 @@ extern void wireless_send_event(struct n
289 /* We may need a function to send a stream of events to user space.
290 * More on that later... */
292 +/* Standard handler for SIOCSIWSPY */
293 +extern int iw_handler_set_spy(struct net_device * dev,
294 + struct iw_request_info * info,
295 + union iwreq_data * wrqu,
297 +/* Standard handler for SIOCGIWSPY */
298 +extern int iw_handler_get_spy(struct net_device * dev,
299 + struct iw_request_info * info,
300 + union iwreq_data * wrqu,
302 +/* Standard handler for SIOCSIWTHRSPY */
303 +extern int iw_handler_set_thrspy(struct net_device * dev,
304 + struct iw_request_info *info,
305 + union iwreq_data * wrqu,
307 +/* Standard handler for SIOCGIWTHRSPY */
308 +extern int iw_handler_get_thrspy(struct net_device * dev,
309 + struct iw_request_info *info,
310 + union iwreq_data * wrqu,
312 +/* Driver call to update spy records */
313 +extern void wireless_spy_update(struct net_device * dev,
314 + unsigned char * address,
315 + struct iw_quality * wstats);
317 /************************* INLINE FUNTIONS *************************/
319 * Function that are so simple that it's more efficient inlining them
320 diff -u -p linux/net/core/wireless.15.c linux/net/core/wireless.c
321 --- linux/net/core/wireless.15.c 2004-11-05 15:00:11.000000000 -0800
322 +++ linux/net/core/wireless.c 2004-11-05 15:00:42.000000000 -0800
324 * This file implement the Wireless Extensions APIs.
326 * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com>
327 - * Copyright (c) 1997-2002 Jean Tourrilhes, All Rights Reserved.
328 + * Copyright (c) 1997-2003 Jean Tourrilhes, All Rights Reserved.
330 * (As all part of the Linux kernel, this file is GPL)
333 * o Turn on WE_STRICT_WRITE by default + kernel warning
334 * o Fix WE_STRICT_WRITE in ioctl_export_private() (32 => iw_num)
335 * o Fix off-by-one in test (extra_size <= IFNAMSIZ)
337 + * v6 - 9.01.03 - Jean II
338 + * o Add common spy support : iw_handler_set_spy(), wireless_spy_update()
339 + * o Add enhanced spy support : iw_handler_set_thrspy() and event.
340 + * o Add WIRELESS_EXT version display in /proc/net/wireless
343 /***************************** INCLUDES *****************************/
345 #include <linux/types.h> /* off_t */
346 #include <linux/netdevice.h> /* struct ifreq, dev_get_by_name() */
347 #include <linux/rtnetlink.h> /* rtnetlink stuff */
348 +#include <linux/if_arp.h> /* ARPHRD_ETHER */
350 #include <linux/wireless.h> /* Pretty obvious */
351 #include <net/iw_handler.h> /* New driver API */
354 #undef WE_IOCTL_DEBUG /* Debug IOCTL API */
355 #undef WE_EVENT_DEBUG /* Debug Event dispatcher */
356 +#undef WE_SPY_DEBUG /* Debug enhanced spy support */
359 #define WE_EVENT_NETLINK /* Propagate events using rtnetlink */
362 /************************* GLOBAL VARIABLES *************************/
364 - * You should not use global variables, because or re-entrancy.
365 + * You should not use global variables, because of re-entrancy.
366 * On our case, it's only const, so it's OK...
369 @@ -115,11 +122,11 @@ static const struct iw_ioctl_description
371 { IW_HEADER_TYPE_POINT, 0, sizeof(struct sockaddr), 0, IW_MAX_SPY, 0},
373 - { IW_HEADER_TYPE_POINT, 0, (sizeof(struct sockaddr) + sizeof(struct iw_quality)), 0, IW_MAX_GET_SPY, 0},
375 - { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
377 - { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
378 + { IW_HEADER_TYPE_POINT, 0, (sizeof(struct sockaddr) + sizeof(struct iw_quality)), 0, IW_MAX_SPY, 0},
379 + /* SIOCSIWTHRSPY */
380 + { IW_HEADER_TYPE_POINT, 0, sizeof(struct iw_thrspy), 1, 1, 0},
381 + /* SIOCGIWTHRSPY */
382 + { IW_HEADER_TYPE_POINT, 0, sizeof(struct iw_thrspy), 1, 1, 0},
384 { IW_HEADER_TYPE_ADDR, 0, 0, 0, 0, 0},
386 @@ -377,9 +384,9 @@ int dev_get_wireless_info(char * buffer,
387 struct net_device * dev;
389 size = sprintf(buffer,
390 - "Inter-| sta-| Quality | Discarded packets | Missed\n"
391 - " face | tus | link level noise | nwid crypt frag retry misc | beacon\n"
393 + "Inter-| sta-| Quality | Discarded packets | Missed | WE\n"
394 + " face | tus | link level noise | nwid crypt frag retry misc | beacon | %d\n",
399 @@ -1024,3 +1031,252 @@ void wireless_send_event(struct net_devi
401 return; /* Always success, I guess ;-) */
404 +/********************** ENHANCED IWSPY SUPPORT **********************/
406 + * In the old days, the driver was handling spy support all by itself.
407 + * Now, the driver can delegate this task to Wireless Extensions.
408 + * It needs to use those standard spy iw_handler in struct iw_handler_def,
409 + * push data to us via XXX and include struct iw_spy_data in its
411 + * One of the main advantage of centralising spy support here is that
412 + * it becomes much easier to improve and extend it without having to touch
413 + * the drivers. One example is the addition of the Spy-Threshold events.
414 + * Note : IW_WIRELESS_SPY is defined in iw_handler.h
417 +/*------------------------------------------------------------------*/
419 + * Standard Wireless Handler : set Spy List
421 +int iw_handler_set_spy(struct net_device * dev,
422 + struct iw_request_info * info,
423 + union iwreq_data * wrqu,
426 +#ifdef IW_WIRELESS_SPY
427 + struct iw_spy_data * spydata = (dev->priv +
428 + dev->wireless_handlers->spy_offset);
429 + struct sockaddr * address = (struct sockaddr *) extra;
431 + /* Disable spy collection while we copy the addresses.
432 + * As we don't disable interrupts, we need to do this to avoid races.
433 + * As we are the only writer, this is good enough. */
434 + spydata->spy_number = 0;
436 + /* Are there are addresses to copy? */
437 + if(wrqu->data.length > 0) {
440 + /* Copy addresses */
441 + for(i = 0; i < wrqu->data.length; i++)
442 + memcpy(spydata->spy_address[i], address[i].sa_data,
445 + memset(spydata->spy_stat, 0,
446 + sizeof(struct iw_quality) * IW_MAX_SPY);
449 + printk(KERN_DEBUG "iw_handler_set_spy() : offset %ld, spydata %p, num %d\n", dev->wireless_handlers->spy_offset, spydata, wrqu->data.length);
450 + for (i = 0; i < wrqu->data.length; i++)
452 + "%02X:%02X:%02X:%02X:%02X:%02X \n",
453 + spydata->spy_address[i][0],
454 + spydata->spy_address[i][1],
455 + spydata->spy_address[i][2],
456 + spydata->spy_address[i][3],
457 + spydata->spy_address[i][4],
458 + spydata->spy_address[i][5]);
459 +#endif /* WE_SPY_DEBUG */
461 + /* Enable addresses */
462 + spydata->spy_number = wrqu->data.length;
465 +#else /* IW_WIRELESS_SPY */
466 + return -EOPNOTSUPP;
467 +#endif /* IW_WIRELESS_SPY */
470 +/*------------------------------------------------------------------*/
472 + * Standard Wireless Handler : get Spy List
474 +int iw_handler_get_spy(struct net_device * dev,
475 + struct iw_request_info * info,
476 + union iwreq_data * wrqu,
479 +#ifdef IW_WIRELESS_SPY
480 + struct iw_spy_data * spydata = (dev->priv +
481 + dev->wireless_handlers->spy_offset);
482 + struct sockaddr * address = (struct sockaddr *) extra;
485 + wrqu->data.length = spydata->spy_number;
487 + /* Copy addresses. */
488 + for(i = 0; i < spydata->spy_number; i++) {
489 + memcpy(address[i].sa_data, spydata->spy_address[i], ETH_ALEN);
490 + address[i].sa_family = AF_UNIX;
492 + /* Copy stats to the user buffer (just after). */
493 + if(spydata->spy_number > 0)
494 + memcpy(extra + (sizeof(struct sockaddr) *spydata->spy_number),
496 + sizeof(struct iw_quality) * spydata->spy_number);
497 + /* Reset updated flags. */
498 + for(i = 0; i < spydata->spy_number; i++)
499 + spydata->spy_stat[i].updated = 0;
501 +#else /* IW_WIRELESS_SPY */
502 + return -EOPNOTSUPP;
503 +#endif /* IW_WIRELESS_SPY */
506 +/*------------------------------------------------------------------*/
508 + * Standard Wireless Handler : set spy threshold
510 +int iw_handler_set_thrspy(struct net_device * dev,
511 + struct iw_request_info *info,
512 + union iwreq_data * wrqu,
515 +#ifdef IW_WIRELESS_THRSPY
516 + struct iw_spy_data * spydata = (dev->priv +
517 + dev->wireless_handlers->spy_offset);
518 + struct iw_thrspy * threshold = (struct iw_thrspy *) extra;
521 + memcpy(&(spydata->spy_thr_low), &(threshold->low),
522 + 2 * sizeof(struct iw_quality));
525 + memset(spydata->spy_thr_under, '\0', sizeof(spydata->spy_thr_under));
528 + printk(KERN_DEBUG "iw_handler_set_thrspy() : low %d ; high %d\n", spydata->spy_thr_low.level, spydata->spy_thr_high.level);
529 +#endif /* WE_SPY_DEBUG */
532 +#else /* IW_WIRELESS_THRSPY */
533 + return -EOPNOTSUPP;
534 +#endif /* IW_WIRELESS_THRSPY */
537 +/*------------------------------------------------------------------*/
539 + * Standard Wireless Handler : get spy threshold
541 +int iw_handler_get_thrspy(struct net_device * dev,
542 + struct iw_request_info *info,
543 + union iwreq_data * wrqu,
546 +#ifdef IW_WIRELESS_THRSPY
547 + struct iw_spy_data * spydata = (dev->priv +
548 + dev->wireless_handlers->spy_offset);
549 + struct iw_thrspy * threshold = (struct iw_thrspy *) extra;
552 + memcpy(&(threshold->low), &(spydata->spy_thr_low),
553 + 2 * sizeof(struct iw_quality));
556 +#else /* IW_WIRELESS_THRSPY */
557 + return -EOPNOTSUPP;
558 +#endif /* IW_WIRELESS_THRSPY */
561 +#ifdef IW_WIRELESS_THRSPY
562 +/*------------------------------------------------------------------*/
564 + * Prepare and send a Spy Threshold event
566 +static void iw_send_thrspy_event(struct net_device * dev,
567 + struct iw_spy_data * spydata,
568 + unsigned char * address,
569 + struct iw_quality * wstats)
571 + union iwreq_data wrqu;
572 + struct iw_thrspy threshold;
575 + wrqu.data.length = 1;
576 + wrqu.data.flags = 0;
578 + memcpy(threshold.addr.sa_data, address, ETH_ALEN);
579 + threshold.addr.sa_family = ARPHRD_ETHER;
581 + memcpy(&(threshold.qual), wstats, sizeof(struct iw_quality));
582 + /* Copy also thresholds */
583 + memcpy(&(threshold.low), &(spydata->spy_thr_low),
584 + 2 * sizeof(struct iw_quality));
587 + printk(KERN_DEBUG "iw_send_thrspy_event() : address %02X:%02X:%02X:%02X:%02X:%02X, level %d, up = %d\n",
588 + threshold.addr.sa_data[0],
589 + threshold.addr.sa_data[1],
590 + threshold.addr.sa_data[2],
591 + threshold.addr.sa_data[3],
592 + threshold.addr.sa_data[4],
593 + threshold.addr.sa_data[5], threshold.qual.level);
594 +#endif /* WE_SPY_DEBUG */
596 + /* Send event to user space */
597 + wireless_send_event(dev, SIOCGIWTHRSPY, &wrqu, (char *) &threshold);
599 +#endif /* IW_WIRELESS_THRSPY */
601 +/* ---------------------------------------------------------------- */
603 + * Call for the driver to update the spy data.
604 + * For now, the spy data is a simple array. As the size of the array is
605 + * small, this is good enough. If we wanted to support larger number of
606 + * spy addresses, we should use something more efficient...
608 +void wireless_spy_update(struct net_device * dev,
609 + unsigned char * address,
610 + struct iw_quality * wstats)
612 +#ifdef IW_WIRELESS_SPY
613 + struct iw_spy_data * spydata = (dev->priv +
614 + dev->wireless_handlers->spy_offset);
619 + 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]);
620 +#endif /* WE_SPY_DEBUG */
622 + /* Update all records that match */
623 + for(i = 0; i < spydata->spy_number; i++)
624 + if(!memcmp(address, spydata->spy_address[i], ETH_ALEN)) {
625 + memcpy(&(spydata->spy_stat[i]), wstats,
626 + sizeof(struct iw_quality));
629 +#ifdef IW_WIRELESS_THRSPY
630 + /* Generate an event if we cross the spy threshold.
631 + * To avoid event storms, we have a simple hysteresis : we generate
632 + * event only when we go under the low threshold or above the
633 + * high threshold. */
635 + if(spydata->spy_thr_under[match]) {
636 + if(wstats->level > spydata->spy_thr_high.level) {
637 + spydata->spy_thr_under[match] = 0;
638 + iw_send_thrspy_event(dev, spydata,
642 + if(wstats->level < spydata->spy_thr_low.level) {
643 + spydata->spy_thr_under[match] = 1;
644 + iw_send_thrspy_event(dev, spydata,
649 +#endif /* IW_WIRELESS_THRSPY */
650 +#endif /* IW_WIRELESS_SPY */
652 diff -u -p linux/net/netsyms.15.c linux/net/netsyms.c
653 --- linux/net/netsyms.15.c 2004-11-05 15:00:25.000000000 -0800
654 +++ linux/net/netsyms.c 2004-11-05 15:01:38.000000000 -0800
655 @@ -589,9 +589,13 @@ EXPORT_SYMBOL(net_call_rx_atomic);
656 EXPORT_SYMBOL(softnet_data);
658 #if defined(CONFIG_NET_RADIO) || defined(CONFIG_NET_PCMCIA_RADIO)
659 -/* Don't include the whole header mess for a single function */
660 -extern void wireless_send_event(struct net_device *dev, unsigned int cmd, union iwreq_data *wrqu, char *extra);
661 +#include <net/iw_handler.h>
662 EXPORT_SYMBOL(wireless_send_event);
663 +EXPORT_SYMBOL(iw_handler_set_spy);
664 +EXPORT_SYMBOL(iw_handler_get_spy);
665 +EXPORT_SYMBOL(iw_handler_set_thrspy);
666 +EXPORT_SYMBOL(iw_handler_get_thrspy);
667 +EXPORT_SYMBOL(wireless_spy_update);
668 #endif /* CONFIG_NET_RADIO || CONFIG_NET_PCMCIA_RADIO */
670 #endif /* CONFIG_NET */