From: Or Gerlitz <ogerl...@mellanox.com>

Add the API to create send-to-vport e-switch rules of the form

 packet meta-data :: send-queue-number == $SQN and source-vport == 0 --> $VPORT

These rules are to be used for a send-to-vport logic which conceptually bypasses
the "normal" steering rules currently present at the e-switch datapath.

Such rule should apply only for packets that originate in the e-switch manager
vport (0) and are sent for a given SQN which is used by a given VF representor
device, and hence the matching logic.

Signed-off-by: Or Gerlitz <ogerl...@mellanox.com>
Signed-off-by: Saeed Mahameed <sae...@mellanox.com>
---
 drivers/net/ethernet/mellanox/mlx5/core/eswitch.h  |  3 +-
 .../ethernet/mellanox/mlx5/core/eswitch_offloads.c | 39 ++++++++++++++++++++++
 2 files changed, 41 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h 
b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
index 8eed33f..b7fabd1 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
@@ -193,6 +193,8 @@ int mlx5_eswitch_get_vport_config(struct mlx5_eswitch *esw,
 int mlx5_eswitch_get_vport_stats(struct mlx5_eswitch *esw,
                                 int vport,
                                 struct ifla_vf_stats *vf_stats);
+struct mlx5_flow_rule *
+mlx5_eswitch_add_send_to_vport_rule(struct mlx5_eswitch *esw, int vport, u32 
sqn);
 
 #define MLX5_DEBUG_ESWITCH_MASK BIT(3)
 
@@ -204,5 +206,4 @@ int mlx5_eswitch_get_vport_stats(struct mlx5_eswitch *esw,
 
 #define esw_debug(dev, format, ...)                            \
        mlx5_core_dbg_mask(dev, MLX5_DEBUG_ESWITCH_MASK, format, ##__VA_ARGS__)
-
 #endif /* __MLX5_ESWITCH_H__ */
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c 
b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
index 9310017..a8be43d 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c
@@ -38,6 +38,45 @@
 #include "mlx5_core.h"
 #include "eswitch.h"
 
+struct mlx5_flow_rule *
+mlx5_eswitch_add_send_to_vport_rule(struct mlx5_eswitch *esw, int vport, u32 
sqn)
+{
+       struct mlx5_flow_destination dest;
+       struct mlx5_flow_rule *flow_rule;
+       int match_header = MLX5_MATCH_MISC_PARAMETERS;
+       u32 *match_v, *match_c;
+       void *misc;
+
+       match_v = kzalloc(MLX5_ST_SZ_BYTES(fte_match_param), GFP_KERNEL);
+       match_c = kzalloc(MLX5_ST_SZ_BYTES(fte_match_param), GFP_KERNEL);
+       if (!match_v || !match_c) {
+               esw_warn(esw->dev, "FDB: Failed to alloc match parameters\n");
+               flow_rule = ERR_PTR(-ENOMEM);
+               goto out;
+       }
+
+       misc = MLX5_ADDR_OF(fte_match_param, match_v, misc_parameters);
+       MLX5_SET(fte_match_set_misc, misc, source_sqn, sqn);
+       MLX5_SET(fte_match_set_misc, misc, source_port, 0x0); /* source vport 
is 0 */
+
+       misc = MLX5_ADDR_OF(fte_match_param, match_c, misc_parameters);
+       MLX5_SET_TO_ONES(fte_match_set_misc, misc, source_sqn);
+       MLX5_SET_TO_ONES(fte_match_set_misc, misc, source_port);
+
+       dest.type = MLX5_FLOW_DESTINATION_TYPE_VPORT;
+       dest.vport_num = vport;
+
+       flow_rule = mlx5_add_flow_rule(esw->fdb_table.fdb, match_header, 
match_c,
+                                      match_v, 
MLX5_FLOW_CONTEXT_ACTION_FWD_DEST,
+                                      0, &dest);
+       if (IS_ERR(flow_rule))
+               esw_warn(esw->dev, "FDB: Failed to add send to vport rule err 
%ld\n", PTR_ERR(flow_rule));
+out:
+       kfree(match_v);
+       kfree(match_c);
+       return flow_rule;
+}
+
 static int esw_add_fdb_miss_rule(struct mlx5_eswitch *esw)
 {
        struct mlx5_flow_destination dest;
-- 
2.8.0

Reply via email to