diff options
author | John W. Linville <linville@tuxdriver.com> | 2006-09-08 16:04:05 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2006-09-25 16:52:14 -0400 |
commit | baef186519c69b11cf7e48c26e75feb1e6173baa (patch) | |
tree | a4a1ac70808443bec2f924e48b8a705050325cdf | |
parent | 7c250413e5b7c3dfae89354725b70c76d7621395 (diff) |
[PATCH] WE-21 support (core API)
This is version 21 of the Wireless Extensions. Changelog :
o finishes migrating the ESSID API (remove the +1)
o netdev->get_wireless_stats is no more
o long/short retry
This is a redacted version of a patch originally submitted by Jean
Tourrilhes. I removed most of the additions, in order to minimize
future support requirements for nl80211 (or other WE successor).
CC: Jean Tourrilhes <jt@hpl.hp.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
-rw-r--r-- | include/linux/netdevice.h | 1 | ||||
-rw-r--r-- | include/linux/wireless.h | 24 | ||||
-rw-r--r-- | net/core/net-sysfs.c | 5 | ||||
-rw-r--r-- | net/core/wireless.c | 67 |
4 files changed, 62 insertions, 35 deletions
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 43289127b458..ac4f50213bc3 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -334,7 +334,6 @@ struct net_device | |||
334 | 334 | ||
335 | 335 | ||
336 | struct net_device_stats* (*get_stats)(struct net_device *dev); | 336 | struct net_device_stats* (*get_stats)(struct net_device *dev); |
337 | struct iw_statistics* (*get_wireless_stats)(struct net_device *dev); | ||
338 | 337 | ||
339 | /* List of functions to handle Wireless Extensions (instead of ioctl). | 338 | /* List of functions to handle Wireless Extensions (instead of ioctl). |
340 | * See <net/iw_handler.h> for details. Jean II */ | 339 | * See <net/iw_handler.h> for details. Jean II */ |
diff --git a/include/linux/wireless.h b/include/linux/wireless.h index 13588564b42b..a50a0130fd9e 100644 --- a/include/linux/wireless.h +++ b/include/linux/wireless.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * This file define a set of standard wireless extensions | 2 | * This file define a set of standard wireless extensions |
3 | * | 3 | * |
4 | * Version : 20 17.2.06 | 4 | * Version : 21 14.3.06 |
5 | * | 5 | * |
6 | * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com> | 6 | * Authors : Jean Tourrilhes - HPL - <jt@hpl.hp.com> |
7 | * Copyright (c) 1997-2006 Jean Tourrilhes, All Rights Reserved. | 7 | * Copyright (c) 1997-2006 Jean Tourrilhes, All Rights Reserved. |
@@ -69,9 +69,14 @@ | |||
69 | 69 | ||
70 | /***************************** INCLUDES *****************************/ | 70 | /***************************** INCLUDES *****************************/ |
71 | 71 | ||
72 | /* This header is used in user-space, therefore need to be sanitised | ||
73 | * for that purpose. Those includes are usually not compatible with glibc. | ||
74 | * To know which includes to use in user-space, check iwlib.h. */ | ||
75 | #ifdef __KERNEL__ | ||
72 | #include <linux/types.h> /* for "caddr_t" et al */ | 76 | #include <linux/types.h> /* for "caddr_t" et al */ |
73 | #include <linux/socket.h> /* for "struct sockaddr" et al */ | 77 | #include <linux/socket.h> /* for "struct sockaddr" et al */ |
74 | #include <linux/if.h> /* for IFNAMSIZ and co... */ | 78 | #include <linux/if.h> /* for IFNAMSIZ and co... */ |
79 | #endif /* __KERNEL__ */ | ||
75 | 80 | ||
76 | /***************************** VERSION *****************************/ | 81 | /***************************** VERSION *****************************/ |
77 | /* | 82 | /* |
@@ -80,7 +85,7 @@ | |||
80 | * (there is some stuff that will be added in the future...) | 85 | * (there is some stuff that will be added in the future...) |
81 | * I just plan to increment with each new version. | 86 | * I just plan to increment with each new version. |
82 | */ | 87 | */ |
83 | #define WIRELESS_EXT 20 | 88 | #define WIRELESS_EXT 21 |
84 | 89 | ||
85 | /* | 90 | /* |
86 | * Changes : | 91 | * Changes : |
@@ -208,6 +213,14 @@ | |||
208 | * V19 to V20 | 213 | * V19 to V20 |
209 | * ---------- | 214 | * ---------- |
210 | * - RtNetlink requests support (SET/GET) | 215 | * - RtNetlink requests support (SET/GET) |
216 | * | ||
217 | * V20 to V21 | ||
218 | * ---------- | ||
219 | * - Remove (struct net_device *)->get_wireless_stats() | ||
220 | * - Change length in ESSID and NICK to strlen() instead of strlen()+1 | ||
221 | * - Add IW_RETRY_SHORT/IW_RETRY_LONG retry modifiers | ||
222 | * - Power/Retry relative values no longer * 100000 | ||
223 | * - Add explicit flag to tell stats are in 802.11k RCPI : IW_QUAL_RCPI | ||
211 | */ | 224 | */ |
212 | 225 | ||
213 | /**************************** CONSTANTS ****************************/ | 226 | /**************************** CONSTANTS ****************************/ |
@@ -448,6 +461,7 @@ | |||
448 | #define IW_QUAL_QUAL_INVALID 0x10 /* Driver doesn't provide value */ | 461 | #define IW_QUAL_QUAL_INVALID 0x10 /* Driver doesn't provide value */ |
449 | #define IW_QUAL_LEVEL_INVALID 0x20 | 462 | #define IW_QUAL_LEVEL_INVALID 0x20 |
450 | #define IW_QUAL_NOISE_INVALID 0x40 | 463 | #define IW_QUAL_NOISE_INVALID 0x40 |
464 | #define IW_QUAL_RCPI 0x80 /* Level + Noise are 802.11k RCPI */ | ||
451 | #define IW_QUAL_ALL_INVALID 0x70 | 465 | #define IW_QUAL_ALL_INVALID 0x70 |
452 | 466 | ||
453 | /* Frequency flags */ | 467 | /* Frequency flags */ |
@@ -500,10 +514,12 @@ | |||
500 | #define IW_RETRY_TYPE 0xF000 /* Type of parameter */ | 514 | #define IW_RETRY_TYPE 0xF000 /* Type of parameter */ |
501 | #define IW_RETRY_LIMIT 0x1000 /* Maximum number of retries*/ | 515 | #define IW_RETRY_LIMIT 0x1000 /* Maximum number of retries*/ |
502 | #define IW_RETRY_LIFETIME 0x2000 /* Maximum duration of retries in us */ | 516 | #define IW_RETRY_LIFETIME 0x2000 /* Maximum duration of retries in us */ |
503 | #define IW_RETRY_MODIFIER 0x000F /* Modify a parameter */ | 517 | #define IW_RETRY_MODIFIER 0x00FF /* Modify a parameter */ |
504 | #define IW_RETRY_MIN 0x0001 /* Value is a minimum */ | 518 | #define IW_RETRY_MIN 0x0001 /* Value is a minimum */ |
505 | #define IW_RETRY_MAX 0x0002 /* Value is a maximum */ | 519 | #define IW_RETRY_MAX 0x0002 /* Value is a maximum */ |
506 | #define IW_RETRY_RELATIVE 0x0004 /* Value is not in seconds/ms/us */ | 520 | #define IW_RETRY_RELATIVE 0x0004 /* Value is not in seconds/ms/us */ |
521 | #define IW_RETRY_SHORT 0x0010 /* Value is for short packets */ | ||
522 | #define IW_RETRY_LONG 0x0020 /* Value is for long packets */ | ||
507 | 523 | ||
508 | /* Scanning request flags */ | 524 | /* Scanning request flags */ |
509 | #define IW_SCAN_DEFAULT 0x0000 /* Default scan of the driver */ | 525 | #define IW_SCAN_DEFAULT 0x0000 /* Default scan of the driver */ |
@@ -1017,7 +1033,7 @@ struct iw_range | |||
1017 | /* Note : this frequency list doesn't need to fit channel numbers, | 1033 | /* Note : this frequency list doesn't need to fit channel numbers, |
1018 | * because each entry contain its channel index */ | 1034 | * because each entry contain its channel index */ |
1019 | 1035 | ||
1020 | __u32 enc_capa; /* IW_ENC_CAPA_* bit field */ | 1036 | __u32 enc_capa; /* IW_ENC_CAPA_* bit field */ |
1021 | }; | 1037 | }; |
1022 | 1038 | ||
1023 | /* | 1039 | /* |
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index 13472762b18b..f47f319bb7dc 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c | |||
@@ -344,8 +344,6 @@ static ssize_t wireless_show(struct class_device *cd, char *buf, | |||
344 | if(dev->wireless_handlers && | 344 | if(dev->wireless_handlers && |
345 | dev->wireless_handlers->get_wireless_stats) | 345 | dev->wireless_handlers->get_wireless_stats) |
346 | iw = dev->wireless_handlers->get_wireless_stats(dev); | 346 | iw = dev->wireless_handlers->get_wireless_stats(dev); |
347 | else if (dev->get_wireless_stats) | ||
348 | iw = dev->get_wireless_stats(dev); | ||
349 | if (iw != NULL) | 347 | if (iw != NULL) |
350 | ret = (*format)(iw, buf); | 348 | ret = (*format)(iw, buf); |
351 | } | 349 | } |
@@ -465,8 +463,7 @@ int netdev_register_sysfs(struct net_device *net) | |||
465 | *groups++ = &netstat_group; | 463 | *groups++ = &netstat_group; |
466 | 464 | ||
467 | #ifdef WIRELESS_EXT | 465 | #ifdef WIRELESS_EXT |
468 | if (net->get_wireless_stats | 466 | if (net->wireless_handlers && net->wireless_handlers->get_wireless_stats) |
469 | || (net->wireless_handlers && net->wireless_handlers->get_wireless_stats)) | ||
470 | *groups++ = &wireless_group; | 467 | *groups++ = &wireless_group; |
471 | #endif | 468 | #endif |
472 | 469 | ||
diff --git a/net/core/wireless.c b/net/core/wireless.c index 3168fca312f7..ffff0da46c6e 100644 --- a/net/core/wireless.c +++ b/net/core/wireless.c | |||
@@ -68,6 +68,14 @@ | |||
68 | * | 68 | * |
69 | * v8 - 17.02.06 - Jean II | 69 | * v8 - 17.02.06 - Jean II |
70 | * o RtNetlink requests support (SET/GET) | 70 | * o RtNetlink requests support (SET/GET) |
71 | * | ||
72 | * v8b - 03.08.06 - Herbert Xu | ||
73 | * o Fix Wireless Event locking issues. | ||
74 | * | ||
75 | * v9 - 14.3.06 - Jean II | ||
76 | * o Change length in ESSID and NICK to strlen() instead of strlen()+1 | ||
77 | * o Make standard_ioctl_num and standard_event_num unsigned | ||
78 | * o Remove (struct net_device *)->get_wireless_stats() | ||
71 | */ | 79 | */ |
72 | 80 | ||
73 | /***************************** INCLUDES *****************************/ | 81 | /***************************** INCLUDES *****************************/ |
@@ -234,24 +242,24 @@ static const struct iw_ioctl_description standard_ioctl[] = { | |||
234 | [SIOCSIWESSID - SIOCIWFIRST] = { | 242 | [SIOCSIWESSID - SIOCIWFIRST] = { |
235 | .header_type = IW_HEADER_TYPE_POINT, | 243 | .header_type = IW_HEADER_TYPE_POINT, |
236 | .token_size = 1, | 244 | .token_size = 1, |
237 | .max_tokens = IW_ESSID_MAX_SIZE + 1, | 245 | .max_tokens = IW_ESSID_MAX_SIZE, |
238 | .flags = IW_DESCR_FLAG_EVENT, | 246 | .flags = IW_DESCR_FLAG_EVENT, |
239 | }, | 247 | }, |
240 | [SIOCGIWESSID - SIOCIWFIRST] = { | 248 | [SIOCGIWESSID - SIOCIWFIRST] = { |
241 | .header_type = IW_HEADER_TYPE_POINT, | 249 | .header_type = IW_HEADER_TYPE_POINT, |
242 | .token_size = 1, | 250 | .token_size = 1, |
243 | .max_tokens = IW_ESSID_MAX_SIZE + 1, | 251 | .max_tokens = IW_ESSID_MAX_SIZE, |
244 | .flags = IW_DESCR_FLAG_DUMP, | 252 | .flags = IW_DESCR_FLAG_DUMP, |
245 | }, | 253 | }, |
246 | [SIOCSIWNICKN - SIOCIWFIRST] = { | 254 | [SIOCSIWNICKN - SIOCIWFIRST] = { |
247 | .header_type = IW_HEADER_TYPE_POINT, | 255 | .header_type = IW_HEADER_TYPE_POINT, |
248 | .token_size = 1, | 256 | .token_size = 1, |
249 | .max_tokens = IW_ESSID_MAX_SIZE + 1, | 257 | .max_tokens = IW_ESSID_MAX_SIZE, |
250 | }, | 258 | }, |
251 | [SIOCGIWNICKN - SIOCIWFIRST] = { | 259 | [SIOCGIWNICKN - SIOCIWFIRST] = { |
252 | .header_type = IW_HEADER_TYPE_POINT, | 260 | .header_type = IW_HEADER_TYPE_POINT, |
253 | .token_size = 1, | 261 | .token_size = 1, |
254 | .max_tokens = IW_ESSID_MAX_SIZE + 1, | 262 | .max_tokens = IW_ESSID_MAX_SIZE, |
255 | }, | 263 | }, |
256 | [SIOCSIWRATE - SIOCIWFIRST] = { | 264 | [SIOCSIWRATE - SIOCIWFIRST] = { |
257 | .header_type = IW_HEADER_TYPE_PARAM, | 265 | .header_type = IW_HEADER_TYPE_PARAM, |
@@ -338,8 +346,8 @@ static const struct iw_ioctl_description standard_ioctl[] = { | |||
338 | .max_tokens = sizeof(struct iw_pmksa), | 346 | .max_tokens = sizeof(struct iw_pmksa), |
339 | }, | 347 | }, |
340 | }; | 348 | }; |
341 | static const int standard_ioctl_num = (sizeof(standard_ioctl) / | 349 | static const unsigned standard_ioctl_num = (sizeof(standard_ioctl) / |
342 | sizeof(struct iw_ioctl_description)); | 350 | sizeof(struct iw_ioctl_description)); |
343 | 351 | ||
344 | /* | 352 | /* |
345 | * Meta-data about all the additional standard Wireless Extension events | 353 | * Meta-data about all the additional standard Wireless Extension events |
@@ -389,8 +397,8 @@ static const struct iw_ioctl_description standard_event[] = { | |||
389 | .max_tokens = sizeof(struct iw_pmkid_cand), | 397 | .max_tokens = sizeof(struct iw_pmkid_cand), |
390 | }, | 398 | }, |
391 | }; | 399 | }; |
392 | static const int standard_event_num = (sizeof(standard_event) / | 400 | static const unsigned standard_event_num = (sizeof(standard_event) / |
393 | sizeof(struct iw_ioctl_description)); | 401 | sizeof(struct iw_ioctl_description)); |
394 | 402 | ||
395 | /* Size (in bytes) of the various private data types */ | 403 | /* Size (in bytes) of the various private data types */ |
396 | static const char iw_priv_type_size[] = { | 404 | static const char iw_priv_type_size[] = { |
@@ -465,17 +473,6 @@ static inline struct iw_statistics *get_wireless_stats(struct net_device *dev) | |||
465 | (dev->wireless_handlers->get_wireless_stats != NULL)) | 473 | (dev->wireless_handlers->get_wireless_stats != NULL)) |
466 | return dev->wireless_handlers->get_wireless_stats(dev); | 474 | return dev->wireless_handlers->get_wireless_stats(dev); |
467 | 475 | ||
468 | /* Old location, field to be removed in next WE */ | ||
469 | if(dev->get_wireless_stats) { | ||
470 | static int printed_message; | ||
471 | |||
472 | if (!printed_message++) | ||
473 | printk(KERN_DEBUG "%s (WE) : Driver using old /proc/net/wireless support, please fix driver !\n", | ||
474 | dev->name); | ||
475 | |||
476 | return dev->get_wireless_stats(dev); | ||
477 | } | ||
478 | |||
479 | /* Not found */ | 476 | /* Not found */ |
480 | return (struct iw_statistics *) NULL; | 477 | return (struct iw_statistics *) NULL; |
481 | } | 478 | } |
@@ -1843,8 +1840,33 @@ int wireless_rtnetlink_set(struct net_device * dev, | |||
1843 | */ | 1840 | */ |
1844 | 1841 | ||
1845 | #ifdef WE_EVENT_RTNETLINK | 1842 | #ifdef WE_EVENT_RTNETLINK |
1843 | /* ---------------------------------------------------------------- */ | ||
1844 | /* | ||
1845 | * Locking... | ||
1846 | * ---------- | ||
1847 | * | ||
1848 | * Thanks to Herbert Xu <herbert@gondor.apana.org.au> for fixing | ||
1849 | * the locking issue in here and implementing this code ! | ||
1850 | * | ||
1851 | * The issue : wireless_send_event() is often called in interrupt context, | ||
1852 | * while the Netlink layer can never be called in interrupt context. | ||
1853 | * The fully formed RtNetlink events are queued, and then a tasklet is run | ||
1854 | * to feed those to Netlink. | ||
1855 | * The skb_queue is interrupt safe, and its lock is not held while calling | ||
1856 | * Netlink, so there is no possibility of dealock. | ||
1857 | * Jean II | ||
1858 | */ | ||
1859 | |||
1846 | static struct sk_buff_head wireless_nlevent_queue; | 1860 | static struct sk_buff_head wireless_nlevent_queue; |
1847 | 1861 | ||
1862 | static int __init wireless_nlevent_init(void) | ||
1863 | { | ||
1864 | skb_queue_head_init(&wireless_nlevent_queue); | ||
1865 | return 0; | ||
1866 | } | ||
1867 | |||
1868 | subsys_initcall(wireless_nlevent_init); | ||
1869 | |||
1848 | static void wireless_nlevent_process(unsigned long data) | 1870 | static void wireless_nlevent_process(unsigned long data) |
1849 | { | 1871 | { |
1850 | struct sk_buff *skb; | 1872 | struct sk_buff *skb; |
@@ -1921,13 +1943,6 @@ static inline void rtmsg_iwinfo(struct net_device * dev, | |||
1921 | tasklet_schedule(&wireless_nlevent_tasklet); | 1943 | tasklet_schedule(&wireless_nlevent_tasklet); |
1922 | } | 1944 | } |
1923 | 1945 | ||
1924 | static int __init wireless_nlevent_init(void) | ||
1925 | { | ||
1926 | skb_queue_head_init(&wireless_nlevent_queue); | ||
1927 | return 0; | ||
1928 | } | ||
1929 | |||
1930 | subsys_initcall(wireless_nlevent_init); | ||
1931 | #endif /* WE_EVENT_RTNETLINK */ | 1946 | #endif /* WE_EVENT_RTNETLINK */ |
1932 | 1947 | ||
1933 | /* ---------------------------------------------------------------- */ | 1948 | /* ---------------------------------------------------------------- */ |