From a81dcd85a7c1bc548ce8fb635623970fdee5887d Mon Sep 17 00:00:00 2001 From: Edward Cree Date: Thu, 2 Jul 2020 17:29:58 +0100 Subject: sfc: assign TXQs without gaps Since we only allocate VIs for the number of TXQs we actually need, we cannot naively use "channel * TXQ_TYPES + txq" for the TXQ number, as this has gaps (when efx->tx_queues_per_channel < EFX_TXQ_TYPES) and thus overruns the driver's VI allocations, causing the firmware to reject the MC_CMD_INIT_TXQ based on INSTANCE. Thus, we distinguish INSTANCE (stored in tx_queue->queue) from LABEL (tx_queue->label); the former is allocated starting from 0 in efx_set_channels(), while the latter is simply the txq type (index in channel->tx_queue array). To simplify things, rather than changing tx_queues_per_channel after setting up TXQs, make Siena always probe its HIGHPRI queues at start of day, rather than deferring it until tc mqprio enables them. Signed-off-by: Edward Cree Signed-off-by: David S. Miller --- drivers/net/ethernet/sfc/mcdi_functions.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net/ethernet/sfc/mcdi_functions.c') diff --git a/drivers/net/ethernet/sfc/mcdi_functions.c b/drivers/net/ethernet/sfc/mcdi_functions.c index 962d8395d958..b3a8aa88db06 100644 --- a/drivers/net/ethernet/sfc/mcdi_functions.c +++ b/drivers/net/ethernet/sfc/mcdi_functions.c @@ -164,7 +164,7 @@ int efx_mcdi_tx_init(struct efx_tx_queue *tx_queue, bool tso_v2) { MCDI_DECLARE_BUF(inbuf, MC_CMD_INIT_TXQ_IN_LEN(EFX_MAX_DMAQ_SIZE * 8 / EFX_BUF_SIZE)); - bool csum_offload = tx_queue->queue & EFX_TXQ_TYPE_OFFLOAD; + bool csum_offload = tx_queue->label & EFX_TXQ_TYPE_OFFLOAD; size_t entries = tx_queue->txd.buf.len / EFX_BUF_SIZE; struct efx_channel *channel = tx_queue->channel; struct efx_nic *efx = tx_queue->efx; @@ -176,7 +176,7 @@ int efx_mcdi_tx_init(struct efx_tx_queue *tx_queue, bool tso_v2) MCDI_SET_DWORD(inbuf, INIT_TXQ_IN_SIZE, tx_queue->ptr_mask + 1); MCDI_SET_DWORD(inbuf, INIT_TXQ_IN_TARGET_EVQ, channel->channel); - MCDI_SET_DWORD(inbuf, INIT_TXQ_IN_LABEL, tx_queue->queue); + MCDI_SET_DWORD(inbuf, INIT_TXQ_IN_LABEL, tx_queue->label); MCDI_SET_DWORD(inbuf, INIT_TXQ_IN_INSTANCE, tx_queue->queue); MCDI_SET_DWORD(inbuf, INIT_TXQ_IN_OWNER_ID, 0); MCDI_SET_DWORD(inbuf, INIT_TXQ_IN_PORT_ID, efx->vport_id); -- cgit v1.2.3 From d700fe014ec13cf96df8df4de6ee46034008ff85 Mon Sep 17 00:00:00 2001 From: Edward Cree Date: Thu, 2 Jul 2020 17:30:56 +0100 Subject: sfc: commonise efx_fini_dmaq Signed-off-by: Edward Cree Signed-off-by: David S. Miller --- drivers/net/ethernet/sfc/ef10.c | 42 ++----------------------------- drivers/net/ethernet/sfc/mcdi_functions.c | 38 ++++++++++++++++++++++++++++ drivers/net/ethernet/sfc/mcdi_functions.h | 1 + 3 files changed, 41 insertions(+), 40 deletions(-) (limited to 'drivers/net/ethernet/sfc/mcdi_functions.c') diff --git a/drivers/net/ethernet/sfc/ef10.c b/drivers/net/ethernet/sfc/ef10.c index 311a2d2a906d..d2101d2a55be 100644 --- a/drivers/net/ethernet/sfc/ef10.c +++ b/drivers/net/ethernet/sfc/ef10.c @@ -3117,44 +3117,6 @@ fail: netif_err(efx, hw, efx->net_dev, "%s: failed rc=%d\n", __func__, rc); } -static int efx_ef10_fini_dmaq(struct efx_nic *efx) -{ - struct efx_tx_queue *tx_queue; - struct efx_rx_queue *rx_queue; - struct efx_channel *channel; - int pending; - - /* If the MC has just rebooted, the TX/RX queues will have already been - * torn down, but efx->active_queues needs to be set to zero. - */ - if (efx->must_realloc_vis) { - atomic_set(&efx->active_queues, 0); - return 0; - } - - /* Do not attempt to write to the NIC during EEH recovery */ - if (efx->state != STATE_RECOVERY) { - efx_for_each_channel(channel, efx) { - efx_for_each_channel_rx_queue(rx_queue, channel) - efx_mcdi_rx_fini(rx_queue); - efx_for_each_channel_tx_queue(tx_queue, channel) - efx_mcdi_tx_fini(tx_queue); - } - - wait_event_timeout(efx->flush_wq, - atomic_read(&efx->active_queues) == 0, - msecs_to_jiffies(EFX_MAX_FLUSH_TIME)); - pending = atomic_read(&efx->active_queues); - if (pending) { - netif_err(efx, hw, efx->net_dev, "failed to flush %d queues\n", - pending); - return -ETIMEDOUT; - } - } - - return 0; -} - static void efx_ef10_prepare_flr(struct efx_nic *efx) { atomic_set(&efx->active_queues, 0); @@ -4026,7 +3988,7 @@ const struct efx_nic_type efx_hunt_a0_vf_nic_type = { .reset = efx_ef10_reset, .probe_port = efx_mcdi_port_probe, .remove_port = efx_mcdi_port_remove, - .fini_dmaq = efx_ef10_fini_dmaq, + .fini_dmaq = efx_fini_dmaq, .prepare_flr = efx_ef10_prepare_flr, .finish_flr = efx_port_dummy_op_void, .describe_stats = efx_ef10_describe_stats, @@ -4134,7 +4096,7 @@ const struct efx_nic_type efx_hunt_a0_nic_type = { .reset = efx_ef10_reset, .probe_port = efx_mcdi_port_probe, .remove_port = efx_mcdi_port_remove, - .fini_dmaq = efx_ef10_fini_dmaq, + .fini_dmaq = efx_fini_dmaq, .prepare_flr = efx_ef10_prepare_flr, .finish_flr = efx_port_dummy_op_void, .describe_stats = efx_ef10_describe_stats, diff --git a/drivers/net/ethernet/sfc/mcdi_functions.c b/drivers/net/ethernet/sfc/mcdi_functions.c index b3a8aa88db06..92b9a741c286 100644 --- a/drivers/net/ethernet/sfc/mcdi_functions.c +++ b/drivers/net/ethernet/sfc/mcdi_functions.c @@ -341,6 +341,44 @@ fail: outbuf, outlen, rc); } +int efx_fini_dmaq(struct efx_nic *efx) +{ + struct efx_tx_queue *tx_queue; + struct efx_rx_queue *rx_queue; + struct efx_channel *channel; + int pending; + + /* If the MC has just rebooted, the TX/RX queues will have already been + * torn down, but efx->active_queues needs to be set to zero. + */ + if (efx->must_realloc_vis) { + atomic_set(&efx->active_queues, 0); + return 0; + } + + /* Do not attempt to write to the NIC during EEH recovery */ + if (efx->state != STATE_RECOVERY) { + efx_for_each_channel(channel, efx) { + efx_for_each_channel_rx_queue(rx_queue, channel) + efx_mcdi_rx_fini(rx_queue); + efx_for_each_channel_tx_queue(tx_queue, channel) + efx_mcdi_tx_fini(tx_queue); + } + + wait_event_timeout(efx->flush_wq, + atomic_read(&efx->active_queues) == 0, + msecs_to_jiffies(EFX_MAX_FLUSH_TIME)); + pending = atomic_read(&efx->active_queues); + if (pending) { + netif_err(efx, hw, efx->net_dev, "failed to flush %d queues\n", + pending); + return -ETIMEDOUT; + } + } + + return 0; +} + int efx_mcdi_window_mode_to_stride(struct efx_nic *efx, u8 vi_window_mode) { switch (vi_window_mode) { diff --git a/drivers/net/ethernet/sfc/mcdi_functions.h b/drivers/net/ethernet/sfc/mcdi_functions.h index ca4a5ac1a66b..687be8b00cd8 100644 --- a/drivers/net/ethernet/sfc/mcdi_functions.h +++ b/drivers/net/ethernet/sfc/mcdi_functions.h @@ -26,6 +26,7 @@ int efx_mcdi_rx_probe(struct efx_rx_queue *rx_queue); void efx_mcdi_rx_init(struct efx_rx_queue *rx_queue); void efx_mcdi_rx_remove(struct efx_rx_queue *rx_queue); void efx_mcdi_rx_fini(struct efx_rx_queue *rx_queue); +int efx_fini_dmaq(struct efx_nic *efx); int efx_mcdi_window_mode_to_stride(struct efx_nic *efx, u8 vi_window_mode); int efx_get_pf_index(struct efx_nic *efx, unsigned int *pf_index); -- cgit v1.2.3 From 39c965f4e663fa53955f77435068748448514da1 Mon Sep 17 00:00:00 2001 From: Edward Cree Date: Thu, 2 Jul 2020 17:32:24 +0100 Subject: sfc_ef100: populate BUFFER_SIZE_BYTES in INIT_RXQ The QDMA subsystem on EF100 needs this information. Signed-off-by: Edward Cree Signed-off-by: David S. Miller --- drivers/net/ethernet/sfc/mcdi_functions.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'drivers/net/ethernet/sfc/mcdi_functions.c') diff --git a/drivers/net/ethernet/sfc/mcdi_functions.c b/drivers/net/ethernet/sfc/mcdi_functions.c index 92b9a741c286..d8a3af86ef78 100644 --- a/drivers/net/ethernet/sfc/mcdi_functions.c +++ b/drivers/net/ethernet/sfc/mcdi_functions.c @@ -267,20 +267,22 @@ int efx_mcdi_rx_probe(struct efx_rx_queue *rx_queue) void efx_mcdi_rx_init(struct efx_rx_queue *rx_queue) { - MCDI_DECLARE_BUF(inbuf, - MC_CMD_INIT_RXQ_IN_LEN(EFX_MAX_DMAQ_SIZE * 8 / - EFX_BUF_SIZE)); struct efx_channel *channel = efx_rx_queue_channel(rx_queue); size_t entries = rx_queue->rxd.buf.len / EFX_BUF_SIZE; + MCDI_DECLARE_BUF(inbuf, MC_CMD_INIT_RXQ_V4_IN_LEN); struct efx_nic *efx = rx_queue->efx; + unsigned int buffer_size; dma_addr_t dma_addr; - size_t inlen; int rc; int i; BUILD_BUG_ON(MC_CMD_INIT_RXQ_OUT_LEN != 0); rx_queue->scatter_n = 0; rx_queue->scatter_len = 0; + if (efx->type->revision == EFX_REV_EF100) + buffer_size = efx->rx_page_buf_step; + else + buffer_size = 0; MCDI_SET_DWORD(inbuf, INIT_RXQ_IN_SIZE, rx_queue->ptr_mask + 1); MCDI_SET_DWORD(inbuf, INIT_RXQ_IN_TARGET_EVQ, channel->channel); @@ -292,6 +294,7 @@ void efx_mcdi_rx_init(struct efx_rx_queue *rx_queue) INIT_RXQ_IN_FLAG_TIMESTAMP, 1); MCDI_SET_DWORD(inbuf, INIT_RXQ_IN_OWNER_ID, 0); MCDI_SET_DWORD(inbuf, INIT_RXQ_IN_PORT_ID, efx->vport_id); + MCDI_SET_DWORD(inbuf, INIT_RXQ_V4_IN_BUFFER_SIZE_BYTES, buffer_size); dma_addr = rx_queue->rxd.buf.dma_addr; @@ -303,9 +306,7 @@ void efx_mcdi_rx_init(struct efx_rx_queue *rx_queue) dma_addr += EFX_BUF_SIZE; } - inlen = MC_CMD_INIT_RXQ_IN_LEN(entries); - - rc = efx_mcdi_rpc(efx, MC_CMD_INIT_RXQ, inbuf, inlen, + rc = efx_mcdi_rpc(efx, MC_CMD_INIT_RXQ, inbuf, sizeof(inbuf), NULL, 0, NULL); if (rc) netdev_WARN(efx->net_dev, "failed to initialise RXQ %d\n", -- cgit v1.2.3