Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 16 Jul 2008 10:35:13 -0700
From:      "David Christensen" <davidch@broadcom.com>
To:        "freebsd-net@freebsd.org" <freebsd-net@freebsd.org>
Subject:   Enabling MSI-X on -CURRENT for New Network Driver
Message-ID:  <5D267A3F22FD854F8F48B3D2B52381932677F1A0C3@IRVEXCHCCR01.corp.ad.broadcom.com>

next in thread | raw e-mail | index | archive | help
I'm working on adding MSI-X support for a new network driver
and having some difficulty in actually getting an interrupt.
Does this look right?

        /* Select and configure the IRQ. */
        sc->bxe_msix_count =3D pci_msix_count(dev);
        rid =3D 1;

        /* Try allocating MSI-X interrupts. */
        if ((sc->bxe_cap_flags & BXE_MSIX_CAPABLE_FLAG) &&
                (bxe_msi_enable >=3D 2) && (sc->bxe_msix_count > 0)) {

                int msix_needed =3D sc->bxe_msix_count;

                if (pci_alloc_msix(dev, &sc->bxe_msix_count) =3D=3D 0) {
                        if (sc->bxe_msix_count =3D=3D msix_needed) {
                                DBPRINT(sc, BXE_INFO_LOAD, "%s(): Using %d =
MSI-X "
                                        "vector(s).\n", __FUNCTION__, sc->b=
xe_msix_count);
                                sc->bxe_flags |=3D BXE_USING_MSIX_FLAG;
                        } else {
                                pci_release_msi(dev);
                                sc->bxe_flags &=3D ~BXE_USING_MSIX_FLAG;
                                sc->bxe_msix_count =3D 0;
                        }
                }
        }

        /* Try allocating MSI interrupts if we didn't get MSI-X. */

        ...

        /* Try legacy interrupt. */
        ...

        /* Allocate the interrupt and report any errors. */
        sc->bxe_res_irq =3D bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
                RF_ACTIVE);

        /* Report any IRQ allocation errors. */
        if (sc->bxe_res_irq =3D=3D NULL) {
                BXE_PRINTF("%s(%d): PCI map interrupt failed!\n",
                        __FILE__, __LINE__);
                rc =3D ENXIO;
                goto bxe_attach_fail;
        }

        sc->bxe_irq_rid =3D rid;
        sc->bxe_intr =3D bxe_intr;


The allocation doesn't fail and I usually see an IRQ allocated to
the driver using "vmstat -i" (though not always):

=3D=3D=3D[root] /usr/src/sys/modules/bxe # vmstat -i
interrupt                          total       rate
irq1: atkbd0                           1          0
irq4: sio0                         46432          6
irq6: fdc0                            10          0
irq14: ata0                           58          0
irq17: atapci1                     42684          5
cpu0: timer                     15331063       1999
irq256: em0                          917          0
cpu3: timer                     15330811       1999
cpu1: timer                     15330808       1999
cpu2: timer                     15330811       1999
cpu5: timer                     15330811       1999
cpu6: timer                     15330810       1999
cpu4: timer                     15330806       1999
cpu7: timer                     15330811       1999
irq258: bxe0                           2          0
Total                          122736835      16010

But my interrupt handler doesn't seem to be called.
The goal is to get a single interrupt working first,
multiple queue support comes next.  Any ideas?

Dave





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