Skip to content

Commit ed3849e

Browse files
committed
Merge branch 'sfc-vf-representors-for-ef100-rx-side'
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/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents 7193084 + 7267aa6 commit ed3849e

22 files changed

+1085
-49
lines changed

drivers/net/ethernet/sfc/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ sfc-y += efx.o efx_common.o efx_channels.o nic.o \
88
ef100.o ef100_nic.o ef100_netdev.o \
99
ef100_ethtool.o ef100_rx.o ef100_tx.o
1010
sfc-$(CONFIG_SFC_MTD) += mtd.o
11-
sfc-$(CONFIG_SFC_SRIOV) += sriov.o ef10_sriov.o ef100_sriov.o ef100_rep.o mae.o
11+
sfc-$(CONFIG_SFC_SRIOV) += sriov.o ef10_sriov.o ef100_sriov.o ef100_rep.o \
12+
mae.o tc.o
1213

1314
obj-$(CONFIG_SFC) += sfc.o
1415

drivers/net/ethernet/sfc/ef10.c

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2538,23 +2538,33 @@ static int efx_ef10_filter_table_probe(struct efx_nic *efx)
25382538

25392539
if (rc)
25402540
return rc;
2541+
down_write(&efx->filter_sem);
25412542
rc = efx_mcdi_filter_table_probe(efx, nic_data->workaround_26807);
25422543

25432544
if (rc)
2544-
return rc;
2545+
goto out_unlock;
25452546

25462547
list_for_each_entry(vlan, &nic_data->vlan_list, list) {
25472548
rc = efx_mcdi_filter_add_vlan(efx, vlan->vid);
25482549
if (rc)
25492550
goto fail_add_vlan;
25502551
}
2551-
return 0;
2552+
goto out_unlock;
25522553

25532554
fail_add_vlan:
25542555
efx_mcdi_filter_table_remove(efx);
2556+
out_unlock:
2557+
up_write(&efx->filter_sem);
25552558
return rc;
25562559
}
25572560

2561+
static void efx_ef10_filter_table_remove(struct efx_nic *efx)
2562+
{
2563+
down_write(&efx->filter_sem);
2564+
efx_mcdi_filter_table_remove(efx);
2565+
up_write(&efx->filter_sem);
2566+
}
2567+
25582568
/* This creates an entry in the RX descriptor queue */
25592569
static inline void
25602570
efx_ef10_build_rx_desc(struct efx_rx_queue *rx_queue, unsigned int index)
@@ -3211,9 +3221,7 @@ static int efx_ef10_vport_set_mac_address(struct efx_nic *efx)
32113221

32123222
efx_device_detach_sync(efx);
32133223
efx_net_stop(efx->net_dev);
3214-
down_write(&efx->filter_sem);
3215-
efx_mcdi_filter_table_remove(efx);
3216-
up_write(&efx->filter_sem);
3224+
efx_ef10_filter_table_remove(efx);
32173225

32183226
rc = efx_ef10_vadaptor_free(efx, efx->vport_id);
32193227
if (rc)
@@ -3243,9 +3251,7 @@ static int efx_ef10_vport_set_mac_address(struct efx_nic *efx)
32433251
if (rc2)
32443252
goto reset_nic;
32453253
restore_filters:
3246-
down_write(&efx->filter_sem);
32473254
rc2 = efx_ef10_filter_table_probe(efx);
3248-
up_write(&efx->filter_sem);
32493255
if (rc2)
32503256
goto reset_nic;
32513257

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

32773283
mutex_lock(&efx->mac_lock);
3278-
down_write(&efx->filter_sem);
3279-
efx_mcdi_filter_table_remove(efx);
3284+
efx_ef10_filter_table_remove(efx);
32803285

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

32883293
efx_ef10_filter_table_probe(efx);
3289-
up_write(&efx->filter_sem);
32903294
mutex_unlock(&efx->mac_lock);
32913295

32923296
if (was_enabled)
@@ -4092,7 +4096,7 @@ const struct efx_nic_type efx_hunt_a0_vf_nic_type = {
40924096
.ev_test_generate = efx_ef10_ev_test_generate,
40934097
.filter_table_probe = efx_ef10_filter_table_probe,
40944098
.filter_table_restore = efx_mcdi_filter_table_restore,
4095-
.filter_table_remove = efx_mcdi_filter_table_remove,
4099+
.filter_table_remove = efx_ef10_filter_table_remove,
40964100
.filter_update_rx_scatter = efx_mcdi_update_rx_scatter,
40974101
.filter_insert = efx_mcdi_filter_insert,
40984102
.filter_remove_safe = efx_mcdi_filter_remove_safe,

drivers/net/ethernet/sfc/ef100.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,9 @@ static void ef100_pci_remove(struct pci_dev *pci_dev)
431431

432432
probe_data = container_of(efx, struct efx_probe_data, efx);
433433
ef100_remove_netdev(probe_data);
434+
#ifdef CONFIG_SFC_SRIOV
435+
efx_fini_struct_tc(efx);
436+
#endif
434437

435438
ef100_remove(efx);
436439
efx_fini_io(efx);

drivers/net/ethernet/sfc/ef100_netdev.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,10 @@ void ef100_remove_netdev(struct efx_probe_data *probe_data)
329329

330330
ef100_unregister_netdev(efx);
331331

332+
#ifdef CONFIG_SFC_SRIOV
333+
efx_fini_tc(efx);
334+
#endif
335+
332336
down_write(&efx->filter_sem);
333337
efx_mcdi_filter_table_remove(efx);
334338
up_write(&efx->filter_sem);

drivers/net/ethernet/sfc/ef100_nic.c

Lines changed: 83 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
#include "ef100_tx.h"
2525
#include "ef100_sriov.h"
2626
#include "ef100_netdev.h"
27+
#include "tc.h"
28+
#include "mae.h"
2729
#include "rx_common.h"
2830

2931
#define EF100_MAX_VIS 4096
@@ -374,26 +376,46 @@ static int ef100_filter_table_up(struct efx_nic *efx)
374376
{
375377
int rc;
376378

379+
down_write(&efx->filter_sem);
377380
rc = efx_mcdi_filter_add_vlan(efx, EFX_FILTER_VID_UNSPEC);
378-
if (rc) {
379-
efx_mcdi_filter_table_down(efx);
380-
return rc;
381-
}
381+
if (rc)
382+
goto fail_unspec;
382383

383384
rc = efx_mcdi_filter_add_vlan(efx, 0);
384-
if (rc) {
385-
efx_mcdi_filter_del_vlan(efx, EFX_FILTER_VID_UNSPEC);
386-
efx_mcdi_filter_table_down(efx);
387-
}
385+
if (rc)
386+
goto fail_vlan0;
387+
/* Drop the lock: we've finished altering table existence, and
388+
* filter insertion will need to take the lock for read.
389+
*/
390+
up_write(&efx->filter_sem);
391+
#ifdef CONFIG_SFC_SRIOV
392+
rc = efx_tc_insert_rep_filters(efx);
393+
/* Rep filter failure is nonfatal */
394+
if (rc)
395+
netif_warn(efx, drv, efx->net_dev,
396+
"Failed to insert representor filters, rc %d\n",
397+
rc);
398+
#endif
399+
return 0;
388400

401+
fail_vlan0:
402+
efx_mcdi_filter_del_vlan(efx, EFX_FILTER_VID_UNSPEC);
403+
fail_unspec:
404+
efx_mcdi_filter_table_down(efx);
405+
up_write(&efx->filter_sem);
389406
return rc;
390407
}
391408

392409
static void ef100_filter_table_down(struct efx_nic *efx)
393410
{
411+
#ifdef CONFIG_SFC_SRIOV
412+
efx_tc_remove_rep_filters(efx);
413+
#endif
414+
down_write(&efx->filter_sem);
394415
efx_mcdi_filter_del_vlan(efx, 0);
395416
efx_mcdi_filter_del_vlan(efx, EFX_FILTER_VID_UNSPEC);
396417
efx_mcdi_filter_table_down(efx);
418+
up_write(&efx->filter_sem);
397419
}
398420

399421
/* Other
@@ -704,6 +726,31 @@ static unsigned int efx_ef100_recycle_ring_size(const struct efx_nic *efx)
704726
return 10 * EFX_RECYCLE_RING_SIZE_10G;
705727
}
706728

729+
#ifdef CONFIG_SFC_SRIOV
730+
static int efx_ef100_get_base_mport(struct efx_nic *efx)
731+
{
732+
struct ef100_nic_data *nic_data = efx->nic_data;
733+
u32 selector, id;
734+
int rc;
735+
736+
/* Construct mport selector for "physical network port" */
737+
efx_mae_mport_wire(efx, &selector);
738+
/* Look up actual mport ID */
739+
rc = efx_mae_lookup_mport(efx, selector, &id);
740+
if (rc)
741+
return rc;
742+
/* The ID should always fit in 16 bits, because that's how wide the
743+
* corresponding fields in the RX prefix & TX override descriptor are
744+
*/
745+
if (id >> 16)
746+
netif_warn(efx, probe, efx->net_dev, "Bad base m-port id %#x\n",
747+
id);
748+
nic_data->base_mport = id;
749+
nic_data->have_mport = true;
750+
return 0;
751+
}
752+
#endif
753+
707754
static int compare_versions(const char *a, const char *b)
708755
{
709756
int a_major, a_minor, a_point, a_patch;
@@ -1064,6 +1111,34 @@ int ef100_probe_netdev_pf(struct efx_nic *efx)
10641111
eth_hw_addr_set(net_dev, net_dev->perm_addr);
10651112
memcpy(nic_data->port_id, net_dev->perm_addr, ETH_ALEN);
10661113

1114+
if (!nic_data->grp_mae)
1115+
return 0;
1116+
1117+
#ifdef CONFIG_SFC_SRIOV
1118+
rc = efx_init_struct_tc(efx);
1119+
if (rc)
1120+
return rc;
1121+
1122+
rc = efx_ef100_get_base_mport(efx);
1123+
if (rc) {
1124+
netif_warn(efx, probe, net_dev,
1125+
"Failed to probe base mport rc %d; representors will not function\n",
1126+
rc);
1127+
}
1128+
1129+
rc = efx_init_tc(efx);
1130+
if (rc) {
1131+
/* Either we don't have an MAE at all (i.e. legacy v-switching),
1132+
* or we do but we failed to probe it. In the latter case, we
1133+
* may not have set up default rules, in which case we won't be
1134+
* able to pass any traffic. However, we don't fail the probe,
1135+
* because the user might need to use the netdevice to apply
1136+
* configuration changes to fix whatever's wrong with the MAE.
1137+
*/
1138+
netif_warn(efx, probe, net_dev, "Failed to probe MAE rc %d\n",
1139+
rc);
1140+
}
1141+
#endif
10671142
return 0;
10681143

10691144
fail:

drivers/net/ethernet/sfc/ef100_nic.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ struct ef100_nic_data {
7272
u8 port_id[ETH_ALEN];
7373
DECLARE_BITMAP(evq_phases, EFX_MAX_CHANNELS);
7474
u64 stats[EF100_STAT_COUNT];
75+
u32 base_mport;
76+
bool have_mport; /* base_mport was populated successfully */
7577
bool grp_mae; /* MAE Privilege */
7678
u16 tso_max_hdr_len;
7779
u16 tso_max_payload_num_segs;

0 commit comments

Comments
 (0)