Skip to content

Commit cc49518

Browse files
jialiu02Saeed Mahameed
authored andcommitted
net/mlx5e: Support offloading double vlan push/pop tc actions
As we can configure two push/pop actions in one flow table entry, add support to offload those double vlan actions in a rule to HW. Signed-off-by: Jianbo Liu <[email protected]> Reviewed-by: Or Gerlitz <[email protected]> Signed-off-by: Saeed Mahameed <[email protected]>
1 parent 1482bd3 commit cc49518

File tree

3 files changed

+58
-20
lines changed

3 files changed

+58
-20
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en_tc.c

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2583,24 +2583,48 @@ static int parse_tc_vlan_action(struct mlx5e_priv *priv,
25832583
struct mlx5_esw_flow_attr *attr,
25842584
u32 *action)
25852585
{
2586+
u8 vlan_idx = attr->total_vlan;
2587+
2588+
if (vlan_idx >= MLX5_FS_VLAN_DEPTH)
2589+
return -EOPNOTSUPP;
2590+
25862591
if (tcf_vlan_action(a) == TCA_VLAN_ACT_POP) {
2587-
*action |= MLX5_FLOW_CONTEXT_ACTION_VLAN_POP;
2592+
if (vlan_idx) {
2593+
if (!mlx5_eswitch_vlan_actions_supported(priv->mdev,
2594+
MLX5_FS_VLAN_DEPTH))
2595+
return -EOPNOTSUPP;
2596+
2597+
*action |= MLX5_FLOW_CONTEXT_ACTION_VLAN_POP_2;
2598+
} else {
2599+
*action |= MLX5_FLOW_CONTEXT_ACTION_VLAN_POP;
2600+
}
25882601
} else if (tcf_vlan_action(a) == TCA_VLAN_ACT_PUSH) {
2589-
*action |= MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH;
2590-
attr->vlan_vid[0] = tcf_vlan_push_vid(a);
2591-
if (mlx5_eswitch_vlan_actions_supported(priv->mdev)) {
2592-
attr->vlan_prio[0] = tcf_vlan_push_prio(a);
2593-
attr->vlan_proto[0] = tcf_vlan_push_proto(a);
2594-
if (!attr->vlan_proto[0])
2595-
attr->vlan_proto[0] = htons(ETH_P_8021Q);
2596-
} else if (tcf_vlan_push_proto(a) != htons(ETH_P_8021Q) ||
2597-
tcf_vlan_push_prio(a)) {
2598-
return -EOPNOTSUPP;
2602+
attr->vlan_vid[vlan_idx] = tcf_vlan_push_vid(a);
2603+
attr->vlan_prio[vlan_idx] = tcf_vlan_push_prio(a);
2604+
attr->vlan_proto[vlan_idx] = tcf_vlan_push_proto(a);
2605+
if (!attr->vlan_proto[vlan_idx])
2606+
attr->vlan_proto[vlan_idx] = htons(ETH_P_8021Q);
2607+
2608+
if (vlan_idx) {
2609+
if (!mlx5_eswitch_vlan_actions_supported(priv->mdev,
2610+
MLX5_FS_VLAN_DEPTH))
2611+
return -EOPNOTSUPP;
2612+
2613+
*action |= MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH_2;
2614+
} else {
2615+
if (!mlx5_eswitch_vlan_actions_supported(priv->mdev, 1) &&
2616+
(tcf_vlan_push_proto(a) != htons(ETH_P_8021Q) ||
2617+
tcf_vlan_push_prio(a)))
2618+
return -EOPNOTSUPP;
2619+
2620+
*action |= MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH;
25992621
}
26002622
} else { /* action is TCA_VLAN_ACT_MODIFY */
26012623
return -EOPNOTSUPP;
26022624
}
26032625

2626+
attr->total_vlan = vlan_idx + 1;
2627+
26042628
return 0;
26052629
}
26062630

drivers/net/ethernet/mellanox/mlx5/core/eswitch.h

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include <net/devlink.h>
3939
#include <linux/mlx5/device.h>
4040
#include <linux/mlx5/eswitch.h>
41+
#include <linux/mlx5/fs.h>
4142
#include "lib/mpfs.h"
4243

4344
#ifdef CONFIG_MLX5_ESWITCH
@@ -256,9 +257,10 @@ struct mlx5_esw_flow_attr {
256257
int out_count;
257258

258259
int action;
259-
__be16 vlan_proto[1];
260-
u16 vlan_vid[1];
261-
u8 vlan_prio[1];
260+
__be16 vlan_proto[MLX5_FS_VLAN_DEPTH];
261+
u16 vlan_vid[MLX5_FS_VLAN_DEPTH];
262+
u8 vlan_prio[MLX5_FS_VLAN_DEPTH];
263+
u8 total_vlan;
262264
bool vlan_handled;
263265
u32 encap_id;
264266
u32 mod_hdr_id;
@@ -282,10 +284,17 @@ int mlx5_eswitch_del_vlan_action(struct mlx5_eswitch *esw,
282284
int __mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch *esw,
283285
int vport, u16 vlan, u8 qos, u8 set_flags);
284286

285-
static inline bool mlx5_eswitch_vlan_actions_supported(struct mlx5_core_dev *dev)
287+
static inline bool mlx5_eswitch_vlan_actions_supported(struct mlx5_core_dev *dev,
288+
u8 vlan_depth)
286289
{
287-
return MLX5_CAP_ESW_FLOWTABLE_FDB(dev, pop_vlan) &&
288-
MLX5_CAP_ESW_FLOWTABLE_FDB(dev, push_vlan);
290+
bool ret = MLX5_CAP_ESW_FLOWTABLE_FDB(dev, pop_vlan) &&
291+
MLX5_CAP_ESW_FLOWTABLE_FDB(dev, push_vlan);
292+
293+
if (vlan_depth == 1)
294+
return ret;
295+
296+
return ret && MLX5_CAP_ESW_FLOWTABLE_FDB(dev, pop_vlan_2) &&
297+
MLX5_CAP_ESW_FLOWTABLE_FDB(dev, push_vlan_2);
289298
}
290299

291300
#define MLX5_DEBUG_ESWITCH_MASK BIT(3)

drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,18 @@ mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw,
6666

6767
flow_act.action = attr->action;
6868
/* if per flow vlan pop/push is emulated, don't set that into the firmware */
69-
if (!mlx5_eswitch_vlan_actions_supported(esw->dev))
69+
if (!mlx5_eswitch_vlan_actions_supported(esw->dev, 1))
7070
flow_act.action &= ~(MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH |
7171
MLX5_FLOW_CONTEXT_ACTION_VLAN_POP);
7272
else if (flow_act.action & MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH) {
7373
flow_act.vlan[0].ethtype = ntohs(attr->vlan_proto[0]);
7474
flow_act.vlan[0].vid = attr->vlan_vid[0];
7575
flow_act.vlan[0].prio = attr->vlan_prio[0];
76+
if (flow_act.action & MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH_2) {
77+
flow_act.vlan[1].ethtype = ntohs(attr->vlan_proto[1]);
78+
flow_act.vlan[1].vid = attr->vlan_vid[1];
79+
flow_act.vlan[1].prio = attr->vlan_prio[1];
80+
}
7681
}
7782

7883
if (flow_act.action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) {
@@ -284,7 +289,7 @@ int mlx5_eswitch_add_vlan_action(struct mlx5_eswitch *esw,
284289
int err = 0;
285290

286291
/* nop if we're on the vlan push/pop non emulation mode */
287-
if (mlx5_eswitch_vlan_actions_supported(esw->dev))
292+
if (mlx5_eswitch_vlan_actions_supported(esw->dev, 1))
288293
return 0;
289294

290295
push = !!(attr->action & MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH);
@@ -347,7 +352,7 @@ int mlx5_eswitch_del_vlan_action(struct mlx5_eswitch *esw,
347352
int err = 0;
348353

349354
/* nop if we're on the vlan push/pop non emulation mode */
350-
if (mlx5_eswitch_vlan_actions_supported(esw->dev))
355+
if (mlx5_eswitch_vlan_actions_supported(esw->dev, 1))
351356
return 0;
352357

353358
if (!attr->vlan_handled)

0 commit comments

Comments
 (0)