diff --git a/drivers/net/ice/ice_dcf_ethdev.c b/drivers/net/ice/ice_dcf_ethdev.c index a90dff9a46..1793d8cbd3 100644 --- a/drivers/net/ice/ice_dcf_ethdev.c +++ b/drivers/net/ice/ice_dcf_ethdev.c @@ -870,6 +870,13 @@ ice_dcf_dev_close(struct rte_eth_dev *dev) return 0; } +bool +ice_dcf_adminq_need_retry(struct ice_adapter *ad) +{ + return ad->hw.dcf_enabled && + !__atomic_load_n(&ad->dcf_state_on, __ATOMIC_RELAXED); +} + static int ice_dcf_link_update(__rte_unused struct rte_eth_dev *dev, __rte_unused int wait_to_complete) @@ -905,6 +912,7 @@ static int ice_dcf_dev_init(struct rte_eth_dev *eth_dev) { struct ice_dcf_adapter *adapter = eth_dev->data->dev_private; + struct ice_adapter *parent_adapter = &adapter->parent; eth_dev->dev_ops = &ice_dcf_eth_dev_ops; eth_dev->rx_pkt_burst = ice_dcf_recv_pkts; @@ -916,9 +924,13 @@ ice_dcf_dev_init(struct rte_eth_dev *eth_dev) adapter->real_hw.vc_event_msg_cb = ice_dcf_handle_pf_event_msg; if (ice_dcf_init_hw(eth_dev, &adapter->real_hw) != 0) { PMD_INIT_LOG(ERR, "Failed to init DCF hardware"); + __atomic_store_n(&parent_adapter->dcf_state_on, false, + __ATOMIC_RELAXED); return -1; } + __atomic_store_n(&parent_adapter->dcf_state_on, true, __ATOMIC_RELAXED); + if (ice_dcf_init_parent_adapter(eth_dev) != 0) { PMD_INIT_LOG(ERR, "Failed to init DCF parent adapter"); ice_dcf_uninit_hw(eth_dev, &adapter->real_hw); diff --git a/drivers/net/ice/ice_dcf_ethdev.h b/drivers/net/ice/ice_dcf_ethdev.h index b54528beae..0d25ff315e 100644 --- a/drivers/net/ice/ice_dcf_ethdev.h +++ b/drivers/net/ice/ice_dcf_ethdev.h @@ -26,5 +26,6 @@ void ice_dcf_handle_pf_event_msg(struct ice_dcf_hw *dcf_hw, uint8_t *msg, uint16_t msglen); int ice_dcf_init_parent_adapter(struct rte_eth_dev *eth_dev); void ice_dcf_uninit_parent_adapter(struct rte_eth_dev *eth_dev); +bool ice_dcf_adminq_need_retry(struct ice_adapter *ad); #endif /* _ICE_DCF_ETHDEV_H_ */ diff --git a/drivers/net/ice/ice_dcf_parent.c b/drivers/net/ice/ice_dcf_parent.c index 903e4db616..ad94953932 100644 --- a/drivers/net/ice/ice_dcf_parent.c +++ b/drivers/net/ice/ice_dcf_parent.c @@ -111,6 +111,9 @@ static void* ice_dcf_vsi_update_service_handler(void *param) { struct ice_dcf_hw *hw = param; + struct ice_dcf_adapter *adapter = + container_of(hw, struct ice_dcf_adapter, real_hw); + struct ice_adapter *parent_adapter = &adapter->parent; pthread_detach(pthread_self()); usleep(ICE_DCF_VSI_UPDATE_SERVICE_INTERVAL); @@ -122,6 +125,8 @@ ice_dcf_vsi_update_service_handler(void *param) struct ice_dcf_adapter *dcf_ad = container_of(hw, struct ice_dcf_adapter, real_hw); + __atomic_store_n(&parent_adapter->dcf_state_on, true, + __ATOMIC_RELAXED); ice_dcf_update_vf_vsi_map(&dcf_ad->parent.hw, hw->num_vfs, hw->vf_vsi_map); } @@ -137,6 +142,9 @@ ice_dcf_handle_pf_event_msg(struct ice_dcf_hw *dcf_hw, { struct virtchnl_pf_event *pf_msg = (struct virtchnl_pf_event *)msg; pthread_t thread; + struct ice_dcf_adapter *adapter = + container_of(dcf_hw, struct ice_dcf_adapter, real_hw); + struct ice_adapter *parent_adapter = &adapter->parent; if (msglen < sizeof(struct virtchnl_pf_event)) { PMD_DRV_LOG(DEBUG, "Invalid event message length : %u", msglen); @@ -161,6 +169,8 @@ ice_dcf_handle_pf_event_msg(struct ice_dcf_hw *dcf_hw, pf_msg->event_data.vf_vsi_map.vsi_id); pthread_create(&thread, NULL, ice_dcf_vsi_update_service_handler, dcf_hw); + __atomic_store_n(&parent_adapter->dcf_state_on, false, + __ATOMIC_RELAXED); break; default: PMD_DRV_LOG(ERR, "Unknown event received %u", pf_msg->event); diff --git a/drivers/net/ice/ice_ethdev.h b/drivers/net/ice/ice_ethdev.h index b3e518fcbc..fd81ede8a1 100644 --- a/drivers/net/ice/ice_ethdev.h +++ b/drivers/net/ice/ice_ethdev.h @@ -478,6 +478,8 @@ struct ice_adapter { struct ice_devargs devargs; enum ice_pkg_type active_pkg_type; /* loaded ddp package type */ uint16_t fdir_ref_cnt; + /* True if DCF state of the associated PF is on */ + bool dcf_state_on; #ifdef RTE_ARCH_X86 bool rx_use_avx2; bool rx_use_avx512; diff --git a/drivers/net/ice/ice_generic_flow.c b/drivers/net/ice/ice_generic_flow.c index ca401c7703..311fd7d162 100644 --- a/drivers/net/ice/ice_generic_flow.c +++ b/drivers/net/ice/ice_generic_flow.c @@ -2323,7 +2323,9 @@ ice_flow_flush(struct rte_eth_dev *dev, ret = ice_flow_destroy(dev, p_flow, error); if (ret) { PMD_DRV_LOG(ERR, "Failed to flush flows"); - return -EINVAL; + if (ret != -EAGAIN) + ret = -EINVAL; + return ret; } } diff --git a/drivers/net/ice/ice_switch_filter.c b/drivers/net/ice/ice_switch_filter.c index f41a57acf4..ea5ced60a7 100644 --- a/drivers/net/ice/ice_switch_filter.c +++ b/drivers/net/ice/ice_switch_filter.c @@ -438,6 +438,14 @@ ice_switch_create(struct ice_adapter *ad, "lookup list should not be NULL"); goto error; } + + if (ice_dcf_adminq_need_retry(ad)) { + rte_flow_error_set(error, EAGAIN, + RTE_FLOW_ERROR_TYPE_ITEM, NULL, + "DCF is not on"); + goto error; + } + ret = ice_add_adv_rule(hw, list, lkups_cnt, rule_info, &rule_added); if (!ret) { filter_conf_ptr = rte_zmalloc("ice_switch_filter", @@ -461,7 +469,12 @@ ice_switch_create(struct ice_adapter *ad, flow->rule = filter_conf_ptr; } else { - rte_flow_error_set(error, EINVAL, + if (ice_dcf_adminq_need_retry(ad)) + ret = -EAGAIN; + else + ret = -EINVAL; + + rte_flow_error_set(error, -ret, RTE_FLOW_ERROR_TYPE_HANDLE, NULL, "switch filter create flow fail"); goto error; @@ -513,9 +526,21 @@ ice_switch_destroy(struct ice_adapter *ad, return -rte_errno; } + if (ice_dcf_adminq_need_retry(ad)) { + rte_flow_error_set(error, EAGAIN, + RTE_FLOW_ERROR_TYPE_ITEM, NULL, + "DCF is not on"); + return -rte_errno; + } + ret = ice_rem_adv_rule_by_id(hw, &filter_conf_ptr->sw_query_data); if (ret) { - rte_flow_error_set(error, EINVAL, + if (ice_dcf_adminq_need_retry(ad)) + ret = -EAGAIN; + else + ret = -EINVAL; + + rte_flow_error_set(error, -ret, RTE_FLOW_ERROR_TYPE_HANDLE, NULL, "fail to destroy switch filter rule"); return -rte_errno; @@ -1904,6 +1929,12 @@ ice_switch_redirect(struct ice_adapter *ad, } rmv_rule: + if (ice_dcf_adminq_need_retry(ad)) { + PMD_DRV_LOG(WARNING, "DCF is not on"); + ret = -EAGAIN; + goto out; + } + /* Remove the old rule */ ret = ice_rem_adv_rule(hw, lkups_ref, lkups_cnt, &rinfo); if (ret) { @@ -1916,6 +1947,12 @@ ice_switch_redirect(struct ice_adapter *ad, } add_rule: + if (ice_dcf_adminq_need_retry(ad)) { + PMD_DRV_LOG(WARNING, "DCF is not on"); + ret = -EAGAIN; + goto out; + } + /* Update VSI context */ hw->vsi_ctx[rd->vsi_handle]->vsi_num = rd->new_vsi_num; @@ -1935,6 +1972,10 @@ ice_switch_redirect(struct ice_adapter *ad, } out: + if (ret == -EINVAL) + if (ice_dcf_adminq_need_retry(ad)) + ret = -EAGAIN; + ice_free(hw, lkups_dp); return ret; }