Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 14 Nov 2010 23:37:43 +0000 (UTC)
From:      Pyun YongHyeon <yongari@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r215327 - head/sys/dev/nfe
Message-ID:  <201011142337.oAENbheD097425@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: yongari
Date: Sun Nov 14 23:37:43 2010
New Revision: 215327
URL: http://svn.freebsd.org/changeset/base/215327

Log:
  P5N32-SLI PREMIUM from ASUSTeK is known to have MSI/MSI-X issue
  such that nfe(4) does not work with MSI-X. When MSI-X support was
  introduced, I remember MCP55 controller worked without problems so
  the issue could be either PCI bridge or BIOS issue. But I also
  noticed snd_hda(4) disabled MSI on all MCP55 chipset so I'm still
  not sure this is generic issue of MCP55 chipset. If this was PCI
  bridge issue we would have added it to a system wide black-list
  table but it's not clear to me at this moment whether it was caused
  by either broken BIOS or silicon bug of MCP55 chipset.
  
  To workaround the issue, maintain a MSI/MSI-X black-list table in
  driver and lookup base board manufacturer and product name from the
  table before attempting to use MSI-X. If driver find an matching
  entry, nfe(4) will not use MSI/MSI-X and fall back on traditional
  INTx mode. This approach should be the last resort since it relies
  on smbios and if another instance of MSI/MSI-X breakage is reported
  with different maker/product, we may have to get the PCI bridge
  black-listed instead of adding an new entry.
  
  PR:	kern/152150

Modified:
  head/sys/dev/nfe/if_nfe.c

Modified: head/sys/dev/nfe/if_nfe.c
==============================================================================
--- head/sys/dev/nfe/if_nfe.c	Sun Nov 14 23:05:57 2010	(r215326)
+++ head/sys/dev/nfe/if_nfe.c	Sun Nov 14 23:37:43 2010	(r215327)
@@ -77,6 +77,7 @@ static int  nfe_detach(device_t);
 static int  nfe_suspend(device_t);
 static int  nfe_resume(device_t);
 static int nfe_shutdown(device_t);
+static int  nfe_can_use_msix(struct nfe_softc *);
 static void nfe_power(struct nfe_softc *);
 static int  nfe_miibus_readreg(device_t, int, int);
 static int  nfe_miibus_writereg(device_t, int, int, int);
@@ -383,6 +384,13 @@ nfe_attach(device_t dev)
 			    "max. width of link(x%d)\n", width, v);
 	}
 
+	if (nfe_can_use_msix(sc) == 0) {
+		device_printf(sc->nfe_dev,
+		    "MSI/MSI-X capability black-listed, will use INTx\n"); 
+		msix_disable = 1;
+		msi_disable = 1;
+	}
+
 	/* Allocate interrupt */
 	if (msix_disable == 0 || msi_disable == 0) {
 		if (msix_disable == 0 &&
@@ -784,6 +792,41 @@ nfe_resume(device_t dev)
 }
 
 
+static int
+nfe_can_use_msix(struct nfe_softc *sc)
+{
+	static struct msix_blacklist {
+		char	*maker;
+		char	*product;
+	} msix_blacklists[] = {
+		{ "ASUSTeK Computer INC.", "P5N32-SLI PREMIUM" }
+	};
+
+	struct msix_blacklist *mblp;
+	char *maker, *product;
+	int count, n;
+
+	/*
+	 * Search base board manufacturer and product name table
+	 * to see this system has a known MSI/MSI-X issue.
+	 */
+	maker = getenv("smbios.planar.maker");
+	product = getenv("smbios.planar.product");
+	if (maker != NULL && product != NULL) {
+		count = sizeof(msix_blacklists) / sizeof(msix_blacklists[0]);
+		mblp = msix_blacklists;
+		for (n = 0; n < count; n++) {
+			if (strcmp(maker, mblp->maker) == 0 &&
+			    strcmp(product, mblp->product) == 0)
+				return (0);
+			mblp++;
+		}
+	}
+
+	return (1);
+}
+
+
 /* Take PHY/NIC out of powerdown, from Linux */
 static void
 nfe_power(struct nfe_softc *sc)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201011142337.oAENbheD097425>