void sfc_ev_qpoll(struct sfc_evq *evq) { SFC_ASSERT(evq->init_state == SFC_EVQ_STARTED || evq->init_state == SFC_EVQ_STARTING); /* Synchronize the DMA memory for reading not required */ efx_ev_qpoll(evq->common, &evq->read_ptr, evq->callbacks, evq); if (unlikely(evq->exception) && sfc_adapter_trylock(evq->sa)) { struct sfc_adapter *sa = evq->sa; int rc; if (evq->dp_rxq != NULL) { unsigned int rxq_sw_index; rxq_sw_index = evq->dp_rxq->dpq.queue_id; sfc_warn(sa, "restart RxQ %u because of exception on its EvQ %u", rxq_sw_index, evq->evq_index); sfc_rx_qstop(sa, rxq_sw_index); rc = sfc_rx_qstart(sa, rxq_sw_index); if (rc != 0) sfc_err(sa, "cannot restart RxQ %u", rxq_sw_index); } if (evq->dp_txq != NULL) { unsigned int txq_sw_index; txq_sw_index = evq->dp_txq->dpq.queue_id; sfc_warn(sa, "restart TxQ %u because of exception on its EvQ %u", txq_sw_index, evq->evq_index); sfc_tx_qstop(sa, txq_sw_index); rc = sfc_tx_qstart(sa, txq_sw_index); if (rc != 0) sfc_err(sa, "cannot restart TxQ %u", txq_sw_index); } if (evq->exception) sfc_panic(sa, "unrecoverable exception on EvQ %u", evq->evq_index); sfc_adapter_unlock(sa); } /* Poll-mode driver does not re-prime the event queue for interrupts */ }
int sfxge_ev_qpoll(struct sfxge_softc *sc, unsigned int index) { struct sfxge_evq *evq; int rc; evq = sc->evq[index]; mtx_lock(&evq->lock); if (evq->init_state != SFXGE_EVQ_STARTING && evq->init_state != SFXGE_EVQ_STARTED) { rc = EINVAL; goto fail; } /* Synchronize the DMA memory for reading */ bus_dmamap_sync(evq->mem.esm_tag, evq->mem.esm_map, BUS_DMASYNC_POSTREAD); KASSERT(evq->rx_done == 0, ("evq->rx_done != 0")); KASSERT(evq->tx_done == 0, ("evq->tx_done != 0")); KASSERT(evq->txq == NULL, ("evq->txq != NULL")); KASSERT(evq->txqs == &evq->txq, ("evq->txqs != &evq->txq")); /* Poll the queue */ efx_ev_qpoll(evq->common, &evq->read_ptr, &sfxge_ev_callbacks, evq); evq->rx_done = 0; evq->tx_done = 0; /* Perform any pending completion processing */ sfxge_ev_qcomplete(evq, B_TRUE); /* Re-prime the event queue for interrupts */ if ((rc = efx_ev_qprime(evq->common, evq->read_ptr)) != 0) goto fail; mtx_unlock(&evq->lock); return (0); fail: mtx_unlock(&(evq->lock)); return (rc); }
int sfxge_ev_qpoll(struct sfxge_evq *evq) { int rc; SFXGE_EVQ_LOCK(evq); if (__predict_false(evq->init_state != SFXGE_EVQ_STARTING && evq->init_state != SFXGE_EVQ_STARTED)) { rc = EINVAL; goto fail; } /* Synchronize the DMA memory for reading */ bus_dmamap_sync(evq->mem.esm_tag, evq->mem.esm_map, BUS_DMASYNC_POSTREAD); KASSERT(evq->rx_done == 0, ("evq->rx_done != 0")); KASSERT(evq->tx_done == 0, ("evq->tx_done != 0")); KASSERT(evq->txq == NULL, ("evq->txq != NULL")); KASSERT(evq->txqs == &evq->txq, ("evq->txqs != &evq->txq")); /* Poll the queue */ efx_ev_qpoll(evq->common, &evq->read_ptr, &sfxge_ev_callbacks, evq); evq->rx_done = 0; evq->tx_done = 0; /* Perform any pending completion processing */ sfxge_ev_qcomplete(evq, B_TRUE); /* Re-prime the event queue for interrupts */ if ((rc = efx_ev_qprime(evq->common, evq->read_ptr)) != 0) goto fail; SFXGE_EVQ_UNLOCK(evq); return (0); fail: SFXGE_EVQ_UNLOCK(evq); return (rc); }