Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 2867

kernel-2.6.18-238.el5.src.rpm

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 {