Commit 5d6201e1 authored by David S. Miller's avatar David S. Miller

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-next

Jeff Kirsher says:

====================
Intel Wired LAN Driver Updates 2014-12-09

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
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 602de7ea 4bd145be
...@@ -617,7 +617,8 @@ i40e_status i40e_init_adminq(struct i40e_hw *hw) ...@@ -617,7 +617,8 @@ i40e_status i40e_init_adminq(struct i40e_hw *hw)
/* pre-emptive resource lock release */ /* pre-emptive resource lock release */
i40e_aq_release_resource(hw, I40E_NVM_RESOURCE_ID, 0, NULL); i40e_aq_release_resource(hw, I40E_NVM_RESOURCE_ID, 0, NULL);
hw->aq.nvm_busy = false; hw->aq.nvm_release_on_done = false;
hw->nvmupd_state = I40E_NVMUPD_STATE_INIT;
ret_code = i40e_aq_set_hmc_resource_profile(hw, ret_code = i40e_aq_set_hmc_resource_profile(hw,
I40E_HMC_PROFILE_DEFAULT, I40E_HMC_PROFILE_DEFAULT,
...@@ -754,12 +755,6 @@ i40e_status i40e_asq_send_command(struct i40e_hw *hw, ...@@ -754,12 +755,6 @@ i40e_status i40e_asq_send_command(struct i40e_hw *hw,
goto asq_send_command_exit; 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); details = I40E_ADMINQ_DETAILS(hw->aq.asq, hw->aq.asq.next_to_use);
if (cmd_details) { if (cmd_details) {
*details = *cmd_details; *details = *cmd_details;
...@@ -901,9 +896,6 @@ i40e_status i40e_asq_send_command(struct i40e_hw *hw, ...@@ -901,9 +896,6 @@ i40e_status i40e_asq_send_command(struct i40e_hw *hw,
status = I40E_ERR_ADMIN_QUEUE_TIMEOUT; status = I40E_ERR_ADMIN_QUEUE_TIMEOUT;
} }
if (!status && i40e_is_nvm_update_op(desc))
hw->aq.nvm_busy = true;
asq_send_command_error: asq_send_command_error:
mutex_unlock(&hw->aq.asq_mutex); mutex_unlock(&hw->aq.asq_mutex);
asq_send_command_exit: asq_send_command_exit:
...@@ -1016,7 +1008,6 @@ i40e_status i40e_clean_arq_element(struct i40e_hw *hw, ...@@ -1016,7 +1008,6 @@ i40e_status i40e_clean_arq_element(struct i40e_hw *hw,
mutex_unlock(&hw->aq.arq_mutex); mutex_unlock(&hw->aq.arq_mutex);
if (i40e_is_nvm_update_op(&e->desc)) { if (i40e_is_nvm_update_op(&e->desc)) {
hw->aq.nvm_busy = false;
if (hw->aq.nvm_release_on_done) { if (hw->aq.nvm_release_on_done) {
i40e_release_nvm(hw); i40e_release_nvm(hw);
hw->aq.nvm_release_on_done = false; hw->aq.nvm_release_on_done = false;
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#define _I40E_ADMINQ_H_ #define _I40E_ADMINQ_H_
#include "i40e_osdep.h" #include "i40e_osdep.h"
#include "i40e_status.h"
#include "i40e_adminq_cmd.h" #include "i40e_adminq_cmd.h"
#define I40E_ADMINQ_DESC(R, i) \ #define I40E_ADMINQ_DESC(R, i) \
...@@ -94,7 +95,6 @@ struct i40e_adminq_info { ...@@ -94,7 +95,6 @@ struct i40e_adminq_info {
u16 fw_min_ver; /* firmware minor version */ u16 fw_min_ver; /* firmware minor version */
u16 api_maj_ver; /* api major version */ u16 api_maj_ver; /* api major version */
u16 api_min_ver; /* api minor version */ u16 api_min_ver; /* api minor version */
bool nvm_busy;
bool nvm_release_on_done; bool nvm_release_on_done;
struct mutex asq_mutex; /* Send queue lock */ struct mutex asq_mutex; /* Send queue lock */
...@@ -109,7 +109,7 @@ struct i40e_adminq_info { ...@@ -109,7 +109,7 @@ struct i40e_adminq_info {
* i40e_aq_rc_to_posix - convert errors to user-land codes * i40e_aq_rc_to_posix - convert errors to user-land codes
* aq_rc: AdminQ error code to convert * 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[] = { int aq_to_posix[] = {
0, /* I40E_AQ_RC_OK */ 0, /* I40E_AQ_RC_OK */
...@@ -137,6 +137,12 @@ static inline int i40e_aq_rc_to_posix(u16 aq_rc) ...@@ -137,6 +137,12 @@ static inline int i40e_aq_rc_to_posix(u16 aq_rc)
-EFBIG, /* I40E_AQ_RC_EFBIG */ -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]; return aq_to_posix[aq_rc];
} }
......
...@@ -822,7 +822,7 @@ static int i40e_get_eeprom(struct net_device *netdev, ...@@ -822,7 +822,7 @@ static int i40e_get_eeprom(struct net_device *netdev,
struct i40e_netdev_priv *np = netdev_priv(netdev); struct i40e_netdev_priv *np = netdev_priv(netdev);
struct i40e_hw *hw = &np->vsi->back->hw; struct i40e_hw *hw = &np->vsi->back->hw;
struct i40e_pf *pf = np->vsi->back; struct i40e_pf *pf = np->vsi->back;
int ret_val = 0, len; int ret_val = 0, len, offset;
u8 *eeprom_buff; u8 *eeprom_buff;
u16 i, sectors; u16 i, sectors;
bool last; bool last;
...@@ -835,19 +835,21 @@ static int i40e_get_eeprom(struct net_device *netdev, ...@@ -835,19 +835,21 @@ static int i40e_get_eeprom(struct net_device *netdev,
/* check for NVMUpdate access method */ /* check for NVMUpdate access method */
magic = hw->vendor_id | (hw->device_id << 16); magic = hw->vendor_id | (hw->device_id << 16);
if (eeprom->magic && eeprom->magic != magic) { if (eeprom->magic && eeprom->magic != magic) {
struct i40e_nvm_access *cmd;
int errno; int errno;
/* make sure it is the right magic for NVMUpdate */ /* make sure it is the right magic for NVMUpdate */
if ((eeprom->magic >> 16) != hw->device_id) if ((eeprom->magic >> 16) != hw->device_id)
return -EINVAL; return -EINVAL;
ret_val = i40e_nvmupd_command(hw, cmd = (struct i40e_nvm_access *)eeprom;
(struct i40e_nvm_access *)eeprom, ret_val = i40e_nvmupd_command(hw, cmd, bytes, &errno);
bytes, &errno);
if (ret_val) if (ret_val)
dev_info(&pf->pdev->dev, dev_info(&pf->pdev->dev,
"NVMUpdate read failed err=%d status=0x%x\n", "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); ret_val, hw->aq.asq_last_status, errno,
(u8)(cmd->config & I40E_NVM_MOD_PNT_MASK),
cmd->offset, cmd->data_size);
return errno; return errno;
} }
...@@ -876,20 +878,29 @@ static int i40e_get_eeprom(struct net_device *netdev, ...@@ -876,20 +878,29 @@ static int i40e_get_eeprom(struct net_device *netdev,
len = eeprom->len - (I40E_NVM_SECTOR_SIZE * i); len = eeprom->len - (I40E_NVM_SECTOR_SIZE * i);
last = true; last = true;
} }
ret_val = i40e_aq_read_nvm(hw, 0x0, offset = eeprom->offset + (I40E_NVM_SECTOR_SIZE * i),
eeprom->offset + (I40E_NVM_SECTOR_SIZE * i), ret_val = i40e_aq_read_nvm(hw, 0x0, offset, len,
len,
(u8 *)eeprom_buff + (I40E_NVM_SECTOR_SIZE * i), (u8 *)eeprom_buff + (I40E_NVM_SECTOR_SIZE * i),
last, NULL); last, NULL);
if (ret_val) { if (ret_val && hw->aq.asq_last_status == I40E_AQ_RC_EPERM) {
dev_info(&pf->pdev->dev, dev_info(&pf->pdev->dev,
"read NVM failed err=%d status=0x%x\n", "read NVM failed, invalid offset 0x%x\n",
ret_val, hw->aq.asq_last_status); offset);
goto release_nvm; 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); i40e_release_nvm(hw);
memcpy(bytes, (u8 *)eeprom_buff, eeprom->len); memcpy(bytes, (u8 *)eeprom_buff, eeprom->len);
free_buff: free_buff:
...@@ -917,6 +928,7 @@ static int i40e_set_eeprom(struct net_device *netdev, ...@@ -917,6 +928,7 @@ static int i40e_set_eeprom(struct net_device *netdev,
struct i40e_netdev_priv *np = netdev_priv(netdev); struct i40e_netdev_priv *np = netdev_priv(netdev);
struct i40e_hw *hw = &np->vsi->back->hw; struct i40e_hw *hw = &np->vsi->back->hw;
struct i40e_pf *pf = np->vsi->back; struct i40e_pf *pf = np->vsi->back;
struct i40e_nvm_access *cmd;
int ret_val = 0; int ret_val = 0;
int errno; int errno;
u32 magic; u32 magic;
...@@ -934,12 +946,14 @@ static int i40e_set_eeprom(struct net_device *netdev, ...@@ -934,12 +946,14 @@ static int i40e_set_eeprom(struct net_device *netdev,
test_bit(__I40E_RESET_INTR_RECEIVED, &pf->state)) test_bit(__I40E_RESET_INTR_RECEIVED, &pf->state))
return -EBUSY; return -EBUSY;
ret_val = i40e_nvmupd_command(hw, (struct i40e_nvm_access *)eeprom, cmd = (struct i40e_nvm_access *)eeprom;
bytes, &errno); ret_val = i40e_nvmupd_command(hw, cmd, bytes, &errno);
if (ret_val) if (ret_val && hw->aq.asq_last_status != I40E_AQ_RC_EBUSY)
dev_info(&pf->pdev->dev, dev_info(&pf->pdev->dev,
"NVMUpdate write failed err=%d status=0x%x\n", "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); ret_val, hw->aq.asq_last_status, errno,
(u8)(cmd->config & I40E_NVM_MOD_PNT_MASK),
cmd->offset, cmd->data_size);
return errno; return errno;
} }
...@@ -1393,6 +1407,9 @@ static int i40e_eeprom_test(struct net_device *netdev, u64 *data) ...@@ -1393,6 +1407,9 @@ static int i40e_eeprom_test(struct net_device *netdev, u64 *data)
netif_info(pf, hw, netdev, "eeprom test\n"); netif_info(pf, hw, netdev, "eeprom test\n");
*data = i40e_diag_eeprom_test(&pf->hw); *data = i40e_diag_eeprom_test(&pf->hw);
/* forcebly clear the NVM Update state machine */
pf->hw.nvmupd_state = I40E_NVMUPD_STATE_INIT;
return *data; return *data;
} }
......
This diff is collapsed.
...@@ -261,8 +261,7 @@ enum i40e_aq_resource_access_type { ...@@ -261,8 +261,7 @@ enum i40e_aq_resource_access_type {
}; };
struct i40e_nvm_info { struct i40e_nvm_info {
u64 hw_semaphore_timeout; /* 2usec global time (GTIME resolution) */ u64 hw_semaphore_timeout; /* usec global time (GTIME resolution) */
u64 hw_semaphore_wait; /* - || - */
u32 timeout; /* [ms] */ u32 timeout; /* [ms] */
u16 sr_size; /* Shadow RAM size in words */ u16 sr_size; /* Shadow RAM size in words */
bool blank_nvm_mode; /* is NVM empty (no FW present)*/ bool blank_nvm_mode; /* is NVM empty (no FW present)*/
...@@ -482,7 +481,10 @@ struct i40e_hw { ...@@ -482,7 +481,10 @@ struct i40e_hw {
u32 debug_mask; 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 { struct i40e_driver_version {
u8 major_version; u8 major_version;
......
...@@ -836,9 +836,6 @@ i40e_status i40evf_asq_send_command(struct i40e_hw *hw, ...@@ -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; 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, i40e_debug(hw, I40E_DEBUG_AQ_MESSAGE,
"AQTX: desc and buffer writeback:\n"); "AQTX: desc and buffer writeback:\n");
i40evf_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc, buff, 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, ...@@ -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, memcpy(e->msg_buf, hw->aq.arq.r.arq_bi[desc_idx].va,
e->msg_len); 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"); 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, i40evf_debug_aq(hw, I40E_DEBUG_AQ_COMMAND, (void *)desc, e->msg_buf,
hw->aq.arq_buf_size); hw->aq.arq_buf_size);
......
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#define _I40E_ADMINQ_H_ #define _I40E_ADMINQ_H_
#include "i40e_osdep.h" #include "i40e_osdep.h"
#include "i40e_status.h"
#include "i40e_adminq_cmd.h" #include "i40e_adminq_cmd.h"
#define I40E_ADMINQ_DESC(R, i) \ #define I40E_ADMINQ_DESC(R, i) \
...@@ -94,7 +95,6 @@ struct i40e_adminq_info { ...@@ -94,7 +95,6 @@ struct i40e_adminq_info {
u16 fw_min_ver; /* firmware minor version */ u16 fw_min_ver; /* firmware minor version */
u16 api_maj_ver; /* api major version */ u16 api_maj_ver; /* api major version */
u16 api_min_ver; /* api minor version */ u16 api_min_ver; /* api minor version */
bool nvm_busy;
bool nvm_release_on_done; bool nvm_release_on_done;
struct mutex asq_mutex; /* Send queue lock */ struct mutex asq_mutex; /* Send queue lock */
...@@ -109,7 +109,7 @@ struct i40e_adminq_info { ...@@ -109,7 +109,7 @@ struct i40e_adminq_info {
* i40e_aq_rc_to_posix - convert errors to user-land codes * i40e_aq_rc_to_posix - convert errors to user-land codes
* aq_rc: AdminQ error code to convert * 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[] = { int aq_to_posix[] = {
0, /* I40E_AQ_RC_OK */ 0, /* I40E_AQ_RC_OK */
...@@ -137,6 +137,12 @@ static inline int i40e_aq_rc_to_posix(u16 aq_rc) ...@@ -137,6 +137,12 @@ static inline int i40e_aq_rc_to_posix(u16 aq_rc)
-EFBIG, /* I40E_AQ_RC_EFBIG */ -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]; return aq_to_posix[aq_rc];
} }
......
...@@ -260,8 +260,7 @@ enum i40e_aq_resource_access_type { ...@@ -260,8 +260,7 @@ enum i40e_aq_resource_access_type {
}; };
struct i40e_nvm_info { struct i40e_nvm_info {
u64 hw_semaphore_timeout; /* 2usec global time (GTIME resolution) */ u64 hw_semaphore_timeout; /* usec global time (GTIME resolution) */
u64 hw_semaphore_wait; /* - || - */
u32 timeout; /* [ms] */ u32 timeout; /* [ms] */
u16 sr_size; /* Shadow RAM size in words */ u16 sr_size; /* Shadow RAM size in words */
bool blank_nvm_mode; /* is NVM empty (no FW present)*/ bool blank_nvm_mode; /* is NVM empty (no FW present)*/
...@@ -476,7 +475,10 @@ struct i40e_hw { ...@@ -476,7 +475,10 @@ struct i40e_hw {
u32 debug_mask; 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 { struct i40e_driver_version {
u8 major_version; u8 major_version;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment