commit 2aa81938bd60d866d41cc9959b735f12b0d2f593 Author: Ryota Ozaki Date: Tue Jan 19 11:21:48 2016 +0900 WM polling RX (polling loop = 100) diff --git a/sys/dev/pci/if_wm.c b/sys/dev/pci/if_wm.c index de23f5c..555a921 100644 --- a/sys/dev/pci/if_wm.c +++ b/sys/dev/pci/if_wm.c @@ -318,6 +318,7 @@ struct wm_rxqueue { struct mbuf **rxq_tailp; /* XXX which event counter is required? */ + void *rxq_si; }; /* @@ -604,6 +605,7 @@ static void wm_nq_start_locked(struct ifnet *); /* Interrupt */ static int wm_txeof(struct wm_softc *); static void wm_rxeof(struct wm_rxqueue *); +static void wm_rxeof_sih(void *); static void wm_linkintr_gmii(struct wm_softc *, uint32_t); static void wm_linkintr_tbi(struct wm_softc *, uint32_t); static void wm_linkintr_serdes(struct wm_softc *, uint32_t); @@ -2445,7 +2447,7 @@ alloc_retry: /* Attach the interface. */ if_attach(ifp); - if_init_softint_input(ifp); + //if_init_softint_input(ifp); ether_ifattach(ifp, enaddr); ether_set_ifflags_cb(&sc->sc_ethercom, wm_ifflags_cb); rnd_attach_source(&sc->rnd_source, xname, RND_TYPE_NET, @@ -4371,6 +4373,9 @@ wm_setup_msix(struct wm_softc *sc) rxq->rxq_id = qidx; rxq->rxq_intr_idx = intr_idx; + rxq->rxq_si = softint_establish(SOFTINT_NET | SOFTINT_MPSAFE, + wm_rxeof_sih, rxq); + rx_established++; intr_idx++; } @@ -6943,8 +6948,12 @@ wm_rxeof(struct wm_rxqueue *rxq) int count = 0; uint8_t status, errors; uint16_t vlantag; + int loop = 100; // same as FreeBSD's igb for (i = rxq->rxq_ptr;; i = WM_NEXTRX(i)) { + if (--loop < 0) + break; + rxs = &rxq->rxq_soft[i]; DPRINTF(WM_DEBUG_RX, @@ -7118,7 +7127,8 @@ wm_rxeof(struct wm_rxqueue *rxq) WM_RX_UNLOCK(rxq); - if_input(ifp, m); + bpf_mtap(ifp, m); + ifp->if_input(ifp, m); WM_RX_LOCK(rxq); @@ -7133,6 +7143,22 @@ wm_rxeof(struct wm_rxqueue *rxq) DPRINTF(WM_DEBUG_RX, ("%s: RX: rxptr -> %d\n", device_xname(sc->sc_dev), i)); + + // XXX ack + if (sc->sc_type == WM_T_82574) + CSR_WRITE(sc, WMREG_IMS, ICR_RXQ(rxq->rxq_id)); + else if (sc->sc_type == WM_T_82575) + CSR_WRITE(sc, WMREG_EIMS, EITR_RX_QUEUE(rxq->rxq_id)); + else + CSR_WRITE(sc, WMREG_EIMS, 1 << rxq->rxq_intr_idx); +} + +static void +wm_rxeof_sih(void *arg) +{ + struct wm_rxqueue *rxq = arg; + + wm_rxeof(rxq); } /* @@ -7529,17 +7555,20 @@ wm_rxintr_msix(void *arg) goto out; WM_EVCNT_INCR(&sc->sc_ev_rxintr); - wm_rxeof(rxq); + //wm_rxeof(rxq); + softint_schedule(rxq->rxq_si); out: WM_RX_UNLOCK(rxq); +#if 0 if (sc->sc_type == WM_T_82574) CSR_WRITE(sc, WMREG_IMS, ICR_RXQ(rxq->rxq_id)); else if (sc->sc_type == WM_T_82575) CSR_WRITE(sc, WMREG_EIMS, EITR_RX_QUEUE(rxq->rxq_id)); else CSR_WRITE(sc, WMREG_EIMS, 1 << rxq->rxq_intr_idx); +#endif return 1; }