When VF closed, the VF should notify PF to close/reset relative resources from PF side.
Check the VF RSS offload flag and ignore relative operation when iavf hash uninit to avoid reset/close error. Fixes: 22b123a36d07 ("net/avf: initialize PMD") Signed-off-by: Steve Yang <stevex.y...@intel.com> --- drivers/common/iavf/iavf_prototype.h | 1 + drivers/common/iavf/version.map | 1 + drivers/net/iavf/iavf_ethdev.c | 48 +++++++++++++++++++++++++++- drivers/net/iavf/iavf_hash.c | 9 ++++-- 4 files changed, 55 insertions(+), 4 deletions(-) diff --git a/drivers/common/iavf/iavf_prototype.h b/drivers/common/iavf/iavf_prototype.h index f34e77db0f..3998d26dc0 100644 --- a/drivers/common/iavf/iavf_prototype.h +++ b/drivers/common/iavf/iavf_prototype.h @@ -83,6 +83,7 @@ void iavf_destroy_spinlock(struct iavf_spinlock *sp); __rte_internal void iavf_vf_parse_hw_config(struct iavf_hw *hw, struct virtchnl_vf_resource *msg); +__rte_internal enum iavf_status iavf_vf_reset(struct iavf_hw *hw); __rte_internal enum iavf_status iavf_aq_send_msg_to_pf(struct iavf_hw *hw, diff --git a/drivers/common/iavf/version.map b/drivers/common/iavf/version.map index e0f117197c..6c1427cca4 100644 --- a/drivers/common/iavf/version.map +++ b/drivers/common/iavf/version.map @@ -7,6 +7,7 @@ INTERNAL { iavf_set_mac_type; iavf_shutdown_adminq; iavf_vf_parse_hw_config; + iavf_vf_reset; local: *; }; diff --git a/drivers/net/iavf/iavf_ethdev.c b/drivers/net/iavf/iavf_ethdev.c index 7e3c26a94e..e2498a184e 100644 --- a/drivers/net/iavf/iavf_ethdev.c +++ b/drivers/net/iavf/iavf_ethdev.c @@ -1780,6 +1780,34 @@ iavf_init_proto_xtr(struct rte_eth_dev *dev) } } +static int +iavf_reset_vf(struct iavf_hw *hw) +{ + int ret; + if (iavf_vf_reset(hw) != IAVF_SUCCESS) { + PMD_INIT_LOG(ERR, "Reset VF NIC failed"); + return -1; + } + /** + * After issuing vf reset command to pf, pf won't necessarily + * reset vf, it depends on what state it exactly is. If it's not + * initialized yet, it won't have vf reset since it's in a certain + * state. If not, it will try to reset. Even vf is reset, pf will + * set I40E_VFGEN_RSTAT to COMPLETE first, then wait 10ms and set + * it to ACTIVE. In this duration, vf may not catch the moment that + * COMPLETE is set. So, for vf, we'll try to wait a long time. + */ + rte_delay_ms(200); + + ret = iavf_check_vf_reset_done(hw); + if (ret) { + PMD_INIT_LOG(ERR, "VF is still resetting"); + return ret; + } + + return 0; +} + static int iavf_init_vf(struct rte_eth_dev *dev) { @@ -1814,6 +1842,24 @@ iavf_init_vf(struct rte_eth_dev *dev) goto err; } + /* Reset VF and wait until it's complete */ + if (iavf_reset_vf(hw)) { + PMD_INIT_LOG(ERR, "reset NIC failed"); + goto err_aq; + } + + /* VF reset, shutdown admin queue and initialize again */ + if (iavf_shutdown_adminq(hw) != IAVF_SUCCESS) { + PMD_INIT_LOG(ERR, "iavf_shutdown_adminq failed"); + goto err; + } + + iavf_init_adminq_parameter(hw); + if (iavf_init_adminq(hw) != IAVF_SUCCESS) { + PMD_INIT_LOG(ERR, "init_adminq failed"); + goto err; + } + vf->aq_resp = rte_zmalloc("vf_aq_resp", IAVF_AQ_BUF_SZ, 0); if (!vf->aq_resp) { PMD_INIT_LOG(ERR, "unable to allocate vf_aq_resp memory"); @@ -2050,7 +2096,7 @@ iavf_dev_close(struct rte_eth_dev *dev) iavf_flow_flush(dev, NULL); iavf_flow_uninit(adapter); - + iavf_reset_vf(hw); /* * disable promiscuous mode before reset vf * it is a workaround solution when work with kernel driver diff --git a/drivers/net/iavf/iavf_hash.c b/drivers/net/iavf/iavf_hash.c index 8a5a6bb5a4..d3e9218f75 100644 --- a/drivers/net/iavf/iavf_hash.c +++ b/drivers/net/iavf/iavf_hash.c @@ -1093,10 +1093,13 @@ iavf_hash_uninit(struct iavf_adapter *ad) if (vf->vf_reset) return; - if (iavf_hash_default_set(ad, false)) - PMD_DRV_LOG(ERR, "fail to delete default RSS"); + if (vf->vf_res && + vf->vf_res->vf_cap_flags & VIRTCHNL_VF_OFFLOAD_ADV_RSS_PF) { + if (iavf_hash_default_set(ad, false)) + PMD_DRV_LOG(ERR, "fail to delete default RSS"); - iavf_unregister_parser(&iavf_hash_parser, ad); + iavf_unregister_parser(&iavf_hash_parser, ad); + } } static void -- 2.17.1