diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c index 95bc3839173c1..6434129dedf06 100644 --- a/drivers/net/ethernet/cadence/macb_main.c +++ b/drivers/net/ethernet/cadence/macb_main.c @@ -1357,10 +1357,8 @@ static void macb_tx_error_task(struct work_struct *work) skb->data); bp->dev->stats.tx_packets++; queue->stats.tx_packets++; - packets++; bp->dev->stats.tx_bytes += skb->len; queue->stats.tx_bytes += skb->len; - bytes += skb->len; } } else { /* "Buffers exhausted mid-frame" errors may only happen @@ -1374,6 +1372,12 @@ static void macb_tx_error_task(struct work_struct *work) desc->ctrl = ctrl | MACB_BIT(TX_USED); } + /* BQL has to see every frame leaving the ring, sent or not */ + if (skb) { + packets++; + bytes += skb->len; + } + macb_tx_unmap(bp, tx_skb, 0); } @@ -4699,8 +4703,20 @@ static int macb_setup_tc(struct net_device *dev, enum tc_setup_type type, static void macb_tx_timeout(struct net_device *dev, unsigned int q) { struct macb *bp = netdev_priv(dev); + struct macb_queue *queue = &bp->queues[q]; - macb_tx_restart(&bp->queues[q]); + macb_tx_restart(queue); + + /* The frames may have gone out with their TCOMP interrupt lost. + * macb_tx_restart() does nothing then as TBQP already matches + * tx_head, so reap them from NAPI or the queue stays stopped. + */ + if (macb_tx_complete_pending(queue)) { + queue_writel(queue, IDR, MACB_BIT(TCOMP)); + if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) + queue_writel(queue, ISR, MACB_BIT(TCOMP)); + napi_schedule(&queue->napi_tx); + } } static const struct net_device_ops macb_netdev_ops = {