Commit f9cac93e authored by Edward Cree's avatar Edward Cree Committed by David S. Miller
Browse files

sfc: make tx_queues_per_channel variable at runtime



Siena needs four TX queues (csum * highpri), EF10 needs two (csum),
 and EF100 only needs one (as checksumming is controlled entirely by
 the transmit descriptor).  Rather than having various bits of ad-hoc
 code to decide which queues to set up etc., put the knowledge of how
 many TXQs a channel has in one place.

Signed-off-by: default avatarEdward Cree <ecree@solarflare.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 67e6398e
Loading
Loading
Loading
Loading
+7 −6
Original line number Original line Diff line number Diff line
@@ -600,6 +600,7 @@ static int efx_ef10_probe(struct efx_nic *efx)
	 * However, until we use TX option descriptors we need two TX queues
	 * However, until we use TX option descriptors we need two TX queues
	 * per channel.
	 * per channel.
	 */
	 */
	efx->tx_queues_per_channel = 2;
	efx->max_vis = efx_ef10_mem_map_size(efx) / efx->vi_stride;
	efx->max_vis = efx_ef10_mem_map_size(efx) / efx->vi_stride;
	if (!efx->max_vis) {
	if (!efx->max_vis) {
		netif_err(efx, drv, efx->net_dev, "error determining max VIs\n");
		netif_err(efx, drv, efx->net_dev, "error determining max VIs\n");
@@ -607,7 +608,7 @@ static int efx_ef10_probe(struct efx_nic *efx)
		goto fail5;
		goto fail5;
	}
	}
	efx->max_channels = min_t(unsigned int, EFX_MAX_CHANNELS,
	efx->max_channels = min_t(unsigned int, EFX_MAX_CHANNELS,
				  efx->max_vis / EFX_TXQ_TYPES);
				  efx->max_vis / efx->tx_queues_per_channel);
	efx->max_tx_channels = efx->max_channels;
	efx->max_tx_channels = efx->max_channels;
	if (WARN_ON(efx->max_channels == 0)) {
	if (WARN_ON(efx->max_channels == 0)) {
		rc = -EIO;
		rc = -EIO;
@@ -1120,17 +1121,17 @@ static int efx_ef10_alloc_vis(struct efx_nic *efx,
 */
 */
static int efx_ef10_dimension_resources(struct efx_nic *efx)
static int efx_ef10_dimension_resources(struct efx_nic *efx)
{
{
	struct efx_ef10_nic_data *nic_data = efx->nic_data;
	unsigned int min_vis = max_t(unsigned int, efx->tx_queues_per_channel,
	unsigned int uc_mem_map_size, wc_mem_map_size;
	unsigned int min_vis = max(EFX_TXQ_TYPES,
				     efx_separate_tx_channels ? 2 : 1);
				     efx_separate_tx_channels ? 2 : 1);
	unsigned int channel_vis, pio_write_vi_base, max_vis;
	unsigned int channel_vis, pio_write_vi_base, max_vis;
	struct efx_ef10_nic_data *nic_data = efx->nic_data;
	unsigned int uc_mem_map_size, wc_mem_map_size;
	void __iomem *membase;
	void __iomem *membase;
	int rc;
	int rc;


	channel_vis = max(efx->n_channels,
	channel_vis = max(efx->n_channels,
			  ((efx->n_tx_channels + efx->n_extra_tx_channels) *
			  ((efx->n_tx_channels + efx->n_extra_tx_channels) *
			   EFX_TXQ_TYPES) +
			   efx->tx_queues_per_channel) +
			   efx->n_xdp_channels * efx->xdp_tx_per_channel);
			   efx->n_xdp_channels * efx->xdp_tx_per_channel);
	if (efx->max_vis && efx->max_vis < channel_vis) {
	if (efx->max_vis && efx->max_vis < channel_vis) {
		netif_dbg(efx, drv, efx->net_dev,
		netif_dbg(efx, drv, efx->net_dev,
@@ -1219,7 +1220,7 @@ static int efx_ef10_dimension_resources(struct efx_nic *efx)
		 */
		 */
		efx->max_channels = nic_data->n_allocated_vis;
		efx->max_channels = nic_data->n_allocated_vis;
		efx->max_tx_channels =
		efx->max_tx_channels =
			nic_data->n_allocated_vis / EFX_TXQ_TYPES;
			nic_data->n_allocated_vis / efx->tx_queues_per_channel;


		efx_mcdi_free_vis(efx);
		efx_mcdi_free_vis(efx);
		return -EAGAIN;
		return -EAGAIN;
+2 −2
Original line number Original line Diff line number Diff line
@@ -726,7 +726,7 @@ void efx_remove_channel(struct efx_channel *channel)


	efx_for_each_channel_rx_queue(rx_queue, channel)
	efx_for_each_channel_rx_queue(rx_queue, channel)
		efx_remove_rx_queue(rx_queue);
		efx_remove_rx_queue(rx_queue);
	efx_for_each_possible_channel_tx_queue(tx_queue, channel)
	efx_for_each_channel_tx_queue(tx_queue, channel)
		efx_remove_tx_queue(tx_queue);
		efx_remove_tx_queue(tx_queue);
	efx_remove_eventq(channel);
	efx_remove_eventq(channel);
	channel->type->post_remove(channel);
	channel->type->post_remove(channel);
@@ -1090,7 +1090,7 @@ void efx_stop_channels(struct efx_nic *efx)
	efx_for_each_channel(channel, efx) {
	efx_for_each_channel(channel, efx) {
		efx_for_each_channel_rx_queue(rx_queue, channel)
		efx_for_each_channel_rx_queue(rx_queue, channel)
			efx_fini_rx_queue(rx_queue);
			efx_fini_rx_queue(rx_queue);
		efx_for_each_possible_channel_tx_queue(tx_queue, channel)
		efx_for_each_channel_tx_queue(tx_queue, channel)
			efx_fini_tx_queue(tx_queue);
			efx_fini_tx_queue(tx_queue);
	}
	}
}
}
+1 −0
Original line number Original line Diff line number Diff line
@@ -1036,6 +1036,7 @@ int efx_init_struct(struct efx_nic *efx,
	INIT_WORK(&efx->mac_work, efx_mac_work);
	INIT_WORK(&efx->mac_work, efx_mac_work);
	init_waitqueue_head(&efx->flush_wq);
	init_waitqueue_head(&efx->flush_wq);


	efx->tx_queues_per_channel = 1;
	efx->rxq_entries = EFX_DEFAULT_DMAQ_SIZE;
	efx->rxq_entries = EFX_DEFAULT_DMAQ_SIZE;
	efx->txq_entries = EFX_DEFAULT_DMAQ_SIZE;
	efx->txq_entries = EFX_DEFAULT_DMAQ_SIZE;


+13 −21
Original line number Original line Diff line number Diff line
@@ -867,6 +867,7 @@ struct efx_async_filter_insertion {
 * @n_rx_channels: Number of channels used for RX (= number of RX queues)
 * @n_rx_channels: Number of channels used for RX (= number of RX queues)
 * @n_tx_channels: Number of channels used for TX
 * @n_tx_channels: Number of channels used for TX
 * @n_extra_tx_channels: Number of extra channels with TX queues
 * @n_extra_tx_channels: Number of extra channels with TX queues
 * @tx_queues_per_channel: number of TX queues probed on each channel
 * @n_xdp_channels: Number of channels used for XDP TX
 * @n_xdp_channels: Number of channels used for XDP TX
 * @xdp_channel_offset: Offset of zeroth channel used for XPD TX.
 * @xdp_channel_offset: Offset of zeroth channel used for XPD TX.
 * @xdp_tx_per_channel: Max number of TX queues on an XDP TX channel.
 * @xdp_tx_per_channel: Max number of TX queues on an XDP TX channel.
@@ -1031,6 +1032,7 @@ struct efx_nic {
	unsigned tx_channel_offset;
	unsigned tx_channel_offset;
	unsigned n_tx_channels;
	unsigned n_tx_channels;
	unsigned n_extra_tx_channels;
	unsigned n_extra_tx_channels;
	unsigned int tx_queues_per_channel;
	unsigned int n_xdp_channels;
	unsigned int n_xdp_channels;
	unsigned int xdp_channel_offset;
	unsigned int xdp_channel_offset;
	unsigned int xdp_tx_per_channel;
	unsigned int xdp_tx_per_channel;
@@ -1529,7 +1531,7 @@ static inline struct efx_tx_queue *
efx_get_tx_queue(struct efx_nic *efx, unsigned index, unsigned type)
efx_get_tx_queue(struct efx_nic *efx, unsigned index, unsigned type)
{
{
	EFX_WARN_ON_ONCE_PARANOID(index >= efx->n_tx_channels ||
	EFX_WARN_ON_ONCE_PARANOID(index >= efx->n_tx_channels ||
				  type >= EFX_TXQ_TYPES);
				  type >= efx->tx_queues_per_channel);
	return &efx->channel[efx->tx_channel_offset + index]->tx_queue[type];
	return &efx->channel[efx->tx_channel_offset + index]->tx_queue[type];
}
}


@@ -1551,18 +1553,18 @@ static inline bool efx_channel_has_tx_queues(struct efx_channel *channel)
	return true;
	return true;
}
}


static inline struct efx_tx_queue *
static inline unsigned int efx_channel_num_tx_queues(struct efx_channel *channel)
efx_channel_get_tx_queue(struct efx_channel *channel, unsigned type)
{
{
	EFX_WARN_ON_ONCE_PARANOID(!efx_channel_has_tx_queues(channel) ||
	if (efx_channel_is_xdp_tx(channel))
				  type >= EFX_TXQ_TYPES);
		return channel->efx->xdp_tx_per_channel;
	return &channel->tx_queue[type];
	return channel->efx->tx_queues_per_channel;
}
}


static inline bool efx_tx_queue_used(struct efx_tx_queue *tx_queue)
static inline struct efx_tx_queue *
efx_channel_get_tx_queue(struct efx_channel *channel, unsigned type)
{
{
	return !(tx_queue->efx->net_dev->num_tc < 2 &&
	EFX_WARN_ON_ONCE_PARANOID(type >= efx_channel_num_tx_queues(channel));
		 tx_queue->queue & EFX_TXQ_TYPE_HIGHPRI);
	return &channel->tx_queue[type];
}
}


/* Iterate over all TX queues belonging to a channel */
/* Iterate over all TX queues belonging to a channel */
@@ -1571,18 +1573,8 @@ static inline bool efx_tx_queue_used(struct efx_tx_queue *tx_queue)
		;							\
		;							\
	else								\
	else								\
		for (_tx_queue = (_channel)->tx_queue;			\
		for (_tx_queue = (_channel)->tx_queue;			\
		     _tx_queue < (_channel)->tx_queue + EFX_TXQ_TYPES && \
		     _tx_queue < (_channel)->tx_queue +			\
			     (efx_tx_queue_used(_tx_queue) ||            \
				 efx_channel_num_tx_queues(_channel);		\
			      efx_channel_is_xdp_tx(_channel));		\
		     _tx_queue++)

/* Iterate over all possible TX queues belonging to a channel */
#define efx_for_each_possible_channel_tx_queue(_tx_queue, _channel)	\
	if (!efx_channel_has_tx_queues(_channel))			\
		;							\
	else								\
		for (_tx_queue = (_channel)->tx_queue;			\
		     _tx_queue < (_channel)->tx_queue + EFX_TXQ_TYPES;	\
		     _tx_queue++)
		     _tx_queue++)


static inline bool efx_channel_has_rx_queue(struct efx_channel *channel)
static inline bool efx_channel_has_rx_queue(struct efx_channel *channel)
+1 −0
Original line number Original line Diff line number Diff line
@@ -279,6 +279,7 @@ static int siena_probe_nic(struct efx_nic *efx)
	efx->max_channels = EFX_MAX_CHANNELS;
	efx->max_channels = EFX_MAX_CHANNELS;
	efx->max_vis = EFX_MAX_CHANNELS;
	efx->max_vis = EFX_MAX_CHANNELS;
	efx->max_tx_channels = EFX_MAX_CHANNELS;
	efx->max_tx_channels = EFX_MAX_CHANNELS;
	efx->tx_queues_per_channel = 2;


	efx_reado(efx, &reg, FR_AZ_CS_DEBUG);
	efx_reado(efx, &reg, FR_AZ_CS_DEBUG);
	efx->port_num = EFX_OWORD_FIELD(reg, FRF_CZ_CS_PORT_NUM) - 1;
	efx->port_num = EFX_OWORD_FIELD(reg, FRF_CZ_CS_PORT_NUM) - 1;
Loading