Skip to content

Commit

Permalink
Merge branch 'sfc-vf-representors-for-ef100-rx-side'
Browse files Browse the repository at this point in the history
Edward Cree says:

====================
sfc: VF representors for EF100 - RX side

This series adds the receive path for EF100 VF representors, plus other
 minor features such as statistics.
====================

Link: https://lore.kernel.org/r/cover.1659034549.git.ecree.xilinx@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Jakub Kicinski committed Jul 30, 2022
2 parents 7193084 + 7267aa6 commit ed3849e
Show file tree
Hide file tree
Showing 22 changed files with 1,085 additions and 49 deletions.
3 changes: 2 additions & 1 deletion drivers/net/ethernet/sfc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ sfc-y += efx.o efx_common.o efx_channels.o nic.o \
ef100.o ef100_nic.o ef100_netdev.o \
ef100_ethtool.o ef100_rx.o ef100_tx.o
sfc-$(CONFIG_SFC_MTD) += mtd.o
sfc-$(CONFIG_SFC_SRIOV) += sriov.o ef10_sriov.o ef100_sriov.o ef100_rep.o mae.o
sfc-$(CONFIG_SFC_SRIOV) += sriov.o ef10_sriov.o ef100_sriov.o ef100_rep.o \
mae.o tc.o

obj-$(CONFIG_SFC) += sfc.o

Expand Down
26 changes: 15 additions & 11 deletions drivers/net/ethernet/sfc/ef10.c
Original file line number Diff line number Diff line change
Expand Up @@ -2538,23 +2538,33 @@ static int efx_ef10_filter_table_probe(struct efx_nic *efx)

if (rc)
return rc;
down_write(&efx->filter_sem);
rc = efx_mcdi_filter_table_probe(efx, nic_data->workaround_26807);

if (rc)
return rc;
goto out_unlock;

list_for_each_entry(vlan, &nic_data->vlan_list, list) {
rc = efx_mcdi_filter_add_vlan(efx, vlan->vid);
if (rc)
goto fail_add_vlan;
}
return 0;
goto out_unlock;

fail_add_vlan:
efx_mcdi_filter_table_remove(efx);
out_unlock:
up_write(&efx->filter_sem);
return rc;
}

static void efx_ef10_filter_table_remove(struct efx_nic *efx)
{
down_write(&efx->filter_sem);
efx_mcdi_filter_table_remove(efx);
up_write(&efx->filter_sem);
}

/* This creates an entry in the RX descriptor queue */
static inline void
efx_ef10_build_rx_desc(struct efx_rx_queue *rx_queue, unsigned int index)
Expand Down Expand Up @@ -3211,9 +3221,7 @@ static int efx_ef10_vport_set_mac_address(struct efx_nic *efx)

efx_device_detach_sync(efx);
efx_net_stop(efx->net_dev);
down_write(&efx->filter_sem);
efx_mcdi_filter_table_remove(efx);
up_write(&efx->filter_sem);
efx_ef10_filter_table_remove(efx);

rc = efx_ef10_vadaptor_free(efx, efx->vport_id);
if (rc)
Expand Down Expand Up @@ -3243,9 +3251,7 @@ static int efx_ef10_vport_set_mac_address(struct efx_nic *efx)
if (rc2)
goto reset_nic;
restore_filters:
down_write(&efx->filter_sem);
rc2 = efx_ef10_filter_table_probe(efx);
up_write(&efx->filter_sem);
if (rc2)
goto reset_nic;

Expand Down Expand Up @@ -3275,8 +3281,7 @@ static int efx_ef10_set_mac_address(struct efx_nic *efx)
efx_net_stop(efx->net_dev);

mutex_lock(&efx->mac_lock);
down_write(&efx->filter_sem);
efx_mcdi_filter_table_remove(efx);
efx_ef10_filter_table_remove(efx);

ether_addr_copy(MCDI_PTR(inbuf, VADAPTOR_SET_MAC_IN_MACADDR),
efx->net_dev->dev_addr);
Expand All @@ -3286,7 +3291,6 @@ static int efx_ef10_set_mac_address(struct efx_nic *efx)
sizeof(inbuf), NULL, 0, NULL);

efx_ef10_filter_table_probe(efx);
up_write(&efx->filter_sem);
mutex_unlock(&efx->mac_lock);

if (was_enabled)
Expand Down Expand Up @@ -4092,7 +4096,7 @@ const struct efx_nic_type efx_hunt_a0_vf_nic_type = {
.ev_test_generate = efx_ef10_ev_test_generate,
.filter_table_probe = efx_ef10_filter_table_probe,
.filter_table_restore = efx_mcdi_filter_table_restore,
.filter_table_remove = efx_mcdi_filter_table_remove,
.filter_table_remove = efx_ef10_filter_table_remove,
.filter_update_rx_scatter = efx_mcdi_update_rx_scatter,
.filter_insert = efx_mcdi_filter_insert,
.filter_remove_safe = efx_mcdi_filter_remove_safe,
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/ethernet/sfc/ef100.c
Original file line number Diff line number Diff line change
Expand Up @@ -431,6 +431,9 @@ static void ef100_pci_remove(struct pci_dev *pci_dev)

probe_data = container_of(efx, struct efx_probe_data, efx);
ef100_remove_netdev(probe_data);
#ifdef CONFIG_SFC_SRIOV
efx_fini_struct_tc(efx);
#endif

ef100_remove(efx);
efx_fini_io(efx);
Expand Down
4 changes: 4 additions & 0 deletions drivers/net/ethernet/sfc/ef100_netdev.c
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,10 @@ void ef100_remove_netdev(struct efx_probe_data *probe_data)

ef100_unregister_netdev(efx);

#ifdef CONFIG_SFC_SRIOV
efx_fini_tc(efx);
#endif

down_write(&efx->filter_sem);
efx_mcdi_filter_table_remove(efx);
up_write(&efx->filter_sem);
Expand Down
91 changes: 83 additions & 8 deletions drivers/net/ethernet/sfc/ef100_nic.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
#include "ef100_tx.h"
#include "ef100_sriov.h"
#include "ef100_netdev.h"
#include "tc.h"
#include "mae.h"
#include "rx_common.h"

#define EF100_MAX_VIS 4096
Expand Down Expand Up @@ -374,26 +376,46 @@ static int ef100_filter_table_up(struct efx_nic *efx)
{
int rc;

down_write(&efx->filter_sem);
rc = efx_mcdi_filter_add_vlan(efx, EFX_FILTER_VID_UNSPEC);
if (rc) {
efx_mcdi_filter_table_down(efx);
return rc;
}
if (rc)
goto fail_unspec;

rc = efx_mcdi_filter_add_vlan(efx, 0);
if (rc) {
efx_mcdi_filter_del_vlan(efx, EFX_FILTER_VID_UNSPEC);
efx_mcdi_filter_table_down(efx);
}
if (rc)
goto fail_vlan0;
/* Drop the lock: we've finished altering table existence, and
* filter insertion will need to take the lock for read.
*/
up_write(&efx->filter_sem);
#ifdef CONFIG_SFC_SRIOV
rc = efx_tc_insert_rep_filters(efx);
/* Rep filter failure is nonfatal */
if (rc)
netif_warn(efx, drv, efx->net_dev,
"Failed to insert representor filters, rc %d\n",
rc);
#endif
return 0;

fail_vlan0:
efx_mcdi_filter_del_vlan(efx, EFX_FILTER_VID_UNSPEC);
fail_unspec:
efx_mcdi_filter_table_down(efx);
up_write(&efx->filter_sem);
return rc;
}

static void ef100_filter_table_down(struct efx_nic *efx)
{
#ifdef CONFIG_SFC_SRIOV
efx_tc_remove_rep_filters(efx);
#endif
down_write(&efx->filter_sem);
efx_mcdi_filter_del_vlan(efx, 0);
efx_mcdi_filter_del_vlan(efx, EFX_FILTER_VID_UNSPEC);
efx_mcdi_filter_table_down(efx);
up_write(&efx->filter_sem);
}

/* Other
Expand Down Expand Up @@ -704,6 +726,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;
Expand Down Expand Up @@ -1064,6 +1111,34 @@ 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_init_struct_tc(efx);
if (rc)
return rc;

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

rc = efx_init_tc(efx);
if (rc) {
/* Either we don't have an MAE at all (i.e. legacy v-switching),
* or we do but we failed to probe it. In the latter case, we
* may not have set up default rules, in which case we won't be
* able to pass any traffic. However, we don't fail the probe,
* because the user might need to use the netdevice to apply
* configuration changes to fix whatever's wrong with the MAE.
*/
netif_warn(efx, probe, net_dev, "Failed to probe MAE rc %d\n",
rc);
}
#endif
return 0;

fail:
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/sfc/ef100_nic.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Loading

0 comments on commit ed3849e

Please sign in to comment.