diff options
author | Sandeep Gopalpet <sandeep.kumar@freescale.com> | 2009-12-15 20:15:07 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2009-12-18 23:38:37 -0500 |
commit | a7f38041b8c38d0721b042c123bd5d6bd2d21feb (patch) | |
tree | 375dc0df2bf89ac9502972b986018dd16fa9dad6 /drivers/net | |
parent | 1ccb8389f26f2d513b06abe45d8e0b8f32458302 (diff) |
gianfar: Fix stats support
This patch updates the per rx/tx queue stats.
To update the per rx queue stats a new structure has been
introduced rx_q_stats.
The per tx queue stats are updated via the netdev_queue
structure itself.
Note that we update only the tx_packtes, tx_bytes, rx_packets,
rx_bytes and rx_dropped stats on a per queue basis.
Signed-off-by: Sandeep Gopalpet <Sandeep.Kumar@freescale.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/gianfar.c | 42 | ||||
-rw-r--r-- | drivers/net/gianfar.h | 10 |
2 files changed, 46 insertions, 6 deletions
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 1616531a71f7..e0620d084644 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c | |||
@@ -417,6 +417,36 @@ static void gfar_init_mac(struct net_device *ndev) | |||
417 | gfar_write(®s->fifo_tx_starve_shutoff, priv->fifo_starve_off); | 417 | gfar_write(®s->fifo_tx_starve_shutoff, priv->fifo_starve_off); |
418 | } | 418 | } |
419 | 419 | ||
420 | static struct net_device_stats *gfar_get_stats(struct net_device *dev) | ||
421 | { | ||
422 | struct gfar_private *priv = netdev_priv(dev); | ||
423 | struct netdev_queue *txq; | ||
424 | unsigned long rx_packets = 0, rx_bytes = 0, rx_dropped = 0; | ||
425 | unsigned long tx_packets = 0, tx_bytes = 0; | ||
426 | int i = 0; | ||
427 | |||
428 | for (i = 0; i < priv->num_rx_queues; i++) { | ||
429 | rx_packets += priv->rx_queue[i]->stats.rx_packets; | ||
430 | rx_bytes += priv->rx_queue[i]->stats.rx_bytes; | ||
431 | rx_dropped += priv->rx_queue[i]->stats.rx_dropped; | ||
432 | } | ||
433 | |||
434 | dev->stats.rx_packets = rx_packets; | ||
435 | dev->stats.rx_bytes = rx_bytes; | ||
436 | dev->stats.rx_dropped = rx_dropped; | ||
437 | |||
438 | for (i = 0; i < priv->num_tx_queues; i++) { | ||
439 | txq = netdev_get_tx_queue(dev, i); | ||
440 | tx_bytes += txq->tx_bytes; | ||
441 | tx_packets += txq->tx_packets; | ||
442 | } | ||
443 | |||
444 | dev->stats.tx_bytes = tx_bytes; | ||
445 | dev->stats.tx_packets = tx_packets; | ||
446 | |||
447 | return &dev->stats; | ||
448 | } | ||
449 | |||
420 | static const struct net_device_ops gfar_netdev_ops = { | 450 | static const struct net_device_ops gfar_netdev_ops = { |
421 | .ndo_open = gfar_enet_open, | 451 | .ndo_open = gfar_enet_open, |
422 | .ndo_start_xmit = gfar_start_xmit, | 452 | .ndo_start_xmit = gfar_start_xmit, |
@@ -426,6 +456,7 @@ static const struct net_device_ops gfar_netdev_ops = { | |||
426 | .ndo_tx_timeout = gfar_timeout, | 456 | .ndo_tx_timeout = gfar_timeout, |
427 | .ndo_do_ioctl = gfar_ioctl, | 457 | .ndo_do_ioctl = gfar_ioctl, |
428 | .ndo_select_queue = gfar_select_queue, | 458 | .ndo_select_queue = gfar_select_queue, |
459 | .ndo_get_stats = gfar_get_stats, | ||
429 | .ndo_vlan_rx_register = gfar_vlan_rx_register, | 460 | .ndo_vlan_rx_register = gfar_vlan_rx_register, |
430 | .ndo_set_mac_address = eth_mac_addr, | 461 | .ndo_set_mac_address = eth_mac_addr, |
431 | .ndo_validate_addr = eth_validate_addr, | 462 | .ndo_validate_addr = eth_validate_addr, |
@@ -1943,7 +1974,8 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev) | |||
1943 | } | 1974 | } |
1944 | 1975 | ||
1945 | /* Update transmit stats */ | 1976 | /* Update transmit stats */ |
1946 | dev->stats.tx_bytes += skb->len; | 1977 | txq->tx_bytes += skb->len; |
1978 | txq->tx_packets ++; | ||
1947 | 1979 | ||
1948 | txbdp = txbdp_start = tx_queue->cur_tx; | 1980 | txbdp = txbdp_start = tx_queue->cur_tx; |
1949 | 1981 | ||
@@ -2301,8 +2333,6 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue) | |||
2301 | tx_queue->skb_dirtytx = skb_dirtytx; | 2333 | tx_queue->skb_dirtytx = skb_dirtytx; |
2302 | tx_queue->dirty_tx = bdp; | 2334 | tx_queue->dirty_tx = bdp; |
2303 | 2335 | ||
2304 | dev->stats.tx_packets += howmany; | ||
2305 | |||
2306 | return howmany; | 2336 | return howmany; |
2307 | } | 2337 | } |
2308 | 2338 | ||
@@ -2516,14 +2546,14 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit) | |||
2516 | } | 2546 | } |
2517 | } else { | 2547 | } else { |
2518 | /* Increment the number of packets */ | 2548 | /* Increment the number of packets */ |
2519 | dev->stats.rx_packets++; | 2549 | rx_queue->stats.rx_packets++; |
2520 | howmany++; | 2550 | howmany++; |
2521 | 2551 | ||
2522 | if (likely(skb)) { | 2552 | if (likely(skb)) { |
2523 | pkt_len = bdp->length - ETH_FCS_LEN; | 2553 | pkt_len = bdp->length - ETH_FCS_LEN; |
2524 | /* Remove the FCS from the packet length */ | 2554 | /* Remove the FCS from the packet length */ |
2525 | skb_put(skb, pkt_len); | 2555 | skb_put(skb, pkt_len); |
2526 | dev->stats.rx_bytes += pkt_len; | 2556 | rx_queue->stats.rx_bytes += pkt_len; |
2527 | 2557 | ||
2528 | gfar_process_frame(dev, skb, amount_pull); | 2558 | gfar_process_frame(dev, skb, amount_pull); |
2529 | 2559 | ||
@@ -2531,7 +2561,7 @@ int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit) | |||
2531 | if (netif_msg_rx_err(priv)) | 2561 | if (netif_msg_rx_err(priv)) |
2532 | printk(KERN_WARNING | 2562 | printk(KERN_WARNING |
2533 | "%s: Missing skb!\n", dev->name); | 2563 | "%s: Missing skb!\n", dev->name); |
2534 | dev->stats.rx_dropped++; | 2564 | rx_queue->stats.rx_dropped++; |
2535 | priv->extra_stats.rx_skbmissing++; | 2565 | priv->extra_stats.rx_skbmissing++; |
2536 | } | 2566 | } |
2537 | 2567 | ||
diff --git a/drivers/net/gianfar.h b/drivers/net/gianfar.h index 68d16dc6e7c8..4943cbe642ab 100644 --- a/drivers/net/gianfar.h +++ b/drivers/net/gianfar.h | |||
@@ -940,6 +940,15 @@ struct gfar_priv_tx_q { | |||
940 | unsigned short txtime; | 940 | unsigned short txtime; |
941 | }; | 941 | }; |
942 | 942 | ||
943 | /* | ||
944 | * Per RX queue stats | ||
945 | */ | ||
946 | struct rx_q_stats { | ||
947 | unsigned long rx_packets; | ||
948 | unsigned long rx_bytes; | ||
949 | unsigned long rx_dropped; | ||
950 | }; | ||
951 | |||
943 | /** | 952 | /** |
944 | * struct gfar_priv_rx_q - per rx queue structure | 953 | * struct gfar_priv_rx_q - per rx queue structure |
945 | * @rxlock: per queue rx spin lock | 954 | * @rxlock: per queue rx spin lock |
@@ -962,6 +971,7 @@ struct gfar_priv_rx_q { | |||
962 | struct rxbd8 *cur_rx; | 971 | struct rxbd8 *cur_rx; |
963 | struct net_device *dev; | 972 | struct net_device *dev; |
964 | struct gfar_priv_grp *grp; | 973 | struct gfar_priv_grp *grp; |
974 | struct rx_q_stats stats; | ||
965 | u16 skb_currx; | 975 | u16 skb_currx; |
966 | u16 qindex; | 976 | u16 qindex; |
967 | unsigned int rx_ring_size; | 977 | unsigned int rx_ring_size; |