OSDN Git Service

IB/mlx5: Enable QP creation with cvlan offload
authorNoa Osherovich <noaos@mellanox.com>
Wed, 18 Jan 2017 13:40:03 +0000 (15:40 +0200)
committerDoug Ledford <dledford@redhat.com>
Tue, 14 Feb 2017 16:41:15 +0000 (11:41 -0500)
Enable creating a RAW Ethernet QP with cvlan stripping offload when
it's supported by the hardware.

Signed-off-by: Noa Osherovich <noaos@mellanox.com>
Reviewed-by: Maor Gottlieb <maorg@mellanox.com>
Reviewed-by: Yishai Hadas <yishaih@mellanox.com>
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Doug Ledford <dledford@redhat.com>
drivers/infiniband/hw/mlx5/mlx5_ib.h
drivers/infiniband/hw/mlx5/qp.c

index 6609083..13bef19 100644 (file)
@@ -220,6 +220,10 @@ struct wr_list {
        u16     next;
 };
 
+enum mlx5_ib_rq_flags {
+       MLX5_IB_RQ_CVLAN_STRIPPING      = 1 << 0,
+};
+
 struct mlx5_ib_wq {
        u64                    *wrid;
        u32                    *wr_data;
@@ -308,6 +312,7 @@ struct mlx5_ib_rq {
        struct mlx5_db          *doorbell;
        u32                     tirn;
        u8                      state;
+       u32                     flags;
 };
 
 struct mlx5_ib_sq {
@@ -392,6 +397,7 @@ enum mlx5_ib_qp_flags {
        MLX5_IB_QP_SQPN_QP1                     = 1 << 6,
        MLX5_IB_QP_CAP_SCATTER_FCS              = 1 << 7,
        MLX5_IB_QP_RSS                          = 1 << 8,
+       MLX5_IB_QP_CVLAN_STRIPPING              = 1 << 9,
 };
 
 struct mlx5_umr_wr {
index 59bbe24..0b2b17d 100644 (file)
@@ -1141,7 +1141,8 @@ static int create_raw_packet_qp_rq(struct mlx5_ib_dev *dev,
                return -ENOMEM;
 
        rqc = MLX5_ADDR_OF(create_rq_in, in, ctx);
-       MLX5_SET(rqc, rqc, vsd, 1);
+       if (!(rq->flags & MLX5_IB_RQ_CVLAN_STRIPPING))
+               MLX5_SET(rqc, rqc, vsd, 1);
        MLX5_SET(rqc, rqc, mem_rq_type, MLX5_RQC_MEM_RQ_TYPE_MEMORY_RQ_INLINE);
        MLX5_SET(rqc, rqc, state, MLX5_RQC_STATE_RST);
        MLX5_SET(rqc, rqc, flush_in_error_en, 1);
@@ -1238,6 +1239,8 @@ static int create_raw_packet_qp(struct mlx5_ib_dev *dev, struct mlx5_ib_qp *qp,
        if (qp->rq.wqe_cnt) {
                rq->base.container_mibqp = qp;
 
+               if (qp->flags & MLX5_IB_QP_CVLAN_STRIPPING)
+                       rq->flags |= MLX5_IB_RQ_CVLAN_STRIPPING;
                err = create_raw_packet_qp_rq(dev, rq, in);
                if (err)
                        goto err_destroy_sq;
@@ -1559,6 +1562,14 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
        if (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR)
                qp->sq_signal_bits = MLX5_WQE_CTRL_CQ_UPDATE;
 
+       if (init_attr->create_flags & IB_QP_CREATE_CVLAN_STRIPPING) {
+               if (!(MLX5_CAP_GEN(dev->mdev, eth_net_offloads) &&
+                     MLX5_CAP_ETH(dev->mdev, vlan_cap)) ||
+                   (init_attr->qp_type != IB_QPT_RAW_PACKET))
+                       return -EOPNOTSUPP;
+               qp->flags |= MLX5_IB_QP_CVLAN_STRIPPING;
+       }
+
        if (pd && pd->uobject) {
                if (ib_copy_from_udata(&ucmd, udata, sizeof(ucmd))) {
                        mlx5_ib_dbg(dev, "copy failed\n");