Skip to content

Commit 05ccd8d

Browse files
Edward Creekuba-moo
authored andcommitted
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>
1 parent 494f642 commit 05ccd8d

File tree

4 files changed

+67
-0
lines changed

4 files changed

+67
-0
lines changed

drivers/net/ethernet/sfc/mae.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -682,6 +682,10 @@ int efx_mae_alloc_action_set(struct efx_nic *efx, struct efx_tc_action_set *act)
682682
size_t outlen;
683683
int rc;
684684

685+
MCDI_POPULATE_DWORD_2(inbuf, MAE_ACTION_SET_ALLOC_IN_FLAGS,
686+
MAE_ACTION_SET_ALLOC_IN_VLAN_PUSH, act->vlan_push,
687+
MAE_ACTION_SET_ALLOC_IN_VLAN_POP, act->vlan_pop);
688+
685689
MCDI_SET_DWORD(inbuf, MAE_ACTION_SET_ALLOC_IN_SRC_MAC_ID,
686690
MC_CMD_MAE_MAC_ADDR_ALLOC_OUT_MAC_ID_NULL);
687691
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)
694698
MC_CMD_MAE_COUNTER_ALLOC_OUT_COUNTER_ID_NULL);
695699
MCDI_SET_DWORD(inbuf, MAE_ACTION_SET_ALLOC_IN_COUNTER_LIST_ID,
696700
MC_CMD_MAE_COUNTER_LIST_ALLOC_OUT_COUNTER_LIST_ID_NULL);
701+
if (act->vlan_push) {
702+
MCDI_SET_WORD_BE(inbuf, MAE_ACTION_SET_ALLOC_IN_VLAN0_TCI_BE,
703+
act->vlan_tci[0]);
704+
MCDI_SET_WORD_BE(inbuf, MAE_ACTION_SET_ALLOC_IN_VLAN0_PROTO_BE,
705+
act->vlan_proto[0]);
706+
}
707+
if (act->vlan_push >= 2) {
708+
MCDI_SET_WORD_BE(inbuf, MAE_ACTION_SET_ALLOC_IN_VLAN1_TCI_BE,
709+
act->vlan_tci[1]);
710+
MCDI_SET_WORD_BE(inbuf, MAE_ACTION_SET_ALLOC_IN_VLAN1_PROTO_BE,
711+
act->vlan_proto[1]);
712+
}
697713
MCDI_SET_DWORD(inbuf, MAE_ACTION_SET_ALLOC_IN_ENCAP_HEADER_ID,
698714
MC_CMD_MAE_ENCAP_HEADER_ALLOC_OUT_ENCAP_HEADER_ID_NULL);
699715
if (act->deliver)

drivers/net/ethernet/sfc/mcdi.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,11 @@ void efx_mcdi_sensor_event(struct efx_nic *efx, efx_qword_t *ev);
233233
((void)BUILD_BUG_ON_ZERO(_field ## _LEN != 2), \
234234
le16_to_cpu(*(__force const __le16 *)MCDI_STRUCT_PTR(_buf, _field)))
235235
/* Write a 16-bit field defined in the protocol as being big-endian. */
236+
#define MCDI_SET_WORD_BE(_buf, _field, _value) do { \
237+
BUILD_BUG_ON(MC_CMD_ ## _field ## _LEN != 2); \
238+
BUILD_BUG_ON(MC_CMD_ ## _field ## _OFST & 1); \
239+
*(__force __be16 *)MCDI_PTR(_buf, _field) = (_value); \
240+
} while (0)
236241
#define MCDI_STRUCT_SET_WORD_BE(_buf, _field, _value) do { \
237242
BUILD_BUG_ON(_field ## _LEN != 2); \
238243
BUILD_BUG_ON(_field ## _OFST & 1); \

drivers/net/ethernet/sfc/tc.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,8 @@ static int efx_tc_flower_parse_match(struct efx_nic *efx,
286286

287287
/* For details of action order constraints refer to SF-123102-TC-1§12.6.1 */
288288
enum efx_tc_action_order {
289+
EFX_TC_AO_VLAN_POP,
290+
EFX_TC_AO_VLAN_PUSH,
289291
EFX_TC_AO_COUNT,
290292
EFX_TC_AO_DELIVER
291293
};
@@ -294,6 +296,20 @@ static bool efx_tc_flower_action_order_ok(const struct efx_tc_action_set *act,
294296
enum efx_tc_action_order new)
295297
{
296298
switch (new) {
299+
case EFX_TC_AO_VLAN_POP:
300+
if (act->vlan_pop >= 2)
301+
return false;
302+
/* If we've already pushed a VLAN, we can't then pop it;
303+
* the hardware would instead try to pop an existing VLAN
304+
* before pushing the new one.
305+
*/
306+
if (act->vlan_push)
307+
return false;
308+
fallthrough;
309+
case EFX_TC_AO_VLAN_PUSH:
310+
if (act->vlan_push >= 2)
311+
return false;
312+
fallthrough;
297313
case EFX_TC_AO_COUNT:
298314
if (act->count)
299315
return false;
@@ -393,6 +409,7 @@ static int efx_tc_flower_replace(struct efx_nic *efx,
393409

394410
flow_action_for_each(i, fa, &fr->action) {
395411
struct efx_tc_action_set save;
412+
u16 tci;
396413

397414
if (!act) {
398415
/* more actions after a non-pipe action */
@@ -494,6 +511,31 @@ static int efx_tc_flower_replace(struct efx_nic *efx,
494511
}
495512
*act = save;
496513
break;
514+
case FLOW_ACTION_VLAN_POP:
515+
if (act->vlan_push) {
516+
act->vlan_push--;
517+
} else if (efx_tc_flower_action_order_ok(act, EFX_TC_AO_VLAN_POP)) {
518+
act->vlan_pop++;
519+
} else {
520+
NL_SET_ERR_MSG_MOD(extack,
521+
"More than two VLAN pops, or action order violated");
522+
rc = -EINVAL;
523+
goto release;
524+
}
525+
break;
526+
case FLOW_ACTION_VLAN_PUSH:
527+
if (!efx_tc_flower_action_order_ok(act, EFX_TC_AO_VLAN_PUSH)) {
528+
rc = -EINVAL;
529+
NL_SET_ERR_MSG_MOD(extack,
530+
"More than two VLAN pushes, or action order violated");
531+
goto release;
532+
}
533+
tci = fa->vlan.vid & VLAN_VID_MASK;
534+
tci |= fa->vlan.prio << VLAN_PRIO_SHIFT;
535+
act->vlan_tci[act->vlan_push] = cpu_to_be16(tci);
536+
act->vlan_proto[act->vlan_push] = fa->vlan.proto;
537+
act->vlan_push++;
538+
break;
497539
default:
498540
NL_SET_ERR_MSG_FMT_MOD(extack, "Unhandled action %u",
499541
fa->id);

drivers/net/ethernet/sfc/tc.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,11 @@
1919
#define IS_ALL_ONES(v) (!(typeof (v))~(v))
2020

2121
struct efx_tc_action_set {
22+
u16 vlan_push:2;
23+
u16 vlan_pop:2;
2224
u16 deliver:1;
25+
__be16 vlan_tci[2]; /* TCIs for vlan_push */
26+
__be16 vlan_proto[2]; /* Ethertypes for vlan_push */
2327
struct efx_tc_counter_index *count;
2428
u32 dest_mport;
2529
u32 fw_id; /* index of this entry in firmware actions table */

0 commit comments

Comments
 (0)