lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening linux-cve-announce PHC | |
Open Source and information security mailing list archives
| ||
|
Message-ID: <20230216160442.48394-1-edward.cree@amd.com> Date: Thu, 16 Feb 2023 16:04:42 +0000 From: <edward.cree@....com> To: <linux-net-drivers@....com>, <davem@...emloft.net>, <kuba@...nel.org>, <pabeni@...hat.com>, <edumazet@...gle.com> CC: Edward Cree <ecree.xilinx@...il.com>, <netdev@...r.kernel.org>, <habetsm.xilinx@...il.com> Subject: [PATCH net-next] sfc: support offloading TC VLAN push/pop actions to the MAE From: Edward Cree <ecree.xilinx@...il.com> EF100 can pop and/or push up to two VLAN tags. Signed-off-by: Edward Cree <ecree.xilinx@...il.com> --- drivers/net/ethernet/sfc/mae.c | 43 ++++++++++++++++++++++++++ drivers/net/ethernet/sfc/mcdi.h | 5 ++++ drivers/net/ethernet/sfc/tc.c | 53 +++++++++++++++++++++++++++++++++ drivers/net/ethernet/sfc/tc.h | 4 +++ 4 files changed, 105 insertions(+) diff --git a/drivers/net/ethernet/sfc/mae.c b/drivers/net/ethernet/sfc/mae.c index 6321fd393fc3..7ae5b22af624 100644 --- a/drivers/net/ethernet/sfc/mae.c +++ b/drivers/net/ethernet/sfc/mae.c @@ -679,9 +679,40 @@ int efx_mae_alloc_action_set(struct efx_nic *efx, struct efx_tc_action_set *act) { MCDI_DECLARE_BUF(outbuf, MC_CMD_MAE_ACTION_SET_ALLOC_OUT_LEN); MCDI_DECLARE_BUF(inbuf, MC_CMD_MAE_ACTION_SET_ALLOC_IN_LEN); + unsigned char vlan_push, vlan_pop; size_t outlen; int rc; + /* Translate vlan actions from bitmask to count */ + switch (act->vlan_push) { + case 0: + case 1: + vlan_push = act->vlan_push; + break; + case 2: /* can't happen */ + default: + return -EINVAL; + case 3: + vlan_push = 2; + break; + } + switch (act->vlan_pop) { + case 0: + case 1: + vlan_pop = act->vlan_pop; + break; + case 2: /* can't happen */ + default: + return -EINVAL; + case 3: + vlan_pop = 2; + break; + } + + MCDI_POPULATE_DWORD_2(inbuf, MAE_ACTION_SET_ALLOC_IN_FLAGS, + MAE_ACTION_SET_ALLOC_IN_VLAN_PUSH, vlan_push, + MAE_ACTION_SET_ALLOC_IN_VLAN_POP, vlan_pop); + MCDI_SET_DWORD(inbuf, MAE_ACTION_SET_ALLOC_IN_SRC_MAC_ID, MC_CMD_MAE_MAC_ADDR_ALLOC_OUT_MAC_ID_NULL); MCDI_SET_DWORD(inbuf, MAE_ACTION_SET_ALLOC_IN_DST_MAC_ID, @@ -694,6 +725,18 @@ int efx_mae_alloc_action_set(struct efx_nic *efx, struct efx_tc_action_set *act) MC_CMD_MAE_COUNTER_ALLOC_OUT_COUNTER_ID_NULL); MCDI_SET_DWORD(inbuf, MAE_ACTION_SET_ALLOC_IN_COUNTER_LIST_ID, MC_CMD_MAE_COUNTER_LIST_ALLOC_OUT_COUNTER_LIST_ID_NULL); + if (act->vlan_push & 1) { + MCDI_SET_WORD_BE(inbuf, MAE_ACTION_SET_ALLOC_IN_VLAN0_TCI_BE, + act->vlan_tci[0]); + MCDI_SET_WORD_BE(inbuf, MAE_ACTION_SET_ALLOC_IN_VLAN0_PROTO_BE, + act->vlan_proto[0]); + } + if (act->vlan_push & 2) { + MCDI_SET_WORD_BE(inbuf, MAE_ACTION_SET_ALLOC_IN_VLAN1_TCI_BE, + act->vlan_tci[1]); + MCDI_SET_WORD_BE(inbuf, MAE_ACTION_SET_ALLOC_IN_VLAN1_PROTO_BE, + act->vlan_proto[1]); + } MCDI_SET_DWORD(inbuf, MAE_ACTION_SET_ALLOC_IN_ENCAP_HEADER_ID, MC_CMD_MAE_ENCAP_HEADER_ALLOC_OUT_ENCAP_HEADER_ID_NULL); if (act->deliver) diff --git a/drivers/net/ethernet/sfc/mcdi.h b/drivers/net/ethernet/sfc/mcdi.h index b139b76febff..454e9d51a4c2 100644 --- a/drivers/net/ethernet/sfc/mcdi.h +++ b/drivers/net/ethernet/sfc/mcdi.h @@ -233,6 +233,11 @@ void efx_mcdi_sensor_event(struct efx_nic *efx, efx_qword_t *ev); ((void)BUILD_BUG_ON_ZERO(_field ## _LEN != 2), \ le16_to_cpu(*(__force const __le16 *)MCDI_STRUCT_PTR(_buf, _field))) /* Write a 16-bit field defined in the protocol as being big-endian. */ +#define MCDI_SET_WORD_BE(_buf, _field, _value) do { \ + BUILD_BUG_ON(MC_CMD_ ## _field ## _LEN != 2); \ + BUILD_BUG_ON(MC_CMD_ ## _field ## _OFST & 1); \ + *(__force __be16 *)MCDI_PTR(_buf, _field) = (_value); \ + } while (0) #define MCDI_STRUCT_SET_WORD_BE(_buf, _field, _value) do { \ BUILD_BUG_ON(_field ## _LEN != 2); \ BUILD_BUG_ON(_field ## _OFST & 1); \ diff --git a/drivers/net/ethernet/sfc/tc.c b/drivers/net/ethernet/sfc/tc.c index deeaab9ee761..195c288736be 100644 --- a/drivers/net/ethernet/sfc/tc.c +++ b/drivers/net/ethernet/sfc/tc.c @@ -286,6 +286,10 @@ static int efx_tc_flower_parse_match(struct efx_nic *efx, /* For details of action order constraints refer to SF-123102-TC-1ยง12.6.1 */ enum efx_tc_action_order { + EFX_TC_AO_VLAN1_POP, + EFX_TC_AO_VLAN0_POP, + EFX_TC_AO_VLAN0_PUSH, + EFX_TC_AO_VLAN1_PUSH, EFX_TC_AO_COUNT, EFX_TC_AO_DELIVER }; @@ -294,6 +298,22 @@ static bool efx_tc_flower_action_order_ok(const struct efx_tc_action_set *act, enum efx_tc_action_order new) { switch (new) { + case EFX_TC_AO_VLAN0_POP: + if (act->vlan_pop & 1) + return false; + fallthrough; + case EFX_TC_AO_VLAN1_POP: + if (act->vlan_pop & 2) + return false; + fallthrough; + case EFX_TC_AO_VLAN0_PUSH: + if (act->vlan_push & 1) + return false; + fallthrough; + case EFX_TC_AO_VLAN1_PUSH: + if (act->vlan_push & 2) + return false; + fallthrough; case EFX_TC_AO_COUNT: if (act->count) return false; @@ -393,6 +413,8 @@ static int efx_tc_flower_replace(struct efx_nic *efx, flow_action_for_each(i, fa, &fr->action) { struct efx_tc_action_set save; + int depth; + u16 tci; if (!act) { /* more actions after a non-pipe action */ @@ -494,6 +516,37 @@ static int efx_tc_flower_replace(struct efx_nic *efx, } *act = save; break; + case FLOW_ACTION_VLAN_POP: + if (act->vlan_push & 2) { + act->vlan_push &= ~2; + } else if (act->vlan_push & 1) { + act->vlan_push &= ~1; + } else if (efx_tc_flower_action_order_ok(act, EFX_TC_AO_VLAN0_POP)) { + act->vlan_pop |= 1; + } else if (efx_tc_flower_action_order_ok(act, EFX_TC_AO_VLAN1_POP)) { + act->vlan_pop |= 2; + } else { + NL_SET_ERR_MSG_MOD(extack, "More than two VLAN pops, or action order violated"); + rc = -EINVAL; + goto release; + } + break; + case FLOW_ACTION_VLAN_PUSH: + if (efx_tc_flower_action_order_ok(act, EFX_TC_AO_VLAN0_PUSH)) { + depth = 0; + } else if (efx_tc_flower_action_order_ok(act, EFX_TC_AO_VLAN1_PUSH)) { + depth = 1; + } else { + rc = -EINVAL; + NL_SET_ERR_MSG_MOD(extack, "More than two VLAN pushes, or action order violated"); + goto release; + } + tci = fa->vlan.vid & 0x0fff; + tci |= fa->vlan.prio << 13; + act->vlan_push |= (1 << depth); + act->vlan_tci[depth] = cpu_to_be16(tci); + act->vlan_proto[depth] = fa->vlan.proto; + break; default: NL_SET_ERR_MSG_FMT_MOD(extack, "Unhandled action %u", fa->id); diff --git a/drivers/net/ethernet/sfc/tc.h b/drivers/net/ethernet/sfc/tc.h index 418ce8c13a06..542853f60c2a 100644 --- a/drivers/net/ethernet/sfc/tc.h +++ b/drivers/net/ethernet/sfc/tc.h @@ -19,7 +19,11 @@ #define IS_ALL_ONES(v) (!(typeof (v))~(v)) struct efx_tc_action_set { + u16 vlan_push:2; + u16 vlan_pop:2; u16 deliver:1; + __be16 vlan_tci[2]; /* TCIs for vlan_push */ + __be16 vlan_proto[2]; /* Ethertypes for vlan_push */ struct efx_tc_counter_index *count; u32 dest_mport; u32 fw_id; /* index of this entry in firmware actions table */
Powered by blists - more mailing lists