With Au1xx0 Ethernet driver, TX bytes/packets always remain zero. The problem seems to be that when packet has been transmitted, the length word in DMA buffer is zero. Attached is a patch that updates the TX stats when a buffer is fed to DMA. The initial 2.4 patch was posted to linux-mips@xxxxxxxxxxxxxx by Thomas Lange 21 Jan 2005. Signed-off-by: Thomas Lange <thomas@xxxxxxxxxxxx> Signed-off-by: Sergei Shtylyov <sshtylyov@xxxxxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxx> Signed-off-by: Jeff Garzik <jeff@xxxxxxxxxx>
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c index 0418801..b41c522 100644 --- a/drivers/net/au1000_eth.c +++ b/drivers/net/au1000_eth.c @@ -83,8 +83,6 @@ static void au1000_tx_timeout(struct net static int au1000_set_config(struct net_device *dev, struct ifmap *map); static void set_rx_mode(struct net_device *); static struct net_device_stats *au1000_get_stats(struct net_device *); -static inline void update_tx_stats(struct net_device *, u32, u32); -static inline void update_rx_stats(struct net_device *, u32); static void au1000_timer(unsigned long); static int au1000_ioctl(struct net_device *, struct ifreq *, int); static int mdio_read(struct net_device *, int, int); @@ -1540,16 +1538,11 @@ static void __exit au1000_cleanup_module } } - -static inline void -update_tx_stats(struct net_device *dev, u32 status, u32 pkt_len) +static void update_tx_stats(struct net_device *dev, u32 status) { struct au1000_private *aup = (struct au1000_private *) dev->priv; struct net_device_stats *ps = &aup->stats; - ps->tx_packets++; - ps->tx_bytes += pkt_len; - if (status & TX_FRAME_ABORTED) { if (dev->if_port == IF_PORT_100BASEFX) { if (status & (TX_JAB_TIMEOUT | TX_UNDERRUN)) { @@ -1582,7 +1575,7 @@ static void au1000_tx_ack(struct net_dev ptxd = aup->tx_dma_ring[aup->tx_tail]; while (ptxd->buff_stat & TX_T_DONE) { - update_tx_stats(dev, ptxd->status, ptxd->len & 0x3ff); + update_tx_stats(dev, ptxd->status); ptxd->buff_stat &= ~TX_T_DONE; ptxd->len = 0; au_sync(); @@ -1604,6 +1597,7 @@ static void au1000_tx_ack(struct net_dev static int au1000_tx(struct sk_buff *skb, struct net_device *dev) { struct au1000_private *aup = (struct au1000_private *) dev->priv; + struct net_device_stats *ps = &aup->stats; volatile tx_dma_t *ptxd; u32 buff_stat; db_dest_t *pDB; @@ -1623,7 +1617,7 @@ static int au1000_tx(struct sk_buff *skb return 1; } else if (buff_stat & TX_T_DONE) { - update_tx_stats(dev, ptxd->status, ptxd->len & 0x3ff); + update_tx_stats(dev, ptxd->status); ptxd->len = 0; } @@ -1643,6 +1637,9 @@ static int au1000_tx(struct sk_buff *skb else ptxd->len = skb->len; + ps->tx_packets++; + ps->tx_bytes += ptxd->len; + ptxd->buff_stat = pDB->dma_addr | TX_DMA_ENABLE; au_sync(); dev_kfree_skb(skb); @@ -1651,7 +1648,6 @@ static int au1000_tx(struct sk_buff *skb return 0; } - static inline void update_rx_stats(struct net_device *dev, u32 status) { struct au1000_private *aup = (struct au1000_private *) dev->priv;