From 62c3a8b7e0beae6800510d3538fe46de7f1c688d Mon Sep 17 00:00:00 2001 From: Ivan Malov Date: Tue, 20 Oct 2020 10:13:09 +0100 Subject: [PATCH] net/sfc: support VLAN push actions in MAE backend A group of actions (OF_PUSH_VLAN, OF_VLAN_SET_VID and OF_VLAN_SET_PCP) maps to MAE action VLAN_PUSH. This action group is supported only for rules which have transfer attribute, and can be requested once or twice per a rule. Signed-off-by: Ivan Malov Signed-off-by: Andrew Rybchenko Reviewed-by: Andy Moreton --- doc/guides/nics/sfc_efx.rst | 6 ++++ drivers/net/sfc/sfc_mae.c | 61 +++++++++++++++++++++++++++++++++++-- 2 files changed, 65 insertions(+), 2 deletions(-) diff --git a/doc/guides/nics/sfc_efx.rst b/doc/guides/nics/sfc_efx.rst index a7061fb7d7..2d41dcee8d 100644 --- a/doc/guides/nics/sfc_efx.rst +++ b/doc/guides/nics/sfc_efx.rst @@ -198,6 +198,12 @@ Supported actions (***transfer*** rules): - OF_POP_VLAN +- OF_PUSH_VLAN + +- OF_VLAN_SET_VID + +- OF_VLAN_SET_PCP + - PHY_PORT Validating flow rules depends on the firmware variant. diff --git a/drivers/net/sfc/sfc_mae.c b/drivers/net/sfc/sfc_mae.c index 5fbf627f0a..98808ac3f0 100644 --- a/drivers/net/sfc/sfc_mae.c +++ b/drivers/net/sfc/sfc_mae.c @@ -463,6 +463,7 @@ fail_init_match_spec_action: enum sfc_mae_actions_bundle_type { SFC_MAE_ACTIONS_BUNDLE_EMPTY = 0, + SFC_MAE_ACTIONS_BUNDLE_VLAN_PUSH, }; struct sfc_mae_actions_bundle { @@ -470,6 +471,10 @@ struct sfc_mae_actions_bundle { /* Indicates actions already tracked by the current bundle */ uint64_t actions_mask; + + /* Parameters used by SFC_MAE_ACTIONS_BUNDLE_VLAN_PUSH */ + rte_be16_t vlan_push_tpid; + rte_be16_t vlan_push_tci; }; /* @@ -479,13 +484,17 @@ struct sfc_mae_actions_bundle { */ static int sfc_mae_actions_bundle_submit(const struct sfc_mae_actions_bundle *bundle, - __rte_unused efx_mae_actions_t *spec) + efx_mae_actions_t *spec) { int rc = 0; switch (bundle->type) { case SFC_MAE_ACTIONS_BUNDLE_EMPTY: break; + case SFC_MAE_ACTIONS_BUNDLE_VLAN_PUSH: + rc = efx_mae_action_set_populate_vlan_push( + spec, bundle->vlan_push_tpid, bundle->vlan_push_tci); + break; default: SFC_ASSERT(B_FALSE); break; @@ -509,6 +518,11 @@ sfc_mae_actions_bundle_sync(const struct rte_flow_action *action, int rc; switch (action->type) { + case RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN: + case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID: + case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP: + bundle_type_new = SFC_MAE_ACTIONS_BUNDLE_VLAN_PUSH; + break; default: /* * Self-sufficient actions, including END, are handled in this @@ -538,6 +552,34 @@ fail_submit: "Failed to request the (group of) action(s)"); } +static void +sfc_mae_rule_parse_action_of_push_vlan( + const struct rte_flow_action_of_push_vlan *conf, + struct sfc_mae_actions_bundle *bundle) +{ + bundle->vlan_push_tpid = conf->ethertype; +} + +static void +sfc_mae_rule_parse_action_of_set_vlan_vid( + const struct rte_flow_action_of_set_vlan_vid *conf, + struct sfc_mae_actions_bundle *bundle) +{ + bundle->vlan_push_tci |= (conf->vlan_vid & + rte_cpu_to_be_16(RTE_LEN2MASK(12, uint16_t))); +} + +static void +sfc_mae_rule_parse_action_of_set_vlan_pcp( + const struct rte_flow_action_of_set_vlan_pcp *conf, + struct sfc_mae_actions_bundle *bundle) +{ + uint16_t vlan_tci_pcp = (uint16_t)(conf->vlan_pcp & + RTE_LEN2MASK(3, uint8_t)) << 13; + + bundle->vlan_push_tci |= rte_cpu_to_be_16(vlan_tci_pcp); +} + static int sfc_mae_rule_parse_action_phy_port(struct sfc_adapter *sa, const struct rte_flow_action_phy_port *conf, @@ -566,7 +608,7 @@ sfc_mae_rule_parse_action(struct sfc_adapter *sa, efx_mae_actions_t *spec, struct rte_flow_error *error) { - int rc; + int rc = 0; switch (action->type) { case RTE_FLOW_ACTION_TYPE_OF_POP_VLAN: @@ -574,6 +616,21 @@ sfc_mae_rule_parse_action(struct sfc_adapter *sa, bundle->actions_mask); rc = efx_mae_action_set_populate_vlan_pop(spec); break; + case RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN: + SFC_BUILD_SET_OVERFLOW(RTE_FLOW_ACTION_TYPE_OF_PUSH_VLAN, + bundle->actions_mask); + sfc_mae_rule_parse_action_of_push_vlan(action->conf, bundle); + break; + case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID: + SFC_BUILD_SET_OVERFLOW(RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_VID, + bundle->actions_mask); + sfc_mae_rule_parse_action_of_set_vlan_vid(action->conf, bundle); + break; + case RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP: + SFC_BUILD_SET_OVERFLOW(RTE_FLOW_ACTION_TYPE_OF_SET_VLAN_PCP, + bundle->actions_mask); + sfc_mae_rule_parse_action_of_set_vlan_pcp(action->conf, bundle); + break; case RTE_FLOW_ACTION_TYPE_PHY_PORT: SFC_BUILD_SET_OVERFLOW(RTE_FLOW_ACTION_TYPE_PHY_PORT, bundle->actions_mask); -- 2.20.1