From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id D34FDA034F; Mon, 11 Oct 2021 16:49:32 +0200 (CEST) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id A1D3A410FA; Mon, 11 Oct 2021 16:49:18 +0200 (CEST) Received: from shelob.oktetlabs.ru (shelob.oktetlabs.ru [91.220.146.113]) by mails.dpdk.org (Postfix) with ESMTP id 4A29E410E8 for ; Mon, 11 Oct 2021 16:49:15 +0200 (CEST) Received: by shelob.oktetlabs.ru (Postfix, from userid 122) id 050B07F721; Mon, 11 Oct 2021 17:49:15 +0300 (MSK) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on shelob.oktetlabs.ru X-Spam-Level: X-Spam-Status: No, score=0.8 required=5.0 tests=ALL_TRUSTED, DKIM_ADSP_DISCARD, URIBL_BLOCKED autolearn=no autolearn_force=no version=3.4.2 Received: from aros.oktetlabs.ru (aros.oktetlabs.ru [192.168.38.17]) by shelob.oktetlabs.ru (Postfix) with ESMTP id 42BE57F6F4; Mon, 11 Oct 2021 17:49:07 +0300 (MSK) DKIM-Filter: OpenDKIM Filter v2.11.0 shelob.oktetlabs.ru 42BE57F6F4 Authentication-Results: shelob.oktetlabs.ru/42BE57F6F4; dkim=none; dkim-atps=neutral From: Andrew Rybchenko To: dev@dpdk.org Cc: Igor Romanov , Andy Moreton , Ivan Malov Date: Mon, 11 Oct 2021 17:48:22 +0300 Message-Id: <20211011144857.446802-4-andrew.rybchenko@oktetlabs.ru> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20211011144857.446802-1-andrew.rybchenko@oktetlabs.ru> References: <20210827065717.1838258-1-andrew.rybchenko@oktetlabs.ru> <20211011144857.446802-1-andrew.rybchenko@oktetlabs.ru> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [dpdk-dev] [PATCH v2 03/38] net/sfc: add switch mode device argument X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dev-bounces@dpdk.org Sender: "dev" From: Igor Romanov Add the argument that allows user to choose either switchdev or legacy mode. Legacy mode enables switching by using Ethernet virtual bridging (EVB) API. In switchdev mode, VF traffic goes via port representor (if any) on PF, and software virtual switch (for example, Open vSwitch) steers the traffic. Signed-off-by: Igor Romanov Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton Reviewed-by: Ivan Malov --- doc/guides/nics/sfc_efx.rst | 13 ++++++++ drivers/net/sfc/sfc.h | 2 ++ drivers/net/sfc/sfc_ethdev.c | 60 ++++++++++++++++++++++++++++++++++++ drivers/net/sfc/sfc_kvargs.c | 1 + drivers/net/sfc/sfc_kvargs.h | 8 +++++ drivers/net/sfc/sfc_sriov.c | 9 ++++-- 6 files changed, 91 insertions(+), 2 deletions(-) diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst index 163bc2533f..d66cb76dab 100644 --- a/doc/guides/nics/sfc_efx.rst +++ b/doc/guides/nics/sfc_efx.rst @@ -371,6 +371,19 @@ boolean parameters value. 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. diff --git a/drivers/net/sfc/sfc.h b/drivers/net/sfc/sfc.h index 331e06bac6..b045baca9e 100644 --- a/drivers/net/sfc/sfc.h +++ b/drivers/net/sfc/sfc.h @@ -313,6 +313,8 @@ struct sfc_adapter { boolean_t tso_encap; uint32_t rxd_wait_timeout_ns; + + bool switchdev; }; static inline struct sfc_adapter_shared * diff --git a/drivers/net/sfc/sfc_ethdev.c b/drivers/net/sfc/sfc_ethdev.c index 9dc5e5b3a3..b353bfe358 100644 --- a/drivers/net/sfc/sfc_ethdev.c +++ b/drivers/net/sfc/sfc_ethdev.c @@ -2189,6 +2189,46 @@ sfc_register_dp(void) } } +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) { @@ -2276,6 +2316,14 @@ 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) @@ -2286,6 +2334,13 @@ sfc_eth_dev_init(struct rte_eth_dev *dev) 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); /* @@ -2300,10 +2355,14 @@ sfc_eth_dev_init(struct rte_eth_dev *dev) 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: @@ -2371,6 +2430,7 @@ RTE_PMD_REGISTER_PCI(net_sfc_efx, sfc_efx_pmd); 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 " " diff --git a/drivers/net/sfc/sfc_kvargs.c b/drivers/net/sfc/sfc_kvargs.c index 974c05e68e..cd16213637 100644 --- a/drivers/net/sfc/sfc_kvargs.c +++ b/drivers/net/sfc/sfc_kvargs.c @@ -22,6 +22,7 @@ sfc_kvargs_parse(struct sfc_adapter *sa) 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, diff --git a/drivers/net/sfc/sfc_kvargs.h b/drivers/net/sfc/sfc_kvargs.h index ff76e7d9fc..8e34ec92a2 100644 --- a/drivers/net/sfc/sfc_kvargs.h +++ b/drivers/net/sfc/sfc_kvargs.h @@ -18,6 +18,14 @@ extern "C" { #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" diff --git a/drivers/net/sfc/sfc_sriov.c b/drivers/net/sfc/sfc_sriov.c index baa0242433..385b172e2e 100644 --- a/drivers/net/sfc/sfc_sriov.c +++ b/drivers/net/sfc/sfc_sriov.c @@ -53,7 +53,7 @@ sfc_sriov_attach(struct sfc_adapter *sa) 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)); @@ -110,6 +110,11 @@ sfc_sriov_vswitch_create(struct sfc_adapter *sa) 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; @@ -152,7 +157,7 @@ sfc_sriov_vswitch_destroy(struct sfc_adapter *sa) 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); -- 2.30.2