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.
v3 changes: * Renamed hardware initialization function. * Added initialization of register 'PFQF_CTL_0'. Signed-off-by: Helin Zhang <helin.zhang at intel.com> Acked-by: Jingjing Wu <jingjing.wu 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 ee7c9de..f23e0bf 100644 --- a/lib/librte_pmd_i40e/i40e_ethdev.c +++ b/lib/librte_pmd_i40e/i40e_ethdev.c @@ -209,6 +209,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); /* Default hash key buffer for RSS */ static uint32_t rss_key_default[I40E_PFQF_HKEY_MAX_INDEX + 1]; @@ -390,6 +391,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) { @@ -4533,3 +4537,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