From: Doug Ledford <dledford@redhat.com> Date: Sat, 22 Aug 2009 08:58:31 -0400 Subject: [net] mlx4_en device multi-function patch Message-id: C7AE90B5-D4ED-4C53-A610-606E4CEDA206@redhat.com O-Subject: [Patch RHEL5] mlx4_en device multi-function patch Bugzilla: 500346 This is for bugzilla 500346. This patch updates the mlx4_en driver to be able to handle multi-function devices which Mellanox will be coming out with shortly. Submitted to Infiniband maintainer, tested locally and by submitter, and built through brew: https://brewweb.devel.redhat.com/taskinfo?taskID=1940489 commit 8cd024cecd1b9662ac92619c43185a07ba2ba60b Author: Doug Ledford <dledford@redhat.com> Date: Fri Aug 21 18:17:06 2009 -0400 [mlx4] Support more than one function on a device Signed-off-by: Doug Ledford <dledford@redhat.com> diff --git a/drivers/net/mlx4/cmd.c b/drivers/net/mlx4/cmd.c index 79387fc..afe9ec0 100644 --- a/drivers/net/mlx4/cmd.c +++ b/drivers/net/mlx4/cmd.c @@ -80,7 +80,9 @@ enum { /* Bad management packet (silently discarded): */ CMD_STAT_BAD_PKT = 0x30, /* More outstanding CQEs in CQ than new CQ size: */ - CMD_STAT_BAD_SIZE = 0x40 + CMD_STAT_BAD_SIZE = 0x40, + /* Multi Function device support required: */ + CMD_STAT_MULTI_FUNC_REQ = 0x50 }; enum { @@ -129,6 +131,7 @@ static int mlx4_status_to_errno(u8 status) [CMD_STAT_LAM_NOT_PRE] = -EAGAIN, [CMD_STAT_BAD_PKT] = -EINVAL, [CMD_STAT_BAD_SIZE] = -ENOMEM, + [CMD_STAT_MULTI_FUNC_REQ] = -EACCES, }; if (status >= ARRAY_SIZE(trans_table) || @@ -239,7 +242,7 @@ static int mlx4_cmd_poll(struct mlx4_dev *dev, u64 in_param, u64 *out_param, __raw_readl(hcr + HCR_OUT_PARAM_OFFSET + 4)); stat = be32_to_cpu((__force __be32) __raw_readl(hcr + HCR_STATUS_OFFSET)) >> 24; err = mlx4_status_to_errno(stat); - if (err) + if (err && err != CMD_STAT_MULTI_FUNC_REQ) mlx4_err(dev, "command 0x%x failed: fw status = 0x%x\n", op, stat); out: diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c index c0dc474..1ea81e9 100644 --- a/drivers/net/mlx4/main.c +++ b/drivers/net/mlx4/main.c @@ -859,7 +859,11 @@ static int mlx4_init_hca(struct mlx4_dev *dev) err = mlx4_QUERY_FW(dev); if (err) { - mlx4_err(dev, "QUERY_FW command failed, aborting.\n"); + if (err == -EACCES) + mlx4_dbg(dev, "Function disabled, please upgrade " + "to multi function driver.\n"); + else + mlx4_err(dev, "QUERY_FW command failed, aborting.\n"); return err; } @@ -1271,8 +1275,14 @@ static int __mlx4_init_one(struct pci_dev *pdev, const struct pci_device_id *id) } err = mlx4_init_hca(dev); - if (err) - goto err_cmd; + if (err) { + if (err == -EACCES) { + dev->flags |= MLX4_FLAG_NOT_PRIME; + pci_set_drvdata(pdev, dev); + return 0; + } else + goto err_cmd; + } mlx4_enable_msi_x(dev); @@ -1372,6 +1382,8 @@ static void mlx4_remove_one(struct pci_dev *pdev) int p; if (dev) { + if (dev->flags & MLX4_FLAG_NOT_PRIME) + goto cmd_cleanup; mlx4_sense_cleanup(dev); mlx4_unregister_device(dev); device_remove_file(&dev->pdev->dev, &priv->trigger_attr); @@ -1392,11 +1404,12 @@ static void mlx4_remove_one(struct pci_dev *pdev) mlx4_uar_free(dev, &priv->driver_uar); mlx4_cleanup_uar_table(dev); mlx4_close_hca(dev); - mlx4_cmd_cleanup(dev); if (dev->flags & MLX4_FLAG_MSI_X) pci_disable_msix(pdev); +cmd_cleanup: + mlx4_cmd_cleanup(dev); kfree(priv); pci_release_region(pdev, 2); pci_release_region(pdev, 0); @@ -1421,6 +1434,7 @@ static struct pci_device_id mlx4_pci_table[] = { { PCI_VDEVICE(MELLANOX, 0x6750) }, /* MT25408 "Hermon"EN 10GigE + Gen2 */ { PCI_VDEVICE(MELLANOX, 0x6372) }, /* MT25408 "YATIR" EN 10GigE */ { PCI_VDEVICE(MELLANOX, 0x675a) }, /* MT25408 "YATIR" EN 10GigE + Gen2 */ + { PCI_VDEVICE(MELLANOX, 0x6764) }, /* MT26468 "ConnectX 10GigE, PCIe, 2.0 5Gt/s] */ { 0, } }; diff --git a/include/linux/mlx4/device.h b/include/linux/mlx4/device.h index 39bf8bd..ad9c772 100644 --- a/include/linux/mlx4/device.h +++ b/include/linux/mlx4/device.h @@ -42,6 +42,7 @@ enum { MLX4_FLAG_MSI_X = 1 << 0, MLX4_FLAG_OLD_PORT_CMDS = 1 << 1, + MLX4_FLAG_NOT_PRIME = 1 << 2, }; enum {