diff options
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/pci/if_myx.c | 28 |
1 files changed, 9 insertions, 19 deletions
diff --git a/sys/dev/pci/if_myx.c b/sys/dev/pci/if_myx.c index fef3993aeb7..f1c98245fbb 100644 --- a/sys/dev/pci/if_myx.c +++ b/sys/dev/pci/if_myx.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_myx.c,v 1.89 2015/12/01 12:37:12 dlg Exp $ */ +/* $OpenBSD: if_myx.c,v 1.90 2015/12/03 12:45:56 dlg Exp $ */ /* * Copyright (c) 2007 Reyk Floeter <reyk@openbsd.org> @@ -511,6 +511,7 @@ myx_attachhook(void *arg) ifp->if_softc = sc; ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; + ifp->if_xflags = IFXF_MPSAFE; ifp->if_ioctl = myx_ioctl; ifp->if_start = myx_start; ifp->if_watchdog = myx_watchdog; @@ -1360,8 +1361,9 @@ myx_down(struct myx_softc *sc) printf("%s: failed to reset the device\n", DEVNAME(sc)); } - CLR(ifp->if_flags, IFF_RUNNING); ifq_clr_oactive(&ifp->if_snd); + CLR(ifp->if_flags, IFF_RUNNING); + if_start_barrier(ifp); for (ring = 0; ring < 2; ring++) { struct myx_rx_ring *mrr = &sc->sc_rx_ring[ring]; @@ -1436,11 +1438,6 @@ myx_start(struct ifnet *ifp) u_int free, used; u_int8_t flags; - if (!ISSET(ifp->if_flags, IFF_RUNNING) || - ifq_is_oactive(&ifp->if_snd) || - IFQ_IS_EMPTY(&ifp->if_snd)) - return; - idx = sc->sc_tx_ring_prod; /* figure out space */ @@ -1588,11 +1585,10 @@ int myx_intr(void *arg) { struct myx_softc *sc = (struct myx_softc *)arg; - struct ifnet *ifp = &sc->sc_ac.ac_if; volatile struct myx_status *sts = sc->sc_sts; enum myx_state state; bus_dmamap_t map = sc->sc_sts_dma.mxm_map; - u_int32_t data, start; + u_int32_t data; u_int8_t valid = 0; state = sc->sc_state; @@ -1638,15 +1634,12 @@ myx_intr(void *arg) bus_space_write_raw_region_4(sc->sc_memt, sc->sc_memh, sc->sc_irqclaimoff + sizeof(data), &data, sizeof(data)); - start = ifq_is_oactive(&ifp->if_snd); - if (sts->ms_statusupdated) { if (state == MYX_S_DOWN && sc->sc_linkdown != sts->ms_linkdown) { sc->sc_state = MYX_S_OFF; membar_producer(); wakeup(sts); - start = 0; } else { data = sts->ms_linkstate; if (data != 0xffffffff) { @@ -1660,13 +1653,6 @@ myx_intr(void *arg) bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); - if (start) { - KERNEL_LOCK(); - ifq_clr_oactive(&ifp->if_snd); - myx_start(ifp); - KERNEL_UNLOCK(); - } - return (1); } @@ -1715,6 +1701,10 @@ myx_txeof(struct myx_softc *sc, u_int32_t done_count) sc->sc_tx_ring_cons = idx; sc->sc_tx_cons = cons; + + ifq_clr_oactive(&ifp->if_snd); + if (!ifq_empty(&ifp->if_snd)) + if_start(ifp); } void |