diff options
author | Jim Lewis <jklewis@us.ibm.com> | 2006-09-22 20:22:53 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-09-22 20:26:02 -0400 |
commit | 9b6b0b81f0de6a17ce57c818d1f403253c200e1f (patch) | |
tree | 51706d05197363768630bdcbd5249c906f9567f9 /drivers/net | |
parent | 78cc3b78c4208d28e7f4ecded82e238224ed4d1c (diff) |
[PATCH] Spidernet: add ethtool -S (show statistics)
Add the ethtool -S (show statistics) feature to the Spidernet ethernet
driver. I have tested it extensively and believe it is ready to be
applied.
Signed-off-by: James K Lewis <jklewis@us.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/spider_net.c | 10 | ||||
-rw-r--r-- | drivers/net/spider_net.h | 11 | ||||
-rw-r--r-- | drivers/net/spider_net_ethtool.c | 55 |
3 files changed, 74 insertions, 2 deletions
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c index d64e718afbd2..cc240adb7269 100644 --- a/drivers/net/spider_net.c +++ b/drivers/net/spider_net.c | |||
@@ -403,6 +403,7 @@ spider_net_prepare_rx_descr(struct spider_net_card *card, | |||
403 | if (!descr->skb) { | 403 | if (!descr->skb) { |
404 | if (netif_msg_rx_err(card) && net_ratelimit()) | 404 | if (netif_msg_rx_err(card) && net_ratelimit()) |
405 | pr_err("Not enough memory to allocate rx buffer\n"); | 405 | pr_err("Not enough memory to allocate rx buffer\n"); |
406 | card->spider_stats.alloc_rx_skb_error++; | ||
406 | return -ENOMEM; | 407 | return -ENOMEM; |
407 | } | 408 | } |
408 | descr->buf_size = bufsize; | 409 | descr->buf_size = bufsize; |
@@ -423,6 +424,7 @@ spider_net_prepare_rx_descr(struct spider_net_card *card, | |||
423 | dev_kfree_skb_any(descr->skb); | 424 | dev_kfree_skb_any(descr->skb); |
424 | if (netif_msg_rx_err(card) && net_ratelimit()) | 425 | if (netif_msg_rx_err(card) && net_ratelimit()) |
425 | pr_err("Could not iommu-map rx buffer\n"); | 426 | pr_err("Could not iommu-map rx buffer\n"); |
427 | card->spider_stats.rx_iommu_map_error++; | ||
426 | descr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; | 428 | descr->dmac_cmd_status = SPIDER_NET_DESCR_NOT_IN_USE; |
427 | } else { | 429 | } else { |
428 | descr->dmac_cmd_status = SPIDER_NET_DESCR_CARDOWNED | | 430 | descr->dmac_cmd_status = SPIDER_NET_DESCR_CARDOWNED | |
@@ -651,6 +653,7 @@ spider_net_prepare_tx_descr(struct spider_net_card *card, | |||
651 | if (netif_msg_tx_err(card) && net_ratelimit()) | 653 | if (netif_msg_tx_err(card) && net_ratelimit()) |
652 | pr_err("could not iommu-map packet (%p, %i). " | 654 | pr_err("could not iommu-map packet (%p, %i). " |
653 | "Dropping packet\n", skb->data, skb->len); | 655 | "Dropping packet\n", skb->data, skb->len); |
656 | card->spider_stats.tx_iommu_map_error++; | ||
654 | return -ENOMEM; | 657 | return -ENOMEM; |
655 | } | 658 | } |
656 | 659 | ||
@@ -818,6 +821,7 @@ spider_net_xmit(struct sk_buff *skb, struct net_device *netdev) | |||
818 | } | 821 | } |
819 | 822 | ||
820 | if (spider_net_get_descr_status(descr) != SPIDER_NET_DESCR_NOT_IN_USE) { | 823 | if (spider_net_get_descr_status(descr) != SPIDER_NET_DESCR_NOT_IN_USE) { |
824 | card->netdev_stats.tx_dropped++; | ||
821 | result = NETDEV_TX_LOCKED; | 825 | result = NETDEV_TX_LOCKED; |
822 | goto out; | 826 | goto out; |
823 | } | 827 | } |
@@ -913,6 +917,7 @@ spider_net_pass_skb_up(struct spider_net_descr *descr, | |||
913 | pr_err("error in received descriptor found, " | 917 | pr_err("error in received descriptor found, " |
914 | "data_status=x%08x, data_error=x%08x\n", | 918 | "data_status=x%08x, data_error=x%08x\n", |
915 | data_status, data_error); | 919 | data_status, data_error); |
920 | card->spider_stats.rx_desc_error++; | ||
916 | return 0; | 921 | return 0; |
917 | } | 922 | } |
918 | 923 | ||
@@ -1010,9 +1015,11 @@ spider_net_decode_one_descr(struct spider_net_card *card, int napi) | |||
1010 | 1015 | ||
1011 | if ( (status != SPIDER_NET_DESCR_COMPLETE) && | 1016 | if ( (status != SPIDER_NET_DESCR_COMPLETE) && |
1012 | (status != SPIDER_NET_DESCR_FRAME_END) ) { | 1017 | (status != SPIDER_NET_DESCR_FRAME_END) ) { |
1013 | if (netif_msg_rx_err(card)) | 1018 | if (netif_msg_rx_err(card)) { |
1014 | pr_err("%s: RX descriptor with state %d\n", | 1019 | pr_err("%s: RX descriptor with state %d\n", |
1015 | card->netdev->name, status); | 1020 | card->netdev->name, status); |
1021 | card->spider_stats.rx_desc_unk_state++; | ||
1022 | } | ||
1016 | goto refill; | 1023 | goto refill; |
1017 | } | 1024 | } |
1018 | 1025 | ||
@@ -1934,6 +1941,7 @@ spider_net_tx_timeout(struct net_device *netdev) | |||
1934 | schedule_work(&card->tx_timeout_task); | 1941 | schedule_work(&card->tx_timeout_task); |
1935 | else | 1942 | else |
1936 | atomic_dec(&card->tx_timeout_task_counter); | 1943 | atomic_dec(&card->tx_timeout_task_counter); |
1944 | card->spider_stats.tx_timeouts++; | ||
1937 | } | 1945 | } |
1938 | 1946 | ||
1939 | /** | 1947 | /** |
diff --git a/drivers/net/spider_net.h b/drivers/net/spider_net.h index 2e80882b345a..a59deda2f95e 100644 --- a/drivers/net/spider_net.h +++ b/drivers/net/spider_net.h | |||
@@ -415,6 +415,15 @@ struct spider_net_options { | |||
415 | NETIF_MSG_HW | \ | 415 | NETIF_MSG_HW | \ |
416 | NETIF_MSG_WOL ) | 416 | NETIF_MSG_WOL ) |
417 | 417 | ||
418 | struct spider_net_extra_stats { | ||
419 | unsigned long rx_desc_error; | ||
420 | unsigned long tx_timeouts; | ||
421 | unsigned long alloc_rx_skb_error; | ||
422 | unsigned long rx_iommu_map_error; | ||
423 | unsigned long tx_iommu_map_error; | ||
424 | unsigned long rx_desc_unk_state; | ||
425 | }; | ||
426 | |||
418 | struct spider_net_card { | 427 | struct spider_net_card { |
419 | struct net_device *netdev; | 428 | struct net_device *netdev; |
420 | struct pci_dev *pdev; | 429 | struct pci_dev *pdev; |
@@ -439,9 +448,9 @@ struct spider_net_card { | |||
439 | 448 | ||
440 | /* for ethtool */ | 449 | /* for ethtool */ |
441 | int msg_enable; | 450 | int msg_enable; |
442 | |||
443 | int rx_desc; | 451 | int rx_desc; |
444 | int tx_desc; | 452 | int tx_desc; |
453 | struct spider_net_extra_stats spider_stats; | ||
445 | 454 | ||
446 | struct spider_net_descr descr[0]; | 455 | struct spider_net_descr descr[0]; |
447 | }; | 456 | }; |
diff --git a/drivers/net/spider_net_ethtool.c b/drivers/net/spider_net_ethtool.c index b0e65d0e0645..589e43658dee 100644 --- a/drivers/net/spider_net_ethtool.c +++ b/drivers/net/spider_net_ethtool.c | |||
@@ -27,6 +27,27 @@ | |||
27 | 27 | ||
28 | #include "spider_net.h" | 28 | #include "spider_net.h" |
29 | 29 | ||
30 | |||
31 | #define SPIDER_NET_NUM_STATS 13 | ||
32 | |||
33 | static struct { | ||
34 | const char str[ETH_GSTRING_LEN]; | ||
35 | } ethtool_stats_keys[] = { | ||
36 | { "tx_packets" }, | ||
37 | { "tx_bytes" }, | ||
38 | { "rx_packets" }, | ||
39 | { "rx_bytes" }, | ||
40 | { "tx_errors" }, | ||
41 | { "tx_dropped" }, | ||
42 | { "rx_dropped" }, | ||
43 | { "rx_descriptor_error" }, | ||
44 | { "tx_timeouts" }, | ||
45 | { "alloc_rx_skb_error" }, | ||
46 | { "rx_iommu_map_error" }, | ||
47 | { "tx_iommu_map_error" }, | ||
48 | { "rx_desc_unk_state" }, | ||
49 | }; | ||
50 | |||
30 | static int | 51 | static int |
31 | spider_net_ethtool_get_settings(struct net_device *netdev, | 52 | spider_net_ethtool_get_settings(struct net_device *netdev, |
32 | struct ethtool_cmd *cmd) | 53 | struct ethtool_cmd *cmd) |
@@ -142,6 +163,37 @@ spider_net_ethtool_get_ringparam(struct net_device *netdev, | |||
142 | ering->rx_pending = card->rx_desc; | 163 | ering->rx_pending = card->rx_desc; |
143 | } | 164 | } |
144 | 165 | ||
166 | static int spider_net_get_stats_count(struct net_device *netdev) | ||
167 | { | ||
168 | return SPIDER_NET_NUM_STATS; | ||
169 | } | ||
170 | |||
171 | static void spider_net_get_ethtool_stats(struct net_device *netdev, | ||
172 | struct ethtool_stats *stats, u64 *data) | ||
173 | { | ||
174 | struct spider_net_card *card = netdev->priv; | ||
175 | |||
176 | data[0] = card->netdev_stats.tx_packets; | ||
177 | data[1] = card->netdev_stats.tx_bytes; | ||
178 | data[2] = card->netdev_stats.rx_packets; | ||
179 | data[3] = card->netdev_stats.rx_bytes; | ||
180 | data[4] = card->netdev_stats.tx_errors; | ||
181 | data[5] = card->netdev_stats.tx_dropped; | ||
182 | data[6] = card->netdev_stats.rx_dropped; | ||
183 | data[7] = card->spider_stats.rx_desc_error; | ||
184 | data[8] = card->spider_stats.tx_timeouts; | ||
185 | data[9] = card->spider_stats.alloc_rx_skb_error; | ||
186 | data[10] = card->spider_stats.rx_iommu_map_error; | ||
187 | data[11] = card->spider_stats.tx_iommu_map_error; | ||
188 | data[12] = card->spider_stats.rx_desc_unk_state; | ||
189 | } | ||
190 | |||
191 | static void spider_net_get_strings(struct net_device *netdev, u32 stringset, | ||
192 | u8 *data) | ||
193 | { | ||
194 | memcpy(data, ethtool_stats_keys, sizeof(ethtool_stats_keys)); | ||
195 | } | ||
196 | |||
145 | const struct ethtool_ops spider_net_ethtool_ops = { | 197 | const struct ethtool_ops spider_net_ethtool_ops = { |
146 | .get_settings = spider_net_ethtool_get_settings, | 198 | .get_settings = spider_net_ethtool_get_settings, |
147 | .get_drvinfo = spider_net_ethtool_get_drvinfo, | 199 | .get_drvinfo = spider_net_ethtool_get_drvinfo, |
@@ -154,5 +206,8 @@ const struct ethtool_ops spider_net_ethtool_ops = { | |||
154 | .get_tx_csum = spider_net_ethtool_get_tx_csum, | 206 | .get_tx_csum = spider_net_ethtool_get_tx_csum, |
155 | .set_tx_csum = spider_net_ethtool_set_tx_csum, | 207 | .set_tx_csum = spider_net_ethtool_set_tx_csum, |
156 | .get_ringparam = spider_net_ethtool_get_ringparam, | 208 | .get_ringparam = spider_net_ethtool_get_ringparam, |
209 | .get_strings = spider_net_get_strings, | ||
210 | .get_stats_count = spider_net_get_stats_count, | ||
211 | .get_ethtool_stats = spider_net_get_ethtool_stats, | ||
157 | }; | 212 | }; |
158 | 213 | ||