From 5e4ef67346ee8f64b3cac4cbc1c866fd8f18dcd7 Mon Sep 17 00:00:00 2001 From: Edward Cree Date: Mon, 27 Jul 2020 12:58:02 +0100 Subject: [PATCH] sfc_ef100: process events for MCDI completions Currently RX and TX-completion events are unhandled, as neither the RX nor the TX path has been implemented yet. Signed-off-by: Edward Cree Signed-off-by: David S. Miller --- drivers/net/ethernet/sfc/ef100_nic.c | 57 +++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/sfc/ef100_nic.c b/drivers/net/ethernet/sfc/ef100_nic.c index be37055743c3..c6703527bbe9 100644 --- a/drivers/net/ethernet/sfc/ef100_nic.c +++ b/drivers/net/ethernet/sfc/ef100_nic.c @@ -160,7 +160,62 @@ static void ef100_ev_read_ack(struct efx_channel *channel) static int ef100_ev_process(struct efx_channel *channel, int quota) { - return 0; + struct efx_nic *efx = channel->efx; + struct ef100_nic_data *nic_data; + bool evq_phase, old_evq_phase; + unsigned int read_ptr; + efx_qword_t *p_event; + int spent = 0; + bool ev_phase; + int ev_type; + + if (unlikely(!channel->enabled)) + return 0; + + nic_data = efx->nic_data; + evq_phase = test_bit(channel->channel, nic_data->evq_phases); + old_evq_phase = evq_phase; + read_ptr = channel->eventq_read_ptr; + BUILD_BUG_ON(ESF_GZ_EV_RXPKTS_PHASE_LBN != ESF_GZ_EV_TXCMPL_PHASE_LBN); + + while (spent < quota) { + p_event = efx_event(channel, read_ptr); + + ev_phase = !!EFX_QWORD_FIELD(*p_event, ESF_GZ_EV_RXPKTS_PHASE); + if (ev_phase != evq_phase) + break; + + netif_vdbg(efx, drv, efx->net_dev, + "processing event on %d " EFX_QWORD_FMT "\n", + channel->channel, EFX_QWORD_VAL(*p_event)); + + ev_type = EFX_QWORD_FIELD(*p_event, ESF_GZ_E_TYPE); + + switch (ev_type) { + case ESE_GZ_EF100_EV_MCDI: + efx_mcdi_process_event(channel, p_event); + break; + case ESE_GZ_EF100_EV_DRIVER: + netif_info(efx, drv, efx->net_dev, + "Driver initiated event " EFX_QWORD_FMT "\n", + EFX_QWORD_VAL(*p_event)); + break; + default: + netif_info(efx, drv, efx->net_dev, + "Unhandled event " EFX_QWORD_FMT "\n", + EFX_QWORD_VAL(*p_event)); + } + + ++read_ptr; + if ((read_ptr & channel->eventq_mask) == 0) + evq_phase = !evq_phase; + } + + channel->eventq_read_ptr = read_ptr; + if (evq_phase != old_evq_phase) + change_bit(channel->channel, nic_data->evq_phases); + + return spent; } static irqreturn_t ef100_msi_interrupt(int irq, void *dev_id) -- 2.39.5