[PATCH net-next v2 04/14] sfc: determine wire m-port at EF100 PF probe time
From: <hidden>
Date: 2022-07-27 18:51:10
Subsystem:
networking drivers, sfc network driver, the rest · Maintainers:
Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Edward Cree, Linus Torvalds
From: Edward Cree <ecree.xilinx@gmail.com> 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 <ecree.xilinx@gmail.com> --- 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 4625d35269e6..393d6ca4525c 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 40f84a275057..0295933145fa 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 011ebd46ada5..0cbcadde6677 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 27e69e8a54b6..25c2fd94e158 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);