Netdev List
 help / color / mirror / Atom feed
* Re: Reoccuring kern.log events after running xl2tp with ethernet adapter Realtek 8111E
From: Dustin Schumm @ 2012-06-06 19:04 UTC (permalink / raw)
  To: Francois Romieu; +Cc: netdev
In-Reply-To: <CANcVnzj-DUD8x9jcj3awyWkZjH9x5PMf3fAFtR_osPNAU9adgA@mail.gmail.com>

On Tue, Jun 5, 2012 at 11:59 AM, Dustin Schumm <shodid@gmail.com> wrote:
> On Tue, Jun 5, 2012 at 11:37 AM, Francois Romieu <romieu@fr.zoreil.com> wrote:
>>
>> This is with an usual 1500 bytes MTU and without TSO (see 'ethtool -k ethX'),
>> right ?
>>
>> --
>> Ueimor
>
> Yes,
>
> MTU:1500
> tcp-segmentation-offload: off

Do you see any indication if this is a problem with the mainline
kernel, distro kernel, driver, or otherwise? It's not definitive, been
I've been good using kernels 2.6.x and getting errors on everything
3.x I have tried. I am looking for some direction to pursue. Thanks.

-Dustin

^ permalink raw reply

* Re: Change in alloc_skb() behavior in 3.2+ kernels?
From: David Miller @ 2012-06-06 19:02 UTC (permalink / raw)
  To: grant.b.edwards; +Cc: netdev
In-Reply-To: <jqo9a6$ah6$1@dough.gmane.org>

From: Grant Edwards <grant.b.edwards@gmail.com>
Date: Wed, 6 Jun 2012 18:59:19 +0000 (UTC)

> At the time it was written (probably 10+ years ago) it was relying on
> the documented API for alloc_skb() that stated alloc_skb() either
> returned an sk_buff of the requested size or it failed.

It was never a formal API that we would only allocate 'size'
amount of tailroom.

^ permalink raw reply

* Re: Change in alloc_skb() behavior in 3.2+ kernels?
From: Grant Edwards @ 2012-06-06 18:59 UTC (permalink / raw)
  To: netdev
In-Reply-To: <1339008142.26966.40.camel@edumazet-glaptop>

On 2012-06-06, Eric Dumazet <eric.dumazet@gmail.com> wrote:
> On Wed, 2012-06-06 at 18:32 +0000, Grant Edwards wrote:
>
>> I'm tracking down a problem that appears to be caused by a change in
>> the behavior of alloc_skb() introduced in kernel version 3.2.  In
>> kernel versions prior to 3.2, calling alloc_skb(1350), returned an
>> sk_buff with a tailroom of around 1400 bytes (safely below the
>> default Ethernet frame size limit of 1500).
>> 
>> In 3.2 and later, calling alloc_skb(1350) returns an sk_buff with a
>> tailroom of about 1850.
>> 
>> Why has the "extra" space increased from 60 bytes to 500 bytes?
>
> Because of kmalloc-2048 being used. Previous kernels were losing this
> space. We are now able to expand some packets without extra
> re-allocation/copy.
>
>> [It's always possible that I've unintentionally changed something in
>> the kernel configs that causes this, but I've tried to build the
>> kernels as identically as possible.]
>> 
>> The kernel module that's started failing fills the allocated sk_buff
>> until tailroom() indicates it is full and then sends it.  The problem
>> is that sending a packet with a length of 1850 won't work (it's a
>> MAC-layer Ethernet packet).
>
> This code seems buggy.

It is with today's alloc_skb().

At the time it was written (probably 10+ years ago) it was relying on
the documented API for alloc_skb() that stated alloc_skb() either
returned an sk_buff of the requested size or it failed.

>> I've found man pages for alloc_skb() from a few years ago that state
>> explicitly that alloc_skb(_size_) will allocate a new sk_buff with no
>> headroom and a tail room of _size_ bytes.  This doesn't seem to be the
>> case for recent kernels.  Is there any documentation stating what the
>> current behavior is supposed to be?
>> 
>> Are callers to alloc_skb() supposed to check the tailroom and
>> reserve() an appropriate number of bytes such that the tailroom is
>> correct?
>
> If you allocate skbs with 1500 bytes, you probably should check skb->len
> more than tailroom...

I can do that -- assuming it's backwards compatible with older kernels
as well (let's say as far back as 2.6 -- we stopped trying to support
2.4 kernels last year).

>> Is the tailroom of the allocated sk_buff guaranteed to be at least as
>> large as the requested size, or does application code also have to
>> check for tailroom less than the requested size?
>> 
>> The ultimate question I'm trying to answer is what is the "right" way
>> to allocate an sk_buff that has a size appropriate for an Ethernet
>> frame assuming an MTU of 1500?
>
> I dont know what to answer. Could you point the code in question?

Sure:

   alloc_skb(dev->hard_header_len + 1340)

The intent was to allocate a frame that we can guarantee we can send
out via the Ethernet device 'dev'.  Sometime 12-14 years ago, somebody
pulled the number "1340" out of the air under the assumption that the
resulting sk_buff would always be safely under the Ethernet limit of
1500 bytes.

That worked until kernel 3.2 came out, at which time we started ending
up with 1800 byte frames.

-- 
Grant Edwards               grant.b.edwards        Yow! I've read SEVEN
                                  at               MILLION books!!
                              gmail.com            

^ permalink raw reply

* Re: [PATCH v9] tilegx network driver: initial support
From: David Miller @ 2012-06-06 18:54 UTC (permalink / raw)
  To: cmetcalf; +Cc: eric.dumazet, bhutchings, arnd, linux-kernel, netdev
In-Reply-To: <4FCFA312.4020505@tilera.com>

From: Chris Metcalf <cmetcalf@tilera.com>
Date: Wed, 6 Jun 2012 14:36:02 -0400

> By the way, your question about tx_queue_len is a good one; I'm roping in
> our other network developer folks to figure it out.  Originally it was a
> performance optimization, I believe; I'm not sure it's still required. 

It's illegal, you cannot do this.

If you set the TX queue length to zero, amongst other very serious
and grave problems, your device cannot be used with the various
packet scheduler queueing disciplies.

Zero TX queue lengths should only be used for layering drivers which
are purely software entities rather than for real actual hardware.

As stated before, all of the areas where the tilegx driver tries to be
different end up being bugs.  It would therefore be nice, if, as I
suggested before, the driver is audited by you against a known
gold-standard Linux driver such as tg3 to spot inconsistencies like
this.

^ permalink raw reply

* Re: Change in alloc_skb() behavior in 3.2+ kernels?
From: David Miller @ 2012-06-06 18:51 UTC (permalink / raw)
  To: grant.b.edwards; +Cc: netdev
In-Reply-To: <jqo7op$t6f$1@dough.gmane.org>

From: Grant Edwards <grant.b.edwards@gmail.com>
Date: Wed, 6 Jun 2012 18:32:57 +0000 (UTC)

> The kernel module that's started failing fills the allocated sk_buff
> until tailroom() indicates it is full and then sends it.  The problem
> is that sending a packet with a length of 1850 won't work (it's a
> MAC-layer Ethernet packet).

The amount of tailroom an SKB has is implementation dependent.

It's incredibly poor form to rely upon it to determine whether a fully
sized frame has been constructed or not.

Please fix the code that does this.

^ permalink raw reply

* Re: [PATCH] virtio-net: fix a race on 32bit arches
From: Michael S. Tsirkin @ 2012-06-06 18:51 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: Eric Dumazet, netdev, linux-kernel, virtualization
In-Reply-To: <20120606081432.6b602065@nehalam.linuxnetplumber.net>

On Wed, Jun 06, 2012 at 08:14:32AM -0700, Stephen Hemminger wrote:
> On Wed, 6 Jun 2012 17:49:42 +0300
> "Michael S. Tsirkin" <mst@redhat.com> wrote:
> 
> > Sounds good, but I have a question: this realies on counters
> > being atomic on 64 bit.
> > Would not it be better to always use a seqlock even on 64 bit?
> > This way counters would actually be correct and in sync.
> > As it is if we want e.g. average packet size,
> > we can not rely e.g. on it being bytes/packets.
> 
> This has not been a requirement on real physical devices; therefore
> the added overhead is not really justified.
> 
> Many network cards use counters in hardware to count packets/bytes
> and there is no expectation of atomic access there.

BTW for cards that do implement the counters in software,
under xmit lock, is anything wrong with simply taking the xmit lock
when we get the stats instead of the per-cpu trick + seqlock?

^ permalink raw reply

* Re: Strange latency spikes/TX network stalls on Sun Fire X4150(x86) and e1000e
From: Stephen Hemminger @ 2012-06-06 18:46 UTC (permalink / raw)
  To: David Miller
  Cc: therbert, shimoda.hiroaki, jesse.brandeburg, eric.dumazet, denys,
	netdev, e1000-devel, jeffrey.t.kirsher
In-Reply-To: <20120606.112332.885204082939531665.davem@davemloft.net>

On Wed, 06 Jun 2012 11:23:32 -0700 (PDT)
David Miller <davem@davemloft.net> wrote:

> From: Tom Herbert <therbert@google.com>
> Date: Wed, 6 Jun 2012 11:21:40 -0700
> 
> > I'm not exactly sure what the exact effect of WTHRESH is here.  Does
> > the device coalesce 5 completions regardless of size?  Would the
> > problem be avoided if bql limit_min were MTU, or could same issue be
> > hit with larger that 64 byte packets?
> 
> The problem is that no TX completions are signalled happen until at
> least WTHRESH are pending.
> 
> BQL is the least of the problems generated by this kind of behavior.
> 
> All drivers must TX complete in a small, finite, amount of time so
> it is absolutely illegal to have the behavior that WRTHRESH > 1
> gives.

The TX completion is also controlled by the programming of the corresponding
interrupt moderation register (EITR).  It makes sense to hold off a little
bit to try and reduce the TX completion interrupt load. 

Intel manual..

Descriptors are written back in one of three cases:
• TXDCTL[n].WTHRESH = 0b and a descriptor which has RS set is ready to be written back
• The corresponding EITR counter has reached zero
• TXDCTL[n].WTHRESH > 0b and TXDCTL[n].WTHRESH descriptors have accumulated

For the first condition, write-backs are immediate. This is the default operation and is backward
compatible with previous device implementations.
The other two conditions are only valid if descriptor bursting is enabled (Section 8.12.13). In the
second condition, the EITR counter is used to force timely write-back of descriptors. The first packet
after timer initialization starts the timer. Timer expiration flushes any accumulated descriptors and sets
an interrupt event (TXDW).
For the final condition, if TXDCTL[n].WTHRESH descriptors are ready for write-back, the write-back is
performed.

^ permalink raw reply

* Remove out of date message in appletalk printk
From: Dave Jones @ 2012-06-06 18:45 UTC (permalink / raw)
  To: netdev; +Cc: acme

I accidentally triggered this printk, which amused me for a few moments.
Given we're post 2.2, we could just -EACCES, but does anyone even care about Appletalk now ?
I figure it's better to leave sleeping dogs lie, and just update the message.

Signed-off-by: Dave Jones <davej@redhat.com>

diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
index 0301b32..12e9100 100644
--- a/net/appletalk/ddp.c
+++ b/net/appletalk/ddp.c
@@ -1208,9 +1208,7 @@ static int atalk_connect(struct socket *sock, struct sockaddr *uaddr,
 	if (addr->sat_addr.s_node == ATADDR_BCAST &&
 	    !sock_flag(sk, SOCK_BROADCAST)) {
 #if 1
-		printk(KERN_WARNING "%s is broken and did not set "
-				    "SO_BROADCAST. It will break when 2.2 is "
-				    "released.\n",
+		printk(KERN_WARNING "%s is broken and did not set SO_BROADCAST.\n",
 			current->comm);
 #else
 		return -EACCES;

^ permalink raw reply related

* Re: [PATCH] virtio-net: fix a race on 32bit arches
From: Michael S. Tsirkin @ 2012-06-06 18:43 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: netdev, linux-kernel, virtualization, Stephen Hemminger
In-Reply-To: <1339002782.26966.22.camel@edumazet-glaptop>

On Wed, Jun 06, 2012 at 07:13:02PM +0200, Eric Dumazet wrote:
> On Wed, 2012-06-06 at 19:17 +0300, Michael S. Tsirkin wrote:
> 
> > But why do you say at most 1 packet?
> > 
> > Consider get_stats doing:
> >                u64_stats_update_begin(&stats->syncp);
> >                stats->tx_bytes += skb->len;
> > 
> > on 64 bit at this point
> > tx_packets might get incremented any number of times, no?
> > 
> >                 stats->tx_packets++;
> >                 u64_stats_update_end(&stats->syncp);
> > 
> > now tx_bytes and tx_packets are out of sync by more than 1.
> 
> You lost me there.
> 
> No idea of what you are thinking about.

Sorry about that. This is not a bug. I am saying two things:

1. We are trying to look at counters for purposes of tuning the device.
E.g. if ethtool reports packets and bytes, we'd like to calculate
average packet size by bytes/packets.

If both counters are read atomically the metric becomes more exact.
Not a must but nice to have.

2. 32 bit systems have some overhead because of the seqlock.
virtio could instead simply keep tx counters in the queue structure, and
get the tx lock when they are read.


-- 
MST

^ permalink raw reply

* Re: Change in alloc_skb() behavior in 3.2+ kernels?
From: Eric Dumazet @ 2012-06-06 18:42 UTC (permalink / raw)
  To: Grant Edwards; +Cc: netdev
In-Reply-To: <jqo7op$t6f$1@dough.gmane.org>

On Wed, 2012-06-06 at 18:32 +0000, Grant Edwards wrote:
> I'm tracking down a problem that appears to be caused by a change in
> the behavior of alloc_skb() introduced in kernel version 3.2.  In
> kernel versions prior to 3.2, calling alloc_skb(1350), returned an
> sk_buff with a tailroom of around 1400 bytes (safely below the default
> Ethernet frame size limit of 1500).
> 
> In 3.2 and later, calling alloc_skb(1350) returns an sk_buff with a
> tailroom of about 1850.
> 
> Why has the "extra" space increased from 60 bytes to 500 bytes?
> 

Because of kmalloc-2048 being used. Previous kernels were losing this
space. We are now able to expand some packets without extra
re-allocation/copy.

> [It's always possible that I've unintentionally changed something in
> the kernel configs that causes this, but I've tried to build the
> kernels as identically as possible.]
> 
> The kernel module that's started failing fills the allocated sk_buff
> until tailroom() indicates it is full and then sends it.  The problem
> is that sending a packet with a length of 1850 won't work (it's a
> MAC-layer Ethernet packet).

This code seems buggy.

> 
> I've found man pages for alloc_skb() from a few years ago that state
> explicitly that alloc_skb(_size_) will allocate a new sk_buff with no
> headroom and a tail room of _size_ bytes.  This doesn't seem to be the
> case for recent kernels.  Is there any documentation stating what the
> current behavior is supposed to be?
> 
> Are callers to alloc_skb() supposed to check the tailroom and
> reserve() an appropriate number of bytes such that the tailroom is
> correct?
> 

If you allocate skbs with 1500 bytes, you probably should check skb->len
more than tailroom...

> Is the tailroom of the allocated sk_buff guaranteed to be at least as
> large as the requested size, or does application code also have to
> check for tailroom less than the requested size?
> 
> The ultimate question I'm trying to answer is what is the "right" way
> to allocate an sk_buff that has a size appropriate for an Ethernet
> frame assuming an MTU of 1500?
> 

I dont know what to answer. Could you point the code in question ?

^ permalink raw reply

* pull request: wireless 2012-06-06
From: John W. Linville @ 2012-06-06 18:36 UTC (permalink / raw)
  To: davem; +Cc: linux-wireless, netdev, linux-kernel

Dave,

Here is a batch of wireless/bluetooth fixes intended for 3.5...

Amitkumar Karwar gives us a cfg80211 fix that changes some state
tracking in order to avoid a WARNING.

Arik Nemtsov provide a mac80211 fix for an RCU-related race.

Avinash Patil shares a pair of mwifiex fixes, one which invalidates
some stale configuration data before a channel change and another to
restrict hidden SSID support to zero-length SSIDs only.

Chun-Yeow Yeoh brings a mac80211 fix for a mesh problem triggered
when combining multiple mesh networks into one.

Felix Fietkau provides a mac80211 lockdep fix.

Joe Perches fixes a couple of thinkos related to bitwise operations.

Johannes Berg comes through with a flurry of fixes.  The iwlwifi ones
address a problem Linus recently reported, and some of the fallout
discovered while fixing it.  The mac80211 fix properly cleans-up
remain-on-channel work on an interface that is stopped.  The others
are clean-ups for regressions caused by stricter checking of possible
virtual interfaces supported by wireless drivers.

Meenakshi Venkataraman provides a mac80211 fix for an off-by-one error.

Seth Forshee provides a fix to make the wireless adapters used in
some Mac boxes work after being in S3 power saving state.

Stanislaw Gruszka offers a copule of fixes, a fix for a mac80211
scanning regression and an rt2x00 fix to avoid some lockdep spew.

Last but not least, Vinicius Costa Gomes provides a bluetooth fix
for a typo that "was preventing important features of Bluetooth
from working".

Please let me know if there are problems!

Thanks,

John

---

The following changes since commit dd03cff23d694cfb0fdae80cb618e7ced05ea696:

  net: sierra_net: device IDs for Aircard 320U++ (2012-06-06 10:40:32 -0700)

are available in the git repository at:
  git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless.git for-davem

Amitkumar Karwar (1):
      cfg80211: use sme_state in ibss start/join path

Arik Nemtsov (1):
      mac80211: fix non RCU-safe sta_list manipulation

Avinash Patil (2):
      mwifiex: invalidate bss config before setting channel for uAP
      mwifiex: support NL80211_HIDDEN_SSID_ZERO_LEN for uAP

Chun-Yeow Yeoh (1):
      mac80211: Fix Unreachable Mesh Station Problem when joining to another MBSS

Felix Fietkau (1):
      mac80211: add missing rcu_read_lock/unlock in agg-rx session timer

Joe Perches (2):
      mac80211: Fix likely misuse of | for &
      brcmfmac: Fix likely misuse of | for &

Johannes Berg (7):
      iwlwifi: fix TX power antenna access
      mac80211_hwsim: advertise interface combinations
      mac80211: clean up remain-on-channel on interface stop
      iwlwifi: disable WoWLAN if !CONFIG_PM_SLEEP
      iwlwifi: fix double free/complete in firmware loading
      iwlwifi: unregister LEDs if mac80211 registration fails
      cfg80211: fix interface combinations check

John W. Linville (2):
      Merge branch 'master' of git://git.kernel.org/.../bluetooth/bluetooth
      Merge branch 'master' of git://git.kernel.org/.../linville/wireless into for-davem

Meenakshi Venkataraman (1):
      mac80211: fix error in station state transitions during reconfig

Seth Forshee (1):
      bcma: add ext PA workaround for BCM4331 and BCM43431

Stanislaw Gruszka (2):
      mac80211: run scan after finish connection monitoring
      rt2x00: use atomic variable for seqno

Vinicius Costa Gomes (1):
      Bluetooth: Fix checking the wrong flag when accepting a socket

 drivers/bcma/driver_chipcommon_pmu.c             |    4 ++-
 drivers/bcma/sprom.c                             |    4 +-
 drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c |    4 +-
 drivers/net/wireless/iwlwifi/iwl-drv.c           |    9 ++++-
 drivers/net/wireless/iwlwifi/iwl-eeprom.c        |   18 +++++-----
 drivers/net/wireless/iwlwifi/iwl-mac80211.c      |    3 ++
 drivers/net/wireless/mac80211_hwsim.c            |   21 +++++++++++++
 drivers/net/wireless/mwifiex/cfg80211.c          |   13 ++++++++
 drivers/net/wireless/mwifiex/fw.h                |    6 ++++
 drivers/net/wireless/mwifiex/uap_cmd.c           |   10 ++++++
 drivers/net/wireless/rt2x00/rt2x00.h             |    3 +-
 drivers/net/wireless/rt2x00/rt2x00mac.c          |    1 -
 drivers/net/wireless/rt2x00/rt2x00queue.c        |   13 ++++----
 net/bluetooth/af_bluetooth.c                     |    2 +-
 net/mac80211/agg-rx.c                            |    7 ++++-
 net/mac80211/cfg.c                               |    6 ++--
 net/mac80211/iface.c                             |   12 +++++++
 net/mac80211/mlme.c                              |   36 ++++++++++++++++-----
 net/mac80211/offchannel.c                        |   16 ++++++++++
 net/mac80211/sta_info.c                          |    4 +-
 net/mac80211/tx.c                                |    9 ++++--
 net/mac80211/util.c                              |    2 +-
 net/wireless/ibss.c                              |    6 +++-
 net/wireless/util.c                              |   19 +++++++++++-
 24 files changed, 180 insertions(+), 48 deletions(-)

diff --git a/drivers/bcma/driver_chipcommon_pmu.c b/drivers/bcma/driver_chipcommon_pmu.c
index a058842..61ce405 100644
--- a/drivers/bcma/driver_chipcommon_pmu.c
+++ b/drivers/bcma/driver_chipcommon_pmu.c
@@ -139,7 +139,9 @@ void bcma_pmu_workarounds(struct bcma_drv_cc *cc)
 		bcma_chipco_chipctl_maskset(cc, 0, ~0, 0x7);
 		break;
 	case 0x4331:
-		/* BCM4331 workaround is SPROM-related, we put it in sprom.c */
+	case 43431:
+		/* Ext PA lines must be enabled for tx on BCM4331 */
+		bcma_chipco_bcm4331_ext_pa_lines_ctl(cc, true);
 		break;
 	case 43224:
 		if (bus->chipinfo.rev == 0) {
diff --git a/drivers/bcma/sprom.c b/drivers/bcma/sprom.c
index c7f9335..f16f42d 100644
--- a/drivers/bcma/sprom.c
+++ b/drivers/bcma/sprom.c
@@ -579,13 +579,13 @@ int bcma_sprom_get(struct bcma_bus *bus)
 	if (!sprom)
 		return -ENOMEM;
 
-	if (bus->chipinfo.id == 0x4331)
+	if (bus->chipinfo.id == 0x4331 || bus->chipinfo.id == 43431)
 		bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, false);
 
 	pr_debug("SPROM offset 0x%x\n", offset);
 	bcma_sprom_read(bus, offset, sprom);
 
-	if (bus->chipinfo.id == 0x4331)
+	if (bus->chipinfo.id == 0x4331 || bus->chipinfo.id == 43431)
 		bcma_chipco_bcm4331_ext_pa_lines_ctl(&bus->drv_cc, true);
 
 	err = bcma_sprom_valid(sprom);
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
index e2480d1..8e7e692 100644
--- a/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
+++ b/drivers/net/wireless/brcm80211/brcmfmac/bcmsdh.c
@@ -89,9 +89,9 @@ int brcmf_sdio_intr_register(struct brcmf_sdio_dev *sdiodev)
 	data |= 1 << SDIO_FUNC_1 | 1 << SDIO_FUNC_2 | 1;
 	brcmf_sdio_regwb(sdiodev, SDIO_CCCR_IENx, data, &ret);
 
-	/* redirect, configure ane enable io for interrupt signal */
+	/* redirect, configure and enable io for interrupt signal */
 	data = SDIO_SEPINT_MASK | SDIO_SEPINT_OE;
-	if (sdiodev->irq_flags | IRQF_TRIGGER_HIGH)
+	if (sdiodev->irq_flags & IRQF_TRIGGER_HIGH)
 		data |= SDIO_SEPINT_ACT_HI;
 	brcmf_sdio_regwb(sdiodev, SDIO_CCCR_BRCM_SEPINT, data, &ret);
 
diff --git a/drivers/net/wireless/iwlwifi/iwl-drv.c b/drivers/net/wireless/iwlwifi/iwl-drv.c
index d742900..fac67a5 100644
--- a/drivers/net/wireless/iwlwifi/iwl-drv.c
+++ b/drivers/net/wireless/iwlwifi/iwl-drv.c
@@ -861,13 +861,18 @@ static void iwl_ucode_callback(const struct firmware *ucode_raw, void *context)
 
 	/* We have our copies now, allow OS release its copies */
 	release_firmware(ucode_raw);
-	complete(&drv->request_firmware_complete);
 
 	drv->op_mode = iwl_dvm_ops.start(drv->trans, drv->cfg, &drv->fw);
 
 	if (!drv->op_mode)
-		goto out_free_fw;
+		goto out_unbind;
 
+	/*
+	 * Complete the firmware request last so that
+	 * a driver unbind (stop) doesn't run while we
+	 * are doing the start() above.
+	 */
+	complete(&drv->request_firmware_complete);
 	return;
 
  try_again:
diff --git a/drivers/net/wireless/iwlwifi/iwl-eeprom.c b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
index 50c5891..b8e2b22 100644
--- a/drivers/net/wireless/iwlwifi/iwl-eeprom.c
+++ b/drivers/net/wireless/iwlwifi/iwl-eeprom.c
@@ -568,28 +568,28 @@ static int iwl_find_otp_image(struct iwl_trans *trans,
  * iwl_get_max_txpower_avg - get the highest tx power from all chains.
  *     find the highest tx power from all chains for the channel
  */
-static s8 iwl_get_max_txpower_avg(const struct iwl_cfg *cfg,
+static s8 iwl_get_max_txpower_avg(struct iwl_priv *priv,
 		struct iwl_eeprom_enhanced_txpwr *enhanced_txpower,
 		int element, s8 *max_txpower_in_half_dbm)
 {
 	s8 max_txpower_avg = 0; /* (dBm) */
 
 	/* Take the highest tx power from any valid chains */
-	if ((cfg->valid_tx_ant & ANT_A) &&
+	if ((priv->hw_params.valid_tx_ant & ANT_A) &&
 	    (enhanced_txpower[element].chain_a_max > max_txpower_avg))
 		max_txpower_avg = enhanced_txpower[element].chain_a_max;
-	if ((cfg->valid_tx_ant & ANT_B) &&
+	if ((priv->hw_params.valid_tx_ant & ANT_B) &&
 	    (enhanced_txpower[element].chain_b_max > max_txpower_avg))
 		max_txpower_avg = enhanced_txpower[element].chain_b_max;
-	if ((cfg->valid_tx_ant & ANT_C) &&
+	if ((priv->hw_params.valid_tx_ant & ANT_C) &&
 	    (enhanced_txpower[element].chain_c_max > max_txpower_avg))
 		max_txpower_avg = enhanced_txpower[element].chain_c_max;
-	if (((cfg->valid_tx_ant == ANT_AB) |
-	    (cfg->valid_tx_ant == ANT_BC) |
-	    (cfg->valid_tx_ant == ANT_AC)) &&
+	if (((priv->hw_params.valid_tx_ant == ANT_AB) |
+	    (priv->hw_params.valid_tx_ant == ANT_BC) |
+	    (priv->hw_params.valid_tx_ant == ANT_AC)) &&
 	    (enhanced_txpower[element].mimo2_max > max_txpower_avg))
 		max_txpower_avg =  enhanced_txpower[element].mimo2_max;
-	if ((cfg->valid_tx_ant == ANT_ABC) &&
+	if ((priv->hw_params.valid_tx_ant == ANT_ABC) &&
 	    (enhanced_txpower[element].mimo3_max > max_txpower_avg))
 		max_txpower_avg = enhanced_txpower[element].mimo3_max;
 
@@ -691,7 +691,7 @@ static void iwl_eeprom_enhanced_txpower(struct iwl_priv *priv)
 				 ((txp->delta_20_in_40 & 0xf0) >> 4),
 				 (txp->delta_20_in_40 & 0x0f));
 
-		max_txp_avg = iwl_get_max_txpower_avg(priv->cfg, txp_array, idx,
+		max_txp_avg = iwl_get_max_txpower_avg(priv, txp_array, idx,
 						      &max_txp_avg_halfdbm);
 
 		/*
diff --git a/drivers/net/wireless/iwlwifi/iwl-mac80211.c b/drivers/net/wireless/iwlwifi/iwl-mac80211.c
index ab2f4d7..3ee23134 100644
--- a/drivers/net/wireless/iwlwifi/iwl-mac80211.c
+++ b/drivers/net/wireless/iwlwifi/iwl-mac80211.c
@@ -199,6 +199,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
 			    WIPHY_FLAG_DISABLE_BEACON_HINTS |
 			    WIPHY_FLAG_IBSS_RSN;
 
+#ifdef CONFIG_PM_SLEEP
 	if (priv->fw->img[IWL_UCODE_WOWLAN].sec[0].len &&
 	    priv->trans->ops->wowlan_suspend &&
 	    device_can_wakeup(priv->trans->dev)) {
@@ -217,6 +218,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
 		hw->wiphy->wowlan.pattern_max_len =
 					IWLAGN_WOWLAN_MAX_PATTERN_LEN;
 	}
+#endif
 
 	if (iwlwifi_mod_params.power_save)
 		hw->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
@@ -249,6 +251,7 @@ int iwlagn_mac_setup_register(struct iwl_priv *priv,
 	ret = ieee80211_register_hw(priv->hw);
 	if (ret) {
 		IWL_ERR(priv, "Failed to register hw (error %d)\n", ret);
+		iwl_leds_exit(priv);
 		return ret;
 	}
 	priv->mac80211_registered = 1;
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index fb787df..4c9336c 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -1721,6 +1721,24 @@ static void hwsim_exit_netlink(void)
 		       "unregister family %i\n", ret);
 }
 
+static const struct ieee80211_iface_limit hwsim_if_limits[] = {
+	{ .max = 1, .types = BIT(NL80211_IFTYPE_ADHOC) },
+	{ .max = 2048,  .types = BIT(NL80211_IFTYPE_STATION) |
+				 BIT(NL80211_IFTYPE_P2P_CLIENT) |
+#ifdef CONFIG_MAC80211_MESH
+				 BIT(NL80211_IFTYPE_MESH_POINT) |
+#endif
+				 BIT(NL80211_IFTYPE_AP) |
+				 BIT(NL80211_IFTYPE_P2P_GO) },
+};
+
+static const struct ieee80211_iface_combination hwsim_if_comb = {
+	.limits = hwsim_if_limits,
+	.n_limits = ARRAY_SIZE(hwsim_if_limits),
+	.max_interfaces = 2048,
+	.num_different_channels = 1,
+};
+
 static int __init init_mac80211_hwsim(void)
 {
 	int i, err = 0;
@@ -1782,6 +1800,9 @@ static int __init init_mac80211_hwsim(void)
 		hw->wiphy->n_addresses = 2;
 		hw->wiphy->addresses = data->addresses;
 
+		hw->wiphy->iface_combinations = &hwsim_if_comb;
+		hw->wiphy->n_iface_combinations = 1;
+
 		if (fake_hw_scan) {
 			hw->wiphy->max_scan_ssids = 255;
 			hw->wiphy->max_scan_ie_len = IEEE80211_MAX_DATA_LEN;
diff --git a/drivers/net/wireless/mwifiex/cfg80211.c b/drivers/net/wireless/mwifiex/cfg80211.c
index 8767144..015fec3 100644
--- a/drivers/net/wireless/mwifiex/cfg80211.c
+++ b/drivers/net/wireless/mwifiex/cfg80211.c
@@ -948,6 +948,19 @@ static int mwifiex_cfg80211_start_ap(struct wiphy *wiphy,
 		bss_cfg->ssid.ssid_len = params->ssid_len;
 	}
 
+	switch (params->hidden_ssid) {
+	case NL80211_HIDDEN_SSID_NOT_IN_USE:
+		bss_cfg->bcast_ssid_ctl = 1;
+		break;
+	case NL80211_HIDDEN_SSID_ZERO_LEN:
+		bss_cfg->bcast_ssid_ctl = 0;
+		break;
+	case NL80211_HIDDEN_SSID_ZERO_CONTENTS:
+		/* firmware doesn't support this type of hidden SSID */
+	default:
+		return -EINVAL;
+	}
+
 	if (mwifiex_set_secure_params(priv, bss_cfg, params)) {
 		kfree(bss_cfg);
 		wiphy_err(wiphy, "Failed to parse secuirty parameters!\n");
diff --git a/drivers/net/wireless/mwifiex/fw.h b/drivers/net/wireless/mwifiex/fw.h
index 9f674bb..561452a 100644
--- a/drivers/net/wireless/mwifiex/fw.h
+++ b/drivers/net/wireless/mwifiex/fw.h
@@ -122,6 +122,7 @@ enum MWIFIEX_802_11_PRIVACY_FILTER {
 #define TLV_TYPE_CHANNELBANDLIST    (PROPRIETARY_TLV_BASE_ID + 42)
 #define TLV_TYPE_UAP_BEACON_PERIOD  (PROPRIETARY_TLV_BASE_ID + 44)
 #define TLV_TYPE_UAP_DTIM_PERIOD    (PROPRIETARY_TLV_BASE_ID + 45)
+#define TLV_TYPE_UAP_BCAST_SSID     (PROPRIETARY_TLV_BASE_ID + 48)
 #define TLV_TYPE_UAP_RTS_THRESHOLD  (PROPRIETARY_TLV_BASE_ID + 51)
 #define TLV_TYPE_UAP_WPA_PASSPHRASE (PROPRIETARY_TLV_BASE_ID + 60)
 #define TLV_TYPE_UAP_ENCRY_PROTOCOL (PROPRIETARY_TLV_BASE_ID + 64)
@@ -1209,6 +1210,11 @@ struct host_cmd_tlv_ssid {
 	u8 ssid[0];
 } __packed;
 
+struct host_cmd_tlv_bcast_ssid {
+	struct host_cmd_tlv tlv;
+	u8 bcast_ctl;
+} __packed;
+
 struct host_cmd_tlv_beacon_period {
 	struct host_cmd_tlv tlv;
 	__le16 period;
diff --git a/drivers/net/wireless/mwifiex/uap_cmd.c b/drivers/net/wireless/mwifiex/uap_cmd.c
index 76dfbc4..8173ab6 100644
--- a/drivers/net/wireless/mwifiex/uap_cmd.c
+++ b/drivers/net/wireless/mwifiex/uap_cmd.c
@@ -132,6 +132,7 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
 	struct host_cmd_tlv_dtim_period *dtim_period;
 	struct host_cmd_tlv_beacon_period *beacon_period;
 	struct host_cmd_tlv_ssid *ssid;
+	struct host_cmd_tlv_bcast_ssid *bcast_ssid;
 	struct host_cmd_tlv_channel_band *chan_band;
 	struct host_cmd_tlv_frag_threshold *frag_threshold;
 	struct host_cmd_tlv_rts_threshold *rts_threshold;
@@ -153,6 +154,14 @@ mwifiex_uap_bss_param_prepare(u8 *tlv, void *cmd_buf, u16 *param_size)
 		cmd_size += sizeof(struct host_cmd_tlv) +
 			    bss_cfg->ssid.ssid_len;
 		tlv += sizeof(struct host_cmd_tlv) + bss_cfg->ssid.ssid_len;
+
+		bcast_ssid = (struct host_cmd_tlv_bcast_ssid *)tlv;
+		bcast_ssid->tlv.type = cpu_to_le16(TLV_TYPE_UAP_BCAST_SSID);
+		bcast_ssid->tlv.len =
+				cpu_to_le16(sizeof(bcast_ssid->bcast_ctl));
+		bcast_ssid->bcast_ctl = bss_cfg->bcast_ssid_ctl;
+		cmd_size += sizeof(struct host_cmd_tlv_bcast_ssid);
+		tlv += sizeof(struct host_cmd_tlv_bcast_ssid);
 	}
 	if (bss_cfg->channel && bss_cfg->channel <= MAX_CHANNEL_BAND_BG) {
 		chan_band = (struct host_cmd_tlv_channel_band *)tlv;
@@ -416,6 +425,7 @@ int mwifiex_uap_set_channel(struct mwifiex_private *priv, int channel)
 	if (!bss_cfg)
 		return -ENOMEM;
 
+	mwifiex_set_sys_config_invalid_data(bss_cfg);
 	bss_cfg->band_cfg = BAND_CONFIG_MANUAL;
 	bss_cfg->channel = channel;
 
diff --git a/drivers/net/wireless/rt2x00/rt2x00.h b/drivers/net/wireless/rt2x00/rt2x00.h
index ca36ccc..8f75402 100644
--- a/drivers/net/wireless/rt2x00/rt2x00.h
+++ b/drivers/net/wireless/rt2x00/rt2x00.h
@@ -396,8 +396,7 @@ struct rt2x00_intf {
 	 * for hardware which doesn't support hardware
 	 * sequence counting.
 	 */
-	spinlock_t seqlock;
-	u16 seqno;
+	atomic_t seqno;
 };
 
 static inline struct rt2x00_intf* vif_to_intf(struct ieee80211_vif *vif)
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c
index b49773e..dd24b26 100644
--- a/drivers/net/wireless/rt2x00/rt2x00mac.c
+++ b/drivers/net/wireless/rt2x00/rt2x00mac.c
@@ -277,7 +277,6 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw,
 	else
 		rt2x00dev->intf_sta_count++;
 
-	spin_lock_init(&intf->seqlock);
 	mutex_init(&intf->beacon_skb_mutex);
 	intf->beacon = entry;
 
diff --git a/drivers/net/wireless/rt2x00/rt2x00queue.c b/drivers/net/wireless/rt2x00/rt2x00queue.c
index 4c662ec..2fd8301 100644
--- a/drivers/net/wireless/rt2x00/rt2x00queue.c
+++ b/drivers/net/wireless/rt2x00/rt2x00queue.c
@@ -207,6 +207,7 @@ static void rt2x00queue_create_tx_descriptor_seq(struct rt2x00_dev *rt2x00dev,
 	struct ieee80211_tx_info *tx_info = IEEE80211_SKB_CB(skb);
 	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
 	struct rt2x00_intf *intf = vif_to_intf(tx_info->control.vif);
+	u16 seqno;
 
 	if (!(tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ))
 		return;
@@ -238,15 +239,13 @@ static void rt2x00queue_create_tx_descriptor_seq(struct rt2x00_dev *rt2x00dev,
 	 * sequence counting per-frame, since those will override the
 	 * sequence counter given by mac80211.
 	 */
-	spin_lock(&intf->seqlock);
-
 	if (test_bit(ENTRY_TXD_FIRST_FRAGMENT, &txdesc->flags))
-		intf->seqno += 0x10;
-	hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
-	hdr->seq_ctrl |= cpu_to_le16(intf->seqno);
-
-	spin_unlock(&intf->seqlock);
+		seqno = atomic_add_return(0x10, &intf->seqno);
+	else
+		seqno = atomic_read(&intf->seqno);
 
+	hdr->seq_ctrl &= cpu_to_le16(IEEE80211_SCTL_FRAG);
+	hdr->seq_ctrl |= cpu_to_le16(seqno);
 }
 
 static void rt2x00queue_create_tx_descriptor_plcp(struct rt2x00_dev *rt2x00dev,
diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index 46e7f86..3e18af4 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -210,7 +210,7 @@ struct sock *bt_accept_dequeue(struct sock *parent, struct socket *newsock)
 		}
 
 		if (sk->sk_state == BT_CONNECTED || !newsock ||
-		    test_bit(BT_DEFER_SETUP, &bt_sk(parent)->flags)) {
+		    test_bit(BT_SK_DEFER_SETUP, &bt_sk(parent)->flags)) {
 			bt_accept_unlink(sk);
 			if (newsock)
 				sock_graft(sk, newsock);
diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index 26ddb69..c649188 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -145,15 +145,20 @@ static void sta_rx_agg_session_timer_expired(unsigned long data)
 	struct tid_ampdu_rx *tid_rx;
 	unsigned long timeout;
 
+	rcu_read_lock();
 	tid_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[*ptid]);
-	if (!tid_rx)
+	if (!tid_rx) {
+		rcu_read_unlock();
 		return;
+	}
 
 	timeout = tid_rx->last_rx + TU_TO_JIFFIES(tid_rx->timeout);
 	if (time_is_after_jiffies(timeout)) {
 		mod_timer(&tid_rx->session_timer, timeout);
+		rcu_read_unlock();
 		return;
 	}
+	rcu_read_unlock();
 
 #ifdef CONFIG_MAC80211_HT_DEBUG
 	printk(KERN_DEBUG "rx session timer expired on tid %d\n", (u16)*ptid);
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 495831e..e9cecca 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -533,16 +533,16 @@ static void ieee80211_get_et_stats(struct wiphy *wiphy,
 		sinfo.filled = 0;
 		sta_set_sinfo(sta, &sinfo);
 
-		if (sinfo.filled | STATION_INFO_TX_BITRATE)
+		if (sinfo.filled & STATION_INFO_TX_BITRATE)
 			data[i] = 100000 *
 				cfg80211_calculate_bitrate(&sinfo.txrate);
 		i++;
-		if (sinfo.filled | STATION_INFO_RX_BITRATE)
+		if (sinfo.filled & STATION_INFO_RX_BITRATE)
 			data[i] = 100000 *
 				cfg80211_calculate_bitrate(&sinfo.rxrate);
 		i++;
 
-		if (sinfo.filled | STATION_INFO_SIGNAL_AVG)
+		if (sinfo.filled & STATION_INFO_SIGNAL_AVG)
 			data[i] = (u8)sinfo.signal_avg;
 		i++;
 	} else {
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index d4c19a7..8664111 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -637,6 +637,18 @@ static void ieee80211_do_stop(struct ieee80211_sub_if_data *sdata,
 		ieee80211_configure_filter(local);
 		break;
 	default:
+		mutex_lock(&local->mtx);
+		if (local->hw_roc_dev == sdata->dev &&
+		    local->hw_roc_channel) {
+			/* ignore return value since this is racy */
+			drv_cancel_remain_on_channel(local);
+			ieee80211_queue_work(&local->hw, &local->hw_roc_done);
+		}
+		mutex_unlock(&local->mtx);
+
+		flush_work(&local->hw_roc_start);
+		flush_work(&local->hw_roc_done);
+
 		flush_work(&sdata->work);
 		/*
 		 * When we get here, the interface is marked down.
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 04c3063..d94627c 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -1220,6 +1220,22 @@ static void ieee80211_sta_wmm_params(struct ieee80211_local *local,
 	sdata->vif.bss_conf.qos = true;
 }
 
+static void __ieee80211_stop_poll(struct ieee80211_sub_if_data *sdata)
+{
+	lockdep_assert_held(&sdata->local->mtx);
+
+	sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL |
+				IEEE80211_STA_BEACON_POLL);
+	ieee80211_run_deferred_scan(sdata->local);
+}
+
+static void ieee80211_stop_poll(struct ieee80211_sub_if_data *sdata)
+{
+	mutex_lock(&sdata->local->mtx);
+	__ieee80211_stop_poll(sdata);
+	mutex_unlock(&sdata->local->mtx);
+}
+
 static u32 ieee80211_handle_bss_capability(struct ieee80211_sub_if_data *sdata,
 					   u16 capab, bool erp_valid, u8 erp)
 {
@@ -1285,8 +1301,7 @@ static void ieee80211_set_associated(struct ieee80211_sub_if_data *sdata,
 	sdata->u.mgd.flags |= IEEE80211_STA_RESET_SIGNAL_AVE;
 
 	/* just to be sure */
-	sdata->u.mgd.flags &= ~(IEEE80211_STA_CONNECTION_POLL |
-				IEEE80211_STA_BEACON_POLL);
+	ieee80211_stop_poll(sdata);
 
 	ieee80211_led_assoc(local, 1);
 
@@ -1456,8 +1471,7 @@ static void ieee80211_reset_ap_probe(struct ieee80211_sub_if_data *sdata)
 		return;
 	}
 
-	ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL |
-			  IEEE80211_STA_BEACON_POLL);
+	__ieee80211_stop_poll(sdata);
 
 	mutex_lock(&local->iflist_mtx);
 	ieee80211_recalc_ps(local, -1);
@@ -1477,7 +1491,6 @@ static void ieee80211_reset_ap_probe(struct ieee80211_sub_if_data *sdata)
 		  round_jiffies_up(jiffies +
 				   IEEE80211_CONNECTION_IDLE_TIME));
 out:
-	ieee80211_run_deferred_scan(local);
 	mutex_unlock(&local->mtx);
 }
 
@@ -2408,7 +2421,11 @@ static void ieee80211_rx_mgmt_beacon(struct ieee80211_sub_if_data *sdata,
 		net_dbg_ratelimited("%s: cancelling probereq poll due to a received beacon\n",
 				    sdata->name);
 #endif
+		mutex_lock(&local->mtx);
 		ifmgd->flags &= ~IEEE80211_STA_BEACON_POLL;
+		ieee80211_run_deferred_scan(local);
+		mutex_unlock(&local->mtx);
+
 		mutex_lock(&local->iflist_mtx);
 		ieee80211_recalc_ps(local, -1);
 		mutex_unlock(&local->iflist_mtx);
@@ -2595,8 +2612,7 @@ static void ieee80211_sta_connection_lost(struct ieee80211_sub_if_data *sdata,
 	struct ieee80211_if_managed *ifmgd = &sdata->u.mgd;
 	u8 frame_buf[DEAUTH_DISASSOC_LEN];
 
-	ifmgd->flags &= ~(IEEE80211_STA_CONNECTION_POLL |
-			  IEEE80211_STA_BEACON_POLL);
+	ieee80211_stop_poll(sdata);
 
 	ieee80211_set_disassoc(sdata, IEEE80211_STYPE_DEAUTH, reason,
 			       false, frame_buf);
@@ -2874,8 +2890,7 @@ static void ieee80211_restart_sta_timer(struct ieee80211_sub_if_data *sdata)
 	u32 flags;
 
 	if (sdata->vif.type == NL80211_IFTYPE_STATION) {
-		sdata->u.mgd.flags &= ~(IEEE80211_STA_BEACON_POLL |
-					IEEE80211_STA_CONNECTION_POLL);
+		__ieee80211_stop_poll(sdata);
 
 		/* let's probe the connection once */
 		flags = sdata->local->hw.flags;
@@ -2944,7 +2959,10 @@ void ieee80211_sta_restart(struct ieee80211_sub_if_data *sdata)
 	if (test_and_clear_bit(TMR_RUNNING_CHANSW, &ifmgd->timers_running))
 		add_timer(&ifmgd->chswitch_timer);
 	ieee80211_sta_reset_beacon_monitor(sdata);
+
+	mutex_lock(&sdata->local->mtx);
 	ieee80211_restart_sta_timer(sdata);
+	mutex_unlock(&sdata->local->mtx);
 }
 #endif
 
diff --git a/net/mac80211/offchannel.c b/net/mac80211/offchannel.c
index f054e94..935aa4b 100644
--- a/net/mac80211/offchannel.c
+++ b/net/mac80211/offchannel.c
@@ -234,6 +234,22 @@ static void ieee80211_hw_roc_done(struct work_struct *work)
 		return;
 	}
 
+	/* was never transmitted */
+	if (local->hw_roc_skb) {
+		u64 cookie;
+
+		cookie = local->hw_roc_cookie ^ 2;
+
+		cfg80211_mgmt_tx_status(local->hw_roc_dev, cookie,
+					local->hw_roc_skb->data,
+					local->hw_roc_skb->len, false,
+					GFP_KERNEL);
+
+		kfree_skb(local->hw_roc_skb);
+		local->hw_roc_skb = NULL;
+		local->hw_roc_skb_for_status = NULL;
+	}
+
 	if (!local->hw_roc_for_tx)
 		cfg80211_remain_on_channel_expired(local->hw_roc_dev,
 						   local->hw_roc_cookie,
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index f5b1638..de455f8 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -378,7 +378,7 @@ static int sta_info_insert_finish(struct sta_info *sta) __acquires(RCU)
 	/* make the station visible */
 	sta_info_hash_add(local, sta);
 
-	list_add(&sta->list, &local->sta_list);
+	list_add_rcu(&sta->list, &local->sta_list);
 
 	set_sta_flag(sta, WLAN_STA_INSERTED);
 
@@ -688,7 +688,7 @@ int __must_check __sta_info_destroy(struct sta_info *sta)
 	if (ret)
 		return ret;
 
-	list_del(&sta->list);
+	list_del_rcu(&sta->list);
 
 	mutex_lock(&local->key_mtx);
 	for (i = 0; i < NUM_DEFAULT_KEYS; i++)
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index 847215b..e453212 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1737,7 +1737,7 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
 	__le16 fc;
 	struct ieee80211_hdr hdr;
 	struct ieee80211s_hdr mesh_hdr __maybe_unused;
-	struct mesh_path __maybe_unused *mppath = NULL;
+	struct mesh_path __maybe_unused *mppath = NULL, *mpath = NULL;
 	const u8 *encaps_data;
 	int encaps_len, skip_header_bytes;
 	int nh_pos, h_pos;
@@ -1803,8 +1803,11 @@ netdev_tx_t ieee80211_subif_start_xmit(struct sk_buff *skb,
 			goto fail;
 		}
 		rcu_read_lock();
-		if (!is_multicast_ether_addr(skb->data))
-			mppath = mpp_path_lookup(skb->data, sdata);
+		if (!is_multicast_ether_addr(skb->data)) {
+			mpath = mesh_path_lookup(skb->data, sdata);
+			if (!mpath)
+				mppath = mpp_path_lookup(skb->data, sdata);
+		}
 
 		/*
 		 * Use address extension if it is a packet from
diff --git a/net/mac80211/util.c b/net/mac80211/util.c
index a44c680..8dd4712 100644
--- a/net/mac80211/util.c
+++ b/net/mac80211/util.c
@@ -1271,7 +1271,7 @@ int ieee80211_reconfig(struct ieee80211_local *local)
 			enum ieee80211_sta_state state;
 
 			for (state = IEEE80211_STA_NOTEXIST;
-			     state < sta->sta_state - 1; state++)
+			     state < sta->sta_state; state++)
 				WARN_ON(drv_sta_state(local, sta->sdata, sta,
 						      state, state + 1));
 		}
diff --git a/net/wireless/ibss.c b/net/wireless/ibss.c
index d2a19b0..89baa33 100644
--- a/net/wireless/ibss.c
+++ b/net/wireless/ibss.c
@@ -42,6 +42,7 @@ void __cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid)
 	cfg80211_hold_bss(bss_from_pub(bss));
 	wdev->current_bss = bss_from_pub(bss);
 
+	wdev->sme_state = CFG80211_SME_CONNECTED;
 	cfg80211_upload_connect_keys(wdev);
 
 	nl80211_send_ibss_bssid(wiphy_to_dev(wdev->wiphy), dev, bssid,
@@ -60,7 +61,7 @@ void cfg80211_ibss_joined(struct net_device *dev, const u8 *bssid, gfp_t gfp)
 	struct cfg80211_event *ev;
 	unsigned long flags;
 
-	CFG80211_DEV_WARN_ON(!wdev->ssid_len);
+	CFG80211_DEV_WARN_ON(wdev->sme_state != CFG80211_SME_CONNECTING);
 
 	ev = kzalloc(sizeof(*ev), gfp);
 	if (!ev)
@@ -115,9 +116,11 @@ int __cfg80211_join_ibss(struct cfg80211_registered_device *rdev,
 #ifdef CONFIG_CFG80211_WEXT
 	wdev->wext.ibss.channel = params->channel;
 #endif
+	wdev->sme_state = CFG80211_SME_CONNECTING;
 	err = rdev->ops->join_ibss(&rdev->wiphy, dev, params);
 	if (err) {
 		wdev->connect_keys = NULL;
+		wdev->sme_state = CFG80211_SME_IDLE;
 		return err;
 	}
 
@@ -169,6 +172,7 @@ static void __cfg80211_clear_ibss(struct net_device *dev, bool nowext)
 	}
 
 	wdev->current_bss = NULL;
+	wdev->sme_state = CFG80211_SME_IDLE;
 	wdev->ssid_len = 0;
 #ifdef CONFIG_CFG80211_WEXT
 	if (!nowext)
diff --git a/net/wireless/util.c b/net/wireless/util.c
index 55d9946..8f2d68f 100644
--- a/net/wireless/util.c
+++ b/net/wireless/util.c
@@ -935,6 +935,7 @@ int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev,
 				  enum nl80211_iftype iftype)
 {
 	struct wireless_dev *wdev_iter;
+	u32 used_iftypes = BIT(iftype);
 	int num[NUM_NL80211_IFTYPES];
 	int total = 1;
 	int i, j;
@@ -961,6 +962,7 @@ int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev,
 
 		num[wdev_iter->iftype]++;
 		total++;
+		used_iftypes |= BIT(wdev_iter->iftype);
 	}
 	mutex_unlock(&rdev->devlist_mtx);
 
@@ -970,6 +972,7 @@ int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev,
 	for (i = 0; i < rdev->wiphy.n_iface_combinations; i++) {
 		const struct ieee80211_iface_combination *c;
 		struct ieee80211_iface_limit *limits;
+		u32 all_iftypes = 0;
 
 		c = &rdev->wiphy.iface_combinations[i];
 
@@ -984,6 +987,7 @@ int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev,
 			if (rdev->wiphy.software_iftypes & BIT(iftype))
 				continue;
 			for (j = 0; j < c->n_limits; j++) {
+				all_iftypes |= limits[j].types;
 				if (!(limits[j].types & BIT(iftype)))
 					continue;
 				if (limits[j].max < num[iftype])
@@ -991,7 +995,20 @@ int cfg80211_can_change_interface(struct cfg80211_registered_device *rdev,
 				limits[j].max -= num[iftype];
 			}
 		}
-		/* yay, it fits */
+
+		/*
+		 * Finally check that all iftypes that we're currently
+		 * using are actually part of this combination. If they
+		 * aren't then we can't use this combination and have
+		 * to continue to the next.
+		 */
+		if ((all_iftypes & used_iftypes) != used_iftypes)
+			goto cont;
+
+		/*
+		 * This combination covered all interface types and
+		 * supported the requested numbers, so we're good.
+		 */
 		kfree(limits);
 		return 0;
  cont:
-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

^ permalink raw reply related

* Re: [PATCH v9] tilegx network driver: initial support
From: Chris Metcalf @ 2012-06-06 18:36 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: bhutchings, arnd, David Miller, linux-kernel, netdev
In-Reply-To: <1339004459.26966.31.camel@edumazet-glaptop>

On 6/6/2012 1:40 PM, Eric Dumazet wrote:
> On Mon, 2012-06-04 at 16:12 -0400, Chris Metcalf wrote:
>
>> +/* Allocate and push a buffer. */
>> +static bool tile_net_provide_buffer(bool small)
>> +{
>> +	int stack = small ? small_buffer_stack : large_buffer_stack;
>> +	const unsigned long buffer_alignment = 128;
>> +	struct sk_buff *skb;
>> +	int len;
>> +
>> +	len = sizeof(struct sk_buff **) + buffer_alignment;
>> +	len += (small ? 128 : 1664);
> 1664 is a magic number, it should be a nice define
>
> #define ..... ( ETH_DATA_LEN + .... )

Fair enough.  However, the magic-ness comes from the hardware header code
in arch/tile/gxio/mpipe.h, which provides a limited set of allowed buffer
sizes, including 1664.  But I can add these #defines at the top of this driver:

/* Buffer sizes and mpipe enum codes for buffer stacks.
 * See arch/tile/include/gxio/mpipe.h for the set of possible values.
 */
#define BUFFER_SIZE_SMALL_ENUM GXIO_MPIPE_BUFFER_SIZE_128
#define BUFFER_SIZE_SMALL 128
#define BUFFER_SIZE_LARGE_ENUM GXIO_MPIPE_BUFFER_SIZE_1664
#define BUFFER_SIZE_LARGE 1664


>> +	skb = dev_alloc_skb(len);
>> +	if (skb == NULL)
>> +		return false;
>> +
>> +	/* Make room for a back-pointer to 'skb' and guarantee alignment. */
>> +	skb_reserve(skb, sizeof(struct sk_buff **));
>> +	skb_reserve(skb, -(long)skb->data & (buffer_alignment - 1));
>> +
>> +	/* Save a back-pointer to 'skb'. */
>> +	*(struct sk_buff **)(skb->data - sizeof(struct sk_buff **)) = skb;
>> +
>> +	/* Make sure "skb" and the back-pointer have been flushed. */
>> +	wmb();
> Interesting, have you considered using build_skb() instead of this
> convoluted thing ?
>
> This could save some cache misses...

I hadn't looked at build_skb() before; we built up this driver mostly on a
base of 2.6.38, where it doesn't exist.  That said, it doesn't seem like it
matters; dev_alloc_skb() will just end up calling down to build_skb()
anyway, as far as I can tell.

The code where we do the two skb_reserves and then stuff in a backpointer
and do a barrier are because we track the skbuffs in hardware, and hardware
ignores the low 7 bits aof the address (thus the "buffer_alignment" part)
and we need to be able to pull the actual skb address out of the data when
the hardware returns a pointer to the data to us.

By the way, your question about tx_queue_len is a good one; I'm roping in
our other network developer folks to figure it out.  Originally it was a
performance optimization, I believe; I'm not sure it's still required. 
I'll follow up on that one when we've tracked it down.

-- 
Chris Metcalf, Tilera Corp.
http://www.tilera.com

^ permalink raw reply

* Re: [PATCH net-next 2/3] qlcnic: fix unsupported CDRP command error message.
From: Anirban Chakraborty @ 2012-06-06 18:35 UTC (permalink / raw)
  To: Joe Perches
  Cc: David Miller, netdev, Dept-NX Linux NIC Driver, Jitendra Kalsaria
In-Reply-To: <1339006447.13710.6.camel@joe2Laptop>



On 6/6/12 11:14 AM, "Joe Perches" <joe@perches.com> wrote:

>On Wed, 2012-06-06 at 13:35 -0400, Anirban Chakraborty wrote:
>> From: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>
>> 
>> Add debug messages for FW CDRP command failure.
>
>trivia:
>
>Please be consistent with the use of (preferably _no_) periods
>at the end of logging messages.
>
>$ git grep -E "[^\.]\\\\n\"" drivers/net/ethernet/qlogic/qlcnic/ | wc -l
>187
>$ git grep -E "\.\\\\n\"" drivers/net/ethernet/qlogic/qlcnic/ | wc -l
>22
>
>[]
>> diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c
>>b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c
>[]
>> @@ -53,12 +53,39 @@ qlcnic_issue_cmd(struct qlcnic_adapter *adapter,
>>struct qlcnic_cmd_args *cmd)
>>  	rsp = qlcnic_poll_rsp(adapter);
>>  
>>  	if (rsp == QLCNIC_CDRP_RSP_TIMEOUT) {
>> -		dev_err(&pdev->dev, "card response timeout.\n");
>> +		dev_err(&pdev->dev, "CDRP response timeout.\n");
>
>ie: no period necessary.

Thanks for pointing it out. We will not add that period in commit messages
from next time on.

>
>CDRP is kind of an odd acronym.
>Is it for CarD ResPonse?

It stands for FW CommanD ResPonse.

>
>If it is, then I think a lot of the below messages are
>not particularly sensible and the CDRP should be dropped.

Having CDRRP in the message string helps us identify the source of error.
This works well for us in debugging issues.

-Anirban

^ permalink raw reply

* Change in alloc_skb() behavior in 3.2+ kernels?
From: Grant Edwards @ 2012-06-06 18:32 UTC (permalink / raw)
  To: netdev

I'm tracking down a problem that appears to be caused by a change in
the behavior of alloc_skb() introduced in kernel version 3.2.  In
kernel versions prior to 3.2, calling alloc_skb(1350), returned an
sk_buff with a tailroom of around 1400 bytes (safely below the default
Ethernet frame size limit of 1500).

In 3.2 and later, calling alloc_skb(1350) returns an sk_buff with a
tailroom of about 1850.

Why has the "extra" space increased from 60 bytes to 500 bytes?

[It's always possible that I've unintentionally changed something in
the kernel configs that causes this, but I've tried to build the
kernels as identically as possible.]

The kernel module that's started failing fills the allocated sk_buff
until tailroom() indicates it is full and then sends it.  The problem
is that sending a packet with a length of 1850 won't work (it's a
MAC-layer Ethernet packet).

I've found man pages for alloc_skb() from a few years ago that state
explicitly that alloc_skb(_size_) will allocate a new sk_buff with no
headroom and a tail room of _size_ bytes.  This doesn't seem to be the
case for recent kernels.  Is there any documentation stating what the
current behavior is supposed to be?

Are callers to alloc_skb() supposed to check the tailroom and
reserve() an appropriate number of bytes such that the tailroom is
correct?

Is the tailroom of the allocated sk_buff guaranteed to be at least as
large as the requested size, or does application code also have to
check for tailroom less than the requested size?

The ultimate question I'm trying to answer is what is the "right" way
to allocate an sk_buff that has a size appropriate for an Ethernet
frame assuming an MTU of 1500?

-- 
Grant Edwards               grant.b.edwards        Yow! Let's send the
                                  at               Russians defective
                              gmail.com            lifestyle accessories!

^ permalink raw reply

* Re: Strange latency spikes/TX network stalls on Sun Fire X4150(x86) and e1000e
From: David Miller @ 2012-06-06 18:23 UTC (permalink / raw)
  To: therbert
  Cc: shimoda.hiroaki, jesse.brandeburg, eric.dumazet, denys, netdev,
	e1000-devel, jeffrey.t.kirsher
In-Reply-To: <CA+mtBx-o4WB5gmHRMTQ6+haNrbeJyaaX9zXPhhYZydZbSPO98w@mail.gmail.com>

From: Tom Herbert <therbert@google.com>
Date: Wed, 6 Jun 2012 11:21:40 -0700

> I'm not exactly sure what the exact effect of WTHRESH is here.  Does
> the device coalesce 5 completions regardless of size?  Would the
> problem be avoided if bql limit_min were MTU, or could same issue be
> hit with larger that 64 byte packets?

The problem is that no TX completions are signalled happen until at
least WTHRESH are pending.

BQL is the least of the problems generated by this kind of behavior.

All drivers must TX complete in a small, finite, amount of time so
it is absolutely illegal to have the behavior that WRTHRESH > 1
gives.

^ permalink raw reply

* Re: Strange latency spikes/TX network stalls on Sun Fire X4150(x86) and e1000e
From: Tom Herbert @ 2012-06-06 18:21 UTC (permalink / raw)
  To: Hiroaki SHIMODA
  Cc: Denys Fedoryshchenko, e1000-devel, netdev, Jesse Brandeburg,
	davem
In-Reply-To: <20120607021937.a5638bfd.shimoda.hiroaki@gmail.com>

I'm not exactly sure what the exact effect of WTHRESH is here.  Does
the device coalesce 5 completions regardless of size?  Would the
problem be avoided if bql limit_min were MTU, or could same issue be
hit with larger that 64 byte packets?

Tom

On Wed, Jun 6, 2012 at 10:19 AM, Hiroaki SHIMODA
<shimoda.hiroaki@gmail.com> wrote:
> On Wed, 6 Jun 2012 09:26:35 -0700
> Jesse Brandeburg <jesse.brandeburg@intel.com> wrote:
>
>> On Wed, 6 Jun 2012 Hiroaki SHIMODA <shimoda.hiroaki@gmail.com> wrote:
>> > Sorry for long delay. I'll post.
>> > (I have no idea how to fix this problem as keeping TXDCTL.WTHRESH to 5)
>>
>> I don't like changing WTHRESH wholesale because making the global change
>> to WTHRESH on e1000e just to fix this one bug (likely specific to a
>> particular chip/hardware) will adversely effect performance on many
>> models supported by e1000e not demonstrating any problem.  We could
>> possibly check something in for just ESB2LAN (S5000 chipset).
>>
>> Other people (tom herbert) with this same chipset have been unable to
>> reproduce this issue right?
>
> I understand your performance concern.
>
> The affected chip would be e1000_82571, e1000_82572, e1000_82574
> and e1000_80003es2lan which have FLAG2_DMA_BURST bit in
> adapter->flags2.
> Anyway, I have no objection intel guys NACK to my patch and
> provide right fix. But in that case please consider 82574L chip too
> which I observed similar behaviour.
>
> Thanks.

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
E1000-devel mailing list
E1000-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/e1000-devel
To learn more about Intel&#174; Ethernet, visit http://communities.intel.com/community/wired

^ permalink raw reply

* Re: [PATCH v9] tilegx network driver: initial support
From: Ben Hutchings @ 2012-06-06 18:19 UTC (permalink / raw)
  To: Eric Dumazet; +Cc: Chris Metcalf, arnd, David Miller, linux-kernel, netdev
In-Reply-To: <1339006223.26966.36.camel@edumazet-glaptop>

On Wed, 2012-06-06 at 20:10 +0200, Eric Dumazet wrote:
> On Mon, 2012-06-04 at 16:12 -0400, Chris Metcalf wrote:
> > This change adds support for the tilegx network driver based on the
> > GXIO IORPC support in the tilegx software stack, using the on-chip
> > mPIPE packet processing engine.
> > 
> 
> > +
> > +/* Do "TSO" handling for egress.
> > + *
> > + * Normally drivers set NETIF_F_TSO only to support hardware TSO;
> > + * otherwise the stack uses scatter-gather to implement GSO in software.
> > + * On our testing, enabling GSO support (via NETIF_F_SG) drops network
> > + * performance down to around 7.5 Gbps on the 10G interfaces, although
> > + * also dropping cpu utilization way down, to under 8%.  But
> > + * implementing "TSO" in the driver brings performance back up to line
> > + * rate, while dropping cpu usage even further, to less than 4%.  In
> > + * practice, profiling of GSO shows that skb_segment() is what causes
> > + * the performance overheads; we benefit in the driver from using
> > + * preallocated memory to duplicate the TCP/IP headers.
> > + */
> 
> All this stuff cost about 300 lines of code in this driver, without IPv6
> support.
> 
> I am pretty sure this performance problem should be solved in net/{core|
> ipv4|ipv6} instead
> 
> What TCP performance do you get with TSO/GSO and SG off ?

It's a real problem and we have soft-TSO in the sfc driver for the same
reason.  GSO means more allocation, more DMA mapping, more calls into
the driver and more register writes.

If drivers could use GSO explicitly from their ndo_start_xmit function,
more like they do with GRO, much of this would presumably be avoidable.

Ben.

-- 
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.

^ permalink raw reply

* Re: [PATCH v9] tilegx network driver: initial support
From: David Miller @ 2012-06-06 18:17 UTC (permalink / raw)
  To: eric.dumazet; +Cc: cmetcalf, bhutchings, arnd, linux-kernel, netdev
In-Reply-To: <1339006223.26966.36.camel@edumazet-glaptop>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Wed, 06 Jun 2012 20:10:23 +0200

> I am pretty sure this performance problem should be solved in net/{core|
> ipv4|ipv6} instead
> 
> What TCP performance do you get with TSO/GSO and SG off ?

We have other drivers already doing this.

I tried a few years ago to make this generic, because NIU could
benefit from it as well, but I couldn't figure out a clean enough
way to abstract this.

Therefore it is absolutely reasonable to continue to let drivers
do this locally until we actually have a reasonable solution.

The gains are definitely significant for chips that lack real TSO
hardware, I absolutely do not require "proof" of this, it is clearly
evident to anyone who considers the issue.

^ permalink raw reply

* Re: pull-request: can-next 2012-06-04
From: David Miller @ 2012-06-06 18:15 UTC (permalink / raw)
  To: socketcan; +Cc: mkl, netdev, linux-can
In-Reply-To: <4FCF9B3B.1070105@hartkopp.net>

From: Oliver Hartkopp <socketcan@hartkopp.net>
Date: Wed, 06 Jun 2012 20:02:35 +0200

> i think there was a confusion about
> 
> 	linux-can and linux-can-next
> 
> pull requests that overlapped in the mail traffic that day.
> 
> The pull request of linux-can-next is still pending.
> 
> git://gitorious.org/linux-can/linux-can-next.git master

Strange, I thought I had pulled it, I've done so now, thanks.

^ permalink raw reply

* Re: [PATCH net-next 2/3] qlcnic: fix unsupported CDRP command error message.
From: Joe Perches @ 2012-06-06 18:14 UTC (permalink / raw)
  To: Anirban Chakraborty
  Cc: davem, netdev, Dept_NX_Linux_NIC_Driver, Jitendra Kalsaria
In-Reply-To: <1339004108-7356-3-git-send-email-anirban.chakraborty@qlogic.com>

On Wed, 2012-06-06 at 13:35 -0400, Anirban Chakraborty wrote:
> From: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>
> 
> Add debug messages for FW CDRP command failure.

trivia:

Please be consistent with the use of (preferably _no_) periods
at the end of logging messages.

$ git grep -E "[^\.]\\\\n\"" drivers/net/ethernet/qlogic/qlcnic/ | wc -l
187
$ git grep -E "\.\\\\n\"" drivers/net/ethernet/qlogic/qlcnic/ | wc -l
22

[]
> diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c
[]
> @@ -53,12 +53,39 @@ qlcnic_issue_cmd(struct qlcnic_adapter *adapter, struct qlcnic_cmd_args *cmd)
>  	rsp = qlcnic_poll_rsp(adapter);
>  
>  	if (rsp == QLCNIC_CDRP_RSP_TIMEOUT) {
> -		dev_err(&pdev->dev, "card response timeout.\n");
> +		dev_err(&pdev->dev, "CDRP response timeout.\n");

ie: no period necessary.

CDRP is kind of an odd acronym.
Is it for CarD ResPonse?

If it is, then I think a lot of the below messages are
not particularly sensible and the CDRP should be dropped.

>  		cmd->rsp.cmd = QLCNIC_RCODE_TIMEOUT;
>  	} else if (rsp == QLCNIC_CDRP_RSP_FAIL) {
>  		cmd->rsp.cmd = QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET);
> -		dev_err(&pdev->dev, "failed card response code:0x%x\n",
> +		switch (cmd->rsp.cmd) {
> +		case QLCNIC_RCODE_INVALID_ARGS:
> +			dev_err(&pdev->dev, "CDRP invalid args: 0x%x.\n",
>  				cmd->rsp.cmd);
> +			break;
> +		case QLCNIC_RCODE_NOT_SUPPORTED:
> +		case QLCNIC_RCODE_NOT_IMPL:
> +			dev_err(&pdev->dev,
> +				"CDRP command not supported: 0x%x.\n",
> +				cmd->rsp.cmd);
> +			break;
> +		case QLCNIC_RCODE_NOT_PERMITTED:
> +			dev_err(&pdev->dev,
> +				"CDRP requested action not permitted: 0x%x.\n",
> +				cmd->rsp.cmd);
> +			break;
> +		case QLCNIC_RCODE_INVALID:
> +			dev_err(&pdev->dev,
> +				"CDRP invalid or unknown cmd received: 0x%x.\n",
> +				cmd->rsp.cmd);
> +			break;
> +		case QLCNIC_RCODE_TIMEOUT:
> +			dev_err(&pdev->dev, "CDRP command timeout: 0x%x.\n",
> +				cmd->rsp.cmd);
> +			break;
> +		default:
> +			dev_err(&pdev->dev, "CDRP command failed: 0x%x.\n",
> +				cmd->rsp.cmd);
> +		}
>  	} else if (rsp == QLCNIC_CDRP_RSP_OK) {
>  		cmd->rsp.cmd = QLCNIC_RCODE_SUCCESS;
>  		if (cmd->rsp.arg2)
> @@ -957,9 +984,6 @@ int qlcnic_get_mac_stats(struct qlcnic_adapter *adapter,
>  		mac_stats->mac_rx_jabber = le64_to_cpu(stats->mac_rx_jabber);
>  		mac_stats->mac_rx_dropped = le64_to_cpu(stats->mac_rx_dropped);
>  		mac_stats->mac_rx_crc_error = le64_to_cpu(stats->mac_rx_crc_error);
> -	} else {
> -		dev_info(&adapter->pdev->dev,
> -			"%s: Get mac stats failed =%d.\n", __func__, err);
>  	}
>  
>  	dma_free_coherent(&adapter->pdev->dev, stats_size, stats_addr,

^ permalink raw reply

* Re: [PATCH v9] tilegx network driver: initial support
From: Eric Dumazet @ 2012-06-06 18:10 UTC (permalink / raw)
  To: Chris Metcalf; +Cc: bhutchings, arnd, David Miller, linux-kernel, netdev
In-Reply-To: <201206042023.q54KNEZp003834@farm-0002.internal.tilera.com>

On Mon, 2012-06-04 at 16:12 -0400, Chris Metcalf wrote:
> This change adds support for the tilegx network driver based on the
> GXIO IORPC support in the tilegx software stack, using the on-chip
> mPIPE packet processing engine.
> 

> +
> +/* Do "TSO" handling for egress.
> + *
> + * Normally drivers set NETIF_F_TSO only to support hardware TSO;
> + * otherwise the stack uses scatter-gather to implement GSO in software.
> + * On our testing, enabling GSO support (via NETIF_F_SG) drops network
> + * performance down to around 7.5 Gbps on the 10G interfaces, although
> + * also dropping cpu utilization way down, to under 8%.  But
> + * implementing "TSO" in the driver brings performance back up to line
> + * rate, while dropping cpu usage even further, to less than 4%.  In
> + * practice, profiling of GSO shows that skb_segment() is what causes
> + * the performance overheads; we benefit in the driver from using
> + * preallocated memory to duplicate the TCP/IP headers.
> + */

All this stuff cost about 300 lines of code in this driver, without IPv6
support.

I am pretty sure this performance problem should be solved in net/{core|
ipv4|ipv6} instead

What TCP performance do you get with TSO/GSO and SG off ?

^ permalink raw reply

* Re: pull-request: can-next 2012-06-04
From: Oliver Hartkopp @ 2012-06-06 18:02 UTC (permalink / raw)
  To: davem; +Cc: Marc Kleine-Budde, Linux Netdev List, linux-can@vger.kernel.org
In-Reply-To: <4FCCD9A8.7030207@pengutronix.de>

Hello Dave,

i think there was a confusion about

	linux-can and linux-can-next

pull requests that overlapped in the mail traffic that day.

The pull request of linux-can-next is still pending.

git://gitorious.org/linux-can/linux-can-next.git master

Regards,
Oliver



On 04.06.2012 17:52, Marc Kleine-Budde wrote:

> On 06/04/2012 12:52 AM, Marc Kleine-Budde wrote:
>> Hello David,
>>
>> here are the first patches for net-next, they add power management
>> support for the flexcan driver and clarify the documentation with
>> respect to error messages.
>>
>> regards, Marc
>>
>> ---
>>
>> The following changes since commit 31a67102f4762df5544bc2dfb34a931233d2a5b2:
>>
>>   Fix blocking allocations called very early during bootup (2012-05-21 12:52:42 -0700)
>>
>> are available in the git repository at:
>>   git@gitorious.org:linux-can/linux-can-next.git master
> 
> That should be:
> 
> git://gitorious.org/linux-can/linux-can-next.git master
> 
> Sorry for the noise,
> Marc
> 



^ permalink raw reply

* [PATCH net-next 1/3] qlcnic: Fix estimation of recv MSS in case of LRO
From: Anirban Chakraborty @ 2012-06-06 17:35 UTC (permalink / raw)
  To: davem; +Cc: netdev, Dept_NX_Linux_NIC_Driver, Rajesh Borundia
In-Reply-To: <1339004108-7356-1-git-send-email-anirban.chakraborty@qlogic.com>

From: Rajesh Borundia <rajesh.borundia@qlogic.com>

o Linux stack estimates MSS from skb->len or skb_shinfo(skb)->gso_size.
In case of LRO skb->len is aggregate of len of number of packets hence MSS
obtained using skb->len would be incorrect. Incorrect estimation of recv MSS
would lead to delayed acks in some traffic patterns (which sends two or three
packets and wait for ack and only then send remaining packets). This leads to
drop in performance. Hence we need to set gso_size to MSS obtained from firmware.

o This is fixed recently in firmware hence the MSS is obtained based on
capability. If fw is capable of sending the MSS then only driver sets the gso_size.

Signed-off-by: Rajesh Borundia <rajesh.borundia@qlogic.com>
Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
---
 drivers/net/ethernet/qlogic/qlcnic/qlcnic.h      |    7 +++++++
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c  |    3 +++
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h  |    1 +
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c |    3 +++
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c |    9 +++++++++
 5 files changed, 23 insertions(+), 0 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index 8680a5d..520ff03 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -258,6 +258,8 @@ struct rcv_desc {
 	(((sts_data) >> 52) & 0x1)
 #define qlcnic_get_lro_sts_seq_number(sts_data)		\
 	((sts_data) & 0x0FFFFFFFF)
+#define qlcnic_get_lro_sts_mss(sts_data1)		\
+	((sts_data1 >> 32) & 0x0FFFF)
 
 
 struct status_desc {
@@ -623,6 +625,7 @@ struct qlcnic_recv_context {
 #define QLCNIC_CAP0_JUMBO_CONTIGUOUS	(1 << 7)
 #define QLCNIC_CAP0_LRO_CONTIGUOUS	(1 << 8)
 #define QLCNIC_CAP0_VALIDOFF		(1 << 11)
+#define QLCNIC_CAP0_LRO_MSS		(1 << 21)
 
 /*
  * Context state
@@ -829,6 +832,9 @@ struct qlcnic_mac_list_s {
 #define QLCNIC_FW_CAPABILITY_FVLANTX		BIT_9
 #define QLCNIC_FW_CAPABILITY_HW_LRO		BIT_10
 #define QLCNIC_FW_CAPABILITY_MULTI_LOOPBACK	BIT_27
+#define QLCNIC_FW_CAPABILITY_MORE_CAPS		BIT_31
+
+#define QLCNIC_FW_CAPABILITY_2_LRO_MAX_TCP_SEG	BIT_2
 
 /* module types */
 #define LINKEVENT_MODULE_NOT_PRESENT			1
@@ -918,6 +924,7 @@ struct qlcnic_ipaddr {
 #define QLCNIC_NEED_FLR			0x1000
 #define QLCNIC_FW_RESET_OWNER		0x2000
 #define QLCNIC_FW_HANG			0x4000
+#define QLCNIC_FW_LRO_MSS_CAP		0x8000
 #define QLCNIC_IS_MSI_FAMILY(adapter) \
 	((adapter)->flags & (QLCNIC_MSI_ENABLED | QLCNIC_MSIX_ENABLED))
 
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c
index 8db8524..cfa174d 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c
@@ -237,6 +237,9 @@ qlcnic_fw_cmd_create_rx_ctx(struct qlcnic_adapter *adapter)
 						| QLCNIC_CAP0_VALIDOFF);
 	cap |= (QLCNIC_CAP0_JUMBO_CONTIGUOUS | QLCNIC_CAP0_LRO_CONTIGUOUS);
 
+	if (adapter->flags & QLCNIC_FW_LRO_MSS_CAP)
+		cap |= QLCNIC_CAP0_LRO_MSS;
+
 	prq->valid_field_offset = offsetof(struct qlcnic_hostrq_rx_ctx,
 							 msix_handler);
 	prq->txrx_sds_binding = nsds_rings - 1;
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h
index 6ced319..28a6b28 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_hdr.h
@@ -588,6 +588,7 @@ enum {
 #define CRB_DRIVER_VERSION		(QLCNIC_REG(0x2a0))
 
 #define CRB_FW_CAPABILITIES_1		(QLCNIC_CAM_RAM(0x128))
+#define CRB_FW_CAPABILITIES_2		(QLCNIC_CAM_RAM(0x12c))
 #define CRB_MAC_BLOCK_START		(QLCNIC_CAM_RAM(0x1c0))
 
 /*
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c
index 799fd40..8620b69 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_init.c
@@ -1653,6 +1653,9 @@ qlcnic_process_lro(struct qlcnic_adapter *adapter,
 
 	length = skb->len;
 
+	if (adapter->flags & QLCNIC_FW_LRO_MSS_CAP)
+		skb_shinfo(skb)->gso_size = qlcnic_get_lro_sts_mss(sts_data1);
+
 	if (vid != 0xffff)
 		__vlan_hwaccel_put_tag(skb, vid);
 	netif_receive_skb(skb);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index 46e77a2..707b5ca 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -1136,6 +1136,8 @@ static int
 __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev)
 {
 	int ring;
+	u32 capab2;
+
 	struct qlcnic_host_rds_ring *rds_ring;
 
 	if (adapter->is_up != QLCNIC_ADAPTER_UP_MAGIC)
@@ -1146,6 +1148,12 @@ __qlcnic_up(struct qlcnic_adapter *adapter, struct net_device *netdev)
 	if (qlcnic_set_eswitch_port_config(adapter))
 		return -EIO;
 
+	if (adapter->capabilities & QLCNIC_FW_CAPABILITY_MORE_CAPS) {
+		capab2 = QLCRD32(adapter, CRB_FW_CAPABILITIES_2);
+		if (capab2 & QLCNIC_FW_CAPABILITY_2_LRO_MAX_TCP_SEG)
+			adapter->flags |= QLCNIC_FW_LRO_MSS_CAP;
+	}
+
 	if (qlcnic_fw_create_ctx(adapter))
 		return -EIO;
 
@@ -1215,6 +1223,7 @@ __qlcnic_down(struct qlcnic_adapter *adapter, struct net_device *netdev)
 	qlcnic_napi_disable(adapter);
 
 	qlcnic_fw_destroy_ctx(adapter);
+	adapter->flags &= ~QLCNIC_FW_LRO_MSS_CAP;
 
 	qlcnic_reset_rx_buffers_list(adapter);
 	qlcnic_release_tx_buffers(adapter);
-- 
1.7.4.1

^ permalink raw reply related

* [PATCH net-next 3/3] qlcnic: Fix protcol type in case of inband vlan.
From: Anirban Chakraborty @ 2012-06-06 17:35 UTC (permalink / raw)
  To: davem; +Cc: netdev, Dept_NX_Linux_NIC_Driver, Rajesh Borundia
In-Reply-To: <1339004108-7356-1-git-send-email-anirban.chakraborty@qlogic.com>

From: Rajesh Borundia <rajesh.borundia@qlogic.com>

o Use correct l3 (ETH_IP or ETH_IPV6)protcol in case
of inband vlan. Because of incorrect protcol type driver
was setting incorrect opcode. This resulted in adapter calculating
checksum incorrectly.
o Updated driver version to 5.0.29

Signed-off-by: Rajesh Borundia <rajesh.borundia@qlogic.com>
Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
---
 drivers/net/ethernet/qlogic/qlcnic/qlcnic.h      |    4 ++--
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c |    1 +
 2 files changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index df4552f..eaa1db9 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -36,8 +36,8 @@
 
 #define _QLCNIC_LINUX_MAJOR 5
 #define _QLCNIC_LINUX_MINOR 0
-#define _QLCNIC_LINUX_SUBVERSION 28
-#define QLCNIC_LINUX_VERSIONID  "5.0.28"
+#define _QLCNIC_LINUX_SUBVERSION 29
+#define QLCNIC_LINUX_VERSIONID  "5.0.29"
 #define QLCNIC_DRV_IDC_VER  0x01
 #define QLCNIC_DRIVER_VERSION  ((_QLCNIC_LINUX_MAJOR << 16) |\
 		 (_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION))
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index 707b5ca..33c3e46 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -2033,6 +2033,7 @@ qlcnic_tx_pkt(struct qlcnic_adapter *adapter,
 		vh = (struct vlan_ethhdr *)skb->data;
 		flags = FLAGS_VLAN_TAGGED;
 		vlan_tci = vh->h_vlan_TCI;
+		protocol = ntohs(vh->h_vlan_encapsulated_proto);
 	} else if (vlan_tx_tag_present(skb)) {
 		flags = FLAGS_VLAN_OOB;
 		vlan_tci = vlan_tx_tag_get(skb);
-- 
1.7.4.1

^ permalink raw reply related

* [PATCH net-next 2/3] qlcnic: fix unsupported CDRP command error message.
From: Anirban Chakraborty @ 2012-06-06 17:35 UTC (permalink / raw)
  To: davem; +Cc: netdev, Dept_NX_Linux_NIC_Driver, Jitendra Kalsaria
In-Reply-To: <1339004108-7356-1-git-send-email-anirban.chakraborty@qlogic.com>

From: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>

Add debug messages for FW CDRP command failure.

Signed-off-by: Jitendra Kalsaria <jitendra.kalsaria@qlogic.com>
Signed-off-by: Anirban Chakraborty <anirban.chakraborty@qlogic.com>
---
 drivers/net/ethernet/qlogic/qlcnic/qlcnic.h     |    4 +++
 drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c |   34 +++++++++++++++++++---
 2 files changed, 33 insertions(+), 5 deletions(-)

diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index 520ff03..df4552f 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
@@ -612,7 +612,11 @@ struct qlcnic_recv_context {
 #define QLCNIC_CDRP_CMD_GET_MAC_STATS		0x00000037
 
 #define QLCNIC_RCODE_SUCCESS		0
+#define QLCNIC_RCODE_INVALID_ARGS	6
 #define QLCNIC_RCODE_NOT_SUPPORTED	9
+#define QLCNIC_RCODE_NOT_PERMITTED	10
+#define QLCNIC_RCODE_NOT_IMPL		15
+#define QLCNIC_RCODE_INVALID		16
 #define QLCNIC_RCODE_TIMEOUT		17
 #define QLCNIC_DESTROY_CTX_RESET	0
 
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c
index cfa174d..b8ead69 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c
@@ -53,12 +53,39 @@ qlcnic_issue_cmd(struct qlcnic_adapter *adapter, struct qlcnic_cmd_args *cmd)
 	rsp = qlcnic_poll_rsp(adapter);
 
 	if (rsp == QLCNIC_CDRP_RSP_TIMEOUT) {
-		dev_err(&pdev->dev, "card response timeout.\n");
+		dev_err(&pdev->dev, "CDRP response timeout.\n");
 		cmd->rsp.cmd = QLCNIC_RCODE_TIMEOUT;
 	} else if (rsp == QLCNIC_CDRP_RSP_FAIL) {
 		cmd->rsp.cmd = QLCRD32(adapter, QLCNIC_ARG1_CRB_OFFSET);
-		dev_err(&pdev->dev, "failed card response code:0x%x\n",
+		switch (cmd->rsp.cmd) {
+		case QLCNIC_RCODE_INVALID_ARGS:
+			dev_err(&pdev->dev, "CDRP invalid args: 0x%x.\n",
 				cmd->rsp.cmd);
+			break;
+		case QLCNIC_RCODE_NOT_SUPPORTED:
+		case QLCNIC_RCODE_NOT_IMPL:
+			dev_err(&pdev->dev,
+				"CDRP command not supported: 0x%x.\n",
+				cmd->rsp.cmd);
+			break;
+		case QLCNIC_RCODE_NOT_PERMITTED:
+			dev_err(&pdev->dev,
+				"CDRP requested action not permitted: 0x%x.\n",
+				cmd->rsp.cmd);
+			break;
+		case QLCNIC_RCODE_INVALID:
+			dev_err(&pdev->dev,
+				"CDRP invalid or unknown cmd received: 0x%x.\n",
+				cmd->rsp.cmd);
+			break;
+		case QLCNIC_RCODE_TIMEOUT:
+			dev_err(&pdev->dev, "CDRP command timeout: 0x%x.\n",
+				cmd->rsp.cmd);
+			break;
+		default:
+			dev_err(&pdev->dev, "CDRP command failed: 0x%x.\n",
+				cmd->rsp.cmd);
+		}
 	} else if (rsp == QLCNIC_CDRP_RSP_OK) {
 		cmd->rsp.cmd = QLCNIC_RCODE_SUCCESS;
 		if (cmd->rsp.arg2)
@@ -957,9 +984,6 @@ int qlcnic_get_mac_stats(struct qlcnic_adapter *adapter,
 		mac_stats->mac_rx_jabber = le64_to_cpu(stats->mac_rx_jabber);
 		mac_stats->mac_rx_dropped = le64_to_cpu(stats->mac_rx_dropped);
 		mac_stats->mac_rx_crc_error = le64_to_cpu(stats->mac_rx_crc_error);
-	} else {
-		dev_info(&adapter->pdev->dev,
-			"%s: Get mac stats failed =%d.\n", __func__, err);
 	}
 
 	dma_free_coherent(&adapter->pdev->dev, stats_size, stats_addr,
-- 
1.7.4.1

^ permalink raw reply related


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