aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorAyaz Abdulla <aabdulla@nvidia.com>2007-01-23 12:27:21 -0500
committerJeff Garzik <jeff@garzik.org>2007-02-05 16:58:48 -0500
commit21828163b2b31e0675cb3e66a2a4a231dec06236 (patch)
tree33371fd65ddaa334b6233bdf77e61ae5f7580b30 /drivers/net
parent57fff6986b6daae13947c565786757c05303f0f6 (diff)
forcedeth: statistics optimization
This patch optimizes the data paths that can support hw counters. It removes the sw counted statistics. This is the last patch for the optimization set. Bumping up version of driver. Signed-Off-By: Ayaz Abdulla <aabdulla@nvidia.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/forcedeth.c38
1 files changed, 17 insertions, 21 deletions
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 9f6b9d446e98..a363148d0198 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -111,6 +111,7 @@
111 * 0.57: 14 May 2006: Mac address set in probe/remove and order corrections. 111 * 0.57: 14 May 2006: Mac address set in probe/remove and order corrections.
112 * 0.58: 30 Oct 2006: Added support for sideband management unit. 112 * 0.58: 30 Oct 2006: Added support for sideband management unit.
113 * 0.59: 30 Oct 2006: Added support for recoverable error. 113 * 0.59: 30 Oct 2006: Added support for recoverable error.
114 * 0.60: 20 Jan 2007: Code optimizations for rings, rx & tx data paths, and stats.
114 * 115 *
115 * Known bugs: 116 * Known bugs:
116 * We suspect that on some hardware no TX done interrupts are generated. 117 * We suspect that on some hardware no TX done interrupts are generated.
@@ -127,7 +128,7 @@
127#else 128#else
128#define DRIVERNAPI 129#define DRIVERNAPI
129#endif 130#endif
130#define FORCEDETH_VERSION "0.59" 131#define FORCEDETH_VERSION "0.60"
131#define DRV_NAME "forcedeth" 132#define DRV_NAME "forcedeth"
132 133
133#include <linux/module.h> 134#include <linux/module.h>
@@ -1351,10 +1352,19 @@ static struct net_device_stats *nv_get_stats(struct net_device *dev)
1351{ 1352{
1352 struct fe_priv *np = netdev_priv(dev); 1353 struct fe_priv *np = netdev_priv(dev);
1353 1354
1354 /* It seems that the nic always generates interrupts and doesn't 1355 /* If the nic supports hw counters then retrieve latest values */
1355 * accumulate errors internally. Thus the current values in np->stats 1356 if (np->driver_data & (DEV_HAS_STATISTICS_V1|DEV_HAS_STATISTICS_V2)) {
1356 * are already up to date. 1357 nv_get_hw_stats(dev);
1357 */ 1358
1359 /* copy to net_device stats */
1360 np->stats.tx_bytes = np->estats.tx_bytes;
1361 np->stats.tx_fifo_errors = np->estats.tx_fifo_errors;
1362 np->stats.tx_carrier_errors = np->estats.tx_carrier_errors;
1363 np->stats.rx_crc_errors = np->estats.rx_crc_errors;
1364 np->stats.rx_over_errors = np->estats.rx_over_errors;
1365 np->stats.rx_errors = np->estats.rx_errors_total;
1366 np->stats.tx_errors = np->estats.tx_errors_total;
1367 }
1358 return &np->stats; 1368 return &np->stats;
1359} 1369}
1360 1370
@@ -1944,16 +1954,8 @@ static void nv_tx_done_optimized(struct net_device *dev, int limit)
1944 np->get_tx_ctx->dma = 0; 1954 np->get_tx_ctx->dma = 0;
1945 1955
1946 if (flags & NV_TX2_LASTPACKET) { 1956 if (flags & NV_TX2_LASTPACKET) {
1947 if (flags & NV_TX2_ERROR) { 1957 if (!(flags & NV_TX2_ERROR))
1948 if (flags & NV_TX2_UNDERFLOW)
1949 np->stats.tx_fifo_errors++;
1950 if (flags & NV_TX2_CARRIERLOST)
1951 np->stats.tx_carrier_errors++;
1952 np->stats.tx_errors++;
1953 } else {
1954 np->stats.tx_packets++; 1958 np->stats.tx_packets++;
1955 np->stats.tx_bytes += np->get_tx_ctx->skb->len;
1956 }
1957 dev_kfree_skb_any(np->get_tx_ctx->skb); 1959 dev_kfree_skb_any(np->get_tx_ctx->skb);
1958 np->get_tx_ctx->skb = NULL; 1960 np->get_tx_ctx->skb = NULL;
1959 } 1961 }
@@ -2290,7 +2292,6 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit)
2290 if (flags & NV_RX2_ERROR4) { 2292 if (flags & NV_RX2_ERROR4) {
2291 len = nv_getlen(dev, skb->data, len); 2293 len = nv_getlen(dev, skb->data, len);
2292 if (len < 0) { 2294 if (len < 0) {
2293 np->stats.rx_errors++;
2294 dev_kfree_skb(skb); 2295 dev_kfree_skb(skb);
2295 goto next_pkt; 2296 goto next_pkt;
2296 } 2297 }
@@ -2303,11 +2304,6 @@ static int nv_rx_process_optimized(struct net_device *dev, int limit)
2303 } 2304 }
2304 /* the rest are hard errors */ 2305 /* the rest are hard errors */
2305 else { 2306 else {
2306 if (flags & NV_RX2_CRCERR)
2307 np->stats.rx_crc_errors++;
2308 if (flags & NV_RX2_OVERFLOW)
2309 np->stats.rx_over_errors++;
2310 np->stats.rx_errors++;
2311 dev_kfree_skb(skb); 2307 dev_kfree_skb(skb);
2312 goto next_pkt; 2308 goto next_pkt;
2313 } 2309 }
@@ -4941,7 +4937,7 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
4941 np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK; 4937 np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK;
4942 dev->features |= NETIF_F_HW_CSUM | NETIF_F_SG; 4938 dev->features |= NETIF_F_HW_CSUM | NETIF_F_SG;
4943 dev->features |= NETIF_F_TSO; 4939 dev->features |= NETIF_F_TSO;
4944 } 4940 }
4945 4941
4946 np->vlanctl_bits = 0; 4942 np->vlanctl_bits = 0;
4947 if (id->driver_data & DEV_HAS_VLAN) { 4943 if (id->driver_data & DEV_HAS_VLAN) {