aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/i40e
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/i40e')
-rw-r--r--drivers/net/i40e/base/i40e_adminq.c7
-rw-r--r--drivers/net/i40e/base/i40e_common.c25
-rw-r--r--drivers/net/i40e/base/i40e_lan_hmc.c15
-rw-r--r--drivers/net/i40e/base/i40e_type.h2
-rw-r--r--drivers/net/i40e/i40e_ethdev.c75
-rw-r--r--drivers/net/i40e/i40e_rxtx.c4
6 files changed, 99 insertions, 29 deletions
diff --git a/drivers/net/i40e/base/i40e_adminq.c b/drivers/net/i40e/base/i40e_adminq.c
index e231582c..4d3f938e 100644
--- a/drivers/net/i40e/base/i40e_adminq.c
+++ b/drivers/net/i40e/base/i40e_adminq.c
@@ -126,6 +126,7 @@ enum i40e_status_code i40e_alloc_adminq_arq_ring(struct i40e_hw *hw)
**/
void i40e_free_adminq_asq(struct i40e_hw *hw)
{
+ i40e_free_virt_mem(hw, &hw->aq.asq.cmd_buf);
i40e_free_dma_mem(hw, &hw->aq.asq.desc_buf);
}
@@ -433,7 +434,7 @@ enum i40e_status_code i40e_init_asq(struct i40e_hw *hw)
/* initialize base registers */
ret_code = i40e_config_asq_regs(hw);
if (ret_code != I40E_SUCCESS)
- goto init_adminq_free_rings;
+ goto init_config_regs;
/* success! */
hw->aq.asq.count = hw->aq.num_asq_entries;
@@ -441,6 +442,10 @@ enum i40e_status_code i40e_init_asq(struct i40e_hw *hw)
init_adminq_free_rings:
i40e_free_adminq_asq(hw);
+ return ret_code;
+
+init_config_regs:
+ i40e_free_asq_bufs(hw);
init_adminq_exit:
return ret_code;
diff --git a/drivers/net/i40e/base/i40e_common.c b/drivers/net/i40e/base/i40e_common.c
index de60e2a1..8ba75c73 100644
--- a/drivers/net/i40e/base/i40e_common.c
+++ b/drivers/net/i40e/base/i40e_common.c
@@ -1348,7 +1348,7 @@ enum i40e_status_code i40e_pf_reset(struct i40e_hw *hw)
I40E_GLGEN_RSTCTL_GRSTDEL_MASK) >>
I40E_GLGEN_RSTCTL_GRSTDEL_SHIFT;
- grst_del = grst_del * 20;
+ grst_del = min(grst_del * 20, 160U);
for (cnt = 0; cnt < grst_del; cnt++) {
reg = rd32(hw, I40E_GLGEN_RSTAT);
@@ -3574,9 +3574,10 @@ STATIC void i40e_parse_discover_capabilities(struct i40e_hw *hw, void *buff,
u32 valid_functions, num_functions;
u32 number, logical_id, phys_id;
struct i40e_hw_capabilities *p;
+ enum i40e_status_code status;
+ u16 id, ocp_cfg_word0;
u8 major_rev;
u32 i = 0;
- u16 id;
cap = (struct i40e_aqc_list_capabilities_element_resp *) buff;
@@ -3863,6 +3864,26 @@ STATIC void i40e_parse_discover_capabilities(struct i40e_hw *hw, void *buff,
hw->num_ports++;
}
+ /* OCP cards case: if a mezz is removed the ethernet port is at
+ * disabled state in PRTGEN_CNF register. Additional NVM read is
+ * needed in order to check if we are dealing with OCP card.
+ * Those cards have 4 PFs at minimum, so using PRTGEN_CNF for counting
+ * physical ports results in wrong partition id calculation and thus
+ * not supporting WoL.
+ */
+ if (hw->mac.type == I40E_MAC_X722) {
+ if (i40e_acquire_nvm(hw, I40E_RESOURCE_READ) == I40E_SUCCESS) {
+ status = i40e_aq_read_nvm(hw, I40E_SR_EMP_MODULE_PTR,
+ 2 * I40E_SR_OCP_CFG_WORD0,
+ sizeof(ocp_cfg_word0),
+ &ocp_cfg_word0, true, NULL);
+ if (status == I40E_SUCCESS &&
+ (ocp_cfg_word0 & I40E_SR_OCP_ENABLED))
+ hw->num_ports = 4;
+ i40e_release_nvm(hw);
+ }
+ }
+
valid_functions = p->valid_functions;
num_functions = 0;
while (valid_functions) {
diff --git a/drivers/net/i40e/base/i40e_lan_hmc.c b/drivers/net/i40e/base/i40e_lan_hmc.c
index 22606484..739f3d5a 100644
--- a/drivers/net/i40e/base/i40e_lan_hmc.c
+++ b/drivers/net/i40e/base/i40e_lan_hmc.c
@@ -143,7 +143,7 @@ enum i40e_status_code i40e_init_lan_hmc(struct i40e_hw *hw, u32 txq_num,
ret_code = I40E_ERR_INVALID_HMC_OBJ_COUNT;
DEBUGOUT3("i40e_init_lan_hmc: Tx context: asks for 0x%x but max allowed is 0x%x, returns error %d\n",
txq_num, obj->max_cnt, ret_code);
- goto init_lan_hmc_out;
+ goto free_hmc_out;
}
/* aggregate values into the full LAN object for later */
@@ -166,7 +166,7 @@ enum i40e_status_code i40e_init_lan_hmc(struct i40e_hw *hw, u32 txq_num,
ret_code = I40E_ERR_INVALID_HMC_OBJ_COUNT;
DEBUGOUT3("i40e_init_lan_hmc: Rx context: asks for 0x%x but max allowed is 0x%x, returns error %d\n",
rxq_num, obj->max_cnt, ret_code);
- goto init_lan_hmc_out;
+ goto free_hmc_out;
}
/* aggregate values into the full LAN object for later */
@@ -189,7 +189,7 @@ enum i40e_status_code i40e_init_lan_hmc(struct i40e_hw *hw, u32 txq_num,
ret_code = I40E_ERR_INVALID_HMC_OBJ_COUNT;
DEBUGOUT3("i40e_init_lan_hmc: FCoE context: asks for 0x%x but max allowed is 0x%x, returns error %d\n",
fcoe_cntx_num, obj->max_cnt, ret_code);
- goto init_lan_hmc_out;
+ goto free_hmc_out;
}
/* aggregate values into the full LAN object for later */
@@ -212,7 +212,7 @@ enum i40e_status_code i40e_init_lan_hmc(struct i40e_hw *hw, u32 txq_num,
ret_code = I40E_ERR_INVALID_HMC_OBJ_COUNT;
DEBUGOUT3("i40e_init_lan_hmc: FCoE filter: asks for 0x%x but max allowed is 0x%x, returns error %d\n",
fcoe_filt_num, obj->max_cnt, ret_code);
- goto init_lan_hmc_out;
+ goto free_hmc_out;
}
/* aggregate values into the full LAN object for later */
@@ -233,7 +233,7 @@ enum i40e_status_code i40e_init_lan_hmc(struct i40e_hw *hw, u32 txq_num,
(sizeof(struct i40e_hmc_sd_entry) *
hw->hmc.sd_table.sd_cnt));
if (ret_code)
- goto init_lan_hmc_out;
+ goto free_hmc_out;
hw->hmc.sd_table.sd_entry =
(struct i40e_hmc_sd_entry *)hw->hmc.sd_table.addr.va;
}
@@ -242,6 +242,11 @@ enum i40e_status_code i40e_init_lan_hmc(struct i40e_hw *hw, u32 txq_num,
init_lan_hmc_out:
return ret_code;
+free_hmc_out:
+ if (hw->hmc.hmc_obj_virt_mem.va)
+ i40e_free_virt_mem(hw, &hw->hmc.hmc_obj_virt_mem);
+
+ return ret_code;
}
/**
diff --git a/drivers/net/i40e/base/i40e_type.h b/drivers/net/i40e/base/i40e_type.h
index d514abe3..aa45d10c 100644
--- a/drivers/net/i40e/base/i40e_type.h
+++ b/drivers/net/i40e/base/i40e_type.h
@@ -1519,6 +1519,8 @@ struct i40e_hw_port_stats {
#define I40E_SR_PCIE_ALT_MODULE_MAX_SIZE 1024
#define I40E_SR_CONTROL_WORD_1_SHIFT 0x06
#define I40E_SR_CONTROL_WORD_1_MASK (0x03 << I40E_SR_CONTROL_WORD_1_SHIFT)
+#define I40E_SR_OCP_CFG_WORD0 0x2B
+#define I40E_SR_OCP_ENABLED BIT(15)
/* Shadow RAM related */
#define I40E_SR_SECTOR_SIZE_IN_WORDS 0x800
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 30612963..62b36c9a 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -1081,9 +1081,6 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
/* Make sure all is clean before doing PF reset */
i40e_clear_hw(hw);
- /* Initialize the hardware */
- i40e_hw_init(dev);
-
/* Reset here to make sure all is clean for each PF */
ret = i40e_pf_reset(hw);
if (ret) {
@@ -1098,20 +1095,6 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
return ret;
}
- i40e_config_automask(pf);
-
- /*
- * To work around the NVM issue, initialize registers
- * for flexible payload and packet type of QinQ by
- * software. It should be removed once issues are fixed
- * in NVM.
- */
- if (!pf->support_multi_driver)
- i40e_GLQF_reg_init(hw);
-
- /* Initialize the input set for filters (hash and fd) to default value */
- i40e_filter_input_set_init(pf);
-
/* Initialize the parameters for adminq */
i40e_init_adminq_parameter(hw);
ret = i40e_init_adminq(hw);
@@ -1126,6 +1109,23 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
((hw->nvm.version >> 4) & 0xff),
(hw->nvm.version & 0xf), hw->nvm.eetrack);
+ /* Initialize the hardware */
+ i40e_hw_init(dev);
+
+ i40e_config_automask(pf);
+
+ /*
+ * To work around the NVM issue, initialize registers
+ * for flexible payload and packet type of QinQ by
+ * software. It should be removed once issues are fixed
+ * in NVM.
+ */
+ if (!pf->support_multi_driver)
+ i40e_GLQF_reg_init(hw);
+
+ /* Initialize the input set for filters (hash and fd) to default value */
+ i40e_filter_input_set_init(pf);
+
/* Need the special FW version to support floating VEB */
config_floating_veb(dev);
/* Clear PXE mode */
@@ -2085,6 +2085,10 @@ i40e_dev_promiscuous_disable(struct rte_eth_dev *dev)
if (status != I40E_SUCCESS)
PMD_DRV_LOG(ERR, "Failed to disable unicast promiscuous");
+ /* must remain in all_multicast mode */
+ if (dev->data->all_multicast == 1)
+ return;
+
status = i40e_aq_set_vsi_multicast_promiscuous(hw, vsi->seid,
false, NULL);
if (status != I40E_SUCCESS)
@@ -4589,7 +4593,7 @@ i40e_enable_pf_lb(struct i40e_pf *pf)
int ret;
/* Use the FW API if FW >= v5.0 */
- if (hw->aq.fw_maj_ver < 5) {
+ if (hw->aq.fw_maj_ver < 5 && hw->mac.type != I40E_MAC_X722) {
PMD_INIT_LOG(ERR, "FW < v5.0, cannot enable loopback");
return;
}
@@ -4858,7 +4862,7 @@ i40e_vsi_setup(struct i40e_pf *pf,
ctxt.flags = I40E_AQ_VSI_TYPE_VF;
/* Use the VEB configuration if FW >= v5.0 */
- if (hw->aq.fw_maj_ver >= 5) {
+ if (hw->aq.fw_maj_ver >= 5 || hw->mac.type == I40E_MAC_X722) {
/* Configure switch ID */
ctxt.info.valid_sections |=
rte_cpu_to_le_16(I40E_AQ_VSI_PROP_SWITCH_VALID);
@@ -10080,6 +10084,32 @@ i40e_dev_rx_queue_intr_disable(struct rte_eth_dev *dev, uint16_t queue_id)
return 0;
}
+/**
+ * This function is used to check if the register is valid.
+ * Below is the valid registers list for X722 only:
+ * 0x2b800--0x2bb00
+ * 0x38700--0x38a00
+ * 0x3d800--0x3db00
+ * 0x208e00--0x209000
+ * 0x20be00--0x20c000
+ * 0x263c00--0x264000
+ * 0x265c00--0x266000
+ */
+static inline int i40e_valid_regs(enum i40e_mac_type type, uint32_t reg_offset)
+{
+ if ((type != I40E_MAC_X722) &&
+ ((reg_offset >= 0x2b800 && reg_offset <= 0x2bb00) ||
+ (reg_offset >= 0x38700 && reg_offset <= 0x38a00) ||
+ (reg_offset >= 0x3d800 && reg_offset <= 0x3db00) ||
+ (reg_offset >= 0x208e00 && reg_offset <= 0x209000) ||
+ (reg_offset >= 0x20be00 && reg_offset <= 0x20c000) ||
+ (reg_offset >= 0x263c00 && reg_offset <= 0x264000) ||
+ (reg_offset >= 0x265c00 && reg_offset <= 0x266000)))
+ return 0;
+ else
+ return 1;
+}
+
static int i40e_get_regs(struct rte_eth_dev *dev,
struct rte_dev_reg_info *regs)
{
@@ -10121,8 +10151,11 @@ static int i40e_get_regs(struct rte_eth_dev *dev,
reg_offset = arr_idx * reg_info->stride1 +
arr_idx2 * reg_info->stride2;
reg_offset += reg_info->base_addr;
- ptr_data[reg_offset >> 2] =
- I40E_READ_REG(hw, reg_offset);
+ if (!i40e_valid_regs(hw->mac.type, reg_offset))
+ ptr_data[reg_offset >> 2] = 0;
+ else
+ ptr_data[reg_offset >> 2] =
+ I40E_READ_REG(hw, reg_offset);
}
}
diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index 777ffc21..2c56c1ac 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -74,6 +74,10 @@
#define I40E_TXD_CMD (I40E_TX_DESC_CMD_EOP | I40E_TX_DESC_CMD_RS)
#define I40E_TX_CKSUM_OFFLOAD_MASK ( \
+ PKT_TX_OUTER_IPV4 | \
+ PKT_TX_OUTER_IPV6 | \
+ PKT_TX_IPV4 | \
+ PKT_TX_IPV6 | \
PKT_TX_IP_CKSUM | \
PKT_TX_L4_MASK | \
PKT_TX_TCP_SEG | \