From f6481870eb2fe8bad2f3218c99777490c1450c43 Mon Sep 17 00:00:00 2001 From: Edward Cree Date: Thu, 28 Jul 2022 19:57:46 +0100 Subject: [PATCH] sfc: determine wire m-port at EF100 PF probe time Traffic delivered to the (MAE admin) PF could be from either the wire or a VF. The INGRESS_MPORT field of the RX prefix distinguishes these; base_mport is the value this field will have for traffic from the wire (which should be delivered to the PF's netdevice, not a representor). Signed-off-by: Edward Cree Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/sfc/ef100_nic.c | 37 ++++++++++++++++++++++++++++ drivers/net/ethernet/sfc/ef100_nic.h | 2 ++ drivers/net/ethernet/sfc/mae.c | 10 ++++++++ drivers/net/ethernet/sfc/mae.h | 1 + 4 files changed, 50 insertions(+) diff --git a/drivers/net/ethernet/sfc/ef100_nic.c b/drivers/net/ethernet/sfc/ef100_nic.c index 4625d35269e68..393d6ca4525c4 100644 --- a/drivers/net/ethernet/sfc/ef100_nic.c +++ b/drivers/net/ethernet/sfc/ef100_nic.c @@ -24,6 +24,7 @@ #include "ef100_tx.h" #include "ef100_sriov.h" #include "ef100_netdev.h" +#include "mae.h" #include "rx_common.h" #define EF100_MAX_VIS 4096 @@ -704,6 +705,31 @@ static unsigned int efx_ef100_recycle_ring_size(const struct efx_nic *efx) return 10 * EFX_RECYCLE_RING_SIZE_10G; } +#ifdef CONFIG_SFC_SRIOV +static int efx_ef100_get_base_mport(struct efx_nic *efx) +{ + struct ef100_nic_data *nic_data = efx->nic_data; + u32 selector, id; + int rc; + + /* Construct mport selector for "physical network port" */ + efx_mae_mport_wire(efx, &selector); + /* Look up actual mport ID */ + rc = efx_mae_lookup_mport(efx, selector, &id); + if (rc) + return rc; + /* The ID should always fit in 16 bits, because that's how wide the + * corresponding fields in the RX prefix & TX override descriptor are + */ + if (id >> 16) + netif_warn(efx, probe, efx->net_dev, "Bad base m-port id %#x\n", + id); + nic_data->base_mport = id; + nic_data->have_mport = true; + return 0; +} +#endif + static int compare_versions(const char *a, const char *b) { int a_major, a_minor, a_point, a_patch; @@ -1064,6 +1090,17 @@ int ef100_probe_netdev_pf(struct efx_nic *efx) eth_hw_addr_set(net_dev, net_dev->perm_addr); memcpy(nic_data->port_id, net_dev->perm_addr, ETH_ALEN); + if (!nic_data->grp_mae) + return 0; + +#ifdef CONFIG_SFC_SRIOV + rc = efx_ef100_get_base_mport(efx); + if (rc) { + netif_warn(efx, probe, net_dev, + "Failed to probe base mport rc %d; representors will not function\n", + rc); + } +#endif return 0; fail: diff --git a/drivers/net/ethernet/sfc/ef100_nic.h b/drivers/net/ethernet/sfc/ef100_nic.h index 40f84a2750571..0295933145fa0 100644 --- a/drivers/net/ethernet/sfc/ef100_nic.h +++ b/drivers/net/ethernet/sfc/ef100_nic.h @@ -72,6 +72,8 @@ struct ef100_nic_data { u8 port_id[ETH_ALEN]; DECLARE_BITMAP(evq_phases, EFX_MAX_CHANNELS); u64 stats[EF100_STAT_COUNT]; + u32 base_mport; + bool have_mport; /* base_mport was populated successfully */ bool grp_mae; /* MAE Privilege */ u16 tso_max_hdr_len; u16 tso_max_payload_num_segs; diff --git a/drivers/net/ethernet/sfc/mae.c b/drivers/net/ethernet/sfc/mae.c index 011ebd46ada51..0cbcadde66770 100644 --- a/drivers/net/ethernet/sfc/mae.c +++ b/drivers/net/ethernet/sfc/mae.c @@ -13,6 +13,16 @@ #include "mcdi.h" #include "mcdi_pcol.h" +void efx_mae_mport_wire(struct efx_nic *efx, u32 *out) +{ + efx_dword_t mport; + + EFX_POPULATE_DWORD_2(mport, + MAE_MPORT_SELECTOR_TYPE, MAE_MPORT_SELECTOR_TYPE_PPORT, + MAE_MPORT_SELECTOR_PPORT_ID, efx->port_num); + *out = EFX_DWORD_VAL(mport); +} + void efx_mae_mport_vf(struct efx_nic *efx __always_unused, u32 vf_id, u32 *out) { efx_dword_t mport; diff --git a/drivers/net/ethernet/sfc/mae.h b/drivers/net/ethernet/sfc/mae.h index 27e69e8a54b62..25c2fd94e158d 100644 --- a/drivers/net/ethernet/sfc/mae.h +++ b/drivers/net/ethernet/sfc/mae.h @@ -15,6 +15,7 @@ #include "net_driver.h" +void efx_mae_mport_wire(struct efx_nic *efx, u32 *out); void efx_mae_mport_vf(struct efx_nic *efx, u32 vf_id, u32 *out); int efx_mae_lookup_mport(struct efx_nic *efx, u32 selector, u32 *id); -- 2.39.5