From e37f3b1561a038c0630e7364740d6d55f2b5d5b5 Mon Sep 17 00:00:00 2001 From: Edward Cree Date: Thu, 28 Jul 2022 19:57:51 +0100 Subject: sfc: use a dynamic m-port for representor RX and set it promisc Representors do not want to be subject to the PF's Ethernet address filters, since traffic from VFs will typically have a destination either elsewhere on the link segment or on an overlay network. So, create a dynamic m-port with promiscuous and all-multicast filters, and set it as the egress port of representor default rules. Since the m-port is an alias of the calling PF's own m-port, traffic will still be delivered to the PF's RXQs, but it will be subject to the VNRX filter rules installed on the dynamic m-port (specified by the v-port ID field of the filter spec). Signed-off-by: Edward Cree Signed-off-by: Jakub Kicinski --- drivers/net/ethernet/sfc/tc.c | 73 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 71 insertions(+), 2 deletions(-) (limited to 'drivers/net/ethernet/sfc/tc.c') diff --git a/drivers/net/ethernet/sfc/tc.c b/drivers/net/ethernet/sfc/tc.c index 0fb01f73c56e..0c0aeb91f500 100644 --- a/drivers/net/ethernet/sfc/tc.c +++ b/drivers/net/ethernet/sfc/tc.c @@ -12,6 +12,7 @@ #include "tc.h" #include "mae.h" #include "ef100_rep.h" +#include "efx.h" static void efx_tc_free_action_set(struct efx_nic *efx, struct efx_tc_action_set *act, bool in_hw) @@ -122,7 +123,7 @@ int efx_tc_configure_default_rule_rep(struct efx_rep *efv) u32 ing_port, eg_port; efx_mae_mport_mport(efx, efv->mport, &ing_port); - efx_mae_mport_uplink(efx, &eg_port); + efx_mae_mport_mport(efx, efx->tc->reps_mport_id, &eg_port); return efx_tc_configure_default_rule(efx, ing_port, eg_port, rule); } @@ -134,6 +135,68 @@ void efx_tc_deconfigure_default_rule(struct efx_nic *efx, rule->fw_id = MC_CMD_MAE_ACTION_RULE_INSERT_OUT_ACTION_RULE_ID_NULL; } +static int efx_tc_configure_rep_mport(struct efx_nic *efx) +{ + u32 rep_mport_label; + int rc; + + rc = efx_mae_allocate_mport(efx, &efx->tc->reps_mport_id, &rep_mport_label); + if (rc) + return rc; + pci_dbg(efx->pci_dev, "created rep mport 0x%08x (0x%04x)\n", + efx->tc->reps_mport_id, rep_mport_label); + /* Use mport *selector* as vport ID */ + efx_mae_mport_mport(efx, efx->tc->reps_mport_id, + &efx->tc->reps_mport_vport_id); + return 0; +} + +static void efx_tc_deconfigure_rep_mport(struct efx_nic *efx) +{ + efx_mae_free_mport(efx, efx->tc->reps_mport_id); + efx->tc->reps_mport_id = MAE_MPORT_SELECTOR_NULL; +} + +int efx_tc_insert_rep_filters(struct efx_nic *efx) +{ + struct efx_filter_spec promisc, allmulti; + int rc; + + if (efx->type->is_vf) + return 0; + if (!efx->tc) + return 0; + efx_filter_init_rx(&promisc, EFX_FILTER_PRI_REQUIRED, 0, 0); + efx_filter_set_uc_def(&promisc); + efx_filter_set_vport_id(&promisc, efx->tc->reps_mport_vport_id); + rc = efx_filter_insert_filter(efx, &promisc, false); + if (rc < 0) + return rc; + efx->tc->reps_filter_uc = rc; + efx_filter_init_rx(&allmulti, EFX_FILTER_PRI_REQUIRED, 0, 0); + efx_filter_set_mc_def(&allmulti); + efx_filter_set_vport_id(&allmulti, efx->tc->reps_mport_vport_id); + rc = efx_filter_insert_filter(efx, &allmulti, false); + if (rc < 0) + return rc; + efx->tc->reps_filter_mc = rc; + return 0; +} + +void efx_tc_remove_rep_filters(struct efx_nic *efx) +{ + if (efx->type->is_vf) + return; + if (!efx->tc) + return; + if (efx->tc->reps_filter_mc >= 0) + efx_filter_remove_id_safe(efx, EFX_FILTER_PRI_REQUIRED, efx->tc->reps_filter_mc); + efx->tc->reps_filter_mc = -1; + if (efx->tc->reps_filter_uc >= 0) + efx_filter_remove_id_safe(efx, EFX_FILTER_PRI_REQUIRED, efx->tc->reps_filter_uc); + efx->tc->reps_filter_uc = -1; +} + int efx_init_tc(struct efx_nic *efx) { int rc; @@ -141,7 +204,10 @@ int efx_init_tc(struct efx_nic *efx) rc = efx_tc_configure_default_rule_pf(efx); if (rc) return rc; - return efx_tc_configure_default_rule_wire(efx); + rc = efx_tc_configure_default_rule_wire(efx); + if (rc) + return rc; + return efx_tc_configure_rep_mport(efx); } void efx_fini_tc(struct efx_nic *efx) @@ -149,6 +215,7 @@ void efx_fini_tc(struct efx_nic *efx) /* We can get called even if efx_init_struct_tc() failed */ if (!efx->tc) return; + efx_tc_deconfigure_rep_mport(efx); efx_tc_deconfigure_default_rule(efx, &efx->tc->dflt.pf); efx_tc_deconfigure_default_rule(efx, &efx->tc->dflt.wire); } @@ -162,6 +229,8 @@ int efx_init_struct_tc(struct efx_nic *efx) if (!efx->tc) return -ENOMEM; + efx->tc->reps_filter_uc = -1; + efx->tc->reps_filter_mc = -1; INIT_LIST_HEAD(&efx->tc->dflt.pf.acts.list); efx->tc->dflt.pf.fw_id = MC_CMD_MAE_ACTION_RULE_INSERT_OUT_ACTION_RULE_ID_NULL; INIT_LIST_HEAD(&efx->tc->dflt.wire.acts.list); -- cgit v1.2.3-59-g8ed1b