Merge tag 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/rdma/rdma
[linux-2.6-block.git] / drivers / net / ethernet / mellanox / mlx5 / core / main.c
index 8391dde869a7e5bd6019776d14c20e4f7cd3ac80..70cc906a102b2dde87d161385126f43da4948266 100644 (file)
@@ -465,20 +465,17 @@ static int handle_hca_cap_odp(struct mlx5_core_dev *dev)
        void *set_hca_cap;
        void *set_ctx;
        int set_sz;
+       bool do_set = false;
        int err;
 
-       if (!MLX5_CAP_GEN(dev, pg))
+       if (!IS_ENABLED(CONFIG_INFINIBAND_ON_DEMAND_PAGING) ||
+           !MLX5_CAP_GEN(dev, pg))
                return 0;
 
        err = mlx5_core_get_caps(dev, MLX5_CAP_ODP);
        if (err)
                return err;
 
-       if (!(MLX5_CAP_ODP_MAX(dev, ud_odp_caps.srq_receive) ||
-             MLX5_CAP_ODP_MAX(dev, rc_odp_caps.srq_receive) ||
-             MLX5_CAP_ODP_MAX(dev, xrc_odp_caps.srq_receive)))
-               return 0;
-
        set_sz = MLX5_ST_SZ_BYTES(set_hca_cap_in);
        set_ctx = kzalloc(set_sz, GFP_KERNEL);
        if (!set_ctx)
@@ -488,19 +485,30 @@ static int handle_hca_cap_odp(struct mlx5_core_dev *dev)
        memcpy(set_hca_cap, dev->caps.hca_cur[MLX5_CAP_ODP],
               MLX5_ST_SZ_BYTES(odp_cap));
 
-       /* set ODP SRQ support for RC/UD and XRC transports */
-       MLX5_SET(odp_cap, set_hca_cap, ud_odp_caps.srq_receive,
-                MLX5_CAP_ODP_MAX(dev, ud_odp_caps.srq_receive));
-
-       MLX5_SET(odp_cap, set_hca_cap, rc_odp_caps.srq_receive,
-                MLX5_CAP_ODP_MAX(dev, rc_odp_caps.srq_receive));
-
-       MLX5_SET(odp_cap, set_hca_cap, xrc_odp_caps.srq_receive,
-                MLX5_CAP_ODP_MAX(dev, xrc_odp_caps.srq_receive));
-
-       err = set_caps(dev, set_ctx, set_sz, MLX5_SET_HCA_CAP_OP_MOD_ODP);
+#define ODP_CAP_SET_MAX(dev, field)                                            \
+       do {                                                                   \
+               u32 _res = MLX5_CAP_ODP_MAX(dev, field);                       \
+               if (_res) {                                                    \
+                       do_set = true;                                         \
+                       MLX5_SET(odp_cap, set_hca_cap, field, _res);           \
+               }                                                              \
+       } while (0)
+
+       ODP_CAP_SET_MAX(dev, ud_odp_caps.srq_receive);
+       ODP_CAP_SET_MAX(dev, rc_odp_caps.srq_receive);
+       ODP_CAP_SET_MAX(dev, xrc_odp_caps.srq_receive);
+       ODP_CAP_SET_MAX(dev, xrc_odp_caps.send);
+       ODP_CAP_SET_MAX(dev, xrc_odp_caps.receive);
+       ODP_CAP_SET_MAX(dev, xrc_odp_caps.write);
+       ODP_CAP_SET_MAX(dev, xrc_odp_caps.read);
+       ODP_CAP_SET_MAX(dev, xrc_odp_caps.atomic);
+
+       if (do_set)
+               err = set_caps(dev, set_ctx, set_sz,
+                              MLX5_SET_HCA_CAP_OP_MOD_ODP);
 
        kfree(set_ctx);
+
        return err;
 }
 
@@ -577,6 +585,33 @@ query_ex:
        return err;
 }
 
+static int set_hca_cap(struct mlx5_core_dev *dev)
+{
+       struct pci_dev *pdev = dev->pdev;
+       int err;
+
+       err = handle_hca_cap(dev);
+       if (err) {
+               dev_err(&pdev->dev, "handle_hca_cap failed\n");
+               goto out;
+       }
+
+       err = handle_hca_cap_atomic(dev);
+       if (err) {
+               dev_err(&pdev->dev, "handle_hca_cap_atomic failed\n");
+               goto out;
+       }
+
+       err = handle_hca_cap_odp(dev);
+       if (err) {
+               dev_err(&pdev->dev, "handle_hca_cap_odp failed\n");
+               goto out;
+       }
+
+out:
+       return err;
+}
+
 static int set_hca_ctrl(struct mlx5_core_dev *dev)
 {
        struct mlx5_reg_host_endianness he_in;
@@ -969,21 +1004,9 @@ static int mlx5_load_one(struct mlx5_core_dev *dev, struct mlx5_priv *priv,
                goto reclaim_boot_pages;
        }
 
-       err = handle_hca_cap(dev);
+       err = set_hca_cap(dev);
        if (err) {
-               dev_err(&pdev->dev, "handle_hca_cap failed\n");
-               goto reclaim_boot_pages;
-       }
-
-       err = handle_hca_cap_atomic(dev);
-       if (err) {
-               dev_err(&pdev->dev, "handle_hca_cap_atomic failed\n");
-               goto reclaim_boot_pages;
-       }
-
-       err = handle_hca_cap_odp(dev);
-       if (err) {
-               dev_err(&pdev->dev, "handle_hca_cap_odp failed\n");
+               dev_err(&pdev->dev, "set_hca_cap failed\n");
                goto reclaim_boot_pages;
        }