From 26706314d4188d7073a40d62019b3d85f1492494 Mon Sep 17 00:00:00 2001 From: Viacheslav Galaktionov Date: Fri, 15 Oct 2021 09:49:03 +0300 Subject: [PATCH] net/sfc: implement transfer proxy port callback In sfc, MAE admin serves as a transfer proxy. In order to track which ethdev is privileged, augment every independent switch port structure with information about its MAE privilege. Signed-off-by: Viacheslav Galaktionov Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton --- doc/guides/rel_notes/release_21_11.rst | 1 + drivers/net/sfc/sfc.c | 4 ++ drivers/net/sfc/sfc_flow.c | 21 ++++++++ drivers/net/sfc/sfc_mae.c | 2 + drivers/net/sfc/sfc_switch.c | 68 ++++++++++++++++++++++++-- drivers/net/sfc/sfc_switch.h | 11 +++++ 6 files changed, 104 insertions(+), 3 deletions(-) diff --git a/doc/guides/rel_notes/release_21_11.rst b/doc/guides/rel_notes/release_21_11.rst index 3129741841..9e58466f35 100644 --- a/doc/guides/rel_notes/release_21_11.rst +++ b/doc/guides/rel_notes/release_21_11.rst @@ -152,6 +152,7 @@ New Features Updated the Solarflare ``sfc_efx`` driver with changes including: * Added port representors support on SN1000 SmartNICs + * Added flow API transfer proxy support * **Updated Marvell cnxk crypto PMD.** diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c index f79f4d5ffc..431c42f508 100644 --- a/drivers/net/sfc/sfc.c +++ b/drivers/net/sfc/sfc.c @@ -25,6 +25,7 @@ #include "sfc_kvargs.h" #include "sfc_tweak.h" #include "sfc_sw_stats.h" +#include "sfc_switch.h" bool sfc_repr_supported(const struct sfc_adapter *sa) @@ -1329,6 +1330,9 @@ sfc_unprobe(struct sfc_adapter *sa) */ rte_eal_alarm_cancel(sfc_restart_if_required, sa); + sfc_mae_clear_switch_port(sa->mae.switch_domain_id, + sa->mae.switch_port_id); + sfc_log_init(sa, "destroy nic"); sa->nic = NULL; efx_nic_destroy(enp); diff --git a/drivers/net/sfc/sfc_flow.c b/drivers/net/sfc/sfc_flow.c index d57235f358..8096af5673 100644 --- a/drivers/net/sfc/sfc_flow.c +++ b/drivers/net/sfc/sfc_flow.c @@ -26,6 +26,7 @@ #include "sfc_log.h" #include "sfc_dp_rx.h" #include "sfc_mae_counter.h" +#include "sfc_switch.h" struct sfc_flow_ops_by_spec { sfc_flow_parse_cb_t *parse; @@ -2924,6 +2925,25 @@ sfc_flow_isolate(struct rte_eth_dev *dev, int enable, return ret; } +static int +sfc_flow_pick_transfer_proxy(struct rte_eth_dev *dev, + uint16_t *transfer_proxy_port, + struct rte_flow_error *error) +{ + struct sfc_adapter *sa = sfc_adapter_by_eth_dev(dev); + int ret; + + ret = sfc_mae_get_switch_domain_admin(sa->mae.switch_domain_id, + transfer_proxy_port); + if (ret != 0) { + return rte_flow_error_set(error, ret, + RTE_FLOW_ERROR_TYPE_UNSPECIFIED, + NULL, NULL); + } + + return 0; +} + const struct rte_flow_ops sfc_flow_ops = { .validate = sfc_flow_validate, .create = sfc_flow_create, @@ -2936,6 +2956,7 @@ const struct rte_flow_ops sfc_flow_ops = { .tunnel_action_decap_release = sfc_flow_tunnel_action_decap_release, .tunnel_item_release = sfc_flow_tunnel_item_release, .get_restore_info = sfc_flow_tunnel_get_restore_info, + .pick_transfer_proxy = sfc_flow_pick_transfer_proxy, }; void diff --git a/drivers/net/sfc/sfc_mae.c b/drivers/net/sfc/sfc_mae.c index 6a1385283b..455744c570 100644 --- a/drivers/net/sfc/sfc_mae.c +++ b/drivers/net/sfc/sfc_mae.c @@ -234,6 +234,8 @@ sfc_mae_attach(struct sfc_adapter *sa) /* RTE ethdev MPORT matches that of the entity for independent ports. */ switch_port_request.ethdev_mportp = &entity_mport; switch_port_request.ethdev_port_id = sas->port_id; + switch_port_request.port_data.indep.mae_admin = + encp->enc_mae_admin == B_TRUE; rc = sfc_mae_assign_switch_port(mae->switch_domain_id, &switch_port_request, &mae->switch_port_id); diff --git a/drivers/net/sfc/sfc_switch.c b/drivers/net/sfc/sfc_switch.c index dc5b9a676c..a28e861de5 100644 --- a/drivers/net/sfc/sfc_switch.c +++ b/drivers/net/sfc/sfc_switch.c @@ -93,6 +93,8 @@ struct sfc_mae_switch_domain { efx_pcie_interface_t *controllers; /** Number of DPDK controllers and EFX interfaces */ size_t nb_controllers; + /** MAE admin port */ + struct sfc_mae_switch_port *mae_admin_port; }; TAILQ_HEAD(sfc_mae_switch_domains, sfc_mae_switch_domain); @@ -454,13 +456,17 @@ done: port->ethdev_mport = *req->ethdev_mportp; port->ethdev_port_id = req->ethdev_port_id; + memcpy(&port->data, &req->port_data, + sizeof(port->data)); + switch (req->type) { case SFC_MAE_SWITCH_PORT_INDEPENDENT: - /* No data */ + if (port->data.indep.mae_admin) { + SFC_ASSERT(domain->mae_admin_port == NULL); + domain->mae_admin_port = port; + } break; case SFC_MAE_SWITCH_PORT_REPRESENTOR: - memcpy(&port->data.repr, &req->port_data, - sizeof(port->data.repr)); break; default: SFC_ASSERT(B_FALSE); @@ -478,6 +484,30 @@ fail_find_switch_domain_by_id: return rc; } +int +sfc_mae_clear_switch_port(uint16_t switch_domain_id, + uint16_t switch_port_id) +{ + struct sfc_mae_switch_domain *domain; + + rte_spinlock_lock(&sfc_mae_switch.lock); + + domain = sfc_mae_find_switch_domain_by_id(switch_domain_id); + if (domain == NULL) { + rte_spinlock_unlock(&sfc_mae_switch.lock); + return EINVAL; + } + + if (domain->mae_admin_port != NULL && + domain->mae_admin_port->id == switch_port_id) { + domain->mae_admin_port->data.indep.mae_admin = B_FALSE; + domain->mae_admin_port = NULL; + } + + rte_spinlock_unlock(&sfc_mae_switch.lock); + return 0; +} + /* This function expects to be called only when the lock is held */ static int sfc_mae_find_switch_port_by_ethdev(uint16_t switch_domain_id, @@ -537,3 +567,35 @@ sfc_mae_switch_port_id_by_entity(uint16_t switch_domain_id, return rc; } + +static int +sfc_mae_get_switch_domain_admin_locked(uint16_t switch_domain_id, + uint16_t *port_id) +{ + struct sfc_mae_switch_domain *domain; + + SFC_ASSERT(rte_spinlock_is_locked(&sfc_mae_switch.lock)); + + domain = sfc_mae_find_switch_domain_by_id(switch_domain_id); + if (domain == NULL) + return EINVAL; + + if (domain->mae_admin_port != NULL) { + *port_id = domain->mae_admin_port->ethdev_port_id; + return 0; + } + + return ENOENT; +} + +int +sfc_mae_get_switch_domain_admin(uint16_t switch_domain_id, + uint16_t *port_id) +{ + int rc; + + rte_spinlock_lock(&sfc_mae_switch.lock); + rc = sfc_mae_get_switch_domain_admin_locked(switch_domain_id, port_id); + rte_spinlock_unlock(&sfc_mae_switch.lock); + return rc; +} diff --git a/drivers/net/sfc/sfc_switch.h b/drivers/net/sfc/sfc_switch.h index a77d2e6f28..7917141038 100644 --- a/drivers/net/sfc/sfc_switch.h +++ b/drivers/net/sfc/sfc_switch.h @@ -34,6 +34,10 @@ enum sfc_mae_switch_port_type { SFC_MAE_SWITCH_PORT_REPRESENTOR, }; +struct sfc_mae_switch_port_indep_data { + bool mae_admin; +}; + struct sfc_mae_switch_port_repr_data { efx_pcie_interface_t intf; uint16_t pf; @@ -41,6 +45,7 @@ struct sfc_mae_switch_port_repr_data { }; union sfc_mae_switch_port_data { + struct sfc_mae_switch_port_indep_data indep; struct sfc_mae_switch_port_repr_data repr; }; @@ -94,6 +99,9 @@ int sfc_mae_assign_switch_port(uint16_t switch_domain_id, const struct sfc_mae_switch_port_request *req, uint16_t *switch_port_id); +int sfc_mae_clear_switch_port(uint16_t switch_domain_id, + uint16_t switch_port_id); + int sfc_mae_switch_port_by_ethdev(uint16_t switch_domain_id, uint16_t ethdev_port_id, efx_mport_sel_t *mport_sel); @@ -103,6 +111,9 @@ int sfc_mae_switch_port_id_by_entity(uint16_t switch_domain_id, enum sfc_mae_switch_port_type type, uint16_t *switch_port_id); +int sfc_mae_get_switch_domain_admin(uint16_t switch_domain_id, + uint16_t *port_id); + #ifdef __cplusplus } #endif -- 2.20.1