If this parameter is not specified then ef100 device will operate as
network device.
+- ``switch_mode`` [legacy|switchdev] (see below for default)
+
+ In legacy mode, NIC firmware provides Ethernet virtual bridging (EVB) API
+ to configure switching inside NIC to deliver traffic to physical (PF) and
+ virtual (VF) PCI functions. PF driver is responsible to build the
+ infrastructure for VFs, and traffic goes to/from VF by default in accordance
+ with MAC address assigned, permissions and filters installed by VF drivers.
+ In switchdev mode VF traffic goes via port representor (if any) on PF, and
+ software virtual switch (for example, Open vSwitch) makes the decision.
+ Software virtual switch may install MAE rules to pass established traffic
+ flows via hardware and offload software datapath as the result.
+ Default is legacy.
+
- ``rx_datapath`` [auto|efx|ef10|ef10_essb] (default **auto**)
Choose receive datapath implementation.
boolean_t tso_encap;
uint32_t rxd_wait_timeout_ns;
+
+ bool switchdev;
};
static inline struct sfc_adapter_shared *
}
}
+static int
+sfc_parse_switch_mode(struct sfc_adapter *sa)
+{
+ const efx_nic_cfg_t *encp = efx_nic_cfg_get(sa->nic);
+ const char *switch_mode = NULL;
+ int rc;
+
+ sfc_log_init(sa, "entry");
+
+ rc = sfc_kvargs_process(sa, SFC_KVARG_SWITCH_MODE,
+ sfc_kvarg_string_handler, &switch_mode);
+ if (rc != 0)
+ goto fail_kvargs;
+
+ if (switch_mode == NULL) {
+ sa->switchdev = encp->enc_mae_supported &&
+ !encp->enc_datapath_cap_evb;
+ } else if (strcasecmp(switch_mode, SFC_KVARG_SWITCH_MODE_LEGACY) == 0) {
+ sa->switchdev = false;
+ } else if (strcasecmp(switch_mode,
+ SFC_KVARG_SWITCH_MODE_SWITCHDEV) == 0) {
+ sa->switchdev = true;
+ } else {
+ sfc_err(sa, "invalid switch mode device argument '%s'",
+ switch_mode);
+ rc = EINVAL;
+ goto fail_mode;
+ }
+
+ sfc_log_init(sa, "done");
+
+ return 0;
+
+fail_mode:
+fail_kvargs:
+ sfc_log_init(sa, "failed: %s", rte_strerror(rc));
+
+ return rc;
+}
+
static int
sfc_eth_dev_init(struct rte_eth_dev *dev)
{
if (rc != 0)
goto fail_probe;
+ /*
+ * Selecting a default switch mode requires the NIC to be probed and
+ * to have its capabilities filled in.
+ */
+ rc = sfc_parse_switch_mode(sa);
+ if (rc != 0)
+ goto fail_switch_mode;
+
sfc_log_init(sa, "set device ops");
rc = sfc_eth_dev_set_ops(dev);
if (rc != 0)
if (rc != 0)
goto fail_attach;
+ if (sa->switchdev && sa->mae.status != SFC_MAE_STATUS_SUPPORTED) {
+ sfc_err(sa,
+ "failed to enable switchdev mode without MAE support");
+ rc = ENOTSUP;
+ goto fail_switchdev_no_mae;
+ }
+
encp = efx_nic_cfg_get(sa->nic);
/*
sfc_log_init(sa, "done");
return 0;
+fail_switchdev_no_mae:
+ sfc_detach(sa);
+
fail_attach:
sfc_eth_dev_clear_ops(dev);
fail_set_ops:
+fail_switch_mode:
sfc_unprobe(sa);
fail_probe:
RTE_PMD_REGISTER_PCI_TABLE(net_sfc_efx, pci_id_sfc_efx_map);
RTE_PMD_REGISTER_KMOD_DEP(net_sfc_efx, "* igb_uio | uio_pci_generic | vfio-pci");
RTE_PMD_REGISTER_PARAM_STRING(net_sfc_efx,
+ SFC_KVARG_SWITCH_MODE "=" SFC_KVARG_VALUES_SWITCH_MODE " "
SFC_KVARG_RX_DATAPATH "=" SFC_KVARG_VALUES_RX_DATAPATH " "
SFC_KVARG_TX_DATAPATH "=" SFC_KVARG_VALUES_TX_DATAPATH " "
SFC_KVARG_PERF_PROFILE "=" SFC_KVARG_VALUES_PERF_PROFILE " "
struct rte_eth_dev *eth_dev = (sa)->eth_dev;
struct rte_devargs *devargs = eth_dev->device->devargs;
const char **params = (const char *[]){
+ SFC_KVARG_SWITCH_MODE,
SFC_KVARG_STATS_UPDATE_PERIOD_MS,
SFC_KVARG_PERF_PROFILE,
SFC_KVARG_RX_DATAPATH,
#define SFC_KVARG_VALUES_BOOL "[1|y|yes|on|0|n|no|off]"
+#define SFC_KVARG_SWITCH_MODE_LEGACY "legacy"
+#define SFC_KVARG_SWITCH_MODE_SWITCHDEV "switchdev"
+
+#define SFC_KVARG_SWITCH_MODE "switch_mode"
+#define SFC_KVARG_VALUES_SWITCH_MODE \
+ "[" SFC_KVARG_SWITCH_MODE_LEGACY "|" \
+ SFC_KVARG_SWITCH_MODE_SWITCHDEV "]"
+
#define SFC_KVARG_PERF_PROFILE "perf_profile"
#define SFC_KVARG_PERF_PROFILE_AUTO "auto"
sfc_log_init(sa, "entry");
sriov->num_vfs = pci_dev->max_vfs;
- if (sriov->num_vfs == 0)
+ if (sa->switchdev || sriov->num_vfs == 0)
goto done;
vport_config = calloc(sriov->num_vfs + 1, sizeof(*vport_config));
sfc_log_init(sa, "entry");
+ if (sa->switchdev) {
+ sfc_log_init(sa, "don't create vswitch in switchdev mode");
+ goto done;
+ }
+
if (sriov->num_vfs == 0) {
sfc_log_init(sa, "no VFs enabled");
goto done;
sfc_log_init(sa, "entry");
- if (sriov->num_vfs == 0)
+ if (sa->switchdev || sriov->num_vfs == 0)
goto done;
rc = efx_evb_vswitch_destroy(sa->nic, sriov->vswitch);