X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fsfc%2Fsfc_switch.c;h=5cd9b46d26a1d3780fc508b900974206721545e2;hb=6ded2e01380e5f3bd48154ca8f23eaad35ffe839;hp=bdea2a2446c80b03dc7352e2a77bb55b94008266;hpb=1fb65e4dae8a5af151bcf8d5bb894a0d3d2c8e52;p=dpdk.git diff --git a/drivers/net/sfc/sfc_switch.c b/drivers/net/sfc/sfc_switch.c index bdea2a2446..5cd9b46d26 100644 --- a/drivers/net/sfc/sfc_switch.c +++ b/drivers/net/sfc/sfc_switch.c @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: BSD-3-Clause * - * Copyright(c) 2019-2020 Xilinx, Inc. + * Copyright(c) 2019-2021 Xilinx, Inc. * Copyright(c) 2019 Solarflare Communications Inc. * * This software was jointly developed between OKTET Labs (under contract @@ -63,6 +63,8 @@ struct sfc_mae_switch_port { enum sfc_mae_switch_port_type type; /** RTE switch port ID */ uint16_t id; + + union sfc_mae_switch_port_data data; }; TAILQ_HEAD(sfc_mae_switch_ports, sfc_mae_switch_port); @@ -87,6 +89,10 @@ struct sfc_mae_switch_domain { struct sfc_mae_switch_ports ports; /** RTE switch domain ID allocated for a group of devices */ uint16_t id; + /** DPDK controller -> EFX interface mapping */ + efx_pcie_interface_t *controllers; + /** Number of DPDK controllers and EFX interfaces */ + size_t nb_controllers; }; TAILQ_HEAD(sfc_mae_switch_domains, sfc_mae_switch_domain); @@ -214,12 +220,117 @@ fail_domain_alloc: fail_mem_alloc: sfc_hw_switch_id_fini(sa, hw_switch_id); - rte_spinlock_unlock(&sfc_mae_switch.lock); fail_hw_switch_id_init: + rte_spinlock_unlock(&sfc_mae_switch.lock); return rc; } +int +sfc_mae_switch_domain_controllers(uint16_t switch_domain_id, + const efx_pcie_interface_t **controllers, + size_t *nb_controllers) +{ + struct sfc_mae_switch_domain *domain; + + if (controllers == NULL || nb_controllers == NULL) + return EINVAL; + + 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; + } + + *controllers = domain->controllers; + *nb_controllers = domain->nb_controllers; + + rte_spinlock_unlock(&sfc_mae_switch.lock); + return 0; +} + +int +sfc_mae_switch_domain_map_controllers(uint16_t switch_domain_id, + efx_pcie_interface_t *controllers, + size_t nb_controllers) +{ + 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; + } + + /* Controller mapping may be set only once */ + if (domain->controllers != NULL) { + rte_spinlock_unlock(&sfc_mae_switch.lock); + return EINVAL; + } + + domain->controllers = controllers; + domain->nb_controllers = nb_controllers; + + rte_spinlock_unlock(&sfc_mae_switch.lock); + return 0; +} + +int +sfc_mae_switch_domain_get_controller(uint16_t switch_domain_id, + efx_pcie_interface_t intf, + int *controller) +{ + const efx_pcie_interface_t *controllers; + size_t nb_controllers; + size_t i; + int rc; + + rc = sfc_mae_switch_domain_controllers(switch_domain_id, &controllers, + &nb_controllers); + if (rc != 0) + return rc; + + if (controllers == NULL) + return ENOENT; + + for (i = 0; i < nb_controllers; i++) { + if (controllers[i] == intf) { + *controller = i; + return 0; + } + } + + return ENOENT; +} + +int sfc_mae_switch_domain_get_intf(uint16_t switch_domain_id, + int controller, + efx_pcie_interface_t *intf) +{ + const efx_pcie_interface_t *controllers; + size_t nb_controllers; + int rc; + + rc = sfc_mae_switch_domain_controllers(switch_domain_id, &controllers, + &nb_controllers); + if (rc != 0) + return rc; + + if (controllers == NULL) + return ENOENT; + + if ((size_t)controller > nb_controllers) + return EINVAL; + + *intf = controllers[controller]; + + return 0; +} + /* This function expects to be called only when the lock is held */ static struct sfc_mae_switch_port * sfc_mae_find_switch_port_by_entity(const struct sfc_mae_switch_domain *domain, @@ -278,6 +389,18 @@ done: port->ethdev_mport = *req->ethdev_mportp; port->ethdev_port_id = req->ethdev_port_id; + switch (req->type) { + case SFC_MAE_SWITCH_PORT_INDEPENDENT: + /* No data */ + break; + case SFC_MAE_SWITCH_PORT_REPRESENTOR: + memcpy(&port->data.repr, &req->port_data, + sizeof(port->data.repr)); + break; + default: + SFC_ASSERT(B_FALSE); + } + *switch_port_id = port->id; rte_spinlock_unlock(&sfc_mae_switch.lock);