From a2df38ebba98611e24336c9e4ac4f709224aeadc Mon Sep 17 00:00:00 2001
From: Vladimir Sokolovsky <[EMAIL PROTECTED]>
Date: Sun, 18 May 2008 11:25:55 +0300
Subject: [PATCH] mlx4: implement MOD_STAT_CFG command to use for changing 
ConnectX page size

There was a bug in the mlx4 driver in mlx4_alloc_fmr which hardcoded
the minimum acceptable page_shift to be 12. However, new ConnectX firmware has a
minimum page_shift of 9 (log_pg_sz of 9 returned by QUERY_DEV_LIM) -- so that
ib_fmr_alloc fails for ULPs using the device minimum when creating FMRs.

To preserve firmware compatibility with released mlx4 drivers, the firmware
will continue to return 12 as before for log_page_sz in QUERY_DEV_CAP for these
drivers.
However, to enable new drivers to take advantage of the available smaller page
size, the mlx4 driver now first sets the log_pg_sz to the device minimum via
the MOD_STAT_CFG() command, and only then calls QUERY_DEV_CAP().
The QUERY_DEV_CAP() command then returns the new (lower) log_pg_sz value.

Signed-off-by: Jack Morgenstein <[EMAIL PROTECTED]>
Signed-off-by: Vladimir Sokolovsky <[EMAIL PROTECTED]>
---
 drivers/net/mlx4/fw.c   |   28 ++++++++++++++++++++++++++++
 drivers/net/mlx4/fw.h   |    6 ++++++
 drivers/net/mlx4/main.c |    7 +++++++
 3 files changed, 41 insertions(+), 0 deletions(-)

diff --git a/drivers/net/mlx4/fw.c b/drivers/net/mlx4/fw.c
index d82f275..2b5006b 100644
--- a/drivers/net/mlx4/fw.c
+++ b/drivers/net/mlx4/fw.c
@@ -101,6 +101,34 @@ static void dump_dev_cap_flags(struct mlx4_dev *dev, u32 
flags)
                        mlx4_dbg(dev, "    %s\n", fname[i]);
 }

+int mlx4_MOD_STAT_CFG(struct mlx4_dev *dev, struct mlx4_mod_stat_cfg *cfg)
+{
+       struct mlx4_cmd_mailbox *mailbox;
+       u32 *inbox;
+       int err = 0;
+
+#define MOD_STAT_CFG_IN_SIZE           0x100
+
+#define MOD_STAT_CFG_PG_SZ_M_OFFSET    0x002
+#define MOD_STAT_CFG_PG_SZ_OFFSET      0x003
+
+       mailbox = mlx4_alloc_cmd_mailbox(dev);
+       if (IS_ERR(mailbox))
+               return PTR_ERR(mailbox);
+       inbox = mailbox->buf;
+
+       memset(inbox, 0, MOD_STAT_CFG_IN_SIZE);
+
+       MLX4_PUT(inbox, cfg->log_pg_sz, MOD_STAT_CFG_PG_SZ_OFFSET);
+       MLX4_PUT(inbox, cfg->log_pg_sz_m, MOD_STAT_CFG_PG_SZ_M_OFFSET);
+
+       err = mlx4_cmd(dev, mailbox->dma, 0, 0, MLX4_CMD_MOD_STAT_CFG,
+                       MLX4_CMD_TIME_CLASS_A);
+
+       mlx4_free_cmd_mailbox(dev, mailbox);
+       return err;
+}
+
 int mlx4_QUERY_DEV_CAP(struct mlx4_dev *dev, struct mlx4_dev_cap *dev_cap)
 {
        struct mlx4_cmd_mailbox *mailbox;
diff --git a/drivers/net/mlx4/fw.h b/drivers/net/mlx4/fw.h
index 306cb9b..a0e046c 100644
--- a/drivers/net/mlx4/fw.h
+++ b/drivers/net/mlx4/fw.h
@@ -38,6 +38,11 @@
 #include "mlx4.h"
 #include "icm.h"

+struct mlx4_mod_stat_cfg {
+       u8 log_pg_sz;
+       u8 log_pg_sz_m;
+};
+
 struct mlx4_dev_cap {
        int max_srq_sz;
        int max_qp_sz;
@@ -162,5 +167,6 @@ int mlx4_SET_ICM_SIZE(struct mlx4_dev *dev, u64 icm_size, 
u64 *aux_pages);
 int mlx4_MAP_ICM_AUX(struct mlx4_dev *dev, struct mlx4_icm *icm);
 int mlx4_UNMAP_ICM_AUX(struct mlx4_dev *dev);
 int mlx4_NOP(struct mlx4_dev *dev);
+int mlx4_MOD_STAT_CFG(struct mlx4_dev *dev, struct mlx4_mod_stat_cfg *cfg);

 #endif /* MLX4_FW_H */
diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c
index a6aa49f..d373601 100644
--- a/drivers/net/mlx4/main.c
+++ b/drivers/net/mlx4/main.c
@@ -485,6 +485,7 @@ static int mlx4_init_hca(struct mlx4_dev *dev)
        struct mlx4_priv          *priv = mlx4_priv(dev);
        struct mlx4_adapter        adapter;
        struct mlx4_dev_cap        dev_cap;
+       struct mlx4_mod_stat_cfg   mlx4_cfg;
        struct mlx4_profile        profile;
        struct mlx4_init_hca_param init_hca;
        u64 icm_size;
@@ -502,6 +503,12 @@ static int mlx4_init_hca(struct mlx4_dev *dev)
                return err;
        }

+       mlx4_cfg.log_pg_sz_m = 1;
+       mlx4_cfg.log_pg_sz = 0;
+       err = mlx4_MOD_STAT_CFG(dev, &mlx4_cfg);
+       if (err)
+               mlx4_warn(dev, "Failed to override log_pg_sz parameter\n");
+
        err = mlx4_dev_cap(dev, &dev_cap);
        if (err) {
                mlx4_err(dev, "QUERY_DEV_CAP command failed, aborting.\n");
--
1.5.5.1

_______________________________________________
general mailing list
[email protected]
http://lists.openfabrics.org/cgi-bin/mailman/listinfo/general

To unsubscribe, please visit http://openib.org/mailman/listinfo/openib-general

Reply via email to