Skip to content

Commit

Permalink
ixgbe: firmware recovery mode
Browse files Browse the repository at this point in the history
Add check for FW NVM recovery mode during driver initialization and
service task. If in recovery mode, log message and unregister device

Signed-off-by: Sebastian Basierski <sebastianx.basierski@intel.com>
Tested-by: Don Buchholz <donald.buchholz@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
  • Loading branch information
Sebastian Basierski authored and Jeff Kirsher committed Aug 28, 2018
1 parent 050cdc6 commit 59dd45d
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 0 deletions.
11 changes: 11 additions & 0 deletions drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -3484,6 +3484,17 @@ void ixgbe_set_vlan_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf)
IXGBE_WRITE_REG(hw, IXGBE_PFVFSPOOF(vf_target_reg), pfvfspoof);
}

/**
* ixgbe_fw_recovery_mode - Check if in FW NVM recovery mode
* @hw: pointer to hardware structure
*/
bool ixgbe_fw_recovery_mode(struct ixgbe_hw *hw)
{
if (hw->mac.ops.fw_recovery_mode)
return hw->mac.ops.fw_recovery_mode(hw);
return false;
}

/**
* ixgbe_get_device_caps_generic - Get additional device capabilities
* @hw: pointer to hardware structure
Expand Down
41 changes: 41 additions & 0 deletions drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -7774,6 +7774,33 @@ static void ixgbe_reset_subtask(struct ixgbe_adapter *adapter)
rtnl_unlock();
}

/**
* ixgbe_check_fw_error - Check firmware for errors
* @adapter: the adapter private structure
*
* Check firmware errors in register FWSM
*/
static bool ixgbe_check_fw_error(struct ixgbe_adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
u32 fwsm;

/* read fwsm.ext_err_ind register and log errors */
fwsm = IXGBE_READ_REG(hw, IXGBE_FWSM(hw));

if (fwsm & IXGBE_FWSM_EXT_ERR_IND_MASK ||
!(fwsm & IXGBE_FWSM_FW_VAL_BIT))
e_dev_warn("Warning firmware error detected FWSM: 0x%08X\n",
fwsm);

if (hw->mac.ops.fw_recovery_mode && hw->mac.ops.fw_recovery_mode(hw)) {
e_dev_err("Firmware recovery mode detected. Limiting functionality. Refer to the Intel(R) Ethernet Adapters and Devices User Guide for details on firmware recovery mode.\n");
return true;
}

return false;
}

/**
* ixgbe_service_task - manages and runs subtasks
* @work: pointer to work_struct containing our data
Expand All @@ -7792,6 +7819,15 @@ static void ixgbe_service_task(struct work_struct *work)
ixgbe_service_event_complete(adapter);
return;
}
if (ixgbe_check_fw_error(adapter)) {
if (!test_bit(__IXGBE_DOWN, &adapter->state)) {
rtnl_lock();
unregister_netdev(adapter->netdev);
rtnl_unlock();
}
ixgbe_service_event_complete(adapter);
return;
}
if (adapter->flags2 & IXGBE_FLAG2_UDP_TUN_REREG_NEEDED) {
rtnl_lock();
adapter->flags2 &= ~IXGBE_FLAG2_UDP_TUN_REREG_NEEDED;
Expand Down Expand Up @@ -10716,6 +10752,11 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (adapter->flags2 & IXGBE_FLAG2_RSC_ENABLED)
netdev->features |= NETIF_F_LRO;

if (ixgbe_check_fw_error(adapter)) {
err = -EIO;
goto err_sw_init;
}

/* make sure the EEPROM is good */
if (hw->eeprom.ops.validate_checksum(hw, NULL) < 0) {
e_dev_err("The EEPROM Checksum Is Not Valid\n");
Expand Down
4 changes: 4 additions & 0 deletions drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -924,6 +924,9 @@ struct ixgbe_nvm_version {
/* Firmware Semaphore Register */
#define IXGBE_FWSM_MODE_MASK 0xE
#define IXGBE_FWSM_FW_MODE_PT 0x4
#define IXGBE_FWSM_FW_NVM_RECOVERY_MODE BIT(5)
#define IXGBE_FWSM_EXT_ERR_IND_MASK 0x01F80000
#define IXGBE_FWSM_FW_VAL_BIT BIT(15)

/* ARC Subsystem registers */
#define IXGBE_HICR 0x15F00
Expand Down Expand Up @@ -3461,6 +3464,7 @@ struct ixgbe_mac_operations {
const char *);
s32 (*get_thermal_sensor_data)(struct ixgbe_hw *);
s32 (*init_thermal_sensor_thresh)(struct ixgbe_hw *hw);
bool (*fw_recovery_mode)(struct ixgbe_hw *hw);
void (*disable_rx)(struct ixgbe_hw *hw);
void (*enable_rx)(struct ixgbe_hw *hw);
void (*set_source_address_pruning)(struct ixgbe_hw *, bool,
Expand Down
15 changes: 15 additions & 0 deletions drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c
Original file line number Diff line number Diff line change
Expand Up @@ -1247,6 +1247,20 @@ static s32 ixgbe_get_bus_info_X550em(struct ixgbe_hw *hw)
return 0;
}

/**
* ixgbe_fw_recovery_mode - Check FW NVM recovery mode
* @hw: pointer t hardware structure
*
* Returns true if in FW NVM recovery mode.
*/
static bool ixgbe_fw_recovery_mode_X550(struct ixgbe_hw *hw)
{
u32 fwsm;

fwsm = IXGBE_READ_REG(hw, IXGBE_FWSM(hw));
return !!(fwsm & IXGBE_FWSM_FW_NVM_RECOVERY_MODE);
}

/** ixgbe_disable_rx_x550 - Disable RX unit
*
* Enables the Rx DMA unit for x550
Expand Down Expand Up @@ -3816,6 +3830,7 @@ static s32 ixgbe_write_phy_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr,
.enable_rx_buff = &ixgbe_enable_rx_buff_generic, \
.get_thermal_sensor_data = NULL, \
.init_thermal_sensor_thresh = NULL, \
.fw_recovery_mode = &ixgbe_fw_recovery_mode_X550, \
.enable_rx = &ixgbe_enable_rx_generic, \
.disable_rx = &ixgbe_disable_rx_x550, \

Expand Down

0 comments on commit 59dd45d

Please sign in to comment.