Skip to content

Commit

Permalink
sfc: Really disable flow control while flushing
Browse files Browse the repository at this point in the history
Receiving pause frames can block TX queue flushes.  Earlier changes
work around this by reconfiguring the MAC during flushes for VFs, but
during flushes for the PF we would only change the fc_disable counter.
Unless the MAC is reconfigured for some other reason during the flush
(which I would not expect to happen) this had no effect at all.

Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
  • Loading branch information
Ben Hutchings committed Dec 1, 2012
1 parent 3f978ef commit d5e8cc6
Show file tree
Hide file tree
Showing 6 changed files with 23 additions and 7 deletions.
2 changes: 2 additions & 0 deletions drivers/net/ethernet/sfc/falcon.c
Original file line number Diff line number Diff line change
Expand Up @@ -1792,6 +1792,7 @@ const struct efx_nic_type falcon_a1_nic_type = {
.remove_port = falcon_remove_port,
.handle_global_event = falcon_handle_global_event,
.prepare_flush = falcon_prepare_flush,
.finish_flush = efx_port_dummy_op_void,
.update_stats = falcon_update_nic_stats,
.start_stats = falcon_start_nic_stats,
.stop_stats = falcon_stop_nic_stats,
Expand Down Expand Up @@ -1834,6 +1835,7 @@ const struct efx_nic_type falcon_b0_nic_type = {
.remove_port = falcon_remove_port,
.handle_global_event = falcon_handle_global_event,
.prepare_flush = falcon_prepare_flush,
.finish_flush = efx_port_dummy_op_void,
.update_stats = falcon_update_nic_stats,
.start_stats = falcon_start_nic_stats,
.stop_stats = falcon_stop_nic_stats,
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/sfc/net_driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -907,6 +907,7 @@ static inline unsigned int efx_port_num(struct efx_nic *efx)
* @remove_port: Free resources allocated by probe_port()
* @handle_global_event: Handle a "global" event (may be %NULL)
* @prepare_flush: Prepare the hardware for flushing the DMA queues
* @finish_flush: Clean up after flushing the DMA queues
* @update_stats: Update statistics not provided by event handling
* @start_stats: Start the regular fetching of statistics
* @stop_stats: Stop the regular fetching of statistics
Expand Down Expand Up @@ -954,6 +955,7 @@ struct efx_nic_type {
void (*remove_port)(struct efx_nic *efx);
bool (*handle_global_event)(struct efx_channel *channel, efx_qword_t *);
void (*prepare_flush)(struct efx_nic *efx);
void (*finish_flush)(struct efx_nic *efx);
void (*update_stats)(struct efx_nic *efx);
void (*start_stats)(struct efx_nic *efx);
void (*stop_stats)(struct efx_nic *efx);
Expand Down
3 changes: 1 addition & 2 deletions drivers/net/ethernet/sfc/nic.c
Original file line number Diff line number Diff line change
Expand Up @@ -680,7 +680,6 @@ int efx_nic_flush_queues(struct efx_nic *efx)
struct efx_tx_queue *tx_queue;
int rc = 0;

efx->fc_disable++;
efx->type->prepare_flush(efx);

efx_for_each_channel(channel, efx) {
Expand Down Expand Up @@ -742,7 +741,7 @@ int efx_nic_flush_queues(struct efx_nic *efx)
atomic_set(&efx->rxq_flush_outstanding, 0);
}

efx->fc_disable--;
efx->type->finish_flush(efx);

return rc;
}
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/sfc/nic.h
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,8 @@ static inline int efx_nic_irq_test_irq_cpu(struct efx_nic *efx)

/* Global Resources */
extern int efx_nic_flush_queues(struct efx_nic *efx);
extern void siena_prepare_flush(struct efx_nic *efx);
extern void siena_finish_flush(struct efx_nic *efx);
extern void falcon_start_nic_stats(struct efx_nic *efx);
extern void falcon_stop_nic_stats(struct efx_nic *efx);
extern void falcon_setup_xaui(struct efx_nic *efx);
Expand Down
15 changes: 14 additions & 1 deletion drivers/net/ethernet/sfc/siena.c
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,18 @@ static void siena_remove_port(struct efx_nic *efx)
efx_nic_free_buffer(efx, &efx->stats_buffer);
}

void siena_prepare_flush(struct efx_nic *efx)
{
if (efx->fc_disable++ == 0)
efx_mcdi_set_mac(efx);
}

void siena_finish_flush(struct efx_nic *efx)
{
if (--efx->fc_disable == 0)
efx_mcdi_set_mac(efx);
}

static const struct efx_nic_register_test siena_register_tests[] = {
{ FR_AZ_ADR_REGION,
EFX_OWORD32(0x0003FFFF, 0x0003FFFF, 0x0003FFFF, 0x0003FFFF) },
Expand Down Expand Up @@ -659,7 +671,8 @@ const struct efx_nic_type siena_a0_nic_type = {
.reset = siena_reset_hw,
.probe_port = siena_probe_port,
.remove_port = siena_remove_port,
.prepare_flush = efx_port_dummy_op_void,
.prepare_flush = siena_prepare_flush,
.finish_flush = siena_finish_flush,
.update_stats = siena_update_nic_stats,
.start_stats = siena_start_nic_stats,
.stop_stats = siena_stop_nic_stats,
Expand Down
6 changes: 2 additions & 4 deletions drivers/net/ethernet/sfc/siena_sriov.c
Original file line number Diff line number Diff line change
Expand Up @@ -695,8 +695,7 @@ static int efx_vfdi_fini_all_queues(struct efx_vf *vf)
return VFDI_RC_ENOMEM;

rtnl_lock();
if (efx->fc_disable++ == 0)
efx_mcdi_set_mac(efx);
siena_prepare_flush(efx);
rtnl_unlock();

/* Flush all the initialized queues */
Expand Down Expand Up @@ -733,8 +732,7 @@ static int efx_vfdi_fini_all_queues(struct efx_vf *vf)
}

rtnl_lock();
if (--efx->fc_disable == 0)
efx_mcdi_set_mac(efx);
siena_finish_flush(efx);
rtnl_unlock();

/* Irrespective of success/failure, fini the queues */
Expand Down

0 comments on commit d5e8cc6

Please sign in to comment.