diff options
author | yongari <yongari@FreeBSD.org> | 2009-12-14 20:49:50 +0000 |
---|---|---|
committer | yongari <yongari@FreeBSD.org> | 2009-12-14 20:49:50 +0000 |
commit | 6903a53024eaa277f73dcf33525acb8c048c52fe (patch) | |
tree | 804acea962c632ff2b5f467d3aa5053320705ef1 /sys/dev/vge | |
parent | 168c3be20e42c45d370fc8a0b8d094db9a495f92 (diff) | |
download | FreeBSD-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.c | 29 | ||||
-rw-r--r-- | sys/dev/vge/if_vgevar.h | 1 |
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; |