Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 14 Dec 2009 20:49:50 +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: r200541 - head/sys/dev/vge
Message-ID:  <200912142049.nBEKnoAo037896@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: yongari
Date: Mon Dec 14 20:49:50 2009
New Revision: 200541
URL: http://svn.freebsd.org/changeset/base/200541

Log:
  Add MSI support for VT613x controllers.

Modified:
  head/sys/dev/vge/if_vge.c
  head/sys/dev/vge/if_vgevar.h

Modified: head/sys/dev/vge/if_vge.c
==============================================================================
--- head/sys/dev/vge/if_vge.c	Mon Dec 14 20:39:42 2009	(r200540)
+++ head/sys/dev/vge/if_vge.c	Mon Dec 14 20:49:50 2009	(r200541)
@@ -127,6 +127,10 @@ MODULE_DEPEND(vge, miibus, 1, 1, 1);
 
 #define VGE_CSUM_FEATURES    (CSUM_IP | CSUM_TCP | CSUM_UDP)
 
+/* Tunables */
+static int msi_disable = 0;
+TUNABLE_INT("hw.vge.msi_disable", &msi_disable);
+
 /*
  * Various supported device vendors/types and their names.
  */
@@ -954,7 +958,7 @@ vge_attach(device_t dev)
 	u_char eaddr[ETHER_ADDR_LEN];
 	struct vge_softc *sc;
 	struct ifnet *ifp;
-	int error = 0, cap, rid;
+	int error = 0, cap, msic, rid;
 
 	sc = device_get_softc(dev);
 	sc->vge_dev = dev;
@@ -982,12 +986,24 @@ vge_attach(device_t dev)
 		sc->vge_flags |= VGE_FLAG_PCIE;
 		sc->vge_expcap = cap;
 	}
+	rid = 0;
+	msic = pci_msi_count(dev);
+	if (msi_disable == 0 && msic > 0) {
+		msic = 1;
+		if (pci_alloc_msi(dev, &msic) == 0) {
+			if (msic == 1) {
+				sc->vge_flags |= VGE_FLAG_MSI;
+				device_printf(dev, "Using %d MSI message\n",
+				    msic);
+				rid = 1;
+			} else
+				pci_release_msi(dev);
+		}
+	}
 
 	/* Allocate interrupt */
-	rid = 0;
 	sc->vge_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
-	    RF_SHAREABLE | RF_ACTIVE);
-
+	    ((sc->vge_flags & VGE_FLAG_MSI) ? 0 : RF_SHAREABLE) | RF_ACTIVE);
 	if (sc->vge_irq == NULL) {
 		device_printf(dev, "couldn't map interrupt\n");
 		error = ENXIO;
@@ -1108,7 +1124,10 @@ vge_detach(device_t dev)
 	if (sc->vge_intrhand)
 		bus_teardown_intr(dev, sc->vge_irq, sc->vge_intrhand);
 	if (sc->vge_irq)
-		bus_release_resource(dev, SYS_RES_IRQ, 0, sc->vge_irq);
+		bus_release_resource(dev, SYS_RES_IRQ,
+		    sc->vge_flags & VGE_FLAG_MSI ? 1 : 0, sc->vge_irq);
+	if (sc->vge_flags & VGE_FLAG_MSI)
+		pci_release_msi(dev);
 	if (sc->vge_res)
 		bus_release_resource(dev, SYS_RES_MEMORY,
 		    PCIR_BAR(1), sc->vge_res);

Modified: head/sys/dev/vge/if_vgevar.h
==============================================================================
--- head/sys/dev/vge/if_vgevar.h	Mon Dec 14 20:39:42 2009	(r200540)
+++ head/sys/dev/vge/if_vgevar.h	Mon Dec 14 20:49:50 2009	(r200541)
@@ -144,6 +144,7 @@ struct vge_softc {
 	int			vge_phyaddr;
 	int			vge_flags;
 #define	VGE_FLAG_PCIE		0x0001
+#define	VGE_FLAG_MSI		0x0002
 #define	VGE_FLAG_LINK		0x8000
 	int			vge_expcap;
 	int			vge_camidx;



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