diff options
-rw-r--r-- | drivers/net/forcedeth.c | 38 |
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) { |