X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=drivers%2Fnet%2Fsfc%2Fsfc_switch.c;h=c37cdf4a6146dc69427f0c0d8cc551e8c819f904;hb=76fd789cc7dddbaa2c08065b7c3ca915b5c07e7c;hp=395fc4026354e42da1015c5a8715dd9a2e7fa47c;hpb=1e7fbdf0ba196004be49451dbbd85ab28a10d6a4;p=dpdk.git diff --git a/drivers/net/sfc/sfc_switch.c b/drivers/net/sfc/sfc_switch.c index 395fc40263..c37cdf4a61 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 @@ -41,10 +41,22 @@ * This mapping comprises a port type to ensure that RTE switch port ID * of a represented entity and that of its representor are different in * the case when the entity gets plugged into DPDK and not into a guest. + * + * Entry data also comprises RTE ethdev's own MPORT. This value + * coincides with the entity MPORT in the case of independent ports. + * In the case of representors, this ID is not a selector and refers + * to an allocatable object (that is, it's likely to change on RTE + * ethdev replug). Flow API backend must use this value rather + * than entity_mport to support flow rule action PORT_ID. */ struct sfc_mae_switch_port { TAILQ_ENTRY(sfc_mae_switch_port) switch_domain_ports; + /** RTE ethdev MPORT */ + efx_mport_sel_t ethdev_mport; + /** RTE ethdev port ID */ + uint16_t ethdev_port_id; + /** Entity (PCIe function) MPORT selector */ efx_mport_sel_t entity_mport; /** Port type (independent/representor) */ @@ -263,6 +275,9 @@ sfc_mae_assign_switch_port(uint16_t switch_domain_id, TAILQ_INSERT_TAIL(&domain->ports, port, switch_domain_ports); done: + port->ethdev_mport = *req->ethdev_mportp; + port->ethdev_port_id = req->ethdev_port_id; + *switch_port_id = port->id; rte_spinlock_unlock(&sfc_mae_switch.lock); @@ -274,3 +289,46 @@ fail_find_switch_domain_by_id: rte_spinlock_unlock(&sfc_mae_switch.lock); return rc; } + +/* 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, + uint16_t ethdev_port_id, + efx_mport_sel_t *mport_sel) +{ + struct sfc_mae_switch_domain *domain; + struct sfc_mae_switch_port *port; + + SFC_ASSERT(rte_spinlock_is_locked(&sfc_mae_switch.lock)); + + if (ethdev_port_id == RTE_MAX_ETHPORTS) + return EINVAL; + + domain = sfc_mae_find_switch_domain_by_id(switch_domain_id); + if (domain == NULL) + return EINVAL; + + TAILQ_FOREACH(port, &domain->ports, switch_domain_ports) { + if (port->ethdev_port_id == ethdev_port_id) { + *mport_sel = port->ethdev_mport; + return 0; + } + } + + return ENOENT; +} + +int +sfc_mae_switch_port_by_ethdev(uint16_t switch_domain_id, + uint16_t ethdev_port_id, + efx_mport_sel_t *mport_sel) +{ + int rc; + + rte_spinlock_lock(&sfc_mae_switch.lock); + rc = sfc_mae_find_switch_port_by_ethdev(switch_domain_id, + ethdev_port_id, mport_sel); + rte_spinlock_unlock(&sfc_mae_switch.lock); + + return rc; +}