Skip to content

Commit

Permalink
Merge branch 'sfc-prerequisites-for-EF100-driver-part-3'
Browse files Browse the repository at this point in the history
Edward Cree says:

====================
sfc: prerequisites for EF100 driver, part 3

Continuing on from [1] and [2], this series assembles the last pieces
 of the common codebase that will be used by the forthcoming EF100
 driver.
Patch #1 also adds a minor feature to EF10 (setting MTU on VFs) since
 EF10 supports the same MCDI extension which that feature will use on
 EF100.
Patches #5 & #7, while they should have no externally-visible effect
 on driver functionality, change how that functionality is implemented
 and how the driver represents TXQ configuration internally, so are
 not mere cleanup/refactoring like most of these prerequisites have
 (from the perspective of the existing sfc driver) been.

Changes in v2:
* Patch #1: use efx_mcdi_set_mtu() directly, instead of as a fallback,
  in the mtu_only case (Jakub)
* Patch #3: fix symbol collision in non-modular builds by renaming
  interrupt_mode to efx_interrupt_mode (kernel test robot)
* Patch #6: check for failure of netif_set_real_num_[tr]x_queues (Jakub)
* Patch #12: cleaner solution for ethtool drvinfo (Jakub, David)

[1]: https://lore.kernel.org/netdev/[email protected]/T/
[2]: https://lore.kernel.org/netdev/[email protected]/T/
====================

Reviewed-by: Jakub Kicinski <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
davem330 committed Jul 2, 2020
2 parents e44f65f + b6d02dd commit 8c8278a
Show file tree
Hide file tree
Showing 22 changed files with 292 additions and 211 deletions.
76 changes: 16 additions & 60 deletions drivers/net/ethernet/sfc/ef10.c
Original file line number Diff line number Diff line change
Expand Up @@ -552,8 +552,6 @@ static int efx_ef10_probe(struct efx_nic *efx)
}
nic_data->warm_boot_count = rc;

efx->rss_context.context_id = EFX_MCDI_RSS_CONTEXT_INVALID;

/* In case we're recovering from a crash (kexec), we want to
* cancel any outstanding request by the previous user of this
* function. We send a special message using the least
Expand Down Expand Up @@ -600,14 +598,15 @@ static int efx_ef10_probe(struct efx_nic *efx)
* However, until we use TX option descriptors we need two TX queues
* per channel.
*/
efx->tx_queues_per_channel = 2;
efx->max_vis = efx_ef10_mem_map_size(efx) / efx->vi_stride;
if (!efx->max_vis) {
netif_err(efx, drv, efx->net_dev, "error determining max VIs\n");
rc = -EIO;
goto fail5;
}
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;
if (WARN_ON(efx->max_channels == 0)) {
rc = -EIO;
Expand Down Expand Up @@ -1120,17 +1119,17 @@ static int efx_ef10_alloc_vis(struct efx_nic *efx,
*/
static int efx_ef10_dimension_resources(struct efx_nic *efx)
{
unsigned int min_vis = max_t(unsigned int, efx->tx_queues_per_channel,
efx_separate_tx_channels ? 2 : 1);
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;
unsigned int min_vis = max(EFX_TXQ_TYPES,
efx_separate_tx_channels ? 2 : 1);
unsigned int channel_vis, pio_write_vi_base, max_vis;
void __iomem *membase;
int rc;

channel_vis = max(efx->n_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);
if (efx->max_vis && efx->max_vis < channel_vis) {
netif_dbg(efx, drv, efx->net_dev,
Expand Down Expand Up @@ -1219,7 +1218,7 @@ static int efx_ef10_dimension_resources(struct efx_nic *efx)
*/
efx->max_channels = nic_data->n_allocated_vis;
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);
return -EAGAIN;
Expand Down Expand Up @@ -2243,7 +2242,7 @@ static u32 efx_ef10_tso_versions(struct efx_nic *efx)

static void efx_ef10_tx_init(struct efx_tx_queue *tx_queue)
{
bool csum_offload = tx_queue->queue & EFX_TXQ_TYPE_OFFLOAD;
bool csum_offload = tx_queue->label & EFX_TXQ_TYPE_OFFLOAD;
struct efx_channel *channel = tx_queue->channel;
struct efx_nic *efx = tx_queue->efx;
struct efx_ef10_nic_data *nic_data;
Expand Down Expand Up @@ -3116,44 +3115,6 @@ static void efx_ef10_ev_test_generate(struct efx_channel *channel)
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);
Expand Down Expand Up @@ -3306,18 +3267,15 @@ static int efx_ef10_set_mac_address(struct efx_nic *efx)
return rc;
}

static int efx_ef10_mac_reconfigure(struct efx_nic *efx)
static int efx_ef10_mac_reconfigure(struct efx_nic *efx, bool mtu_only)
{
efx_mcdi_filter_sync_rx_mode(efx);
WARN_ON(!mutex_is_locked(&efx->mac_lock));

return efx_mcdi_set_mac(efx);
}

static int efx_ef10_mac_reconfigure_vf(struct efx_nic *efx)
{
efx_mcdi_filter_sync_rx_mode(efx);

return 0;
if (mtu_only && efx_has_cap(efx, SET_MAC_ENHANCED))
return efx_mcdi_set_mtu(efx);
return efx_mcdi_set_mac(efx);
}

static int efx_ef10_start_bist(struct efx_nic *efx, u32 bist_type)
Expand Down Expand Up @@ -4028,7 +3986,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,
Expand All @@ -4038,7 +3996,7 @@ const struct efx_nic_type efx_hunt_a0_vf_nic_type = {
.stop_stats = efx_port_dummy_op_void,
.set_id_led = efx_mcdi_set_id_led,
.push_irq_moderation = efx_ef10_push_irq_moderation,
.reconfigure_mac = efx_ef10_mac_reconfigure_vf,
.reconfigure_mac = efx_ef10_mac_reconfigure,
.check_mac_fault = efx_mcdi_mac_check_fault,
.reconfigure_port = efx_mcdi_port_reconfigure,
.get_wol = efx_ef10_get_wol_vf,
Expand Down Expand Up @@ -4111,7 +4069,6 @@ const struct efx_nic_type efx_hunt_a0_vf_nic_type = {
.can_rx_scatter = true,
.always_rx_scatter = true,
.min_interrupt_mode = EFX_INT_MODE_MSIX,
.max_interrupt_mode = EFX_INT_MODE_MSIX,
.timer_period_max = 1 << ERF_DD_EVQ_IND_TIMER_VAL_WIDTH,
.offload_features = EF10_OFFLOAD_FEATURES,
.mcdi_max_ver = 2,
Expand All @@ -4137,7 +4094,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,
Expand Down Expand Up @@ -4248,7 +4205,6 @@ const struct efx_nic_type efx_hunt_a0_nic_type = {
.always_rx_scatter = true,
.option_descriptors = true,
.min_interrupt_mode = EFX_INT_MODE_LEGACY,
.max_interrupt_mode = EFX_INT_MODE_MSIX,
.timer_period_max = 1 << ERF_DD_EVQ_IND_TIMER_VAL_WIDTH,
.offload_features = EF10_OFFLOAD_FEATURES,
.mcdi_max_ver = 2,
Expand Down
14 changes: 7 additions & 7 deletions drivers/net/ethernet/sfc/efx.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,13 @@ void efx_get_udp_tunnel_type_name(u16 type, char *buf, size_t buflen)
*
*************************************************************************/

module_param_named(interrupt_mode, efx_interrupt_mode, uint, 0444);
MODULE_PARM_DESC(interrupt_mode,
"Interrupt mode (0=>MSIX 1=>MSI 2=>legacy)");

module_param(rss_cpus, uint, 0444);
MODULE_PARM_DESC(rss_cpus, "Number of CPUs to use for Receive-Side Scaling");

/*
* Use separate channels for TX and RX events
*
Expand Down Expand Up @@ -169,10 +176,6 @@ static int efx_init_port(struct efx_nic *efx)

efx->port_initialized = true;

/* Reconfigure the MAC before creating dma queues (required for
* Falcon/A1 where RX_INGR_EN/TX_DRAIN_EN isn't supported) */
efx_mac_reconfigure(efx);

/* Ensure the PHY advertises the correct flow control settings */
rc = efx->phy_op->reconfigure(efx);
if (rc && rc != -EPERM)
Expand Down Expand Up @@ -333,9 +336,6 @@ static int efx_probe_nic(struct efx_nic *efx)
sizeof(efx->rss_context.rx_hash_key));
efx_set_default_rx_indir_table(efx, &efx->rss_context);

netif_set_real_num_tx_queues(efx->net_dev, efx->n_tx_channels);
netif_set_real_num_rx_queues(efx->net_dev, efx->n_rx_channels);

/* Initialise the interrupt moderation settings */
efx->irq_mod_step_us = DIV_ROUND_UP(efx->timer_quantum_ns, 1000);
efx_init_irq_moderation(efx, tx_irq_mod_usec, rx_irq_mod_usec, true,
Expand Down
66 changes: 39 additions & 27 deletions drivers/net/ethernet/sfc/efx_channels.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,7 @@
* 1 => MSI
* 2 => legacy
*/
static unsigned int interrupt_mode;
module_param(interrupt_mode, uint, 0444);
MODULE_PARM_DESC(interrupt_mode,
"Interrupt mode (0=>MSIX 1=>MSI 2=>legacy)");
unsigned int efx_interrupt_mode = EFX_INT_MODE_MSIX;

/* This is the requested number of CPUs to use for Receive-Side Scaling (RSS),
* i.e. the number of CPUs among which we may distribute simultaneous
Expand All @@ -35,9 +32,7 @@ MODULE_PARM_DESC(interrupt_mode,
* Cards without MSI-X will only target one CPU via legacy or MSI interrupt.
* The default (0) means to assign an interrupt to each core.
*/
static unsigned int rss_cpus;
module_param(rss_cpus, uint, 0444);
MODULE_PARM_DESC(rss_cpus, "Number of CPUs to use for Receive-Side Scaling");
unsigned int rss_cpus;

static unsigned int irq_adapt_low_thresh = 8000;
module_param(irq_adapt_low_thresh, uint, 0644);
Expand Down Expand Up @@ -529,7 +524,8 @@ efx_alloc_channel(struct efx_nic *efx, int i, struct efx_channel *old_channel)
for (j = 0; j < EFX_TXQ_TYPES; j++) {
tx_queue = &channel->tx_queue[j];
tx_queue->efx = efx;
tx_queue->queue = i * EFX_TXQ_TYPES + j;
tx_queue->queue = -1;
tx_queue->label = j;
tx_queue->channel = channel;
}

Expand Down Expand Up @@ -557,14 +553,8 @@ int efx_init_channels(struct efx_nic *efx)
}

/* Higher numbered interrupt modes are less capable! */
if (WARN_ON_ONCE(efx->type->max_interrupt_mode >
efx->type->min_interrupt_mode)) {
return -EIO;
}
efx->interrupt_mode = max(efx->type->max_interrupt_mode,
interrupt_mode);
efx->interrupt_mode = min(efx->type->min_interrupt_mode,
interrupt_mode);
efx_interrupt_mode);

efx->max_channels = EFX_MAX_CHANNELS;
efx->max_tx_channels = EFX_MAX_CHANNELS;
Expand Down Expand Up @@ -737,7 +727,7 @@ void efx_remove_channel(struct efx_channel *channel)

efx_for_each_channel_rx_queue(rx_queue, channel)
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_eventq(channel);
channel->type->post_remove(channel);
Expand Down Expand Up @@ -864,9 +854,11 @@ int efx_realloc_channels(struct efx_nic *efx, u32 rxq_entries, u32 txq_entries)

int efx_set_channels(struct efx_nic *efx)
{
struct efx_channel *channel;
struct efx_tx_queue *tx_queue;
struct efx_channel *channel;
unsigned int next_queue = 0;
int xdp_queue_number;
int rc;

efx->tx_channel_offset =
efx_separate_tx_channels ?
Expand Down Expand Up @@ -894,18 +886,38 @@ int efx_set_channels(struct efx_nic *efx)
else
channel->rx_queue.core_index = -1;

efx_for_each_channel_tx_queue(tx_queue, channel) {
tx_queue->queue -= (efx->tx_channel_offset *
EFX_TXQ_TYPES);

if (efx_channel_is_xdp_tx(channel) &&
xdp_queue_number < efx->xdp_tx_queue_count) {
efx->xdp_tx_queues[xdp_queue_number] = tx_queue;
xdp_queue_number++;
if (channel->channel >= efx->tx_channel_offset) {
if (efx_channel_is_xdp_tx(channel)) {
efx_for_each_channel_tx_queue(tx_queue, channel) {
tx_queue->queue = next_queue++;
netif_dbg(efx, drv, efx->net_dev, "Channel %u TXQ %u is XDP %u, HW %u\n",
channel->channel, tx_queue->label,
xdp_queue_number, tx_queue->queue);
/* We may have a few left-over XDP TX
* queues owing to xdp_tx_queue_count
* not dividing evenly by EFX_TXQ_TYPES.
* We still allocate and probe those
* TXQs, but never use them.
*/
if (xdp_queue_number < efx->xdp_tx_queue_count)
efx->xdp_tx_queues[xdp_queue_number] = tx_queue;
xdp_queue_number++;
}
} else {
efx_for_each_channel_tx_queue(tx_queue, channel) {
tx_queue->queue = next_queue++;
netif_dbg(efx, drv, efx->net_dev, "Channel %u TXQ %u is HW %u\n",
channel->channel, tx_queue->label,
tx_queue->queue);
}
}
}
}
return 0;

rc = netif_set_real_num_tx_queues(efx->net_dev, efx->n_tx_channels);
if (rc)
return rc;
return netif_set_real_num_rx_queues(efx->net_dev, efx->n_rx_channels);
}

bool efx_default_channel_want_txqs(struct efx_channel *channel)
Expand Down Expand Up @@ -1101,7 +1113,7 @@ void efx_stop_channels(struct efx_nic *efx)
efx_for_each_channel(channel, efx) {
efx_for_each_channel_rx_queue(rx_queue, channel)
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);
}
}
Expand Down
3 changes: 3 additions & 0 deletions drivers/net/ethernet/sfc/efx_channels.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
#ifndef EFX_CHANNELS_H
#define EFX_CHANNELS_H

extern unsigned int efx_interrupt_mode;
extern unsigned int rss_cpus;

int efx_probe_interrupts(struct efx_nic *efx);
void efx_remove_interrupts(struct efx_nic *efx);
int efx_soft_enable_interrupts(struct efx_nic *efx);
Expand Down
Loading

0 comments on commit 8c8278a

Please sign in to comment.