diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/ethernet/sfc/mcdi_mac.c | 2 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/net_driver.h | 4 | ||||
-rw-r--r-- | drivers/net/ethernet/sfc/nic.c | 3 |
3 files changed, 9 insertions, 0 deletions
diff --git a/drivers/net/ethernet/sfc/mcdi_mac.c b/drivers/net/ethernet/sfc/mcdi_mac.c index f67cf921bd1..98afe1c1165 100644 --- a/drivers/net/ethernet/sfc/mcdi_mac.c +++ b/drivers/net/ethernet/sfc/mcdi_mac.c @@ -44,6 +44,8 @@ static int efx_mcdi_set_mac(struct efx_nic *efx) } if (efx->wanted_fc & EFX_FC_AUTO) fcntl = MC_CMD_FCNTL_AUTO; + if (efx->fc_disable) + fcntl = MC_CMD_FCNTL_OFF; MCDI_SET_DWORD(cmdbytes, SET_MAC_IN_FCNTL, fcntl); diff --git a/drivers/net/ethernet/sfc/net_driver.h b/drivers/net/ethernet/sfc/net_driver.h index 18c4b3c245e..f5268774150 100644 --- a/drivers/net/ethernet/sfc/net_driver.h +++ b/drivers/net/ethernet/sfc/net_driver.h @@ -670,6 +670,9 @@ struct efx_filter_state; * @promiscuous: Promiscuous flag. Protected by netif_tx_lock. * @multicast_hash: Multicast hash table * @wanted_fc: Wanted flow control flags + * @fc_disable: When non-zero flow control is disabled. Typically used to + * ensure that network back pressure doesn't delay dma queue flushes. + * Serialised by the rtnl lock. * @mac_work: Work item for changing MAC promiscuity and multicast hash * @loopback_mode: Loopback status * @loopback_modes: Supported loopback mode bitmask @@ -769,6 +772,7 @@ struct efx_nic { bool promiscuous; union efx_multicast_hash multicast_hash; u8 wanted_fc; + unsigned fc_disable; atomic_t rx_reset; enum efx_loopback_mode loopback_mode; diff --git a/drivers/net/ethernet/sfc/nic.c b/drivers/net/ethernet/sfc/nic.c index 539b57441e8..1bb41fff3ed 100644 --- a/drivers/net/ethernet/sfc/nic.c +++ b/drivers/net/ethernet/sfc/nic.c @@ -677,6 +677,7 @@ 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) { @@ -727,6 +728,8 @@ int efx_nic_flush_queues(struct efx_nic *efx) atomic_set(&efx->rxq_flush_outstanding, 0); } + efx->fc_disable--; + return rc; } |