Netdev List
 help / color / mirror / Atom feed
* [PATCH 1/5] spidernet: add missing initialization
From: Ishizaki Kou @ 2008-01-11  6:38 UTC (permalink / raw)
  To: linas; +Cc: netdev, cbe-oss-dev

This patch fixes initialization of "aneg_count" and "medium" fields in
spider_net_card to make spidernet driver correctly sets "link status".

Signed-off-by: Kou Ishizaki <kou.ishizaki@toshiba.co.jp>
---

Index: linux-powerpc-git/drivers/net/spider_net.c
===================================================================
--- linux-powerpc-git.orig/drivers/net/spider_net.c
+++ linux-powerpc-git/drivers/net/spider_net.c
@@ -1399,6 +1399,8 @@ spider_net_link_reset(struct net_device 
 	spider_net_write_reg(card, SPIDER_NET_GMACINTEN, 0);
 
 	/* reset phy and setup aneg */
+	card->aneg_count = 0;
+	card->medium = BCM54XX_COPPER;
 	spider_net_setup_aneg(card);
 	mod_timer(&card->aneg_timer, jiffies + SPIDER_NET_ANEG_TIMER);
 
@@ -1982,6 +1984,8 @@ spider_net_open(struct net_device *netde
 		goto init_firmware_failed;
 
 	/* start probing with copper */
+	card->aneg_count = 0;
+	card->medium = BCM54XX_COPPER;
 	spider_net_setup_aneg(card);
 	if (card->phy.def->phy_id)
 		mod_timer(&card->aneg_timer, jiffies + SPIDER_NET_ANEG_TIMER);

^ permalink raw reply

* [PATCH 5/5] spidernet: revise link status logging
From: Ishizaki Kou @ 2008-01-11  6:48 UTC (permalink / raw)
  To: linas; +Cc: netdev, cbe-oss-dev

This patch revises the logging for link informations of spidernet.

  - The link down message is too verbose because auto-negotiation timeout
    occurs periodically while an ethernet cable is not connected. 
  - We want to see the link result, and we think it should be displayed. 

Signed-off-by: Kou Ishizaki <kou.ishizaki@toshiba.co.jp>
---

Index: linux-powerpc-git/drivers/net/spider_net.c
===================================================================
--- linux-powerpc-git.orig/drivers/net/spider_net.c
+++ linux-powerpc-git/drivers/net/spider_net.c
@@ -2045,7 +2045,8 @@ static void spider_net_link_phy(unsigned
 	/* if link didn't come up after SPIDER_NET_ANEG_TIMEOUT tries, setup phy again */
 	if (card->aneg_count > SPIDER_NET_ANEG_TIMEOUT) {
 
-		pr_info("%s: link is down trying to bring it up\n", card->netdev->name);
+		pr_debug("%s: link is down trying to bring it up\n",
+			 card->netdev->name);
 
 		switch (card->medium) {
 		case BCM54XX_COPPER:
@@ -2096,9 +2097,10 @@ static void spider_net_link_phy(unsigned
 
 	card->aneg_count = 0;
 
-	pr_debug("Found %s with %i Mbps, %s-duplex %sautoneg.\n",
-		phy->def->name, phy->speed, phy->duplex==1 ? "Full" : "Half",
-		phy->autoneg==1 ? "" : "no ");
+	pr_info("%s: link up, %i Mbps, %s-duplex %sautoneg.\n",
+		card->netdev->name, phy->speed,
+		phy->duplex == 1 ? "Full" : "Half",
+		phy->autoneg == 1 ? "" : "no ");
 
 	return;
 }

^ permalink raw reply

* [PATCH 2/5] spidernet: increase auto-negotiation timeout to 5 seconds
From: Ishizaki Kou @ 2008-01-11  6:41 UTC (permalink / raw)
  To: linas; +Cc: netdev, cbe-oss-dev

This patch extends the timeout for spidernet auto-negotiation.
Auto-negotiation often fails to finish in 2 seconds.

Signed-off-by: Kou Ishizaki <kou.ishizaki@toshiba.co.jp>
---

Index: linux-powerpc-git/drivers/net/spider_net.h
===================================================================
--- linux-powerpc-git.orig/drivers/net/spider_net.h
+++ linux-powerpc-git/drivers/net/spider_net.h
@@ -52,7 +52,7 @@ extern char spider_net_driver_name[];
 
 #define SPIDER_NET_TX_TIMER			(HZ/5)
 #define SPIDER_NET_ANEG_TIMER			(HZ)
-#define SPIDER_NET_ANEG_TIMEOUT			2
+#define SPIDER_NET_ANEG_TIMEOUT			5
 
 #define SPIDER_NET_RX_CSUM_DEFAULT		1
 

^ permalink raw reply

* Re: [klibc] [patch] import socket defines
From: David Miller @ 2008-01-11  6:47 UTC (permalink / raw)
  To: vapier; +Cc: hpa, netdev, klibc
In-Reply-To: <200801110123.38406.vapier@gentoo.org>

From: Mike Frysinger <vapier@gentoo.org>
Date: Fri, 11 Jan 2008 01:23:37 -0500

> On Friday 11 January 2008, David Miller wrote:
> > From: "H. Peter Anvin" <hpa@zytor.com>
> > > Seems the most logical thing to do would be to break out the small
> > > portion that everyone wants into <linux/sockaddr.h> or somesuch, and
> > > then remove those ifdefs entirely.
> > >
> > > Proposed patch (still being tested) attached...
> >
> > I think this would clearly break existing glibc builds.
> >
> > I agree with fixing the ifdef checks, but not like this.
> 
> how ?  the large crap in linux/socket.h never made it into glibc builds, and 
> the few things at the top which were relocated to linux/sockaddr.h are still 
> pulled in via linux/socket.h.  for glibc, the resulting '#include 
> <linux/socket.h>' should be unchanged.

Hmmm...

Doesn't glibc include linux/socket.h?  If so, before it wouldn't get
the sa_family_t et al. defines (because __GLIBC__ will be defined and
it will be >= 2), but with your change it get those things.

Correct me if I'm wrong.

Thanks.

^ permalink raw reply

* Re: [klibc] [patch] import socket defines
From: H. Peter Anvin @ 2008-01-11  6:41 UTC (permalink / raw)
  To: Mike Frysinger; +Cc: David Miller, netdev, klibc
In-Reply-To: <200801110123.38406.vapier@gentoo.org>

Mike Frysinger wrote:
> On Friday 11 January 2008, David Miller wrote:
>> From: "H. Peter Anvin" <hpa@zytor.com>
>>> Seems the most logical thing to do would be to break out the small
>>> portion that everyone wants into <linux/sockaddr.h> or somesuch, and
>>> then remove those ifdefs entirely.
>>>
>>> Proposed patch (still being tested) attached...
>> I think this would clearly break existing glibc builds.
>>
>> I agree with fixing the ifdef checks, but not like this.
> 
> how ?  the large crap in linux/socket.h never made it into glibc builds, and 
> the few things at the top which were relocated to linux/sockaddr.h are still 
> pulled in via linux/socket.h.  for glibc, the resulting '#include 
> <linux/socket.h>' should be unchanged.

The problem is that there isn't any way to do this without breaking 
*something*, since the fundamental problem is that userspace doesn't ask 
for what it wants, so the kernel is expected to "figure it out."

We can either change the way glibc includes the kernel headers, or the 
way everything else does.  The latter should really include the kernel, 
although there is the hack of

/* linux/socket.h */

/* sockaddr stuff */

#ifdef __KERNEL__
# include <linux/socket2.h>
#endif

The reason I went the direction I did was that it looked like the end 
result was cleaner.

	-hpa

^ permalink raw reply

* Re: [patch net-2.6.25 0/5][NETNS][IPV6] discriminate inet6 addresses per namespace
From: David Miller @ 2008-01-11  6:45 UTC (permalink / raw)
  To: dlezcano; +Cc: netdev, benjamin.thery
In-Reply-To: <20080110180240.517524760@fr.ibm.com>

From: Daniel Lezcano <dlezcano@fr.ibm.com>
Date: Thu, 10 Jan 2008 19:02:40 +0100

> The inet6_addr_lst hash table contains the configured addresses 
> for the ipv6 protocol on the system.
> 
> With the network namespace, we have 2 solutions:
>  * make this hash table per namespace
>  * keep a global hash table and discard addresses not belonging
>    to the network namespace
> 
> This patchset use the second method. It will use less memory, but
> can be a less efficient in case of a lot of containers.
> 
> The code is changed to have the network namespace parameter for the
> different functions, if we change our mind during an intense usage
> of the network namespace, the switch to a hash table per namespace
> is really easy to do and will not change the new api again.

All 5 patches applied, thanks.

^ permalink raw reply

* Re: [MACVLAN]: Prevent nesting macvlan devices
From: David Miller @ 2008-01-11  6:39 UTC (permalink / raw)
  To: kaber; +Cc: netdev
In-Reply-To: <47863A96.5080708@trash.net>

From: Patrick McHardy <kaber@trash.net>
Date: Thu, 10 Jan 2008 16:32:38 +0100

> [MACVLAN]: Prevent nesting macvlan devices
> 
> Don't allow to nest macvlan devices since it will cause lockdep warnings and
> isn't really useful for anything.
> 
> Signed-off-by: Patrick McHardy <kaber@trash.net>

Applied.

^ permalink raw reply

* Re: [VLAN]: nested VLAN: fix lockdep's recursive locking warning
From: David Miller @ 2008-01-11  6:38 UTC (permalink / raw)
  To: kaber; +Cc: netdev
In-Reply-To: <47863A93.5060000@trash.net>

From: Patrick McHardy <kaber@trash.net>
Date: Thu, 10 Jan 2008 16:32:35 +0100

> [VLAN]: nested VLAN: fix lockdep's recursive locking warning
> 
> Allow vlans nesting other vlans without lockdep's warnings (max. 2 levels
> i.e. parent + child). Thanks to Patrick McHardy for pointing a bug in the
> first version of this patch.
> 
> Reported-by: Benny Amorsen
> 
> Signed-off-by: Jarek Poplawski <jarkao2@gmail.com>
> Signed-off-by: Patrick McHardy <kaber@trash.net>

Applied, thanks.

^ permalink raw reply

* Re: [PATCH net-2.6.25][NEIGH]: Add a comment describing what a NUD stands for.
From: David Miller @ 2008-01-11  6:37 UTC (permalink / raw)
  To: xemul; +Cc: netdev, kuznet, devel
In-Reply-To: <47863435.3090407@openvz.org>

From: Pavel Emelyanov <xemul@openvz.org>
Date: Thu, 10 Jan 2008 18:05:25 +0300

> When I studied the neighbor code I puzzled over what
> the NUD can mean for quite a long time.
> 
> Finally I asked Alexey and he said that this was smth
> like "neighbor unreachability detection".
> 
> Does it worth adding a comment helping future developers 
> understand what's going on?
> 
> Signed-off-by: Pavel Emelyanov <xemul@openvz.org>

NUD is a common acronym in the IPV6 RFCs and various books
on the topic, but it doesn't hurt to add this comment so I
applied this patch thanks.

^ permalink raw reply

* Re: [DECNET] ROUTE: fix rcu_dereference() uses in /proc/net/decnet_cache
From: David Miller @ 2008-01-11  6:35 UTC (permalink / raw)
  To: dada1; +Cc: herbert, paulmck, dipankar, netdev
In-Reply-To: <20080110150610.c13e2125.dada1@cosmosbay.com>

From: Eric Dumazet <dada1@cosmosbay.com>
Date: Thu, 10 Jan 2008 15:06:10 +0100

> [DECNET] ROUTE: fix rcu_dereference() uses in /proc/net/decnet_cache
 ...
> Signed-off-by: Eric Dumazet <dada1@cosmosbay.com>

Applied, thanks Eric.

^ permalink raw reply

* Re: [PATCH 001/001] ipv4: enable use of 240/4 address space
From: David Miller @ 2008-01-11  6:33 UTC (permalink / raw)
  To: vaf; +Cc: netdev, linux-kernel
In-Reply-To: <20080108011057.GA21168@cisco.com>

From: Vince Fuller <vaf@cisco.com>
Date: Mon, 7 Jan 2008 17:10:57 -0800

> from Vince Fuller <vaf@vaf.net>
> 
> This set of diffs modify the 2.6.20 kernel to enable use of the 240/4
> (aka "class-E") address space as consistent with the Internet Draft
> draft-fuller-240space-00.txt.
> 
> Signed-off-by: Vince Fuller <vaf@vaf.net>

There has been more than 90K worth of changes to the files you are
changing since 2.6.20

It is generally unwise to submit patches against such old kernel
versions, they rarely apply, so please respin your patch against more
current sources.

Please also remove the trailing whitespace, like the one found
here:

+#define	IN_CLASSE_HOST		(0xffffffff & ~IN_CLASSE_NET)
+
+/* 
   ^^^^^

Thanks.

^ permalink raw reply

* Re: [klibc] [patch] import socket defines
From: Mike Frysinger @ 2008-01-11  6:23 UTC (permalink / raw)
  To: David Miller; +Cc: hpa, netdev, klibc
In-Reply-To: <20080110.221615.188955433.davem@davemloft.net>

[-- Attachment #1: Type: text/plain, Size: 734 bytes --]

On Friday 11 January 2008, David Miller wrote:
> From: "H. Peter Anvin" <hpa@zytor.com>
> > Seems the most logical thing to do would be to break out the small
> > portion that everyone wants into <linux/sockaddr.h> or somesuch, and
> > then remove those ifdefs entirely.
> >
> > Proposed patch (still being tested) attached...
>
> I think this would clearly break existing glibc builds.
>
> I agree with fixing the ifdef checks, but not like this.

how ?  the large crap in linux/socket.h never made it into glibc builds, and 
the few things at the top which were relocated to linux/sockaddr.h are still 
pulled in via linux/socket.h.  for glibc, the resulting '#include 
<linux/socket.h>' should be unchanged.
-mike

[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 835 bytes --]

^ permalink raw reply

* Re: [PATCH] bluetooth : rfcomm tty BUG_ON() code fix
From: David Miller @ 2008-01-11  6:23 UTC (permalink / raw)
  To: hidave.darkstar; +Cc: netdev, marcel, bluez-devel, linux-kernel
In-Reply-To: <20080107054122.GA4502@darkstar.te-china.tietoenator.com>

From: Dave Young <hidave.darkstar@gmail.com>
Date: Mon, 7 Jan 2008 13:41:22 +0800

> 1) In tty.c the BUG_ON at line 115 will never be called, because the the before list_del_init in this same function.
>  115          BUG_ON(!list_empty(&dev->list));
> So move the list_del_init to rfcomm_dev_del 
> 
> 2) The rfcomm_dev_del could be called from diffrent path (rfcomm_tty_hangup/rfcomm_dev_state_change/rfcomm_release_dev),
> So add another BUG_ON when the rfcomm_dev_del is called more than one time.
> 
> Signed-off-by: Dave Young <hidave.darkstar@gmail.com> 

Applied, thanks Dave.

-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace

^ permalink raw reply

* Re: [klibc] [patch] import socket defines
From: David Miller @ 2008-01-11  6:16 UTC (permalink / raw)
  To: hpa; +Cc: vapier, netdev, klibc
In-Reply-To: <477BD374.6060506@zytor.com>

From: "H. Peter Anvin" <hpa@zytor.com>
Date: Wed, 02 Jan 2008 10:09:56 -0800

> Seems the most logical thing to do would be to break out the small 
> portion that everyone wants into <linux/sockaddr.h> or somesuch, and 
> then remove those ifdefs entirely.
> 
> Proposed patch (still being tested) attached...

I think this would clearly break existing glibc builds.

I agree with fixing the ifdef checks, but not like this.

^ permalink raw reply

* Re: [PATCH 1/3] [UDP]: add udp_mem, udp_rmem_min and udp_wmem_min
From: David Miller @ 2008-01-11  6:00 UTC (permalink / raw)
  To: dada1
  Cc: haoki, herbert, netdev, tyasui, mhiramat, satoshi.oshima.fk,
	billfink, andi, johnpol, shemminger, yoshfuji, yumiko.sugita.yf
In-Reply-To: <4778FFE2.9090008@cosmosbay.com>

From: Eric Dumazet <dada1@cosmosbay.com>
Date: Mon, 31 Dec 2007 15:42:42 +0100

> Maybe we need to introduce some mechanism to let sk_forward between 0 and 
> SK_MEM_QUANTUM (inclusive).
> 
> static inline void sk_mem_reclaim_overpage(struct sock *sk)
> {
>          if (sk->sk_forward_alloc > SK_MEM_QUANTUM) {
>                  __sk_mem_reclaim(sk);
> 		}
> }
> 
> and use sk_mem_reclaim_overpage() instead of sk_mem_reclaim() in 
> tcp_delack_timer() ?

This makes a lot of sense to me, it is definitely doing the wrong
thing here for the load you describe.

I've applied the following to net-2.6.25 and I am definitely
willing to put this into 2.6.24 and -stable if you think that's
worthwhile too.

[TCP]: Do not purge sk_forward_alloc entirely in tcp_delack_timer().

Otherwise we beat heavily on the global tcp_memory atomics
when all of the sockets in the system are slowly sending
perioding packet clumps.

Noticed and suggested by Eric Dumazet.

Signed-off-by: David S. Miller <davem@davemloft.net>
---
 include/net/sock.h   |    8 ++++++++
 net/ipv4/tcp_timer.c |    2 +-
 2 files changed, 9 insertions(+), 1 deletions(-)

diff --git a/include/net/sock.h b/include/net/sock.h
index 89e04e4..d24b826 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -759,6 +759,14 @@ static inline void sk_mem_reclaim(struct sock *sk)
 		__sk_mem_reclaim(sk);
 }
 
+static inline void sk_mem_reclaim_partial(struct sock *sk)
+{
+	if (!sk_has_account(sk))
+		return;
+	if (sk->sk_forward_alloc > SK_MEM_QUANTUM)
+		__sk_mem_reclaim(sk);
+}
+
 static inline void sk_mem_charge(struct sock *sk, int size)
 {
 	if (!sk_has_account(sk))
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
index 17931be..803d758 100644
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -186,7 +186,7 @@ static void tcp_delack_timer(unsigned long data)
 		goto out_unlock;
 	}
 
-	sk_mem_reclaim(sk);
+	sk_mem_reclaim_partial(sk);
 
 	if (sk->sk_state == TCP_CLOSE || !(icsk->icsk_ack.pending & ICSK_ACK_TIMER))
 		goto out;
-- 
1.5.4.rc2.84.gf85fd


^ permalink raw reply related

* Re: [PATCH][ROSE][AX25] af_ax25: possible circular locking
From: David Miller @ 2008-01-11  5:22 UTC (permalink / raw)
  To: jarkao2; +Cc: f6bvp, ralf, adobriyan, netdev
In-Reply-To: <20071230141323.GA3377@ami.dom.local>

From: Jarek Poplawski <jarkao2@gmail.com>
Date: Sun, 30 Dec 2007 15:13:23 +0100

> On Sat, Dec 29, 2007 at 07:14:43PM -0800, David Miller wrote:
> ...
> > You can't just drop this linked list lock and expect it to stay
> > consistent like that.
> > 
> > Once you drop it, any thread of control can get in there and delete
> > entries from the list.
> > 
> > Since we know it can happen, using a WARN_ON_ONCE(1) is not
> > appropriate.
> 
> The problem is 'we' don't know if it can happen... In the first
> message with this patch I've tried to get this information, and
> now it seems you are the only one with this knowledge, but of
> course this is more than enough for me to agree with your decision
> to dump this patch.

I've removed the warning and made the branch back to 'again'
unconditional as I think this is the safest version of the
change.

I'll push this upstream, thanks for fixing this Jarek.

diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c
index ecb14ee..b4725ff 100644
--- a/net/ax25/af_ax25.c
+++ b/net/ax25/af_ax25.c
@@ -87,10 +87,22 @@ static void ax25_kill_by_device(struct net_device *dev)
 		return;
 
 	spin_lock_bh(&ax25_list_lock);
+again:
 	ax25_for_each(s, node, &ax25_list) {
 		if (s->ax25_dev == ax25_dev) {
 			s->ax25_dev = NULL;
+			spin_unlock_bh(&ax25_list_lock);
 			ax25_disconnect(s, ENETUNREACH);
+			spin_lock_bh(&ax25_list_lock);
+
+			/* The entry could have been deleted from the
+			 * list meanwhile and thus the next pointer is
+			 * no longer valid.  Play it safe and restart
+			 * the scan.  Forward progress is ensured
+			 * because we set s->ax25_dev to NULL and we
+			 * are never passed a NULL 'dev' argument.
+			 */
+			goto again;
 		}
 	}
 	spin_unlock_bh(&ax25_list_lock);
-- 
1.5.4.rc2.84.gf85fd


^ permalink raw reply related

* Re: [RFC PATCH] IPoIB: improve IPv4/IPv6 to IB mcast mapping functions
From: David Miller @ 2008-01-11  4:56 UTC (permalink / raw)
  To: rdreier; +Cc: netdev, rvm, general
In-Reply-To: <adair29mel2.fsf_-_@cisco.com>

From: Roland Dreier <rdreier@cisco.com>
Date: Fri, 04 Jan 2008 14:05:29 -0800

> Any objection to merging the following for 2.6.25?

The ipv4/ipv6 bits look fine to me.

^ permalink raw reply

* Re: [PATCH 0/3] bonding: 3 fixes for 2.6.24
From: Herbert Xu @ 2008-01-11  4:55 UTC (permalink / raw)
  To: Jay Vosburgh; +Cc: herbert, andy, olel, netdev, jgarzik, davem
In-Reply-To: <23761.1200013613@death>

Jay Vosburgh <fubar@us.ibm.com> wrote:
>
>        For the case of the bond_set_multicast_list function, changing
> the existing write_lock to a read_lock_bh doesn't affect any calls to

Right that should also resolve the lockdep issue.  So as long as you
guys are sure that this is safe with respect to the rest of the bonding
driver it's fine by me.

BTW you only need read_lock since set_multicast_list always gets called
with BH off.

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply

* RE:  [PATCH 0/3] UCC TDM driver for MPC83xx platforms
From: Aggrwal Poonam @ 2008-01-11  4:54 UTC (permalink / raw)
  To: Aggrwal Poonam, sfr, rubini, linux-ppcdev, netdev, linux-kernel
  Cc: Barkowski Michael, Phillips Kim, Kalra Ashish, Cutler Richard
In-Reply-To: <FBA61160C48B8D438F3323FEFB4EF2C259F2F6@zin33exm24.fsl.freescale.net>

 
Hello  All

I am waiting for more feedback on the patches.

If there are no objections please consider them for 2.6.25.

With Regards
Poonam 
 
 

-----Original Message-----
From: netdev-owner@vger.kernel.org [mailto:netdev-owner@vger.kernel.org]
On Behalf Of Aggrwal Poonam
Sent: Monday, December 10, 2007 5:23 PM
To: rubini@vision.unipv.it; linux-ppcdev@ozlabs.kernel.org;
netdev@vger.kernel.org; linux-kernel@vger.kernel.org; Gala Kumar
Cc: Barkowski Michael; Phillips Kim; Kalra Ashish; Cutler Richard
Subject: [PATCH 0/3] UCC TDM driver for MPC83xx platforms 

There are three patches
[PATCH 1/3] drivers/misc : UCC TDM driver for mpc83xx platforms. This
driver is usable in VoIP iind of applications to interface with SLIC
kind of devices to exchange TDM voice samples.

[PATCH 2/3] arch/ : Platform changes
- device tree entries for UCC TDM driver for MPC8323ERDB platform.
- QE changes related to TDM , like,
	 1) Modified ucc_fast_init so that it can be used by fast UCC
based TDM driver. Mainly changes have been made to configure TDM clocks
and Fsyncs.

	2) Modified get_brg_clk so that it can return the input frequncy
and input source of any BRG by reading the corresponding entries from
device tree.

	3) Added new nodes brg and clocks in the device tree which
represent input clocks for different BRGs.

	4) Modified qe_setbrg accordingly.
- new device tree entries added for "clocks" and "brg"

[PATCH 3/3] Documentation
- Modified Documentation to explain the device tree entries related to
UCC TDM driver and the new nodes added("clocks" and "brg")

The patch applies over a merge of galak's for-2.6.25 plus for-2.6.24
plus of_doc_update branches.
In brief the steps were
git clone
git://git.kernel.org/pub/scm/linux/kernel/git/galak/powerpc.git
powerpc-galak git checkout -b for-2.6.25 origin/for-2.6.25 git checkout
-b for-2.6.24 origin/for-2.6.24 git checkout -b of_doc_update
origin/of_doc_update
git pull . for-2.6.24    # merge the other two
git pull . for-2.6.25 
git checkout -b tdm      # clean slate for tdm rebase work

Also after applying the patches changes have to be made corresponding to
Tabi's patch "qe: add function qe_clock_source".

The driver has been tested with a VoIP stack and application on
MPC8323ERDB.

With Regards
Poonam 
 
 
--
To unsubscribe from this list: send the line "unsubscribe netdev" in the
body of a message to majordomo@vger.kernel.org More majordomo info at
http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* RE:  [PATCH 0/3] UCC TDM driver for MPC83xx platforms
From: Aggrwal Poonam @ 2008-01-11  4:41 UTC (permalink / raw)
  To: sfr, rubini, linux-ppcdev, netdev, linux-kernel, Gala Kumar
  Cc: Barkowski Michael, Phillips Kim, Kalra Ashish, Cutler Richard,
	Aggrwal Poonam
In-Reply-To: <FBA61160C48B8D438F3323FEFB4EF2C259F2F6@zin33exm24.fsl.freescale.net>

Hello  All

I am waiting for more feedback on the patches.

If there are no objections please consider them for 2.6.25.

With Regards
Poonam 
 
 

-----Original Message-----
From: netdev-owner@vger.kernel.org [mailto:netdev-owner@vger.kernel.org]
On Behalf Of Aggrwal Poonam
Sent: Monday, December 10, 2007 5:23 PM
To: rubini@vision.unipv.it; linux-ppcdev@ozlabs.kernel.org;
netdev@vger.kernel.org; linux-kernel@vger.kernel.org; Gala Kumar
Cc: Barkowski Michael; Phillips Kim; Kalra Ashish; Cutler Richard
Subject: [PATCH 0/3] UCC TDM driver for MPC83xx platforms 

There are three patches
[PATCH 1/3] drivers/misc : UCC TDM driver for mpc83xx platforms. This
driver is usable in VoIP iind of applications to interface with SLIC
kind of devices to exchange TDM voice samples.

[PATCH 2/3] arch/ : Platform changes
- device tree entries for UCC TDM driver for MPC8323ERDB platform.
- QE changes related to TDM , like,
	 1) Modified ucc_fast_init so that it can be used by fast UCC
based TDM driver. Mainly changes have been made to configure TDM clocks
and Fsyncs.

	2) Modified get_brg_clk so that it can return the input frequncy
and input source of any BRG by reading the corresponding entries from
device tree.

	3) Added new nodes brg and clocks in the device tree which
represent input clocks for different BRGs.

	4) Modified qe_setbrg accordingly.
- new device tree entries added for "clocks" and "brg"

[PATCH 3/3] Documentation
- Modified Documentation to explain the device tree entries related to
UCC TDM driver and the new nodes added("clocks" and "brg")

The patch applies over a merge of galak's for-2.6.25 plus for-2.6.24
plus of_doc_update branches.
In brief the steps were
git clone
git://git.kernel.org/pub/scm/linux/kernel/git/galak/powerpc.git
powerpc-galak git checkout -b for-2.6.25 origin/for-2.6.25 git checkout
-b for-2.6.24 origin/for-2.6.24 git checkout -b of_doc_update
origin/of_doc_update
git pull . for-2.6.24    # merge the other two
git pull . for-2.6.25 
git checkout -b tdm      # clean slate for tdm rebase work

Also after applying the patches changes have to be made corresponding to
Tabi's patch "qe: add function qe_clock_source".

The driver has been tested with a VoIP stack and application on
MPC8323ERDB.

With Regards
Poonam 
 
 
--
To unsubscribe from this list: send the line "unsubscribe netdev" in the
body of a message to majordomo@vger.kernel.org More majordomo info at
http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: : Emit event stream compat iw_point objects correctly.
From: Masakazu Mokuno @ 2008-01-11  4:16 UTC (permalink / raw)
  To: David Miller
  Cc: linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	netdev-u79uwXL29TY76Z2rM5mHXA
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;

^ permalink raw reply

* Re: my NAPI patches
From: David Miller @ 2008-01-11  4:05 UTC (permalink / raw)
  To: jacliburn; +Cc: netdev
In-Reply-To: <20080110194421.589d09df@osprey.hogchain.net>

From: Jay Cliburn <jacliburn@bellsouth.net>
Date: Thu, 10 Jan 2008 19:44:21 -0600

> On Tue, 08 Jan 2008 15:08:48 -0800 (PST)
> David Miller <davem@davemloft.net> wrote:
> 
> > 
> > Can people do me a favor and do more constructive things like test
> > that my patches really do fix the "device down during packet flood"
> > bug 
> 
> Hi Dave,
> 
> Your patches seem to work for the atl1 NAPI implementation.  I can drop
> the interface just fine while hammering the NIC with packets from iperf.

Thanks a lot for testing.

^ permalink raw reply

* [PATCH 4/4] sky2: version 1.21
From: Stephen Hemminger @ 2008-01-11  0:14 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: netdev
In-Reply-To: <20080111001411.158113585@linux-foundation.org>

[-- Attachment #1: sky2-1.21 --]
[-- Type: text/plain, Size: 500 bytes --]

Update driver version reflects new hardware support.

Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>

---
Please add to staging tree for 2.6.25.

--- a/drivers/net/sky2.c	2008-01-10 15:49:27.000000000 -0800
+++ b/drivers/net/sky2.c	2008-01-10 15:49:29.000000000 -0800
@@ -51,7 +51,7 @@
 #include "sky2.h"
 
 #define DRV_NAME		"sky2"
-#define DRV_VERSION		"1.20"
+#define DRV_VERSION		"1.21"
 #define PFX			DRV_NAME " "
 
 /*

-- 
Stephen Hemminger <stephen.hemminger@vyatta.com>


^ permalink raw reply

* [PATCH 1/4] sky2: large memory workaround.
From: Stephen Hemminger @ 2008-01-11  0:14 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: netdev
In-Reply-To: <20080111001411.158113585@linux-foundation.org>

[-- Attachment #1: sky2-dma64.patch --]
[-- Type: text/plain, Size: 3203 bytes --]

This patch might fix problems with 4G or more of memory.
It stops the driver from doing a small optimization for Tx and Rx,
and instead always sets the high-page on tx/rx descriptors.

Fixes-bug: http://bugzilla.kernel.org/show_bug.cgi?id=9725

Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>

---
Please apply to 2.6.24.

--- a/drivers/net/sky2.c	2008-01-10 15:42:09.000000000 -0800
+++ b/drivers/net/sky2.c	2008-01-10 15:49:12.000000000 -0800
@@ -943,7 +943,6 @@ static void tx_init(struct sky2_port *sk
 	le = get_tx_le(sky2);
 	le->addr = 0;
 	le->opcode = OP_ADDR64 | HW_OWNER;
-	sky2->tx_addr64 = 0;
 }
 
 static inline struct tx_ring_info *tx_le_re(struct sky2_port *sky2,
@@ -977,13 +976,11 @@ static void sky2_rx_add(struct sky2_port
 			dma_addr_t map, unsigned len)
 {
 	struct sky2_rx_le *le;
-	u32 hi = upper_32_bits(map);
 
-	if (sky2->rx_addr64 != hi) {
+	if (sizeof(dma_addr_t) > sizeof(u32)) {
 		le = sky2_next_rx(sky2);
-		le->addr = cpu_to_le32(hi);
+		le->addr = cpu_to_le32(upper_32_bits(map));
 		le->opcode = OP_ADDR64 | HW_OWNER;
-		sky2->rx_addr64 = upper_32_bits(map + len);
 	}
 
 	le = sky2_next_rx(sky2);
@@ -1477,7 +1474,6 @@ static int sky2_xmit_frame(struct sk_buf
 	struct tx_ring_info *re;
 	unsigned i, len;
 	dma_addr_t mapping;
-	u32 addr64;
 	u16 mss;
 	u8 ctrl;
 
@@ -1490,15 +1486,12 @@ static int sky2_xmit_frame(struct sk_buf
 
 	len = skb_headlen(skb);
 	mapping = pci_map_single(hw->pdev, skb->data, len, PCI_DMA_TODEVICE);
-	addr64 = upper_32_bits(mapping);
 
-	/* Send high bits if changed or crosses boundary */
-	if (addr64 != sky2->tx_addr64 ||
-	    upper_32_bits(mapping + len) != sky2->tx_addr64) {
+	/* Send high bits if needed */
+	if (sizeof(dma_addr_t) > sizeof(u32)) {
 		le = get_tx_le(sky2);
-		le->addr = cpu_to_le32(addr64);
+		le->addr = cpu_to_le32(upper_32_bits(mapping));
 		le->opcode = OP_ADDR64 | HW_OWNER;
-		sky2->tx_addr64 = upper_32_bits(mapping + len);
 	}
 
 	/* Check for TCP Segmentation Offload */
@@ -1579,13 +1572,12 @@ static int sky2_xmit_frame(struct sk_buf
 
 		mapping = pci_map_page(hw->pdev, frag->page, frag->page_offset,
 				       frag->size, PCI_DMA_TODEVICE);
-		addr64 = upper_32_bits(mapping);
-		if (addr64 != sky2->tx_addr64) {
+
+		if (sizeof(dma_addr_t) > sizeof(u32)) {
 			le = get_tx_le(sky2);
-			le->addr = cpu_to_le32(addr64);
+			le->addr = cpu_to_le32(upper_32_bits(mapping));
 			le->ctrl = 0;
 			le->opcode = OP_ADDR64 | HW_OWNER;
-			sky2->tx_addr64 = addr64;
 		}
 
 		le = get_tx_le(sky2);
--- a/drivers/net/sky2.h	2008-01-10 15:41:55.000000000 -0800
+++ b/drivers/net/sky2.h	2008-01-10 15:49:12.000000000 -0800
@@ -1991,14 +1991,14 @@ struct sky2_port {
 	u16		     tx_cons;		/* next le to check */
 	u16		     tx_prod;		/* next le to use */
 	u16		     tx_next;		/* debug only */
-	u32		     tx_addr64;
+
 	u16		     tx_pending;
 	u16		     tx_last_mss;
 	u32		     tx_tcpsum;
 
 	struct rx_ring_info  *rx_ring ____cacheline_aligned_in_smp;
 	struct sky2_rx_le    *rx_le;
-	u32		     rx_addr64;
+
 	u16		     rx_next;		/* next re to check */
 	u16		     rx_put;		/* next le index to use */
 	u16		     rx_pending;

-- 
Stephen Hemminger <stephen.hemminger@vyatta.com>


^ permalink raw reply

* [PATCH 0/4] sky2: version 1.21
From: Stephen Hemminger @ 2008-01-11  0:14 UTC (permalink / raw)
  To: Jeff Garzik; +Cc: netdev

Set of sky2 patches:
  1) bug fix for 4G mem
  2) low priority fix for WOL default
 --- cut line for 2.6.24 ---
  3) new hardware support
  4) verson 1.21

-- 
Stephen Hemminger <stephen.hemminger@vyatta.com>


^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox