Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

sis190: account for Tx errors

Update the collision counter as well.

Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>

+35 -3
+35 -3
drivers/net/sis190.c
··· 212 212 THOL2 = 0x20000000, 213 213 THOL1 = 0x10000000, 214 214 THOL0 = 0x00000000, 215 + 216 + WND = 0x00080000, 217 + TABRT = 0x00040000, 218 + FIFO = 0x00020000, 219 + LINK = 0x00010000, 220 + ColCountMask = 0x0000ffff, 215 221 /* RxDesc.status */ 216 222 IPON = 0x20000000, 217 223 TCPON = 0x10000000, ··· 659 653 memset(desc, 0x00, sizeof(*desc)); 660 654 } 661 655 656 + static inline int sis190_tx_pkt_err(u32 status, struct net_device_stats *stats) 657 + { 658 + #define TxErrMask (WND | TABRT | FIFO | LINK) 659 + 660 + if (!unlikely(status & TxErrMask)) 661 + return 0; 662 + 663 + if (status & WND) 664 + stats->tx_window_errors++; 665 + if (status & TABRT) 666 + stats->tx_aborted_errors++; 667 + if (status & FIFO) 668 + stats->tx_fifo_errors++; 669 + if (status & LINK) 670 + stats->tx_carrier_errors++; 671 + 672 + stats->tx_errors++; 673 + 674 + return -1; 675 + } 676 + 662 677 static void sis190_tx_interrupt(struct net_device *dev, 663 678 struct sis190_private *tp, void __iomem *ioaddr) 664 679 { 680 + struct net_device_stats *stats = &dev->stats; 665 681 u32 pending, dirty_tx = tp->dirty_tx; 666 682 /* 667 683 * It would not be needed if queueing was allowed to be enabled ··· 698 670 for (; pending; pending--, dirty_tx++) { 699 671 unsigned int entry = dirty_tx % NUM_TX_DESC; 700 672 struct TxDesc *txd = tp->TxDescRing + entry; 673 + u32 status = le32_to_cpu(txd->status); 701 674 struct sk_buff *skb; 702 675 703 - if (le32_to_cpu(txd->status) & OWNbit) 676 + if (status & OWNbit) 704 677 break; 705 678 706 679 skb = tp->Tx_skbuff[entry]; 707 680 708 - dev->stats.tx_packets++; 709 - dev->stats.tx_bytes += skb->len; 681 + if (likely(sis190_tx_pkt_err(status, stats) == 0)) { 682 + stats->tx_packets++; 683 + stats->tx_bytes += skb->len; 684 + stats->collisions += ((status & ColCountMask) - 1); 685 + } 710 686 711 687 sis190_unmap_tx_skb(tp->pci_dev, skb, txd); 712 688 tp->Tx_skbuff[entry] = NULL;