From: Mark Bloch <ma...@mellanox.com>

In order to forward traffic from representor's SQ to the right virtual
function, every time an SQ is created also add the corresponding flow rule
to the FDB.

Signed-off-by: Mark Bloch <ma...@mellanox.com>
Signed-off-by: Leon Romanovsky <l...@kernel.org>
Signed-off-by: Saeed Mahameed <sae...@mellanox.com>
---
 drivers/infiniband/hw/mlx5/ib_rep.c  | 20 ++++++++++++++++++++
 drivers/infiniband/hw/mlx5/ib_rep.h  |  8 ++++++++
 drivers/infiniband/hw/mlx5/mlx5_ib.h |  1 +
 drivers/infiniband/hw/mlx5/qp.c      | 16 ++++++++++++++++
 4 files changed, 45 insertions(+)

diff --git a/drivers/infiniband/hw/mlx5/ib_rep.c 
b/drivers/infiniband/hw/mlx5/ib_rep.c
index adf2439ddacb..a5d0c3917568 100644
--- a/drivers/infiniband/hw/mlx5/ib_rep.c
+++ b/drivers/infiniband/hw/mlx5/ib_rep.c
@@ -102,3 +102,23 @@ struct mlx5_eswitch_rep *mlx5_ib_vport_rep(struct 
mlx5_eswitch *esw, int vport)
 {
        return mlx5_eswitch_vport_rep(esw, vport);
 }
+
+int create_flow_rule_vport_sq(struct mlx5_ib_dev *dev,
+                             struct mlx5_ib_sq *sq)
+{
+       struct mlx5_flow_handle *flow_rule;
+       struct mlx5_eswitch *esw = dev->mdev->priv.eswitch;
+
+       if (!dev->rep)
+               return 0;
+
+       flow_rule =
+               mlx5_eswitch_add_send_to_vport_rule(esw,
+                                                   dev->rep->vport,
+                                                   sq->base.mqp.qpn);
+       if (IS_ERR(flow_rule))
+               return PTR_ERR(flow_rule);
+       sq->flow_rule = flow_rule;
+
+       return 0;
+}
diff --git a/drivers/infiniband/hw/mlx5/ib_rep.h 
b/drivers/infiniband/hw/mlx5/ib_rep.h
index 923ad4cba941..832cfd382ecc 100644
--- a/drivers/infiniband/hw/mlx5/ib_rep.h
+++ b/drivers/infiniband/hw/mlx5/ib_rep.h
@@ -17,6 +17,8 @@ struct mlx5_eswitch_rep *mlx5_ib_vport_rep(struct 
mlx5_eswitch *esw,
                                           int vport_index);
 void mlx5_ib_register_vport_reps(struct mlx5_ib_dev *dev);
 void mlx5_ib_unregister_vport_reps(struct mlx5_ib_dev *dev);
+int create_flow_rule_vport_sq(struct mlx5_ib_dev *dev,
+                             struct mlx5_ib_sq *sq);
 struct net_device *mlx5_ib_get_rep_netdev(struct mlx5_eswitch *esw,
                                          int vport_index);
 #else /* CONFIG_MLX5_ESWITCH */
@@ -41,6 +43,12 @@ struct mlx5_eswitch_rep *mlx5_ib_vport_rep(struct 
mlx5_eswitch *esw,
 
 static inline void mlx5_ib_register_vport_reps(struct mlx5_ib_dev *dev) {}
 static inline void mlx5_ib_unregister_vport_reps(struct mlx5_ib_dev *dev) {}
+static inline int create_flow_rule_vport_sq(struct mlx5_ib_dev *dev,
+                                           struct mlx5_ib_sq *sq)
+{
+       return 0;
+}
+
 static inline
 struct net_device *mlx5_ib_get_rep_netdev(struct mlx5_eswitch *esw,
                                          int vport_index)
diff --git a/drivers/infiniband/hw/mlx5/mlx5_ib.h 
b/drivers/infiniband/hw/mlx5/mlx5_ib.h
index 4dd98b1e9165..86d07670bfeb 100644
--- a/drivers/infiniband/hw/mlx5/mlx5_ib.h
+++ b/drivers/infiniband/hw/mlx5/mlx5_ib.h
@@ -343,6 +343,7 @@ struct mlx5_ib_sq {
        struct mlx5_ib_wq       *sq;
        struct mlx5_ib_ubuffer  ubuffer;
        struct mlx5_db          *doorbell;
+       struct mlx5_flow_handle *flow_rule;
        u32                     tisn;
        u8                      state;
 };
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
index 39d24bf694a8..8aed091036c6 100644
--- a/drivers/infiniband/hw/mlx5/qp.c
+++ b/drivers/infiniband/hw/mlx5/qp.c
@@ -36,6 +36,7 @@
 #include <rdma/ib_user_verbs.h>
 #include <linux/mlx5/fs.h>
 #include "mlx5_ib.h"
+#include "ib_rep.h"
 
 /* not supported currently */
 static int wq_signature;
@@ -1082,6 +1083,13 @@ static void destroy_raw_packet_qp_tis(struct mlx5_ib_dev 
*dev,
        mlx5_core_destroy_tis(dev->mdev, sq->tisn);
 }
 
+static void destroy_flow_rule_vport_sq(struct mlx5_ib_dev *dev,
+                                      struct mlx5_ib_sq *sq)
+{
+       if (sq->flow_rule)
+               mlx5_del_flow_rules(sq->flow_rule);
+}
+
 static int create_raw_packet_qp_sq(struct mlx5_ib_dev *dev,
                                   struct mlx5_ib_sq *sq, void *qpin,
                                   struct ib_pd *pd)
@@ -1145,8 +1153,15 @@ static int create_raw_packet_qp_sq(struct mlx5_ib_dev 
*dev,
        if (err)
                goto err_umem;
 
+       err = create_flow_rule_vport_sq(dev, sq);
+       if (err)
+               goto err_flow;
+
        return 0;
 
+err_flow:
+       mlx5_core_destroy_sq_tracked(dev->mdev, &sq->base.mqp);
+
 err_umem:
        ib_umem_release(sq->ubuffer.umem);
        sq->ubuffer.umem = NULL;
@@ -1157,6 +1172,7 @@ static int create_raw_packet_qp_sq(struct mlx5_ib_dev 
*dev,
 static void destroy_raw_packet_qp_sq(struct mlx5_ib_dev *dev,
                                     struct mlx5_ib_sq *sq)
 {
+       destroy_flow_rule_vport_sq(dev, sq);
        mlx5_core_destroy_sq_tracked(dev->mdev, &sq->base.mqp);
        ib_umem_release(sq->ubuffer.umem);
 }
-- 
2.14.3

Reply via email to