Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4eb3f768 authored by Shannon Nelson's avatar Shannon Nelson Committed by Jeff Kirsher
Browse files

i40e: eeprom integrity check on load and empr



The driver needs to verify the eeprom checksum and firmware crc status bits,
and shutdown the driver if they fail. This code stops the processing of traffic,
but doesn't kill the PF netdev so that the NVMUpdate process should still have a
chance at fixing the image. The eeprom is checked on driver load and after an
EMP reset, the latter of which should be generated after an NVMUpdate.

Change-ID: I34deef21d2e16bf5a43c603cf8af27e6a29dc9d2
Signed-off-by: default avatarShannon Nelson <shannon.nelson@intel.com>
Signed-off-by: default avatarCatherine Sullivan <catherine.sullivan@intel.com>
Tested-by: default avatarKavindya Deegala <kavindya.s.deegala@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent 90e04070
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -136,6 +136,7 @@ enum i40e_state_t {
	__I40E_EMP_RESET_REQUESTED,
	__I40E_FILTER_OVERFLOW_PROMISC,
	__I40E_SUSPENDED,
	__I40E_BAD_EEPROM,
};

enum i40e_interrupt_policy {
+44 −6
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@

/* Local includes */
#include "i40e.h"
#include "i40e_diag.h"
#ifdef CONFIG_I40E_VXLAN
#include <net/vxlan.h>
#endif
@@ -2877,12 +2878,14 @@ static irqreturn_t i40e_intr(int irq, void *data)
		val = rd32(hw, I40E_GLGEN_RSTAT);
		val = (val & I40E_GLGEN_RSTAT_RESET_TYPE_MASK)
		       >> I40E_GLGEN_RSTAT_RESET_TYPE_SHIFT;
		if (val == I40E_RESET_CORER)
		if (val == I40E_RESET_CORER) {
			pf->corer_count++;
		else if (val == I40E_RESET_GLOBR)
		} else if (val == I40E_RESET_GLOBR) {
			pf->globr_count++;
		else if (val == I40E_RESET_EMPR)
		} else if (val == I40E_RESET_EMPR) {
			pf->empr_count++;
			set_bit(__I40E_EMP_RESET_REQUESTED, &pf->state);
		}
	}

	if (icr0 & I40E_PFINT_ICR0_HMC_ERR_MASK) {
@@ -4257,8 +4260,9 @@ static int i40e_open(struct net_device *netdev)
	struct i40e_pf *pf = vsi->back;
	int err;

	/* disallow open during test */
	if (test_bit(__I40E_TESTING, &pf->state))
	/* disallow open during test or if eeprom is broken */
	if (test_bit(__I40E_TESTING, &pf->state) ||
	    test_bit(__I40E_BAD_EEPROM, &pf->state))
		return -EBUSY;

	netif_carrier_off(netdev);
@@ -5077,6 +5081,31 @@ static void i40e_clean_adminq_subtask(struct i40e_pf *pf)
	kfree(event.msg_buf);
}

/**
 * i40e_verify_eeprom - make sure eeprom is good to use
 * @pf: board private structure
 **/
static void i40e_verify_eeprom(struct i40e_pf *pf)
{
	int err;

	err = i40e_diag_eeprom_test(&pf->hw);
	if (err) {
		/* retry in case of garbage read */
		err = i40e_diag_eeprom_test(&pf->hw);
		if (err) {
			dev_info(&pf->pdev->dev, "eeprom check failed (%d), Tx/Rx traffic disabled\n",
				 err);
			set_bit(__I40E_BAD_EEPROM, &pf->state);
		}
	}

	if (!err && test_bit(__I40E_BAD_EEPROM, &pf->state)) {
		dev_info(&pf->pdev->dev, "eeprom check passed, Tx/Rx traffic enabled\n");
		clear_bit(__I40E_BAD_EEPROM, &pf->state);
	}
}

/**
 * i40e_reconstitute_veb - rebuild the VEB and anything connected to it
 * @veb: pointer to the VEB instance
@@ -5386,6 +5415,12 @@ static void i40e_reset_and_rebuild(struct i40e_pf *pf, bool reinit)
		goto end_core_reset;
	}

	/* re-verify the eeprom if we just had an EMP reset */
	if (test_bit(__I40E_EMP_RESET_REQUESTED, &pf->state)) {
		clear_bit(__I40E_EMP_RESET_REQUESTED, &pf->state);
		i40e_verify_eeprom(pf);
	}

	ret = i40e_get_capabilities(pf);
	if (ret) {
		dev_info(&pf->pdev->dev, "i40e_get_capabilities failed, %d\n",
@@ -8157,6 +8192,8 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
		goto err_pf_reset;
	}

	i40e_verify_eeprom(pf);

	i40e_clear_pxe_mode(hw);
	err = i40e_get_capabilities(pf);
	if (err)
@@ -8258,7 +8295,8 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)

	/* prep for VF support */
	if ((pf->flags & I40E_FLAG_SRIOV_ENABLED) &&
	    (pf->flags & I40E_FLAG_MSIX_ENABLED)) {
	    (pf->flags & I40E_FLAG_MSIX_ENABLED) &&
	    !test_bit(__I40E_BAD_EEPROM, &pf->state)) {
		u32 val;

		/* disable link interrupts for VFs */