When user_frac in the polling subsystem is low it is going to busy the

CPU for too long period than necessary.  Additively, interfaces are kept
polled (in the tick) even if no more packets are available.
In order to avoid such situations a new generic mechanism can be
implemented in proactive way, keeping track of the time spent on any
packet and fragmenting the time for any tick, stopping the processing
as soon as possible.

In order to implement such mechanism, the polling handler needs to
change, returning the number of packets processed.
While the intended logic is not part of this patch, the polling KPI is
broken by this commit, adding an int return value and the new flag
IFCAP_POLLING_NOCOUNT (which will signal that the return value is
meaningless for the installed handler and checking should be skipped).

Bump __FreeBSD_version in order to signal such situation.

Reviewed by:	emaste
Sponsored by:	Sandvine Incorporated
This commit is contained in:
Attilio Rao 2009-05-30 15:14:44 +00:00
parent d68bbb81fb
commit 1abcdbd127
27 changed files with 280 additions and 155 deletions

View File

@ -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 */

View File

@ -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];

View File

@ -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);

View File

@ -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 */

View File

@ -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 */

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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);
}
}

View File

@ -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);
}
/*

View File

@ -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);
}
/*********************************************************************

View File

@ -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

View File

@ -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

View File

@ -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);
}

View File

@ -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);

View File

@ -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 */

View File

@ -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 */

View File

@ -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
}

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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)

View File

@ -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 */

View File

@ -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 */

View File

@ -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 <sys/types.h>