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 <jianbol@mellanox.com> Reviewed-by: Or Gerlitz <ogerlitz@mellanox.com> Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
This commit is contained in:
parent
1482bd3d50
commit
cc495188a8
@ -2583,24 +2583,48 @@ static int parse_tc_vlan_action(struct mlx5e_priv *priv,
|
||||
struct mlx5_esw_flow_attr *attr,
|
||||
u32 *action)
|
||||
{
|
||||
u8 vlan_idx = attr->total_vlan;
|
||||
|
||||
if (vlan_idx >= MLX5_FS_VLAN_DEPTH)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (tcf_vlan_action(a) == TCA_VLAN_ACT_POP) {
|
||||
*action |= MLX5_FLOW_CONTEXT_ACTION_VLAN_POP;
|
||||
if (vlan_idx) {
|
||||
if (!mlx5_eswitch_vlan_actions_supported(priv->mdev,
|
||||
MLX5_FS_VLAN_DEPTH))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
*action |= MLX5_FLOW_CONTEXT_ACTION_VLAN_POP_2;
|
||||
} else {
|
||||
*action |= MLX5_FLOW_CONTEXT_ACTION_VLAN_POP;
|
||||
}
|
||||
} else if (tcf_vlan_action(a) == TCA_VLAN_ACT_PUSH) {
|
||||
*action |= MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH;
|
||||
attr->vlan_vid[0] = tcf_vlan_push_vid(a);
|
||||
if (mlx5_eswitch_vlan_actions_supported(priv->mdev)) {
|
||||
attr->vlan_prio[0] = tcf_vlan_push_prio(a);
|
||||
attr->vlan_proto[0] = tcf_vlan_push_proto(a);
|
||||
if (!attr->vlan_proto[0])
|
||||
attr->vlan_proto[0] = htons(ETH_P_8021Q);
|
||||
} else if (tcf_vlan_push_proto(a) != htons(ETH_P_8021Q) ||
|
||||
tcf_vlan_push_prio(a)) {
|
||||
return -EOPNOTSUPP;
|
||||
attr->vlan_vid[vlan_idx] = tcf_vlan_push_vid(a);
|
||||
attr->vlan_prio[vlan_idx] = tcf_vlan_push_prio(a);
|
||||
attr->vlan_proto[vlan_idx] = tcf_vlan_push_proto(a);
|
||||
if (!attr->vlan_proto[vlan_idx])
|
||||
attr->vlan_proto[vlan_idx] = htons(ETH_P_8021Q);
|
||||
|
||||
if (vlan_idx) {
|
||||
if (!mlx5_eswitch_vlan_actions_supported(priv->mdev,
|
||||
MLX5_FS_VLAN_DEPTH))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
*action |= MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH_2;
|
||||
} else {
|
||||
if (!mlx5_eswitch_vlan_actions_supported(priv->mdev, 1) &&
|
||||
(tcf_vlan_push_proto(a) != htons(ETH_P_8021Q) ||
|
||||
tcf_vlan_push_prio(a)))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
*action |= MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH;
|
||||
}
|
||||
} else { /* action is TCA_VLAN_ACT_MODIFY */
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
attr->total_vlan = vlan_idx + 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include <net/devlink.h>
|
||||
#include <linux/mlx5/device.h>
|
||||
#include <linux/mlx5/eswitch.h>
|
||||
#include <linux/mlx5/fs.h>
|
||||
#include "lib/mpfs.h"
|
||||
|
||||
#ifdef CONFIG_MLX5_ESWITCH
|
||||
@ -256,9 +257,10 @@ struct mlx5_esw_flow_attr {
|
||||
int out_count;
|
||||
|
||||
int action;
|
||||
__be16 vlan_proto[1];
|
||||
u16 vlan_vid[1];
|
||||
u8 vlan_prio[1];
|
||||
__be16 vlan_proto[MLX5_FS_VLAN_DEPTH];
|
||||
u16 vlan_vid[MLX5_FS_VLAN_DEPTH];
|
||||
u8 vlan_prio[MLX5_FS_VLAN_DEPTH];
|
||||
u8 total_vlan;
|
||||
bool vlan_handled;
|
||||
u32 encap_id;
|
||||
u32 mod_hdr_id;
|
||||
@ -282,10 +284,17 @@ int mlx5_eswitch_del_vlan_action(struct mlx5_eswitch *esw,
|
||||
int __mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch *esw,
|
||||
int vport, u16 vlan, u8 qos, u8 set_flags);
|
||||
|
||||
static inline bool mlx5_eswitch_vlan_actions_supported(struct mlx5_core_dev *dev)
|
||||
static inline bool mlx5_eswitch_vlan_actions_supported(struct mlx5_core_dev *dev,
|
||||
u8 vlan_depth)
|
||||
{
|
||||
return MLX5_CAP_ESW_FLOWTABLE_FDB(dev, pop_vlan) &&
|
||||
MLX5_CAP_ESW_FLOWTABLE_FDB(dev, push_vlan);
|
||||
bool ret = MLX5_CAP_ESW_FLOWTABLE_FDB(dev, pop_vlan) &&
|
||||
MLX5_CAP_ESW_FLOWTABLE_FDB(dev, push_vlan);
|
||||
|
||||
if (vlan_depth == 1)
|
||||
return ret;
|
||||
|
||||
return ret && MLX5_CAP_ESW_FLOWTABLE_FDB(dev, pop_vlan_2) &&
|
||||
MLX5_CAP_ESW_FLOWTABLE_FDB(dev, push_vlan_2);
|
||||
}
|
||||
|
||||
#define MLX5_DEBUG_ESWITCH_MASK BIT(3)
|
||||
|
@ -66,13 +66,18 @@ mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw,
|
||||
|
||||
flow_act.action = attr->action;
|
||||
/* if per flow vlan pop/push is emulated, don't set that into the firmware */
|
||||
if (!mlx5_eswitch_vlan_actions_supported(esw->dev))
|
||||
if (!mlx5_eswitch_vlan_actions_supported(esw->dev, 1))
|
||||
flow_act.action &= ~(MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH |
|
||||
MLX5_FLOW_CONTEXT_ACTION_VLAN_POP);
|
||||
else if (flow_act.action & MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH) {
|
||||
flow_act.vlan[0].ethtype = ntohs(attr->vlan_proto[0]);
|
||||
flow_act.vlan[0].vid = attr->vlan_vid[0];
|
||||
flow_act.vlan[0].prio = attr->vlan_prio[0];
|
||||
if (flow_act.action & MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH_2) {
|
||||
flow_act.vlan[1].ethtype = ntohs(attr->vlan_proto[1]);
|
||||
flow_act.vlan[1].vid = attr->vlan_vid[1];
|
||||
flow_act.vlan[1].prio = attr->vlan_prio[1];
|
||||
}
|
||||
}
|
||||
|
||||
if (flow_act.action & MLX5_FLOW_CONTEXT_ACTION_FWD_DEST) {
|
||||
@ -284,7 +289,7 @@ int mlx5_eswitch_add_vlan_action(struct mlx5_eswitch *esw,
|
||||
int err = 0;
|
||||
|
||||
/* nop if we're on the vlan push/pop non emulation mode */
|
||||
if (mlx5_eswitch_vlan_actions_supported(esw->dev))
|
||||
if (mlx5_eswitch_vlan_actions_supported(esw->dev, 1))
|
||||
return 0;
|
||||
|
||||
push = !!(attr->action & MLX5_FLOW_CONTEXT_ACTION_VLAN_PUSH);
|
||||
@ -347,7 +352,7 @@ int mlx5_eswitch_del_vlan_action(struct mlx5_eswitch *esw,
|
||||
int err = 0;
|
||||
|
||||
/* nop if we're on the vlan push/pop non emulation mode */
|
||||
if (mlx5_eswitch_vlan_actions_supported(esw->dev))
|
||||
if (mlx5_eswitch_vlan_actions_supported(esw->dev, 1))
|
||||
return 0;
|
||||
|
||||
if (!attr->vlan_handled)
|
||||
|
Loading…
Reference in New Issue
Block a user