From: Masakazu Mokuno <mokuno-DfbDroY8Xu1L9jVzuh4AOg@public.gmane.org>
To: David Miller <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Subject: Re: : Emit event stream compat iw_point objects correctly.
Date: Fri, 11 Jan 2008 13:16:29 +0900 [thread overview]
Message-ID: <20080111112248.610C.40F06B3A@sm.sony.co.jp> (raw)
In-Reply-To: <20080110.011602.74511551.davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 12627 bytes --]
Hi
Thank you for updating the patch.
On Thu, 10 Jan 2008 01:16:02 -0800 (PST)
David Miller <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org> wrote:
> From: Masakazu Mokuno <mokuno-DfbDroY8Xu1L9jVzuh4AOg@public.gmane.org>
> Date: Thu, 27 Dec 2007 18:24:40 +0900
>
> > On ppc64 (PS3), IW_EV_LCP_LEN is 8, not 4.
> >
> > include/linux/wireless.h:
> >
> > #define IW_EV_LCP_LEN (sizeof(struct iw_event) - sizeof(union iwreq_data))
> >
> > where sizeof(struct iw_event) == 24, sizeof(union iwreq_data) == 16 on
> > PS3.
>
> Here is a new version of the last patch (#12), it should handle
> all of these cases properly now.
>
> Let me know if you spot any more errors.
>
> Thanks!
>
> [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.
>
> With help from Masakazu Mokuno
>
> Signed-off-by: David S. Miller <davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
> ---
> drivers/net/wireless/airo.c | 39 +++++---
> drivers/net/wireless/atmel.c | 24 ++++-
> drivers/net/wireless/hostap/hostap.h | 3 +-
> drivers/net/wireless/hostap/hostap_ap.c | 32 +++---
> drivers/net/wireless/hostap/hostap_ioctl.c | 54 ++++++-----
> drivers/net/wireless/libertas/scan.c | 35 ++++---
> drivers/net/wireless/orinoco.c | 30 ++++--
> drivers/net/wireless/prism54/isl_ioctl.c | 45 +++++----
> drivers/net/wireless/wl3501_cs.c | 10 +-
> drivers/net/wireless/zd1201.c | 21 +++--
> include/linux/wireless.h | 16 +++
> include/net/iw_handler.h | 150 ++++++++--------------------
> net/ieee80211/ieee80211_wx.c | 44 +++++----
> net/mac80211/ieee80211_i.h | 5 +-
> net/mac80211/ieee80211_ioctl.c | 2 +-
> net/mac80211/ieee80211_sta.c | 59 ++++++-----
> 16 files changed, 293 insertions(+), 276 deletions(-)
[snip]
> diff --git a/include/linux/wireless.h b/include/linux/wireless.h
> index 2088524..bec73df 100644
> --- a/include/linux/wireless.h
> +++ b/include/linux/wireless.h
> @@ -1098,6 +1098,22 @@ struct iw_event
> #define IW_EV_POINT_LEN (IW_EV_LCP_LEN + sizeof(struct iw_point) - \
> IW_EV_POINT_OFF)
>
> +#if defined(__KERNEL__) && defined(CONFIG_COMPAT)
> +struct __compat_iw_event {
> + __u16 len; /* Real lenght of this stuff */
~~~~~
length?
> + __u16 cmd; /* Wireless IOCTL */
> + compat_caddr_t pointer;
> +};
> +#define IW_EV_COMPAT_LCP_LEN \
> + (sizeof(struct __compat_iw_event) - sizeof(compat_caddr_t))
> +#define IW_EV_COMPAT_POINT_OFF (((char *) \
> + &(((struct compat_iw_point *) NULL)->length)) - \
> + (char *) NULL)
How about the followings?
#define IW_EV_COMPAT_LCP_LEN offsetof(struct __compat_iw_event, pointer)
#define IW_EV_COMPAT_POINT_OFF offsetof(struct compat_iw_point, length)
> +#define IW_EV_COMPAT_POINT_LEN \
> + (IW_EV_COMPAT_LCP_LEN + sizeof(struct compat_iw_point) - \
> + IW_EV_COMPAT_POINT_OFF)
> +#endif
> +
> /* Size of the Event prefix when packed in stream */
> #define IW_EV_LCP_PK_LEN (4)
> /* Size of the various events when packed in stream */
> diff --git a/include/net/iw_handler.h b/include/net/iw_handler.h
> index c99a8ee..d6f0c51 100644
> --- a/include/net/iw_handler.h
> +++ b/include/net/iw_handler.h
> @@ -483,19 +483,26 @@ extern void wireless_spy_update(struct net_device * dev,
> * Wrapper to add an Wireless Event to a stream of events.
> */
> static inline char *
> -iwe_stream_add_event(char * stream, /* Stream of events */
> - char * ends, /* End of stream */
> - struct iw_event *iwe, /* Payload */
> - int event_len) /* Real size of payload */
> +iwe_stream_add_event(struct iw_request_info *info, char *stream, char *ends,
> + struct iw_event *iwe, int event_len)
> {
> + int lcp_len = IW_EV_LCP_LEN;
> +
> +#ifdef CONFIG_COMPAT
> + if (info->flags & IW_REQUEST_FLAG_COMPAT) {
> + event_len -= IW_EV_LCP_LEN;
> + event_len += IW_EV_COMPAT_LCP_LEN;
> + lcp_len = IW_EV_COMPAT_LCP_LEN;
> + }
> +#endif
> /* Check if it's possible */
> if(likely((stream + event_len) < ends)) {
> iwe->len = event_len;
> /* Beware of alignement issues on 64 bits */
> memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
> - memcpy(stream + IW_EV_LCP_LEN,
> - ((char *) iwe) + IW_EV_LCP_LEN,
> - event_len - IW_EV_LCP_LEN);
> + memcpy(stream + lcp_len,
> + ((char *) iwe) + lcp_len,
The source address does not have to be adjusted. I think it should be
((char *) iwe) + IW_EV_LCP_LEN,
or just
&iwe->u
I think it is more readable what we want to do here.
> + event_len - lcp_len);
The length of the real payload does not need to take account of the
destination offset change. So we can keep the original code like:
org_event_len - IW_EV_LCP_LEN);
> stream += event_len;
> }
> return stream;
> @@ -507,104 +514,33 @@ iwe_stream_add_event(char * stream, /* Stream of events */
> * stream of events.
> */
> static inline char *
> -iwe_stream_add_point(char * stream, /* Stream of events */
> - char * ends, /* End of stream */
> - struct iw_event *iwe, /* Payload length + flags */
> - char * extra) /* More payload */
> +iwe_stream_add_point(struct iw_request_info *info, char *stream, char *ends,
> + struct iw_event *iwe, char *extra)
> {
> - int event_len = IW_EV_POINT_LEN + iwe->u.data.length;
> - /* Check if it's possible */
> - if(likely((stream + event_len) < ends)) {
> - iwe->len = event_len;
> - memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
> - memcpy(stream + IW_EV_LCP_LEN,
> - ((char *) iwe) + IW_EV_LCP_LEN + IW_EV_POINT_OFF,
> - IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN);
> - memcpy(stream + IW_EV_POINT_LEN, extra, iwe->u.data.length);
> - stream += event_len;
> + int event_len = IW_EV_POINT_LEN + iwe->u.data.length;
> + int point_len = IW_EV_POINT_LEN;
> + int lcp_len = IW_EV_LCP_LEN;
> + int point_off = IW_EV_POINT_OFF;
> +
> +#ifdef CONFIG_COMPAT
> + if (info->flags & IW_REQUEST_FLAG_COMPAT) {
> + event_len = IW_EV_COMPAT_POINT_LEN + iwe->u.data.length;
> + point_len = IW_EV_COMPAT_POINT_LEN;
> + lcp_len = IW_EV_COMPAT_LCP_LEN;
> + point_off = IW_EV_COMPAT_POINT_OFF;
> }
> - return stream;
> -}
> -
> -/*------------------------------------------------------------------*/
> -/*
> - * Wrapper to add a value to a Wireless Event in a stream of events.
> - * Be careful, this one is tricky to use properly :
> - * At the first run, you need to have (value = event + IW_EV_LCP_LEN).
> - */
> -static inline char *
> -iwe_stream_add_value(char * event, /* Event in the stream */
> - char * value, /* Value in event */
> - char * ends, /* End of stream */
> - struct iw_event *iwe, /* Payload */
> - int event_len) /* Real size of payload */
> -{
> - /* Don't duplicate LCP */
> - event_len -= IW_EV_LCP_LEN;
> +#endif
>
> /* Check if it's possible */
> - if(likely((value + event_len) < ends)) {
> - /* Add new value */
> - memcpy(value, (char *) iwe + IW_EV_LCP_LEN, event_len);
> - value += event_len;
> - /* Patch LCP */
> - iwe->len = value - event;
> - memcpy(event, (char *) iwe, IW_EV_LCP_LEN);
> - }
> - return value;
> -}
> -
> -/*------------------------------------------------------------------*/
> -/*
> - * Wrapper to add an Wireless Event to a stream of events.
> - * Same as above, with explicit error check...
> - */
> -static inline char *
> -iwe_stream_check_add_event(char * stream, /* Stream of events */
> - char * ends, /* End of stream */
> - struct iw_event *iwe, /* Payload */
> - int event_len, /* Size of payload */
> - int * perr) /* Error report */
> -{
> - /* Check if it's possible, set error if not */
> if(likely((stream + event_len) < ends)) {
> iwe->len = event_len;
> - /* Beware of alignement issues on 64 bits */
> memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
> - memcpy(stream + IW_EV_LCP_LEN,
> - ((char *) iwe) + IW_EV_LCP_LEN,
> - event_len - IW_EV_LCP_LEN);
> - stream += event_len;
> - } else
> - *perr = -E2BIG;
> - return stream;
> -}
> -
> -/*------------------------------------------------------------------*/
> -/*
> - * Wrapper to add an short Wireless Event containing a pointer to a
> - * stream of events.
> - * Same as above, with explicit error check...
> - */
> -static inline char *
> -iwe_stream_check_add_point(char * stream, /* Stream of events */
> - char * ends, /* End of stream */
> - struct iw_event *iwe, /* Payload length + flags */
> - char * extra, /* More payload */
> - int * perr) /* Error report */
> -{
> - int event_len = IW_EV_POINT_LEN + iwe->u.data.length;
> - /* Check if it's possible */
> - if(likely((stream + event_len) < ends)) {
> - iwe->len = event_len;
> - memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
> - memcpy(stream + IW_EV_LCP_LEN,
> - ((char *) iwe) + IW_EV_LCP_LEN + IW_EV_POINT_OFF,
> + memcpy(stream + lcp_len,
> + ((char *) iwe) + lcp_len + point_off,
Same as iwe_stream_add_event(). Source address does not need to be
fixed.
> IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN);
> - memcpy(stream + IW_EV_POINT_LEN, extra, iwe->u.data.length);
> + memcpy(stream + point_len, extra, iwe->u.data.length);
> stream += event_len;
> - } else
> - *perr = -E2BIG;
> + }
> return stream;
> }
>
> @@ -613,29 +549,29 @@ iwe_stream_check_add_point(char * stream, /* Stream of events */
> * Wrapper to add a value to a Wireless Event in a stream of events.
> * Be careful, this one is tricky to use properly :
> * At the first run, you need to have (value = event + IW_EV_LCP_LEN).
> - * Same as above, with explicit error check...
> */
> static inline char *
> -iwe_stream_check_add_value(char * event, /* Event in the stream */
> - char * value, /* Value in event */
> - char * ends, /* End of stream */
> - struct iw_event *iwe, /* Payload */
> - int event_len, /* Size of payload */
> - int * perr) /* Error report */
> +iwe_stream_add_value(struct iw_request_info *info, char *event, char *value,
> + char *ends, struct iw_event *iwe, int event_len)
> {
> + int lcp_len = IW_EV_LCP_LEN;
> +
> +#ifdef CONFIG_COMPAT
> + if (info->flags & IW_REQUEST_FLAG_COMPAT)
> + lcp_len = IW_EV_COMPAT_LCP_LEN;
> +#endif
> /* Don't duplicate LCP */
> event_len -= IW_EV_LCP_LEN;
>
> /* Check if it's possible */
> if(likely((value + event_len) < ends)) {
> /* Add new value */
> - memcpy(value, (char *) iwe + IW_EV_LCP_LEN, event_len);
> + memcpy(value, (char *) iwe + lcp_len, event_len);
Same as iwe_stream_add_event(). We can keep the original code.
> value += event_len;
> /* Patch LCP */
> iwe->len = value - event;
> - memcpy(event, (char *) iwe, IW_EV_LCP_LEN);
> - } else
> - *perr = -E2BIG;
> + memcpy(event, (char *) iwe, lcp_len);
> + }
> return value;
> }
iwe_stream_add_value() is a bit tricky, so callers of this function
should do some adjusting work. For example,
ieee80211_translate_scan():ieee80211_wx.c needs like:
/* Add basic and extended rates */
/* Rate : stuffing multiple values in a single event require a bit
* more of magic - Jean II */
+#ifdef CONFIG_COMPAT
+ if (info->flags & IW_REQUEST_FLAG_COMPAT)
+ current_val = start + IW_EV_COMPAT_LCP_LEN;
+ else
+ current_val = start + IW_EV_LCP_LEN;
+#else
current_val = start + IW_EV_LCP_LEN;
+#endif
iwe.cmd = SIOCGIWRATE;
/* Those two flags are ignored... */
iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
I tried to make the patch that was incorporated with my comments above and
tested it with zd1211 based USB wireless adapter on my PS3. It seemed
that the scan result prints from iwlist was OK. The attached is the
patch.
But wpa_supplicant did not work properly with it. Although I did not
look it closely, it seemed that wpa_supplicant got a NULL IWAP event
when associated.
--
Masakazu MOKUNO
[-- Attachment #2: davem-12-modified.patch --]
[-- Type: application/octet-stream, Size: 58860 bytes --]
Here is a new version of the last patch (#12), it should handle
all of these cases properly now.
Let me know if you spot any more errors.
Thanks!
[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.
With help from Masakazu Mokuno
Signed-off-by: David S. Miller <davem@davemloft.net>
---
drivers/net/wireless/airo.c | 46 +++++---
drivers/net/wireless/atmel.c | 24 +++-
drivers/net/wireless/hostap/hostap.h | 3
drivers/net/wireless/hostap/hostap_ap.c | 32 ++---
drivers/net/wireless/hostap/hostap_ioctl.c | 61 ++++++----
drivers/net/wireless/libertas/scan.c | 42 ++++---
drivers/net/wireless/orinoco.c | 41 ++++---
drivers/net/wireless/prism54/isl_ioctl.c | 55 ++++++---
drivers/net/wireless/wl3501_cs.c | 10 -
drivers/net/wireless/zd1201.c | 21 ++-
include/linux/wireless.h | 13 ++
include/net/iw_handler.h | 164 +++++++++--------------------
net/ieee80211/ieee80211_wx.c | 51 +++++----
net/mac80211/ieee80211_i.h | 5
net/mac80211/ieee80211_ioctl.c | 2
net/mac80211/ieee80211_sta.c | 59 +++++-----
16 files changed, 346 insertions(+), 283 deletions(-)
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -7234,6 +7234,7 @@ out:
* format that the Wireless Tools will understand - Jean II
*/
static inline char *airo_translate_scan(struct net_device *dev,
+ struct iw_request_info *info,
char *current_ev,
char *end_buf,
BSSListRid *bss)
@@ -7249,7 +7250,8 @@ static inline char *airo_translate_scan(
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_ADDR_LEN);
/* Other entries will be displayed in the order we give them */
@@ -7259,7 +7261,8 @@ static inline char *airo_translate_scan(
iwe.u.data.length = 32;
iwe.cmd = SIOCGIWESSID;
iwe.u.data.flags = 1;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->ssid);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, bss->ssid);
/* Add mode */
iwe.cmd = SIOCGIWMODE;
@@ -7269,7 +7272,8 @@ static inline char *airo_translate_scan(
iwe.u.mode = IW_MODE_MASTER;
else
iwe.u.mode = IW_MODE_ADHOC;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_UINT_LEN);
}
/* Add frequency */
@@ -7280,7 +7284,8 @@ static inline char *airo_translate_scan(
*/
iwe.u.freq.m = frequency_list[iwe.u.freq.m - 1] * 100000;
iwe.u.freq.e = 1;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_FREQ_LEN);
/* Add quality statistics */
iwe.cmd = IWEVQUAL;
@@ -7298,7 +7303,8 @@ static inline char *airo_translate_scan(
| IW_QUAL_DBM;
}
iwe.u.qual.noise = ai->wstats.qual.noise;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_QUAL_LEN);
/* Add encryption capability */
iwe.cmd = SIOCGIWENCODE;
@@ -7307,11 +7313,19 @@ static inline char *airo_translate_scan(
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, bss->ssid);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, bss->ssid);
/* Rate : stuffing multiple values in a single event require a bit
* more of magic - Jean II */
+#ifdef CONFIG_COMPAT
+ if (info->flags & IW_REQUEST_FLAG_COMPAT)
+ current_val = current_ev + IW_EV_COMPAT_LCP_LEN;
+ else
+ current_val = current_ev + IW_EV_LCP_LEN;
+#else
current_val = current_ev + IW_EV_LCP_LEN;
+#endif
iwe.cmd = SIOCGIWRATE;
/* Those two flags are ignored... */
@@ -7324,7 +7338,9 @@ static inline char *airo_translate_scan(
/* Bit rate given in 500 kb/s units (+ 0x80) */
iwe.u.bitrate.value = ((bss->rates[i] & 0x7f) * 500000);
/* Add new value to event */
- current_val = iwe_stream_add_value(current_ev, current_val, end_buf, &iwe, IW_EV_PARAM_LEN);
+ current_val = iwe_stream_add_value(info, current_ev,
+ current_val, end_buf,
+ &iwe, IW_EV_PARAM_LEN);
}
/* Check if we added any event */
if((current_val - current_ev) > IW_EV_LCP_LEN)
@@ -7336,7 +7352,8 @@ static inline char *airo_translate_scan(
iwe.cmd = IWEVCUSTOM;
sprintf(buf, "bcn_int=%d", bss->beaconInterval);
iwe.u.data.length = strlen(buf);
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, buf);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, buf);
kfree(buf);
}
@@ -7370,8 +7387,10 @@ static inline char *airo_translate_scan(
iwe.cmd = IWEVGENIE;
iwe.u.data.length = min(info_element->len + 2,
MAX_WPA_IE_LEN);
- current_ev = iwe_stream_add_point(current_ev, end_buf,
- &iwe, (char *) info_element);
+ current_ev = iwe_stream_add_point(
+ info, current_ev,
+ end_buf, &iwe,
+ (char *) info_element);
}
break;
@@ -7379,8 +7398,9 @@ static inline char *airo_translate_scan(
iwe.cmd = IWEVGENIE;
iwe.u.data.length = min(info_element->len + 2,
MAX_WPA_IE_LEN);
- current_ev = iwe_stream_add_point(current_ev, end_buf,
- &iwe, (char *) info_element);
+ current_ev = iwe_stream_add_point(
+ info, current_ev, end_buf,
+ &iwe, (char *) info_element);
break;
default:
@@ -7419,7 +7439,7 @@ static int airo_get_scan(struct net_devi
list_for_each_entry (net, &ai->network_list, list) {
/* Translate to WE format this entry */
- current_ev = airo_translate_scan(dev, current_ev,
+ current_ev = airo_translate_scan(dev, info, current_ev,
extra + dwrq->length,
&net->bss);
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -2320,30 +2320,40 @@ static int atmel_get_scan(struct net_dev
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, priv->BSSinfo[i].BSSID, 6);
- current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_ADDR_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev,
+ extra + IW_SCAN_MAX_DATA,
+ &iwe, IW_EV_ADDR_LEN);
iwe.u.data.length = priv->BSSinfo[i].SSIDsize;
if (iwe.u.data.length > 32)
iwe.u.data.length = 32;
iwe.cmd = SIOCGIWESSID;
iwe.u.data.flags = 1;
- current_ev = iwe_stream_add_point(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, priv->BSSinfo[i].SSID);
+ current_ev = iwe_stream_add_point(info, current_ev,
+ extra + IW_SCAN_MAX_DATA,
+ &iwe, priv->BSSinfo[i].SSID);
iwe.cmd = SIOCGIWMODE;
iwe.u.mode = priv->BSSinfo[i].BSStype;
- current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_UINT_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev,
+ extra + IW_SCAN_MAX_DATA,
+ &iwe, IW_EV_UINT_LEN);
iwe.cmd = SIOCGIWFREQ;
iwe.u.freq.m = priv->BSSinfo[i].channel;
iwe.u.freq.e = 0;
- current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, IW_EV_FREQ_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev,
+ extra + IW_SCAN_MAX_DATA,
+ &iwe, IW_EV_FREQ_LEN);
/* Add quality statistics */
iwe.cmd = IWEVQUAL;
iwe.u.qual.level = priv->BSSinfo[i].RSSI;
iwe.u.qual.qual = iwe.u.qual.level;
/* iwe.u.qual.noise = SOMETHING */
- current_ev = iwe_stream_add_event(current_ev, extra + IW_SCAN_MAX_DATA , &iwe, IW_EV_QUAL_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev,
+ extra + IW_SCAN_MAX_DATA,
+ &iwe, IW_EV_QUAL_LEN);
iwe.cmd = SIOCGIWENCODE;
@@ -2352,7 +2362,9 @@ static int atmel_get_scan(struct net_dev
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0;
- current_ev = iwe_stream_add_point(current_ev, extra + IW_SCAN_MAX_DATA, &iwe, NULL);
+ current_ev = iwe_stream_add_point(info, current_ev,
+ extra + IW_SCAN_MAX_DATA,
+ &iwe, NULL);
}
/* Length of data */
--- 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
int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[],
struct iw_quality qual[], int buf_size,
int aplist);
-int prism2_ap_translate_scan(struct net_device *dev, char *buffer);
+int prism2_ap_translate_scan(struct net_device *dev,
+ struct iw_request_info *info, char *buffer);
int prism2_hostapd(struct ap_data *ap, struct prism2_hostapd_param *param);
--- a/drivers/net/wireless/hostap/hostap_ap.c
+++ b/drivers/net/wireless/hostap/hostap_ap.c
@@ -2381,7 +2381,8 @@ int prism2_ap_get_sta_qual(local_info_t
/* Translate our list of Access Points & Stations to a card independant
* format that the Wireless Tools will understand - Jean II */
-int prism2_ap_translate_scan(struct net_device *dev, char *buffer)
+int prism2_ap_translate_scan(struct net_device *dev,
+ struct iw_request_info *info, char *buffer)
{
struct hostap_interface *iface;
local_info_t *local;
@@ -2410,8 +2411,8 @@ int prism2_ap_translate_scan(struct net_
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, sta->addr, ETH_ALEN);
iwe.len = IW_EV_ADDR_LEN;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
- IW_EV_ADDR_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_ADDR_LEN);
/* Use the mode to indicate if it's a station or
* an Access Point */
@@ -2422,8 +2423,8 @@ int prism2_ap_translate_scan(struct net_
else
iwe.u.mode = IW_MODE_INFRA;
iwe.len = IW_EV_UINT_LEN;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
- IW_EV_UINT_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_UINT_LEN);
/* Some quality */
memset(&iwe, 0, sizeof(iwe));
@@ -2438,8 +2439,8 @@ int prism2_ap_translate_scan(struct net_
iwe.u.qual.noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence);
iwe.u.qual.updated = sta->last_rx_updated;
iwe.len = IW_EV_QUAL_LEN;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
- IW_EV_QUAL_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_QUAL_LEN);
#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT
if (sta->ap) {
@@ -2447,8 +2448,8 @@ int prism2_ap_translate_scan(struct net_
iwe.cmd = SIOCGIWESSID;
iwe.u.data.length = sta->u.ap.ssid_len;
iwe.u.data.flags = 1;
- current_ev = iwe_stream_add_point(current_ev, end_buf,
- &iwe,
+ current_ev = iwe_stream_add_point(info, current_ev,
+ end_buf, &iwe,
sta->u.ap.ssid);
memset(&iwe, 0, sizeof(iwe));
@@ -2458,10 +2459,9 @@ int prism2_ap_translate_scan(struct net_
IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
- current_ev = iwe_stream_add_point(current_ev, end_buf,
- &iwe,
- sta->u.ap.ssid
- /* 0 byte memcpy */);
+ current_ev = iwe_stream_add_point(info, current_ev,
+ end_buf, &iwe,
+ sta->u.ap.ssid);
if (sta->u.ap.channel > 0 &&
sta->u.ap.channel <= FREQ_COUNT) {
@@ -2471,7 +2471,7 @@ int prism2_ap_translate_scan(struct net_
* 100000;
iwe.u.freq.e = 1;
current_ev = iwe_stream_add_event(
- current_ev, end_buf, &iwe,
+ info, current_ev, end_buf, &iwe,
IW_EV_FREQ_LEN);
}
@@ -2480,8 +2480,8 @@ int prism2_ap_translate_scan(struct net_
sprintf(buf, "beacon_interval=%d",
sta->listen_interval);
iwe.u.data.length = strlen(buf);
- current_ev = iwe_stream_add_point(current_ev, end_buf,
- &iwe, buf);
+ current_ev = iwe_stream_add_point(info, current_ev,
+ end_buf, &iwe, buf);
}
#endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
--- a/drivers/net/wireless/hostap/hostap_ioctl.c
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -1794,6 +1794,7 @@ static int prism2_ioctl_siwscan(struct n
#ifndef PRISM2_NO_STATION_MODES
static char * __prism2_translate_scan(local_info_t *local,
+ struct iw_request_info *info,
struct hfa384x_hostscan_result *scan,
struct hostap_bss_info *bss,
char *current_ev, char *end_buf)
@@ -1824,7 +1825,7 @@ static char * __prism2_translate_scan(lo
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, bssid, ETH_ALEN);
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf, &iwe,
IW_EV_ADDR_LEN);
/* Other entries will be displayed in the order we give them */
@@ -1833,7 +1834,8 @@ static char * __prism2_translate_scan(lo
iwe.cmd = SIOCGIWESSID;
iwe.u.data.length = ssid_len;
iwe.u.data.flags = 1;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, ssid);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, ssid);
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = SIOCGIWMODE;
@@ -1848,8 +1850,8 @@ static char * __prism2_translate_scan(lo
iwe.u.mode = IW_MODE_MASTER;
else
iwe.u.mode = IW_MODE_ADHOC;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
- IW_EV_UINT_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_UINT_LEN);
}
memset(&iwe, 0, sizeof(iwe));
@@ -1865,8 +1867,8 @@ static char * __prism2_translate_scan(lo
if (chan > 0) {
iwe.u.freq.m = freq_list[chan - 1] * 100000;
iwe.u.freq.e = 1;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
- IW_EV_FREQ_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_FREQ_LEN);
}
if (scan) {
@@ -1885,8 +1887,8 @@ static char * __prism2_translate_scan(lo
| IW_QUAL_NOISE_UPDATED
| IW_QUAL_QUAL_INVALID
| IW_QUAL_DBM;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
- IW_EV_QUAL_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_QUAL_LEN);
}
memset(&iwe, 0, sizeof(iwe));
@@ -1896,13 +1898,20 @@ static char * __prism2_translate_scan(lo
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, "");
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, "");
/* TODO: add SuppRates into BSS table */
if (scan) {
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = SIOCGIWRATE;
+#ifdef CONFIG_COMPAT
+ if (info->flags & IW_REQUEST_FLAG_COMPAT)
+ current_val = current_ev + IW_EV_COMPAT_LCP_LEN;
+ else
+ current_val = current_ev + IW_EV_LCP_LEN;
+#else
current_val = current_ev + IW_EV_LCP_LEN;
+#endif
pos = scan->sup_rates;
for (i = 0; i < sizeof(scan->sup_rates); i++) {
if (pos[i] == 0)
@@ -1910,7 +1919,7 @@ static char * __prism2_translate_scan(lo
/* Bit rate given in 500 kb/s units (+ 0x80) */
iwe.u.bitrate.value = ((pos[i] & 0x7f) * 500000);
current_val = iwe_stream_add_value(
- current_ev, current_val, end_buf, &iwe,
+ info, current_ev, current_val, end_buf, &iwe,
IW_EV_PARAM_LEN);
}
/* Check if we added any event */
@@ -1925,15 +1934,15 @@ static char * __prism2_translate_scan(lo
iwe.cmd = IWEVCUSTOM;
sprintf(buf, "bcn_int=%d", le16_to_cpu(scan->beacon_interval));
iwe.u.data.length = strlen(buf);
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
- buf);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, buf);
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVCUSTOM;
sprintf(buf, "resp_rate=%d", le16_to_cpu(scan->rate));
iwe.u.data.length = strlen(buf);
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
- buf);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, buf);
if (local->last_scan_type == PRISM2_HOSTSCAN &&
(capabilities & WLAN_CAPABILITY_IBSS)) {
@@ -1941,8 +1950,8 @@ static char * __prism2_translate_scan(lo
iwe.cmd = IWEVCUSTOM;
sprintf(buf, "atim=%d", le16_to_cpu(scan->atim));
iwe.u.data.length = strlen(buf);
- current_ev = iwe_stream_add_point(current_ev, end_buf,
- &iwe, buf);
+ current_ev = iwe_stream_add_point(info, current_ev,
+ end_buf, &iwe, buf);
}
}
kfree(buf);
@@ -1951,16 +1960,16 @@ static char * __prism2_translate_scan(lo
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVGENIE;
iwe.u.data.length = bss->wpa_ie_len;
- current_ev = iwe_stream_add_point(
- current_ev, end_buf, &iwe, bss->wpa_ie);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, bss->wpa_ie);
}
if (bss && bss->rsn_ie_len > 0 && bss->rsn_ie_len <= MAX_WPA_IE_LEN) {
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVGENIE;
iwe.u.data.length = bss->rsn_ie_len;
- current_ev = iwe_stream_add_point(
- current_ev, end_buf, &iwe, bss->rsn_ie);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, bss->rsn_ie);
}
return current_ev;
@@ -1970,6 +1979,7 @@ static char * __prism2_translate_scan(lo
/* Translate scan data returned from the card to a card independant
* format that the Wireless Tools will understand - Jean II */
static inline int prism2_translate_scan(local_info_t *local,
+ struct iw_request_info *info,
char *buffer, int buflen)
{
struct hfa384x_hostscan_result *scan;
@@ -2000,13 +2010,14 @@ static inline int prism2_translate_scan(
if (memcmp(bss->bssid, scan->bssid, ETH_ALEN) == 0) {
bss->included = 1;
current_ev = __prism2_translate_scan(
- local, scan, bss, current_ev, end_buf);
+ local, info, scan, bss, current_ev,
+ end_buf);
found++;
}
}
if (!found) {
current_ev = __prism2_translate_scan(
- local, scan, NULL, current_ev, end_buf);
+ local, info, scan, NULL, current_ev, end_buf);
}
/* Check if there is space for one more entry */
if ((end_buf - current_ev) <= IW_EV_ADDR_LEN) {
@@ -2024,7 +2035,7 @@ static inline int prism2_translate_scan(
bss = list_entry(ptr, struct hostap_bss_info, list);
if (bss->included)
continue;
- current_ev = __prism2_translate_scan(local, NULL, bss,
+ current_ev = __prism2_translate_scan(local, info, NULL, bss,
current_ev, end_buf);
/* Check if there is space for one more entry */
if ((end_buf - current_ev) <= IW_EV_ADDR_LEN) {
@@ -2071,7 +2082,7 @@ static inline int prism2_ioctl_giwscan_s
}
local->scan_timestamp = 0;
- res = prism2_translate_scan(local, extra, data->length);
+ res = prism2_translate_scan(local, info, extra, data->length);
if (res >= 0) {
data->length = res;
@@ -2104,7 +2115,7 @@ static int prism2_ioctl_giwscan(struct n
* Jean II */
/* Translate to WE format */
- res = prism2_ap_translate_scan(dev, extra);
+ res = prism2_ap_translate_scan(dev, info, extra);
if (res >= 0) {
printk(KERN_DEBUG "Scan result translation succeeded "
"(length=%d)\n", res);
--- a/drivers/net/wireless/libertas/scan.c
+++ b/drivers/net/wireless/libertas/scan.c
@@ -1444,8 +1444,9 @@ out:
#define MAX_CUSTOM_LEN 64
static inline char *libertas_translate_scan(wlan_private *priv,
- char *start, char *stop,
- struct bss_descriptor *bss)
+ struct iw_request_info *info,
+ char *start, char *stop,
+ struct bss_descriptor *bss)
{
wlan_adapter *adapter = priv->adapter;
struct chan_freq_power *cfp;
@@ -1470,24 +1471,24 @@ static inline char *libertas_translate_s
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, &bss->bssid, ETH_ALEN);
- start = iwe_stream_add_event(start, stop, &iwe, IW_EV_ADDR_LEN);
+ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
/* SSID */
iwe.cmd = SIOCGIWESSID;
iwe.u.data.flags = 1;
iwe.u.data.length = min((u32) bss->ssid_len, (u32) IW_ESSID_MAX_SIZE);
- start = iwe_stream_add_point(start, stop, &iwe, bss->ssid);
+ start = iwe_stream_add_point(info, start, stop, &iwe, bss->ssid);
/* Mode */
iwe.cmd = SIOCGIWMODE;
iwe.u.mode = bss->mode;
- start = iwe_stream_add_event(start, stop, &iwe, IW_EV_UINT_LEN);
+ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_UINT_LEN);
/* Frequency */
iwe.cmd = SIOCGIWFREQ;
iwe.u.freq.m = (long)cfp->freq * 100000;
iwe.u.freq.e = 1;
- start = iwe_stream_add_event(start, stop, &iwe, IW_EV_FREQ_LEN);
+ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN);
/* Add quality statistics */
iwe.cmd = IWEVQUAL;
@@ -1523,7 +1524,7 @@ static inline char *libertas_translate_s
nf = adapter->NF[TYPE_RXPD][TYPE_AVG] / AVG_SCALE;
iwe.u.qual.level = CAL_RSSI(snr, nf);
}
- start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN);
+ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
/* Add encryption capability */
iwe.cmd = SIOCGIWENCODE;
@@ -1533,9 +1534,16 @@ static inline char *libertas_translate_s
iwe.u.data.flags = IW_ENCODE_DISABLED;
}
iwe.u.data.length = 0;
- start = iwe_stream_add_point(start, stop, &iwe, bss->ssid);
+ start = iwe_stream_add_point(info, start, stop, &iwe, bss->ssid);
+#ifdef CONFIG_COMPAT
+ if (info->flags & IW_REQUEST_FLAG_COMPAT)
+ current_val = start + IW_EV_COMAT_LCP_LEN;
+ else
+ current_val = start + IW_EV_LCP_LEN;
+#else
current_val = start + IW_EV_LCP_LEN;
+#endif
iwe.cmd = SIOCGIWRATE;
iwe.u.bitrate.fixed = 0;
@@ -1545,8 +1553,8 @@ static inline char *libertas_translate_s
for (j = 0; bss->rates[j] && (j < sizeof(bss->rates)); j++) {
/* Bit rate given in 500 kb/s units */
iwe.u.bitrate.value = bss->rates[j] * 500000;
- current_val = iwe_stream_add_value(start, current_val,
- stop, &iwe, IW_EV_PARAM_LEN);
+ current_val = iwe_stream_add_value(info, start, current_val,
+ stop, &iwe, IW_EV_PARAM_LEN);
}
if ((bss->mode == IW_MODE_ADHOC)
&& !libertas_ssid_cmp(adapter->curbssparams.ssid,
@@ -1554,8 +1562,8 @@ static inline char *libertas_translate_s
bss->ssid, bss->ssid_len)
&& adapter->adhoccreate) {
iwe.u.bitrate.value = 22 * 500000;
- current_val = iwe_stream_add_value(start, current_val,
- stop, &iwe, IW_EV_PARAM_LEN);
+ current_val = iwe_stream_add_value(info, start, current_val,
+ stop, &iwe, IW_EV_PARAM_LEN);
}
/* Check if we added any event */
if((current_val - start) > IW_EV_LCP_LEN)
@@ -1567,7 +1575,7 @@ static inline char *libertas_translate_s
memcpy(buf, bss->wpa_ie, bss->wpa_ie_len);
iwe.cmd = IWEVGENIE;
iwe.u.data.length = bss->wpa_ie_len;
- start = iwe_stream_add_point(start, stop, &iwe, buf);
+ start = iwe_stream_add_point(info, start, stop, &iwe, buf);
}
memset(&iwe, 0, sizeof(iwe));
@@ -1576,7 +1584,7 @@ static inline char *libertas_translate_s
memcpy(buf, bss->rsn_ie, bss->rsn_ie_len);
iwe.cmd = IWEVGENIE;
iwe.u.data.length = bss->rsn_ie_len;
- start = iwe_stream_add_point(start, stop, &iwe, buf);
+ start = iwe_stream_add_point(info, start, stop, &iwe, buf);
}
if (bss->mesh) {
@@ -1588,7 +1596,8 @@ static inline char *libertas_translate_s
"mesh-type: olpc");
iwe.u.data.length = p - custom;
if (iwe.u.data.length)
- start = iwe_stream_add_point(start, stop, &iwe, custom);
+ start = iwe_stream_add_point(info, start, stop,
+ &iwe, custom);
}
out:
@@ -1650,7 +1659,8 @@ int libertas_get_scan(struct net_device
}
/* Translate to WE format this entry */
- next_ev = libertas_translate_scan(priv, ev, stop, iter_bss);
+ next_ev = libertas_translate_scan(priv, info, ev, stop,
+ iter_bss);
if (next_ev == NULL)
continue;
ev = next_ev;
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -3909,6 +3909,7 @@ static int orinoco_ioctl_setscan(struct
* format that the Wireless Tools will understand - Jean II
* Return message length or -errno for fatal errors */
static inline int orinoco_translate_scan(struct net_device *dev,
+ struct iw_request_info *info,
char *buffer,
char *scan,
int scan_len)
@@ -3979,7 +3980,8 @@ static inline int orinoco_translate_scan
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, atom->a.bssid, ETH_ALEN);
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_ADDR_LEN);
/* Other entries will be displayed in the order we give them */
@@ -3989,7 +3991,8 @@ static inline int orinoco_translate_scan
iwe.u.data.length = 32;
iwe.cmd = SIOCGIWESSID;
iwe.u.data.flags = 1;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, atom->a.essid);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, atom->a.essid);
/* Add mode */
iwe.cmd = SIOCGIWMODE;
@@ -3999,7 +4002,9 @@ static inline int orinoco_translate_scan
iwe.u.mode = IW_MODE_MASTER;
else
iwe.u.mode = IW_MODE_ADHOC;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_UINT_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev,
+ end_buf, &iwe,
+ IW_EV_UINT_LEN);
}
channel = atom->s.channel;
@@ -4008,8 +4013,9 @@ static inline int orinoco_translate_scan
iwe.cmd = SIOCGIWFREQ;
iwe.u.freq.m = channel_frequency[channel-1] * 100000;
iwe.u.freq.e = 1;
- current_ev = iwe_stream_add_event(current_ev, end_buf,
- &iwe, IW_EV_FREQ_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev,
+ end_buf, &iwe,
+ IW_EV_FREQ_LEN);
}
/* Add quality statistics */
@@ -4023,7 +4029,8 @@ static inline int orinoco_translate_scan
iwe.u.qual.qual = iwe.u.qual.level - iwe.u.qual.noise;
else
iwe.u.qual.qual = 0;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_QUAL_LEN);
/* Add encryption capability */
iwe.cmd = SIOCGIWENCODE;
@@ -4032,14 +4039,22 @@ static inline int orinoco_translate_scan
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, atom->a.essid);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, atom->a.essid);
/* Bit rate is not available in Lucent/Agere firmwares */
if (priv->firmware_type != FIRMWARE_TYPE_AGERE) {
- char * current_val = current_ev + IW_EV_LCP_LEN;
+ char *current_val;
int i;
int step;
-
+#ifdef CONFIG_COMPAT
+ if (info->flags & IW_REQUEST_FLAG_COMPAT)
+ current_val = current_ev + IW_EV_COMPAT_LCP_LEN;
+ else
+ current_val = current_ev + IW_EV_LCP_LEN;
+#else
+ current_val = current_ev + IW_EV_LCP_LEN;
+#endif
if (priv->firmware_type == FIRMWARE_TYPE_SYMBOL)
step = 2;
else
@@ -4055,9 +4070,9 @@ static inline int orinoco_translate_scan
break;
/* Bit rate given in 500 kb/s units (+ 0x80) */
iwe.u.bitrate.value = ((atom->p.rates[i] & 0x7f) * 500000);
- current_val = iwe_stream_add_value(current_ev, current_val,
- end_buf, &iwe,
- IW_EV_PARAM_LEN);
+ current_val = iwe_stream_add_value(
+ info, current_ev, current_val,
+ end_buf, &iwe, IW_EV_PARAM_LEN);
}
/* Check if we added any event */
if ((current_val - current_ev) > IW_EV_LCP_LEN)
@@ -4102,7 +4117,7 @@ static int orinoco_ioctl_getscan(struct
/* We have some results to push back to user space */
/* Translate to WE format */
- int ret = orinoco_translate_scan(dev, extra,
+ int ret = orinoco_translate_scan(dev, info, extra,
priv->scan_result,
priv->scan_len);
--- a/drivers/net/wireless/prism54/isl_ioctl.c
+++ b/drivers/net/wireless/prism54/isl_ioctl.c
@@ -572,8 +572,9 @@ prism54_set_scan(struct net_device *dev,
*/
static char *
-prism54_translate_bss(struct net_device *ndev, char *current_ev,
- char *end_buf, struct obj_bss *bss, char noise)
+prism54_translate_bss(struct net_device *ndev, struct iw_request_info *info,
+ char *current_ev, char *end_buf, struct obj_bss *bss,
+ char noise)
{
struct iw_event iwe; /* Temporary buffer */
short cap;
@@ -585,8 +586,8 @@ prism54_translate_bss(struct net_device
memcpy(iwe.u.ap_addr.sa_data, bss->address, 6);
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
iwe.cmd = SIOCGIWAP;
- current_ev =
- iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_ADDR_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_ADDR_LEN);
/* The following entries will be displayed in the same order we give them */
@@ -594,7 +595,7 @@ prism54_translate_bss(struct net_device
iwe.u.data.length = bss->ssid.length;
iwe.u.data.flags = 1;
iwe.cmd = SIOCGIWESSID;
- current_ev = iwe_stream_add_point(current_ev, end_buf,
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
&iwe, bss->ssid.octets);
/* Capabilities */
@@ -611,9 +612,8 @@ prism54_translate_bss(struct net_device
iwe.u.mode = IW_MODE_ADHOC;
iwe.cmd = SIOCGIWMODE;
if (iwe.u.mode)
- current_ev =
- iwe_stream_add_event(current_ev, end_buf, &iwe,
- IW_EV_UINT_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_UINT_LEN);
/* Encryption capability */
if (cap & CAP_CRYPT)
@@ -622,14 +622,15 @@ prism54_translate_bss(struct net_device
iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0;
iwe.cmd = SIOCGIWENCODE;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, NULL);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, NULL);
/* Add frequency. (short) bss->channel is the frequency in MHz */
iwe.u.freq.m = bss->channel;
iwe.u.freq.e = 6;
iwe.cmd = SIOCGIWFREQ;
- current_ev =
- iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_FREQ_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_FREQ_LEN);
/* Add quality statistics */
iwe.u.qual.level = bss->rssi;
@@ -637,24 +638,32 @@ prism54_translate_bss(struct net_device
/* do a simple SNR for quality */
iwe.u.qual.qual = bss->rssi - noise;
iwe.cmd = IWEVQUAL;
- current_ev =
- iwe_stream_add_event(current_ev, end_buf, &iwe, IW_EV_QUAL_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_QUAL_LEN);
/* Add WPA/RSN Information Element, if any */
wpa_ie_len = prism54_wpa_bss_ie_get(priv, bss->address, wpa_ie);
if (wpa_ie_len > 0) {
iwe.cmd = IWEVGENIE;
iwe.u.data.length = min(wpa_ie_len, (size_t)MAX_WPA_IE_LEN);
- current_ev = iwe_stream_add_point(current_ev, end_buf,
- &iwe, wpa_ie);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, wpa_ie);
}
/* Do the bitrates */
{
- char * current_val = current_ev + IW_EV_LCP_LEN;
+ char *current_val;
int i;
int mask;
iwe.cmd = SIOCGIWRATE;
+#ifdef CONFIG_COMPAT
+ if (info->flags & IW_REQUEST_FLAG_COMPAT)
+ current_val = current_ev + IW_EV_COMPAT_LCP_LEN;
+ else
+ current_val = current_ev + IW_EV_LCP_LEN;
+#else
+ current_val = current_ev + IW_EV_LCP_LEN;
+#endif
/* Those two flags are ignored... */
iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
@@ -663,9 +672,9 @@ prism54_translate_bss(struct net_device
for(i = 0; i < sizeof(scan_rate_list); i++) {
if(bss->rates & mask) {
iwe.u.bitrate.value = (scan_rate_list[i] * 500000);
- current_val = iwe_stream_add_value(current_ev, current_val,
- end_buf, &iwe,
- IW_EV_PARAM_LEN);
+ current_val = iwe_stream_add_value(
+ info, current_ev, current_val,
+ end_buf, &iwe, IW_EV_PARAM_LEN);
}
mask <<= 1;
}
@@ -711,7 +720,7 @@ prism54_get_scan(struct net_device *ndev
/* ok now, scan the list and translate its info */
for (i = 0; i < (int) bsslist->nr; i++) {
- current_ev = prism54_translate_bss(ndev, current_ev,
+ current_ev = prism54_translate_bss(ndev, info, current_ev,
extra + dwrq->length,
&(bsslist->bsslist[i]),
noise);
@@ -2705,6 +2714,7 @@ prism2_ioctl_scan_req(struct net_device
struct prism2_hostapd_param *param)
{
islpci_private *priv = netdev_priv(ndev);
+ struct iw_request_info info;
int i, rvalue;
struct obj_bsslist *bsslist;
u32 noise = 0;
@@ -2728,9 +2738,12 @@ prism2_ioctl_scan_req(struct net_device
rvalue |= mgt_get_request(priv, DOT11_OID_BSSLIST, 0, NULL, &r);
bsslist = r.ptr;
+ info.cmd = PRISM54_HOSTAPD;
+ info.flags = 0;
+
/* ok now, scan the list and translate its info */
for (i = 0; i < min(IW_MAX_AP, (int) bsslist->nr); i++)
- current_ev = prism54_translate_bss(ndev, current_ev,
+ current_ev = prism54_translate_bss(ndev, current_ev, &info,
extra + IW_SCAN_MAX_DATA,
&(bsslist->bsslist[i]),
noise);
--- 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_de
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, this->bss_set[i].bssid, ETH_ALEN);
- current_ev = iwe_stream_add_event(current_ev,
+ current_ev = iwe_stream_add_event(info, current_ev,
extra + IW_SCAN_MAX_DATA,
&iwe, IW_EV_ADDR_LEN);
iwe.cmd = SIOCGIWESSID;
iwe.u.data.flags = 1;
iwe.u.data.length = this->bss_set[i].ssid.el.len;
- current_ev = iwe_stream_add_point(current_ev,
+ current_ev = iwe_stream_add_point(info, current_ev,
extra + IW_SCAN_MAX_DATA,
&iwe,
this->bss_set[i].ssid.essid);
iwe.cmd = SIOCGIWMODE;
iwe.u.mode = this->bss_set[i].bss_type;
- current_ev = iwe_stream_add_event(current_ev,
+ current_ev = iwe_stream_add_event(info, current_ev,
extra + IW_SCAN_MAX_DATA,
&iwe, IW_EV_UINT_LEN);
iwe.cmd = SIOCGIWFREQ;
iwe.u.freq.m = this->bss_set[i].ds_pset.chan;
iwe.u.freq.e = 0;
- current_ev = iwe_stream_add_event(current_ev,
+ current_ev = iwe_stream_add_event(info, current_ev,
extra + IW_SCAN_MAX_DATA,
&iwe, IW_EV_FREQ_LEN);
iwe.cmd = SIOCGIWENCODE;
@@ -1651,7 +1651,7 @@ static int wl3501_get_scan(struct net_de
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0;
- current_ev = iwe_stream_add_point(current_ev,
+ current_ev = iwe_stream_add_point(info, current_ev,
extra + IW_SCAN_MAX_DATA,
&iwe, NULL);
}
--- a/drivers/net/wireless/zd1201.c
+++ b/drivers/net/wireless/zd1201.c
@@ -1152,32 +1152,36 @@ static int zd1201_get_scan(struct net_de
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, zd->rxdata+i+6, 6);
- cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_ADDR_LEN);
+ cev = iwe_stream_add_event(info, cev, end_buf,
+ &iwe, IW_EV_ADDR_LEN);
iwe.cmd = SIOCGIWESSID;
iwe.u.data.length = zd->rxdata[i+16];
iwe.u.data.flags = 1;
- cev = iwe_stream_add_point(cev, end_buf, &iwe, zd->rxdata+i+18);
+ cev = iwe_stream_add_point(info, cev, end_buf,
+ &iwe, zd->rxdata+i+18);
iwe.cmd = SIOCGIWMODE;
if (zd->rxdata[i+14]&0x01)
iwe.u.mode = IW_MODE_MASTER;
else
iwe.u.mode = IW_MODE_ADHOC;
- cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_UINT_LEN);
+ cev = iwe_stream_add_event(info, cev, end_buf,
+ &iwe, IW_EV_UINT_LEN);
iwe.cmd = SIOCGIWFREQ;
iwe.u.freq.m = zd->rxdata[i+0];
iwe.u.freq.e = 0;
- cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_FREQ_LEN);
+ cev = iwe_stream_add_event(info, cev, end_buf,
+ &iwe, IW_EV_FREQ_LEN);
iwe.cmd = SIOCGIWRATE;
iwe.u.bitrate.fixed = 0;
iwe.u.bitrate.disabled = 0;
for (j=0; j<10; j++) if (zd->rxdata[i+50+j]) {
iwe.u.bitrate.value = (zd->rxdata[i+50+j]&0x7f)*500000;
- cev=iwe_stream_add_event(cev, end_buf, &iwe,
- IW_EV_PARAM_LEN);
+ cev=iwe_stream_add_event(info, cev, end_buf,
+ &iwe, IW_EV_PARAM_LEN);
}
iwe.cmd = SIOCGIWENCODE;
@@ -1186,14 +1190,15 @@ static int zd1201_get_scan(struct net_de
iwe.u.data.flags = IW_ENCODE_ENABLED;
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
- cev = iwe_stream_add_point(cev, end_buf, &iwe, NULL);
+ cev = iwe_stream_add_point(info, cev, end_buf, &iwe, NULL);
iwe.cmd = IWEVQUAL;
iwe.u.qual.qual = zd->rxdata[i+4];
iwe.u.qual.noise= zd->rxdata[i+2]/10-100;
iwe.u.qual.level = (256+zd->rxdata[i+4]*100)/255-100;
iwe.u.qual.updated = 7;
- cev = iwe_stream_add_event(cev, end_buf, &iwe, IW_EV_QUAL_LEN);
+ cev = iwe_stream_add_event(info, cev, end_buf,
+ &iwe, IW_EV_QUAL_LEN);
}
if (!enabled_save)
--- a/include/linux/wireless.h
+++ b/include/linux/wireless.h
@@ -1098,6 +1098,19 @@ struct iw_event
#define IW_EV_POINT_LEN (IW_EV_LCP_LEN + sizeof(struct iw_point) - \
IW_EV_POINT_OFF)
+#if defined(__KERNEL__) && defined(CONFIG_COMPAT)
+struct __compat_iw_event {
+ __u16 len; /* Real length of this stuff */
+ __u16 cmd; /* Wireless IOCTL */
+ compat_caddr_t pointer;
+};
+#define IW_EV_COMPAT_LCP_LEN offsetof(struct __compat_iw_event, pointer)
+#define IW_EV_COMPAT_POINT_OFF offsetof(struct compat_iw_point, length)
+#define IW_EV_COMPAT_POINT_LEN \
+ (IW_EV_COMPAT_LCP_LEN + sizeof(struct compat_iw_point) - \
+ IW_EV_COMPAT_POINT_OFF)
+#endif
+
/* Size of the Event prefix when packed in stream */
#define IW_EV_LCP_PK_LEN (4)
/* Size of the various events when packed in stream */
--- a/include/net/iw_handler.h
+++ b/include/net/iw_handler.h
@@ -483,19 +483,26 @@ extern void wireless_spy_update(struct n
* Wrapper to add an Wireless Event to a stream of events.
*/
static inline char *
-iwe_stream_add_event(char * stream, /* Stream of events */
- char * ends, /* End of stream */
- struct iw_event *iwe, /* Payload */
- int event_len) /* Real size of payload */
+iwe_stream_add_event(struct iw_request_info *info, char *stream, char *ends,
+ struct iw_event *iwe, int event_len)
{
+ int lcp_len = IW_EV_LCP_LEN;
+ int org_event_len = event_len;
+
+#ifdef CONFIG_COMPAT
+ if (info->flags & IW_REQUEST_FLAG_COMPAT) {
+ event_len -= IW_EV_LCP_LEN;
+ event_len += IW_EV_COMPAT_LCP_LEN;
+ lcp_len = IW_EV_COMPAT_LCP_LEN;
+ }
+#endif
/* Check if it's possible */
if(likely((stream + event_len) < ends)) {
iwe->len = event_len;
/* Beware of alignement issues on 64 bits */
memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
- memcpy(stream + IW_EV_LCP_LEN,
- ((char *) iwe) + IW_EV_LCP_LEN,
- event_len - IW_EV_LCP_LEN);
+ memcpy(stream + lcp_len, &iwe->u,
+ org_event_len - IW_EV_LCP_LEN);
stream += event_len;
}
return stream;
@@ -507,104 +514,31 @@ iwe_stream_add_event(char * stream, /*
* stream of events.
*/
static inline char *
-iwe_stream_add_point(char * stream, /* Stream of events */
- char * ends, /* End of stream */
- struct iw_event *iwe, /* Payload length + flags */
- char * extra) /* More payload */
-{
- int event_len = IW_EV_POINT_LEN + iwe->u.data.length;
- /* Check if it's possible */
- if(likely((stream + event_len) < ends)) {
- iwe->len = event_len;
- memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
- memcpy(stream + IW_EV_LCP_LEN,
- ((char *) iwe) + IW_EV_LCP_LEN + IW_EV_POINT_OFF,
- IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN);
- memcpy(stream + IW_EV_POINT_LEN, extra, iwe->u.data.length);
- stream += event_len;
- }
- return stream;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wrapper to add a value to a Wireless Event in a stream of events.
- * Be careful, this one is tricky to use properly :
- * At the first run, you need to have (value = event + IW_EV_LCP_LEN).
- */
-static inline char *
-iwe_stream_add_value(char * event, /* Event in the stream */
- char * value, /* Value in event */
- char * ends, /* End of stream */
- struct iw_event *iwe, /* Payload */
- int event_len) /* Real size of payload */
+iwe_stream_add_point(struct iw_request_info *info, char *stream, char *ends,
+ struct iw_event *iwe, char *extra)
{
- /* Don't duplicate LCP */
- event_len -= IW_EV_LCP_LEN;
-
- /* Check if it's possible */
- if(likely((value + event_len) < ends)) {
- /* Add new value */
- memcpy(value, (char *) iwe + IW_EV_LCP_LEN, event_len);
- value += event_len;
- /* Patch LCP */
- iwe->len = value - event;
- memcpy(event, (char *) iwe, IW_EV_LCP_LEN);
+ int event_len = IW_EV_POINT_LEN + iwe->u.data.length;
+ int point_len = IW_EV_POINT_LEN;
+ int lcp_len = IW_EV_LCP_LEN;
+
+#ifdef CONFIG_COMPAT
+ if (info->flags & IW_REQUEST_FLAG_COMPAT) {
+ event_len = IW_EV_COMPAT_POINT_LEN + iwe->u.data.length;
+ point_len = IW_EV_COMPAT_POINT_LEN;
+ lcp_len = IW_EV_COMPAT_LCP_LEN;
}
- return value;
-}
-
-/*------------------------------------------------------------------*/
-/*
- * Wrapper to add an Wireless Event to a stream of events.
- * Same as above, with explicit error check...
- */
-static inline char *
-iwe_stream_check_add_event(char * stream, /* Stream of events */
- char * ends, /* End of stream */
- struct iw_event *iwe, /* Payload */
- int event_len, /* Size of payload */
- int * perr) /* Error report */
-{
- /* Check if it's possible, set error if not */
- if(likely((stream + event_len) < ends)) {
- iwe->len = event_len;
- /* Beware of alignement issues on 64 bits */
- memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
- memcpy(stream + IW_EV_LCP_LEN,
- ((char *) iwe) + IW_EV_LCP_LEN,
- event_len - IW_EV_LCP_LEN);
- stream += event_len;
- } else
- *perr = -E2BIG;
- return stream;
-}
+#endif
-/*------------------------------------------------------------------*/
-/*
- * Wrapper to add an short Wireless Event containing a pointer to a
- * stream of events.
- * Same as above, with explicit error check...
- */
-static inline char *
-iwe_stream_check_add_point(char * stream, /* Stream of events */
- char * ends, /* End of stream */
- struct iw_event *iwe, /* Payload length + flags */
- char * extra, /* More payload */
- int * perr) /* Error report */
-{
- int event_len = IW_EV_POINT_LEN + iwe->u.data.length;
/* Check if it's possible */
if(likely((stream + event_len) < ends)) {
iwe->len = event_len;
memcpy(stream, (char *) iwe, IW_EV_LCP_PK_LEN);
- memcpy(stream + IW_EV_LCP_LEN,
- ((char *) iwe) + IW_EV_LCP_LEN + IW_EV_POINT_OFF,
+ memcpy(stream + lcp_len,
+ &iwe->u.data.length,
IW_EV_POINT_PK_LEN - IW_EV_LCP_PK_LEN);
- memcpy(stream + IW_EV_POINT_LEN, extra, iwe->u.data.length);
+ memcpy(stream + point_len, extra, iwe->u.data.length);
stream += event_len;
- } else
- *perr = -E2BIG;
+ }
return stream;
}
@@ -612,30 +546,38 @@ iwe_stream_check_add_point(char * stream
/*
* Wrapper to add a value to a Wireless Event in a stream of events.
* Be careful, this one is tricky to use properly :
- * At the first run, you need to have (value = event + IW_EV_LCP_LEN).
- * Same as above, with explicit error check...
- */
-static inline char *
-iwe_stream_check_add_value(char * event, /* Event in the stream */
- char * value, /* Value in event */
- char * ends, /* End of stream */
- struct iw_event *iwe, /* Payload */
- int event_len, /* Size of payload */
- int * perr) /* Error report */
-{
+ * At the first run, you need to have the code like:
+ * #ifdef CONFIG_COMPAT
+ * if (info->flags & IW_REQUEST_FLAG_COMPAT)
+ * value = ev + IW_EV_COMPAT_LCP_LEN;
+ * else
+ * value = ev + IW_EV_COMPAT_LEN;
+ * #else
+ * value = ev + IW_EV_COMPAT_LEN;
+ * #endif
+ */
+static inline char *
+iwe_stream_add_value(struct iw_request_info *info, char *event, char *value,
+ char *ends, struct iw_event *iwe, int event_len)
+{
+ int lcp_len = IW_EV_LCP_LEN;
+
+#ifdef CONFIG_COMPAT
+ if (info->flags & IW_REQUEST_FLAG_COMPAT)
+ lcp_len = IW_EV_COMPAT_LCP_LEN;
+#endif
/* Don't duplicate LCP */
event_len -= IW_EV_LCP_LEN;
/* Check if it's possible */
if(likely((value + event_len) < ends)) {
/* Add new value */
- memcpy(value, (char *) iwe + IW_EV_LCP_LEN, event_len);
+ memcpy(value, &iwe->u, event_len);
value += event_len;
/* Patch LCP */
iwe->len = value - event;
- memcpy(event, (char *) iwe, IW_EV_LCP_LEN);
- } else
- *perr = -E2BIG;
+ memcpy(event, (char *) iwe, lcp_len);
+ }
return value;
}
--- a/net/ieee80211/ieee80211_wx.c
+++ b/net/ieee80211/ieee80211_wx.c
@@ -43,8 +43,9 @@ static const char *ieee80211_modes[] = {
#define MAX_CUSTOM_LEN 64
static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
- char *start, char *stop,
- struct ieee80211_network *network)
+ char *start, char *stop,
+ struct ieee80211_network *network,
+ struct iw_request_info *info)
{
char custom[MAX_CUSTOM_LEN];
char *p;
@@ -57,7 +58,7 @@ static char *ieee80211_translate_scan(st
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, network->bssid, ETH_ALEN);
- start = iwe_stream_add_event(start, stop, &iwe, IW_EV_ADDR_LEN);
+ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
/* Remaining entries will be displayed in the order we provide them */
@@ -66,17 +67,19 @@ static char *ieee80211_translate_scan(st
iwe.u.data.flags = 1;
if (network->flags & NETWORK_EMPTY_ESSID) {
iwe.u.data.length = sizeof("<hidden>");
- start = iwe_stream_add_point(start, stop, &iwe, "<hidden>");
+ start = iwe_stream_add_point(info, start, stop,
+ &iwe, "<hidden>");
} else {
iwe.u.data.length = min(network->ssid_len, (u8) 32);
- start = iwe_stream_add_point(start, stop, &iwe, network->ssid);
+ start = iwe_stream_add_point(info, start, stop,
+ &iwe, network->ssid);
}
/* Add the protocol name */
iwe.cmd = SIOCGIWNAME;
snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11%s",
ieee80211_modes[network->mode]);
- start = iwe_stream_add_event(start, stop, &iwe, IW_EV_CHAR_LEN);
+ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
/* Add mode */
iwe.cmd = SIOCGIWMODE;
@@ -86,7 +89,8 @@ static char *ieee80211_translate_scan(st
else
iwe.u.mode = IW_MODE_ADHOC;
- start = iwe_stream_add_event(start, stop, &iwe, IW_EV_UINT_LEN);
+ start = iwe_stream_add_event(info, start, stop,
+ &iwe, IW_EV_UINT_LEN);
}
/* Add channel and frequency */
@@ -95,7 +99,7 @@ static char *ieee80211_translate_scan(st
iwe.u.freq.m = ieee80211_channel_to_freq(ieee, network->channel);
iwe.u.freq.e = 6;
iwe.u.freq.i = 0;
- start = iwe_stream_add_event(start, stop, &iwe, IW_EV_FREQ_LEN);
+ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN);
/* Add encryption capability */
iwe.cmd = SIOCGIWENCODE;
@@ -104,12 +108,20 @@ static char *ieee80211_translate_scan(st
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0;
- start = iwe_stream_add_point(start, stop, &iwe, network->ssid);
+ start = iwe_stream_add_point(info, start, stop,
+ &iwe, network->ssid);
/* Add basic and extended rates */
/* Rate : stuffing multiple values in a single event require a bit
* more of magic - Jean II */
+#ifdef CONFIG_COMPAT
+ if (info->flags & IW_REQUEST_FLAG_COMPAT)
+ current_val = start + IW_EV_COMPAT_LCP_LEN;
+ else
+ current_val = start + IW_EV_LCP_LEN;
+#else
current_val = start + IW_EV_LCP_LEN;
+#endif
iwe.cmd = SIOCGIWRATE;
/* Those two flags are ignored... */
iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
@@ -124,14 +136,16 @@ static char *ieee80211_translate_scan(st
/* Bit rate given in 500 kb/s units (+ 0x80) */
iwe.u.bitrate.value = ((rate & 0x7f) * 500000);
/* Add new value to event */
- current_val = iwe_stream_add_value(start, current_val, stop, &iwe, IW_EV_PARAM_LEN);
+ current_val = iwe_stream_add_value(info, start, current_val,
+ stop, &iwe, IW_EV_PARAM_LEN);
}
for (; j < network->rates_ex_len; j++) {
rate = network->rates_ex[j] & 0x7F;
/* Bit rate given in 500 kb/s units (+ 0x80) */
iwe.u.bitrate.value = ((rate & 0x7f) * 500000);
/* Add new value to event */
- current_val = iwe_stream_add_value(start, current_val, stop, &iwe, IW_EV_PARAM_LEN);
+ current_val = iwe_stream_add_value(info, start, current_val,
+ stop, &iwe, IW_EV_PARAM_LEN);
}
/* Check if we added any rate */
if((current_val - start) > IW_EV_LCP_LEN)
@@ -181,14 +195,14 @@ static char *ieee80211_translate_scan(st
iwe.u.qual.level = network->stats.signal;
}
- start = iwe_stream_add_event(start, stop, &iwe, IW_EV_QUAL_LEN);
+ start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
iwe.cmd = IWEVCUSTOM;
p = custom;
iwe.u.data.length = p - custom;
if (iwe.u.data.length)
- start = iwe_stream_add_point(start, stop, &iwe, custom);
+ start = iwe_stream_add_point(info, start, stop, &iwe, custom);
memset(&iwe, 0, sizeof(iwe));
if (network->wpa_ie_len) {
@@ -196,7 +210,7 @@ static char *ieee80211_translate_scan(st
memcpy(buf, network->wpa_ie, network->wpa_ie_len);
iwe.cmd = IWEVGENIE;
iwe.u.data.length = network->wpa_ie_len;
- start = iwe_stream_add_point(start, stop, &iwe, buf);
+ start = iwe_stream_add_point(info, start, stop, &iwe, buf);
}
memset(&iwe, 0, sizeof(iwe));
@@ -205,7 +219,7 @@ static char *ieee80211_translate_scan(st
memcpy(buf, network->rsn_ie, network->rsn_ie_len);
iwe.cmd = IWEVGENIE;
iwe.u.data.length = network->rsn_ie_len;
- start = iwe_stream_add_point(start, stop, &iwe, buf);
+ start = iwe_stream_add_point(info, start, stop, &iwe, buf);
}
/* Add EXTRA: Age to display seconds since last beacon/probe response
@@ -217,7 +231,7 @@ static char *ieee80211_translate_scan(st
jiffies_to_msecs(jiffies - network->last_scanned));
iwe.u.data.length = p - custom;
if (iwe.u.data.length)
- start = iwe_stream_add_point(start, stop, &iwe, custom);
+ start = iwe_stream_add_point(info, start, stop, &iwe, custom);
/* Add spectrum management information */
iwe.cmd = -1;
@@ -238,7 +252,7 @@ static char *ieee80211_translate_scan(st
if (iwe.cmd == IWEVCUSTOM) {
iwe.u.data.length = p - custom;
- start = iwe_stream_add_point(start, stop, &iwe, custom);
+ start = iwe_stream_add_point(info, start, stop, &iwe, custom);
}
return start;
@@ -272,7 +286,8 @@ int ieee80211_wx_get_scan(struct ieee802
if (ieee->scan_age == 0 ||
time_after(network->last_scanned + ieee->scan_age, jiffies))
- ev = ieee80211_translate_scan(ieee, ev, stop, network);
+ ev = ieee80211_translate_scan(ieee, ev, stop, network,
+ info);
else
IEEE80211_DEBUG_SCAN("Not showing network '%s ("
"%s)' due to age (%dms).\n",
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -23,6 +23,7 @@
#include <linux/spinlock.h>
#include <linux/etherdevice.h>
#include <net/wireless.h>
+#include <net/iw_handler.h>
#include "ieee80211_key.h"
#include "sta_info.h"
@@ -748,7 +749,9 @@ int ieee80211_sta_set_bssid(struct net_d
int ieee80211_sta_req_scan(struct net_device *dev, u8 *ssid, size_t ssid_len);
void ieee80211_sta_req_auth(struct net_device *dev,
struct ieee80211_if_sta *ifsta);
-int ieee80211_sta_scan_results(struct net_device *dev, char *buf, size_t len);
+int ieee80211_sta_scan_results(struct net_device *dev,
+ struct iw_request_info *info,
+ char *buf, size_t len);
void ieee80211_sta_rx_scan(struct net_device *dev, struct sk_buff *skb,
struct ieee80211_rx_status *rx_status);
void ieee80211_rx_bss_list_init(struct net_device *dev);
--- a/net/mac80211/ieee80211_ioctl.c
+++ b/net/mac80211/ieee80211_ioctl.c
@@ -560,7 +560,7 @@ static int ieee80211_ioctl_giwscan(struc
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
if (local->sta_scanning)
return -EAGAIN;
- res = ieee80211_sta_scan_results(dev, extra, data->length);
+ res = ieee80211_sta_scan_results(dev, info, extra, data->length);
if (res >= 0) {
data->length = res;
return 0;
--- a/net/mac80211/ieee80211_sta.c
+++ b/net/mac80211/ieee80211_sta.c
@@ -2881,6 +2881,7 @@ int ieee80211_sta_req_scan(struct net_de
static char *
ieee80211_sta_scan_result(struct net_device *dev,
+ struct iw_request_info *info,
struct ieee80211_sta_bss *bss,
char *current_ev, char *end_buf)
{
@@ -2907,15 +2908,15 @@ ieee80211_sta_scan_result(struct net_dev
iwe.cmd = SIOCGIWAP;
iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
memcpy(iwe.u.ap_addr.sa_data, bss->bssid, ETH_ALEN);
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
- IW_EV_ADDR_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_ADDR_LEN);
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = SIOCGIWESSID;
iwe.u.data.length = bss->ssid_len;
iwe.u.data.flags = 1;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
- bss->ssid);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, bss->ssid);
if (bss->capability & (WLAN_CAPABILITY_ESS | WLAN_CAPABILITY_IBSS)) {
memset(&iwe, 0, sizeof(iwe));
@@ -2924,20 +2925,20 @@ ieee80211_sta_scan_result(struct net_dev
iwe.u.mode = IW_MODE_MASTER;
else
iwe.u.mode = IW_MODE_ADHOC;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
- IW_EV_UINT_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_UINT_LEN);
}
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = SIOCGIWFREQ;
iwe.u.freq.m = bss->channel;
iwe.u.freq.e = 0;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
- IW_EV_FREQ_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_FREQ_LEN);
iwe.u.freq.m = bss->freq * 100000;
iwe.u.freq.e = 1;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
- IW_EV_FREQ_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_FREQ_LEN);
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVQUAL;
@@ -2945,8 +2946,8 @@ ieee80211_sta_scan_result(struct net_dev
iwe.u.qual.level = bss->rssi;
iwe.u.qual.noise = bss->noise;
iwe.u.qual.updated = local->wstats_flags;
- current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
- IW_EV_QUAL_LEN);
+ current_ev = iwe_stream_add_event(info, current_ev, end_buf,
+ &iwe, IW_EV_QUAL_LEN);
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = SIOCGIWENCODE;
@@ -2955,22 +2956,22 @@ ieee80211_sta_scan_result(struct net_dev
else
iwe.u.data.flags = IW_ENCODE_DISABLED;
iwe.u.data.length = 0;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, "");
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf, &iwe, "");
if (bss && bss->wpa_ie) {
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVGENIE;
iwe.u.data.length = bss->wpa_ie_len;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
- bss->wpa_ie);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, bss->wpa_ie);
}
if (bss && bss->rsn_ie) {
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVGENIE;
iwe.u.data.length = bss->rsn_ie_len;
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
- bss->rsn_ie);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, bss->rsn_ie);
}
if (bss && bss->supp_rates_len > 0) {
@@ -2986,8 +2987,8 @@ ieee80211_sta_scan_result(struct net_dev
for (i = 0; i < bss->supp_rates_len; i++) {
iwe.u.bitrate.value = ((bss->supp_rates[i] &
0x7f) * 500000);
- p = iwe_stream_add_value(current_ev, p,
- end_buf, &iwe, IW_EV_PARAM_LEN);
+ p = iwe_stream_add_value(info, current_ev, p, end_buf,
+ &iwe, IW_EV_PARAM_LEN);
}
current_ev = p;
}
@@ -3000,8 +3001,8 @@ ieee80211_sta_scan_result(struct net_dev
iwe.cmd = IWEVCUSTOM;
sprintf(buf, "tsf=%016llx", (unsigned long long)(bss->timestamp));
iwe.u.data.length = strlen(buf);
- current_ev = iwe_stream_add_point(current_ev, end_buf,
- &iwe, buf);
+ current_ev = iwe_stream_add_point(info, current_ev,
+ end_buf, &iwe, buf);
kfree(buf);
}
}
@@ -3020,15 +3021,15 @@ ieee80211_sta_scan_result(struct net_dev
iwe.cmd = IWEVCUSTOM;
sprintf(buf, "bcn_int=%d", bss->beacon_int);
iwe.u.data.length = strlen(buf);
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
- buf);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, buf);
memset(&iwe, 0, sizeof(iwe));
iwe.cmd = IWEVCUSTOM;
sprintf(buf, "capab=0x%04x", bss->capability);
iwe.u.data.length = strlen(buf);
- current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe,
- buf);
+ current_ev = iwe_stream_add_point(info, current_ev, end_buf,
+ &iwe, buf);
kfree(buf);
break;
@@ -3038,7 +3039,9 @@ ieee80211_sta_scan_result(struct net_dev
}
-int ieee80211_sta_scan_results(struct net_device *dev, char *buf, size_t len)
+int ieee80211_sta_scan_results(struct net_device *dev,
+ struct iw_request_info *info,
+ char *buf, size_t len)
{
struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
char *current_ev = buf;
@@ -3051,8 +3054,8 @@ int ieee80211_sta_scan_results(struct ne
spin_unlock_bh(&local->sta_bss_lock);
return -E2BIG;
}
- current_ev = ieee80211_sta_scan_result(dev, bss, current_ev,
- end_buf);
+ current_ev = ieee80211_sta_scan_result(dev, info, bss,
+ current_ev, end_buf);
}
spin_unlock_bh(&local->sta_bss_lock);
return current_ev - buf;
next prev parent reply other threads:[~2008-01-11 4:16 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-12-22 4:58 [WEXT 12/12]: Emit event stream compat iw_point objects correctly David Miller
[not found] ` <20071221.205808.213484078.davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
2007-12-27 8:51 ` : " Masakazu Mokuno
2007-12-27 8:57 ` David Miller
[not found] ` <20071227.005725.144782426.davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
2007-12-27 9:24 ` Masakazu Mokuno
[not found] ` <20071227181439.6F59.40F06B3A-DfbDroY8Xu1L9jVzuh4AOg@public.gmane.org>
2007-12-27 9:26 ` David Miller
2008-01-10 9:16 ` David Miller
[not found] ` <20080110.011602.74511551.davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
2008-01-11 4:16 ` Masakazu Mokuno [this message]
2008-06-03 16:57 ` David Miller
[not found] ` <20080603.095750.120470495.davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org>
2008-06-03 17:37 ` David Miller
2008-01-21 11:23 ` Masakazu Mokuno
[not found] ` <20080121194942.613C.40F06B3A-DfbDroY8Xu1L9jVzuh4AOg@public.gmane.org>
2008-01-21 11:37 ` David Miller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20080111112248.610C.40F06B3A@sm.sony.co.jp \
--to=mokuno-dfbdroy8xu1l9jvzuh4aog@public.gmane.org \
--cc=davem-fT/PcQaiUtIeIZ0/mPfg9Q@public.gmane.org \
--cc=linux-wireless-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox