* Re: [stable] net: Handle different key sizes between address families in flow cache
From: David Miller @ 2011-11-04 20:41 UTC (permalink / raw)
To: kim.phillips; +Cc: stable, eric.dumazet, zheng.z.yan, netdev, david.ward
In-Reply-To: <20111104144659.3e0a30afffffd9dd73cf740e@freescale.com>
From: Kim Phillips <kim.phillips@freescale.com>
Date: Fri, 4 Nov 2011 14:46:59 -0500
> commit aa1c366e4febc7f5c2b84958a2dd7cd70e28f9d0 upstream.
>
> With the conversion of struct flowi to a union of AF-specific structs, some
> operations on the flow cache need to account for the exact size of the key.
>
> Signed-off-by: David Ward <david.ward@ll.mit.edu>
> Signed-off-by: David S. Miller <davem@davemloft.net>
> Cc: stable@vger.kernel.org # v3.0.x
I'm fine with this, -stable folks please apply.
Thanks.
^ permalink raw reply
* Re: [patch] bonding: comparing a u8 with -1 is always false
From: Ben Hutchings @ 2011-11-04 20:35 UTC (permalink / raw)
To: Jay Vosburgh
Cc: Dan Carpenter, Weiping Pan, Andy Gospodarek, netdev,
David S. Miller, kernel-janitors
In-Reply-To: <10444.1320436921@death>
On Fri, 2011-11-04 at 13:02 -0700, Jay Vosburgh wrote:
> Dan Carpenter <dan.carpenter@oracle.com> wrote:
> >slave->duplex is a u8 type so the in bond_info_show_slave() when we
> >check "if (slave->duplex == -1)", it's always false.
> >
> >Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
> >
> >diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
> >index b2b9109..b0c5772 100644
> >--- a/drivers/net/bonding/bond_main.c
> >+++ b/drivers/net/bonding/bond_main.c
> >@@ -560,8 +560,8 @@ static int bond_update_speed_duplex(struct slave *slave)
> > u32 slave_speed;
> > int res;
> >
> >- slave->speed = -1;
> >- slave->duplex = -1;
> >+ slave->speed = SPEED_UNKNOWN;
> >+ slave->duplex = DUPLEX_UNKNOWN;
> >
> > res = __ethtool_get_settings(slave_dev, &ecmd);
> > if (res < 0)
> >diff --git a/drivers/net/bonding/bond_procfs.c b/drivers/net/bonding/bond_procfs.c
> >index 2acf0b0..ad284ba 100644
> >--- a/drivers/net/bonding/bond_procfs.c
> >+++ b/drivers/net/bonding/bond_procfs.c
> >@@ -158,12 +158,12 @@ static void bond_info_show_slave(struct seq_file *seq,
> > seq_printf(seq, "\nSlave Interface: %s\n", slave->dev->name);
> > seq_printf(seq, "MII Status: %s\n",
> > (slave->link == BOND_LINK_UP) ? "up" : "down");
> >- if (slave->speed == -1)
> >+ if (slave->speed == SPEED_UNKNOWN)
> > seq_printf(seq, "Speed: %s\n", "Unknown");
> > else
> > seq_printf(seq, "Speed: %d Mbps\n", slave->speed);
>
> Since you #define SPEED_UNKNOWN to -1 (below), how does this
> actually change anything? Did you mean 0xffff (because struct
> ethtool_cmd's speed is a u16)?
The speed in ethtool_cmd is 32 bits divided between two fields.
> Running on a moderately recent net-next (without the very recent
> change to bond_update_speed_duplex), I see that bonding indeed doesn't
> get the speed or duplex correct after a cable pull:
>
> Slave Interface: eth2
> MII Status: down
> Speed: 100 Mbps
> Duplex: full
>
> so perhaps a rational (unsigned-friendly) SPEED_UNKNOWN and
> DUPLEX_UNKNOWN are needed, but I'm not sure how this #define actually
> would change any behavior in the bonding case.
Agree that they should be defined somewhere. The ethtool utility
recognises speed values of 0, (u16)(-1) and (u32)(-1) as 'unknown'.
Personally I think 0 makes more sense than (u32)(-1) but it doesn't
matter much.
> >- if (slave->duplex == -1)
> >+ if (slave->duplex == DUPLEX_UNKNOWN)
> > seq_printf(seq, "Duplex: %s\n", "Unknown");
> > else
> > seq_printf(seq, "Duplex: %s\n", slave->duplex ? "full" : "half");
>
> This one might "work," but it seems to depend on the fact that
> the integral conversion of -1 to an 8 bit unsigned type will be 255
> (0xff). I believe that's true (according to the ISO C copy I have
> handy), but I'm not sure that kind of implicit assumption should be
> built into the code. At least not without some explanation.
[...]
It's true and does not need explanation. Quite why anyone expected a
negative value to survive conversion to u8 and back to int, now that
deserves explanation...
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] bonding: comparing a u8 with -1 is always false
From: Jay Vosburgh @ 2011-11-04 20:02 UTC (permalink / raw)
To: Dan Carpenter
Cc: Weiping Pan, Andy Gospodarek, netdev, David S. Miller,
kernel-janitors, Ben Hutchings
In-Reply-To: <20111104182138.GB5796@elgon.mountain>
Dan Carpenter <dan.carpenter@oracle.com> wrote:
>slave->duplex is a u8 type so the in bond_info_show_slave() when we
>check "if (slave->duplex == -1)", it's always false.
>
>Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
>
>diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
>index b2b9109..b0c5772 100644
>--- a/drivers/net/bonding/bond_main.c
>+++ b/drivers/net/bonding/bond_main.c
>@@ -560,8 +560,8 @@ static int bond_update_speed_duplex(struct slave *slave)
> u32 slave_speed;
> int res;
>
>- slave->speed = -1;
>- slave->duplex = -1;
>+ slave->speed = SPEED_UNKNOWN;
>+ slave->duplex = DUPLEX_UNKNOWN;
>
> res = __ethtool_get_settings(slave_dev, &ecmd);
> if (res < 0)
>diff --git a/drivers/net/bonding/bond_procfs.c b/drivers/net/bonding/bond_procfs.c
>index 2acf0b0..ad284ba 100644
>--- a/drivers/net/bonding/bond_procfs.c
>+++ b/drivers/net/bonding/bond_procfs.c
>@@ -158,12 +158,12 @@ static void bond_info_show_slave(struct seq_file *seq,
> seq_printf(seq, "\nSlave Interface: %s\n", slave->dev->name);
> seq_printf(seq, "MII Status: %s\n",
> (slave->link == BOND_LINK_UP) ? "up" : "down");
>- if (slave->speed == -1)
>+ if (slave->speed == SPEED_UNKNOWN)
> seq_printf(seq, "Speed: %s\n", "Unknown");
> else
> seq_printf(seq, "Speed: %d Mbps\n", slave->speed);
Since you #define SPEED_UNKNOWN to -1 (below), how does this
actually change anything? Did you mean 0xffff (because struct
ethtool_cmd's speed is a u16)?
Running on a moderately recent net-next (without the very recent
change to bond_update_speed_duplex), I see that bonding indeed doesn't
get the speed or duplex correct after a cable pull:
Slave Interface: eth2
MII Status: down
Speed: 100 Mbps
Duplex: full
so perhaps a rational (unsigned-friendly) SPEED_UNKNOWN and
DUPLEX_UNKNOWN are needed, but I'm not sure how this #define actually
would change any behavior in the bonding case.
>- if (slave->duplex == -1)
>+ if (slave->duplex == DUPLEX_UNKNOWN)
> seq_printf(seq, "Duplex: %s\n", "Unknown");
> else
> seq_printf(seq, "Duplex: %s\n", slave->duplex ? "full" : "half");
This one might "work," but it seems to depend on the fact that
the integral conversion of -1 to an 8 bit unsigned type will be 255
(0xff). I believe that's true (according to the ISO C copy I have
handy), but I'm not sure that kind of implicit assumption should be
built into the code. At least not without some explanation.
-J
>diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
>index 45f00b6..de33de1 100644
>--- a/include/linux/ethtool.h
>+++ b/include/linux/ethtool.h
>@@ -1097,10 +1097,12 @@ struct ethtool_ops {
> #define SPEED_1000 1000
> #define SPEED_2500 2500
> #define SPEED_10000 10000
>+#define SPEED_UNKNOWN -1
>
> /* Duplex, half or full. */
> #define DUPLEX_HALF 0x00
> #define DUPLEX_FULL 0x01
>+#define DUPLEX_UNKNOWN 0xff
>
> /* Which connector port. */
> #define PORT_TP 0x00
---
-Jay Vosburgh, IBM Linux Technology Center, fubar@us.ibm.com
^ permalink raw reply
* [stable] net: Handle different key sizes between address families in flow cache
From: Kim Phillips @ 2011-11-04 19:46 UTC (permalink / raw)
To: David Miller; +Cc: stable, eric.dumazet, zheng.z.yan, netdev, David Ward
In-Reply-To: <20111103.224329.2276058062630695656.davem@davemloft.net>
commit aa1c366e4febc7f5c2b84958a2dd7cd70e28f9d0 upstream.
With the conversion of struct flowi to a union of AF-specific structs, some
operations on the flow cache need to account for the exact size of the key.
Signed-off-by: David Ward <david.ward@ll.mit.edu>
Signed-off-by: David S. Miller <davem@davemloft.net>
Cc: stable@vger.kernel.org # v3.0.x
---
This patch is the result of a clean cherry-pick onto v3.0.8.
It restores IPSec fwding performance from ~4kpps back to ~44kpps on
a P2020DS board.
include/net/flow.h | 19 +++++++++++++++++++
net/core/flow.c | 31 +++++++++++++++++--------------
2 files changed, 36 insertions(+), 14 deletions(-)
diff --git a/include/net/flow.h b/include/net/flow.h
index c6d5fe5..93a8785 100644
--- a/include/net/flow.h
+++ b/include/net/flow.h
@@ -7,6 +7,7 @@
#ifndef _NET_FLOW_H
#define _NET_FLOW_H
+#include <linux/socket.h>
#include <linux/in6.h>
#include <asm/atomic.h>
@@ -161,6 +162,24 @@ static inline struct flowi *flowidn_to_flowi(struct flowidn *fldn)
return container_of(fldn, struct flowi, u.dn);
}
+typedef unsigned long flow_compare_t;
+
+static inline size_t flow_key_size(u16 family)
+{
+ switch (family) {
+ case AF_INET:
+ BUILD_BUG_ON(sizeof(struct flowi4) % sizeof(flow_compare_t));
+ return sizeof(struct flowi4) / sizeof(flow_compare_t);
+ case AF_INET6:
+ BUILD_BUG_ON(sizeof(struct flowi6) % sizeof(flow_compare_t));
+ return sizeof(struct flowi6) / sizeof(flow_compare_t);
+ case AF_DECnet:
+ BUILD_BUG_ON(sizeof(struct flowidn) % sizeof(flow_compare_t));
+ return sizeof(struct flowidn) / sizeof(flow_compare_t);
+ }
+ return 0;
+}
+
#define FLOW_DIR_IN 0
#define FLOW_DIR_OUT 1
#define FLOW_DIR_FWD 2
diff --git a/net/core/flow.c b/net/core/flow.c
index 990703b..a6bda2a 100644
--- a/net/core/flow.c
+++ b/net/core/flow.c
@@ -172,29 +172,26 @@ static void flow_new_hash_rnd(struct flow_cache *fc,
static u32 flow_hash_code(struct flow_cache *fc,
struct flow_cache_percpu *fcp,
- const struct flowi *key)
+ const struct flowi *key,
+ size_t keysize)
{
const u32 *k = (const u32 *) key;
+ const u32 length = keysize * sizeof(flow_compare_t) / sizeof(u32);
- return jhash2(k, (sizeof(*key) / sizeof(u32)), fcp->hash_rnd)
+ return jhash2(k, length, fcp->hash_rnd)
& (flow_cache_hash_size(fc) - 1);
}
-typedef unsigned long flow_compare_t;
-
/* I hear what you're saying, use memcmp. But memcmp cannot make
- * important assumptions that we can here, such as alignment and
- * constant size.
+ * important assumptions that we can here, such as alignment.
*/
-static int flow_key_compare(const struct flowi *key1, const struct flowi *key2)
+static int flow_key_compare(const struct flowi *key1, const struct flowi *key2,
+ size_t keysize)
{
const flow_compare_t *k1, *k1_lim, *k2;
- const int n_elem = sizeof(struct flowi) / sizeof(flow_compare_t);
-
- BUILD_BUG_ON(sizeof(struct flowi) % sizeof(flow_compare_t));
k1 = (const flow_compare_t *) key1;
- k1_lim = k1 + n_elem;
+ k1_lim = k1 + keysize;
k2 = (const flow_compare_t *) key2;
@@ -215,6 +212,7 @@ flow_cache_lookup(struct net *net, const struct flowi *key, u16 family, u8 dir,
struct flow_cache_entry *fle, *tfle;
struct hlist_node *entry;
struct flow_cache_object *flo;
+ size_t keysize;
unsigned int hash;
local_bh_disable();
@@ -222,6 +220,11 @@ flow_cache_lookup(struct net *net, const struct flowi *key, u16 family, u8 dir,
fle = NULL;
flo = NULL;
+
+ keysize = flow_key_size(family);
+ if (!keysize)
+ goto nocache;
+
/* Packet really early in init? Making flow_cache_init a
* pre-smp initcall would solve this. --RR */
if (!fcp->hash_table)
@@ -230,11 +233,11 @@ flow_cache_lookup(struct net *net, const struct flowi *key, u16 family, u8 dir,
if (fcp->hash_rnd_recalc)
flow_new_hash_rnd(fc, fcp);
- hash = flow_hash_code(fc, fcp, key);
+ hash = flow_hash_code(fc, fcp, key, keysize);
hlist_for_each_entry(tfle, entry, &fcp->hash_table[hash], u.hlist) {
if (tfle->family == family &&
tfle->dir == dir &&
- flow_key_compare(key, &tfle->key) == 0) {
+ flow_key_compare(key, &tfle->key, keysize) == 0) {
fle = tfle;
break;
}
@@ -248,7 +251,7 @@ flow_cache_lookup(struct net *net, const struct flowi *key, u16 family, u8 dir,
if (fle) {
fle->family = family;
fle->dir = dir;
- memcpy(&fle->key, key, sizeof(*key));
+ memcpy(&fle->key, key, keysize * sizeof(flow_compare_t));
fle->object = NULL;
hlist_add_head(&fle->u.hlist, &fcp->hash_table[hash]);
fcp->hash_count++;
--
1.7.7.2
^ permalink raw reply related
* Re: iproute2 neighboring
From: Kevin Wilson @ 2011-11-04 19:27 UTC (permalink / raw)
To: François-Xavier Le Bail
Cc: David Stevens, netdev@vger.kernel.org,
netdev-owner@vger.kernel.org
In-Reply-To: <1320422044.81742.YahooMailNeo@web126019.mail.ne1.yahoo.com>
Hi,
Thanks all responses!
The answer that there is a fixed mapping in case of multicast is reasonable,
and I assume this is the reason for not seeing multicast addresses in
neigh table.
>You can also see group memberships with "ip m".
I wonder whether I can know from "ip -m" which multicast addresses
are attached to which ip addresses.
For example,
"ip -m" shows:
2: em1
... ip1
... ip2
... ip3
inet 224.0.0.1
inet6 ff02::1:ffcf:c821
inet6 ff02::1
is the order important here?
namely, is ip1 belongs to 224.0.0.1,
ip2 belongs to ff02::1:ffcf:c821, and ip3 belong to ff02::1?
rgs,
Kevin
2011/11/4 François-Xavier Le Bail <fx.lebail@yahoo.com>:
>
>
>
>
> ----- Original Message -----
>> From: David Stevens <dlstevens@us.ibm.com>
>> To: Kevin Wilson <wkevils@gmail.com>
>> Cc: netdev@vger.kernel.org; netdev-owner@vger.kernel.org
>> Sent: Friday, November 4, 2011 4:46 PM
>> Subject: Re: iproute2 neighboring
>>
>>> From: Kevin Wilson <wkevils@gmail.com>
>>
>>> Hi,
>>> It seems to me that "ip -6 neigh show" does not show multicast
>> entries
>> from
>>> IPv6 neighboring table. Is there a reason for this ?
>>
>> Multicast memberships aren't in the neighbor table. The
>> neighbor table is for translating protocol addresses to
>> MAC addresses and that translation is fixed for multicast
>> destinations.
>>
>> You can see group memberships with "netstat -g". There are also
>> some data in /proc/net/{dev_mcast,igmp6,mcfilter6} depending on
>> what you're looking for.
>>
>> +-DLS
>
> Hi,
>
> You can also see group memberships with "ip m".
>
> François-Xavier
>
>
^ permalink raw reply
* Re: [PATCH series][6LoWPAN]
From: Alexander Smirnov @ 2011-11-04 19:19 UTC (permalink / raw)
To: netdev
In-Reply-To: <20111102.155751.937213919986688678.davem@davemloft.net>
Hello everybody,
2011/11/2, David Miller <davem@davemloft.net>:
> From: Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
> Date: Wed, 2 Nov 2011 19:25:20 +0300
>
>> The following patch series adds both major feature and minor fixes.
>> Please find detailed description in each of the patches.
>
> Right in the middle of the merge window is not the time to be
> submitting new features.
>
> You'll need to repost these when the net-next tree opens back
> up.
>
sorry if my question looks too silly, but I'm not so long here and
don't know all the patch-submitting-process details. :-(
Could anyone please describe me (or link to some wiki) the merge
process, how the new merge window is announced, what the proper time
to send bug fixes/new features and so on..
Thank you for your time!
With best regards,
Alexander
^ permalink raw reply
* pull request: wireless 2011-11-04
From: John W. Linville @ 2011-11-04 19:13 UTC (permalink / raw)
To: davem; +Cc: linux-wireless, netdev, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 29651 bytes --]
commit 22097fd297c85ec6c2e700d506f231f7cae442e1
Dave,
Here is the first batch of wireless fixes intended for 3.2 -- hooray!
This includes a fix for a race in iwlagn, a number of simple
initialization fixes for ath9k, a couple of mac80211 fixes
related to off-channel work, a carl9170 fix to properly handle the
TX_CTL_REQ_TX_STATUS flag, a TDLS fix for mac80211 (including a memory
leak fix), a libertas fix for cleaning-up properly after a scan,
an iwlwifi fix for working correctly even if MSI is unavailable,
a mac80211 fix to disable powersave for broken APs, the removal of
some log spam from b43, another iwlwifi fix for avoiding a stuck cmd
queue, and a mac80211 fix to reduce log spam about not finding a rate.
Also included is a Bluetooth pull from Gustavo:
"Some fixes for the 3.2 release, there are four fixes in
our drivers code by David Hermann. Szymon Janc fixed a bug
that was making some dongles not work well and a sleep in
invalid context. And finally a bug fix in the mgmt code by
Johan Hedberg."
Please let me know if there are problems!
Thanks,
John
---
The following changes since commit 1a67a573b8d9f02211f36fbab50f6265dc49384a:
Merge git://git.samba.org/sfrench/cifs-2.6 (2011-11-03 21:07:58 -0700)
are available in the git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/linville/wireless.git for-davem
Andres Salomon (1):
libertas: ensure we clean up a scan request properly
Christian Lamparter (1):
carl9170: fix AMPDU TX_CTL_REQ_TX_STATUS handling
David Herrmann (4):
Bluetooth: ath3k: Use GFP_KERNEL instead of GFP_ATOMIC
Bluetooth: bcm203x: Fix race condition on disconnect
Bluetooth: bcm203x: Use GFP_KERNEL in workqueue
Bluetooth: bfusb: Fix error path on firmware load
Eliad Peller (2):
mac80211: fix remain_off_channel regression
mac80211: config hw when going back on-channel
Emmanuel Grumbach (1):
iwlagn: fix the race in the unmapping of the HCMD
Johan Hedberg (1):
Bluetooth: Set HCI_MGMT flag only in read_controller_info
Johannes Berg (2):
mac80211: disable powersave for broken APs
mac80211: warn only once about not finding a rate
John W. Linville (2):
Merge branch 'master' of git://git.kernel.org/.../padovan/bluetooth
Merge branch 'master' of git://git.kernel.org/.../linville/wireless into for-davem
Jouni Malinen (1):
mac80211: Fix TDLS support validation in add_station handler
Larry Finger (1):
b43: Remove unneeded message
Rajkumar Manoharan (5):
ath9k_hw: Fix regression of register offset for AR9003 chips
ath9k_hw: Fix radio retention for AR9462
ath9k_hw: Fix regression of register offset of AR9330/AR9340
ath9k_hw: Update AR9485 initvals to fix system hang issue
ath9k_hw: Fix noise floor calibration timeout on fast channel change
Szymon Janc (2):
Bluetooth: rfcomm: Fix sleep in invalid context in rfcomm_security_cfm
Bluetooth: Increase HCI reset timeout in hci_dev_do_close
Wey-Yi Guy (2):
iwlwifi: allow pci_enable_msi fail
iwlwifi: don't perform "echo test" when cmd queue stuck
drivers/bluetooth/ath3k.c | 4 +-
drivers/bluetooth/bcm203x.c | 12 +++++++-
drivers/bluetooth/bfusb.c | 13 ++++----
drivers/net/wireless/ath/ath9k/ar9002_calib.c | 4 --
drivers/net/wireless/ath/ath9k/ar9003_calib.c | 11 ++++---
drivers/net/wireless/ath/ath9k/ar9003_phy.h | 34 +++++++++++-----------
drivers/net/wireless/ath/ath9k/ar9485_initvals.h | 10 +++---
drivers/net/wireless/ath/ath9k/hw.c | 3 ++
drivers/net/wireless/ath/carl9170/tx.c | 11 ++++--
drivers/net/wireless/b43/xmit.c | 1 -
drivers/net/wireless/iwlwifi/iwl-core.c | 10 ------
drivers/net/wireless/iwlwifi/iwl-pci.c | 8 ++---
drivers/net/wireless/iwlwifi/iwl-trans-pcie.c | 12 +++++--
drivers/net/wireless/libertas/cfg.c | 25 +++++++++++-----
drivers/net/wireless/libertas/cfg.h | 1 +
drivers/net/wireless/libertas/main.c | 6 +--
include/net/bluetooth/rfcomm.h | 1 +
include/net/mac80211.h | 3 +-
net/bluetooth/hci_core.c | 2 +-
net/bluetooth/mgmt.c | 2 -
net/bluetooth/rfcomm/core.c | 9 ++++-
net/mac80211/cfg.c | 12 ++++----
net/mac80211/ieee80211_i.h | 1 +
net/mac80211/mlme.c | 18 ++++++++++-
net/mac80211/work.c | 7 ++--
25 files changed, 126 insertions(+), 94 deletions(-)
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c
index db7cb81..106beb1 100644
--- a/drivers/bluetooth/ath3k.c
+++ b/drivers/bluetooth/ath3k.c
@@ -105,7 +105,7 @@ static int ath3k_load_firmware(struct usb_device *udev,
pipe = usb_sndctrlpipe(udev, 0);
- send_buf = kmalloc(BULK_SIZE, GFP_ATOMIC);
+ send_buf = kmalloc(BULK_SIZE, GFP_KERNEL);
if (!send_buf) {
BT_ERR("Can't allocate memory chunk for firmware");
return -ENOMEM;
@@ -176,7 +176,7 @@ static int ath3k_load_fwfile(struct usb_device *udev,
count = firmware->size;
- send_buf = kmalloc(BULK_SIZE, GFP_ATOMIC);
+ send_buf = kmalloc(BULK_SIZE, GFP_KERNEL);
if (!send_buf) {
BT_ERR("Can't allocate memory chunk for firmware");
return -ENOMEM;
diff --git a/drivers/bluetooth/bcm203x.c b/drivers/bluetooth/bcm203x.c
index 8b1b643..54952ab 100644
--- a/drivers/bluetooth/bcm203x.c
+++ b/drivers/bluetooth/bcm203x.c
@@ -24,6 +24,7 @@
#include <linux/module.h>
+#include <linux/atomic.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/slab.h>
@@ -65,6 +66,7 @@ struct bcm203x_data {
unsigned long state;
struct work_struct work;
+ atomic_t shutdown;
struct urb *urb;
unsigned char *buffer;
@@ -97,6 +99,7 @@ static void bcm203x_complete(struct urb *urb)
data->state = BCM203X_SELECT_MEMORY;
+ /* use workqueue to have a small delay */
schedule_work(&data->work);
break;
@@ -155,7 +158,10 @@ static void bcm203x_work(struct work_struct *work)
struct bcm203x_data *data =
container_of(work, struct bcm203x_data, work);
- if (usb_submit_urb(data->urb, GFP_ATOMIC) < 0)
+ if (atomic_read(&data->shutdown))
+ return;
+
+ if (usb_submit_urb(data->urb, GFP_KERNEL) < 0)
BT_ERR("Can't submit URB");
}
@@ -243,6 +249,7 @@ static int bcm203x_probe(struct usb_interface *intf, const struct usb_device_id
usb_set_intfdata(intf, data);
+ /* use workqueue to have a small delay */
schedule_work(&data->work);
return 0;
@@ -254,6 +261,9 @@ static void bcm203x_disconnect(struct usb_interface *intf)
BT_DBG("intf %p", intf);
+ atomic_inc(&data->shutdown);
+ cancel_work_sync(&data->work);
+
usb_kill_urb(data->urb);
usb_set_intfdata(intf, NULL);
diff --git a/drivers/bluetooth/bfusb.c b/drivers/bluetooth/bfusb.c
index 005919a..61b5914 100644
--- a/drivers/bluetooth/bfusb.c
+++ b/drivers/bluetooth/bfusb.c
@@ -568,22 +568,23 @@ static int bfusb_load_firmware(struct bfusb_data *data,
BT_INFO("BlueFRITZ! USB loading firmware");
+ buf = kmalloc(BFUSB_MAX_BLOCK_SIZE + 3, GFP_KERNEL);
+ if (!buf) {
+ BT_ERR("Can't allocate memory chunk for firmware");
+ return -ENOMEM;
+ }
+
pipe = usb_sndctrlpipe(data->udev, 0);
if (usb_control_msg(data->udev, pipe, USB_REQ_SET_CONFIGURATION,
0, 1, 0, NULL, 0, USB_CTRL_SET_TIMEOUT) < 0) {
BT_ERR("Can't change to loading configuration");
+ kfree(buf);
return -EBUSY;
}
data->udev->toggle[0] = data->udev->toggle[1] = 0;
- buf = kmalloc(BFUSB_MAX_BLOCK_SIZE + 3, GFP_ATOMIC);
- if (!buf) {
- BT_ERR("Can't allocate memory chunk for firmware");
- return -ENOMEM;
- }
-
pipe = usb_sndbulkpipe(data->udev, data->bulk_out_ep);
while (count) {
diff --git a/drivers/net/wireless/ath/ath9k/ar9002_calib.c b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
index e0ab065..88279e3 100644
--- a/drivers/net/wireless/ath/ath9k/ar9002_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9002_calib.c
@@ -868,10 +868,6 @@ static bool ar9002_hw_init_cal(struct ath_hw *ah, struct ath9k_channel *chan)
/* Do PA Calibration */
ar9002_hw_pa_cal(ah, true);
- /* Do NF Calibration after DC offset and other calibrations */
- ath9k_hw_loadnf(ah, chan);
- ath9k_hw_start_nfcal(ah, true);
-
if (ah->caldata)
ah->caldata->nfcal_pending = true;
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_calib.c b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
index 16851cb..12a730d 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_calib.c
+++ b/drivers/net/wireless/ath/ath9k/ar9003_calib.c
@@ -908,12 +908,15 @@ static bool ar9003_hw_rtt_restore(struct ath_hw *ah, struct ath9k_channel *chan)
int i;
bool restore;
- if (!(ah->caps.hw_caps & ATH9K_HW_CAP_RTT) || !ah->caldata)
+ if (!ah->caldata)
return false;
hist = &ah->caldata->rtt_hist;
+ if (!hist->num_readings)
+ return false;
+
ar9003_hw_rtt_enable(ah);
- ar9003_hw_rtt_set_mask(ah, 0x10);
+ ar9003_hw_rtt_set_mask(ah, 0x00);
for (i = 0; i < AR9300_MAX_CHAINS; i++) {
if (!(ah->rxchainmask & (1 << i)))
continue;
@@ -1070,6 +1073,7 @@ skip_tx_iqcal:
if (is_reusable && (hist->num_readings < RTT_HIST_MAX)) {
u32 *table;
+ hist->num_readings++;
for (i = 0; i < AR9300_MAX_CHAINS; i++) {
if (!(ah->rxchainmask & (1 << i)))
continue;
@@ -1081,9 +1085,6 @@ skip_tx_iqcal:
ar9003_hw_rtt_disable(ah);
}
- ath9k_hw_loadnf(ah, chan);
- ath9k_hw_start_nfcal(ah, true);
-
/* Initialize list pointers */
ah->cal_list = ah->cal_list_last = ah->cal_list_curr = NULL;
ah->supp_cals = IQ_MISMATCH_CAL;
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_phy.h b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
index 2f4023e..4114fe7 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_phy.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_phy.h
@@ -572,14 +572,14 @@
#define AR_PHY_TXGAIN_TABLE (AR_SM_BASE + 0x300)
-#define AR_PHY_TX_IQCAL_CONTROL_0 (AR_SM_BASE + AR_SREV_9485(ah) ? \
- 0x3c4 : 0x444)
-#define AR_PHY_TX_IQCAL_CONTROL_1 (AR_SM_BASE + AR_SREV_9485(ah) ? \
- 0x3c8 : 0x448)
-#define AR_PHY_TX_IQCAL_START (AR_SM_BASE + AR_SREV_9485(ah) ? \
- 0x3c4 : 0x440)
-#define AR_PHY_TX_IQCAL_STATUS_B0 (AR_SM_BASE + AR_SREV_9485(ah) ? \
- 0x3f0 : 0x48c)
+#define AR_PHY_TX_IQCAL_CONTROL_0 (AR_SM_BASE + (AR_SREV_9485(ah) ? \
+ 0x3c4 : 0x444))
+#define AR_PHY_TX_IQCAL_CONTROL_1 (AR_SM_BASE + (AR_SREV_9485(ah) ? \
+ 0x3c8 : 0x448))
+#define AR_PHY_TX_IQCAL_START (AR_SM_BASE + (AR_SREV_9485(ah) ? \
+ 0x3c4 : 0x440))
+#define AR_PHY_TX_IQCAL_STATUS_B0 (AR_SM_BASE + (AR_SREV_9485(ah) ? \
+ 0x3f0 : 0x48c))
#define AR_PHY_TX_IQCAL_CORR_COEFF_B0(_i) (AR_SM_BASE + \
(AR_SREV_9485(ah) ? \
0x3d0 : 0x450) + ((_i) << 2))
@@ -651,7 +651,7 @@
#define AR_SWITCH_TABLE_ALL_S (0)
#define AR_PHY_65NM_CH0_THERM (AR_SREV_9300(ah) ? 0x16290 :\
- (AR_SREV_9485(ah) ? 0x1628c : 0x16294))
+ (AR_SREV_9462(ah) ? 0x16294 : 0x1628c))
#define AR_PHY_65NM_CH0_THERM_LOCAL 0x80000000
#define AR_PHY_65NM_CH0_THERM_LOCAL_S 31
@@ -668,12 +668,12 @@
#define AR_PHY_65NM_CH2_RXTX2 0x16904
#define AR_CH0_TOP2 (AR_SREV_9300(ah) ? 0x1628c : \
- (AR_SREV_9485(ah) ? 0x16284 : 0x16290))
+ (AR_SREV_9462(ah) ? 0x16290 : 0x16284))
#define AR_CH0_TOP2_XPABIASLVL 0xf000
#define AR_CH0_TOP2_XPABIASLVL_S 12
#define AR_CH0_XTAL (AR_SREV_9300(ah) ? 0x16294 : \
- (AR_SREV_9485(ah) ? 0x16290 : 0x16298))
+ (AR_SREV_9462(ah) ? 0x16298 : 0x16290))
#define AR_CH0_XTAL_CAPINDAC 0x7f000000
#define AR_CH0_XTAL_CAPINDAC_S 24
#define AR_CH0_XTAL_CAPOUTDAC 0x00fe0000
@@ -908,8 +908,8 @@
#define AR_PHY_TPC_5_B1 (AR_SM1_BASE + 0x208)
#define AR_PHY_TPC_6_B1 (AR_SM1_BASE + 0x20c)
#define AR_PHY_TPC_11_B1 (AR_SM1_BASE + 0x220)
-#define AR_PHY_PDADC_TAB_1 (AR_SM1_BASE + (AR_SREV_AR9300(ah) ? \
- 0x240 : 0x280))
+#define AR_PHY_PDADC_TAB_1 (AR_SM1_BASE + (AR_SREV_AR9462(ah) ? \
+ 0x280 : 0x240))
#define AR_PHY_TPC_19_B1 (AR_SM1_BASE + 0x240)
#define AR_PHY_TPC_19_B1_ALPHA_THERM 0xff
#define AR_PHY_TPC_19_B1_ALPHA_THERM_S 0
@@ -931,10 +931,10 @@
#define AR_PHY_AIC_SRAM_ADDR_B1 (AR_SM1_BASE + 0x5f0)
#define AR_PHY_AIC_SRAM_DATA_B1 (AR_SM1_BASE + 0x5f4)
-#define AR_PHY_RTT_TABLE_SW_INTF_B(i) (0x384 + (i) ? \
- AR_SM1_BASE : AR_SM_BASE)
-#define AR_PHY_RTT_TABLE_SW_INTF_1_B(i) (0x388 + (i) ? \
- AR_SM1_BASE : AR_SM_BASE)
+#define AR_PHY_RTT_TABLE_SW_INTF_B(i) (0x384 + ((i) ? \
+ AR_SM1_BASE : AR_SM_BASE))
+#define AR_PHY_RTT_TABLE_SW_INTF_1_B(i) (0x388 + ((i) ? \
+ AR_SM1_BASE : AR_SM_BASE))
/*
* Channel 2 Register Map
*/
diff --git a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h
index 611ea6c..d16d029 100644
--- a/drivers/net/wireless/ath/ath9k/ar9485_initvals.h
+++ b/drivers/net/wireless/ath/ath9k/ar9485_initvals.h
@@ -521,7 +521,7 @@ static const u32 ar9485_1_1_radio_postamble[][2] = {
{0x000160ac, 0x24611800},
{0x000160b0, 0x03284f3e},
{0x0001610c, 0x00170000},
- {0x00016140, 0x10804008},
+ {0x00016140, 0x50804008},
};
static const u32 ar9485_1_1_mac_postamble[][5] = {
@@ -603,7 +603,7 @@ static const u32 ar9485_1_1_radio_core[][2] = {
static const u32 ar9485_1_1_pcie_phy_pll_on_clkreq_enable_L1[][2] = {
/* Addr allmodes */
- {0x00018c00, 0x10052e5e},
+ {0x00018c00, 0x18052e5e},
{0x00018c04, 0x000801d8},
{0x00018c08, 0x0000080c},
};
@@ -776,7 +776,7 @@ static const u32 ar9485_modes_green_ob_db_tx_gain_1_1[][5] = {
static const u32 ar9485_1_1_pcie_phy_clkreq_disable_L1[][2] = {
/* Addr allmodes */
- {0x00018c00, 0x10013e5e},
+ {0x00018c00, 0x18013e5e},
{0x00018c04, 0x000801d8},
{0x00018c08, 0x0000080c},
};
@@ -882,7 +882,7 @@ static const u32 ar9485_fast_clock_1_1_baseband_postamble[][3] = {
static const u32 ar9485_1_1_pcie_phy_pll_on_clkreq_disable_L1[][2] = {
/* Addr allmodes */
- {0x00018c00, 0x10012e5e},
+ {0x00018c00, 0x18012e5e},
{0x00018c04, 0x000801d8},
{0x00018c08, 0x0000080c},
};
@@ -1021,7 +1021,7 @@ static const u32 ar9485_common_rx_gain_1_1[][2] = {
static const u32 ar9485_1_1_pcie_phy_clkreq_enable_L1[][2] = {
/* Addr allmodes */
- {0x00018c00, 0x10053e5e},
+ {0x00018c00, 0x18053e5e},
{0x00018c04, 0x000801d8},
{0x00018c08, 0x0000080c},
};
diff --git a/drivers/net/wireless/ath/ath9k/hw.c b/drivers/net/wireless/ath/ath9k/hw.c
index f16d203..b479160 100644
--- a/drivers/net/wireless/ath/ath9k/hw.c
+++ b/drivers/net/wireless/ath/ath9k/hw.c
@@ -1724,6 +1724,9 @@ int ath9k_hw_reset(struct ath_hw *ah, struct ath9k_channel *chan,
if (!ath9k_hw_init_cal(ah, chan))
return -EIO;
+ ath9k_hw_loadnf(ah, chan);
+ ath9k_hw_start_nfcal(ah, true);
+
ENABLE_REGWRITE_BUFFER(ah);
ath9k_hw_restore_chainmask(ah);
diff --git a/drivers/net/wireless/ath/carl9170/tx.c b/drivers/net/wireless/ath/carl9170/tx.c
index d209469..59472e1 100644
--- a/drivers/net/wireless/ath/carl9170/tx.c
+++ b/drivers/net/wireless/ath/carl9170/tx.c
@@ -296,7 +296,8 @@ static void carl9170_tx_release(struct kref *ref)
super = (void *)skb->data;
txinfo->status.ampdu_len = super->s.rix;
txinfo->status.ampdu_ack_len = super->s.cnt;
- } else if (txinfo->flags & IEEE80211_TX_STAT_ACK) {
+ } else if ((txinfo->flags & IEEE80211_TX_STAT_ACK) &&
+ !(txinfo->flags & IEEE80211_TX_CTL_REQ_TX_STATUS)) {
/*
* drop redundant tx_status reports:
*
@@ -308,15 +309,17 @@ static void carl9170_tx_release(struct kref *ref)
*
* 3. minstrel_ht is picky, it only accepts
* reports of frames with the TX_STATUS_AMPDU flag.
+ *
+ * 4. mac80211 is not particularly interested in
+ * feedback either [CTL_REQ_TX_STATUS not set]
*/
dev_kfree_skb_any(skb);
return;
} else {
/*
- * Frame has failed, but we want to keep it in
- * case it was lost due to a power-state
- * transition.
+ * Either the frame transmission has failed or
+ * mac80211 requested tx status.
*/
}
}
diff --git a/drivers/net/wireless/b43/xmit.c b/drivers/net/wireless/b43/xmit.c
index c73e860..58ea0e5 100644
--- a/drivers/net/wireless/b43/xmit.c
+++ b/drivers/net/wireless/b43/xmit.c
@@ -827,7 +827,6 @@ void b43_rx(struct b43_wldev *dev, struct sk_buff *skb, const void *_rxhdr)
#endif
return;
drop:
- b43dbg(dev->wl, "RX: Packet dropped\n");
dev_kfree_skb_any(skb);
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-core.c b/drivers/net/wireless/iwlwifi/iwl-core.c
index b247a56..001fdf1 100644
--- a/drivers/net/wireless/iwlwifi/iwl-core.c
+++ b/drivers/net/wireless/iwlwifi/iwl-core.c
@@ -1755,16 +1755,6 @@ static inline int iwl_check_stuck_queue(struct iwl_priv *priv, int txq)
{
if (iwl_trans_check_stuck_queue(trans(priv), txq)) {
int ret;
- if (txq == priv->shrd->cmd_queue) {
- /*
- * validate command queue still working
- * by sending "ECHO" command
- */
- if (!iwl_cmd_echo_test(priv))
- return 0;
- else
- IWL_DEBUG_HC(priv, "echo testing fail\n");
- }
ret = iwl_force_reset(priv, IWL_FW_RESET, false);
return (ret == -EAGAIN) ? 0 : 1;
}
diff --git a/drivers/net/wireless/iwlwifi/iwl-pci.c b/drivers/net/wireless/iwlwifi/iwl-pci.c
index 3b6cc66..19cc6a8 100644
--- a/drivers/net/wireless/iwlwifi/iwl-pci.c
+++ b/drivers/net/wireless/iwlwifi/iwl-pci.c
@@ -445,10 +445,9 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00);
err = pci_enable_msi(pdev);
- if (err) {
- dev_printk(KERN_ERR, &pdev->dev, "pci_enable_msi failed");
- goto out_iounmap;
- }
+ if (err)
+ dev_printk(KERN_ERR, &pdev->dev,
+ "pci_enable_msi failed(0X%x)", err);
/* TODO: Move this away, not needed if not MSI */
/* enable rfkill interrupt: hw bug w/a */
@@ -469,7 +468,6 @@ static int iwl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
out_disable_msi:
pci_disable_msi(pdev);
-out_iounmap:
pci_iounmap(pdev, pci_bus->hw_base);
out_pci_release_regions:
pci_set_drvdata(pdev, NULL);
diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
index 8e8c75c..da34110 100644
--- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
+++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie.c
@@ -407,6 +407,7 @@ static void iwl_tx_queue_unmap(struct iwl_trans *trans, int txq_id)
struct iwl_queue *q = &txq->q;
enum dma_data_direction dma_dir;
unsigned long flags;
+ spinlock_t *lock;
if (!q->n_bd)
return;
@@ -414,19 +415,22 @@ static void iwl_tx_queue_unmap(struct iwl_trans *trans, int txq_id)
/* In the command queue, all the TBs are mapped as BIDI
* so unmap them as such.
*/
- if (txq_id == trans->shrd->cmd_queue)
+ if (txq_id == trans->shrd->cmd_queue) {
dma_dir = DMA_BIDIRECTIONAL;
- else
+ lock = &trans->hcmd_lock;
+ } else {
dma_dir = DMA_TO_DEVICE;
+ lock = &trans->shrd->sta_lock;
+ }
- spin_lock_irqsave(&trans->shrd->sta_lock, flags);
+ spin_lock_irqsave(lock, flags);
while (q->write_ptr != q->read_ptr) {
/* The read_ptr needs to bound by q->n_window */
iwlagn_txq_free_tfd(trans, txq, get_cmd_index(q, q->read_ptr),
dma_dir);
q->read_ptr = iwl_queue_inc_wrap(q->read_ptr, q->n_bd);
}
- spin_unlock_irqrestore(&trans->shrd->sta_lock, flags);
+ spin_unlock_irqrestore(lock, flags);
}
/**
diff --git a/drivers/net/wireless/libertas/cfg.c b/drivers/net/wireless/libertas/cfg.c
index ff63782..4fcd653 100644
--- a/drivers/net/wireless/libertas/cfg.c
+++ b/drivers/net/wireless/libertas/cfg.c
@@ -728,15 +728,9 @@ static void lbs_scan_worker(struct work_struct *work)
le16_to_cpu(scan_cmd->hdr.size),
lbs_ret_scan, 0);
- if (priv->scan_channel >= priv->scan_req->n_channels) {
+ if (priv->scan_channel >= priv->scan_req->n_channels)
/* Mark scan done */
- if (priv->internal_scan)
- kfree(priv->scan_req);
- else
- cfg80211_scan_done(priv->scan_req, false);
-
- priv->scan_req = NULL;
- }
+ lbs_scan_done(priv);
/* Restart network */
if (carrier)
@@ -774,6 +768,21 @@ static void _internal_start_scan(struct lbs_private *priv, bool internal,
lbs_deb_leave(LBS_DEB_CFG80211);
}
+/*
+ * Clean up priv->scan_req. Should be used to handle the allocation details.
+ */
+void lbs_scan_done(struct lbs_private *priv)
+{
+ WARN_ON(!priv->scan_req);
+
+ if (priv->internal_scan)
+ kfree(priv->scan_req);
+ else
+ cfg80211_scan_done(priv->scan_req, false);
+
+ priv->scan_req = NULL;
+}
+
static int lbs_cfg_scan(struct wiphy *wiphy,
struct net_device *dev,
struct cfg80211_scan_request *request)
diff --git a/drivers/net/wireless/libertas/cfg.h b/drivers/net/wireless/libertas/cfg.h
index a02ee15..558168c 100644
--- a/drivers/net/wireless/libertas/cfg.h
+++ b/drivers/net/wireless/libertas/cfg.h
@@ -16,6 +16,7 @@ int lbs_reg_notifier(struct wiphy *wiphy,
void lbs_send_disconnect_notification(struct lbs_private *priv);
void lbs_send_mic_failureevent(struct lbs_private *priv, u32 event);
+void lbs_scan_done(struct lbs_private *priv);
void lbs_scan_deinit(struct lbs_private *priv);
int lbs_disconnect(struct lbs_private *priv, u16 reason);
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index b03779b..39a6a7a 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -255,10 +255,8 @@ static int lbs_eth_stop(struct net_device *dev)
lbs_update_mcast(priv);
cancel_delayed_work_sync(&priv->scan_work);
- if (priv->scan_req) {
- cfg80211_scan_done(priv->scan_req, false);
- priv->scan_req = NULL;
- }
+ if (priv->scan_req)
+ lbs_scan_done(priv);
netif_carrier_off(priv->dev);
diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h
index d5eee20..e2e3eca 100644
--- a/include/net/bluetooth/rfcomm.h
+++ b/include/net/bluetooth/rfcomm.h
@@ -211,6 +211,7 @@ struct rfcomm_dlc {
#define RFCOMM_AUTH_ACCEPT 6
#define RFCOMM_AUTH_REJECT 7
#define RFCOMM_DEFER_SETUP 8
+#define RFCOMM_ENC_DROP 9
/* Scheduling flags and events */
#define RFCOMM_SCHED_WAKEUP 31
diff --git a/include/net/mac80211.h b/include/net/mac80211.h
index dc1123a..72eddd1 100644
--- a/include/net/mac80211.h
+++ b/include/net/mac80211.h
@@ -3567,8 +3567,9 @@ rate_lowest_index(struct ieee80211_supported_band *sband,
return i;
/* warn when we cannot find a rate. */
- WARN_ON(1);
+ WARN_ON_ONCE(1);
+ /* and return 0 (the lowest index) */
return 0;
}
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index b84458d..be84ae3 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -613,7 +613,7 @@ static int hci_dev_do_close(struct hci_dev *hdev)
if (!test_bit(HCI_RAW, &hdev->flags)) {
set_bit(HCI_INIT, &hdev->flags);
__hci_request(hdev, hci_reset_req, 0,
- msecs_to_jiffies(250));
+ msecs_to_jiffies(HCI_INIT_TIMEOUT));
clear_bit(HCI_INIT, &hdev->flags);
}
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 5a94eec..5caff4d 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -147,8 +147,6 @@ static int read_index_list(struct sock *sk)
hci_del_off_timer(d);
- set_bit(HCI_MGMT, &d->flags);
-
if (test_bit(HCI_SETUP, &d->flags))
continue;
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index 38b618c..4e32e18 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -1802,6 +1802,11 @@ static inline void rfcomm_process_dlcs(struct rfcomm_session *s)
continue;
}
+ if (test_bit(RFCOMM_ENC_DROP, &d->flags)) {
+ __rfcomm_dlc_close(d, ECONNREFUSED);
+ continue;
+ }
+
if (test_and_clear_bit(RFCOMM_AUTH_ACCEPT, &d->flags)) {
rfcomm_dlc_clear_timer(d);
if (d->out) {
@@ -2077,7 +2082,7 @@ static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt)
if (test_and_clear_bit(RFCOMM_SEC_PENDING, &d->flags)) {
rfcomm_dlc_clear_timer(d);
if (status || encrypt == 0x00) {
- __rfcomm_dlc_close(d, ECONNREFUSED);
+ set_bit(RFCOMM_ENC_DROP, &d->flags);
continue;
}
}
@@ -2088,7 +2093,7 @@ static void rfcomm_security_cfm(struct hci_conn *conn, u8 status, u8 encrypt)
rfcomm_dlc_set_timer(d, RFCOMM_AUTH_TIMEOUT);
continue;
} else if (d->sec_level == BT_SECURITY_HIGH) {
- __rfcomm_dlc_close(d, ECONNREFUSED);
+ set_bit(RFCOMM_ENC_DROP, &d->flags);
continue;
}
}
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index ebd7fb1..d06c65f 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -832,6 +832,12 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
if (is_multicast_ether_addr(mac))
return -EINVAL;
+ /* Only TDLS-supporting stations can add TDLS peers */
+ if ((params->sta_flags_set & BIT(NL80211_STA_FLAG_TDLS_PEER)) &&
+ !((wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) &&
+ sdata->vif.type == NL80211_IFTYPE_STATION))
+ return -ENOTSUPP;
+
sta = sta_info_alloc(sdata, mac, GFP_KERNEL);
if (!sta)
return -ENOMEM;
@@ -841,12 +847,6 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
sta_apply_parameters(local, sta, params);
- /* Only TDLS-supporting stations can add TDLS peers */
- if (test_sta_flag(sta, WLAN_STA_TDLS_PEER) &&
- !((wiphy->flags & WIPHY_FLAG_SUPPORTS_TDLS) &&
- sdata->vif.type == NL80211_IFTYPE_STATION))
- return -ENOTSUPP;
-
rate_control_rate_init(sta);
layer2_update = sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 4c3d1f5..ea10a51 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -389,6 +389,7 @@ struct ieee80211_if_managed {
unsigned long timers_running; /* used for quiesce/restart */
bool powersave; /* powersave requested for this iface */
+ bool broken_ap; /* AP is broken -- turn off powersave */
enum ieee80211_smps_mode req_smps, /* requested smps mode */
ap_smps, /* smps mode AP thinks we're in */
driver_smps_mode; /* smps mode request */
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index ba2da11..17258fe 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -637,6 +637,9 @@ static bool ieee80211_powersave_allowed(struct ieee80211_sub_if_data *sdata)
if (!mgd->powersave)
return false;
+ if (mgd->broken_ap)
+ return false;
+
if (!mgd->associated)
return false;
@@ -1489,10 +1492,21 @@ static bool ieee80211_assoc_success(struct ieee80211_work *wk,
capab_info = le16_to_cpu(mgmt->u.assoc_resp.capab_info);
if ((aid & (BIT(15) | BIT(14))) != (BIT(15) | BIT(14)))
- printk(KERN_DEBUG "%s: invalid aid value %d; bits 15:14 not "
- "set\n", sdata->name, aid);
+ printk(KERN_DEBUG
+ "%s: invalid AID value 0x%x; bits 15:14 not set\n",
+ sdata->name, aid);
aid &= ~(BIT(15) | BIT(14));
+ ifmgd->broken_ap = false;
+
+ if (aid == 0 || aid > IEEE80211_MAX_AID) {
+ printk(KERN_DEBUG
+ "%s: invalid AID value %d (out of range), turn off PS\n",
+ sdata->name, aid);
+ aid = 0;
+ ifmgd->broken_ap = true;
+ }
+
pos = mgmt->u.assoc_resp.variable;
ieee802_11_parse_elems(pos, len - (pos - (u8 *) mgmt), &elems);
diff --git a/net/mac80211/work.c b/net/mac80211/work.c
index 94472eb..6c53b6d 100644
--- a/net/mac80211/work.c
+++ b/net/mac80211/work.c
@@ -1084,14 +1084,13 @@ static void ieee80211_work_work(struct work_struct *work)
continue;
if (wk->chan != local->tmp_channel)
continue;
- if (ieee80211_work_ct_coexists(wk->chan_type,
- local->tmp_channel_type))
+ if (!ieee80211_work_ct_coexists(wk->chan_type,
+ local->tmp_channel_type))
continue;
remain_off_channel = true;
}
if (!remain_off_channel && local->tmp_channel) {
- bool on_oper_chan = ieee80211_cfg_on_oper_channel(local);
local->tmp_channel = NULL;
/* If tmp_channel wasn't operating channel, then
* we need to go back on-channel.
@@ -1101,7 +1100,7 @@ static void ieee80211_work_work(struct work_struct *work)
* we still need to do a hardware config. Currently,
* we cannot be here while scanning, however.
*/
- if (ieee80211_cfg_on_oper_channel(local) && !on_oper_chan)
+ if (!ieee80211_cfg_on_oper_channel(local))
ieee80211_hw_config(local, 0);
/* At the least, we need to disable offchannel_ps,
--
John W. Linville Someday the world will need a hero, and you
linville@tuxdriver.com might be all we have. Be ready.
[-- Attachment #2: Type: application/pgp-signature, Size: 836 bytes --]
^ permalink raw reply related
* [PATCH 8/8] tg3: Update version to 3.121
From: Matt Carlson @ 2011-11-04 19:15 UTC (permalink / raw)
To: davem; +Cc: netdev, mcarlson
This patch updates the tg3 version to 3.121.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Reviewed-by: Michael Chan <mchan@broadcom.com>
---
drivers/net/ethernet/broadcom/tg3.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index cc7349f..bf40741 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -89,10 +89,10 @@ static inline void _tg3_flag_clear(enum TG3_FLAGS flag, unsigned long *bits)
#define DRV_MODULE_NAME "tg3"
#define TG3_MAJ_NUM 3
-#define TG3_MIN_NUM 120
+#define TG3_MIN_NUM 121
#define DRV_MODULE_VERSION \
__stringify(TG3_MAJ_NUM) "." __stringify(TG3_MIN_NUM)
-#define DRV_MODULE_RELDATE "August 18, 2011"
+#define DRV_MODULE_RELDATE "November 2, 2011"
#define RESET_KIND_SHUTDOWN 0
#define RESET_KIND_INIT 1
--
1.7.3.4
^ permalink raw reply related
* [PATCH 5/8] tg3: Obtain PCI function number from device
From: Matt Carlson @ 2011-11-04 19:15 UTC (permalink / raw)
To: davem; +Cc: netdev, mcarlson
This patch adds code to attempt to obtain the PCI function number from
the device rather than accept the number handed by the kernel. In
pass-through scenarios, the function number handed by the kernel may not
reflect the true function of the device.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Reviewed-by: Michael Chan <mchan@broadcom.com>
---
drivers/net/ethernet/broadcom/tg3.c | 30 ++++++++++++++++++++++++------
drivers/net/ethernet/broadcom/tg3.h | 9 +++++++++
2 files changed, 33 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 0413e1e..6973d01 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -14230,12 +14230,30 @@ static int __devinit tg3_get_invariants(struct tg3 *tp)
val = tr32(MEMARB_MODE);
tw32(MEMARB_MODE, val | MEMARB_MODE_ENABLE);
- if (tg3_flag(tp, PCIX_MODE)) {
- pci_read_config_dword(tp->pdev,
- tp->pcix_cap + PCI_X_STATUS, &val);
- tp->pci_fn = val & 0x7;
- } else {
- tp->pci_fn = PCI_FUNC(tp->pdev->devfn) & 3;
+ tp->pci_fn = PCI_FUNC(tp->pdev->devfn) & 3;
+ if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 ||
+ tg3_flag(tp, 5780_CLASS)) {
+ if (tg3_flag(tp, PCIX_MODE)) {
+ pci_read_config_dword(tp->pdev,
+ tp->pcix_cap + PCI_X_STATUS,
+ &val);
+ tp->pci_fn = val & 0x7;
+ }
+ } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5717) {
+ tg3_read_mem(tp, NIC_SRAM_CPMU_STATUS, &val);
+ if ((val & NIC_SRAM_CPMUSTAT_SIG_MSK) ==
+ NIC_SRAM_CPMUSTAT_SIG) {
+ tp->pci_fn = val & TG3_CPMU_STATUS_FMSK_5717;
+ tp->pci_fn = tp->pci_fn ? 1 : 0;
+ }
+ } else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5719 ||
+ GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5720) {
+ tg3_read_mem(tp, NIC_SRAM_CPMU_STATUS, &val);
+ if ((val & NIC_SRAM_CPMUSTAT_SIG_MSK) ==
+ NIC_SRAM_CPMUSTAT_SIG) {
+ tp->pci_fn = (val & TG3_CPMU_STATUS_FMSK_5719) >>
+ TG3_CPMU_STATUS_FSHFT_5719;
+ }
}
/* Get eeprom hw config before calling tg3_set_power_state().
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h
index 03fab8c..acfa265 100644
--- a/drivers/net/ethernet/broadcom/tg3.h
+++ b/drivers/net/ethernet/broadcom/tg3.h
@@ -1095,6 +1095,11 @@
#define TG3_CPMU_CLCK_ORIDE 0x00003624
#define CPMU_CLCK_ORIDE_MAC_ORIDE_EN 0x80000000
+#define TG3_CPMU_STATUS 0x0000362c
+#define TG3_CPMU_STATUS_FMSK_5717 0x20000000
+#define TG3_CPMU_STATUS_FMSK_5719 0xc0000000
+#define TG3_CPMU_STATUS_FSHFT_5719 30
+
#define TG3_CPMU_CLCK_STAT 0x00003630
#define CPMU_CLCK_STAT_MAC_CLCK_MASK 0x001f0000
#define CPMU_CLCK_STAT_MAC_CLCK_62_5 0x00000000
@@ -2128,6 +2133,10 @@
#define NIC_SRAM_RGMII_EXT_IBND_RX_EN 0x00000008
#define NIC_SRAM_RGMII_EXT_IBND_TX_EN 0x00000010
+#define NIC_SRAM_CPMU_STATUS 0x00000e00
+#define NIC_SRAM_CPMUSTAT_SIG 0x0000362c
+#define NIC_SRAM_CPMUSTAT_SIG_MSK 0x0000ffff
+
#define NIC_SRAM_RX_MINI_BUFFER_DESC 0x00001000
#define NIC_SRAM_DMA_DESC_POOL_BASE 0x00002000
--
1.7.3.4
^ permalink raw reply related
* [PATCH 0/8] tg3: Driver bugfixes
From: Matt Carlson @ 2011-11-04 19:14 UTC (permalink / raw)
To: davem; +Cc: netdev, mcarlson
This patchset implements a few error path workarounds and corrects a few
problems around tg3_reset_task() scheduling.
^ permalink raw reply
* [PATCH 2/8] tg3: Fix 4k tx bd segmentation code
From: Matt Carlson @ 2011-11-04 19:14 UTC (permalink / raw)
To: davem; +Cc: netdev, mcarlson
The new 4k tx bd segmentation code had a bug in the error cleanup path.
If the driver did not map all the physical fragments, the abort path
would wind up advancing the producer index beyond the point where the
setup code stopped. This would ultimately turn into a tx recovery error
where the driver would expect the skb pointer to be set when it isn't.
This patch fixes the problem, and then makes the code a little easier to
understand.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Reviewed-by: Michael Chan <mchan@broadcom.com>
---
drivers/net/ethernet/broadcom/tg3.c | 47 ++++++++++++++++++-----------------
1 files changed, 24 insertions(+), 23 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 3590163..507b73b 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -6444,31 +6444,26 @@ static bool tg3_tx_frag_set(struct tg3_napi *tnapi, u32 *entry, u32 *budget,
hwbug = 1;
if (tg3_flag(tp, 4K_FIFO_LIMIT)) {
+ u32 prvidx = *entry;
u32 tmp_flag = flags & ~TXD_FLAG_END;
- while (len > TG3_TX_BD_DMA_MAX) {
+ while (len > TG3_TX_BD_DMA_MAX && *budget) {
u32 frag_len = TG3_TX_BD_DMA_MAX;
len -= TG3_TX_BD_DMA_MAX;
- if (len) {
- tnapi->tx_buffers[*entry].fragmented = true;
- /* Avoid the 8byte DMA problem */
- if (len <= 8) {
- len += TG3_TX_BD_DMA_MAX / 2;
- frag_len = TG3_TX_BD_DMA_MAX / 2;
- }
- } else
- tmp_flag = flags;
-
- if (*budget) {
- tg3_tx_set_bd(&tnapi->tx_ring[*entry], map,
- frag_len, tmp_flag, mss, vlan);
- (*budget)--;
- *entry = NEXT_TX(*entry);
- } else {
- hwbug = 1;
- break;
+ /* Avoid the 8byte DMA problem */
+ if (len <= 8) {
+ len += TG3_TX_BD_DMA_MAX / 2;
+ frag_len = TG3_TX_BD_DMA_MAX / 2;
}
+ tnapi->tx_buffers[*entry].fragmented = true;
+
+ tg3_tx_set_bd(&tnapi->tx_ring[*entry], map,
+ frag_len, tmp_flag, mss, vlan);
+ *budget -= 1;
+ prvidx = *entry;
+ *entry = NEXT_TX(*entry);
+
map += frag_len;
}
@@ -6476,10 +6471,11 @@ static bool tg3_tx_frag_set(struct tg3_napi *tnapi, u32 *entry, u32 *budget,
if (*budget) {
tg3_tx_set_bd(&tnapi->tx_ring[*entry], map,
len, flags, mss, vlan);
- (*budget)--;
+ *budget -= 1;
*entry = NEXT_TX(*entry);
} else {
hwbug = 1;
+ tnapi->tx_buffers[prvidx].fragmented = false;
}
}
} else {
@@ -6561,6 +6557,8 @@ static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi,
dev_kfree_skb(new_skb);
ret = -1;
} else {
+ u32 save_entry = *entry;
+
base_flags |= TXD_FLAG_END;
tnapi->tx_buffers[*entry].skb = new_skb;
@@ -6570,7 +6568,7 @@ static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi,
if (tg3_tx_frag_set(tnapi, entry, budget, new_addr,
new_skb->len, base_flags,
mss, vlan)) {
- tg3_tx_skb_unmap(tnapi, *entry, 0);
+ tg3_tx_skb_unmap(tnapi, save_entry, 0);
dev_kfree_skb(new_skb);
ret = -1;
}
@@ -6786,11 +6784,14 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (dma_mapping_error(&tp->pdev->dev, mapping))
goto dma_error;
- if (tg3_tx_frag_set(tnapi, &entry, &budget, mapping,
+ if (!budget ||
+ tg3_tx_frag_set(tnapi, &entry, &budget, mapping,
len, base_flags |
((i == last) ? TXD_FLAG_END : 0),
- tmp_mss, vlan))
+ tmp_mss, vlan)) {
would_hit_hwbug = 1;
+ break;
+ }
}
}
--
1.7.3.4
^ permalink raw reply related
* [PATCH 4/8] tg3: Fix irq alloc error cleanup path
From: Matt Carlson @ 2011-11-04 19:15 UTC (permalink / raw)
To: davem; +Cc: netdev, mcarlson, Ben Li, Akinobu Mita
This patch fixes a bug where the irq error cleanup path did not free all
the resources it allocated.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Signed-off-by: Ben Li <benli@broadcom.com>
Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
Reviewed-by: Michael Chan <mchan@broadcom.com>
---
drivers/net/ethernet/broadcom/tg3.c | 9 ++++-----
1 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 3a75179..0413e1e 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -9677,15 +9677,14 @@ static int tg3_open(struct net_device *dev)
struct tg3_napi *tnapi = &tp->napi[i];
err = tg3_request_irq(tp, i);
if (err) {
- for (i--; i >= 0; i--)
+ for (i--; i >= 0; i--) {
+ tnapi = &tp->napi[i];
free_irq(tnapi->irq_vec, tnapi);
- break;
+ }
+ goto err_out2;
}
}
- if (err)
- goto err_out2;
-
tg3_full_lock(tp, 0);
err = tg3_init_hw(tp, 1);
--
1.7.3.4
^ permalink raw reply related
* [PATCH 1/8] tg3: Fix APE mutex init and use
From: Matt Carlson @ 2011-11-04 19:14 UTC (permalink / raw)
To: davem; +Cc: netdev, mcarlson, Michael Chan
APE mutex register blocks are shared by all ports of multiport devices.
For some mutexing purposes, each function is assigned their own
register. For other cases, each function is assigned its own request
and grant bits of a single register. For the latter cases, the tg3
driver is incorrectly allowing each function to use the same set of
grant / request bits. This patch fixes the code so that each function
uses the appropriate bitset.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Signed-off-by: Michael Chan <mchan@broadcom.com>
---
drivers/net/ethernet/broadcom/tg3.c | 44 ++++++++++++++++++----------------
drivers/net/ethernet/broadcom/tg3.h | 10 +++++--
2 files changed, 30 insertions(+), 24 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 161cbbb..3590163 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -628,19 +628,23 @@ static void tg3_ape_lock_init(struct tg3 *tp)
regbase = TG3_APE_PER_LOCK_GRANT;
/* Make sure the driver hasn't any stale locks. */
- for (i = 0; i < 8; i++) {
- if (i == TG3_APE_LOCK_GPIO)
- continue;
- tg3_ape_write32(tp, regbase + 4 * i, APE_LOCK_GRANT_DRIVER);
+ for (i = TG3_APE_LOCK_PHY0; i <= TG3_APE_LOCK_GPIO; i++) {
+ switch (i) {
+ case TG3_APE_LOCK_PHY0:
+ case TG3_APE_LOCK_PHY1:
+ case TG3_APE_LOCK_PHY2:
+ case TG3_APE_LOCK_PHY3:
+ bit = APE_LOCK_GRANT_DRIVER;
+ break;
+ default:
+ if (!tp->pci_fn)
+ bit = APE_LOCK_GRANT_DRIVER;
+ else
+ bit = 1 << tp->pci_fn;
+ }
+ tg3_ape_write32(tp, regbase + 4 * i, bit);
}
- /* Clear the correct bit of the GPIO lock too. */
- if (!tp->pci_fn)
- bit = APE_LOCK_GRANT_DRIVER;
- else
- bit = 1 << tp->pci_fn;
-
- tg3_ape_write32(tp, regbase + 4 * TG3_APE_LOCK_GPIO, bit);
}
static int tg3_ape_lock(struct tg3 *tp, int locknum)
@@ -658,6 +662,10 @@ static int tg3_ape_lock(struct tg3 *tp, int locknum)
return 0;
case TG3_APE_LOCK_GRC:
case TG3_APE_LOCK_MEM:
+ if (!tp->pci_fn)
+ bit = APE_LOCK_REQ_DRIVER;
+ else
+ bit = 1 << tp->pci_fn;
break;
default:
return -EINVAL;
@@ -673,11 +681,6 @@ static int tg3_ape_lock(struct tg3 *tp, int locknum)
off = 4 * locknum;
- if (locknum != TG3_APE_LOCK_GPIO || !tp->pci_fn)
- bit = APE_LOCK_REQ_DRIVER;
- else
- bit = 1 << tp->pci_fn;
-
tg3_ape_write32(tp, req + off, bit);
/* Wait for up to 1 millisecond to acquire lock. */
@@ -710,6 +713,10 @@ static void tg3_ape_unlock(struct tg3 *tp, int locknum)
return;
case TG3_APE_LOCK_GRC:
case TG3_APE_LOCK_MEM:
+ if (!tp->pci_fn)
+ bit = APE_LOCK_GRANT_DRIVER;
+ else
+ bit = 1 << tp->pci_fn;
break;
default:
return;
@@ -720,11 +727,6 @@ static void tg3_ape_unlock(struct tg3 *tp, int locknum)
else
gnt = TG3_APE_PER_LOCK_GRANT;
- if (locknum != TG3_APE_LOCK_GPIO || !tp->pci_fn)
- bit = APE_LOCK_GRANT_DRIVER;
- else
- bit = 1 << tp->pci_fn;
-
tg3_ape_write32(tp, gnt + 4 * locknum, bit);
}
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h
index f32f288..03fab8c 100644
--- a/drivers/net/ethernet/broadcom/tg3.h
+++ b/drivers/net/ethernet/broadcom/tg3.h
@@ -2344,9 +2344,13 @@
#define APE_PER_LOCK_GRANT_DRIVER 0x00001000
/* APE convenience enumerations. */
-#define TG3_APE_LOCK_GRC 1
-#define TG3_APE_LOCK_MEM 4
-#define TG3_APE_LOCK_GPIO 7
+#define TG3_APE_LOCK_PHY0 0
+#define TG3_APE_LOCK_GRC 1
+#define TG3_APE_LOCK_PHY1 2
+#define TG3_APE_LOCK_PHY2 3
+#define TG3_APE_LOCK_MEM 4
+#define TG3_APE_LOCK_PHY3 5
+#define TG3_APE_LOCK_GPIO 7
#define TG3_EEPROM_SB_F1R2_MBA_OFF 0x10
--
1.7.3.4
^ permalink raw reply related
* [PATCH 6/8] tg3: Schedule at most one tg3_reset_task run
From: Matt Carlson @ 2011-11-04 19:15 UTC (permalink / raw)
To: davem; +Cc: netdev, mcarlson
It is possible for multiple threads in the tg3 driver to each attempt to
schedule a run of tg3_reset_task(). The multiple tg3_reset_task
executions could all wind up on the same queue (and execute serially) or
wind up on the queues of another processor (which could execute in
parallel). Either scenario is not what was truly desired.
This patch adds a new flag, TG3_FLAG_RESET_TASK_PENDING, and uses it to
determine whether or not to schedule another run of tg3_reset_task().
With the new flag comes two new functions to facilitate scheduling and
descheduling of tg3_reset_task().
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Reviewed-by: Michael Chan <mchan@broadcom.com>
---
drivers/net/ethernet/broadcom/tg3.c | 33 ++++++++++++++++++++++++---------
drivers/net/ethernet/broadcom/tg3.h | 1 +
2 files changed, 25 insertions(+), 9 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 6973d01..d4a85b7 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -5929,6 +5929,18 @@ static int tg3_poll_work(struct tg3_napi *tnapi, int work_done, int budget)
return work_done;
}
+static inline void tg3_reset_task_schedule(struct tg3 *tp)
+{
+ if (!test_and_set_bit(TG3_FLAG_RESET_TASK_PENDING, tp->tg3_flags))
+ schedule_work(&tp->reset_task);
+}
+
+static inline void tg3_reset_task_cancel(struct tg3 *tp)
+{
+ cancel_work_sync(&tp->reset_task);
+ tg3_flag_clear(tp, RESET_TASK_PENDING);
+}
+
static int tg3_poll_msix(struct napi_struct *napi, int budget)
{
struct tg3_napi *tnapi = container_of(napi, struct tg3_napi, napi);
@@ -5969,7 +5981,7 @@ static int tg3_poll_msix(struct napi_struct *napi, int budget)
tx_recovery:
/* work_done is guaranteed to be less than budget. */
napi_complete(napi);
- schedule_work(&tp->reset_task);
+ tg3_reset_task_schedule(tp);
return work_done;
}
@@ -6004,7 +6016,7 @@ static void tg3_process_error(struct tg3 *tp)
tg3_dump_state(tp);
tg3_flag_set(tp, ERROR_PROCESSED);
- schedule_work(&tp->reset_task);
+ tg3_reset_task_schedule(tp);
}
static int tg3_poll(struct napi_struct *napi, int budget)
@@ -6051,7 +6063,7 @@ static int tg3_poll(struct napi_struct *napi, int budget)
tx_recovery:
/* work_done is guaranteed to be less than budget. */
napi_complete(napi);
- schedule_work(&tp->reset_task);
+ tg3_reset_task_schedule(tp);
return work_done;
}
@@ -6345,6 +6357,7 @@ static void tg3_reset_task(struct work_struct *work)
tg3_full_lock(tp, 0);
if (!netif_running(tp->dev)) {
+ tg3_flag_clear(tp, RESET_TASK_PENDING);
tg3_full_unlock(tp);
return;
}
@@ -6382,6 +6395,8 @@ out:
if (!err)
tg3_phy_start(tp);
+
+ tg3_flag_clear(tp, RESET_TASK_PENDING);
}
static void tg3_tx_timeout(struct net_device *dev)
@@ -6393,7 +6408,7 @@ static void tg3_tx_timeout(struct net_device *dev)
tg3_dump_state(tp);
}
- schedule_work(&tp->reset_task);
+ tg3_reset_task_schedule(tp);
}
/* Test for DMA buffers crossing any 4GB boundaries: 4G, 8G, etc */
@@ -9228,7 +9243,7 @@ static void tg3_timer(unsigned long __opaque)
if (!(tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) {
tg3_flag_set(tp, RESTART_TIMER);
spin_unlock(&tp->lock);
- schedule_work(&tp->reset_task);
+ tg3_reset_task_schedule(tp);
return;
}
}
@@ -9785,7 +9800,7 @@ static int tg3_close(struct net_device *dev)
struct tg3 *tp = netdev_priv(dev);
tg3_napi_disable(tp);
- cancel_work_sync(&tp->reset_task);
+ tg3_reset_task_cancel(tp);
netif_tx_stop_all_queues(dev);
@@ -15685,7 +15700,7 @@ static void __devexit tg3_remove_one(struct pci_dev *pdev)
if (tp->fw)
release_firmware(tp->fw);
- cancel_work_sync(&tp->reset_task);
+ tg3_reset_task_cancel(tp);
if (tg3_flag(tp, USE_PHYLIB)) {
tg3_phy_fini(tp);
@@ -15719,7 +15734,7 @@ static int tg3_suspend(struct device *device)
if (!netif_running(dev))
return 0;
- flush_work_sync(&tp->reset_task);
+ tg3_reset_task_cancel(tp);
tg3_phy_stop(tp);
tg3_netif_stop(tp);
@@ -15835,7 +15850,7 @@ static pci_ers_result_t tg3_io_error_detected(struct pci_dev *pdev,
tg3_flag_clear(tp, RESTART_TIMER);
/* Want to make sure that the reset task doesn't run */
- cancel_work_sync(&tp->reset_task);
+ tg3_reset_task_cancel(tp);
tg3_flag_clear(tp, TX_RECOVERY_PENDING);
tg3_flag_clear(tp, RESTART_TIMER);
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h
index acfa265..610fd84 100644
--- a/drivers/net/ethernet/broadcom/tg3.h
+++ b/drivers/net/ethernet/broadcom/tg3.h
@@ -2922,6 +2922,7 @@ enum TG3_FLAGS {
TG3_FLAG_APE_HAS_NCSI,
TG3_FLAG_5717_PLUS,
TG3_FLAG_4K_FIFO_LIMIT,
+ TG3_FLAG_RESET_TASK_PENDING,
/* Add new flags before this comment and TG3_FLAG_NUMBER_OF_FLAGS */
TG3_FLAG_NUMBER_OF_FLAGS, /* Last entry in enum TG3_FLAGS */
--
1.7.3.4
^ permalink raw reply related
* [PATCH 3/8] tg3: Fix 4k skb error recovery path
From: Matt Carlson @ 2011-11-04 19:15 UTC (permalink / raw)
To: davem; +Cc: netdev, mcarlson
On the error recovery resource unwind path, it is possible for the
driver to attempt to unmap a fragment that hadn't been mapped. This
patch fixes the problem by correcting the "last" parameter supplied.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Reviewed-by: Michael Chan <mchan@broadcom.com>
---
drivers/net/ethernet/broadcom/tg3.c | 16 ++++++++--------
1 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index 507b73b..3a75179 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -6507,7 +6507,7 @@ static void tg3_tx_skb_unmap(struct tg3_napi *tnapi, u32 entry, int last)
txb = &tnapi->tx_buffers[entry];
}
- for (i = 0; i < last; i++) {
+ for (i = 0; i <= last; i++) {
const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
entry = NEXT_TX(entry);
@@ -6568,7 +6568,7 @@ static int tigon3_dma_hwbug_workaround(struct tg3_napi *tnapi,
if (tg3_tx_frag_set(tnapi, entry, budget, new_addr,
new_skb->len, base_flags,
mss, vlan)) {
- tg3_tx_skb_unmap(tnapi, save_entry, 0);
+ tg3_tx_skb_unmap(tnapi, save_entry, -1);
dev_kfree_skb(new_skb);
ret = -1;
}
@@ -6758,11 +6758,10 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
if (tg3_tx_frag_set(tnapi, &entry, &budget, mapping, len, base_flags |
((skb_shinfo(skb)->nr_frags == 0) ? TXD_FLAG_END : 0),
- mss, vlan))
+ mss, vlan)) {
would_hit_hwbug = 1;
-
/* Now loop through additional data fragments, and queue them. */
- if (skb_shinfo(skb)->nr_frags > 0) {
+ } else if (skb_shinfo(skb)->nr_frags > 0) {
u32 tmp_mss = mss;
if (!tg3_flag(tp, HW_TSO_1) &&
@@ -6831,7 +6830,7 @@ static netdev_tx_t tg3_start_xmit(struct sk_buff *skb, struct net_device *dev)
return NETDEV_TX_OK;
dma_error:
- tg3_tx_skb_unmap(tnapi, tnapi->tx_prod, i);
+ tg3_tx_skb_unmap(tnapi, tnapi->tx_prod, --i);
tnapi->tx_buffers[tnapi->tx_prod].skb = NULL;
drop:
dev_kfree_skb(skb);
@@ -7284,7 +7283,8 @@ static void tg3_free_rings(struct tg3 *tp)
if (!skb)
continue;
- tg3_tx_skb_unmap(tnapi, i, skb_shinfo(skb)->nr_frags);
+ tg3_tx_skb_unmap(tnapi, i,
+ skb_shinfo(skb)->nr_frags - 1);
dev_kfree_skb_any(skb);
}
@@ -11523,7 +11523,7 @@ static int tg3_run_loopback(struct tg3 *tp, u32 pktsz, bool tso_loopback)
break;
}
- tg3_tx_skb_unmap(tnapi, tnapi->tx_prod - 1, 0);
+ tg3_tx_skb_unmap(tnapi, tnapi->tx_prod - 1, -1);
dev_kfree_skb(skb);
if (tx_idx != tnapi->tx_prod)
--
1.7.3.4
^ permalink raw reply related
* [PATCH 7/8] tg3: Eliminate timer race with reset_task
From: Matt Carlson @ 2011-11-04 19:15 UTC (permalink / raw)
To: davem; +Cc: netdev, mcarlson
During shutdown, it is impossible to reliably disable the timer and
reset_task threads. Each thread can schedule the other, which leads to
shutdown code that chases its tail.
To fix the problem, this patch removes the ability of tg3_reset_task to
schedule a new timer thread. To support this change, tg3_timer no
longer terminates itself, but rather goes into a polling mode.
Signed-off-by: Matt Carlson <mcarlson@broadcom.com>
Reviewed-by: Michael Chan <mchan@broadcom.com>
---
drivers/net/ethernet/broadcom/tg3.c | 14 ++------------
drivers/net/ethernet/broadcom/tg3.h | 1 -
2 files changed, 2 insertions(+), 13 deletions(-)
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index d4a85b7..cc7349f 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -6352,7 +6352,6 @@ static void tg3_reset_task(struct work_struct *work)
{
struct tg3 *tp = container_of(work, struct tg3, reset_task);
int err;
- unsigned int restart_timer;
tg3_full_lock(tp, 0);
@@ -6370,9 +6369,6 @@ static void tg3_reset_task(struct work_struct *work)
tg3_full_lock(tp, 1);
- restart_timer = tg3_flag(tp, RESTART_TIMER);
- tg3_flag_clear(tp, RESTART_TIMER);
-
if (tg3_flag(tp, TX_RECOVERY_PENDING)) {
tp->write32_tx_mbox = tg3_write32_tx_mbox;
tp->write32_rx_mbox = tg3_write_flush_reg32;
@@ -6387,9 +6383,6 @@ static void tg3_reset_task(struct work_struct *work)
tg3_netif_start(tp);
- if (restart_timer)
- mod_timer(&tp->timer, jiffies + 1);
-
out:
tg3_full_unlock(tp);
@@ -9218,7 +9211,7 @@ static void tg3_timer(unsigned long __opaque)
{
struct tg3 *tp = (struct tg3 *) __opaque;
- if (tp->irq_sync)
+ if (tp->irq_sync || tg3_flag(tp, RESET_TASK_PENDING))
goto restart_timer;
spin_lock(&tp->lock);
@@ -9241,10 +9234,9 @@ static void tg3_timer(unsigned long __opaque)
}
if (!(tr32(WDMAC_MODE) & WDMAC_MODE_ENABLE)) {
- tg3_flag_set(tp, RESTART_TIMER);
spin_unlock(&tp->lock);
tg3_reset_task_schedule(tp);
- return;
+ goto restart_timer;
}
}
@@ -15847,12 +15839,10 @@ static pci_ers_result_t tg3_io_error_detected(struct pci_dev *pdev,
tg3_netif_stop(tp);
del_timer_sync(&tp->timer);
- tg3_flag_clear(tp, RESTART_TIMER);
/* Want to make sure that the reset task doesn't run */
tg3_reset_task_cancel(tp);
tg3_flag_clear(tp, TX_RECOVERY_PENDING);
- tg3_flag_clear(tp, RESTART_TIMER);
netif_device_detach(netdev);
diff --git a/drivers/net/ethernet/broadcom/tg3.h b/drivers/net/ethernet/broadcom/tg3.h
index 610fd84..94b4bd0 100644
--- a/drivers/net/ethernet/broadcom/tg3.h
+++ b/drivers/net/ethernet/broadcom/tg3.h
@@ -2879,7 +2879,6 @@ enum TG3_FLAGS {
TG3_FLAG_JUMBO_CAPABLE,
TG3_FLAG_CHIP_RESETTING,
TG3_FLAG_INIT_COMPLETE,
- TG3_FLAG_RESTART_TIMER,
TG3_FLAG_TSO_BUG,
TG3_FLAG_IS_5788,
TG3_FLAG_MAX_RXPEND_64,
--
1.7.3.4
^ permalink raw reply related
* [patch] bonding: comparing a u8 with -1 is always false
From: Dan Carpenter @ 2011-11-04 18:21 UTC (permalink / raw)
To: Weiping Pan
Cc: Jay Vosburgh, Andy Gospodarek, netdev, David S. Miller,
kernel-janitors
slave->duplex is a u8 type so the in bond_info_show_slave() when we
check "if (slave->duplex == -1)", it's always false.
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index b2b9109..b0c5772 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -560,8 +560,8 @@ static int bond_update_speed_duplex(struct slave *slave)
u32 slave_speed;
int res;
- slave->speed = -1;
- slave->duplex = -1;
+ slave->speed = SPEED_UNKNOWN;
+ slave->duplex = DUPLEX_UNKNOWN;
res = __ethtool_get_settings(slave_dev, &ecmd);
if (res < 0)
diff --git a/drivers/net/bonding/bond_procfs.c b/drivers/net/bonding/bond_procfs.c
index 2acf0b0..ad284ba 100644
--- a/drivers/net/bonding/bond_procfs.c
+++ b/drivers/net/bonding/bond_procfs.c
@@ -158,12 +158,12 @@ static void bond_info_show_slave(struct seq_file *seq,
seq_printf(seq, "\nSlave Interface: %s\n", slave->dev->name);
seq_printf(seq, "MII Status: %s\n",
(slave->link == BOND_LINK_UP) ? "up" : "down");
- if (slave->speed == -1)
+ if (slave->speed == SPEED_UNKNOWN)
seq_printf(seq, "Speed: %s\n", "Unknown");
else
seq_printf(seq, "Speed: %d Mbps\n", slave->speed);
- if (slave->duplex == -1)
+ if (slave->duplex == DUPLEX_UNKNOWN)
seq_printf(seq, "Duplex: %s\n", "Unknown");
else
seq_printf(seq, "Duplex: %s\n", slave->duplex ? "full" : "half");
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index 45f00b6..de33de1 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -1097,10 +1097,12 @@ struct ethtool_ops {
#define SPEED_1000 1000
#define SPEED_2500 2500
#define SPEED_10000 10000
+#define SPEED_UNKNOWN -1
/* Duplex, half or full. */
#define DUPLEX_HALF 0x00
#define DUPLEX_FULL 0x01
+#define DUPLEX_UNKNOWN 0xff
/* Which connector port. */
#define PORT_TP 0x00
^ permalink raw reply related
* Re: [net-next 03/10] seeq: Move the SEEQ drivers
From: Russell King - ARM Linux @ 2011-11-04 17:24 UTC (permalink / raw)
To: Jeff Kirsher, torvalds; +Cc: davem, netdev, gospo, sassmann, Hamish Coleman
In-Reply-To: <1313134384-7287-4-git-send-email-jeffrey.t.kirsher@intel.com>
Okay, this is the only patch I saw (for the SEEQ drivers), but I notice
that more of the ARM drivers have moved. The result is not nice. Or
even workable.
While looking for my ether1, ether3 and etherh drivers in Kconfig, I
enable every option which is presented to me under the new 'ethernet
drivers' stuff. I'm offered my ether3 driver under the SEEQ stuff -
that's fine. But what about the rest?
Well...
drivers/net/ethernet/intel/Kconfig:
config NET_VENDOR_INTEL
bool "Intel devices"
default y
depends on PCI || PCI_MSI
drivers/net/ethernet/i825xx/Kconfig:
config NET_VENDOR_I825XX
bool "Intel (82586/82593/82596) devices"
default y
depends on NET_VENDOR_INTEL && (ISA || ISA_DMA_API || ARM || \
ARCH_ACORN || MCA || MCA_LEGACY || SNI_RM || SUN3 || \
GSC || BVME6000 || MVME16x || EXPERIMENTAL)
if NET_VENDOR_I825XX
config ARM_ETHER1
tristate "Acorn Ether1 support"
depends on ARM && ARCH_ACORN
This is NOT a PCI driver, yet it has ended up with a requirement for
CONFIG_PCI to be set, which is nonsense for this platform because it
has no PCI.
What about etherh?
drivers/net/ethernet/natsemi/Kconfig:
config NET_VENDOR_NATSEMI
bool "National Semi-conductor devices"
default y
depends on MCA || MAC || MACH_JAZZ || PCI || XTENSA_PLATFORM_XT2000
drivers/net/ethernet/8390/Kconfig:
config NET_VENDOR_8390
bool "National Semi-conductor 8390 devices"
default y
depends on NET_VENDOR_NATSEMI && (AMIGA_PCMCIA || PCI || SUPERH || \
ISA || MCA || EISA || MAC || M32R || MACH_TX49XX || \
MCA_LEGACY || H8300 || ARM || MIPS || ZORRO || PCMCIA || \
EXPERIMENTAL)
if NET_VENDOR_8390
config ARM_ETHERH
tristate "I-cubed EtherH/ANT EtherM support"
depends on ARM && ARCH_ACORN
Again, exactly the same thing.
Thankfully, ARM_AM79C961A is right, so that's two out of five correct.
I've no idea what the right solution is to this complex maze of Kconfig
stuff. Do I through an 'ARM' into the NET_VENDOR_INTEL and
NET_VENDOR_NATSEMI dependencies?
While I realise this is a big change, and bugs like this are likely, it
would've been nice to be copied on more of the patches which affect
drivers I maintain.
^ permalink raw reply
* Re: [PATCH net v2 6/8] forcedeth: Fix a race during rmmod of forcedeth
From: David Decotigny @ 2011-11-04 17:22 UTC (permalink / raw)
To: Ben Hutchings
Cc: netdev, linux-kernel, David S. Miller, Ian Campbell, Eric Dumazet,
Jeff Kirsher, Jiri Pirko, Joe Perches, Szymon Janc, Salman Qazi
In-Reply-To: <1320378386.3079.56.camel@deadeye>
Ben,
Thank you for your comments. I understand this patch needs more work.
So I am going to remove it from this series for now and work on it in
isolation.
Regards,
On Thu, Nov 3, 2011 at 8:46 PM, Ben Hutchings <bhutchings@solarflare.com> wrote:
> On Thu, 2011-11-03 at 18:41 -0700, David Decotigny wrote:
>> From: Salman Qazi <sqazi@google.com>
>>
>> The race was between del_timer_sync and nv_do_stats_poll called through
>> nv_get_ethtool_stats.
>
> I don't think so. nv_close() and nv_get_ethtool_stats() are both called
> with RTNL held.
>
> Calling the timer function from nv_get_ethtool_stats is very likely part
> of the problem though, so why don't you stop doing that?
>
> [...]
>> diff --git a/drivers/net/ethernet/nvidia/forcedeth.c b/drivers/net/ethernet/nvidia/forcedeth.c
>> index 0af12a8..7996782 100644
>> --- a/drivers/net/ethernet/nvidia/forcedeth.c
>> +++ b/drivers/net/ethernet/nvidia/forcedeth.c
>> @@ -3937,6 +3937,10 @@ static void nv_poll_controller(struct net_device *dev)
>> }
>> #endif
>>
>> +/* No locking is needed as long as this is in the timer
>> + * callback. However, any other callers must call this
>> + * function with np->lock held.
>> + */
>
> So long as this function is used by all of (1) the timer function (2)
> the ndo_get_stats implementation (3) the ethtool get_stats
> implementation, it can most certainly be called concurrently on multiple
> processors.
>
> You could have (2) and (3) return the last polled stats and not poll the
> hardware themselves, but you would need to use the functions from
> <linux/u64_stats_sync.h> to avoid word-tearing on 32-bit architectures.
>
>> static void nv_do_stats_poll(unsigned long data)
>> {
>> struct net_device *dev = (struct net_device *) data;
>> @@ -4589,12 +4593,17 @@ static int nv_get_sset_count(struct net_device *dev, int sset)
>>
>> static void nv_get_ethtool_stats(struct net_device *dev, struct ethtool_stats *estats, u64 *buffer)
>> {
>> + unsigned long flags;
>> struct fe_priv *np = netdev_priv(dev);
>>
>> + spin_lock_irqsave(&np->lock, flags);
>> +
>> /* update stats */
>> nv_do_stats_poll((unsigned long)dev);
>>
>> memcpy(buffer, &np->estats, nv_get_sset_count(dev, ETH_SS_STATS)*sizeof(u64));
>> +
>> + spin_unlock_irqrestore(&np->lock, flags);
>
> This function is not called from interrupt context.
>
>> }
>>
>> static int nv_link_test(struct net_device *dev)
>> @@ -5189,13 +5198,13 @@ static int nv_close(struct net_device *dev)
>>
>> spin_lock_irq(&np->lock);
>> np->in_shutdown = 1;
>> + del_timer_sync(&np->stats_poll);
>> spin_unlock_irq(&np->lock);
>> nv_napi_disable(dev);
>> synchronize_irq(np->pci_dev->irq);
>>
>> del_timer_sync(&np->oom_kick);
>> del_timer_sync(&np->nic_poll);
>> - del_timer_sync(&np->stats_poll);
>>
>> netif_stop_queue(dev);
>> spin_lock_irq(&np->lock);
>
> I don't believe this code movement is helpful.
>
> 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 net v2 1/8] forcedeth: Improve stats counters
From: David Decotigny @ 2011-11-04 17:17 UTC (permalink / raw)
To: Stephen Hemminger
Cc: netdev, linux-kernel, David S. Miller, Ian Campbell, Eric Dumazet,
Jeff Kirsher, Jiri Pirko, Joe Perches, Szymon Janc,
Mandeep Baines
In-Reply-To: <20111104075414.3f674ba8@nehalam.linuxnetplumber.net>
Hi all,
On Fri, Nov 4, 2011 at 7:54 AM, Stephen Hemminger <shemminger@vyatta.com> wrote:
> Why not convert it to 64 bit stats as well.
Doing it for next version of patch series. So please hang on...
Regards,
^ permalink raw reply
* Re: [GIT] Networking
From: Ben Greear @ 2011-11-04 17:07 UTC (permalink / raw)
To: Johannes Berg
Cc: Linus Torvalds, David Miller, Grumbach, Emmanuel, Guy, Wey-Yi W,
John W. Linville, akpm@linux-foundation.org,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
Stanislaw Gruszka
In-Reply-To: <1320426222.3969.121.camel@jlt3.sipsolutions.net>
On 11/04/2011 10:03 AM, Johannes Berg wrote:
> On Tue, 2011-10-25 at 12:26 +0000, Linus Torvalds wrote:
>> On Tue, Oct 25, 2011 at 12:32 PM, David Miller<davem@davemloft.net> wrote:
>>>
>>> The most visible thing in here is the reorganization of the drivers
>>> under drivers/net.
>>
>> Nope, the most visible thing are some new annoying warnings, that seem
>> absolutely broken.
>>
>> At the very minimum, that WARN_ON(1) should be a WARN_ON_ONCE() or
>> something like that. Because showing it over an dover again is not
>> helpful.
>>
>> Added the people who signed off on the changes to the affected files,
>> since they hopefully know why this happens and can fix it..
>
> Sorry for the late reply.
>
> I think this was actually caused by some changes from Ben Greear
> "optimising" stuff in net/mac80211/work.c and keeping the wrong channel,
> Stanislaw was also looking at this at some point I think. I agree that
> it would be good to change to WARN_ON_ONCE(), will do that.
>
> The warning itself has been around forever, but the fact that it
> triggers now is probably related to the channel work& band switches.
There are patches for the work_work bugs I introduced, and they
are in wireless-testing, and were CC'd to stable as far as I
can tell.
Thanks,
Ben
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply
* Re: [GIT] Networking
From: Johannes Berg @ 2011-11-04 17:03 UTC (permalink / raw)
To: Linus Torvalds
Cc: David Miller, Grumbach, Emmanuel, Guy, Wey-Yi W, John W. Linville,
akpm@linux-foundation.org, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, Stanislaw Gruszka
In-Reply-To: <CA+55aFzkZofnUmBOGVvmNKyA0_FApo73xZ7J=aevbHPS_0+xKQ@mail.gmail.com>
On Tue, 2011-10-25 at 12:26 +0000, Linus Torvalds wrote:
> On Tue, Oct 25, 2011 at 12:32 PM, David Miller <davem@davemloft.net> wrote:
> >
> > The most visible thing in here is the reorganization of the drivers
> > under drivers/net.
>
> Nope, the most visible thing are some new annoying warnings, that seem
> absolutely broken.
>
> At the very minimum, that WARN_ON(1) should be a WARN_ON_ONCE() or
> something like that. Because showing it over an dover again is not
> helpful.
>
> Added the people who signed off on the changes to the affected files,
> since they hopefully know why this happens and can fix it..
Sorry for the late reply.
I think this was actually caused by some changes from Ben Greear
"optimising" stuff in net/mac80211/work.c and keeping the wrong channel,
Stanislaw was also looking at this at some point I think. I agree that
it would be good to change to WARN_ON_ONCE(), will do that.
The warning itself has been around forever, but the fact that it
triggers now is probably related to the channel work & band switches.
johannes
^ permalink raw reply
* Re: [PATCH] net: add calxeda xgmac ethernet driver
From: Grant Likely @ 2011-11-04 16:57 UTC (permalink / raw)
To: Rob Herring
Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
devicetree-discuss-uLR06cmDAlY/bJ5BZ2RsiQ, Rob Herring
In-Reply-To: <CACxGe6sAFUwQc5Nk=gGLC+si-_C32AWu=E14vBkSm7YCFhazFg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Fri, Nov 4, 2011 at 12:57 PM, Grant Likely <grant.likely-s3s/WqlpOiPyB63q8FvJNQ@public.gmane.org> wrote:
> On Wed, Oct 26, 2011 at 10:56 PM, Rob Herring <robherring2-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org> wrote:
>> From: Rob Herring <rob.herring-bsGFqQB8/DxBDgjK7y7TUQ@public.gmane.org>
>>
>> Add support for the XGMAC 10Gb ethernet device in the Calxeda Highbank
>> SOC.
>>
>> Signed-off-by: Rob Herring <rob.herring-bsGFqQB8/DxBDgjK7y7TUQ@public.gmane.org>
>
> Sinker question: is this a driver for an entirely new GMAC device
> (designed from scratch) or is it based on an existing IP block?
s/sinker/stinker/
g.
^ permalink raw reply
* Re: [PATCH] net: add calxeda xgmac ethernet driver
From: Grant Likely @ 2011-11-04 16:57 UTC (permalink / raw)
To: Rob Herring; +Cc: netdev, devicetree-discuss, Rob Herring
In-Reply-To: <1319684206-473-1-git-send-email-robherring2@gmail.com>
On Wed, Oct 26, 2011 at 10:56 PM, Rob Herring <robherring2@gmail.com> wrote:
> From: Rob Herring <rob.herring@calxeda.com>
>
> Add support for the XGMAC 10Gb ethernet device in the Calxeda Highbank
> SOC.
>
> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Sinker question: is this a driver for an entirely new GMAC device
(designed from scratch) or is it based on an existing IP block?
> +/**
> + * xgmac_init - Entry point for the driver
> + * Description: This function is the entry point for the driver.
> + */
> +static int __init xgmac_init(void)
> +{
> + return platform_driver_register(&xgmac_driver);
> +}
> +module_init(xgmac_init);
> +
> +/**
> + * xgmac_cleanup_module - Cleanup routine for the driver
> + * Description: This function is the cleanup routine for the driver.
> + */
> +static void __exit xgmac_exit(void)
> +{
> + platform_driver_unregister(&xgmac_driver);
> +}
> +module_exit(xgmac_exit);
You can drop some boilerplate with module_platform_driver() now.
g.
^ permalink raw reply
* Re: [RFC] The Linux kernel IPv6 stack don't follow the RFC 4942 recommendation
From: Eric Dumazet @ 2011-11-04 16:24 UTC (permalink / raw)
To: François-Xavier Le Bail; +Cc: netdev@vger.kernel.org
In-Reply-To: <1320417988.69298.YahooMailNeo@web126013.mail.ne1.yahoo.com>
Le vendredi 04 novembre 2011 à 07:46 -0700, François-Xavier Le Bail a
écrit :
> Hi,
>
> I do some tests on a Linux 3.0 kernel with IPv6 forwarding mode enabled.
>
> When I ping (ICMPv6 echo request) on one of its Subnet-Router anycast addresses
> (SRAA, http://tools.ietf.org/html/rfc4291#section-2.6.1),
> the Linux kernel reply with an unicast source address, not the anycast one.
>
> When I send an IPv6 UDP packet to a server on Linux on one of its SRAA,
> the Linux kernel build a reply with an unicast source address, not the anycast one.
>
Nothing in the kernel builds a reply to an UDP packet.
I would say the user application is responsible to build an answer, and
chose appropriate source address.
If your application uses a ANY_ADDR bind, then it must appropriate
action so that a good source address is used in answers.
In case of IPv6 socket, I advise you take a look at IPV6_PKTINFO /
IPV6_RECVPKTINFO options.
> The RFC 4942 states (http://tools.ietf.org/html/rfc4942#section-2.1.6) :
> 2.1.6. Anycast Traffic Identification and Security
> [. . .]
> To avoid exposing knowledge about the internal structure of the
> network, it is recommended that anycast servers now take advantage of
> the ability to return responses with the anycast address as the
> source address if possible.
>
> Also, If the source address of reply differs from destination address of the request, many applications are broken.
> Please let me know your feedback.
>
'anycast servers' are a combination of kernel and userland parts.
^ 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