Commit a39f165d authored by Piotr Kwapulinski's avatar Piotr Kwapulinski Committed by Jeff Kirsher
Browse files

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: default avatarPiotr Kwapulinski <piotr.kwapulinski@intel.com>
Tested-by: default avatarAndrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent 541d9731
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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;

+60 −7
Original line number Diff line number Diff line
@@ -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);

	err = i40e_set_mac_type(hw);
	if (err) {
			dev_info(&pdev->dev, "Initial pf_reset failed: %d\n", err);
		dev_warn(&pdev->dev, "unidentified MAC or BLANK NVM: %d\n",
			 err);
		goto err_pf_reset;
	}
		pf->pfr_count++;

	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;
+2 −0
Original line number Diff line number Diff line
@@ -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)