@@ -681,7 +681,8 @@ ice_dcf_init_hw(struct rte_eth_dev *eth_dev, struct ice_dcf_hw *hw)
if (ice_dcf_get_vf_vsi_map(hw) < 0) {
PMD_INIT_LOG(ERR, "Failed to get VF VSI map");
- ice_dcf_mode_disable(hw);
+ if (!hw->multi_inst)
+ ice_dcf_mode_disable(hw);
goto err_alloc;
}
@@ -759,8 +760,8 @@ ice_dcf_uninit_hw(struct rte_eth_dev *eth_dev, struct ice_dcf_hw *hw)
rte_intr_disable(intr_handle);
rte_intr_callback_unregister(intr_handle,
ice_dcf_dev_interrupt_handler, hw);
-
- ice_dcf_mode_disable(hw);
+ if (!hw->multi_inst)
+ ice_dcf_mode_disable(hw);
iavf_shutdown_adminq(&hw->avf);
rte_free(hw->arq_buf);
@@ -1187,3 +1188,19 @@ ice_dcf_cap_reset(struct rte_eth_dev *eth_dev, struct ice_dcf_hw *hw)
ice_dcf_enable_irq0(hw);
return ret;
}
+
+int
+ice_dcf_flush_rules(struct ice_dcf_hw *hw)
+{
+ struct dcf_virtchnl_cmd args;
+ int err = 0;
+
+ memset(&args, 0, sizeof(args));
+ args.v_op = VIRTCHNL_OP_DCF_RULE_FLUSH;
+
+ err = ice_dcf_execute_virtchnl_cmd(hw, &args);
+ if (err)
+ PMD_DRV_LOG(WARNING, "fail to execute command OF_DCF_RULE_FLUSH, DCF role must be preempted.");
+
+ return 0;
+}
@@ -98,6 +98,8 @@ struct ice_dcf_hw {
uint16_t vsi_id;
struct rte_eth_dev *eth_dev;
+ bool multi_inst;
+ bool dcf_replaced;
uint8_t *rss_lut;
uint8_t *rss_key;
uint64_t supported_rxdid;
@@ -142,5 +144,6 @@ void ice_dcf_tm_conf_init(struct rte_eth_dev *dev);
void ice_dcf_tm_conf_uninit(struct rte_eth_dev *dev);
int ice_dcf_replay_vf_bw(struct ice_dcf_hw *hw, uint16_t vf_id);
int ice_dcf_clear_bw(struct ice_dcf_hw *hw);
+int ice_dcf_flush_rules(struct ice_dcf_hw *hw);
#endif /* _ICE_DCF_H_ */
@@ -19,6 +19,7 @@
#include <rte_malloc.h>
#include <rte_memzone.h>
#include <rte_dev.h>
+#include <rte_ethdev.h>
#include <iavf_devids.h>
@@ -1788,12 +1789,66 @@ static const struct eth_dev_ops ice_dcf_eth_dev_ops = {
.mtu_set = ice_dcf_dev_mtu_set,
};
+static int
+ice_dcf_cap_check_handler(__rte_unused const char *key,
+ const char *value, void *opaque)
+{
+ bool *mi = opaque;
+
+ if (!strcmp(value, "dcf")) {
+ *mi = 0;
+ return 0;
+ }
+ if (!strcmp(value, "mdcf")) {
+ *mi = 1;
+ return 0;
+ }
+
+ return -1;
+}
+
+static int
+ice_dcf_cap_selected(struct ice_dcf_adapter *adapter,
+ struct rte_devargs *devargs)
+{
+ struct ice_adapter *ad = &adapter->parent;
+ struct rte_kvargs *kvlist;
+ const char *key_cap = "cap";
+ int ret = 0;
+
+ if (devargs == NULL)
+ return 0;
+
+ kvlist = rte_kvargs_parse(devargs->args, NULL);
+ if (kvlist == NULL)
+ return 0;
+
+ if (!rte_kvargs_count(kvlist, key_cap))
+ goto exit;
+
+ /* dcf capability selected when there's a key-value pair: cap=dcf */
+ if (rte_kvargs_process(kvlist, key_cap,
+ ice_dcf_cap_check_handler,
+ &adapter->real_hw.multi_inst) < 0)
+ goto exit;
+
+ ret = 1;
+
+exit:
+ rte_kvargs_free(kvlist);
+ return ret;
+}
+
static int
ice_dcf_dev_init(struct rte_eth_dev *eth_dev)
{
+ struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(eth_dev->device);
struct ice_dcf_adapter *adapter = eth_dev->data->dev_private;
struct ice_adapter *parent_adapter = &adapter->parent;
+ if (!ice_dcf_cap_selected(adapter, pci_dev->device.devargs))
+ return 1;
+
eth_dev->dev_ops = &ice_dcf_eth_dev_ops;
eth_dev->rx_pkt_burst = ice_dcf_recv_pkts;
eth_dev->tx_pkt_burst = ice_dcf_xmit_pkts;
@@ -1829,45 +1884,6 @@ ice_dcf_dev_uninit(struct rte_eth_dev *eth_dev)
return 0;
}
-static int
-ice_dcf_cap_check_handler(__rte_unused const char *key,
- const char *value, __rte_unused void *opaque)
-{
- if (strcmp(value, "dcf"))
- return -1;
-
- return 0;
-}
-
-static int
-ice_dcf_cap_selected(struct rte_devargs *devargs)
-{
- struct rte_kvargs *kvlist;
- const char *key = "cap";
- int ret = 0;
-
- if (devargs == NULL)
- return 0;
-
- kvlist = rte_kvargs_parse(devargs->args, NULL);
- if (kvlist == NULL)
- return 0;
-
- if (!rte_kvargs_count(kvlist, key))
- goto exit;
-
- /* dcf capability selected when there's a key-value pair: cap=dcf */
- if (rte_kvargs_process(kvlist, key,
- ice_dcf_cap_check_handler, NULL) < 0)
- goto exit;
-
- ret = 1;
-
-exit:
- rte_kvargs_free(kvlist);
- return ret;
-}
-
static int
eth_ice_dcf_pci_probe(__rte_unused struct rte_pci_driver *pci_drv,
struct rte_pci_device *pci_dev)
@@ -1880,9 +1896,6 @@ eth_ice_dcf_pci_probe(__rte_unused struct rte_pci_driver *pci_drv,
uint16_t dcf_vsi_id;
int i, ret;
- if (!ice_dcf_cap_selected(pci_dev->device.devargs))
- return 1;
-
ret = rte_eth_devargs_parse(pci_dev->device.devargs->args, ð_da);
if (ret)
return ret;
@@ -1995,4 +2008,4 @@ static struct rte_pci_driver rte_ice_dcf_pmd = {
RTE_PMD_REGISTER_PCI(net_ice_dcf, rte_ice_dcf_pmd);
RTE_PMD_REGISTER_PCI_TABLE(net_ice_dcf, pci_id_ice_dcf_map);
RTE_PMD_REGISTER_KMOD_DEP(net_ice_dcf, "* igb_uio | vfio-pci");
-RTE_PMD_REGISTER_PARAM_STRING(net_ice_dcf, "cap=dcf");
+RTE_PMD_REGISTER_PARAM_STRING(net_ice_dcf, "cap=dcf|mdcf");
@@ -125,6 +125,9 @@ ice_dcf_vsi_update_service_handler(void *param)
pthread_detach(pthread_self());
+ if (hw->multi_inst)
+ return NULL;
+
rte_delay_us(ICE_DCF_VSI_UPDATE_SERVICE_INTERVAL);
rte_spinlock_lock(&vsi_update_lock);
@@ -269,6 +272,10 @@ ice_dcf_handle_pf_event_msg(struct ice_dcf_hw *dcf_hw,
start_vsi_reset_thread(dcf_hw, true,
pf_msg->event_data.vf_vsi_map.vf_id);
break;
+ case VIRTCHNL_EVENT_DCF_VSI_INFO:
+ if (dcf_hw->vsi_id != pf_msg->event_data.vf_vsi_map.vsi_id)
+ dcf_hw->dcf_replaced = true;
+ break;
default:
PMD_DRV_LOG(ERR, "Unknown event received %u", pf_msg->event);
break;
@@ -436,6 +443,7 @@ ice_dcf_init_parent_adapter(struct rte_eth_dev *eth_dev)
parent_hw->aq_send_cmd_fn = ice_dcf_send_aq_cmd;
parent_hw->aq_send_cmd_param = &adapter->real_hw;
parent_hw->dcf_enabled = true;
+ hw->dcf_replaced = false;
err = ice_dcf_init_parent_hw(parent_hw);
if (err) {
@@ -17,6 +17,7 @@
#include "ice_ethdev.h"
#include "ice_generic_flow.h"
+#include "ice_dcf.h"
/**
* Non-pipeline mode, fdir and switch both used as distributor,
@@ -2533,10 +2534,16 @@ ice_flow_flush(struct rte_eth_dev *dev,
struct rte_flow_error *error)
{
struct ice_pf *pf = ICE_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+ struct ice_adapter *ad =
+ ICE_DEV_PRIVATE_TO_ADAPTER(dev->data->dev_private);
+ struct ice_dcf_hw *hw = ad->hw.aq_send_cmd_param;
struct rte_flow *p_flow;
void *temp;
int ret = 0;
+ if (ad->hw.dcf_enabled && hw->dcf_replaced)
+ return ret;
+
RTE_TAILQ_FOREACH_SAFE(p_flow, &pf->flow_list, node, temp) {
ret = ice_flow_destroy(dev, p_flow, error);
if (ret) {
@@ -2547,6 +2554,9 @@ ice_flow_flush(struct rte_eth_dev *dev,
}
}
+ if (ad->hw.dcf_enabled && hw->multi_inst)
+ return ice_dcf_flush_rules(ad->hw.aq_send_cmd_param);
+
return ret;
}
@@ -497,6 +497,7 @@ ice_switch_destroy(struct ice_adapter *ad,
struct rte_flow *flow,
struct rte_flow_error *error)
{
+ struct ice_dcf_hw *dcf_hw = ad->hw.aq_send_cmd_param;
struct ice_hw *hw = &ad->hw;
int ret;
struct ice_switch_filter_conf *filter_conf_ptr;
@@ -524,7 +525,7 @@ ice_switch_destroy(struct ice_adapter *ad,
}
ret = ice_rem_adv_rule_by_id(hw, &filter_conf_ptr->sw_query_data);
- if (ret) {
+ if (ret && !(hw->dcf_enabled && dcf_hw->multi_inst)) {
if (ice_dcf_adminq_need_retry(ad))
ret = -EAGAIN;
else
@@ -537,7 +538,7 @@ ice_switch_destroy(struct ice_adapter *ad,
}
ice_switch_filter_rule_free(flow);
- return ret;
+ return 0;
}
static bool