devices/e1000e/ethtool-3.14-orig.c
author Patrick Bruenn <p.bruenn@beckhoff.com>
Tue, 12 Apr 2016 11:17:36 +0200
branchstable-1.5
changeset 2654 b3f6b3e5ef29
parent 2587 afd76ee3aa87
permissions -rw-r--r--
devices/ccat: revert "limit rx processing to one frame per poll"

revert "limit rx processing to one frame per poll", which caused etherlab
frame timeouts in setups with more than one frame per cycle.
2587
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     1
/*******************************************************************************
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     2
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     3
  Intel PRO/1000 Linux driver
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     4
  Copyright(c) 1999 - 2013 Intel Corporation.
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     5
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     6
  This program is free software; you can redistribute it and/or modify it
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     7
  under the terms and conditions of the GNU General Public License,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     8
  version 2, as published by the Free Software Foundation.
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
     9
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    10
  This program is distributed in the hope it will be useful, but WITHOUT
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    11
  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    12
  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    13
  more details.
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    14
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    15
  You should have received a copy of the GNU General Public License along with
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    16
  this program; if not, write to the Free Software Foundation, Inc.,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    17
  51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    18
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    19
  The full GNU General Public License is included in this distribution in
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    20
  the file called "COPYING".
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    21
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    22
  Contact Information:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    23
  Linux NICS <linux.nics@intel.com>
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    24
  e1000-devel Mailing List <e1000-devel@lists.sourceforge.net>
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    25
  Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    26
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    27
*******************************************************************************/
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    28
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    29
/* ethtool support for e1000 */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    30
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    31
#include <linux/netdevice.h>
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    32
#include <linux/interrupt.h>
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    33
#include <linux/ethtool.h>
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    34
#include <linux/pci.h>
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    35
#include <linux/slab.h>
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    36
#include <linux/delay.h>
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    37
#include <linux/vmalloc.h>
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    38
#include <linux/pm_runtime.h>
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    39
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    40
#include "e1000.h"
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    41
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    42
enum { NETDEV_STATS, E1000_STATS };
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    43
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    44
struct e1000_stats {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    45
	char stat_string[ETH_GSTRING_LEN];
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    46
	int type;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    47
	int sizeof_stat;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    48
	int stat_offset;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    49
};
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    50
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    51
#define E1000_STAT(str, m) { \
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    52
		.stat_string = str, \
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    53
		.type = E1000_STATS, \
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    54
		.sizeof_stat = sizeof(((struct e1000_adapter *)0)->m), \
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    55
		.stat_offset = offsetof(struct e1000_adapter, m) }
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    56
#define E1000_NETDEV_STAT(str, m) { \
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    57
		.stat_string = str, \
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    58
		.type = NETDEV_STATS, \
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    59
		.sizeof_stat = sizeof(((struct rtnl_link_stats64 *)0)->m), \
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    60
		.stat_offset = offsetof(struct rtnl_link_stats64, m) }
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    61
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    62
static const struct e1000_stats e1000_gstrings_stats[] = {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    63
	E1000_STAT("rx_packets", stats.gprc),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    64
	E1000_STAT("tx_packets", stats.gptc),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    65
	E1000_STAT("rx_bytes", stats.gorc),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    66
	E1000_STAT("tx_bytes", stats.gotc),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    67
	E1000_STAT("rx_broadcast", stats.bprc),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    68
	E1000_STAT("tx_broadcast", stats.bptc),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    69
	E1000_STAT("rx_multicast", stats.mprc),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    70
	E1000_STAT("tx_multicast", stats.mptc),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    71
	E1000_NETDEV_STAT("rx_errors", rx_errors),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    72
	E1000_NETDEV_STAT("tx_errors", tx_errors),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    73
	E1000_NETDEV_STAT("tx_dropped", tx_dropped),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    74
	E1000_STAT("multicast", stats.mprc),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    75
	E1000_STAT("collisions", stats.colc),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    76
	E1000_NETDEV_STAT("rx_length_errors", rx_length_errors),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    77
	E1000_NETDEV_STAT("rx_over_errors", rx_over_errors),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    78
	E1000_STAT("rx_crc_errors", stats.crcerrs),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    79
	E1000_NETDEV_STAT("rx_frame_errors", rx_frame_errors),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    80
	E1000_STAT("rx_no_buffer_count", stats.rnbc),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    81
	E1000_STAT("rx_missed_errors", stats.mpc),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    82
	E1000_STAT("tx_aborted_errors", stats.ecol),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    83
	E1000_STAT("tx_carrier_errors", stats.tncrs),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    84
	E1000_NETDEV_STAT("tx_fifo_errors", tx_fifo_errors),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    85
	E1000_NETDEV_STAT("tx_heartbeat_errors", tx_heartbeat_errors),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    86
	E1000_STAT("tx_window_errors", stats.latecol),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    87
	E1000_STAT("tx_abort_late_coll", stats.latecol),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    88
	E1000_STAT("tx_deferred_ok", stats.dc),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    89
	E1000_STAT("tx_single_coll_ok", stats.scc),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    90
	E1000_STAT("tx_multi_coll_ok", stats.mcc),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    91
	E1000_STAT("tx_timeout_count", tx_timeout_count),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    92
	E1000_STAT("tx_restart_queue", restart_queue),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    93
	E1000_STAT("rx_long_length_errors", stats.roc),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    94
	E1000_STAT("rx_short_length_errors", stats.ruc),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    95
	E1000_STAT("rx_align_errors", stats.algnerrc),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    96
	E1000_STAT("tx_tcp_seg_good", stats.tsctc),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    97
	E1000_STAT("tx_tcp_seg_failed", stats.tsctfc),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    98
	E1000_STAT("rx_flow_control_xon", stats.xonrxc),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
    99
	E1000_STAT("rx_flow_control_xoff", stats.xoffrxc),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   100
	E1000_STAT("tx_flow_control_xon", stats.xontxc),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   101
	E1000_STAT("tx_flow_control_xoff", stats.xofftxc),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   102
	E1000_STAT("rx_csum_offload_good", hw_csum_good),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   103
	E1000_STAT("rx_csum_offload_errors", hw_csum_err),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   104
	E1000_STAT("rx_header_split", rx_hdr_split),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   105
	E1000_STAT("alloc_rx_buff_failed", alloc_rx_buff_failed),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   106
	E1000_STAT("tx_smbus", stats.mgptc),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   107
	E1000_STAT("rx_smbus", stats.mgprc),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   108
	E1000_STAT("dropped_smbus", stats.mgpdc),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   109
	E1000_STAT("rx_dma_failed", rx_dma_failed),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   110
	E1000_STAT("tx_dma_failed", tx_dma_failed),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   111
	E1000_STAT("rx_hwtstamp_cleared", rx_hwtstamp_cleared),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   112
	E1000_STAT("uncorr_ecc_errors", uncorr_errors),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   113
	E1000_STAT("corr_ecc_errors", corr_errors),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   114
};
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   115
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   116
#define E1000_GLOBAL_STATS_LEN	ARRAY_SIZE(e1000_gstrings_stats)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   117
#define E1000_STATS_LEN (E1000_GLOBAL_STATS_LEN)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   118
static const char e1000_gstrings_test[][ETH_GSTRING_LEN] = {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   119
	"Register test  (offline)", "Eeprom test    (offline)",
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   120
	"Interrupt test (offline)", "Loopback test  (offline)",
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   121
	"Link test   (on/offline)"
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   122
};
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   123
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   124
#define E1000_TEST_LEN ARRAY_SIZE(e1000_gstrings_test)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   125
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   126
static int e1000_get_settings(struct net_device *netdev,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   127
			      struct ethtool_cmd *ecmd)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   128
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   129
	struct e1000_adapter *adapter = netdev_priv(netdev);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   130
	struct e1000_hw *hw = &adapter->hw;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   131
	u32 speed;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   132
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   133
	if (hw->phy.media_type == e1000_media_type_copper) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   134
		ecmd->supported = (SUPPORTED_10baseT_Half |
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   135
				   SUPPORTED_10baseT_Full |
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   136
				   SUPPORTED_100baseT_Half |
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   137
				   SUPPORTED_100baseT_Full |
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   138
				   SUPPORTED_1000baseT_Full |
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   139
				   SUPPORTED_Autoneg |
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   140
				   SUPPORTED_TP);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   141
		if (hw->phy.type == e1000_phy_ife)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   142
			ecmd->supported &= ~SUPPORTED_1000baseT_Full;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   143
		ecmd->advertising = ADVERTISED_TP;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   144
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   145
		if (hw->mac.autoneg == 1) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   146
			ecmd->advertising |= ADVERTISED_Autoneg;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   147
			/* the e1000 autoneg seems to match ethtool nicely */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   148
			ecmd->advertising |= hw->phy.autoneg_advertised;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   149
		}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   150
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   151
		ecmd->port = PORT_TP;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   152
		ecmd->phy_address = hw->phy.addr;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   153
		ecmd->transceiver = XCVR_INTERNAL;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   154
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   155
	} else {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   156
		ecmd->supported   = (SUPPORTED_1000baseT_Full |
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   157
				     SUPPORTED_FIBRE |
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   158
				     SUPPORTED_Autoneg);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   159
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   160
		ecmd->advertising = (ADVERTISED_1000baseT_Full |
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   161
				     ADVERTISED_FIBRE |
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   162
				     ADVERTISED_Autoneg);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   163
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   164
		ecmd->port = PORT_FIBRE;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   165
		ecmd->transceiver = XCVR_EXTERNAL;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   166
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   167
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   168
	speed = -1;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   169
	ecmd->duplex = -1;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   170
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   171
	if (netif_running(netdev)) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   172
		if (netif_carrier_ok(netdev)) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   173
			speed = adapter->link_speed;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   174
			ecmd->duplex = adapter->link_duplex - 1;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   175
		}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   176
	} else if (!pm_runtime_suspended(netdev->dev.parent)) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   177
		u32 status = er32(STATUS);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   178
		if (status & E1000_STATUS_LU) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   179
			if (status & E1000_STATUS_SPEED_1000)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   180
				speed = SPEED_1000;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   181
			else if (status & E1000_STATUS_SPEED_100)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   182
				speed = SPEED_100;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   183
			else
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   184
				speed = SPEED_10;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   185
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   186
			if (status & E1000_STATUS_FD)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   187
				ecmd->duplex = DUPLEX_FULL;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   188
			else
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   189
				ecmd->duplex = DUPLEX_HALF;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   190
		}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   191
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   192
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   193
	ethtool_cmd_speed_set(ecmd, speed);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   194
	ecmd->autoneg = ((hw->phy.media_type == e1000_media_type_fiber) ||
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   195
			 hw->mac.autoneg) ? AUTONEG_ENABLE : AUTONEG_DISABLE;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   196
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   197
	/* MDI-X => 2; MDI =>1; Invalid =>0 */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   198
	if ((hw->phy.media_type == e1000_media_type_copper) &&
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   199
	    netif_carrier_ok(netdev))
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   200
		ecmd->eth_tp_mdix = hw->phy.is_mdix ? ETH_TP_MDI_X : ETH_TP_MDI;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   201
	else
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   202
		ecmd->eth_tp_mdix = ETH_TP_MDI_INVALID;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   203
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   204
	if (hw->phy.mdix == AUTO_ALL_MODES)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   205
		ecmd->eth_tp_mdix_ctrl = ETH_TP_MDI_AUTO;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   206
	else
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   207
		ecmd->eth_tp_mdix_ctrl = hw->phy.mdix;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   208
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   209
	return 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   210
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   211
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   212
static int e1000_set_spd_dplx(struct e1000_adapter *adapter, u32 spd, u8 dplx)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   213
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   214
	struct e1000_mac_info *mac = &adapter->hw.mac;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   215
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   216
	mac->autoneg = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   217
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   218
	/* Make sure dplx is at most 1 bit and lsb of speed is not set
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   219
	 * for the switch() below to work
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   220
	 */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   221
	if ((spd & 1) || (dplx & ~1))
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   222
		goto err_inval;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   223
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   224
	/* Fiber NICs only allow 1000 gbps Full duplex */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   225
	if ((adapter->hw.phy.media_type == e1000_media_type_fiber) &&
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   226
	    (spd != SPEED_1000) && (dplx != DUPLEX_FULL)) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   227
		goto err_inval;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   228
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   229
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   230
	switch (spd + dplx) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   231
	case SPEED_10 + DUPLEX_HALF:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   232
		mac->forced_speed_duplex = ADVERTISE_10_HALF;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   233
		break;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   234
	case SPEED_10 + DUPLEX_FULL:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   235
		mac->forced_speed_duplex = ADVERTISE_10_FULL;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   236
		break;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   237
	case SPEED_100 + DUPLEX_HALF:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   238
		mac->forced_speed_duplex = ADVERTISE_100_HALF;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   239
		break;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   240
	case SPEED_100 + DUPLEX_FULL:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   241
		mac->forced_speed_duplex = ADVERTISE_100_FULL;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   242
		break;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   243
	case SPEED_1000 + DUPLEX_FULL:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   244
		mac->autoneg = 1;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   245
		adapter->hw.phy.autoneg_advertised = ADVERTISE_1000_FULL;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   246
		break;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   247
	case SPEED_1000 + DUPLEX_HALF:	/* not supported */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   248
	default:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   249
		goto err_inval;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   250
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   251
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   252
	/* clear MDI, MDI(-X) override is only allowed when autoneg enabled */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   253
	adapter->hw.phy.mdix = AUTO_ALL_MODES;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   254
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   255
	return 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   256
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   257
err_inval:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   258
	e_err("Unsupported Speed/Duplex configuration\n");
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   259
	return -EINVAL;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   260
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   261
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   262
static int e1000_set_settings(struct net_device *netdev,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   263
			      struct ethtool_cmd *ecmd)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   264
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   265
	struct e1000_adapter *adapter = netdev_priv(netdev);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   266
	struct e1000_hw *hw = &adapter->hw;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   267
	int ret_val = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   268
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   269
	pm_runtime_get_sync(netdev->dev.parent);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   270
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   271
	/* When SoL/IDER sessions are active, autoneg/speed/duplex
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   272
	 * cannot be changed
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   273
	 */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   274
	if (hw->phy.ops.check_reset_block &&
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   275
	    hw->phy.ops.check_reset_block(hw)) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   276
		e_err("Cannot change link characteristics when SoL/IDER is active.\n");
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   277
		ret_val = -EINVAL;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   278
		goto out;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   279
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   280
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   281
	/* MDI setting is only allowed when autoneg enabled because
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   282
	 * some hardware doesn't allow MDI setting when speed or
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   283
	 * duplex is forced.
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   284
	 */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   285
	if (ecmd->eth_tp_mdix_ctrl) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   286
		if (hw->phy.media_type != e1000_media_type_copper) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   287
			ret_val = -EOPNOTSUPP;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   288
			goto out;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   289
		}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   290
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   291
		if ((ecmd->eth_tp_mdix_ctrl != ETH_TP_MDI_AUTO) &&
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   292
		    (ecmd->autoneg != AUTONEG_ENABLE)) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   293
			e_err("forcing MDI/MDI-X state is not supported when link speed and/or duplex are forced\n");
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   294
			ret_val = -EINVAL;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   295
			goto out;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   296
		}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   297
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   298
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   299
	while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   300
		usleep_range(1000, 2000);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   301
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   302
	if (ecmd->autoneg == AUTONEG_ENABLE) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   303
		hw->mac.autoneg = 1;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   304
		if (hw->phy.media_type == e1000_media_type_fiber)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   305
			hw->phy.autoneg_advertised = ADVERTISED_1000baseT_Full |
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   306
			    ADVERTISED_FIBRE | ADVERTISED_Autoneg;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   307
		else
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   308
			hw->phy.autoneg_advertised = ecmd->advertising |
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   309
			    ADVERTISED_TP | ADVERTISED_Autoneg;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   310
		ecmd->advertising = hw->phy.autoneg_advertised;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   311
		if (adapter->fc_autoneg)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   312
			hw->fc.requested_mode = e1000_fc_default;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   313
	} else {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   314
		u32 speed = ethtool_cmd_speed(ecmd);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   315
		/* calling this overrides forced MDI setting */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   316
		if (e1000_set_spd_dplx(adapter, speed, ecmd->duplex)) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   317
			ret_val = -EINVAL;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   318
			goto out;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   319
		}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   320
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   321
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   322
	/* MDI-X => 2; MDI => 1; Auto => 3 */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   323
	if (ecmd->eth_tp_mdix_ctrl) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   324
		/* fix up the value for auto (3 => 0) as zero is mapped
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   325
		 * internally to auto
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   326
		 */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   327
		if (ecmd->eth_tp_mdix_ctrl == ETH_TP_MDI_AUTO)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   328
			hw->phy.mdix = AUTO_ALL_MODES;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   329
		else
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   330
			hw->phy.mdix = ecmd->eth_tp_mdix_ctrl;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   331
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   332
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   333
	/* reset the link */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   334
	if (netif_running(adapter->netdev)) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   335
		e1000e_down(adapter);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   336
		e1000e_up(adapter);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   337
	} else {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   338
		e1000e_reset(adapter);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   339
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   340
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   341
out:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   342
	pm_runtime_put_sync(netdev->dev.parent);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   343
	clear_bit(__E1000_RESETTING, &adapter->state);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   344
	return ret_val;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   345
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   346
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   347
static void e1000_get_pauseparam(struct net_device *netdev,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   348
				 struct ethtool_pauseparam *pause)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   349
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   350
	struct e1000_adapter *adapter = netdev_priv(netdev);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   351
	struct e1000_hw *hw = &adapter->hw;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   352
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   353
	pause->autoneg =
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   354
	    (adapter->fc_autoneg ? AUTONEG_ENABLE : AUTONEG_DISABLE);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   355
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   356
	if (hw->fc.current_mode == e1000_fc_rx_pause) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   357
		pause->rx_pause = 1;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   358
	} else if (hw->fc.current_mode == e1000_fc_tx_pause) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   359
		pause->tx_pause = 1;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   360
	} else if (hw->fc.current_mode == e1000_fc_full) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   361
		pause->rx_pause = 1;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   362
		pause->tx_pause = 1;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   363
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   364
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   365
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   366
static int e1000_set_pauseparam(struct net_device *netdev,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   367
				struct ethtool_pauseparam *pause)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   368
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   369
	struct e1000_adapter *adapter = netdev_priv(netdev);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   370
	struct e1000_hw *hw = &adapter->hw;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   371
	int retval = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   372
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   373
	adapter->fc_autoneg = pause->autoneg;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   374
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   375
	while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   376
		usleep_range(1000, 2000);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   377
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   378
	pm_runtime_get_sync(netdev->dev.parent);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   379
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   380
	if (adapter->fc_autoneg == AUTONEG_ENABLE) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   381
		hw->fc.requested_mode = e1000_fc_default;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   382
		if (netif_running(adapter->netdev)) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   383
			e1000e_down(adapter);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   384
			e1000e_up(adapter);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   385
		} else {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   386
			e1000e_reset(adapter);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   387
		}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   388
	} else {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   389
		if (pause->rx_pause && pause->tx_pause)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   390
			hw->fc.requested_mode = e1000_fc_full;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   391
		else if (pause->rx_pause && !pause->tx_pause)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   392
			hw->fc.requested_mode = e1000_fc_rx_pause;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   393
		else if (!pause->rx_pause && pause->tx_pause)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   394
			hw->fc.requested_mode = e1000_fc_tx_pause;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   395
		else if (!pause->rx_pause && !pause->tx_pause)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   396
			hw->fc.requested_mode = e1000_fc_none;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   397
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   398
		hw->fc.current_mode = hw->fc.requested_mode;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   399
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   400
		if (hw->phy.media_type == e1000_media_type_fiber) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   401
			retval = hw->mac.ops.setup_link(hw);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   402
			/* implicit goto out */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   403
		} else {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   404
			retval = e1000e_force_mac_fc(hw);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   405
			if (retval)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   406
				goto out;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   407
			e1000e_set_fc_watermarks(hw);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   408
		}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   409
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   410
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   411
out:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   412
	pm_runtime_put_sync(netdev->dev.parent);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   413
	clear_bit(__E1000_RESETTING, &adapter->state);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   414
	return retval;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   415
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   416
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   417
static u32 e1000_get_msglevel(struct net_device *netdev)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   418
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   419
	struct e1000_adapter *adapter = netdev_priv(netdev);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   420
	return adapter->msg_enable;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   421
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   422
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   423
static void e1000_set_msglevel(struct net_device *netdev, u32 data)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   424
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   425
	struct e1000_adapter *adapter = netdev_priv(netdev);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   426
	adapter->msg_enable = data;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   427
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   428
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   429
static int e1000_get_regs_len(struct net_device __always_unused *netdev)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   430
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   431
#define E1000_REGS_LEN 32	/* overestimate */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   432
	return E1000_REGS_LEN * sizeof(u32);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   433
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   434
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   435
static void e1000_get_regs(struct net_device *netdev,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   436
			   struct ethtool_regs *regs, void *p)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   437
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   438
	struct e1000_adapter *adapter = netdev_priv(netdev);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   439
	struct e1000_hw *hw = &adapter->hw;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   440
	u32 *regs_buff = p;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   441
	u16 phy_data;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   442
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   443
	pm_runtime_get_sync(netdev->dev.parent);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   444
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   445
	memset(p, 0, E1000_REGS_LEN * sizeof(u32));
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   446
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   447
	regs->version = (1 << 24) | (adapter->pdev->revision << 16) |
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   448
	    adapter->pdev->device;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   449
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   450
	regs_buff[0] = er32(CTRL);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   451
	regs_buff[1] = er32(STATUS);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   452
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   453
	regs_buff[2] = er32(RCTL);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   454
	regs_buff[3] = er32(RDLEN(0));
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   455
	regs_buff[4] = er32(RDH(0));
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   456
	regs_buff[5] = er32(RDT(0));
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   457
	regs_buff[6] = er32(RDTR);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   458
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   459
	regs_buff[7] = er32(TCTL);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   460
	regs_buff[8] = er32(TDLEN(0));
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   461
	regs_buff[9] = er32(TDH(0));
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   462
	regs_buff[10] = er32(TDT(0));
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   463
	regs_buff[11] = er32(TIDV);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   464
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   465
	regs_buff[12] = adapter->hw.phy.type;	/* PHY type (IGP=1, M88=0) */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   466
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   467
	/* ethtool doesn't use anything past this point, so all this
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   468
	 * code is likely legacy junk for apps that may or may not exist
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   469
	 */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   470
	if (hw->phy.type == e1000_phy_m88) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   471
		e1e_rphy(hw, M88E1000_PHY_SPEC_STATUS, &phy_data);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   472
		regs_buff[13] = (u32)phy_data; /* cable length */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   473
		regs_buff[14] = 0;  /* Dummy (to align w/ IGP phy reg dump) */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   474
		regs_buff[15] = 0;  /* Dummy (to align w/ IGP phy reg dump) */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   475
		regs_buff[16] = 0;  /* Dummy (to align w/ IGP phy reg dump) */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   476
		e1e_rphy(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   477
		regs_buff[17] = (u32)phy_data; /* extended 10bt distance */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   478
		regs_buff[18] = regs_buff[13]; /* cable polarity */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   479
		regs_buff[19] = 0;  /* Dummy (to align w/ IGP phy reg dump) */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   480
		regs_buff[20] = regs_buff[17]; /* polarity correction */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   481
		/* phy receive errors */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   482
		regs_buff[22] = adapter->phy_stats.receive_errors;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   483
		regs_buff[23] = regs_buff[13]; /* mdix mode */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   484
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   485
	regs_buff[21] = 0;	/* was idle_errors */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   486
	e1e_rphy(hw, MII_STAT1000, &phy_data);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   487
	regs_buff[24] = (u32)phy_data;	/* phy local receiver status */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   488
	regs_buff[25] = regs_buff[24];	/* phy remote receiver status */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   489
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   490
	pm_runtime_put_sync(netdev->dev.parent);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   491
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   492
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   493
static int e1000_get_eeprom_len(struct net_device *netdev)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   494
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   495
	struct e1000_adapter *adapter = netdev_priv(netdev);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   496
	return adapter->hw.nvm.word_size * 2;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   497
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   498
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   499
static int e1000_get_eeprom(struct net_device *netdev,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   500
			    struct ethtool_eeprom *eeprom, u8 *bytes)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   501
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   502
	struct e1000_adapter *adapter = netdev_priv(netdev);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   503
	struct e1000_hw *hw = &adapter->hw;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   504
	u16 *eeprom_buff;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   505
	int first_word;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   506
	int last_word;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   507
	int ret_val = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   508
	u16 i;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   509
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   510
	if (eeprom->len == 0)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   511
		return -EINVAL;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   512
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   513
	eeprom->magic = adapter->pdev->vendor | (adapter->pdev->device << 16);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   514
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   515
	first_word = eeprom->offset >> 1;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   516
	last_word = (eeprom->offset + eeprom->len - 1) >> 1;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   517
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   518
	eeprom_buff = kmalloc(sizeof(u16) * (last_word - first_word + 1),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   519
			      GFP_KERNEL);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   520
	if (!eeprom_buff)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   521
		return -ENOMEM;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   522
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   523
	pm_runtime_get_sync(netdev->dev.parent);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   524
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   525
	if (hw->nvm.type == e1000_nvm_eeprom_spi) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   526
		ret_val = e1000_read_nvm(hw, first_word,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   527
					 last_word - first_word + 1,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   528
					 eeprom_buff);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   529
	} else {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   530
		for (i = 0; i < last_word - first_word + 1; i++) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   531
			ret_val = e1000_read_nvm(hw, first_word + i, 1,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   532
						 &eeprom_buff[i]);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   533
			if (ret_val)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   534
				break;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   535
		}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   536
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   537
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   538
	pm_runtime_put_sync(netdev->dev.parent);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   539
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   540
	if (ret_val) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   541
		/* a read error occurred, throw away the result */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   542
		memset(eeprom_buff, 0xff, sizeof(u16) *
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   543
		       (last_word - first_word + 1));
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   544
	} else {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   545
		/* Device's eeprom is always little-endian, word addressable */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   546
		for (i = 0; i < last_word - first_word + 1; i++)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   547
			le16_to_cpus(&eeprom_buff[i]);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   548
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   549
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   550
	memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 1), eeprom->len);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   551
	kfree(eeprom_buff);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   552
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   553
	return ret_val;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   554
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   555
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   556
static int e1000_set_eeprom(struct net_device *netdev,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   557
			    struct ethtool_eeprom *eeprom, u8 *bytes)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   558
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   559
	struct e1000_adapter *adapter = netdev_priv(netdev);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   560
	struct e1000_hw *hw = &adapter->hw;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   561
	u16 *eeprom_buff;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   562
	void *ptr;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   563
	int max_len;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   564
	int first_word;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   565
	int last_word;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   566
	int ret_val = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   567
	u16 i;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   568
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   569
	if (eeprom->len == 0)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   570
		return -EOPNOTSUPP;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   571
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   572
	if (eeprom->magic !=
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   573
	    (adapter->pdev->vendor | (adapter->pdev->device << 16)))
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   574
		return -EFAULT;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   575
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   576
	if (adapter->flags & FLAG_READ_ONLY_NVM)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   577
		return -EINVAL;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   578
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   579
	max_len = hw->nvm.word_size * 2;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   580
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   581
	first_word = eeprom->offset >> 1;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   582
	last_word = (eeprom->offset + eeprom->len - 1) >> 1;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   583
	eeprom_buff = kmalloc(max_len, GFP_KERNEL);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   584
	if (!eeprom_buff)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   585
		return -ENOMEM;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   586
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   587
	ptr = (void *)eeprom_buff;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   588
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   589
	pm_runtime_get_sync(netdev->dev.parent);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   590
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   591
	if (eeprom->offset & 1) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   592
		/* need read/modify/write of first changed EEPROM word */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   593
		/* only the second byte of the word is being modified */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   594
		ret_val = e1000_read_nvm(hw, first_word, 1, &eeprom_buff[0]);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   595
		ptr++;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   596
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   597
	if (((eeprom->offset + eeprom->len) & 1) && (!ret_val))
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   598
		/* need read/modify/write of last changed EEPROM word */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   599
		/* only the first byte of the word is being modified */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   600
		ret_val = e1000_read_nvm(hw, last_word, 1,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   601
					 &eeprom_buff[last_word - first_word]);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   602
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   603
	if (ret_val)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   604
		goto out;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   605
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   606
	/* Device's eeprom is always little-endian, word addressable */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   607
	for (i = 0; i < last_word - first_word + 1; i++)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   608
		le16_to_cpus(&eeprom_buff[i]);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   609
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   610
	memcpy(ptr, bytes, eeprom->len);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   611
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   612
	for (i = 0; i < last_word - first_word + 1; i++)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   613
		cpu_to_le16s(&eeprom_buff[i]);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   614
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   615
	ret_val = e1000_write_nvm(hw, first_word,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   616
				  last_word - first_word + 1, eeprom_buff);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   617
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   618
	if (ret_val)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   619
		goto out;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   620
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   621
	/* Update the checksum over the first part of the EEPROM if needed
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   622
	 * and flush shadow RAM for applicable controllers
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   623
	 */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   624
	if ((first_word <= NVM_CHECKSUM_REG) ||
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   625
	    (hw->mac.type == e1000_82583) ||
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   626
	    (hw->mac.type == e1000_82574) ||
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   627
	    (hw->mac.type == e1000_82573))
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   628
		ret_val = e1000e_update_nvm_checksum(hw);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   629
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   630
out:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   631
	pm_runtime_put_sync(netdev->dev.parent);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   632
	kfree(eeprom_buff);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   633
	return ret_val;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   634
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   635
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   636
static void e1000_get_drvinfo(struct net_device *netdev,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   637
			      struct ethtool_drvinfo *drvinfo)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   638
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   639
	struct e1000_adapter *adapter = netdev_priv(netdev);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   640
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   641
	strlcpy(drvinfo->driver, e1000e_driver_name, sizeof(drvinfo->driver));
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   642
	strlcpy(drvinfo->version, e1000e_driver_version,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   643
		sizeof(drvinfo->version));
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   644
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   645
	/* EEPROM image version # is reported as firmware version # for
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   646
	 * PCI-E controllers
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   647
	 */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   648
	snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   649
		 "%d.%d-%d",
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   650
		 (adapter->eeprom_vers & 0xF000) >> 12,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   651
		 (adapter->eeprom_vers & 0x0FF0) >> 4,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   652
		 (adapter->eeprom_vers & 0x000F));
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   653
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   654
	strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   655
		sizeof(drvinfo->bus_info));
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   656
	drvinfo->regdump_len = e1000_get_regs_len(netdev);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   657
	drvinfo->eedump_len = e1000_get_eeprom_len(netdev);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   658
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   659
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   660
static void e1000_get_ringparam(struct net_device *netdev,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   661
				struct ethtool_ringparam *ring)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   662
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   663
	struct e1000_adapter *adapter = netdev_priv(netdev);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   664
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   665
	ring->rx_max_pending = E1000_MAX_RXD;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   666
	ring->tx_max_pending = E1000_MAX_TXD;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   667
	ring->rx_pending = adapter->rx_ring_count;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   668
	ring->tx_pending = adapter->tx_ring_count;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   669
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   670
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   671
static int e1000_set_ringparam(struct net_device *netdev,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   672
			       struct ethtool_ringparam *ring)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   673
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   674
	struct e1000_adapter *adapter = netdev_priv(netdev);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   675
	struct e1000_ring *temp_tx = NULL, *temp_rx = NULL;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   676
	int err = 0, size = sizeof(struct e1000_ring);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   677
	bool set_tx = false, set_rx = false;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   678
	u16 new_rx_count, new_tx_count;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   679
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   680
	if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   681
		return -EINVAL;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   682
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   683
	new_rx_count = clamp_t(u32, ring->rx_pending, E1000_MIN_RXD,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   684
			       E1000_MAX_RXD);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   685
	new_rx_count = ALIGN(new_rx_count, REQ_RX_DESCRIPTOR_MULTIPLE);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   686
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   687
	new_tx_count = clamp_t(u32, ring->tx_pending, E1000_MIN_TXD,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   688
			       E1000_MAX_TXD);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   689
	new_tx_count = ALIGN(new_tx_count, REQ_TX_DESCRIPTOR_MULTIPLE);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   690
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   691
	if ((new_tx_count == adapter->tx_ring_count) &&
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   692
	    (new_rx_count == adapter->rx_ring_count))
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   693
		/* nothing to do */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   694
		return 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   695
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   696
	while (test_and_set_bit(__E1000_RESETTING, &adapter->state))
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   697
		usleep_range(1000, 2000);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   698
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   699
	if (!netif_running(adapter->netdev)) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   700
		/* Set counts now and allocate resources during open() */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   701
		adapter->tx_ring->count = new_tx_count;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   702
		adapter->rx_ring->count = new_rx_count;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   703
		adapter->tx_ring_count = new_tx_count;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   704
		adapter->rx_ring_count = new_rx_count;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   705
		goto clear_reset;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   706
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   707
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   708
	set_tx = (new_tx_count != adapter->tx_ring_count);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   709
	set_rx = (new_rx_count != adapter->rx_ring_count);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   710
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   711
	/* Allocate temporary storage for ring updates */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   712
	if (set_tx) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   713
		temp_tx = vmalloc(size);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   714
		if (!temp_tx) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   715
			err = -ENOMEM;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   716
			goto free_temp;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   717
		}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   718
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   719
	if (set_rx) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   720
		temp_rx = vmalloc(size);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   721
		if (!temp_rx) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   722
			err = -ENOMEM;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   723
			goto free_temp;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   724
		}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   725
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   726
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   727
	pm_runtime_get_sync(netdev->dev.parent);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   728
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   729
	e1000e_down(adapter);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   730
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   731
	/* We can't just free everything and then setup again, because the
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   732
	 * ISRs in MSI-X mode get passed pointers to the Tx and Rx ring
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   733
	 * structs.  First, attempt to allocate new resources...
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   734
	 */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   735
	if (set_tx) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   736
		memcpy(temp_tx, adapter->tx_ring, size);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   737
		temp_tx->count = new_tx_count;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   738
		err = e1000e_setup_tx_resources(temp_tx);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   739
		if (err)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   740
			goto err_setup;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   741
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   742
	if (set_rx) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   743
		memcpy(temp_rx, adapter->rx_ring, size);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   744
		temp_rx->count = new_rx_count;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   745
		err = e1000e_setup_rx_resources(temp_rx);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   746
		if (err)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   747
			goto err_setup_rx;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   748
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   749
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   750
	/* ...then free the old resources and copy back any new ring data */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   751
	if (set_tx) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   752
		e1000e_free_tx_resources(adapter->tx_ring);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   753
		memcpy(adapter->tx_ring, temp_tx, size);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   754
		adapter->tx_ring_count = new_tx_count;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   755
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   756
	if (set_rx) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   757
		e1000e_free_rx_resources(adapter->rx_ring);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   758
		memcpy(adapter->rx_ring, temp_rx, size);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   759
		adapter->rx_ring_count = new_rx_count;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   760
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   761
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   762
err_setup_rx:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   763
	if (err && set_tx)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   764
		e1000e_free_tx_resources(temp_tx);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   765
err_setup:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   766
	e1000e_up(adapter);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   767
	pm_runtime_put_sync(netdev->dev.parent);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   768
free_temp:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   769
	vfree(temp_tx);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   770
	vfree(temp_rx);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   771
clear_reset:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   772
	clear_bit(__E1000_RESETTING, &adapter->state);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   773
	return err;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   774
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   775
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   776
static bool reg_pattern_test(struct e1000_adapter *adapter, u64 *data,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   777
			     int reg, int offset, u32 mask, u32 write)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   778
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   779
	u32 pat, val;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   780
	static const u32 test[] = {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   781
		0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   782
	};
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   783
	for (pat = 0; pat < ARRAY_SIZE(test); pat++) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   784
		E1000_WRITE_REG_ARRAY(&adapter->hw, reg, offset,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   785
				      (test[pat] & write));
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   786
		val = E1000_READ_REG_ARRAY(&adapter->hw, reg, offset);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   787
		if (val != (test[pat] & write & mask)) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   788
			e_err("pattern test failed (reg 0x%05X): got 0x%08X expected 0x%08X\n",
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   789
			      reg + (offset << 2), val,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   790
			      (test[pat] & write & mask));
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   791
			*data = reg;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   792
			return 1;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   793
		}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   794
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   795
	return 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   796
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   797
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   798
static bool reg_set_and_check(struct e1000_adapter *adapter, u64 *data,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   799
			      int reg, u32 mask, u32 write)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   800
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   801
	u32 val;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   802
	__ew32(&adapter->hw, reg, write & mask);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   803
	val = __er32(&adapter->hw, reg);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   804
	if ((write & mask) != (val & mask)) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   805
		e_err("set/check test failed (reg 0x%05X): got 0x%08X expected 0x%08X\n",
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   806
		      reg, (val & mask), (write & mask));
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   807
		*data = reg;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   808
		return 1;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   809
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   810
	return 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   811
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   812
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   813
#define REG_PATTERN_TEST_ARRAY(reg, offset, mask, write)                       \
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   814
	do {                                                                   \
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   815
		if (reg_pattern_test(adapter, data, reg, offset, mask, write)) \
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   816
			return 1;                                              \
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   817
	} while (0)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   818
#define REG_PATTERN_TEST(reg, mask, write)                                     \
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   819
	REG_PATTERN_TEST_ARRAY(reg, 0, mask, write)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   820
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   821
#define REG_SET_AND_CHECK(reg, mask, write)                                    \
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   822
	do {                                                                   \
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   823
		if (reg_set_and_check(adapter, data, reg, mask, write))        \
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   824
			return 1;                                              \
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   825
	} while (0)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   826
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   827
static int e1000_reg_test(struct e1000_adapter *adapter, u64 *data)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   828
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   829
	struct e1000_hw *hw = &adapter->hw;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   830
	struct e1000_mac_info *mac = &adapter->hw.mac;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   831
	u32 value;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   832
	u32 before;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   833
	u32 after;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   834
	u32 i;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   835
	u32 toggle;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   836
	u32 mask;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   837
	u32 wlock_mac = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   838
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   839
	/* The status register is Read Only, so a write should fail.
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   840
	 * Some bits that get toggled are ignored.  There are several bits
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   841
	 * on newer hardware that are r/w.
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   842
	 */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   843
	switch (mac->type) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   844
	case e1000_82571:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   845
	case e1000_82572:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   846
	case e1000_80003es2lan:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   847
		toggle = 0x7FFFF3FF;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   848
		break;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   849
	default:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   850
		toggle = 0x7FFFF033;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   851
		break;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   852
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   853
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   854
	before = er32(STATUS);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   855
	value = (er32(STATUS) & toggle);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   856
	ew32(STATUS, toggle);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   857
	after = er32(STATUS) & toggle;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   858
	if (value != after) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   859
		e_err("failed STATUS register test got: 0x%08X expected: 0x%08X\n",
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   860
		      after, value);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   861
		*data = 1;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   862
		return 1;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   863
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   864
	/* restore previous status */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   865
	ew32(STATUS, before);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   866
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   867
	if (!(adapter->flags & FLAG_IS_ICH)) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   868
		REG_PATTERN_TEST(E1000_FCAL, 0xFFFFFFFF, 0xFFFFFFFF);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   869
		REG_PATTERN_TEST(E1000_FCAH, 0x0000FFFF, 0xFFFFFFFF);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   870
		REG_PATTERN_TEST(E1000_FCT, 0x0000FFFF, 0xFFFFFFFF);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   871
		REG_PATTERN_TEST(E1000_VET, 0x0000FFFF, 0xFFFFFFFF);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   872
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   873
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   874
	REG_PATTERN_TEST(E1000_RDTR, 0x0000FFFF, 0xFFFFFFFF);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   875
	REG_PATTERN_TEST(E1000_RDBAH(0), 0xFFFFFFFF, 0xFFFFFFFF);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   876
	REG_PATTERN_TEST(E1000_RDLEN(0), 0x000FFF80, 0x000FFFFF);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   877
	REG_PATTERN_TEST(E1000_RDH(0), 0x0000FFFF, 0x0000FFFF);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   878
	REG_PATTERN_TEST(E1000_RDT(0), 0x0000FFFF, 0x0000FFFF);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   879
	REG_PATTERN_TEST(E1000_FCRTH, 0x0000FFF8, 0x0000FFF8);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   880
	REG_PATTERN_TEST(E1000_FCTTV, 0x0000FFFF, 0x0000FFFF);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   881
	REG_PATTERN_TEST(E1000_TIPG, 0x3FFFFFFF, 0x3FFFFFFF);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   882
	REG_PATTERN_TEST(E1000_TDBAH(0), 0xFFFFFFFF, 0xFFFFFFFF);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   883
	REG_PATTERN_TEST(E1000_TDLEN(0), 0x000FFF80, 0x000FFFFF);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   884
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   885
	REG_SET_AND_CHECK(E1000_RCTL, 0xFFFFFFFF, 0x00000000);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   886
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   887
	before = ((adapter->flags & FLAG_IS_ICH) ? 0x06C3B33E : 0x06DFB3FE);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   888
	REG_SET_AND_CHECK(E1000_RCTL, before, 0x003FFFFB);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   889
	REG_SET_AND_CHECK(E1000_TCTL, 0xFFFFFFFF, 0x00000000);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   890
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   891
	REG_SET_AND_CHECK(E1000_RCTL, before, 0xFFFFFFFF);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   892
	REG_PATTERN_TEST(E1000_RDBAL(0), 0xFFFFFFF0, 0xFFFFFFFF);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   893
	if (!(adapter->flags & FLAG_IS_ICH))
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   894
		REG_PATTERN_TEST(E1000_TXCW, 0xC000FFFF, 0x0000FFFF);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   895
	REG_PATTERN_TEST(E1000_TDBAL(0), 0xFFFFFFF0, 0xFFFFFFFF);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   896
	REG_PATTERN_TEST(E1000_TIDV, 0x0000FFFF, 0x0000FFFF);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   897
	mask = 0x8003FFFF;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   898
	switch (mac->type) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   899
	case e1000_ich10lan:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   900
	case e1000_pchlan:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   901
	case e1000_pch2lan:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   902
	case e1000_pch_lpt:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   903
		mask |= (1 << 18);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   904
		break;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   905
	default:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   906
		break;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   907
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   908
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   909
	if (mac->type == e1000_pch_lpt)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   910
		wlock_mac = (er32(FWSM) & E1000_FWSM_WLOCK_MAC_MASK) >>
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   911
		    E1000_FWSM_WLOCK_MAC_SHIFT;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   912
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   913
	for (i = 0; i < mac->rar_entry_count; i++) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   914
		if (mac->type == e1000_pch_lpt) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   915
			/* Cannot test write-protected SHRAL[n] registers */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   916
			if ((wlock_mac == 1) || (wlock_mac && (i > wlock_mac)))
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   917
				continue;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   918
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   919
			/* SHRAH[9] different than the others */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   920
			if (i == 10)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   921
				mask |= (1 << 30);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   922
			else
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   923
				mask &= ~(1 << 30);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   924
		}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   925
		if (mac->type == e1000_pch2lan) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   926
			/* SHRAH[0,1,2] different than previous */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   927
			if (i == 7)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   928
				mask &= 0xFFF4FFFF;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   929
			/* SHRAH[3] different than SHRAH[0,1,2] */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   930
			if (i == 10)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   931
				mask |= (1 << 30);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   932
		}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   933
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   934
		REG_PATTERN_TEST_ARRAY(E1000_RA, ((i << 1) + 1), mask,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   935
				       0xFFFFFFFF);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   936
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   937
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   938
	for (i = 0; i < mac->mta_reg_count; i++)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   939
		REG_PATTERN_TEST_ARRAY(E1000_MTA, i, 0xFFFFFFFF, 0xFFFFFFFF);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   940
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   941
	*data = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   942
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   943
	return 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   944
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   945
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   946
static int e1000_eeprom_test(struct e1000_adapter *adapter, u64 *data)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   947
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   948
	u16 temp;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   949
	u16 checksum = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   950
	u16 i;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   951
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   952
	*data = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   953
	/* Read and add up the contents of the EEPROM */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   954
	for (i = 0; i < (NVM_CHECKSUM_REG + 1); i++) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   955
		if ((e1000_read_nvm(&adapter->hw, i, 1, &temp)) < 0) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   956
			*data = 1;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   957
			return *data;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   958
		}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   959
		checksum += temp;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   960
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   961
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   962
	/* If Checksum is not Correct return error else test passed */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   963
	if ((checksum != (u16)NVM_SUM) && !(*data))
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   964
		*data = 2;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   965
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   966
	return *data;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   967
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   968
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   969
static irqreturn_t e1000_test_intr(int __always_unused irq, void *data)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   970
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   971
	struct net_device *netdev = (struct net_device *)data;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   972
	struct e1000_adapter *adapter = netdev_priv(netdev);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   973
	struct e1000_hw *hw = &adapter->hw;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   974
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   975
	adapter->test_icr |= er32(ICR);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   976
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   977
	return IRQ_HANDLED;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   978
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   979
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   980
static int e1000_intr_test(struct e1000_adapter *adapter, u64 *data)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   981
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   982
	struct net_device *netdev = adapter->netdev;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   983
	struct e1000_hw *hw = &adapter->hw;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   984
	u32 mask;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   985
	u32 shared_int = 1;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   986
	u32 irq = adapter->pdev->irq;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   987
	int i;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   988
	int ret_val = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   989
	int int_mode = E1000E_INT_MODE_LEGACY;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   990
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   991
	*data = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   992
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   993
	/* NOTE: we don't test MSI/MSI-X interrupts here, yet */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   994
	if (adapter->int_mode == E1000E_INT_MODE_MSIX) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   995
		int_mode = adapter->int_mode;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   996
		e1000e_reset_interrupt_capability(adapter);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   997
		adapter->int_mode = E1000E_INT_MODE_LEGACY;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   998
		e1000e_set_interrupt_capability(adapter);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
   999
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1000
	/* Hook up test interrupt handler just for this test */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1001
	if (!request_irq(irq, e1000_test_intr, IRQF_PROBE_SHARED, netdev->name,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1002
			 netdev)) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1003
		shared_int = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1004
	} else if (request_irq(irq, e1000_test_intr, IRQF_SHARED, netdev->name,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1005
			       netdev)) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1006
		*data = 1;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1007
		ret_val = -1;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1008
		goto out;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1009
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1010
	e_info("testing %s interrupt\n", (shared_int ? "shared" : "unshared"));
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1011
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1012
	/* Disable all the interrupts */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1013
	ew32(IMC, 0xFFFFFFFF);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1014
	e1e_flush();
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1015
	usleep_range(10000, 20000);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1016
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1017
	/* Test each interrupt */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1018
	for (i = 0; i < 10; i++) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1019
		/* Interrupt to test */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1020
		mask = 1 << i;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1021
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1022
		if (adapter->flags & FLAG_IS_ICH) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1023
			switch (mask) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1024
			case E1000_ICR_RXSEQ:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1025
				continue;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1026
			case 0x00000100:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1027
				if (adapter->hw.mac.type == e1000_ich8lan ||
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1028
				    adapter->hw.mac.type == e1000_ich9lan)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1029
					continue;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1030
				break;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1031
			default:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1032
				break;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1033
			}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1034
		}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1035
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1036
		if (!shared_int) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1037
			/* Disable the interrupt to be reported in
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1038
			 * the cause register and then force the same
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1039
			 * interrupt and see if one gets posted.  If
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1040
			 * an interrupt was posted to the bus, the
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1041
			 * test failed.
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1042
			 */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1043
			adapter->test_icr = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1044
			ew32(IMC, mask);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1045
			ew32(ICS, mask);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1046
			e1e_flush();
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1047
			usleep_range(10000, 20000);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1048
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1049
			if (adapter->test_icr & mask) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1050
				*data = 3;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1051
				break;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1052
			}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1053
		}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1054
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1055
		/* Enable the interrupt to be reported in
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1056
		 * the cause register and then force the same
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1057
		 * interrupt and see if one gets posted.  If
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1058
		 * an interrupt was not posted to the bus, the
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1059
		 * test failed.
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1060
		 */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1061
		adapter->test_icr = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1062
		ew32(IMS, mask);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1063
		ew32(ICS, mask);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1064
		e1e_flush();
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1065
		usleep_range(10000, 20000);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1066
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1067
		if (!(adapter->test_icr & mask)) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1068
			*data = 4;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1069
			break;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1070
		}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1071
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1072
		if (!shared_int) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1073
			/* Disable the other interrupts to be reported in
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1074
			 * the cause register and then force the other
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1075
			 * interrupts and see if any get posted.  If
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1076
			 * an interrupt was posted to the bus, the
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1077
			 * test failed.
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1078
			 */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1079
			adapter->test_icr = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1080
			ew32(IMC, ~mask & 0x00007FFF);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1081
			ew32(ICS, ~mask & 0x00007FFF);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1082
			e1e_flush();
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1083
			usleep_range(10000, 20000);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1084
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1085
			if (adapter->test_icr) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1086
				*data = 5;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1087
				break;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1088
			}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1089
		}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1090
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1091
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1092
	/* Disable all the interrupts */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1093
	ew32(IMC, 0xFFFFFFFF);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1094
	e1e_flush();
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1095
	usleep_range(10000, 20000);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1096
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1097
	/* Unhook test interrupt handler */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1098
	free_irq(irq, netdev);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1099
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1100
out:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1101
	if (int_mode == E1000E_INT_MODE_MSIX) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1102
		e1000e_reset_interrupt_capability(adapter);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1103
		adapter->int_mode = int_mode;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1104
		e1000e_set_interrupt_capability(adapter);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1105
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1106
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1107
	return ret_val;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1108
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1109
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1110
static void e1000_free_desc_rings(struct e1000_adapter *adapter)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1111
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1112
	struct e1000_ring *tx_ring = &adapter->test_tx_ring;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1113
	struct e1000_ring *rx_ring = &adapter->test_rx_ring;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1114
	struct pci_dev *pdev = adapter->pdev;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1115
	struct e1000_buffer *buffer_info;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1116
	int i;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1117
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1118
	if (tx_ring->desc && tx_ring->buffer_info) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1119
		for (i = 0; i < tx_ring->count; i++) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1120
			buffer_info = &tx_ring->buffer_info[i];
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1121
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1122
			if (buffer_info->dma)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1123
				dma_unmap_single(&pdev->dev,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1124
						 buffer_info->dma,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1125
						 buffer_info->length,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1126
						 DMA_TO_DEVICE);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1127
			if (buffer_info->skb)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1128
				dev_kfree_skb(buffer_info->skb);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1129
		}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1130
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1131
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1132
	if (rx_ring->desc && rx_ring->buffer_info) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1133
		for (i = 0; i < rx_ring->count; i++) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1134
			buffer_info = &rx_ring->buffer_info[i];
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1135
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1136
			if (buffer_info->dma)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1137
				dma_unmap_single(&pdev->dev,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1138
						 buffer_info->dma,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1139
						 2048, DMA_FROM_DEVICE);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1140
			if (buffer_info->skb)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1141
				dev_kfree_skb(buffer_info->skb);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1142
		}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1143
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1144
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1145
	if (tx_ring->desc) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1146
		dma_free_coherent(&pdev->dev, tx_ring->size, tx_ring->desc,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1147
				  tx_ring->dma);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1148
		tx_ring->desc = NULL;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1149
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1150
	if (rx_ring->desc) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1151
		dma_free_coherent(&pdev->dev, rx_ring->size, rx_ring->desc,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1152
				  rx_ring->dma);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1153
		rx_ring->desc = NULL;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1154
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1155
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1156
	kfree(tx_ring->buffer_info);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1157
	tx_ring->buffer_info = NULL;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1158
	kfree(rx_ring->buffer_info);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1159
	rx_ring->buffer_info = NULL;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1160
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1161
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1162
static int e1000_setup_desc_rings(struct e1000_adapter *adapter)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1163
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1164
	struct e1000_ring *tx_ring = &adapter->test_tx_ring;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1165
	struct e1000_ring *rx_ring = &adapter->test_rx_ring;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1166
	struct pci_dev *pdev = adapter->pdev;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1167
	struct e1000_hw *hw = &adapter->hw;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1168
	u32 rctl;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1169
	int i;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1170
	int ret_val;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1171
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1172
	/* Setup Tx descriptor ring and Tx buffers */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1173
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1174
	if (!tx_ring->count)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1175
		tx_ring->count = E1000_DEFAULT_TXD;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1176
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1177
	tx_ring->buffer_info = kcalloc(tx_ring->count,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1178
				       sizeof(struct e1000_buffer), GFP_KERNEL);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1179
	if (!tx_ring->buffer_info) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1180
		ret_val = 1;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1181
		goto err_nomem;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1182
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1183
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1184
	tx_ring->size = tx_ring->count * sizeof(struct e1000_tx_desc);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1185
	tx_ring->size = ALIGN(tx_ring->size, 4096);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1186
	tx_ring->desc = dma_alloc_coherent(&pdev->dev, tx_ring->size,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1187
					   &tx_ring->dma, GFP_KERNEL);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1188
	if (!tx_ring->desc) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1189
		ret_val = 2;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1190
		goto err_nomem;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1191
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1192
	tx_ring->next_to_use = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1193
	tx_ring->next_to_clean = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1194
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1195
	ew32(TDBAL(0), ((u64)tx_ring->dma & 0x00000000FFFFFFFF));
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1196
	ew32(TDBAH(0), ((u64)tx_ring->dma >> 32));
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1197
	ew32(TDLEN(0), tx_ring->count * sizeof(struct e1000_tx_desc));
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1198
	ew32(TDH(0), 0);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1199
	ew32(TDT(0), 0);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1200
	ew32(TCTL, E1000_TCTL_PSP | E1000_TCTL_EN | E1000_TCTL_MULR |
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1201
	     E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT |
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1202
	     E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1203
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1204
	for (i = 0; i < tx_ring->count; i++) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1205
		struct e1000_tx_desc *tx_desc = E1000_TX_DESC(*tx_ring, i);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1206
		struct sk_buff *skb;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1207
		unsigned int skb_size = 1024;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1208
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1209
		skb = alloc_skb(skb_size, GFP_KERNEL);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1210
		if (!skb) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1211
			ret_val = 3;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1212
			goto err_nomem;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1213
		}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1214
		skb_put(skb, skb_size);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1215
		tx_ring->buffer_info[i].skb = skb;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1216
		tx_ring->buffer_info[i].length = skb->len;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1217
		tx_ring->buffer_info[i].dma =
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1218
		    dma_map_single(&pdev->dev, skb->data, skb->len,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1219
				   DMA_TO_DEVICE);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1220
		if (dma_mapping_error(&pdev->dev,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1221
				      tx_ring->buffer_info[i].dma)) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1222
			ret_val = 4;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1223
			goto err_nomem;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1224
		}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1225
		tx_desc->buffer_addr = cpu_to_le64(tx_ring->buffer_info[i].dma);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1226
		tx_desc->lower.data = cpu_to_le32(skb->len);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1227
		tx_desc->lower.data |= cpu_to_le32(E1000_TXD_CMD_EOP |
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1228
						   E1000_TXD_CMD_IFCS |
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1229
						   E1000_TXD_CMD_RS);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1230
		tx_desc->upper.data = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1231
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1232
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1233
	/* Setup Rx descriptor ring and Rx buffers */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1234
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1235
	if (!rx_ring->count)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1236
		rx_ring->count = E1000_DEFAULT_RXD;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1237
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1238
	rx_ring->buffer_info = kcalloc(rx_ring->count,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1239
				       sizeof(struct e1000_buffer), GFP_KERNEL);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1240
	if (!rx_ring->buffer_info) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1241
		ret_val = 5;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1242
		goto err_nomem;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1243
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1244
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1245
	rx_ring->size = rx_ring->count * sizeof(union e1000_rx_desc_extended);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1246
	rx_ring->desc = dma_alloc_coherent(&pdev->dev, rx_ring->size,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1247
					   &rx_ring->dma, GFP_KERNEL);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1248
	if (!rx_ring->desc) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1249
		ret_val = 6;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1250
		goto err_nomem;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1251
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1252
	rx_ring->next_to_use = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1253
	rx_ring->next_to_clean = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1254
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1255
	rctl = er32(RCTL);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1256
	if (!(adapter->flags2 & FLAG2_NO_DISABLE_RX))
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1257
		ew32(RCTL, rctl & ~E1000_RCTL_EN);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1258
	ew32(RDBAL(0), ((u64)rx_ring->dma & 0xFFFFFFFF));
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1259
	ew32(RDBAH(0), ((u64)rx_ring->dma >> 32));
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1260
	ew32(RDLEN(0), rx_ring->size);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1261
	ew32(RDH(0), 0);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1262
	ew32(RDT(0), 0);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1263
	rctl = E1000_RCTL_EN | E1000_RCTL_BAM | E1000_RCTL_SZ_2048 |
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1264
	    E1000_RCTL_UPE | E1000_RCTL_MPE | E1000_RCTL_LPE |
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1265
	    E1000_RCTL_SBP | E1000_RCTL_SECRC |
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1266
	    E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF |
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1267
	    (adapter->hw.mac.mc_filter_type << E1000_RCTL_MO_SHIFT);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1268
	ew32(RCTL, rctl);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1269
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1270
	for (i = 0; i < rx_ring->count; i++) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1271
		union e1000_rx_desc_extended *rx_desc;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1272
		struct sk_buff *skb;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1273
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1274
		skb = alloc_skb(2048 + NET_IP_ALIGN, GFP_KERNEL);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1275
		if (!skb) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1276
			ret_val = 7;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1277
			goto err_nomem;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1278
		}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1279
		skb_reserve(skb, NET_IP_ALIGN);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1280
		rx_ring->buffer_info[i].skb = skb;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1281
		rx_ring->buffer_info[i].dma =
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1282
		    dma_map_single(&pdev->dev, skb->data, 2048,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1283
				   DMA_FROM_DEVICE);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1284
		if (dma_mapping_error(&pdev->dev,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1285
				      rx_ring->buffer_info[i].dma)) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1286
			ret_val = 8;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1287
			goto err_nomem;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1288
		}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1289
		rx_desc = E1000_RX_DESC_EXT(*rx_ring, i);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1290
		rx_desc->read.buffer_addr =
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1291
		    cpu_to_le64(rx_ring->buffer_info[i].dma);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1292
		memset(skb->data, 0x00, skb->len);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1293
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1294
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1295
	return 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1296
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1297
err_nomem:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1298
	e1000_free_desc_rings(adapter);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1299
	return ret_val;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1300
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1301
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1302
static void e1000_phy_disable_receiver(struct e1000_adapter *adapter)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1303
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1304
	/* Write out to PHY registers 29 and 30 to disable the Receiver. */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1305
	e1e_wphy(&adapter->hw, 29, 0x001F);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1306
	e1e_wphy(&adapter->hw, 30, 0x8FFC);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1307
	e1e_wphy(&adapter->hw, 29, 0x001A);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1308
	e1e_wphy(&adapter->hw, 30, 0x8FF0);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1309
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1310
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1311
static int e1000_integrated_phy_loopback(struct e1000_adapter *adapter)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1312
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1313
	struct e1000_hw *hw = &adapter->hw;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1314
	u32 ctrl_reg = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1315
	u16 phy_reg = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1316
	s32 ret_val = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1317
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1318
	hw->mac.autoneg = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1319
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1320
	if (hw->phy.type == e1000_phy_ife) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1321
		/* force 100, set loopback */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1322
		e1e_wphy(hw, MII_BMCR, 0x6100);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1323
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1324
		/* Now set up the MAC to the same speed/duplex as the PHY. */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1325
		ctrl_reg = er32(CTRL);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1326
		ctrl_reg &= ~E1000_CTRL_SPD_SEL; /* Clear the speed sel bits */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1327
		ctrl_reg |= (E1000_CTRL_FRCSPD | /* Set the Force Speed Bit */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1328
			     E1000_CTRL_FRCDPX | /* Set the Force Duplex Bit */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1329
			     E1000_CTRL_SPD_100 |/* Force Speed to 100 */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1330
			     E1000_CTRL_FD);	 /* Force Duplex to FULL */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1331
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1332
		ew32(CTRL, ctrl_reg);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1333
		e1e_flush();
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1334
		usleep_range(500, 1000);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1335
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1336
		return 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1337
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1338
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1339
	/* Specific PHY configuration for loopback */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1340
	switch (hw->phy.type) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1341
	case e1000_phy_m88:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1342
		/* Auto-MDI/MDIX Off */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1343
		e1e_wphy(hw, M88E1000_PHY_SPEC_CTRL, 0x0808);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1344
		/* reset to update Auto-MDI/MDIX */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1345
		e1e_wphy(hw, MII_BMCR, 0x9140);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1346
		/* autoneg off */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1347
		e1e_wphy(hw, MII_BMCR, 0x8140);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1348
		break;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1349
	case e1000_phy_gg82563:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1350
		e1e_wphy(hw, GG82563_PHY_KMRN_MODE_CTRL, 0x1CC);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1351
		break;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1352
	case e1000_phy_bm:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1353
		/* Set Default MAC Interface speed to 1GB */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1354
		e1e_rphy(hw, PHY_REG(2, 21), &phy_reg);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1355
		phy_reg &= ~0x0007;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1356
		phy_reg |= 0x006;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1357
		e1e_wphy(hw, PHY_REG(2, 21), phy_reg);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1358
		/* Assert SW reset for above settings to take effect */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1359
		hw->phy.ops.commit(hw);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1360
		usleep_range(1000, 2000);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1361
		/* Force Full Duplex */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1362
		e1e_rphy(hw, PHY_REG(769, 16), &phy_reg);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1363
		e1e_wphy(hw, PHY_REG(769, 16), phy_reg | 0x000C);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1364
		/* Set Link Up (in force link) */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1365
		e1e_rphy(hw, PHY_REG(776, 16), &phy_reg);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1366
		e1e_wphy(hw, PHY_REG(776, 16), phy_reg | 0x0040);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1367
		/* Force Link */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1368
		e1e_rphy(hw, PHY_REG(769, 16), &phy_reg);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1369
		e1e_wphy(hw, PHY_REG(769, 16), phy_reg | 0x0040);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1370
		/* Set Early Link Enable */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1371
		e1e_rphy(hw, PHY_REG(769, 20), &phy_reg);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1372
		e1e_wphy(hw, PHY_REG(769, 20), phy_reg | 0x0400);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1373
		break;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1374
	case e1000_phy_82577:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1375
	case e1000_phy_82578:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1376
		/* Workaround: K1 must be disabled for stable 1Gbps operation */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1377
		ret_val = hw->phy.ops.acquire(hw);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1378
		if (ret_val) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1379
			e_err("Cannot setup 1Gbps loopback.\n");
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1380
			return ret_val;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1381
		}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1382
		e1000_configure_k1_ich8lan(hw, false);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1383
		hw->phy.ops.release(hw);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1384
		break;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1385
	case e1000_phy_82579:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1386
		/* Disable PHY energy detect power down */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1387
		e1e_rphy(hw, PHY_REG(0, 21), &phy_reg);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1388
		e1e_wphy(hw, PHY_REG(0, 21), phy_reg & ~(1 << 3));
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1389
		/* Disable full chip energy detect */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1390
		e1e_rphy(hw, PHY_REG(776, 18), &phy_reg);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1391
		e1e_wphy(hw, PHY_REG(776, 18), phy_reg | 1);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1392
		/* Enable loopback on the PHY */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1393
		e1e_wphy(hw, I82577_PHY_LBK_CTRL, 0x8001);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1394
		break;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1395
	default:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1396
		break;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1397
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1398
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1399
	/* force 1000, set loopback */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1400
	e1e_wphy(hw, MII_BMCR, 0x4140);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1401
	msleep(250);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1402
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1403
	/* Now set up the MAC to the same speed/duplex as the PHY. */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1404
	ctrl_reg = er32(CTRL);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1405
	ctrl_reg &= ~E1000_CTRL_SPD_SEL; /* Clear the speed sel bits */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1406
	ctrl_reg |= (E1000_CTRL_FRCSPD | /* Set the Force Speed Bit */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1407
		     E1000_CTRL_FRCDPX | /* Set the Force Duplex Bit */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1408
		     E1000_CTRL_SPD_1000 |/* Force Speed to 1000 */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1409
		     E1000_CTRL_FD);	 /* Force Duplex to FULL */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1410
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1411
	if (adapter->flags & FLAG_IS_ICH)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1412
		ctrl_reg |= E1000_CTRL_SLU;	/* Set Link Up */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1413
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1414
	if (hw->phy.media_type == e1000_media_type_copper &&
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1415
	    hw->phy.type == e1000_phy_m88) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1416
		ctrl_reg |= E1000_CTRL_ILOS;	/* Invert Loss of Signal */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1417
	} else {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1418
		/* Set the ILOS bit on the fiber Nic if half duplex link is
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1419
		 * detected.
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1420
		 */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1421
		if ((er32(STATUS) & E1000_STATUS_FD) == 0)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1422
			ctrl_reg |= (E1000_CTRL_ILOS | E1000_CTRL_SLU);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1423
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1424
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1425
	ew32(CTRL, ctrl_reg);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1426
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1427
	/* Disable the receiver on the PHY so when a cable is plugged in, the
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1428
	 * PHY does not begin to autoneg when a cable is reconnected to the NIC.
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1429
	 */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1430
	if (hw->phy.type == e1000_phy_m88)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1431
		e1000_phy_disable_receiver(adapter);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1432
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1433
	usleep_range(500, 1000);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1434
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1435
	return 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1436
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1437
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1438
static int e1000_set_82571_fiber_loopback(struct e1000_adapter *adapter)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1439
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1440
	struct e1000_hw *hw = &adapter->hw;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1441
	u32 ctrl = er32(CTRL);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1442
	int link;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1443
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1444
	/* special requirements for 82571/82572 fiber adapters */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1445
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1446
	/* jump through hoops to make sure link is up because serdes
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1447
	 * link is hardwired up
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1448
	 */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1449
	ctrl |= E1000_CTRL_SLU;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1450
	ew32(CTRL, ctrl);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1451
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1452
	/* disable autoneg */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1453
	ctrl = er32(TXCW);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1454
	ctrl &= ~(1 << 31);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1455
	ew32(TXCW, ctrl);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1456
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1457
	link = (er32(STATUS) & E1000_STATUS_LU);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1458
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1459
	if (!link) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1460
		/* set invert loss of signal */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1461
		ctrl = er32(CTRL);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1462
		ctrl |= E1000_CTRL_ILOS;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1463
		ew32(CTRL, ctrl);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1464
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1465
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1466
	/* special write to serdes control register to enable SerDes analog
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1467
	 * loopback
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1468
	 */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1469
	ew32(SCTL, E1000_SCTL_ENABLE_SERDES_LOOPBACK);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1470
	e1e_flush();
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1471
	usleep_range(10000, 20000);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1472
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1473
	return 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1474
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1475
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1476
/* only call this for fiber/serdes connections to es2lan */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1477
static int e1000_set_es2lan_mac_loopback(struct e1000_adapter *adapter)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1478
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1479
	struct e1000_hw *hw = &adapter->hw;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1480
	u32 ctrlext = er32(CTRL_EXT);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1481
	u32 ctrl = er32(CTRL);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1482
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1483
	/* save CTRL_EXT to restore later, reuse an empty variable (unused
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1484
	 * on mac_type 80003es2lan)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1485
	 */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1486
	adapter->tx_fifo_head = ctrlext;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1487
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1488
	/* clear the serdes mode bits, putting the device into mac loopback */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1489
	ctrlext &= ~E1000_CTRL_EXT_LINK_MODE_PCIE_SERDES;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1490
	ew32(CTRL_EXT, ctrlext);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1491
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1492
	/* force speed to 1000/FD, link up */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1493
	ctrl &= ~(E1000_CTRL_SPD_1000 | E1000_CTRL_SPD_100);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1494
	ctrl |= (E1000_CTRL_SLU | E1000_CTRL_FRCSPD | E1000_CTRL_FRCDPX |
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1495
		 E1000_CTRL_SPD_1000 | E1000_CTRL_FD);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1496
	ew32(CTRL, ctrl);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1497
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1498
	/* set mac loopback */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1499
	ctrl = er32(RCTL);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1500
	ctrl |= E1000_RCTL_LBM_MAC;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1501
	ew32(RCTL, ctrl);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1502
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1503
	/* set testing mode parameters (no need to reset later) */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1504
#define KMRNCTRLSTA_OPMODE (0x1F << 16)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1505
#define KMRNCTRLSTA_OPMODE_1GB_FD_GMII 0x0582
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1506
	ew32(KMRNCTRLSTA,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1507
	     (KMRNCTRLSTA_OPMODE | KMRNCTRLSTA_OPMODE_1GB_FD_GMII));
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1508
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1509
	return 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1510
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1511
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1512
static int e1000_setup_loopback_test(struct e1000_adapter *adapter)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1513
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1514
	struct e1000_hw *hw = &adapter->hw;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1515
	u32 rctl;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1516
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1517
	if (hw->phy.media_type == e1000_media_type_fiber ||
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1518
	    hw->phy.media_type == e1000_media_type_internal_serdes) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1519
		switch (hw->mac.type) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1520
		case e1000_80003es2lan:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1521
			return e1000_set_es2lan_mac_loopback(adapter);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1522
			break;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1523
		case e1000_82571:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1524
		case e1000_82572:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1525
			return e1000_set_82571_fiber_loopback(adapter);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1526
			break;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1527
		default:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1528
			rctl = er32(RCTL);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1529
			rctl |= E1000_RCTL_LBM_TCVR;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1530
			ew32(RCTL, rctl);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1531
			return 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1532
		}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1533
	} else if (hw->phy.media_type == e1000_media_type_copper) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1534
		return e1000_integrated_phy_loopback(adapter);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1535
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1536
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1537
	return 7;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1538
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1539
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1540
static void e1000_loopback_cleanup(struct e1000_adapter *adapter)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1541
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1542
	struct e1000_hw *hw = &adapter->hw;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1543
	u32 rctl;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1544
	u16 phy_reg;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1545
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1546
	rctl = er32(RCTL);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1547
	rctl &= ~(E1000_RCTL_LBM_TCVR | E1000_RCTL_LBM_MAC);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1548
	ew32(RCTL, rctl);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1549
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1550
	switch (hw->mac.type) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1551
	case e1000_80003es2lan:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1552
		if (hw->phy.media_type == e1000_media_type_fiber ||
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1553
		    hw->phy.media_type == e1000_media_type_internal_serdes) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1554
			/* restore CTRL_EXT, stealing space from tx_fifo_head */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1555
			ew32(CTRL_EXT, adapter->tx_fifo_head);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1556
			adapter->tx_fifo_head = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1557
		}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1558
		/* fall through */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1559
	case e1000_82571:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1560
	case e1000_82572:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1561
		if (hw->phy.media_type == e1000_media_type_fiber ||
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1562
		    hw->phy.media_type == e1000_media_type_internal_serdes) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1563
			ew32(SCTL, E1000_SCTL_DISABLE_SERDES_LOOPBACK);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1564
			e1e_flush();
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1565
			usleep_range(10000, 20000);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1566
			break;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1567
		}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1568
		/* Fall Through */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1569
	default:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1570
		hw->mac.autoneg = 1;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1571
		if (hw->phy.type == e1000_phy_gg82563)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1572
			e1e_wphy(hw, GG82563_PHY_KMRN_MODE_CTRL, 0x180);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1573
		e1e_rphy(hw, MII_BMCR, &phy_reg);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1574
		if (phy_reg & BMCR_LOOPBACK) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1575
			phy_reg &= ~BMCR_LOOPBACK;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1576
			e1e_wphy(hw, MII_BMCR, phy_reg);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1577
			if (hw->phy.ops.commit)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1578
				hw->phy.ops.commit(hw);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1579
		}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1580
		break;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1581
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1582
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1583
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1584
static void e1000_create_lbtest_frame(struct sk_buff *skb,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1585
				      unsigned int frame_size)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1586
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1587
	memset(skb->data, 0xFF, frame_size);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1588
	frame_size &= ~1;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1589
	memset(&skb->data[frame_size / 2], 0xAA, frame_size / 2 - 1);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1590
	memset(&skb->data[frame_size / 2 + 10], 0xBE, 1);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1591
	memset(&skb->data[frame_size / 2 + 12], 0xAF, 1);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1592
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1593
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1594
static int e1000_check_lbtest_frame(struct sk_buff *skb,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1595
				    unsigned int frame_size)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1596
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1597
	frame_size &= ~1;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1598
	if (*(skb->data + 3) == 0xFF)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1599
		if ((*(skb->data + frame_size / 2 + 10) == 0xBE) &&
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1600
		    (*(skb->data + frame_size / 2 + 12) == 0xAF))
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1601
			return 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1602
	return 13;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1603
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1604
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1605
static int e1000_run_loopback_test(struct e1000_adapter *adapter)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1606
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1607
	struct e1000_ring *tx_ring = &adapter->test_tx_ring;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1608
	struct e1000_ring *rx_ring = &adapter->test_rx_ring;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1609
	struct pci_dev *pdev = adapter->pdev;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1610
	struct e1000_hw *hw = &adapter->hw;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1611
	struct e1000_buffer *buffer_info;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1612
	int i, j, k, l;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1613
	int lc;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1614
	int good_cnt;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1615
	int ret_val = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1616
	unsigned long time;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1617
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1618
	ew32(RDT(0), rx_ring->count - 1);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1619
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1620
	/* Calculate the loop count based on the largest descriptor ring
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1621
	 * The idea is to wrap the largest ring a number of times using 64
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1622
	 * send/receive pairs during each loop
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1623
	 */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1624
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1625
	if (rx_ring->count <= tx_ring->count)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1626
		lc = ((tx_ring->count / 64) * 2) + 1;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1627
	else
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1628
		lc = ((rx_ring->count / 64) * 2) + 1;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1629
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1630
	k = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1631
	l = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1632
	/* loop count loop */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1633
	for (j = 0; j <= lc; j++) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1634
		/* send the packets */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1635
		for (i = 0; i < 64; i++) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1636
			buffer_info = &tx_ring->buffer_info[k];
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1637
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1638
			e1000_create_lbtest_frame(buffer_info->skb, 1024);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1639
			dma_sync_single_for_device(&pdev->dev,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1640
						   buffer_info->dma,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1641
						   buffer_info->length,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1642
						   DMA_TO_DEVICE);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1643
			k++;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1644
			if (k == tx_ring->count)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1645
				k = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1646
		}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1647
		ew32(TDT(0), k);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1648
		e1e_flush();
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1649
		msleep(200);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1650
		time = jiffies;	/* set the start time for the receive */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1651
		good_cnt = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1652
		/* receive the sent packets */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1653
		do {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1654
			buffer_info = &rx_ring->buffer_info[l];
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1655
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1656
			dma_sync_single_for_cpu(&pdev->dev,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1657
						buffer_info->dma, 2048,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1658
						DMA_FROM_DEVICE);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1659
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1660
			ret_val = e1000_check_lbtest_frame(buffer_info->skb,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1661
							   1024);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1662
			if (!ret_val)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1663
				good_cnt++;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1664
			l++;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1665
			if (l == rx_ring->count)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1666
				l = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1667
			/* time + 20 msecs (200 msecs on 2.4) is more than
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1668
			 * enough time to complete the receives, if it's
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1669
			 * exceeded, break and error off
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1670
			 */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1671
		} while ((good_cnt < 64) && !time_after(jiffies, time + 20));
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1672
		if (good_cnt != 64) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1673
			ret_val = 13;	/* ret_val is the same as mis-compare */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1674
			break;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1675
		}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1676
		if (time_after(jiffies, time + 20)) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1677
			ret_val = 14;	/* error code for time out error */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1678
			break;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1679
		}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1680
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1681
	return ret_val;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1682
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1683
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1684
static int e1000_loopback_test(struct e1000_adapter *adapter, u64 *data)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1685
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1686
	struct e1000_hw *hw = &adapter->hw;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1687
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1688
	/* PHY loopback cannot be performed if SoL/IDER sessions are active */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1689
	if (hw->phy.ops.check_reset_block &&
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1690
	    hw->phy.ops.check_reset_block(hw)) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1691
		e_err("Cannot do PHY loopback test when SoL/IDER is active.\n");
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1692
		*data = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1693
		goto out;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1694
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1695
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1696
	*data = e1000_setup_desc_rings(adapter);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1697
	if (*data)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1698
		goto out;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1699
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1700
	*data = e1000_setup_loopback_test(adapter);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1701
	if (*data)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1702
		goto err_loopback;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1703
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1704
	*data = e1000_run_loopback_test(adapter);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1705
	e1000_loopback_cleanup(adapter);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1706
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1707
err_loopback:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1708
	e1000_free_desc_rings(adapter);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1709
out:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1710
	return *data;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1711
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1712
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1713
static int e1000_link_test(struct e1000_adapter *adapter, u64 *data)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1714
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1715
	struct e1000_hw *hw = &adapter->hw;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1716
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1717
	*data = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1718
	if (hw->phy.media_type == e1000_media_type_internal_serdes) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1719
		int i = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1720
		hw->mac.serdes_has_link = false;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1721
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1722
		/* On some blade server designs, link establishment
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1723
		 * could take as long as 2-3 minutes
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1724
		 */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1725
		do {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1726
			hw->mac.ops.check_for_link(hw);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1727
			if (hw->mac.serdes_has_link)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1728
				return *data;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1729
			msleep(20);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1730
		} while (i++ < 3750);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1731
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1732
		*data = 1;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1733
	} else {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1734
		hw->mac.ops.check_for_link(hw);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1735
		if (hw->mac.autoneg)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1736
			/* On some Phy/switch combinations, link establishment
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1737
			 * can take a few seconds more than expected.
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1738
			 */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1739
			msleep_interruptible(5000);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1740
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1741
		if (!(er32(STATUS) & E1000_STATUS_LU))
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1742
			*data = 1;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1743
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1744
	return *data;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1745
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1746
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1747
static int e1000e_get_sset_count(struct net_device __always_unused *netdev,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1748
				 int sset)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1749
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1750
	switch (sset) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1751
	case ETH_SS_TEST:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1752
		return E1000_TEST_LEN;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1753
	case ETH_SS_STATS:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1754
		return E1000_STATS_LEN;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1755
	default:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1756
		return -EOPNOTSUPP;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1757
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1758
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1759
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1760
static void e1000_diag_test(struct net_device *netdev,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1761
			    struct ethtool_test *eth_test, u64 *data)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1762
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1763
	struct e1000_adapter *adapter = netdev_priv(netdev);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1764
	u16 autoneg_advertised;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1765
	u8 forced_speed_duplex;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1766
	u8 autoneg;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1767
	bool if_running = netif_running(netdev);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1768
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1769
	pm_runtime_get_sync(netdev->dev.parent);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1770
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1771
	set_bit(__E1000_TESTING, &adapter->state);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1772
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1773
	if (!if_running) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1774
		/* Get control of and reset hardware */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1775
		if (adapter->flags & FLAG_HAS_AMT)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1776
			e1000e_get_hw_control(adapter);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1777
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1778
		e1000e_power_up_phy(adapter);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1779
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1780
		adapter->hw.phy.autoneg_wait_to_complete = 1;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1781
		e1000e_reset(adapter);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1782
		adapter->hw.phy.autoneg_wait_to_complete = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1783
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1784
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1785
	if (eth_test->flags == ETH_TEST_FL_OFFLINE) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1786
		/* Offline tests */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1787
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1788
		/* save speed, duplex, autoneg settings */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1789
		autoneg_advertised = adapter->hw.phy.autoneg_advertised;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1790
		forced_speed_duplex = adapter->hw.mac.forced_speed_duplex;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1791
		autoneg = adapter->hw.mac.autoneg;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1792
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1793
		e_info("offline testing starting\n");
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1794
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1795
		if (if_running)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1796
			/* indicate we're in test mode */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1797
			dev_close(netdev);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1798
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1799
		if (e1000_reg_test(adapter, &data[0]))
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1800
			eth_test->flags |= ETH_TEST_FL_FAILED;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1801
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1802
		e1000e_reset(adapter);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1803
		if (e1000_eeprom_test(adapter, &data[1]))
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1804
			eth_test->flags |= ETH_TEST_FL_FAILED;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1805
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1806
		e1000e_reset(adapter);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1807
		if (e1000_intr_test(adapter, &data[2]))
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1808
			eth_test->flags |= ETH_TEST_FL_FAILED;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1809
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1810
		e1000e_reset(adapter);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1811
		if (e1000_loopback_test(adapter, &data[3]))
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1812
			eth_test->flags |= ETH_TEST_FL_FAILED;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1813
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1814
		/* force this routine to wait until autoneg complete/timeout */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1815
		adapter->hw.phy.autoneg_wait_to_complete = 1;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1816
		e1000e_reset(adapter);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1817
		adapter->hw.phy.autoneg_wait_to_complete = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1818
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1819
		if (e1000_link_test(adapter, &data[4]))
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1820
			eth_test->flags |= ETH_TEST_FL_FAILED;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1821
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1822
		/* restore speed, duplex, autoneg settings */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1823
		adapter->hw.phy.autoneg_advertised = autoneg_advertised;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1824
		adapter->hw.mac.forced_speed_duplex = forced_speed_duplex;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1825
		adapter->hw.mac.autoneg = autoneg;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1826
		e1000e_reset(adapter);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1827
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1828
		clear_bit(__E1000_TESTING, &adapter->state);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1829
		if (if_running)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1830
			dev_open(netdev);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1831
	} else {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1832
		/* Online tests */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1833
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1834
		e_info("online testing starting\n");
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1835
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1836
		/* register, eeprom, intr and loopback tests not run online */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1837
		data[0] = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1838
		data[1] = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1839
		data[2] = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1840
		data[3] = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1841
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1842
		if (e1000_link_test(adapter, &data[4]))
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1843
			eth_test->flags |= ETH_TEST_FL_FAILED;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1844
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1845
		clear_bit(__E1000_TESTING, &adapter->state);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1846
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1847
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1848
	if (!if_running) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1849
		e1000e_reset(adapter);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1850
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1851
		if (adapter->flags & FLAG_HAS_AMT)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1852
			e1000e_release_hw_control(adapter);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1853
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1854
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1855
	msleep_interruptible(4 * 1000);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1856
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1857
	pm_runtime_put_sync(netdev->dev.parent);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1858
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1859
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1860
static void e1000_get_wol(struct net_device *netdev,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1861
			  struct ethtool_wolinfo *wol)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1862
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1863
	struct e1000_adapter *adapter = netdev_priv(netdev);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1864
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1865
	wol->supported = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1866
	wol->wolopts = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1867
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1868
	if (!(adapter->flags & FLAG_HAS_WOL) ||
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1869
	    !device_can_wakeup(&adapter->pdev->dev))
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1870
		return;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1871
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1872
	wol->supported = WAKE_UCAST | WAKE_MCAST |
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1873
	    WAKE_BCAST | WAKE_MAGIC | WAKE_PHY;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1874
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1875
	/* apply any specific unsupported masks here */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1876
	if (adapter->flags & FLAG_NO_WAKE_UCAST) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1877
		wol->supported &= ~WAKE_UCAST;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1878
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1879
		if (adapter->wol & E1000_WUFC_EX)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1880
			e_err("Interface does not support directed (unicast) frame wake-up packets\n");
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1881
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1882
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1883
	if (adapter->wol & E1000_WUFC_EX)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1884
		wol->wolopts |= WAKE_UCAST;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1885
	if (adapter->wol & E1000_WUFC_MC)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1886
		wol->wolopts |= WAKE_MCAST;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1887
	if (adapter->wol & E1000_WUFC_BC)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1888
		wol->wolopts |= WAKE_BCAST;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1889
	if (adapter->wol & E1000_WUFC_MAG)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1890
		wol->wolopts |= WAKE_MAGIC;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1891
	if (adapter->wol & E1000_WUFC_LNKC)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1892
		wol->wolopts |= WAKE_PHY;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1893
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1894
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1895
static int e1000_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1896
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1897
	struct e1000_adapter *adapter = netdev_priv(netdev);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1898
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1899
	if (!(adapter->flags & FLAG_HAS_WOL) ||
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1900
	    !device_can_wakeup(&adapter->pdev->dev) ||
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1901
	    (wol->wolopts & ~(WAKE_UCAST | WAKE_MCAST | WAKE_BCAST |
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1902
			      WAKE_MAGIC | WAKE_PHY)))
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1903
		return -EOPNOTSUPP;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1904
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1905
	/* these settings will always override what we currently have */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1906
	adapter->wol = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1907
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1908
	if (wol->wolopts & WAKE_UCAST)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1909
		adapter->wol |= E1000_WUFC_EX;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1910
	if (wol->wolopts & WAKE_MCAST)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1911
		adapter->wol |= E1000_WUFC_MC;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1912
	if (wol->wolopts & WAKE_BCAST)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1913
		adapter->wol |= E1000_WUFC_BC;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1914
	if (wol->wolopts & WAKE_MAGIC)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1915
		adapter->wol |= E1000_WUFC_MAG;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1916
	if (wol->wolopts & WAKE_PHY)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1917
		adapter->wol |= E1000_WUFC_LNKC;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1918
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1919
	device_set_wakeup_enable(&adapter->pdev->dev, adapter->wol);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1920
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1921
	return 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1922
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1923
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1924
static int e1000_set_phys_id(struct net_device *netdev,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1925
			     enum ethtool_phys_id_state state)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1926
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1927
	struct e1000_adapter *adapter = netdev_priv(netdev);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1928
	struct e1000_hw *hw = &adapter->hw;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1929
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1930
	switch (state) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1931
	case ETHTOOL_ID_ACTIVE:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1932
		pm_runtime_get_sync(netdev->dev.parent);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1933
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1934
		if (!hw->mac.ops.blink_led)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1935
			return 2;	/* cycle on/off twice per second */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1936
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1937
		hw->mac.ops.blink_led(hw);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1938
		break;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1939
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1940
	case ETHTOOL_ID_INACTIVE:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1941
		if (hw->phy.type == e1000_phy_ife)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1942
			e1e_wphy(hw, IFE_PHY_SPECIAL_CONTROL_LED, 0);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1943
		hw->mac.ops.led_off(hw);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1944
		hw->mac.ops.cleanup_led(hw);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1945
		pm_runtime_put_sync(netdev->dev.parent);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1946
		break;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1947
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1948
	case ETHTOOL_ID_ON:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1949
		hw->mac.ops.led_on(hw);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1950
		break;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1951
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1952
	case ETHTOOL_ID_OFF:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1953
		hw->mac.ops.led_off(hw);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1954
		break;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1955
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1956
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1957
	return 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1958
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1959
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1960
static int e1000_get_coalesce(struct net_device *netdev,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1961
			      struct ethtool_coalesce *ec)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1962
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1963
	struct e1000_adapter *adapter = netdev_priv(netdev);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1964
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1965
	if (adapter->itr_setting <= 4)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1966
		ec->rx_coalesce_usecs = adapter->itr_setting;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1967
	else
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1968
		ec->rx_coalesce_usecs = 1000000 / adapter->itr_setting;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1969
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1970
	return 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1971
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1972
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1973
static int e1000_set_coalesce(struct net_device *netdev,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1974
			      struct ethtool_coalesce *ec)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1975
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1976
	struct e1000_adapter *adapter = netdev_priv(netdev);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1977
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1978
	if ((ec->rx_coalesce_usecs > E1000_MAX_ITR_USECS) ||
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1979
	    ((ec->rx_coalesce_usecs > 4) &&
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1980
	     (ec->rx_coalesce_usecs < E1000_MIN_ITR_USECS)) ||
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1981
	    (ec->rx_coalesce_usecs == 2))
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1982
		return -EINVAL;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1983
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1984
	if (ec->rx_coalesce_usecs == 4) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1985
		adapter->itr_setting = 4;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1986
		adapter->itr = adapter->itr_setting;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1987
	} else if (ec->rx_coalesce_usecs <= 3) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1988
		adapter->itr = 20000;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1989
		adapter->itr_setting = ec->rx_coalesce_usecs;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1990
	} else {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1991
		adapter->itr = (1000000 / ec->rx_coalesce_usecs);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1992
		adapter->itr_setting = adapter->itr & ~3;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1993
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1994
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1995
	pm_runtime_get_sync(netdev->dev.parent);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1996
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1997
	if (adapter->itr_setting != 0)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1998
		e1000e_write_itr(adapter, adapter->itr);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  1999
	else
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2000
		e1000e_write_itr(adapter, 0);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2001
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2002
	pm_runtime_put_sync(netdev->dev.parent);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2003
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2004
	return 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2005
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2006
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2007
static int e1000_nway_reset(struct net_device *netdev)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2008
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2009
	struct e1000_adapter *adapter = netdev_priv(netdev);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2010
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2011
	if (!netif_running(netdev))
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2012
		return -EAGAIN;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2013
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2014
	if (!adapter->hw.mac.autoneg)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2015
		return -EINVAL;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2016
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2017
	pm_runtime_get_sync(netdev->dev.parent);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2018
	e1000e_reinit_locked(adapter);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2019
	pm_runtime_put_sync(netdev->dev.parent);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2020
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2021
	return 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2022
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2023
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2024
static void e1000_get_ethtool_stats(struct net_device *netdev,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2025
				    struct ethtool_stats __always_unused *stats,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2026
				    u64 *data)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2027
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2028
	struct e1000_adapter *adapter = netdev_priv(netdev);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2029
	struct rtnl_link_stats64 net_stats;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2030
	int i;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2031
	char *p = NULL;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2032
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2033
	pm_runtime_get_sync(netdev->dev.parent);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2034
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2035
	e1000e_get_stats64(netdev, &net_stats);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2036
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2037
	pm_runtime_put_sync(netdev->dev.parent);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2038
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2039
	for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2040
		switch (e1000_gstrings_stats[i].type) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2041
		case NETDEV_STATS:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2042
			p = (char *)&net_stats +
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2043
			    e1000_gstrings_stats[i].stat_offset;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2044
			break;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2045
		case E1000_STATS:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2046
			p = (char *)adapter +
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2047
			    e1000_gstrings_stats[i].stat_offset;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2048
			break;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2049
		default:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2050
			data[i] = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2051
			continue;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2052
		}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2053
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2054
		data[i] = (e1000_gstrings_stats[i].sizeof_stat ==
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2055
			   sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2056
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2057
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2058
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2059
static void e1000_get_strings(struct net_device __always_unused *netdev,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2060
			      u32 stringset, u8 *data)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2061
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2062
	u8 *p = data;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2063
	int i;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2064
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2065
	switch (stringset) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2066
	case ETH_SS_TEST:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2067
		memcpy(data, e1000_gstrings_test, sizeof(e1000_gstrings_test));
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2068
		break;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2069
	case ETH_SS_STATS:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2070
		for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2071
			memcpy(p, e1000_gstrings_stats[i].stat_string,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2072
			       ETH_GSTRING_LEN);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2073
			p += ETH_GSTRING_LEN;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2074
		}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2075
		break;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2076
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2077
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2078
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2079
static int e1000_get_rxnfc(struct net_device *netdev,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2080
			   struct ethtool_rxnfc *info,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2081
			   u32 __always_unused *rule_locs)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2082
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2083
	info->data = 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2084
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2085
	switch (info->cmd) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2086
	case ETHTOOL_GRXFH: {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2087
		struct e1000_adapter *adapter = netdev_priv(netdev);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2088
		struct e1000_hw *hw = &adapter->hw;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2089
		u32 mrqc;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2090
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2091
		pm_runtime_get_sync(netdev->dev.parent);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2092
		mrqc = er32(MRQC);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2093
		pm_runtime_put_sync(netdev->dev.parent);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2094
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2095
		if (!(mrqc & E1000_MRQC_RSS_FIELD_MASK))
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2096
			return 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2097
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2098
		switch (info->flow_type) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2099
		case TCP_V4_FLOW:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2100
			if (mrqc & E1000_MRQC_RSS_FIELD_IPV4_TCP)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2101
				info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2102
			/* fall through */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2103
		case UDP_V4_FLOW:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2104
		case SCTP_V4_FLOW:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2105
		case AH_ESP_V4_FLOW:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2106
		case IPV4_FLOW:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2107
			if (mrqc & E1000_MRQC_RSS_FIELD_IPV4)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2108
				info->data |= RXH_IP_SRC | RXH_IP_DST;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2109
			break;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2110
		case TCP_V6_FLOW:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2111
			if (mrqc & E1000_MRQC_RSS_FIELD_IPV6_TCP)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2112
				info->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2113
			/* fall through */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2114
		case UDP_V6_FLOW:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2115
		case SCTP_V6_FLOW:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2116
		case AH_ESP_V6_FLOW:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2117
		case IPV6_FLOW:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2118
			if (mrqc & E1000_MRQC_RSS_FIELD_IPV6)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2119
				info->data |= RXH_IP_SRC | RXH_IP_DST;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2120
			break;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2121
		default:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2122
			break;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2123
		}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2124
		return 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2125
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2126
	default:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2127
		return -EOPNOTSUPP;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2128
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2129
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2130
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2131
static int e1000e_get_eee(struct net_device *netdev, struct ethtool_eee *edata)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2132
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2133
	struct e1000_adapter *adapter = netdev_priv(netdev);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2134
	struct e1000_hw *hw = &adapter->hw;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2135
	u16 cap_addr, lpa_addr, pcs_stat_addr, phy_data;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2136
	u32 ret_val;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2137
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2138
	if (!(adapter->flags2 & FLAG2_HAS_EEE))
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2139
		return -EOPNOTSUPP;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2140
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2141
	switch (hw->phy.type) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2142
	case e1000_phy_82579:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2143
		cap_addr = I82579_EEE_CAPABILITY;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2144
		lpa_addr = I82579_EEE_LP_ABILITY;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2145
		pcs_stat_addr = I82579_EEE_PCS_STATUS;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2146
		break;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2147
	case e1000_phy_i217:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2148
		cap_addr = I217_EEE_CAPABILITY;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2149
		lpa_addr = I217_EEE_LP_ABILITY;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2150
		pcs_stat_addr = I217_EEE_PCS_STATUS;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2151
		break;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2152
	default:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2153
		return -EOPNOTSUPP;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2154
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2155
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2156
	pm_runtime_get_sync(netdev->dev.parent);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2157
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2158
	ret_val = hw->phy.ops.acquire(hw);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2159
	if (ret_val) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2160
		pm_runtime_put_sync(netdev->dev.parent);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2161
		return -EBUSY;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2162
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2163
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2164
	/* EEE Capability */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2165
	ret_val = e1000_read_emi_reg_locked(hw, cap_addr, &phy_data);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2166
	if (ret_val)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2167
		goto release;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2168
	edata->supported = mmd_eee_cap_to_ethtool_sup_t(phy_data);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2169
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2170
	/* EEE Advertised */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2171
	edata->advertised = mmd_eee_adv_to_ethtool_adv_t(adapter->eee_advert);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2172
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2173
	/* EEE Link Partner Advertised */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2174
	ret_val = e1000_read_emi_reg_locked(hw, lpa_addr, &phy_data);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2175
	if (ret_val)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2176
		goto release;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2177
	edata->lp_advertised = mmd_eee_adv_to_ethtool_adv_t(phy_data);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2178
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2179
	/* EEE PCS Status */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2180
	ret_val = e1000_read_emi_reg_locked(hw, pcs_stat_addr, &phy_data);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2181
	if (ret_val)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2182
		goto release;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2183
	if (hw->phy.type == e1000_phy_82579)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2184
		phy_data <<= 8;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2185
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2186
	/* Result of the EEE auto negotiation - there is no register that
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2187
	 * has the status of the EEE negotiation so do a best-guess based
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2188
	 * on whether Tx or Rx LPI indications have been received.
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2189
	 */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2190
	if (phy_data & (E1000_EEE_TX_LPI_RCVD | E1000_EEE_RX_LPI_RCVD))
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2191
		edata->eee_active = true;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2192
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2193
	edata->eee_enabled = !hw->dev_spec.ich8lan.eee_disable;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2194
	edata->tx_lpi_enabled = true;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2195
	edata->tx_lpi_timer = er32(LPIC) >> E1000_LPIC_LPIET_SHIFT;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2196
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2197
release:
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2198
	hw->phy.ops.release(hw);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2199
	if (ret_val)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2200
		ret_val = -ENODATA;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2201
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2202
	pm_runtime_put_sync(netdev->dev.parent);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2203
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2204
	return ret_val;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2205
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2206
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2207
static int e1000e_set_eee(struct net_device *netdev, struct ethtool_eee *edata)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2208
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2209
	struct e1000_adapter *adapter = netdev_priv(netdev);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2210
	struct e1000_hw *hw = &adapter->hw;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2211
	struct ethtool_eee eee_curr;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2212
	s32 ret_val;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2213
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2214
	ret_val = e1000e_get_eee(netdev, &eee_curr);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2215
	if (ret_val)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2216
		return ret_val;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2217
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2218
	if (eee_curr.tx_lpi_enabled != edata->tx_lpi_enabled) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2219
		e_err("Setting EEE tx-lpi is not supported\n");
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2220
		return -EINVAL;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2221
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2222
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2223
	if (eee_curr.tx_lpi_timer != edata->tx_lpi_timer) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2224
		e_err("Setting EEE Tx LPI timer is not supported\n");
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2225
		return -EINVAL;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2226
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2227
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2228
	if (edata->advertised & ~(ADVERTISE_100_FULL | ADVERTISE_1000_FULL)) {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2229
		e_err("EEE advertisement supports only 100TX and/or 1000T full-duplex\n");
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2230
		return -EINVAL;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2231
	}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2232
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2233
	adapter->eee_advert = ethtool_adv_to_mmd_eee_adv_t(edata->advertised);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2234
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2235
	hw->dev_spec.ich8lan.eee_disable = !edata->eee_enabled;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2236
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2237
	pm_runtime_get_sync(netdev->dev.parent);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2238
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2239
	/* reset the link */
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2240
	if (netif_running(netdev))
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2241
		e1000e_reinit_locked(adapter);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2242
	else
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2243
		e1000e_reset(adapter);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2244
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2245
	pm_runtime_put_sync(netdev->dev.parent);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2246
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2247
	return 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2248
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2249
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2250
static int e1000e_get_ts_info(struct net_device *netdev,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2251
			      struct ethtool_ts_info *info)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2252
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2253
	struct e1000_adapter *adapter = netdev_priv(netdev);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2254
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2255
	ethtool_op_get_ts_info(netdev, info);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2256
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2257
	if (!(adapter->flags & FLAG_HAS_HW_TIMESTAMP))
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2258
		return 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2259
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2260
	info->so_timestamping |= (SOF_TIMESTAMPING_TX_HARDWARE |
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2261
				  SOF_TIMESTAMPING_RX_HARDWARE |
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2262
				  SOF_TIMESTAMPING_RAW_HARDWARE);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2263
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2264
	info->tx_types = (1 << HWTSTAMP_TX_OFF) | (1 << HWTSTAMP_TX_ON);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2265
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2266
	info->rx_filters = ((1 << HWTSTAMP_FILTER_NONE) |
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2267
			    (1 << HWTSTAMP_FILTER_PTP_V1_L4_SYNC) |
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2268
			    (1 << HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ) |
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2269
			    (1 << HWTSTAMP_FILTER_PTP_V2_L4_SYNC) |
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2270
			    (1 << HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ) |
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2271
			    (1 << HWTSTAMP_FILTER_PTP_V2_L2_SYNC) |
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2272
			    (1 << HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ) |
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2273
			    (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) |
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2274
			    (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2275
			    (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ) |
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2276
			    (1 << HWTSTAMP_FILTER_ALL));
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2277
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2278
	if (adapter->ptp_clock)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2279
		info->phc_index = ptp_clock_index(adapter->ptp_clock);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2280
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2281
	return 0;
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2282
}
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2283
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2284
static const struct ethtool_ops e1000_ethtool_ops = {
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2285
	.get_settings		= e1000_get_settings,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2286
	.set_settings		= e1000_set_settings,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2287
	.get_drvinfo		= e1000_get_drvinfo,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2288
	.get_regs_len		= e1000_get_regs_len,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2289
	.get_regs		= e1000_get_regs,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2290
	.get_wol		= e1000_get_wol,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2291
	.set_wol		= e1000_set_wol,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2292
	.get_msglevel		= e1000_get_msglevel,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2293
	.set_msglevel		= e1000_set_msglevel,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2294
	.nway_reset		= e1000_nway_reset,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2295
	.get_link		= ethtool_op_get_link,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2296
	.get_eeprom_len		= e1000_get_eeprom_len,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2297
	.get_eeprom		= e1000_get_eeprom,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2298
	.set_eeprom		= e1000_set_eeprom,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2299
	.get_ringparam		= e1000_get_ringparam,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2300
	.set_ringparam		= e1000_set_ringparam,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2301
	.get_pauseparam		= e1000_get_pauseparam,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2302
	.set_pauseparam		= e1000_set_pauseparam,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2303
	.self_test		= e1000_diag_test,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2304
	.get_strings		= e1000_get_strings,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2305
	.set_phys_id		= e1000_set_phys_id,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2306
	.get_ethtool_stats	= e1000_get_ethtool_stats,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2307
	.get_sset_count		= e1000e_get_sset_count,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2308
	.get_coalesce		= e1000_get_coalesce,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2309
	.set_coalesce		= e1000_set_coalesce,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2310
	.get_rxnfc		= e1000_get_rxnfc,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2311
	.get_ts_info		= e1000e_get_ts_info,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2312
	.get_eee		= e1000e_get_eee,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2313
	.set_eee		= e1000e_set_eee,
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2314
};
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2315
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2316
void e1000e_set_ethtool_ops(struct net_device *netdev)
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2317
{
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2318
	SET_ETHTOOL_OPS(netdev, &e1000_ethtool_ops);
afd76ee3aa87 Added all drivers for kernel 3.14.
Florian Pose <fp@igh-essen.com>
parents:
diff changeset
  2319
}