* [PATCH 4/4] ipg: fix Tx completion irq request
From: Francois Romieu @ 2008-01-10 23:38 UTC (permalink / raw)
To: David Miller; +Cc: linux, jeff, Andrew Morton, netdev
In-Reply-To: <20080110233508.GA13315@electric-eye.fr.zoreil.com>
The current logic will only request an ack for the first pending
packet. No irq is triggered as soon as the CPU submits a few
packets a bit quickly. Let's request an irq for every packet
instead.
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
---
drivers/net/ipg.c | 5 +----
1 files changed, 1 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c
index b234b29..50f0c17 100644
--- a/drivers/net/ipg.c
+++ b/drivers/net/ipg.c
@@ -1934,10 +1934,7 @@ static int ipg_nic_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
*/
if (sp->tenmbpsmode)
txfd->tfc |= cpu_to_le64(IPG_TFC_TXINDICATE);
- else if (!((sp->tx_current - sp->tx_dirty + 1) >
- IPG_FRAMESBETWEENTXDMACOMPLETES)) {
- txfd->tfc |= cpu_to_le64(IPG_TFC_TXDMAINDICATE);
- }
+ txfd->tfc |= cpu_to_le64(IPG_TFC_TXDMAINDICATE);
/* Based on compilation option, determine if FCS is to be
* appended to transmit frame by IPG.
*/
--
1.5.3.3
^ permalink raw reply related
* RFC: igb: Intel 82575 gigabit ethernet driver (take #3)
From: Kok, Auke @ 2008-01-10 23:32 UTC (permalink / raw)
To: NetDev, Jeff Garzik
Cc: Arjan van de Ven, Jesse Brandeburg, Ronciak, John, Andrew Morton
[-- Attachment #1: Type: text/plain, Size: 4517 bytes --]
All,
here is the third version of the igb (82575) ethernet controller driver. This
driver was previously posted 2007-07-13 and 2007-12-11. Many comments received
were addressed:
- removed indirection wrappers in the same way as e1000e and ixgbe.
- cleaned up largely against sparse, checkpatch
- removed module parameters and moved functionality to ethtool ioctls
- new NAPI API rewrites
- by default the driver runs in multiqueue mode with 2 to 40 RX queues enabled.
and specifically in this version:
- register macro's were condensed for readability
- fixed namespace collisions by renaming functions to igb_*
Since the driver is still too large (allthough the patch shrunk from 558k to 416k
to 407k, almost 38% of its size) to post to this list I am attaching the bzipped
patch here. You can get the same driver alternatively from here:
http://foo-projects.org/~sofar/0001-igb-PCI-Express-82575-Gigabit-Ethernet-driver.patch
[407k]
http://foo-projects.org/~sofar/0001-igb-PCI-Express-82575-Gigabit-Ethernet-driver.patch.bz2
[74k]
or through git:
git://lost.foo-projects.org/~ahkok/git/linux-2.6 #igb
There are several concerns still open for this driver:
- hardware code is still a large API. we're expecting more hardware to be
supported by this driver in the future. The API has already been scrubbed but we
anticipate that the remaining hooks will be used in the future.
- The register defines are still named "E1000_" as they are mostly identical to
the e1000 chipsets (igb register space is a superset of most recent e1000 register
sets).
Please review,
Cheers,
Auke
---
>From 4ec9e52f44de0c1c41265c5f326b573643f24da7 Mon Sep 17 00:00:00 2001
From: Auke Kok <auke-jan.h.kok@intel.com>
Date: Thu, 10 Jan 2008 14:55:46 -0800
Subject: [PATCH] igb: PCI-Express 82575 Gigabit Ethernet driver
We are pleased to announce a new Gigabit Ethernet product and its
driver to the linux community. This product is the Intel(R) 82575
Gigabit Ethernet adapter family. Physical adapters will be available
to the public soon. These adapters come in 2- and 4-port versions
(copper PHY) currently. Other variants will be available later.
The 82575 chipset supports significantly different features that
warrant a new driver. The descriptor format is (just like the
ixgbe driver) different. The device can use multiple MSI-X vectors
and multiple queues for both send and receive. This allows us to
optimize some of the driver code specifically as well compared to
the e1000-supported devices.
This version of the igb driver no lnger uses fake netdevices and
incorporates napi_struct members for each ring to do the multi-
queue polling. multi-queue is enabled by default and the driver
supports NAPI mode only.
All the namespace collisions should be gone in this version too. The
register macro's have been condensed to improve readability.
Signed-off-by: Auke Kok <auke-jan.h.kok@intel.com>
---
drivers/net/Kconfig | 22 +
drivers/net/Makefile | 1 +
drivers/net/igb/Makefile | 37 +
drivers/net/igb/e1000_82575.c | 1269 ++++++++++++
drivers/net/igb/e1000_82575.h | 150 ++
drivers/net/igb/e1000_defines.h | 772 ++++++++
drivers/net/igb/e1000_hw.h | 599 ++++++
drivers/net/igb/e1000_mac.c | 1505 ++++++++++++++
drivers/net/igb/e1000_mac.h | 98 +
drivers/net/igb/e1000_nvm.c | 605 ++++++
drivers/net/igb/e1000_nvm.h | 40 +
drivers/net/igb/e1000_phy.c | 1807 +++++++++++++++++
drivers/net/igb/e1000_phy.h | 98 +
drivers/net/igb/e1000_regs.h | 270 +++
drivers/net/igb/igb.h | 300 +++
drivers/net/igb/igb_ethtool.c | 1927 ++++++++++++++++++
drivers/net/igb/igb_main.c | 4138 +++++++++++++++++++++++++++++++++++++++
17 files changed, 13638 insertions(+), 0 deletions(-)
create mode 100644 drivers/net/igb/Makefile
create mode 100644 drivers/net/igb/e1000_82575.c
create mode 100644 drivers/net/igb/e1000_82575.h
create mode 100644 drivers/net/igb/e1000_defines.h
create mode 100644 drivers/net/igb/e1000_hw.h
create mode 100644 drivers/net/igb/e1000_mac.c
create mode 100644 drivers/net/igb/e1000_mac.h
create mode 100644 drivers/net/igb/e1000_nvm.c
create mode 100644 drivers/net/igb/e1000_nvm.h
create mode 100644 drivers/net/igb/e1000_phy.c
create mode 100644 drivers/net/igb/e1000_phy.h
create mode 100644 drivers/net/igb/e1000_regs.h
create mode 100644 drivers/net/igb/igb.h
create mode 100644 drivers/net/igb/igb_ethtool.c
create mode 100644 drivers/net/igb/igb_main.c
[-- Attachment #2: 0001-igb-PCI-Express-82575-Gigabit-Ethernet-driver.patch.bz2 --]
[-- Type: application/x-bzip2, Size: 75975 bytes --]
^ permalink raw reply
* [PATCH 3/4] ipg: fix queue stop condition in the xmit handler
From: Francois Romieu @ 2008-01-10 23:37 UTC (permalink / raw)
To: David Miller; +Cc: linux, jeff, Andrew Morton, netdev
In-Reply-To: <20080110233508.GA13315@electric-eye.fr.zoreil.com>
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
---
drivers/net/ipg.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/ipg.c b/drivers/net/ipg.c
index 9752902..b234b29 100644
--- a/drivers/net/ipg.c
+++ b/drivers/net/ipg.c
@@ -1994,7 +1994,7 @@ static int ipg_nic_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
ipg_w32(IPG_DC_TX_DMA_POLL_NOW, DMA_CTRL);
if (sp->tx_current == (sp->tx_dirty + IPG_TFDLIST_LENGTH))
- netif_wake_queue(dev);
+ netif_stop_queue(dev);
spin_unlock_irqrestore(&sp->lock, flags);
--
1.5.3.3
^ permalink raw reply related
* Re: [NET] ROUTE: fix rcu_dereference() uses in /proc/net/rt_cache
From: Herbert Xu @ 2008-01-11 0:00 UTC (permalink / raw)
To: Jarek Poplawski; +Cc: Eric Dumazet, Paul E. McKenney, davem, dipankar, netdev
In-Reply-To: <20080110231042.GA3199@ami.dom.local>
On Fri, Jan 11, 2008 at 12:10:42AM +0100, Jarek Poplawski wrote:
>
> It seems this optimization could've a side effect: if during such a
> loop updates are done, and r is seen !NULL during while() check, but
> NULL after rcu_dereference(), the listing/counting could stop too
> soon. So, IMHO, probably the first version of this patch is more
> reliable. (Or alternatively additional check is needed before return.)
No, while the value of r->u.dst.rt_next can change between two readings,
the value of r cannot.
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: RFC: igb: Intel 82575 gigabit ethernet driver (take #3)
From: Jeff Garzik @ 2008-01-11 0:01 UTC (permalink / raw)
To: Kok, Auke
Cc: NetDev, Arjan van de Ven, Jesse Brandeburg, Ronciak, John,
Andrew Morton
In-Reply-To: <4786AB0C.6010202@intel.com>
Kok, Auke wrote:
> All,
>
> here is the third version of the igb (82575) ethernet controller driver. This
> driver was previously posted 2007-07-13 and 2007-12-11. Many comments received
> were addressed:
>
> - removed indirection wrappers in the same way as e1000e and ixgbe.
> - cleaned up largely against sparse, checkpatch
> - removed module parameters and moved functionality to ethtool ioctls
> - new NAPI API rewrites
> - by default the driver runs in multiqueue mode with 2 to 40 RX queues enabled.
>
> and specifically in this version:
>
> - register macro's were condensed for readability
> - fixed namespace collisions by renaming functions to igb_*
>
> Since the driver is still too large (allthough the patch shrunk from 558k to 416k
> to 407k, almost 38% of its size) to post to this list I am attaching the bzipped
> patch here. You can get the same driver alternatively from here:
>
> http://foo-projects.org/~sofar/0001-igb-PCI-Express-82575-Gigabit-Ethernet-driver.patch
> [407k]
> http://foo-projects.org/~sofar/0001-igb-PCI-Express-82575-Gigabit-Ethernet-driver.patch.bz2
> [74k]
>
> or through git:
> git://lost.foo-projects.org/~ahkok/git/linux-2.6 #igb
>
>
> There are several concerns still open for this driver:
> - hardware code is still a large API. we're expecting more hardware to be
> supported by this driver in the future. The API has already been scrubbed but we
> anticipate that the remaining hooks will be used in the future.
> - The register defines are still named "E1000_" as they are mostly identical to
> the e1000 chipsets (igb register space is a superset of most recent e1000 register
> sets).
I think we can throw it into netdev#upstream if you're ready...
Jeff
^ permalink raw reply
* Re: RFC: igb: Intel 82575 gigabit ethernet driver (take #3)
From: Kok, Auke @ 2008-01-11 0:22 UTC (permalink / raw)
To: Jeff Garzik
Cc: NetDev, Arjan van de Ven, Jesse Brandeburg, Ronciak, John,
Andrew Morton
In-Reply-To: <4786B1E7.5030700@pobox.com>
Jeff Garzik wrote:
> Kok, Auke wrote:
>> All,
>>
>> here is the third version of the igb (82575) ethernet controller
>> driver. This
>> driver was previously posted 2007-07-13 and 2007-12-11. Many comments
>> received
>> were addressed:
>>
>> - removed indirection wrappers in the same way as e1000e and ixgbe.
>> - cleaned up largely against sparse, checkpatch
>> - removed module parameters and moved functionality to ethtool ioctls
>> - new NAPI API rewrites
>> - by default the driver runs in multiqueue mode with 2 to 40 RX queues
>> enabled.
>>
>> and specifically in this version:
>>
>> - register macro's were condensed for readability
>> - fixed namespace collisions by renaming functions to igb_*
>>
>> Since the driver is still too large (allthough the patch shrunk from
>> 558k to 416k
>> to 407k, almost 38% of its size) to post to this list I am attaching
>> the bzipped
>> patch here. You can get the same driver alternatively from here:
>>
>> http://foo-projects.org/~sofar/0001-igb-PCI-Express-82575-Gigabit-Ethernet-driver.patch
>>
>> [407k]
>> http://foo-projects.org/~sofar/0001-igb-PCI-Express-82575-Gigabit-Ethernet-driver.patch.bz2
>>
>> [74k]
>>
>> or through git:
>> git://lost.foo-projects.org/~ahkok/git/linux-2.6 #igb
>>
>>
>> There are several concerns still open for this driver:
>> - hardware code is still a large API. we're expecting more hardware to be
>> supported by this driver in the future. The API has already been
>> scrubbed but we
>> anticipate that the remaining hooks will be used in the future.
>> - The register defines are still named "E1000_" as they are mostly
>> identical to
>> the e1000 chipsets (igb register space is a superset of most recent
>> e1000 register
>> sets).
>
> I think we can throw it into netdev#upstream if you're ready...
yes, of course :)
both the patch file and the git tree should work for you.
Cheers,
Auke
^ permalink raw reply
* Re: [ipw3945-devel] [PATCH 4/5] iwlwifi: iwl3945 eliminate sleepable task queue from context
From: Zhu Yi @ 2008-01-11 1:06 UTC (permalink / raw)
To: Joonwoo Park
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
linux-wireless-u79uwXL29TY76Z2rM5mHXA, lkml,
ipw3945-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
In-Reply-To: <11998765783953-git-send-email-joonwpark81-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
Hi Joonwoo,
We already did something similiar in our code base. Could you please
take a look at this patch?
http://intellinuxwireless.org/repos/?p=iwlwifi.git;a=commitdiff;h=57aa02255e9d7be5e2494683fc2793bd1d0707e2
Thanks,
-yi
On Wed, 2008-01-09 at 20:02 +0900, Joonwoo Park wrote:
> Eleminiate task queuing of iwl_pci_probe, register hw to ieee80211 immediately
>
> Signed-off-by: Joonwoo Park <joonwpark81-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> ---
> drivers/net/wireless/iwlwifi/iwl3945-base.c | 66 +++++++++++++++++---------
> 1 files changed, 43 insertions(+), 23 deletions(-)
>
> diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c
> index f95f226..7e8d8b3 100644
> --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c
> +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c
> @@ -6171,27 +6171,9 @@ static void iwl_alive_start(struct iwl_priv *priv)
> if (iwl_is_rfkill(priv))
> return;
>
> - if (!priv->mac80211_registered) {
> - /* Unlock so any user space entry points can call back into
> - * the driver without a deadlock... */
> - mutex_unlock(&priv->mutex);
> - iwl_rate_control_register(priv->hw);
> - rc = ieee80211_register_hw(priv->hw);
> - priv->hw->conf.beacon_int = 100;
> - mutex_lock(&priv->mutex);
> -
> - if (rc) {
> - iwl_rate_control_unregister(priv->hw);
> - IWL_ERROR("Failed to register network "
> - "device (error %d)\n", rc);
> - return;
> - }
> -
> - priv->mac80211_registered = 1;
> + iwl_reset_channel_flag(priv);
>
> - iwl_reset_channel_flag(priv);
> - } else
> - ieee80211_start_queues(priv->hw);
> + ieee80211_start_queues(priv->hw);
>
> priv->active_rate = priv->rates_mask;
> priv->active_rate_basic = priv->rates_mask & IWL_BASIC_RATES_MASK;
> @@ -6369,7 +6351,8 @@ static int __iwl_up(struct iwl_priv *priv)
>
> /* clear (again), then enable host interrupts */
> iwl_write32(priv, CSR_INT, 0xFFFFFFFF);
> - iwl_enable_interrupts(priv);
> + if (priv->mac80211_registered)
> + iwl_enable_interrupts(priv);
>
> /* really make sure rfkill handshake bits are cleared */
> iwl_write32(priv, CSR_UCODE_DRV_GP1_CLR, CSR_UCODE_SW_BIT_RFKILL);
> @@ -6887,10 +6870,21 @@ static void iwl_bg_scan_completed(struct work_struct *work)
>
> static int iwl_mac_start(struct ieee80211_hw *hw)
> {
> + int ret;
> struct iwl_priv *priv = hw->priv;
>
> IWL_DEBUG_MAC80211("enter\n");
>
> + ret = wait_event_interruptible_timeout(priv->wait_command_queue,
> + iwl_is_ready(priv), HOST_COMPLETE_TIMEOUT);
> +
> + if (ret == -ERESTARTSYS)
> + return ret;
> + else if (ret == 0 && !iwl_is_ready(priv)) {
> + IWL_ERROR("IWL ready timeout\n");
> + return -ETIMEDOUT;
> + }
> +
> /* we should be verifying the device is ready to be opened */
> mutex_lock(&priv->mutex);
>
> @@ -8299,6 +8293,19 @@ static void iwl_cancel_deferred_work(struct iwl_priv *priv)
> cancel_work_sync(&priv->beacon_update);
> }
>
> +static int iwl_register_hw(struct iwl_priv *priv)
> +{
> + int err;
> + IWL_DEBUG_INFO("register_hw\n");
> + iwl_rate_control_register(priv->hw);
> + err = ieee80211_register_hw(priv->hw);
> + if (!err) {
> + priv->hw->conf.beacon_int = 100;
> + priv->mac80211_registered = 1;
> + }
> + return err;
> +}
> +
> static struct attribute *iwl_sysfs_entries[] = {
> &dev_attr_antenna.attr,
> &dev_attr_channels.attr,
> @@ -8546,11 +8553,24 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
> goto out_pci_alloc;
> }
>
> + err = __iwl_up(priv);
> + if (err) {
> + IWL_ERROR("Could not make up interface : %d\n", err);
> + mutex_unlock(&priv->mutex);
> + goto out_pci_alloc;
> + }
> +
> mutex_unlock(&priv->mutex);
>
> - IWL_DEBUG_INFO("Queing UP work.\n");
> + err = iwl_register_hw(priv);
> + if (err) {
> + iwl_rate_control_unregister(priv->hw);
> + IWL_ERROR("Failed to register network "
> + "device (error %d)\n", err);
> + goto out_pci_alloc;
> + }
>
> - queue_work(priv->workqueue, &priv->up);
> + iwl_enable_interrupts(priv);
>
> return 0;
>
^ permalink raw reply
* Re: [PATCH 0/3] bonding: 3 fixes for 2.6.24
From: Jay Vosburgh @ 2008-01-11 1:06 UTC (permalink / raw)
To: Herbert Xu
Cc: Andy Gospodarek, Krzysztof Oledzki, netdev, Jeff Garzik,
David Miller
In-Reply-To: <20080110210507.GA17344@gondor.apana.org.au>
Herbert Xu <herbert@gondor.apana.org.au> wrote:
>On Thu, Jan 10, 2008 at 04:03:53PM -0500, Andy Gospodarek wrote:
>>
>> > >Sure, but where do you call that function while holding the bond lock?
>> >
>> > If I recall correctly, the problem was that tg3, et al, did
>> > things that might sleep, and bonding was calling from a timer context,
>> > which couldn't sleep. It wasn't about the lock.
>>
>> Exactly, I was just about to post the same.
>
>In other words, changing read_lock on bond->lock to read_lock_bh doesn't
>affect this one bit.
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
dev_set_mac_address (since it isn't called from there) and, apparently,
also resolves the lockdep warning. I'm still trying to get lockdep to
generate the warning for me locally; I'm not sure which magic thing I'm
missing.
-J
---
-Jay Vosburgh, IBM Linux Technology Center, fubar@us.ibm.com
^ permalink raw reply
* handing cloned frames to netif_rx()?
From: Johannes Berg @ 2008-01-11 1:17 UTC (permalink / raw)
To: netdev; +Cc: Ron Rindjunsky, linux-wireless
[-- Attachment #1: Type: text/plain, Size: 792 bytes --]
In 802.11n, there is a case where multiple data frames are received
aggregated into a single frame (A-MSDU).
Currently, we copy each of these frames out into their own skb, but
because of the alignment with that etc. I started to think that we could
simply pass up a clone of the original skb with start/length adjusted
properly so that it windows only the contained packet.
The buffer would be shared but the data within the original window
(starting with the 802.3 header) could even be written to, it won't be
needed again by mac80211 once it's handed off to netif_rx(). The skb
will obviously have lots of head- and tailroom but that space would be
part of other packets.
Is it ok to do this? Will something freak out if we pass a cloned skb to
netif_rx()?
johannes
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]
^ permalink raw reply
* Re: questions on NAPI processing latency and dropped network packets
From: David Miller @ 2008-01-11 1:20 UTC (permalink / raw)
To: cfriesen; +Cc: netdev, linux-kernel
In-Reply-To: <478654C3.60806@nortel.com>
From: "Chris Friesen" <cfriesen@nortel.com>
Date: Thu, 10 Jan 2008 11:24:19 -0600
> I've got an issue that's popped up with a deployed system running
> 2.6.10.
...
> So...anyone have any ideas/suggestions?
You have to be kidding, coming here for help with a nearly
4 year old kernel.
The networking stack as well as the e1000 driver has been
practically rewritten several times over since then.
^ permalink raw reply
* Re: [PATCH 2/5] iwlwifi: iwl3945 synchronize interruptand tasklet for down iwlwifi
From: Joonwoo Park @ 2008-01-11 1:24 UTC (permalink / raw)
To: Chatre, Reinette; +Cc: netdev, Zhu, Yi, linux-wireless, lkml, ipw3945-devel
In-Reply-To: <D936D925018D154694D8A362EEB08920035CCD70@orsmsx416.amr.corp.intel.com>
Hello Reinette,
2008/1/11, Chatre, Reinette <reinette.chatre@intel.com>:
>
> Could synchronize_irq() be moved into iwl_disable_interrupts() ? I am
At this time, iwl_disable_interrupts() can be called with irq
disabled, so for do that I think additional modification would be
needed.
> also wondering if we cannot call tasklet_kill() before
> iwl_disable_interrupts() ... thus preventing it from being scheduled
> when we are going down.
Thanks for your catch, it seems tasklet can re-enable interrupts.
I'll handle and make an another patch for them at this weekend :)
Thanks,
Joonwoo
-------------------------------------------------------------------------
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: e1000 performance issue in 4 simultaneous links
From: David Miller @ 2008-01-11 1:28 UTC (permalink / raw)
To: jesse.brandeburg; +Cc: leitao, netdev
In-Reply-To: <36D9DB17C6DE9E40B059440DB8D95F5204275B04@orsmsx418.amr.corp.intel.com>
From: "Brandeburg, Jesse" <jesse.brandeburg@intel.com>
Date: Thu, 10 Jan 2008 12:52:15 -0800
> I hope this explanation makes sense, but what it comes down to is that
> combining hardware round robin balancing with NAPI is a BAD IDEA.
Absolutely agreed on all counts.
No IRQ balancing should be done at all for networking device
interrupts, with zero exceptions. It destroys performance.
^ permalink raw reply
* Re: [ipw3945-devel] [PATCH 4/5] iwlwifi: iwl3945 eliminate sleepable task queue from context
From: Joonwoo Park @ 2008-01-11 1:38 UTC (permalink / raw)
To: Zhu Yi
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
linux-wireless-u79uwXL29TY76Z2rM5mHXA, lkml,
ipw3945-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
In-Reply-To: <1200013607.3530.128.camel-F7Q/YMNgnyhhZnBKgDE8z0EOCMrvLtNR@public.gmane.org>
2008/1/11, Zhu Yi <yi.zhu-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>:
> Hi Joonwoo,
>
> We already did something similiar in our code base. Could you please
> take a look at this patch?
>
> http://intellinuxwireless.org/repos/?p=iwlwifi.git;a=commitdiff;h=57aa02255e9d7be5e2494683fc2793bd1d0707e2
>
> Thanks,
> -yi
Ooops :-)
I should have checked code base, it's my fault.
it's seems very similar, but I could not made build unfortunately.
Can you introduce to me how to build it please?
my build error is here:
jason@ehus ~/SRC/DRIVERS/iwlwifi $ KSRC=/home/jason/SRC/LINUX/linux-2.6 make
make -C /home/jason/SRC/LINUX/linux-2.6 O=
M=/home/jason/SRC/DRIVERS/iwlwifi/compatible/
EXTRA_CFLAGS="-DCONFIG_IWL3945_DEBUG=y -DCONFIG_IWL4965_DEBUG=y
-DCONFIG_IWL3945_SPECTRUM_MEASUREMENT=y
-DCONFIG_IWL4965_SPECTRUM_MEASUREMENT=y -DCONFIG_IWL4965_SENSITIVITY=y
-DCONFIG_IWL3945_QOS=y -DCONFIG_IWL4965_QOS=y" modules
make[1]: Entering directory `/home/jason/SRC/LINUX/linux-2.6'
CC [M] /home/jason/SRC/DRIVERS/iwlwifi/compatible/iwl3945-base.o
In file included from
/home/jason/SRC/DRIVERS/iwlwifi/compatible/iwl3945-base.c:51:
/home/jason/SRC/DRIVERS/iwlwifi/compatible/iwl-3945.h:443: error:
expected specifier-qualifier-list before 'ieee80211_key_alg'
/home/jason/SRC/DRIVERS/iwlwifi/compatible/iwl3945-base.c: In function
'iwl3945_add_station':
/home/jason/SRC/DRIVERS/iwlwifi/compatible/iwl3945-base.c:539: error:
implicit declaration of function 'MAC_ARG'
/home/jason/SRC/DRIVERS/iwlwifi/compatible/iwl3945-base.c:539:
warning: too few arguments for format
/home/jason/SRC/DRIVERS/iwlwifi/compatible/iwl3945-base.c: In function
'iwl3945_commit_rxon':
/home/jason/SRC/DRIVERS/iwlwifi/compatible/iwl3945-base.c:1161:
warning: too few arguments for format
/home/jason/SRC/DRIVERS/iwlwifi/compatible/iwl3945-base.c: In function
'iwl3945_update_sta_key_info':
/home/jason/SRC/DRIVERS/iwlwifi/compatible/iwl3945-base.c:1400: error:
'struct iwl3945_hw_key' has no member named 'alg'
/home/jason/SRC/DRIVERS/iwlwifi/compatible/iwl3945-base.c:1401: error:
'struct iwl3945_hw_key' has no member named 'keylen'
/home/jason/SRC/DRIVERS/iwlwifi/compatible/iwl3945-base.c:1402: error:
'struct iwl3945_hw_key' has no member named 'key'
/home/jason/SRC/DRIVERS/iwlwifi/compatible/iwl3945-base.c:1402: error:
'struct iwl3945_hw_key' has no member named 'key'
/home/jason/SRC/DRIVERS/iwlwifi/compatible/iwl3945-base.c: In function
'iwl3945_build_tx_cmd_hwcrypto':
/home/jason/SRC/DRIVERS/iwlwifi/compatible/iwl3945-base.c:2594: error:
'struct iwl3945_hw_key' has no member named 'alg'
/home/jason/SRC/DRIVERS/iwlwifi/compatible/iwl3945-base.c:2597: error:
'struct iwl3945_hw_key' has no member named 'keylen'
/home/jason/SRC/DRIVERS/iwlwifi/compatible/iwl3945-base.c:2597: error:
'struct iwl3945_hw_key' has no member named 'key'
/home/jason/SRC/DRIVERS/iwlwifi/compatible/iwl3945-base.c:2597: error:
'struct iwl3945_hw_key' has no member named 'keylen'
/home/jason/SRC/DRIVERS/iwlwifi/compatible/iwl3945-base.c:2597: error:
'struct iwl3945_hw_key' has no member named 'key'
/home/jason/SRC/DRIVERS/iwlwifi/compatible/iwl3945-base.c:2597: error:
'struct iwl3945_hw_key' has no member named 'keylen'
Thanks,
Joonwoo
^ permalink raw reply
* Re: my NAPI patches
From: Jay Cliburn @ 2008-01-11 1:44 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20080108.150848.116653308.davem@davemloft.net>
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.
Jay
^ permalink raw reply
* Re: [PATCH net-2.6.25 0/6][NETNS]: Make ipv6_devconf (all and default) live in net namespaces
From: David Miller @ 2008-01-11 1:54 UTC (permalink / raw)
To: xemul; +Cc: netdev, devel, dlezcano, benjamin.thery
In-Reply-To: <478623C0.7030008@openvz.org>
From: Pavel Emelyanov <xemul@openvz.org>
Date: Thu, 10 Jan 2008 16:55:12 +0300
> The ipv6_devconf_(all) and ipv6_devconf_dflt are currently
> global, but should be per-namespace.
>
> This set moves them on the struct net. Or, more precisely,
> on the struct netns_ipv6, which is already added.
>
> Unfortunately, many code in the ipv6 cannot yet provide a
> correct struct net to get the ipv6_devconf from (e.g. routing
> code), so this part of job is to be done after the appropriate
> parts are virtualized.
>
> However, after this set user can play with the ipv6_devconf
> inside a namespace not affecting the others.
>
> Signed-off-by: Pavel Emelyanov <xemul@openvz.org>
All 6 patches applied, thanks Pavel.
^ permalink raw reply
* Re: [PATCH 0/4] Pull request for 'ipg-fixes' branch
From: linux @ 2008-01-11 1:58 UTC (permalink / raw)
To: davem, romieu; +Cc: akpm, jeff, linux, netdev
In-Reply-To: <20080110233508.GA13315@electric-eye.fr.zoreil.com>
Thank you very much, this appears to work.
> The driver is still a POMS but it seems better now.
I notice that the vendor-supplied driver doesn't have these bugs.
Now, it does have a bug in that it doesn't have an "is this
interrupt for me?" test at all (and always returns "I handled it"),
but the bypass and its locking screwups are a later addition.
The same with the sp->rx_current bugs. The original loop which used
rx_current as the loop iteration variable wasn't great style, precisely
because it hides the interaction that someone's "optimization" broke,
but I don't want to blame the vendor for things they didn't do.
Would you be interested in some cleanup patches? In particular, I think I
can get rid of tx->lock entirely, or at least take it off the fast path.
All it's protecting is the write to sp->tx_current, and a few judicious
memory barriers can deal with that.
(Oh, another BUG: the sp->ResetCurrentTFD logic in hard_start_xmit is
just plain broken. It writes the new data to entry 0, then increments
sp->tx_current just like usual. THAT isn't in the vendor driver that
I see, either.)
^ permalink raw reply
* Re: [ipw3945-devel] [PATCH 4/5] iwlwifi: iwl3945 eliminate sleepable task queue from context
From: Zhu Yi @ 2008-01-11 2:01 UTC (permalink / raw)
To: Joonwoo Park
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
linux-wireless-u79uwXL29TY76Z2rM5mHXA, lkml,
ipw3945-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
In-Reply-To: <b25c3fa70801101738j512a6189i3e4541bf0348b91f-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Fri, 2008-01-11 at 10:38 +0900, Joonwoo Park wrote:
> I should have checked code base, it's my fault.
> it's seems very similar, but I could not made build unfortunately.
> Can you introduce to me how to build it please?
>
> my build error is here:
> jason@ehus ~/SRC/DRIVERS/iwlwifi $
> KSRC=/home/jason/SRC/LINUX/linux-2.6 make
The version doesn't work on a .24-rc kernel. Can you compile it
with .23?
Thanks,
-yi
^ permalink raw reply
* Re: [ipw3945-devel] [PATCH 4/5] iwlwifi: iwl3945 eliminate sleepable task queue from context
From: Joonwoo Park @ 2008-01-11 2:22 UTC (permalink / raw)
To: Zhu Yi
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
linux-wireless-u79uwXL29TY76Z2rM5mHXA, lkml,
ipw3945-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f
In-Reply-To: <1200016915.3530.161.camel-F7Q/YMNgnyhhZnBKgDE8z0EOCMrvLtNR@public.gmane.org>
2008/1/11, Zhu Yi <yi.zhu-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>:
>
> The version doesn't work on a .24-rc kernel. Can you compile it
> with .23?
>
Thank you for your help, I built it.
Thanks,
Joonwoo
^ permalink raw reply
* [PATCH 3/4] sky2: support for Yukon Supreme
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-supreme.patch --]
[-- Type: text/plain, Size: 4815 bytes --]
Add support from sk98lin vendor driver 10.50.1.3 for 88E8055 and
88E8075 chips. I don't have this hardware to test, so this changes
are untested.
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:20.000000000 -0800
+++ b/drivers/net/sky2.c 2008-01-10 15:49:27.000000000 -0800
@@ -134,6 +134,8 @@ static const struct pci_device_id sky2_i
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436A) }, /* 88E8058 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436B) }, /* 88E8071 */
{ PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436C) }, /* 88E8072 */
+ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x436D) }, /* 88E8055 */
+ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4370) }, /* 88E8075 */
{ 0 }
};
@@ -547,6 +549,7 @@ static void sky2_phy_init(struct sky2_hw
case CHIP_ID_YUKON_EC_U:
case CHIP_ID_YUKON_EX:
+ case CHIP_ID_YUKON_SUPR:
pg = gm_phy_read(hw, port, PHY_MARV_EXT_ADR);
/* select page 3 to access LED control register */
@@ -713,23 +716,33 @@ static void sky2_set_tx_stfwd(struct sky
{
struct net_device *dev = hw->dev[port];
- if (dev->mtu <= ETH_DATA_LEN)
- sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
- TX_JUMBO_DIS | TX_STFW_ENA);
+ if ( (hw->chip_id == CHIP_ID_YUKON_EX &&
+ hw->chip_rev != CHIP_REV_YU_EX_A0) ||
+ hw->chip_id == CHIP_ID_YUKON_FE_P ||
+ hw->chip_id == CHIP_ID_YUKON_SUPR) {
+ /* Yukon-Extreme B0 and further Extreme devices */
+ /* enable Store & Forward mode for TX */
+
+ if (dev->mtu <= ETH_DATA_LEN)
+ sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
+ TX_JUMBO_DIS | TX_STFW_ENA);
- else if (hw->chip_id != CHIP_ID_YUKON_EC_U)
- sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
- TX_STFW_ENA | TX_JUMBO_ENA);
- else {
- /* set Tx GMAC FIFO Almost Empty Threshold */
- sky2_write32(hw, SK_REG(port, TX_GMF_AE_THR),
- (ECU_JUMBO_WM << 16) | ECU_AE_THR);
+ else
+ sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
+ TX_JUMBO_ENA| TX_STFW_ENA);
+ } else {
+ if (dev->mtu <= ETH_DATA_LEN)
+ sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_STFW_ENA);
+ else {
+ /* set Tx GMAC FIFO Almost Empty Threshold */
+ sky2_write32(hw, SK_REG(port, TX_GMF_AE_THR),
+ (ECU_JUMBO_WM << 16) | ECU_AE_THR);
- sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T),
- TX_JUMBO_ENA | TX_STFW_DIS);
+ sky2_write32(hw, SK_REG(port, TX_GMF_CTRL_T), TX_STFW_DIS);
- /* Can't do offload because of lack of store/forward */
- dev->features &= ~(NETIF_F_TSO | NETIF_F_SG | NETIF_F_ALL_CSUM);
+ /* Can't do offload because of lack of store/forward */
+ dev->features &= ~(NETIF_F_TSO | NETIF_F_SG | NETIF_F_ALL_CSUM);
+ }
}
}
@@ -2660,6 +2673,7 @@ static u32 sky2_mhz(const struct sky2_hw
case CHIP_ID_YUKON_EC:
case CHIP_ID_YUKON_EC_U:
case CHIP_ID_YUKON_EX:
+ case CHIP_ID_YUKON_SUPR:
return 125;
case CHIP_ID_YUKON_FE:
@@ -2743,6 +2757,15 @@ static int __devinit sky2_init(struct sk
| SKY2_HW_AUTO_TX_SUM
| SKY2_HW_ADV_POWER_CTL;
break;
+
+ case CHIP_ID_YUKON_SUPR:
+ hw->flags = SKY2_HW_GIGABIT
+ | SKY2_HW_NEWER_PHY
+ | SKY2_HW_NEW_LE
+ | SKY2_HW_AUTO_TX_SUM
+ | SKY2_HW_ADV_POWER_CTL;
+ break;
+
default:
dev_err(&hw->pdev->dev, "unsupported chip type 0x%x\n",
hw->chip_id);
@@ -2813,7 +2836,8 @@ static void sky2_reset(struct sky2_hw *h
sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET);
sky2_write8(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR);
- if (hw->chip_id == CHIP_ID_YUKON_EX)
+ if (hw->chip_id == CHIP_ID_YUKON_EX ||
+ hw->chip_id == CHIP_ID_YUKON_SUPR)
sky2_write16(hw, SK_REG(i, GMAC_CTRL),
GMC_BYP_MACSECRX_ON | GMC_BYP_MACSECTX_ON
| GMC_BYP_RETR_ON);
--- a/drivers/net/sky2.h 2008-01-10 15:49:12.000000000 -0800
+++ b/drivers/net/sky2.h 2008-01-10 15:49:27.000000000 -0800
@@ -425,12 +425,13 @@ enum {
/* B2_CHIP_ID 8 bit Chip Identification Number */
enum {
- CHIP_ID_YUKON_XL = 0xb3, /* Chip ID for YUKON-2 XL */
- CHIP_ID_YUKON_EC_U = 0xb4, /* Chip ID for YUKON-2 EC Ultra */
- CHIP_ID_YUKON_EX = 0xb5, /* Chip ID for YUKON-2 Extreme */
- CHIP_ID_YUKON_EC = 0xb6, /* Chip ID for YUKON-2 EC */
- CHIP_ID_YUKON_FE = 0xb7, /* Chip ID for YUKON-2 FE */
- CHIP_ID_YUKON_FE_P = 0xb8, /* Chip ID for YUKON-2 FE+ */
+ CHIP_ID_YUKON_XL = 0xb3, /* YUKON-2 XL */
+ CHIP_ID_YUKON_EC_U = 0xb4, /* YUKON-2 EC Ultra */
+ CHIP_ID_YUKON_EX = 0xb5, /* YUKON-2 Extreme */
+ CHIP_ID_YUKON_EC = 0xb6, /* YUKON-2 EC */
+ CHIP_ID_YUKON_FE = 0xb7, /* YUKON-2 FE */
+ CHIP_ID_YUKON_FE_P = 0xb8, /* YUKON-2 FE+ */
+ CHIP_ID_YUKON_SUPR = 0xb9, /* YUKON-2 Supreme */
};
enum yukon_ec_rev {
CHIP_REV_YU_EC_A1 = 0, /* Chip Rev. for Yukon-EC A1/A0 */
--
Stephen Hemminger <stephen.hemminger@vyatta.com>
^ permalink raw reply
* [PATCH 2/4] sky2: remove check for PCI wakeup setting from BIOS
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-remove-pci-check.patch --]
[-- Type: text/plain, Size: 2641 bytes --]
The driver checks status of PCI power management to mark
default setting of Wake On Lan. On some systems this works, but often
it reports a that WOL is disabled when it isn't.
This patch gets rid of that check and just reports the wake on
lan status based on the hardware capablity.
Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org>
---
Please apply for 2.6.24.
--- a/drivers/net/sky2.c 2008-01-10 15:49:12.000000000 -0800
+++ b/drivers/net/sky2.c 2008-01-10 15:49:20.000000000 -0800
@@ -3946,7 +3946,7 @@ static __exit void sky2_debug_cleanup(vo
/* Initialize network device */
static __devinit struct net_device *sky2_init_netdev(struct sky2_hw *hw,
unsigned port,
- int highmem, int wol)
+ int highmem)
{
struct sky2_port *sky2;
struct net_device *dev = alloc_etherdev(sizeof(*sky2));
@@ -3986,7 +3986,7 @@ static __devinit struct net_device *sky2
sky2->speed = -1;
sky2->advertising = sky2_supported_modes(hw);
sky2->rx_csum = (hw->chip_id != CHIP_ID_YUKON_XL);
- sky2->wol = wol;
+ sky2->wol = sky2_wol_supported(hw) & WAKE_MAGIC;
spin_lock_init(&sky2->phy_lock);
sky2->tx_pending = TX_DEF_PENDING;
@@ -4083,24 +4083,12 @@ static int __devinit sky2_test_msi(struc
return err;
}
-static int __devinit pci_wake_enabled(struct pci_dev *dev)
-{
- int pm = pci_find_capability(dev, PCI_CAP_ID_PM);
- u16 value;
-
- if (!pm)
- return 0;
- if (pci_read_config_word(dev, pm + PCI_PM_CTRL, &value))
- return 0;
- return value & PCI_PM_CTRL_PME_ENABLE;
-}
-
static int __devinit sky2_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct net_device *dev;
struct sky2_hw *hw;
- int err, using_dac = 0, wol_default;
+ int err, using_dac = 0;
err = pci_enable_device(pdev);
if (err) {
@@ -4133,8 +4121,6 @@ static int __devinit sky2_probe(struct p
}
}
- wol_default = pci_wake_enabled(pdev) ? WAKE_MAGIC : 0;
-
err = -ENOMEM;
hw = kzalloc(sizeof(*hw), GFP_KERNEL);
if (!hw) {
@@ -4178,7 +4164,7 @@ static int __devinit sky2_probe(struct p
sky2_reset(hw);
- dev = sky2_init_netdev(hw, 0, using_dac, wol_default);
+ dev = sky2_init_netdev(hw, 0, using_dac);
if (!dev) {
err = -ENOMEM;
goto err_out_free_pci;
@@ -4215,7 +4201,7 @@ static int __devinit sky2_probe(struct p
if (hw->ports > 1) {
struct net_device *dev1;
- dev1 = sky2_init_netdev(hw, 1, using_dac, wol_default);
+ dev1 = sky2_init_netdev(hw, 1, using_dac);
if (!dev1)
dev_warn(&pdev->dev, "allocation for second device failed\n");
else if ((err = register_netdev(dev1))) {
--
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
* [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 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
* 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
* 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
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox