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>