@@ -1039,6 +1039,64 @@ i40e_init_queue_region_conf(struct rte_eth_dev *dev)
memset(info, 0, sizeof(struct i40e_queue_regions));
}
+#define ETH_I40E_SUPPORT_MULTI_DRIVER "support-multi-driver"
+
+static int
+i40e_parse_multi_drv_handler(__rte_unused const char *key,
+ const char *value,
+ void *opaque)
+{
+ struct i40e_pf *pf;
+ unsigned long support_multi_driver;
+ char *end;
+
+ pf = (struct i40e_pf *)opaque;
+
+ errno = 0;
+ support_multi_driver = strtoul(value, &end, 10);
+ if (errno != 0 || end == value || *end != 0) {
+ PMD_DRV_LOG(WARNING, "Wrong global configuration");
+ return -(EINVAL);
+ }
+
+ if (support_multi_driver == 1 || support_multi_driver == 0)
+ pf->support_multi_driver = (bool)support_multi_driver;
+ else
+ PMD_DRV_LOG(WARNING, "%s must be 1 or 0,",
+ "enable global configuration by default."
+ ETH_I40E_SUPPORT_MULTI_DRIVER);
+ return 0;
+}
+
+static int
+i40e_support_multi_driver(struct rte_eth_dev *dev)
+{
+ struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
+ static const char *const valid_keys[] = {
+ ETH_I40E_SUPPORT_MULTI_DRIVER, NULL};
+ struct rte_kvargs *kvlist;
+
+ /* Enable global configuration by default */
+ pf->support_multi_driver = false;
+
+ if (!dev->device->devargs)
+ return 0;
+
+ kvlist = rte_kvargs_parse(dev->device->devargs->args, valid_keys);
+ if (!kvlist)
+ return -EINVAL;
+
+ if (rte_kvargs_count(kvlist, ETH_I40E_SUPPORT_MULTI_DRIVER) > 1)
+ PMD_DRV_LOG(WARNING, "More than one argument \"%s\" and only "
+ "the first invalid or last valid one is used !",
+ ETH_I40E_SUPPORT_MULTI_DRIVER);
+
+ rte_kvargs_process(kvlist, ETH_I40E_SUPPORT_MULTI_DRIVER,
+ i40e_parse_multi_drv_handler, pf);
+ rte_kvargs_free(kvlist);
+ return 0;
+}
+
static int
eth_i40e_dev_init(struct rte_eth_dev *dev)
{
@@ -1092,6 +1150,9 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
hw->bus.func = pci_dev->addr.function;
hw->adapter_stopped = 0;
+ /* Check if need to support multi-driver */
+ i40e_support_multi_driver(dev);
+
/* Make sure all is clean before doing PF reset */
i40e_clear_hw(hw);
@@ -1119,7 +1180,8 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
* for packet type of QinQ by software.
* It should be removed once issues are fixed in NVM.
*/
- i40e_GLQF_reg_init(hw);
+ if (!pf->support_multi_driver)
+ i40e_GLQF_reg_init(hw);
/* Initialize the input set for filters (hash and fd) to default value */
i40e_filter_input_set_init(pf);
@@ -1139,13 +1201,17 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
(hw->nvm.version & 0xf), hw->nvm.eetrack);
/* initialise the L3_MAP register */
- ret = i40e_aq_debug_write_register(hw, I40E_GLQF_L3_MAP(40),
- 0x00000028, NULL);
- if (ret)
- PMD_INIT_LOG(ERR, "Failed to write L3 MAP register %d", ret);
- PMD_INIT_LOG(DEBUG, "Global register 0x%08x is changed with value 0x28",
- I40E_GLQF_L3_MAP(40));
- i40e_global_cfg_warning(I40E_WARNING_QINQ_CLOUD_FILTER);
+ if (!pf->support_multi_driver) {
+ ret = i40e_aq_debug_write_register(hw, I40E_GLQF_L3_MAP(40),
+ 0x00000028, NULL);
+ if (ret)
+ PMD_INIT_LOG(ERR, "Failed to write L3 MAP register %d",
+ ret);
+ PMD_INIT_LOG(DEBUG,
+ "Global register 0x%08x is changed with 0x28",
+ I40E_GLQF_L3_MAP(40));
+ i40e_global_cfg_warning(I40E_WARNING_QINQ_CLOUD_FILTER);
+ }
/* Need the special FW version to support floating VEB */
config_floating_veb(dev);
@@ -1221,11 +1287,15 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
i40e_set_fc(hw, &aq_fail, TRUE);
/* Set the global registers with default ether type value */
- ret = i40e_vlan_tpid_set(dev, ETH_VLAN_TYPE_OUTER, ETHER_TYPE_VLAN);
- if (ret != I40E_SUCCESS) {
- PMD_INIT_LOG(ERR,
- "Failed to set the default outer VLAN ether type");
- goto err_setup_pf_switch;
+ if (!pf->support_multi_driver) {
+ ret = i40e_vlan_tpid_set(dev, ETH_VLAN_TYPE_OUTER,
+ ETHER_TYPE_VLAN);
+ if (ret != I40E_SUCCESS) {
+ PMD_INIT_LOG(ERR,
+ "Failed to set the default outer "
+ "VLAN ether type");
+ goto err_setup_pf_switch;
+ }
}
/* PF setup, which includes VSI setup */
@@ -1291,7 +1361,8 @@ eth_i40e_dev_init(struct rte_eth_dev *dev)
rte_intr_enable(intr_handle);
/* By default disable flexible payload in global configuration */
- i40e_flex_payload_reg_set_default(hw);
+ if (!pf->support_multi_driver)
+ i40e_flex_payload_reg_set_default(hw);
/*
* Add an ethertype filter to drop all flow control frames transmitted
@@ -2225,7 +2296,8 @@ i40e_dev_close(struct rte_eth_dev *dev)
i40e_res_pool_destroy(&pf->msix_pool);
/* Disable flexible payload in global configuration */
- i40e_flex_payload_reg_set_default(hw);
+ if (!pf->support_multi_driver)
+ i40e_flex_payload_reg_set_default(hw);
/* force a PF reset to clean anything leftover */
reg = I40E_READ_REG(hw, I40E_PFGEN_CTRL);
@@ -3242,6 +3314,7 @@ i40e_vlan_tpid_set(struct rte_eth_dev *dev,
uint16_t tpid)
{
struct i40e_hw *hw = I40E_DEV_PRIVATE_TO_HW(dev->data->dev_private);
+ struct i40e_pf *pf = I40E_DEV_PRIVATE_TO_PF(dev->data->dev_private);
int qinq = dev->data->dev_conf.rxmode.hw_vlan_extend;
int ret = 0;
@@ -3252,6 +3325,12 @@ i40e_vlan_tpid_set(struct rte_eth_dev *dev,
"Unsupported vlan type.");
return -EINVAL;
}
+
+ if (pf->support_multi_driver) {
+ PMD_DRV_LOG(ERR, "Setting TPID is not supported.");
+ return -ENOTSUP;
+ }
+
/* 802.1ad frames ability is added in NVM API 1.7*/
if (hw->flags & I40E_HW_FLAG_802_1AD_CAPABLE) {
if (qinq) {
@@ -3504,20 +3583,25 @@ i40e_flow_ctrl_set(struct rte_eth_dev *dev, struct rte_eth_fc_conf *fc_conf)
I40E_WRITE_REG(hw, I40E_PRTDCB_MFLCN, mflcn_reg);
}
- /* config the water marker both based on the packets and bytes */
- I40E_WRITE_GLB_REG(hw, I40E_GLRPB_PHW,
- (pf->fc_conf.high_water[I40E_MAX_TRAFFIC_CLASS]
- << I40E_KILOSHIFT) / I40E_PACKET_AVERAGE_SIZE);
- I40E_WRITE_GLB_REG(hw, I40E_GLRPB_PLW,
- (pf->fc_conf.low_water[I40E_MAX_TRAFFIC_CLASS]
- << I40E_KILOSHIFT) / I40E_PACKET_AVERAGE_SIZE);
- I40E_WRITE_GLB_REG(hw, I40E_GLRPB_GHW,
- pf->fc_conf.high_water[I40E_MAX_TRAFFIC_CLASS]
- << I40E_KILOSHIFT);
- I40E_WRITE_GLB_REG(hw, I40E_GLRPB_GLW,
- pf->fc_conf.low_water[I40E_MAX_TRAFFIC_CLASS]
- << I40E_KILOSHIFT);
- i40e_global_cfg_warning(I40E_WARNING_FLOW_CTL);
+ if (!pf->support_multi_driver) {
+ /* config water marker both based on the packets and bytes */
+ I40E_WRITE_GLB_REG(hw, I40E_GLRPB_PHW,
+ (pf->fc_conf.high_water[I40E_MAX_TRAFFIC_CLASS]
+ << I40E_KILOSHIFT) / I40E_PACKET_AVERAGE_SIZE);
+ I40E_WRITE_GLB_REG(hw, I40E_GLRPB_PLW,
+ (pf->fc_conf.low_water[I40E_MAX_TRAFFIC_CLASS]
+ << I40E_KILOSHIFT) / I40E_PACKET_AVERAGE_SIZE);
+ I40E_WRITE_GLB_REG(hw, I40E_GLRPB_GHW,
+ pf->fc_conf.high_water[I40E_MAX_TRAFFIC_CLASS]
+ << I40E_KILOSHIFT);
+ I40E_WRITE_GLB_REG(hw, I40E_GLRPB_GLW,
+ pf->fc_conf.low_water[I40E_MAX_TRAFFIC_CLASS]
+ << I40E_KILOSHIFT);
+ i40e_global_cfg_warning(I40E_WARNING_FLOW_CTL);
+ } else {
+ PMD_DRV_LOG(ERR,
+ "Water marker configuration is not supported.");
+ }
I40E_WRITE_FLUSH(hw);
@@ -4050,7 +4134,6 @@ i40e_get_cap(struct i40e_hw *hw)
#define RTE_LIBRTE_I40E_QUEUE_NUM_PER_VF 4
#define QUEUE_NUM_PER_VF_ARG "queue-num-per-vf"
-RTE_PMD_REGISTER_PARAM_STRING(net_i40e, QUEUE_NUM_PER_VF_ARG "=1|2|4|8|16");
static int i40e_pf_parse_vf_queue_number_handler(const char *key,
const char *value,
@@ -7264,6 +7347,11 @@ i40e_status_code i40e_replace_mpls_l1_filter(struct i40e_pf *pf)
struct i40e_hw *hw = I40E_PF_TO_HW(pf);
enum i40e_status_code status = I40E_SUCCESS;
+ if (pf->support_multi_driver) {
+ PMD_DRV_LOG(ERR, "Replace l1 filter is not supported.");
+ return I40E_NOT_SUPPORTED;
+ }
+
memset(&filter_replace, 0,
sizeof(struct i40e_aqc_replace_cloud_filters_cmd));
memset(&filter_replace_buf, 0,
@@ -7318,6 +7406,11 @@ i40e_status_code i40e_replace_mpls_cloud_filter(struct i40e_pf *pf)
struct i40e_hw *hw = I40E_PF_TO_HW(pf);
enum i40e_status_code status = I40E_SUCCESS;
+ if (pf->support_multi_driver) {
+ PMD_DRV_LOG(ERR, "Replace cloud filter is not supported.");
+ return I40E_NOT_SUPPORTED;
+ }
+
/* For MPLSoUDP */
memset(&filter_replace, 0,
sizeof(struct i40e_aqc_replace_cloud_filters_cmd));
@@ -7383,6 +7476,11 @@ i40e_replace_gtp_l1_filter(struct i40e_pf *pf)
struct i40e_hw *hw = I40E_PF_TO_HW(pf);
enum i40e_status_code status = I40E_SUCCESS;
+ if (pf->support_multi_driver) {
+ PMD_DRV_LOG(ERR, "Replace l1 filter is not supported.");
+ return I40E_NOT_SUPPORTED;
+ }
+
/* For GTP-C */
memset(&filter_replace, 0,
sizeof(struct i40e_aqc_replace_cloud_filters_cmd));
@@ -7461,6 +7559,11 @@ i40e_status_code i40e_replace_gtp_cloud_filter(struct i40e_pf *pf)
struct i40e_hw *hw = I40E_PF_TO_HW(pf);
enum i40e_status_code status = I40E_SUCCESS;
+ if (pf->support_multi_driver) {
+ PMD_DRV_LOG(ERR, "Replace cloud filter is not supported.");
+ return I40E_NOT_SUPPORTED;
+ }
+
/* for GTP-C */
memset(&filter_replace, 0,
sizeof(struct i40e_aqc_replace_cloud_filters_cmd));
@@ -8042,9 +8145,15 @@ i40e_tunnel_filter_param_check(struct i40e_pf *pf,
static int
i40e_dev_set_gre_key_len(struct i40e_hw *hw, uint8_t len)
{
+ struct i40e_pf *pf = &((struct i40e_adapter *)hw->back)->pf;
uint32_t val, reg;
int ret = -EINVAL;
+ if (pf->support_multi_driver) {
+ PMD_DRV_LOG(ERR, "GRE key length configuration is unsupported");
+ return -ENOTSUP;
+ }
+
val = I40E_READ_REG(hw, I40E_GL_PRS_FVBM(2));
PMD_DRV_LOG(DEBUG, "Read original GL_PRS_FVBM with 0x%08x", val);
@@ -8299,11 +8408,17 @@ i40e_set_hash_filter_global_config(struct i40e_hw *hw,
struct rte_eth_hash_global_conf *g_cfg)
{
struct i40e_adapter *adapter = (struct i40e_adapter *)hw->back;
+ struct i40e_pf *pf = &((struct i40e_adapter *)hw->back)->pf;
int ret;
uint16_t i, j;
uint32_t reg;
uint64_t mask0 = g_cfg->valid_bit_mask[0] & adapter->flow_types_mask;
+ if (pf->support_multi_driver) {
+ PMD_DRV_LOG(ERR, "Hash global configuration is not supported.");
+ return -ENOTSUP;
+ }
+
/* Check the input parameters */
ret = i40e_hash_global_config_check(adapter, g_cfg);
if (ret < 0)
@@ -8975,6 +9090,10 @@ i40e_filter_input_set_init(struct i40e_pf *pf)
I40E_INSET_MASK_NUM_REG);
if (num < 0)
return;
+ if (pf->support_multi_driver && num > 0) {
+ PMD_DRV_LOG(ERR, "Input set setting is not supported.");
+ return;
+ }
inset_reg = i40e_translate_input_set_reg(hw->mac.type,
input_set);
@@ -8983,39 +9102,48 @@ i40e_filter_input_set_init(struct i40e_pf *pf)
i40e_check_write_reg(hw, I40E_PRTQF_FD_INSET(pctype, 1),
(uint32_t)((inset_reg >>
I40E_32_BIT_WIDTH) & UINT32_MAX));
- i40e_check_write_global_reg(hw, I40E_GLQF_HASH_INSET(0, pctype),
- (uint32_t)(inset_reg & UINT32_MAX));
- i40e_check_write_global_reg(hw, I40E_GLQF_HASH_INSET(1, pctype),
- (uint32_t)((inset_reg >>
- I40E_32_BIT_WIDTH) & UINT32_MAX));
-
- for (i = 0; i < num; i++) {
+ if (!pf->support_multi_driver) {
+ i40e_check_write_global_reg(hw,
+ I40E_GLQF_HASH_INSET(0, pctype),
+ (uint32_t)(inset_reg & UINT32_MAX));
i40e_check_write_global_reg(hw,
+ I40E_GLQF_HASH_INSET(1, pctype),
+ (uint32_t)((inset_reg >>
+ I40E_32_BIT_WIDTH) & UINT32_MAX));
+
+ for (i = 0; i < num; i++) {
+ i40e_check_write_global_reg(hw,
I40E_GLQF_FD_MSK(i, pctype),
mask_reg[i]);
- i40e_check_write_global_reg(hw,
+ i40e_check_write_global_reg(hw,
I40E_GLQF_HASH_MSK(i, pctype),
mask_reg[i]);
- }
- /*clear unused mask registers of the pctype */
- for (i = num; i < I40E_INSET_MASK_NUM_REG; i++) {
- i40e_check_write_global_reg(hw,
+ }
+ /*clear unused mask registers of the pctype */
+ for (i = num; i < I40E_INSET_MASK_NUM_REG; i++) {
+ i40e_check_write_global_reg(hw,
I40E_GLQF_FD_MSK(i, pctype),
0);
- i40e_check_write_global_reg(hw,
+ i40e_check_write_global_reg(hw,
I40E_GLQF_HASH_MSK(i, pctype),
0);
+ }
+ } else {
+ PMD_DRV_LOG(ERR, "Input set setting is not supported.");
}
I40E_WRITE_FLUSH(hw);
/* store the default input set */
- pf->hash_input_set[pctype] = input_set;
+ if (!pf->support_multi_driver)
+ pf->hash_input_set[pctype] = input_set;
pf->fdir.input_set[pctype] = input_set;
}
- i40e_global_cfg_warning(I40E_WARNING_HASH_INSET);
- i40e_global_cfg_warning(I40E_WARNING_FD_MSK);
- i40e_global_cfg_warning(I40E_WARNING_HASH_MSK);
+ if (!pf->support_multi_driver) {
+ i40e_global_cfg_warning(I40E_WARNING_HASH_INSET);
+ i40e_global_cfg_warning(I40E_WARNING_FD_MSK);
+ i40e_global_cfg_warning(I40E_WARNING_HASH_MSK);
+ }
}
int
@@ -9038,6 +9166,11 @@ i40e_hash_filter_inset_select(struct i40e_hw *hw,
return -EINVAL;
}
+ if (pf->support_multi_driver) {
+ PMD_DRV_LOG(ERR, "Hash input set setting is not supported.");
+ return -ENOTSUP;
+ }
+
pctype = i40e_flowtype_to_pctype(pf->adapter, conf->flow_type);
if (pctype == I40E_FILTER_PCTYPE_INVALID) {
PMD_DRV_LOG(ERR, "invalid flow_type input.");
@@ -9143,6 +9276,10 @@ i40e_fdir_filter_inset_select(struct i40e_pf *pf,
I40E_INSET_MASK_NUM_REG);
if (num < 0)
return -EINVAL;
+ if (pf->support_multi_driver && num > 0) {
+ PMD_DRV_LOG(ERR, "FDIR bit mask is not supported.");
+ return -ENOTSUP;
+ }
inset_reg |= i40e_translate_input_set_reg(hw->mac.type, input_set);
@@ -9152,14 +9289,20 @@ i40e_fdir_filter_inset_select(struct i40e_pf *pf,
(uint32_t)((inset_reg >>
I40E_32_BIT_WIDTH) & UINT32_MAX));
- for (i = 0; i < num; i++)
- i40e_check_write_global_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
- mask_reg[i]);
- /*clear unused mask registers of the pctype */
- for (i = num; i < I40E_INSET_MASK_NUM_REG; i++)
- i40e_check_write_global_reg(hw, I40E_GLQF_FD_MSK(i, pctype),
- 0);
- i40e_global_cfg_warning(I40E_WARNING_FD_MSK);
+ if (!pf->support_multi_driver) {
+ for (i = 0; i < num; i++)
+ i40e_check_write_global_reg(hw,
+ I40E_GLQF_FD_MSK(i, pctype),
+ mask_reg[i]);
+ /*clear unused mask registers of the pctype */
+ for (i = num; i < I40E_INSET_MASK_NUM_REG; i++)
+ i40e_check_write_global_reg(hw,
+ I40E_GLQF_FD_MSK(i, pctype),
+ 0);
+ i40e_global_cfg_warning(I40E_WARNING_FD_MSK);
+ } else {
+ PMD_DRV_LOG(ERR, "FDIR bit mask is not supported.");
+ }
I40E_WRITE_FLUSH(hw);
pf->fdir.input_set[pctype] = input_set;
@@ -11676,6 +11819,11 @@ i40e_cloud_filter_qinq_create(struct i40e_pf *pf)
struct i40e_aqc_replace_cloud_filters_cmd_buf filter_replace_buf;
struct i40e_hw *hw = I40E_PF_TO_HW(pf);
+ if (pf->support_multi_driver) {
+ PMD_DRV_LOG(ERR, "Replace cloud filter is not supported.");
+ return ret;
+ }
+
/* Init */
memset(&filter_replace, 0,
sizeof(struct i40e_aqc_replace_cloud_filters_cmd));
@@ -11828,3 +11976,7 @@ i40e_init_log(void)
if (i40e_logtype_driver >= 0)
rte_log_set_level(i40e_logtype_driver, RTE_LOG_NOTICE);
}
+
+RTE_PMD_REGISTER_PARAM_STRING(net_i40e,
+ QUEUE_NUM_PER_VF_ARG "=1|2|4|8|16"
+ ETH_I40E_SUPPORT_MULTI_DRIVER "=1");
@@ -950,6 +950,7 @@ struct i40e_pf {
bool gtp_replace_flag; /* 1 - GTP-C/U filter replace is done */
bool qinq_replace_flag; /* QINQ filter replace is done */
struct i40e_tm_conf tm_conf;
+ bool support_multi_driver; /* 1 - support multiple driver */
/* Dynamic Device Personalization */
bool gtp_support; /* 1 - support GTP-C and GTP-U */
@@ -649,22 +649,31 @@ i40e_fdir_configure(struct rte_eth_dev *dev)
PMD_DRV_LOG(ERR, " invalid configuration arguments.");
return -EINVAL;
}
- /* configure flex payload */
- for (i = 0; i < conf->nb_payloads; i++)
- i40e_set_flx_pld_cfg(pf, &conf->flex_set[i]);
- /* configure flex mask*/
- for (i = 0; i < conf->nb_flexmasks; i++) {
- if (hw->mac.type == I40E_MAC_X722) {
- /* get translated pctype value in fd pctype register */
- pctype = (enum i40e_filter_pctype)i40e_read_rx_ctl(
- hw, I40E_GLQF_FD_PCTYPES(
- (int)i40e_flowtype_to_pctype(pf->adapter,
- conf->flex_mask[i].flow_type)));
- } else
- pctype = i40e_flowtype_to_pctype(pf->adapter,
- conf->flex_mask[i].flow_type);
- i40e_set_flex_mask_on_pctype(pf, pctype, &conf->flex_mask[i]);
+ if (!pf->support_multi_driver) {
+ /* configure flex payload */
+ for (i = 0; i < conf->nb_payloads; i++)
+ i40e_set_flx_pld_cfg(pf, &conf->flex_set[i]);
+ /* configure flex mask*/
+ for (i = 0; i < conf->nb_flexmasks; i++) {
+ if (hw->mac.type == I40E_MAC_X722) {
+ /* get pctype value in fd pctype register */
+ pctype = (enum i40e_filter_pctype)
+ i40e_read_rx_ctl(hw,
+ I40E_GLQF_FD_PCTYPES(
+ (int)i40e_flowtype_to_pctype(
+ pf->adapter,
+ conf->flex_mask[i].flow_type)));
+ } else {
+ pctype = i40e_flowtype_to_pctype(pf->adapter,
+ conf->flex_mask[i].flow_type);
+ }
+
+ i40e_set_flex_mask_on_pctype(pf, pctype,
+ &conf->flex_mask[i]);
+ }
+ } else {
+ PMD_DRV_LOG(ERR, "Not support flexible payload.");
}
return ret;
@@ -2851,6 +2851,14 @@ i40e_flow_parse_fdir_pattern(struct rte_eth_dev *dev,
return -rte_errno;
}
+ if (pf->support_multi_driver) {
+ rte_flow_error_set(error, ENOTSUP,
+ RTE_FLOW_ERROR_TYPE_ITEM,
+ item,
+ "Unsupported flexible payload.");
+ return -rte_errno;
+ }
+
ret = i40e_flow_check_raw_item(item, raw_spec, error);
if (ret < 0)
return ret;