i40e: allow reset in recovery mode
Driver waits after issuing a reset. When a reset takes too long a driver gives up. Implemented by invoking PF reset in a loop. After defined number of unsuccessful PF reset trials it returns error. Without this patch PF reset fails when NIC is in recovery mode. So make i40e_set_mac_type() public. i40e driver requires i40e_set_mac_type() to be public. It is required for recovery mode handling. Without this patch recovery mode could not be detected in i40e_probe(). Signed-off-by: Piotr Kwapulinski <piotr.kwapulinski@intel.com> Tested-by: Andrew Bowers <andrewx.bowers@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
parent
541d97310a
commit
a39f165db5
|
@ -13,7 +13,7 @@
|
|||
* This function sets the mac type of the adapter based on the
|
||||
* vendor ID and device ID stored in the hw structure.
|
||||
**/
|
||||
static i40e_status i40e_set_mac_type(struct i40e_hw *hw)
|
||||
i40e_status i40e_set_mac_type(struct i40e_hw *hw)
|
||||
{
|
||||
i40e_status status = 0;
|
||||
|
||||
|
|
|
@ -14564,6 +14564,51 @@ static bool i40e_check_recovery_mode(struct i40e_pf *pf)
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* i40e_pf_loop_reset - perform reset in a loop.
|
||||
* @pf: board private structure
|
||||
*
|
||||
* This function is useful when a NIC is about to enter recovery mode.
|
||||
* When a NIC's internal data structures are corrupted the NIC's
|
||||
* firmware is going to enter recovery mode.
|
||||
* Right after a POR it takes about 7 minutes for firmware to enter
|
||||
* recovery mode. Until that time a NIC is in some kind of intermediate
|
||||
* state. After that time period the NIC almost surely enters
|
||||
* recovery mode. The only way for a driver to detect intermediate
|
||||
* state is to issue a series of pf-resets and check a return value.
|
||||
* If a PF reset returns success then the firmware could be in recovery
|
||||
* mode so the caller of this code needs to check for recovery mode
|
||||
* if this function returns success. There is a little chance that
|
||||
* firmware will hang in intermediate state forever.
|
||||
* Since waiting 7 minutes is quite a lot of time this function waits
|
||||
* 10 seconds and then gives up by returning an error.
|
||||
*
|
||||
* Return 0 on success, negative on failure.
|
||||
**/
|
||||
static i40e_status i40e_pf_loop_reset(struct i40e_pf *pf)
|
||||
{
|
||||
const unsigned short MAX_CNT = 1000;
|
||||
const unsigned short MSECS = 10;
|
||||
struct i40e_hw *hw = &pf->hw;
|
||||
i40e_status ret;
|
||||
int cnt;
|
||||
|
||||
for (cnt = 0; cnt < MAX_CNT; ++cnt) {
|
||||
ret = i40e_pf_reset(hw);
|
||||
if (!ret)
|
||||
break;
|
||||
msleep(MSECS);
|
||||
}
|
||||
|
||||
if (cnt == MAX_CNT) {
|
||||
dev_info(&pf->pdev->dev, "PF reset failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
pf->pfr_count++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* i40e_init_recovery_mode - initialize subsystems needed in recovery mode
|
||||
* @pf: board private structure
|
||||
|
@ -14792,14 +14837,22 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
|||
|
||||
/* Reset here to make sure all is clean and to define PF 'n' */
|
||||
i40e_clear_hw(hw);
|
||||
if (!i40e_check_recovery_mode(pf)) {
|
||||
err = i40e_pf_reset(hw);
|
||||
if (err) {
|
||||
dev_info(&pdev->dev, "Initial pf_reset failed: %d\n", err);
|
||||
goto err_pf_reset;
|
||||
}
|
||||
pf->pfr_count++;
|
||||
|
||||
err = i40e_set_mac_type(hw);
|
||||
if (err) {
|
||||
dev_warn(&pdev->dev, "unidentified MAC or BLANK NVM: %d\n",
|
||||
err);
|
||||
goto err_pf_reset;
|
||||
}
|
||||
|
||||
err = i40e_pf_loop_reset(pf);
|
||||
if (err) {
|
||||
dev_info(&pdev->dev, "Initial pf_reset failed: %d\n", err);
|
||||
goto err_pf_reset;
|
||||
}
|
||||
|
||||
i40e_check_recovery_mode(pf);
|
||||
|
||||
hw->aq.num_arq_entries = I40E_AQ_LEN;
|
||||
hw->aq.num_asq_entries = I40E_AQ_LEN;
|
||||
hw->aq.arq_buf_size = I40E_MAX_AQ_BUF_SIZE;
|
||||
|
|
|
@ -326,6 +326,8 @@ void i40e_nvmupd_check_wait_event(struct i40e_hw *hw, u16 opcode,
|
|||
void i40e_nvmupd_clear_wait_state(struct i40e_hw *hw);
|
||||
void i40e_set_pci_config_data(struct i40e_hw *hw, u16 link_status);
|
||||
|
||||
i40e_status i40e_set_mac_type(struct i40e_hw *hw);
|
||||
|
||||
extern struct i40e_rx_ptype_decoded i40e_ptype_lookup[];
|
||||
|
||||
static inline struct i40e_rx_ptype_decoded decode_rx_desc_ptype(u8 ptype)
|
||||
|
|
Loading…
Reference in New Issue