diff options
author | Jean Tourrilhes <jt@hpl.hp.com> | 2005-09-02 14:32:28 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@pobox.com> | 2005-09-06 22:40:24 -0400 |
commit | 6582c164f2b3b6e58d1f13c1c031b19ee691eb14 (patch) | |
tree | 492043111300ee6e1341a6e679a13983893c438c /net/core | |
parent | 054034dbf5b1a6aef800af4eb22d421d1c7d4b6d (diff) |
[PATCH] WE-19 for kernel 2.6.13
Hi Jeff,
This is version 19 of the Wireless Extensions. It was supposed
to be the fallback of the WPA API changes, but people seem quite happy
about it (especially Jouni), so the patch is rather small.
The patch has been fully tested with 2.6.13 and various
wireless drivers, and is in its final version. Would you mind pushing
that into Linus's kernel so that the driver and the apps can take
advantage ot it ?
It includes :
o iwstat improvement (explicit dBm). This is the result of
long discussions with Dan Williams, the authors of
NetworkManager. Thanks to him for all the fruitful feedback.
o remove pointer from event stream. I was not totally sure if
this pointer was 32-64 bits clean, so I'd rather remove it and be at
peace with it.
o remove linux header from wireless.h. This has long been
requested by people writting user space apps, now it's done, and it
was not even painful.
o final deprecation of spy_offset. You did not like it, it's
now gone for good.
o Start deprecating dev->get_wireless_stats -> debloat netdev
o Add "check" version of event macros for ieee802.11
stack. Jiri Benc doesn't like the current macros, we aim to please ;-)
All those changes, except the last one, have been bit-roting on
my web pages for a while...
Patches for most kernel drivers will follow. Patches for the
Orinoco and the HostAP drivers have been sent to their respective
maintainers.
Have fun...
Jean
Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/wireless.c | 58 |
1 files changed, 34 insertions, 24 deletions
diff --git a/net/core/wireless.c b/net/core/wireless.c index 5caae2399f3a..d17f1583ea3e 100644 --- a/net/core/wireless.c +++ b/net/core/wireless.c | |||
@@ -58,6 +58,13 @@ | |||
58 | * o Add wmb() in iw_handler_set_spy() for non-coherent archs/cpus | 58 | * o Add wmb() in iw_handler_set_spy() for non-coherent archs/cpus |
59 | * Based on patch from Pavel Roskin <proski@gnu.org> : | 59 | * Based on patch from Pavel Roskin <proski@gnu.org> : |
60 | * o Fix kernel data leak to user space in private handler handling | 60 | * o Fix kernel data leak to user space in private handler handling |
61 | * | ||
62 | * v7 - 18.3.05 - Jean II | ||
63 | * o Remove (struct iw_point *)->pointer from events and streams | ||
64 | * o Remove spy_offset from struct iw_handler_def | ||
65 | * o Start deprecating dev->get_wireless_stats, output a warning | ||
66 | * o If IW_QUAL_DBM is set, show dBm values in /proc/net/wireless | ||
67 | * o Don't loose INVALID/DBM flags when clearing UPDATED flags (iwstats) | ||
61 | */ | 68 | */ |
62 | 69 | ||
63 | /***************************** INCLUDES *****************************/ | 70 | /***************************** INCLUDES *****************************/ |
@@ -446,10 +453,14 @@ static inline struct iw_statistics *get_wireless_stats(struct net_device *dev) | |||
446 | (dev->wireless_handlers->get_wireless_stats != NULL)) | 453 | (dev->wireless_handlers->get_wireless_stats != NULL)) |
447 | return dev->wireless_handlers->get_wireless_stats(dev); | 454 | return dev->wireless_handlers->get_wireless_stats(dev); |
448 | 455 | ||
449 | /* Old location, will be phased out in next WE */ | 456 | /* Old location, field to be removed in next WE */ |
450 | return (dev->get_wireless_stats ? | 457 | if(dev->get_wireless_stats) { |
451 | dev->get_wireless_stats(dev) : | 458 | printk(KERN_DEBUG "%s (WE) : Driver using old /proc/net/wireless support, please fix driver !\n", |
452 | (struct iw_statistics *) NULL); | 459 | dev->name); |
460 | return dev->get_wireless_stats(dev); | ||
461 | } | ||
462 | /* Not found */ | ||
463 | return (struct iw_statistics *) NULL; | ||
453 | } | 464 | } |
454 | 465 | ||
455 | /* ---------------------------------------------------------------- */ | 466 | /* ---------------------------------------------------------------- */ |
@@ -541,16 +552,18 @@ static __inline__ void wireless_seq_printf_stats(struct seq_file *seq, | |||
541 | dev->name, stats->status, stats->qual.qual, | 552 | dev->name, stats->status, stats->qual.qual, |
542 | stats->qual.updated & IW_QUAL_QUAL_UPDATED | 553 | stats->qual.updated & IW_QUAL_QUAL_UPDATED |
543 | ? '.' : ' ', | 554 | ? '.' : ' ', |
544 | ((__u8) stats->qual.level), | 555 | ((__s32) stats->qual.level) - |
556 | ((stats->qual.updated & IW_QUAL_DBM) ? 0x100 : 0), | ||
545 | stats->qual.updated & IW_QUAL_LEVEL_UPDATED | 557 | stats->qual.updated & IW_QUAL_LEVEL_UPDATED |
546 | ? '.' : ' ', | 558 | ? '.' : ' ', |
547 | ((__u8) stats->qual.noise), | 559 | ((__s32) stats->qual.noise) - |
560 | ((stats->qual.updated & IW_QUAL_DBM) ? 0x100 : 0), | ||
548 | stats->qual.updated & IW_QUAL_NOISE_UPDATED | 561 | stats->qual.updated & IW_QUAL_NOISE_UPDATED |
549 | ? '.' : ' ', | 562 | ? '.' : ' ', |
550 | stats->discard.nwid, stats->discard.code, | 563 | stats->discard.nwid, stats->discard.code, |
551 | stats->discard.fragment, stats->discard.retries, | 564 | stats->discard.fragment, stats->discard.retries, |
552 | stats->discard.misc, stats->miss.beacon); | 565 | stats->discard.misc, stats->miss.beacon); |
553 | stats->qual.updated = 0; | 566 | stats->qual.updated &= ~IW_QUAL_ALL_UPDATED; |
554 | } | 567 | } |
555 | } | 568 | } |
556 | 569 | ||
@@ -593,6 +606,7 @@ static struct file_operations wireless_seq_fops = { | |||
593 | 606 | ||
594 | int __init wireless_proc_init(void) | 607 | int __init wireless_proc_init(void) |
595 | { | 608 | { |
609 | /* Create /proc/net/wireless entry */ | ||
596 | if (!proc_net_fops_create("wireless", S_IRUGO, &wireless_seq_fops)) | 610 | if (!proc_net_fops_create("wireless", S_IRUGO, &wireless_seq_fops)) |
597 | return -ENOMEM; | 611 | return -ENOMEM; |
598 | 612 | ||
@@ -627,9 +641,9 @@ static inline int dev_iwstats(struct net_device *dev, struct ifreq *ifr) | |||
627 | sizeof(struct iw_statistics))) | 641 | sizeof(struct iw_statistics))) |
628 | return -EFAULT; | 642 | return -EFAULT; |
629 | 643 | ||
630 | /* Check if we need to clear the update flag */ | 644 | /* Check if we need to clear the updated flag */ |
631 | if(wrq->u.data.flags != 0) | 645 | if(wrq->u.data.flags != 0) |
632 | stats->qual.updated = 0; | 646 | stats->qual.updated &= ~IW_QUAL_ALL_UPDATED; |
633 | return 0; | 647 | return 0; |
634 | } else | 648 | } else |
635 | return -EOPNOTSUPP; | 649 | return -EOPNOTSUPP; |
@@ -1161,10 +1175,11 @@ void wireless_send_event(struct net_device * dev, | |||
1161 | struct iw_event *event; /* Mallocated whole event */ | 1175 | struct iw_event *event; /* Mallocated whole event */ |
1162 | int event_len; /* Its size */ | 1176 | int event_len; /* Its size */ |
1163 | int hdr_len; /* Size of the event header */ | 1177 | int hdr_len; /* Size of the event header */ |
1178 | int wrqu_off = 0; /* Offset in wrqu */ | ||
1164 | /* Don't "optimise" the following variable, it will crash */ | 1179 | /* Don't "optimise" the following variable, it will crash */ |
1165 | unsigned cmd_index; /* *MUST* be unsigned */ | 1180 | unsigned cmd_index; /* *MUST* be unsigned */ |
1166 | 1181 | ||
1167 | /* Get the description of the IOCTL */ | 1182 | /* Get the description of the Event */ |
1168 | if(cmd <= SIOCIWLAST) { | 1183 | if(cmd <= SIOCIWLAST) { |
1169 | cmd_index = cmd - SIOCIWFIRST; | 1184 | cmd_index = cmd - SIOCIWFIRST; |
1170 | if(cmd_index < standard_ioctl_num) | 1185 | if(cmd_index < standard_ioctl_num) |
@@ -1207,6 +1222,8 @@ void wireless_send_event(struct net_device * dev, | |||
1207 | /* Calculate extra_len - extra is NULL for restricted events */ | 1222 | /* Calculate extra_len - extra is NULL for restricted events */ |
1208 | if(extra != NULL) | 1223 | if(extra != NULL) |
1209 | extra_len = wrqu->data.length * descr->token_size; | 1224 | extra_len = wrqu->data.length * descr->token_size; |
1225 | /* Always at an offset in wrqu */ | ||
1226 | wrqu_off = IW_EV_POINT_OFF; | ||
1210 | #ifdef WE_EVENT_DEBUG | 1227 | #ifdef WE_EVENT_DEBUG |
1211 | printk(KERN_DEBUG "%s (WE) : Event 0x%04X, tokens %d, extra_len %d\n", dev->name, cmd, wrqu->data.length, extra_len); | 1228 | printk(KERN_DEBUG "%s (WE) : Event 0x%04X, tokens %d, extra_len %d\n", dev->name, cmd, wrqu->data.length, extra_len); |
1212 | #endif /* WE_EVENT_DEBUG */ | 1229 | #endif /* WE_EVENT_DEBUG */ |
@@ -1217,7 +1234,7 @@ void wireless_send_event(struct net_device * dev, | |||
1217 | event_len = hdr_len + extra_len; | 1234 | event_len = hdr_len + extra_len; |
1218 | 1235 | ||
1219 | #ifdef WE_EVENT_DEBUG | 1236 | #ifdef WE_EVENT_DEBUG |
1220 | printk(KERN_DEBUG "%s (WE) : Event 0x%04X, hdr_len %d, event_len %d\n", dev->name, cmd, hdr_len, event_len); | 1237 | printk(KERN_DEBUG "%s (WE) : Event 0x%04X, hdr_len %d, wrqu_off %d, event_len %d\n", dev->name, cmd, hdr_len, wrqu_off, event_len); |
1221 | #endif /* WE_EVENT_DEBUG */ | 1238 | #endif /* WE_EVENT_DEBUG */ |
1222 | 1239 | ||
1223 | /* Create temporary buffer to hold the event */ | 1240 | /* Create temporary buffer to hold the event */ |
@@ -1228,7 +1245,7 @@ void wireless_send_event(struct net_device * dev, | |||
1228 | /* Fill event */ | 1245 | /* Fill event */ |
1229 | event->len = event_len; | 1246 | event->len = event_len; |
1230 | event->cmd = cmd; | 1247 | event->cmd = cmd; |
1231 | memcpy(&event->u, wrqu, hdr_len - IW_EV_LCP_LEN); | 1248 | memcpy(&event->u, ((char *) wrqu) + wrqu_off, hdr_len - IW_EV_LCP_LEN); |
1232 | if(extra != NULL) | 1249 | if(extra != NULL) |
1233 | memcpy(((char *) event) + hdr_len, extra, extra_len); | 1250 | memcpy(((char *) event) + hdr_len, extra, extra_len); |
1234 | 1251 | ||
@@ -1249,7 +1266,7 @@ void wireless_send_event(struct net_device * dev, | |||
1249 | * Now, the driver can delegate this task to Wireless Extensions. | 1266 | * Now, the driver can delegate this task to Wireless Extensions. |
1250 | * It needs to use those standard spy iw_handler in struct iw_handler_def, | 1267 | * It needs to use those standard spy iw_handler in struct iw_handler_def, |
1251 | * push data to us via wireless_spy_update() and include struct iw_spy_data | 1268 | * push data to us via wireless_spy_update() and include struct iw_spy_data |
1252 | * in its private part (and advertise it in iw_handler_def->spy_offset). | 1269 | * in its private part (and export it in net_device->wireless_data->spy_data). |
1253 | * One of the main advantage of centralising spy support here is that | 1270 | * One of the main advantage of centralising spy support here is that |
1254 | * it becomes much easier to improve and extend it without having to touch | 1271 | * it becomes much easier to improve and extend it without having to touch |
1255 | * the drivers. One example is the addition of the Spy-Threshold events. | 1272 | * the drivers. One example is the addition of the Spy-Threshold events. |
@@ -1266,10 +1283,7 @@ static inline struct iw_spy_data * get_spydata(struct net_device *dev) | |||
1266 | /* This is the new way */ | 1283 | /* This is the new way */ |
1267 | if(dev->wireless_data) | 1284 | if(dev->wireless_data) |
1268 | return(dev->wireless_data->spy_data); | 1285 | return(dev->wireless_data->spy_data); |
1269 | 1286 | return NULL; | |
1270 | /* This is the old way. Doesn't work for multi-headed drivers. | ||
1271 | * It will be removed in the next version of WE. */ | ||
1272 | return (dev->priv + dev->wireless_handlers->spy_offset); | ||
1273 | } | 1287 | } |
1274 | 1288 | ||
1275 | /*------------------------------------------------------------------*/ | 1289 | /*------------------------------------------------------------------*/ |
@@ -1284,10 +1298,6 @@ int iw_handler_set_spy(struct net_device * dev, | |||
1284 | struct iw_spy_data * spydata = get_spydata(dev); | 1298 | struct iw_spy_data * spydata = get_spydata(dev); |
1285 | struct sockaddr * address = (struct sockaddr *) extra; | 1299 | struct sockaddr * address = (struct sockaddr *) extra; |
1286 | 1300 | ||
1287 | if(!dev->wireless_data) | ||
1288 | /* Help user know that driver needs updating */ | ||
1289 | printk(KERN_DEBUG "%s (WE) : Driver using old/buggy spy support, please fix driver !\n", | ||
1290 | dev->name); | ||
1291 | /* Make sure driver is not buggy or using the old API */ | 1301 | /* Make sure driver is not buggy or using the old API */ |
1292 | if(!spydata) | 1302 | if(!spydata) |
1293 | return -EOPNOTSUPP; | 1303 | return -EOPNOTSUPP; |
@@ -1318,7 +1328,7 @@ int iw_handler_set_spy(struct net_device * dev, | |||
1318 | sizeof(struct iw_quality) * IW_MAX_SPY); | 1328 | sizeof(struct iw_quality) * IW_MAX_SPY); |
1319 | 1329 | ||
1320 | #ifdef WE_SPY_DEBUG | 1330 | #ifdef WE_SPY_DEBUG |
1321 | printk(KERN_DEBUG "iw_handler_set_spy() : offset %ld, spydata %p, num %d\n", dev->wireless_handlers->spy_offset, spydata, wrqu->data.length); | 1331 | printk(KERN_DEBUG "iw_handler_set_spy() : wireless_data %p, spydata %p, num %d\n", dev->wireless_data, spydata, wrqu->data.length); |
1322 | for (i = 0; i < wrqu->data.length; i++) | 1332 | for (i = 0; i < wrqu->data.length; i++) |
1323 | printk(KERN_DEBUG | 1333 | printk(KERN_DEBUG |
1324 | "%02X:%02X:%02X:%02X:%02X:%02X \n", | 1334 | "%02X:%02X:%02X:%02X:%02X:%02X \n", |
@@ -1371,7 +1381,7 @@ int iw_handler_get_spy(struct net_device * dev, | |||
1371 | sizeof(struct iw_quality) * spydata->spy_number); | 1381 | sizeof(struct iw_quality) * spydata->spy_number); |
1372 | /* Reset updated flags. */ | 1382 | /* Reset updated flags. */ |
1373 | for(i = 0; i < spydata->spy_number; i++) | 1383 | for(i = 0; i < spydata->spy_number; i++) |
1374 | spydata->spy_stat[i].updated = 0; | 1384 | spydata->spy_stat[i].updated &= ~IW_QUAL_ALL_UPDATED; |
1375 | return 0; | 1385 | return 0; |
1376 | } | 1386 | } |
1377 | 1387 | ||
@@ -1486,7 +1496,7 @@ void wireless_spy_update(struct net_device * dev, | |||
1486 | return; | 1496 | return; |
1487 | 1497 | ||
1488 | #ifdef WE_SPY_DEBUG | 1498 | #ifdef WE_SPY_DEBUG |
1489 | 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]); | 1499 | printk(KERN_DEBUG "wireless_spy_update() : wireless_data %p, spydata %p, address %02X:%02X:%02X:%02X:%02X:%02X\n", dev->wireless_data, spydata, address[0], address[1], address[2], address[3], address[4], address[5]); |
1490 | #endif /* WE_SPY_DEBUG */ | 1500 | #endif /* WE_SPY_DEBUG */ |
1491 | 1501 | ||
1492 | /* Update all records that match */ | 1502 | /* Update all records that match */ |