net/mlx5: E-Switch, Allow fine tuning of eswitch vport push/pop vlan
authorOr Gerlitz <ogerlitz@mellanox.com>
Thu, 22 Sep 2016 17:01:44 +0000 (20:01 +0300)
committerDavid S. Miller <davem@davemloft.net>
Fri, 23 Sep 2016 11:22:12 +0000 (07:22 -0400)
The HW can be programmed to push vlan, pop vlan or both.

A factorization step towards using the push/pop capabilties in the
eswitch offloads mode. This patch doesn't add new functionality.

Signed-off-by: Or Gerlitz <ogerlitz@mellanox.com>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
drivers/net/ethernet/mellanox/mlx5/core/eswitch.h

index f75f864..abbf2c3 100644 (file)
@@ -127,7 +127,7 @@ static int modify_esw_vport_context_cmd(struct mlx5_core_dev *dev, u16 vport,
 }
 
 static int modify_esw_vport_cvlan(struct mlx5_core_dev *dev, u32 vport,
-                                 u16 vlan, u8 qos, bool set)
+                                 u16 vlan, u8 qos, u8 set_flags)
 {
        u32 in[MLX5_ST_SZ_DW(modify_esw_vport_context_in)] = {0};
 
@@ -135,14 +135,18 @@ static int modify_esw_vport_cvlan(struct mlx5_core_dev *dev, u32 vport,
            !MLX5_CAP_ESW(dev, vport_cvlan_insert_if_not_exist))
                return -ENOTSUPP;
 
-       esw_debug(dev, "Set Vport[%d] VLAN %d qos %d set=%d\n",
-                 vport, vlan, qos, set);
-       if (set) {
+       esw_debug(dev, "Set Vport[%d] VLAN %d qos %d set=%x\n",
+                 vport, vlan, qos, set_flags);
+
+       if (set_flags & SET_VLAN_STRIP)
                MLX5_SET(modify_esw_vport_context_in, in,
                         esw_vport_context.vport_cvlan_strip, 1);
+
+       if (set_flags & SET_VLAN_INSERT) {
                /* insert only if no vlan in packet */
                MLX5_SET(modify_esw_vport_context_in, in,
                         esw_vport_context.vport_cvlan_insert, 1);
+
                MLX5_SET(modify_esw_vport_context_in, in,
                         esw_vport_context.cvlan_pcp, qos);
                MLX5_SET(modify_esw_vport_context_in, in,
@@ -1778,25 +1782,21 @@ int mlx5_eswitch_get_vport_config(struct mlx5_eswitch *esw,
        return 0;
 }
 
-int mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch *esw,
-                               int vport, u16 vlan, u8 qos)
+int __mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch *esw,
+                                 int vport, u16 vlan, u8 qos, u8 set_flags)
 {
        struct mlx5_vport *evport;
        int err = 0;
-       int set = 0;
 
        if (!ESW_ALLOWED(esw))
                return -EPERM;
        if (!LEGAL_VPORT(esw, vport) || (vlan > 4095) || (qos > 7))
                return -EINVAL;
 
-       if (vlan || qos)
-               set = 1;
-
        mutex_lock(&esw->state_lock);
        evport = &esw->vports[vport];
 
-       err = modify_esw_vport_cvlan(esw->dev, vport, vlan, qos, set);
+       err = modify_esw_vport_cvlan(esw->dev, vport, vlan, qos, set_flags);
        if (err)
                goto unlock;
 
@@ -1814,6 +1814,17 @@ unlock:
        return err;
 }
 
+int mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch *esw,
+                               int vport, u16 vlan, u8 qos)
+{
+       u8 set_flags = 0;
+
+       if (vlan || qos)
+               set_flags = SET_VLAN_STRIP | SET_VLAN_INSERT;
+
+       return __mlx5_eswitch_set_vport_vlan(esw, vport, vlan, qos, set_flags);
+}
+
 int mlx5_eswitch_set_vport_spoofchk(struct mlx5_eswitch *esw,
                                    int vport, bool spoofchk)
 {
index ebfcde0..4f5391a 100644 (file)
@@ -246,6 +246,11 @@ mlx5_eswitch_add_offloaded_rule(struct mlx5_eswitch *esw,
 struct mlx5_flow_rule *
 mlx5_eswitch_create_vport_rx_rule(struct mlx5_eswitch *esw, int vport, u32 tirn);
 
+enum {
+       SET_VLAN_STRIP  = BIT(0),
+       SET_VLAN_INSERT = BIT(1)
+};
+
 int mlx5_eswitch_sqs2vport_start(struct mlx5_eswitch *esw,
                                 struct mlx5_eswitch_rep *rep,
                                 u16 *sqns_array, int sqns_num);