aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/sfc/tc.c
diff options
context:
space:
mode:
authorEdward Cree <ecree.xilinx@gmail.com>2022-07-28 19:57:51 +0100
committerJakub Kicinski <kuba@kernel.org>2022-07-29 21:22:07 -0700
commite37f3b1561a038c0630e7364740d6d55f2b5d5b5 (patch)
tree2c2af3041ec49c5c3dd476db0892a159a71fa400 /drivers/net/ethernet/sfc/tc.c
parentsfc: move table locking into filter_table_{probe,remove} methods (diff)
downloadlinux-dev-e37f3b1561a038c0630e7364740d6d55f2b5d5b5.tar.xz
linux-dev-e37f3b1561a038c0630e7364740d6d55f2b5d5b5.zip
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 <ecree.xilinx@gmail.com> Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'drivers/net/ethernet/sfc/tc.c')
-rw-r--r--drivers/net/ethernet/sfc/tc.c73
1 files changed, 71 insertions, 2 deletions
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);