提交 c2d3d4b9 编写于 作者: S Sergei Shtylylov 提交者: Jeff Garzik

[PATCH] AMD Au1xx0: fix Ethernet TX stats

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.

The patch updates the TX stats when a buffer is fed to DMA.  The initial
2.4 patch was posted to linux-mips@linux-mips.org by Thomas Lange 21 Jan
2005.
Signed-off-by: NThomas Lange <thomas@corelatus.se>
Signed-off-by: NSergei Shtylyov <sshtylyov@ru.mvista.com>
Cc: Jordan Crouse <jordan.crouse@amd.com>
Cc: Jeff Garzik <jgarzik@pobox.com>
Signed-off-by: NAndrew Morton <akpm@osdl.org>
Signed-off-by: NJeff Garzik <jeff@garzik.org>
上级 d9738170
...@@ -90,8 +90,6 @@ static void au1000_tx_timeout(struct net_device *); ...@@ -90,8 +90,6 @@ static void au1000_tx_timeout(struct net_device *);
static int au1000_set_config(struct net_device *dev, struct ifmap *map); static int au1000_set_config(struct net_device *dev, struct ifmap *map);
static void set_rx_mode(struct net_device *); static void set_rx_mode(struct net_device *);
static struct net_device_stats *au1000_get_stats(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 void au1000_timer(unsigned long);
static int au1000_ioctl(struct net_device *, struct ifreq *, int); static int au1000_ioctl(struct net_device *, struct ifreq *, int);
static int mdio_read(struct net_device *, int, int); static int mdio_read(struct net_device *, int, int);
...@@ -1825,16 +1823,11 @@ static void __exit au1000_cleanup_module(void) ...@@ -1825,16 +1823,11 @@ static void __exit au1000_cleanup_module(void)
} }
} }
static void update_tx_stats(struct net_device *dev, u32 status)
static inline void
update_tx_stats(struct net_device *dev, u32 status, u32 pkt_len)
{ {
struct au1000_private *aup = (struct au1000_private *) dev->priv; struct au1000_private *aup = (struct au1000_private *) dev->priv;
struct net_device_stats *ps = &aup->stats; struct net_device_stats *ps = &aup->stats;
ps->tx_packets++;
ps->tx_bytes += pkt_len;
if (status & TX_FRAME_ABORTED) { if (status & TX_FRAME_ABORTED) {
if (dev->if_port == IF_PORT_100BASEFX) { if (dev->if_port == IF_PORT_100BASEFX) {
if (status & (TX_JAB_TIMEOUT | TX_UNDERRUN)) { if (status & (TX_JAB_TIMEOUT | TX_UNDERRUN)) {
...@@ -1867,7 +1860,7 @@ static void au1000_tx_ack(struct net_device *dev) ...@@ -1867,7 +1860,7 @@ static void au1000_tx_ack(struct net_device *dev)
ptxd = aup->tx_dma_ring[aup->tx_tail]; ptxd = aup->tx_dma_ring[aup->tx_tail];
while (ptxd->buff_stat & TX_T_DONE) { 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->buff_stat &= ~TX_T_DONE;
ptxd->len = 0; ptxd->len = 0;
au_sync(); au_sync();
...@@ -1889,6 +1882,7 @@ static void au1000_tx_ack(struct net_device *dev) ...@@ -1889,6 +1882,7 @@ static void au1000_tx_ack(struct net_device *dev)
static int au1000_tx(struct sk_buff *skb, struct net_device *dev) static int au1000_tx(struct sk_buff *skb, struct net_device *dev)
{ {
struct au1000_private *aup = (struct au1000_private *) dev->priv; struct au1000_private *aup = (struct au1000_private *) dev->priv;
struct net_device_stats *ps = &aup->stats;
volatile tx_dma_t *ptxd; volatile tx_dma_t *ptxd;
u32 buff_stat; u32 buff_stat;
db_dest_t *pDB; db_dest_t *pDB;
...@@ -1908,7 +1902,7 @@ static int au1000_tx(struct sk_buff *skb, struct net_device *dev) ...@@ -1908,7 +1902,7 @@ static int au1000_tx(struct sk_buff *skb, struct net_device *dev)
return 1; return 1;
} }
else if (buff_stat & TX_T_DONE) { 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; ptxd->len = 0;
} }
...@@ -1928,6 +1922,9 @@ static int au1000_tx(struct sk_buff *skb, struct net_device *dev) ...@@ -1928,6 +1922,9 @@ static int au1000_tx(struct sk_buff *skb, struct net_device *dev)
else else
ptxd->len = skb->len; ptxd->len = skb->len;
ps->tx_packets++;
ps->tx_bytes += ptxd->len;
ptxd->buff_stat = pDB->dma_addr | TX_DMA_ENABLE; ptxd->buff_stat = pDB->dma_addr | TX_DMA_ENABLE;
au_sync(); au_sync();
dev_kfree_skb(skb); dev_kfree_skb(skb);
...@@ -1936,7 +1933,6 @@ static int au1000_tx(struct sk_buff *skb, struct net_device *dev) ...@@ -1936,7 +1933,6 @@ static int au1000_tx(struct sk_buff *skb, struct net_device *dev)
return 0; return 0;
} }
static inline void update_rx_stats(struct net_device *dev, u32 status) static inline void update_rx_stats(struct net_device *dev, u32 status)
{ {
struct au1000_private *aup = (struct au1000_private *) dev->priv; struct au1000_private *aup = (struct au1000_private *) dev->priv;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册