[dpdk-dev,3/3,v7] i40e: Add global reset support for i40e

Message ID 1458895321-21896-4-git-send-email-zhe.tao@intel.com (mailing list archive)
State Changes Requested, archived
Delegated to: Bruce Richardson
Headers

Commit Message

Zhe Tao March 25, 2016, 8:42 a.m. UTC
  Add global reset support in i40e.
Sometimes the PF reset will fail, and the PF software reset cannot ensure
all the status and components are reset. So added the global reset to fix
this issue.
The essential difference for the new global reset and PF reset is that the
PF Reset doesn't clear the packet buffers, doesn't reset the PE
firmware, and doesn't bother the other PFs on the chip.

Signed-off-by: Zhe Tao <zhe.tao@intel.com>
---
 drivers/net/i40e/i40e_ethdev.c | 35 ++++++++++++++++++++++++++++++++++-
 drivers/net/i40e/i40e_ethdev.h | 30 ++++++++++++++++++++++++++++++
 2 files changed, 64 insertions(+), 1 deletion(-)
  

Comments

Jingjing Wu April 20, 2016, 10:15 a.m. UTC | #1
Hi, zhe

Beside hein's global reset concern. I have another comment:
Do you copy the following codes from i40e kernel driver? Have
You done the Protext IP scan for it?
Just let you know that linux kernel is GPL liscense, we can
Not just copy code from it without any modification.

Thanks
Jingjing

> +
> +/**
> + * i40e_do_reset - Start a PF or Core Reset sequence
> + * @pf: board private structure
> + * @reset_flags: which reset is requested
> + *
> + * The essential difference in resets is that the PF Reset
> + * doesn't clear the packet buffers, doesn't reset the PE
> + * firmware, and doesn't bother the other PFs on the chip.
> + **/
> +static void i40e_do_reset(struct i40e_hw *hw, u32 reset_flags) {
> +	u32 val;
> +
> +	/* do the biggest reset indicated */
> +	if (reset_flags & BIT_ULL(__I40E_GLOBAL_RESET_REQUESTED)) {
> +		/* Request a Global Reset
> +		 *
> +		 * This will start the chip's countdown to the actual full
> +		 * chip reset event, and a warning interrupt to be sent
> +		 * to all PFs, including the requestor.  Our handler
> +		 * for the warning interrupt will deal with the shutdown
> +		 * and recovery of the switch setup.
> +		 */
> +		PMD_INIT_LOG(NOTICE, "GlobalR requested\n");
> +		val = rd32(hw, I40E_GLGEN_RTRIG);
> +		val |= I40E_GLGEN_RTRIG_GLOBR_MASK;
> +		wr32(hw, I40E_GLGEN_RTRIG, val);
> +	}
> +	/* other reset operations are not supported now */ }
> diff --git a/drivers/net/i40e/i40e_ethdev.h
> b/drivers/net/i40e/i40e_ethdev.h index 09fb6e2..f2a2fcc 100644
> --- a/drivers/net/i40e/i40e_ethdev.h
> +++ b/drivers/net/i40e/i40e_ethdev.h
> @@ -108,6 +108,36 @@ enum i40e_flxpld_layer_idx {
>  	I40E_FLXPLD_L4_IDX    = 2,
>  	I40E_MAX_FLXPLD_LAYER = 3,
>  };
> +
> +/* driver state flags */
> +enum i40e_state_t {
> +	__I40E_TESTING,
> +	__I40E_CONFIG_BUSY,
> +	__I40E_CONFIG_DONE,
> +	__I40E_DOWN,
> +	__I40E_NEEDS_RESTART,
> +	__I40E_SERVICE_SCHED,
> +	__I40E_ADMINQ_EVENT_PENDING,
> +	__I40E_MDD_EVENT_PENDING,
> +	__I40E_VFLR_EVENT_PENDING,
> +	__I40E_RESET_RECOVERY_PENDING,
> +	__I40E_RESET_INTR_RECEIVED,
> +	__I40E_REINIT_REQUESTED,
> +	__I40E_PF_RESET_REQUESTED,
> +	__I40E_CORE_RESET_REQUESTED,
> +	__I40E_GLOBAL_RESET_REQUESTED,
> +	__I40E_EMP_RESET_REQUESTED,
> +	__I40E_EMP_RESET_INTR_RECEIVED,
> +	__I40E_FILTER_OVERFLOW_PROMISC,
> +	__I40E_SUSPENDED,
> +	__I40E_BAD_EEPROM,
> +	__I40E_DEBUG_MODE,
> +	__I40E_DOWN_REQUESTED,
> +	__I40E_FD_FLUSH_REQUESTED,
> +	__I40E_RESET_FAILED,
> +	__I40E_PORT_TX_SUSPENDED,
> +	__I40E_VF_DISABLE,
> +};
>  #define I40E_MAX_FLXPLD_FIED        3  /* max number of flex payload fields
> */
>  #define I40E_FDIR_BITMASK_NUM_WORD  2  /* max number of bitmask
> words */  #define I40E_FDIR_MAX_FLEXWORD_NUM  8  /* max number of
> flexpayload words */
> --
> 2.1.4
  

Patch

diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 87801d3..8336321 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -437,6 +437,8 @@  static int i40e_get_eeprom(struct rte_eth_dev *dev,
 static void i40e_set_default_mac_addr(struct rte_eth_dev *dev,
 				      struct ether_addr *mac_addr);
 
+static void i40e_do_reset(struct i40e_hw *hw, u32 reset_flags);
+
 static const struct rte_pci_id pci_id_i40e_map[] = {
 #define RTE_PCI_DEV_ID_DECL_I40E(vend, dev) {RTE_PCI_DEVICE(vend, dev)},
 #include "rte_pci_dev_ids.h"
@@ -836,7 +838,7 @@  eth_i40e_dev_init(struct rte_eth_dev *dev)
 	ret = i40e_pf_reset(hw);
 	if (ret) {
 		PMD_INIT_LOG(ERR, "Failed to reset pf: %d", ret);
-		return ret;
+		i40e_do_reset(hw, BIT(__I40E_GLOBAL_RESET_REQUESTED));
 	}
 
 	/* Initialize the shared code (base driver) */
@@ -9117,3 +9119,34 @@  static void i40e_set_default_mac_addr(struct rte_eth_dev *dev,
 	/* Flags: 0x3 updates port address */
 	i40e_aq_mac_address_write(hw, 0x3, mac_addr->addr_bytes, NULL);
 }
+
+/**
+ * i40e_do_reset - Start a PF or Core Reset sequence
+ * @pf: board private structure
+ * @reset_flags: which reset is requested
+ *
+ * The essential difference in resets is that the PF Reset
+ * doesn't clear the packet buffers, doesn't reset the PE
+ * firmware, and doesn't bother the other PFs on the chip.
+ **/
+static void i40e_do_reset(struct i40e_hw *hw, u32 reset_flags)
+{
+	u32 val;
+
+	/* do the biggest reset indicated */
+	if (reset_flags & BIT_ULL(__I40E_GLOBAL_RESET_REQUESTED)) {
+		/* Request a Global Reset
+		 *
+		 * This will start the chip's countdown to the actual full
+		 * chip reset event, and a warning interrupt to be sent
+		 * to all PFs, including the requestor.  Our handler
+		 * for the warning interrupt will deal with the shutdown
+		 * and recovery of the switch setup.
+		 */
+		PMD_INIT_LOG(NOTICE, "GlobalR requested\n");
+		val = rd32(hw, I40E_GLGEN_RTRIG);
+		val |= I40E_GLGEN_RTRIG_GLOBR_MASK;
+		wr32(hw, I40E_GLGEN_RTRIG, val);
+	}
+	/* other reset operations are not supported now */
+}
diff --git a/drivers/net/i40e/i40e_ethdev.h b/drivers/net/i40e/i40e_ethdev.h
index 09fb6e2..f2a2fcc 100644
--- a/drivers/net/i40e/i40e_ethdev.h
+++ b/drivers/net/i40e/i40e_ethdev.h
@@ -108,6 +108,36 @@  enum i40e_flxpld_layer_idx {
 	I40E_FLXPLD_L4_IDX    = 2,
 	I40E_MAX_FLXPLD_LAYER = 3,
 };
+
+/* driver state flags */
+enum i40e_state_t {
+	__I40E_TESTING,
+	__I40E_CONFIG_BUSY,
+	__I40E_CONFIG_DONE,
+	__I40E_DOWN,
+	__I40E_NEEDS_RESTART,
+	__I40E_SERVICE_SCHED,
+	__I40E_ADMINQ_EVENT_PENDING,
+	__I40E_MDD_EVENT_PENDING,
+	__I40E_VFLR_EVENT_PENDING,
+	__I40E_RESET_RECOVERY_PENDING,
+	__I40E_RESET_INTR_RECEIVED,
+	__I40E_REINIT_REQUESTED,
+	__I40E_PF_RESET_REQUESTED,
+	__I40E_CORE_RESET_REQUESTED,
+	__I40E_GLOBAL_RESET_REQUESTED,
+	__I40E_EMP_RESET_REQUESTED,
+	__I40E_EMP_RESET_INTR_RECEIVED,
+	__I40E_FILTER_OVERFLOW_PROMISC,
+	__I40E_SUSPENDED,
+	__I40E_BAD_EEPROM,
+	__I40E_DEBUG_MODE,
+	__I40E_DOWN_REQUESTED,
+	__I40E_FD_FLUSH_REQUESTED,
+	__I40E_RESET_FAILED,
+	__I40E_PORT_TX_SUSPENDED,
+	__I40E_VF_DISABLE,
+};
 #define I40E_MAX_FLXPLD_FIED        3  /* max number of flex payload fields */
 #define I40E_FDIR_BITMASK_NUM_WORD  2  /* max number of bitmask words */
 #define I40E_FDIR_MAX_FLEXWORD_NUM  8  /* max number of flexpayload words */