IB/mlx5: Support 4k UAR for libmlx5
authorEli Cohen <eli@mellanox.com>
Tue, 3 Jan 2017 21:55:27 +0000 (23:55 +0200)
committerSaeed Mahameed <saeedm@mellanox.com>
Mon, 9 Jan 2017 18:25:09 +0000 (20:25 +0200)
Add fields to structs to convey to kernel an indication whether the
library supports multi UARs per page and return to the library the size
of a UAR based on the queried value.

Signed-off-by: Eli Cohen <eli@mellanox.com>
Reviewed-by: Matan Barak <matanb@mellanox.com>
Signed-off-by: Leon Romanovsky <leon@kernel.org>
Signed-off-by: Saeed Mahameed <saeedm@mellanox.com>
drivers/infiniband/hw/mlx5/main.c
drivers/net/ethernet/mellanox/mlx5/core/cq.c
drivers/net/ethernet/mellanox/mlx5/core/en.h
drivers/net/ethernet/mellanox/mlx5/core/en_common.c
drivers/net/ethernet/mellanox/mlx5/core/en_main.c
drivers/net/ethernet/mellanox/mlx5/core/uar.c
include/linux/mlx5/cq.h
include/linux/mlx5/driver.h
include/uapi/rdma/mlx5-abi.h

index 664067239de519f8ded1e53501d6f603f6cc4bd4..a191b9327b0c1d5de95529e7395f1635547a46d6 100644 (file)
@@ -992,6 +992,12 @@ out:
        return err;
 }
 
+static void print_lib_caps(struct mlx5_ib_dev *dev, u64 caps)
+{
+       mlx5_ib_dbg(dev, "MLX5_LIB_CAP_4K_UAR = %s\n",
+                   caps & MLX5_LIB_CAP_4K_UAR ? "y" : "n");
+}
+
 static int calc_total_bfregs(struct mlx5_ib_dev *dev, bool lib_uar_4k,
                             struct mlx5_ib_alloc_ucontext_req_v2 *req,
                             u32 *num_sys_pages)
@@ -1122,6 +1128,10 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev,
        resp.cqe_version = min_t(__u8,
                                 (__u8)MLX5_CAP_GEN(dev->mdev, cqe_version),
                                 req.max_cqe_version);
+       resp.log_uar_size = MLX5_CAP_GEN(dev->mdev, uar_4k) ?
+                               MLX5_ADAPTER_PAGE_SHIFT : PAGE_SHIFT;
+       resp.num_uars_per_page = MLX5_CAP_GEN(dev->mdev, uar_4k) ?
+                                       MLX5_CAP_GEN(dev->mdev, num_of_uars_per_page) : 1;
        resp.response_length = min(offsetof(typeof(resp), response_length) +
                                   sizeof(resp.response_length), udata->outlen);
 
@@ -1129,7 +1139,7 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev,
        if (!context)
                return ERR_PTR(-ENOMEM);
 
-       lib_uar_4k = false;
+       lib_uar_4k = req.lib_caps & MLX5_LIB_CAP_4K_UAR;
        bfregi = &context->bfregi;
 
        /* updates req->total_num_bfregs */
@@ -1209,6 +1219,12 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev,
                                        sizeof(resp.reserved2);
        }
 
+       if (field_avail(typeof(resp), log_uar_size, udata->outlen))
+               resp.response_length += sizeof(resp.log_uar_size);
+
+       if (field_avail(typeof(resp), num_uars_per_page, udata->outlen))
+               resp.response_length += sizeof(resp.num_uars_per_page);
+
        err = ib_copy_to_udata(udata, &resp, resp.response_length);
        if (err)
                goto out_td;
@@ -1216,7 +1232,8 @@ static struct ib_ucontext *mlx5_ib_alloc_ucontext(struct ib_device *ibdev,
        bfregi->ver = ver;
        bfregi->num_low_latency_bfregs = req.num_low_latency_bfregs;
        context->cqe_version = resp.cqe_version;
-       context->lib_caps = false;
+       context->lib_caps = req.lib_caps;
+       print_lib_caps(dev, context->lib_caps);
 
        return &context->ibucontext;
 
index 32d4af9b594d6950b5f91ee64a1445cb81ebe182..336d4738b807f863d14edb594a8b94292eb8cbf2 100644 (file)
@@ -179,6 +179,8 @@ int mlx5_core_create_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq,
                mlx5_core_dbg(dev, "failed adding CP 0x%x to debug file system\n",
                              cq->cqn);
 
+       cq->uar = dev->priv.uar;
+
        return 0;
 
 err_cmd:
index 3037631570b1ffd6b0175ff68e7be22a38723b39..a473cea10c16eca565101dd550762f853ce2238b 100644 (file)
@@ -465,7 +465,6 @@ struct mlx5e_sq {
        /* read only */
        struct mlx5_wq_cyc         wq;
        u32                        dma_fifo_mask;
-       void __iomem              *uar_map;
        struct netdev_queue       *txq;
        u32                        sqn;
        u16                        bf_buf_size;
@@ -479,7 +478,7 @@ struct mlx5e_sq {
 
        /* control path */
        struct mlx5_wq_ctrl        wq_ctrl;
-       struct mlx5_uar            uar;
+       struct mlx5_sq_bfreg       bfreg;
        struct mlx5e_channel      *channel;
        int                        tc;
        u32                        rate_limit;
@@ -806,7 +805,7 @@ void mlx5e_set_rx_cq_mode_params(struct mlx5e_params *params,
 static inline void mlx5e_tx_notify_hw(struct mlx5e_sq *sq,
                                      struct mlx5_wqe_ctrl_seg *ctrl, int bf_sz)
 {
-       u16 ofst = MLX5_BF_OFFSET + sq->bf_offset;
+       u16 ofst = sq->bf_offset;
 
        /* ensure wqe is visible to device before updating doorbell record */
        dma_wmb();
@@ -818,9 +817,9 @@ static inline void mlx5e_tx_notify_hw(struct mlx5e_sq *sq,
         */
        wmb();
        if (bf_sz)
-               __iowrite64_copy(sq->uar_map + ofst, ctrl, bf_sz);
+               __iowrite64_copy(sq->bfreg.map + ofst, ctrl, bf_sz);
        else
-               mlx5_write64((__be32 *)ctrl, sq->uar_map + ofst, NULL);
+               mlx5_write64((__be32 *)ctrl, sq->bfreg.map + ofst, NULL);
        /* flush the write-combining mapped buffer */
        wmb();
 
index f175518ff07aa9163e6e84022a4e9ae4c4c9f9da..bd898d8deda0ce0c4d6dca7f1ac26722eacf96c4 100644 (file)
@@ -89,16 +89,10 @@ int mlx5e_create_mdev_resources(struct mlx5_core_dev *mdev)
        struct mlx5e_resources *res = &mdev->mlx5e_res;
        int err;
 
-       err = mlx5_alloc_map_uar(mdev, &res->cq_uar, false);
-       if (err) {
-               mlx5_core_err(mdev, "alloc_map uar failed, %d\n", err);
-               return err;
-       }
-
        err = mlx5_core_alloc_pd(mdev, &res->pdn);
        if (err) {
                mlx5_core_err(mdev, "alloc pd failed, %d\n", err);
-               goto err_unmap_free_uar;
+               return err;
        }
 
        err = mlx5_core_alloc_transport_domain(mdev, &res->td.tdn);
@@ -121,9 +115,6 @@ err_dealloc_transport_domain:
        mlx5_core_dealloc_transport_domain(mdev, res->td.tdn);
 err_dealloc_pd:
        mlx5_core_dealloc_pd(mdev, res->pdn);
-err_unmap_free_uar:
-       mlx5_unmap_free_uar(mdev, &res->cq_uar);
-
        return err;
 }
 
@@ -134,7 +125,6 @@ void mlx5e_destroy_mdev_resources(struct mlx5_core_dev *mdev)
        mlx5_core_destroy_mkey(mdev, &res->mkey);
        mlx5_core_dealloc_transport_domain(mdev, res->td.tdn);
        mlx5_core_dealloc_pd(mdev, res->pdn);
-       mlx5_unmap_free_uar(mdev, &res->cq_uar);
 }
 
 int mlx5e_refresh_tirs_self_loopback(struct mlx5_core_dev *mdev,
index 5ff86f0ecb7b32a83b0cb4a561c42a33622e8250..c32754b1598ef8df42c2233ae88dad321606077a 100644 (file)
@@ -991,7 +991,7 @@ static int mlx5e_create_sq(struct mlx5e_channel *c,
        sq->channel   = c;
        sq->tc        = tc;
 
-       err = mlx5_alloc_map_uar(mdev, &sq->uar, !!MLX5_CAP_GEN(mdev, bf));
+       err = mlx5_alloc_bfreg(mdev, &sq->bfreg, MLX5_CAP_GEN(mdev, bf), false);
        if (err)
                return err;
 
@@ -1003,12 +1003,9 @@ static int mlx5e_create_sq(struct mlx5e_channel *c,
                goto err_unmap_free_uar;
 
        sq->wq.db       = &sq->wq.db[MLX5_SND_DBR];
-       if (sq->uar.bf_map) {
+       if (sq->bfreg.wc)
                set_bit(MLX5E_SQ_STATE_BF_ENABLE, &sq->state);
-               sq->uar_map = sq->uar.bf_map;
-       } else {
-               sq->uar_map = sq->uar.map;
-       }
+
        sq->bf_buf_size = (1 << MLX5_CAP_GEN(mdev, log_bf_reg_size)) / 2;
        sq->max_inline  = param->max_inline;
        sq->min_inline_mode =
@@ -1036,7 +1033,7 @@ err_sq_wq_destroy:
        mlx5_wq_destroy(&sq->wq_ctrl);
 
 err_unmap_free_uar:
-       mlx5_unmap_free_uar(mdev, &sq->uar);
+       mlx5_free_bfreg(mdev, &sq->bfreg);
 
        return err;
 }
@@ -1048,7 +1045,7 @@ static void mlx5e_destroy_sq(struct mlx5e_sq *sq)
 
        mlx5e_free_sq_db(sq);
        mlx5_wq_destroy(&sq->wq_ctrl);
-       mlx5_unmap_free_uar(priv->mdev, &sq->uar);
+       mlx5_free_bfreg(priv->mdev, &sq->bfreg);
 }
 
 static int mlx5e_enable_sq(struct mlx5e_sq *sq, struct mlx5e_sq_param *param)
@@ -1082,7 +1079,7 @@ static int mlx5e_enable_sq(struct mlx5e_sq *sq, struct mlx5e_sq_param *param)
        MLX5_SET(sqc,  sqc, tis_lst_sz, param->type == MLX5E_SQ_ICO ? 0 : 1);
 
        MLX5_SET(wq,   wq, wq_type,       MLX5_WQ_TYPE_CYCLIC);
-       MLX5_SET(wq,   wq, uar_page,      sq->uar.index);
+       MLX5_SET(wq,   wq, uar_page,      sq->bfreg.index);
        MLX5_SET(wq,   wq, log_wq_pg_sz,  sq->wq_ctrl.buf.page_shift -
                                          MLX5_ADAPTER_PAGE_SHIFT);
        MLX5_SET64(wq, wq, dbr_addr,      sq->wq_ctrl.db.dma);
@@ -1240,7 +1237,6 @@ static int mlx5e_create_cq(struct mlx5e_channel *c,
        mcq->comp       = mlx5e_completion_event;
        mcq->event      = mlx5e_cq_error_event;
        mcq->irqn       = irqn;
-       mcq->uar        = &mdev->mlx5e_res.cq_uar;
 
        for (i = 0; i < mlx5_cqwq_get_size(&cq->wq); i++) {
                struct mlx5_cqe64 *cqe = mlx5_cqwq_get_wqe(&cq->wq, i);
@@ -1289,7 +1285,7 @@ static int mlx5e_enable_cq(struct mlx5e_cq *cq, struct mlx5e_cq_param *param)
 
        MLX5_SET(cqc,   cqc, cq_period_mode, param->cq_period_mode);
        MLX5_SET(cqc,   cqc, c_eqn,         eqn);
-       MLX5_SET(cqc,   cqc, uar_page,      mcq->uar->index);
+       MLX5_SET(cqc,   cqc, uar_page,      mdev->priv.uar->index);
        MLX5_SET(cqc,   cqc, log_page_size, cq->wq_ctrl.frag_buf.page_shift -
                                            MLX5_ADAPTER_PAGE_SHIFT);
        MLX5_SET64(cqc, cqc, dbr_addr,      cq->wq_ctrl.db.dma);
@@ -1701,7 +1697,7 @@ static void mlx5e_build_common_cq_param(struct mlx5e_priv *priv,
 {
        void *cqc = param->cqc;
 
-       MLX5_SET(cqc, cqc, uar_page, priv->mdev->mlx5e_res.cq_uar.index);
+       MLX5_SET(cqc, cqc, uar_page, priv->mdev->priv.uar->index);
 }
 
 static void mlx5e_build_rx_cq_param(struct mlx5e_priv *priv,
@@ -2320,7 +2316,6 @@ static int mlx5e_create_drop_cq(struct mlx5e_priv *priv,
        mcq->comp       = mlx5e_completion_event;
        mcq->event      = mlx5e_cq_error_event;
        mcq->irqn       = irqn;
-       mcq->uar        = &mdev->mlx5e_res.cq_uar;
 
        cq->priv = priv;
 
index 07b273cccc265f7bed9e05e2e91a8bc099d630ab..2e6b0f290ddc2cbf3beeb2f5c1fe813378691c69 100644 (file)
 #include <linux/mlx5/cmd.h>
 #include "mlx5_core.h"
 
-enum {
-       NUM_DRIVER_UARS         = 4,
-       NUM_LOW_LAT_BFREGS      = 4,
-};
-
 int mlx5_cmd_alloc_uar(struct mlx5_core_dev *dev, u32 *uarn)
 {
        u32 out[MLX5_ST_SZ_DW(alloc_uar_out)] = {0};
@@ -67,57 +62,6 @@ int mlx5_cmd_free_uar(struct mlx5_core_dev *dev, u32 uarn)
 }
 EXPORT_SYMBOL(mlx5_cmd_free_uar);
 
-int mlx5_alloc_map_uar(struct mlx5_core_dev *mdev, struct mlx5_uar *uar,
-                      bool map_wc)
-{
-       phys_addr_t pfn;
-       phys_addr_t uar_bar_start;
-       int err;
-
-       err = mlx5_cmd_alloc_uar(mdev, &uar->index);
-       if (err) {
-               mlx5_core_warn(mdev, "mlx5_cmd_alloc_uar() failed, %d\n", err);
-               return err;
-       }
-
-       uar_bar_start = pci_resource_start(mdev->pdev, 0);
-       pfn           = (uar_bar_start >> PAGE_SHIFT) + uar->index;
-
-       if (map_wc) {
-               uar->bf_map = ioremap_wc(pfn << PAGE_SHIFT, PAGE_SIZE);
-               if (!uar->bf_map) {
-                       mlx5_core_warn(mdev, "ioremap_wc() failed\n");
-                       uar->map = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE);
-                       if (!uar->map)
-                               goto err_free_uar;
-               }
-       } else {
-               uar->map = ioremap(pfn << PAGE_SHIFT, PAGE_SIZE);
-               if (!uar->map)
-                       goto err_free_uar;
-       }
-
-       return 0;
-
-err_free_uar:
-       mlx5_core_warn(mdev, "ioremap() failed\n");
-       err = -ENOMEM;
-       mlx5_cmd_free_uar(mdev, uar->index);
-
-       return err;
-}
-EXPORT_SYMBOL(mlx5_alloc_map_uar);
-
-void mlx5_unmap_free_uar(struct mlx5_core_dev *mdev, struct mlx5_uar *uar)
-{
-       if (uar->map)
-               iounmap(uar->map);
-       else
-               iounmap(uar->bf_map);
-       mlx5_cmd_free_uar(mdev, uar->index);
-}
-EXPORT_SYMBOL(mlx5_unmap_free_uar);
-
 static int uars_per_sys_page(struct mlx5_core_dev *mdev)
 {
        if (MLX5_CAP_GEN(mdev, uar_4k))
index 996863381bc8e707b792a4b85511271cd85581b3..95898847c7d4420c70773893c260f0c2cbeef450 100644 (file)
@@ -42,13 +42,13 @@ struct mlx5_core_cq {
        int                     cqe_sz;
        __be32                 *set_ci_db;
        __be32                 *arm_db;
+       struct mlx5_uars_page  *uar;
        atomic_t                refcount;
        struct completion       free;
        unsigned                vector;
        unsigned int            irqn;
        void (*comp)            (struct mlx5_core_cq *);
        void (*event)           (struct mlx5_core_cq *, enum mlx5_event);
-       struct mlx5_uar        *uar;
        u32                     cons_index;
        unsigned                arm_sn;
        struct mlx5_rsc_debug   *dbg;
index 7e7394fef8352314d76fef633d72a74d54bffbfa..10e632588cd5e453dcbea516e1f84063a4e98c3e 100644 (file)
@@ -467,12 +467,6 @@ struct mlx5_sq_bfreg {
        unsigned int            offset;
 };
 
-struct mlx5_uar {
-       u32                     index;
-       void __iomem           *map;
-       void __iomem           *bf_map;
-};
-
 struct mlx5_core_health {
        struct health_buffer __iomem   *health;
        __be32 __iomem                 *health_counter;
@@ -725,7 +719,6 @@ struct mlx5_td {
 };
 
 struct mlx5e_resources {
-       struct mlx5_uar            cq_uar;
        u32                        pdn;
        struct mlx5_td             td;
        struct mlx5_core_mkey      mkey;
@@ -915,11 +908,6 @@ void mlx5_cmd_mbox_status(void *out, u8 *status, u32 *syndrome);
 int mlx5_core_get_caps(struct mlx5_core_dev *dev, enum mlx5_cap_type cap_type);
 int mlx5_cmd_alloc_uar(struct mlx5_core_dev *dev, u32 *uarn);
 int mlx5_cmd_free_uar(struct mlx5_core_dev *dev, u32 uarn);
-int mlx5_alloc_bfregs(struct mlx5_core_dev *dev, struct mlx5_bfreg_info *bfregi);
-int mlx5_free_bfregs(struct mlx5_core_dev *dev, struct mlx5_bfreg_info *bfregi);
-int mlx5_alloc_map_uar(struct mlx5_core_dev *mdev, struct mlx5_uar *uar,
-                      bool map_wc);
-void mlx5_unmap_free_uar(struct mlx5_core_dev *mdev, struct mlx5_uar *uar);
 void mlx5_health_cleanup(struct mlx5_core_dev *dev);
 int mlx5_health_init(struct mlx5_core_dev *dev);
 void mlx5_start_health_poll(struct mlx5_core_dev *dev);
index 86a8f30060f3789eb94559819c3b4f17ab072c6e..85dc966ea70be14a07863c1d6ccc88e3431c517d 100644 (file)
@@ -65,6 +65,10 @@ struct mlx5_ib_alloc_ucontext_req {
        __u32   num_low_latency_bfregs;
 };
 
+enum mlx5_lib_caps {
+       MLX5_LIB_CAP_4K_UAR     = (u64)1 << 0,
+};
+
 struct mlx5_ib_alloc_ucontext_req_v2 {
        __u32   total_num_bfregs;
        __u32   num_low_latency_bfregs;
@@ -74,6 +78,7 @@ struct mlx5_ib_alloc_ucontext_req_v2 {
        __u8    reserved0;
        __u16   reserved1;
        __u32   reserved2;
+       __u64   lib_caps;
 };
 
 enum mlx5_ib_alloc_ucontext_resp_mask {
@@ -103,6 +108,8 @@ struct mlx5_ib_alloc_ucontext_resp {
        __u8    cmds_supp_uhw;
        __u16   reserved2;
        __u64   hca_core_clock_offset;
+       __u32   log_uar_size;
+       __u32   num_uars_per_page;
 };
 
 struct mlx5_ib_alloc_pd_resp {