11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*******************************************************************************
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
30abb6eb12806cf99ea815810d470423083c3b9f4Auke Kok  Intel PRO/10GbE Linux driver
4f731a9ef82c6728559b34743bca19d231e5e1b63Jesse Brandeburg  Copyright(c) 1999 - 2008 Intel Corporation.
50abb6eb12806cf99ea815810d470423083c3b9f4Auke Kok
60abb6eb12806cf99ea815810d470423083c3b9f4Auke Kok  This program is free software; you can redistribute it and/or modify it
70abb6eb12806cf99ea815810d470423083c3b9f4Auke Kok  under the terms and conditions of the GNU General Public License,
80abb6eb12806cf99ea815810d470423083c3b9f4Auke Kok  version 2, as published by the Free Software Foundation.
90abb6eb12806cf99ea815810d470423083c3b9f4Auke Kok
100abb6eb12806cf99ea815810d470423083c3b9f4Auke Kok  This program is distributed in the hope it will be useful, but WITHOUT
110abb6eb12806cf99ea815810d470423083c3b9f4Auke Kok  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
120abb6eb12806cf99ea815810d470423083c3b9f4Auke Kok  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  more details.
140abb6eb12806cf99ea815810d470423083c3b9f4Auke Kok
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  You should have received a copy of the GNU General Public License along with
160abb6eb12806cf99ea815810d470423083c3b9f4Auke Kok  this program; if not, write to the Free Software Foundation, Inc.,
170abb6eb12806cf99ea815810d470423083c3b9f4Auke Kok  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
180abb6eb12806cf99ea815810d470423083c3b9f4Auke Kok
190abb6eb12806cf99ea815810d470423083c3b9f4Auke Kok  The full GNU General Public License is included in this distribution in
200abb6eb12806cf99ea815810d470423083c3b9f4Auke Kok  the file called "COPYING".
210abb6eb12806cf99ea815810d470423083c3b9f4Auke Kok
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  Contact Information:
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  Linux NICS <linux.nics@intel.com>
240abb6eb12806cf99ea815810d470423083c3b9f4Auke Kok  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds*******************************************************************************/
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* ethtool support for ixgb */
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "ixgb.h"
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/uaccess.h>
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
35c85fd6f0dedcec411438768bb5ebd133b1ae3347Auke Kok#define IXGB_ALL_RAR_ENTRIES 16
36c85fd6f0dedcec411438768bb5ebd133b1ae3347Auke Kok
37d189a7e85835dbfb22b1d04eb7f3ab575ccacb96Ajit Khapardeenum {NETDEV_STATS, IXGB_STATS};
38d189a7e85835dbfb22b1d04eb7f3ab575ccacb96Ajit Khaparde
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct ixgb_stats {
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char stat_string[ETH_GSTRING_LEN];
41d189a7e85835dbfb22b1d04eb7f3ab575ccacb96Ajit Khaparde	int type;
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int sizeof_stat;
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int stat_offset;
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
46d189a7e85835dbfb22b1d04eb7f3ab575ccacb96Ajit Khaparde#define IXGB_STAT(m)		IXGB_STATS, \
47d189a7e85835dbfb22b1d04eb7f3ab575ccacb96Ajit Khaparde				FIELD_SIZEOF(struct ixgb_adapter, m), \
48d189a7e85835dbfb22b1d04eb7f3ab575ccacb96Ajit Khaparde				offsetof(struct ixgb_adapter, m)
49d189a7e85835dbfb22b1d04eb7f3ab575ccacb96Ajit Khaparde#define IXGB_NETDEV_STAT(m)	NETDEV_STATS, \
50d189a7e85835dbfb22b1d04eb7f3ab575ccacb96Ajit Khaparde				FIELD_SIZEOF(struct net_device, m), \
51d189a7e85835dbfb22b1d04eb7f3ab575ccacb96Ajit Khaparde				offsetof(struct net_device, m)
52d189a7e85835dbfb22b1d04eb7f3ab575ccacb96Ajit Khaparde
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct ixgb_stats ixgb_gstrings_stats[] = {
540cdc03698f2586923ad3b9fca06643ff5675f221Ajit Khaparde	{"rx_packets", IXGB_NETDEV_STAT(stats.rx_packets)},
550cdc03698f2586923ad3b9fca06643ff5675f221Ajit Khaparde	{"tx_packets", IXGB_NETDEV_STAT(stats.tx_packets)},
560cdc03698f2586923ad3b9fca06643ff5675f221Ajit Khaparde	{"rx_bytes", IXGB_NETDEV_STAT(stats.rx_bytes)},
570cdc03698f2586923ad3b9fca06643ff5675f221Ajit Khaparde	{"tx_bytes", IXGB_NETDEV_STAT(stats.tx_bytes)},
580cdc03698f2586923ad3b9fca06643ff5675f221Ajit Khaparde	{"rx_errors", IXGB_NETDEV_STAT(stats.rx_errors)},
590cdc03698f2586923ad3b9fca06643ff5675f221Ajit Khaparde	{"tx_errors", IXGB_NETDEV_STAT(stats.tx_errors)},
600cdc03698f2586923ad3b9fca06643ff5675f221Ajit Khaparde	{"rx_dropped", IXGB_NETDEV_STAT(stats.rx_dropped)},
610cdc03698f2586923ad3b9fca06643ff5675f221Ajit Khaparde	{"tx_dropped", IXGB_NETDEV_STAT(stats.tx_dropped)},
620cdc03698f2586923ad3b9fca06643ff5675f221Ajit Khaparde	{"multicast", IXGB_NETDEV_STAT(stats.multicast)},
630cdc03698f2586923ad3b9fca06643ff5675f221Ajit Khaparde	{"collisions", IXGB_NETDEV_STAT(stats.collisions)},
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
650cdc03698f2586923ad3b9fca06643ff5675f221Ajit Khaparde/*	{ "rx_length_errors", IXGB_NETDEV_STAT(stats.rx_length_errors) },	*/
660cdc03698f2586923ad3b9fca06643ff5675f221Ajit Khaparde	{"rx_over_errors", IXGB_NETDEV_STAT(stats.rx_over_errors)},
670cdc03698f2586923ad3b9fca06643ff5675f221Ajit Khaparde	{"rx_crc_errors", IXGB_NETDEV_STAT(stats.rx_crc_errors)},
680cdc03698f2586923ad3b9fca06643ff5675f221Ajit Khaparde	{"rx_frame_errors", IXGB_NETDEV_STAT(stats.rx_frame_errors)},
69ac0b3509f048b34ba1b60f164fd811b7cbdbc27aAuke Kok	{"rx_no_buffer_count", IXGB_STAT(stats.rnbc)},
700cdc03698f2586923ad3b9fca06643ff5675f221Ajit Khaparde	{"rx_fifo_errors", IXGB_NETDEV_STAT(stats.rx_fifo_errors)},
710cdc03698f2586923ad3b9fca06643ff5675f221Ajit Khaparde	{"rx_missed_errors", IXGB_NETDEV_STAT(stats.rx_missed_errors)},
720cdc03698f2586923ad3b9fca06643ff5675f221Ajit Khaparde	{"tx_aborted_errors", IXGB_NETDEV_STAT(stats.tx_aborted_errors)},
730cdc03698f2586923ad3b9fca06643ff5675f221Ajit Khaparde	{"tx_carrier_errors", IXGB_NETDEV_STAT(stats.tx_carrier_errors)},
740cdc03698f2586923ad3b9fca06643ff5675f221Ajit Khaparde	{"tx_fifo_errors", IXGB_NETDEV_STAT(stats.tx_fifo_errors)},
750cdc03698f2586923ad3b9fca06643ff5675f221Ajit Khaparde	{"tx_heartbeat_errors", IXGB_NETDEV_STAT(stats.tx_heartbeat_errors)},
760cdc03698f2586923ad3b9fca06643ff5675f221Ajit Khaparde	{"tx_window_errors", IXGB_NETDEV_STAT(stats.tx_window_errors)},
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{"tx_deferred_ok", IXGB_STAT(stats.dc)},
789b8118df486ffec2f42d43dadaceebd0561dd564Auke Kok	{"tx_timeout_count", IXGB_STAT(tx_timeout_count) },
79dfd341e4e467d146901a3accb761f04fda535433Jesse Brandeburg	{"tx_restart_queue", IXGB_STAT(restart_queue) },
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{"rx_long_length_errors", IXGB_STAT(stats.roc)},
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{"rx_short_length_errors", IXGB_STAT(stats.ruc)},
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{"tx_tcp_seg_good", IXGB_STAT(stats.tsctc)},
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{"tx_tcp_seg_failed", IXGB_STAT(stats.tsctfc)},
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{"rx_flow_control_xon", IXGB_STAT(stats.xonrxc)},
851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{"rx_flow_control_xoff", IXGB_STAT(stats.xoffrxc)},
861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{"tx_flow_control_xon", IXGB_STAT(stats.xontxc)},
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{"tx_flow_control_xoff", IXGB_STAT(stats.xofftxc)},
881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{"rx_csum_offload_good", IXGB_STAT(hw_csum_rx_good)},
891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{"rx_csum_offload_errors", IXGB_STAT(hw_csum_rx_error)},
901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{"tx_csum_offload_good", IXGB_STAT(hw_csum_tx_good)},
911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	{"tx_csum_offload_errors", IXGB_STAT(hw_csum_tx_error)}
921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
94ff8ac60948ba819b89e9c87083e8050fc2f89999Denis Cheng#define IXGB_STATS_LEN	ARRAY_SIZE(ixgb_gstrings_stats)
951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int
971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_get_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
998908c6cd1d6889850148aeb50bb14301959adaa7Malli Chilakala	struct ixgb_adapter *adapter = netdev_priv(netdev);
1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ecmd->supported = (SUPPORTED_10000baseT_Full | SUPPORTED_FIBRE);
102db0bacaa8313e00bb571e2d1102dc9f567353a24Malli Chilakala	ecmd->advertising = (ADVERTISED_10000baseT_Full | ADVERTISED_FIBRE);
1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ecmd->port = PORT_FIBRE;
1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ecmd->transceiver = XCVR_EXTERNAL;
1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
10603f83041d836022a17258c2731f6221f248bedcbJesse Brandeburg	if (netif_carrier_ok(adapter->netdev)) {
107707394972093e2056e1e8cc39be19cf9bcb3e7b3David Decotigny		ethtool_cmd_speed_set(ecmd, SPEED_10000);
1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ecmd->duplex = DUPLEX_FULL;
1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} else {
110707394972093e2056e1e8cc39be19cf9bcb3e7b3David Decotigny		ethtool_cmd_speed_set(ecmd, -1);
1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ecmd->duplex = -1;
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ecmd->autoneg = AUTONEG_DISABLE;
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
118d7ccb8c2f2f73a9fcdb8fb0f3bcdd09746f3a9efMichał Mirosławvoid ixgb_set_speed_duplex(struct net_device *netdev)
1194de17c8c7295d32d4e112e214aa90d8f7006972fAuke Kok{
1204de17c8c7295d32d4e112e214aa90d8f7006972fAuke Kok	struct ixgb_adapter *adapter = netdev_priv(netdev);
1214de17c8c7295d32d4e112e214aa90d8f7006972fAuke Kok	/* be optimistic about our link, since we were up before */
1224de17c8c7295d32d4e112e214aa90d8f7006972fAuke Kok	adapter->link_speed = 10000;
1234de17c8c7295d32d4e112e214aa90d8f7006972fAuke Kok	adapter->link_duplex = FULL_DUPLEX;
1244de17c8c7295d32d4e112e214aa90d8f7006972fAuke Kok	netif_carrier_on(netdev);
1254de17c8c7295d32d4e112e214aa90d8f7006972fAuke Kok	netif_wake_queue(netdev);
1264de17c8c7295d32d4e112e214aa90d8f7006972fAuke Kok}
1274de17c8c7295d32d4e112e214aa90d8f7006972fAuke Kok
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1318908c6cd1d6889850148aeb50bb14301959adaa7Malli Chilakala	struct ixgb_adapter *adapter = netdev_priv(netdev);
13225db0338813a8915457636b1f6abe6a28fa73f8dDavid Decotigny	u32 speed = ethtool_cmd_speed(ecmd);
1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
13403f83041d836022a17258c2731f6221f248bedcbJesse Brandeburg	if (ecmd->autoneg == AUTONEG_ENABLE ||
13525db0338813a8915457636b1f6abe6a28fa73f8dDavid Decotigny	    (speed + ecmd->duplex != SPEED_10000 + DUPLEX_FULL))
1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -EINVAL;
1370060c07230ee6a5b070388ae55855c594a3d9132Jesse Brandeburg
13803f83041d836022a17258c2731f6221f248bedcbJesse Brandeburg	if (netif_running(adapter->netdev)) {
139446490ca44dcc8a1a9f3c082809bdab208626891Joe Perches		ixgb_down(adapter, true);
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ixgb_reset(adapter);
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ixgb_up(adapter);
1424de17c8c7295d32d4e112e214aa90d8f7006972fAuke Kok		ixgb_set_speed_duplex(netdev);
1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} else
1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ixgb_reset(adapter);
1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void
1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_get_pauseparam(struct net_device *netdev,
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 struct ethtool_pauseparam *pause)
1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1538908c6cd1d6889850148aeb50bb14301959adaa7Malli Chilakala	struct ixgb_adapter *adapter = netdev_priv(netdev);
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ixgb_hw *hw = &adapter->hw;
1550060c07230ee6a5b070388ae55855c594a3d9132Jesse Brandeburg
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	pause->autoneg = AUTONEG_DISABLE;
1570060c07230ee6a5b070388ae55855c594a3d9132Jesse Brandeburg
15803f83041d836022a17258c2731f6221f248bedcbJesse Brandeburg	if (hw->fc.type == ixgb_fc_rx_pause)
1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		pause->rx_pause = 1;
16003f83041d836022a17258c2731f6221f248bedcbJesse Brandeburg	else if (hw->fc.type == ixgb_fc_tx_pause)
1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		pause->tx_pause = 1;
16203f83041d836022a17258c2731f6221f248bedcbJesse Brandeburg	else if (hw->fc.type == ixgb_fc_full) {
1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		pause->rx_pause = 1;
1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		pause->tx_pause = 1;
1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int
1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_set_pauseparam(struct net_device *netdev,
1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			 struct ethtool_pauseparam *pause)
1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1728908c6cd1d6889850148aeb50bb14301959adaa7Malli Chilakala	struct ixgb_adapter *adapter = netdev_priv(netdev);
1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ixgb_hw *hw = &adapter->hw;
1740060c07230ee6a5b070388ae55855c594a3d9132Jesse Brandeburg
17503f83041d836022a17258c2731f6221f248bedcbJesse Brandeburg	if (pause->autoneg == AUTONEG_ENABLE)
1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -EINVAL;
1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
17803f83041d836022a17258c2731f6221f248bedcbJesse Brandeburg	if (pause->rx_pause && pause->tx_pause)
1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		hw->fc.type = ixgb_fc_full;
18003f83041d836022a17258c2731f6221f248bedcbJesse Brandeburg	else if (pause->rx_pause && !pause->tx_pause)
1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		hw->fc.type = ixgb_fc_rx_pause;
18203f83041d836022a17258c2731f6221f248bedcbJesse Brandeburg	else if (!pause->rx_pause && pause->tx_pause)
1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		hw->fc.type = ixgb_fc_tx_pause;
18403f83041d836022a17258c2731f6221f248bedcbJesse Brandeburg	else if (!pause->rx_pause && !pause->tx_pause)
1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		hw->fc.type = ixgb_fc_none;
1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
18703f83041d836022a17258c2731f6221f248bedcbJesse Brandeburg	if (netif_running(adapter->netdev)) {
188446490ca44dcc8a1a9f3c082809bdab208626891Joe Perches		ixgb_down(adapter, true);
1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ixgb_up(adapter);
1904de17c8c7295d32d4e112e214aa90d8f7006972fAuke Kok		ixgb_set_speed_duplex(netdev);
1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} else
1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ixgb_reset(adapter);
1930060c07230ee6a5b070388ae55855c594a3d9132Jesse Brandeburg
1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
197222441a6201f791238320e77eb4ba9528cd3934cJoe Perchesstatic u32
198ec9c3f5d3b8c4dd7340800f02eed87bdf0233e3bAuke Kokixgb_get_msglevel(struct net_device *netdev)
199ec9c3f5d3b8c4dd7340800f02eed87bdf0233e3bAuke Kok{
20025943071b40580ba24e0a111e86b4869b9f5c07cAuke Kok	struct ixgb_adapter *adapter = netdev_priv(netdev);
201ec9c3f5d3b8c4dd7340800f02eed87bdf0233e3bAuke Kok	return adapter->msg_enable;
202ec9c3f5d3b8c4dd7340800f02eed87bdf0233e3bAuke Kok}
203ec9c3f5d3b8c4dd7340800f02eed87bdf0233e3bAuke Kok
204ec9c3f5d3b8c4dd7340800f02eed87bdf0233e3bAuke Kokstatic void
205222441a6201f791238320e77eb4ba9528cd3934cJoe Perchesixgb_set_msglevel(struct net_device *netdev, u32 data)
206ec9c3f5d3b8c4dd7340800f02eed87bdf0233e3bAuke Kok{
20725943071b40580ba24e0a111e86b4869b9f5c07cAuke Kok	struct ixgb_adapter *adapter = netdev_priv(netdev);
208ec9c3f5d3b8c4dd7340800f02eed87bdf0233e3bAuke Kok	adapter->msg_enable = data;
209ec9c3f5d3b8c4dd7340800f02eed87bdf0233e3bAuke Kok}
2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define IXGB_GET_STAT(_A_, _R_) _A_->stats._R_
2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2120060c07230ee6a5b070388ae55855c594a3d9132Jesse Brandeburgstatic int
2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_get_regs_len(struct net_device *netdev)
2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
215222441a6201f791238320e77eb4ba9528cd3934cJoe Perches#define IXGB_REG_DUMP_LEN  136*sizeof(u32)
2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return IXGB_REG_DUMP_LEN;
2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void
2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_get_regs(struct net_device *netdev,
2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		   struct ethtool_regs *regs, void *p)
2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2238908c6cd1d6889850148aeb50bb14301959adaa7Malli Chilakala	struct ixgb_adapter *adapter = netdev_priv(netdev);
2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ixgb_hw *hw = &adapter->hw;
225222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u32 *reg = p;
226222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u32 *reg_start = reg;
227222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u8 i;
2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2295e3c30deb21d0eb0da44830fb1c1fc7054e54229Malli Chilakala	/* the 1 (one) below indicates an attempt at versioning, if the
230ab707da7cf0a1a1d27c6021356cfb3692cf1bd26Malli Chilakala	 * interface in ethtool or the driver changes, this 1 should be
231ab707da7cf0a1a1d27c6021356cfb3692cf1bd26Malli Chilakala	 * incremented */
2325e3c30deb21d0eb0da44830fb1c1fc7054e54229Malli Chilakala	regs->version = (1<<24) | hw->revision_id << 16 | hw->device_id;
2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* General Registers */
2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_READ_REG(hw, CTRL0);	/*   0 */
2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_READ_REG(hw, CTRL1);	/*   1 */
2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_READ_REG(hw, STATUS);	/*   2 */
2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_READ_REG(hw, EECD);	/*   3 */
2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_READ_REG(hw, MFS);	/*   4 */
2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Interrupt */
2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_READ_REG(hw, ICR);	/*   5 */
2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_READ_REG(hw, ICS);	/*   6 */
2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_READ_REG(hw, IMS);	/*   7 */
2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_READ_REG(hw, IMC);	/*   8 */
2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Receive */
2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_READ_REG(hw, RCTL);	/*   9 */
2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_READ_REG(hw, FCRTL);	/*  10 */
2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_READ_REG(hw, FCRTH);	/*  11 */
2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_READ_REG(hw, RDBAL);	/*  12 */
2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_READ_REG(hw, RDBAH);	/*  13 */
2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_READ_REG(hw, RDLEN);	/*  14 */
2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_READ_REG(hw, RDH);	/*  15 */
2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_READ_REG(hw, RDT);	/*  16 */
2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_READ_REG(hw, RDTR);	/*  17 */
2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_READ_REG(hw, RXDCTL);	/*  18 */
2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_READ_REG(hw, RAIDC);	/*  19 */
2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_READ_REG(hw, RXCSUM);	/*  20 */
2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2619ef2eec39383f8fe2bd7c9fac4dfdd4fdf7173e6Malli Chilakala	/* there are 16 RAR entries in hardware, we only use 3 */
2621459336da45b214a59f0825777549fb0cb60ed7dJesse Brandeburg	for (i = 0; i < IXGB_ALL_RAR_ENTRIES; i++) {
2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		*reg++ = IXGB_READ_REG_ARRAY(hw, RAL, (i << 1)); /*21,...,51 */
2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		*reg++ = IXGB_READ_REG_ARRAY(hw, RAH, (i << 1)); /*22,...,52 */
2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Transmit */
2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_READ_REG(hw, TCTL);	/*  53 */
2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_READ_REG(hw, TDBAL);	/*  54 */
2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_READ_REG(hw, TDBAH);	/*  55 */
2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_READ_REG(hw, TDLEN);	/*  56 */
2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_READ_REG(hw, TDH);	/*  57 */
2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_READ_REG(hw, TDT);	/*  58 */
2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_READ_REG(hw, TIDV);	/*  59 */
2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_READ_REG(hw, TXDCTL);	/*  60 */
2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_READ_REG(hw, TSPMT);	/*  61 */
2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_READ_REG(hw, PAP);	/*  62 */
2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Physical */
2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_READ_REG(hw, PCSC1);	/*  63 */
2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_READ_REG(hw, PCSC2);	/*  64 */
2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_READ_REG(hw, PCSS1);	/*  65 */
2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_READ_REG(hw, PCSS2);	/*  66 */
2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_READ_REG(hw, XPCSS);	/*  67 */
2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_READ_REG(hw, UCCR);	/*  68 */
2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_READ_REG(hw, XPCSTC);	/*  69 */
2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_READ_REG(hw, MACA);	/*  70 */
2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_READ_REG(hw, APAE);	/*  71 */
2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_READ_REG(hw, ARD);	/*  72 */
2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_READ_REG(hw, AIS);	/*  73 */
2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_READ_REG(hw, MSCA);	/*  74 */
2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_READ_REG(hw, MSRWD);	/*  75 */
2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Statistics */
2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, tprl);	/*  76 */
2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, tprh);	/*  77 */
2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, gprcl);	/*  78 */
2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, gprch);	/*  79 */
2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, bprcl);	/*  80 */
3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, bprch);	/*  81 */
3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, mprcl);	/*  82 */
3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, mprch);	/*  83 */
3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, uprcl);	/*  84 */
3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, uprch);	/*  85 */
3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, vprcl);	/*  86 */
3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, vprch);	/*  87 */
3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, jprcl);	/*  88 */
3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, jprch);	/*  89 */
3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, gorcl);	/*  90 */
3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, gorch);	/*  91 */
3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, torl);	/*  92 */
3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, torh);	/*  93 */
3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, rnbc);	/*  94 */
3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, ruc);	/*  95 */
3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, roc);	/*  96 */
3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, rlec);	/*  97 */
3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, crcerrs);	/*  98 */
3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, icbc);	/*  99 */
3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, ecbc);	/* 100 */
3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, mpc);	/* 101 */
3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, tptl);	/* 102 */
3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, tpth);	/* 103 */
3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, gptcl);	/* 104 */
3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, gptch);	/* 105 */
3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, bptcl);	/* 106 */
3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, bptch);	/* 107 */
3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, mptcl);	/* 108 */
3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, mptch);	/* 109 */
3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, uptcl);	/* 110 */
3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, uptch);	/* 111 */
3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, vptcl);	/* 112 */
3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, vptch);	/* 113 */
3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, jptcl);	/* 114 */
3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, jptch);	/* 115 */
3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, gotcl);	/* 116 */
3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, gotch);	/* 117 */
3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, totl);	/* 118 */
3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, toth);	/* 119 */
3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, dc);	/* 120 */
3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, plt64c);	/* 121 */
3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, tsctc);	/* 122 */
3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, tsctfc);	/* 123 */
3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, ibic);	/* 124 */
3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, rfc);	/* 125 */
3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, lfc);	/* 126 */
3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, pfrc);	/* 127 */
3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, pftc);	/* 128 */
3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, mcfrc);	/* 129 */
3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, mcftc);	/* 130 */
3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, xonrxc);	/* 131 */
3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, xontxc);	/* 132 */
3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, xoffrxc);	/* 133 */
3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, xofftxc);	/* 134 */
3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	*reg++ = IXGB_GET_STAT(adapter, rjc);	/* 135 */
3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
356222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	regs->len = (reg - reg_start) * sizeof(u32);
3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int
3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_get_eeprom_len(struct net_device *netdev)
3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* return size in bytes */
363807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet	return IXGB_EEPROM_SIZE << 1;
3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int
3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_get_eeprom(struct net_device *netdev,
368222441a6201f791238320e77eb4ba9528cd3934cJoe Perches		  struct ethtool_eeprom *eeprom, u8 *bytes)
3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
3708908c6cd1d6889850148aeb50bb14301959adaa7Malli Chilakala	struct ixgb_adapter *adapter = netdev_priv(netdev);
3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ixgb_hw *hw = &adapter->hw;
372c676504ef5fe682bd343149de0e5c57bbf793ff9Al Viro	__le16 *eeprom_buff;
3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int i, max_len, first_word, last_word;
3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int ret_val = 0;
3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
37603f83041d836022a17258c2731f6221f248bedcbJesse Brandeburg	if (eeprom->len == 0) {
3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ret_val = -EINVAL;
3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto geeprom_error;
3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	eeprom->magic = hw->vendor_id | (hw->device_id << 16);
3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	max_len = ixgb_get_eeprom_len(netdev);
3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
38503f83041d836022a17258c2731f6221f248bedcbJesse Brandeburg	if (eeprom->offset > eeprom->offset + eeprom->len) {
3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ret_val = -EINVAL;
3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto geeprom_error;
3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
39003f83041d836022a17258c2731f6221f248bedcbJesse Brandeburg	if ((eeprom->offset + eeprom->len) > max_len)
3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		eeprom->len = (max_len - eeprom->offset);
3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	first_word = eeprom->offset >> 1;
3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	last_word = (eeprom->offset + eeprom->len - 1) >> 1;
3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
396c676504ef5fe682bd343149de0e5c57bbf793ff9Al Viro	eeprom_buff = kmalloc(sizeof(__le16) *
3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			(last_word - first_word + 1), GFP_KERNEL);
39803f83041d836022a17258c2731f6221f248bedcbJesse Brandeburg	if (!eeprom_buff)
3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -ENOMEM;
4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* note the eeprom was good because the driver loaded */
4021459336da45b214a59f0825777549fb0cb60ed7dJesse Brandeburg	for (i = 0; i <= (last_word - first_word); i++)
4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		eeprom_buff[i] = ixgb_get_eeprom_word(hw, (first_word + i));
4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4051459336da45b214a59f0825777549fb0cb60ed7dJesse Brandeburg	memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 1), eeprom->len);
4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	kfree(eeprom_buff);
4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsgeeprom_error:
4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret_val;
4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int
4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_set_eeprom(struct net_device *netdev,
414222441a6201f791238320e77eb4ba9528cd3934cJoe Perches		  struct ethtool_eeprom *eeprom, u8 *bytes)
4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4168908c6cd1d6889850148aeb50bb14301959adaa7Malli Chilakala	struct ixgb_adapter *adapter = netdev_priv(netdev);
4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ixgb_hw *hw = &adapter->hw;
418222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u16 *eeprom_buff;
4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	void *ptr;
4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int max_len, first_word, last_word;
421222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	u16 i;
4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
42303f83041d836022a17258c2731f6221f248bedcbJesse Brandeburg	if (eeprom->len == 0)
4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -EINVAL;
4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
42603f83041d836022a17258c2731f6221f248bedcbJesse Brandeburg	if (eeprom->magic != (hw->vendor_id | (hw->device_id << 16)))
4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -EFAULT;
4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	max_len = ixgb_get_eeprom_len(netdev);
4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
43103f83041d836022a17258c2731f6221f248bedcbJesse Brandeburg	if (eeprom->offset > eeprom->offset + eeprom->len)
4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -EINVAL;
4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
43403f83041d836022a17258c2731f6221f248bedcbJesse Brandeburg	if ((eeprom->offset + eeprom->len) > max_len)
4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		eeprom->len = (max_len - eeprom->offset);
4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	first_word = eeprom->offset >> 1;
4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	last_word = (eeprom->offset + eeprom->len - 1) >> 1;
4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	eeprom_buff = kmalloc(max_len, GFP_KERNEL);
44003f83041d836022a17258c2731f6221f248bedcbJesse Brandeburg	if (!eeprom_buff)
4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -ENOMEM;
4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ptr = (void *)eeprom_buff;
4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
44503f83041d836022a17258c2731f6221f248bedcbJesse Brandeburg	if (eeprom->offset & 1) {
4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* need read/modify/write of first changed EEPROM word */
4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* only the second byte of the word is being modified */
4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		eeprom_buff[0] = ixgb_read_eeprom(hw, first_word);
4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ptr++;
4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
45103f83041d836022a17258c2731f6221f248bedcbJesse Brandeburg	if ((eeprom->offset + eeprom->len) & 1) {
4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* need read/modify/write of last changed EEPROM word */
4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* only the first byte of the word is being modified */
4540060c07230ee6a5b070388ae55855c594a3d9132Jesse Brandeburg		eeprom_buff[last_word - first_word]
4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			= ixgb_read_eeprom(hw, last_word);
4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	memcpy(ptr, bytes, eeprom->len);
4591459336da45b214a59f0825777549fb0cb60ed7dJesse Brandeburg	for (i = 0; i <= (last_word - first_word); i++)
4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ixgb_write_eeprom(hw, first_word + i, eeprom_buff[i]);
4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Update the checksum over the first part of the EEPROM if needed */
46303f83041d836022a17258c2731f6221f248bedcbJesse Brandeburg	if (first_word <= EEPROM_CHECKSUM_REG)
4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ixgb_update_eeprom_checksum(hw);
4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	kfree(eeprom_buff);
4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void
4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_get_drvinfo(struct net_device *netdev,
4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		   struct ethtool_drvinfo *drvinfo)
4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4748908c6cd1d6889850148aeb50bb14301959adaa7Malli Chilakala	struct ixgb_adapter *adapter = netdev_priv(netdev);
4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
476612a94d6f24eb2427eabf554392080302da664ddRick Jones	strlcpy(drvinfo->driver,  ixgb_driver_name,
477612a94d6f24eb2427eabf554392080302da664ddRick Jones		sizeof(drvinfo->driver));
478612a94d6f24eb2427eabf554392080302da664ddRick Jones	strlcpy(drvinfo->version, ixgb_driver_version,
479612a94d6f24eb2427eabf554392080302da664ddRick Jones		sizeof(drvinfo->version));
480612a94d6f24eb2427eabf554392080302da664ddRick Jones	strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
481612a94d6f24eb2427eabf554392080302da664ddRick Jones		sizeof(drvinfo->bus_info));
4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	drvinfo->n_stats = IXGB_STATS_LEN;
4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	drvinfo->regdump_len = ixgb_get_regs_len(netdev);
4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	drvinfo->eedump_len = ixgb_get_eeprom_len(netdev);
4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void
4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_get_ringparam(struct net_device *netdev,
4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		struct ethtool_ringparam *ring)
4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
4918908c6cd1d6889850148aeb50bb14301959adaa7Malli Chilakala	struct ixgb_adapter *adapter = netdev_priv(netdev);
4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ixgb_desc_ring *txdr = &adapter->tx_ring;
4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ixgb_desc_ring *rxdr = &adapter->rx_ring;
4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
4950060c07230ee6a5b070388ae55855c594a3d9132Jesse Brandeburg	ring->rx_max_pending = MAX_RXD;
4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ring->tx_max_pending = MAX_TXD;
4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ring->rx_pending = rxdr->count;
4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ring->tx_pending = txdr->count;
4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5010060c07230ee6a5b070388ae55855c594a3d9132Jesse Brandeburgstatic int
5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsixgb_set_ringparam(struct net_device *netdev,
5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		struct ethtool_ringparam *ring)
5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5058908c6cd1d6889850148aeb50bb14301959adaa7Malli Chilakala	struct ixgb_adapter *adapter = netdev_priv(netdev);
5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ixgb_desc_ring *txdr = &adapter->tx_ring;
5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ixgb_desc_ring *rxdr = &adapter->rx_ring;
5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct ixgb_desc_ring tx_old, tx_new, rx_old, rx_new;
5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int err;
5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	tx_old = adapter->tx_ring;
5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	rx_old = adapter->rx_ring;
5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
51403f83041d836022a17258c2731f6221f248bedcbJesse Brandeburg	if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return -EINVAL;
5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
51703f83041d836022a17258c2731f6221f248bedcbJesse Brandeburg	if (netif_running(adapter->netdev))
518446490ca44dcc8a1a9f3c082809bdab208626891Joe Perches		ixgb_down(adapter, true);
5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
520222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	rxdr->count = max(ring->rx_pending,(u32)MIN_RXD);
521222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	rxdr->count = min(rxdr->count,(u32)MAX_RXD);
52255e924cf5772cbcf00549e448be35b392ff3084cMilind Arun Choudhary	rxdr->count = ALIGN(rxdr->count, IXGB_REQ_RX_DESCRIPTOR_MULTIPLE);
5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
524222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	txdr->count = max(ring->tx_pending,(u32)MIN_TXD);
525222441a6201f791238320e77eb4ba9528cd3934cJoe Perches	txdr->count = min(txdr->count,(u32)MAX_TXD);
52655e924cf5772cbcf00549e448be35b392ff3084cMilind Arun Choudhary	txdr->count = ALIGN(txdr->count, IXGB_REQ_TX_DESCRIPTOR_MULTIPLE);
5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
52803f83041d836022a17258c2731f6221f248bedcbJesse Brandeburg	if (netif_running(adapter->netdev)) {
5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Try to get new resources before deleting old */
53003f83041d836022a17258c2731f6221f248bedcbJesse Brandeburg		if ((err = ixgb_setup_rx_resources(adapter)))
5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			goto err_setup_rx;
53203f83041d836022a17258c2731f6221f248bedcbJesse Brandeburg		if ((err = ixgb_setup_tx_resources(adapter)))
5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			goto err_setup_tx;
5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* save the new, restore the old in order to free it,
5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		 * then restore the new back again */
5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		rx_new = adapter->rx_ring;
5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		tx_new = adapter->tx_ring;
5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		adapter->rx_ring = rx_old;
5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		adapter->tx_ring = tx_old;
5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ixgb_free_rx_resources(adapter);
5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ixgb_free_tx_resources(adapter);
5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		adapter->rx_ring = rx_new;
5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		adapter->tx_ring = tx_new;
54603f83041d836022a17258c2731f6221f248bedcbJesse Brandeburg		if ((err = ixgb_up(adapter)))
5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return err;
5484de17c8c7295d32d4e112e214aa90d8f7006972fAuke Kok		ixgb_set_speed_duplex(netdev);
5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldserr_setup_tx:
5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ixgb_free_rx_resources(adapter);
5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldserr_setup_rx:
5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	adapter->rx_ring = rx_old;
5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	adapter->tx_ring = tx_old;
5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ixgb_up(adapter);
5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return err;
5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int
562ec7e97e9a0265255485e217f4f2d3513949e7083Jeff Kirsherixgb_set_phys_id(struct net_device *netdev, enum ethtool_phys_id_state state)
5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5648908c6cd1d6889850148aeb50bb14301959adaa7Malli Chilakala	struct ixgb_adapter *adapter = netdev_priv(netdev);
5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
566ec7e97e9a0265255485e217f4f2d3513949e7083Jeff Kirsher	switch (state) {
567ec7e97e9a0265255485e217f4f2d3513949e7083Jeff Kirsher	case ETHTOOL_ID_ACTIVE:
568ec7e97e9a0265255485e217f4f2d3513949e7083Jeff Kirsher		return 2;
5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
570ec7e97e9a0265255485e217f4f2d3513949e7083Jeff Kirsher	case ETHTOOL_ID_ON:
571ec7e97e9a0265255485e217f4f2d3513949e7083Jeff Kirsher		ixgb_led_on(&adapter->hw);
572ec7e97e9a0265255485e217f4f2d3513949e7083Jeff Kirsher		break;
5731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
574ec7e97e9a0265255485e217f4f2d3513949e7083Jeff Kirsher	case ETHTOOL_ID_OFF:
575ec7e97e9a0265255485e217f4f2d3513949e7083Jeff Kirsher	case ETHTOOL_ID_INACTIVE:
576ec7e97e9a0265255485e217f4f2d3513949e7083Jeff Kirsher		ixgb_led_off(&adapter->hw);
577ec7e97e9a0265255485e217f4f2d3513949e7083Jeff Kirsher	}
5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return 0;
5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5820060c07230ee6a5b070388ae55855c594a3d9132Jesse Brandeburgstatic int
583b9f2c0440d806e01968c3ed4def930a43be248adJeff Garzikixgb_get_sset_count(struct net_device *netdev, int sset)
5841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
585b9f2c0440d806e01968c3ed4def930a43be248adJeff Garzik	switch (sset) {
586b9f2c0440d806e01968c3ed4def930a43be248adJeff Garzik	case ETH_SS_STATS:
587b9f2c0440d806e01968c3ed4def930a43be248adJeff Garzik		return IXGB_STATS_LEN;
588b9f2c0440d806e01968c3ed4def930a43be248adJeff Garzik	default:
589b9f2c0440d806e01968c3ed4def930a43be248adJeff Garzik		return -EOPNOTSUPP;
590b9f2c0440d806e01968c3ed4def930a43be248adJeff Garzik	}
5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
5930060c07230ee6a5b070388ae55855c594a3d9132Jesse Brandeburgstatic void
5940060c07230ee6a5b070388ae55855c594a3d9132Jesse Brandeburgixgb_get_ethtool_stats(struct net_device *netdev,
595222441a6201f791238320e77eb4ba9528cd3934cJoe Perches		struct ethtool_stats *stats, u64 *data)
5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
5978908c6cd1d6889850148aeb50bb14301959adaa7Malli Chilakala	struct ixgb_adapter *adapter = netdev_priv(netdev);
5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int i;
599d189a7e85835dbfb22b1d04eb7f3ab575ccacb96Ajit Khaparde	char *p = NULL;
6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ixgb_update_stats(adapter);
6021459336da45b214a59f0825777549fb0cb60ed7dJesse Brandeburg	for (i = 0; i < IXGB_STATS_LEN; i++) {
603d189a7e85835dbfb22b1d04eb7f3ab575ccacb96Ajit Khaparde		switch (ixgb_gstrings_stats[i].type) {
604d189a7e85835dbfb22b1d04eb7f3ab575ccacb96Ajit Khaparde		case NETDEV_STATS:
605d189a7e85835dbfb22b1d04eb7f3ab575ccacb96Ajit Khaparde			p = (char *) netdev +
606d189a7e85835dbfb22b1d04eb7f3ab575ccacb96Ajit Khaparde					ixgb_gstrings_stats[i].stat_offset;
607d189a7e85835dbfb22b1d04eb7f3ab575ccacb96Ajit Khaparde			break;
608d189a7e85835dbfb22b1d04eb7f3ab575ccacb96Ajit Khaparde		case IXGB_STATS:
609d189a7e85835dbfb22b1d04eb7f3ab575ccacb96Ajit Khaparde			p = (char *) adapter +
610d189a7e85835dbfb22b1d04eb7f3ab575ccacb96Ajit Khaparde					ixgb_gstrings_stats[i].stat_offset;
611d189a7e85835dbfb22b1d04eb7f3ab575ccacb96Ajit Khaparde			break;
612d189a7e85835dbfb22b1d04eb7f3ab575ccacb96Ajit Khaparde		}
613d189a7e85835dbfb22b1d04eb7f3ab575ccacb96Ajit Khaparde
6140060c07230ee6a5b070388ae55855c594a3d9132Jesse Brandeburg		data[i] = (ixgb_gstrings_stats[i].sizeof_stat ==
615222441a6201f791238320e77eb4ba9528cd3934cJoe Perches			sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
6161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
6171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6190060c07230ee6a5b070388ae55855c594a3d9132Jesse Brandeburgstatic void
620222441a6201f791238320e77eb4ba9528cd3934cJoe Perchesixgb_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
6211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
6221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int i;
6231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	switch(stringset) {
6251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	case ETH_SS_STATS:
6261459336da45b214a59f0825777549fb0cb60ed7dJesse Brandeburg		for (i = 0; i < IXGB_STATS_LEN; i++) {
6270060c07230ee6a5b070388ae55855c594a3d9132Jesse Brandeburg			memcpy(data + i * ETH_GSTRING_LEN,
6281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			ixgb_gstrings_stats[i].stat_string,
6291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			ETH_GSTRING_LEN);
6301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
6311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		break;
6321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
6331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
6341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6357282d491ecaee9883233a0e27283c4c79486279aJeff Garzikstatic const struct ethtool_ops ixgb_ethtool_ops = {
6361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.get_settings = ixgb_get_settings,
6371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.set_settings = ixgb_set_settings,
6381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.get_drvinfo = ixgb_get_drvinfo,
6391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.get_regs_len = ixgb_get_regs_len,
6401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.get_regs = ixgb_get_regs,
6411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.get_link = ethtool_op_get_link,
6421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.get_eeprom_len = ixgb_get_eeprom_len,
6431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.get_eeprom = ixgb_get_eeprom,
6441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.set_eeprom = ixgb_set_eeprom,
6451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.get_ringparam = ixgb_get_ringparam,
6461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.set_ringparam = ixgb_set_ringparam,
6471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.get_pauseparam	= ixgb_get_pauseparam,
6481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.set_pauseparam	= ixgb_set_pauseparam,
649ec9c3f5d3b8c4dd7340800f02eed87bdf0233e3bAuke Kok	.get_msglevel = ixgb_get_msglevel,
650ec9c3f5d3b8c4dd7340800f02eed87bdf0233e3bAuke Kok	.set_msglevel = ixgb_set_msglevel,
6511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.get_strings = ixgb_get_strings,
652ec7e97e9a0265255485e217f4f2d3513949e7083Jeff Kirsher	.set_phys_id = ixgb_set_phys_id,
653b9f2c0440d806e01968c3ed4def930a43be248adJeff Garzik	.get_sset_count = ixgb_get_sset_count,
6541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	.get_ethtool_stats = ixgb_get_ethtool_stats,
6551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
6561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
6571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid ixgb_set_ethtool_ops(struct net_device *netdev)
6581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
6591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	SET_ETHTOOL_OPS(netdev, &ixgb_ethtool_ops);
6601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
661