{
rtl8169_tx_clear_range(tp, tp->dirty_tx, NUM_TX_DESC);
tp->cur_tx = tp->dirty_tx = 0;
+ netdev_reset_queue(tp->dev);
}
static void rtl_reset_work(struct rtl8169_private *tp)
txd->opts2 = cpu_to_le32(opts[1]);
+ netdev_sent_queue(dev, skb->len);
+
wmb();
/* Anti gcc 2.95.3 bugware (sic) */
rtl_schedule_task(tp, RTL_FLAG_TASK_RESET_PENDING);
}
+struct rtl_txc {
+ int packets;
+ int bytes;
+};
+
static void rtl_tx(struct net_device *dev, struct rtl8169_private *tp)
{
+ struct rtl8169_stats *tx_stats = &tp->tx_stats;
unsigned int dirty_tx, tx_left;
+ struct rtl_txc txc = { 0, 0 };
dirty_tx = tp->dirty_tx;
smp_rmb();
rtl8169_unmap_tx_skb(&tp->pci_dev->dev, tx_skb,
tp->TxDescArray + entry);
if (status & LastFrag) {
- u64_stats_update_begin(&tp->tx_stats.syncp);
- tp->tx_stats.packets++;
- tp->tx_stats.bytes += tx_skb->skb->len;
- u64_stats_update_end(&tp->tx_stats.syncp);
- dev_kfree_skb(tx_skb->skb);
+ struct sk_buff *skb = tx_skb->skb;
+
+ txc.packets++;
+ txc.bytes += skb->len;
+ dev_kfree_skb(skb);
tx_skb->skb = NULL;
}
dirty_tx++;
tx_left--;
}
+ u64_stats_update_begin(&tx_stats->syncp);
+ tx_stats->packets += txc.packets;
+ tx_stats->bytes += txc.bytes;
+ u64_stats_update_end(&tx_stats->syncp);
+
+ netdev_completed_queue(dev, txc.packets, txc.bytes);
+
if (tp->dirty_tx != dirty_tx) {
tp->dirty_tx = dirty_tx;
/* Sync with rtl8169_start_xmit: