Netdev List
 help / color / mirror / Atom feed
* Re: the next chunk of iov_iter-net stuff for review
From: Al Viro @ 2014-12-09 22:49 UTC (permalink / raw)
  To: David Miller; +Cc: netdev, linux-kernel
In-Reply-To: <20141209.163758.1934464464299516168.davem@davemloft.net>

On Tue, Dec 09, 2014 at 04:37:58PM -0500, David Miller wrote:
> From: Al Viro <viro@ZenIV.linux.org.uk>
> Date: Tue, 9 Dec 2014 21:23:37 +0000
> 
> > On Tue, Dec 09, 2014 at 04:17:12PM -0500, David Miller wrote:
> >> From: Al Viro <viro@ZenIV.linux.org.uk>
> >> Date: Tue, 9 Dec 2014 21:04:14 +0000
> >> 
> >> > Well, I've got no comments whatsoever on the networking side of things;
> >> 
> >> I've been away for more than 10 days, so I personally haven't had time
> >> to review any of it.
> >> 
> >> Why don't you respin and I'll try to allocate some review time myself?
> > 
> > Umm...  Do you want a rebase on top of current net-next/master?
> 
> Sure, why not?

OK, rebase is in
git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs.git for-davem-2,
individual patches - in followups (first 13 - iov_iter, then 12 net-related)

^ permalink raw reply

* Re: [PATCH] bridge: Remove BR_PROXYARP flooding check code
From: Stephen Hemminger @ 2014-12-09 22:21 UTC (permalink / raw)
  To: Jouni Malinen; +Cc: David Miller, netdev, Kyeyoon Park
In-Reply-To: <1418052460-30691-1-git-send-email-jouni@codeaurora.org>

On Mon,  8 Dec 2014 17:27:40 +0200
Jouni Malinen <jouni@codeaurora.org> wrote:

> From: Kyeyoon Park <kyeyoonp@codeaurora.org>
> 
> Because dropping broadcast packets for IEEE 802.11 Proxy ARP is more
> selective than previously thought, it is better to remove the direct
> dropping logic in the bridge code in favor of using the netfilter
> infrastructure to provide more control on which frames get dropped. This
> code was added in commit 958501163ddd ("bridge: Add support for IEEE
> 802.11 Proxy ARP").
> 
> Signed-off-by: Kyeyoon Park <kyeyoonp@codeaurora.org>
> Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
> ---
>  net/bridge/br_forward.c | 4 ----
>  1 file changed, 4 deletions(-)
> 
> diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c
> index f96933a..8a025a7 100644
> --- a/net/bridge/br_forward.c
> +++ b/net/bridge/br_forward.c
> @@ -185,10 +185,6 @@ static void br_flood(struct net_bridge *br, struct sk_buff *skb,
>  		if (unicast && !(p->flags & BR_FLOOD))
>  			continue;
>  
> -		/* Do not flood to ports that enable proxy ARP */
> -		if (p->flags & BR_PROXYARP)
> -			continue;
> -
>  		prev = maybe_deliver(prev, p, skb, __packet_hook);
>  		if (IS_ERR(prev))
>  			goto out;

Aren't you at risk of duplicate ARP responses in some cases.
You can't assume user will run netfilter.

^ permalink raw reply

* Re: [RFC PATCH net-next] tun: support retrieving multiple packets in a single read with IFF_MULTI_READ
From: Stephen Hemminger @ 2014-12-09 22:19 UTC (permalink / raw)
  To: Alex Gartrell
  Cc: jasonwang, davem, netdev, linux-kernel, mst, herbert, kernel-team
In-Reply-To: <1417752000-27171-1-git-send-email-agartrell@fb.com>

On Thu, 4 Dec 2014 20:00:00 -0800
Alex Gartrell <agartrell@fb.com> wrote:

>  
> +static inline size_t tun_calc_max_put_len(const struct tun_struct *tun)
> +{
> +	size_t len = 0;

No need for inline with local static function. Let compiler decide.

^ permalink raw reply

* Re: [PATCH][net-next][V2] net: avoid to call skb_queue_len again
From: David Miller @ 2014-12-09 22:03 UTC (permalink / raw)
  To: roy.qing.li; +Cc: netdev, edumazet, sergei.shtylyov
In-Reply-To: <1418002975-15271-1-git-send-email-roy.qing.li@gmail.com>

From: roy.qing.li@gmail.com
Date: Mon,  8 Dec 2014 09:42:55 +0800

> From: Li RongQing <roy.qing.li@gmail.com>
> 
> the queue length of sd->input_pkt_queue has been put into qlen,
> and impossible to change, since hold the lock
> 
> Signed-off-by: Li RongQing <roy.qing.li@gmail.com>
> Acked-by: Eric Dumazet <edumazet@google.com>

Applied, thanks.

^ permalink raw reply

* Re: [net-next v2 00/13][pull request] Intel Wired LAN Driver Updates 2014-12-09
From: David Miller @ 2014-12-09 22:01 UTC (permalink / raw)
  To: jeffrey.t.kirsher; +Cc: netdev, nhorman, sassmann, jogreene
In-Reply-To: <1418160380-29847-1-git-send-email-jeffrey.t.kirsher@intel.com>

From: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Date: Tue,  9 Dec 2014 13:26:07 -0800

> This series contains updates to i40e and i40evf.
> 
> Jeff (me) provides a single patch to convert a macro to a static inline
> function based on feedback from Joe Perches on a previous patch.
> 
> Shannon provides the remaining twelve patches against i40e.  Almost all
> of Shannon's patches cleanup/fix NVM issues varying in range from
> adding more detail to debug messages, to removing dead code, to fixing
> NVM state transitions after an error.  Change the handy decoder interface
> for admin queue return code to help catch and properly report the condition
> as a useful errno rather than returning a misleading '0'.  Added a range
> check to avoid any possible array index-out-of-bound issues.
> 
> v2:
>  - fixed up patch 05 in the series to use the ARRAY_SIZE() macro as suggested
>    by Sergei Shtylyov
>  - fix up patch 13 to remove unnecessary parens in the return statement
>    as suggested by Sergei Shtylyov

Pulled, thanks for the quick turnaround Jeff.

^ permalink raw reply

* Re: pull-request: can-next 2014-12-07
From: David Miller @ 2014-12-09 21:49 UTC (permalink / raw)
  To: mkl; +Cc: netdev, linux-can, kernel
In-Reply-To: <5484E3C3.5030205@pengutronix.de>

From: Marc Kleine-Budde <mkl@pengutronix.de>
Date: Mon, 08 Dec 2014 00:33:23 +0100

> this is a pull request of 8 patches for net-next/master.
> 
> Andri Yngvason contributes 4 patches in which the CAN state change
> handling is consolidated and unified among the sja1000, mscan and
> flexcan driver. The three patches by Jeremiah Mahler fix spelling
> mistakes and eliminate the banner[] variable in various parts. And a
> patch by me that switches on sparse endianess checking by default.

Pulled, thanks Marc.

^ permalink raw reply

* Re: [PATCH] fix suspicious rcu_dereference_check in net/sched/sch_fq_codel.c
From: Eric Dumazet @ 2014-12-09 21:42 UTC (permalink / raw)
  To: Valdis Kletnieks
  Cc: Eric Dumazet, John Fastabend, David S. Miller, linux-kernel,
	netdev
In-Reply-To: <58905.1418159750@turing-police.cc.vt.edu>

On Tue, 2014-12-09 at 16:15 -0500, Valdis Kletnieks wrote:
> commit 46e5da40ae (net: qdisc: use rcu prefix and silence
>  sparse warnings) triggers a spurious warning:
> 
> net/sched/sch_fq_codel.c:97 suspicious rcu_dereference_check() usage!
> 
> The code should be using the _bh variant of rcu_dereference.
> 
> Signed-off-by: Valdis Kletnieks <valdis.kletnieks@vt.edu>
> ---
>  net/sched/sch_fq_codel.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Acked-by: Eric Dumazet <edumazet@google.com>

Thanks !

^ permalink raw reply

* Re: pull-request: can 2014-12-07
From: David Miller @ 2014-12-09 21:41 UTC (permalink / raw)
  To: mkl; +Cc: netdev, linux-can, kernel
In-Reply-To: <1417989966-31309-1-git-send-email-mkl@pengutronix.de>

From: Marc Kleine-Budde <mkl@pengutronix.de>
Date: Sun,  7 Dec 2014 23:06:03 +0100

> this is a pull request of three patches by Stephane Grosjean which fix several
> bugs in the peak_usb CAN drivers.
> 
> Please queue, if possible for 3.18, if it's too late these patches takes the
> slow lane via net-next.

Pulled, thanks.

^ permalink raw reply

* Re: [bisected] xfrm: TCP connection initiating PMTU discovery stalls on v3.
From: Eric Dumazet @ 2014-12-09 21:40 UTC (permalink / raw)
  To: Wolfgang Walter
  Cc: Thomas Jarosch, netdev, Eric Dumazet, Herbert Xu,
	Steffen Klassert
In-Reply-To: <2625472.GutY3xCvKT@h2o.as.studentenwerk.mhn.de>

On Tue, 2014-12-09 at 21:36 +0100, Wolfgang Walter wrote:

> How would that be done? I found no way to disable it especially for xfrm. I 
> disabled gso for the interface which serves the ipsec traffic but this does 
> not help. tcp still uses gso for the esp tunnel.
> 
> I put a view printk's in net/xfrm/xfrm_output.c and net/ipv4/tcp_output.c. (I 
> try to understand where in the xfrm transformation gso is handeled).
> 
> What I can say yet is:
> 
> xfrm_output() is used with ipsec (esp) tunnel mode but at I never see gso 
> packets here. xfrm_output_gso() is never called.
> 
> Everytime tcp_set_skb_tso_segs() is called for a tcp connection over the esp-
> tunnel and it is a gso case then the tcp connection hangs. Those packets 
> always have skb->len 1398 and mss_now is 1374. I see a call of xfrm_output() 
> afterwards but for a packet of skb->len 52 (maybe ACK from other direction?).
> 
> As long as the tcp-connection over the ipsec-tunnel works and if I send bulk 
> traffic xfrm_output() is called 3 times with packet skb->len 1426 and then one 
> time with 78 (maybe other direction?), don't know if that is of any interest.
> 
> 
> With non-ipsec-traffic gso works fine: in this case the skb->len() varies a 
> lot and mss_now is always 1288.
> 

Presumably something happens so that sk_can_gso() returns false.

But apparently, this happens _after_ tcp_sendmsg(), ie a bit too late.

Note that after https://patchwork.ozlabs.org/patch/418506/ is applied,
fix would simply be :

diff --git a/net/core/sock.c b/net/core/sock.c
index 9a56b2000c3f374fb95aedada3327447816a9512..678ef8393680dc781445c5f121719ea8ea7bb7c1 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -1585,6 +1585,8 @@ void sk_setup_caps(struct sock *sk, struct dst_entry *dst)
 			sk->sk_gso_max_size = dst->dev->gso_max_size;
 			sk->sk_gso_max_segs = dst->dev->gso_max_segs;
 		}
+	} else {
+		sk->sk_gso_max_segs = 1;
 	}
 }
 EXPORT_SYMBOL_GPL(sk_setup_caps);

^ permalink raw reply related

* Re: [PATCH v3 net-next] tcp: refine TSO autosizing
From: David Miller @ 2014-12-09 21:39 UTC (permalink / raw)
  To: eric.dumazet; +Cc: netdev, ncardwell, ycheng, nanditad
In-Reply-To: <1417983738.15618.38.camel@edumazet-glaptop2.roam.corp.google.com>

From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Sun, 07 Dec 2014 12:22:18 -0800

> From: Eric Dumazet <edumazet@google.com>
> 
> Commit 95bd09eb2750 ("tcp: TSO packets automatic sizing") tried to
> control TSO size, but did this at the wrong place (sendmsg() time)
> 
> At sendmsg() time, we might have a pessimistic view of flow rate,
> and we end up building very small skbs (with 2 MSS per skb).
> 
> This is bad because :
> 
>  - It sends small TSO packets even in Slow Start where rate quickly
>    increases.
>  - It tends to make socket write queue very big, increasing tcp_ack()
>    processing time, but also increasing memory needs, not necessarily
>    accounted for, as fast clones overhead is currently ignored.
>  - Lower GRO efficiency and more ACK packets.
> 
> Servers with a lot of small lived connections suffer from this.
> 
> Lets instead fill skbs as much as possible (64KB of payload), but split
> them at xmit time, when we have a precise idea of the flow rate.
> skb split is actually quite efficient.
> 
> Patch looks bigger than necessary, because TCP Small Queue decision now
> has to take place after the eventual split.
> 
> As Neal suggested, introduce a new tcp_tso_autosize() helper, so that
> tcp_tso_should_defer() can be synchronized on same goal.
> 
> Rename tp->xmit_size_goal_segs to tp->gso_segs, as this variable
> contains number of mss that we can put in GSO packet, and is not
> related to the autosizing goal anymore.
 ...
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Signed-off-by: Neal Cardwell <ncardwell@google.com>
> ---
> v3: tcp_xmit_size_goal() still needs to return a multiple of mss.
> v2: added tcp_tso_autosize() helper and removed tp->xmit_size_goal_segs

Applied, thanks Eric.

^ permalink raw reply

* Re: the next chunk of iov_iter-net stuff for review
From: David Miller @ 2014-12-09 21:37 UTC (permalink / raw)
  To: viro; +Cc: netdev, linux-kernel
In-Reply-To: <20141209212337.GK22149@ZenIV.linux.org.uk>

From: Al Viro <viro@ZenIV.linux.org.uk>
Date: Tue, 9 Dec 2014 21:23:37 +0000

> On Tue, Dec 09, 2014 at 04:17:12PM -0500, David Miller wrote:
>> From: Al Viro <viro@ZenIV.linux.org.uk>
>> Date: Tue, 9 Dec 2014 21:04:14 +0000
>> 
>> > Well, I've got no comments whatsoever on the networking side of things;
>> 
>> I've been away for more than 10 days, so I personally haven't had time
>> to review any of it.
>> 
>> Why don't you respin and I'll try to allocate some review time myself?
> 
> Umm...  Do you want a rebase on top of current net-next/master?

Sure, why not?

^ permalink raw reply

* [net-next v2 13/13] i40e/i40evf: Convert macro to static inline
From: Jeff Kirsher @ 2014-12-09 21:26 UTC (permalink / raw)
  To: davem; +Cc: Jeff Kirsher, netdev, nhorman, sassmann, jogreene,
	Sergei Shtylyov
In-Reply-To: <1418160380-29847-1-git-send-email-jeffrey.t.kirsher@intel.com>

Inline functions are preferred over macros when they can be used
interchangeably.

CC: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Reported-by: Joe Perches <joe@perches.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
v2:
 - remove unnecessary parens in the return statement as suggested
   by Sergei Shtylyov

 drivers/net/ethernet/intel/i40e/i40e_type.h   | 5 ++++-
 drivers/net/ethernet/intel/i40evf/i40e_type.h | 5 ++++-
 2 files changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/intel/i40e/i40e_type.h b/drivers/net/ethernet/intel/i40e/i40e_type.h
index 844421f..c1f2eb9 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_type.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_type.h
@@ -481,7 +481,10 @@ struct i40e_hw {
 	u32 debug_mask;
 };
 
-#define i40e_is_vf(_hw)	((_hw)->mac.type == I40E_MAC_VF)
+static inline bool i40e_is_vf(struct i40e_hw *hw)
+{
+	return hw->mac.type == I40E_MAC_VF;
+}
 
 struct i40e_driver_version {
 	u8 major_version;
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_type.h b/drivers/net/ethernet/intel/i40evf/i40e_type.h
index d8175cd..68aec11 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_type.h
+++ b/drivers/net/ethernet/intel/i40evf/i40e_type.h
@@ -475,7 +475,10 @@ struct i40e_hw {
 	u32 debug_mask;
 };
 
-#define i40e_is_vf(_hw)	((_hw)->mac.type == I40E_MAC_VF)
+static inline bool i40e_is_vf(struct i40e_hw *hw)
+{
+	return hw->mac.type == I40E_MAC_VF;
+}
 
 struct i40e_driver_version {
 	u8 major_version;
-- 
1.9.3

^ permalink raw reply related

* [net-next v2 12/13] i40e: add to NVM update debug message
From: Jeff Kirsher @ 2014-12-09 21:26 UTC (permalink / raw)
  To: davem; +Cc: Shannon Nelson, netdev, nhorman, sassmann, jogreene, Jeff Kirsher
In-Reply-To: <1418160380-29847-1-git-send-email-jeffrey.t.kirsher@intel.com>

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

Add a little more state context to an NVM update debug message.

Change-ID: I512160259052bcdbe5bdf1adf403ab2bf7984970
Signed-off-by: Shannon Nelson <shannon.nelson@intel.com>
Acked-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Tested-by: Jim Young <jamesx.m.young@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/i40e/i40e_nvm.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/ethernet/intel/i40e/i40e_nvm.c b/drivers/net/ethernet/intel/i40e/i40e_nvm.c
index 1613ef4..3e70f2e 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_nvm.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_nvm.c
@@ -806,8 +806,10 @@ static enum i40e_nvmupd_cmd i40e_nvmupd_validate_command(struct i40e_hw *hw,
 		}
 		break;
 	}
-	i40e_debug(hw, I40E_DEBUG_NVM, "%s\n",
-		   i40e_nvm_update_state_str[upd_cmd]);
+	i40e_debug(hw, I40E_DEBUG_NVM, "%s state %d nvm_release_on_hold %d\n",
+		   i40e_nvm_update_state_str[upd_cmd],
+		   hw->nvmupd_state,
+		   hw->aq.nvm_release_on_done);
 
 	if (upd_cmd == I40E_NVMUPD_INVALID) {
 		*errno = -EFAULT;
-- 
1.9.3

^ permalink raw reply related

* [net-next v2 11/13] i40e: check for AQ timeout in aq_rc decode
From: Jeff Kirsher @ 2014-12-09 21:26 UTC (permalink / raw)
  To: davem; +Cc: Shannon Nelson, netdev, nhorman, sassmann, jogreene, Jeff Kirsher
In-Reply-To: <1418160380-29847-1-git-send-email-jeffrey.t.kirsher@intel.com>

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

Decoding the AQ return code is great except when the AQ send timed out
and there's no return code set.  This changes the handy decoder
interface to help catch and properly report the condition as a useful
errno rather than returning a misleading '0'.

Change-ID: I07a1f94f921606da49ffac7837bcdc37cd8222eb
Signed-off-by: Shannon Nelson <shannon.nelson@intel.com>
Acked-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Tested-by: Jim Young <jamesx.m.young@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/i40e/i40e_adminq.h   |  7 +++++-
 drivers/net/ethernet/intel/i40e/i40e_nvm.c      | 33 ++++++++++++++++---------
 drivers/net/ethernet/intel/i40evf/i40e_adminq.h |  7 +++++-
 3 files changed, 33 insertions(+), 14 deletions(-)

diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq.h b/drivers/net/ethernet/intel/i40e/i40e_adminq.h
index 2c68bf7..564d0b0 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_adminq.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_adminq.h
@@ -28,6 +28,7 @@
 #define _I40E_ADMINQ_H_
 
 #include "i40e_osdep.h"
+#include "i40e_status.h"
 #include "i40e_adminq_cmd.h"
 
 #define I40E_ADMINQ_DESC(R, i)   \
@@ -108,7 +109,7 @@ struct i40e_adminq_info {
  * i40e_aq_rc_to_posix - convert errors to user-land codes
  * aq_rc: AdminQ error code to convert
  **/
-static inline int i40e_aq_rc_to_posix(u16 aq_rc)
+static inline int i40e_aq_rc_to_posix(u32 aq_ret, u16 aq_rc)
 {
 	int aq_to_posix[] = {
 		0,           /* I40E_AQ_RC_OK */
@@ -136,6 +137,10 @@ static inline int i40e_aq_rc_to_posix(u16 aq_rc)
 		-EFBIG,      /* I40E_AQ_RC_EFBIG */
 	};
 
+	/* aq_rc is invalid if AQ timed out */
+	if (aq_ret == I40E_ERR_ADMIN_QUEUE_TIMEOUT)
+		return -EAGAIN;
+
 	if (aq_rc >= ARRAY_SIZE(aq_to_posix))
 		return -ERANGE;
 	return aq_to_posix[aq_rc];
diff --git a/drivers/net/ethernet/intel/i40e/i40e_nvm.c b/drivers/net/ethernet/intel/i40e/i40e_nvm.c
index 0fc62fc..1613ef4 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_nvm.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_nvm.c
@@ -527,7 +527,8 @@ static i40e_status i40e_nvmupd_state_init(struct i40e_hw *hw,
 	case I40E_NVMUPD_READ_SA:
 		status = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
 		if (status) {
-			*errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status);
+			*errno = i40e_aq_rc_to_posix(status,
+						     hw->aq.asq_last_status);
 		} else {
 			status = i40e_nvmupd_nvm_read(hw, cmd, bytes, errno);
 			i40e_release_nvm(hw);
@@ -537,7 +538,8 @@ static i40e_status i40e_nvmupd_state_init(struct i40e_hw *hw,
 	case I40E_NVMUPD_READ_SNT:
 		status = i40e_acquire_nvm(hw, I40E_RESOURCE_READ);
 		if (status) {
-			*errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status);
+			*errno = i40e_aq_rc_to_posix(status,
+						     hw->aq.asq_last_status);
 		} else {
 			status = i40e_nvmupd_nvm_read(hw, cmd, bytes, errno);
 			if (status)
@@ -550,7 +552,8 @@ static i40e_status i40e_nvmupd_state_init(struct i40e_hw *hw,
 	case I40E_NVMUPD_WRITE_ERA:
 		status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
 		if (status) {
-			*errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status);
+			*errno = i40e_aq_rc_to_posix(status,
+						     hw->aq.asq_last_status);
 		} else {
 			status = i40e_nvmupd_nvm_erase(hw, cmd, errno);
 			if (status)
@@ -563,7 +566,8 @@ static i40e_status i40e_nvmupd_state_init(struct i40e_hw *hw,
 	case I40E_NVMUPD_WRITE_SA:
 		status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
 		if (status) {
-			*errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status);
+			*errno = i40e_aq_rc_to_posix(status,
+						     hw->aq.asq_last_status);
 		} else {
 			status = i40e_nvmupd_nvm_write(hw, cmd, bytes, errno);
 			if (status)
@@ -576,7 +580,8 @@ static i40e_status i40e_nvmupd_state_init(struct i40e_hw *hw,
 	case I40E_NVMUPD_WRITE_SNT:
 		status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
 		if (status) {
-			*errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status);
+			*errno = i40e_aq_rc_to_posix(status,
+						     hw->aq.asq_last_status);
 		} else {
 			status = i40e_nvmupd_nvm_write(hw, cmd, bytes, errno);
 			if (status)
@@ -589,12 +594,14 @@ static i40e_status i40e_nvmupd_state_init(struct i40e_hw *hw,
 	case I40E_NVMUPD_CSUM_SA:
 		status = i40e_acquire_nvm(hw, I40E_RESOURCE_WRITE);
 		if (status) {
-			*errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status);
+			*errno = i40e_aq_rc_to_posix(status,
+						     hw->aq.asq_last_status);
 		} else {
 			status = i40e_update_nvm_checksum(hw);
 			if (status) {
 				*errno = hw->aq.asq_last_status ?
-				   i40e_aq_rc_to_posix(hw->aq.asq_last_status) :
+				   i40e_aq_rc_to_posix(status,
+						       hw->aq.asq_last_status) :
 				   -EIO;
 				i40e_release_nvm(hw);
 			} else {
@@ -691,7 +698,8 @@ static i40e_status i40e_nvmupd_state_writing(struct i40e_hw *hw,
 		status = i40e_update_nvm_checksum(hw);
 		if (status) {
 			*errno = hw->aq.asq_last_status ?
-				   i40e_aq_rc_to_posix(hw->aq.asq_last_status) :
+				   i40e_aq_rc_to_posix(status,
+						       hw->aq.asq_last_status) :
 				   -EIO;
 			hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
 		}
@@ -701,7 +709,8 @@ static i40e_status i40e_nvmupd_state_writing(struct i40e_hw *hw,
 		status = i40e_update_nvm_checksum(hw);
 		if (status)
 			*errno = hw->aq.asq_last_status ?
-				   i40e_aq_rc_to_posix(hw->aq.asq_last_status) :
+				   i40e_aq_rc_to_posix(status,
+						       hw->aq.asq_last_status) :
 				   -EIO;
 		else
 			hw->aq.nvm_release_on_done = true;
@@ -839,7 +848,7 @@ static i40e_status i40e_nvmupd_nvm_read(struct i40e_hw *hw,
 		i40e_debug(hw, I40E_DEBUG_NVM,
 			   "i40e_nvmupd_nvm_read status %d aq %d\n",
 			   status, hw->aq.asq_last_status);
-		*errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status);
+		*errno = i40e_aq_rc_to_posix(status, hw->aq.asq_last_status);
 	}
 
 	return status;
@@ -873,7 +882,7 @@ static i40e_status i40e_nvmupd_nvm_erase(struct i40e_hw *hw,
 		i40e_debug(hw, I40E_DEBUG_NVM,
 			   "i40e_nvmupd_nvm_erase status %d aq %d\n",
 			   status, hw->aq.asq_last_status);
-		*errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status);
+		*errno = i40e_aq_rc_to_posix(status, hw->aq.asq_last_status);
 	}
 
 	return status;
@@ -909,7 +918,7 @@ static i40e_status i40e_nvmupd_nvm_write(struct i40e_hw *hw,
 		i40e_debug(hw, I40E_DEBUG_NVM,
 			   "i40e_nvmupd_nvm_write status %d aq %d\n",
 			   status, hw->aq.asq_last_status);
-		*errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status);
+		*errno = i40e_aq_rc_to_posix(status, hw->aq.asq_last_status);
 	}
 
 	return status;
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_adminq.h b/drivers/net/ethernet/intel/i40evf/i40e_adminq.h
index 0ffb8d1..6c31bf2 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_adminq.h
+++ b/drivers/net/ethernet/intel/i40evf/i40e_adminq.h
@@ -28,6 +28,7 @@
 #define _I40E_ADMINQ_H_
 
 #include "i40e_osdep.h"
+#include "i40e_status.h"
 #include "i40e_adminq_cmd.h"
 
 #define I40E_ADMINQ_DESC(R, i)   \
@@ -108,7 +109,7 @@ struct i40e_adminq_info {
  * i40e_aq_rc_to_posix - convert errors to user-land codes
  * aq_rc: AdminQ error code to convert
  **/
-static inline int i40e_aq_rc_to_posix(u16 aq_rc)
+static inline int i40e_aq_rc_to_posix(u32 aq_ret, u16 aq_rc)
 {
 	int aq_to_posix[] = {
 		0,           /* I40E_AQ_RC_OK */
@@ -136,6 +137,10 @@ static inline int i40e_aq_rc_to_posix(u16 aq_rc)
 		-EFBIG,      /* I40E_AQ_RC_EFBIG */
 	};
 
+	/* aq_rc is invalid if AQ timed out */
+	if (aq_ret == I40E_ERR_ADMIN_QUEUE_TIMEOUT)
+		return -EAGAIN;
+
 	if (aq_rc >= ARRAY_SIZE(aq_to_posix))
 		return -ERANGE;
 	return aq_to_posix[aq_rc];
-- 
1.9.3

^ permalink raw reply related

* [net-next v2 09/13] i40e: fix up NVM update sm error handling
From: Jeff Kirsher @ 2014-12-09 21:26 UTC (permalink / raw)
  To: davem; +Cc: Shannon Nelson, netdev, nhorman, sassmann, jogreene, Jeff Kirsher
In-Reply-To: <1418160380-29847-1-git-send-email-jeffrey.t.kirsher@intel.com>

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

The state transitions after an error were not managed well, so
these changes get us back to the INIT state or don't transition
out of the INIT state after most errors.

Change-ID: I90aa0e4e348dc4f58cbcdce9c5d4b7fd35981c6c
Signed-off-by: Shannon Nelson <shannon.nelson@intel.com>
Acked-by: Michal Kosiarz <michal.kosiarz@intel.com>
Tested-by: Jim Young <jamesx.m.young@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/i40e/i40e_nvm.c | 26 ++++++++++++++++----------
 1 file changed, 16 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/intel/i40e/i40e_nvm.c b/drivers/net/ethernet/intel/i40e/i40e_nvm.c
index f55e52b..f3d1c85 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_nvm.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_nvm.c
@@ -535,7 +535,10 @@ static i40e_status i40e_nvmupd_state_init(struct i40e_hw *hw,
 			*errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status);
 		} else {
 			status = i40e_nvmupd_nvm_read(hw, cmd, bytes, errno);
-			hw->nvmupd_state = I40E_NVMUPD_STATE_READING;
+			if (status)
+				i40e_release_nvm(hw);
+			else
+				hw->nvmupd_state = I40E_NVMUPD_STATE_READING;
 		}
 		break;
 
@@ -571,7 +574,10 @@ static i40e_status i40e_nvmupd_state_init(struct i40e_hw *hw,
 			*errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status);
 		} else {
 			status = i40e_nvmupd_nvm_write(hw, cmd, bytes, errno);
-			hw->nvmupd_state = I40E_NVMUPD_STATE_WRITING;
+			if (status)
+				i40e_release_nvm(hw);
+			else
+				hw->nvmupd_state = I40E_NVMUPD_STATE_WRITING;
 		}
 		break;
 
@@ -671,30 +677,30 @@ static i40e_status i40e_nvmupd_state_writing(struct i40e_hw *hw,
 
 	case I40E_NVMUPD_WRITE_LCB:
 		status = i40e_nvmupd_nvm_write(hw, cmd, bytes, errno);
-		if (!status) {
+		if (!status)
 			hw->aq.nvm_release_on_done = true;
-			hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
-		}
+		hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
 		break;
 
 	case I40E_NVMUPD_CSUM_CON:
 		status = i40e_update_nvm_checksum(hw);
-		if (status)
+		if (status) {
 			*errno = hw->aq.asq_last_status ?
 				   i40e_aq_rc_to_posix(hw->aq.asq_last_status) :
 				   -EIO;
+			hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
+		}
 		break;
 
 	case I40E_NVMUPD_CSUM_LCB:
 		status = i40e_update_nvm_checksum(hw);
-		if (status) {
+		if (status)
 			*errno = hw->aq.asq_last_status ?
 				   i40e_aq_rc_to_posix(hw->aq.asq_last_status) :
 				   -EIO;
-		} else {
+		else
 			hw->aq.nvm_release_on_done = true;
-			hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
-		}
+		hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
 		break;
 
 	default:
-- 
1.9.3

^ permalink raw reply related

* [net-next v2 10/13] i40e: poll on NVM semaphore only if not other error
From: Jeff Kirsher @ 2014-12-09 21:26 UTC (permalink / raw)
  To: davem; +Cc: Shannon Nelson, netdev, nhorman, sassmann, jogreene, Jeff Kirsher
In-Reply-To: <1418160380-29847-1-git-send-email-jeffrey.t.kirsher@intel.com>

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

Only poll on the NVM semaphore if there's time left on a previous
reservation.  Also, add a little more info to debug messages.

Change-ID: I2439bf870b95a28b810dcb5cca1c06440463cf8a
Signed-off-by: Shannon Nelson <shannon.nelson@intel.com>
Acked-by: Jesse Brandeburg <jesse.brandeburg@intel.com>
Tested-by: Jim Young <jamesx.m.young@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/i40e/i40e_nvm.c | 13 +++++++++----
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/net/ethernet/intel/i40e/i40e_nvm.c b/drivers/net/ethernet/intel/i40e/i40e_nvm.c
index f3d1c85..0fc62fc 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_nvm.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_nvm.c
@@ -93,10 +93,15 @@ i40e_status i40e_acquire_nvm(struct i40e_hw *hw,
 	/* Store the timeout */
 	hw->nvm.hw_semaphore_timeout = I40E_MS_TO_GTIME(time_left) + gtime;
 
-	if (ret_code) {
+	if (ret_code)
+		i40e_debug(hw, I40E_DEBUG_NVM,
+			   "NVM acquire type %d failed time_left=%llu ret=%d aq_err=%d\n",
+			   access, time_left, ret_code, hw->aq.asq_last_status);
+
+	if (ret_code && time_left) {
 		/* Poll until the current NVM owner timeouts */
 		timeout = I40E_MS_TO_GTIME(I40E_MAX_NVM_TIMEOUT) + gtime;
-		while (gtime < timeout) {
+		while ((gtime < timeout) && time_left) {
 			usleep_range(10000, 20000);
 			gtime = rd32(hw, I40E_GLVFGEN_TIMER);
 			ret_code = i40e_aq_request_resource(hw,
@@ -112,8 +117,8 @@ i40e_status i40e_acquire_nvm(struct i40e_hw *hw,
 		if (ret_code) {
 			hw->nvm.hw_semaphore_timeout = 0;
 			i40e_debug(hw, I40E_DEBUG_NVM,
-				   "NVM acquire timed out, wait %llu ms before trying again.\n",
-				   time_left);
+				   "NVM acquire timed out, wait %llu ms before trying again. status=%d aq_err=%d\n",
+				   time_left, ret_code, hw->aq.asq_last_status);
 		}
 	}
 
-- 
1.9.3

^ permalink raw reply related

* [net-next v2 08/13] i40e: set max limit for access polling
From: Jeff Kirsher @ 2014-12-09 21:26 UTC (permalink / raw)
  To: davem; +Cc: Shannon Nelson, netdev, nhorman, sassmann, jogreene, Jeff Kirsher
In-Reply-To: <1418160380-29847-1-git-send-email-jeffrey.t.kirsher@intel.com>

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

Don't bother trying to set a smaller timeout on the polling,
just simplify the code and always use the max limit.  Also,
rename a variable for clarity and fix a comment.

Change-ID: I0300c3562ccc4fd5fa3088f8ae52db0c1eb33af5
Signed-off-by: Shannon Nelson <shannon.nelson@intel.com>
Acked-by: Michal Kosiarz <michal.kosiarz@intel.com>
Tested-by: Jim Young <jamesx.m.young@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/i40e/i40e_nvm.c    | 21 ++++++++-------------
 drivers/net/ethernet/intel/i40e/i40e_type.h   |  2 +-
 drivers/net/ethernet/intel/i40evf/i40e_type.h |  2 +-
 3 files changed, 10 insertions(+), 15 deletions(-)

diff --git a/drivers/net/ethernet/intel/i40e/i40e_nvm.c b/drivers/net/ethernet/intel/i40e/i40e_nvm.c
index 37f0f5f..f55e52b 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_nvm.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_nvm.c
@@ -80,45 +80,40 @@ i40e_status i40e_acquire_nvm(struct i40e_hw *hw,
 {
 	i40e_status ret_code = 0;
 	u64 gtime, timeout;
-	u64 time = 0;
+	u64 time_left = 0;
 
 	if (hw->nvm.blank_nvm_mode)
 		goto i40e_i40e_acquire_nvm_exit;
 
 	ret_code = i40e_aq_request_resource(hw, I40E_NVM_RESOURCE_ID, access,
-					    0, &time, NULL);
+					    0, &time_left, NULL);
 	/* Reading the Global Device Timer */
 	gtime = rd32(hw, I40E_GLVFGEN_TIMER);
 
 	/* Store the timeout */
-	hw->nvm.hw_semaphore_timeout = I40E_MS_TO_GTIME(time) + gtime;
+	hw->nvm.hw_semaphore_timeout = I40E_MS_TO_GTIME(time_left) + gtime;
 
 	if (ret_code) {
-		/* Set the polling timeout */
-		if (time > I40E_MAX_NVM_TIMEOUT)
-			timeout = I40E_MS_TO_GTIME(I40E_MAX_NVM_TIMEOUT)
-				  + gtime;
-		else
-			timeout = hw->nvm.hw_semaphore_timeout;
 		/* Poll until the current NVM owner timeouts */
+		timeout = I40E_MS_TO_GTIME(I40E_MAX_NVM_TIMEOUT) + gtime;
 		while (gtime < timeout) {
 			usleep_range(10000, 20000);
+			gtime = rd32(hw, I40E_GLVFGEN_TIMER);
 			ret_code = i40e_aq_request_resource(hw,
 							I40E_NVM_RESOURCE_ID,
-							access, 0, &time,
+							access, 0, &time_left,
 							NULL);
 			if (!ret_code) {
 				hw->nvm.hw_semaphore_timeout =
-						I40E_MS_TO_GTIME(time) + gtime;
+					    I40E_MS_TO_GTIME(time_left) + gtime;
 				break;
 			}
-			gtime = rd32(hw, I40E_GLVFGEN_TIMER);
 		}
 		if (ret_code) {
 			hw->nvm.hw_semaphore_timeout = 0;
 			i40e_debug(hw, I40E_DEBUG_NVM,
 				   "NVM acquire timed out, wait %llu ms before trying again.\n",
-				   time);
+				   time_left);
 		}
 	}
 
diff --git a/drivers/net/ethernet/intel/i40e/i40e_type.h b/drivers/net/ethernet/intel/i40e/i40e_type.h
index 306a23a..844421f 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_type.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_type.h
@@ -261,7 +261,7 @@ enum i40e_aq_resource_access_type {
 };
 
 struct i40e_nvm_info {
-	u64 hw_semaphore_timeout; /* 2usec global time (GTIME resolution) */
+	u64 hw_semaphore_timeout; /* usec global time (GTIME resolution) */
 	u32 timeout;              /* [ms] */
 	u16 sr_size;              /* Shadow RAM size in words */
 	bool blank_nvm_mode;      /* is NVM empty (no FW present)*/
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_type.h b/drivers/net/ethernet/intel/i40evf/i40e_type.h
index 9d472d6..d8175cd 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_type.h
+++ b/drivers/net/ethernet/intel/i40evf/i40e_type.h
@@ -260,7 +260,7 @@ enum i40e_aq_resource_access_type {
 };
 
 struct i40e_nvm_info {
-	u64 hw_semaphore_timeout; /* 2usec global time (GTIME resolution) */
+	u64 hw_semaphore_timeout; /* usec global time (GTIME resolution) */
 	u32 timeout;              /* [ms] */
 	u16 sr_size;              /* Shadow RAM size in words */
 	bool blank_nvm_mode;      /* is NVM empty (no FW present)*/
-- 
1.9.3

^ permalink raw reply related

* [net-next v2 07/13] i40e: remove unused nvm_semaphore_wait
From: Jeff Kirsher @ 2014-12-09 21:26 UTC (permalink / raw)
  To: davem; +Cc: Shannon Nelson, netdev, nhorman, sassmann, jogreene, Jeff Kirsher
In-Reply-To: <1418160380-29847-1-git-send-email-jeffrey.t.kirsher@intel.com>

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

The nvm_semaphore_wait field is set but never used, so let's
just get rid of it.

Change-ID: I2107bd29b69f99b1a61d7591d087429527c9d8fa
Signed-off-by: Shannon Nelson <shannon.nelson@intel.com>
Acked-by: Michal Kosiarz <michal.kosiarz@intel.com>
Tested-by: Jim Young <jamesx.m.young@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/i40e/i40e_nvm.c    | 2 --
 drivers/net/ethernet/intel/i40e/i40e_type.h   | 1 -
 drivers/net/ethernet/intel/i40evf/i40e_type.h | 1 -
 3 files changed, 4 deletions(-)

diff --git a/drivers/net/ethernet/intel/i40e/i40e_nvm.c b/drivers/net/ethernet/intel/i40e/i40e_nvm.c
index df429bb..37f0f5f 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_nvm.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_nvm.c
@@ -116,8 +116,6 @@ i40e_status i40e_acquire_nvm(struct i40e_hw *hw,
 		}
 		if (ret_code) {
 			hw->nvm.hw_semaphore_timeout = 0;
-			hw->nvm.hw_semaphore_wait =
-						I40E_MS_TO_GTIME(time) + gtime;
 			i40e_debug(hw, I40E_DEBUG_NVM,
 				   "NVM acquire timed out, wait %llu ms before trying again.\n",
 				   time);
diff --git a/drivers/net/ethernet/intel/i40e/i40e_type.h b/drivers/net/ethernet/intel/i40e/i40e_type.h
index 3904dd8..306a23a 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_type.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_type.h
@@ -262,7 +262,6 @@ enum i40e_aq_resource_access_type {
 
 struct i40e_nvm_info {
 	u64 hw_semaphore_timeout; /* 2usec global time (GTIME resolution) */
-	u64 hw_semaphore_wait;    /* - || - */
 	u32 timeout;              /* [ms] */
 	u16 sr_size;              /* Shadow RAM size in words */
 	bool blank_nvm_mode;      /* is NVM empty (no FW present)*/
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_type.h b/drivers/net/ethernet/intel/i40evf/i40e_type.h
index 77abe17..9d472d6 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_type.h
+++ b/drivers/net/ethernet/intel/i40evf/i40e_type.h
@@ -261,7 +261,6 @@ enum i40e_aq_resource_access_type {
 
 struct i40e_nvm_info {
 	u64 hw_semaphore_timeout; /* 2usec global time (GTIME resolution) */
-	u64 hw_semaphore_wait;    /* - || - */
 	u32 timeout;              /* [ms] */
 	u16 sr_size;              /* Shadow RAM size in words */
 	bool blank_nvm_mode;      /* is NVM empty (no FW present)*/
-- 
1.9.3

^ permalink raw reply related

* [net-next v2 06/13] i40e: init NVM update state on adminq init
From: Jeff Kirsher @ 2014-12-09 21:26 UTC (permalink / raw)
  To: davem; +Cc: Shannon Nelson, netdev, nhorman, sassmann, jogreene, Jeff Kirsher
In-Reply-To: <1418160380-29847-1-git-send-email-jeffrey.t.kirsher@intel.com>

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

The adminq init is run after the EMPR that is triggered by the
NVM update.  The final write command will cause the reset and
will want to wait for the ARQ event that signals the end of the
update, but the reset precludes the event being sent.  The state
is probably already at INIT, but we set it so here anyway, and
clear the release_on_done flag as well.

Change-ID: Ie9d724a39e71f988741abc3d51b4cb198c7e0272
Signed-off-by: Shannon Nelson <shannon.nelson@intel.com>
Acked-by: Michal Kosiarz <michal.kosiarz@intel.com>
Acked-by: Kamil Krawczyk <kamil.krawczyk@intel.com>
Tested-by: Jim Young <jamesx.m.young@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/i40e/i40e_adminq.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq.c b/drivers/net/ethernet/intel/i40e/i40e_adminq.c
index ebff11b..77f6254 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_adminq.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_adminq.c
@@ -617,6 +617,8 @@ i40e_status i40e_init_adminq(struct i40e_hw *hw)
 
 	/* pre-emptive resource lock release */
 	i40e_aq_release_resource(hw, I40E_NVM_RESOURCE_ID, 0, NULL);
+	hw->aq.nvm_release_on_done = false;
+	hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
 
 	ret_code = i40e_aq_set_hmc_resource_profile(hw,
 						    I40E_HMC_PROFILE_DEFAULT,
-- 
1.9.3

^ permalink raw reply related

* [net-next v2 05/13] i40e: add range check to i40e_aq_rc_to_posix
From: Jeff Kirsher @ 2014-12-09 21:26 UTC (permalink / raw)
  To: davem
  Cc: Shannon Nelson, netdev, nhorman, sassmann, jogreene,
	Sergei Shtylyov, Jeff Kirsher
In-Reply-To: <1418160380-29847-1-git-send-email-jeffrey.t.kirsher@intel.com>

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

Just to be sure, add a range check to avoid any possible
array index-out-of-bound issues.

CC: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
Change-ID: I9323bee6732c2a47599816e1d6c6b3a1f8dcbf54
Signed-off-by: Shannon Nelson <shannon.nelson@intel.com>
Acked-by: Michal Kosiarz <michal.kosiarz@intel.com>
Tested-by: Jim Young <jamesx.m.young@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
v2:
 - modified the patch to use ARRAY_SIZE() macro as suggested by Sergei Shtylyov

 drivers/net/ethernet/intel/i40e/i40e_adminq.h   | 2 ++
 drivers/net/ethernet/intel/i40evf/i40e_adminq.h | 2 ++
 2 files changed, 4 insertions(+)

diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq.h b/drivers/net/ethernet/intel/i40e/i40e_adminq.h
index 618fe96..2c68bf7 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_adminq.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_adminq.h
@@ -136,6 +136,8 @@ static inline int i40e_aq_rc_to_posix(u16 aq_rc)
 		-EFBIG,      /* I40E_AQ_RC_EFBIG */
 	};
 
+	if (aq_rc >= ARRAY_SIZE(aq_to_posix))
+		return -ERANGE;
 	return aq_to_posix[aq_rc];
 }
 
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_adminq.h b/drivers/net/ethernet/intel/i40evf/i40e_adminq.h
index d5d3c93..0ffb8d1 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_adminq.h
+++ b/drivers/net/ethernet/intel/i40evf/i40e_adminq.h
@@ -136,6 +136,8 @@ static inline int i40e_aq_rc_to_posix(u16 aq_rc)
 		-EFBIG,      /* I40E_AQ_RC_EFBIG */
 	};
 
+	if (aq_rc >= ARRAY_SIZE(aq_to_posix))
+		return -ERANGE;
 	return aq_to_posix[aq_rc];
 }
 
-- 
1.9.3

^ permalink raw reply related

* [net-next v2 04/13] i40e: rework debug messages for NVM update
From: Jeff Kirsher @ 2014-12-09 21:26 UTC (permalink / raw)
  To: davem; +Cc: Shannon Nelson, netdev, nhorman, sassmann, jogreene, Jeff Kirsher
In-Reply-To: <1418160380-29847-1-git-send-email-jeffrey.t.kirsher@intel.com>

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

Rework the debug messages in the NVM update state machine so that we can
turn them on and off dynamically rather than forcing a recompile/reload.

These can now be turned on with something like:
	ethtool -s eth1 msglvl 0xf000008f
and off with:
	ethtool -s eth1 msglvl 0xf000000f

The high 0xf0000000 gets the driver's attention that we want to change the
internal debug flags, and the 0x80 bit is the NVM debug.

Change-ID: I5efb9039400304b29a0fd6ddea3f47bb362e6661
Signed-off-by: Shannon Nelson <shannon.nelson@intel.com>
Acked-by: Greg Rose <gregory.v.rose@intel.com>
Tested-by: Jim Young <jamesx.m.young@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/i40e/i40e_nvm.c | 107 +++++++++++++++++++++--------
 1 file changed, 80 insertions(+), 27 deletions(-)

diff --git a/drivers/net/ethernet/intel/i40e/i40e_nvm.c b/drivers/net/ethernet/intel/i40e/i40e_nvm.c
index 25c4f9a..df429bb 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_nvm.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_nvm.c
@@ -61,7 +61,7 @@ i40e_status i40e_init_nvm(struct i40e_hw *hw)
 	} else { /* Blank programming mode */
 		nvm->blank_nvm_mode = true;
 		ret_code = I40E_ERR_NVM_BLANK_MODE;
-		hw_dbg(hw, "NVM init error: unsupported blank mode.\n");
+		i40e_debug(hw, I40E_DEBUG_NVM, "NVM init error: unsupported blank mode.\n");
 	}
 
 	return ret_code;
@@ -118,8 +118,9 @@ i40e_status i40e_acquire_nvm(struct i40e_hw *hw,
 			hw->nvm.hw_semaphore_timeout = 0;
 			hw->nvm.hw_semaphore_wait =
 						I40E_MS_TO_GTIME(time) + gtime;
-			hw_dbg(hw, "NVM acquire timed out, wait %llu ms before trying again.\n",
-				  time);
+			i40e_debug(hw, I40E_DEBUG_NVM,
+				   "NVM acquire timed out, wait %llu ms before trying again.\n",
+				   time);
 		}
 	}
 
@@ -160,7 +161,7 @@ static i40e_status i40e_poll_sr_srctl_done_bit(struct i40e_hw *hw)
 		udelay(5);
 	}
 	if (ret_code == I40E_ERR_TIMEOUT)
-		hw_dbg(hw, "Done bit in GLNVM_SRCTL not set\n");
+		i40e_debug(hw, I40E_DEBUG_NVM, "Done bit in GLNVM_SRCTL not set");
 	return ret_code;
 }
 
@@ -179,7 +180,9 @@ i40e_status i40e_read_nvm_word(struct i40e_hw *hw, u16 offset,
 	u32 sr_reg;
 
 	if (offset >= hw->nvm.sr_size) {
-		hw_dbg(hw, "NVM read error: Offset beyond Shadow RAM limit.\n");
+		i40e_debug(hw, I40E_DEBUG_NVM,
+			   "NVM read error: offset %d beyond Shadow RAM limit %d\n",
+			   offset, hw->nvm.sr_size);
 		ret_code = I40E_ERR_PARAM;
 		goto read_nvm_exit;
 	}
@@ -202,8 +205,9 @@ i40e_status i40e_read_nvm_word(struct i40e_hw *hw, u16 offset,
 		}
 	}
 	if (ret_code)
-		hw_dbg(hw, "NVM read error: Couldn't access Shadow RAM address: 0x%x\n",
-			  offset);
+		i40e_debug(hw, I40E_DEBUG_NVM,
+			   "NVM read error: Couldn't access Shadow RAM address: 0x%x\n",
+			   offset);
 
 read_nvm_exit:
 	return ret_code;
@@ -263,14 +267,20 @@ static i40e_status i40e_write_nvm_aq(struct i40e_hw *hw, u8 module_pointer,
 	 * Firmware will check the module-based model.
 	 */
 	if ((offset + words) > hw->nvm.sr_size)
-		hw_dbg(hw, "NVM write error: offset beyond Shadow RAM limit.\n");
+		i40e_debug(hw, I40E_DEBUG_NVM,
+			   "NVM write error: offset %d beyond Shadow RAM limit %d\n",
+			   (offset + words), hw->nvm.sr_size);
 	else if (words > I40E_SR_SECTOR_SIZE_IN_WORDS)
 		/* We can write only up to 4KB (one sector), in one AQ write */
-		hw_dbg(hw, "NVM write fail error: cannot write more than 4KB in a single write.\n");
+		i40e_debug(hw, I40E_DEBUG_NVM,
+			   "NVM write fail error: tried to write %d words, limit is %d.\n",
+			   words, I40E_SR_SECTOR_SIZE_IN_WORDS);
 	else if (((offset + (words - 1)) / I40E_SR_SECTOR_SIZE_IN_WORDS)
 		 != (offset / I40E_SR_SECTOR_SIZE_IN_WORDS))
 		/* A single write cannot spread over two sectors */
-		hw_dbg(hw, "NVM write error: cannot spread over two sectors in a single write.\n");
+		i40e_debug(hw, I40E_DEBUG_NVM,
+			   "NVM write error: cannot spread over two sectors in a single write offset=%d words=%d\n",
+			   offset, words);
 	else
 		ret_code = i40e_aq_update_nvm(hw, module_pointer,
 					      2 * offset,  /*bytes*/
@@ -438,6 +448,22 @@ static inline u8 i40e_nvmupd_get_transaction(u32 val)
 	return (u8)((val & I40E_NVM_TRANS_MASK) >> I40E_NVM_TRANS_SHIFT);
 }
 
+static char *i40e_nvm_update_state_str[] = {
+	"I40E_NVMUPD_INVALID",
+	"I40E_NVMUPD_READ_CON",
+	"I40E_NVMUPD_READ_SNT",
+	"I40E_NVMUPD_READ_LCB",
+	"I40E_NVMUPD_READ_SA",
+	"I40E_NVMUPD_WRITE_ERA",
+	"I40E_NVMUPD_WRITE_CON",
+	"I40E_NVMUPD_WRITE_SNT",
+	"I40E_NVMUPD_WRITE_LCB",
+	"I40E_NVMUPD_WRITE_SA",
+	"I40E_NVMUPD_CSUM_CON",
+	"I40E_NVMUPD_CSUM_SA",
+	"I40E_NVMUPD_CSUM_LCB",
+};
+
 /**
  * i40e_nvmupd_command - Process an NVM update command
  * @hw: pointer to hardware structure
@@ -471,6 +497,8 @@ i40e_status i40e_nvmupd_command(struct i40e_hw *hw,
 
 	default:
 		/* invalid state, should never happen */
+		i40e_debug(hw, I40E_DEBUG_NVM,
+			   "NVMUPD: no such state %d\n", hw->nvmupd_state);
 		status = I40E_NOT_SUPPORTED;
 		*errno = -ESRCH;
 		break;
@@ -572,6 +600,9 @@ static i40e_status i40e_nvmupd_state_init(struct i40e_hw *hw,
 		break;
 
 	default:
+		i40e_debug(hw, I40E_DEBUG_NVM,
+			   "NVMUPD: bad cmd %s in init state\n",
+			   i40e_nvm_update_state_str[upd_cmd]);
 		status = I40E_ERR_NVM;
 		*errno = -ESRCH;
 		break;
@@ -611,6 +642,9 @@ static i40e_status i40e_nvmupd_state_reading(struct i40e_hw *hw,
 		break;
 
 	default:
+		i40e_debug(hw, I40E_DEBUG_NVM,
+			   "NVMUPD: bad cmd %s in reading state.\n",
+			   i40e_nvm_update_state_str[upd_cmd]);
 		status = I40E_NOT_SUPPORTED;
 		*errno = -ESRCH;
 		break;
@@ -671,6 +705,9 @@ static i40e_status i40e_nvmupd_state_writing(struct i40e_hw *hw,
 		break;
 
 	default:
+		i40e_debug(hw, I40E_DEBUG_NVM,
+			   "NVMUPD: bad cmd %s in writing state.\n",
+			   i40e_nvm_update_state_str[upd_cmd]);
 		status = I40E_NOT_SUPPORTED;
 		*errno = -ESRCH;
 		break;
@@ -702,8 +739,9 @@ static enum i40e_nvmupd_cmd i40e_nvmupd_validate_command(struct i40e_hw *hw,
 	/* limits on data size */
 	if ((cmd->data_size < 1) ||
 	    (cmd->data_size > I40E_NVMUPD_MAX_DATA)) {
-		hw_dbg(hw, "i40e_nvmupd_validate_command data_size %d\n",
-		       cmd->data_size);
+		i40e_debug(hw, I40E_DEBUG_NVM,
+			   "i40e_nvmupd_validate_command data_size %d\n",
+			   cmd->data_size);
 		*errno = -EFAULT;
 		return I40E_NVMUPD_INVALID;
 	}
@@ -755,12 +793,14 @@ static enum i40e_nvmupd_cmd i40e_nvmupd_validate_command(struct i40e_hw *hw,
 		}
 		break;
 	}
+	i40e_debug(hw, I40E_DEBUG_NVM, "%s\n",
+		   i40e_nvm_update_state_str[upd_cmd]);
 
 	if (upd_cmd == I40E_NVMUPD_INVALID) {
 		*errno = -EFAULT;
-		hw_dbg(hw,
-		       "i40e_nvmupd_validate_command returns %d  errno: %d\n",
-		       upd_cmd, *errno);
+		i40e_debug(hw, I40E_DEBUG_NVM,
+			   "i40e_nvmupd_validate_command returns %d errno %d\n",
+			   upd_cmd, *errno);
 	}
 	return upd_cmd;
 }
@@ -785,14 +825,18 @@ static i40e_status i40e_nvmupd_nvm_read(struct i40e_hw *hw,
 	transaction = i40e_nvmupd_get_transaction(cmd->config);
 	module = i40e_nvmupd_get_module(cmd->config);
 	last = (transaction == I40E_NVM_LCB) || (transaction == I40E_NVM_SA);
-	hw_dbg(hw, "i40e_nvmupd_nvm_read mod 0x%x  off 0x%x  len 0x%x\n",
-	       module, cmd->offset, cmd->data_size);
 
 	status = i40e_aq_read_nvm(hw, module, cmd->offset, (u16)cmd->data_size,
 				  bytes, last, NULL);
-	hw_dbg(hw, "i40e_nvmupd_nvm_read status %d\n", status);
-	if (status)
+	if (status) {
+		i40e_debug(hw, I40E_DEBUG_NVM,
+			   "i40e_nvmupd_nvm_read mod 0x%x  off 0x%x  len 0x%x\n",
+			   module, cmd->offset, cmd->data_size);
+		i40e_debug(hw, I40E_DEBUG_NVM,
+			   "i40e_nvmupd_nvm_read status %d aq %d\n",
+			   status, hw->aq.asq_last_status);
 		*errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status);
+	}
 
 	return status;
 }
@@ -816,13 +860,17 @@ static i40e_status i40e_nvmupd_nvm_erase(struct i40e_hw *hw,
 	transaction = i40e_nvmupd_get_transaction(cmd->config);
 	module = i40e_nvmupd_get_module(cmd->config);
 	last = (transaction & I40E_NVM_LCB);
-	hw_dbg(hw, "i40e_nvmupd_nvm_erase mod 0x%x  off 0x%x  len 0x%x\n",
-	       module, cmd->offset, cmd->data_size);
 	status = i40e_aq_erase_nvm(hw, module, cmd->offset, (u16)cmd->data_size,
 				   last, NULL);
-	hw_dbg(hw, "i40e_nvmupd_nvm_erase status %d\n", status);
-	if (status)
+	if (status) {
+		i40e_debug(hw, I40E_DEBUG_NVM,
+			   "i40e_nvmupd_nvm_erase mod 0x%x  off 0x%x len 0x%x\n",
+			   module, cmd->offset, cmd->data_size);
+		i40e_debug(hw, I40E_DEBUG_NVM,
+			   "i40e_nvmupd_nvm_erase status %d aq %d\n",
+			   status, hw->aq.asq_last_status);
 		*errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status);
+	}
 
 	return status;
 }
@@ -847,13 +895,18 @@ static i40e_status i40e_nvmupd_nvm_write(struct i40e_hw *hw,
 	transaction = i40e_nvmupd_get_transaction(cmd->config);
 	module = i40e_nvmupd_get_module(cmd->config);
 	last = (transaction & I40E_NVM_LCB);
-	hw_dbg(hw, "i40e_nvmupd_nvm_write mod 0x%x off 0x%x len 0x%x\n",
-	       module, cmd->offset, cmd->data_size);
+
 	status = i40e_aq_update_nvm(hw, module, cmd->offset,
 				    (u16)cmd->data_size, bytes, last, NULL);
-	hw_dbg(hw, "i40e_nvmupd_nvm_write status %d\n", status);
-	if (status)
+	if (status) {
+		i40e_debug(hw, I40E_DEBUG_NVM,
+			   "i40e_nvmupd_nvm_write mod 0x%x off 0x%x len 0x%x\n",
+			   module, cmd->offset, cmd->data_size);
+		i40e_debug(hw, I40E_DEBUG_NVM,
+			   "i40e_nvmupd_nvm_write status %d aq %d\n",
+			   status, hw->aq.asq_last_status);
 		*errno = i40e_aq_rc_to_posix(hw->aq.asq_last_status);
+	}
 
 	return status;
 }
-- 
1.9.3

^ permalink raw reply related

* [net-next v2 03/13] i40e: let firmware catch the NVM busy error
From: Jeff Kirsher @ 2014-12-09 21:26 UTC (permalink / raw)
  To: davem; +Cc: Shannon Nelson, netdev, nhorman, sassmann, jogreene, Jeff Kirsher
In-Reply-To: <1418160380-29847-1-git-send-email-jeffrey.t.kirsher@intel.com>

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

The NVM update operations take time finish asynchronously, and follow-on
update requests need to wait for the current one to finish.  Early
firmware didn't handle this well, so the code had to track the busy state.
The released firmware handles the busy state correctly, returning
I40E_AQ_RC_EBUSY if an update is still in progress, so the code no longer
needs to track this.

Change-ID: I6e6b4adc26d6dcc5fd7adfee5763423858a7d921
Signed-off-by: Shannon Nelson <shannon.nelson@intel.com>
Acked-by: Greg Rose <gregory.v.rose@intel.com>
Tested-by: Jim Young <jamesx.m.young@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/i40e/i40e_adminq.c   | 11 -----------
 drivers/net/ethernet/intel/i40e/i40e_adminq.h   |  1 -
 drivers/net/ethernet/intel/i40evf/i40e_adminq.c |  6 ------
 drivers/net/ethernet/intel/i40evf/i40e_adminq.h |  1 -
 4 files changed, 19 deletions(-)

diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq.c b/drivers/net/ethernet/intel/i40e/i40e_adminq.c
index 35fa09a..ebff11b 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_adminq.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_adminq.c
@@ -617,7 +617,6 @@ i40e_status i40e_init_adminq(struct i40e_hw *hw)
 
 	/* pre-emptive resource lock release */
 	i40e_aq_release_resource(hw, I40E_NVM_RESOURCE_ID, 0, NULL);
-	hw->aq.nvm_busy = false;
 
 	ret_code = i40e_aq_set_hmc_resource_profile(hw,
 						    I40E_HMC_PROFILE_DEFAULT,
@@ -754,12 +753,6 @@ i40e_status i40e_asq_send_command(struct i40e_hw *hw,
 		goto asq_send_command_exit;
 	}
 
-	if (i40e_is_nvm_update_op(desc) && hw->aq.nvm_busy) {
-		i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, "AQTX: NVM busy.\n");
-		status = I40E_ERR_NVM;
-		goto asq_send_command_exit;
-	}
-
 	details = I40E_ADMINQ_DETAILS(hw->aq.asq, hw->aq.asq.next_to_use);
 	if (cmd_details) {
 		*details = *cmd_details;
@@ -901,9 +894,6 @@ i40e_status i40e_asq_send_command(struct i40e_hw *hw,
 		status = I40E_ERR_ADMIN_QUEUE_TIMEOUT;
 	}
 
-	if (!status && i40e_is_nvm_update_op(desc))
-		hw->aq.nvm_busy = true;
-
 asq_send_command_error:
 	mutex_unlock(&hw->aq.asq_mutex);
 asq_send_command_exit:
@@ -1016,7 +1006,6 @@ clean_arq_element_out:
 	mutex_unlock(&hw->aq.arq_mutex);
 
 	if (i40e_is_nvm_update_op(&e->desc)) {
-		hw->aq.nvm_busy = false;
 		if (hw->aq.nvm_release_on_done) {
 			i40e_release_nvm(hw);
 			hw->aq.nvm_release_on_done = false;
diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq.h b/drivers/net/ethernet/intel/i40e/i40e_adminq.h
index 003a227..618fe96 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_adminq.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_adminq.h
@@ -94,7 +94,6 @@ struct i40e_adminq_info {
 	u16 fw_min_ver;                 /* firmware minor version */
 	u16 api_maj_ver;                /* api major version */
 	u16 api_min_ver;                /* api minor version */
-	bool nvm_busy;
 	bool nvm_release_on_done;
 
 	struct mutex asq_mutex; /* Send queue lock */
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_adminq.c b/drivers/net/ethernet/intel/i40evf/i40e_adminq.c
index 1698994..c1d25f8 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_adminq.c
+++ b/drivers/net/ethernet/intel/i40evf/i40e_adminq.c
@@ -836,9 +836,6 @@ i40e_status i40evf_asq_send_command(struct i40e_hw *hw,
 		hw->aq.asq_last_status = (enum i40e_admin_queue_err)retval;
 	}
 
-	if (i40e_is_nvm_update_op(desc))
-		hw->aq.nvm_busy = true;
-
 	i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE,
 		   "AQTX: desc and buffer writeback:\n");
 	i40evf_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc, buff,
@@ -931,9 +928,6 @@ i40e_status i40evf_clean_arq_element(struct i40e_hw *hw,
 		memcpy(e->msg_buf, hw->aq.arq.r.arq_bi[desc_idx].va,
 		       e->msg_len);
 
-	if (i40e_is_nvm_update_op(&e->desc))
-		hw->aq.nvm_busy = false;
-
 	i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE, "AQRX: desc and buffer:\n");
 	i40evf_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc, e->msg_buf,
 			hw->aq.arq_buf_size);
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_adminq.h b/drivers/net/ethernet/intel/i40evf/i40e_adminq.h
index 0d58378..d5d3c93 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_adminq.h
+++ b/drivers/net/ethernet/intel/i40evf/i40e_adminq.h
@@ -94,7 +94,6 @@ struct i40e_adminq_info {
 	u16 fw_min_ver;                 /* firmware minor version */
 	u16 api_maj_ver;                /* api major version */
 	u16 api_min_ver;                /* api minor version */
-	bool nvm_busy;
 	bool nvm_release_on_done;
 
 	struct mutex asq_mutex; /* Send queue lock */
-- 
1.9.3

^ permalink raw reply related

* [net-next v2 02/13] i40e: better error messages for NVM update issues
From: Jeff Kirsher @ 2014-12-09 21:26 UTC (permalink / raw)
  To: davem; +Cc: Shannon Nelson, netdev, nhorman, sassmann, jogreene, Jeff Kirsher
In-Reply-To: <1418160380-29847-1-git-send-email-jeffrey.t.kirsher@intel.com>

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

Add more detail to the NVM update error messages so folks
have a better chance at diagnosing issues without having to
resort to heroic measures to reproduce an issue.

Change-ID: I270d1a9c903baceaef0bebcc55d29108ac08b0bd
Signed-off-by: Shannon Nelson <shannon.nelson@intel.com>
Tested-by: Jim Young <jamesx.m.young@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 52 ++++++++++++++++----------
 1 file changed, 33 insertions(+), 19 deletions(-)

diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
index 25242f5..951e876 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
@@ -822,7 +822,7 @@ static int i40e_get_eeprom(struct net_device *netdev,
 	struct i40e_netdev_priv *np = netdev_priv(netdev);
 	struct i40e_hw *hw = &np->vsi->back->hw;
 	struct i40e_pf *pf = np->vsi->back;
-	int ret_val = 0, len;
+	int ret_val = 0, len, offset;
 	u8 *eeprom_buff;
 	u16 i, sectors;
 	bool last;
@@ -835,19 +835,21 @@ static int i40e_get_eeprom(struct net_device *netdev,
 	/* check for NVMUpdate access method */
 	magic = hw->vendor_id | (hw->device_id << 16);
 	if (eeprom->magic && eeprom->magic != magic) {
+		struct i40e_nvm_access *cmd;
 		int errno;
 
 		/* make sure it is the right magic for NVMUpdate */
 		if ((eeprom->magic >> 16) != hw->device_id)
 			return -EINVAL;
 
-		ret_val = i40e_nvmupd_command(hw,
-					      (struct i40e_nvm_access *)eeprom,
-					      bytes, &errno);
+		cmd = (struct i40e_nvm_access *)eeprom;
+		ret_val = i40e_nvmupd_command(hw, cmd, bytes, &errno);
 		if (ret_val)
 			dev_info(&pf->pdev->dev,
-				 "NVMUpdate read failed err=%d status=0x%x\n",
-				 ret_val, hw->aq.asq_last_status);
+				 "NVMUpdate read failed err=%d status=0x%x errno=%d module=%d offset=0x%x size=%d\n",
+				 ret_val, hw->aq.asq_last_status, errno,
+				 (u8)(cmd->config & I40E_NVM_MOD_PNT_MASK),
+				 cmd->offset, cmd->data_size);
 
 		return errno;
 	}
@@ -876,20 +878,29 @@ static int i40e_get_eeprom(struct net_device *netdev,
 			len = eeprom->len - (I40E_NVM_SECTOR_SIZE * i);
 			last = true;
 		}
-		ret_val = i40e_aq_read_nvm(hw, 0x0,
-				eeprom->offset + (I40E_NVM_SECTOR_SIZE * i),
-				len,
+		offset = eeprom->offset + (I40E_NVM_SECTOR_SIZE * i),
+		ret_val = i40e_aq_read_nvm(hw, 0x0, offset, len,
 				(u8 *)eeprom_buff + (I40E_NVM_SECTOR_SIZE * i),
 				last, NULL);
-		if (ret_val) {
+		if (ret_val && hw->aq.asq_last_status == I40E_AQ_RC_EPERM) {
 			dev_info(&pf->pdev->dev,
-				 "read NVM failed err=%d status=0x%x\n",
-				 ret_val, hw->aq.asq_last_status);
-			goto release_nvm;
+				 "read NVM failed, invalid offset 0x%x\n",
+				 offset);
+			break;
+		} else if (ret_val &&
+			   hw->aq.asq_last_status == I40E_AQ_RC_EACCES) {
+			dev_info(&pf->pdev->dev,
+				 "read NVM failed, access, offset 0x%x\n",
+				 offset);
+			break;
+		} else if (ret_val) {
+			dev_info(&pf->pdev->dev,
+				 "read NVM failed offset %d err=%d status=0x%x\n",
+				 offset, ret_val, hw->aq.asq_last_status);
+			break;
 		}
 	}
 
-release_nvm:
 	i40e_release_nvm(hw);
 	memcpy(bytes, (u8 *)eeprom_buff, eeprom->len);
 free_buff:
@@ -917,6 +928,7 @@ static int i40e_set_eeprom(struct net_device *netdev,
 	struct i40e_netdev_priv *np = netdev_priv(netdev);
 	struct i40e_hw *hw = &np->vsi->back->hw;
 	struct i40e_pf *pf = np->vsi->back;
+	struct i40e_nvm_access *cmd;
 	int ret_val = 0;
 	int errno;
 	u32 magic;
@@ -934,12 +946,14 @@ static int i40e_set_eeprom(struct net_device *netdev,
 	    test_bit(__I40E_RESET_INTR_RECEIVED, &pf->state))
 		return -EBUSY;
 
-	ret_val = i40e_nvmupd_command(hw, (struct i40e_nvm_access *)eeprom,
-				      bytes, &errno);
-	if (ret_val)
+	cmd = (struct i40e_nvm_access *)eeprom;
+	ret_val = i40e_nvmupd_command(hw, cmd, bytes, &errno);
+	if (ret_val && hw->aq.asq_last_status != I40E_AQ_RC_EBUSY)
 		dev_info(&pf->pdev->dev,
-			 "NVMUpdate write failed err=%d status=0x%x\n",
-			 ret_val, hw->aq.asq_last_status);
+			 "NVMUpdate write failed err=%d status=0x%x errno=%d module=%d offset=0x%x size=%d\n",
+			 ret_val, hw->aq.asq_last_status, errno,
+			 (u8)(cmd->config & I40E_NVM_MOD_PNT_MASK),
+			 cmd->offset, cmd->data_size);
 
 	return errno;
 }
-- 
1.9.3

^ permalink raw reply related

* [net-next v2 01/13] i40e: clear NVM update state on ethtool test
From: Jeff Kirsher @ 2014-12-09 21:26 UTC (permalink / raw)
  To: davem; +Cc: Shannon Nelson, netdev, nhorman, sassmann, jogreene, Jeff Kirsher
In-Reply-To: <1418160380-29847-1-git-send-email-jeffrey.t.kirsher@intel.com>

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

Once in a great while the NVMUpdate tools and the driver get out
of phase with each other.  This gives us a way to reset things
without having to unload the driver.

Change-ID: I353f688236249a666a90ba3e7233e0ed8c1a04e9
Signed-off-by: Shannon Nelson <shannon.nelson@intel.com>
Tested-by: Jim Young <jamesx.m.young@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
index fcd815d..25242f5 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
@@ -1393,6 +1393,9 @@ static int i40e_eeprom_test(struct net_device *netdev, u64 *data)
 	netif_info(pf, hw, netdev, "eeprom test\n");
 	*data = i40e_diag_eeprom_test(&pf->hw);
 
+	/* forcebly clear the NVM Update state machine */
+	pf->hw.nvmupd_state = I40E_NVMUPD_STATE_INIT;
+
 	return *data;
 }
 
-- 
1.9.3

^ permalink raw reply related

* [net-next v2 00/13][pull request] Intel Wired LAN Driver Updates 2014-12-09
From: Jeff Kirsher @ 2014-12-09 21:26 UTC (permalink / raw)
  To: davem; +Cc: Jeff Kirsher, netdev, nhorman, sassmann, jogreene

This series contains updates to i40e and i40evf.

Jeff (me) provides a single patch to convert a macro to a static inline
function based on feedback from Joe Perches on a previous patch.

Shannon provides the remaining twelve patches against i40e.  Almost all
of Shannon's patches cleanup/fix NVM issues varying in range from
adding more detail to debug messages, to removing dead code, to fixing
NVM state transitions after an error.  Change the handy decoder interface
for admin queue return code to help catch and properly report the condition
as a useful errno rather than returning a misleading '0'.  Added a range
check to avoid any possible array index-out-of-bound issues.

v2:
 - fixed up patch 05 in the series to use the ARRAY_SIZE() macro as suggested
   by Sergei Shtylyov
 - fix up patch 13 to remove unnecessary parens in the return statement
   as suggested by Sergei Shtylyov

The following are changes since commit b2abeeddad3844072d63f27602b581d9c4adc134:
  net: ethernet: rocker: Add dependency to CONFIG_BRIDGE in Kconfig
and are available in the git repository at:
  git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-next master

Jeff Kirsher (1):
  i40e/i40evf: Convert macro to static inline

Shannon Nelson (12):
  i40e: clear NVM update state on ethtool test
  i40e: better error messages for NVM update issues
  i40e: let firmware catch the NVM busy error
  i40e: rework debug messages for NVM update
  i40e: add range check to i40e_aq_rc_to_posix
  i40e: init NVM update state on adminq init
  i40e: remove unused nvm_semaphore_wait
  i40e: set max limit for access polling
  i40e: fix up NVM update sm error handling
  i40e: poll on NVM semaphore only if not other error
  i40e: check for AQ timeout in aq_rc decode
  i40e: add to NVM update debug message

 drivers/net/ethernet/intel/i40e/i40e_adminq.c   |  13 +-
 drivers/net/ethernet/intel/i40e/i40e_adminq.h   |  10 +-
 drivers/net/ethernet/intel/i40e/i40e_ethtool.c  |  55 ++++---
 drivers/net/ethernet/intel/i40e/i40e_nvm.c      | 198 ++++++++++++++++--------
 drivers/net/ethernet/intel/i40e/i40e_type.h     |   8 +-
 drivers/net/ethernet/intel/i40evf/i40e_adminq.c |   6 -
 drivers/net/ethernet/intel/i40evf/i40e_adminq.h |  10 +-
 drivers/net/ethernet/intel/i40evf/i40e_type.h   |   8 +-
 8 files changed, 197 insertions(+), 111 deletions(-)

-- 
1.9.3

^ permalink raw reply


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