summaryrefslogtreecommitdiffstats
path: root/sys/dev/et
diff options
context:
space:
mode:
authoryongari <yongari@FreeBSD.org>2009-11-19 21:45:06 +0000
committeryongari <yongari@FreeBSD.org>2009-11-19 21:45:06 +0000
commit16c3f5116048eb97b6cf8fc71db77ebf33213a55 (patch)
tree74286bc822303c53eeb95453aeb4553930f02a3f /sys/dev/et
parent2192f568cc5a5ff84e5052f89dbfd740b739fad5 (diff)
downloadFreeBSD-src-16c3f5116048eb97b6cf8fc71db77ebf33213a55.zip
FreeBSD-src-16c3f5116048eb97b6cf8fc71db77ebf33213a55.tar.gz
Add MSI support.
Diffstat (limited to 'sys/dev/et')
-rw-r--r--sys/dev/et/if_et.c47
-rw-r--r--sys/dev/et/if_etvar.h7
2 files changed, 44 insertions, 10 deletions
diff --git a/sys/dev/et/if_et.c b/sys/dev/et/if_et.c
index d9af586..e6e5d60 100644
--- a/sys/dev/et/if_et.c
+++ b/sys/dev/et/if_et.c
@@ -76,6 +76,10 @@ MODULE_DEPEND(et, pci, 1, 1, 1);
MODULE_DEPEND(et, ether, 1, 1, 1);
MODULE_DEPEND(et, miibus, 1, 1, 1);
+/* Tunables. */
+static int msi_disable = 0;
+TUNABLE_INT("hw.re.msi_disable", &msi_disable);
+
static int et_probe(device_t);
static int et_attach(device_t);
static int et_detach(device_t);
@@ -230,7 +234,7 @@ et_attach(device_t dev)
struct et_softc *sc;
struct ifnet *ifp;
uint8_t eaddr[ETHER_ADDR_LEN];
- int error;
+ int cap, error, msic;
sc = device_get_softc(dev);
sc->dev = dev;
@@ -268,13 +272,38 @@ et_attach(device_t dev)
sc->sc_mem_bt = rman_get_bustag(sc->sc_mem_res);
sc->sc_mem_bh = rman_get_bushandle(sc->sc_mem_res);
+ msic = 0;
+ if (pci_find_extcap(dev, PCIY_EXPRESS, &cap) == 0) {
+ sc->sc_expcap = cap;
+ sc->sc_flags |= ET_FLAG_PCIE;
+ msic = pci_msi_count(dev);
+ if (bootverbose)
+ device_printf(dev, "MSI count : %d\n", msic);
+ }
+ if (msic > 0 && msi_disable == 0) {
+ msic = 1;
+ if (pci_alloc_msi(dev, &msic) == 0) {
+ if (msic == 1) {
+ device_printf(dev, "Using %d MSI message\n",
+ msic);
+ sc->sc_flags |= ET_FLAG_MSI;
+ } else
+ pci_release_msi(dev);
+ }
+ }
+
/*
* Allocate IRQ
*/
- sc->sc_irq_rid = 0;
- sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
- &sc->sc_irq_rid,
- RF_SHAREABLE | RF_ACTIVE);
+ if ((sc->sc_flags & ET_FLAG_MSI) == 0) {
+ sc->sc_irq_rid = 0;
+ sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
+ &sc->sc_irq_rid, RF_SHAREABLE | RF_ACTIVE);
+ } else {
+ sc->sc_irq_rid = 1;
+ sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ,
+ &sc->sc_irq_rid, RF_ACTIVE);
+ }
if (sc->sc_irq_res == NULL) {
device_printf(dev, "can't allocate irq\n");
error = ENXIO;
@@ -323,8 +352,7 @@ et_attach(device_t dev)
callout_init_mtx(&sc->sc_tick, &sc->sc_mtx, 0);
error = bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_NET | INTR_MPSAFE,
- NULL, et_intr, sc, &sc->sc_irq_handle);
-
+ NULL, et_intr, sc, &sc->sc_irq_handle);
if (error) {
ether_ifdetach(ifp);
device_printf(dev, "can't setup intr\n");
@@ -363,6 +391,8 @@ et_detach(device_t dev)
bus_release_resource(dev, SYS_RES_IRQ, sc->sc_irq_rid,
sc->sc_irq_res);
}
+ if ((sc->sc_flags & ET_FLAG_MSI) != 0)
+ pci_release_msi(dev);
if (sc->sc_mem_res != NULL) {
bus_release_resource(dev, SYS_RES_MEMORY, sc->sc_mem_rid,
@@ -1433,7 +1463,8 @@ et_chip_init(struct et_softc *sc)
CSR_WRITE_4(sc, ET_LOOPBACK, 0);
/* Clear MSI configure */
- CSR_WRITE_4(sc, ET_MSI_CFG, 0);
+ if ((sc->sc_flags & ET_FLAG_MSI) == 0)
+ CSR_WRITE_4(sc, ET_MSI_CFG, 0);
/* Disable timer */
CSR_WRITE_4(sc, ET_TIMER, 0);
diff --git a/sys/dev/et/if_etvar.h b/sys/dev/et/if_etvar.h
index 2c092ab..5077745 100644
--- a/sys/dev/et/if_etvar.h
+++ b/sys/dev/et/if_etvar.h
@@ -238,6 +238,7 @@ struct et_softc {
struct arpcom arpcom;
int sc_if_flags;
uint32_t sc_flags; /* ET_FLAG_ */
+ int sc_expcap;
int sc_mem_rid;
@@ -277,7 +278,9 @@ struct et_softc {
#define ET_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx)
#define ET_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_mtx, MA_OWNED)
-#define ET_FLAG_TXRX_ENABLED 0x1
-#define ET_FLAG_JUMBO 0x2
+#define ET_FLAG_PCIE 0x0001
+#define ET_FLAG_MSI 0x0002
+#define ET_FLAG_TXRX_ENABLED 0x0100
+#define ET_FLAG_JUMBO 0x0200
#endif /* !_IF_ETVAR_H */
OpenPOWER on IntegriCloud