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);