diff options
author | Jeff Garzik <jeff@garzik.org> | 2006-09-27 18:01:53 -0400 |
---|---|---|
committer | Jeff Garzik <jeff@garzik.org> | 2006-09-27 18:01:53 -0400 |
commit | 022e7a12b6aa11a11de4d708fe8606c9a6734b37 (patch) | |
tree | f4b94bbbe7f585eddcbf06c4bb92903b71a1840f /drivers/net/e1000/e1000_ethtool.c | |
parent | d4b0a4c19ace3021235a33658c520ab0da80dfb1 (diff) | |
parent | 76ddb3fd96a8dada2d09bc3f02b3a5efbc8390c5 (diff) |
Merge branch 'upstream' of git://lost.foo-projects.org/~ahkok/git/netdev-2.6 into tmp
Diffstat (limited to 'drivers/net/e1000/e1000_ethtool.c')
-rw-r--r-- | drivers/net/e1000/e1000_ethtool.c | 150 |
1 files changed, 80 insertions, 70 deletions
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c index e39aa1fc4d1e..778ede3c0216 100644 --- a/drivers/net/e1000/e1000_ethtool.c +++ b/drivers/net/e1000/e1000_ethtool.c | |||
@@ -1,25 +1,24 @@ | |||
1 | /******************************************************************************* | 1 | /******************************************************************************* |
2 | 2 | ||
3 | 3 | Intel PRO/1000 Linux driver | |
4 | Copyright(c) 1999 - 2006 Intel Corporation. All rights reserved. | 4 | Copyright(c) 1999 - 2006 Intel Corporation. |
5 | 5 | ||
6 | This program is free software; you can redistribute it and/or modify it | 6 | This program is free software; you can redistribute it and/or modify it |
7 | under the terms of the GNU General Public License as published by the Free | 7 | under the terms and conditions of the GNU General Public License, |
8 | Software Foundation; either version 2 of the License, or (at your option) | 8 | version 2, as published by the Free Software Foundation. |
9 | any later version. | 9 | |
10 | 10 | This program is distributed in the hope it will be useful, but WITHOUT | |
11 | This program is distributed in the hope that it will be useful, but WITHOUT | 11 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
12 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | 12 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
13 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
14 | more details. | 13 | more details. |
15 | 14 | ||
16 | You should have received a copy of the GNU General Public License along with | 15 | You should have received a copy of the GNU General Public License along with |
17 | this program; if not, write to the Free Software Foundation, Inc., 59 | 16 | this program; if not, write to the Free Software Foundation, Inc., |
18 | Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 17 | 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. |
19 | 18 | ||
20 | The full GNU General Public License is included in this distribution in the | 19 | The full GNU General Public License is included in this distribution in |
21 | file called LICENSE. | 20 | the file called "COPYING". |
22 | 21 | ||
23 | Contact Information: | 22 | Contact Information: |
24 | Linux NICS <linux.nics@intel.com> | 23 | Linux NICS <linux.nics@intel.com> |
25 | e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> | 24 | e1000-devel Mailing List <e1000-devel@lists.sourceforge.net> |
@@ -33,6 +32,21 @@ | |||
33 | 32 | ||
34 | #include <asm/uaccess.h> | 33 | #include <asm/uaccess.h> |
35 | 34 | ||
35 | extern char e1000_driver_name[]; | ||
36 | extern char e1000_driver_version[]; | ||
37 | |||
38 | extern int e1000_up(struct e1000_adapter *adapter); | ||
39 | extern void e1000_down(struct e1000_adapter *adapter); | ||
40 | extern void e1000_reinit_locked(struct e1000_adapter *adapter); | ||
41 | extern void e1000_reset(struct e1000_adapter *adapter); | ||
42 | extern int e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx); | ||
43 | extern int e1000_setup_all_rx_resources(struct e1000_adapter *adapter); | ||
44 | extern int e1000_setup_all_tx_resources(struct e1000_adapter *adapter); | ||
45 | extern void e1000_free_all_rx_resources(struct e1000_adapter *adapter); | ||
46 | extern void e1000_free_all_tx_resources(struct e1000_adapter *adapter); | ||
47 | extern void e1000_update_stats(struct e1000_adapter *adapter); | ||
48 | |||
49 | |||
36 | struct e1000_stats { | 50 | struct e1000_stats { |
37 | char stat_string[ETH_GSTRING_LEN]; | 51 | char stat_string[ETH_GSTRING_LEN]; |
38 | int sizeof_stat; | 52 | int sizeof_stat; |
@@ -42,26 +56,30 @@ struct e1000_stats { | |||
42 | #define E1000_STAT(m) sizeof(((struct e1000_adapter *)0)->m), \ | 56 | #define E1000_STAT(m) sizeof(((struct e1000_adapter *)0)->m), \ |
43 | offsetof(struct e1000_adapter, m) | 57 | offsetof(struct e1000_adapter, m) |
44 | static const struct e1000_stats e1000_gstrings_stats[] = { | 58 | static const struct e1000_stats e1000_gstrings_stats[] = { |
45 | { "rx_packets", E1000_STAT(net_stats.rx_packets) }, | 59 | { "rx_packets", E1000_STAT(stats.gprc) }, |
46 | { "tx_packets", E1000_STAT(net_stats.tx_packets) }, | 60 | { "tx_packets", E1000_STAT(stats.gptc) }, |
47 | { "rx_bytes", E1000_STAT(net_stats.rx_bytes) }, | 61 | { "rx_bytes", E1000_STAT(stats.gorcl) }, |
48 | { "tx_bytes", E1000_STAT(net_stats.tx_bytes) }, | 62 | { "tx_bytes", E1000_STAT(stats.gotcl) }, |
49 | { "rx_errors", E1000_STAT(net_stats.rx_errors) }, | 63 | { "rx_broadcast", E1000_STAT(stats.bprc) }, |
50 | { "tx_errors", E1000_STAT(net_stats.tx_errors) }, | 64 | { "tx_broadcast", E1000_STAT(stats.bptc) }, |
65 | { "rx_multicast", E1000_STAT(stats.mprc) }, | ||
66 | { "tx_multicast", E1000_STAT(stats.mptc) }, | ||
67 | { "rx_errors", E1000_STAT(stats.rxerrc) }, | ||
68 | { "tx_errors", E1000_STAT(stats.txerrc) }, | ||
51 | { "tx_dropped", E1000_STAT(net_stats.tx_dropped) }, | 69 | { "tx_dropped", E1000_STAT(net_stats.tx_dropped) }, |
52 | { "multicast", E1000_STAT(net_stats.multicast) }, | 70 | { "multicast", E1000_STAT(stats.mprc) }, |
53 | { "collisions", E1000_STAT(net_stats.collisions) }, | 71 | { "collisions", E1000_STAT(stats.colc) }, |
54 | { "rx_length_errors", E1000_STAT(net_stats.rx_length_errors) }, | 72 | { "rx_length_errors", E1000_STAT(stats.rlerrc) }, |
55 | { "rx_over_errors", E1000_STAT(net_stats.rx_over_errors) }, | 73 | { "rx_over_errors", E1000_STAT(net_stats.rx_over_errors) }, |
56 | { "rx_crc_errors", E1000_STAT(net_stats.rx_crc_errors) }, | 74 | { "rx_crc_errors", E1000_STAT(stats.crcerrs) }, |
57 | { "rx_frame_errors", E1000_STAT(net_stats.rx_frame_errors) }, | 75 | { "rx_frame_errors", E1000_STAT(net_stats.rx_frame_errors) }, |
58 | { "rx_no_buffer_count", E1000_STAT(stats.rnbc) }, | 76 | { "rx_no_buffer_count", E1000_STAT(stats.rnbc) }, |
59 | { "rx_missed_errors", E1000_STAT(net_stats.rx_missed_errors) }, | 77 | { "rx_missed_errors", E1000_STAT(stats.mpc) }, |
60 | { "tx_aborted_errors", E1000_STAT(net_stats.tx_aborted_errors) }, | 78 | { "tx_aborted_errors", E1000_STAT(stats.ecol) }, |
61 | { "tx_carrier_errors", E1000_STAT(net_stats.tx_carrier_errors) }, | 79 | { "tx_carrier_errors", E1000_STAT(stats.tncrs) }, |
62 | { "tx_fifo_errors", E1000_STAT(net_stats.tx_fifo_errors) }, | 80 | { "tx_fifo_errors", E1000_STAT(net_stats.tx_fifo_errors) }, |
63 | { "tx_heartbeat_errors", E1000_STAT(net_stats.tx_heartbeat_errors) }, | 81 | { "tx_heartbeat_errors", E1000_STAT(net_stats.tx_heartbeat_errors) }, |
64 | { "tx_window_errors", E1000_STAT(net_stats.tx_window_errors) }, | 82 | { "tx_window_errors", E1000_STAT(stats.latecol) }, |
65 | { "tx_abort_late_coll", E1000_STAT(stats.latecol) }, | 83 | { "tx_abort_late_coll", E1000_STAT(stats.latecol) }, |
66 | { "tx_deferred_ok", E1000_STAT(stats.dc) }, | 84 | { "tx_deferred_ok", E1000_STAT(stats.dc) }, |
67 | { "tx_single_coll_ok", E1000_STAT(stats.scc) }, | 85 | { "tx_single_coll_ok", E1000_STAT(stats.scc) }, |
@@ -193,13 +211,9 @@ e1000_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) | |||
193 | ADVERTISED_FIBRE | | 211 | ADVERTISED_FIBRE | |
194 | ADVERTISED_Autoneg; | 212 | ADVERTISED_Autoneg; |
195 | else | 213 | else |
196 | hw->autoneg_advertised = ADVERTISED_10baseT_Half | | 214 | hw->autoneg_advertised = ecmd->advertising | |
197 | ADVERTISED_10baseT_Full | | 215 | ADVERTISED_TP | |
198 | ADVERTISED_100baseT_Half | | 216 | ADVERTISED_Autoneg; |
199 | ADVERTISED_100baseT_Full | | ||
200 | ADVERTISED_1000baseT_Full| | ||
201 | ADVERTISED_Autoneg | | ||
202 | ADVERTISED_TP; | ||
203 | ecmd->advertising = hw->autoneg_advertised; | 217 | ecmd->advertising = hw->autoneg_advertised; |
204 | } else | 218 | } else |
205 | if (e1000_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex)) { | 219 | if (e1000_set_spd_dplx(adapter, ecmd->speed + ecmd->duplex)) { |
@@ -229,11 +243,11 @@ e1000_get_pauseparam(struct net_device *netdev, | |||
229 | pause->autoneg = | 243 | pause->autoneg = |
230 | (adapter->fc_autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE); | 244 | (adapter->fc_autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE); |
231 | 245 | ||
232 | if (hw->fc == e1000_fc_rx_pause) | 246 | if (hw->fc == E1000_FC_RX_PAUSE) |
233 | pause->rx_pause = 1; | 247 | pause->rx_pause = 1; |
234 | else if (hw->fc == e1000_fc_tx_pause) | 248 | else if (hw->fc == E1000_FC_TX_PAUSE) |
235 | pause->tx_pause = 1; | 249 | pause->tx_pause = 1; |
236 | else if (hw->fc == e1000_fc_full) { | 250 | else if (hw->fc == E1000_FC_FULL) { |
237 | pause->rx_pause = 1; | 251 | pause->rx_pause = 1; |
238 | pause->tx_pause = 1; | 252 | pause->tx_pause = 1; |
239 | } | 253 | } |
@@ -253,13 +267,13 @@ e1000_set_pauseparam(struct net_device *netdev, | |||
253 | msleep(1); | 267 | msleep(1); |
254 | 268 | ||
255 | if (pause->rx_pause && pause->tx_pause) | 269 | if (pause->rx_pause && pause->tx_pause) |
256 | hw->fc = e1000_fc_full; | 270 | hw->fc = E1000_FC_FULL; |
257 | else if (pause->rx_pause && !pause->tx_pause) | 271 | else if (pause->rx_pause && !pause->tx_pause) |
258 | hw->fc = e1000_fc_rx_pause; | 272 | hw->fc = E1000_FC_RX_PAUSE; |
259 | else if (!pause->rx_pause && pause->tx_pause) | 273 | else if (!pause->rx_pause && pause->tx_pause) |
260 | hw->fc = e1000_fc_tx_pause; | 274 | hw->fc = E1000_FC_TX_PAUSE; |
261 | else if (!pause->rx_pause && !pause->tx_pause) | 275 | else if (!pause->rx_pause && !pause->tx_pause) |
262 | hw->fc = e1000_fc_none; | 276 | hw->fc = E1000_FC_NONE; |
263 | 277 | ||
264 | hw->original_fc = hw->fc; | 278 | hw->original_fc = hw->fc; |
265 | 279 | ||
@@ -632,8 +646,8 @@ e1000_set_ringparam(struct net_device *netdev, | |||
632 | { | 646 | { |
633 | struct e1000_adapter *adapter = netdev_priv(netdev); | 647 | struct e1000_adapter *adapter = netdev_priv(netdev); |
634 | e1000_mac_type mac_type = adapter->hw.mac_type; | 648 | e1000_mac_type mac_type = adapter->hw.mac_type; |
635 | struct e1000_tx_ring *txdr, *tx_old, *tx_new; | 649 | struct e1000_tx_ring *txdr, *tx_old; |
636 | struct e1000_rx_ring *rxdr, *rx_old, *rx_new; | 650 | struct e1000_rx_ring *rxdr, *rx_old; |
637 | int i, err, tx_ring_size, rx_ring_size; | 651 | int i, err, tx_ring_size, rx_ring_size; |
638 | 652 | ||
639 | if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) | 653 | if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) |
@@ -651,23 +665,17 @@ e1000_set_ringparam(struct net_device *netdev, | |||
651 | tx_old = adapter->tx_ring; | 665 | tx_old = adapter->tx_ring; |
652 | rx_old = adapter->rx_ring; | 666 | rx_old = adapter->rx_ring; |
653 | 667 | ||
654 | adapter->tx_ring = kmalloc(tx_ring_size, GFP_KERNEL); | 668 | err = -ENOMEM; |
655 | if (!adapter->tx_ring) { | 669 | txdr = kzalloc(tx_ring_size, GFP_KERNEL); |
656 | err = -ENOMEM; | 670 | if (!txdr) |
657 | goto err_setup_rx; | 671 | goto err_alloc_tx; |
658 | } | ||
659 | memset(adapter->tx_ring, 0, tx_ring_size); | ||
660 | 672 | ||
661 | adapter->rx_ring = kmalloc(rx_ring_size, GFP_KERNEL); | 673 | rxdr = kzalloc(rx_ring_size, GFP_KERNEL); |
662 | if (!adapter->rx_ring) { | 674 | if (!rxdr) |
663 | kfree(adapter->tx_ring); | 675 | goto err_alloc_rx; |
664 | err = -ENOMEM; | ||
665 | goto err_setup_rx; | ||
666 | } | ||
667 | memset(adapter->rx_ring, 0, rx_ring_size); | ||
668 | 676 | ||
669 | txdr = adapter->tx_ring; | 677 | adapter->tx_ring = txdr; |
670 | rxdr = adapter->rx_ring; | 678 | adapter->rx_ring = rxdr; |
671 | 679 | ||
672 | rxdr->count = max(ring->rx_pending,(uint32_t)E1000_MIN_RXD); | 680 | rxdr->count = max(ring->rx_pending,(uint32_t)E1000_MIN_RXD); |
673 | rxdr->count = min(rxdr->count,(uint32_t)(mac_type < e1000_82544 ? | 681 | rxdr->count = min(rxdr->count,(uint32_t)(mac_type < e1000_82544 ? |
@@ -694,16 +702,14 @@ e1000_set_ringparam(struct net_device *netdev, | |||
694 | /* save the new, restore the old in order to free it, | 702 | /* save the new, restore the old in order to free it, |
695 | * then restore the new back again */ | 703 | * then restore the new back again */ |
696 | 704 | ||
697 | rx_new = adapter->rx_ring; | ||
698 | tx_new = adapter->tx_ring; | ||
699 | adapter->rx_ring = rx_old; | 705 | adapter->rx_ring = rx_old; |
700 | adapter->tx_ring = tx_old; | 706 | adapter->tx_ring = tx_old; |
701 | e1000_free_all_rx_resources(adapter); | 707 | e1000_free_all_rx_resources(adapter); |
702 | e1000_free_all_tx_resources(adapter); | 708 | e1000_free_all_tx_resources(adapter); |
703 | kfree(tx_old); | 709 | kfree(tx_old); |
704 | kfree(rx_old); | 710 | kfree(rx_old); |
705 | adapter->rx_ring = rx_new; | 711 | adapter->rx_ring = rxdr; |
706 | adapter->tx_ring = tx_new; | 712 | adapter->tx_ring = txdr; |
707 | if ((err = e1000_up(adapter))) | 713 | if ((err = e1000_up(adapter))) |
708 | goto err_setup; | 714 | goto err_setup; |
709 | } | 715 | } |
@@ -715,6 +721,10 @@ err_setup_tx: | |||
715 | err_setup_rx: | 721 | err_setup_rx: |
716 | adapter->rx_ring = rx_old; | 722 | adapter->rx_ring = rx_old; |
717 | adapter->tx_ring = tx_old; | 723 | adapter->tx_ring = tx_old; |
724 | kfree(rxdr); | ||
725 | err_alloc_rx: | ||
726 | kfree(txdr); | ||
727 | err_alloc_tx: | ||
718 | e1000_up(adapter); | 728 | e1000_up(adapter); |
719 | err_setup: | 729 | err_setup: |
720 | clear_bit(__E1000_RESETTING, &adapter->flags); | 730 | clear_bit(__E1000_RESETTING, &adapter->flags); |
@@ -1610,7 +1620,7 @@ e1000_diag_test(struct net_device *netdev, | |||
1610 | struct e1000_adapter *adapter = netdev_priv(netdev); | 1620 | struct e1000_adapter *adapter = netdev_priv(netdev); |
1611 | boolean_t if_running = netif_running(netdev); | 1621 | boolean_t if_running = netif_running(netdev); |
1612 | 1622 | ||
1613 | set_bit(__E1000_DRIVER_TESTING, &adapter->flags); | 1623 | set_bit(__E1000_TESTING, &adapter->flags); |
1614 | if (eth_test->flags == ETH_TEST_FL_OFFLINE) { | 1624 | if (eth_test->flags == ETH_TEST_FL_OFFLINE) { |
1615 | /* Offline tests */ | 1625 | /* Offline tests */ |
1616 | 1626 | ||
@@ -1655,7 +1665,7 @@ e1000_diag_test(struct net_device *netdev, | |||
1655 | adapter->hw.autoneg = autoneg; | 1665 | adapter->hw.autoneg = autoneg; |
1656 | 1666 | ||
1657 | e1000_reset(adapter); | 1667 | e1000_reset(adapter); |
1658 | clear_bit(__E1000_DRIVER_TESTING, &adapter->flags); | 1668 | clear_bit(__E1000_TESTING, &adapter->flags); |
1659 | if (if_running) | 1669 | if (if_running) |
1660 | dev_open(netdev); | 1670 | dev_open(netdev); |
1661 | } else { | 1671 | } else { |
@@ -1670,7 +1680,7 @@ e1000_diag_test(struct net_device *netdev, | |||
1670 | data[2] = 0; | 1680 | data[2] = 0; |
1671 | data[3] = 0; | 1681 | data[3] = 0; |
1672 | 1682 | ||
1673 | clear_bit(__E1000_DRIVER_TESTING, &adapter->flags); | 1683 | clear_bit(__E1000_TESTING, &adapter->flags); |
1674 | } | 1684 | } |
1675 | msleep_interruptible(4 * 1000); | 1685 | msleep_interruptible(4 * 1000); |
1676 | } | 1686 | } |