As global registers will be reset only after a whole chip reset, those registers might not be in an initial state after each launching a physical port. The hardware initialization is added to put specific global registers into an initial state.
Signed-off-by: Helin Zhang <helin.zhang at intel.com> --- lib/librte_pmd_i40e/i40e_ethdev.c | 78 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) diff --git a/lib/librte_pmd_i40e/i40e_ethdev.c b/lib/librte_pmd_i40e/i40e_ethdev.c index 7531e3c..cedd09a 100644 --- a/lib/librte_pmd_i40e/i40e_ethdev.c +++ b/lib/librte_pmd_i40e/i40e_ethdev.c @@ -190,6 +190,7 @@ static int i40e_dev_filter_ctrl(struct rte_eth_dev *dev, enum rte_filter_type filter_type, enum rte_filter_op filter_op, void *arg); +static void i40e_hw_init(struct i40e_hw *hw); static struct rte_pci_id pci_id_i40e_map[] = { #define RTE_PCI_DEV_ID_DECL_I40E(vend, dev) {RTE_PCI_DEVICE(vend, dev)}, @@ -368,6 +369,9 @@ eth_i40e_dev_init(__rte_unused struct eth_driver *eth_drv, /* Make sure all is clean before doing PF reset */ i40e_clear_hw(hw); + /* Initialize the hardware */ + i40e_hw_init(hw); + /* Reset here to make sure all is clean for each PF */ ret = i40e_pf_reset(hw); if (ret) { @@ -4541,3 +4545,77 @@ i40e_dev_filter_ctrl(struct rte_eth_dev *dev, return ret; } + +/* Initialization for hash function */ +static void +i40e_hash_function_hw_init(struct i40e_hw *hw) +{ + uint32_t i; + const struct rte_eth_sym_hash_ena_info sym_hash_ena_info[] = { + {ETH_RSS_NONF_IPV4_UDP_SHIFT, 0}, + {ETH_RSS_NONF_IPV4_TCP_SHIFT, 0}, + {ETH_RSS_NONF_IPV4_SCTP_SHIFT, 0}, + {ETH_RSS_NONF_IPV4_OTHER_SHIFT, 0}, + {ETH_RSS_FRAG_IPV4_SHIFT, 0}, + {ETH_RSS_NONF_IPV6_UDP_SHIFT, 0}, + {ETH_RSS_NONF_IPV6_TCP_SHIFT, 0}, + {ETH_RSS_NONF_IPV6_SCTP_SHIFT, 0}, + {ETH_RSS_NONF_IPV6_OTHER_SHIFT, 0}, + {ETH_RSS_FRAG_IPV6_SHIFT, 0}, + {ETH_RSS_L2_PAYLOAD_SHIFT, 0}, + }; + const struct rte_eth_filter_swap_info swap_info[] = { + {ETH_RSS_NONF_IPV4_UDP_SHIFT, + 0x1e, 0x36, 0x04, 0x3a, 0x3c, 0x02}, + {ETH_RSS_NONF_IPV4_TCP_SHIFT, + 0x1e, 0x36, 0x04, 0x3a, 0x3c, 0x02}, + {ETH_RSS_NONF_IPV4_SCTP_SHIFT, + 0x1e, 0x36, 0x04, 0x00, 0x00, 0x00}, + {ETH_RSS_NONF_IPV4_OTHER_SHIFT, + 0x1e, 0x36, 0x04, 0x00, 0x00, 0x00}, + {ETH_RSS_FRAG_IPV4_SHIFT, + 0x1e, 0x36, 0x04, 0x00, 0x00, 0x00}, + {ETH_RSS_NONF_IPV6_UDP_SHIFT, + 0x1a, 0x2a, 0x10, 0x3a, 0x3c, 0x02}, + {ETH_RSS_NONF_IPV6_TCP_SHIFT, + 0x1a, 0x2a, 0x10, 0x3a, 0x3c, 0x02}, + {ETH_RSS_NONF_IPV6_SCTP_SHIFT, + 0x1a, 0x2a, 0x10, 0x00, 0x00, 0x00}, + {ETH_RSS_NONF_IPV6_OTHER_SHIFT, + 0x1a, 0x2a, 0x10, 0x00, 0x00, 0x00}, + {ETH_RSS_FRAG_IPV6_SHIFT, + 0x1a, 0x2a, 0x10, 0x00, 0x00, 0x00}, + {ETH_RSS_L2_PAYLOAD_SHIFT, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + }; + + /* Disable symmetric hash per PCTYPE */ + for (i = 0; i < RTE_DIM(sym_hash_ena_info); i++) + i40e_set_symmetric_hash_enable_per_pctype(hw, + &sym_hash_ena_info[i]); + + /* Disable symmetric hash per port */ + i40e_set_symmetric_hash_enable_per_port(hw, 0); + + /* Initialize filter swap */ + for (i = 0; i < RTE_DIM(swap_info); i++) + i40e_set_filter_swap(hw, &swap_info[i]); + + /* Set hash function to Toeplitz by default */ + i40e_set_hash_function(hw, RTE_ETH_HASH_FUNCTION_TOEPLITZ); +} + +/* + * As global registers wouldn't be reset unless a global hardware reset, + * hardware initialization is needed to put those registers into an + * expected initial state. + */ +static void +i40e_hw_init(struct i40e_hw *hw) +{ + /* clear the PF Queue Filter control register */ + I40E_WRITE_REG(hw, I40E_PFQF_CTL_0, 0); + + /* Initialize hardware for hash function */ + i40e_hash_function_hw_init(hw); +} -- 1.8.1.4