diff --git a/drivers/net/sfc/sfc_ev.c b/drivers/net/sfc/sfc_ev.c index 412645a0e2..bb22001565 100644 --- a/drivers/net/sfc/sfc_ev.c +++ b/drivers/net/sfc/sfc_ev.c @@ -70,6 +70,18 @@ sfc_ev_initialized(void *arg) return B_FALSE; } +static boolean_t +sfc_ev_nop_rx(void *arg, uint32_t label, uint32_t id, + uint32_t size, uint16_t flags) +{ + struct sfc_evq *evq = arg; + + sfc_err(evq->sa, + "EVQ %u unexpected Rx event label=%u id=%#x size=%u flags=%#x", + evq->evq_index, label, id, size, flags); + return B_TRUE; +} + static boolean_t sfc_ev_rx(void *arg, __rte_unused uint32_t label, uint32_t id, uint32_t size, uint16_t flags) @@ -143,6 +155,16 @@ done: return B_FALSE; } +static boolean_t +sfc_ev_nop_tx(void *arg, uint32_t label, uint32_t id) +{ + struct sfc_evq *evq = arg; + + sfc_err(evq->sa, "EVQ %u unexpected Tx event label=%u id=%#x", + evq->evq_index, label, id); + return B_TRUE; +} + static boolean_t sfc_ev_tx(void *arg, __rte_unused uint32_t label, uint32_t id) { @@ -197,6 +219,16 @@ sfc_ev_exception(void *arg, __rte_unused uint32_t code, return B_TRUE; } +static boolean_t +sfc_ev_nop_rxq_flush_done(void *arg, uint32_t rxq_hw_index) +{ + struct sfc_evq *evq = arg; + + sfc_err(evq->sa, "EVQ %u unexpected RxQ %u flush done", + evq->evq_index, rxq_hw_index); + return B_TRUE; +} + static boolean_t sfc_ev_rxq_flush_done(void *arg, __rte_unused uint32_t rxq_hw_index) { @@ -212,6 +244,16 @@ sfc_ev_rxq_flush_done(void *arg, __rte_unused uint32_t rxq_hw_index) return B_FALSE; } +static boolean_t +sfc_ev_nop_rxq_flush_failed(void *arg, uint32_t rxq_hw_index) +{ + struct sfc_evq *evq = arg; + + sfc_err(evq->sa, "EVQ %u unexpected RxQ %u flush failed", + evq->evq_index, rxq_hw_index); + return B_TRUE; +} + static boolean_t sfc_ev_rxq_flush_failed(void *arg, __rte_unused uint32_t rxq_hw_index) { @@ -227,6 +269,16 @@ sfc_ev_rxq_flush_failed(void *arg, __rte_unused uint32_t rxq_hw_index) return B_FALSE; } +static boolean_t +sfc_ev_nop_txq_flush_done(void *arg, uint32_t txq_hw_index) +{ + struct sfc_evq *evq = arg; + + sfc_err(evq->sa, "EVQ %u unexpected TxQ %u flush done", + evq->evq_index, txq_hw_index); + return B_TRUE; +} + static boolean_t sfc_ev_txq_flush_done(void *arg, __rte_unused uint32_t txq_hw_index) { @@ -282,6 +334,16 @@ sfc_ev_timer(void *arg, uint32_t index) return B_TRUE; } +static boolean_t +sfc_ev_nop_link_change(void *arg, __rte_unused efx_link_mode_t link_mode) +{ + struct sfc_evq *evq = arg; + + sfc_err(evq->sa, "EVQ %u unexpected link change event", + evq->evq_index); + return B_TRUE; +} + static boolean_t sfc_ev_link_change(void *arg, efx_link_mode_t link_mode) { @@ -314,12 +376,12 @@ sfc_ev_link_change(void *arg, efx_link_mode_t link_mode) static const efx_ev_callbacks_t sfc_ev_callbacks = { .eec_initialized = sfc_ev_initialized, - .eec_rx = sfc_ev_rx, - .eec_tx = sfc_ev_tx, + .eec_rx = sfc_ev_nop_rx, + .eec_tx = sfc_ev_nop_tx, .eec_exception = sfc_ev_exception, - .eec_rxq_flush_done = sfc_ev_rxq_flush_done, - .eec_rxq_flush_failed = sfc_ev_rxq_flush_failed, - .eec_txq_flush_done = sfc_ev_txq_flush_done, + .eec_rxq_flush_done = sfc_ev_nop_rxq_flush_done, + .eec_rxq_flush_failed = sfc_ev_nop_rxq_flush_failed, + .eec_txq_flush_done = sfc_ev_nop_txq_flush_done, .eec_software = sfc_ev_software, .eec_sram = sfc_ev_sram, .eec_wake_up = sfc_ev_wake_up, @@ -327,6 +389,36 @@ static const efx_ev_callbacks_t sfc_ev_callbacks = { .eec_link_change = sfc_ev_link_change, }; +static const efx_ev_callbacks_t sfc_ev_callbacks_rx = { + .eec_initialized = sfc_ev_initialized, + .eec_rx = sfc_ev_rx, + .eec_tx = sfc_ev_nop_tx, + .eec_exception = sfc_ev_exception, + .eec_rxq_flush_done = sfc_ev_rxq_flush_done, + .eec_rxq_flush_failed = sfc_ev_rxq_flush_failed, + .eec_txq_flush_done = sfc_ev_nop_txq_flush_done, + .eec_software = sfc_ev_software, + .eec_sram = sfc_ev_sram, + .eec_wake_up = sfc_ev_wake_up, + .eec_timer = sfc_ev_timer, + .eec_link_change = sfc_ev_nop_link_change, +}; + +static const efx_ev_callbacks_t sfc_ev_callbacks_tx = { + .eec_initialized = sfc_ev_initialized, + .eec_rx = sfc_ev_nop_rx, + .eec_tx = sfc_ev_tx, + .eec_exception = sfc_ev_exception, + .eec_rxq_flush_done = sfc_ev_nop_rxq_flush_done, + .eec_rxq_flush_failed = sfc_ev_nop_rxq_flush_failed, + .eec_txq_flush_done = sfc_ev_txq_flush_done, + .eec_software = sfc_ev_software, + .eec_sram = sfc_ev_sram, + .eec_wake_up = sfc_ev_wake_up, + .eec_timer = sfc_ev_timer, + .eec_link_change = sfc_ev_nop_link_change, +}; + void sfc_ev_qpoll(struct sfc_evq *evq) @@ -336,7 +428,7 @@ sfc_ev_qpoll(struct sfc_evq *evq) /* Synchronize the DMA memory for reading not required */ - efx_ev_qpoll(evq->common, &evq->read_ptr, &sfc_ev_callbacks, evq); + 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; @@ -427,6 +519,14 @@ sfc_ev_qstart(struct sfc_adapter *sa, unsigned int sw_index) if (rc != 0) goto fail_ev_qcreate; + SFC_ASSERT(evq->rxq == NULL || evq->txq == NULL); + if (evq->rxq != 0) + evq->callbacks = &sfc_ev_callbacks_rx; + else if (evq->txq != 0) + evq->callbacks = &sfc_ev_callbacks_tx; + else + evq->callbacks = &sfc_ev_callbacks; + evq->init_state = SFC_EVQ_STARTING; /* Wait for the initialization event */ @@ -485,6 +585,7 @@ sfc_ev_qstop(struct sfc_adapter *sa, unsigned int sw_index) return; evq->init_state = SFC_EVQ_INITIALIZED; + evq->callbacks = NULL; evq->read_ptr = 0; evq->exception = B_FALSE; diff --git a/drivers/net/sfc/sfc_ev.h b/drivers/net/sfc/sfc_ev.h index 5bb2be4a28..359958e875 100644 --- a/drivers/net/sfc/sfc_ev.h +++ b/drivers/net/sfc/sfc_ev.h @@ -56,17 +56,18 @@ enum sfc_evq_state { struct sfc_evq { /* Used on datapath */ - efx_evq_t *common; - unsigned int read_ptr; - boolean_t exception; - efsys_mem_t mem; - struct sfc_rxq *rxq; - struct sfc_txq *txq; + efx_evq_t *common; + const efx_ev_callbacks_t *callbacks; + unsigned int read_ptr; + boolean_t exception; + efsys_mem_t mem; + struct sfc_rxq *rxq; + struct sfc_txq *txq; /* Not used on datapath */ - struct sfc_adapter *sa; - unsigned int evq_index; - enum sfc_evq_state init_state; + struct sfc_adapter *sa; + unsigned int evq_index; + enum sfc_evq_state init_state; }; struct sfc_evq_info {