From f33ac8a4449a4ea4b3bb35641c298e6d9836c81f Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Wed, 10 Apr 2013 17:05:56 +0800 Subject: [PATCH] bnx: Group interrupt related fields together --- sys/dev/netif/bnx/if_bnx.c | 198 ++++++++++++++++++++++------------ sys/dev/netif/bnx/if_bnxvar.h | 40 +++++-- 2 files changed, 159 insertions(+), 79 deletions(-) diff --git a/sys/dev/netif/bnx/if_bnx.c b/sys/dev/netif/bnx/if_bnx.c index 5783e3189c..5482054778 100644 --- a/sys/dev/netif/bnx/if_bnx.c +++ b/sys/dev/netif/bnx/if_bnx.c @@ -163,6 +163,8 @@ static void bnx_rxeof(struct bnx_rx_ret_ring *, uint16_t, int); static int bnx_alloc_intr(struct bnx_softc *); static int bnx_setup_intr(struct bnx_softc *); static void bnx_free_intr(struct bnx_softc *); +static void bnx_teardown_intr(struct bnx_softc *, int); +static void bnx_check_intr(void *); static void bnx_start(struct ifnet *, struct ifaltq_subque *); static int bnx_ioctl(struct ifnet *, u_long, caddr_t, struct ucred *); @@ -1685,8 +1687,8 @@ bnx_attach(device_t dev) sc = device_get_softc(dev); sc->bnx_dev = dev; callout_init_mp(&sc->bnx_stat_timer); - callout_init_mp(&sc->bnx_intr_timer); lwkt_serialize_init(&sc->bnx_jslot_serializer); + lwkt_serialize_init(&sc->bnx_main_serialize); product = pci_get_device(dev); @@ -1808,7 +1810,7 @@ bnx_attach(device_t dev) * For the rest of the chips in these two families, we will * have to poll the status block at high rate (10ms currently) * to check whether the interrupt is hosed or not. - * See bnx_intr_check() for details. + * See bnx_check_intr() for details. */ sc->bnx_flags |= BNX_FLAG_STATUSTAG_BUG; } @@ -2101,9 +2103,9 @@ bnx_attach(device_t dev) /* * Call MI attach routine. */ - ether_ifattach(ifp, ether_addr, NULL); + ether_ifattach(ifp, ether_addr, &sc->bnx_main_serialize); - ifq_set_cpuid(&ifp->if_snd, sc->bnx_intr_cpuid); + ifq_set_cpuid(&ifp->if_snd, sc->bnx_tx_ring[0].bnx_tx_cpuid); #ifdef IFPOLL_ENABLE ifpoll_compat_setup(&sc->bnx_npoll, @@ -2117,8 +2119,7 @@ bnx_attach(device_t dev) goto fail; } - sc->bnx_intr_cpuid = rman_get_cpuid(sc->bnx_irq); - sc->bnx_stat_cpuid = sc->bnx_intr_cpuid; + sc->bnx_stat_cpuid = sc->bnx_intr_data[0].bnx_intr_cpuid; return(0); fail: @@ -2137,7 +2138,7 @@ bnx_detach(device_t dev) lwkt_serialize_enter(ifp->if_serializer); bnx_stop(sc); bnx_reset(sc); - bus_teardown_intr(dev, sc->bnx_irq, sc->bnx_intrhand); + bnx_teardown_intr(sc, sc->bnx_intr_cnt); lwkt_serialize_exit(ifp->if_serializer); ether_ifdetach(ifp); @@ -2526,7 +2527,7 @@ bnx_npoll(struct ifnet *ifp, struct ifpoll_info *info) } else { if (ifp->if_flags & IFF_RUNNING) bnx_enable_intr(sc); - ifq_set_cpuid(&ifp->if_snd, sc->bnx_intr_cpuid); + ifq_set_cpuid(&ifp->if_snd, sc->bnx_tx_ring[0].bnx_tx_cpuid); } } @@ -3000,7 +3001,7 @@ bnx_init(void *xsc) else CSR_WRITE_4(sc, BGE_MAX_RX_FRAME_LOWAT, 2); - if (sc->bnx_irq_type == PCI_INTR_TYPE_MSI) { + if (sc->bnx_intr_type == PCI_INTR_TYPE_MSI) { if (bootverbose) { if_printf(ifp, "MSI_MODE: %#x\n", CSR_READ_4(sc, BGE_MSI_MODE)); @@ -3869,51 +3870,59 @@ bnx_coal_change(struct bnx_softc *sc) } static void -bnx_intr_check(void *xsc) +bnx_check_intr(void *xintr) { - struct bnx_softc *sc = xsc; - struct bnx_tx_ring *txr = &sc->bnx_tx_ring[0]; /* XXX */ - struct bnx_rx_ret_ring *ret = &sc->bnx_rx_ret_ring[0]; /* XXX */ - struct ifnet *ifp = &sc->arpcom.ac_if; + struct bnx_intr_data *intr = xintr; + struct bnx_rx_ret_ring *ret; + struct bnx_tx_ring *txr; + struct ifnet *ifp; - lwkt_serialize_enter(ifp->if_serializer); + lwkt_serialize_enter(intr->bnx_intr_serialize); - KKASSERT(mycpuid == sc->bnx_intr_cpuid); + KKASSERT(mycpuid == intr->bnx_intr_cpuid); + ifp = &intr->bnx_sc->arpcom.ac_if; if ((ifp->if_flags & (IFF_RUNNING | IFF_NPOLLING)) != IFF_RUNNING) { - lwkt_serialize_exit(ifp->if_serializer); + lwkt_serialize_exit(intr->bnx_intr_serialize); return; } + txr = intr->bnx_txr; + ret = intr->bnx_ret; + if (*ret->bnx_rx_considx != ret->bnx_rx_saved_considx || *txr->bnx_tx_considx != txr->bnx_tx_saved_considx) { - if (sc->bnx_rx_check_considx == ret->bnx_rx_saved_considx && - sc->bnx_tx_check_considx == txr->bnx_tx_saved_considx) { - if (!sc->bnx_intr_maylose) { - sc->bnx_intr_maylose = TRUE; + if (intr->bnx_rx_check_considx == ret->bnx_rx_saved_considx && + intr->bnx_tx_check_considx == txr->bnx_tx_saved_considx) { + if (!intr->bnx_intr_maylose) { + intr->bnx_intr_maylose = TRUE; goto done; } if (bootverbose) if_printf(ifp, "lost interrupt\n"); - bnx_msi(sc); + intr->bnx_intr_func(intr->bnx_intr_arg); } } - sc->bnx_intr_maylose = FALSE; - sc->bnx_rx_check_considx = ret->bnx_rx_saved_considx; - sc->bnx_tx_check_considx = txr->bnx_tx_saved_considx; + intr->bnx_intr_maylose = FALSE; + intr->bnx_rx_check_considx = ret->bnx_rx_saved_considx; + intr->bnx_tx_check_considx = txr->bnx_tx_saved_considx; done: - callout_reset(&sc->bnx_intr_timer, BNX_INTR_CKINTVL, - bnx_intr_check, sc); - lwkt_serialize_exit(ifp->if_serializer); + callout_reset(&intr->bnx_intr_timer, BNX_INTR_CKINTVL, + intr->bnx_intr_check, intr); + lwkt_serialize_exit(intr->bnx_intr_serialize); } static void bnx_enable_intr(struct bnx_softc *sc) { struct ifnet *ifp = &sc->arpcom.ac_if; + int i; - lwkt_serialize_handler_enable(ifp->if_serializer); + for (i = 0; i < sc->bnx_intr_cnt; ++i) { + lwkt_serialize_handler_enable( + sc->bnx_intr_data[i].bnx_intr_serialize); + } /* * Enable interrupt. @@ -3938,23 +3947,35 @@ bnx_enable_intr(struct bnx_softc *sc) BNX_SETBIT(sc, BGE_MISC_LOCAL_CTL, BGE_MLC_INTR_SET); if (sc->bnx_flags & BNX_FLAG_STATUSTAG_BUG) { - sc->bnx_intr_maylose = FALSE; - sc->bnx_rx_check_considx = 0; - sc->bnx_tx_check_considx = 0; - if (bootverbose) if_printf(ifp, "status tag bug workaround\n"); - /* 10ms check interval */ - callout_reset_bycpu(&sc->bnx_intr_timer, BNX_INTR_CKINTVL, - bnx_intr_check, sc, sc->bnx_intr_cpuid); + for (i = 0; i < sc->bnx_intr_cnt; ++i) { + struct bnx_intr_data *intr = &sc->bnx_intr_data[i]; + + intr->bnx_intr_maylose = FALSE; + intr->bnx_rx_check_considx = 0; + intr->bnx_tx_check_considx = 0; + callout_reset_bycpu(&intr->bnx_intr_timer, + BNX_INTR_CKINTVL, intr->bnx_intr_check, intr, + intr->bnx_intr_cpuid); + } } } static void bnx_disable_intr(struct bnx_softc *sc) { - struct ifnet *ifp = &sc->arpcom.ac_if; + int i; + + for (i = 0; i < sc->bnx_intr_cnt; ++i) { + struct bnx_intr_data *intr = &sc->bnx_intr_data[i]; + + callout_stop(&intr->bnx_intr_timer); + intr->bnx_intr_maylose = FALSE; + intr->bnx_rx_check_considx = 0; + intr->bnx_tx_check_considx = 0; + } /* * Mask the interrupt when we start polling. @@ -3967,14 +3988,11 @@ bnx_disable_intr(struct bnx_softc *sc) */ bnx_writembx(sc, BGE_MBX_IRQ0_LO, 1); - callout_stop(&sc->bnx_intr_timer); - sc->bnx_intr_maylose = FALSE; - sc->bnx_rx_check_considx = 0; - sc->bnx_tx_check_considx = 0; - sc->bnx_npoll.ifpc_stcount = 0; - - lwkt_serialize_handler_disable(ifp->if_serializer); + for (i = 0; i < sc->bnx_intr_cnt; ++i) { + lwkt_serialize_handler_disable( + sc->bnx_intr_data[i].bnx_intr_serialize); + } } static int @@ -4380,58 +4398,98 @@ bnx_destroy_rx_ret_ring(struct bnx_rx_ret_ring *ret) static int bnx_alloc_intr(struct bnx_softc *sc) { + struct bnx_intr_data *intr; u_int intr_flags; - sc->bnx_irq_type = pci_alloc_1intr(sc->bnx_dev, bnx_msi_enable, - &sc->bnx_irq_rid, &intr_flags); + sc->bnx_intr_cnt = 1; + + intr = &sc->bnx_intr_data[0]; + intr->bnx_sc = sc; + intr->bnx_ret = &sc->bnx_rx_ret_ring[0]; + intr->bnx_txr = &sc->bnx_tx_ring[0]; + intr->bnx_intr_serialize = &sc->bnx_main_serialize; + callout_init_mp(&intr->bnx_intr_timer); + intr->bnx_intr_check = bnx_check_intr; - sc->bnx_irq = bus_alloc_resource_any(sc->bnx_dev, SYS_RES_IRQ, - &sc->bnx_irq_rid, intr_flags); - if (sc->bnx_irq == NULL) { + sc->bnx_intr_type = pci_alloc_1intr(sc->bnx_dev, bnx_msi_enable, + &intr->bnx_intr_rid, &intr_flags); + + intr->bnx_intr_res = bus_alloc_resource_any(sc->bnx_dev, SYS_RES_IRQ, + &intr->bnx_intr_rid, intr_flags); + if (intr->bnx_intr_res == NULL) { device_printf(sc->bnx_dev, "could not alloc interrupt\n"); return ENXIO; } - if (sc->bnx_irq_type == PCI_INTR_TYPE_MSI) { + if (sc->bnx_intr_type == PCI_INTR_TYPE_MSI) { sc->bnx_flags |= BNX_FLAG_ONESHOT_MSI; bnx_enable_msi(sc); + + if (sc->bnx_flags & BNX_FLAG_ONESHOT_MSI) { + intr->bnx_intr_func = bnx_msi_oneshot; + if (bootverbose) + device_printf(sc->bnx_dev, "oneshot MSI\n"); + } else { + intr->bnx_intr_func = bnx_msi; + } + } else { + intr->bnx_intr_func = bnx_intr_legacy; } + intr->bnx_intr_arg = sc; + intr->bnx_intr_cpuid = rman_get_cpuid(intr->bnx_intr_res); + + intr->bnx_txr->bnx_tx_cpuid = intr->bnx_intr_cpuid; + return 0; } static int bnx_setup_intr(struct bnx_softc *sc) { - driver_intr_t *intr_func; - int error; + int error, i; - if (sc->bnx_irq_type == PCI_INTR_TYPE_MSI) { - if (sc->bnx_flags & BNX_FLAG_ONESHOT_MSI) { - intr_func = bnx_msi_oneshot; - if (bootverbose) - device_printf(sc->bnx_dev, "oneshot MSI\n"); - } else { - intr_func = bnx_msi; + for (i = 0; i < sc->bnx_intr_cnt; ++i) { + struct bnx_intr_data *intr = &sc->bnx_intr_data[i]; + + error = bus_setup_intr_descr(sc->bnx_dev, intr->bnx_intr_res, + INTR_MPSAFE, intr->bnx_intr_func, intr->bnx_intr_arg, + &intr->bnx_intr_hand, intr->bnx_intr_serialize, + intr->bnx_intr_desc); + if (error) { + device_printf(sc->bnx_dev, + "could not set up %dth intr\n", i); + bnx_teardown_intr(sc, i); + return error; } - } else { - intr_func = bnx_intr_legacy; - } - error = bus_setup_intr(sc->bnx_dev, sc->bnx_irq, INTR_MPSAFE, - intr_func, sc, &sc->bnx_intrhand, sc->arpcom.ac_if.if_serializer); - if (error) { - device_printf(sc->bnx_dev, "could not set up irq\n"); - return error; } return 0; } +static void +bnx_teardown_intr(struct bnx_softc *sc, int cnt) +{ + int i; + + for (i = 0; i < cnt; ++i) { + struct bnx_intr_data *intr = &sc->bnx_intr_data[i]; + + bus_teardown_intr(sc->bnx_dev, intr->bnx_intr_res, + intr->bnx_intr_hand); + } +} + static void bnx_free_intr(struct bnx_softc *sc) { - if (sc->bnx_irq != NULL) { + struct bnx_intr_data *intr; + + KKASSERT(sc->bnx_intr_cnt <= 1); + intr = &sc->bnx_intr_data[0]; + + if (intr->bnx_intr_res != NULL) { bus_release_resource(sc->bnx_dev, SYS_RES_IRQ, - sc->bnx_irq_rid, sc->bnx_irq); + intr->bnx_intr_rid, intr->bnx_intr_res); } - if (sc->bnx_irq_type == PCI_INTR_TYPE_MSI) + if (sc->bnx_intr_type == PCI_INTR_TYPE_MSI) pci_release_msi(sc->bnx_dev); } diff --git a/sys/dev/netif/bnx/if_bnxvar.h b/sys/dev/netif/bnx/if_bnxvar.h index 136fd66a66..1e5b463c02 100644 --- a/sys/dev/netif/bnx/if_bnxvar.h +++ b/sys/dev/netif/bnx/if_bnxvar.h @@ -224,18 +224,40 @@ struct bnx_tx_ring { bus_dma_tag_t bnx_tx_ring_tag; bus_dmamap_t bnx_tx_ring_map; bus_addr_t bnx_tx_ring_paddr; + int bnx_tx_cpuid; } __cachealign; +struct bnx_intr_data { + struct bnx_softc *bnx_sc; + struct bnx_rx_ret_ring *bnx_ret; + struct bnx_tx_ring *bnx_txr; + + int bnx_intr_cpuid; + struct lwkt_serialize *bnx_intr_serialize; + struct callout bnx_intr_timer; + void (*bnx_intr_check)(void *); + uint16_t bnx_rx_check_considx; + uint16_t bnx_tx_check_considx; + boolean_t bnx_intr_maylose; + + void *bnx_intr_arg; + driver_intr_t *bnx_intr_func; + void *bnx_intr_hand; + struct resource *bnx_intr_res; + int bnx_intr_rid; + + const char *bnx_intr_desc; + char bnx_intr_desc0[64]; +} __cachealign; + +#define BNX_INTR_MAX 5 + struct bnx_softc { struct arpcom arpcom; /* interface info */ device_t bnx_dev; device_t bnx_miibus; bus_space_handle_t bnx_bhandle; bus_space_tag_t bnx_btag; - void *bnx_intrhand; - struct resource *bnx_irq; - int bnx_irq_type; - int bnx_irq_rid; struct resource *bnx_res; struct ifmedia bnx_ifmedia; /* TBI media info */ int bnx_pciecap; @@ -259,6 +281,8 @@ struct bnx_softc { struct bnx_ring_data bnx_ldata; /* rings */ struct bnx_chain_data bnx_cdata; /* mbufs */ + struct lwkt_serialize bnx_main_serialize; + int bnx_tx_ringcnt; struct bnx_tx_ring *bnx_tx_ring; int bnx_rx_retcnt; @@ -282,11 +306,9 @@ struct bnx_softc { struct callout bnx_stat_timer; struct ifpoll_compat bnx_npoll; - uint16_t bnx_rx_check_considx; - uint16_t bnx_tx_check_considx; - boolean_t bnx_intr_maylose; - int bnx_intr_cpuid; - struct callout bnx_intr_timer; + int bnx_intr_type; + int bnx_intr_cnt; + struct bnx_intr_data bnx_intr_data[BNX_INTR_MAX]; struct sysctl_ctx_list bnx_sysctl_ctx; struct sysctl_oid *bnx_sysctl_tree; -- 2.41.0