]> pilppa.org Git - familiar-h63xx-build.git/blob - org.handhelds.familiar/packages/linux/files/iw249_we16-6.diff
OE tree imported from monotone branch org.openembedded.oz354fam083 at revision 8b12e3...
[familiar-h63xx-build.git] / org.handhelds.familiar / packages / linux / files / iw249_we16-6.diff
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
4 @@ -1,7 +1,7 @@
5  /*
6   * This file define a set of standard wireless extensions
7   *
8 - * Version :   15      12.7.02
9 + * Version :   16      2.4.03
10   *
11   * Authors :   Jean Tourrilhes - HPL - <jt@hpl.hp.com>
12   * Copyright (c) 1997-2002 Jean Tourrilhes, All Rights Reserved.
13 @@ -69,6 +69,8 @@
14  
15  /***************************** INCLUDES *****************************/
16  
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... */
22 @@ -80,7 +82,7 @@
23   * (there is some stuff that will be added in the future...)
24   * I just plan to increment with each new version.
25   */
26 -#define WIRELESS_EXT   15
27 +#define WIRELESS_EXT   16
28  
29  /*
30   * Changes :
31 @@ -163,6 +165,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
35 + *
36 + * V15 to V16
37 + * ----------
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
45   */
46  
47  /**************************** CONSTANTS ****************************/
48 @@ -196,9 +208,11 @@
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). */
51  
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 */
58  
59  /* Access Point manipulation */
60  #define SIOCSIWAP      0x8B14          /* set access point MAC addresses */
61 @@ -294,7 +308,7 @@
62  #define IW_PRIV_TYPE_FLOAT     0x5000  /* struct iw_freq */
63  #define IW_PRIV_TYPE_ADDR      0x6000  /* struct sockaddr */
64  
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 */
67  
68  #define IW_PRIV_SIZE_MASK      0x07FF  /* Max number of those args */
69  
70 @@ -306,13 +320,13 @@
71  /* ----------------------- OTHER CONSTANTS ----------------------- */
72  
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... */
79  
80  /* Maximum bit rates in the range struct */
81 -#define IW_MAX_BITRATES                8
82 +#define IW_MAX_BITRATES                32
83  
84  /* Maximum tx powers in the range struct */
85  #define IW_MAX_TXPOWER         8
86 @@ -320,8 +334,7 @@
87   * a few of them in the struct iw_range. */
88  
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 */
92 +#define IW_MAX_SPY             8
93  
94  /* Maximum of address that you may get in the
95     list of access points in range */
96 @@ -354,7 +367,8 @@
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 */
103  
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 */
108  };
109  
110 +/*
111 + *     Quality range (for spy threshold)
112 + */
113 +struct iw_thrspy
114 +{
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 */
119 +};
120 +
121  /* ------------------------ WIRELESS STATS ------------------------ */
122  /*
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 */
126  
127         struct sockaddr ap_addr;        /* Access point address */
128 -       struct sockaddr addr;           /* Destination address (hw) */
129 +       struct sockaddr addr;           /* Destination address (hw/mac) */
130  
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 */
136  
137 -       /* Frequency */
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 */
146 +       __s32           old_freq[6];
147  
148         /* signal level threshold range */
149         __s32   sensitivity;
150  
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 */
167  
168         /* Rates */
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 */
176  
177         /* Transmit power */
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 */
182  
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...
194 -        */
195 +       /* Frequency */
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 */
201  };
202  
203  /*
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
207 @@ -1,7 +1,7 @@
208  /*
209   * This file define the new driver API for Wireless Extensions
210   *
211 - * Version :   4       21.6.02
212 + * Version :   5       4.12.02
213   *
214   * Authors :   Jean Tourrilhes - HPL - <jt@hpl.hp.com>
215   * Copyright (c) 2001-2002 Jean Tourrilhes, All Rights Reserved.
216 @@ -206,7 +206,7 @@
217   * will be needed...
218   * I just plan to increment with each new version.
219   */
220 -#define IW_HANDLER_VERSION     4
221 +#define IW_HANDLER_VERSION     5
222  
223  /*
224   * Changes :
225 @@ -220,10 +220,18 @@
226   * V3 to V4
227   * --------
228   *     - Reshuffle IW_HEADER_TYPE_XXX to map IW_PRIV_TYPE_XXX changes
229 + *
230 + * V4 to V5
231 + * --------
232 + *     - Add new spy support : struct iw_spy_data & prototypes
233   */
234  
235  /**************************** CONSTANTS ****************************/
236  
237 +/* Enable enhanced spy support. Disable to reduce footprint */
238 +#define IW_WIRELESS_SPY
239 +#define IW_WIRELESS_THRSPY
240 +
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;
247  
248 +       /* Driver enhanced spy support */
249 +       long                    spy_offset;     /* Spy data offset */
250 +
251         /* In the long term, get_wireless_stats will move from
252          * 'struct net_device' to here, to minimise bloat. */
253  };
254 @@ -350,6 +361,33 @@ struct iw_ioctl_description
255  
256  /* Need to think of short header translation table. Later. */
257  
258 +/* --------------------- ENHANCED SPY SUPPORT --------------------- */
259 +/*
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.
264 + */
265 +
266 +/*
267 + * Instance specific spy data, i.e. addresses spied and quality for them.
268 + */
269 +struct iw_spy_data
270 +{
271 +#ifdef IW_WIRELESS_SPY
272 +       /* --- Standard spy support --- */
273 +       int                     spy_number;
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 */
283 +};
284 +
285  /**************************** PROTOTYPES ****************************/
286  /*
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... */
291  
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,
296 +                             char *                    extra);
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,
301 +                             char *                    extra);
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,
306 +                                char *                 extra);
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,
311 +                                char *                 extra);
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);
316 +
317  /************************* INLINE FUNTIONS *************************/
318  /*
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
323 @@ -2,7 +2,7 @@
324   * This file implement the Wireless Extensions APIs.
325   *
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.
329   *
330   * (As all part of the Linux kernel, this file is GPL)
331   */
332 @@ -43,6 +43,11 @@
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)
336 + *
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
341   */
342  
343  /***************************** INCLUDES *****************************/
344 @@ -52,6 +57,7 @@
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 */
349  
350  #include <linux/wireless.h>            /* Pretty obvious */
351  #include <net/iw_handler.h>            /* New driver API */
352 @@ -65,6 +71,7 @@
353  /* Debuging stuff */
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 */
357  
358  /* Options */
359  #define WE_EVENT_NETLINK       /* Propagate events using rtnetlink */
360 @@ -72,7 +79,7 @@
361  
362  /************************* GLOBAL VARIABLES *************************/
363  /*
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...
367   */
368  /*
369 @@ -115,11 +122,11 @@ static const struct iw_ioctl_description
370         /* SIOCSIWSPY */
371         { IW_HEADER_TYPE_POINT, 0, sizeof(struct sockaddr), 0, IW_MAX_SPY, 0},
372         /* SIOCGIWSPY */
373 -       { IW_HEADER_TYPE_POINT, 0, (sizeof(struct sockaddr) + sizeof(struct iw_quality)), 0, IW_MAX_GET_SPY, 0},
374 -       /* -- hole -- */
375 -       { IW_HEADER_TYPE_NULL, 0, 0, 0, 0, 0},
376 -       /* -- hole -- */
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},
383         /* SIOCSIWAP */
384         { IW_HEADER_TYPE_ADDR, 0, 0, 0, 0, 0},
385         /* SIOCGIWAP */
386 @@ -377,9 +384,9 @@ int dev_get_wireless_info(char * buffer,
387         struct net_device *     dev;
388  
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"
392 -                       );
393 +                      "Inter-| sta-|   Quality        |   Discarded packets               | Missed | WE\n"
394 +                      " face | tus | link level noise |  nwid  crypt   frag  retry   misc | beacon | %d\n",
395 +                      WIRELESS_EXT);
396         
397         pos += size;
398         len += size;
399 @@ -1024,3 +1031,252 @@ void wireless_send_event(struct net_devi
400  
401         return;         /* Always success, I guess ;-) */
402  }
403 +
404 +/********************** ENHANCED IWSPY SUPPORT **********************/
405 +/*
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
410 + * private part.
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
415 + */
416 +
417 +/*------------------------------------------------------------------*/
418 +/*
419 + * Standard Wireless Handler : set Spy List
420 + */
421 +int iw_handler_set_spy(struct net_device *     dev,
422 +                      struct iw_request_info * info,
423 +                      union iwreq_data *       wrqu,
424 +                      char *                   extra)
425 +{
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;
430 +
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;
435 +
436 +       /* Are there are addresses to copy? */
437 +       if(wrqu->data.length > 0) {
438 +               int i;
439 +
440 +               /* Copy addresses */
441 +               for(i = 0; i < wrqu->data.length; i++)
442 +                       memcpy(spydata->spy_address[i], address[i].sa_data,
443 +                              ETH_ALEN);
444 +               /* Reset stats */
445 +               memset(spydata->spy_stat, 0,
446 +                      sizeof(struct iw_quality) * IW_MAX_SPY);
447 +
448 +#ifdef WE_SPY_DEBUG
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++)
451 +                       printk(KERN_DEBUG
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 */
460 +       }
461 +       /* Enable addresses */
462 +       spydata->spy_number = wrqu->data.length;
463 +
464 +       return 0;
465 +#else /* IW_WIRELESS_SPY */
466 +       return -EOPNOTSUPP;
467 +#endif /* IW_WIRELESS_SPY */
468 +}
469 +
470 +/*------------------------------------------------------------------*/
471 +/*
472 + * Standard Wireless Handler : get Spy List
473 + */
474 +int iw_handler_get_spy(struct net_device *     dev,
475 +                      struct iw_request_info * info,
476 +                      union iwreq_data *       wrqu,
477 +                      char *                   extra)
478 +{
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;
483 +       int                     i;
484 +
485 +       wrqu->data.length = spydata->spy_number;
486 +
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;
491 +       }
492 +       /* Copy stats to the user buffer (just after). */
493 +       if(spydata->spy_number > 0)
494 +               memcpy(extra  + (sizeof(struct sockaddr) *spydata->spy_number),
495 +                      spydata->spy_stat,
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;
500 +       return 0;
501 +#else /* IW_WIRELESS_SPY */
502 +       return -EOPNOTSUPP;
503 +#endif /* IW_WIRELESS_SPY */
504 +}
505 +
506 +/*------------------------------------------------------------------*/
507 +/*
508 + * Standard Wireless Handler : set spy threshold
509 + */
510 +int iw_handler_set_thrspy(struct net_device *  dev,
511 +                         struct iw_request_info *info,
512 +                         union iwreq_data *    wrqu,
513 +                         char *                extra)
514 +{
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;
519 +
520 +       /* Just do it */
521 +       memcpy(&(spydata->spy_thr_low), &(threshold->low),
522 +              2 * sizeof(struct iw_quality));
523 +
524 +       /* Clear flag */
525 +       memset(spydata->spy_thr_under, '\0', sizeof(spydata->spy_thr_under));
526 +
527 +#ifdef WE_SPY_DEBUG
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 */
530 +
531 +       return 0;
532 +#else /* IW_WIRELESS_THRSPY */
533 +       return -EOPNOTSUPP;
534 +#endif /* IW_WIRELESS_THRSPY */
535 +}
536 +
537 +/*------------------------------------------------------------------*/
538 +/*
539 + * Standard Wireless Handler : get spy threshold
540 + */
541 +int iw_handler_get_thrspy(struct net_device *  dev,
542 +                         struct iw_request_info *info,
543 +                         union iwreq_data *    wrqu,
544 +                         char *                extra)
545 +{
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;
550 +
551 +       /* Just do it */
552 +       memcpy(&(threshold->low), &(spydata->spy_thr_low),
553 +              2 * sizeof(struct iw_quality));
554 +
555 +       return 0;
556 +#else /* IW_WIRELESS_THRSPY */
557 +       return -EOPNOTSUPP;
558 +#endif /* IW_WIRELESS_THRSPY */
559 +}
560 +
561 +#ifdef IW_WIRELESS_THRSPY
562 +/*------------------------------------------------------------------*/
563 +/*
564 + * Prepare and send a Spy Threshold event
565 + */
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)
570 +{
571 +       union iwreq_data        wrqu;
572 +       struct iw_thrspy        threshold;
573 +
574 +       /* Init */
575 +       wrqu.data.length = 1;
576 +       wrqu.data.flags = 0;
577 +       /* Copy address */
578 +       memcpy(threshold.addr.sa_data, address, ETH_ALEN);
579 +       threshold.addr.sa_family = ARPHRD_ETHER;
580 +       /* Copy stats */
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));
585 +
586 +#ifdef WE_SPY_DEBUG
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 */
595 +
596 +       /* Send event to user space */
597 +       wireless_send_event(dev, SIOCGIWTHRSPY, &wrqu, (char *) &threshold);
598 +}
599 +#endif /* IW_WIRELESS_THRSPY */
600 +
601 +/* ---------------------------------------------------------------- */
602 +/*
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...
607 + */
608 +void wireless_spy_update(struct net_device *   dev,
609 +                        unsigned char *        address,
610 +                        struct iw_quality *    wstats)
611 +{
612 +#ifdef IW_WIRELESS_SPY
613 +       struct iw_spy_data *    spydata = (dev->priv +
614 +                                          dev->wireless_handlers->spy_offset);
615 +       int                     i;
616 +       int                     match = -1;
617 +
618 +#ifdef WE_SPY_DEBUG
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 */
621 +
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));
627 +                       match = i;
628 +               }
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. */
634 +       if(match >= 0) {
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,
639 +                                                    address, wstats);
640 +                       }
641 +               } else {
642 +                       if(wstats->level < spydata->spy_thr_low.level) {
643 +                               spydata->spy_thr_under[match] = 1;
644 +                               iw_send_thrspy_event(dev, spydata,
645 +                                                    address, wstats);
646 +                       }
647 +               }
648 +       }
649 +#endif /* IW_WIRELESS_THRSPY */
650 +#endif /* IW_WIRELESS_SPY */
651 +}
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);
657  
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 */
669  
670  #endif  /* CONFIG_NET */