mirror of
https://git.proxmox.com/git/mirror_ubuntu-kernels.git
synced 2026-01-06 19:02:48 +00:00
sfc: support offloading TC VLAN push/pop actions to the MAE
EF100 can pop and/or push up to two VLAN tags. Signed-off-by: Edward Cree <ecree.xilinx@gmail.com> Reviewed-by: Simon Horman <simon.horman@corigine.com> Link: https://lore.kernel.org/r/20230309115904.56442-1-edward.cree@amd.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
494f642f8c
commit
05ccd8d8a1
@ -682,6 +682,10 @@ int efx_mae_alloc_action_set(struct efx_nic *efx, struct efx_tc_action_set *act)
|
||||
size_t outlen;
|
||||
int rc;
|
||||
|
||||
MCDI_POPULATE_DWORD_2(inbuf, MAE_ACTION_SET_ALLOC_IN_FLAGS,
|
||||
MAE_ACTION_SET_ALLOC_IN_VLAN_PUSH, act->vlan_push,
|
||||
MAE_ACTION_SET_ALLOC_IN_VLAN_POP, act->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 +698,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) {
|
||||
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)
|
||||
|
||||
@ -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); \
|
||||
|
||||
@ -286,6 +286,8 @@ 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_VLAN_POP,
|
||||
EFX_TC_AO_VLAN_PUSH,
|
||||
EFX_TC_AO_COUNT,
|
||||
EFX_TC_AO_DELIVER
|
||||
};
|
||||
@ -294,6 +296,20 @@ 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_VLAN_POP:
|
||||
if (act->vlan_pop >= 2)
|
||||
return false;
|
||||
/* If we've already pushed a VLAN, we can't then pop it;
|
||||
* the hardware would instead try to pop an existing VLAN
|
||||
* before pushing the new one.
|
||||
*/
|
||||
if (act->vlan_push)
|
||||
return false;
|
||||
fallthrough;
|
||||
case EFX_TC_AO_VLAN_PUSH:
|
||||
if (act->vlan_push >= 2)
|
||||
return false;
|
||||
fallthrough;
|
||||
case EFX_TC_AO_COUNT:
|
||||
if (act->count)
|
||||
return false;
|
||||
@ -393,6 +409,7 @@ static int efx_tc_flower_replace(struct efx_nic *efx,
|
||||
|
||||
flow_action_for_each(i, fa, &fr->action) {
|
||||
struct efx_tc_action_set save;
|
||||
u16 tci;
|
||||
|
||||
if (!act) {
|
||||
/* more actions after a non-pipe action */
|
||||
@ -494,6 +511,31 @@ static int efx_tc_flower_replace(struct efx_nic *efx,
|
||||
}
|
||||
*act = save;
|
||||
break;
|
||||
case FLOW_ACTION_VLAN_POP:
|
||||
if (act->vlan_push) {
|
||||
act->vlan_push--;
|
||||
} else if (efx_tc_flower_action_order_ok(act, EFX_TC_AO_VLAN_POP)) {
|
||||
act->vlan_pop++;
|
||||
} 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_VLAN_PUSH)) {
|
||||
rc = -EINVAL;
|
||||
NL_SET_ERR_MSG_MOD(extack,
|
||||
"More than two VLAN pushes, or action order violated");
|
||||
goto release;
|
||||
}
|
||||
tci = fa->vlan.vid & VLAN_VID_MASK;
|
||||
tci |= fa->vlan.prio << VLAN_PRIO_SHIFT;
|
||||
act->vlan_tci[act->vlan_push] = cpu_to_be16(tci);
|
||||
act->vlan_proto[act->vlan_push] = fa->vlan.proto;
|
||||
act->vlan_push++;
|
||||
break;
|
||||
default:
|
||||
NL_SET_ERR_MSG_FMT_MOD(extack, "Unhandled action %u",
|
||||
fa->id);
|
||||
|
||||
@ -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 */
|
||||
|
||||
Loading…
Reference in New Issue
Block a user