diff --git a/sys/arm/xscale/ixp425/if_npe.c b/sys/arm/xscale/ixp425/if_npe.c index f50a8689130d..3d174e78d163 100644 --- a/sys/arm/xscale/ixp425/if_npe.c +++ b/sys/arm/xscale/ixp425/if_npe.c @@ -229,7 +229,7 @@ static void npe_getmac(struct npe_softc *sc, u_char *eaddr); static void npe_txdone(int qid, void *arg); static int npe_rxbuf_init(struct npe_softc *, struct npebuf *, struct mbuf *); -static void npe_rxdone(int qid, void *arg); +static int npe_rxdone(int qid, void *arg); static void npeinit(void *); static void npestart_locked(struct ifnet *); static void npestart(struct ifnet *); @@ -777,7 +777,7 @@ npe_activate(device_t dev) */ sc->rx_qid = npeconfig[sc->sc_npeid].rx_qid; ixpqmgr_qconfig(sc->rx_qid, npe_rxbuf, 0, 1, - IX_QMGR_Q_SOURCE_ID_NOT_E, npe_rxdone, sc); + IX_QMGR_Q_SOURCE_ID_NOT_E, (qconfig_hand_t *)npe_rxdone, sc); sc->rx_freeqid = npeconfig[sc->sc_npeid].rx_freeqid; ixpqmgr_qconfig(sc->rx_freeqid, npe_rxbuf, 0, npe_rxbuf/2, 0, NULL, sc); /* @@ -1091,7 +1091,7 @@ npe_rxbuf_init(struct npe_softc *sc, struct npebuf *npe, struct mbuf *m) * from the hardware queue and pass the frames up the * stack. Pass the rx buffers to the free list. */ -static void +static int npe_rxdone(int qid, void *arg) { #define P2V(a, dma) \ @@ -1099,6 +1099,7 @@ npe_rxdone(int qid, void *arg) struct npe_softc *sc = arg; struct npedma *dma = &sc->rxdma; uint32_t entry; + int rx_npkts = 0; while (ixpqmgr_qread(qid, &entry) == 0) { struct npebuf *npe = P2V(NPE_QM_Q_ADDR(entry), dma); @@ -1132,6 +1133,7 @@ npe_rxdone(int qid, void *arg) ifp->if_ipackets++; ifp->if_input(ifp, mrx); + rx_npkts++; } else { /* discard frame and re-use mbuf */ m = npe->ix_m; @@ -1143,19 +1145,22 @@ npe_rxdone(int qid, void *arg) /* XXX should not happen */ } } + return (rx_npkts); #undef P2V } #ifdef DEVICE_POLLING -static void +static int npe_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) { struct npe_softc *sc = ifp->if_softc; + int rx_npkts = 0; if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - npe_rxdone(sc->rx_qid, sc); + rx_npkts = npe_rxdone(sc->rx_qid, sc); npe_txdone(sc->tx_doneqid, sc); /* XXX polls both NPE's */ } + return (rx_npkts); } #endif /* DEVICE_POLLING */ diff --git a/sys/arm/xscale/ixp425/ixp425_qmgr.c b/sys/arm/xscale/ixp425/ixp425_qmgr.c index 42294669703d..2c6ff568b36a 100644 --- a/sys/arm/xscale/ixp425/ixp425_qmgr.c +++ b/sys/arm/xscale/ixp425/ixp425_qmgr.c @@ -338,7 +338,7 @@ ixpqmgr_detach(device_t dev) int ixpqmgr_qconfig(int qId, int qEntries, int ne, int nf, int srcSel, - void (*cb)(int, void *), void *cbarg) + qconfig_hand_t *cb, void *cbarg) { struct ixpqmgr_softc *sc = ixpqmgr_sc; struct qmgrInfo *qi = &sc->qinfo[qId]; diff --git a/sys/arm/xscale/ixp425/ixp425_qmgr.h b/sys/arm/xscale/ixp425/ixp425_qmgr.h index af021d553990..f593fd19f5b7 100644 --- a/sys/arm/xscale/ixp425/ixp425_qmgr.h +++ b/sys/arm/xscale/ixp425/ixp425_qmgr.h @@ -229,8 +229,10 @@ #define IX_QMGR_ENTRY2_OFFSET 1 #define IX_QMGR_ENTRY4_OFFSET 3 +typedef void qconfig_hand_t(int, void *); + int ixpqmgr_qconfig(int qId, int qSizeInWords, int ne, int nf, int srcSel, - void (*cb)(int, void *), void *cbarg); + qconfig_hand_t *cb, void *cbarg); int ixpqmgr_qwrite(int qId, uint32_t entry); int ixpqmgr_qread(int qId, uint32_t *entry); int ixpqmgr_qreadm(int qId, uint32_t n, uint32_t *p); diff --git a/sys/dev/bge/if_bge.c b/sys/dev/bge/if_bge.c index fbda2ba400a7..c481b9a499a3 100644 --- a/sys/dev/bge/if_bge.c +++ b/sys/dev/bge/if_bge.c @@ -332,7 +332,7 @@ static int bge_get_eaddr_eeprom(struct bge_softc *, uint8_t[]); static int bge_get_eaddr(struct bge_softc *, uint8_t[]); static void bge_txeof(struct bge_softc *); -static void bge_rxeof(struct bge_softc *); +static int bge_rxeof(struct bge_softc *); static void bge_asf_driver_up (struct bge_softc *); static void bge_tick(void *); @@ -390,7 +390,7 @@ static int bge_miibus_readreg(device_t, int, int); static int bge_miibus_writereg(device_t, int, int, int); static void bge_miibus_statchg(device_t); #ifdef DEVICE_POLLING -static void bge_poll(struct ifnet *ifp, enum poll_cmd cmd, int count); +static int bge_poll(struct ifnet *ifp, enum poll_cmd cmd, int count); #endif #define BGE_RESET_START 1 @@ -3050,18 +3050,18 @@ bge_reset(struct bge_softc *sc) * 2) the frame is from the standard receive ring */ -static void +static int bge_rxeof(struct bge_softc *sc) { struct ifnet *ifp; - int stdcnt = 0, jumbocnt = 0; + int rx_npkts = 0, stdcnt = 0, jumbocnt = 0; BGE_LOCK_ASSERT(sc); /* Nothing to do. */ if (sc->bge_rx_saved_considx == sc->bge_ldata.bge_status_block->bge_idx[0].bge_rx_prod_idx) - return; + return (rx_npkts); ifp = sc->bge_ifp; @@ -3193,6 +3193,7 @@ bge_rxeof(struct bge_softc *sc) BGE_UNLOCK(sc); (*ifp->if_input)(ifp, m); BGE_LOCK(sc); + rk_npkts++; if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) return; @@ -3219,6 +3220,7 @@ bge_rxeof(struct bge_softc *sc) if (BGE_IS_5705_PLUS(sc)) ifp->if_ierrors += CSR_READ_4(sc, BGE_RXLP_LOCSTAT_IFIN_DROPS); #endif + return (rx_npkts); } static void @@ -3271,16 +3273,17 @@ bge_txeof(struct bge_softc *sc) } #ifdef DEVICE_POLLING -static void +static int bge_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) { struct bge_softc *sc = ifp->if_softc; uint32_t statusword; - + int rx_npkts = 0; + BGE_LOCK(sc); if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { BGE_UNLOCK(sc); - return; + return (rx_npkts); } bus_dmamap_sync(sc->bge_cdata.bge_status_tag, @@ -3303,7 +3306,7 @@ bge_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) bge_link_upd(sc); sc->rxcycles = count; - bge_rxeof(sc); + rx_npkts = bge_rxeof(sc); if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { BGE_UNLOCK(sc); return; @@ -3313,6 +3316,7 @@ bge_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) bge_start_locked(ifp); BGE_UNLOCK(sc); + return (rx_npkts); } #endif /* DEVICE_POLLING */ diff --git a/sys/dev/dc/if_dc.c b/sys/dev/dc/if_dc.c index e29ff1891020..d1f51ac53380 100644 --- a/sys/dev/dc/if_dc.c +++ b/sys/dev/dc/if_dc.c @@ -236,7 +236,7 @@ static int dc_newbuf(struct dc_softc *, int, int); static int dc_encap(struct dc_softc *, struct mbuf **); static void dc_pnic_rx_bug_war(struct dc_softc *, int); static int dc_rx_resync(struct dc_softc *); -static void dc_rxeof(struct dc_softc *); +static int dc_rxeof(struct dc_softc *); static void dc_txeof(struct dc_softc *); static void dc_tick(void *); static void dc_tx_underrun(struct dc_softc *); @@ -2640,19 +2640,21 @@ dc_rx_resync(struct dc_softc *sc) * A frame has been uploaded: pass the resulting mbuf chain up to * the higher level protocols. */ -static void +static int dc_rxeof(struct dc_softc *sc) { struct mbuf *m, *m0; struct ifnet *ifp; struct dc_desc *cur_rx; - int i, total_len = 0; + int i, total_len, rx_npkts; u_int32_t rxstat; DC_LOCK_ASSERT(sc); ifp = sc->dc_ifp; i = sc->dc_cdata.dc_rx_prod; + total_len = 0; + rx_npkts = 0; bus_dmamap_sync(sc->dc_ltag, sc->dc_lmap, BUS_DMASYNC_POSTREAD); while (!(le32toh(sc->dc_ldata->dc_rx_list[i].dc_status) & @@ -2706,7 +2708,7 @@ dc_rxeof(struct dc_softc *sc) continue; } else { dc_init_locked(sc); - return; + return (rx_npkts); } } } @@ -2745,9 +2747,11 @@ dc_rxeof(struct dc_softc *sc) DC_UNLOCK(sc); (*ifp->if_input)(ifp, m); DC_LOCK(sc); + rx_npkts++; } sc->dc_cdata.dc_rx_prod = i; + return (rx_npkts); } /* @@ -2989,20 +2993,21 @@ dc_tx_underrun(struct dc_softc *sc) #ifdef DEVICE_POLLING static poll_handler_t dc_poll; -static void +static int dc_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) { struct dc_softc *sc = ifp->if_softc; + int rx_npkts = 0; DC_LOCK(sc); if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { DC_UNLOCK(sc); - return; + return (rx_npkts); } sc->rxcycles = count; - dc_rxeof(sc); + rx_npkts = dc_rxeof(sc); dc_txeof(sc); if (!IFQ_IS_EMPTY(&ifp->if_snd) && !(ifp->if_drv_flags & IFF_DRV_OACTIVE)) @@ -3017,7 +3022,7 @@ dc_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) DC_ISR_BUS_ERR); if (!status) { DC_UNLOCK(sc); - return; + return (rx_npkts); } /* ack what we have */ CSR_WRITE_4(sc, DC_ISR, status); @@ -3043,6 +3048,7 @@ dc_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) } } DC_UNLOCK(sc); + return (rx_npkts); } #endif /* DEVICE_POLLING */ diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c index 0883018c84d2..3d1d36272f67 100644 --- a/sys/dev/e1000/if_em.c +++ b/sys/dev/e1000/if_em.c @@ -261,7 +261,7 @@ static void em_txeof(struct adapter *); static void em_tx_purge(struct adapter *); static int em_allocate_receive_structures(struct adapter *); static int em_allocate_transmit_structures(struct adapter *); -static int em_rxeof(struct adapter *, int); +static int em_rxeof(struct adapter *, int, int *); #ifndef __NO_STRICT_ALIGNMENT static int em_fixup_rx(struct adapter *); #endif @@ -1653,16 +1653,20 @@ em_init(void *arg) * Legacy polling routine * *********************************************************************/ -static void +static int em_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) { - struct adapter *adapter = ifp->if_softc; + struct adapter *adapter; u32 reg_icr; + int rx_npkts; + + adapter = ifp->if_softc; + rx_npkts = 0; EM_CORE_LOCK(adapter); if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { EM_CORE_UNLOCK(adapter); - return; + return (rx_npkts); } if (cmd == POLL_AND_CHECK_STATUS) { @@ -1677,7 +1681,7 @@ em_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) } EM_CORE_UNLOCK(adapter); - em_rxeof(adapter, count); + em_rxeof(adapter, count, &rx_npkts); EM_TX_LOCK(adapter); em_txeof(adapter); @@ -1685,6 +1689,7 @@ em_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) if (!ADAPTER_RING_EMPTY(adapter)) em_start_locked(ifp); EM_TX_UNLOCK(adapter); + return (rx_npkts); } #endif /* DEVICE_POLLING */ @@ -1718,7 +1723,7 @@ em_intr(void *arg) EM_TX_LOCK(adapter); em_txeof(adapter); - em_rxeof(adapter, -1); + em_rxeof(adapter, -1, NULL); em_txeof(adapter); EM_TX_UNLOCK(adapter); @@ -1771,7 +1776,7 @@ em_handle_rxtx(void *context, int pending) if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - if (em_rxeof(adapter, adapter->rx_process_limit) != 0) + if (em_rxeof(adapter, adapter->rx_process_limit, NULL) != 0) taskqueue_enqueue(adapter->tq, &adapter->rxtx_task); EM_TX_LOCK(adapter); em_txeof(adapter); @@ -1882,7 +1887,7 @@ em_msix_rx(void *arg) ++adapter->rx_irq; if ((ifp->if_drv_flags & IFF_DRV_RUNNING) && - (em_rxeof(adapter, adapter->rx_process_limit) != 0)) + (em_rxeof(adapter, adapter->rx_process_limit, NULL) != 0)) taskqueue_enqueue(adapter->tq, &adapter->rx_task); /* Reenable this interrupt */ E1000_WRITE_REG(&adapter->hw, E1000_IMS, EM_MSIX_RX); @@ -1920,7 +1925,7 @@ em_handle_rx(void *context, int pending) struct ifnet *ifp = adapter->ifp; if ((ifp->if_drv_flags & IFF_DRV_RUNNING) && - (em_rxeof(adapter, adapter->rx_process_limit) != 0)) + (em_rxeof(adapter, adapter->rx_process_limit, NULL) != 0)) taskqueue_enqueue(adapter->tq, &adapter->rx_task); } @@ -4461,23 +4466,26 @@ em_free_receive_structures(struct adapter *adapter) * *********************************************************************/ static int -em_rxeof(struct adapter *adapter, int count) +em_rxeof(struct adapter *adapter, int count, int *rx_npktsp) { struct ifnet *ifp = adapter->ifp;; struct mbuf *mp; u8 status, accept_frame = 0, eop = 0; u16 len, desc_len, prev_len_adj; - int i; + int i, rx_npkts; struct e1000_rx_desc *current_desc; EM_RX_LOCK(adapter); i = adapter->next_rx_desc_to_check; + rx_npkts = 0; current_desc = &adapter->rx_desc_base[i]; bus_dmamap_sync(adapter->rxdma.dma_tag, adapter->rxdma.dma_map, BUS_DMASYNC_POSTREAD); if (!((current_desc->status) & E1000_RXD_STAT_DD)) { EM_RX_UNLOCK(adapter); + if (rx_npktsp != NULL) + *rx_npktsp = rx_npkts; return (0); } @@ -4626,6 +4634,7 @@ em_rxeof(struct adapter *adapter, int count) EM_RX_UNLOCK(adapter); (*ifp->if_input)(ifp, m); EM_RX_LOCK(adapter); + rx_npkts++; i = adapter->next_rx_desc_to_check; } current_desc = &adapter->rx_desc_base[i]; @@ -4637,6 +4646,8 @@ em_rxeof(struct adapter *adapter, int count) i = adapter->num_rx_desc - 1; E1000_WRITE_REG(&adapter->hw, E1000_RDT(0), i); EM_RX_UNLOCK(adapter); + if (rx_npktsp != NULL) + *rx_npktsp = rx_npkts; if (!((current_desc->status) & E1000_RXD_STAT_DD)) return (0); diff --git a/sys/dev/firewire/if_fwe.c b/sys/dev/firewire/if_fwe.c index 1c88af8eaa4c..62616cfcf667 100644 --- a/sys/dev/firewire/if_fwe.c +++ b/sys/dev/firewire/if_fwe.c @@ -105,18 +105,19 @@ TUNABLE_INT("hw.firewire.fwe.rx_queue_len", &rx_queue_len); #ifdef DEVICE_POLLING static poll_handler_t fwe_poll; -static void +static int fwe_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) { struct fwe_softc *fwe; struct firewire_comm *fc; if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) - return; + return (0); fwe = ((struct fwe_eth_softc *)ifp->if_softc)->fwe; fc = fwe->fd.fc; fc->poll(fc, (cmd == POLL_AND_CHECK_STATUS)?0:1, count); + return (0); } #endif /* DEVICE_POLLING */ @@ -455,6 +456,7 @@ fwe_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) /* Disable interrupts */ fc->set_intr(fc, 0); ifp->if_capenable |= IFCAP_POLLING; + ifp->if_capenable |= IFCAP_POLLING_NOCOUNT; return (error); } if (!(ifr->ifr_reqcap & IFCAP_POLLING) && @@ -463,6 +465,7 @@ fwe_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) /* Enable interrupts. */ fc->set_intr(fc, 1); ifp->if_capenable &= ~IFCAP_POLLING; + ifp->if_capenable &= ~IFCAP_POLLING_NOCOUNT; return (error); } } diff --git a/sys/dev/firewire/if_fwip.c b/sys/dev/firewire/if_fwip.c index 90df5a52c4f8..66cdb4aba11d 100644 --- a/sys/dev/firewire/if_fwip.c +++ b/sys/dev/firewire/if_fwip.c @@ -112,18 +112,19 @@ TUNABLE_INT("hw.firewire.fwip.rx_queue_len", &rx_queue_len); #ifdef DEVICE_POLLING static poll_handler_t fwip_poll; -static void +static int fwip_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) { struct fwip_softc *fwip; struct firewire_comm *fc; if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) - return; + return (0); fwip = ((struct fwip_eth_softc *)ifp->if_softc)->fwip; fc = fwip->fd.fc; fc->poll(fc, (cmd == POLL_AND_CHECK_STATUS)?0:1, count); + return (0); } #endif /* DEVICE_POLLING */ @@ -436,7 +437,8 @@ fwip_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) return(error); /* Disable interrupts */ fc->set_intr(fc, 0); - ifp->if_capenable |= IFCAP_POLLING; + ifp->if_capenable |= IFCAP_POLLING | + IFCAP_POLLING_NOCOUNT; return (error); } @@ -446,6 +448,7 @@ fwip_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) /* Enable interrupts. */ fc->set_intr(fc, 1); ifp->if_capenable &= ~IFCAP_POLLING; + ifp->if_capenable &= ~IFCAP_POLLING_NOCOUNT; return (error); } } diff --git a/sys/dev/fxp/if_fxp.c b/sys/dev/fxp/if_fxp.c index 0bddd179bf16..c332552fbd30 100644 --- a/sys/dev/fxp/if_fxp.c +++ b/sys/dev/fxp/if_fxp.c @@ -217,7 +217,7 @@ static int fxp_resume(device_t dev); static void fxp_intr(void *xsc); static void fxp_rxcsum(struct fxp_softc *sc, struct ifnet *ifp, struct mbuf *m, uint16_t status, int pos); -static void fxp_intr_body(struct fxp_softc *sc, struct ifnet *ifp, +static int fxp_intr_body(struct fxp_softc *sc, struct ifnet *ifp, uint8_t statack, int count); static void fxp_init(void *xsc); static void fxp_init_body(struct fxp_softc *sc); @@ -1619,16 +1619,17 @@ fxp_encap(struct fxp_softc *sc, struct mbuf **m_head) #ifdef DEVICE_POLLING static poll_handler_t fxp_poll; -static void +static int fxp_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) { struct fxp_softc *sc = ifp->if_softc; uint8_t statack; + int rx_npkts = 0; FXP_LOCK(sc); if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { FXP_UNLOCK(sc); - return; + return (rx_npkts); } statack = FXP_SCB_STATACK_CXTNO | FXP_SCB_STATACK_CNA | @@ -1639,7 +1640,7 @@ fxp_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) tmp = CSR_READ_1(sc, FXP_CSR_SCB_STATACK); if (tmp == 0xff || tmp == 0) { FXP_UNLOCK(sc); - return; /* nothing to do */ + return (rx_npkts); /* nothing to do */ } tmp &= ~statack; /* ack what we can */ @@ -1647,8 +1648,9 @@ fxp_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) CSR_WRITE_1(sc, FXP_CSR_SCB_STATACK, tmp); statack |= tmp; } - fxp_intr_body(sc, ifp, statack, count); + rx_npkts = fxp_intr_body(sc, ifp, statack, count); FXP_UNLOCK(sc); + return (rx_npkts); } #endif /* DEVICE_POLLING */ @@ -1805,7 +1807,7 @@ fxp_rxcsum(struct fxp_softc *sc, struct ifnet *ifp, struct mbuf *m, m->m_pkthdr.csum_data = csum; } -static void +static int fxp_intr_body(struct fxp_softc *sc, struct ifnet *ifp, uint8_t statack, int count) { @@ -1813,9 +1815,12 @@ fxp_intr_body(struct fxp_softc *sc, struct ifnet *ifp, uint8_t statack, struct fxp_rx *rxp; struct fxp_rfa *rfa; int rnr = (statack & FXP_SCB_STATACK_RNR) ? 1 : 0; + int rx_npkts; uint16_t status; + rx_npkts = 0; FXP_LOCK_ASSERT(sc, MA_OWNED); + if (rnr) sc->rnr++; #ifdef DEVICE_POLLING @@ -1852,7 +1857,7 @@ fxp_intr_body(struct fxp_softc *sc, struct ifnet *ifp, uint8_t statack, * Just return if nothing happened on the receive side. */ if (!rnr && (statack & FXP_SCB_STATACK_FR) == 0) - return; + return (rx_npkts); /* * Process receiver interrupts. If a no-resource (RNR) @@ -1944,6 +1949,7 @@ fxp_intr_body(struct fxp_softc *sc, struct ifnet *ifp, uint8_t statack, FXP_UNLOCK(sc); (*ifp->if_input)(ifp, m); FXP_LOCK(sc); + rx_npkts++; } else { /* Reuse RFA and loaded DMA map. */ ifp->if_iqdrops++; @@ -1957,6 +1963,7 @@ fxp_intr_body(struct fxp_softc *sc, struct ifnet *ifp, uint8_t statack, sc->fxp_desc.rx_head->rx_addr); fxp_scb_cmd(sc, FXP_SCB_COMMAND_RU_START); } + return (rx_npkts); } /* diff --git a/sys/dev/ixgb/if_ixgb.c b/sys/dev/ixgb/if_ixgb.c index 1fb35445552a..f555e79101e3 100644 --- a/sys/dev/ixgb/if_ixgb.c +++ b/sys/dev/ixgb/if_ixgb.c @@ -121,7 +121,7 @@ static void ixgb_update_stats_counters(struct adapter *); static void ixgb_clean_transmit_interrupts(struct adapter *); static int ixgb_allocate_receive_structures(struct adapter *); static int ixgb_allocate_transmit_structures(struct adapter *); -static void ixgb_process_receive_interrupts(struct adapter *, int); +static int ixgb_process_receive_interrupts(struct adapter *, int); static void ixgb_receive_checksum(struct adapter *, struct ixgb_rx_desc * rx_desc, @@ -748,11 +748,12 @@ ixgb_init(void *arg) } #ifdef DEVICE_POLLING -static void +static int ixgb_poll_locked(struct ifnet * ifp, enum poll_cmd cmd, int count) { struct adapter *adapter = ifp->if_softc; u_int32_t reg_icr; + int rx_npkts; IXGB_LOCK_ASSERT(adapter); @@ -766,22 +767,25 @@ ixgb_poll_locked(struct ifnet * ifp, enum poll_cmd cmd, int count) adapter); } } - ixgb_process_receive_interrupts(adapter, count); + rx_npkts = ixgb_process_receive_interrupts(adapter, count); ixgb_clean_transmit_interrupts(adapter); if (ifp->if_snd.ifq_head != NULL) ixgb_start_locked(ifp); + return (rx_npkts); } -static void +static int ixgb_poll(struct ifnet * ifp, enum poll_cmd cmd, int count) { struct adapter *adapter = ifp->if_softc; + int rx_npkts = 0; IXGB_LOCK(adapter); if (ifp->if_drv_flags & IFF_DRV_RUNNING) - ixgb_poll_locked(ifp, cmd, count); + rx_npkts = ixgb_poll_locked(ifp, cmd, count); IXGB_UNLOCK(adapter); + return (rx_npkts); } #endif /* DEVICE_POLLING */ @@ -2065,7 +2069,7 @@ ixgb_free_receive_structures(struct adapter * adapter) * count < 0. * *********************************************************************/ -static void +static int ixgb_process_receive_interrupts(struct adapter * adapter, int count) { struct ifnet *ifp; @@ -2079,6 +2083,7 @@ ixgb_process_receive_interrupts(struct adapter * adapter, int count) int i; int next_to_use = 0; int eop_desc; + int rx_npkts = 0; /* Pointer to the receive descriptor being examined. */ struct ixgb_rx_desc *current_desc; @@ -2094,7 +2099,7 @@ ixgb_process_receive_interrupts(struct adapter * adapter, int count) #ifdef _SV_ adapter->no_pkts_avail++; #endif - return; + return (rx_npkts); } while ((current_desc->status & IXGB_RX_DESC_STATUS_DD) && (count != 0)) { @@ -2168,6 +2173,7 @@ ixgb_process_receive_interrupts(struct adapter * adapter, int count) IXGB_UNLOCK(adapter); (*ifp->if_input) (ifp, adapter->fmp); IXGB_LOCK(adapter); + rx_npkts++; } #endif adapter->fmp = NULL; @@ -2239,7 +2245,7 @@ ixgb_process_receive_interrupts(struct adapter * adapter, int count) /* Advance the IXGB's Receive Queue #0 "Tail Pointer" */ IXGB_WRITE_REG(&adapter->hw, RDT, next_to_use); - return; + return (rx_npkts); } /********************************************************************* diff --git a/sys/dev/lmc/if_lmc.c b/sys/dev/lmc/if_lmc.c index c97bdfa6c99c..1df51ad8b4d5 100644 --- a/sys/dev/lmc/if_lmc.c +++ b/sys/dev/lmc/if_lmc.c @@ -3960,7 +3960,7 @@ user_interrupt(softc_t *sc, int check_status) # if (defined(__FreeBSD__) && defined(DEVICE_POLLING)) /* Service the card from the kernel idle loop without interrupts. */ -static void +static int fbsd_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) { softc_t *sc = IFP2SC(ifp); @@ -4828,6 +4828,7 @@ setup_ifnet(struct ifnet *ifp) # if (defined(__FreeBSD__) && defined(DEVICE_POLLING)) ifp->if_capabilities |= IFCAP_POLLING; + ifp->if_capenable |= IFCAP_POLLING_NOCOUNT; # if (__FreeBSD_version < 500000) ifp->if_capenable |= IFCAP_POLLING; # endif diff --git a/sys/dev/mge/if_mge.c b/sys/dev/mge/if_mge.c index 43a7a18c8be5..2373f0cebb60 100644 --- a/sys/dev/mge/if_mge.c +++ b/sys/dev/mge/if_mge.c @@ -106,7 +106,7 @@ static void mge_ver_params(struct mge_softc *sc); static void mge_intrs_ctrl(struct mge_softc *sc, int enable); static void mge_intr_rx(void *arg); -static void mge_intr_rx_locked(struct mge_softc *sc, int count); +static int mge_intr_rx_locked(struct mge_softc *sc, int count); static void mge_intr_tx(void *arg); static void mge_intr_tx_locked(struct mge_softc *sc); static void mge_intr_misc(void *arg); @@ -569,17 +569,18 @@ mge_reinit_rx(struct mge_softc *sc) #ifdef DEVICE_POLLING static poll_handler_t mge_poll; -static void +static int mge_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) { struct mge_softc *sc = ifp->if_softc; uint32_t int_cause, int_cause_ext; + int rx_npkts = 0; MGE_GLOBAL_LOCK(sc); if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { MGE_GLOBAL_UNLOCK(sc); - return; + return (rx_npkts); } if (cmd == POLL_AND_CHECK_STATUS) { @@ -597,9 +598,10 @@ mge_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) } mge_intr_tx_locked(sc); - mge_intr_rx_locked(sc, count); + rx_npkts = mge_intr_rx_locked(sc, count); MGE_GLOBAL_UNLOCK(sc); + return (rx_npkts); } #endif /* DEVICE_POLLING */ @@ -1013,7 +1015,7 @@ mge_intr_rx(void *arg) { } -static void +static int mge_intr_rx_locked(struct mge_softc *sc, int count) { struct ifnet *ifp = sc->ifp; @@ -1021,6 +1023,7 @@ mge_intr_rx_locked(struct mge_softc *sc, int count) uint16_t bufsize; struct mge_desc_wrapper* dw; struct mbuf *mb; + int rx_npkts = 0; MGE_RECEIVE_LOCK_ASSERT(sc); @@ -1059,6 +1062,7 @@ mge_intr_rx_locked(struct mge_softc *sc, int count) MGE_RECEIVE_UNLOCK(sc); (*ifp->if_input)(ifp, mb); MGE_RECEIVE_LOCK(sc); + rx_npkts++; } dw->mge_desc->byte_count = 0; @@ -1071,7 +1075,7 @@ mge_intr_rx_locked(struct mge_softc *sc, int count) count -= 1; } - return; + return (rx_npkts); } static void diff --git a/sys/dev/nfe/if_nfe.c b/sys/dev/nfe/if_nfe.c index cb7a163a9170..99f75aafe1cc 100644 --- a/sys/dev/nfe/if_nfe.c +++ b/sys/dev/nfe/if_nfe.c @@ -93,8 +93,8 @@ static __inline void nfe_discard_rxbuf(struct nfe_softc *, int); static __inline void nfe_discard_jrxbuf(struct nfe_softc *, int); static int nfe_newbuf(struct nfe_softc *, int); static int nfe_jnewbuf(struct nfe_softc *, int); -static int nfe_rxeof(struct nfe_softc *, int); -static int nfe_jrxeof(struct nfe_softc *, int); +static int nfe_rxeof(struct nfe_softc *, int, int *); +static int nfe_jrxeof(struct nfe_softc *, int, int *); static void nfe_txeof(struct nfe_softc *); static int nfe_encap(struct nfe_softc *, struct mbuf **); static void nfe_setmulti(struct nfe_softc *); @@ -1551,23 +1551,24 @@ nfe_free_tx_ring(struct nfe_softc *sc, struct nfe_tx_ring *ring) static poll_handler_t nfe_poll; -static void +static int nfe_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) { struct nfe_softc *sc = ifp->if_softc; uint32_t r; + int rx_npkts = 0; NFE_LOCK(sc); if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { NFE_UNLOCK(sc); - return; + return (rx_npkts); } if (sc->nfe_framesize > MCLBYTES - ETHER_HDR_LEN) - nfe_jrxeof(sc, count); + rx_npkts = nfe_jrxeof(sc, count, &rx_npkts); else - nfe_rxeof(sc, count); + rx_npkts = nfe_rxeof(sc, count, &rx_npkts); nfe_txeof(sc); if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) taskqueue_enqueue_fast(sc->nfe_tq, &sc->nfe_tx_task); @@ -1575,7 +1576,7 @@ nfe_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) if (cmd == POLL_AND_CHECK_STATUS) { if ((r = NFE_READ(sc, sc->nfe_irq_status)) == 0) { NFE_UNLOCK(sc); - return; + return (rx_npkts); } NFE_WRITE(sc, sc->nfe_irq_status, r); @@ -1586,6 +1587,7 @@ nfe_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) } } NFE_UNLOCK(sc); + return (rx_npkts); } #endif /* DEVICE_POLLING */ @@ -1826,9 +1828,9 @@ nfe_int_task(void *arg, int pending) domore = 0; /* check Rx ring */ if (sc->nfe_framesize > MCLBYTES - ETHER_HDR_LEN) - domore = nfe_jrxeof(sc, sc->nfe_process_limit); + domore = nfe_jrxeof(sc, sc->nfe_process_limit, NULL); else - domore = nfe_rxeof(sc, sc->nfe_process_limit); + domore = nfe_rxeof(sc, sc->nfe_process_limit, NULL); /* check Tx ring */ nfe_txeof(sc); @@ -2015,7 +2017,7 @@ nfe_jnewbuf(struct nfe_softc *sc, int idx) static int -nfe_rxeof(struct nfe_softc *sc, int count) +nfe_rxeof(struct nfe_softc *sc, int count, int *rx_npktsp) { struct ifnet *ifp = sc->nfe_ifp; struct nfe_desc32 *desc32; @@ -2023,9 +2025,10 @@ nfe_rxeof(struct nfe_softc *sc, int count) struct nfe_rx_data *data; struct mbuf *m; uint16_t flags; - int len, prog; + int len, prog, rx_npkts; uint32_t vtag = 0; + rx_npkts = 0; NFE_LOCK_ASSERT(sc); bus_dmamap_sync(sc->rxq.rx_desc_tag, sc->rxq.rx_desc_map, @@ -2115,18 +2118,21 @@ nfe_rxeof(struct nfe_softc *sc, int count) NFE_UNLOCK(sc); (*ifp->if_input)(ifp, m); NFE_LOCK(sc); + rx_npkts++; } if (prog > 0) bus_dmamap_sync(sc->rxq.rx_desc_tag, sc->rxq.rx_desc_map, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + if (rx_npktsp != NULL) + *rx_npktsp = rx_npkts; return (count > 0 ? 0 : EAGAIN); } static int -nfe_jrxeof(struct nfe_softc *sc, int count) +nfe_jrxeof(struct nfe_softc *sc, int count, int *rx_npktsp) { struct ifnet *ifp = sc->nfe_ifp; struct nfe_desc32 *desc32; @@ -2134,9 +2140,10 @@ nfe_jrxeof(struct nfe_softc *sc, int count) struct nfe_rx_data *data; struct mbuf *m; uint16_t flags; - int len, prog; + int len, prog, rx_npkts; uint32_t vtag = 0; + rx_npkts = 0; NFE_LOCK_ASSERT(sc); bus_dmamap_sync(sc->jrxq.jrx_desc_tag, sc->jrxq.jrx_desc_map, @@ -2227,12 +2234,15 @@ nfe_jrxeof(struct nfe_softc *sc, int count) NFE_UNLOCK(sc); (*ifp->if_input)(ifp, m); NFE_LOCK(sc); + rx_npkts++; } if (prog > 0) bus_dmamap_sync(sc->jrxq.jrx_desc_tag, sc->jrxq.jrx_desc_map, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); + if (rx_npktsp != NULL) + *rx_npktsp = rx_npkts; return (count > 0 ? 0 : EAGAIN); } diff --git a/sys/dev/re/if_re.c b/sys/dev/re/if_re.c index 23abb46ec489..10725f11837f 100644 --- a/sys/dev/re/if_re.c +++ b/sys/dev/re/if_re.c @@ -237,11 +237,11 @@ static int re_tx_list_init (struct rl_softc *); static __inline void re_fixup_rx (struct mbuf *); #endif -static int re_rxeof (struct rl_softc *); +static int re_rxeof (struct rl_softc *, int *); static void re_txeof (struct rl_softc *); #ifdef DEVICE_POLLING -static void re_poll (struct ifnet *, enum poll_cmd, int); -static void re_poll_locked (struct ifnet *, enum poll_cmd, int); +static int re_poll (struct ifnet *, enum poll_cmd, int); +static int re_poll_locked (struct ifnet *, enum poll_cmd, int); #endif static int re_intr (void *); static void re_tick (void *); @@ -1792,14 +1792,14 @@ re_rx_list_init(struct rl_softc *sc) * across multiple 2K mbuf cluster buffers. */ static int -re_rxeof(struct rl_softc *sc) +re_rxeof(struct rl_softc *sc, int *rx_npktsp) { struct mbuf *m; struct ifnet *ifp; int i, total_len; struct rl_desc *cur_rx; u_int32_t rxstat, rxvlan; - int maxpkt = 16; + int maxpkt = 16, rx_npkts = 0; RL_LOCK_ASSERT(sc); @@ -1982,6 +1982,7 @@ re_rxeof(struct rl_softc *sc) RL_UNLOCK(sc); (*ifp->if_input)(ifp, m); RL_LOCK(sc); + rx_npkts++; } /* Flush the RX DMA ring */ @@ -1992,6 +1993,8 @@ re_rxeof(struct rl_softc *sc) sc->rl_ldata.rl_rx_prodidx = i; + if (rx_npktsp != NULL) + *rx_npktsp = rx_npkts; if (maxpkt) return(EAGAIN); @@ -2092,26 +2095,29 @@ re_tick(void *xsc) } #ifdef DEVICE_POLLING -static void +static int re_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) { struct rl_softc *sc = ifp->if_softc; + int rx_npkts = 0; RL_LOCK(sc); if (ifp->if_drv_flags & IFF_DRV_RUNNING) - re_poll_locked(ifp, cmd, count); + rx_npkts = re_poll_locked(ifp, cmd, count); RL_UNLOCK(sc); + return (rx_npkts); } -static void +static int re_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count) { struct rl_softc *sc = ifp->if_softc; + int rx_npkts; RL_LOCK_ASSERT(sc); sc->rxcycles = count; - re_rxeof(sc); + re_rxeof(sc, &rx_npkts); re_txeof(sc); if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) @@ -2122,7 +2128,7 @@ re_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count) status = CSR_READ_2(sc, RL_ISR); if (status == 0xffff) - return; + return (rx_npkts); if (status) CSR_WRITE_2(sc, RL_ISR, status); if ((status & (RL_ISR_TX_OK | RL_ISR_TX_DESC_UNAVAIL)) && @@ -2136,6 +2142,7 @@ re_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count) if (status & RL_ISR_SYSTEM_ERR) re_init_locked(sc); } + return (rx_npkts); } #endif /* DEVICE_POLLING */ @@ -2187,7 +2194,7 @@ re_int_task(void *arg, int npending) #endif if (status & (RL_ISR_RX_OK|RL_ISR_RX_ERR|RL_ISR_FIFO_OFLOW)) - rval = re_rxeof(sc); + rval = re_rxeof(sc, NULL); /* * Some chips will ignore a second TX request issued @@ -2885,7 +2892,7 @@ re_watchdog(struct rl_softc *sc) if_printf(ifp, "watchdog timeout\n"); ifp->if_oerrors++; - re_rxeof(sc); + re_rxeof(sc, NULL); re_init_locked(sc); if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) taskqueue_enqueue_fast(taskqueue_fast, &sc->rl_txtask); diff --git a/sys/dev/sf/if_sf.c b/sys/dev/sf/if_sf.c index 2abd80cc5345..5105c706ad24 100644 --- a/sys/dev/sf/if_sf.c +++ b/sys/dev/sf/if_sf.c @@ -160,7 +160,7 @@ static void sf_stats_update(struct sf_softc *); #ifndef __NO_STRICT_ALIGNMENT static __inline void sf_fixup_rx(struct mbuf *); #endif -static void sf_rxeof(struct sf_softc *); +static int sf_rxeof(struct sf_softc *); static void sf_txeof(struct sf_softc *); static int sf_encap(struct sf_softc *, struct mbuf **); static void sf_start(struct ifnet *); @@ -193,7 +193,7 @@ static int sf_miibus_writereg(device_t, int, int, int); static void sf_miibus_statchg(device_t); static void sf_link_task(void *, int); #ifdef DEVICE_POLLING -static void sf_poll(struct ifnet *ifp, enum poll_cmd cmd, int count); +static int sf_poll(struct ifnet *ifp, enum poll_cmd cmd, int count); #endif static uint32_t csr_read_4(struct sf_softc *, int); @@ -1526,19 +1526,20 @@ sf_fixup_rx(struct mbuf *m) * completely unuseable on the Alpha. Our only recourse is to copy received * packets into properly aligned buffers before handing them off. */ -static void +static int sf_rxeof(struct sf_softc *sc) { struct mbuf *m; struct ifnet *ifp; struct sf_rxdesc *rxd; struct sf_rx_rcdesc *cur_cmp; - int cons, eidx, prog; + int cons, eidx, prog, rx_npkts; uint32_t status, status2; SF_LOCK_ASSERT(sc); ifp = sc->sf_ifp; + rx_npkts = 0; bus_dmamap_sync(sc->sf_cdata.sf_rx_ring_tag, sc->sf_cdata.sf_rx_ring_map, @@ -1652,6 +1653,7 @@ sf_rxeof(struct sf_softc *sc) SF_UNLOCK(sc); (*ifp->if_input)(ifp, m); SF_LOCK(sc); + rx_npkts++; /* Clear completion status. */ cur_cmp->sf_rx_status1 = 0; @@ -1675,6 +1677,7 @@ sf_rxeof(struct sf_softc *sc) (csr_read_4(sc, SF_RXDQ_PTR_Q1) & ~SF_RXDQ_PRODIDX) | (eidx & SF_RXDQ_PRODIDX)); } + return (rx_npkts); } /* @@ -1789,22 +1792,24 @@ sf_txthresh_adjust(struct sf_softc *sc) } #ifdef DEVICE_POLLING -static void +static int sf_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) { struct sf_softc *sc; uint32_t status; + int rx_npkts; sc = ifp->if_softc; + rx_npkts = 0; SF_LOCK(sc); if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { SF_UNLOCK(sc); - return; + return (rx_npkts); } sc->rxcycles = count; - sf_rxeof(sc); + rx_npkts = sf_rxeof(sc); sf_txeof(sc); if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) sf_start_locked(ifp); @@ -1839,6 +1844,7 @@ sf_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) } SF_UNLOCK(sc); + return (rx_npkts); } #endif /* DEVICE_POLLING */ diff --git a/sys/dev/sis/if_sis.c b/sys/dev/sis/if_sis.c index 78b61496681e..38a3e73f6193 100644 --- a/sys/dev/sis/if_sis.c +++ b/sys/dev/sis/if_sis.c @@ -1394,13 +1394,13 @@ sis_newbuf(struct sis_softc *sc, struct sis_desc *c, struct mbuf *m) * A frame has been uploaded: pass the resulting mbuf chain up to * the higher level protocols. */ -static void +static int sis_rxeof(struct sis_softc *sc) { struct mbuf *m, *m0; struct ifnet *ifp; struct sis_desc *cur_rx; - int total_len = 0; + int total_len = 0, rx_npkts = 0; u_int32_t rxstat; SIS_LOCK_ASSERT(sc); @@ -1476,9 +1476,11 @@ sis_rxeof(struct sis_softc *sc) SIS_UNLOCK(sc); (*ifp->if_input)(ifp, m); SIS_LOCK(sc); + rx_npkts++; } sc->sis_rx_pdsc = cur_rx; + return (rx_npkts); } static void @@ -1580,15 +1582,16 @@ sis_tick(void *xsc) #ifdef DEVICE_POLLING static poll_handler_t sis_poll; -static void +static int sis_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) { struct sis_softc *sc = ifp->if_softc; + int rx_npkts = 0; SIS_LOCK(sc); if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { SIS_UNLOCK(sc); - return; + return (rx_npkts); } /* @@ -1599,7 +1602,7 @@ sis_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) * and then call the interrupt routine */ sc->rxcycles = count; - sis_rxeof(sc); + rx_npkts = sis_rxeof(sc); sis_txeof(sc); if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) sis_startl(ifp); @@ -1623,6 +1626,7 @@ sis_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) } SIS_UNLOCK(sc); + return (rx_npkts); } #endif /* DEVICE_POLLING */ diff --git a/sys/dev/smc/if_smc.c b/sys/dev/smc/if_smc.c index 0040f9ccea17..6204fafaa409 100644 --- a/sys/dev/smc/if_smc.c +++ b/sys/dev/smc/if_smc.c @@ -1224,6 +1224,7 @@ smc_stop(struct smc_softc *sc) #ifdef DEVICE_POLLING ether_poll_deregister(sc->smc_ifp); sc->smc_ifp->if_capenable &= ~IFCAP_POLLING; + sc->smc_ifp->if_capenable &= ~IFCAP_POLLING_NOCOUNT; #endif /* @@ -1282,6 +1283,7 @@ smc_init_locked(struct smc_softc *sc) ether_poll_register(smc_poll, ifp); SMC_LOCK(sc); ifp->if_capenable |= IFCAP_POLLING; + ifp->if_capenable |= IFCAP_POLLING_NOCOUNT; #endif } diff --git a/sys/dev/ste/if_ste.c b/sys/dev/ste/if_ste.c index 0e06d7bd85bd..5411d084212b 100644 --- a/sys/dev/ste/if_ste.c +++ b/sys/dev/ste/if_ste.c @@ -98,7 +98,7 @@ static void ste_init(void *); static void ste_init_locked(struct ste_softc *); static void ste_intr(void *); static void ste_rxeoc(struct ste_softc *); -static void ste_rxeof(struct ste_softc *); +static int ste_rxeof(struct ste_softc *); static void ste_txeoc(struct ste_softc *); static void ste_txeof(struct ste_softc *); static void ste_stats_update(void *); @@ -620,28 +620,31 @@ ste_setmulti(sc) #ifdef DEVICE_POLLING static poll_handler_t ste_poll, ste_poll_locked; -static void +static int ste_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) { struct ste_softc *sc = ifp->if_softc; + int rx_npkts = 0; STE_LOCK(sc); if (ifp->if_drv_flags & IFF_DRV_RUNNING) - ste_poll_locked(ifp, cmd, count); + rx_npkts = ste_poll_locked(ifp, cmd, count); STE_UNLOCK(sc); + return (rx_npkts); } -static void +static int ste_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count) { struct ste_softc *sc = ifp->if_softc; + int rx_npkts; STE_LOCK_ASSERT(sc); sc->rxcycles = count; if (cmd == POLL_AND_CHECK_STATUS) ste_rxeoc(sc); - ste_rxeof(sc); + rx_npkts = ste_rxeof(sc); ste_txeof(sc); if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) ste_start_locked(ifp); @@ -667,6 +670,7 @@ ste_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count) ste_init_locked(sc); } } + return (rx_npkts); } #endif /* DEVICE_POLLING */ @@ -765,14 +769,14 @@ ste_rxeoc(struct ste_softc *sc) * A frame has been uploaded: pass the resulting mbuf chain up to * the higher level protocols. */ -static void +static int ste_rxeof(sc) struct ste_softc *sc; { struct mbuf *m; struct ifnet *ifp; struct ste_chain_onefrag *cur_rx; - int total_len = 0, count=0; + int total_len = 0, count=0, rx_npkts = 0; u_int32_t rxstat; STE_LOCK_ASSERT(sc); @@ -847,9 +851,10 @@ ste_rxeof(sc) cur_rx->ste_ptr->ste_status = 0; count++; + rx_npkts++; } - return; + return (rx_npkts); } static void diff --git a/sys/dev/stge/if_stge.c b/sys/dev/stge/if_stge.c index e78ff25ab48a..0e12728aaf53 100644 --- a/sys/dev/stge/if_stge.c +++ b/sys/dev/stge/if_stge.c @@ -160,7 +160,7 @@ static void stge_link_task(void *, int); static void stge_intr(void *); static __inline int stge_tx_error(struct stge_softc *); static void stge_txeof(struct stge_softc *); -static void stge_rxeof(struct stge_softc *); +static int stge_rxeof(struct stge_softc *); static __inline void stge_discard_rxbuf(struct stge_softc *, int); static int stge_newbuf(struct stge_softc *, int); #ifndef __NO_STRICT_ALIGNMENT @@ -184,7 +184,7 @@ static void stge_dma_wait(struct stge_softc *); static void stge_init_tx_ring(struct stge_softc *); static int stge_init_rx_ring(struct stge_softc *); #ifdef DEVICE_POLLING -static void stge_poll(struct ifnet *, enum poll_cmd, int); +static int stge_poll(struct ifnet *, enum poll_cmd, int); #endif static void stge_setwol(struct stge_softc *); @@ -1772,7 +1772,7 @@ stge_fixup_rx(struct stge_softc *sc, struct mbuf *m) * * Helper; handle receive interrupts. */ -static void +static int stge_rxeof(struct stge_softc *sc) { struct ifnet *ifp; @@ -1780,10 +1780,11 @@ stge_rxeof(struct stge_softc *sc) struct mbuf *mp, *m; uint64_t status64; uint32_t status; - int cons, prog; + int cons, prog, rx_npkts; STGE_LOCK_ASSERT(sc); + rx_npkts = 0; ifp = sc->sc_ifp; bus_dmamap_sync(sc->sc_cdata.stge_rx_ring_tag, @@ -1901,6 +1902,7 @@ stge_rxeof(struct stge_softc *sc) /* Pass it on. */ (*ifp->if_input)(ifp, m); STGE_LOCK(sc); + rx_npkts++; STGE_RXCHAIN_RESET(sc); } @@ -1913,24 +1915,27 @@ stge_rxeof(struct stge_softc *sc) sc->sc_cdata.stge_rx_ring_map, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); } + return (rx_npkts); } #ifdef DEVICE_POLLING -static void +static int stge_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) { struct stge_softc *sc; uint16_t status; + int rx_npkts; + rx_npkts = 0; sc = ifp->if_softc; STGE_LOCK(sc); if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { STGE_UNLOCK(sc); - return; + return (rx_npkts); } sc->sc_cdata.stge_rxcycles = count; - stge_rxeof(sc); + rx_npkts = stge_rxeof(sc); stge_txeof(sc); if (cmd == POLL_AND_CHECK_STATUS) { @@ -1954,6 +1959,7 @@ stge_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) stge_start_locked(ifp); STGE_UNLOCK(sc); + return (rx_npkts); } #endif /* DEVICE_POLLING */ diff --git a/sys/dev/tsec/if_tsec.c b/sys/dev/tsec/if_tsec.c index 7c11229e131c..3676cfca9a3b 100644 --- a/sys/dev/tsec/if_tsec.c +++ b/sys/dev/tsec/if_tsec.c @@ -97,7 +97,7 @@ static int tsec_sysctl_ic_time(SYSCTL_HANDLER_ARGS); static int tsec_sysctl_ic_count(SYSCTL_HANDLER_ARGS); static void tsec_set_rxic(struct tsec_softc *sc); static void tsec_set_txic(struct tsec_softc *sc); -static void tsec_receive_intr_locked(struct tsec_softc *sc, int count); +static int tsec_receive_intr_locked(struct tsec_softc *sc, int count); static void tsec_transmit_intr_locked(struct tsec_softc *sc); static void tsec_error_intr_locked(struct tsec_softc *sc, int count); static void tsec_offload_setup(struct tsec_softc *sc); @@ -857,16 +857,19 @@ tsec_setfilter(struct tsec_softc *sc) #ifdef DEVICE_POLLING static poll_handler_t tsec_poll; -static void +static int tsec_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) { uint32_t ie; struct tsec_softc *sc = ifp->if_softc; + int rx_npkts; + + rx_npkts = 0; TSEC_GLOBAL_LOCK(sc); if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { TSEC_GLOBAL_UNLOCK(sc); - return; + return (rx_npkts); } if (cmd == POLL_AND_CHECK_STATUS) { @@ -881,9 +884,11 @@ tsec_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) TSEC_GLOBAL_TO_RECEIVE_LOCK(sc); - tsec_receive_intr_locked(sc, count); + rx_npkts = tsec_receive_intr_locked(sc, count); TSEC_RECEIVE_UNLOCK(sc); + + return (rx_npkts); } #endif /* DEVICE_POLLING */ @@ -1248,7 +1253,7 @@ tsec_tick(void *arg) * * Loops at most count times if count is > 0, or until done if count < 0. */ -static void +static int tsec_receive_intr_locked(struct tsec_softc *sc, int count) { struct tsec_desc *rx_desc; @@ -1257,7 +1262,7 @@ tsec_receive_intr_locked(struct tsec_softc *sc, int count) struct mbuf *m; device_t dev; uint32_t i; - int c; + int c, rx_npkts; uint16_t flags; TSEC_RECEIVE_LOCK_ASSERT(sc); @@ -1265,6 +1270,7 @@ tsec_receive_intr_locked(struct tsec_softc *sc, int count) ifp = sc->tsec_ifp; rx_data = sc->rx_data; dev = sc->dev; + rx_npkts = 0; bus_dmamap_sync(sc->tsec_rx_dtag, sc->tsec_rx_dmap, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); @@ -1358,6 +1364,7 @@ tsec_receive_intr_locked(struct tsec_softc *sc, int count) TSEC_RECEIVE_UNLOCK(sc); (*ifp->if_input)(ifp, m); TSEC_RECEIVE_LOCK(sc); + rx_npkts++; } } @@ -1373,6 +1380,7 @@ tsec_receive_intr_locked(struct tsec_softc *sc, int count) * halted, and is harmless if already running. */ TSEC_WRITE(sc, TSEC_REG_RSTAT, TSEC_RSTAT_QHLT); + return (rx_npkts); } void diff --git a/sys/dev/vge/if_vge.c b/sys/dev/vge/if_vge.c index 5a56eb1e0662..b9eaeaa42750 100644 --- a/sys/dev/vge/if_vge.c +++ b/sys/dev/vge/if_vge.c @@ -156,7 +156,7 @@ static int vge_tx_list_init (struct vge_softc *); static __inline void vge_fixup_rx (struct mbuf *); #endif -static void vge_rxeof (struct vge_softc *); +static int vge_rxeof (struct vge_softc *); static void vge_txeof (struct vge_softc *); static void vge_intr (void *); static void vge_tick (void *); @@ -1295,7 +1295,7 @@ vge_fixup_rx(m) * RX handler. We support the reception of jumbo frames that have * been fragmented across multiple 2K mbuf cluster buffers. */ -static void +static int vge_rxeof(sc) struct vge_softc *sc; { @@ -1482,7 +1482,7 @@ vge_rxeof(sc) CSR_WRITE_2(sc, VGE_RXDESC_RESIDUECNT, lim); - return; + return (lim); } static void @@ -1582,17 +1582,18 @@ vge_tick(xsc) } #ifdef DEVICE_POLLING -static void +static int vge_poll (struct ifnet *ifp, enum poll_cmd cmd, int count) { struct vge_softc *sc = ifp->if_softc; + int rx_npkts = 0; VGE_LOCK(sc); if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) goto done; sc->rxcycles = count; - vge_rxeof(sc); + rx_npkts = vge_rxeof(sc); vge_txeof(sc); if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) @@ -1623,6 +1624,7 @@ vge_poll (struct ifnet *ifp, enum poll_cmd cmd, int count) } done: VGE_UNLOCK(sc); + return (rx_npkts); } #endif /* DEVICE_POLLING */ diff --git a/sys/dev/vr/if_vr.c b/sys/dev/vr/if_vr.c index 46414099fa90..0ec70bc20431 100644 --- a/sys/dev/vr/if_vr.c +++ b/sys/dev/vr/if_vr.c @@ -160,7 +160,7 @@ static int vr_newbuf(struct vr_softc *, int); #ifndef __NO_STRICT_ALIGNMENT static __inline void vr_fixup_rx(struct mbuf *); #endif -static void vr_rxeof(struct vr_softc *); +static int vr_rxeof(struct vr_softc *); static void vr_txeof(struct vr_softc *); static void vr_tick(void *); static int vr_error(struct vr_softc *, uint16_t); @@ -1296,19 +1296,20 @@ vr_fixup_rx(struct mbuf *m) * A frame has been uploaded: pass the resulting mbuf chain up to * the higher level protocols. */ -static void +static int vr_rxeof(struct vr_softc *sc) { struct vr_rxdesc *rxd; struct mbuf *m; struct ifnet *ifp; struct vr_desc *cur_rx; - int cons, prog, total_len; + int cons, prog, total_len, rx_npkts; uint32_t rxstat, rxctl; VR_LOCK_ASSERT(sc); ifp = sc->vr_ifp; cons = sc->vr_cdata.vr_rx_cons; + rx_npkts = 0; bus_dmamap_sync(sc->vr_cdata.vr_rx_ring_tag, sc->vr_cdata.vr_rx_ring_map, @@ -1414,6 +1415,7 @@ vr_rxeof(struct vr_softc *sc) VR_UNLOCK(sc); (*ifp->if_input)(ifp, m); VR_LOCK(sc); + rx_npkts++; } if (prog > 0) { @@ -1422,6 +1424,7 @@ vr_rxeof(struct vr_softc *sc) sc->vr_cdata.vr_rx_ring_map, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); } + return (rx_npkts); } /* @@ -1571,30 +1574,34 @@ vr_tick(void *xsc) static poll_handler_t vr_poll; static poll_handler_t vr_poll_locked; -static void +static int vr_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) { struct vr_softc *sc; + int rx_npkts; sc = ifp->if_softc; + rx_npkts = 0; VR_LOCK(sc); if ((ifp->if_drv_flags & IFF_DRV_RUNNING) != 0) - vr_poll_locked(ifp, cmd, count); + rx_npkts = vr_poll_locked(ifp, cmd, count); VR_UNLOCK(sc); + return (rx_npkts); } -static void +static int vr_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count) { struct vr_softc *sc; + int rx_npkts; sc = ifp->if_softc; VR_LOCK_ASSERT(sc); sc->rxcycles = count; - vr_rxeof(sc); + rx_npkts = vr_rxeof(sc); vr_txeof(sc); if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) vr_start_locked(ifp); @@ -1608,12 +1615,12 @@ vr_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count) CSR_WRITE_2(sc, VR_ISR, status); if ((status & VR_INTRS) == 0) - return; + return (rx_npkts); if ((status & (VR_ISR_BUSERR | VR_ISR_LINKSTAT2 | VR_ISR_STATSOFLOW)) != 0) { if (vr_error(sc, status) != 0) - return; + return (rx_npkts); } if ((status & (VR_ISR_RX_NOBUF | VR_ISR_RX_OFLOW)) != 0) { #ifdef VR_SHOW_ERRORS @@ -1623,6 +1630,7 @@ vr_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count) vr_rx_start(sc); } } + return (rx_npkts); } #endif /* DEVICE_POLLING */ diff --git a/sys/dev/xl/if_xl.c b/sys/dev/xl/if_xl.c index 073aa416df0a..a0f70420bfef 100644 --- a/sys/dev/xl/if_xl.c +++ b/sys/dev/xl/if_xl.c @@ -228,7 +228,7 @@ static int xl_newbuf(struct xl_softc *, struct xl_chain_onefrag *); static void xl_stats_update(void *); static void xl_stats_update_locked(struct xl_softc *); static int xl_encap(struct xl_softc *, struct xl_chain *, struct mbuf **); -static void xl_rxeof(struct xl_softc *); +static int xl_rxeof(struct xl_softc *); static void xl_rxeof_task(void *, int); static int xl_rx_resync(struct xl_softc *); static void xl_txeof(struct xl_softc *); @@ -248,8 +248,8 @@ static int xl_suspend(device_t); static int xl_resume(device_t); #ifdef DEVICE_POLLING -static void xl_poll(struct ifnet *ifp, enum poll_cmd cmd, int count); -static void xl_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count); +static int xl_poll(struct ifnet *ifp, enum poll_cmd cmd, int count); +static int xl_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count); #endif static int xl_ifmedia_upd(struct ifnet *); @@ -1882,13 +1882,14 @@ xl_rx_resync(struct xl_softc *sc) * A frame has been uploaded: pass the resulting mbuf chain up to * the higher level protocols. */ -static void +static int xl_rxeof(struct xl_softc *sc) { struct mbuf *m; struct ifnet *ifp = sc->xl_ifp; struct xl_chain_onefrag *cur_rx; int total_len = 0; + int rx_npkts = 0; u_int32_t rxstat; XL_LOCK_ASSERT(sc); @@ -1990,6 +1991,7 @@ xl_rxeof(struct xl_softc *sc) XL_UNLOCK(sc); (*ifp->if_input)(ifp, m); XL_LOCK(sc); + rx_npkts++; /* * If we are running from the taskqueue, the interface @@ -1997,7 +1999,7 @@ xl_rxeof(struct xl_softc *sc) * packet up the network stack. */ if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) - return; + return (rx_npkts); } /* @@ -2021,6 +2023,7 @@ xl_rxeof(struct xl_softc *sc) CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_UP_UNSTALL); goto again; } + return (rx_npkts); } /* @@ -2265,26 +2268,29 @@ xl_intr(void *arg) } #ifdef DEVICE_POLLING -static void +static int xl_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) { struct xl_softc *sc = ifp->if_softc; + int rx_npkts = 0; XL_LOCK(sc); if (ifp->if_drv_flags & IFF_DRV_RUNNING) - xl_poll_locked(ifp, cmd, count); + rx_npkts = xl_poll_locked(ifp, cmd, count); XL_UNLOCK(sc); + return (rx_npkts); } -static void +static int xl_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count) { struct xl_softc *sc = ifp->if_softc; + int rx_npkts; XL_LOCK_ASSERT(sc); sc->rxcycles = count; - xl_rxeof(sc); + rx_npkts = xl_rxeof(sc); if (sc->xl_type == XL_TYPE_905B) xl_txeof_90xB(sc); else @@ -2322,6 +2328,7 @@ xl_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count) } } } + return (rx_npkts); } #endif /* DEVICE_POLLING */ diff --git a/sys/net/if.h b/sys/net/if.h index 30b9ccbeb883..b73b46f4e001 100644 --- a/sys/net/if.h +++ b/sys/net/if.h @@ -216,6 +216,7 @@ struct if_data { #define IFCAP_TOE4 0x04000 /* interface can offload TCP */ #define IFCAP_TOE6 0x08000 /* interface can offload TCP6 */ #define IFCAP_VLAN_HWFILTER 0x10000 /* interface hw can filter vlan tag */ +#define IFCAP_POLLING_NOCOUNT 0x20000 /* polling ticks cannot be fragmented */ #define IFCAP_HWCSUM (IFCAP_RXCSUM | IFCAP_TXCSUM) #define IFCAP_TSO (IFCAP_TSO4 | IFCAP_TSO6) diff --git a/sys/net/if_var.h b/sys/net/if_var.h index 6124352cbbb3..d811f227acad 100644 --- a/sys/net/if_var.h +++ b/sys/net/if_var.h @@ -807,7 +807,7 @@ void if_deregister_com_alloc(u_char type); #ifdef DEVICE_POLLING enum poll_cmd { POLL_ONLY, POLL_AND_CHECK_STATUS }; -typedef void poll_handler_t(struct ifnet *ifp, enum poll_cmd cmd, int count); +typedef int poll_handler_t(struct ifnet *ifp, enum poll_cmd cmd, int count); int ether_poll_register(poll_handler_t *h, struct ifnet *ifp); int ether_poll_deregister(struct ifnet *ifp); #endif /* DEVICE_POLLING */ diff --git a/sys/pci/if_rl.c b/sys/pci/if_rl.c index dc3e3b5c0932..16e3ccc14c6d 100644 --- a/sys/pci/if_rl.c +++ b/sys/pci/if_rl.c @@ -205,14 +205,14 @@ static int rl_miibus_readreg(device_t, int, int); static void rl_miibus_statchg(device_t); static int rl_miibus_writereg(device_t, int, int, int); #ifdef DEVICE_POLLING -static void rl_poll(struct ifnet *ifp, enum poll_cmd cmd, int count); -static void rl_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count); +static int rl_poll(struct ifnet *ifp, enum poll_cmd cmd, int count); +static int rl_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count); #endif static int rl_probe(device_t); static void rl_read_eeprom(struct rl_softc *, uint8_t *, int, int, int); static void rl_reset(struct rl_softc *); static int rl_resume(device_t); -static void rl_rxeof(struct rl_softc *); +static int rl_rxeof(struct rl_softc *); static void rl_setmulti(struct rl_softc *); static int rl_shutdown(device_t); static void rl_start(struct ifnet *); @@ -1221,7 +1221,7 @@ rl_list_rx_init(struct rl_softc *sc) * on a 32-bit boundary. To achieve this, we pass RL_ETHER_ALIGN (2 bytes) * as the offset argument to m_devget(). */ -static void +static int rl_rxeof(struct rl_softc *sc) { struct mbuf *m; @@ -1229,6 +1229,7 @@ rl_rxeof(struct rl_softc *sc) uint8_t *rxbufpos; int total_len = 0; int wrap = 0; + int rx_npkts = 0; uint32_t rxstat; uint16_t cur_rx; uint16_t limit; @@ -1277,7 +1278,7 @@ rl_rxeof(struct rl_softc *sc) total_len > ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN) { ifp->if_ierrors++; rl_init_locked(sc); - return; + return (rx_npkts); } /* No errors; receive the packet. */ @@ -1331,9 +1332,11 @@ rl_rxeof(struct rl_softc *sc) RL_UNLOCK(sc); (*ifp->if_input)(ifp, m); RL_LOCK(sc); + rx_npkts++; } /* No need to sync Rx memory block as we didn't modify it. */ + return (rx_npkts); } /* @@ -1538,26 +1541,29 @@ rl_tick(void *xsc) } #ifdef DEVICE_POLLING -static void +static int rl_poll(struct ifnet *ifp, enum poll_cmd cmd, int count) { struct rl_softc *sc = ifp->if_softc; + int rx_npkts = 0; RL_LOCK(sc); if (ifp->if_drv_flags & IFF_DRV_RUNNING) - rl_poll_locked(ifp, cmd, count); + rx_npkts = rl_poll_locked(ifp, cmd, count); RL_UNLOCK(sc); + return (rx_npkts); } -static void +static int rl_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count) { struct rl_softc *sc = ifp->if_softc; + int rx_npkts; RL_LOCK_ASSERT(sc); sc->rxcycles = count; - rl_rxeof(sc); + rx_npkts = rl_rxeof(sc); rl_txeof(sc); if (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) @@ -1569,7 +1575,7 @@ rl_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count) /* We should also check the status register. */ status = CSR_READ_2(sc, RL_ISR); if (status == 0xffff) - return; + return (rx_npkts); if (status != 0) CSR_WRITE_2(sc, RL_ISR, status); @@ -1578,6 +1584,7 @@ rl_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count) if (status & RL_ISR_SYSTEM_ERR) rl_init_locked(sc); } + return (rx_npkts); } #endif /* DEVICE_POLLING */ diff --git a/sys/sys/param.h b/sys/sys/param.h index 742694497c0c..9defb92e7eb5 100644 --- a/sys/sys/param.h +++ b/sys/sys/param.h @@ -57,7 +57,7 @@ * is created, otherwise 1. */ #undef __FreeBSD_version -#define __FreeBSD_version 800094 /* Master, propagated to newvers */ +#define __FreeBSD_version 800095 /* Master, propagated to newvers */ #ifndef LOCORE #include