From 09360d5408cb641abff0f32a172a3332f02e8e88 Mon Sep 17 00:00:00 2001 From: Eli Cohen Date: Wed, 30 May 2007 13:14:31 +0300 Subject: mlx4_core: Fix CQ context layout The reserved6 field should be 64 bits, not just 16 bits. Without this, the structure does not match the hardware layout on 32-bit architectures: the db_rec_addr field ends up at offset 52 instead of offset 56. The bug slipped by because the alignment of __be64 members ends up putting it in the right place on x86-64. Signed-off-by: Eli Cohen Signed-off-by: Roland Dreier --- drivers/net/mlx4/cq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/mlx4/cq.c b/drivers/net/mlx4/cq.c index 437d78ad091..39253d0c159 100644 --- a/drivers/net/mlx4/cq.c +++ b/drivers/net/mlx4/cq.c @@ -61,7 +61,7 @@ struct mlx4_cq_context { __be32 solicit_producer_index; __be32 consumer_index; __be32 producer_index; - u8 reserved6[2]; + u32 reserved6[2]; __be64 db_rec_addr; }; -- cgit v1.2.3 From b581401ed0cc83a4483ed39c00a14a60bacecc3a Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Thu, 7 Jun 2007 11:51:58 -0700 Subject: mlx4_core: Initialize ctx_list and ctx_lock earlier We may call mlx4_dispatch_event() before mlx4_register_device() is called for a device, because for example a catastrophic error happens immediately after we enable interrupts. Therefore priv->ctx_list and priv->ctx_lock need to be initialized earlier. This bug was actually exposed by the MSI-X bug that returned IRQ numbers to drivers in reverse order, so that the first FW command interrupt looked to mlx4 like a catastrophic error. Signed-off-by: Roland Dreier --- drivers/net/mlx4/intf.c | 3 --- drivers/net/mlx4/main.c | 2 ++ 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/mlx4/intf.c b/drivers/net/mlx4/intf.c index 65854f9e9c7..9ae951bf6aa 100644 --- a/drivers/net/mlx4/intf.c +++ b/drivers/net/mlx4/intf.c @@ -135,9 +135,6 @@ int mlx4_register_device(struct mlx4_dev *dev) struct mlx4_priv *priv = mlx4_priv(dev); struct mlx4_interface *intf; - INIT_LIST_HEAD(&priv->ctx_list); - spin_lock_init(&priv->ctx_lock); - mutex_lock(&intf_mutex); list_add_tail(&priv->dev_list, &dev_list); diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c index 20b8c0d3ced..d4172937025 100644 --- a/drivers/net/mlx4/main.c +++ b/drivers/net/mlx4/main.c @@ -787,6 +787,8 @@ static int __devinit mlx4_init_one(struct pci_dev *pdev, dev = &priv->dev; dev->pdev = pdev; + INIT_LIST_HEAD(&priv->ctx_list); + spin_lock_init(&priv->ctx_lock); /* * Now reset the HCA before we touch the PCI capabilities or -- cgit v1.2.3 From 2c5cb2355843f9958e19a4b243456be92f97c73b Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Sat, 2 Jun 2007 07:16:02 -0700 Subject: mlx4_core: Free catastrophic error MSI-X interrupt with correct dev_id We need to pass the same dev_id to free_irq() and request_irq(). When using MSI-X, the MLX4_EQ_CATAS interrupt uses a different dev_id from the other interrupts. Signed-off-by: Roland Dreier --- drivers/net/mlx4/eq.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/mlx4/eq.c b/drivers/net/mlx4/eq.c index 0f11adb8eb4..27a82cecd69 100644 --- a/drivers/net/mlx4/eq.c +++ b/drivers/net/mlx4/eq.c @@ -490,9 +490,11 @@ static void mlx4_free_irqs(struct mlx4_dev *dev) if (eq_table->have_irq) free_irq(dev->pdev->irq, dev); - for (i = 0; i < MLX4_NUM_EQ; ++i) + for (i = 0; i < MLX4_EQ_CATAS; ++i) if (eq_table->eq[i].have_irq) free_irq(eq_table->eq[i].irq, eq_table->eq + i); + if (eq_table->eq[MLX4_EQ_CATAS].have_irq) + free_irq(eq_table->eq[MLX4_EQ_CATAS].irq, dev); } static int __devinit mlx4_map_clr_int(struct mlx4_dev *dev) -- cgit v1.2.3 From 3e1db334dca97df9034ebeec4657329a2b37a811 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Sun, 3 Jun 2007 19:47:10 -0700 Subject: IB/mthca, mlx4_core: Fix typo in comment s/signifant/significant/ Signed-off-by: Roland Dreier --- drivers/net/mlx4/fw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/mlx4/fw.c b/drivers/net/mlx4/fw.c index cfa5cc07233..ab259b2e11a 100644 --- a/drivers/net/mlx4/fw.c +++ b/drivers/net/mlx4/fw.c @@ -477,7 +477,7 @@ int mlx4_QUERY_FW(struct mlx4_dev *dev) MLX4_GET(fw_ver, outbox, QUERY_FW_VER_OFFSET); /* - * FW subminor version is at more signifant bits than minor + * FW subminor version is at more significant bits than minor * version, so swap here. */ dev->caps.fw_ver = (fw_ver & 0xffff00000000ull) | -- cgit v1.2.3 From fe40900f408642e772739088d30636e2f3f7d0d8 Mon Sep 17 00:00:00 2001 From: Roland Dreier Date: Thu, 7 Jun 2007 23:24:36 -0700 Subject: mlx4_core: Check firmware command interface revision HCA firmware with incompatible changes to the FW commmand interface is coming soon. Add a check of the interface revision during initialization and bail out if the firmware advertises a revision that the driver doesn't know about. This will avoid strange failures later if the driver goes on using the wrong interface revision. Signed-off-by: Roland Dreier --- drivers/net/mlx4/fw.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/mlx4/fw.c b/drivers/net/mlx4/fw.c index ab259b2e11a..e7ca118c8df 100644 --- a/drivers/net/mlx4/fw.c +++ b/drivers/net/mlx4/fw.c @@ -37,6 +37,10 @@ #include "fw.h" #include "icm.h" +enum { + MLX4_COMMAND_INTERFACE_REV = 1 +}; + extern void __buggy_use_of_MLX4_GET(void); extern void __buggy_use_of_MLX4_PUT(void); @@ -452,10 +456,12 @@ int mlx4_QUERY_FW(struct mlx4_dev *dev) u32 *outbox; int err = 0; u64 fw_ver; + u16 cmd_if_rev; u8 lg; #define QUERY_FW_OUT_SIZE 0x100 #define QUERY_FW_VER_OFFSET 0x00 +#define QUERY_FW_CMD_IF_REV_OFFSET 0x0a #define QUERY_FW_MAX_CMD_OFFSET 0x0f #define QUERY_FW_ERR_START_OFFSET 0x30 #define QUERY_FW_ERR_SIZE_OFFSET 0x38 @@ -484,14 +490,29 @@ int mlx4_QUERY_FW(struct mlx4_dev *dev) ((fw_ver & 0xffff0000ull) >> 16) | ((fw_ver & 0x0000ffffull) << 16); + MLX4_GET(cmd_if_rev, outbox, QUERY_FW_CMD_IF_REV_OFFSET); + if (cmd_if_rev != MLX4_COMMAND_INTERFACE_REV) { + mlx4_err(dev, "Installed FW has unsupported " + "command interface revision %d.\n", + cmd_if_rev); + mlx4_err(dev, "(Installed FW version is %d.%d.%03d)\n", + (int) (dev->caps.fw_ver >> 32), + (int) (dev->caps.fw_ver >> 16) & 0xffff, + (int) dev->caps.fw_ver & 0xffff); + mlx4_err(dev, "This driver version supports only revision %d.\n", + MLX4_COMMAND_INTERFACE_REV); + err = -ENODEV; + goto out; + } + MLX4_GET(lg, outbox, QUERY_FW_MAX_CMD_OFFSET); cmd->max_cmds = 1 << lg; - mlx4_dbg(dev, "FW version %d.%d.%03d, max commands %d\n", + mlx4_dbg(dev, "FW version %d.%d.%03d (cmd intf rev %d), max commands %d\n", (int) (dev->caps.fw_ver >> 32), (int) (dev->caps.fw_ver >> 16) & 0xffff, (int) dev->caps.fw_ver & 0xffff, - cmd->max_cmds); + cmd_if_rev, cmd->max_cmds); MLX4_GET(fw->catas_offset, outbox, QUERY_FW_ERR_START_OFFSET); MLX4_GET(fw->catas_size, outbox, QUERY_FW_ERR_SIZE_OFFSET); -- cgit v1.2.3 From b2d9308ae43a9cfa56cc9682dc6ed63347a8d2bf Mon Sep 17 00:00:00 2001 From: Jack Morgenstein Date: Thu, 7 Jun 2007 23:24:38 -0700 Subject: mlx4_core: Don't set MTT address in dMPT entries with PA set If a dMPT entry has the PA flag (direct physical address) set, then the (unused) MTT base address field has to be set to 0. Signed-off-by: Jack Morgenstein Signed-off-by: Roland Dreier --- drivers/net/mlx4/mr.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/mlx4/mr.c b/drivers/net/mlx4/mr.c index b33864dab17..d0808fa3ec8 100644 --- a/drivers/net/mlx4/mr.c +++ b/drivers/net/mlx4/mr.c @@ -324,15 +324,17 @@ int mlx4_mr_enable(struct mlx4_dev *dev, struct mlx4_mr *mr) MLX4_MPT_FLAG_MIO | MLX4_MPT_FLAG_REGION | mr->access); - if (mr->mtt.order < 0) - mpt_entry->flags |= cpu_to_be32(MLX4_MPT_FLAG_PHYSICAL); mpt_entry->key = cpu_to_be32(key_to_hw_index(mr->key)); mpt_entry->pd = cpu_to_be32(mr->pd); mpt_entry->start = cpu_to_be64(mr->iova); mpt_entry->length = cpu_to_be64(mr->size); mpt_entry->entity_size = cpu_to_be32(mr->mtt.page_shift); - mpt_entry->mtt_seg = cpu_to_be64(mlx4_mtt_addr(dev, &mr->mtt)); + if (mr->mtt.order < 0) { + mpt_entry->flags |= cpu_to_be32(MLX4_MPT_FLAG_PHYSICAL); + mpt_entry->mtt_seg = 0; + } else + mpt_entry->mtt_seg = cpu_to_be64(mlx4_mtt_addr(dev, &mr->mtt)); err = mlx4_SW2HW_MPT(dev, mailbox, key_to_hw_index(mr->key) & (dev->caps.num_mpts - 1)); -- cgit v1.2.3