summaryrefslogtreecommitdiffstats
path: root/sys/dev/vge
diff options
context:
space:
mode:
authoryongari <yongari@FreeBSD.org>2009-12-14 20:49:50 +0000
committeryongari <yongari@FreeBSD.org>2009-12-14 20:49:50 +0000
commit6903a53024eaa277f73dcf33525acb8c048c52fe (patch)
tree804acea962c632ff2b5f467d3aa5053320705ef1 /sys/dev/vge
parent168c3be20e42c45d370fc8a0b8d094db9a495f92 (diff)
downloadFreeBSD-src-6903a53024eaa277f73dcf33525acb8c048c52fe.zip
FreeBSD-src-6903a53024eaa277f73dcf33525acb8c048c52fe.tar.gz
Add MSI support for VT613x controllers.
Diffstat (limited to 'sys/dev/vge')
-rw-r--r--sys/dev/vge/if_vge.c29
-rw-r--r--sys/dev/vge/if_vgevar.h1
2 files changed, 25 insertions, 5 deletions
diff --git a/sys/dev/vge/if_vge.c b/sys/dev/vge/if_vge.c
index 07e3cd1..8296ad1a 100644
--- a/sys/dev/vge/if_vge.c
+++ b/sys/dev/vge/if_vge.c
@@ -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);
diff --git a/sys/dev/vge/if_vgevar.h b/sys/dev/vge/if_vgevar.h
index ffc60a1..6119288 100644
--- a/sys/dev/vge/if_vgevar.h
+++ b/sys/dev/vge/if_vgevar.h
@@ -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;
OpenPOWER on IntegriCloud