diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2005-09-07 20:22:43 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-09-07 20:22:43 -0400 |
commit | 55faed1e607a24ca7f3453a3eb463ca8987f8139 (patch) | |
tree | 70c1f910576713e799b5b409d9f4c3c56840526e /net/core | |
parent | 946e91f36e90eea46758dd725b1c3b239f270f68 (diff) | |
parent | 0edd5b44913cd0aba6f23b626b407f70bb3fb018 (diff) |
Merge branch 'upstream' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/netdev-2.6
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 */ |