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