Netdev List
 help / color / mirror / Atom feed
* [PATCH net-next 2/2] cxgb4: Changed FW check version to match FW binary version
From: Hariprasad Shenai @ 2014-01-07 11:28 UTC (permalink / raw)
  To: netdev; +Cc: davem, dm, leedom, nirranjan, kumaras, santosh, hariprasad
In-Reply-To: <1389094088-6261-1-git-send-email-hariprasad@chelsio.com>

Signed-off-by: Hariprasad Shenai <hariprasad@chelsio.com>
---
 drivers/net/ethernet/chelsio/cxgb4/cxgb4.h | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
index 0d5b365..ddf7f8b 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
@@ -50,13 +50,13 @@
 #include "cxgb4_uld.h"
 
 #define T4FW_VERSION_MAJOR 0x01
-#define T4FW_VERSION_MINOR 0x06
-#define T4FW_VERSION_MICRO 0x18
+#define T4FW_VERSION_MINOR 0x09
+#define T4FW_VERSION_MICRO 0x17
 #define T4FW_VERSION_BUILD 0x00
 
 #define T5FW_VERSION_MAJOR 0x01
-#define T5FW_VERSION_MINOR 0x08
-#define T5FW_VERSION_MICRO 0x1C
+#define T5FW_VERSION_MINOR 0x09
+#define T5FW_VERSION_MICRO 0x17
 #define T5FW_VERSION_BUILD 0x00
 
 #define CH_WARN(adap, fmt, ...) dev_warn(adap->pdev_dev, fmt, ## __VA_ARGS__)
-- 
1.8.0

^ permalink raw reply related

* [PATCH net-next 1/2] cxgb4: Fix namespace collision issue.
From: Hariprasad Shenai @ 2014-01-07 11:28 UTC (permalink / raw)
  To: netdev; +Cc: davem, dm, leedom, nirranjan, kumaras, santosh, hariprasad
In-Reply-To: <1389094088-6261-1-git-send-email-hariprasad@chelsio.com>

Signed-off-by: Hariprasad Shenai <hariprasad@chelsio.com>
---
 drivers/net/ethernet/chelsio/cxgb4/cxgb4.h |   4 --
 drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 100 ++++++++++++++---------------
 2 files changed, 50 insertions(+), 54 deletions(-)

diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
index b97e35c..0d5b365 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
+++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
@@ -918,9 +918,6 @@ static inline int t4_wr_mbox_ns(struct adapter *adap, int mbox, const void *cmd,
 void t4_write_indirect(struct adapter *adap, unsigned int addr_reg,
 		       unsigned int data_reg, const u32 *vals,
 		       unsigned int nregs, unsigned int start_idx);
-void t4_read_indirect(struct adapter *adap, unsigned int addr_reg,
-		      unsigned int data_reg, u32 *vals, unsigned int nregs,
-		      unsigned int start_idx);
 
 struct fw_filter_wr;
 
@@ -945,7 +942,6 @@ int t4_prep_fw(struct adapter *adap, struct fw_info *fw_info,
 	       struct fw_hdr *card_fw, enum dev_state state, int *reset);
 int t4_prep_adapter(struct adapter *adapter);
 int t4_init_tp_params(struct adapter *adap);
-int t4_filter_field_shift(const struct adapter *adap, int filter_sel);
 int t4_port_init(struct adapter *adap, int mbox, int pf, int vf);
 void t4_fatal_err(struct adapter *adapter);
 int t4_config_rss_range(struct adapter *adapter, int mbox, unsigned int viid,
diff --git a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
index a396475..45bb037 100644
--- a/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
+++ b/drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
@@ -111,7 +111,7 @@ void t4_set_reg_field(struct adapter *adapter, unsigned int addr, u32 mask,
  *	Reads registers that are accessed indirectly through an address/data
  *	register pair.
  */
-void t4_read_indirect(struct adapter *adap, unsigned int addr_reg,
+static void t4_read_indirect(struct adapter *adap, unsigned int addr_reg,
 			     unsigned int data_reg, u32 *vals,
 			     unsigned int nregs, unsigned int start_idx)
 {
@@ -3683,54 +3683,6 @@ int t4_prep_adapter(struct adapter *adapter)
 }
 
 /**
- *      t4_init_tp_params - initialize adap->params.tp
- *      @adap: the adapter
- *
- *      Initialize various fields of the adapter's TP Parameters structure.
- */
-int t4_init_tp_params(struct adapter *adap)
-{
-	int chan;
-	u32 v;
-
-	v = t4_read_reg(adap, TP_TIMER_RESOLUTION);
-	adap->params.tp.tre = TIMERRESOLUTION_GET(v);
-	adap->params.tp.dack_re = DELAYEDACKRESOLUTION_GET(v);
-
-	/* MODQ_REQ_MAP defaults to setting queues 0-3 to chan 0-3 */
-	for (chan = 0; chan < NCHAN; chan++)
-		adap->params.tp.tx_modq[chan] = chan;
-
-	/* Cache the adapter's Compressed Filter Mode and global Incress
-	 * Configuration.
-	 */
-	t4_read_indirect(adap, TP_PIO_ADDR, TP_PIO_DATA,
-			 &adap->params.tp.vlan_pri_map, 1,
-			 TP_VLAN_PRI_MAP);
-	t4_read_indirect(adap, TP_PIO_ADDR, TP_PIO_DATA,
-			 &adap->params.tp.ingress_config, 1,
-			 TP_INGRESS_CONFIG);
-
-	/* Now that we have TP_VLAN_PRI_MAP cached, we can calculate the field
-	 * shift positions of several elements of the Compressed Filter Tuple
-	 * for this adapter which we need frequently ...
-	 */
-	adap->params.tp.vlan_shift = t4_filter_field_shift(adap, F_VLAN);
-	adap->params.tp.vnic_shift = t4_filter_field_shift(adap, F_VNIC_ID);
-	adap->params.tp.port_shift = t4_filter_field_shift(adap, F_PORT);
-	adap->params.tp.protocol_shift = t4_filter_field_shift(adap,
-							       F_PROTOCOL);
-
-	/* If TP_INGRESS_CONFIG.VNID == 0, then TP_VLAN_PRI_MAP.VNIC_ID
-	 * represents the presense of an Outer VLAN instead of a VNIC ID.
-	 */
-	if ((adap->params.tp.ingress_config & F_VNIC) == 0)
-		adap->params.tp.vnic_shift = -1;
-
-	return 0;
-}
-
-/**
  *      t4_filter_field_shift - calculate filter field shift
  *      @adap: the adapter
  *      @filter_sel: the desired field (from TP_VLAN_PRI_MAP bits)
@@ -3739,7 +3691,7 @@ int t4_init_tp_params(struct adapter *adap)
  *      Filter Tuple.  The filter field is specified via its selection bit
  *      within TP_VLAN_PRI_MAL (filter mode).  E.g. F_VLAN.
  */
-int t4_filter_field_shift(const struct adapter *adap, int filter_sel)
+static int t4_filter_field_shift(const struct adapter *adap, int filter_sel)
 {
 	unsigned int filter_mode = adap->params.tp.vlan_pri_map;
 	unsigned int sel;
@@ -3785,6 +3737,54 @@ int t4_filter_field_shift(const struct adapter *adap, int filter_sel)
 	return field_shift;
 }
 
+/**
+ *      t4_init_tp_params - initialize adap->params.tp
+ *      @adap: the adapter
+ *
+ *      Initialize various fields of the adapter's TP Parameters structure.
+ */
+int t4_init_tp_params(struct adapter *adap)
+{
+	int chan;
+	u32 v;
+
+	v = t4_read_reg(adap, TP_TIMER_RESOLUTION);
+	adap->params.tp.tre = TIMERRESOLUTION_GET(v);
+	adap->params.tp.dack_re = DELAYEDACKRESOLUTION_GET(v);
+
+	/* MODQ_REQ_MAP defaults to setting queues 0-3 to chan 0-3 */
+	for (chan = 0; chan < NCHAN; chan++)
+		adap->params.tp.tx_modq[chan] = chan;
+
+	/* Cache the adapter's Compressed Filter Mode and global Incress
+	 * Configuration.
+	 */
+	t4_read_indirect(adap, TP_PIO_ADDR, TP_PIO_DATA,
+			 &adap->params.tp.vlan_pri_map, 1,
+			 TP_VLAN_PRI_MAP);
+	t4_read_indirect(adap, TP_PIO_ADDR, TP_PIO_DATA,
+			 &adap->params.tp.ingress_config, 1,
+			 TP_INGRESS_CONFIG);
+
+	/* Now that we have TP_VLAN_PRI_MAP cached, we can calculate the field
+	 * shift positions of several elements of the Compressed Filter Tuple
+	 * for this adapter which we need frequently ...
+	 */
+	adap->params.tp.vlan_shift = t4_filter_field_shift(adap, F_VLAN);
+	adap->params.tp.vnic_shift = t4_filter_field_shift(adap, F_VNIC_ID);
+	adap->params.tp.port_shift = t4_filter_field_shift(adap, F_PORT);
+	adap->params.tp.protocol_shift = t4_filter_field_shift(adap,
+							       F_PROTOCOL);
+
+	/* If TP_INGRESS_CONFIG.VNID == 0, then TP_VLAN_PRI_MAP.VNIC_ID
+	 * represents the presense of an Outer VLAN instead of a VNIC ID.
+	 */
+	if ((adap->params.tp.ingress_config & F_VNIC) == 0)
+		adap->params.tp.vnic_shift = -1;
+
+	return 0;
+}
+
 int t4_port_init(struct adapter *adap, int mbox, int pf, int vf)
 {
 	u8 addr[6];
-- 
1.8.0

^ permalink raw reply related

* [PATCH net-next 0/2] namespace collision fix and update FW version check on cxgb4
From: Hariprasad Shenai @ 2014-01-07 11:28 UTC (permalink / raw)
  To: netdev; +Cc: davem, dm, leedom, nirranjan, kumaras, santosh, hariprasad

Hi

This patch series provides namespace collision fix for cxgb4 driver.
Also updated FW version check for cxgb4 driver.

Patch series is created against David Miller's net-next tree.

We have included all the maintainers of respective drivers. Kindly review the
change and let us know in case of any review comments.

Thanks,
Hari

Hariprasad Shenai (2):
  cxgb4: Fix namespace collision issue.
  cxgb4: Changed FW check version to match FW binary version

 drivers/net/ethernet/chelsio/cxgb4/cxgb4.h |  12 ++--
 drivers/net/ethernet/chelsio/cxgb4/t4_hw.c | 100 ++++++++++++++---------------
 2 files changed, 54 insertions(+), 58 deletions(-)

-- 
1.8.0

^ permalink raw reply

* Re: Possible to add netfilter hooks to IFB driver?
From: Alban Crequy @ 2014-01-07 11:18 UTC (permalink / raw)
  To: Andrew Collins; +Cc: Stephen Hemminger, Brad Johnson, netdev@vger.kernel.org
In-Reply-To: <CAKTPYJTDj82YM8peU-bbS5OtuXnq1ty4+f-Wyk_bE2LBf4vGmw@mail.gmail.com>

On Mon, 6 Jan 2014 15:51:37 -0700
Andrew Collins <bsderandrew@gmail.com> wrote:

> On Mon, Jan 6, 2014 at 2:51 PM, Stephen Hemminger
> <stephen@networkplumber.org> wrote:
> >
> > The risk is creating the same races that made IMQ unacceptable.
> > --
> 
> I believe openwrt nowadays uses a TC action which runs the packet
> through prerouting then pulls in the mark off the ct entry into the
> skb, so ingress+IFB can take action on it.

Thanks for the info. I guess the implementation is this one:

https://dev.openwrt.org/browser/trunk/target/linux/generic/patches-3.12/621-sched_act_connmark.patch
https://dev.openwrt.org/browser/trunk/package/network/utils/iproute2/patches/210-add-act_connmark.patch
https://dev.openwrt.org/browser/trunk/package/network/config/qos-scripts/files/usr/lib/qos/generate.sh#L343

> Perhaps a cleaned up version of this would be suitable for upstream?

I don't know but this seems a useful feature to me.

Best regards,
Alban

^ permalink raw reply

* Re: [PATCH] netfilter: nf_conntrack: release conntrack from rcu callback
From: Andrey Wagin @ 2014-01-07 10:39 UTC (permalink / raw)
  To: Florian Westphal
  Cc: netfilter-devel, netfilter, coreteam, netdev, LKML, vvs,
	Pablo Neira Ayuso, Patrick McHardy, Jozsef Kadlecsik,
	David S. Miller, Cyrill Gorcunov
In-Reply-To: <20140106215335.GC9894@breakpoint.cc>

Hi Florian,

2014/1/7 Florian Westphal <fw@strlen.de>:
> Andrew Vagin <avagin@gmail.com> wrote:

>> >                 ct = nf_ct_tuplehash_to_ctrack(h);
>> >                 if (unlikely(nf_ct_is_dying(ct) ||
>> >                              !atomic_inc_not_zero(&ct->ct_general.use)))
>> >                     // which means we should hit this path (0 ref).
>> >                         h = NULL;
>> >                 else {
>> >                     // otherwise, it cannot go away from under us, since
>> >                     // we own a reference now.
>> >                         if (unlikely(!nf_ct_tuple_equal(tuple, &h->tuple) ||
>> >                                      nf_ct_zone(ct) != zone)) {
>
> Perhaps this needs additional !nf_ct_is_confirmed()?

Yes, it think it must help. Thank you for the comments. I resent this patch:
[PATCH] netfilter: nf_conntrack: fix RCU race in nf_conntrack_find_get

>
> It would cover your case (found a recycled element that has been put on
> the unconfirmed list (refcnt already set to 1, ct->tuple is set) on another cpu,
> extensions possibly not yet fully initialised), and the same tuple).
>
> Regards,
> Florian

Thanks,
Andrey

^ permalink raw reply

* [PATCH] netfilter: nf_conntrack: fix RCU race in nf_conntrack_find_get
From: Andrey Vagin @ 2014-01-07 10:31 UTC (permalink / raw)
  To: netfilter-devel
  Cc: netfilter, coreteam, netdev, linux-kernel, vvs, Andrey Vagin,
	Florian Westphal, Pablo Neira Ayuso, Patrick McHardy,
	Jozsef Kadlecsik, David S. Miller, Cyrill Gorcunov

Lets look at destroy_conntrack:

hlist_nulls_del_rcu(&ct->tuplehash[IP_CT_DIR_ORIGINAL].hnnode);
...
nf_conntrack_free(ct)
	kmem_cache_free(net->ct.nf_conntrack_cachep, ct);

net->ct.nf_conntrack_cachep is created with SLAB_DESTROY_BY_RCU.

The hash is protected by rcu, so readers look up conntracks without
locks.
A conntrack is removed from the hash, but in this moment a few readers
still can use the conntrack. Then this conntrack is released and another
thread creates conntrack with the same address and the equal tuple.
After this a reader starts to validate the conntrack:
* It's not dying, because a new conntrack was created
* nf_ct_tuple_equal() returns true.

But this conntrack is not initialized yet, so it can not be used by two
threads concurrently. In this case BUG_ON may be triggered from
nf_nat_setup_info().

Florian Westphal suggested to check the confirm bit too. I think it's
right.

task 1			task 2			task 3
			nf_conntrack_find_get
			 ____nf_conntrack_find
destroy_conntrack
 hlist_nulls_del_rcu
 nf_conntrack_free
 kmem_cache_free
						__nf_conntrack_alloc
						 kmem_cache_alloc
						 memset(&ct->tuplehash[IP_CT_DIR_MAX],
			 if (nf_ct_is_dying(ct))
			 if (!nf_ct_tuple_equal()

I'm not sure, that I have ever seen this race condition in a real life.
Currently we are investigating a bug, which is reproduced on a few node.
In our case one conntrack is initialized from a few tasks concurrently,
we don't have any other explanation for this.

<2>[46267.083061] kernel BUG at net/ipv4/netfilter/nf_nat_core.c:322!
...
<4>[46267.083951] RIP: 0010:[<ffffffffa01e00a4>]  [<ffffffffa01e00a4>] nf_nat_setup_info+0x564/0x590 [nf_nat]
...
<4>[46267.085549] Call Trace:
<4>[46267.085622]  [<ffffffffa023421b>] alloc_null_binding+0x5b/0xa0 [iptable_nat]
<4>[46267.085697]  [<ffffffffa02342bc>] nf_nat_rule_find+0x5c/0x80 [iptable_nat]
<4>[46267.085770]  [<ffffffffa0234521>] nf_nat_fn+0x111/0x260 [iptable_nat]
<4>[46267.085843]  [<ffffffffa0234798>] nf_nat_out+0x48/0xd0 [iptable_nat]
<4>[46267.085919]  [<ffffffff814841b9>] nf_iterate+0x69/0xb0
<4>[46267.085991]  [<ffffffff81494e70>] ? ip_finish_output+0x0/0x2f0
<4>[46267.086063]  [<ffffffff81484374>] nf_hook_slow+0x74/0x110
<4>[46267.086133]  [<ffffffff81494e70>] ? ip_finish_output+0x0/0x2f0
<4>[46267.086207]  [<ffffffff814b5890>] ? dst_output+0x0/0x20
<4>[46267.086277]  [<ffffffff81495204>] ip_output+0xa4/0xc0
<4>[46267.086346]  [<ffffffff814b65a4>] raw_sendmsg+0x8b4/0x910
<4>[46267.086419]  [<ffffffff814c10fa>] inet_sendmsg+0x4a/0xb0
<4>[46267.086491]  [<ffffffff814459aa>] ? sock_update_classid+0x3a/0x50
<4>[46267.086562]  [<ffffffff81444d67>] sock_sendmsg+0x117/0x140
<4>[46267.086638]  [<ffffffff8151997b>] ? _spin_unlock_bh+0x1b/0x20
<4>[46267.086712]  [<ffffffff8109d370>] ? autoremove_wake_function+0x0/0x40
<4>[46267.086785]  [<ffffffff81495e80>] ? do_ip_setsockopt+0x90/0xd80
<4>[46267.086858]  [<ffffffff8100be0e>] ? call_function_interrupt+0xe/0x20
<4>[46267.086936]  [<ffffffff8118cb10>] ? ub_slab_ptr+0x20/0x90
<4>[46267.087006]  [<ffffffff8118cb10>] ? ub_slab_ptr+0x20/0x90
<4>[46267.087081]  [<ffffffff8118f2e8>] ? kmem_cache_alloc+0xd8/0x1e0
<4>[46267.087151]  [<ffffffff81445599>] sys_sendto+0x139/0x190
<4>[46267.087229]  [<ffffffff81448c0d>] ? sock_setsockopt+0x16d/0x6f0
<4>[46267.087303]  [<ffffffff810efa47>] ? audit_syscall_entry+0x1d7/0x200
<4>[46267.087378]  [<ffffffff810ef795>] ? __audit_syscall_exit+0x265/0x290
<4>[46267.087454]  [<ffffffff81474885>] ? compat_sys_setsockopt+0x75/0x210
<4>[46267.087531]  [<ffffffff81474b5f>] compat_sys_socketcall+0x13f/0x210
<4>[46267.087607]  [<ffffffff8104dea3>] ia32_sysret+0x0/0x5
<4>[46267.087676] Code: 91 20 e2 01 75 29 48 89 de 4c 89 f7 e8 56 fa ff ff 85 c0 0f 84 68 fc ff ff 0f b6 4d c6 41 8b 45 00 e9 4d fb ff ff e8 7c 19 e9 e0 <0f> 0b eb fe f6 05 17 91 20 e2 80 74 ce 80 3d 5f 2e 00 00 00 74
<1>[46267.088023] RIP  [<ffffffffa01e00a4>] nf_nat_setup_info+0x564/0x590

Cc: Florian Westphal <fw@strlen.de>
Cc: Pablo Neira Ayuso <pablo@netfilter.org>
Cc: Patrick McHardy <kaber@trash.net>
Cc: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Cyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: Andrey Vagin <avagin@openvz.org>
---
 net/netfilter/nf_conntrack_core.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 43549eb..7a34bb2 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -387,8 +387,12 @@ begin:
 			     !atomic_inc_not_zero(&ct->ct_general.use)))
 			h = NULL;
 		else {
+			/* A conntrack can be recreated with the equal tuple,
+			 * so we need to check that the conntrack is initialized
+			 */
 			if (unlikely(!nf_ct_tuple_equal(tuple, &h->tuple) ||
-				     nf_ct_zone(ct) != zone)) {
+				     nf_ct_zone(ct) != zone) ||
+				     !nf_ct_is_confirmed(ct)) {
 				nf_ct_put(ct);
 				goto begin;
 			}
-- 
1.8.4.2

^ permalink raw reply related

* RE: [PATCH net-next v3] xen-netfront: Add support for IPv6 offloads
From: Paul Durrant @ 2014-01-07 10:25 UTC (permalink / raw)
  To: xen-devel@lists.xen.org, netdev@vger.kernel.org
  Cc: Konrad Rzeszutek Wilk, David Vrabel, Ian Campbell, Wei Liu,
	Annie Li, Boris Ostrovsky
In-Reply-To: <52C31691.9040302@oracle.com>

> -----Original Message-----
> From: Boris Ostrovsky [mailto:boris.ostrovsky@oracle.com]
> Sent: 31 December 2013 19:10
> To: Paul Durrant
> Cc: xen-devel@lists.xen.org; netdev@vger.kernel.org; Konrad Rzeszutek
> Wilk; David Vrabel; Ian Campbell; Wei Liu; Annie Li
> Subject: Re: [PATCH net-next v3] xen-netfront: Add support for IPv6 offloads
> 
> On 11/26/2013 11:41 AM, Paul Durrant wrote:
> > This patch adds support for IPv6 checksum offload and GSO when those
> > features are available in the backend.
> 
> Sorry for late review. Mostly style comments.
> 

Thanks for the review.

The checksum related code essentially needs to be a duplicate of that in netback and it seems wasteful to have the code in both places. Could this code be moved perhaps to net/core/dev.c? It's not specific to netback/netfront usage.

Opinions?

  Paul

> >
> > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> > Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
> > Cc: Boris Ostrovsky <boris.ostrovsky@oracle.com>
> > Cc: David Vrabel <david.vrabel@citrix.com>
> > Cc: Ian Campbell <ian.campbell@citrix.com>
> > Cc: Wei Liu <wei.liu2@citrix.com>
> > Cc: Annie Li <annie.li@oracle.com>
> > ---
> >
> > v3:
> >   - Addressed comments raised by Annie Li
> >
> > v2:
> >   - Addressed comments raised by Ian Campbell
> >
> >   drivers/net/xen-netfront.c |  239
> ++++++++++++++++++++++++++++++++++++++++----
> >   include/linux/ipv6.h       |    2 +
> >   2 files changed, 224 insertions(+), 17 deletions(-)
> >
> > diff --git a/drivers/net/xen-netfront.c b/drivers/net/xen-netfront.c
> > index dd1011e..fe747e4 100644
> > --- a/drivers/net/xen-netfront.c
> > +++ b/drivers/net/xen-netfront.c
> > @@ -616,7 +616,9 @@ static int xennet_start_xmit(struct sk_buff *skb,
> struct net_device *dev)
> >   		tx->flags |= XEN_NETTXF_extra_info;
> >
> >   		gso->u.gso.size = skb_shinfo(skb)->gso_size;
> > -		gso->u.gso.type = XEN_NETIF_GSO_TYPE_TCPV4;
> > +		gso->u.gso.type = (skb_shinfo(skb)->gso_type &
> SKB_GSO_TCPV6) ?
> > +			          XEN_NETIF_GSO_TYPE_TCPV6 :
> > +			          XEN_NETIF_GSO_TYPE_TCPV4;
> >   		gso->u.gso.pad = 0;
> >   		gso->u.gso.features = 0;
> >
> > @@ -808,15 +810,18 @@ static int xennet_set_skb_gso(struct sk_buff
> *skb,
> >   		return -EINVAL;
> >   	}
> >
> > -	/* Currently only TCPv4 S.O. is supported. */
> > -	if (gso->u.gso.type != XEN_NETIF_GSO_TYPE_TCPV4) {
> > +	if (gso->u.gso.type != XEN_NETIF_GSO_TYPE_TCPV4 &&
> > +	    gso->u.gso.type != XEN_NETIF_GSO_TYPE_TCPV6) {
> >   		if (net_ratelimit())
> >   			pr_warn("Bad GSO type %d\n", gso->u.gso.type);
> >   		return -EINVAL;
> >   	}
> >
> >   	skb_shinfo(skb)->gso_size = gso->u.gso.size;
> > -	skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
> > +	skb_shinfo(skb)->gso_type =
> > +		(gso->u.gso.type == XEN_NETIF_GSO_TYPE_TCPV4) ?
> > +		SKB_GSO_TCPV4 :
> > +		SKB_GSO_TCPV6;
> >
> >   	/* Header must be checked, and gso_segs computed. */
> >   	skb_shinfo(skb)->gso_type |= SKB_GSO_DODGY;
> > @@ -856,11 +861,42 @@ static RING_IDX xennet_fill_frags(struct
> netfront_info *np,
> >   	return cons;
> >   }
> >
> > -static int checksum_setup(struct net_device *dev, struct sk_buff *skb)
> > +static inline bool maybe_pull_tail(struct sk_buff *skb, unsigned int min,
> > +				   unsigned int max)
> 
> Should this routine return error code instead of a boolean? Otherwise
> it's not clear what "false" should mean --- whether it is that it failed
> to pull or that the pull wasn't needed.
> 
> >   {
> > -	struct iphdr *iph;
> > -	int err = -EPROTO;
> > +	int target;
> > +
> > +	BUG_ON(max < min);
> > +
> > +	if (!skb_is_nonlinear(skb) || skb_headlen(skb) >= min)
> > +		return true;
> > +
> > +	/* If we need to pullup then pullup to max, so we hopefully
> > +	 * won't need to do it again.
> > +	 */
> 
> Comment style.
> 
> > +	target = min_t(int, skb->len, max);
> > +	__pskb_pull_tail(skb, target - skb_headlen(skb));
> > +
> > +	if (skb_headlen(skb) < min) {
> 
> Why not explicitly check whether__pskb_pull_tail() returned NULL ?
> 
> > +		net_err_ratelimited("Failed to pullup packet header\n");
> > +		return false;
> > +	}
> > +
> > +	return true;
> > +}
> > +
> > +/* This value should be large enough to cover a tagged ethernet header
> plus
> > + * maximally sized IP and TCP or UDP headers.
> > + */
> 
> Comment style.
> 
> > +#define MAX_IP_HEADER 128
> > +
> > +static int checksum_setup_ip(struct net_device *dev, struct sk_buff
> *skb)
> > +{
> > +	struct iphdr *iph = (void *)skb->data;
> > +	unsigned int header_size;
> > +	unsigned int off;
> >   	int recalculate_partial_csum = 0;
> > +	int err = -EPROTO;
> >
> >   	/*
> >   	 * A GSO SKB must be CHECKSUM_PARTIAL. However some buggy
> > @@ -879,40 +915,158 @@ static int checksum_setup(struct net_device
> *dev, struct sk_buff *skb)
> >   	if (skb->ip_summed != CHECKSUM_PARTIAL)
> >   		return 0;
> >
> > -	if (skb->protocol != htons(ETH_P_IP))
> > +	off = sizeof(struct iphdr);
> > +
> > +	header_size = skb->network_header + off;
> > +	if (!maybe_pull_tail(skb, header_size, MAX_IP_HEADER))
> >   		goto out;
> >
> > -	iph = (void *)skb->data;
> > +	off = iph->ihl * 4;
> >
> >   	switch (iph->protocol) {
> >   	case IPPROTO_TCP:
> > -		if (!skb_partial_csum_set(skb, 4 * iph->ihl,
> > +		if (!skb_partial_csum_set(skb, off,
> >   					  offsetof(struct tcphdr, check)))
> >   			goto out;
> >
> >   		if (recalculate_partial_csum) {
> >   			struct tcphdr *tcph = tcp_hdr(skb);
> > +
> > +			header_size = skb->network_header +
> > +				off +
> > +				sizeof(struct tcphdr);
> 
> You can put these (off and sizeof) onto the same line.
> 
> > +			if (!maybe_pull_tail(skb, header_size,
> MAX_IP_HEADER))
> > +				goto out;
> > +
> >   			tcph->check = ~csum_tcpudp_magic(iph->saddr, iph-
> >daddr,
> > -							 skb->len - iph->ihl*4,
> > +							 skb->len - off,
> >   							 IPPROTO_TCP, 0);
> >   		}
> >   		break;
> >   	case IPPROTO_UDP:
> > -		if (!skb_partial_csum_set(skb, 4 * iph->ihl,
> > +		if (!skb_partial_csum_set(skb, off,
> >   					  offsetof(struct udphdr, check)))
> >   			goto out;
> >
> >   		if (recalculate_partial_csum) {
> >   			struct udphdr *udph = udp_hdr(skb);
> > +
> > +			header_size = skb->network_header +
> > +				off +
> > +				sizeof(struct udphdr);
> > +			if (!maybe_pull_tail(skb, header_size,
> MAX_IP_HEADER))
> > +				goto out;
> > +
> >   			udph->check = ~csum_tcpudp_magic(iph->saddr,
> iph->daddr,
> > -							 skb->len - iph->ihl*4,
> > +							 skb->len - off,
> >   							 IPPROTO_UDP, 0);
> >   		}
> >   		break;
> >   	default:
> > -		if (net_ratelimit())
> > -			pr_err("Attempting to checksum a non-TCP/UDP
> packet, dropping a protocol %d packet\n",
> > -			       iph->protocol);
> > +		net_err_ratelimited("Attempting to checksum a non-
> TCP/UDP packet, dropping a protocol %d packet\n",
> > +				    iph->protocol);
> > +		goto out;
> > +	}
> > +
> > +	err = 0;
> > +
> > +out:
> > +	return err;
> > +}
> > +
> > +/* This value should be large enough to cover a tagged ethernet header
> plus
> > + * an IPv6 header, all options, and a maximal TCP or UDP header.
> > + */
> > +#define MAX_IPV6_HEADER 256
> > +
> > +static int checksum_setup_ipv6(struct net_device *dev, struct sk_buff
> *skb)
> > +{
> > +	struct ipv6hdr *ipv6h = (void *)skb->data;
> > +	u8 nexthdr;
> > +	unsigned int header_size;
> > +	unsigned int off;
> > +	bool fragment;
> > +	bool done;
> > +	int err = -EPROTO;
> > +
> > +	done = false;
> 
> This should probably be moved down to the beginning of the while loop.
> And you also need to initialize fragment to "false" (and possibly rename
> it to is_fragment?)
> 
> > +
> > +	/* A non-CHECKSUM_PARTIAL SKB does not require setup. */
> > +	if (skb->ip_summed != CHECKSUM_PARTIAL)
> > +		return 0;
> > +
> > +	off = sizeof(struct ipv6hdr);
> > +
> > +	header_size = skb->network_header + off;
> > +	if (!maybe_pull_tail(skb, header_size, MAX_IPV6_HEADER))
> > +		goto out;
> > +
> > +	nexthdr = ipv6h->nexthdr;
> > +
> > +	while ((off <= sizeof(struct ipv6hdr) + ntohs(ipv6h->payload_len))
> &&
> > +	       !done) {
> > +		switch (nexthdr) {
> > +		case IPPROTO_DSTOPTS:
> > +		case IPPROTO_HOPOPTS:
> > +		case IPPROTO_ROUTING: {
> > +			struct ipv6_opt_hdr *hp = (void *)(skb->data + off);
> > +
> > +			header_size = skb->network_header +
> > +				off +
> > +				sizeof(struct ipv6_opt_hdr);
> 
> I'd merge the last two lines.
> 
> > +			if (!maybe_pull_tail(skb, header_size,
> MAX_IPV6_HEADER))
> > +				goto out;
> > +
> > +			nexthdr = hp->nexthdr;
> > +			off += ipv6_optlen(hp);
> > +			break;
> > +		}
> > +		case IPPROTO_AH: {
> > +			struct ip_auth_hdr *hp = (void *)(skb->data + off);
> > +
> > +			header_size = skb->network_header +
> > +				off +
> > +				sizeof(struct ip_auth_hdr);
> 
> Here as well.
> 
> > +			if (!maybe_pull_tail(skb, header_size,
> MAX_IPV6_HEADER))
> > +				goto out;
> > +
> > +			nexthdr = hp->nexthdr;
> > +			off += ipv6_ahlen(hp);
> > +			break;
> > +		}
> > +		case IPPROTO_FRAGMENT:
> > +			fragment = true;
> > +			/* fall through */
> > +		default:
> > +			done = true;
> > +			break;
> > +		}
> > +	}
> > +
> > +	if (!done) {
> > +		net_err_ratelimited("Failed to parse packet header\n");
> > +		goto out;
> > +	}
> > +
> > +	if (fragment) {
> > +		net_err_ratelimited("Packet is a fragment!\n");
> > +		goto out;
> > +	}
> > +
> > +	switch (nexthdr) {
> > +	case IPPROTO_TCP:
> > +		if (!skb_partial_csum_set(skb, off,
> > +					  offsetof(struct tcphdr, check)))
> > +			goto out;
> > +		break;
> > +	case IPPROTO_UDP:
> > +		if (!skb_partial_csum_set(skb, off,
> > +					  offsetof(struct udphdr, check)))
> > +			goto out;
> > +		break;
> > +	default:
> > +		net_err_ratelimited("Attempting to checksum a non-
> TCP/UDP packet, dropping a protocol %d packet\n",
> > +				    nexthdr);
> >   		goto out;
> >   	}
> >
> > @@ -922,6 +1076,25 @@ out:
> >   	return err;
> >   }
> >
> > +static int checksum_setup(struct net_device *dev, struct sk_buff *skb)
> > +{
> > +	int err;
> 
> Initialize to -EPROTO (just to keep consistent with the rest of the file)
> 
> > +
> > +	switch (skb->protocol) {
> > +	case htons(ETH_P_IP):
> > +		err = checksum_setup_ip(dev, skb);
> > +		break;
> > +	case htons(ETH_P_IPV6):
> > +		err = checksum_setup_ipv6(dev, skb);
> > +		break;
> > +	default:
> > +		err = -EPROTO;
> > +		break;
> > +	}
> > +
> > +	return err;
> > +}
> > +
> >   static int handle_incoming_queue(struct net_device *dev,
> >   				 struct sk_buff_head *rxq)
> >   {
> > @@ -1232,6 +1405,15 @@ static netdev_features_t
> xennet_fix_features(struct net_device *dev,
> >   			features &= ~NETIF_F_SG;
> >   	}
> >
> > +	if (features & NETIF_F_IPV6_CSUM) {
> > +		if (xenbus_scanf(XBT_NIL, np->xbdev->otherend,
> > +				 "feature-ipv6-csum-offload", "%d", &val) <
> 0)
> > +			val = 0;
> > +
> > +		if (!val)
> > +			features &= ~NETIF_F_IPV6_CSUM;
> > +	}
> > +
> >   	if (features & NETIF_F_TSO) {
> >   		if (xenbus_scanf(XBT_NIL, np->xbdev->otherend,
> >   				 "feature-gso-tcpv4", "%d", &val) < 0)
> > @@ -1241,6 +1423,15 @@ static netdev_features_t
> xennet_fix_features(struct net_device *dev,
> >   			features &= ~NETIF_F_TSO;
> >   	}
> >
> > +	if (features & NETIF_F_TSO6) {
> > +		if (xenbus_scanf(XBT_NIL, np->xbdev->otherend,
> > +				 "feature-gso-tcpv6", "%d", &val) < 0)
> > +			val = 0;
> > +
> > +		if (!val)
> > +			features &= ~NETIF_F_TSO6;
> > +	}
> > +
> >   	return features;
> >   }
> >
> > @@ -1373,7 +1564,9 @@ static struct net_device
> *xennet_create_dev(struct xenbus_device *dev)
> >   	netif_napi_add(netdev, &np->napi, xennet_poll, 64);
> >   	netdev->features        = NETIF_F_IP_CSUM | NETIF_F_RXCSUM |
> >   				  NETIF_F_GSO_ROBUST;
> > -	netdev->hw_features	= NETIF_F_IP_CSUM | NETIF_F_SG |
> NETIF_F_TSO;
> > +	netdev->hw_features	= NETIF_F_SG |
> > +		                  NETIF_F_IPV6_CSUM |
> > +		                  NETIF_F_TSO | NETIF_F_TSO6;
> 
> Can you merge these three lines and stay under 80? If not, merge either
> of the two of them.
> 
> 
> -boris
> 
> >
> >   	/*
> >            * Assume that all hw features are available for now. This set
> > @@ -1751,6 +1944,18 @@ again:
> >   		goto abort_transaction;
> >   	}
> >
> > +	err = xenbus_printf(xbt, dev->nodename, "feature-gso-tcpv6",
> "%d", 1);
> > +	if (err) {
> > +		message = "writing feature-gso-tcpv6";
> > +		goto abort_transaction;
> > +	}
> > +
> > +	err = xenbus_printf(xbt, dev->nodename, "feature-ipv6-csum-
> offload", "%d", 1);
> > +	if (err) {
> > +		message = "writing feature-ipv6-csum-offload";
> > +		goto abort_transaction;
> > +	}
> > +
> >   	err = xenbus_transaction_end(xbt, 0);
> >   	if (err) {
> >   		if (err == -EAGAIN)
> > diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h
> > index 5d89d1b..10f1b03 100644
> > --- a/include/linux/ipv6.h
> > +++ b/include/linux/ipv6.h
> > @@ -4,6 +4,8 @@
> >   #include <uapi/linux/ipv6.h>
> >
> >   #define ipv6_optlen(p)  (((p)->hdrlen+1) << 3)
> > +#define ipv6_ahlen(p)   (((p)->hdrlen+2) << 2);
> > +
> >   /*
> >    * This structure contains configuration options per IPv6 link.
> >    */


^ permalink raw reply

* Re: Re: [PATCH 04/10] net: stmmac: sunxi platfrom extensions for GMAC in Allwinner A20 SoC's
From: Chen-Yu Tsai @ 2014-01-07 10:24 UTC (permalink / raw)
  To: srinivas kandagatla
  Cc: linux-sunxi, Giuseppe Cavallaro, netdev, Rob Herring, devicetree,
	linux-arm-kernel, linux-kernel
In-Reply-To: <52C5656A.4060402-qxv4g6HH51o@public.gmane.org>

Hi,

On Thu, Jan 2, 2014 at 9:11 PM, srinivas kandagatla
<srinivas.kandagatla-qxv4g6HH51o@public.gmane.org> wrote:
> Hi Chen,
>
> On 24/12/13 03:27, Chen-Yu Tsai wrote:
>> Srinivas,
>>
>> Let's keep platform data as of_data, so SoC compatibles can pass
>> hardware feature flags for cores that don't support auto-detection.
>
> I understand your concern here, But making platform_data as of_data
> would just open a wide door for other hacky stuff too. So other glue
> drivers would just use this interface instead, ignoring standard
> interfaces. Also there would be issues on who takes the priority if the
> parameters are specified in multiple places.
>
>
> Can't this field/s be one of the variable in the struct stmmac_of_data
> rather than reusing platform data?

We (sunxi) need .has_gmac and .tx_coe.

To be generic and usable to other SoCs, it seems like I would be
adding most of the fields from platform data. But maybe future
glue layers will only need the callbacks. I can not be sure.

Also since snps,phy-addr should be deprecated, I am thinking of
changing the default phy address to auto-detect, until
Giuseppe merges his phy node support work.

I will post a v2 series this week.

>>
>> We can adjust the callbacks as you suggested, and I added a .free
>> to complement .setup. Driver private data and platform data are
>> off limits to the callbacks. My version of the callbacks:
>>
>>         void (*fix_mac_speed)(void *priv, unsigned int speed);
>>         void (*bus_setup)(void __iomem *ioaddr);
>
> In reply to your question in last email:
> bus_setup this is something very specific to ST which configures the bus
> parameters of AMBA-to-STBUS converter. This register falls inside the
> memory map of stmmac.

I see. IMHO it could be merged into .init?

>
>>         void *(*setup)(struct platform_device *pdev);
>>         void (*free)(struct platform_device *pdev, void *priv);
>>         int (*init)(struct platform_device *pdev, void *priv);
>>         void (*exit)(struct platform_device *pdev, void *priv);
>>
>
> The callbacks to Ok to me, unless Peppe has more comments on this.

Ok.


Cheers
ChenYu

^ permalink raw reply

* [PATCH net] bnx2x: prevent WARN during driver unload
From: Yuval Mintz @ 2014-01-07 10:07 UTC (permalink / raw)
  To: davem, netdev; +Cc: Yuval Mintz, Dmitry Kravkov, Ariel Elior

Starting with commit 80c33dd "net: add might_sleep() call to napi_disable"
bnx2x fails the might_sleep tests causing a stack trace to appear whenever
the driver is unloaded, as local_bh_disable() is being called before 
napi_disable().

This changes the locking schematics related to CONFIG_NET_RX_BUSY_POLL,
preventing the need for calling local_bh_disable() and thus eliminating
the issue.

Signed-off-by: Yuval Mintz <yuvalmin@broadcom.com>
Signed-off-by: Dmitry Kravkov <dmitry@broadcom.com>
Signed-off-by: Ariel Elior <ariele@broadcom.com>
---
Hi Dave,

Please apply this to `net'.

Thanks,
Yuval Mintz
---
 drivers/net/ethernet/broadcom/bnx2x/bnx2x.h     | 44 +++++++++++++++++++------
 drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c | 12 +++----
 2 files changed, 38 insertions(+), 18 deletions(-)

diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
index a1f66e2..46eeace 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h
@@ -520,10 +520,12 @@ struct bnx2x_fastpath {
 #define BNX2X_FP_STATE_IDLE		      0
 #define BNX2X_FP_STATE_NAPI		(1 << 0)    /* NAPI owns this FP */
 #define BNX2X_FP_STATE_POLL		(1 << 1)    /* poll owns this FP */
-#define BNX2X_FP_STATE_NAPI_YIELD	(1 << 2)    /* NAPI yielded this FP */
-#define BNX2X_FP_STATE_POLL_YIELD	(1 << 3)    /* poll yielded this FP */
+#define BNX2X_FP_STATE_DISABLED		(1 << 2)
+#define BNX2X_FP_STATE_NAPI_YIELD	(1 << 3)    /* NAPI yielded this FP */
+#define BNX2X_FP_STATE_POLL_YIELD	(1 << 4)    /* poll yielded this FP */
+#define BNX2X_FP_OWNED	(BNX2X_FP_STATE_NAPI | BNX2X_FP_STATE_POLL)
 #define BNX2X_FP_YIELD	(BNX2X_FP_STATE_NAPI_YIELD | BNX2X_FP_STATE_POLL_YIELD)
-#define BNX2X_FP_LOCKED	(BNX2X_FP_STATE_NAPI | BNX2X_FP_STATE_POLL)
+#define BNX2X_FP_LOCKED	(BNX2X_FP_OWNED | BNX2X_FP_STATE_DISABLED)
 #define BNX2X_FP_USER_PEND (BNX2X_FP_STATE_POLL | BNX2X_FP_STATE_POLL_YIELD)
 	/* protect state */
 	spinlock_t lock;
@@ -613,7 +615,7 @@ static inline bool bnx2x_fp_lock_napi(struct bnx2x_fastpath *fp)
 {
 	bool rc = true;
 
-	spin_lock(&fp->lock);
+	spin_lock_bh(&fp->lock);
 	if (fp->state & BNX2X_FP_LOCKED) {
 		WARN_ON(fp->state & BNX2X_FP_STATE_NAPI);
 		fp->state |= BNX2X_FP_STATE_NAPI_YIELD;
@@ -622,7 +624,7 @@ static inline bool bnx2x_fp_lock_napi(struct bnx2x_fastpath *fp)
 		/* we don't care if someone yielded */
 		fp->state = BNX2X_FP_STATE_NAPI;
 	}
-	spin_unlock(&fp->lock);
+	spin_unlock_bh(&fp->lock);
 	return rc;
 }
 
@@ -631,14 +633,16 @@ static inline bool bnx2x_fp_unlock_napi(struct bnx2x_fastpath *fp)
 {
 	bool rc = false;
 
-	spin_lock(&fp->lock);
+	spin_lock_bh(&fp->lock);
 	WARN_ON(fp->state &
 		(BNX2X_FP_STATE_POLL | BNX2X_FP_STATE_NAPI_YIELD));
 
 	if (fp->state & BNX2X_FP_STATE_POLL_YIELD)
 		rc = true;
-	fp->state = BNX2X_FP_STATE_IDLE;
-	spin_unlock(&fp->lock);
+
+	/* state ==> idle, unless currently disabled */
+	fp->state &= BNX2X_FP_STATE_DISABLED;
+	spin_unlock_bh(&fp->lock);
 	return rc;
 }
 
@@ -669,7 +673,9 @@ static inline bool bnx2x_fp_unlock_poll(struct bnx2x_fastpath *fp)
 
 	if (fp->state & BNX2X_FP_STATE_POLL_YIELD)
 		rc = true;
-	fp->state = BNX2X_FP_STATE_IDLE;
+
+	/* state ==> idle, unless currently disabled */
+	fp->state &= BNX2X_FP_STATE_DISABLED;
 	spin_unlock_bh(&fp->lock);
 	return rc;
 }
@@ -677,9 +683,23 @@ static inline bool bnx2x_fp_unlock_poll(struct bnx2x_fastpath *fp)
 /* true if a socket is polling, even if it did not get the lock */
 static inline bool bnx2x_fp_ll_polling(struct bnx2x_fastpath *fp)
 {
-	WARN_ON(!(fp->state & BNX2X_FP_LOCKED));
+	WARN_ON(!(fp->state & BNX2X_FP_OWNED));
 	return fp->state & BNX2X_FP_USER_PEND;
 }
+
+/* false if fp is currently owned */
+static inline bool bnx2x_fp_ll_disable(struct bnx2x_fastpath *fp)
+{
+	int rc = true;
+
+	spin_lock_bh(&fp->lock);
+	if (fp->state & BNX2X_FP_OWNED)
+		rc = false;
+	fp->state |= BNX2X_FP_STATE_DISABLED;
+	spin_unlock_bh(&fp->lock);
+
+	return rc;
+}
 #else
 static inline void bnx2x_fp_init_lock(struct bnx2x_fastpath *fp)
 {
@@ -709,6 +729,10 @@ static inline bool bnx2x_fp_ll_polling(struct bnx2x_fastpath *fp)
 {
 	return false;
 }
+static inline bool bnx2x_fp_ll_disable(struct bnx2x_fastpath *fp)
+{
+	return true;
+}
 #endif /* CONFIG_NET_RX_BUSY_POLL */
 
 /* Use 2500 as a mini-jumbo MTU for FCoE */
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
index ec96130..c6745d7 100644
--- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_cmn.c
@@ -1790,26 +1790,22 @@ static void bnx2x_napi_disable_cnic(struct bnx2x *bp)
 {
 	int i;
 
-	local_bh_disable();
 	for_each_rx_queue_cnic(bp, i) {
 		napi_disable(&bnx2x_fp(bp, i, napi));
-		while (!bnx2x_fp_lock_napi(&bp->fp[i]))
-			mdelay(1);
+		while (!bnx2x_fp_ll_disable(&bp->fp[i]))
+			usleep_range(1000, 2000);
 	}
-	local_bh_enable();
 }
 
 static void bnx2x_napi_disable(struct bnx2x *bp)
 {
 	int i;
 
-	local_bh_disable();
 	for_each_eth_queue(bp, i) {
 		napi_disable(&bnx2x_fp(bp, i, napi));
-		while (!bnx2x_fp_lock_napi(&bp->fp[i]))
-			mdelay(1);
+		while (!bnx2x_fp_ll_disable(&bp->fp[i]))
+			usleep_range(1000, 2000);
 	}
-	local_bh_enable();
 }
 
 void bnx2x_netif_start(struct bnx2x *bp)
-- 
1.8.1.227.g44fe835

^ permalink raw reply related

* Re: single process receives own frames due to PACKET_MMAP
From: Jesper Dangaard Brouer @ 2014-01-07 10:06 UTC (permalink / raw)
  To: Norbert van Bolhuis; +Cc: Daniel Borkmann, netdev, David Miller, uaca
In-Reply-To: <52CBC991.8030701@redhat.com>

On Tue, 07 Jan 2014 10:32:01 +0100
Daniel Borkmann <dborkman@redhat.com> wrote:

> On 01/06/2014 11:58 PM, Norbert van Bolhuis wrote:
> >
> > Our application uses raw AF_PACKET socket to send and receive
> > on one particular ethernet interface.
> >
> > Recently we started using PACKET_MMAP (TPACKET_V2). This makes
> > the Appl use a TX socket and a RX socket.
> > Both sockets are bound to the same (eth) interface. I noticed
> > the RX socket receives all frames that are sent via the
> > TX socket (same process, different thread). This I do not want.
> >
> > I know it is supposed to happen for different processes
> > (otherwise wireshark won't work), but I did not expect it to
> > happen for one single process (with different threads).
> >
> > I can filter them out in user-space (PACKET_OUTGOING)
> > or via kernel packet filter (SO_ATTACH_FILTER), but performance is
> > critical.
> >
> > I wonder whether this (PACKET_MMAP) behaviour is OK.
> 
> For your use-case, we recently introduced in d346a3fae3ff1
> ("packet: introduce PACKET_QDISC_BYPASS socket option") a
> bypass of dev_queue_xmit() (that internally invokes
> dev_queue_xmit_nit()).
> 
> > It did not happen before (with a non-PACKET_MMAP AF_PACKET socket
> > which was used by both threads of the same Appl process). So
> > why is it happening now ?
> 
> Can you elaborate a bit on which kernel versions that behaviour
> changed?
> 
> > I'd say it makes no sense to make the same process receive its
> > own transmitted frames on that same interface (unless its lo).

Have you setup:
 ring->s_ll.sll_protocol = 0

This is what I did in trafgen to avoid this problem.

See line 55 in netsniff-ng/ring.c:
 https://github.com/borkmann/netsniff-ng/blob/c3602a995b21e8133c7f4fd1fb1e7e21b6a844f1/ring.c#L55

Commit:
 https://github.com/borkmann/netsniff-ng/commit/c3602a995b21e8133c7f4fd1fb1e7e21b6a844f1

> > If I'm not doing something wrong, this means this behaviour
> > causes my CPU to be loaded much more (since all transmitted frames
> > have to be filtered out).
> >
> > Let me know what you think.
> >
> > thanks,
> > Norbert van Bolhuis

-- 
Best regards,
  Jesper Dangaard Brouer
  MSc.CS, Sr. Network Kernel Developer at Red Hat
  Author of http://www.iptv-analyzer.org
  LinkedIn: http://www.linkedin.com/in/brouer

^ permalink raw reply

* Re: [PATCH v3 4/5] alx: add alx_get_stats64 operation
From: Sabrina Dubroca @ 2014-01-07 10:02 UTC (permalink / raw)
  To: Ben Hutchings; +Cc: davem, johannes, stephen, netdev
In-Reply-To: <1389035253.9947.93.camel@bwh-desktop.uk.level5networks.com>

Then the stats in all atheros drivers are a bit broken? They all use
the same formulas for ndo_get_stats.

Other atheros drivers (atl1e/atl1e.h and atl1c/atl1c.h) have the same
stats structure with a comment for each field. I will copy the
comments to alx.h.


2014-01-06, 19:07:33 +0000, Ben Hutchings wrote:
> On Mon, 2014-01-06 at 17:33 +0100, Sabrina Dubroca wrote:
> [...]
> > --- a/drivers/net/ethernet/atheros/alx/main.c
> > +++ b/drivers/net/ethernet/atheros/alx/main.c
> > @@ -1166,10 +1166,54 @@ static void alx_poll_controller(struct net_device *netdev)
> >  }
> >  #endif
> >  
> > +static struct rtnl_link_stats64 *alx_get_stats64(struct net_device *dev,
> > +					struct rtnl_link_stats64 *net_stats)
> > +{
> > +	struct alx_priv *alx = netdev_priv(dev);
> > +	struct alx_hw_stats *hw_stats = &alx->hw.stats;
> > +
> > +	spin_lock(&alx->stats_lock);
> > +
> > +	alx_update_hw_stats(&alx->hw);
> > +
> > +	net_stats->tx_packets = hw_stats->tx_ok;
> 
> I think this should be set to hw_stats->tx_ok + net_stats->tx_errors
> (after you set tx_errors).
> 
> > +	net_stats->tx_bytes   = hw_stats->tx_byte_cnt;
> > +	net_stats->rx_packets = hw_stats->rx_ok;
> 
> Similarly, I think this should be hw_stats->rx_ok +
> net_stats->rx_errors.
> 
> > +	net_stats->rx_bytes   = hw_stats->rx_byte_cnt;
> > +	net_stats->multicast  = hw_stats->rx_mcast;
> > +	net_stats->collisions = hw_stats->tx_single_col +
> > +				hw_stats->tx_multi_col * 2 +
> 
> I would expect this to count the number of packets that had collisions
> rather than total number of collisions (which you're only guessing at by
> using * 2).

Okay, all changed.


> > +				hw_stats->tx_late_col + hw_stats->tx_abort_col;
> > +
> > +	net_stats->rx_errors  = hw_stats->rx_frag + hw_stats->rx_fcs_err +
> > +				hw_stats->rx_len_err + hw_stats->rx_ov_sz +
> > +				hw_stats->rx_ov_rrd + hw_stats->rx_align_err;
> > +
> > +	net_stats->rx_fifo_errors   = hw_stats->rx_ov_rxf;
> > +	net_stats->rx_length_errors = hw_stats->rx_len_err;
> > +	net_stats->rx_crc_errors    = hw_stats->rx_fcs_err;
> > +	net_stats->rx_frame_errors  = hw_stats->rx_align_err;
> > +	net_stats->rx_over_errors   = hw_stats->rx_ov_rrd + hw_stats->rx_ov_rxf;
> 
> rx_over_errors is commented as 'receiver ring buff overflow' and
> ifconfig includes it in the 'frame' error count.  I think it is intended
> to count frames which are too large for on-chip RX buffers and should
> always be 0 for devices that do RX DMA.
> 
> Each error should contribute to at most one specific error stat, so
> don't count rx_ov_rxf in both rx_fifo_errors and rx_over_errors.  I
> would guess rx_fifo_errors is the right counter.
>
> I don't know what rx_ov_rrd represents, but if it's the number of
> packets dropped because the RX descriptor ring was empty then it should
> be counted in rx_dropped not rx_over_errors.

in atl1e/atl1e.h:
rx_ov_rxf: The number of frame dropped due to occurrence of RX FIFO overflow.
rx_ov_rrd: The number of frame dropped due to occurrence of RRD overflow.

I'm not sure which counter fits these best.


> > +	net_stats->rx_missed_errors = hw_stats->rx_ov_rrd + hw_stats->rx_ov_rxf;
> [...]
> 
> This counter is commented as 'receiver missed packet'.  I think this
> means the MAC detected SOF but was somehow too busy to receive the
> packet, but I'm not sure.  I don't think these hardware counters match
> the description, and certainly they shouldn't be counted here as well as
> the other specific error stats.

Okay.


Thanks,

-- 
Sabrina

^ permalink raw reply

* RE: [PATCH net-next 0/2] Pack struct xfrm_usersa_info and struct xfrm_userpolicy_info
From: David Laight @ 2014-01-07 10:00 UTC (permalink / raw)
  To: 'Fan Du', Steffen Klassert
  Cc: davem@davemloft.net, stephen@networkplumber.org,
	dev@lists.strongswan.org, netdev@vger.kernel.org
In-Reply-To: <52CBB3FC.9050207@windriver.com>

> From: Fan Du
> Sent: 07 January 2014 08:00
> On 2014?01?07? 15:47, Steffen Klassert wrote:
> > On Tue, Jan 07, 2014 at 02:48:57PM +0800, Fan Du wrote:
> >> When trying to setup IPsec configuration on a 64bits host with
> >> iproute2(32bits compiled), the intened xfrm policy and sa is
> >> either deficit or wrong when kernel trying to parse user land
> >> information.
> >>
> >> Further investigatino shows that:
> >> L: kernel
> >> R: iproute2
> >>
> >>            sizeof       userpolicy      usersa
> >> 64bits(unpacked)        168/168        224/224
> >> 32bits(unpacked)        164/164        220/220
> >>                           ^   ^
> >>                           L   R
> >>
> >> To keep kernel and user land see a consistent structure, after
> >> add packing attribute, now it looks like this:
> >>
> >> 64bits(  packed)        164/164        217/217
> >> 32bits(  packed)        164/164        217/217
> >>                           ^   ^
> >>                           L   R
> >>
> >
> > We don't change userspace exported structures. This breaks
> > existing userspace tools.
> >
> 
> Then user with 32bits iproute2 or StrongSwan has to rebuild as 64bits?

The kernel has support (in various places) for different structure
layouts for 32bit and 64bit processes.
Looks like it needs one here as well (I'm not volunteering though).

At a guess the structures contain a 64bit field that is on an 8n+4
byte boundary. On i386 64bit fields are only 4 byte aligned, on
amd64 they are 8 byte aligned.

Packing the structures is definitely wrong. Some 32bit systems (IIRC sparc)
align 64bit items on 8 byte boundaries. Not to mention the expensive byte
by byte accesses this forces on some systems.

The structure could have been defined with the 64bit field marked
__attribute__((aligned(4))) - so using the same layout on 32bit
and 64 bit systems , but it is too late to do that now.

	David


^ permalink raw reply

* Re: [PATCH 1/1] ipv6 addrconf: add IFA_F_NOPREFIXROUTE flag to suppress creation of IP6 routes
From: Hannes Frederic Sowa @ 2014-01-07  9:39 UTC (permalink / raw)
  To: Jiri Pirko; +Cc: Thomas Haller, netdev, stephen, dcbw
In-Reply-To: <20140106173837.GA2571@minipsycho.orion>

On Mon, Jan 06, 2014 at 06:38:37PM +0100, Jiri Pirko wrote:
> Mon, Jan 06, 2014 at 06:29:35PM CET, thaller@redhat.com wrote:
> >When adding/modifying an IPv6 address, the userspace application needs
> >a way to suppress adding a prefix route. This is for example relevant
> >together with IFA_F_MANAGERTEMPADDR, where userspace creates autoconf
> >generated addresses, but depending on on-link, no route should for the
> >prefix should be added.
> >
> >This flag will not be set as ifa_flags of the address, it is only
> >considered as parameter while adding/modifying an address.
> >
> >Signed-off-by: Thomas Haller <thaller@redhat.com>
> >---
> > Hi, how about this?
> >
> > The flag is only a parameter for the netlink command.
> > This might be unexpected, because when adding an address,
> > you won't see the flag in `ip -6 addr`.
> > Still, I think, it is better to do it this way, because having
> > an address with the NOPREFIXROUTE flag, does not mean, that
> > there is no route for this prefix. It only means, that at the
> > moment of setting the address, no route was added.
> >
> > The alternative would be, not to add a prefix route, when
> > IFA_F_MANAGERTEMPADDR is set.

Looks good, maybe you could apply Jiri's feedback.

Otherwise we could skip trying to find a corresponding prefix route in
ipv6_del_addr. You would need to add the IFA_F_NOPREFIXROUTE test just before
the addrconf_get_prefix_route and ip6_del_rt.

Greetings,

  Hannes

^ permalink raw reply

* Re: single process receives own frames due to PACKET_MMAP
From: Daniel Borkmann @ 2014-01-07  9:32 UTC (permalink / raw)
  To: Norbert van Bolhuis; +Cc: netdev, David Miller, uaca, Jesper Dangaard Brouer
In-Reply-To: <52CB34F9.6020906@aimvalley.nl>

On 01/06/2014 11:58 PM, Norbert van Bolhuis wrote:
>
> Our application uses raw AF_PACKET socket to send and receive
> on one particular ethernet interface.
>
> Recently we started using PACKET_MMAP (TPACKET_V2). This makes
> the Appl use a TX socket and a RX socket.
> Both sockets are bound to the same (eth) interface. I noticed
> the RX socket receives all frames that are sent via the
> TX socket (same process, different thread). This I do not want.
>
> I know it is supposed to happen for different processes
> (otherwise wireshark won't work), but I did not expect it to
> happen for one single process (with different threads).
>
> I can filter them out in user-space (PACKET_OUTGOING)
> or via kernel packet filter (SO_ATTACH_FILTER), but performance is
> critical.
>
> I wonder whether this (PACKET_MMAP) behaviour is OK.

For your use-case, we recently introduced in d346a3fae3ff1
("packet: introduce PACKET_QDISC_BYPASS socket option") a
bypass of dev_queue_xmit() (that internally invokes
dev_queue_xmit_nit()).

> It did not happen before (with a non-PACKET_MMAP AF_PACKET socket
> which was used by both threads of the same Appl process). So
> why is it happening now ?

Can you elaborate a bit on which kernel versions that behaviour
changed?

> I'd say it makes no sense to make the same process receive its
> own transmitted frames on that same interface (unless its lo).
>
> If I'm not doing something wrong, this means this behaviour
> causes my CPU to be loaded much more (since all transmitted frames
> have to be filtered out).
>
> Let me know what you think.
>
> thanks,
> Norbert van Bolhuis
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [net-next 15/15] i40e: correctly setup ARQ descriptors
From: Jeff Kirsher @ 2014-01-07  9:32 UTC (permalink / raw)
  To: davem
  Cc: Mitch Williams, netdev, gospo, sassmann, Jesse Brandeburg,
	Jeff Kirsher
In-Reply-To: <1389087149-27962-1-git-send-email-jeffrey.t.kirsher@intel.com>

From: Mitch Williams <mitch.a.williams@intel.com>

When cleaning descriptors, we must set up ALL fields, not just the DMA
address. The initial setup does this correctly, but not the cleanup
code, so the firmware would process the ring exactly once and then fail.

Change-ID: I2930b83c76194b3016a8ac0fa693f9a573995640
Signed-off-by: Mitch Williams <mitch.a.williams@intel.com>
Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Tested-by: Kavindya Deegala <kavindya.s.deegala@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/i40e/i40e_adminq.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq.c b/drivers/net/ethernet/intel/i40e/i40e_adminq.c
index c87dc15..2b32084 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_adminq.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_adminq.c
@@ -933,6 +933,11 @@ i40e_status i40e_clean_arq_element(struct i40e_hw *hw,
 	 * size
 	 */
 	bi = &hw->aq.arq.r.arq_bi[ntc];
+	memset((void *)desc, 0, sizeof(struct i40e_aq_desc));
+
+	desc->flags = cpu_to_le16(I40E_AQ_FLAG_BUF);
+	if (hw->aq.arq_buf_size > I40E_AQ_LARGE_BUF)
+		desc->flags |= cpu_to_le16(I40E_AQ_FLAG_LB);
 	desc->datalen = cpu_to_le16((u16)bi->size);
 	desc->params.external.addr_high = cpu_to_le32(upper_32_bits(bi->pa));
 	desc->params.external.addr_low = cpu_to_le32(lower_32_bits(bi->pa));
-- 
1.8.3.1

^ permalink raw reply related

* [net-next 14/15] i40e: remove redundant AQ enable
From: Jeff Kirsher @ 2014-01-07  9:32 UTC (permalink / raw)
  To: davem
  Cc: Kamil Krawczyk, netdev, gospo, sassmann, Jesse Brandeburg,
	Jeff Kirsher
In-Reply-To: <1389087149-27962-1-git-send-email-jeffrey.t.kirsher@intel.com>

From: Kamil Krawczyk <kamil.krawczyk@intel.com>

The admin queue length register is updated in
config_a<sq|rq>_regs functions.  We should not update it again,
as we will trigger firmware to init the AQ again. In this case
firmware will lose the information about the AQ Rx tail position
and will see Rx queue as full (no free desc for FW to use).

Signed-off-by: Kamil Krawczyk <kamil.krawczyk@intel.com>
Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Tested-by: Kavindya Deegala <kavindya.s.deegala@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/i40e/i40e_adminq.c | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq.c b/drivers/net/ethernet/intel/i40e/i40e_adminq.c
index 18a768f..c87dc15 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_adminq.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_adminq.c
@@ -957,20 +957,14 @@ clean_arq_element_out:
 
 static void i40e_resume_aq(struct i40e_hw *hw)
 {
-	u32 reg = 0;
-
 	/* Registers are reset after PF reset */
 	hw->aq.asq.next_to_use = 0;
 	hw->aq.asq.next_to_clean = 0;
 
 	i40e_config_asq_regs(hw);
-	reg = hw->aq.num_asq_entries | I40E_PF_ATQLEN_ATQENABLE_MASK;
-	wr32(hw, hw->aq.asq.len, reg);
 
 	hw->aq.arq.next_to_use = 0;
 	hw->aq.arq.next_to_clean = 0;
 
 	i40e_config_arq_regs(hw);
-	reg = hw->aq.num_arq_entries | I40E_PF_ATQLEN_ATQENABLE_MASK;
-	wr32(hw, hw->aq.arq.len, reg);
 }
-- 
1.8.3.1

^ permalink raw reply related

* [net-next 13/15] i40e: Enable/Disable PF switch LB on SR-IOV configure changes
From: Jeff Kirsher @ 2014-01-07  9:32 UTC (permalink / raw)
  To: davem; +Cc: Greg Rose, netdev, gospo, sassmann, Jeff Kirsher
In-Reply-To: <1389087149-27962-1-git-send-email-jeffrey.t.kirsher@intel.com>

From: Greg Rose <gregory.v.rose@intel.com>

The PF VSI was never updated to enable or disable internal switch loopback
when VFs were created or destroyed via the sysfs interface.  Add some
helper functions to take care of that.

Signed-off-by: Greg Rose <gregory.v.rose@intel.com>
Tested-by: Sibai Li <sibai.li@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c | 76 +++++++++++++++++++++-
 1 file changed, 74 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
index 5c99164..efb9a24 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
@@ -716,6 +716,76 @@ static bool i40e_vfs_are_assigned(struct i40e_pf *pf)
 
 	return false;
 }
+#ifdef CONFIG_PCI_IOV
+
+/**
+ * i40e_enable_pf_switch_lb
+ * @pf: pointer to the pf structure
+ *
+ * enable switch loop back or die - no point in a return value
+ **/
+static void i40e_enable_pf_switch_lb(struct i40e_pf *pf)
+{
+	struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];
+	struct i40e_vsi_context ctxt;
+	int aq_ret;
+
+	ctxt.seid = pf->main_vsi_seid;
+	ctxt.pf_num = pf->hw.pf_id;
+	ctxt.vf_num = 0;
+	aq_ret = i40e_aq_get_vsi_params(&pf->hw, &ctxt, NULL);
+	if (aq_ret) {
+		dev_info(&pf->pdev->dev,
+			 "%s couldn't get pf vsi config, err %d, aq_err %d\n",
+			 __func__, aq_ret, pf->hw.aq.asq_last_status);
+		return;
+	}
+	ctxt.flags = I40E_AQ_VSI_TYPE_PF;
+	ctxt.info.valid_sections = cpu_to_le16(I40E_AQ_VSI_PROP_SWITCH_VALID);
+	ctxt.info.switch_id |= cpu_to_le16(I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB);
+
+	aq_ret = i40e_aq_update_vsi_params(&vsi->back->hw, &ctxt, NULL);
+	if (aq_ret) {
+		dev_info(&pf->pdev->dev,
+			 "%s: update vsi switch failed, aq_err=%d\n",
+			 __func__, vsi->back->hw.aq.asq_last_status);
+	}
+}
+#endif
+
+/**
+ * i40e_disable_pf_switch_lb
+ * @pf: pointer to the pf structure
+ *
+ * disable switch loop back or die - no point in a return value
+ **/
+static void i40e_disable_pf_switch_lb(struct i40e_pf *pf)
+{
+	struct i40e_vsi *vsi = pf->vsi[pf->lan_vsi];
+	struct i40e_vsi_context ctxt;
+	int aq_ret;
+
+	ctxt.seid = pf->main_vsi_seid;
+	ctxt.pf_num = pf->hw.pf_id;
+	ctxt.vf_num = 0;
+	aq_ret = i40e_aq_get_vsi_params(&pf->hw, &ctxt, NULL);
+	if (aq_ret) {
+		dev_info(&pf->pdev->dev,
+			 "%s couldn't get pf vsi config, err %d, aq_err %d\n",
+			 __func__, aq_ret, pf->hw.aq.asq_last_status);
+		return;
+	}
+	ctxt.flags = I40E_AQ_VSI_TYPE_PF;
+	ctxt.info.valid_sections = cpu_to_le16(I40E_AQ_VSI_PROP_SWITCH_VALID);
+	ctxt.info.switch_id &= ~cpu_to_le16(I40E_AQ_VSI_SW_ID_FLAG_ALLOW_LB);
+
+	aq_ret = i40e_aq_update_vsi_params(&vsi->back->hw, &ctxt, NULL);
+	if (aq_ret) {
+		dev_info(&pf->pdev->dev,
+			 "%s: update vsi switch failed, aq_err=%d\n",
+			 __func__, vsi->back->hw.aq.asq_last_status);
+	}
+}
 
 /**
  * i40e_free_vfs
@@ -759,10 +829,11 @@ void i40e_free_vfs(struct i40e_pf *pf)
 			bit_idx = (hw->func_caps.vf_base_id + vf_id) % 32;
 			wr32(hw, I40E_GLGEN_VFLRSTAT(reg_idx), (1 << bit_idx));
 		}
-	}
-	else
+		i40e_disable_pf_switch_lb(pf);
+	} else {
 		dev_warn(&pf->pdev->dev,
 			 "unable to disable SR-IOV because VFs are assigned.\n");
+	}
 
 	/* Re-enable interrupt 0. */
 	i40e_irq_dynamic_enable_icr0(pf);
@@ -816,6 +887,7 @@ static int i40e_alloc_vfs(struct i40e_pf *pf, u16 num_alloc_vfs)
 	pf->vf = vfs;
 	pf->num_alloc_vfs = num_alloc_vfs;
 
+	i40e_enable_pf_switch_lb(pf);
 err_alloc:
 	if (ret)
 		i40e_free_vfs(pf);
-- 
1.8.3.1

^ permalink raw reply related

* [net-next 12/15] i40e: whitespace paren and comment tweaks
From: Jeff Kirsher @ 2014-01-07  9:32 UTC (permalink / raw)
  To: davem; +Cc: Shannon Nelson, netdev, gospo, sassmann, Mitch Williams,
	Jeff Kirsher
In-Reply-To: <1389087149-27962-1-git-send-email-jeffrey.t.kirsher@intel.com>

From: Shannon Nelson <shannon.nelson@intel.com>

Addresses a few code format issues that have crept in over time.

Change-Id: I1a62cbd16b29a218a933b0f7176abe748f9615e8
Signed-off-by: Mitch Williams <mitch.a.williams@intel.com>
Signed-off-by: Shannon Nelson <shannon.nelson@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/i40e/i40e_adminq.c | 4 ++--
 drivers/net/ethernet/intel/i40e/i40e_common.c | 1 +
 drivers/net/ethernet/intel/i40e/i40e_type.h   | 8 ++++----
 3 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq.c b/drivers/net/ethernet/intel/i40e/i40e_adminq.c
index 3ee5323..18a768f 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_adminq.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_adminq.c
@@ -672,7 +672,7 @@ static bool i40e_asq_done(struct i40e_hw *hw)
 	/* AQ designers suggest use of head for better
 	 * timing reliability than DD bit
 	 */
-	return (rd32(hw, hw->aq.asq.head) == hw->aq.asq.next_to_use);
+	return rd32(hw, hw->aq.asq.head) == hw->aq.asq.next_to_use;
 
 }
 
@@ -682,7 +682,7 @@ static bool i40e_asq_done(struct i40e_hw *hw)
  *  @desc: prefilled descriptor describing the command (non DMA mem)
  *  @buff: buffer to use for indirect commands
  *  @buff_size: size of buffer for indirect commands
- *  @opaque: pointer to info to be used in async cleanup
+ *  @cmd_details: pointer to command details structure
  *
  *  This is the main send command driver routine for the Admin Queue send
  *  queue.  It runs the queue, cleans the queue, etc
diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c
index 7e34de1..d564910 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_common.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_common.c
@@ -406,6 +406,7 @@ i40e_status i40e_pf_reset(struct i40e_hw *hw)
 	}
 
 	i40e_clear_pxe_mode(hw);
+
 	return 0;
 }
 
diff --git a/drivers/net/ethernet/intel/i40e/i40e_type.h b/drivers/net/ethernet/intel/i40e/i40e_type.h
index 4ac712e..bcf0317 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_type.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_type.h
@@ -89,7 +89,7 @@ typedef void (*I40E_ADMINQ_CALLBACK)(struct i40e_hw *, struct i40e_aq_desc *);
 #define I40E_QTX_CTL_VF_QUEUE	0x0
 #define I40E_QTX_CTL_PF_QUEUE	0x2
 
-/* debug masks */
+/* debug masks - set these bits in hw->debug_mask to control output */
 enum i40e_debug_mask {
 	I40E_DEBUG_INIT			= 0x00000001,
 	I40E_DEBUG_RELEASE		= 0x00000002,
@@ -103,10 +103,10 @@ enum i40e_debug_mask {
 	I40E_DEBUG_DCB			= 0x00000400,
 	I40E_DEBUG_DIAG			= 0x00000800,
 
-	I40E_DEBUG_AQ_MESSAGE		= 0x01000000, /* for i40e_debug() */
+	I40E_DEBUG_AQ_MESSAGE		= 0x01000000,
 	I40E_DEBUG_AQ_DESCRIPTOR	= 0x02000000,
 	I40E_DEBUG_AQ_DESC_BUFFER	= 0x04000000,
-	I40E_DEBUG_AQ_COMMAND		= 0x06000000, /* for i40e_debug_aq() */
+	I40E_DEBUG_AQ_COMMAND		= 0x06000000,
 	I40E_DEBUG_AQ			= 0x0F000000,
 
 	I40E_DEBUG_USER			= 0xF0000000,
@@ -520,7 +520,7 @@ enum i40e_rx_desc_status_bits {
 
 #define I40E_RXD_QW1_STATUS_TSYNVALID_SHIFT  I40E_RX_DESC_STATUS_TSYNVALID_SHIFT
 #define I40E_RXD_QW1_STATUS_TSYNVALID_MASK	(0x1UL << \
-					     I40E_RXD_QW1_STATUS_TSYNVALID_SHIFT)
+					 I40E_RXD_QW1_STATUS_TSYNVALID_SHIFT)
 
 enum i40e_rx_desc_fltstat_values {
 	I40E_RX_DESC_FLTSTAT_NO_DATA	= 0,
-- 
1.8.3.1

^ permalink raw reply related

* [net-next 11/15] i40e: rework shadow ram read functions
From: Jeff Kirsher @ 2014-01-07  9:32 UTC (permalink / raw)
  To: davem; +Cc: Shannon Nelson, netdev, gospo, sassmann, Kamil Krawczyk,
	Jeff Kirsher
In-Reply-To: <1389087149-27962-1-git-send-email-jeffrey.t.kirsher@intel.com>

From: Shannon Nelson <shannon.nelson@intel.com>

Rework Shadow RAM read word/buffer functions to not use AQ Request
Resource commands.  Requesting resource is not needed for SR read
operations which are done through SRCTL register.  Access to SR through
register is controlled through DONE bit within SRCTL.  With this change
we do not block whole NVM resource for SR read operations.

Change-Id: I73e96cdea39a45ee7b5bdf038e527308de2d9efe
Signed-off-by: Kamil Krawczyk <kamil.krawczyk@intel.com>
Signed-off-by: Shannon Nelson <shannon.nelson@intel.com>
Tested-by: Kavindya Deegala <kavindya.s.deegala@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/i40e/i40e_nvm.c | 67 +++++++-----------------------
 1 file changed, 16 insertions(+), 51 deletions(-)

diff --git a/drivers/net/ethernet/intel/i40e/i40e_nvm.c b/drivers/net/ethernet/intel/i40e/i40e_nvm.c
index 97e1bb3..e2da0a2 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_nvm.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_nvm.c
@@ -166,15 +166,15 @@ static i40e_status i40e_poll_sr_srctl_done_bit(struct i40e_hw *hw)
 }
 
 /**
- *  i40e_read_nvm_srctl - Reads Shadow RAM.
+ *  i40e_read_nvm_word - Reads Shadow RAM
  *  @hw: pointer to the HW structure.
  *  @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF).
  *  @data: word read from the Shadow RAM.
  *
  *  Reads 16 bit word from the Shadow RAM using the GLNVM_SRCTL register.
  **/
-static i40e_status i40e_read_nvm_srctl(struct i40e_hw *hw, u16 offset,
-						 u16 *data)
+i40e_status i40e_read_nvm_word(struct i40e_hw *hw, u16 offset,
+					 u16 *data)
 {
 	i40e_status ret_code = I40E_ERR_TIMEOUT;
 	u32 sr_reg;
@@ -211,29 +211,6 @@ read_nvm_exit:
 }
 
 /**
- *  i40e_read_nvm_word - Reads Shadow RAM word.
- *  @hw: pointer to the HW structure.
- *  @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF).
- *  @data: word read from the Shadow RAM.
- *
- *  Reads 16 bit word from the Shadow RAM. Each read is preceded
- *  with the NVM ownership taking and followed by the release.
- **/
-i40e_status i40e_read_nvm_word(struct i40e_hw *hw, u16 offset,
-					 u16 *data)
-{
-	i40e_status ret_code = 0;
-
-	ret_code = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
-	if (!ret_code) {
-		ret_code = i40e_read_nvm_srctl(hw, offset, data);
-		i40e_release_nvm(hw);
-	}
-
-	return ret_code;
-}
-
-/**
  *  i40e_read_nvm_buffer - Reads Shadow RAM buffer.
  *  @hw: pointer to the HW structure.
  *  @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF).
@@ -250,30 +227,18 @@ i40e_status i40e_read_nvm_buffer(struct i40e_hw *hw, u16 offset,
 {
 	i40e_status ret_code = 0;
 	u16 index, word;
-	u32 time;
 
-	ret_code = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
-	if (!ret_code) {
-		/* Loop thru the selected region. */
-		for (word = 0; word < *words; word++) {
-			index = offset + word;
-			ret_code = i40e_read_nvm_srctl(hw, index, &data[word]);
-			if (ret_code)
-				break;
-			/* Check if we didn't exceeded the semaphore timeout. */
-			time = rd32(hw, I40E_GLVFGEN_TIMER);
-			if (time >= hw->nvm.hw_semaphore_timeout) {
-				ret_code = I40E_ERR_TIMEOUT;
-				hw_dbg(hw, "NVM read error: timeout.\n");
-				break;
-			}
-		}
-		/* Update the number of words read from the Shadow RAM. */
-		*words = word;
-		/* Release the NVM ownership. */
-		i40e_release_nvm(hw);
+	/* Loop thru the selected region. */
+	for (word = 0; word < *words; word++) {
+		index = offset + word;
+		ret_code = i40e_read_nvm_word(hw, index, &data[word]);
+		if (ret_code)
+			break;
 	}
 
+	/* Update the number of words read from the Shadow RAM. */
+	*words = word;
+
 	return ret_code;
 }
 
@@ -297,14 +262,14 @@ static i40e_status i40e_calc_nvm_checksum(struct i40e_hw *hw,
 	u32 i = 0;
 
 	/* read pointer to VPD area */
-	ret_code = i40e_read_nvm_srctl(hw, I40E_SR_VPD_PTR, &vpd_module);
+	ret_code = i40e_read_nvm_word(hw, I40E_SR_VPD_PTR, &vpd_module);
 	if (ret_code) {
 		ret_code = I40E_ERR_NVM_CHECKSUM;
 		goto i40e_calc_nvm_checksum_exit;
 	}
 
 	/* read pointer to PCIe Alt Auto-load module */
-	ret_code = i40e_read_nvm_srctl(hw, I40E_SR_PCIE_ALT_AUTO_LOAD_PTR,
+	ret_code = i40e_read_nvm_word(hw, I40E_SR_PCIE_ALT_AUTO_LOAD_PTR,
 				       &pcie_alt_module);
 	if (ret_code) {
 		ret_code = I40E_ERR_NVM_CHECKSUM;
@@ -331,7 +296,7 @@ static i40e_status i40e_calc_nvm_checksum(struct i40e_hw *hw,
 				break;
 		}
 
-		ret_code = i40e_read_nvm_srctl(hw, (u16)i, &word);
+		ret_code = i40e_read_nvm_word(hw, (u16)i, &word);
 		if (ret_code) {
 			ret_code = I40E_ERR_NVM_CHECKSUM;
 			goto i40e_calc_nvm_checksum_exit;
@@ -371,7 +336,7 @@ i40e_status i40e_validate_nvm_checksum(struct i40e_hw *hw,
 	/* Do not use i40e_read_nvm_word() because we do not want to take
 	 * the synchronization semaphores twice here.
 	 */
-	i40e_read_nvm_srctl(hw, I40E_SR_SW_CHECKSUM_WORD, &checksum_sr);
+	i40e_read_nvm_word(hw, I40E_SR_SW_CHECKSUM_WORD, &checksum_sr);
 
 	/* Verify read checksum from EEPROM is the same as
 	 * calculated checksum
-- 
1.8.3.1

^ permalink raw reply related

* [net-next 09/15] i40e: move PF ID init from PF reset to SC init
From: Jeff Kirsher @ 2014-01-07  9:32 UTC (permalink / raw)
  To: davem; +Cc: Shannon Nelson, netdev, gospo, sassmann, Kamil Krawczyk,
	Jeff Kirsher
In-Reply-To: <1389087149-27962-1-git-send-email-jeffrey.t.kirsher@intel.com>

From: Shannon Nelson <shannon.nelson@intel.com>

Move PF ID initialization code from PF reset routine to earlier driver
initialization function.  There are a few operations which need the
PF ID before the first PF reset is called.

Change-Id: I7e971f7556b46a837149850ec05ce115c35db575
Signed-off-by: Kamil Krawczyk <kamil.krawczyk@intel.com>
Signed-off-by: Shannon Nelson <shannon.nelson@intel.com>
Tested-by: Kavindya Deegala <kavindya.s.deegala@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/i40e/i40e_common.c | 14 +++++++-------
 1 file changed, 7 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c
index 96c8f15..02ad529 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_common.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_common.c
@@ -198,6 +198,13 @@ i40e_status i40e_init_shared_code(struct i40e_hw *hw)
 		break;
 	}
 
+	/* Determine the PF number based on the PCI fn */
+	reg = rd32(hw, I40E_GLPCI_CAPSUP);
+	if (reg & I40E_GLPCI_CAPSUP_ARI_EN_MASK)
+		hw->pf_id = (u8)((hw->bus.device << 3) | hw->bus.func);
+	else
+		hw->pf_id = (u8)hw->bus.func;
+
 	status = i40e_init_nvm(hw);
 	return status;
 }
@@ -375,13 +382,6 @@ i40e_status i40e_pf_reset(struct i40e_hw *hw)
 		return I40E_ERR_RESET_FAILED;
 	}
 
-	/* Determine the PF number based on the PCI fn */
-	reg = rd32(hw, I40E_GLPCI_CAPSUP);
-	if (reg & I40E_GLPCI_CAPSUP_ARI_EN_MASK)
-		hw->pf_id = (u8)((hw->bus.device << 3) | hw->bus.func);
-	else
-		hw->pf_id = (u8)hw->bus.func;
-
 	/* If there was a Global Reset in progress when we got here,
 	 * we don't need to do the PF Reset
 	 */
-- 
1.8.3.1

^ permalink raw reply related

* [net-next 10/15] i40e: check MAC type before any REG access
From: Jeff Kirsher @ 2014-01-07  9:32 UTC (permalink / raw)
  To: davem; +Cc: Shannon Nelson, netdev, gospo, sassmann, Kamil Krawczyk,
	Jeff Kirsher
In-Reply-To: <1389087149-27962-1-git-send-email-jeffrey.t.kirsher@intel.com>

From: Shannon Nelson <shannon.nelson@intel.com>

We need to check if we are dealing with the correct MAC type before we
try to read anything from the registers.

Change-Id: I3989516999d06c3009e87d6a2eafc20af305c5c2
Signed-off-by: Kamil Krawczyk <kamil.krawczyk@intel.com>
Signed-off-by: Shannon Nelson <shannon.nelson@intel.com>
Tested-by: Kavindya Deegala <kavindya.s.deegala@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/i40e/i40e_common.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c
index 02ad529..7e34de1 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_common.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_common.c
@@ -180,14 +180,6 @@ i40e_status i40e_init_shared_code(struct i40e_hw *hw)
 	i40e_status status = 0;
 	u32 reg;
 
-	hw->phy.get_link_info = true;
-
-	/* Determine port number */
-	reg = rd32(hw, I40E_PFGEN_PORTNUM);
-	reg = ((reg & I40E_PFGEN_PORTNUM_PORT_NUM_MASK) >>
-	       I40E_PFGEN_PORTNUM_PORT_NUM_SHIFT);
-	hw->port = (u8)reg;
-
 	i40e_set_mac_type(hw);
 
 	switch (hw->mac.type) {
@@ -198,6 +190,14 @@ i40e_status i40e_init_shared_code(struct i40e_hw *hw)
 		break;
 	}
 
+	hw->phy.get_link_info = true;
+
+	/* Determine port number */
+	reg = rd32(hw, I40E_PFGEN_PORTNUM);
+	reg = ((reg & I40E_PFGEN_PORTNUM_PORT_NUM_MASK) >>
+	       I40E_PFGEN_PORTNUM_PORT_NUM_SHIFT);
+	hw->port = (u8)reg;
+
 	/* Determine the PF number based on the PCI fn */
 	reg = rd32(hw, I40E_GLPCI_CAPSUP);
 	if (reg & I40E_GLPCI_CAPSUP_ARI_EN_MASK)
-- 
1.8.3.1

^ permalink raw reply related

* [net-next 08/15] i40e: Reduce range of interrupt reg in reg test
From: Jeff Kirsher @ 2014-01-07  9:32 UTC (permalink / raw)
  To: davem; +Cc: Shannon Nelson, netdev, gospo, sassmann, Kamil Krawczyk,
	Jeff Kirsher
In-Reply-To: <1389087149-27962-1-git-send-email-jeffrey.t.kirsher@intel.com>

From: Shannon Nelson <shannon.nelson@intel.com>

Use a smaller range of test registers in MFP mode as there are fewer
resources than when in SFP mode.

Change-Id: I08424890c3f57b5dde5ee99e99724ce252e0875a
Signed-off-by: Kamil Krawczyk <kamil.krawczyk@intel.com>
Signed-off-by: Shannon Nelson <shannon.nelson@intel.com>
Tested-by: Kavindya Deegala <kavindya.s.deegala@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/i40e/i40e_diag.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/ethernet/intel/i40e/i40e_diag.c b/drivers/net/ethernet/intel/i40e/i40e_diag.c
index 98c1ef5..6a1657e 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_diag.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_diag.c
@@ -70,9 +70,9 @@ struct i40e_diag_reg_test_info i40e_reg_list[] = {
 	/* offset               mask         elements   stride */
 	{I40E_QTX_CTL(0),       0x0000FFBF,   4, I40E_QTX_CTL(1) - I40E_QTX_CTL(0)},
 	{I40E_PFINT_ITR0(0),    0x00000FFF,   3, I40E_PFINT_ITR0(1) - I40E_PFINT_ITR0(0)},
-	{I40E_PFINT_ITRN(0, 0), 0x00000FFF,  64, I40E_PFINT_ITRN(0, 1) - I40E_PFINT_ITRN(0, 0)},
-	{I40E_PFINT_ITRN(1, 0), 0x00000FFF,  64, I40E_PFINT_ITRN(1, 1) - I40E_PFINT_ITRN(1, 0)},
-	{I40E_PFINT_ITRN(2, 0), 0x00000FFF,  64, I40E_PFINT_ITRN(2, 1) - I40E_PFINT_ITRN(2, 0)},
+	{I40E_PFINT_ITRN(0, 0), 0x00000FFF,   8, I40E_PFINT_ITRN(0, 1) - I40E_PFINT_ITRN(0, 0)},
+	{I40E_PFINT_ITRN(1, 0), 0x00000FFF,   8, I40E_PFINT_ITRN(1, 1) - I40E_PFINT_ITRN(1, 0)},
+	{I40E_PFINT_ITRN(2, 0), 0x00000FFF,   8, I40E_PFINT_ITRN(2, 1) - I40E_PFINT_ITRN(2, 0)},
 	{I40E_PFINT_STAT_CTL0,  0x0000000C,   1, 0},
 	{I40E_PFINT_LNKLST0,    0x00001FFF,   1, 0},
 	{I40E_PFINT_LNKLSTN(0), 0x000007FF,  64, I40E_PFINT_LNKLSTN(1) - I40E_PFINT_LNKLSTN(0)},
-- 
1.8.3.1

^ permalink raw reply related

* [net-next 07/15] i40e: update firmware api to 1.1
From: Jeff Kirsher @ 2014-01-07  9:32 UTC (permalink / raw)
  To: davem; +Cc: Shannon Nelson, netdev, gospo, sassmann, Jeff Kirsher
In-Reply-To: <1389087149-27962-1-git-send-email-jeffrey.t.kirsher@intel.com>

From: Shannon Nelson <shannon.nelson@intel.com>

The firmware's AdminQ interface has matured a little, so update the
code to use the new fields and values.

Change-Id: I8fcd7b443f268dcf9346bd6a9e940fe9c2958891
Signed-off-by: Shannon Nelson <shannon.nelson@intel.com>
Tested-by: Kavindya Deegala <kavindya.s.deegala@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/i40e/i40e_adminq.c     |  12 ++-
 drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h | 126 ++++++++++++++++------
 drivers/net/ethernet/intel/i40e/i40e_common.c     |   2 +-
 drivers/net/ethernet/intel/i40e/i40e_type.h       |   3 -
 4 files changed, 99 insertions(+), 44 deletions(-)

diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq.c b/drivers/net/ethernet/intel/i40e/i40e_adminq.c
index f75b573..3ee5323 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_adminq.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_adminq.c
@@ -572,16 +572,18 @@ i40e_status i40e_init_adminq(struct i40e_hw *hw)
 	if (ret_code != I40E_SUCCESS)
 		goto init_adminq_free_arq;
 
-	if (hw->aq.api_maj_ver != I40E_FW_API_VERSION_MAJOR ||
-	    hw->aq.api_min_ver != I40E_FW_API_VERSION_MINOR) {
-		ret_code = I40E_ERR_FIRMWARE_API_VERSION;
-		goto init_adminq_free_arq;
-	}
+	/* get the NVM version info */
 	i40e_read_nvm_word(hw, I40E_SR_NVM_IMAGE_VERSION, &hw->nvm.version);
 	i40e_read_nvm_word(hw, I40E_SR_NVM_EETRACK_LO, &eetrack_lo);
 	i40e_read_nvm_word(hw, I40E_SR_NVM_EETRACK_HI, &eetrack_hi);
 	hw->nvm.eetrack = (eetrack_hi << 16) | eetrack_lo;
 
+	if (hw->aq.api_maj_ver != I40E_FW_API_VERSION_MAJOR ||
+	    hw->aq.api_min_ver > I40E_FW_API_VERSION_MINOR) {
+		ret_code = I40E_ERR_FIRMWARE_API_VERSION;
+		goto init_adminq_free_arq;
+	}
+
 	ret_code = i40e_aq_set_hmc_resource_profile(hw,
 						    I40E_HMC_PROFILE_DEFAULT,
 						    0,
diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h b/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h
index 2859377..0075087 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h
@@ -35,7 +35,7 @@
  */
 
 #define I40E_FW_API_VERSION_MAJOR  0x0001
-#define I40E_FW_API_VERSION_MINOR  0x0000
+#define I40E_FW_API_VERSION_MINOR  0x0001
 
 struct i40e_aq_desc {
 	__le16 flags;
@@ -137,10 +137,13 @@ enum i40e_admin_queue_opc {
 	i40e_aqc_opc_set_ns_proxy_entry     = 0x0105,
 
 	/* LAA */
-	i40e_aqc_opc_mng_laa                = 0x0106,
+	i40e_aqc_opc_mng_laa                = 0x0106,   /* AQ obsolete */
 	i40e_aqc_opc_mac_address_read       = 0x0107,
 	i40e_aqc_opc_mac_address_write      = 0x0108,
 
+	/* PXE */
+	i40e_aqc_opc_clear_pxe_mode         = 0x0110,
+
 	/* internal switch commands */
 	i40e_aqc_opc_get_switch_config         = 0x0200,
 	i40e_aqc_opc_add_statistics            = 0x0201,
@@ -317,13 +320,15 @@ struct i40e_aqc_get_version {
 
 I40E_CHECK_CMD_LENGTH(i40e_aqc_get_version);
 
-/* Send driver version (direct 0x0002) */
+/* Send driver version (indirect 0x0002) */
 struct i40e_aqc_driver_version {
 	u8     driver_major_ver;
 	u8     driver_minor_ver;
 	u8     driver_build_ver;
 	u8     driver_subbuild_ver;
-	u8     reserved[12];
+	u8     reserved[4];
+	__le32 address_high;
+	__le32 address_low;
 };
 
 I40E_CHECK_CMD_LENGTH(i40e_aqc_driver_version);
@@ -479,7 +484,7 @@ struct i40e_aqc_mng_laa {
 	u8     reserved2[6];
 };
 
-/* Manage MAC Address Read Command (0x0107) */
+/* Manage MAC Address Read Command (indirect 0x0107) */
 struct i40e_aqc_mac_address_read {
 	__le16	command_flags;
 #define I40E_AQC_LAN_ADDR_VALID   0x10
@@ -517,6 +522,16 @@ struct i40e_aqc_mac_address_write {
 
 I40E_CHECK_CMD_LENGTH(i40e_aqc_mac_address_write);
 
+/* PXE commands (0x011x) */
+
+/* Clear PXE Command and response  (direct 0x0110) */
+struct i40e_aqc_clear_pxe {
+	u8	rx_cnt;
+	u8	reserved[15];
+};
+
+I40E_CHECK_CMD_LENGTH(i40e_aqc_clear_pxe);
+
 /* Switch configuration commands (0x02xx) */
 
 /* Used by many indirect commands that only pass an seid and a buffer in the
@@ -639,13 +654,15 @@ struct i40e_aqc_switch_resource_alloc_element_resp {
 	u8     reserved2[6];
 };
 
-/* Add VSI (indirect 0x210)
+/* Add VSI (indirect 0x0210)
  *    this indirect command uses struct i40e_aqc_vsi_properties_data
  *    as the indirect buffer (128 bytes)
  *
- * Update VSI (indirect 0x211) Get VSI (indirect 0x0212)
- *    use the generic i40e_aqc_switch_seid descriptor format
- *    use the same completion and data structure as Add VSI
+ * Update VSI (indirect 0x211)
+ *     uses the same data structure as Add VSI
+ *
+ * Get VSI (indirect 0x0212)
+ *     uses the same completion and data structure as Add VSI
  */
 struct i40e_aqc_add_get_update_vsi {
 	__le16 uplink_seid;
@@ -1185,27 +1202,40 @@ struct i40e_aqc_add_remove_cloud_filters_element_data {
 #define I40E_AQC_ADD_CLOUD_FILTER_SHIFT                 0
 #define I40E_AQC_ADD_CLOUD_FILTER_MASK                  (0x3F << \
 					I40E_AQC_ADD_CLOUD_FILTER_SHIFT)
+/* 0x0000 reserved */
 #define I40E_AQC_ADD_CLOUD_FILTER_OIP                   0x0001
-#define I40E_AQC_ADD_CLOUD_FILTER_OIP_GRE               0x0002
+/* 0x0002 reserved */
 #define I40E_AQC_ADD_CLOUD_FILTER_IMAC_IVLAN            0x0003
-#define I40E_AQC_ADD_CLOUD_FILTER_IMAC_IVLAN_GRE        0x0004
+#define I40E_AQC_ADD_CLOUD_FILTER_IMAC_IVLAN_TEN_ID     0x0004
+/* 0x0005 reserved */
 #define I40E_AQC_ADD_CLOUD_FILTER_IMAC_TEN_ID           0x0006
-#define I40E_AQC_ADD_CLOUD_FILTER_IMAC_IVLAN_VNL        0x0007
+/* 0x0007 reserved */
 /* 0x0008 reserved */
 #define I40E_AQC_ADD_CLOUD_FILTER_OMAC                  0x0009
 #define I40E_AQC_ADD_CLOUD_FILTER_IMAC                  0x000A
+#define I40E_AQC_ADD_CLOUD_FILTER_OMAC_TEN_ID_IMAC      0x000B
+#define I40E_AQC_ADD_CLOUD_FILTER_IIP                   0x000C
+
 #define I40E_AQC_ADD_CLOUD_FLAGS_TO_QUEUE               0x0080
 #define I40E_AQC_ADD_CLOUD_VNK_SHIFT                    6
 #define I40E_AQC_ADD_CLOUD_VNK_MASK                     0x00C0
 #define I40E_AQC_ADD_CLOUD_FLAGS_IPV4                   0
 #define I40E_AQC_ADD_CLOUD_FLAGS_IPV6                   0x0100
-	__le32 key_low;
-	__le32 key_high;
+
+#define I40E_AQC_ADD_CLOUD_TNL_TYPE_SHIFT               9
+#define I40E_AQC_ADD_CLOUD_TNL_TYPE_MASK                0x1E00
+#define I40E_AQC_ADD_CLOUD_TNL_TYPE_XVLAN               0
+#define I40E_AQC_ADD_CLOUD_TNL_TYPE_NVGRE_OMAC          1
+#define I40E_AQC_ADD_CLOUD_TNL_TYPE_NGE                 2
+#define I40E_AQC_ADD_CLOUD_TNL_TYPE_IP                  3
+
+	__le32 tenant_id;
+	u8     reserved[4];
 	__le16 queue_number;
 #define I40E_AQC_ADD_CLOUD_QUEUE_SHIFT                  0
 #define I40E_AQC_ADD_CLOUD_QUEUE_MASK                   (0x3F << \
 					I40E_AQC_ADD_CLOUD_QUEUE_SHIFT)
-	u8     reserved[14];
+	u8     reserved2[14];
 	/* response section */
 	u8     allocation_result;
 #define I40E_AQC_ADD_CLOUD_FILTER_SUCCESS         0x0
@@ -1548,7 +1578,7 @@ struct i40e_aqc_module_desc {
 
 struct i40e_aq_get_phy_abilities_resp {
 	__le32 phy_type;       /* bitmap using the above enum for offsets */
-	u8     link_speed;     /* bitmap using the above enum */
+	u8     link_speed;     /* bitmap using the above enum bit patterns */
 	u8     abilities;
 #define I40E_AQ_PHY_FLAG_PAUSE_TX         0x01
 #define I40E_AQ_PHY_FLAG_PAUSE_RX         0x02
@@ -1582,6 +1612,10 @@ struct i40e_aq_set_phy_config { /* same bits as above in all */
 	__le32 phy_type;
 	u8     link_speed;
 	u8     abilities;
+/* bits 0-2 use the values from get_phy_abilities_resp */
+#define I40E_AQ_PHY_ENABLE_LINK		0x08
+#define I40E_AQ_PHY_ENABLE_AN		0x10
+#define I40E_AQ_PHY_ENABLE_ATOMIC_LINK	0x20
 	__le16 eee_capability;
 	__le32 eeer;
 	u8     low_power_ctrl;
@@ -1915,22 +1949,39 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_lldp_start);
 struct i40e_aqc_add_udp_tunnel {
 	__le16 udp_port;
 	u8     header_len; /* in DWords, 1 to 15 */
-	u8     protocol_index;
-#define I40E_AQC_TUNNEL_TYPE_MAC    0x0
-#define I40E_AQC_TUNNEL_TYPE_UDP    0x1
-#define I40E_AQC_TUNNEL_TYPE_VXLAN  0x2
-	u8     reserved[12];
+	u8     protocol_type;
+#define I40E_AQC_TUNNEL_TYPE_TEREDO	0x0
+#define I40E_AQC_TUNNEL_TYPE_VXLAN	0x2
+#define I40E_AQC_TUNNEL_TYPE_NGE	0x3
+	u8     variable_udp_length;
+#define I40E_AQC_TUNNEL_FIXED_UDP_LENGTH	0x0
+#define I40E_AQC_TUNNEL_VARIABLE_UDP_LENGTH	0x1
+	u8     udp_key_index;
+#define I40E_AQC_TUNNEL_KEY_INDEX_VXLAN			0x0
+#define I40E_AQC_TUNNEL_KEY_INDEX_NGE			0x1
+#define I40E_AQC_TUNNEL_KEY_INDEX_PROPRIETARY_UDP	0x2
+	u8     reserved[10];
 };
 
 I40E_CHECK_CMD_LENGTH(i40e_aqc_add_udp_tunnel);
 
+struct i40e_aqc_add_udp_tunnel_completion {
+	__le16 udp_port;
+	u8     filter_entry_index;
+	u8     multiple_pfs;
+#define I40E_AQC_SINGLE_PF	0x0
+#define I40E_AQC_MULTIPLE_PFS	0x1
+	u8     total_filters;
+	u8     reserved[11];
+};
+
+I40E_CHECK_CMD_LENGTH(i40e_aqc_add_udp_tunnel_completion);
+
 /* remove UDP Tunnel command (0x0B01) */
 struct i40e_aqc_remove_udp_tunnel {
 	u8     reserved[2];
 	u8     index; /* 0 to 15 */
-	u8     pf_filters;
-	u8     total_filters;
-	u8     reserved2[11];
+	u8     reserved2[13];
 };
 
 I40E_CHECK_CMD_LENGTH(i40e_aqc_remove_udp_tunnel);
@@ -1938,28 +1989,32 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_remove_udp_tunnel);
 struct i40e_aqc_del_udp_tunnel_completion {
 	__le16 udp_port;
 	u8     index; /* 0 to 15 */
-	u8     multiple_entries;
-	u8     tunnels_used;
-	u8     reserved;
-	u8     tunnels_free;
-	u8     reserved1[9];
+	u8     multiple_pfs;
+	u8     total_filters_used;
+	u8     reserved1[11];
 };
 
 I40E_CHECK_CMD_LENGTH(i40e_aqc_del_udp_tunnel_completion);
 
 /* tunnel key structure 0x0B10 */
+
 struct i40e_aqc_tunnel_key_structure {
-	__le16     key1_off;
-	__le16     key1_len;
-	__le16     key2_off;
-	__le16     key2_len;
-	__le16     flags;
+	u8	key1_off;
+	u8	key2_off;
+	u8	key1_len;  /* 0 to 15 */
+	u8	key2_len;  /* 0 to 15 */
+	u8	flags;
 #define I40E_AQC_TUNNEL_KEY_STRUCT_OVERRIDE 0x01
 /* response flags */
 #define I40E_AQC_TUNNEL_KEY_STRUCT_SUCCESS    0x01
 #define I40E_AQC_TUNNEL_KEY_STRUCT_MODIFIED   0x02
 #define I40E_AQC_TUNNEL_KEY_STRUCT_OVERRIDDEN 0x03
-	u8         resreved[6];
+	u8	network_key_index;
+#define I40E_AQC_NETWORK_KEY_INDEX_VXLAN		0x0
+#define I40E_AQC_NETWORK_KEY_INDEX_NGE			0x1
+#define I40E_AQC_NETWORK_KEY_INDEX_FLEX_MAC_IN_UDP	0x2
+#define I40E_AQC_NETWORK_KEY_INDEX_GRE			0x3
+	u8	reserved[10];
 };
 
 I40E_CHECK_CMD_LENGTH(i40e_aqc_tunnel_key_structure);
@@ -2053,6 +2108,7 @@ I40E_CHECK_CMD_LENGTH(i40e_aqc_debug_modify_reg);
 #define I40E_AQ_CLUSTER_ID_DCB		8
 #define I40E_AQ_CLUSTER_ID_EMP_MEM	9
 #define I40E_AQ_CLUSTER_ID_PKT_BUF	10
+#define I40E_AQ_CLUSTER_ID_ALTRAM	11
 
 struct i40e_aqc_debug_dump_internals {
 	u8     cluster_id;
diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c
index 337e913..96c8f15 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_common.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_common.c
@@ -1738,7 +1738,7 @@ i40e_status i40e_aq_add_udp_tunnel(struct i40e_hw *hw,
 
 	cmd->udp_port = cpu_to_le16(udp_port);
 	cmd->header_len = header_len;
-	cmd->protocol_index = protocol_index;
+	cmd->protocol_type = protocol_index;
 
 	status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
 
diff --git a/drivers/net/ethernet/intel/i40e/i40e_type.h b/drivers/net/ethernet/intel/i40e/i40e_type.h
index 7bbcc71..4ac712e 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_type.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_type.h
@@ -53,9 +53,6 @@
 					 (d) == I40E_QSFP_B_DEVICE_ID  || \
 					 (d) == I40E_QSFP_C_DEVICE_ID)
 
-#define I40E_FW_API_VERSION_MAJOR  0x0001
-#define I40E_FW_API_VERSION_MINOR  0x0000
-
 #define I40E_MAX_VSI_QP			16
 #define I40E_MAX_VF_VSI			3
 #define I40E_MAX_CHAINED_RX_BUFFERS	5
-- 
1.8.3.1

^ permalink raw reply related

* [net-next 05/15] i40e: Bump version
From: Jeff Kirsher @ 2014-01-07  9:32 UTC (permalink / raw)
  To: davem
  Cc: Catherine Sullivan, netdev, gospo, sassmann, Jesse Brandeburg,
	Jeff Kirsher
In-Reply-To: <1389087149-27962-1-git-send-email-jeffrey.t.kirsher@intel.com>

From: Catherine Sullivan <catherine.sullivan@intel.com>

Version update to 0.3.25-k

Signed-off-by: Catherine Sullivan <catherine.sullivan@intel.com>
Signed-off-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/i40e/i40e_main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index 2a42470..f736c44 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -39,7 +39,7 @@ static const char i40e_driver_string[] =
 
 #define DRV_VERSION_MAJOR 0
 #define DRV_VERSION_MINOR 3
-#define DRV_VERSION_BUILD 14
+#define DRV_VERSION_BUILD 25
 #define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \
 	     __stringify(DRV_VERSION_MINOR) "." \
 	     __stringify(DRV_VERSION_BUILD)    DRV_KERN
-- 
1.8.3.1

^ permalink raw reply related

* [net-next 06/15] i40e: Add code to wait for FW to complete in reset path
From: Jeff Kirsher @ 2014-01-07  9:32 UTC (permalink / raw)
  To: davem
  Cc: Shannon Nelson, netdev, gospo, sassmann, Anjali Singhai Jain,
	Jeff Kirsher
In-Reply-To: <1389087149-27962-1-git-send-email-jeffrey.t.kirsher@intel.com>

From: Shannon Nelson <shannon.nelson@intel.com>

The RSTAT comes back with DEVICE READY to indicate that the HW is ready,
but we still have to wait for the FW to indicate that the Core and Global
modules are back up again.  This needs a read of the NVM_ULD register.

Change-Id: I88276165f9cd446d2f166fb4b8cff00521af4bec
Signed-off-by: Anjali Singhai Jain <anjali.singhai@intel.com>
Signed-off-by: Shannon Nelson <shannon.nelson@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/i40e/i40e_common.c   | 20 ++++++++++++++++++++
 drivers/net/ethernet/intel/i40e/i40e_register.h | 22 ++++++++++++++++++++++
 2 files changed, 42 insertions(+)

diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c
index 7cd59ce..337e913 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_common.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_common.c
@@ -335,6 +335,7 @@ static enum i40e_media_type i40e_get_media_type(struct i40e_hw *hw)
 i40e_status i40e_pf_reset(struct i40e_hw *hw)
 {
 	u32 cnt = 0;
+	u32 cnt1 = 0;
 	u32 reg = 0;
 	u32 grst_del;
 
@@ -355,6 +356,25 @@ i40e_status i40e_pf_reset(struct i40e_hw *hw)
 		return I40E_ERR_RESET_FAILED;
 	}
 
+	/* Now Wait for the FW to be ready */
+	for (cnt1 = 0; cnt1 < I40E_PF_RESET_WAIT_COUNT; cnt1++) {
+		reg = rd32(hw, I40E_GLNVM_ULD);
+		reg &= (I40E_GLNVM_ULD_CONF_CORE_DONE_MASK |
+			I40E_GLNVM_ULD_CONF_GLOBAL_DONE_MASK);
+		if (reg == (I40E_GLNVM_ULD_CONF_CORE_DONE_MASK |
+			    I40E_GLNVM_ULD_CONF_GLOBAL_DONE_MASK)) {
+			hw_dbg(hw, "Core and Global modules ready %d\n", cnt1);
+			break;
+		}
+		usleep_range(10000, 20000);
+	}
+	if (!(reg & (I40E_GLNVM_ULD_CONF_CORE_DONE_MASK |
+		     I40E_GLNVM_ULD_CONF_GLOBAL_DONE_MASK))) {
+		hw_dbg(hw, "wait for FW Reset complete timedout\n");
+		hw_dbg(hw, "I40E_GLNVM_ULD = 0x%x\n", reg);
+		return I40E_ERR_RESET_FAILED;
+	}
+
 	/* Determine the PF number based on the PCI fn */
 	reg = rd32(hw, I40E_GLPCI_CAPSUP);
 	if (reg & I40E_GLPCI_CAPSUP_ARI_EN_MASK)
diff --git a/drivers/net/ethernet/intel/i40e/i40e_register.h b/drivers/net/ethernet/intel/i40e/i40e_register.h
index 2394c66..d188ec0 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_register.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_register.h
@@ -2053,6 +2053,28 @@
 #define I40E_GLNVM_SRDATA_WRDATA_MASK (0xFFFF << I40E_GLNVM_SRDATA_WRDATA_SHIFT)
 #define I40E_GLNVM_SRDATA_RDDATA_SHIFT 16
 #define I40E_GLNVM_SRDATA_RDDATA_MASK (0xFFFF << I40E_GLNVM_SRDATA_RDDATA_SHIFT)
+#define I40E_GLNVM_ULD 0x000B6008
+#define I40E_GLNVM_ULD_CONF_PCIR_DONE_SHIFT 0
+#define I40E_GLNVM_ULD_CONF_PCIR_DONE_MASK (0x1 << I40E_GLNVM_ULD_CONF_PCIR_DONE_SHIFT)
+#define I40E_GLNVM_ULD_CONF_PCIRTL_DONE_SHIFT 1
+#define I40E_GLNVM_ULD_CONF_PCIRTL_DONE_MASK (0x1 << I40E_GLNVM_ULD_CONF_PCIRTL_DONE_SHIFT)
+#define I40E_GLNVM_ULD_CONF_LCB_DONE_SHIFT 2
+#define I40E_GLNVM_ULD_CONF_LCB_DONE_MASK (0x1 << I40E_GLNVM_ULD_CONF_LCB_DONE_SHIFT)
+#define I40E_GLNVM_ULD_CONF_CORE_DONE_SHIFT 3
+#define I40E_GLNVM_ULD_CONF_CORE_DONE_MASK (0x1 << I40E_GLNVM_ULD_CONF_CORE_DONE_SHIFT)
+#define I40E_GLNVM_ULD_CONF_GLOBAL_DONE_SHIFT 4
+#define I40E_GLNVM_ULD_CONF_GLOBAL_DONE_MASK (0x1 << I40E_GLNVM_ULD_CONF_GLOBAL_DONE_SHIFT)
+#define I40E_GLNVM_ULD_CONF_POR_DONE_SHIFT 5
+#define I40E_GLNVM_ULD_CONF_POR_DONE_MASK (0x1 << I40E_GLNVM_ULD_CONF_POR_DONE_SHIFT)
+#define I40E_GLNVM_ULD_CONF_PCIE_ANA_DONE_SHIFT 6
+#define I40E_GLNVM_ULD_CONF_PCIE_ANA_DONE_MASK (0x1 << I40E_GLNVM_ULD_CONF_PCIE_ANA_DONE_SHIFT)
+#define I40E_GLNVM_ULD_CONF_PHY_ANA_DONE_SHIFT 7
+#define I40E_GLNVM_ULD_CONF_PHY_ANA_DONE_MASK (0x1 << I40E_GLNVM_ULD_CONF_PHY_ANA_DONE_SHIFT)
+#define I40E_GLNVM_ULD_CONF_EMP_DONE_SHIFT 8
+#define I40E_GLNVM_ULD_CONF_EMP_DONE_MASK (0x1 << I40E_GLNVM_ULD_CONF_EMP_DONE_SHIFT)
+#define I40E_GLNVM_ULD_CONF_PCIALT_DONE_SHIFT 9
+#define I40E_GLNVM_ULD_CONF_PCIALT_DONE_MASK (0x1 << I40E_GLNVM_ULD_CONF_PCIALT_DONE_SHIFT)
+
 #define I40E_GLPCI_BYTCTH 0x0009C484
 #define I40E_GLPCI_BYTCTH_PCI_COUNT_BW_BCT_SHIFT 0
 #define I40E_GLPCI_BYTCTH_PCI_COUNT_BW_BCT_MASK (0xFFFFFFFF << I40E_GLPCI_BYTCTH_PCI_COUNT_BW_BCT_SHIFT)
-- 
1.8.3.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