aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-06-16 21:50:49 -0400
committerDavid S. Miller <davem@davemloft.net>2008-06-16 21:50:49 -0400
commitccc580571cf0799d0460a085a7632b77753f083e (patch)
tree018e0f83776b089b1f272694132688ac93be25b4
parent0f5cabba49021d36e9f76bd97d7fa0f4a408063f (diff)
wext: Emit event stream entries correctly when compat.
Three major portions to this change: 1) Add IW_EV_COMPAT_LCP_LEN, IW_EV_COMPAT_POINT_OFF, and IW_EV_COMPAT_POINT_LEN helper defines. 2) Delete iw_stream_check_add_*(), they are unused. 3) Add iw_request_info argument to iwe_stream_add_*(), and use it to size the event and pointer lengths correctly depending upon whether IW_REQUEST_FLAG_COMPAT is set or not. 4) The mechanical transformations to the drivers and wireless stack bits to get the iw_request_info passed down into the routines modified in #3. Also, explicit references to IW_EV_LCP_LEN are replaced with iwe_stream_lcp_len(info). With a lot of help and bug fixes from Masakazu Mokuno. Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/ps3_gelic_wireless.c30
-rw-r--r--drivers/net/wireless/airo.c43
-rw-r--r--drivers/net/wireless/atmel.c24
-rw-r--r--drivers/net/wireless/hostap/hostap.h3
-rw-r--r--drivers/net/wireless/hostap/hostap_ap.c32
-rw-r--r--drivers/net/wireless/hostap/hostap_ioctl.c58
-rw-r--r--drivers/net/wireless/libertas/scan.c36
-rw-r--r--drivers/net/wireless/orinoco.c30
-rw-r--r--drivers/net/wireless/prism54/isl_ioctl.c49
-rw-r--r--drivers/net/wireless/rndis_wlan.c32
-rw-r--r--drivers/net/wireless/wl3501_cs.c10
-rw-r--r--drivers/net/wireless/zd1201.c21
-rw-r--r--include/linux/wireless.h15
-rw-r--r--include/net/iw_handler.h149
-rw-r--r--net/ieee80211/ieee80211_wx.c48
-rw-r--r--net/mac80211/ieee80211_i.h5
-rw-r--r--net/mac80211/mlme.c66
-rw-r--r--net/mac80211/wext.c2
18 files changed, 345 insertions, 308 deletions
diff --git a/drivers/net/ps3_gelic_wireless.c b/drivers/net/ps3_gelic_wireless.c
index aa963ac1e37b..6b2dee0cf3a9 100644
--- a/drivers/net/ps3_gelic_wireless.c
+++ b/drivers/net/ps3_gelic_wireless.c
@@ -571,6 +571,7 @@ static void gelic_wl_parse_ie(u8 *data, size_t len,
571 * independent format 571 * independent format
572 */ 572 */
573static char *gelic_wl_translate_scan(struct net_device *netdev, 573static char *gelic_wl_translate_scan(struct net_device *netdev,
574 struct iw_request_info *info,
574 char *ev, 575 char *ev,
575 char *stop, 576 char *stop,
576 struct gelic_wl_scan_info *network) 577 struct gelic_wl_scan_info *network)
@@ -588,26 +589,26 @@ static char *gelic_wl_translate_scan(struct net_device *netdev,
588 iwe.cmd = SIOCGIWAP; 589 iwe.cmd = SIOCGIWAP;
589 iwe.u.ap_addr.sa_family = ARPHRD_ETHER; 590 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
590 memcpy(iwe.u.ap_addr.sa_data, &scan->bssid[2], ETH_ALEN); 591 memcpy(iwe.u.ap_addr.sa_data, &scan->bssid[2], ETH_ALEN);
591 ev = iwe_stream_add_event(ev, stop, &iwe, IW_EV_ADDR_LEN); 592 ev = iwe_stream_add_event(info, ev, stop, &iwe, IW_EV_ADDR_LEN);
592 593
593 /* ESSID */ 594 /* ESSID */
594 iwe.cmd = SIOCGIWESSID; 595 iwe.cmd = SIOCGIWESSID;
595 iwe.u.data.flags = 1; 596 iwe.u.data.flags = 1;
596 iwe.u.data.length = strnlen(scan->essid, 32); 597 iwe.u.data.length = strnlen(scan->essid, 32);
597 ev = iwe_stream_add_point(ev, stop, &iwe, scan->essid); 598 ev = iwe_stream_add_point(info, ev, stop, &iwe, scan->essid);
598 599
599 /* FREQUENCY */ 600 /* FREQUENCY */
600 iwe.cmd = SIOCGIWFREQ; 601 iwe.cmd = SIOCGIWFREQ;
601 iwe.u.freq.m = be16_to_cpu(scan->channel); 602 iwe.u.freq.m = be16_to_cpu(scan->channel);
602 iwe.u.freq.e = 0; /* table value in MHz */ 603 iwe.u.freq.e = 0; /* table value in MHz */
603 iwe.u.freq.i = 0; 604 iwe.u.freq.i = 0;
604 ev = iwe_stream_add_event(ev, stop, &iwe, IW_EV_FREQ_LEN); 605 ev = iwe_stream_add_event(info, ev, stop, &iwe, IW_EV_FREQ_LEN);
605 606
606 /* RATES */ 607 /* RATES */
607 iwe.cmd = SIOCGIWRATE; 608 iwe.cmd = SIOCGIWRATE;
608 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; 609 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
609 /* to stuff multiple values in one event */ 610 /* to stuff multiple values in one event */
610 tmp = ev + IW_EV_LCP_LEN; 611 tmp = ev + iwe_stream_lcp_len(info);
611 /* put them in ascendant order (older is first) */ 612 /* put them in ascendant order (older is first) */
612 i = 0; 613 i = 0;
613 j = 0; 614 j = 0;
@@ -620,16 +621,16 @@ static char *gelic_wl_translate_scan(struct net_device *netdev,
620 else 621 else
621 rate = scan->rate[i++] & 0x7f; 622 rate = scan->rate[i++] & 0x7f;
622 iwe.u.bitrate.value = rate * 500000; /* 500kbps unit */ 623 iwe.u.bitrate.value = rate * 500000; /* 500kbps unit */
623 tmp = iwe_stream_add_value(ev, tmp, stop, &iwe, 624 tmp = iwe_stream_add_value(info, ev, tmp, stop, &iwe,
624 IW_EV_PARAM_LEN); 625 IW_EV_PARAM_LEN);
625 } 626 }
626 while (j < network->rate_ext_len) { 627 while (j < network->rate_ext_len) {
627 iwe.u.bitrate.value = (scan->ext_rate[j++] & 0x7f) * 500000; 628 iwe.u.bitrate.value = (scan->ext_rate[j++] & 0x7f) * 500000;
628 tmp = iwe_stream_add_value(ev, tmp, stop, &iwe, 629 tmp = iwe_stream_add_value(info, ev, tmp, stop, &iwe,
629 IW_EV_PARAM_LEN); 630 IW_EV_PARAM_LEN);
630 } 631 }
631 /* Check if we added any rate */ 632 /* Check if we added any rate */
632 if (IW_EV_LCP_LEN < (tmp - ev)) 633 if (iwe_stream_lcp_len(info) < (tmp - ev))
633 ev = tmp; 634 ev = tmp;
634 635
635 /* ENCODE */ 636 /* ENCODE */
@@ -639,7 +640,7 @@ static char *gelic_wl_translate_scan(struct net_device *netdev,
639 else 640 else
640 iwe.u.data.flags = IW_ENCODE_DISABLED; 641 iwe.u.data.flags = IW_ENCODE_DISABLED;
641 iwe.u.data.length = 0; 642 iwe.u.data.length = 0;
642 ev = iwe_stream_add_point(ev, stop, &iwe, scan->essid); 643 ev = iwe_stream_add_point(info, ev, stop, &iwe, scan->essid);
643 644
644 /* MODE */ 645 /* MODE */
645 iwe.cmd = SIOCGIWMODE; 646 iwe.cmd = SIOCGIWMODE;
@@ -649,7 +650,7 @@ static char *gelic_wl_translate_scan(struct net_device *netdev,
649 iwe.u.mode = IW_MODE_MASTER; 650 iwe.u.mode = IW_MODE_MASTER;
650 else 651 else
651 iwe.u.mode = IW_MODE_ADHOC; 652 iwe.u.mode = IW_MODE_ADHOC;
652 ev = iwe_stream_add_event(ev, stop, &iwe, IW_EV_UINT_LEN); 653 ev = iwe_stream_add_event(info, ev, stop, &iwe, IW_EV_UINT_LEN);
653 } 654 }
654 655
655 /* QUAL */ 656 /* QUAL */
@@ -659,7 +660,7 @@ static char *gelic_wl_translate_scan(struct net_device *netdev,
659 iwe.u.qual.level = be16_to_cpu(scan->rssi); 660 iwe.u.qual.level = be16_to_cpu(scan->rssi);
660 iwe.u.qual.qual = be16_to_cpu(scan->rssi); 661 iwe.u.qual.qual = be16_to_cpu(scan->rssi);
661 iwe.u.qual.noise = 0; 662 iwe.u.qual.noise = 0;
662 ev = iwe_stream_add_event(ev, stop, &iwe, IW_EV_QUAL_LEN); 663 ev = iwe_stream_add_event(info, ev, stop, &iwe, IW_EV_QUAL_LEN);
663 664
664 /* RSN */ 665 /* RSN */
665 memset(&iwe, 0, sizeof(iwe)); 666 memset(&iwe, 0, sizeof(iwe));
@@ -669,7 +670,7 @@ static char *gelic_wl_translate_scan(struct net_device *netdev,
669 if (len) { 670 if (len) {
670 iwe.cmd = IWEVGENIE; 671 iwe.cmd = IWEVGENIE;
671 iwe.u.data.length = len; 672 iwe.u.data.length = len;
672 ev = iwe_stream_add_point(ev, stop, &iwe, buf); 673 ev = iwe_stream_add_point(info, ev, stop, &iwe, buf);
673 } 674 }
674 } else { 675 } else {
675 /* this scan info has IE data */ 676 /* this scan info has IE data */
@@ -684,7 +685,7 @@ static char *gelic_wl_translate_scan(struct net_device *netdev,
684 memcpy(buf, ie_info.wpa.data, ie_info.wpa.len); 685 memcpy(buf, ie_info.wpa.data, ie_info.wpa.len);
685 iwe.cmd = IWEVGENIE; 686 iwe.cmd = IWEVGENIE;
686 iwe.u.data.length = ie_info.wpa.len; 687 iwe.u.data.length = ie_info.wpa.len;
687 ev = iwe_stream_add_point(ev, stop, &iwe, buf); 688 ev = iwe_stream_add_point(info, ev, stop, &iwe, buf);
688 } 689 }
689 690
690 if (ie_info.rsn.len && (ie_info.rsn.len <= sizeof(buf))) { 691 if (ie_info.rsn.len && (ie_info.rsn.len <= sizeof(buf))) {
@@ -692,7 +693,7 @@ static char *gelic_wl_translate_scan(struct net_device *netdev,
692 memcpy(buf, ie_info.rsn.data, ie_info.rsn.len); 693 memcpy(buf, ie_info.rsn.data, ie_info.rsn.len);
693 iwe.cmd = IWEVGENIE; 694 iwe.cmd = IWEVGENIE;
694 iwe.u.data.length = ie_info.rsn.len; 695 iwe.u.data.length = ie_info.rsn.len;
695 ev = iwe_stream_add_point(ev, stop, &iwe, buf); 696 ev = iwe_stream_add_point(info, ev, stop, &iwe, buf);
696 } 697 }
697 } 698 }
698 699
@@ -737,7 +738,8 @@ static int gelic_wl_get_scan(struct net_device *netdev,
737 if (wl->scan_age == 0 || 738 if (wl->scan_age == 0 ||
738 time_after(scan_info->last_scanned + wl->scan_age, 739 time_after(scan_info->last_scanned + wl->scan_age,
739 this_time)) 740 this_time))
740 ev = gelic_wl_translate_scan(netdev, ev, stop, 741 ev = gelic_wl_translate_scan(netdev, info,
742 ev, stop,
741 scan_info); 743 scan_info);
742 else 744 else
743 pr_debug("%s:entry too old\n", __func__); 745 pr_debug("%s:entry too old\n", __func__);
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index e30f8b79ea89..73d66a80c4a3 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -7156,6 +7156,7 @@ out:
7156 * format that the Wireless Tools will understand - Jean II 7156 * format that the Wireless Tools will understand - Jean II
7157 */ 7157 */
7158static inline char *airo_translate_scan(struct net_device *dev, 7158static inline char *airo_translate_scan(struct net_device *dev,
7159 struct iw_request_info *info,
7159 char *current_ev, 7160 char *current_ev,
7160 char *end_buf, 7161 char *end_buf,
7161 BSSListRid *bss) 7162 BSSListRid *bss)
@@ -7172,7 +7173,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
7172 iwe.cmd = SIOCGIWAP; 7173 iwe.cmd = SIOCGIWAP;
7173 iwe.u.ap_addr.sa_family = ARPHRD_ETHER; 7174 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
7174 memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN); 7175 memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
7175 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN); 7176 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
7177 &iwe, IW_EV_ADDR_LEN);
7176 7178
7177 /* Other entries will be displayed in the order we give them */ 7179 /* Other entries will be displayed in the order we give them */
7178 7180
@@ -7182,7 +7184,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
7182 iwe.u.data.length = 32; 7184 iwe.u.data.length = 32;
7183 iwe.cmd = SIOCGIWESSID; 7185 iwe.cmd = SIOCGIWESSID;
7184 iwe.u.data.flags = 1; 7186 iwe.u.data.flags = 1;
7185 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->ssid); 7187 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
7188 &iwe, bss->ssid);
7186 7189
7187 /* Add mode */ 7190 /* Add mode */
7188 iwe.cmd = SIOCGIWMODE; 7191 iwe.cmd = SIOCGIWMODE;
@@ -7192,7 +7195,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
7192 iwe.u.mode = IW_MODE_MASTER; 7195 iwe.u.mode = IW_MODE_MASTER;
7193 else 7196 else
7194 iwe.u.mode = IW_MODE_ADHOC; 7197 iwe.u.mode = IW_MODE_ADHOC;
7195 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_UINT_LEN); 7198 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
7199 &iwe, IW_EV_UINT_LEN);
7196 } 7200 }
7197 7201
7198 /* Add frequency */ 7202 /* Add frequency */
@@ -7203,7 +7207,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
7203 */ 7207 */
7204 iwe.u.freq.m = frequency_list[iwe.u.freq.m - 1] * 100000; 7208 iwe.u.freq.m = frequency_list[iwe.u.freq.m - 1] * 100000;
7205 iwe.u.freq.e = 1; 7209 iwe.u.freq.e = 1;
7206 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN); 7210 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
7211 &iwe, IW_EV_FREQ_LEN);
7207 7212
7208 dBm = le16_to_cpu(bss->dBm); 7213 dBm = le16_to_cpu(bss->dBm);
7209 7214
@@ -7223,7 +7228,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
7223 | IW_QUAL_DBM; 7228 | IW_QUAL_DBM;
7224 } 7229 }
7225 iwe.u.qual.noise = ai->wstats.qual.noise; 7230 iwe.u.qual.noise = ai->wstats.qual.noise;
7226 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN); 7231 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
7232 &iwe, IW_EV_QUAL_LEN);
7227 7233
7228 /* Add encryption capability */ 7234 /* Add encryption capability */
7229 iwe.cmd = SIOCGIWENCODE; 7235 iwe.cmd = SIOCGIWENCODE;
@@ -7232,11 +7238,12 @@ static inline char *airo_translate_scan(struct net_device *dev,
7232 else 7238 else
7233 iwe.u.data.flags = IW_ENCODE_DISABLED; 7239 iwe.u.data.flags = IW_ENCODE_DISABLED;
7234 iwe.u.data.length = 0; 7240 iwe.u.data.length = 0;
7235 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->ssid); 7241 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
7242 &iwe, bss->ssid);
7236 7243
7237 /* Rate : stuffing multiple values in a single event require a bit 7244 /* Rate : stuffing multiple values in a single event require a bit
7238 * more of magic - Jean II */ 7245 * more of magic - Jean II */
7239 current_val = current_ev + IW_EV_LCP_LEN; 7246 current_val = current_ev + iwe_stream_lcp_len(info);
7240 7247
7241 iwe.cmd = SIOCGIWRATE; 7248 iwe.cmd = SIOCGIWRATE;
7242 /* Those two flags are ignored... */ 7249 /* Those two flags are ignored... */
@@ -7249,10 +7256,12 @@ static inline char *airo_translate_scan(struct net_device *dev,
7249 /* Bit rate given in 500 kb/s units (+ 0x80) */ 7256 /* Bit rate given in 500 kb/s units (+ 0x80) */
7250 iwe.u.bitrate.value = ((bss->rates[i] & 0x7f) * 500000); 7257 iwe.u.bitrate.value = ((bss->rates[i] & 0x7f) * 500000);
7251 /* Add new value to event */ 7258 /* Add new value to event */
7252 current_val = iwe_stream_add_value(current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN); 7259 current_val = iwe_stream_add_value(info, current_ev,
7260 current_val, end_buf,
7261 &iwe, IW_EV_PARAM_LEN);
7253 } 7262 }
7254 /* Check if we added any event */ 7263 /* Check if we added any event */
7255 if((current_val - current_ev) > IW_EV_LCP_LEN) 7264 if ((current_val - current_ev) > iwe_stream_lcp_len(info))
7256 current_ev = current_val; 7265 current_ev = current_val;
7257 7266
7258 /* Beacon interval */ 7267 /* Beacon interval */
@@ -7261,7 +7270,8 @@ static inline char *airo_translate_scan(struct net_device *dev,
7261 iwe.cmd = IWEVCUSTOM; 7270 iwe.cmd = IWEVCUSTOM;
7262 sprintf(buf, "bcn_int=%d", bss->beaconInterval); 7271 sprintf(buf, "bcn_int=%d", bss->beaconInterval);
7263 iwe.u.data.length = strlen(buf); 7272 iwe.u.data.length = strlen(buf);
7264 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, buf); 7273 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
7274 &iwe, buf);
7265 kfree(buf); 7275 kfree(buf);
7266 } 7276 }
7267 7277
@@ -7295,8 +7305,10 @@ static inline char *airo_translate_scan(struct net_device *dev,
7295 iwe.cmd = IWEVGENIE; 7305 iwe.cmd = IWEVGENIE;
7296 iwe.u.data.length = min(info_element->len + 2, 7306 iwe.u.data.length = min(info_element->len + 2,
7297 MAX_WPA_IE_LEN); 7307 MAX_WPA_IE_LEN);
7298 current_ev = iwe_stream_add_point(current_ev, end_buf, 7308 current_ev = iwe_stream_add_point(
7299 &iwe, (char *) info_element); 7309 info, current_ev,
7310 end_buf, &iwe,
7311 (char *) info_element);
7300 } 7312 }
7301 break; 7313 break;
7302 7314
@@ -7304,8 +7316,9 @@ static inline char *airo_translate_scan(struct net_device *dev,
7304 iwe.cmd = IWEVGENIE; 7316 iwe.cmd = IWEVGENIE;
7305 iwe.u.data.length = min(info_element->len + 2, 7317 iwe.u.data.length = min(info_element->len + 2,
7306 MAX_WPA_IE_LEN); 7318 MAX_WPA_IE_LEN);
7307 current_ev = iwe_stream_add_point(current_ev, end_buf, 7319 current_ev = iwe_stream_add_point(
7308 &iwe, (char *) info_element); 7320 info, current_ev, end_buf,
7321 &iwe, (char *) info_element);
7309 break; 7322 break;
7310 7323
7311 default: 7324 default:
@@ -7344,7 +7357,7 @@ static int airo_get_scan(struct net_device *dev,
7344 7357
7345 list_for_each_entry (net, &ai->network_list, list) { 7358 list_for_each_entry (net, &ai->network_list, list) {
7346 /* Translate to WE format this entry */ 7359 /* Translate to WE format this entry */
7347 current_ev = airo_translate_scan(dev, current_ev, 7360 current_ev = airo_translate_scan(dev, info, current_ev,
7348 extra + dwrq->length, 7361 extra + dwrq->length,
7349 &net->bss); 7362 &net->bss);
7350 7363
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index 7bb2646ae0ef..28b6ff3eaa37 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -2310,30 +2310,40 @@ static int atmel_get_scan(struct net_device *dev,
2310 iwe.cmd = SIOCGIWAP; 2310 iwe.cmd = SIOCGIWAP;
2311 iwe.u.ap_addr.sa_family = ARPHRD_ETHER; 2311 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
2312 memcpy(iwe.u.ap_addr.sa_data, priv->BSSinfo[i].BSSID, 6); 2312 memcpy(iwe.u.ap_addr.sa_data, priv->BSSinfo[i].BSSID, 6);
2313 current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_ADDR_LEN); 2313 current_ev = iwe_stream_add_event(info, current_ev,
2314 extra + IW_SCAN_MAX_DATA,
2315 &iwe, IW_EV_ADDR_LEN);
2314 2316
2315 iwe.u.data.length = priv->BSSinfo[i].SSIDsize; 2317 iwe.u.data.length = priv->BSSinfo[i].SSIDsize;
2316 if (iwe.u.data.length > 32) 2318 if (iwe.u.data.length > 32)
2317 iwe.u.data.length = 32; 2319 iwe.u.data.length = 32;
2318 iwe.cmd = SIOCGIWESSID; 2320 iwe.cmd = SIOCGIWESSID;
2319 iwe.u.data.flags = 1; 2321 iwe.u.data.flags = 1;
2320 current_ev = iwe_stream_add_point(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, priv->BSSinfo[i].SSID); 2322 current_ev = iwe_stream_add_point(info, current_ev,
2323 extra + IW_SCAN_MAX_DATA,
2324 &iwe, priv->BSSinfo[i].SSID);
2321 2325
2322 iwe.cmd = SIOCGIWMODE; 2326 iwe.cmd = SIOCGIWMODE;
2323 iwe.u.mode = priv->BSSinfo[i].BSStype; 2327 iwe.u.mode = priv->BSSinfo[i].BSStype;
2324 current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_UINT_LEN); 2328 current_ev = iwe_stream_add_event(info, current_ev,
2329 extra + IW_SCAN_MAX_DATA,
2330 &iwe, IW_EV_UINT_LEN);
2325 2331
2326 iwe.cmd = SIOCGIWFREQ; 2332 iwe.cmd = SIOCGIWFREQ;
2327 iwe.u.freq.m = priv->BSSinfo[i].channel; 2333 iwe.u.freq.m = priv->BSSinfo[i].channel;
2328 iwe.u.freq.e = 0; 2334 iwe.u.freq.e = 0;
2329 current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_FREQ_LEN); 2335 current_ev = iwe_stream_add_event(info, current_ev,
2336 extra + IW_SCAN_MAX_DATA,
2337 &iwe, IW_EV_FREQ_LEN);
2330 2338
2331 /* Add quality statistics */ 2339 /* Add quality statistics */
2332 iwe.cmd = IWEVQUAL; 2340 iwe.cmd = IWEVQUAL;
2333 iwe.u.qual.level = priv->BSSinfo[i].RSSI; 2341 iwe.u.qual.level = priv->BSSinfo[i].RSSI;
2334 iwe.u.qual.qual = iwe.u.qual.level; 2342 iwe.u.qual.qual = iwe.u.qual.level;
2335 /* iwe.u.qual.noise = SOMETHING */ 2343 /* iwe.u.qual.noise = SOMETHING */
2336 current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA , &iwe, IW_EV_QUAL_LEN); 2344 current_ev = iwe_stream_add_event(info, current_ev,
2345 extra + IW_SCAN_MAX_DATA,
2346 &iwe, IW_EV_QUAL_LEN);
2337 2347
2338 2348
2339 iwe.cmd = SIOCGIWENCODE; 2349 iwe.cmd = SIOCGIWENCODE;
@@ -2342,7 +2352,9 @@ static int atmel_get_scan(struct net_device *dev,
2342 else 2352 else
2343 iwe.u.data.flags = IW_ENCODE_DISABLED; 2353 iwe.u.data.flags = IW_ENCODE_DISABLED;
2344 iwe.u.data.length = 0; 2354 iwe.u.data.length = 0;
2345 current_ev = iwe_stream_add_point(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, NULL); 2355 current_ev = iwe_stream_add_point(info, current_ev,
2356 extra + IW_SCAN_MAX_DATA,
2357 &iwe, NULL);
2346 } 2358 }
2347 2359
2348 /* Length of data */ 2360 /* Length of data */
diff --git a/drivers/net/wireless/hostap/hostap.h b/drivers/net/wireless/hostap/hostap.h
index 547ba84dc797..3a386a636cca 100644
--- a/drivers/net/wireless/hostap/hostap.h
+++ b/drivers/net/wireless/hostap/hostap.h
@@ -67,7 +67,8 @@ void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent,
67int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[], 67int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[],
68 struct iw_quality qual[], int buf_size, 68 struct iw_quality qual[], int buf_size,
69 int aplist); 69 int aplist);
70int prism2_ap_translate_scan(struct net_device *dev, char *buffer); 70int prism2_ap_translate_scan(struct net_device *dev,
71 struct iw_request_info *info, char *buffer);
71int prism2_hostapd(struct ap_data *ap, struct prism2_hostapd_param *param); 72int prism2_hostapd(struct ap_data *ap, struct prism2_hostapd_param *param);
72 73
73 74
diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c
index 0acd9589c48c..06b23df8f69b 100644
--- a/drivers/net/wireless/hostap/hostap_ap.c
+++ b/drivers/net/wireless/hostap/hostap_ap.c
@@ -2420,7 +2420,8 @@ int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[],
2420 2420
2421/* Translate our list of Access Points & Stations to a card independant 2421/* Translate our list of Access Points & Stations to a card independant
2422 * format that the Wireless Tools will understand - Jean II */ 2422 * format that the Wireless Tools will understand - Jean II */
2423int prism2_ap_translate_scan(struct net_device *dev, char *buffer) 2423int prism2_ap_translate_scan(struct net_device *dev,
2424 struct iw_request_info *info, char *buffer)
2424{ 2425{
2425 struct hostap_interface *iface; 2426 struct hostap_interface *iface;
2426 local_info_t *local; 2427 local_info_t *local;
@@ -2449,8 +2450,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
2449 iwe.u.ap_addr.sa_family = ARPHRD_ETHER; 2450 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
2450 memcpy(iwe.u.ap_addr.sa_data, sta->addr, ETH_ALEN); 2451 memcpy(iwe.u.ap_addr.sa_data, sta->addr, ETH_ALEN);
2451 iwe.len = IW_EV_ADDR_LEN; 2452 iwe.len = IW_EV_ADDR_LEN;
2452 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, 2453 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
2453 IW_EV_ADDR_LEN); 2454 &iwe, IW_EV_ADDR_LEN);
2454 2455
2455 /* Use the mode to indicate if it's a station or 2456 /* Use the mode to indicate if it's a station or
2456 * an Access Point */ 2457 * an Access Point */
@@ -2461,8 +2462,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
2461 else 2462 else
2462 iwe.u.mode = IW_MODE_INFRA; 2463 iwe.u.mode = IW_MODE_INFRA;
2463 iwe.len = IW_EV_UINT_LEN; 2464 iwe.len = IW_EV_UINT_LEN;
2464 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, 2465 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
2465 IW_EV_UINT_LEN); 2466 &iwe, IW_EV_UINT_LEN);
2466 2467
2467 /* Some quality */ 2468 /* Some quality */
2468 memset(&iwe, 0, sizeof(iwe)); 2469 memset(&iwe, 0, sizeof(iwe));
@@ -2477,8 +2478,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
2477 iwe.u.qual.noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence); 2478 iwe.u.qual.noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence);
2478 iwe.u.qual.updated = sta->last_rx_updated; 2479 iwe.u.qual.updated = sta->last_rx_updated;
2479 iwe.len = IW_EV_QUAL_LEN; 2480 iwe.len = IW_EV_QUAL_LEN;
2480 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, 2481 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
2481 IW_EV_QUAL_LEN); 2482 &iwe, IW_EV_QUAL_LEN);
2482 2483
2483#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT 2484#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
2484 if (sta->ap) { 2485 if (sta->ap) {
@@ -2486,8 +2487,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
2486 iwe.cmd = SIOCGIWESSID; 2487 iwe.cmd = SIOCGIWESSID;
2487 iwe.u.data.length = sta->u.ap.ssid_len; 2488 iwe.u.data.length = sta->u.ap.ssid_len;
2488 iwe.u.data.flags = 1; 2489 iwe.u.data.flags = 1;
2489 current_ev = iwe_stream_add_point(current_ev, end_buf, 2490 current_ev = iwe_stream_add_point(info, current_ev,
2490 &iwe, 2491 end_buf, &iwe,
2491 sta->u.ap.ssid); 2492 sta->u.ap.ssid);
2492 2493
2493 memset(&iwe, 0, sizeof(iwe)); 2494 memset(&iwe, 0, sizeof(iwe));
@@ -2497,10 +2498,9 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
2497 IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; 2498 IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
2498 else 2499 else
2499 iwe.u.data.flags = IW_ENCODE_DISABLED; 2500 iwe.u.data.flags = IW_ENCODE_DISABLED;
2500 current_ev = iwe_stream_add_point(current_ev, end_buf, 2501 current_ev = iwe_stream_add_point(info, current_ev,
2501 &iwe, 2502 end_buf, &iwe,
2502 sta->u.ap.ssid 2503 sta->u.ap.ssid);
2503 /* 0 byte memcpy */);
2504 2504
2505 if (sta->u.ap.channel > 0 && 2505 if (sta->u.ap.channel > 0 &&
2506 sta->u.ap.channel <= FREQ_COUNT) { 2506 sta->u.ap.channel <= FREQ_COUNT) {
@@ -2510,7 +2510,7 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
2510 * 100000; 2510 * 100000;
2511 iwe.u.freq.e = 1; 2511 iwe.u.freq.e = 1;
2512 current_ev = iwe_stream_add_event( 2512 current_ev = iwe_stream_add_event(
2513 current_ev, end_buf, &iwe, 2513 info, current_ev, end_buf, &iwe,
2514 IW_EV_FREQ_LEN); 2514 IW_EV_FREQ_LEN);
2515 } 2515 }
2516 2516
@@ -2519,8 +2519,8 @@ int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
2519 sprintf(buf, "beacon_interval=%d", 2519 sprintf(buf, "beacon_interval=%d",
2520 sta->listen_interval); 2520 sta->listen_interval);
2521 iwe.u.data.length = strlen(buf); 2521 iwe.u.data.length = strlen(buf);
2522 current_ev = iwe_stream_add_point(current_ev, end_buf, 2522 current_ev = iwe_stream_add_point(info, current_ev,
2523 &iwe, buf); 2523 end_buf, &iwe, buf);
2524 } 2524 }
2525#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ 2525#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
2526 2526
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c
index 0ca0bfeb0ada..ed52d98317cd 100644
--- a/drivers/net/wireless/hostap/hostap_ioctl.c
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -1793,6 +1793,7 @@ static int prism2_ioctl_siwscan(struct net_device *dev,
1793 1793
1794#ifndef PRISM2_NO_STATION_MODES 1794#ifndef PRISM2_NO_STATION_MODES
1795static char * __prism2_translate_scan(local_info_t *local, 1795static char * __prism2_translate_scan(local_info_t *local,
1796 struct iw_request_info *info,
1796 struct hfa384x_hostscan_result *scan, 1797 struct hfa384x_hostscan_result *scan,
1797 struct hostap_bss_info *bss, 1798 struct hostap_bss_info *bss,
1798 char *current_ev, char *end_buf) 1799 char *current_ev, char *end_buf)
@@ -1823,7 +1824,7 @@ static char * __prism2_translate_scan(local_info_t *local,
1823 iwe.cmd = SIOCGIWAP; 1824 iwe.cmd = SIOCGIWAP;
1824 iwe.u.ap_addr.sa_family = ARPHRD_ETHER; 1825 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
1825 memcpy(iwe.u.ap_addr.sa_data, bssid, ETH_ALEN); 1826 memcpy(iwe.u.ap_addr.sa_data, bssid, ETH_ALEN);
1826 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, 1827 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
1827 IW_EV_ADDR_LEN); 1828 IW_EV_ADDR_LEN);
1828 1829
1829 /* Other entries will be displayed in the order we give them */ 1830 /* Other entries will be displayed in the order we give them */
@@ -1832,7 +1833,8 @@ static char * __prism2_translate_scan(local_info_t *local,
1832 iwe.cmd = SIOCGIWESSID; 1833 iwe.cmd = SIOCGIWESSID;
1833 iwe.u.data.length = ssid_len; 1834 iwe.u.data.length = ssid_len;
1834 iwe.u.data.flags = 1; 1835 iwe.u.data.flags = 1;
1835 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, ssid); 1836 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
1837 &iwe, ssid);
1836 1838
1837 memset(&iwe, 0, sizeof(iwe)); 1839 memset(&iwe, 0, sizeof(iwe));
1838 iwe.cmd = SIOCGIWMODE; 1840 iwe.cmd = SIOCGIWMODE;
@@ -1847,8 +1849,8 @@ static char * __prism2_translate_scan(local_info_t *local,
1847 iwe.u.mode = IW_MODE_MASTER; 1849 iwe.u.mode = IW_MODE_MASTER;
1848 else 1850 else
1849 iwe.u.mode = IW_MODE_ADHOC; 1851 iwe.u.mode = IW_MODE_ADHOC;
1850 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, 1852 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
1851 IW_EV_UINT_LEN); 1853 &iwe, IW_EV_UINT_LEN);
1852 } 1854 }
1853 1855
1854 memset(&iwe, 0, sizeof(iwe)); 1856 memset(&iwe, 0, sizeof(iwe));
@@ -1864,8 +1866,8 @@ static char * __prism2_translate_scan(local_info_t *local,
1864 if (chan > 0) { 1866 if (chan > 0) {
1865 iwe.u.freq.m = freq_list[chan - 1] * 100000; 1867 iwe.u.freq.m = freq_list[chan - 1] * 100000;
1866 iwe.u.freq.e = 1; 1868 iwe.u.freq.e = 1;
1867 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, 1869 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
1868 IW_EV_FREQ_LEN); 1870 &iwe, IW_EV_FREQ_LEN);
1869 } 1871 }
1870 1872
1871 if (scan) { 1873 if (scan) {
@@ -1884,8 +1886,8 @@ static char * __prism2_translate_scan(local_info_t *local,
1884 | IW_QUAL_NOISE_UPDATED 1886 | IW_QUAL_NOISE_UPDATED
1885 | IW_QUAL_QUAL_INVALID 1887 | IW_QUAL_QUAL_INVALID
1886 | IW_QUAL_DBM; 1888 | IW_QUAL_DBM;
1887 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, 1889 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
1888 IW_EV_QUAL_LEN); 1890 &iwe, IW_EV_QUAL_LEN);
1889 } 1891 }
1890 1892
1891 memset(&iwe, 0, sizeof(iwe)); 1893 memset(&iwe, 0, sizeof(iwe));
@@ -1895,13 +1897,13 @@ static char * __prism2_translate_scan(local_info_t *local,
1895 else 1897 else
1896 iwe.u.data.flags = IW_ENCODE_DISABLED; 1898 iwe.u.data.flags = IW_ENCODE_DISABLED;
1897 iwe.u.data.length = 0; 1899 iwe.u.data.length = 0;
1898 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, ""); 1900 current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, "");
1899 1901
1900 /* TODO: add SuppRates into BSS table */ 1902 /* TODO: add SuppRates into BSS table */
1901 if (scan) { 1903 if (scan) {
1902 memset(&iwe, 0, sizeof(iwe)); 1904 memset(&iwe, 0, sizeof(iwe));
1903 iwe.cmd = SIOCGIWRATE; 1905 iwe.cmd = SIOCGIWRATE;
1904 current_val = current_ev + IW_EV_LCP_LEN; 1906 current_val = current_ev + iwe_stream_lcp_len(info);
1905 pos = scan->sup_rates; 1907 pos = scan->sup_rates;
1906 for (i = 0; i < sizeof(scan->sup_rates); i++) { 1908 for (i = 0; i < sizeof(scan->sup_rates); i++) {
1907 if (pos[i] == 0) 1909 if (pos[i] == 0)
@@ -1909,11 +1911,11 @@ static char * __prism2_translate_scan(local_info_t *local,
1909 /* Bit rate given in 500 kb/s units (+ 0x80) */ 1911 /* Bit rate given in 500 kb/s units (+ 0x80) */
1910 iwe.u.bitrate.value = ((pos[i] & 0x7f) * 500000); 1912 iwe.u.bitrate.value = ((pos[i] & 0x7f) * 500000);
1911 current_val = iwe_stream_add_value( 1913 current_val = iwe_stream_add_value(
1912 current_ev, current_val, end_buf, &iwe, 1914 info, current_ev, current_val, end_buf, &iwe,
1913 IW_EV_PARAM_LEN); 1915 IW_EV_PARAM_LEN);
1914 } 1916 }
1915 /* Check if we added any event */ 1917 /* Check if we added any event */
1916 if ((current_val - current_ev) > IW_EV_LCP_LEN) 1918 if ((current_val - current_ev) > iwe_stream_lcp_len(info))
1917 current_ev = current_val; 1919 current_ev = current_val;
1918 } 1920 }
1919 1921
@@ -1924,15 +1926,15 @@ static char * __prism2_translate_scan(local_info_t *local,
1924 iwe.cmd = IWEVCUSTOM; 1926 iwe.cmd = IWEVCUSTOM;
1925 sprintf(buf, "bcn_int=%d", le16_to_cpu(scan->beacon_interval)); 1927 sprintf(buf, "bcn_int=%d", le16_to_cpu(scan->beacon_interval));
1926 iwe.u.data.length = strlen(buf); 1928 iwe.u.data.length = strlen(buf);
1927 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, 1929 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
1928 buf); 1930 &iwe, buf);
1929 1931
1930 memset(&iwe, 0, sizeof(iwe)); 1932 memset(&iwe, 0, sizeof(iwe));
1931 iwe.cmd = IWEVCUSTOM; 1933 iwe.cmd = IWEVCUSTOM;
1932 sprintf(buf, "resp_rate=%d", le16_to_cpu(scan->rate)); 1934 sprintf(buf, "resp_rate=%d", le16_to_cpu(scan->rate));
1933 iwe.u.data.length = strlen(buf); 1935 iwe.u.data.length = strlen(buf);
1934 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, 1936 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
1935 buf); 1937 &iwe, buf);
1936 1938
1937 if (local->last_scan_type == PRISM2_HOSTSCAN && 1939 if (local->last_scan_type == PRISM2_HOSTSCAN &&
1938 (capabilities & WLAN_CAPABILITY_IBSS)) { 1940 (capabilities & WLAN_CAPABILITY_IBSS)) {
@@ -1940,8 +1942,8 @@ static char * __prism2_translate_scan(local_info_t *local,
1940 iwe.cmd = IWEVCUSTOM; 1942 iwe.cmd = IWEVCUSTOM;
1941 sprintf(buf, "atim=%d", le16_to_cpu(scan->atim)); 1943 sprintf(buf, "atim=%d", le16_to_cpu(scan->atim));
1942 iwe.u.data.length = strlen(buf); 1944 iwe.u.data.length = strlen(buf);
1943 current_ev = iwe_stream_add_point(current_ev, end_buf, 1945 current_ev = iwe_stream_add_point(info, current_ev,
1944 &iwe, buf); 1946 end_buf, &iwe, buf);
1945 } 1947 }
1946 } 1948 }
1947 kfree(buf); 1949 kfree(buf);
@@ -1950,16 +1952,16 @@ static char * __prism2_translate_scan(local_info_t *local,
1950 memset(&iwe, 0, sizeof(iwe)); 1952 memset(&iwe, 0, sizeof(iwe));
1951 iwe.cmd = IWEVGENIE; 1953 iwe.cmd = IWEVGENIE;
1952 iwe.u.data.length = bss->wpa_ie_len; 1954 iwe.u.data.length = bss->wpa_ie_len;
1953 current_ev = iwe_stream_add_point( 1955 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
1954 current_ev, end_buf, &iwe, bss->wpa_ie); 1956 &iwe, bss->wpa_ie);
1955 } 1957 }
1956 1958
1957 if (bss && bss->rsn_ie_len > 0 && bss->rsn_ie_len <= MAX_WPA_IE_LEN) { 1959 if (bss && bss->rsn_ie_len > 0 && bss->rsn_ie_len <= MAX_WPA_IE_LEN) {
1958 memset(&iwe, 0, sizeof(iwe)); 1960 memset(&iwe, 0, sizeof(iwe));
1959 iwe.cmd = IWEVGENIE; 1961 iwe.cmd = IWEVGENIE;
1960 iwe.u.data.length = bss->rsn_ie_len; 1962 iwe.u.data.length = bss->rsn_ie_len;
1961 current_ev = iwe_stream_add_point( 1963 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
1962 current_ev, end_buf, &iwe, bss->rsn_ie); 1964 &iwe, bss->rsn_ie);
1963 } 1965 }
1964 1966
1965 return current_ev; 1967 return current_ev;
@@ -1969,6 +1971,7 @@ static char * __prism2_translate_scan(local_info_t *local,
1969/* Translate scan data returned from the card to a card independant 1971/* Translate scan data returned from the card to a card independant
1970 * format that the Wireless Tools will understand - Jean II */ 1972 * format that the Wireless Tools will understand - Jean II */
1971static inline int prism2_translate_scan(local_info_t *local, 1973static inline int prism2_translate_scan(local_info_t *local,
1974 struct iw_request_info *info,
1972 char *buffer, int buflen) 1975 char *buffer, int buflen)
1973{ 1976{
1974 struct hfa384x_hostscan_result *scan; 1977 struct hfa384x_hostscan_result *scan;
@@ -1999,13 +2002,14 @@ static inline int prism2_translate_scan(local_info_t *local,
1999 if (memcmp(bss->bssid, scan->bssid, ETH_ALEN) == 0) { 2002 if (memcmp(bss->bssid, scan->bssid, ETH_ALEN) == 0) {
2000 bss->included = 1; 2003 bss->included = 1;
2001 current_ev = __prism2_translate_scan( 2004 current_ev = __prism2_translate_scan(
2002 local, scan, bss, current_ev, end_buf); 2005 local, info, scan, bss, current_ev,
2006 end_buf);
2003 found++; 2007 found++;
2004 } 2008 }
2005 } 2009 }
2006 if (!found) { 2010 if (!found) {
2007 current_ev = __prism2_translate_scan( 2011 current_ev = __prism2_translate_scan(
2008 local, scan, NULL, current_ev, end_buf); 2012 local, info, scan, NULL, current_ev, end_buf);
2009 } 2013 }
2010 /* Check if there is space for one more entry */ 2014 /* Check if there is space for one more entry */
2011 if ((end_buf - current_ev) <= IW_EV_ADDR_LEN) { 2015 if ((end_buf - current_ev) <= IW_EV_ADDR_LEN) {
@@ -2023,7 +2027,7 @@ static inline int prism2_translate_scan(local_info_t *local,
2023 bss = list_entry(ptr, struct hostap_bss_info, list); 2027 bss = list_entry(ptr, struct hostap_bss_info, list);
2024 if (bss->included) 2028 if (bss->included)
2025 continue; 2029 continue;
2026 current_ev = __prism2_translate_scan(local, NULL, bss, 2030 current_ev = __prism2_translate_scan(local, info, NULL, bss,
2027 current_ev, end_buf); 2031 current_ev, end_buf);
2028 /* Check if there is space for one more entry */ 2032 /* Check if there is space for one more entry */
2029 if ((end_buf - current_ev) <= IW_EV_ADDR_LEN) { 2033 if ((end_buf - current_ev) <= IW_EV_ADDR_LEN) {
@@ -2070,7 +2074,7 @@ static inline int prism2_ioctl_giwscan_sta(struct net_device *dev,
2070 } 2074 }
2071 local->scan_timestamp = 0; 2075 local->scan_timestamp = 0;
2072 2076
2073 res = prism2_translate_scan(local, extra, data->length); 2077 res = prism2_translate_scan(local, info, extra, data->length);
2074 2078
2075 if (res >= 0) { 2079 if (res >= 0) {
2076 data->length = res; 2080 data->length = res;
@@ -2103,7 +2107,7 @@ static int prism2_ioctl_giwscan(struct net_device *dev,
2103 * Jean II */ 2107 * Jean II */
2104 2108
2105 /* Translate to WE format */ 2109 /* Translate to WE format */
2106 res = prism2_ap_translate_scan(dev, extra); 2110 res = prism2_ap_translate_scan(dev, info, extra);
2107 if (res >= 0) { 2111 if (res >= 0) {
2108 printk(KERN_DEBUG "Scan result translation succeeded " 2112 printk(KERN_DEBUG "Scan result translation succeeded "
2109 "(length=%d)\n", res); 2113 "(length=%d)\n", res);
diff --git a/drivers/net/wireless/libertas/scan.c b/drivers/net/wireless/libertas/scan.c
index d448c9702a0f..343ed38f772d 100644
--- a/drivers/net/wireless/libertas/scan.c
+++ b/drivers/net/wireless/libertas/scan.c
@@ -776,8 +776,9 @@ out:
776#define MAX_CUSTOM_LEN 64 776#define MAX_CUSTOM_LEN 64
777 777
778static inline char *lbs_translate_scan(struct lbs_private *priv, 778static inline char *lbs_translate_scan(struct lbs_private *priv,
779 char *start, char *stop, 779 struct iw_request_info *info,
780 struct bss_descriptor *bss) 780 char *start, char *stop,
781 struct bss_descriptor *bss)
781{ 782{
782 struct chan_freq_power *cfp; 783 struct chan_freq_power *cfp;
783 char *current_val; /* For rates */ 784 char *current_val; /* For rates */
@@ -801,24 +802,24 @@ static inline char *lbs_translate_scan(struct lbs_private *priv,
801 iwe.cmd = SIOCGIWAP; 802 iwe.cmd = SIOCGIWAP;
802 iwe.u.ap_addr.sa_family = ARPHRD_ETHER; 803 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
803 memcpy(iwe.u.ap_addr.sa_data, &bss->bssid, ETH_ALEN); 804 memcpy(iwe.u.ap_addr.sa_data, &bss->bssid, ETH_ALEN);
804 start = iwe_stream_add_event(start, stop, &iwe, IW_EV_ADDR_LEN); 805 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
805 806
806 /* SSID */ 807 /* SSID */
807 iwe.cmd = SIOCGIWESSID; 808 iwe.cmd = SIOCGIWESSID;
808 iwe.u.data.flags = 1; 809 iwe.u.data.flags = 1;
809 iwe.u.data.length = min((uint32_t) bss->ssid_len, (uint32_t) IW_ESSID_MAX_SIZE); 810 iwe.u.data.length = min((uint32_t) bss->ssid_len, (uint32_t) IW_ESSID_MAX_SIZE);
810 start = iwe_stream_add_point(start, stop, &iwe, bss->ssid); 811 start = iwe_stream_add_point(info, start, stop, &iwe, bss->ssid);
811 812
812 /* Mode */ 813 /* Mode */
813 iwe.cmd = SIOCGIWMODE; 814 iwe.cmd = SIOCGIWMODE;
814 iwe.u.mode = bss->mode; 815 iwe.u.mode = bss->mode;
815 start = iwe_stream_add_event(start, stop, &iwe, IW_EV_UINT_LEN); 816 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_UINT_LEN);
816 817
817 /* Frequency */ 818 /* Frequency */
818 iwe.cmd = SIOCGIWFREQ; 819 iwe.cmd = SIOCGIWFREQ;
819 iwe.u.freq.m = (long)cfp->freq * 100000; 820 iwe.u.freq.m = (long)cfp->freq * 100000;
820 iwe.u.freq.e = 1; 821 iwe.u.freq.e = 1;
821 start = iwe_stream_add_event(start, stop, &iwe, IW_EV_FREQ_LEN); 822 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN);
822 823
823 /* Add quality statistics */ 824 /* Add quality statistics */
824 iwe.cmd = IWEVQUAL; 825 iwe.cmd = IWEVQUAL;
@@ -852,7 +853,7 @@ static inline char *lbs_translate_scan(struct lbs_private *priv,
852 nf = priv->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE; 853 nf = priv->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
853 iwe.u.qual.level = CAL_RSSI(snr, nf); 854 iwe.u.qual.level = CAL_RSSI(snr, nf);
854 } 855 }
855 start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN); 856 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
856 857
857 /* Add encryption capability */ 858 /* Add encryption capability */
858 iwe.cmd = SIOCGIWENCODE; 859 iwe.cmd = SIOCGIWENCODE;
@@ -862,9 +863,9 @@ static inline char *lbs_translate_scan(struct lbs_private *priv,
862 iwe.u.data.flags = IW_ENCODE_DISABLED; 863 iwe.u.data.flags = IW_ENCODE_DISABLED;
863 } 864 }
864 iwe.u.data.length = 0; 865 iwe.u.data.length = 0;
865 start = iwe_stream_add_point(start, stop, &iwe, bss->ssid); 866 start = iwe_stream_add_point(info, start, stop, &iwe, bss->ssid);
866 867
867 current_val = start + IW_EV_LCP_LEN; 868 current_val = start + iwe_stream_lcp_len(info);
868 869
869 iwe.cmd = SIOCGIWRATE; 870 iwe.cmd = SIOCGIWRATE;
870 iwe.u.bitrate.fixed = 0; 871 iwe.u.bitrate.fixed = 0;
@@ -874,19 +875,19 @@ static inline char *lbs_translate_scan(struct lbs_private *priv,
874 for (j = 0; bss->rates[j] && (j < sizeof(bss->rates)); j++) { 875 for (j = 0; bss->rates[j] && (j < sizeof(bss->rates)); j++) {
875 /* Bit rate given in 500 kb/s units */ 876 /* Bit rate given in 500 kb/s units */
876 iwe.u.bitrate.value = bss->rates[j] * 500000; 877 iwe.u.bitrate.value = bss->rates[j] * 500000;
877 current_val = iwe_stream_add_value(start, current_val, 878 current_val = iwe_stream_add_value(info, start, current_val,
878 stop, &iwe, IW_EV_PARAM_LEN); 879 stop, &iwe, IW_EV_PARAM_LEN);
879 } 880 }
880 if ((bss->mode == IW_MODE_ADHOC) && priv->adhoccreate 881 if ((bss->mode == IW_MODE_ADHOC) && priv->adhoccreate
881 && !lbs_ssid_cmp(priv->curbssparams.ssid, 882 && !lbs_ssid_cmp(priv->curbssparams.ssid,
882 priv->curbssparams.ssid_len, 883 priv->curbssparams.ssid_len,
883 bss->ssid, bss->ssid_len)) { 884 bss->ssid, bss->ssid_len)) {
884 iwe.u.bitrate.value = 22 * 500000; 885 iwe.u.bitrate.value = 22 * 500000;
885 current_val = iwe_stream_add_value(start, current_val, 886 current_val = iwe_stream_add_value(info, start, current_val,
886 stop, &iwe, IW_EV_PARAM_LEN); 887 stop, &iwe, IW_EV_PARAM_LEN);
887 } 888 }
888 /* Check if we added any event */ 889 /* Check if we added any event */
889 if((current_val - start) > IW_EV_LCP_LEN) 890 if ((current_val - start) > iwe_stream_lcp_len(info))
890 start = current_val; 891 start = current_val;
891 892
892 memset(&iwe, 0, sizeof(iwe)); 893 memset(&iwe, 0, sizeof(iwe));
@@ -895,7 +896,7 @@ static inline char *lbs_translate_scan(struct lbs_private *priv,
895 memcpy(buf, bss->wpa_ie, bss->wpa_ie_len); 896 memcpy(buf, bss->wpa_ie, bss->wpa_ie_len);
896 iwe.cmd = IWEVGENIE; 897 iwe.cmd = IWEVGENIE;
897 iwe.u.data.length = bss->wpa_ie_len; 898 iwe.u.data.length = bss->wpa_ie_len;
898 start = iwe_stream_add_point(start, stop, &iwe, buf); 899 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
899 } 900 }
900 901
901 memset(&iwe, 0, sizeof(iwe)); 902 memset(&iwe, 0, sizeof(iwe));
@@ -904,7 +905,7 @@ static inline char *lbs_translate_scan(struct lbs_private *priv,
904 memcpy(buf, bss->rsn_ie, bss->rsn_ie_len); 905 memcpy(buf, bss->rsn_ie, bss->rsn_ie_len);
905 iwe.cmd = IWEVGENIE; 906 iwe.cmd = IWEVGENIE;
906 iwe.u.data.length = bss->rsn_ie_len; 907 iwe.u.data.length = bss->rsn_ie_len;
907 start = iwe_stream_add_point(start, stop, &iwe, buf); 908 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
908 } 909 }
909 910
910 if (bss->mesh) { 911 if (bss->mesh) {
@@ -915,7 +916,8 @@ static inline char *lbs_translate_scan(struct lbs_private *priv,
915 p += snprintf(p, MAX_CUSTOM_LEN, "mesh-type: olpc"); 916 p += snprintf(p, MAX_CUSTOM_LEN, "mesh-type: olpc");
916 iwe.u.data.length = p - custom; 917 iwe.u.data.length = p - custom;
917 if (iwe.u.data.length) 918 if (iwe.u.data.length)
918 start = iwe_stream_add_point(start, stop, &iwe, custom); 919 start = iwe_stream_add_point(info, start, stop,
920 &iwe, custom);
919 } 921 }
920 922
921out: 923out:
@@ -1036,7 +1038,7 @@ int lbs_get_scan(struct net_device *dev, struct iw_request_info *info,
1036 } 1038 }
1037 1039
1038 /* Translate to WE format this entry */ 1040 /* Translate to WE format this entry */
1039 next_ev = lbs_translate_scan(priv, ev, stop, iter_bss); 1041 next_ev = lbs_translate_scan(priv, info, ev, stop, iter_bss);
1040 if (next_ev == NULL) 1042 if (next_ev == NULL)
1041 continue; 1043 continue;
1042 ev = next_ev; 1044 ev = next_ev;
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index 6d13a0d15a0c..b047306bf386 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -4046,6 +4046,7 @@ static int orinoco_ioctl_setscan(struct net_device *dev,
4046 * format that the Wireless Tools will understand - Jean II 4046 * format that the Wireless Tools will understand - Jean II
4047 * Return message length or -errno for fatal errors */ 4047 * Return message length or -errno for fatal errors */
4048static inline char *orinoco_translate_scan(struct net_device *dev, 4048static inline char *orinoco_translate_scan(struct net_device *dev,
4049 struct iw_request_info *info,
4049 char *current_ev, 4050 char *current_ev,
4050 char *end_buf, 4051 char *end_buf,
4051 union hermes_scan_info *bss, 4052 union hermes_scan_info *bss,
@@ -4062,7 +4063,8 @@ static inline char *orinoco_translate_scan(struct net_device *dev,
4062 iwe.cmd = SIOCGIWAP; 4063 iwe.cmd = SIOCGIWAP;
4063 iwe.u.ap_addr.sa_family = ARPHRD_ETHER; 4064 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
4064 memcpy(iwe.u.ap_addr.sa_data, bss->a.bssid, ETH_ALEN); 4065 memcpy(iwe.u.ap_addr.sa_data, bss->a.bssid, ETH_ALEN);
4065 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN); 4066 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
4067 &iwe, IW_EV_ADDR_LEN);
4066 4068
4067 /* Other entries will be displayed in the order we give them */ 4069 /* Other entries will be displayed in the order we give them */
4068 4070
@@ -4072,7 +4074,8 @@ static inline char *orinoco_translate_scan(struct net_device *dev,
4072 iwe.u.data.length = 32; 4074 iwe.u.data.length = 32;
4073 iwe.cmd = SIOCGIWESSID; 4075 iwe.cmd = SIOCGIWESSID;
4074 iwe.u.data.flags = 1; 4076 iwe.u.data.flags = 1;
4075 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->a.essid); 4077 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4078 &iwe, bss->a.essid);
4076 4079
4077 /* Add mode */ 4080 /* Add mode */
4078 iwe.cmd = SIOCGIWMODE; 4081 iwe.cmd = SIOCGIWMODE;
@@ -4082,7 +4085,8 @@ static inline char *orinoco_translate_scan(struct net_device *dev,
4082 iwe.u.mode = IW_MODE_MASTER; 4085 iwe.u.mode = IW_MODE_MASTER;
4083 else 4086 else
4084 iwe.u.mode = IW_MODE_ADHOC; 4087 iwe.u.mode = IW_MODE_ADHOC;
4085 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_UINT_LEN); 4088 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
4089 &iwe, IW_EV_UINT_LEN);
4086 } 4090 }
4087 4091
4088 channel = bss->s.channel; 4092 channel = bss->s.channel;
@@ -4091,7 +4095,7 @@ static inline char *orinoco_translate_scan(struct net_device *dev,
4091 iwe.cmd = SIOCGIWFREQ; 4095 iwe.cmd = SIOCGIWFREQ;
4092 iwe.u.freq.m = channel_frequency[channel-1] * 100000; 4096 iwe.u.freq.m = channel_frequency[channel-1] * 100000;
4093 iwe.u.freq.e = 1; 4097 iwe.u.freq.e = 1;
4094 current_ev = iwe_stream_add_event(current_ev, end_buf, 4098 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
4095 &iwe, IW_EV_FREQ_LEN); 4099 &iwe, IW_EV_FREQ_LEN);
4096 } 4100 }
4097 4101
@@ -4106,7 +4110,8 @@ static inline char *orinoco_translate_scan(struct net_device *dev,
4106 iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise; 4110 iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise;
4107 else 4111 else
4108 iwe.u.qual.qual = 0; 4112 iwe.u.qual.qual = 0;
4109 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN); 4113 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
4114 &iwe, IW_EV_QUAL_LEN);
4110 4115
4111 /* Add encryption capability */ 4116 /* Add encryption capability */
4112 iwe.cmd = SIOCGIWENCODE; 4117 iwe.cmd = SIOCGIWENCODE;
@@ -4115,7 +4120,8 @@ static inline char *orinoco_translate_scan(struct net_device *dev,
4115 else 4120 else
4116 iwe.u.data.flags = IW_ENCODE_DISABLED; 4121 iwe.u.data.flags = IW_ENCODE_DISABLED;
4117 iwe.u.data.length = 0; 4122 iwe.u.data.length = 0;
4118 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->a.essid); 4123 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4124 &iwe, bss->a.essid);
4119 4125
4120 /* Add EXTRA: Age to display seconds since last beacon/probe response 4126 /* Add EXTRA: Age to display seconds since last beacon/probe response
4121 * for given network. */ 4127 * for given network. */
@@ -4126,11 +4132,12 @@ static inline char *orinoco_translate_scan(struct net_device *dev,
4126 jiffies_to_msecs(jiffies - last_scanned)); 4132 jiffies_to_msecs(jiffies - last_scanned));
4127 iwe.u.data.length = p - custom; 4133 iwe.u.data.length = p - custom;
4128 if (iwe.u.data.length) 4134 if (iwe.u.data.length)
4129 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, custom); 4135 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4136 &iwe, custom);
4130 4137
4131 /* Bit rate is not available in Lucent/Agere firmwares */ 4138 /* Bit rate is not available in Lucent/Agere firmwares */
4132 if (priv->firmware_type != FIRMWARE_TYPE_AGERE) { 4139 if (priv->firmware_type != FIRMWARE_TYPE_AGERE) {
4133 char *current_val = current_ev + IW_EV_LCP_LEN; 4140 char *current_val = current_ev + iwe_stream_lcp_len(info);
4134 int i; 4141 int i;
4135 int step; 4142 int step;
4136 4143
@@ -4149,12 +4156,13 @@ static inline char *orinoco_translate_scan(struct net_device *dev,
4149 break; 4156 break;
4150 /* Bit rate given in 500 kb/s units (+ 0x80) */ 4157 /* Bit rate given in 500 kb/s units (+ 0x80) */
4151 iwe.u.bitrate.value = ((bss->p.rates[i] & 0x7f) * 500000); 4158 iwe.u.bitrate.value = ((bss->p.rates[i] & 0x7f) * 500000);
4152 current_val = iwe_stream_add_value(current_ev, current_val, 4159 current_val = iwe_stream_add_value(info, current_ev,
4160 current_val,
4153 end_buf, &iwe, 4161 end_buf, &iwe,
4154 IW_EV_PARAM_LEN); 4162 IW_EV_PARAM_LEN);
4155 } 4163 }
4156 /* Check if we added any event */ 4164 /* Check if we added any event */
4157 if ((current_val - current_ev) > IW_EV_LCP_LEN) 4165 if ((current_val - current_ev) > iwe_stream_lcp_len(info))
4158 current_ev = current_val; 4166 current_ev = current_val;
4159 } 4167 }
4160 4168
@@ -4190,7 +4198,7 @@ static int orinoco_ioctl_getscan(struct net_device *dev,
4190 4198
4191 list_for_each_entry(bss, &priv->bss_list, list) { 4199 list_for_each_entry(bss, &priv->bss_list, list) {
4192 /* Translate to WE format this entry */ 4200 /* Translate to WE format this entry */
4193 current_ev = orinoco_translate_scan(dev, current_ev, 4201 current_ev = orinoco_translate_scan(dev, info, current_ev,
4194 extra + srq->length, 4202 extra + srq->length,
4195 &bss->bss, 4203 &bss->bss,
4196 bss->last_scanned); 4204 bss->last_scanned);
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
index 5b375b289036..97fa14e0a479 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.c
+++ b/drivers/net/wireless/prism54/isl_ioctl.c
@@ -571,8 +571,9 @@ prism54_set_scan(struct net_device *dev, struct iw_request_info *info,
571 */ 571 */
572 572
573static char * 573static char *
574prism54_translate_bss(struct net_device *ndev, char *current_ev, 574prism54_translate_bss(struct net_device *ndev, struct iw_request_info *info,
575 char *end_buf, struct obj_bss *bss, char noise) 575 char *current_ev, char *end_buf, struct obj_bss *bss,
576 char noise)
576{ 577{
577 struct iw_event iwe; /* Temporary buffer */ 578 struct iw_event iwe; /* Temporary buffer */
578 short cap; 579 short cap;
@@ -584,8 +585,8 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
584 memcpy(iwe.u.ap_addr.sa_data, bss->address, 6); 585 memcpy(iwe.u.ap_addr.sa_data, bss->address, 6);
585 iwe.u.ap_addr.sa_family = ARPHRD_ETHER; 586 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
586 iwe.cmd = SIOCGIWAP; 587 iwe.cmd = SIOCGIWAP;
587 current_ev = 588 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
588 iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN); 589 &iwe, IW_EV_ADDR_LEN);
589 590
590 /* The following entries will be displayed in the same order we give them */ 591 /* The following entries will be displayed in the same order we give them */
591 592
@@ -593,7 +594,7 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
593 iwe.u.data.length = bss->ssid.length; 594 iwe.u.data.length = bss->ssid.length;
594 iwe.u.data.flags = 1; 595 iwe.u.data.flags = 1;
595 iwe.cmd = SIOCGIWESSID; 596 iwe.cmd = SIOCGIWESSID;
596 current_ev = iwe_stream_add_point(current_ev, end_buf, 597 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
597 &iwe, bss->ssid.octets); 598 &iwe, bss->ssid.octets);
598 599
599 /* Capabilities */ 600 /* Capabilities */
@@ -610,9 +611,8 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
610 iwe.u.mode = IW_MODE_ADHOC; 611 iwe.u.mode = IW_MODE_ADHOC;
611 iwe.cmd = SIOCGIWMODE; 612 iwe.cmd = SIOCGIWMODE;
612 if (iwe.u.mode) 613 if (iwe.u.mode)
613 current_ev = 614 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
614 iwe_stream_add_event(current_ev, end_buf, &iwe, 615 &iwe, IW_EV_UINT_LEN);
615 IW_EV_UINT_LEN);
616 616
617 /* Encryption capability */ 617 /* Encryption capability */
618 if (cap & CAP_CRYPT) 618 if (cap & CAP_CRYPT)
@@ -621,14 +621,15 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
621 iwe.u.data.flags = IW_ENCODE_DISABLED; 621 iwe.u.data.flags = IW_ENCODE_DISABLED;
622 iwe.u.data.length = 0; 622 iwe.u.data.length = 0;
623 iwe.cmd = SIOCGIWENCODE; 623 iwe.cmd = SIOCGIWENCODE;
624 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, NULL); 624 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
625 &iwe, NULL);
625 626
626 /* Add frequency. (short) bss->channel is the frequency in MHz */ 627 /* Add frequency. (short) bss->channel is the frequency in MHz */
627 iwe.u.freq.m = bss->channel; 628 iwe.u.freq.m = bss->channel;
628 iwe.u.freq.e = 6; 629 iwe.u.freq.e = 6;
629 iwe.cmd = SIOCGIWFREQ; 630 iwe.cmd = SIOCGIWFREQ;
630 current_ev = 631 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
631 iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN); 632 &iwe, IW_EV_FREQ_LEN);
632 633
633 /* Add quality statistics */ 634 /* Add quality statistics */
634 iwe.u.qual.level = bss->rssi; 635 iwe.u.qual.level = bss->rssi;
@@ -636,20 +637,20 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
636 /* do a simple SNR for quality */ 637 /* do a simple SNR for quality */
637 iwe.u.qual.qual = bss->rssi - noise; 638 iwe.u.qual.qual = bss->rssi - noise;
638 iwe.cmd = IWEVQUAL; 639 iwe.cmd = IWEVQUAL;
639 current_ev = 640 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
640 iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN); 641 &iwe, IW_EV_QUAL_LEN);
641 642
642 /* Add WPA/RSN Information Element, if any */ 643 /* Add WPA/RSN Information Element, if any */
643 wpa_ie_len = prism54_wpa_bss_ie_get(priv, bss->address, wpa_ie); 644 wpa_ie_len = prism54_wpa_bss_ie_get(priv, bss->address, wpa_ie);
644 if (wpa_ie_len > 0) { 645 if (wpa_ie_len > 0) {
645 iwe.cmd = IWEVGENIE; 646 iwe.cmd = IWEVGENIE;
646 iwe.u.data.length = min(wpa_ie_len, (size_t)MAX_WPA_IE_LEN); 647 iwe.u.data.length = min(wpa_ie_len, (size_t)MAX_WPA_IE_LEN);
647 current_ev = iwe_stream_add_point(current_ev, end_buf, 648 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
648 &iwe, wpa_ie); 649 &iwe, wpa_ie);
649 } 650 }
650 /* Do the bitrates */ 651 /* Do the bitrates */
651 { 652 {
652 char * current_val = current_ev + IW_EV_LCP_LEN; 653 char *current_val = current_ev + iwe_stream_lcp_len(info);
653 int i; 654 int i;
654 int mask; 655 int mask;
655 656
@@ -662,14 +663,14 @@ prism54_translate_bss(struct net_device *ndev, char *current_ev,
662 for(i = 0; i < sizeof(scan_rate_list); i++) { 663 for(i = 0; i < sizeof(scan_rate_list); i++) {
663 if(bss->rates & mask) { 664 if(bss->rates & mask) {
664 iwe.u.bitrate.value = (scan_rate_list[i] * 500000); 665 iwe.u.bitrate.value = (scan_rate_list[i] * 500000);
665 current_val = iwe_stream_add_value(current_ev, current_val, 666 current_val = iwe_stream_add_value(
666 end_buf, &iwe, 667 info, current_ev, current_val,
667 IW_EV_PARAM_LEN); 668 end_buf, &iwe, IW_EV_PARAM_LEN);
668 } 669 }
669 mask <<= 1; 670 mask <<= 1;
670 } 671 }
671 /* Check if we added any event */ 672 /* Check if we added any event */
672 if ((current_val - current_ev) > IW_EV_LCP_LEN) 673 if ((current_val - current_ev) > iwe_stream_lcp_len(info))
673 current_ev = current_val; 674 current_ev = current_val;
674 } 675 }
675 676
@@ -710,7 +711,7 @@ prism54_get_scan(struct net_device *ndev, struct iw_request_info *info,
710 711
711 /* ok now, scan the list and translate its info */ 712 /* ok now, scan the list and translate its info */
712 for (i = 0; i < (int) bsslist->nr; i++) { 713 for (i = 0; i < (int) bsslist->nr; i++) {
713 current_ev = prism54_translate_bss(ndev, current_ev, 714 current_ev = prism54_translate_bss(ndev, info, current_ev,
714 extra + dwrq->length, 715 extra + dwrq->length,
715 &(bsslist->bsslist[i]), 716 &(bsslist->bsslist[i]),
716 noise); 717 noise);
@@ -2704,6 +2705,7 @@ prism2_ioctl_scan_req(struct net_device *ndev,
2704 struct prism2_hostapd_param *param) 2705 struct prism2_hostapd_param *param)
2705{ 2706{
2706 islpci_private *priv = netdev_priv(ndev); 2707 islpci_private *priv = netdev_priv(ndev);
2708 struct iw_request_info info;
2707 int i, rvalue; 2709 int i, rvalue;
2708 struct obj_bsslist *bsslist; 2710 struct obj_bsslist *bsslist;
2709 u32 noise = 0; 2711 u32 noise = 0;
@@ -2727,9 +2729,12 @@ prism2_ioctl_scan_req(struct net_device *ndev,
2727 rvalue |= mgt_get_request(priv, DOT11_OID_BSSLIST, 0, NULL, &r); 2729 rvalue |= mgt_get_request(priv, DOT11_OID_BSSLIST, 0, NULL, &r);
2728 bsslist = r.ptr; 2730 bsslist = r.ptr;
2729 2731
2732 info.cmd = PRISM54_HOSTAPD;
2733 info.flags = 0;
2734
2730 /* ok now, scan the list and translate its info */ 2735 /* ok now, scan the list and translate its info */
2731 for (i = 0; i < min(IW_MAX_AP, (int) bsslist->nr); i++) 2736 for (i = 0; i < min(IW_MAX_AP, (int) bsslist->nr); i++)
2732 current_ev = prism54_translate_bss(ndev, current_ev, 2737 current_ev = prism54_translate_bss(ndev, &info, current_ev,
2733 extra + IW_SCAN_MAX_DATA, 2738 extra + IW_SCAN_MAX_DATA,
2734 &(bsslist->bsslist[i]), 2739 &(bsslist->bsslist[i]),
2735 noise); 2740 noise);
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c
index a36d2c85e26e..65c50025c88f 100644
--- a/drivers/net/wireless/rndis_wlan.c
+++ b/drivers/net/wireless/rndis_wlan.c
@@ -1648,7 +1648,9 @@ static int rndis_iw_set_scan(struct net_device *dev,
1648 1648
1649 1649
1650static char *rndis_translate_scan(struct net_device *dev, 1650static char *rndis_translate_scan(struct net_device *dev,
1651 char *cev, char *end_buf, struct ndis_80211_bssid_ex *bssid) 1651 struct iw_request_info *info, char *cev,
1652 char *end_buf,
1653 struct ndis_80211_bssid_ex *bssid)
1652{ 1654{
1653#ifdef DEBUG 1655#ifdef DEBUG
1654 struct usbnet *usbdev = dev->priv; 1656 struct usbnet *usbdev = dev->priv;
@@ -1667,14 +1669,14 @@ static char *rndis_translate_scan(struct net_device *dev,
1667 iwe.cmd = SIOCGIWAP; 1669 iwe.cmd = SIOCGIWAP;
1668 iwe.u.ap_addr.sa_family = ARPHRD_ETHER; 1670 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
1669 memcpy(iwe.u.ap_addr.sa_data, bssid->mac, ETH_ALEN); 1671 memcpy(iwe.u.ap_addr.sa_data, bssid->mac, ETH_ALEN);
1670 cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_ADDR_LEN); 1672 cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_ADDR_LEN);
1671 1673
1672 devdbg(usbdev, "SSID(%d) %s", le32_to_cpu(bssid->ssid.length), 1674 devdbg(usbdev, "SSID(%d) %s", le32_to_cpu(bssid->ssid.length),
1673 bssid->ssid.essid); 1675 bssid->ssid.essid);
1674 iwe.cmd = SIOCGIWESSID; 1676 iwe.cmd = SIOCGIWESSID;
1675 iwe.u.essid.length = le32_to_cpu(bssid->ssid.length); 1677 iwe.u.essid.length = le32_to_cpu(bssid->ssid.length);
1676 iwe.u.essid.flags = 1; 1678 iwe.u.essid.flags = 1;
1677 cev = iwe_stream_add_point(cev, end_buf, &iwe, bssid->ssid.essid); 1679 cev = iwe_stream_add_point(info, cev, end_buf, &iwe, bssid->ssid.essid);
1678 1680
1679 devdbg(usbdev, "MODE %d", le32_to_cpu(bssid->net_infra)); 1681 devdbg(usbdev, "MODE %d", le32_to_cpu(bssid->net_infra));
1680 iwe.cmd = SIOCGIWMODE; 1682 iwe.cmd = SIOCGIWMODE;
@@ -1690,12 +1692,12 @@ static char *rndis_translate_scan(struct net_device *dev,
1690 iwe.u.mode = IW_MODE_AUTO; 1692 iwe.u.mode = IW_MODE_AUTO;
1691 break; 1693 break;
1692 } 1694 }
1693 cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_UINT_LEN); 1695 cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_UINT_LEN);
1694 1696
1695 devdbg(usbdev, "FREQ %d kHz", le32_to_cpu(bssid->config.ds_config)); 1697 devdbg(usbdev, "FREQ %d kHz", le32_to_cpu(bssid->config.ds_config));
1696 iwe.cmd = SIOCGIWFREQ; 1698 iwe.cmd = SIOCGIWFREQ;
1697 dsconfig_to_freq(le32_to_cpu(bssid->config.ds_config), &iwe.u.freq); 1699 dsconfig_to_freq(le32_to_cpu(bssid->config.ds_config), &iwe.u.freq);
1698 cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_FREQ_LEN); 1700 cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_FREQ_LEN);
1699 1701
1700 devdbg(usbdev, "QUAL %d", le32_to_cpu(bssid->rssi)); 1702 devdbg(usbdev, "QUAL %d", le32_to_cpu(bssid->rssi));
1701 iwe.cmd = IWEVQUAL; 1703 iwe.cmd = IWEVQUAL;
@@ -1704,7 +1706,7 @@ static char *rndis_translate_scan(struct net_device *dev,
1704 iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED 1706 iwe.u.qual.updated = IW_QUAL_QUAL_UPDATED
1705 | IW_QUAL_LEVEL_UPDATED 1707 | IW_QUAL_LEVEL_UPDATED
1706 | IW_QUAL_NOISE_INVALID; 1708 | IW_QUAL_NOISE_INVALID;
1707 cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_QUAL_LEN); 1709 cev = iwe_stream_add_event(info, cev, end_buf, &iwe, IW_EV_QUAL_LEN);
1708 1710
1709 devdbg(usbdev, "ENCODE %d", le32_to_cpu(bssid->privacy)); 1711 devdbg(usbdev, "ENCODE %d", le32_to_cpu(bssid->privacy));
1710 iwe.cmd = SIOCGIWENCODE; 1712 iwe.cmd = SIOCGIWENCODE;
@@ -1714,10 +1716,10 @@ static char *rndis_translate_scan(struct net_device *dev,
1714 else 1716 else
1715 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY; 1717 iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
1716 1718
1717 cev = iwe_stream_add_point(cev, end_buf, &iwe, NULL); 1719 cev = iwe_stream_add_point(info, cev, end_buf, &iwe, NULL);
1718 1720
1719 devdbg(usbdev, "RATES:"); 1721 devdbg(usbdev, "RATES:");
1720 current_val = cev + IW_EV_LCP_LEN; 1722 current_val = cev + iwe_stream_lcp_len(info);
1721 iwe.cmd = SIOCGIWRATE; 1723 iwe.cmd = SIOCGIWRATE;
1722 for (i = 0; i < sizeof(bssid->rates); i++) { 1724 for (i = 0; i < sizeof(bssid->rates); i++) {
1723 if (bssid->rates[i] & 0x7f) { 1725 if (bssid->rates[i] & 0x7f) {
@@ -1725,13 +1727,13 @@ static char *rndis_translate_scan(struct net_device *dev,
1725 ((bssid->rates[i] & 0x7f) * 1727 ((bssid->rates[i] & 0x7f) *
1726 500000); 1728 500000);
1727 devdbg(usbdev, " %d", iwe.u.bitrate.value); 1729 devdbg(usbdev, " %d", iwe.u.bitrate.value);
1728 current_val = iwe_stream_add_value(cev, 1730 current_val = iwe_stream_add_value(info, cev,
1729 current_val, end_buf, &iwe, 1731 current_val, end_buf, &iwe,
1730 IW_EV_PARAM_LEN); 1732 IW_EV_PARAM_LEN);
1731 } 1733 }
1732 } 1734 }
1733 1735
1734 if ((current_val - cev) > IW_EV_LCP_LEN) 1736 if ((current_val - cev) > iwe_stream_lcp_len(info))
1735 cev = current_val; 1737 cev = current_val;
1736 1738
1737 beacon = le32_to_cpu(bssid->config.beacon_period); 1739 beacon = le32_to_cpu(bssid->config.beacon_period);
@@ -1739,14 +1741,14 @@ static char *rndis_translate_scan(struct net_device *dev,
1739 iwe.cmd = IWEVCUSTOM; 1741 iwe.cmd = IWEVCUSTOM;
1740 snprintf(sbuf, sizeof(sbuf), "bcn_int=%d", beacon); 1742 snprintf(sbuf, sizeof(sbuf), "bcn_int=%d", beacon);
1741 iwe.u.data.length = strlen(sbuf); 1743 iwe.u.data.length = strlen(sbuf);
1742 cev = iwe_stream_add_point(cev, end_buf, &iwe, sbuf); 1744 cev = iwe_stream_add_point(info, cev, end_buf, &iwe, sbuf);
1743 1745
1744 atim = le32_to_cpu(bssid->config.atim_window); 1746 atim = le32_to_cpu(bssid->config.atim_window);
1745 devdbg(usbdev, "ATIM %d", atim); 1747 devdbg(usbdev, "ATIM %d", atim);
1746 iwe.cmd = IWEVCUSTOM; 1748 iwe.cmd = IWEVCUSTOM;
1747 snprintf(sbuf, sizeof(sbuf), "atim=%u", atim); 1749 snprintf(sbuf, sizeof(sbuf), "atim=%u", atim);
1748 iwe.u.data.length = strlen(sbuf); 1750 iwe.u.data.length = strlen(sbuf);
1749 cev = iwe_stream_add_point(cev, end_buf, &iwe, sbuf); 1751 cev = iwe_stream_add_point(info, cev, end_buf, &iwe, sbuf);
1750 1752
1751 ie = (void *)(bssid->ies + sizeof(struct ndis_80211_fixed_ies)); 1753 ie = (void *)(bssid->ies + sizeof(struct ndis_80211_fixed_ies));
1752 ie_len = min(bssid_len - (int)sizeof(*bssid), 1754 ie_len = min(bssid_len - (int)sizeof(*bssid),
@@ -1760,7 +1762,7 @@ static char *rndis_translate_scan(struct net_device *dev,
1760 (ie->id == MFIE_TYPE_RSN) ? 2 : 1); 1762 (ie->id == MFIE_TYPE_RSN) ? 2 : 1);
1761 iwe.cmd = IWEVGENIE; 1763 iwe.cmd = IWEVGENIE;
1762 iwe.u.data.length = min(ie->len + 2, MAX_WPA_IE_LEN); 1764 iwe.u.data.length = min(ie->len + 2, MAX_WPA_IE_LEN);
1763 cev = iwe_stream_add_point(cev, end_buf, &iwe, 1765 cev = iwe_stream_add_point(info, cev, end_buf, &iwe,
1764 (u8 *)ie); 1766 (u8 *)ie);
1765 } 1767 }
1766 1768
@@ -1803,8 +1805,8 @@ static int rndis_iw_get_scan(struct net_device *dev,
1803 devdbg(usbdev, "SIOCGIWSCAN: %d BSSIDs found", count); 1805 devdbg(usbdev, "SIOCGIWSCAN: %d BSSIDs found", count);
1804 1806
1805 while (count && ((void *)bssid + bssid_len) <= (buf + len)) { 1807 while (count && ((void *)bssid + bssid_len) <= (buf + len)) {
1806 cev = rndis_translate_scan(dev, cev, extra + IW_SCAN_MAX_DATA, 1808 cev = rndis_translate_scan(dev, info, cev,
1807 bssid); 1809 extra + IW_SCAN_MAX_DATA, bssid);
1808 bssid = (void *)bssid + bssid_len; 1810 bssid = (void *)bssid + bssid_len;
1809 bssid_len = le32_to_cpu(bssid->length); 1811 bssid_len = le32_to_cpu(bssid->length);
1810 count--; 1812 count--;
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index 42a36b3f3ff7..377141995e36 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -1624,25 +1624,25 @@ static int wl3501_get_scan(struct net_device *dev, struct iw_request_info *info,
1624 iwe.cmd = SIOCGIWAP; 1624 iwe.cmd = SIOCGIWAP;
1625 iwe.u.ap_addr.sa_family = ARPHRD_ETHER; 1625 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
1626 memcpy(iwe.u.ap_addr.sa_data, this->bss_set[i].bssid, ETH_ALEN); 1626 memcpy(iwe.u.ap_addr.sa_data, this->bss_set[i].bssid, ETH_ALEN);
1627 current_ev = iwe_stream_add_event(current_ev, 1627 current_ev = iwe_stream_add_event(info, current_ev,
1628 extra + IW_SCAN_MAX_DATA, 1628 extra + IW_SCAN_MAX_DATA,
1629 &iwe, IW_EV_ADDR_LEN); 1629 &iwe, IW_EV_ADDR_LEN);
1630 iwe.cmd = SIOCGIWESSID; 1630 iwe.cmd = SIOCGIWESSID;
1631 iwe.u.data.flags = 1; 1631 iwe.u.data.flags = 1;
1632 iwe.u.data.length = this->bss_set[i].ssid.el.len; 1632 iwe.u.data.length = this->bss_set[i].ssid.el.len;
1633 current_ev = iwe_stream_add_point(current_ev, 1633 current_ev = iwe_stream_add_point(info, current_ev,
1634 extra + IW_SCAN_MAX_DATA, 1634 extra + IW_SCAN_MAX_DATA,
1635 &iwe, 1635 &iwe,
1636 this->bss_set[i].ssid.essid); 1636 this->bss_set[i].ssid.essid);
1637 iwe.cmd = SIOCGIWMODE; 1637 iwe.cmd = SIOCGIWMODE;
1638 iwe.u.mode = this->bss_set[i].bss_type; 1638 iwe.u.mode = this->bss_set[i].bss_type;
1639 current_ev = iwe_stream_add_event(current_ev, 1639 current_ev = iwe_stream_add_event(info, current_ev,
1640 extra + IW_SCAN_MAX_DATA, 1640 extra + IW_SCAN_MAX_DATA,
1641 &iwe, IW_EV_UINT_LEN); 1641 &iwe, IW_EV_UINT_LEN);
1642 iwe.cmd = SIOCGIWFREQ; 1642 iwe.cmd = SIOCGIWFREQ;
1643 iwe.u.freq.m = this->bss_set[i].ds_pset.chan; 1643 iwe.u.freq.m = this->bss_set[i].ds_pset.chan;
1644 iwe.u.freq.e = 0; 1644 iwe.u.freq.e = 0;
1645 current_ev = iwe_stream_add_event(current_ev, 1645 current_ev = iwe_stream_add_event(info, current_ev,
1646 extra + IW_SCAN_MAX_DATA, 1646 extra + IW_SCAN_MAX_DATA,
1647 &iwe, IW_EV_FREQ_LEN); 1647 &iwe, IW_EV_FREQ_LEN);
1648 iwe.cmd = SIOCGIWENCODE; 1648 iwe.cmd = SIOCGIWENCODE;
@@ -1651,7 +1651,7 @@ static int wl3501_get_scan(struct net_device *dev, struct iw_request_info *info,
1651 else 1651 else
1652 iwe.u.data.flags = IW_ENCODE_DISABLED; 1652 iwe.u.data.flags = IW_ENCODE_DISABLED;
1653 iwe.u.data.length = 0; 1653 iwe.u.data.length = 0;
1654 current_ev = iwe_stream_add_point(current_ev, 1654 current_ev = iwe_stream_add_point(info, current_ev,
1655 extra + IW_SCAN_MAX_DATA, 1655 extra + IW_SCAN_MAX_DATA,
1656 &iwe, NULL); 1656 &iwe, NULL);
1657 } 1657 }
diff --git a/drivers/net/wireless/zd1201.c b/drivers/net/wireless/zd1201.c
index d5c0c66188ca..07e4d1f73207 100644
--- a/drivers/net/wireless/zd1201.c
+++ b/drivers/net/wireless/zd1201.c
@@ -1152,32 +1152,36 @@ static int zd1201_get_scan(struct net_device *dev,
1152 iwe.cmd = SIOCGIWAP; 1152 iwe.cmd = SIOCGIWAP;
1153 iwe.u.ap_addr.sa_family = ARPHRD_ETHER; 1153 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
1154 memcpy(iwe.u.ap_addr.sa_data, zd->rxdata+i+6, 6); 1154 memcpy(iwe.u.ap_addr.sa_data, zd->rxdata+i+6, 6);
1155 cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_ADDR_LEN); 1155 cev = iwe_stream_add_event(info, cev, end_buf,
1156 &iwe, IW_EV_ADDR_LEN);
1156 1157
1157 iwe.cmd = SIOCGIWESSID; 1158 iwe.cmd = SIOCGIWESSID;
1158 iwe.u.data.length = zd->rxdata[i+16]; 1159 iwe.u.data.length = zd->rxdata[i+16];
1159 iwe.u.data.flags = 1; 1160 iwe.u.data.flags = 1;
1160 cev = iwe_stream_add_point(cev, end_buf, &iwe, zd->rxdata+i+18); 1161 cev = iwe_stream_add_point(info, cev, end_buf,
1162 &iwe, zd->rxdata+i+18);
1161 1163
1162 iwe.cmd = SIOCGIWMODE; 1164 iwe.cmd = SIOCGIWMODE;
1163 if (zd->rxdata[i+14]&0x01) 1165 if (zd->rxdata[i+14]&0x01)
1164 iwe.u.mode = IW_MODE_MASTER; 1166 iwe.u.mode = IW_MODE_MASTER;
1165 else 1167 else
1166 iwe.u.mode = IW_MODE_ADHOC; 1168 iwe.u.mode = IW_MODE_ADHOC;
1167 cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_UINT_LEN); 1169 cev = iwe_stream_add_event(info, cev, end_buf,
1170 &iwe, IW_EV_UINT_LEN);
1168 1171
1169 iwe.cmd = SIOCGIWFREQ; 1172 iwe.cmd = SIOCGIWFREQ;
1170 iwe.u.freq.m = zd->rxdata[i+0]; 1173 iwe.u.freq.m = zd->rxdata[i+0];
1171 iwe.u.freq.e = 0; 1174 iwe.u.freq.e = 0;
1172 cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_FREQ_LEN); 1175 cev = iwe_stream_add_event(info, cev, end_buf,
1176 &iwe, IW_EV_FREQ_LEN);
1173 1177
1174 iwe.cmd = SIOCGIWRATE; 1178 iwe.cmd = SIOCGIWRATE;
1175 iwe.u.bitrate.fixed = 0; 1179 iwe.u.bitrate.fixed = 0;
1176 iwe.u.bitrate.disabled = 0; 1180 iwe.u.bitrate.disabled = 0;
1177 for (j=0; j<10; j++) if (zd->rxdata[i+50+j]) { 1181 for (j=0; j<10; j++) if (zd->rxdata[i+50+j]) {
1178 iwe.u.bitrate.value = (zd->rxdata[i+50+j]&0x7f)*500000; 1182 iwe.u.bitrate.value = (zd->rxdata[i+50+j]&0x7f)*500000;
1179 cev=iwe_stream_add_event(cev, end_buf, &iwe, 1183 cev = iwe_stream_add_event(info, cev, end_buf,
1180 IW_EV_PARAM_LEN); 1184 &iwe, IW_EV_PARAM_LEN);
1181 } 1185 }
1182 1186
1183 iwe.cmd = SIOCGIWENCODE; 1187 iwe.cmd = SIOCGIWENCODE;
@@ -1186,14 +1190,15 @@ static int zd1201_get_scan(struct net_device *dev,
1186 iwe.u.data.flags = IW_ENCODE_ENABLED; 1190 iwe.u.data.flags = IW_ENCODE_ENABLED;
1187 else 1191 else
1188 iwe.u.data.flags = IW_ENCODE_DISABLED; 1192 iwe.u.data.flags = IW_ENCODE_DISABLED;
1189 cev = iwe_stream_add_point(cev, end_buf, &iwe, NULL); 1193 cev = iwe_stream_add_point(info, cev, end_buf, &iwe, NULL);
1190 1194
1191 iwe.cmd = IWEVQUAL; 1195 iwe.cmd = IWEVQUAL;
1192 iwe.u.qual.qual = zd->rxdata[i+4]; 1196 iwe.u.qual.qual = zd->rxdata[i+4];
1193 iwe.u.qual.noise= zd->rxdata[i+2]/10-100; 1197 iwe.u.qual.noise= zd->rxdata[i+2]/10-100;
1194 iwe.u.qual.level = (256+zd->rxdata[i+4]*100)/255-100; 1198 iwe.u.qual.level = (256+zd->rxdata[i+4]*100)/255-100;
1195 iwe.u.qual.updated = 7; 1199 iwe.u.qual.updated = 7;
1196 cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_QUAL_LEN); 1200 cev = iwe_stream_add_event(info, cev, end_buf,
1201 &iwe, IW_EV_QUAL_LEN);
1197 } 1202 }
1198 1203
1199 if (!enabled_save) 1204 if (!enabled_save)
diff --git a/include/linux/wireless.h b/include/linux/wireless.h
index 79d846875825..d7958f9b52cb 100644
--- a/include/linux/wireless.h
+++ b/include/linux/wireless.h
@@ -1113,6 +1113,21 @@ struct iw_event
1113#define IW_EV_POINT_LEN (IW_EV_LCP_LEN + sizeof(struct iw_point) - \ 1113#define IW_EV_POINT_LEN (IW_EV_LCP_LEN + sizeof(struct iw_point) - \
1114 IW_EV_POINT_OFF) 1114 IW_EV_POINT_OFF)
1115 1115
1116#ifdef __KERNEL__
1117#ifdef CONFIG_COMPAT
1118struct __compat_iw_event {
1119 __u16 len; /* Real length of this stuff */
1120 __u16 cmd; /* Wireless IOCTL */
1121 compat_caddr_t pointer;
1122};
1123#define IW_EV_COMPAT_LCP_LEN offsetof(struct __compat_iw_event, pointer)
1124#define IW_EV_COMPAT_POINT_OFF offsetof(struct compat_iw_point, length)
1125#define IW_EV_COMPAT_POINT_LEN \
1126 (IW_EV_COMPAT_LCP_LEN + sizeof(struct compat_iw_point) - \
1127 IW_EV_COMPAT_POINT_OFF)
1128#endif
1129#endif
1130
1116/* Size of the Event prefix when packed in stream */ 1131/* Size of the Event prefix when packed in stream */
1117#define IW_EV_LCP_PK_LEN (4) 1132#define IW_EV_LCP_PK_LEN (4)
1118/* Size of the various events when packed in stream */ 1133/* Size of the various events when packed in stream */
diff --git a/include/net/iw_handler.h b/include/net/iw_handler.h
index c99a8eec84e7..51b9a37de991 100644
--- a/include/net/iw_handler.h
+++ b/include/net/iw_handler.h
@@ -478,105 +478,58 @@ extern void wireless_spy_update(struct net_device * dev,
478 * Function that are so simple that it's more efficient inlining them 478 * Function that are so simple that it's more efficient inlining them
479 */ 479 */
480 480
481/*------------------------------------------------------------------*/ 481static inline int iwe_stream_lcp_len(struct iw_request_info *info)
482/*
483 * Wrapper to add an Wireless Event to a stream of events.
484 */
485static inline char *
486iwe_stream_add_event(char * stream, /* Stream of events */
487 char * ends, /* End of stream */
488 struct iw_event *iwe, /* Payload */
489 int event_len) /* Real size of payload */
490{ 482{
491 /* Check if it's possible */ 483#ifdef CONFIG_COMPAT
492 if(likely((stream + event_len) < ends)) { 484 if (info->flags & IW_REQUEST_FLAG_COMPAT)
493 iwe->len = event_len; 485 return IW_EV_COMPAT_LCP_LEN;
494 /* Beware of alignement issues on 64 bits */ 486#endif
495 memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN); 487 return IW_EV_LCP_LEN;
496 memcpy(stream + IW_EV_LCP_LEN,
497 ((char *) iwe) + IW_EV_LCP_LEN,
498 event_len - IW_EV_LCP_LEN);
499 stream += event_len;
500 }
501 return stream;
502} 488}
503 489
504/*------------------------------------------------------------------*/ 490static inline int iwe_stream_point_len(struct iw_request_info *info)
505/*
506 * Wrapper to add an short Wireless Event containing a pointer to a
507 * stream of events.
508 */
509static inline char *
510iwe_stream_add_point(char * stream, /* Stream of events */
511 char * ends, /* End of stream */
512 struct iw_event *iwe, /* Payload length + flags */
513 char * extra) /* More payload */
514{ 491{
515 int event_len = IW_EV_POINT_LEN + iwe->u.data.length; 492#ifdef CONFIG_COMPAT
516 /* Check if it's possible */ 493 if (info->flags & IW_REQUEST_FLAG_COMPAT)
517 if(likely((stream + event_len) < ends)) { 494 return IW_EV_COMPAT_POINT_LEN;
518 iwe->len = event_len; 495#endif
519 memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN); 496 return IW_EV_POINT_LEN;
520 memcpy(stream + IW_EV_LCP_LEN,
521 ((char *) iwe) + IW_EV_LCP_LEN + IW_EV_POINT_OFF,
522 IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN);
523 memcpy(stream + IW_EV_POINT_LEN, extra, iwe->u.data.length);
524 stream += event_len;
525 }
526 return stream;
527} 497}
528 498
529/*------------------------------------------------------------------*/ 499static inline int iwe_stream_event_len_adjust(struct iw_request_info *info,
530/* 500 int event_len)
531 * Wrapper to add a value to a Wireless Event in a stream of events.
532 * Be careful, this one is tricky to use properly :
533 * At the first run, you need to have (value = event + IW_EV_LCP_LEN).
534 */
535static inline char *
536iwe_stream_add_value(char * event, /* Event in the stream */
537 char * value, /* Value in event */
538 char * ends, /* End of stream */
539 struct iw_event *iwe, /* Payload */
540 int event_len) /* Real size of payload */
541{ 501{
542 /* Don't duplicate LCP */ 502#ifdef CONFIG_COMPAT
543 event_len -= IW_EV_LCP_LEN; 503 if (info->flags & IW_REQUEST_FLAG_COMPAT) {
544 504 event_len -= IW_EV_LCP_LEN;
545 /* Check if it's possible */ 505 event_len += IW_EV_COMPAT_LCP_LEN;
546 if(likely((value + event_len) < ends)) {
547 /* Add new value */
548 memcpy(value, (char *) iwe + IW_EV_LCP_LEN, event_len);
549 value += event_len;
550 /* Patch LCP */
551 iwe->len = value - event;
552 memcpy(event, (char *) iwe, IW_EV_LCP_LEN);
553 } 506 }
554 return value; 507#endif
508
509 return event_len;
555} 510}
556 511
557/*------------------------------------------------------------------*/ 512/*------------------------------------------------------------------*/
558/* 513/*
559 * Wrapper to add an Wireless Event to a stream of events. 514 * Wrapper to add an Wireless Event to a stream of events.
560 * Same as above, with explicit error check...
561 */ 515 */
562static inline char * 516static inline char *
563iwe_stream_check_add_event(char * stream, /* Stream of events */ 517iwe_stream_add_event(struct iw_request_info *info, char *stream, char *ends,
564 char * ends, /* End of stream */ 518 struct iw_event *iwe, int event_len)
565 struct iw_event *iwe, /* Payload */
566 int event_len, /* Size of payload */
567 int * perr) /* Error report */
568{ 519{
569 /* Check if it's possible, set error if not */ 520 int lcp_len = iwe_stream_lcp_len(info);
521
522 event_len = iwe_stream_event_len_adjust(info, event_len);
523
524 /* Check if it's possible */
570 if(likely((stream + event_len) < ends)) { 525 if(likely((stream + event_len) < ends)) {
571 iwe->len = event_len; 526 iwe->len = event_len;
572 /* Beware of alignement issues on 64 bits */ 527 /* Beware of alignement issues on 64 bits */
573 memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN); 528 memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
574 memcpy(stream + IW_EV_LCP_LEN, 529 memcpy(stream + lcp_len, &iwe->u,
575 ((char *) iwe) + IW_EV_LCP_LEN, 530 event_len - lcp_len);
576 event_len - IW_EV_LCP_LEN);
577 stream += event_len; 531 stream += event_len;
578 } else 532 }
579 *perr = -E2BIG;
580 return stream; 533 return stream;
581} 534}
582 535
@@ -584,27 +537,25 @@ iwe_stream_check_add_event(char * stream, /* Stream of events */
584/* 537/*
585 * Wrapper to add an short Wireless Event containing a pointer to a 538 * Wrapper to add an short Wireless Event containing a pointer to a
586 * stream of events. 539 * stream of events.
587 * Same as above, with explicit error check...
588 */ 540 */
589static inline char * 541static inline char *
590iwe_stream_check_add_point(char * stream, /* Stream of events */ 542iwe_stream_add_point(struct iw_request_info *info, char *stream, char *ends,
591 char * ends, /* End of stream */ 543 struct iw_event *iwe, char *extra)
592 struct iw_event *iwe, /* Payload length + flags */
593 char * extra, /* More payload */
594 int * perr) /* Error report */
595{ 544{
596 int event_len = IW_EV_POINT_LEN + iwe->u.data.length; 545 int event_len = iwe_stream_point_len(info) + iwe->u.data.length;
546 int point_len = iwe_stream_point_len(info);
547 int lcp_len = iwe_stream_lcp_len(info);
548
597 /* Check if it's possible */ 549 /* Check if it's possible */
598 if(likely((stream + event_len) < ends)) { 550 if(likely((stream + event_len) < ends)) {
599 iwe->len = event_len; 551 iwe->len = event_len;
600 memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN); 552 memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
601 memcpy(stream + IW_EV_LCP_LEN, 553 memcpy(stream + lcp_len,
602 ((char *) iwe) + IW_EV_LCP_LEN + IW_EV_POINT_OFF, 554 ((char *) &iwe->u) + IW_EV_POINT_OFF,
603 IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN); 555 IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN);
604 memcpy(stream + IW_EV_POINT_LEN, extra, iwe->u.data.length); 556 memcpy(stream + point_len, extra, iwe->u.data.length);
605 stream += event_len; 557 stream += event_len;
606 } else 558 }
607 *perr = -E2BIG;
608 return stream; 559 return stream;
609} 560}
610 561
@@ -613,29 +564,25 @@ iwe_stream_check_add_point(char * stream, /* Stream of events */
613 * Wrapper to add a value to a Wireless Event in a stream of events. 564 * Wrapper to add a value to a Wireless Event in a stream of events.
614 * Be careful, this one is tricky to use properly : 565 * Be careful, this one is tricky to use properly :
615 * At the first run, you need to have (value = event + IW_EV_LCP_LEN). 566 * At the first run, you need to have (value = event + IW_EV_LCP_LEN).
616 * Same as above, with explicit error check...
617 */ 567 */
618static inline char * 568static inline char *
619iwe_stream_check_add_value(char * event, /* Event in the stream */ 569iwe_stream_add_value(struct iw_request_info *info, char *event, char *value,
620 char * value, /* Value in event */ 570 char *ends, struct iw_event *iwe, int event_len)
621 char * ends, /* End of stream */
622 struct iw_event *iwe, /* Payload */
623 int event_len, /* Size of payload */
624 int * perr) /* Error report */
625{ 571{
572 int lcp_len = iwe_stream_lcp_len(info);
573
626 /* Don't duplicate LCP */ 574 /* Don't duplicate LCP */
627 event_len -= IW_EV_LCP_LEN; 575 event_len -= IW_EV_LCP_LEN;
628 576
629 /* Check if it's possible */ 577 /* Check if it's possible */
630 if(likely((value + event_len) < ends)) { 578 if(likely((value + event_len) < ends)) {
631 /* Add new value */ 579 /* Add new value */
632 memcpy(value, (char *) iwe + IW_EV_LCP_LEN, event_len); 580 memcpy(value, &iwe->u, event_len);
633 value += event_len; 581 value += event_len;
634 /* Patch LCP */ 582 /* Patch LCP */
635 iwe->len = value - event; 583 iwe->len = value - event;
636 memcpy(event, (char *) iwe, IW_EV_LCP_LEN); 584 memcpy(event, (char *) iwe, lcp_len);
637 } else 585 }
638 *perr = -E2BIG;
639 return value; 586 return value;
640} 587}
641 588
diff --git a/net/ieee80211/ieee80211_wx.c b/net/ieee80211/ieee80211_wx.c
index 822606b615ca..973832dd7faf 100644
--- a/net/ieee80211/ieee80211_wx.c
+++ b/net/ieee80211/ieee80211_wx.c
@@ -43,8 +43,9 @@ static const char *ieee80211_modes[] = {
43 43
44#define MAX_CUSTOM_LEN 64 44#define MAX_CUSTOM_LEN 64
45static char *ieee80211_translate_scan(struct ieee80211_device *ieee, 45static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
46 char *start, char *stop, 46 char *start, char *stop,
47 struct ieee80211_network *network) 47 struct ieee80211_network *network,
48 struct iw_request_info *info)
48{ 49{
49 char custom[MAX_CUSTOM_LEN]; 50 char custom[MAX_CUSTOM_LEN];
50 char *p; 51 char *p;
@@ -57,7 +58,7 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
57 iwe.cmd = SIOCGIWAP; 58 iwe.cmd = SIOCGIWAP;
58 iwe.u.ap_addr.sa_family = ARPHRD_ETHER; 59 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
59 memcpy(iwe.u.ap_addr.sa_data, network->bssid, ETH_ALEN); 60 memcpy(iwe.u.ap_addr.sa_data, network->bssid, ETH_ALEN);
60 start = iwe_stream_add_event(start, stop, &iwe, IW_EV_ADDR_LEN); 61 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
61 62
62 /* Remaining entries will be displayed in the order we provide them */ 63 /* Remaining entries will be displayed in the order we provide them */
63 64
@@ -66,17 +67,19 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
66 iwe.u.data.flags = 1; 67 iwe.u.data.flags = 1;
67 if (network->flags & NETWORK_EMPTY_ESSID) { 68 if (network->flags & NETWORK_EMPTY_ESSID) {
68 iwe.u.data.length = sizeof("<hidden>"); 69 iwe.u.data.length = sizeof("<hidden>");
69 start = iwe_stream_add_point(start, stop, &iwe, "<hidden>"); 70 start = iwe_stream_add_point(info, start, stop,
71 &iwe, "<hidden>");
70 } else { 72 } else {
71 iwe.u.data.length = min(network->ssid_len, (u8) 32); 73 iwe.u.data.length = min(network->ssid_len, (u8) 32);
72 start = iwe_stream_add_point(start, stop, &iwe, network->ssid); 74 start = iwe_stream_add_point(info, start, stop,
75 &iwe, network->ssid);
73 } 76 }
74 77
75 /* Add the protocol name */ 78 /* Add the protocol name */
76 iwe.cmd = SIOCGIWNAME; 79 iwe.cmd = SIOCGIWNAME;
77 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11%s", 80 snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11%s",
78 ieee80211_modes[network->mode]); 81 ieee80211_modes[network->mode]);
79 start = iwe_stream_add_event(start, stop, &iwe, IW_EV_CHAR_LEN); 82 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
80 83
81 /* Add mode */ 84 /* Add mode */
82 iwe.cmd = SIOCGIWMODE; 85 iwe.cmd = SIOCGIWMODE;
@@ -86,7 +89,8 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
86 else 89 else
87 iwe.u.mode = IW_MODE_ADHOC; 90 iwe.u.mode = IW_MODE_ADHOC;
88 91
89 start = iwe_stream_add_event(start, stop, &iwe, IW_EV_UINT_LEN); 92 start = iwe_stream_add_event(info, start, stop,
93 &iwe, IW_EV_UINT_LEN);
90 } 94 }
91 95
92 /* Add channel and frequency */ 96 /* Add channel and frequency */
@@ -95,7 +99,7 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
95 iwe.u.freq.m = ieee80211_channel_to_freq(ieee, network->channel); 99 iwe.u.freq.m = ieee80211_channel_to_freq(ieee, network->channel);
96 iwe.u.freq.e = 6; 100 iwe.u.freq.e = 6;
97 iwe.u.freq.i = 0; 101 iwe.u.freq.i = 0;
98 start = iwe_stream_add_event(start, stop, &iwe, IW_EV_FREQ_LEN); 102 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN);
99 103
100 /* Add encryption capability */ 104 /* Add encryption capability */
101 iwe.cmd = SIOCGIWENCODE; 105 iwe.cmd = SIOCGIWENCODE;
@@ -104,12 +108,13 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
104 else 108 else
105 iwe.u.data.flags = IW_ENCODE_DISABLED; 109 iwe.u.data.flags = IW_ENCODE_DISABLED;
106 iwe.u.data.length = 0; 110 iwe.u.data.length = 0;
107 start = iwe_stream_add_point(start, stop, &iwe, network->ssid); 111 start = iwe_stream_add_point(info, start, stop,
112 &iwe, network->ssid);
108 113
109 /* Add basic and extended rates */ 114 /* Add basic and extended rates */
110 /* Rate : stuffing multiple values in a single event require a bit 115 /* Rate : stuffing multiple values in a single event require a bit
111 * more of magic - Jean II */ 116 * more of magic - Jean II */
112 current_val = start + IW_EV_LCP_LEN; 117 current_val = start + iwe_stream_lcp_len(info);
113 iwe.cmd = SIOCGIWRATE; 118 iwe.cmd = SIOCGIWRATE;
114 /* Those two flags are ignored... */ 119 /* Those two flags are ignored... */
115 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0; 120 iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
@@ -124,17 +129,19 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
124 /* Bit rate given in 500 kb/s units (+ 0x80) */ 129 /* Bit rate given in 500 kb/s units (+ 0x80) */
125 iwe.u.bitrate.value = ((rate & 0x7f) * 500000); 130 iwe.u.bitrate.value = ((rate & 0x7f) * 500000);
126 /* Add new value to event */ 131 /* Add new value to event */
127 current_val = iwe_stream_add_value(start, current_val, stop, &iwe, IW_EV_PARAM_LEN); 132 current_val = iwe_stream_add_value(info, start, current_val,
133 stop, &iwe, IW_EV_PARAM_LEN);
128 } 134 }
129 for (; j < network->rates_ex_len; j++) { 135 for (; j < network->rates_ex_len; j++) {
130 rate = network->rates_ex[j] & 0x7F; 136 rate = network->rates_ex[j] & 0x7F;
131 /* Bit rate given in 500 kb/s units (+ 0x80) */ 137 /* Bit rate given in 500 kb/s units (+ 0x80) */
132 iwe.u.bitrate.value = ((rate & 0x7f) * 500000); 138 iwe.u.bitrate.value = ((rate & 0x7f) * 500000);
133 /* Add new value to event */ 139 /* Add new value to event */
134 current_val = iwe_stream_add_value(start, current_val, stop, &iwe, IW_EV_PARAM_LEN); 140 current_val = iwe_stream_add_value(info, start, current_val,
141 stop, &iwe, IW_EV_PARAM_LEN);
135 } 142 }
136 /* Check if we added any rate */ 143 /* Check if we added any rate */
137 if((current_val - start) > IW_EV_LCP_LEN) 144 if ((current_val - start) > iwe_stream_lcp_len(info))
138 start = current_val; 145 start = current_val;
139 146
140 /* Add quality statistics */ 147 /* Add quality statistics */
@@ -181,14 +188,14 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
181 iwe.u.qual.level = network->stats.signal; 188 iwe.u.qual.level = network->stats.signal;
182 } 189 }
183 190
184 start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN); 191 start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
185 192
186 iwe.cmd = IWEVCUSTOM; 193 iwe.cmd = IWEVCUSTOM;
187 p = custom; 194 p = custom;
188 195
189 iwe.u.data.length = p - custom; 196 iwe.u.data.length = p - custom;
190 if (iwe.u.data.length) 197 if (iwe.u.data.length)
191 start = iwe_stream_add_point(start, stop, &iwe, custom); 198 start = iwe_stream_add_point(info, start, stop, &iwe, custom);
192 199
193 memset(&iwe, 0, sizeof(iwe)); 200 memset(&iwe, 0, sizeof(iwe));
194 if (network->wpa_ie_len) { 201 if (network->wpa_ie_len) {
@@ -196,7 +203,7 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
196 memcpy(buf, network->wpa_ie, network->wpa_ie_len); 203 memcpy(buf, network->wpa_ie, network->wpa_ie_len);
197 iwe.cmd = IWEVGENIE; 204 iwe.cmd = IWEVGENIE;
198 iwe.u.data.length = network->wpa_ie_len; 205 iwe.u.data.length = network->wpa_ie_len;
199 start = iwe_stream_add_point(start, stop, &iwe, buf); 206 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
200 } 207 }
201 208
202 memset(&iwe, 0, sizeof(iwe)); 209 memset(&iwe, 0, sizeof(iwe));
@@ -205,7 +212,7 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
205 memcpy(buf, network->rsn_ie, network->rsn_ie_len); 212 memcpy(buf, network->rsn_ie, network->rsn_ie_len);
206 iwe.cmd = IWEVGENIE; 213 iwe.cmd = IWEVGENIE;
207 iwe.u.data.length = network->rsn_ie_len; 214 iwe.u.data.length = network->rsn_ie_len;
208 start = iwe_stream_add_point(start, stop, &iwe, buf); 215 start = iwe_stream_add_point(info, start, stop, &iwe, buf);
209 } 216 }
210 217
211 /* Add EXTRA: Age to display seconds since last beacon/probe response 218 /* Add EXTRA: Age to display seconds since last beacon/probe response
@@ -217,7 +224,7 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
217 jiffies_to_msecs(jiffies - network->last_scanned)); 224 jiffies_to_msecs(jiffies - network->last_scanned));
218 iwe.u.data.length = p - custom; 225 iwe.u.data.length = p - custom;
219 if (iwe.u.data.length) 226 if (iwe.u.data.length)
220 start = iwe_stream_add_point(start, stop, &iwe, custom); 227 start = iwe_stream_add_point(info, start, stop, &iwe, custom);
221 228
222 /* Add spectrum management information */ 229 /* Add spectrum management information */
223 iwe.cmd = -1; 230 iwe.cmd = -1;
@@ -238,7 +245,7 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
238 245
239 if (iwe.cmd == IWEVCUSTOM) { 246 if (iwe.cmd == IWEVCUSTOM) {
240 iwe.u.data.length = p - custom; 247 iwe.u.data.length = p - custom;
241 start = iwe_stream_add_point(start, stop, &iwe, custom); 248 start = iwe_stream_add_point(info, start, stop, &iwe, custom);
242 } 249 }
243 250
244 return start; 251 return start;
@@ -272,7 +279,8 @@ int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
272 279
273 if (ieee->scan_age == 0 || 280 if (ieee->scan_age == 0 ||
274 time_after(network->last_scanned + ieee->scan_age, jiffies)) 281 time_after(network->last_scanned + ieee->scan_age, jiffies))
275 ev = ieee80211_translate_scan(ieee, ev, stop, network); 282 ev = ieee80211_translate_scan(ieee, ev, stop, network,
283 info);
276 else 284 else
277 IEEE80211_DEBUG_SCAN("Not showing network '%s (" 285 IEEE80211_DEBUG_SCAN("Not showing network '%s ("
278 "%s)' due to age (%dms).\n", 286 "%s)' due to age (%dms).\n",
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 14fccf16b80f..80a9e7c07b47 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -24,6 +24,7 @@
24#include <linux/spinlock.h> 24#include <linux/spinlock.h>
25#include <linux/etherdevice.h> 25#include <linux/etherdevice.h>
26#include <net/wireless.h> 26#include <net/wireless.h>
27#include <net/iw_handler.h>
27#include "key.h" 28#include "key.h"
28#include "sta_info.h" 29#include "sta_info.h"
29 30
@@ -867,7 +868,9 @@ int ieee80211_sta_set_bssid(struct net_device *dev, u8 *bssid);
867int ieee80211_sta_req_scan(struct net_device *dev, u8 *ssid, size_t ssid_len); 868int ieee80211_sta_req_scan(struct net_device *dev, u8 *ssid, size_t ssid_len);
868void ieee80211_sta_req_auth(struct net_device *dev, 869void ieee80211_sta_req_auth(struct net_device *dev,
869 struct ieee80211_if_sta *ifsta); 870 struct ieee80211_if_sta *ifsta);
870int ieee80211_sta_scan_results(struct net_device *dev, char *buf, size_t len); 871int ieee80211_sta_scan_results(struct net_device *dev,
872 struct iw_request_info *info,
873 char *buf, size_t len);
871ieee80211_rx_result ieee80211_sta_rx_scan( 874ieee80211_rx_result ieee80211_sta_rx_scan(
872 struct net_device *dev, struct sk_buff *skb, 875 struct net_device *dev, struct sk_buff *skb,
873 struct ieee80211_rx_status *rx_status); 876 struct ieee80211_rx_status *rx_status);
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 55659a730dc1..e06d6450f215 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -4087,6 +4087,7 @@ int ieee80211_sta_req_scan(struct net_device *dev, u8 *ssid, size_t ssid_len)
4087 4087
4088static char * 4088static char *
4089ieee80211_sta_scan_result(struct net_device *dev, 4089ieee80211_sta_scan_result(struct net_device *dev,
4090 struct iw_request_info *info,
4090 struct ieee80211_sta_bss *bss, 4091 struct ieee80211_sta_bss *bss,
4091 char *current_ev, char *end_buf) 4092 char *current_ev, char *end_buf)
4092{ 4093{
@@ -4101,7 +4102,7 @@ ieee80211_sta_scan_result(struct net_device *dev,
4101 iwe.cmd = SIOCGIWAP; 4102 iwe.cmd = SIOCGIWAP;
4102 iwe.u.ap_addr.sa_family = ARPHRD_ETHER; 4103 iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
4103 memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN); 4104 memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
4104 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, 4105 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
4105 IW_EV_ADDR_LEN); 4106 IW_EV_ADDR_LEN);
4106 4107
4107 memset(&iwe, 0, sizeof(iwe)); 4108 memset(&iwe, 0, sizeof(iwe));
@@ -4109,13 +4110,13 @@ ieee80211_sta_scan_result(struct net_device *dev,
4109 if (bss_mesh_cfg(bss)) { 4110 if (bss_mesh_cfg(bss)) {
4110 iwe.u.data.length = bss_mesh_id_len(bss); 4111 iwe.u.data.length = bss_mesh_id_len(bss);
4111 iwe.u.data.flags = 1; 4112 iwe.u.data.flags = 1;
4112 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, 4113 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4113 bss_mesh_id(bss)); 4114 &iwe, bss_mesh_id(bss));
4114 } else { 4115 } else {
4115 iwe.u.data.length = bss->ssid_len; 4116 iwe.u.data.length = bss->ssid_len;
4116 iwe.u.data.flags = 1; 4117 iwe.u.data.flags = 1;
4117 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, 4118 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4118 bss->ssid); 4119 &iwe, bss->ssid);
4119 } 4120 }
4120 4121
4121 if (bss->capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS) 4122 if (bss->capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)
@@ -4128,22 +4129,22 @@ ieee80211_sta_scan_result(struct net_device *dev,
4128 iwe.u.mode = IW_MODE_MASTER; 4129 iwe.u.mode = IW_MODE_MASTER;
4129 else 4130 else
4130 iwe.u.mode = IW_MODE_ADHOC; 4131 iwe.u.mode = IW_MODE_ADHOC;
4131 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, 4132 current_ev = iwe_stream_add_event(info, current_ev, end_buf,
4132 IW_EV_UINT_LEN); 4133 &iwe, IW_EV_UINT_LEN);
4133 } 4134 }
4134 4135
4135 memset(&iwe, 0, sizeof(iwe)); 4136 memset(&iwe, 0, sizeof(iwe));
4136 iwe.cmd = SIOCGIWFREQ; 4137 iwe.cmd = SIOCGIWFREQ;
4137 iwe.u.freq.m = ieee80211_frequency_to_channel(bss->freq); 4138 iwe.u.freq.m = ieee80211_frequency_to_channel(bss->freq);
4138 iwe.u.freq.e = 0; 4139 iwe.u.freq.e = 0;
4139 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, 4140 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
4140 IW_EV_FREQ_LEN); 4141 IW_EV_FREQ_LEN);
4141 4142
4142 memset(&iwe, 0, sizeof(iwe)); 4143 memset(&iwe, 0, sizeof(iwe));
4143 iwe.cmd = SIOCGIWFREQ; 4144 iwe.cmd = SIOCGIWFREQ;
4144 iwe.u.freq.m = bss->freq; 4145 iwe.u.freq.m = bss->freq;
4145 iwe.u.freq.e = 6; 4146 iwe.u.freq.e = 6;
4146 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, 4147 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
4147 IW_EV_FREQ_LEN); 4148 IW_EV_FREQ_LEN);
4148 memset(&iwe, 0, sizeof(iwe)); 4149 memset(&iwe, 0, sizeof(iwe));
4149 iwe.cmd = IWEVQUAL; 4150 iwe.cmd = IWEVQUAL;
@@ -4151,7 +4152,7 @@ ieee80211_sta_scan_result(struct net_device *dev,
4151 iwe.u.qual.level = bss->signal; 4152 iwe.u.qual.level = bss->signal;
4152 iwe.u.qual.noise = bss->noise; 4153 iwe.u.qual.noise = bss->noise;
4153 iwe.u.qual.updated = local->wstats_flags; 4154 iwe.u.qual.updated = local->wstats_flags;
4154 current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, 4155 current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
4155 IW_EV_QUAL_LEN); 4156 IW_EV_QUAL_LEN);
4156 4157
4157 memset(&iwe, 0, sizeof(iwe)); 4158 memset(&iwe, 0, sizeof(iwe));
@@ -4161,35 +4162,36 @@ ieee80211_sta_scan_result(struct net_device *dev,
4161 else 4162 else
4162 iwe.u.data.flags = IW_ENCODE_DISABLED; 4163 iwe.u.data.flags = IW_ENCODE_DISABLED;
4163 iwe.u.data.length = 0; 4164 iwe.u.data.length = 0;
4164 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, ""); 4165 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4166 &iwe, "");
4165 4167
4166 if (bss && bss->wpa_ie) { 4168 if (bss && bss->wpa_ie) {
4167 memset(&iwe, 0, sizeof(iwe)); 4169 memset(&iwe, 0, sizeof(iwe));
4168 iwe.cmd = IWEVGENIE; 4170 iwe.cmd = IWEVGENIE;
4169 iwe.u.data.length = bss->wpa_ie_len; 4171 iwe.u.data.length = bss->wpa_ie_len;
4170 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, 4172 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4171 bss->wpa_ie); 4173 &iwe, bss->wpa_ie);
4172 } 4174 }
4173 4175
4174 if (bss && bss->rsn_ie) { 4176 if (bss && bss->rsn_ie) {
4175 memset(&iwe, 0, sizeof(iwe)); 4177 memset(&iwe, 0, sizeof(iwe));
4176 iwe.cmd = IWEVGENIE; 4178 iwe.cmd = IWEVGENIE;
4177 iwe.u.data.length = bss->rsn_ie_len; 4179 iwe.u.data.length = bss->rsn_ie_len;
4178 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, 4180 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4179 bss->rsn_ie); 4181 &iwe, bss->rsn_ie);
4180 } 4182 }
4181 4183
4182 if (bss && bss->ht_ie) { 4184 if (bss && bss->ht_ie) {
4183 memset(&iwe, 0, sizeof(iwe)); 4185 memset(&iwe, 0, sizeof(iwe));
4184 iwe.cmd = IWEVGENIE; 4186 iwe.cmd = IWEVGENIE;
4185 iwe.u.data.length = bss->ht_ie_len; 4187 iwe.u.data.length = bss->ht_ie_len;
4186 current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, 4188 current_ev = iwe_stream_add_point(info, current_ev, end_buf,
4187 bss->ht_ie); 4189 &iwe, bss->ht_ie);
4188 } 4190 }
4189 4191
4190 if (bss && bss->supp_rates_len > 0) { 4192 if (bss && bss->supp_rates_len > 0) {
4191 /* display all supported rates in readable format */ 4193 /* display all supported rates in readable format */
4192 char *p = current_ev + IW_EV_LCP_LEN; 4194 char *p = current_ev + iwe_stream_lcp_len(info);
4193 int i; 4195 int i;
4194 4196
4195 memset(&iwe, 0, sizeof(iwe)); 4197 memset(&iwe, 0, sizeof(iwe));
@@ -4200,7 +4202,7 @@ ieee80211_sta_scan_result(struct net_device *dev,
4200 for (i = 0; i < bss->supp_rates_len; i++) { 4202 for (i = 0; i < bss->supp_rates_len; i++) {
4201 iwe.u.bitrate.value = ((bss->supp_rates[i] & 4203 iwe.u.bitrate.value = ((bss->supp_rates[i] &
4202 0x7f) * 500000); 4204 0x7f) * 500000);
4203 p = iwe_stream_add_value(current_ev, p, 4205 p = iwe_stream_add_value(info, current_ev, p,
4204 end_buf, &iwe, IW_EV_PARAM_LEN); 4206 end_buf, &iwe, IW_EV_PARAM_LEN);
4205 } 4207 }
4206 current_ev = p; 4208 current_ev = p;
@@ -4214,7 +4216,8 @@ ieee80211_sta_scan_result(struct net_device *dev,
4214 iwe.cmd = IWEVCUSTOM; 4216 iwe.cmd = IWEVCUSTOM;
4215 sprintf(buf, "tsf=%016llx", (unsigned long long)(bss->timestamp)); 4217 sprintf(buf, "tsf=%016llx", (unsigned long long)(bss->timestamp));
4216 iwe.u.data.length = strlen(buf); 4218 iwe.u.data.length = strlen(buf);
4217 current_ev = iwe_stream_add_point(current_ev, end_buf, 4219 current_ev = iwe_stream_add_point(info, current_ev,
4220 end_buf,
4218 &iwe, buf); 4221 &iwe, buf);
4219 kfree(buf); 4222 kfree(buf);
4220 } 4223 }
@@ -4229,31 +4232,36 @@ ieee80211_sta_scan_result(struct net_device *dev,
4229 iwe.cmd = IWEVCUSTOM; 4232 iwe.cmd = IWEVCUSTOM;
4230 sprintf(buf, "Mesh network (version %d)", cfg[0]); 4233 sprintf(buf, "Mesh network (version %d)", cfg[0]);
4231 iwe.u.data.length = strlen(buf); 4234 iwe.u.data.length = strlen(buf);
4232 current_ev = iwe_stream_add_point(current_ev, end_buf, 4235 current_ev = iwe_stream_add_point(info, current_ev,
4236 end_buf,
4233 &iwe, buf); 4237 &iwe, buf);
4234 sprintf(buf, "Path Selection Protocol ID: " 4238 sprintf(buf, "Path Selection Protocol ID: "
4235 "0x%02X%02X%02X%02X", cfg[1], cfg[2], cfg[3], 4239 "0x%02X%02X%02X%02X", cfg[1], cfg[2], cfg[3],
4236 cfg[4]); 4240 cfg[4]);
4237 iwe.u.data.length = strlen(buf); 4241 iwe.u.data.length = strlen(buf);
4238 current_ev = iwe_stream_add_point(current_ev, end_buf, 4242 current_ev = iwe_stream_add_point(info, current_ev,
4243 end_buf,
4239 &iwe, buf); 4244 &iwe, buf);
4240 sprintf(buf, "Path Selection Metric ID: " 4245 sprintf(buf, "Path Selection Metric ID: "
4241 "0x%02X%02X%02X%02X", cfg[5], cfg[6], cfg[7], 4246 "0x%02X%02X%02X%02X", cfg[5], cfg[6], cfg[7],
4242 cfg[8]); 4247 cfg[8]);
4243 iwe.u.data.length = strlen(buf); 4248 iwe.u.data.length = strlen(buf);
4244 current_ev = iwe_stream_add_point(current_ev, end_buf, 4249 current_ev = iwe_stream_add_point(info, current_ev,
4250 end_buf,
4245 &iwe, buf); 4251 &iwe, buf);
4246 sprintf(buf, "Congestion Control Mode ID: " 4252 sprintf(buf, "Congestion Control Mode ID: "
4247 "0x%02X%02X%02X%02X", cfg[9], cfg[10], 4253 "0x%02X%02X%02X%02X", cfg[9], cfg[10],
4248 cfg[11], cfg[12]); 4254 cfg[11], cfg[12]);
4249 iwe.u.data.length = strlen(buf); 4255 iwe.u.data.length = strlen(buf);
4250 current_ev = iwe_stream_add_point(current_ev, end_buf, 4256 current_ev = iwe_stream_add_point(info, current_ev,
4257 end_buf,
4251 &iwe, buf); 4258 &iwe, buf);
4252 sprintf(buf, "Channel Precedence: " 4259 sprintf(buf, "Channel Precedence: "
4253 "0x%02X%02X%02X%02X", cfg[13], cfg[14], 4260 "0x%02X%02X%02X%02X", cfg[13], cfg[14],
4254 cfg[15], cfg[16]); 4261 cfg[15], cfg[16]);
4255 iwe.u.data.length = strlen(buf); 4262 iwe.u.data.length = strlen(buf);
4256 current_ev = iwe_stream_add_point(current_ev, end_buf, 4263 current_ev = iwe_stream_add_point(info, current_ev,
4264 end_buf,
4257 &iwe, buf); 4265 &iwe, buf);
4258 kfree(buf); 4266 kfree(buf);
4259 } 4267 }
@@ -4263,7 +4271,9 @@ ieee80211_sta_scan_result(struct net_device *dev,
4263} 4271}
4264 4272
4265 4273
4266int ieee80211_sta_scan_results(struct net_device *dev, char *buf, size_t len) 4274int ieee80211_sta_scan_results(struct net_device *dev,
4275 struct iw_request_info *info,
4276 char *buf, size_t len)
4267{ 4277{
4268 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 4278 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
4269 char *current_ev = buf; 4279 char *current_ev = buf;
@@ -4276,8 +4286,8 @@ int ieee80211_sta_scan_results(struct net_device *dev, char *buf, size_t len)
4276 spin_unlock_bh(&local->sta_bss_lock); 4286 spin_unlock_bh(&local->sta_bss_lock);
4277 return -E2BIG; 4287 return -E2BIG;
4278 } 4288 }
4279 current_ev = ieee80211_sta_scan_result(dev, bss, current_ev, 4289 current_ev = ieee80211_sta_scan_result(dev, info, bss,
4280 end_buf); 4290 current_ev, end_buf);
4281 } 4291 }
4282 spin_unlock_bh(&local->sta_bss_lock); 4292 spin_unlock_bh(&local->sta_bss_lock);
4283 return current_ev - buf; 4293 return current_ev - buf;
diff --git a/net/mac80211/wext.c b/net/mac80211/wext.c
index 5af3862e7191..f47d13bdf7f7 100644
--- a/net/mac80211/wext.c
+++ b/net/mac80211/wext.c
@@ -567,7 +567,7 @@ static int ieee80211_ioctl_giwscan(struct net_device *dev,
567 if (local->sta_sw_scanning || local->sta_hw_scanning) 567 if (local->sta_sw_scanning || local->sta_hw_scanning)
568 return -EAGAIN; 568 return -EAGAIN;
569 569
570 res = ieee80211_sta_scan_results(dev, extra, data->length); 570 res = ieee80211_sta_scan_results(dev, info, extra, data->length);
571 if (res >= 0) { 571 if (res >= 0) {
572 data->length = res; 572 data->length = res;
573 return 0; 573 return 0;