Author: yongari
Date: Tue Nov 23 19:14:17 2010
New Revision: 215760
URL: http://svn.freebsd.org/changeset/base/215760

Log:
  MFC r215327,215350:
  r215327:
    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
  
  r215350:
    Plug memory leakage introduced in r215327.
  
    Submitted by:       jkim

Modified:
  stable/7/sys/dev/nfe/if_nfe.c
Directory Properties:
  stable/7/sys/   (props changed)
  stable/7/sys/cddl/contrib/opensolaris/   (props changed)
  stable/7/sys/contrib/dev/acpica/   (props changed)
  stable/7/sys/contrib/pf/   (props changed)

Modified: stable/7/sys/dev/nfe/if_nfe.c
==============================================================================
--- stable/7/sys/dev/nfe/if_nfe.c       Tue Nov 23 19:11:27 2010        
(r215759)
+++ stable/7/sys/dev/nfe/if_nfe.c       Tue Nov 23 19:14:17 2010        
(r215760)
@@ -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,48 @@ 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, use_msix;
+
+       /*
+        * 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");
+       use_msix = 1;
+       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) {
+                               use_msix = 0;
+                               break;
+                       }
+                       mblp++;
+               }
+       }
+       if (maker != NULL)
+               freeenv(maker);
+       if (product != NULL)
+               freeenv(product);
+
+       return (use_msix);
+}
+
+
 /* Take PHY/NIC out of powerdown, from Linux */
 static void
 nfe_power(struct nfe_softc *sc)
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to