diff options
Diffstat (limited to 'drivers/net/sfc/tx.c')
-rw-r--r-- | drivers/net/sfc/tx.c | 13 |
1 files changed, 12 insertions, 1 deletions
diff --git a/drivers/net/sfc/tx.c b/drivers/net/sfc/tx.c index da3e9ff339f5..d6681edb7014 100644 --- a/drivers/net/sfc/tx.c +++ b/drivers/net/sfc/tx.c @@ -162,6 +162,14 @@ static int efx_enqueue_skb(struct efx_tx_queue *tx_queue, /* Get size of the initial fragment */ len = skb_headlen(skb); + /* Pad if necessary */ + if (EFX_WORKAROUND_15592(efx) && skb->len <= 32) { + EFX_BUG_ON_PARANOID(skb->data_len); + len = 32 + 1; + if (skb_pad(skb, len - skb->len)) + return NETDEV_TX_OK; + } + fill_level = tx_queue->insert_count - tx_queue->old_read_count; q_space = efx->type->txd_ring_mask - 1 - fill_level; @@ -376,6 +384,9 @@ int efx_hard_start_xmit(struct sk_buff *skb, struct net_device *net_dev) struct efx_nic *efx = netdev_priv(net_dev); struct efx_tx_queue *tx_queue; + if (unlikely(efx->port_inhibited)) + return NETDEV_TX_BUSY; + if (likely(skb->ip_summed == CHECKSUM_PARTIAL)) tx_queue = &efx->tx_queue[EFX_TX_QUEUE_OFFLOAD_CSUM]; else @@ -397,7 +408,7 @@ void efx_xmit_done(struct efx_tx_queue *tx_queue, unsigned int index) * separates the update of read_count from the test of * stopped. */ smp_mb(); - if (unlikely(tx_queue->stopped)) { + if (unlikely(tx_queue->stopped) && likely(efx->port_enabled)) { fill_level = tx_queue->insert_count - tx_queue->read_count; if (fill_level < EFX_NETDEV_TX_THRESHOLD(tx_queue)) { EFX_BUG_ON_PARANOID(!efx_dev_registered(efx)); |