re(4): Use MSI if device supports it.
authorTim Bisson <bissont@mac.com>
Mon, 19 Mar 2012 02:39:37 +0000 (19:39 -0700)
committerFran├žois Tigeot <ftigeot@wolfpond.org>
Fri, 5 Oct 2012 09:50:58 +0000 (11:50 +0200)
RT8168E supports MSI.

sys/dev/netif/re/if_re.c
sys/dev/netif/re/if_revar.h

index 5cc60ae..567930e 100644 (file)
@@ -387,9 +387,11 @@ DRIVER_MODULE(miibus, re, miibus_driver, miibus_devclass, NULL, NULL);
 
 static int     re_rx_desc_count = RE_RX_DESC_CNT_DEF;
 static int     re_tx_desc_count = RE_TX_DESC_CNT_DEF;
 
 static int     re_rx_desc_count = RE_RX_DESC_CNT_DEF;
 static int     re_tx_desc_count = RE_TX_DESC_CNT_DEF;
+static int     re_msi_enable = 1;
 
 TUNABLE_INT("hw.re.rx_desc_count", &re_rx_desc_count);
 TUNABLE_INT("hw.re.tx_desc_count", &re_tx_desc_count);
 
 TUNABLE_INT("hw.re.rx_desc_count", &re_rx_desc_count);
 TUNABLE_INT("hw.re.tx_desc_count", &re_tx_desc_count);
+TUNABLE_INT("hw.re.msi.enable", &re_msi_enable);
 
 #define EE_SET(x)      \
        CSR_WRITE_1(sc, RE_EECMD, CSR_READ_1(sc, RE_EECMD) | (x))
 
 #define EE_SET(x)      \
        CSR_WRITE_1(sc, RE_EECMD, CSR_READ_1(sc, RE_EECMD) | (x))
@@ -1306,6 +1308,7 @@ re_attach(device_t dev)
        struct ifnet *ifp;
        uint8_t eaddr[ETHER_ADDR_LEN];
        int error = 0, rid, qlen;
        struct ifnet *ifp;
        uint8_t eaddr[ETHER_ADDR_LEN];
        int error = 0, rid, qlen;
+       u_int irq_flags;
 
        callout_init(&sc->re_timer);
        sc->re_dev = dev;
 
        callout_init(&sc->re_timer);
        sc->re_dev = dev;
@@ -1436,10 +1439,11 @@ re_attach(device_t dev)
        sc->re_bhandle = rman_get_bushandle(sc->re_res);
 
        /* Allocate interrupt */
        sc->re_bhandle = rman_get_bushandle(sc->re_res);
 
        /* Allocate interrupt */
-       rid = 0;
-       sc->re_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
-                                           RF_SHAREABLE | RF_ACTIVE);
+       sc->re_irq_type = pci_alloc_1intr(dev, re_msi_enable,
+                                          &sc->re_irq_rid, &irq_flags);
 
 
+       sc->re_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->re_irq_rid,
+                                           irq_flags);
        if (sc->re_irq == NULL) {
                device_printf(dev, "couldn't map interrupt\n");
                error = ENXIO;
        if (sc->re_irq == NULL) {
                device_printf(dev, "couldn't map interrupt\n");
                error = ENXIO;
@@ -1659,7 +1663,12 @@ re_detach(device_t dev)
                sysctl_ctx_free(&sc->re_sysctl_ctx);
 
        if (sc->re_irq)
                sysctl_ctx_free(&sc->re_sysctl_ctx);
 
        if (sc->re_irq)
-               bus_release_resource(dev, SYS_RES_IRQ, 0, sc->re_irq);
+               bus_release_resource(dev, SYS_RES_IRQ, sc->re_irq_rid,
+                                    sc->re_irq);
+
+       if (sc->re_irq_type == PCI_INTR_TYPE_MSI)
+               pci_release_msi(dev);
+
        if (sc->re_res) {
                bus_release_resource(dev, SYS_RES_IOPORT, RE_PCI_LOIO,
                                     sc->re_res);
        if (sc->re_res) {
                bus_release_resource(dev, SYS_RES_IOPORT, RE_PCI_LOIO,
                                     sc->re_res);
index 124407f..4e5ac37 100644 (file)
@@ -184,6 +184,8 @@ struct re_softc {
        int                     rxcycles;
        int                     re_rxbuf_size;
        int                     (*re_newbuf)(struct re_softc *, int, int);
        int                     rxcycles;
        int                     re_rxbuf_size;
        int                     (*re_newbuf)(struct re_softc *, int, int);
+       int                     re_irq_type;
+       int                     re_irq_rid;
 
        uint32_t                re_flags;       /* see RE_F_ */
        int                     re_if_flags;    /* saved ifnet.if_flags */
 
        uint32_t                re_flags;       /* see RE_F_ */
        int                     re_if_flags;    /* saved ifnet.if_flags */